Analysis of QualNet receiving and sending packets (3)

Follow the above https://blog.csdn.net/zhang1806618/article/details/107753611

The MacDot11StationTransmitFrame() function distinguishes the current state of the link, or calls MacDot11StationTransmitDataFrame() to send data frames, or calls MacDot11StationTransmitRTSFrame() to send RTS frames. Take sending a data frame as an example. The destination address determines whether it is broadcast or unicast. The broadcast will not use the RTS-CTS mechanism. After changing the link status, call MacDot11StationStartTransmittingPacket to send data. When unicasting, distinguish whether to use the RTS-CTS mechanism, set the delay, and then call MacDot11StationStartTransmittingPacket

static //inline//
void MacDot11StationTransmitDataFrame(
    Node* node,
    MacDataDot11* dot11)
{
    Mac802Address destAddr;
    //广播
    if (destAddr == ANY_MAC802) 
    {
        Message* dequeuedPacket;
        DOT11_FrameHdr* hdr;
        hdr = (DOT11_FrameHdr*)MESSAGE_ReturnPacket(dequeuedPacket);
        if (MacDot11IsAp(dot11) && dot11->dot11TxFrameInfo != NULL)
        {
            if (dot11->dot11TxFrameInfo->frameType == DOT11_BEACON)             
                MacDot11StationSetState(node, dot11, DOT11_X_BEACON);
            else
                MacDot11StationSetState(node, dot11, DOT11_X_BROADCAST);
        }
        else
            MacDot11StationSetState(node, dot11, DOT11_X_BROADCAST);
        MacDot11StationStartTransmittingPacket(node, dot11, dequeuedPacket,
            dot11->delayUntilSignalAirborn);
    }
    //单播/组播
    else 
    {
        clocktype transmitDelay = 0;
        DOT11_SeqNoEntry *entry;
        DOT11_FrameHdr* hdr;
        DOT11e_FrameHdr* Qhdr;
        Message* pktToPhy = MESSAGE_Duplicate(node, dot11->currentMessage);
        dot11->waitingForAckOrCtsFromAddress = destAddr;
        if (MESSAGE_ReturnPacketSize(dot11->currentMessage) > fragThreshold)
        {...}
        else 
        {
             if (hdr->frameType == DOT11_PS_POLL)                 
                MacDot11StationSetState(node, dot11, DOT11_X_PSPOLL);
             else
                MacDot11StationSetState(node, dot11, DOT11_X_UNICAST);
            //使用RTS-CTS机制
            if ((MESSAGE_ReturnPacketSize(pktToPhy)>
                dot11->rtsThreshold)&&
               (hdr->frameType != DOT11_PS_POLL))       
                transmitDelay += dot11->sifs;
            //不使用RTS-CTS机制
            else             
                transmitDelay += dot11->delayUntilSignalAirborn;
            MacDot11StationStartTransmittingPacket(node, dot11, pktToPhy, transmitDelay);
        }
    }
}

The main function of MacDot11StationStartTransmittingPacket is to obtain frame information, determine whether it is a control frame/data frame, broadcast frame/unicast frame, local frame/non-local frame, and then call the physical layer function to send the frame. 

static //inline//
void MacDot11StationStartTransmittingPacket(
    Node* node,
    MacDataDot11* dot11,
    Message* packet,
    clocktype delay)
{
    //接口未启用
    if (!MAC_InterfaceIsEnabled(node, dot11->myMacData->interfaceIndex))
    {        
        MESSAGE_Free(node, packet);        
        return;
    }
    //获取数据帧信息,判断是控制帧/数据帧,广播帧/单播帧,本地帧/非本地帧 
    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);
}

1.5 Physical layer

The function PHY_StartTransmittingSignal() in phy.cpp distinguishes the physical layer protocol and calls the corresponding protocol function respectively. Taking 802.11 as an example, the function Phy802_11StartTransmittingSignal() in phy_802_11.cpp directly calls StartTransmittingSignal, adds the header and calls the function ReleaseSignalToChannel() to send the signal to the transmission channel.

static
void StartTransmittingSignal(
    Node* node,
    int phyIndex,
    Message* packet,
    BOOL useMacLayerSpecifiedDelay,
    clocktype initDelayUntilAirborne,
    BOOL sendDirectionally,
    double azimuthAngle)
{
    //获取传输信道
    PHY_GetTransmissionChannel(node, phyIndex, &channelIndex);
    assert(phy802_11->mode != PHY_TRANSMITTING);    
    //物理层正在接收信号
    if (phy802_11->mode == PHY_RECEIVING) 
    {
        //丢弃包
         PHY_NotificationOfPacketDrop(
             node,
             phyIndex,
             channelIndex,
             phy802_11->rxMsg,
             "PHY Stop Rx for Tx",
             phy802_11->rxMsgPower_mW,
             phy802_11->interferencePower_mW,
             0.0);        
        Phy802_11UnlockSignal(phy802_11);
    }
    Phy802_11ChangeState(node, phyIndex, PHY_TRANSMITTING);

    //添加物理层首部
    Phy802_11AddPlcpHeader(node, phy802_11, packet);

    if (PHY_IsListeningToChannel(node, phyIndex, channelIndex))
    {
        PHY_StopListeningToChannel(node, phyIndex, channelIndex);
    }
    //根据传输模型,发送信号至传播信道
    if (thisPhy->antennaData->antennaModelType == ANTENNA_PATTERNED)
    {
        //全向天线
        if (!sendDirectionally) {
            ReleaseSignalToChannel(
                node,
                packet,
                phyIndex,
                channelIndex,
                phy802_11->txPower_dBm,
                duration,
                delayUntilAirborne,
                0.0);
        }
        //定向天线
        else {
            ReleaseSignalToChannel(
                node,
                packet,
                phyIndex,
                channelIndex,
                phy802_11->txPower_dBm,
                duration,
                delayUntilAirborne,
                phy802_11->directionalAntennaGain_dB);
        }
    }
    else
    {...}
    //调度结束发送事件
    endMsg = MESSAGE_Alloc(node,
                            PHY_LAYER,
                            0,
                            MSG_PHY_TransmissionEnd);
    MESSAGE_SetInstanceId(endMsg, (short) phyIndex);
    MESSAGE_Send(node, endMsg, delayUntilAirborne + duration + 1);
    phy802_11->txEndTimer = endMsg;   
}

ReleaseSignalToChannel() calls the function PROP_ReleaseSignal() to send the signal to the channel.

1.6 Communication media

The function PROP_ReleaseSignal() is declared in propagation.h, but the implementation of this function is not found. It may belong to the kernel code and cannot be read.

At this point, the signal has been delivered to the channel. When the endMsg message with the end of the delivery signal timer message is executed, the signal delivery ends and the delivery of a packet ends.

Guess you like

Origin blog.csdn.net/zhang1806618/article/details/107781895