00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include "p802_15_4pkt.h"
00054 #include "p802_15_4mac.h"
00055 #include "p802_15_4const.h"
00056 #include "p802_15_4csmaca.h"
00057 #include "p802_15_4sscs.h"
00058 #include "p802_15_4trace.h"
00059 #include "p802_15_4fail.h"
00060 #include "p802_15_4nam.h"
00061
00062 bool Mac802_15_4::verbose = false;
00063 UINT_8 Mac802_15_4::txOption = 0x00;
00064 bool Mac802_15_4::ack4data = true;
00065 UINT_8 Mac802_15_4::callBack = 1;
00066 UINT_32 Mac802_15_4::DBG_UID = 0;
00067
00068 static MAC_PIB MPIB =
00069 {
00070 def_macAckWaitDuration, def_macAssociationPermit,
00071 def_macAutoRequest, def_macBattLifeExt,
00072 def_macBattLifeExtPeriods, def_macBeaconPayload,
00073 def_macBeaconPayloadLength, def_macBeaconOrder,
00074 def_macBeaconTxTime, 0,
00075 def_macCoordExtendedAddress, def_macCoordShortAddress,
00076 0, def_macGTSPermit,
00077 def_macMaxCSMABackoffs, def_macMinBE,
00078 def_macPANId, def_macPromiscuousMode,
00079 def_macRxOnWhenIdle, def_macShortAddress,
00080 def_macSuperframeOrder, def_macTransactionPersistenceTime,
00081 def_macACLEntryDescriptorSet, def_macACLEntryDescriptorSetSize,
00082 def_macDefaultSecurity, def_macACLDefaultSecurityMaterialLength,
00083 def_macDefaultSecurityMaterial, def_macDefaultSecuritySuite,
00084 def_macSecurityMode
00085 };
00086
00087 void Mac802_15_4Handler::handle(Event* e)
00088 {
00089 nullEvent.uid_ = 0;
00090 if (type == macTxBcnCmdDataHType)
00091 mac->txBcnCmdDataHandler();
00092 else if (type == macIFSHType)
00093 mac->IFSHandler();
00094 else if (type == macBackoffBoundType)
00095 mac->backoffBoundHandler();
00096 else
00097 assert(0);
00098 }
00099
00100 int hdr_lrwpan::offset_;
00101 static class LRWPANHeaderClass : public PacketHeaderClass
00102 {
00103 public:
00104 LRWPANHeaderClass() : PacketHeaderClass("PacketHeader/LRWPAN",
00105 sizeof(hdr_lrwpan))
00106 {
00107 bind_offset(&hdr_lrwpan::offset_);
00108 }
00109 } class_hdr_lrwpan;
00110
00111 static class Mac802_15_4Class : public TclClass
00112 {
00113 public:
00114 Mac802_15_4Class() : TclClass("Mac/802_15_4") {}
00115 TclObject* create(int, const char*const*)
00116 {
00117 return (new Mac802_15_4(&MPIB));
00118 }
00119 virtual void bind(void);
00120 virtual int method(int argc, const char*const* argv);
00121 } class_mac802_15_4;
00122
00123 void Mac802_15_4Class::bind(void)
00124 {
00125 TclClass::bind();
00126 add_method("wpanCmd");
00127 add_method("wpanNam");
00128 }
00129
00130 int Mac802_15_4Class::method(int ac, const char*const* av)
00131 {
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 Tcl& tcl = Tcl::instance();
00153 int argc = ac - 2;
00154 const char*const* argv = av + 2;
00155
00156 if (strcmp(argv[1], "wpanCmd") == 0)
00157 if (argc == 3)
00158 {
00159 if (strcmp(argv[2], "verbose") == 0)
00160 {
00161 if (!Mac802_15_4::verbose)
00162 tcl.result("off");
00163 else
00164 tcl.result("on");
00165 return (TCL_OK);
00166 }
00167 else if (strcmp(argv[2], "txOption") == 0)
00168 {
00169 if (Mac802_15_4::txOption == 0x02)
00170 tcl.result("GTS");
00171 else if (Mac802_15_4::txOption == 0x04)
00172 tcl.result("Indirect");
00173 else
00174 tcl.result("Direct");
00175 return (TCL_OK);
00176 }
00177 else if (strcmp(argv[2], "ack4data") == 0)
00178 {
00179 if (!Mac802_15_4::ack4data)
00180 tcl.result("off");
00181 else
00182 tcl.result("on");
00183 return (TCL_OK);
00184 }
00185 else if (strcmp(argv[2], "callBack") == 0)
00186 {
00187 tcl.resultf("%u",Mac802_15_4::callBack);
00188 return (TCL_OK);
00189 }
00190 }
00191 else if (argc == 4)
00192 {
00193 if (strcmp(argv[2], "verbose") == 0)
00194 {
00195 if (strcmp(argv[3], "on") == 0)
00196 Mac802_15_4::verbose = true;
00197 else
00198 Mac802_15_4::verbose = false;
00199 return (TCL_OK);
00200 }
00201 else if (strcmp(argv[2], "txOption") == 0)
00202 {
00203 Mac802_15_4::txOption = atoi(argv[3]);
00204 return (TCL_OK);
00205 }
00206 else if (strcmp(argv[2], "ack4data") == 0)
00207 {
00208 if (strcmp(argv[3], "on") == 0)
00209 Mac802_15_4::ack4data = true;
00210 else
00211 Mac802_15_4::ack4data = false;
00212 return (TCL_OK);
00213 }
00214 else if (strcmp(argv[2], "callBack") == 0)
00215 {
00216 Mac802_15_4::callBack = atoi(argv[3]);
00217 return (TCL_OK);
00218 }
00219 }
00220 else if (argc == 5)
00221 {
00222 if (strcmp(argv[2], "link-down") == 0)
00223 {
00224 chkAddLFailLink(atoi(argv[3]),atoi(argv[4]));
00225 return (TCL_OK);
00226 }
00227 else if (strcmp(argv[2], "link-up") == 0)
00228 {
00229 updateLFailLink(fl_oper_del,atoi(argv[3]),atoi(argv[4]));
00230 return (TCL_OK);
00231 }
00232 }
00233
00234 if (strcmp(argv[1], "wpanNam") == 0)
00235 if (strcmp(argv[2], "namStatus") == 0)
00236 {
00237 if (argc == 3)
00238 {
00239 if (!Nam802_15_4::Nam_Status)
00240 tcl.result("off");
00241 else
00242 tcl.result("on");
00243 }
00244 else if (argc == 4)
00245 {
00246 if (strcmp(argv[3], "on") == 0)
00247 Nam802_15_4::Nam_Status = true;
00248 else
00249 Nam802_15_4::Nam_Status = false;
00250 }
00251 return (TCL_OK);
00252 }
00253 else if (strcmp(argv[2], "emHandling") == 0)
00254 {
00255 if (argc == 3)
00256 {
00257 if (!Nam802_15_4::emHandling)
00258 tcl.result("off");
00259 else
00260 tcl.result("on");
00261 }
00262 else if (argc == 4)
00263 {
00264 if (strcmp(argv[3], "on") == 0)
00265 Nam802_15_4::emHandling = true;
00266 else
00267 Nam802_15_4::emHandling = false;
00268 }
00269 return (TCL_OK);
00270 }
00271 else if (strcmp(argv[2], "PANCoorClr") == 0)
00272 {
00273 if (argc == 3)
00274 tcl.result(Nam802_15_4::def_PANCoor_clr);
00275 else if (argc >= 4)
00276 {
00277 strncpy(Nam802_15_4::def_PANCoor_clr,argv[3],20);
00278 Nam802_15_4::def_PANCoor_clr[20] = 0;
00279 }
00280 return (TCL_OK);
00281 }
00282 else if (strcmp(argv[2], "CoorClr") == 0)
00283 {
00284 if (argc == 3)
00285 tcl.result(Nam802_15_4::def_Coor_clr);
00286 else if (argc >= 4)
00287 {
00288 strncpy(Nam802_15_4::def_Coor_clr,argv[3],20);
00289 Nam802_15_4::def_Coor_clr[20] = 0;
00290 }
00291 return (TCL_OK);
00292 }
00293 else if (strcmp(argv[2], "DevClr") == 0)
00294 {
00295 if (argc == 3)
00296 tcl.result(Nam802_15_4::def_Dev_clr);
00297 else if (argc >= 4)
00298 {
00299 strncpy(Nam802_15_4::def_Dev_clr,argv[3],20);
00300 Nam802_15_4::def_Dev_clr[20] = 0;
00301 }
00302 return (TCL_OK);
00303 }
00304 else if (strcmp(argv[2], "ColFlashClr") == 0)
00305 {
00306 if (argc == 3)
00307 tcl.result(Nam802_15_4::def_ColFlash_clr);
00308 else if (argc >= 4)
00309 {
00310 strncpy(Nam802_15_4::def_ColFlash_clr,argv[3],20);
00311 Nam802_15_4::def_ColFlash_clr[20] = 0;
00312 }
00313 return (TCL_OK);
00314 }
00315 else if (strcmp(argv[2], "NodeFailClr") == 0)
00316 {
00317 if (argc == 3)
00318 tcl.result(Nam802_15_4::def_NodeFail_clr);
00319 else if (argc >= 4)
00320 {
00321 strncpy(Nam802_15_4::def_NodeFail_clr,argv[3],20);
00322 Nam802_15_4::def_NodeFail_clr[20] = 0;
00323 }
00324 return (TCL_OK);
00325 }
00326 else if (strcmp(argv[2], "PlaybackRate") == 0)
00327 {
00328 if (argc == 3)
00329 tcl.result("??");
00330 else if (argc >= 4)
00331 Nam802_15_4::changePlaybackRate(CURRENT_TIME,argv[3]);
00332 return (TCL_OK);
00333 }
00334 else if (strcmp(argv[2], "FlowClr") == 0)
00335 {
00336 int i,lp,src,dst;
00337 char pName[21],cName[21];
00338 ATTRIBUTELINK *attr;
00339
00340 src = -2;
00341 dst = -2;
00342 strcpy(pName,packet_info.name(PT_NTYPE));
00343 lp = (argc - 3) / 2;
00344 for (i=0;i<lp;i++)
00345 {
00346 if (strcmp(argv[i*2+3],"-p") == 0)
00347 {
00348 strncpy(pName,argv[i*2+4],20);
00349 pName[20] = 0;
00350 }
00351 else if (strcmp(argv[i*2+3],"-s") == 0)
00352 src = atoi(argv[i*2+4]);
00353 else if (strcmp(argv[i*2+3],"-d") == 0)
00354 dst = atoi(argv[i*2+4]);
00355 else if (strcmp(argv[i*2+3],"-c") == 0)
00356 {
00357 strncpy(cName,argv[i*2+4],20);
00358 cName[20] = 0;
00359 }
00360 }
00361 i = chkAddAttrLink(nam_pktName2Type(pName),cName,src,dst);
00362 if (i == 1)
00363 {
00364 attr = findAttrLink(nam_pktName2Type(pName),src,dst);
00365 if (strcmp(attr->color,cName) != 0)
00366 {
00367 strncpy(attr->color,cName,20);
00368 attr->color[20] = 0;
00369 Nam802_15_4::flowAttribute(attr->attribute,attr->color);
00370 }
00371
00372 }
00373 else if (i == 0)
00374 {
00375 attr = findAttrLink(nam_pktName2Type(pName),src,dst);
00376 Nam802_15_4::flowAttribute(attr->attribute,attr->color);
00377 }
00378 return (TCL_OK);
00379 }
00380
00381
00382 return TclClass::method(ac, av);
00383 }
00384
00385 Mac802_15_4::Mac802_15_4(MAC_PIB *mp) : Mac(),
00386 txCmdDataH(this,macTxBcnCmdDataHType),
00387 IFSH(this,macIFSHType),
00388 backoffBoundH(this,macBackoffBoundType)
00389 {
00390 capability.cap = 0xc1;
00391
00392
00393
00394
00395
00396 capability.parse();
00397 aExtendedAddress = index_;
00398 oneMoreBeacon = false;
00399 isPANCoor = false;
00400 inTransmission = false;
00401 mpib = *mp;
00402 mpib.macBSN = Random::random() % 0x100;
00403 mpib.macDSN = Random::random() % 0x100;
00404 macBeaconOrder2 = 15;
00405 macSuperframeOrder2 = def_macBeaconOrder;
00406 macBeaconOrder3 = 15;
00407 macSuperframeOrder3 = def_macBeaconOrder;
00408 if (mpib.macBeaconOrder == 15)
00409 mpib.macRxOnWhenIdle = true;
00410 numLostBeacons = 0;
00411 phy = NULL;
00412 txOverT = new macTxOverTimer(this);
00413 assert(txOverT);
00414 txT = new macTxTimer(this);
00415 assert(txT);
00416 extractT = new macExtractTimer(this);
00417 assert(extractT);
00418 assoRspWaitT = new macAssoRspWaitTimer(this);
00419 assert(assoRspWaitT);
00420 dataWaitT = new macDataWaitTimer(this);
00421 assert(dataWaitT);
00422 rxEnableT = new macRxEnableTimer(this);
00423 assert(rxEnableT);
00424 scanT = new macScanTimer(this);
00425 assert(scanT);
00426 bcnTxT = new macBeaconTxTimer(this);
00427 assert(bcnTxT);
00428 bcnRxT = new macBeaconRxTimer(this);
00429 assert(bcnRxT);
00430 bcnSearchT = new macBeaconSearchTimer(this);
00431 assert(bcnSearchT);
00432 sscs = new SSCS802_15_4(this);
00433 assert(sscs);
00434 nam = new Nam802_15_4((isPANCoor)?Nam802_15_4::def_PANCoor_clr:"black","black",this);
00435 assert(nam);
00436
00437 chkAddMacLink(index_,this);
00438
00439 init();
00440 }
00441
00442 Mac802_15_4::~Mac802_15_4()
00443 {
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 }
00460
00461 void Mac802_15_4::init(bool reset)
00462 {
00463 secuBeacon = false;
00464 beaconWaiting = false;
00465 txBeacon = 0;
00466 txAck = 0;
00467 txBcnCmd = 0;
00468 txBcnCmd2 = 0;
00469 txData = 0;
00470 rxData = 0;
00471 rxCmd = 0;
00472
00473 if (reset)
00474 {
00475 emptyHListLink(&hlistBLink1,&hlistBLink2);
00476 emptyHListLink(&hlistDLink1,&hlistDLink2);
00477 emptyDeviceLink(&deviceLink1,&deviceLink2);
00478 emptyTransacLink(&transacLink1,&transacLink2);
00479 }
00480 else
00481 {
00482 hlistBLink1 = NULL;
00483 hlistBLink2 = NULL;
00484 hlistDLink1 = NULL;
00485 hlistDLink2 = NULL;
00486 deviceLink1 = NULL;
00487 deviceLink2 = NULL;
00488 transacLink1 = NULL;
00489 transacLink2 = NULL;
00490 }
00491
00492 taskP.init();
00493 }
00494
00495 void Mac802_15_4::PD_DATA_confirm(PHYenum status)
00496 {
00497 inTransmission = false;
00498 if (txOverT->busy())
00499 txOverT->stop();
00500 if (backoffStatus == 1)
00501 backoffStatus = 0;
00502 if (status == p_SUCCESS)
00503 {
00504 dispatch(status,__FUNCTION__);
00505 }
00506 else if (txPkt == txBeacon)
00507 {
00508 beaconWaiting = false;
00509 Packet::free(txBeacon);
00510 txBeacon = 0;
00511
00512 }
00513 else if (txPkt == txAck)
00514 {
00515 Packet::free(txAck);
00516 txAck = 0;
00517
00518 }
00519 else
00520 {}
00521 }
00522
00523 void Mac802_15_4::PLME_CCA_confirm(PHYenum status)
00524 {
00525 if (taskP.taskStatus(TP_CCA_csmaca))
00526 {
00527 taskP.taskStatus(TP_CCA_csmaca) = false;
00528 csmaca->CCA_confirm(status);
00529 }
00530 }
00531
00532 void Mac802_15_4::PLME_ED_confirm(PHYenum status,UINT_8 EnergyLevel)
00533 {
00534 energyLevel = EnergyLevel;
00535 dispatch(status,__FUNCTION__);
00536 }
00537
00538 void Mac802_15_4::PLME_GET_confirm(PHYenum status,PPIBAenum PIBAttribute,PHY_PIB *PIBAttributeValue)
00539 {
00540 if (status == p_SUCCESS)
00541 switch(PIBAttribute)
00542 {
00543 case phyCurrentChannel:
00544 tmp_ppib.phyCurrentChannel = PIBAttributeValue->phyCurrentChannel;
00545 break;
00546 case phyChannelsSupported:
00547 tmp_ppib.phyChannelsSupported = PIBAttributeValue->phyChannelsSupported;
00548 break;
00549 case phyTransmitPower:
00550 tmp_ppib.phyTransmitPower = PIBAttributeValue->phyTransmitPower;
00551 break;
00552 case phyCCAMode:
00553 tmp_ppib.phyCCAMode = PIBAttributeValue->phyCCAMode;
00554 break;
00555 default:
00556 break;
00557 }
00558 }
00559
00560 void Mac802_15_4::PLME_SET_TRX_STATE_confirm(PHYenum status)
00561 {
00562
00563
00564 double delay;
00565
00566 if (status == p_SUCCESS) status = trx_state_req;
00567
00568 if (backoffStatus == 99)
00569 {
00570 if (trx_state_req == p_RX_ON)
00571 {
00572 if (taskP.taskStatus(TP_RX_ON_csmaca))
00573 {
00574 taskP.taskStatus(TP_RX_ON_csmaca) = false;
00575 csmaca->RX_ON_confirm(status);
00576 }
00577 }
00578 }
00579 else
00580 dispatch(status,__FUNCTION__,trx_state_req);
00581
00582 if (status != p_TX_ON) return;
00583
00584
00585 if (beaconWaiting)
00586 {
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 }
00598 else if (txAck)
00599 {
00600
00601
00602
00603 if ((mpib.macBeaconOrder == 15)&&(macBeaconOrder2 == 15))
00604 delay = 0.0;
00605 else
00606 delay = locateBoundary((p802_15_4macDA(txAck) == mpib.macCoordShortAddress),0.0);
00607 if (delay == 0.0)
00608 backoffBoundHandler();
00609 else
00610 Scheduler::instance().schedule(&backoffBoundH, &(backoffBoundH.nullEvent), delay);
00611 }
00612 else
00613 transmitCmdData();
00614 }
00615
00616 void Mac802_15_4::PLME_SET_confirm(PHYenum status,PPIBAenum PIBAttribute)
00617 {
00618 if ((PIBAttribute == phyCurrentChannel)&&(status == p_SUCCESS))
00619 dispatch(status,__FUNCTION__);
00620 }
00621
00622 void Mac802_15_4::MCPS_DATA_request(UINT_8 SrcAddrMode,UINT_16 SrcPANId,IE3ADDR SrcAddr,
00623 UINT_8 DstAddrMode,UINT_16 DstPANId,IE3ADDR DstAddr,
00624 UINT_8 msduLength,Packet *msdu,UINT_8 msduHandle,UINT_8 TxOptions)
00625 {
00626 mcps_data_request(SrcAddrMode,SrcPANId,SrcAddr,DstAddrMode,DstPANId,DstAddr,msduLength,msdu,msduHandle,TxOptions,true);
00627 }
00628
00629 void Mac802_15_4::MCPS_DATA_indication(UINT_8 SrcAddrMode,UINT_16 SrcPANId,IE3ADDR SrcAddr,
00630 UINT_8 DstAddrMode,UINT_16 DstPANId,IE3ADDR DstAddr,
00631 UINT_8 msduLength,Packet *msdu,UINT_8 mpduLinkQuality,
00632 bool SecurityUse,UINT_8 ACLEntry)
00633 {
00634 HDR_CMN(msdu)->num_forwards() += 1;
00635
00636 if (HDR_LRWPAN(msdu)->msduHandle != 0)
00637 {
00638 log(msdu->refcopy());
00639 sscs->MCPS_DATA_indication(SrcAddrMode,SrcPANId,SrcAddr,DstAddrMode,DstPANId,DstAddr,msduLength,msdu,mpduLinkQuality,SecurityUse,ACLEntry);
00640 }
00641 else
00642 uptarget_->recv(msdu,(Handler*) 0);
00643 }
00644
00645 void Mac802_15_4::MCPS_PURGE_request(UINT_8 msduHandle)
00646 {
00647
00648 int i;
00649 MACenum t_status;
00650
00651 i = updateTransacLinkByPktOrHandle(tr_oper_del,&transacLink1,&transacLink2,NULL,msduHandle);
00652 t_status = (i == 0)?m_SUCCESS:m_INVALID_HANDLE;
00653 sscs->MCPS_PURGE_confirm(msduHandle,t_status);
00654 }
00655
00656 void Mac802_15_4::MLME_ASSOCIATE_request(UINT_8 LogicalChannel,UINT_8 CoordAddrMode,UINT_16 CoordPANId,IE3ADDR CoordAddress,
00657 UINT_8 CapabilityInformation,bool SecurityEnable)
00658 {
00659 mlme_associate_request(LogicalChannel,CoordAddrMode,CoordPANId,CoordAddress,CapabilityInformation,SecurityEnable,true);
00660 }
00661
00662 void Mac802_15_4::MLME_ASSOCIATE_response(IE3ADDR DeviceAddress,UINT_16 AssocShortAddress,MACenum status,bool SecurityEnable)
00663 {
00664 mlme_associate_response(DeviceAddress,AssocShortAddress,status,SecurityEnable,true);
00665 }
00666
00667 void Mac802_15_4::MLME_DISASSOCIATE_request(IE3ADDR DeviceAddress,UINT_8 DisassociateReason,bool SecurityEnable)
00668 {
00669 mlme_disassociate_request(DeviceAddress,DisassociateReason,SecurityEnable,true);
00670 }
00671
00672 void Mac802_15_4::MLME_DISASSOCIATE_indication(IE3ADDR DeviceAddress,UINT_8 DisassociateReason,bool SecurityUse,UINT_8 ACLEntry)
00673 {
00674 }
00675
00676 void Mac802_15_4::MLME_GET_request(MPIBAenum PIBAttribute)
00677 {
00678 MACenum t_status;
00679
00680 switch(PIBAttribute)
00681 {
00682 case macAckWaitDuration:
00683 case macAssociationPermit:
00684 case macAutoRequest:
00685 case macBattLifeExt:
00686 case macBattLifeExtPeriods:
00687 case macBeaconPayload:
00688 case macBeaconPayloadLength:
00689 case macBeaconOrder:
00690 case macBeaconTxTime:
00691 case macBSN:
00692 case macCoordExtendedAddress:
00693 case macCoordShortAddress:
00694 case macDSN:
00695 case macGTSPermit:
00696 case macMaxCSMABackoffs:
00697 case macMinBE:
00698 case macPANId:
00699 case macPromiscuousMode:
00700 case macRxOnWhenIdle:
00701 case macShortAddress:
00702 case macSuperframeOrder:
00703 case macTransactionPersistenceTime:
00704 case macACLEntryDescriptorSet:
00705 case macACLEntryDescriptorSetSize:
00706 case macDefaultSecurity:
00707 case macACLDefaultSecurityMaterialLength:
00708 case macDefaultSecurityMaterial:
00709 case macDefaultSecuritySuite:
00710 case macSecurityMode:
00711 t_status = m_SUCCESS;
00712 break;
00713 default:
00714 t_status = m_UNSUPPORTED_ATTRIBUTE;
00715 break;
00716 }
00717 sscs->MLME_GET_confirm(t_status,PIBAttribute,&mpib);
00718 }
00719
00720 void Mac802_15_4::MLME_GTS_request(UINT_8 GTSCharacteristics,bool SecurityEnable)
00721 {
00722 }
00723
00724 void Mac802_15_4::MLME_GTS_confirm(UINT_8 GTSCharacteristics,MACenum status)
00725 {
00726 }
00727
00728 void Mac802_15_4::MLME_GTS_indication(UINT_16 DevAddress,UINT_8 GTSCharacteristics,
00729 bool SecurityUse, UINT_8 ACLEntry)
00730 {
00731 }
00732
00733 void Mac802_15_4::MLME_ORPHAN_response(IE3ADDR OrphanAddress,UINT_16 ShortAddress,bool AssociatedMember,bool SecurityEnable)
00734 {
00735 mlme_orphan_response(OrphanAddress,ShortAddress,AssociatedMember,SecurityEnable,true);
00736 }
00737
00738 void Mac802_15_4::MLME_RESET_request(bool SetDefaultPIB)
00739 {
00740 mlme_reset_request(SetDefaultPIB,true);
00741 }
00742
00743 void Mac802_15_4::MLME_RX_ENABLE_request(bool DeferPermit,UINT_32 RxOnTime,UINT_32 RxOnDuration)
00744 {
00745 mlme_rx_enable_request(DeferPermit,RxOnTime,RxOnDuration,true);
00746 }
00747
00748 void Mac802_15_4::MLME_SCAN_request(UINT_8 ScanType,UINT_32 ScanChannels,UINT_8 ScanDuration)
00749 {
00750 mlme_scan_request(ScanType,ScanChannels,ScanDuration,true);
00751 }
00752
00753 void Mac802_15_4::MLME_SET_request(MPIBAenum PIBAttribute,MAC_PIB *PIBAttributeValue)
00754 {
00755 PHYenum p_state;
00756 MACenum t_status;
00757
00758 t_status = m_SUCCESS;
00759 switch(PIBAttribute)
00760 {
00761 case macAckWaitDuration:
00762 phy->PLME_GET_request(phyCurrentChannel);
00763 if ((tmp_ppib.phyCurrentChannel <= 10)&&(PIBAttributeValue->macAckWaitDuration != 120)
00764 || (tmp_ppib.phyCurrentChannel > 10)&&(PIBAttributeValue->macAckWaitDuration != 54))
00765 t_status = m_INVALID_PARAMETER;
00766 else
00767 mpib.macAckWaitDuration = PIBAttributeValue->macAckWaitDuration;
00768 break;
00769 case macAssociationPermit:
00770 mpib.macAssociationPermit = PIBAttributeValue->macAssociationPermit;
00771 break;
00772 case macAutoRequest:
00773 mpib.macAutoRequest = PIBAttributeValue->macAutoRequest;
00774 break;
00775 case macBattLifeExt:
00776 mpib.macBattLifeExt = PIBAttributeValue->macBattLifeExt;
00777 break;
00778 case macBattLifeExtPeriods:
00779 phy->PLME_GET_request(phyCurrentChannel);
00780 if ((tmp_ppib.phyCurrentChannel <= 10)&&(PIBAttributeValue->macBattLifeExtPeriods != 8)
00781 || (tmp_ppib.phyCurrentChannel > 10)&&(PIBAttributeValue->macBattLifeExtPeriods != 6))
00782 t_status = m_INVALID_PARAMETER;
00783 else
00784 mpib.macBattLifeExtPeriods = PIBAttributeValue->macBattLifeExtPeriods;
00785 break;
00786 case macBeaconPayload:
00787
00788 memcpy(mpib.macBeaconPayload,PIBAttributeValue->macBeaconPayload,mpib.macBeaconPayloadLength);
00789 break;
00790 case macBeaconPayloadLength:
00791 if (PIBAttributeValue->macBeaconPayloadLength > aMaxBeaconPayloadLength)
00792 t_status = m_INVALID_PARAMETER;
00793 else
00794 mpib.macBeaconPayloadLength = PIBAttributeValue->macBeaconPayloadLength;
00795 break;
00796 case macBeaconOrder:
00797 if (PIBAttributeValue->macBeaconOrder > 15)
00798 t_status = m_INVALID_PARAMETER;
00799 else
00800 mpib.macBeaconOrder = PIBAttributeValue->macBeaconOrder;
00801 break;
00802 case macBeaconTxTime:
00803 mpib.macBeaconTxTime = PIBAttributeValue->macBeaconTxTime;
00804 break;
00805 case macBSN:
00806 mpib.macBSN = PIBAttributeValue->macBSN;
00807 break;
00808 case macCoordExtendedAddress:
00809 mpib.macCoordExtendedAddress = PIBAttributeValue->macCoordExtendedAddress;
00810 break;
00811 case macCoordShortAddress:
00812 mpib.macCoordShortAddress = PIBAttributeValue->macCoordShortAddress;
00813 break;
00814 case macDSN:
00815 mpib.macDSN = PIBAttributeValue->macDSN;
00816 break;
00817 case macGTSPermit:
00818 mpib.macGTSPermit = PIBAttributeValue->macGTSPermit;
00819 break;
00820 case macMaxCSMABackoffs:
00821 if (PIBAttributeValue->macMaxCSMABackoffs > 5)
00822 t_status = m_INVALID_PARAMETER;
00823 else
00824 mpib.macMaxCSMABackoffs = PIBAttributeValue->macMaxCSMABackoffs;
00825 break;
00826 case macMinBE:
00827 if (PIBAttributeValue->macMinBE > 3)
00828 t_status = m_INVALID_PARAMETER;
00829 else
00830 mpib.macMinBE = PIBAttributeValue->macMinBE;
00831 break;
00832 case macPANId:
00833 mpib.macPANId = PIBAttributeValue->macPANId;
00834 break;
00835 case macPromiscuousMode:
00836 mpib.macPromiscuousMode = PIBAttributeValue->macPromiscuousMode;
00837
00838 mpib.macRxOnWhenIdle = PIBAttributeValue->macPromiscuousMode;
00839 p_state = mpib.macRxOnWhenIdle?p_RX_ON:p_TRX_OFF;
00840 phy->PLME_SET_TRX_STATE_request(p_state);
00841 break;
00842 case macRxOnWhenIdle:
00843 mpib.macRxOnWhenIdle = PIBAttributeValue->macRxOnWhenIdle;
00844 break;
00845 case macShortAddress:
00846 mpib.macShortAddress = PIBAttributeValue->macShortAddress;
00847 break;
00848 case macSuperframeOrder:
00849 if (PIBAttributeValue->macSuperframeOrder > 15)
00850 t_status = m_INVALID_PARAMETER;
00851 else
00852 mpib.macSuperframeOrder = PIBAttributeValue->macSuperframeOrder;
00853 break;
00854 case macTransactionPersistenceTime:
00855 mpib.macTransactionPersistenceTime = PIBAttributeValue->macTransactionPersistenceTime;
00856 break;
00857 case macACLEntryDescriptorSet:
00858 case macACLEntryDescriptorSetSize:
00859 case macDefaultSecurity:
00860 case macACLDefaultSecurityMaterialLength:
00861 case macDefaultSecurityMaterial:
00862 case macDefaultSecuritySuite:
00863 case macSecurityMode:
00864 break;
00865 default:
00866 t_status = m_UNSUPPORTED_ATTRIBUTE;
00867 break;
00868 }
00869 sscs->MLME_SET_confirm(t_status,PIBAttribute);
00870 }
00871
00872 void Mac802_15_4::MLME_START_request(UINT_16 PANId,UINT_8 LogicalChannel,UINT_8 BeaconOrder,
00873 UINT_8 SuperframeOrder,bool PANCoordinator,bool BatteryLifeExtension,
00874 bool CoordRealignment,bool SecurityEnable)
00875 {
00876 mlme_start_request(PANId,LogicalChannel,BeaconOrder,SuperframeOrder,PANCoordinator,BatteryLifeExtension,CoordRealignment,SecurityEnable,true);
00877 }
00878
00879 void Mac802_15_4::MLME_SYNC_request(UINT_8 LogicalChannel, bool TrackBeacon)
00880 {
00881 mlme_sync_request(LogicalChannel,TrackBeacon,true);
00882 }
00883
00884 void Mac802_15_4::MLME_POLL_request(UINT_8 CoordAddrMode,UINT_16 CoordPANId,IE3ADDR CoordAddress,bool SecurityEnable)
00885 {
00886 mlme_poll_request(CoordAddrMode,CoordPANId,CoordAddress,SecurityEnable,false,true);
00887 }
00888
00889 inline int Mac802_15_4::hdr_dst(char* hdr, int dst)
00890 {
00891 return p802_15_4hdr_dst(hdr,dst);
00892 }
00893
00894 inline int Mac802_15_4::hdr_src(char* hdr, int src)
00895 {
00896 return p802_15_4hdr_src(hdr,src);
00897 }
00898
00899 inline int Mac802_15_4::hdr_type(char* hdr, UINT_16 type)
00900 {
00901 return p802_15_4hdr_type(hdr,type);
00902 }
00903
00904 void Mac802_15_4::recv(Packet *p, Handler *h)
00905 {
00906 hdr_lrwpan* wph = HDR_LRWPAN(p);
00907 hdr_cmn *ch = HDR_CMN(p);
00908 bool noAck;
00909 int i;
00910 UINT_8 txop;
00911 FrameCtrl frmCtrl;
00912 SuperframeSpec t_sfSpec;
00913
00914 if (!Nam802_15_4::emStatus)
00915 Nam802_15_4::emStatus = (netif_->node()->energy_model()?true:false);
00916
00917 if(ch->direction() == hdr_cmn::DOWN)
00918 {
00919 #ifdef DEBUG802_15_4
00920 fprintf(stdout,"[%s::%s][%f](node %d) outgoing pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = ??, size = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),ch->size());
00921 #endif
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936 EnergyModel *em = netif_->node()->energy_model();
00937 if (em)
00938 {
00939 if (em->energy() <= 0)
00940 {
00941 drop(p,"ENE");
00942 return;
00943 }
00944 if (em->sleep())
00945 {
00946 em->set_node_sleep(0);
00947 em->set_node_state(EnergyModel::INROUTE);
00948 }
00949 }
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959 {
00960 callback_ = h;
00961 if (p802_15_4macDA(p) == (nsaddr_t)MAC_BROADCAST)
00962 txop = 0;
00963 else
00964 {
00965 if (Mac802_15_4::ack4data)
00966 txop = TxOp_Acked;
00967 else
00968 txop = 0;
00969 txop |= Mac802_15_4::txOption;
00970 }
00971 wph->msduHandle = 0;
00972 MCPS_DATA_request(0,0,0,defFrmCtrl_AddrMode16,mpib.macPANId,p802_15_4macDA(p),ch->size(),p,0,txop);
00973 }
00974 return;
00975 }
00976 else
00977 {
00978 #ifdef DEBUG802_15_4
00979 fprintf(stdout,"[%s::%s][%f](node %d) incoming pkt: 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());
00980 #endif
00981 resetCounter(p802_15_4macSA(p));
00982
00983
00984
00985 frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
00986 frmCtrl.parse();
00987 if (taskP.taskStatus(TP_mlme_scan_request))
00988 if (taskP.mlme_scan_request_ScanType == 0x00)
00989 {
00990 #ifdef DEBUG802_15_4
00991 fprintf(stdout,"[D][ED][%s::%s::%d][%f](node %d) dropping pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,__LINE__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());
00992 #endif
00993 drop(p,"ED");
00994 return;
00995 }
00996 else if (((taskP.mlme_scan_request_ScanType == 0x01)
00997 ||(taskP.mlme_scan_request_ScanType == 0x02))
00998 && (frmCtrl.frmType != defFrmCtrl_Type_Beacon))
00999 {
01000 #ifdef DEBUG802_15_4
01001 fprintf(stdout,"[D][APS][%s::%s::%d][%f](node %d) dropping pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,__LINE__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());
01002 #endif
01003 drop(p,"APS");
01004 return;
01005 }
01006 else if ((taskP.mlme_scan_request_ScanType == 0x03)
01007 && ((frmCtrl.frmType != defFrmCtrl_Type_MacCmd)||(wph->MSDU_CmdType != 0x08)))
01008 {
01009 #ifdef DEBUG802_15_4
01010 fprintf(stdout,"[D][OPH][%s::%s::%d][%f](node %d) dropping pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,__LINE__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());
01011 #endif
01012 drop(p,"OPH");
01013 return;
01014 }
01015
01016
01017 if (ch->error())
01018 {
01019 #ifdef DEBUG802_15_4
01020 fprintf(stdout,"[D][ERR][%s::%s::%d][%f](node %d) dropping pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,__LINE__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());
01021 #endif
01022 drop(p,"ERR");
01023 return;
01024 }
01025
01026 if ((wph->rxTotPower-p->txinfo_.RxPr) > 0.0)
01027 if (p->txinfo_.RxPr/(wph->rxTotPower-p->txinfo_.RxPr) < p->txinfo_.CPThresh)
01028 {
01029 #ifdef DEBUG802_15_4
01030 fprintf(stdout,"[D][LQI][%s::%s::%d][%f](node %d) dropping pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,__LINE__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());
01031 #endif
01032 if (!wph->colFlag)
01033 nam->flashNodeColor(CURRENT_TIME);
01034 drop(p,"LQI");
01035 return;
01036 }
01037
01038 if (frmCtrl.frmType == defFrmCtrl_Type_Beacon)
01039 {
01040 t_sfSpec.SuperSpec = wph->MSDU_SuperSpec;
01041 t_sfSpec.parse();
01042 if (t_sfSpec.BO != 15)
01043 {
01044
01045 sfSpec3 = t_sfSpec;
01046
01047 macBcnOtherRxTime = (CURRENT_TIME - phy->trxTime(p)) * phy->getRate('s');
01048
01049 macBeaconOrder3 = sfSpec3.BO;
01050 macSuperframeOrder3 = sfSpec3.SO;
01051 }
01052 }
01053
01054
01055
01056 if (ch->ptype() == PT_MAC)
01057 if (!mpib.macPromiscuousMode)
01058 {
01059
01060 if ((frmCtrl.frmType != defFrmCtrl_Type_Beacon)
01061 &&(frmCtrl.frmType != defFrmCtrl_Type_Data)
01062 &&(frmCtrl.frmType != defFrmCtrl_Type_Ack)
01063 &&(frmCtrl.frmType != defFrmCtrl_Type_MacCmd))
01064 {
01065 #ifdef DEBUG802_15_4
01066 fprintf(stdout,"[D][TYPE][%s::%s::%d][%f](node %d) dropping pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,__LINE__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());
01067 #endif
01068 drop(p,"TYPE");
01069 return;
01070 }
01071
01072 if ((frmCtrl.frmType == defFrmCtrl_Type_Beacon)
01073 &&(mpib.macPANId != 0xffff)
01074 &&(wph->MHR_SrcAddrInfo.panID != mpib.macPANId))
01075 {
01076 #ifdef DEBUG802_15_4
01077 fprintf(stdout,"[D][PAN][%s::%s::%d][%f](node %d) dropping pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,__LINE__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());
01078 #endif
01079 drop(p,"PAN");
01080 return;
01081 }
01082
01083 if ((frmCtrl.dstAddrMode == defFrmCtrl_AddrMode16)
01084 ||(frmCtrl.dstAddrMode == defFrmCtrl_AddrMode64))
01085 if ((wph->MHR_DstAddrInfo.panID != 0xffff)
01086 &&(wph->MHR_DstAddrInfo.panID != mpib.macPANId))
01087 {
01088 #ifdef DEBUG802_15_4
01089 fprintf(stdout,"[D][PAN][%s::%s::%d][%f](node %d) dropping pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,__LINE__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());
01090 #endif
01091 drop(p,"PAN");
01092 return;
01093 }
01094
01095 if (frmCtrl.dstAddrMode == defFrmCtrl_AddrMode16)
01096 {
01097 if ((wph->MHR_DstAddrInfo.addr_16 != 0xffff)
01098 && (wph->MHR_DstAddrInfo.addr_16 != mpib.macShortAddress))
01099 {
01100 #ifdef DEBUG802_15_4
01101 fprintf(stdout,"[D][ADR][%s::%s::%d][%f](node %d) dropping pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,__LINE__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());
01102 #endif
01103 drop(p,"ADR");
01104 return;
01105 }
01106
01107 }
01108 else if (frmCtrl.dstAddrMode == defFrmCtrl_AddrMode64)
01109 {
01110 if (wph->MHR_DstAddrInfo.addr_64 != aExtendedAddress)
01111 {
01112 #ifdef DEBUG802_15_4
01113 fprintf(stdout,"[D][ADR][%s::%s::%d][%f](node %d) dropping pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,__LINE__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());
01114 #endif
01115 drop(p,"ADR");
01116 return;
01117 }
01118 }
01119
01120 if ((frmCtrl.frmType == defFrmCtrl_Type_Data)
01121 ||(frmCtrl.frmType == defFrmCtrl_Type_MacCmd))
01122 if (frmCtrl.dstAddrMode == defFrmCtrl_AddrModeNone)
01123 {
01124 if (((!capability.FFD)||(numberDeviceLink(&deviceLink1) == 0))
01125 ||(wph->MHR_SrcAddrInfo.panID != mpib.macPANId))
01126 {
01127 #ifdef DEBUG802_15_4
01128 fprintf(stdout,"[D][PAN][%s::%s::%d][%f](node %d) dropping pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,__LINE__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());
01129 #endif
01130 drop(p,"PAN");
01131 return;
01132 }
01133 }
01134
01135 if (frmCtrl.frmType == defFrmCtrl_Type_Beacon)
01136 if (wph->MHR_DstAddrInfo.panID != 0xffff)
01137 if ((mpib.macCoordExtendedAddress != wph->MHR_SrcAddrInfo.addr_64)
01138 && (mpib.macCoordExtendedAddress != def_macCoordExtendedAddress))
01139 {
01140 #ifdef DEBUG802_15_4
01141 fprintf(stdout,"[D][COO][%s::%s::%d][%f](node %d) dropping pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,__LINE__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());
01142 #endif
01143 drop(p,"COO");
01144 return;
01145 }
01146 }
01147
01148
01149
01150
01151 if ((frmCtrl.frmType == defFrmCtrl_Type_Data)
01152 ||(frmCtrl.frmType == defFrmCtrl_Type_MacCmd))
01153 if (frmCtrl.ackReq)
01154 {
01155
01156 if ((frmCtrl.frmType == defFrmCtrl_Type_MacCmd)
01157 && (wph->MSDU_CmdType == 0x01))
01158 if ((!capability.FFD)
01159 || (mpib.macShortAddress == 0xffff)
01160 || (!macAssociationPermit))
01161 {
01162 Packet::free(p);
01163 return;
01164 }
01165
01166 noAck = false;
01167 if (frmCtrl.frmType == defFrmCtrl_Type_MacCmd)
01168 if ((rxCmd)||(txBcnCmd))
01169 noAck = true;
01170 if (!noAck)
01171 {
01172 constructACK(p);
01173
01174 if (backoffStatus == 99)
01175 {
01176 backoffStatus = 0;
01177 csmaca->cancel();
01178 }
01179 plme_set_trx_state_request(p_TX_ON);
01180 }
01181 }
01182 else
01183 resetTRX();
01184
01185 if (frmCtrl.frmType == defFrmCtrl_Type_MacCmd)
01186 if ((rxCmd)||(txBcnCmd))
01187 {
01188 #ifdef DEBUG802_15_4
01189 {
01190 fprintf(stdout,"[D][BSY][%s::%s::%d][%f](node %d) dropping pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,__LINE__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());
01191 if (rxCmd)
01192 fprintf(stdout,"\trxCmd pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",wpan_pName(rxCmd),p802_15_4macSA(rxCmd),p802_15_4macDA(rxCmd),HDR_CMN(rxCmd)->uid(),HDR_LRWPAN(rxCmd)->uid,HDR_CMN(rxCmd)->size());
01193 if (txBcnCmd)
01194 fprintf(stdout,"\ttxBcnCmd pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",wpan_pName(txBcnCmd),p802_15_4macSA(txBcnCmd),p802_15_4macDA(txBcnCmd),HDR_CMN(txBcnCmd)->uid(),HDR_LRWPAN(txBcnCmd)->uid,HDR_CMN(txBcnCmd)->size());
01195 }
01196 #endif
01197 drop(p,"BSY");
01198 return;
01199 }
01200
01201 if (frmCtrl.frmType == defFrmCtrl_Type_Data)
01202 if (rxData)
01203 {
01204 #ifdef DEBUG802_15_4
01205 fprintf(stdout,"[D][BSY][%s::%s::%d][%f](node %d) dropping pkt: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,__LINE__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),p802_15_4macDA(p),ch->uid(),wph->uid,ch->size());
01206 #endif
01207 drop(p,"BSY");
01208 return;
01209 }
01210
01211
01212 if (frmCtrl.frmType == defFrmCtrl_Type_Beacon)
01213 i = chkAddUpdHListLink(&hlistBLink1,&hlistBLink2,p802_15_4macSA(p),wph->MHR_BDSN);
01214 else if (frmCtrl.frmType != defFrmCtrl_Type_Ack)
01215 i = chkAddUpdHListLink(&hlistDLink1,&hlistDLink2,p802_15_4macSA(p),wph->MHR_BDSN);
01216 else
01217 {
01218 assert(txPkt);
01219 if (wph->MHR_BDSN != HDR_LRWPAN(txPkt)->MHR_BDSN)
01220 i = 2;
01221 else i = 0;
01222 }
01223 if (i == 2)
01224 {
01225 #ifdef DEBUG802_15_4
01226 fprintf(stdout,"[D][DUP][%s::%s][%f](node %d) dropping duplicated packet: type = %s, from = %d, uid = %d, mac_uid = %ld, size = %d, SN = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),ch->uid(),wph->uid,ch->size(),wph->MHR_BDSN);
01227 #endif
01228 drop(p,"DUP");
01229 return;
01230 }
01231
01232
01233 if (frmCtrl.frmType == defFrmCtrl_Type_Beacon)
01234 recvBeacon(p);
01235
01236
01237 else if (frmCtrl.frmType == defFrmCtrl_Type_Ack)
01238 recvAck(p);
01239
01240
01241 else if (frmCtrl.frmType == defFrmCtrl_Type_MacCmd)
01242 recvCommand(p);
01243
01244
01245 else if (frmCtrl.frmType == defFrmCtrl_Type_Data)
01246 {
01247 recvData(p);
01248 }
01249 }
01250 }
01251
01252 void Mac802_15_4::recvBeacon(Packet *p)
01253 {
01254 hdr_lrwpan* wph = HDR_LRWPAN(p);
01255 FrameCtrl frmCtrl;
01256 PendAddrSpec pendSpec;
01257 bool pending;
01258 double txtime;
01259 UINT_8 ifs;
01260 int i;
01261
01262 sfSpec2.SuperSpec = wph->MSDU_SuperSpec;
01263 sfSpec2.parse();
01264 #ifdef DEBUG802_15_4
01265 hdr_cmn* ch = HDR_CMN(p);
01266 fprintf(stdout,"[%s::%s][%f](node %d) M_BEACON [BO:%d][SO:%d] received: from = %d, uid = %d, mac_uid = %ld, size = %d, SN = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,sfSpec2.BO,sfSpec2.SO,p802_15_4macSA(p),ch->uid(),wph->uid,ch->size(),wph->MHR_BDSN);
01267 #endif
01268
01269 txtime = phy->trxTime(p);
01270
01271
01272
01273
01274 {
01275 double tmpf;
01276 tmpf = CURRENT_TIME - txtime;
01277 macBcnRxTime = tmpf * phy->getRate('s');
01278 }
01279
01280
01281 if (HDR_CMN(p)->size() <= aMaxSIFSFrameSize)
01282 ifs = aMinSIFSPeriod;
01283 else
01284 ifs = aMinLIFSPeriod;
01285
01286
01287
01288
01289 double tmpf;
01290 tmpf = txtime * phy->getRate('s');
01291 tmpf += ifs;
01292 beaconPeriods2 = (UINT_8)(tmpf / aUnitBackoffPeriod);
01293
01294
01295
01296
01297 if (fmod(tmpf ,aUnitBackoffPeriod) > 0.0)
01298 beaconPeriods2++;
01299
01300 frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
01301 frmCtrl.parse();
01302 panDes2.CoordAddrMode = frmCtrl.srcAddrMode;
01303 panDes2.CoordPANId = wph->MHR_SrcAddrInfo.panID;
01304 panDes2.CoordAddress_64 = wph->MHR_SrcAddrInfo.addr_64;
01305 panDes2.LogicalChannel = wph->phyCurrentChannel;
01306 panDes2.SuperframeSpec = wph->MSDU_SuperSpec;
01307 gtsSpec2.fields = wph->MSDU_GTSFields;
01308 gtsSpec2.parse();
01309 panDes2.GTSPermit = gtsSpec2.permit;
01310 panDes2.LinkQuality = wph->ppduLinkQuality;
01311 panDes2.TimeStamp = (UINT_32)macBcnRxTime;
01312 panDes2.SecurityUse = wph->SecurityUse;
01313 panDes2.ACLEntry = wph->ACLEntry;
01314 panDes2.SecurityFailure = false;
01315 panDes2.clusTreeDepth = wph->clusTreeDepth;
01316
01317 if ((taskP.taskStatus(TP_mlme_scan_request))
01318 || (taskP.taskStatus(TP_mlme_rx_enable_request)))
01319 {
01320 rxBeacon = p;
01321 dispatch(p_SUCCESS,__FUNCTION__);
01322 }
01323
01324 if ((mpib.macPANId == 0xffff)
01325 || (mpib.macPANId != panDes2.CoordPANId)
01326 || (taskP.taskStatus(TP_mlme_associate_request)))
01327 {
01328 Packet::free(p);
01329 return;
01330 }
01331 numLostBeacons = 0;
01332 nam->flashNodeMark(CURRENT_TIME);
01333 macBeaconOrder2 = sfSpec2.BO;
01334 macSuperframeOrder2 = sfSpec2.SO;
01335
01336 if (mpib.macCoordShortAddress == def_macCoordShortAddress)
01337 if (frmCtrl.srcAddrMode == defFrmCtrl_AddrMode16)
01338 mpib.macCoordShortAddress = wph->MHR_SrcAddrInfo.addr_16;
01339 dispatch(p_SUCCESS,__FUNCTION__);
01340
01341 extractT->resume();
01342
01343 if (wph->MHR_SrcAddrInfo.panID == mpib.macPANId)
01344 if (backoffStatus == 99)
01345 csmaca->newBeacon('r');
01346
01347
01348 if ((!mpib.macAutoRequest)||(wph->MSDU_PayloadLen > 0))
01349 sscs->MLME_BEACON_NOTIFY_indication(wph->MHR_BDSN,&panDes2,wph->MSDU_PendAddrFields.spec,wph->MSDU_PendAddrFields.addrList,wph->MSDU_PayloadLen,wph->MSDU_Payload);
01350 if (mpib.macAutoRequest)
01351 {
01352
01353 pendSpec.fields = wph->MSDU_PendAddrFields;
01354 pendSpec.parse();
01355 pending = false;
01356 for (i=0;i<pendSpec.numShortAddr;i++)
01357 {
01358 if (pendSpec.fields.addrList[i] == mpib.macShortAddress)
01359 {
01360 pending = true;
01361 break;
01362 }
01363 }
01364 if (!pending)
01365 for (i=0;i<pendSpec.numExtendedAddr;i++)
01366 {
01367 if (pendSpec.fields.addrList[pendSpec.numShortAddr + i] == aExtendedAddress)
01368 {
01369 pending = true;
01370 break;
01371 }
01372 }
01373
01374 if (pending)
01375 {
01376
01377
01378 mlme_poll_request(frmCtrl.srcAddrMode,wph->MHR_SrcAddrInfo.panID,wph->MHR_SrcAddrInfo.addr_64,capability.secuCapable,true,true);
01379 }
01380
01381 log(p);
01382 }
01383 }
01384
01385 void Mac802_15_4::recvAck(Packet *p)
01386 {
01387 hdr_lrwpan *wph;
01388 hdr_cmn *ch;
01389 FrameCtrl frmCtrl;
01390
01391 wph = HDR_LRWPAN(p);
01392 ch = HDR_CMN(p);
01393 #ifdef DEBUG802_15_4
01394 fprintf(stdout,"[%s::%s][%f](node %d) M_ACK received: from = %d, SN = %d, uid = %d, mac_uid = %ld\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,p802_15_4macSA(p),wph->MHR_BDSN,ch->uid(),wph->uid);
01395 #endif
01396 if ((!txBcnCmd)&&(!txBcnCmd2)&&(!txData))
01397 {
01398 Packet::free(p);
01399 return;
01400 }
01401
01402
01403 if (wph->MHR_BDSN != HDR_LRWPAN(txPkt)->MHR_BDSN)
01404 {
01405 Packet::free(p);
01406 return;
01407 }
01408
01409 if (txT->busy())
01410 txT->stop();
01411 else
01412 {
01413 #ifdef DEBUG802_15_4
01414 fprintf(stdout,"[%s::%s][%f](node %d) LATE ACK received: from = %d, SN = %d, uid = %d, mac_uid = %ld\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,p802_15_4macSA(p),wph->MHR_BDSN,ch->uid(),wph->uid);
01415 #endif
01416
01417 if (txPkt != txData)
01418 {
01419 Packet::free(p);
01420 return;
01421 }
01422
01423 if (backoffStatus == 99)
01424 {
01425 backoffStatus = 0;
01426 csmaca->cancel();
01427 }
01428 }
01429
01430
01431 if (txPkt == txBcnCmd2)
01432 if ((taskP.taskStatus(TP_mlme_poll_request))
01433 && (strcmp(taskP.taskFrFunc(TP_mlme_poll_request),__FUNCTION__) == 0))
01434 {
01435 frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
01436 frmCtrl.parse();
01437 taskP.mlme_poll_request_pending = frmCtrl.frmPending;
01438 }
01439
01440 dispatch(p_SUCCESS,__FUNCTION__);
01441
01442 log(p);
01443 }
01444
01445 void Mac802_15_4::recvCommand(Packet *p)
01446 {
01447 hdr_lrwpan* wph;
01448 FrameCtrl frmCtrl;
01449 bool ackReq;
01450
01451 #ifdef DEBUG802_15_4
01452 wph = HDR_LRWPAN(p);
01453 hdr_cmn* ch = HDR_CMN(p);
01454 fprintf(stdout,"[%s::%s][%f](node %d) %s received: from = %d, uid = %d, mac_uid = %ld, size = %d, SN = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),ch->uid(),wph->uid,ch->size(),wph->MHR_BDSN);
01455 #endif
01456 ackReq = false;
01457 switch(HDR_LRWPAN(p)->MSDU_CmdType)
01458 {
01459 case 0x01:
01460
01461
01462 assert(rxCmd == 0);
01463 rxCmd = p;
01464 ackReq = true;
01465 break;
01466 case 0x02:
01467
01468
01469 assert(rxCmd == 0);
01470 rxCmd = p;
01471 ackReq = true;
01472 wph = HDR_LRWPAN(p);
01473 rt_myNodeID = *((UINT_16 *)wph->MSDU_Payload);
01474 #ifdef ZigBeeIF
01475 sscs->setGetClusTreePara('g',p);
01476 #endif
01477 break;
01478 case 0x03:
01479 break;
01480 case 0x04:
01481
01482
01483 assert(rxCmd == 0);
01484 rxCmd = p;
01485 ackReq = true;
01486 break;
01487 case 0x05:
01488 break;
01489 case 0x06:
01490 wph = HDR_LRWPAN(p);
01491 sscs->MLME_ORPHAN_indication(wph->MHR_SrcAddrInfo.addr_64,false,0);
01492 break;
01493 case 0x07:
01494 if (capability.FFD
01495 && (mpib.macAssociationPermit)
01496 && (mpib.macShortAddress != 0xffff)
01497 && (mpib.macBeaconOrder == 15))
01498 {
01499
01500 #ifdef DEBUG802_15_4
01501 fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBcnCmd:\n\t\ttxBeacon\t= %ld\n\t\ttxAck \t= %ld\n\t\ttxBcnCmd\t= %ld\n\t\ttxBcnCmd2\t= %ld\n\t\ttxData \t= %ld\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
01502 #endif
01503 assert(!txBcnCmd);
01504 txBcnCmd = Packet::alloc();
01505 if (!txBcnCmd) break;
01506 wph = HDR_LRWPAN(txBcnCmd);
01507 frmCtrl.FrmCtrl = 0;
01508 frmCtrl.setFrmType(defFrmCtrl_Type_Beacon);
01509 frmCtrl.setSecu(secuBeacon);
01510 frmCtrl.setFrmPending(false);
01511 frmCtrl.setAckReq(false);
01512 frmCtrl.setDstAddrMode(defFrmCtrl_AddrModeNone);
01513 if (mpib.macShortAddress == 0xfffe)
01514 {
01515 frmCtrl.setSrcAddrMode(defFrmCtrl_AddrMode64);
01516 wph->MHR_SrcAddrInfo.panID = mpib.macPANId;
01517 wph->MHR_SrcAddrInfo.addr_64 = aExtendedAddress;
01518 }
01519 else
01520 {
01521 frmCtrl.setSrcAddrMode(defFrmCtrl_AddrMode16);
01522 wph->MHR_SrcAddrInfo.panID = mpib.macPANId;
01523 wph->MHR_SrcAddrInfo.addr_16 = mpib.macShortAddress;
01524 }
01525 sfSpec.SuperSpec = 0;
01526 sfSpec.setBO(15);
01527 sfSpec.setBLE(mpib.macBattLifeExt);
01528 sfSpec.setPANCoor(isPANCoor);
01529 sfSpec.setAssoPmt(mpib.macAssociationPermit);
01530 wph->MSDU_GTSFields.spec = 0;
01531 wph->MSDU_PendAddrFields.spec = 0;
01532 wph->MSDU_PayloadLen = 0;
01533 #ifdef ZigBeeIF
01534 sscs->setGetClusTreePara('s',txBcnCmd);
01535 #endif
01536 constructMPDU(4,txBcnCmd,frmCtrl.FrmCtrl,mpib.macBSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,sfSpec.SuperSpec,0,0);
01537 hdr_dst((char *)HDR_MAC(txBcnCmd),p802_15_4macSA(p));
01538 hdr_src((char *)HDR_MAC(txBcnCmd),index_);
01539 HDR_CMN(txBcnCmd)->ptype() = PT_MAC;
01540
01541 HDR_CMN(txBcnCmd)->next_hop_ = p802_15_4macDA(txBcnCmd);
01542 p802_15_4hdrBeacon(txBcnCmd);
01543 csmacaBegin('c');
01544 }
01545 break;
01546 case 0x08:
01547 wph = HDR_LRWPAN(p);
01548 frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
01549 frmCtrl.parse();
01550 if (frmCtrl.dstAddrMode == defFrmCtrl_AddrMode64)
01551 {
01552
01553
01554 assert(rxCmd == 0);
01555 rxCmd = p;
01556 ackReq = true;
01557 }
01558 else
01559 if ((wph->MHR_SrcAddrInfo.addr_64 == macCoordExtendedAddress)
01560 && (wph->MHR_SrcAddrInfo.panID == mpib.macPANId))
01561 {
01562
01563 mpib.macPANId = *((UINT_16 *)wph->MSDU_Payload);
01564 mpib.macCoordShortAddress = *((UINT_16 *)(wph->MSDU_Payload + 2));
01565 tmp_ppib.phyCurrentChannel = wph->MSDU_Payload[4];
01566 phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
01567 }
01568 break;
01569 case 0x09:
01570 break;
01571 default:
01572 assert(0);
01573 break;
01574 }
01575
01576 if (!ackReq)
01577 log(p);
01578 else
01579 log(p->refcopy());
01580 }
01581
01582 void Mac802_15_4::recvData(Packet *p)
01583 {
01584 hdr_lrwpan* wph;
01585 hdr_cmn* ch;
01586 FrameCtrl frmCtrl;
01587 UINT_8 ifs;
01588
01589
01590
01591
01592 assert(rxData == 0);
01593 rxData = p;
01594 wph = HDR_LRWPAN(p);
01595 ch = HDR_CMN(p);
01596 #ifdef DEBUG802_15_4
01597 fprintf(stdout,"[%s::%s][%f](node %d) DATA (%s) received: from = %d, uid = %d, mac_uid = %ld, size = %d, SN = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(p),p802_15_4macSA(p),ch->uid(),wph->uid,ch->size(),wph->MHR_BDSN);
01598 #endif
01599 frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
01600 frmCtrl.parse();
01601 rxDataTime = CURRENT_TIME;
01602 if (!frmCtrl.ackReq)
01603 {
01604 if (ch->size() <= aMaxSIFSFrameSize)
01605 ifs = aMinSIFSPeriod;
01606 else
01607 ifs = aMinLIFSPeriod;
01608 Scheduler::instance().schedule(&IFSH, &(IFSH.nullEvent), ifs/phy->getRate('s'));
01609 }
01610
01611 }
01612
01613 bool Mac802_15_4::toParent(Packet *p)
01614 {
01615 hdr_lrwpan* wph = HDR_LRWPAN(p);
01616 FrameCtrl frmCtrl;
01617
01618 frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
01619 frmCtrl.parse();
01620 if (((frmCtrl.dstAddrMode == defFrmCtrl_AddrMode16)&&(wph->MHR_DstAddrInfo.addr_16 == mpib.macCoordShortAddress))
01621 || ((frmCtrl.dstAddrMode == defFrmCtrl_AddrMode64)&&(wph->MHR_DstAddrInfo.addr_64 == mpib.macCoordExtendedAddress)))
01622 return true;
01623 else
01624 return false;
01625 }
01626
01627 double Mac802_15_4::locateBoundary(bool parent,double wtime)
01628 {
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640 int align;
01641 double bcnTxRxTime,bPeriod;
01642 double newtime;
01643
01644 if ((mpib.macBeaconOrder == 15)&&(macBeaconOrder2 == 15))
01645 return wtime;
01646
01647 if (parent)
01648 align = (macBeaconOrder2 == 15)?1:2;
01649 else
01650 align = (mpib.macBeaconOrder == 15)?2:1;
01651
01652 bcnTxRxTime = (align == 1)?(macBcnTxTime / phy->getRate('s')):(macBcnRxTime / phy->getRate('s'));
01653 bPeriod = aUnitBackoffPeriod / phy->getRate('s');
01654
01655
01656
01657
01658 {
01659 double tmpf;
01660 tmpf = CURRENT_TIME + wtime;
01661 tmpf -= bcnTxRxTime;
01662 newtime = fmod(tmpf, bPeriod);
01663 }
01664
01665 #ifdef DEBUG802_15_4
01666
01667 #endif
01668 if(newtime > 0.0)
01669 {
01670
01671
01672
01673 {
01674 double tmpf;
01675 tmpf = bPeriod - newtime;
01676 newtime = wtime + tmpf;
01677 }
01678 }
01679 else
01680 newtime = wtime;
01681
01682 return newtime;
01683 }
01684
01685 void Mac802_15_4::txOverHandler(void)
01686 {
01687 assert(txPkt);
01688 PD_DATA_confirm(p_UNDEFINED);
01689 }
01690
01691 void Mac802_15_4::txHandler(void)
01692 {
01693 assert(txBcnCmd||txBcnCmd2||txData);
01694
01695 Packet *p;
01696 hdr_lrwpan* wph;
01697 hdr_cmn* ch;
01698 UINT_8 t_numRetry;
01699
01700 if (txBcnCmd) p = txBcnCmd;
01701 else if (txBcnCmd2) p = txBcnCmd2;
01702 else p = txData;
01703 wph = HDR_LRWPAN(p);
01704 ch = HDR_CMN(p);
01705
01706 if (txBcnCmd) t_numRetry = numBcnCmdRetry;
01707 else if (txBcnCmd2) t_numRetry = numBcnCmdRetry2;
01708 else t_numRetry = numDataRetry;
01709 t_numRetry++;
01710 #ifdef DEBUG802_15_4
01711 if (t_numRetry <= aMaxFrameRetries)
01712 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());
01713 else
01714 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());
01715 #endif
01716 if (t_numRetry > aMaxFrameRetries)
01717 nam->flashLinkFail(CURRENT_TIME,p802_15_4macDA(p));
01718
01719 dispatch(p_BUSY,__FUNCTION__);
01720 }
01721
01722 void Mac802_15_4::extractHandler(void)
01723 {
01724 if (taskP.taskStatus(TP_mlme_associate_request))
01725 strcpy(taskP.taskFrFunc(TP_mlme_associate_request),__FUNCTION__);
01726 dispatch(p_BUSY,__FUNCTION__);
01727 }
01728
01729 void Mac802_15_4::assoRspWaitHandler(void)
01730 {
01731 dispatch(p_BUSY,__FUNCTION__);
01732 }
01733
01734 void Mac802_15_4::dataWaitHandler(void)
01735 {
01736 dispatch(p_BUSY,__FUNCTION__);
01737 }
01738
01739 void Mac802_15_4::rxEnableHandler(void)
01740 {
01741 dispatch(p_SUCCESS,__FUNCTION__);
01742 }
01743
01744 void Mac802_15_4::scanHandler(void)
01745 {
01746 if (taskP.mlme_scan_request_ScanType == 0x01)
01747 taskP.taskStep(TP_mlme_scan_request)++;
01748 dispatch(p_SUCCESS,__FUNCTION__);
01749 }
01750
01751 void Mac802_15_4::beaconTxHandler(bool forTX)
01752 {
01753 hdr_lrwpan* wph;
01754 FrameCtrl frmCtrl;
01755 TRANSACLINK *tmp;
01756 int i;
01757
01758 if ((mpib.macBeaconOrder != 15)
01759 || (oneMoreBeacon))
01760 if (forTX)
01761 {
01762 if (capability.FFD)
01763 {
01764
01765 beaconWaiting = true;
01766 plme_set_trx_state_request(p_FORCE_TRX_OFF);
01767
01768
01769
01770
01771
01772 if (txAck)
01773 {
01774 #ifdef DEBUG802_15_4
01775 if (!updateDeviceLink(tr_oper_est, &deviceLink1, &deviceLink2, p802_15_4macDA(txAck)))
01776 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());
01777 #endif
01778 Packet::free(txAck);
01779 txAck = 0;
01780 }
01781 plme_set_trx_state_request(p_TX_ON);
01782 }
01783 else
01784 assert(0);
01785 }
01786 else
01787 {
01788 if (capability.FFD)
01789 {
01790
01791 if ((taskP.taskStatus(TP_mlme_start_request))
01792 && (mpib.macBeaconOrder != 15))
01793 {
01794 if (txAck||backoffStatus == 1)
01795 {
01796 beaconWaiting = false;
01797 bcnTxT->start();
01798 return;
01799 }
01800 }
01801 #ifdef DEBUG802_15_4
01802 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);
01803 #endif
01804 if (updateNFailLink(fl_oper_est,index_) == 0)
01805 {
01806 if (txBeacon)
01807 {
01808 Packet::free(txBeacon);
01809 txBeacon = 0;
01810 }
01811 beaconWaiting = false;
01812 bcnTxT->start();
01813 return;
01814 }
01815 assert(!txBeacon);
01816 txBeacon = Packet::alloc();
01817 if (!txBeacon)
01818 {
01819 bcnTxT->start();
01820 return;
01821 }
01822 wph = HDR_LRWPAN(txBeacon);
01823 frmCtrl.FrmCtrl = 0;
01824 frmCtrl.setFrmType(defFrmCtrl_Type_Beacon);
01825 frmCtrl.setSecu(secuBeacon);
01826 frmCtrl.setAckReq(false);
01827 frmCtrl.setDstAddrMode(defFrmCtrl_AddrModeNone);
01828 if (mpib.macShortAddress == 0xfffe)
01829 {
01830 frmCtrl.setSrcAddrMode(defFrmCtrl_AddrMode64);
01831 wph->MHR_SrcAddrInfo.panID = mpib.macPANId;
01832 wph->MHR_SrcAddrInfo.addr_64 = aExtendedAddress;
01833 }
01834 else
01835 {
01836 frmCtrl.setSrcAddrMode(defFrmCtrl_AddrMode16);
01837 wph->MHR_SrcAddrInfo.panID = mpib.macPANId;
01838 wph->MHR_SrcAddrInfo.addr_16 = mpib.macShortAddress;
01839 }
01840 sfSpec.SuperSpec = 0;
01841 sfSpec.setBO(mpib.macBeaconOrder);
01842 sfSpec.setSO(mpib.macSuperframeOrder);
01843 sfSpec.setFinCAP(aNumSuperframeSlots - 1);
01844 sfSpec.setBLE(mpib.macBattLifeExt);
01845 sfSpec.setPANCoor(isPANCoor);
01846 sfSpec.setAssoPmt(mpib.macAssociationPermit);
01847
01848 gtsSpec.fields.spec = 0;
01849 gtsSpec.setPermit(mpib.macGTSPermit);
01850 wph->MSDU_GTSFields = gtsSpec.fields;
01851
01852 pendAddrSpec.numShortAddr = 0;
01853 pendAddrSpec.numExtendedAddr = 0;
01854 purgeTransacLink(&transacLink1,&transacLink2);
01855 tmp = transacLink1;
01856 i = 0;
01857 while (tmp != NULL)
01858 {
01859 if (tmp->pendAddrMode == defFrmCtrl_AddrMode16)
01860 {
01861 if (updateDeviceLink(tr_oper_est,&deviceLink1,&deviceLink2,tmp->pendAddr64) == 0)
01862 i = pendAddrSpec.addShortAddr(tmp->pendAddr16);
01863 }
01864 else
01865 {
01866 if (updateDeviceLink(tr_oper_est,&deviceLink1,&deviceLink2,tmp->pendAddr64) == 0)
01867 i = pendAddrSpec.addExtendedAddr(tmp->pendAddr64);
01868 }
01869 if (i >= 7) break;
01870 tmp = tmp->next;
01871 }
01872 pendAddrSpec.format();
01873 wph->MSDU_PendAddrFields = pendAddrSpec.fields;
01874 frmCtrl.setFrmPending(i>0);
01875
01876
01877 wph->MSDU_PayloadLen = mpib.macBeaconPayloadLength;
01878 memcpy(wph->MSDU_Payload,mpib.macBeaconPayload,mpib.macBeaconPayloadLength);
01879
01880 #ifdef ZigBeeIF
01881 sscs->setGetClusTreePara('s',txBeacon);
01882 #endif
01883 constructMPDU(2 + gtsSpec.size() + pendAddrSpec.size() + mpib.macBeaconPayloadLength,txBeacon,frmCtrl.FrmCtrl,mpib.macBSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,sfSpec.SuperSpec,0,0);
01884 hdr_src((char *)HDR_MAC(txBeacon),index_);
01885 hdr_dst((char *)HDR_MAC(txBeacon),MAC_BROADCAST);
01886 HDR_CMN(txBeacon)->ptype() = PT_MAC;
01887 HDR_CMN(txBeacon)->next_hop_ = p802_15_4macDA(txBeacon);
01888 p802_15_4hdrBeacon(txBeacon);
01889 #ifdef DEBUG802_15_4
01890 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);
01891 #endif
01892 txPkt = txBeacon;
01893 HDR_CMN(txBeacon)->direction() = hdr_cmn::DOWN;
01894
01895 sendDown(txBeacon->refcopy(), this);
01896 mpib.macBeaconTxTime = (UINT_32)(CURRENT_TIME * phy->getRate('s'));
01897 macBcnTxTime = CURRENT_TIME * phy->getRate('s');
01898 oneMoreBeacon = false;
01899 }
01900 else
01901 assert(0);
01902 }
01903 bcnTxT->start();
01904 }
01905
01906 void Mac802_15_4::beaconRxHandler(void)
01907 {
01908 if (macBeaconOrder2 != 15)
01909 {
01910 if (txAck)
01911 {
01912 Packet::free(txAck);
01913 txAck = 0;
01914 }
01915
01916 plme_set_trx_state_request(p_RX_ON);
01917 if (taskP.mlme_sync_request_tracking)
01918 {
01919
01920 if (numLostBeacons > aMaxLostBeacons)
01921 {
01922 char label[11];
01923
01924 strcpy(label,"\" \"");
01925 #ifdef ZigBeeIF
01926 if (sscs->t_isCT)
01927 sprintf(label,"\"%s\"",(sscs->RNType())?"+":"-");
01928 #endif
01929 nam->changeLabel(CURRENT_TIME,label);
01930 changeNodeColor(CURRENT_TIME,Nam802_15_4::def_Node_clr);
01931 sscs->MLME_SYNC_LOSS_indication(m_BEACON_LOSS);
01932 numLostBeacons = 0;
01933 }
01934 else
01935 {
01936 numLostBeacons++;
01937 bcnRxT->start();
01938 }
01939 }
01940 }
01941 }
01942
01943 void Mac802_15_4::beaconSearchHandler(void)
01944 {
01945 dispatch(p_BUSY,__FUNCTION__);
01946 }
01947
01948 void Mac802_15_4::isPanCoor(bool isPC)
01949 {
01950 if (isPANCoor == isPC)
01951 return;
01952
01953 if (isPC)
01954 changeNodeColor(CURRENT_TIME,Nam802_15_4::def_PANCoor_clr);
01955 else if (isPANCoor)
01956 changeNodeColor(CURRENT_TIME,
01957 (mpib.macPANId == 0xffff) ? Nam802_15_4::def_Node_clr :
01958 (mpib.macAssociationPermit) ? Nam802_15_4::def_Coor_clr : Nam802_15_4::def_Dev_clr);
01959 isPANCoor = isPC;
01960 }
01961
01962
01963
01964 void Mac802_15_4::set_trx_state_request(PHYenum state,const char *frFile,const char *frFunc,int line)
01965 {
01966 #ifdef DEBUG802_15_4
01967 fprintf(stdout,"[%s::%s][%f](node %d): %s request from [%s:%s:%d]\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,
01968 (state == p_RX_ON)?"RX_ON":
01969 (state == p_TX_ON)?"TX_ON":
01970 (state == p_TRX_OFF)?"TRX_OFF":
01971 (state == p_FORCE_TRX_OFF)?"FORCE_TRX_OFF":"???",
01972 frFile,frFunc,line);
01973 #endif
01974 trx_state_req = state;
01975 phy->PLME_SET_TRX_STATE_request(state);
01976 }
01977
01978 char *taskName[] = {"NONE",
01979 "MCPS-DATA.request",
01980 "MLME-ASSOCIATE.request",
01981 "MLME-ASSOCIATE.response",
01982 "MLME-DISASSOCIATE.request",
01983 "MLME-ORPHAN.response",
01984 "MLME-RESET.request",
01985 "MLME-RX-ENABLE.request",
01986 "MLME-SCAN.request",
01987 "MLME-START.request",
01988 "MLME-SYNC.request",
01989 "MLME-POLL.request",
01990 "CCA_csmaca",
01991 "RX_ON_csmaca"};
01992 void Mac802_15_4::checkTaskOverflow(UINT_8 task)
01993 {
01994
01995
01996 if (taskP.taskStatus(task))
01997 {
01998 fprintf(stdout,"[%s::%s][%f](node %d) task overflow: %s\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,taskName[task]);
01999 exit(1);
02000 }
02001 else
02002 {
02003 taskP.taskStep(task) = 0;
02004 (taskP.taskFrFunc(task))[0] = 0;
02005 }
02006 }
02007
02008 void Mac802_15_4::dispatch(PHYenum status,const char *frFunc,PHYenum req_state,MACenum mStatus)
02009 {
02010 hdr_lrwpan *wph;
02011 hdr_cmn *ch;
02012 FrameCtrl frmCtrl;
02013 UINT_8 ifs;
02014
02015
02016 if (strcmp(frFunc,"csmacaCallBack") == 0)
02017 {
02018 if (txCsmaca == txBcnCmd2)
02019 {
02020 if (taskP.taskStatus(TP_mlme_scan_request)
02021 && (strcmp(taskP.taskFrFunc(TP_mlme_scan_request),frFunc) == 0))
02022 {
02023 if ((taskP.mlme_scan_request_ScanType == 0x01)
02024 || (taskP.mlme_scan_request_ScanType == 0x03))
02025 mlme_scan_request(taskP.mlme_scan_request_ScanType,taskP.mlme_scan_request_ScanChannels,taskP.mlme_scan_request_ScanDuration,false,status);
02026 }
02027 else if (taskP.taskStatus(TP_mlme_start_request)
02028 && (strcmp(taskP.taskFrFunc(TP_mlme_start_request),frFunc) == 0))
02029 mlme_start_request(taskP.mlme_start_request_PANId,taskP.mlme_start_request_LogicalChannel,taskP.mlme_start_request_BeaconOrder,taskP.mlme_start_request_SuperframeOrder,taskP.mlme_start_request_PANCoordinator,taskP.mlme_start_request_BatteryLifeExtension,0,taskP.mlme_start_request_SecurityEnable,false,status);
02030 else if (taskP.taskStatus(TP_mlme_associate_request)
02031 && (strcmp(taskP.taskFrFunc(TP_mlme_associate_request),frFunc) == 0))
02032 mlme_associate_request(0,0,0,0,0,taskP.mlme_associate_request_SecurityEnable,false,status);
02033 else if (taskP.taskStatus(TP_mlme_poll_request)
02034 && (strcmp(taskP.taskFrFunc(TP_mlme_poll_request),frFunc) == 0))
02035 mlme_poll_request(taskP.mlme_poll_request_CoordAddrMode,taskP.mlme_poll_request_CoordPANId,taskP.mlme_poll_request_CoordAddress,taskP.mlme_poll_request_SecurityEnable,taskP.mlme_poll_request_autoRequest,false,status);
02036 else
02037 {
02038 if (status == p_IDLE)
02039 plme_set_trx_state_request(p_TX_ON);
02040 else
02041 {
02042 freePkt(txBcnCmd2);
02043 txBcnCmd2 = 0;
02044 csmacaResume();
02045 }
02046 }
02047 }
02048 else if (txCsmaca == txData)
02049 {
02050 assert(taskP.taskStatus(TP_mcps_data_request)
02051 && (strcmp(taskP.taskFrFunc(TP_mcps_data_request),frFunc) == 0));
02052
02053 if (taskP.mcps_data_request_TxOptions & TxOp_GTS)
02054 {
02055 ;
02056 }
02057 else if ((taskP.mcps_data_request_TxOptions & TxOp_Indirect)
02058 && (capability.FFD&&(numberDeviceLink(&deviceLink1) > 0)))
02059 {
02060 if (status != p_IDLE)
02061 mcps_data_request(0,0,0,0,0,0,0,0,0,taskP.mcps_data_request_TxOptions,false,p_BUSY,m_CHANNEL_ACCESS_FAILURE);
02062 else
02063 {
02064 strcpy(taskP.taskFrFunc(TP_mcps_data_request),"PD_DATA_confirm");
02065 plme_set_trx_state_request(p_TX_ON);
02066 }
02067 }
02068 else
02069 mcps_data_request(0,0,0,0,0,0,0,0,0,taskP.mcps_data_request_TxOptions,false,status);
02070 }
02071 else if (txCsmaca == txBcnCmd)
02072 {
02073 wph = HDR_LRWPAN(txBcnCmd);
02074 frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
02075 frmCtrl.parse();
02076 if (status == p_IDLE)
02077 {
02078 if ((frmCtrl.frmType == defFrmCtrl_Type_MacCmd)
02079 && (wph->MSDU_CmdType == 0x02))
02080 strcpy(taskP.taskFrFunc(TP_mlme_associate_response),"PD_DATA_confirm");
02081 else if ((frmCtrl.frmType == defFrmCtrl_Type_MacCmd)
02082 && (wph->MSDU_CmdType == 0x08))
02083 strcpy(taskP.taskFrFunc(TP_mlme_orphan_response),"PD_DATA_confirm");
02084 plme_set_trx_state_request(p_TX_ON);
02085 }
02086 else
02087 {
02088 if ((frmCtrl.frmType == defFrmCtrl_Type_MacCmd)
02089 && (wph->MSDU_CmdType == 0x02))
02090 mlme_associate_response(taskP.mlme_associate_response_DeviceAddress,0,m_CHANNEL_ACCESS_FAILURE,0,false,p_BUSY);
02091 else if ((frmCtrl.frmType == defFrmCtrl_Type_MacCmd)
02092 && (wph->MSDU_CmdType == 0x08))
02093 mlme_orphan_response(taskP.mlme_orphan_response_OrphanAddress,0,true,false,false,p_BUSY);
02094 else
02095 {
02096 freePkt(txBcnCmd);
02097 txBcnCmd = 0;
02098 csmacaResume();
02099 }
02100 }
02101 }
02102
02103 }
02104 else if (strcmp(frFunc,"PD_DATA_confirm") == 0)
02105 {
02106 if (txPkt == txBeacon)
02107 {
02108 if (taskP.taskStatus(TP_mlme_start_request)
02109 && (strcmp(taskP.taskFrFunc(TP_mlme_start_request),frFunc) == 0))
02110 mlme_start_request(taskP.mlme_start_request_PANId,taskP.mlme_start_request_LogicalChannel,taskP.mlme_start_request_BeaconOrder,taskP.mlme_start_request_SuperframeOrder,taskP.mlme_start_request_PANCoordinator,taskP.mlme_start_request_BatteryLifeExtension,0,taskP.mlme_start_request_SecurityEnable,false,status);
02111 else
02112 {
02113 resetTRX();
02114 taskSuccess('b');
02115 }
02116 }
02117 else if (txPkt == txAck)
02118 {
02119 if (rxCmd)
02120 {
02121 ch = HDR_CMN(rxCmd);
02122 if (ch->size() <= aMaxSIFSFrameSize)
02123 ifs = aMinSIFSPeriod;
02124 else
02125 ifs = aMinLIFSPeriod;
02126 Scheduler::instance().schedule(&IFSH, &(IFSH.nullEvent), ifs/phy->getRate('s'));
02127 resetTRX();
02128 taskSuccess('a');
02129 }
02130 else if (rxData)
02131 {
02132 ch = HDR_CMN(rxData);
02133 if (ch->size() <= aMaxSIFSFrameSize)
02134 ifs = aMinSIFSPeriod;
02135 else
02136 ifs = aMinLIFSPeriod;
02137 Scheduler::instance().schedule(&IFSH, &(IFSH.nullEvent), ifs/phy->getRate('s'));
02138 resetTRX();
02139 taskSuccess('a');
02140 }
02141 else
02142 {
02143 resetTRX();
02144 taskSuccess('a');
02145 }
02146 }
02147 else if (txPkt == txBcnCmd)
02148 {
02149
02150 wph = HDR_LRWPAN(txBcnCmd);
02151 ch = HDR_CMN(txBcnCmd);
02152 frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
02153 frmCtrl.parse();
02154 if (frmCtrl.ackReq)
02155 {
02156
02157 plme_set_trx_state_request(p_RX_ON);
02158 txT->start(mpib.macAckWaitDuration/phy->getRate('s'));
02159 waitBcnCmdAck = true;
02160 }
02161 else
02162 {
02163 resetTRX();
02164 taskSuccess('c');
02165 }
02166 }
02167 else if (txPkt == txBcnCmd2)
02168 {
02169 if (taskP.taskStatus(TP_mlme_scan_request)
02170 && ((taskP.mlme_scan_request_ScanType == 0x01)
02171 ||(taskP.mlme_scan_request_ScanType == 0x03))
02172 && (strcmp(taskP.taskFrFunc(TP_mlme_scan_request),frFunc) == 0))
02173 mlme_scan_request(taskP.mlme_scan_request_ScanType,taskP.mlme_scan_request_ScanChannels,taskP.mlme_scan_request_ScanDuration,false,status);
02174 else if (taskP.taskStatus(TP_mlme_start_request)
02175 && (strcmp(taskP.taskFrFunc(TP_mlme_start_request),frFunc) == 0))
02176 mlme_start_request(taskP.mlme_start_request_PANId,taskP.mlme_start_request_LogicalChannel,taskP.mlme_start_request_BeaconOrder,taskP.mlme_start_request_SuperframeOrder,taskP.mlme_start_request_PANCoordinator,taskP.mlme_start_request_BatteryLifeExtension,0,taskP.mlme_start_request_SecurityEnable,false,status);
02177 else if (taskP.taskStatus(TP_mlme_associate_request)
02178 && (strcmp(taskP.taskFrFunc(TP_mlme_associate_request),frFunc) == 0))
02179 mlme_associate_request(0,0,0,0,0,taskP.mlme_associate_request_SecurityEnable,false,status);
02180 else if (taskP.taskStatus(TP_mlme_poll_request)
02181 && (strcmp(taskP.taskFrFunc(TP_mlme_poll_request),frFunc) == 0))
02182 mlme_poll_request(taskP.mlme_poll_request_CoordAddrMode,taskP.mlme_poll_request_CoordPANId,taskP.mlme_poll_request_CoordAddress,taskP.mlme_poll_request_SecurityEnable,taskP.mlme_poll_request_autoRequest,false,status);
02183 else
02184 {
02185 wph = HDR_LRWPAN(txBcnCmd2);
02186 ch = HDR_CMN(txBcnCmd2);
02187 frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
02188 frmCtrl.parse();
02189 if (frmCtrl.ackReq)
02190 {
02191
02192 plme_set_trx_state_request(p_RX_ON);
02193 txT->start(mpib.macAckWaitDuration/phy->getRate('s'));
02194 waitBcnCmdAck2 = true;
02195 }
02196 else
02197 {
02198 resetTRX();
02199 taskSuccess('C');
02200 }
02201 }
02202 }
02203 else if (txPkt == txData)
02204 {
02205 assert((taskP.taskStatus(TP_mcps_data_request))
02206 && (strcmp(taskP.taskFrFunc(TP_mcps_data_request),frFunc) == 0));
02207
02208 wph = HDR_LRWPAN(txData);
02209 ch = HDR_CMN(txData);
02210 frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
02211 frmCtrl.parse();
02212 if (taskP.taskStatus(TP_mcps_data_request))
02213 {
02214 if (taskP.mcps_data_request_TxOptions & TxOp_GTS)
02215 {
02216 ;
02217 }
02218 else if ((taskP.mcps_data_request_TxOptions & TxOp_Indirect)
02219 && (capability.FFD&&(numberDeviceLink(&deviceLink1) > 0)))
02220 {
02221 if (!frmCtrl.ackReq)
02222 mcps_data_request(0,0,0,0,0,0,0,0,0,taskP.mcps_data_request_TxOptions,false,p_SUCCESS);
02223 else
02224 {
02225 strcpy(taskP.taskFrFunc(TP_mcps_data_request),"recvAck");
02226
02227 plme_set_trx_state_request(p_RX_ON);
02228 txT->start(mpib.macAckWaitDuration/phy->getRate('s'));
02229 waitDataAck = true;
02230 }
02231 }
02232 else
02233 mcps_data_request(0,0,0,0,0,0,0,0,0,taskP.mcps_data_request_TxOptions,false,status);
02234 }
02235 else
02236 {
02237 if (frmCtrl.ackReq)
02238 {
02239
02240 plme_set_trx_state_request(p_RX_ON);
02241 txT->start(mpib.macAckWaitDuration/phy->getRate('s'));
02242 waitDataAck = true;
02243 }
02244 else
02245 {
02246 resetTRX();
02247 taskSuccess('d');
02248 }
02249 }
02250 }
02251
02252 }
02253 else if (strcmp(frFunc,"recvAck") == 0)
02254 {
02255 if (txPkt == txData)
02256 {
02257 if ((taskP.taskStatus(TP_mcps_data_request))
02258 && (strcmp(taskP.taskFrFunc(TP_mcps_data_request),frFunc) == 0))
02259 mcps_data_request(0,0,0,0,0,0,0,0,0,taskP.mcps_data_request_TxOptions,false,p_SUCCESS);
02260 else
02261 {
02262 if (taskP.taskStatus(TP_mcps_data_request))
02263 taskP.taskStatus(TP_mcps_data_request) = false;
02264 resetTRX();
02265 taskSuccess('d');
02266 }
02267 }
02268 else if (txPkt == txBcnCmd2)
02269 {
02270 if (taskP.taskStatus(TP_mlme_associate_request)
02271 && (strcmp(taskP.taskFrFunc(TP_mlme_associate_request),frFunc) == 0))
02272 mlme_associate_request(0,0,0,0,0,taskP.mlme_associate_request_SecurityEnable,false,p_SUCCESS);
02273 else if (taskP.taskStatus(TP_mlme_poll_request)
02274 && (strcmp(taskP.taskFrFunc(TP_mlme_poll_request),frFunc) == 0))
02275 mlme_poll_request(taskP.mlme_poll_request_CoordAddrMode,taskP.mlme_poll_request_CoordPANId,taskP.mlme_poll_request_CoordAddress,taskP.mlme_poll_request_SecurityEnable,taskP.mlme_poll_request_autoRequest,false,p_SUCCESS);
02276 else
02277 taskSuccess('C');
02278 }
02279 else if (txPkt == txBcnCmd)
02280 {
02281 wph = HDR_LRWPAN(txBcnCmd);
02282 frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
02283 frmCtrl.parse();
02284 if ((frmCtrl.frmType == defFrmCtrl_Type_MacCmd)
02285 && (wph->MSDU_CmdType == 0x02))
02286 mlme_associate_response(taskP.mlme_associate_response_DeviceAddress,0,m_SUCCESS,0,false,p_SUCCESS);
02287 else if ((frmCtrl.frmType == defFrmCtrl_Type_MacCmd)
02288 && (wph->MSDU_CmdType == 0x08))
02289 mlme_orphan_response(taskP.mlme_orphan_response_OrphanAddress,0,true,false,false);
02290 else
02291 taskSuccess('c');
02292 }
02293
02294 }
02295 else if (strcmp(frFunc,"txHandler") == 0)
02296 {
02297 if (txPkt == txData)
02298 {
02299 if ((!taskP.taskStatus(TP_mcps_data_request))
02300 || (strcmp(taskP.taskFrFunc(TP_mcps_data_request),"recvAck") != 0))
02301 return;
02302
02303 if (taskP.taskStatus(TP_mcps_data_request))
02304 if (taskP.mcps_data_request_TxOptions & TxOp_GTS)
02305 {
02306 ;
02307 }
02308 else if ((taskP.mcps_data_request_TxOptions & TxOp_Indirect)
02309 && (capability.FFD&&(numberDeviceLink(&deviceLink1) > 0)))
02310 {
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340 mcps_data_request(0,0,0,0,0,0,0,0,0,taskP.mcps_data_request_TxOptions,false,p_BUSY,m_NO_ACK);
02341 }
02342 else
02343 mcps_data_request(0,0,0,0,0,0,0,0,0,taskP.mcps_data_request_TxOptions,false,p_BUSY);
02344 }
02345 else if (txPkt == txBcnCmd2)
02346 {
02347 if (taskP.taskStatus(TP_mlme_associate_request)
02348 && (strcmp(taskP.taskFrFunc(TP_mlme_associate_request),"recvAck") == 0))
02349 mlme_associate_request(0,0,0,0,0,taskP.mlme_associate_request_SecurityEnable,false,p_BUSY);
02350 else if (taskP.taskStatus(TP_mlme_poll_request)
02351 && (strcmp(taskP.taskFrFunc(TP_mlme_poll_request),"recvAck") == 0))
02352 mlme_poll_request(taskP.mlme_poll_request_CoordAddrMode,taskP.mlme_poll_request_CoordPANId,taskP.mlme_poll_request_CoordAddress,taskP.mlme_poll_request_SecurityEnable,taskP.mlme_poll_request_autoRequest,false,p_BUSY);
02353 else
02354 {
02355 numBcnCmdRetry2++;
02356 if (numBcnCmdRetry2 <= aMaxFrameRetries)
02357 waitBcnCmdAck2 = false;
02358 else
02359 {
02360 freePkt(txBcnCmd2);
02361 txBcnCmd2 = 0;
02362 }
02363 csmacaResume();
02364 }
02365 }
02366 else if (txPkt == txBcnCmd)
02367 {
02368 wph = HDR_LRWPAN(txBcnCmd);
02369 frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
02370 frmCtrl.parse();
02371 if ((frmCtrl.frmType == defFrmCtrl_Type_MacCmd)
02372 && (wph->MSDU_CmdType == 0x02))
02373 {
02374
02375
02376
02377 numBcnCmdRetry++;
02378 if (numBcnCmdRetry <= aMaxFrameRetries)
02379 {
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394 strcpy(taskP.taskFrFunc(TP_mlme_associate_response),"csmacaCallBack");
02395 waitBcnCmdAck = false;
02396 csmacaResume();
02397 }
02398 else
02399 mlme_associate_response(taskP.mlme_associate_response_DeviceAddress,0,m_NO_ACK,0,false,p_BUSY);
02400 }
02401 else if ((frmCtrl.frmType == defFrmCtrl_Type_MacCmd)
02402 && (wph->MSDU_CmdType == 0x08))
02403 {
02404 numBcnCmdRetry++;
02405 if (numBcnCmdRetry <= aMaxFrameRetries)
02406 {
02407 strcpy(taskP.taskFrFunc(TP_mlme_orphan_response),"csmacaCallBack");
02408 waitBcnCmdAck = false;
02409 csmacaResume();
02410 }
02411 else
02412 mlme_orphan_response(taskP.mlme_orphan_response_OrphanAddress,0,true,false,p_BUSY);
02413 }
02414 else
02415 {
02416 freePkt(txBcnCmd);
02417 txBcnCmd = 0;
02418 csmacaResume();
02419 }
02420 }
02421
02422
02423 }
02424 else if (strcmp(frFunc,"PLME_SET_TRX_STATE_confirm") == 0)
02425 {
02426
02427 if (req_state == p_TRX_OFF)
02428 if (taskP.taskStatus(TP_mlme_reset_request)
02429 && (strcmp(taskP.taskFrFunc(TP_mlme_reset_request),frFunc) == 0))
02430 mlme_reset_request(taskP.mlme_reset_request_SetDefaultPIB,false,status);
02431
02432 if (req_state == p_RX_ON)
02433 if (taskP.taskStatus(TP_mlme_scan_request)
02434 && (strcmp(taskP.taskFrFunc(TP_mlme_scan_request),frFunc) == 0))
02435 mlme_scan_request(taskP.mlme_scan_request_ScanType,taskP.mlme_scan_request_ScanChannels,taskP.mlme_scan_request_ScanDuration,false,status);
02436 else if (taskP.taskStatus(TP_mlme_rx_enable_request)
02437 && (strcmp(taskP.taskFrFunc(TP_mlme_rx_enable_request),frFunc) == 0))
02438 mlme_rx_enable_request(0,taskP.mlme_rx_enable_request_RxOnTime,taskP.mlme_rx_enable_request_RxOnDuration,false);
02439 }
02440 else if (strcmp(frFunc,"PLME_SET_confirm") == 0)
02441 {
02442 if (taskP.taskStatus(TP_mlme_scan_request)
02443 && (strcmp(taskP.taskFrFunc(TP_mlme_scan_request),frFunc) == 0))
02444 mlme_scan_request(taskP.mlme_scan_request_ScanType,taskP.mlme_scan_request_ScanChannels,taskP.mlme_scan_request_ScanDuration,false,status);
02445 }
02446 else if (strcmp(frFunc,"PLME_ED_confirm") == 0)
02447 {
02448 if (taskP.taskStatus(TP_mlme_scan_request)
02449 && (taskP.mlme_scan_request_ScanType == 0x00)
02450 && (strcmp(taskP.taskFrFunc(TP_mlme_scan_request),frFunc) == 0))
02451 mlme_scan_request(taskP.mlme_scan_request_ScanType,taskP.mlme_scan_request_ScanChannels,taskP.mlme_scan_request_ScanDuration,false,status);
02452 }
02453 else if (strcmp(frFunc,"recvBeacon") == 0)
02454 {
02455 if (taskP.taskStatus(TP_mlme_scan_request)
02456 && (strcmp(taskP.taskFrFunc(TP_mlme_scan_request),frFunc) == 0))
02457 mlme_scan_request(taskP.mlme_scan_request_ScanType,taskP.mlme_scan_request_ScanChannels,taskP.mlme_scan_request_ScanDuration,false,p_SUCCESS);
02458 else if (taskP.taskStatus(TP_mlme_rx_enable_request)
02459 && (strcmp(taskP.taskFrFunc(TP_mlme_rx_enable_request),frFunc) == 0))
02460 mlme_rx_enable_request(0,taskP.mlme_rx_enable_request_RxOnTime,taskP.mlme_rx_enable_request_RxOnDuration,false);
02461 else if (taskP.taskStatus(TP_mlme_sync_request)
02462 && (strcmp(taskP.taskFrFunc(TP_mlme_sync_request),frFunc) == 0))
02463 mlme_sync_request(0,taskP.mlme_sync_request_tracking,false,p_SUCCESS);
02464 }
02465 else if (strcmp(frFunc,"scanHandler") == 0)
02466 {
02467 if (taskP.taskStatus(TP_mlme_scan_request))
02468 mlme_scan_request(taskP.mlme_scan_request_ScanType,taskP.mlme_scan_request_ScanChannels,taskP.mlme_scan_request_ScanDuration,false,p_BUSY);
02469 }
02470 else if (strcmp(frFunc,"extractHandler") == 0)
02471 {
02472 if (taskP.taskStatus(TP_mlme_associate_request)
02473 && (strcmp(taskP.taskFrFunc(TP_mlme_associate_request),frFunc) == 0))
02474 {
02475 mlme_associate_request(0,0,0,0,0,taskP.mlme_associate_request_SecurityEnable,false,p_BUSY);
02476 }
02477 else if (taskP.taskStatus(TP_mlme_poll_request)
02478 && (strcmp(taskP.taskFrFunc(TP_mlme_poll_request),"IFSHandler") == 0))
02479 mlme_poll_request(taskP.mlme_poll_request_CoordAddrMode,taskP.mlme_poll_request_CoordPANId,taskP.mlme_poll_request_CoordAddress,taskP.mlme_poll_request_SecurityEnable,taskP.mlme_poll_request_autoRequest,false,p_BUSY);
02480 }
02481 else if (strcmp(frFunc,"assoRspWaitHandler") == 0)
02482 {
02483 if (taskP.taskStatus(TP_mlme_associate_response))
02484 {
02485 taskP.taskStep(TP_mlme_associate_response) = 2;
02486 mlme_associate_response(taskP.mlme_associate_response_DeviceAddress,0,m_SUCCESS,0,false,p_BUSY);
02487 }
02488 }
02489 else if (strcmp(frFunc,"dataWaitHandler") == 0)
02490 {
02491 if (taskP.taskStatus(TP_mcps_data_request))
02492 {
02493 taskP.taskStep(TP_mcps_data_request) = 2;
02494 mcps_data_request(0,0,0,0,0,0,0,0,0,taskP.mcps_data_request_TxOptions,false,p_BUSY);
02495 }
02496 }
02497 else if (strcmp(frFunc,"IFSHandler") == 0)
02498 {
02499 if (taskP.taskStatus(TP_mlme_associate_request)
02500 && (strcmp(taskP.taskFrFunc(TP_mlme_associate_request),frFunc) == 0))
02501 mlme_associate_request(0,0,0,0,0,taskP.mlme_associate_request_SecurityEnable,false,p_SUCCESS,mStatus);
02502 else if (taskP.taskStatus(TP_mlme_poll_request)
02503 && (strcmp(taskP.taskFrFunc(TP_mlme_poll_request),frFunc) == 0))
02504 mlme_poll_request(taskP.mlme_poll_request_CoordAddrMode,taskP.mlme_poll_request_CoordPANId,taskP.mlme_poll_request_CoordAddress,taskP.mlme_poll_request_SecurityEnable,taskP.mlme_poll_request_autoRequest,false,p_SUCCESS);
02505 else if (taskP.taskStatus(TP_mlme_scan_request)
02506 && (strcmp(taskP.taskFrFunc(TP_mlme_scan_request),frFunc) == 0))
02507 mlme_scan_request(taskP.mlme_scan_request_ScanType,taskP.mlme_scan_request_ScanChannels,taskP.mlme_scan_request_ScanDuration,false,p_SUCCESS);
02508 }
02509 else if (strcmp(frFunc,"rxEnableHandler") == 0)
02510 {
02511
02512 if (strcmp(taskP.taskFrFunc(TP_mlme_rx_enable_request),frFunc) == 0)
02513 mlme_rx_enable_request(0,taskP.mlme_rx_enable_request_RxOnTime,taskP.mlme_rx_enable_request_RxOnDuration,false);
02514 }
02515 else if (strcmp(frFunc,"beaconSearchHandler") == 0)
02516 {
02517 if (taskP.taskStatus(TP_mlme_sync_request)
02518 && (strcmp(taskP.taskFrFunc(TP_mlme_sync_request),"recvBeacon") == 0))
02519 mlme_sync_request(0,taskP.mlme_sync_request_tracking,false,p_BUSY);
02520 }
02521 }
02522
02523 void Mac802_15_4::sendDown(Packet *p,Handler* h)
02524 {
02525 if (updateNFailLink(fl_oper_est,index_) == 0)
02526 {
02527 if (txBeacon)
02528 {
02529 beaconWaiting = false;
02530 Packet::free(txBeacon);
02531 txBeacon = 0;
02532 }
02533 return;
02534 }
02535 else if (updateLFailLink(fl_oper_est,index_,p802_15_4macDA(p)) == 0)
02536 {
02537 dispatch(p_UNDEFINED,"PD_DATA_confirm");
02538 return;
02539 }
02540
02541 inTransmission = true;
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552 EnergyModel *em = netif_->node()->energy_model();
02553 if (em)
02554 if (em->energy() <= 0)
02555 {
02556 PD_DATA_confirm(p_UNDEFINED);
02557 return;
02558 }
02559
02560 downtarget_->recv(p, h);
02561 }
02562
02563 void Mac802_15_4::mcps_data_request(UINT_8 SrcAddrMode,UINT_16 SrcPANId,IE3ADDR SrcAddr,
02564 UINT_8 DstAddrMode,UINT_16 DstPANId,IE3ADDR DstAddr,
02565 UINT_8 msduLength,Packet *msdu,UINT_8 msduHandle,UINT_8 TxOptions,
02566 bool frUpper,PHYenum status,MACenum mStatus)
02567 {
02568 UINT_8 step,task;
02569 hdr_lrwpan *wph;
02570 hdr_cmn *ch;
02571 FrameCtrl frmCtrl;
02572 double kpTime;
02573 int i;
02574
02575 task = TP_mcps_data_request;
02576 if (frUpper) checkTaskOverflow(task);
02577
02578 step = taskP.taskStep(task);
02579 if (step == 0)
02580 {
02581
02582 ch = HDR_CMN(msdu);
02583 if (ch->ptype() == PT_MAC)
02584 if ((SrcAddrMode > 0x03)
02585 ||(DstAddrMode > 0x03)
02586 ||(msduLength > aMaxMACFrameSize)
02587 ||(TxOptions > 0x0f))
02588 {
02589 sscs->MCPS_DATA_confirm(msduHandle,m_INVALID_PARAMETER);
02590 return;
02591 }
02592
02593 taskP.taskStatus(task) = true;
02594 taskP.mcps_data_request_TxOptions = TxOptions;
02595
02596 frmCtrl.FrmCtrl = 0;
02597 frmCtrl.setFrmType(defFrmCtrl_Type_Data);
02598 if (TxOptions & TxOp_Acked)
02599 frmCtrl.setAckReq(true);
02600 if (SrcPANId == DstPANId)
02601 frmCtrl.setIntraPan(true);
02602 frmCtrl.setDstAddrMode(DstAddrMode);
02603 frmCtrl.setSrcAddrMode(SrcAddrMode);
02604 wph = HDR_LRWPAN(msdu);
02605 wph->MHR_DstAddrInfo.panID = DstPANId;
02606 wph->MHR_DstAddrInfo.addr_64 = DstAddr;
02607 wph->MHR_SrcAddrInfo.panID = SrcPANId;
02608 wph->MHR_SrcAddrInfo.addr_64 = SrcAddr;
02609
02610 constructMPDU(msduLength,msdu,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0,0);
02611
02612 p802_15_4hdrDATA(msdu);
02613
02614
02615
02616 }
02617
02618 if (TxOptions & TxOp_GTS)
02619 {
02620 switch(step)
02621 {
02622
02623 default:
02624 break;
02625 }
02626 }
02627 else if ((TxOptions & TxOp_Indirect)
02628 && (capability.FFD&&(numberDeviceLink(&deviceLink1) > 0)))
02629 {
02630 switch(step)
02631 {
02632 case 0:
02633 taskP.taskStep(task)++;
02634 taskP.mcps_data_request_pendPkt = msdu;
02635 if ((DstAddrMode == defFrmCtrl_AddrMode16)
02636 || (DstAddrMode == defFrmCtrl_AddrMode64))
02637 {
02638
02639
02640
02641 {
02642 double tmpf;
02643 tmpf = (aBaseSuperframeDuration * (1 << mpib.macBeaconOrder) / phy->getRate('s'));
02644 kpTime = mpib.macTransactionPersistenceTime * tmpf;
02645 }
02646
02647 chkAddTransacLink(&transacLink1,&transacLink2,DstAddrMode,DstAddr,msdu,msduHandle,kpTime);
02648 }
02649 strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
02650 dataWaitT->start(kpTime);
02651 break;
02652 case 1:
02653 if (!taskP.taskStatus(task))
02654 break;
02655 if (status == p_SUCCESS)
02656 {
02657 dataWaitT->stop();
02658 taskP.taskStatus(task) = false;
02659 resetTRX();
02660 taskSuccess('d');
02661 }
02662 else
02663 {
02664
02665 strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
02666
02667
02668 resetTRX();
02669 taskFailed('d',mStatus);
02670 }
02671 break;
02672 case 2:
02673 if (!taskP.taskStatus(task))
02674 break;
02675 taskP.taskStatus(task) = false;
02676
02677 i = updateTransacLinkByPktOrHandle(tr_oper_est,&transacLink1,&transacLink2,taskP.mcps_data_request_pendPkt);
02678 if (i == 0)
02679 {
02680
02681 if (!txData)
02682 txData = taskP.mcps_data_request_pendPkt->copy();
02683
02684 updateTransacLinkByPktOrHandle(tr_oper_del,&transacLink1,&transacLink2,taskP.mcps_data_request_pendPkt);
02685 resetTRX();
02686 taskFailed('d',m_TRANSACTION_EXPIRED);
02687 return;
02688 }
02689 else
02690 {
02691 resetTRX();
02692 taskFailed('d',m_SUCCESS);
02693 return;
02694 }
02695 break;
02696
02697 default:
02698 break;
02699 }
02700 }
02701 else
02702 {
02703 switch(step)
02704 {
02705 case 0:
02706 taskP.taskStep(task)++;
02707 strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
02708 assert(!txData);
02709 txData = msdu;
02710 csmacaBegin('d');
02711 break;
02712 case 1:
02713 if (status == p_IDLE)
02714 {
02715 taskP.taskStep(task)++;
02716 strcpy(taskP.taskFrFunc(task),"PD_DATA_confirm");
02717
02718 plme_set_trx_state_request(p_TX_ON);
02719 }
02720 else
02721 {
02722 wph = HDR_LRWPAN(txData);
02723 ch = HDR_CMN(txData);
02724 if (wph->msduHandle)
02725 {
02726
02727 taskP.taskStatus(task) = false;
02728 resetTRX();
02729 taskFailed('d',m_CHANNEL_ACCESS_FAILURE);
02730 }
02731 else
02732 {
02733 csmacaResume();
02734 }
02735 }
02736 break;
02737 case 2:
02738 wph = HDR_LRWPAN(txData);
02739 ch = HDR_CMN(txData);
02740 frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
02741 frmCtrl.parse();
02742 if (frmCtrl.ackReq)
02743 {
02744 taskP.taskStep(task)++;
02745 strcpy(taskP.taskFrFunc(task),"recvAck");
02746
02747 plme_set_trx_state_request(p_RX_ON);
02748 txT->start(mpib.macAckWaitDuration/phy->getRate('s'));
02749 waitDataAck = true;
02750 }
02751 else
02752 {
02753 taskP.taskStatus(task) = false;
02754 resetTRX();
02755 taskSuccess('d');
02756 }
02757 break;
02758 case 3:
02759 if (status == p_SUCCESS)
02760 {
02761 taskP.taskStatus(task) = false;
02762 resetTRX();
02763 taskSuccess('d');
02764 }
02765 else
02766 {
02767 numDataRetry++;
02768 if (numDataRetry <= aMaxFrameRetries)
02769 {
02770 taskP.taskStep(task) = 1;
02771 strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
02772 waitDataAck = false;
02773 csmacaResume();
02774 }
02775 else
02776 {
02777 taskP.taskStatus(task) = false;
02778 resetTRX();
02779 taskFailed('d',m_NO_ACK);
02780 }
02781 }
02782 break;
02783 default:
02784 break;
02785 }
02786 }
02787 }
02788
02789 void Mac802_15_4::mlme_associate_request(UINT_8 LogicalChannel,UINT_8 CoordAddrMode,UINT_16 CoordPANId,IE3ADDR CoordAddress,
02790 UINT_8 CapabilityInformation,bool SecurityEnable,
02791 bool frUpper,PHYenum status,MACenum mStatus)
02792 {
02793
02794 UINT_8 step,task;
02795 FrameCtrl frmCtrl;
02796 hdr_lrwpan* wph;
02797
02798 task = TP_mlme_associate_request;
02799 if (frUpper) checkTaskOverflow(task);
02800
02801 step = taskP.taskStep(task);
02802 switch(step)
02803 {
02804 case 0:
02805
02806 if ((!phy->channelSupported(LogicalChannel))
02807 || ((CoordAddrMode != defFrmCtrl_AddrMode16)&&(CoordAddrMode != defFrmCtrl_AddrMode64)))
02808 {
02809 sscs->MLME_ASSOCIATE_confirm(0,m_INVALID_PARAMETER);
02810 return;
02811 }
02812
02813
02814
02815
02816
02817 tmp_ppib.phyCurrentChannel = LogicalChannel;
02818 phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
02819 mpib.macPANId = CoordPANId;
02820 mpib.macCoordExtendedAddress = CoordAddress;
02821 taskP.taskStatus(task) = true;
02822 taskP.taskStep(task)++;
02823 strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
02824 taskP.mlme_associate_request_CoordAddrMode = CoordAddrMode;
02825 taskP.mlme_associate_request_SecurityEnable = SecurityEnable;
02826
02827 #ifdef DEBUG802_15_4
02828 fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBcnCmd2:\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);
02829 #endif
02830 assert(!txBcnCmd2);
02831 txBcnCmd2 = Packet::alloc();
02832 assert(txBcnCmd2);
02833 wph = HDR_LRWPAN(txBcnCmd2);
02834 constructCommandHeader(txBcnCmd2,&frmCtrl,0x01,CoordAddrMode,CoordPANId,CoordAddress,defFrmCtrl_AddrMode64,0xffff,aExtendedAddress,SecurityEnable,false,true);
02835 wph->MSDU_Payload[0] = capability.cap;
02836 constructMPDU(2,txBcnCmd2,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0x01,0);
02837 csmacaBegin('C');
02838
02839 break;
02840 case 1:
02841 if (status == p_IDLE)
02842 {
02843 taskP.taskStep(task)++;
02844 strcpy(taskP.taskFrFunc(task),"PD_DATA_confirm");
02845 if (Mac802_15_4::verbose)
02846 fprintf(stdout,"[%f](node %d) sending association request command ...\n",CURRENT_TIME,index_);
02847 plme_set_trx_state_request(p_TX_ON);
02848 break;
02849 }
02850 else
02851 {
02852 taskP.taskStatus(task) = false;
02853 freePkt(txBcnCmd2);
02854 txBcnCmd2 = 0;
02855
02856 mpib.macPANId = def_macPANId;
02857 mpib.macCoordExtendedAddress = def_macCoordExtendedAddress;
02858 sscs->MLME_ASSOCIATE_confirm(0,m_CHANNEL_ACCESS_FAILURE);
02859 csmacaResume();
02860 return;
02861 }
02862 break;
02863 case 2:
02864 taskP.taskStep(task)++;
02865 strcpy(taskP.taskFrFunc(task),"recvAck");
02866 plme_set_trx_state_request(p_RX_ON);
02867 txT->start(mpib.macAckWaitDuration/phy->getRate('s'));
02868 waitBcnCmdAck2 = true;
02869 break;
02870 case 3:
02871 if (status == p_SUCCESS)
02872 {
02873 taskP.taskStep(task)++;
02874 strcpy(taskP.taskFrFunc(task),"extractHandler");
02875 plme_set_trx_state_request(p_TRX_OFF);
02876 if (Mac802_15_4::verbose)
02877 fprintf(stdout,"[%f](node %d) ack for association request command received\n",CURRENT_TIME,index_);
02878 taskSuccess('C',false);
02879 extractT->start(aResponseWaitTime/phy->getRate('s'),false);
02880 }
02881 else
02882 {
02883 numBcnCmdRetry2++;
02884 if (numBcnCmdRetry2 <= aMaxFrameRetries)
02885 {
02886 taskP.taskStep(task) = 1;
02887 strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
02888 waitBcnCmdAck2 = false;
02889 csmacaResume();
02890 }
02891 else
02892 {
02893 taskP.taskStatus(task) = false;
02894 resetTRX();
02895 freePkt(txBcnCmd2);
02896 txBcnCmd2 = 0;
02897
02898 mpib.macPANId = def_macPANId;
02899 mpib.macCoordExtendedAddress = def_macCoordExtendedAddress;
02900 sscs->MLME_ASSOCIATE_confirm(0,m_NO_ACK);
02901 csmacaResume();
02902 return;
02903 }
02904 }
02905 break;
02906 case 4:
02907 taskP.taskStep(task)++;
02908 strcpy(taskP.taskFrFunc(task),"PD_DATA_confirm");
02909
02910 #ifdef DEBUG802_15_4
02911 fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBcnCmd2:\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);
02912 #endif
02913 assert(!txBcnCmd2);
02914 txBcnCmd2 = Packet::alloc();
02915 assert(txBcnCmd2);
02916 wph = HDR_LRWPAN(txBcnCmd2);
02917 if ((mpib.macShortAddress == 0xfffe)||(mpib.macShortAddress == 0xffff))
02918 {
02919 frmCtrl.setSrcAddrMode(defFrmCtrl_AddrMode64);
02920 wph->MHR_SrcAddrInfo.addr_64 = aExtendedAddress;
02921 }
02922 else
02923 {
02924 frmCtrl.setSrcAddrMode(defFrmCtrl_AddrMode16);
02925 wph->MHR_SrcAddrInfo.addr_16 = mpib.macShortAddress;
02926 }
02927 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);
02928 constructMPDU(1,txBcnCmd2,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0x04,0);
02929 waitBcnCmdAck2 = false;
02930 numBcnCmdRetry2 = 0;
02931 if (Mac802_15_4::verbose)
02932 fprintf(stdout,"[%f](node %d) sending data request command ...\n",CURRENT_TIME,index_);
02933 txCsmaca = txBcnCmd2;
02934 plme_set_trx_state_request(p_TX_ON);
02935
02936 break;
02937 case 5:
02938 taskP.taskStep(task)++;
02939 strcpy(taskP.taskFrFunc(task),"recvAck");
02940
02941 plme_set_trx_state_request(p_RX_ON);
02942 txT->start(mpib.macAckWaitDuration/phy->getRate('s'));
02943 waitBcnCmdAck2 = true;
02944 break;
02945 case 6:
02946 if (status == p_SUCCESS)
02947 {
02948 taskP.taskStep(task)++;
02949 strcpy(taskP.taskFrFunc(task),"IFSHandler");
02950 plme_set_trx_state_request(p_RX_ON);
02951 if (Mac802_15_4::verbose)
02952 fprintf(stdout,"[%f](node %d) ack for data request command received\n",CURRENT_TIME,index_);
02953 taskSuccess('C',false);
02954 extractT->start(aResponseWaitTime/phy->getRate('s'),false);
02955 }
02956 else
02957 {
02958
02959
02960
02961 numBcnCmdRetry2++;
02962 if (numBcnCmdRetry2 <= aMaxFrameRetries)
02963 {
02964 taskP.taskStep(task) = 5;
02965 strcpy(taskP.taskFrFunc(task),"PD_DATA_confirm");
02966 waitBcnCmdAck2 = false;
02967 txCsmaca = txBcnCmd2;
02968 plme_set_trx_state_request(p_TX_ON);
02969 }
02970 else
02971 {
02972 taskP.taskStatus(task) = false;
02973 resetTRX();
02974 freePkt(txBcnCmd2);
02975 txBcnCmd2 = 0;
02976
02977 mpib.macPANId = def_macPANId;
02978 mpib.macCoordExtendedAddress = def_macCoordExtendedAddress;
02979 sscs->MLME_ASSOCIATE_confirm(0,m_NO_DATA);
02980 csmacaResume();
02981 return;
02982 }
02983 }
02984 break;
02985 case 7:
02986 taskP.taskStatus(task) = false;
02987 resetTRX();
02988 if (status == p_SUCCESS)
02989 {
02990 if (mStatus == m_SUCCESS)
02991 {
02992 changeNodeColor(CURRENT_TIME,(mpib.macAssociationPermit)?Nam802_15_4::def_Coor_clr:Nam802_15_4::def_Dev_clr);
02993 char label[31];
02994 sprintf(label,"[%d]",mpib.macCoordExtendedAddress);
02995 #ifdef ZigBeeIF
02996 if (sscs->t_isCT)
02997 sprintf(label,"\"%s%d (%d.%d)\"",(sscs->RNType())?"+":"-",rt_myNodeID,sscs->rt_myParentNodeID,sscs->rt_myDepth);
02998 #endif
02999 nam->changeLabel(CURRENT_TIME,label);
03000 }
03001 else
03002 {
03003
03004 mpib.macPANId = def_macPANId;
03005 mpib.macCoordExtendedAddress = def_macCoordExtendedAddress;
03006 }
03007
03008 if (Mac802_15_4::verbose)
03009 fprintf(stdout,"[%f](node %d) association response command received\n",CURRENT_TIME,index_);
03010 extractT->stop();
03011 sscs->MLME_ASSOCIATE_confirm(rt_myNodeID,mStatus);
03012 }
03013 else
03014 {
03015
03016 mpib.macPANId = def_macPANId;
03017 mpib.macCoordExtendedAddress = def_macCoordExtendedAddress;
03018 sscs->MLME_ASSOCIATE_confirm(0,m_NO_DATA);
03019 }
03020 csmacaResume();
03021 default:
03022 break;
03023 }
03024 }
03025
03026 void Mac802_15_4::mlme_associate_response(IE3ADDR DeviceAddress,UINT_16 AssocShortAddress,MACenum Status,bool SecurityEnable,
03027 bool frUpper,PHYenum status)
03028 {
03029 FrameCtrl frmCtrl;
03030 hdr_lrwpan* wph;
03031 Packet *rspPkt;
03032 double kpTime;
03033 UINT_8 step,task;
03034 int i;
03035 task = TP_mlme_associate_response;
03036
03037 if (frUpper)
03038 {
03039 if (taskP.taskStatus(task))
03040 {
03041 sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,DeviceAddress,m_TRANSACTION_OVERFLOW);
03042 return;
03043 }
03044 taskP.taskStep(task) = 0;
03045 (taskP.taskFrFunc(task))[0] = 0;
03046 }
03047 step = taskP.taskStep(task);
03048 switch(step)
03049 {
03050 case 0:
03051
03052 if ((Status != m_SUCCESS)&&(Status != m_PAN_at_capacity)&&(Status != m_PAN_access_denied))
03053 {
03054 sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,DeviceAddress,m_INVALID_PARAMETER);
03055 return;
03056 }
03057 taskP.taskStatus(task) = true;
03058 taskP.taskStep(task)++;
03059 strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
03060 taskP.mlme_associate_response_DeviceAddress = DeviceAddress;
03061
03062 rspPkt = Packet::alloc();
03063 assert(rspPkt);
03064 wph = HDR_LRWPAN(rspPkt);
03065 #ifdef ZigBeeIF
03066 sscs->setGetClusTreePara('s',rspPkt);
03067 #endif
03068 constructCommandHeader(rspPkt,&frmCtrl,0x02,defFrmCtrl_AddrMode64,mpib.macPANId,DeviceAddress,defFrmCtrl_AddrMode64,mpib.macPANId,aExtendedAddress,SecurityEnable,false,true);
03069 *((UINT_16 *)wph->MSDU_Payload) = AssocShortAddress;
03070 *((MACenum *)(wph->MSDU_Payload + 2)) = Status;
03071 constructMPDU(4,rspPkt,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0x02,0);
03072 kpTime = (2 * aResponseWaitTime) / phy->getRate('s');
03073 i = chkAddTransacLink(&transacLink1,&transacLink2,defFrmCtrl_AddrMode64,DeviceAddress,rspPkt,0,kpTime);
03074 if (i != 0)
03075 {
03076 #ifdef DEBUG802_15_4
03077 hdr_cmn *ch = HDR_CMN(rspPkt);
03078 fprintf(stdout,"[%s::%s][%f](node %d) task overflow or failed: type = %s, src = %d, dst = %d, uid = %d, mac_uid = ??, size = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(rspPkt),p802_15_4macSA(rspPkt),p802_15_4macDA(rspPkt),wph->uid,ch->size());
03079 #endif
03080 taskP.taskStatus(task) = false;
03081 Packet::free(rspPkt);
03082 sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,DeviceAddress,m_TRANSACTION_OVERFLOW);
03083 return;
03084 }
03085
03086 assoRspWaitT->start(kpTime);
03087 taskP.mlme_associate_response_pendPkt = rspPkt;
03088 break;
03089 case 1:
03090 if (!taskP.taskStatus(task))
03091 break;
03092 taskP.taskStatus(task) = false;
03093 assoRspWaitT->stop();
03094 if (status == p_SUCCESS)
03095 {
03096 sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,DeviceAddress,m_SUCCESS);
03097 taskSuccess('c');
03098 }
03099 else
03100 {
03101
03102 sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,DeviceAddress,Status);
03103 freePkt(txBcnCmd);
03104 txBcnCmd = 0;
03105 }
03106 break;
03107 case 2:
03108 if (!taskP.taskStatus(task))
03109 break;
03110 taskP.taskStatus(task) = false;
03111
03112 i = updateTransacLinkByPktOrHandle(tr_oper_est,&transacLink1,&transacLink2,taskP.mlme_associate_response_pendPkt);
03113 if (i == 0)
03114 {
03115
03116 updateTransacLinkByPktOrHandle(tr_oper_del,&transacLink1,&transacLink2,taskP.mlme_associate_response_pendPkt);
03117 sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,DeviceAddress,m_TRANSACTION_EXPIRED);
03118 return;
03119 }
03120 else
03121 {
03122 sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,DeviceAddress,m_SUCCESS);
03123 return;
03124 }
03125 break;
03126 default:
03127 break;
03128 }
03129 }
03130
03131 void Mac802_15_4::mlme_disassociate_request(IE3ADDR DeviceAddress,UINT_8 DisassociateReason,bool SecurityEnable,bool frUpper,PHYenum status)
03132 {
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228 }
03229
03230 void Mac802_15_4::mlme_orphan_response(IE3ADDR OrphanAddress,UINT_16 ShortAddress,bool AssociatedMember,bool SecurityEnable,bool frUpper,PHYenum status)
03231 {
03232 hdr_lrwpan* wph;
03233 FrameCtrl frmCtrl;
03234
03235 UINT_8 task;
03236
03237 task = TP_mlme_orphan_response;
03238 if (frUpper) checkTaskOverflow(task);
03239
03240 switch(taskP.taskStep(task))
03241 {
03242 case 0:
03243 if (AssociatedMember)
03244 {
03245
03246 #ifdef DEBUG802_15_4
03247 fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBcnCmd:\n\t\ttxBeacon\t= %ld\n\t\ttxAck \t= %ld\n\t\ttxBcnCmd\t= %ld\n\t\ttxBcnCmd2\t= %ld\n\t\ttxData \t= %ld\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
03248 #endif
03249 taskP.taskStatus(task) = true;
03250 taskP.taskStep(task)++;
03251 strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
03252 taskP.mlme_orphan_response_OrphanAddress = OrphanAddress;
03253 assert(!txBcnCmd);
03254 txBcnCmd = Packet::alloc();
03255 assert(txBcnCmd);
03256 wph = HDR_LRWPAN(txBcnCmd);
03257 constructCommandHeader(txBcnCmd,&frmCtrl,0x08,defFrmCtrl_AddrMode64,0xffff,OrphanAddress,defFrmCtrl_AddrMode64,mpib.macPANId,aExtendedAddress,SecurityEnable,false,true);
03258 *((UINT_16 *)wph->MSDU_Payload) = mpib.macPANId;
03259 *((UINT_16 *)wph->MSDU_Payload + 2) = mpib.macShortAddress;
03260 phy->PLME_GET_request(phyCurrentChannel);
03261 *((UINT_8 *)wph->MSDU_Payload + 4) = tmp_ppib.phyCurrentChannel;
03262 *((UINT_16 *)wph->MSDU_Payload + 5) = ShortAddress;
03263 constructMPDU(8,txBcnCmd,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0x08,0);
03264 csmacaBegin('c');
03265 }
03266 break;
03267 case 1:
03268 taskP.taskStatus(task) = false;
03269 if (status == p_SUCCESS)
03270 {
03271 sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,OrphanAddress,m_SUCCESS);
03272 taskSuccess('c');
03273 }
03274 else
03275 {
03276 sscs->MLME_COMM_STATUS_indication(mpib.macPANId,defFrmCtrl_AddrMode64,aExtendedAddress,defFrmCtrl_AddrMode64,OrphanAddress,m_CHANNEL_ACCESS_FAILURE);
03277 freePkt(txBcnCmd);
03278 txBcnCmd = 0;
03279 csmacaResume();
03280 }
03281 break;
03282 default:
03283 break;
03284 }
03285 }
03286
03287 void Mac802_15_4::mlme_reset_request(bool SetDefaultPIB,bool frUpper,PHYenum status)
03288 {
03289
03290 UINT_8 task;
03291
03292 task = TP_mlme_reset_request;
03293 if (frUpper) checkTaskOverflow(task);
03294
03295 switch(taskP.taskStep(task))
03296 {
03297 case 0:
03298 taskP.taskStatus(task) = true;
03299 taskP.taskStep(task)++;
03300 strcpy(taskP.taskFrFunc(task),"PLME_SET_TRX_STATE_confirm");
03301 taskP.mlme_reset_request_SetDefaultPIB = SetDefaultPIB;
03302 plme_set_trx_state_request(p_TRX_OFF);
03303 break;
03304 case 1:
03305 taskP.taskStatus(task) = false;
03306 init(true);
03307 if (SetDefaultPIB)
03308 mpib = MPIB;
03309 if (status == p_TRX_OFF)
03310 sscs->MLME_RESET_confirm(m_SUCCESS);
03311 else
03312 sscs->MLME_RESET_confirm(m_DISABLE_TRX_FAILURE);
03313 break;
03314 default:
03315 break;
03316 }
03317 }
03318
03319 void Mac802_15_4::mlme_rx_enable_request(bool DeferPermit,UINT_32 RxOnTime,UINT_32 RxOnDuration,bool frUpper,PHYenum status)
03320 {
03321 UINT_8 step,task;
03322 UINT_32 t_CAP;
03323 double cutTime,tmpf;
03324
03325 task = TP_mlme_rx_enable_request;
03326 if (frUpper) checkTaskOverflow(task);
03327
03328 step = taskP.taskStep(task);
03329
03330 if (step == 0)
03331 if (RxOnDuration == 0)
03332 {
03333 sscs->MLME_RX_ENABLE_confirm(m_SUCCESS);
03334 plme_set_trx_state_request(p_TRX_OFF);
03335 return;
03336 }
03337
03338 if (macBeaconOrder2 != 15)
03339 {
03340 switch(step)
03341 {
03342 case 0:
03343 taskP.mlme_rx_enable_request_RxOnTime = RxOnTime;
03344 taskP.mlme_rx_enable_request_RxOnDuration = RxOnDuration;
03345 if (RxOnTime + RxOnDuration >= sfSpec2.BI)
03346 {
03347 sscs->MLME_RX_ENABLE_confirm(m_INVALID_PARAMETER);
03348 return;
03349 }
03350 t_CAP = (sfSpec2.FinCAP + 1) * sfSpec2.sd;
03351
03352
03353
03354 tmpf = CURRENT_TIME * phy->getRate('s');
03355
03356 if ((RxOnTime - aTurnaroundTime) > t_CAP)
03357 {
03358 sscs->MLME_RX_ENABLE_confirm(m_OUT_OF_CAP);
03359 return;
03360 }
03361
03362
03363
03364 else if ((tmpf - macBcnRxTime) < (RxOnTime - aTurnaroundTime))
03365 {
03366
03367 taskP.taskStatus(task) = true;
03368 taskP.taskStep(task)++;
03369
03370 }
03371 else if (DeferPermit)
03372 {
03373
03374 taskP.taskStatus(task) = true;
03375 taskP.taskStep(task)++;
03376 strcpy(taskP.taskFrFunc(task),"recvBeacon");
03377 break;
03378 }
03379 else
03380 {
03381 sscs->MLME_RX_ENABLE_confirm(m_OUT_OF_CAP);
03382 return;
03383 }
03384 case 1:
03385 taskP.taskStep(task)++;
03386 strcpy(taskP.taskFrFunc(task),"rxEnableHandler");
03387
03388
03389
03390 {
03391 double tmpf2;
03392 tmpf = macBcnRxTime / phy->getRate('s');
03393 tmpf = CURRENT_TIME - tmpf;
03394 tmpf2 = RxOnTime / phy->getRate('s');
03395 tmpf = tmpf2 - tmpf;
03396 rxEnableT->start(tmpf);
03397 }
03398 break;
03399 case 2:
03400 taskP.taskStep(task)++;
03401 strcpy(taskP.taskFrFunc(task),"PLME_SET_TRX_STATE_confirm");
03402 taskP.mlme_rx_enable_request_currentTime = CURRENT_TIME;
03403 plme_set_trx_state_request(p_RX_ON);
03404 break;
03405 case 3:
03406 taskP.taskStatus(task) = false;
03407 strcpy(taskP.taskFrFunc(task),"rxEnableHandler");
03408 taskP.taskStep(task)++;
03409 if (status == p_TX_ON)
03410 sscs->MLME_RX_ENABLE_confirm(m_TX_ACTIVE);
03411 else
03412 sscs->MLME_RX_ENABLE_confirm(m_SUCCESS);
03413
03414 t_CAP = (sfSpec2.FinCAP + 1) * sfSpec2.sd;
03415 cutTime = (RxOnTime + RxOnDuration - t_CAP) / phy->getRate('s');
03416
03417
03418
03419
03420 {
03421 tmpf = RxOnDuration / phy->getRate('s');
03422 tmpf -= CURRENT_TIME;
03423 tmpf += taskP.mlme_rx_enable_request_currentTime;
03424 tmpf -= cutTime;
03425 rxEnableT->start(tmpf);
03426 }
03427 break;
03428 case 4:
03429 strcpy(taskP.taskFrFunc(task),"");
03430 plme_set_trx_state_request(p_TRX_OFF);
03431 break;
03432 default:
03433 break;
03434 }
03435 }
03436 else
03437 {
03438 switch(step)
03439 {
03440 case 0:
03441 taskP.taskStatus(task) = true;
03442 strcpy(taskP.taskFrFunc(task),"PLME_SET_TRX_STATE_confirm");
03443 taskP.taskStep(task)++;
03444 taskP.mlme_rx_enable_request_RxOnDuration = RxOnDuration;
03445 taskP.mlme_rx_enable_request_currentTime = CURRENT_TIME;
03446 plme_set_trx_state_request(p_RX_ON);
03447 break;
03448 case 1:
03449 taskP.taskStatus(task) = false;
03450 strcpy(taskP.taskFrFunc(task),"rxEnableHandler");
03451 taskP.taskStep(task)++;
03452 if (status == p_TX_ON)
03453 sscs->MLME_RX_ENABLE_confirm(m_TX_ACTIVE);
03454 else
03455 sscs->MLME_RX_ENABLE_confirm(m_SUCCESS);
03456
03457
03458
03459 {
03460 tmpf = RxOnDuration / phy->getRate('s');
03461 tmpf -= CURRENT_TIME;
03462 tmpf += taskP.mlme_rx_enable_request_currentTime;
03463 rxEnableT->start(tmpf);
03464 }
03465 break;
03466 case 2:
03467 strcpy(taskP.taskFrFunc(task),"");
03468 plme_set_trx_state_request(p_TRX_OFF);
03469 break;
03470 default:
03471 break;
03472 }
03473 }
03474 }
03475
03476 void Mac802_15_4::mlme_scan_request(UINT_8 ScanType,UINT_32 ScanChannels,UINT_8 ScanDuration,bool frUpper,PHYenum status)
03477 {
03478 UINT_32 t_chanPos;
03479 UINT_8 step,task;
03480 FrameCtrl frmCtrl;
03481 hdr_lrwpan* wph;
03482 int i;
03483
03484 task = TP_mlme_scan_request;
03485 if (frUpper) checkTaskOverflow(task);
03486
03487 step = taskP.taskStep(task);
03488
03489 if (step == 0)
03490 {
03491 if ((ScanType > 3)
03492 ||((ScanType != 3)&&(ScanDuration > 14)))
03493 {
03494 sscs->MLME_SCAN_confirm(m_INVALID_PARAMETER,ScanType,ScanChannels,0,NULL,NULL);
03495 return;
03496 }
03497
03498 taskP.mlme_scan_request_orig_macBeaconOrder = mpib.macBeaconOrder;
03499 taskP.mlme_scan_request_orig_macBeaconOrder2 = macBeaconOrder2;
03500 taskP.mlme_scan_request_orig_macBeaconOrder3 = macBeaconOrder3;
03501 mpib.macBeaconOrder = 15;
03502 macBeaconOrder2 = 15;
03503 macBeaconOrder3 = 15;
03504
03505 if (backoffStatus == 99)
03506 {
03507 backoffStatus = 0;
03508 csmaca->cancel();
03509 }
03510 taskP.mlme_scan_request_ScanType = ScanType;
03511 }
03512
03513 if (ScanType == 0x00)
03514 switch (step)
03515 {
03516 case 0:
03517 phy->PLME_GET_request(phyChannelsSupported);
03518 taskP.mlme_scan_request_ScanChannels = ScanChannels;
03519 if ((taskP.mlme_scan_request_ScanChannels & tmp_ppib.phyChannelsSupported) == 0)
03520 {
03521
03522 mpib.macBeaconOrder = taskP.mlme_scan_request_orig_macBeaconOrder;
03523 macBeaconOrder2 = taskP.mlme_scan_request_orig_macBeaconOrder2;
03524 macBeaconOrder3 = taskP.mlme_scan_request_orig_macBeaconOrder3;
03525 sscs->MLME_SCAN_confirm(m_SUCCESS,ScanType,ScanChannels,0,NULL,NULL);
03526 csmacaResume();
03527 return;
03528 }
03529 taskP.taskStatus(task) = true;
03530 taskP.taskStep(task)++;
03531 strcpy(taskP.taskFrFunc(task),"PLME_SET_confirm");
03532 taskP.mlme_scan_request_CurrentChannel = 0;
03533 taskP.mlme_scan_request_ListNum = 0;
03534 t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
03535 while((t_chanPos & taskP.mlme_scan_request_ScanChannels) == 0
03536 ||(t_chanPos & tmp_ppib.phyChannelsSupported) == 0)
03537 {
03538 taskP.mlme_scan_request_CurrentChannel++;
03539 t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
03540 }
03541 tmp_ppib.phyCurrentChannel = taskP.mlme_scan_request_CurrentChannel;
03542 phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
03543 break;
03544 case 1:
03545 taskP.taskStep(task)++;
03546 strcpy(taskP.taskFrFunc(task),"PLME_SET_TRX_STATE_confirm");
03547 plme_set_trx_state_request(p_RX_ON);
03548 break;
03549 case 2:
03550 if (status == p_RX_ON)
03551 {
03552 taskP.taskStep(task)++;
03553 strcpy(taskP.taskFrFunc(task),"PLME_ED_confirm");
03554 phy->PLME_ED_request();
03555 break;
03556 }
03557
03558 case 3:
03559 if (step == 3)
03560 {
03561 if (status == p_SUCCESS)
03562 {
03563 t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
03564 taskP.mlme_scan_request_ScanChannels &= (t_chanPos^0xffffffff);
03565 taskP.mlme_scan_request_EnergyDetectList[taskP.mlme_scan_request_ListNum] = energyLevel;
03566 taskP.mlme_scan_request_ListNum++;
03567 }
03568 }
03569
03570 case 4:
03571 if ((taskP.mlme_scan_request_ScanChannels & tmp_ppib.phyChannelsSupported) == 0)
03572 {
03573
03574 mpib.macBeaconOrder = taskP.mlme_scan_request_orig_macBeaconOrder;
03575 macBeaconOrder2 = taskP.mlme_scan_request_orig_macBeaconOrder2;
03576 macBeaconOrder3 = taskP.mlme_scan_request_orig_macBeaconOrder3;
03577 taskP.taskStatus(task) = false;
03578 sscs->MLME_SCAN_confirm(m_SUCCESS,ScanType,taskP.mlme_scan_request_ScanChannels,taskP.mlme_scan_request_ListNum,taskP.mlme_scan_request_EnergyDetectList,NULL);
03579 csmacaResume();
03580 return;
03581 }
03582 taskP.taskStep(task) = 1;
03583 strcpy(taskP.taskFrFunc(task),"PLME_SET_confirm");
03584 taskP.mlme_scan_request_CurrentChannel++;
03585 t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
03586 while((t_chanPos & taskP.mlme_scan_request_ScanChannels) == 0
03587 ||(t_chanPos & tmp_ppib.phyChannelsSupported) == 0)
03588 {
03589 taskP.mlme_scan_request_CurrentChannel++;
03590 t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
03591 }
03592 tmp_ppib.phyCurrentChannel = taskP.mlme_scan_request_CurrentChannel;
03593 phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
03594 break;
03595 default:
03596 break;
03597 }
03598
03599 else if ((ScanType == 0x01)
03600 || (ScanType == 0x02))
03601 switch (step)
03602 {
03603 case 0:
03604 phy->PLME_GET_request(phyChannelsSupported);
03605 taskP.mlme_scan_request_ScanChannels = ScanChannels;
03606 if ((taskP.mlme_scan_request_ScanChannels & tmp_ppib.phyChannelsSupported) == 0)
03607 {
03608 mpib.macBeaconOrder = taskP.mlme_scan_request_orig_macBeaconOrder;
03609 macBeaconOrder2 = taskP.mlme_scan_request_orig_macBeaconOrder2;
03610 macBeaconOrder3 = taskP.mlme_scan_request_orig_macBeaconOrder3;
03611 sscs->MLME_SCAN_confirm(m_SUCCESS,ScanType,ScanChannels,0,NULL,NULL);
03612 csmacaResume();
03613 return;
03614 }
03615 taskP.taskStatus(task) = true;
03616 taskP.taskStep(task)++;
03617 strcpy(taskP.taskFrFunc(task),"PLME_SET_confirm");
03618 taskP.mlme_scan_request_orig_macPANId = mpib.macPANId;
03619 mpib.macPANId = 0xffff;
03620 taskP.mlme_scan_request_ScanDuration = ScanDuration;
03621 taskP.mlme_scan_request_CurrentChannel = 0;
03622 taskP.mlme_scan_request_ListNum = 0;
03623 t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
03624 while((t_chanPos & taskP.mlme_scan_request_ScanChannels) == 0
03625 ||(t_chanPos & tmp_ppib.phyChannelsSupported) == 0)
03626 {
03627 taskP.mlme_scan_request_CurrentChannel++;
03628 t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
03629 }
03630 tmp_ppib.phyCurrentChannel = taskP.mlme_scan_request_CurrentChannel;
03631 phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
03632 break;
03633 case 1:
03634 if (Mac802_15_4::verbose)
03635 fprintf(stdout,"[%f](node %d) scanning channel %d\n",CURRENT_TIME,index_,taskP.mlme_scan_request_CurrentChannel);
03636 if (ScanType == 0x01)
03637 {
03638 taskP.taskStep(task)++;
03639 strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
03640
03641 #ifdef DEBUG802_15_4
03642 fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBcnCmd2:\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);
03643 #endif
03644 assert(!txBcnCmd2);
03645 txBcnCmd2 = Packet::alloc();
03646 assert(txBcnCmd2);
03647 wph = HDR_LRWPAN(txBcnCmd2);
03648 constructCommandHeader(txBcnCmd2,&frmCtrl,0x07,defFrmCtrl_AddrMode16,0xffff,0xffff,defFrmCtrl_AddrModeNone,0,0,false,false,false);
03649 constructMPDU(1,txBcnCmd2,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0x07,0);
03650 csmacaBegin('C');
03651
03652 }
03653 else
03654 {
03655 taskP.taskStep(task) = 4;
03656 strcpy(taskP.taskFrFunc(task),"PLME_SET_TRX_STATE_confirm");
03657 plme_set_trx_state_request(p_RX_ON);
03658 }
03659 break;
03660 case 2:
03661 if (status == p_IDLE)
03662 {
03663 taskP.taskStep(task)++;
03664 strcpy(taskP.taskFrFunc(task),"PD_DATA_confirm");
03665 plme_set_trx_state_request(p_TX_ON);
03666 break;
03667 }
03668 else
03669 {
03670 freePkt(txBcnCmd2);
03671 txBcnCmd2 = 0;
03672
03673 }
03674 case 3:
03675 if (step == 3)
03676 {
03677 taskP.taskStep(task)++;
03678 strcpy(taskP.taskFrFunc(task),"PLME_SET_TRX_STATE_confirm");
03679 taskSuccess('C',false);
03680 plme_set_trx_state_request(p_RX_ON);
03681 break;
03682 }
03683 case 4:
03684 if (step == 4)
03685 {
03686 if (status == p_RX_ON)
03687 {
03688 taskP.taskStep(task)++;
03689 strcpy(taskP.taskFrFunc(task),"recvBeacon");
03690
03691 scanT->start((aBaseSuperframeDuration * ((1 << taskP.mlme_scan_request_ScanDuration) + 1)) / phy->getRate('s'));
03692 break;
03693 }
03694
03695 }
03696 case 5:
03697 if (step == 5)
03698 {
03699
03700
03701 assert(rxBeacon);
03702 wph = HDR_LRWPAN(rxBeacon);
03703 frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
03704 frmCtrl.parse();
03705 for (i=0;i<taskP.mlme_scan_request_ListNum;i++)
03706 if ((taskP.mlme_scan_request_PANDescriptorList[i].LogicalChannel == taskP.mlme_scan_request_CurrentChannel)
03707 && (taskP.mlme_scan_request_PANDescriptorList[i].CoordAddrMode == frmCtrl.srcAddrMode)
03708 && (taskP.mlme_scan_request_PANDescriptorList[i].CoordPANId == wph->MHR_SrcAddrInfo.panID)
03709 && (((frmCtrl.srcAddrMode == defFrmCtrl_AddrMode16)&&(taskP.mlme_scan_request_PANDescriptorList[i].CoordAddress_16 == (wph->MHR_SrcAddrInfo.addr_16))
03710 ||((frmCtrl.srcAddrMode == defFrmCtrl_AddrMode64)&&(taskP.mlme_scan_request_PANDescriptorList[i].CoordAddress_64 == wph->MHR_SrcAddrInfo.addr_64)))))
03711 break;
03712 if (i >= taskP.mlme_scan_request_ListNum)
03713 {
03714 taskP.mlme_scan_request_PANDescriptorList[taskP.mlme_scan_request_ListNum] = panDes2;
03715 taskP.mlme_scan_request_ListNum++;
03716 if (taskP.mlme_scan_request_ListNum >= 27)
03717 {
03718
03719 scanT->stop();
03720
03721 }
03722 else
03723 break;
03724 }
03725 else
03726 break;
03727 }
03728 case 6:
03729 if (step == 6)
03730 {
03731 t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
03732 taskP.mlme_scan_request_ScanChannels &= (t_chanPos^0xffffffff);
03733
03734 }
03735 case 7:
03736 if (((taskP.mlme_scan_request_ScanChannels & tmp_ppib.phyChannelsSupported) == 0)
03737 ||(taskP.mlme_scan_request_ListNum >= 27))
03738 {
03739 mpib.macPANId = taskP.mlme_scan_request_orig_macPANId;
03740 mpib.macBeaconOrder = taskP.mlme_scan_request_orig_macBeaconOrder;
03741 macBeaconOrder2 = taskP.mlme_scan_request_orig_macBeaconOrder2;
03742 macBeaconOrder3 = taskP.mlme_scan_request_orig_macBeaconOrder3;
03743 taskP.taskStatus(task) = false;
03744 sscs->MLME_SCAN_confirm(m_SUCCESS,ScanType,taskP.mlme_scan_request_ScanChannels,taskP.mlme_scan_request_ListNum,NULL,taskP.mlme_scan_request_PANDescriptorList);
03745 csmacaResume();
03746 return;
03747 }
03748 taskP.taskStep(task) = 1;
03749 strcpy(taskP.taskFrFunc(task),"PLME_SET_confirm");
03750 taskP.mlme_scan_request_CurrentChannel++;
03751 t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
03752 while((t_chanPos & taskP.mlme_scan_request_ScanChannels) == 0
03753 ||(t_chanPos & tmp_ppib.phyChannelsSupported) == 0)
03754 {
03755 taskP.mlme_scan_request_CurrentChannel++;
03756 t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
03757 }
03758 tmp_ppib.phyCurrentChannel = taskP.mlme_scan_request_CurrentChannel;
03759 phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
03760 break;
03761 default:
03762 break;
03763 }
03764
03765 else
03766 switch (step)
03767 {
03768 case 0:
03769 phy->PLME_GET_request(phyChannelsSupported);
03770 taskP.mlme_scan_request_ScanChannels = ScanChannels;
03771 if ((taskP.mlme_scan_request_ScanChannels & tmp_ppib.phyChannelsSupported) == 0)
03772 {
03773 mpib.macBeaconOrder = taskP.mlme_scan_request_orig_macBeaconOrder;
03774
03775 macBeaconOrder2 = 15;
03776 macBeaconOrder3 = taskP.mlme_scan_request_orig_macBeaconOrder3;
03777 sscs->MLME_SCAN_confirm(m_INVALID_PARAMETER,ScanType,ScanChannels,0,NULL,NULL);
03778 csmacaResume();
03779 return;
03780 }
03781 taskP.taskStatus(task) = true;
03782 taskP.taskStep(task)++;
03783 strcpy(taskP.taskFrFunc(task),"PLME_SET_confirm");
03784 taskP.mlme_scan_request_CurrentChannel = 0;
03785 t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
03786 while((t_chanPos & taskP.mlme_scan_request_ScanChannels) == 0
03787 ||(t_chanPos & tmp_ppib.phyChannelsSupported) == 0)
03788 {
03789 taskP.mlme_scan_request_CurrentChannel++;
03790 t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
03791 }
03792 tmp_ppib.phyCurrentChannel = taskP.mlme_scan_request_CurrentChannel;
03793 phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
03794 break;
03795 case 1:
03796 if (Mac802_15_4::verbose)
03797 fprintf(stdout,"[%f](node %d) orphan-scanning channel %d\n",CURRENT_TIME,index_,taskP.mlme_scan_request_CurrentChannel);
03798 taskP.taskStep(task)++;
03799 strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
03800
03801 #ifdef DEBUG802_15_4
03802 fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBcnCmd2:\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);
03803 #endif
03804 assert(!txBcnCmd2);
03805 txBcnCmd2 = Packet::alloc();
03806 assert(txBcnCmd2);
03807 wph = HDR_LRWPAN(txBcnCmd2);
03808 constructCommandHeader(txBcnCmd2,&frmCtrl,0x06,defFrmCtrl_AddrMode64,mpib.macPANId,mpib.macCoordExtendedAddress,defFrmCtrl_AddrMode64,mpib.macPANId,aExtendedAddress,false,false,false);
03809 constructMPDU(1,txBcnCmd2,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0x06,0);
03810 csmacaBegin('C');
03811
03812 break;
03813 case 2:
03814 if (status == p_IDLE)
03815 {
03816 taskP.taskStep(task)++;
03817 strcpy(taskP.taskFrFunc(task),"PD_DATA_confirm");
03818 plme_set_trx_state_request(p_TX_ON);
03819 break;
03820 }
03821 else
03822 {
03823 freePkt(txBcnCmd2);
03824 txBcnCmd2 = 0;
03825
03826 }
03827 case 3:
03828 if (step == 3)
03829 {
03830 taskP.taskStep(task)++;
03831 strcpy(taskP.taskFrFunc(task),"PLME_SET_TRX_STATE_confirm");
03832 taskSuccess('C',false);
03833 plme_set_trx_state_request(p_RX_ON);
03834 break;
03835 }
03836 case 4:
03837 if (step == 4)
03838 {
03839 if (status == p_RX_ON)
03840 {
03841 taskP.taskStep(task)++;
03842 strcpy(taskP.taskFrFunc(task),"IFSHandler");
03843 scanT->start(aResponseWaitTime / phy->getRate('s'));
03844 break;
03845 }
03846
03847 }
03848 case 5:
03849 if (step == 5)
03850 {
03851 if (status == p_SUCCESS)
03852 {
03853 scanT->stop();
03854 mpib.macBeaconOrder = taskP.mlme_scan_request_orig_macBeaconOrder;
03855 macBeaconOrder2 = taskP.mlme_scan_request_orig_macBeaconOrder2;
03856 macBeaconOrder3 = taskP.mlme_scan_request_orig_macBeaconOrder3;
03857 taskP.taskStatus(task) = false;
03858 changeNodeColor(CURRENT_TIME,(mpib.macAssociationPermit)?Nam802_15_4::def_Coor_clr:Nam802_15_4::def_Dev_clr);
03859 t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
03860 taskP.mlme_scan_request_ScanChannels &= (t_chanPos^0xffffffff);
03861 sscs->MLME_SCAN_confirm(m_SUCCESS,ScanType,taskP.mlme_scan_request_ScanChannels,0,NULL,NULL);
03862 csmacaResume();
03863 break;
03864 }
03865 else
03866 {
03867 t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
03868 taskP.mlme_scan_request_ScanChannels &= (t_chanPos^0xffffffff);
03869
03870 }
03871 }
03872 case 6:
03873 if ((taskP.mlme_scan_request_ScanChannels & tmp_ppib.phyChannelsSupported) == 0)
03874 {
03875 mpib.macBeaconOrder = taskP.mlme_scan_request_orig_macBeaconOrder;
03876
03877 macBeaconOrder2 = 15;
03878 macBeaconOrder3 = taskP.mlme_scan_request_orig_macBeaconOrder3;
03879 taskP.taskStatus(task) = false;
03880 sscs->MLME_SCAN_confirm(m_NO_BEACON,ScanType,taskP.mlme_scan_request_ScanChannels,0,NULL,NULL);
03881 csmacaResume();
03882 return;
03883 }
03884 taskP.taskStep(task) = 1;
03885 strcpy(taskP.taskFrFunc(task),"PLME_SET_confirm");
03886 taskP.mlme_scan_request_CurrentChannel++;
03887 t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
03888 while((t_chanPos & taskP.mlme_scan_request_ScanChannels) == 0
03889 ||(t_chanPos & tmp_ppib.phyChannelsSupported) == 0)
03890 {
03891 taskP.mlme_scan_request_CurrentChannel++;
03892 t_chanPos = (1<<taskP.mlme_scan_request_CurrentChannel);
03893 }
03894 tmp_ppib.phyCurrentChannel = taskP.mlme_scan_request_CurrentChannel;
03895 phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
03896 break;
03897 default:
03898 break;
03899 }
03900 }
03901
03902 void Mac802_15_4::mlme_start_request(UINT_16 PANId,UINT_8 LogicalChannel,UINT_8 BeaconOrder,
03903 UINT_8 SuperframeOrder,bool PANCoordinator,bool BatteryLifeExtension,
03904 bool CoordRealignment,bool SecurityEnable,
03905 bool frUpper,PHYenum status)
03906 {
03907 FrameCtrl frmCtrl;
03908 hdr_lrwpan* wph;
03909 UINT_8 origBeaconOrder;
03910 UINT_8 step,task;
03911
03912 task = TP_mlme_start_request;
03913 if (frUpper) checkTaskOverflow(task);
03914
03915 step = taskP.taskStep(task);
03916 switch (step)
03917 {
03918 case 0:
03919 if (mpib.macShortAddress == 0xffff)
03920 {
03921 sscs->MLME_START_confirm(m_NO_SHORT_ADDRESS);
03922 return;
03923 }
03924 else if ((!phy->channelSupported(LogicalChannel))
03925 || (BeaconOrder > 15)
03926 || ((SuperframeOrder > BeaconOrder)&&(SuperframeOrder != 15)))
03927 {
03928 sscs->MLME_START_confirm(m_INVALID_PARAMETER);
03929 return;
03930 }
03931 else if (!capability.FFD)
03932 {
03933 sscs->MLME_START_confirm(m_UNDEFINED);
03934 return;
03935 }
03936 taskP.taskStatus(task) = true;
03937 if (CoordRealignment)
03938 {
03939 taskP.taskStep(task)++;
03940 strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
03941
03942 #ifdef DEBUG802_15_4
03943 fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBcnCmd2:\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);
03944 #endif
03945 assert(!txBcnCmd2);
03946 txBcnCmd2 = Packet::alloc();
03947 assert(txBcnCmd2);
03948 wph = HDR_LRWPAN(txBcnCmd2);
03949 constructCommandHeader(txBcnCmd2,&frmCtrl,0x08,defFrmCtrl_AddrMode16,0xffff,0xffff,defFrmCtrl_AddrMode64,mpib.macPANId,aExtendedAddress,false,false,false);
03950
03951 wph->MSDU_PayloadLen = 7;
03952 *((UINT_16 *)wph->MSDU_Payload) = PANId;
03953 *((UINT_16 *)(wph->MSDU_Payload + 2)) = mpib.macShortAddress;
03954 wph->MSDU_Payload[4] = LogicalChannel;
03955 *((UINT_16 *)(wph->MSDU_Payload + 5)) = 0xffff;
03956 constructMPDU(8,txBcnCmd2,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0x08,0);
03957 csmacaBegin('C');
03958
03959
03960 taskP.mlme_start_request_BeaconOrder = BeaconOrder;
03961 taskP.mlme_start_request_SuperframeOrder = SuperframeOrder;
03962 taskP.mlme_start_request_BatteryLifeExtension = BatteryLifeExtension;
03963 taskP.mlme_start_request_SecurityEnable = SecurityEnable;
03964 taskP.mlme_start_request_PANCoordinator = PANCoordinator;
03965 taskP.mlme_start_request_PANId = PANId;
03966 taskP.mlme_start_request_LogicalChannel = LogicalChannel;
03967 break;
03968 }
03969 else
03970 {
03971 taskP.taskStep(task) = 2;
03972 step = 2;
03973
03974 }
03975 case 1:
03976 if (step == 1)
03977 {
03978 if (status == p_IDLE)
03979 {
03980 taskP.taskStep(task)++;
03981 strcpy(taskP.taskFrFunc(task),"PD_DATA_confirm");
03982 plme_set_trx_state_request(p_TX_ON);
03983 break;
03984 }
03985 else
03986 {
03987 freePkt(txBcnCmd2);
03988 txBcnCmd2 = 0;
03989
03990 taskP.taskStep(task) = 2;
03991 }
03992 }
03993 case 2:
03994 taskP.taskStep(task)++;
03995 strcpy(taskP.taskFrFunc(task),"PD_DATA_confirm");
03996 resetTRX();
03997 if (CoordRealignment)
03998 taskSuccess('C',false);
03999
04000 origBeaconOrder = mpib.macBeaconOrder;
04001 mpib.macBeaconOrder = BeaconOrder;
04002 if (BeaconOrder == 15)
04003 mpib.macSuperframeOrder = 15;
04004 else
04005 mpib.macSuperframeOrder = SuperframeOrder;
04006 mpib.macBattLifeExt = BatteryLifeExtension;
04007 secuBeacon = SecurityEnable;
04008 if (isPANCoor != PANCoordinator)
04009 changeNodeColor(CURRENT_TIME,PANCoordinator?Nam802_15_4::def_PANCoor_clr:Nam802_15_4::def_Coor_clr);
04010 isPANCoor = PANCoordinator;
04011 if (PANCoordinator)
04012 {
04013 mpib.macPANId = PANId;
04014 mpib.macCoordExtendedAddress = aExtendedAddress;
04015 tmp_ppib.phyCurrentChannel = LogicalChannel;
04016 phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
04017 }
04018 if (origBeaconOrder == BeaconOrder)
04019 {
04020 taskP.taskStatus(task) = false;
04021 sscs->MLME_START_confirm(m_SUCCESS);
04022 csmacaResume();
04023 }
04024 else if ((origBeaconOrder == 15)&&(BeaconOrder < 15))
04025 {
04026
04027 if (bcnTxT->busy())
04028 bcnTxT->stop();
04029 bcnTxT->start(true,true,0.0);
04030 }
04031 else if ((origBeaconOrder < 15)&&(BeaconOrder == 15))
04032 oneMoreBeacon = true;
04033 break;
04034 case 3:
04035 taskP.taskStatus(task) = false;
04036 sscs->MLME_START_confirm(m_SUCCESS);
04037 taskSuccess('b');
04038 break;
04039 default:
04040 break;
04041 }
04042 }
04043
04044 void Mac802_15_4::mlme_sync_request(UINT_8 LogicalChannel, bool TrackBeacon,bool frUpper,PHYenum status)
04045 {
04046 UINT_8 step,task,BO;
04047
04048 task = TP_mlme_sync_request;
04049 if (frUpper)
04050 {
04051
04052
04053 if (bcnRxT->busy())
04054 bcnRxT->stop();
04055 taskP.taskStep(task) = 0;
04056 (taskP.taskFrFunc(task))[0] = 0;
04057 }
04058
04059 step = taskP.taskStep(task);
04060 switch(step)
04061 {
04062 case 0:
04063
04064 if ((!phy->channelSupported(LogicalChannel))
04065 || (mpib.macPANId == 0xffff)
04066
04067 )
04068 {
04069 sscs->MLME_SYNC_LOSS_indication(m_UNDEFINED);
04070 return;
04071 }
04072 taskP.taskStatus(task) = true;
04073 taskP.taskStep(task)++;
04074 strcpy(taskP.taskFrFunc(task),"recvBeacon");
04075 taskP.mlme_sync_request_numSearchRetry = 0;
04076 taskP.mlme_sync_request_tracking = TrackBeacon;
04077
04078 tmp_ppib.phyCurrentChannel = LogicalChannel;
04079 phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
04080
04081 plme_set_trx_state_request(p_RX_ON);
04082 BO = (macBeaconOrder2 == 15)?14:macBeaconOrder2;
04083 if (bcnSearchT->busy())
04084 bcnSearchT->stop();
04085 bcnSearchT->start(aBaseSuperframeDuration*((1 << BO)+1) / phy->getRate('s'));
04086 break;
04087 case 1:
04088 if (status == p_SUCCESS)
04089 {
04090
04091 taskP.taskStatus(task) = false;
04092
04093 if (TrackBeacon)
04094 {
04095
04096 taskP.mlme_sync_request_numSearchRetry = 0;
04097 if(!bcnRxT->busy())
04098 bcnRxT->start();
04099 }
04100 csmacaResume();
04101 }
04102 else
04103 {
04104 taskP.mlme_sync_request_numSearchRetry++;
04105 if (taskP.mlme_sync_request_numSearchRetry <= aMaxLostBeacons)
04106 {
04107 plme_set_trx_state_request(p_RX_ON);
04108 BO = (macBeaconOrder2 == 15)?14:macBeaconOrder2;
04109 bcnSearchT->start(aBaseSuperframeDuration*((1 << BO)+1) / phy->getRate('s'));
04110 }
04111 else
04112 {
04113 taskP.taskStatus(task) = false;
04114 changeNodeColor(CURRENT_TIME,Nam802_15_4::def_Node_clr);
04115 sscs->MLME_SYNC_LOSS_indication(m_BEACON_LOSS);
04116
04117
04118
04119
04120 taskP.mlme_sync_request_tracking = false;
04121 csmacaResume();
04122 return;
04123 }
04124 }
04125 break;
04126 default:
04127 break;
04128 }
04129 }
04130
04131 void Mac802_15_4::mlme_poll_request(UINT_8 CoordAddrMode,UINT_16 CoordPANId,IE3ADDR CoordAddress,bool SecurityEnable,
04132 bool autoRequest,bool firstTime,PHYenum status)
04133 {
04134 UINT_8 step,task;
04135 FrameCtrl frmCtrl;
04136 hdr_lrwpan* wph;
04137
04138 task = TP_mlme_poll_request;
04139 if (firstTime)
04140 {
04141 if (taskP.taskStatus(task))
04142 return;
04143 else
04144 {
04145 taskP.taskStep(task) = 0;
04146 (taskP.taskFrFunc(task))[0] = 0;
04147 }
04148 }
04149
04150 step = taskP.taskStep(task);
04151 switch(step)
04152 {
04153 case 0:
04154
04155 if (((CoordAddrMode != defFrmCtrl_AddrMode16)&&(CoordAddrMode != defFrmCtrl_AddrMode64))
04156 || (CoordPANId == 0xffff))
04157 {
04158 if (!autoRequest)
04159 sscs->MLME_POLL_confirm(m_INVALID_PARAMETER);
04160 return;
04161 }
04162 taskP.taskStatus(task) = true;
04163 taskP.taskStep(task)++;
04164 strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
04165 taskP.mlme_poll_request_CoordAddrMode = CoordAddrMode;
04166 taskP.mlme_poll_request_CoordPANId = CoordPANId;
04167 taskP.mlme_poll_request_CoordAddress = CoordAddress;
04168 taskP.mlme_poll_request_SecurityEnable = SecurityEnable;
04169 taskP.mlme_poll_request_autoRequest = autoRequest;
04170
04171 #ifdef DEBUG802_15_4
04172 fprintf(stdout,"[%s::%s][%f](node %d) before alloc txBcnCmd2:\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);
04173 #endif
04174 assert(!txBcnCmd2);
04175 txBcnCmd2 = Packet::alloc();
04176 assert(txBcnCmd2);
04177 wph = HDR_LRWPAN(txBcnCmd2);
04178 if ((mpib.macShortAddress == 0xfffe)||(mpib.macShortAddress == 0xffff))
04179 {
04180 frmCtrl.setSrcAddrMode(defFrmCtrl_AddrMode64);
04181 wph->MHR_SrcAddrInfo.addr_64 = aExtendedAddress;
04182 }
04183 else
04184 {
04185 frmCtrl.setSrcAddrMode(defFrmCtrl_AddrMode16);
04186 wph->MHR_SrcAddrInfo.addr_16 = mpib.macShortAddress;
04187 }
04188 if (sfSpec2.PANCoor)
04189 frmCtrl.setDstAddrMode(defFrmCtrl_AddrModeNone);
04190 else
04191 frmCtrl.setDstAddrMode(CoordAddrMode);
04192 constructCommandHeader(txBcnCmd2,&frmCtrl,0x04,frmCtrl.dstAddrMode,CoordPANId,CoordAddress,frmCtrl.srcAddrMode,mpib.macPANId,wph->MHR_SrcAddrInfo.addr_64,SecurityEnable,false,true);
04193 constructMPDU(1,txBcnCmd2,frmCtrl.FrmCtrl,mpib.macDSN++,wph->MHR_DstAddrInfo,wph->MHR_SrcAddrInfo,0,0x04,0);
04194 csmacaBegin('C');
04195
04196 break;
04197 case 1:
04198 if (status == p_IDLE)
04199 {
04200 taskP.taskStep(task)++;
04201 strcpy(taskP.taskFrFunc(task),"PD_DATA_confirm");
04202 plme_set_trx_state_request(p_TX_ON);
04203 break;
04204 }
04205 else
04206 {
04207 taskP.taskStatus(task) = false;
04208 if (!autoRequest)
04209 sscs->MLME_POLL_confirm(m_CHANNEL_ACCESS_FAILURE);
04210 resetTRX();
04211 taskFailed('C',m_CHANNEL_ACCESS_FAILURE);
04212 return;
04213 }
04214 break;
04215 case 2:
04216 taskP.taskStep(task)++;
04217 strcpy(taskP.taskFrFunc(task),"recvAck");
04218
04219 plme_set_trx_state_request(p_RX_ON);
04220 txT->start(mpib.macAckWaitDuration/phy->getRate('s'));
04221 waitBcnCmdAck2 = true;
04222 break;
04223 case 3:
04224 if (status == p_SUCCESS)
04225 {
04226 if (!taskP.mlme_poll_request_pending)
04227 {
04228 taskP.taskStatus(task) = false;
04229 if (!autoRequest)
04230 sscs->MLME_POLL_confirm(m_NO_DATA);
04231 resetTRX();
04232 taskSuccess('C');
04233 return;
04234 }
04235 else
04236 {
04237 taskP.taskStep(task)++;
04238 strcpy(taskP.taskFrFunc(task),"IFSHandler");
04239 plme_set_trx_state_request(p_RX_ON);
04240 taskSuccess('C',false);
04241 extractT->start(aMaxFrameResponseTime/phy->getRate('s'),true);
04242 }
04243 }
04244 else
04245 {
04246 numBcnCmdRetry2++;
04247 if (numBcnCmdRetry2 <= aMaxFrameRetries)
04248 {
04249 taskP.taskStep(task) = 1;
04250 strcpy(taskP.taskFrFunc(task),"csmacaCallBack");
04251 waitBcnCmdAck2 = false;
04252 csmacaResume();
04253 }
04254 else
04255 {
04256 taskP.taskStatus(task) = false;
04257 if (!autoRequest)
04258 sscs->MLME_POLL_confirm(m_NO_ACK);
04259 resetTRX();
04260 taskFailed('C',m_NO_ACK);
04261 return;
04262 }
04263 }
04264 break;
04265 case 4:
04266 taskP.taskStatus(task) = false;
04267 if (status == p_SUCCESS)
04268 {
04269
04270 extractT->stop();
04271 if (!autoRequest)
04272 sscs->MLME_POLL_confirm(m_SUCCESS);
04273
04274
04275
04276 mlme_poll_request(CoordAddrMode,CoordPANId,CoordAddress,SecurityEnable,autoRequest,true);
04277 }
04278 else
04279 {
04280 if (!autoRequest)
04281 sscs->MLME_POLL_confirm(m_NO_DATA);
04282 resetTRX();
04283 csmacaResume();
04284 }
04285 break;
04286 default:
04287 break;
04288 }
04289 }
04290
04291
04292
04293 void Mac802_15_4::csmacaBegin(char pktType)
04294 {
04295 if (pktType == 'c')
04296 {
04297 waitBcnCmdAck = false;
04298 numBcnCmdRetry = 0;
04299 if (backoffStatus == 99)
04300 {
04301 backoffStatus = 0;
04302 csmaca->cancel();
04303 }
04304 csmacaResume();
04305 }
04306 else if (pktType == 'C')
04307 {
04308 waitBcnCmdAck2 = false;
04309 numBcnCmdRetry2 = 0;
04310 if ((backoffStatus == 99)&&(txCsmaca != txBcnCmd))
04311 {
04312 backoffStatus = 0;
04313 csmaca->cancel();
04314 }
04315 csmacaResume();
04316
04317 }
04318 else
04319 {
04320 waitDataAck = false;
04321 numDataRetry = 0;
04322 csmacaResume();
04323 }
04324 }
04325
04326 void Mac802_15_4::csmacaResume(void)
04327 {
04328 FrameCtrl frmCtrl;
04329
04330 if ((backoffStatus != 99)
04331 && (!inTransmission))
04332 if ((txBcnCmd)&&(!waitBcnCmdAck))
04333 {
04334 backoffStatus = 99;
04335 frmCtrl.FrmCtrl = HDR_LRWPAN(txBcnCmd)->MHR_FrmCtrl;
04336 frmCtrl.parse();
04337 txCsmaca = txBcnCmd;
04338 csmaca->start(true,txBcnCmd,frmCtrl.ackReq);
04339 }
04340 else if ((txBcnCmd2)&&(!waitBcnCmdAck2))
04341 {
04342 backoffStatus = 99;
04343 frmCtrl.FrmCtrl = HDR_LRWPAN(txBcnCmd2)->MHR_FrmCtrl;
04344 frmCtrl.parse();
04345 txCsmaca = txBcnCmd2;
04346 csmaca->start(true,txBcnCmd2,frmCtrl.ackReq);
04347 }
04348 else if ((txData)&&(!waitDataAck))
04349 {
04350 strcpy(taskP.taskFrFunc(TP_mcps_data_request),"csmacaCallBack");
04351 taskP.taskStep(TP_mcps_data_request) = 1;
04352 backoffStatus = 99;
04353 frmCtrl.FrmCtrl = HDR_LRWPAN(txData)->MHR_FrmCtrl;
04354 frmCtrl.parse();
04355 txCsmaca = txData;
04356 csmaca->start(true,txData,frmCtrl.ackReq);
04357 }
04358 }
04359
04360 void Mac802_15_4::csmacaCallBack(PHYenum status)
04361 {
04362 if (((!txBcnCmd)||(waitBcnCmdAck))
04363 &&((!txBcnCmd2)||(waitBcnCmdAck2))
04364 &&((!txData)||(waitDataAck)))
04365 return;
04366
04367 backoffStatus = (status == p_IDLE)?1:2;
04368
04369 #ifdef DEBUG802_15_4
04370 hdr_cmn *ch = HDR_CMN(txCsmaca);
04371 if (status != p_IDLE)
04372 fprintf(stdout,"[%s::%s][%f](node %d) backoff failed: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,wpan_pName(txCsmaca),p802_15_4macSA(txCsmaca),p802_15_4macDA(txCsmaca),ch->uid(),HDR_LRWPAN(txCsmaca)->uid,ch->size());
04373 #endif
04374
04375 dispatch(status,__FUNCTION__);
04376 }
04377
04378 int Mac802_15_4::getBattLifeExtSlotNum(void)
04379 {
04380 phy->PLME_GET_request(phyCurrentChannel);
04381 return (tmp_ppib.phyCurrentChannel<=10)?8:6;
04382 }
04383
04384 double Mac802_15_4::getCAP(bool small)
04385 {
04386 double bcnTxTime,bcnRxTime,bcnOtherRxTime,bPeriod;
04387 double sSlotDuration,sSlotDuration2,sSlotDuration3,BI2,BI3,t_CAP,t_CAP2,t_CAP3;
04388 double now,oneDay,tmpf;
04389
04390 now = CURRENT_TIME;
04391 oneDay = now + 24.0*3600;
04392
04393 if ((mpib.macBeaconOrder == 15)&&(macBeaconOrder2 == 15)
04394 &&(macBeaconOrder3 == 15))
04395 return oneDay;
04396
04397 bcnTxTime = macBcnTxTime / phy->getRate('s');
04398 bcnRxTime = macBcnRxTime / phy->getRate('s');
04399 bcnOtherRxTime = macBcnOtherRxTime / phy->getRate('s');
04400 bPeriod = aUnitBackoffPeriod / phy->getRate('s');
04401 sSlotDuration = sfSpec.sd / phy->getRate('s');
04402 sSlotDuration2 = sfSpec2.sd / phy->getRate('s');
04403 sSlotDuration3 = sfSpec3.sd / phy->getRate('s');
04404 BI2 = (sfSpec2.BI / phy->getRate('s'));
04405 BI3 = (sfSpec3.BI / phy->getRate('s'));
04406 if (mpib.macBeaconOrder != 15)
04407 {
04408 if (sfSpec.BLE)
04409 {
04410
04411
04412
04413 {
04414 tmpf = (beaconPeriods + getBattLifeExtSlotNum()) * aUnitBackoffPeriod;
04415 t_CAP = bcnTxTime + tmpf;
04416 }
04417 }
04418 else
04419 {
04420
04421
04422
04423 {
04424 tmpf = (sfSpec.FinCAP + 1) * sSlotDuration;
04425 t_CAP = bcnTxTime + tmpf;
04426 }
04427 }
04428 }
04429 if (macBeaconOrder2 != 15)
04430 {
04431 if (sfSpec2.BLE)
04432 {
04433
04434
04435
04436 {
04437 tmpf = (beaconPeriods2 + getBattLifeExtSlotNum()) * aUnitBackoffPeriod;
04438 t_CAP2 = bcnRxTime + tmpf;
04439 }
04440 }
04441 else
04442 {
04443
04444
04445
04446 {
04447 tmpf = (sfSpec2.FinCAP + 1) * sSlotDuration2;
04448 t_CAP2 = bcnRxTime + tmpf;
04449 }
04450 }
04451
04452
04453
04454
04455 tmpf = aMaxLostBeacons * BI2;
04456 if ((t_CAP2 < now)&&(t_CAP2 + tmpf >= now))
04457 while (t_CAP2 < now)
04458 t_CAP2 += BI2;
04459 }
04460 if (macBeaconOrder3 != 15)
04461 {
04462
04463
04464
04465
04466 {
04467 tmpf = (sfSpec3.FinCAP + 1) * sSlotDuration3;
04468 t_CAP3 = bcnOtherRxTime + tmpf;
04469 }
04470
04471
04472
04473
04474 tmpf = aMaxLostBeacons * BI3;
04475 if ((t_CAP3 < now)&&(t_CAP3 + tmpf >= now))
04476 while (t_CAP3 < now)
04477 t_CAP3 += BI3;
04478 }
04479
04480 if ((mpib.macBeaconOrder == 15)&&(macBeaconOrder2 == 15))
04481 {
04482 if (t_CAP3 >= now)
04483 return t_CAP3;
04484 else
04485 return oneDay;
04486 }
04487 else if (mpib.macBeaconOrder == 15)
04488 {
04489 if (t_CAP2 >= now)
04490 return t_CAP2;
04491 else
04492 return oneDay;
04493 }
04494 else if (macBeaconOrder2 == 15)
04495 {
04496 if (t_CAP >= now)
04497 return t_CAP;
04498 else
04499 return oneDay;
04500 }
04501 else
04502 {
04503 if (t_CAP2 < now)
04504 return t_CAP;
04505
04506 if ((small)
04507 && (t_CAP > t_CAP2))
04508 t_CAP = t_CAP2;
04509 if ((!small)
04510 && (t_CAP < t_CAP2))
04511 t_CAP = t_CAP2;
04512
04513 return t_CAP;
04514 }
04515 }
04516
04517 double Mac802_15_4::getCAPbyType(int type)
04518 {
04519 double bcnTxTime,bcnRxTime,bcnOtherRxTime,bPeriod;
04520 double sSlotDuration,sSlotDuration2,sSlotDuration3,BI2,BI3,t_CAP,t_CAP2,t_CAP3;
04521 double now,oneDay,tmpf;
04522
04523 now = CURRENT_TIME;
04524 oneDay = now + 24.0*3600;
04525
04526 if ((mpib.macBeaconOrder == 15)&&(macBeaconOrder2 == 15)
04527 &&(macBeaconOrder3 == 15))
04528 return oneDay;
04529
04530 bcnTxTime = macBcnTxTime / phy->getRate('s');
04531 bcnRxTime = macBcnRxTime / phy->getRate('s');
04532 bcnOtherRxTime = macBcnOtherRxTime / phy->getRate('s');
04533 bPeriod = aUnitBackoffPeriod / phy->getRate('s');
04534 sSlotDuration = sfSpec.sd / phy->getRate('s');
04535 sSlotDuration2 = sfSpec2.sd / phy->getRate('s');
04536 sSlotDuration3 = sfSpec3.sd / phy->getRate('s');
04537 BI2 = (sfSpec2.BI / phy->getRate('s'));
04538 BI3 = (sfSpec3.BI / phy->getRate('s'));
04539
04540 if (type == 1)
04541 if (mpib.macBeaconOrder != 15)
04542 {
04543 if (sfSpec.BLE)
04544 {
04545
04546
04547
04548 {
04549 tmpf = (beaconPeriods + getBattLifeExtSlotNum()) * aUnitBackoffPeriod;
04550 t_CAP = bcnTxTime + tmpf;
04551 }
04552 }
04553 else
04554 {
04555
04556
04557
04558 {
04559 tmpf = (sfSpec.FinCAP + 1) * sSlotDuration;
04560 t_CAP = bcnTxTime + tmpf;
04561 }
04562 }
04563 return (t_CAP>=now)?t_CAP:oneDay;
04564 }
04565 else
04566 return oneDay;
04567
04568 if (type == 2)
04569 if (macBeaconOrder2 != 15)
04570 {
04571 if (sfSpec2.BLE)
04572 {
04573
04574
04575
04576 {
04577 tmpf = (beaconPeriods2 + getBattLifeExtSlotNum()) * aUnitBackoffPeriod;
04578 t_CAP2 = bcnRxTime + tmpf;
04579 }
04580 }
04581 else
04582 {
04583
04584
04585
04586 {
04587 tmpf = (sfSpec2.FinCAP + 1) * sSlotDuration2;
04588 t_CAP2 = bcnRxTime + tmpf;
04589 }
04590 }
04591
04592
04593
04594
04595 tmpf = aMaxLostBeacons * BI2;
04596 if ((t_CAP2 < now)&&(t_CAP2 + tmpf >= now))
04597 while (t_CAP2 < now)
04598 t_CAP2 += BI2;
04599 return (t_CAP2>=now)?t_CAP2:oneDay;
04600 }
04601 else
04602 return oneDay;
04603
04604 if (type == 3)
04605 if (macBeaconOrder3 != 15)
04606 {
04607
04608
04609
04610
04611 {
04612 tmpf = (sfSpec3.FinCAP + 1) * sSlotDuration3;
04613 t_CAP3 = bcnOtherRxTime + tmpf;
04614 }
04615
04616
04617
04618
04619 tmpf = aMaxLostBeacons * BI3;
04620 if ((t_CAP3 < now)&&(t_CAP3 + tmpf >= now))
04621 while (t_CAP3 < now)
04622 t_CAP3 += BI3;
04623 return (t_CAP3>=now)?t_CAP3:oneDay;
04624 }
04625 else
04626 return oneDay;
04627
04628 return oneDay;
04629 }
04630
04631 bool Mac802_15_4::canProceedWOcsmaca(Packet *p)
04632 {
04633
04634
04635 double wtime,t_IFS,t_transacTime,t_CAP,tmpf;
04636 FrameCtrl frmCtrl;
04637
04638
04639 if ((mpib.macBeaconOrder == 15)&&(macBeaconOrder2 == 15)
04640 &&(macBeaconOrder3 == 15))
04641 return true;
04642 else
04643 {
04644 frmCtrl.FrmCtrl = HDR_LRWPAN(p)->MHR_FrmCtrl;
04645 frmCtrl.parse();
04646 wtime = 0.0;
04647
04648
04649 if (HDR_CMN(p)->size() <= aMaxSIFSFrameSize)
04650 t_IFS = aMinSIFSPeriod;
04651 else
04652 t_IFS = aMinLIFSPeriod;
04653 t_IFS /= phy->getRate('s');
04654 t_transacTime = locateBoundary(toParent(p),wtime) - wtime;
04655 t_transacTime += phy->trxTime(p);
04656 if (frmCtrl.ackReq)
04657 {
04658 t_transacTime += mpib.macAckWaitDuration/phy->getRate('s');
04659 t_transacTime += 2*max_pDelay;
04660 t_transacTime += t_IFS;
04661 t_CAP = getCAP(true);
04662
04663
04664
04665
04666 tmpf = CURRENT_TIME + wtime;
04667 tmpf += t_transacTime;
04668 if (tmpf > t_CAP)
04669 return false;
04670 else
04671 return true;
04672 }
04673 else
04674 {
04675
04676 t_CAP = getCAPbyType(1);
04677
04678
04679
04680
04681 tmpf = CURRENT_TIME + wtime;
04682 tmpf += t_transacTime;
04683 if (tmpf > t_CAP)
04684 return false;
04685 t_CAP = getCAPbyType(2);
04686 t_transacTime += max_pDelay;
04687 t_transacTime += 12/phy->getRate('s');
04688 t_transacTime += t_IFS;
04689
04690
04691
04692
04693 tmpf = CURRENT_TIME + wtime;
04694 tmpf += t_transacTime;
04695 if (tmpf > t_CAP)
04696 return false;
04697 t_CAP = getCAPbyType(3);
04698 t_transacTime -= t_IFS;
04699
04700
04701
04702
04703 tmpf = CURRENT_TIME + wtime;
04704 tmpf += t_transacTime;
04705 if (tmpf > t_CAP)
04706 return false;
04707
04708 return true;
04709 }
04710 }
04711 }
04712
04713 void Mac802_15_4::transmitCmdData(void)
04714 {
04715 double delay;
04716
04717 if ((mpib.macBeaconOrder != 15)||(macBeaconOrder2 != 15))
04718 {
04719 delay =locateBoundary(toParent(txCsmaca),0.0);
04720 if(delay > 0.0)
04721 {
04722 Scheduler::instance().schedule(&txCmdDataH, &(txCmdDataH.nullEvent), delay);
04723 return;
04724 }
04725 }
04726
04727
04728 txBcnCmdDataHandler();
04729 }
04730
04731 void Mac802_15_4::reset_TRX(const char *frFile,const char *frFunc,int line)
04732 {
04733 double t_CAP;
04734 PHYenum t_state;
04735
04736 if ((mpib.macBeaconOrder != 15)||(macBeaconOrder2 != 15))
04737 {
04738
04739 t_CAP = getCAP(false);
04740 if (CURRENT_TIME < t_CAP)
04741 t_state = mpib.macRxOnWhenIdle?p_RX_ON:p_TRX_OFF;
04742 else
04743 t_state = p_RX_ON;
04744 }
04745 else
04746 t_state = mpib.macRxOnWhenIdle?p_RX_ON:p_TRX_OFF;
04747
04748 set_trx_state_request(t_state,frFile,frFunc,line);
04749 }
04750
04751 void Mac802_15_4::taskSuccess(char task,bool csmacaRes)
04752 {
04753 hdr_cmn* ch;
04754 hdr_lrwpan* wph;
04755 UINT_16 t_CAP;
04756 UINT_8 ifs;
04757 double tmpf;
04758
04759 #ifdef DEBUG802_15_4
04760 fprintf(stdout,"[%s::%s][%f](node %d) task '%c' successful:\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_,task,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
04761 #endif
04762
04763 if (task == 'b')
04764 {
04765 if (!txBeacon)
04766 {
04767 assert(txBcnCmd2);
04768 txBeacon = txBcnCmd2;
04769 txBcnCmd2 = 0;
04770 }
04771
04772 sfSpec.parse();
04773 if (HDR_CMN(txBeacon)->size() <= aMaxSIFSFrameSize)
04774 ifs = aMinSIFSPeriod;
04775 else
04776 ifs = aMinLIFSPeriod;
04777
04778
04779
04780
04781 {
04782 tmpf = phy->trxTime(txBeacon) * phy->getRate('s');
04783 tmpf += ifs;
04784 beaconPeriods = (UINT_8)(tmpf / aUnitBackoffPeriod);
04785 }
04786
04787
04788
04789
04790 tmpf = phy->trxTime(txBeacon) * phy->getRate('s');
04791 tmpf += ifs;
04792 if (fmod(tmpf,aUnitBackoffPeriod) > 0.0)
04793 beaconPeriods++;
04794
04795 t_CAP = (sfSpec.FinCAP + 1) * (sfSpec.sd / aUnitBackoffPeriod) - beaconPeriods;
04796
04797 if (t_CAP == 0)
04798 {
04799 csmacaRes = false;
04800 plme_set_trx_state_request(p_TRX_OFF);
04801 }
04802 else
04803 plme_set_trx_state_request(p_RX_ON);
04804
04805 if (backoffStatus == 99)
04806 csmaca->newBeacon('t');
04807
04808 beaconWaiting = false;
04809 Packet::free(txBeacon);
04810 txBeacon = 0;
04811
04812
04813
04814
04815
04816
04817
04818
04819 }
04820 else if (task == 'a')
04821 {
04822 assert(txAck);
04823 Packet::free(txAck);
04824 txAck = 0;
04825 }
04826 else if (task == 'c')
04827 {
04828 assert(txBcnCmd);
04829
04830 updateTransacLinkByPktOrHandle(tr_oper_del,&transacLink1,&transacLink2,txBcnCmd);
04831 freePkt(txBcnCmd);
04832 txBcnCmd = 0;
04833 }
04834 else if (task == 'C')
04835 {
04836 assert(txBcnCmd2);
04837 freePkt(txBcnCmd2);
04838 txBcnCmd2 = 0;
04839 }
04840 else if (task == 'd')
04841 {
04842 assert(txData);
04843
04844 ch = HDR_CMN(txData);
04845 wph = HDR_LRWPAN(txData);
04846
04847 Packet *p = txData;
04848 txData = 0;
04849 if (ch->ptype() == PT_MAC)
04850 {
04851 assert(wph->msduHandle);
04852 sscs->MCPS_DATA_confirm(wph->msduHandle,m_SUCCESS);
04853 }
04854 else
04855 {
04856 if (Mac802_15_4::callBack == 2)
04857 if (ch->xmit_failure_)
04858 if (p802_15_4macDA(p) != (nsaddr_t)MAC_BROADCAST)
04859 {
04860 ch->size() -= macHeaderLen(wph->MHR_FrmCtrl);
04861 ch->xmit_reason_ = 1;
04862 ch->xmit_failure_(p->refcopy(),ch->xmit_failure_data_);
04863 }
04864 if (callback_)
04865 {
04866 Handler *h = callback_;
04867 callback_ = 0;
04868 h->handle((Event*) 0);
04869 }
04870 }
04871
04872 updateTransacLinkByPktOrHandle(tr_oper_del,&transacLink1,&transacLink2,p);
04873 freePkt(p);
04874 }
04875 else
04876 assert(0);
04877
04878 if (csmacaRes)
04879 csmacaResume();
04880 }
04881
04882 void Mac802_15_4::taskFailed(char task,MACenum status,bool csmacaRes)
04883 {
04884 hdr_cmn* ch;
04885 hdr_lrwpan* wph;
04886
04887 #ifdef DEBUG802_15_4
04888 fprintf(stdout,"[D][FAIL][%s::%s][%f](node %d) task '%c' failed:\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_,task,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
04889 #endif
04890
04891 if ((task == 'b')
04892 || (task == 'a')
04893 || (task == 'c'))
04894 {
04895 assert(0);
04896 }
04897 else if (task == 'C')
04898 {
04899 freePkt(txBcnCmd2);
04900 txBcnCmd2 = 0;
04901 }
04902 else if (task == 'd')
04903 {
04904 wph = HDR_LRWPAN(txData);
04905 ch = HDR_CMN(txData);
04906 #ifdef DEBUG802_15_4
04907 fprintf(stdout,"[D][FAIL][%s::%s::%d][%f](node %d) failure: type = %s, src = %d, dst = %d, uid = %d, mac_uid = %ld, size = %d\n",__FILE__,__FUNCTION__,__LINE__,CURRENT_TIME,index_,wpan_pName(txData),p802_15_4macSA(txData),p802_15_4macDA(txData),ch->uid(),wph->uid,ch->size());
04908 #endif
04909 Packet *p = txData;
04910 txData = 0;
04911 if (wph->msduHandle)
04912 sscs->MCPS_DATA_confirm(wph->msduHandle,status);
04913 else
04914 {
04915 if (Mac802_15_4::callBack)
04916 if (ch->xmit_failure_)
04917 {
04918 wph->setSN = true;
04919 ch->size() -= macHeaderLen(wph->MHR_FrmCtrl);
04920 ch->xmit_reason_ = 0;
04921 ch->xmit_failure_(p->refcopy(),ch->xmit_failure_data_);
04922 }
04923 if (callback_
04924 && (!dataWaitT->busy()))
04925 {
04926 Handler *h = callback_;
04927 callback_ = 0;
04928 h->handle((Event*) 0);
04929 }
04930 }
04931 freePkt(p);
04932 }
04933 else
04934 assert(0);
04935
04936 if (csmacaRes)
04937 csmacaResume();
04938 }
04939
04940 void Mac802_15_4::freePkt(Packet *pkt)
04941 {
04942
04943
04944
04945
04946
04947
04948 Packet::free(pkt);
04949 }
04950
04951 UINT_8 Mac802_15_4::macHeaderLen(UINT_16 FrmCtrl)
04952 {
04953
04954 UINT_8 macHLen;
04955 FrameCtrl frmCtrl;
04956
04957 frmCtrl.FrmCtrl = FrmCtrl;
04958 frmCtrl.parse();
04959
04960 macHLen = 0;
04961 macHLen += 2
04962 +1
04963 +2;
04964 if (frmCtrl.frmType == defFrmCtrl_Type_Beacon)
04965 {
04966 if (frmCtrl.srcAddrMode == defFrmCtrl_AddrMode16)
04967 macHLen += 2;
04968 else if (frmCtrl.srcAddrMode == defFrmCtrl_AddrMode64)
04969 macHLen += 8;
04970 }
04971 else if ((frmCtrl.frmType == defFrmCtrl_Type_Data)
04972 ||(frmCtrl.frmType == defFrmCtrl_Type_MacCmd))
04973 {
04974 if (frmCtrl.dstAddrMode == defFrmCtrl_AddrMode16)
04975 macHLen += 2;
04976 else if (frmCtrl.dstAddrMode == defFrmCtrl_AddrMode64)
04977 macHLen += 8;
04978 if (frmCtrl.srcAddrMode == defFrmCtrl_AddrMode16)
04979 macHLen += 2;
04980 else if (frmCtrl.srcAddrMode == defFrmCtrl_AddrMode64)
04981 macHLen += 8;
04982 }
04983 else if (frmCtrl.frmType == defFrmCtrl_Type_Ack)
04984 {
04985 ;
04986 }
04987 else
04988 fprintf(stdout,"[%s][%f](node %d) Invalid frame type!\n",__FUNCTION__,CURRENT_TIME,index_);
04989
04990 return macHLen;
04991 }
04992
04993 void Mac802_15_4::constructACK(Packet *p)
04994 {
04995 bool intraPan;
04996 UINT_8 origFrmType;
04997 FrameCtrl frmCtrl;
04998 Packet *ack = Packet::alloc();
04999 hdr_lrwpan* wph1 = HDR_LRWPAN(p);
05000 hdr_lrwpan* wph2 = HDR_LRWPAN(ack);
05001 hdr_cmn* ch1 = HDR_CMN(p);
05002 hdr_cmn* ch2 = HDR_CMN(ack);
05003 int i;
05004
05005 hdr_dst((char *)HDR_MAC(ack),p802_15_4macSA(p));
05006 hdr_src((char *)HDR_MAC(ack),index_);
05007 frmCtrl.FrmCtrl = wph1->MHR_FrmCtrl;
05008 frmCtrl.parse();
05009 intraPan = frmCtrl.intraPan;
05010 origFrmType = frmCtrl.frmType;
05011 frmCtrl.FrmCtrl = 0;
05012 frmCtrl.setFrmType(defFrmCtrl_Type_Ack);
05013 frmCtrl.setSecu(false);
05014
05015
05016
05017
05018
05019
05020 if ((origFrmType == defFrmCtrl_Type_MacCmd)
05021 && (wph1->MSDU_CmdType == 0x04))
05022 {
05023 i = updateTransacLink(tr_oper_est,&transacLink1,&transacLink2,frmCtrl.srcAddrMode,wph1->MHR_SrcAddrInfo.addr_64);
05024 frmCtrl.setFrmPending(i==0);
05025 }
05026 else
05027 frmCtrl.setFrmPending(false);
05028 frmCtrl.setAckReq(false);
05029 frmCtrl.setIntraPan(intraPan);
05030 frmCtrl.setDstAddrMode(defFrmCtrl_AddrModeNone);
05031 frmCtrl.setSrcAddrMode(defFrmCtrl_AddrModeNone);
05032 wph2->MHR_FrmCtrl = frmCtrl.FrmCtrl;
05033 wph2->MHR_BDSN = wph1->MHR_BDSN;
05034 wph2->uid = wph1->uid;
05035
05036
05037 ch2->uid() = 0;
05038 ch2->ptype() = PT_MAC;
05039 ch2->iface() = -2;
05040 ch2->error() = 0;
05041 ch2->size() = 5;
05042 ch2->uid() = ch1->uid();
05043
05044 ch2->next_hop_ = p802_15_4macDA(ack);
05045 p802_15_4hdrACK(ack);
05046
05047 #ifdef DEBUG802_15_4
05048 fprintf(stdout,"[%s::%s][%f](node %d) before alloc txAck:\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);
05049 #endif
05050 assert(!txAck);
05051
05052 txAck = ack;
05053 }
05054
05055 void Mac802_15_4::constructMPDU(UINT_8 msduLength,Packet *msdu, UINT_16 FrmCtrl,UINT_8 BDSN,panAddrInfo DstAddrInfo,
05056 panAddrInfo SrcAddrInfo,UINT_16 SuperSpec,UINT_8 CmdType,UINT_16 FCS)
05057 {
05058 hdr_lrwpan* wph = HDR_LRWPAN(msdu);
05059 hdr_cmn* ch = HDR_CMN(msdu);
05060
05061
05062
05063 wph->MHR_FrmCtrl = FrmCtrl;
05064 if (!wph->setSN)
05065 wph->MHR_BDSN = BDSN;
05066 else
05067 wph->setSN = false;
05068 if (!wph->uid)
05069 wph->uid = Mac802_15_4::DBG_UID++;
05070 wph->MHR_DstAddrInfo = DstAddrInfo;
05071 wph->MHR_SrcAddrInfo = SrcAddrInfo;
05072 wph->MSDU_SuperSpec = SuperSpec;
05073 wph->MSDU_CmdType = CmdType;
05074 wph->MFR_FCS = FCS;
05075
05076
05077 ch->size() = msduLength + macHeaderLen(FrmCtrl);
05078 }
05079
05080 void Mac802_15_4::constructCommandHeader(Packet *p,FrameCtrl *frmCtrl,UINT_8 CmdType,
05081 UINT_8 dstAddrMode,UINT_16 dstPANId,IE3ADDR dstAddr,
05082 UINT_8 srcAddrMode,UINT_16 srcPANId,IE3ADDR srcAddr,
05083 bool secuEnable,bool pending,bool ackreq)
05084 {
05085 hdr_lrwpan *wph = HDR_LRWPAN(p);
05086
05087 frmCtrl->FrmCtrl = 0;
05088 frmCtrl->setFrmType(defFrmCtrl_Type_MacCmd);
05089 frmCtrl->setDstAddrMode(dstAddrMode);
05090 wph->MHR_DstAddrInfo.panID = dstPANId;
05091 wph->MHR_DstAddrInfo.addr_64 = dstAddr;
05092 hdr_src((char *)HDR_MAC(p),index_);
05093 if (dstAddr == 0xffff)
05094 hdr_dst((char *)HDR_MAC(p),MAC_BROADCAST);
05095 else
05096 hdr_dst((char *)HDR_MAC(p),dstAddr);
05097 frmCtrl->setSrcAddrMode(srcAddrMode);
05098 wph->MHR_SrcAddrInfo.panID = srcPANId;
05099 wph->MHR_SrcAddrInfo.addr_64 = srcAddr;
05100 frmCtrl->setSecu(secuEnable);
05101 frmCtrl->setFrmPending(pending);
05102 frmCtrl->setAckReq(ackreq);
05103
05104 HDR_CMN(p)->ptype() = PT_MAC;
05105
05106
05107 HDR_CMN(p)->next_hop_ = p802_15_4macDA(p);
05108 p802_15_4hdrCommand(p,CmdType);
05109 }
05110
05111 void Mac802_15_4::log(Packet *p)
05112 {
05113 logtarget_->recv(p, (Handler*) 0);
05114 }
05115
05116 void Mac802_15_4::resetCounter(int dst)
05117 {
05118 if (txBcnCmd)
05119 if (p802_15_4macDA(txBcnCmd) == dst)
05120 numBcnCmdRetry = 0;
05121
05122 if (txBcnCmd2)
05123 if (p802_15_4macDA(txBcnCmd2) == dst)
05124 numBcnCmdRetry2 = 0;
05125
05126 if (txData)
05127 if (p802_15_4macDA(txData) == dst)
05128 numDataRetry = 0;
05129 }
05130
05131 int Mac802_15_4::command(int argc, const char*const* argv)
05132 {
05133 if (argc == 3)
05134 {
05135 if (strcmp(argv[1], "log-target") == 0)
05136 {
05137 logtarget_ = (NsObject*) TclObject::lookup(argv[2]);
05138 if(logtarget_ == 0)
05139 return TCL_ERROR;
05140 return TCL_OK;
05141 }
05142 }
05143
05144 if (strcmp(argv[1], "NodeClr") == 0)
05145 {
05146 changeNodeColor(CURRENT_TIME,argv[2]);
05147 return (TCL_OK);
05148 }
05149
05150 if (strcmp(argv[1], "NodeLabel") == 0)
05151 {
05152 char label[81];
05153 int i;
05154 strcpy(label,"\"");
05155 strcat(label,argv[2]);
05156 i = 3;
05157 while (i < argc)
05158 {
05159 if (strlen(label) + strlen(argv[i]) < 78)
05160 {
05161 strcat(label," ");
05162 strcat(label,argv[i]);
05163 }
05164 else
05165 break;
05166 i++;
05167 }
05168 strcat(label,"\"");
05169 nam->changeLabel(CURRENT_TIME,label);
05170 return (TCL_OK);
05171 }
05172
05173 if (strcmp(argv[1], "node-down") == 0)
05174 {
05175 chkAddNFailLink(index_);
05176 changeNodeColor(CURRENT_TIME,Nam802_15_4::def_NodeFail_clr);
05177 if (txAck)
05178 {
05179 Packet::free(txAck);
05180 txAck = 0;
05181 }
05182 if (txBcnCmd)
05183 {
05184 freePkt(txBcnCmd);
05185 txBcnCmd = 0;
05186 }
05187 if (txBcnCmd2)
05188 {
05189 freePkt(txBcnCmd2);
05190 txBcnCmd2 = 0;
05191 }
05192 if (txData)
05193 {
05194 freePkt(txData);
05195 txData = 0;
05196 }
05197 if (phy->rxPacket())
05198 HDR_CMN(phy->rxPacket())->error() = 1;
05199 init(true);
05200 return (TCL_OK);
05201 }
05202 if (strcmp(argv[1], "node-up") == 0)
05203 {
05204 updateNFailLink(fl_oper_del,index_);
05205 nam->changeBackNodeColor(CURRENT_TIME);
05206 init(true);
05207 if (callback_)
05208 {
05209 Handler *h = callback_;
05210 callback_ = 0;
05211 h->handle((Event*) 0);
05212 }
05213 return (TCL_OK);
05214 }
05215
05216
05217 if ((argc >= 3)&&(strcmp(argv[1],"sscs") == 0))
05218 return sscs->command(argc,argv);
05219
05220 int rt = Mac::command(argc, argv);
05221
05222
05223 if (netif_)
05224 if (phy == NULL)
05225 {
05226 phy = (Phy802_15_4 *)netif_;
05227 phy->macObj(this);
05228 csmaca = new CsmaCA802_15_4(phy,this);
05229 assert(csmaca);
05230 }
05231
05232 return rt;
05233 }
05234
05235 void Mac802_15_4::changeNodeColor(double atTime,const char *newColor,bool save)
05236 {
05237 nam->changeNodeColor(atTime,newColor,save);
05238 nam->changeNodeColor(atTime+0.030001,newColor,false);
05239 }
05240
05241 void Mac802_15_4::txBcnCmdDataHandler(void)
05242 {
05243 int i;
05244
05245 if (taskP.taskStatus(TP_mlme_scan_request))
05246 if (txBcnCmd2 != txCsmaca)
05247 return;
05248
05249 if (HDR_LRWPAN(txCsmaca)->indirect)
05250 {
05251 i = updateTransacLinkByPktOrHandle(tr_oper_est,&transacLink1,&transacLink2,txCsmaca);
05252 if (i != 0)
05253 {
05254 resetTRX();
05255 if (txBcnCmd == txCsmaca)
05256 txBcnCmd = 0;
05257 else if (txBcnCmd2 == txCsmaca)
05258 txBcnCmd2 = 0;
05259 else if (txData == txCsmaca)
05260 txData = 0;
05261
05262 csmacaResume();
05263 return;
05264 }
05265 }
05266
05267 if (txBcnCmd == txCsmaca)
05268 {
05269 #ifdef DEBUG802_15_4
05270 FrameCtrl frmCtrl;
05271 frmCtrl.FrmCtrl = HDR_LRWPAN(txBcnCmd)->MHR_FrmCtrl;
05272 frmCtrl.parse();
05273
05274
05275
05276
05277
05278
05279
05280 fprintf(stdout,"[%s::%s][%f](node %d) transmit %s to %d: SN = %d, uid = %d, mac_uid = %ld\n",__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);
05281 #endif
05282 txPkt = txBcnCmd;
05283 HDR_CMN(txBcnCmd)->direction() = hdr_cmn::DOWN;
05284 sendDown(txBcnCmd->copy(), this);
05285 }
05286 else if (txBcnCmd2 == txCsmaca)
05287 {
05288 #ifdef DEBUG802_15_4
05289 FrameCtrl frmCtrl2;
05290 frmCtrl2.FrmCtrl = HDR_LRWPAN(txBcnCmd2)->MHR_FrmCtrl;
05291 frmCtrl2.parse();
05292
05293
05294
05295
05296
05297
05298
05299 fprintf(stdout,"[%s::%s][%f](node %d) transmit %s to %d: SN = %d, uid = %d, mac_uid = %ld\n",__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);
05300 #endif
05301 txPkt = txBcnCmd2;
05302 HDR_CMN(txBcnCmd2)->direction() = hdr_cmn::DOWN;
05303 sendDown(txBcnCmd2->copy(), this);
05304 }
05305 else if (txData == txCsmaca)
05306 {
05307 #ifdef DEBUG802_15_4
05308 fprintf(stdout,"[%s::%s][%f](node %d) transmit DATA (%s) to %d: SN = %d, uid = %d, mac_uid = %ld\n",__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);
05309 #endif
05310 txPkt = txData;
05311 HDR_CMN(txData)->direction() = hdr_cmn::DOWN;
05312 sendDown(txData->copy(), this);
05313 }
05314 }
05315
05316 void Mac802_15_4::IFSHandler(void)
05317 {
05318 hdr_lrwpan* wph;
05319 hdr_cmn* ch;
05320 FrameCtrl frmCtrl;
05321 Packet *pendPkt;
05322 MACenum status;
05323 int i;
05324
05325 assert(rxData||rxCmd);
05326
05327 if (rxCmd)
05328 {
05329 wph = HDR_LRWPAN(rxCmd);
05330 frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
05331 frmCtrl.parse();
05332
05333 if (wph->MSDU_CmdType == 0x01)
05334 sscs->MLME_ASSOCIATE_indication(wph->MHR_SrcAddrInfo.addr_64,wph->MSDU_Payload[0],frmCtrl.secu,0);
05335 else if (wph->MSDU_CmdType == 0x02)
05336 {
05337 status = (*(MACenum *)(wph->MSDU_Payload + 2));
05338
05339 if (status == m_SUCCESS)
05340 mpib.macShortAddress = *((UINT_16 *)wph->MSDU_Payload);
05341 dispatch(p_SUCCESS,__FUNCTION__,p_SUCCESS,status);
05342 }
05343 else if (wph->MSDU_CmdType == 0x04)
05344 {
05345
05346
05347
05348
05349
05350
05351 i = updateTransacLink(tr_oper_EST,&transacLink1,&transacLink2,frmCtrl.srcAddrMode,wph->MHR_SrcAddrInfo.addr_64);
05352 if (i != 0)
05353 {
05354 i = updateTransacLink(tr_oper_est,&transacLink1,&transacLink2,frmCtrl.srcAddrMode,wph->MHR_SrcAddrInfo.addr_64);
05355 i = (i == 0)?1:0;
05356 }
05357 else
05358 {
05359 i = 2;
05360 }
05361 if (i > 0)
05362 {
05363 pendPkt = getPktFrTransacLink(&transacLink1,frmCtrl.srcAddrMode,wph->MHR_SrcAddrInfo.addr_64);
05364 wph = HDR_LRWPAN(pendPkt);
05365 wph->indirect = true;
05366 frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
05367 frmCtrl.parse();
05368 frmCtrl.setFrmPending(i>1);
05369 wph->MHR_FrmCtrl = frmCtrl.FrmCtrl;
05370 HDR_CMN(pendPkt)->direction() = hdr_cmn::DOWN;
05371 if (frmCtrl.frmType == defFrmCtrl_Type_MacCmd)
05372 {
05373 if (txBcnCmd == pendPkt)
05374 {
05375 Packet::free(rxCmd);
05376 rxCmd = 0;
05377 return;
05378 }
05379 #ifdef DEBUG802_15_4
05380 fprintf(stdout,"[%s::%s][%f](node %d) before assign txBcnCmd:\n\t\ttxBeacon\t= %ld\n\t\ttxAck \t= %ld\n\t\ttxBcnCmd\t= %ld\n\t\ttxBcnCmd2\t= %ld\n\t\ttxData \t= %ld\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,txBeacon,txAck,txBcnCmd,txBcnCmd2,txData);
05381 #endif
05382 assert(!txBcnCmd);
05383 txBcnCmd = pendPkt->refcopy();
05384 waitBcnCmdAck = false;
05385 numBcnCmdRetry = 0;
05386
05387 }
05388 else if (frmCtrl.frmType == defFrmCtrl_Type_Data)
05389 {
05390 if (txData == pendPkt)
05391 {
05392 Packet::free(rxCmd);
05393 rxCmd = 0;
05394 return;
05395 }
05396 #ifdef DEBUG802_15_4
05397 fprintf(stdout,"[%s::%s][%f](node %d) before assign txData:\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);
05398 #endif
05399 assert(!txData);
05400 txData = pendPkt->refcopy();
05401 waitDataAck = false;
05402 numDataRetry = 0;
05403 }
05404
05405 if (canProceedWOcsmaca(pendPkt))
05406 {
05407
05408 if(taskP.taskStatus(TP_mcps_data_request))
05409 {
05410 if (strcmp(taskP.taskFrFunc(TP_mcps_data_request),"csmacaCallBack") == 0)
05411 strcpy(taskP.taskFrFunc(TP_mcps_data_request),"PD_DATA_confirm");
05412 }
05413 else if (taskP.taskStatus(TP_mlme_associate_response))
05414 {
05415 if (strcmp(taskP.taskFrFunc(TP_mlme_associate_response),"csmacaCallBack") == 0)
05416 strcpy(taskP.taskFrFunc(TP_mlme_associate_response),"PD_DATA_confirm");
05417
05418 }
05419 txCsmaca = pendPkt;
05420 plme_set_trx_state_request(p_TX_ON);
05421 }
05422 else
05423 {
05424 csmacaResume();
05425 }
05426 }
05427
05428 }
05429 else if (wph->MSDU_CmdType == 0x08)
05430 {
05431 mpib.macPANId = *((UINT_16 *)wph->MSDU_Payload);
05432 mpib.macCoordShortAddress = *((UINT_16 *)wph->MSDU_Payload + 2);
05433 tmp_ppib.phyCurrentChannel = wph->MSDU_Payload[4];
05434 phy->PLME_SET_request(phyCurrentChannel,&tmp_ppib);
05435 mpib.macShortAddress = *((UINT_16 *)wph->MSDU_Payload + 5);
05436 dispatch(p_SUCCESS,__FUNCTION__);
05437 }
05438 Packet::free(rxCmd);
05439 rxCmd = 0;
05440 }
05441 else if (rxData)
05442 {
05443 wph = HDR_LRWPAN(rxData);
05444 ch = HDR_CMN(rxData);
05445 frmCtrl.FrmCtrl = wph->MHR_FrmCtrl;
05446 frmCtrl.parse();
05447
05448 if (taskP.taskStatus(TP_mlme_poll_request))
05449 dispatch(p_SUCCESS,__FUNCTION__,p_SUCCESS,status);
05450
05451
05452
05453
05454
05455
05456
05457 ch->size() -= macHeaderLen(wph->MHR_FrmCtrl);
05458 MCPS_DATA_indication(frmCtrl.srcAddrMode,wph->MHR_SrcAddrInfo.panID,wph->MHR_SrcAddrInfo.addr_64,
05459 frmCtrl.dstAddrMode,wph->MHR_DstAddrInfo.panID,wph->MHR_DstAddrInfo.addr_64,
05460 ch->size(),rxData,wph->ppduLinkQuality,
05461 wph->SecurityUse,wph->ACLEntry);
05462 rxData = 0;
05463 }
05464 }
05465
05466 void Mac802_15_4::backoffBoundHandler(void)
05467 {
05468 if (!beaconWaiting)
05469 if (txAck)
05470 {
05471 #ifdef DEBUG802_15_4
05472 fprintf(stdout,"[%s::%s][%f](node %d) transmit M_ACK to %d: SN = %d, uid = %d, mac_uid = %ld\n",__FILE__,__FUNCTION__,CURRENT_TIME,index_,p802_15_4macDA(txAck),HDR_LRWPAN(txAck)->MHR_BDSN,HDR_CMN(txAck)->uid(),HDR_LRWPAN(txAck)->uid);
05473 #endif
05474 txPkt = txAck;
05475 HDR_CMN(txAck)->direction() = hdr_cmn::DOWN;
05476 sendDown(txAck->refcopy(), this);
05477 }
05478 }
05479
05480