Example #1
0
/**@brief      Function for handling the Connection Security Update event received from the BLE
 *             stack.
 *
 * @param[in]  p_ble_evt   Event received from the BLE stack.
 */
static void on_sec_update(ble_gap_evt_conn_sec_update_t * p_sec_update)
{
    uint8_t security_mode  = p_sec_update->conn_sec.sec_mode.sm;
    uint8_t security_level = p_sec_update->conn_sec.sec_mode.lv;

    if (((security_mode == 1) && (security_level > 1)) ||
        ((security_mode == 2) && (security_level != 0)))
    {
        ENCRYPTION_STATUS_SET();

        uint32_t err_code = master_sys_attr_set(&m_master);

        if (err_code != NRF_SUCCESS)
        {
            m_bondmngr_config.error_handler(err_code);
        }
        else
        {
            m_sys_attr_loaded = true;
        }

        if (m_bondmngr_config.evt_handler != NULL)
        {
            ble_bondmngr_evt_t evt;

            evt.evt_type      = BLE_BONDMNGR_EVT_ENCRYPTED;
            evt.master_handle = m_master.bond.master_handle;
            evt.master_id     = m_master.bond.master_id_info.div;

            m_bondmngr_config.evt_handler(&evt);
        }
    }
}
Example #2
0
/**@brief      This function handles the connected event received from the BLE stack.
 *
 * @param[in]  p_ble_evt   Event received from the BLE stack.
 */
static void on_connect(ble_evt_t * p_ble_evt)
{
    m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
    
    m_master.bond.master_handle     = INVALID_MASTER_HANDLE;
    m_master.bond.master_addr       = p_ble_evt->evt.gap_evt.params.connected.peer_addr;
    m_master.sys_attr.sys_attr_size = 0;

    if (p_ble_evt->evt.gap_evt.params.connected.irk_match)
    {
        uint8_t irk_idx  = p_ble_evt->evt.gap_evt.params.connected.irk_match_idx;
        
        if ((irk_idx >= MAX_NUM_MASTER_WHITE_LIST) ||
            (m_whitelist_irk[irk_idx].master_handle >= BLE_BONDMNGR_MAX_BONDED_MASTERS))
        {
            m_bondmngr_config.error_handler(NRF_ERROR_INTERNAL);
        }
        else
        {
            m_master = m_masters_db[m_whitelist_irk[irk_idx].master_handle];
        }
    }
    else
    {
        int i;
        
        for (i = 0; i < m_addr_count; i++)
        {
            ble_gap_addr_t * p_cur_addr = m_whitelist_addr[i].p_addr;
            
            if (memcmp(p_cur_addr->addr, m_master.bond.master_addr.addr, BLE_GAP_ADDR_LEN) == 0)
            {
                m_master = m_masters_db[m_whitelist_addr[i].master_handle];
                break;
            }
        }
    }

    if (m_master.bond.master_handle != INVALID_MASTER_HANDLE)
    {
        uint32_t err_code = master_sys_attr_set(&m_master);
        if (err_code != NRF_SUCCESS)
        {
            m_bondmngr_config.error_handler(err_code);
        }
        
        if (m_bondmngr_config.evt_handler != NULL)
        {
            ble_bondmngr_evt_t evt;
            
            evt.evt_type      = BLE_BONDMNGR_EVT_CONN_TO_BONDED_MASTER;
            evt.master_handle = m_master.bond.master_handle;
            evt.master_id     = m_master.bond.master_id_info.div;
            
            m_bondmngr_config.evt_handler(&evt);
        }
    }
}
Example #3
0
/**@brief      This function handles the authentication status event related to a new master.
 *
 * @details    This function adds the new master to the database and stores the master's Bonding
 *             Information to flash. It also notifies the application when the new bond is created,
 *             and sets the System Attributes to prepare the stack for connection with the new
 *             master.
 *
 * @param[in]  p_auth_status   New authentication status.
 *
 * @return     NRF_SUCCESS on success, otherwise an error code.
 */
