This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Adding observer role to peripheral example

I started development with the S132 (SDK 15.0.0) peripheral example "blinky". After some modification, it handles all necessary communication with my phone flawlessly. Now, I would like to add a concurrent observer role that will allow me to listen for non-connectable beacons while maintaining a connection to my phone. After reading the S132 soft device specification and perusing the API reference, I am still not sure how to accomplish this. So far, I've been using the S132 central example "blinky" as a template.

I transplanted db_discovery_init() and lbs_c_init() from the initialization routine in the central example to my working project, added the appropriate files to the project, and adjusted sdk_config.h to enable the database discovery module, the advertising module, and the LBS client.

Now, on connection event, BLE_GAP_EVT_CONNECTED, I execute observe_start():

static uint8_t ad_buffer[BLE_GAP_SCAN_BUFFER_MIN];
static ble_data_t observerAdBuf = 
{
	ad_buffer,
	BLE_GAP_SCAN_BUFFER_MIN
};
static ble_gap_scan_params_t scanParameters =
{
	0,							//Accept extended advertising packets?
	0,							//Report incomplete events? (only relevant to extended scanning)
	0,							//Perform active scanning by sending scan requests?
	BLE_GAP_SCAN_FP_ACCEPT_ALL,	//Accept all advertising packets except directed advertising packets not addressed to this device.
	BLE_GAP_PHY_1MBPS,			//Bitfield of PHYs to scan on.
	0x0100,						//Scan interval, in 625us increments
	0x0100,						//Scan window, in 625us increments
	0x0000,						//Scan timeout, in 10ms increments (0 disables timeout)
	0							//Channel mask for primary and secondary advertising channels. At least one of the primary channels, that is channel index 37-39, must be set to 0.
};

void observe_start( void )
{	
    sd_ble_gap_scan_stop();
    sd_ble_gap_scan_start( &scanParameters, &observerAdBuf );
}

The function runs as expected and sd_ble_gap_scan_start returns NRF_SUCCESS. My expectation at this point was that advertising packets would now trigger a BLE_GAP_EVT_ADV_REPORT event. Except, BLE_GAP_EVT_ADV_REPORT never triggers. The device still connects and communicates with the phone, but advertising packets are never reported.

I'm sure that I'm missing an obvious step, but I'm not sure what that step is. Anything to point me in the correct direction would be greatly appreciated.

  • I wonder if you have solved this problem. If you did, I would like to know the answer.

  • I have not, but glad to know I'm not alone. I'll be sure to update this thread if I do find a solution. I also received an email from Nordic indicating that an engineer has been assigned to this ticket, so hopefully we'll get some input soon.

  • Hi,

    Sorry for the slow response. It is holiday season in Norway and the response time is slower than usual.

    I suggest that you have a look at the BLE Central & Peripheral examples. They show how you can e.g. act as a relay and connect to both a central and peripheral(s) at the same time. 

    The db_discovery_init() stuff should only be necessary of you plan on connecting to peripherals and use their services and characteristics. 

    If you are still struggling, do you mind uploading your entire project so I can have a look?

  • I found the obvious step that I was missing. Apparently, scanning for advertising packets will stop when the status of a received advertisement packet is not  BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. Scanning has to be restarted when these packets are received. From the S132 API Reference (v6.0.0):

    * @note    The scanner will automatically stop when ... a @ref BLE_GAP_EVT_ADV_REPORT event is received and @ref ble_gap_adv_report_type_t::status is not set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. In this case scanning is only paused to let the application access received data. The application must call this function to continue scanning, or call @ref sd_ble_gap_scan_stop to stop scanning.

    So the fix for me was to call observe_start(), defined above, after every received advertising packet. Interestingly, the sd_ble_gap_scan_stop() portion of observe_start() was necessary to restart scanning. Trying to restart without calling out the stop function returned NRF_ERROR_INVALID_STATE.

    As Martin mentioned, db_discovery and lbs_c were not necessary, since I wasn't trying to make a connection.

Related