Qiao
Qiao

Reputation: 512

How to get/set Bluetooth MTU value in Linux with command line tool (hciconfig/bluetoothctl)

I'm developing an embedded Linux device as a BLE peripheral to communicate to Android App.

I start from the github project python-gatt-server.

Now there's some throughput bottleneck and I doubt it's about MTU setting.

The output of hciconfig is as follows:

root@linux:~# hciconfig
hci0:   Type: Primary  Bus: UART
        BD Address: C0:EE:40:3B:31:A0  ACL MTU: 1021:8  SCO MTU: 64:1
        UP RUNNING PSCAN ISCAN 
        RX bytes:1392 acl:0 sco:0 events:78 errors:0
        TX bytes:1752 acl:0 sco:0 commands:78 errors:0
  1. There're 2 MTU settings: ACL MTU: 1021:8 and SCO MTU: 64:1, what are they meaning respectively?
  2. I heard different chipset support different MTU settings. How to find those values?
  3. How to set MTU with command line tools like hciconfig or bluetoothctl?

Upvotes: 1

Views: 3881

Answers (2)

yurenchen
yurenchen

Reputation: 2493

--- answer for GATT only ---



the two option from hciconfig cmd not for gatt mtu.
//meaning not very sure, practice does not work

一. api or cli

gatt mtu can be set in (by programing api, or cli)

  • server: btgatt-server,
  • client: btgatt-client, gatttool
    //they all work as a demo instance, only set current instance, not global settings.

//cli

btgatt-server, btgatt-client

//only set in cmdline args
tools/btgatt-server --mtu 123 ..
tools/btgatt-client --mtu 123

//btgatt-server can seen mtu change, passively

[GATT server]# att: > 02 7b 00                                         
[GATT server]# att: ATT PDU received: 0x02
server: MTU exchange complete, with MTU: 123
[GATT server]# att: ATT op 0x03
[GATT server]# att: < 03 05 02                                        

gatttool

//gatttool (only set with result, no interface do query only)

//in cmdline arg
tools/gatttool --mtu 123 ..

//in runtime 
tools/gatttool --interactive
[XX:XX:XX:XX:XX:XX][LE]> mtu 123
MTU was exchanged successfully: 123
[XX:XX:XX:XX:XX:XX][LE]> mtu 122
Command Failed: MTU exchange can only occur once per connection.
//in other app, it can be set many times.

//mtu   <value>     Exchange MTU for GATT/ATT

they all not provided query only interface yet (bluez-5.53),
you can change code implement one.

c api

//api



int mtu = 123;
server->gatt = bt_gatt_server_new(server->db, server->att, mtu, 0);

mtu = bt_att_get_mtu(server->att);
printf("--- get mtu: %d\n", mtu);  // got 672 // wrong from L2CAP (on my test device
    
bt_att_set_mtu(server->att, 23);  // conservative size

二. communication

or by communication

  • gatt negotiation by exchange mtu
    // client send mtu req(with client mtu), server reply (with server mtu): then they use MIN of them.
    // by default it's 23
    // some ble test app, can change mtu in need at runtime.
  • from link layer, L2CAP negotiate mtu.

NOTE: in bluez, mtu from link layer (L2CAP) may overide mtu from gatt api. and for BR/EDR link device, exchange mtu is disabled.

so, if L2CAP got wrong mtu, the communication may be abnormal.


三. Typical value

  • 23 //min, default
  • 517 //max from bluz
  • 527 //max from some android device

if mtu is 23, gatt may split big packet into many small packets to transmit.
// should still work.

Upvotes: 2

efran
efran

Reputation: 11

You can change MTU value by using gatttool. You need to use gatttool -I command. Then connect you device. You can use help command. MTU 1234 will works

Upvotes: 1

Related Questions