前几篇文章已经将发包过程进行了详细解读,此处进行概要回顾,浓缩都是精华。
1.应用层
APP_UdpSendNewHeaderData()函数分配消息,添加应用层数据、应用层首部(另有不添加应用层首部的接口函数如APP_UdpSendNewData),添加辅助信息AppToUdpSend,调度传输层UDP协议事件MSG_TRANSPORT_FromAppSend。
msg = MESSAGE_Alloc(
node,
TRANSPORT_LAYER,
TransportProtocol_UDP,
MSG_TRANSPORT_FromAppSend);
MESSAGE_PacketAlloc(node, msg, payloadSize, traceProtocol);
memcpy(MESSAGE_ReturnPacket(msg), payload, payloadSize);
MESSAGE_AddHeader(node, msg, headerSize, traceProtocol);
memcpy(MESSAGE_ReturnPacket(msg), header, headerSize);
MESSAGE_InfoAlloc(node, msg, sizeof(AppToUdpSend));
info = (AppToUdpSend *) MESSAGE_ReturnInfo(msg);
2.传输层
TransportUdpSendToNetwork()函数添加传输层首部TransportUdpHeader,调用层间接口函数NetworkIpReceivePacketFromTransportLayer()发送至网络层。
void TransportUdpSendToNetwork(Node *node, Message *msg)
{
TransportUdpHeader *udpHdr;
AppToUdpSend *info;
info = (AppToUdpSend *) MESSAGE_ReturnInfo(msg);
MESSAGE_AddHeader(node, msg, sizeof(TransportUdpHeader), TRACE_UDP);
udpHdr = (TransportUdpHeader *) msg->packet;
NetworkIpReceivePacketFromTransportLayer(
node,
msg,
info->sourceAddr,
info->destAddr,
info->outgoingInterface,
info->priority,
protocol,
FALSE,
info->ttl);
}
3.网络层
NetworkIpSendRawMessage()函数调用AddIpHeader添加IP首部IpHeaderType;
RoutePacketAndSendToMac()函数区分回环、单播、广播、组播,单播时获取路由协议并路由发送,其他方式不经过路由协议。
NetworkIpSendPacketOnInterface()函数判断是否需要分片传输,分片则逐片发送后删除原消息,不分片则将原消息直接发送。
NetworkIpSendOnBackplane()函数判断队列是否无限制,有限制时判断队列是否已满,经过入列出列动作,调用层间接口函数MAC_NetworkLayerHasPacketToSend()发送数据至链路层。
static void
QueueUpIpFragmentForMacLayer(
Node *node,
Message *msg,
int interfaceIndex,
NodeAddress nextHop,
int incomingInterface)
{
//在接口输出队列中插入数据包
NetworkIpOutputQueueInsert(node,
interfaceIndex,
msg,
nextHop,
ipHeader->ip_dst,
NETWORK_PROTOCOL_IP,
&queueIsFull);
//发送数据
if (queueWasEmpty)
{
if (!NetworkIpOutputQueueIsEmpty(node, interfaceIndex))
{
MAC_NetworkLayerHasPacketToSend(node, interfaceIndex);
}
}
}
4. 链路层
MacDot11NetworkLayerHasPacketToSend()函数将数据包从网络层移至链路层,添加802.11帧首部DOT11_FrameHdr,并在链路空闲时,尝试发送数据。
MacDot11StationTransmitFrame()函数区分链路当前状态,调用MacDot11StationTransmitDataFrame()发送数据帧,或调用MacDot11StationTransmitRTSFrame()发送RTS帧。广播不使用RTS-CTS机制,单播时区分是否使用RTS-CTS机制,设置延迟。
MacDot11StationStartTransmittingPacket()函数获取帧的信息,判断是控制帧/数据帧,广播帧/单播帧,本地帧/非本地帧,更新统计信息,然后调用层间接口函数PHY_StartTransmittingSignal()发送帧。
static //inline//
void MacDot11StationStartTransmittingPacket(
Node* node,
MacDataDot11* dot11,
Message* packet,
clocktype delay)
{
//获取数据帧信息,判断是控制帧/数据帧,广播帧/单播帧,本地帧/非本地帧
BOOL isCtrlFrame = FALSE;
BOOL isMyFrame = FALSE;
BOOL isAnyFrame = FALSE;
int headerSize = -1;
Mac802Address destAddr;
NodeId destID;
MacDot11GetPacketProperty(
node,
packet,
dot11->myMacData->interfaceIndex,
headerSize,
destAddr,
destID,
isCtrlFrame,
isMyFrame,
isAnyFrame);
//更新统计信息
MacDot11UpdateStatsSend(
node,
packet,
dot11->myMacData->interfaceIndex,
isAnyFrame,
isMyFrame,
!isCtrlFrame,
destAddr);
//调用物理层发送数据帧
PHY_StartTransmittingSignal(
node, dot11->myMacData->phyNumber, packet, TRUE, delay);
}
5. 物理层
Phy802_11StartTransmittingSignal()函数调用StartTransmittingSignal,添加物理层首部Phy802_11PlcpHeader,调用函数ReleaseSignalToChannel()将信号发送至传输信道。
ReleaseSignalToChannel()调用函数层间接口函数PROP_ReleaseSignal()将信号发送至信道。
static
void ReleaseSignalToChannel(
Node *node,
Message *packet,
int phyIndex,
int channelIndex,
float txPower_dBm,
clocktype duration,
clocktype delayUntilAirborne,
double directionalAntennaGain_dB)
{
PhyData* thisPhy = node->phyData[phyIndex];
PhyData802_11* phy802_11 = (PhyData802_11 *)thisPhy->phyVar;
if (thisPhy->phyModel == PHY802_11n)
{
...
}
else
{
PROP_ReleaseSignal(
node,
packet,
phyIndex,
channelIndex,
(float)(txPower_dBm - directionalAntennaGain_dB),
duration,
delayUntilAirborne);
}
}
本文简要回顾了QualNet中从应用层到物理层的数据发包过程。在应用层,通过APP_UdpSendNewHeaderData()函数添加应用层数据;传输层由TransportUdpSendToNetwork()函数添加传输层首部;网络层处理IP首部及路由,可能进行分片;链路层添加802.11帧首部并尝试发送;物理层添加物理层首部后释放信号至信道。
922

被折叠的 条评论
为什么被折叠?



