xref: /btstack/doc/manual/docs-template/protocols.md (revision 849f0fb42e98c1fff4bdcbddc36037b16efbe362)
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![Architecture of a BTstack-based application.](picts/btstack-protocols.png) {#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