Optimizing NUS client to server latency

Hi!

Background (feel free to skip)
---------------------------------------

We have 3 nRF52840 boards, connected via ble/NUS as follows:

A (NUS server) <---NUS---> (NUS client) B (NUS server) <---NUS---> (NUS client) C

B also advertises bluetooth HID, and both B and C feature a USB HID.

Following text considers the connection between A and B. All other connections are disconnected (although the advertisement is running). I am testing one direction at a time only, unless specified otherwise.

All connections are configured so that:

- data length extension is turned on

- connection interval is set to 7.5ms

    bt_conn_le_data_len_update(conn, BT_LE_DATA_LEN_PARAM_MAX);
    
    static const struct bt_le_conn_param conn_params = BT_LE_CONN_PARAM_INIT( 6, 6, 0, 100);
    bt_conn_le_param_update(conn, &conn_params);

Our main prj.conf CONFIG_BT values:

CONFIG_BT_ATT_PREPARE_COUNT=4
CONFIG_BT_BAS=y
CONFIG_BT_BUF_ACL_RX_SIZE=251
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_CENTRAL=y
CONFIG_BT_DEVICE_APPEARANCE=961
CONFIG_BT_DEVICE_NAME="UHK 80"
CONFIG_BT_DIS_MANUF="Ultimate Gadget Laboratories"
CONFIG_BT_DIS_PNP_VID=0x37A8
CONFIG_BT_DIS_PNP_VID_SRC=2
CONFIG_BT_DIS_PNP=y
CONFIG_BT_DIS=y
CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=n
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_GATT_DM=y
CONFIG_BT_L2CAP_TX_BUF_COUNT=5
CONFIG_BT_L2CAP_TX_MTU=247
CONFIG_BT_MAX_CONN=1
CONFIG_BT_MAX_PAIRED=1
CONFIG_BT_NUS_CLIENT=y
CONFIG_BT_NUS=y
CONFIG_BT_OBSERVER=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_SCAN_ADDRESS_CNT=2
CONFIG_BT_SCAN_FILTER_ENABLE=y
CONFIG_BT_SCAN_UUID_CNT=1
CONFIG_BT_SCAN=y
CONFIG_BT_SETTINGS=y
CONFIG_BT_SHELL=y
CONFIG_BT_SMP=y
CONFIG_BT_USER_DATA_LEN_UPDATE=y
CONFIG_BT=y

Single direction testing
------------------------------

Testing with simple 2-byte pings (sending 50 pings, one each millisecond) reveals:

- Server-to-client (2-byte-messages) accepts and transports all the packets, with send-to-sent time around 15ms (measured from calling send to receiving relevant sent callback).

- Server-to-client (230-byte messages) In this case, sending slows down significantly, send function clearly blocking until there is a free slot in the queue. send-to-sent time increases to ~30ms in that case (which corresponds to a 4 slot long queue, I believe configured by CONFIG_BT_ATT_PREPARE_COUNT). The time of the whole sequence is 336ms.

- Client-to-server accepts one packet for transport every 15ms, and returns -120 otherwise. send-to-sent time is again 15ms.


Round trip time testing
------------------------------

- Round trips take around 15ms, which sounds fine, except that no more than 1 roundtrip succeeds every 15ms.

Questions
-------------

- Seeing above results (especially sending 50 messages in 336ms), am I right that server-to-client communication aggregates and splits our messages into (smaller number of) ble packets?

- Can we achieve the same packet-aggregation behavior for client-to-server communication?

- Is there a way to make the client send a packet every 7.5ms?

Related