Disconnection request from peripheral device.

Hi Everyone,

sdk : nrf Connect v1.7.0

ide : VS code

I was trying out central_hr sample on nrf52840 dk. I have simulated hrs server in nrf Connect mobile application. So basically our dk is Central and nrf Connect app is peripheral here.

Suppose I have disconnected in nrf Connect app,after central made a connection, I couldn't see any callback related to disconnection on central side.

This isn't the case with peripheral_hr sample in nrf52dk. 

My question is ...

1.How the Central device knows if the peripheral is still in connection?

2.Can we disconnect from peripheral side in a ble connection?

3.Suppose I have both functionalities central and peripheral running parallely in a nrf52 chip, how to handle connection and disconnection from two independent roles?

  • Hi

    Most of the central applications in the nRFConnect SDK (NCS) handle disconnections with a disconnected event similar to this, so you should get a "Disconnected" logging message: 

    static void disconnected(struct bt_conn *conn, uint8_t reason)
    {
    	int err;
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	printk("Disconnected: %s (reason 0x%02x)\n", addr, reason);
    
    	if (default_conn != conn) {
    		return;
    	}
    
    	bt_conn_unref(default_conn);
    	default_conn = NULL;
    
    	err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
    	if (err) {
    		printk("Scanning failed to start (err %d)\n", err);
    	}
    }

    Generally I think most central applications have a button assigned to disconnect from peripherals, alternatively they'll disconnect automatically when the connection supervision timeout is exceeded.

    Best regards,

    Simon

  • yeah, I've waited for 10minutes long,

    /******** My change to central_hr sample code ****************/
    
    static bool eir_found(struct bt_data *data, void *user_data)
    {
    	bt_addr_le_t *addr = user_data;
    	int i;
        uint8_t array[20] = {0};
    	printk("[AD]: %u data_len %u\n", data->type, data->data_len);
    
    	switch (data->type) {
    	case BT_DATA_UUID16_SOME:
    	case BT_DATA_UUID16_ALL:
    		if (data->data_len % sizeof(uint16_t) != 0U) {
    			printk("AD malformed\n");
    			return true;
    		}
    
    		for (i = 0; i < data->data_len; i += sizeof(uint16_t)) {
    			struct bt_le_conn_param *param;
    			struct bt_uuid *uuid;
    			uint16_t u16;
    			int err;
    
    			memcpy(&u16, &data->data[i], sizeof(u16));
    			uuid = BT_UUID_DECLARE_16(sys_le16_to_cpu(u16));
    			if (bt_uuid_cmp(uuid, BT_UUID_HRS)) {
    				continue;
    			}
    
    			err = bt_le_scan_stop();
    			if (err) {
    				printk("Stop LE scan failed (err %d)\n", err);
    				continue;
    			}
    
    			param = BT_LE_CONN_PARAM_DEFAULT;
    			err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
    						param, &default_conn);
    			if (err) {
    				printk("Create conn failed (err %d)\n", err);
    				// bt_start_scan();
    			}
    
    			return false;
    		}
    	break;
    	case BT_DATA_NAME_COMPLETE:
    			
    	memcpy(array, data->data,data->data_len);
    	printk("Complete local Name: %s\r\n",array);
    	if(strcmp(array,"Viswa's A52") == 0)
    	{
    	int err = bt_le_scan_stop();
    	printk("BLE SCAN STOP\r\n");
    			if (err) {
    				printk("Stop LE scan failed (err %d)\n", err);
    				// continue;
    			}
    			struct bt_le_conn_param *param;
    			struct bt_uuid *uuid;
    			param = BT_LE_CONN_PARAM_DEFAULT;
    			err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
    						param, &default_conn);
    			if (err) {
    				printk("Create conn failed (err %d)\n", err);
    				// bt_start_scan();
    			}
    			return false;
    	}
    		break;
    	}
    
    	return true;                   
    	
    }
    
    
    but in my case I couldn't see the callback triggered. the only change i did is to start connection based on "complete local name 0x09 flag" from advertising parameters into existing central_hr  sample code.

    I have commented the discovery of services part too. Now the client simply connects. I have registered disconnect callbacks so i expect, it should be triggered.

    please clarify my doubt below

    Can we disconnect from peripheral side in a ble connection?

    i

  • Just to be clear. You want to trigger the disconnect on the peripheral side, is that so? That is indeed possible as well. You can check out the Connection Management API that the Zephyr Bluetooth stack uses to manage connections and disconnections for both roles. Here you see that the bt_conn_disconnect call can be called to disconnect from a remote device. Both the central and peripheral can use this call.

    Best regards,

    Simon

  • Hi Simon,

    Thanks for clearing my doubt. 

    We include some connection timeout timer before creating a connection. 

    /** Default LE connection parameters:
     * Connection Interval: 30-50 ms
     * Latency: 0
     * Timeout: 4 s
     */
    #define BT_LE_CONN_PARAM_DEFAULT BT_LE_CONN_PARAM(BT_GAP_INIT_CONN_INT_MIN, \
     BT_GAP_INIT_CONN_INT_MAX, \
     0, 400)Code

    After a timeout the bluetooth stack should trigger a callback isn't it, then why it's not triggering....I'm still getting used to rtos and Nordic, I couldn't debug it myself. I request you once to try with any development board and let me know if it happens the same with you.

    I thought of adding the timer myself and monitor the connection, then what's the point in giving a timeout before a connection.

  • Please note that this timeout you set is a connection supervision timeout, and will be trigged after 4 seconds of inactivity in the connection. Are you sure that the application is inactive for 4 seconds, or else the connection timeout won't be trigged. 

    Since you're using a phone (and nRFConnect) as a peripheral you should be able to see logging information in nRFConnect where I believe the conn sup. timeout should be printed upon a connection. Can you confirm that it is set to 4 seconds?

    Best regards,

    Simon

Related