-
Notifications
You must be signed in to change notification settings - Fork 189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Missing API for GATT Write w/o Response #238
Comments
Do you have devices that allow both Write with Response and Write w/o Response on the same characteristic? What behavior do you want when the requested write type isn't among the characteristic's properties? I suspect the API shape will be |
Is possible and allowed by the BT spec.
I'd say if
Sounds good to me! |
Hi, I think I may got stuck in this issue: basically I'm trying to cache the GATT server connection, but when I write some data it executes the command and it disconnects right after! So the second time that I try to write a command using the cached service variable, I get the error "Uncaught (in promise) DOMException: GATT Service no longer exists.". I started to guess why this happens and then I read that the kind of command in this case, for my device, is "without response", so, guessing, when the API doesn't get anything after the promise, it disconnects the GATT server. If this is right...is there a workaround or we need to wait an update in the API? :\ |
It would be great if you could open a Chromium issue with your problem. Here are the instructions: https://www.chromium.org/developers/how-tos/file-web-bluetooth-bugs |
For info, @360fun also reported this issue at poshaughnessy/web-bluetooth-parrot-drone#1 (comment) |
Yes I did :) I'm kind of lost...but now I've a new way to investigate the issue, thanks! :D I never worked with Bluetooth before, so is good to learn! ;) |
We'll continue conversation at poshaughnessy/web-bluetooth-parrot-drone#1 (comment) to not pollute this thread and come back if it's a Web Bluetooth API issue. |
I'm also in favor for adding this option. From the Bluetooth spec:
It basically informs that Write Without Response should be chosen when the client does not need an acknowledgement. In this case I guess the "client" should refer to the application (and not the stack or browser) since the application is the only one who knows if an acknowledgement is really needed or not. The Bluetooth spec does not state that Write Without Response can only be used if no other write sub-procedures are allowed according to the characteristic's permissions. If the client wants to write many values and it ignores Write Responses, and the browser by itself chooses Write With Response, it results in wasteful significant delays. |
In the end I found that the problem was in my device: a watchdog is killing the connection after 500ms, so I just have to use a loop to keep alive the connection! :) But was nice to discover this thing anyway and know a bit more about Bluetooth. :D |
It goes both ways, if the remote device does not support this mode for some reason then the values would be ignored so at least it shouldn't be the default behavior. |
Just to be clear, this option would only be useful if one single bluetooth characteristic supports |
@beaufortfrancois I have a device with a characteristic which supports both write and write without response. The device is the BBC micro:bit. It has an event bus which is exposed over Bluetooth via input and output event characteristics. For the input event, you can use either write or write without response. The point is that events are a generalised mechanism for communicating with the micro:bit and the decision as to whether acknowledged or unacknowledged writes are required has to be taken on an application by application basis. We definitely need this. Some of the standard SIG defined Bluetooth services allow characteristics which support both variants too btw. For example: Automation IO: Human Interface Device (HID): |
Hi All, Also need this for Silicon Labs Bluetooth over the air updates which have both Write and Write without response. Any updates on whether this can be added in the near future? Cheers |
@timmyhadwen, can you clarify whether you need support for both methods because of your application logic or because the UA is choosing the wrong one (perhaps the device advertises support for both and one is broken)? |
On this topic (I hope), please may I check... It looks from the spec that (We're developing a Bluetooth peripheral and it should be returning a success response from the 'write' command, but I'm not receiving it back...) I wondered if this is by design and if so, how this would fit in with this split between write with response, and write without response. Should write with response return a value from the Promise? |
@poshaughnessy: in both cases the promise returned by writeValue should resolve. This sounds like a bug with the implementation or the peripheral. Would you mind opening a bug at http://crbug.com/new with a repro case? If you can include logs that would be great. Instructions at: https://www.chromium.org/developers/how-tos/file-web-bluetooth-bugs |
I'm wondering if this is this ever going to be addressed? It's clearly a mistake in the Web Bluetooth specification. Characteristics may support both WRITE (requests) and WRITE WITHOUT RESPONSE and a browser cannot be expected to second guess which is the most appropriate to use for a given application. Only the application developer can decide whether reliability or responsiveness are their priorities. There need to be two distinct APIs available or a flag which allows developers to indicate which variant should be used. You can continue to default to the current auto (not very) magic approach for backward compatibility. There are plenty of examples of characteristics with both write operations supported, clearly documented at bluetooth.com. |
@reillyeon @dougt Shall we add |
BlueZ now finally supports to select which write type to perform (Write With Response or Write Without Response) since https://git.kernel.org/pub/scm/bluetooth/bluez.git/commit/?id=fa9473bcc48417d69cc9ef81d41a72b18e34a55a. This means it is now implementable on all platforms, so there shouldn't be any reason to hide the option for the user anymore. As we have seen, there are multiple devices out in the market allowing both write types and it would be good to fully support them. |
I'm not implementing this and don't know when @reillyeon's team will have time, but I'd probably design the API as, |
I think I would rather use |
I suggest the following: |
@MikeTheDane 's suggestion looks good to me. |
@reillyeon Do you think you'd have time to implement this? If not, I'm happy to have a look and start prototyping something. |
@MikeTheDane, @bluetooth-mdw, @Emill, @poshaughnessy, @timmyhadwen, @martijnthe What do you think of this proposal? // Write value to a BLE characteristic. Client trusts UA to know which type to send.
try {
await myCharacteristic.writeValue(someData, { response: 'auto' });
// OR await `myCharacteristic.writeValue(someData);`
} catch(error) {
// Error is thrown if BLE characteristic does NOT support any write operation.
}
// Write value with response to a BLE characteristic.
try {
await myCharacteristic.writeValue(someData, { response: 'with' });
} catch(error) {
// [NEW] Error is thrown if BLE characteristic does NOT support writeWithResponse.
}
// Write value without response to a BLE characteristic.
try {
await myCharacteristic.writeValue(someData, { response: 'without' });
} catch(error) {
// [NEW] Error is thrown if BLE characteristic does NOT support writeWithoutResponse.
} |
Yes that looks ok to me! |
I think the advantage of |
I don't think we should abstract the Web Bluetooth developer too far from
the Bluetooth specification. When you write an app, you should know which
properties are supported for each individual GATT characteristic that you
are interacting with. It is very easy to figure this out in the chrome
browser if you do not have access to documentation (
chrome://bluetooth-internals/#devices ).
There should be 2 write methods (write w/o response and write w/ response)
in addition to the existing "best effort write" which should remain for
backward compatibility.
My two cents...
…On Tue, Apr 28, 2020 at 6:34 PM Vincent Scheib ***@***.***> wrote:
My personal thoughts on:
a) writeValue should be specified to follow a specific algorithm. I agree
with @g-ortuno <https://github.com/g-ortuno>'s preferring
writeWithResponse.
b) I believe Web Bluetooth should not check characteristic properties.
Applications can access characteristic properties to check themselves if
needed. If an algorithm can work with a device advertising incorrect
property bits I'd like the application to have a chance to attempt it.
If the algorithm won't work it will fail regardless. The value of having
Web Bluetooth check would be i) consistent error type and ii) cross
platform consistency. But these come at the expense of application
functionality.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#238 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACNNFKNREUSXZFOTTR2SERTRO57ZLANCNFSM4CC422ZQ>
.
|
I agree with @MikeTheDane . The remote device will enforce its own rules anyway. |
Please correct me if I'm wrong, but it sounds like there's still agreement to have two explicit methods for write with/without response while keeping the original writeValue. This change was already added to the spec with #433. It also looks like there's agreement that the specified write should be done regardless of the characteristic properties. I also agree with these ideas. If that's the case, what's left is to agree on a default algorithm for writeValue(), which @scheib and @g-ortuno prefer writeWithResponse(). Would this algorithm also be the "best effort write" @MikeTheDane and @bluetooth-mdw ? |
I would leave the "best effort write" exactly as is - whatever that is. It
should only remain to ensure backward compatibility, and it should
potentially come with a note to not use it in new projects - perhaps even
be removed from the documentation entirely (it should have never existed in
the first place).Changing the method will break implementations. I should
note that in one of my implementations the GATT server device offered both
WriteNoResponse and WriteWithResponse for a characteristic used for
firmware upgrade over the air. Unfortunaltely writeValue() in my case
picked WriteWithResponse and the firmware upgrade took about twice as long.
Changing the GATT options to only offer WriteNoResponse fixed this issue,
but I could only do that because I am in control of the device firmware
(probably unlike most people).
…On Wed, Apr 29, 2020 at 10:45 AM Ovidio Ruiz-Henríquez < ***@***.***> wrote:
Please correct me if I'm wrong, but it sounds like there's still agreement
to have two explicit methods for write with/without response while keeping
the original writeValue. This change was already added to the spec with
#433 <#433>. It also
looks like there's agreement that the specified write should be done
regardless of the characteristic properties. I also agree with these ideas.
If that's the case, what's left is to agree on a default algorithm for
writeValue(), which @scheib <https://github.com/scheib> and @g-ortuno
<https://github.com/g-ortuno> prefer writeWithResponse(). Would this
algorithm also be the "best effort write" @MikeTheDane
<https://github.com/MikeTheDane> and @bluetooth-mdw
<https://github.com/bluetooth-mdw> ?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#238 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACNNFKL7SZOWLKIQVQQJB7TRPBRTHANCNFSM4CC422ZQ>
.
|
The issue with best effort is that it's not specified, so what we do depends on the underlying platform. I think it would be good to specify what we mean by best effort. |
Giovanni, your short description "depends on the underlying platform" with
the added recommendation not to ever use it for that very reason should
suffice. Do you agree?
…On Wed, Apr 29, 2020 at 4:48 PM Giovanni Ortuño ***@***.***> wrote:
The issue with best effort is that it's not specified, so what we do
depends on the underlying platform. I think it would be good to specify
what we mean by best effort.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#238 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACNNFKPXBBUARYZSCAN5B2LRPC4GDANCNFSM4CC422ZQ>
.
|
For not using |
FWIW, the current implementation of |
That's one reason that the specification should declare what algorithm As for the error, the algorithm for write value currently specifies that in that scenario, |
The Bluetooth specification specifies that the DEVICE should throw the
NotSupportedError error over the link when an unsupported GATT request is
received. It does not specify, nor should it specify, how that is
communicated to upper layers on the peer device or what action to take when
this error occurs.
I strongly believe that Web Bluetooth should specify writeValue() as an
obsolete method that should not be used in new implementations due to the
inconsistent behavior on various platforms. Changing the behavior of
writeValue() in ANY way would completely remove the need to keep it - which
is to ensure backward compatibility. I would even suggest that the method
is retired after a certain period of time (leave it after this time, but
remove it from the documentation).
…On Thu, Apr 30, 2020 at 3:28 PM Ovidio Ruiz-Henríquez < ***@***.***> wrote:
That's one reason that the specification should declare what algorithm
writeValue() should use. That would clear up any confusion on how this
API is implemented for both users and implementors.
As for the error, the algorithm for write value currently specifies that
in that scenario, NotSupportedError should be thrown. So it looks like
that's a bug for Chromium's implementation using BlueZ.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#238 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACNNFKJDBMXCEA6PVGL465DRPH3QTANCNFSM4CC422ZQ>
.
|
Ah, I misunderstood where the error was coming from. From a Web Bluetooth point of view, I was suggesting that the error returned should be consistent if the platform does not support writing to a characteristic without the write property set. I do acknowledge that this might not be easy to do given that different errors are produced by different platforms. I see what you mean now, and I agree now that |
I agree that |
This deprecates BluetoothRemoteGATTCharacteristic.writeValue() in favor of writeValueWithResponse() and writeValueWithoutResponse(). Issue: WebBluetoothCG#238
This deprecates BluetoothRemoteGATTCharacteristic.writeValue() in favor of writeValueWithResponse() and writeValueWithoutResponse(). Issue: WebBluetoothCG#238
This deprecates BluetoothRemoteGATTCharacteristic.writeValue() in favor of writeValueWithResponse() and writeValueWithoutResponse(). Issue: WebBluetoothCG#238
This deprecates BluetoothRemoteGATTCharacteristic.writeValue() in favor of writeValueWithResponse() and writeValueWithoutResponse(). Issue: #238
This deprecates the current implementation of WriteRemoteCharacteristic. This implementation has been found to have issues when dealing with writing with response vs. writing without response. For example, most platforms look at characteristic properties to determine which to use and prefer writing with response if both are available while Android uses the OS default without looking the properties. Furthermore, there is currently no way to explicitly select writing with or without response. WriteRemoteCharacteristic will be replaced by a new implementation in crrev.com/c/2191232. However, to maintain backward compatibility we need to keep the current implementation as-is. So, we rename it to DeprecatedWriteRemoteCharacteristic. Unit tests that test this method are also renamed accordingly. Ref: WebBluetoothCG/web-bluetooth#238 Also fix spelling of "already" in a comment while we are touching this code. Bug: 672648 Change-Id: I4469a51de960e2b6215b8f402318ee901ba5c335 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2191231 Commit-Queue: Reilly Grant <[email protected]> Reviewed-by: Ryan Hansberry <[email protected]> Reviewed-by: Sonny Sasaka <[email protected]> Reviewed-by: Hidehiko Abe <[email protected]> Reviewed-by: Reilly Grant <[email protected]> Reviewed-by: Ovidio de Jesús Ruiz-Henríquez <[email protected]> Reviewed-by: Vincent Scheib <[email protected]> Cr-Commit-Position: refs/heads/master@{#769901}
Interested web-devs: @dlech 's chromium patch adding Give it a try in Chrome Canary with chrome://flags/#enable-experimental-web-platform-features set. |
The new writeWithResponse() and writeWithoutResponse() methods are available in Chrome 85. |
There does not seem to be a way to specify that the GATT Write w/o Response operation should be used when calling
writeValue()
.I don't think this should be "abstracted away" / left up to the UA implementation because this is the only GATT operation by which GATT clients can have more than one GATT packets in flight towards the GATT server. The other write operations have to be ack'd before the next write can be sent out, making it very slow.
Most applications that I've seen that need to optimize for throughput (Pebble smartwatch, Parrot's drones, ...), usually use GATT Write w/o Response in combination with GATT Value Notifications for data in the other direction.
Also related: #26
The text was updated successfully, but these errors were encountered: