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);}}//单播帧,回复ACKelse {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 网络层
见下文