New issue
Advanced search Search tips

Issue 635320 link

Starred by 3 users

Issue metadata

Status: WontFix
Owner:
Closed: Aug 2016
Components:
EstimatedDays: ----
NextAction: ----
OS: Mac
Pri: 3
Type: Bug



Sign in to add a comment

[WebBluetooth]: Writing GATT characteristic results in an internal error

Reported by devel...@gmail.com, Aug 7 2016

Issue description

Chrome Version       : 54.0.2822.0
OS Version: OS X 10.11.6


UserAgentString: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2822.0 Safari/537.36


When writing a characteristic value of a GATT service an internal error occurs.
The data has been written to the device (the data ended up being transmitted to the device) but the Promise chain breaks because of the mentioned internal error (No Characteristics with specified UUID found in Service)

Code that writes the characteristic (TS):

private transmitDataPromise(characteristicUUID : string, checkDirtyAction, getBytesAction, successAction) {
    return this.m_service.getCharacteristic(characteristicUUID)
    .then((characteristic) => {
        if(checkDirtyAction()) {
            var data: Uint8Array = getBytesAction();
            return characteristic.writeValue(data);
        }
        return new Promise((resolve, reject) => { reject(); });
    })
    .then(() => {
        successAction();
    })
    .catch((ex) => { console.error(ex, "Error writing characteristic value!"); });
}

[...SNIP...]
Promise.all([
    this.transmitDataPromise(
        Protocol.STEER_CHARACTERISTIC_UUID,
        () => { 
            return l_steering != this.m_lastSentSteering; 
        },
        () => {  
            var angle = (l_steering * 90) / 100;

            var steeringData = new Uint8Array(1);
            steeringData[0] = Math.floor(angle);
				
            console.log("Sending steering (" + l_steering + "%)");

            return steeringData;
        },
        () => {
            this.m_lastSentSteering = l_steering;
            console.log("Sent steering (" + l_steering + "%)");
        }),
[...SNIP...]

See the attached log files (Chrome log and Mac BT log)

If you need any additional information about the environment please let me know.
 
chrome_log.log
88.5 KB View Download
PacketLogger.pklg
64.8 KB Download
Components: Blink>Bluetooth
Status: Available (was: Unconfirmed)
Owner: jlebel@chromium.org
Thanks for filing this bug Michael.
Jerome can you have a look please?
For info, here are the interesting logs I get from PacketLogger.pklg:

...
Info: **** [IOBluetoothHostControllerUSBTransport][BulkOutWriteCompleteAction] -- removed Bulk Out Write Timer 0xffffff8025205cc0 ****
Rcvd Error Response - Attribute Not Found, Handle: 0x0017
Sent LE Create Connection Cancel

Hello develmil,

Do you reproduce this problem all the time? What device do you use? I wish to reproduce this bug.

Thanks.
Also, can you give scan you device with the Apple application "Bluetooth Explorer" and tell me what are the properties of your characteristic?

Thanks,
I think they are using a Parrot Mini Drone. It seems to me that it's a problem with the device. The "No Characteristic Found" error is showing up because the device disconnected so we remove all it's services, characteristics, and descriptors. That said, we could be using the API in a way that causes the disconnection. I think Francois has a parrot drone.

Comment 8 by devel...@gmail.com, Aug 9 2016

Yes that is correct! It is a custom hardware. There might be an issue with the characteristic implementation but the Android App and the WebApp on Chrome for Android work.
I will do the characteristic scan when I'm back home and post them here.
Hmm then yeah then problem is probably with how we use the CoreBluetooth API.
I did connect to the device using the Bluetooth Explorer. I didn't find a way to export this information so I made a screenshot.
BTScan.png
187 KB View Download
And as a side note if this isn't clear: it doesn't matter what characteristic I try to write to. They all behave the same. The Steering characteristic I took as an example is only representative
Thanks for the screen shot! That's perfect!

I suspected you had a characteristic with Write and WriteWithoutResponse. I will try to get a characteristic like that on a device. It might work better if you change your characteristic to be Write or WriteWithResponse (but even if it works for you better that way, it is definitely a valid bug).

Thanks
Can you let us know if changing to either Write or WriteWithoutResponse works better for you? Not both at the same time.
Ok, I did some tests:
When the characteristics have read/write the same error occurs and breaks the Promise chain.
When the characteristics have read/write without response then the error also occurs but the Promise chain gets completed. The result is a slight delay but a much better behavior then with variant 1 (read/write).

I have attached the screenshots of the configurations I tested and the chrome log of the "write without response" try.
BTScan_write.png
165 KB View Download
BTScan_write_wo_response.png
178 KB View Download
chrome_log.log
93.3 KB View Download
Hello develmil,

I see that you use RedBear DUO and BLE Nano for you project. With which board do you have the problem? Where is the code for this board? Did you try to use something else than chrome to communicate with your board? Do you have the same problem when your attribute is in "write"?

I don't know very well RedBear. But I have a BLE Mini. Could I use your code on that board?

Thanks,

Comment 16 by devel...@gmail.com, Aug 10 2016

Hi,
The DUO is used for the communication with the app. You can find the code here:

https://github.com/devmil/remotelego/tree/master/embedded/RedBearDuo/LegoControl

You can try if it works on the Mini but as RedBear used different APIs for many of there boards I fear that this won't work out of the box.

I used Chrome for Android and a native Android app to communicate with the device and they both worked.

In the evening I will do some tests with an older Raspberry Pi variant of the car control software and see if this problem is reproducible in that setting.
If you can make a little code to reproduce it on a BLE Mini, that would be great! But maybe I should confirm I can find it somewhere in my house, before you send too much time on the code... 

Comment 18 by devel...@gmail.com, Aug 10 2016

Intermediate find: Chrome on Android also throws exceptions. I didn't see them because 
a) they don't break the Promise chain
b) I hadn't a version published that logs the errors

