static void events_send_from_err_code(uint16_t conn_handle, ret_code_t err_code)
{
     if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY))
     {
        sm_evt_t evt =
        {
            .conn_handle = conn_handle,
            .params = {.error_unexpected = {
                .error = err_code
            }}
        };
        if (err_code == NRF_ERROR_TIMEOUT)
        {
            evt.evt_id = SM_EVT_ERROR_SMP_TIMEOUT;
        }
        else if (err_code == NRF_ERROR_NO_MEM)
        {
            evt.evt_id = SM_EVT_ERROR_NO_MEM;
        }
        else
        {
            evt.evt_id = SM_EVT_ERROR_UNEXPECTED;
        }
        evt_send(&evt);
     }
Example #2
0
ret_code_t pm_peers_delete(void)
{
    VERIFY_MODULE_INITIALIZED();

    m_deleting_all = true;

    pm_peer_id_t current_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID);

    if (current_peer_id == PM_PEER_ID_INVALID)
    {
        // No peers bonded.
        m_deleting_all = false;

        pm_evt_t pm_delete_all_evt;
        memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t));
        pm_delete_all_evt.evt_id      = PM_EVT_PEERS_DELETE_SUCCEEDED;
        pm_delete_all_evt.peer_id     = PM_PEER_ID_INVALID;
        pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID;

        evt_send(&pm_delete_all_evt);
    }

    while (current_peer_id != PM_PEER_ID_INVALID)
    {
        ret_code_t err_code = pm_peer_delete(current_peer_id);
        if (err_code != NRF_SUCCESS)
        {
            return NRF_ERROR_INTERNAL;
        }

        current_peer_id = pdb_next_peer_id_get(current_peer_id);
    }

    return NRF_SUCCESS;
}
Example #3
0
ret_code_t pm_peer_rank_highest(pm_peer_id_t peer_id)
{
    VERIFY_MODULE_INITIALIZED();

    ret_code_t err_code;
    //lint -save -e65 -e64
    pm_peer_data_flash_t peer_data   = {.length_words = BYTES_TO_WORDS(sizeof(m_current_highest_peer_rank)),
                                        .data_id      = PM_PEER_DATA_ID_PEER_RANK,
                                        .p_peer_rank  = &m_current_highest_peer_rank};
    //lint -restore


    if (!m_peer_rank_initialized)
    {
        rank_init();
    }

    if (!m_peer_rank_initialized || (m_peer_rank_token != PM_STORE_TOKEN_INVALID))
    {
        err_code = NRF_ERROR_BUSY;
    }
    else
    {
        if ((peer_id == m_highest_ranked_peer) && (m_current_highest_peer_rank > 0))
        {
            pm_evt_t pm_evt;

            // The reported peer is already regarded as highest (provided it has an index at all)
            err_code = NRF_SUCCESS;

            memset(&pm_evt, 0, sizeof(pm_evt));
            pm_evt.evt_id      = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
            pm_evt.conn_handle = im_conn_handle_get(peer_id);
            pm_evt.peer_id     = peer_id;
            pm_evt.params.peer_data_update_succeeded.data_id       = PM_PEER_DATA_ID_PEER_RANK;
            pm_evt.params.peer_data_update_succeeded.action        = PM_PEER_DATA_OP_UPDATE;
            pm_evt.params.peer_data_update_succeeded.token         = PM_STORE_TOKEN_INVALID;
            pm_evt.params.peer_data_update_succeeded.flash_changed = false;

            evt_send(&pm_evt);
        }
        else
        {
            m_current_highest_peer_rank += 1;
            err_code = pdb_raw_store(peer_id, &peer_data, &m_peer_rank_token);
            if (err_code != NRF_SUCCESS)
            {
                m_peer_rank_token    = PM_STORE_TOKEN_INVALID;
                m_current_highest_peer_rank -= 1;
                {
                if ((err_code != NRF_ERROR_BUSY) && (err_code != NRF_ERROR_STORAGE_FULL))
                    err_code = NRF_ERROR_INTERNAL;
                }
            }
        }
    }
    return err_code;
}
Example #4
0
/**@brief Event handler for events from the Peer Database module.
 *        This function is extern in Peer Database.
 *
 * @param[in]  p_event The event that has happend with peer id and flags.
 */
