Mistake on this page?
Report an issue in GitHub or email us
GattServer.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 
20 #ifndef MBED_GATT_SERVER_H__
21 #define MBED_GATT_SERVER_H__
22 
23 #include "ble/common/CallChainOfFunctionPointersWithContext.h"
24 #include "ble/common/blecommon.h"
25 
26 #include "ble/gatt/GattService.h"
27 #include "ble/gatt/GattAttribute.h"
28 #include "ble/gatt/GattCallbackParamTypes.h"
29 
30 namespace ble {
31 
32 #if !defined(DOXYGEN_ONLY)
33 namespace impl {
34 class GattServer;
35 }
36 #endif // !defined(DOXYGEN_ONLY)
37 
38 
39 /**
40  * @addtogroup ble
41  * @{
42  * @addtogroup gatt
43  * @{
44  * @addtogroup server
45  * @{
46  */
47 
48 /**
49  * Construct and operates a GATT server.
50  *
51  * A Gatt server is a collection of GattService; these services contain
52  * characteristics that a peer connected to the device may read or write.
53  * These characteristics may also emit updates to subscribed clients when their
54  * values change.
55  *
56  * @p Server Layout
57  *
58  * Application code can add a GattService object to the server with the help of
59  * the function addService(). That function registers all the GattCharacteristic
60  * enclosed in the service, as well as all the characteristics descriptors (see
61  * GattAttribute) these characteristics contain. Service registration assigns
62  * a unique handle to the various attributes being part of the service; this
63  * handle should be used for subsequent read or write of these components.
64  *
65  * There are no primitives defined to remove a single service; however, a call to
66  * the function reset() removes all services previously registered in the
67  * GattServer.
68  *
69  * @p Characteristic and attributes access
70  *
71  * Values of the characteristic and the characteristic descriptor present in the
72  * GattServer must be accessed through the handle assigned to them when the service
73  * has been registered; the GattServer class offers several flavors of read()
74  * and write() functions that retrieve or mutate an attribute value.
75  *
76  * Application code can query if a client has subscribed to a given
77  * characteristic's value update by invoking the function areUpdatesEnabled().
78  *
79  * @p Events
80  *
81  * The GattServer allows application code to register several event handlers that
82  * can be used to monitor client and server activities:
83  * - onDataSent(): Register an event handler that is called when a
84  * characteristic value update has been sent to a client.
85  * - onDataWriten(): Register an event handler that is called when a
86  * client has written an attribute of the server.
87  * - onDataRead(): Register an event handler that is called when a
88  * client has read an attribute of the server.
89  * - onUpdatesEnabled: Register an event handler that is called when a
90  * client subscribes to updates of a characteristic.
91  * - onUpdatesDisabled: Register an event handler that is called when a
92  * client unsubscribes from updates of a characteristic.
93  * - onConfimationReceived: Register an event handler that is called
94  * when a client acknowledges a characteristic value notification.
95  *
96  * @note The term characteristic value update is used to represent
97  * Characteristic Value Notification and Characteristic Value Indication when
98  * the nature of the server initiated is not relevant.
99  */
100 class GattServer {
101 public:
102  /**
103  * Definition of the general handler of GattServer related events.
104  */
105  struct EventHandler {
106  /**
107  * Function invoked when the connections changes the ATT_MTU which controls
108  * the maximum size of an attribute that can be read in a single L2CAP packet
109  * which might be fragmented across multiple packets.
110  *
111  * @param connectionHandle The handle of the connection that changed the size.
112  * @param attMtuSize
113  */
114  virtual void onAttMtuChange(
115  ble::connection_handle_t connectionHandle,
116  uint16_t attMtuSize
117  ) {
118  (void)connectionHandle;
119  (void)attMtuSize;
120  }
121  protected:
122  /**
123  * Prevent polymorphic deletion and avoid unnecessary virtual destructor
124  * as the GattServer class will never delete the instance it contains.
125  */
126  ~EventHandler() = default;
127  };
128 
129  /**
130  * Event handler invoked when the server has sent data to a client.
131  *
132  * @see onDataSent().
133  */
135 
136  /**
137  * Callchain of DataSentCallback_t objects.
138  *
139  * @see onDataSent().
140  */
143 
144  /**
145  * Event handler invoked when the client has written an attribute of the
146  * server.
147  *
148  * @see onDataWritten().
149  */
152 
153  /**
154  * Callchain of DataWrittenCallback_t objects.
155  *
156  * @see onDataWritten().
157  */
160 
161  /**
162  * Event handler invoked when the client has read an attribute of the server.
163  *
164  * @see onDataRead().
165  */
168 
169  /**
170  * Callchain of DataReadCallback_t.
171  *
172  * @see onDataRead().
173  */
176 
177  /**
178  * Event handler invoked when the GattServer is reset.
179  *
180  * @see onShutdown() reset()
181  */
184 
185  /**
186  * Callchain of GattServerShutdownCallback_t.
187  *
188  * @see onShutdown() reset()
189  */
192 
193  /**
194  * Event handler that handles subscription to characteristic updates,
195  * unsubscription from characteristic updates and notification confirmation.
196  *
197  * @see onUpdatesEnabled() onUpdateDisabled() onConfirmationReceived()
198  */
200 
201 public:
202  /**
203  * Assign the event handler implementation that will be used by the
204  * module to signal events back to the application.
205  *
206  * @param handler Application implementation of an EventHandler.
207  */
208  void setEventHandler(EventHandler *handler);
209 
210  /**
211  * Shut down the GattServer instance.
212  *
213  * This function notifies all event handlers listening for shutdown events
214  * that the GattServer is about to be shut down; then it clears all
215  * GattServer state.
216  *
217  * @note This function is meant to be overridden in the platform-specific
218  * subclass. Overides must call the parent function before any cleanup.
219  *
220  * @return BLE_ERROR_NONE on success.
221  */
222  ble_error_t reset();
223 
224  /**
225  * Add a service declaration to the local attribute server table.
226  *
227  * This functions inserts a service declaration in the attribute table
228  * followed by the characteristic declarations (including characteristic
229  * descriptors) present in @p service.
230  *
231  * The process assigns a unique attribute handle to all the elements added
232  * into the attribute table. This handle is an ID that must be used for
233  * subsequent interractions with the elements.
234  *
235  * @note There is no mirror function that removes a single service.
236  * Application code can remove all the registered services by calling
237  * reset().
238  *
239  * @attention Service, characteristics and descriptors objects registered
240  * within the GattServer must remain reachable until reset() is called.
241  *
242  * @param[in] service The service to be added; attribute handle of services,
243  * characteristic and characteristic descriptors are updated by the
244  * process.
245  *
246  * @return BLE_ERROR_NONE if the service was successfully added.
247  */
248  ble_error_t addService(GattService &service);
249 
250  /**
251  * Read the value of an attribute present in the local GATT server.
252  *
253  * @param[in] attributeHandle Handle of the attribute to read.
254  * @param[out] buffer A buffer to hold the value being read.
255  * @param[in,out] lengthP Length of the buffer being supplied. If the
256  * attribute value is longer than the size of the supplied buffer, this
257  * variable holds upon return the total attribute value length (excluding
258  * offset). The application may use this information to allocate a suitable
259  * buffer size.
260  *
261  * @return BLE_ERROR_NONE if a value was read successfully into the buffer.
262  *
263  * @attention read(ble::connection_handle_t, GattAttribute::Handle_t, uint8_t *, uint16_t *)
264  * must be used to read Client Characteristic Configuration Descriptor (CCCD)
265  * because the value of this type of attribute depends on the connection.
266  */
267  ble_error_t read(
268  GattAttribute::Handle_t attributeHandle,
269  uint8_t buffer[],
270  uint16_t *lengthP
271  );
272 
273  /**
274  * Read the value of an attribute present in the local GATT server.
275  *
276  * The connection handle allows application code to read the value of a
277  * Client Characteristic Configuration Descriptor for a given connection.
278  *
279  * @param[in] connectionHandle Connection handle.
280  * @param[in] attributeHandle Attribute handle for the value attribute of
281  * the characteristic.
282  * @param[out] buffer A buffer to hold the value being read.
283  * @param[in,out] lengthP Length of the buffer being supplied. If the
284  * attribute value is longer than the size of the supplied buffer, this
285  * variable holds upon return the total attribute value length (excluding
286  * offset). The application may use this information to allocate a suitable
287  * buffer size.
288  *
289  * @return BLE_ERROR_NONE if a value was read successfully into the buffer.
290  */
291  ble_error_t read(
292  ble::connection_handle_t connectionHandle,
293  GattAttribute::Handle_t attributeHandle,
294  uint8_t *buffer,
295  uint16_t *lengthP
296  );
297 
298  /**
299  * Update the value of an attribute present in the local GATT server.
300  *
301  * @param[in] attributeHandle Handle of the attribute to write.
302  * @param[in] value A pointer to a buffer holding the new value.
303  * @param[in] size Size in bytes of the new value (in bytes).
304  * @param[in] localOnly If this flag is false and the attribute handle
305  * written is a characteristic value, then the server sends an update
306  * containing the new value to all clients that have subscribed to the
307  * characteristic's notifications or indications. Otherwise, the update does
308  * not generate a single server initiated event.
309  *
310  * @return BLE_ERROR_NONE if the attribute value has been successfully
311  * updated.
312  */
313  ble_error_t write(
314  GattAttribute::Handle_t attributeHandle,
315  const uint8_t *value,
316  uint16_t size,
317  bool localOnly = false
318  );
319 
320  /**
321  * Update the value of an attribute present in the local GATT server.
322  *
323  * The connection handle parameter allows application code to direct
324  * notification or indication resulting from the update to a specific client.
325  *
326  * @param[in] connectionHandle Connection handle.
327  * @param[in] attributeHandle Handle for the value attribute of the
328  * characteristic.
329  * @param[in] value A pointer to a buffer holding the new value.
330  * @param[in] size Size of the new value (in bytes).
331  * @param[in] localOnly If this flag is false and the attribute handle
332  * written is a characteristic value, then the server sends an update
333  * containing the new value to the client identified by the parameter
334  * @p connectionHandle if it is subscribed to the characteristic's
335  * notifications or indications. Otherwise, the update does not generate a
336  * single server initiated event.
337  *
338  * @return BLE_ERROR_NONE if the attribute value has been successfully
339  * updated.
340  */
341  ble_error_t write(
342  ble::connection_handle_t connectionHandle,
343  GattAttribute::Handle_t attributeHandle,
344  const uint8_t *value,
345  uint16_t size,
346  bool localOnly = false
347  );
348 
349  /**
350  * Determine if one of the connected clients has subscribed to notifications
351  * or indications of the characteristic in input.
352  *
353  * @param[in] characteristic The characteristic.
354  * @param[out] enabledP Upon return, *enabledP is true if updates are
355  * enabled for a connected client; otherwise, *enabledP is false.
356  *
357  * @return BLE_ERROR_NONE if the connection and handle are found. False
358  * otherwise.
359  */
360  ble_error_t areUpdatesEnabled(
361  const GattCharacteristic &characteristic,
362  bool *enabledP
363  );
364 
365  /**
366  * Determine if an identified client has subscribed to notifications or
367  * indications of a given characteristic.
368  *
369  * @param[in] connectionHandle The connection handle.
370  * @param[in] characteristic The characteristic.
371  * @param[out] enabledP Upon return, *enabledP is true if the client
372  * identified by @p connectionHandle has subscribed to notifications or
373  * indications of @p characteristic; otherwise, *enabledP is false.
374  *
375  * @return BLE_ERROR_NONE if the connection and handle are found. False
376  * otherwise.
377  */
378  ble_error_t areUpdatesEnabled(
379  ble::connection_handle_t connectionHandle,
380  const GattCharacteristic &characteristic,
381  bool *enabledP
382  );
383 
384  /**
385  * Indicate if the underlying stack emit events when an attribute is read by
386  * a client.
387  *
388  * @attention This function should be overridden to return true if
389  * applicable.
390  *
391  * @return true if onDataRead is supported; false otherwise.
392  */
393  bool isOnDataReadAvailable() const;
394 
395  /**
396  * Add an event handler that monitors emission of characteristic value
397  * updates.
398  *
399  * @param[in] callback Event handler being registered.
400  *
401  * @note It is possible to chain together multiple onDataSent callbacks
402  * (potentially from different modules of an application).
403  */
404  void onDataSent(const DataSentCallback_t &callback);
405 
406  /**
407  * Add an event handler that monitors emission of characteristic value
408  * updates.
409  *
410  * @param[in] objPtr Pointer to the instance that is used to invoke the
411  * event handler.
412  * @param[in] memberPtr Event handler being registered. It is a member
413  * function.
414  */
415  template <typename T>
416  void onDataSent(T *objPtr, void (T::*memberPtr)(unsigned count))
417  {
418  onDataSent({objPtr, memberPtr});
419  }
420 
421  /**
422  * Access the callchain of data sent event handlers.
423  *
424  * @return A reference to the DATA_SENT event callback chain.
425  */
426  DataSentCallbackChain_t &onDataSent();
427 
428  /**
429  * Set an event handler that is called after
430  * a connected peer has written an attribute.
431  *
432  * @param[in] callback The event handler being registered.
433  *
434  * @attention It is possible to set multiple event handlers. Registered
435  * handlers may be removed with onDataWritten().detach(callback).
436  */
437  void onDataWritten(const DataWrittenCallback_t &callback);
438 
439  /**
440  * Set an event handler that is called after
441  * a connected peer has written an attribute.
442  *
443  * @param[in] objPtr Pointer to the instance that is used to invoke the
444  * event handler (@p memberPtr).
445  * @param[in] memberPtr Event handler being registered. It is a member
446  * function.
447  */
448  template <typename T>
450  T *objPtr,
451  void (T::*memberPtr)(const GattWriteCallbackParams *context)
452  )
453  {
454  onDataWritten({objPtr, memberPtr});
455  }
456 
457  /**
458  * Access the callchain of data written event handlers.
459  *
460  * @return A reference to the data written event callbacks chain.
461  *
462  * @note It is possible to register callbacks using
463  * onDataWritten().add(callback).
464  *
465  * @note It is possible to unregister callbacks using
466  * onDataWritten().detach(callback).
467  */
468  DataWrittenCallbackChain_t &onDataWritten();
469 
470  /**
471  * Set an event handler that monitors attribute reads from connected clients.
472  *
473  * @param[in] callback Event handler being registered.
474  *
475  * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available;
476  * else BLE_ERROR_NONE.
477  *
478  * @note This functionality may not be available on all underlying stacks.
479  * Application code may work around that limitation by monitoring read
480  * requests instead of read events.
481  *
482  * @see GattCharacteristic::setReadAuthorizationCallback()
483  * @see isOnDataReadAvailable().
484  *
485  * @attention It is possible to set multiple event handlers. Registered
486  * handlers may be removed with onDataRead().detach(callback).
487  */
488  ble_error_t onDataRead(const DataReadCallback_t &callback);
489 
490  /**
491  * Set an event handler that monitors attribute reads from connected clients.
492  *
493  * @param[in] objPtr Pointer to the instance that is used to invoke the
494  * event handler (@p memberPtr).
495  * @param[in] memberPtr Event handler being registered. It is a member
496  * function.
497  */
498  template <typename T>
500  T *objPtr,
501  void (T::*memberPtr)(const GattReadCallbackParams *context)
502  )
503  {
504  return onDataRead({objPtr, memberPtr});
505  }
506 
507  /**
508  * Access the callchain of data read event handlers.
509  *
510  * @return A reference to the data read event callbacks chain.
511  *
512  * @note It is possible to register callbacks using
513  * onDataRead().add(callback).
514  *
515  * @note It is possible to unregister callbacks using
516  * onDataRead().detach(callback).
517  */
518  DataReadCallbackChain_t &onDataRead();
519 
520  /**
521  * Set an event handler that monitors shutdown or reset of the GattServer.
522  *
523  * The event handler is invoked when the GattServer instance is about
524  * to be shut down. This can result in a call to reset() or BLE::reset().
525  *
526  * @param[in] callback Event handler being registered.
527  *
528  * @note It is possible to set up multiple shutdown event handlers.
529  *
530  * @note It is possible to unregister a callback using
531  * onShutdown().detach(callback)
532  */
533  void onShutdown(const GattServerShutdownCallback_t &callback);
534 
535  /**
536  * Set an event handler that monitors shutdown or reset of the GattServer.
537  *
538  * The event handler is invoked when the GattServer instance is about
539  * to be shut down. This can result of a call to reset() or BLE::reset().
540  *
541  * @param[in] objPtr Pointer to the instance that is used to invoke the
542  * event handler (@p memberPtr).
543  * @param[in] memberPtr Event handler being registered. It is a member
544  * function.
545  */
546  template <typename T>
547  void onShutdown(T *objPtr, void (T::*memberPtr)(const GattServer *))
548  {
549  onShutdown({objPtr, memberPtr});
550  }
551 
552  /**
553  * Access the callchain of shutdown event handlers.
554  *
555  * @return A reference to the shutdown event callbacks chain.
556  *
557  * @note It is possible to register callbacks using
558  * onShutdown().add(callback).
559  *
560  * @note It is possible to unregister callbacks using
561  * onShutdown().detach(callback).
562  */
563  GattServerShutdownCallbackChain_t& onShutdown();
564 
565  /**
566  * Set up an event handler that monitors subscription to characteristic
567  * updates.
568  *
569  * @param[in] callback Event handler being registered.
570  */
571  void onUpdatesEnabled(EventCallback_t callback);
572 
573  /**
574  * Set up an event handler that monitors unsubscription from characteristic
575  * updates.
576  *
577  * @param[in] callback Event handler being registered.
578  */
579  void onUpdatesDisabled(EventCallback_t callback);
580 
581  /**
582  * Set up an event handler that monitors notification acknowledgment.
583  *
584  * The event handler is called when a client sends a confirmation that it has
585  * correctly received a notification from the server.
586  *
587  * @param[in] callback Event handler being registered.
588  */
589  void onConfirmationReceived(EventCallback_t callback);
590 
591 #if !defined(DOXYGEN_ONLY)
592  GattServer(impl::GattServer* impl) : impl(impl) {}
593  GattServer(const GattServer&) = delete;
594  GattServer& operator=(const GattServer&) = delete;
595 #endif // !defined(DOXYGEN_ONLY)
596 
597 private:
598  impl::GattServer *impl;
599 };
600 
601 /**
602  * @}
603  * @}
604  * @}
605  */
606 
607 } // ble
608 
609 /** @deprecated Use the namespaced ble::GattServer instead of the global GattServer. */
610 using ble::GattServer;
611 
612 #endif /* ifndef MBED_GATT_SERVER_H__ */
FunctionPointerWithContext< unsigned > DataSentCallback_t
Event handler invoked when the server has sent data to a client.
Definition: GattServer.h:134
Function like object adapter over freestanding and member functions.
CallChainOfFunctionPointersWithContext< unsigned > DataSentCallbackChain_t
Callchain of DataSentCallback_t objects.
Definition: GattServer.h:142
void onDataSent(T *objPtr, void(T::*memberPtr)(unsigned count))
Add an event handler that monitors emission of characteristic value updates.
Definition: GattServer.h:416
Construct and operates a GATT server.
Definition: GattServer.h:100
uintptr_t connection_handle_t
Opaque reference to a connection.
FunctionPointerWithContext< GattAttribute::Handle_t > EventCallback_t
Event handler that handles subscription to characteristic updates, unsubscription from characteristic...
Definition: GattServer.h:199
CallChainOfFunctionPointersWithContext< const GattServer * > GattServerShutdownCallbackChain_t
Callchain of GattServerShutdownCallback_t.
Definition: GattServer.h:191
Callback< R(ArgTs...)> callback(R(*func)(ArgTs...)=nullptr) noexcept
Create a callback class with type inferred from the arguments.
Definition: Callback.h:678
CallChainOfFunctionPointersWithContext< const GattReadCallbackParams * > DataReadCallbackChain_t
Callchain of DataReadCallback_t.
Definition: GattServer.h:175
ble::attribute_handle_t Handle_t
Representation of an attribute handle.
ble_error_t onDataRead(T *objPtr, void(T::*memberPtr)(const GattReadCallbackParams *context))
Set an event handler that monitors attribute reads from connected clients.
Definition: GattServer.h:499
Definition of the general handler of GattServer related events.
Definition: GattServer.h:105
GATT Write event definition.
GATT Read event definition.
void onShutdown(T *objPtr, void(T::*memberPtr)(const GattServer *))
Set an event handler that monitors shutdown or reset of the GattServer.
Definition: GattServer.h:547
Representation of a GattServer characteristic.
virtual void onAttMtuChange(ble::connection_handle_t connectionHandle, uint16_t attMtuSize)
Function invoked when the connections changes the ATT_MTU which controls the maximum size of an attri...
Definition: GattServer.h:114
Function like object hosting a list of FunctionPointerWithContext.
void onDataWritten(T *objPtr, void(T::*memberPtr)(const GattWriteCallbackParams *context))
Set an event handler that is called after a connected peer has written an attribute.
Definition: GattServer.h:449
FunctionPointerWithContext< const GattReadCallbackParams * > DataReadCallback_t
Event handler invoked when the client has read an attribute of the server.
Definition: GattServer.h:167
Representation of a GattServer service.
FunctionPointerWithContext< const GattWriteCallbackParams * > DataWrittenCallback_t
Event handler invoked when the client has written an attribute of the server.
Definition: GattServer.h:151
Entry namespace for all BLE API definitions.
CallChainOfFunctionPointersWithContext< const GattWriteCallbackParams * > DataWrittenCallbackChain_t
Callchain of DataWrittenCallback_t objects.
Definition: GattServer.h:159
FunctionPointerWithContext< const GattServer * > GattServerShutdownCallback_t
Event handler invoked when the GattServer is reset.
Definition: GattServer.h:183
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.