/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; static ble_gap_evt_auth_status_t m_auth_status; ble_gap_enc_info_t * p_enc_info; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: led_off(LED); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: m_conn_handle = BLE_CONN_HANDLE_INVALID; advertising_start(); break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status; break; case BLE_GAP_EVT_SEC_INFO_REQUEST: p_enc_info = &m_auth_status.periph_keys.enc_info; if (p_enc_info->div == p_ble_evt->evt.gap_evt.params.sec_info_request.div) { err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, NULL); APP_ERROR_CHECK(err_code); } else { // No keys found for this device err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL); APP_ERROR_CHECK(err_code); } break; default: // No implementation needed. break; } }
uint32_t conn_mw_ble_gap_sec_info_reply(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len) { SER_ASSERT_NOT_NULL(p_rx_buf); SER_ASSERT_NOT_NULL(p_tx_buf); SER_ASSERT_NOT_NULL(p_tx_buf_len); uint32_t err_code = NRF_SUCCESS; uint32_t sd_err_code; uint16_t conn_handle; ble_gap_enc_info_t enc_info; ble_gap_enc_info_t * p_enc_info = &enc_info; ble_gap_sign_info_t sign_info; ble_gap_sign_info_t * p_sign_info = &sign_info; err_code = ble_gap_sec_info_reply_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_enc_info, &p_sign_info); SER_ASSERT(err_code == NRF_SUCCESS, err_code); sd_err_code = sd_ble_gap_sec_info_reply(conn_handle, p_enc_info, p_sign_info); err_code = ble_gap_sec_info_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); SER_ASSERT(err_code == NRF_SUCCESS, err_code); return err_code; }
/**@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); } }
/**@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); } }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: app.conn_handle = p_ble_evt->evt.gap_evt.conn_handle; //advertising_stop(); break; case BLE_GAP_EVT_DISCONNECTED: app.conn_handle = BLE_CONN_HANDLE_INVALID; advertising_start(); break; case BLE_GATTS_EVT_WRITE: break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(app.conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params, NULL); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(app.conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: break; case BLE_GAP_EVT_SEC_INFO_REQUEST: // No keys found for this device. err_code = sd_ble_gap_sec_info_reply(app.conn_handle, NULL, NULL, NULL); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; default: break; } }
/**@brief Application's BLE Stack event handler. * * @param[in] p_ble_evt Bluetooth stack event. */ void bleApp_onEvt(ble_evt_t * p_ble_evt) { uint32_t err_code = NRF_SUCCESS; static ble_gap_evt_auth_status_t m_auth_status; ble_gap_enc_info_t * p_enc_info; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; led_setState(LED_BLUE, LED_STATE_ON); break; case BLE_GAP_EVT_DISCONNECTED: m_conn_handle = BLE_CONN_HANDLE_INVALID; led_setState(LED_BLUE, LED_STATE_OFF); if (advertisingEnabled) { bleApp_advertisingStart(); } break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0); break; case BLE_GAP_EVT_AUTH_STATUS: m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status; break; case BLE_GAP_EVT_SEC_INFO_REQUEST: p_enc_info = &m_auth_status.periph_keys.enc_info; if (p_enc_info->div == p_ble_evt->evt.gap_evt.params.sec_info_request.div) { err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, NULL); } else { // No keys found for this device err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL); } break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT) { led_setState(LED_BLUE, LED_STATE_OFF); // Go to system-off mode (this function will not return; wakeup will cause a reset) //GPIO_WAKEUP_BUTTON_CONFIG(WAKEUP_BUTTON_PIN); //err_code = sd_power_system_off(); } break; case BLE_GAP_EVT_RSSI_CHANGED: break; default: break; } APP_ERROR_CHECK(err_code); }
/** * @brief Handler for all BLE events */ void ble_event_handler(ble_evt_t* p_ble_evt) { static ble_gap_evt_auth_status_t m_auth_status; ble_gap_enc_info_t* p_enc_info; ble_gatts_evt_write_t* p_evt_write; uint32_t retval; if (p_ble_evt == NULL) return; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: nrf_gpio_pin_clear(PIN_LED_ADVERTISING); nrf_gpio_pin_set(PIN_LED_CONNECTED); nrf_gpio_pin_clear(PIN_LED_DATA); ble_connection_handle = p_ble_evt->evt.gap_evt.conn_handle; //on_ble_connected(); break; case BLE_GAP_EVT_DISCONNECTED: nrf_gpio_pin_clear(PIN_LED_ADVERTISING); nrf_gpio_pin_clear(PIN_LED_CONNECTED); nrf_gpio_pin_clear(PIN_LED_DATA); ble_connection_handle = BLE_CONN_HANDLE_INVALID; //on_ble_disconnected(); //start_advertising(); // TODO: Something's not working properly upon disconnect preventing reconnect NVIC_SystemReset(); break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: retval = sd_ble_gap_sec_params_reply( ble_connection_handle, BLE_GAP_SEC_STATUS_SUCCESS, &ble_security_parameters ); APP_ERROR_CHECK(retval); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: retval = sd_ble_gatts_sys_attr_set(ble_connection_handle, NULL, 0); APP_ERROR_CHECK(retval); break; case BLE_GAP_EVT_AUTH_STATUS: m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status; break; case BLE_GAP_EVT_SEC_INFO_REQUEST: p_enc_info = &m_auth_status.periph_keys.enc_info; if (p_enc_info->div == p_ble_evt->evt.gap_evt.params.sec_info_request.div) { retval = sd_ble_gap_sec_info_reply(ble_connection_handle, p_enc_info, NULL); APP_ERROR_CHECK(retval); } else { // No keys found for this device retval = sd_ble_gap_sec_info_reply(ble_connection_handle, NULL, NULL); APP_ERROR_CHECK(retval); } break; case BLE_GATTS_EVT_WRITE: nrf_gpio_pin_set(PIN_LED_DATA); p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; if (p_evt_write->handle == tree_service.characteristic_set_led_color_handles.value_handle) { on_characteristic_written(tree_service.characteristic_set_led_color_uuid.uuid, p_evt_write->data, p_evt_write->len); } break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT) { // Go to system-off mode (this function will not return; wakeup will cause a reset) //err_code = sd_power_system_off(); } NVIC_SystemReset(); break; /* case BLE_EVT_TX_COMPLETE: if (!ble_buffer_available) tx_complete = true; break; */ default: //printf("unimplemented event\n"); break; } }
void nRF51822::poll() { uint32_t evtBuf[BLE_STACK_EVT_MSG_BUF_SIZE] __attribute__ ((__aligned__(BLE_EVTS_PTR_ALIGNMENT))); uint16_t evtLen = sizeof(evtBuf); ble_evt_t* bleEvt = (ble_evt_t*)evtBuf; if (sd_ble_evt_get((uint8_t*)evtBuf, &evtLen) == NRF_SUCCESS) { switch (bleEvt->header.evt_id) { case BLE_EVT_TX_COMPLETE: #ifdef NRF_51822_DEBUG Serial.print(F("Evt TX complete ")); Serial.println(bleEvt->evt.common_evt.params.tx_complete.count); #endif this->_txBufferCount++; break; case BLE_GAP_EVT_CONNECTED: #ifdef NRF_51822_DEBUG char address[18]; BLEUtil::addressToString(bleEvt->evt.gap_evt.params.connected.peer_addr.addr, address); Serial.print(F("Evt Connected ")); Serial.println(address); #endif this->_connectionHandle = bleEvt->evt.gap_evt.conn_handle; sd_ble_tx_buffer_count_get(&this->_txBufferCount); if (this->_eventListener) { this->_eventListener->BLEDeviceConnected(*this, bleEvt->evt.gap_evt.params.connected.peer_addr.addr); } if (this->_minimumConnectionInterval >= BLE_GAP_CP_MIN_CONN_INTVL_MIN && this->_maximumConnectionInterval <= BLE_GAP_CP_MAX_CONN_INTVL_MAX) { ble_gap_conn_params_t gap_conn_params; gap_conn_params.min_conn_interval = this->_minimumConnectionInterval; // in 1.25ms units gap_conn_params.max_conn_interval = this->_maximumConnectionInterval; // in 1.25ms unit gap_conn_params.slave_latency = 0; gap_conn_params.conn_sup_timeout = 4000 / 10; // in 10ms unit sd_ble_gap_conn_param_update(this->_connectionHandle, &gap_conn_params); } if (this->_numRemoteServices > 0) { sd_ble_gattc_primary_services_discover(this->_connectionHandle, 1, NULL); } break; case BLE_GAP_EVT_DISCONNECTED: #ifdef NRF_51822_DEBUG Serial.println(F("Evt Disconnected")); #endif this->_connectionHandle = BLE_CONN_HANDLE_INVALID; this->_txBufferCount = 0; for (int i = 0; i < this->_numLocalCharacteristics; i++) { struct localCharacteristicInfo* localCharacteristicInfo = &this->_localCharacteristicInfo[i]; localCharacteristicInfo->notifySubscribed = false; localCharacteristicInfo->indicateSubscribed = false; if (localCharacteristicInfo->characteristic->subscribed()) { if (this->_eventListener) { this->_eventListener->BLEDeviceCharacteristicSubscribedChanged(*this, *localCharacteristicInfo->characteristic, false); } } } if (this->_eventListener) { this->_eventListener->BLEDeviceDisconnected(*this); } // clear remote handle info for (int i = 0; i < this->_numRemoteServices; i++) { memset(&this->_remoteServiceInfo[i].handlesRange, 0, sizeof(this->_remoteServiceInfo[i].handlesRange)); } for (int i = 0; i < this->_numRemoteCharacteristics; i++) { memset(&this->_remoteCharacteristicInfo[i].properties, 0, sizeof(this->_remoteCharacteristicInfo[i].properties)); this->_remoteCharacteristicInfo[i].valueHandle = 0; } this->_remoteRequestInProgress = false; this->startAdvertising(); break; case BLE_GAP_EVT_CONN_PARAM_UPDATE: #ifdef NRF_51822_DEBUG Serial.print(F("Evt Conn Param Update 0x")); Serial.print(bleEvt->evt.gap_evt.params.conn_param_update.conn_params.min_conn_interval, HEX); Serial.print(F(" 0x")); Serial.print(bleEvt->evt.gap_evt.params.conn_param_update.conn_params.max_conn_interval, HEX); Serial.print(F(" 0x")); Serial.print(bleEvt->evt.gap_evt.params.conn_param_update.conn_params.slave_latency, HEX); Serial.print(F(" 0x")); Serial.print(bleEvt->evt.gap_evt.params.conn_param_update.conn_params.conn_sup_timeout, HEX); Serial.println(); #endif break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: #ifdef NRF_51822_DEBUG Serial.print(F("Evt Sec Params Request ")); #ifndef NRF51_S130 Serial.print(bleEvt->evt.gap_evt.params.sec_params_request.peer_params.timeout); Serial.print(F(" ")); #endif Serial.print(bleEvt->evt.gap_evt.params.sec_params_request.peer_params.bond); Serial.print(F(" ")); Serial.print(bleEvt->evt.gap_evt.params.sec_params_request.peer_params.mitm); Serial.print(F(" ")); Serial.print(bleEvt->evt.gap_evt.params.sec_params_request.peer_params.io_caps); Serial.print(F(" ")); Serial.print(bleEvt->evt.gap_evt.params.sec_params_request.peer_params.oob); Serial.print(F(" ")); Serial.print(bleEvt->evt.gap_evt.params.sec_params_request.peer_params.min_key_size); Serial.print(F(" ")); Serial.print(bleEvt->evt.gap_evt.params.sec_params_request.peer_params.max_key_size); Serial.println(); #endif if (this->_bondStore && !this->_bondStore->hasData()) { // only allow bonding if bond store exists and there is no data ble_gap_sec_params_t gapSecParams; #ifdef NRF51_S130 gapSecParams.kdist_periph.enc = 1; #else gapSecParams.timeout = 30; // must be 30s #endif gapSecParams.bond = true; gapSecParams.mitm = false; gapSecParams.io_caps = BLE_GAP_IO_CAPS_NONE; gapSecParams.oob = false; gapSecParams.min_key_size = 7; gapSecParams.max_key_size = 16; #ifdef NRF51_S130 ble_gap_sec_keyset_t keyset; keyset.keys_central.p_enc_key = NULL; keyset.keys_central.p_id_key = NULL; keyset.keys_central.p_sign_key = NULL; keyset.keys_periph.p_enc_key = this->_encKey; keyset.keys_periph.p_id_key = NULL; keyset.keys_periph.p_sign_key = NULL; sd_ble_gap_sec_params_reply(this->_connectionHandle, BLE_GAP_SEC_STATUS_SUCCESS, &gapSecParams, &keyset); #else sd_ble_gap_sec_params_reply(this->_connectionHandle, BLE_GAP_SEC_STATUS_SUCCESS, &gapSecParams); #endif } else { #ifdef NRF51_S130 sd_ble_gap_sec_params_reply(this->_connectionHandle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); #else sd_ble_gap_sec_params_reply(this->_connectionHandle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL); #endif } break; case BLE_GAP_EVT_SEC_INFO_REQUEST: #ifdef NRF_51822_DEBUG Serial.print(F("Evt Sec Info Request ")); // Serial.print(bleEvt->evt.gap_evt.params.sec_info_request.peer_addr); // Serial.print(F(" ")); #ifdef NRF51_S130 Serial.print(bleEvt->evt.gap_evt.params.sec_info_request.master_id.ediv); #else Serial.print(bleEvt->evt.gap_evt.params.sec_info_request.div); #endif Serial.print(F(" ")); Serial.print(bleEvt->evt.gap_evt.params.sec_info_request.enc_info); Serial.print(F(" ")); Serial.print(bleEvt->evt.gap_evt.params.sec_info_request.id_info); Serial.print(F(" ")); Serial.print(bleEvt->evt.gap_evt.params.sec_info_request.sign_info); Serial.println(); #endif #ifdef NRF51_S130 if (this->_encKey->master_id.ediv == bleEvt->evt.gap_evt.params.sec_info_request.master_id.ediv) { sd_ble_gap_sec_info_reply(this->_connectionHandle, &this->_encKey->enc_info, NULL, NULL); } else { sd_ble_gap_sec_info_reply(this->_connectionHandle, NULL, NULL, NULL); } #else if (this->_authStatus->periph_keys.enc_info.div == bleEvt->evt.gap_evt.params.sec_info_request.div) { sd_ble_gap_sec_info_reply(this->_connectionHandle, &this->_authStatus->periph_keys.enc_info, NULL); } else { sd_ble_gap_sec_info_reply(this->_connectionHandle, NULL, NULL); } #endif break; case BLE_GAP_EVT_AUTH_STATUS: #ifdef NRF_51822_DEBUG Serial.println(F("Evt Auth Status")); Serial.println(bleEvt->evt.gap_evt.params.auth_status.auth_status); #endif if (BLE_GAP_SEC_STATUS_SUCCESS == bleEvt->evt.gap_evt.params.auth_status.auth_status) { #ifndef NRF51_S130 *this->_authStatus = bleEvt->evt.gap_evt.params.auth_status; #endif if (this->_bondStore) { #ifdef NRF_51822_DEBUG Serial.println(F("Storing bond data")); #endif #ifdef NRF51_S130 this->_bondStore->putData(this->_bondData, 0, sizeof(this->_bondData)); #else this->_bondStore->putData(this->_authStatusBuffer, 0, sizeof(this->_authStatusBuffer)); #endif } if (this->_eventListener) { this->_eventListener->BLEDeviceBonded(*this); } } break; case BLE_GAP_EVT_CONN_SEC_UPDATE: #ifdef NRF_51822_DEBUG Serial.print(F("Evt Conn Sec Update ")); Serial.print(bleEvt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm); Serial.print(F(" ")); Serial.print(bleEvt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv); Serial.print(F(" ")); Serial.print(bleEvt->evt.gap_evt.params.conn_sec_update.conn_sec.encr_key_size); Serial.println(); #endif break; case BLE_GATTS_EVT_WRITE: { #ifdef NRF_51822_DEBUG Serial.print(F("Evt Write, handle = ")); Serial.println(bleEvt->evt.gatts_evt.params.write.handle, DEC); BLEUtil::printBuffer(bleEvt->evt.gatts_evt.params.write.data, bleEvt->evt.gatts_evt.params.write.len); #endif uint16_t handle = bleEvt->evt.gatts_evt.params.write.handle; for (int i = 0; i < this->_numLocalCharacteristics; i++) { struct localCharacteristicInfo* localCharacteristicInfo = &this->_localCharacteristicInfo[i]; if (localCharacteristicInfo->handles.value_handle == handle) { if (this->_eventListener) { this->_eventListener->BLEDeviceCharacteristicValueChanged(*this, *localCharacteristicInfo->characteristic, bleEvt->evt.gatts_evt.params.write.data, bleEvt->evt.gatts_evt.params.write.len); } break; } else if (localCharacteristicInfo->handles.cccd_handle == handle) { uint16_t value = bleEvt->evt.gatts_evt.params.write.data[0] | (bleEvt->evt.gatts_evt.params.write.data[1] << 8); localCharacteristicInfo->notifySubscribed = (value & 0x0001); localCharacteristicInfo->indicateSubscribed = (value & 0x0002); bool subscribed = (localCharacteristicInfo->notifySubscribed || localCharacteristicInfo->indicateSubscribed); if (subscribed != localCharacteristicInfo->characteristic->subscribed()) { if (this->_eventListener) { this->_eventListener->BLEDeviceCharacteristicSubscribedChanged(*this, *localCharacteristicInfo->characteristic, subscribed); } break; } } } break; } case BLE_GATTS_EVT_SYS_ATTR_MISSING: #ifdef NRF_51822_DEBUG Serial.print(F("Evt Sys Attr Missing ")); Serial.println(bleEvt->evt.gatts_evt.params.sys_attr_missing.hint); #endif #ifdef NRF51_S130 sd_ble_gatts_sys_attr_set(this->_connectionHandle, NULL, 0, 0); #else sd_ble_gatts_sys_attr_set(this->_connectionHandle, NULL, 0); #endif break; case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: #ifdef NRF_51822_DEBUG Serial.print(F("Evt Prim Srvc Disc Rsp 0x")); Serial.println(bleEvt->evt.gattc_evt.gatt_status, HEX); #endif if (bleEvt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_SUCCESS) { uint16_t count = bleEvt->evt.gattc_evt.params.prim_srvc_disc_rsp.count; for (int i = 0; i < count; i++) { for (int j = 0; j < this->_numRemoteServices; j++) { if ((bleEvt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].uuid.type == this->_remoteServiceInfo[j].uuid.type) && (bleEvt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].uuid.uuid == this->_remoteServiceInfo[j].uuid.uuid)) { this->_remoteServiceInfo[j].handlesRange = bleEvt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].handle_range; break; } } } uint16_t startHandle = bleEvt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[count - 1].handle_range.end_handle + 1; sd_ble_gattc_primary_services_discover(this->_connectionHandle, startHandle, NULL); } else { // done discovering services for (int i = 0; i < this->_numRemoteServices; i++) { if (this->_remoteServiceInfo[i].handlesRange.start_handle != 0 && this->_remoteServiceInfo[i].handlesRange.end_handle != 0) { this->_remoteServiceDiscoveryIndex = i; sd_ble_gattc_characteristics_discover(this->_connectionHandle, &this->_remoteServiceInfo[i].handlesRange); break; } } } break; case BLE_GATTC_EVT_CHAR_DISC_RSP: #ifdef NRF_51822_DEBUG Serial.print(F("Evt Char Disc Rsp 0x")); Serial.println(bleEvt->evt.gattc_evt.gatt_status, HEX); #endif if (bleEvt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_SUCCESS) { ble_gattc_handle_range_t serviceHandlesRange = this->_remoteServiceInfo[this->_remoteServiceDiscoveryIndex].handlesRange; uint16_t count = bleEvt->evt.gattc_evt.params.char_disc_rsp.count; for (int i = 0; i < count; i++) { for (int j = 0; j < this->_numRemoteCharacteristics; j++) { if ((this->_remoteServiceInfo[this->_remoteServiceDiscoveryIndex].service == this->_remoteCharacteristicInfo[j].service) && (bleEvt->evt.gattc_evt.params.char_disc_rsp.chars[i].uuid.type == this->_remoteCharacteristicInfo[j].uuid.type) && (bleEvt->evt.gattc_evt.params.char_disc_rsp.chars[i].uuid.uuid == this->_remoteCharacteristicInfo[j].uuid.uuid)) { this->_remoteCharacteristicInfo[j].properties = bleEvt->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props; this->_remoteCharacteristicInfo[j].valueHandle = bleEvt->evt.gattc_evt.params.char_disc_rsp.chars[i].handle_value; } } serviceHandlesRange.start_handle = bleEvt->evt.gattc_evt.params.char_disc_rsp.chars[i].handle_value; } sd_ble_gattc_characteristics_discover(this->_connectionHandle, &serviceHandlesRange); } else { bool discoverCharacteristics = false; for (int i = this->_remoteServiceDiscoveryIndex + 1; i < this->_numRemoteServices; i++) { if (this->_remoteServiceInfo[i].handlesRange.start_handle != 0 && this->_remoteServiceInfo[i].handlesRange.end_handle != 0) { this->_remoteServiceDiscoveryIndex = i; sd_ble_gattc_characteristics_discover(this->_connectionHandle, &this->_remoteServiceInfo[i].handlesRange); discoverCharacteristics = true; break; } } if (!discoverCharacteristics) { if (this->_eventListener) { this->_eventListener->BLEDeviceRemoteServicesDiscovered(*this); } } } break; case BLE_GATTC_EVT_READ_RSP: { #ifdef NRF_51822_DEBUG Serial.print(F("Evt Read Rsp 0x")); Serial.println(bleEvt->evt.gattc_evt.gatt_status, HEX); Serial.println(bleEvt->evt.gattc_evt.params.read_rsp.handle, DEC); BLEUtil::printBuffer(bleEvt->evt.gattc_evt.params.read_rsp.data, bleEvt->evt.gattc_evt.params.read_rsp.len); #endif this->_remoteRequestInProgress = false; if (bleEvt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION && this->_bondStore) { ble_gap_sec_params_t gapSecParams; #ifdef NRF51_S130 gapSecParams.kdist_periph.enc = 1; #else gapSecParams.timeout = 30; // must be 30s #endif gapSecParams.bond = true; gapSecParams.mitm = false; gapSecParams.io_caps = BLE_GAP_IO_CAPS_NONE; gapSecParams.oob = false; gapSecParams.min_key_size = 7; gapSecParams.max_key_size = 16; sd_ble_gap_authenticate(this->_connectionHandle, &gapSecParams); } else { uint16_t handle = bleEvt->evt.gattc_evt.params.read_rsp.handle; for (int i = 0; i < this->_numRemoteCharacteristics; i++) { if (this->_remoteCharacteristicInfo[i].valueHandle == handle) { if (this->_eventListener) { this->_eventListener->BLEDeviceRemoteCharacteristicValueChanged(*this, *this->_remoteCharacteristicInfo[i].characteristic, bleEvt->evt.gattc_evt.params.read_rsp.data, bleEvt->evt.gattc_evt.params.read_rsp. len); } break; } } } break; } case BLE_GATTC_EVT_WRITE_RSP: #ifdef NRF_51822_DEBUG Serial.print(F("Evt Write Rsp 0x")); Serial.println(bleEvt->evt.gattc_evt.gatt_status, HEX); Serial.println(bleEvt->evt.gattc_evt.params.write_rsp.handle, DEC); #endif this->_remoteRequestInProgress = false; if (bleEvt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION && this->_bondStore) { ble_gap_sec_params_t gapSecParams; #ifdef NRF51_S130 gapSecParams.kdist_periph.enc = 1; #else gapSecParams.timeout = 30; // must be 30s #endif gapSecParams.bond = true; gapSecParams.mitm = false; gapSecParams.io_caps = BLE_GAP_IO_CAPS_NONE; gapSecParams.oob = false; gapSecParams.min_key_size = 7; gapSecParams.max_key_size = 16; sd_ble_gap_authenticate(this->_connectionHandle, &gapSecParams); } break; case BLE_GATTC_EVT_HVX: { #ifdef NRF_51822_DEBUG Serial.print(F("Evt Hvx 0x")); Serial.println(bleEvt->evt.gattc_evt.gatt_status, HEX); Serial.println(bleEvt->evt.gattc_evt.params.hvx.handle, DEC); #endif uint16_t handle = bleEvt->evt.gattc_evt.params.hvx.handle; if (bleEvt->evt.gattc_evt.params.hvx.type == BLE_GATT_HVX_INDICATION) { sd_ble_gattc_hv_confirm(this->_connectionHandle, handle); } for (int i = 0; i < this->_numRemoteCharacteristics; i++) { if (this->_remoteCharacteristicInfo[i].valueHandle == handle) { if (this->_eventListener) { this->_eventListener->BLEDeviceRemoteCharacteristicValueChanged(*this, *this->_remoteCharacteristicInfo[i].characteristic, bleEvt->evt.gattc_evt.params.read_rsp.data, bleEvt->evt.gattc_evt.params.read_rsp. len); } break; } } break; } default: #ifdef NRF_51822_DEBUG Serial.print(F("bleEvt->header.evt_id = 0x")); Serial.print(bleEvt->header.evt_id, HEX); Serial.print(F(" ")); Serial.println(bleEvt->header.evt_len); #endif break; } } // sd_app_evt_wait(); }
/**@brief Function for the Application's S110 SoftDevice event handler. * * @param[in] p_ble_evt S110 SoftDevice event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; static ble_gap_sec_keyset_t s_sec_keyset; ble_gap_enc_info_t * p_enc_info; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); m_conn_handle = BLE_CONN_HANDLE_INVALID; advertising_start(); break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: s_sec_keyset.keys_periph.p_enc_key = NULL; err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params, &s_sec_keyset); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: // TODO: Adoptation to s110v8.0.0, is this needed anymore ? break; case BLE_GAP_EVT_SEC_INFO_REQUEST: if (s_sec_keyset.keys_periph.p_enc_key != NULL) { p_enc_info = &s_sec_keyset.keys_periph.p_enc_key->enc_info; err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, NULL, NULL); APP_ERROR_CHECK(err_code); } else { // No keys found for this device. err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL, NULL); APP_ERROR_CHECK(err_code); } break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); // Configure buttons with sense level low as wakeup source. err_code = bsp_buttons_enable(1 << WAKEUP_BUTTON_ID); APP_ERROR_CHECK(err_code); // Go to system-off mode (this function will not return; wakeup will cause a reset). err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; default: // No implementation needed. break; } }
/**@brief Function for the Application's S110 SoftDevice event handler. * * @param[in] p_ble_evt S110 SoftDevice event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; static ble_gap_evt_auth_status_t m_auth_status; ble_gap_enc_info_t * p_enc_info; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: nrf_gpio_pin_set(CONNECTED_LED_PIN_NO); nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO); m_conn_handle = BLE_CONN_HANDLE_INVALID; advertising_start(); break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status; break; case BLE_GAP_EVT_SEC_INFO_REQUEST: p_enc_info = &m_auth_status.periph_keys.enc_info; if (p_enc_info->div == p_ble_evt->evt.gap_evt.params.sec_info_request.div) { err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, NULL); APP_ERROR_CHECK(err_code); } else { // No keys found for this device err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL); APP_ERROR_CHECK(err_code); } break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT) { nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); // Configure buttons with sense level low as wakeup source. nrf_gpio_cfg_sense_input(WAKEUP_BUTTON_PIN, BUTTON_PULL, NRF_GPIO_PIN_SENSE_LOW); // Go to system-off mode (this function will not return; wakeup will cause a reset) err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; case BLE_EVT_TX_COMPLETE: if(!ble_buffer_available) tx_complete = true; break; default: // No implementation needed. break; } }
static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; // security-related static ble_gap_evt_auth_status_t m_auth_status; bool master_id_matches; ble_gap_sec_kdist_t * p_distributed_keys; ble_gap_enc_info_t * p_enc_info; ble_gap_irk_t * p_id_info; ble_gap_sign_info_t * p_sign_info; static ble_gap_enc_key_t m_enc_key; /**< Encryption Key (Encryption Info and Master ID). */ static ble_gap_id_key_t m_id_key; /**< Identity Key (IRK and address). */ static ble_gap_sign_info_t m_sign_key; /**< Signing Key (Connection Signature Resolving Key). */ static ble_gap_sec_keyset_t m_keys = {.keys_periph = {&m_enc_key, &m_id_key, &m_sign_key}}; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: //on BLE connect event m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; BLEonConnect(); break; case BLE_GAP_EVT_DISCONNECTED: //on BLE disconnect event m_conn_handle = BLE_CONN_HANDLE_INVALID; //debug_log("Disconnect reason: %d\r\n",(int)p_ble_evt->evt.gap_evt.params.disconnected.reason); BLEonDisconnect(); break; case BLE_GAP_EVT_ADV_REPORT: //On receipt of a response to an advertising request (during a scan) BLEonAdvReport(&(p_ble_evt->evt.gap_evt.params.adv_report)); break; case BLE_GAP_EVT_TIMEOUT: if(p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN) { //debug_log("Scan ended\r\n"); BLEonScanTimeout(); } /*else { debug_log("Timeout. src=%d\r\n", p_ble_evt->evt.gap_evt.params.timeout.src); }*/ break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params, &m_keys); BLE_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS); BLE_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status; break; case BLE_GAP_EVT_SEC_INFO_REQUEST: master_id_matches = memcmp(&p_ble_evt->evt.gap_evt.params.sec_info_request.master_id, &m_enc_key.master_id, sizeof(ble_gap_master_id_t)) == 0; p_distributed_keys = &m_auth_status.kdist_periph; p_enc_info = (p_distributed_keys->enc && master_id_matches) ? &m_enc_key.enc_info : NULL; p_id_info = (p_distributed_keys->id && master_id_matches) ? &m_id_key.id_info : NULL; p_sign_info = (p_distributed_keys->sign && master_id_matches) ? &m_sign_key : NULL; err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, p_id_info, p_sign_info); BLE_ERROR_CHECK(err_code); break; default: break; } }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; static uint16_t s_conn_handle = BLE_CONN_HANDLE_INVALID; static ble_gap_sec_keyset_t s_sec_keyset; ble_gap_enc_info_t * p_enc_info; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); s_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); advertising_start(); break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: s_sec_keyset.keys_central.p_enc_key = NULL; s_sec_keyset.keys_central.p_id_key = NULL; s_sec_keyset.keys_central.p_enc_key = NULL; err_code = sd_ble_gap_sec_params_reply(s_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params, &s_sec_keyset); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(s_conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_SEC_INFO_REQUEST: if (s_sec_keyset.keys_periph.p_enc_key != NULL) { p_enc_info = &s_sec_keyset.keys_periph.p_enc_key->enc_info; err_code = sd_ble_gap_sec_info_reply(s_conn_handle, p_enc_info, NULL, NULL); APP_ERROR_CHECK(err_code); } else { // No keys found for this device. err_code = sd_ble_gap_sec_info_reply(s_conn_handle, NULL, NULL, NULL); APP_ERROR_CHECK(err_code); } break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); err_code = app_button_disable(); APP_ERROR_CHECK(err_code); if (err_code == NRF_SUCCESS) { // Configure buttons with sense level low as wakeup source. // err_code = bsp_buttons_enable((1 << BLE_BUTTON_ID) | (1 << GZLL_BUTTON_ID)); // nrf_gpio_cfg_sense_input(BLE_BUTTON_PIN_NO, // BUTTON_PULL, // NRF_GPIO_PIN_SENSE_LOW); // // nrf_gpio_cfg_sense_input(GZLL_BUTTON_PIN_NO, // BUTTON_PULL, // NRF_GPIO_PIN_SENSE_LOW); // Go to system-off mode. // (this function will not return; wakeup will cause a reset) err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } } break; default: // No implementation needed. break; } }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code = NRF_SUCCESS; static ble_gap_evt_auth_status_t m_auth_status; ble_gap_enc_info_t * p_enc_info; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: nrf_gpio_pin_set(CONNECTED_LED_PIN_N); nrf_gpio_pin_clear(ADVERTISING_LED_PIN_N); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; err_code = app_button_enable(); break; case BLE_GAP_EVT_DISCONNECTED: nrf_gpio_pin_clear(CONNECTED_LED_PIN_N); m_conn_handle = BLE_CONN_HANDLE_INVALID; err_code = app_button_disable(); if (err_code == NRF_SUCCESS) { advertising_start(); } break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0); break; case BLE_GAP_EVT_AUTH_STATUS: m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status; break; case BLE_GAP_EVT_SEC_INFO_REQUEST: p_enc_info = &m_auth_status.periph_keys.enc_info; if (p_enc_info->div == p_ble_evt->evt.gap_evt.params.sec_info_request.div) { err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, NULL); } else { // No keys found for this device err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL); } break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT) { nrf_gpio_pin_clear(ADVERTISING_LED_PIN_N); // Go to system-off mode (this function will not return; wakeup will cause a reset) GPIO_WAKEUP_BUTTON_CONFIG(WAKEUP_BUTTON_PIN); uart_tx_str("reset by timeout"); err_code = sd_power_system_off(); } break; case BLE_GATTS_EVT_WRITE: break; case BLE_GAP_EVT_CONN_PARAM_UPDATE: nrf_gpio_pin_toggle (LEDBUTTON_LED_PIN_NO); break; default: break; } APP_ERROR_CHECK(err_code); }
bool GAPController::bleConnectionEventHandler(ble_evt_t* bleEvent) { u32 err = 0; //Depending on the type of the BLE event, we have to do different stuff //Further Events: http://developer.nordicsemi.com/nRF51_SDK/doc/7.1.0/s120/html/a00746.html#gada486dd3c0cce897b23a887bed284fef switch (bleEvent->header.evt_id) { //************************** GAP ***************************** //########## Connection with other device case BLE_GAP_EVT_CONNECTED: { currentlyConnecting = false; // Our advertisement stopped because we received a connection on this packet (we are peripheral) if (bleEvent->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_PERIPH){ AdvertisingController::AdvertisingInterruptedBecauseOfIncomingConnectionHandler(); } logt("C", "Connected device"); //Connection stops advertising connectionSuccessCallback(bleEvent); return true; } //########## Another Device disconnected case BLE_GAP_EVT_DISCONNECTED: { logt("C", "Disconnected device %d", bleEvent->evt.gap_evt.params.disconnected.reason); disconnectionCallback(bleEvent); return true; } break; case BLE_GAP_EVT_TIMEOUT: { if (bleEvent->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN) { currentlyConnecting = false; connectionTimeoutCallback(bleEvent); } break; } //The other device requested an encrypted connection case BLE_GAP_EVT_SEC_INFO_REQUEST: { //With this request, we receive the key identifier and a random number //This identification is used to select the correct key //We skip that process and select our mesh network key //TODO: Check what to do when we want different keys for Modules e.g. ble_gap_evt_sec_info_request_t securityRequest = bleEvent->evt.gap_evt.params.sec_info_request; //This is our security key ble_gap_enc_info_t key; key.auth = 1; //This key is authenticated memcpy(&key.ltk, Node::getInstance()->persistentConfig.networkKey, 16); //Copy our mesh network key key.ltk_len = 16; //Reply with our stored key err = sd_ble_gap_sec_info_reply( bleEvent->evt.gap_evt.conn_handle, &key, //This is our stored long term key NULL, //We do not have an identity resolving key NULL //We do not have signing info ); APP_ERROR_CHECK(err); logt("SEC", "SEC_INFO_REQUEST received, replying with key. result %d", err); break; } //This event tells us that the security keys are now in use case BLE_GAP_EVT_CONN_SEC_UPDATE: { u8 keySize = bleEvent->evt.gap_evt.params.conn_sec_update.conn_sec.encr_key_size; u8 level = bleEvent->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv; u8 securityMode = bleEvent->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm; logt("SEC", "Connection key is now %u bytes, level %u, securityMode %u", keySize, level, securityMode); if(connectionEncryptedCallback) connectionEncryptedCallback(bleEvent); break; } //Another device wants to initiate a secure connection //Currently not used because the other method worked pretty good /*case BLE_GAP_EVT_SEC_PARAMS_REQUEST: { //Security parameters: What is provided and what capabilities do we have? ble_gap_sec_params_t securityParameters; securityParameters.bond = 0; //We do not want to bond securityParameters.mitm = 1; //We need man in the middle protection securityParameters.io_caps = BLE_GAP_IO_CAPS_KEYBOARD_ONLY; //Use this if we want OOB method securityParameters.oob = 1; //We have out of band data (our mesh network key) securityParameters.min_key_size = 16; //We want 128bit key securityParameters.max_key_size = 16; //yes, we do securityParameters.kdist_periph.enc = 1; //We will provide a long term key for the connection securityParameters.kdist_periph.id = 0; //We do not provide an identity resolving key securityParameters.kdist_periph.sign = 0; //We do not provide a signature resolving key //Mhhh, ....? securityParameters.kdist_central.enc = 1; securityParameters.kdist_central.id = 0; securityParameters.kdist_central.sign = 0; ble_gap_enc_key_t key; key.enc_info.auth = 1; memcpy(&key.enc_info.ltk, &Config->meshNetworkKey, 16); key.enc_info.ltk_len = 16; key.master_id.ediv = 123; key.master_id.rand[0] = 234; //Keys ble_gap_sec_keyset_t keys; keys.keys_periph.p_enc_key = &key; keys.keys_periph.p_id_key = NULL; keys.keys_periph.p_sign_key = NULL; keys.keys_central.p_enc_key = &key; keys.keys_central.p_id_key = NULL; keys.keys_central.p_sign_key = NULL; //If we are central if(TestModule::isCentral) { err = sd_ble_gap_sec_params_reply( bleEvent->evt.gap_evt.conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, NULL, &keys ); logt("SEC", "SEC_PARAMS_REQUEST received as central, replying with result %d", err); } //We assume that we are peripheral else if(!TestModule::isCentral) { //TODO: Check if we are peripheral err = sd_ble_gap_sec_params_reply( bleEvent->evt.gap_evt.conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &securityParameters, &keys ); APP_ERROR_CHECK(err); } logt("SEC", "SEC_PARAMS_REQUEST received as peripheral, replying with result %d", err); break; } case BLE_GAP_EVT_AUTH_KEY_REQUEST: { err = sd_ble_gap_auth_key_reply( bleEvent->evt.gap_evt.conn_handle, BLE_GAP_AUTH_KEY_TYPE_OOB, Config->meshNetworkKey ); APP_ERROR_CHECK(err); logt("SEC", "AUTH_KEY_REQUEST received, replying with result %d", err); break; } case BLE_GAP_EVT_AUTH_STATUS: { logt("SEC", "AUTH_STATUS: status %u", bleEvent->evt.gap_evt.params.auth_status.auth_status); logt("SEC", "AUTH_STATUS: bonded %u", bleEvent->evt.gap_evt.params.auth_status.bonded); break; }*/ default: break; } return false; }
void BLETransceiver::onBleEvt(ble_evt_t * p_ble_evt) { uint32_t err_code; static ble_gap_evt_auth_status_t m_auth_status; ble_gap_enc_info_t * p_enc_info; LOG_VERBOSE_LN("BLE event received : %d", p_ble_evt->header.evt_id); switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: //RP - 14/01/2015 - notify u16_connHandle = p_ble_evt->evt.gap_evt.conn_handle; b_isAdvertising = false; if(p_transceiverListener) { p_transceiverListener->onConnection(); } break; case BLE_GAP_EVT_DISCONNECTED: u16_connHandle = BLE_CONN_HANDLE_INVALID; if(p_transceiverListener) { p_transceiverListener->onDisconnection(); } break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(u16_connHandle, BLE_GAP_SEC_STATUS_SUCCESS, &secParams); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(u16_connHandle, NULL, 0); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status; break; case BLE_GAP_EVT_SEC_INFO_REQUEST: p_enc_info = &m_auth_status.periph_keys.enc_info; if (p_enc_info->div == p_ble_evt->evt.gap_evt.params.sec_info_request.div) { err_code = sd_ble_gap_sec_info_reply(u16_connHandle, p_enc_info, NULL); APP_ERROR_CHECK(err_code); } else { // No keys found for this device err_code = sd_ble_gap_sec_info_reply(u16_connHandle, NULL, NULL); APP_ERROR_CHECK(err_code); } break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT) { //RP - 14/01/2015 - notify // Configure buttons with sense level low as wakeup source. //RP do not power off // nrf_gpio_cfg_sense_input(WAKEUP_BUTTON_PIN, // BUTTON_PULL, // NRF_GPIO_PIN_SENSE_LOW); // Go to system-off mode (this function will not return; wakeup will cause a reset) // err_code = sd_power_system_off(); // APP_ERROR_CHECK(err_code); } break; case BLE_GAP_EVT_RSSI_CHANGED: if(p_transceiverListener) { p_transceiverListener->onRSSIChange(p_ble_evt->evt.gap_evt.params.rssi_changed.rssi); } break; default: // No implementation needed. break; } }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: // continue advertising nonconnectably app.conn_handle = p_ble_evt->evt.gap_evt.conn_handle; m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND; advertising_start(); break; case BLE_GAP_EVT_DISCONNECTED: app.conn_handle = BLE_CONN_HANDLE_INVALID; // advertise connectivity advertising_stop(); m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; advertising_start(); break; case BLE_GATTS_EVT_WRITE: { ble_gatts_evt_write_t* write_data = &(p_ble_evt->evt.gatts_evt.params.write); if (write_data->context.char_uuid.uuid == test_char_uuid16) { if (write_data->data[0] == 0x42) { //led_on(BLEES_LED_PIN); // enable higher connection interval. Only lasts for this connection ble_gap_conn_params_t gap_conn_params; memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = 0x06; // 7.5 ms gap_conn_params.max_conn_interval = MSEC_TO_UNITS(30, UNIT_1_25_MS); gap_conn_params.slave_latency = 0; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_conn_param_update(app.conn_handle, &gap_conn_params); APP_ERROR_CHECK(err_code); } } } break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(app.conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params, NULL); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(app.conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: break; case BLE_GAP_EVT_SEC_INFO_REQUEST: // No keys found for this device. err_code = sd_ble_gap_sec_info_reply(app.conn_handle, NULL, NULL, NULL); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; default: break; } }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { printf("on_ble_evt %d", p_ble_evt->header.evt_id); uint32_t err_code; static ble_gap_sec_keyset_t s_sec_keyset; ble_gap_enc_info_t * p_enc_info; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; bta_bleConnected(); break; case BLE_GAP_EVT_DISCONNECTED: m_conn_handle = BLE_CONN_HANDLE_INVALID; bta_bleDisconnected(); break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: s_sec_keyset.keys_periph.p_enc_key = NULL; err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params, &s_sec_keyset); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: // TODO: Adoptation to s110v8.0.0, is this needed anymore ? break; case BLE_GAP_EVT_SEC_INFO_REQUEST: if (s_sec_keyset.keys_periph.p_enc_key != NULL) { p_enc_info = &s_sec_keyset.keys_periph.p_enc_key->enc_info; err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, NULL, NULL); APP_ERROR_CHECK(err_code); } else { // No keys found for this device. err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL, NULL); APP_ERROR_CHECK(err_code); } break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { bta_bleAdvertiseTimeout(); } break; default: // No implementation needed. break; } }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; static ble_gap_evt_auth_status_t m_auth_status; ble_gap_enc_info_t * p_enc_info; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: nrf_gpio_pin_set(CONNECTED_LED_PIN_NO); nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; /* YOUR_JOB: Uncomment this part if you are using the app_button module to handle button events (assuming that the button events are only needed in connected state). If this is uncommented out here, 1. Make sure that app_button_disable() is called when handling BLE_GAP_EVT_DISCONNECTED below. 2. Make sure the app_button module is initialized. err_code = app_button_enable(); APP_ERROR_CHECK(err_code); */ break; case BLE_GAP_EVT_DISCONNECTED: nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO); m_conn_handle = BLE_CONN_HANDLE_INVALID; /* YOUR_JOB: Uncomment this part if you are using the app_button module to handle button events. This should be done to save power when not connected to a peer. err_code = app_button_disable(); APP_ERROR_CHECK(err_code); */ advertising_start(); break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status; break; case BLE_GAP_EVT_SEC_INFO_REQUEST: p_enc_info = &m_auth_status.periph_keys.enc_info; if (p_enc_info->div == p_ble_evt->evt.gap_evt.params.sec_info_request.div) { err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, NULL); APP_ERROR_CHECK(err_code); } else { // No keys found for this device err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL); APP_ERROR_CHECK(err_code); } break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT) { nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); // Configure buttons with sense level low as wakeup source. nrf_gpio_cfg_sense_input(WAKEUP_BUTTON_PIN, BUTTON_PULL, NRF_GPIO_PIN_SENSE_LOW); // Go to system-off mode (this function will not return; wakeup will cause a reset) err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; default: // No implementation needed. break; } }
/**@brief Application's BLE Stack event handler. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code = NRF_SUCCESS; static ble_gap_evt_auth_status_t m_auth_status; ble_gap_enc_info_t * p_enc_info; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: nrf_gpio_pin_set(LED_OTHER); BLESessionActive = 1; break; case BLE_GAP_EVT_DISCONNECTED: advertising_start(); BLESessionActive = 0; sendRawData = 0; do_post_processing = true; nrf_gpio_pin_clear(LED_OTHER); break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status; break; case BLE_GAP_EVT_SEC_INFO_REQUEST: p_enc_info = &m_auth_status.periph_keys.enc_info; if (p_enc_info->div == p_ble_evt->evt.gap_evt.params.sec_info_request.div) { err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, NULL); APP_ERROR_CHECK(err_code); } else { // No keys found for this device err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL); APP_ERROR_CHECK(err_code); } break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISEMENT) { //nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); // Go to system-off mode (this function will not return; wakeup will cause a reset) GPIO_WAKEUP_BUTTON_CONFIG(WAKEUP_BUTTON_PIN); err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; default: break; } APP_ERROR_CHECK(err_code); }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; static ble_gap_evt_auth_status_t m_auth_status; bool master_id_matches; ble_gap_sec_kdist_t * p_distributed_keys; ble_gap_enc_info_t * p_enc_info; ble_gap_irk_t * p_id_info; ble_gap_sign_info_t * p_sign_info; static ble_gap_enc_key_t m_enc_key; /**< Encryption Key (Encryption Info and Master ID). */ static ble_gap_id_key_t m_id_key; /**< Identity Key (IRK and address). */ static ble_gap_sign_info_t m_sign_key; /**< Signing Key (Connection Signature Resolving Key). */ static ble_gap_sec_keyset_t m_keys = {.keys_periph = {&m_enc_key, &m_id_key, &m_sign_key}}; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; /* YOUR_JOB: Uncomment this part if you are using the app_button module to handle button events (assuming that the button events are only needed in connected state). If this is uncommented out here, 1. Make sure that app_button_disable() is called when handling BLE_GAP_EVT_DISCONNECTED below. 2. Make sure the app_button module is initialized. err_code = app_button_enable(); APP_ERROR_CHECK(err_code); */ break; case BLE_GAP_EVT_DISCONNECTED: err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); m_conn_handle = BLE_CONN_HANDLE_INVALID; /* YOUR_JOB: Uncomment this part if you are using the app_button module to handle button events. This should be done to save power when not connected to a peer. err_code = app_button_disable(); APP_ERROR_CHECK(err_code); */ advertising_start(); break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params, &m_keys); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status; break; case BLE_GAP_EVT_SEC_INFO_REQUEST: master_id_matches = memcmp(&p_ble_evt->evt.gap_evt.params.sec_info_request.master_id, &m_enc_key.master_id, sizeof(ble_gap_master_id_t)) == 0; p_distributed_keys = &m_auth_status.kdist_periph; p_enc_info = (p_distributed_keys->enc && master_id_matches) ? &m_enc_key.enc_info : NULL; p_id_info = (p_distributed_keys->id && master_id_matches) ? &m_id_key.id_info : NULL; p_sign_info = (p_distributed_keys->sign && master_id_matches) ? &m_sign_key : NULL; err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, p_id_info, p_sign_info); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); // Configure buttons with sense level low as wakeup source. err_code = bsp_buttons_enable(1 << WAKEUP_BUTTON_ID); APP_ERROR_CHECK(err_code); // Go to system-off mode (this function will not return; wakeup will cause a reset) err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; default: // No implementation needed. break; } }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; static ble_gap_evt_auth_status_t m_auth_status; bool master_id_matches; ble_gap_sec_kdist_t * p_distributed_keys; ble_gap_enc_info_t * p_enc_info; ble_gap_irk_t * p_id_info; ble_gap_sign_info_t * p_sign_info; static ble_gap_enc_key_t m_enc_key; /**< Encryption Key (Encryption Info and Master ID). */ static ble_gap_id_key_t m_id_key; /**< Identity Key (IRK and address). */ static ble_gap_sign_info_t m_sign_key; /**< Signing Key (Connection Signature Resolving Key). */ static ble_gap_sec_keyset_t m_keys = {.keys_periph = {&m_enc_key, &m_id_key, &m_sign_key}}; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: m_conn_handle = BLE_CONN_HANDLE_INVALID; advertising_start(); break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params, &m_keys); APP_ERROR_CHECK(err_code);// Check for errors break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS); APP_ERROR_CHECK(err_code);// Check for errors break; case BLE_GAP_EVT_AUTH_STATUS: m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status; break; case BLE_GAP_EVT_SEC_INFO_REQUEST: master_id_matches = memcmp(&p_ble_evt->evt.gap_evt.params.sec_info_request.master_id, &m_enc_key.master_id, sizeof(ble_gap_master_id_t)) == 0; p_distributed_keys = &m_auth_status.kdist_periph; p_enc_info = (p_distributed_keys->enc && master_id_matches) ? &m_enc_key.enc_info : NULL; p_id_info = (p_distributed_keys->id && master_id_matches) ? &m_id_key.id_info : NULL; p_sign_info = (p_distributed_keys->sign && master_id_matches) ? &m_sign_key : NULL; err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, p_id_info, p_sign_info); APP_ERROR_CHECK(err_code);// Check for errors break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { // Go to system-off mode (this function will not return; wakeup will cause a reset) err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code);// Check for errors } break; default: // No implementation needed. break; } }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; static ble_gap_evt_auth_status_t m_auth_status; static ble_gap_master_id_t p_master_id; static ble_gap_sec_keyset_t keys_exchanged; SEGGER_RTT_WriteString(0,"\n--> IN on_ble_evt (a BLE event has come into main.c\n"); switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: SEGGER_RTT_WriteString(0,"\n... BLE_GAP_EVT_CONNECTED\n"); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: SEGGER_RTT_WriteString(0,"\n... BLE_GAP_EVT_DISCONNECTED\n"); m_conn_handle = BLE_CONN_HANDLE_INVALID; advertising_start(); break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: SEGGER_RTT_WriteString(0,"\n... BLE_GAP_EVT_SEC_PARAMS_REQUEST\n"); err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params,&keys_exchanged); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: SEGGER_RTT_WriteString(0,"\n... BLE_GATTS_EVT_SYS_ATTR_MISSING\n"); err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0,BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: SEGGER_RTT_WriteString(0,"\n... BLE_GAP_EVT_AUTH_STATUS\n"); m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status; break; case BLE_GAP_EVT_SEC_INFO_REQUEST: //p_enc_info = keys_exchanged.keys_central.p_enc_key SEGGER_RTT_WriteString(0,"\n... BLE_GAP_EVT_SEC_INFO_REQUEST\n"); if (p_master_id.ediv == p_ble_evt->evt.gap_evt.params.sec_info_request.master_id.ediv) { err_code = sd_ble_gap_sec_info_reply(m_conn_handle, &keys_exchanged.keys_central.p_enc_key->enc_info, &keys_exchanged.keys_central.p_id_key->id_info, NULL); APP_ERROR_CHECK(err_code); p_master_id.ediv = p_ble_evt->evt.gap_evt.params.sec_info_request.master_id.ediv; } else { // No keys found for this device err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL,NULL); APP_ERROR_CHECK(err_code); } break; case BLE_GAP_EVT_TIMEOUT: SEGGER_RTT_WriteString(0,"\n... BLE_GAP_EVT_TIMEOUT\n"); if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { // Go to system-off mode (this function will not return; wakeup will cause a reset) err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; default: SEGGER_RTT_WriteString(0,"\n... Not handling a BLE event here.\n"); // No implementation needed. break; } }
/**@brief Function for the Application's SoftDevice event handler. * * @param[in] p_ble_evt SoftDevice event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: dfu_set_status(DFUS_ADVERTISING_STOP); dfu_set_status(DFUS_CONNECTED); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; m_flags &= ~DFU_BLE_FLAG_IS_ADVERTISING; break; case BLE_GAP_EVT_DISCONNECTED: // Restart advertising so that the DFU Controller can reconnect if possible. dfu_set_status(DFUS_DISCONNECTED); err_code = advertising_start(); APP_ERROR_CHECK(err_code); m_conn_handle = BLE_CONN_HANDLE_INVALID; break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: { err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); APP_ERROR_CHECK(err_code); } break; case BLE_GATTS_EVT_TIMEOUT: if (p_ble_evt->evt.gatts_evt.params.timeout.src == BLE_GATT_TIMEOUT_SRC_PROTOCOL) { err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); } break; case BLE_EVT_USER_MEM_REQUEST: err_code = sd_ble_user_mem_reply(m_conn_handle, NULL); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: if (p_ble_evt->evt.gatts_evt.params.authorize_request.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID) { if (on_rw_authorize_req(&m_dfu, p_ble_evt)) { err_code = on_ctrl_pt_write(&m_dfu, &(p_ble_evt->evt.gatts_evt.params.authorize_request.request.write)); #ifdef NRF_DFU_DEBUG_VERSION if (err_code != NRF_SUCCESS) { NRF_LOG_ERROR("Could not handle on_ctrl_pt_write. err_code: 0x%04x\r\n", err_code); } #else // Swallow result (void) err_code; #endif } } break; case BLE_GAP_EVT_SEC_INFO_REQUEST: err_code = sd_ble_gap_sec_info_reply(p_ble_evt->evt.gap_evt.conn_handle, NULL, NULL, NULL); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(p_ble_evt->evt.gap_evt.conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_WRITE: on_write(&m_dfu, p_ble_evt); break; #if (NRF_SD_BLE_API_VERSION == 3) case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: err_code = sd_ble_gatts_exchange_mtu_reply(p_ble_evt->evt.gatts_evt.conn_handle, NRF_BLE_MAX_MTU_SIZE); APP_ERROR_CHECK(err_code); break; // BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST #endif default: // No implementation needed. break; } }
/** * @brief BLEスタックイベントハンドラ * * @param[in] p_ble_evt BLEスタックイベント */ static void ble_evt_handler(ble_evt_t *p_ble_evt) { uint32_t err_code; static ble_gap_evt_auth_status_t m_auth_status; bool master_id_matches; ble_gap_sec_kdist_t * p_distributed_keys; ble_gap_enc_info_t *p_enc_info; ble_gap_irk_t * p_id_info; ble_gap_sign_info_t * p_sign_info; static ble_gap_enc_key_t m_enc_key; /**< Encryption Key (Encryption Info and Master ID). */ static ble_gap_id_key_t m_id_key; /**< Identity Key (IRK and address). */ static ble_gap_sign_info_t m_sign_key; /**< Signing Key (Connection Signature Resolving Key). */ static ble_gap_sec_keyset_t sec_key = {.keys_periph = {&m_enc_key, &m_id_key, &m_sign_key}}; switch (p_ble_evt->header.evt_id) { /************* * GAP event *************/ //接続が成立したとき case BLE_GAP_EVT_CONNECTED: app_trace_log("BLE_GAP_EVT_CONNECTED\r\n"); led_on(LED_PIN_NO_CONNECTED); led_off(LED_PIN_NO_ADVERTISING); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; //相手から切断されたとき //必要があればsd_ble_gatts_sys_attr_get()でSystem Attributeを取得し、保持しておく。 //保持したSystem Attributeは、EVT_SYS_ATTR_MISSINGで返すことになる。 case BLE_GAP_EVT_DISCONNECTED: app_trace_log("BLE_GAP_EVT_DISCONNECTED\r\n"); led_off(LED_PIN_NO_CONNECTED); m_conn_handle = BLE_CONN_HANDLE_INVALID; app_ble_start(); break; //SMP Paring要求を受信したとき //sd_ble_gap_sec_params_reply()で値を返したあと、SMP Paring Phase 2に状態遷移する case BLE_GAP_EVT_SEC_PARAMS_REQUEST: app_trace_log("BLE_GAP_EVT_SEC_PARAMS_REQUEST\r\n"); { ble_gap_sec_params_t sec_param; sec_param.bond = SEC_PARAM_BOND; sec_param.mitm = SEC_PARAM_MITM; sec_param.io_caps = SEC_PARAM_IO_CAPABILITIES; sec_param.oob = SEC_PARAM_OOB; sec_param.min_key_size = SEC_PARAM_MIN_KEY_SIZE; sec_param.max_key_size = SEC_PARAM_MAX_KEY_SIZE; err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &sec_param, &sec_key); APP_ERROR_CHECK(err_code); } break; //Just Works(Bonding有り)の場合、SMP Paring Phase 3のあとでPeripheral Keyが渡される。 //ここではPeripheral Keyを保存だけしておき、次のBLE_GAP_EVT_SEC_INFO_REQUESTで処理する。 case BLE_GAP_EVT_AUTH_STATUS: app_trace_log("BLE_GAP_EVT_AUTH_STATUS\r\n"); m_auth_status = p_ble_evt->evt.gap_evt.params.auth_status; break; //SMP Paringが終わったとき? case BLE_GAP_EVT_SEC_INFO_REQUEST: app_trace_log("BLE_GAP_EVT_SEC_INFO_REQUEST\r\n"); master_id_matches = memcmp(&p_ble_evt->evt.gap_evt.params.sec_info_request.master_id, &m_enc_key.master_id, sizeof(ble_gap_master_id_t)) == 0; p_distributed_keys = &m_auth_status.kdist_periph; p_enc_info = (p_distributed_keys->enc && master_id_matches) ? &m_enc_key.enc_info : NULL; p_id_info = (p_distributed_keys->id && master_id_matches) ? &m_id_key.id_info : NULL; p_sign_info = (p_distributed_keys->sign && master_id_matches) ? &m_sign_key : NULL; err_code = sd_ble_gap_sec_info_reply(m_conn_handle, p_enc_info, p_id_info, p_sign_info); APP_ERROR_CHECK(err_code); break; //Advertisingか認証のタイムアウト発生 case BLE_GAP_EVT_TIMEOUT: app_trace_log("BLE_GAP_EVT_TIMEOUT\r\n"); switch (p_ble_evt->evt.gap_evt.params.timeout.src) { case BLE_GAP_TIMEOUT_SRC_ADVERTISING: //Advertisingのタイムアウト /* Advertising LEDを消灯 */ led_off(LED_PIN_NO_ADVERTISING); /* System-OFFにする(もう戻ってこない) */ err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); break; case BLE_GAP_TIMEOUT_SRC_SECURITY_REQUEST: //Security requestのタイムアウト break; default: break; } break; /********************* * GATT Server event *********************/ //接続後、Bondingした相手からSystem Attribute要求を受信したとき //System Attributeは、EVT_DISCONNECTEDで保持するが、今回は保持しないのでNULLを返す。 case BLE_GATTS_EVT_SYS_ATTR_MISSING: app_trace_log("BLE_GATTS_EVT_SYS_ATTR_MISSING\r\n"); err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS); APP_ERROR_CHECK(err_code); break; default: // No implementation needed. break; } }
// handler for application's BLE Stack events static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; switch(p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: app.conn_handle = p_ble_evt->evt.gap_evt.conn_handle; // resume advertising, but not connectably m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND; advertising_start(); break; case BLE_GAP_EVT_DISCONNECTED: app.conn_handle = BLE_CONN_HANDLE_INVALID; // go back to advertising connectably advertising_stop(); m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; advertising_start(); break; case BLE_GATTS_EVT_WRITE: //do to break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: err_code = sd_ble_gap_sec_params_reply(app.conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &m_sec_params, NULL); APP_ERROR_CHECK(err_code); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: err_code = sd_ble_gatts_sys_attr_set(app.conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_AUTH_STATUS: break; case BLE_GAP_EVT_SEC_INFO_REQUEST: // no keys found for this device err_code = sd_ble_gap_sec_info_reply(app.conn_handle, NULL, NULL, NULL); APP_ERROR_CHECK(err_code); break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; case BLE_GATTS_EVT_TIMEOUT: if (p_ble_evt->evt.gatts_evt.params.timeout.src == BLE_GATT_TIMEOUT_SRC_PROTOCOL) { err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); } break; default: break; } }