void ble_lmxs_on_ble_evt(ble_lmxs_t * p_lmxs, ble_evt_t * p_ble_evt) { switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: on_connect(p_lmxs, p_ble_evt); break; case BLE_GAP_EVT_DISCONNECTED: on_disconnect(p_lmxs, p_ble_evt); break; case BLE_GATTS_EVT_WRITE: { ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; GATMEMHDR *hdr = (GATMEMHDR *)g_GatWriteBuff; uint8_t *p = (uint8_t*)g_GatWriteBuff; if (p_evt_write->handle == 0 && p_evt_write->op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) { static char buff[256]; int len = 0; while (hdr->Handle == p_lmxs->char_handles.value_handle) { memcpy(buff + hdr->Offset, hdr->Data, hdr->Len); len += hdr->Len; p += hdr->Len + 6; hdr = (GATMEMHDR*)p; } p_lmxs->write_handler(p_lmxs, buff, 0, len);//p_evt_write->data); return; } else if ((p_evt_write->handle == p_lmxs->char_handles.value_handle) && (p_evt_write->len > 0) && (p_lmxs->write_handler != NULL)) { p_lmxs->write_handler(p_lmxs, p_evt_write->data, 0, p_evt_write->len); } } break; case BLE_EVT_USER_MEM_REQUEST: { uint32_t err_code; ble_user_mem_block_t mblk; memset(&mblk, 0, sizeof(ble_user_mem_block_t)); mblk.p_mem = g_GatWriteBuff; mblk.len = sizeof(g_GatWriteBuff); memset(g_GatWriteBuff, 0, sizeof(g_GatWriteBuff)); err_code = sd_ble_user_mem_reply(p_lmxs->conn_handle, &mblk); APP_ERROR_CHECK(err_code); } break; case BLE_EVT_USER_MEM_RELEASE: // err_code = sd_ble_user_mem_reply(g_EkoCCServ.conn_handle, NULL); // 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) { uint32_t err_code = NRF_SUCCESS; ble_gatts_rw_authorize_reply_params_t auth_reply; 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: m_conn_handle = BLE_CONN_HANDLE_INVALID; 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 ((p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) || (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) || (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)) { if (p_ble_evt->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; } else { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ; } auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED; err_code = sd_ble_gatts_rw_authorize_reply(m_conn_handle,&auth_reply); APP_ERROR_CHECK(err_code); } } break; case BLE_GATTS_OP_EXEC_WRITE_REQ_NOW: break; default: // No implementation needed. break; } }
/**@brief Function for handling BLE Stack events involving peripheral applications. Manages the * LEDs used to report the status of the peripheral applications. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_peripheral_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: NRF_LOG_PRINTF("Peripheral connected\r\n"); LEDS_OFF(PERIPHERAL_ADVERTISING_LED); LEDS_ON(PERIPHERAL_CONNECTED_LED); break; //BLE_GAP_EVT_CONNECTED case BLE_GAP_EVT_DISCONNECTED: NRF_LOG_PRINTF("Peripheral disconnected\r\n"); LEDS_OFF(PERIPHERAL_CONNECTED_LED); break;//BLE_GAP_EVT_DISCONNECTED case BLE_EVT_USER_MEM_REQUEST: err_code = sd_ble_user_mem_reply(p_ble_evt->evt.gap_evt.conn_handle, NULL); APP_ERROR_CHECK(err_code); break;//BLE_EVT_USER_MEM_REQUEST case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: { ble_gatts_rw_authorize_reply_params_t auth_reply; if(p_ble_evt->evt.gatts_evt.params.authorize_request.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID) { if ((p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) || (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) || (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)) { if (p_ble_evt->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; } else { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ; } auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED; err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gap_evt.conn_handle,&auth_reply); APP_ERROR_CHECK(err_code); } } }break;//BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST 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: 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); advertising_start(); 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). err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; case BLE_EVT_USER_MEM_REQUEST: mem_block.len = QUEUED_WRITE_BUFFER_SIZE; mem_block.p_mem = &queued_write_buffer[0]; err_code = sd_ble_user_mem_reply(m_conn_handle, &mem_block); //simple_uart_putstring("User mem request \r\n"); break; case BLE_EVT_USER_MEM_RELEASE: if ((p_ble_evt->evt.common_evt.params.user_mem_release.mem_block.p_mem == mem_block.p_mem)&&(p_ble_evt->evt.common_evt.params.user_mem_release.mem_block.len == mem_block.len)) { //memory released do nothing. //simple_uart_putstring("User mem released \r\n"); } break; case BLE_GATTS_EVT_WRITE: //simple_uart_putstring("Evt Write \r\n"); break; default: // No implementation needed. break; } }
/**@brief Function for handling 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; ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_ADV_REPORT: on_ble_gap_evt_adv_report(p_gap_evt); break; case BLE_GAP_EVT_CONNECTED: on_ble_gap_evt_connected(p_gap_evt); break; case BLE_GAP_EVT_DISCONNECTED: on_ble_gap_evt_disconnected(p_gap_evt); break; case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: { // Accept parameters requested by the peer. ble_gap_conn_params_t params; params = p_gap_evt->params.conn_param_update_request.conn_params; params.max_conn_interval = params.min_conn_interval; err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle, ¶ms); APP_ERROR_CHECK(err_code); } break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: { err_code = sd_ble_gatts_sys_attr_set(p_gap_evt->conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); } break; case BLE_GATTC_EVT_TIMEOUT: // Fallthrough. case BLE_GATTS_EVT_TIMEOUT: { NRF_LOG_DEBUG("GATT timeout, disconnecting.\r\n"); 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(p_ble_evt->evt.common_evt.conn_handle, NULL); APP_ERROR_CHECK(err_code); } break; default: // No implementation needed. break; } }
ret_code_t nrf_ble_escs_on_ble_evt(nrf_ble_escs_t * p_escs, ble_evt_t * p_ble_evt) { ret_code_t err_code; VERIFY_PARAM_NOT_NULL(p_escs); VERIFY_PARAM_NOT_NULL(p_ble_evt); switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: on_connect(p_escs, p_ble_evt); break; case BLE_GAP_EVT_DISCONNECTED: on_disconnect(p_escs, p_ble_evt); break; case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: err_code = on_rw_authorize_req(p_escs, p_ble_evt); VERIFY_SUCCESS(err_code); break; // BLE_EVT_USER_MEM_REQUEST & BLE_EVT_USER_MEM_RELEASE are for long writes to the RW ADV slot characteristic case BLE_EVT_USER_MEM_REQUEST: err_code = sd_ble_user_mem_reply(p_escs->conn_handle, &m_eid_mem_block); VERIFY_SUCCESS(err_code); break; case BLE_EVT_USER_MEM_RELEASE: break; default: // No implementation needed. break; } return NRF_SUCCESS; }
uint32_t conn_mw_ble_user_mem_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); ble_user_mem_block_t mem_block; ble_user_mem_block_t * p_mem_block = &mem_block; uint32_t err_code = NRF_SUCCESS; uint32_t user_mem_tab_index; uint16_t conn_handle; /* Allocate user memory context for SoftDevice */ uint32_t sd_err_code; err_code = ble_user_mem_reply_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_mem_block); SER_ASSERT(err_code == NRF_SUCCESS, err_code); if (p_mem_block != NULL) { //Use the context if p_mem_block was not null err_code = conn_ble_user_mem_context_create(&user_mem_tab_index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); m_conn_user_mem_table[user_mem_tab_index].conn_handle = conn_handle; m_conn_user_mem_table[user_mem_tab_index].mem_block.len = p_mem_block->len; p_mem_block = &(m_conn_user_mem_table[user_mem_tab_index].mem_block); } sd_err_code = sd_ble_user_mem_reply(conn_handle, p_mem_block); err_code = ble_user_mem_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); SER_ASSERT(err_code == NRF_SUCCESS, err_code); return err_code; }
static void ble_event_handler(ble_evt_t const * p_ble_evt, void * p_context){ //pm_on_ble_evt(p_ble_evt); switch (p_ble_evt->header.evt_id){ case BLE_GAP_EVT_DISCONNECTED: start_advertising(); break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: { const uint16_t conn = p_ble_evt->evt.gatts_evt.conn_handle; APP_ERROR_CHECK(sd_ble_gatts_sys_attr_set(conn, NULL, 0, 0)); } break; case BLE_GAP_EVT_ADV_REPORT: { if(_nsec_ble_scan_callback == NULL) { break; } const ble_gap_evt_adv_report_t * rp = &p_ble_evt->evt.gap_evt.params.adv_report; int8_t i = 0; while((rp->dlen - i) >= 2) { const uint8_t len = rp->data[i++] - 1; // The type is included in the length const uint8_t type = rp->data[i++]; const uint8_t * data = &rp->data[i]; i += len; if(type == BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME) { if(len == 8 && data[0] == 'N' && data[1] == 'S' && data[2] == 'E' && data[3] == 'C') { uint16_t other_id = 0; if(sscanf((const char *) &data[4], "%04hx", &other_id) == 1) { _nsec_ble_scan_callback(other_id, rp->peer_addr.addr, rp->rssi); } } } } } break; case BLE_GATTS_EVT_WRITE: { const ble_gatts_evt_write_t * event = &p_ble_evt->evt.gatts_evt.params.write; if(event->op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW){ on_execute_queued_write_commands(); } else{ on_characteristic_write_command_event(event); } break; } case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: { uint8_t type = p_ble_evt->evt.gatts_evt.params.authorize_request.type; if(type == BLE_GATTS_AUTHORIZE_TYPE_READ){ const ble_gatts_evt_read_t * event = &p_ble_evt->evt.gatts_evt.params.authorize_request.request.read; on_characteristic_read_request_event(event, p_ble_evt->evt.gatts_evt.conn_handle); } else if(type == BLE_GATTS_AUTHORIZE_TYPE_WRITE){ const ble_gatts_evt_write_t * event = &p_ble_evt->evt.gatts_evt.params.authorize_request.request.write; uint16_t connection_handle = p_ble_evt->evt.gatts_evt.conn_handle; switch(event->op){ case BLE_GATTS_OP_WRITE_REQ: on_characteristic_write_request_event(event, connection_handle); break; case BLE_GATTS_OP_PREP_WRITE_REQ: on_prepare_write_request(event, connection_handle); break; case BLE_GATTS_OP_EXEC_WRITE_REQ_NOW: on_execute_queued_write_requests(connection_handle); break; default: break; } } break; } case BLE_EVT_USER_MEM_REQUEST: { buffer = malloc(LONG_WRITE_MAX_LENGTH); ble_user_mem_block_t memory_block; memory_block.p_mem = buffer; memory_block.len = LONG_WRITE_MAX_LENGTH; volatile uint32_t error_code = sd_ble_user_mem_reply(p_ble_evt->evt.common_evt.conn_handle, &memory_block); APP_ERROR_CHECK(error_code); } break; case BLE_EVT_USER_MEM_RELEASE: free(p_ble_evt->evt.common_evt.params.user_mem_release.mem_block.p_mem); buffer = NULL; break; default: 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: isConnected = true; SEGGER_RTT_WriteString(0, "\nConnected to Bluetooth Device\n"); 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; // BLE_GAP_EVT_CONNECTED case BLE_GAP_EVT_DISCONNECTED: isConnected = false; SEGGER_RTT_WriteString(0, "\nDisconnected from Bluetooth Device\n"); err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); m_conn_handle = BLE_CONN_HANDLE_INVALID; break; // BLE_GAP_EVT_DISCONNECTED case BLE_GAP_EVT_SEC_PARAMS_REQUEST: // Pairing not supported 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; // BLE_GAP_EVT_SEC_PARAMS_REQUEST case BLE_GATTS_EVT_SYS_ATTR_MISSING: // No system attributes have been stored. err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); break; // BLE_GATTS_EVT_SYS_ATTR_MISSING case BLE_GATTC_EVT_TIMEOUT: // Disconnect on GATT Client timeout event. err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break; // BLE_GATTC_EVT_TIMEOUT case BLE_GATTS_EVT_TIMEOUT: // Disconnect on GATT Server timeout event. err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break; // BLE_GATTS_EVT_TIMEOUT case BLE_EVT_USER_MEM_REQUEST: err_code = sd_ble_user_mem_reply(p_ble_evt->evt.gattc_evt.conn_handle, NULL); APP_ERROR_CHECK(err_code); break; // BLE_EVT_USER_MEM_REQUEST case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: { ble_gatts_evt_rw_authorize_request_t req; ble_gatts_rw_authorize_reply_params_t auth_reply; req = p_ble_evt->evt.gatts_evt.params.authorize_request; if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID) { if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) || (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) || (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)) { if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; } else { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ; } auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED; err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle, &auth_reply); APP_ERROR_CHECK(err_code); } } } break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST #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 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 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: NRF_LOG_INFO("Connected\r\n"); err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; /* Disable advertising, so when disconnected it does not restart. */ advertising_disable(); break; // BLE_GAP_EVT_CONNECTED case BLE_GAP_EVT_DISCONNECTED: NRF_LOG_INFO("Disonnected\r\n"); m_conn_handle = BLE_CONN_HANDLE_INVALID; m_advertising_flag = 0; if (m_is_wl_changed) { // The whitelist has been modified, update it in the Peer Manager. err_code = pm_whitelist_set(m_whitelist_peers, m_whitelist_peer_cnt); APP_ERROR_CHECK(err_code); err_code = pm_device_identities_list_set(m_whitelist_peers, m_whitelist_peer_cnt); if (err_code != NRF_ERROR_NOT_SUPPORTED) { APP_ERROR_CHECK(err_code); } m_is_wl_changed = false; } break; // BLE_GAP_EVT_DISCONNECTED case BLE_GAP_EVT_AUTH_KEY_REQUEST: err_code = sd_ble_gap_auth_key_reply(p_ble_evt->evt.gap_evt.conn_handle, BLE_GAP_AUTH_KEY_TYPE_OOB, m_oob_auth_key.tk); APP_ERROR_CHECK(err_code); break; // BLE_GAP_EVT_AUTH_KEY_REQUEST case BLE_GAP_EVT_AUTH_STATUS: { if (p_ble_evt->evt.gap_evt.params.auth_status.auth_status == BLE_GAP_SEC_STATUS_SUCCESS) { /* Configure NFC launchapp data (requires stopping NFC tag emulation) */ err_code = nfc_t2t_emulation_stop(); APP_ERROR_CHECK(err_code); nfc_launchapp_data_set(); err_code = nfc_t2t_emulation_start(); APP_ERROR_CHECK(err_code); } }break; // BLE_GAP_EVT_AUTH_STATUS case BLE_GATTC_EVT_TIMEOUT: // Disconnect on GATT Client timeout event. NRF_LOG_DEBUG("GATT Client Timeout.\r\n"); err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break; // BLE_GATTC_EVT_TIMEOUT case BLE_GATTS_EVT_TIMEOUT: // Disconnect on GATT Server timeout event. NRF_LOG_DEBUG("GATT Server Timeout.\r\n"); err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break; // BLE_GATTS_EVT_TIMEOUT case BLE_EVT_USER_MEM_REQUEST: err_code = sd_ble_user_mem_reply(m_conn_handle, NULL); APP_ERROR_CHECK(err_code); break; // BLE_EVT_USER_MEM_REQUEST case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: { ble_gatts_evt_rw_authorize_request_t req; ble_gatts_rw_authorize_reply_params_t auth_reply; req = p_ble_evt->evt.gatts_evt.params.authorize_request; if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID) { if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) || (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) || (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)) { if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; } else { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ; } auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED; err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle, &auth_reply); APP_ERROR_CHECK(err_code); } } } break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST #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 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: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; NRF_LOG_INFO("Connected\r\n"); break; // BLE_GAP_EVT_CONNECTED 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; NRF_LOG_INFO("Disconnected\r\n"); break; // BLE_GAP_EVT_DISCONNECTED case BLE_GAP_EVT_SEC_PARAMS_REQUEST: // Pairing not supported 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; // BLE_GAP_EVT_SEC_PARAMS_REQUEST case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: { ble_gap_data_length_params_t dl_params; // Clearing the struct will effectivly set members to @ref BLE_GAP_DATA_LENGTH_AUTO memset(&dl_params, 0, sizeof(ble_gap_data_length_params_t)); err_code = sd_ble_gap_data_length_update(p_ble_evt->evt.gap_evt.conn_handle, &dl_params, NULL); APP_ERROR_CHECK(err_code); } break; case BLE_GATTS_EVT_SYS_ATTR_MISSING: // No system attributes have been stored. err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0); APP_ERROR_CHECK(err_code); break; // BLE_GATTS_EVT_SYS_ATTR_MISSING case BLE_GATTC_EVT_TIMEOUT: // Disconnect on GATT Client timeout event. err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break; // BLE_GATTC_EVT_TIMEOUT case BLE_GATTS_EVT_TIMEOUT: // Disconnect on GATT Server timeout event. err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break; // BLE_GATTS_EVT_TIMEOUT case BLE_EVT_USER_MEM_REQUEST: err_code = sd_ble_user_mem_reply(p_ble_evt->evt.gattc_evt.conn_handle, NULL); APP_ERROR_CHECK(err_code); break; // BLE_EVT_USER_MEM_REQUEST case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: { ble_gatts_evt_rw_authorize_request_t req; ble_gatts_rw_authorize_reply_params_t auth_reply; req = p_ble_evt->evt.gatts_evt.params.authorize_request; if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID) { if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) || (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) || (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)) { if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; } else { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ; } auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED; err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle, &auth_reply); APP_ERROR_CHECK(err_code); } } } break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST 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; ble_gatts_rw_authorize_reply_params_t auth_reply; 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); advertising_start(); 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); // enable buttons to wake-up from power off err_code = bsp_buttons_enable( (1 << WAKEUP_BUTTON_ID) |(1 << BOND_DELETE_ALL_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; case BLE_GAP_EVT_PASSKEY_DISPLAY: { char passkey[PASSKEY_LENGTH+1]; memcpy(passkey,p_ble_evt->evt.gap_evt.params.passkey_display.passkey,PASSKEY_LENGTH); passkey[PASSKEY_LENGTH] = 0; // Don't send delayed Security Request if security procedure is already in progress. err_code = app_timer_stop(m_sec_req_timer_id); APP_ERROR_CHECK(err_code); printf("Passkey: %s\n",passkey); 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 ((p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) || (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) || (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)) { if (p_ble_evt->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; } else { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ; } auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED; err_code = sd_ble_gatts_rw_authorize_reply(m_conn_handle,&auth_reply); APP_ERROR_CHECK(err_code); } } break; case BLE_GAP_EVT_AUTH_STATUS: case BLE_GAP_EVT_CONN_SEC_UPDATE: 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; //lint -save -e438 // Last value assigned to variable 'err_code' not used switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_DISCONNECTED: { NRF_LOG_PRINTF("[APP]: %s: BLE_GAP_EVT_DISCONNECTED\r\n", __func__); m_conn_handle = BLE_CONN_HANDLE_INVALID; /*check if the last connected peer had not used MITM, if so, delete its bond information*/ if (peer_to_be_deleted != PM_PEER_ID_INVALID) { ret_code_t ret_val = pm_peer_delete(peer_to_be_deleted); APP_ERROR_CHECK(ret_val); APP_LOG("Collector's bond deleted\r\n"); peer_to_be_deleted = PM_PEER_ID_INVALID; } // advertising_init(); // TODO: Check if this is correct, shouldn't be needed nrf_gpio_pin_clear(LED_1); }break;//BLE_GAP_EVT_DISCONNECTED case BLE_GAP_EVT_CONNECTED: { NRF_LOG_PRINTF("[APP]: %s: BLE_GAP_EVT_CONNECTED\r\n", __func__); peer_to_be_deleted = PM_PEER_ID_INVALID; m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; // Start Security Request timer. err_code = app_timer_start(m_sec_req_timer_id, SECURITY_REQUEST_DELAY, NULL); APP_ERROR_CHECK(err_code); }break;//BLE_GAP_EVT_CONNECTED case BLE_GATTS_EVT_TIMEOUT: NRF_LOG_PRINTF("[APP]: %s: BLE_GATTS_EVT_TIMEOUT\r\n", __func__); // Disconnect on GATT Server timeout events. err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break;//BLE_GATTS_EVT_TIMEOUT case BLE_GAP_EVT_SEC_PARAMS_REQUEST: NRF_LOG_DEBUG("BLE_GAP_EVT_SEC_PARAMS_REQUEST\r\n"); break;//BLE_GAP_EVT_SEC_PARAMS_REQUEST case BLE_GAP_EVT_PASSKEY_DISPLAY: { NRF_LOG_PRINTF("[APP]: %s: BLE_GAP_EVT_PASSKEY_DISPLAY\r\n", __func__); char passkey[PASSKEY_LENGTH+1]; memcpy(passkey,p_ble_evt->evt.gap_evt.params.passkey_display.passkey,PASSKEY_LENGTH); passkey[PASSKEY_LENGTH] = 0; // Don't send delayed Security Request if security procedure is already in progress. err_code = app_timer_stop(m_sec_req_timer_id); APP_ERROR_CHECK(err_code); NRF_LOG_PRINTF("Passkey: %s\r\n",passkey); }break;//BLE_GAP_EVT_PASSKEY_DISPLAY case BLE_EVT_USER_MEM_REQUEST: NRF_LOG_PRINTF("[APP]: %s: BLE_EVT_USER_MEM_REQUEST\r\n", __func__); err_code = sd_ble_user_mem_reply(m_conn_handle, NULL); APP_ERROR_CHECK(err_code); break;//BLE_EVT_USER_MEM_REQUEST case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: { NRF_LOG_PRINTF("[APP]: %s: BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST\r\n", __func__); ble_gatts_rw_authorize_reply_params_t auth_reply; if(p_ble_evt->evt.gatts_evt.params.authorize_request.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID) { if ((p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) || (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) || (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)) { if (p_ble_evt->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; } else { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ; } auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED; err_code = sd_ble_gatts_rw_authorize_reply(m_conn_handle,&auth_reply); APP_ERROR_CHECK(err_code); } } }break;//BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST default: // No implementation needed. break; } }
void nRF5xGattServer::hwCallback(const ble_evt_t *p_ble_evt) { GattAttribute::Handle_t handle_value; GattServerEvents::gattEvent_t eventType; const ble_gatts_evt_t *gattsEventP = &p_ble_evt->evt.gatts_evt; switch (p_ble_evt->header.evt_id) { case BLE_GATTS_EVT_WRITE: { /* There are 2 use case here: Values being updated & CCCD (indicate/notify) enabled */ /* 1.) Handle CCCD changes */ handle_value = gattsEventP->params.write.handle; int characteristicIndex = resolveCCCDHandleToCharIndex(handle_value); if ((characteristicIndex != -1) && (p_characteristics[characteristicIndex]->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY))) { uint16_t cccd_value = (gattsEventP->params.write.data[1] << 8) | gattsEventP->params.write.data[0]; /* Little Endian but M0 may be mis-aligned */ if (((p_characteristics[characteristicIndex]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE) && (cccd_value & BLE_GATT_HVX_INDICATION)) || ((p_characteristics[characteristicIndex]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) && (cccd_value & BLE_GATT_HVX_NOTIFICATION))) { eventType = GattServerEvents::GATT_EVENT_UPDATES_ENABLED; } else { eventType = GattServerEvents::GATT_EVENT_UPDATES_DISABLED; } handleEvent(eventType, p_characteristics[characteristicIndex]->getValueHandle()); return; } /* 2.) Changes to the characteristic value will be handled with other events below */ eventType = GattServerEvents::GATT_EVENT_DATA_WRITTEN; } break; case BLE_GATTS_EVT_HVC: /* Indication confirmation received */ eventType = GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED; handle_value = gattsEventP->params.hvc.handle; break; #if NRF_SD_BLE_API_VERSION >= 4 // This event has been renamed in API V4+ case BLE_GATTS_EVT_HVN_TX_COMPLETE: { handleDataSentEvent(p_ble_evt->evt.gatts_evt.params.hvn_tx_complete.count); return; } #else case BLE_EVT_TX_COMPLETE: { handleDataSentEvent(p_ble_evt->evt.common_evt.params.tx_complete.count); return; } #endif case BLE_GATTS_EVT_SYS_ATTR_MISSING: sd_ble_gatts_sys_attr_set(gattsEventP->conn_handle, NULL, 0, 0); return; case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: switch (gattsEventP->params.authorize_request.type) { case BLE_GATTS_AUTHORIZE_TYPE_READ: eventType = GattServerEvents::GATT_EVENT_READ_AUTHORIZATION_REQ; handle_value = gattsEventP->params.authorize_request.request.read.handle; break; case BLE_GATTS_AUTHORIZE_TYPE_WRITE: eventType = GattServerEvents::GATT_EVENT_WRITE_AUTHORIZATION_REQ; handle_value = gattsEventP->params.authorize_request.request.write.handle; break; default: return; } break; case BLE_EVT_USER_MEM_REQUEST: { uint16_t conn_handle = p_ble_evt->evt.common_evt.conn_handle; // allocate a new long request for this connection // NOTE: we don't care about the result at this stage, // it is not possible to cancel the operation anyway. // If the request was not allocated then it will gracefully failled // at subsequent stages. allocateLongWriteRequest(conn_handle); sd_ble_user_mem_reply(conn_handle, NULL); return; } default: return; } int characteristicIndex = resolveValueHandleToCharIndex(handle_value); if (characteristicIndex == -1) { // filter out the case were the request is a long one, // and there is no attribute handle provided uint8_t write_op = gattsEventP->params.authorize_request.request.write.op; if (eventType != GattServerEvents::GATT_EVENT_WRITE_AUTHORIZATION_REQ || (write_op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW && write_op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)) { return; } } /* Find index (charHandle) in the pool */ switch (eventType) { case GattServerEvents::GATT_EVENT_DATA_WRITTEN: { GattWriteCallbackParams cbParams = { /* .connHandle = */ gattsEventP->conn_handle, /* .handle = */ handle_value, /* .writeOp = */ static_cast<GattWriteCallbackParams::WriteOp_t>(gattsEventP->params.write.op), /* .offset = */ gattsEventP->params.write.offset, /* .len = */ gattsEventP->params.write.len, /* .data = */ gattsEventP->params.write.data }; handleDataWrittenEvent(&cbParams); break; } case GattServerEvents::GATT_EVENT_WRITE_AUTHORIZATION_REQ: { uint16_t conn_handle = gattsEventP->conn_handle; const ble_gatts_evt_write_t& input_req = gattsEventP->params.authorize_request.request.write; const uint16_t max_size = getBiggestCharacteristicSize(); // this is a long write request, handle it here. switch (input_req.op) { case BLE_GATTS_OP_PREP_WRITE_REQ: { // verify that the request is not outside of the possible range if ((input_req.offset + input_req.len) > max_size) { sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_invalid_offset_reply); releaseLongWriteRequest(conn_handle); return; } // find the write request long_write_request_t* req = findLongWriteRequest(conn_handle); if (!req) { sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_invalid_reply); return; } // initialize the first request by setting the offset if (req->length == 0) { req->attr_handle = input_req.handle; req->offset = input_req.offset; } else { // it should be the subsequent write if ((req->offset + req->length) != input_req.offset) { sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_invalid_offset_reply); releaseLongWriteRequest(conn_handle); return; } // it is not allowed to write multiple characteristic with the same request if (input_req.handle != req->attr_handle) { sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_invalid_reply); releaseLongWriteRequest(conn_handle); return; } } // start the copy of what is in input memcpy(req->data + req->length, input_req.data, input_req.len); // update the lenght of the data written req->length = req->length + input_req.len; // success, signal it to the softdevice ble_gatts_rw_authorize_reply_params_t reply = { /* .type = */ BLE_GATTS_AUTHORIZE_TYPE_WRITE, /* .params = */ { /* .write = */ { /* .gatt_status = */ BLE_GATT_STATUS_SUCCESS, /* .update = */ 1, /* .offset = */ input_req.offset, /* .len = */ input_req.len, /* .p_data = */ input_req.data } } }; sd_ble_gatts_rw_authorize_reply(conn_handle, &reply); } return; case BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL: { releaseLongWriteRequest(conn_handle); sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_succes_reply); } return; case BLE_GATTS_OP_EXEC_WRITE_REQ_NOW: { long_write_request_t* req = findLongWriteRequest(conn_handle); if (!req) { sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_invalid_reply); return; } GattWriteAuthCallbackParams cbParams = { /* .connHandle = */ conn_handle, /* .handle = */ req->attr_handle, /* .offset = */ req->offset, /* .len = */ req->length, /* .data = */ req->data, /* .authorizationReply = */ AUTH_CALLBACK_REPLY_SUCCESS /* the callback handler must leave this member * set to AUTH_CALLBACK_REPLY_SUCCESS if the client * request is to proceed. */ }; uint16_t write_authorization = p_characteristics[characteristicIndex]->authorizeWrite(&cbParams); // the user code didn't provide the write authorization, // just leave here. if (write_authorization != AUTH_CALLBACK_REPLY_SUCCESS) { // report the status of the operation in any cases sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_invalid_reply); releaseLongWriteRequest(conn_handle); return; } // FIXME can't use ::write here, this function doesn't take the offset into account ... ble_gatts_value_t value = { /* .len = */ req->length, /* .offset = */ req->offset, /* .p_value = */ req->data }; uint32_t update_err = sd_ble_gatts_value_set(conn_handle, req->attr_handle, &value); if (update_err) { sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_invalid_reply); releaseLongWriteRequest(conn_handle); return; } sd_ble_gatts_rw_authorize_reply(conn_handle, &write_auth_succes_reply); GattWriteCallbackParams writeParams = { /* .connHandle = */ conn_handle, /* .handle = */ req->attr_handle, /* .writeOp = */ static_cast<GattWriteCallbackParams::WriteOp_t>(input_req.op), /* .offset = */ req->offset, /* .len = */ req->length, /* .data = */ req->data, }; handleDataWrittenEvent(&writeParams); releaseLongWriteRequest(conn_handle); } return; } GattWriteAuthCallbackParams cbParams = { /* .connHandle = */ gattsEventP->conn_handle, /* .handle = */ handle_value, /* .offset = */ gattsEventP->params.authorize_request.request.write.offset, /* .len = */ gattsEventP->params.authorize_request.request.write.len, /* .data = */ gattsEventP->params.authorize_request.request.write.data, /* .authorizationReply = */ AUTH_CALLBACK_REPLY_SUCCESS /* the callback handler must leave this member * set to AUTH_CALLBACK_REPLY_SUCCESS if the client * request is to proceed. */ }; ble_gatts_rw_authorize_reply_params_t reply = { /* .type = */ BLE_GATTS_AUTHORIZE_TYPE_WRITE, /* .params = */ { /* .write = */ { /* .gatt_status = */ p_characteristics[characteristicIndex]->authorizeWrite(&cbParams), /* .update = */ 1, /* .offset = */ cbParams.offset, /* .len = */ cbParams.len, /* .p_data = */ cbParams.data } } }; if (reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS) { reply.params.write.update = 0; } sd_ble_gatts_rw_authorize_reply(gattsEventP->conn_handle, &reply); /* * If write-authorization is enabled for a characteristic, * AUTHORIZATION_REQ event (if replied with true) is *not* * followed by another DATA_WRITTEN event; so we still need * to invoke handleDataWritten(), much the same as we would * have done if write-authorization had not been enabled. */ if (reply.params.write.gatt_status == BLE_GATT_STATUS_SUCCESS) { GattWriteCallbackParams cbParams = { /* .connHandle = */ gattsEventP->conn_handle, /* .handle = */ handle_value, /* .writeOp = */ static_cast<GattWriteCallbackParams::WriteOp_t>(gattsEventP->params.authorize_request.request.write.op), /* .offset = */ gattsEventP->params.authorize_request.request.write.offset, /* .len = */ gattsEventP->params.authorize_request.request.write.len, /* .data = */ gattsEventP->params.authorize_request.request.write.data, }; handleDataWrittenEvent(&cbParams); } break; } case GattServerEvents::GATT_EVENT_READ_AUTHORIZATION_REQ: { GattReadAuthCallbackParams cbParams = { /* .connHandle = */ gattsEventP->conn_handle, /* .handle = */ handle_value, /* .offset = */ gattsEventP->params.authorize_request.request.read.offset, /* .len = */ 0, /* .data = */ NULL, /* .authorizationReply = */ AUTH_CALLBACK_REPLY_SUCCESS /* the callback handler must leave this member * set to AUTH_CALLBACK_REPLY_SUCCESS if the client * request is to proceed. */ }; ble_gatts_rw_authorize_reply_params_t reply = { /* .type = */ BLE_GATTS_AUTHORIZE_TYPE_READ, /* .params = */ { /* .read = */ { /* .gatt_status = */ p_characteristics[characteristicIndex]->authorizeRead(&cbParams) } } }; if (cbParams.authorizationReply == BLE_GATT_STATUS_SUCCESS) { if (cbParams.data != NULL) { reply.params.read.update = 1; reply.params.read.offset = cbParams.offset; reply.params.read.len = cbParams.len; reply.params.read.p_data = cbParams.data; } } sd_ble_gatts_rw_authorize_reply(gattsEventP->conn_handle, &reply); break; } default: handleEvent(eventType, handle_value); 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: NRF_LOG_INFO("Connected\r\n"); 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; // BLE_GAP_EVT_CONNECTED case BLE_GAP_EVT_DISCONNECTED: NRF_LOG_INFO("Disconnected, reason %d\r\n", p_ble_evt->evt.gap_evt.params.disconnected.reason); m_conn_handle = BLE_CONN_HANDLE_INVALID; break; // BLE_GAP_EVT_DISCONNECTED case BLE_GATTC_EVT_TIMEOUT: // Disconnect on GATT Client timeout event. NRF_LOG_DEBUG("GATT Client Timeout.\r\n"); err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break; // BLE_GATTC_EVT_TIMEOUT case BLE_GATTS_EVT_TIMEOUT: // Disconnect on GATT Server timeout event. NRF_LOG_DEBUG("GATT Server Timeout.\r\n"); err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break; // BLE_GATTS_EVT_TIMEOUT case BLE_EVT_USER_MEM_REQUEST: err_code = sd_ble_user_mem_reply(m_conn_handle, NULL); APP_ERROR_CHECK(err_code); break; // BLE_EVT_USER_MEM_REQUEST case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: { ble_gatts_evt_rw_authorize_request_t req; ble_gatts_rw_authorize_reply_params_t auth_reply; req = p_ble_evt->evt.gatts_evt.params.authorize_request; if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID) { if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) || (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) || (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)) { if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; } else { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ; } auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED; err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle, &auth_reply); APP_ERROR_CHECK(err_code); } } } break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST 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; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_DISCONNECTED: err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); break;//BLE_GAP_EVT_DISCONNECTED case BLE_GAP_EVT_CONNECTED: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); err_code = ble_db_discovery_start(&m_ble_db_discovery, p_ble_evt->evt.gap_evt.conn_handle); APP_ERROR_CHECK(err_code); break;//BLE_GAP_EVT_CONNECTED case BLE_GATTC_EVT_TIMEOUT: /* fall through */ case BLE_GATTS_EVT_TIMEOUT: // Disconnect on GATT Server and Client timeout events. err_code = sd_ble_gap_disconnect(m_ans_c.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); break;//BLE_GATTC_EVT_TIMEOUT and BLE_GATTS_EVT_TIMEOUT case BLE_EVT_USER_MEM_REQUEST: err_code = sd_ble_user_mem_reply(m_ans_c.conn_handle, NULL); APP_ERROR_CHECK(err_code); break;//BLE_EVT_USER_MEM_REQUEST case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: { ble_gatts_rw_authorize_reply_params_t auth_reply; if(p_ble_evt->evt.gatts_evt.params.authorize_request.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID) { if ((p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) || (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) || (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)) { if (p_ble_evt->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; } else { auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ; } auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED; err_code = sd_ble_gatts_rw_authorize_reply(m_ans_c.conn_handle,&auth_reply); APP_ERROR_CHECK(err_code); } } }break;//BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST default: // No implementation needed. break; } }