| // Copyright 2021 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| library fuchsia.bluetooth.gatt2; |
| |
| using fuchsia.bluetooth as bt; |
| using zx; |
| |
| /// The amount of credits defined to be available for sending indications/notifications when a |
| /// LocalService is first published. |
| const INITIAL_VALUE_CHANGED_CREDITS uint32 = 10; |
| |
| /// The parameters used to signal a characteristic value change from a LocalService to a peer. |
| type ValueChangedParameters = table { |
| /// The handle of the characteristic value being signalled. |
| /// Mandatory. |
| 1: handle Handle; |
| /// The updated value of the characteristic. |
| /// Note for clients using indications/notifications for high-throughput (not recommended): |
| /// While statically constrained to `MAX_VALUE_LENGTH`, the real limit depends on the specific |
| /// peer's configuration as notified by `LocalService.PeerUpdate`. Any bytes exceeding that |
| /// limit are truncated internally by the stack. |
| /// Mandatory. |
| 2: value bytes:MAX_VALUE_LENGTH; |
| /// Only signal a subset of peers. |
| /// If not present or empty, all peers that can be updated are signaled. |
| /// If included, only the set of peers in this list will be signaled. |
| /// Peers are only signaled if they have configured updates or notifications per `LocalService.` |
| /// `CharacteristicConfiguration`; other peers in `peer_ids` will be ignored. |
| 3: peer_ids vector<bt.PeerId>:MAX; |
| }; |
| |
| /// Interface for serving a local GATT service. Closing the server_end of this protocol causes the |
| /// GATT service to be removed from the local GATT database. Similarly, closure of the client_end |
| /// of this protocol means the Bluetooth stack has removed this service from its GATT database. |
| protocol LocalService { |
| /// This notifies the current configuration of a particular characteristic/descriptor for a |
| /// particular peer. It will be called when the peer GATT client changes the configuration. |
| /// |
| /// The Bluetooth stack maintains the state of each peer's configuration across reconnections. |
| /// As such, this method will also be called when a peer connects for each characteristic with |
| /// the initial, persisted state of the newly-connected peer's configuration. However, clients |
| /// should not rely on this state being persisted indefinitely by the Bluetooth stack. |
| /// |
| /// + request `peer_id` The PeerId of the GATT client associated with this particular CCC. |
| /// + request `handle` The handle of the characteristic associated with the `notify` and |
| /// `indicate` parameters. |
| /// + request `notify` True if the client has enabled notifications, false otherwise. |
| /// + request `indicate` True if the client has enabled indications, false otherwise. |
| /// - response empty Returns nothing to acknowledge the characteristic configuration. |
| CharacteristicConfiguration(struct { |
| peer_id bt.PeerId; |
| handle Handle; |
| notify bool; |
| indicate bool; |
| }) -> (); |
| |
| /// Called when a peer requests to read the value of a characteristic or descriptor. It is |
| /// guaranteed that the peer satisfies the permssions associated with this attribute. |
| /// |
| /// + request `peer_id` The PeerId of the GATT client making the read request. |
| /// + request `handle` The handle of the requested descriptor/characteristic. |
| /// + request `offset` The offset at which to start reading the requested value. |
| /// - response `value` The value of the characteristic. |
| /// * error See `gatt2.Error` documentation for possible errors. |
| ReadValue(struct { |
| peer_id bt.PeerId; |
| handle Handle; |
| offset int32; |
| }) -> (struct { |
| value bytes:MAX_VALUE_LENGTH; |
| }) error Error; |
| |
| /// Called when a peer issues a request to write the value of a characteristic or descriptor. It |
| /// is guaranteed that the peer satisfies the permissions associated with this attribute. |
| /// |
| /// + request `peer_id` The PeerId of the GATT client making the write request. Always present. |
| /// + request `handle` The handle of the requested descriptor/characteristic. Always present. |
| /// + request `offset` The offset at which to start writing the value. If the offset is 0, any |
| /// existing value should be overwritten by the new value. Otherwise, the existing value from |
| /// offset:(offset + len(value)) should be changed to `value`. Always present. |
| /// + request `value` The new value for the descriptor/characteristic. Always present, but may |
| /// be the empty string. |
| /// - response The implementation must send an empty response once the value has been updated |
| /// as confirmation. |
| /// * error See `gatt2.Error` documentation for possible errors. |
| WriteValue(table { |
| 1: peer_id bt.PeerId; |
| 2: handle Handle; |
| 3: offset uint32; |
| 4: value bytes:MAX_VALUE_LENGTH; |
| }) -> (struct {}) error Error; |
| |
| /// Called to provide GATT information specific to a peer. PeerUpdate will not be called unless |
| /// the prior invocation received a response. As such, the implementation can simply ignore the |
| /// first invocation if they are not interested in any PeerUpdate fields. |
| /// |
| /// A PeerUpdate will be made before propagating any other interaction from the peer to the |
| /// LocalService (Write/ReadValue, CharacteristicConfiguration) on a best-effort basis, as long |
| /// as all preceding PeerUpdates were acknowledged. |
| /// |
| /// + request `peer_id` The PeerId the update pertains to. Always present. |
| /// + request `mtu` The maximum number of bytes that fit in a notification/indication to this |
| /// peer. Any bytes past this limit are silently truncated. Most clients need not concern |
| /// themselves with this unless they are using notifications/indications for high throughput. |
| /// Optional. |
| /// - response An empty response to acknowledge that the update was received. |
| PeerUpdate(table { |
| 1: peer_id bt.PeerId; |
| 2: mtu uint16; |
| }) -> (); |
| |
| /// After this event, new peers will no longer be able to discover the service, although peers |
| /// which have already discovered this service may still access it. This should be sent once per |
| /// service lifetime; sending more than once closes the protocol and disconnects GATT clients. |
| @transitional("Not currently supported. Comment on fxbug.dev/98598 to request support") |
| -> OnSuppressDiscovery(); |
| |
| /// This event is used to send a notification to a peer. Notifications should be used instead of |
| /// indications when the service does *not* require peer confirmation of the update. |
| /// |
| /// Notifications should not be sent to peers which have not enabled notifications on a |
| /// particular characteristic - if they are sent, they will not be propagated. The Bluetooth |
| /// stack will track this configuration for the lifetime of the service. |
| /// |
| /// LocalServices must keep track of available credit provided by the `ValueChangedCredit` |
| /// method and send at most that many `OnNotifyValue` and `OnIndicateValue` events. If more |
| /// events are sent than available credits, the protocol will be closed. |
| -> OnNotifyValue(ValueChangedParameters); |
| |
| /// This event is used to send an indication to a peer. Indications should be used instead of |
| /// notifications when the service *does* require peer confirmation of the update. |
| /// |
| /// Indications should not be sent to peers which have not enabled indications on a particular |
| /// characteristic - if they are sent, they will not be propagated. The Bluetooth stack will |
| /// track this configuration for the lifetime of the service. |
| /// |
| /// LocalServices must keep track of available credit provided by the `ValueChangedCredit` |
| /// method and send at most that many `OnNotifyValue` and `OnIndicateValue` events. If more |
| /// events are sent than available credits, the protocol will be closed. |
| /// |
| /// + request `update` The parameters associated with the changed characteristic. |
| /// + request `confirmation` When all peers that will be updated have confirmed the indication, |
| /// `confirmation` is signalled with ZX_EVENTPAIR_SIGNALLED. `confirmation` will be closed if |
| /// indicating any peer fails, such as if the peer hasn't configured indications, is not |
| /// connected, or does not confirm within the ATT transaction timeout of 30 seconds (Bluetooth |
| /// 5.3 Vol. 3 Part F 3.3.3). To track indication confirmation on a per-peer basis, the |
| /// implementation can send this event with a single ID in `update.peer_ids`. |
| // `confirmation` is an EventPair instead of an Event because the language bindings for Events |
| // treat them as resources/move-only, but the LocalService will need to retain a handle to the |
| // `confirmation` kernel object in order to wait on the signal from the other side. |
| -> OnIndicateValue(resource struct { |
| update ValueChangedParameters; |
| confirmation zx.handle:EVENTPAIR; |
| }); |
| |
| /// Add credit for sending indications/notifications. Implementors are defined to start out with |
| /// INITIAL_VALUE_CHANGED_CREDITS credits before this method is called. Implementors must keep |
| /// track of the available credit they have. The implementor can send exactly one OnNotifyValue |
| /// or OnIndicateValue event for each credit. Note that `ValueChangedCredit` will only be called |
| /// if at least one indication/notification has been sent since the prior call. |
| ValueChangedCredit(struct { |
| additional_credit uint8; |
| }); |
| }; |
| |
| @discoverable |
| protocol Server { |
| /// Publishes the given `service` so that it is available to all remote peers. Upon publication, |
| /// the service is defined to have INITIAL_VALUE_CHANGED_CREDITS credits available for sending |
| /// indications/notifications. |
| /// |
| /// The caller must assign distinct handles to the characteristics and descriptors listed in |
| /// `info`. These identifiers will be used in requests sent to `service`. |
| /// |
| /// + request `info` Defines the structure of the GATT service. Includes characteristics and |
| /// descriptors that will be made available to peers, as well as the service handle, which is |
| /// required to be unique across all services published to this Server. |
| /// + request `service` Provides the implementation of the service per the documented behavior |
| /// of a `LocalService`. |
| /// - response An empty response indicates the service was successfully published. |
| /// * error See `gatt2.PublishServiceError` for possible failure modes. |
| @transitional("Implementation and migration progress tracked in http://fxbug.dev/36375") |
| PublishService(resource struct { |
| info ServiceInfo; |
| service client_end:LocalService; |
| }) -> (struct {}) error PublishServiceError; |
| }; |