static uint32_t on_auth_status_from_new_master(ble_gap_evt_auth_status_t * p_auth_status)
{
    uint32_t err_code;
    
    if (m_masters_in_db_count >= BLE_BONDMNGR_MAX_BONDED_MASTERS)
    {
        return NRF_ERROR_NO_MEM;
    }

    // Update master
    m_master.bond.auth_status        = *p_auth_status;
    m_master.bond.master_id_info.div = p_auth_status->periph_keys.enc_info.div;
    m_master.sys_attr.sys_attr_size  = 0;

    // Add new master to database
    m_master.bond.master_handle           = m_masters_in_db_count;
    m_masters_db[m_masters_in_db_count++] = m_master;
    
    update_whitelist();

    // Clear System Attributes
    err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
    
    // Write new master's Bonding Information to flash
    err_code = bond_info_store(&m_master.bond);
    if ((err_code == NRF_ERROR_NO_MEM) && (m_bondmngr_config.evt_handler != NULL))
    {
        ble_bondmngr_evt_t evt;
        
        evt.evt_type      = BLE_BONDMNGR_EVT_BOND_FLASH_FULL;
        evt.master_handle = m_master.bond.master_handle;
        evt.master_id     = m_master.bond.master_id_info.div;
        
        m_bondmngr_config.evt_handler(&evt);
    }
    else if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
    
    // Pass event to application
    if (m_bondmngr_config.evt_handler != NULL)
    {
        ble_bondmngr_evt_t evt;
        
        evt.evt_type      = BLE_BONDMNGR_EVT_NEW_BOND;
        evt.master_handle = m_master.bond.master_handle;
        evt.master_id     = m_master.bond.master_id_info.div;
        
        m_bondmngr_config.evt_handler(&evt);
    }
    
    return NRF_SUCCESS;
}
Example #4
0
/**@brief      Function for handling the 'System Attributes Missing' event received from the
 *             SoftDevice.
 *
 * @param[in]  p_ble_evt   Event received from the BLE stack.
 */
static void on_sys_attr_missing(ble_evt_t * p_ble_evt)
{
    uint32_t err_code;

    if (
        (m_master.bond.master_handle == INVALID_MASTER_HANDLE) ||
        !ENCRYPTION_STATUS_GET()                               ||
        BONDING_IN_PROGRESS_STATUS_GET()
       )
    {
        err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0);
    }
    else
    {
        // Current master is valid, use its data. Set the corresponding sys_attr.
        err_code = master_sys_attr_set(&m_master);
        if (err_code == NRF_SUCCESS)
        {
            // Set System Attributes loaded status variable.
            m_sys_attr_loaded = true;
        }
    }

    if (err_code != NRF_SUCCESS)
    {
        m_bondmngr_config.error_handler(err_code);
    }
}
Example #5
0
/**@brief      Function for handling the Security Info Request event received from the BLE stack.
 *
 * @param[in]  p_ble_evt   Event received from the BLE stack.
 */
static void on_sec_info_request(ble_evt_t * p_ble_evt)
{
    uint32_t err_code;

    err_code = master_find_in_db(p_ble_evt->evt.gap_evt.params.sec_info_request.div);
    if (err_code == NRF_SUCCESS)
    {
        // Bond information has been found and loaded for security procedures. Reflect this in the
        // status variable
        m_bond_loaded = true;

        // Master found in the list of bonded master. Use the encryption info for this master.
        err_code = sd_ble_gap_sec_info_reply(m_conn_handle,
                                             &m_master.bond.auth_status.periph_keys.enc_info,
                                             NULL);
        if (err_code != NRF_SUCCESS)
        {
            m_bondmngr_config.error_handler(err_code);
        }

        // Do not set the sys_attr yet, should be set only when sec_update is successful.
    }
    else if (err_code == NRF_ERROR_NOT_FOUND)
    {
        m_master.bond.master_id_info = p_ble_evt->evt.gap_evt.params.sec_info_request;

        // New master.
        err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL);
        if (err_code != NRF_SUCCESS)
        {
            m_bondmngr_config.error_handler(err_code);
        }

        // Initialize the sys_attr.
        err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0);
    }

    if (err_code != NRF_SUCCESS)
    {
        m_bondmngr_config.error_handler(err_code);
    }
}
Example #6
0
/**@brief      This function handles the new authentication status event, received from the
 *             SoftDevice, related to an already bonded master.
 *
 * @details    This function also writes the updated Bonding Information to flash and notifies the
 *             application.
 *
 * @param[in]  p_auth_status   Updated authentication status.
 */
