uint32_t ble_central_bondmngr_init(ble_central_bondmngr_t * p_bm, ble_central_bondmngr_init_t * p_bm_init)
{
    uint32_t err_code;
    
    p_bm->p_sec_params = p_bm_init->p_sec_params;
    
    bond_info.keyset.keys_periph.p_enc_key = &bond_info.enc_key;
    
    if (p_bm_init->delete_bonds)
    {
        err_code = ble_flash_page_erase(BLE_CENTRAL_BONDMNGR_PAGE_NUM);
        if (err_code != NRF_SUCCESS)
            return err_code;
    }
    else
    {
        uint8_t size_to_read = sizeof(bond_info)/sizeof(uint32_t);
        err_code = ble_flash_page_read(BLE_CENTRAL_BONDMNGR_PAGE_NUM, (uint32_t *) &bond_info, &size_to_read);
        if (err_code != NRF_ERROR_NOT_FOUND && err_code != NRF_SUCCESS)
            return err_code;

        printf("Restoring data from %d, %d...\r\n", BLE_CENTRAL_BONDMNGR_PAGE_NUM, BLE_CENTRAL_BONDMNGR_PAGE_NUM*NRF_FICR->CODEPAGESIZE);
    }
    
    print_address(&bond_info.addr);
    
    return NRF_SUCCESS;
}
Exemple #2
0
uint32_t pstorage_clear(pstorage_handle_t * p_dest, pstorage_size_t size)
{
    uint32_t page_addr;
    uint32_t retval;
    uint16_t page_count;

    VERIFY_MODULE_INITIALIZED();
    NULL_PARAM_CHECK(p_dest);
    MODULE_ID_RANGE_CHECK(p_dest);

    page_addr = p_dest->block_id / BLE_FLASH_PAGE_SIZE;

    retval = NRF_SUCCESS;

    for (page_count = 0; page_count < m_app_table[p_dest->module_id].no_of_pages; page_count++)
    {
        retval = ble_flash_page_erase(page_addr);
        page_addr++;
        if (retval != NRF_SUCCESS)
        {
            break;
        }
    }
    app_notify(p_dest, NULL, PSTORAGE_CLEAR_OP_CODE, size, retval);
    return retval;
}
Exemple #3
0
void persistent_init(void)
{
	uint8_t i, j;
	uint8_t buf[16], buf2[4];
	uint32_t magic32 = 0xEFBEADDE;		// reverse DEADBEEF
	uint32_t ido2Name1 = 0x326F4469;	// reverse iDo2
	uint32_t ido2Name2 = 0x00000000;	// string end
	uint32_t tmp32;
	uint32_t buf32[64];

	__debug_sizeof_persistent_page = sizeof(struct persistent_page);

	pidx = (uint8_t)PERSISTENT_PAGE_IDX;
	HalFlashRead(pidx, 0, buf, 4);
	HalFlashRead((pidx + 1), 0, buf2, 4);

	if (memcmp(buf2, PERSISTENT_MAGIC, 4) == 0) {
		if (memcmp(buf, PERSISTENT_MAGIC, 4) != 0) {
			ble_flash_page_erase(pidx);
			for (i = 0; i < 4; i++) {
				HalFlashRead((pidx + 1), (uint16_t)i * 256, (uint8_t *)buf32, 256);
				for (j = 0; j < 64; j++) {
					flash_word_unprotected_write((uint32_t *)((uint32_t)pidx * 1024 + (uint32_t)i * 256 + (uint32_t)j * 4), buf32[j]);
				}
			}
		}
		ble_flash_page_erase(pidx + 1);
	} else {
		if (memcmp(buf, PERSISTENT_MAGIC, 4) != 0) {
			// This is invoked before softdevice and radio
			ble_flash_page_erase(pidx);
			flash_word_unprotected_write((uint32_t *)((uint32_t)pidx * 1024), magic32);
			flash_word_unprotected_write((uint32_t *)((uint32_t)pidx * 1024 + 4), ido2Name1);
			flash_word_unprotected_write((uint32_t *)((uint32_t)pidx * 1024 + 8), ido2Name2);
		}
	}

	// Update boot count
	HalFlashRead(pidx, 24, buf, 16);
	boot_cnt = __persistent_mark_bit_map(buf, 16);

	// Write back
	for (i = 0; i < 4; i++) {
		tmp32 = ((uint32_t)buf[i * 4 + 3] << 24) | ((uint32_t)buf[i * 4 + 2] << 16) | ((uint32_t)buf[i * 4 + 1] << 8) | (uint32_t)buf[i * 4];
		flash_word_unprotected_write((uint32_t *)((uint32_t)pidx * 1024 + 24 + i * 4), tmp32);
	}
}
Exemple #4
0
/**@brief      This function erases flash pages that contain Bonding Information and System
 *             Attributes.
 *
 * @return     NRF_SUCCESS on success, otherwise an error code.
 */
