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