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