void im_pdb_evt_handler(pdb_evt_t const * p_event)
{
    ret_code_t           ret;
    pm_peer_id_t         peer_id;
    pm_peer_data_flash_t peer_data;
    pm_peer_data_flash_t peer_data_duplicate;

    NRF_PM_DEBUG_CHECK(m_module_initialized);
    NRF_PM_DEBUG_CHECK(p_event != NULL);

    if ((p_event->evt_id  != PDB_EVT_WRITE_BUF_STORED) ||
        (p_event->data_id != PM_PEER_DATA_ID_BONDING))
    {
        return;
    }

    // If new data about peer id has been stored it is compared to other peers peer ids in
    // search of duplicates.

    ret = pdb_peer_data_ptr_get(p_event->peer_id, PM_PEER_DATA_ID_BONDING, &peer_data);

    if (ret != NRF_SUCCESS)
    {
        // @note emdi: this shouldn't happen, since the data was just stored, right?
        NRF_PM_DEBUG_CHECK(false);
        return;
    }

    pds_peer_data_iterate_prepare();

    while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data_duplicate))
    {
        if (p_event->peer_id == peer_id)
        {
            // Skip the iteration if the bonding data retrieved is for a peer
            // with the same ID as the one contained in the event.
            continue;
        }

        if (im_is_duplicate_bonding_data(peer_data.p_bonding_data,
                                         peer_data_duplicate.p_bonding_data))
        {
            im_evt_t im_evt;
            im_evt.conn_handle                   = im_conn_handle_get(p_event->peer_id);
            im_evt.evt_id                        = IM_EVT_DUPLICATE_ID;
            im_evt.params.duplicate_id.peer_id_1 = p_event->peer_id;
            im_evt.params.duplicate_id.peer_id_2 = peer_id;
            evt_send(&im_evt);
            break;
        }
    }
}
Example #5
0
void im_evt_handler(im_evt_t const * p_evt)
{
    pm_evt_t pm_evt;

    switch (p_evt->evt_id)
    {
        case IM_EVT_DUPLICATE_ID:
            // Delete the duplicate data to free space and avoid finding old data when scanning in the future
            pm_peer_delete(p_evt->params.duplicate_id.peer_id_2);
            break;

        case IM_EVT_BONDED_PEER_CONNECTED:
            ble_conn_state_user_flag_set(p_evt->conn_handle, m_pm.bonding_flag_id, true);
            memset(&pm_evt, 0, sizeof(pm_evt_t));
            pm_evt.conn_handle = p_evt->conn_handle;
            pm_evt.peer_id = im_peer_id_get_by_conn_handle(p_evt->conn_handle);
            pm_evt.evt_id = PM_EVT_BONDED_PEER_CONNECTED;
            evt_send(&pm_evt);
            break;
    }
}
Example #6
0
/**@brief Event handler for events from the peer_database module.
 *
 * @param[in]  p_event The event that has happend with peer id and flags.
 */
