IanHarvey / bluepy

Python interface to Bluetooth LE on Linux
Other
1.59k stars 491 forks source link

writeCharacteristic() function cuts message after 20 bytes #398

Closed nickes closed 4 years ago

nickes commented 4 years ago

Hello, the writeCharacteristic() function cuts my messages after 20bytes. The rest of the message is lost somehow.

Example: Central: device.writeCharacteristic(11,b'1111122222333334444455555') Peripheral receives b'11111222223333344444' No further message was sent.

I build bluepy from source (Commit: https://github.com/IanHarvey/bluepy/commit/53ce2f2388a936663b94f00636cc2e3677325182) in combination with blueZ V5.50.

Are there some properties, that I forgot to set or are there some limitations that I didn't see? The funny thing is that readCharacteristic() works with messages > 20 bytes perfectly.

BTW: Does bluepy support BT 5.0? I could not find some official sources.

StefJar commented 4 years ago

@write: The write tunnels through different Bluetooth layers. write -> gatt write -> gatt att -> L2CAP -> Link Layer Every layer defines a max MTU size. GATT MTU for data exchange between client and server can be set by client as well as by the server. So you should check the max GATT MTU of your server(guess you query a bt device to read some data) Your write gatt command is splitt into multiple PDUs of the Link Layer. Depending on the hardware the bluetooth stack(blueZ) runs on, oversized PDUs can be handled in different ways. Some bluetooth controller just not sending them(flush event) or some cuts them. @BT 5.0 support: BT 5.0 is by definition compatible with all the lower standards. The max GATT MTUs for the different BT versions: 4.0 PDU=33, GATT MTU=22 4.1 PDU=33, GATT MTU=22 4.2 PDU=257, GATT MTU=246 5.0 PDU=512, GATT MTU=501

BT BLE runs on a symbol rate of 1M/s. BT 5.0 defines a higher symbol rate of 2M/s. The speed and bandwith of your connection is affected by the connection interval, latency and the rx/tx buffers that can store the PDUs send in one connection interval. Not that easy.

Good start is the BT Core Specification(you can download it for free) and the datasheet of the bt device & bt chip at your computer.

nickes commented 4 years ago

@StefJar thanks for your reply. I take a look into that. For now I'm using a workaround, by splitting the message into less than 20 byte chunks and sending each chunk separately.

sneko commented 3 years ago

Hi @nickes,

Splitting messages can be a solution indeed. How did you manage the retry on tiny chunks (this should done on client and server)? The start and end "char" that delimit your initial splitted message? Did you do this on your own or you found a well-known library?

The ideal solution would be to solve this issue of customizing the MTU ^^

Thank you,