Marco Zecchini
/
Example_RTOS
Rtos API example
Diff: mbed-os/features/FEATURE_BLE/ble/DiscoveredCharacteristic.h
- Revision:
- 0:9fca2b23d0ba
diff -r 000000000000 -r 9fca2b23d0ba mbed-os/features/FEATURE_BLE/ble/DiscoveredCharacteristic.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os/features/FEATURE_BLE/ble/DiscoveredCharacteristic.h Sat Feb 23 12:13:36 2019 +0000 @@ -0,0 +1,637 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ + +#ifndef MBED_DISCOVERED_CHARACTERISTIC_H__ +#define MBED_DISCOVERED_CHARACTERISTIC_H__ + +#include "UUID.h" +#include "Gap.h" +#include "GattAttribute.h" +#include "GattClient.h" +#include "CharacteristicDescriptorDiscovery.h" +#include "DiscoveredCharacteristicDescriptor.h" + +/** + * @addtogroup ble + * @{ + * @addtogroup gatt + * @{ + * @addtogroup client + * @{ + */ + +/** + * Representation of a characteristic discovered. + * + * The GattClient discovery procedure initiated with + * GattClient::launchServiceDiscovery() generates instances of this class. + * + * It exposes the main attributes of the discovered characteristic: + * - The UUID of the characteristic, it can be retrieved by a call to the + * function getUUID(). This UUID is the type of the characteristic. + * - Attribute Handles of the characteristic are present as the triplet + * declaration handle, value handle and last handle. The value handle is + * used to read or write the content of the characteristic. + * - The properties contain the set of operations the characteristic can + * handle, for instance being read or written. + * + * It important to note that the value of the characteristic - if it is + * accessible - is not fetched at discovery time. + * + * The main operations the class offers are reading, writing and discovering + * the descriptors of the characteristic discovered. + * + * Reading a discovered characteristic can be accomplished in two different + * fashions: + * + * If the user has a callback registered for the data read operation in the + * GattClient, then a call to the read(uint16_t) function will initiate a read of + * the characteristic. Results of the operation will be pass on the callback + * registered by GattClient::onDataRead(), which processes all the responses to + * read requests. The read request for a given characteristic can be identified + * by the connection handle and the attribute handle, which are present in + * GattReadCallbackParams. + * + * Another overload (read(uint16_t, const GattClient::ReadCallback_t&)) of the + * read function accepts a completion callback as a last parameter. That + * completion callback will be invoked automatically once the response to the + * read request for that given characteristic has been received. However, + * convenience came at the expense of dynamic memory usage for the time of the + * transaction. + * + * Similarly, two versions of the write() API are exposed. One where the user + * has to register a callback handling write response through the function + * GattClient::onDataWritten() and another one that accepts a completion + * callback in input. + * + * It is also possible to send a write command, which is not acknowledged by the + * peer server by using the function writeWoResponse(). + * + * Finally, descriptors of the characteristic can be discovered by invoking the + * function discoverDescriptors, which is shorthand for calling + * GattClient::discoverCharacteristicDescriptors. That discovery is necessary to + * enable or disable characteristic notification or indication that is achieved + * by writing on the Client Characteristic Configuration Descriptor (CCCD). + */ +class DiscoveredCharacteristic { +public: + /** + * Properties of a discovered characteristic. + */ + struct Properties_t { + /** + * Permits broadcasts of the characteristic value using the character + * the Server Characteristic Configuration Descriptor. + * + * @note If set, descriptors of the characteristic contain a Server + * Characteristic Configuration Descriptor. + */ + uint8_t _broadcast :1; + + /** + * If set, the value of the characteristic can be read. + */ + uint8_t _read :1; + + /** + * If set, a write command can write the characteristic value + * (write without response). + */ + uint8_t _writeWoResp :1; + + /** + * If set, clients can issue requests to write the characteristic. + */ + uint8_t _write :1; + + /** + * If set, the server can emit notifications of the Characteristic Value + * (without client acknowledgment). + * + * @note If set, descriptors of the characteristic contain a Client + * Characteristic Configuration Descriptor. + */ + uint8_t _notify :1; + + /** + * If set, the server can emit indication of the Characteristic Value + * (with client acknowledgement). + * + * @note If set, descriptors of the characteristic contain a Client + * Characteristic Configuration Descriptor. + */ + uint8_t _indicate :1; + + /** + * If set, signed write of the Characteristic Value is supported. + */ + uint8_t _authSignedWrite :1; + + public: + /** + * Return the value of the broadcast propertie. + * + * @return true if the Server Characteristic Configuration Descriptor + * of the characteristic can be configured to broadcast the + * characteristic value during broadcast procedure. + * + * @see _broadcast + */ + bool broadcast(void) const + { + return _broadcast; + } + + /** + * Return the value of the read property + * + * @return true if the characteristic value can be read and false + * otherwise. + * + * @see _read + */ + bool read(void) const + { + return _read; + } + + /** + * Return the value of the write without response property. + * + * @return true if the characteristic accepts write without response + * commands and false otherwise. + * + * @see _writeWoResp + */ + bool writeWoResp(void) const + { + return _writeWoResp; + } + + /** + * Return the value of the write property. + * + * @return true if writing the characteristic accepts write requests and + * false otherwise. + * + * @see _write + */ + bool write(void) const + { + return _write; + } + + /** + * Return the value of the notification property. + * + * @return true if the Client Characteristic Configuration Descriptor + * can be configured to notify the characteristic value to a given + * client and false otherwise. + * + * @note unlike indication, the notification procedure does not require + * acknowledgement from the client. + * + * @see _notify + */ + bool notify(void) const + { + return _notify; + } + + /** + * Return the value of the indicate property. + * + * @return true if the Client Characteristic Configuration Descriptor + * can be configured to indicate the characteristic value to a given + * client and false otherwise. + * + * @note unlike notification the indication procedure does require + * acknowledgment from the client. + * + * @see _indicate + */ + bool indicate(void) const + { + return _indicate; + } + + /** + * Return the value of the authenticated signed writes property. + * + * @return true if the characteristic accepts authenticated signed write + * and false otherwise. + */ + bool authSignedWrite(void) const + { + return _authSignedWrite; + } + + /** + * Equal to operator for DiscoveredCharacteristic::Properties_t. + * + * @param[in] lhs The left hand side of the equality expression. + * @param[in] rhs The right hand side of the equality expression. + * + * @return true if operands are equals and false otherwise. + */ + friend bool operator==(Properties_t lhs, Properties_t rhs) + { + return lhs._broadcast == rhs._broadcast && + lhs._read == rhs._read && + lhs._writeWoResp == rhs._writeWoResp && + lhs._write == rhs._write && + lhs._notify == rhs._notify && + lhs._indicate == rhs._indicate && + lhs._authSignedWrite == rhs._authSignedWrite; + } + + /** + * Not equal to operator for DiscoveredCharacteristic::Properties_t. + * + * @param lhs The left hand side of the expression. + * @param rhs The right hand side of the expression. + * + * @return true if operands are not equals, false otherwise. + */ + friend bool operator!=(Properties_t lhs, Properties_t rhs) + { + return !(lhs == rhs); + } + + private: + /* Disallow implicit conversion to integer types. */ + operator uint8_t() const; + operator unsigned() const; + }; + + /** + * Initiate a read of the characteristic value. + * + * The characteristic value is read in its entirety from the value attribute + * of the characteristic. + * + * Read responses will be passed to the callback registered in + * GattClient::onDataRead(). Read responses to read requests that this function + * call initiates will have their GattReadCallbackParams::connHandle + * field equal to the value returned by getConnectionHandle() and their + * GattReadCallbackParams::handle field equal to the value returned by + * getValueHandle(). + * + * @param[in] offset The position - in the characteristic value bytes stream + * - where the read operation begin. This parameter is optional. + * + * @return BLE_ERROR_NONE if a read has been initiated. + * @return BLE_ERROR_INVALID_STATE if some internal state about the + * connection is invalid. + * @return BLE_STACK_BUSY if some client procedure is already in progress. + * @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's + * properties. + */ + ble_error_t read(uint16_t offset = 0) const; + + /** + * Initiate a read of the characteristic value and pass the response to its + * completion callback. + * + * @param[in] offset The position - in the characteristic value bytes stream + * - where the read operation begin. + * + * @param[in] onRead Completion callback which will accept the response of + * the read request. The callback is copied; it is unnecessary to keep it + * in memory after the call. + * + * @return BLE_ERROR_NONE if a read has been initiated. + * @return BLE_ERROR_INVALID_STATE if some internal state about the + * connection is invalid. + * @return BLE_STACK_BUSY if some client procedure is already in progress. + * @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's + * properties. + * + * @note This function is similar to read(uint16_t) const; however, it uses + * dynamic memory to store the use completion callback. + */ + ble_error_t read( + uint16_t offset, + const GattClient::ReadCallback_t &onRead + ) const; + + /** + * Perform a write without response procedure. + * + * @note The server does not acknowledge write without responses. + * Therefore, they won't generate any event on the client side. + * + * @param[in] length The amount of data being written. + * @param[in] value The bytes being written. + * + * @return BLE_ERROR_NONE Successfully started the Write procedure. + * @return BLE_ERROR_INVALID_STATE if some internal state about the + * connection is invalid. + * @return BLE_STACK_BUSY if some client procedure is already in progress. + * @return BLE_ERROR_NO_MEM if there are no available buffers left to + * process the request. + * @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's + * properties. + */ + ble_error_t writeWoResponse(uint16_t length, const uint8_t *value) const; + + /** + * Initiate a discovery of the characteristic descriptors. + * + * When a descriptor is discovered, the callback onDescriptorDiscovered is + * invoked with the descriptor discovered as parameter. When the process + * ends, the callback onTermination is invoked. + * + * @param[in] onDescriptorDiscovered Callback is invoked when a descriptor is + * discovered. + * + * @param[in] onTermination Callback is invoked when the discovery process ends. + * + * @return BLE_ERROR_NONE if descriptor discovery is launched successfully; + * else an appropriate error. + * + * @note This function is shorthand for + * GattClient::discoverCharacteristicDescriptors; therefore, + * GattClient::isCharacteristicDescriptorDiscoveryActive can be used to + * determine the descriptor discovery and + * GattClient::terminateCharacteristicDescriptorDiscovery can be used to + * end the discovery process. + */ + ble_error_t discoverDescriptors( + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t &onDescriptorDiscovered, + const CharacteristicDescriptorDiscovery::TerminationCallback_t &onTermination + ) const; + + /** + * Initiate a write procedure of the characteristic value. + * + * Unlike write without responses (see writeWoResponse()), an acknowledgment + * is expected for this procedure. The response of the peer GATT server to + * the write request is passed to callbacks registered in + * GattClient::onDataWritten(). + * + * Similarly to read responses, responses to write request of this + * characteristic can be identified by their connection handle ( + * GattWriteCallbackParams::connHandle), which is equal to the value + * returned by getConnectionHandle() and their attribute handle ( + * GattWriteCallbackParams::handle), which is equal to the value + * returned by getValueHandle(). + * + * @param[in] length The amount of data being written. + * @param[in] value The bytes being written. + * + * @return BLE_ERROR_NONE Successfully started the Write procedure. + * @return BLE_ERROR_INVALID_STATE If some internal state about the + * connection is invalid. + * @return BLE_STACK_BUSY If some client procedure is already in progress. + * @return BLE_ERROR_NO_MEM If there are no available buffers left to + * process the request. + * @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's + * properties. + * + * @note Internally, the API uses the write or long write procedure, depending + * on the number of bytes to write and the MTU size. + */ + ble_error_t write(uint16_t length, const uint8_t *value) const; + + /** + * Initiate a write procedure of the characteristic value. + * + * Same as write(uint16_t, const uint8_t *) const but accepts a completion + * callback, which is invoked when the server response is received. + * + * @param[in] length The amount of bytes to write. + * @param[in] value The bytes to write. + * @param[in] onWrite Continuation callback of the write procedure. + * + * @return BLE_ERROR_NONE Successfully started the Write procedure. + * @return BLE_ERROR_INVALID_STATE if some internal state about the + * connection is invalid. + * @return BLE_STACK_BUSY if some client procedure is already in progress. + * @return BLE_ERROR_NO_MEM if there are no available buffers left to + * process the request. + * @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's + * properties. + */ + ble_error_t write( + uint16_t length, + const uint8_t *value, + const GattClient::WriteCallback_t &onWrite + ) const; + + void setupLongUUID(UUID::LongUUIDBytes_t longUUID, UUID::ByteOrder_t order = UUID::MSB) { + uuid.setupLong(longUUID, order); + } + +public: + /** + * Get the UUID of the discovered characteristic. + * + * @return The UUID of this characteristic. + */ + const UUID &getUUID(void) const + { + return uuid; + } + + /** + * Get the properties of this characteristic. + * + * @return The set of properties of this characteristic. + */ + const Properties_t &getProperties(void) const + { + return props; + } + + /** + * Get the declaration handle of this characteristic. + * + * The declaration handle is the first handle of a characteristic + * definition. The value accessible at this handle contains the following + * informations: + * - The characteristics properties (see Properties_t). This value can + * be accessed by using #getProperties . + * - The characteristic value attribute handle. This field can be accessed + * by using #getValueHandle . + * - The characteristic UUID, this value can be accessed by using the + * function #getUUID . + * + * @return the declaration handle of this characteristic. + */ + GattAttribute::Handle_t getDeclHandle(void) const + { + return declHandle; + } + + /** + * Get the attribute handle of the characteristic value. + * + * This handle is used to read or write the value of the characteristic. + * + * @return The handle to access the value of this characteristic. + */ + GattAttribute::Handle_t getValueHandle(void) const + { + return valueHandle; + } + + /** + * Return the last attribute handle of the characteristic definition. + * + * The attribute layout of a characteristic definition is: + * - Declaration attribute (see #getDeclHandle). + * - Value attribute (see #getValueHandle). + * - Zero or more characteristic descriptors attribute. + * + * The last attribute handle is used internally to discover characteristic + * descriptors. The discovery operates on the range [ValueHandle + 1 : + * LastHandle]. + * + * @return The last handle of this characteristic definition. + * + * @note This function is public for informative purposes. + */ + GattAttribute::Handle_t getLastHandle(void) const + { + return lastHandle; + } + + /** + * Get the GattClient, which can operate on this characteristic. + * + * @return The GattClient, which can operate on this characteristic. + */ + GattClient* getGattClient() + { + return gattc; + } + + /** + * Get the GattClient, which can operate on this characteristic. + * + * @return The GattClient, which can operate on this characteristic. + */ + const GattClient* getGattClient() const + { + return gattc; + } + + /** + * @brief Get the connection handle to the GattServer containing this + * characteristic. + * + * @return Connection handle to the GattServer, which contains this + * characteristic. + */ + Gap::Handle_t getConnectionHandle() const + { + return connHandle; + } + + /** + * "Equal to" operator for DiscoveredCharacteristic. + * + * @param[in] lhs The left hand side of the equality expression. + * @param[in] rhs The right hand side of the equality expression. + * + * @return true if operands are equals and false otherwise. + */ + friend bool operator==( + const DiscoveredCharacteristic& lhs, const DiscoveredCharacteristic& rhs + ) { + return lhs.gattc == rhs.gattc && + lhs.uuid == rhs.uuid && + lhs.props == rhs.props && + lhs.declHandle == rhs.declHandle && + lhs.valueHandle == rhs.valueHandle && + lhs.lastHandle == rhs.lastHandle && + lhs.connHandle == rhs.connHandle; + } + + /** + * "Not equal to" operator for DiscoveredCharacteristic. + * + * @param[in] lhs The right hand side of the expression. + * @param[in] rhs The left hand side of the expression. + * + * @return true if operands are not equal and false otherwise. + */ + friend bool operator !=( + const DiscoveredCharacteristic& lhs, const DiscoveredCharacteristic& rhs + ) { + return !(lhs == rhs); + } + +public: + DiscoveredCharacteristic() : + gattc(NULL), + uuid(UUID::ShortUUIDBytes_t(0)), + props(), + declHandle(GattAttribute::INVALID_HANDLE), + valueHandle(GattAttribute::INVALID_HANDLE), + lastHandle(GattAttribute::INVALID_HANDLE), + connHandle() { + } + +protected: + /** + * Pointer to the underlying GattClient for this DiscoveredCharacteristic + * object. + */ + GattClient *gattc; + +protected: + /** + * Discovered characteristic's UUID. + */ + UUID uuid; + + /** + * Hold the configured properties of the discovered characteristic. + * + * @see Properties_t. + */ + Properties_t props; + + /** + * Value handle of the discovered characteristic's declaration attribute. + */ + GattAttribute::Handle_t declHandle; + + /** + * Value handle of the discovered characteristic's value attribute. + */ + GattAttribute::Handle_t valueHandle; + + /** + * Value handle of the discovered characteristic's last attribute. + */ + GattAttribute::Handle_t lastHandle; + + /** + * Handle of the connection where the characteristic was discovered. + */ + Gap::Handle_t connHandle; +}; + +/** + * @} + * @} + * @} + */ + +#endif /*MBED_DISCOVERED_CHARACTERISTIC_H__*/