Exemplo n.º 1
0
void pm_handler(pm_evt_t const *p_event)
{
    nRF5xn               &ble             = nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
    nRF5xSecurityManager &securityManager = (nRF5xSecurityManager &) ble.getSecurityManager();
    ret_code_t            err_code;
    SecurityManager::SecurityMode_t resolvedSecurityMode;

    switch (p_event->evt_id) {
        case PM_EVT_CONN_SEC_START: /* started */ {
            const ble_gap_sec_params_t *peerParams = &securityParameters;
            securityManager.processSecuritySetupInitiatedEvent(p_event->conn_handle,
                                                                                   peerParams->bond,
                                                                                   peerParams->mitm,
                                                                                   (SecurityManager::SecurityIOCapabilities_t)peerParams->io_caps);
            _enc_in_progress = true;
            break;
        }
        case PM_EVT_CONN_SEC_SUCCEEDED:
            // Update the rank of the peer.
            if (p_event->params.conn_sec_succeeded.procedure == PM_LINK_SECURED_PROCEDURE_BONDING)
            {
                err_code = pm_peer_rank_highest(p_event->peer_id);
            }
        
            securityManager.
                processSecuritySetupCompletedEvent(p_event->conn_handle,
                                                    SecurityManager::SEC_STATUS_SUCCESS);// SEC_STATUS_SUCCESS of SecurityCompletionStatus_t
                                                    
            ble_gap_conn_sec_t conn_sec;
            sd_ble_gap_conn_sec_get(p_event->conn_handle, &conn_sec);
            
            resolvedSecurityMode = SecurityManager::SECURITY_MODE_NO_ACCESS;
            
            switch (conn_sec.sec_mode.sm) {
                case 1:
                    switch (conn_sec.sec_mode.lv) {
                        case 1:
                            resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK;
                            break;
                        case 2:
                            resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM;
                            break;
                        case 3:
                            resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM;
                            break;
                    }
                    break;
                case 2:
                    switch (conn_sec.sec_mode.lv) {
                        case 1:
                            resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_NO_MITM;
                            break;
                        case 2:
                            resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM;
                            break;
                    }
                    break;
            }

            securityManager.processLinkSecuredEvent(p_event->conn_handle, resolvedSecurityMode);

            _enc_in_progress = false;
            break;
            
        case PM_EVT_CONN_SEC_FAILED:
            SecurityManager::SecurityCompletionStatus_t securityCompletionStatus;
            
            if ((uint32_t)p_event->params.conn_sec_failed.error >= PM_CONN_SEC_ERROR_BASE ) {
                securityCompletionStatus = SecurityManager::SEC_STATUS_UNSPECIFIED;
            } else {
                 securityCompletionStatus = 
                    (SecurityManager::SecurityCompletionStatus_t)p_event->params.conn_sec_failed.error;
            }
                
            securityManager.
                processSecuritySetupCompletedEvent(p_event->conn_handle, securityCompletionStatus);

            _enc_in_progress = false;
            break;
            
        case PM_EVT_BONDED_PEER_CONNECTED:
            pm_peer_rank_highest(p_event->peer_id);
            break;
        
        case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
            if (p_event->params.peer_data_update_succeeded.action == PM_PEER_DATA_OP_UPDATE)
            {
                securityManager.processSecurityContextStoredEvent(p_event->conn_handle);
            }
            break;
            
        case PM_EVT_PEER_DATA_UPDATE_FAILED:
            break;
            
        case PM_EVT_PEERS_DELETE_SUCCEEDED:
            async_ret_code = NRF_SUCCESS;        // respond SUCCESS to the busy-loop in f. btle_purgeAllBondingState
            break;
        
        case PM_EVT_PEERS_DELETE_FAILED:
            async_ret_code = NRF_ERROR_INTERNAL; // respond FAILURE to the busy-loop in f. btle_purgeAllBondingState
            break;

        case PM_EVT_STORAGE_FULL:
            // Run garbage collection on the flash.
            err_code = fds_gc();
            if (err_code == FDS_ERR_BUSY || err_code == FDS_ERR_NO_SPACE_IN_QUEUES)
            {
                // Retry.
            }
            else
            {
                APP_ERROR_CHECK(err_code);
            }
            break;//PM_EVT_STORAGE_FULL
            
        case PM_EVT_CONN_SEC_CONFIG_REQ:{
            // A connected peer (central) is trying to pair, but the Peer Manager already has a bond
            // for that peer. Setting allow_repairing to false rejects the pairing request.
            // If this event is ignored (pm_conn_sec_config_reply is not called in the event
            // handler), the Peer Manager assumes allow_repairing to be false.
            pm_conn_sec_config_t conn_sec_config = {.allow_repairing = true};
            pm_conn_sec_config_reply(p_event->conn_handle, &conn_sec_config);
            }
            break;//PM_EVT_CONN_SEC_CONFIG_REQ
            
        default:
            break;
    }
}

