xref: /btstack/doc/manual/docs-template/profiles.md (revision cf7250aa3d6090314187d303f46421dd69a5eef4)
1#
2
3In the following, we explain how the various Bluetooth profiles are used
4in BTstack.
5
6## A2DP - Advanced Audio Distribution
7
8The A2DP profile defines how to stream audio over a Bluetooth connection from one device, such as a mobile phone, to another device such as a headset.  A device that acts as source of audio stream implements the A2DP Source role. Similarly, a device that receives an audio stream implements the A2DP Sink role. As such, the A2DP service allows uni-directional transfer of an audio stream, from single channel mono, up to two channel stereo. Our implementation includes mandatory support for the low-complexity SBC codec. Signaling for optional codes (FDK AAC, LDAC, APTX) is supported as well, by you need to provide your own codec library.
9
10
11## AVRCP - Audio/Video Remote Control Profile
12
13The AVRCP profile defines how audio playback on a remote device (e.g. a music app on a smartphone) can be controlled as well as how to state changes such as volume, information on currently played media, battery, etc. can be received from a remote device (e.g. a speaker). Usually, each device implements two roles:
14- The Controller role allows to query information on currently played media, such are title, artist and album, as well as to control the playback, i.e. to play, stop, repeat, etc.
15- The Target role responds to commands, e.g. playback control, and queries, e.g. playback status, media info, from the Controller currently played media.
16
17
18## GAP - Generic Access Profile: Classic
19
20
21The GAP profile defines how devices find each other and establish a
22secure connection for other profiles. As mentioned before, the GAP
23functionality is split between and . Please check both.
24
25### Become discoverable
26
27A remote unconnected Bluetooth device must be set as “discoverable” in
28order to be seen by a device performing the inquiry scan. To become
29discoverable, an application can call *gap_discoverable_control* with
30input parameter 1. If you want to provide a helpful name for your
31device, the application can set its local name by calling
32*gap_set_local_name*. To save energy, you may set the device as
33undiscoverable again, once a connection is established. See Listing
34[below](#lst:Discoverable) for an example.
35
36~~~~ {#lst:Discoverable .c caption="{Setting discoverable mode.}"}
37    int main(void){
38        ...
39        // make discoverable
40        gap_discoverable_control(1);
41        btstack_run_loop_execute();
42        return 0;
43    }
44    void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){
45         ...
46         switch(state){
47              case W4_CHANNEL_COMPLETE:
48                  // if connection is successful, make device undiscoverable
49                  gap_discoverable_control(0);
50              ...
51         }
52     }
53~~~~
54
55### Discover remote devices {#sec:GAPdiscoverRemoteDevices}
56
57To scan for remote devices, the *hci_inquiry* command is used. Found
58remote devices are reported as a part of:
59
60- HCI_EVENT_INQUIRY_RESULT,
61
62- HCI_EVENT-_INQUIRY_RESULT_WITH_RSSI, or
63
64- HCI_EVENT_EXTENDED_INQUIRY_RESPONSE events.
65
66Each response contains at least the Bluetooth address, the class of device, the page scan
67repetition mode, and the clock offset of found device. The latter events
68add information about the received signal strength or provide the
69Extended Inquiry Result (EIR). A code snippet is shown in Listing
70[below](#lst:DiscoverDevices).
71
72~~~~ {#lst:DiscoverDevices .c caption="{Discover remote devices.}"}
73    void print_inquiry_results(uint8_t *packet){
74        int event = packet[0];
75        int numResponses = hci_event_inquiry_result_get_num_responses(packet);
76        uint16_t classOfDevice, clockOffset;
77        uint8_t  rssi, pageScanRepetitionMode;
78        for (i=0; i<numResponses; i++){
79            bt_flip_addr(addr, &packet[3+i*6]);
80            pageScanRepetitionMode = packet [3 + numResponses*6 + i];
81            if (event == HCI_EVENT_INQUIRY_RESULT){
82                classOfDevice = little_endian_read_24(packet, 3 + numResponses*(6+1+1+1) + i*3);
83                clockOffset =   little_endian_read_16(packet, 3 + numResponses*(6+1+1+1+3) + i*2) & 0x7fff;
84                rssi  = 0;
85            } else {
86                classOfDevice = little_endian_read_24(packet, 3 + numResponses*(6+1+1)     + i*3);
87                clockOffset =   little_endian_read_16(packet, 3 + numResponses*(6+1+1+3)   + i*2) & 0x7fff;
88                rssi  = packet [3 + numResponses*(6+1+1+3+2) + i*1];
89            }
90            printf("Device found: %s with COD: 0x%06x, pageScan %u, clock offset 0x%04x, rssi 0x%02x\n", bd_addr_to_str(addr), classOfDevice, pageScanRepetitionMode, clockOffset, rssi);
91        }
92    }
93
94    void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){
95        ...
96        switch (event) {
97             case HCI_STATE_WORKING:
98                hci_send_cmd(&hci_write_inquiry_mode, 0x01); // with RSSI
99                break;
100            case HCI_EVENT_COMMAND_COMPLETE:
101                if (COMMAND_COMPLETE_EVENT(packet, hci_write_inquiry_mode) ) {
102                    start_scan();
103                }
104            case HCI_EVENT_COMMAND_STATUS:
105                if (COMMAND_STATUS_EVENT(packet, hci_write_inquiry_mode) ) {
106                    printf("Ignoring error (0x%x) from hci_write_inquiry_mode.\n", packet[2]);
107                    hci_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0);
108                }
109                break;
110            case HCI_EVENT_INQUIRY_RESULT:
111            case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:
112                print_inquiry_results(packet);
113                break;
114           ...
115        }
116    }
117~~~~
118
119By default, neither RSSI values nor EIR are reported. If the Bluetooth
120device implements Bluetooth Specification 2.1 or higher, the
121*hci_write_inquiry_mode* command enables reporting of this advanced
122features (0 for standard results, 1 for RSSI, 2 for RSSI and EIR).
123
124A complete GAP inquiry example is provided [here](../examples/examples/#sec:gapinquiryExample).
125
126### Pairing of Devices
127
128By default, Bluetooth communication is not authenticated, and any device
129can talk to any other device. A Bluetooth device (for example, cellular
130phone) may choose to require authentication to provide a particular
131service (for example, a Dial-Up service). The process of establishing
132authentication is called pairing. Bluetooth provides two mechanism for
133this.
134
135On Bluetooth devices that conform to the Bluetooth v2.0 or older
136specification, a PIN code (up to 16 bytes ASCII) has to be entered on
137both sides. This isn’t optimal for embedded systems that do not have
138full I/O capabilities. To support pairing with older devices using a
139PIN, see Listing [below](#lst:PinCodeRequest).
140
141~~~~ {#lst:PinCodeRequest .c caption="{PIN code request.}"}
142    void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){
143        ...
144        switch (event) {
145            case HCI_EVENT_PIN_CODE_REQUEST:
146                // inform about pin code request
147                printf("Pin code request - using '0000'\n\r");
148                hci_event_pin_code_request_get_bd_addr(packet, bd_addr);
149
150                // baseband address, pin length, PIN: c-string
151                hci_send_cmd(&hci_pin_code_request_reply, &bd_addr, 4, "0000");
152                break;
153           ...
154        }
155    }
156~~~~
157
158The Bluetooth v2.1 specification introduces Secure Simple Pairing (SSP),
159which is a better approach as it both improves security and is better
160adapted to embedded systems. With SSP, the devices first exchange their
161IO Capabilities and then settle on one of several ways to verify that
162the pairing is legitimate. If the Bluetooth device supports SSP, BTstack
163enables it by default and even automatically accepts SSP pairing
164requests. Depending on the product in which BTstack is used, this may
165not be desired and should be replaced with code to interact with the
166user.
167
168Regardless of the authentication mechanism (PIN/SSP), on success, both
169devices will generate a link key. The link key can be stored either in
170the Bluetooth module itself or in a persistent storage, see
171[here](../porting/#sec:persistentStoragePorting). The next time the device connects and
172requests an authenticated connection, both devices can use the
173previously generated link key. Please note that the pairing must be
174repeated if the link key is lost by one device.
175
176### Dedicated Bonding
177
178Aside from the regular bonding, Bluetooth also provides the concept of
179“dedicated bonding”, where a connection is established for the sole
180purpose of bonding the device. After the bonding process is over, the
181connection will be automatically terminated. BTstack supports dedicated
182bonding via the *gap_dedicated_bonding* function.
183
184## SPP - Serial Port Profile
185
186The SPP profile defines how to set up virtual serial ports and connect
187two Bluetooth enabled devices. Please keep in mind that a serial port does not
188preserve packet boundaries if you try to send data as packets and read about
189[RFCOMM packet boundaries](../protocols/#sec:noRfcommPacketBoundaries).
190
191### Accessing an SPP Server on a remote device
192
193To access a remote SPP server, you first need to query the remote device
194for its SPP services. Section [on querying remote SDP service](#sec:querySDPProtocols)
195shows how to query for all RFCOMM channels. For SPP, you can do the same
196but use the SPP UUID 0x1101 for the query. After you have identified the
197correct RFCOMM channel, you can create an RFCOMM connection as shown
198[here](../protocols/#sec:rfcommClientProtocols).
199
200### Providing an SPP Server
201
202To provide an SPP Server, you need to provide an RFCOMM service with a
203specific RFCOMM channel number as explained in section on
204[RFCOMM service](../protocols/#sec:rfcommServiceProtocols). Then, you need to create
205an SDP record for it and publish it with the SDP server by calling
206*sdp_register_service*. BTstack provides the
207*spp_create_sdp_record* function in that requires an empty buffer of
208approximately 200 bytes, the service channel number, and a service name.
209Have a look at the [SPP Counter example](../examples/examples/#sec:sppcounterExample).
210
211
212## PAN - Personal Area Networking Profile {#sec:panProfiles}
213
214
215The PAN profile uses BNEP to provide on-demand networking capabilities
216between Bluetooth devices. The PAN profile defines the following roles:
217
218-   PAN User (PANU)
219
220-   Network Access Point (NAP)
221
222-   Group Ad-hoc Network (GN)
223
224PANU is a Bluetooth device that communicates as a client with GN, or
225NAP, or with another PANU Bluetooth device, through a point-to-point
226connection. Either the PANU or the other Bluetooth device may terminate
227the connection at anytime.
228
229NAP is a Bluetooth device that provides the service of routing network
230packets between PANU by using BNEP and the IP routing mechanism. A NAP
231can also act as a bridge between Bluetooth networks and other network
232technologies by using the Ethernet packets.
233
234The GN role enables two or more PANUs to interact with each other
235through a wireless network without using additional networking hardware.
236The devices are connected in a piconet where the GN acts as a master and
237communicates either point-to-point or a point-to-multipoint with a
238maximum of seven PANU slaves by using BNEP.
239
240Currently, BTstack supports only PANU.
241
242### Accessing a remote PANU service
243
244To access a remote PANU service, you first need perform an SDP query to
245get the L2CAP PSM for the requested PANU UUID. With these two pieces of
246information, you can connect BNEP to the remote PANU service with the
247*bnep_connect* function. The Section on [PANU Demo example](../examples/examples/#sec:panudemoExample)
248shows how this is accomplished.
249
250### Providing a PANU service
251
252To provide a PANU service, you need to provide a BNEP service with the
253service UUID, e.g. the PANU UUID, and a maximal ethernet frame size,
254as explained in Section [on BNEP service](../protocols/#sec:bnepServiceProtocols). Then, you need to
255create an SDP record for it and publish it with the SDP server by
256calling *sdp_register_service*. BTstack provides the
257*pan_create_panu_sdp_record* function in *src/pan.c* that requires an
258empty buffer of approximately 200 bytes, a description, and a security
259description.
260
261## HSP - Headset Profile
262
263The HSP profile defines how a Bluetooth-enabled headset should communicate
264with another Bluetooth enabled device. It relies on SCO for audio encoded
265in 64 kbit/s CVSD and a subset of AT commands from GSM 07.07 for
266minimal controls including the ability to ring, answer a call, hang up and adjust the volume.
267
268The HSP defines two roles:
269
270 - Audio Gateway (AG) - a device that acts as the gateway of the audio, typically a mobile phone or PC.
271
272 - Headset (HS) - a device that acts as the AG's remote audio input and output control.
273
274There are following restrictions:
275- The CVSD is used for audio transmission.
276
277- Between headset and audio gateway, only one audio connection at a time is supported.
278
279- The profile offers only basic interoperability – for example, handling of multiple calls at the audio gateway is not included.
280
281- The only assumption on the headset’s user interface is the possibility to detect a user initiated action (e.g. pressing a button).
282
283%TODO: audio paths
284
285
286## HFP - Hands-Free Profile  {#sec:hfp}
287
288The HFP profile defines how a Bluetooth-enabled device, e.g. a car kit or a headset, can be used to place and receive calls via a audio gateway device, typically a mobile phone.
289It relies on SCO for audio encoded in 64 kbit/s CVSD and a bigger subset of AT commands from GSM 07.07 then HSP for
290controls including the ability to ring, to place and receive calls, join a conference call, to answer, hold or reject a call, and adjust the volume.
291
292The HFP defines two roles:
293
294- Audio Gateway (AG) – a device that acts as the gateway of the audio,, typically a mobile phone.
295
296- Hands-Free Unit (HF) – a device that acts as the AG's remote audio input and output control.
297
298### Supported Features {#sec:hfpSupportedFeatures}
299
300The supported features define the HFP capabilities of the device. The enumeration unfortunately differs between HF and AG sides.
301
302The AG supported features are set by combining the flags that start with HFP_AGSF_xx and calling hfp_ag_init_supported_features, followed by creating SDP record for the service using the same feature set.
303
304Similarly, the HF supported features are a combination of HFP_HFSF_xx flags and are configured by calling hfp_hf_init_supported_features, as well as creating an SDP record.
305
306| Define for AG Supported Feature         |  Description  |
307| --------------------------------------- |  ----------------------------  |
308| HFP_AGSF_THREE_WAY_CALLING              |  Three-way calling             |
309| HFP_AGSF_EC_NR_FUNCTION                 |  Echo Canceling and/or Noise Reduction function |
310| HFP_AGSF_VOICE_RECOGNITION_FUNCTION     |  Voice recognition function |
311| HFP_AGSF_IN_BAND_RING_TONE              |  In-band ring tone capability |
312| HFP_AGSF_ATTACH_A_NUMBER_TO_A_VOICE_TAG |  Attach a number to a voice tag |
313| HFP_AGSF_ABILITY_TO_REJECT_A_CALL       |  Ability to reject a call |
314| HFP_AGSF_ENHANCED_CALL_STATUS           |  Enhanced call status |
315| HFP_AGSF_ENHANCED_CALL_CONTROL          |  Enhanced call control |
316| HFP_AGSF_EXTENDED_ERROR_RESULT_CODES    |  Extended Error Result Codes |
317| HFP_AGSF_CODEC_NEGOTIATION              |  Codec negotiation |
318| HFP_AGSF_HF_INDICATORS                  |  HF Indicators |
319| HFP_AGSF_ESCO_S4                        |  eSCO S4 (and T2) Settings Supported |
320| HFP_AGSF_ENHANCED_VOICE_RECOGNITION_STATUS |  Enhanced voice recognition status |
321| HFP_AGSF_VOICE_RECOGNITION_TEXT         |  Voice recognition text |
322
323
324| Define for HF Supported Feature         |  Description  |
325| --------------------------------------- |  ----------------------------  |
326| HFP_HFSF_THREE_WAY_CALLING              |  Three-way calling  |
327| HFP_HFSF_EC_NR_FUNCTION                 |  Echo Canceling and/or Noise Reduction function |
328| HFP_HFSF_CLI_PRESENTATION_CAPABILITY    |  CLI presentation capability |
329| HFP_HFSF_VOICE_RECOGNITION_FUNCTION     |  Voice recognition function |
330| HFP_HFSF_REMOTE_VOLUME_CONTROL          |  Remote volume control |
331| HFP_HFSF_ATTACH_A_NUMBER_TO_A_VOICE_TAG |  Attach a number to a voice tag |
332| HFP_HFSF_ENHANCED_CALL_STATUS           |  Enhanced call status |
333| HFP_HFSF_ENHANCED_CALL_CONTROL          |  Enhanced call control |
334| HFP_HFSF_CODEC_NEGOTIATION              |  Codec negotiation |
335| HFP_HFSF_HF_INDICATORS                  |  HF Indicators |
336| HFP_HFSF_ESCO_S4                        |  eSCO S4 (and T2) Settings Supported |
337| HFP_HFSF_ENHANCED_VOICE_RECOGNITION_STATUS |  Enhanced voice recognition status |
338| HFP_HFSF_VOICE_RECOGNITION_TEXT         |  Voice recognition text |
339
340
341### Audio Voice Recognition Activation {#sec:hfpAVRActivation}
342
343Audio voice recognition (AVR) requires that HF and AG have the following  features enabled:
344
345- HF: HFP_HFSF_VOICE_RECOGNITION_FUNCTION and
346
347- AG: HFP_AGSF_VOICE_RECOGNITION_FUNCTION.
348
349It can be activated or deactivated on both sides by calling:
350
351    // AG
352    uint8_t hfp_ag_activate_voice_recognition(hci_con_handle_t acl_handle);
353    uint8_t hfp_ag_deactivate_voice_recognition(hci_con_handle_t acl_handle);
354
355    // HF
356    uint8_t hfp_hf_activate_voice_recognition(hci_con_handle_t acl_handle);
357    uint8_t hfp_hf_deactivate_voice_recognition(hci_con_handle_t acl_handle);
358
359On activation change, the HFP_SUBEVENT_VOICE_RECOGNITION_(DE)ACTIVATED event will be emitted with status field set to ERROR_CODE_SUCCESS on success.
360
361Voice recognition will stay active until either the deactivation command is called, or until the current Service Level Connection between the AG and the HF is dropped for any reason.
362
363| Use cases                                              |  Expected behavior  |
364|--------------------------------------------------------|---------------------|
365| No previous audio connection, AVR activated then deactivated | Audio connection will be opened by AG upon AVR activation, and upon AVR deactivation closed|
366| AVR activated and deactivated during existing audio connection | Audio remains active upon AVR deactivation |
367| Call to close audio connection during active AVR session       | The audio connection shut down will be refused |
368| AVR activated, but audio connection failed to be established   | AVR will stay activated |
369
370Beyond the audio routing and voice recognition activation capabilities, the rest of the voice recognition functionality is implementation dependent - the stack only provides the signaling for this.
371
372### Enhanced Audio Voice Recognition {#sec:hfpeAVRActivation}
373
374Similarly to AVR, Enhanced Audio voice recognition (eAVR) requires that HF and AG have the following features enabled:
375
376- HF: HFP_HFSF_ENHANCED_VOICE_RECOGNITION_STATUS and
377
378- AG: HFP_AGSF_ENHANCED_VOICE_RECOGNITION_STATUS.
379
380In addition, to allow textual representation of audio that is parsed by eAVR (note that parsing is not part of Bluetooth specification), both devices must enable:
381
382- HF: HFP_HFSF_VOICE_RECOGNITION_TEXT and
383
384- AG: HFP_AGSF_VOICE_RECOGNITION_TEXT.
385
386eAVR implements the same use cases as AVR (see previous section) and it can be activated or deactivated using the same API as for AVR, see above.
387
388When eAVR and audio channel are established there are several additional commands that can be sent:
389
390| HFP Role | eVRA API | Description |
391-----------|----------|-------------|
392|HF | hfp_hf_enhanced_voice_recognition_report_ready_for_audio| Ready to accept audio input. |
393|AG | hfp_ag_enhanced_voice_recognition_report_ready_for_audio | Voice recognition engine is ready to accept audio input. |
394|AG | hfp_ag_enhanced_voice_recognition_report_sending_audio | The voice recognition engine will play a sound, e.g. starting sound. |
395|AG | hfp_ag_enhanced_voice_recognition_report_processing_input | Voice recognition engine is processing the audio input. |
396|AG | hfp_ag_enhanced_voice_recognition_send_message | Report textual representation from the voice recognition engine. |
397
398
399## HID - Human-Interface Device Profile
400
401The HID profile allows an HID Host to connect to one or more HID Devices and communicate with them.
402Examples of Bluetooth HID devices are keyboards, mice, joysticks, gamepads, remote controls, and also voltmeters and temperature sensors.
403Typical HID hosts would be a personal computer, tablets, gaming console, industrial machine, or data-recording device.
404
405Please refer to:
406
407- [HID Host API](../appendix/apis/#sec:hidHostAPIAppendix) and [hid_host_demo](../examples/examples/#sec:hidhostdemoExample) for the HID Host role
408
409- [HID Device API](../appendix/apis/#sec:hidDeviceAPIAppendix), [hid_keyboard_demo](../examples/examples/#sec:hidkeyboarddemoExample) and [hid_mouse_demo](../examples/examples/#sec:hidmousedemoExample)  for the HID Device role.
410
411
412## GAP LE - Generic Access Profile for Low Energy
413
414
415As with GAP for Classic, the GAP LE profile defines how to discover and
416how to connect to a Bluetooth Low Energy device. There are several GAP
417roles that a Bluetooth device can take, but the most important ones are
418the Central and the Peripheral role. Peripheral devices are those that
419provide information or can be controlled. Central devices are those that
420consume information or control the peripherals. Before the connection
421can be established, devices are first going through an advertising
422process.
423
424### Private addresses.
425
426To better protect privacy, an LE device can choose to use a private i.e.
427random Bluetooth address. This address changes at a user-specified rate.
428To allow for later reconnection, the central and peripheral devices will
429exchange their Identity Resolving Keys (IRKs) during bonding. The IRK is
430used to verify if a new address belongs to a previously bonded device.
431
432To toggle privacy mode using private addresses, call the
433*gap_random_address_set_mode* function. The update period can be set
434with *gap_random_address_set_update_period*.
435
436After a connection is established, the Security Manager will try to
437resolve the peer Bluetooth address as explained in Section on
438[SMP](../protocols/#sec:smpProtocols).
439
440### Advertising and Discovery
441
442An LE device is discoverable and connectable, only if it periodically
443sends out Advertisements. An advertisement contains up to 31 bytes of
444data. To configure and enable advertisement broadcast, the following GAP
445functions can be used:
446
447-   *gap_advertisements_set_data*
448
449-   *gap_advertisements_set_params*
450
451-   *gap_advertisements_enable*
452
453In addition to the Advertisement data, a device in the peripheral role
454can also provide Scan Response data, which has to be explicitly queried
455by the central device. It can be set with *gap_scan_response_set_data*.
456
457Please have a look at the [SPP and LE
458Counter example](../examples/examples/#sec:sppandlecounterExample).
459
460The scan parameters can be set with
461*gap_set_scan_parameters*. The scan can be started/stopped
462with *gap_start_scan*/*gap_stop_scan*.
463
464Finally, if a suitable device is found, a connection can be initiated by
465calling *gap_connect*. In contrast to Bluetooth classic, there
466is no timeout for an LE connection establishment. To cancel such an
467attempt, *gap_connect_cancel* has be be called.
468
469By default, a Bluetooth device stops sending Advertisements when it gets
470into the Connected state. However, it does not start broadcasting
471advertisements on disconnect again. To re-enable it, please send the
472*hci_le_set_advertise_enable* again .
473
474## GATT Client {#sec:GATTClientProfiles}
475
476The GATT profile uses ATT Attributes to represent a hierarchical
477structure of GATT Services and GATT Characteristics. Each Service has
478one or more Characteristics. Each Characteristic has meta data attached
479like its type or its properties. This hierarchy of Characteristics and
480Services are queried and modified via ATT operations.
481
482GATT defines both a server and a client role. A device can implement one
483or both GATT roles.
484
485The GATT Client is used to discover services, characteristics
486and their descriptors on a peer device. It allows to subscribe for
487notifications or indications that the characteristic on the GATT server
488has changed its value.
489
490To perform GATT queries, it provides a rich interface. Before calling
491queries, the GATT client must be initialized with *gatt_client_init*
492once.
493
494To allow for modular profile implementations, GATT client can be used
495independently by multiple entities.
496
497After an LE connection was created using the GAP LE API, you can query
498for the connection MTU with *gatt_client_get_mtu*.
499
500Multiple GATT queries to the same GATT Server cannot be interleaved.
501Therefore, you can either use a state machine or similar to perform the
502queries in sequence, or you can check if you can perform a GATT query
503on a particular connection right now using
504*gatt_client_is_ready*, and retry later if it is not ready.
505As a result to a GATT query, zero to many
506*GATT_EVENT_X*s are returned before a *GATT_EVENT_QUERY_COMPLETE* event
507completes the query.
508
509For more details on the available GATT queries, please consult
510[GATT Client API](#sec:gattClientAPIAppendix).
511
512### Authentication
513
514By default, the GATT Server is responsible for security and the GATT Client does not enforce any kind of authentication.
515If the GATT Client accesses Characteristic that require encrytion or authentication, the remote GATT Server will return an error,
516which is returned in the *att status* of the *GATT_EVENT_QUERY_COMPLETE*.
517
518You can define *ENABLE_GATT_CLIENT_PAIRING* to instruct the GATT Client to trigger pairing in this case and to repeat the request.
519
520This model allows for an attacker to spoof another device, but don't require authentication for the Characteristics.
521As a first improvement, you can define *ENABLE_LE_PROACTIVE_AUTHENTICATION* in *btstack_config.h*. When defined, the GATT Client will
522request the Security Manager to re-encrypt the connection if there is stored bonding information available.
523If this fails, the  *GATT_EVENT_QUERY_COMPLETE* will return with the att status *ATT_ERROR_BONDING_INFORMATION_MISSING*.
524
525With *ENABLE_LE_PROACTIVE_AUTHENTICATION* defined and in Central role, you need to delete the local bonding information if the remote
526lost its bonding information, e.g. because of a device reset. See *example/sm_pairing_central.c*.
527
528Even with the Proactive Authentication, your device may still connect to an attacker that provides the same advertising data as
529your actual device. If the device that you want to connect requires pairing, you can instruct the GATT Client to automatically
530request an encrypted connection before sending any GATT Client request by calling *gatt_client_set_required_security_level()*.
531If the device provides sufficient IO capabilities, a MITM attack can then be prevented. We call this 'Mandatory Authentication'.
532
533The following diagrams provide a detailed overview about the GATT Client security mechanisms in different configurations:
534
535-  [Reactive Authentication as Central](picts/gatt_client_security_reactive_authentication_central.svg)
536-  [Reactive Authentication as Peripheral](picts/gatt_client_security_reactive_authentication_peripheral.svg)
537-  [Proactive Authentication as Central](picts/gatt_client_security_proactive_authentication_central.svg)
538-  [Proactive Authentication as Peripheral](picts/gatt_client_security_proactive_authentication_peripheral.svg)
539-  [Mandatory Authentication as Central](picts/gatt_client_security_mandatory_authentication_central.svg)
540-  [Mandatory Authentication as Peripheral](picts/gatt_client_security_mandatory_authentication_peripheral.svg)
541
542## GATT Server {#sec:GATTServerProfiles}
543
544The GATT server stores data and accepts GATT client requests, commands
545and confirmations. The GATT server sends responses to requests and when
546configured, sends indication and notifications asynchronously to the
547GATT client.
548
549To save on both code space and memory, BTstack does not provide a GATT
550Server implementation. Instead, a textual description of the GATT
551profile is directly converted into a compact internal ATT Attribute
552database by a GATT profile compiler. The ATT protocol server -
553implemented by and - answers incoming ATT requests based on information
554provided in the compiled database and provides read- and write-callbacks
555for dynamic attributes.
556
557GATT profiles are defined by a simple textual comma separated value
558(.csv) representation. While the description is easy to read and edit,
559it is compact and can be placed in ROM.
560
561The current format is shown in Listing [below](#lst:GATTServerProfile).
562
563~~~~ {#lst:GATTServerProfile .c caption="{GATT profile.}"}
564    // import service_name
565    #import <service_name.gatt>
566
567    PRIMARY_SERVICE, {SERVICE_UUID}
568    CHARACTERISTIC, {ATTRIBUTE_TYPE_UUID}, {PROPERTIES}, {VALUE}
569    CHARACTERISTIC, {ATTRIBUTE_TYPE_UUID}, {PROPERTIES}, {VALUE}
570    ...
571    PRIMARY_SERVICE, {SERVICE_UUID}
572    CHARACTERISTIC, {ATTRIBUTE_TYPE_UUID}, {PROPERTIES}, {VALUE}
573    ...
574~~~~
575
576UUIDs are either 16 bit (1800) or 128 bit
577(00001234-0000-1000-8000-00805F9B34FB).
578
579Value can either be a string (“this is a string”), or, a sequence of hex
580bytes (e.g. 01 02 03).
581
582Properties can be a list of properties combined using '|'
583
584Reads/writes to a Characteristic that is defined with the DYNAMIC flag,
585are forwarded to the application via callback. Otherwise, the
586Characteristics cannot be written and it will return the specified
587constant value.
588
589Adding NOTIFY and/or INDICATE automatically creates an additional Client
590Configuration Characteristic.
591
592Property                | Description
593------------------------|-----------------------------------------------
594READ                    | Characteristic can be read
595WRITE                   | Characteristic can be written using Write Request
596WRITE_WITHOUT_RESPONSE  | Characteristic can be written using Write Command
597NOTIFY                  | Characteristic allows notifications by server
598INDICATE                | Characteristic allows indication by server
599DYNAMIC                 | Read or writes to Characteristic are handled by application
600
601To require encryption or authentication before a Characteristic can be
602accessed, you can add one or more of the following properties:
603
604Property                | Description
605------------------------|-----------------------------------------------
606AUTHENTICATION_REQUIRED | Read and Write operations require Authentication
607READ_ENCRYPTED          | Read operations require Encryption
608READ_AUTHENTICATED      | Read operations require Authentication
609WRITE_ENCRYPTED         | Write operations require Encryption
610WRITE_AUTHENTICATED     | Write operations require Authentication
611ENCRYPTION_KEY_SIZE_X   | Require encryption size >= X, with W in [7..16]
612
613For example, Volume State Characteristic (Voice Control Service) requires:
614- Mandatory Properties: Read, Notify
615- Security Permissions: Encryption Required
616
617In addition, its read is handled by application. We can model this Characteristic as follows:
618
619~~~~
620    CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_VOLUME_STATE, DYNAMIC | READ | NOTIFY | ENCRYPTION_KEY_SIZE_16
621~~~~
622
623To use already implemented GATT Services, you can import it
624using the *#import <service_name.gatt>* command. See [list of provided services](gatt_services.md).
625
626BTstack only provides an ATT Server, while the GATT Server logic is
627mainly provided by the GATT compiler. While GATT identifies
628Characteristics by UUIDs, ATT uses Handles (16 bit values). To allow to
629identify a Characteristic without hard-coding the attribute ID, the GATT
630compiler creates a list of defines in the generated \*.h file.
631
632Similar to other protocols, it might be not possible to send any time.
633To send a Notification, you can call *att_server_request_can_send_now*
634to receive a ATT_EVENT_CAN_SEND_NOW event.
635
636If your application cannot handle an ATT Read Request in the *att_read_callback*
637in some situations, you can enable support for this by adding ENABLE_ATT_DELAYED_RESPONSE
638to *btstack_config.h*. Now, you can store the requested attribute handle and return
639*ATT_READ_RESPONSE_PENDING* instead of the length of the provided data when you don't have the data ready.
640For ATT operations that read more than one attribute, your *att_read_callback*
641might get called multiple times as well. To let you know that all necessary
642attribute handles have been 'requested' by the *att_server*, you'll get a final
643*att_read_callback* with the attribute handle of *ATT_READ_RESPONSE_PENDING*.
644When you've got the data for all requested attributes ready, you can call
645*att_server_response_ready*, which will trigger processing of the current request.
646Please keep in mind that there is only one active ATT operation and that it has a 30 second
647timeout after which the ATT server is considered defunct by the GATT Client.
648
649### Implementing Standard GATT Services {#sec:GATTStandardServices}
650
651Implementation of a standard GATT Service consists of the following 4 steps:
652
653  1. Identify full Service Name
654  2. Use Service Name to fetch XML definition at Bluetooth SIG site and convert into generic .gatt file
655  3. Edit .gatt file to set constant values and exclude unwanted Characteristics
656  4. Implement Service server, e.g., battery_service_server.c
657
658Step 1:
659
660To facilitate the creation of .gatt files for standard profiles defined by the Bluetooth SIG,
661the *tool/convert_gatt_service.py* script can be used. When run without a parameter, it queries the
662Bluetooth SIG website and lists the available Services by their Specification Name, e.g.,
663*org.bluetooth.service.battery_service*.
664
665    $ tool/convert_gatt_service.py
666    Fetching list of services from https://www.bluetooth.com/specifications/gatt/services
667
668    Specification Type                                     | Specification Name            | UUID
669    -------------------------------------------------------+-------------------------------+-----------
670    org.bluetooth.service.alert_notification               | Alert Notification Service    | 0x1811
671    org.bluetooth.service.automation_io                    | Automation IO                 | 0x1815
672    org.bluetooth.service.battery_service                  | Battery Service               | 0x180F
673    ...
674    org.bluetooth.service.weight_scale                     | Weight Scale                  | 0x181D
675
676    To convert a service into a .gatt file template, please call the script again with the requested Specification Type and the output file name
677    Usage: tool/convert_gatt_service.py SPECIFICATION_TYPE [service_name.gatt]
678
679Step 2:
680
681To convert service into .gatt file, call *tool/convert_gatt_service.py with the requested Specification Type and the output file name.
682
683    $ tool/convert_gatt_service.py org.bluetooth.service.battery_service battery_service.gatt
684    Fetching org.bluetooth.service.battery_service from
685    https://www.bluetooth.com/api/gatt/xmlfile?xmlFileName=org.bluetooth.service.battery_service.xml
686
687    Service Battery Service
688    - Characteristic Battery Level - properties ['Read', 'Notify']
689    -- Descriptor Characteristic Presentation Format       - TODO: Please set values
690    -- Descriptor Client Characteristic Configuration
691
692    Service successfully converted into battery_service.gatt
693    Please check for TODOs in the .gatt file
694
695
696Step 3:
697
698In most cases, you will need to customize the .gatt file. Please pay attention to the tool output and have a look
699at the generated .gatt file.
700
701E.g. in the generated .gatt file for the Battery Service
702
703    // Specification Type org.bluetooth.service.battery_service
704    // https://www.bluetooth.com/api/gatt/xmlfile?xmlFileName=org.bluetooth.service.battery_service.xml
705
706    // Battery Service 180F
707    PRIMARY_SERVICE, ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE
708    CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL, DYNAMIC | READ | NOTIFY,
709    // TODO: Characteristic Presentation Format: please set values
710    #TODO CHARACTERISTIC_FORMAT, READ, _format_, _exponent_, _unit_, _name_space_, _description_
711    CLIENT_CHARACTERISTIC_CONFIGURATION, READ | WRITE,
712
713you could delete the line regarding the CHARACTERISTIC_FORMAT, since it's not required if there is a single instance of the service.
714Please compare the .gatt file against the [Adopted Specifications](https://www.bluetooth.com/specifications/adopted-specifications).
715
716Step 4:
717
718As described [above](#sec:GATTServerProfiles) all read/write requests are handled by the application.
719To implement the new services as a reusable module, it's necessary to get access to all read/write requests related to this service.
720
721For this, the ATT DB allows to register read/write callbacks for a specific handle range with *att_server_register_can_send_now_callback()*.
722
723Since the handle range depends on the application's .gatt file, the handle range for Primary and Secondary Services can be queried with *gatt_server_get_get_handle_range_for_service_with_uuid16*.
724
725Similarly, you will need to know the attribute handle for particular Characteristics to handle Characteristic read/writes requests. You can get the attribute value handle for a Characteristics *gatt_server_get_value_handle_for_characteristic_with_uuid16()*.
726
727In addition to the attribute value handle, the handle for the Client Characteristic Configuration is needed to support Indications/Notifications. You can get this attribute handle with *gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16()*
728
729Finally, in order to send Notifications and Indications independently from the main application, *att_server_register_can_send_now_callback* can be used to request a callback when it's possible to send a Notification or Indication.
730
731To see how this works together, please check out the Battery Service Server in *src/ble/battery_service_server.c*.
732
733### GATT Database Hash
734
735When a GATT Client connects to a GATT Server, it cannot know if the GATT Database has changed
736and has to discover the provided GATT Services and Characteristics after each connect.
737
738To speed this up, the Bluetooth
739specification defines a GATT Service Changed Characteristic, with the idea that a GATT Server would notify
740a bonded GATT Client if its database changed. However, this is quite fragile and it is not clear how it can be implemented
741in a robust way.
742
743The Bluetooth Core Spec 5.1 introduced the GATT Database Hash Characteristic, which allows for a simple
744robust mechanism to cache a remote GATT Database. The GATT Database Hash is a 16-byte value that is calculated
745over the list of Services and Characteristics. If there is any change to the database, the hash will change as well.
746
747To support this on the GATT Server, you only need to add a GATT Service with the GATT Database Characteristic to your .gatt file.
748The hash value is then calculated by the GATT compiler.
749
750
751    PRIMARY_SERVICE, GATT_SERVICE
752    CHARACTERISTIC, GATT_DATABASE_HASH, READ,
753
754Note: make sure to install the PyCryptodome python package as the hash is calculated using AES-CMAC,
755e.g. with:
756
757    pip install pycryptodomex
758