/*************************************************************************************************** * @fn MT_SysOsalNVDelete * * @brief Attempt to delete an NV item * * @param uint8 pData - pointer to the data * * @return None ***************************************************************************************************/ void MT_SysOsalNVDelete(uint8 *pBuf) { uint16 nvId; uint16 nvLen; uint8 ret; /* Skip over RPC header */ pBuf += MT_RPC_FRAME_HDR_SZ; /* Get the ID */ nvId = BUILD_UINT16(pBuf[0], pBuf[1]); /* Get the length */ nvLen = BUILD_UINT16(pBuf[2], pBuf[3]); /* Attempt to delete the NV item */ ret = osal_nv_delete( nvId, nvLen ); /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), MT_SYS_OSAL_NV_DELETE, 1, &ret); }
/********************************************************************* * @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 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 ); }