/**@brief Function for handling BLE_GAP_EVT_CONNECTED events. * Save the connection handle and GAP role, then discover the peer DB. */ void on_ble_gap_evt_connected(ble_gap_evt_t const * p_gap_evt) { m_conn_handle = p_gap_evt->conn_handle; m_gap_role = p_gap_evt->params.connected.role; if (m_gap_role == BLE_GAP_ROLE_PERIPH) { NRF_LOG_INFO("Connected as a peripheral.\r\n"); } else if (m_gap_role == BLE_GAP_ROLE_CENTRAL) { NRF_LOG_INFO("Connected as a central.\r\n"); } // Stop scanning and advertising. (void) sd_ble_gap_scan_stop(); (void) sd_ble_gap_adv_stop(); NRF_LOG_INFO("Discovering GATT database...\r\n"); // Zero the database before starting discovery. memset(&m_ble_db_discovery, 0x00, sizeof(m_ble_db_discovery)); ret_code_t err_code; err_code = ble_db_discovery_start(&m_ble_db_discovery, p_gap_evt->conn_handle); APP_ERROR_CHECK(err_code); bsp_board_leds_off(); }
void ScanController::SetScanDutyCycle(u16 interval, u16 window){ u32 err; if (scanningState != SCAN_STATE_OFF) { err = sd_ble_gap_scan_stop(); if(err != NRF_SUCCESS){ //We'll just ignore NRF_ERROR_INVALID_STATE and hope that scanning is stopped } logt("C", "Scanning stopped"); } if(interval != 0){ currentScanParams.interval = interval; currentScanParams.window = window; err = sd_ble_gap_scan_start(¤tScanParams); if(err == NRF_SUCCESS){ logt("C", "Scanning started"); } else { //Ignore all errors, scanning could not be started scanningState = SCAN_STATE_OFF; } } }
/*JSON{ "type" : "kill", "generate" : "jswrap_nrf_kill" }*/ void jswrap_nrf_kill() { // if we were scanning, make sure we stop at reset! if (bleStatus & BLE_IS_SCANNING) { sd_ble_gap_scan_stop(); bleStatus &= ~BLE_IS_SCANNING; } }
uint32_t startScan() { sd_ble_gap_scan_stop(); // stop any in-progress scans scan.num = 0; scan.timestamp = now(); return sd_ble_gap_scan_start(&scan_params); }
/**@brief Function for initiating scanning. */ static void scan_start(void) { ret_code_t err_code; (void) sd_ble_gap_scan_stop(); err_code = sd_ble_gap_scan_start(&m_scan_param); // It is okay to ignore this error since we are stopping the scan anyway. if (err_code != NRF_ERROR_INVALID_STATE) { APP_ERROR_CHECK(err_code); } }
/**@brief Function to start scanning. */ static void scan_start(void) { ret_code_t err_code; err_code = sd_ble_gap_scan_stop(); // It is okay to ignore this error since we are stopping the scan anyway. if (err_code != NRF_ERROR_INVALID_STATE) { APP_ERROR_CHECK(err_code); } NRF_LOG_PRINTF("[APP]: start scanning for device name %s\r\n", m_target_periph_name); err_code = sd_ble_gap_scan_start(&m_scan_param); APP_ERROR_CHECK(err_code); }
uint32_t conn_mw_ble_gap_scan_stop(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len) { SER_ASSERT_NOT_NULL(p_rx_buf); SER_ASSERT_NOT_NULL(p_tx_buf); SER_ASSERT_NOT_NULL(p_tx_buf_len); uint32_t err_code = NRF_SUCCESS; uint32_t sd_err_code; sd_err_code = sd_ble_gap_scan_stop(); err_code = ble_gap_scan_stop_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); SER_ASSERT(err_code == NRF_SUCCESS, err_code); return err_code; }
/**@brief Function for disabling the use of whitelist for scanning. */ static void whitelist_disable(void) { uint32_t err_code; if ((m_scan_mode == BLE_WHITELIST_SCAN) && !m_whitelist_temporarily_disabled) { m_whitelist_temporarily_disabled = true; err_code = sd_ble_gap_scan_stop(); if (err_code == NRF_SUCCESS) { scan_start(); } else if (err_code != NRF_ERROR_INVALID_STATE) { APP_ERROR_CHECK(err_code); } } m_whitelist_temporarily_disabled = true; }
//Start scanning with the specified scanning parameters void ScanController::SetScanState(scanState newState) { u32 err = 0; if (newState == scanningState) return; //Stop scanning to either leave it stopped or update it if (scanningState != SCAN_STATE_OFF) { err = sd_ble_gap_scan_stop(); if(err != NRF_SUCCESS){ //We'll just ignore NRF_ERROR_INVALID_STATE and hope that scanning is stopped } logt("C", "Scanning stopped"); } if (newState == SCAN_STATE_HIGH) { currentScanParams.interval = Config->meshScanIntervalHigh; currentScanParams.window = Config->meshScanWindowHigh; } else if (newState == SCAN_STATE_LOW) { currentScanParams.interval = Config->meshScanIntervalLow; currentScanParams.window = Config->meshScanWindowLow; } //FIXME: Add Saveguard. Because if we are currently in connecting state, we can not scan if (newState != SCAN_STATE_OFF) { err = sd_ble_gap_scan_start(¤tScanParams); if(err == NRF_SUCCESS){ logt("C", "Scanning started"); } else { //Ignore all errors, scanning could not be started newState = SCAN_STATE_OFF; } } scanningState = newState; }
uint32_t conn_mw_ble_gap_scan_stop(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len) { SER_ASSERT_NOT_NULL(p_rx_buf); SER_ASSERT_NOT_NULL(p_tx_buf); SER_ASSERT_NOT_NULL(p_tx_buf_len); uint32_t err_code = NRF_SUCCESS; uint32_t sd_err_code; #if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5 conn_ble_gap_scan_data_unset(true); #endif sd_err_code = sd_ble_gap_scan_stop(); err_code = ble_gap_scan_stop_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); SER_ASSERT(err_code == NRF_SUCCESS, err_code); return err_code; }
/*JSON{ "type" : "staticmethod", "class" : "NRF", "name" : "setScan", "generate" : "jswrap_nrf_bluetooth_setScan", "params" : [ ["callback","JsVar","The callback to call with information about received, or undefined to stop"] ] } Start/stop listening for BLE advertising packets within range. ``` // Start scanning NRF.setScan(function(d) { console.log(JSON.stringify(d,null,2)); }); // prints {"rssi":-72, "addr":"##:##:##:##:##:##", "data":new ArrayBuffer([2,1,6,...])} // Stop Scanning NRF.setScan(false); ``` */ void jswrap_nrf_bluetooth_setScan(JsVar *callback) { uint32_t err_code; // set the callback event variable if (!jsvIsFunction(callback)) callback=0; jsvObjectSetChild(execInfo.root, BLE_SCAN_EVENT, callback); // either start or stop scanning if (callback) { ble_gap_scan_params_t m_scan_param; // non-selective scan m_scan_param.active = 0; // Active scanning set. m_scan_param.selective = 0; // Selective scanning not set. m_scan_param.interval = SCAN_INTERVAL;// Scan interval. m_scan_param.window = SCAN_WINDOW; // Scan window. m_scan_param.p_whitelist = NULL; // No whitelist provided. m_scan_param.timeout = 0x0000; // No timeout. err_code = sd_ble_gap_scan_start(&m_scan_param); } else { err_code = sd_ble_gap_scan_stop(); } if (err_code) jsExceptionHere(JSET_ERROR, "Got BLE error code %d", err_code); }
/**@brief Function for handling the Application's BLE Stack events. * * @param[in] p_ble_evt Bluetooth stack event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { uint32_t err_code; const ble_gap_evt_t * p_gap_evt = &p_ble_evt->evt.gap_evt; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_ADV_REPORT: { data_t adv_data; data_t type_data; // Initialize advertisement report for parsing. adv_data.p_data = (uint8_t *)p_gap_evt->params.adv_report.data; adv_data.data_len = p_gap_evt->params.adv_report.dlen; err_code = adv_report_parse(BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE, &adv_data, &type_data); if (err_code != NRF_SUCCESS) { // Compare 128 UUID. err_code = adv_report_parse(BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE, &adv_data, &type_data); } // Verify if short or complete name matches target. if (err_code == NRF_SUCCESS) { if(!memcmp( nus_service_uuid,type_data.p_data,16)) { // Stop scanning. err_code = sd_ble_gap_scan_stop(); if (err_code != NRF_SUCCESS) { printf("[APPL]: Scan stop failed, reason %d\r\n", (int)err_code); } nrf_gpio_pin_clear(SCAN_LED_PIN_NO); m_scan_param.selective = 0; // Initiate connection. err_code = sd_ble_gap_connect(&p_gap_evt->params.adv_report.\ peer_addr, &m_scan_param, &m_connection_param); if (err_code != NRF_SUCCESS) { printf("[APPL]: Connection Request Failed, reason %d\r\n", (int)err_code); } break; } // } } break; } case BLE_GAP_EVT_TIMEOUT: if(p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN) { if (m_scan_mode == BLE_WHITELIST_SCAN) { m_scan_mode = BLE_FAST_SCAN; // Start non selective scanning. scan_start(); } } else if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN) { // } break; case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: // Accepting parameters requested by peer. err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle, &p_gap_evt->params.conn_param_update_request.conn_params); APP_ERROR_CHECK(err_code); break; default: break; } }
ble_error_t nRF5xGap::startRadioScan(const GapScanningParams &scanningParams) { /* Allocate the stack's whitelist statically */ ble_gap_whitelist_t whitelist; ble_gap_addr_t *whitelistAddressPtrs[YOTTA_CFG_WHITELIST_MAX_SIZE]; ble_gap_irk_t *whitelistIrkPtrs[YOTTA_CFG_IRK_TABLE_MAX_SIZE]; /* Initialize the whitelist */ whitelist.pp_addrs = whitelistAddressPtrs; whitelist.pp_irks = whitelistIrkPtrs; whitelist.addr_count = 0; whitelist.irk_count = 0; /* Add missing IRKs to whitelist from the bond table held by the SoftDevice */ if (scanningPolicyMode != Gap::SCAN_POLICY_IGNORE_WHITELIST) { ble_error_t error = generateStackWhitelist(whitelist); if (error != BLE_ERROR_NONE) { return error; } } ble_gap_scan_params_t scanParams = { .active = scanningParams.getActiveScanning(), /**< If 1, perform active scanning (scan requests). */ .selective = scanningPolicyMode, /**< If 1, ignore unknown devices (non whitelisted). */ .p_whitelist = &whitelist, /**< Pointer to whitelist, NULL if none is given. */ .interval = scanningParams.getInterval(), /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ .window = scanningParams.getWindow(), /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ .timeout = scanningParams.getTimeout(), /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ }; if (sd_ble_gap_scan_start(&scanParams) != NRF_SUCCESS) { return BLE_ERROR_PARAM_OUT_OF_RANGE; } return BLE_ERROR_NONE; } ble_error_t nRF5xGap::stopScan(void) { if (sd_ble_gap_scan_stop() == NRF_SUCCESS) { return BLE_ERROR_NONE; } return BLE_STACK_BUSY; } #endif /**************************************************************************/ /*! @brief Stops the BLE HW and disconnects from any devices @returns ble_error_t @retval BLE_ERROR_NONE Everything executed properly @section EXAMPLE @code @endcode */ /**************************************************************************/ ble_error_t nRF5xGap::stopAdvertising(void) { /* Stop Advertising */ ASSERT_TRUE(ERROR_NONE == sd_ble_gap_adv_stop(), BLE_ERROR_PARAM_OUT_OF_RANGE); state.advertising = 0; return BLE_ERROR_NONE; }
/**@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; const ble_gap_evt_t * p_gap_evt = &p_ble_evt->evt.gap_evt; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_ADV_REPORT: { data_t adv_data; data_t type_data; // Initialize advertisement report for parsing. adv_data.p_data = (uint8_t *)p_gap_evt->params.adv_report.data; adv_data.data_len = p_gap_evt->params.adv_report.dlen; err_code = adv_report_parse(BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE, &adv_data, &type_data); if (err_code != NRF_SUCCESS) { // Compare short local name in case complete name does not match. err_code = adv_report_parse(BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE, &adv_data, &type_data); } // Verify if short or complete name matches target. if (err_code == NRF_SUCCESS) { uint16_t extracted_uuid; // UUIDs found, look for matching UUID for (uint32_t u_index = 0; u_index < (type_data.data_len/UUID16_SIZE); u_index++) { UUID16_EXTRACT(&extracted_uuid,&type_data.p_data[u_index * UUID16_SIZE]); APPL_LOG("\t[APPL]: %x\r\n",extracted_uuid); if(extracted_uuid == TARGET_UUID) { // Stop scanning. err_code = sd_ble_gap_scan_stop(); if (err_code != NRF_SUCCESS) { APPL_LOG("[APPL]: Scan stop failed, reason %d\r\n", err_code); } err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); m_scan_param.selective = 0; // Initiate connection. err_code = sd_ble_gap_connect(&p_gap_evt->params.adv_report.peer_addr, &m_scan_param, &m_connection_param); m_whitelist_temporarily_disabled = false; if (err_code != NRF_SUCCESS) { APPL_LOG("[APPL]: Connection Request Failed, reason %d\r\n", err_code); } break; } } } break; } case BLE_GAP_EVT_TIMEOUT: if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN) { APPL_LOG("[APPL]: Scan timed out.\r\n"); scan_start(); } else if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN) { APPL_LOG("[APPL]: Connection Request timed out.\r\n"); } break; case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: // Accepting parameters requested by peer. err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle, &p_gap_evt->params.conn_param_update_request.conn_params); 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; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_ADV_REPORT: { data_t adv_data; data_t type_data; // Initialize advertisement report for parsing. adv_data.p_data = p_ble_evt->evt.gap_evt.params.adv_report.data; adv_data.data_len = p_ble_evt->evt.gap_evt.params.adv_report.dlen; err_code = adv_report_parse(BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, &adv_data, &type_data); if (err_code != NRF_SUCCESS) { // Compare short local name in case complete name does not match. err_code = adv_report_parse(BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME, &adv_data, &type_data); } // Verify if short or complete name matches target. if ((err_code == NRF_SUCCESS) && (0 == memcmp(TARGET_DEV_NAME,type_data.p_data,type_data.data_len))) { err_code = sd_ble_gap_scan_stop(); if (err_code != NRF_SUCCESS) { APPL_LOG("[APPL]: Scan stop failed, reason %d\r\n", err_code); } err_code = sd_ble_gap_connect(&p_ble_evt->evt.gap_evt.params.adv_report.\ peer_addr, &m_scan_param, &m_connection_param); if (err_code != NRF_SUCCESS) { APPL_LOG("[APPL]: Connection Request Failed, reason %d\r\n", err_code); } } break; } case BLE_GAP_EVT_TIMEOUT: if(p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN) { APPL_LOG("[APPL]: Scan Timedout.\r\n"); } else if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN) { APPL_LOG("[APPL]: Connection Request Timedout.\r\n"); } break; default: break; } }
/* Function to start scanning devices */ void conn_stop_scan(void) { /* stop scanning */ sd_ble_gap_scan_stop(); }
/**@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; const ble_gap_evt_t * p_gap_evt = &p_ble_evt->evt.gap_evt; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_ADV_REPORT: { const ble_gap_evt_adv_report_t *p_adv_report = &p_gap_evt->params.adv_report; //TODO: implement whitelist bool friend = true; // Whitelist substitute for (int i = 0; i < BLE_GAP_ADDR_LEN - 1; i++) // Last number of address doesnt count. Others should be same as ours. { if (p_adv_report->peer_addr.addr[BLE_GAP_ADDR_LEN - 1 - i] != l_device_address[i]) { friend = false; break; } } if (friend) { make_report(NRF_RTC1->COUNTER, timer_epoch, p_adv_report->rssi, p_adv_report->peer_addr.addr[0]); } break; } case BLE_GAP_EVT_CONNECTED: err_code = NRF_SUCCESS; sd_ble_gap_scan_stop(); __LOG("conn. scan stopped"); 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; __LOG("disco. scan start"); scan_start(); //initialize advertising again in case power level changed. //advertised power is not by default tx power advertising_init(); advertising_start(); break; case BLE_GAP_EVT_TIMEOUT: //advertising starts itself. scan_start(); __LOG("timeout. scan start"); 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); } //TODO: manage timeout. __LOG("GATTS timeout."); break; case BLE_EVT_TX_COMPLETE: if (m_file_in_transit) ble_nus_data_transfer(); break; default: // No implementation needed. break; } }