static void auth_status_update(ble_gap_evt_auth_status_t * p_auth_status)
{
    if (!auth_status_equal(&m_master.bond.auth_status, p_auth_status))
    {
        uint32_t err_code;

        // Authentication status changed, update Bonding Information
        m_master.bond.auth_status        = *p_auth_status;
        m_master.bond.master_id_info.div = p_auth_status->periph_keys.enc_info.div;
        
        // Write updated Bonding Information to flash
        err_code = bond_info_store(&m_master.bond);
        if ((err_code == NRF_ERROR_NO_MEM) && (m_bondmngr_config.evt_handler != NULL))
        {
            ble_bondmngr_evt_t evt;
            
            evt.evt_type      = BLE_BONDMNGR_EVT_BOND_FLASH_FULL;
            evt.master_handle = m_master.bond.master_handle;
            evt.master_id     = m_master.bond.master_id_info.div;
            
            m_bondmngr_config.evt_handler(&evt);
        }
        else if (err_code != NRF_SUCCESS)
        {
            m_bondmngr_config.error_handler(err_code);
        }
        
        // Pass event to the application
        if (m_bondmngr_config.evt_handler != NULL)
        {
            ble_bondmngr_evt_t evt;
        
            evt.evt_type      = BLE_BONDMNGR_EVT_AUTH_STATUS_UPDATED;
            evt.master_handle = m_master.bond.master_handle;
            evt.master_id     = m_master.bond.master_id_info.div;
            
            m_bondmngr_config.evt_handler(&evt);
        }
    }
}
Example #7
0
/**@brief      This function handles the Security Info Request event received from the BLE stack.
 *
 * @param[in]  p_ble_evt   Event received from the BLE stack.
 */
static void on_sec_info_request(ble_evt_t * p_ble_evt)
{
    uint32_t err_code;

    m_master.bond.master_id_info = p_ble_evt->evt.gap_evt.params.sec_info_request;
    
    err_code = master_find_in_db(m_master.bond.master_id_info.div);
    if (err_code == NRF_SUCCESS)
    {
        // Master found in the list of bonded master. Use the encryption info for this master.
        err_code = sd_ble_gap_sec_info_reply(m_conn_handle, 
                                             &m_master.bond.auth_status.periph_keys.enc_info,
                                             NULL);
        if (err_code != NRF_SUCCESS)
        {
            m_bondmngr_config.error_handler(err_code);
        }
        
        // In addition set the corresponding sys_attr
        err_code = master_sys_attr_set(&m_master);
    }
    else if (err_code == NRF_ERROR_NOT_FOUND)
    {
        // New master
        err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL);
        if (err_code != NRF_SUCCESS)
        {
            m_bondmngr_config.error_handler(err_code);
        }
        
        // Initialize the sys_attr
        err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0);
    }
    
    if (err_code != NRF_SUCCESS)
    {
        m_bondmngr_config.error_handler(err_code);
    }
}
Example #8
0
void ble_bondmngr_on_ble_evt(ble_evt_t * p_ble_evt)
{
    if (!m_is_bondmngr_initialized)
    {
        m_bondmngr_config.error_handler(NRF_ERROR_INVALID_STATE);
    }

    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            on_connect(p_ble_evt);
            break;

        // NOTE: All actions to be taken on the Disconnected event are performed in
        //       ble_bondmngr_bonded_masters_store(). This function must be called from the
        //       Disconnected handler of the application before advertising is restarted (to make
        //       sure the flash blocks are cleared while the radio is inactive).
        case BLE_GAP_EVT_DISCONNECTED:
            SECURITY_STATUS_RESET();
            break;

        case BLE_GATTS_EVT_SYS_ATTR_MISSING:
            on_sys_attr_missing(p_ble_evt);
            break;

        case BLE_GAP_EVT_AUTH_STATUS:
            on_auth_status(&p_ble_evt->evt.gap_evt.params.auth_status);
            break;

        case BLE_GAP_EVT_SEC_INFO_REQUEST:
            on_sec_info_request(p_ble_evt);
            break;

        case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
            on_sec_param_request(&p_ble_evt->evt.gap_evt.params.sec_params_request);
            break;

        case BLE_GAP_EVT_CONN_SEC_UPDATE:
            on_sec_update(&p_ble_evt->evt.gap_evt.params.conn_sec_update);
            break;

        default:
            break;
    }
}
Example #9
0
/**@brief      This function handles the 'System Attributes Missing' event received from the
 *             SoftDevice.
 *
 * @param[in]  p_ble_evt   Event received from the BLE stack.
 */
