@@ -4102,6 +4102,30 @@ slots</a> described in the following table:
41024102 has been removed or otherwise invalidated.
41034103 </td>
41044104</tr>
4105+ <tr>
4106+ <td> <dfn>\[[automatedDescriptorReadResponse]]</dfn> </td>
4107+ <td><code> "not-expected"</code></td>
4108+ <td>
4109+ The simulated GATT descriptor response code for a GATT descriptor
4110+ read attempt.
4111+ </td>
4112+ </tr>
4113+ <tr>
4114+ <td> <dfn>\[[automatedDescriptorReadResponseData]]</dfn> </td>
4115+ <td> Empty <a>byte sequence</a> </td>
4116+ <td>
4117+ The simulated GATT descriptor response data for a GATT descriptor
4118+ read attempt.
4119+ </td>
4120+ </tr>
4121+ <tr>
4122+ <td> <dfn>\[[automatedDescriptorWriteResponse]]</dfn> </td>
4123+ <td><code> "not-expected"</code></td>
4124+ <td>
4125+ The simulated GATT descriptor response code for a GATT descriptor
4126+ write attempt.
4127+ </td>
4128+ </tr>
41054129</table>
41064130
41074131<div algorithm="BluetoothRemoteGATTDescriptor constructor">
@@ -4146,27 +4170,48 @@ readValue()</dfn></code> method, when invoked, MUST run the following steps:
41464170 "{{InvalidStateError}} " {{DOMException}} .
414741711. Return a |gatt|-[=connection-checking wrapper=] around [=a new promise=]
41484172 |promise| and run the following steps [=in parallel=] :
4149- 1. If the UA is currently using the Bluetooth system, it MAY [=queue a
4150- global task=] on the [=Bluetooth task source=] given |global| to
4151- [=reject=] |promise| with a "{{NetworkError}} " {{DOMException}} and
4152- abort these steps.
4173+ 1. If |global|'s [=Window/navigable=]' s
4174+ [=navigable/top-level traversable=] 's <a>simulated Bluetooth adapter</a>
4175+ is not empty, run the following steps:
4176+ 1. If [=this=] .{{[[automatedDescriptorReadResponse]]}} is not `"not-expected"`,
4177+ [=queue a global task=] on the [=Bluetooth task source=] given |global| to
4178+ [=reject=] |promise| with a "{{InvalidStateError}} " {{DOMException}} and abort
4179+ these steps.
4180+ 1. [=Trigger a simulated descriptor event=] given |global|'s
4181+ [=Window/navigable=] , [=this=] .{{BluetoothRemoteGATTServer/device}} ,
4182+ |descriptor|, and `read`.
4183+ 1. Set [=this=] .{{[[automatedDescriptorReadResponse]]}} to `"expected"`,
4184+ and wait for it to change.
4185+ 1. Let |response| be [=this=] .{{[[automatedDescriptorReadResponse]]}} .
4186+ 1. Set [=this=] .{{[[automatedDescriptorReadResponse]]}} to `"not-expected"`.
4187+ 1. If |response| is not `0`, do the following sub-steps:
4188+ 1. [=Queue a global task=] on the [=Bluetooth task source=] given
4189+ |global| to [=reject=] |promise| with a "{{NetworkError}} "
4190+ {{DOMException}} and abort these steps.
4191+ 1. Otherwise, let |buffer| be a [=new=] {{ArrayBuffer}} containing
4192+ [=this=] .{{[[automatedDescriptorReadResponseData]]}} .
4193+ 1. Otherwise, run the following steps:
4194+ 1. If the UA is currently using the Bluetooth system, it MAY [=queue a
4195+ global task=] on the [=Bluetooth task source=] given |global| to
4196+ [=reject=] |promise| with a "{{NetworkError}} " {{DOMException}} and
4197+ abort these steps.
41534198
4154- Issue(188): Implementations may be able to avoid this {{NetworkError}} ,
4155- but for now sites need to serialize their use of this API
4156- and/or give the user a way to retry failed operations.
4157- 1. Use either the [=Read Characteristic Descriptors=] or the [=Read Long
4158- Characteristic Descriptors=] sub-procedure to retrieve the value of
4159- |descriptor|. Handle errors as described in
4160- <a href="#error-handling"></a> .
4199+ Issue(188): Implementations may be able to avoid this {{NetworkError}} ,
4200+ but for now sites need to serialize their use of this API
4201+ and/or give the user a way to retry failed operations.
4202+ 1. Use either the [=Read Characteristic Descriptors=] or the [=Read Long
4203+ Characteristic Descriptors=] sub-procedure to retrieve the value of
4204+ |descriptor| and let |buffer| be a [=new=] {{ArrayBuffer}} holding the
4205+ retrieved value. Handle errors as described in
4206+ <a href="#error-handling"></a> .
41614207 1. [=Queue a global task=] on the [=Bluetooth task source=] given |global|
41624208 to perform the following steps:
41634209 1. If |promise| is not in |gatt|.{{[[activeAlgorithms]]}} , [=reject=]
41644210 |promise| with a "{{NetworkError}} " {{DOMException}} and abort
41654211 these steps.
41664212 1. If the sub-procedure above returned an error, [=reject=] |promise|
41674213 with that error and abort these steps.
4168- 1. Let |buffer| be a [=new=] {{ArrayBuffer}} holding the retrieved
4169- value, and assign a [=new=] {{DataView}} created with |buffer| to
4214+ 1. Assign a [=new=] {{DataView}} created with |buffer| to
41704215 [=this=] .{{BluetoothRemoteGATTDescriptor/value}} .
41714216 1. [=Resolve=] |promise| with
41724217 [=this=] .{{BluetoothRemoteGATTDescriptor/value}} .
@@ -4194,18 +4239,37 @@ following steps:
41944239 "{{InvalidStateError}} " {{DOMException}} .
419542401. Return a |gatt|-[=connection-checking wrapper=] around [=a new promise=]
41964241 |promise| and run the following steps [=in parallel=] .
4197- 1. If the UA is currently using the Bluetooth system, it MAY [=queue a
4198- global task=] on the [=Bluetooth task source=] given |global| to
4199- [=reject=] |promise| with a "{{NetworkError}} " {{DOMException}} and
4200- abort these steps.
4242+ 1. If |global|'s [=Window/navigable=]' s
4243+ [=navigable/top-level traversable=] 's <a>simulated Bluetooth adapter</a>
4244+ is not empty, run the following steps:
4245+ 1. If [=this=] .{{[[automatedDescriptorWriteResponse]]}} is not `"not-expected"`,
4246+ [=queue a global task=] on the [=Bluetooth task source=] given |global| to
4247+ [=reject=] |promise| with a "{{InvalidStateError}} " {{DOMException}} and abort
4248+ these steps.
4249+ 1. [=Trigger a simulated descriptor event=] given |global|'s
4250+ [=Window/navigable=] , [=this=] .{{BluetoothRemoteGATTServer/device}} ,
4251+ |descriptor|, `write`, and |bytes|.
4252+ 1. Set [=this=] .{{[[automatedDescriptorWriteResponse]]}} to `"expected"`,
4253+ and wait for it to change.
4254+ 1. Let |response| be [=this=] .{{[[automatedDescriptorWriteResponse]]}} .
4255+ 1. Set [=this=] .{{[[automatedDescriptorWriteResponse]]}} to `"not-expected"`.
4256+ 1. If |response| is not `0`, do the following sub-steps:
4257+ 1. [=Queue a global task=] on the [=Bluetooth task source=] given
4258+ |global| to [=reject=] |promise| with a "{{NetworkError}} "
4259+ {{DOMException}} and abort these steps.
4260+ 1. Otherwise, run the following steps:
4261+ 1. If the UA is currently using the Bluetooth system, it MAY [=queue a
4262+ global task=] on the [=Bluetooth task source=] given |global| to
4263+ [=reject=] |promise| with a "{{NetworkError}} " {{DOMException}} and
4264+ abort these steps.
42014265
4202- Issue(188): Implementations may be able to avoid this {{NetworkError}} ,
4203- but for now sites need to serialize their use of this API
4204- and/or give the user a way to retry failed operations.
4205- 1. Use either the [=Write Characteristic Descriptors=] or the [=Write Long
4206- Characteristic Descriptors=] sub-procedure to write |bytes| to
4207- |descriptor|. Handle errors as described in
4208- <a href="#error-handling"></a> .
4266+ Issue(188): Implementations may be able to avoid this {{NetworkError}} ,
4267+ but for now sites need to serialize their use of this API
4268+ and/or give the user a way to retry failed operations.
4269+ 1. Use either the [=Write Characteristic Descriptors=] or the [=Write Long
4270+ Characteristic Descriptors=] sub-procedure to write |bytes| to
4271+ |descriptor|. Handle errors as described in
4272+ <a href="#error-handling"></a> .
42094273 1. [=Queue a global task=] on the [=Bluetooth task source=] given |global|
42104274 to perform the following steps:
42114275 1. If |promise| is not in |gatt|.{{[[activeAlgorithms]]}} , [=reject=]
@@ -5139,11 +5203,15 @@ is an <a>ordered map</a> of Bluetooth <a>UUID</a> strings to <a>simulated GATT c
51395203
51405204A <dfn>simulated GATT characteristic</dfn> is a software defined [=Characteristic=] that belongs to a
51415205<a>simulated GATT service</a> , has a property of <a>UUID</a> , a property of <a>Characteristic Properties</a> ,
5142- and is known-present in the <a>Bluetooth cache</a> .
5206+ is known-present in the <a>Bluetooth cache</a> , and has a <dfn>simulated GATT descriptor mapping</dfn> , which
5207+ is an <a>ordered map</a> of Bluetooth <a>UUID</a> strings to <a>simulated GATT descriptors</a> .
51435208
51445209<dfn>Simulated GATT characteristic properties</dfn> are software defined [=Characteristic Properties=] that belong to a
51455210<a>simulated GATT characteristic</a> and are known-present in the <a>Bluetooth cache</a> .
51465211
5212+ A <dfn>simulated GATT descriptor</dfn> is a software defined [=Descriptor=] that belongs to a
5213+ <a>simulated GATT characteristic</a> , has a property of <a>UUID</a> , and is known-present in the <a>Bluetooth cache</a> .
5214+
51475215Issue: CDDL snippetes use the "text" type instead of
51485216"browsingContext.BrowsingContext" to allow indepedent programmatic
51495217processing of CDDL snippets. Currently, other modules cannot be
@@ -5757,7 +5825,7 @@ The [=remote end steps=] with command parameters |params| are:
57575825 and add a mapping from |simulatedGattService| to the resulting {{Promise}} in
57585826 |simulatedDeviceInstance|.{{[[context]]}} .{{Bluetooth/[[attributeInstanceMap]]}} .
57595827 1. Return [=success=] with data `null`.
5760- 1. Else if |params|[`"type"`] is `"remove"`:
5828+ 1. If |params|[`"type"`] is `"remove"`:
57615829 1. If |serviceMapping|[|uuid|] [=map/exists=] , let |simulatedGattService| be |serviceMapping|[|uuid|] .
57625830 1. Otherwise, return [=error=] with [=error code=] [=invalid element state=] .
57635831 1. Remove |simulatedGattService| from |simulatedDeviceInstance|.{{[[context]]}} .{{Bluetooth/[[attributeInstanceMap]]}} .
@@ -5867,7 +5935,7 @@ The [=remote end steps=] with command parameters |params| are:
58675935 and add a mapping from |simulatedGattCharacteristic| to the resulting {{Promise}} in
58685936 |simulatedDeviceInstance|.{{[[context]]}} .{{Bluetooth/[[attributeInstanceMap]]}} .
58695937 1. Return [=success=] with data `null`.
5870- 1. Else if |params|[`"type"`] is `"remove"`:
5938+ 1. If |params|[`"type"`] is `"remove"`:
58715939 1. If |params|[`"characteristicProperties"`] [=map/exists=] , return [=error=] with [=error code=] [=invalid argument=] .
58725940 1. If |characteristicMapping|[|characteristicUuid|] [=map/exists=] , let |simulatedGattCharacteristic|
58735941 be |characteristicMapping|[|characteristicUuid|] .
@@ -6025,7 +6093,46 @@ bluetooth.SimulateDescriptorParameters = {
60256093
60266094<div algorithm="remote end steps for bluetooth.simulateDescriptor">
60276095
6028- Issue: TODO: Finish the algorithm of bluetooth.simulateDescriptor.
6096+ 1. Let |contextId| be |params|[`"context"`] .
6097+ 1. Let |navigable| be the result of [=trying=] to [=get a navigable=] with |contextId|.
6098+ 1. Let |deviceAddress| be |params|[`"address"`] .
6099+ 1. Let |simulatedBluetoothAdapter| be |navigable|'s <a>simulated Bluetooth adapter</a> .
6100+ 1. If |simulatedBluetoothAdapter| is empty, return [=error=] with [=error code=] [=invalid argument=] .
6101+ 1. Let |deviceMapping| be |simulatedBluetoothAdapter|'s <a>simulated Bluetooth device mapping</a> .
6102+ 1. If |deviceMapping|[|deviceAddress|] [=map/exists=] , let |simulatedDevice| be |deviceMapping|[|deviceAddress|] .
6103+ 1. Otherwise, return [=error=] with [=error code=] [=invalid argument=] .
6104+ 1. Let |simulatedDeviceInstance| be the result of <a>get the <code>BluetoothDevice</code> representing</a>
6105+ |simulatedDevice| inside |navigable|'s <a>active window</a>' s <a spec=HTML>associated <code>Navigator</code></a> 's
6106+ [=associated Bluetooth=] .
6107+ 1. Let |serviceMapping| be |simulatedDevice|'s <a>simulated GATT service mapping</a> .
6108+ 1. Let |serviceUuid| be |params|[`"serviceUuid"`] .
6109+ 1. If |serviceMapping|[|serviceUuid|] [=map/exists=] , let |simulatedService| be |serviceMapping|[|serviceUuid|] .
6110+ 1. Otherwise, return [=error=] with [=error code=] [=invalid argument=] .
6111+ 1. Let |characteristicMapping| be |simulatedService|'s <a>simulated GATT characteristic mapping</a> .
6112+ 1. Let |characteristicUuid| be |params|[`"characteristicUuid"`] .
6113+ 1. If |characteristicMapping|[|characteristicUuid|] [=map/exists=] , let |simulatedCharacteristic| be
6114+ |characteristicMapping|[|characteristicUuid|] .
6115+ 1. Otherwise, return [=error=] with [=error code=] [=invalid argument=] .
6116+ 1. Let |descriptorMapping| be |simulatedCharacteristic|'s <a>simulated GATT descriptor mapping</a> .
6117+ 1. Let |descriptorUuid| be |params|[`"descriptorUuid"`] .
6118+ 1. If |params|[`"type"`] is `"add"`:
6119+ 1. If |descriptorMapping|[|descriptorUuid|] [=map/exists=] , return [=error=] with
6120+ [=error code=] [=invalid element state=] .
6121+ 1. Let |simulatedGattDescriptor| be a new <a>simulated GATT descriptor</a> .
6122+ 1. Set |simulatedGattDescriptor|'s <a>UUID</a> to |descriptorUuid|.
6123+ 1. Set |descriptorMapping|[|descriptorUuid|] to |simulatedGattDescriptor|.
6124+ 1. <a>Create a <code>BluetoothRemoteGATTDescriptor</code> representing</a> |simulatedGattDescriptor|
6125+ and add a mapping from |simulatedGattDescriptor| to the resulting {{Promise}} in
6126+ |simulatedDeviceInstance|.{{[[context]]}} .{{Bluetooth/[[attributeInstanceMap]]}} .
6127+ 1. Return [=success=] with data `null`.
6128+ 1. If |params|[`"type"`] is `"remove"`:
6129+ 1. If |descriptorMapping|[|descriptorUuid|] [=map/exists=] , let |simulatedGattDescriptor|
6130+ be |descriptorMapping|[|descriptorUuid|] .
6131+ 1. Otherwise, return [=error=] with [=error code=] [=invalid element state=] .
6132+ 1. Remove |simulatedGattDescriptor| from |simulatedDeviceInstance|.{{[[context]]}} .{{Bluetooth/[[attributeInstanceMap]]}} .
6133+ 1. Remove |descriptorUuid| from |descriptorMapping|.
6134+ 1. Return [=success=] with data `null`.
6135+ 1. Return [=error=] with [=error code=] [=invalid argument=] .
60296136
60306137</div>
60316138
@@ -6087,7 +6194,44 @@ bluetooth.SimulateDescriptorResponseParameters = {
60876194
60886195<div algorithm="remote end steps for bluetooth.simulateDescriptorResponse">
60896196
6090- Issue: TODO: Finish the algorithm of bluetooth.simulateDescriptorResponse.
6197+ 1. Let |contextId| be |params|[`"context"`] .
6198+ 1. Let |navigable| be the result of [=trying=] to [=get a navigable=] with |contextId|.
6199+ 1. Let |deviceAddress| be |params|[`"address"`] .
6200+ 1. Let |simulatedBluetoothAdapter| be |navigable|'s <a>simulated Bluetooth adapter</a> .
6201+ 1. If |simulatedBluetoothAdapter| is empty, return [=error=] with [=error code=] [=invalid argument=] .
6202+ 1. Let |deviceMapping| be |simulatedBluetoothAdapter|'s <a>simulated Bluetooth device mapping</a> .
6203+ 1. If |deviceMapping|[|deviceAddress|] [=map/exists=] , let |simulatedDevice| be |deviceMapping|[|deviceAddress|] .
6204+ Otherwise, return [=error=] with [=error code=] [=invalid argument=] .
6205+ 1. Let |serviceMapping| be |simulatedDevice|'s <a>simulated GATT service mapping</a> .
6206+ 1. Let |serviceUuid| be |params|[`"serviceUuid"`] .
6207+ 1. If |serviceMapping|[|serviceUuid|] [=map/exists=] , let |simulatedService| be |serviceMapping|[|serviceUuid|] .
6208+ 1. Otherwise, return [=error=] with [=error code=] [=invalid argument=] .
6209+ 1. Let |characteristicMapping| be |simulatedService|'s <a>simulated GATT characteristic mapping</a> .
6210+ 1. Let |characteristicUuid| be |params|[`"characteristicUuid"`] .
6211+ 1. If |characteristicMapping|[|characteristicUuid|] [=map/exists=] , let |simulatedCharacteristic|
6212+ be |characteristicMapping|[|characteristicUuid|] .
6213+ 1. Otherwise, return [=error=] with [=error code=] [=invalid element state=] .
6214+ 1. Let |descriptorMapping| be |simulatedCharacteristic|'s <a>simulated GATT descriptor mapping</a> .
6215+ 1. Let |descriptorUuid| be |params|[`"descriptorUuid"`] .
6216+ 1. If |descriptorMapping|[|descriptorUuid|] [=map/exists=] , let |simulatedDescriptor|
6217+ be |descriptorMapping|[|descriptorUuid|] .
6218+ 1. Otherwise, return [=error=] with [=error code=] [=invalid element state=] .
6219+ 1. Let |simulatedDeviceInstance| be the result of <a>get the <code>BluetoothDevice</code> representing</a>
6220+ |simulatedDevice| inside |navigable|'s <a>active window</a>' s <a spec=HTML>associated <code>Navigator</code></a> 's
6221+ [=associated Bluetooth=] .
6222+ 1. Let |promise| be |simulatedDeviceInstance|.{{[[context]]}} .{{Bluetooth/[[attributeInstanceMap]]}} [|simulatedDescriptor|] .
6223+ 1. <a>Upon fulfillment</a> of |promise| with |descriptor|, run the following steps:
6224+ 1. If |params|[`"type"`] is `read`, run the following steps:
6225+ 1. If |descriptor|.{{[[automatedDescriptorReadResponse]]}} is `expected`,
6226+ set |descriptor|.{{[[automatedDescriptorReadResponse]]}} to |params|[`"code"`] and
6227+ |descriptor|.{{[[automatedDescriptorReadResponseData]]}} to [=a copy of the bytes held=]
6228+ by |params|[`"data"`] .
6229+ 1. Otherwise, return [=error=] with [=error code=] [=invalid element state=] .
6230+ 1. If |params|[`"type"`] is `write`, run the following steps:
6231+ 1. If |characteristic|.{{[[automatedDescriptorWriteResponse]]}} is `expected`,
6232+ set |characteristic|.{{[[automatedDescriptorWriteResponse]]}} to |params|[`"code"`] .
6233+ 1. Otherwise, return [=error=] with [=error code=] [=invalid element state=] .
6234+ 1. Otherwise, return [=error=] with [=error code=] [=invalid argument=] .
60916235
60926236</div>
60936237
@@ -6212,7 +6356,11 @@ To <dfn>trigger a simulated characteristic event </dfn> given a [=navigable=] |n
62126356 1. Set |params|[`"serviceUuid"`] to |service|'s <a>UUID</a> .
62136357 1. Set |params|[`"characteristicUuid"`] to |characteristic|'s <a>UUID</a> .
62146358 1. Set |params|[`"type"`] to |type|.
6215- 1. If |type| is `write`, set |params|[`"data"`] to a [=new=] {{Uint8Array}} wrapping a [=new=] {{ArrayBuffer}} containing |bytes|.
6359+ 1. If |type| is `write`, run the following steps:
6360+ 1. Let |data| be an empty list.
6361+ 1. For each |byte| in |bytes|:
6362+ 1. Append |byte|'s [=byte/value=] to |data|.
6363+ 1. Set |params|[`"data"`] to |data|.
621663641. Let |body| be a [=map=] matching the <code> bluetooth.CharacteristicEventGenerated</code> production, with the
62176365 <code> params</code> field set to |params|.
621863661. Let |relatedNavigables| be a [=/set=] containing |navigable|.
@@ -6243,7 +6391,31 @@ bluetooth.DescriptorEventGeneratedParameters = {
62436391
62446392<div algorithm="remote end event trigger for bluetooth.descriptorEventGenerated">
62456393
6246- Issue: TODO: Finish the algorithm of bluetooth.descriptorEventGenerated.
6394+ To <dfn>trigger a simulated descriptor event </dfn> given a [=navigable=] |navigable|, a {{BluetoothDevice}} |device|, a
6395+ <a>simulated GATT descriptor</a> |descriptor|, <a>string</a> |type|, and an optional <a>byte sequence</a> |bytes|:
6396+
6397+ 1. Let |navigableId| be |navigable|'s [=navigable id=] .
6398+ 1. Let |params| be a [=map=] matching the <code> bluetooth.DescriptorEventGeneratedParameters</code> production and run
6399+ the following steps:
6400+ 1. Set |params|[`"context"`] to |navigableId|.
6401+ 1. Set |params|[`"address"`] to |device|.{{[[representedDevice]]}} 's address.
6402+ 1. Let |characteristic| be the <a>simulated GATT characteristic</a> containing |descriptor|.
6403+ 1. Let |service| be the <a>simulated GATT service</a> containing |characteristic|.
6404+ 1. Set |params|[`"serviceUuid"`] to |service|'s <a>UUID</a> .
6405+ 1. Set |params|[`"characteristicUuid"`] to |characteristic|'s <a>UUID</a> .
6406+ 1. Set |params|[`"descriptorUuid"`] to |descriptor|'s <a>UUID</a> .
6407+ 1. Set |params|[`"type"`] to |type|.
6408+ 1. If |type| is `write`, run the following steps:
6409+ 1. Let |data| be an empty list.
6410+ 1. For each |byte| in |bytes|:
6411+ 1. Append |byte|'s [=byte/value=] to |data|.
6412+ 1. Set |params|[`"data"`] to |data|.
6413+ 1. Let |body| be a [=map=] matching the <code> bluetooth.DescriptorEventGenerated</code> production, with the
6414+ <code> params</code> field set to |params|.
6415+ 1. Let |relatedNavigables| be a [=/set=] containing |navigable|.
6416+ 1. For each |session| in the [=set of sessions for which an event is enabled=] given
6417+ "<code> bluetooth.descriptorEventGenerated</code> " and |relatedNavigables|:
6418+ 1. [=Emit an event=] with |session| and |body|.
62476419
62486420</div>
62496421
0 commit comments