Connection Interval and MTU size

255 views
Skip to first unread message

Alec Labadie

unread,
Sep 29, 2021, 1:23:37 PM9/29/21
to btstack-dev
Hello,

I am working with the le_data_channel_server example as a starting point. I have a question about connection interval changes and a question about MTU changes. Any and all advice would be much appreciated!  

Connection Interval:
I read on this forum that calling the function " gap_request_connection_parameter_update(handle, min, max,timeout) " can be used to send a request for a new parameters (such as conn_interval) to the central device. However, after trying different values for min & max I am not noticing any change in both the printed conn_interval value or the time between L2CAP send & subsequent receive logs on the iOS device using Xcode packetlogger. 

For more detail, I'm calling it like this from within the packet handler:

                case HCI_EVENT_LE_META:
                    switch (hci_event_le_meta_get_subevent_code(packet)) {
                        case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
                            // print connection parameters (without using float operations)
                            conn_interval = hci_subevent_le_connection_complete_get_conn_interval(packet);
                            // min con interval 15 ms - supported from iOS 11 
                            gap_request_connection_parameter_update(le_data_channel_connection.connection_handle, 48,48, 0, 0x0048);
                            printf("%c: Connection Interval: %u.%02u ms\n", le_data_channel_connection.name, conn_interval * 125 / 100, 25 * (conn_interval & 3));
                            printf("%c: Connection Latency: %u\n", le_data_channel_connection.name, hci_subevent_le_connection_complete_get_conn_latency(packet));
                            //att_dispatch_server_mtu_exchanged(le_data_channel_connection.connection_handle, 52);
                            printf("Connected, requesting conn param update for handle 0x%04x\n", le_data_channel_connection.connection_handle);
                            // 
                            //test_reset(&le_data_channel_connection);

So, is there more to it than that? I also read that the central device must respond to the request; could that be why no change is happening? 

MTU:
I also read on this forum that changing MTU is possible. I was curious as to how this can be done. I tried calling "att_dispatch_server_mtu_exchanged(..) " and again noticed no difference, I assume because I used it wrong or it is the wrong way to accomplish this. If possible, could you describe how I could change the size of the packets being sent over the air? 

Thank you for your time


Sven Krauss

unread,
Sep 30, 2021, 6:31:18 AM9/30/21
to btstack-dev
The MTU size can be changed from central device. I have a peripheral device running on btstack and an Android central device. On Andoid you can use requestMtu() to change the MTU. Keep in mind that the HCI_ACL_PAYLOAD_SIZE must be large enough.

I guess that you want to maximize the BLE throughput? Here are some useful links:

Matthias Ringwald

unread,
Sep 30, 2021, 4:46:30 PM9/30/21
to btsta...@googlegroups.com
Hi Alec

The Peripiheral can only request the change and the Central is free to accept or reject it. The default Conn Interval on iOS is 30 ms as far as I know. Why do you want to increase it to 60 ms?
Do you have an HCI Packet log for either side to check?

MTU: the MTU is negotiated by the GATT Client. When asked, BTstack will use the largest possible MTU given the HCI_ACL_PAYLOAD_SIZE (e.g. 200 is sufficient for max ATT MTU with iOS and Android devices).
While the spec allows to change it later, I haven't seen that yet.

Best
Matthias
> --
> You received this message because you are subscribed to the Google Groups "btstack-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to btstack-dev...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/btstack-dev/d0b0f5d1-4845-4827-9423-dfe00f536a15n%40googlegroups.com.

Alec Labadie

unread,
Sep 30, 2021, 5:14:06 PM9/30/21
to btstack-dev
Hello Sven and Matthias,

Thank you both for your responses. I will read those links. 

I am more concerned about latency than throughput. I'm trying to avoid segmentation and reassembly, if possible, by increasing the MTU. 

I'm noticing in wireshark & xcode packet logger that when I try to send 52 unsigned chars it is getting broken up into two packets. This seems unnecessary and, if I'm understanding correctly, could increase latency. Correct me if I'm wrong, but if I send a packet once every connection interval and I need to use two packets to send one complete "message", than wouldn't that have the same effect as just having a connection interval that is twice as long? And taking twice as long to relay one message? 

Re: Matthias:
Thank you. I don't want a larger connection interval. I was just setting different values and seeing if any made a difference. It is clear now that this didn't work because I didn't make any changes on the iOS side to handle the request. 

 I noticed a comment in the example which said that the minimum possible connection interval was 15ms for iOS as of version 11.0. I will see if I can get that to work. 


Matthias Ringwald

unread,
Oct 2, 2021, 4:26:07 AM10/2/21
to btsta...@googlegroups.com
Hi Alec

Do you provide a GATT Server or do you use the LE Data Channels? The ATT MTU is only relevant for ATT and GATT.
iOS and Android automatically increase the MTU, so if you set HCI_ACL_PAYLOAD_SIZE to 200 or higher, you're good.

If both sides LE Data Length Extension, the over-the-air packets will always be the same size (23 bytes of ATT payload or so). But the segmentation and reassembly will happen automatically, and the packets could be sent in a single connection interval.

If you use ATT Write, the other side need to confirm that. If you want to optimize for minima latency, you should use Wire Without Response, which allows you so stream data (see gatt_streamer..)

For LE Data Channels, make sure that you provide a large enough data buffer - the example uses a 1k buffer, so that should be fine. Even then, the data will be sent in regular 23 byte packets.

Best
Matthias
> To view this discussion on the web visit https://groups.google.com/d/msgid/btstack-dev/c43a4464-08d0-4deb-b359-9decefa9971dn%40googlegroups.com.

Alec Labadie

unread,
Oct 4, 2021, 10:18:15 AM10/4/21
to btstack-dev
I am using LE Data Channels. 

Re: LE DLE & reassembly: Ah, thank you. I knew I was missing something. My mistake. 
I am calling "l2cap_le_accept_connection()" with data_channel_buffer size 52. From the iOS side I see a message size of 54. It gets split into a size 48 packet and a size 6 packet. Based on what you've said, this is not DLE then.

I'll look into gatt_streamer, thank you. 

Thank you again,
Alec
Reply all
Reply to author
Forward
0 new messages