###############################################################################
#                                                                             #
# IAR 8051 C/C++ Compiler V7.30B/W32                    12/Jun/2010  16:11:08 #
# Copyright 2004-2007 IAR Systems. All rights reserved.                       #
#                                                                             #
#    Core               =  plain                                              #
#    Code model         =  banked                                             #
#    Data model         =  large                                              #
#    Calling convention =  xdata reentrant                                    #
#    Constant location  =  data                                               #
#    Dptr setup         =  1,16                                               #
#    Source file        =  C:\Texas Instruments\ZStack-1.4.3-1.2.1\Components #
#                          \stack\zdo\ZDSecMgr.c                              #
#    Command line       =  -f "C:\Texas Instruments\ZStack-1.4.3-1.2.1\Projec #
#                          ts\zstack\Samples\Location\CC2430DB\..\..\..\Tools #
#                          \CC2430DB\f8wRouter.cfg" (-DCPU32MHZ               #
#                          -DFORCE_MAC_NEAR -DROOT=__near_func                #
#                          -DMAC_CFG_APP_PENDING_QUEUE=TRUE -DRTR_NWK         #
#                          -DBLINK_LEDS "-DCONST=const __code"                #
#                          -DGENERIC=__generic) -f "C:\Texas                  #
#                          Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Sam #
#                          ples\Location\CC2430DB\..\..\..\Tools\CC2430DB\f8w #
#                          Config.cfg" (-DSECURE=1 -DDEFAULT_CHANLIST=0x04000 #
#                          000 -DZDAPP_CONFIG_PAN_ID=0x00FF                   #
#                          -DNWK_START_DELAY=100 -DEXTENDED_JOINING_RANDOM_MA #
#                          SK=0x007F -DBEACON_REQUEST_DELAY=100               #
#                          -DBEACON_REQ_DELAY_MASK=0x00FF                     #
#                          -DROUTE_EXPIRY_TIME=30 -DAPSC_ACK_WAIT_DURATION_PO #
#                          LLED=3000 -DNWK_INDIRECT_MSG_TIMEOUT=7             #
#                          -DMAX_RREQ_ENTRIES=10 -DAPSC_MAX_FRAME_RETRIES=3   #
#                          -DNWK_MAX_DATA_RETRIES=2                           #
#                          -DMAX_POLL_FAILURE_RETRIES=2 -DMAX_BCAST=9         #
#                          -DAPS_MAX_GROUPS=16 -DMAX_RTG_ENTRIES=20           #
#                          -DNWK_MAX_BINDING_ENTRIES=10                       #
#                          -DMAX_BINDING_CLUSTER_IDS=5 "-DDEFAULT_KEY={0x02,  #
#                          0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, 0x00,    #
#                          0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0D}"         #
#                          -DRFD_RCVC_ALWAYS_ON=FALSE -DPOLL_RATE=1000        #
#                          -DQUEUED_POLL_RATE=100 -DRESPONSE_POLL_RATE=100)   #
#                          -DREJOIN_POLL_RATE=440 "C:\Texas                   #
#                          Instruments\ZStack-1.4.3-1.2.1\Components\stack\zd #
#                          o\ZDSecMgr.c" -D CC2430EB -D LOCATION_REFNODE -D   #
#                          xNV_RESTORE -D ZTOOL_P1 -D MT_TASK -D              #
#                          POWER_SAVING -D HAL_UART_BIG_TX_BUF=1 -D           #
#                          SPI_MGR_DEFAULT_MAX_TX_BUFF=1024 -D                #
#                          SPI_MGR_DEFAULT_OVERFLOW=1 -lC "C:\Texas           #
#                          Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Sam #
#                          ples\Location\CC2430DB\RefNode\List\" -lA          #
#                          "C:\Texas Instruments\ZStack-1.4.3-1.2.1\Projects\ #
#                          zstack\Samples\Location\CC2430DB\RefNode\List\"    #
#                          --diag_suppress Pe001,Pa010 --diag_remark pe550    #
#                          -o "C:\Texas Instruments\ZStack-1.4.3-1.2.1\Projec #
#                          ts\zstack\Samples\Location\CC2430DB\RefNode\Obj\"  #
#                          -e --require_prototypes -z9 --no_code_motion       #
#                          --debug --core=plain --dptr=16,1                   #
#                          --data_model=large --code_model=banked             #
#                          --calling_convention=xdata_reentrant               #
#                          --place_constants=data --nr_virtual_regs 8 -I      #
#                          "C:\Texas Instruments\ZStack-1.4.3-1.2.1\Projects\ #
#                          zstack\Samples\Location\CC2430DB\" -I "C:\Texas    #
#                          Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Sam #
#                          ples\Location\CC2430DB\..\SOURCE\" -I "C:\Texas    #
#                          Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Sam #
#                          ples\Location\CC2430DB\..\..\..\ZMAIN\TI2430DB\"   #
#                          -I "C:\Texas Instruments\ZStack-1.4.3-1.2.1\Projec #
#                          ts\zstack\Samples\Location\CC2430DB\..\..\..\..\.. #
#                          \COMPONENTS\MT\" -I "C:\Texas                      #
#                          Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Sam #
#                          ples\Location\CC2430DB\..\..\..\..\..\COMPONENTS\H #
#                          AL\INCLUDE\" -I "C:\Texas                          #
#                          Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Sam #
#                          ples\Location\CC2430DB\..\..\..\..\..\COMPONENTS\H #
#                          AL\TARGET\CC2430BB\" -I "C:\Texas                  #
#                          Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Sam #
#                          ples\Location\CC2430DB\..\..\..\..\..\COMPONENTS\O #
#                          SAL\MCU\CCSOC\" -I "C:\Texas                       #
#                          Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Sam #
#                          ples\Location\CC2430DB\..\..\..\..\..\COMPONENTS\O #
#                          SAL\INCLUDE\" -I "C:\Texas                         #
#                          Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Sam #
#                          ples\Location\CC2430DB\..\..\..\..\..\COMPONENTS\S #
#                          TACK\AF\" -I "C:\Texas Instruments\ZStack-1.4.3-1. #
#                          2.1\Projects\zstack\Samples\Location\CC2430DB\..\. #
#                          .\..\..\..\COMPONENTS\STACK\NWK\" -I "C:\Texas     #
#                          Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Sam #
#                          ples\Location\CC2430DB\..\..\..\..\..\COMPONENTS\S #
#                          TACK\SEC\" -I "C:\Texas Instruments\ZStack-1.4.3-1 #
#                          .2.1\Projects\zstack\Samples\Location\CC2430DB\..\ #
#                          ..\..\..\..\COMPONENTS\STACK\SYS\" -I "C:\Texas    #
#                          Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Sam #
#                          ples\Location\CC2430DB\..\..\..\..\..\COMPONENTS\S #
#                          TACK\ZDO\" -I "C:\Texas Instruments\ZStack-1.4.3-1 #
#                          .2.1\Projects\zstack\Samples\Location\CC2430DB\..\ #
#                          ..\..\..\..\COMPONENTS\ZMAC\F8W\" -I "C:\Texas     #
#                          Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Sam #
#                          ples\Location\CC2430DB\..\..\..\..\..\COMPONENTS\Z #
#                          MAC\" -I "C:\Texas Instruments\ZStack-1.4.3-1.2.1\ #
#                          Projects\zstack\Samples\Location\CC2430DB\..\..\.. #
#                          \..\..\COMPONENTS\SERVICES\SADDR\" -I "C:\Texas    #
#                          Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Sam #
#                          ples\Location\CC2430DB\..\..\..\..\..\COMPONENTS\S #
#                          ERVICES\SDATA\" -I "C:\Texas                       #
#                          Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Sam #
#                          ples\Location\CC2430DB\..\..\..\..\..\COMPONENTS\M #
#                          AC\INCLUDE\" -I "C:\Texas                          #
#                          Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Sam #
#                          ples\Location\CC2430DB\..\..\..\..\..\COMPONENTS\M #
#                          AC\HIGH_LEVEL\" -I "C:\Texas                       #
#                          Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Sam #
#                          ples\Location\CC2430DB\..\..\..\..\..\COMPONENTS\M #
#                          AC\LOW_LEVEL\SRF03\" -I "C:\Texas                  #
#                          Instruments\ZStack-1.4.3-1.2.1\Projects\zstack\Sam #
#                          ples\Location\CC2430DB\..\..\..\..\..\COMPONENTS\M #
#                          AC\LOW_LEVEL\SRF03\SINGLE_CHIP\" -I "C:\Program    #
#                          Files\IAR Systems\Embedded Workbench 4.0           #
#                          Evaluation version\8051\INC\" -I "C:\Program       #
#                          Files\IAR Systems\Embedded Workbench 4.0           #
#                          Evaluation version\8051\INC\CLIB\"                 #
#    List file          =  C:\Texas Instruments\ZStack-1.4.3-1.2.1\Projects\z #
#                          stack\Samples\Location\CC2430DB\RefNode\List\ZDSec #
#                          Mgr.lst                                            #
#    Object file        =  C:\Texas Instruments\ZStack-1.4.3-1.2.1\Projects\z #
#                          stack\Samples\Location\CC2430DB\RefNode\Obj\ZDSecM #
#                          gr.r51                                             #
#                                                                             #
#                                                                             #
###############################################################################

