📄 p802_15_4mac.cc
字号:
else //Acknowledgement { assert(txPkt); if (wph->MHR_BDSN != HDR_LRWPAN(txPkt)->MHR_BDSN) i = 2; else i = 0; } if (i == 2) {#ifdef DEBUG802_15_4 fprintf(stdout,"[D][DUP][%s::%s][%f](node %d) dropping duplicated packet: type = %s, from = %d, uid = %d, mac_uid = %ld, size = %d, SN = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),ch->uid(),wph->uid,ch->size(),wph->MHR_BDSN);#endif drop(p,"DUP"); return; } //handle the beacon packet if (frmCtrl.frmType == defFrmCtrl_Type_Beacon) recvBeacon(p); //handle the ack. packet else if (frmCtrl.frmType == defFrmCtrl_Type_Ack) recvAck(p); //handle the command packet else if (frmCtrl.frmType == defFrmCtrl_Type_MacCmd) recvCommand(p); //handle the data packet else if (frmCtrl.frmType == defFrmCtrl_Type_Data) { recvData(p); } }}void Mac802_15_4::recvBeacon(Packet *p){ hdr_lrwpan* wph = HDR_LRWPAN(p); FrameCtrl frmCtrl; PendAddrSpec pendSpec; bool pending; double txtime; UINT_8 ifs; int i; //update superframe specification sfSpec2.SuperSpec = wph->MSDU_SuperSpec; sfSpec2.parse();#ifdef DEBUG802_15_4 hdr_cmn* ch = HDR_CMN(p); fprintf(stdout,"[%s::%s][%f](node %d) M_BEACON [BO:%d][SO:%d] received: from = %d, uid = %d, mac_uid = %ld, size = %d, SN = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,sfSpec2.BO,sfSpec2.SO,p802_15_4macSA(p),ch->uid(),wph->uid,ch->size(),wph->MHR_BDSN);#endif //calculate the time when we received the first bit of the beacon txtime = phy->trxTime(p); /* Linux floating number compatibility macBcnRxTime = (CURRENT_TIME - txtime) * phy->getRate('s'); */ { double tmpf; tmpf = CURRENT_TIME - txtime; macBcnRxTime = tmpf * phy->getRate('s'); } //calculate <beaconPeriods2> if (HDR_CMN(p)->size() <= aMaxSIFSFrameSize) ifs = aMinSIFSPeriod; else ifs = aMinLIFSPeriod; /* Linux floating number compatibility beaconPeriods2 = (UINT_8)((txtime * phy->getRate('s') + ifs) / aUnitBackoffPeriod); */ double tmpf; tmpf = txtime * phy->getRate('s'); tmpf += ifs; beaconPeriods2 = (UINT_8)(tmpf / aUnitBackoffPeriod); /* Linux floating number compatibility if (fmod((txtime * phy->getRate('s')+ ifs) ,aUnitBackoffPeriod) > 0.0) */ if (fmod(tmpf ,aUnitBackoffPeriod) > 0.0) beaconPeriods2++; //update PAN descriptor frmCtrl.FrmCtrl = wph->MHR_FrmCtrl; frmCtrl.parse(); panDes2.CoordAddrMode = frmCtrl.srcAddrMode; panDes2.CoordPANId = wph->MHR_SrcAddrInfo.panID; panDes2.CoordAddress_64 = wph->MHR_SrcAddrInfo.addr_64; //ok even it is a 16-bit address panDes2.LogicalChannel = wph->phyCurrentChannel; panDes2.SuperframeSpec = wph->MSDU_SuperSpec; gtsSpec2.fields = wph->MSDU_GTSFields; gtsSpec2.parse(); panDes2.GTSPermit = gtsSpec2.permit; panDes2.LinkQuality = wph->ppduLinkQuality; panDes2.TimeStamp = (UINT_32)macBcnRxTime; panDes2.SecurityUse = wph->SecurityUse; panDes2.ACLEntry = wph->ACLEntry; panDes2.SecurityFailure = false; //ignored in simulation panDes2.clusTreeDepth = wph->clusTreeDepth; //handle active and passive channel scans if ((taskP.taskStatus(TP_mlme_scan_request)) || (taskP.taskStatus(TP_mlme_rx_enable_request))) { rxBeacon = p; dispatch(p_SUCCESS,__FUNCTION__); } if ((mpib.macPANId == 0xffff) || (mpib.macPANId != panDes2.CoordPANId) || (taskP.taskStatus(TP_mlme_associate_request))) { Packet::free(p); return; } numLostBeacons = 0; nam->flashNodeMark(CURRENT_TIME); macBeaconOrder2 = sfSpec2.BO; macSuperframeOrder2 = sfSpec2.SO; //populate <macCoordShortAddress> if needed if (mpib.macCoordShortAddress == def_macCoordShortAddress) if (frmCtrl.srcAddrMode == defFrmCtrl_AddrMode16) mpib.macCoordShortAddress = wph->MHR_SrcAddrInfo.addr_16; dispatch(p_SUCCESS,__FUNCTION__); //resume extraction timer if needed extractT->resume(); //CSMA-CA may be waiting for the new beacon if (wph->MHR_SrcAddrInfo.panID == mpib.macPANId) if (backoffStatus == 99) csmaca->newBeacon('r'); //check if need to notify the upper layer if ((!mpib.macAutoRequest)||(wph->MSDU_PayloadLen > 0)) sscs->MLME_BEACON_NOTIFY_indication(wph->MHR_BDSN,&panDes2,wph->MSDU_PendAddrFields.spec,wph->MSDU_PendAddrFields.addrList,wph->MSDU_PayloadLen,wph->MSDU_Payload); if (mpib.macAutoRequest) { //handle the pending packet pendSpec.fields = wph->MSDU_PendAddrFields; pendSpec.parse(); pending = false; for (i=0;i<pendSpec.numShortAddr;i++) { if (pendSpec.fields.addrList[i] == mpib.macShortAddress) { pending = true; break; } } if (!pending) for (i=0;i<pendSpec.numExtendedAddr;i++) { if (pendSpec.fields.addrList[pendSpec.numShortAddr + i] == aExtendedAddress) { pending = true; break; } } if (pending) { //frmCtrl.FrmCtrl = wph->MHR_FrmCtrl; //frmCtrl.parse(); mlme_poll_request(frmCtrl.srcAddrMode,wph->MHR_SrcAddrInfo.panID,wph->MHR_SrcAddrInfo.addr_64,capability.secuCapable,true,true); } log(p); }}void Mac802_15_4::recvAck(Packet *p){ hdr_lrwpan *wph; hdr_cmn *ch; FrameCtrl frmCtrl; wph = HDR_LRWPAN(p); ch = HDR_CMN(p);#ifdef DEBUG802_15_4 fprintf(stdout,"[%s::%s][%f](node %d) M_ACK received: from = %d, SN = %d, uid = %d, mac_uid = %ld\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,p802_15_4macSA(p),wph->MHR_BDSN,ch->uid(),wph->uid);#endif if ((!txBcnCmd)&&(!txBcnCmd2)&&(!txData)) { Packet::free(p); return; } //check the sequence number in the ack. to see if it matches that in the <txPkt> if (wph->MHR_BDSN != HDR_LRWPAN(txPkt)->MHR_BDSN) { Packet::free(p); return; } if (txT->busy()) txT->stop(); else {#ifdef DEBUG802_15_4 fprintf(stdout,"[%s::%s][%f](node %d) LATE ACK received: from = %d, SN = %d, uid = %d, mac_uid = %ld\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,p802_15_4macSA(p),wph->MHR_BDSN,ch->uid(),wph->uid);#endif //only handle late ack. for data packet if (txPkt != txData) { Packet::free(p); return; } if (backoffStatus == 99) { backoffStatus = 0; csmaca->cancel(); } } //set pending flag for data polling if (txPkt == txBcnCmd2) if ((taskP.taskStatus(TP_mlme_poll_request)) && (strcmp(taskP.taskFrFunc(TP_mlme_poll_request),__FUNCTION__) == 0)) { frmCtrl.FrmCtrl = wph->MHR_FrmCtrl; frmCtrl.parse(); taskP.mlme_poll_request_pending = frmCtrl.frmPending; } dispatch(p_SUCCESS,__FUNCTION__); log(p);}void Mac802_15_4::recvCommand(Packet *p){ hdr_lrwpan* wph; FrameCtrl frmCtrl; bool ackReq;#ifdef DEBUG802_15_4 wph = HDR_LRWPAN(p); hdr_cmn* ch = HDR_CMN(p); fprintf(stdout,"[%s::%s][%f](node %d) %s received: from = %d, uid = %d, mac_uid = %ld, size = %d, SN = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),ch->uid(),wph->uid,ch->size(),wph->MHR_BDSN);#endif ackReq = false; switch(HDR_LRWPAN(p)->MSDU_CmdType) { case 0x01: //Association request //recv() is in charge of sending ack. //MLME-ASSOCIATE.indication() will be passed to upper layer after the transmission of ack. assert(rxCmd == 0); rxCmd = p; ackReq = true; break; case 0x02: //Association response //recv() is in charge of sending ack. //MLME-ASSOCIATE.confirm will be passed to upper layer after the transmission of ack. assert(rxCmd == 0); rxCmd = p; ackReq = true; wph = HDR_LRWPAN(p); rt_myNodeID = *((UINT_16 *)wph->MSDU_Payload);#ifdef ZigBeeIF sscs->setGetClusTreePara('g',p);#endif break; case 0x03: //Disassociation notification break; case 0x04: //Data request //recv() is in charge of sending ack. //pending packet will be sent after the transmission of ack. assert(rxCmd == 0); rxCmd = p; ackReq = true; break; case 0x05: //PAN ID conflict notification break; case 0x06: //Orphan notification wph = HDR_LRWPAN(p); sscs->MLME_ORPHAN_indication(wph->MHR_SrcAddrInfo.addr_64,false,0); break; case 0x07: //Beacon request if (capability.FFD //I am an FFD && (mpib.macAssociationPermit) //association permitted && (mpib.macShortAddress != 0xffff) //allow to send beacons && (mpib.macBeaconOrder == 15)) //non-beacon enabled mode { //send a beacon using unslotted CSMA-CA#ifdef DEBUG802_15_4 fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBcnCmd:\n\t\ttxBeacon\t= %ld\n\t\ttxAck \t= %ld\n\t\ttxBcnCmd\t= %ld\n\t\ttxBcnCmd2\t= %ld\n\t\ttxData \t= %ld\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);#endif assert(!txBcnCmd); txBcnCmd = Packet::alloc(); if (!txBcnCmd) break; wph = HDR_LRWPAN(txBcnCmd); frmCtrl.FrmCtrl = 0; frmCtrl.setFrmType(defFrmCtrl_Type_Beacon); frmCtrl.setSecu(secuBeacon); frmCtrl.setFrmPending(false); frmCtrl.setAckReq(false); frmCtrl.setDstAddrMode(defFrmCtrl_AddrModeNone); if (mpib.macShortAddress == 0xfffe) { frmCtrl.setSrcAddrMode(defFrmCtrl_AddrMode64); wph->MHR_SrcAddrInfo.panID = mpib.macPANId; wph->MHR_SrcAddrInfo.addr_64 = aExtendedAddress; } else { frmCtrl.setSrcAddrMode(defFrmCtrl_AddrMode16); wph->MHR_SrcAddrInfo.panID = mpib.macPANId; wph->MHR_SrcAddrInfo.addr_16 = mpib.macShortAddress; } sfSpec.SuperSpec = 0; sfSpec.setBO(15); sfSpec.setBLE(mpib.macBattLifeExt); sfSpec.setPANCoor(isPANCoor); sfSpec.setAssoPmt(mpib.macAssociationPermit); wph->MSDU_GTSFields.spec = 0; wph->MSDU_PendAddrFields.spec = 0; wph->MSDU_PayloadLen = 0;#ifdef ZigBeeIF sscs->setGetClusTreePara('s',txBcnCmd);#endif constructMPDU(4,txBcnCmd,frmCtrl.FrmCtrl,mpib.macBSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,sfSpec.SuperSpec,0,0); hdr_dst((char *)HDR_MAC(txBcnCmd),p802_15_4macSA(p)); hdr_src((char *)HDR_MAC(txBcnCmd),index_); HDR_CMN(txBcnCmd)->ptype() = PT_MAC; //for trace HDR_CMN(txBcnCmd)->next_hop_ = p802_15_4macDA(txBcnCmd); //nam needs the nex_hop information p802_15_4hdrBeacon(txBcnCmd); csmacaBegin('c'); } break; case 0x08: //Coordinator realignment wph = HDR_LRWPAN(p); frmCtrl.FrmCtrl = wph->MHR_FrmCtrl; frmCtrl.parse(); if (frmCtrl.dstAddrMode == defFrmCtrl_AddrMode64) //directed to an orphan device { //recv() is in charge of sending ack. //further handling continues after the transmission of ack. assert(rxCmd == 0); rxCmd = p; ackReq = true; } else //broadcasted realignment command if ((wph->MHR_SrcAddrInfo.addr_64 == macCoordExtendedAddress) && (wph->MHR_SrcAddrInfo.panID == mpib.macPANId)) { //no specification in the draft as how to handle this packet, so use our discretion mpib.macPANId = *((UINT_16 *)wph->MSDU_Payload); mpib.macCoordShortAddress = *((UINT_16 *)(wph->MSDU_Payload + 2)); tmp_ppib.phyCurrentChannel = wph->MSDU_Payload[4]; phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib); } break; case 0x09: //GTS request break; default: assert(0); break; } if (!ackReq) log(p); else log(p->refcopy());}void Mac802_15_4::recvData(Packet *p){ hdr_lrwpan* wph; hdr_cmn* ch; FrameCtrl frmCtrl; UINT_8 ifs; //pass the data packet to upper layer //(we need some time to process the packet -- so delay SIFS/LIFS symbols from now or after finishing sending the ack.) //(refer to Figure 60 for details of SIFS/LIFS) assert(rxData == 0); rxData = p; wph = HDR_LRWPAN(p); ch = HDR_CMN(p);#ifdef DEBUG802_15_4 fprintf(stdout,"[%s::%s][%f](node %d) DATA (%s) received: from = %d, uid = %d, mac_uid = %ld, size = %d, SN = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),ch->uid(),wph->uid,ch->size(),wph->MHR_BDSN);#endif frmCtrl.FrmCtrl = wph->MHR_FrmCtrl; frmCtrl.parse(); rxDataTime = CURRENT_TIME; if (!frmCtrl.ackReq) { if (ch->size() <= aMaxSIFSFrameSize) ifs = aMinSIFSPeriod; else ifs = aMinLIFSPeriod; Scheduler::instance().schedule(&IFSH, &(IFSH.nullEvent), ifs/phy->getRate('s')); } //else //schedule and dispatch after finishing ack. transmission}bool Mac802_15_4::toParent(Packet *p){ hdr_lrwpan* wph = HDR_LRWPAN(p); FrameCtrl frmCtrl; frmCtrl.FrmCtrl = wph->MHR_FrmCtrl; frmCtrl.parse(); if (((frmCtrl.dstAddrMode == defFrmCtrl_AddrMode16)&&(wph->MHR_DstAddrInfo.addr_16 == mpib.macCoordShortAddress))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -