pebble/src/fw/applib/bluetooth/ble_client.h
Josh Soref 56b1584352 spelling: success
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2025-01-29 00:03:28 -05:00

345 lines
18 KiB
C

/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <bluetooth/bluetooth_types.h>
typedef enum {
BLEClientServicesAdded,
BLEClientServicesRemoved,
BLEClientServicesInvalidateAll
} BLEClientServiceChangeUpdate;
//! Callback that is called when the services on a remote device that are
//! available to the application have changed. It gets called when:
//! + the initial discovery of services completes
//! + a new service has been discovered on the device after initial discovery
//! + a service has been removed
//! + the remote device has disconnected
//!
//! @note For convenience, the services are owned by the system and references
//! to services, characteristics and descriptors are guaranteed to remain valid
//! *until the service exposing the characteristic or descriptor is removed or
//! all services are invalidated* or until application is terminated.
//! @note References to services, characteristics and descriptors for the
//! specified device, that have been obtained in a previous callback to the
//! handler, are no longer valid. The application is responsible for cleaning up
//! these references.
//!
//! @param device The device associated with the service discovery process
//! @param update_type Defines what type of service update is being received
//! @param services Array of pointers to the discovered services. The array will
//! only contain Service UUIDs that matches the filter that was passed into the
//! ble_client_discover_services_and_characteristics() call.
//! @param num_services The number of discovered services matching the criteria.
//! @param status BTErrnoOK if the service discovery was completed successfully.
//! If the device was disconnected, BTErrnoConnectionTimeout,
//! BTErrnoRemotelyTerminated, BTErrnoLocallyTerminatedBySystem or
//! BTErrnoLocallyTerminatedByApp will specify the reason of the disconnection.
//! The number of services will be zero upon a disconnection.
typedef void (*BLEClientServiceChangeHandler)(BTDevice device,
BLEClientServiceChangeUpdate update_type,
const BLEService services[],
uint8_t num_services,
BTErrno status);
//! Registers the callback that handles service changes. After the call to
//! this function returns, the application should be ready to handle calls to
//! the handler.
//! @param handler Pointer to the function that will handle the service changes
//! @return BTErrnoOK if the handler was registered successfully,
//! or TODO....
BTErrno ble_client_set_service_change_handler(BLEClientServiceChangeHandler handler);
//! Registers the filter list of Service UUIDs.
//! @param service_uuids An array of the Service UUIDs that the application is
//! interested in and the system should filter by. Passing NULL will discover
//! all services on the device.
//! @param num_uuids The number of Uuid`s in the service_uuids array. Ignored
//! when NULL is passed for the service_uuids argument.
//! @return BTErrnoOK if the filter was set up successfully,
//! or TODO....
BTErrno ble_client_set_service_filter(const Uuid service_uuids[],
uint8_t num_uuids);
//! Starts a discovery of services and characteristics on a remote device.
//! The discovered services will be delivered to the application through the
//! BLEClientServiceChangeHandler. The results will be filtered with the list
//! of Service UUIDs as configured with ble_client_set_service_filter().
//! @param device The device for which to perform service discovery.
//! @return BTErrnoOK if the service discovery started successfully,
//! BTErrnoInvalidParameter if the device was not connected,
//! BTErrnoInvalidState if service discovery was already on-going, or
//! an internal error otherwise (>= BTErrnoInternalErrorBegin).
BTErrno ble_client_discover_services_and_characteristics(BTDevice device);
//! Different subscription types that can be used with ble_client_subscribe()
typedef enum {
//! No subscription.
BLESubscriptionNone = 0,
//! Notification subscription.
BLESubscriptionNotifications = (1 << 0),
//! Indication subscription.
BLESubscriptionIndications = (1 << 1),
//! Any subscription. Use this value with ble_client_subscribe(), in case
//! the application does not care about the type of subscription. If both
//! types are supported by the server, the notification subscription type
//! will be used.
BLESubscriptionAny = BLESubscriptionNotifications | BLESubscriptionIndications,
} BLESubscription;
//! Callback to receive the characteristic value, resulting from either
//! ble_client_read() and/or ble_client_subscribe().
//! @param characteristic The characteristic of the received value
//! @param value Byte-array containing the value
//! @param value_length The number of bytes the byte-array contains
//! @param value_offset The offset in bytes from the start of the characteristic
//! value that has been read.
//! @param error The error or status as returned by the remote server. If the
//! read was successful, this remote server is supposed to send
//! BLEGATTErrorSuccess.
typedef void (*BLEClientReadHandler)(BLECharacteristic characteristic,
const uint8_t *value,
size_t value_length,
uint16_t value_offset,
BLEGATTError error);
//! Callback to handle the response to a written characteristic, resulting from
//! ble_client_write().
//! @param characteristic The characteristic that was written to.
//! @param error The error or status as returned by the remote server. If the
//! write was successful, this remote server is supposed to send
//! BLEGATTErrorSuccess.
typedef void (*BLEClientWriteHandler)(BLECharacteristic characteristic,
BLEGATTError error);
//! Callback to handle the confirmation of a subscription or unsubscription to
//! characteristic value changes (notifications or indications).
//! @param characteristic The characteristic for which the client is now
//! (un)subscribed.
//! @param subscription_type The type of subscription. If the client is now
//! unsubscribed, the type will be BLESubscriptionNone.
//! @param The error or status as returned by the remote server. If the
//! (un)subscription was successful, this remote server is supposed to send
//! BLEGATTErrorSuccess.
typedef void (*BLEClientSubscribeHandler)(BLECharacteristic characteristic,
BLESubscription subscription_type,
BLEGATTError error);
//! Callback to handle the event that the buffer for outbound data is empty.
typedef void (*BLEClientBufferEmptyHandler)(void);
//! Registers the handler for characteristic value read operations.
//! @param read_handler Pointer to the function that will handle callbacks
//! with read characteristic values as result of calls to ble_client_read().
//! @return BTErrnoOK if the handlers were successfully registered, or ... TODO
BTErrno ble_client_set_read_handler(BLEClientReadHandler read_handler);
//! Registers the handler for characteristic value write (with response)
//! operations.
//! @param write_handler Pointer to the function that will handle callbacks
//! for written characteristic values as result of calls to ble_client_write().
//! @return BTErrnoOK if the handlers were successfully registered, or ... TODO
BTErrno ble_client_set_write_response_handler(BLEClientWriteHandler write_handler);
//! Registers the handler for characteristic value subscribe operations.
//! @param subscribe_handler Pointer to the function that will handle callbacks
//! for (un)subscription confirmations as result of calls to
//! ble_client_subscribe().
//! @return BTErrnoOK if the handlers were successfully registered, or ... TODO
BTErrno ble_client_set_subscribe_handler(BLEClientSubscribeHandler subscribe_handler);
//! Registers the handler to get called back when the buffer for outbound
//! data is empty again.
//! @param empty_handler Pointer to the function that will handle callbacks
//! for "buffer empty" events.
//! @return BTErrnoOK if the handlers were successfully registered, or ... TODO
BTErrno ble_client_set_buffer_empty_handler(BLEClientBufferEmptyHandler empty_handler);
//! Gets the maximum characteristic value size that can be written. This size
//! can vary depending on the connected device.
//! @param device The device for which to get the maximum characteristic value
//! size.
//! @return The maximum characteristic value size that can be written.
uint16_t ble_client_get_maximum_value_length(BTDevice device);
//! Read the value of a characteristic.
//! A call to this function will result in a callback to the registered
//! BLEClientReadHandler handler. @see ble_client_set_read_handler.
//! @param characteristic The characteristic for which to read the value
//! @return BTErrnoOK if the operation was successfully started, or ... TODO
BTErrno ble_client_read(BLECharacteristic characteristic);
//! Write the value of a characteristic.
//! A call to this function will result in a callback to the registered
//! BLEClientWriteHandler handler. @see ble_client_set_write_response_handler.
//! @param characteristic The characteristic for which to write the value
//! @param value Buffer with the value to write
//! @param value_length Number of bytes to write
//! @note Values must not be longer than ble_client_get_maximum_value_length().
//! @return BTErrnoOK if the operation was successfully started, or ... TODO
BTErrno ble_client_write(BLECharacteristic characteristic,
const uint8_t *value,
size_t value_length);
//! Write the value of a characteristic without response.
//! @param characteristic The characteristic for which to write the value
//! @param value Buffer with the value to write
//! @param value_length Number of bytes to write
//! @note Values must not be longer than ble_client_get_maximum_value_length().
//! @return BTErrnoOK if the operation was successfully started, or ... TODO
//! If the buffer for outbound data was full, BTErrnoNotEnoughResources will
//! be returned. When the buffer is emptied, the handler that is registered
//! using ble_client_set_buffer_empty_handler() will be called.
BTErrno ble_client_write_without_response(BLECharacteristic characteristic,
const uint8_t *value,
size_t value_length);
//! Subscribe to be notified or indicated of value changes of a characteristic.
//!
//! The value updates are delivered to the application through the
//! BLEClientReadHandler, which should be registered before calling this
//! function using ble_client_set_read_handler().
//!
//! There are two types of subscriptions: notifications and indications.
//! For notifications there is no flow-control. This means that notifications
//! can get dropped if the rate at which they are sent is too high. Conversely,
//! each indication needs an acknowledgement from the receiver before the next
//! one can get sent and is thus more reliable. The system performs
//! acknowledgements to indications automatically. Applications do not need to
//! worry about this, nor can they affect this.
//! @param characteristic The characteristic to subscribe to.
//! @param subscription_type The type of subscription to use.
//! If BLESubscriptionAny is used as subscription_type and both types are
//! supported by the server, the notification subscription type will be used.
//! @note This call does not block and returns quickly. A callback to
//! the BLEClientSubscribeHandler will happen at a later point in time, to
//! report the success or failure of the subscription. This handler should be
//! registered before calling this function using
//! ble_client_set_subscribe_handler().
//! @note Under the hood, this API writes to the Client Characteristic
//! Configuration Descriptor's Notifications or Indications enabled/disabled
//! bit.
//! @return BTErrnoOK if the subscription request was sent successfully, or
//! TODO...
BTErrno ble_client_subscribe(BLECharacteristic characteristic,
BLESubscription subscription_type);
//! Callback to receive the descriptor value, resulting from a call to
//! ble_client_read_descriptor().
//! @param descriptor The descriptor of the received value
//! @param value Byte-array containing the value
//! @param value_length The number of bytes the byte-array contains
//! @param value_offset The offset in bytes from the start of the descriptor
//! value that has been read.
//! @param error The error or status as returned by the remote server. If the
//! read was successful, this remote server is supposed to send
//! BLEGATTErrorSuccess.
typedef void (*BLEClientReadDescriptorHandler)(BLEDescriptor descriptor,
const uint8_t *value,
size_t value_length,
uint16_t value_offset,
BLEGATTError error);
//! Callback to handle the response to a written descriptor, resulting from
//! ble_client_write_descriptor().
//! @param descriptor The descriptor that was written to.
//! @param error The error or status as returned by the remote server. If the
//! write was successful, this remote server is supposed to send
//! BLEGATTErrorSuccess.
typedef void (*BLEClientWriteDescriptorHandler)(BLEDescriptor descriptor,
BLEGATTError error);
//! Registers the handlers for descriptor value write operations.
//! @param write_handler Pointer to the function that will handle callbacks
//! for written descriptor values as result of calls to
//! ble_client_write_descriptor().
//! @return BTErrnoOK if the handlers were successfully registered, or ... TODO
BTErrno ble_client_set_descriptor_write_handler(BLEClientWriteDescriptorHandler write_handler);
//! Registers the handlers for descriptor value read operations.
//! @param read_handler Pointer to the function that will handle callbacks
//! with read descriptor values as result of calls to
//! ble_client_read_descriptor().
//! @return BTErrnoOK if the handlers were successfully registered, or ... TODO
BTErrno ble_client_set_descriptor_read_handler(BLEClientReadDescriptorHandler read_handler);
//! Write the value of a descriptor.
//! A call to this function will result in a callback to the registered
//! BLEClientWriteDescriptorHandler handler.
//! @see ble_client_set_descriptor_write_handler.
//! @param descriptor The descriptor for which to write the value
//! @param value Buffer with the value to write
//! @param value_length Number of bytes to write
//! @note Values must not be longer than ble_client_get_maximum_value_length().
//! @return BTErrnoOK if the operation was successfully started, or ... TODO
BTErrno ble_client_write_descriptor(BLEDescriptor descriptor,
const uint8_t *value,
size_t value_length);
//! Read the value of a descriptor.
//! A call to this function will result in a callback to the registered
//! BLEClientReadDescriptorHandler handler.
//! @see ble_client_set_descriptor_read_handler.
//! @param descriptor The descriptor for which to read the value
//! @return BTErrnoOK if the operation was successfully started, or ... TODO
BTErrno ble_client_read_descriptor(BLEDescriptor descriptor);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// (FUTURE / LATER / NOT SCOPED)
// Just to see how symmetric the Server APIs would be:
//! Opaque ATT request context
typedef void * BLERequest;
typedef void (*BLEServerWriteHandler)(BLERequest request,
BLECharacteristic characteristic,
BTDevice remote_device,
const uint8_t *value,
size_t value_length,
uint16_t value_offset);
typedef void (*BLEServerReadHandler)(BLECharacteristic characteristic,
BTDevice remote_device,
uint16_t value_offset);
typedef void (*BLEServerSubscribeHandler)(BLECharacteristic characteristic,
BTDevice remote_device,
BLESubscription subscription_type);
BTErrno ble_server_set_handlers(BLEServerReadHandler read_handler,
BLEServerWriteHandler write_handler,
BLEServerSubscribeHandler subscription_handler);
BTErrno ble_server_start_service(BLEService service);
BTErrno ble_server_stop_service(BLEService service);
BTErrno ble_server_respond_to_write(BLERequest request, BLEGATTError error);
BTErrno ble_server_respond_to_read(BLERequest request, BLEGATTError error,
const uint8_t *value, size_t value_length,
uint16_t value_offset);
BTErrno ble_server_send_update(BLECharacteristic characteristic,
const uint8_t *value, size_t value_length);
BTErrno ble_server_send_update_selectively(BLECharacteristic characteristic,
const uint8_t *value, size_t value_length,
const BTDevice *devices, uint8_t num_devices);