So summary so far on my environment:
Chrome on Mac breaks the Promise chain on Read/Write characteristics. Having "Read/Wrinte without response" characteristics doesn't break the Promise chain but throws exceptions.
On Android exceptions are thrown (the exact same exceptions) but they don't break the Promise chain.

Next:
I will try to get a reproduction of the problem using a BLE Mini (as far as I understand the BLE Mini isn't meant to be programmed directly for but it provides kind of a bridge to an UART connected device) as I also have one lying around.
I will also do some experiments with other BLE devices (directly accessing the BLE Nano for example) to get a better environment parameter narrowing.
What exceptions are you seeing?

Comment 20 by devel...@gmail.com, Aug 10 2016

I have attached the JavaScript log from the Android Chrome version.
One containing the communication with a model configured with read/write characteristics and containing the communication with a model configured with read/write without response characteristics.
chrome_android-write.log
20.9 KB View Download
chrome_android-write_wo_response.log
12.2 KB View Download

Comment 21 by devel...@gmail.com, Aug 10 2016

I'm on a hot track and I think the problem has something to do with the way I use the API. I will do some more tests with some variants tomorrow and post my findings here.
fwiw: You are not supposed to be calling Promise.all([char.writeValue(), char.writeValue()]). If you do this the second promise should reject with "In progress", but for some reason you are not getting this error...
For info, I've just tested this sample code on Mac and it works great:

...
let reset = new Uint8Array([1]);
Promise.all([
  heartRateControlPointCharacteristic.writeValue(reset),
  heartRateControlPointCharacteristic.writeValue(reset)
]);


I do get the "GATT operation already in progress" error.
It looks like the root issue is the fact that "this.m_service.getCharacteristic(characteristicUUID)" returns "DOMException: No Characteristics with specified UUID found in Service."

Michael, may you give a try to https://googlechrome.github.io/samples/web-bluetooth/characteristic-properties.html?service=40480f29-7bad-4ea5-8bf8-499405c9b324&characteristic=7baf8dca-2bfc-47fb-af29-042fccc180eb

This will simply read Steer characteristic properties from a nearby BLE device that advertises 40480f29-7bad-4ea5-8bf8-499405c9b324 Service UUID. I'd like to see if we also get the same error.

Comment 25 by devel...@gmail.com, Aug 11 2016

Hi,

a short update.

there was more than one problem involved this is why my narrowing took so long and that caused some misleading tracks:

For clarification

1) Characteristic not found
This is 100% no bug in Chrome. This has been caused by the WebApp implementation as it tried to get Characteristics that are optional. As the log didn't state the UUID that is missing I mistakenly mixed this log entry with the behavior the app showed (no / delayed characteristic write with a broken Promise chain)
2) Broken Promise chain
The Bluetooth implementation on the device had an issue. (The write method I have implemented returned the number of bytes written but the integer was expected to represent a boolean value so basically I always returned false)
So I think the Mac implementation behaves (in contrast to the Android implementation) correctly by throwing an exception upon a error code returned by the device. You can see this in the packet logger file I initially posted.
So again no bug in the Mac implementation. If anything then an issue in the Android implementation.

