p802_15_4sscs.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:30k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /********************************************/
  2. /*     NS2 Simulator for IEEE 802.15.4      */
  3. /*           (per P802.15.4/D18)            */
  4. /*------------------------------------------*/
  5. /* by:        Jianliang Zheng               */
  6. /*        (zheng@ee.ccny.cuny.edu)          */
  7. /*              Myung J. Lee                */
  8. /*          (lee@ccny.cuny.edu)             */
  9. /*        ~~~~~~~~~~~~~~~~~~~~~~~~~         */
  10. /*           SAIT-CUNY Joint Lab            */
  11. /********************************************/
  12. // File:  p802_15_4sscs.cc
  13. // Mode:  C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t
  14. // $Header: /cvsroot/nsnam/ns-2/wpan/p802_15_4sscs.cc,v 1.2 2005/07/13 03:51:33 tomh Exp $
  15. // Functions in this file are out of the scope of 802.15.4.
  16. // But they elaborate how a higher layer interfaces with 802.15.4.
  17. // You can modify this file at will to fit your need.
  18. /*
  19.  * Copyright (c) 2003-2004 Samsung Advanced Institute of Technology and
  20.  * The City University of New York. All rights reserved.
  21.  *
  22.  * Redistribution and use in source and binary forms, with or without
  23.  * modification, are permitted provided that the following conditions
  24.  * are met:
  25.  * 1. Redistributions of source code must retain the above copyright
  26.  *    notice, this list of conditions and the following disclaimer.
  27.  * 2. Redistributions in binary form must reproduce the above copyright
  28.  *    notice, this list of conditions and the following disclaimer in the
  29.  *    documentation and/or other materials provided with the distribution.
  30.  * 3. All advertising materials mentioning features or use of this software
  31.  *    must display the following acknowledgement:
  32.  * This product includes software developed by the Joint Lab of Samsung 
  33.  *      Advanced Institute of Technology and The City University of New York.
  34.  * 4. Neither the name of Samsung Advanced Institute of Technology nor of 
  35.  *    The City University of New York may be used to endorse or promote 
  36.  *    products derived from this software without specific prior written 
  37.  *    permission.
  38.  *
  39.  * THIS SOFTWARE IS PROVIDED BY THE JOINT LAB OF SAMSUNG ADVANCED INSTITUTE
  40.  * OF TECHNOLOGY AND THE CITY UNIVERSITY OF NEW YORK ``AS IS'' AND ANY EXPRESS 
  41.  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
  42.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 
  43.  * NO EVENT SHALL SAMSUNG ADVANCED INSTITUTE OR THE CITY UNIVERSITY OF NEW YORK 
  44.  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
  45.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
  46.  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  47.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  48.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
  49.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50.  */
  51. #include "p802_15_4sscs.h"
  52. #ifdef ZigBeeIF
  53. #include "../zbr/zbr_link.h"
  54. #include "../zbr/zbr.h"
  55. #endif
  56. #define assoRetryInterval 1.0
  57. //UINT_32 SSCS802_15_4::ScanChannels = 0x07ffffff;
  58. UINT_32 SSCS802_15_4::ScanChannels = 0x00003800; //only scan the first 3 channels in 2.4G
  59. void SSCS802_15_4Timer::start(double wtime)
  60. {
  61. assert(!active);
  62. active = true;
  63. nullEvent.uid_ = 0;
  64. Scheduler::instance().schedule(this,&nullEvent,wtime);
  65. }
  66. void SSCS802_15_4Timer::cancel(void)
  67. {
  68. active = false;
  69. Scheduler::instance().cancel(&nullEvent);
  70. }
  71. void SSCS802_15_4Timer::handle(Event* e)
  72. {
  73. active = false;
  74. if (sscs->neverAsso)
  75. sscs->startDevice(sscs->t_isCT,sscs->t_isFFD,sscs->t_assoPermit,sscs->t_txBeacon,sscs->t_BO,sscs->t_SO,true);
  76. }
  77. char *statusName(MACenum status)
  78. {
  79. switch(status)
  80. {
  81. case m_SUCCESS:
  82. return "SUCCESS";
  83. case m_PAN_at_capacity:
  84. return "PAN_at_capacity";
  85. case m_PAN_access_denied:
  86. return "PAN_access_denied";
  87. case m_BEACON_LOSS:
  88. return "BEACON_LOSS";
  89. case m_CHANNEL_ACCESS_FAILURE:
  90. return "CHANNEL_ACCESS_FAILURE";
  91. case m_DENIED:
  92. return "DENIED";
  93. case m_DISABLE_TRX_FAILURE:
  94. return "DISABLE_TRX_FAILURE";
  95. case m_FAILED_SECURITY_CHECK:
  96. return "FAILED_SECURITY_CHECK";
  97. case m_FRAME_TOO_LONG:
  98. return "FRAME_TOO_LONG";
  99. case m_INVALID_GTS:
  100. return "INVALID_GTS";
  101. case m_INVALID_HANDLE:
  102. return "INVALID_HANDLE";
  103. case m_INVALID_PARAMETER:
  104. return "INVALID_PARAMETER";
  105. case m_NO_ACK:
  106. return "NO_ACK";
  107. case m_NO_BEACON:
  108. return "NO_BEACON";
  109. case m_NO_DATA:
  110. return "NO_DATA";
  111. case m_NO_SHORT_ADDRESS:
  112. return "NO_SHORT_ADDRESS";
  113. case m_OUT_OF_CAP:
  114. return "OUT_OF_CAP";
  115. case m_PAN_ID_CONFLICT:
  116. return "PAN_ID_CONFLICT";
  117. case m_REALIGNMENT:
  118. return "REALIGNMENT";
  119. case m_TRANSACTION_EXPIRED:
  120. return "TRANSACTION_EXPIRED";
  121. case m_TRANSACTION_OVERFLOW:
  122. return "TRANSACTION_OVERFLOW";
  123. case m_TX_ACTIVE:
  124. return "TX_ACTIVE";
  125. case m_UNAVAILABLE_KEY:
  126. return "UNAVAILABLE_KEY";
  127. case m_UNSUPPORTED_ATTRIBUTE:
  128. return "UNSUPPORTED_ATTRIBUTE";
  129. case m_UNDEFINED:
  130. default:
  131. return "UNDEFINED";
  132. }
  133. }
  134. SSCS802_15_4::SSCS802_15_4(Mac802_15_4 *m):assoH(this)
  135. {
  136. mac = m;
  137. neverAsso = true;
  138. #ifdef ZigBeeIF
  139. zbr = getZBRLink(mac->index_);
  140. #endif
  141. hlistLink1 = NULL;
  142. hlistLink2 = NULL;
  143. }
  144. SSCS802_15_4::~SSCS802_15_4()
  145. {
  146. }
  147. void SSCS802_15_4::MCPS_DATA_confirm(UINT_8 msduHandle,MACenum status)
  148. {
  149. }
  150. void SSCS802_15_4::MCPS_DATA_indication(UINT_8 SrcAddrMode,UINT_16 SrcPANId,IE3ADDR SrcAddr,
  151. UINT_8 DstAddrMode,UINT_16 DstPANId,IE3ADDR DstAddr,
  152. UINT_8 msduLength,Packet *msdu,UINT_8 mpduLinkQuality,
  153. bool SecurityUse,UINT_8 ACLEntry)
  154. {
  155. Packet::free(msdu);
  156. }
  157. void SSCS802_15_4::MCPS_PURGE_confirm(UINT_8 msduHandle,MACenum status)
  158. {
  159. }
  160. #ifdef ZigBeeIF
  161. extern NET_SYSTEM_CONFIG NetSystemConfig;
  162. #endif
  163. void SSCS802_15_4::MLME_ASSOCIATE_indication(IE3ADDR DeviceAddress,UINT_8 CapabilityInformation,bool SecurityUse,UINT_8 ACLEntry)
  164. {
  165. //we assign the cluster tree address as the MAC short address
  166. #ifdef ZigBeeIF
  167. if (t_isCT) //need to assign a cluster tree logic address
  168. {
  169. assertZBR();
  170. noCapacity = false;
  171. if (zbr->myDepth >= NetSystemConfig.Lm)
  172. noCapacity = true;
  173. else
  174. {
  175. child_num = 1;
  176. logAddr = zbr->myNodeID + 1;
  177. while (!updateCTAddrLink(zbr_oper_est,logAddr))
  178. {
  179. if (getIpAddrFrLogAddr(logAddr,false) == (UINT_16)DeviceAddress)
  180. break; 
  181. logAddr += ZBR::c_skip(zbr->myDepth);
  182. child_num++;
  183. if (child_num > NetSystemConfig.Cm)
  184. break;
  185. }
  186. if (child_num > NetSystemConfig.Cm)
  187. noCapacity = true;
  188. }
  189. if (noCapacity) //no capacity
  190. {
  191. #ifdef DEBUG802_15_4
  192. fprintf(stdout,"[%s::%s][%f](node %d) no capacity for cluster-tree: request from %dn",__FILE__,__FUNCTION__,CURRENT_TIME,mac->index_,DeviceAddress);
  193. #endif
  194. zbr->sscs_nb_insert((UINT_16)DeviceAddress,NEIGHBOR);
  195. mac->MLME_ASSOCIATE_response(DeviceAddress,0,m_PAN_at_capacity,false);
  196. }
  197. else
  198. {
  199. chkAddCTAddrLink(logAddr,DeviceAddress);
  200. chkAddDeviceLink(&mac->deviceLink1,&mac->deviceLink2,DeviceAddress,CapabilityInformation);
  201. zbr->sscs_nb_insert((UINT_16)DeviceAddress,CHILD);
  202. mac->MLME_ASSOCIATE_response(DeviceAddress,logAddr,m_SUCCESS,false);
  203. }
  204. }
  205. else //just assign the IP address as the MAC short address for non-cluster tree
  206. #endif
  207. {
  208. chkAddDeviceLink(&mac->deviceLink1,&mac->deviceLink2,DeviceAddress,CapabilityInformation);
  209. mac->MLME_ASSOCIATE_response(DeviceAddress,(UINT_16)DeviceAddress,m_SUCCESS,false);
  210. }
  211. }
  212. void SSCS802_15_4::MLME_ASSOCIATE_confirm(UINT_16 AssocShortAddress,MACenum status)
  213. {
  214. MAC_PIB t_mpib;
  215. if (status == m_SUCCESS)
  216. {
  217. rt_myNodeID = AssocShortAddress;
  218. /*
  219. if (!sscsTaskP.startDevice_isCluster_Tree)
  220. t_mpib.macShortAddress = AssocShortAddress;
  221. else
  222. */
  223. t_mpib.macShortAddress = mac->index_; //don't use cluster tree logic address
  224. mac->MLME_SET_request(macShortAddress,&t_mpib);
  225. }
  226. dispatch(status,"MLME_ASSOCIATE_confirm");
  227. }
  228. void SSCS802_15_4::MLME_DISASSOCIATE_confirm(MACenum status)
  229. {
  230. }
  231. void SSCS802_15_4::MLME_BEACON_NOTIFY_indication(UINT_8 BSN,PAN_ELE *PANDescriptor,UINT_8 PendAddrSpec,IE3ADDR *AddrList,UINT_8 sduLength,UINT_8 *sdu)
  232. {
  233. }
  234. void SSCS802_15_4::MLME_GET_confirm(MACenum status,MPIBAenum PIBAttribute,MAC_PIB *PIBAttributeValue)
  235. {
  236. }
  237. void SSCS802_15_4::MLME_ORPHAN_indication(IE3ADDR OrphanAddress,bool SecurityUse,UINT_8 ACLEntry)
  238. {
  239. if (updateDeviceLink(tr_oper_est,&mac->deviceLink1,&mac->deviceLink2,OrphanAddress) == 0)
  240. mac->MLME_ORPHAN_response(OrphanAddress,(UINT_16)OrphanAddress,true,false);
  241. else
  242. mac->MLME_ORPHAN_response(OrphanAddress,0,false,false);
  243. }
  244. void SSCS802_15_4::MLME_RESET_confirm(MACenum status)
  245. {
  246. }
  247. void SSCS802_15_4::MLME_RX_ENABLE_confirm(MACenum status)
  248. {
  249. }
  250. void SSCS802_15_4::MLME_SET_confirm(MACenum status,MPIBAenum PIBAttribute)
  251. {
  252. }
  253. void SSCS802_15_4::MLME_SCAN_confirm(MACenum status,UINT_8 ScanType,UINT_32 UnscannedChannels,
  254.      UINT_8 ResultListSize,UINT_8 *EnergyDetectList,
  255.      PAN_ELE *PANDescriptorList)
  256. {
  257. MAC_PIB t_mpib;
  258. T_UnscannedChannels = UnscannedChannels;
  259. T_ResultListSize = ResultListSize;
  260. T_EnergyDetectList = EnergyDetectList;
  261. T_PANDescriptorList = PANDescriptorList;
  262. if (ScanType == 0x01)
  263. dispatch(status,"MLME_SCAN_confirm");
  264. if (ScanType == 0x03)
  265. if (status == m_SUCCESS)
  266. {
  267. fprintf(stdout,"[%f](node %d) coordinator relocation successful, begin to re-synchronize with the coordinatorn",CURRENT_TIME,mac->index_);
  268. //re-synchronize with the coordinator
  269. mac->phy->PLME_GET_request(phyCurrentChannel);
  270. mac->MLME_SYNC_request(mac->tmp_ppib.phyCurrentChannel,true);
  271. }
  272. else
  273. {
  274. bool isCoord = ((mac->capability.FFD)&&(numberDeviceLink(&mac->deviceLink1) > 0));
  275. fprintf(stdout,"[%f](node %d) coordinator relocation failed%sn",CURRENT_TIME,mac->index_,(isCoord)?".":" --> try to reassociate ...");
  276.   if (!isCoord) //I am not a coordinator
  277.   {
  278.   t_mpib.macShortAddress = 0xffff;
  279. mac->MLME_SET_request(macShortAddress,&t_mpib);
  280.   t_mpib.macCoordExtendedAddress = def_macCoordExtendedAddress;
  281. mac->MLME_SET_request(macCoordExtendedAddress,&t_mpib);
  282. startDevice(t_isCT,t_isFFD,t_assoPermit,t_txBeacon,t_BO,t_SO,true);
  283. }
  284. }
  285. }
  286. void SSCS802_15_4::MLME_COMM_STATUS_indication(UINT_16 PANId,UINT_8 SrcAddrMode,IE3ADDR SrcAddr,
  287.  UINT_8 DstAddrMode,IE3ADDR DstAddr,MACenum status)
  288. {
  289. }
  290. void SSCS802_15_4::MLME_START_confirm(MACenum status)
  291. {
  292. dispatch(status,"MLME_START_confirm");
  293. }
  294. void SSCS802_15_4::MLME_SYNC_LOSS_indication(MACenum LossReason)
  295. {
  296. fprintf(stdout,"[%f](node %d) synchronization lossn",CURRENT_TIME,mac->index_);
  297. mac->MLME_SCAN_request(0x03,SSCS802_15_4::ScanChannels,0);
  298. }
  299. void SSCS802_15_4::MLME_POLL_confirm(MACenum status)
  300. {
  301. }
  302. //--------------------------------------------------------------------------
  303. char *sscsTaskName[] = {"NONE",
  304. "startPANCoord",
  305. "startDevice"};
  306. void SSCS802_15_4::checkTaskOverflow(UINT_8 task)
  307. {
  308. if (sscsTaskP.taskStatus(task))
  309. {
  310. fprintf(stdout,"[SSCS][%f](node %d) task overflow: %sn",CURRENT_TIME,mac->index_,sscsTaskName[task]);
  311. exit(1);
  312. }
  313. else
  314. sscsTaskP.taskStep(task) = 0;
  315. }
  316. void SSCS802_15_4::dispatch(MACenum status,char *frFunc)
  317. {
  318. if (strcmp(frFunc,"MLME_SCAN_confirm") == 0)
  319. {
  320. if (sscsTaskP.taskStatus(sscsTP_startPANCoord))
  321. startPANCoord(sscsTaskP.startPANCoord_isCluster_Tree,sscsTaskP.startPANCoord_txBeacon,sscsTaskP.startPANCoord_BO,sscsTaskP.startPANCoord_SO,false,status);
  322. else if (sscsTaskP.taskStatus(sscsTP_startDevice))
  323. startDevice(sscsTaskP.startDevice_isCluster_Tree,sscsTaskP.startDevice_isFFD,sscsTaskP.startDevice_assoPermit,sscsTaskP.startDevice_txBeacon,sscsTaskP.startDevice_BO,sscsTaskP.startDevice_SO,false,status);
  324. }
  325. else if (strcmp(frFunc,"MLME_START_confirm") == 0)
  326. {
  327. if(sscsTaskP.taskStatus(sscsTP_startPANCoord))
  328. startPANCoord(sscsTaskP.startPANCoord_isCluster_Tree,sscsTaskP.startPANCoord_txBeacon,sscsTaskP.startPANCoord_BO,sscsTaskP.startPANCoord_SO,false,status);
  329. else if (sscsTaskP.taskStatus(sscsTP_startDevice))
  330. startDevice(sscsTaskP.startDevice_isCluster_Tree,sscsTaskP.startDevice_isFFD,sscsTaskP.startDevice_assoPermit,sscsTaskP.startDevice_txBeacon,sscsTaskP.startDevice_BO,sscsTaskP.startDevice_SO,false,status);
  331. else //default handling
  332. {
  333. if (mac->mpib.macBeaconOrder == 15)
  334. fprintf(stdout,"[%f](node %d) beacon transmission stopped [channel:%d] [PAN_ID:%d]n",CURRENT_TIME,mac->index_,mac->tmp_ppib.phyCurrentChannel,mac->mpib.macPANId);
  335. else if (status == m_SUCCESS)
  336. fprintf(stdout,"[%f](node %d) beacon transmission successful [channel:%d] [PAN_ID:%d]n",CURRENT_TIME,mac->index_,mac->tmp_ppib.phyCurrentChannel,mac->mpib.macPANId);
  337. else
  338. fprintf(stdout,"<!>[%f](node %d) failed to transmit beacons -> %s [channel:%d] [PAN_ID:%d]n",CURRENT_TIME,mac->index_,statusName(status),mac->tmp_ppib.phyCurrentChannel,mac->mpib.macPANId);
  339. }
  340. }
  341. else if (strcmp(frFunc,"MLME_ASSOCIATE_confirm") == 0)
  342. {
  343. if(sscsTaskP.taskStatus(sscsTP_startDevice))
  344. startDevice(sscsTaskP.startDevice_isCluster_Tree,sscsTaskP.startDevice_isFFD,sscsTaskP.startDevice_assoPermit,sscsTaskP.startDevice_txBeacon,sscsTaskP.startDevice_BO,sscsTaskP.startDevice_SO,false,status);
  345. }
  346. }
  347. void SSCS802_15_4::startPANCoord(bool isClusterTree,bool txBeacon,UINT_8 BO,UINT_8 SO,bool firsttime,MACenum status)
  348. {
  349. UINT_8 step;
  350. MAC_PIB t_mpib;
  351. PHY_PIB t_ppib;
  352. int i;
  353. if (firsttime) checkTaskOverflow(sscsTP_startPANCoord);
  354. step = sscsTaskP.taskStep(sscsTP_startPANCoord);
  355. switch(step)
  356. {
  357. case 0:
  358. fprintf(stdout,"--- startPANCoord [%d] ---n",mac->index_);
  359. sscsTaskP.taskStatus(sscsTP_startPANCoord) = true;
  360. sscsTaskP.taskStep(sscsTP_startPANCoord)++;
  361. sscsTaskP.startPANCoord_isCluster_Tree = isClusterTree;
  362. sscsTaskP.startPANCoord_txBeacon = txBeacon;
  363. sscsTaskP.startPANCoord_BO = BO;
  364. sscsTaskP.startPANCoord_SO = SO;
  365. //must be an FFD
  366. mac->capability.setFFD(true);
  367. //assign a short address for myself
  368. #ifdef ZigBeeIF
  369. if (isClusterTree)
  370. {
  371. assertZBR();
  372. zbr->myDepth = 0;
  373. zbr->myNodeID = 0; //assign logic address 0 for myself
  374. zbr->myParentNodeID = 0; //no parent, assign my own ID
  375. chkAddCTAddrLink(zbr->myNodeID,mac->index_);
  376. activateCTAddrLink(zbr->myNodeID,mac->index_);
  377. }
  378. #endif
  379. t_mpib.macShortAddress = mac->index_;
  380. mac->MLME_SET_request(macShortAddress,&t_mpib);
  381. //scan the channels
  382. fprintf(stdout,"[%f](node %d) performing active channel scann",CURRENT_TIME,mac->index_);
  383. mac->MLME_SCAN_request(0x01,SSCS802_15_4::ScanChannels,BO);
  384. break;
  385. case 1:
  386. if (status != m_SUCCESS)
  387. {
  388. fprintf(stdout,"<!>[%f](node %d) unable to start as a PAN coordinator: active channel scan failed -> %sn",CURRENT_TIME,mac->index_,statusName(status));
  389. sscsTaskP.taskStatus(sscsTP_startPANCoord) = false;
  390. return;
  391. }
  392. //select a channel and a PAN ID (for simplicity, we just use the IP address as the PAN ID)
  393. //(it's not an easy task to select a channel and PAN ID in implementation!)
  394. for (i=11;i<27;i++) //we give priority to 2.4G
  395. if ((T_UnscannedChannels & (1 << i)) == 0)
  396. break;
  397. if (i >= 27)
  398. for (i=0;i<11;i++)
  399. if ((T_UnscannedChannels & (1 << i)) == 0)
  400. break;
  401. sscsTaskP.startPANCoord_Channel = i;
  402. //permit association
  403. t_mpib.macAssociationPermit = true;
  404. mac->MLME_SET_request(macAssociationPermit,&t_mpib);
  405. if (txBeacon)
  406. {
  407. sscsTaskP.taskStep(sscsTP_startPANCoord)++;
  408. fprintf(stdout,"[%f](node %d) begin to transmit beaconsn",CURRENT_TIME,mac->index_);
  409. mac->MLME_START_request(mac->index_,i,BO,SO,true,false,false,false);
  410. }
  411. else
  412. {
  413. mac->isPanCoor(true);
  414. t_mpib.macCoordExtendedAddress = mac->index_;
  415. mac->MLME_SET_request(macCoordExtendedAddress,&t_mpib);
  416. t_ppib.phyCurrentChannel = i;
  417. mac->phy->PLME_SET_request(phyCurrentChannel,&t_ppib);
  418. sscsTaskP.taskStatus(sscsTP_startPANCoord) = false;
  419. fprintf(stdout,"[%f](node %d) successfully started a new PAN (non-beacon enabled) [channel:%d] [PAN_ID:%d]n",CURRENT_TIME,mac->index_,sscsTaskP.startPANCoord_Channel,mac->index_);
  420. t_mpib.macPANId = mac->index_;
  421. mac->MLME_SET_request(macPANId,&t_mpib);
  422. t_mpib.macBeaconOrder = 15;
  423. mac->MLME_SET_request(macBeaconOrder,&t_mpib);
  424. t_mpib.macSuperframeOrder = 15;
  425. mac->MLME_SET_request(macSuperframeOrder,&t_mpib);
  426. }
  427. #ifdef ZigBeeIF
  428. if (isClusterTree)
  429. {
  430. assertZBR();
  431. zbr->dRate = mac->phy->getRate('d');
  432. }
  433. #endif
  434. break;
  435. case 2:
  436. sscsTaskP.taskStatus(sscsTP_startPANCoord) = false;
  437. if (status == m_SUCCESS)
  438. fprintf(stdout,"[%f](node %d) successfully started a new PAN (beacon enabled) [channel:%d] [PAN_ID:%d]n",CURRENT_TIME,mac->index_,sscsTaskP.startPANCoord_Channel,mac->index_);
  439. else
  440. fprintf(stdout,"<!>[%f](node %d) failed to transmit beacons -> %s [channel:%d] [PAN_ID:%d]n",CURRENT_TIME,mac->index_,statusName(status),sscsTaskP.startPANCoord_Channel,mac->index_);
  441. break;
  442. default:
  443. break;
  444. }
  445. }
  446. void SSCS802_15_4::startDevice(bool isClusterTree,bool isFFD,bool assoPermit,bool txBeacon,UINT_8 BO,UINT_8 SO,bool firsttime,MACenum status)
  447. {
  448. UINT_8 step,scan_BO;
  449. MAC_PIB t_mpib;
  450. SuperframeSpec sfSpec;
  451. UINT_8 ch,fstChannel,fstChannel2_4G;
  452. char tmpstr[30];
  453. int i,k,l,n;
  454. if (firsttime) checkTaskOverflow(sscsTP_startDevice);
  455. step = sscsTaskP.taskStep(sscsTP_startDevice);
  456. switch(step)
  457. {
  458. case 0:
  459. fprintf(stdout,"--- startDevice [%d] ---n",mac->index_);
  460. sscsTaskP.taskStatus(sscsTP_startDevice) = true;
  461. sscsTaskP.taskStep(sscsTP_startDevice)++;
  462. mac->capability.setFFD(isFFD);
  463. sscsTaskP.startDevice_isCluster_Tree = isClusterTree;
  464. sscsTaskP.startDevice_isFFD = isFFD;
  465. sscsTaskP.startDevice_assoPermit = assoPermit;
  466. sscsTaskP.startDevice_txBeacon = txBeacon;
  467. sscsTaskP.startDevice_BO = BO;
  468. sscsTaskP.startDevice_SO = SO;
  469. scan_BO = sscsTaskP.startDevice_BO + 1;
  470. //set FFD
  471. mac->capability.setFFD(isFFD);
  472. //scan the channels
  473. fprintf(stdout,"[%f](node %d) performing active channel scan ...n",CURRENT_TIME,mac->index_);
  474. mac->MLME_SCAN_request(0x01,SSCS802_15_4::ScanChannels,scan_BO);
  475. break;
  476. case 1:
  477. if (status != m_SUCCESS)
  478. {
  479. sscsTaskP.taskStatus(sscsTP_startDevice) = false;
  480. fprintf(stdout,"<!>[%f](node %d) unable to start as a device: active channel scan failed -> %sn",CURRENT_TIME,mac->index_,statusName(status));
  481. assoH.start(assoRetryInterval);
  482. return;
  483. }
  484. //select a PAN and a coordinator to join
  485. fstChannel = 0xff;
  486. fstChannel2_4G = 0xff;
  487. for (i=0;i<T_ResultListSize;i++)
  488. {
  489. sfSpec.SuperSpec = T_PANDescriptorList[i].SuperframeSpec;
  490. sfSpec.parse();
  491. n = updateHListLink(hl_oper_est,&hlistLink1,&hlistLink2,(UINT_16)T_PANDescriptorList[i].CoordAddress_64);
  492. if ((!sfSpec.AssoPmt)||(!n))
  493. continue;
  494. else
  495. {
  496. if (T_PANDescriptorList[i].LogicalChannel < 11)
  497. {
  498. if (fstChannel == 0xff)
  499. {
  500. fstChannel = T_PANDescriptorList[i].LogicalChannel;
  501. k = i;
  502. }
  503. }
  504. else
  505. {
  506. if (fstChannel2_4G == 0xff)
  507. {
  508. fstChannel2_4G = T_PANDescriptorList[i].LogicalChannel;
  509. l = i;
  510. }
  511. }
  512. }
  513. }
  514. if (fstChannel2_4G != 0xff)
  515. {
  516. ch = fstChannel2_4G;
  517. i = l;
  518. }
  519. else
  520. {
  521. ch = fstChannel;
  522. i = k;
  523. }
  524. if (ch == 0xff) //cannot find any coordinator for association
  525. {
  526. sscsTaskP.taskStatus(sscsTP_startDevice) = false;
  527. fprintf(stdout,"<!>[%f](node %d) no coordinator found for association.n",CURRENT_TIME,mac->index_);
  528. assoH.start(assoRetryInterval);
  529. return;
  530. }
  531. else
  532. {
  533. //select the least depth for cluster tree association
  534. #ifdef ZigBeeIF
  535. if (isClusterTree)
  536. {
  537. depth = T_PANDescriptorList[i].clusTreeDepth;
  538. for (m=0;m<T_ResultListSize;m++)
  539. {
  540. n = updateHListLink(hl_oper_est,&hlistLink1,&hlistLink2,(UINT_16)T_PANDescriptorList[m].CoordAddress_64);
  541. if ((ch == T_PANDescriptorList[m].LogicalChannel)&&(n))
  542. if (T_PANDescriptorList[m].clusTreeDepth < depth)
  543. {
  544. depth = T_PANDescriptorList[m].clusTreeDepth;
  545. i = m;
  546. }
  547. }
  548. }
  549. #endif
  550. //If the coordinator is in beacon-enabled mode, we may begin to track beacons now.
  551. //But this is only possible if the network is a one-hop star; otherwise we don't know
  552. //which coordinator to track, since there may be more than one beaconing coordinators
  553. //in a device's neighborhood and MLME-SYNC.request() has no parameter telling which 
  554. //coordinator to track. As this is an optional step, we will not track beacons here.
  555. t_mpib.macAssociationPermit = assoPermit;
  556. mac->MLME_SET_request(macAssociationPermit,&t_mpib);
  557. sscsTaskP.startDevice_Channel = ch;
  558. fprintf(stdout,"[%f](node %d) sending association request to [channel:%d] [PAN_ID:%d] [CoordAddr:%d] ... n",CURRENT_TIME,mac->index_,ch,T_PANDescriptorList[i].CoordPANId,T_PANDescriptorList[i].CoordAddress_64);
  559. sscsTaskP.taskStep(sscsTP_startDevice)++;
  560. sscsTaskP.startDevice_panDes = T_PANDescriptorList[i];
  561. mac->MLME_ASSOCIATE_request(ch,T_PANDescriptorList[i].CoordAddrMode,T_PANDescriptorList[i].CoordPANId,T_PANDescriptorList[i].CoordAddress_64,mac->capability.cap,false);
  562. }
  563. break;
  564. case 2:
  565. sfSpec.SuperSpec = sscsTaskP.startDevice_panDes.SuperframeSpec;
  566. sfSpec.parse();
  567. if (sfSpec.BO != 15)
  568. strcpy(tmpstr,"beacon enabled");
  569. else
  570. strcpy(tmpstr,"non-beacon enabled");
  571. if (status != m_SUCCESS)
  572. {
  573. //reset association permission
  574. t_mpib.macAssociationPermit = false;
  575. mac->MLME_SET_request(macAssociationPermit,&t_mpib);
  576. fprintf(stdout,"<!>[%f](node %d) association failed -> %s (%s) [channel:%d] [PAN_ID:%d] [CoordAddr:%d]n",CURRENT_TIME,mac->index_,statusName(status),tmpstr,sscsTaskP.startDevice_panDes.LogicalChannel,sscsTaskP.startDevice_panDes.CoordPANId,sscsTaskP.startDevice_panDes.CoordAddress_64);
  577. assoH.start(assoRetryInterval);
  578. sscsTaskP.taskStatus(sscsTP_startDevice) = false;
  579. #ifdef ZigBeeIF
  580. if (isClusterTree)
  581. {
  582. assertZBR();
  583. zbr->sscs_nb_insert(sscsTaskP.startDevice_panDes.CoordAddress_64,NEIGHBOR);
  584. if (status == m_PAN_at_capacity)
  585. chkAddUpdHListLink(&hlistLink1,&hlistLink2,(UINT_16)sscsTaskP.startDevice_panDes.CoordAddress_64,0);
  586. }
  587. #endif
  588. }
  589. else
  590. {
  591. neverAsso = false;
  592. fprintf(stdout,"[%f](node %d) association successful (%s) [channel:%d] [PAN_ID:%d] [CoordAddr:%d]n",CURRENT_TIME,mac->index_,tmpstr,sscsTaskP.startDevice_panDes.LogicalChannel,sscsTaskP.startDevice_panDes.CoordPANId,sscsTaskP.startDevice_panDes.CoordAddress_64);
  593. #ifdef ZigBeeIF
  594. if (isClusterTree)
  595. {
  596. assertZBR();
  597. zbr->myDepth = rt_myDepth;
  598. zbr->myNodeID = rt_myNodeID;
  599. zbr->myParentNodeID = rt_myParentNodeID;
  600. zbr->sscs_nb_insert(sscsTaskP.startDevice_panDes.CoordAddress_64,PARENT);
  601. //chkAddCTAddrLink(zbr->myNodeID,mac->index_); //too late -- may result in assigning duplicated addresses
  602. activateCTAddrLink(zbr->myNodeID,mac->index_);
  603. emptyHListLink(&hlistLink1,&hlistLink2);
  604. }
  605. #endif
  606. if (sfSpec.BO != 15)
  607. {
  608. fprintf(stdout,"[%f](node %d) begin to synchronize with the coordinatorn",CURRENT_TIME,mac->index_);
  609. mac->MLME_SYNC_request(sscsTaskP.startDevice_panDes.LogicalChannel,true);
  610. sscsTaskP.taskStatus(sscsTP_startDevice) = false;
  611. }
  612. if (isFFD && txBeacon)
  613. {
  614. sscsTaskP.taskStep(sscsTP_startDevice)++;
  615. fprintf(stdout,"[%f](node %d) begin to transmit beaconsn",CURRENT_TIME,mac->index_);
  616. mac->MLME_START_request(mac->mpib.macPANId,sscsTaskP.startDevice_Channel,BO,SO,false,false,false,false);
  617. }
  618. else
  619. sscsTaskP.taskStatus(sscsTP_startDevice) = false;
  620. #ifdef ZigBeeIF
  621. if (isClusterTree)
  622. zbr->dRate = mac->phy->getRate('d');
  623. #endif
  624. }
  625. break;
  626. case 3:
  627. sscsTaskP.taskStatus(sscsTP_startDevice) = false;
  628. if (status == m_SUCCESS)
  629. fprintf(stdout,"[%f](node %d) beacon transmission successful [channel:%d] [PAN_ID:%d]n",CURRENT_TIME,mac->index_,sscsTaskP.startDevice_Channel,mac->mpib.macPANId);
  630. else
  631. fprintf(stdout,"<!>[%f](node %d) failed to transmit beacons -> %s [channel:%d] [PAN_ID:%d]n",CURRENT_TIME,mac->index_,statusName(status),sscsTaskP.startDevice_Channel,mac->mpib.macPANId);
  632. break;
  633. default:
  634. break;
  635. }
  636. }
  637. //--------------------------------------------------------------------------
  638. /* The following primitives are availabe from MAC sublayer. You can call these primitives from SSCS or other upper layer
  639.  * void MCPS_DATA_request(UINT_8 SrcAddrMode,UINT_16 SrcPANId,IE3ADDR SrcAddr,
  640.  *        UINT_8 DstAddrMode,UINT_16 DstPANId,IE3ADDR DstAddr,
  641.  *        UINT_8 msduLength,Packet *msdu,UINT_8 msduHandle,UINT_8 TxOptions);
  642.  * void MCPS_DATA_indication(UINT_8 SrcAddrMode,UINT_16 SrcPANId,IE3ADDR SrcAddr,
  643.  *   UINT_8 DstAddrMode,UINT_16 DstPANId,IE3ADDR DstAddr,
  644.  *   UINT_8 msduLength,Packet *msdu,UINT_8 mpduLinkQuality,
  645.  *   bool SecurityUse,UINT_8 ACLEntry);
  646.  * void MCPS_PURGE_request(UINT_8 msduHandle);
  647.  * void MLME_ASSOCIATE_request(UINT_8 LogicalChannel,UINT_8 CoordAddrMode,UINT_16 CoordPANId,IE3ADDR CoordAddress,
  648.  *     UINT_8 CapabilityInformation,bool SecurityEnable);
  649.  * void MLME_ASSOCIATE_response(IE3ADDR DeviceAddress,UINT_16 AssocShortAddress,MACenum status,bool SecurityEnable);
  650.  * void MLME_DISASSOCIATE_request(IE3ADDR DeviceAddress,UINT_8 DisassociateReason,bool SecurityEnable);
  651.  * void MLME_DISASSOCIATE_indication(IE3ADDR DeviceAddress,UINT_8 DisassociateReason,bool SecurityUse,UINT_8 ACLEntry);
  652.  * void MLME_DISASSOCIATE_confirm(MACenum status);
  653.  * void MLME_GET_request(MPIBAenum PIBAttribute);
  654.  * void MLME_GTS_request(UINT_8 GTSCharacteristics,bool SecurityEnable);
  655.  * void MLME_GTS_confirm(UINT_8 GTSCharacteristics,MACenum status);
  656.  * void MLME_GTS_indication(UINT_16 DevAddress,UINT_8 GTSCharacteristics,
  657.  *  bool SecurityUse, UINT_8 ACLEntry);
  658.  * void MLME_ORPHAN_indication(IE3ADDR OrphanAddress,bool SecurityUse,UINT_8 ACLEntry);
  659.  * void MLME_ORPHAN_response(IE3ADDR OrphanAddress,UINT_16 ShortAddress,bool AssociatedMember,bool SecurityEnable);
  660.  * void MLME_RESET_request(bool SetDefaultPIB);
  661.  * void MLME_RX_ENABLE_request(bool DeferPermit,UINT_32 RxOnTime,UINT_32 RxOnDuration);
  662.  * void MLME_RX_ENABLE_confirm(MACenum status);
  663.  * void MLME_SCAN_request(UINT_8 ScanType,UINT_32 ScanChannels,UINT_8 ScanDuration);
  664.  * void MLME_SET_request(MPIBAenum PIBAttribute,MAC_PIB *PIBAttributeValue);
  665.  * void MLME_SET_confirm(MACenum status,MPIBAenum PIBAttribute);
  666.  * void MLME_START_request(UINT_16 PANId,UINT_8 LogicalChannel,UINT_8 BeaconOrder,
  667.  * UINT_8 SuperframeOrder,bool PANCoordinator,bool BatteryLifeExtension,
  668.  * bool CoordRealignment,bool SecurityEnable);
  669.  * void MLME_SYNC_request(UINT_8 LogicalChannel, bool TrackBeacon);
  670.  * void MLME_SYNC_LOSS_indication(MACenum LossReason);
  671.  * void MLME_POLL_request(UINT_8 CoordAddrMode,UINT_16 CoordPANId,IE3ADDR CoordAddress,bool SecurityEnable);
  672.  * void MLME_POLL_confirm(MACenum status);
  673.  */
  674. //--------------------------------------------------------------------------
  675. /* The following commands are available in Tcl scripts -- most of them are the wrap-up of primitives */
  676. int SSCS802_15_4::command(int argc, const char*const* argv)
  677. {
  678. //Commands from Tcl will be one of the following forms:
  679. // --- $node sscs startPANCoord <txBeacon = 1> <beaconOrder = 3> <SuperframeOrder = 3>
  680. // --- $node sscs startDevice <isFFD = 1> <assoPermit = 1> <txBeacon = 0> <beaconOrder = 3> <SuperframeOrder = 3>
  681. // --- $node sscs startCTPANCoord <txBeacon = 1> <beaconOrder = 3> <SuperframeOrder = 3>
  682. // --- $node sscs startCTDevice <isFFD = 1> <assoPermit = 1> <txBeacon = 0> <beaconOrder = 3> <SuperframeOrder = 3>
  683. // --- $node sscs startBeacon <beaconOrder = 3> <SuperframeOrder = 3>
  684. // --- $node sscs stopBeacon
  685. int i;
  686. if ((strcmp(argv[2], "startPANCoord") == 0)
  687. ||  (strcmp(argv[2], "startCTPANCoord") == 0))
  688. {
  689. i = 2;
  690. t_isCT = (strcmp(argv[i], "startCTPANCoord") == 0);
  691. #ifndef ZigBeeIF
  692. t_isCT = false;
  693. #endif
  694. if (argc == i + 1)
  695. {
  696. t_txBeacon = true;
  697. t_BO = 3;
  698. t_SO = 3;
  699. }
  700. else if (argc == i + 2)
  701. {
  702. t_txBeacon = (atoi(argv[i+1])!=0);
  703. t_BO = 3;
  704. t_SO = 3;
  705. }
  706. else if (argc == i + 3)
  707. {
  708. t_txBeacon = (atoi(argv[i+1])!=0);
  709. t_BO = atoi(argv[i+2]);
  710. t_SO = 3;
  711. }
  712. else
  713. {
  714. t_txBeacon = (atoi(argv[i+1])!=0);
  715. t_BO = atoi(argv[i+2]);
  716. t_SO = atoi(argv[i+3]);
  717. }
  718. startPANCoord(t_isCT,t_txBeacon,t_BO,t_SO,true);
  719. }
  720. else if ((strcmp(argv[2], "startDevice") == 0)
  721. ||       (strcmp(argv[2], "startCTDevice") == 0))
  722. {
  723. i = 2;
  724. t_isCT = (strcmp(argv[i], "startCTDevice") == 0);
  725. #ifndef ZigBeeIF
  726. t_isCT = false;
  727. #endif
  728. if (argc == i + 1)
  729. {
  730. t_isFFD = true;
  731. t_assoPermit = true;
  732. t_txBeacon = false;
  733. t_BO = 3;
  734. t_SO = 3;
  735. }
  736. else if (argc == i + 2)
  737. {
  738. t_isFFD = (atoi(argv[i+1])!=0);
  739. t_assoPermit = true;
  740. t_txBeacon = false;
  741. t_BO = 3;
  742. t_SO = 3;
  743. }
  744. else if (argc == i + 3)
  745. {
  746. t_isFFD = (atoi(argv[i+1])!=0);
  747. t_assoPermit = (atoi(argv[i+2])!=0);
  748. t_txBeacon = false;
  749. t_BO = 3;
  750. t_SO = 3;
  751. }
  752. else if (argc == i + 4)
  753. {
  754. t_isFFD = (atoi(argv[i+1])!=0);
  755. t_assoPermit = (atoi(argv[i+2])!=0);
  756. t_txBeacon = (atoi(argv[i+3])!=0);
  757. t_BO = 3;
  758. t_SO = 3;
  759. }
  760. else if (argc == i + 5)
  761. {
  762. t_isFFD = (atoi(argv[i+1])!=0);
  763. t_assoPermit = (atoi(argv[i+2])!=0);
  764. t_txBeacon = (atoi(argv[i+3])!=0);
  765. t_BO = atoi(argv[i+4]);
  766. t_SO = 3;
  767. }
  768. else
  769. {
  770. t_isFFD = (atoi(argv[i+1])!=0);
  771. t_assoPermit = (atoi(argv[i+2])!=0);
  772. t_txBeacon = (atoi(argv[i+3])!=0);
  773. t_BO = atoi(argv[i+4]);
  774. t_SO = atoi(argv[i+5]);
  775. }
  776. if (!t_isFFD)
  777. t_assoPermit = false;
  778. startDevice(t_isCT,t_isFFD,t_assoPermit,t_txBeacon,t_BO,t_SO,true);
  779. }
  780. else if (strcmp(argv[2], "startBeacon") == 0)
  781. {
  782. if (argc == 3)
  783. {
  784. t_BO = 3;
  785. t_SO = 3;
  786. }
  787. else if (argc == 4)
  788. {
  789. t_BO = atoi(argv[3]);
  790. t_SO = 3;
  791. }
  792. else
  793. {
  794. t_BO = atoi(argv[3]);
  795. t_SO = atoi(argv[4]);
  796. }
  797. mac->phy->PLME_GET_request(phyCurrentChannel);
  798. mac->MLME_START_request(mac->mpib.macPANId,mac->tmp_ppib.phyCurrentChannel,t_BO,t_SO,mac->isPANCoor,false,false,false);
  799. }
  800. else if (strcmp(argv[2], "stopBeacon") == 0)
  801. {
  802. mac->phy->PLME_GET_request(phyCurrentChannel);
  803. mac->MLME_START_request(mac->mpib.macPANId,mac->tmp_ppib.phyCurrentChannel,15,15,mac->isPANCoor,false,false,false);
  804. }
  805. return TCL_OK;
  806. }
  807. #ifdef ZigBeeIF
  808. void SSCS802_15_4::assertZBR(void)
  809. {
  810. if (!zbr)
  811. zbr = getZBRLink(mac->index_);
  812. assert(zbr);
  813. zbr->dRate = mac->phy->getRate('d');
  814. }
  815. int SSCS802_15_4::RNType(void)
  816. {
  817. if (!t_isCT)
  818. return 1;
  819. assertZBR();
  820. return zbr->RNType;
  821. }
  822. void SSCS802_15_4::setGetClusTreePara(char setGet,Packet *p)
  823. {
  824. hdr_lrwpan *wph = HDR_LRWPAN(p);
  825. if (!t_isCT)
  826. return;
  827. assertZBR();
  828. if (setGet == 's')
  829. {
  830. wph->clusTreeDepth = zbr->myDepth;
  831. wph->clusTreeParentNodeID = zbr->myNodeID;
  832. }
  833. else
  834. {
  835. rt_myDepth = wph->clusTreeDepth + 1;
  836. rt_myParentNodeID = wph->clusTreeParentNodeID;
  837. }
  838. }
  839. #endif
  840. // End of file: p802_15_4sscs.cc