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

Always reconnect after peers deleted

Hi community,

I'm working on a BLE gamepad with custom board based on 51802 and s130, code modified from ble_app_hids_keyboard. The gamepad works like a charm on my Android phone, but I found there's a strange problem with reconnecting.

If I hold a specific button down while power up, the gamepad deletes all peers, just like the keyboard example does, but I don't know why, it still reconnect to my phone automatically, no matter whether peers were deleted. The only way to unbond to the phone is to delete bond from the phone side. I've tried several phones and several boards, all same results. Is that suppose to happen?

My pm init code is:

#define SEC_PARAM_BOND					1
#define SEC_PARAM_MITM					0
#define SEC_PARAM_LESC					0
#define SEC_PARAM_KEYPRESS				0
#define SEC_PARAM_IO_CAPABILITIES		BLE_GAP_IO_CAPS_NONE
#define SEC_PARAM_OOB					0
#define SEC_PARAM_MIN_KEY_SIZE			7
#define SEC_PARAM_MAX_KEY_SIZE			16
memset(&sec_param, 0, sizeof(ble_gap_sec_params_t));
>
// Security parameters to be used for all security procedures.
sec_param.bond			= SEC_PARAM_BOND;
sec_param.mitm			= SEC_PARAM_MITM;
sec_param.lesc			= SEC_PARAM_LESC;
sec_param.keypress		= SEC_PARAM_KEYPRESS;
sec_param.io_caps		= SEC_PARAM_IO_CAPABILITIES;
sec_param.oob			= SEC_PARAM_OOB;
sec_param.min_key_size	= SEC_PARAM_MIN_KEY_SIZE;
sec_param.max_key_size	= SEC_PARAM_MAX_KEY_SIZE;
sec_param.kdist_own.enc	= 1;
sec_param.kdist_own.id	= 1;
sec_param.kdist_peer.enc = 1;
sec_param.kdist_peer.id	= 1;
err_code = pm_sec_params_set(&sec_param);
APP_ERROR_CHECK(err_code);

the adv init code is:

void advertising_init(void)
{
	uint32_t				err_code;
	uint8_t					adv_flags;
	ble_advdata_t			advdata;
	ble_adv_modes_config_t	options;
	// Build and set advertising data
	memset(&advdata, 0, sizeof(advdata));
	adv_flags						= BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
	advdata.name_type				= BLE_ADVDATA_FULL_NAME;
	advdata.include_appearance		= true;
	advdata.flags					= adv_flags;
	advdata.uuids_complete.uuid_cnt	= sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
	advdata.uuids_complete.p_uuids	= m_adv_uuids;
	memset(&options, 0, sizeof(options));
	options.ble_adv_whitelist_enabled		= false;
	options.ble_adv_directed_enabled		= true;
	options.ble_adv_directed_slow_enabled	= false;
	options.ble_adv_directed_slow_interval	= 0;
	options.ble_adv_directed_slow_timeout	= 0;
	options.ble_adv_fast_enabled			= true;
	options.ble_adv_fast_interval			= APP_ADV_FAST_INTERVAL;
	options.ble_adv_fast_timeout			= APP_ADV_FAST_TIMEOUT;
	options.ble_adv_slow_enabled			= false;
	options.ble_adv_slow_interval			= APP_ADV_SLOW_INTERVAL;
	options.ble_adv_slow_timeout			= APP_ADV_SLOW_TIMEOUT;
	err_code = ble_advertising_init(&advdata,
								NULL,
								&options,
								on_adv_evt,
								ble_advertising_error_handler);
	APP_ERROR_CHECK(err_code);
}

Thanks in advance.

  • ​ Oh I see now, turn out the phone is in the leading role:

    • if the phone has bonding info but my device hasn't, they will connect anyway;
    • if the phone has no bonding info but my device has, repairing will be rejected.

    So based on my usage scenario, I'd like to reverse it. For the latter situation, I think I know how to handle, as you said, just don't reject the pairing request, in the case PM_EVT_CONN_SEC_CONFIG_REQ, right? But for the former situation, I still don't know how to let them not to reconnect, since in that situation the WL is empty, my device have no idea if the connection request is from the last host.

    Now I've thought this through, what I really want is, in a situation a new host which my device has no bond info about, send a connection request, if the host has no bond info of my device either, accept it; if the host has, that means I have deleted bond info from the device, then reject it. Is this possible?

    BTW I'm using SDK12, s130v2.

  • Yes, set .allow_repairing to true.

    It is not possible, without a whitelist any device can connect to your device. There are ways of figuring out if a device has been bonded with you before after you have connected, and then disconnect if the device is not familiar with you. See this for more information. Can changing the device address work for you? So that the phone that has deleted its bond can't recognize your device?

  • Let me describe my dilemma in a more generic way, from a user's perspective.

    Say I have two Android phone A&B, in the same place, then I realize there's no elegant way to add them both in my device's whitelist.

    Once my device bonded with A,

    1. if I disconnect from A, it will reconnect to A instantly, I have no chance to be discovered by B;
    2. if I power up it with pm_peers_delete(), it will reconnect to A anyway, and since I want to add both A&B in my WL, deleting peer is not an option;
    3. delete bond from A is a feasible way, but not elegant, they need to repair later;
    4. turn off BT of A is currently my best choice, but still not so elegant, because A may have connected with other BT devices which I don't like to cut off.

    And although I don't really understand why it's not possible to have my device connectable without a whitelist, I've still kept it, I merely don't advertise with it, because I haven't actually see the point of adv with WL in my scenario yet. If I do adv with WL, even if I turn the BT of A off, to let my device restart advertising, B still can't discover it cause B is not in it's WL. that's the reason why I set options.ble_adv_whitelist_enabled = false;

  • As for changing address, I'm not sure what address you were talking about, is the 6 bytes bt address? I'm only a newbie in BLE dev. No matter what address it is, if I change it to bond with B, then B must have a different address in its bond info from A, then my device will not be able to connect to both of them with a single address, is that correct?

  • I'm not very familiar with WL code but from what you explain I understand that you need to modify it so it will work in two modes. One is how it works now where it will accept only bonded connections, and second one will work in reverse rejecting only bonded connections. kind of black list. If whitelisting done in SD then it will be difficult to implement without Nordic help.

Related