xref: /btstack/doc/manual/docs-template/profiles.md (revision e54a3bca5d33ee0e65d314c9513f358064739602)
1503a627eSMilanka Ringwald#
2503a627eSMilanka Ringwald
3503a627eSMilanka RingwaldIn the following, we explain how the various Bluetooth profiles are used
4503a627eSMilanka Ringwaldin BTstack.
5503a627eSMilanka Ringwald
6ba8d4e9bSMilanka Ringwald## A2DP - Advanced Audio Distribution
7ba8d4e9bSMilanka Ringwald
8ba8d4e9bSMilanka RingwaldThe 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.
9ba8d4e9bSMilanka Ringwald
10ba8d4e9bSMilanka Ringwald
11ba8d4e9bSMilanka Ringwald## AVRCP - Audio/Video Remote Control Profile
12ba8d4e9bSMilanka Ringwald
13ba8d4e9bSMilanka RingwaldThe 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:
14ba8d4e9bSMilanka Ringwald- 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.
15ba8d4e9bSMilanka Ringwald- The Target role responds to commands, e.g. playback control, and queries, e.g. playback status, media info, from the Controller currently played media.
16ba8d4e9bSMilanka Ringwald
17ba8d4e9bSMilanka Ringwald
18503a627eSMilanka Ringwald## GAP - Generic Access Profile: Classic
19503a627eSMilanka Ringwald
20503a627eSMilanka Ringwald
21503a627eSMilanka RingwaldThe GAP profile defines how devices find each other and establish a
22503a627eSMilanka Ringwaldsecure connection for other profiles. As mentioned before, the GAP
23*e54a3bcaSMatthias Ringwaldfunctionality is split between and `hci.h` and `gap.h`. Please check both.
24503a627eSMilanka Ringwald
25503a627eSMilanka Ringwald### Become discoverable
26503a627eSMilanka Ringwald
27503a627eSMilanka RingwaldA remote unconnected Bluetooth device must be set as “discoverable” in
28503a627eSMilanka Ringwaldorder to be seen by a device performing the inquiry scan. To become
29503a627eSMilanka Ringwalddiscoverable, an application can call *gap_discoverable_control* with
30503a627eSMilanka Ringwaldinput parameter 1. If you want to provide a helpful name for your
31503a627eSMilanka Ringwalddevice, the application can set its local name by calling
32503a627eSMilanka Ringwald*gap_set_local_name*. To save energy, you may set the device as
33503a627eSMilanka Ringwaldundiscoverable again, once a connection is established. See Listing
34503a627eSMilanka Ringwald[below](#lst:Discoverable) for an example.
35503a627eSMilanka Ringwald
36503a627eSMilanka Ringwald~~~~ {#lst:Discoverable .c caption="{Setting discoverable mode.}"}
37503a627eSMilanka Ringwald    int main(void){
38503a627eSMilanka Ringwald        ...
39503a627eSMilanka Ringwald        // make discoverable
40503a627eSMilanka Ringwald        gap_discoverable_control(1);
41503a627eSMilanka Ringwald        btstack_run_loop_execute();
42503a627eSMilanka Ringwald        return 0;
43503a627eSMilanka Ringwald    }
44503a627eSMilanka Ringwald    void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){
45503a627eSMilanka Ringwald         ...
46503a627eSMilanka Ringwald         switch(state){
47503a627eSMilanka Ringwald              case W4_CHANNEL_COMPLETE:
48503a627eSMilanka Ringwald                  // if connection is successful, make device undiscoverable
49503a627eSMilanka Ringwald                  gap_discoverable_control(0);
50503a627eSMilanka Ringwald              ...
51503a627eSMilanka Ringwald         }
52503a627eSMilanka Ringwald     }
53503a627eSMilanka Ringwald~~~~
54503a627eSMilanka Ringwald
55503a627eSMilanka Ringwald### Discover remote devices {#sec:GAPdiscoverRemoteDevices}
56503a627eSMilanka Ringwald
57503a627eSMilanka RingwaldTo scan for remote devices, the *hci_inquiry* command is used. Found
58503a627eSMilanka Ringwaldremote devices are reported as a part of:
59503a627eSMilanka Ringwald
60503a627eSMilanka Ringwald- HCI_EVENT_INQUIRY_RESULT,
61503a627eSMilanka Ringwald
62503a627eSMilanka Ringwald- HCI_EVENT-_INQUIRY_RESULT_WITH_RSSI, or
63503a627eSMilanka Ringwald
64503a627eSMilanka Ringwald- HCI_EVENT_EXTENDED_INQUIRY_RESPONSE events.
65503a627eSMilanka Ringwald
66503a627eSMilanka RingwaldEach response contains at least the Bluetooth address, the class of device, the page scan
67503a627eSMilanka Ringwaldrepetition mode, and the clock offset of found device. The latter events
68503a627eSMilanka Ringwaldadd information about the received signal strength or provide the
69503a627eSMilanka RingwaldExtended Inquiry Result (EIR). A code snippet is shown in Listing
70503a627eSMilanka Ringwald[below](#lst:DiscoverDevices).
71503a627eSMilanka Ringwald
72503a627eSMilanka Ringwald~~~~ {#lst:DiscoverDevices .c caption="{Discover remote devices.}"}
73503a627eSMilanka Ringwald    void print_inquiry_results(uint8_t *packet){
74503a627eSMilanka Ringwald        int event = packet[0];
75503a627eSMilanka Ringwald        int numResponses = hci_event_inquiry_result_get_num_responses(packet);
76503a627eSMilanka Ringwald        uint16_t classOfDevice, clockOffset;
77503a627eSMilanka Ringwald        uint8_t  rssi, pageScanRepetitionMode;
78503a627eSMilanka Ringwald        for (i=0; i<numResponses; i++){
79503a627eSMilanka Ringwald            bt_flip_addr(addr, &packet[3+i*6]);
80503a627eSMilanka Ringwald            pageScanRepetitionMode = packet [3 + numResponses*6 + i];
81503a627eSMilanka Ringwald            if (event == HCI_EVENT_INQUIRY_RESULT){
82503a627eSMilanka Ringwald                classOfDevice = little_endian_read_24(packet, 3 + numResponses*(6+1+1+1) + i*3);
83503a627eSMilanka Ringwald                clockOffset =   little_endian_read_16(packet, 3 + numResponses*(6+1+1+1+3) + i*2) & 0x7fff;
84503a627eSMilanka Ringwald                rssi  = 0;
85503a627eSMilanka Ringwald            } else {
86503a627eSMilanka Ringwald                classOfDevice = little_endian_read_24(packet, 3 + numResponses*(6+1+1)     + i*3);
87503a627eSMilanka Ringwald                clockOffset =   little_endian_read_16(packet, 3 + numResponses*(6+1+1+3)   + i*2) & 0x7fff;
88503a627eSMilanka Ringwald                rssi  = packet [3 + numResponses*(6+1+1+3+2) + i*1];
89503a627eSMilanka Ringwald            }
90503a627eSMilanka Ringwald            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);
91503a627eSMilanka Ringwald        }
92503a627eSMilanka Ringwald    }
93503a627eSMilanka Ringwald
94503a627eSMilanka Ringwald    void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){
95503a627eSMilanka Ringwald        ...
96503a627eSMilanka Ringwald        switch (event) {
97503a627eSMilanka Ringwald             case HCI_STATE_WORKING:
98503a627eSMilanka Ringwald                hci_send_cmd(&hci_write_inquiry_mode, 0x01); // with RSSI
99503a627eSMilanka Ringwald                break;
100503a627eSMilanka Ringwald            case HCI_EVENT_COMMAND_COMPLETE:
101503a627eSMilanka Ringwald                if (COMMAND_COMPLETE_EVENT(packet, hci_write_inquiry_mode) ) {
102503a627eSMilanka Ringwald                    start_scan();
103503a627eSMilanka Ringwald                }
104503a627eSMilanka Ringwald            case HCI_EVENT_COMMAND_STATUS:
105503a627eSMilanka Ringwald                if (COMMAND_STATUS_EVENT(packet, hci_write_inquiry_mode) ) {
106503a627eSMilanka Ringwald                    printf("Ignoring error (0x%x) from hci_write_inquiry_mode.\n", packet[2]);
107503a627eSMilanka Ringwald                    hci_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0);
108503a627eSMilanka Ringwald                }
109503a627eSMilanka Ringwald                break;
110503a627eSMilanka Ringwald            case HCI_EVENT_INQUIRY_RESULT:
111503a627eSMilanka Ringwald            case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:
112503a627eSMilanka Ringwald                print_inquiry_results(packet);
113503a627eSMilanka Ringwald                break;
114503a627eSMilanka Ringwald           ...
115503a627eSMilanka Ringwald        }
116503a627eSMilanka Ringwald    }
117503a627eSMilanka Ringwald~~~~
118503a627eSMilanka Ringwald
119503a627eSMilanka RingwaldBy default, neither RSSI values nor EIR are reported. If the Bluetooth
120503a627eSMilanka Ringwalddevice implements Bluetooth Specification 2.1 or higher, the
121503a627eSMilanka Ringwald*hci_write_inquiry_mode* command enables reporting of this advanced
122503a627eSMilanka Ringwaldfeatures (0 for standard results, 1 for RSSI, 2 for RSSI and EIR).
123503a627eSMilanka Ringwald
124820e47d0SMilanka RingwaldA complete GAP inquiry example is provided [here](../examples/examples/#sec:gapinquiryExample).
125503a627eSMilanka Ringwald
126503a627eSMilanka Ringwald### Pairing of Devices
127503a627eSMilanka Ringwald
128503a627eSMilanka RingwaldBy default, Bluetooth communication is not authenticated, and any device
129503a627eSMilanka Ringwaldcan talk to any other device. A Bluetooth device (for example, cellular
130503a627eSMilanka Ringwaldphone) may choose to require authentication to provide a particular
131503a627eSMilanka Ringwaldservice (for example, a Dial-Up service). The process of establishing
132503a627eSMilanka Ringwaldauthentication is called pairing. Bluetooth provides two mechanism for
133503a627eSMilanka Ringwaldthis.
134503a627eSMilanka Ringwald
135503a627eSMilanka RingwaldOn Bluetooth devices that conform to the Bluetooth v2.0 or older
136503a627eSMilanka Ringwaldspecification, a PIN code (up to 16 bytes ASCII) has to be entered on
137503a627eSMilanka Ringwaldboth sides. This isn’t optimal for embedded systems that do not have
138503a627eSMilanka Ringwaldfull I/O capabilities. To support pairing with older devices using a
139503a627eSMilanka RingwaldPIN, see Listing [below](#lst:PinCodeRequest).
140503a627eSMilanka Ringwald
141503a627eSMilanka Ringwald~~~~ {#lst:PinCodeRequest .c caption="{PIN code request.}"}
142503a627eSMilanka Ringwald    void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){
143503a627eSMilanka Ringwald        ...
144503a627eSMilanka Ringwald        switch (event) {
145503a627eSMilanka Ringwald            case HCI_EVENT_PIN_CODE_REQUEST:
146503a627eSMilanka Ringwald                // inform about pin code request
147503a627eSMilanka Ringwald                printf("Pin code request - using '0000'\n\r");
148503a627eSMilanka Ringwald                hci_event_pin_code_request_get_bd_addr(packet, bd_addr);
149503a627eSMilanka Ringwald
150503a627eSMilanka Ringwald                // baseband address, pin length, PIN: c-string
151503a627eSMilanka Ringwald                hci_send_cmd(&hci_pin_code_request_reply, &bd_addr, 4, "0000");
152503a627eSMilanka Ringwald                break;
153503a627eSMilanka Ringwald           ...
154503a627eSMilanka Ringwald        }
155503a627eSMilanka Ringwald    }
156503a627eSMilanka Ringwald~~~~
157503a627eSMilanka Ringwald
158503a627eSMilanka RingwaldThe Bluetooth v2.1 specification introduces Secure Simple Pairing (SSP),
159503a627eSMilanka Ringwaldwhich is a better approach as it both improves security and is better
160503a627eSMilanka Ringwaldadapted to embedded systems. With SSP, the devices first exchange their
161503a627eSMilanka RingwaldIO Capabilities and then settle on one of several ways to verify that
162503a627eSMilanka Ringwaldthe pairing is legitimate. If the Bluetooth device supports SSP, BTstack
163503a627eSMilanka Ringwaldenables it by default and even automatically accepts SSP pairing
164503a627eSMilanka Ringwaldrequests. Depending on the product in which BTstack is used, this may
165503a627eSMilanka Ringwaldnot be desired and should be replaced with code to interact with the
166503a627eSMilanka Ringwalduser.
167503a627eSMilanka Ringwald
168503a627eSMilanka RingwaldRegardless of the authentication mechanism (PIN/SSP), on success, both
169503a627eSMilanka Ringwalddevices will generate a link key. The link key can be stored either in
170503a627eSMilanka Ringwaldthe Bluetooth module itself or in a persistent storage, see
171820e47d0SMilanka Ringwald[here](../porting/#sec:persistentStoragePorting). The next time the device connects and
172503a627eSMilanka Ringwaldrequests an authenticated connection, both devices can use the
173503a627eSMilanka Ringwaldpreviously generated link key. Please note that the pairing must be
174503a627eSMilanka Ringwaldrepeated if the link key is lost by one device.
175503a627eSMilanka Ringwald
176503a627eSMilanka Ringwald### Dedicated Bonding
177503a627eSMilanka Ringwald
178503a627eSMilanka RingwaldAside from the regular bonding, Bluetooth also provides the concept of
179503a627eSMilanka Ringwald“dedicated bonding”, where a connection is established for the sole
180503a627eSMilanka Ringwaldpurpose of bonding the device. After the bonding process is over, the
181503a627eSMilanka Ringwaldconnection will be automatically terminated. BTstack supports dedicated
182503a627eSMilanka Ringwaldbonding via the *gap_dedicated_bonding* function.
183503a627eSMilanka Ringwald
184503a627eSMilanka Ringwald## SPP - Serial Port Profile
185503a627eSMilanka Ringwald
186503a627eSMilanka RingwaldThe SPP profile defines how to set up virtual serial ports and connect
187503a627eSMilanka Ringwaldtwo Bluetooth enabled devices. Please keep in mind that a serial port does not
188503a627eSMilanka Ringwaldpreserve packet boundaries if you try to send data as packets and read about
189820e47d0SMilanka Ringwald[RFCOMM packet boundaries](../protocols/#sec:noRfcommPacketBoundaries).
190503a627eSMilanka Ringwald
191503a627eSMilanka Ringwald### Accessing an SPP Server on a remote device
192503a627eSMilanka Ringwald
193503a627eSMilanka RingwaldTo access a remote SPP server, you first need to query the remote device
194503a627eSMilanka Ringwaldfor its SPP services. Section [on querying remote SDP service](#sec:querySDPProtocols)
195503a627eSMilanka Ringwaldshows how to query for all RFCOMM channels. For SPP, you can do the same
196503a627eSMilanka Ringwaldbut use the SPP UUID 0x1101 for the query. After you have identified the
197503a627eSMilanka Ringwaldcorrect RFCOMM channel, you can create an RFCOMM connection as shown
198820e47d0SMilanka Ringwald[here](../protocols/#sec:rfcommClientProtocols).
199503a627eSMilanka Ringwald
200503a627eSMilanka Ringwald### Providing an SPP Server
201503a627eSMilanka Ringwald
202503a627eSMilanka RingwaldTo provide an SPP Server, you need to provide an RFCOMM service with a
203503a627eSMilanka Ringwaldspecific RFCOMM channel number as explained in section on
204820e47d0SMilanka Ringwald[RFCOMM service](../protocols/#sec:rfcommServiceProtocols). Then, you need to create
205503a627eSMilanka Ringwaldan SDP record for it and publish it with the SDP server by calling
206503a627eSMilanka Ringwald*sdp_register_service*. BTstack provides the
207503a627eSMilanka Ringwald*spp_create_sdp_record* function in that requires an empty buffer of
208503a627eSMilanka Ringwaldapproximately 200 bytes, the service channel number, and a service name.
209820e47d0SMilanka RingwaldHave a look at the [SPP Counter example](../examples/examples/#sec:sppcounterExample).
210503a627eSMilanka Ringwald
211503a627eSMilanka Ringwald
212503a627eSMilanka Ringwald## PAN - Personal Area Networking Profile {#sec:panProfiles}
213503a627eSMilanka Ringwald
214503a627eSMilanka Ringwald
215503a627eSMilanka RingwaldThe PAN profile uses BNEP to provide on-demand networking capabilities
216503a627eSMilanka Ringwaldbetween Bluetooth devices. The PAN profile defines the following roles:
217503a627eSMilanka Ringwald
218503a627eSMilanka Ringwald-   PAN User (PANU)
219503a627eSMilanka Ringwald
220503a627eSMilanka Ringwald-   Network Access Point (NAP)
221503a627eSMilanka Ringwald
222503a627eSMilanka Ringwald-   Group Ad-hoc Network (GN)
223503a627eSMilanka Ringwald
224503a627eSMilanka RingwaldPANU is a Bluetooth device that communicates as a client with GN, or
225503a627eSMilanka RingwaldNAP, or with another PANU Bluetooth device, through a point-to-point
226503a627eSMilanka Ringwaldconnection. Either the PANU or the other Bluetooth device may terminate
227503a627eSMilanka Ringwaldthe connection at anytime.
228503a627eSMilanka Ringwald
229503a627eSMilanka RingwaldNAP is a Bluetooth device that provides the service of routing network
230503a627eSMilanka Ringwaldpackets between PANU by using BNEP and the IP routing mechanism. A NAP
231503a627eSMilanka Ringwaldcan also act as a bridge between Bluetooth networks and other network
232503a627eSMilanka Ringwaldtechnologies by using the Ethernet packets.
233503a627eSMilanka Ringwald
234503a627eSMilanka RingwaldThe GN role enables two or more PANUs to interact with each other
235503a627eSMilanka Ringwaldthrough a wireless network without using additional networking hardware.
236503a627eSMilanka RingwaldThe devices are connected in a piconet where the GN acts as a master and
237503a627eSMilanka Ringwaldcommunicates either point-to-point or a point-to-multipoint with a
238503a627eSMilanka Ringwaldmaximum of seven PANU slaves by using BNEP.
239503a627eSMilanka Ringwald
240503a627eSMilanka RingwaldCurrently, BTstack supports only PANU.
241503a627eSMilanka Ringwald
242503a627eSMilanka Ringwald### Accessing a remote PANU service
243503a627eSMilanka Ringwald
244503a627eSMilanka RingwaldTo access a remote PANU service, you first need perform an SDP query to
245503a627eSMilanka Ringwaldget the L2CAP PSM for the requested PANU UUID. With these two pieces of
246503a627eSMilanka Ringwaldinformation, you can connect BNEP to the remote PANU service with the
247820e47d0SMilanka Ringwald*bnep_connect* function. The Section on [PANU Demo example](../examples/examples/#sec:panudemoExample)
248503a627eSMilanka Ringwaldshows how this is accomplished.
249503a627eSMilanka Ringwald
250503a627eSMilanka Ringwald### Providing a PANU service
251503a627eSMilanka Ringwald
252503a627eSMilanka RingwaldTo provide a PANU service, you need to provide a BNEP service with the
253503a627eSMilanka Ringwaldservice UUID, e.g. the PANU UUID, and a maximal ethernet frame size,
254820e47d0SMilanka Ringwaldas explained in Section [on BNEP service](../protocols/#sec:bnepServiceProtocols). Then, you need to
255503a627eSMilanka Ringwaldcreate an SDP record for it and publish it with the SDP server by
256503a627eSMilanka Ringwaldcalling *sdp_register_service*. BTstack provides the
257503a627eSMilanka Ringwald*pan_create_panu_sdp_record* function in *src/pan.c* that requires an
258503a627eSMilanka Ringwaldempty buffer of approximately 200 bytes, a description, and a security
259503a627eSMilanka Ringwalddescription.
260503a627eSMilanka Ringwald
261503a627eSMilanka Ringwald## HSP - Headset Profile
262503a627eSMilanka Ringwald
263503a627eSMilanka RingwaldThe HSP profile defines how a Bluetooth-enabled headset should communicate
264503a627eSMilanka Ringwaldwith another Bluetooth enabled device. It relies on SCO for audio encoded
265503a627eSMilanka Ringwaldin 64 kbit/s CVSD and a subset of AT commands from GSM 07.07 for
266503a627eSMilanka Ringwaldminimal controls including the ability to ring, answer a call, hang up and adjust the volume.
267503a627eSMilanka Ringwald
268503a627eSMilanka RingwaldThe HSP defines two roles:
269503a627eSMilanka Ringwald
270503a627eSMilanka Ringwald - Audio Gateway (AG) - a device that acts as the gateway of the audio, typically a mobile phone or PC.
271503a627eSMilanka Ringwald
272503a627eSMilanka Ringwald - Headset (HS) - a device that acts as the AG's remote audio input and output control.
273503a627eSMilanka Ringwald
274503a627eSMilanka RingwaldThere are following restrictions:
275503a627eSMilanka Ringwald- The CVSD is used for audio transmission.
276503a627eSMilanka Ringwald
277503a627eSMilanka Ringwald- Between headset and audio gateway, only one audio connection at a time is supported.
278503a627eSMilanka Ringwald
279503a627eSMilanka Ringwald- The profile offers only basic interoperability – for example, handling of multiple calls at the audio gateway is not included.
280503a627eSMilanka Ringwald
281503a627eSMilanka Ringwald- The only assumption on the headset’s user interface is the possibility to detect a user initiated action (e.g. pressing a button).
282503a627eSMilanka Ringwald
283503a627eSMilanka Ringwald%TODO: audio paths
284503a627eSMilanka Ringwald
285503a627eSMilanka Ringwald
2869e5566acSMilanka Ringwald## HFP - Hands-Free Profile  {#sec:hfp}
287503a627eSMilanka Ringwald
288503a627eSMilanka RingwaldThe 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.
289503a627eSMilanka RingwaldIt 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
290503a627eSMilanka Ringwaldcontrols 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.
291503a627eSMilanka Ringwald
292503a627eSMilanka RingwaldThe HFP defines two roles:
293503a627eSMilanka Ringwald
294503a627eSMilanka Ringwald- Audio Gateway (AG) – a device that acts as the gateway of the audio,, typically a mobile phone.
295503a627eSMilanka Ringwald
296503a627eSMilanka Ringwald- Hands-Free Unit (HF) – a device that acts as the AG's remote audio input and output control.
297503a627eSMilanka Ringwald
2989e5566acSMilanka Ringwald### Supported Features {#sec:hfpSupportedFeatures}
29993ffa3acSMilanka Ringwald
30093ffa3acSMilanka RingwaldThe supported features define the HFP capabilities of the device. The enumeration unfortunately differs between HF and AG sides.
30193ffa3acSMilanka Ringwald
30293ffa3acSMilanka RingwaldThe 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.
30393ffa3acSMilanka Ringwald
30493ffa3acSMilanka RingwaldSimilarly, 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.
30593ffa3acSMilanka Ringwald
30693ffa3acSMilanka Ringwald| Define for AG Supported Feature         |  Description  |
30793ffa3acSMilanka Ringwald| --------------------------------------- |  ----------------------------  |
30893ffa3acSMilanka Ringwald| HFP_AGSF_THREE_WAY_CALLING              |  Three-way calling             |
30993ffa3acSMilanka Ringwald| HFP_AGSF_EC_NR_FUNCTION                 |  Echo Canceling and/or Noise Reduction function |
31093ffa3acSMilanka Ringwald| HFP_AGSF_VOICE_RECOGNITION_FUNCTION     |  Voice recognition function |
31193ffa3acSMilanka Ringwald| HFP_AGSF_IN_BAND_RING_TONE              |  In-band ring tone capability |
31293ffa3acSMilanka Ringwald| HFP_AGSF_ATTACH_A_NUMBER_TO_A_VOICE_TAG |  Attach a number to a voice tag |
31393ffa3acSMilanka Ringwald| HFP_AGSF_ABILITY_TO_REJECT_A_CALL       |  Ability to reject a call |
31493ffa3acSMilanka Ringwald| HFP_AGSF_ENHANCED_CALL_STATUS           |  Enhanced call status |
31593ffa3acSMilanka Ringwald| HFP_AGSF_ENHANCED_CALL_CONTROL          |  Enhanced call control |
31693ffa3acSMilanka Ringwald| HFP_AGSF_EXTENDED_ERROR_RESULT_CODES    |  Extended Error Result Codes |
31793ffa3acSMilanka Ringwald| HFP_AGSF_CODEC_NEGOTIATION              |  Codec negotiation |
31893ffa3acSMilanka Ringwald| HFP_AGSF_HF_INDICATORS                  |  HF Indicators |
31993ffa3acSMilanka Ringwald| HFP_AGSF_ESCO_S4                        |  eSCO S4 (and T2) Settings Supported |
32093ffa3acSMilanka Ringwald| HFP_AGSF_ENHANCED_VOICE_RECOGNITION_STATUS |  Enhanced voice recognition status |
32193ffa3acSMilanka Ringwald| HFP_AGSF_VOICE_RECOGNITION_TEXT         |  Voice recognition text |
32293ffa3acSMilanka Ringwald
32393ffa3acSMilanka Ringwald
32493ffa3acSMilanka Ringwald| Define for HF Supported Feature         |  Description  |
32593ffa3acSMilanka Ringwald| --------------------------------------- |  ----------------------------  |
32693ffa3acSMilanka Ringwald| HFP_HFSF_THREE_WAY_CALLING              |  Three-way calling  |
32793ffa3acSMilanka Ringwald| HFP_HFSF_EC_NR_FUNCTION                 |  Echo Canceling and/or Noise Reduction function |
32893ffa3acSMilanka Ringwald| HFP_HFSF_CLI_PRESENTATION_CAPABILITY    |  CLI presentation capability |
32993ffa3acSMilanka Ringwald| HFP_HFSF_VOICE_RECOGNITION_FUNCTION     |  Voice recognition function |
33093ffa3acSMilanka Ringwald| HFP_HFSF_REMOTE_VOLUME_CONTROL          |  Remote volume control |
33193ffa3acSMilanka Ringwald| HFP_HFSF_ATTACH_A_NUMBER_TO_A_VOICE_TAG |  Attach a number to a voice tag |
33293ffa3acSMilanka Ringwald| HFP_HFSF_ENHANCED_CALL_STATUS           |  Enhanced call status |
33393ffa3acSMilanka Ringwald| HFP_HFSF_ENHANCED_CALL_CONTROL          |  Enhanced call control |
33493ffa3acSMilanka Ringwald| HFP_HFSF_CODEC_NEGOTIATION              |  Codec negotiation |
33593ffa3acSMilanka Ringwald| HFP_HFSF_HF_INDICATORS                  |  HF Indicators |
33693ffa3acSMilanka Ringwald| HFP_HFSF_ESCO_S4                        |  eSCO S4 (and T2) Settings Supported |
33793ffa3acSMilanka Ringwald| HFP_HFSF_ENHANCED_VOICE_RECOGNITION_STATUS |  Enhanced voice recognition status |
33893ffa3acSMilanka Ringwald| HFP_HFSF_VOICE_RECOGNITION_TEXT         |  Voice recognition text |
33993ffa3acSMilanka Ringwald
34093ffa3acSMilanka Ringwald
3419e5566acSMilanka Ringwald### Audio Voice Recognition Activation {#sec:hfpAVRActivation}
34293ffa3acSMilanka Ringwald
343543e856bSMilanka RingwaldAudio voice recognition (AVR) requires that HF and AG have the following  features enabled:
3449b78c3deSMilanka Ringwald
34593ffa3acSMilanka Ringwald- HF: HFP_HFSF_VOICE_RECOGNITION_FUNCTION and
3469b78c3deSMilanka Ringwald
34793ffa3acSMilanka Ringwald- AG: HFP_AGSF_VOICE_RECOGNITION_FUNCTION.
34893ffa3acSMilanka Ringwald
34993ffa3acSMilanka RingwaldIt can be activated or deactivated on both sides by calling:
35093ffa3acSMilanka Ringwald
35193ffa3acSMilanka Ringwald    // AG
35293ffa3acSMilanka Ringwald    uint8_t hfp_ag_activate_voice_recognition(hci_con_handle_t acl_handle);
35393ffa3acSMilanka Ringwald    uint8_t hfp_ag_deactivate_voice_recognition(hci_con_handle_t acl_handle);
35493ffa3acSMilanka Ringwald
35593ffa3acSMilanka Ringwald    // HF
35693ffa3acSMilanka Ringwald    uint8_t hfp_hf_activate_voice_recognition(hci_con_handle_t acl_handle);
35793ffa3acSMilanka Ringwald    uint8_t hfp_hf_deactivate_voice_recognition(hci_con_handle_t acl_handle);
35893ffa3acSMilanka Ringwald
359b321b609SMilanka RingwaldOn activation change, the HFP_SUBEVENT_VOICE_RECOGNITION_(DE)ACTIVATED event will be emitted with status field set to ERROR_CODE_SUCCESS on success.
36093ffa3acSMilanka Ringwald
36193ffa3acSMilanka RingwaldVoice 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.
36293ffa3acSMilanka Ringwald
36393ffa3acSMilanka Ringwald| Use cases                                              |  Expected behavior  |
36493ffa3acSMilanka Ringwald|--------------------------------------------------------|---------------------|
36593ffa3acSMilanka Ringwald| No previous audio connection, AVR activated then deactivated | Audio connection will be opened by AG upon AVR activation, and upon AVR deactivation closed|
36693ffa3acSMilanka Ringwald| AVR activated and deactivated during existing audio connection | Audio remains active upon AVR deactivation |
367543e856bSMilanka Ringwald| Call to close audio connection during active AVR session       | The audio connection shut down will be refused |
368543e856bSMilanka Ringwald| AVR activated, but audio connection failed to be established   | AVR will stay activated |
36993ffa3acSMilanka Ringwald
37093ffa3acSMilanka RingwaldBeyond 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.
37193ffa3acSMilanka Ringwald
3729e5566acSMilanka Ringwald### Enhanced Audio Voice Recognition {#sec:hfpeAVRActivation}
373503a627eSMilanka Ringwald
374543e856bSMilanka RingwaldSimilarly to AVR, Enhanced Audio voice recognition (eAVR) requires that HF and AG have the following features enabled:
3759b78c3deSMilanka Ringwald
376543e856bSMilanka Ringwald- HF: HFP_HFSF_ENHANCED_VOICE_RECOGNITION_STATUS and
3779b78c3deSMilanka Ringwald
378543e856bSMilanka Ringwald- AG: HFP_AGSF_ENHANCED_VOICE_RECOGNITION_STATUS.
379543e856bSMilanka Ringwald
380543e856bSMilanka RingwaldIn 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:
3819b78c3deSMilanka Ringwald
382543e856bSMilanka Ringwald- HF: HFP_HFSF_VOICE_RECOGNITION_TEXT and
3839b78c3deSMilanka Ringwald
384543e856bSMilanka Ringwald- AG: HFP_AGSF_VOICE_RECOGNITION_TEXT.
385543e856bSMilanka Ringwald
386b321b609SMilanka RingwaldeAVR 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.
387543e856bSMilanka Ringwald
388543e856bSMilanka RingwaldWhen eAVR and audio channel are established there are several additional commands that can be sent:
389543e856bSMilanka Ringwald
390543e856bSMilanka Ringwald| HFP Role | eVRA API | Description |
391543e856bSMilanka Ringwald-----------|----------|-------------|
392543e856bSMilanka Ringwald|HF | hfp_hf_enhanced_voice_recognition_report_ready_for_audio| Ready to accept audio input. |
393543e856bSMilanka Ringwald|AG | hfp_ag_enhanced_voice_recognition_report_ready_for_audio | Voice recognition engine is ready to accept audio input. |
394543e856bSMilanka Ringwald|AG | hfp_ag_enhanced_voice_recognition_report_sending_audio | The voice recognition engine will play a sound, e.g. starting sound. |
395543e856bSMilanka Ringwald|AG | hfp_ag_enhanced_voice_recognition_report_processing_input | Voice recognition engine is processing the audio input. |
396543e856bSMilanka Ringwald|AG | hfp_ag_enhanced_voice_recognition_send_message | Report textual representation from the voice recognition engine. |
397543e856bSMilanka Ringwald
398543e856bSMilanka Ringwald
399503a627eSMilanka Ringwald## HID - Human-Interface Device Profile
400503a627eSMilanka Ringwald
401503a627eSMilanka RingwaldThe HID profile allows an HID Host to connect to one or more HID Devices and communicate with them.
402503a627eSMilanka RingwaldExamples of Bluetooth HID devices are keyboards, mice, joysticks, gamepads, remote controls, and also voltmeters and temperature sensors.
403503a627eSMilanka RingwaldTypical HID hosts would be a personal computer, tablets, gaming console, industrial machine, or data-recording device.
404503a627eSMilanka Ringwald
405503a627eSMilanka RingwaldPlease refer to:
406503a627eSMilanka Ringwald
407820e47d0SMilanka Ringwald- [HID Host API](../appendix/apis/#sec:hidHostAPIAppendix) and [hid_host_demo](../examples/examples/#sec:hidhostdemoExample) for the HID Host role
408503a627eSMilanka Ringwald
409820e47d0SMilanka Ringwald- [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.
410503a627eSMilanka Ringwald
411503a627eSMilanka Ringwald
412503a627eSMilanka Ringwald## GAP LE - Generic Access Profile for Low Energy
413503a627eSMilanka Ringwald
414503a627eSMilanka Ringwald
415503a627eSMilanka RingwaldAs with GAP for Classic, the GAP LE profile defines how to discover and
416503a627eSMilanka Ringwaldhow to connect to a Bluetooth Low Energy device. There are several GAP
417503a627eSMilanka Ringwaldroles that a Bluetooth device can take, but the most important ones are
418503a627eSMilanka Ringwaldthe Central and the Peripheral role. Peripheral devices are those that
419503a627eSMilanka Ringwaldprovide information or can be controlled. Central devices are those that
420503a627eSMilanka Ringwaldconsume information or control the peripherals. Before the connection
421503a627eSMilanka Ringwaldcan be established, devices are first going through an advertising
422503a627eSMilanka Ringwaldprocess.
423503a627eSMilanka Ringwald
424503a627eSMilanka Ringwald### Private addresses.
425503a627eSMilanka Ringwald
426503a627eSMilanka RingwaldTo better protect privacy, an LE device can choose to use a private i.e.
427503a627eSMilanka Ringwaldrandom Bluetooth address. This address changes at a user-specified rate.
428503a627eSMilanka RingwaldTo allow for later reconnection, the central and peripheral devices will
429503a627eSMilanka Ringwaldexchange their Identity Resolving Keys (IRKs) during bonding. The IRK is
430503a627eSMilanka Ringwaldused to verify if a new address belongs to a previously bonded device.
431503a627eSMilanka Ringwald
432503a627eSMilanka RingwaldTo toggle privacy mode using private addresses, call the
433503a627eSMilanka Ringwald*gap_random_address_set_mode* function. The update period can be set
434503a627eSMilanka Ringwaldwith *gap_random_address_set_update_period*.
435503a627eSMilanka Ringwald
436503a627eSMilanka RingwaldAfter a connection is established, the Security Manager will try to
437503a627eSMilanka Ringwaldresolve the peer Bluetooth address as explained in Section on
438820e47d0SMilanka Ringwald[SMP](../protocols/#sec:smpProtocols).
439503a627eSMilanka Ringwald
440503a627eSMilanka Ringwald### Advertising and Discovery
441503a627eSMilanka Ringwald
442503a627eSMilanka RingwaldAn LE device is discoverable and connectable, only if it periodically
443503a627eSMilanka Ringwaldsends out Advertisements. An advertisement contains up to 31 bytes of
444503a627eSMilanka Ringwalddata. To configure and enable advertisement broadcast, the following GAP
445503a627eSMilanka Ringwaldfunctions can be used:
446503a627eSMilanka Ringwald
447503a627eSMilanka Ringwald-   *gap_advertisements_set_data*
448503a627eSMilanka Ringwald
449503a627eSMilanka Ringwald-   *gap_advertisements_set_params*
450503a627eSMilanka Ringwald
451503a627eSMilanka Ringwald-   *gap_advertisements_enable*
452503a627eSMilanka Ringwald
453503a627eSMilanka RingwaldIn addition to the Advertisement data, a device in the peripheral role
454503a627eSMilanka Ringwaldcan also provide Scan Response data, which has to be explicitly queried
455503a627eSMilanka Ringwaldby the central device. It can be set with *gap_scan_response_set_data*.
456503a627eSMilanka Ringwald
457503a627eSMilanka RingwaldPlease have a look at the [SPP and LE
458820e47d0SMilanka RingwaldCounter example](../examples/examples/#sec:sppandlecounterExample).
459503a627eSMilanka Ringwald
460503a627eSMilanka RingwaldThe scan parameters can be set with
461503a627eSMilanka Ringwald*gap_set_scan_parameters*. The scan can be started/stopped
462503a627eSMilanka Ringwaldwith *gap_start_scan*/*gap_stop_scan*.
463503a627eSMilanka Ringwald
464503a627eSMilanka RingwaldFinally, if a suitable device is found, a connection can be initiated by
465503a627eSMilanka Ringwaldcalling *gap_connect*. In contrast to Bluetooth classic, there
466503a627eSMilanka Ringwaldis no timeout for an LE connection establishment. To cancel such an
467503a627eSMilanka Ringwaldattempt, *gap_connect_cancel* has be be called.
468503a627eSMilanka Ringwald
469503a627eSMilanka RingwaldBy default, a Bluetooth device stops sending Advertisements when it gets
470503a627eSMilanka Ringwaldinto the Connected state. However, it does not start broadcasting
471503a627eSMilanka Ringwaldadvertisements on disconnect again. To re-enable it, please send the
472503a627eSMilanka Ringwald*hci_le_set_advertise_enable* again .
473503a627eSMilanka Ringwald
474503a627eSMilanka Ringwald## GATT Client {#sec:GATTClientProfiles}
475503a627eSMilanka Ringwald
476503a627eSMilanka RingwaldThe GATT profile uses ATT Attributes to represent a hierarchical
477503a627eSMilanka Ringwaldstructure of GATT Services and GATT Characteristics. Each Service has
478503a627eSMilanka Ringwaldone or more Characteristics. Each Characteristic has meta data attached
479503a627eSMilanka Ringwaldlike its type or its properties. This hierarchy of Characteristics and
480503a627eSMilanka RingwaldServices are queried and modified via ATT operations.
481503a627eSMilanka Ringwald
482503a627eSMilanka RingwaldGATT defines both a server and a client role. A device can implement one
483503a627eSMilanka Ringwaldor both GATT roles.
484503a627eSMilanka Ringwald
485503a627eSMilanka RingwaldThe GATT Client is used to discover services, characteristics
486503a627eSMilanka Ringwaldand their descriptors on a peer device. It allows to subscribe for
487503a627eSMilanka Ringwaldnotifications or indications that the characteristic on the GATT server
488503a627eSMilanka Ringwaldhas changed its value.
489503a627eSMilanka Ringwald
490503a627eSMilanka RingwaldTo perform GATT queries, it provides a rich interface. Before calling
491503a627eSMilanka Ringwaldqueries, the GATT client must be initialized with *gatt_client_init*
492503a627eSMilanka Ringwaldonce.
493503a627eSMilanka Ringwald
494503a627eSMilanka RingwaldTo allow for modular profile implementations, GATT client can be used
495503a627eSMilanka Ringwaldindependently by multiple entities.
496503a627eSMilanka Ringwald
497503a627eSMilanka RingwaldAfter an LE connection was created using the GAP LE API, you can query
498503a627eSMilanka Ringwaldfor the connection MTU with *gatt_client_get_mtu*.
499503a627eSMilanka Ringwald
500503a627eSMilanka RingwaldMultiple GATT queries to the same GATT Server cannot be interleaved.
501503a627eSMilanka RingwaldTherefore, you can either use a state machine or similar to perform the
502503a627eSMilanka Ringwaldqueries in sequence, or you can check if you can perform a GATT query
503503a627eSMilanka Ringwaldon a particular connection right now using
504503a627eSMilanka Ringwald*gatt_client_is_ready*, and retry later if it is not ready.
505503a627eSMilanka RingwaldAs a result to a GATT query, zero to many
506503a627eSMilanka Ringwald*GATT_EVENT_X*s are returned before a *GATT_EVENT_QUERY_COMPLETE* event
507503a627eSMilanka Ringwaldcompletes the query.
508503a627eSMilanka Ringwald
509503a627eSMilanka RingwaldFor more details on the available GATT queries, please consult
510503a627eSMilanka Ringwald[GATT Client API](#sec:gattClientAPIAppendix).
511503a627eSMilanka Ringwald
512503a627eSMilanka Ringwald### Authentication
513503a627eSMilanka Ringwald
514503a627eSMilanka RingwaldBy default, the GATT Server is responsible for security and the GATT Client does not enforce any kind of authentication.
515503a627eSMilanka RingwaldIf the GATT Client accesses Characteristic that require encrytion or authentication, the remote GATT Server will return an error,
516503a627eSMilanka Ringwaldwhich is returned in the *att status* of the *GATT_EVENT_QUERY_COMPLETE*.
517503a627eSMilanka Ringwald
518503a627eSMilanka RingwaldYou can define *ENABLE_GATT_CLIENT_PAIRING* to instruct the GATT Client to trigger pairing in this case and to repeat the request.
519503a627eSMilanka Ringwald
520503a627eSMilanka RingwaldThis model allows for an attacker to spoof another device, but don't require authentication for the Characteristics.
521503a627eSMilanka RingwaldAs a first improvement, you can define *ENABLE_LE_PROACTIVE_AUTHENTICATION* in *btstack_config.h*. When defined, the GATT Client will
522503a627eSMilanka Ringwaldrequest the Security Manager to re-encrypt the connection if there is stored bonding information available.
523503a627eSMilanka RingwaldIf this fails, the  *GATT_EVENT_QUERY_COMPLETE* will return with the att status *ATT_ERROR_BONDING_INFORMATION_MISSING*.
524503a627eSMilanka Ringwald
525503a627eSMilanka RingwaldWith *ENABLE_LE_PROACTIVE_AUTHENTICATION* defined and in Central role, you need to delete the local bonding information if the remote
526503a627eSMilanka Ringwaldlost its bonding information, e.g. because of a device reset. See *example/sm_pairing_central.c*.
527503a627eSMilanka Ringwald
528503a627eSMilanka RingwaldEven with the Proactive Authentication, your device may still connect to an attacker that provides the same advertising data as
529503a627eSMilanka Ringwaldyour actual device. If the device that you want to connect requires pairing, you can instruct the GATT Client to automatically
530503a627eSMilanka Ringwaldrequest an encrypted connection before sending any GATT Client request by calling *gatt_client_set_required_security_level()*.
531503a627eSMilanka RingwaldIf the device provides sufficient IO capabilities, a MITM attack can then be prevented. We call this 'Mandatory Authentication'.
532503a627eSMilanka Ringwald
533503a627eSMilanka RingwaldThe following diagrams provide a detailed overview about the GATT Client security mechanisms in different configurations:
534503a627eSMilanka Ringwald
5357029d61cSMilanka Ringwald-  [Reactive Authentication as Central](picts/gatt_client_security_reactive_authentication_central.svg)
5367029d61cSMilanka Ringwald-  [Reactive Authentication as Peripheral](picts/gatt_client_security_reactive_authentication_peripheral.svg)
5377029d61cSMilanka Ringwald-  [Proactive Authentication as Central](picts/gatt_client_security_proactive_authentication_central.svg)
5387029d61cSMilanka Ringwald-  [Proactive Authentication as Peripheral](picts/gatt_client_security_proactive_authentication_peripheral.svg)
5397029d61cSMilanka Ringwald-  [Mandatory Authentication as Central](picts/gatt_client_security_mandatory_authentication_central.svg)
5407029d61cSMilanka Ringwald-  [Mandatory Authentication as Peripheral](picts/gatt_client_security_mandatory_authentication_peripheral.svg)
541503a627eSMilanka Ringwald
542503a627eSMilanka Ringwald## GATT Server {#sec:GATTServerProfiles}
543503a627eSMilanka Ringwald
544503a627eSMilanka RingwaldThe GATT server stores data and accepts GATT client requests, commands
545503a627eSMilanka Ringwaldand confirmations. The GATT server sends responses to requests and when
546503a627eSMilanka Ringwaldconfigured, sends indication and notifications asynchronously to the
547503a627eSMilanka RingwaldGATT client.
548503a627eSMilanka Ringwald
549503a627eSMilanka RingwaldTo save on both code space and memory, BTstack does not provide a GATT
550503a627eSMilanka RingwaldServer implementation. Instead, a textual description of the GATT
551503a627eSMilanka Ringwaldprofile is directly converted into a compact internal ATT Attribute
552503a627eSMilanka Ringwalddatabase by a GATT profile compiler. The ATT protocol server -
553*e54a3bcaSMatthias Ringwaldprovided by `att_db.h` and `att_server.h` - answers incoming ATT
554*e54a3bcaSMatthias Ringwaldrequests based on information provided in the compiled database and
555*e54a3bcaSMatthias Ringwaldprovides read- and write-callbacks for dynamic attributes.
556503a627eSMilanka Ringwald
557503a627eSMilanka RingwaldGATT profiles are defined by a simple textual comma separated value
558503a627eSMilanka Ringwald(.csv) representation. While the description is easy to read and edit,
559503a627eSMilanka Ringwaldit is compact and can be placed in ROM.
560503a627eSMilanka Ringwald
561503a627eSMilanka RingwaldThe current format is shown in Listing [below](#lst:GATTServerProfile).
562503a627eSMilanka Ringwald
563503a627eSMilanka Ringwald~~~~ {#lst:GATTServerProfile .c caption="{GATT profile.}"}
564503a627eSMilanka Ringwald    // import service_name
565503a627eSMilanka Ringwald    #import <service_name.gatt>
566503a627eSMilanka Ringwald
567503a627eSMilanka Ringwald    PRIMARY_SERVICE, {SERVICE_UUID}
568503a627eSMilanka Ringwald    CHARACTERISTIC, {ATTRIBUTE_TYPE_UUID}, {PROPERTIES}, {VALUE}
569503a627eSMilanka Ringwald    CHARACTERISTIC, {ATTRIBUTE_TYPE_UUID}, {PROPERTIES}, {VALUE}
570503a627eSMilanka Ringwald    ...
571503a627eSMilanka Ringwald    PRIMARY_SERVICE, {SERVICE_UUID}
572503a627eSMilanka Ringwald    CHARACTERISTIC, {ATTRIBUTE_TYPE_UUID}, {PROPERTIES}, {VALUE}
573503a627eSMilanka Ringwald    ...
574503a627eSMilanka Ringwald~~~~
575503a627eSMilanka Ringwald
576503a627eSMilanka RingwaldUUIDs are either 16 bit (1800) or 128 bit
577503a627eSMilanka Ringwald(00001234-0000-1000-8000-00805F9B34FB).
578503a627eSMilanka Ringwald
579503a627eSMilanka RingwaldValue can either be a string (“this is a string”), or, a sequence of hex
580503a627eSMilanka Ringwaldbytes (e.g. 01 02 03).
581503a627eSMilanka Ringwald
582503a627eSMilanka RingwaldProperties can be a list of properties combined using '|'
583503a627eSMilanka Ringwald
584503a627eSMilanka RingwaldReads/writes to a Characteristic that is defined with the DYNAMIC flag,
585503a627eSMilanka Ringwaldare forwarded to the application via callback. Otherwise, the
586503a627eSMilanka RingwaldCharacteristics cannot be written and it will return the specified
587503a627eSMilanka Ringwaldconstant value.
588503a627eSMilanka Ringwald
5895e9859c7SMilanka RingwaldAdding NOTIFY and/or INDICATE automatically creates an additional Client
590503a627eSMilanka RingwaldConfiguration Characteristic.
591503a627eSMilanka Ringwald
59214c4dac7SMilanka RingwaldProperty                | Description
593503a627eSMilanka Ringwald------------------------|-----------------------------------------------
594503a627eSMilanka RingwaldREAD                    | Characteristic can be read
595503a627eSMilanka RingwaldWRITE                   | Characteristic can be written using Write Request
596503a627eSMilanka RingwaldWRITE_WITHOUT_RESPONSE  | Characteristic can be written using Write Command
597503a627eSMilanka RingwaldNOTIFY                  | Characteristic allows notifications by server
598503a627eSMilanka RingwaldINDICATE                | Characteristic allows indication by server
599503a627eSMilanka RingwaldDYNAMIC                 | Read or writes to Characteristic are handled by application
600503a627eSMilanka Ringwald
601503a627eSMilanka RingwaldTo require encryption or authentication before a Characteristic can be
602503a627eSMilanka Ringwaldaccessed, you can add one or more of the following properties:
603503a627eSMilanka Ringwald
60414c4dac7SMilanka RingwaldProperty                | Description
605503a627eSMilanka Ringwald------------------------|-----------------------------------------------
606503a627eSMilanka RingwaldAUTHENTICATION_REQUIRED | Read and Write operations require Authentication
607503a627eSMilanka RingwaldREAD_ENCRYPTED          | Read operations require Encryption
608503a627eSMilanka RingwaldREAD_AUTHENTICATED      | Read operations require Authentication
609503a627eSMilanka RingwaldWRITE_ENCRYPTED         | Write operations require Encryption
610503a627eSMilanka RingwaldWRITE_AUTHENTICATED     | Write operations require Authentication
611503a627eSMilanka RingwaldENCRYPTION_KEY_SIZE_X   | Require encryption size >= X, with W in [7..16]
612503a627eSMilanka Ringwald
6135e9859c7SMilanka RingwaldFor example, Volume State Characteristic (Voice Control Service) requires:
6145e9859c7SMilanka Ringwald- Mandatory Properties: Read, Notify
61514c4dac7SMilanka Ringwald- Security Permissions: Encryption Required
6165e9859c7SMilanka Ringwald
6175e9859c7SMilanka RingwaldIn addition, its read is handled by application. We can model this Characteristic as follows:
6185e9859c7SMilanka Ringwald
6195e9859c7SMilanka Ringwald~~~~
6205e9859c7SMilanka Ringwald    CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_VOLUME_STATE, DYNAMIC | READ | NOTIFY | ENCRYPTION_KEY_SIZE_16
6215e9859c7SMilanka Ringwald~~~~
6225e9859c7SMilanka Ringwald
623503a627eSMilanka RingwaldTo use already implemented GATT Services, you can import it
624503a627eSMilanka Ringwaldusing the *#import <service_name.gatt>* command. See [list of provided services](gatt_services.md).
625503a627eSMilanka Ringwald
626503a627eSMilanka RingwaldBTstack only provides an ATT Server, while the GATT Server logic is
627503a627eSMilanka Ringwaldmainly provided by the GATT compiler. While GATT identifies
628503a627eSMilanka RingwaldCharacteristics by UUIDs, ATT uses Handles (16 bit values). To allow to
629503a627eSMilanka Ringwaldidentify a Characteristic without hard-coding the attribute ID, the GATT
630503a627eSMilanka Ringwaldcompiler creates a list of defines in the generated \*.h file.
631503a627eSMilanka Ringwald
632503a627eSMilanka RingwaldSimilar to other protocols, it might be not possible to send any time.
633753e0cc2SMatthias RingwaldTo send a Notification, you can call *att_server_request_to_send_notification*
634753e0cc2SMatthias Ringwaldto request a callback, when yuo can send the Notification.
635503a627eSMilanka Ringwald
636d72e9d4bSMatthias Ringwald### Deferred Handling of ATT Read / Write Requests
637d72e9d4bSMatthias Ringwald
638503a627eSMilanka RingwaldIf your application cannot handle an ATT Read Request in the *att_read_callback*
639503a627eSMilanka Ringwaldin some situations, you can enable support for this by adding ENABLE_ATT_DELAYED_RESPONSE
640503a627eSMilanka Ringwaldto *btstack_config.h*. Now, you can store the requested attribute handle and return
641503a627eSMilanka Ringwald*ATT_READ_RESPONSE_PENDING* instead of the length of the provided data when you don't have the data ready.
642503a627eSMilanka RingwaldFor ATT operations that read more than one attribute, your *att_read_callback*
643503a627eSMilanka Ringwaldmight get called multiple times as well. To let you know that all necessary
644503a627eSMilanka Ringwaldattribute handles have been 'requested' by the *att_server*, you'll get a final
645503a627eSMilanka Ringwald*att_read_callback* with the attribute handle of *ATT_READ_RESPONSE_PENDING*.
646503a627eSMilanka RingwaldWhen you've got the data for all requested attributes ready, you can call
647503a627eSMilanka Ringwald*att_server_response_ready*, which will trigger processing of the current request.
648503a627eSMilanka RingwaldPlease keep in mind that there is only one active ATT operation and that it has a 30 second
649503a627eSMilanka Ringwaldtimeout after which the ATT server is considered defunct by the GATT Client.
650503a627eSMilanka Ringwald
651d72e9d4bSMatthias RingwaldSimilarly, you can return ATT_ERROR_WRITE_RESPONSE_PENDING in the *att_write_callback*.
652d72e9d4bSMatthias RingwaldThe ATT Server will not respond to the ATT Client in this case and wait for your code to
653d72e9d4bSMatthias Ringwaldcall *att_server_response_ready*, which then triggers the  *att_write_callback* again.
654d72e9d4bSMatthias Ringwald
655d72e9d4bSMatthias RingwaldPlease have a look at the [ATT Delayed Response example](../examples/examples/#sec:attdelayedresponseExample).
656d72e9d4bSMatthias Ringwald
657503a627eSMilanka Ringwald### Implementing Standard GATT Services {#sec:GATTStandardServices}
658503a627eSMilanka Ringwald
659503a627eSMilanka RingwaldImplementation of a standard GATT Service consists of the following 4 steps:
660503a627eSMilanka Ringwald
66141e15c2aSMatthias Ringwald  1. Get the Service specification from Bluetooth SIG
66241e15c2aSMatthias Ringwald  2. Find the Service Characteristics table and their properties
66341e15c2aSMatthias Ringwald  3. Create .gatt file from Service Characteristics table
664503a627eSMilanka Ringwald  4. Implement Service server, e.g., battery_service_server.c
665503a627eSMilanka Ringwald
666503a627eSMilanka RingwaldStep 1:
667503a627eSMilanka Ringwald
66841e15c2aSMatthias RingwaldAll GATT Service specifications can be found [here](https://www.bluetooth.com/specifications/specs/).
669503a627eSMilanka Ringwald
670503a627eSMilanka Ringwald
671503a627eSMilanka RingwaldStep 2:
672503a627eSMilanka Ringwald
67341e15c2aSMatthias RingwaldThe Service Characteristics table is usually in chapter "Service Characteristics".
674503a627eSMilanka Ringwald
67541e15c2aSMatthias RingwaldLet's have a look at an actual example, the [Battery Service Specification v1.0](https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=245138).
67641e15c2aSMatthias RingwaldIn it, we find this:
677503a627eSMilanka Ringwald
67841e15c2aSMatthias RingwaldCharacteristic | Ref | Mandatory/Optional
67941e15c2aSMatthias Ringwald---------------|-----|-------------------
68041e15c2aSMatthias RingwaldBattery Level  | 3.1 | M
681503a627eSMilanka Ringwald
68241e15c2aSMatthias RingwaldSo, the Battery Service has a single mandatory Characteristic.
68341e15c2aSMatthias Ringwald
68441e15c2aSMatthias RingwaldCharacteristic | Broadcast | Read | Write without Response | Write | Notify | Indicate | Signed Write | Reliable Write | Writable Auxiliaries
68541e15c2aSMatthias Ringwald---------------|-----------|------|------------------------|-------|--------|----------|--------------|----------------|---------
68641e15c2aSMatthias RingwaldBattery Level  |      x    |  M   |            x           |  x    |  O     |     x    |      x       |        x       |     x
68741e15c2aSMatthias Ringwald
68841e15c2aSMatthias RingwaldThe Battery Level Characteristic must supports Read and optionally allows for Notifications.
689503a627eSMilanka Ringwald
690503a627eSMilanka Ringwald
691503a627eSMilanka RingwaldStep 3:
692503a627eSMilanka Ringwald
69341e15c2aSMatthias RingwaldFollowing the Battery Service v1.0 example, let's create `battery_service.gatt`.
694503a627eSMilanka Ringwald
69541e15c2aSMatthias RingwaldBTstack has a list of most GATT Service and Characteristics UUIDs in `src/bluetooth_gatt.h`, which can be used in .gatt files.
696503a627eSMilanka Ringwald
69741e15c2aSMatthias RingwaldMissing UUIDs can be found in Bluetooth SIG Bitbucket repo:
69841e15c2aSMatthias Ringwald- [Service UUIDs](https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/uuids/service_uuids.yaml)
69941e15c2aSMatthias Ringwald- [Characteristic UUIDs](https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/uuids/characteristic_uuids.yaml)
700503a627eSMilanka Ringwald
70141e15c2aSMatthias RingwaldFirst we add the Primary Service definition:
70241e15c2aSMatthias Ringwald
70341e15c2aSMatthias Ringwald```
70441e15c2aSMatthias Ringwald// Battery Service v1.0
705503a627eSMilanka RingwaldPRIMARY_SERVICE, ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE
70641e15c2aSMatthias Ringwald```
707503a627eSMilanka Ringwald
70841e15c2aSMatthias RingwaldNext, we add all Characteristics and map their properties into the format of the .gatt file.
70941e15c2aSMatthias Ringwald
71041e15c2aSMatthias RingwaldIn this example, the Battery Level is dynamic and supports Read and Notification.
71141e15c2aSMatthias Ringwald```
71241e15c2aSMatthias RingwaldCHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL, DYNAMIC | READ | NOTIFY,
71341e15c2aSMatthias Ringwald```
71441e15c2aSMatthias Ringwald
71541e15c2aSMatthias RingwaldFeel free to take a look at already implemented GATT Service .gatt files in `src/ble/gatt-service/`.
716503a627eSMilanka Ringwald
717503a627eSMilanka RingwaldStep 4:
718503a627eSMilanka Ringwald
719503a627eSMilanka RingwaldAs described [above](#sec:GATTServerProfiles) all read/write requests are handled by the application.
720503a627eSMilanka RingwaldTo implement the new services as a reusable module, it's necessary to get access to all read/write requests related to this service.
721503a627eSMilanka Ringwald
722753e0cc2SMatthias RingwaldFor this, the ATT DB allows to register read/write callbacks for a specific handle range with *att_server_register_service_handler()*.
723503a627eSMilanka Ringwald
724503a627eSMilanka RingwaldSince 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*.
725503a627eSMilanka Ringwald
726503a627eSMilanka RingwaldSimilarly, 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()*.
727503a627eSMilanka Ringwald
728503a627eSMilanka RingwaldIn 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()*
729503a627eSMilanka Ringwald
730503a627eSMilanka RingwaldFinally, 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.
731503a627eSMilanka Ringwald
732503a627eSMilanka RingwaldTo see how this works together, please check out the Battery Service Server in *src/ble/battery_service_server.c*.
733503a627eSMilanka Ringwald
734503a627eSMilanka Ringwald### GATT Database Hash
735503a627eSMilanka Ringwald
736503a627eSMilanka RingwaldWhen a GATT Client connects to a GATT Server, it cannot know if the GATT Database has changed
737503a627eSMilanka Ringwaldand has to discover the provided GATT Services and Characteristics after each connect.
738503a627eSMilanka Ringwald
739503a627eSMilanka RingwaldTo speed this up, the Bluetooth
740503a627eSMilanka Ringwaldspecification defines a GATT Service Changed Characteristic, with the idea that a GATT Server would notify
741503a627eSMilanka Ringwalda bonded GATT Client if its database changed. However, this is quite fragile and it is not clear how it can be implemented
742503a627eSMilanka Ringwaldin a robust way.
743503a627eSMilanka Ringwald
744503a627eSMilanka RingwaldThe Bluetooth Core Spec 5.1 introduced the GATT Database Hash Characteristic, which allows for a simple
745503a627eSMilanka Ringwaldrobust mechanism to cache a remote GATT Database. The GATT Database Hash is a 16-byte value that is calculated
746503a627eSMilanka Ringwaldover the list of Services and Characteristics. If there is any change to the database, the hash will change as well.
747503a627eSMilanka Ringwald
748503a627eSMilanka RingwaldTo support this on the GATT Server, you only need to add a GATT Service with the GATT Database Characteristic to your .gatt file.
749503a627eSMilanka RingwaldThe hash value is then calculated by the GATT compiler.
750503a627eSMilanka Ringwald
751503a627eSMilanka Ringwald
752503a627eSMilanka Ringwald    PRIMARY_SERVICE, GATT_SERVICE
753503a627eSMilanka Ringwald    CHARACTERISTIC, GATT_DATABASE_HASH, READ,
754503a627eSMilanka Ringwald
755503a627eSMilanka RingwaldNote: make sure to install the PyCryptodome python package as the hash is calculated using AES-CMAC,
756503a627eSMilanka Ringwalde.g. with:
757503a627eSMilanka Ringwald
758503a627eSMilanka Ringwald    pip install pycryptodomex
759