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?

Parents
  • 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

Reply
  • 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

Children
No Data
Related