Mbed OS Reference
Loading...
Searching...
No Matches
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
28namespace ble {
29class 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 */
95public:
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 */
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 */
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 */
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 */
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 */
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 */
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
444public:
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
584public:
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
595protected:
596 /**
597 * Pointer to the underlying ble::GattClient for this DiscoveredCharacteristic
598 * object.
599 */
601
602protected:
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__*/
Representation of a characteristic discovered.
GattAttribute::Handle_t declHandle
Value handle of the discovered characteristic's declaration attribute.
GattAttribute::Handle_t getValueHandle() const
Get the attribute handle of the characteristic value.
const Properties_t & getProperties() const
Get the properties of this characteristic.
GattAttribute::Handle_t getDeclHandle() const
Get the declaration handle of this characteristic.
GattAttribute::Handle_t valueHandle
Value handle of the discovered characteristic's value attribute.
ble_error_t write(uint16_t length, const uint8_t *value, const ble::WriteCallback_t &onWrite) const
Initiate a write procedure of the characteristic value.
ble_error_t read(uint16_t offset=0) const
Initiate a read of the characteristic value.
ble_error_t writeWoResponse(uint16_t length, const uint8_t *value) const
Perform a write without response procedure.
ble::connection_handle_t connHandle
Handle of the connection where the characteristic was discovered.
GattAttribute::Handle_t getLastHandle() const
Return the last attribute handle of the characteristic definition.
GattAttribute::Handle_t lastHandle
Value handle of the discovered characteristic's last attribute.
ble_error_t write(uint16_t length, const uint8_t *value) const
Initiate a write procedure of the characteristic value.
friend bool operator==(const DiscoveredCharacteristic &lhs, const DiscoveredCharacteristic &rhs)
"Equal to" operator for DiscoveredCharacteristic.
ble::connection_handle_t getConnectionHandle() const
Get the connection handle to the GattServer containing this characteristic.
friend bool operator!=(const DiscoveredCharacteristic &lhs, const DiscoveredCharacteristic &rhs)
"Not equal to" operator for DiscoveredCharacteristic.
Properties_t props
Hold the configured properties of the discovered characteristic.
ble_error_t discoverDescriptors(const CharacteristicDescriptorDiscovery::DiscoveryCallback_t &onDescriptorDiscovered, const CharacteristicDescriptorDiscovery::TerminationCallback_t &onTermination) const
Initiate a discovery of the characteristic descriptors.
const ble::GattClient * getGattClient() const
Get the ble::GattClient, which can operate on this characteristic.
ble::GattClient * getGattClient()
Get the ble::GattClient, which can operate on this characteristic.
ble::GattClient * gattc
Pointer to the underlying ble::GattClient for this DiscoveredCharacteristic object.
UUID uuid
Discovered characteristic's UUID.
ble_error_t read(uint16_t offset, const ble::ReadCallback_t &onRead) const
Initiate a read of the characteristic value and pass the response to its completion callback.
const UUID & getUUID() const
Get the UUID of the discovered characteristic.
Function like object adapter over freestanding and member functions.
Representation of a GattServer attribute.
ble::attribute_handle_t Handle_t
Representation of an attribute handle.
Representation of a Universally Unique Identifier (UUID).
Definition: common/UUID.h:76
void setupLong(const LongUUIDBytes_t longUUID, ByteOrder_t order=UUID::MSB)
Replace existing value with a 128-bit UUID.
Definition: common/UUID.h:264
uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID]
Type for a 128-bit UUID.
Definition: common/UUID.h:124
ByteOrder_t
Enumeration of byte ordering.
Definition: common/UUID.h:99
@ MSB
Most significant byte first (at the smallest address).
Definition: common/UUID.h:103
Define procedures required for interacting with a distant GATT server.
Definition: GattClient.h:97
ble_error_t
Error codes for the BLE API.
Entry namespace for all BLE API definitions.
uintptr_t connection_handle_t
Opaque reference to a connection.
Properties of a discovered characteristic.
friend bool operator==(Properties_t lhs, Properties_t rhs)
Equal to operator for DiscoveredCharacteristic::Properties_t.
uint8_t _indicate
If set, the server can emit indication of the Characteristic Value (with client acknowledgement).
uint8_t _notify
If set, the server can emit notifications of the Characteristic Value (without client acknowledgment)...
bool writeWoResp() const
Return the value of the write without response property.
uint8_t _writeWoResp
If set, a write command can write the characteristic value (write without response).
bool broadcast() const
Return the value of the broadcast propertie.
uint8_t _write
If set, clients can issue requests to write the characteristic.
bool indicate() const
Return the value of the indicate property.
bool read() const
Return the value of the read property.
bool notify() const
Return the value of the notification property.
uint8_t _authSignedWrite
If set, signed write of the Characteristic Value is supported.
uint8_t _broadcast
Permits broadcasts of the characteristic value using the character the Server Characteristic Configur...
bool write() const
Return the value of the write property.
uint8_t _read
If set, the value of the characteristic can be read.
bool authSignedWrite() const
Return the value of the authenticated signed writes property.
friend bool operator!=(Properties_t lhs, Properties_t rhs)
Not equal to operator for DiscoveredCharacteristic::Properties_t.