/**@brief Function for handling service discovery completion. * * @details This function will be used to determine if there are more services to be discovered, * and if so, initiate the discovery of the next service. * * @param[in] p_db_discovery Pointer to the DB Discovery Structure. * @param[in] conn_handle Connection Handle. */ static void on_srv_disc_completion(ble_db_discovery_t * p_db_discovery, uint16_t const conn_handle) { p_db_discovery->discoveries_count++; // Check if more services need to be discovered. if (p_db_discovery->discoveries_count < m_num_of_handlers_reg) { // Reset the current characteristic index since a new service discovery is about to start. p_db_discovery->curr_char_ind = 0; // Initiate discovery of the next service. p_db_discovery->curr_srv_ind++; ble_gatt_db_srv_t * p_srv_being_discovered; p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind]; // Reset the characteristic count in the current service to zero since a new service // discovery is about to start. p_srv_being_discovered->char_count = 0; NRF_LOG_INFO("Starting discovery of service with UUID 0x%x for Connection handle %d\r\n", p_srv_being_discovered->srv_uuid.uuid, conn_handle); uint32_t err_code; err_code = sd_ble_gattc_primary_services_discover ( conn_handle, SRV_DISC_START_HANDLE, &(p_srv_being_discovered->srv_uuid) ); if (err_code != NRF_SUCCESS) { p_db_discovery->discovery_in_progress = false; // Error with discovering the service. // Indicate the error to the registered user application. discovery_error_evt_trigger(p_db_discovery, err_code, conn_handle); m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; m_pending_user_evts[0].evt.conn_handle = conn_handle; // m_evt_handler(&m_pending_user_evts[0].evt); return; } } else { // No more service discovery is needed. p_db_discovery->discovery_in_progress = false; m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; m_pending_user_evts[0].evt.conn_handle = conn_handle; //m_evt_handler(&m_pending_user_evts[0].evt); } }
//Handle discovery is not currently used and should not be used during the discovery //phase because it adds additional packets and time to the handshake. It is better //To use the mesh write handle that is broadcasted in the join_me packet and //is sent with the initial cluster_welcome packet void GATTController::bleDiscoverHandles(u16 connectionHandle) { u32 err = 0; //At first we need to enumerate the services err = sd_ble_gattc_primary_services_discover(connectionHandle, 0x0001, &meshService.serviceUuid); APP_ERROR_CHECK(err); //Currently Unhandeled }
/**@brief Function for handling the Connect event. * * @param[in] p_ias_c Immediate Alert Service client structure. * @param[in] p_ble_evt Event received from the BLE stack. */ static uint32_t on_connect(ble_ias_c_t * p_ias_c, ble_evt_t const * p_ble_evt) { ble_uuid_t ias_uuid; p_ias_c->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; // Discover Immediate alert service BLE_UUID_BLE_ASSIGN(ias_uuid, BLE_UUID_IMMEDIATE_ALERT_SERVICE); return sd_ble_gattc_primary_services_discover(p_ias_c->conn_handle, START_HANDLE, &ias_uuid); }
uint32_t ble_db_discovery_start(ble_db_discovery_t * const p_db_discovery, uint16_t conn_handle) { if (p_db_discovery == NULL) { return NRF_ERROR_NULL; } if (!m_initialized) { return NRF_ERROR_INVALID_STATE; } if (m_num_of_handlers_reg == 0) { // No user modules were registered. There are no services to discover. return NRF_ERROR_INVALID_STATE; } if (p_db_discovery->discovery_in_progress) { return NRF_ERROR_BUSY; } ble_db_discovery_srv_t * p_srv_being_discovered; m_num_of_discoveries_made = 0; m_pending_usr_evt_index = 0; p_db_discovery->curr_srv_ind = 0; p_db_discovery->conn_handle = conn_handle; p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind].srv_uuid; DB_LOG("[DB]: Starting discovery of service with UUID 0x%x for Connection handle %d\r\n", p_srv_being_discovered->srv_uuid.uuid, p_db_discovery->conn_handle); uint32_t err_code; err_code = sd_ble_gattc_primary_services_discover(p_db_discovery->conn_handle, SRV_DISC_START_HANDLE, &(p_srv_being_discovered->srv_uuid)); if (err_code != NRF_SUCCESS) { return err_code; } p_db_discovery->discovery_in_progress = true; return NRF_SUCCESS; }
/**@brief Function for handling service discovery completion. * * @details This function will be used to determine if there are more services to be discovered, * and if so, initiate the discovery of the next service. * * @param[in] p_db_discovery Pointer to the DB Discovery Structure. */ static void on_srv_disc_completion(ble_db_discovery_t * p_db_discovery) { m_num_of_discoveries_made++; // Check if more services need to be discovered. if (m_num_of_discoveries_made < m_num_of_handlers_reg) { // Reset the current characteristic index since a new service discovery is about to start. p_db_discovery->curr_char_ind = 0; // Initiate discovery of the next service. p_db_discovery->curr_srv_ind++; ble_db_discovery_srv_t * p_srv_being_discovered; p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind].srv_uuid; // Reset the characteristic count in the current service to zero since a new service // discovery is about to start. p_srv_being_discovered->char_count = 0; DB_LOG("[DB]: Starting discovery of service with UUID 0x%x for Connection handle %d\r\n", p_srv_being_discovered->srv_uuid.uuid, p_db_discovery->conn_handle); uint32_t err_code; err_code = sd_ble_gattc_primary_services_discover ( p_db_discovery->conn_handle, SRV_DISC_START_HANDLE, &(p_srv_being_discovered->srv_uuid) ); if (err_code != NRF_SUCCESS) { p_db_discovery->discovery_in_progress = false; // Error with discovering the service. // Indicate the error to the registered user application. discovery_error_evt_trigger(p_db_discovery, err_code); return; } } else { // No more service discovery is needed. p_db_discovery->discovery_in_progress = false; } }
uint32_t ble_db_discovery_start(ble_db_discovery_t * const p_db_discovery, uint16_t conn_handle) { VERIFY_PARAM_NOT_NULL(p_db_discovery); VERIFY_MODULE_INITIALIZED(); if (m_num_of_handlers_reg == 0) { // No user modules were registered. There are no services to discover. return NRF_ERROR_INVALID_STATE; } if (p_db_discovery->discovery_in_progress) { return NRF_ERROR_BUSY; } p_db_discovery->conn_handle = conn_handle; ble_gatt_db_srv_t * p_srv_being_discovered; m_pending_usr_evt_index = 0; p_db_discovery->discoveries_count = 0; p_db_discovery->curr_srv_ind = 0; p_db_discovery->curr_char_ind = 0; p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind]; NRF_LOG_INFO("Starting discovery of service with UUID 0x%x for Connection handle %d\r\n", p_srv_being_discovered->srv_uuid.uuid, conn_handle); uint32_t err_code; err_code = sd_ble_gattc_primary_services_discover(conn_handle, SRV_DISC_START_HANDLE, &(p_srv_being_discovered->srv_uuid)); VERIFY_SUCCESS(err_code); p_db_discovery->discovery_in_progress = true; return NRF_SUCCESS; }
/**@brief Function for executing the Service Discovery Procedure. */ static void service_disc_req_send(const ble_ans_c_t * p_ans) { uint16_t handle = START_HANDLE_DISCOVER; ble_uuid_t ans_uuid; uint32_t err_code; // Discover services on uuid Alert Notification. BLE_UUID_BLE_ASSIGN(ans_uuid, BLE_UUID_ALERT_NOTIFICATION_SERVICE); err_code = sd_ble_gattc_primary_services_discover(p_ans->conn_handle, handle, &ans_uuid); if (err_code != NRF_SUCCESS) { handle_discovery_failure(p_ans, err_code); } else { m_client_state = STATE_DISC_SERV; } }
/**@brief Function for executing the Service Discovery Procedure. */ static void service_disc_req_send(const ble_ancs_c_t * p_ancs) { uint16_t handle = START_HANDLE_DISCOVER; ble_uuid_t ancs_uuid; uint32_t err_code; // Discover services on uuid for ANCS. BLE_UUID_BLE_ASSIGN(ancs_uuid, BLE_UUID_APPLE_NOTIFICATION_CENTER_SERVICE); ancs_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN; err_code = sd_ble_gattc_primary_services_discover(p_ancs->conn_handle, handle, &ancs_uuid); if (err_code != NRF_SUCCESS) { handle_discovery_failure(p_ancs, err_code); } else { m_client_state = STATE_DISC_SERV; } }
uint32_t ble_db_discovery_start(ble_db_discovery_t * const p_db_discovery, uint16_t conn_handle) { if (p_db_discovery == NULL) { return NRF_ERROR_NULL; } if (!m_initialized) { return NRF_ERROR_INVALID_STATE; } p_db_discovery->srv_being_discovered.srv_uuid = m_srv_uuid; p_db_discovery->conn_handle = conn_handle; DB_LOG("[DB]: Starting service discovery\r\n"); return sd_ble_gattc_primary_services_discover(p_db_discovery->conn_handle, SRV_DISC_START_HANDLE, &m_srv_uuid); }
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(); }