QualNet收发包过程分析(四)

2. 接收端

2.1 物理层

发送断物理层有两个信号,一个是开始发送,一个是结束发送,两个信号成对出现,表示一个数据帧发送完成。接收端类似,一个开始接收,一个结束接收,两个信号成对出现,表示一个数据帧接收完成。在物理层分别由两个函数处理信号,PHY_SignalArrivalFromChannel()和PHY_SignalEndFromChannel()。前一个函数判断物理层当前状态,空闲或侦听中,则锁定信号,更改状态为接收中,开始接收;若当前状态为接收中,则丢弃准备接收的信号。第二个函数结束接收,将接收完整的数据帧向上层传递。仍以802.11协议为例

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 链路层

链路层接收到帧后,根据首部中的目的地址判断是否为传输至本地节点的帧,若不是,则丢弃;若是广播地址,则按广播帧处理;若是单播地址,则按单播帧处理。

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 单播帧处理

MacDot11ProcessMyFrame()函数处理单播帧,源代码较为繁琐,其核心要义如下:对RTS帧,回复CTS帧;对CTS帧,发送数据帧;对数据帧,处理数据帧并回复ACK帧;对ACK帧,处理ACK帧。此处以数据帧为例,调用MacDot11ProcessFrame()处理数据帧并回复ACK帧。

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 广播帧处理 

MacDot11ProcessAnyFrame()函数调用MacDot11ProcessFrame()处理广播帧。

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

广播帧和单播帧都由帧处理函数MacDot11ProcessFrame()进行处理。广播时调用MacDot11StationHandOffSuccessfullyReceivedBroadcast()处置帧,单播时调用MacDot11StationHandOffSuccessfullyReceivedUnicast()

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

无论广播帧还是单播帧,都经过一个去除链路层首部动作后,由 MAC_HandOffSuccessfullyReceivedPacket()函数调用NETWORK_ReceivePacketFromMacLayer层间通信函数向网络层传递。

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 网络层

见下文

猜你喜欢

转载自blog.csdn.net/zhang1806618/article/details/107856736
今日推荐