/**@brief Function for fetching BLE events from the S110 Stack. * * @param[in] p_event_data Unused by this function. * @param[in] event_size Unused by this function. */ static void stack_evt_get(void * p_event_data, uint16_t event_size) { // This function expects the p_event_data and event_size to be zero. This function will fetch // the event from the S110 Stack. UNUSED_PARAMETER(p_event_data); UNUSED_PARAMETER(event_size); for (;;) { uint32_t err_code; uint16_t evt_len = sizeof(m_evt_buffer); // Pull the event from stack. err_code = sd_ble_evt_get((uint8_t *) m_evt_buffer, &evt_len); if ((err_code == NRF_ERROR_NOT_FOUND) || (err_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED)) { // Either there are no more events OR the S110 Stack has been disabled. This additional // error code check is the only difference between this function and @ref // ble_stack_evt_get. This check is needed because the bootloader may have disabled // the S110 stack after finishing the firmware update. break; } else if (err_code != NRF_SUCCESS) { APP_ERROR_HANDLER(err_code); } // Call the BLE stack event handler. ble_evt_dispatch((ble_evt_t *)m_evt_buffer); } }
/** * @brief Softdevice event handler */ void SD_EVT_IRQHandler(void) { rbc_mesh_sd_irq_handler(); ble_evt_t ble_evt; uint16_t len = sizeof(ble_evt); while (sd_ble_evt_get((uint8_t*) &ble_evt, &len) == NRF_SUCCESS) { nrf_adv_conn_evt_handler(&ble_evt); } }
static void uart_init(void) { #ifdef USE_UART_LOGGING int status = NRF_SUCCESS; const app_uart_comm_params_t uart_params = { .rx_pin_no = RX_PIN_NUMBER, .tx_pin_no = TX_PIN_NUMBER, .rts_pin_no = RTS_PIN_NUMBER, .cts_pin_no = CTS_PIN_NUMBER, .flow_control = APP_UART_FLOW_CONTROL_ENABLED, .use_parity = false, .baud_rate = UART_BAUDRATE_BAUDRATE_Baud38400 }; APP_UART_FIFO_INIT(&uart_params, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE, uart_event_handler, APP_IRQ_PRIORITY_LOW, status); APP_ERROR_CHECK(status); #endif } static void uart_putstring(const uint8_t * string) { #ifdef USE_UART_LOGGING for(int i = 0; string[i] != 0; ++i) app_uart_put(string[i]); #endif } /** * Interrupt handler for Softdevice events */ void SD_EVT_IRQHandler(void) { uint32_t evt; ble_evt_t ble_evt; uint16_t len; while(sd_evt_get(&evt) == NRF_SUCCESS) { btle_hci_adv_sd_evt_handler(evt); } while (sd_ble_evt_get((uint8_t *) &evt, &len) == NRF_SUCCESS) { nrf_adv_conn_evt_handler(&ble_evt); } }
void SD_EVT_IRQHandler(void) { uint8_t evt_buf[sizeof(ble_evt_t) + BLE_L2CAP_MTU_DEF]; uint16_t evt_len; ble_evt_t *p_ble_evt = (ble_evt_t *) evt_buf; uint32_t event; while ( sd_evt_get(&event) == NRF_SUCCESS ) { sys_evt_dispatch(event); } evt_len = sizeof(evt_buf); while (sd_ble_evt_get(evt_buf, &evt_len) == NRF_SUCCESS) { ble_evt_dispatch(p_ble_evt); evt_len = sizeof(evt_buf); } }
/**@brief BLE Stack event interrupt * Triggered whenever an event is ready to be pulled */ void SD_EVT_IRQHandler (void) { uint32_t evt; ble_evt_t ble_evt; uint16_t len; while (sd_evt_get(&evt) == NRF_SUCCESS) { g_evt = evt; switch (evt) { case NRF_EVT_RADIO_SESSION_IDLE: case NRF_EVT_RADIO_BLOCKED: /* Request a new timeslot */ ASSERT (btle_scan_enable_set (scan_enable) == BTLE_STATUS_CODE_SUCCESS); break; case NRF_EVT_RADIO_SESSION_CLOSED: break; case NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN: ASSERT(false); break; case NRF_EVT_RADIO_CANCELED: ASSERT (btle_scan_enable_set (scan_enable) == BTLE_STATUS_CODE_SUCCESS); break; default: /* This should not happen */ __LOG ("%s: Program failure, undefined event = %d", __FUNCTION__, evt); ASSERT(false); } } while (sd_ble_evt_get((uint8_t *) &evt, &len) == NRF_SUCCESS) { nrf_adv_conn_evt_handler(&ble_evt); } }
CU_TEST_END // This test case is intended to test that if an invalid (non-existing/unsupport) gap event is // received, then sd_ble_evt_get(...) shall return NRF_ERROR_NOT_FOUND. CU_TEST_START(gatts_evt_unsupported) { // Place holder for the actual decoded event length, size is 2 less (Too small). ble_evt_t actual_ble_evt = {{0}, {{0}}}; uint16_t actual_ble_evt_len = sizeof(actual_ble_evt); /**************************** Creation of the encoded input data ****************************/ /** The connected event as it looks on the wire (UART) */ uint8_t encoded_gatts_unsupported_evt[] = { BLE_RPC_PKT_EVT, (BLE_GATTS_EVT_LAST - 1), 0, // Evt ID - Doesn't exist. 0xaa, 0xbb, // Some data. 0xcc, 0xdd // Some data. }; uint16_t encoded_packet_length = 7; /**************************** Creation of the expected event ****************************/ /** We only validate that length can is returned correctly, without destroying the event. */ // NONE Needed as we verify unaligned pointer behavior. /**************************** Execution of the test / Verify decoder behavior ****************************/ // Simulate an event from the transport layer. -- Should stimulate an event from hci_transmport (evt. dispatcher) with pointer to RX buffer. // Execute the call to the decoder with the encoded data. // This should trigger an interrupt, and the data can be retrieved with sd_ble_evt_get(...) (void) ble_rpc_event_pkt_received(encoded_gatts_unsupported_evt, encoded_packet_length); uint32_t err_code = sd_ble_evt_get((uint8_t *)(&actual_ble_evt), &actual_ble_evt_len); CU_ASSERT_INT_EQUAL(err_code, NRF_ERROR_NOT_FOUND); CU_ASSERT_INT_EQUAL(actual_ble_evt_len, 0); nrf_cunit_verify_call_return(); }
void intern_softdevice_events_execute(void) { if (!m_softdevice_enabled) { // SoftDevice not enabled. This can be possible if the SoftDevice was enabled by the // application without using this module's API (i.e softdevice_handler_init) return; } bool no_more_soc_evts = (m_sys_evt_handler == NULL); #ifdef BLE_STACK_SUPPORT_REQD bool no_more_ble_evts = (m_ble_evt_handler == NULL); #endif #ifdef ANT_STACK_SUPPORT_REQD bool no_more_ant_evts = (m_ant_evt_handler == NULL); #endif for (;;) { uint32_t err_code; if (!no_more_soc_evts) { uint32_t evt_id; // Pull event from SOC. #if (defined(BLE_STACK_SUPPORT_REQD) && defined(ANT_STACK_SUPPORT_REQD)) || defined(ANT_STACK_SUPPORT_REQD) // Experimental: The S310 and S210 SoftDevices APIs have a differnt name for the // function to fetch the event. err_code = sd_event_get(&evt_id); #else err_code = sd_evt_get(&evt_id); #endif if (err_code == NRF_ERROR_NOT_FOUND) { no_more_soc_evts = true; } else if (err_code != NRF_SUCCESS) { APP_ERROR_HANDLER(err_code); } else { // Call application's SOC event handler. m_sys_evt_handler(evt_id); } } #ifdef BLE_STACK_SUPPORT_REQD // Fetch BLE Events. if (!no_more_ble_evts) { // Pull event from stack uint16_t evt_len = m_ble_evt_buffer_size; err_code = sd_ble_evt_get(m_evt_buffer, &evt_len); if (err_code == NRF_ERROR_NOT_FOUND) { no_more_ble_evts = true; } else if (err_code != NRF_SUCCESS) { APP_ERROR_HANDLER(err_code); } else { // Call application's BLE stack event handler. m_ble_evt_handler((ble_evt_t *)m_evt_buffer); } } #endif #ifdef ANT_STACK_SUPPORT_REQD // Fetch ANT Events. if (!no_more_ant_evts) { // Pull event from stack err_code = sd_ant_event_get(&((ant_evt_t *)m_evt_buffer)->channel, &((ant_evt_t *)m_evt_buffer)->event, ((ant_evt_t *)m_evt_buffer)->evt_buffer); if (err_code == NRF_ERROR_NOT_FOUND) { no_more_ant_evts = true; } else if (err_code != NRF_SUCCESS) { APP_ERROR_HANDLER(err_code); } else { // Call application's ANT stack event handler. m_ant_evt_handler((ant_evt_t *)m_evt_buffer); } } #endif if (no_more_soc_evts) { // There are no remaining System (SOC) events to be fetched from the SoftDevice. #if defined(ANT_STACK_SUPPORT_REQD) && defined(BLE_STACK_SUPPORT_REQD) // Check if there are any remaining BLE and ANT events. if (no_more_ble_evts && no_more_ant_evts) { break; } #elif defined(BLE_STACK_SUPPORT_REQD) // Check if there are any remaining BLE events. if (no_more_ble_evts) { break; } #elif defined(ANT_STACK_SUPPORT_REQD) // Check if there are any remaining ANT events. if (no_more_ant_evts) { break; } #else // No need to check for BLE or ANT events since there is no support for BLE and ANT // required. break; #endif } } }
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(); }
int main(void) { u32 err; //Initialize the UART Terminal Terminal::Init(); //Initialialize the SoftDevice and the BLE stack bleInit(); //Enable logging for some interesting log tags Logger::getInstance().enableTag("NODE"); Logger::getInstance().enableTag("STORAGE"); Logger::getInstance().enableTag("DATA"); Logger::getInstance().enableTag("SEC"); //Initialize the storage class Storage::getInstance(); //Init the magic node = new Node(Config->meshNetworkIdentifier); new Testing(); struct mallinfo used = mallinfo(); volatile u32 size = used.uordblks + used.hblkhd; //Start Timers initTimers(); while (true) { u32 err = NRF_ERROR_NOT_FOUND; //Check if there is input on uart Terminal::PollUART(); do { //Fetch the event sizeOfCurrentEvent = sizeOfEvent; err = sd_ble_evt_get(currentEventBuffer, &sizeOfCurrentEvent); //Handle ble event event if (err == NRF_SUCCESS) { //logt("EVENT", "--- EVENT_HANDLER %d -----", currentEvent->header.evt_id); bleDispatchEventHandler(currentEvent); } //No more events available else if (err == NRF_ERROR_NOT_FOUND) { //Handle Timer event that was waiting if (node && node->passsedTimeSinceLastTimerHandler > 0) { //Call the timer handler from the node node->TimerTickHandler(node->passsedTimeSinceLastTimerHandler); //Dispatch timer to all other modules timerEventDispatch(node->passsedTimeSinceLastTimerHandler, node->appTimerMs); node->passsedTimeSinceLastTimerHandler = 0; } err = sd_app_evt_wait(); APP_ERROR_CHECK(err); sd_nvic_ClearPendingIRQ(SD_EVT_IRQn); break; } else { APP_ERROR_CHECK(err); break; } } while (true); } }
CU_TEST_END CU_TEST_START(gatts_evt_write) { // Place holder for the actual decoded event. ble_evt_t actual_ble_evt = {{0}, {{0}}}; uint16_t actual_len = sizeof(actual_ble_evt); /**************************** Creation of the encoded input data ****************************/ /** The connected event as it looks on the wire (UART) */ uint8_t encoded_gatts_write_evt[] = { BLE_RPC_PKT_EVT, BLE_GATTS_EVT_WRITE, 0, // Evt ID 0x90, 0x78, // Conn Handle 0x56, 0x34, // Attribute handle 0x12, // Operation 0x01, 0x10, // service uuid 0x20, // service uuid type 0x03, 0x30, // char uuid 0x40, // char uuid type 0x05, 0x50, // desc uuid 0x60, // desc uuid type 0x07, 0x70, // Service handle 0x08, 0x80, // Value handle 0x90, // Attribute type 0x45, 0x54, // Offset 0x05, 0x00, // Data length 0x99, 0x88, 0x77, 0x66, 0x55 // Data }; uint16_t encoded_packet_length = 31; /**************************** Creation of the expected event ****************************/ /** The BLE event as it should look when it has been decoded and fetch by the application. */ uint32_t event_buffer[80 / sizeof(uint32_t)]; ble_evt_t * expected_ble_evt = (ble_evt_t *)event_buffer; memset(event_buffer, 0, 80); expected_ble_evt->header.evt_id = BLE_GATTS_EVT_WRITE; expected_ble_evt->header.evt_len = 33; expected_ble_evt->evt.gatts_evt.conn_handle = 0x7890; expected_ble_evt->evt.gatts_evt.params.write.handle = 0x3456; expected_ble_evt->evt.gatts_evt.params.write.op = 0x12; // context expected_ble_evt->evt.gatts_evt.params.write.context.srvc_uuid.uuid = 0x1001; expected_ble_evt->evt.gatts_evt.params.write.context.srvc_uuid.type = 0x20; expected_ble_evt->evt.gatts_evt.params.write.context.char_uuid.uuid = 0x3003; expected_ble_evt->evt.gatts_evt.params.write.context.char_uuid.type = 0x40; expected_ble_evt->evt.gatts_evt.params.write.context.desc_uuid.uuid = 0x5005; expected_ble_evt->evt.gatts_evt.params.write.context.desc_uuid.type = 0x60; expected_ble_evt->evt.gatts_evt.params.write.context.srvc_handle = 0x7007; expected_ble_evt->evt.gatts_evt.params.write.context.value_handle = 0x8008; expected_ble_evt->evt.gatts_evt.params.write.context.type = 0x90; expected_ble_evt->evt.gatts_evt.params.write.offset = 0x5445; expected_ble_evt->evt.gatts_evt.params.write.len = 0x5; expected_ble_evt->evt.gatts_evt.params.write.data[0] = 0x99; expected_ble_evt->evt.gatts_evt.params.write.data[1] = 0x88; //lint !e415 !e416 expected_ble_evt->evt.gatts_evt.params.write.data[2] = 0x77; //lint !e415 !e416 expected_ble_evt->evt.gatts_evt.params.write.data[3] = 0x66; //lint !e415 !e416 expected_ble_evt->evt.gatts_evt.params.write.data[4] = 0x55; //lint !e415 !e416 uint16_t expected_len = (uint16_t)(offsetof(ble_evt_t, evt.gatts_evt.params.write.data)); expected_len += expected_ble_evt->evt.gatts_evt.params.write.len; // One byte is already counted in the struct itself. /**************************** Execution of the test / Verify decoder behavior ****************************/ // Simulate an event from the transport layer. -- Should stimulate an event from hci_transmport (evt. dispatcher) with pointer to RX buffer. // Execute the call to the decoder with the encoded data. // This should trigger an interrupt, and the data can be retrieved with sd_ble_evt_get(...) (void) ble_rpc_event_pkt_received(encoded_gatts_write_evt, encoded_packet_length); // Fetch the decoded event and compare it to the expected. uint32_t err_code = sd_ble_evt_get((uint8_t *)(&actual_ble_evt), &actual_len); CU_ASSERT_INT_EQUAL(err_code, NRF_SUCCESS); CU_ASSERT(compare_ble_events(expected_ble_evt, expected_len, &actual_ble_evt, actual_len) == true); nrf_cunit_verify_call_return(); // CU_ASSERT(pull_and_verify_ble_evt(expected_ble_evt, expected_len) == true); }
void intern_softdevice_events_execute(void) { if (!m_softdevice_enabled) { // SoftDevice not enabled. This can be possible if the SoftDevice was enabled by the // application without using this module's API (i.e softdevice_handler_init) return; } #if NRF_MODULE_ENABLED(CLOCK) bool no_more_soc_evts = false; #else bool no_more_soc_evts = (m_sys_evt_handler == NULL); #endif #ifdef BLE_STACK_SUPPORT_REQD bool no_more_ble_evts = (m_ble_evt_handler == NULL); #endif #ifdef ANT_STACK_SUPPORT_REQD bool no_more_ant_evts = (m_ant_evt_handler == NULL); #endif for (;;) { uint32_t err_code; if (!no_more_soc_evts) { if (m_suspended) { // Cancel pulling next event if event handler was suspended by user. return; } uint32_t evt_id; // Pull event from SOC. err_code = sd_evt_get(&evt_id); if (err_code == NRF_ERROR_NOT_FOUND) { no_more_soc_evts = true; } else if (err_code != NRF_SUCCESS) { APP_ERROR_HANDLER(err_code); } else { // Call application's SOC event handler. #if (NRF_MODULE_ENABLED(CLOCK) && defined(SOFTDEVICE_PRESENT)) nrf_drv_clock_on_soc_event(evt_id); if (m_sys_evt_handler) { m_sys_evt_handler(evt_id); } #else m_sys_evt_handler(evt_id); #endif } } #ifdef BLE_STACK_SUPPORT_REQD // Fetch BLE Events. if (!no_more_ble_evts) { if (m_suspended) { // Cancel pulling next event if event handler was suspended by user. return; } // Pull event from stack uint16_t evt_len = m_ble_evt_buffer_size; err_code = sd_ble_evt_get(mp_ble_evt_buffer, &evt_len); if (err_code == NRF_ERROR_NOT_FOUND) { no_more_ble_evts = true; } else if (err_code != NRF_SUCCESS) { APP_ERROR_HANDLER(err_code); } else { // Call application's BLE stack event handler. m_ble_evt_handler((ble_evt_t *)mp_ble_evt_buffer); } } #endif #ifdef ANT_STACK_SUPPORT_REQD // Fetch ANT Events. if (!no_more_ant_evts) { if (m_suspended) { // Cancel pulling next event if event handler was suspended by user. return; } // Pull event from stack err_code = sd_ant_event_get(&m_ant_evt_buffer.channel, &m_ant_evt_buffer.event, m_ant_evt_buffer.msg.evt_buffer); if (err_code == NRF_ERROR_NOT_FOUND) { no_more_ant_evts = true; } else if (err_code != NRF_SUCCESS) { APP_ERROR_HANDLER(err_code); } else { // Call application's ANT stack event handler. m_ant_evt_handler(&m_ant_evt_buffer); } } #endif if (no_more_soc_evts) { // There are no remaining System (SOC) events to be fetched from the SoftDevice. #if defined(ANT_STACK_SUPPORT_REQD) && defined(BLE_STACK_SUPPORT_REQD) // Check if there are any remaining BLE and ANT events. if (no_more_ble_evts && no_more_ant_evts) { break; } #elif defined(BLE_STACK_SUPPORT_REQD) // Check if there are any remaining BLE events. if (no_more_ble_evts) { break; } #elif defined(ANT_STACK_SUPPORT_REQD) // Check if there are any remaining ANT events. if (no_more_ant_evts) { break; } #else // No need to check for BLE or ANT events since there is no support for BLE and ANT // required. break; #endif } } }