static void pdb_evt_handler(pdb_evt_t const * p_event)
{
    ret_code_t err_code;
    if ((p_event != NULL) && (p_event->evt_id == PDB_EVT_WRITE_BUF_STORED))
    {
        // If new data about peer id has been stored it is compared to other peers peer ids in
        // search of duplicates.
        if (p_event->data_id == PM_PEER_DATA_ID_BONDING)
        {
            pm_peer_data_flash_t written_data;
            err_code = pdb_read_buf_get(p_event->peer_id, PM_PEER_DATA_ID_BONDING, &written_data, NULL);
            if (err_code == NRF_SUCCESS)
            {
                pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID);
                while (compared_peer_id != PM_PEER_ID_INVALID)
                {
                    pm_peer_data_flash_t compared_data;
                    err_code = pdb_read_buf_get(compared_peer_id,
                                                PM_PEER_DATA_ID_BONDING,
                                                &compared_data,
                                                NULL);
                    if ( err_code == NRF_SUCCESS &&
                            p_event->peer_id != compared_peer_id &&
                            is_duplicate_bonding_data(written_data.p_bonding_data,
                                                      compared_data.p_bonding_data)
                       )
                    {
                        im_evt_t im_evt;
                        im_evt.conn_handle = im_conn_handle_get(p_event->peer_id);
                        im_evt.evt_id = IM_EVT_DUPLICATE_ID;
                        im_evt.params.duplicate_id.peer_id_1 = p_event->peer_id;
                        im_evt.params.duplicate_id.peer_id_2 = compared_peer_id;
                        evt_send(&im_evt);
                    }
                    compared_peer_id = pdb_next_peer_id_get(compared_peer_id);
                }
            }
        }
    }
}
Example #7
0
void im_ble_evt_handler(ble_evt_t * ble_evt)
{
    ble_gap_evt_t gap_evt;
    pm_peer_id_t  bonded_matching_peer_id;

    NRF_PM_DEBUG_CHECK(m_module_initialized);

    if (ble_evt->header.evt_id != BLE_GAP_EVT_CONNECTED)
    {
        // Nothing to do.
        return;
    }

    gap_evt                 = ble_evt->evt.gap_evt;
    bonded_matching_peer_id = PM_PEER_ID_INVALID;

    if (   gap_evt.params.connected.peer_addr.addr_type
        != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE)
    {
        /* Search the database for bonding data matching the one that triggered the event.
         * Public and static addresses can be matched on address alone, while resolvable
         * random addresses can be resolved agains known IRKs. Non-resolvable random addresses
         * are never matching because they are not longterm form of identification.
         */

        pm_peer_id_t         peer_id;
        pm_peer_data_flash_t peer_data;

        pds_peer_data_iterate_prepare();

        switch (gap_evt.params.connected.peer_addr.addr_type)
        {
            case BLE_GAP_ADDR_TYPE_PUBLIC:
            case BLE_GAP_ADDR_TYPE_RANDOM_STATIC:
            {
                while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data))
                {
                    if (addr_compare(&gap_evt.params.connected.peer_addr,
                                     &peer_data.p_bonding_data->peer_id.id_addr_info))
                    {
                        bonded_matching_peer_id = peer_id;
                        break;
                    }
                }
            }
            break;

            case BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE:
            {
                while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data))
                {
                    if (im_address_resolve(&gap_evt.params.connected.peer_addr,
                                           &peer_data.p_bonding_data->peer_id.id_info))
                    {
                        bonded_matching_peer_id = peer_id;
                        break;
                    }
                }
            }
            break;

            default:
                NRF_PM_DEBUG_CHECK(false);
                break;
        }
    }

    uint8_t new_index = new_connection(gap_evt.conn_handle,
                                       &gap_evt.params.connected.peer_addr);
    UNUSED_VARIABLE(new_index);

    if (bonded_matching_peer_id != PM_PEER_ID_INVALID)
    {
        im_new_peer_id(gap_evt.conn_handle, bonded_matching_peer_id);

        // Send a bonded peer event
        im_evt_t im_evt;
        im_evt.conn_handle = gap_evt.conn_handle;
        im_evt.evt_id      = IM_EVT_BONDED_PEER_CONNECTED;
        evt_send(&im_evt);
    }
}
Example #8
0
__IRAM_CODE void btn_processPress(int val)
{
    int btn;
    struct evt_t evt;

    for(btn=0;btn<NB_BUTTONS;btn++)
    {
        if(BTN_NOT_PRESSED(val,btn)) /* the btn is NOT pressed */
        {
            nb_pressed[btn]=0;   /* reset nb_pressed */
            mx_press[btn] = current_repeatParam->init_delay;
            press_step[btn] = 0;
            /*if(btn==BTN_OFF)
                nb_off_press=0;   */ /* if off btn released -> reset nb_off_press */
        }
        else            /* the btn i is pressed */
        {    
            
            /*if(btn==BTN_OFF)  */  /* OFF btn pressed => check if we have to halt */
            /*{
                nb_off_press++;
                if(nb_off_press>MAX_OFF)
                {
                    printk("[OFF button] => halt\n");
                    halt_device();                    
                }
            }*/

            if(nb_pressed[btn]==0)
            {
#ifdef HAVE_FM_REMOTE
                if(!inHold)
                {
#endif
                    switch(press_step[btn])
                    {
                        case 0:
                            press_step[btn] = 1;
                            nb_pressed[btn] = current_repeatParam->init_delay;
                            break;
                        case 1:
                            press_step[btn] = 2;
                            nb_pressed[btn] = current_repeatParam->second_delay;
                            mx_press[btn] = current_repeatParam->second_delay;
                            break;
                        case 2:
                            mx_press[btn] -= current_repeatParam->dec_value;
                            if(mx_press[btn]<current_repeatParam->min_delay)
                                mx_press[btn]=current_repeatParam->min_delay;
                            nb_pressed[btn] = mx_press[btn];
                            break;
                        default:
                            press_step[btn] = 0;
                            mx_press[btn] = current_repeatParam->init_delay;
                    }
#if 0
                    if(lcd_get_state()==0)
                    {
                        /* the lcd is off => turn on and discard the event */
                        lcd_keyPress();
                        break;
                    }
                    else
                        lcd_launchTimer(); /* postpone the lcd timer */
                    halt_launchTimer(); /* postpone the poweroff timer */
#endif

                    if(!con_screenIsVisible())
                    {
                      if (val&BTMASK_F1 && btn+1==BTN_ON) con_screenSwitch();
                      
                      // post the event
                      evt.evt=btn+1;
                      evt.evt_class=BTN_CLASS;
                      evt.data=(void*)mx_press[btn];
                      evt_send(&evt);
                    }
                    else
                    {
                        switch(btn+1)
                        {
                            case BTN_ON:
                                con_screenSwitch();
                                break;
                            case BTN_OFF:
                                con_clear();
                                break;
                            case BTN_UP:
                                con_screenScroll(-1);
                                break;
                            case BTN_DOWN:
                                con_screenScroll(1);
                                break;
                        }
                    }


                    //printk("BTN %d pressed\n",btn);
#ifdef HAVE_FM_REMOTE
                }
                else
                {
                    //FM_putTmpText("** HOLD **",30);
                    printk("** HOLD **\n");
                }
#endif
            }
            else
                nb_pressed[btn]--;
        }
    }
}
Example #9
0
/**@brief Event handler for events from the Peer Database module.
 *        This handler is extern in the Peer Database module.
 *
 * @param[in]  p_pdb_evt  The incoming Peer Database event.
 */