static uint32_t flash_pages_erase(void)
{
    uint32_t err_code;
    
    err_code = ble_flash_page_erase(m_bondmngr_config.flash_page_num_bond);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    err_code = ble_flash_page_erase(m_bondmngr_config.flash_page_num_sys_attr);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
    
    return NRF_SUCCESS;
}
Exemple #5
0
static void bootloader_settings_save(bootloader_settings_t settings)
{
    const bootloader_settings_t * p_bootloader_settings;

    bootloader_util_settings_get(&p_bootloader_settings);

    // Save needed data for later use. 
    uint32_t settings_page = ((uint32_t) p_bootloader_settings) / NRF_FICR->CODEPAGESIZE;

    uint32_t num_of_words = sizeof(bootloader_settings_t) / sizeof(uint32_t);

    // Save bootloader settings.
    uint32_t err_code = ble_flash_page_erase(settings_page);
    APP_ERROR_CHECK(err_code);    
    err_code          = ble_flash_block_write((uint32_t *)p_bootloader_settings, 
                                              (uint32_t *)&settings, 
                                              num_of_words);
    APP_ERROR_CHECK(err_code);
}
Exemple #6
0
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;
}
uint32_t ble_central_bondmngr_store(ble_central_bondmngr_t * p_bm)
{
    uint32_t err_code;
    
    print_address(&bond_info.addr);
    
    err_code = ble_flash_page_erase(BLE_CENTRAL_BONDMNGR_PAGE_NUM);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
    
    printf("Writing %d b to %d\r\n", sizeof(bond_info)/sizeof(uint32_t), BLE_CENTRAL_BONDMNGR_PAGE_NUM);
    
    err_code = ble_flash_page_write(BLE_CENTRAL_BONDMNGR_PAGE_NUM, (uint32_t *) &bond_info, sizeof(bond_info)/sizeof(uint32_t));
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
    
    return NRF_SUCCESS;
}
Exemple #8
0
uint32_t ble_error_log_read(ble_error_log_data_t * error_log)
{
    uint8_t  error_log_size = CEIL_DIV(sizeof(ble_error_log_data_t), sizeof(uint32_t));
    uint32_t err_code       = NRF_SUCCESS;
    
    err_code = ble_flash_page_read(FLASH_PAGE_ERROR_LOG, (uint32_t *) error_log, &error_log_size);
    
    // If nothing is in flash; then return NRF_SUCCESS.
    if (err_code == NRF_ERROR_NOT_FOUND)
    {
        return NRF_SUCCESS;
    }

    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    if (!error_log->failure)
    {
        return NRF_SUCCESS;
    }

    nrf_gpio_pin_set(LOG_LED_PIN_NO); // Notify that a message exists in the log.

    while (error_log->failure && !m_ble_log_clear_flag)
    {
        // Put breakpoint, and read data, then log->failure=false; to continue in debug mode.
        // In application, define how to clear the error log, 
        // e.g. read button 6, if pressed, then clear log and continue.
    }
    
    nrf_gpio_pin_clear(LOG_LED_PIN_NO);
    err_code = ble_flash_page_erase(FLASH_PAGE_ERROR_LOG);

    return err_code;
}
Exemple #9
0
uint32_t ble_bondmngr_bonded_masters_store(void)
{
    uint32_t err_code;
    int      i;

    if (!m_is_bondmngr_initialized)
    {
        return NRF_ERROR_INVALID_STATE;
    }

    if (m_master.bond.master_handle != INVALID_MASTER_HANDLE)
    {
        // Fetch System Attributes from stack.
        uint16_t sys_attr_size = SYS_ATTR_BUFFER_MAX_LEN;
        
        err_code = sd_ble_gatts_sys_attr_get(m_conn_handle,
                                             m_master.sys_attr.sys_attr,
                                             &sys_attr_size);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
        
        m_master.sys_attr.master_handle = m_master.bond.master_handle;
        m_master.sys_attr.sys_attr_size = (uint16_t)sys_attr_size;
        
        // Update current master
        err_code = master_update();
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
    }

    // Save Bonding Information if changed
    if (bond_info_changed())
    {
        // Erase flash page
        err_code = ble_flash_page_erase(m_bondmngr_config.flash_page_num_bond);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
    
        // Store bond information for all masters
        m_bond_info_in_flash_count = 0;
        for (i = 0; i < m_masters_in_db_count; i++)
        {
            err_code = bond_info_store(&m_masters_db[i].bond);
            if (err_code != NRF_SUCCESS)
            {
                return err_code;
            }
        }
    }
    
    // Save System Attributes, if changed
    if (sys_attr_changed())
    {
        // Erase flash page
        err_code = ble_flash_page_erase(m_bondmngr_config.flash_page_num_sys_attr);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }

        // Store System Attributes for all masters
        m_sys_attr_in_flash_count = 0;
        for (i = 0; i < m_masters_in_db_count; i++)
        {
            err_code = sys_attr_store(&m_masters_db[i].sys_attr);
            if (err_code != NRF_SUCCESS)
            {
                return err_code;
            }
        }
    }
    
    m_conn_handle                   = BLE_CONN_HANDLE_INVALID;
    m_master.bond.master_handle     = INVALID_MASTER_HANDLE;
    m_master.sys_attr.master_handle = INVALID_MASTER_HANDLE;
    m_master.sys_attr.sys_attr_size = 0;
    
    return NRF_SUCCESS;
}
Exemple #10
0
uint32_t pstorage_update(pstorage_handle_t * p_dest,
                        uint8_t           * p_src,
                        pstorage_size_t     size,
                        pstorage_size_t     offset)
{

    uint32_t *p_swap_addr = (uint32_t *)PSTORAGE_SWAP_ADDR;
    uint32_t *p_page_addr1 =  (uint32_t *) PAGE_BASE_ADDR(p_dest->block_id + offset);
#ifdef SUPPORT_MODULES_LARGER_THAN_PAGE
    uint32_t *p_page_addr2 =  (uint32_t *) PAGE_BASE_ADDR(p_dest->block_id + offset + size-1);
#endif
    uint16_t head_word_count =  offset/sizeof(uint32_t);
    uint16_t body_word_count =  size/sizeof(uint32_t);
    uint16_t tail_word_count;
    uint32_t retval;


	VERIFY_MODULE_INITIALIZED();
    NULL_PARAM_CHECK(p_src);
    NULL_PARAM_CHECK(p_dest);
    MODULE_ID_RANGE_CHECK(p_dest);
    BLOCK_ID_RANGE_CHECK(p_dest);
    SIZE_CHECK(p_dest, size);
    OFFSET_CHECK(p_dest, offset, size);

    // Verify word alignment.
    if ((!is_word_aligned(p_src)) || (!is_word_aligned((void *)(uint32_t)offset)))
    {
        return NRF_ERROR_INVALID_ADDR;
    }
    // erase swap page
    (void) ble_flash_page_erase(PSTORAGE_SWAP_ADDR / BLE_FLASH_PAGE_SIZE);
#ifdef SUPPORT_MODULES_LARGER_THAN_PAGE
    if (p_page_addr1 == p_page_addr2)
    {
#endif
    	// tail is in the same page as head
        tail_word_count = BLE_FLASH_PAGE_SIZE/sizeof(uint32_t) - head_word_count - body_word_count;
    	// copy of the head
        if (head_word_count)
        {
        	retval = ble_flash_block_write(p_swap_addr, p_page_addr1, head_word_count );
        	if (retval != NRF_SUCCESS)
        	{
        		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
        		return retval;
        	}
        }
        // copy of the body
        retval = ble_flash_block_write(p_swap_addr+head_word_count, (uint32_t *)p_src, body_word_count);
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // copy of the tail
        if (tail_word_count)
        {
        	retval = ble_flash_block_write(p_swap_addr+head_word_count+body_word_count, p_page_addr1+head_word_count+body_word_count, tail_word_count );
        	if (retval != NRF_SUCCESS)
        	{
        		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
        		return retval;
        	}
        }
        // erase active page
        (void) ble_flash_page_erase((uint32_t)p_page_addr1 / BLE_FLASH_PAGE_SIZE);
        // restore updated page
        retval = ble_flash_block_write(p_page_addr1, p_swap_addr, BLE_FLASH_PAGE_SIZE/sizeof(uint32_t));
#ifdef SUPPORT_MODULES_LARGER_THAN_PAGE
    }
    else
    {
    	// tail is in NOT in the same page as head - need to swap twice
    	uint16_t body1_word_count =  BLE_FLASH_PAGE_SIZE/sizeof(uint32_t) - head_word_count;
    	uint16_t body2_word_count =  body_word_count - body1_word_count;
        tail_word_count = BLE_FLASH_PAGE_SIZE/sizeof(uint32_t) - body2_word_count;
        // copy head
        retval = ble_flash_block_write(p_swap_addr, p_page_addr1, head_word_count );
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // copy body1
        retval = ble_flash_block_write(p_swap_addr, (uint32_t *)p_src, body1_word_count );
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // erase active page
        (void) ble_flash_page_erase((uint32_t)p_page_addr1 / BLE_FLASH_PAGE_SIZE);
        // restore updated page1
        retval = ble_flash_block_write(p_page_addr1, p_swap_addr, BLE_FLASH_PAGE_SIZE/sizeof(uint32_t));
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // erase swap page
        (void) ble_flash_page_erase(PSTORAGE_SWAP_ADDR / BLE_FLASH_PAGE_SIZE);
        // copy body2
        retval = ble_flash_block_write(p_swap_addr, (uint32_t *)p_src + body1_word_count, body2_word_count );
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // copy tail
        retval = ble_flash_block_write(p_swap_addr, p_page_addr2+body2_word_count, tail_word_count );
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // erase active page
        (void) ble_flash_page_erase((uint32_t)p_page_addr2 / BLE_FLASH_PAGE_SIZE);
        // restore updated page2
        retval = ble_flash_block_write(p_page_addr2, p_swap_addr, BLE_FLASH_PAGE_SIZE/sizeof(uint32_t));
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
    }
#endif
    app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    return retval;

}