diff --git a/index.bs b/index.bs index 3649684..16d8f7a 100644 --- a/index.bs +++ b/index.bs @@ -3476,6 +3476,7 @@ peripheral's service. readonly attribute UUID uuid; readonly attribute BluetoothCharacteristicProperties properties; readonly attribute DataView? value; + readonly attribute unsigned short maxWriteWithoutResponseSize; Promise getDescriptor(BluetoothDescriptorUUID descriptor); Promise> getDescriptors(optional BluetoothDescriptorUUID descriptor); @@ -3503,6 +3504,24 @@ Heart Rate Measurement characteristic. value is the currently cached characteristic value. This value gets updated when the value of the characteristic is read or updated via a notification or indication. + +maxWriteWithoutResponseSize is the largest [=byte sequence=], in +octets, that {{BluetoothRemoteGATTCharacteristic/writeValueWithoutResponse()}} +can send to the peer in a single ATT PDU without it being fragmented or +rejected. It is derived from the ATT_MTU negotiated for the connection that +carries this characteristic. + +Note: This value can change while the device is connected, for example because +an [=Exchange MTU=] procedure completes after service discovery. On some +platforms an updated value can arrive late, after services are resolved. +Whenever the UA observes that the ATT_MTU has changed it updates this value and +[=fires an event=] named {{maxwritewithoutresponsesizechanged}}, so the two stay +in sync: the value never changes without the event firing. Some platforms do +not surface ATT_MTU changes to the UA at all; on those platforms the value +stays constant after it is first established and the event never fires. +Applications that batch large transfers can listen for +{{maxwritewithoutresponsesizechanged}} to react to an increase instead of +re-reading the attribute on every write. Instances of {{BluetoothRemoteGATTCharacteristic}} are created with the @@ -3522,6 +3541,20 @@ Instances of {{BluetoothRemoteGATTCharacteristic}} are created with the Characteristic has been removed or otherwise invalidated. + + \[[maxWriteWithoutResponseSize]] + 20 + + The value, in octets, exposed by + {{BluetoothRemoteGATTCharacteristic/maxWriteWithoutResponseSize}}. It is + established when the {{[[representedCharacteristic]]}} is discovered and + updated only when the UA learns of an ATT_MTU change for the + [=ATT Bearer=] that carries it, at which point the + {{maxwritewithoutresponsesizechanged}} event is fired. The initial value + of 20 corresponds to the default ATT_MTU of 23 octets minus + the 3-octet ATT Write Command header. + + \[[automatedCharacteristicReadResponse]] "not-expected" @@ -3624,6 +3657,22 @@ getDescriptors(descriptor) method retrieves a list of > child type="GATT Descriptor") +
+The {{BluetoothRemoteGATTCharacteristic/maxWriteWithoutResponseSize}} getter +steps are: + +1. Return [=this=].{{[[maxWriteWithoutResponseSize]]}}. + +
+Note: The stored value is the ATT_MTU negotiated for the [=ATT Bearer=] that +carries the characteristic, minus 3 octets. The 3 octets account for the ATT +Write Command header (1 octet opcode and 2 octet attribute handle), leaving the +space available for the attribute value in a single PDU. The value is +established when the characteristic is discovered and only changes when the UA +observes an ATT_MTU change; see [[#mtu-change-events]]. +
+
+
The readValue() method, when invoked, MUST run the following steps: @@ -4362,6 +4411,21 @@ interface participate in a tree. an active GATT connection is lost. +
+ + maxwritewithoutresponsesizechanged + +
+
+ Fired on a {{BluetoothRemoteGATTCharacteristic}} when its + {{BluetoothRemoteGATTCharacteristic/maxWriteWithoutResponseSize}} + changes, for example after an + [=Exchange MTU=] procedure renegotiates the ATT_MTU for the connection. + The UA fires this event whenever it updates the value, so platforms that + never surface ATT_MTU changes (and therefore never change the value) also + never fire this event. +
+
serviceadded
@@ -4483,6 +4547,51 @@ it must perform the following steps:
+### Responding to MTU Changes ### {#mtu-change-events} + +
+When the ATT_MTU negotiated for an [=ATT Bearer=] changes, for example because +the UA receives the result of an [=Exchange MTU=] procedure, the UA must +perform the following steps for each Characteristic +characteristic carried by that [=ATT Bearer=]: + +Note: The UA only runs these steps when it observes an ATT_MTU change. Updating +the stored value and firing the {{maxwritewithoutresponsesizechanged}} event +happen together, so the value never changes without the event firing. Platforms +that do not surface ATT_MTU changes to the UA never run these steps, so on those +platforms the value stays constant after it is first established and the event +never fires. + +1. Let newSize be the ATT_MTU now negotiated for that + [=ATT Bearer=] − 3. This is the smaller of the local Host's transmit + ATT_MTU and the peer's receive ATT_MTU, less the 3-octet ATT Write Command + header. +1. For each |bluetoothGlobal| whose [=Bluetooth tree=] contains a + {{BluetoothRemoteGATTCharacteristic}} representing characteristic, + [=queue a global task=] on the [=Bluetooth task source=] given + |bluetoothGlobal|'s [=relevant global object=] to do the following + sub-steps: + 1. Let characteristicObject be the + {{BluetoothRemoteGATTCharacteristic}} in the Bluetooth tree + rooted at bluetoothGlobal that represents + characteristic. + 1. If characteristicObject + .service.device.gatt.{{BluetoothRemoteGATTServer/connected}} + is `false`, abort these sub-steps. + 1. If characteristicObject.{{[[maxWriteWithoutResponseSize]]}} + equals newSize, abort these sub-steps. + 1. Set characteristicObject.{{[[maxWriteWithoutResponseSize]]}} + to newSize. + 1. Fire an event named {{maxwritewithoutresponsesizechanged}} with + its bubbles attribute initialized to true at + characteristicObject. + + Note: The new value is not carried on the event. Listeners read + characteristicObject.{{BluetoothRemoteGATTCharacteristic/maxWriteWithoutResponseSize}} + to obtain the current value. + +
+
### Responding to Service Changes ### {#service-change-events} @@ -4673,6 +4782,7 @@ Changed characteristic, it MUST perform the following steps. [SecureContext] interface mixin CharacteristicEventHandlers { attribute EventHandler oncharacteristicvaluechanged; + attribute EventHandler onmaxwritewithoutresponsesizechanged; }; @@ -4680,6 +4790,10 @@ Changed characteristic, it MUST perform the following steps. oncharacteristicvaluechanged is an Event handler IDL attribute for the {{characteristicvaluechanged}} event type. + +onmaxwritewithoutresponsesizechanged is an Event handler IDL +attribute for the {{maxwritewithoutresponsesizechanged}} event type. + [SecureContext] interface mixin BluetoothDeviceEventHandlers {