#if  (NRF_SD_BLE_API_VERSION <= 2)
ble_error_t
btle_createWhitelistFromBondTable(ble_gap_whitelist_t *p_whitelist)
{
    if (!btle_hasInitializedSecurity()) {
        return BLE_ERROR_INITIALIZATION_INCOMPLETE;
    }
    ret_code_t err = pm_whitelist_create( NULL, BLE_GAP_WHITELIST_ADDR_MAX_COUNT, p_whitelist);
    if (err == NRF_SUCCESS) {
        return BLE_ERROR_NONE;
    } else if (err == NRF_ERROR_NULL) {
        return BLE_ERROR_PARAM_OUT_OF_RANGE;
    } else {
        return BLE_ERROR_INVALID_STATE;
    }
}
#endif

bool
btle_matchAddressAndIrk(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk)
{
    /*
     * Use a helper function from the Nordic SDK to test whether the BLE
     * address can be generated using the IRK.
     */
    return im_address_resolve(p_addr, p_irk);
}

void
btle_generateResolvableAddress(const ble_gap_irk_t &irk, ble_gap_addr_t &address)
{
    /* Set type to resolvable */
    address.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;

    /*
     * Assign a random number to the most significant 3 bytes
     * of the address.
     */
    address.addr[BLE_GAP_ADDR_LEN - 3] = 0x8E;
    address.addr[BLE_GAP_ADDR_LEN - 2] = 0x4F;
    address.addr[BLE_GAP_ADDR_LEN - 1] = 0x7C;

    /* Calculate the hash and store it in the top half of the address */
    ah(irk.irk, &address.addr[BLE_GAP_ADDR_LEN - 3], address.addr);
}
Exemplo n.º 2
0
Arquivo: main.c Projeto: t21/HomeHub
/**@brief Function for handling the Application's BLE Stack events.
 *
 * @details This function will be called for advertising events which are passed to the application.
 *
 * @param[in] ble_adv_evt  Advertising event.
 */
static void on_adv_evt(ess_adv_evt_t ess_adv_evt)
{
    switch (ess_adv_evt)
    {
        case ESS_ADV_EVT_MODE_1:
            NRF_LOG_PRINTF("%s - ESS_ADV_EVT_MODE_1\r\n", __func__);
            break;

        case ESS_ADV_EVT_MODE_2:
            NRF_LOG_PRINTF("%s - ESS_ADV_EVT_MODE_2\r\n", __func__);
            break;

        case ESS_ADV_EVT_MODE_3:
            NRF_LOG_PRINTF("%s - ESS_ADV_EVT_MODE_3\r\n", __func__);
            m_adv_state = W_ADV_STATE_IDLE;
            break;
       
        case ESS_ADV_EVT_IDLE:
            NRF_LOG_PRINTF("%s - ESS_ADV_EVT_IDLE\r\n", __func__);
            NRF_LOG("[APP]: Going to sleep.\r\n\r\n\r\n");
            sleep_mode_enter();
            break;

        case ESS_ADV_EVT_WHITELIST_REQUEST:
        {
            NRF_LOG_PRINTF("%s - ESS_ADV_EVT_WHITELIST_REQUEST\r\n", __func__);
            ret_code_t err_code;
            // Storage for the whitelist.
            ble_gap_irk_t * irks[8];
            ble_gap_addr_t * addrs[8];
            ble_gap_whitelist_t whitelist = {.pp_irks = irks, .pp_addrs = addrs};
            // Construct a list of peer IDs.
            pm_peer_id_t peer_ids[8];
            pm_peer_id_t peer_id = pm_next_peer_id_get(PM_PEER_ID_INVALID);
            uint32_t n_peer_ids = 0;
            while((peer_id != PM_PEER_ID_INVALID) && (n_peer_ids < 8))
            {
                peer_ids[n_peer_ids++] = peer_id;
                peer_id = pm_next_peer_id_get(peer_id);
            }
            // Create the whitelist.
            err_code = pm_whitelist_create(peer_ids, n_peer_ids, &whitelist);
            APP_ERROR_CHECK(err_code);
            // Apply the whitelist.
            err_code = ess_advertising_whitelist_reply(&whitelist);
            APP_ERROR_CHECK(err_code);
            break;
        }

        case ESS_ADV_EVT_PEER_ADDR_REQUEST:
        {
            NRF_LOG_PRINTF("%s - ESS_ADV_EVT_PEER_ADDR_REQUEST\r\n", __func__);
//            ble_gap_addr_t peer_address;

//            // Only Give peer address if we have a handle to the bonded peer.
//            if(m_bonded_peer_handle.appl_id != DM_INVALID_ID)
//            {

//                err_code = dm_peer_addr_get(&m_bonded_peer_handle, &peer_address);
//                if (err_code != (NRF_ERROR_NOT_FOUND | DEVICE_MANAGER_ERR_BASE))
//                {
//                    APP_ERROR_CHECK(err_code);

//                    err_code = ble_advertising_peer_addr_reply(&peer_address);
//                    APP_ERROR_CHECK(err_code);
//                }

//            }
            break;
        }
        
        default:
            break;
    }
}