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