void pm_pdb_evt_handler(pdb_evt_t const * p_pdb_evt)
{
    bool send_evt = true;
    pm_evt_t pm_evt;

    memset(&pm_evt, 0, sizeof(pm_evt_t));
    pm_evt.peer_id = p_pdb_evt->peer_id;
    pm_evt.conn_handle = im_conn_handle_get(pm_evt.peer_id);

    switch (p_pdb_evt->evt_id)
    {
        case PDB_EVT_WRITE_BUF_STORED:
            pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
            pm_evt.params.peer_data_update_succeeded.data_id       = p_pdb_evt->data_id;
            pm_evt.params.peer_data_update_succeeded.action        = PM_PEER_DATA_OP_UPDATE;
            pm_evt.params.peer_data_update_succeeded.token         = PM_STORE_TOKEN_INVALID;
            pm_evt.params.peer_data_update_succeeded.flash_changed = true;
            break;

        case PDB_EVT_RAW_STORED:
            pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
            pm_evt.params.peer_data_update_succeeded.data_id = p_pdb_evt->data_id;
            pm_evt.params.peer_data_update_succeeded.action  = PM_PEER_DATA_OP_UPDATE;
            pm_evt.params.peer_data_update_succeeded.token
                                            = p_pdb_evt->params.raw_stored_evt.store_token;
            pm_evt.params.peer_data_update_succeeded.flash_changed = true;

            if (    (m_peer_rank_token != PM_STORE_TOKEN_INVALID)
                && (m_peer_rank_token == p_pdb_evt->params.raw_stored_evt.store_token))
            {
                m_peer_rank_token     = PM_STORE_TOKEN_INVALID;
                m_highest_ranked_peer = pm_evt.peer_id;

                pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID;
            }
            break;

        case PDB_EVT_RAW_STORE_FAILED:
            pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED;
            pm_evt.params.peer_data_update_failed.data_id = p_pdb_evt->data_id;
            pm_evt.params.peer_data_update_failed.action  = PM_PEER_DATA_OP_UPDATE;
            pm_evt.params.peer_data_update_failed.token
                                            = p_pdb_evt->params.error_raw_store_evt.store_token;
            pm_evt.params.peer_data_update_failed.error
                                            = p_pdb_evt->params.error_raw_store_evt.err_code;

            if (    (m_peer_rank_token != PM_STORE_TOKEN_INVALID)
                && (m_peer_rank_token == p_pdb_evt->params.raw_stored_evt.store_token))
            {
                m_peer_rank_token            = PM_STORE_TOKEN_INVALID;
                m_current_highest_peer_rank -= 1;

                pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID;
            }
            break;

        case PDB_EVT_CLEARED:
            pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
            pm_evt.params.peer_data_update_succeeded.data_id = p_pdb_evt->data_id;
            pm_evt.params.peer_data_update_succeeded.action  = PM_PEER_DATA_OP_DELETE;
            pm_evt.params.peer_data_update_succeeded.token   = PM_STORE_TOKEN_INVALID;
            break;

        case PDB_EVT_CLEAR_FAILED:
            pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED;
            pm_evt.params.peer_data_update_failed.data_id = p_pdb_evt->data_id;
            pm_evt.params.peer_data_update_failed.action  = PM_PEER_DATA_OP_DELETE;
            pm_evt.params.peer_data_update_failed.error
                                                    = p_pdb_evt->params.clear_failed_evt.err_code;
            break;

        case PDB_EVT_PEER_FREED:
            pm_evt.evt_id = PM_EVT_PEER_DELETE_SUCCEEDED;
            // Check that no peers marked for deletion are left.
            if (m_deleting_all
                && (pdb_next_peer_id_get(PM_PEER_ID_INVALID) == PM_PEER_ID_INVALID)
                && (pdb_next_deleted_peer_id_get(PM_PEER_ID_INVALID) == PM_PEER_ID_INVALID))
            {
                // pm_peers_delete() has been called and this is the last peer to be deleted.
                m_deleting_all = false;

                pm_evt_t pm_delete_all_evt;
                memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t));
                pm_delete_all_evt.evt_id      = PM_EVT_PEERS_DELETE_SUCCEEDED;
                pm_delete_all_evt.peer_id     = PM_PEER_ID_INVALID;
                pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID;

                evt_send(&pm_delete_all_evt);
            }
            break;

        case PDB_EVT_PEER_FREE_FAILED:
            pm_evt.evt_id = PM_EVT_PEER_DELETE_FAILED;
            pm_evt.params.peer_delete_failed.error
                                                = p_pdb_evt->params.peer_free_failed_evt.err_code;
            if (m_deleting_all)
            {
                // pm_peers_delete() has been called and has thus failed.

                m_deleting_all = false;

                pm_evt_t pm_delete_all_evt;
                memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t));
                pm_delete_all_evt.evt_id      = PM_EVT_PEERS_DELETE_FAILED;
                pm_delete_all_evt.peer_id     = PM_PEER_ID_INVALID;
                pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID;
                pm_delete_all_evt.params.peers_delete_failed_evt.error
                                              = p_pdb_evt->params.peer_free_failed_evt.err_code;

                evt_send(&pm_delete_all_evt);
            }
            break;

        case PDB_EVT_COMPRESSED:
            send_evt = false;
            // Do nothing
            break;

        case PDB_EVT_ERROR_NO_MEM:
            pm_evt.evt_id = PM_EVT_STORAGE_FULL;
            break;

        case PDB_EVT_ERROR_UNEXPECTED:
            pm_evt.evt_id = PM_EVT_ERROR_UNEXPECTED;
            break;

        default:
            send_evt = false;
            break;
    }

    if (send_evt)
    {
        evt_send(&pm_evt);
    }
}
Example #10
0
/**@brief Event handler for events from the GATT Cache Manager module.
 *        This handler is extern in GATT Cache Manager.
 *
 * @param[in]  p_gcm_evt  The incoming GATT Cache Manager event.
 */
