p802_15_4mac.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:179k
- ch = HDR_CMN(txData);
- frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
- frmCtrl.parse();
- if (frmCtrl.ackReq) //ack. required
- {
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"recvAck");
- //enable the receiver
- plme_set_trx_state_request(p_RX_ON);
- txT->start(mpib.macAckWaitDuration/phy->getRate('s'));
- waitDataAck = true;
- }
- else //assume success if ack. not required
- {
- taskP.taskStatus(task) = false;
- resetTRX();
- taskSuccess('d');
- // 2.31 change: added this to put the node to sleep after successful pkt tx
- #ifdef SHUTDOWN
- if ((em) && ((!capability.FFD)||(numberDeviceLink(&deviceLink1) == 0)) && (NOW>phy->T_sleep_)){ //I can sleep only if i am not a coordinator
- phy->putNodeToSleep();
- }
- #endif
- }
- break;
- case 3:
- if (status == p_SUCCESS) //ack. received
- {
- taskP.taskStatus(task) = false;
- resetTRX();
- taskSuccess('d');
- }
- else //time out when waiting for ack.
- {
- numDataRetry++;
- if (numDataRetry <= aMaxFrameRetries)
- {
- taskP.taskStep(task) = 1; //important
- strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
- waitDataAck = false;
- csmacaResume();
- }
- else
- {
- taskP.taskStatus(task) = false;
- resetTRX();
- taskFailed('d',m_NO_ACK);
- }
- }
- #ifdef SHUTDOWN
- if ((em) && ((!capability.FFD)||(numberDeviceLink(&deviceLink1) == 0)) && (NOW>phy->T_sleep_)){ //I can sleep only if i am not a coordinator
- phy->putNodeToSleep();
- }
- #endif
- break;
- default:
- break;
- }
- }
- }
- void Mac802_15_4::mlme_associate_request(UINT_8 LogicalChannel,UINT_8 CoordAddrMode,UINT_16 CoordPANId,IE3ADDR CoordAddress,
- UINT_8 CapabilityInformation,bool SecurityEnable,
- bool frUpper,PHYenum status,MACenum mStatus)
- {
- //refer to Figure 25 for association details
- UINT_8 step,task;
- FrameCtrl frmCtrl;
- hdr_lrwpan* wph;
- task = TP_mlme_associate_request;
- if (frUpper) checkTaskOverflow(task);
- step = taskP.taskStep(task);
- switch(step)
- {
- case 0:
- //check if parameters valid or not
- if ((!phy->channelSupported(LogicalChannel))
- || ((CoordAddrMode != defFrmCtrl_AddrMode16)&&(CoordAddrMode != defFrmCtrl_AddrMode64)))
- {
- sscs->MLME_ASSOCIATE_confirm(0,m_INVALID_PARAMETER);
- return;
- }
- //assert(mpib.macShortAddress == 0xffff); //not associated yet
- //we may optionally track beacons if beacon enabled (here we don't)
- tmp_ppib.phyCurrentChannel = LogicalChannel;
- phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
- mpib.macPANId = CoordPANId;
- mpib.macCoordExtendedAddress = CoordAddress;
- taskP.taskStatus(task) = true;
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
- taskP.mlme_associate_request_CoordAddrMode = CoordAddrMode;
- taskP.mlme_associate_request_SecurityEnable = SecurityEnable;
- //--- send an association request command ---
- #ifdef DEBUG802_15_4
- fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBcnCmd2:ntttxBeacont= %ldntttxAck t= %ldntttxBcnCmdt= %ldntttxBcnCmd2t= %ldntttxData t= %ldn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
- #endif
- assert(!txBcnCmd2);
- txBcnCmd2 = Packet::alloc();
- assert(txBcnCmd2);
- wph = HDR_LRWPAN(txBcnCmd2);
- constructCommandHeader(txBcnCmd2,&frmCtrl,0x01,CoordAddrMode,CoordPANId,CoordAddress,defFrmCtrl_AddrMode64,0xffff,aExtendedAddress,SecurityEnable,false,true);
- wph->MSDU_Payload[0] = capability.cap;
- constructMPDU(2,txBcnCmd2,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0x01,0);
- csmacaBegin('C');
- //------------------------------------
- break;
- case 1:
- if (status == p_IDLE)
- {
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"PD_DATA_confirm");
- if (Mac802_15_4::verbose)
- fprintf(stdout,"[%f](node %d) sending association request command ...n",CURRENT_TIME,index_);
- plme_set_trx_state_request(p_TX_ON);
- break;
- }
- else
- {
- taskP.taskStatus(task) = false;
- freePkt(txBcnCmd2);
- txBcnCmd2 = 0;
- //restore default values
- mpib.macPANId = def_macPANId;
- mpib.macCoordExtendedAddress = def_macCoordExtendedAddress;
- sscs->MLME_ASSOCIATE_confirm(0,m_CHANNEL_ACCESS_FAILURE);
- csmacaResume();
- return;
- }
- break;
- case 2:
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"recvAck");
- plme_set_trx_state_request(p_RX_ON); //waiting for ack.
- txT->start(mpib.macAckWaitDuration/phy->getRate('s'));
- waitBcnCmdAck2 = true;
- break;
- case 3:
- if (status == p_SUCCESS) //ack. received
- {
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"extractHandler");
- plme_set_trx_state_request(p_TRX_OFF); //we don't want to receive any packet at this moment
- if (Mac802_15_4::verbose)
- fprintf(stdout,"[%f](node %d) ack for association request command receivedn",CURRENT_TIME,index_);
- taskSuccess('C',false);
- extractT->start(aResponseWaitTime/phy->getRate('s'),false);
- }
- else //time out when waiting for ack.
- {
- numBcnCmdRetry2++;
- if (numBcnCmdRetry2 <= aMaxFrameRetries)
- {
- taskP.taskStep(task) = 1; //important
- strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
- waitBcnCmdAck2 = false;
- csmacaResume();
- }
- else
- {
- taskP.taskStatus(task) = false;
- resetTRX();
- freePkt(txBcnCmd2);
- txBcnCmd2 = 0;
- //restore default values
- mpib.macPANId = def_macPANId;
- mpib.macCoordExtendedAddress = def_macCoordExtendedAddress;
- sscs->MLME_ASSOCIATE_confirm(0,m_NO_ACK);
- csmacaResume();
- return;
- }
- }
- break;
- case 4:
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"PD_DATA_confirm");
- //-- send a data request command to extract the response ---
- #ifdef DEBUG802_15_4
- fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBcnCmd2:ntttxBeacont= %ldntttxAck t= %ldntttxBcnCmdt= %ldntttxBcnCmd2t= %ldntttxData t= %ldn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
- #endif
- assert(!txBcnCmd2);
- txBcnCmd2 = Packet::alloc();
- assert(txBcnCmd2);
- wph = HDR_LRWPAN(txBcnCmd2);
- if ((mpib.macShortAddress == 0xfffe)||(mpib.macShortAddress == 0xffff))
- {
- frmCtrl.setSrcAddrMode(defFrmCtrl_AddrMode64);
- wph->MHR_SrcAddrInfo.addr_64 = aExtendedAddress;
- }
- else
- {
- frmCtrl.setSrcAddrMode(defFrmCtrl_AddrMode16);
- wph->MHR_SrcAddrInfo.addr_16 = mpib.macShortAddress;
- }
- constructCommandHeader(txBcnCmd2,&frmCtrl,0x04,taskP.mlme_associate_request_CoordAddrMode,mpib.macPANId,mpib.macCoordExtendedAddress,frmCtrl.srcAddrMode,mpib.macPANId,wph->MHR_SrcAddrInfo.addr_64,SecurityEnable,false,true);
- constructMPDU(1,txBcnCmd2,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0x04,0);
- waitBcnCmdAck2 = false; //command packet not yet transmitted
- numBcnCmdRetry2 = 0;
- if (Mac802_15_4::verbose)
- fprintf(stdout,"[%f](node %d) sending data request command ...n",CURRENT_TIME,index_);
- txCsmaca = txBcnCmd2;
- plme_set_trx_state_request(p_TX_ON);
- //------------------------------------
- break;
- case 5:
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"recvAck");
- //enable the receiver
- plme_set_trx_state_request(p_RX_ON);
- txT->start(mpib.macAckWaitDuration/phy->getRate('s'));
- waitBcnCmdAck2 = true;
- break;
- case 6:
- if (status == p_SUCCESS) //ack. received
- {
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"IFSHandler");
- plme_set_trx_state_request(p_RX_ON); //wait for response
- if (Mac802_15_4::verbose)
- fprintf(stdout,"[%f](node %d) ack for data request command receivedn",CURRENT_TIME,index_);
- taskSuccess('C',false);
- extractT->start(aResponseWaitTime/phy->getRate('s'),false); //compare: for normal data, wait for <aMaxFrameResponseTime> symbols (or CAP symbols if beacon enabled) (see page 156, line 1-3)
- }
- else //time out when waiting for ack.
- {
- //No retransmission required in general (just wait for next beacon and poll again, see page 156, line 20-24),
- //but we need to retransmit here, since the node will not handle the pending list before it has associated
- //with the coordinator.
- numBcnCmdRetry2++;
- if (numBcnCmdRetry2 <= aMaxFrameRetries)
- {
- taskP.taskStep(task) = 5; //important
- strcpy(taskP.taskFrFunc(task),"PD_DATA_confirm");
- waitBcnCmdAck2 = false;
- txCsmaca = txBcnCmd2;
- plme_set_trx_state_request(p_TX_ON);
- }
- else
- {
- taskP.taskStatus(task) = false;
- resetTRX();
- freePkt(txBcnCmd2);
- txBcnCmd2 = 0;
- //restore default values
- mpib.macPANId = def_macPANId;
- mpib.macCoordExtendedAddress = def_macCoordExtendedAddress;
- sscs->MLME_ASSOCIATE_confirm(0,m_NO_DATA); //assume no DATA
- csmacaResume();
- return;
- }
- }
- break;
- case 7:
- taskP.taskStatus(task) = false;
- resetTRX();
- if (status == p_SUCCESS) //response received
- {
- if (mStatus == m_SUCCESS)
- {
- changeNodeColor(CURRENT_TIME,(mpib.macAssociationPermit)?Nam802_15_4::def_Coor_clr:Nam802_15_4::def_Dev_clr);
- char label[31];
- sprintf(label,"[%d]",mpib.macCoordExtendedAddress);
- #ifdef ZigBeeIF
- if (sscs->t_isCT)
- sprintf(label,""%s%d (%d.%d)"",(sscs->RNType())?"+":"-",rt_myNodeID,sscs->rt_myParentNodeID,sscs->rt_myDepth);
- #endif
- nam->changeLabel(CURRENT_TIME,label);
- }
- else
- {
- //restore default values
- mpib.macPANId = def_macPANId;
- mpib.macCoordExtendedAddress = def_macCoordExtendedAddress;
- }
- //stop the timer
- if (Mac802_15_4::verbose)
- fprintf(stdout,"[%f](node %d) association response command receivedn",CURRENT_TIME,index_);
- extractT->stop();
- sscs->MLME_ASSOCIATE_confirm(rt_myNodeID,mStatus);
- }
- else //time out when waiting for response
- {
- //restore default values
- mpib.macPANId = def_macPANId;
- mpib.macCoordExtendedAddress = def_macCoordExtendedAddress;
- sscs->MLME_ASSOCIATE_confirm(0,m_NO_DATA);
- }
- csmacaResume();
- default:
- break;
- }
- }
- void Mac802_15_4::mlme_associate_response(IE3ADDR DeviceAddress,UINT_16 AssocShortAddress,MACenum Status,bool SecurityEnable,
- bool frUpper,PHYenum status)
- {
- FrameCtrl frmCtrl;
- hdr_lrwpan* wph;
- Packet *rspPkt;
- double kpTime;
- UINT_8 step,task;
- int i;
- task = TP_mlme_associate_response;
- //checkTaskOverflow(task);
- if (frUpper)
- {
- if (taskP.taskStatus(task)) //overflow
- {
- sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,DeviceAddress,m_TRANSACTION_OVERFLOW);
- return;
- }
- taskP.taskStep(task) = 0;
- (taskP.taskFrFunc(task))[0] = 0;
- }
- step = taskP.taskStep(task);
- switch(step)
- {
- case 0:
- //check if parameters valid or not
- if ((Status != m_SUCCESS)&&(Status != m_PAN_at_capacity)&&(Status != m_PAN_access_denied))
- {
- sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,DeviceAddress,m_INVALID_PARAMETER);
- return;
- }
- taskP.taskStatus(task) = true;
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
- taskP.mlme_associate_response_DeviceAddress = DeviceAddress;
- //--- construct an association response command packet and put it in the pending list ---
- rspPkt = Packet::alloc();
- assert(rspPkt);
- wph = HDR_LRWPAN(rspPkt);
- #ifdef ZigBeeIF
- sscs->setGetClusTreePara('s',rspPkt);
- #endif
- constructCommandHeader(rspPkt,&frmCtrl,0x02,defFrmCtrl_AddrMode64,mpib.macPANId,DeviceAddress,defFrmCtrl_AddrMode64,mpib.macPANId,aExtendedAddress,SecurityEnable,false,true);
- *((UINT_16 *)wph->MSDU_Payload) = AssocShortAddress;
- *((MACenum *)(wph->MSDU_Payload + 2)) = Status;
- constructMPDU(4,rspPkt,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0x02,0);
- kpTime = (2 * aResponseWaitTime) / phy->getRate('s');
- i = chkAddTransacLink(&transacLink1,&transacLink2,defFrmCtrl_AddrMode64,DeviceAddress,rspPkt,0,kpTime);
- if (i != 0) //overflow or failed
- {
- #ifdef DEBUG802_15_4
- hdr_cmn *ch = HDR_CMN(rspPkt);
- fprintf(stdout,"[%s::%s][%f](node %d) task overflow or failed: type = %s, src = %d, dst = %d, uid = %d, mac_uid = ??, size = %dn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(rspPkt),p802_15_4macSA(rspPkt),p802_15_4macDA(rspPkt),wph->uid,ch->size());
- #endif
- taskP.taskStatus(task) = false;
- Packet::free(rspPkt);
- sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,DeviceAddress,m_TRANSACTION_OVERFLOW);
- return;
- }
- //----------------------------------------------------------------------
- assoRspWaitT->start(kpTime);
- taskP.mlme_associate_response_pendPkt = rspPkt;
- break;
- case 1:
- if (!taskP.taskStatus(task))
- break;
- taskP.taskStatus(task) = false;
- assoRspWaitT->stop();
- if (status == p_SUCCESS) //response packet transmitted and ack. received
- {
- sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,DeviceAddress,m_SUCCESS);
- taskSuccess('c');
- }
- else //response packet transmission failed
- {
- //be careful, we use MACenum to return the status, either CHANNEL_ACCESS_FAILURE or NO_ACK
- sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,DeviceAddress,Status);
- freePkt(txBcnCmd);
- txBcnCmd = 0;
- }
- break;
- case 2:
- if (!taskP.taskStatus(task))
- break;
- taskP.taskStatus(task) = false;
- //check if the transaction still pending -- actually no need to check (it must be pending if case 1 didn't happen), but no harm
- i = updateTransacLinkByPktOrHandle(tr_oper_est,&transacLink1,&transacLink2,taskP.mlme_associate_response_pendPkt); //don't use <txBcnCmd>, since assignment 'txBcnCmd = rspPkt' only happens if a data request command received
- if (i == 0) //still pending
- {
- //delete the packet from the transaction list immediately -- prevent the packet from being transmitted at the last moment
- updateTransacLinkByPktOrHandle(tr_oper_del,&transacLink1,&transacLink2,taskP.mlme_associate_response_pendPkt);
- sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,DeviceAddress,m_TRANSACTION_EXPIRED);
- return;
- }
- else //being successfully extracted
- {
- sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,DeviceAddress,m_SUCCESS);
- return;
- }
- break;
- default:
- break;
- }
- }
- void Mac802_15_4::mlme_disassociate_request(IE3ADDR DeviceAddress,UINT_8 DisassociateReason,bool SecurityEnable,bool frUpper,PHYenum status)
- {
- /*
- FrameCtrl frmCtrl;
- hdr_lrwpan* wph;
- double kpTime;
- UINT_8 step,task;
- int i;
- task = TP_mlme_disassociate_request;
- if (frUpper) checkTaskOverflow(task);
- step = taskP.taskStep(task);
- switch(step)
- {
- case 0:
- //check if parameters valid or not
- if (DeviceAddress != mpib.macCoordExtendedAddress) //send to a device
- if ((!capability.FFD)||(numberDeviceLink(&deviceLink1) == 0)) //I am not a coordinator
- {
- sscs->MLME_DISASSOCIATE_confirm(m_INVALID_PARAMETER);
- return;
- }
- taskP.mlme_disassociate_request_toCoor = (DeviceAddress == mpib.macCoordExtendedAddress);
- //--- construct a disassociation notification command packet ---
- #ifdef DEBUG802_15_4
- fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBcnCmd2:ntttxBeacont= %ldntttxAck t= %ldntttxBcnCmdt= %ldntttxBcnCmd2t= %ldntttxData t= %ldn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
- #endif
- assert(!txBcnCmd2);
- txBcnCmd2 = Packet::alloc();
- assert(txBcnCmd2);
- wph = HDR_LRWPAN(txBcnCmd2);
- if (!taskP.mlme_disassociate_request_toCoor)
- wph->MHR_DstAddrInfo.addr_64 = DeviceAddress;
- else
- wph->MHR_DstAddrInfo.addr_64 = mpib.macCoordExtendedAddress;
- constructCommandHeader(txBcnCmd2,&frmCtrl,0x03,defFrmCtrl_AddrMode64,mpib.macPANId,wph->MHR_DstAddrInfo.addr_64,defFrmCtrl_AddrMode64,mpib.macPANId,aExtendedAddress,SecurityEnable,false,true);
- *((UINT_8 *)wph->MSDU_Payload) = (taskP.mlme_disassociate_request_toCoor)?0x02:0x01;
- constructMPDU(2,txBcnCmd2,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0x03,0);
- //----------------------------------------------------------------------
- taskP.taskStatus(task) = true;
- taskP.taskStep(task)++;
- taskP.mlme_disassociate_request_pendPkt = txBcnCmd2;
- if (!taskP.mlme_disassociate_request_toCoor) //indirect transmission should be used
- {
- // Linux floating number compatibility
- //kpTime = mpib.macTransactionPersistenceTime * (aBaseSuperframeDuration * (1 << mpib.macBeaconOrder) / phy->getRate('s'));
- {
- double tmpf;
- tmpf = (aBaseSuperframeDuration * (1 << mpib.macBeaconOrder) / phy->getRate('s'));
- kpTime = mpib.macTransactionPersistenceTime * tmpf;
- }
- i = chkAddTransacLink(&transacLink1,&transacLink2,defFrmCtrl_AddrMode64,wph->MHR_DstAddrInfo.addr_64,txBcnCmd2,0,kpTime);
- if (i != 0) //overflow or failed
- {
- taskP.taskStatus(task) = false;
- Packet::free(txBcnCmd2);
- txBcnCmd2 = 0;
- sscs->MLME_DISASSOCIATE_confirm(m_TRANSACTION_OVERFLOW);
- return;
- }
- extractT->start(kpTime,false);
- }
- else
- csmacaBegin('C');
- break;
- case 1:
- if (!taskP.mlme_disassociate_request_toCoor) //indirect transmission
- {
- //check if the transaction still pending
- wph = HDR_LRWPAN(txBcnCmd2);
- i = updateTransacLinkByPktOrHandle(tr_oper_est,&transacLink1,&transacLink2,taskP.mlme_disassociate_request_pendPkt); //don't use <txBcnCmd2>, since it may be null if a data request command not received
- if (i == 0) //still pending
- {
- //delete the packet from the transaction list immediately -- prevent the packet from being transmitted at the last moment
- updateTransacLinkByPktOrHandle(tr_oper_del,&transacLink1,&transacLink2,taskP.mlme_disassociate_request_pendPkt);
- taskP.taskStatus(task) = false;
- sscs->MLME_DISASSOCIATE_confirm(m_TRANSACTION_EXPIRED);
- return;
- }
- else //being successfully extracted
- {
- taskP.taskStatus(task) = false;
- sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,DeviceAddress,m_SUCCESS);
- return;
- }
- }
- else
- {
- }
- break;
- default:
- break;
- }
- */
- }
- void Mac802_15_4::mlme_orphan_response(IE3ADDR OrphanAddress,UINT_16 ShortAddress,bool AssociatedMember,bool SecurityEnable,bool frUpper,PHYenum status)
- {
- hdr_lrwpan* wph;
- FrameCtrl frmCtrl;
- //UINT_8 step;
- UINT_8 task;
- task = TP_mlme_orphan_response;
- if (frUpper) checkTaskOverflow(task);
-
- switch(taskP.taskStep(task))
- {
- case 0:
- if (AssociatedMember)
- {
- //send a coordinator realignment command
- #ifdef DEBUG802_15_4
- fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBcnCmd:ntttxBeacont= %ldntttxAck t= %ldntttxBcnCmdt= %ldntttxBcnCmd2t= %ldntttxData t= %ldn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
- #endif
- taskP.taskStatus(task) = true;
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
- taskP.mlme_orphan_response_OrphanAddress = OrphanAddress;
- assert(!txBcnCmd);
- txBcnCmd = Packet::alloc();
- assert(txBcnCmd);
- wph = HDR_LRWPAN(txBcnCmd);
- constructCommandHeader(txBcnCmd,&frmCtrl,0x08,defFrmCtrl_AddrMode64,0xffff,OrphanAddress,defFrmCtrl_AddrMode64,mpib.macPANId,aExtendedAddress,SecurityEnable,false,true);
- *((UINT_16 *)wph->MSDU_Payload) = mpib.macPANId;
- *((UINT_16 *)wph->MSDU_Payload + 2) = mpib.macShortAddress;
- phy->PLME_GET_request(phyCurrentChannel);
- *((UINT_8 *)wph->MSDU_Payload + 4) = tmp_ppib.phyCurrentChannel;
- *((UINT_16 *)wph->MSDU_Payload + 5) = ShortAddress;
- constructMPDU(8,txBcnCmd,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0x08,0);
- csmacaBegin('c');
- }
- break;
- case 1:
- taskP.taskStatus(task) = false;
- if (status == p_SUCCESS) //response packet transmitted and ack. received
- {
- sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,OrphanAddress,m_SUCCESS);
- taskSuccess('c');
- }
- else //response packet transmission failed
- {
- sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,OrphanAddress,m_CHANNEL_ACCESS_FAILURE);
- freePkt(txBcnCmd);
- txBcnCmd = 0;
- csmacaResume(); //other packets may be waiting
- }
- break;
- default:
- break;
- }
- }
- void Mac802_15_4::mlme_reset_request(bool SetDefaultPIB,bool frUpper,PHYenum status)
- {
- //UINT_8 step;
- UINT_8 task;
- task = TP_mlme_reset_request;
- if (frUpper) checkTaskOverflow(task);
- switch(taskP.taskStep(task))
- {
- case 0:
- taskP.taskStatus(task) = true;
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"PLME_SET_TRX_STATE_confirm");
- taskP.mlme_reset_request_SetDefaultPIB = SetDefaultPIB;
- {plme_set_trx_state_request(p_TRX_OFF);}
- break;
- case 1:
- taskP.taskStatus(task) = false;
- init(true);
- if (SetDefaultPIB)
- mpib = MPIB;
- if (status == p_TRX_OFF)
- sscs->MLME_RESET_confirm(m_SUCCESS);
- else
- sscs->MLME_RESET_confirm(m_DISABLE_TRX_FAILURE);
- break;
- default:
- break;
- }
- }
- void Mac802_15_4::mlme_rx_enable_request(bool DeferPermit,UINT_32 RxOnTime,UINT_32 RxOnDuration,bool frUpper,PHYenum status)
- {
- UINT_8 step,task;
- UINT_32 t_CAP;
- double cutTime,tmpf;
- task = TP_mlme_rx_enable_request;
- if (frUpper) checkTaskOverflow(task);
- step = taskP.taskStep(task);
- if (step == 0)
- if (RxOnDuration == 0)
- {
- sscs->MLME_RX_ENABLE_confirm(m_SUCCESS);
- plme_set_trx_state_request(p_TRX_OFF);
- return;
- }
-
- if (macBeaconOrder2 != 15) //beacon enabled
- {
- switch(step)
- {
- case 0:
- taskP.mlme_rx_enable_request_RxOnTime = RxOnTime;
- taskP.mlme_rx_enable_request_RxOnDuration = RxOnDuration;
- if (RxOnTime + RxOnDuration >= sfSpec2.BI)
- {
- sscs->MLME_RX_ENABLE_confirm(m_INVALID_PARAMETER);
- return;
- }
- t_CAP = (sfSpec2.FinCAP + 1) * sfSpec2.sd;
- /* Linux floating number compatibility
- */
- tmpf = CURRENT_TIME * phy->getRate('s');
- if ((RxOnTime - aTurnaroundTime) > t_CAP)
- {
- sscs->MLME_RX_ENABLE_confirm(m_OUT_OF_CAP);
- return;
- }
- /* Linux floating number compatibility
- else if ((CURRENT_TIME * phy->getRate('s') - macBcnRxTime) < (RxOnTime - aTurnaroundTime))
- */
- else if ((tmpf - macBcnRxTime) < (RxOnTime - aTurnaroundTime))
- {
- //can proceed in current superframe
- taskP.taskStatus(task) = true;
- taskP.taskStep(task)++;
- //just fall through case 1
- }
- else if (DeferPermit)
- {
- //need to defer until next superframe
- taskP.taskStatus(task) = true;
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"recvBeacon");
- break;
- }
- else
- {
- sscs->MLME_RX_ENABLE_confirm(m_OUT_OF_CAP);
- return;
- }
- case 1:
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"rxEnableHandler");
- /* Linux floating number compatibility
- rxEnableT->start(RxOnTime / phy->getRate('s') - (CURRENT_TIME - macBcnRxTime / phy->getRate('s')));
- */
- {
- double tmpf2;
- tmpf = macBcnRxTime / phy->getRate('s');
- tmpf = CURRENT_TIME - tmpf;
- tmpf2 = RxOnTime / phy->getRate('s');
- tmpf = tmpf2 - tmpf;
- rxEnableT->start(tmpf);
- }
- break;
- case 2:
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"PLME_SET_TRX_STATE_confirm");
- taskP.mlme_rx_enable_request_currentTime = CURRENT_TIME;
- plme_set_trx_state_request(p_RX_ON);
- break;
- case 3:
- taskP.taskStatus(task) = false;
- strcpy(taskP.taskFrFunc(task),"rxEnableHandler");
- taskP.taskStep(task)++;
- if (status == p_TX_ON)
- sscs->MLME_RX_ENABLE_confirm(m_TX_ACTIVE);
- else
- sscs->MLME_RX_ENABLE_confirm(m_SUCCESS);
- //turn off the receiver before the CFP so as not to disturb it, and we see no reason to turn it on again after the CFP (i.e., inactive port of the superframe)
- t_CAP = (sfSpec2.FinCAP + 1) * sfSpec2.sd;
- cutTime = (RxOnTime + RxOnDuration - t_CAP) / phy->getRate('s');
- /* Linux floating number compatibility
- rxEnableT->start(RxOnDuration / phy->getRate('s') - (CURRENT_TIME - taskP.mlme_rx_enable_request_currentTime) - cutTime);
- */
- {
- tmpf = RxOnDuration / phy->getRate('s');
- tmpf -= CURRENT_TIME;
- tmpf += taskP.mlme_rx_enable_request_currentTime;
- tmpf -= cutTime;
- rxEnableT->start(tmpf);
- }
- break;
- case 4:
- strcpy(taskP.taskFrFunc(task),"");
- plme_set_trx_state_request(p_TRX_OFF);
- break;
- default:
- break;
- }
- }
- else
- {
- switch(step)
- {
- case 0:
- taskP.taskStatus(task) = true;
- strcpy(taskP.taskFrFunc(task),"PLME_SET_TRX_STATE_confirm");
- taskP.taskStep(task)++;
- taskP.mlme_rx_enable_request_RxOnDuration = RxOnDuration;
- taskP.mlme_rx_enable_request_currentTime = CURRENT_TIME;
- plme_set_trx_state_request(p_RX_ON);
- break;
- case 1:
- taskP.taskStatus(task) = false;
- strcpy(taskP.taskFrFunc(task),"rxEnableHandler");
- taskP.taskStep(task)++;
- if (status == p_TX_ON)
- sscs->MLME_RX_ENABLE_confirm(m_TX_ACTIVE);
- else
- sscs->MLME_RX_ENABLE_confirm(m_SUCCESS);
- /* Linux floating number compatibility
- rxEnableT->start(RxOnDuration / phy->getRate('s') - (CURRENT_TIME - taskP.mlme_rx_enable_request_currentTime));
- */
- {
- tmpf = RxOnDuration / phy->getRate('s');
- tmpf -= CURRENT_TIME;
- tmpf += taskP.mlme_rx_enable_request_currentTime;
- rxEnableT->start(tmpf);
- }
- break;
- case 2:
- strcpy(taskP.taskFrFunc(task),"");
- plme_set_trx_state_request(p_TRX_OFF);
- break;
- default:
- break;
- }
- }
- }
- void Mac802_15_4::mlme_scan_request(UINT_8 ScanType,UINT_32 ScanChannels,UINT_8 ScanDuration,bool frUpper,PHYenum status)
- {
- UINT_32 t_chanPos;
- UINT_8 step,task;
- FrameCtrl frmCtrl;
- hdr_lrwpan* wph;
- int i;
- task = TP_mlme_scan_request;
- if (frUpper) checkTaskOverflow(task);
- step = taskP.taskStep(task);
- if (step == 0)
- {
- if ((ScanType > 3)
- ||((ScanType != 3)&&(ScanDuration > 14)))
- {
- sscs->MLME_SCAN_confirm(m_INVALID_PARAMETER,ScanType,ScanChannels,0,NULL,NULL);
- return;
- }
- //disable the beacon
- taskP.mlme_scan_request_orig_macBeaconOrder = mpib.macBeaconOrder;
- taskP.mlme_scan_request_orig_macBeaconOrder2 = macBeaconOrder2;
- taskP.mlme_scan_request_orig_macBeaconOrder3 = macBeaconOrder3;
- mpib.macBeaconOrder = 15;
- macBeaconOrder2 = 15;
- macBeaconOrder3 = 15;
- //stop the CSMA-CA if it is running
- if (backoffStatus == 99)
- {
- backoffStatus = 0;
- csmaca->cancel();
- }
- taskP.mlme_scan_request_ScanType = ScanType;
- }
- if (ScanType == 0x00) //ED scan
- switch (step)
- {
- case 0:
- phy->PLME_GET_request(phyChannelsSupported); //value will be returned in tmp_ppib
- taskP.mlme_scan_request_ScanChannels = ScanChannels;
- if ((taskP.mlme_scan_request_ScanChannels & tmp_ppib.phyChannelsSupported) == 0)
- {
- //restore the beacon order
- mpib.macBeaconOrder = taskP.mlme_scan_request_orig_macBeaconOrder;
- macBeaconOrder2 = taskP.mlme_scan_request_orig_macBeaconOrder2;
- macBeaconOrder3 = taskP.mlme_scan_request_orig_macBeaconOrder3;
- sscs->MLME_SCAN_confirm(m_SUCCESS,ScanType,ScanChannels,0,NULL,NULL); //SUCCESS or INVALID_PARAMETER?
- csmacaResume();
- return;
- }
- taskP.taskStatus(task) = true;
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"PLME_SET_confirm");
- taskP.mlme_scan_request_CurrentChannel = 0;
- taskP.mlme_scan_request_ListNum = 0;
- t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
- while((t_chanPos & taskP.mlme_scan_request_ScanChannels) == 0
- ||(t_chanPos & tmp_ppib.phyChannelsSupported) == 0)
- {
- taskP.mlme_scan_request_CurrentChannel++;
- t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
- }
- tmp_ppib.phyCurrentChannel = taskP.mlme_scan_request_CurrentChannel;
- phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
- break;
- case 1:
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"PLME_SET_TRX_STATE_confirm");
- {plme_set_trx_state_request(p_RX_ON);}
- break;
- case 2:
- if (status == p_RX_ON)
- {
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"PLME_ED_confirm");
- phy->PLME_ED_request();
- break;
- }
- //else //fall through case 4
- case 3:
- if (step == 3) //note that case 2 needs to fall through case 4 via here
- {
- if (status == p_SUCCESS)
- {
- t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
- taskP.mlme_scan_request_ScanChannels &= (t_chanPos^0xffffffff);
- taskP.mlme_scan_request_EnergyDetectList[taskP.mlme_scan_request_ListNum] = energyLevel;
- taskP.mlme_scan_request_ListNum++;
- }
- }
- //fall through
- case 4:
- if ((taskP.mlme_scan_request_ScanChannels & tmp_ppib.phyChannelsSupported) == 0)
- {
- //restore the beacon order
- mpib.macBeaconOrder = taskP.mlme_scan_request_orig_macBeaconOrder;
- macBeaconOrder2 = taskP.mlme_scan_request_orig_macBeaconOrder2;
- macBeaconOrder3 = taskP.mlme_scan_request_orig_macBeaconOrder3;
- taskP.taskStatus(task) = false;
- sscs->MLME_SCAN_confirm(m_SUCCESS,ScanType,taskP.mlme_scan_request_ScanChannels,taskP.mlme_scan_request_ListNum,taskP.mlme_scan_request_EnergyDetectList,NULL);
- csmacaResume();
- return;
- }
- taskP.taskStep(task) = 1; //important
- strcpy(taskP.taskFrFunc(task),"PLME_SET_confirm");
- taskP.mlme_scan_request_CurrentChannel++;
- t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
- while((t_chanPos & taskP.mlme_scan_request_ScanChannels) == 0
- ||(t_chanPos & tmp_ppib.phyChannelsSupported) == 0)
- {
- taskP.mlme_scan_request_CurrentChannel++;
- t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
- }
- tmp_ppib.phyCurrentChannel = taskP.mlme_scan_request_CurrentChannel;
- phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
- break;
- default:
- break;
- }
- else if ((ScanType == 0x01) //active scan
- || (ScanType == 0x02)) //passive scan
- switch (step)
- {
- case 0:
- phy->PLME_GET_request(phyChannelsSupported); //value will be returned in tmp_ppib
- taskP.mlme_scan_request_ScanChannels = ScanChannels;
- if ((taskP.mlme_scan_request_ScanChannels & tmp_ppib.phyChannelsSupported) == 0)
- {
- mpib.macBeaconOrder = taskP.mlme_scan_request_orig_macBeaconOrder;
- macBeaconOrder2 = taskP.mlme_scan_request_orig_macBeaconOrder2;
- macBeaconOrder3 = taskP.mlme_scan_request_orig_macBeaconOrder3;
- sscs->MLME_SCAN_confirm(m_SUCCESS,ScanType,ScanChannels,0,NULL,NULL); //SUCCESS or INVALID_PARAMETER?
- csmacaResume();
- return;
- }
- taskP.taskStatus(task) = true;
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"PLME_SET_confirm");
- taskP.mlme_scan_request_orig_macPANId = mpib.macPANId;
- mpib.macPANId = 0xffff;
- taskP.mlme_scan_request_ScanDuration = ScanDuration;
- taskP.mlme_scan_request_CurrentChannel = 0;
- taskP.mlme_scan_request_ListNum = 0;
- t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
- while((t_chanPos & taskP.mlme_scan_request_ScanChannels) == 0
- ||(t_chanPos & tmp_ppib.phyChannelsSupported) == 0)
- {
- taskP.mlme_scan_request_CurrentChannel++;
- t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
- }
- tmp_ppib.phyCurrentChannel = taskP.mlme_scan_request_CurrentChannel;
- phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
- break;
- case 1:
- if (Mac802_15_4::verbose)
- fprintf(stdout,"[%f](node %d) scanning channel %dn",CURRENT_TIME,index_,taskP.mlme_scan_request_CurrentChannel);
- if (ScanType == 0x01) //active scan
- {
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
- //--- send a beacon request command ---
- #ifdef DEBUG802_15_4
- fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBcnCmd2:ntttxBeacont= %ldntttxAck t= %ldntttxBcnCmdt= %ldntttxBcnCmd2t= %ldntttxData t= %ldn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
- #endif
- assert(!txBcnCmd2);
- txBcnCmd2 = Packet::alloc();
- assert(txBcnCmd2);
- wph = HDR_LRWPAN(txBcnCmd2);
- constructCommandHeader(txBcnCmd2,&frmCtrl,0x07,defFrmCtrl_AddrMode16,0xffff,0xffff,defFrmCtrl_AddrModeNone,0,0,false,false,false);
- constructMPDU(1,txBcnCmd2,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0x07,0);
- csmacaBegin('C');
- //------------------------------------
- }
- else
- {
- taskP.taskStep(task) = 4; //skip the steps only for active scan
- strcpy(taskP.taskFrFunc(task),"PLME_SET_TRX_STATE_confirm");
- plme_set_trx_state_request(p_RX_ON);
- }
- break;
- case 2:
- if (status == p_IDLE)
- {
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"PD_DATA_confirm");
- plme_set_trx_state_request(p_TX_ON);
- break;
- }
- else
- {
- freePkt(txBcnCmd2); //actually we can keep <txBcnCmd2> for next channel
- txBcnCmd2 = 0;
- //fall through case 7
- }
- case 3:
- if (step == 3)
- {
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"PLME_SET_TRX_STATE_confirm");
- taskSuccess('C',false);
- plme_set_trx_state_request(p_RX_ON);
- break;
- }
- case 4:
- if (step == 4)
- {
- if (status == p_RX_ON)
- {
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"recvBeacon");
- //schedule for next channel
- scanT->start((aBaseSuperframeDuration * ((1 << taskP.mlme_scan_request_ScanDuration) + 1)) / phy->getRate('s'));
- break;
- }
- //else //fall through case 7
- }
- case 5:
- if (step == 5)
- {
- //beacon received
- //record the PAN descriptor if it is a new one
- assert(rxBeacon);
- wph = HDR_LRWPAN(rxBeacon);
- frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
- frmCtrl.parse();
- for (i=0;i<taskP.mlme_scan_request_ListNum;i++)
- if ((taskP.mlme_scan_request_PANDescriptorList[i].LogicalChannel == taskP.mlme_scan_request_CurrentChannel)
- && (taskP.mlme_scan_request_PANDescriptorList[i].CoordAddrMode == frmCtrl.srcAddrMode)
- && (taskP.mlme_scan_request_PANDescriptorList[i].CoordPANId == wph->MHR_SrcAddrInfo.panID) //but (page 146, line 4-5) implies not checking PAN ID
- && (((frmCtrl.srcAddrMode == defFrmCtrl_AddrMode16)&&(taskP.mlme_scan_request_PANDescriptorList[i].CoordAddress_16 == (wph->MHR_SrcAddrInfo.addr_16))
- ||((frmCtrl.srcAddrMode == defFrmCtrl_AddrMode64)&&(taskP.mlme_scan_request_PANDescriptorList[i].CoordAddress_64 == wph->MHR_SrcAddrInfo.addr_64)))))
- break;
- if (i >= taskP.mlme_scan_request_ListNum) //unique beacon
- {
- taskP.mlme_scan_request_PANDescriptorList[taskP.mlme_scan_request_ListNum] = panDes2;
- taskP.mlme_scan_request_ListNum++;
- if (taskP.mlme_scan_request_ListNum >= 27)
- {
- //stop the timer
- scanT->stop();
- //fall through case 7
- }
- else
- break;
- }
- else
- break;
- }
- case 6:
- if (step == 6)
- {
- t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
- taskP.mlme_scan_request_ScanChannels &= (t_chanPos^0xffffffff);
- //fall through case 7
- }
- case 7:
- if (((taskP.mlme_scan_request_ScanChannels & tmp_ppib.phyChannelsSupported) == 0)
- ||(taskP.mlme_scan_request_ListNum >= 27))
- {
- mpib.macPANId = taskP.mlme_scan_request_orig_macPANId;
- mpib.macBeaconOrder = taskP.mlme_scan_request_orig_macBeaconOrder;
- macBeaconOrder2 = taskP.mlme_scan_request_orig_macBeaconOrder2;
- macBeaconOrder3 = taskP.mlme_scan_request_orig_macBeaconOrder3;
- taskP.taskStatus(task) = false;
- sscs->MLME_SCAN_confirm(m_SUCCESS,ScanType,taskP.mlme_scan_request_ScanChannels,taskP.mlme_scan_request_ListNum,NULL,taskP.mlme_scan_request_PANDescriptorList);
- csmacaResume();
- return;
- }
- taskP.taskStep(task) = 1; //important
- strcpy(taskP.taskFrFunc(task),"PLME_SET_confirm");
- taskP.mlme_scan_request_CurrentChannel++;
- t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
- while((t_chanPos & taskP.mlme_scan_request_ScanChannels) == 0
- ||(t_chanPos & tmp_ppib.phyChannelsSupported) == 0)
- {
- taskP.mlme_scan_request_CurrentChannel++;
- t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
- }
- tmp_ppib.phyCurrentChannel = taskP.mlme_scan_request_CurrentChannel;
- phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
- break;
- default:
- break;
- }
- else //if (ScanType == 0x03) //orphan scan
- switch (step)
- {
- case 0:
- phy->PLME_GET_request(phyChannelsSupported); //value will be returned in tmp_ppib
- taskP.mlme_scan_request_ScanChannels = ScanChannels;
- if ((taskP.mlme_scan_request_ScanChannels & tmp_ppib.phyChannelsSupported) == 0)
- {
- mpib.macBeaconOrder = taskP.mlme_scan_request_orig_macBeaconOrder;
- //macBeaconOrder2 = taskP.mlme_scan_request_orig_macBeaconOrder2;
- macBeaconOrder2 = 15;
- macBeaconOrder3 = taskP.mlme_scan_request_orig_macBeaconOrder3;
- sscs->MLME_SCAN_confirm(m_INVALID_PARAMETER,ScanType,ScanChannels,0,NULL,NULL);
- csmacaResume();
- return;
- }
- taskP.taskStatus(task) = true;
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"PLME_SET_confirm");
- taskP.mlme_scan_request_CurrentChannel = 0;
- t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
- while((t_chanPos & taskP.mlme_scan_request_ScanChannels) == 0
- ||(t_chanPos & tmp_ppib.phyChannelsSupported) == 0)
- {
- taskP.mlme_scan_request_CurrentChannel++;
- t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
- }
- tmp_ppib.phyCurrentChannel = taskP.mlme_scan_request_CurrentChannel;
- phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
- break;
- case 1:
- if (Mac802_15_4::verbose)
- fprintf(stdout,"[%f](node %d) orphan-scanning channel %dn",CURRENT_TIME,index_,taskP.mlme_scan_request_CurrentChannel);
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
- //--- send an orphan notification command ---
- #ifdef DEBUG802_15_4
- fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBcnCmd2:ntttxBeacont= %ldntttxAck t= %ldntttxBcnCmdt= %ldntttxBcnCmd2t= %ldntttxData t= %ldn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
- #endif
- assert(!txBcnCmd2);
- txBcnCmd2 = Packet::alloc();
- assert(txBcnCmd2);
- wph = HDR_LRWPAN(txBcnCmd2);
- constructCommandHeader(txBcnCmd2,&frmCtrl,0x06,defFrmCtrl_AddrMode64,mpib.macPANId,mpib.macCoordExtendedAddress,defFrmCtrl_AddrMode64,mpib.macPANId,aExtendedAddress,false,false,false);
- constructMPDU(1,txBcnCmd2,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0x06,0);
- csmacaBegin('C');
- //------------------------------------
- break;
- case 2:
- if (status == p_IDLE)
- {
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"PD_DATA_confirm");
- plme_set_trx_state_request(p_TX_ON);
- break;
- }
- else
- {
- freePkt(txBcnCmd2);
- txBcnCmd2 = 0;
- //fall through case 6
- }
- case 3:
- if (step == 3)
- {
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"PLME_SET_TRX_STATE_confirm");
- taskSuccess('C',false);
- plme_set_trx_state_request(p_RX_ON);
- break;
- }
- case 4:
- if (step == 4)
- {
- if (status == p_RX_ON)
- {
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"IFSHandler");
- scanT->start(aResponseWaitTime / phy->getRate('s'));
- break;
- }
- //else //fall through case 6
- }
- case 5:
- if (step == 5)
- {
- if (status == p_SUCCESS) //coordinator realignment command received
- {
- scanT->stop();
- mpib.macBeaconOrder = taskP.mlme_scan_request_orig_macBeaconOrder;
- macBeaconOrder2 = taskP.mlme_scan_request_orig_macBeaconOrder2;
- macBeaconOrder3 = taskP.mlme_scan_request_orig_macBeaconOrder3;
- taskP.taskStatus(task) = false;
- changeNodeColor(CURRENT_TIME,(mpib.macAssociationPermit)?Nam802_15_4::def_Coor_clr:Nam802_15_4::def_Dev_clr);
- t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
- taskP.mlme_scan_request_ScanChannels &= (t_chanPos^0xffffffff);
- sscs->MLME_SCAN_confirm(m_SUCCESS,ScanType,taskP.mlme_scan_request_ScanChannels,0,NULL,NULL);
- csmacaResume();
- break;
- }
- else //time out
- {
- t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
- taskP.mlme_scan_request_ScanChannels &= (t_chanPos^0xffffffff);
- //fall through case 6
- }
- }
- case 6:
- if ((taskP.mlme_scan_request_ScanChannels & tmp_ppib.phyChannelsSupported) == 0)
- {
- mpib.macBeaconOrder = taskP.mlme_scan_request_orig_macBeaconOrder;
- //macBeaconOrder2 = taskP.mlme_scan_request_orig_macBeaconOrder2;
- macBeaconOrder2 = 15;
- macBeaconOrder3 = taskP.mlme_scan_request_orig_macBeaconOrder3;
- taskP.taskStatus(task) = false;
- sscs->MLME_SCAN_confirm(m_NO_BEACON,ScanType,taskP.mlme_scan_request_ScanChannels,0,NULL,NULL);
- csmacaResume();
- return;
- }
- taskP.taskStep(task) = 1; //important
- strcpy(taskP.taskFrFunc(task),"PLME_SET_confirm");
- taskP.mlme_scan_request_CurrentChannel++;
- t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
- while((t_chanPos & taskP.mlme_scan_request_ScanChannels) == 0
- ||(t_chanPos & tmp_ppib.phyChannelsSupported) == 0)
- {
- taskP.mlme_scan_request_CurrentChannel++;
- t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
- }
- tmp_ppib.phyCurrentChannel = taskP.mlme_scan_request_CurrentChannel;
- phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
- break;
- default:
- break;
- }
- }
- void Mac802_15_4::mlme_start_request(UINT_16 PANId,UINT_8 LogicalChannel,UINT_8 BeaconOrder,
- UINT_8 SuperframeOrder,bool PANCoordinator,bool BatteryLifeExtension,
- bool CoordRealignment,bool SecurityEnable,
- bool frUpper,PHYenum status)
- {
- FrameCtrl frmCtrl;
- hdr_lrwpan* wph;
- UINT_8 origBeaconOrder;
- UINT_8 step,task;
- task = TP_mlme_start_request;
- if (frUpper) checkTaskOverflow(task);
- step = taskP.taskStep(task);
- switch (step)
- {
- case 0:
- if (mpib.macShortAddress == 0xffff)
- {
- sscs->MLME_START_confirm(m_NO_SHORT_ADDRESS);
- return;
- }
- else if ((!phy->channelSupported(LogicalChannel))
- || (BeaconOrder > 15)
- || ((SuperframeOrder > BeaconOrder)&&(SuperframeOrder != 15)))
- {
- sscs->MLME_START_confirm(m_INVALID_PARAMETER);
- return;
- }
- else if (!capability.FFD)
- {
- sscs->MLME_START_confirm(m_UNDEFINED);
- return;
- }
- taskP.taskStatus(task) = true;
- if (CoordRealignment) //send a realignment command before changing configuration that affects the command
- {
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
- //broadcast a realignment command
- #ifdef DEBUG802_15_4
- fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBcnCmd2:ntttxBeacont= %ldntttxAck t= %ldntttxBcnCmdt= %ldntttxBcnCmd2t= %ldntttxData t= %ldn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
- #endif
- assert(!txBcnCmd2);
- txBcnCmd2 = Packet::alloc();
- assert(txBcnCmd2);
- wph = HDR_LRWPAN(txBcnCmd2);
- constructCommandHeader(txBcnCmd2,&frmCtrl,0x08,defFrmCtrl_AddrMode16,0xffff,0xffff,defFrmCtrl_AddrMode64,mpib.macPANId,aExtendedAddress,false,false,false);
- //--- payload (refer to Figure 56) ---
- wph->MSDU_PayloadLen = 7;
- *((UINT_16 *)wph->MSDU_Payload) = PANId; //PAN identifier
- *((UINT_16 *)(wph->MSDU_Payload + 2)) = mpib.macShortAddress; //Coor. short address
- wph->MSDU_Payload[4] = LogicalChannel; //Logical channel
- *((UINT_16 *)(wph->MSDU_Payload + 5)) = 0xffff; //short address; be the assigned address if directed to an orphaned device
- constructMPDU(8,txBcnCmd2,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0x08,0);
- csmacaBegin('C');
- //------------------------------------
- //change the configuration and begin to transmit beacons after the transmission of the realignment command
- taskP.mlme_start_request_BeaconOrder = BeaconOrder;
- taskP.mlme_start_request_SuperframeOrder = SuperframeOrder;
- taskP.mlme_start_request_BatteryLifeExtension = BatteryLifeExtension;
- taskP.mlme_start_request_SecurityEnable = SecurityEnable;
- taskP.mlme_start_request_PANCoordinator = PANCoordinator;
- taskP.mlme_start_request_PANId = PANId;
- taskP.mlme_start_request_LogicalChannel = LogicalChannel;
- break;
- }
- else
- {
- taskP.taskStep(task) = 2;
- step = 2;
- //fall through case 2
- }
- case 1:
- if (step == 1)
- {
- if (status == p_IDLE)
- {
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"PD_DATA_confirm");
- plme_set_trx_state_request(p_TX_ON);
- break;
- }
- else
- {
- freePkt(txBcnCmd2); //actually we can keep <txBcnCmd2> for next channel
- txBcnCmd2 = 0;
- //fall through case case 2 -- ignore the failure and continue to transmit beacons
- taskP.taskStep(task) = 2;
- }
- }
- case 2:
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"PD_DATA_confirm"); //for beacon
- resetTRX();
- if (CoordRealignment)
- taskSuccess('C',false);
- //change the configuration
- origBeaconOrder = mpib.macBeaconOrder;
- mpib.macBeaconOrder = BeaconOrder;
- if (BeaconOrder == 15)
- mpib.macSuperframeOrder = 15;
- else
- mpib.macSuperframeOrder = SuperframeOrder;
- mpib.macBattLifeExt = BatteryLifeExtension;
- secuBeacon = SecurityEnable;
- if (isPANCoor != PANCoordinator)
- changeNodeColor(CURRENT_TIME,PANCoordinator?Nam802_15_4::def_PANCoor_clr:Nam802_15_4::def_Coor_clr);
- isPANCoor = PANCoordinator;
- if (PANCoordinator)
- {
- mpib.macPANId = PANId;
- mpib.macCoordExtendedAddress = aExtendedAddress; //I'm the coordinator of myself
- tmp_ppib.phyCurrentChannel = LogicalChannel;
- phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
- }
- if (origBeaconOrder == BeaconOrder)
- {
- taskP.taskStatus(task) = false;
- sscs->MLME_START_confirm(m_SUCCESS);
- csmacaResume();
- }
- else if ((origBeaconOrder == 15)&&(BeaconOrder < 15))
- {
- //transmit beacon immediately
- if (bcnTxT->busy()) //the timer may still be looping there
- bcnTxT->stop();
- bcnTxT->start(true,true,0.0);
- }
- else if ((origBeaconOrder < 15)&&(BeaconOrder == 15))
- oneMoreBeacon = true;
- break;
- case 3:
- taskP.taskStatus(task) = false;
- sscs->MLME_START_confirm(m_SUCCESS);
- taskSuccess('b');
- break;
- default:
- break;
- }
- }
- void Mac802_15_4::mlme_sync_request(UINT_8 LogicalChannel, bool TrackBeacon,bool frUpper,PHYenum status)
- {
- UINT_8 step,task,BO;
- task = TP_mlme_sync_request;
- if (frUpper)
- {
- //checkTaskOverflow(task); //overlapping allowed
- //stop the beacon receiving timer if it is running
- if (bcnRxT->busy())
- bcnRxT->stop();
- taskP.taskStep(task) = 0;
- (taskP.taskFrFunc(task))[0] = 0;
- }
- step = taskP.taskStep(task);
- switch(step)
- {
- case 0:
- //no validation check required in the draft, but it's better to check it
- if ((!phy->channelSupported(LogicalChannel)) //channel not supported
- || (mpib.macPANId == 0xffff) //broadcast PAN ID
- //|| (macBeaconOrder2 == 15) //non-beacon mode or <macBeaconOrder2> not yet populated
- )
- {
- sscs->MLME_SYNC_LOSS_indication(m_UNDEFINED);
- return;
- }
- taskP.taskStatus(task) = true;
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"recvBeacon");
- taskP.mlme_sync_request_numSearchRetry = 0;
- taskP.mlme_sync_request_tracking = TrackBeacon;
- //set current channel
- tmp_ppib.phyCurrentChannel = LogicalChannel;
- phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
- //enable the receiver
- {plme_set_trx_state_request(p_RX_ON);}
- BO = (macBeaconOrder2 == 15)?14:macBeaconOrder2;
- if (bcnSearchT->busy())
- bcnSearchT->stop();
- bcnSearchT->start(aBaseSuperframeDuration*((1 << BO)+1) / phy->getRate('s'));
- break;
- case 1:
- if (status == p_SUCCESS) //beacon received
- {
- //no confirm primitive for the success - it's better to have one
- taskP.taskStatus(task) = false;
- //continue to track the beacon if required
- if (TrackBeacon)
- {
- //reset <numSearchRetry> (so that tracking can work properly)
- taskP.mlme_sync_request_numSearchRetry = 0;
- if(!bcnRxT->busy())
- bcnRxT->start();
- }
- csmacaResume();
- }
- else //time out when waiting for beacon
- {
- taskP.mlme_sync_request_numSearchRetry++;
- if (taskP.mlme_sync_request_numSearchRetry <= aMaxLostBeacons)
- {
- plme_set_trx_state_request(p_RX_ON);
- BO = (macBeaconOrder2 == 15)?14:macBeaconOrder2;
- bcnSearchT->start(aBaseSuperframeDuration*((1 << BO)+1) / phy->getRate('s'));
- }
- else
- {
- taskP.taskStatus(task) = false;
- changeNodeColor(CURRENT_TIME,Nam802_15_4::def_Node_clr);
- sscs->MLME_SYNC_LOSS_indication(m_BEACON_LOSS);
- /*If the initial beacon location fails, no need to track the beacon even it is required
- *Note that not tracking does not mean the device will not be able to receive beacons --
- *but the reception may be not so reliable since there is no synchronization.
- */
- taskP.mlme_sync_request_tracking = false;
- csmacaResume();
- return;
- }
- }
- break;
- default:
- break;
- }
- }
- void Mac802_15_4::mlme_poll_request(UINT_8 CoordAddrMode,UINT_16 CoordPANId,IE3ADDR CoordAddress,bool SecurityEnable,
- bool autoRequest,bool firstTime,PHYenum status)
- {
- UINT_8 step,task;
- FrameCtrl frmCtrl;
- hdr_lrwpan* wph;
- task = TP_mlme_poll_request;
- if (firstTime)
- {
- if (taskP.taskStatus(task))
- return;
- else
- {
- taskP.taskStep(task) = 0;
- (taskP.taskFrFunc(task))[0] = 0;
- }
- }
- step = taskP.taskStep(task);
- switch(step)
- {
- case 0:
- //check if parameters valid or not
- if (((CoordAddrMode != defFrmCtrl_AddrMode16)&&(CoordAddrMode != defFrmCtrl_AddrMode64))
- || (CoordPANId == 0xffff))
- {
- if (!autoRequest)
- sscs->MLME_POLL_confirm(m_INVALID_PARAMETER);
- return;
- }
- taskP.taskStatus(task) = true;
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
- taskP.mlme_poll_request_CoordAddrMode = CoordAddrMode;
- taskP.mlme_poll_request_CoordPANId = CoordPANId;
- taskP.mlme_poll_request_CoordAddress = CoordAddress;
- taskP.mlme_poll_request_SecurityEnable = SecurityEnable;
- taskP.mlme_poll_request_autoRequest = autoRequest;
- //-- send a data request command ---
- #ifdef DEBUG802_15_4
- fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBcnCmd2:ntttxBeacont= %ldntttxAck t= %ldntttxBcnCmdt= %ldntttxBcnCmd2t= %ldntttxData t= %ldn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
- #endif
- assert(!txBcnCmd2);
- txBcnCmd2 = Packet::alloc();
- assert(txBcnCmd2);
- wph = HDR_LRWPAN(txBcnCmd2);
- if ((mpib.macShortAddress == 0xfffe)||(mpib.macShortAddress == 0xffff))
- {
- frmCtrl.setSrcAddrMode(defFrmCtrl_AddrMode64);
- wph->MHR_SrcAddrInfo.addr_64 = aExtendedAddress;
- }
- else
- {
- frmCtrl.setSrcAddrMode(defFrmCtrl_AddrMode16);
- wph->MHR_SrcAddrInfo.addr_16 = mpib.macShortAddress;
- }
- if (sfSpec2.PANCoor)
- frmCtrl.setDstAddrMode(defFrmCtrl_AddrModeNone);
- else
- frmCtrl.setDstAddrMode(CoordAddrMode);
- constructCommandHeader(txBcnCmd2,&frmCtrl,0x04,frmCtrl.dstAddrMode,CoordPANId,CoordAddress,frmCtrl.srcAddrMode,mpib.macPANId,wph->MHR_SrcAddrInfo.addr_64,SecurityEnable,false,true);
- constructMPDU(1,txBcnCmd2,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0x04,0);
- csmacaBegin('C');
- //------------------------------------
- break;
- case 1:
- if (status == p_IDLE)
- {
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"PD_DATA_confirm");
- plme_set_trx_state_request(p_TX_ON);
- break;
- }
- else
- {
- taskP.taskStatus(task) = false;
- if (!autoRequest)
- sscs->MLME_POLL_confirm(m_CHANNEL_ACCESS_FAILURE);
- resetTRX();
- taskFailed('C',m_CHANNEL_ACCESS_FAILURE);
- return;
- }
- break;
- case 2:
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"recvAck");
- //enable the receiver
- plme_set_trx_state_request(p_RX_ON);
- txT->start(mpib.macAckWaitDuration/phy->getRate('s'));
- waitBcnCmdAck2 = true;
- break;
- case 3:
- if (status == p_SUCCESS) //ack. received
- {
- if (!taskP.mlme_poll_request_pending)
- {
- taskP.taskStatus(task) = false;
- if (!autoRequest)
- sscs->MLME_POLL_confirm(m_NO_DATA);
- resetTRX();
- taskSuccess('C');
- return;
- }
- else
- {
- taskP.taskStep(task)++;
- strcpy(taskP.taskFrFunc(task),"IFSHandler");
- plme_set_trx_state_request(p_RX_ON); //wait for data
- taskSuccess('C',false);
- extractT->start(aMaxFrameResponseTime/phy->getRate('s'),true); //wait for <aMaxFrameResponseTime> symbols (or CAP symbols if beacon enabled) (see page 156, line 1-3)
- }
- }
- else //time out when waiting for ack.
- {
- numBcnCmdRetry2++;
- if (numBcnCmdRetry2 <= aMaxFrameRetries)
- {
- taskP.taskStep(task) = 1; //important
- strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
- waitBcnCmdAck2 = false;
- csmacaResume();
- }
- else
- {
- taskP.taskStatus(task) = false;
- if (!autoRequest)
- sscs->MLME_POLL_confirm(m_NO_ACK);
- resetTRX();
- taskFailed('C',m_NO_ACK);
- return;
- }
- }
- break;
- case 4:
- taskP.taskStatus(task) = false;
- if (status == p_SUCCESS) //data received
- {
- //stop the timer
- extractT->stop();
- if (!autoRequest)
- sscs->MLME_POLL_confirm(m_SUCCESS);
- //another step is to issue DATA.indication() which has been done in IFSHandler()
- //poll again to see if there are more packets pending -- note that, for each poll request, more than one confirm could be passed to upper layer
- mlme_poll_request(CoordAddrMode,CoordPANId,CoordAddress,SecurityEnable,autoRequest,true);
- }
- else //time out when waiting for response
- {
- if (!autoRequest)
- sscs->MLME_POLL_confirm(m_NO_DATA);
- resetTRX();
- csmacaResume();
- }
- break;
- default:
- break;
- }
- }
- //-------------------------------------------------------------------------------------
- void Mac802_15_4::csmacaBegin(char pktType)
- {
- if (pktType == 'c') //txBcnCmd
- {
- waitBcnCmdAck = false; //beacon packet not yet transmitted
- numBcnCmdRetry = 0;
- if (backoffStatus == 99) //backoffing for data packet
- {
- backoffStatus = 0;
- csmaca->cancel();
- }
- csmacaResume();
- }
- else if (pktType == 'C') //txBcnCmd2
- {
- waitBcnCmdAck2 = false; //command packet not yet transmitted
- numBcnCmdRetry2 = 0;
- if ((backoffStatus == 99)&&(txCsmaca != txBcnCmd)) //backoffing for data packet
- {
- backoffStatus = 0;
- csmaca->cancel();
- }
- csmacaResume();
- }
- else //if (pktType == 'd') //txData
- {
- waitDataAck = false; //data packet not yet transmitted
- numDataRetry = 0;
- csmacaResume();
- }
- }
- void Mac802_15_4::csmacaResume(void)
- {
- FrameCtrl frmCtrl;
- if ((backoffStatus != 99) //not during backoff
- && (!inTransmission)) //not during transmission
- if ((txBcnCmd)&&(!waitBcnCmdAck))
- {
- backoffStatus = 99;
- frmCtrl.FrmCtrl = HDR_LRWPAN(txBcnCmd)->MHR_FrmCtrl;
- frmCtrl.parse();
- txCsmaca = txBcnCmd;
- csmaca->start(true,txBcnCmd,frmCtrl.ackReq);
- }
- else if ((txBcnCmd2)&&(!waitBcnCmdAck2))
- {
- backoffStatus = 99;
- frmCtrl.FrmCtrl = HDR_LRWPAN(txBcnCmd2)->MHR_FrmCtrl;
- frmCtrl.parse();
- txCsmaca = txBcnCmd2;
- csmaca->start(true,txBcnCmd2,frmCtrl.ackReq);
- }
- else if ((txData)&&(!waitDataAck))
- {
- strcpy(taskP.taskFrFunc(TP_mcps_data_request),"csmacaCallBack"); //the transmission may be interrupted and need to backoff again
- taskP.taskStep(TP_mcps_data_request) = 1; //also set the step
- backoffStatus = 99;
- frmCtrl.FrmCtrl = HDR_LRWPAN(txData)->MHR_FrmCtrl;
- frmCtrl.parse();
- txCsmaca = txData;
- csmaca->start(true,txData,frmCtrl.ackReq);
- }
- }
- void Mac802_15_4::csmacaCallBack(PHYenum status)
- {
- if (((!txBcnCmd)||(waitBcnCmdAck))
- &&((!txBcnCmd2)||(waitBcnCmdAck2))
- &&((!txData)||(waitDataAck)))
- return;
- backoffStatus = (status == p_IDLE)?1:2;
- #ifdef DEBUG802_15_4
- hdr_cmn *ch = HDR_CMN(txCsmaca);
- if (status != p_IDLE)
- fprintf(stdout,"[%s::%s][%f](node %d) backoff failed: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %dn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(txCsmaca),p802_15_4macSA(txCsmaca),p802_15_4macDA(txCsmaca),ch->uid(),HDR_LRWPAN(txCsmaca)->uid,ch->size());
- #endif
-
- dispatch(status,__FUNCTION__);
- }
- int Mac802_15_4::getBattLifeExtSlotNum(void)
- {
- phy->PLME_GET_request(phyCurrentChannel);
- return (tmp_ppib.phyCurrentChannel<=10)?8:6;
- }
- double Mac802_15_4::getCAP(bool small)
- {
- double bcnTxTime,bcnRxTime,bcnOtherRxTime,bPeriod;
- double sSlotDuration,sSlotDuration2,sSlotDuration3,BI2,BI3,t_CAP,t_CAP2,t_CAP3;
- double now,oneDay,tmpf;
-
- now = CURRENT_TIME;
- oneDay = now + 24.0*3600;
- if ((mpib.macBeaconOrder == 15)&&(macBeaconOrder2 == 15) //non-beacon enabled
- &&(macBeaconOrder3 == 15)) //no beacons from outside PAN
- return oneDay; //transmission can always go ahead
-
- bcnTxTime = macBcnTxTime / phy->getRate('s');
- bcnRxTime = macBcnRxTime / phy->getRate('s');
- bcnOtherRxTime = macBcnOtherRxTime / phy->getRate('s');
- bPeriod = aUnitBackoffPeriod / phy->getRate('s');
- sSlotDuration = sfSpec.sd / phy->getRate('s');
- sSlotDuration2 = sfSpec2.sd / phy->getRate('s');
- sSlotDuration3 = sfSpec3.sd / phy->getRate('s');
- BI2 = (sfSpec2.BI / phy->getRate('s'));
- BI3 = (sfSpec3.BI / phy->getRate('s'));
- if (mpib.macBeaconOrder != 15)
- {
- if (sfSpec.BLE)
- {
- /* Linux floating number compatibility
- t_CAP = (bcnTxTime + (beaconPeriods + getBattLifeExtSlotNum()) * aUnitBackoffPeriod);
- */
- {
- tmpf = (beaconPeriods + getBattLifeExtSlotNum()) * aUnitBackoffPeriod;
- t_CAP = bcnTxTime + tmpf;
- }
- }
- else
- {
- /* Linux floating number compatibility
- t_CAP = (bcnTxTime + (sfSpec.FinCAP + 1) * sSlotDuration);
- */
- {
- tmpf = (sfSpec.FinCAP + 1) * sSlotDuration;
- t_CAP = bcnTxTime + tmpf;
- }
- }
- }
- if (macBeaconOrder2 != 15)
- {
- if (sfSpec2.BLE)
- {
- /* Linux floating number compatibility
- t_CAP2 = (bcnRxTime + (beaconPeriods2 + getBattLifeExtSlotNum()) * aUnitBackoffPeriod);
- */
- {
- tmpf = (beaconPeriods2 + getBattLifeExtSlotNum()) * aUnitBackoffPeriod;
- t_CAP2 = bcnRxTime + tmpf;
- }
- }
- else
- {
- /* Linux floating number compatibility
- t_CAP2 = (bcnRxTime + (sfSpec2.FinCAP + 1) * sSlotDuration2);
- */
- {
- tmpf = (sfSpec2.FinCAP + 1) * sSlotDuration2;
- t_CAP2 = bcnRxTime + tmpf;
- }
- }
- /* Linux floating number compatibility
- if ((t_CAP2 < now)&&(t_CAP2 + aMaxLostBeacons * BI2 >= now))
- */
- tmpf = aMaxLostBeacons * BI2;
- if ((t_CAP2 < now)&&(t_CAP2 + tmpf >= now)) //no more than <aMaxLostBeacons> beacons missed
- while (t_CAP2 < now)
- t_CAP2 += BI2;
- }
- if (macBeaconOrder3 != 15)
- {
- //no need to handle option <macBattLifeExt> here
- /* Linux floating number compatibility
- t_CAP3 = (bcnOtherRxTime + (sfSpec3.FinCAP + 1) * sSlotDuration3);
- */
- {
- tmpf = (sfSpec3.FinCAP + 1) * sSlotDuration3;
- t_CAP3 = bcnOtherRxTime + tmpf;
- }
- /* Linux floating number compatibility
- if ((t_CAP3 < now)&&(t_CAP3 + aMaxLostBeacons * BI3 >= now))
- */
- tmpf = aMaxLostBeacons * BI3;
- if ((t_CAP3 < now)&&(t_CAP3 + tmpf >= now)) //no more than <aMaxLostBeacons> beacons missed
- while (t_CAP3 < now)
- t_CAP3 += BI3;
- }
- if ((mpib.macBeaconOrder == 15)&&(macBeaconOrder2 == 15))
- {
- if (t_CAP3 >= now)
- return t_CAP3;
- else
- return oneDay;
- }
- else if (mpib.macBeaconOrder == 15)
- {
- if (t_CAP2 >= now)
- return t_CAP2;
- else
- return oneDay;
- }
- else if (macBeaconOrder2 == 15)
- {
- if (t_CAP >= now)
- return t_CAP;
- else
- return oneDay;
- }
- else
- {
- if (t_CAP2 < now)
- return t_CAP;
- if ((small)
- && (t_CAP > t_CAP2))
- t_CAP = t_CAP2;
- if ((!small)
- && (t_CAP < t_CAP2))
- t_CAP = t_CAP2;
- return t_CAP;
- }
- }
- double Mac802_15_4::getCAPbyType(int type)
- {
- double bcnTxTime,bcnRxTime,bcnOtherRxTime,bPeriod;
- double sSlotDuration,sSlotDuration2,sSlotDuration3,BI2,BI3,t_CAP,t_CAP2,t_CAP3;
- double now,oneDay,tmpf;
-
- now = CURRENT_TIME;
- oneDay = now + 24.0*3600;
- if ((mpib.macBeaconOrder == 15)&&(macBeaconOrder2 == 15) //non-beacon enabled
- &&(macBeaconOrder3 == 15)) //no beacons from outside PAN
- return oneDay; //transmission can always go ahead
-
- bcnTxTime = macBcnTxTime / phy->getRate('s');
- bcnRxTime = macBcnRxTime / phy->getRate('s');
- bcnOtherRxTime = macBcnOtherRxTime / phy->getRate('s');
- bPeriod = aUnitBackoffPeriod / phy->getRate('s');
- sSlotDuration = sfSpec.sd / phy->getRate('s');
- sSlotDuration2 = sfSpec2.sd / phy->getRate('s');
- sSlotDuration3 = sfSpec3.sd / phy->getRate('s');
- BI2 = (sfSpec2.BI / phy->getRate('s'));
- BI3 = (sfSpec3.BI / phy->getRate('s'));
- if (type == 1)
- if (mpib.macBeaconOrder != 15)
- {
- if (sfSpec.BLE)
- {
- /* Linux floating number compatibility
- t_CAP = (bcnTxTime + (beaconPeriods + getBattLifeExtSlotNum()) * aUnitBackoffPeriod);
- */
- {
- tmpf = (beaconPeriods + getBattLifeExtSlotNum()) * aUnitBackoffPeriod;
- t_CAP = bcnTxTime + tmpf;
- }
- }
- else
- {
- /* Linux floating number compatibility
- t_CAP = (bcnTxTime + (sfSpec.FinCAP + 1) * sSlotDuration);
- */
- {
- tmpf = (sfSpec.FinCAP + 1) * sSlotDuration;
- t_CAP = bcnTxTime + tmpf;
- }
- }
- return (t_CAP>=now)?t_CAP:oneDay;
- }
- else
- return oneDay;
- if (type == 2)
- if (macBeaconOrder2 != 15)
- {
- if (sfSpec2.BLE)
- {
- /* Linux floating number compatibility
- t_CAP2 = (bcnRxTime + (beaconPeriods2 + getBattLifeExtSlotNum()) * aUnitBackoffPeriod);
- */
- {
- tmpf = (beaconPeriods2 + getBattLifeExtSlotNum()) * aUnitBackoffPeriod;
- t_CAP2 = bcnRxTime + tmpf;
- }
- }
- else
- {
- /* Linux floating number compatibility
- t_CAP2 = (bcnRxTime + (sfSpec2.FinCAP + 1) * sSlotDuration2);
- */
- {
- tmpf = (sfSpec2.FinCAP + 1) * sSlotDuration2;
- t_CAP2 = bcnRxTime + tmpf;
- }
- }
- /* Linux floating number compatibility
- if ((t_CAP2 < now)&&(t_CAP2 + aMaxLostBeacons * BI2 >= now))
- */
- tmpf = aMaxLostBeacons * BI2;
- if ((t_CAP2 < now)&&(t_CAP2 + tmpf >= now)) //no more than <aMaxLostBeacons> beacons missed
- while (t_CAP2 < now)
- t_CAP2 += BI2;
- return (t_CAP2>=now)?t_CAP2:oneDay;
- }
- else
- return oneDay;
-
- if (type == 3)
- if (macBeaconOrder3 != 15)
- {
- //no need to handle option <macBattLifeExt> here
- /* Linux floating number compatibility
- t_CAP3 = (bcnOtherRxTime + (sfSpec3.FinCAP + 1) * sSlotDuration3);
- */
- {
- tmpf = (sfSpec3.FinCAP + 1) * sSlotDuration3;
- t_CAP3 = bcnOtherRxTime + tmpf;
- }
- /* Linux floating number compatibility
- if ((t_CAP3 < now)&&(t_CAP3 + aMaxLostBeacons * BI3 >= now))
- */
- tmpf = aMaxLostBeacons * BI3;
- if ((t_CAP3 < now)&&(t_CAP3 + tmpf >= now)) //no more than <aMaxLostBeacons> beacons missed
- while (t_CAP3 < now)
- t_CAP3 += BI3;
- return (t_CAP3>=now)?t_CAP3:oneDay;
- }
- else
- return oneDay;
- return oneDay;
- }
- bool Mac802_15_4::canProceedWOcsmaca(Packet *p)
- {
- //this function checks whether there is enough time in the CAP of current superframe to finish a transaction (transmit a pending packet to a device)
- //(in the case the node acts as both a coordinator and a device, both the superframes from and to this node should be taken into account)
- double wtime,t_IFS,t_transacTime,t_CAP,tmpf;
- FrameCtrl frmCtrl;
- //int type;
- if ((mpib.macBeaconOrder == 15)&&(macBeaconOrder2 == 15)
- &&(macBeaconOrder3 == 15))
- return true;
- else
- {
- frmCtrl.FrmCtrl = HDR_LRWPAN(p)->MHR_FrmCtrl;
- frmCtrl.parse();
- wtime = 0.0;
- //there is no need to consider <macBattLifeExt>, since the device polling the data
- //should be waiting rather than go to sleep after the first 6 CAP backoff perios.
- if (HDR_CMN(p)->size() <= aMaxSIFSFrameSize)
- t_IFS = aMinSIFSPeriod;
- else
- t_IFS = aMinLIFSPeriod;
- t_IFS /= phy->getRate('s');
- t_transacTime = locateBoundary(toParent(p),wtime) - wtime; //boundary location time
- t_transacTime += phy->trxTime(p); //packet transmission time
- if (frmCtrl.ackReq)
- {
- t_transacTime += mpib.macAckWaitDuration/phy->getRate('s'); //ack. waiting time
- t_transacTime += 2*max_pDelay; //round trip propagation delay (802.15.4 ignores this, but it should be there even though it is very small)
- t_transacTime += t_IFS; //IFS time -- not only ensure that the sender can finish the transaction, but also the receiver
- t_CAP = getCAP(true);
- /* Linux floating number compatibility
- if (CURRENT_TIME + wtime + t_transacTime > t_CAP)
- */
- tmpf = CURRENT_TIME + wtime;
- tmpf += t_transacTime;
- if (tmpf > t_CAP)
- return false;
- else
- return true;
- }
- else
- {
- //in this case, we need to handle individual CAP
- t_CAP = getCAPbyType(1);
- /* Linux floating number compatibility
- if (CURRENT_TIME + wtime + t_transacTime > t_CAP)
- */
- tmpf = CURRENT_TIME + wtime;
- tmpf += t_transacTime;
- if (tmpf > t_CAP)
- return false;
- t_CAP = getCAPbyType(2);
- t_transacTime += max_pDelay; //one-way trip propagation delay (802.15.4 ignores this, but it should be there even though it is very small)
- t_transacTime += 12/phy->getRate('s'); //transceiver turn-around time (receiver may need to do this to transmit next beacon)
- t_transacTime += t_IFS; //IFS time -- not only ensure that the sender can finish the transaction, but also the receiver
- /* Linux floating number compatibility
- if (CURRENT_TIME + wtime + t_transacTime > t_CAP)
- */
- tmpf = CURRENT_TIME + wtime;
- tmpf += t_transacTime;
- if (tmpf > t_CAP)
- return false;
- t_CAP = getCAPbyType(3);
- t_transacTime -= t_IFS; //the third node does not need to handle the transaction
- /* Linux floating number compatibility
- if (CURRENT_TIME + wtime + t_transacTime > t_CAP)
- */
- tmpf = CURRENT_TIME + wtime;
- tmpf += t_transacTime;
- if (tmpf > t_CAP)
- return false;
- return true;
- }
- }
- }
- void Mac802_15_4::transmitCmdData(void)
- {
- double delay;
- if ((mpib.macBeaconOrder != 15)||(macBeaconOrder2 != 15)) //beacon enabled -- slotted
- {
- delay =locateBoundary(toParent(txCsmaca),0.0);
- if(delay > 0.0)
- {
- Scheduler::instance().schedule(&txCmdDataH, &(txCmdDataH.nullEvent), delay);
- return;
- }
- }
- //transmit immediately
- txBcnCmdDataHandler();
- }
- void Mac802_15_4::reset_TRX(const char *frFile,const char *frFunc,int line)
- {
- double t_CAP;
- PHYenum t_state;
- if ((mpib.macBeaconOrder != 15)||(macBeaconOrder2 != 15)) //beacon enabled
- {
- //according to the draft, <macRxOnWhenIdle> only considered during idle periods of the CAP if beacon enabled
- t_CAP = getCAP(false);
- if (CURRENT_TIME < t_CAP)
- t_state = mpib.macRxOnWhenIdle?p_RX_ON:p_TRX_OFF;
- else
- t_state = p_RX_ON; //(not considered ==> RX_ON)?
- }
- else
- t_state = mpib.macRxOnWhenIdle?p_RX_ON:p_TRX_OFF;
-
- set_trx_state_request(t_state,frFile,frFunc,line);
- }
- void Mac802_15_4::taskSuccess(char task,bool csmacaRes)
- {
- hdr_cmn* ch;
- hdr_lrwpan* wph;
- UINT_16 t_CAP;
- UINT_8 ifs;
- double tmpf;
- #ifdef DEBUG802_15_4
- fprintf(stdout,"[%s::%s][%f](node %d) task '%c' successful:ntttxBeacont= %ldntttxAck t= %ldntttxBcnCmdt= %ldntttxBcnCmd2t= %ldntttxData t= %ldn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,task,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
- #endif
- if (task == 'b') //beacon
- {
- if (!txBeacon)
- {
- assert(txBcnCmd2);
- txBeacon = txBcnCmd2;
- txBcnCmd2 = 0;
- }
- //--- calculate CAP ---
- sfSpec.parse();
- if (HDR_CMN(txBeacon)->size() <= aMaxSIFSFrameSize)
- ifs = aMinSIFSPeriod;
- else
- ifs = aMinLIFSPeriod;
- /* Linux floating number compatibility
- beaconPeriods = (UINT_8)((phy->trxTime(txBeacon) * phy->getRate('s') + ifs) / aUnitBackoffPeriod);
- */
- {
- tmpf = phy->trxTime(txBeacon) * phy->getRate('s');
- tmpf += ifs;
- beaconPeriods = (UINT_8)(tmpf / aUnitBackoffPeriod);
- }
- /* Linux floating number compatibility
- if (fmod((phy->trxTime(txBeacon) * phy->getRate('s')+ ifs) ,aUnitBackoffPeriod) > 0.0)
- */
- tmpf = phy->trxTime(txBeacon) * phy->getRate('s');
- tmpf += ifs;
- if (fmod(tmpf,aUnitBackoffPeriod) > 0.0)
- beaconPeriods++;
- t_CAP = (sfSpec.FinCAP + 1) * (sfSpec.sd / aUnitBackoffPeriod) - beaconPeriods;
- if (t_CAP == 0)
- {
- csmacaRes = false;
- plme_set_trx_state_request(p_TRX_OFF);
- }
- else
- plme_set_trx_state_request(p_RX_ON);
- //CSMA-CA may be waiting for the new beacon
- if (backoffStatus == 99)
- csmaca->newBeacon('t');
- //----------------------
- beaconWaiting = false;
- Packet::free(txBeacon);
- txBeacon = 0;
- /*
- //send out delayed ack.
- if (txAck)
- {
- csmacaRes = false;
- plme_set_trx_state_request(p_TX_ON);
- }
- */
- }
- else if (task == 'a') //ack.
- {
- assert(txAck);
- Packet::free(txAck);
- txAck = 0;
- }
- else if (task == 'c') //command
- {
- assert(txBcnCmd);
- //if it is a pending packet, delete it from the pending list
- updateTransacLinkByPktOrHandle(tr_oper_del,&transacLink1,&transacLink2,txBcnCmd);
- freePkt(txBcnCmd);
- txBcnCmd = 0;
- }
- else if (task == 'C') //command
- {
- assert(txBcnCmd2);
- freePkt(txBcnCmd2);
- txBcnCmd2 = 0;
- }
- else if (task == 'd') //data
- {
- assert(txData);
- ch = HDR_CMN(txData);
- wph = HDR_LRWPAN(txData);
- Packet *p = txData;
- txData = 0;
- if (ch->ptype() == PT_MAC)
- {
- assert(wph->msduHandle);
- sscs->MCPS_DATA_confirm(wph->msduHandle,m_SUCCESS);
- }
- else
- {
- if (Mac802_15_4::callBack == 2)
- if (ch->xmit_failure_)
- if (p802_15_4macDA(p) != (nsaddr_t)MAC_BROADCAST)
- {
- ch->size() -= macHeaderLen(wph->MHR_FrmCtrl);
- ch->xmit_reason_ = 1;
- ch->xmit_failure_(p->refcopy(),ch->xmit_failure_data_);
- }
- if (callback_)
- {
- Handler *h = callback_;
- callback_ = 0;
- h->handle((Event*) 0);
- }
- }
- //if it is a pending packet, delete it from the pending list
- updateTransacLinkByPktOrHandle(tr_oper_del,&transacLink1,&transacLink2,p);
- freePkt(p);
- }
- else
- assert(0);
- if (csmacaRes)
- csmacaResume();
- }
- void Mac802_15_4::taskFailed(char task,MACenum status,bool csmacaRes)
- {
- hdr_cmn* ch;
- hdr_lrwpan* wph;
- #ifdef DEBUG802_15_4
- fprintf(stdout,"[D][FAIL][%s::%s][%f](node %d) task '%c' failed:ntttxBeacont= %ldntttxAck t= %ldntttxBcnCmdt= %ldntttxBcnCmd2t= %ldntttxData t= %ldn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,task,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
- #endif
- if ((task == 'b') //beacon
- || (task == 'a') //ack.
- || (task == 'c')) //command
- {
- assert(0); //we don't handle the above failures here
- }
- else if (task == 'C') //command
- {
- freePkt(txBcnCmd2);
- txBcnCmd2 = 0;
- }
- else if (task == 'd') //data
- {
- wph = HDR_LRWPAN(txData);
- ch = HDR_CMN(txData);
- #ifdef DEBUG802_15_4
- fprintf(stdout,"[D][FAIL][%s::%s::%d][%f](node %d) failure: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %dn",__FILE__,__FUNCTION__,__LINE__,CURRENT_TIME,index_,wpan_pName(txData),p802_15_4macSA(txData),p802_15_4macDA(txData),ch->uid(),wph->uid,ch->size());
- #endif
- Packet *p = txData;
- txData = 0;
- if (wph->msduHandle) //from SSCS
- sscs->MCPS_DATA_confirm(wph->msduHandle,status);
- else
- {
- if (Mac802_15_4::callBack)
- if (ch->xmit_failure_)
- {
- wph->setSN = true;
- ch->size() -= macHeaderLen(wph->MHR_FrmCtrl);
- ch->xmit_reason_ = 0;
- ch->xmit_failure_(p->refcopy(),ch->xmit_failure_data_);
- }
- if (callback_
- && (!dataWaitT->busy()))
- {
- Handler *h = callback_;
- callback_ = 0;
- h->handle((Event*) 0);
- }
- }
- freePkt(p);
- }
- else
- assert(0);
- if (csmacaRes)
- csmacaResume();
- }
- void Mac802_15_4::freePkt(Packet *pkt)
- {
- /*
- if (HDR_LRWPAN(pkt)->indirect)
- return; //the packet will be automatically deleted when expired
- else
- Packet::free(pkt);
- */
- Packet::free(pkt); //now same operation for directly transmitted and indirectly transmitted packets
- }
- UINT_8 Mac802_15_4::macHeaderLen(UINT_16 FrmCtrl)
- {
- //calculate the MAC sublayer header (also including footer) length
- UINT_8 macHLen;
- FrameCtrl frmCtrl;
- frmCtrl.FrmCtrl = FrmCtrl;
- frmCtrl.parse();
-
- macHLen = 0;
- macHLen += 2 //FrmCtrl
- +1 //BSN/DSN
- +2; //FCS
- if (frmCtrl.frmType == defFrmCtrl_Type_Beacon) //Beacon
- {
- if (frmCtrl.srcAddrMode == defFrmCtrl_AddrMode16)
- macHLen += 2;
- else if (frmCtrl.srcAddrMode == defFrmCtrl_AddrMode64)
- macHLen += 8;
- }
- else if ((frmCtrl.frmType == defFrmCtrl_Type_Data) //Data
- ||(frmCtrl.frmType == defFrmCtrl_Type_MacCmd)) //Mac Command
- {
- if (frmCtrl.dstAddrMode == defFrmCtrl_AddrMode16)
- macHLen += 2;
- else if (frmCtrl.dstAddrMode == defFrmCtrl_AddrMode64)
- macHLen += 8;
- if (frmCtrl.srcAddrMode == defFrmCtrl_AddrMode16)
- macHLen += 2;
- else if (frmCtrl.srcAddrMode == defFrmCtrl_AddrMode64)
- macHLen += 8;
- }
- else if (frmCtrl.frmType == defFrmCtrl_Type_Ack) //Ack.
- {
- ;//nothing to do
- }
- else
- fprintf(stdout,"[%s][%f](node %d) Invalid frame type!n",__FUNCTION__,CURRENT_TIME,index_);
- return macHLen;
- }
- void Mac802_15_4::constructACK(Packet *p)
- {
- bool intraPan;
- UINT_8 origFrmType;
- FrameCtrl frmCtrl;
- Packet *ack = Packet::alloc();
- hdr_lrwpan* wph1 = HDR_LRWPAN(p);
- hdr_lrwpan* wph2 = HDR_LRWPAN(ack);
- hdr_cmn* ch1 = HDR_CMN(p);
- hdr_cmn* ch2 = HDR_CMN(ack);
- int i;
-
- hdr_dst((char *)HDR_MAC(ack),p802_15_4macSA(p));
- hdr_src((char *)HDR_MAC(ack),index_);
- frmCtrl.FrmCtrl = wph1->MHR_FrmCtrl;
- frmCtrl.parse();
- intraPan = frmCtrl.intraPan;
- origFrmType = frmCtrl.frmType;
- frmCtrl.FrmCtrl = 0;
- frmCtrl.setFrmType(defFrmCtrl_Type_Ack);
- frmCtrl.setSecu(false);
- //if it is a data request command, then need to check if there is any packet pending.
- //In implementation, we may not have enough time to check if packets pending. If this is the case,
- //then the pending flag in the ack. should be set to 1, and then send a zero-length data packet
- //if later it turns out there is no packet actually pending.
- //In simulation, we assume having enough time to determine the pending status -- so zero-length packet will never be sent.
- //(refer to page 155, line 46-50)
- if ((origFrmType == defFrmCtrl_Type_MacCmd) //command packet
- && (wph1->MSDU_CmdType == 0x04)) //data request command
- {
- i = updateTransacLink(tr_oper_est,&transacLink1,&transacLink2,frmCtrl.srcAddrMode,wph1->MHR_SrcAddrInfo.addr_64);
- frmCtrl.setFrmPending(i==0);
- }
- else
- frmCtrl.setFrmPending(false);
- frmCtrl.setAckReq(false);
- frmCtrl.setIntraPan(intraPan);
- frmCtrl.setDstAddrMode(defFrmCtrl_AddrModeNone);
- frmCtrl.setSrcAddrMode(defFrmCtrl_AddrModeNone);
- wph2->MHR_FrmCtrl = frmCtrl.FrmCtrl;
- wph2->MHR_BDSN = wph1->MHR_BDSN; //copy the SN from Data/MacCmd packet
- wph2->uid = wph1->uid; //for debug
- //wph2->MFR_FCS
- ch2->uid() = 0;
- ch2->ptype() = PT_MAC;
- ch2->iface() = -2;
- ch2->error() = 0;
- ch2->size() = 5;
- ch2->uid() = ch1->uid(); //copy the uid
- ch2->next_hop_ = p802_15_4macDA(ack); //nam needs the nex_hop information
- p802_15_4hdrACK(ack);
- #ifdef DEBUG802_15_4
- fprintf(stdout,"[%s::%s][%f](node %d) before alloc txAck:ntttxBeacont= %ldntttxAck t= %ldntttxBcnCmdt= %ldntttxBcnCmd2t= %ldntttxData t= %ldn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
- #endif
- assert(!txAck); //it's impossilbe to receive the second packet before
- //the Ack has been sent out.
- txAck = ack;
- }
- void Mac802_15_4::constructMPDU(UINT_8 msduLength,Packet *msdu, UINT_16 FrmCtrl,UINT_8 BDSN,panAddrInfo DstAddrInfo,
- panAddrInfo SrcAddrInfo,UINT_16 SuperSpec,UINT_8 CmdType,UINT_16 FCS)
- {
- hdr_lrwpan* wph = HDR_LRWPAN(msdu);
- hdr_cmn* ch = HDR_CMN(msdu);
- //FrameCtrl frmCtrl;
- //fill out fields
- wph->MHR_FrmCtrl = FrmCtrl;
- if (!wph->setSN)
- wph->MHR_BDSN = BDSN;
- else
- wph->setSN = false;
- if (!wph->uid)
- wph->uid = Mac802_15_4::DBG_UID++;
- wph->MHR_DstAddrInfo = DstAddrInfo;
- wph->MHR_SrcAddrInfo = SrcAddrInfo;
- wph->MSDU_SuperSpec = SuperSpec;
- wph->MSDU_CmdType = CmdType;
- wph->MFR_FCS = FCS;
- //update packet length
- ch->size() = msduLength + macHeaderLen(FrmCtrl);
- }
- void Mac802_15_4::constructCommandHeader(Packet *p,FrameCtrl *frmCtrl,UINT_8 CmdType,
- UINT_8 dstAddrMode,UINT_16 dstPANId,IE3ADDR dstAddr,
- UINT_8 srcAddrMode,UINT_16 srcPANId,IE3ADDR srcAddr,
- bool secuEnable,bool pending,bool ackreq)
- {
- hdr_lrwpan *wph = HDR_LRWPAN(p);
- frmCtrl->FrmCtrl = 0;
- frmCtrl->setFrmType(defFrmCtrl_Type_MacCmd);
- frmCtrl->setDstAddrMode(dstAddrMode);
- wph->MHR_DstAddrInfo.panID = dstPANId;
- wph->MHR_DstAddrInfo.addr_64 = dstAddr;
- hdr_src((char *)HDR_MAC(p),index_);
- if (dstAddr == 0xffff)
- hdr_dst((char *)HDR_MAC(p),MAC_BROADCAST);
- else
- hdr_dst((char *)HDR_MAC(p),dstAddr);
- frmCtrl->setSrcAddrMode(srcAddrMode);
- wph->MHR_SrcAddrInfo.panID = srcPANId;
- wph->MHR_SrcAddrInfo.addr_64 = srcAddr;
- frmCtrl->setSecu(secuEnable);
- frmCtrl->setFrmPending(pending);
- frmCtrl->setAckReq(ackreq);
- HDR_CMN(p)->ptype() = PT_MAC;
- //for trace purpose
- HDR_CMN(p)->next_hop_ = p802_15_4macDA(p); //nam needs the nex_hop information
- p802_15_4hdrCommand(p,CmdType);
- }
- void Mac802_15_4::log(Packet *p)
- {
- logtarget_->recv(p, (Handler*) 0);
- }
- void Mac802_15_4::resetCounter(int dst)
- {
- if (txBcnCmd)
- if (p802_15_4macDA(txBcnCmd) == dst)
- numBcnCmdRetry = 0;
- if (txBcnCmd2)
- if (p802_15_4macDA(txBcnCmd2) == dst)
- numBcnCmdRetry2 = 0;
- if (txData)
- if (p802_15_4macDA(txData) == dst)
- numDataRetry = 0;
- }
- int Mac802_15_4::command(int argc, const char*const* argv)
- {
- if (argc == 3)
- {
- if (strcmp(argv[1], "log-target") == 0)
- {
- logtarget_ = (NsObject*) TclObject::lookup(argv[2]);
- if(logtarget_ == 0)
- return TCL_ERROR;
- return TCL_OK;
- }
- }
- if (strcmp(argv[1], "NodeClr") == 0)
- {
- changeNodeColor(CURRENT_TIME,argv[2]);
- return (TCL_OK);
- }
- if (strcmp(argv[1], "NodeLabel") == 0)
- {
- char label[81];
- int i;
- strcpy(label,""");
- strcat(label,argv[2]);
- i = 3;
- while (i < argc)
- {
- if (strlen(label) + strlen(argv[i]) < 78)
- {
- strcat(label," ");
- strcat(label,argv[i]);
- }
- else
- break;
- i++;
- }
- strcat(label,""");
- nam->changeLabel(CURRENT_TIME,label);
- return (TCL_OK);
- }
- if (strcmp(argv[1], "node-down") == 0)
- {
- chkAddNFailLink(index_);
- changeNodeColor(CURRENT_TIME,Nam802_15_4::def_NodeFail_clr);
- if (txAck)
- {
- Packet::free(txAck);
- txAck = 0;
- }
- if (txBcnCmd)
- {
- freePkt(txBcnCmd);
- txBcnCmd = 0;
- }
- if (txBcnCmd2)
- {
- freePkt(txBcnCmd2);
- txBcnCmd2 = 0;
- }
- if (txData)
- {
- freePkt(txData);
- txData = 0;
- }
- if (phy->rxPacket())
- HDR_CMN(phy->rxPacket())->error() = 1;
- init(true); //reset
- return (TCL_OK);
- }
- if (strcmp(argv[1], "node-up") == 0)
- {
- updateNFailLink(fl_oper_del,index_);
- nam->changeBackNodeColor(CURRENT_TIME);
- init(true); //reset
- if (callback_)
- {
- Handler *h = callback_;
- callback_ = 0;
- h->handle((Event*) 0);
- }
- return (TCL_OK);
- }
- //check if this is actually a SSCS command
- if ((argc >= 3)&&(strcmp(argv[1],"sscs") == 0))
- return sscs->command(argc,argv);
- int rt = Mac::command(argc, argv);
-
- //check if Mac::command has already populated netif_
- if (netif_)
- if (phy == NULL) //only execute once
- {
- phy = (Phy802_15_4 *)netif_;
- phy->macObj(this);
- csmaca = new CsmaCA802_15_4(phy,this);
- assert(csmaca);
- }
- return rt;
- }
- void Mac802_15_4::changeNodeColor(double atTime,const char *newColor,bool save)
- {
- nam->changeNodeColor(atTime,newColor,save);
- nam->changeNodeColor(atTime+0.030001,newColor,false);
- }
- void Mac802_15_4::txBcnCmdDataHandler(void)
- {
- int i;
- if (taskP.taskStatus(TP_mlme_scan_request))
- if (txBcnCmd2 != txCsmaca)
- return; //terminate all other transmissions (will resume afte channel scan)
- if (HDR_LRWPAN(txCsmaca)->indirect)
- {
- i = updateTransacLinkByPktOrHandle(tr_oper_est,&transacLink1,&transacLink2,txCsmaca);
- if (i != 0) //transaction expired
- {
- resetTRX();
- if (txBcnCmd == txCsmaca)
- txBcnCmd = 0;
- else if (txBcnCmd2 == txCsmaca)
- txBcnCmd2 = 0;
- else if (txData == txCsmaca)
- txData = 0;
- //Packet::free(txCsmaca); //don't do this, since the packet will be automatically deleted when expired
- csmacaResume();
- return;
- }
- }
- if (txBcnCmd == txCsmaca)
- {
- #ifdef DEBUG802_15_4
- FrameCtrl frmCtrl;
- frmCtrl.FrmCtrl = HDR_LRWPAN(txBcnCmd)->MHR_FrmCtrl;
- frmCtrl.parse();
- /*
- char frm_type[21];
- if (frmCtrl.frmType == defFrmCtrl_Type_Beacon)
- strcpy(frm_type,"BEACON");
- else
- sprintf(frm_type,"COMMAND_%d",HDR_LRWPAN(txBcnCmd)->MSDU_CmdType);
- */
- fprintf(stdout,"[%s::%s][%f](node %d) transmit %s to %d: SN = %d, uid = %d, mac_uid = %ldn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(txBcnCmd),p802_15_4macDA(txBcnCmd),HDR_LRWPAN(txBcnCmd)->MHR_BDSN,HDR_CMN(txBcnCmd)->uid(),HDR_LRWPAN(txBcnCmd)->uid);
- #endif
- txPkt = txBcnCmd;
- HDR_CMN(txBcnCmd)->direction() = hdr_cmn::DOWN;
- sendDown(txBcnCmd->copy(), this);
- }
- else if (txBcnCmd2 == txCsmaca)
- {
- #ifdef DEBUG802_15_4
- FrameCtrl frmCtrl2;
- frmCtrl2.FrmCtrl = HDR_LRWPAN(txBcnCmd2)->MHR_FrmCtrl;
- frmCtrl2.parse();
- /*
- char frm_type2[21];
- if (frmCtrl2.frmType == defFrmCtrl_Type_Beacon)
- strcpy(frm_type2,"BEACON");
- else
- sprintf(frm_type2,"COMMAND_%d",HDR_LRWPAN(txBcnCmd2)->MSDU_CmdType);
- */
- fprintf(stdout,"[%s::%s][%f](node %d) transmit %s to %d: SN = %d, uid = %d, mac_uid = %ldn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(txBcnCmd2),p802_15_4macDA(txBcnCmd2),HDR_LRWPAN(txBcnCmd2)->MHR_BDSN,HDR_CMN(txBcnCmd2)->uid(),HDR_LRWPAN(txBcnCmd2)->uid);
- #endif
- txPkt = txBcnCmd2;
- HDR_CMN(txBcnCmd2)->direction() = hdr_cmn::DOWN;
- sendDown(txBcnCmd2->copy(), this);
- }
- else if (txData == txCsmaca)
- {
- #ifdef DEBUG802_15_4
- fprintf(stdout,"[%s::%s][%f](node %d) transmit DATA (%s) to %d: SN = %d, uid = %d, mac_uid = %ldn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(txData),p802_15_4macDA(txData),HDR_LRWPAN(txData)->MHR_BDSN,HDR_CMN(txData)->uid(),HDR_LRWPAN(txData)->uid);
- #endif
- txPkt = txData;
- HDR_CMN(txData)->direction() = hdr_cmn::DOWN;
- sendDown(txData->copy(), this);
- }
- }
- void Mac802_15_4::IFSHandler(void)
- {
- hdr_lrwpan* wph;
- hdr_cmn* ch;
- FrameCtrl frmCtrl;
- Packet *pendPkt;
- MACenum status;
- int i;
- assert(rxData||rxCmd);
- if (rxCmd)
- {
- wph = HDR_LRWPAN(rxCmd);
- frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
- frmCtrl.parse();
- if (wph->MSDU_CmdType == 0x01) //Association request
- sscs->MLME_ASSOCIATE_indication(wph->MHR_SrcAddrInfo.addr_64,wph->MSDU_Payload[0],frmCtrl.secu,0); //ACL ignored in simulation
- else if (wph->MSDU_CmdType == 0x02) //Association response
- {
- status = (*(MACenum *)(wph->MSDU_Payload + 2));
- //save the short address (if association successful)
- if (status == m_SUCCESS)
- mpib.macShortAddress = *((UINT_16 *)wph->MSDU_Payload);
- dispatch(p_SUCCESS,__FUNCTION__,p_SUCCESS,status);
- }
- else if (wph->MSDU_CmdType == 0x04) //Data request
- {
- //Continue to send pending packet (an ack. already sent).
- //In implementation, we may not have enough time to check if packets pending. If this is the case,
- //then the pending flag in the ack. should be set to 1, and then send a zero-length data packet
- //if later it turns out there is no packet actually pending.
- //In simulation, we assume having enough time to determine the pending status -- so zero-length packet will never be sent.
- //(refer to page 155, line 46-50)
- i = updateTransacLink(tr_oper_EST,&transacLink1,&transacLink2,frmCtrl.srcAddrMode,wph->MHR_SrcAddrInfo.addr_64);
- if (i != 0)
- {
- i = updateTransacLink(tr_oper_est,&transacLink1,&transacLink2,frmCtrl.srcAddrMode,wph->MHR_SrcAddrInfo.addr_64);
- i = (i == 0)?1:0;
- }
- else //more than one packet pending
- {
- i = 2;
- }
- if (i > 0) //packet(s) pending
- {
- pendPkt = getPktFrTransacLink(&transacLink1,frmCtrl.srcAddrMode,wph->MHR_SrcAddrInfo.addr_64);
- wph = HDR_LRWPAN(pendPkt);
- wph->indirect = true;
- frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
- frmCtrl.parse();
- frmCtrl.setFrmPending(i>1); //more packet pending?
- wph->MHR_FrmCtrl = frmCtrl.FrmCtrl;
- HDR_CMN(pendPkt)->direction() = hdr_cmn::DOWN;
- if (frmCtrl.frmType == defFrmCtrl_Type_MacCmd)
- {
- if (txBcnCmd == pendPkt) //it's being processed
- {
- Packet::free(rxCmd); //we logged the command packet before, here just free it
- rxCmd = 0;
- return;
- }
- #ifdef DEBUG802_15_4
- fprintf(stdout,"[%s::%s][%f](node %d) before assign txBcnCmd:ntttxBeacont= %ldntttxAck t= %ldntttxBcnCmdt= %ldntttxBcnCmd2t= %ldntttxData t= %ldn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
- #endif
- assert(!txBcnCmd); //we couldn't receive the data request command if we are processing txBcnCmd
- txBcnCmd = pendPkt->refcopy();
- waitBcnCmdAck = false;
- numBcnCmdRetry = 0;
- }
- else if (frmCtrl.frmType == defFrmCtrl_Type_Data)
- {
- if (txData == pendPkt) //it's being processed
- {
- Packet::free(rxCmd); //we logged the command packet before, here just free it
- rxCmd = 0;
- return;
- }
- #ifdef DEBUG802_15_4
- fprintf(stdout,"[%s::%s][%f](node %d) before assign txData:ntttxBeacont= %ldntttxAck t= %ldntttxBcnCmdt= %ldntttxBcnCmd2t= %ldntttxData t= %ldn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
- #endif
- assert(!txData); //we couldn't receive the data request command if we are processing txData
- txData = pendPkt->refcopy();
- waitDataAck = false;
- numDataRetry = 0;
- }
- //there are two ways to transmit the pending packet for the first time (refer to page 156), w/o or w/ CSMA-CA,
- if (canProceedWOcsmaca(pendPkt))
- {
- //change task field "frFunc"
- if(taskP.taskStatus(TP_mcps_data_request))
- {
- if (strcmp(taskP.taskFrFunc(TP_mcps_data_request),"csmacaCallBack") == 0)
- strcpy(taskP.taskFrFunc(TP_mcps_data_request),"PD_DATA_confirm");
- }
- else if (taskP.taskStatus(TP_mlme_associate_response))
- {
- if (strcmp(taskP.taskFrFunc(TP_mlme_associate_response),"csmacaCallBack") == 0)
- strcpy(taskP.taskFrFunc(TP_mlme_associate_response),"PD_DATA_confirm");
- //else //other commands using indirect transmission (may be none): TBD
- }
- txCsmaca = pendPkt;
- plme_set_trx_state_request(p_TX_ON);
- }
- else
- {
- csmacaResume();
- }
- }
- //else //may need to send a zero-length packet in implementation
- }
- else if (wph->MSDU_CmdType == 0x08) //Coordinator realignment
- {
- 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);
- mpib.macShortAddress = *((UINT_16 *)wph->MSDU_Payload + 5);
- dispatch(p_SUCCESS,__FUNCTION__);
- }
- Packet::free(rxCmd); //we logged the command packet before, here just free it
- rxCmd = 0;
- }
- else if (rxData)
- {
- wph = HDR_LRWPAN(rxData);
- ch = HDR_CMN(rxData);
- frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
- frmCtrl.parse();
- if (taskP.taskStatus(TP_mlme_poll_request))
- dispatch(p_SUCCESS,__FUNCTION__,p_SUCCESS,status);
- //else //do nothing
- //the data waiting timer in data polling expired and the upper layer confirmed
- //with a status NO_DATA -- but we see no reason not to continue passing this data
- //packet to upper layer (note that the ack. has already been sent to data source --
- //we shouldn't drop the data packet here).
- //strip off the MAC sublayer header
- ch->size() -= macHeaderLen(wph->MHR_FrmCtrl);
- MCPS_DATA_indication(frmCtrl.srcAddrMode,wph->MHR_SrcAddrInfo.panID,wph->MHR_SrcAddrInfo.addr_64,
- frmCtrl.dstAddrMode,wph->MHR_DstAddrInfo.panID,wph->MHR_DstAddrInfo.addr_64,
- ch->size(),rxData,wph->ppduLinkQuality,
- wph->SecurityUse,wph->ACLEntry);
- rxData = 0;
- }
- }
- void Mac802_15_4::backoffBoundHandler(void)
- {
- if (!beaconWaiting)
- if (txAck) //<txAck> may have been cancelled by <macBeaconRxTimer>
- {
- #ifdef DEBUG802_15_4
- fprintf(stdout,"[%s::%s][%f](node %d) transmit M_ACK to %d: SN = %d, uid = %d, mac_uid = %ldn",__FILE__,__FUNCTION__,CURRENT_TIME,index_,p802_15_4macDA(txAck),HDR_LRWPAN(txAck)->MHR_BDSN,HDR_CMN(txAck)->uid(),HDR_LRWPAN(txAck)->uid);
- #endif
- txPkt = txAck;
- HDR_CMN(txAck)->direction() = hdr_cmn::DOWN;
- sendDown(txAck->refcopy(), this);
- }
- }
- // End of file: p802_15_4mac.cc