1503a627eSMilanka Ringwald# 2503a627eSMilanka Ringwald 3503a627eSMilanka RingwaldBTstack is a modular dual-mode Bluetooth stack, supporting both 4503a627eSMilanka RingwaldBluetooth Basic Rate/Enhanced Date Rate (BR/EDR) as well as Bluetooth 5503a627eSMilanka RingwaldLow Energy (LE). The BR/EDR technology, also known as Classic Bluetooth, 6503a627eSMilanka Ringwaldprovides a robust wireless connection between devices designed for high 7503a627eSMilanka Ringwalddata rates. In contrast, the LE technology has a lower throughput but 8503a627eSMilanka Ringwaldalso lower energy consumption, faster connection setup, and the ability 9503a627eSMilanka Ringwaldto connect to more devices in parallel. 10503a627eSMilanka Ringwald 11503a627eSMilanka RingwaldWhether Classic or LE, a Bluetooth device implements one or more 12503a627eSMilanka RingwaldBluetooth profiles. A Bluetooth profile specifies how one or more 13503a627eSMilanka RingwaldBluetooth protocols are used to achieve its goals. For example, every 14503a627eSMilanka RingwaldBluetooth device must implement the Generic Access Profile (GAP), which 15503a627eSMilanka Ringwalddefines how devices find each other and how they establish a connection. 16503a627eSMilanka RingwaldThis profile mainly make use of the Host Controller Interface (HCI) 17503a627eSMilanka Ringwaldprotocol, the lowest protocol in the stack hierarchy which implements a 18503a627eSMilanka Ringwaldcommand interface to the Bluetooth chipset. 19503a627eSMilanka Ringwald 20503a627eSMilanka RingwaldIn addition to GAP, a popular Classic Bluetooth example would be a 21503a627eSMilanka Ringwaldperipheral devices that can be connected via the Serial Port Profile 22503a627eSMilanka Ringwald(SPP). SPP basically specifies that a compatible device should provide a 23503a627eSMilanka RingwaldService Discovery Protocol (SDP) record containing an RFCOMM channel 24503a627eSMilanka Ringwaldnumber, which will be used for the actual communication. 25503a627eSMilanka Ringwald 26503a627eSMilanka RingwaldSimilarly, for every LE device, the Generic Attribute Profile (GATT) 27503a627eSMilanka Ringwaldprofile must be implemented in addition to GAP. GATT is built on top of 28503a627eSMilanka Ringwaldthe Attribute Protocol (ATT), and defines how one device can interact 29503a627eSMilanka Ringwaldwith GATT Services on a remote device. 30503a627eSMilanka Ringwald 31503a627eSMilanka RingwaldSo far, the most popular use of BTstack is in peripheral devices that 32503a627eSMilanka Ringwaldcan be connected via SPP (Android 2.0 or higher) and GATT (Android 4.3 33503a627eSMilanka Ringwaldor higher, and iOS 5 or higher). If higher data rates are required 34503a627eSMilanka Ringwaldbetween a peripheral and iOS device, the iAP1 and iAP2 protocols of the 35503a627eSMilanka RingwaldMade for iPhone program can be used instead of GATT. Please contact us 36503a627eSMilanka Ringwalddirectly for information on BTstack and MFi. 37503a627eSMilanka Ringwald 38503a627eSMilanka RingwaldFigure {@fig:BTstackProtocolArchitecture} depicts Bluetooth protocols 39503a627eSMilanka Ringwaldand profiles that are currently implemented by BTstack. 40503a627eSMilanka RingwaldIn the following, we first explain how the various Bluetooth protocols 41503a627eSMilanka Ringwaldare used in BTstack. In the next chapter, we go over the profiles. 42503a627eSMilanka Ringwald 43503a627eSMilanka Ringwald {#fig:BTstackProtocolArchitecture} 44503a627eSMilanka Ringwald 45503a627eSMilanka Ringwald 46503a627eSMilanka Ringwald## HCI - Host Controller Interface 47503a627eSMilanka Ringwald 48503a627eSMilanka RingwaldThe HCI protocol provides a command interface to the Bluetooth chipset. 49503a627eSMilanka RingwaldIn BTstack, the HCI implementation also keeps track of all active 50503a627eSMilanka Ringwaldconnections and handles the fragmentation and re-assembly of higher 51503a627eSMilanka Ringwaldlayer (L2CAP) packets. 52503a627eSMilanka Ringwald 53503a627eSMilanka RingwaldPlease note, that an application rarely has to send HCI commands on its 54503a627eSMilanka Ringwaldown. Instead, BTstack provides convenience functions in GAP and higher 55503a627eSMilanka Ringwaldlevel protocols that use HCI automatically. E.g. to set the name, you 56503a627eSMilanka Ringwaldcall *gap_set_local_name()* before powering up. The main use of HCI 57503a627eSMilanka Ringwaldcommands in application is during the startup phase to configure special 58503a627eSMilanka Ringwaldfeatures that are not available via the GAP API yet. How to send a 59503a627eSMilanka Ringwaldcustom HCI command is explained in the following section. 60503a627eSMilanka Ringwald 61503a627eSMilanka Ringwald### Defining custom HCI command templates 62503a627eSMilanka Ringwald 63503a627eSMilanka RingwaldEach HCI command is assigned a 2-byte OpCode used to uniquely identify 64503a627eSMilanka Ringwalddifferent types of commands. The OpCode parameter is divided into two 65503a627eSMilanka Ringwaldfields, called the OpCode Group Field (OGF) and OpCode Command Field 66503a627eSMilanka Ringwald(OCF), see [Bluetooth Specification](https://www.bluetooth.org/Technical/Specifications/adopted.htm) - 67503a627eSMilanka RingwaldCore Version 4.0, Volume 2, Part E, Chapter 5.4. 68503a627eSMilanka Ringwald 6911ebce11SMilanka RingwaldListing [below](#lst:hciOGFs) shows the OGFs provided by BTstack in file [src/hci.h](GITHUB_URL/src/hci.h): 70503a627eSMilanka Ringwald 71503a627eSMilanka Ringwald~~~~ {#lst:hciOGFs .c caption="{HCI OGFs provided by BTstack.}"} 72503a627eSMilanka Ringwald 73503a627eSMilanka Ringwald #define OGF_LINK_CONTROL 0x01 74503a627eSMilanka Ringwald #define OGF_LINK_POLICY 0x02 75503a627eSMilanka Ringwald #define OGF_CONTROLLER_BASEBAND 0x03 76503a627eSMilanka Ringwald #define OGF_INFORMATIONAL_PARAMETERS 0x04 77503a627eSMilanka Ringwald #define OGF_LE_CONTROLLER 0x08 78503a627eSMilanka Ringwald #define OGF_BTSTACK 0x3d 79503a627eSMilanka Ringwald #define OGF_VENDOR 0x3f 80503a627eSMilanka Ringwald~~~~ 81503a627eSMilanka Ringwald 82503a627eSMilanka RingwaldFor all existing Bluetooth 83503a627eSMilanka Ringwaldcommands and their OCFs see [Bluetooth Specification](https://www.bluetooth.org/Technical/Specifications/adopted.htm) - 84503a627eSMilanka RingwaldCore Version 4.0, Volume 2, Part E, Chapter 7. 85503a627eSMilanka Ringwald 86503a627eSMilanka RingwaldIn a HCI command packet, the OpCode is followed by parameter total 87503a627eSMilanka Ringwaldlength, and the actual parameters. The OpCode of a command can be 88503a627eSMilanka Ringwaldcalculated using the OPCODE macro. BTstack provides the *hci_cmd_t* 89503a627eSMilanka Ringwaldstruct as a compact format to define HCI command packets, see 9011ebce11SMilanka RingwaldListing [below](#lst:HCIcmdTemplate), and [src/hci_cmd.h](GITHUB_URL/src/hci_cmd.h) 91503a627eSMilanka Ringwaldfile in the source code. 92503a627eSMilanka Ringwald 93503a627eSMilanka Ringwald~~~~ {#lst:HCIcmdTemplate .c caption="{HCI command struct.}"} 94503a627eSMilanka Ringwald 95503a627eSMilanka Ringwald // Calculate combined ogf/ocf value. 96503a627eSMilanka Ringwald #define OPCODE(ogf, ocf) (ocf | ogf << 10) 97503a627eSMilanka Ringwald 98503a627eSMilanka Ringwald // Compact HCI Command packet description. 99503a627eSMilanka Ringwald typedef struct { 100503a627eSMilanka Ringwald uint16_t opcode; 101503a627eSMilanka Ringwald const char *format; 102503a627eSMilanka Ringwald } hci_cmd_t; 103503a627eSMilanka Ringwald~~~~ 104503a627eSMilanka Ringwald 105503a627eSMilanka RingwaldListing [below](#lst:HCIcmdExample) illustrates the *hci_write_local_name* HCI 106503a627eSMilanka Ringwaldcommand template from library: 107503a627eSMilanka Ringwald 108503a627eSMilanka Ringwald~~~~ {#lst:HCIcmdExample .c caption="{HCI command example.}"} 109503a627eSMilanka Ringwald 110503a627eSMilanka Ringwald // Sets local Bluetooth name 111503a627eSMilanka Ringwald const hci_cmd_t hci_write_local_name = { 112503a627eSMilanka Ringwald OPCODE(OGF_CONTROLLER_BASEBAND, 0x13), "N" 113503a627eSMilanka Ringwald // Local name (UTF-8, Null Terminated, max 248 octets) 114503a627eSMilanka Ringwald }; 115503a627eSMilanka Ringwald~~~~ 116503a627eSMilanka Ringwald 117503a627eSMilanka RingwaldIt uses OGF_CONTROLLER_BASEBAND as OGF, 118503a627eSMilanka Ringwald0x13 as OCF, and has one parameter with format “N” indicating a null 119503a627eSMilanka Ringwaldterminated UTF-8 string. Table {@tbl:hciCmdParamSpecifier} lists the format 120503a627eSMilanka Ringwaldspecifiers supported by BTstack. Check for other predefined HCI commands 121503a627eSMilanka Ringwaldand info on their parameters. 122503a627eSMilanka Ringwald 123503a627eSMilanka Ringwald ------------------- ---------------------------------------------------- 124503a627eSMilanka Ringwald Format Specifier Description 125503a627eSMilanka Ringwald 1,2,3,4 one to four byte value 126503a627eSMilanka Ringwald A 31 bytes advertising data 127503a627eSMilanka Ringwald B Bluetooth Baseband Address 128503a627eSMilanka Ringwald D 8 byte data block 129503a627eSMilanka Ringwald E Extended Inquiry Information 240 octets 130503a627eSMilanka Ringwald H HCI connection handle 131503a627eSMilanka Ringwald N Name up to 248 chars, UTF8 string, null terminated 132503a627eSMilanka Ringwald P 16 byte Pairing code, e.g. PIN code or link key 133503a627eSMilanka Ringwald S Service Record (Data Element Sequence) 134503a627eSMilanka Ringwald ------------------- ---------------------------------------------------- 135503a627eSMilanka Ringwald 136503a627eSMilanka RingwaldTable: Supported Format Specifiers of HCI Command Parameter. {#tbl:hciCmdParamSpecifier} 137503a627eSMilanka Ringwald 138503a627eSMilanka Ringwald 139503a627eSMilanka Ringwald### Sending HCI command based on a template {#sec:sendingHCIProtocols} 140503a627eSMilanka Ringwald 141503a627eSMilanka RingwaldYou can use the *hci_send_cmd* function to send HCI command based on a 142503a627eSMilanka Ringwaldtemplate and a list of parameters. However, it is necessary to check 143503a627eSMilanka Ringwaldthat the outgoing packet buffer is empty and that the Bluetooth module 144503a627eSMilanka Ringwaldis ready to receive the next command - most modern Bluetooth modules 145503a627eSMilanka Ringwaldonly allow to send a single HCI command. This can be done by calling 146503a627eSMilanka Ringwald*hci_can_send_command_packet_now()* function, which returns true, 147503a627eSMilanka Ringwaldif it is ok to send. 148503a627eSMilanka Ringwald 149503a627eSMilanka RingwaldListing [below](#lst:HCIcmdExampleLocalName) illustrates how to manually set the 150503a627eSMilanka Ringwalddevice name with the HCI Write Local Name command. 151503a627eSMilanka Ringwald 152503a627eSMilanka Ringwald~~~~ {#lst:HCIcmdExampleLocalName .c caption="{Sending HCI command example.}"} 153503a627eSMilanka Ringwald 154503a627eSMilanka Ringwald if (hci_can_send_command_packet_now()){ 155503a627eSMilanka Ringwald hci_send_cmd(&hci_write_local_name, "BTstack Demo"); 156503a627eSMilanka Ringwald } 157503a627eSMilanka Ringwald~~~~ 158503a627eSMilanka Ringwald 159503a627eSMilanka RingwaldPlease note, that an application rarely has to send HCI commands on its 160503a627eSMilanka Ringwaldown. Instead, BTstack provides convenience functions in GAP and higher 161503a627eSMilanka Ringwaldlevel protocols that use HCI automatically. 162503a627eSMilanka Ringwald 163503a627eSMilanka Ringwald 164503a627eSMilanka Ringwald## L2CAP - Logical Link Control and Adaptation Protocol 165503a627eSMilanka Ringwald 166503a627eSMilanka Ringwald 167503a627eSMilanka RingwaldThe L2CAP protocol supports higher level protocol multiplexing and 168503a627eSMilanka Ringwaldpacket fragmentation. It provides the base for the RFCOMM and BNEP 169503a627eSMilanka Ringwaldprotocols. For all profiles that are officially supported by BTstack, 170503a627eSMilanka RingwaldL2CAP does not need to be used directly. For testing or the development 171503a627eSMilanka Ringwaldof custom protocols, it’s helpful to be able to access and provide L2CAP 172503a627eSMilanka Ringwaldservices however. 173503a627eSMilanka Ringwald 174503a627eSMilanka Ringwald### Access an L2CAP service on a remote device 175503a627eSMilanka Ringwald 176503a627eSMilanka RingwaldL2CAP is based around the concept of channels. A channel is a logical 177503a627eSMilanka Ringwaldconnection on top of a baseband connection. Each channel is bound to a 178503a627eSMilanka Ringwaldsingle protocol in a many-to-one fashion. Multiple channels can be bound 179503a627eSMilanka Ringwaldto the same protocol, but a channel cannot be bound to multiple 180503a627eSMilanka Ringwaldprotocols. Multiple channels can share the same baseband connection. 181503a627eSMilanka Ringwald 182503a627eSMilanka RingwaldTo communicate with an L2CAP service on a remote device, the application 183503a627eSMilanka Ringwaldon a local Bluetooth device initiates the L2CAP layer using the 184503a627eSMilanka Ringwald*l2cap_init* function, and then creates an outgoing L2CAP channel to 185503a627eSMilanka Ringwaldthe PSM of a remote device using the *l2cap_create_channel* 186503a627eSMilanka Ringwaldfunction. The *l2cap_create_channel* function will initiate 187503a627eSMilanka Ringwalda new baseband connection if it does not already exist. The packet 188503a627eSMilanka Ringwaldhandler that is given as an input parameter of the L2CAP create channel 189503a627eSMilanka Ringwaldfunction will be assigned to the new outgoing L2CAP channel. This 190503a627eSMilanka Ringwaldhandler receives the L2CAP_EVENT_CHANNEL_OPENED and 191503a627eSMilanka RingwaldL2CAP_EVENT_CHANNEL_CLOSED events and L2CAP data packets, as shown 192503a627eSMilanka Ringwaldin Listing [below](#lst:L2CAPremoteService). 193503a627eSMilanka Ringwald 194503a627eSMilanka Ringwald 195503a627eSMilanka Ringwald~~~~ {#lst:L2CAPremoteService .c caption="{Accessing an L2CAP service on a remote device.}"} 196503a627eSMilanka Ringwald 197503a627eSMilanka Ringwald btstack_packet_handler_t l2cap_packet_handler; 198503a627eSMilanka Ringwald 199503a627eSMilanka Ringwald void l2cap_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 200503a627eSMilanka Ringwald bd_addr_t event_addr; 201503a627eSMilanka Ringwald switch (packet_type){ 202503a627eSMilanka Ringwald case HCI_EVENT_PACKET: 203503a627eSMilanka Ringwald switch (hci_event_packet_get_type(packet)){ 204503a627eSMilanka Ringwald case L2CAP_EVENT_CHANNEL_OPENED: 205503a627eSMilanka Ringwald l2cap_event_channel_opened_get_address(packet, &event_addr); 206503a627eSMilanka Ringwald psm = l2cap_event_channel_opened_get_psm(packet); 207503a627eSMilanka Ringwald local_cid = l2cap_event_channel_opened_get_local_cid(packet); 208503a627eSMilanka Ringwald handle = l2cap_event_channel_opened_get_handle(packet); 209503a627eSMilanka Ringwald if (l2cap_event_channel_opened_get_status(packet)) { 210503a627eSMilanka Ringwald printf("Connection failed\n\r"); 211503a627eSMilanka Ringwald } else 212503a627eSMilanka Ringwald printf("Connected\n\r"); 213503a627eSMilanka Ringwald } 214503a627eSMilanka Ringwald break; 215503a627eSMilanka Ringwald case L2CAP_EVENT_CHANNEL_CLOSED: 216503a627eSMilanka Ringwald break; 217503a627eSMilanka Ringwald ... 218503a627eSMilanka Ringwald } 219503a627eSMilanka Ringwald case L2CAP_DATA_PACKET: 220503a627eSMilanka Ringwald // handle L2CAP data packet 221503a627eSMilanka Ringwald break; 222503a627eSMilanka Ringwald ... 223503a627eSMilanka Ringwald } 224503a627eSMilanka Ringwald } 225503a627eSMilanka Ringwald 226503a627eSMilanka Ringwald void create_outgoing_l2cap_channel(bd_addr_t address, uint16_t psm, uint16_t mtu){ 227503a627eSMilanka Ringwald l2cap_create_channel(NULL, l2cap_packet_handler, remote_bd_addr, psm, mtu); 228503a627eSMilanka Ringwald } 229503a627eSMilanka Ringwald 230503a627eSMilanka Ringwald void btstack_setup(){ 231503a627eSMilanka Ringwald ... 232503a627eSMilanka Ringwald l2cap_init(); 233503a627eSMilanka Ringwald } 234503a627eSMilanka Ringwald 235503a627eSMilanka Ringwald~~~~ 236503a627eSMilanka Ringwald 237503a627eSMilanka Ringwald### Provide an L2CAP service 238503a627eSMilanka Ringwald 239503a627eSMilanka RingwaldTo provide an L2CAP service, the application on a local Bluetooth device 240503a627eSMilanka Ringwaldmust init the L2CAP layer and register the service with 241503a627eSMilanka Ringwald*l2cap_register_service*. From there on, it can wait for 242503a627eSMilanka Ringwaldincoming L2CAP connections. The application can accept or deny an 243503a627eSMilanka Ringwaldincoming connection by calling the *l2cap_accept_connection* 244503a627eSMilanka Ringwaldand *l2cap_deny_connection* functions respectively. 245503a627eSMilanka Ringwald 246503a627eSMilanka RingwaldIf a connection is accepted and the incoming L2CAP channel gets successfully 247503a627eSMilanka Ringwaldopened, the L2CAP service can send and receive L2CAP data packets to the connected 248503a627eSMilanka Ringwalddevice with *l2cap_send*. 249503a627eSMilanka Ringwald 250503a627eSMilanka RingwaldListing [below](#lst:L2CAPService) 251503a627eSMilanka Ringwaldprovides L2CAP service example code. 252503a627eSMilanka Ringwald 253503a627eSMilanka Ringwald~~~~ {#lst:L2CAPService .c caption="{Providing an L2CAP service.}"} 254503a627eSMilanka Ringwald 255503a627eSMilanka Ringwald void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 256503a627eSMilanka Ringwald bd_addr_t event_addr; 257503a627eSMilanka Ringwald switch (packet_type){ 258503a627eSMilanka Ringwald case HCI_EVENT_PACKET: 259503a627eSMilanka Ringwald switch (hci_event_packet_get_type(packet)){ 260503a627eSMilanka Ringwald case L2CAP_EVENT_INCOMING_CONNECTION: 261503a627eSMilanka Ringwald local_cid = l2cap_event_incoming_connection_get_local_cid(packet); 262503a627eSMilanka Ringwald l2cap_accept_connection(local_cid); 263503a627eSMilanka Ringwald break; 264503a627eSMilanka Ringwald case L2CAP_EVENT_CHANNEL_OPENED: 265503a627eSMilanka Ringwald l2cap_event_channel_opened_get_address(packet, &event_addr); 266503a627eSMilanka Ringwald psm = l2cap_event_channel_opened_get_psm(packet); 267503a627eSMilanka Ringwald local_cid = l2cap_event_channel_opened_get_local_cid(packet); 268503a627eSMilanka Ringwald handle = l2cap_event_channel_opened_get_handle(packet); 269503a627eSMilanka Ringwald if (l2cap_event_channel_opened_get_status(packet)) { 270503a627eSMilanka Ringwald printf("Connection failed\n\r"); 271503a627eSMilanka Ringwald } else 272503a627eSMilanka Ringwald printf("Connected\n\r"); 273503a627eSMilanka Ringwald } 274503a627eSMilanka Ringwald break; 275503a627eSMilanka Ringwald case L2CAP_EVENT_CHANNEL_CLOSED: 276503a627eSMilanka Ringwald break; 277503a627eSMilanka Ringwald ... 278503a627eSMilanka Ringwald } 279503a627eSMilanka Ringwald case L2CAP_DATA_PACKET: 280503a627eSMilanka Ringwald // handle L2CAP data packet 281503a627eSMilanka Ringwald break; 282503a627eSMilanka Ringwald ... 283503a627eSMilanka Ringwald } 284503a627eSMilanka Ringwald } 285503a627eSMilanka Ringwald 286503a627eSMilanka Ringwald void btstack_setup(){ 287503a627eSMilanka Ringwald ... 288503a627eSMilanka Ringwald l2cap_init(); 289503a627eSMilanka Ringwald l2cap_register_service(NULL, packet_handler, 0x11,100); 290503a627eSMilanka Ringwald } 291503a627eSMilanka Ringwald 292503a627eSMilanka Ringwald~~~~ 293503a627eSMilanka Ringwald 294503a627eSMilanka Ringwald### Sending L2CAP Data {#sec:l2capSendProtocols} 295503a627eSMilanka Ringwald 296503a627eSMilanka RingwaldSending of L2CAP data packets may fail due to a full internal BTstack 297503a627eSMilanka Ringwaldoutgoing packet buffer, or if the ACL buffers in the Bluetooth module 298503a627eSMilanka Ringwaldbecome full, i.e., if the application is sending faster than the packets 299503a627eSMilanka Ringwaldcan be transferred over the air. 300503a627eSMilanka Ringwald 301503a627eSMilanka RingwaldInstead of directly calling *l2cap_send*, it is recommended to call 302503a627eSMilanka Ringwald*l2cap_request_can_send_now_event(cahnnel_id)* which will trigger an L2CAP_EVENT_CAN_SEND_NOW 303503a627eSMilanka Ringwaldas soon as possible. It might happen that the event is received via 304503a627eSMilanka Ringwaldpacket handler before the *l2cap_request_can_send_now_event* function returns. 305503a627eSMilanka RingwaldThe L2CAP_EVENT_CAN_SEND_NOW indicates a channel ID on which sending is possible. 306503a627eSMilanka Ringwald 307503a627eSMilanka RingwaldPlease note that the guarantee that a packet can be sent is only valid when the event is received. 308503a627eSMilanka RingwaldAfter returning from the packet handler, BTstack might need to send itself. 309503a627eSMilanka Ringwald 310503a627eSMilanka Ringwald### LE Data Channels 311503a627eSMilanka Ringwald 312503a627eSMilanka RingwaldThe full title for LE Data Channels is actually LE Connection-Oriented Channels with LE Credit-Based Flow-Control Mode. In this mode, data is sent as Service Data Units (SDUs) that can be larger than an individual HCI LE ACL packet. 313503a627eSMilanka Ringwald 314503a627eSMilanka RingwaldLE Data Channels are similar to Classic L2CAP Channels but also provide a credit-based flow control similar to RFCOMM Channels. 315503a627eSMilanka RingwaldUnless the LE Data Packet Extension of Bluetooth Core 4.2 specification is used, the maximum packet size for LE ACL packets is 27 bytes. In order to send larger packets, each packet will be split into multiple ACL LE packets and recombined on the receiving side. 316503a627eSMilanka Ringwald 317f25e60deSMatthias RingwaldSince multiple SDUs can be transmitted at the same time and the individual ACL LE packets can be sent interleaved, BTstack requires a dedicated receive buffer per channel that has to be passed when creating the channel or accepting it. Similarly, when sending SDUs, the data provided to the *l2cap_cbm_send_data* must stay valid until the *L2CAP_EVENT_LE_PACKET_SENT* is received. 318503a627eSMilanka Ringwald 319f25e60deSMatthias RingwaldWhen creating an outgoing connection of accepting an incoming, the *initial_credits* allows to provide a fixed number of credits to the remote side. Further credits can be provided anytime with *l2cap_cbm_provide_credits*. If *L2CAP_LE_AUTOMATIC_CREDITS* is used, BTstack automatically provides credits as needed - effectively trading in the flow-control functionality for convenience. 320503a627eSMilanka Ringwald 321503a627eSMilanka RingwaldThe remainder of the API is similar to the one of L2CAP: 322503a627eSMilanka Ringwald 323f25e60deSMatthias Ringwald * *l2cap_cbm_register_service* and *l2cap_cbm_unregister_service* are used to manage local services. 324f25e60deSMatthias Ringwald * *l2cap_cbm_accept_connection* and *l2cap_cbm_decline_connection* are used to accept or deny an incoming connection request. 325f25e60deSMatthias Ringwald * *l2cap_cbm_create_channel* creates an outgoing connections. 326f25e60deSMatthias Ringwald * *l2cap_cbm_can_send_now* checks if a packet can be scheduled for transmission now. 327f25e60deSMatthias Ringwald * *l2cap_cbm_request_can_send_now_event* requests an *L2CAP_EVENT_LE_CAN_SEND_NOW* event as soon as possible. 328f25e60deSMatthias Ringwald * *l2cap_cbm_disconnect* closes the connection. 329503a627eSMilanka Ringwald 330503a627eSMilanka Ringwald## RFCOMM - Radio Frequency Communication Protocol 331503a627eSMilanka Ringwald 332503a627eSMilanka RingwaldThe Radio frequency communication (RFCOMM) protocol provides emulation 333503a627eSMilanka Ringwaldof serial ports over the L2CAP protocol and reassembly. It is the base 334503a627eSMilanka Ringwaldfor the Serial Port Profile and other profiles used for 335503a627eSMilanka Ringwaldtelecommunication like Head-Set Profile, Hands-Free Profile, Object 336503a627eSMilanka RingwaldExchange (OBEX) etc. 337503a627eSMilanka Ringwald 338503a627eSMilanka Ringwald### No RFCOMM packet boundaries {#sec:noRfcommPacketBoundaries} 339503a627eSMilanka Ringwald 340503a627eSMilanka RingwaldAs RFCOMM emulates a serial port, it does not preserve packet boundaries. 341503a627eSMilanka Ringwald 342503a627eSMilanka RingwaldOn most operating systems, RFCOMM/SPP will be modeled as a pipe that allows 343503a627eSMilanka Ringwaldto write a block of bytes. The OS and the Bluetooth Stack are free to buffer 344503a627eSMilanka Ringwaldand chunk this data in any way it seems fit. In your BTstack application, you will 345503a627eSMilanka Ringwaldtherefore receive this data in the same order, but there are no guarantees as 346503a627eSMilanka Ringwaldhow it might be fragmented into multiple chunks. 347503a627eSMilanka Ringwald 348503a627eSMilanka RingwaldIf you need to preserve the concept of sending a packet with a specific size 349503a627eSMilanka Ringwaldover RFCOMM, the simplest way is to prefix the data with a 2 or 4 byte length field 350503a627eSMilanka Ringwaldand then reconstruct the packet on the receiving side. 351503a627eSMilanka Ringwald 352503a627eSMilanka RingwaldPlease note, that due to BTstack's 'no buffers' policy, BTstack will send outgoing RFCOMM data immediately 353503a627eSMilanka Ringwaldand implicitly preserve the packet boundaries, i.e., it will send the data as a single 354503a627eSMilanka RingwaldRFCOMM packet in a single L2CAP packet, which will arrive in one piece. 355503a627eSMilanka RingwaldWhile this will hold between two BTstack instances, it's not a good idea to rely on implementation details 356503a627eSMilanka Ringwaldand rather prefix the data as described. 357503a627eSMilanka Ringwald 358503a627eSMilanka Ringwald### RFCOMM flow control {#sec:flowControlProtocols} 359503a627eSMilanka Ringwald 360503a627eSMilanka RingwaldRFCOMM has a mandatory credit-based flow-control. This means that two 361503a627eSMilanka Ringwalddevices that established RFCOMM connection, use credits to keep track of 362503a627eSMilanka Ringwaldhow many more RFCOMM data packets can be sent to each. If a device has 363503a627eSMilanka Ringwaldno (outgoing) credits left, it cannot send another RFCOMM packet, the 364503a627eSMilanka Ringwaldtransmission must be paused. During the connection establishment, 365503a627eSMilanka Ringwaldinitial credits are provided. BTstack tracks the number of credits in 366503a627eSMilanka Ringwaldboth directions. If no outgoing credits are available, the RFCOMM send 367503a627eSMilanka Ringwaldfunction will return an error, and you can try later. For incoming data, 368503a627eSMilanka RingwaldBTstack provides channels and services with and without automatic credit 369503a627eSMilanka Ringwaldmanagement via different functions to create/register them respectively. 370503a627eSMilanka RingwaldIf the management of credits is automatic, the new credits are provided 371503a627eSMilanka Ringwaldwhen needed relying on ACL flow control - this is only useful if there 372503a627eSMilanka Ringwaldis not much data transmitted and/or only one physical connection is 373503a627eSMilanka Ringwaldused. If the management of credits is manual, credits are provided by 374503a627eSMilanka Ringwaldthe application such that it can manage its receive buffers explicitly. 375503a627eSMilanka Ringwald 376503a627eSMilanka Ringwald 377503a627eSMilanka Ringwald### Access an RFCOMM service on a remote device {#sec:rfcommClientProtocols} 378503a627eSMilanka Ringwald 379503a627eSMilanka RingwaldTo communicate with an RFCOMM service on a remote device, the 380503a627eSMilanka Ringwaldapplication on a local Bluetooth device initiates the RFCOMM layer using 381503a627eSMilanka Ringwaldthe *rfcomm_init* function, and then creates an outgoing RFCOMM channel 382503a627eSMilanka Ringwaldto a given server channel on a remote device using the 383503a627eSMilanka Ringwald*rfcomm_create_channel* function. The 384503a627eSMilanka Ringwald*rfcomm_create_channel* function will initiate a new L2CAP 385503a627eSMilanka Ringwaldconnection for the RFCOMM multiplexer, if it does not already exist. The 386503a627eSMilanka Ringwaldchannel will automatically provide enough credits to the remote side. To 387503a627eSMilanka Ringwaldprovide credits manually, you have to create the RFCOMM connection by 388503a627eSMilanka Ringwaldcalling *rfcomm_create_channel_with_initial_credits* - 389503a627eSMilanka Ringwaldsee Section [on manual credit assignement](#sec:manualCreditsProtocols). 390503a627eSMilanka Ringwald 391503a627eSMilanka RingwaldThe packet handler that is given as an input parameter of the RFCOMM 392503a627eSMilanka Ringwaldcreate channel function will be assigned to the new outgoing channel. 393503a627eSMilanka RingwaldThis handler receives the RFCOMM_EVENT_CHANNEL_OPENED and 394503a627eSMilanka RingwaldRFCOMM_EVENT_CHANNEL_CLOSED events, and RFCOMM data packets, as shown in 395503a627eSMilanka RingwaldListing [below](#lst:RFCOMMremoteService). 396503a627eSMilanka Ringwald 397503a627eSMilanka Ringwald 398503a627eSMilanka Ringwald~~~~ {#lst:RFCOMMremoteService .c caption="{RFCOMM handler for outgoing RFCOMM channel.}"} 399503a627eSMilanka Ringwald 400503a627eSMilanka Ringwald void rfcomm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 401503a627eSMilanka Ringwald switch (packet_type){ 402503a627eSMilanka Ringwald case HCI_EVENT_PACKET: 403503a627eSMilanka Ringwald switch (hci_event_packet_get_type(packet)){ 404503a627eSMilanka Ringwald case RFCOMM_EVENT_CHANNEL_OPENED: 405503a627eSMilanka Ringwald if (rfcomm_event_open_channel_complete_get_status(packet)) { 406503a627eSMilanka Ringwald printf("Connection failed\n\r"); 407503a627eSMilanka Ringwald } else { 408503a627eSMilanka Ringwald printf("Connected\n\r"); 409503a627eSMilanka Ringwald } 410503a627eSMilanka Ringwald break; 411503a627eSMilanka Ringwald case RFCOMM_EVENT_CHANNEL_CLOSED: 412503a627eSMilanka Ringwald break; 413503a627eSMilanka Ringwald ... 414503a627eSMilanka Ringwald } 415503a627eSMilanka Ringwald break; 416503a627eSMilanka Ringwald case RFCOMM_DATA_PACKET: 417503a627eSMilanka Ringwald // handle RFCOMM data packets 418503a627eSMilanka Ringwald return; 419503a627eSMilanka Ringwald } 420503a627eSMilanka Ringwald } 421503a627eSMilanka Ringwald 422503a627eSMilanka Ringwald void create_rfcomm_channel(uint8_t packet_type, uint8_t *packet, uint16_t size){ 423503a627eSMilanka Ringwald rfcomm_create_channel(rfcomm_packet_handler, addr, rfcomm_channel); 424503a627eSMilanka Ringwald } 425503a627eSMilanka Ringwald 426503a627eSMilanka Ringwald void btstack_setup(){ 427503a627eSMilanka Ringwald ... 428503a627eSMilanka Ringwald l2cap_init(); 429503a627eSMilanka Ringwald rfcomm_init(); 430503a627eSMilanka Ringwald } 431503a627eSMilanka Ringwald 432503a627eSMilanka Ringwald 433503a627eSMilanka Ringwald~~~~ 434503a627eSMilanka Ringwald 435d13e5cf6SMatthias RingwaldThe RFCOMM channel will stay open until either side closes it with rfcomm_disconnect. 436*849f0fb4SMatthias RingwaldThe RFCOMM multiplexer will be closed by the peer that closes the last RFCOMM channel. 437d13e5cf6SMatthias Ringwald 438503a627eSMilanka Ringwald### Provide an RFCOMM service {#sec:rfcommServiceProtocols} 439503a627eSMilanka Ringwald 440503a627eSMilanka RingwaldTo provide an RFCOMM service, the application on a local Bluetooth 441503a627eSMilanka Ringwalddevice must first init the L2CAP and RFCOMM layers and then register the 442503a627eSMilanka Ringwaldservice with *rfcomm_register_service*. From there on, it 443503a627eSMilanka Ringwaldcan wait for incoming RFCOMM connections. The application can accept or 444503a627eSMilanka Ringwalddeny an incoming connection by calling the 445503a627eSMilanka Ringwald*rfcomm_accept_connection* and *rfcomm_deny_connection* functions respectively. 446503a627eSMilanka RingwaldIf a connection is accepted and the incoming RFCOMM channel gets successfully 447503a627eSMilanka Ringwaldopened, the RFCOMM service can send RFCOMM data packets to the connected 448503a627eSMilanka Ringwalddevice with *rfcomm_send* and receive data packets by the 449503a627eSMilanka Ringwaldpacket handler provided by the *rfcomm_register_service* 450503a627eSMilanka Ringwaldcall. 451503a627eSMilanka Ringwald 452503a627eSMilanka RingwaldListing [below](#lst:RFCOMMService) provides the RFCOMM service example code. 453503a627eSMilanka Ringwald 454503a627eSMilanka Ringwald~~~~ {#lst:RFCOMMService .c caption="{Providing an RFCOMM service.}"} 455503a627eSMilanka Ringwald 456503a627eSMilanka Ringwald void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 457503a627eSMilanka Ringwald switch (packet_type){ 458503a627eSMilanka Ringwald case HCI_EVENT_PACKET: 459503a627eSMilanka Ringwald switch (hci_event_packet_get_type(packet)){ 460503a627eSMilanka Ringwald case RFCOMM_EVENT_INCOMING_CONNECTION: 461503a627eSMilanka Ringwald rfcomm_channel_id = rfcomm_event_incoming_connection_get_rfcomm_cid(packet); 462503a627eSMilanka Ringwald rfcomm_accept_connection(rfcomm_channel_id); 463503a627eSMilanka Ringwald break; 464503a627eSMilanka Ringwald case RFCOMM_EVENT_CHANNEL_OPENED: 465503a627eSMilanka Ringwald if (rfcomm_event_open_channel_complete_get_status(packet)){ 466503a627eSMilanka Ringwald printf("RFCOMM channel open failed."); 467503a627eSMilanka Ringwald break; 468503a627eSMilanka Ringwald } 469503a627eSMilanka Ringwald rfcomm_channel_id = rfcomm_event_open_channel_complete_get_rfcomm_cid(packet); 470503a627eSMilanka Ringwald mtu = rfcomm_event_open_channel_complete_get_max_frame_size(packet); 471503a627eSMilanka Ringwald printf("RFCOMM channel open succeeded, max frame size %u.", mtu); 472503a627eSMilanka Ringwald break; 473503a627eSMilanka Ringwald case RFCOMM_EVENT_CHANNEL_CLOSED: 474503a627eSMilanka Ringwald printf("Channel closed."); 475503a627eSMilanka Ringwald break; 476503a627eSMilanka Ringwald ... 477503a627eSMilanka Ringwald } 478503a627eSMilanka Ringwald break; 479503a627eSMilanka Ringwald case RFCOMM_DATA_PACKET: 480503a627eSMilanka Ringwald // handle RFCOMM data packets 481503a627eSMilanka Ringwald return; 482503a627eSMilanka Ringwald ... 483503a627eSMilanka Ringwald } 484503a627eSMilanka Ringwald ... 485503a627eSMilanka Ringwald } 486503a627eSMilanka Ringwald 487503a627eSMilanka Ringwald void btstack_setup(){ 488503a627eSMilanka Ringwald ... 489503a627eSMilanka Ringwald l2cap_init(); 490503a627eSMilanka Ringwald rfcomm_init(); 491503a627eSMilanka Ringwald rfcomm_register_service(packet_handler, rfcomm_channel_nr, mtu); 492503a627eSMilanka Ringwald } 493503a627eSMilanka Ringwald 494503a627eSMilanka Ringwald~~~~ 495503a627eSMilanka Ringwald 496503a627eSMilanka Ringwald### Slowing down RFCOMM data reception {#sec:manualCreditsProtocols} 497503a627eSMilanka Ringwald 498503a627eSMilanka RingwaldRFCOMM’s credit-based flow-control can be used to adapt, i.e., slow down 499503a627eSMilanka Ringwaldthe RFCOMM data to your processing speed. For incoming data, BTstack 500503a627eSMilanka Ringwaldprovides channels and services with and without automatic credit 501503a627eSMilanka Ringwaldmanagement. If the management of credits is automatic, new credits 502503a627eSMilanka Ringwaldare provided when needed relying on ACL flow control. This is only 503503a627eSMilanka Ringwalduseful if there is not much data transmitted and/or only one physical 504503a627eSMilanka Ringwaldconnection is used. See Listing [below](#lst:automaticFlowControl). 505503a627eSMilanka Ringwald 506503a627eSMilanka Ringwald~~~~ {#lst:automaticFlowControl .c caption="{RFCOMM service with automatic credit management.}"} 507503a627eSMilanka Ringwald void btstack_setup(void){ 508503a627eSMilanka Ringwald ... 509503a627eSMilanka Ringwald // init RFCOMM 510503a627eSMilanka Ringwald rfcomm_init(); 511503a627eSMilanka Ringwald rfcomm_register_service(packet_handler, rfcomm_channel_nr, 100); 512503a627eSMilanka Ringwald } 513503a627eSMilanka Ringwald~~~~ 514503a627eSMilanka Ringwald 515503a627eSMilanka RingwaldIf the management of credits is manual, credits are provided by the 516503a627eSMilanka Ringwaldapplication such that it can manage its receive buffers explicitly, see 517503a627eSMilanka RingwaldListing [below](#lst:explicitFlowControl). 518503a627eSMilanka Ringwald 519503a627eSMilanka RingwaldManual credit management is recommended when received RFCOMM data cannot 52011ebce11SMilanka Ringwaldbe processed immediately. In the [SPP flow control example](../examples/examples/#sec:sppflowcontrolExample), 5217029d61cSMilanka Ringwalddelayed processing of received data is 522503a627eSMilanka Ringwaldsimulated with the help of a periodic timer. To provide new credits, you 523503a627eSMilanka Ringwaldcall the *rfcomm_grant_credits* function with the RFCOMM channel ID 524503a627eSMilanka Ringwaldand the number of credits as shown in Listing [below](#lst:NewCredits). 525503a627eSMilanka Ringwald 526503a627eSMilanka Ringwald~~~~ {#lst:explicitFlowControl .c caption="{RFCOMM service with manual credit management.}"} 527503a627eSMilanka Ringwald void btstack_setup(void){ 528503a627eSMilanka Ringwald ... 529503a627eSMilanka Ringwald // init RFCOMM 530503a627eSMilanka Ringwald rfcomm_init(); 531503a627eSMilanka Ringwald // reserved channel, mtu=100, 1 credit 532503a627eSMilanka Ringwald rfcomm_register_service_with_initial_credits(packet_handler, rfcomm_channel_nr, 100, 1); 533503a627eSMilanka Ringwald } 534503a627eSMilanka Ringwald~~~~ 535503a627eSMilanka Ringwald 536503a627eSMilanka Ringwald~~~~ {#lst:NewCredits .c caption="{Granting RFCOMM credits.}"} 537503a627eSMilanka Ringwald void processing(){ 538503a627eSMilanka Ringwald // process incoming data packet 539503a627eSMilanka Ringwald ... 540503a627eSMilanka Ringwald // provide new credit 541503a627eSMilanka Ringwald rfcomm_grant_credits(rfcomm_channel_id, 1); 542503a627eSMilanka Ringwald } 543503a627eSMilanka Ringwald~~~~ 544503a627eSMilanka Ringwald 545503a627eSMilanka RingwaldPlease note that providing single credits effectively reduces the credit-based 546503a627eSMilanka Ringwald(sliding window) flow control to a stop-and-wait flow-control that 547503a627eSMilanka Ringwaldlimits the data throughput substantially. On the plus side, it allows 548503a627eSMilanka Ringwaldfor a minimal memory footprint. If possible, multiple RFCOMM buffers 549503a627eSMilanka Ringwaldshould be used to avoid pauses while the sender has to wait for a new 550503a627eSMilanka Ringwaldcredit. 551503a627eSMilanka Ringwald 552503a627eSMilanka Ringwald### Sending RFCOMM data {#sec:rfcommSendProtocols} 553503a627eSMilanka Ringwald 554503a627eSMilanka RingwaldOutgoing packets, both commands and data, are not queued in BTstack. 555503a627eSMilanka RingwaldThis section explains the consequences of this design decision for 556503a627eSMilanka Ringwaldsending data and why it is not as bad as it sounds. 557503a627eSMilanka Ringwald 558503a627eSMilanka RingwaldIndependent from the number of output buffers, packet generation has to 559503a627eSMilanka Ringwaldbe adapted to the remote receiver and/or maximal link speed. Therefore, 560503a627eSMilanka Ringwalda packet can only be generated when it can get sent. With this 561503a627eSMilanka Ringwaldassumption, the single output buffer design does not impose additional 562503a627eSMilanka Ringwaldrestrictions. In the following, we show how this is used for adapting 563503a627eSMilanka Ringwaldthe RFCOMM send rate. 564503a627eSMilanka Ringwald 565503a627eSMilanka RingwaldWhen there is a need to send a packet, call *rcomm_request_can_send_now* 566503a627eSMilanka Ringwaldand wait for the reception of the RFCOMM_EVENT_CAN_SEND_NOW event 567503a627eSMilanka Ringwaldto send the packet, as shown in Listing [below](#lst:rfcommRequestCanSendNow). 568503a627eSMilanka Ringwald 569503a627eSMilanka RingwaldPlease note that the guarantee that a packet can be sent is only valid when the event is received. 570503a627eSMilanka RingwaldAfter returning from the packet handler, BTstack might need to send itself. 571503a627eSMilanka Ringwald 572503a627eSMilanka Ringwald~~~~ {#lst:rfcommRequestCanSendNow .c caption="{Preparing and sending data.}"} 573503a627eSMilanka Ringwald void prepare_data(uint16_t rfcomm_channel_id){ 574503a627eSMilanka Ringwald ... 575503a627eSMilanka Ringwald // prepare data in data_buffer 576503a627eSMilanka Ringwald rfcomm_request_can_send_now_event(rfcomm_channel_id); 577503a627eSMilanka Ringwald } 578503a627eSMilanka Ringwald 579503a627eSMilanka Ringwald void send_data(uint16_t rfcomm_channel_id){ 580503a627eSMilanka Ringwald rfcomm_send(rfcomm_channel_id, data_buffer, data_len); 581503a627eSMilanka Ringwald // packet is handed over to BTstack, we can prepare the next one 582503a627eSMilanka Ringwald prepare_data(rfcomm_channel_id); 583503a627eSMilanka Ringwald } 584503a627eSMilanka Ringwald 585503a627eSMilanka Ringwald void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 586503a627eSMilanka Ringwald switch (packet_type){ 587503a627eSMilanka Ringwald case HCI_EVENT_PACKET: 588503a627eSMilanka Ringwald switch (hci_event_packet_get_type(packet)){ 589503a627eSMilanka Ringwald ... 590503a627eSMilanka Ringwald case RFCOMM_EVENT_CAN_SEND_NOW: 591503a627eSMilanka Ringwald rfcomm_channel_id = rfcomm_event_can_send_now_get_rfcomm_cid(packet); 592503a627eSMilanka Ringwald send_data(rfcomm_channel_id); 593503a627eSMilanka Ringwald break; 594503a627eSMilanka Ringwald ... 595503a627eSMilanka Ringwald } 596503a627eSMilanka Ringwald ... 597503a627eSMilanka Ringwald } 598503a627eSMilanka Ringwald } 599503a627eSMilanka Ringwald } 600503a627eSMilanka Ringwald 601503a627eSMilanka Ringwald~~~~ 602503a627eSMilanka Ringwald 603503a627eSMilanka Ringwald### Optimized sending of RFCOMM data 604503a627eSMilanka Ringwald 605503a627eSMilanka RingwaldWhen sending RFCOMM data via *rfcomm_send*, BTstack needs to copy the data 606503a627eSMilanka Ringwaldfrom the user provided buffer into the outgoing buffer. This requires both 607503a627eSMilanka Ringwaldan additional buffer for the user data as well requires a copy operation. 608503a627eSMilanka Ringwald 609503a627eSMilanka RingwaldTo avoid this, it is possible to directly write the user data into the outgoing buffer. 610503a627eSMilanka Ringwald 611503a627eSMilanka RingwaldWhen get the RFCOMM_CAN_SEND_NOW event, you call *rfcomm_reserve_packet_buffer* to 612503a627eSMilanka Ringwaldlock the buffer for your send operation. Then, you can ask how many bytes you can send 613503a627eSMilanka Ringwaldwith *rfcomm_get_max_frame_size* and get a pointer to BTstack's buffer with 614503a627eSMilanka Ringwald*rfcomm_get_outgoing_buffer*. Now, you can fill that buffer and finally send the 615503a627eSMilanka Ringwalddata with *rfcomm_send_prepared*. 616503a627eSMilanka Ringwald 617503a627eSMilanka Ringwald 618503a627eSMilanka Ringwald## SDP - Service Discovery Protocol 619503a627eSMilanka Ringwald 620503a627eSMilanka RingwaldThe SDP protocol allows to announce services and discover services 621503a627eSMilanka Ringwaldprovided by a remote Bluetooth device. 622503a627eSMilanka Ringwald 623503a627eSMilanka Ringwald### Create and announce SDP records 624503a627eSMilanka Ringwald 625503a627eSMilanka RingwaldBTstack contains a complete SDP server and allows to register SDP 626503a627eSMilanka Ringwaldrecords. An SDP record is a list of SDP Attribute *{ID, Value}* pairs 627503a627eSMilanka Ringwaldthat are stored in a Data Element Sequence (DES). The Attribute ID is a 628503a627eSMilanka Ringwald16-bit number, the value can be of other simple types like integers or 629503a627eSMilanka Ringwaldstrings or can itself contain other DES. 630503a627eSMilanka Ringwald 631503a627eSMilanka RingwaldTo create an SDP record for an SPP service, you can call 632503a627eSMilanka Ringwald*spp_create_sdp_record* from with a pointer to a buffer to store the 633503a627eSMilanka Ringwaldrecord, the server channel number, and a record name. 634503a627eSMilanka Ringwald 635503a627eSMilanka RingwaldFor other types of records, you can use the other functions in, using 636503a627eSMilanka Ringwaldthe data element *de_* functions. Listing [sdpCreate] shows how an SDP 637503a627eSMilanka Ringwaldrecord containing two SDP attributes can be created. First, a DES is 638503a627eSMilanka Ringwaldcreated and then the Service Record Handle and Service Class ID List 639503a627eSMilanka Ringwaldattributes are added to it. The Service Record Handle attribute is added 640503a627eSMilanka Ringwaldby calling the *de_add_number* function twice: the first time to add 641503a627eSMilanka Ringwald0x0000 as attribute ID, and the second time to add the actual record 642503a627eSMilanka Ringwaldhandle (here 0x1000) as attribute value. The Service Class ID List 643503a627eSMilanka Ringwaldattribute has ID 0x0001, and it requires a list of UUIDs as attribute 644503a627eSMilanka Ringwaldvalue. To create the list, *de_push_sequence* is called, which “opens” 645503a627eSMilanka Ringwalda sub-DES. The returned pointer is used to add elements to this sub-DES. 646503a627eSMilanka RingwaldAfter adding all UUIDs, the sub-DES is “closed” with 647503a627eSMilanka Ringwald*de_pop_sequence*. 648503a627eSMilanka Ringwald 649503a627eSMilanka RingwaldTo register an SDP record, you call *sdp_register_service* with a pointer to it. 650503a627eSMilanka RingwaldThe SDP record can be stored in FLASH since BTstack only stores the pointer. 651503a627eSMilanka RingwaldPlease note that the buffer needs to persist (e.g. global storage, dynamically 652503a627eSMilanka Ringwaldallocated from the heap or in FLASH) and cannot be used to create another SDP 653503a627eSMilanka Ringwaldrecord. 654503a627eSMilanka Ringwald 655503a627eSMilanka Ringwald### Query remote SDP service {#sec:querySDPProtocols} 656503a627eSMilanka Ringwald 657503a627eSMilanka RingwaldBTstack provides an SDP client to query SDP services of a remote device. 658820e47d0SMilanka RingwaldThe SDP Client API is shown in [here](../appendix/apis/#sec:sdpAPIAppendix). The 659503a627eSMilanka Ringwald*sdp_client_query* function initiates an L2CAP connection to the 660503a627eSMilanka Ringwaldremote SDP server. Upon connect, a *Service Search Attribute* request 661503a627eSMilanka Ringwaldwith a *Service Search Pattern* and a *Attribute ID List* is sent. The 662503a627eSMilanka Ringwaldresult of the *Service Search Attribute* query contains a list of 663503a627eSMilanka Ringwald*Service Records*, and each of them contains the requested attributes. 664503a627eSMilanka RingwaldThese records are handled by the SDP parser. The parser delivers 665503a627eSMilanka RingwaldSDP_PARSER_ATTRIBUTE_VALUE and SDP_PARSER_COMPLETE events via a 666503a627eSMilanka Ringwaldregistered callback. The SDP_PARSER_ATTRIBUTE_VALUE event delivers 667503a627eSMilanka Ringwaldthe attribute value byte by byte. 668503a627eSMilanka Ringwald 669503a627eSMilanka RingwaldOn top of this, you can implement specific SDP queries. For example, 670503a627eSMilanka RingwaldBTstack provides a query for RFCOMM service name and channel number. 671503a627eSMilanka RingwaldThis information is needed, e.g., if you want to connect to a remote SPP 672503a627eSMilanka Ringwaldservice. The query delivers all matching RFCOMM services, including its 673503a627eSMilanka Ringwaldname and the channel number, as well as a query complete event via a 674503a627eSMilanka Ringwaldregistered callback, as shown in Listing [below](#lst:SDPClientRFCOMM). 675503a627eSMilanka Ringwald 676503a627eSMilanka Ringwald 677503a627eSMilanka Ringwald~~~~ {#lst:SDPClientRFCOMM .c caption="{Searching RFCOMM services on a remote device.}"} 678503a627eSMilanka Ringwald 679503a627eSMilanka Ringwald bd_addr_t remote = {0x04,0x0C,0xCE,0xE4,0x85,0xD3}; 680503a627eSMilanka Ringwald 681503a627eSMilanka Ringwald void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 682503a627eSMilanka Ringwald if (packet_type != HCI_EVENT_PACKET) return; 683503a627eSMilanka Ringwald 684503a627eSMilanka Ringwald uint8_t event = packet[0]; 685503a627eSMilanka Ringwald switch (event) { 686503a627eSMilanka Ringwald case BTSTACK_EVENT_STATE: 687503a627eSMilanka Ringwald // bt stack activated, get started 688503a627eSMilanka Ringwald if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING){ 689503a627eSMilanka Ringwald sdp_client_query_rfcomm_channel_and_name_for_uuid(remote, 0x0003); 690503a627eSMilanka Ringwald } 691503a627eSMilanka Ringwald break; 692503a627eSMilanka Ringwald default: 693503a627eSMilanka Ringwald break; 694503a627eSMilanka Ringwald } 695503a627eSMilanka Ringwald } 696503a627eSMilanka Ringwald 697503a627eSMilanka Ringwald static void btstack_setup(){ 698503a627eSMilanka Ringwald ... 699503a627eSMilanka Ringwald // init L2CAP 700503a627eSMilanka Ringwald l2cap_init(); 701503a627eSMilanka Ringwald l2cap_register_packet_handler(packet_handler); 702503a627eSMilanka Ringwald } 703503a627eSMilanka Ringwald 704503a627eSMilanka Ringwald void handle_query_rfcomm_event(sdp_query_event_t * event, void * context){ 705503a627eSMilanka Ringwald sdp_client_query_rfcomm_service_event_t * ve; 706503a627eSMilanka Ringwald 707503a627eSMilanka Ringwald switch (event->type){ 708503a627eSMilanka Ringwald case SDP_EVENT_QUERY_RFCOMM_SERVICE: 709503a627eSMilanka Ringwald ve = (sdp_client_query_rfcomm_service_event_t*) event; 710503a627eSMilanka Ringwald printf("Service name: '%s', RFCOMM port %u\n", ve->service_name, ve->channel_nr); 711503a627eSMilanka Ringwald break; 712503a627eSMilanka Ringwald case SDP_EVENT_QUERY_COMPLETE: 713503a627eSMilanka Ringwald report_found_services(); 714503a627eSMilanka Ringwald printf("Client query response done with status %d. \n", ce->status); 715503a627eSMilanka Ringwald break; 716503a627eSMilanka Ringwald } 717503a627eSMilanka Ringwald } 718503a627eSMilanka Ringwald 719503a627eSMilanka Ringwald int main(void){ 720503a627eSMilanka Ringwald hw_setup(); 721503a627eSMilanka Ringwald btstack_setup(); 722503a627eSMilanka Ringwald 723503a627eSMilanka Ringwald // register callback to receive matching RFCOMM Services and 724503a627eSMilanka Ringwald // query complete event 725503a627eSMilanka Ringwald sdp_client_query_rfcomm_register_callback(handle_query_rfcomm_event, NULL); 726503a627eSMilanka Ringwald 727503a627eSMilanka Ringwald // turn on! 728503a627eSMilanka Ringwald hci_power_control(HCI_POWER_ON); 729503a627eSMilanka Ringwald // go! 730503a627eSMilanka Ringwald btstack_run_loop_execute(); 731503a627eSMilanka Ringwald return 0; 732503a627eSMilanka Ringwald } 733503a627eSMilanka Ringwald~~~~ 734503a627eSMilanka Ringwald 735503a627eSMilanka Ringwald## BNEP - Bluetooth Network Encapsulation Protocol 736503a627eSMilanka Ringwald 737503a627eSMilanka RingwaldThe BNEP protocol is used to transport control and data packets over 738503a627eSMilanka Ringwaldstandard network protocols such as TCP, IPv4 or IPv6. It is built on top 739503a627eSMilanka Ringwaldof L2CAP, and it specifies a minimum L2CAP MTU of 1691 bytes. 740503a627eSMilanka Ringwald 741503a627eSMilanka Ringwald### Receive BNEP events 742503a627eSMilanka Ringwald 743503a627eSMilanka RingwaldTo receive BNEP events, please register a packet handler with 744503a627eSMilanka Ringwald*bnep_register_packet_handler*. 745503a627eSMilanka Ringwald 746503a627eSMilanka Ringwald### Access a BNEP service on a remote device {#sec:bnepClientProtocols} 747503a627eSMilanka Ringwald 748503a627eSMilanka RingwaldTo connect to a remote BNEP service, you need to know its UUID. The set 749503a627eSMilanka Ringwaldof available UUIDs can be queried by a SDP query for the PAN profile. 750820e47d0SMilanka RingwaldPlease see section on [PAN profile](../profiles/#sec:panProfiles) for details. 751503a627eSMilanka RingwaldWith the remote UUID, you can create a connection using the *bnep_connect* 752503a627eSMilanka Ringwaldfunction. You’ll receive a *BNEP_EVENT_CHANNEL_OPENED* on success or 753503a627eSMilanka Ringwaldfailure. 754503a627eSMilanka Ringwald 755503a627eSMilanka RingwaldAfter the connection was opened successfully, you can send and receive 756503a627eSMilanka RingwaldEthernet packets. Before sending an Ethernet frame with *bnep_send*, 757503a627eSMilanka Ringwald*bnep_can_send_packet_now* needs to return true. Ethernet frames 758503a627eSMilanka Ringwaldare received via the registered packet handler with packet type 759503a627eSMilanka Ringwald*BNEP_DATA_PACKET*. 760503a627eSMilanka Ringwald 761503a627eSMilanka RingwaldBTstack BNEP implementation supports both network protocol filter and 762503a627eSMilanka Ringwaldmulticast filters with *bnep_set_net_type_filter* and 763503a627eSMilanka Ringwald*bnep_set_multicast_filter* respectively. 764503a627eSMilanka Ringwald 765503a627eSMilanka RingwaldFinally, to close a BNEP connection, you can call *bnep_disconnect*. 766503a627eSMilanka Ringwald 767503a627eSMilanka Ringwald### Provide BNEP service {#sec:bnepServiceProtocols} 768503a627eSMilanka Ringwald 769503a627eSMilanka RingwaldTo provide a BNEP service, call *bnep_register_service* with the 770503a627eSMilanka Ringwaldprovided service UUID and a max frame size. 771503a627eSMilanka Ringwald 772503a627eSMilanka RingwaldA *BNEP_EVENT_INCOMING_CONNECTION* event will mark that an incoming 773503a627eSMilanka Ringwaldconnection is established. At this point you can start sending and 774503a627eSMilanka Ringwaldreceiving Ethernet packets as described in the previous section. 775503a627eSMilanka Ringwald 776503a627eSMilanka Ringwald### Sending Ethernet packets 777503a627eSMilanka Ringwald 778503a627eSMilanka RingwaldSimilar to L2CAP and RFOMM, directly sending an Ethernet packet via BNEP might fail, 779503a627eSMilanka Ringwaldif the outgoing packet buffer or the ACL buffers in the Bluetooth module are full. 780503a627eSMilanka Ringwald 781503a627eSMilanka RingwaldWhen there's a need to send an Ethernet packet, call *bnep_request_can_send_now* 782503a627eSMilanka Ringwaldand send the packet when the BNEP_EVENT_CAN_SEND_NOW event 783503a627eSMilanka Ringwaldgets received. 784503a627eSMilanka Ringwald 785503a627eSMilanka Ringwald 786503a627eSMilanka Ringwald## ATT - Attribute Protocol 787503a627eSMilanka Ringwald 788503a627eSMilanka RingwaldThe ATT protocol is used by an ATT client to read and write attribute 789503a627eSMilanka Ringwaldvalues stored on an ATT server. In addition, the ATT server can notify 790503a627eSMilanka Ringwaldthe client about attribute value changes. An attribute has a handle, a 791503a627eSMilanka Ringwaldtype, and a set of properties. 792503a627eSMilanka Ringwald 793503a627eSMilanka RingwaldThe Generic Attribute (GATT) profile is built upon ATT and provides 794503a627eSMilanka Ringwaldhigher level organization of the ATT attributes into GATT Services and 795503a627eSMilanka RingwaldGATT Characteristics. In BTstack, the complete ATT client functionality 796820e47d0SMilanka Ringwaldis included within the GATT Client. See [GATT client](../profiles/#sec:GATTClientProfiles) for more. 797503a627eSMilanka Ringwald 798503a627eSMilanka RingwaldOn the server side, one ore more GATT profiles are converted ahead of time 799503a627eSMilanka Ringwaldinto the corresponding ATT attribute database and provided by the *att_server* 800503a627eSMilanka Ringwaldimplementation. The constant data are automatically served by the ATT server upon client 801503a627eSMilanka Ringwaldrequest. To receive the dynamic data, such is characteristic value, the 802503a627eSMilanka Ringwaldapplication needs to register read and/or write callback. In addition, 803503a627eSMilanka Ringwaldnotifications and indications can be sent. Please see Section on 804820e47d0SMilanka Ringwald[GATT server](../profiles/#sec:GATTServerProfile) for more. 805503a627eSMilanka Ringwald 806503a627eSMilanka Ringwald## SMP - Security Manager Protocol {#sec:smpProtocols} 807503a627eSMilanka Ringwald 808503a627eSMilanka RingwaldThe SMP protocol allows to setup authenticated and encrypted LE 809503a627eSMilanka Ringwaldconnection. After initialization and configuration, SMP handles security 810503a627eSMilanka Ringwaldrelated functions on its own but emits events when feedback from the 811503a627eSMilanka Ringwaldmain app or the user is required. The two main tasks of the SMP protocol 812503a627eSMilanka Ringwaldare: bonding and identity resolving. 813503a627eSMilanka Ringwald 814503a627eSMilanka Ringwald### LE Legacy Pairing and LE Secure Connections 815503a627eSMilanka Ringwald 816503a627eSMilanka RingwaldThe original pairing algorithm introduced in Bluetooth Core V4.0 does not 817503a627eSMilanka Ringwaldprovide security in case of an attacker present during the initial pairing. 818503a627eSMilanka RingwaldTo fix this, the Bluetooth Core V4.2 specification introduced the new 819503a627eSMilanka Ringwald*LE Secure Connections* method, while referring to the original method as *LE Legacy Pairing*. 820503a627eSMilanka Ringwald 821503a627eSMilanka RingwaldBTstack supports both pairing methods. To enable the more secure LE Secure Connections method, 822503a627eSMilanka Ringwald*ENABLE_LE_SECURE_CONNECTIONS* needs to be defined in *btstack_config.h*. 823503a627eSMilanka Ringwald 824503a627eSMilanka RingwaldLE Secure Connections are based on Elliptic Curve Diffie-Hellman (ECDH) algorithm for the key exchange. 825503a627eSMilanka RingwaldOn start, a new public/private key pair is generated. During pairing, the 826503a627eSMilanka RingwaldLong Term Key (LTK) is generated based on the local keypair and the remote public key. 827503a627eSMilanka RingwaldTo facilitate the creation of such a keypairs and the calculation of the LTK, 828503a627eSMilanka Ringwaldthe Bluetooth Core V4.2 specification introduced appropriate commands for the Bluetooth controller. 829503a627eSMilanka Ringwald 830503a627eSMilanka RingwaldAs an alternative for controllers that don't provide these primitives, BTstack provides the relevant cryptographic functions in software via the BSD-2-Clause licensed [micro-ecc library](https://github.com/kmackay/micro-ecc/tree/static). 831503a627eSMilanka RingwaldWhen using using LE Secure Connections, the Peripheral must store LTK in non-volatile memory. 832503a627eSMilanka Ringwald 833503a627eSMilanka RingwaldTo only allow LE Secure Connections, you can call *sm_set_secure_connections_only_mode(true)*. 834503a627eSMilanka Ringwald 835503a627eSMilanka Ringwald 836503a627eSMilanka Ringwald### Initialization 837503a627eSMilanka Ringwald 838503a627eSMilanka RingwaldTo activate the security manager, call *sm_init()*. 839503a627eSMilanka Ringwald 840503a627eSMilanka RingwaldIf you’re creating a product, you should also call *sm_set_ir()* and 841503a627eSMilanka Ringwald*sm_set_er()* with a fixed random 16 byte number to create the IR and 842503a627eSMilanka RingwaldER key seeds. If possible use a unique random number per device instead 843503a627eSMilanka Ringwaldof deriving it from the product serial number or something similar. The 844503a627eSMilanka Ringwaldencryption key generated by the BLE peripheral will be ultimately 845503a627eSMilanka Ringwaldderived from the ER key seed. See 846503a627eSMilanka Ringwald[Bluetooth Specification](https://www.bluetooth.org/Technical/Specifications/adopted.htm) - 847503a627eSMilanka RingwaldBluetooth Core V4.0, Vol 3, Part G, 5.2.2 for more details on deriving 848503a627eSMilanka Ringwaldthe different keys. The IR key is used to identify a device if private, 849503a627eSMilanka Ringwaldresolvable Bluetooth addresses are used. 850503a627eSMilanka Ringwald 851503a627eSMilanka Ringwald 852503a627eSMilanka Ringwald### Configuration 853503a627eSMilanka Ringwald 854503a627eSMilanka RingwaldTo receive events from the Security Manager, a callback is necessary. 855503a627eSMilanka RingwaldHow to register this packet handler depends on your application 856503a627eSMilanka Ringwaldconfiguration. 857503a627eSMilanka Ringwald 858503a627eSMilanka RingwaldWhen *att_server* is used to provide a GATT/ATT service, *att_server* 859503a627eSMilanka Ringwaldregisters itself as the Security Manager packet handler. Security 860503a627eSMilanka RingwaldManager events are then received by the application via the 861503a627eSMilanka Ringwald*att_server* packet handler. 862503a627eSMilanka Ringwald 863503a627eSMilanka RingwaldIf *att_server* is not used, you can directly register your packet 864503a627eSMilanka Ringwaldhandler with the security manager by calling 865503a627eSMilanka Ringwald*sm_register_packet_handler*. 866503a627eSMilanka Ringwald 867503a627eSMilanka RingwaldThe default SMP configuration in BTstack is to be as open as possible: 868503a627eSMilanka Ringwald 869503a627eSMilanka Ringwald- accept all Short Term Key (STK) Generation methods, 870503a627eSMilanka Ringwald 871503a627eSMilanka Ringwald- accept encryption key size from 7..16 bytes, 872503a627eSMilanka Ringwald 873503a627eSMilanka Ringwald- expect no authentication requirements, 874503a627eSMilanka Ringwald 875503a627eSMilanka Ringwald- don't require LE Secure Connections, and 876503a627eSMilanka Ringwald 877503a627eSMilanka Ringwald- IO Capabilities set to *IO_CAPABILITY_NO_INPUT_NO_OUTPUT*. 878503a627eSMilanka Ringwald 879503a627eSMilanka RingwaldYou can configure these items by calling following functions 880503a627eSMilanka Ringwaldrespectively: 881503a627eSMilanka Ringwald 882503a627eSMilanka Ringwald- *sm_set_accepted_stk_generation_methods* 883503a627eSMilanka Ringwald 884503a627eSMilanka Ringwald- *sm_set_encryption_key_size_range* 885503a627eSMilanka Ringwald 886503a627eSMilanka Ringwald- *sm_set_authentication_requirements* : add SM_AUTHREQ_SECURE_CONNECTION flag to enable LE Secure Connections 887503a627eSMilanka Ringwald 888503a627eSMilanka Ringwald- *sm_set_io_capabilities* 889503a627eSMilanka Ringwald 890503a627eSMilanka Ringwald 891503a627eSMilanka Ringwald### Identity Resolving 892503a627eSMilanka Ringwald 893503a627eSMilanka RingwaldIdentity resolving is the process of matching a private, resolvable 894503a627eSMilanka RingwaldBluetooth address to a previously paired device using its Identity 895503a627eSMilanka RingwaldResolving (IR) key. After an LE connection gets established, BTstack 896503a627eSMilanka Ringwaldautomatically tries to resolve the address of this device. During this 897503a627eSMilanka Ringwaldlookup, BTstack will emit the following events: 898503a627eSMilanka Ringwald 899503a627eSMilanka Ringwald- *SM_EVENT_IDENTITY_RESOLVING_STARTED* to mark the start of a lookup, 900503a627eSMilanka Ringwald 901503a627eSMilanka Ringwaldand later: 902503a627eSMilanka Ringwald 903503a627eSMilanka Ringwald- *SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED* on lookup success, or 904503a627eSMilanka Ringwald 905503a627eSMilanka Ringwald- *SM_EVENT_IDENTITY_RESOLVING_FAILED* on lookup failure. 906503a627eSMilanka Ringwald 907503a627eSMilanka Ringwald 908503a627eSMilanka Ringwald### User interaction during Pairing 909503a627eSMilanka Ringwald 910503a627eSMilanka RingwaldBTstack will inform the app about pairing via theses events: 911503a627eSMilanka Ringwald 912503a627eSMilanka Ringwald - *SM_EVENT_PAIRING_STARTED*: inform user that pairing has started 913503a627eSMilanka Ringwald - *SM_EVENT_PAIRING_COMPLETE*: inform user that pairing is complete, see status 914503a627eSMilanka Ringwald 915503a627eSMilanka RingwaldDepending on the authentication requirements, IO capabilities, 916503a627eSMilanka Ringwaldavailable OOB data, and the enabled STK generation methods, 917503a627eSMilanka RingwaldBTstack will request feedback from 918503a627eSMilanka Ringwaldthe app in the form of an event: 919503a627eSMilanka Ringwald 920503a627eSMilanka Ringwald - *SM_EVENT_JUST_WORKS_REQUEST*: request a user to accept a Just Works pairing 921503a627eSMilanka Ringwald - *SM_EVENT_PASSKEY_INPUT_NUMBER*: request user to input a passkey 922503a627eSMilanka Ringwald - *SM_EVENT_PASSKEY_DISPLAY_NUMBER*: show a passkey to the user 923503a627eSMilanka Ringwald - *SM_EVENT_PASSKEY_DISPLAY_CANCEL*: cancel show passkey to user 924503a627eSMilanka Ringwald - *SM_EVENT_NUMERIC_COMPARISON_REQUEST*: show a passkey to the user and request confirmation 925503a627eSMilanka Ringwald 926503a627eSMilanka RingwaldTo accept Just Works/Numeric Comparison, or provide a Passkey, *sm_just_works_confirm* or *sm_passkey_input* can be called respectively. 927503a627eSMilanka RingwaldOthwerise, *sm_bonding_decline* aborts the pairing. 928503a627eSMilanka Ringwald 929503a627eSMilanka RingwaldAfter the bonding process, *SM_EVENT_PAIRING_COMPLETE*, is emitted. Any active dialog can be closed on this. 930503a627eSMilanka Ringwald 931503a627eSMilanka Ringwald### Connection with Bonded Devices 932503a627eSMilanka Ringwald 933503a627eSMilanka RingwaldDuring pairing, two devices exchange bonding information, notably a Long-Term Key (LTK) and their respective Identity Resolving Key (IRK). 934503a627eSMilanka RingwaldOn a subsequent connection, the Securit Manager will use this information to establish an encrypted connection. 935503a627eSMilanka Ringwald 936503a627eSMilanka RingwaldTo inform about this, the following events are emitted: 937503a627eSMilanka Ringwald 938503a627eSMilanka Ringwald - *SM_EVENT_REENCRYPTION_STARTED*: we have stored bonding information and either trigger encryption (as Central), or, sent a security request (as Peripheral). 939503a627eSMilanka Ringwald - *SM_EVENT_REENCRYPTION_COMPLETE*: re-encryption is complete. If the remote device does not have a stored LTK, the status code will be *ERROR_CODE_PIN_OR_KEY_MISSING*. 940503a627eSMilanka Ringwald 941503a627eSMilanka RingwaldThe *SM_EVENT_REENCRYPTION_COMPLETE* with *ERROR_CODE_PIN_OR_KEY_MISSING* can be caused: 942503a627eSMilanka Ringwald 943503a627eSMilanka Ringwald - if the remote device was reset or the bonding was removed, or, 944503a627eSMilanka Ringwald - we're connected to an attacker that uses the Bluetooth address of a bonded device. 945503a627eSMilanka Ringwald 946503a627eSMilanka RingwaldIn Peripheral role, pairing will start even in case of an re-encryption error. It might be helpful to inform the user about the lost bonding or reject it right away due to security considerations. 947503a627eSMilanka Ringwald 948503a627eSMilanka Ringwald 949503a627eSMilanka Ringwald### Keypress Notifications 950503a627eSMilanka Ringwald 951503a627eSMilanka RingwaldAs part of Bluetooth Core V4.2 specification, a device with a keyboard but no display can send keypress notifications to provide better user feedback. In BTstack, the *sm_keypress_notification()* function is used for sending notifications. Notifications are received by BTstack via the *SM_EVENT_KEYPRESS_NOTIFICATION* event. 952503a627eSMilanka Ringwald 953503a627eSMilanka Ringwald### Cross-transport Key Derivation (CTKD) for LE Secure Connections 954503a627eSMilanka Ringwald 955503a627eSMilanka RingwaldIn a dual-mode configuration, BTstack generates an BR/EDR Link Key from the LE LTK via the Link Key Conversion functions *h6* , 956503a627eSMilanka Ringwald(or *h7* if supported) when *ENABLE_CROSS_TRANSPORT_KEY_DERIVATION* is defined. 957503a627eSMilanka RingwaldThe derived key then stored in local LE Device DB. 958503a627eSMilanka Ringwald 959503a627eSMilanka RingwaldThe main use case for this is connections with smartphones. E.g. iOS provides APIs for LE scanning and connection, but none for BR/EDR. This allows an application to connect and pair with 960503a627eSMilanka Ringwalda device and also later setup a BR/EDR connection without the need for the smartphone user to use the system Settings menu. 961503a627eSMilanka Ringwald 962503a627eSMilanka RingwaldTo derive an LE LTK from a BR/EDR link key, the Bluetooth controller needs to support Secure Connections via NIST P-256 elliptic curves. BTstack does not support LE Secure Connections via LE Transport currently. 963503a627eSMilanka Ringwald 964503a627eSMilanka Ringwald### Out-of-Band Data with LE Legacy Pairing 965503a627eSMilanka Ringwald 966503a627eSMilanka RingwaldLE Legacy Pairing can be made secure by providing a way for both devices 967503a627eSMilanka Ringwaldto acquire a pre-shared secret 16 byte key by some fancy method. 968503a627eSMilanka RingwaldIn most cases, this is not an option, especially since popular OS like iOS 969503a627eSMilanka Ringwalddon’t provide a way to specify it. In some applications, where both 970503a627eSMilanka Ringwaldsides of a Bluetooth link are developed together, this could provide a 971503a627eSMilanka Ringwaldviable option. 972503a627eSMilanka Ringwald 973503a627eSMilanka RingwaldTo provide OOB data, you can register an OOB data callback with 974503a627eSMilanka Ringwald*sm_register_oob_data_callback*. 975