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

How does a peripheral refuse a connection from a central?

I have a peripheral (nRF51822, s110, SDK 8.1, using the device manager) which should only ever be bonded with zero or one centrals. The behaviour I'm aiming for is this:

  1. Whether there's a bond or not, advertise. 2a. If there's no bond and a central connects, accept the connection and allow the central to bond. 2b. If there's a bond, accept connections from the bonded peer, but refuse all other connections.

At first this looks like a candidate for using the advertising type BLE_GAP_ADV_TYPE_ADV_DIRECT_IND (connectable, directed). There are two reasons I don't want to use that advertising type. First, I want other centrals to know when my peripheral is around, without actually connecting to it. Second, it's my understanding that I'd need to use a known peer address and this approach does NOT play nicely with iOS where the peer address changes frequently.

I'm not sure how I can refuse the connection in case 2b above. In my device_manager_cnfg.h I have

DEVICE_MANAGER_MAX_BONDS         1

So I'd expect an assert on attempting to bond, if I got that far.

I'm using a whitelist when dm_whitelist_create() sets the number of addresses or IRKs to more than 0. My advertising code looks like this:

uint32_t err_code;
ble_gap_adv_params_t adv_params;
ble_gap_whitelist_t whitelist;
uint32_t pstorage_count;

err_code = pstorage_access_status_get(&pstorage_count);
APP_ERROR_CHECK(err_code);

if (pstorage_count != 0)
{
    m_memory_access_in_progress = true;
    return;
}

memset(&adv_params, 0, sizeof(adv_params));
adv_params.interval = APP_ADV_INTERVAL;
adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND;
adv_params.p_peer_addr = NULL;

ble_gap_addr_t * p_whitelist_addr[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
ble_gap_irk_t * p_whitelist_irk[BLE_GAP_WHITELIST_IRK_MAX_COUNT];

whitelist.addr_count = BLE_GAP_WHITELIST_ADDR_MAX_COUNT;
whitelist.irk_count = BLE_GAP_WHITELIST_IRK_MAX_COUNT;
whitelist.pp_addrs = p_whitelist_addr;
whitelist.pp_irks = p_whitelist_irk;

err_code = dm_whitelist_create(&m_app_handle, &whitelist);
APP_ERROR_CHECK(err_code);

if ((whitelist.addr_count != 0) || (whitelist.irk_count != 0))
{
	adv_params.fp = BLE_GAP_ADV_FP_FILTER_CONNREQ;
	adv_params.p_whitelist = &whitelist;
	adv_params.timeout = 0;
}
else
{
	adv_params.fp = BLE_GAP_ADV_FP_ANY;
	adv_params.p_whitelist = NULL;
	adv_params.timeout = APP_ADV_TIMEOUT_UNBONDED;
}

ble_advdata_t advdata;
ble_uuid_t adv_uuids[] =
{
    {BTS_UUID_SERVICE, m_bts.uuid_type}
};

memset(&advdata, 0, sizeof(advdata));

advdata.flags                   = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
advdata.name_type               = BLE_ADVDATA_FULL_NAME;
advdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
advdata.uuids_complete.p_uuids  = adv_uuids;

err_code = ble_advdata_set(&advdata, NULL);
APP_ERROR_CHECK(err_code);

err_code = sd_ble_gap_adv_start(&adv_params);
APP_ERROR_CHECK(err_code);
Parents
  • "The Link Layer may perform device filtering based on the device address of the peer device. Link Layer Device Filtering is used by the Link Layer to minimize the number of devices to which it responds." See Vol. 6, Part B, Section 4.3 in the Bluetooth Core specification 4.2.

    "The set of devices that the Link Layer uses for device filtering is called the White List." See Vol. 6, Part B, Section 4.3.1 in the Bluetooth Core specification 4.2.

    Whitelist is exactly what you describe, you still send out advertising packets, but you only respond to connection requests from devices in the whitelist. The whitelist is usually created by using the addresses and IRKs of the current bonded devices.

    There are many questions regarding whitelist on Devzone, so a search should give you some information on how to set it up, but please ask if you get into trouble, preferably in a new question.

    If you are using the Advertising Module in SDK 8.1.0, please be aware of this.

Reply Children
No Data
Related