QualNet发包过程简要回顾

本文简要回顾了QualNet中从应用层到物理层的数据发包过程。在应用层,通过APP_UdpSendNewHeaderData()函数添加应用层数据;传输层由TransportUdpSendToNetwork()函数添加传输层首部;网络层处理IP首部及路由,可能进行分片;链路层添加802.11帧首部并尝试发送;物理层添加物理层首部后释放信号至信道。

前几篇文章已经将发包过程进行了详细解读,此处进行概要回顾,浓缩都是精华。

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);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值