p802_15_4sscs.cc

Go to the documentation of this file.
00001 /********************************************/
00002 /*     NS2 Simulator for IEEE 802.15.4      */
00003 /*           (per P802.15.4/D18)            */
00004 /*------------------------------------------*/
00005 /* by:        Jianliang Zheng               */
00006 /*        (zheng@ee.ccny.cuny.edu)          */
00007 /*              Myung J. Lee                */
00008 /*          (lee@ccny.cuny.edu)             */
00009 /*        ~~~~~~~~~~~~~~~~~~~~~~~~~         */
00010 /*           SAIT-CUNY Joint Lab            */
00011 /********************************************/
00012 
00013 // File:  p802_15_4sscs.cc
00014 // Mode:  C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t
00015 
00016 // $Header: /nfs/jade/vint/CVSROOT/ns-2/wpan/p802_15_4sscs.cc,v 1.2 2005/07/13 03:51:33 tomh Exp $
00017 
00018 // Functions in this file are out of the scope of 802.15.4.
00019 // But they elaborate how a higher layer interfaces with 802.15.4.
00020 // You can modify this file at will to fit your need.
00021 
00022 /*
00023  * Copyright (c) 2003-2004 Samsung Advanced Institute of Technology and
00024  * The City University of New York. All rights reserved.
00025  *
00026  * Redistribution and use in source and binary forms, with or without
00027  * modification, are permitted provided that the following conditions
00028  * are met:
00029  * 1. Redistributions of source code must retain the above copyright
00030  *    notice, this list of conditions and the following disclaimer.
00031  * 2. Redistributions in binary form must reproduce the above copyright
00032  *    notice, this list of conditions and the following disclaimer in the
00033  *    documentation and/or other materials provided with the distribution.
00034  * 3. All advertising materials mentioning features or use of this software
00035  *    must display the following acknowledgement:
00036  *  This product includes software developed by the Joint Lab of Samsung 
00037  *      Advanced Institute of Technology and The City University of New York.
00038  * 4. Neither the name of Samsung Advanced Institute of Technology nor of 
00039  *    The City University of New York may be used to endorse or promote 
00040  *    products derived from this software without specific prior written 
00041  *    permission.
00042  *
00043  * THIS SOFTWARE IS PROVIDED BY THE JOINT LAB OF SAMSUNG ADVANCED INSTITUTE
00044  * OF TECHNOLOGY AND THE CITY UNIVERSITY OF NEW YORK ``AS IS'' AND ANY EXPRESS 
00045  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
00046  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 
00047  * NO EVENT SHALL SAMSUNG ADVANCED INSTITUTE OR THE CITY UNIVERSITY OF NEW YORK 
00048  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00049  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
00050  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00051  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00052  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
00053  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00054  */
00055 
00056 
00057 #include "p802_15_4sscs.h"
00058 
00059 #ifdef ZigBeeIF
00060 #include "../zbr/zbr_link.h"
00061 #include "../zbr/zbr.h"
00062 #endif
00063 
00064 #define assoRetryInterval   1.0
00065 
00066 //UINT_32 SSCS802_15_4::ScanChannels = 0x07ffffff;
00067 UINT_32 SSCS802_15_4::ScanChannels = 0x00003800;    //only scan the first 3 channels in 2.4G
00068 
00069 void SSCS802_15_4Timer::start(double wtime)
00070 {
00071     assert(!active);
00072     active = true;
00073     nullEvent.uid_ = 0;
00074     Scheduler::instance().schedule(this,&nullEvent,wtime);
00075 }
00076 
00077 void SSCS802_15_4Timer::cancel(void)
00078 {
00079     active = false;
00080     Scheduler::instance().cancel(&nullEvent);
00081 }
00082 
00083 void SSCS802_15_4Timer::handle(Event* e)
00084 {
00085     active = false;
00086     if (sscs->neverAsso)
00087         sscs->startDevice(sscs->t_isCT,sscs->t_isFFD,sscs->t_assoPermit,sscs->t_txBeacon,sscs->t_BO,sscs->t_SO,true);
00088 }
00089 
00090 char *statusName(MACenum status)
00091 {
00092     switch(status)
00093     {
00094         case m_SUCCESS:
00095             return "SUCCESS";
00096         case m_PAN_at_capacity:
00097             return "PAN_at_capacity";
00098         case m_PAN_access_denied:
00099             return "PAN_access_denied";
00100         case m_BEACON_LOSS:
00101             return "BEACON_LOSS";
00102         case m_CHANNEL_ACCESS_FAILURE:
00103             return "CHANNEL_ACCESS_FAILURE";
00104         case m_DENIED:
00105             return "DENIED";
00106         case m_DISABLE_TRX_FAILURE:
00107             return "DISABLE_TRX_FAILURE";
00108         case m_FAILED_SECURITY_CHECK:
00109             return "FAILED_SECURITY_CHECK";
00110         case m_FRAME_TOO_LONG:
00111             return "FRAME_TOO_LONG";
00112         case m_INVALID_GTS:
00113             return "INVALID_GTS";
00114         case m_INVALID_HANDLE:
00115             return "INVALID_HANDLE";
00116         case m_INVALID_PARAMETER:
00117             return "INVALID_PARAMETER";
00118         case m_NO_ACK:
00119             return "NO_ACK";
00120         case m_NO_BEACON:
00121             return "NO_BEACON";
00122         case m_NO_DATA:
00123             return "NO_DATA";
00124         case m_NO_SHORT_ADDRESS:
00125             return "NO_SHORT_ADDRESS";
00126         case m_OUT_OF_CAP:
00127             return "OUT_OF_CAP";
00128         case m_PAN_ID_CONFLICT:
00129             return "PAN_ID_CONFLICT";
00130         case m_REALIGNMENT:
00131             return "REALIGNMENT";
00132         case m_TRANSACTION_EXPIRED:
00133             return "TRANSACTION_EXPIRED";
00134         case m_TRANSACTION_OVERFLOW:
00135             return "TRANSACTION_OVERFLOW";
00136         case m_TX_ACTIVE:
00137             return "TX_ACTIVE";
00138         case m_UNAVAILABLE_KEY:
00139             return "UNAVAILABLE_KEY";
00140         case m_UNSUPPORTED_ATTRIBUTE:
00141             return "UNSUPPORTED_ATTRIBUTE";
00142         case m_UNDEFINED:
00143         default:
00144             return "UNDEFINED";
00145     }
00146 }
00147 
00148 SSCS802_15_4::SSCS802_15_4(Mac802_15_4 *m):assoH(this)
00149 {
00150     mac = m;
00151     neverAsso = true;
00152 #ifdef ZigBeeIF
00153     zbr = getZBRLink(mac->index_);
00154 #endif
00155     hlistLink1 = NULL;
00156     hlistLink2 = NULL;
00157 }
00158 
00159 SSCS802_15_4::~SSCS802_15_4()
00160 {
00161 }
00162 
00163 void SSCS802_15_4::MCPS_DATA_confirm(UINT_8 msduHandle,MACenum status)
00164 {
00165 }
00166 
00167 void SSCS802_15_4::MCPS_DATA_indication(UINT_8 SrcAddrMode,UINT_16 SrcPANId,IE3ADDR SrcAddr,
00168                     UINT_8 DstAddrMode,UINT_16 DstPANId,IE3ADDR DstAddr,
00169                     UINT_8 msduLength,Packet *msdu,UINT_8 mpduLinkQuality,
00170                     bool SecurityUse,UINT_8 ACLEntry)
00171 {
00172     Packet::free(msdu);
00173 }
00174 
00175 void SSCS802_15_4::MCPS_PURGE_confirm(UINT_8 msduHandle,MACenum status)
00176 {
00177 }
00178 
00179 #ifdef ZigBeeIF
00180 extern NET_SYSTEM_CONFIG NetSystemConfig;
00181 #endif
00182 void SSCS802_15_4::MLME_ASSOCIATE_indication(IE3ADDR DeviceAddress,UINT_8 CapabilityInformation,bool SecurityUse,UINT_8 ACLEntry)
00183 {
00184     
00185     //we assign the cluster tree address as the MAC short address
00186 
00187 #ifdef ZigBeeIF
00188     if (t_isCT)         //need to assign a cluster tree logic address
00189     {
00190         assertZBR();
00191         noCapacity = false;
00192         if (zbr->myDepth >= NetSystemConfig.Lm)
00193             noCapacity = true;
00194         else
00195         {
00196             child_num = 1;
00197             logAddr = zbr->myNodeID + 1;                
00198             while (!updateCTAddrLink(zbr_oper_est,logAddr))
00199             {
00200                 if (getIpAddrFrLogAddr(logAddr,false) == (UINT_16)DeviceAddress)
00201                     break; 
00202                 logAddr += ZBR::c_skip(zbr->myDepth);       
00203                 child_num++;
00204                 if (child_num > NetSystemConfig.Cm)
00205                     break;
00206             }
00207             if (child_num > NetSystemConfig.Cm)
00208                 noCapacity = true;
00209         }
00210         if (noCapacity)                     //no capacity
00211         {
00212 #ifdef DEBUG802_15_4
00213             fprintf(stdout,"[%s::%s][%f](node %d) no capacity for cluster-tree: request from %d\n",__FILE__,__FUNCTION__,CURRENT_TIME,mac->index_,DeviceAddress);
00214 #endif
00215             zbr->sscs_nb_insert((UINT_16)DeviceAddress,NEIGHBOR);
00216             mac->MLME_ASSOCIATE_response(DeviceAddress,0,m_PAN_at_capacity,false);
00217         }
00218         else
00219         {
00220             chkAddCTAddrLink(logAddr,DeviceAddress);
00221             chkAddDeviceLink(&mac->deviceLink1,&mac->deviceLink2,DeviceAddress,CapabilityInformation);
00222             zbr->sscs_nb_insert((UINT_16)DeviceAddress,CHILD);
00223             mac->MLME_ASSOCIATE_response(DeviceAddress,logAddr,m_SUCCESS,false);
00224         }
00225     }
00226     else    //just assign the IP address as the MAC short address for non-cluster tree
00227 #endif
00228     {
00229         chkAddDeviceLink(&mac->deviceLink1,&mac->deviceLink2,DeviceAddress,CapabilityInformation);
00230         mac->MLME_ASSOCIATE_response(DeviceAddress,(UINT_16)DeviceAddress,m_SUCCESS,false);
00231     }
00232 }
00233 
00234 void SSCS802_15_4::MLME_ASSOCIATE_confirm(UINT_16 AssocShortAddress,MACenum status)
00235 {
00236     MAC_PIB t_mpib;
00237 
00238     if (status == m_SUCCESS)
00239     {
00240         rt_myNodeID = AssocShortAddress;
00241         /*
00242         if (!sscsTaskP.startDevice_isCluster_Tree)
00243             t_mpib.macShortAddress = AssocShortAddress;
00244         else
00245         */
00246             t_mpib.macShortAddress = mac->index_;       //don't use cluster tree logic address
00247         mac->MLME_SET_request(macShortAddress,&t_mpib);
00248     }
00249     dispatch(status,"MLME_ASSOCIATE_confirm");
00250 }
00251 
00252 void SSCS802_15_4::MLME_DISASSOCIATE_confirm(MACenum status)
00253 {
00254 }
00255 
00256 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)
00257 {
00258 }
00259 
00260 void SSCS802_15_4::MLME_GET_confirm(MACenum status,MPIBAenum PIBAttribute,MAC_PIB *PIBAttributeValue)
00261 {
00262 }
00263 
00264 void SSCS802_15_4::MLME_ORPHAN_indication(IE3ADDR OrphanAddress,bool SecurityUse,UINT_8 ACLEntry)
00265 {
00266     if (updateDeviceLink(tr_oper_est,&mac->deviceLink1,&mac->deviceLink2,OrphanAddress) == 0)
00267         mac->MLME_ORPHAN_response(OrphanAddress,(UINT_16)OrphanAddress,true,false);
00268     else
00269         mac->MLME_ORPHAN_response(OrphanAddress,0,false,false);
00270 }
00271 
00272 void SSCS802_15_4::MLME_RESET_confirm(MACenum status)
00273 {
00274 }
00275 
00276 void SSCS802_15_4::MLME_RX_ENABLE_confirm(MACenum status)
00277 {
00278 }
00279 
00280 void SSCS802_15_4::MLME_SET_confirm(MACenum status,MPIBAenum PIBAttribute)
00281 {
00282 }
00283 
00284 void SSCS802_15_4::MLME_SCAN_confirm(MACenum status,UINT_8 ScanType,UINT_32 UnscannedChannels,
00285                      UINT_8 ResultListSize,UINT_8 *EnergyDetectList,
00286                      PAN_ELE *PANDescriptorList)
00287 {
00288     MAC_PIB t_mpib;
00289 
00290     T_UnscannedChannels = UnscannedChannels;
00291     T_ResultListSize = ResultListSize;
00292     T_EnergyDetectList = EnergyDetectList;
00293     T_PANDescriptorList = PANDescriptorList;
00294     if (ScanType == 0x01)
00295         dispatch(status,"MLME_SCAN_confirm");
00296     if (ScanType == 0x03)
00297     if (status == m_SUCCESS)
00298     {
00299         fprintf(stdout,"[%f](node %d) coordinator relocation successful, begin to re-synchronize with the coordinator\n",CURRENT_TIME,mac->index_);
00300         //re-synchronize with the coordinator
00301         mac->phy->PLME_GET_request(phyCurrentChannel);
00302         mac->MLME_SYNC_request(mac->tmp_ppib.phyCurrentChannel,true);
00303     }
00304     else
00305     {
00306         bool isCoord = ((mac->capability.FFD)&&(numberDeviceLink(&mac->deviceLink1) > 0));
00307         fprintf(stdout,"[%f](node %d) coordinator relocation failed%s\n",CURRENT_TIME,mac->index_,(isCoord)?".":" --> try to reassociate ...");
00308         if (!isCoord)       //I am not a coordinator
00309         {
00310             t_mpib.macShortAddress = 0xffff;
00311             mac->MLME_SET_request(macShortAddress,&t_mpib);
00312             t_mpib.macCoordExtendedAddress = def_macCoordExtendedAddress;
00313             mac->MLME_SET_request(macCoordExtendedAddress,&t_mpib);
00314             startDevice(t_isCT,t_isFFD,t_assoPermit,t_txBeacon,t_BO,t_SO,true);
00315         }
00316     }
00317 }
00318 
00319 void SSCS802_15_4::MLME_COMM_STATUS_indication(UINT_16 PANId,UINT_8 SrcAddrMode,IE3ADDR SrcAddr,
00320                  UINT_8 DstAddrMode,IE3ADDR DstAddr,MACenum status)
00321 {
00322 }
00323 
00324 void SSCS802_15_4::MLME_START_confirm(MACenum status)
00325 {
00326     dispatch(status,"MLME_START_confirm");
00327 }
00328 
00329 void SSCS802_15_4::MLME_SYNC_LOSS_indication(MACenum LossReason)
00330 {
00331     fprintf(stdout,"[%f](node %d) synchronization loss\n",CURRENT_TIME,mac->index_);
00332     mac->MLME_SCAN_request(0x03,SSCS802_15_4::ScanChannels,0);
00333 }
00334 
00335 void SSCS802_15_4::MLME_POLL_confirm(MACenum status)
00336 {
00337 }
00338 
00339 //--------------------------------------------------------------------------
00340 
00341 char *sscsTaskName[] = {"NONE",
00342             "startPANCoord",
00343             "startDevice"};
00344 void SSCS802_15_4::checkTaskOverflow(UINT_8 task)
00345 {
00346     if (sscsTaskP.taskStatus(task))
00347     {
00348         fprintf(stdout,"[SSCS][%f](node %d) task overflow: %s\n",CURRENT_TIME,mac->index_,sscsTaskName[task]);
00349         exit(1);
00350     }
00351     else
00352         sscsTaskP.taskStep(task) = 0;
00353 }
00354 
00355 void SSCS802_15_4::dispatch(MACenum status,char *frFunc)
00356 {
00357     if (strcmp(frFunc,"MLME_SCAN_confirm") == 0)
00358     {
00359         if (sscsTaskP.taskStatus(sscsTP_startPANCoord))
00360             startPANCoord(sscsTaskP.startPANCoord_isCluster_Tree,sscsTaskP.startPANCoord_txBeacon,sscsTaskP.startPANCoord_BO,sscsTaskP.startPANCoord_SO,false,status);
00361         else if (sscsTaskP.taskStatus(sscsTP_startDevice))
00362             startDevice(sscsTaskP.startDevice_isCluster_Tree,sscsTaskP.startDevice_isFFD,sscsTaskP.startDevice_assoPermit,sscsTaskP.startDevice_txBeacon,sscsTaskP.startDevice_BO,sscsTaskP.startDevice_SO,false,status);
00363     }
00364     else if (strcmp(frFunc,"MLME_START_confirm") == 0)
00365     {
00366         if(sscsTaskP.taskStatus(sscsTP_startPANCoord))
00367             startPANCoord(sscsTaskP.startPANCoord_isCluster_Tree,sscsTaskP.startPANCoord_txBeacon,sscsTaskP.startPANCoord_BO,sscsTaskP.startPANCoord_SO,false,status);
00368         else if (sscsTaskP.taskStatus(sscsTP_startDevice))
00369             startDevice(sscsTaskP.startDevice_isCluster_Tree,sscsTaskP.startDevice_isFFD,sscsTaskP.startDevice_assoPermit,sscsTaskP.startDevice_txBeacon,sscsTaskP.startDevice_BO,sscsTaskP.startDevice_SO,false,status);
00370         else    //default handling
00371         {
00372             if (mac->mpib.macBeaconOrder == 15)
00373                 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);
00374             else if (status == m_SUCCESS)
00375                 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);
00376             else
00377                 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);
00378         }
00379     }
00380     else if (strcmp(frFunc,"MLME_ASSOCIATE_confirm") == 0)
00381     {
00382         if(sscsTaskP.taskStatus(sscsTP_startDevice))
00383             startDevice(sscsTaskP.startDevice_isCluster_Tree,sscsTaskP.startDevice_isFFD,sscsTaskP.startDevice_assoPermit,sscsTaskP.startDevice_txBeacon,sscsTaskP.startDevice_BO,sscsTaskP.startDevice_SO,false,status);
00384     }
00385 }
00386 
00387 void SSCS802_15_4::startPANCoord(bool isClusterTree,bool txBeacon,UINT_8 BO,UINT_8 SO,bool firsttime,MACenum status)
00388 {
00389     UINT_8 step;
00390     MAC_PIB t_mpib;
00391     PHY_PIB t_ppib;
00392     int i;
00393         
00394     if (firsttime) checkTaskOverflow(sscsTP_startPANCoord);
00395 
00396     step = sscsTaskP.taskStep(sscsTP_startPANCoord);
00397     switch(step)
00398     {
00399         case 0:
00400             fprintf(stdout,"--- startPANCoord [%d] ---\n",mac->index_);
00401             sscsTaskP.taskStatus(sscsTP_startPANCoord) = true;
00402             sscsTaskP.taskStep(sscsTP_startPANCoord)++;
00403             sscsTaskP.startPANCoord_isCluster_Tree = isClusterTree;
00404             sscsTaskP.startPANCoord_txBeacon = txBeacon;
00405             sscsTaskP.startPANCoord_BO = BO;
00406             sscsTaskP.startPANCoord_SO = SO;
00407             //must be an FFD
00408             mac->capability.setFFD(true);
00409             //assign a short address for myself
00410 #ifdef ZigBeeIF
00411             if (isClusterTree)
00412             {
00413                 assertZBR();
00414                 zbr->myDepth = 0;
00415                 zbr->myNodeID = 0;          //assign logic address 0 for myself
00416                 zbr->myParentNodeID = 0;        //no parent, assign my own ID
00417                 chkAddCTAddrLink(zbr->myNodeID,mac->index_);
00418                 activateCTAddrLink(zbr->myNodeID,mac->index_);
00419             }
00420 #endif
00421             t_mpib.macShortAddress = mac->index_;
00422             mac->MLME_SET_request(macShortAddress,&t_mpib);
00423             //scan the channels
00424             fprintf(stdout,"[%f](node %d) performing active channel scan\n",CURRENT_TIME,mac->index_);
00425             mac->MLME_SCAN_request(0x01,SSCS802_15_4::ScanChannels,BO);
00426             break;
00427         case 1:
00428             if (status != m_SUCCESS)
00429             {
00430                 fprintf(stdout,"<!>[%f](node %d) unable to start as a PAN coordinator: active channel scan failed -> %s\n",CURRENT_TIME,mac->index_,statusName(status));
00431                 sscsTaskP.taskStatus(sscsTP_startPANCoord) = false;
00432                 return;
00433             }
00434             //select a channel and a PAN ID (for simplicity, we just use the IP address as the PAN ID)
00435             //(it's not an easy task to select a channel and PAN ID in implementation!)
00436             for (i=11;i<27;i++)     //we give priority to 2.4G
00437             if ((T_UnscannedChannels & (1 << i)) == 0)
00438                 break;
00439             if (i >= 27)
00440             for (i=0;i<11;i++)
00441             if ((T_UnscannedChannels & (1 << i)) == 0)
00442                 break;
00443             sscsTaskP.startPANCoord_Channel = i;
00444             //permit association
00445             t_mpib.macAssociationPermit = true;
00446             mac->MLME_SET_request(macAssociationPermit,&t_mpib);
00447             if (txBeacon)
00448             {
00449                 sscsTaskP.taskStep(sscsTP_startPANCoord)++;
00450                 fprintf(stdout,"[%f](node %d) begin to transmit beacons\n",CURRENT_TIME,mac->index_);
00451                 mac->MLME_START_request(mac->index_,i,BO,SO,true,false,false,false);
00452             }
00453             else
00454             {
00455                 mac->isPanCoor(true);
00456                 t_mpib.macCoordExtendedAddress = mac->index_;
00457                 mac->MLME_SET_request(macCoordExtendedAddress,&t_mpib);
00458                 t_ppib.phyCurrentChannel = i;
00459                 mac->phy->PLME_SET_request(phyCurrentChannel,&t_ppib);
00460                 sscsTaskP.taskStatus(sscsTP_startPANCoord) = false;
00461                 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_);
00462                 t_mpib.macPANId = mac->index_;
00463                 mac->MLME_SET_request(macPANId,&t_mpib);
00464                 t_mpib.macBeaconOrder = 15;
00465                 mac->MLME_SET_request(macBeaconOrder,&t_mpib);
00466                 t_mpib.macSuperframeOrder = 15;
00467                 mac->MLME_SET_request(macSuperframeOrder,&t_mpib);
00468             }
00469 #ifdef ZigBeeIF
00470             if (isClusterTree)
00471             {
00472                 assertZBR();
00473                 zbr->dRate = mac->phy->getRate('d');
00474             }
00475 #endif
00476             break;
00477         case 2:
00478             sscsTaskP.taskStatus(sscsTP_startPANCoord) = false;
00479             if (status == m_SUCCESS)
00480                 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_);
00481             else
00482                 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_);
00483             break;
00484         default:
00485             break;
00486     }
00487 }
00488 
00489 void SSCS802_15_4::startDevice(bool isClusterTree,bool isFFD,bool assoPermit,bool txBeacon,UINT_8 BO,UINT_8 SO,bool firsttime,MACenum status)
00490 {
00491     UINT_8 step,scan_BO;
00492     MAC_PIB t_mpib;
00493     SuperframeSpec sfSpec;
00494     UINT_8 ch,fstChannel,fstChannel2_4G;
00495     char tmpstr[30];
00496     int i,k,l,n;
00497         
00498     if (firsttime) checkTaskOverflow(sscsTP_startDevice);
00499 
00500     step = sscsTaskP.taskStep(sscsTP_startDevice);
00501     switch(step)
00502     {
00503         case 0:
00504             fprintf(stdout,"--- startDevice [%d] ---\n",mac->index_);
00505             sscsTaskP.taskStatus(sscsTP_startDevice) = true;
00506             sscsTaskP.taskStep(sscsTP_startDevice)++;
00507             mac->capability.setFFD(isFFD);
00508             sscsTaskP.startDevice_isCluster_Tree = isClusterTree;
00509             sscsTaskP.startDevice_isFFD = isFFD;
00510             sscsTaskP.startDevice_assoPermit = assoPermit;
00511             sscsTaskP.startDevice_txBeacon = txBeacon;
00512             sscsTaskP.startDevice_BO = BO;
00513             sscsTaskP.startDevice_SO = SO;
00514             scan_BO = sscsTaskP.startDevice_BO + 1;
00515             //set FFD
00516             mac->capability.setFFD(isFFD);
00517             //scan the channels
00518             fprintf(stdout,"[%f](node %d) performing active channel scan ...\n",CURRENT_TIME,mac->index_);
00519             mac->MLME_SCAN_request(0x01,SSCS802_15_4::ScanChannels,scan_BO);
00520             break;
00521         case 1:
00522             if (status != m_SUCCESS)
00523             {
00524                 sscsTaskP.taskStatus(sscsTP_startDevice) = false;
00525                 fprintf(stdout,"<!>[%f](node %d) unable to start as a device: active channel scan failed -> %s\n",CURRENT_TIME,mac->index_,statusName(status));
00526                 assoH.start(assoRetryInterval);
00527                 return;
00528             }
00529             //select a PAN and a coordinator to join
00530             fstChannel = 0xff;
00531             fstChannel2_4G = 0xff;
00532             for (i=0;i<T_ResultListSize;i++)
00533             {
00534                 sfSpec.SuperSpec = T_PANDescriptorList[i].SuperframeSpec;
00535                 sfSpec.parse();
00536                 n = updateHListLink(hl_oper_est,&hlistLink1,&hlistLink2,(UINT_16)T_PANDescriptorList[i].CoordAddress_64);
00537                 if ((!sfSpec.AssoPmt)||(!n))
00538                     continue;
00539                 else
00540                 {
00541                     if (T_PANDescriptorList[i].LogicalChannel < 11)
00542                     {
00543                         if (fstChannel == 0xff)
00544                         {
00545                             fstChannel = T_PANDescriptorList[i].LogicalChannel;
00546                             k = i;
00547                         }
00548                     }
00549                     else
00550                     {
00551                         if (fstChannel2_4G == 0xff)
00552                         {
00553                             fstChannel2_4G = T_PANDescriptorList[i].LogicalChannel;
00554                             l = i;
00555                         }
00556                     }
00557                 }
00558             }
00559             if (fstChannel2_4G != 0xff)
00560             {
00561                 ch = fstChannel2_4G;
00562                 i = l;
00563             }
00564             else
00565             {
00566                 ch = fstChannel;
00567                 i = k;
00568             }
00569             if (ch == 0xff)     //cannot find any coordinator for association
00570             {
00571                 sscsTaskP.taskStatus(sscsTP_startDevice) = false;
00572                 fprintf(stdout,"<!>[%f](node %d) no coordinator found for association.\n",CURRENT_TIME,mac->index_);
00573                 assoH.start(assoRetryInterval);
00574                 return;
00575             }
00576             else
00577             {
00578                 //select the least depth for cluster tree association
00579 #ifdef ZigBeeIF
00580                 if (isClusterTree)
00581                 {
00582                     depth = T_PANDescriptorList[i].clusTreeDepth;
00583                     for (m=0;m<T_ResultListSize;m++)
00584                     {
00585                         n = updateHListLink(hl_oper_est,&hlistLink1,&hlistLink2,(UINT_16)T_PANDescriptorList[m].CoordAddress_64);
00586                         if ((ch == T_PANDescriptorList[m].LogicalChannel)&&(n))
00587                         if (T_PANDescriptorList[m].clusTreeDepth < depth)
00588                         {
00589                             depth = T_PANDescriptorList[m].clusTreeDepth;
00590                             i = m;
00591                         }
00592                     }
00593                 }
00594 #endif
00595                 //If the coordinator is in beacon-enabled mode, we may begin to track beacons now.
00596                 //But this is only possible if the network is a one-hop star; otherwise we don't know
00597                 //which coordinator to track, since there may be more than one beaconing coordinators
00598                 //in a device's neighborhood and MLME-SYNC.request() has no parameter telling which 
00599                 //coordinator to track. As this is an optional step, we will not track beacons here.
00600                 t_mpib.macAssociationPermit = assoPermit;
00601                 mac->MLME_SET_request(macAssociationPermit,&t_mpib);
00602                 sscsTaskP.startDevice_Channel = ch;
00603                 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);
00604                 sscsTaskP.taskStep(sscsTP_startDevice)++;
00605                 sscsTaskP.startDevice_panDes = T_PANDescriptorList[i];
00606                 mac->MLME_ASSOCIATE_request(ch,T_PANDescriptorList[i].CoordAddrMode,T_PANDescriptorList[i].CoordPANId,T_PANDescriptorList[i].CoordAddress_64,mac->capability.cap,false);
00607             }
00608             break;
00609         case 2:
00610             sfSpec.SuperSpec = sscsTaskP.startDevice_panDes.SuperframeSpec;
00611             sfSpec.parse();
00612             if (sfSpec.BO != 15)
00613                 strcpy(tmpstr,"beacon enabled");
00614             else
00615                 strcpy(tmpstr,"non-beacon enabled");
00616             if (status != m_SUCCESS)
00617             {
00618                 //reset association permission
00619                 t_mpib.macAssociationPermit = false;
00620                 mac->MLME_SET_request(macAssociationPermit,&t_mpib);
00621                 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);
00622                 assoH.start(assoRetryInterval);
00623                 sscsTaskP.taskStatus(sscsTP_startDevice) = false;
00624 #ifdef ZigBeeIF
00625                 if (isClusterTree)
00626                 {
00627                     assertZBR();
00628                     zbr->sscs_nb_insert(sscsTaskP.startDevice_panDes.CoordAddress_64,NEIGHBOR);
00629                     if (status == m_PAN_at_capacity)
00630                         chkAddUpdHListLink(&hlistLink1,&hlistLink2,(UINT_16)sscsTaskP.startDevice_panDes.CoordAddress_64,0);
00631                 }
00632 #endif
00633             }
00634             else
00635             {
00636                 neverAsso = false;
00637                 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);
00638 #ifdef ZigBeeIF
00639                 if (isClusterTree)
00640                 {
00641                     assertZBR();
00642                     zbr->myDepth = rt_myDepth;
00643                     zbr->myNodeID = rt_myNodeID;
00644                     zbr->myParentNodeID = rt_myParentNodeID;
00645                     zbr->sscs_nb_insert(sscsTaskP.startDevice_panDes.CoordAddress_64,PARENT);
00646                     //chkAddCTAddrLink(zbr->myNodeID,mac->index_);  //too late -- may result in assigning duplicated addresses
00647                     activateCTAddrLink(zbr->myNodeID,mac->index_);
00648                     emptyHListLink(&hlistLink1,&hlistLink2);
00649                 }
00650 #endif
00651                 if (sfSpec.BO != 15)
00652                 {
00653                     fprintf(stdout,"[%f](node %d) begin to synchronize with the coordinator\n",CURRENT_TIME,mac->index_);
00654                     mac->MLME_SYNC_request(sscsTaskP.startDevice_panDes.LogicalChannel,true);
00655                     sscsTaskP.taskStatus(sscsTP_startDevice) = false;
00656                 }
00657                 if (isFFD && txBeacon)
00658                 {
00659                     sscsTaskP.taskStep(sscsTP_startDevice)++;
00660                     fprintf(stdout,"[%f](node %d) begin to transmit beacons\n",CURRENT_TIME,mac->index_);
00661                     mac->MLME_START_request(mac->mpib.macPANId,sscsTaskP.startDevice_Channel,BO,SO,false,false,false,false);
00662                 }
00663                 else
00664                     sscsTaskP.taskStatus(sscsTP_startDevice) = false;
00665 #ifdef ZigBeeIF
00666                 if (isClusterTree)
00667                     zbr->dRate = mac->phy->getRate('d');
00668 #endif
00669             }
00670             break;
00671         case 3:
00672             sscsTaskP.taskStatus(sscsTP_startDevice) = false;
00673             if (status == m_SUCCESS)
00674                 fprintf(stdout,"[%f](node %d) beacon transmission successful [channel:%d] [PAN_ID:%d]\n",CURRENT_TIME,mac->index_,sscsTaskP.startDevice_Channel,mac->mpib.macPANId);
00675             else
00676                 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);
00677             break;
00678         default:
00679             break;
00680     }
00681 }
00682 
00683 //--------------------------------------------------------------------------
00684 
00685 /* The following primitives are availabe from MAC sublayer. You can call these primitives from SSCS or other upper layer
00686  *  void MCPS_DATA_request(UINT_8 SrcAddrMode,UINT_16 SrcPANId,IE3ADDR SrcAddr,
00687  *                 UINT_8 DstAddrMode,UINT_16 DstPANId,IE3ADDR DstAddr,
00688  *                 UINT_8 msduLength,Packet *msdu,UINT_8 msduHandle,UINT_8 TxOptions);
00689  *  void MCPS_DATA_indication(UINT_8 SrcAddrMode,UINT_16 SrcPANId,IE3ADDR SrcAddr,
00690  *                UINT_8 DstAddrMode,UINT_16 DstPANId,IE3ADDR DstAddr,
00691  *                UINT_8 msduLength,Packet *msdu,UINT_8 mpduLinkQuality,
00692  *                bool SecurityUse,UINT_8 ACLEntry);
00693  *  void MCPS_PURGE_request(UINT_8 msduHandle);
00694  *  void MLME_ASSOCIATE_request(UINT_8 LogicalChannel,UINT_8 CoordAddrMode,UINT_16 CoordPANId,IE3ADDR CoordAddress,
00695  *                  UINT_8 CapabilityInformation,bool SecurityEnable);
00696  *  void MLME_ASSOCIATE_response(IE3ADDR DeviceAddress,UINT_16 AssocShortAddress,MACenum status,bool SecurityEnable);
00697  *  void MLME_DISASSOCIATE_request(IE3ADDR DeviceAddress,UINT_8 DisassociateReason,bool SecurityEnable);
00698  *  void MLME_DISASSOCIATE_indication(IE3ADDR DeviceAddress,UINT_8 DisassociateReason,bool SecurityUse,UINT_8 ACLEntry);
00699  *  void MLME_DISASSOCIATE_confirm(MACenum status);
00700  *  void MLME_GET_request(MPIBAenum PIBAttribute);
00701  *  void MLME_GTS_request(UINT_8 GTSCharacteristics,bool SecurityEnable);
00702  *  void MLME_GTS_confirm(UINT_8 GTSCharacteristics,MACenum status);
00703  *  void MLME_GTS_indication(UINT_16 DevAddress,UINT_8 GTSCharacteristics,
00704  *               bool SecurityUse, UINT_8 ACLEntry);
00705  *  void MLME_ORPHAN_indication(IE3ADDR OrphanAddress,bool SecurityUse,UINT_8 ACLEntry);
00706  *  void MLME_ORPHAN_response(IE3ADDR OrphanAddress,UINT_16 ShortAddress,bool AssociatedMember,bool SecurityEnable);
00707  *  void MLME_RESET_request(bool SetDefaultPIB);
00708  *  void MLME_RX_ENABLE_request(bool DeferPermit,UINT_32 RxOnTime,UINT_32 RxOnDuration);
00709  *  void MLME_RX_ENABLE_confirm(MACenum status);
00710  *  void MLME_SCAN_request(UINT_8 ScanType,UINT_32 ScanChannels,UINT_8 ScanDuration);
00711  *  void MLME_SET_request(MPIBAenum PIBAttribute,MAC_PIB *PIBAttributeValue);
00712  *  void MLME_SET_confirm(MACenum status,MPIBAenum PIBAttribute);
00713  *  void MLME_START_request(UINT_16 PANId,UINT_8 LogicalChannel,UINT_8 BeaconOrder,
00714  *              UINT_8 SuperframeOrder,bool PANCoordinator,bool BatteryLifeExtension,
00715  *              bool CoordRealignment,bool SecurityEnable);
00716  *  void MLME_SYNC_request(UINT_8 LogicalChannel, bool TrackBeacon);
00717  *  void MLME_SYNC_LOSS_indication(MACenum LossReason);
00718  *  void MLME_POLL_request(UINT_8 CoordAddrMode,UINT_16 CoordPANId,IE3ADDR CoordAddress,bool SecurityEnable);
00719  *  void MLME_POLL_confirm(MACenum status);
00720  */
00721 
00722 //--------------------------------------------------------------------------
00723 
00724 /* The following commands are available in Tcl scripts -- most of them are the wrap-up of primitives */
00725 int SSCS802_15_4::command(int argc, const char*const* argv)
00726 {
00727     //Commands from Tcl will be one of the following forms:
00728     // --- $node sscs startPANCoord <txBeacon = 1> <beaconOrder = 3> <SuperframeOrder = 3>
00729     // --- $node sscs startDevice <isFFD = 1> <assoPermit = 1> <txBeacon = 0> <beaconOrder = 3> <SuperframeOrder = 3>
00730     // --- $node sscs startCTPANCoord <txBeacon = 1> <beaconOrder = 3> <SuperframeOrder = 3>
00731     // --- $node sscs startCTDevice <isFFD = 1> <assoPermit = 1> <txBeacon = 0> <beaconOrder = 3> <SuperframeOrder = 3>
00732     // --- $node sscs startBeacon <beaconOrder = 3> <SuperframeOrder = 3>
00733     // --- $node sscs stopBeacon
00734     int i;
00735 
00736     if ((strcmp(argv[2], "startPANCoord") == 0)
00737     ||  (strcmp(argv[2], "startCTPANCoord") == 0))
00738     {
00739         i = 2;
00740         t_isCT = (strcmp(argv[i], "startCTPANCoord") == 0);
00741 #ifndef ZigBeeIF
00742         t_isCT = false;
00743 #endif
00744         if (argc == i + 1)
00745         {
00746             t_txBeacon = true;
00747             t_BO = 3;
00748             t_SO = 3;
00749         }
00750         else if (argc == i + 2)
00751         {
00752             t_txBeacon = (atoi(argv[i+1])!=0);
00753             t_BO = 3;
00754             t_SO = 3;
00755         }
00756         else if (argc == i + 3)
00757         {
00758             t_txBeacon = (atoi(argv[i+1])!=0);
00759             t_BO = atoi(argv[i+2]);
00760             t_SO = 3;
00761         }
00762         else
00763         {
00764             t_txBeacon = (atoi(argv[i+1])!=0);
00765             t_BO = atoi(argv[i+2]);
00766             t_SO = atoi(argv[i+3]);
00767         }
00768         startPANCoord(t_isCT,t_txBeacon,t_BO,t_SO,true);
00769     }
00770     else if ((strcmp(argv[2], "startDevice") == 0)
00771     ||       (strcmp(argv[2], "startCTDevice") == 0))
00772     {
00773         i = 2;
00774         t_isCT = (strcmp(argv[i], "startCTDevice") == 0);
00775 #ifndef ZigBeeIF
00776         t_isCT = false;
00777 #endif
00778         if (argc == i + 1)
00779         {
00780             t_isFFD = true;
00781             t_assoPermit = true;
00782             t_txBeacon = false;
00783             t_BO = 3;
00784             t_SO = 3;
00785         }
00786         else if (argc == i + 2)
00787         {
00788             t_isFFD = (atoi(argv[i+1])!=0);
00789             t_assoPermit = true;
00790             t_txBeacon = false;
00791             t_BO = 3;
00792             t_SO = 3;
00793         }
00794         else if (argc == i + 3)
00795         {
00796             t_isFFD = (atoi(argv[i+1])!=0);
00797             t_assoPermit = (atoi(argv[i+2])!=0);
00798             t_txBeacon = false;
00799             t_BO = 3;
00800             t_SO = 3;
00801         }
00802 
00803         else if (argc == i + 4)
00804         {
00805             t_isFFD = (atoi(argv[i+1])!=0);
00806             t_assoPermit = (atoi(argv[i+2])!=0);
00807             t_txBeacon = (atoi(argv[i+3])!=0);
00808             t_BO = 3;
00809             t_SO = 3;
00810         }
00811         else if (argc == i + 5)
00812         {
00813             t_isFFD = (atoi(argv[i+1])!=0);
00814             t_assoPermit = (atoi(argv[i+2])!=0);
00815             t_txBeacon = (atoi(argv[i+3])!=0);
00816             t_BO = atoi(argv[i+4]);
00817             t_SO = 3;
00818         }
00819         else
00820         {
00821             t_isFFD = (atoi(argv[i+1])!=0);
00822             t_assoPermit = (atoi(argv[i+2])!=0);
00823             t_txBeacon = (atoi(argv[i+3])!=0);
00824             t_BO = atoi(argv[i+4]);
00825             t_SO = atoi(argv[i+5]);
00826         }
00827         if (!t_isFFD)
00828             t_assoPermit = false;
00829         startDevice(t_isCT,t_isFFD,t_assoPermit,t_txBeacon,t_BO,t_SO,true);
00830     }
00831     else if (strcmp(argv[2], "startBeacon") == 0)
00832     {
00833         if (argc == 3)
00834         {
00835             t_BO = 3;
00836             t_SO = 3;
00837         }
00838         else if (argc == 4)
00839         {
00840             t_BO = atoi(argv[3]);
00841             t_SO = 3;
00842         }
00843         else
00844         {
00845             t_BO = atoi(argv[3]);
00846             t_SO = atoi(argv[4]);
00847         }
00848         mac->phy->PLME_GET_request(phyCurrentChannel);
00849         mac->MLME_START_request(mac->mpib.macPANId,mac->tmp_ppib.phyCurrentChannel,t_BO,t_SO,mac->isPANCoor,false,false,false);
00850     }
00851     else if (strcmp(argv[2], "stopBeacon") == 0)
00852     {
00853         mac->phy->PLME_GET_request(phyCurrentChannel);
00854         mac->MLME_START_request(mac->mpib.macPANId,mac->tmp_ppib.phyCurrentChannel,15,15,mac->isPANCoor,false,false,false);
00855     }
00856 
00857     return TCL_OK;
00858 }
00859 
00860 #ifdef ZigBeeIF
00861 void SSCS802_15_4::assertZBR(void)
00862 {
00863     if (!zbr)
00864         zbr = getZBRLink(mac->index_);
00865     assert(zbr);
00866     zbr->dRate = mac->phy->getRate('d');
00867 }
00868 
00869 int SSCS802_15_4::RNType(void)
00870 {
00871     if (!t_isCT)
00872         return 1;
00873 
00874     assertZBR();
00875 
00876     return zbr->RNType;
00877 }
00878 
00879 void SSCS802_15_4::setGetClusTreePara(char setGet,Packet *p)
00880 {
00881     hdr_lrwpan *wph = HDR_LRWPAN(p);
00882 
00883     if (!t_isCT)
00884         return;
00885 
00886     assertZBR();
00887     if (setGet == 's')
00888     {
00889         wph->clusTreeDepth = zbr->myDepth;
00890         wph->clusTreeParentNodeID = zbr->myNodeID;
00891     }
00892     else
00893     {
00894         rt_myDepth = wph->clusTreeDepth + 1;
00895         rt_myParentNodeID = wph->clusTreeParentNodeID;
00896     }
00897 }
00898 #endif
00899 
00900 // End of file: p802_15_4sscs.cc

Generated on Tue Mar 6 16:47:48 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6