Analysis of QualNet receiving and sending packets (4)

2. Receiver

2.1 Physical layer

There are two signals in the physical layer of the transmission fault, one is to start sending and the other is to end sending. The two signals appear in pairs, indicating that a data frame is sent. The receiving end is similar, one starts to receive, one ends to receive, and the two signals appear in pairs, indicating that a data frame is received. In the physical layer, the signal is processed by two functions, PHY_SignalArrivalFromChannel() and PHY_SignalEndFromChannel(). The previous function judges the current state of the physical layer. Idle or listening, lock the signal, change the state to receiving, and start receiving; if the current state is receiving, discard the signal to be received. The second function ends the reception and passes the received complete data frame to the upper layer. Still take the 802.11 protocol as an example

void Phy802_11SignalEndFromChannel(
    Node* node,
    int phyIndex,
    int channelIndex,
    PropRxInfo *propRxInfo)
{
    PhyData *thisPhy = node->phyData[phyIndex];
    PhyData802_11* phy802_11 = (PhyData802_11*) thisPhy->phyVar;
    BOOL receiveErrorOccurred = FALSE;
    assert(phy802_11->mode != PHY_TRANSMITTING);    

    if ((phy802_11->mode == PHY_RECEIVING)
         && (phy802_11->rxMsg == propRxInfo->txMsg))
    {
        Message* newMsg = NULL; 
        Phy802_11UnlockSignal(phy802_11);
        //载波侦听,进入侦听状态
        if (Phy802_11CarrierSensing(node, phy802_11) == TRUE) 
        {
            Phy802_11ChangeState(node,phyIndex, PHY_SENSING);
        }
        //不载波侦听,进入空闲状态
        else 
        {
            Phy802_11ChangeState(node,phyIndex, PHY_IDLE);
        }

        if (!receiveErrorOccurred)
        {
            //复制消息
            newMsg = MESSAGE_Duplicate(node, propRxInfo->txMsg);
	    //去除物理层首部		
            MESSAGE_RemoveHeader(
                node, newMsg, sizeof(Phy802_11PlcpHeader), TRACE_802_11);

            PhySignalMeasurement* signalMeaInfo;
            MESSAGE_InfoAlloc(node,
                              newMsg,
                              sizeof(PhySignalMeasurement));
			
            signalMeaInfo = (PhySignalMeasurement*)
                            MESSAGE_ReturnInfo(newMsg);
            memcpy(signalMeaInfo,&sigMeasure,sizeof(PhySignalMeasurement));
            MESSAGE_SetInstanceId(newMsg, (short) phyIndex);
            phy802_11->rxDOA = propRxInfo->rxDOA;
	    //向上传递至MAC层	
            MAC_ReceivePacketFromPhy(
                node,
                node->phyData[phyIndex]->macInterfaceIndex,
                newMsg);
        }
        //接收出现错误,丢弃
        else 
        {           
            PHY_NotificationOfPacketDrop(
                node,
                phyIndex,
                channelIndex,
                propRxInfo->txMsg,
                "Signal Received with Error",
                rxMsgPower_mW,
                phy802_11->interferencePower_mW,
                propRxInfo->pathloss_dB);

        }       
    }
}

2.2 Link layer

After the link layer receives the frame, it judges whether it is a frame transmitted to the local node according to the destination address in the header, if not, it is discarded; if it is a broadcast address, it is processed as a broadcast frame; if it is a unicast address, it is a unicast frame deal with.

void MacDot11ReceivePacketFromPhy(
    Node* node,
    MacDataDot11* dot11,
    Message* msg)
{    
    DOT11_ShortControlFrame* hdr =
        (DOT11_ShortControlFrame*) MESSAGE_ReturnPacket(msg);

    //QualNet允许两个事件同时发生,但节点在发送时不能同时接收帧
    ERROR_Assert(!(MacDot11IsTransmittingState(dot11->state)||
        MacDot11IsCfpTransmittingState(dot11->cfpState)),
        "MacDot11ReceivePacketFromPhy: "
        "Cannot receive packet while in transmit state.\n");

    BOOL isMyAddr = FALSE;
    //判断目的地址是否本地地址
    if (NetworkIpIsUnnumberedInterface(
            node, dot11->myMacData->interfaceIndex))
    {
        MacHWAddress linkAddr;
        Convert802AddressToVariableHWAddress(
                                node, &linkAddr, &(hdr->destAddr));

        isMyAddr = MAC_IsMyAddress(node, &linkAddr);
    }
    else
    {
        isMyAddr = (dot11->selfAddr == hdr->destAddr);
    }
    //是传送至本地的帧
    if (isMyAddr) 
    {
        MacDot11ProcessMyFrame (node, dot11, msg);
    }
    //是广播帧
    else if (hdr->destAddr == ANY_MAC802) 
    {
        MacDot11ProcessAnyFrame (node, dot11, msg);
    }    
    else 
    {
        MESSAGE_Free(node, msg);
    }
}

2.2.1 Unicast frame processing

