I would like UART client in example
C:\NordicSdks\SDK_14.1.0\examples\ble_central\ble_app_uart_c\pca10040\s132\arm5_no_packs
to connect auotomatically to nearby devices broadcasting advertising packets with Nordic UART service UUID encoded data payloads. Example client code without modifications currently connects to single perihperal based on service UUID in payload but does not connect to mutiple devices as I want.
I looked at ble_evt_handler
call-back and noticed two events, BLE_GAP_EVT_ADV_REPORT
and BLE_GAP_EVT_CONNECTED
.
BLE_GAP_EVT_ADV_REPORT
case BLE_GAP_EVT_ADV_REPORT:
{
ble_gap_evt_adv_report_t const * p_adv_report = &p_gap_evt->params.adv_report;
if (is_uuid_present(&m_nus_uuid, p_adv_report))
{
log("Connecting to device...");
err_code = sd_ble_gap_connect(&p_adv_report->peer_addr,
&m_scan_params,
&m_connection_param,
APP_BLE_CONN_CFG_TAG);
log("Stopping scan...");
if (err_code == NRF_SUCCESS)
{
// scan is automatically stopped by the connect
err_code = bsp_indication_set(BSP_INDICATE_IDLE);
APP_ERROR_CHECK(err_code);
NRF_LOG_INFO("Connecting to target %02x%02x%02x%02x%02x%02x",
p_adv_report->peer_addr.addr[0],
p_adv_report->peer_addr.addr[1],
p_adv_report->peer_addr.addr[2],
p_adv_report->peer_addr.addr[3],
p_adv_report->peer_addr.addr[4],
p_adv_report->peer_addr.addr[5]
);
}
}
}break; // BLE_GAP_EVT_ADV_REPORT
BLE_GAP_EVT_CONNECTED
case BLE_GAP_EVT_CONNECTED:
log("Connected to device.");
NRF_LOG_INFO("Connected to target");
err_code = ble_nus_c_handles_assign(&m_ble_nus_c, p_ble_evt->evt.gap_evt.conn_handle, NULL);
APP_ERROR_CHECK(err_code);
err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
APP_ERROR_CHECK(err_code);
// start discovery of services. The NUS Client waits for a discovery result
err_code = ble_db_discovery_start(&m_db_disc, p_ble_evt->evt.gap_evt.conn_handle);
APP_ERROR_CHECK(err_code);
log("Starting scan...");
scan_start();
break;
In BLE_GAP_EVT_ADV_REPORT
I noticed that on API call sd_ble_gap_connect
chip will stop scanning before attempting to connect so there is no conflict with radio; so what I did was add scan_start()
method in BLE_GAP_EVT_CONNECTED
case.
I logged in my RTT that the client will attempt to connect to a second client, but not a third or more because when the client tries to connect to a secondary device the client appears to freeze up because there is no call back from ble_evt_handler
.
I do not undestand why client freezes up probably inside soft device, but this is my explanation.
I noticed in the API call sd_ble_gap_connect
that a data structure called peer_addr
is passed as an argument
err_code = sd_ble_gap_connect(&p_adv_report->peer_addr,
&m_scan_params,
&m_connection_param,
APP_BLE_CONN_CFG_TAG);
I look at ble_gap_evt_adv_report_t
typedef struct
{
ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1
and the address is the device's identity address. */
ble_gap_addr_t direct_addr; /**< Set when the scanner is unable to resolve the private resolvable address of the initiator
field of a directed advertisement packet and the scanner has been enabled to report this in @ref ble_gap_scan_params_t::adv_dir_report. */
int8_t rssi; /**< Received Signal Strength Indication in dBm. */
uint8_t scan_rsp : 1; /**< If 1, the report corresponds to a scan response and the type field may be ignored. */
uint8_t type : 2; /**< See @ref BLE_GAP_ADV_TYPES. Only valid if the scan_rsp field is 0. */
uint8_t dlen : 5; /**< Advertising or scan response data length. */
uint8_t data[BLE_GAP_ADV_MAX_SIZE]; /**< Advertising or scan response data. */
} ble_gap_evt_adv_report_t;
And then I look at ble_gap_addr_t
typedef struct
{
uint8_t addr_id_peer : 1; /**< Only valid for peer addresses.
Reference to peer in device identities list (as set with @ref sd_ble_gap_device_identities_set) when peer is using privacy. */
uint8_t addr_type : 7; /**< See @ref BLE_GAP_ADDR_TYPES. */
uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format. */
} ble_gap_addr_t;
And I notice addr_id_peer
is 1
which make me wonder if there is some address conflict? And what about addr_t
? Does it change from one uart server to the next? Is there address conflict here which is why client cannot connect to multiple servers?
Long story short, why is client not connecting to multiple servers?