bt_gatt_subsrcibe can not recive more than 20Byte data

Compilation environment :nRF Connect SDK V1.4.2

I successfully subscribed to a notification property of the peripheral using bt_gatt_subscribe, the callback function is 

notify_func(struct bt_conn *conn, struct bt_gatt_subscribe_params *params, const void *data, uint16_t length).

When the data sent by the external device I am connected to is 30 bytes, the notification callback function parameter length keeps printing out 20 bytes. I have configured CONFIG-BT-L2CAP-RX-MTU=247, but it does not work.
I hope the callback function can correctly obtain the length of data passed from the peripheral.

how to slove this problem?

thanks.

Parents
  • Hello,

    Are you actually using NCS v1.4.2? Is it a possibility to test the same application in e.g. 2.6.0, and check if it still behaves the same?

    Can you please show how you declare and populate the parameters that you use in the notify function? Is it possible for me to reproduce? Are you sure the MTU is actually large enough to send more than 20 bytes of payload? What does the notify function return? Does it behave the same if you use nRF Connect for Desktop -> Bluetooth Low Energy as the central?

    Best regards,

    Edvin

Reply
  • Hello,

    Are you actually using NCS v1.4.2? Is it a possibility to test the same application in e.g. 2.6.0, and check if it still behaves the same?

    Can you please show how you declare and populate the parameters that you use in the notify function? Is it possible for me to reproduce? Are you sure the MTU is actually large enough to send more than 20 bytes of payload? What does the notify function return? Does it behave the same if you use nRF Connect for Desktop -> Bluetooth Low Energy as the central?

    Best regards,

    Edvin

Children
  • My code is similar to the routine ble_central_hr. After connecting to the peripheral, I subscribe to the properties and print out the data in the notification callback function.

    Step1:Successfully created a connection using the bt_conn_le_create function, and entered the callback function connect

    bt_conn_le_create

    Step2:In the connect callback function, I will find its notification attribute and subscribe to it in the discover_func_uuid callback function. The final subscription callback function is notify_func

    discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
    discover_params.func = discover_func_uuid;
    discover_params.start_handle = 0x0001;
    discover_params.end_handle = 0xffff;
    
    err = bt_gatt_discover(conn, &discover_params);
    if (err) {
    	printk("Discover failed(err %d)\n", err);
    	return;
    }

    subscribe_params.notify = notify_func;
    subscribe_params.value = BT_GATT_CCC_NOTIFY;
    subscribe_params.ccc_handle = attr->handle;
    
    err = bt_gatt_subscribe(conn, &subscribe_params);
    if (err && err != -EALREADY) {
    	printk("Subscribe failed (err %d)\n", err);
    } else {
    	printk("[SUBSCRIBED]\n");
    }

    Step3:Print out data and length in the notification callback function notify_func

    static uint8_t notify_func(struct bt_conn *conn, struct bt_gatt_subscribe_params *params, const void *data, uint16_t length) {
    	if (!data) {
    		printk("[UNSUBSCRIBED]\n");
    		params->value_handle = 0U;
    		bt_conn_disconnect(conn,BT_HCI_ERR_REMOTE_USER_TERM_CONN);
    		return BT_GATT_ITER_STOP;
    	}
    	const bt_addr_le_t *addr = bt_conn_get_dst(conn);
    	
    	printk("len:%d  data:",length);
    	uint8_t ubTemp;
    	for (ubTemp = 0;ubTemp < length;ubTemp++) {
    		printk("%02x ",((uint8_t *)data)[ubTemp]);
    	}
    	printk("\n");
    }

    This is the writing method for standard routines, which can obtain data normally. But when I increase the size of the data for each notification on the connected device to 30 bytes, The maximum length of data obtained in the notify'func callback function is 20 bytes. So I connected to the device using a mobile app, subscribed to the same properties, and could see 30 bytes of data from the mobile app.

    How to solve this problem? Do you have any relevant reference codes?

    thanks.

  • Edvin said:

    Are you actually using NCS v1.4.2? Is it a possibility to test the same application in e.g. 2.6.0, and check if it still behaves the same?

    When you send your packet with 30 bytes from your peripheral, are you able to see that it actually transmits 30 bytes?

    I suspect that you don't perform any MTU exchange, so the MTU is left at the default 20 bytes of payload (MTU = 23, but 3 bytes are used for headers). 

    This would also explain why you can see 30 bytes when connecting with your phone, because it supports a higher MTU. 

    You should however be able to see this from your peripheral. I guess there is some logic that caps the message length to the current MTU. Try to either debug, or print in the log from the peripheral what length it actually transmits.

    Also, to increase the MTU (and enable data length extension), please see Lesson 3 in the Bluetooth Low Energy Fundamentals course on Nordic Developer Academy. Particularly exercise 2, step 10 and out is particularly relevant in your case.

    Best regards,

    Edvin

Related