IanHarvey / bluepy

Python interface to Bluetooth LE on Linux
Other
1.6k stars 490 forks source link

setMTU race condition? #325

Open csonsino opened 5 years ago

csonsino commented 5 years ago

There seems to be a race condition between the Peripheral connect() and setMTU() functions. If setMTU() is called immediately after connect(), the MTU is not always negotiated properly. The observed behavior is that the MTU appears to be negotiated properly, but then reading a characteristic that is supposed to return a "large" value (more than 22 bytes) results in only receiving the first 22 bytes.

This is a very intermittent issue, and appears to occur more frequently when running "fast". I see this issue up to 50% of the time when running my python application from the terminal, but I see it much less frequently when running in a debugger (pycharm).

It appears to have some relationship to which side initiates the MTU negotiation. Relevant btmon output below. Notice that in the success case, the remote device is the one that sends the first Exchange MTU Request, whereas in the failure case it is the local device that initiates the Exchange MTU Request. I would also note that I'm not sure why my local device is responding with Request Not Supported, but it does not seem to affect anything.

I seem to have resolved the issue by inserting a time.sleep(0.5) between the connect() and setMTU() calls. I'm not exactly sure how long of a sleep is required, but after adding the 1/2 second sleep(), I have yet to see this problem occur again.

Success case

> ACL Data RX: Handle 18 flags 0x02 dlen 7                                          #5989 [hci0] 5282.660245
      ATT: Exchange MTU Request (0x02) len 2
        Client RX MTU: 104
< ACL Data TX: Handle 18 flags 0x00 dlen 9                                          #5990 [hci0] 5282.660660
      ATT: Error Response (0x01) len 4
        Exchange MTU Request (0x02)
        Handle: 0x0000
        Error: Request Not Supported (0x06)
< ACL Data TX: Handle 18 flags 0x00 dlen 7                                          #5991 [hci0] 5282.661032
      ATT: Exchange MTU Request (0x02) len 2
        Client RX MTU: 185
> HCI Event: Number of Completed Packets (0x13) plen 5                              #5992 [hci0] 5282.705223
        Num handles: 1
        Handle: 18
        Count: 2
> ACL Data RX: Handle 18 flags 0x02 dlen 7                                          #5993 [hci0] 5282.749175
      ATT: Exchange MTU Response (0x03) len 2
        Server RX MTU: 104

Failure case

< ACL Data TX: Handle 64 flags 0x00 dlen 7                     [hci0] 42.373367
      ATT: Exchange MTU Request (0x02) len 2
        Client RX MTU: 185
> ACL Data RX: Handle 64 flags 0x02 dlen 7                     [hci0] 42.417932
      ATT: Exchange MTU Request (0x02) len 2
        Client RX MTU: 104
< ACL Data TX: Handle 64 flags 0x00 dlen 9                     [hci0] 42.418090
      ATT: Error Response (0x01) len 4
        Exchange MTU Request (0x02)
        Handle: 0x0000
        Error: Request Not Supported (0x06)
> HCI Event: Number of Completed Packets (0x13) plen 5         [hci0] 42.467363
        Num handles: 1
        Handle: 64
        Count: 2
> ACL Data RX: Handle 64 flags 0x02 dlen 7                     [hci0] 42.515483
      ATT: Exchange MTU Response (0x03) len 2
        Server RX MTU: 104