Flutter_blue: Write characteristic doesn't work after requestMtu

Created on 14 Nov 2019  路  18Comments  路  Source: pauldemarco/flutter_blue

I faced an issue that after adding await currentDevice.requestMtu(242) to my code I cannot get write data to the characteristic. My code:
await currentDevice.requestMtu(242) characteristic.value.listen((value) { print("data received $value"); }); await writeCharacteristic.write(utf8.encode(command)).timeout(Duration(seconds: 3), onTimeout: () { print("onTimeout write"); });
Here is log output:
D/BluetoothGatt( 2556): configureMTU() - device: CA:6E:D6:5E:68:09 mtu: 242
I/flutter ( 2556): data received []
D/BluetoothGatt( 2556): onConfigureMTU() - Device=CA:6E:D6:5E:68:09 mtu=242 status=0
D/FlutterBluePlugin( 2556): [onMtuChanged] mtu: 242 status: 0
onTimeout write

But if I remove the line await currentDevice.requestMtu(242) I will be able to get the callback from the device.
Any thoughts?

mtu write-error

Most helpful comment

I found the solution to my issue, I had to enable Read property on my characteristic for the requestMtu to work and not block the write buffer. Hope this can be useful to someone.

All 18 comments

The issue happened only after immediate execution of write request, but if I do it asynchronously, i.e. after some user action then everything works good

Had the same issue, actually hardly anything works right after the requestMtu call, in my case I was doing the services discovery after that call (even when using await to ensure the call completed). The call doesn't actually seem to return when the MTU is actually changed, that seems to be done later, so what I did to fix it was waiting on a Completer's future that is completed when the mtu changes (using a listener on the mtu property).

I have the same issue. After requestMtu call, characteristic read and write doesn't work after requestMtu. If I remove requestMtu, then it will work again.

Please view #579

having the same issue.. something is messing up but I cannot point into the right direction why this is the case..

Had the same issue, actually hardly anything works right after the requestMtu call, in my case I was doing the services discovery after that call (even when using await to ensure the call completed). The call doesn't actually seem to return when the MTU is actually changed, that seems to be done later, so what I did to fix it was waiting on a Completer's future that is completed when the mtu changes (using a listener on the mtu property).

@nmbus do you have a code snippet to share how you used a Completer for that?

Same issue here, once requestMtu is called with or without await, then nothing works afterward, can't receive notifications either. I can't change MTU size, which makes all the communication protocol unusable.

I'm using this patch https://github.com/pauldemarco/flutter_blue/pull/579#issuecomment-628325875 to connect to bluetooth printers and setting mtu. It solved for me.
In android that code waits for the gatt event onMtuChanged before trigger completion, in that way you can write to bluetooth AFTER the mtu was set.

I'm using this patch #579 (comment) to connect to bluetooth printers and setting mtu. It solved for me.
In android that code waits for the gatt event onMtuChanged before trigger completion, in that way you can write to bluetooth AFTER the mtu was set.

Thanks, I already tried your patch, but unfortunately still experiencing the same issue. Once I call requestMtu, I can no longer write to the characteristic.
When I requestMtu using the nrf scanner app, it works perfectly, so I know its not my ble device at fault here.

I don't know what value you are passing in, but maybe it's a negotiation
problem.
What about passing lower values, let's say 20, then 40, then 100 and see if
anything changes. Search in the log panel for "[onMtuChanged]"

I don't know what value you are passing in, but maybe it's a negotiation problem. What about passing lower values, let's say 20, then 40, then 100 and see if anything changes. Search in the log panel for "[onMtuChanged]"

Im using await widget.device.requestMtu(185); as soon as I call it, Characteristic.write stops working, no matter what I do.
I checked the Mtu and it is indeed changed to 185, so it seems like the request to change Mtu is successful, but write calls no longer works.
When I set it using nrf scanner app it works perfectly.

Im using await widget.device.requestMtu(185); as soon as I call it, Characteristic.write stops working, no matter what I do.
I checked the Mtu and it is indeed changed to 185, so it seems like the request to change Mtu is successful, but write calls no longer works.
When I set it using nrf scanner app it works perfectly.

From what I understand of your explanation you are requesting a new MTU in the middle of your write operations ?

If it's the case it's probably normal that your write will stop since you are asking device for a new MTU and awaiting for it to answer which should stop any other writing operations.

In any case it's better to negotiate the MTU and wait for completion, before starting any writing operations.

Also if you already put the negotiation before writing, make sure that you copied the snippet @efreibe submitted in the correct file :

  • flutter_blue-0.7.2/lib/src/bluetooth_device.dart.

Maybe sharing the bit of code and the error prompted in your terminal would allow us to help you more too..

GL

I'm using this patch #579 (comment) to connect to bluetooth printers and setting mtu. It solved for me.
In android that code waits for the gatt event onMtuChanged before trigger completion, in that way you can write to bluetooth AFTER the mtu was set.

Thanks, I already tried your patch, but unfortunately still experiencing the same issue. Once I call requestMtu, I can no longer write to the characteristic.
When I requestMtu using the nrf scanner app, it works perfectly, so I know its not my ble device at fault here.

@xelons please be aware, the MTU is not necessarily the DATA MTU but maybe the ATT MTU (depends on iOS/Android and all other kind of things).. so after requesting an MTU of let's say 100, try to send only 97 bytes per char write as 3 bytes might still be required for the ATT header which is not consistently reported back. (the minimum ATT MTU is 23, but flutter_blue hardcodes initially an MTU of 20, thats why you don't have that issue with the initial MTU).

@Bobby9292 I request the Mtu after I connect and before I do any discovery or writes. It seems like the write buffer is stuck as soon as requestMtu is called.
@savar Thanks, yes I know, this issue is only happening on Android, iOS works fine. My write command is just about 10 bytes, my received notifications are the ones needing 185 (around 180 of data or less).

One thing that is worth noting is that my characteristic properties are set to notify and write, I'm going to enable read property on it and see if that is going to solve the blocking issue, although I don't think it makes much sense.

I found the solution to my issue, I had to enable Read property on my characteristic for the requestMtu to work and not block the write buffer. Hope this can be useful to someone.

@Bobby9292 I request the Mtu after I connect and before I do any discovery or writes. It seems like the write buffer is stuck as soon as requestMtu is called.
@savar Thanks, yes I know, this issue is only happening on Android, iOS works fine. My write command is just about 10 bytes, my received notifications are the ones needing 185 (around 180 of data or less).

One thing that is worth noting is that my characteristic properties are set to notify and write, I'm going to enable read property on it and see if that is going to solve the blocking issue, although I don't think it makes much sense.

As iOS is ignoring your requestMtu (see the docs) there is no surprise that this works fine on iOS :wink: .. but good to hear that you found the solution!

Same problem in my case.

Was this page helpful?
0 / 5 - 0 ratings