void pm_gcm_evt_handler(gcm_evt_t const * p_gcm_evt)
{
    bool send_evt = true;
    pm_evt_t pm_evt;

    memset(&pm_evt, 0, sizeof(pm_evt_t));
    pm_evt.peer_id = p_gcm_evt->peer_id;
    pm_evt.conn_handle = im_conn_handle_get(pm_evt.peer_id);

    switch (p_gcm_evt->evt_id)
    {
        case GCM_EVT_LOCAL_DB_CACHE_STORED:
            pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
            pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE;
            pm_evt.params.peer_data_update_succeeded.data_id =  PM_PEER_DATA_ID_GATT_LOCAL;
            break;

        case GCM_EVT_LOCAL_DB_CACHE_UPDATED:
            pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
            pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE;
            pm_evt.params.peer_data_update_succeeded.data_id =  PM_PEER_DATA_ID_GATT_LOCAL;
            break;

        case GCM_EVT_LOCAL_DB_CACHE_APPLIED:
            pm_evt.evt_id = PM_EVT_LOCAL_DB_CACHE_APPLIED;
            break;

        case GCM_EVT_ERROR_LOCAL_DB_CACHE_APPLY:
            pm_evt.evt_id = PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED;
            break;

        case GCM_EVT_REMOTE_DB_CACHE_UPDATED:
            pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
            pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE;
            pm_evt.params.peer_data_update_succeeded.data_id =  PM_PEER_DATA_ID_GATT_REMOTE;
            break;

        case GCM_EVT_SERVICE_CHANGED_IND_SENT:
            pm_evt.evt_id = PM_EVT_SERVICE_CHANGED_IND_SENT;
            break;

        case GCM_EVT_SERVICE_CHANGED_IND_CONFIRMED:
            pm_evt.evt_id = PM_EVT_SERVICE_CHANGED_IND_CONFIRMED;
            break;

        case GCM_EVT_ERROR_DATA_SIZE:
            send_evt = false;
            break;

        case GCM_EVT_ERROR_STORAGE_FULL:
            pm_evt.evt_id = PM_EVT_STORAGE_FULL;
            break;

        case GCM_EVT_ERROR_UNEXPECTED:
            pm_evt.evt_id = PM_EVT_ERROR_UNEXPECTED;
            pm_evt.params.error_unexpected.error = p_gcm_evt->params.error_unexpected.error;
            pm_evt.conn_handle = p_gcm_evt->params.error_unexpected.conn_handle;
            break;
    }

    if (send_evt)
    {
        evt_send(&pm_evt);
    }
}
Example #11
0
/**@brief Event handler for events from the Security Manager module.
 *        This handler is extern in the Security Manager module.
 *
 * @param[in]  p_sm_evt  The incoming Security Manager event.
 */
