📄 p802_15_4mac.cc
字号:
|| ((frmCtrl.dstAddrMode == defFrmCtrl_AddrMode64)&&(wph->MHR_DstAddrInfo.addr_64 == mpib.macCoordExtendedAddress))) return true; else return false;}double Mac802_15_4::locateBoundary(bool parent,double wtime){ //In the case that a node acts as both a coordinator and a device, //transmission of beacons is preferablly to be aligned with reception //of beacons to achieve the best results -- but we cannot control this. //For example, the parent may originally work in non-beacon enabled mode //and later on begin to work in beacon enabled mode; the parent will //not align with the child since it is not supposed to handle the beacons //from the child. //So the alignment is specifically w.r.t. either transmission of beacons //(as a coordinator) or reception of beacons (as a device), but there is //no guarantee to satisfy both. int align; double bcnTxRxTime,bPeriod; double newtime; if ((mpib.macBeaconOrder == 15)&&(macBeaconOrder2 == 15)) return wtime; if (parent) align = (macBeaconOrder2 == 15)?1:2; else align = (mpib.macBeaconOrder == 15)?2:1; bcnTxRxTime = (align == 1)?(macBcnTxTime / phy->getRate('s')):(macBcnRxTime / phy->getRate('s')); bPeriod = aUnitBackoffPeriod / phy->getRate('s'); /* Linux floating number compatibility newtime = fmod(CURRENT_TIME + wtime - bcnTxRxTime, bPeriod); */ { double tmpf; tmpf = CURRENT_TIME + wtime; tmpf -= bcnTxRxTime; newtime = fmod(tmpf, bPeriod); }#ifdef DEBUG802_15_4 //fprintf(stdout,"[%s::%s][%f](node %d) delay = bPeriod - fmod = %f - %f = %f\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,bPeriod,newtime,bPeriod - newtime);#endif if(newtime > 0.0) { /* Linux floating number compatibility newtime = wtime + (bPeriod - newtime); */ { double tmpf; tmpf = bPeriod - newtime; newtime = wtime + tmpf; } } else newtime = wtime; return newtime;}void Mac802_15_4::txOverHandler(void){ assert(txPkt); PD_DATA_confirm(p_UNDEFINED);}void Mac802_15_4::txHandler(void){ assert(txBcnCmd||txBcnCmd2||txData); Packet *p; hdr_lrwpan* wph; hdr_cmn* ch; UINT_8 t_numRetry; if (txBcnCmd) p = txBcnCmd; else if (txBcnCmd2) p = txBcnCmd2; else p = txData; wph = HDR_LRWPAN(p); ch = HDR_CMN(p); if (txBcnCmd) t_numRetry = numBcnCmdRetry; else if (txBcnCmd2) t_numRetry = numBcnCmdRetry2; else t_numRetry = numDataRetry; t_numRetry++;#ifdef DEBUG802_15_4 if (t_numRetry <= aMaxFrameRetries) fprintf(stdout,"[%s::%s][%f](node %d) No ACK - retransmitting: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size()); else fprintf(stdout,"[%s::%s][%f](node %d) No ACK - giving up: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());#endif if (t_numRetry > aMaxFrameRetries) nam->flashLinkFail(CURRENT_TIME,p802_15_4macDA(p)); dispatch(p_BUSY,__FUNCTION__); //the status p_BUSY will be ignore}void Mac802_15_4::extractHandler(void){ if (taskP.taskStatus(TP_mlme_associate_request)) strcpy(taskP.taskFrFunc(TP_mlme_associate_request),__FUNCTION__); dispatch(p_BUSY,__FUNCTION__);}void Mac802_15_4::assoRspWaitHandler(void){ dispatch(p_BUSY,__FUNCTION__);}void Mac802_15_4::dataWaitHandler(void){ dispatch(p_BUSY,__FUNCTION__);}void Mac802_15_4::rxEnableHandler(void){ dispatch(p_SUCCESS,__FUNCTION__);}void Mac802_15_4::scanHandler(void){ if (taskP.mlme_scan_request_ScanType == 0x01) taskP.taskStep(TP_mlme_scan_request)++; dispatch(p_SUCCESS,__FUNCTION__);}void Mac802_15_4::beaconTxHandler(bool forTX){ hdr_lrwpan* wph; FrameCtrl frmCtrl; TRANSACLINK *tmp; int i; if ((mpib.macBeaconOrder != 15) //beacon enabled || (oneMoreBeacon)) if (forTX) { if (capability.FFD/*&&(numberDeviceLink(&deviceLink1) > 0)*/) { //enable the transmitter beaconWaiting = true; plme_set_trx_state_request(p_FORCE_TRX_OFF); //finish your job before this! //assert(txAck == 0); //It's not true, for the reason that packets can arrive //at any time if the source is in non-beacon mode. //This could also happen if a device loses synchronization //with its coordinator, or if a coordinator changes beacon //order in the middle. if (txAck) {#ifdef DEBUG802_15_4 if (!updateDeviceLink(tr_oper_est, &deviceLink1, &deviceLink2, p802_15_4macDA(txAck))) //this ACK is for my child fprintf(stdout,"[%f](node %d) outgoing ACK truncated by beacon: src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n", CURRENT_TIME,index_,p802_15_4macSA(txAck),p802_15_4macDA(txAck),HDR_CMN(txAck)->uid(),HDR_LRWPAN(txAck)->uid,HDR_CMN(txAck)->size());#endif Packet::free(txAck); txAck = 0; } plme_set_trx_state_request(p_TX_ON); } else assert(0); } else { if (capability.FFD/*&&(numberDeviceLink(&deviceLink1) > 0)*/) //send a beacon here { //beaconWaiting = false; if ((taskP.taskStatus(TP_mlme_start_request)) && (mpib.macBeaconOrder != 15)) { if (txAck||backoffStatus == 1) { beaconWaiting = false; bcnTxT->start(); return; } }#ifdef DEBUG802_15_4 fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBeacon:\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 if (updateNFailLink(fl_oper_est,index_) == 0) { if (txBeacon) { Packet::free(txBeacon); txBeacon = 0; } beaconWaiting = false; bcnTxT->start(); return; } assert(!txBeacon); txBeacon = Packet::alloc(); if (!txBeacon) { bcnTxT->start(); //try to restore the transmission of beacons next time return; } wph = HDR_LRWPAN(txBeacon); frmCtrl.FrmCtrl = 0; frmCtrl.setFrmType(defFrmCtrl_Type_Beacon); frmCtrl.setSecu(secuBeacon); 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(mpib.macBeaconOrder); sfSpec.setSO(mpib.macSuperframeOrder); sfSpec.setFinCAP(aNumSuperframeSlots - 1); //TBD: may be less than <aNumSuperframeSlots> when considering GTS sfSpec.setBLE(mpib.macBattLifeExt); sfSpec.setPANCoor(isPANCoor); sfSpec.setAssoPmt(mpib.macAssociationPermit); //populate the GTS fields -- more TBD when considering GTS gtsSpec.fields.spec = 0; gtsSpec.setPermit(mpib.macGTSPermit); wph->MSDU_GTSFields = gtsSpec.fields; //--- populate the pending address list --- pendAddrSpec.numShortAddr = 0; pendAddrSpec.numExtendedAddr = 0; purgeTransacLink(&transacLink1,&transacLink2); tmp = transacLink1; i = 0; while (tmp != NULL) { if (tmp->pendAddrMode == defFrmCtrl_AddrMode16) { if (updateDeviceLink(tr_oper_est,&deviceLink1,&deviceLink2,tmp->pendAddr64) == 0) i = pendAddrSpec.addShortAddr(tmp->pendAddr16); //duplicated address filtered out } else { if (updateDeviceLink(tr_oper_est,&deviceLink1,&deviceLink2,tmp->pendAddr64) == 0) i = pendAddrSpec.addExtendedAddr(tmp->pendAddr64); //duplicated address filtered out } if (i >= 7) break; tmp = tmp->next; } pendAddrSpec.format(); wph->MSDU_PendAddrFields = pendAddrSpec.fields; frmCtrl.setFrmPending(i>0); //To populate the beacon payload field, <macBeaconPayloadLength> and <macBeaconPayload> //should be set first, in that order (use primitive MLME_SET_request). wph->MSDU_PayloadLen = mpib.macBeaconPayloadLength; memcpy(wph->MSDU_Payload,mpib.macBeaconPayload,mpib.macBeaconPayloadLength); //-----------------------------------------#ifdef ZigBeeIF sscs->setGetClusTreePara('s',txBeacon);#endif constructMPDU(2 + gtsSpec.size() + pendAddrSpec.size() + mpib.macBeaconPayloadLength,txBeacon,frmCtrl.FrmCtrl,mpib.macBSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,sfSpec.SuperSpec,0,0); hdr_src((char *)HDR_MAC(txBeacon),index_); hdr_dst((char *)HDR_MAC(txBeacon),MAC_BROADCAST); HDR_CMN(txBeacon)->ptype() = PT_MAC; HDR_CMN(txBeacon)->next_hop_ = p802_15_4macDA(txBeacon); //nam needs the nex_hop information p802_15_4hdrBeacon(txBeacon);#ifdef DEBUG802_15_4 fprintf(stdout,"[%s::%s][%f](node %d) transmit BEACON to %d: SN = %d, uid = %d, mac_uid = %ld\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,p802_15_4macDA(txBeacon),HDR_LRWPAN(txBeacon)->MHR_BDSN,HDR_CMN(txBeacon)->uid(),HDR_LRWPAN(txBeacon)->uid);#endif txPkt = txBeacon; HDR_CMN(txBeacon)->direction() = hdr_cmn::DOWN; //nam->flashNodeMark(CURRENT_TIME); sendDown(txBeacon->refcopy(), this); mpib.macBeaconTxTime = (UINT_32)(CURRENT_TIME * phy->getRate('s')); macBcnTxTime = CURRENT_TIME * phy->getRate('s'); //double used for accuracy oneMoreBeacon = false; } else assert(0); } bcnTxT->start(); //don't disable this even beacon not enabled (beacon may be temporarily disabled like in channel scan, but it will be enabled again)}void Mac802_15_4::beaconRxHandler(void){ if (macBeaconOrder2 != 15) //beacon enabled (do nothing if beacon not enabled) { if (txAck) { Packet::free(txAck); txAck = 0; } //enable the receiver plme_set_trx_state_request(p_RX_ON); if (taskP.mlme_sync_request_tracking) { //a better way is using another timer to detect <numLostBeacons> right after the header of superframe if (numLostBeacons > aMaxLostBeacons) { char label[11]; //label[0] = 0; strcpy(label,"\" \"");#ifdef ZigBeeIF if (sscs->t_isCT) sprintf(label,"\"%s\"",(sscs->RNType())?"+":"-");#endif nam->changeLabel(CURRENT_TIME,label); changeNodeColor(CURRENT_TIME,Nam802_15_4::def_Node_clr); sscs->MLME_SYNC_LOSS_indication(m_BEACON_LOSS); numLostBeacons = 0; } else { numLostBeacons++; bcnRxT->start(); } } }}void Mac802_15_4::beaconSearchHandler(void){ dispatch(p_BUSY,__FUNCTION__);}void Mac802_15_4::isPanCoor(bool isPC){ if (isPANCoor == isPC) return; if (isPC) changeNodeColor(CURRENT_TIME,Nam802_15_4::def_PANCoor_clr); else if (isPANCoor) changeNodeColor(CURRENT_TIME, (mpib.macPANId == 0xffff) ? Nam802_15_4::def_Node_clr : (mpib.macAssociationPermit) ? Nam802_15_4::def_Coor_clr : Nam802_15_4::def_Dev_clr); isPANCoor = isPC;}//-------------------------------------------------------------------------------------void Mac802_15_4::set_trx_state_request(PHYenum state,const char *frFile,const char *frFunc,int line){#ifdef DEBUG802_15_4 fprintf(stdout,"[%s::%s][%f](node %d): %s request from [%s:%s:%d]\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_, (state == p_RX_ON)?"RX_ON": (state == p_TX_ON)?"TX_ON": (state == p_TRX_OFF)?"TRX_OFF": (state == p_FORCE_TRX_OFF)?"FORCE_TRX_OFF":"???", frFile,frFunc,line);#endif trx_state_req = state; phy->PLME_SET_TRX_STATE_request(state);}char *taskName[] = {"NONE", "MCPS-DATA.request", "MLME-ASSOCIATE.request", "MLME-ASSOCIATE.response", "MLME-DISASSOCIATE.request", "MLME-ORPHAN.response", "MLME-RESET.request", "MLME-RX-ENABLE.request", "MLME-SCAN.request", "MLME-START.request", "MLME-SYNC.request", "MLME-POLL.request", "CCA_csmaca", "RX_ON_csmaca"};void Mac802_15_4::checkTaskOverflow(UINT_8 task){ //Though we assume the upper layer should know what it is doing -- should send down requests one by one. //But we'd better check again (we have no control over upper layer and we don't know who is operating on the upper layer) if (taskP.taskStatus(task)) { fprintf(stdout,"[%s::%s][%f](node %d) task overflow: %s\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,taskName[task]); exit(1); } else { taskP.taskStep(task) = 0; (taskP.taskFrFunc(task))[0] = 0; }}void Mac802_15_4::dispatch(PHYenum status,const char *frFunc,PHYenum req_state,MACenum mStatus){ hdr_lrwpan *wph; hdr_cmn *ch; FrameCtrl frmCtrl; UINT_8 ifs; int i; if (strcmp(frFunc,"csmacaCallBack") == 0) { if (txCsmaca == txBcnCmd2) { if (taskP.taskStatus(TP_mlme_scan_request) && (strcmp(taskP.taskFrFunc(TP_mlme_scan_request),frFunc) == 0)) { if ((taskP.mlme_scan_request_ScanType == 0x01) //active scan || (taskP.mlme_scan_request_ScanType == 0x03)) //orphan scan
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -