Marco Zecchini
/
Example_RTOS
Rtos API example
mbed-os/features/FEATURE_BLE/ble/DiscoveredCharacteristic.h
- Committer:
- marcozecchini
- Date:
- 2019-02-23
- Revision:
- 0:9fca2b23d0ba
File content as of revision 0:9fca2b23d0ba:
/* 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__*/