I fixed the BT implementation on the device, replaced the Promise.all with chaining the Promises one after the other and fixed the frequent requests for unavailable characteristics and I can see the following behavior:

a) the Promise chain isn't broken any more
b) there is a big delay between writing the data and the data arriving at the device
c) the chrome log still contains thrown exceptions (see attached files)

I will continue to do some tests.
I tried a BLE Nano and implemented an empty BT service with speed, steer and blink characteristics (set to read/write) and tested the application with it.
It basically behaves the same way the DUO behaves (laggy, exceptions, no broken Promise chain).

I will now try to reproduce this behavior using a small and simple test application.
chrome_device-write.log
147 KB View Download
packet_log-device-write.pklg
85.5 KB Download
Is this on macOS?

> there is a big delay between writing the data and the data arriving at the device

Is this a consequence of having to wait for previous values to be written or is a single write operation taking longer now? To speed things up you could use Write Without Response.

> the chrome log still contains thrown exceptions

The logs only show DOMException :) Could you print the name and message of the exception as well? 

Also, could you link to your source code so we can tell what "LegoCar.js (249)" refers to?

Comment 28 by devel...@gmail.com, Aug 11 2016

Yes, this is MacOS.
You are right. I switched back to WriteWithoutResponse and the delay got much better. Not as good as on Android though.

To be sure to have the log matching the source code I logged another round. You can find the source code for these logs here:
https://github.com/devmil/remotelego_app/tree/Chrome_BLE_bug_reference_1/src

I have no idea how to get more information about the errors in the logs because I don't get any exception object in the Promise catch. The log entry basically only states that the catch entry has been called without any argument and without any effect on the Promise chain. Maybe this is something completely different and independent of the Bluetooth API. This is why I want to create a small sample app.

I also attached the log of the Android Chrome running the app containing the same Promise catch calls.

The DOMExceptions you have seen in the other logs were GATT Exceptions stating that there is another GATT operation going on, they are OK and were triggered by a too frequent update call.

As far as I see this the only remaining "issue" is the mysterious catch call that doesn't have any effect and even may relate to some different problem (Promise related?)
chrome_device-writeWoResponse.log
7.4 KB View Download
chrome_device-writeWoResponse.pklg
91.9 KB Download
chrome-android_device-wrinteWoResponse.log
39.3 KB View Download
You are talking about "undefined "Error writing characteristic value! " right? That catch is getting executed with no arguments because you rejected the promise earlier with no arguments[1]:

if (checkDirtyAction()) {
  //...
}

return new Promise((resolve, reject) => { reject(); });

Also fwiw: you could replace that with "return Promise.reject()";

[1] https://github.com/devmil/remotelego_app/blob/687dd1d06d71ad3a46ab8d72a650efe458006562/src/app/shared/LegoCar.ts#L228

Comment 30 by devel...@gmail.com, Aug 11 2016

Ok... This is embarrassing :) thanks for the hint.

So no issue left.
Status: WontFix (was: Available)
Great! Feel free to open another bug if you run into any issues.

Sign in to add a comment