1503a627eSMilanka Ringwald# 2503a627eSMilanka Ringwald 3503a627eSMilanka RingwaldIn the following, we explain how the various Bluetooth profiles are used 4503a627eSMilanka Ringwaldin BTstack. 5503a627eSMilanka Ringwald 6503a627eSMilanka Ringwald## GAP - Generic Access Profile: Classic 7503a627eSMilanka Ringwald 8503a627eSMilanka Ringwald 9503a627eSMilanka RingwaldThe GAP profile defines how devices find each other and establish a 10503a627eSMilanka Ringwaldsecure connection for other profiles. As mentioned before, the GAP 11503a627eSMilanka Ringwaldfunctionality is split between and . Please check both. 12503a627eSMilanka Ringwald 13503a627eSMilanka Ringwald### Become discoverable 14503a627eSMilanka Ringwald 15503a627eSMilanka RingwaldA remote unconnected Bluetooth device must be set as “discoverable” in 16503a627eSMilanka Ringwaldorder to be seen by a device performing the inquiry scan. To become 17503a627eSMilanka Ringwalddiscoverable, an application can call *gap_discoverable_control* with 18503a627eSMilanka Ringwaldinput parameter 1. If you want to provide a helpful name for your 19503a627eSMilanka Ringwalddevice, the application can set its local name by calling 20503a627eSMilanka Ringwald*gap_set_local_name*. To save energy, you may set the device as 21503a627eSMilanka Ringwaldundiscoverable again, once a connection is established. See Listing 22503a627eSMilanka Ringwald[below](#lst:Discoverable) for an example. 23503a627eSMilanka Ringwald 24503a627eSMilanka Ringwald~~~~ {#lst:Discoverable .c caption="{Setting discoverable mode.}"} 25503a627eSMilanka Ringwald int main(void){ 26503a627eSMilanka Ringwald ... 27503a627eSMilanka Ringwald // make discoverable 28503a627eSMilanka Ringwald gap_discoverable_control(1); 29503a627eSMilanka Ringwald btstack_run_loop_execute(); 30503a627eSMilanka Ringwald return 0; 31503a627eSMilanka Ringwald } 32503a627eSMilanka Ringwald void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){ 33503a627eSMilanka Ringwald ... 34503a627eSMilanka Ringwald switch(state){ 35503a627eSMilanka Ringwald case W4_CHANNEL_COMPLETE: 36503a627eSMilanka Ringwald // if connection is successful, make device undiscoverable 37503a627eSMilanka Ringwald gap_discoverable_control(0); 38503a627eSMilanka Ringwald ... 39503a627eSMilanka Ringwald } 40503a627eSMilanka Ringwald } 41503a627eSMilanka Ringwald~~~~ 42503a627eSMilanka Ringwald 43503a627eSMilanka Ringwald### Discover remote devices {#sec:GAPdiscoverRemoteDevices} 44503a627eSMilanka Ringwald 45503a627eSMilanka RingwaldTo scan for remote devices, the *hci_inquiry* command is used. Found 46503a627eSMilanka Ringwaldremote devices are reported as a part of: 47503a627eSMilanka Ringwald 48503a627eSMilanka Ringwald- HCI_EVENT_INQUIRY_RESULT, 49503a627eSMilanka Ringwald 50503a627eSMilanka Ringwald- HCI_EVENT-_INQUIRY_RESULT_WITH_RSSI, or 51503a627eSMilanka Ringwald 52503a627eSMilanka Ringwald- HCI_EVENT_EXTENDED_INQUIRY_RESPONSE events. 53503a627eSMilanka Ringwald 54503a627eSMilanka RingwaldEach response contains at least the Bluetooth address, the class of device, the page scan 55503a627eSMilanka Ringwaldrepetition mode, and the clock offset of found device. The latter events 56503a627eSMilanka Ringwaldadd information about the received signal strength or provide the 57503a627eSMilanka RingwaldExtended Inquiry Result (EIR). A code snippet is shown in Listing 58503a627eSMilanka Ringwald[below](#lst:DiscoverDevices). 59503a627eSMilanka Ringwald 60503a627eSMilanka Ringwald~~~~ {#lst:DiscoverDevices .c caption="{Discover remote devices.}"} 61503a627eSMilanka Ringwald void print_inquiry_results(uint8_t *packet){ 62503a627eSMilanka Ringwald int event = packet[0]; 63503a627eSMilanka Ringwald int numResponses = hci_event_inquiry_result_get_num_responses(packet); 64503a627eSMilanka Ringwald uint16_t classOfDevice, clockOffset; 65503a627eSMilanka Ringwald uint8_t rssi, pageScanRepetitionMode; 66503a627eSMilanka Ringwald for (i=0; i<numResponses; i++){ 67503a627eSMilanka Ringwald bt_flip_addr(addr, &packet[3+i*6]); 68503a627eSMilanka Ringwald pageScanRepetitionMode = packet [3 + numResponses*6 + i]; 69503a627eSMilanka Ringwald if (event == HCI_EVENT_INQUIRY_RESULT){ 70503a627eSMilanka Ringwald classOfDevice = little_endian_read_24(packet, 3 + numResponses*(6+1+1+1) + i*3); 71503a627eSMilanka Ringwald clockOffset = little_endian_read_16(packet, 3 + numResponses*(6+1+1+1+3) + i*2) & 0x7fff; 72503a627eSMilanka Ringwald rssi = 0; 73503a627eSMilanka Ringwald } else { 74503a627eSMilanka Ringwald classOfDevice = little_endian_read_24(packet, 3 + numResponses*(6+1+1) + i*3); 75503a627eSMilanka Ringwald clockOffset = little_endian_read_16(packet, 3 + numResponses*(6+1+1+3) + i*2) & 0x7fff; 76503a627eSMilanka Ringwald rssi = packet [3 + numResponses*(6+1+1+3+2) + i*1]; 77503a627eSMilanka Ringwald } 78503a627eSMilanka 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); 79503a627eSMilanka Ringwald } 80503a627eSMilanka Ringwald } 81503a627eSMilanka Ringwald 82503a627eSMilanka Ringwald void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){ 83503a627eSMilanka Ringwald ... 84503a627eSMilanka Ringwald switch (event) { 85503a627eSMilanka Ringwald case HCI_STATE_WORKING: 86503a627eSMilanka Ringwald hci_send_cmd(&hci_write_inquiry_mode, 0x01); // with RSSI 87503a627eSMilanka Ringwald break; 88503a627eSMilanka Ringwald case HCI_EVENT_COMMAND_COMPLETE: 89503a627eSMilanka Ringwald if (COMMAND_COMPLETE_EVENT(packet, hci_write_inquiry_mode) ) { 90503a627eSMilanka Ringwald start_scan(); 91503a627eSMilanka Ringwald } 92503a627eSMilanka Ringwald case HCI_EVENT_COMMAND_STATUS: 93503a627eSMilanka Ringwald if (COMMAND_STATUS_EVENT(packet, hci_write_inquiry_mode) ) { 94503a627eSMilanka Ringwald printf("Ignoring error (0x%x) from hci_write_inquiry_mode.\n", packet[2]); 95503a627eSMilanka Ringwald hci_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0); 96503a627eSMilanka Ringwald } 97503a627eSMilanka Ringwald break; 98503a627eSMilanka Ringwald case HCI_EVENT_INQUIRY_RESULT: 99503a627eSMilanka Ringwald case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI: 100503a627eSMilanka Ringwald print_inquiry_results(packet); 101503a627eSMilanka Ringwald break; 102503a627eSMilanka Ringwald ... 103503a627eSMilanka Ringwald } 104503a627eSMilanka Ringwald } 105503a627eSMilanka Ringwald~~~~ 106503a627eSMilanka Ringwald 107503a627eSMilanka RingwaldBy default, neither RSSI values nor EIR are reported. If the Bluetooth 108503a627eSMilanka Ringwalddevice implements Bluetooth Specification 2.1 or higher, the 109503a627eSMilanka Ringwald*hci_write_inquiry_mode* command enables reporting of this advanced 110503a627eSMilanka Ringwaldfeatures (0 for standard results, 1 for RSSI, 2 for RSSI and EIR). 111503a627eSMilanka Ringwald 112503a627eSMilanka RingwaldA complete GAP inquiry example is provided [here](examples/examples/#sec:gapinquiryExample). 113503a627eSMilanka Ringwald 114503a627eSMilanka Ringwald### Pairing of Devices 115503a627eSMilanka Ringwald 116503a627eSMilanka RingwaldBy default, Bluetooth communication is not authenticated, and any device 117503a627eSMilanka Ringwaldcan talk to any other device. A Bluetooth device (for example, cellular 118503a627eSMilanka Ringwaldphone) may choose to require authentication to provide a particular 119503a627eSMilanka Ringwaldservice (for example, a Dial-Up service). The process of establishing 120503a627eSMilanka Ringwaldauthentication is called pairing. Bluetooth provides two mechanism for 121503a627eSMilanka Ringwaldthis. 122503a627eSMilanka Ringwald 123503a627eSMilanka RingwaldOn Bluetooth devices that conform to the Bluetooth v2.0 or older 124503a627eSMilanka Ringwaldspecification, a PIN code (up to 16 bytes ASCII) has to be entered on 125503a627eSMilanka Ringwaldboth sides. This isn’t optimal for embedded systems that do not have 126503a627eSMilanka Ringwaldfull I/O capabilities. To support pairing with older devices using a 127503a627eSMilanka RingwaldPIN, see Listing [below](#lst:PinCodeRequest). 128503a627eSMilanka Ringwald 129503a627eSMilanka Ringwald~~~~ {#lst:PinCodeRequest .c caption="{PIN code request.}"} 130503a627eSMilanka Ringwald void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){ 131503a627eSMilanka Ringwald ... 132503a627eSMilanka Ringwald switch (event) { 133503a627eSMilanka Ringwald case HCI_EVENT_PIN_CODE_REQUEST: 134503a627eSMilanka Ringwald // inform about pin code request 135503a627eSMilanka Ringwald printf("Pin code request - using '0000'\n\r"); 136503a627eSMilanka Ringwald hci_event_pin_code_request_get_bd_addr(packet, bd_addr); 137503a627eSMilanka Ringwald 138503a627eSMilanka Ringwald // baseband address, pin length, PIN: c-string 139503a627eSMilanka Ringwald hci_send_cmd(&hci_pin_code_request_reply, &bd_addr, 4, "0000"); 140503a627eSMilanka Ringwald break; 141503a627eSMilanka Ringwald ... 142503a627eSMilanka Ringwald } 143503a627eSMilanka Ringwald } 144503a627eSMilanka Ringwald~~~~ 145503a627eSMilanka Ringwald 146503a627eSMilanka RingwaldThe Bluetooth v2.1 specification introduces Secure Simple Pairing (SSP), 147503a627eSMilanka Ringwaldwhich is a better approach as it both improves security and is better 148503a627eSMilanka Ringwaldadapted to embedded systems. With SSP, the devices first exchange their 149503a627eSMilanka RingwaldIO Capabilities and then settle on one of several ways to verify that 150503a627eSMilanka Ringwaldthe pairing is legitimate. If the Bluetooth device supports SSP, BTstack 151503a627eSMilanka Ringwaldenables it by default and even automatically accepts SSP pairing 152503a627eSMilanka Ringwaldrequests. Depending on the product in which BTstack is used, this may 153503a627eSMilanka Ringwaldnot be desired and should be replaced with code to interact with the 154503a627eSMilanka Ringwalduser. 155503a627eSMilanka Ringwald 156503a627eSMilanka RingwaldRegardless of the authentication mechanism (PIN/SSP), on success, both 157503a627eSMilanka Ringwalddevices will generate a link key. The link key can be stored either in 158503a627eSMilanka Ringwaldthe Bluetooth module itself or in a persistent storage, see 159503a627eSMilanka Ringwald[here](porting/#sec:persistentStoragePorting). The next time the device connects and 160503a627eSMilanka Ringwaldrequests an authenticated connection, both devices can use the 161503a627eSMilanka Ringwaldpreviously generated link key. Please note that the pairing must be 162503a627eSMilanka Ringwaldrepeated if the link key is lost by one device. 163503a627eSMilanka Ringwald 164503a627eSMilanka Ringwald### Dedicated Bonding 165503a627eSMilanka Ringwald 166503a627eSMilanka RingwaldAside from the regular bonding, Bluetooth also provides the concept of 167503a627eSMilanka Ringwald“dedicated bonding”, where a connection is established for the sole 168503a627eSMilanka Ringwaldpurpose of bonding the device. After the bonding process is over, the 169503a627eSMilanka Ringwaldconnection will be automatically terminated. BTstack supports dedicated 170503a627eSMilanka Ringwaldbonding via the *gap_dedicated_bonding* function. 171503a627eSMilanka Ringwald 172503a627eSMilanka Ringwald## SPP - Serial Port Profile 173503a627eSMilanka Ringwald 174503a627eSMilanka RingwaldThe SPP profile defines how to set up virtual serial ports and connect 175503a627eSMilanka Ringwaldtwo Bluetooth enabled devices. Please keep in mind that a serial port does not 176503a627eSMilanka Ringwaldpreserve packet boundaries if you try to send data as packets and read about 177503a627eSMilanka Ringwald[RFCOMM packet boundaries]({protocols/#sec:noRfcommPacketBoundaries}). 178503a627eSMilanka Ringwald 179503a627eSMilanka Ringwald### Accessing an SPP Server on a remote device 180503a627eSMilanka Ringwald 181503a627eSMilanka RingwaldTo access a remote SPP server, you first need to query the remote device 182503a627eSMilanka Ringwaldfor its SPP services. Section [on querying remote SDP service](#sec:querySDPProtocols) 183503a627eSMilanka Ringwaldshows how to query for all RFCOMM channels. For SPP, you can do the same 184503a627eSMilanka Ringwaldbut use the SPP UUID 0x1101 for the query. After you have identified the 185503a627eSMilanka Ringwaldcorrect RFCOMM channel, you can create an RFCOMM connection as shown 186503a627eSMilanka Ringwald[here](protocols/#sec:rfcommClientProtocols). 187503a627eSMilanka Ringwald 188503a627eSMilanka Ringwald### Providing an SPP Server 189503a627eSMilanka Ringwald 190503a627eSMilanka RingwaldTo provide an SPP Server, you need to provide an RFCOMM service with a 191503a627eSMilanka Ringwaldspecific RFCOMM channel number as explained in section on 192503a627eSMilanka Ringwald[RFCOMM service](protocols/#sec:rfcommServiceProtocols). Then, you need to create 193503a627eSMilanka Ringwaldan SDP record for it and publish it with the SDP server by calling 194503a627eSMilanka Ringwald*sdp_register_service*. BTstack provides the 195503a627eSMilanka Ringwald*spp_create_sdp_record* function in that requires an empty buffer of 196503a627eSMilanka Ringwaldapproximately 200 bytes, the service channel number, and a service name. 197503a627eSMilanka RingwaldHave a look at the [SPP Counter example](examples/examples/#sec:sppcounterExample). 198503a627eSMilanka Ringwald 199503a627eSMilanka Ringwald 200503a627eSMilanka Ringwald## PAN - Personal Area Networking Profile {#sec:panProfiles} 201503a627eSMilanka Ringwald 202503a627eSMilanka Ringwald 203503a627eSMilanka RingwaldThe PAN profile uses BNEP to provide on-demand networking capabilities 204503a627eSMilanka Ringwaldbetween Bluetooth devices. The PAN profile defines the following roles: 205503a627eSMilanka Ringwald 206503a627eSMilanka Ringwald- PAN User (PANU) 207503a627eSMilanka Ringwald 208503a627eSMilanka Ringwald- Network Access Point (NAP) 209503a627eSMilanka Ringwald 210503a627eSMilanka Ringwald- Group Ad-hoc Network (GN) 211503a627eSMilanka Ringwald 212503a627eSMilanka RingwaldPANU is a Bluetooth device that communicates as a client with GN, or 213503a627eSMilanka RingwaldNAP, or with another PANU Bluetooth device, through a point-to-point 214503a627eSMilanka Ringwaldconnection. Either the PANU or the other Bluetooth device may terminate 215503a627eSMilanka Ringwaldthe connection at anytime. 216503a627eSMilanka Ringwald 217503a627eSMilanka RingwaldNAP is a Bluetooth device that provides the service of routing network 218503a627eSMilanka Ringwaldpackets between PANU by using BNEP and the IP routing mechanism. A NAP 219503a627eSMilanka Ringwaldcan also act as a bridge between Bluetooth networks and other network 220503a627eSMilanka Ringwaldtechnologies by using the Ethernet packets. 221503a627eSMilanka Ringwald 222503a627eSMilanka RingwaldThe GN role enables two or more PANUs to interact with each other 223503a627eSMilanka Ringwaldthrough a wireless network without using additional networking hardware. 224503a627eSMilanka RingwaldThe devices are connected in a piconet where the GN acts as a master and 225503a627eSMilanka Ringwaldcommunicates either point-to-point or a point-to-multipoint with a 226503a627eSMilanka Ringwaldmaximum of seven PANU slaves by using BNEP. 227503a627eSMilanka Ringwald 228503a627eSMilanka RingwaldCurrently, BTstack supports only PANU. 229503a627eSMilanka Ringwald 230503a627eSMilanka Ringwald### Accessing a remote PANU service 231503a627eSMilanka Ringwald 232503a627eSMilanka RingwaldTo access a remote PANU service, you first need perform an SDP query to 233503a627eSMilanka Ringwaldget the L2CAP PSM for the requested PANU UUID. With these two pieces of 234503a627eSMilanka Ringwaldinformation, you can connect BNEP to the remote PANU service with the 235503a627eSMilanka Ringwald*bnep_connect* function. The Section on [PANU Demo example](examples/examples/#sec:panudemoExample) 236503a627eSMilanka Ringwaldshows how this is accomplished. 237503a627eSMilanka Ringwald 238503a627eSMilanka Ringwald### Providing a PANU service 239503a627eSMilanka Ringwald 240503a627eSMilanka RingwaldTo provide a PANU service, you need to provide a BNEP service with the 241503a627eSMilanka Ringwaldservice UUID, e.g. the PANU UUID, and a maximal ethernet frame size, 242503a627eSMilanka Ringwaldas explained in Section [on BNEP service](protocols/#sec:bnepServiceProtocols). Then, you need to 243503a627eSMilanka Ringwaldcreate an SDP record for it and publish it with the SDP server by 244503a627eSMilanka Ringwaldcalling *sdp_register_service*. BTstack provides the 245503a627eSMilanka Ringwald*pan_create_panu_sdp_record* function in *src/pan.c* that requires an 246503a627eSMilanka Ringwaldempty buffer of approximately 200 bytes, a description, and a security 247503a627eSMilanka Ringwalddescription. 248503a627eSMilanka Ringwald 249503a627eSMilanka Ringwald## HSP - Headset Profile 250503a627eSMilanka Ringwald 251503a627eSMilanka RingwaldThe HSP profile defines how a Bluetooth-enabled headset should communicate 252503a627eSMilanka Ringwaldwith another Bluetooth enabled device. It relies on SCO for audio encoded 253503a627eSMilanka Ringwaldin 64 kbit/s CVSD and a subset of AT commands from GSM 07.07 for 254503a627eSMilanka Ringwaldminimal controls including the ability to ring, answer a call, hang up and adjust the volume. 255503a627eSMilanka Ringwald 256503a627eSMilanka RingwaldThe HSP defines two roles: 257503a627eSMilanka Ringwald 258503a627eSMilanka Ringwald - Audio Gateway (AG) - a device that acts as the gateway of the audio, typically a mobile phone or PC. 259503a627eSMilanka Ringwald 260503a627eSMilanka Ringwald - Headset (HS) - a device that acts as the AG's remote audio input and output control. 261503a627eSMilanka Ringwald 262503a627eSMilanka RingwaldThere are following restrictions: 263503a627eSMilanka Ringwald- The CVSD is used for audio transmission. 264503a627eSMilanka Ringwald 265503a627eSMilanka Ringwald- Between headset and audio gateway, only one audio connection at a time is supported. 266503a627eSMilanka Ringwald 267503a627eSMilanka Ringwald- The profile offers only basic interoperability – for example, handling of multiple calls at the audio gateway is not included. 268503a627eSMilanka Ringwald 269503a627eSMilanka Ringwald- The only assumption on the headset’s user interface is the possibility to detect a user initiated action (e.g. pressing a button). 270503a627eSMilanka Ringwald 271503a627eSMilanka Ringwald%TODO: audio paths 272503a627eSMilanka Ringwald 273503a627eSMilanka Ringwald 274503a627eSMilanka Ringwald## HFP - Hands-Free Profile 275503a627eSMilanka Ringwald 276503a627eSMilanka 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. 277503a627eSMilanka 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 278503a627eSMilanka 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. 279503a627eSMilanka Ringwald 280503a627eSMilanka RingwaldThe HFP defines two roles: 281503a627eSMilanka Ringwald 282503a627eSMilanka Ringwald- Audio Gateway (AG) – a device that acts as the gateway of the audio,, typically a mobile phone. 283503a627eSMilanka Ringwald 284503a627eSMilanka Ringwald- Hands-Free Unit (HF) – a device that acts as the AG's remote audio input and output control. 285503a627eSMilanka Ringwald 28693ffa3acSMilanka Ringwald### Supported Features 28793ffa3acSMilanka Ringwald 28893ffa3acSMilanka RingwaldThe supported features define the HFP capabilities of the device. The enumeration unfortunately differs between HF and AG sides. 28993ffa3acSMilanka Ringwald 29093ffa3acSMilanka 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. 29193ffa3acSMilanka Ringwald 29293ffa3acSMilanka 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. 29393ffa3acSMilanka Ringwald 29493ffa3acSMilanka Ringwald| Define for AG Supported Feature | Description | 29593ffa3acSMilanka Ringwald| --------------------------------------- | ---------------------------- | 29693ffa3acSMilanka Ringwald| HFP_AGSF_THREE_WAY_CALLING | Three-way calling | 29793ffa3acSMilanka Ringwald| HFP_AGSF_EC_NR_FUNCTION | Echo Canceling and/or Noise Reduction function | 29893ffa3acSMilanka Ringwald| HFP_AGSF_VOICE_RECOGNITION_FUNCTION | Voice recognition function | 29993ffa3acSMilanka Ringwald| HFP_AGSF_IN_BAND_RING_TONE | In-band ring tone capability | 30093ffa3acSMilanka Ringwald| HFP_AGSF_ATTACH_A_NUMBER_TO_A_VOICE_TAG | Attach a number to a voice tag | 30193ffa3acSMilanka Ringwald| HFP_AGSF_ABILITY_TO_REJECT_A_CALL | Ability to reject a call | 30293ffa3acSMilanka Ringwald| HFP_AGSF_ENHANCED_CALL_STATUS | Enhanced call status | 30393ffa3acSMilanka Ringwald| HFP_AGSF_ENHANCED_CALL_CONTROL | Enhanced call control | 30493ffa3acSMilanka Ringwald| HFP_AGSF_EXTENDED_ERROR_RESULT_CODES | Extended Error Result Codes | 30593ffa3acSMilanka Ringwald| HFP_AGSF_CODEC_NEGOTIATION | Codec negotiation | 30693ffa3acSMilanka Ringwald| HFP_AGSF_HF_INDICATORS | HF Indicators | 30793ffa3acSMilanka Ringwald| HFP_AGSF_ESCO_S4 | eSCO S4 (and T2) Settings Supported | 30893ffa3acSMilanka Ringwald| HFP_AGSF_ENHANCED_VOICE_RECOGNITION_STATUS | Enhanced voice recognition status | 30993ffa3acSMilanka Ringwald| HFP_AGSF_VOICE_RECOGNITION_TEXT | Voice recognition text | 31093ffa3acSMilanka Ringwald 31193ffa3acSMilanka Ringwald 31293ffa3acSMilanka Ringwald| Define for HF Supported Feature | Description | 31393ffa3acSMilanka Ringwald| --------------------------------------- | ---------------------------- | 31493ffa3acSMilanka Ringwald| HFP_HFSF_THREE_WAY_CALLING | Three-way calling | 31593ffa3acSMilanka Ringwald| HFP_HFSF_EC_NR_FUNCTION | Echo Canceling and/or Noise Reduction function | 31693ffa3acSMilanka Ringwald| HFP_HFSF_CLI_PRESENTATION_CAPABILITY | CLI presentation capability | 31793ffa3acSMilanka Ringwald| HFP_HFSF_VOICE_RECOGNITION_FUNCTION | Voice recognition function | 31893ffa3acSMilanka Ringwald| HFP_HFSF_REMOTE_VOLUME_CONTROL | Remote volume control | 31993ffa3acSMilanka Ringwald| HFP_HFSF_ATTACH_A_NUMBER_TO_A_VOICE_TAG | Attach a number to a voice tag | 32093ffa3acSMilanka Ringwald| HFP_HFSF_ENHANCED_CALL_STATUS | Enhanced call status | 32193ffa3acSMilanka Ringwald| HFP_HFSF_ENHANCED_CALL_CONTROL | Enhanced call control | 32293ffa3acSMilanka Ringwald| HFP_HFSF_CODEC_NEGOTIATION | Codec negotiation | 32393ffa3acSMilanka Ringwald| HFP_HFSF_HF_INDICATORS | HF Indicators | 32493ffa3acSMilanka Ringwald| HFP_HFSF_ESCO_S4 | eSCO S4 (and T2) Settings Supported | 32593ffa3acSMilanka Ringwald| HFP_HFSF_ENHANCED_VOICE_RECOGNITION_STATUS | Enhanced voice recognition status | 32693ffa3acSMilanka Ringwald| HFP_HFSF_VOICE_RECOGNITION_TEXT | Voice recognition text | 32793ffa3acSMilanka Ringwald 32893ffa3acSMilanka Ringwald 32993ffa3acSMilanka Ringwald### Audio Voice Recognition Activation 33093ffa3acSMilanka Ringwald 331543e856bSMilanka RingwaldAudio voice recognition (AVR) requires that HF and AG have the following features enabled: 332*9b78c3deSMilanka Ringwald 33393ffa3acSMilanka Ringwald- HF: HFP_HFSF_VOICE_RECOGNITION_FUNCTION and 334*9b78c3deSMilanka Ringwald 33593ffa3acSMilanka Ringwald- AG: HFP_AGSF_VOICE_RECOGNITION_FUNCTION. 33693ffa3acSMilanka Ringwald 33793ffa3acSMilanka RingwaldIt can be activated or deactivated on both sides by calling: 33893ffa3acSMilanka Ringwald 33993ffa3acSMilanka Ringwald // AG 34093ffa3acSMilanka Ringwald uint8_t hfp_ag_activate_voice_recognition(hci_con_handle_t acl_handle); 34193ffa3acSMilanka Ringwald uint8_t hfp_ag_deactivate_voice_recognition(hci_con_handle_t acl_handle); 34293ffa3acSMilanka Ringwald 34393ffa3acSMilanka Ringwald // HF 34493ffa3acSMilanka Ringwald uint8_t hfp_hf_activate_voice_recognition(hci_con_handle_t acl_handle); 34593ffa3acSMilanka Ringwald uint8_t hfp_hf_deactivate_voice_recognition(hci_con_handle_t acl_handle); 34693ffa3acSMilanka Ringwald 34793ffa3acSMilanka RingwaldOn either activation change, the HFP_SUBEVENT_VOICE_RECOGNITION_STATUS event will be emitted with status field set to ERROR_CODE_SUCCESS on success. The state field of this event indicates the current voice recognition state : 0 - if deactivated, 1 - if activated. 34893ffa3acSMilanka Ringwald 34993ffa3acSMilanka 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. 35093ffa3acSMilanka Ringwald 35193ffa3acSMilanka Ringwald| Use cases | Expected behavior | 35293ffa3acSMilanka Ringwald|--------------------------------------------------------|---------------------| 35393ffa3acSMilanka Ringwald| No previous audio connection, AVR activated then deactivated | Audio connection will be opened by AG upon AVR activation, and upon AVR deactivation closed| 35493ffa3acSMilanka Ringwald| AVR activated and deactivated during existing audio connection | Audio remains active upon AVR deactivation | 355543e856bSMilanka Ringwald| Call to close audio connection during active AVR session | The audio connection shut down will be refused | 356543e856bSMilanka Ringwald| AVR activated, but audio connection failed to be established | AVR will stay activated | 35793ffa3acSMilanka Ringwald 35893ffa3acSMilanka 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. 35993ffa3acSMilanka Ringwald 36093ffa3acSMilanka Ringwald### Enhanced Audio Voice Recognition 361503a627eSMilanka Ringwald 362543e856bSMilanka RingwaldSimilarly to AVR, Enhanced Audio voice recognition (eAVR) requires that HF and AG have the following features enabled: 363*9b78c3deSMilanka Ringwald 364543e856bSMilanka Ringwald- HF: HFP_HFSF_ENHANCED_VOICE_RECOGNITION_STATUS and 365*9b78c3deSMilanka Ringwald 366543e856bSMilanka Ringwald- AG: HFP_AGSF_ENHANCED_VOICE_RECOGNITION_STATUS. 367543e856bSMilanka Ringwald 368543e856bSMilanka 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: 369*9b78c3deSMilanka Ringwald 370543e856bSMilanka Ringwald- HF: HFP_HFSF_VOICE_RECOGNITION_TEXT and 371*9b78c3deSMilanka Ringwald 372543e856bSMilanka Ringwald- AG: HFP_AGSF_VOICE_RECOGNITION_TEXT. 373543e856bSMilanka Ringwald 374543e856bSMilanka RingwaldeAVR implements the same use cases as AVR (see previous section). It can be activated or deactivated on both sides by calling: 375543e856bSMilanka Ringwald 376543e856bSMilanka Ringwald // AG 377543e856bSMilanka Ringwald uint8_t hfp_ag_enhanced_voice_recognition_activate(hci_con_handle_t acl_handle); 378543e856bSMilanka Ringwald uint8_t hfp_ag_enhanced_voice_recognition_deactivate(hci_con_handle_t acl_handle); 379543e856bSMilanka Ringwald 380543e856bSMilanka Ringwald // HF 381543e856bSMilanka Ringwald uint8_t hfp_hf_enhanced_voice_recognition_activate(hci_con_handle_t acl_handle); 382543e856bSMilanka Ringwald uint8_t hfp_hf_enhanced_voice_recognition_deactivate(hci_con_handle_t acl_handle); 383543e856bSMilanka Ringwald 384543e856bSMilanka RingwaldWhen eAVR and audio channel are established there are several additional commands that can be sent: 385543e856bSMilanka Ringwald 386543e856bSMilanka Ringwald| HFP Role | eVRA API | Description | 387543e856bSMilanka Ringwald-----------|----------|-------------| 388543e856bSMilanka Ringwald|HF | hfp_hf_enhanced_voice_recognition_report_ready_for_audio| Ready to accept audio input. | 389543e856bSMilanka Ringwald|AG | hfp_ag_enhanced_voice_recognition_report_ready_for_audio | Voice recognition engine is ready to accept audio input. | 390543e856bSMilanka Ringwald|AG | hfp_ag_enhanced_voice_recognition_report_sending_audio | The voice recognition engine will play a sound, e.g. starting sound. | 391543e856bSMilanka Ringwald|AG | hfp_ag_enhanced_voice_recognition_report_processing_input | Voice recognition engine is processing the audio input. | 392543e856bSMilanka Ringwald|AG | hfp_ag_enhanced_voice_recognition_send_message | Report textual representation from the voice recognition engine. | 393543e856bSMilanka Ringwald 394543e856bSMilanka Ringwald 395503a627eSMilanka Ringwald## HID - Human-Interface Device Profile 396503a627eSMilanka Ringwald 397503a627eSMilanka RingwaldThe HID profile allows an HID Host to connect to one or more HID Devices and communicate with them. 398503a627eSMilanka RingwaldExamples of Bluetooth HID devices are keyboards, mice, joysticks, gamepads, remote controls, and also voltmeters and temperature sensors. 399503a627eSMilanka RingwaldTypical HID hosts would be a personal computer, tablets, gaming console, industrial machine, or data-recording device. 400503a627eSMilanka Ringwald 401503a627eSMilanka RingwaldPlease refer to: 402503a627eSMilanka Ringwald 403503a627eSMilanka Ringwald- [HID Host API](appendix/apis/#sec:hidHostAPIAppendix) and [hid_host_demo](examples/examples/#sec:hidhostdemoExample) for the HID Host role 404503a627eSMilanka Ringwald 405503a627eSMilanka 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. 406503a627eSMilanka Ringwald 407503a627eSMilanka Ringwald 408503a627eSMilanka Ringwald## GAP LE - Generic Access Profile for Low Energy 409503a627eSMilanka Ringwald 410503a627eSMilanka Ringwald 411503a627eSMilanka RingwaldAs with GAP for Classic, the GAP LE profile defines how to discover and 412503a627eSMilanka Ringwaldhow to connect to a Bluetooth Low Energy device. There are several GAP 413503a627eSMilanka Ringwaldroles that a Bluetooth device can take, but the most important ones are 414503a627eSMilanka Ringwaldthe Central and the Peripheral role. Peripheral devices are those that 415503a627eSMilanka Ringwaldprovide information or can be controlled. Central devices are those that 416503a627eSMilanka Ringwaldconsume information or control the peripherals. Before the connection 417503a627eSMilanka Ringwaldcan be established, devices are first going through an advertising 418503a627eSMilanka Ringwaldprocess. 419503a627eSMilanka Ringwald 420503a627eSMilanka Ringwald### Private addresses. 421503a627eSMilanka Ringwald 422503a627eSMilanka RingwaldTo better protect privacy, an LE device can choose to use a private i.e. 423503a627eSMilanka Ringwaldrandom Bluetooth address. This address changes at a user-specified rate. 424503a627eSMilanka RingwaldTo allow for later reconnection, the central and peripheral devices will 425503a627eSMilanka Ringwaldexchange their Identity Resolving Keys (IRKs) during bonding. The IRK is 426503a627eSMilanka Ringwaldused to verify if a new address belongs to a previously bonded device. 427503a627eSMilanka Ringwald 428503a627eSMilanka RingwaldTo toggle privacy mode using private addresses, call the 429503a627eSMilanka Ringwald*gap_random_address_set_mode* function. The update period can be set 430503a627eSMilanka Ringwaldwith *gap_random_address_set_update_period*. 431503a627eSMilanka Ringwald 432503a627eSMilanka RingwaldAfter a connection is established, the Security Manager will try to 433503a627eSMilanka Ringwaldresolve the peer Bluetooth address as explained in Section on 434503a627eSMilanka Ringwald[SMP](protocols/#sec:smpProtocols). 435503a627eSMilanka Ringwald 436503a627eSMilanka Ringwald### Advertising and Discovery 437503a627eSMilanka Ringwald 438503a627eSMilanka RingwaldAn LE device is discoverable and connectable, only if it periodically 439503a627eSMilanka Ringwaldsends out Advertisements. An advertisement contains up to 31 bytes of 440503a627eSMilanka Ringwalddata. To configure and enable advertisement broadcast, the following GAP 441503a627eSMilanka Ringwaldfunctions can be used: 442503a627eSMilanka Ringwald 443503a627eSMilanka Ringwald- *gap_advertisements_set_data* 444503a627eSMilanka Ringwald 445503a627eSMilanka Ringwald- *gap_advertisements_set_params* 446503a627eSMilanka Ringwald 447503a627eSMilanka Ringwald- *gap_advertisements_enable* 448503a627eSMilanka Ringwald 449503a627eSMilanka RingwaldIn addition to the Advertisement data, a device in the peripheral role 450503a627eSMilanka Ringwaldcan also provide Scan Response data, which has to be explicitly queried 451503a627eSMilanka Ringwaldby the central device. It can be set with *gap_scan_response_set_data*. 452503a627eSMilanka Ringwald 453503a627eSMilanka RingwaldPlease have a look at the [SPP and LE 454503a627eSMilanka RingwaldCounter example](examples/examples/#sec:sppandlecounterExample). 455503a627eSMilanka Ringwald 456503a627eSMilanka RingwaldThe scan parameters can be set with 457503a627eSMilanka Ringwald*gap_set_scan_parameters*. The scan can be started/stopped 458503a627eSMilanka Ringwaldwith *gap_start_scan*/*gap_stop_scan*. 459503a627eSMilanka Ringwald 460503a627eSMilanka RingwaldFinally, if a suitable device is found, a connection can be initiated by 461503a627eSMilanka Ringwaldcalling *gap_connect*. In contrast to Bluetooth classic, there 462503a627eSMilanka Ringwaldis no timeout for an LE connection establishment. To cancel such an 463503a627eSMilanka Ringwaldattempt, *gap_connect_cancel* has be be called. 464503a627eSMilanka Ringwald 465503a627eSMilanka RingwaldBy default, a Bluetooth device stops sending Advertisements when it gets 466503a627eSMilanka Ringwaldinto the Connected state. However, it does not start broadcasting 467503a627eSMilanka Ringwaldadvertisements on disconnect again. To re-enable it, please send the 468503a627eSMilanka Ringwald*hci_le_set_advertise_enable* again . 469503a627eSMilanka Ringwald 470503a627eSMilanka Ringwald## GATT Client {#sec:GATTClientProfiles} 471503a627eSMilanka Ringwald 472503a627eSMilanka RingwaldThe GATT profile uses ATT Attributes to represent a hierarchical 473503a627eSMilanka Ringwaldstructure of GATT Services and GATT Characteristics. Each Service has 474503a627eSMilanka Ringwaldone or more Characteristics. Each Characteristic has meta data attached 475503a627eSMilanka Ringwaldlike its type or its properties. This hierarchy of Characteristics and 476503a627eSMilanka RingwaldServices are queried and modified via ATT operations. 477503a627eSMilanka Ringwald 478503a627eSMilanka RingwaldGATT defines both a server and a client role. A device can implement one 479503a627eSMilanka Ringwaldor both GATT roles. 480503a627eSMilanka Ringwald 481503a627eSMilanka RingwaldThe GATT Client is used to discover services, characteristics 482503a627eSMilanka Ringwaldand their descriptors on a peer device. It allows to subscribe for 483503a627eSMilanka Ringwaldnotifications or indications that the characteristic on the GATT server 484503a627eSMilanka Ringwaldhas changed its value. 485503a627eSMilanka Ringwald 486503a627eSMilanka RingwaldTo perform GATT queries, it provides a rich interface. Before calling 487503a627eSMilanka Ringwaldqueries, the GATT client must be initialized with *gatt_client_init* 488503a627eSMilanka Ringwaldonce. 489503a627eSMilanka Ringwald 490503a627eSMilanka RingwaldTo allow for modular profile implementations, GATT client can be used 491503a627eSMilanka Ringwaldindependently by multiple entities. 492503a627eSMilanka Ringwald 493503a627eSMilanka RingwaldAfter an LE connection was created using the GAP LE API, you can query 494503a627eSMilanka Ringwaldfor the connection MTU with *gatt_client_get_mtu*. 495503a627eSMilanka Ringwald 496503a627eSMilanka RingwaldMultiple GATT queries to the same GATT Server cannot be interleaved. 497503a627eSMilanka RingwaldTherefore, you can either use a state machine or similar to perform the 498503a627eSMilanka Ringwaldqueries in sequence, or you can check if you can perform a GATT query 499503a627eSMilanka Ringwaldon a particular connection right now using 500503a627eSMilanka Ringwald*gatt_client_is_ready*, and retry later if it is not ready. 501503a627eSMilanka RingwaldAs a result to a GATT query, zero to many 502503a627eSMilanka Ringwald*GATT_EVENT_X*s are returned before a *GATT_EVENT_QUERY_COMPLETE* event 503503a627eSMilanka Ringwaldcompletes the query. 504503a627eSMilanka Ringwald 505503a627eSMilanka RingwaldFor more details on the available GATT queries, please consult 506503a627eSMilanka Ringwald[GATT Client API](#sec:gattClientAPIAppendix). 507503a627eSMilanka Ringwald 508503a627eSMilanka Ringwald### Authentication 509503a627eSMilanka Ringwald 510503a627eSMilanka RingwaldBy default, the GATT Server is responsible for security and the GATT Client does not enforce any kind of authentication. 511503a627eSMilanka RingwaldIf the GATT Client accesses Characteristic that require encrytion or authentication, the remote GATT Server will return an error, 512503a627eSMilanka Ringwaldwhich is returned in the *att status* of the *GATT_EVENT_QUERY_COMPLETE*. 513503a627eSMilanka Ringwald 514503a627eSMilanka RingwaldYou can define *ENABLE_GATT_CLIENT_PAIRING* to instruct the GATT Client to trigger pairing in this case and to repeat the request. 515503a627eSMilanka Ringwald 516503a627eSMilanka RingwaldThis model allows for an attacker to spoof another device, but don't require authentication for the Characteristics. 517503a627eSMilanka RingwaldAs a first improvement, you can define *ENABLE_LE_PROACTIVE_AUTHENTICATION* in *btstack_config.h*. When defined, the GATT Client will 518503a627eSMilanka Ringwaldrequest the Security Manager to re-encrypt the connection if there is stored bonding information available. 519503a627eSMilanka RingwaldIf this fails, the *GATT_EVENT_QUERY_COMPLETE* will return with the att status *ATT_ERROR_BONDING_INFORMATION_MISSING*. 520503a627eSMilanka Ringwald 521503a627eSMilanka RingwaldWith *ENABLE_LE_PROACTIVE_AUTHENTICATION* defined and in Central role, you need to delete the local bonding information if the remote 522503a627eSMilanka Ringwaldlost its bonding information, e.g. because of a device reset. See *example/sm_pairing_central.c*. 523503a627eSMilanka Ringwald 524503a627eSMilanka RingwaldEven with the Proactive Authentication, your device may still connect to an attacker that provides the same advertising data as 525503a627eSMilanka Ringwaldyour actual device. If the device that you want to connect requires pairing, you can instruct the GATT Client to automatically 526503a627eSMilanka Ringwaldrequest an encrypted connection before sending any GATT Client request by calling *gatt_client_set_required_security_level()*. 527503a627eSMilanka RingwaldIf the device provides sufficient IO capabilities, a MITM attack can then be prevented. We call this 'Mandatory Authentication'. 528503a627eSMilanka Ringwald 529503a627eSMilanka RingwaldThe following diagrams provide a detailed overview about the GATT Client security mechanisms in different configurations: 530503a627eSMilanka Ringwald 531503a627eSMilanka Ringwald- [Reactive Authentication as Central](picts/gatt_client_security_reactive_authentication_central.svg) 532503a627eSMilanka Ringwald- [Reactive Authentication as Peripheral](picts/gatt_client_security_reactive_authentication_peripheral.svg) 533503a627eSMilanka Ringwald- [Proactive Authentication as Central](picts/gatt_client_security_proactive_authentication_central.svg) 534503a627eSMilanka Ringwald- [Proactive Authentication as Peripheral](picts/gatt_client_security_proactive_authentication_peripheral.svg) 535503a627eSMilanka Ringwald- [Mandatory Authentication as Central](picts/gatt_client_security_mandatory_authentication_central.svg) 536503a627eSMilanka Ringwald- [Mandatory Authentication as Peripheral](picts/gatt_client_security_mandatory_authentication_peripheral.svg) 537503a627eSMilanka Ringwald 538503a627eSMilanka Ringwald## GATT Server {#sec:GATTServerProfiles} 539503a627eSMilanka Ringwald 540503a627eSMilanka RingwaldThe GATT server stores data and accepts GATT client requests, commands 541503a627eSMilanka Ringwaldand confirmations. The GATT server sends responses to requests and when 542503a627eSMilanka Ringwaldconfigured, sends indication and notifications asynchronously to the 543503a627eSMilanka RingwaldGATT client. 544503a627eSMilanka Ringwald 545503a627eSMilanka RingwaldTo save on both code space and memory, BTstack does not provide a GATT 546503a627eSMilanka RingwaldServer implementation. Instead, a textual description of the GATT 547503a627eSMilanka Ringwaldprofile is directly converted into a compact internal ATT Attribute 548503a627eSMilanka Ringwalddatabase by a GATT profile compiler. The ATT protocol server - 549503a627eSMilanka Ringwaldimplemented by and - answers incoming ATT requests based on information 550503a627eSMilanka Ringwaldprovided in the compiled database and provides read- and write-callbacks 551503a627eSMilanka Ringwaldfor dynamic attributes. 552503a627eSMilanka Ringwald 553503a627eSMilanka RingwaldGATT profiles are defined by a simple textual comma separated value 554503a627eSMilanka Ringwald(.csv) representation. While the description is easy to read and edit, 555503a627eSMilanka Ringwaldit is compact and can be placed in ROM. 556503a627eSMilanka Ringwald 557503a627eSMilanka RingwaldThe current format is shown in Listing [below](#lst:GATTServerProfile). 558503a627eSMilanka Ringwald 559503a627eSMilanka Ringwald~~~~ {#lst:GATTServerProfile .c caption="{GATT profile.}"} 560503a627eSMilanka Ringwald // import service_name 561503a627eSMilanka Ringwald #import <service_name.gatt> 562503a627eSMilanka Ringwald 563503a627eSMilanka Ringwald PRIMARY_SERVICE, {SERVICE_UUID} 564503a627eSMilanka Ringwald CHARACTERISTIC, {ATTRIBUTE_TYPE_UUID}, {PROPERTIES}, {VALUE} 565503a627eSMilanka Ringwald CHARACTERISTIC, {ATTRIBUTE_TYPE_UUID}, {PROPERTIES}, {VALUE} 566503a627eSMilanka Ringwald ... 567503a627eSMilanka Ringwald PRIMARY_SERVICE, {SERVICE_UUID} 568503a627eSMilanka Ringwald CHARACTERISTIC, {ATTRIBUTE_TYPE_UUID}, {PROPERTIES}, {VALUE} 569503a627eSMilanka Ringwald ... 570503a627eSMilanka Ringwald~~~~ 571503a627eSMilanka Ringwald 572503a627eSMilanka RingwaldUUIDs are either 16 bit (1800) or 128 bit 573503a627eSMilanka Ringwald(00001234-0000-1000-8000-00805F9B34FB). 574503a627eSMilanka Ringwald 575503a627eSMilanka RingwaldValue can either be a string (“this is a string”), or, a sequence of hex 576503a627eSMilanka Ringwaldbytes (e.g. 01 02 03). 577503a627eSMilanka Ringwald 578503a627eSMilanka RingwaldProperties can be a list of properties combined using '|' 579503a627eSMilanka Ringwald 580503a627eSMilanka RingwaldReads/writes to a Characteristic that is defined with the DYNAMIC flag, 581503a627eSMilanka Ringwaldare forwarded to the application via callback. Otherwise, the 582503a627eSMilanka RingwaldCharacteristics cannot be written and it will return the specified 583503a627eSMilanka Ringwaldconstant value. 584503a627eSMilanka Ringwald 585503a627eSMilanka RingwaldAdding NOTIFY and/or INDICATE automatically creates an addition Client 586503a627eSMilanka RingwaldConfiguration Characteristic. 587503a627eSMilanka Ringwald 588503a627eSMilanka RingwaldProperty | Meaning 589503a627eSMilanka Ringwald------------------------|----------------------------------------------- 590503a627eSMilanka RingwaldREAD | Characteristic can be read 591503a627eSMilanka RingwaldWRITE | Characteristic can be written using Write Request 592503a627eSMilanka RingwaldWRITE_WITHOUT_RESPONSE | Characteristic can be written using Write Command 593503a627eSMilanka RingwaldNOTIFY | Characteristic allows notifications by server 594503a627eSMilanka RingwaldINDICATE | Characteristic allows indication by server 595503a627eSMilanka RingwaldDYNAMIC | Read or writes to Characteristic are handled by application 596503a627eSMilanka Ringwald 597503a627eSMilanka RingwaldTo require encryption or authentication before a Characteristic can be 598503a627eSMilanka Ringwaldaccessed, you can add one or more of the following properties: 599503a627eSMilanka Ringwald 600503a627eSMilanka RingwaldProperty | Meaning 601503a627eSMilanka Ringwald------------------------|----------------------------------------------- 602503a627eSMilanka RingwaldAUTHENTICATION_REQUIRED | Read and Write operations require Authentication 603503a627eSMilanka RingwaldREAD_ENCRYPTED | Read operations require Encryption 604503a627eSMilanka RingwaldREAD_AUTHENTICATED | Read operations require Authentication 605503a627eSMilanka RingwaldWRITE_ENCRYPTED | Write operations require Encryption 606503a627eSMilanka RingwaldWRITE_AUTHENTICATED | Write operations require Authentication 607503a627eSMilanka RingwaldENCRYPTION_KEY_SIZE_X | Require encryption size >= X, with W in [7..16] 608503a627eSMilanka Ringwald 609503a627eSMilanka RingwaldTo use already implemented GATT Services, you can import it 610503a627eSMilanka Ringwaldusing the *#import <service_name.gatt>* command. See [list of provided services](gatt_services.md). 611503a627eSMilanka Ringwald 612503a627eSMilanka RingwaldBTstack only provides an ATT Server, while the GATT Server logic is 613503a627eSMilanka Ringwaldmainly provided by the GATT compiler. While GATT identifies 614503a627eSMilanka RingwaldCharacteristics by UUIDs, ATT uses Handles (16 bit values). To allow to 615503a627eSMilanka Ringwaldidentify a Characteristic without hard-coding the attribute ID, the GATT 616503a627eSMilanka Ringwaldcompiler creates a list of defines in the generated \*.h file. 617503a627eSMilanka Ringwald 618503a627eSMilanka RingwaldSimilar to other protocols, it might be not possible to send any time. 619503a627eSMilanka RingwaldTo send a Notification, you can call *att_server_request_can_send_now* 620503a627eSMilanka Ringwaldto receive a ATT_EVENT_CAN_SEND_NOW event. 621503a627eSMilanka Ringwald 622503a627eSMilanka RingwaldIf your application cannot handle an ATT Read Request in the *att_read_callback* 623503a627eSMilanka Ringwaldin some situations, you can enable support for this by adding ENABLE_ATT_DELAYED_RESPONSE 624503a627eSMilanka Ringwaldto *btstack_config.h*. Now, you can store the requested attribute handle and return 625503a627eSMilanka Ringwald*ATT_READ_RESPONSE_PENDING* instead of the length of the provided data when you don't have the data ready. 626503a627eSMilanka RingwaldFor ATT operations that read more than one attribute, your *att_read_callback* 627503a627eSMilanka Ringwaldmight get called multiple times as well. To let you know that all necessary 628503a627eSMilanka Ringwaldattribute handles have been 'requested' by the *att_server*, you'll get a final 629503a627eSMilanka Ringwald*att_read_callback* with the attribute handle of *ATT_READ_RESPONSE_PENDING*. 630503a627eSMilanka RingwaldWhen you've got the data for all requested attributes ready, you can call 631503a627eSMilanka Ringwald*att_server_response_ready*, which will trigger processing of the current request. 632503a627eSMilanka RingwaldPlease keep in mind that there is only one active ATT operation and that it has a 30 second 633503a627eSMilanka Ringwaldtimeout after which the ATT server is considered defunct by the GATT Client. 634503a627eSMilanka Ringwald 635503a627eSMilanka Ringwald### Implementing Standard GATT Services {#sec:GATTStandardServices} 636503a627eSMilanka Ringwald 637503a627eSMilanka RingwaldImplementation of a standard GATT Service consists of the following 4 steps: 638503a627eSMilanka Ringwald 639503a627eSMilanka Ringwald 1. Identify full Service Name 640503a627eSMilanka Ringwald 2. Use Service Name to fetch XML definition at Bluetooth SIG site and convert into generic .gatt file 641503a627eSMilanka Ringwald 3. Edit .gatt file to set constant values and exclude unwanted Characteristics 642503a627eSMilanka Ringwald 4. Implement Service server, e.g., battery_service_server.c 643503a627eSMilanka Ringwald 644503a627eSMilanka RingwaldStep 1: 645503a627eSMilanka Ringwald 646503a627eSMilanka RingwaldTo facilitate the creation of .gatt files for standard profiles defined by the Bluetooth SIG, 647503a627eSMilanka Ringwaldthe *tool/convert_gatt_service.py* script can be used. When run without a parameter, it queries the 648503a627eSMilanka RingwaldBluetooth SIG website and lists the available Services by their Specification Name, e.g., 649503a627eSMilanka Ringwald*org.bluetooth.service.battery_service*. 650503a627eSMilanka Ringwald 651503a627eSMilanka Ringwald $ tool/convert_gatt_service.py 652503a627eSMilanka Ringwald Fetching list of services from https://www.bluetooth.com/specifications/gatt/services 653503a627eSMilanka Ringwald 654503a627eSMilanka Ringwald Specification Type | Specification Name | UUID 655503a627eSMilanka Ringwald -------------------------------------------------------+-------------------------------+----------- 656503a627eSMilanka Ringwald org.bluetooth.service.alert_notification | Alert Notification Service | 0x1811 657503a627eSMilanka Ringwald org.bluetooth.service.automation_io | Automation IO | 0x1815 658503a627eSMilanka Ringwald org.bluetooth.service.battery_service | Battery Service | 0x180F 659503a627eSMilanka Ringwald ... 660503a627eSMilanka Ringwald org.bluetooth.service.weight_scale | Weight Scale | 0x181D 661503a627eSMilanka Ringwald 662503a627eSMilanka Ringwald To convert a service into a .gatt file template, please call the script again with the requested Specification Type and the output file name 663503a627eSMilanka Ringwald Usage: tool/convert_gatt_service.py SPECIFICATION_TYPE [service_name.gatt] 664503a627eSMilanka Ringwald 665503a627eSMilanka RingwaldStep 2: 666503a627eSMilanka Ringwald 667503a627eSMilanka RingwaldTo convert service into .gatt file, call *tool/convert_gatt_service.py with the requested Specification Type and the output file name. 668503a627eSMilanka Ringwald 669503a627eSMilanka Ringwald $ tool/convert_gatt_service.py org.bluetooth.service.battery_service battery_service.gatt 670503a627eSMilanka Ringwald Fetching org.bluetooth.service.battery_service from 671503a627eSMilanka Ringwald https://www.bluetooth.com/api/gatt/xmlfile?xmlFileName=org.bluetooth.service.battery_service.xml 672503a627eSMilanka Ringwald 673503a627eSMilanka Ringwald Service Battery Service 674503a627eSMilanka Ringwald - Characteristic Battery Level - properties ['Read', 'Notify'] 675503a627eSMilanka Ringwald -- Descriptor Characteristic Presentation Format - TODO: Please set values 676503a627eSMilanka Ringwald -- Descriptor Client Characteristic Configuration 677503a627eSMilanka Ringwald 678503a627eSMilanka Ringwald Service successfully converted into battery_service.gatt 679503a627eSMilanka Ringwald Please check for TODOs in the .gatt file 680503a627eSMilanka Ringwald 681503a627eSMilanka Ringwald 682503a627eSMilanka RingwaldStep 3: 683503a627eSMilanka Ringwald 684503a627eSMilanka RingwaldIn most cases, you will need to customize the .gatt file. Please pay attention to the tool output and have a look 685503a627eSMilanka Ringwaldat the generated .gatt file. 686503a627eSMilanka Ringwald 687503a627eSMilanka RingwaldE.g. in the generated .gatt file for the Battery Service 688503a627eSMilanka Ringwald 689503a627eSMilanka Ringwald // Specification Type org.bluetooth.service.battery_service 690503a627eSMilanka Ringwald // https://www.bluetooth.com/api/gatt/xmlfile?xmlFileName=org.bluetooth.service.battery_service.xml 691503a627eSMilanka Ringwald 692503a627eSMilanka Ringwald // Battery Service 180F 693503a627eSMilanka Ringwald PRIMARY_SERVICE, ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE 694503a627eSMilanka Ringwald CHARACTERISTIC, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL, DYNAMIC | READ | NOTIFY, 695503a627eSMilanka Ringwald // TODO: Characteristic Presentation Format: please set values 696503a627eSMilanka Ringwald #TODO CHARACTERISTIC_FORMAT, READ, _format_, _exponent_, _unit_, _name_space_, _description_ 697503a627eSMilanka Ringwald CLIENT_CHARACTERISTIC_CONFIGURATION, READ | WRITE, 698503a627eSMilanka Ringwald 699503a627eSMilanka Ringwaldyou could delete the line regarding the CHARACTERISTIC_FORMAT, since it's not required if there is a single instance of the service. 700503a627eSMilanka RingwaldPlease compare the .gatt file against the [Adopted Specifications](https://www.bluetooth.com/specifications/adopted-specifications). 701503a627eSMilanka Ringwald 702503a627eSMilanka RingwaldStep 4: 703503a627eSMilanka Ringwald 704503a627eSMilanka RingwaldAs described [above](#sec:GATTServerProfiles) all read/write requests are handled by the application. 705503a627eSMilanka RingwaldTo implement the new services as a reusable module, it's necessary to get access to all read/write requests related to this service. 706503a627eSMilanka Ringwald 707503a627eSMilanka RingwaldFor this, the ATT DB allows to register read/write callbacks for a specific handle range with *att_server_register_can_send_now_callback()*. 708503a627eSMilanka Ringwald 709503a627eSMilanka 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*. 710503a627eSMilanka Ringwald 711503a627eSMilanka 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()*. 712503a627eSMilanka Ringwald 713503a627eSMilanka 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()* 714503a627eSMilanka Ringwald 715503a627eSMilanka 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. 716503a627eSMilanka Ringwald 717503a627eSMilanka RingwaldTo see how this works together, please check out the Battery Service Server in *src/ble/battery_service_server.c*. 718503a627eSMilanka Ringwald 719503a627eSMilanka Ringwald### GATT Database Hash 720503a627eSMilanka Ringwald 721503a627eSMilanka RingwaldWhen a GATT Client connects to a GATT Server, it cannot know if the GATT Database has changed 722503a627eSMilanka Ringwaldand has to discover the provided GATT Services and Characteristics after each connect. 723503a627eSMilanka Ringwald 724503a627eSMilanka RingwaldTo speed this up, the Bluetooth 725503a627eSMilanka Ringwaldspecification defines a GATT Service Changed Characteristic, with the idea that a GATT Server would notify 726503a627eSMilanka Ringwalda bonded GATT Client if its database changed. However, this is quite fragile and it is not clear how it can be implemented 727503a627eSMilanka Ringwaldin a robust way. 728503a627eSMilanka Ringwald 729503a627eSMilanka RingwaldThe Bluetooth Core Spec 5.1 introduced the GATT Database Hash Characteristic, which allows for a simple 730503a627eSMilanka Ringwaldrobust mechanism to cache a remote GATT Database. The GATT Database Hash is a 16-byte value that is calculated 731503a627eSMilanka Ringwaldover the list of Services and Characteristics. If there is any change to the database, the hash will change as well. 732503a627eSMilanka Ringwald 733503a627eSMilanka RingwaldTo support this on the GATT Server, you only need to add a GATT Service with the GATT Database Characteristic to your .gatt file. 734503a627eSMilanka RingwaldThe hash value is then calculated by the GATT compiler. 735503a627eSMilanka Ringwald 736503a627eSMilanka Ringwald 737503a627eSMilanka Ringwald PRIMARY_SERVICE, GATT_SERVICE 738503a627eSMilanka Ringwald CHARACTERISTIC, GATT_DATABASE_HASH, READ, 739503a627eSMilanka Ringwald 740503a627eSMilanka RingwaldNote: make sure to install the PyCryptodome python package as the hash is calculated using AES-CMAC, 741503a627eSMilanka Ringwalde.g. with: 742503a627eSMilanka Ringwald 743503a627eSMilanka Ringwald pip install pycryptodomex 744