void ID_Init(void) { uint16 Init_ID=0x1234; //默认PANID,自己可以任意修改 uint16 preID; //这个是指向ZCD_NV_PANID的值 uint16 ID; //这个想ZCD_NV_PANID1的值 osal_nv_read(ZCD_NV_ID,0,2,&preID); osal_nv_read(ZCD_NV_ID1,0,2,&ID); //如果用串口调试助手修改了,则同时修改ZCD_NV_PANID和ZCD_NV_PANID1 //并且这两个值是相同的,所以当修改后则不会进入下面这个条件语句中 //而在修改之前通过下面的语句将默认PANIDID存入NV中,使得设备启动的 //时候有一个固定的PANID if(preID!=ID) { if ( osal_nv_item_init( ZCD_NV_ID, 2, &Init_ID ) == ZSUCCESS ) { osal_nv_write(ZCD_NV_ID,0,2,&Init_ID); osal_nv_read(ZCD_NV_ID,0,2,&Init_ID); zgID=Init_ID; } } }
/********************************************************************* * @fn BindRestoreFromNV * * @brief Restore the binding table from NV * * @param none * * @return Number of entries restored */ uint16 BindRestoreFromNV( void ) { nvBindingHdr_t hdr; hdr.numRecs = 0; #if !defined ( DONT_UPGRADE_BIND ) if ( BindUpgradeTableInNV() == ZSuccess ) #endif { if ( osal_nv_read( ZCD_NV_BINDING_TABLE, 0, sizeof(nvBindingHdr_t), &hdr ) == ZSuccess ) { bindTableIndex_t x; uint16 validRecsCount = 0; // Read in the device list for ( x = 0; ( x < gNWK_MAX_BINDING_ENTRIES ) && ( validRecsCount < hdr.numRecs ); x++ ) { if ( osal_nv_read( ZCD_NV_BINDING_TABLE, (uint16)(sizeof(nvBindingHdr_t) + (x * NV_BIND_REC_SIZE)), NV_BIND_REC_SIZE, &BindingTable[x] ) == ZSUCCESS ) { if ( BindingTable[x].srcEP != NV_BIND_EMPTY ) { validRecsCount++; } } } } } return ( hdr.numRecs ); }
/**************************************************************************** * @fn ZDiagsRestoreStatsFromNV * * @brief Restores the statistics table from NV into the RAM table. * * @param none. * * @return ZSuccess - if NV data was restored from NV. * ZFailure - Otherwise, NV_OPER_FAILED for failure. */ uint8 ZDiagsRestoreStatsFromNV( void ) { uint8 retValue = ZFailure; #if defined ( FEATURE_SYSTEM_STATS ) // restore diagnostics table from NV into RAM table if ( osal_nv_read( ZCD_NV_DIAGNOSTIC_STATS, 0, (uint16)sizeof( DiagStatistics_t ), &DiagsStatsTable ) == SUCCESS ) { // restore MAC values into the PIB ZMacSetReq( ZMacDiagsRxCrcPass, (uint8 *)&(DiagsStatsTable.MacRxCrcPass) ); ZMacSetReq( ZMacDiagsRxCrcFail, (uint8 *)&(DiagsStatsTable.MacRxCrcFail) ); ZMacSetReq( ZMacDiagsRxBcast, (uint8 *)&(DiagsStatsTable.MacRxBcast) ); ZMacSetReq( ZMacDiagsTxBcast, (uint8 *)&(DiagsStatsTable.MacTxBcast) ); ZMacSetReq( ZMacDiagsRxUcast, (uint8 *)&(DiagsStatsTable.MacRxUcast) ); ZMacSetReq( ZMacDiagsTxUcast, (uint8 *)&(DiagsStatsTable.MacTxUcast) ); ZMacSetReq( ZMacDiagsTxUcastRetry, (uint8 *)&(DiagsStatsTable.MacTxUcastRetry) ); ZMacSetReq( ZMacDiagsTxUcastFail, (uint8 *)&(DiagsStatsTable.MacTxUcastFail) ); retValue = ZSuccess; } #endif // FEATURE_SYSTEM_STATS return ( retValue ); }
/********************************************************************* * @fn zclCCServer_ReadWriteCB * * @brief Read/write attribute data. This callback function should * only be called for the Network Security Key attributes. * * Note: This function is only required when the attribute data * format is unknown to ZCL. This function gets called * when the pointer 'dataPtr' to the attribute value is * NULL in the attribute database registered with the ZCL. * * @param clusterId - cluster that attribute belongs to * @param attrId - attribute to be read or written * @param oper - ZCL_OPER_LEN, ZCL_OPER_READ, or ZCL_OPER_WRITE * @param pValue - pointer to attribute value * @param pLen - length of attribute value read * * @return ZStatus_t */ static ZStatus_t zclCCServer_ReadWriteCB( uint16 clusterId, uint16 attrId, uint8 oper, uint8 *pValue, uint16 *pLen ) { ZStatus_t status = ZCL_STATUS_SUCCESS; switch ( oper ) { case ZCL_OPER_LEN: *pLen = SEC_KEY_LEN; break; case ZCL_OPER_READ: osal_nv_read( NvIdFromAttrId( attrId ), 0, SEC_KEY_LEN, pValue ); if ( pLen != NULL ) { *pLen = SEC_KEY_LEN; } break; case ZCL_OPER_WRITE: osal_nv_write( NvIdFromAttrId( attrId ), 0, SEC_KEY_LEN, pValue ); break; default: status = ZCL_STATUS_SOFTWARE_FAILURE; // Should never get here! break; } return ( status ); }
/********************************************************************* * @fn zgWriteStartupOptions * * @brief Writes bits into the ZCD_NV_STARTUP_OPTION NV Item. * * @param action - ZG_STARTUP_SET set bit, ZG_STARTUP_CLEAR to * clear bit. The set bit is an OR operation, and the * clear bit is an AND ~(bitOptions) operation. * * @param bitOptions - which bits to perform action on: * ZCD_STARTOPT_DEFAULT_CONFIG_STATE * ZCD_STARTOPT_DEFAULT_NETWORK_STATE * * @return ZSUCCESS if successful */ uint8 zgWriteStartupOptions( uint8 action, uint8 bitOptions ) { uint8 status; uint8 startupOptions = 0; status = osal_nv_read( ZCD_NV_STARTUP_OPTION, 0, sizeof( startupOptions ), &startupOptions ); if ( status == ZSUCCESS ) { if ( action == ZG_STARTUP_SET ) { // Set bits startupOptions |= bitOptions; } else { // Clear bits startupOptions &= (bitOptions ^ 0xFF); } // Changed? status = osal_nv_write( ZCD_NV_STARTUP_OPTION, 0, sizeof( startupOptions ), &startupOptions ); } return ( status ); }
/*************************************************************************************************** * @fn MT_UtilAPSME_LinkKeyDataGet * * @brief Retrieves APS Link Key data from NV. * * @param pBuf - pointer to the received buffer * * @return void ***************************************************************************************************/ static void MT_UtilAPSME_LinkKeyDataGet(uint8 *pBuf) { uint8 rsp[MT_APSME_LINKKEY_GET_RSP_LEN]; APSME_LinkKeyData_t *pData = NULL; uint8 cmdId = pBuf[MT_RPC_POS_CMD1]; uint16 apsLinkKeyNvId; uint32 *apsRxFrmCntr; uint32 *apsTxFrmCntr; pBuf += MT_RPC_FRAME_HDR_SZ; *rsp = APSME_LinkKeyNVIdGet(pBuf, &apsLinkKeyNvId); if (SUCCESS == *rsp) { pData = (APSME_LinkKeyData_t *)osal_mem_alloc(sizeof(APSME_LinkKeyData_t)); if (pData != NULL) { // retrieve key from NV if ( osal_nv_read( apsLinkKeyNvId, 0, sizeof(APSME_LinkKeyData_t), pData) == SUCCESS) { apsRxFrmCntr = &ApsLinkKeyFrmCntr[apsLinkKeyNvId - ZCD_NV_APS_LINK_KEY_DATA_START].rxFrmCntr; apsTxFrmCntr = &ApsLinkKeyFrmCntr[apsLinkKeyNvId - ZCD_NV_APS_LINK_KEY_DATA_START].txFrmCntr; uint8 *ptr = rsp+1; (void)osal_memcpy(ptr, pData->key, SEC_KEY_LEN); ptr += SEC_KEY_LEN; *ptr++ = BREAK_UINT32(*apsTxFrmCntr, 0); *ptr++ = BREAK_UINT32(*apsTxFrmCntr, 1); *ptr++ = BREAK_UINT32(*apsTxFrmCntr, 2); *ptr++ = BREAK_UINT32(*apsTxFrmCntr, 3); *ptr++ = BREAK_UINT32(*apsRxFrmCntr, 0); *ptr++ = BREAK_UINT32(*apsRxFrmCntr, 1); *ptr++ = BREAK_UINT32(*apsRxFrmCntr, 2); *ptr++ = BREAK_UINT32(*apsRxFrmCntr, 3); } // clear copy of key in RAM osal_memset( pData, 0x00, sizeof(APSME_LinkKeyData_t) ); osal_mem_free(pData); } } else { // set data key and counters 0xFF osal_memset(&rsp[1], 0xFF, SEC_KEY_LEN + (MT_UTIL_FRM_CTR_LEN * 2)); } MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, MT_APSME_LINKKEY_GET_RSP_LEN, rsp); // clear key data osal_memset(rsp, 0x00, MT_APSME_LINKKEY_GET_RSP_LEN); }
/********************************************************************* * @fn zgInit * * @brief * * Initialize the Z-Stack Globals. If an item doesn't exist in * NV memory, write the system default into NV memory. But if * it exists, set the item to the value stored in NV memory. * * NOTE: The Startup Options (ZCD_NV_STARTUP_OPTION) indicate * that the Config state items (zgItemTable) need to be * set to defaults (ZCD_STARTOPT_DEFAULT_CONFIG_STATE). The * * @param none * * @return ZSUCCESS if successful, NV_ITEM_UNINIT if item did not * exist in NV, NV_OPER_FAILED if failure. */ uint8 zgInit( void ) { uint8 setDefault = FALSE; // Do we want to default the Config state values if ( zgReadStartupOptions() & ZCD_STARTOPT_DEFAULT_CONFIG_STATE ) { setDefault = TRUE; } #if defined ( FEATURE_SYSTEM_STATS ) // This sections tracks the number of resets uint16 bootCnt = 0; // Update the Boot Counter if ( osal_nv_item_init( ZCD_NV_BOOTCOUNTER, sizeof(bootCnt), &bootCnt ) == ZSUCCESS ) { // Get the old value from NV memory osal_nv_read( ZCD_NV_BOOTCOUNTER, 0, sizeof(bootCnt), &bootCnt ); } // Increment the Boot Counter and store it into NV memory if ( setDefault ) { bootCnt = 0; } else { bootCnt++; } osal_nv_write( ZCD_NV_BOOTCOUNTER, 0, sizeof(bootCnt), &bootCnt ); #endif // FEATURE_SYSTEM_STATS // Initialize the Extended PAN ID as my own extended address ZMacGetReq( ZMacExtAddr, zgExtendedPANID ); // Initialize the items table zgInitItems( setDefault ); #ifndef NONWK if ( ZG_SECURE_ENABLED ) { // Initialize the Pre-Configured Key to the default key zgPreconfigKeyInit( setDefault ); // Initialize NV items for all Keys: NWK, APS, TCLK and Master ZDSecMgrInitNVKeyTables( setDefault ); } #endif // NONWK // Clear the Config State default if ( setDefault ) { zgWriteStartupOptions( ZG_STARTUP_CLEAR, ZCD_STARTOPT_DEFAULT_CONFIG_STATE ); } return ( ZSUCCESS ); }
/********************************************************************* * @fn zgInit * * @brief * * Initialize the Z-Stack Globals. If an item doesn't exist in * NV memory, write the system default into NV memory. But if * it exists, set the item to the value stored in NV memory. * * NOTE: The Startup Options (ZCD_NV_STARTUP_OPTION) indicate * that the Config state items (zgItemTable) need to be * set to defaults (ZCD_STARTOPT_DEFAULT_CONFIG_STATE). The * * * @param none * * @return ZSUCCESS if successful, NV_ITEM_UNINIT if item did not * exist in NV, NV_OPER_FAILED if failure. */ uint8 zgInit( void ) { uint8 i = 0; uint8 setDefault = FALSE; // Do we want to default the Config state values if ( zgReadStartupOptions() & ZCD_STARTOPT_DEFAULT_CONFIG_STATE ) { setDefault = TRUE; } #if 0 // Enable this section if you need to track the number of resets // This section is normally disabled to minimize "wear" on NV memory uint16 bootCnt = 0; // Update the Boot Counter if ( osal_nv_item_init( ZCD_NV_BOOTCOUNTER, sizeof(bootCnt), &bootCnt ) == ZSUCCESS ) { // Get the old value from NV memory osal_nv_read( ZCD_NV_BOOTCOUNTER, 0, sizeof(bootCnt), &bootCnt ); } // Increment the Boot Counter and store it into NV memory if ( setDefault ) bootCnt = 0; else bootCnt++; osal_nv_write( ZCD_NV_BOOTCOUNTER, 0, sizeof(bootCnt), &bootCnt ); #endif // Initialize the Extended PAN ID as my own extended address ZMacGetReq( ZMacExtAddr, zgExtendedPANID ); #ifndef NONWK // Initialize the Pre-Configured Key to the default key osal_memcpy( zgPreConfigKey, defaultKey, SEC_KEY_LEN ); // Do NOT Change!!! #endif // NONWK while ( zgItemTable[i].id != 0x00 ) { // Initialize the item zgItemInit( zgItemTable[i].id, zgItemTable[i].len, zgItemTable[i].buf, setDefault ); // Move on to the next item i++; } // Clear the Config State default if ( setDefault ) { zgWriteStartupOptions( ZG_STARTUP_CLEAR, ZCD_STARTOPT_DEFAULT_CONFIG_STATE ); } return ( ZSUCCESS ); }
/************************************************************************************************** * @fn znpTestRF * * @brief This function initializes and checks the ZNP RF Test Mode NV items. It is designed * to be invoked before/instead of MAC radio initialization. * * input parameters * * None. * * output parameters * * None. * * @return None. */ void znpTestRF(void) { uint8 rfTestParms[4] = { 0, 0, 0, 0 }; if ((SUCCESS != osal_nv_item_init(ZNP_NV_RF_TEST_PARMS, 4, rfTestParms)) || (SUCCESS != osal_nv_read(ZNP_NV_RF_TEST_PARMS, 0, 4, rfTestParms)) || (rfTestParms[0] == 0)) { return; } // Settings from SmartRF Studio MDMCTRL0 = 0x85; RXCTRL = 0x3F; FSCTRL = 0x5A; FSCAL1 = 0x2B; AGCCTRL1 = 0x11; ADCTEST0 = 0x10; ADCTEST1 = 0x0E; ADCTEST2 = 0x03; FRMCTRL0 = 0x43; FRMCTRL1 = 0x00; MAC_RADIO_RXTX_OFF(); MAC_RADIO_SET_CHANNEL(rfTestParms[1]); MAC_RADIO_SET_TX_POWER(rfTestParms[2]); TX_PWR_TONE_SET(rfTestParms[3]); switch (rfTestParms[0]) { case 1: // Rx promiscuous mode. MAC_RADIO_RX_ON(); break; case 2: // Un-modulated Tx. TX_PWR_MOD__SET(1); // no break; case 3: // Modulated Tx. // Modulated is default register setting, so no special action. // Now turn on Tx power for either mod or un-modulated Tx test. MAC_RADIO_TX_ON(); break; default: // Not expected. break; } // Clear the RF test mode. (void)osal_memset(rfTestParms, 0, 4); (void)osal_nv_write(ZNP_NV_RF_TEST_PARMS, 0, 4, rfTestParms); while (1); // Spin in RF test mode until a hard reset. }
/********************************************************************* * @fn BindRestoreFromNV * * @brief Restore the binding table from NV * * @param none * * @return Number of entries restored */ uint16 BindRestoreFromNV( void ) { nvBindingHdr_t hdr; uint16 numAdded = 0; if ( osal_nv_read( ZCD_NV_BINDING_TABLE, 0, sizeof(nvBindingHdr_t), &hdr ) == ZSuccess ) { if (hdr.numRecs > 0) { // Read the whole table at once if ( osal_nv_read( ZCD_NV_BINDING_TABLE, (uint16)(sizeof(nvBindingHdr_t)), (NV_BIND_REC_SIZE * gNWK_MAX_BINDING_ENTRIES), BindingTable ) == ZSUCCESS ) { numAdded = gNWK_MAX_BINDING_ENTRIES; } } } return ( numAdded ); }
/********************************************************************* * @fn zclCCServer_UseStartupParameters * * @brief Set the network parameters to the current Startup Parameters. * * @param none * * @return none */ static void zclCCServer_UseStartupParameters( void ) { if ( zclCCServer_StartUpControl == CC_STARTUP_CONTROL_OPTION_1 ) { uint8 networkKey[SEC_KEY_LEN]; // Form the Commissioning network and become the Coordinator for that network // Required attributes: Extended PAN ID osal_nv_write( ZCD_NV_EXTENDED_PAN_ID, 0, Z_EXTADDR_LEN, zclCCServer_ExtendedPanId ); osal_nv_write( ZCD_NV_APS_USE_EXT_PANID, 0, Z_EXTADDR_LEN, zclCCServer_ExtendedPanId ); // Optional attributes: PAN ID, Channel Mask, Network Manager Address, // Network Key, Network Key Type (only KEY_TYPE_NWK is currently supported), // and Trust Center Address (which is used with Preconfigured Link Key). osal_nv_write( ZCD_NV_PANID, 0, sizeof( zclCCServer_PanId ), &zclCCServer_PanId ); osal_nv_write( ZCD_NV_CHANLIST, 0, sizeof( zclCCServer_ChannelMask ), &zclCCServer_ChannelMask ); osal_nv_write( ZCD_NV_NWKMGR_ADDR, 0, sizeof( zclCCServer_NwkManagerAddr ), &zclCCServer_NwkManagerAddr ); osal_nv_read( ZCD_NV_SAS_CURR_NWK_KEY, 0, SEC_KEY_LEN, networkKey ); if ( !nullKey( networkKey ) ) { // Save the Network Key as the Pre-Configured Key in NV osal_nv_write( ZCD_NV_PRECFGKEY, 0, SEC_KEY_LEN, networkKey ); // Clear copy of key in RAM osal_memset( networkKey, 0x00, SEC_KEY_LEN ); } } else if ( zclCCServer_StartUpControl == CC_STARTUP_CONTROL_OPTION_3 ) { // Join the Commissioning network // Required attributes: none // Optional attributes: Extended PAN ID, Channel Mask, and // Preconfigured Link Key osal_nv_write( ZCD_NV_EXTENDED_PAN_ID, 0, Z_EXTADDR_LEN, zclCCServer_ExtendedPanId ); osal_nv_write( ZCD_NV_CHANLIST, 0, sizeof( zclCCServer_ChannelMask ), &zclCCServer_ChannelMask ); zclCCServer_SavePreconfigLinkKey(); } }
void deviceManagerInit(void){ ZDO_DeviceAnnce_t * iter, *end; end = table +TABLE_SIZE; for(iter = table; iter != end; iter++){ iter->nwkAddr=INVALID; } osal_nv_item_init(NV_ID, sizeof(ZDO_DeviceAnnce_t)*TABLE_SIZE, table); uint16 size = osal_nv_item_len(NV_ID); if (size > TABLE_SIZE*sizeof(ZDO_DeviceAnnce_t)){ size = TABLE_SIZE*sizeof(ZDO_DeviceAnnce_t); } osal_nv_read(NV_ID, 0, size, table); }
void Setid(void) { uint16 gu16RecBuffLen; if ( osal_nv_item_init( ZCD_NV_ID, 2, &gu16RecBuffLen ) == ZSUCCESS ) { osal_nv_read(ZCD_NV_ID,0,2,&gu16RecBuffLen); } zgID=gu16RecBuffLen; }
/********************************************************************* * @fn zclCCServer_RestoreStartupParametersInNV * * @brief Restore the Startup Parameters from NV * * @param none * * @return none */ static void zclCCServer_RestoreStartupParametersInNV( void ) { uint8 key[SEC_KEY_LEN]; for ( uint8 i = 0; nvItemTable[i].id != 0x00; i++ ) { // Read the item osal_nv_read( nvItemTable[i].id, 0, nvItemTable[i].len, nvItemTable[i].buf ); } // Update the current keys in the NV osal_nv_read( ZCD_NV_SAS_TC_MASTER_KEY, 0, SEC_KEY_LEN, key ); osal_nv_write( ZCD_NV_SAS_CURR_TC_MASTER_KEY, 0, SEC_KEY_LEN, key ); osal_nv_read( ZCD_NV_SAS_NWK_KEY, 0, SEC_KEY_LEN, key ); osal_nv_write( ZCD_NV_SAS_CURR_NWK_KEY, 0, SEC_KEY_LEN, key ); osal_nv_read( ZCD_NV_SAS_PRECFG_LINK_KEY, 0, SEC_KEY_LEN, key ); osal_nv_write( ZCD_NV_SAS_CURR_PRECFG_LINK_KEY, 0, SEC_KEY_LEN, key ); // Clear copy of key in RAM osal_memset( key, 0x00, SEC_KEY_LEN ); }
/****************************************************************************** * @fn zb_ReadConfiguration * * @brief The zb_ReadConfiguration function is used to get a * Configuration Protperty from Nonvolatile memory. * * @param configId - The identifier for the configuration property * len - The size of the pValue buffer in bytes * pValue - A buffer to hold the configuration property * * @return none */ uint8 zb_ReadConfiguration( uint8 configId, uint8 len, void *pValue ) { uint8 size; size = (uint8)osal_nv_item_len( configId ); if ( size > len ) { return ZFailure; } else { return( osal_nv_read(configId, 0, size, pValue) ); } }
/********************************************************************* * @fn zclCCServer_InitStartupParametersInNV * * @brief Initialize the Startup Parameters in NV. * * @param none * * @return none */ static void zclCCServer_InitStartupParametersInNV( void ) { uint8 key[SEC_KEY_LEN]; for ( uint8 i = 0; nvItemTable[i].id != 0x00; i++ ) { // Initialize the item osal_nv_item_init( nvItemTable[i].id, nvItemTable[i].len, nvItemTable[i].buf ); } // Use the default key values in the NV osal_nv_read( ZCD_NV_SAS_CURR_TC_MASTER_KEY, 0, SEC_KEY_LEN, key ); osal_nv_item_init( ZCD_NV_SAS_TC_MASTER_KEY, SEC_KEY_LEN, key ); osal_nv_read( ZCD_NV_SAS_CURR_NWK_KEY, 0, SEC_KEY_LEN, key ); osal_nv_item_init( ZCD_NV_SAS_NWK_KEY, SEC_KEY_LEN, key ); osal_nv_read( ZCD_NV_SAS_CURR_PRECFG_LINK_KEY, 0, SEC_KEY_LEN, key ); osal_nv_item_init( ZCD_NV_SAS_PRECFG_LINK_KEY, SEC_KEY_LEN, key ); // Clear copy of key in RAM osal_memset( key, 0x00, SEC_KEY_LEN ); }
uint8 cb_ReadConfiguration( uint8 configId, uint8 len, void *pValue ) // it's just check the configId if existed,wont create one,unlikely osal_nv_item_init { uint8 size; size = (uint8)osal_nv_item_len( configId ); if ( size > len ) { return ZFailure; } else { return( osal_nv_read(configId, 0, size, pValue) ); } }
/********************************************************************* * @fn zgReadStartupOptions * * @brief Reads the ZCD_NV_STARTUP_OPTION NV Item. * * @param none * * @return the ZCD_NV_STARTUP_OPTION NV item */ uint8 zgReadStartupOptions( void ) { // Default to Use Config State and Use Network State uint8 startupOption = 0; // This should have been done in ZMain.c, but just in case. if ( osal_nv_item_init( ZCD_NV_STARTUP_OPTION, sizeof(startupOption), &startupOption ) == ZSUCCESS ) { // Read saved startup control osal_nv_read( ZCD_NV_STARTUP_OPTION, 0, sizeof( startupOption ), &startupOption); } return ( startupOption ); }
/********************************************************************* * @fn zclCCServer_SavePreconfigLinkKey * * @brief Save the Pre-Configured Link Key. * * @param void * * @return ZStatus_t */ static void zclCCServer_SavePreconfigLinkKey( void ) { APSME_TCLinkKey_t *pKeyData; pKeyData = (APSME_TCLinkKey_t *)osal_mem_alloc( sizeof( APSME_TCLinkKey_t ) ); if (pKeyData != NULL) { // Making sure data is cleared for every key all the time osal_memset( pKeyData, 0x00, sizeof( APSME_TCLinkKey_t ) ); osal_memset( pKeyData->extAddr, 0xFF, Z_EXTADDR_LEN ); osal_nv_read( ZCD_NV_SAS_CURR_PRECFG_LINK_KEY, 0, SEC_KEY_LEN, pKeyData->key ); // Save the Pre-Configured Link Key as the default TC Link Key the in NV osal_nv_write( ZCD_NV_TCLK_TABLE_START, 0, sizeof( APSME_TCLinkKey_t ), pKeyData ); // Clear copy of key in RAM osal_memset( pKeyData, 0x00, sizeof( APSME_TCLinkKey_t ) ); osal_mem_free( pKeyData ); } }
/********************************************************************* * @fn zgItemInit() * * @brief * * Initialize a global item. If the item doesn't exist in NV memory, * write the system default (value passed in) into NV memory. But if * it exists, set the item to the value stored in NV memory. * * Also, if setDefault is TRUE and the item exists, we will write * the default value to NV space. * * @param id - item id * @param len - item len * @param buf - pointer to the item * @param setDefault - TRUE to set default, not read * * @return ZSUCCESS if successful, NV_ITEM_UNINIT if item did not * exist in NV, NV_OPER_FAILED if failure. */ static uint8 zgItemInit( uint16 id, uint16 len, void *buf, uint8 setDefault ) { uint8 status; // If the item doesn't exist in NV memory, create and initialize // it with the value passed in. status = osal_nv_item_init( id, len, buf ); if ( status == ZSUCCESS ) { if ( setDefault ) { // Write the default value back to NV status = osal_nv_write( id, 0, len, buf ); } else { // The item exists in NV memory, read it from NV memory status = osal_nv_read( id, 0, len, buf ); } } return (status); }
/********************************************************************* * @fn BindUpgradeTableInNV * * @brief Verifies if the existing table in NV has different size * than the table defined by parameters in the current code. * If different, creates a backup table, deletes the existing * table and creates the new table with the new size. After * this process is done ZCD_NV_BINDING_TABLE NV item contains * only valid records retrieved from the original table, up to * the maximum number of records defined by gNWK_MAX_BINDING_ENTRIES * * @param none * * @return ZSuccess - the Update process was sucessful. * ZFailure - otherwise. */ static uint8 BindUpgradeTableInNV( void ) { uint8 status = ZSuccess; nvBindingHdr_t hdr; uint16 dupLen; uint16 bindLen; uint16 newLen; bool duplicateReady = FALSE; // Size of the Binding table based on current paramenters in the code newLen = sizeof(nvBindingHdr_t) + NV_BIND_ITEM_SIZE; // Size of the Binding table NV item, this is the whole size of the item, // it could inculde invalid records also bindLen = osal_nv_item_len( ZCD_NV_BINDING_TABLE ); // Get the number of valid records from the Binding table osal_nv_read( ZCD_NV_BINDING_TABLE, 0, sizeof(nvBindingHdr_t), &hdr ); // Identify if there is a duplicate NV item, if it is there, that means an // Upgrade process did not finish properly last time // The length function will return 0 if the Backup NV ID does not exist. dupLen = osal_nv_item_len( ZCD_NV_DUPLICATE_BINDING_TABLE ); // A duplicate of the original Binding item will be done if: // 1) A duplicate NV item DOES NOT exist AND the size of the original Binding // item in NV is different (larger/smaller) than the the length calculated // from the parameters in the code. If they are the same there is no need // to do the Upgrade process. // 2) A duplicate NV item exists (probably because the previous upgrade // process was interrupted) and [the original Binding NV items exists AND // has valid recods (it is important to make sure that valid records exist // in the binding table because it is possible that the item was created // but the data was not copied in the previous upgrade process). if ( ( ( dupLen == 0 ) && ( bindLen != newLen ) ) || ( ( dupLen > 0 ) && ( bindLen > 0 ) && ( hdr.numRecs > 0 ) ) ) { // Create a copy from original NV item into a duplicate NV item if ( ( status = nwkCreateDuplicateNV( ZCD_NV_BINDING_TABLE, ZCD_NV_DUPLICATE_BINDING_TABLE ) ) == ZSuccess ) { // Delete the original NV item once the duplicate is ready if ( osal_nv_delete( ZCD_NV_BINDING_TABLE, bindLen ) != ZSuccess ) { status = ZFailure; } else { duplicateReady = TRUE; } } } else if ( ( ( dupLen > 0 ) && ( bindLen == 0 ) ) || ( ( dupLen > 0 ) && ( bindLen > 0 ) && ( hdr.numRecs == 0 ) ) ) { // If for some reason a duplicate NV item was left in the system from a // previous upgrade process and: // 1) The original Binding NV item DOES NOT exist OR // 2) The original Binding NV item exist, but has no valid records. // it is necessary to rely in the data in the Duplicate item to create // the Binding table bindLen = dupLen; duplicateReady = TRUE; } if ( duplicateReady == TRUE ) { // Creates the New Binding table, Copy data from backup and Delete backup NV ID status = BindCopyBackupToNewNV( bindLen, newLen ); } return ( status ); }
/********************************************************************* * @fn NIB_init() * * @brief * * Initialize attribute values in NIB * * @param none * * @return none */ void NIB_init() { _NIB.SequenceNum = LO_UINT16(osal_rand()); _NIB.nwkProtocolVersion = ZB_PROT_VERS; _NIB.MaxDepth = MAX_NODE_DEPTH; #if ( NWK_MODE == NWK_MODE_MESH ) _NIB.beaconOrder = BEACON_ORDER_NO_BEACONS; _NIB.superFrameOrder = BEACON_ORDER_NO_BEACONS; #endif // BROADCAST SETTINGS: // ******************* // Broadcast Delivery Time // - set to multiples of 100ms // - should be 500ms more than the retry time // - "retry time" = PassiveAckTimeout * (MaxBroadcastRetries + 1) // Passive Ack Timeout // - set to multiples of 100ms _NIB.BroadcastDeliveryTime = zgBcastDeliveryTime; _NIB.PassiveAckTimeout = zgPassiveAckTimeout; _NIB.MaxBroadcastRetries = zgMaxBcastRetires; _NIB.ReportConstantCost = 0; _NIB.RouteDiscRetries = 0; _NIB.SecureAllFrames = USE_NWK_SECURITY; _NIB.nwkAllFresh = NWK_ALL_FRESH; if ( ZG_SECURE_ENABLED ) { _NIB.SecurityLevel = SECURITY_LEVEL; } else { _NIB.SecurityLevel = 0; } #if defined ( ZIGBEEPRO ) _NIB.SymLink = FALSE; #else _NIB.SymLink = TRUE; #endif _NIB.CapabilityFlags = ZDO_Config_Node_Descriptor.CapabilityFlags; _NIB.TransactionPersistenceTime = zgIndirectMsgTimeout; _NIB.RouteDiscoveryTime = zgRouteDiscoveryTime; _NIB.RouteExpiryTime = zgRouteExpiryTime; _NIB.nwkDevAddress = INVALID_NODE_ADDR; _NIB.nwkLogicalChannel = 0; _NIB.nwkCoordAddress = INVALID_NODE_ADDR; osal_memset( _NIB.nwkCoordExtAddress, 0, Z_EXTADDR_LEN ); _NIB.nwkPanId = INVALID_NODE_ADDR; osal_cpyExtAddr( _NIB.extendedPANID, zgExtendedPANID ); _NIB.nwkKeyLoaded = FALSE; #if defined ( ZIGBEE_STOCHASTIC_ADDRESSING ) _NIB.nwkAddrAlloc = NWK_ADDRESSING_STOCHASTIC; _NIB.nwkUniqueAddr = FALSE; #else _NIB.nwkAddrAlloc = NWK_ADDRESSING_DISTRIBUTED; _NIB.nwkUniqueAddr = TRUE; #endif _NIB.nwkLinkStatusPeriod = NWK_LINK_STATUS_PERIOD; _NIB.nwkRouterAgeLimit = NWK_ROUTE_AGE_LIMIT; //MTO and source routing _NIB.nwkConcentratorDiscoveryTime = zgConcentratorDiscoveryTime; _NIB.nwkIsConcentrator = zgConcentratorEnable; _NIB.nwkConcentratorRadius = zgConcentratorRadius; #if defined ( ZIGBEE_MULTICAST ) _NIB.nwkUseMultiCast = TRUE; #else _NIB.nwkUseMultiCast = FALSE; #endif #if defined ( NV_RESTORE ) if ( osal_nv_read( ZCD_NV_NWKMGR_ADDR, 0, sizeof( _NIB.nwkManagerAddr ), &_NIB.nwkManagerAddr ) != SUCCESS ) #endif { _NIB.nwkManagerAddr = 0x0000; } _NIB.nwkUpdateId = 0; _NIB.nwkTotalTransmissions = 0; if ( ZSTACK_ROUTER_BUILD ) { #if defined ( ZIGBEE_STOCHASTIC_ADDRESSING ) NLME_InitStochasticAddressing(); #else NLME_InitTreeAddressing(); #endif } }
/*************************************************************************************************** * @fn MT_SysOsalNVRead * * @brief Read a NV value * * @param uint8 pBuf - pointer to the data * * @return None ***************************************************************************************************/ void MT_SysOsalNVRead(uint8 *pBuf) { uint16 nvId; uint8 nvItemLen=0, nvItemOffset=0; uint8 *pRetBuf=NULL; uint8 respLen; /* Skip over RPC header */ pBuf += MT_RPC_FRAME_HDR_SZ; /* Get the ID */ nvId = BUILD_UINT16(pBuf[0], pBuf[1]); /* Get the offset */ nvItemOffset = pBuf[2]; #if !MT_SYS_OSAL_NV_READ_CERTIFICATE_DATA if ((ZCD_NV_IMPLICIT_CERTIFICATE == nvId) || (ZCD_NV_CA_PUBLIC_KEY == nvId) || (ZCD_NV_DEVICE_PRIVATE_KEY == nvId)) { uint8 tmp[2] = { INVALIDPARAMETER, 0 }; MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), MT_SYS_OSAL_NV_READ, 2, tmp); return; } #endif #if !MT_SYS_KEY_MANAGEMENT if ( (nvId == ZCD_NV_NWK_ACTIVE_KEY_INFO) || (nvId == ZCD_NV_NWK_ALTERN_KEY_INFO) || ((nvId >= ZCD_NV_TCLK_TABLE_START) && (nvId <= ZCD_NV_TCLK_TABLE_END)) || ((nvId >= ZCD_NV_APS_LINK_KEY_DATA_START) && (nvId <= ZCD_NV_APS_LINK_KEY_DATA_END)) || ((nvId >= ZCD_NV_MASTER_KEY_DATA_START) && (nvId <= ZCD_NV_MASTER_KEY_DATA_END)) || (nvId == ZCD_NV_PRECFGKEY) ) { uint8 tmp1[2] = { INVALIDPARAMETER, 0 }; MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), MT_SYS_OSAL_NV_READ, 2, tmp1); return; } #endif //!MT_SYS_KEY_MANAGEMENT nvItemLen = osal_nv_item_len(nvId); /* Return only 250 bytes max */ if (nvItemLen > MT_NV_ITEM_MAX_LENGTH) { nvItemLen = MT_NV_ITEM_MAX_LENGTH; } if ((nvItemLen > 0) && ((nvItemLen - nvItemOffset) > 0)) { respLen = nvItemLen - nvItemOffset + 2; } else { respLen = 2; } pRetBuf = osal_mem_alloc(respLen); if (pRetBuf != NULL) { osal_memset(pRetBuf, 0, respLen); /* Default to ZFailure */ pRetBuf[0] = ZFailure; if (respLen > 2) { if (((osal_nv_read( nvId, (uint16)nvItemOffset, (uint16)nvItemLen, &pRetBuf[2])) == ZSUCCESS) && (respLen > 2)) { pRetBuf[0] = ZSuccess; } pRetBuf[1] = nvItemLen - nvItemOffset; } else { pRetBuf[1] = 0; } /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), MT_SYS_OSAL_NV_READ, respLen, pRetBuf ); osal_mem_free(pRetBuf); } }
/************************************************************************************************** * @fn MT_ZnpBasicRsp * * @brief Build and send the ZNP Basic Response to the ZAP. * * input parameters * * None. * * output parameters * * None. * * @return true if message built and sent; false otherwise. */ bool MT_ZnpBasicRsp(void) { uint8 *pBuf = osal_mem_alloc(sizeof(mt_znp_basic_rsp_t)); if (pBuf == NULL) { return false; } osal_buffer_uint32( &pBuf[0], MT_PeriodicMsgRate ); osal_buffer_uint32( &pBuf[4], zgDefaultChannelList ); pBuf[8] = LO_UINT16(zgConfigPANID); pBuf[9] = HI_UINT16(zgConfigPANID); osal_nv_read(ZCD_NV_STARTUP_OPTION, 0, 1, pBuf+10); pBuf[11] = zgDeviceLogicalType; pBuf[12] = LO_UINT16(_NIB.nwkDevAddress); pBuf[13] = HI_UINT16(_NIB.nwkDevAddress); pBuf[14] = LO_UINT16(_NIB.nwkCoordAddress); pBuf[15] = HI_UINT16(_NIB.nwkCoordAddress); pBuf[16] = LO_UINT16(_NIB.nwkPanId); pBuf[17] = HI_UINT16(_NIB.nwkPanId); pBuf[18] = _NIB.nwkLogicalChannel; pBuf[19] = _NIB.nwkState; (void)osal_memcpy(pBuf+20, _NIB.nwkCoordExtAddress, Z_EXTADDR_LEN); (void)osal_memcpy(pBuf+28, aExtendedAddress, Z_EXTADDR_LEN); pBuf[36] = devState; #if defined INTER_PAN extern uint8 appEndPoint; pBuf[37] = appEndPoint; //rsp->spare1[2]; #else //rsp->spare1[3]; #endif // Initialize list with invalid EndPoints. (void)osal_memset(pBuf+40, AF_BROADCAST_ENDPOINT, (MT_ZNP_EP_ID_LIST_MAX * 3)); uint8 idx = 40; epList_t *epItem = epList; for (uint8 cnt = 0; cnt < MT_ZNP_EP_ID_LIST_MAX; cnt++) { if (epItem == NULL) { break; } if ((epItem->epDesc->simpleDesc != NULL) && (epItem->epDesc->simpleDesc->EndPoint != ZDO_EP)) { pBuf[idx++] = epItem->epDesc->simpleDesc->EndPoint; pBuf[idx++] = LO_UINT16(epItem->epDesc->simpleDesc->AppProfId); pBuf[idx++] = HI_UINT16(epItem->epDesc->simpleDesc->AppProfId); } epItem = epItem->nextDesc; } idx = 40 + (MT_ZNP_EP_ID_LIST_MAX * 3); // Initialize list with invalid Cluster Id's. (void)osal_memset(pBuf+idx, 0xFF, (MT_ZNP_ZDO_MSG_CB_LIST_MAX * 2)); typedef struct { void *next; uint8 taskID; uint16 clusterID; } ZDO_MsgCB_t; extern ZDO_MsgCB_t *zdoMsgCBs; ZDO_MsgCB_t *pItem = zdoMsgCBs; for (uint8 cnt = 0; cnt < MT_ZNP_ZDO_MSG_CB_LIST_MAX; cnt++) { if (pItem == NULL) { break; } else if (pItem->taskID == MT_TaskID) { pBuf[idx++] = LO_UINT16(pItem->clusterID); pBuf[idx++] = HI_UINT16(pItem->clusterID); } pItem = pItem->next; } idx = 40 + (MT_ZNP_EP_ID_LIST_MAX * 3) + (MT_ZNP_ZDO_MSG_CB_LIST_MAX * 2); extern pfnZdoCb zdoCBFunc[MAX_ZDO_CB_FUNC]; for (uint8 cnt = 0; cnt < MAX_ZDO_CB_FUNC; cnt++) { pBuf[idx++] = (zdoCBFunc[cnt] == NULL) ? 0 : 1; } MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_ZNP), MT_ZNP_BASIC_RSP, 40 + (MT_ZNP_EP_ID_LIST_MAX * 3) + (MT_ZNP_ZDO_MSG_CB_LIST_MAX * 2) + MAX_ZDO_CB_FUNC, pBuf); (void)osal_mem_free(pBuf); return true; }
/*************************************************************************************************** * @fn MT_UtilGetNvInfo * * @brief The Get NV Info serial message. * * @param None. * * @return void ***************************************************************************************************/ void MT_UtilGetNvInfo(void) { uint8 len; uint8 stat; uint8 *buf; uint8 *pBuf; uint16 tmp16; uint32 tmp32; /* Get required length of buffer Status + ExtAddr + ChanList + PanID + SecLevel + PreCfgKey */ len = 1 + Z_EXTADDR_LEN + 4 + 2 + 1 + SEC_KEY_LEN; buf = osal_mem_alloc( len ); if ( buf ) { /* Assume NV not available */ osal_memset( buf, 0xFF, len ); /* Skip over status */ pBuf = buf + 1; /* Start with 64-bit extended address */ stat = osal_nv_read( ZCD_NV_EXTADDR, 0, Z_EXTADDR_LEN, pBuf ); if ( stat ) stat = 0x01; pBuf += Z_EXTADDR_LEN; /* Scan channel list (bit mask) */ if ( osal_nv_read( ZCD_NV_CHANLIST, 0, sizeof( tmp32 ), &tmp32 ) ) stat |= 0x02; else { pBuf[0] = BREAK_UINT32( tmp32, 3 ); pBuf[1] = BREAK_UINT32( tmp32, 2 ); pBuf[2] = BREAK_UINT32( tmp32, 1 ); pBuf[3] = BREAK_UINT32( tmp32, 0 ); } pBuf += sizeof( tmp32 ); /* ZigBee PanID */ if ( osal_nv_read( ZCD_NV_PANID, 0, sizeof( tmp16 ), &tmp16 ) ) stat |= 0x04; else { pBuf[0] = LO_UINT16( tmp16 ); pBuf[1] = HI_UINT16( tmp16 ); } pBuf += sizeof( tmp16 ); /* Security level */ if ( osal_nv_read( ZCD_NV_SECURITY_LEVEL, 0, sizeof( uint8 ), pBuf++ ) ) stat |= 0x08; /* Pre-configured security key */ if ( osal_nv_read( ZCD_NV_PRECFGKEY, 0, SEC_KEY_LEN, pBuf ) ) stat |= 0x10; /* Status bit mask - bit=1 indicates failure */ *buf = stat; MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), MT_UTIL_GET_NV_INFO, len, buf ); osal_mem_free( buf ); } }
/*************************************************************************************************** * @fn MT_UtilGetDeviceInfo * * @brief The Get Device Info serial message. * * @param None. * * @return void ***************************************************************************************************/ void MT_UtilGetDeviceInfo(void) { uint8 *buf; uint8 *pBuf; uint8 bufLen = MT_UTIL_DEVICE_INFO_RESPONSE_LEN; uint16 *assocList = NULL; #if !defined NONWK uint8 assocCnt = 0; if (ZG_DEVICE_RTR_TYPE) { assocList = AssocMakeList( &assocCnt ); bufLen += (assocCnt * sizeof(uint16)); } #endif buf = osal_mem_alloc( bufLen ); if ( buf ) { pBuf = buf; *pBuf++ = ZSUCCESS; // Status osal_nv_read( ZCD_NV_EXTADDR, 0, Z_EXTADDR_LEN, pBuf ); pBuf += Z_EXTADDR_LEN; #if defined NONWK // Skip past ZStack only parameters for NONWK *pBuf++ = 0; *pBuf++ = 0; *pBuf++ = 0; *pBuf++ = 0; *pBuf = 0; #else { uint16 shortAddr = NLME_GetShortAddr(); *pBuf++ = LO_UINT16( shortAddr ); *pBuf++ = HI_UINT16( shortAddr ); } /* Return device type */ *pBuf++ = ZSTACK_DEVICE_BUILD; /*Return device state */ *pBuf++ = (uint8)devState; if (ZG_DEVICE_RTR_TYPE) { *pBuf++ = assocCnt; if ( assocCnt ) { uint8 x; uint16 *puint16 = assocList; for ( x = 0; x < assocCnt; x++, puint16++ ) { *pBuf++ = LO_UINT16( *puint16 ); *pBuf++ = HI_UINT16( *puint16 ); } } } else { *pBuf++ = 0; } #endif MT_BuildAndSendZToolResponse( ((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), MT_UTIL_GET_DEVICE_INFO, bufLen, buf ); osal_mem_free( buf ); } if ( assocList ) { osal_mem_free( assocList ); } }
/********************************************************************* * @fn zllSampleLight_PrintNwkKey * * @brief Print current NWK key on the LCD screen * * @param reverse - TRUE to print the bytes in reverse order * * @return none */ static void zllSampleLight_PrintNwkKey( uint8 reverse ) { nwkKeyDesc KeyInfo; uint8 lcd_buf[SEC_KEY_LEN+1]; uint8 lcd_buf1[SEC_KEY_LEN+1]; uint8 lcd_buf2[SEC_KEY_LEN+1]; uint8 i; static uint8 clear = 1; clear ^= 1; if ( clear ) { nwk_Status( NWK_STATUS_ROUTER_ADDR, _NIB.nwkDevAddress ); nwk_Status( NWK_STATUS_PARENT_ADDR, _NIB.nwkCoordAddress ); HalLcdWriteString( "", HAL_LCD_LINE_3 ); return; } // Swap active and alternate keys writing them directly to NV osal_nv_read(ZCD_NV_NWK_ACTIVE_KEY_INFO, 0, sizeof(nwkKeyDesc), &KeyInfo); for (i = 0; i < SEC_KEY_LEN/2; i++) { uint8 key = KeyInfo.key[i]; _itoa(KeyInfo.key[i], &lcd_buf[i*2], 16); if( (key & 0xF0) == 0) { //_itoa shift to significant figures, so swaps bytes if 0x0? lcd_buf[(i*2) + 1] = lcd_buf[i*2]; lcd_buf[i*2] = '0'; } if( (key & 0xF) == 0) { lcd_buf[(i*2) + 1] = '0'; } } if ( reverse ) { //print in daintree format. Reverse bytes. for (i = 0; i < (SEC_KEY_LEN); i+=2) { lcd_buf2[SEC_KEY_LEN - (i+2)] = lcd_buf[i]; lcd_buf2[SEC_KEY_LEN - (i+1)] = lcd_buf[i+1]; } } else { osal_memcpy(lcd_buf1, lcd_buf, SEC_KEY_LEN); } for (i = 0; i < SEC_KEY_LEN/2; i++) { uint8 key = KeyInfo.key[i + SEC_KEY_LEN/2]; _itoa(KeyInfo.key[i + SEC_KEY_LEN/2], &lcd_buf[i*2], 16); if( (key & 0xF0) == 0) { //_itoa shift to significant figures, so swaps bytes if 0x0? lcd_buf[(i*2) + 1] = lcd_buf[i*2]; lcd_buf[i*2] = '0'; } if( (key & 0xF) == 0) { lcd_buf[(i*2) + 1] = '0'; } } if ( reverse ) { //print in daintree format. Reverse bytes. for (i = 0; i < (SEC_KEY_LEN); i+=2) { lcd_buf1[SEC_KEY_LEN - (i+2)] = lcd_buf[i]; lcd_buf1[SEC_KEY_LEN - (i+1)] = lcd_buf[i+1]; } } else { osal_memcpy(lcd_buf2, lcd_buf, SEC_KEY_LEN); } lcd_buf1[SEC_KEY_LEN] = '\0'; lcd_buf2[SEC_KEY_LEN] = '\0'; if ( reverse ) { HalLcdWriteString( "NWK KEY (Rev.):", HAL_LCD_LINE_1 ); } else { HalLcdWriteString( "NWK KEY: ", HAL_LCD_LINE_1 ); } HalLcdWriteString( (char*)lcd_buf1, HAL_LCD_LINE_2 ); HalLcdWriteString( (char*)lcd_buf2, HAL_LCD_LINE_3 ); }
/********************************************************************* * @fn BindCopyBackupToNewNV * * @brief Creates the New NV item, copies the backup data into * the New NV ID, and Deletes the duplicate NV item. * * @param dupLen - NV item length of the old Binding table. * @param newLen - NV item length of the new Binding table to be created. * * @return ZSuccess - All the actions were successful. * ZFailure - Any of the actions failed. */ static uint8 BindCopyBackupToNewNV( uint16 dupLen, uint16 newLen ) { uint8 status = ZSuccess; uint16 bindLen; bindLen = osal_nv_item_len( ZCD_NV_BINDING_TABLE ); if ( ( bindLen > 0 ) && ( bindLen != newLen ) ) { // The existing item does not match the New length osal_nv_delete( ZCD_NV_BINDING_TABLE, bindLen ); } // Create Binding Table NV item with the NEW legth if ( osal_nv_item_init( ZCD_NV_BINDING_TABLE, newLen, NULL ) != NV_OPER_FAILED ) { nvBindingHdr_t hdrBackup; // Copy ONLY the valid records from the duplicate NV table into the new table // at the end of this process the table content will be compacted if ( osal_nv_read( ZCD_NV_DUPLICATE_BINDING_TABLE, 0, sizeof(nvBindingHdr_t), &hdrBackup ) == ZSuccess ) { bindTableIndex_t i; uint16 validBackupRecs = 0; BindingEntry_t backupRec; // Read in the device list. This loop will stop when: // The total number of valid records has been reached either because: // The new table is full of valid records OR // The old table has less valid records than the size of the table for ( i = 0; ( validBackupRecs < gNWK_MAX_BINDING_ENTRIES ) && ( validBackupRecs < hdrBackup.numRecs ); i++ ) { if ( osal_nv_read( ZCD_NV_DUPLICATE_BINDING_TABLE, (uint16)(sizeof(nvBindingHdr_t) + (i * NV_BIND_REC_SIZE)), NV_BIND_REC_SIZE, &backupRec ) == ZSuccess ) { if ( backupRec.srcEP != NV_BIND_EMPTY ) { // Save the valid record into the NEW NV table. if ( osal_nv_write( ZCD_NV_BINDING_TABLE, (uint16)((sizeof(nvBindingHdr_t)) + (validBackupRecs * NV_BIND_REC_SIZE)), NV_BIND_REC_SIZE, &backupRec ) != ZSuccess ) { status = ZFailure; break; // Terminate the loop as soon as a problem with NV is detected } validBackupRecs++; } } else { status = ZFailure; break; // Terminate the loop as soon as a problem with NV is detected } } // Only save the header and delete the duplicate element if the previous // process was successful if ( status == ZSuccess ) { // Save off the header if ( osal_nv_write( ZCD_NV_BINDING_TABLE, 0, sizeof(nvBindingHdr_t), &validBackupRecs ) == ZSuccess ) { // Delete the duplicate NV Item, once the data has been stored in the NEW table if ( osal_nv_delete( ZCD_NV_DUPLICATE_BINDING_TABLE, dupLen ) != ZSuccess ) { status = ZFailure; } } else { status = ZFailure; } } } else { status = ZFailure; } } else { status = ZFailure; } return ( status ); }
/**************************************************************************** * @fn ZDiagsGetStatsAttr * * @brief Reads specific systemID statistics and/or metrics * * @param attributeId input - unique identifier for the required attribute * * NOTE: the user of this function will have to cast the value * based on the type of the attributeID, the returned value * will allways be uint32. * * @return Value of the attribute requested. */ uint32 ZDiagsGetStatsAttr( uint16 attributeId ) { uint32 diagsValue = 0; #if defined ( FEATURE_SYSTEM_STATS ) switch ( attributeId ) { // System and Hardware Diagnostics case ZDIAGS_SYSTEM_CLOCK: // this is the system clock when statistics were cleared; diagsValue = DiagsStatsTable.SysClock; break; case ZDIAGS_NUMBER_OF_RESETS: // Get the value from NV memory osal_nv_read( ZCD_NV_BOOTCOUNTER, 0, sizeof(uint16), &diagsValue ); break; case ZDIAGS_PERSISTENT_MEMORY_WRITES: diagsValue = DiagsStatsTable.PersistentMemoryWrites; break; // MAC Diagnostics case ZDIAGS_MAC_RX_CRC_PASS: ZMacGetReq( ZMacDiagsRxCrcPass, (uint8 *)&diagsValue ); // Update the statistics table with this value from MAC DiagsStatsTable.MacRxCrcPass = diagsValue; break; case ZDIAGS_MAC_RX_CRC_FAIL: ZMacGetReq( ZMacDiagsRxCrcFail, (uint8 *)&diagsValue ); // Update the statistics table with this value from MAC DiagsStatsTable.MacRxCrcFail = diagsValue; break; case ZDIAGS_MAC_RX_BCAST: ZMacGetReq( ZMacDiagsRxBcast, (uint8 *)&diagsValue ); // Update the statistics table with this value from MAC DiagsStatsTable.MacRxBcast = diagsValue; break; case ZDIAGS_MAC_TX_BCAST: ZMacGetReq( ZMacDiagsTxBcast, (uint8 *)&diagsValue ); // Update the statistics table with this value from MAC DiagsStatsTable.MacTxBcast = diagsValue; break; case ZDIAGS_MAC_RX_UCAST: ZMacGetReq( ZMacDiagsRxUcast, (uint8 *)&diagsValue ); // Update the statistics table with this value from MAC DiagsStatsTable.MacRxUcast = diagsValue; break; case ZDIAGS_MAC_TX_UCAST: ZMacGetReq( ZMacDiagsTxUcast, (uint8 *)&diagsValue ); // Update the statistics table with this value from MAC DiagsStatsTable.MacTxUcast = diagsValue; break; case ZDIAGS_MAC_TX_UCAST_RETRY: ZMacGetReq( ZMacDiagsTxUcastRetry, (uint8 *)&diagsValue ); // Update the statistics table with this value from MAC DiagsStatsTable.MacTxUcastRetry = diagsValue; break; case ZDIAGS_MAC_TX_UCAST_FAIL: ZMacGetReq( ZMacDiagsTxUcastFail, (uint8 *)&diagsValue ); // Update the statistics table with this value from MAC DiagsStatsTable.MacTxUcastFail = diagsValue; break; // NWK Diagnostics case ZDIAGS_ROUTE_DISC_INITIATED: diagsValue = DiagsStatsTable.RouteDiscInitiated; break; case ZDIAGS_NEIGHBOR_ADDED: diagsValue = DiagsStatsTable.NeighborAdded; break; case ZDIAGS_NEIGHBOR_REMOVED: diagsValue = DiagsStatsTable.NeighborRemoved; break; case ZDIAGS_NEIGHBOR_STALE: diagsValue = DiagsStatsTable.NeighborStale; break; case ZDIAGS_JOIN_INDICATION: diagsValue = DiagsStatsTable.JoinIndication; break; case ZDIAGS_CHILD_MOVED: diagsValue = DiagsStatsTable.ChildMoved; break; case ZDIAGS_NWK_FC_FAILURE: diagsValue = DiagsStatsTable.NwkFcFailure; break; case ZDIAGS_NWK_DECRYPT_FAILURES: diagsValue = DiagsStatsTable.NwkDecryptFailures; break; case ZDIAGS_PACKET_BUFFER_ALLOCATE_FAILURES: diagsValue = DiagsStatsTable.PacketBufferAllocateFailures; break; case ZDIAGS_RELAYED_UCAST: diagsValue = DiagsStatsTable.RelayedUcast; break; case ZDIAGS_PHY_TO_MAC_QUEUE_LIMIT_REACHED: diagsValue = DiagsStatsTable.PhyToMacQueueLimitReached; break; case ZDIAGS_PACKET_VALIDATE_DROP_COUNT: diagsValue = DiagsStatsTable.PacketValidateDropCount; break; // APS Diagnostics case ZDIAGS_APS_RX_BCAST: diagsValue = DiagsStatsTable.ApsRxBcast; break; case ZDIAGS_APS_TX_BCAST: diagsValue = DiagsStatsTable.ApsTxBcast; break; case ZDIAGS_APS_RX_UCAST: diagsValue = DiagsStatsTable.ApsRxUcast; break; case ZDIAGS_APS_TX_UCAST_SUCCESS: diagsValue = DiagsStatsTable.ApsTxUcastSuccess; break; case ZDIAGS_APS_TX_UCAST_RETRY: diagsValue = DiagsStatsTable.ApsTxUcastRetry; break; case ZDIAGS_APS_TX_UCAST_FAIL: diagsValue = DiagsStatsTable.ApsTxUcastFail; break; case ZDIAGS_APS_FC_FAILURE: diagsValue = DiagsStatsTable.ApsFcFailure; break; case ZDIAGS_APS_UNAUTHORIZED_KEY: diagsValue = DiagsStatsTable.ApsUnauthorizedKey; break; case ZDIAGS_APS_DECRYPT_FAILURES: diagsValue = DiagsStatsTable.ApsDecryptFailures; break; case ZDIAGS_APS_INVALID_PACKETS: diagsValue = DiagsStatsTable.ApsInvalidPackets; break; case ZDIAGS_MAC_RETRIES_PER_APS_TX_SUCCESS: diagsValue = DiagsStatsTable.MacRetriesPerApsTxSuccess; break; default: break; } #endif // FEATURE_SYSTEM_STATS return ( diagsValue ); }