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 网络层
见下文