Mistake on this page?
Report an issue in GitHub or email us
gatt/DiscoveredCharacteristic.h
1 /* mbed Microcontroller Library
2  * Copyright (c) 2006-2020 ARM Limited
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #ifndef MBED_DISCOVERED_CHARACTERISTIC_H__
20 #define MBED_DISCOVERED_CHARACTERISTIC_H__
21 
22 #include "ble/common/UUID.h"
23 #include "ble/gatt/GattAttribute.h"
24 #include "ble/gatt/GattCallbackParamTypes.h"
25 #include "ble/gatt/CharacteristicDescriptorDiscovery.h"
26 #include "ble/gatt/DiscoveredCharacteristicDescriptor.h"
27 
28 namespace ble {
29 class GattClient;
30 }
31 
32 /**
33  * @addtogroup ble
34  * @{
35  * @addtogroup gatt
36  * @{
37  * @addtogroup client
38  * @{
39  */
40 
41 /**
42  * Representation of a characteristic discovered.
43  *
44  * The ble::GattClient discovery procedure initiated with
45  * ble::GattClient::launchServiceDiscovery() generates instances of this class.
46  *
47  * It exposes the main attributes of the discovered characteristic:
48  * - The UUID of the characteristic, it can be retrieved by a call to the
49  * function getUUID(). This UUID is the type of the characteristic.
50  * - Attribute Handles of the characteristic are present as the triplet
51  * declaration handle, value handle and last handle. The value handle is
52  * used to read or write the content of the characteristic.
53  * - The properties contain the set of operations the characteristic can
54  * handle, for instance being read or written.
55  *
56  * It important to note that the value of the characteristic - if it is
57  * accessible - is not fetched at discovery time.
58  *
59  * The main operations the class offers are reading, writing and discovering
60  * the descriptors of the characteristic discovered.
61  *
62  * Reading a discovered characteristic can be accomplished in two different
63  * fashions:
64  *
65  * If the user has a callback registered for the data read operation in the
66  * ble::GattClient, then a call to the read(uint16_t) function will initiate a read of
67  * the characteristic. Results of the operation will be pass on the callback
68  * registered by ble::GattClient::onDataRead(), which processes all the responses to
69  * read requests. The read request for a given characteristic can be identified
70  * by the connection handle and the attribute handle, which are present in
71  * GattReadCallbackParams.
72  *
73  * Another overload (read(uint16_t, const ble::ReadCallback_t&)) of the
74  * read function accepts a completion callback as a last parameter. That
75  * completion callback will be invoked automatically once the response to the
76  * read request for that given characteristic has been received. However,
77  * convenience came at the expense of dynamic memory usage for the time of the
78  * transaction.
79  *
80  * Similarly, two versions of the write() API are exposed. One where the user
81  * has to register a callback handling write response through the function
82  * ble::GattClient::onDataWritten() and another one that accepts a completion
83  * callback in input.
84  *
85  * It is also possible to send a write command, which is not acknowledged by the
86  * peer server by using the function writeWoResponse().
87  *
88  * Finally, descriptors of the characteristic can be discovered by invoking the
89  * function discoverDescriptors, which is shorthand for calling
90  * ble::GattClient::discoverCharacteristicDescriptors. That discovery is necessary to
91  * enable or disable characteristic notification or indication that is achieved
92  * by writing on the Client Characteristic Configuration Descriptor (CCCD).
93  */
95 public:
96  /**
97  * Properties of a discovered characteristic.
98  */
99  struct Properties_t {
100  /**
101  * Permits broadcasts of the characteristic value using the character
102  * the Server Characteristic Configuration Descriptor.
103  *
104  * @note If set, descriptors of the characteristic contain a Server
105  * Characteristic Configuration Descriptor.
106  */
107  uint8_t _broadcast :1;
108 
109  /**
110  * If set, the value of the characteristic can be read.
111  */
112  uint8_t _read :1;
113 
114  /**
115  * If set, a write command can write the characteristic value
116  * (write without response).
117  */
118  uint8_t _writeWoResp :1;
119 
120  /**
121  * If set, clients can issue requests to write the characteristic.
122  */
123  uint8_t _write :1;
124 
125  /**
126  * If set, the server can emit notifications of the Characteristic Value
127  * (without client acknowledgment).
128  *
129  * @note If set, descriptors of the characteristic contain a Client
130  * Characteristic Configuration Descriptor.
131  */
132  uint8_t _notify :1;
133 
134  /**
135  * If set, the server can emit indication of the Characteristic Value
136  * (with client acknowledgement).
137  *
138  * @note If set, descriptors of the characteristic contain a Client
139  * Characteristic Configuration Descriptor.
140  */
141  uint8_t _indicate :1;
142 
143  /**
144  * If set, signed write of the Characteristic Value is supported.
145  */
146  uint8_t _authSignedWrite :1;
147 
148  public:
149  /**
150  * Return the value of the broadcast propertie.
151  *
152  * @return true if the Server Characteristic Configuration Descriptor
153  * of the characteristic can be configured to broadcast the
154  * characteristic value during broadcast procedure.
155  *
156  * @see _broadcast
157  */
158  bool broadcast() const
159  {
160  return _broadcast;
161  }
162 
163  /**
164  * Return the value of the read property
165  *
166  * @return true if the characteristic value can be read and false
167  * otherwise.
168  *
169  * @see _read
170  */
171  bool read() const
172  {
173  return _read;
174  }
175 
176  /**
177  * Return the value of the write without response property.
178  *
179  * @return true if the characteristic accepts write without response
180  * commands and false otherwise.
181  *
182  * @see _writeWoResp
183  */
184  bool writeWoResp() const
185  {
186  return _writeWoResp;
187  }
188 
189  /**
190  * Return the value of the write property.
191  *
192  * @return true if writing the characteristic accepts write requests and
193  * false otherwise.
194  *
195  * @see _write
196  */
197  bool write() const
198  {
199  return _write;
200  }
201 
202  /**
203  * Return the value of the notification property.
204  *
205  * @return true if the Client Characteristic Configuration Descriptor
206  * can be configured to notify the characteristic value to a given
207  * client and false otherwise.
208  *
209  * @note unlike indication, the notification procedure does not require
210  * acknowledgement from the client.
211  *
212  * @see _notify
213  */
214  bool notify() const
215  {
216  return _notify;
217  }
218 
219  /**
220  * Return the value of the indicate property.
221  *
222  * @return true if the Client Characteristic Configuration Descriptor
223  * can be configured to indicate the characteristic value to a given
224  * client and false otherwise.
225  *
226  * @note unlike notification the indication procedure does require
227  * acknowledgment from the client.
228  *
229  * @see _indicate
230  */
231  bool indicate() const
232  {
233  return _indicate;
234  }
235 
236  /**
237  * Return the value of the authenticated signed writes property.
238  *
239  * @return true if the characteristic accepts authenticated signed write
240  * and false otherwise.
241  */
242  bool authSignedWrite() const
243  {
244  return _authSignedWrite;
245  }
246 
247  /**
248  * Equal to operator for DiscoveredCharacteristic::Properties_t.
249  *
250  * @param[in] lhs The left hand side of the equality expression.
251  * @param[in] rhs The right hand side of the equality expression.
252  *
253  * @return true if operands are equals and false otherwise.
254  */
255  friend bool operator==(Properties_t lhs, Properties_t rhs)
256  {
257  return lhs._broadcast == rhs._broadcast &&
258  lhs._read == rhs._read &&
259  lhs._writeWoResp == rhs._writeWoResp &&
260  lhs._write == rhs._write &&
261  lhs._notify == rhs._notify &&
262  lhs._indicate == rhs._indicate &&
264  }
265 
266  /**
267  * Not equal to operator for DiscoveredCharacteristic::Properties_t.
268  *
269  * @param lhs The left hand side of the expression.
270  * @param rhs The right hand side of the expression.
271  *
272  * @return true if operands are not equals, false otherwise.
273  */
274  friend bool operator!=(Properties_t lhs, Properties_t rhs)
275  {
276  return !(lhs == rhs);
277  }
278 
279  private:
280  /* Disallow implicit conversion to integer types. */
281  operator uint8_t() const;
282  operator unsigned() const;
283  };
284 
285  /**
286  * Initiate a read of the characteristic value.
287  *
288  * The characteristic value is read in its entirety from the value attribute
289  * of the characteristic.
290  *
291  * Read responses will be passed to the callback registered in
292  * ble::GattClient::onDataRead(). Read responses to read requests that this function
293  * call initiates will have their GattReadCallbackParams::connHandle
294  * field equal to the value returned by getConnectionHandle() and their
295  * GattReadCallbackParams::handle field equal to the value returned by
296  * getValueHandle().
297  *
298  * @param[in] offset The position - in the characteristic value bytes stream
299  * - where the read operation begin. This parameter is optional.
300  *
301  * @return BLE_ERROR_NONE if a read has been initiated.
302  * @return BLE_ERROR_INVALID_STATE if some internal state about the
303  * connection is invalid.
304  * @return BLE_STACK_BUSY if some client procedure is already in progress.
305  * @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's
306  * properties.
307  */
308  ble_error_t read(uint16_t offset = 0) const;
309 
310  /**
311  * Initiate a read of the characteristic value and pass the response to its
312  * completion callback.
313  *
314  * @param[in] offset The position - in the characteristic value bytes stream
315  * - where the read operation begin.
316  *
317  * @param[in] onRead Completion callback which will accept the response of
318  * the read request. The callback is copied; it is unnecessary to keep it
319  * in memory after the call.
320  *
321  * @return BLE_ERROR_NONE if a read has been initiated.
322  * @return BLE_ERROR_INVALID_STATE if some internal state about the
323  * connection is invalid.
324  * @return BLE_STACK_BUSY if some client procedure is already in progress.
325  * @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's
326  * properties.
327  *
328  * @note This function is similar to read(uint16_t) const; however, it uses
329  * dynamic memory to store the use completion callback.
330  */
331  ble_error_t read(
332  uint16_t offset,
333  const ble::ReadCallback_t &onRead
334  ) const;
335 
336  /**
337  * Perform a write without response procedure.
338  *
339  * @note The server does not acknowledge write without responses.
340  * Therefore, they won't generate any event on the client side.
341  *
342  * @param[in] length The amount of data being written.
343  * @param[in] value The bytes being written.
344  *
345  * @return BLE_ERROR_NONE Successfully started the Write procedure.
346  * @return BLE_ERROR_INVALID_STATE if some internal state about the
347  * connection is invalid.
348  * @return BLE_STACK_BUSY if some client procedure is already in progress.
349  * @return BLE_ERROR_NO_MEM if there are no available buffers left to
350  * process the request.
351  * @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's
352  * properties.
353  */
354  ble_error_t writeWoResponse(uint16_t length, const uint8_t *value) const;
355 
356  /**
357  * Initiate a discovery of the characteristic descriptors.
358  *
359  * When a descriptor is discovered, the callback onDescriptorDiscovered is
360  * invoked with the descriptor discovered as parameter. When the process
361  * ends, the callback onTermination is invoked.
362  *
363  * @param[in] onDescriptorDiscovered Callback is invoked when a descriptor is
364  * discovered.
365  *
366  * @param[in] onTermination Callback is invoked when the discovery process ends.
367  *
368  * @return BLE_ERROR_NONE if descriptor discovery is launched successfully;
369  * else an appropriate error.
370  *
371  * @note This function is shorthand for
372  * ble::GattClient::discoverCharacteristicDescriptors; therefore,
373  * ble::GattClient::isCharacteristicDescriptorDiscoveryActive can be used to
374  * determine the descriptor discovery and
375  * ble::GattClient::terminateCharacteristicDescriptorDiscovery can be used to
376  * end the discovery process.
377  */
378  ble_error_t discoverDescriptors(
379  const CharacteristicDescriptorDiscovery::DiscoveryCallback_t &onDescriptorDiscovered,
381  ) const;
382 
383  /**
384  * Initiate a write procedure of the characteristic value.
385  *
386  * Unlike write without responses (see writeWoResponse()), an acknowledgment
387  * is expected for this procedure. The response of the peer GATT server to
388  * the write request is passed to callbacks registered in
389  * ble::GattClient::onDataWritten().
390  *
391  * Similarly to read responses, responses to write request of this
392  * characteristic can be identified by their connection handle (
393  * GattWriteCallbackParams::connHandle), which is equal to the value
394  * returned by getConnectionHandle() and their attribute handle (
395  * GattWriteCallbackParams::handle), which is equal to the value
396  * returned by getValueHandle().
397  *
398  * @param[in] length The amount of data being written.
399  * @param[in] value The bytes being written.
400  *
401  * @return BLE_ERROR_NONE Successfully started the Write procedure.
402  * @return BLE_ERROR_INVALID_STATE If some internal state about the
403  * connection is invalid.
404  * @return BLE_STACK_BUSY If some client procedure is already in progress.
405  * @return BLE_ERROR_NO_MEM If there are no available buffers left to
406  * process the request.
407  * @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's
408  * properties.
409  *
410  * @note Internally, the API uses the write or long write procedure, depending
411  * on the number of bytes to write and the MTU size.
412  */
413  ble_error_t write(uint16_t length, const uint8_t *value) const;
414 
415  /**
416  * Initiate a write procedure of the characteristic value.
417  *
418  * Same as write(uint16_t, const uint8_t *) const but accepts a completion
419  * callback, which is invoked when the server response is received.
420  *
421  * @param[in] length The amount of bytes to write.
422  * @param[in] value The bytes to write.
423  * @param[in] onWrite Continuation callback of the write procedure.
424  *
425  * @return BLE_ERROR_NONE Successfully started the Write procedure.
426  * @return BLE_ERROR_INVALID_STATE if some internal state about the
427  * connection is invalid.
428  * @return BLE_STACK_BUSY if some client procedure is already in progress.
429  * @return BLE_ERROR_NO_MEM if there are no available buffers left to
430  * process the request.
431  * @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's
432  * properties.
433  */
434  ble_error_t write(
435  uint16_t length,
436  const uint8_t *value,
437  const ble::WriteCallback_t &onWrite
438  ) const;
439 
440  void setupLongUUID(UUID::LongUUIDBytes_t longUUID, UUID::ByteOrder_t order = UUID::MSB) {
441  uuid.setupLong(longUUID, order);
442  }
443 
444 public:
445  /**
446  * Get the UUID of the discovered characteristic.
447  *
448  * @return The UUID of this characteristic.
449  */
450  const UUID &getUUID() const
451  {
452  return uuid;
453  }
454 
455  /**
456  * Get the properties of this characteristic.
457  *
458  * @return The set of properties of this characteristic.
459  */
461  {
462  return props;
463  }
464 
465  /**
466  * Get the declaration handle of this characteristic.
467  *
468  * The declaration handle is the first handle of a characteristic
469  * definition. The value accessible at this handle contains the following
470  * informations:
471  * - The characteristics properties (see Properties_t). This value can
472  * be accessed by using #getProperties .
473  * - The characteristic value attribute handle. This field can be accessed
474  * by using #getValueHandle .
475  * - The characteristic UUID, this value can be accessed by using the
476  * function #getUUID .
477  *
478  * @return the declaration handle of this characteristic.
479  */
481  {
482  return declHandle;
483  }
484 
485  /**
486  * Get the attribute handle of the characteristic value.
487  *
488  * This handle is used to read or write the value of the characteristic.
489  *
490  * @return The handle to access the value of this characteristic.
491  */
493  {
494  return valueHandle;
495  }
496 
497  /**
498  * Return the last attribute handle of the characteristic definition.
499  *
500  * The attribute layout of a characteristic definition is:
501  * - Declaration attribute (see #getDeclHandle).
502  * - Value attribute (see #getValueHandle).
503  * - Zero or more characteristic descriptors attribute.
504  *
505  * The last attribute handle is used internally to discover characteristic
506  * descriptors. The discovery operates on the range [ValueHandle + 1 :
507  * LastHandle].
508  *
509  * @return The last handle of this characteristic definition.
510  *
511  * @note This function is public for informative purposes.
512  */
514  {
515  return lastHandle;
516  }
517 
518  /**
519  * Get the ble::GattClient, which can operate on this characteristic.
520  *
521  * @return The ble::GattClient, which can operate on this characteristic.
522  */
524  {
525  return gattc;
526  }
527 
528  /**
529  * Get the ble::GattClient, which can operate on this characteristic.
530  *
531  * @return The ble::GattClient, which can operate on this characteristic.
532  */
534  {
535  return gattc;
536  }
537 
538  /**
539  * @brief Get the connection handle to the GattServer containing this
540  * characteristic.
541  *
542  * @return Connection handle to the GattServer, which contains this
543  * characteristic.
544  */
546  {
547  return connHandle;
548  }
549 
550  /**
551  * "Equal to" operator for DiscoveredCharacteristic.
552  *
553  * @param[in] lhs The left hand side of the equality expression.
554  * @param[in] rhs The right hand side of the equality expression.
555  *
556  * @return true if operands are equals and false otherwise.
557  */
558  friend bool operator==(
560  ) {
561  return lhs.gattc == rhs.gattc &&
562  lhs.uuid == rhs.uuid &&
563  lhs.props == rhs.props &&
564  lhs.declHandle == rhs.declHandle &&
565  lhs.valueHandle == rhs.valueHandle &&
566  lhs.lastHandle == rhs.lastHandle &&
567  lhs.connHandle == rhs.connHandle;
568  }
569 
570  /**
571  * "Not equal to" operator for DiscoveredCharacteristic.
572  *
573  * @param[in] lhs The right hand side of the expression.
574  * @param[in] rhs The left hand side of the expression.
575  *
576  * @return true if operands are not equal and false otherwise.
577  */
578  friend bool operator !=(
580  ) {
581  return !(lhs == rhs);
582  }
583 
584 public:
586  gattc(nullptr),
587  uuid(UUID::ShortUUIDBytes_t(0)),
588  props(),
589  declHandle(GattAttribute::INVALID_HANDLE),
590  valueHandle(GattAttribute::INVALID_HANDLE),
591  lastHandle(GattAttribute::INVALID_HANDLE),
592  connHandle() {
593  }
594 
595 protected:
596  /**
597  * Pointer to the underlying ble::GattClient for this DiscoveredCharacteristic
598  * object.
599  */
601 
602 protected:
603  /**
604  * Discovered characteristic's UUID.
605  */
607 
608  /**
609  * Hold the configured properties of the discovered characteristic.
610  *
611  * @see Properties_t.
612  */
614 
615  /**
616  * Value handle of the discovered characteristic's declaration attribute.
617  */
619 
620  /**
621  * Value handle of the discovered characteristic's value attribute.
622  */
624 
625  /**
626  * Value handle of the discovered characteristic's last attribute.
627  */
629 
630  /**
631  * Handle of the connection where the characteristic was discovered.
632  */
634 };
635 
636 /**
637  * @}
638  * @}
639  * @}
640  */
641 
642 #endif /*MBED_DISCOVERED_CHARACTERISTIC_H__*/
Function like object adapter over freestanding and member functions.
uint8_t _notify
If set, the server can emit notifications of the Characteristic Value (without client acknowledgment)...
ByteOrder_t
Enumeration of byte ordering.
Definition: common/UUID.h:99
ble::GattClient * gattc
Pointer to the underlying ble::GattClient for this DiscoveredCharacteristic object.
uint8_t _indicate
If set, the server can emit indication of the Characteristic Value (with client acknowledgement).
uintptr_t connection_handle_t
Opaque reference to a connection.
GattAttribute::Handle_t getLastHandle() const
Return the last attribute handle of the characteristic definition.
Representation of a characteristic discovered.
bool broadcast() const
Return the value of the broadcast propertie.
GattAttribute::Handle_t declHandle
Value handle of the discovered characteristic's declaration attribute.
Most significant byte first (at the smallest address).
Definition: common/UUID.h:103
static const Handle_t INVALID_HANDLE
Invalid attribute handle.
bool authSignedWrite() const
Return the value of the authenticated signed writes property.
friend bool operator==(const DiscoveredCharacteristic &lhs, const DiscoveredCharacteristic &rhs)
"Equal to" operator for DiscoveredCharacteristic.
uint8_t _write
If set, clients can issue requests to write the characteristic.
ble::GattClient * getGattClient()
Get the ble::GattClient, which can operate on this characteristic.
uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID]
Type for a 128-bit UUID.
Definition: common/UUID.h:124
UUID uuid
Discovered characteristic's UUID.
friend bool operator!=(Properties_t lhs, Properties_t rhs)
Not equal to operator for DiscoveredCharacteristic::Properties_t.
Representation of a Universally Unique Identifier (UUID).
Definition: common/UUID.h:76
uint8_t _writeWoResp
If set, a write command can write the characteristic value (write without response).
ble::connection_handle_t connHandle
Handle of the connection where the characteristic was discovered.
ble::attribute_handle_t Handle_t
Representation of an attribute handle.
GattAttribute::Handle_t lastHandle
Value handle of the discovered characteristic's last attribute.
uint8_t _read
If set, the value of the characteristic can be read.
void operator!=(const SafeBool< T > &lhs, const SafeBool< U > &rhs)
Avoid conversion to bool between different classes.
bool write() const
Return the value of the write property.
GattAttribute::Handle_t getDeclHandle() const
Get the declaration handle of this characteristic.
uint8_t _broadcast
Permits broadcasts of the characteristic value using the character the Server Characteristic Configur...
ble::connection_handle_t getConnectionHandle() const
Get the connection handle to the GattServer containing this characteristic.
uint16_t ShortUUIDBytes_t
Type for a 16-bit UUID.
Definition: common/UUID.h:114
const UUID & getUUID() const
Get the UUID of the discovered characteristic.
Define procedures required for interacting with a distant GATT server.
Definition: GattClient.h:97
Properties_t props
Hold the configured properties of the discovered characteristic.
bool writeWoResp() const
Return the value of the write without response property.
Properties of a discovered characteristic.
const ble::GattClient * getGattClient() const
Get the ble::GattClient, which can operate on this characteristic.
GattAttribute::Handle_t valueHandle
Value handle of the discovered characteristic&#39;s value attribute.
GattAttribute::Handle_t getValueHandle() const
Get the attribute handle of the characteristic value.
friend bool operator==(Properties_t lhs, Properties_t rhs)
Equal to operator for DiscoveredCharacteristic::Properties_t.
Entry namespace for all BLE API definitions.
const Properties_t & getProperties() const
Get the properties of this characteristic.
bool notify() const
Return the value of the notification property.
bool read() const
Return the value of the read property.
uint8_t _authSignedWrite
If set, signed write of the Characteristic Value is supported.
bool indicate() const
Return the value of the indicate property.
ble_error_t
Error codes for the BLE API.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.