The MacDot11ProcessMyFrame() function processes unicast frames. The source code is more cumbersome. Its core meanings are as follows: for RTS frames, reply CTS frames; for CTS frames, send data frames; for data frames, process data frames and reply ACK frames; for ACK frames , Process the ACK frame. Here we take the data frame as an example, call MacDot11ProcessFrame() to process the data frame and reply ACK frame.

void MacDot11ProcessMyFrame(
    Node* node,
    MacDataDot11* dot11,
    Message* msg)
{
    switch (hdr->frameType) 
    {
        case DOT11_RTS: 
        {
            ...
            MacDot11StationTransmitCTSFrame(node, dot11, msg);         
            MESSAGE_Free(node, msg);
            break;
        }
        case DOT11_CTS: 
        {
            ...
            MacDot11StationTransmitDataFrame(node, dot11);        
            MESSAGE_Free(node, msg);
            break;
        }
        case DOT11_DATA:
        case DOT11_QOS_DATA:
        case DOT11_MESH_DATA:
        case DOT11_CF_DATA_ACK: 
        {
            ...
            MacDot11ProcessFrame(node, dot11, msg);
            MESSAGE_Free(node, msg);
            break;
        }
        case DOT11_ACK: 
        {            
            ...
            MacDot11StationProcessAck(node, dot11, msg);
            MESSAGE_Free(node, msg);
            break;
        }
    }           
}

2.2.2 Broadcast frame processing 

The MacDot11ProcessAnyFrame() function calls MacDot11ProcessFrame() to process the broadcast frame.

void MacDot11ProcessAnyFrame(
    Node* node,
    MacDataDot11* dot11,
    Message* msg)
{
    switch (hdr->frameType) 
    {
        case DOT11_DATA:
        case DOT11_QOS_DATA:
        case DOT11_CF_DATA_ACK: 
        {          
            MacDot11ProcessFrame(node, dot11, msg);
            MESSAGE_Free(node, msg);
            break;
        }
        case DOT11_MESH_DATA: 
        {
            MacDot11ProcessFrame(node, dot11, msg);
            MESSAGE_Free(node, msg);
            break;
        }
        case DOT11_BEACON:
        {
            MacDot11ProcessBeacon(node, dot11, msg);
            MESSAGE_Free(node, msg);
            break;
        }        
    }
}

Both broadcast frames and unicast frames are processed by the frame processing function MacDot11ProcessFrame(). Call MacDot11StationHandOffSuccessfullyReceivedBroadcast() to dispose of the frame during broadcast, and call MacDot11StationHandOffSuccessfullyReceivedUnicast() during unicast

static 
void MacDot11ProcessFrame(
    Node* node, MacDataDot11* dot11, Message *frame)
{    
    //广播帧
    if (hdr->destAddr == ANY_MAC802) 
    {            
        //成功接收到广播帧,处理
        MacDot11StationHandOffSuccessfullyReceivedBroadcast(
                node, dot11, frame);            
        if (dot11->state == DOT11_S_IDLE)
        {
            MacDot11StationCheckForOutgoingPacket(node, dot11, FALSE);
        }
    }
    //单播帧,回复ACK
    else 
    {
        MacDot11StationCancelTimer(node, dot11);
        MacDot11StationTransmitAck(node, dot11, sourceAddr);
        MacDot11StationHandOffSuccessfullyReceivedUnicast(
                    node, dot11, frame);
    }
}

Regardless of the broadcast frame or the unicast frame, after an action of removing the link layer header, the MAC_HandOffSuccessfullyReceivedPacket() function calls the NETWORK_ReceivePacketFromMacLayer inter-layer communication function to pass to the network layer.

static //inline//
void MacDot11StationHandOffSuccessfullyReceivedBroadcast(
    Node* node,
    MacDataDot11* dot11,
    Message* msg)
{
    MESSAGE_RemoveHeader(node,
                         msg,
                         sizeof(DOT11_FrameHdr),
                         TRACE_DOT11);
    MAC_HandOffSuccessfullyReceivedPacket(node,
        dot11->myMacData->interfaceIndex, msg, &sourceAddr);
}
static //inline//
void MacDot11StationHandOffSuccessfullyReceivedUnicast(
    Node* node,
    MacDataDot11* dot11,
    Message* msg)
{  
    BOOL handOff = TRUE; 
    //mesh point,mesh网络节点 
    if (dot11->isMP) 
    {
        Dot11s_ReceiveDataUnicast(node, dot11, msg);
        handOff = FALSE;
    }
    else 
    {
        MESSAGE_RemoveHeader(node,
                             msg,
                             sizeof(DOT11_FrameHdr),
                             TRACE_DOT11);
    }
    if (handOff && isAmsduMsg)
    {...}  
    else if (handOff) 
    {
        MAC_HandOffSuccessfullyReceivedPacket(node,
            dot11->myMacData->interfaceIndex, msg, &sourceAddr);
    }
}

2.3 Network layer

as follows

Guess you like

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