static void on_sys_attr_missing(ble_evt_t * p_ble_evt)
{
    uint32_t err_code;
    
    if (m_master.bond.master_handle == INVALID_MASTER_HANDLE)
    {
        err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0);
    }
    else
    {
        // Current master is valid, use its data. Set the corresponding sys_attr.
        err_code = master_sys_attr_set(&m_master);
    }

    if (err_code != NRF_SUCCESS)
    {
        m_bondmngr_config.error_handler(err_code);
    }
}
/**@brief Connection Security Update event handler.
 *
 * @param[in]  p_ble_evt   Event received from the BLE stack.
 */
static void on_sec_update(ble_gap_evt_conn_sec_update_t * p_sec_update)
{
    uint8_t security_mode  = p_sec_update->conn_sec.sec_mode.sm;
    uint8_t security_level = p_sec_update->conn_sec.sec_mode.lv;
    
    if (((security_mode == 1) && (security_level > 1)) || 
        ((security_mode == 2) && (security_level != 0)))
    {
        if (m_bondmngr_config.evt_handler != NULL)
        {
            ble_bondmngr_evt_t evt;
            
            evt.evt_type      = BLE_BONDMNGR_EVT_ENCRYPTED;
            evt.master_handle = m_master.bond.master_handle;
            
            m_bondmngr_config.evt_handler(&evt);
        }
    }
}
Example #11
0
/**@brief      Function for handling the Authentication Status event received from the BLE stack.
 *
 * @param[in]  p_ble_evt   Event received from the BLE stack.
 */
static void on_auth_status(ble_gap_evt_auth_status_t * p_auth_status)
{
    if (p_auth_status->auth_status != BLE_GAP_SEC_STATUS_SUCCESS)
    {
        return;
    }

    // Verify if its pairing and not bonding
    if (!ENCRYPTION_STATUS_GET())
    {
        return;
    }

    if (m_master.bond.master_handle == INVALID_MASTER_HANDLE)
    {
        uint32_t err_code = master_find_in_db(p_auth_status->periph_keys.enc_info.div);

        if (err_code == NRF_SUCCESS)
        {
            // Possible DIV Collision indicate error to application,
            // not storing the new LTK
            err_code = NRF_ERROR_FORBIDDEN;
        }
        else
        {
            // Add the new device to data base
            err_code = on_auth_status_from_new_master(p_auth_status);
        }

        if (err_code != NRF_SUCCESS)
        {
            m_bondmngr_config.error_handler(err_code);
        }
    }
    else
    {
        m_bond_loaded = true;

        // Receiving a auth status again when already in have existing information!
        auth_status_update(p_auth_status);
    }
}
Example #12
0
/**@brief      This function handles the Authentication Status event received from the BLE stack.
 *
 * @param[in]  p_ble_evt   Event received from the BLE stack.
 */
static void on_auth_status(ble_gap_evt_auth_status_t * p_auth_status)
{
    if (p_auth_status->auth_status != BLE_GAP_SEC_STATUS_SUCCESS)
    {
        return;
    }
    
    if (m_master.bond.master_handle == INVALID_MASTER_HANDLE)
    {
        uint32_t err_code = master_find_in_db(p_auth_status->periph_keys.enc_info.div);
        
        switch (err_code)
        {
            case NRF_SUCCESS:
                // Master found in the list of bonded masters. Set the corresponding sys_attr.
                err_code = master_sys_attr_set(&m_master);
                break;
                
            case NRF_ERROR_NOT_FOUND:
                // Master not found, add new master
                err_code = on_auth_status_from_new_master(p_auth_status);
                break;
                
            default:
                break;
        }
        
        if (err_code != NRF_SUCCESS)
        {
            m_bondmngr_config.error_handler(err_code);
        }
    }
    else
    {
        auth_status_update(p_auth_status);
    }
}