/********************************************************************* * This function is used to check if the user id has been bonded **********************************************************************/ uint32_t check_user_id_bonded(const uint8_t* user_id, uint8_t length) { uint32_t err_code = NRF_SUCCESS; uint16_t crc_header; uint16_t m_crc_bond_info; uint32_t *mp_flash_bond_info; uint32_t header; if((!user_id) || (length != USER_ID_LENGTH)) { err_code = NRF_ERROR_INVALID_PARAM; return err_code; } // Initialize CRC m_crc_bond_info = ble_flash_crc16_compute(NULL, 0, NULL); // Find pointer to start of bond information flash block err_code = ble_flash_page_addr(FLASH_PAGE_USER_ID, &mp_flash_bond_info); if (err_code != NRF_SUCCESS) { return err_code; } //get crc header = *mp_flash_bond_info; if ((header & 0xFFFF0000U) == BLE_FLASH_MAGIC_NUMBER) { crc_header = (uint16_t)(header & 0x0000FFFFU); } else if (header == 0xFFFFFFFFU) { return NRF_ERROR_NOT_FOUND; } else { return NRF_ERROR_INVALID_DATA; } /* check crc in the flash */ // Check CRC m_crc_bond_info = ble_flash_crc16_compute((uint8_t *)(mp_flash_bond_info + 1), USER_ID_LENGTH, &m_crc_bond_info); if (m_crc_bond_info != crc_header) { return NRF_ERROR_INVALID_DATA; } if (memcmp(user_id,(uint8_t *)(mp_flash_bond_info + 1),length) == 0) { err_code = NRF_SUCCESS; } else { err_code = NRF_ERROR_INVALID_DATA; } return err_code; }
/**@brief This function stores in flash the System Attributes related to a specified master. * * @param[in] p_sys_attr System Attributes to be stored. * * @return NRF_SUCCESS on success, an error_code otherwise. */ static uint32_t sys_attr_store(master_sys_attr_t * p_sys_attr) { uint32_t err_code; // Check if flash is full. if (m_sys_attr_in_flash_count >= MAX_BONDS_IN_FLASH) { return NRF_ERROR_NO_MEM; } // Check if this is the first time any System Attributes is stored. if (m_sys_attr_in_flash_count == 0) { // Initialize CRC m_crc_sys_attr = ble_flash_crc16_compute(NULL, 0, NULL); // Find pointer to start of System Attributes flash block. err_code = ble_flash_page_addr(m_bondmngr_config.flash_page_num_sys_attr, &mp_flash_sys_attr); if (err_code != NRF_SUCCESS) { return err_code; } } // Write System Attributes in flash. err_code = ble_flash_block_write(mp_flash_sys_attr + 1, (uint32_t *)p_sys_attr, sizeof(master_sys_attr_t) / sizeof(uint32_t)); if (err_code != NRF_SUCCESS) { return err_code; } m_crc_sys_attr = ble_flash_crc16_compute((uint8_t *)p_sys_attr, sizeof(master_sys_attr_t), &m_crc_sys_attr); // Write header err_code = ble_flash_word_write(mp_flash_sys_attr, BLE_FLASH_MAGIC_NUMBER | m_crc_sys_attr); if (err_code != NRF_SUCCESS) { return err_code; } // Update flash pointer mp_flash_sys_attr += ((sizeof(master_sys_attr_t) / sizeof(uint32_t)) + 1); m_sys_attr_in_flash_count++; return NRF_SUCCESS; }
/**@brief This function stores the Bonding Information of the specified master to the flash. * * @param[in] p_bond Bonding information to be stored. * * @return NRF_SUCCESS on success, an error_code otherwise. */ static uint32_t bond_info_store(master_bond_t * p_bond) { uint32_t err_code; // Check if flash is full if (m_bond_info_in_flash_count >= MAX_BONDS_IN_FLASH) { return NRF_ERROR_NO_MEM; } // Check if this is the first bond to be stored if (m_bond_info_in_flash_count == 0) { // Initialize CRC m_crc_bond_info = ble_flash_crc16_compute(NULL, 0, NULL); // Find pointer to start of bond information flash block err_code = ble_flash_page_addr(m_bondmngr_config.flash_page_num_bond, &mp_flash_bond_info); if (err_code != NRF_SUCCESS) { return err_code; } } // Write Bonding Information err_code = ble_flash_block_write(mp_flash_bond_info + 1, (uint32_t *)p_bond, sizeof(master_bond_t) / sizeof(uint32_t)); if (err_code != NRF_SUCCESS) { return err_code; } m_crc_bond_info = ble_flash_crc16_compute((uint8_t *)p_bond, sizeof(master_bond_t), &m_crc_bond_info); // Write header err_code = ble_flash_word_write(mp_flash_bond_info, BLE_FLASH_MAGIC_NUMBER | m_crc_bond_info); if (err_code != NRF_SUCCESS) { return err_code; } // Update flash pointer mp_flash_bond_info += (sizeof(master_bond_t) / sizeof(uint32_t)) + 1; m_bond_info_in_flash_count++; return NRF_SUCCESS; }
/**@brief This function checks if System Attributes in RAM is different from that in flash. * * @return TRUE if System Attributes in flash and RAM are different, FALSE otherwise. */ static bool sys_attr_changed(void) { int i; uint16_t crc = ble_flash_crc16_compute(NULL, 0, NULL); // Compute CRC for all System Attributes in database for (i = 0; i < m_masters_in_db_count; i++) { crc = ble_flash_crc16_compute((uint8_t *)&m_masters_db[i].sys_attr, sizeof(master_sys_attr_t), &crc); } // Compare to CRC of System Attributes in flash with that of the System Attributes in memory. return (crc != m_crc_sys_attr); }
/**@brief This function checks if Bonding Information in RAM is different from that in * flash. * * @return TRUE if Bonding Information in flash and RAM are different, FALSE otherwise. */ static bool bond_info_changed(void) { int i; uint16_t crc = ble_flash_crc16_compute(NULL, 0, NULL); // Compute CRC for all bonds in database for (i = 0; i < m_masters_in_db_count; i++) { crc = ble_flash_crc16_compute((uint8_t *)&m_masters_db[i].bond, sizeof(master_bond_t), &crc); } // Compare to CRC of bonds in flash return (crc != m_crc_bond_info); }
/**@brief This function loads the System Attributes related to one master from flash. * * @param[out] p_sys_attr Loaded System Attributes. * * @return NRF_SUCCESS on success, otherwise an error code. */ static uint32_t sys_attr_load_from_flash(master_sys_attr_t * p_sys_attr) { uint32_t err_code; uint16_t crc_header; // Check if this is the first time System Attributes is loaded from flash, in which case the // m_sys_attr_in_flash_count variable would have the initial value 0. if (m_sys_attr_in_flash_count == 0) { // Initialize CRC m_crc_sys_attr = ble_flash_crc16_compute(NULL, 0, NULL); // Find pointer to start of System Attributes flash block err_code = ble_flash_page_addr(m_bondmngr_config.flash_page_num_sys_attr, &mp_flash_sys_attr); if (err_code != NRF_SUCCESS) { return err_code; } } // Extract CRC from header err_code = crc_extract(*mp_flash_sys_attr, &crc_header); if (err_code != NRF_SUCCESS) { return err_code; } // Read System Attributes from flash *p_sys_attr = *(master_sys_attr_t *)(mp_flash_sys_attr + 1); // Check CRC m_crc_sys_attr = ble_flash_crc16_compute((uint8_t *)p_sys_attr, sizeof(master_sys_attr_t), &m_crc_sys_attr); if (m_crc_sys_attr == crc_header) { m_sys_attr_in_flash_count++; mp_flash_sys_attr += (sizeof(master_sys_attr_t) / sizeof(uint32_t)) + 1; return NRF_SUCCESS; } else { return NRF_ERROR_INVALID_DATA; } }
/**@brief This function loads the Bonding Information of one master from flash. * * @param[out] p_bond Loaded Bonding Information. * * @return NRF_SUCCESS on success, otherwise an error code. */ static uint32_t bonding_info_load_from_flash(master_bond_t * p_bond) { uint32_t err_code; uint16_t crc_header; // Check if this is the first bond to be loaded, in which case the // m_bond_info_in_flash_count variable would have the intial value 0. if (m_bond_info_in_flash_count == 0) { // Initialize CRC m_crc_bond_info = ble_flash_crc16_compute(NULL, 0, NULL); // Find pointer to start of bond information flash block err_code = ble_flash_page_addr(m_bondmngr_config.flash_page_num_bond, &mp_flash_bond_info); if (err_code != NRF_SUCCESS) { return err_code; } } // Extract CRC from header err_code = crc_extract(*mp_flash_bond_info, &crc_header); if (err_code != NRF_SUCCESS) { return err_code; } // Load master *p_bond = *(master_bond_t *)(mp_flash_bond_info + 1); // Check CRC m_crc_bond_info = ble_flash_crc16_compute((uint8_t *)p_bond, sizeof(master_bond_t), &m_crc_bond_info); if (m_crc_bond_info == crc_header) { m_bond_info_in_flash_count++; mp_flash_bond_info += (sizeof(master_bond_t) / sizeof(uint32_t)) + 1; return NRF_SUCCESS; } else { return NRF_ERROR_INVALID_DATA; } }
uint32_t bond_read_user_id(void) { uint32_t err_code; uint16_t crc_header; uint16_t m_crc_bond_info; uint32_t *mp_flash_bond_info; uint32_t header; // Initialize CRC m_crc_bond_info = ble_flash_crc16_compute(NULL, 0, NULL); // Find pointer to start of bond information flash block err_code = ble_flash_page_addr(FLASH_PAGE_USER_ID, &mp_flash_bond_info); if (err_code != NRF_SUCCESS) { return err_code; } //get crc header = *mp_flash_bond_info; if ((header & 0xFFFF0000U) == BLE_FLASH_MAGIC_NUMBER) { crc_header = (uint16_t)(header & 0x0000FFFFU); } else if (header == 0xFFFFFFFFU) { return NRF_ERROR_NOT_FOUND; } else { return NRF_ERROR_INVALID_DATA; } // Load master memcpy(user_id,mp_flash_bond_info + 1, USER_ID_LENGTH); // Check CRC m_crc_bond_info = ble_flash_crc16_compute((uint8_t *)user_id, USER_ID_LENGTH, &m_crc_bond_info); if (m_crc_bond_info == crc_header) { return NRF_SUCCESS; } else { return NRF_ERROR_INVALID_DATA; } }
uint32_t bond_store_user_id(void) { uint32_t err_code; uint16_t m_crc_bond_info; uint32_t *mp_flash_bond_info; /* inialize crc check */ m_crc_bond_info = ble_flash_crc16_compute(NULL, 0, NULL); // Find pointer to start of bond information flash block err_code = ble_flash_page_addr(FLASH_PAGE_USER_ID, &mp_flash_bond_info); if (err_code != NRF_SUCCESS) { return err_code; } /*FIXME: erase a page while bluetooth connected may cause disconnect, so this maybe stored when bluetooth disconnected*/ /* Erase the whole page */ ble_flash_page_erase(FLASH_PAGE_USER_ID); // Write private bonding Information err_code = ble_flash_block_write(mp_flash_bond_info + 1, //the first word is used to store crc (uint32_t *)user_id, ((USER_ID_LENGTH - 1) / (4) + 1)); if (err_code != NRF_SUCCESS) { return err_code; } m_crc_bond_info = ble_flash_crc16_compute((uint8_t *)user_id, USER_ID_LENGTH, &m_crc_bond_info); // Write header err_code = ble_flash_word_write(mp_flash_bond_info, BLE_FLASH_MAGIC_NUMBER | m_crc_bond_info); if (err_code != NRF_SUCCESS) { return err_code; } return NRF_SUCCESS; }