C:\Texas Instruments\ZStack-1.4.3-1.2.1\Components\stack\zdo\ZDSecMgr.c
      1          /**************************************************************************************************
      2            Filename:       ZDSecMgr.c
      3            Revised:        $Date: 2007-12-07 14:27:57 -0800 (Fri, 07 Dec 2007) $
      4            Revision:       $Revision: 16045 $
      5          
      6            Description:    The ZigBee Device Security Manager.
      7          
      8          
      9            Copyright 2005-2007 Texas Instruments Incorporated. All rights reserved.
     10          
     11            IMPORTANT: Your use of this Software is limited to those specific rights
     12            granted under the terms of a software license agreement between the user
     13            who downloaded the software, his/her employer (which must be your employer)
     14            and Texas Instruments Incorporated (the "License").  You may not use this
     15            Software unless you agree to abide by the terms of the License. The License
     16            limits your use, and you acknowledge, that the Software may not be modified,
     17            copied or distributed unless embedded on a Texas Instruments microcontroller
     18            or used solely and exclusively in conjunction with a Texas Instruments radio
     19            frequency transceiver, which is integrated into your product.  Other than for
     20            the foregoing purpose, you may not use, reproduce, copy, prepare derivative
     21            works of, modify, distribute, perform, display or sell this Software and/or
     22            its documentation for any purpose.
     23          
     24            YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
     25            PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, 
     26            INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, 
     27            NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
     28            TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
     29            NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
     30            LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
     31            INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
     32            OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
     33            OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
     34            (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
     35          
     36            Should you have any questions regarding your right to use this Software,
     37            contact Texas Instruments Incorporated at www.TI.com. 
     38          **************************************************************************************************/
     39          
     40          #ifdef __cplusplus
     41          extern "C"
     42          {
     43          #endif
     44          
     45          /******************************************************************************
     46           * INCLUDES
     47           */
     48          #include "ZComdef.h"
     49          #include "osal.h"
     50          #include "ZGlobals.h"
     51          #include "ssp.h"
     52          #include "nwk_globals.h"
     53          #include "nwk.h"
     54          #include "NLMEDE.h"
     55          #include "AddrMgr.h"
     56          #include "AssocList.h"
     57          #include "APSMEDE.h"
     58          #include "AF.h"
     59          #include "ZDConfig.h"
     60          #include "ZDApp.h"
     61          #include "ZDSecMgr.h"
     62          
     63          /******************************************************************************
     64           * CONSTANTS
     65           */
     66          // maximum number of devices managed by this Security Manager
     67          #define ZDSECMGR_DEVICE_MAX 3
     68          
     69          // total number of preconfigured devices (EXT address, MASTER key)
     70          #define ZDSECMGR_PRECONFIG_MAX ZDSECMGR_DEVICE_MAX
     71          
     72          // maximum number of MASTER keys this device may hold
     73          #define ZDSECMGR_MASTERKEY_MAX ZDSECMGR_DEVICE_MAX
     74          
     75          // maximum number of LINK keys this device may store
     76          #define ZDSECMGR_ENTRY_MAX ZDSECMGR_DEVICE_MAX
     77          
     78          // total number of devices under control - authentication, SKKE, etc.
     79          #define ZDSECMGR_CTRL_MAX ZDSECMGR_DEVICE_MAX
     80          
     81          // total number of restricted devices
     82          #define ZDSECMGR_RESTRICTED_DEVICES 2
     83          
     84          #define ZDSECMGR_CTRL_NONE       0
     85          #define ZDSECMGR_CTRL_INIT       1
     86          #define ZDSECMGR_CTRL_TK_MASTER  2
     87          #define ZDSECMGR_CTRL_SKKE_INIT  3
     88          #define ZDSECMGR_CTRL_SKKE_WAIT  4
     89          #define ZDSECMGR_CTRL_SKKE_DONE  5
     90          #define ZDSECMGR_CTRL_TK_NWK     6
     91          
     92          #define ZDSECMGR_CTRL_BASE_CNTR      1
     93          #define ZDSECMGR_CTRL_SKKE_INIT_CNTR 10
     94          #define ZDSECMGR_CTRL_SKKE_WAIT_CNTR 100
     95          #define ZDSECMGR_CTRL_TK_NWK_CNTR    10
     96          
     97          // set SKKE slot maximum
     98          #define ZDSECMGR_SKKE_SLOT_MAX 1
     99          
    100          // APSME Stub Implementations
    101          #define ZDSecMgrMasterKeyGet   APSME_MasterKeyGet
    102          #define ZDSecMgrLinkKeySet     APSME_LinkKeySet
    103          #define ZDSecMgrLinkKeyDataGet APSME_LinkKeyDataGet
    104          #define ZDSecMgrKeyFwdToChild  APSME_KeyFwdToChild
    105          
    106          /******************************************************************************
    107           * TYPEDEFS
    108           */
    109          typedef struct
    110          {
    111            uint8 extAddr[Z_EXTADDR_LEN];
    112            uint8 key[SEC_KEY_LEN];
    113          } ZDSecMgrPreConfigData_t;
    114          
    115          typedef struct
    116          {
    117            uint16 ami;
    118            uint8  key[SEC_KEY_LEN];
    119          } ZDSecMgrMasterKeyData_t;
    120          
    121          //should match APSME_LinkKeyData_t;
    122          typedef struct
    123          {
    124            uint8               key[SEC_KEY_LEN];
    125            APSME_LinkKeyData_t apsmelkd;
    126          } ZDSecMgrLinkKeyData_t;
    127          
    128          typedef struct
    129          {
    130            uint16                ami;
    131            ZDSecMgrLinkKeyData_t lkd;
    132          } ZDSecMgrEntry_t;
    133          
    134          typedef struct
    135          {
    136            ZDSecMgrEntry_t* entry;
    137            uint16           parentAddr;
    138            uint8            secure;
    139            uint8            state;
    140            uint8            cntr;
    141            //uint8          next;
    142          } ZDSecMgrCtrl_t;
    143          
    144          typedef struct
    145          {
    146            uint16          nwkAddr;
    147            uint8*          extAddr;
    148            uint16          parentAddr;
    149            uint8           secure;
    150            ZDSecMgrCtrl_t* ctrl;
    151          } ZDSecMgrDevice_t;
    152          
    153          /******************************************************************************
    154           * LOCAL VARIABLES
    155           */
    156          #if defined ( ZDSECMGR_SECURE ) && defined ( ZDO_COORDINATOR )
    157          uint8 ZDSecMgrRestrictedDevices[ZDSECMGR_RESTRICTED_DEVICES][Z_EXTADDR_LEN] =
    158          {
    159            { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
    160            { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
    161          };
    162          #endif // defined ( ZDSECMGR_SECURE ) && defined ( ZDO_COORDINATOR )
    163          
    164          #if defined ( ZDSECMGR_COMMERCIAL )
    165          #if ( ZDSECMGR_PRECONFIG_MAX != 0 )
    166          const ZDSecMgrPreConfigData_t ZDSecMgrPreConfigData[ZDSECMGR_PRECONFIG_MAX] =
    167          {
    168            //---------------------------------------------------------------------------
    169            // DEVICE A
    170            //---------------------------------------------------------------------------
    171            {
    172              // extAddr
    173              {0x7C,0x01,0x12,0x13,0x14,0x15,0x16,0x17},
    174          
    175              // key
    176              {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    177               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
    178            },
    179            //---------------------------------------------------------------------------
    180            // DEVICE B
    181            //---------------------------------------------------------------------------
    182            {
    183              // extAddr
    184              {0x84,0x03,0x00,0x00,0x00,0x4B,0x12,0x00},
    185          
    186              // key
    187              {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    188               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
    189            },
    190            //---------------------------------------------------------------------------
    191            // DEVICE C
    192            //---------------------------------------------------------------------------
    193            {
    194              // extAddr
    195              {0x3E,0x01,0x12,0x13,0x14,0x15,0x16,0x17},
    196          
    197              // key
    198              {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    199               0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
    200            },
    201          };
    202          #endif // ( ZDSECMGR_PRECONFIG_MAX != 0 )
    203          #endif // defined ( ZDSECMGR_COMMERCIAL )
    204          
    205          #if defined ( ZDSECMGR_COMMERCIAL )
    206          ZDSecMgrMasterKeyData_t* ZDSecMgrMasterKeyData = NULL;
    207          ZDSecMgrEntry_t*         ZDSecMgrEntries       = NULL;
    208          ZDSecMgrCtrl_t*          ZDSecMgrCtrlData      = NULL;
    209          void ZDSecMgrAddrMgrUpdate( uint16 ami, uint16 nwkAddr );
    210          void ZDSecMgrAddrMgrCB( uint8 update, AddrMgrEntry_t* newEntry, AddrMgrEntry_t* oldEntry );
    211          #endif // defined ( ZDSECMGR_COMMERCIAL )
    212          
    213          #if defined ( ZDSECMGR_SECURE ) && defined ( ZDO_COORDINATOR )
    214          uint8 ZDSecMgrPermitJoiningEnabled;
    215          uint8 ZDSecMgrPermitJoiningTimed;
    216          #endif // defined ( ZDSECMGR_SECURE ) && defined ( ZDO_COORDINATOR )
    217          
    218          #if defined ( ZDSECMGR_SECURE )
    219          /******************************************************************************
    220           * PRIVATE FUNCTIONS
    221           *
    222           *   ZDSecMgrMasterKeyInit
    223           *   ZDSecMgrExtAddrLookup
    224           *   ZDSecMgrExtAddrStore
    225           *   ZDSecMgrMasterKeyLookup
    226           *   ZDSecMgrMasterKeyStore
    227           *   ZDSecMgrEntryInit
    228           *   ZDSecMgrEntryLookup
    229           *   ZDSecMgrEntryLookupAMI
    230           *   ZDSecMgrEntryLookupExt
    231           *   ZDSecMgrEntryFree
    232           *   ZDSecMgrEntryNew
    233           *   ZDSecMgrCtrlInit
    234           *   ZDSecMgrCtrlRelease
    235           *   ZDSecMgrCtrlLookup
    236           *   ZDSecMgrCtrlSet
    237           *   ZDSecMgrCtrlAdd
    238           *   ZDSecMgrCtrlTerm
    239           *   ZDSecMgrCtrlReset
    240           *   ZDSecMgrMasterKeyLoad
    241           *   ZDSecMgrAppKeyGet
    242           *   ZDSecMgrAppKeyReq
    243           *   ZDSecMgrEstablishKey
    244           *   ZDSecMgrSendMasterKey
    245           *   ZDSecMgrSendNwkKey
    246           *   ZDSecMgrDeviceEntryRemove
    247           *   ZDSecMgrDeviceEntryAdd
    248           *   ZDSecMgrDeviceCtrlHandler
    249           *   ZDSecMgrDeviceCtrlSetup
    250           *   ZDSecMgrDeviceCtrlUpdate
    251           *   ZDSecMgrDeviceRemove
    252           *   ZDSecMgrDeviceValidateSKKE
    253           *   ZDSecMgrDeviceValidateRM
    254           *   ZDSecMgrDeviceValidateCM
    255           *   ZDSecMgrDeviceValidate
    256           *   ZDSecMgrDeviceJoin
    257           *   ZDSecMgrDeviceJoinDirect
    258           *   ZDSecMgrDeviceJoinFwd
    259           *   ZDSecMgrDeviceNew
    260           *   ZDSecMgrAssocDeviceAuth
    261           */
    262          //-----------------------------------------------------------------------------
    263          // master key data
    264          //-----------------------------------------------------------------------------
    265          void ZDSecMgrMasterKeyInit( void );
    266          
    267          //-----------------------------------------------------------------------------
    268          // EXT address management
    269          //-----------------------------------------------------------------------------
    270          ZStatus_t ZDSecMgrExtAddrLookup( uint8* extAddr, uint16* ami );
    271          ZStatus_t ZDSecMgrExtAddrStore( uint8* extAddr, uint16* ami );
    272          
    273          //-----------------------------------------------------------------------------
    274          // MASTER key data
    275          //-----------------------------------------------------------------------------
    276          ZStatus_t ZDSecMgrMasterKeyLookup( uint16 ami, uint8** key );
    277          ZStatus_t ZDSecMgrMasterKeyStore( uint16 ami, uint8* key );
    278          
    279          //-----------------------------------------------------------------------------
    280          // entry data
    281          //-----------------------------------------------------------------------------
    282          void ZDSecMgrEntryInit( void );
    283          ZStatus_t ZDSecMgrEntryLookup( uint16 nwkAddr, ZDSecMgrEntry_t** entry );
    284          ZStatus_t ZDSecMgrEntryLookupAMI( uint16 ami, ZDSecMgrEntry_t** entry );
    285          ZStatus_t ZDSecMgrEntryLookupExt( uint8* extAddr, ZDSecMgrEntry_t** entry );
    286          void ZDSecMgrEntryFree( ZDSecMgrEntry_t* entry );
    287          ZStatus_t ZDSecMgrEntryNew( ZDSecMgrEntry_t** entry );
    288          
    289          //-----------------------------------------------------------------------------
    290          // control data
    291          //-----------------------------------------------------------------------------
    292          void ZDSecMgrCtrlInit( void );
    293          void ZDSecMgrCtrlRelease( ZDSecMgrCtrl_t* ctrl );
    294          void ZDSecMgrCtrlLookup( ZDSecMgrEntry_t* entry, ZDSecMgrCtrl_t** ctrl );
    295          void ZDSecMgrCtrlSet( ZDSecMgrDevice_t* device,
    296                                ZDSecMgrEntry_t*  entry,
    297                                ZDSecMgrCtrl_t*   ctrl );
    298          ZStatus_t ZDSecMgrCtrlAdd( ZDSecMgrDevice_t* device, ZDSecMgrEntry_t*  entry );
    299          void ZDSecMgrCtrlTerm( ZDSecMgrEntry_t* entry );
    300          ZStatus_t ZDSecMgrCtrlReset( ZDSecMgrDevice_t* device,
    301                                       ZDSecMgrEntry_t*  entry );
    302          
    303          //-----------------------------------------------------------------------------
    304          // key support
    305          //-----------------------------------------------------------------------------
    306          void ZDSecMgrMasterKeyLoad( uint16 nwkAddr, uint8* extAddr, uint8* key );
    307          ZStatus_t ZDSecMgrAppKeyGet( uint16  initNwkAddr,
    308                                       uint8*  initExtAddr,
    309                                       uint16  partNwkAddr,
    310                                       uint8*  partExtAddr,
    311                                       uint8** key,
    312                                       uint8*  keyType );
    313          void ZDSecMgrAppKeyReq( ZDO_RequestKeyInd_t* ind );
    314          ZStatus_t ZDSecMgrEstablishKey( ZDSecMgrDevice_t* device );
    315          ZStatus_t ZDSecMgrSendMasterKey( ZDSecMgrDevice_t* device );
    316          ZStatus_t ZDSecMgrSendNwkKey( ZDSecMgrDevice_t* device );
    317          
    318          //-----------------------------------------------------------------------------
    319          // device entry
    320          //-----------------------------------------------------------------------------
    321          void ZDSecMgrDeviceEntryRemove( ZDSecMgrEntry_t* entry );
    322          ZStatus_t ZDSecMgrDeviceEntryAdd( ZDSecMgrDevice_t* device, uint16 ami );
    323          
    324          //-----------------------------------------------------------------------------
    325          // device control
    326          //-----------------------------------------------------------------------------
    327          void ZDSecMgrDeviceCtrlHandler( ZDSecMgrDevice_t* device );
    328          void ZDSecMgrDeviceCtrlSetup( ZDSecMgrDevice_t* device );
    329          void ZDSecMgrDeviceCtrlUpdate( uint8* extAddr, uint8 state );
    330          
    331          //-----------------------------------------------------------------------------
    332          // device management
    333          //-----------------------------------------------------------------------------
    334          void ZDSecMgrDeviceRemove( ZDSecMgrDevice_t* device );
    335          ZStatus_t ZDSecMgrDeviceValidateSKKE( ZDSecMgrDevice_t* device );
    336          ZStatus_t ZDSecMgrDeviceValidateRM( ZDSecMgrDevice_t* device );
    337          ZStatus_t ZDSecMgrDeviceValidateCM( ZDSecMgrDevice_t* device );
    338          ZStatus_t ZDSecMgrDeviceValidate( ZDSecMgrDevice_t* device );
    339          ZStatus_t ZDSecMgrDeviceJoin( ZDSecMgrDevice_t* device );
    340          ZStatus_t ZDSecMgrDeviceJoinDirect( ZDSecMgrDevice_t* device );
    341          ZStatus_t ZDSecMgrDeviceJoinFwd( ZDSecMgrDevice_t* device );
    342          ZStatus_t ZDSecMgrDeviceNew( ZDSecMgrDevice_t* device );
    343          
    344          //-----------------------------------------------------------------------------
    345          // association management
    346          //-----------------------------------------------------------------------------
    347          void ZDSecMgrAssocDeviceAuth( associated_devices_t* assoc );
    348          
    349          #if defined ( ZDSECMGR_COMMERCIAL )
    350          /******************************************************************************
    351           * @fn          ZDSecMgrMasterKeyInit                     ]
    352           *
    353           * @brief       Initialize master key data.
    354           *
    355           * @param       none
    356           *
    357           * @return      none
    358           */
    359          void ZDSecMgrMasterKeyInit( void )
    360          {
    361            uint16         index;
    362            uint16         size;
    363            AddrMgrEntry_t entry;
    364          
    365          
    366            // allocate MASTER key data
    367            size = (short)( sizeof(ZDSecMgrMasterKeyData_t) * ZDSECMGR_MASTERKEY_MAX );
    368          
    369            ZDSecMgrMasterKeyData = osal_mem_alloc( size );
    370          
    371            // initialize MASTER key data
    372            if ( ZDSecMgrMasterKeyData != NULL )
    373            {
    374              for ( index = 0; index < ZDSECMGR_MASTERKEY_MAX; index++ )
    375              {
    376                ZDSecMgrMasterKeyData[index].ami = INVALID_NODE_ADDR;
    377              }
    378          
    379              // check if preconfigured keys are enabled
    380              //-------------------------------------------------------------------------
    381              #if ( ZDSECMGR_PRECONFIG_MAX != 0 )
    382              //-------------------------------------------------------------------------
    383              if ( zgPreConfigKeys == TRUE )
    384              {
    385                // sync configured data
    386                entry.user = ADDRMGR_USER_SECURITY;
    387          
    388                for ( index = 0; index < ZDSECMGR_PRECONFIG_MAX; index++ )
    389                {
    390                  // check for Address Manager entry
    391                  AddrMgrExtAddrSet( entry.extAddr,
    392                                     (uint8*)ZDSecMgrPreConfigData[index].extAddr );
    393          
    394                  if ( AddrMgrEntryLookupExt( &entry ) != TRUE )
    395                  {
    396                    // update Address Manager
    397                    AddrMgrEntryUpdate( &entry );
    398                  }
    399          
    400                  if ( entry.index != INVALID_NODE_ADDR )
    401                  {
    402                    // sync MASTER keys with Address Manager index
    403                    ZDSecMgrMasterKeyData[index].ami = entry.index;
    404          
    405                    osal_cpyExtAddr( ZDSecMgrMasterKeyData[index].key,
    406                                     (void*)ZDSecMgrPreConfigData[index].key );
    407                  }
    408                }
    409              }
    410              //-------------------------------------------------------------------------
    411              #endif // ( ZDSECMGR_PRECONFIG_MAX != 0 )
    412              //-------------------------------------------------------------------------
    413            }
    414          }
    415          #endif // defined ( ZDSECMGR_COMMERCIAL )
    416          
    417          #if defined ( ZDSECMGR_COMMERCIAL )
    418          /******************************************************************************
    419           * @fn          ZDSecMgrExtAddrLookup
    420           *
    421           * @brief       Lookup index for specified EXT address.
    422           *
    423           * @param       extAddr - [in] EXT address
    424           * @param       ami     - [out] Address Manager index
    425           *
    426           * @return      ZStatus_t
    427           */
    428          ZStatus_t ZDSecMgrExtAddrLookup( uint8* extAddr, uint16* ami )
    429          {
    430            ZStatus_t      status;
    431            AddrMgrEntry_t entry;
    432          
    433          
    434            // lookup entry
    435            entry.user = ADDRMGR_USER_SECURITY;
    436            AddrMgrExtAddrSet( entry.extAddr, extAddr );
    437          
    438            if ( AddrMgrEntryLookupExt( &entry ) == TRUE )
    439            {
    440              // return successful results
    441              *ami   = entry.index;
    442              status = ZSuccess;
    443            }
    444            else
    445            {
    446              // return failed results
    447              *ami   = entry.index;
    448              status = ZNwkUnknownDevice;
    449            }
    450          
    451            return status;
    452          }
    453          #endif // defined ( ZDSECMGR_COMMERCIAL )
    454          
    455          #if defined ( ZDSECMGR_COMMERCIAL )
    456          /******************************************************************************
    457           * @fn          ZDSecMgrExtAddrStore
    458           *
    459           * @brief       Store EXT address.
    460           *
    461           * @param       extAddr - [in] EXT address
    462           * @param       ami     - [out] Address Manager index
    463           *
    464           * @return      ZStatus_t
    465           */
    466          ZStatus_t ZDSecMgrExtAddrStore( uint8* extAddr, uint16* ami )
    467          {
    468            ZStatus_t      status;
    469            AddrMgrEntry_t entry;
    470          
    471          
    472            // add entry
    473            entry.user    = ADDRMGR_USER_SECURITY;
    474            entry.nwkAddr = INVALID_NODE_ADDR;
    475            AddrMgrExtAddrSet( entry.extAddr, extAddr );
    476          
    477            if ( AddrMgrEntryUpdate( &entry ) == TRUE )
    478            {
    479              // return successful results
    480              *ami   = entry.index;
    481              status = ZSuccess;
    482            }
    483            else
    484            {
    485              // return failed results
    486              *ami   = entry.index;
    487              status = ZNwkUnknownDevice;
    488            }
    489          
    490            return status;
    491          }
    492          #endif // defined ( ZDSECMGR_COMMERCIAL )
    493          
    494          #if defined ( ZDSECMGR_COMMERCIAL )
    495          /******************************************************************************
    496           * @fn          ZDSecMgrMasterKeyLookup
    497           *
    498           * @brief       Lookup MASTER key for specified address index.
    499           *
    500           * @param       ami - [in] Address Manager index
    501           * @param       key - [out] valid MASTER key
    502           *
    503           * @return      ZStatus_t
    504           */
    505          ZStatus_t ZDSecMgrMasterKeyLookup( uint16 ami, uint8** key )
    506          {
    507            ZStatus_t status;
    508            uint16    index;
    509          
    510          
    511            // initialize results
    512            *key   = NULL;
    513            status = ZNwkUnknownDevice;
    514          
    515            // verify data is available
    516            if ( ZDSecMgrMasterKeyData != NULL )
    517            {
    518              for ( index = 0; index < ZDSECMGR_MASTERKEY_MAX ; index++ )
    519              {
    520                if ( ZDSecMgrMasterKeyData[index].ami == ami )
    521                {
    522                  // return successful results
    523                  *key   = ZDSecMgrMasterKeyData[index].key;
    524                  status = ZSuccess;
    525          
    526                  // break from loop
    527                  index  = ZDSECMGR_MASTERKEY_MAX;
    528                }
    529              }
    530            }
    531          
    532            return status;
    533          }
    534          #endif // defined ( ZDSECMGR_COMMERCIAL )
    535          
    536          #if defined ( ZDSECMGR_COMMERCIAL )
    537          /******************************************************************************
    538           * @fn          ZDSecMgrMasterKeyStore
    539           *
    540           * @brief       Store MASTER key for specified address index.
    541           *
    542           * @param       ami - [in] Address Manager index
    543           * @param       key - [in] valid key to store
    544           *
    545           * @return      ZStatus_t
    546           */
    547          ZStatus_t ZDSecMgrMasterKeyStore( uint16 ami, uint8* key )
    548          {
    549            ZStatus_t status;
    550            uint16    index;
    551            uint8*    entry;
    552          
    553          
    554            // initialize results
    555            status = ZNwkUnknownDevice;
    556          
    557            // verify data is available
    558            if ( ZDSecMgrMasterKeyData != NULL )
    559            {
    560              for ( index = 0; index < ZDSECMGR_MASTERKEY_MAX ; index++ )
    561              {
    562                if ( ZDSecMgrMasterKeyData[index].ami == INVALID_NODE_ADDR )
    563                {
    564                  // store EXT address index
    565                  ZDSecMgrMasterKeyData[index].ami = ami;
    566          
    567                  entry = ZDSecMgrMasterKeyData[index].key;
    568          
    569                  if ( key != NULL )
    570                  {
    571                    osal_cpyExtAddr( entry, key );
    572                  }
    573                  else
    574                  {
    575                    osal_memset( entry, 0, SEC_KEY_LEN );
    576                  }
    577          
    578                  // return successful results
    579                  status = ZSuccess;
    580          
    581                  // break from loop
    582                  index  = ZDSECMGR_MASTERKEY_MAX;
    583                }
    584              }
    585            }
    586          
    587            return status;
    588          }
    589          #endif // !defined ( ZDSECMGR_COMMERCIAL )
    590          
    591          #if defined ( ZDSECMGR_COMMERCIAL )
    592          /******************************************************************************
    593           * @fn          ZDSecMgrEntryInit
    594           *
    595           * @brief       Initialize entry sub module
    596           *
    597           * @param       none
    598           *
    599           * @return      none
    600           */
    601          void ZDSecMgrEntryInit( void )
    602          {
    603            uint16 size;
    604            uint16 index;
    605          
    606          
    607            // allocate entry data
    608            size = (short)( sizeof(ZDSecMgrEntry_t) * ZDSECMGR_ENTRY_MAX );
    609          
    610            ZDSecMgrEntries = osal_mem_alloc( size );
    611          
    612            // initialize data
    613            if ( ZDSecMgrEntries != NULL )
    614            {
    615              for( index = 0; index < ZDSECMGR_ENTRY_MAX; index++ )
    616              {
    617                ZDSecMgrEntries[index].ami = INVALID_NODE_ADDR;
    618              }
    619            }
    620          }
    621          #endif // defined ( ZDSECMGR_COMMERCIAL )
    622          
    623          #if defined ( ZDSECMGR_COMMERCIAL )
    624          /******************************************************************************
    625           * @fn          ZDSecMgrEntryLookup
    626           *
    627           * @brief       Lookup entry index using specified NWK address.
    628           *
    629           * @param       nwkAddr - [in] NWK address
    630           * @param       entry   - [out] valid entry
    631           *
    632           * @return      ZStatus_t
    633           */
    634          ZStatus_t ZDSecMgrEntryLookup( uint16 nwkAddr, ZDSecMgrEntry_t** entry )
    635          {
    636            ZStatus_t      status;
    637            uint16         index;
    638            AddrMgrEntry_t addrMgrEntry;
    639          
    640          
    641            // initialize results
    642            *entry = NULL;
    643            status = ZNwkUnknownDevice;
    644          
    645            // verify data is available
    646            if ( ZDSecMgrEntries != NULL )
    647            {
    648              addrMgrEntry.user    = ADDRMGR_USER_SECURITY;
    649              addrMgrEntry.nwkAddr = nwkAddr;
    650          
    651              if ( AddrMgrEntryLookupNwk( &addrMgrEntry ) == TRUE )
    652              {
    653                for ( index = 0; index < ZDSECMGR_ENTRY_MAX ; index++ )
    654                {
    655                  if ( addrMgrEntry.index == ZDSecMgrEntries[index].ami )
    656                  {
    657                    // return successful results
    658                    *entry = &ZDSecMgrEntries[index];
    659                    status = ZSuccess;
    660          
    661                    // break from loop
    662                    index = ZDSECMGR_ENTRY_MAX;
    663                  }
    664                }
    665              }
    666            }
    667          
    668            return status;
    669          }
    670          #endif // defined ( ZDSECMGR_COMMERCIAL )
    671          
    672          #if defined ( ZDSECMGR_COMMERCIAL )
    673          /******************************************************************************
    674           * @fn          ZDSecMgrEntryLookupAMI
    675           *
    676           * @brief       Lookup entry using specified address index
    677           *
    678           * @param       ami   - [in] Address Manager index
    679           * @param       entry - [out] valid entry
    680           *
    681           * @return      ZStatus_t
    682           */
    683          ZStatus_t ZDSecMgrEntryLookupAMI( uint16 ami, ZDSecMgrEntry_t** entry )
    684          {
    685            ZStatus_t status;
    686            uint16    index;
    687          
    688          
    689            // initialize results
    690            *entry = NULL;
    691            status = ZNwkUnknownDevice;
    692          
    693            // verify data is available
    694            if ( ZDSecMgrEntries != NULL )
    695            {
    696              for ( index = 0; index < ZDSECMGR_ENTRY_MAX ; index++ )
    697              {
    698                if ( ZDSecMgrEntries[index].ami == ami )
    699                {
    700                  // return successful results
    701                  *entry = &ZDSecMgrEntries[index];
    702                  status = ZSuccess;
    703          
    704                  // break from loop
    705                  index = ZDSECMGR_ENTRY_MAX;
    706                }
    707              }
    708            }
    709          
    710            return status;
    711          }
    712          #endif // defined ( ZDSECMGR_COMMERCIAL )
    713          
    714          #if defined ( ZDSECMGR_COMMERCIAL )
    715          /******************************************************************************
    716           * @fn          ZDSecMgrEntryLookupExt
    717           *
    718           * @brief       Lookup entry index using specified EXT address.
    719           *
    720           * @param       extAddr - [in] EXT address
    721           * @param       entry   - [out] valid entry
    722           *
    723           * @return      ZStatus_t
    724           */
    725          ZStatus_t ZDSecMgrEntryLookupExt( uint8* extAddr, ZDSecMgrEntry_t** entry )
    726          {
    727            ZStatus_t status;
    728            uint16    ami;
    729          
    730          
    731            // initialize results
    732            *entry = NULL;
    733            status = ZNwkUnknownDevice;
    734          
    735            // lookup address index
    736            if ( ZDSecMgrExtAddrLookup( extAddr, &ami ) == ZSuccess )
    737            {
    738              status = ZDSecMgrEntryLookupAMI( ami, entry );
    739            }
    740          
    741            return status;
    742          }
    743          #endif // defined ( ZDSECMGR_COMMERCIAL )
    744          
    745          #if defined ( ZDSECMGR_COMMERCIAL )
    746          /******************************************************************************
    747           * @fn          ZDSecMgrEntryFree
    748           *
    749           * @brief       Free entry.
    750           *
    751           * @param       entry - [in] valid entry
    752           *
    753           * @return      ZStatus_t
    754           */
    755          void ZDSecMgrEntryFree( ZDSecMgrEntry_t* entry )
    756          {
    757            entry->ami = INVALID_NODE_ADDR;
    758          }
    759          #endif // defined ( ZDSECMGR_COMMERCIAL )
    760          
    761          #if defined ( ZDSECMGR_COMMERCIAL )
    762          /******************************************************************************
    763           * @fn          ZDSecMgrEntryNew
    764           *
    765           * @brief       Get a new entry.
    766           *
    767           * @param       entry - [out] valid entry
    768           *
    769           * @return      ZStatus_t
    770           */
    771          ZStatus_t ZDSecMgrEntryNew( ZDSecMgrEntry_t** entry )
    772          {
    773            ZStatus_t status;
    774            uint16    index;
    775          
    776          
    777            // initialize results
    778            *entry = NULL;
    779            status = ZNwkUnknownDevice;
    780          
    781            // verify data is available
    782            if ( ZDSecMgrEntries != NULL )
    783            {
    784              // find available entry
    785              for ( index = 0; index < ZDSECMGR_ENTRY_MAX ; index++ )
    786              {
    787                if ( ZDSecMgrEntries[index].ami == INVALID_NODE_ADDR )
    788                {
    789                  // return successful result
    790                  *entry = &ZDSecMgrEntries[index];
    791                  status = ZSuccess;
    792          
    793                  // break from loop
    794                  index = ZDSECMGR_ENTRY_MAX;
    795                }
    796              }
    797            }
    798          
    799            return status;
    800          }
    801          #endif // defined ( ZDSECMGR_COMMERCIAL )
    802          
    803          #if defined ( ZDSECMGR_COMMERCIAL )
    804          /******************************************************************************
    805           * @fn          ZDSecMgrCtrlInit
    806           *
    807           * @brief       Initialize control sub module
    808           *
    809           * @param       none
    810           *
    811           * @return      none
    812           */
    813          void ZDSecMgrCtrlInit( void )
    814          {
    815            //---------------------------------------------------------------------------
    816            #if defined ( ZDO_COORDINATOR )
    817            //---------------------------------------------------------------------------
    818            uint16 size;
    819            uint16 index;
    820          
    821          
    822            // allocate entry data
    823            size = (short)( sizeof(ZDSecMgrCtrl_t) * ZDSECMGR_CTRL_MAX );
    824          
    825            ZDSecMgrCtrlData = osal_mem_alloc( size );
    826          
    827            // initialize data
    828            if ( ZDSecMgrCtrlData != NULL )
    829            {
    830              for( index = 0; index < ZDSECMGR_CTRL_MAX; index++ )
    831              {
    832                ZDSecMgrCtrlData[index].state = ZDSECMGR_CTRL_NONE;
    833              }
    834            }
    835            //---------------------------------------------------------------------------
    836            #endif // defined ( ZDO_COORDINATOR )
    837            //---------------------------------------------------------------------------
    838          }
    839          #endif // defined ( ZDSECMGR_COMMERCIAL )
    840          
    841          #if defined ( ZDSECMGR_COMMERCIAL )
    842          #if defined ( ZDO_COORDINATOR )
    843          /******************************************************************************
    844           * @fn          ZDSecMgrCtrlRelease
    845           *
    846           * @brief       Release control data.
    847           *
    848           * @param       ctrl - [in] valid control data
    849           *
    850           * @return      none
    851           */
    852          void ZDSecMgrCtrlRelease( ZDSecMgrCtrl_t* ctrl )
    853          {
    854            // should always be enough entry control data
    855            ctrl->state = ZDSECMGR_CTRL_NONE;
    856          }
    857          #endif // defined ( ZDO_COORDINATOR )
    858          #endif // defined ( ZDSECMGR_COMMERCIAL )
    859          
    860          #if defined ( ZDSECMGR_COMMERCIAL )
    861          #if defined ( ZDO_COORDINATOR )
    862          /******************************************************************************
    863           * @fn          ZDSecMgrCtrlLookup
    864           *
    865           * @brief       Lookup control data.
    866           *
    867           * @param       entry - [in] valid entry data
    868           * @param       ctrl  - [out] control data - NULL if not found
    869           *
    870           * @return      none
    871           */
    872          void ZDSecMgrCtrlLookup( ZDSecMgrEntry_t* entry, ZDSecMgrCtrl_t** ctrl )
    873          {
    874            uint16 index;
    875          
    876          
    877            // initialize search results
    878            *ctrl = NULL;
    879          
    880            // verify data is available
    881            if ( ZDSecMgrCtrlData != NULL )
    882            {
    883              for ( index = 0; index < ZDSECMGR_CTRL_MAX; index++ )
    884              {
    885                // make sure control data is in use
    886                if ( ZDSecMgrCtrlData[index].state != ZDSECMGR_CTRL_NONE )
    887                {
    888                  // check for entry match
    889                  if ( ZDSecMgrCtrlData[index].entry == entry )
    890                  {
    891                    // return this control data
    892                    *ctrl = &ZDSecMgrCtrlData[index];
    893          
    894                    // break from loop
    895                    index = ZDSECMGR_CTRL_MAX;
    896                  }
    897                }
    898              }
    899            }
    900          }
    901          #endif // defined ( ZDO_COORDINATOR )
    902          #endif // defined ( ZDSECMGR_COMMERCIAL )
    903          
    904          
    905          #if defined ( ZDSECMGR_COMMERCIAL )
    906          #if defined ( ZDO_COORDINATOR )
    907          /******************************************************************************
    908           * @fn          ZDSecMgrCtrlSet
    909           *
    910           * @brief       Set control data.
    911           *
    912           * @param       device - [in] valid device data
    913           * @param       entry  - [in] valid entry data
    914           * @param       ctrl   - [in] valid control data
    915           *
    916           * @return      none
    917           */
    918          void ZDSecMgrCtrlSet( ZDSecMgrDevice_t* device,
    919                                ZDSecMgrEntry_t*  entry,
    920                                ZDSecMgrCtrl_t*   ctrl )
    921          {
    922            // set control date
    923            ctrl->parentAddr = device->parentAddr;
    924            ctrl->secure     = device->secure;
    925            ctrl->entry      = entry;
    926            ctrl->state      = ZDSECMGR_CTRL_INIT;
    927            ctrl->cntr       = 0;
    928          
    929            // set device pointer
    930            device->ctrl = ctrl;
    931          }
    932          #endif // defined ( ZDO_COORDINATOR )
    933          #endif // defined ( ZDSECMGR_COMMERCIAL )
    934          
    935          #if defined ( ZDSECMGR_COMMERCIAL )
    936          /******************************************************************************
    937           * @fn          ZDSecMgrCtrlAdd
    938           *
    939           * @brief       Add control data.
    940           *
    941           * @param       device - [in] valid device data
    942           * @param       entry  - [in] valid entry data
    943           *
    944           * @return      none
    945           */
    946          ZStatus_t ZDSecMgrCtrlAdd( ZDSecMgrDevice_t* device, ZDSecMgrEntry_t*  entry )
    947          {
    948            //---------------------------------------------------------------------------
    949            #if defined ( ZDO_COORDINATOR )
    950            //---------------------------------------------------------------------------
    951            ZStatus_t status;
    952            uint16    index;
    953          
    954          
    955            // initialize results
    956            status = ZNwkUnknownDevice;
    957          
    958            // verify data is available
    959            if ( ZDSecMgrCtrlData != NULL )
    960            {
    961              // look for an empty slot
    962              for ( index = 0; index < ZDSECMGR_CTRL_MAX; index++ )
    963              {
    964                if ( ZDSecMgrCtrlData[index].state == ZDSECMGR_CTRL_NONE )
    965                {
    966                  // return successful results
    967                  ZDSecMgrCtrlSet( device, entry, &ZDSecMgrCtrlData[index] );
    968          
    969                  status = ZSuccess;
    970          
    971                  // break from loop
    972                  index = ZDSECMGR_CTRL_MAX;
    973                }
    974              }
    975            }
    976          
    977            return status;
    978            //---------------------------------------------------------------------------
    979            #else // !defined ( ZDO_COORDINATOR )
    980            //---------------------------------------------------------------------------
    981            return ZSuccess;
    982            //---------------------------------------------------------------------------
    983            #endif // !defined ( ZDO_COORDINATOR )
    984            //---------------------------------------------------------------------------
    985          }
    986          #endif // defined ( ZDSECMGR_COMMERCIAL )
    987          
    988          #if defined ( ZDSECMGR_COMMERCIAL )
    989          /******************************************************************************
    990           * @fn          ZDSecMgrCtrlTerm
    991           *
    992           * @brief       Terminate device control.
    993           *
    994           * @param       entry - [in] valid entry data
    995           *
    996           * @return      none
    997           */
    998          void ZDSecMgrCtrlTerm( ZDSecMgrEntry_t* entry )
    999          {
   1000            //---------------------------------------------------------------------------
   1001            #if defined ( ZDO_COORDINATOR )
   1002            //---------------------------------------------------------------------------
   1003            ZDSecMgrCtrl_t* ctrl;
   1004          
   1005          
   1006            // remove device from control data
   1007            ZDSecMgrCtrlLookup ( entry, &ctrl );
   1008          
   1009            if ( ctrl != NULL )
   1010            {
   1011              ZDSecMgrCtrlRelease ( ctrl );
   1012            }
   1013            //---------------------------------------------------------------------------
   1014            #endif // defined ( ZDO_COORDINATOR )
   1015            //---------------------------------------------------------------------------
   1016          }
   1017          #endif // defined ( ZDSECMGR_COMMERCIAL )
   1018          
   1019          #if defined ( ZDSECMGR_COMMERCIAL )
   1020          /******************************************************************************
   1021           * @fn          ZDSecMgrCtrlReset
   1022           *
   1023           * @brief       Reset control data.
   1024           *
   1025           * @param       device - [in] valid device data
   1026           * @param       entry  - [in] valid entry data
   1027           *
   1028           * @return      none
   1029           */
   1030          ZStatus_t ZDSecMgrCtrlReset( ZDSecMgrDevice_t* device, ZDSecMgrEntry_t* entry )
   1031          {
   1032            //---------------------------------------------------------------------------
   1033            #if defined ( ZDO_COORDINATOR )
   1034            //---------------------------------------------------------------------------
   1035            ZStatus_t       status;
   1036            ZDSecMgrCtrl_t* ctrl;
   1037          
   1038          
   1039            // initialize results
   1040            status = ZNwkUnknownDevice;
   1041          
   1042            // look for a match for the entry
   1043            ZDSecMgrCtrlLookup( entry, &ctrl );
   1044          
   1045            if ( ctrl != NULL )
   1046            {
   1047              ZDSecMgrCtrlSet( device, entry, ctrl );
   1048          
   1049              status = ZSuccess;
   1050            }
   1051            else
   1052            {
   1053              status = ZDSecMgrCtrlAdd( device, entry );
   1054            }
   1055          
   1056            return status;
   1057            //---------------------------------------------------------------------------
   1058            #else // !defined ( ZDO_COORDINATOR )
   1059            //---------------------------------------------------------------------------
   1060            return ZSuccess;
   1061            //---------------------------------------------------------------------------
   1062            #endif // !defined ( ZDO_COORDINATOR )
   1063            //---------------------------------------------------------------------------
   1064          }
   1065          #endif // defined ( ZDSECMGR_COMMERCIAL )
   1066          
   1067          #if defined ( ZDSECMGR_COMMERCIAL )
   1068          /******************************************************************************
   1069           * @fn          ZDSecMgrMasterKeyLoad
   1070           *
   1071           * @brief       Load the MASTER key for device with specified EXT
   1072           *              address.
   1073           *
   1074           * @param       nwkAddr - [in] NWK address of Trust Center
   1075           * @param       extAddr - [in] EXT address of Trust Center
   1076           * @param       key     - [in] MASTER key shared with Trust Center
   1077           *
   1078           * @return      none
   1079           */
   1080          void ZDSecMgrMasterKeyLoad( uint16 nwkAddr, uint8* extAddr, uint8* key )
   1081          {
   1082            AddrMgrEntry_t addr;
   1083            uint8*         loaded;
   1084          
   1085          
   1086            // check if Trust Center address is configured and correct
   1087            // check if MASTER key has already been sent
   1088          
   1089            // add address data
   1090            addr.user    = ADDRMGR_USER_SECURITY;
   1091            addr.nwkAddr = nwkAddr;
   1092            AddrMgrExtAddrSet( addr.extAddr, extAddr );
   1093          
   1094            if ( AddrMgrEntryUpdate( &addr ) == TRUE )
   1095            {
   1096              if ( ZDSecMgrMasterKeyLookup( addr.index, &loaded ) != ZSuccess )
   1097              {
   1098                ZDSecMgrMasterKeyStore( addr.index, key );
   1099              }
   1100            }
   1101          }
   1102          #endif // defined ( ZDSECMGR_COMMERCIAL )
   1103          
   1104          #if defined ( ZDSECMGR_COMMERCIAL )
   1105          /******************************************************************************
   1106           * @fn          ZDSecMgrAppKeyGet
   1107           *
   1108           * @brief       get an APP key - option APP(MASTER or LINK) key
   1109           *
   1110           * @param       initNwkAddr - [in] NWK address of initiator device
   1111           * @param       initExtAddr - [in] EXT address of initiator device
   1112           * @param       partNwkAddr - [in] NWK address of partner device
   1113           * @param       partExtAddr - [in] EXT address of partner device
   1114           * @param       key         - [out] APP(MASTER or LINK) key
   1115           * @param       keyType     - [out] APP(MASTER or LINK) key type
   1116           *
   1117           * @return      pointer to MASTER key
   1118           */
   1119          ZStatus_t ZDSecMgrAppKeyGet( uint16  initNwkAddr,
   1120                                       uint8*  initExtAddr,
   1121                                       uint16  partNwkAddr,
   1122                                       uint8*  partExtAddr,
   1123                                       uint8** key,
   1124                                       uint8*  keyType )
   1125          {
   1126            //---------------------------------------------------------------------------
   1127            // note:
   1128            // should use a robust mechanism to generate keys, for example
   1129            // combine EXT addresses and call a hash function
   1130            //---------------------------------------------------------------------------
   1131            osal_memset( *key, 0, SEC_KEY_LEN );
   1132          
   1133            *keyType = KEY_TYPE_APP_LINK;
   1134            //or       KEY_TYPE_APP_MASTER;
   1135          
   1136            return ZSuccess;
   1137          }
   1138          #endif // defined ( ZDSECMGR_COMMERCIAL )
   1139          
   1140          #if defined ( ZDSECMGR_COMMERCIAL )
   1141          /******************************************************************************
   1142           * @fn          ZDSecMgrAppKeyReq
   1143           *
   1144           * @brief       Process request for APP key between two devices.
   1145           *
   1146           * @param       device - [in] ZDO_RequestKeyInd_t, request info
   1147           *
   1148           * @return      none
   1149           */
   1150          void ZDSecMgrAppKeyReq( ZDO_RequestKeyInd_t* ind )
   1151          {
   1152            APSME_TransportKeyReq_t req;
   1153            uint8                   initExtAddr[Z_EXTADDR_LEN];
   1154            uint16                  partNwkAddr;
   1155            uint8                   key[SEC_KEY_LEN];
   1156          
   1157          
   1158            // validate initiator and partner
   1159            if ( ( APSME_LookupNwkAddr( ind->partExtAddr, &partNwkAddr ) == TRUE ) &&
   1160                 ( APSME_LookupExtAddr( ind->srcAddr, initExtAddr ) == TRUE      )   )
   1161            {
   1162              // point the key to some memory
   1163              req.key = key;
   1164          
   1165              // get an APP key - option APP (MASTER or LINK) key
   1166              if ( ZDSecMgrAppKeyGet( ind->srcAddr,
   1167                                      initExtAddr,
   1168                                      partNwkAddr,
   1169                                      ind->partExtAddr,
   1170                                      &req.key,
   1171                                      &req.keyType ) == ZSuccess )
   1172              {
   1173                // always secure
   1174                req.secure = TRUE;
   1175          
   1176                // send key to initiator device
   1177                req.dstAddr   = ind->srcAddr;
   1178                req.extAddr   = ind->partExtAddr;
   1179                req.initiator = TRUE;
   1180                APSME_TransportKeyReq( &req );
   1181          
   1182                // send key to partner device
   1183                req.dstAddr   = partNwkAddr;
   1184                req.extAddr   = initExtAddr;
   1185                req.initiator = FALSE;
   1186                APSME_TransportKeyReq( &req );
   1187              }
   1188            }
   1189          }
   1190          #endif // defined ( ZDSECMGR_COMMERCIAL )
   1191          
   1192          #if defined ( ZDSECMGR_COMMERCIAL )
   1193          /******************************************************************************
   1194           * @fn          ZDSecMgrEstablishKey
   1195           *
   1196           * @brief       Start SKKE with device joining network.
   1197           *
   1198           * @param       device - [in] ZDSecMgrDevice_t, device info
   1199           *
   1200           * @return      ZStatus_t
   1201           */
   1202          ZStatus_t ZDSecMgrEstablishKey( ZDSecMgrDevice_t* device )
   1203          {
   1204            ZStatus_t               status;
   1205            APSME_EstablishKeyReq_t req;
   1206          
   1207          
   1208            req.respExtAddr = device->extAddr;
   1209            req.method      = APSME_SKKE_METHOD;
   1210          
   1211            if ( device->parentAddr == NLME_GetShortAddr() )
   1212            {
   1213              req.dstAddr = device->nwkAddr;
   1214              req.secure  = FALSE;
   1215            }
   1216            else
   1217            {
   1218              req.dstAddr = device->parentAddr;
   1219              req.secure  = TRUE;
   1220            }
   1221          
   1222            status = APSME_EstablishKeyReq( &req );
   1223          
   1224            return status;
   1225          }
   1226          #endif // defined ( ZDSECMGR_COMMERCIAL )
   1227          
   1228          #if defined ( ZDSECMGR_COMMERCIAL )
   1229          /******************************************************************************
   1230           * @fn          ZDSecMgrSendMasterKey
   1231           *
   1232           * @brief       Send MASTER key to device joining network.
   1233           *
   1234           * @param       device - [in] ZDSecMgrDevice_t, device info
   1235           *
   1236           * @return      ZStatus_t
   1237           */
   1238          ZStatus_t ZDSecMgrSendMasterKey( ZDSecMgrDevice_t* device )
   1239          {
   1240            ZStatus_t               status;
   1241            APSME_TransportKeyReq_t req;
   1242          
   1243          
   1244            req.keyType = KEY_TYPE_TC_MASTER;
   1245            req.extAddr = device->extAddr;
   1246          
   1247            ZDSecMgrMasterKeyLookup( device->ctrl->entry->ami, &req.key );
   1248          
   1249            //check if using secure hop to to parent
   1250            if ( device->parentAddr != NLME_GetShortAddr() )
   1251            {
   1252              //send to parent with security
   1253              req.dstAddr = device->parentAddr;
   1254              req.secure  = TRUE;
   1255            }
   1256            else
   1257            {
   1258              //direct with no security
   1259              req.dstAddr = device->nwkAddr;
   1260              req.secure  = FALSE;
   1261            }
   1262          
   1263            status = APSME_TransportKeyReq( &req );
   1264          
   1265            return status;
   1266          }
   1267          #endif // defined ( ZDSECMGR_COMMERCIAL )
   1268          
   1269          /******************************************************************************
   1270           * @fn          ZDSecMgrSendNwkKey
   1271           *
   1272           * @brief       Send NWK key to device joining network.
   1273           *
   1274           * @param       device - [in] ZDSecMgrDevice_t, device info
   1275           *
   1276           * @return      ZStatus_t
   1277           */

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   1278          ZStatus_t ZDSecMgrSendNwkKey( ZDSecMgrDevice_t* device )
   \                     ZDSecMgrSendNwkKey:
   1279          {
   \   000000   74F6         MOV     A,#-0xa
   \   000002   12....       LCALL   ?BANKED_ENTER_XDATA
   \   000005                ; Saved register size: 10
   \   000005                ; Auto size: 10
   \   000005   74F6         MOV     A,#-0xa
   \   000007   12....       LCALL   ?ALLOC_XSTACK8
   \   00000A   EA           MOV     A,R2
   \   00000B   FE           MOV     R6,A
   \   00000C   EB           MOV     A,R3
   \   00000D   FF           MOV     R7,A
   1280            ZStatus_t               status;
   1281            APSME_TransportKeyReq_t req;
   1282          
   1283          
   1284            //---------------------------------------------------------------------------
   1285            #if defined ( ZDSECMGR_COMMERCIAL )
   1286            //---------------------------------------------------------------------------
   1287            {
   1288              // set values
   1289              req.extAddr   = device->extAddr;
   1290              req.keyType   = KEY_TYPE_NWK;
   1291              req.keySeqNum = _NIB.nwkActiveKey.keySeqNum;
   1292              req.key       = _NIB.nwkActiveKey.key;
   1293          
   1294              // check if using secure hop to to parent
   1295              if ( device->parentAddr == NLME_GetShortAddr() )
   1296              {
   1297                req.dstAddr = device->nwkAddr;
   1298                req.secure  = FALSE;
   1299              }
   1300              else
   1301              {
   1302                req.dstAddr = device->parentAddr;
   1303                req.secure  = TRUE;
   1304              }
   1305            }
   1306            //---------------------------------------------------------------------------
   1307            #else // defined( ZDSECMGR_RESIDENTIAL )
   1308            //---------------------------------------------------------------------------
   1309            {
   1310              // default values
   1311              req.dstAddr = device->nwkAddr;
   \   00000E   12....       LCALL   ?Subroutine0 & 0xFFFF
   1312              req.secure  = device->secure;
   \                     ??CrossCallReturnLabel_0:
   \   000011   EE           MOV     A,R6
   \   000012   2406         ADD     A,#0x6
   \   000014   12....       LCALL   ?Subroutine6 & 0xFFFF
   \                     ??CrossCallReturnLabel_15:
   \   000017   C0E0         PUSH    A
   \   000019   7409         MOV     A,#0x9
   \   00001B   12....       LCALL   ?XSTACK_DISP0_8
   \   00001E   D0E0         POP     A
   \   000020   F0           MOVX    @DPTR,A
   1313              req.keyType = KEY_TYPE_NWK;
   \   000021   7402         MOV     A,#0x2
   \   000023   12....       LCALL   ?XSTACK_DISP0_8
   \   000026   7401         MOV     A,#0x1
   \   000028   F0           MOVX    @DPTR,A
   1314              req.extAddr = device->extAddr;
   \   000029   8E82         MOV     DPL,R6
   \   00002B   8F83         MOV     DPH,R7
   \   00002D   A3           INC     DPTR
   \   00002E   A3           INC     DPTR
   \   00002F   E0           MOVX    A,@DPTR
   \   000030   FA           MOV     R2,A
   \   000031   A3           INC     DPTR
   \   000032   E0           MOVX    A,@DPTR
   \   000033   FB           MOV     R3,A
   \   000034   7406         MOV     A,#0x6
   \   000036   12....       LCALL   ?XSTACK_DISP0_8
   \   000039   EA           MOV     A,R2
   \   00003A   F0           MOVX    @DPTR,A
   \   00003B   A3           INC     DPTR
   \   00003C   EB           MOV     A,R3
   \   00003D   F0           MOVX    @DPTR,A
   1315          
   1316              // special cases
   1317              if ( device->secure == FALSE )
   \   00003E   8882         MOV     DPL,R0
   \   000040   8983         MOV     DPH,R1
   \   000042   E0           MOVX    A,@DPTR
   \   000043   7038         JNZ     ??ZDSecMgrSendNwkKey_0
   1318              {
   1319                req.keySeqNum = _NIB.nwkActiveKey.keySeqNum;
   \   000045   90....       MOV     DPTR,#(_NIB + 62)
   \   000048   E0           MOVX    A,@DPTR
   \   000049   C0E0         PUSH    A
   \   00004B   7403         MOV     A,#0x3
   \   00004D   12....       LCALL   ?XSTACK_DISP0_8
   \   000050   D0E0         POP     A
   \   000052   F0           MOVX    @DPTR,A
   1320                req.key       = _NIB.nwkActiveKey.key;
   \   000053   7404         MOV     A,#0x4
   \   000055   12....       LCALL   ?XSTACK_DISP0_8
   \   000058   74..         MOV     A,#((_NIB + 63) & 0xff)
   \   00005A   F0           MOVX    @DPTR,A
   \   00005B   A3           INC     DPTR
   \   00005C   74..         MOV     A,#(((_NIB + 63) >> 8) & 0xff)
   \   00005E   F0           MOVX    @DPTR,A
   1321          
   1322                // check if using secure hop to to parent
   1323                if ( device->parentAddr != NLME_GetShortAddr() )
   \   00005F                ; Setup parameters for call to function NLME_GetShortAddr
   \   00005F   12....       LCALL   ?Subroutine5 & 0xFFFF
   \                     ??CrossCallReturnLabel_13:
   \   000062   7003         JNZ     ??ZDSecMgrSendNwkKey_1
   \   000064   A3           INC     DPTR
   \   000065   E0           MOVX    A,@DPTR
   \   000066   69           XRL     A,R1
   \                     ??ZDSecMgrSendNwkKey_1:
   \   000067   6024         JZ      ??ZDSecMgrSendNwkKey_2
   1324                {
   1325                  req.dstAddr = device->parentAddr;
   \   000069   8E82         MOV     DPL,R6
   \   00006B   8F83         MOV     DPH,R7
   \   00006D   A3           INC     DPTR
   \   00006E   A3           INC     DPTR
   \   00006F   A3           INC     DPTR
   \   000070   A3           INC     DPTR
   \   000071   12....       LCALL   ??Subroutine0_0 & 0xFFFF
   1326                  req.secure  = TRUE;
   \                     ??CrossCallReturnLabel_1:
   \   000074   7409         MOV     A,#0x9
   \   000076   12....       LCALL   ?XSTACK_DISP0_8
   \   000079   7401         MOV     A,#0x1
   \   00007B   800F         SJMP    ??ZDSecMgrSendNwkKey_3
   1327                }
   1328              }
   1329              else
   1330              {
   1331                req.key       = NULL;
   \                     ??ZDSecMgrSendNwkKey_0:
   \   00007D   7404         MOV     A,#0x4
   \   00007F   12....       LCALL   ?XSTACK_DISP0_8
   \   000082   E4           CLR     A
   \   000083   F0           MOVX    @DPTR,A
   \   000084   A3           INC     DPTR
   \   000085   F0           MOVX    @DPTR,A
   1332                req.keySeqNum = 0;
   \   000086   7403         MOV     A,#0x3
   \   000088   12....       LCALL   ?XSTACK_DISP0_8
   \   00008B   E4           CLR     A
   \                     ??ZDSecMgrSendNwkKey_3:
   \   00008C   F0           MOVX    @DPTR,A
   1333              }
   1334            }
   1335            //-------------------------------------------------------------------------
   1336            #endif // defined( ZDSECMGR_RESIDENTIAL )
   1337            //-------------------------------------------------------------------------
   1338          
   1339            status = APSME_TransportKeyReq( &req );
   1340          
   1341            return status;
   \                     ??ZDSecMgrSendNwkKey_2:
   \   00008D                ; Setup parameters for call to function APSME_TransportKeyReq
   \   00008D   85..82       MOV     DPL,?XSP + 0
   \   000090   85..83       MOV     DPH,?XSP + 1
   \   000093   AA82         MOV     R2,DPL
   \   000095   AB83         MOV     R3,DPH
   \   000097   12....       LCALL   ??APSME_TransportKeyReq?relay
   \   00009A   740A         MOV     A,#0xa
   \   00009C                REQUIRE ?Subroutine8
   \   00009C                ; // Fall through to label ?Subroutine8
   1342          }

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   \                     ?Subroutine8:
   \   000000   12....       LCALL   ?DEALLOC_XSTACK8
   \                     ??Subroutine8_0:
   \   000003   7F02         MOV     R7,#0x2
   \   000005   02....       LJMP    ?BANKED_LEAVE_XDATA

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   \                     ?Subroutine6:
   \   000000   F8           MOV     R0,A
   \   000001   EF           MOV     A,R7
   \   000002   3400         ADDC    A,#0x0
   \   000004   F9           MOV     R1,A
   \   000005   8882         MOV     DPL,R0
   \   000007   8983         MOV     DPH,R1
   \   000009   E0           MOVX    A,@DPTR
   \   00000A   22           RET

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   \                     ?Subroutine5:
   \   000000   12....       LCALL   ??NLME_GetShortAddr?relay
   \   000003   8A..         MOV     ?V0 + 0,R2
   \   000005   8B..         MOV     ?V0 + 1,R3
   \   000007   A8..         MOV     R0,?V0 + 0
   \   000009   A9..         MOV     R1,?V0 + 1
   \   00000B   8E82         MOV     DPL,R6
   \   00000D   8F83         MOV     DPH,R7
   \   00000F   A3           INC     DPTR
   \   000010   A3           INC     DPTR
   \   000011   A3           INC     DPTR
   \   000012   A3           INC     DPTR
   \   000013   E0           MOVX    A,@DPTR
   \   000014   68           XRL     A,R0
   \   000015   22           RET

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   \                     ?Subroutine7:
   \   000000   A3           INC     DPTR
   \   000001   A3           INC     DPTR
   \                     ??Subroutine7_0:
   \   000002   E0           MOVX    A,@DPTR
   \   000003   F8           MOV     R0,A
   \   000004   A3           INC     DPTR
   \   000005   E0           MOVX    A,@DPTR
   \   000006   F9           MOV     R1,A
   \   000007   22           RET

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   \                     ?Subroutine0:
   \   000000   8E82         MOV     DPL,R6
   \   000002   8F83         MOV     DPH,R7
   \                     ??Subroutine0_0:
   \   000004   12....       LCALL   ??Subroutine7_0 & 0xFFFF
   \                     ??CrossCallReturnLabel_20:
   \   000007   85..82       MOV     DPL,?XSP + 0
   \   00000A   85..83       MOV     DPH,?XSP + 1
   \   00000D   E8           MOV     A,R0
   \   00000E   F0           MOVX    @DPTR,A
   \   00000F   A3           INC     DPTR
   \   000010   E9           MOV     A,R1
   \   000011   F0           MOVX    @DPTR,A
   \   000012   22           RET
   1343          
   1344          #if defined ( ZDSECMGR_COMMERCIAL )
   1345          /******************************************************************************
   1346           * @fn          ZDSecMgrDeviceEntryRemove
   1347           *
   1348           * @brief       Remove device entry.
   1349           *
   1350           * @param       entry - [in] valid entry
   1351           *
   1352           * @return      none
   1353           */
   1354          void ZDSecMgrDeviceEntryRemove( ZDSecMgrEntry_t* entry )
   1355          {
   1356            // terminate device control
   1357            ZDSecMgrCtrlTerm( entry );
   1358          
   1359            // remove device from entry data
   1360            ZDSecMgrEntryFree( entry );
   1361          
   1362            // remove EXT address
   1363            //ZDSecMgrExtAddrRelease( aiOld );
   1364          }
   1365          #endif // defined ( ZDSECMGR_COMMERCIAL )
   1366          
   1367          #if defined ( ZDSECMGR_COMMERCIAL )
   1368          /******************************************************************************
   1369           * @fn          ZDSecMgrDeviceEntryAdd
   1370           *
   1371           * @brief       Add entry.
   1372           *
   1373           * @param       device - [in] ZDSecMgrDevice_t, device info
   1374           * @param       ami    - [in] Address Manager index
   1375           *
   1376           * @return      ZStatus_t
   1377           */
   1378          void ZDSecMgrAddrMgrUpdate( uint16 ami, uint16 nwkAddr )
   1379          {
   1380            AddrMgrEntry_t entry;
   1381          
   1382            // get the ami data
   1383            entry.user  = ADDRMGR_USER_SECURITY;
   1384            entry.index = ami;
   1385          
   1386            AddrMgrEntryGet( &entry );
   1387          
   1388            // check if NWK address is same
   1389            if ( entry.nwkAddr != nwkAddr )
   1390            {
   1391              // update NWK address
   1392              entry.nwkAddr = nwkAddr;
   1393          
   1394              AddrMgrEntryUpdate( &entry );
   1395            }
   1396          }
   1397          
   1398          ZStatus_t ZDSecMgrDeviceEntryAdd( ZDSecMgrDevice_t* device, uint16 ami )
   1399          {
   1400            ZStatus_t        status;
   1401            ZDSecMgrEntry_t* entry;
   1402          
   1403          
   1404            // initialize as unknown until completion
   1405            status = ZNwkUnknownDevice;
   1406          
   1407            device->ctrl = NULL;
   1408          
   1409            // make sure not already registered
   1410            if ( ZDSecMgrEntryLookup( device->nwkAddr, &entry ) == ZSuccess )
   1411            {
   1412              // verify that address index is same
   1413              if ( entry->ami != ami )
   1414              {
   1415                // remove conflicting entry
   1416                ZDSecMgrDeviceEntryRemove( entry );
   1417          
   1418                if ( ZDSecMgrEntryLookupAMI( ami, &entry ) == ZSuccess )
   1419                {
   1420                  // update NWK address
   1421                  ZDSecMgrAddrMgrUpdate( ami, device->nwkAddr );
   1422                }
   1423              }
   1424            }
   1425            else if ( ZDSecMgrEntryLookupAMI( ami, &entry ) == ZSuccess )
   1426            {
   1427              // update NWK address
   1428              ZDSecMgrAddrMgrUpdate( ami, device->nwkAddr );
   1429            }
   1430          
   1431            // check if a new entry needs to be created
   1432            if ( entry == NULL )
   1433            {
   1434              // get new entry
   1435              if ( ZDSecMgrEntryNew( &entry ) == ZSuccess )
   1436              {
   1437                // reset entry lkd
   1438          
   1439                // finish setting up entry
   1440                entry->ami = ami;
   1441          
   1442                // update NWK address
   1443                ZDSecMgrAddrMgrUpdate( ami, device->nwkAddr );
   1444          
   1445                // enter new device into device control
   1446                status = ZDSecMgrCtrlAdd( device, entry );
   1447              }
   1448            }
   1449            else
   1450            {
   1451              // reset entry lkd
   1452          
   1453              // reset entry in entry control
   1454              status = ZDSecMgrCtrlReset( device, entry );
   1455            }
   1456          
   1457            return status;
   1458          }
   1459          #endif // defined ( ZDSECMGR_COMMERCIAL )
   1460          
   1461          #if defined ( ZDSECMGR_COMMERCIAL )
   1462          #if defined ( ZDO_COORDINATOR )
   1463          /******************************************************************************
   1464           * @fn          ZDSecMgrDeviceCtrlHandler
   1465           *
   1466           * @brief       Device control handler.
   1467           *
   1468           * @param       device - [in] ZDSecMgrDevice_t, device info
   1469           *
   1470           * @return      none
   1471           */
   1472          void ZDSecMgrDeviceCtrlHandler( ZDSecMgrDevice_t* device )
   1473          {
   1474            uint8 state;
   1475            uint8 cntr;
   1476          
   1477          
   1478            state = device->ctrl->state;
   1479            cntr  = ZDSECMGR_CTRL_BASE_CNTR;
   1480          
   1481            switch ( state )
   1482            {
   1483              case ZDSECMGR_CTRL_TK_MASTER:
   1484                if ( ZDSecMgrSendMasterKey( device ) == ZSuccess )
   1485                {
   1486                  state = ZDSECMGR_CTRL_SKKE_INIT;
   1487                  cntr  = ZDSECMGR_CTRL_SKKE_INIT_CNTR;
   1488                }
   1489                break;
   1490          
   1491              case ZDSECMGR_CTRL_SKKE_INIT:
   1492                if ( ZDSecMgrEstablishKey( device ) == ZSuccess )
   1493                {
   1494                  state = ZDSECMGR_CTRL_SKKE_WAIT;
   1495                  cntr  = ZDSECMGR_CTRL_SKKE_WAIT_CNTR;
   1496                }
   1497                break;
   1498          
   1499              case ZDSECMGR_CTRL_SKKE_WAIT:
   1500                state = ZDSECMGR_CTRL_NONE;
   1501                // timeout error - cleanup SKKE slot and entry
   1502                break;
   1503          
   1504              case ZDSECMGR_CTRL_TK_NWK:
   1505                if ( ZDSecMgrSendNwkKey( device ) == ZSuccess )
   1506                {
   1507                  state = ZDSECMGR_CTRL_NONE;
   1508                }
   1509                break;
   1510          
   1511              default:
   1512                state = ZDSECMGR_CTRL_NONE;
   1513                break;
   1514            }
   1515          
   1516            if ( state != ZDSECMGR_CTRL_NONE )
   1517            {
   1518              device->ctrl->state = state;
   1519              device->ctrl->cntr  = cntr;
   1520          
   1521              osal_start_timerEx(ZDAppTaskID, ZDO_SECMGR_EVENT, 100 );
   1522            }
   1523            else
   1524            {
   1525              ZDSecMgrCtrlRelease( device->ctrl );
   1526            }
   1527          }
   1528          #endif // defined ( ZDO_COORDINATOR )
   1529          #endif // defined ( ZDSECMGR_COMMERCIAL )
   1530          
   1531          #if defined ( ZDO_COORDINATOR )
   1532          #if defined ( ZDSECMGR_COMMERCIAL )
   1533          /******************************************************************************
   1534           * @fn          ZDSecMgrDeviceCtrlSetup
   1535           *
   1536           * @brief       Setup device control.
   1537           *
   1538           * @param       device - [in] ZDSecMgrDevice_t, device info
   1539           *
   1540           * @return      ZStatus_t
   1541           */
   1542          void ZDSecMgrDeviceCtrlSetup( ZDSecMgrDevice_t* device )
   1543          {
   1544            if ( device->ctrl != NULL )
   1545            {
   1546              if ( device->secure == FALSE )
   1547              {
   1548                // send the master key data to the joining device
   1549                device->ctrl->state = ZDSECMGR_CTRL_TK_MASTER;
   1550              }
   1551              else
   1552              {
   1553                // start SKKE
   1554                device->ctrl->state = ZDSECMGR_CTRL_SKKE_INIT;
   1555              }
   1556          
   1557              ZDSecMgrDeviceCtrlHandler( device );
   1558            }
   1559          }
   1560          #endif // defined ( ZDO_COORDINATOR )
   1561          #endif // defined ( ZDSECMGR_COMMERCIAL )
   1562          
   1563          #if defined ( ZDSECMGR_COMMERCIAL )
   1564          /******************************************************************************
   1565           * @fn          ZDSecMgrDeviceCtrlUpdate
   1566           *
   1567           * @brief       Update control data.
   1568           *
   1569           * @param       extAddr - [in] EXT address
   1570           * @param       state   - [in] new control state
   1571           *
   1572           * @return      none
   1573           */
   1574          void ZDSecMgrDeviceCtrlUpdate( uint8* extAddr, uint8 state )
   1575          {
   1576            //---------------------------------------------------------------------------
   1577            #if defined ( ZDO_COORDINATOR )
   1578            //---------------------------------------------------------------------------
   1579            ZDSecMgrEntry_t* entry;
   1580            ZDSecMgrCtrl_t*  ctrl;
   1581          
   1582          
   1583            // lookup device entry data
   1584            ZDSecMgrEntryLookupExt( extAddr, &entry );
   1585          
   1586            if ( entry != NULL )
   1587            {
   1588              // lookup device control data
   1589              ZDSecMgrCtrlLookup( entry, &ctrl );
   1590          
   1591              // make sure control data is valid
   1592              if ( ctrl != NULL )
   1593              {
   1594                // possible state transitions
   1595                if ( ( state == ZDSECMGR_CTRL_SKKE_DONE       ) &&
   1596                     ( ctrl->state == ZDSECMGR_CTRL_SKKE_WAIT )    )
   1597                {
   1598                  ctrl->state = ZDSECMGR_CTRL_TK_NWK;
   1599                  ctrl->cntr  = ZDSECMGR_CTRL_TK_NWK_CNTR;
   1600                }
   1601          
   1602                // timer should be active
   1603              }
   1604            }
   1605            //---------------------------------------------------------------------------
   1606            #endif // defined ( ZDO_COORDINATOR )
   1607            //---------------------------------------------------------------------------
   1608          }
   1609          #endif // defined ( ZDSECMGR_COMMERCIAL )
   1610          
   1611          #if defined ( RTR_NWK )
   1612          /******************************************************************************
   1613           * @fn          ZDSecMgrDeviceRemove
   1614           *
   1615           * @brief       Remove device from network.
   1616           *
   1617           * @param       device - [in] ZDSecMgrDevice_t, device info
   1618           *
   1619           * @return      none
   1620           */

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   1621          void ZDSecMgrDeviceRemove( ZDSecMgrDevice_t* device )
   \                     ZDSecMgrDeviceRemove:
   1622          {
   \   000000   74F6         MOV     A,#-0xa
   \   000002   12....       LCALL   ?BANKED_ENTER_XDATA
   \   000005                ; Saved register size: 10
   \   000005                ; Auto size: 9
   \   000005   74F7         MOV     A,#-0x9
   \   000007   12....       LCALL   ?ALLOC_XSTACK8
   \   00000A   EA           MOV     A,R2
   \   00000B   FE           MOV     R6,A
   \   00000C   EB           MOV     A,R3
   \   00000D   FF           MOV     R7,A
   1623            APSME_RemoveDeviceReq_t remDevReq;
   1624            NLME_LeaveReq_t         leaveReq;
   1625            associated_devices_t*   assoc;
   1626          
   1627          
   1628            // check if parent, remove the device
   1629            if ( device->parentAddr == NLME_GetShortAddr() )
   \   00000E                ; Setup parameters for call to function NLME_GetShortAddr
   \   00000E   12....       LCALL   ?Subroutine5 & 0xFFFF
   \                     ??CrossCallReturnLabel_14:
   \   000011   7003         JNZ     ??ZDSecMgrDeviceRemove_0
   \   000013   A3           INC     DPTR
   \   000014   E0           MOVX    A,@DPTR
   \   000015   69           XRL     A,R1
   \                     ??ZDSecMgrDeviceRemove_0:
   \   000016   706B         JNZ     ??ZDSecMgrDeviceRemove_1
   1630            {
   1631              // this is the parent of the device
   1632              leaveReq.extAddr        = device->extAddr;
   \   000018   EE           MOV     A,R6
   \   000019   2402         ADD     A,#0x2
   \   00001B   12....       LCALL   ?Subroutine6 & 0xFFFF
   \                     ??CrossCallReturnLabel_16:
   \   00001E   FA           MOV     R2,A
   \   00001F   A3           INC     DPTR
   \   000020   E0           MOVX    A,@DPTR
   \   000021   FB           MOV     R3,A
   \   000022   85..82       MOV     DPL,?XSP + 0
   \   000025   85..83       MOV     DPH,?XSP + 1
   \   000028   EA           MOV     A,R2
   \   000029   F0           MOVX    @DPTR,A
   \   00002A   A3           INC     DPTR
   \   00002B   EB           MOV     A,R3
   \   00002C   F0           MOVX    @DPTR,A
   1633              leaveReq.removeChildren = FALSE;
   \   00002D   7402         MOV     A,#0x2
   \   00002F   12....       LCALL   ?XSTACK_DISP0_8
   \   000032   E4           CLR     A
   \   000033   F0           MOVX    @DPTR,A
   1634              leaveReq.rejoin         = FALSE;
   \   000034   7403         MOV     A,#0x3
   \   000036   12....       LCALL   ?XSTACK_DISP0_8
   \   000039   E4           CLR     A
   \   00003A   F0           MOVX    @DPTR,A
   1635          
   1636              // find child association
   1637              assoc = AssocGetWithExt( device->extAddr );
   \   00003B                ; Setup parameters for call to function AssocGetWithExt
   \   00003B   8882         MOV     DPL,R0
   \   00003D   8983         MOV     DPH,R1
   \   00003F   12....       LCALL   ?Subroutine4 & 0xFFFF
   \                     ??CrossCallReturnLabel_11:
   \   000042   8A..         MOV     ?V0 + 0,R2
   \   000044   8B..         MOV     ?V0 + 1,R3
   \   000046   A8..         MOV     R0,?V0 + 0
   \   000048   A9..         MOV     R1,?V0 + 1
   1638          
   1639              if ( ( assoc != NULL                            ) &&
   1640                   ( assoc->nodeRelation >= CHILD_RFD         ) &&
   1641                   ( assoc->nodeRelation <= CHILD_FFD_RX_IDLE )    )
   \   00004A   E8           MOV     A,R0
   \   00004B   7001         JNZ     ??ZDSecMgrDeviceRemove_2
   \   00004D   E9           MOV     A,R1
   \                     ??ZDSecMgrDeviceRemove_2:
   \   00004E   605E         JZ      ??ZDSecMgrDeviceRemove_3
   \   000050   8882         MOV     DPL,R0
   \   000052   8983         MOV     DPH,R1
   \   000054   A3           INC     DPTR
   \   000055   A3           INC     DPTR
   \   000056   A3           INC     DPTR
   \   000057   A3           INC     DPTR
   \   000058   E0           MOVX    A,@DPTR
   \   000059   6053         JZ      ??ZDSecMgrDeviceRemove_3
   \   00005B   C3           CLR     C
   \   00005C   9405         SUBB    A,#0x5
   \   00005E   504E         JNC     ??ZDSecMgrDeviceRemove_3
   1642              {
   1643                // check if associated device is authenticated
   1644                if ( assoc->devStatus & DEV_SEC_AUTH_STATUS )
   \   000060   8882         MOV     DPL,R0
   \   000062   8983         MOV     DPH,R1
   \   000064   A3           INC     DPTR
   \   000065   A3           INC     DPTR
   \   000066   A3           INC     DPTR
   \   000067   A3           INC     DPTR
   \   000068   A3           INC     DPTR
   \   000069   E0           MOVX    A,@DPTR
   \   00006A   A2E3         MOV     C,0xE0 /* A   */.3
   \   00006C   7404         MOV     A,#0x4
   \   00006E   5006         JNC     ??ZDSecMgrDeviceRemove_4
   1645                {
   1646                  leaveReq.silent = FALSE;
   \   000070   12....       LCALL   ?XSTACK_DISP0_8
   \   000073   E4           CLR     A
   \   000074   8005         SJMP    ??ZDSecMgrDeviceRemove_5
   1647                }
   1648                else
   1649                {
   1650                  leaveReq.silent = TRUE;
   \                     ??ZDSecMgrDeviceRemove_4:
   \   000076   12....       LCALL   ?XSTACK_DISP0_8
   \   000079   7401         MOV     A,#0x1
   \                     ??ZDSecMgrDeviceRemove_5:
   \   00007B   12....       LCALL   ?Subroutine1 & 0xFFFF
   1651                }
   1652          
   1653                NLME_LeaveReq( &leaveReq );
   \                     ??CrossCallReturnLabel_3:
   \   00007E   12....       LCALL   ??NLME_LeaveReq?relay
   \   000081   802B         SJMP    ??ZDSecMgrDeviceRemove_3
   1654              }
   1655            }
   1656            else
   1657            {
   1658              // this is not the parent of the device
   1659              remDevReq.parentAddr   = device->parentAddr;
   \                     ??ZDSecMgrDeviceRemove_1:
   \   000083   8E82         MOV     DPL,R6
   \   000085   8F83         MOV     DPH,R7
   \   000087   A3           INC     DPTR
   \   000088   A3           INC     DPTR
   \   000089   12....       LCALL   ?Subroutine7 & 0xFFFF
   \                     ??CrossCallReturnLabel_17:
   \   00008C   7405         MOV     A,#0x5
   \   00008E   12....       LCALL   ?XSTACK_DISP0_8
   \   000091   E8           MOV     A,R0
   \   000092   F0           MOVX    @DPTR,A
   \   000093   A3           INC     DPTR
   \   000094   E9           MOV     A,R1
   \   000095   12....       LCALL   ?Subroutine2 & 0xFFFF
   1660              remDevReq.childExtAddr = device->extAddr;
   \                     ??CrossCallReturnLabel_7:
   \   000098   7407         MOV     A,#0x7
   \   00009A   12....       LCALL   ?XSTACK_DISP0_8
   \   00009D   E8           MOV     A,R0
   \   00009E   F0           MOVX    @DPTR,A
   \   00009F   A3           INC     DPTR
   \   0000A0   E9           MOV     A,R1
   \   0000A1   F0           MOVX    @DPTR,A
   1661          
   1662              APSME_RemoveDeviceReq( &remDevReq );
   \   0000A2                ; Setup parameters for call to function APSME_RemoveDeviceReq
   \   0000A2   7405         MOV     A,#0x5
   \   0000A4   12....       LCALL   ?XSTACK_DISP0_8
   \   0000A7   AA82         MOV     R2,DPL
   \   0000A9   AB83         MOV     R3,DPH
   \   0000AB   12....       LCALL   ??APSME_RemoveDeviceReq?relay
   1663            }
   1664          }
   \                     ??ZDSecMgrDeviceRemove_3:
   \   0000AE   7409         MOV     A,#0x9
   \   0000B0   02....       LJMP    ?Subroutine8 & 0xFFFF

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   \                     ?Subroutine2:
   \   000000   F0           MOVX    @DPTR,A
   \   000001   8E82         MOV     DPL,R6
   \   000003   8F83         MOV     DPH,R7
   \   000005   12....       LCALL   ?Subroutine7 & 0xFFFF
   \                     ??CrossCallReturnLabel_21:
   \   000008   22           RET

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   \                     ?Subroutine1:
   \   000000   F0           MOVX    @DPTR,A
   \   000001                ; Setup parameters for call to function NLME_LeaveReq
   \   000001                ; Setup parameters for call to function APSME_UpdateDeviceReq
   \   000001                ; Setup parameters for call to function ZDSecMgrDeviceNew
   \   000001                ; Setup parameters for call to function ZDSecMgrDeviceRemove
   \   000001   85..82       MOV     DPL,?XSP + 0
   \   000004   85..83       MOV     DPH,?XSP + 1
   \   000007   AA82         MOV     R2,DPL
   \   000009   AB83         MOV     R3,DPH
   \   00000B   22           RET

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   \                     ?Subroutine4:
   \   000000   E0           MOVX    A,@DPTR
   \   000001   FA           MOV     R2,A
   \   000002   A3           INC     DPTR
   \   000003   E0           MOVX    A,@DPTR
   \   000004   FB           MOV     R3,A
   \   000005   12....       LCALL   ??AssocGetWithExt?relay
   \   000008   22           RET
   1665          #endif // defined( RTR_NWK )
   1666          
   1667          #if defined ( ZDSECMGR_COMMERCIAL )
   1668          #if !defined ( ZDO_COORDINATOR ) || defined( SOFT_START )
   1669          /******************************************************************************
   1670           * @fn          ZDSecMgrDeviceValidateSKKE
   1671           *
   1672           * @brief       Decide whether device is allowed for SKKE.
   1673           *
   1674           * @param       device - [in] ZDSecMgrDevice_t, device info
   1675           *
   1676           * @return      ZStatus_t
   1677           */
   1678          ZStatus_t ZDSecMgrDeviceValidateSKKE( ZDSecMgrDevice_t* device )
   1679          {
   1680            ZStatus_t status;
   1681            uint16    ami;
   1682            uint8*    key;
   1683          
   1684          
   1685            // get EXT address
   1686            status = ZDSecMgrExtAddrLookup( device->extAddr, &ami );
   1687          
   1688            if ( status == ZSuccess )
   1689            {
   1690              // get MASTER key
   1691              status = ZDSecMgrMasterKeyLookup( ami, &key );
   1692          
   1693              if ( status == ZSuccess )
   1694              {
   1695              //  // check if initiator is Trust Center
   1696              //  if ( device->nwkAddr == APSME_TRUSTCENTER_NWKADDR )
   1697              //  {
   1698              //    // verify NWK key not sent
   1699              //    // devtag.todo
   1700              //    // temporary - add device to internal data
   1701              //    status = ZDSecMgrDeviceEntryAdd( device, ami );
   1702              //  }
   1703              //  else
   1704              //  {
   1705              //    // initiator not Trust Center - End to End SKKE - set policy
   1706              //    // for accepting an SKKE initiation
   1707              //    // temporary - add device to internal data
   1708              //    status = ZDSecMgrDeviceEntryAdd( device, ami );
   1709              //  }
   1710                  status = ZDSecMgrDeviceEntryAdd( device, ami );
   1711              }
   1712            }
   1713          
   1714            return status;
   1715          }
   1716          #endif // !defined ( ZDO_COORDINATOR ) || defined ( SOFT_START )
   1717          #endif // defined ( ZDSECMGR_COMMERCIAL )
   1718          
   1719          #if defined ( ZDSECMGR_RESIDENTIAL )
   1720          #if defined ( ZDO_COORDINATOR )
   1721          /******************************************************************************
   1722           * @fn          ZDSecMgrDeviceValidateRM (RESIDENTIAL MODE)
   1723           *
   1724           * @brief       Decide whether device is allowed.
   1725           *
   1726           * @param       device - [in] ZDSecMgrDevice_t, device info
   1727           *
   1728           * @return      ZStatus_t
   1729           */
   1730          ZStatus_t ZDSecMgrDeviceValidateRM( ZDSecMgrDevice_t* device )
   1731          {
   1732            ZStatus_t status;
   1733            uint8     index;
   1734            uint8*    restricted;
   1735          
   1736            status = ZSuccess;
   1737          
   1738            // Look through the restricted device list
   1739            for ( index = 0; index < ZDSECMGR_RESTRICTED_DEVICES; index++ )
   1740            {
   1741              restricted = ZDSecMgrRestrictedDevices[index];
   1742          
   1743              if ( AddrMgrExtAddrEqual( restricted, device->extAddr )  == TRUE )
   1744              {
   1745                // return as unknown device in regards to validation
   1746                status = ZNwkUnknownDevice;
   1747          
   1748                // break from loop
   1749                index = ZDSECMGR_RESTRICTED_DEVICES;
   1750              }
   1751            }
   1752          
   1753            return status;
   1754          }
   1755          #endif // defined ( ZDO_COORDINATOR )
   1756          #endif // defined ( ZDSECMGR_RESIDENTIAL )
   1757          
   1758          #if defined ( ZDSECMGR_COMMERCIAL )
   1759          #if defined ( ZDO_COORDINATOR )
   1760          /******************************************************************************
   1761           * @fn          ZDSecMgrDeviceValidateCM (COMMERCIAL MODE)
   1762           *
   1763           * @brief       Decide whether device is allowed.
   1764           *
   1765           * @param       device - [in] ZDSecMgrDevice_t, device info
   1766           *
   1767           * @return      ZStatus_t
   1768           */
   1769          ZStatus_t ZDSecMgrDeviceValidateCM( ZDSecMgrDevice_t* device )
   1770          {
   1771            ZStatus_t status;
   1772            uint16    ami;
   1773            uint8*    key;
   1774          
   1775          
   1776            // check for pre configured setting
   1777            if ( device->secure == TRUE )
   1778            {
   1779              // get EXT address and MASTER key
   1780              status = ZDSecMgrExtAddrLookup( device->extAddr, &ami );
   1781          
   1782              if ( status == ZSuccess )
   1783              {
   1784                status = ZDSecMgrMasterKeyLookup( ami, &key );
   1785              }
   1786            }
   1787            else
   1788            {
   1789              // implement EXT address and MASTER key policy here -- the total number of
   1790              // Security Manager entries should never exceed the number of EXT addresses
   1791              // and MASTER keys available
   1792          
   1793              // set status based on policy
   1794              status = ZSuccess; // ZNwkUnknownDevice;
   1795          
   1796              // get the address index
   1797              if ( ZDSecMgrExtAddrLookup( device->extAddr, &ami ) != ZSuccess )
   1798              {
   1799                // if policy, store new EXT address
   1800                status = ZDSecMgrExtAddrStore( device->extAddr, &ami );
   1801              }
   1802          
   1803              // get the address index
   1804              if ( ZDSecMgrMasterKeyLookup( ami, &key ) != ZSuccess )
   1805              {
   1806                // if policy, store new key -- NULL will zero key
   1807                status = ZDSecMgrMasterKeyStore( ami, NULL );
   1808              }
   1809            }
   1810          
   1811            // if EXT address and MASTER key available -- add device
   1812            if ( status == ZSuccess )
   1813            {
   1814              // add device to internal data - with control
   1815              status = ZDSecMgrDeviceEntryAdd( device, ami );
   1816            }
   1817          
   1818            return status;
   1819          }
   1820          #endif // defined ( ZDO_COORDINATOR )
   1821          #endif // defined ( ZDSECMGR_COMMERCIAL )
   1822          
   1823          #if defined ( ZDO_COORDINATOR )
   1824          /******************************************************************************
   1825           * @fn          ZDSecMgrDeviceValidate
   1826           *
   1827           * @brief       Decide whether device is allowed.
   1828           *
   1829           * @param       device - [in] ZDSecMgrDevice_t, device info
   1830           *
   1831           * @return      ZStatus_t
   1832           */
   1833          ZStatus_t ZDSecMgrDeviceValidate( ZDSecMgrDevice_t* device )
   1834          {
   1835            ZStatus_t status;
   1836          
   1837          
   1838            if ( ZDSecMgrPermitJoiningEnabled == TRUE )
   1839            {
   1840              // device may be joining with a secure flag but it is ultimately the Trust
   1841              // Center that decides -- check if expected pre configured device --
   1842              // override settings
   1843              if ( zgPreConfigKeys == TRUE )
   1844              {
   1845                  device->secure = TRUE;
   1846              }
   1847              else
   1848              {
   1849                  device->secure = FALSE;
   1850              }
   1851          
   1852              //-------------------------------------------------------------------------
   1853              #if defined ( ZDSECMGR_COMMERCIAL )
   1854              //-------------------------------------------------------------------------
   1855              status = ZDSecMgrDeviceValidateCM( device );
   1856              //-------------------------------------------------------------------------
   1857              #else // defined( ZDSECMGR_RESIDENTIAL )
   1858              //-------------------------------------------------------------------------
   1859              status = ZDSecMgrDeviceValidateRM( device );
   1860              //-------------------------------------------------------------------------
   1861              #endif // defined( ZDSECMGR_RESIDENTIAL )
   1862              //-------------------------------------------------------------------------
   1863            }
   1864            else
   1865            {
   1866              status = ZNwkUnknownDevice;
   1867            }
   1868          
   1869            return status;
   1870          }
   1871          #endif // defined ( ZDO_COORDINATOR )
   1872          
   1873          #if defined ( ZDO_COORDINATOR )
   1874          /******************************************************************************
   1875           * @fn          ZDSecMgrDeviceJoin
   1876           *
   1877           * @brief       Try to join this device.
   1878           *
   1879           * @param       device - [in] ZDSecMgrDevice_t, device info
   1880           *
   1881           * @return      ZStatus_t
   1882           */
   1883          ZStatus_t ZDSecMgrDeviceJoin( ZDSecMgrDevice_t* device )
   1884          {
   1885            ZStatus_t status;
   1886          
   1887          
   1888            // attempt to validate device
   1889            status = ZDSecMgrDeviceValidate( device );
   1890          
   1891            if ( status == ZSuccess )
   1892            {
   1893              //-------------------------------------------------------------------------
   1894              #if defined ( ZDSECMGR_COMMERCIAL )
   1895              //-------------------------------------------------------------------------
   1896              ZDSecMgrDeviceCtrlSetup( device );
   1897              //-------------------------------------------------------------------------
   1898              #else // defined( ZDSECMGR_RESIDENTIAL )
   1899              //-------------------------------------------------------------------------
   1900              //send the nwk key data to the joining device
   1901              status = ZDSecMgrSendNwkKey( device );
   1902              //-------------------------------------------------------------------------
   1903              #endif // defined( ZDSECMGR_RESIDENTIAL )
   1904              //-------------------------------------------------------------------------
   1905            }
   1906            else
   1907            {
   1908              // not allowed, remove the device
   1909              ZDSecMgrDeviceRemove( device );
   1910            }
   1911          
   1912            return status;
   1913          }
   1914          #endif // defined ( ZDO_COORDINATOR )
   1915          
   1916          #if defined ( ZDO_COORDINATOR )
   1917          /******************************************************************************
   1918           * @fn          ZDSecMgrDeviceJoinDirect
   1919           *
   1920           * @brief       Try to join this device as a direct child.
   1921           *
   1922           * @param       device - [in] ZDSecMgrDevice_t, device info
   1923           *
   1924           * @return      ZStatus_t
   1925           */
   1926          ZStatus_t ZDSecMgrDeviceJoinDirect( ZDSecMgrDevice_t* device )
   1927          {
   1928            ZStatus_t status;
   1929          
   1930            status = ZDSecMgrDeviceJoin( device );
   1931          
   1932            if ( status == ZSuccess )
   1933            {
   1934              // set association status to authenticated
   1935              ZDSecMgrAssocDeviceAuth( AssocGetWithShort( device->nwkAddr ) );
   1936            }
   1937          
   1938            return status;
   1939          }
   1940          #endif // defined ( ZDO_COORDINATOR )
   1941          
   1942          #if !defined ( ZDO_COORDINATOR ) || defined( SOFT_START )
   1943          /******************************************************************************
   1944           * @fn          ZDSecMgrDeviceJoinFwd
   1945           *
   1946           * @brief       Forward join to Trust Center.
   1947           *
   1948           * @param       device - [in] ZDSecMgrDevice_t, device info
   1949           *
   1950           * @return      ZStatus_t
   1951           */

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   1952          ZStatus_t ZDSecMgrDeviceJoinFwd( ZDSecMgrDevice_t* device )
   \                     ZDSecMgrDeviceJoinFwd:
   1953          {
   \   000000   C082         PUSH    DPL
   \   000002   C083         PUSH    DPH
   \   000004                ; Saved register size: 2
   \   000004                ; Auto size: 7
   \   000004   74F9         MOV     A,#-0x7
   \   000006   12....       LCALL   ?ALLOC_XSTACK8
   1954            ZStatus_t               status;
   1955            APSME_UpdateDeviceReq_t req;
   1956          
   1957          
   1958            // forward any joining device to the Trust Center -- the Trust Center will
   1959            // decide if the device is allowed to join
   1960            status = ZSuccess;
   1961          
   1962            //if ( status == ZSuccess )
   1963            //{
   1964              // forward authorization to the Trust Center
   1965              req.dstAddr    = APSME_TRUSTCENTER_NWKADDR;
   \   000009   85..82       MOV     DPL,?XSP + 0
   \   00000C   85..83       MOV     DPH,?XSP + 1
   \   00000F   E4           CLR     A
   \   000010   F0           MOVX    @DPTR,A
   \   000011   A3           INC     DPTR
   \   000012   F0           MOVX    @DPTR,A
   1966              req.devAddr    = device->nwkAddr;
   \   000013   8A82         MOV     DPL,R2
   \   000015   8B83         MOV     DPH,R3
   \   000017   12....       LCALL   ??Subroutine7_0 & 0xFFFF
   \                     ??CrossCallReturnLabel_18:
   \   00001A   7402         MOV     A,#0x2
   \   00001C   12....       LCALL   ?XSTACK_DISP0_8
   \   00001F   12....       LCALL   ?Subroutine3 & 0xFFFF
   1967              req.devExtAddr = device->extAddr;
   \                     ??CrossCallReturnLabel_9:
   \   000022   12....       LCALL   ??Subroutine7_0 & 0xFFFF
   \                     ??CrossCallReturnLabel_19:
   \   000025   7404         MOV     A,#0x4
   \   000027   12....       LCALL   ?XSTACK_DISP0_8
   \   00002A   12....       LCALL   ?Subroutine3 & 0xFFFF
   1968          
   1969              // set security status, option for router to reject if policy set
   1970              if ( device->secure == TRUE )
   \                     ??CrossCallReturnLabel_10:
   \   00002D   A3           INC     DPTR
   \   00002E   A3           INC     DPTR
   \   00002F   A3           INC     DPTR
   \   000030   A3           INC     DPTR
   \   000031   E0           MOVX    A,@DPTR
   \   000032   6401         XRL     A,#0x1
   \   000034   7008         JNZ     ??ZDSecMgrDeviceJoinFwd_0
   1971              {
   1972                  req.status = APSME_UD_SECURED_JOIN;
   \   000036   7406         MOV     A,#0x6
   \   000038   12....       LCALL   ?XSTACK_DISP0_8
   \   00003B   E4           CLR     A
   \   00003C   8007         SJMP    ??ZDSecMgrDeviceJoinFwd_1
   1973              }
   1974              else
   1975              {
   1976                  req.status = APSME_UD_UNSECURED_JOIN;
   \                     ??ZDSecMgrDeviceJoinFwd_0:
   \   00003E   7406         MOV     A,#0x6
   \   000040   12....       LCALL   ?XSTACK_DISP0_8
   \   000043   7401         MOV     A,#0x1
   \                     ??ZDSecMgrDeviceJoinFwd_1:
   \   000045   12....       LCALL   ?Subroutine1 & 0xFFFF
   1977              }
   1978          
   1979              // send and APSME_UPDATE_DEVICE request to the trust center
   1980              status = APSME_UpdateDeviceReq( &req );
   1981            //}
   1982            //else
   1983            //{
   1984            //  // not allowed, remove the device
   1985            //  ZDSecMgrDeviceRemove( device );
   1986            //}
   1987          
   1988            return status;
   \                     ??CrossCallReturnLabel_4:
   \   000048   12....       LCALL   ??APSME_UpdateDeviceReq?relay
   \   00004B   7407         MOV     A,#0x7
   \   00004D   12....       LCALL   ?DEALLOC_XSTACK8
   \   000050   80..         SJMP    ??Subroutine9_0
   1989          }

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   \                     ?Subroutine3:
   \   000000   E8           MOV     A,R0
   \   000001   F0           MOVX    @DPTR,A
   \   000002   A3           INC     DPTR
   \   000003   E9           MOV     A,R1
   \   000004   F0           MOVX    @DPTR,A
   \   000005   8A82         MOV     DPL,R2
   \   000007   8B83         MOV     DPH,R3
   \   000009   A3           INC     DPTR
   \   00000A   A3           INC     DPTR
   \   00000B   22           RET

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   \                     ?Subroutine9:
   \   000000   C082         PUSH    DPL
   \   000002   C083         PUSH    DPH
   \   000004                ; Saved register size: 2
   \   000004                ; Auto size: 0
   \   000004                ; Setup parameters for call to function SSP_Init
   \   000004                ; Saved register size: 2
   \   000004                ; Auto size: 0
   \   000004                ; Setup parameters for call to function SSP_Init
   \   000004   12....       LCALL   ??SSP_Init?relay
   \   000007                ; Setup parameters for call to function APSME_SecurityRM_RD
   \   000007                ; Setup parameters for call to function APSME_SecurityRM_RD
   \   000007   12....       LCALL   ??APSME_SecurityRM_RD?relay
   \                     ??Subroutine9_0:
   \   00000A   D083         POP     DPH
   \   00000C   D082         POP     DPL
   \   00000E   02....       LJMP    ?BRET
   1990          #endif // !defined ( ZDO_COORDINATOR ) || defined ( SOFT_START )
   1991          
   1992          #if defined ( RTR_NWK )
   1993          /******************************************************************************
   1994           * @fn          ZDSecMgrDeviceNew
   1995           *
   1996           * @brief       Process a new device.
   1997           *
   1998           * @param       device - [in] ZDSecMgrDevice_t, device info
   1999           *
   2000           * @return      ZStatus_t
   2001           */

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   2002          ZStatus_t ZDSecMgrDeviceNew( ZDSecMgrDevice_t* joiner )
   \                     ZDSecMgrDeviceNew:
   2003          {
   \   000000   C082         PUSH    DPL
   \   000002   C083         PUSH    DPH
   \   000004                ; Saved register size: 2
   \   000004                ; Auto size: 0
   2004            ZStatus_t status;
   2005          
   2006            //---------------------------------------------------------------------------
   2007            #if defined ( ZDO_COORDINATOR ) && !defined ( SOFT_START )
   2008            //---------------------------------------------------------------------------
   2009            // try to join this device
   2010            status = ZDSecMgrDeviceJoinDirect( joiner );
   2011            //---------------------------------------------------------------------------
   2012            #elif defined ( ZDO_COORDINATOR ) && defined ( SOFT_START )
   2013            //---------------------------------------------------------------------------
   2014            // which mode -- COORD or ROUTER
   2015            if ( ZDO_Config_Node_Descriptor.LogicalType == NODETYPE_COORDINATOR )
   2016            {
   2017              // try to join this device
   2018              status = ZDSecMgrDeviceJoinDirect( joiner );
   2019            }
   2020            else
   2021            {
   2022              // forward join to Trust Center
   2023              status = ZDSecMgrDeviceJoinFwd( joiner );
   2024            }
   2025            //---------------------------------------------------------------------------
   2026            #else // !ZDO_COORDINATOR
   2027            //---------------------------------------------------------------------------
   2028            // forward join to Trust Center
   2029            status = ZDSecMgrDeviceJoinFwd( joiner );
   2030            //---------------------------------------------------------------------------
   2031            #endif // !ZDO_COORDINATOR
   2032            //---------------------------------------------------------------------------
   2033          
   2034            return status;
   \   000004                ; Setup parameters for call to function ZDSecMgrDeviceJoinFwd
   \   000004   12....       LCALL   ??ZDSecMgrDeviceJoinFwd?relay
   \   000007   80..         SJMP    ??Subroutine9_0
   2035          }
   2036          #endif // defined ( RTR_NWK )
   2037          
   2038          #if defined ( RTR_NWK )
   2039          /******************************************************************************
   2040           * @fn          ZDSecMgrAssocDeviceAuth
   2041           *
   2042           * @brief       Set associated device status to authenticated
   2043           *
   2044           * @param       assoc - [in, out] associated_devices_t
   2045           *
   2046           * @return      none
   2047           */

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   2048          void ZDSecMgrAssocDeviceAuth( associated_devices_t* assoc )
   \                     ZDSecMgrAssocDeviceAuth:
   2049          {
   \   000000   C082         PUSH    DPL
   \   000002   C083         PUSH    DPH
   \   000004                ; Saved register size: 2
   \   000004                ; Auto size: 0
   2050            if ( assoc != NULL )
   \   000004   EA           MOV     A,R2
   \   000005   7001         JNZ     ??ZDSecMgrAssocDeviceAuth_0
   \   000007   EB           MOV     A,R3
   \                     ??ZDSecMgrAssocDeviceAuth_0:
   \   000008   600D         JZ      ??ZDSecMgrAssocDeviceAuth_1
   2051            {
   2052              assoc->devStatus |= DEV_SEC_AUTH_STATUS;
   \   00000A   8A82         MOV     DPL,R2
   \   00000C   8B83         MOV     DPH,R3
   \   00000E   A3           INC     DPTR
   \   00000F   A3           INC     DPTR
   \   000010   A3           INC     DPTR
   \   000011   A3           INC     DPTR
   \   000012   A3           INC     DPTR
   \   000013   E0           MOVX    A,@DPTR
   \   000014   D2E3         SETB    0xE0 /* A   */.3
   \   000016   F0           MOVX    @DPTR,A
   2053            }
   2054          }
   \                     ??ZDSecMgrAssocDeviceAuth_1:
   \   000017   80..         SJMP    ??Subroutine9_0
   2055          #endif // defined ( RTR_NWK )
   2056          #endif // defined ( ZDSECMGR_SECURE )
   2057          
   2058          /******************************************************************************
   2059           * PUBLIC FUNCTIONS
   2060           */
   2061          /******************************************************************************
   2062           * @fn          ZDSecMgrInit
   2063           *
   2064           * @brief       Initialize ZigBee Device Security Manager.
   2065           *
   2066           * @param       none
   2067           *
   2068           * @return      none
   2069           */
   2070          #if defined ( ZDSECMGR_COMMERCIAL )
   2071          #if ( ADDRMGR_CALLBACK_ENABLED == 1 )
   2072          void ZDSecMgrAddrMgrCB( uint8           update,
   2073                                  AddrMgrEntry_t* newEntry,
   2074                                  AddrMgrEntry_t* oldEntry )
   2075          {
   2076            (void)update;
   2077            (void)newEntry;
   2078            (void)oldEntry;
   2079          }
   2080          #endif // ( ADDRMGR_CALLBACK_ENABLED == 1 )
   2081          #endif // defined ( ZDSECMGR_COMMERCIAL )
   2082          

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   2083          void ZDSecMgrInit( void )
   \                     ZDSecMgrInit:
   \   000000   80..         SJMP    ?Subroutine9
   2084          {
   2085            //---------------------------------------------------------------------------
   2086            #if defined ( ZDSECMGR_COMMERCIAL )
   2087            //---------------------------------------------------------------------------
   2088            // initialize sub modules
   2089            ZDSecMgrMasterKeyInit();
   2090            ZDSecMgrEntryInit();
   2091            ZDSecMgrCtrlInit();
   2092          
   2093            // configure SKKE slot data
   2094            APSME_SKKE_SlotInit( ZDSECMGR_SKKE_SLOT_MAX );
   2095          
   2096            // register with Address Manager
   2097            #if ( ADDRMGR_CALLBACK_ENABLED == 1 )
   2098            AddrMgrRegister( ADDRMGR_REG_SECURITY, ZDSecMgrAddrMgrCB );
   2099            #endif
   2100            //---------------------------------------------------------------------------
   2101            #endif // defined ( ZDSECMGR_COMMERCIAL )
   2102            //---------------------------------------------------------------------------
   2103          
   2104            //---------------------------------------------------------------------------
   2105            #if defined ( ZDSECMGR_SECURE ) && defined ( ZDO_COORDINATOR )
   2106            //---------------------------------------------------------------------------
   2107            // setup joining permissions
   2108            ZDSecMgrPermitJoiningEnabled = TRUE;
   2109            ZDSecMgrPermitJoiningTimed   = FALSE;
   2110            //---------------------------------------------------------------------------
   2111            #endif // defined ( ZDSECMGR_SECURE ) && defined ( ZDO_COORDINATOR )
   2112            //---------------------------------------------------------------------------
   2113          
   2114            // configure security based on security mode and type of device
   2115            ZDSecMgrConfig();
   2116          }
   2117          
   2118          /******************************************************************************
   2119           * @fn          ZDSecMgrConfig
   2120           *
   2121           * @brief       Configure ZigBee Device Security Manager.
   2122           *
   2123           * @param       none
   2124           *
   2125           * @return      none
   2126           */

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   2127          void ZDSecMgrConfig( void )
   \                     ZDSecMgrConfig:
   \   000000   80..         SJMP    ?Subroutine9
   2128          {
   2129            #if defined ( ZDSECMGR_SECURE )
   2130            SSP_Init();
   2131            #endif
   2132          
   2133            //---------------------------------------------------------------------------
   2134            #if defined ( ZDSECMGR_COMMERCIAL )
   2135            //---------------------------------------------------------------------------
   2136            {
   2137              #if defined ( ZDO_COORDINATOR )
   2138              {
   2139                #if defined ( SOFT_START )
   2140                {
   2141                  //switch here
   2142                  if ( ZDO_Config_Node_Descriptor.LogicalType == NODETYPE_COORDINATOR )
   2143                  {
   2144                    // COMMERCIAL MODE - COORDINATOR DEVICE
   2145                    APSME_SecurityCM_CD();
   2146                  }
   2147                  else
   2148                  {
   2149                    // COMMERCIAL MODE - ROUTER DEVICE
   2150                    APSME_SecurityCM_RD();
   2151                  }
   2152                }
   2153                #else
   2154                {
   2155                  // COMMERCIAL MODE - COORDINATOR DEVICE
   2156                  APSME_SecurityCM_CD();
   2157                }
   2158                #endif
   2159              }
   2160              #elif defined ( RTR_NWK )
   2161              {
   2162                // COMMERCIAL MODE - ROUTER DEVICE
   2163                APSME_SecurityCM_RD();
   2164              }
   2165              #else
   2166              {
   2167                // COMMERCIAL MODE - END DEVICE
   2168                APSME_SecurityCM_ED();
   2169              }
   2170              #endif
   2171            }
   2172            //---------------------------------------------------------------------------
   2173            #elif defined (ZDSECMGR_RESIDENTIAL )
   2174            //---------------------------------------------------------------------------
   2175            {
   2176              #if defined ( ZDO_COORDINATOR )
   2177              {
   2178                #if defined ( SOFT_START )
   2179                {
   2180                  //switch here
   2181                  if ( ZDO_Config_Node_Descriptor.LogicalType == NODETYPE_COORDINATOR )
   2182                  {
   2183                    // RESIDENTIAL MODE - COORDINATOR DEVICE
   2184                    APSME_SecurityRM_CD();
   2185                  }
   2186                  else
   2187                  {
   2188                    // RESIDENTIAL MODE - ROUTER DEVICE
   2189                    APSME_SecurityRM_RD();
   2190                  }
   2191                }
   2192                #else
   2193                {
   2194                  // RESIDENTIAL MODE - COORDINATOR DEVICE
   2195                  APSME_SecurityRM_CD();
   2196                }
   2197                #endif
   2198              }
   2199              #elif defined ( RTR_NWK )
   2200              {
   2201                // RESIDENTIAL MODE - ROUTER DEVICE
   2202                APSME_SecurityRM_RD();
   2203              }
   2204              #else
   2205              {
   2206                // RESIDENTIAL MODE - END DEVICE
   2207                APSME_SecurityRM_ED();
   2208              }
   2209              #endif
   2210            }
   2211            //---------------------------------------------------------------------------
   2212            #else
   2213            //---------------------------------------------------------------------------
   2214            {
   2215              // NO SECURITY
   2216              APSME_SecurityNM();
   2217            }
   2218            //---------------------------------------------------------------------------
   2219            #endif
   2220            //---------------------------------------------------------------------------
   2221          }
   2222          
   2223          #if defined( ZDO_MGMT_PERMIT_JOIN_RESPONSE ) && defined( RTR_NWK )
   2224          /******************************************************************************
   2225           * @fn          ZDSecMgrPermitJoining
   2226           *
   2227           * @brief       Process request to change joining permissions.
   2228           *
   2229           * @param       duration - [in] timed duration for join in seconds
   2230           *                         - 0x00 not allowed
   2231           *                         - 0xFF allowed without timeout
   2232           *
   2233           * @return      uint8 - success(TRUE:FALSE)
   2234           */
   2235          uint8 ZDSecMgrPermitJoining( uint8 duration )
   2236          {
   2237            //---------------------------------------------------------------------------
   2238            #if defined ( ZDSECMGR_SECURE ) && defined ( ZDO_COORDINATOR )
   2239            //---------------------------------------------------------------------------
   2240            uint8 accept;
   2241          
   2242          
   2243            ZDSecMgrPermitJoiningTimed = FALSE;
   2244          
   2245            if ( duration > 0 )
   2246            {
   2247              ZDSecMgrPermitJoiningEnabled = TRUE;
   2248          
   2249              if ( duration != 0xFF )
   2250              {
   2251                ZDSecMgrPermitJoiningTimed = TRUE;
   2252              }
   2253            }
   2254            else
   2255            {
   2256              ZDSecMgrPermitJoiningEnabled = FALSE;
   2257            }
   2258          
   2259            accept = TRUE;
   2260          
   2261            return accept;
   2262            //---------------------------------------------------------------------------
   2263            #else // !defined ( ZDSECMGR_SECURE ) || !defined ( ZDO_COORDINATOR )
   2264            //---------------------------------------------------------------------------
   2265            return FALSE;
   2266            //---------------------------------------------------------------------------
   2267            #endif // !defined ( ZDSECMGR_SECURE ) || !defined ( ZDO_COORDINATOR )
   2268            //---------------------------------------------------------------------------
   2269          }
   2270          #endif // defined( ZDO_MGMT_PERMIT_JOIN_RESPONSE ) && defined( RTR_NWK )
   2271          
   2272          #if defined( ZDO_MGMT_PERMIT_JOIN_RESPONSE ) && defined( RTR_NWK )
   2273          /******************************************************************************
   2274           * @fn          ZDSecMgrPermitJoiningTimeout
   2275           *
   2276           * @brief       Process permit joining timeout
   2277           *
   2278           * @param       none
   2279           *
   2280           * @return      none
   2281           */
   2282          void ZDSecMgrPermitJoiningTimeout( void )
   2283          {
   2284            //---------------------------------------------------------------------------
   2285            #if defined ( ZDSECMGR_SECURE ) && defined ( ZDO_COORDINATOR )
   2286            //---------------------------------------------------------------------------
   2287            if ( ZDSecMgrPermitJoiningTimed == TRUE )
   2288            {
   2289              ZDSecMgrPermitJoiningEnabled = FALSE;
   2290              ZDSecMgrPermitJoiningTimed   = FALSE;
   2291            }
   2292            //---------------------------------------------------------------------------
   2293            #endif // defined ( ZDSECMGR_SECURE ) && defined ( ZDO_COORDINATOR )
   2294            //---------------------------------------------------------------------------
   2295          }
   2296          #endif // defined( ZDO_MGMT_PERMIT_JOIN_RESPONSE ) && defined( RTR_NWK )
   2297          
   2298          #if defined ( ZDSECMGR_SECURE )
   2299          #if defined ( RTR_NWK )
   2300          /******************************************************************************
   2301           * @fn          ZDSecMgrNewDeviceEvent
   2302           *
   2303           * @brief       Process a the new device event, if found reset new device
   2304           *              event/timer.
   2305           *
   2306           * @param       none
   2307           *
   2308           * @return      uint8 - found(TRUE:FALSE)
   2309           */

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   2310          uint8 ZDSecMgrNewDeviceEvent( void )
   \                     ZDSecMgrNewDeviceEvent:
   2311          {
   \   000000   74F4         MOV     A,#-0xc
   \   000002   12....       LCALL   ?BANKED_ENTER_XDATA
   \   000005                ; Saved register size: 12
   \   000005                ; Auto size: 22
   \   000005   74EA         MOV     A,#-0x16
   \   000007   12....       LCALL   ?ALLOC_XSTACK8
   2312            uint8                 found;
   2313            ZDSecMgrDevice_t      device;
   2314            AddrMgrEntry_t        addrEntry;
   2315            associated_devices_t* assoc;
   2316            ZStatus_t             status;
   2317          
   2318            // initialize return results
   2319            found = FALSE;
   \   00000A   75..00       MOV     ?V0 + 0,#0x0
   2320          
   2321            // look for device in the security init state
   2322            assoc = AssocMatchDeviceStatus( DEV_SEC_INIT_STATUS );
   \   00000D                ; Setup parameters for call to function AssocMatchDeviceStatus
   \   00000D   7904         MOV     R1,#0x4
   \   00000F   12....       LCALL   ??AssocMatchDeviceStatus?relay
   \   000012   8A..         MOV     ?V0 + 2,R2
   \   000014   8B..         MOV     ?V0 + 3,R3
   \   000016   AE..         MOV     R6,?V0 + 2
   \   000018   AF..         MOV     R7,?V0 + 3
   2323          
   2324            if ( assoc != NULL )
   \   00001A   EE           MOV     A,R6
   \   00001B   7001         JNZ     ??ZDSecMgrNewDeviceEvent_0
   \   00001D   EF           MOV     A,R7
   \                     ??ZDSecMgrNewDeviceEvent_0:
   \   00001E   7003         JNZ     $+5
   \   000020   02....       LJMP    ??ZDSecMgrNewDeviceEvent_1 & 0xFFFF
   2325            {
   2326              // device found
   2327              found = TRUE;
   \   000023   75..01       MOV     ?V0 + 0,#0x1
   2328          
   2329              // check for preconfigured security
   2330              if ( zgPreConfigKeys == TRUE )
   \   000026   90....       MOV     DPTR,#zgPreConfigKeys
   \   000029   E0           MOVX    A,@DPTR
   \   00002A   6401         XRL     A,#0x1
   \   00002C   7003         JNZ     ??ZDSecMgrNewDeviceEvent_2
   2331              {
   2332                // set association status to authenticated
   2333                ZDSecMgrAssocDeviceAuth( assoc );
   \   00002E                ; Setup parameters for call to function ZDSecMgrAssocDeviceAuth
   \   00002E   12....       LCALL   ??ZDSecMgrAssocDeviceAuth?relay
   2334              }
   2335          
   2336              // set up device info
   2337              addrEntry.user  = ADDRMGR_USER_DEFAULT;
   \                     ??ZDSecMgrNewDeviceEvent_2:
   \   000031   7409         MOV     A,#0x9
   \   000033   12....       LCALL   ?XSTACK_DISP0_8
   \   000036   E4           CLR     A
   \   000037   12....       LCALL   ?Subroutine2 & 0xFFFF
   2338              addrEntry.index = assoc->addrIdx;
   \                     ??CrossCallReturnLabel_8:
   \   00003A   7414         MOV     A,#0x14
   \   00003C   12....       LCALL   ?XSTACK_DISP0_8
   \   00003F   E8           MOV     A,R0
   \   000040   F0           MOVX    @DPTR,A
   \   000041   A3           INC     DPTR
   \   000042   E9           MOV     A,R1
   \   000043   F0           MOVX    @DPTR,A
   2339              AddrMgrEntryGet( &addrEntry );
   \   000044                ; Setup parameters for call to function AddrMgrEntryGet
   \   000044   7409         MOV     A,#0x9
   \   000046   12....       LCALL   ?XSTACK_DISP0_8
   \   000049   AA82         MOV     R2,DPL
   \   00004B   AB83         MOV     R3,DPH
   \   00004D   12....       LCALL   ??AddrMgrEntryGet?relay
   2340          
   2341              device.nwkAddr    = assoc->shortAddr;
   \   000050   12....       LCALL   ?Subroutine0 & 0xFFFF
   2342              device.extAddr    = addrEntry.extAddr;
   \                     ??CrossCallReturnLabel_2:
   \   000053   740C         MOV     A,#0xc
   \   000055   12....       LCALL   ?XSTACK_DISP0_8
   \   000058   A882         MOV     R0,DPL
   \   00005A   A983         MOV     R1,DPH
   \   00005C   7402         MOV     A,#0x2
   \   00005E   12....       LCALL   ?XSTACK_DISP0_8
   \   000061   E8           MOV     A,R0
   \   000062   F0           MOVX    @DPTR,A
   \   000063   A3           INC     DPTR
   \   000064   E9           MOV     A,R1
   \   000065   F0           MOVX    @DPTR,A
   2343              device.parentAddr = NLME_GetShortAddr();
   \   000066                ; Setup parameters for call to function NLME_GetShortAddr
   \   000066   12....       LCALL   ??NLME_GetShortAddr?relay
   \   000069   7404         MOV     A,#0x4
   \   00006B   12....       LCALL   ?XSTACK_DISP0_8
   \   00006E   EA           MOV     A,R2
   \   00006F   F0           MOVX    @DPTR,A
   \   000070   A3           INC     DPTR
   \   000071   EB           MOV     A,R3
   \   000072   F0           MOVX    @DPTR,A
   2344              device.secure     = FALSE;
   \   000073   7406         MOV     A,#0x6
   \   000075   12....       LCALL   ?XSTACK_DISP0_8
   \   000078   E4           CLR     A
   \   000079   12....       LCALL   ?Subroutine1 & 0xFFFF
   2345          
   2346              // process new device
   2347              status = ZDSecMgrDeviceNew( &device );
   \                     ??CrossCallReturnLabel_5:
   \   00007C   12....       LCALL   ??ZDSecMgrDeviceNew?relay
   \   00007F   E9           MOV     A,R1
   \   000080   FA           MOV     R2,A
   2348          
   2349              if ( status == ZSuccess )
   \   000081   700F         JNZ     ??ZDSecMgrNewDeviceEvent_3
   2350              {
   2351                assoc->devStatus &= ~DEV_SEC_INIT_STATUS;
   \   000083   8E82         MOV     DPL,R6
   \   000085   8F83         MOV     DPH,R7
   \   000087   A3           INC     DPTR
   \   000088   A3           INC     DPTR
   \   000089   A3           INC     DPTR
   \   00008A   A3           INC     DPTR
   \   00008B   A3           INC     DPTR
   \   00008C   E0           MOVX    A,@DPTR
   \   00008D   C2E2         CLR     0xE0 /* A   */.2
   \   00008F   F0           MOVX    @DPTR,A
   \   000090   8011         SJMP    ??ZDSecMgrNewDeviceEvent_1
   2352              }
   2353              else if ( status == ZNwkUnknownDevice )
   \                     ??ZDSecMgrNewDeviceEvent_3:
   \   000092   74C8         MOV     A,#-0x38
   \   000094   6A           XRL     A,R2
   \   000095   700C         JNZ     ??ZDSecMgrNewDeviceEvent_1
   2354              {
   2355                AssocRemove( addrEntry.extAddr );
   \   000097                ; Setup parameters for call to function AssocRemove
   \   000097   740C         MOV     A,#0xc
   \   000099   12....       LCALL   ?XSTACK_DISP0_8
   \   00009C   AA82         MOV     R2,DPL
   \   00009E   AB83         MOV     R3,DPH
   \   0000A0   12....       LCALL   ??AssocRemove?relay
   2356              }
   2357            }
   2358          
   2359            return found;
   \                     ??ZDSecMgrNewDeviceEvent_1:
   \   0000A3   A9..         MOV     R1,?V0 + 0
   \   0000A5   7416         MOV     A,#0x16
   \   0000A7   12....       LCALL   ?DEALLOC_XSTACK8
   \   0000AA   7F04         MOV     R7,#0x4
   \   0000AC   02....       LJMP    ?BANKED_LEAVE_XDATA
   2360          }
   2361          #endif // defined ( RTR_NWK )
   2362          #endif // defined ( ZDSECMGR_SECURE )
   2363          
   2364          #if defined( ZDSECMGR_COMMERCIAL )
   2365          /******************************************************************************
   2366           * @fn          ZDSecMgrEvent
   2367           *
   2368           * @brief       Handle ZDO Security Manager event/timer(ZDO_SECMGR_EVENT).
   2369           *
   2370           * @param       none
   2371           *
   2372           * @return      none
   2373           */
   2374          void ZDSecMgrEvent( void )
   2375          {
   2376            //---------------------------------------------------------------------------
   2377            #if defined ( ZDO_COORDINATOR )
   2378            //---------------------------------------------------------------------------
   2379            uint8            action;
   2380            uint8            restart;
   2381            uint16           index;
   2382            AddrMgrEntry_t   entry;
   2383            ZDSecMgrDevice_t device;
   2384          
   2385          
   2386            // verify data is available
   2387            if ( ZDSecMgrCtrlData != NULL )
   2388            {
   2389              action  = FALSE;
   2390              restart = FALSE;
   2391          
   2392              // update all the counters
   2393              for ( index = 0; index < ZDSECMGR_ENTRY_MAX; index++ )
   2394              {
   2395                if ( ZDSecMgrCtrlData[index].state !=  ZDSECMGR_CTRL_NONE )
   2396                {
   2397                  if ( ZDSecMgrCtrlData[index].cntr != 0 )
   2398                  {
   2399                    ZDSecMgrCtrlData[index].cntr--;
   2400                  }
   2401          
   2402                  if ( ( action == FALSE ) && ( ZDSecMgrCtrlData[index].cntr == 0 ) )
   2403                  {
   2404                    action = TRUE;
   2405          
   2406                    // update from control data
   2407                    device.parentAddr = ZDSecMgrCtrlData[index].parentAddr;
   2408                    device.secure     = ZDSecMgrCtrlData[index].secure;
   2409                    device.ctrl       = &ZDSecMgrCtrlData[index];
   2410          
   2411                    // set the user and address index
   2412                    entry.user  = ADDRMGR_USER_SECURITY;
   2413                    entry.index = ZDSecMgrCtrlData[index].entry->ami;
   2414          
   2415                    // get the address data
   2416                    AddrMgrEntryGet( &entry );
   2417          
   2418                    // set device address data
   2419                    device.nwkAddr = entry.nwkAddr;
   2420                    device.extAddr = entry.extAddr;
   2421          
   2422                    // update from entry data
   2423                    ZDSecMgrDeviceCtrlHandler( &device );
   2424                  }
   2425                  else
   2426                  {
   2427                    restart = TRUE;
   2428                  }
   2429                }
   2430              }
   2431          
   2432              // check for timer restart
   2433              if ( restart == TRUE )
   2434              {
   2435                osal_start_timerEx(ZDAppTaskID, ZDO_SECMGR_EVENT, 100 );
   2436              }
   2437            }
   2438            //---------------------------------------------------------------------------
   2439            #endif // defined ( ZDO_COORDINATOR )
   2440            //---------------------------------------------------------------------------
   2441          }
   2442          #endif // defined ( ZDSECMGR_COMMERCIAL )
   2443          
   2444          #if defined ( ZDSECMGR_COMMERCIAL )
   2445          /******************************************************************************
   2446           * @fn          ZDSecMgrEstablishKeyCfm
   2447           *
   2448           * @brief       Process the ZDO_EstablishKeyCfm_t message.
   2449           *
   2450           * @param       cfm - [in] ZDO_EstablishKeyCfm_t confirmation
   2451           *
   2452           * @return      none
   2453           */
   2454          void ZDSecMgrEstablishKeyCfm( ZDO_EstablishKeyCfm_t* cfm )
   2455          {
   2456            // send the NWK key
   2457            if ( ZDO_Config_Node_Descriptor.LogicalType == NODETYPE_COORDINATOR )
   2458            {
   2459              // update control for specified EXT address
   2460              ZDSecMgrDeviceCtrlUpdate( cfm->partExtAddr, ZDSECMGR_CTRL_SKKE_DONE );
   2461            }
   2462            else
   2463            {
   2464              // this should be done when receiving the NWK key
   2465              // if devState ==
   2466              //if ( devState == DEV_END_DEVICE_UNAUTH )
   2467                  //osal_set_event( ZDAppTaskID, ZDO_DEVICE_AUTH );
   2468          
   2469              // if not in joining state -- this should trigger an event for an
   2470              // end point that requested SKKE
   2471              // if ( devState == DEV_END_DEVICE )
   2472             //       devState == DEV_ROUTER;
   2473          
   2474            }
   2475          }
   2476          #endif // defined ( ZDSECMGR_COMMERCIAL )
   2477          
   2478          #if defined ( ZDSECMGR_COMMERCIAL )
   2479          #if !defined ( ZDO_COORDINATOR ) || defined ( SOFT_START )
   2480          /******************************************************************************
   2481           * @fn          ZDSecMgrEstablishKeyInd
   2482           *
   2483           * @brief       Process the ZDO_EstablishKeyInd_t message.
   2484           *
   2485           * @param       ind - [in] ZDO_EstablishKeyInd_t indication
   2486           *
   2487           * @return      none
   2488           */
   2489          void ZDSecMgrEstablishKeyInd( ZDO_EstablishKeyInd_t* ind )
   2490          {
   2491            ZDSecMgrDevice_t        device;
   2492            APSME_EstablishKeyRsp_t rsp;
   2493          
   2494          
   2495            device.extAddr = ind->initExtAddr;
   2496            device.secure  = ind->secure;
   2497          
   2498            if ( ind->secure == FALSE )
   2499            {
   2500              // SKKE from Trust Center is not secured between child and parent
   2501              device.nwkAddr    = APSME_TRUSTCENTER_NWKADDR;
   2502              device.parentAddr = ind->srcAddr;
   2503            }
   2504            else
   2505            {
   2506              // SKKE from initiator should be secured
   2507              device.nwkAddr    = ind->srcAddr;
   2508              device.parentAddr = INVALID_NODE_ADDR;
   2509            }
   2510          
   2511            rsp.dstAddr     = ind->srcAddr;
   2512            rsp.initExtAddr = &ind->initExtAddr[0];
   2513            rsp.secure      = ind->secure;
   2514          
   2515            // validate device for SKKE
   2516            if ( ZDSecMgrDeviceValidateSKKE( &device ) == ZSuccess )
   2517            {
   2518              rsp.accept = TRUE;
   2519            }
   2520            else
   2521            {
   2522              rsp.accept = FALSE;
   2523            }
   2524          
   2525            APSME_EstablishKeyRsp( &rsp );
   2526          }
   2527          #endif // !defined ( ZDO_COORDINATOR ) || defined ( SOFT_START )
   2528          #endif // defined ( ZDSECMGR_COMMERCIAL )
   2529          
   2530          #if defined ( ZDSECMGR_SECURE )
   2531          #if !defined ( ZDO_COORDINATOR ) || defined( SOFT_START )
   2532          /******************************************************************************
   2533           * @fn          ZDSecMgrTransportKeyInd
   2534           *
   2535           * @brief       Process the ZDO_TransportKeyInd_t message.
   2536           *
   2537           * @param       ind - [in] ZDO_TransportKeyInd_t indication
   2538           *
   2539           * @return      none
   2540           */

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   2541          void ZDSecMgrTransportKeyInd( ZDO_TransportKeyInd_t* ind )
   \                     ZDSecMgrTransportKeyInd:
   2542          {
   \   000000   74F6         MOV     A,#-0xa
   \   000002   12....       LCALL   ?BANKED_ENTER_XDATA
   \   000005                ; Saved register size: 10
   \   000005                ; Auto size: 0
   \   000005   EA           MOV     A,R2
   \   000006   FE           MOV     R6,A
   \   000007   EB           MOV     A,R3
   \   000008   FF           MOV     R7,A
   2543            uint8 index;
   2544          
   2545          
   2546            if ( ind->keyType == KEY_TYPE_TC_MASTER )
   \   000009   8E82         MOV     DPL,R6
   \   00000B   8F83         MOV     DPH,R7
   \   00000D   A3           INC     DPTR
   \   00000E   A3           INC     DPTR
   \   00000F   A3           INC     DPTR
   \   000010   A3           INC     DPTR
   \   000011   E0           MOVX    A,@DPTR
   \   000012   606A         JZ      ??ZDSecMgrTransportKeyInd_0
   2547            {
   2548              #if defined ( ZDSECMGR_COMMERCIAL )
   2549              {
   2550                if ( zgPreConfigKeys != TRUE )
   2551                {
   2552                  ZDSecMgrMasterKeyLoad( ind->srcAddr, ind->srcExtAddr, ind->key );
   2553                }
   2554                else
   2555                {
   2556                  // error condition - reject key
   2557                }
   2558              }
   2559              #endif // defined ( ZDSECMGR_COMMERCIAL )
   2560            }
   2561            else if ( ind->keyType == KEY_TYPE_NWK )
   \   000014   6401         XRL     A,#0x1
   \   000016   7066         JNZ     ??ZDSecMgrTransportKeyInd_0
   2562            {
   2563              // check for dummy NWK key (all zeros)
   2564              for ( index = 0;
   \   000018   7A00         MOV     R2,#0x0
   \                     ??ZDSecMgrTransportKeyInd_1:
   \   00001A   8A..         MOV     ?V0 + 0,R2
   \   00001C   EE           MOV     A,R6
   \   00001D   25..         ADD     A,?V0 + 0
   \   00001F   F582         MOV     DPL,A
   \   000021   EF           MOV     A,R7
   \   000022   3400         ADDC    A,#0x0
   \   000024   F583         MOV     DPH,A
   \   000026   A3           INC     DPTR
   \   000027   A3           INC     DPTR
   \   000028   A3           INC     DPTR
   \   000029   A3           INC     DPTR
   \   00002A   A3           INC     DPTR
   \   00002B   A3           INC     DPTR
   \   00002C   E0           MOVX    A,@DPTR
   \   00002D   7007         JNZ     ??ZDSecMgrTransportKeyInd_2
   2565                    ( (index < SEC_KEY_LEN) && (ind->key[index] == 0) );
   2566                    index++ );
   \   00002F   0A           INC     R2
   \   000030   EA           MOV     A,R2
   \   000031   C3           CLR     C
   \   000032   9410         SUBB    A,#0x10
   \   000034   40E4         JC      ??ZDSecMgrTransportKeyInd_1
   2567          
   2568              if ( index == SEC_KEY_LEN )
   \                     ??ZDSecMgrTransportKeyInd_2:
   \   000036   7410         MOV     A,#0x10
   \   000038   6A           XRL     A,R2
   \   000039   700D         JNZ     ??ZDSecMgrTransportKeyInd_3
   2569              {
   2570                // load preconfigured key
   2571                SSP_UpdateNwkKey( (byte*)zgPreConfigKey, 0 );
   \   00003B                ; Setup parameters for call to function SSP_UpdateNwkKey
   \   00003B   7900         MOV     R1,#0x0
   \   00003D   7A..         MOV     R2,#(zgPreConfigKey & 0xff)
   \   00003F   7B..         MOV     R3,#((zgPreConfigKey >> 8) & 0xff)
   \   000041   12....       LCALL   ??SSP_UpdateNwkKey?relay
   2572                SSP_SwitchNwkKey( 0 );
   \   000044                ; Setup parameters for call to function SSP_SwitchNwkKey
   \   000044   7900         MOV     R1,#0x0
   \   000046   8027         SJMP    ??ZDSecMgrTransportKeyInd_4
   2573              }
   2574              else
   2575              {
   2576                SSP_UpdateNwkKey( ind->key, ind->keySeqNum );
   \                     ??ZDSecMgrTransportKeyInd_3:
   \   000048                ; Setup parameters for call to function SSP_UpdateNwkKey
   \   000048   8E82         MOV     DPL,R6
   \   00004A   8F83         MOV     DPH,R7
   \   00004C   A3           INC     DPTR
   \   00004D   A3           INC     DPTR
   \   00004E   A3           INC     DPTR
   \   00004F   A3           INC     DPTR
   \   000050   A3           INC     DPTR
   \   000051   E0           MOVX    A,@DPTR
   \   000052   F9           MOV     R1,A
   \   000053   EE           MOV     A,R6
   \   000054   2406         ADD     A,#0x6
   \   000056   FA           MOV     R2,A
   \   000057   EF           MOV     A,R7
   \   000058   3400         ADDC    A,#0x0
   \   00005A   FB           MOV     R3,A
   \   00005B   12....       LCALL   ??SSP_UpdateNwkKey?relay
   2577                if ( !_NIB.nwkKeyLoaded )
   \   00005E   90....       MOV     DPTR,#(_NIB + 61)
   \   000061   E0           MOVX    A,@DPTR
   \   000062   700E         JNZ     ??ZDSecMgrTransportKeyInd_5
   2578                {
   2579                  SSP_SwitchNwkKey( ind->keySeqNum );
   \   000064                ; Setup parameters for call to function SSP_SwitchNwkKey
   \   000064   8E82         MOV     DPL,R6
   \   000066   8F83         MOV     DPH,R7
   \   000068   A3           INC     DPTR
   \   000069   A3           INC     DPTR
   \   00006A   A3           INC     DPTR
   \   00006B   A3           INC     DPTR
   \   00006C   A3           INC     DPTR
   \   00006D   E0           MOVX    A,@DPTR
   \   00006E   F9           MOV     R1,A
   \                     ??ZDSecMgrTransportKeyInd_4:
   \   00006F   12....       LCALL   ??SSP_SwitchNwkKey?relay
   2580                }
   2581              }
   2582          
   2583              // inform ZDO that NWK key was received
   2584              osal_set_event ( ZDAppTaskID, ZDO_DEVICE_AUTH );
   \                     ??ZDSecMgrTransportKeyInd_5:
   \   000072                ; Setup parameters for call to function osal_set_event
   \   000072   7A80         MOV     R2,#-0x80
   \   000074   7B00         MOV     R3,#0x0
   \   000076   90....       MOV     DPTR,#ZDAppTaskID
   \   000079   E0           MOVX    A,@DPTR
   \   00007A   F9           MOV     R1,A
   \   00007B   12....       LCALL   ??osal_set_event?relay
   2585            }
   2586            else if ( ind->keyType == KEY_TYPE_APP_MASTER )
   2587            {
   2588              #if defined ( ZDSECMGR_COMMERCIAL )
   2589              #endif
   2590            }
   2591            else // (ind->keyType==KEY_TYPE_APP_LINK)
   2592            {
   2593              #if defined ( ZDSECMGR_COMMERCIAL )
   2594                ZDSecMgrLinkKeySet( ind->srcExtAddr, ind->key );
   2595              #endif
   2596            }
   2597          }
   \                     ??ZDSecMgrTransportKeyInd_0:
   \   00007E   02....       LJMP    ??Subroutine8_0 & 0xFFFF
   2598          #endif // !defined ( ZDO_COORDINATOR ) || defined ( SOFT_START )
   2599          #endif // defined ( ZDSECMGR_SECURE )
   2600          
   2601          #if defined ( ZDSECMGR_SECURE )
   2602          #if defined ( ZDO_COORDINATOR )
   2603          /******************************************************************************
   2604           * @fn          ZDSecMgrUpdateDeviceInd
   2605           *
   2606           * @brief       Process the ZDO_UpdateDeviceInd_t message.
   2607           *
   2608           * @param       ind - [in] ZDO_UpdateDeviceInd_t indication
   2609           *
   2610           * @return      none
   2611           */
   2612          void ZDSecMgrUpdateDeviceInd( ZDO_UpdateDeviceInd_t* ind )
   2613          {
   2614            ZDSecMgrDevice_t device;
   2615          
   2616          
   2617            device.nwkAddr    = ind->devAddr;
   2618            device.extAddr    = ind->devExtAddr;
   2619            device.parentAddr = ind->srcAddr;
   2620          
   2621            if ( ( ind->status == APSME_UD_SECURED_JOIN   ) ||
   2622                 ( ind->status == APSME_UD_UNSECURED_JOIN )   )
   2623            {
   2624              if ( ind->status == APSME_UD_SECURED_JOIN )
   2625              {
   2626                device.secure = TRUE;
   2627              }
   2628              else
   2629              {
   2630                device.secure = FALSE;
   2631              }
   2632          
   2633              // try to join this device
   2634              ZDSecMgrDeviceJoin( &device );
   2635            }
   2636          }
   2637          #endif // defined ( ZDO_COORDINATOR )
   2638          #endif // defined ( ZDSECMGR_SECURE )
   2639          
   2640          #if defined ( ZDSECMGR_SECURE )
   2641          #if defined ( RTR_NWK )
   2642          #if !defined ( ZDO_COORDINATOR ) || defined( SOFT_START )
   2643          /******************************************************************************
   2644           * @fn          ZDSecMgrRemoveDeviceInd
   2645           *
   2646           * @brief       Process the ZDO_RemoveDeviceInd_t message.
   2647           *
   2648           * @param       ind - [in] ZDO_RemoveDeviceInd_t indication
   2649           *
   2650           * @return      none
   2651           */

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   2652          void ZDSecMgrRemoveDeviceInd( ZDO_RemoveDeviceInd_t* ind )
   \                     ZDSecMgrRemoveDeviceInd:
   2653          {
   \   000000   74F7         MOV     A,#-0x9
   \   000002   12....       LCALL   ?BANKED_ENTER_XDATA
   \   000005                ; Saved register size: 9
   \   000005                ; Auto size: 9
   \   000005   74F7         MOV     A,#-0x9
   \   000007   12....       LCALL   ?ALLOC_XSTACK8
   \   00000A   EA           MOV     A,R2
   \   00000B   FE           MOV     R6,A
   \   00000C   EB           MOV     A,R3
   \   00000D   FF           MOV     R7,A
   2654            ZDSecMgrDevice_t device;
   2655          
   2656          
   2657            // only accept from Trust Center
   2658            if ( ind->srcAddr == APSME_TRUSTCENTER_NWKADDR )
   \   00000E   8E82         MOV     DPL,R6
   \   000010   8F83         MOV     DPH,R7
   \   000012   A3           INC     DPTR
   \   000013   A3           INC     DPTR
   \   000014   E0           MOVX    A,@DPTR
   \   000015   7002         JNZ     ??ZDSecMgrRemoveDeviceInd_0
   \   000017   A3           INC     DPTR
   \   000018   E0           MOVX    A,@DPTR
   \                     ??ZDSecMgrRemoveDeviceInd_0:
   \   000019   703E         JNZ     ??ZDSecMgrRemoveDeviceInd_1
   2659            {
   2660              // look up NWK address
   2661              if ( APSME_LookupNwkAddr( ind->childExtAddr, &device.nwkAddr ) == TRUE )
   \   00001B                ; Setup parameters for call to function APSME_LookupNwkAddr
   \   00001B   85..82       MOV     DPL,?XSP + 0
   \   00001E   85..83       MOV     DPH,?XSP + 1
   \   000021   AC82         MOV     R4,DPL
   \   000023   AD83         MOV     R5,DPH
   \   000025   EE           MOV     A,R6
   \   000026   2404         ADD     A,#0x4
   \   000028   FA           MOV     R2,A
   \   000029   EF           MOV     A,R7
   \   00002A   3400         ADDC    A,#0x0
   \   00002C   FB           MOV     R3,A
   \   00002D   12....       LCALL   ??APSME_LookupNwkAddr?relay
   \   000030   E9           MOV     A,R1
   \   000031   6401         XRL     A,#0x1
   \   000033   7024         JNZ     ??ZDSecMgrRemoveDeviceInd_1
   2662              {
   2663                device.parentAddr = NLME_GetShortAddr();
   \   000035                ; Setup parameters for call to function NLME_GetShortAddr
   \   000035   12....       LCALL   ??NLME_GetShortAddr?relay
   \   000038   7404         MOV     A,#0x4
   \   00003A   12....       LCALL   ?XSTACK_DISP0_8
   \   00003D   EA           MOV     A,R2
   \   00003E   F0           MOVX    @DPTR,A
   \   00003F   A3           INC     DPTR
   \   000040   EB           MOV     A,R3
   \   000041   F0           MOVX    @DPTR,A
   2664                device.extAddr    = ind->childExtAddr;
   \   000042   EE           MOV     A,R6
   \   000043   2404         ADD     A,#0x4
   \   000045   F8           MOV     R0,A
   \   000046   EF           MOV     A,R7
   \   000047   3400         ADDC    A,#0x0
   \   000049   F9           MOV     R1,A
   \   00004A   7402         MOV     A,#0x2
   \   00004C   12....       LCALL   ?XSTACK_DISP0_8
   \   00004F   E8           MOV     A,R0
   \   000050   F0           MOVX    @DPTR,A
   \   000051   A3           INC     DPTR
   \   000052   E9           MOV     A,R1
   \   000053   12....       LCALL   ?Subroutine1 & 0xFFFF
   2665          
   2666                // remove device
   2667                ZDSecMgrDeviceRemove( &device );
   \                     ??CrossCallReturnLabel_6:
   \   000056   12....       LCALL   ??ZDSecMgrDeviceRemove?relay
   2668              }
   2669            }
   2670          }
   \                     ??ZDSecMgrRemoveDeviceInd_1:
   \   000059   7409         MOV     A,#0x9
   \   00005B   12....       LCALL   ?DEALLOC_XSTACK8
   \   00005E                REQUIRE ?Subroutine11
   \   00005E                ; // Fall through to label ?Subroutine11

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   \                     ?Subroutine11:
   \   000000   7F01         MOV     R7,#0x1
   \   000002   02....       LJMP    ?BANKED_LEAVE_XDATA
   2671          #endif // !defined ( ZDO_COORDINATOR ) || defined ( SOFT_START )
   2672          #endif // defined( RTR_NWK )
   2673          #endif // defined ( ZDSECMGR_SECURE )
   2674          
   2675          #if defined ( ZDSECMGR_COMMERCIAL )
   2676          #if defined ( ZDO_COORDINATOR )
   2677          /******************************************************************************
   2678           * @fn          ZDSecMgrRequestKeyInd
   2679           *
   2680           * @brief       Process the ZDO_RequestKeyInd_t message.
   2681           *
   2682           * @param       ind - [in] ZDO_RequestKeyInd_t indication
   2683           *
   2684           * @return      none
   2685           */
   2686          void ZDSecMgrRequestKeyInd( ZDO_RequestKeyInd_t* ind )
   2687          {
   2688            if ( ind->keyType == KEY_TYPE_NWK )
   2689            {
   2690            }
   2691            else if ( ind->keyType == KEY_TYPE_APP_MASTER )
   2692            {
   2693              ZDSecMgrAppKeyReq( ind );
   2694            }
   2695            //else ignore
   2696          }
   2697          #endif // defined ( ZDO_COORDINATOR )
   2698          #endif // defined ( ZDSECMGR_COMMERCIAL )
   2699          
   2700          #if defined ( ZDSECMGR_SECURE )
   2701          #if !defined ( ZDO_COORDINATOR ) || defined( SOFT_START )
   2702          /******************************************************************************
   2703           * @fn          ZDSecMgrSwitchKeyInd
   2704           *
   2705           * @brief       Process the ZDO_SwitchKeyInd_t message.
   2706           *
   2707           * @param       ind - [in] ZDO_SwitchKeyInd_t indication
   2708           *
   2709           * @return      none
   2710           */

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   2711          void ZDSecMgrSwitchKeyInd( ZDO_SwitchKeyInd_t* ind )
   \                     ZDSecMgrSwitchKeyInd:
   2712          {
   \   000000   C082         PUSH    DPL
   \   000002   C083         PUSH    DPH
   \   000004                ; Saved register size: 2
   \   000004                ; Auto size: 0
   2713            SSP_SwitchNwkKey( ind->keySeqNum );
   \   000004                ; Setup parameters for call to function SSP_SwitchNwkKey
   \   000004   8A82         MOV     DPL,R2
   \   000006   8B83         MOV     DPH,R3
   \   000008   A3           INC     DPTR
   \   000009   A3           INC     DPTR
   \   00000A   A3           INC     DPTR
   \   00000B   A3           INC     DPTR
   \   00000C   E0           MOVX    A,@DPTR
   \   00000D   F9           MOV     R1,A
   \   00000E   12....       LCALL   ??SSP_SwitchNwkKey?relay
   2714          
   2715            // Save if nv
   2716            ZDApp_NVUpdate();
   \   000011                ; Setup parameters for call to function ZDApp_NVUpdate
   \   000011   12....       LCALL   ??ZDApp_NVUpdate?relay
   2717          }
   \   000014   02....       LJMP    ??Subroutine9_0 & 0xFFFF
   2718          #endif // !defined ( ZDO_COORDINATOR ) || defined ( SOFT_START )
   2719          #endif // defined ( ZDSECMGR_SECURE )
   2720          
   2721          #if defined ( ZDSECMGR_SECURE )
   2722          #if defined ( ZDO_COORDINATOR )
   2723          /******************************************************************************
   2724           * @fn          ZDSecMgrUpdateNwkKey
   2725           *
   2726           * @brief       Load a new NWK key and trigger a network wide update.
   2727           *
   2728           * @param       key       - [in] new NWK key
   2729           * @param       keySeqNum - [in] new NWK key sequence number
   2730           * @param       destAddr  - [in] destination address of the key transport command
   2731           *
   2732           * @return      ZStatus_t
   2733           */
   2734          ZStatus_t ZDSecMgrUpdateNwkKey( uint8* key, uint8 keySeqNum, uint16 dstAddr )
   2735          {
   2736            ZStatus_t               status;
   2737            APSME_TransportKeyReq_t req;
   2738          
   2739          
   2740            req.keyType   = KEY_TYPE_NWK;
   2741            req.keySeqNum = keySeqNum;
   2742            req.key       = key;
   2743            req.dstAddr   = dstAddr;
   2744            req.extAddr   = NULL;
   2745            req.secure    = TRUE;
   2746          
   2747            status = APSME_TransportKeyReq( &req );
   2748          
   2749            SSP_UpdateNwkKey( key, keySeqNum );
   2750          
   2751            // Save if nv
   2752            ZDApp_NVUpdate();
   2753          
   2754            return status;
   2755          }
   2756          #endif // defined ( ZDO_COORDINATOR )
   2757          #endif // defined ( ZDSECMGR_SECURE )
   2758          
   2759          #if defined ( ZDSECMGR_SECURE )
   2760          #if defined ( ZDO_COORDINATOR )
   2761          /******************************************************************************
   2762           * @fn          ZDSecMgrSwitchNwkKey
   2763           *
   2764           * @brief       Causes the NWK key to switch via a network wide command.
   2765           *
   2766           * @param       keySeqNum - [in] new NWK key sequence number
   2767           *
   2768           * @return      ZStatus_t
   2769           */
   2770          ZStatus_t ZDSecMgrSwitchNwkKey( uint8 keySeqNum, uint16 dstAddr )
   2771          {
   2772            ZStatus_t            status;
   2773            APSME_SwitchKeyReq_t req;
   2774          
   2775          
   2776            req.dstAddr   = dstAddr;
   2777            req.keySeqNum = keySeqNum;
   2778          
   2779            status = APSME_SwitchKeyReq( &req );
   2780          
   2781            SSP_SwitchNwkKey( keySeqNum );
   2782          
   2783            // Save if nv
   2784            ZDApp_NVUpdate();
   2785          
   2786            return status;
   2787          }
   2788          #endif // defined ( ZDO_COORDINATOR )
   2789          #endif // defined ( ZDSECMGR_SECURE )
   2790          
   2791          /******************************************************************************
   2792           * ZigBee Device Security Manager - Stub Implementations
   2793           */
   2794          /******************************************************************************
   2795           * @fn          ZDSecMgrMasterKeyGet (stubs APSME_MasterKeyGet)
   2796           *
   2797           * @brief       Get MASTER key for specified EXT address.
   2798           *
   2799           * @param       extAddr - [in] EXT address
   2800           * @param       key     - [out] MASTER key
   2801           *
   2802           * @return      ZStatus_t
   2803           */

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   2804          ZStatus_t ZDSecMgrMasterKeyGet( uint8* extAddr, uint8** key )
   \                     APSME_MasterKeyGet:
   2805          {
   \   000000                ; Saved register size: 0
   \   000000                ; Auto size: 0
   2806            //---------------------------------------------------------------------------
   2807            #if defined ( ZDSECMGR_COMMERCIAL )
   2808            //---------------------------------------------------------------------------
   2809            {
   2810              ZStatus_t        status;
   2811              ZDSecMgrEntry_t* entry;
   2812          
   2813          
   2814              // lookup entry for specified EXT address
   2815              status = ZDSecMgrEntryLookupExt( extAddr, &entry );
   2816          
   2817              if ( status == ZSuccess )
   2818              {
   2819                ZDSecMgrMasterKeyLookup( entry->ami, key );
   2820              }
   2821              else
   2822              {
   2823                *key = NULL;
   2824              }
   2825          
   2826              return status;
   2827            }
   2828            //---------------------------------------------------------------------------
   2829            #else // !defined ( ZDSECMGR_COMMERCIAL )
   2830            //---------------------------------------------------------------------------
   2831            {
   2832              return ZNwkUnknownDevice;
   \   000000                REQUIRE ?Subroutine10
   \   000000                ; // Fall through to label ?Subroutine10

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   \                     ?Subroutine10:
   \   000000   79C8         MOV     R1,#-0x38
   \   000002   02....       LJMP    ?BRET
   2833            }
   2834            //---------------------------------------------------------------------------
   2835            #endif
   2836            //---------------------------------------------------------------------------
   2837          }
   2838          
   2839          /******************************************************************************
   2840           * @fn          ZDSecMgrLinkKeySet (stubs APSME_LinkKeyExtSet)
   2841           *
   2842           * @brief       Set <APSME_LinkKeyData_t> for specified NWK address.
   2843           *
   2844           * @param       extAddr - [in] EXT address
   2845           * @param       data    - [in] APSME_LinkKeyData_t
   2846           *
   2847           * @return      ZStatus_t
   2848           */

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   2849          ZStatus_t ZDSecMgrLinkKeySet( uint8* extAddr, uint8* key )
   \                     APSME_LinkKeySet:
   2850          {
   \   000000                ; Saved register size: 0
   \   000000                ; Auto size: 0
   2851            //---------------------------------------------------------------------------
   2852            #if defined ( ZDSECMGR_COMMERCIAL )
   2853            //---------------------------------------------------------------------------
   2854            {
   2855              ZStatus_t        status;
   2856              ZDSecMgrEntry_t* entry;
   2857          
   2858          
   2859              // lookup entry index for specified EXT address
   2860              status = ZDSecMgrEntryLookupExt( extAddr, &entry );
   2861          
   2862              if ( status == ZSuccess )
   2863              {
   2864                // setup the link key data reference
   2865                osal_memcpy( entry->lkd.key, key, SEC_KEY_LEN );
   2866          
   2867                entry->lkd.apsmelkd.rxFrmCntr = 0;
   2868                entry->lkd.apsmelkd.txFrmCntr = 0;
   2869              }
   2870          
   2871              return status;
   2872            }
   2873            //---------------------------------------------------------------------------
   2874            #else // !defined ( ZDSECMGR_COMMERCIAL )
   2875            //---------------------------------------------------------------------------
   2876            {
   2877              return ZNwkUnknownDevice;
   \   000000   80..         SJMP    ?Subroutine10
   2878            }
   2879            //---------------------------------------------------------------------------
   2880            #endif
   2881            //---------------------------------------------------------------------------
   2882          }
   2883          
   2884          /******************************************************************************
   2885           * @fn          ZDSecMgrLinkKeyDataGet (stubs APSME_LinkKeyDataGet)
   2886           *
   2887           * @brief       Get <APSME_LinkKeyData_t> for specified NWK address.
   2888           *
   2889           * @param       nwkAddr - [in] NWK address
   2890           * @param       data    - [out] APSME_LinkKeyData_t
   2891           *
   2892           * @return      ZStatus_t
   2893           */

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   2894          ZStatus_t ZDSecMgrLinkKeyDataGet(uint16 nwkAddr, APSME_LinkKeyData_t** data)
   \                     APSME_LinkKeyDataGet:
   2895          {
   \   000000                ; Saved register size: 0
   \   000000                ; Auto size: 0
   2896            //---------------------------------------------------------------------------
   2897            #if defined ( ZDSECMGR_COMMERCIAL )
   2898            //---------------------------------------------------------------------------
   2899            {
   2900              ZStatus_t        status;
   2901              ZDSecMgrEntry_t* entry;
   2902          
   2903          
   2904              // lookup entry index for specified NWK address
   2905              status = ZDSecMgrEntryLookup( nwkAddr, &entry );
   2906          
   2907              if ( status == ZSuccess )
   2908              {
   2909                // setup the link key data reference
   2910                (*data) = &entry->lkd.apsmelkd;
   2911                (*data)->key = entry->lkd.key;
   2912              }
   2913              else
   2914              {
   2915                *data = NULL;
   2916              }
   2917          
   2918              return status;
   2919            }
   2920            //---------------------------------------------------------------------------
   2921            #else // !defined ( ZDSECMGR_COMMERCIAL )
   2922            //---------------------------------------------------------------------------
   2923            {
   2924              return ZNwkUnknownDevice;
   \   000000   80..         SJMP    ?Subroutine10
   2925            }
   2926            //---------------------------------------------------------------------------
   2927            #endif
   2928            //---------------------------------------------------------------------------
   2929          }
   2930          
   2931          /******************************************************************************
   2932           * @fn          ZDSecMgrKeyFwdToChild (stubs APSME_KeyFwdToChild)
   2933           *
   2934           * @brief       Verify and process key transportation to child.
   2935           *
   2936           * @param       ind - [in] APSME_TransportKeyInd_t
   2937           *
   2938           * @return      uint8 - success(TRUE:FALSE)
   2939           */

   \                                 In  segment BANKED_CODE, align 1, keep-with-next
   2940          uint8 ZDSecMgrKeyFwdToChild( APSME_TransportKeyInd_t* ind )
   \                     APSME_KeyFwdToChild:
   2941          {
   \   000000   74F7         MOV     A,#-0x9
   \   000002   12....       LCALL   ?BANKED_ENTER_XDATA
   \   000005                ; Saved register size: 9
   \   000005                ; Auto size: 0
   2942            uint8 success;
   2943          
   2944            success = FALSE;
   \   000005   7E00         MOV     R6,#0x0
   2945          
   2946            //---------------------------------------------------------------------------
   2947            #if defined ( ZDSECMGR_SECURE ) && defined ( RTR_NWK )
   2948            //---------------------------------------------------------------------------
   2949            // verify from Trust Center
   2950            if ( ind->srcAddr == APSME_TRUSTCENTER_NWKADDR )
   \   000007   8A82         MOV     DPL,R2
   \   000009   8B83         MOV     DPH,R3
   \   00000B   E0           MOVX    A,@DPTR
   \   00000C   7002         JNZ     ??APSME_KeyFwdToChild_0
   \   00000E   A3           INC     DPTR
   \   00000F   E0           MOVX    A,@DPTR
   \                     ??APSME_KeyFwdToChild_0:
   \   000010   701C         JNZ     ??APSME_KeyFwdToChild_1
   2951            {
   2952              success = TRUE;
   \   000012   0E           INC     R6
   2953          
   2954              // check for initial NWK key
   2955              if ( ind->keyType == KEY_TYPE_NWK )
   \   000013   8A82         MOV     DPL,R2
   \   000015   8B83         MOV     DPH,R3
   \   000017   A3           INC     DPTR
   \   000018   A3           INC     DPTR
   \   000019   E0           MOVX    A,@DPTR
   \   00001A   6401         XRL     A,#0x1
   \   00001C   7010         JNZ     ??APSME_KeyFwdToChild_1
   2956              {
   2957                // set association status to authenticated
   2958                ZDSecMgrAssocDeviceAuth( AssocGetWithExt( ind->dstExtAddr ) );
   \   00001E                ; Setup parameters for call to function ZDSecMgrAssocDeviceAuth
   \   00001E                ; Setup parameters for call to function AssocGetWithExt
   \   00001E   8A82         MOV     DPL,R2
   \   000020   8B83         MOV     DPH,R3
   \   000022   A3           INC     DPTR
   \   000023   A3           INC     DPTR
   \   000024   A3           INC     DPTR
   \   000025   A3           INC     DPTR
   \   000026   A3           INC     DPTR
   \   000027   A3           INC     DPTR
   \   000028   12....       LCALL   ?Subroutine4 & 0xFFFF
   \                     ??CrossCallReturnLabel_12:
   \   00002B   12....       LCALL   ??ZDSecMgrAssocDeviceAuth?relay
   2959              }
   2960            }
   2961            //---------------------------------------------------------------------------
   2962            #endif // defined ( ZDSECMGR_SECURE ) && defined ( RTR_NWK )
   2963            //---------------------------------------------------------------------------
   2964          
   2965            return success;
   \                     ??APSME_KeyFwdToChild_1:
   \   00002E   EE           MOV     A,R6
   \   00002F   F9           MOV     R1,A
   \   000030   80..         SJMP    ?Subroutine11
   2966          }

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??ZDSecMgrSendNwkKey?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    ZDSecMgrSendNwkKey

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??ZDSecMgrDeviceRemove?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    ZDSecMgrDeviceRemove

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??ZDSecMgrDeviceJoinFwd?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    ZDSecMgrDeviceJoinFwd

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??ZDSecMgrDeviceNew?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    ZDSecMgrDeviceNew

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??ZDSecMgrAssocDeviceAuth?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    ZDSecMgrAssocDeviceAuth

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??ZDSecMgrInit?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    ZDSecMgrInit

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??ZDSecMgrConfig?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    ZDSecMgrConfig

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??ZDSecMgrNewDeviceEvent?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    ZDSecMgrNewDeviceEvent

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??ZDSecMgrTransportKeyInd?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    ZDSecMgrTransportKeyInd

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??ZDSecMgrRemoveDeviceInd?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    ZDSecMgrRemoveDeviceInd

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??ZDSecMgrSwitchKeyInd?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    ZDSecMgrSwitchKeyInd

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??APSME_MasterKeyGet?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    APSME_MasterKeyGet

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??APSME_LinkKeySet?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    APSME_LinkKeySet

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??APSME_LinkKeyDataGet?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    APSME_LinkKeyDataGet

   \                                 In  segment BANK_RELAYS, align 1
   \                     ??APSME_KeyFwdToChild?relay:
   \   000000   12....       LCALL   ?BDISPATCH
   \   000003   ......       DC24    APSME_KeyFwdToChild
   2967          
   2968          /******************************************************************************
   2969          ******************************************************************************/
   2970          

   Maximum stack usage in bytes:

     Function                     ISTACK PSTACK XSTACK
     --------                     ------ ------ ------
     APSME_KeyFwdToChild              0      0      9
       -> AssocGetWithExt             0      0     18
       -> ZDSecMgrAssocDeviceAuth     0      0     18
     APSME_LinkKeyDataGet             0      0      0
     APSME_LinkKeySet                 0      0      0
     APSME_MasterKeyGet               0      0      0
     ZDSecMgrAssocDeviceAuth          2      0     34
     ZDSecMgrConfig                   2      0      0
       -> SSP_Init                    4      0      0
       -> APSME_SecurityRM_RD         4      0      0
     ZDSecMgrDeviceJoinFwd            3      0      7
       -> APSME_UpdateDeviceReq       4      0     14
     ZDSecMgrDeviceNew                2      0     34
       -> ZDSecMgrDeviceJoinFwd       4      0      0
     ZDSecMgrDeviceRemove             1      0     37
       -> NLME_GetShortAddr           0      0     38
       -> AssocGetWithExt             0      0     38
       -> NLME_LeaveReq               0      0     38
       -> APSME_RemoveDeviceReq       0      0     38
     ZDSecMgrInit                     2      0      0
       -> SSP_Init                    4      0      0
       -> APSME_SecurityRM_RD         4      0      0
     ZDSecMgrNewDeviceEvent           1      0     34
       -> AssocMatchDeviceStatus      0      0     68
       -> ZDSecMgrAssocDeviceAuth     0      0     68
       -> AddrMgrEntryGet             0      0     68
       -> NLME_GetShortAddr           0      0     68
       -> ZDSecMgrDeviceNew           0      0     68
       -> AssocRemove                 0      0     68
     ZDSecMgrRemoveDeviceInd          0      0     18
       -> APSME_LookupNwkAddr         0      0     36
       -> NLME_GetShortAddr           0      0     36
       -> ZDSecMgrDeviceRemove        0      0     36
     ZDSecMgrSendNwkKey               1      0     20
       -> NLME_GetShortAddr           0      0     40
       -> APSME_TransportKeyReq       0      0     40
     ZDSecMgrSwitchKeyInd             2      0      0
       -> SSP_SwitchNwkKey            4      0      0
       -> ZDApp_NVUpdate              4      0      0
     ZDSecMgrTransportKeyInd          0      0     10
       -> SSP_UpdateNwkKey            0      0     20
       -> SSP_SwitchNwkKey            0      0     20
       -> SSP_UpdateNwkKey            0      0     20
       -> SSP_SwitchNwkKey            0      0     20
       -> osal_set_event              0      0     20


   Segment part sizes:

     Function/Label                 Bytes
     --------------                 -----
     ZDSecMgrSendNwkKey              156
     ?Subroutine8                      8
     ?Subroutine6                     11
     ?Subroutine5                     22
     ?Subroutine7                      8
     ?Subroutine0                     19
     ZDSecMgrDeviceRemove            179
     ?Subroutine2                      9
     ?Subroutine1                     12
     ?Subroutine4                      9
     ZDSecMgrDeviceJoinFwd            82
     ?Subroutine3                     12
     ?Subroutine9                     17
     ZDSecMgrDeviceNew                 9
     ZDSecMgrAssocDeviceAuth          25
     ZDSecMgrInit                      2
     ZDSecMgrConfig                    2
     ZDSecMgrNewDeviceEvent          175
     ZDSecMgrTransportKeyInd         129
     ZDSecMgrRemoveDeviceInd          94
     ?Subroutine11                     5
     ZDSecMgrSwitchKeyInd             23
     APSME_MasterKeyGet                0
     ?Subroutine10                     5
     APSME_LinkKeySet                  2
     APSME_LinkKeyDataGet              2
     APSME_KeyFwdToChild              50
     ??ZDSecMgrSendNwkKey?relay        6
     ??ZDSecMgrDeviceRemove?relay      6
     ??ZDSecMgrDeviceJoinFwd?relay     6
     ??ZDSecMgrDeviceNew?relay         6
     ??ZDSecMgrAssocDeviceAuth?relay
                                       6
     ??ZDSecMgrInit?relay              6
     ??ZDSecMgrConfig?relay            6
     ??ZDSecMgrNewDeviceEvent?relay    6
     ??ZDSecMgrTransportKeyInd?relay
                                       6
     ??ZDSecMgrRemoveDeviceInd?relay
                                       6
     ??ZDSecMgrSwitchKeyInd?relay      6
     ??APSME_MasterKeyGet?relay        6
     ??APSME_LinkKeySet?relay          6
     ??APSME_LinkKeyDataGet?relay      6
     ??APSME_KeyFwdToChild?relay       6

 
 1 067 bytes in segment BANKED_CODE
    90 bytes in segment BANK_RELAYS
 
 1 157 bytes of CODE memory

Errors: none
Warnings: none