void pm_sm_evt_handler(sm_evt_t const * p_sm_evt)
{
    bool find_peer_id = true;
    bool send_evt     = true;
    pm_evt_t pm_evt;
    memset(&pm_evt, 0, sizeof(pm_evt_t));
    pm_evt.conn_handle = p_sm_evt->conn_handle;

    switch (p_sm_evt->evt_id)
    {
        case SM_EVT_SLAVE_SECURITY_REQ:
            find_peer_id = false;
            send_evt     = false;
            break;

        case SM_EVT_SEC_PROCEDURE_START:
        {
            pm_evt.evt_id = PM_EVT_CONN_SEC_START;
            bool pairing = p_sm_evt->params.sec_procedure_start.procedure
                                != PM_LINK_SECURED_PROCEDURE_ENCRYPTION;
            bool bonding = p_sm_evt->params.sec_procedure_start.procedure
                                == PM_LINK_SECURED_PROCEDURE_BONDING;
            ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_pairing_flag_id, pairing);
            ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_bonding_flag_id, bonding);
            break;
        }

        case SM_EVT_PAIRING_SUCCESS:
            pm_evt.evt_id = PM_EVT_CONN_SEC_SUCCEEDED;
            pm_evt.params.conn_sec_succeeded.procedure =
                        p_sm_evt->params.pairing_success.bonded
                        ? PM_LINK_SECURED_PROCEDURE_BONDING
                        : PM_LINK_SECURED_PROCEDURE_PAIRING;
            ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_pairing_flag_id, true);
            ble_conn_state_user_flag_set(p_sm_evt->conn_handle,
                                         m_bonding_flag_id,
                                         p_sm_evt->params.pairing_success.bonded
            );
            break;

        case SM_EVT_PAIRING_FAIL:
            pm_evt.evt_id = PM_EVT_CONN_SEC_FAILED;
            pm_evt.params.conn_sec_failed.procedure =
                        ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_bonding_flag_id)
                        ? PM_LINK_SECURED_PROCEDURE_BONDING
                        : PM_LINK_SECURED_PROCEDURE_PAIRING;
            pm_evt.params.conn_sec_failed.error_src
                = p_sm_evt->params.pairing_failed.error_src;
            pm_evt.params.conn_sec_failed.error
                = p_sm_evt->params.pairing_failed.error;
            break;

        case SM_EVT_LINK_ENCRYPTION_UPDATE:
            if (!ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_pairing_flag_id))
            {
                pm_evt.evt_id = PM_EVT_CONN_SEC_SUCCEEDED;
                pm_evt.params.conn_sec_succeeded.procedure = PM_LINK_SECURED_PROCEDURE_ENCRYPTION;
            }
            else
            {
                find_peer_id = false;
                send_evt     = false;
            }
            break;

        case SM_EVT_LINK_ENCRYPTION_FAILED:
            pm_evt.evt_id = PM_EVT_CONN_SEC_FAILED;
            pm_evt.params.conn_sec_failed.procedure
                            = PM_LINK_SECURED_PROCEDURE_ENCRYPTION;
            pm_evt.params.conn_sec_failed.error_src
                            = p_sm_evt->params.link_encryption_failed.error_src;
            pm_evt.params.conn_sec_failed.error
                            = p_sm_evt->params.link_encryption_failed.error;
            break;

        case SM_EVT_BONDING_INFO_STORED:
            pm_evt.evt_id  = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
            pm_evt.peer_id = p_sm_evt->params.bonding_info_stored.peer_id;
            pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_BONDING;
            pm_evt.params.peer_data_update_succeeded.action  = PM_PEER_DATA_OP_UPDATE;
            find_peer_id = false;
            break;

        case SM_EVT_ERROR_BONDING_INFO:
            pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED;
            pm_evt.peer_id = p_sm_evt->params.error_bonding_info.peer_id;
            pm_evt.params.peer_data_update_failed.data_id = PM_PEER_DATA_ID_BONDING;
            pm_evt.params.peer_data_update_failed.action  = PM_PEER_DATA_OP_UPDATE;
            pm_evt.params.peer_data_update_failed.error
                = p_sm_evt->params.error_bonding_info.error;
            find_peer_id = false;
            break;

        case SM_EVT_ERROR_UNEXPECTED:
            pm_evt.evt_id = PM_EVT_ERROR_UNEXPECTED;
            pm_evt.params.error_unexpected.error = p_sm_evt->params.error_unexpected.error;
            break;

        case SM_EVT_ERROR_NO_MEM:
            pm_evt.evt_id = PM_EVT_STORAGE_FULL;
            break;

        case SM_EVT_ERROR_SMP_TIMEOUT:
            pm_evt.evt_id = PM_EVT_CONN_SEC_FAILED;
            pm_evt.params.conn_sec_failed.procedure
                        = ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_bonding_flag_id)
                        ? PM_LINK_SECURED_PROCEDURE_BONDING
                        : PM_LINK_SECURED_PROCEDURE_PAIRING;
            pm_evt.params.conn_sec_failed.error_src  = BLE_GAP_SEC_STATUS_SOURCE_LOCAL;
            pm_evt.params.conn_sec_failed.error      = PM_CONN_SEC_ERROR_SMP_TIMEOUT;
            break;

        case SM_EVT_CONN_SEC_CONFIG_REQ:
            pm_evt.evt_id = PM_EVT_CONN_SEC_CONFIG_REQ;
            break;

        default:
            send_evt = false;
            break;
    }

    if (find_peer_id)
    {
        pm_evt.peer_id = im_peer_id_get_by_conn_handle(p_sm_evt->conn_handle);
    }

    if (send_evt)
    {
        evt_send(&pm_evt);
    }
}
Example #12
0
void im_ble_evt_handler(ble_evt_t * ble_evt)
{
    ret_code_t err_code;
    switch (ble_evt->header.evt_id)
    {
    case BLE_GAP_EVT_CONNECTED:
    {
        pm_peer_id_t bonded_matching_peer_id = PM_PEER_ID_INVALID;

        if (ble_evt->evt.gap_evt.params.connected.irk_match == 1)
        {
            // The peer was matched using a whitelist.
            bonded_matching_peer_id
                = m_im.irk_whitelist_peer_ids[ble_evt->evt.gap_evt.params.connected.irk_match_idx];
        }
        else if (   ble_evt->evt.gap_evt.params.connected.peer_addr.addr_type
                    != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE)
        {
            /* Search the database for bonding data matching the one that triggered the event.
             * Public and static addresses can be matched on address alone, while resolvable
             * random addresses can be resolved agains known IRKs. Non-resolvable random addresses
             * are never matching because they are not longterm form of identification.
             */
            pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID);
            while (   (compared_peer_id        != PM_PEER_ID_INVALID)
                      && (bonded_matching_peer_id == PM_PEER_ID_INVALID))
            {
                pm_peer_data_flash_t compared_data;
                switch (ble_evt->evt.gap_evt.params.connected.peer_addr.addr_type)
                {
                case BLE_GAP_ADDR_TYPE_PUBLIC:
                /* fall-through */
                case BLE_GAP_ADDR_TYPE_RANDOM_STATIC:
                    err_code = pdb_read_buf_get(compared_peer_id,
                                                PM_PEER_DATA_ID_BONDING,
                                                &compared_data,
                                                NULL);
                    if ((err_code == NRF_SUCCESS) &&
                            addr_compare(&ble_evt->evt.gap_evt.params.connected.peer_addr,
                                         &compared_data.p_bonding_data->peer_id.id_addr_info)
                       )
                    {
                        bonded_matching_peer_id = compared_peer_id;
                    }
                    break;

                case BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE:
                    err_code = pdb_read_buf_get(compared_peer_id,
                                                PM_PEER_DATA_ID_BONDING,
                                                &compared_data,
                                                NULL);
                    if (err_code == NRF_SUCCESS &&
                            im_address_resolve(&ble_evt->evt.gap_evt.params.connected.peer_addr,
                                               &compared_data.p_bonding_data->peer_id.id_info)
                       )
                    {
                        bonded_matching_peer_id = compared_peer_id;
                    }
                    break;

                case BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE:
                    // Should not happen.
                    break;

                default:
                    break;
                }
                compared_peer_id = pdb_next_peer_id_get(compared_peer_id);
            }
        }
        uint8_t new_index = new_connection(ble_evt->evt.gap_evt.conn_handle, &ble_evt->evt.gap_evt.params.connected.peer_addr);
        UNUSED_VARIABLE(new_index);

        if (bonded_matching_peer_id != PM_PEER_ID_INVALID)
        {
            im_new_peer_id(ble_evt->evt.gap_evt.conn_handle, bonded_matching_peer_id);

            // Send a bonded peer event
            im_evt_t im_evt;
            im_evt.conn_handle = ble_evt->evt.gap_evt.conn_handle;
            im_evt.evt_id = IM_EVT_BONDED_PEER_CONNECTED;
            evt_send(&im_evt);
        }
    }
    }
}
Example #13
0
void pdb_evt_handler(pdb_evt_t const * p_evt)
{
    bool send_evt = true;
    pm_evt_t pm_evt;

    memset(&pm_evt, 0, sizeof(pm_evt_t));
    pm_evt.peer_id = p_evt->peer_id;
    pm_evt.conn_handle = im_conn_handle_get(pm_evt.peer_id);

    switch (p_evt->evt_id)
    {
        case PDB_EVT_WRITE_BUF_STORED:
            pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATED;
            pm_evt.params.peer_data_updated_evt.data_id = p_evt->data_id;
            pm_evt.params.peer_data_updated_evt.action  = PM_PEER_DATA_ACTION_UPDATE;
            break;

        case PDB_EVT_RAW_STORED:
            pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATED;
            pm_evt.params.peer_data_updated_evt.data_id = p_evt->data_id;
            pm_evt.params.peer_data_updated_evt.action  = PM_PEER_DATA_ACTION_UPDATE;
            break;

        case PDB_EVT_RAW_STORE_FAILED:
            pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED;
            pm_evt.params.peer_data_update_failed_evt.data_id = p_evt->data_id;
            pm_evt.params.peer_data_update_failed_evt.action  = PM_PEER_DATA_ACTION_UPDATE;
            pm_evt.params.peer_data_update_failed_evt.error   = NRF_ERROR_INTERNAL;
            break;

        case PDB_EVT_CLEARED:
            pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATED;
            pm_evt.params.peer_data_updated_evt.data_id = p_evt->data_id;
            pm_evt.params.peer_data_updated_evt.action  = PM_PEER_DATA_ACTION_CLEAR;
            break;

        case PDB_EVT_CLEAR_FAILED:
            pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED;
            pm_evt.params.peer_data_update_failed_evt.data_id = p_evt->data_id;
            pm_evt.params.peer_data_update_failed_evt.action  = PM_PEER_DATA_ACTION_CLEAR;
            pm_evt.params.peer_data_update_failed_evt.error   = NRF_ERROR_INTERNAL;
            break;

        case PDB_EVT_COMPRESSED:
            send_evt = false;
            // Do nothing
            break;

        case PDB_EVT_ERROR_NO_MEM:
            pm_evt.evt_id = PM_EVT_STORAGE_FULL;
            break;

        case PDB_EVT_ERROR_UNEXPECTED:
            pm_evt.evt_id = PM_EVT_ERROR_UNEXPECTED;
            break;

        default:
            /* No implementation necessary. */
            break;
    }
    if (send_evt)
    {
        evt_send(&pm_evt);
    }
}
Example #14
0
void evt_timer_action(void)
{
    evt_send(&evt);
    evt_timer.expires = tick + EVT_DELAY; /* 1s timer */
    tmr_start(&evt_timer);
}