IncludingQuickstartGuide - BlueKitchen GmbH · 2020. 12. 11. · VERSION1.0 December11,2020...

448
Version v1.4 (77e1642ef) May 31, 2021 BTstack Manual Including Quickstart Guide Dr. sc. Milanka Ringwald Dr. sc. Matthias Ringwald [email protected]

Transcript of IncludingQuickstartGuide - BlueKitchen GmbH · 2020. 12. 11. · VERSION1.0 December11,2020...

  • Version v1.4 (77e1642ef)May 31, 2021

    BTstack ManualIncluding Quickstart Guide

    Dr. sc. Milanka RingwaldDr. sc. Matthias Ringwald

    [email protected]

    [email protected]

  • 1

    Contents

    0.1. General Tools 20.2. Getting BTstack from GitHub 20.3. Let’s Go 20.4. Single threaded design 30.5. No blocking anywhere 40.6. No artificially limited buffers/pools 40.7. Statically bounded memory 40.8. Configuration in btstack config.h 50.8.1. HAVE * directives 50.8.2. ENABLE * directives 60.8.3. HCI Controller to Host Flow Control 80.8.4. Memory configuration directives 80.8.5. Non-volatile memory (NVM) directives 90.8.6. SEGGER Real Time Transfer (RTT) directives 100.9. Run-time configuration 100.10. Source tree structure 110.11. Run loop configuration 120.11.1. Run loop embedded 130.11.2. Run loop FreeRTOS 130.11.3. Run loop POSIX 140.11.4. Run loop CoreFoundation (OS X/iOS) 140.11.5. Run loop Windows 140.11.6. Run loop WICED 140.12. HCI Transport configuration 140.13. Services 160.14. Packet handlers configuration 160.15. Bluetooth HCI Packet Logs 170.16. Bluetooth Power Control 190.17. HCI - Host Controller Interface 200.17.1. Defining custom HCI command templates 210.17.2. Sending HCI command based on a template 220.18. L2CAP - Logical Link Control and Adaptation Protocol 230.18.1. Access an L2CAP service on a remote device 230.18.2. Provide an L2CAP service 240.18.3. Sending L2CAP Data 250.18.4. LE Data Channels 250.19. RFCOMM - Radio Frequency Communication Protocol 260.19.1. No RFCOMM packet boundaries 260.19.2. RFCOMM flow control 270.19.3. Access an RFCOMM service on a remote device 270.19.4. Provide an RFCOMM service 280.19.5. Slowing down RFCOMM data reception 290.19.6. Sending RFCOMM data 300.19.7. Optimized sending of RFCOMM data 310.20. SDP - Service Discovery Protocol 31

  • 2

    0.20.1. Create and announce SDP records 310.20.2. Query remote SDP service 320.21. BNEP - Bluetooth Network Encapsulation Protocol 340.21.1. Receive BNEP events 340.21.2. Access a BNEP service on a remote device 340.21.3. Provide BNEP service 340.21.4. Sending Ethernet packets 340.22. ATT - Attribute Protocol 340.23. SMP - Security Manager Protocol 350.23.1. LE Legacy Pairing and LE Secure Connections 350.23.2. Initialization 350.23.3. Configuration 350.23.4. Identity Resolving 360.23.5. User interaction during Pairing 360.23.6. Connection with Bonded Devices 370.23.7. Keypress Notifications 370.23.8. Cross-transport Key Derivation (CTKD) for LE Secure

    Connections 370.23.9. Out-of-Band Data with LE Legacy Pairing 370.24. GAP - Generic Access Profile: Classic 380.24.1. Become discoverable 380.24.2. Discover remote devices 380.24.3. Pairing of Devices 400.24.4. Dedicated Bonding 410.25. SPP - Serial Port Profile 410.25.1. Accessing an SPP Server on a remote device 410.25.2. Providing an SPP Server 410.26. PAN - Personal Area Networking Profile 410.26.1. Accessing a remote PANU service 420.26.2. Providing a PANU service 420.27. HSP - Headset Profile 420.28. HFP - Hands-Free Profile 420.29. HID - Human-Interface Device Profile 430.30. GAP LE - Generic Access Profile for Low Energy 430.30.1. Private addresses. 430.30.2. Advertising and Discovery 430.31. GATT Client 440.31.1. Authentication 440.32. GATT Server 450.32.1. Implementing Standard GATT Services 470.32.2. GATT Database Hash 490.33. Battery Service Server 490.34. Cycling Power Service Server 500.35. Cycling Speed and Cadence Service Server 500.36. Device Information Service Server 500.37. Heart Rate Service Server 500.38. HIDS Device 51

  • 3

    0.39. Mesh Provisioning Service Server 510.40. Mesh Proxy Service Server 510.41. Nordic SPP Service Server 510.42. Scan Parameters Service Server 510.43. u-blox SPP Service Server 510.44. ANCS Client 510.45. Battery Service Client 520.46. Device Information Service Client 520.47. HIDS Client 520.48. Scan Parameters Service Client 520.49. Hello World - Blinking an LED without Bluetooth 540.49.1. Periodic Timer Setup 540.49.2. Main Application Setup 540.50. GAP Classic Inquiry 550.50.1. Bluetooth Logic 550.50.2. Main Application Setup 550.51. GAP Link Key Management (Classic) 560.51.1. GAP Link Key Logic 560.51.2. Bluetooth Logic 560.51.3. Main Application Setup 560.52. GAP LE Advertisements Scanner 560.52.1. GAP LE setup for receiving advertisements 560.52.2. GAP LE Advertising Data Dumper 570.52.3. HCI packet handler 600.53. GATT Client - Discover Primary Services 600.53.1. GATT client setup 610.53.2. HCI packet handler 610.53.3. GATT Client event handler 620.54. GATT Server - Heartbeat Counter over GATT 640.54.1. Main Application Setup 640.54.2. Heartbeat Handler 660.54.3. Packet Handler 660.54.4. ATT Read 670.54.5. ATT Write 670.55. Performance - Stream Data over GATT (Server) 680.55.1. Main Application Setup 680.55.2. Track throughput 690.55.3. HCI Packet Handler 700.55.4. ATT Packet Handler 710.55.5. Streamer 720.55.6. ATT Write 730.56. GATT Battery Service Client 750.56.1. Main Application Setup 750.57. GATT Device Information Service Client 780.57.1. Main Application Setup 780.58. GATT Heart Rate Sensor Client 800.59. LE Nordic SPP-like Heartbeat Server 80

  • 4

    0.59.1. Main Application Setup 800.59.2. Heartbeat Handler 810.59.3. Packet Handler 820.60. LE Nordic SPP-like Streamer Server 820.60.1. Track throughput 820.60.2. HCI Packet Handler 830.60.3. ATT Packet Handler 840.60.4. Streamer 850.61. LE u-blox SPP-like Heartbeat Server 860.61.1. Main Application Setup 860.61.2. Heartbeat Handler 870.61.3. Packet Handler 870.62. LE Central - Test Pairing Methods 880.62.1. GAP LE setup for receiving advertisements 880.62.2. HCI packet handler 900.62.3. HCI packet handler 900.63. LE Peripheral - Test Pairing Methods 930.63.1. Main Application Setup 940.63.2. Packet Handler 960.64. LE Data Channel Client - Send Data over L2CAP 990.64.1. Track throughput 990.64.2. Streamer 1000.64.3. SM Packet Handler 1010.65. LE Data Channel Server - Receive data over L2CAP 1010.65.1. Main Application Setup 1010.65.2. Track throughput 1020.65.3. Streamer 1020.65.4. HCI + L2CAP Packet Handler 1030.65.5. SM Packet Handler 1030.66. LE Peripheral - Delayed Response 1030.66.1. Main Application Setup 1030.66.2. att invalidate value Handler 1040.66.3. att update value Handler 1040.66.4. ATT Read 1050.66.5. ATT Write 1050.67. LE ANCS Client - Apple Notification Service 1070.68. LE Man-in-the-Middle Tool 1070.69. Performance - Stream Data over GATT (Client) 1070.69.1. Track throughput 1070.70. Performance - Stream Data over GATT (Server) 1080.70.1. Main Application Setup 1080.70.2. Track throughput 1090.70.3. HCI Packet Handler 1100.70.4. ATT Packet Handler 1110.70.5. Streamer 1120.70.6. ATT Write 1130.71. LE Data Channel Client - Send Data over L2CAP 115

  • 5

    0.71.1. Track throughput 1150.71.2. Streamer 1160.71.3. SM Packet Handler 1160.72. LE Data Channel Server - Receive data over L2CAP 1160.72.1. Main Application Setup 1160.72.2. Track throughput 1170.72.3. Streamer 1180.72.4. HCI + L2CAP Packet Handler 1180.72.5. SM Packet Handler 1180.73. Performance - Stream Data over SPP (Client) 1180.73.1. Track throughput 1190.73.2. SDP Query Packet Handler 1190.73.3. Gerenal Packet Handler 1190.73.4. Main Application Setup 1190.74. Performance - Stream Data over SPP (Server) 1200.74.1. Track throughput 1200.74.2. Packet Handler 1210.74.3. Main Application Setup 1210.75. A2DP Sink - Receive Audio Stream and Control Playback 1220.75.1. Main Application Setup 1220.75.2. Handle Media Data Packet 1250.76. A2DP Source - Stream Audio and Control Volume 1250.76.1. Main Application Setup 1250.77. AVRCP Browsing - Browse Media Players and Media Information 1280.77.1. Main Application Setup 1280.78. HFP AG - Audio Gateway 1310.78.1. Main Application Setup 1310.79. HFP HF - Hands-Free 1320.79.1. Main Application Setup 1320.80. HSP AG - Audio Gateway 1340.80.1. Audio Transfer Setup 1340.80.2. Main Application Setup 1340.81. HSP HS - Headset 1350.81.1. Audio Transfer Setup 1350.81.2. Main Application Setup 1350.82. Audio Driver - Play Sine 1360.83. Audio Driver - Play 80’s MOD Song 1360.84. Audio Driver - Forward Audio from Source to Sink 1360.85. SPP Server - Heartbeat Counter over RFCOMM 1360.85.1. SPP Service Setup 1370.85.2. Periodic Timer Setup 1370.85.3. Bluetooth Logic 1380.86. SPP Server - RFCOMM Flow Control 1400.86.1. SPP Service Setup 1400.86.2. Periodic Timer Setup 1400.87. PAN - lwIP HTTP and DHCP Server 1410.87.1. Packet Handler 141

  • 6

    0.87.2. PAN BNEP Setup 1410.87.3. DHCP Server Configuration 1410.87.4. Large File Download 1410.87.5. DHCP Server Setup 1410.87.6. Main 1410.88. BNEP/PANU (Linux only) 1420.88.1. Main application configuration 1420.88.2. SDP parser callback 1430.88.3. Packet Handler 1430.88.4. Network packet handler 1450.89. HID Keyboard Classic 1450.89.1. Main Application Setup 1450.90. HID Mouse Classic 1470.90.1. Main Application Setup 1470.91. HID Host Classic 1490.91.1. Main application configuration 1490.91.2. HID Report Handler 1490.91.3. Packet Handler 1490.92. HID Keyboard LE 1520.93. HID Mouse LE 1520.94. HID Boot Host LE 1520.94.1. HOG Boot Keyboard Handler 1520.94.2. HOG Boot Mouse Handler 1530.94.3. Test if advertisement contains HID UUID 1530.94.4. HCI packet handler 1540.95. Dual Mode - SPP and LE Counter 1560.95.1. Advertisements 1560.95.2. Packet Handler 1560.95.3. Heartbeat Handler 1560.95.4. Main Application Setup 1570.96. Performance - Stream Data over GATT (Server) 1580.96.1. Main Application Setup 1590.96.2. Track throughput 1600.96.3. HCI Packet Handler 1600.96.4. ATT Packet Handler 1620.96.5. Streamer 1630.96.6. ATT Write 1640.97. SDP Client - Query Remote SDP Records 1650.97.1. SDP Client Setup 1650.97.2. SDP Client Query 1660.97.3. Handling SDP Client Query Results 1660.98. SDP Client - Query RFCOMM SDP record 1670.99. SDP Client - Query BNEP SDP record 1670.99.1. SDP Client Setup 1680.99.2. SDP Client Query 1680.99.3. Handling SDP Client Query Result 1690.100. PBAP Client - Get Contacts from Phonebook Server 170

  • 7

    0.101. Testing - Enable Device Under Test (DUT) Mode for Classic 1700.101.1. Bluetooth Logic 1700.101.2. Main Application Setup 1710.102. HCI Interface 1710.102.1. HCI H2 1710.102.2. HCI H4 1720.102.3. HCI H5 1720.102.4. BCSP 1720.102.5. eHCILL 1730.102.6. H4 over SPI 1730.102.7. HCI Shortcomings 1730.103. Documentation and Support 1730.104. Chipset Overview 1770.105. Atmel/Microchip 1770.106. Broadcom/Cypress Semiconductor 1780.107. CSR / Qualcomm Incorporated 1790.108. Dialog Semiconductor 1790.109. Espressif ESP32 1800.110. EM Microelectronic Marin 1800.111. Intel Dual Wireless 8260, 8265 1810.112. Nordic nRF5 series 1810.113. Renesas Electronics 1820.114. STMicroelectronics 1820.115. Texas Instruments CC256x series 1820.116. Toshiba 1840.117. Time Abstraction Layer 1840.117.1. Tick Hardware Abstraction 1840.117.2. Time MS Hardware Abstraction 1850.118. Bluetooth Hardware Control API 1850.119. HCI Transport Implementation 1850.119.1. HCI UART Transport Layer (H4) 1850.119.2. H4 with eHCILL support 1860.119.3. H5 1860.120. Persistent Storage APIs 1870.120.1. Link Key DB 1870.121. Existing ports 1870.122. BTstack Port for Ambiq Apollo2 with EM9304 1880.122.1. Hardware 1880.122.2. Software 1880.122.3. Create Example Projects 1880.122.4. Compile & Run Example Project 1890.122.5. Debug output 1890.122.6. TODO 1890.123. Archive of earlier ports 1890.124. BTstack Port for the Espressif ESP32 Platform 1900.124.1. Setup 1900.124.2. Usage 190

  • 8

    0.124.3. Old Make Versions 1910.124.4. Configuration 1910.124.5. Limitations 1910.124.6. Issues with the Bluetooth Controller Implementation 1910.124.7. Audio playback 1910.124.8. Multi-Threading 1910.124.9. Acknowledgments 1920.125. BTstack Port for POSIX Systems with libusb Library 1920.125.1. Compilation 1920.125.2. Environment Setup 1920.125.3. Linux 1920.125.4. macOS 1930.125.5. Running the examples 1930.126. BTstack Port for POSIX Systems with Intel Wireless 8260/8265

    Controllers 1940.126.1. Compilation 1940.126.2. Environment 1940.126.3. Running the examples 1950.127. BTstack Port for the Maxim MAX32630FTHR ARM Cortex-M4F1960.127.1. Software 1960.127.2. Toolchain Setup 1960.127.3. Usage 1960.127.4. Build 1960.127.5. Eclipse 1960.127.6. Flashing Max32630 ARM Processor 1960.127.7. Debugging 1970.127.8. Debug output 1970.127.9. TODOs 1970.128. BTstack Port for MSP432P401 Launchpad with CC256x 1970.128.1. Hardware 1970.128.2. Software 1980.128.3. Flash And Run The Examples 1980.128.4. Run Example Project using Ozone 1980.128.5. Debug output 1980.128.6. GATT Database 1980.129. BTstack Port with Cinnamon for Nordic nRF5 Series 1980.129.1. Status 1980.129.2. Requirements 1990.129.3. Supported Hardware 1990.129.4. Use 1990.130. BTstack Port for Zephyr RTOS running on Nordic nRF5 Series 1990.130.1. Overview 1990.130.2. Status 1990.130.3. Getting Started 1990.130.4. TODO 2000.131. BTstack Port for POSIX Systems with H4 Bluetooth Controller 2000.131.1. Configuration 200

  • 9

    0.131.2. TI CC256x 2000.131.3. Broadcom BCM/CYW 43430 2000.131.4. Compilation 2000.131.5. Running the examples 2000.132. BTstack Port for POSIX Systems with Atmel ATWILC3000

    Controller 2000.132.1. Compilation 2010.132.2. Usage 2010.133. BTstack Port for POSIX Systems with Dialog Semiconductor

    DA14581 Controller 2030.134. BTstack Port for POSIX Systems with Dialog Semiconductor

    DA14585 Controller 2030.135. BTstack Port for POSIX Systems with Zephyr-based Controller 2030.135.1. Prepare Zephyr Controller 2030.135.2. Configure serial port 2030.135.3. Compile Examples 2040.135.4. Run example 2040.136. BTstack Port for QT with H4 Bluetooth Controller 2040.136.1. Configuration 2040.136.2. TI CC256x 2040.136.3. Broadcom BCM/CYW 43430 2040.136.4. Compilation 2040.136.5. Running the examples 2040.137. BTstack Port for QT with USB Bluetooth Dongle 2050.137.1. Compilation 2050.137.2. Environment Setup 2050.137.3. Windows 2050.137.4. Linux 2050.137.5. macOS 2060.137.6. Running the examples 2060.138. BTstack Port for Raspberry Pi 3 with BCM4343 Bluetooth/Wifi

    Controller 2070.138.1. Raspberry Pi 3 / Zero W Setup 2070.138.2. Install Raspian Stretch Lite: 2070.138.3. Configure Wifi 2070.138.4. Enable SSH 2070.138.5. Boot 2070.138.6. Disable bluez 2070.138.7. Compilation 2080.138.8. Compile using Docker 2080.138.9. Running the examples 2090.138.10. Bluetooth Hardware Overview 2090.138.11. TODO 2090.139. BTstack Port for Renesas Target Board TB-S1JA with CC256x 2090.139.1. Hardware 2090.139.2. Software 2100.139.3. Excluded Examples 210

  • 10

    0.139.4. Build, Flash And Run The Examples in e2 Studio 2100.139.5. Run Example Project using Ozone 2100.139.6. Debug output 2110.139.7. GATT Database 2110.139.8. Notes 2110.139.9. Nice to have 2110.140. BTstack Port for SAMV71 Ultra Xplained with ATWILC3000

    SHIELD 2110.140.1. Create Example Projects 2110.140.2. Compile Example 2110.140.3. Debug output 2120.140.4. TODOs 2120.140.5. Issues 2120.141. BTstack Port for STM32 F4 Discovery Board with CC256x 2120.141.1. Hardware 2120.141.2. Software 2120.141.3. Flash And Run The Examples 2130.141.4. Run Example Project using Ozone 2130.141.5. Debug output 2130.141.6. GATT Database 2130.141.7. Maintainer Notes - Updating The Port 2130.142. BTstack Port for STM32 F4 Discovery Board with USB Bluetooth

    Controller 2130.142.1. Hardware 2130.142.2. Software 2140.142.3. Flash And Run The Examples 2140.142.4. Run Example Project using Ozone 2140.142.5. Debug output 2140.142.6. GATT Database 2140.142.7. Maintainer Notes - Updating The Port 2140.143. BTstack Port for STM32 Nucleo L073RZ Board with EM9304

    Controller 2140.143.1. Hardware 2150.143.2. Software 2150.143.3. Flash And Run The Examples 2150.143.4. Run Example Project using Ozone 2150.143.5. Debug output 2150.143.6. GATT Database 2150.143.7. Image 2170.144. BTstack Port with Cinnamon for Semtech SX1280 Controller on

    Miromico FMLR-80 2180.144.1. Overview 2180.144.2. Status 2180.144.3. Limitation 2180.144.4. Advertising State: 2180.144.5. Connection State: 2180.144.6. Central Role: 218

  • 11

    0.144.7. Observer Role: 2180.144.8. Low power mode - basically not implemented: 2180.144.9. Getting Started 2180.144.10. TODO 2180.144.11. General 2190.144.12. Low Power 2190.145. BTstack Port with Cinnamon for Semtech SX1280 Controller on

    STM32L476 Nucleo 2190.145.1. Overview 2190.145.2. Status 2190.145.3. Limitation 2190.145.4. Advertising State: 2190.145.5. Connection State: 2190.145.6. Central Role: 2190.145.7. Observer Role: 2200.145.8. Low power mode - basically not implemented: 2200.145.9. Getting Started 2200.145.10. TODO 2200.145.11. General 2200.145.12. Low Power 2200.146. BTstack Port for STM32WB55 Nucleo Boards using FreeRTOS 2220.146.1. Hardware 2220.146.2. Nucleo68 2220.146.3. USB Dongle 2220.146.4. Software 2220.146.5. Flash And Run The Examples 2220.146.6. Nucleo68 2230.146.7. USB Dongle 2230.146.8. Run Example Project using Ozone 2230.146.9. Debug output 2230.146.10. GATT Database 2230.147. BTstack Port for WICED platform 2230.148. BTstack Port for Windows Systems with Bluetooth Controller

    connected via Serial Port 2240.148.1. Toolchain 2240.148.2. Compilation 2240.148.3. Console Output 2250.149. BTstack Port for Windows Systems with DA14585 Controller

    connected via Serial Port 2250.149.1. Toolchain 2250.149.2. Compilation 2250.149.3. Console Output 2260.150. BTstack Port for Windows Systems with Zephyr-based Controller2260.150.1. Prepare Zephyr Controller 2260.150.2. Configure serial port 2260.150.3. Toolchain 2260.150.4. Compile Examples 227

  • 12

    0.150.5. Run example 2270.151. BTstack Port for Windows Systems using the WinUSB Driver 2270.151.1. Access to Bluetooth USB Dongle with Zadig 2270.151.2. Toolchain 2270.151.3. Compilation 2280.151.4. Console Output 2280.152. BTstack Port for Windows Systems with Intel Wireless 8260/8265

    Controllers 2280.152.1. Access to Bluetooth USB Dongle with Zadig 2280.152.2. Toolchain 2280.152.3. Compilation 2290.152.4. Console Output 2290.153. Adapting BTstack for Single-Threaded Environments 2290.154. Adapting BTstack for Multi-Threaded Environments 2301. APIs 2321.1. AD Data Parser API 2321.2. ATT Database Engine API 2321.3. Runtine ATT Database Setup API 2321.4. ATT Dispatch API 2351.5. ATT Server API 2351.6. ANCS Client API 2381.7. Battery Service Client API 2381.8. Battery Service Server API 2391.9. Cycling Power Service Server API 2401.10. Cycling Speed and Cadence Service Server API 2431.11. Device Information Service Client API 2441.12. Device Information Service Server API 2451.13. Heart Rate Service Server API 2471.14. HID Service Client API 2481.15. HID Service Server API 2521.16. Mesh Provisioning Service Server API 2531.17. Mesh Proxy Service Server API 2531.18. Nordic SPP Service Server API 2541.19. Scan Parameters Service Client API 2551.20. Scan Parameters Service Server API 2561.21. u-blox SPP Service Server API 2561.22. GATT Client API 2571.23. Device Database API 2771.24. Device Database TLV API 2791.25. Security Manager API 2801.26. Audio Interface API 2841.27. base64 Decoder API 2861.28. Chipset Driver API 2871.29. Bluetooth Power Control API 2881.30. Debug Messages API 2881.31. EM9304 SPI API 2891.32. Human Interface Device (HID) API 290

  • 13

    1.33. HID Parser API 2901.34. Linked List API 2921.35. Linked Queue API 2941.36. BTstack Memory Management API 2951.37. Network Interface API 2951.38. Lienar Resampling API 2961.39. Ring Buffer API 2971.40. Run Loop API 2981.41. SCO Transport API 3001.42. SLIP encoder/decoder API 3011.43. Tag-Value-Length Persistent Storage (TLV) API 3021.44. Empty TLV Instance API 3031.45. UART API 3031.46. UART Block API 3051.47. UART SLIP Wrapper API 3061.48. General Utility Functions API 3061.49. A2DP Sink API 3101.50. A2DP Source API 3131.51. AVDTP Sink API 3181.52. AVDTP Source API 3211.53. AVRCP Browsing API 3271.54. AVRCP Browsing Controller API 3281.55. AVRCP Browsing Target API 3311.56. AVRCP Controller API 3331.57. AVRCP Media Item Iterator API 3391.58. AVRCP Target API 3401.59. BNEP API 3441.60. Link Key DB API 3451.61. In-Memory Link Key Storage API 3471.62. Static Link Key Storage API 3471.63. Link Key TLV Storage API 3471.64. Device ID Server API 3481.65. GATT SDP API 3481.66. GOEP Client API 3481.67. HFP Audio Gateway (AG) API 3521.68. HFP GSM Model API 3591.69. HFP Hands-Free (HF) API 3601.70. HFP mSBC Encoder API 3681.71. HID Device API 3691.72. HID Host API 3711.73. HSP Audio Gateway API 3751.74. HSP Headset API 3771.75. Personal Area Network (PAN) API 3801.76. PBAP Client API 3811.77. RFCOMM API 3861.78. SDP Client API 3891.79. SDP Client RFCOMM API 391

  • 14

    1.80. SDP Server API 3921.81. SDP Utils API 3931.82. SPP Server API 3951.83. Genral Access Profile (GAP) API 3961.84. Host Controler Interface (HCI) API 4131.85. HCI Logging API 4161.86. HCI Transport API 4181.87. HCI Transport EM9304 API API 4201.88. HCI Transport H4 API 4201.89. HCI Transport H5 API 4201.90. HCI Transport USB API 4211.91. L2CAP API 4211.92. L2CAP Events 4271.93. RFCOMM Events 4281.94. Errors 4292. Changes 4292.1. Repository structure 4292.1.1. include/btstack folder 4292.1.2. Plural folder names 4292.1.3. ble and src folders 4302.1.4. platform and port folders 4302.1.5. Common file names 4302.2. Defines and event names 4302.3. Function names 4302.4. Packet Handlers 4302.5. Event Forwarding 4302.6. util folder 4302.7. btstack config.h 4312.8. Linked List 4312.9. Run Loop 4312.10. HCI Setup 4312.10.1. remote device db 4312.10.2. bt control 4312.11. HCI / GAP 4312.12. RFCOMM 4312.13. SPP Server 4312.14. SDP Client 4312.15. SDP Server 4322.16. Security Manager 4322.17. GATT Client 4322.18. ANCS Client 4322.19. Flow control / DAEMON EVENT HCI PACKET SENT 4322.20. Daemon 4322.21. Migration to v1.0 with a script 4322.21.1. Requirements 4332.21.2. Usage 433

  • 15

    2.22. Migration to v1.0 with a Web Service 433

  • 16

    Thanks for checking out BTstack!In this manual, we first provide a ‘quick starter guide’ for common platforms

    before highlighting BTstack’s main design choices and go over all implementedprotocols and profiles.

    A series of examples show how BTstack can be used to implement commonuse cases.

    Finally, we outline the basic steps when integrating BTstack into existingsingle-threaded or even multi-threaded environments.

    #Quick Start

    0.1. General Tools. Most ports use a regular Makefile to build the examples.On Unix-based systems, git, make, and Python are usually installed. If not,

    use the system’s packet manager to install them.On Windows, there is no packet manager, but it’s easy to download and install

    all requires development packets quickly by hand. You’ll need:

    • Python for Windows. When using the official installer, please confirmadding Python to the Windows Path.• MSYS2 is used to provide the bash shell and most standard POSIX com-

    mand line tools.• MinGW64 GCC for Windows 64 & 32 bits incl. make. To install with

    MSYS2: pacman -S mingw-w64-x86 64-gcc• git is used to download BTstack source code. To install with MSYS2:

    pacman -S git• winpty a wrapper to allow for console input when running in MSYS2: To

    install with MSYS2: pacman -S winpty

    0.2. Getting BTstack from GitHub. Use git to clone the latest version:

    g i t c l one https : // g i t hub . com/ b l u e k i t c h en / b t s t a c k . g i t

    Alternatively, you can download it as a ZIP archive from BTstack’s page onGitHub.

    0.3. Let’s Go. The easiest way to try BTstack is on a regular desktop setup likemacOS, Linux or Windows together with a standard USB Bluetooth Controller.Running BTstack on desktop speeds up the development cycle a lot and alsoprovides direct access to full packet log files in cases something doesn’t work asexpected. The same code can then later be run unmodified on an embeddedtarget.

    For macOS and Linux, please see libusb port. For Windows, please seewindows-winusb port.

    Or checkout the listofexistingportsports/existing ports.md)#BTstack ArchitectureAs well as any other communication stack, BTstack is a collection of state

    machines that interact with each other. There is one or more state machines foreach protocol and service that it implements. The rest of the architecture followsthese fundamental design guidelines:

    http://www.python.org/getit/https://msys2.github.iohttps://mingw-w64.org/doku.phphttps://git-scm.comhttps://github.com/rprichard/winptyhttps://github.com/bluekitchen/btstack/archive/master.zipports/existing_ports.md#libusbPortports/existing_ports.md#windows-winusbPort

  • 17

    BTstack  

    Main  Applica/on  

    Communica/on  Logic   PH  

    Run  Loop  Data  Source  

    Data  Source  

    Data  Source  

    Timeouts  

    Bluetooth  Single/Dual  Mode  Chipset  

    add data source

    data source ready

    Bluetooth  Stack  

    HCI  

    L2CAP  

    SDP   RFCOMM   ATT  

    LE  

    H4  UART   eHCILL  UART     USB  …

    add timer timer ready

    Architecture of a BTstack-based application.

    • Single threaded design - BTstack does not use or require multi-threadingto handle data sources and timers. Instead, it uses a single run loop.• No blocking anywhere - If Bluetooth processing is required, its result will

    be delivered as an event via registered packet handlers.• No artificially limited buffers/pools - Incoming and outgoing data packets

    are not queued.• Statically bounded memory (optionally) - The number of maximum con-

    nections/channels/services can be configured.

    Figure below shows the general architecture of a BTstack-based single-threadedapplication that includes the BTstack run loop. The Main Application containsthe application logic, e.g., reading a sensor value and providing it via the Com-munication Logic as a SPP Server. The Communication Logic is often modeledas a finite state machine with events and data coming from either the Main Ap-plication or from BTstack via registered packet handlers (PH). BTstack’s RunLoop is responsible for providing timers and processing incoming data.

    0.4. Single threaded design. BTstack does not use or require multi-threading.It uses a single run loop to handle data sources and timers. Data sources representcommunication interfaces like an UART or an USB driver. Timers are used

  • 18

    by BTstack to implement various Bluetooth-related timeouts. For example, todisconnect a Bluetooth baseband channel without an active L2CAP channel after20 seconds. They can also be used to handle periodic events. During a run loopcycle, the callback functions of all registered data sources are called. Then, thecallback functions of timers that are ready are executed.

    For adapting BTstack to multi-threaded environments check here.

    0.5. No blocking anywhere. Bluetooth logic is event-driven. Therefore, allBTstack functions are non-blocking, i.e., all functions that cannot return im-mediately implement an asynchronous pattern. If the arguments of a functionare valid, the necessary commands are sent to the Bluetooth chipset and thefunction returns with a success value. The actual result is delivered later as anasynchronous event via registered packet handlers.

    If a Bluetooth event triggers longer processing by the application, the process-ing should be split into smaller chunks. The packet handler could then schedulea timer that manages the sequential execution of the chunks.

    0.6. No artificially limited buffers/pools. Incoming and outgoing data pack-ets are not queued. BTstack delivers an incoming data packet to the applicationbefore it receives the next one from the Bluetooth chipset. Therefore, it relieson the link layer of the Bluetooth chipset to slow down the remote sender whenneeded.

    Similarly, the application has to adapt its packet generation to the remotereceiver for outgoing data. L2CAP relies on ACL flow control between sender andreceiver. If there are no free ACL buffers in the Bluetooth module, the applicationcannot send. For RFCOMM, the mandatory credit-based flow-control limits thedata sending rate additionally. The application can only send an RFCOMMpacket if it has RFCOMM credits.

    0.7. Statically bounded memory. BTstack has to keep track of services andactive connections on the various protocol layers. The number of maximum con-nections/channels/services can be configured. In addition, the non-persistentdatabase for remote device names and link keys needs memory and can be beconfigured, too. These numbers determine the amount of static memory alloca-tion.

    #How to configure BtstackBTstack implements a set of Bluetooth protocols and profiles. To connect to

    other Bluetooth devices or to provide a Bluetooth services, BTstack has to beproperly configured.

    The configuration of BTstack is done both at compile time as well as at runtime:

    • compile time configuration:– adjust btstack config.h - this file describes the system configuration,

    used functionality, and also the memory configuration– add necessary source code files to your project

    • run time configuration of:– Bluetooth chipset– run loop

  • 19

    – HCI transport layer– provided services– packet handlers

    In the following, we provide an overview of the configuration that is necessaryto setup BTstack. From the point when the run loop is executed, the applicationruns as a finite state machine, which processes events received from BTstack.BTstack groups events logically and provides them via packet handlers. Weprovide their overview here. For the case that there is a need to inspect thedata exchanged between BTstack and the Bluetooth chipset, we describe how toconfigure packet logging mechanism. Finally, we provide an overview on powermanagement in Bluetooth in general and how to save energy in BTstack.

    0.8. Configuration in btstack config.h. The file btstack config.h containsthree parts:

    • #define HAVE * directives listed here. These directives describe availablesystem properties, similar to config.h in a autoconf setup.• #define ENABLE * directives listed here. These directives list enabled

    properties, most importantly ENABLE CLASSIC and ENABLE BLE.• other #define directives for BTstack configuration, most notably static

    memory, see next section and NVM configuration.

    0.8.1. HAVE * directives. System properties:

    #define Description

    HAVE MALLOC Use dynamic memoryHAVE AES128 Use platform AES128 engine - not

    needed usuallyHAVE BTSTACK STDIN STDIN is available for CLI interfaceHAVE MBEDTLS ECC P256 mbedTLS provides NIST P-256

    operations e.g. for LE SecureConnections

    Embedded platform properties:

    #define Description

    HAVE EMBEDDED TIME MS System provides time in millisecondsHAVE EMBEDDED TICK System provides tick interrupt

    FreeRTOS platform properties:

    #define Description

    HAVE FREERTOS INCLUDE PREFIXFreeRTOS headers are in ‘freertos’folder (e.g. ESP32’s esp-idf)

    POSIX platform properties:

  • 20

    #define Description

    HAVE POSIX B300 MAPPED TO 2000000Workaround to use serial port with 2mbps

    HAVE POSIX B600 MAPPED TO 3000000Workaround to use serial port with 3mpbs

    HAVE POSIX FILE IO POSIX File i/o used for hci dumpHAVE POSIX TIME System provides time functionLINK KEY PATH Path to stored link keysLE DEVICE DB PATH Path to stored LE device information

    0.8.2. ENABLE * directives. BTstack properties:

    #define Description

    ENABLE CLASSIC Enable Classic related code in HCI andL2CAP

    ENABLE BLE Enable BLE related code in HCI andL2CAP

    ENABLE EHCILL Enable eHCILL low power mode on TICC256x/WL18xx chipsets

    ENABLE H5 Enable support for SLIP mode inbtstack uart.h drivers for HCI H5(‘Three-Wire Mode’)

    ENABLE LOG DEBUG Enable log debug messagesENABLE LOG ERROR Enable log error messagesENABLE LOG INFO Enable log info messagesENABLE SCO OVER HCI Enable SCO over HCI for chipsets (if

    supported)ENABLE SCO OVER PCM Enable SCO ofer PCM/I2S for chipsets (if

    supported)ENABLE HFP WIDE BAND SPEECHEnable support for mSBC codec used in

    HFP profile for Wide-Band SpeechENABLE HFP AT MESSAGES Enable HFP SUBEVENT AT MESSAGE SENT

    andHFP SUBEVENT AT MESSAGE RECEIVED

    eventsENABLE LE PERIPHERAL Enable support for LE Peripheral Role in

    HCI and Security ManagerENBALE LE CENTRAL Enable support for LE Central Role in

    HCI and Security ManagerENABLE LE SECURE CONNECTIONSEnable LE Secure ConnectionsENABLE LE PROACTIVE AUTHENTICATIONEnable automatic encryption for bonded

    devices on re-connectENABLE GATT CLIENT PAIRINGEnable GATT Client to start pairing and

    retry operation on security errorENABLE MICRO ECC FOR LE SECURE CONNECTIONSUse micro-ecc library for ECC operations

    https://github.com/kmackay/micro-ecc

  • 21

    #define Description

    ENABLE LE DATA CHANNELSEnable LE Data Channels in credit-basedflow control mode

    ENABLE LE DATA LENGTH EXTENSIONEnable LE Data Length Extension supportENABLE LE SIGNED WRITE Enable LE Signed Writes in ATT/GATTENABLE LE PRIVACY ADDRESS RESOLUTIONEnable address resolution for resolvable

    private addresses in ControllerENABLE CROSS TRANSPORT KEY DERIVATIONEnable Cross-Transport Key Derivation

    (CTKD) for Secure ConnectionsENABLE L2CAP ENHANCED RETRANSMISSION MODEEnable L2CAP Enhanced Retransmission

    Mode. Mandatory for AVRCP BrowsingENABLE HCI CONTROLLER TO HOST FLOW CONTROLEnable HCI Controller to Host Flow

    Control, see belowENABLE ATT DELAYED RESPONSEEnable support for delayed ATT

    operations, see GATT ServerENABLE BCM PCM WBS Enable support for Wide-Band Speech

    codec in BCM controller, requiresENABLE SCO OVER PCM

    ENABLE CC256X ASSISTED HFPEnable support for Assisted HFP mode inCC256x Controller, requiresENABLE SCO OVER PCM

    ENABLE CC256X BAUDRATE CHANGE FLOWCONTROL BUG WORKAROUNDEnable workaround for bug in CC256xFlow Control during baud rate change, seechipset docs.

    ENABLE CYPRESS BAUDRATE CHANGE FLOWCONTROL BUG WORKAROUNDEnable workaround for bug in CYW2070xFlow Control during baud rate change,similar to CC256x.

    ENABLE LE LIMIT ACL FRAGMENT BY MAX OCTETSForce HCI to fragment ACL-LE packets tofit into over-the-air packet

    ENABLE TLV FLASH EXPLICIT DELETE FIELDEnable use of explicit delete field in TLVFlash implemenation - required when flashvalue cannot be overwritten with zero

    ENABLE CONTROLLER WARM BOOTEnable stack startup without power cycle(if supported/possible)

    ENABLE SEGGER RTT Use SEGGER RTT for console output andpacket log, see additional options

    ENABLE EXPLICIT CONNECTABLE MODE CONTROLDisable calls to control Connectable Modeby L2CAP

    ENABLE EXPLICIT IO CAPABILITIES REPLYLet application trigger sending IOCapabilities (Negative) Reply

    ENABLE CLASSIC OOB PAIRINGEnable support for classic Out-of-Band(OOB) pairing

    ENABLE A2DP SOURCE EXPLICIT CONFIGLet application configure stream endpoint(skip auto-config of SBC endpoint)

    Notes:

  • 22

    • ENABLE MICRO ECC FOR LE SECURE CONNECTIONS: Only someBluetooth 4.2+ controllers (e.g., EM9304, ESP32) support the necessaryHCI commands for ECC. Other reason to enable the ECC software im-plementations are if the Host is much faster or if the micro-ecc library isalready provided (e.g., ESP32, WICED, or if the ECC HCI Commandsare unreliable.

    0.8.3. HCI Controller to Host Flow Control. In general, BTstack relies on flowcontrol of the HCI transport, either via Hardware CTS/RTS flow control forUART or regular USB flow control. If this is not possible, e.g on an SoC, BTstackcan use HCI Controller to Host Flow Control by defining ENABLE HCI CONTROLLER TO HOST FLOW CONTROL.If enabled, the HCI Transport implementation must be able to buffer the spec-ified packets. In addition, it also need to be able to buffer a few HCI Events.Using a low number of host buffers might result in less throughput.

    Host buffer configuration for HCI Controller to Host Flow Control:

    #define Description

    HCI HOST ACL PACKET NUM Max number of ACL packetsHCI HOST ACL PACKET LEN Max size of HCI Host ACL packetsHCI HOST SCO PACKET NUM Max number of ACL packetsHCI HOST SCO PACKET LEN Max size of HCI Host SCO packets

    0.8.4. Memory configuration directives. The structs for services, active connec-tions and remote devices can be allocated in two different manners:

    • statically from an individual memory pool, whose maximal number ofelements is defined in the btstack config.h file. To initialize the staticpools, you need to call at runtime btstack memory init function. Anexample of memory configuration for a single SPP service with a minimalL2CAP MTU is shown in Listing {@lst:memoryConfigurationSPP}.• dynamically using the malloc/free functions, if HAVE MALLOC is de-

    fined in btstack config.h file.

    For each HCI connection, a buffer of size HCI ACL PAYLOAD SIZE is re-served. For fast data transfer, however, a large ACL buffer of 1021 bytes isrecommend. The large ACL buffer is required for 3-DH5 packets to be used.

    #define Description

    HCI ACL PAYLOAD SIZE Max size of HCI ACL payloadsMAX NR BNEP CHANNELS Max number of BNEP channelsMAX NR BNEP SERVICES Max number of BNEP servicesMAX NR BTSTACK LINK KEY DB MEMORY ENTRIESMax number of link key entries cached in

    RAMMAX NR GATT CLIENTS Max number of GATT clientsMAX NR HCI CONNECTIONSMax number of HCI connectionsMAX NR HFP CONNECTIONSMax number of HFP connectionsMAX NR L2CAP CHANNELS Max number of L2CAP connectionsMAX NR L2CAP SERVICES Max number of L2CAP services

  • 23

    #define Description

    MAX NR RFCOMM CHANNELSMax number of RFOMMM connectionsMAX NR RFCOMM MULTIPLEXERSMax number of RFCOMM multiplexers,

    with one multiplexer per HCI connectionMAX NR RFCOMM SERVICESMax number of RFCOMM servicesMAX NR SERVICE RECORD ITEMSMax number of SDP service recordsMAX NR SM LOOKUP ENTRIESMax number of items in Security Manager

    lookup queueMAX NR WHITELIST ENTRIESMax number of items in GAP LE Whitelist

    to connect toMAX NR LE DEVICE DB ENTRIESMax number of items in LE Device DB

    The memory is set up by calling btstack memory init function:

    btstack memory in i t ( ) ;

    Here’s the memory configuration for a basic SPP server.

    #define HCI ACL PAYLOAD SIZE 52#define MAX NR HCI CONNECTIONS 1#define MAX NR L2CAP SERVICES 2#define MAX NR L2CAP CHANNELS 2#define MAX NR RFCOMM MULTIPLEXERS 1#define MAX NR RFCOMM SERVICES 1#define MAX NR RFCOMM CHANNELS 1#define MAX NR BTSTACK LINK KEY DB MEMORY ENTRIES 3

    Listing: Memory configuration for a basic SPP server. {#lst:memoryConfigurationSPP}In this example, the size of ACL packets is limited to the minimum of 52 bytes,

    resulting in an L2CAP MTU of 48 bytes. Only a singleHCI connection can beestablished at any time. On it, two L2CAP services are provided, which can beactive at the same time. Here, these two can be RFCOMM and SDP. Then,memory for one RFCOMM multiplexer is reserved over which one connectioncan be active. Finally, up to three link keys can be cached in RAM.

    0.8.5. Non-volatile memory (NVM) directives. If implemented, bonding infor-mation is stored in Non-volatile memory. For Classic, a single link keys and itstype is stored. For LE, the bonding information contains various values (longterm key, random number, EDIV, signing counter, identity, . . . ) Often, this isimplemented using Flash memory. Then, the number of stored entries are limitedby:

  • 24

    #define Description

    #define Description

    NVM NUM LINK KEYS Max number of ClassicLink Keys that can bestored

    NVM NUM DEVICE DB ENTRIES Max number of LEDevice DB entries thatcan be stored

    NVN NUM GATT SERVER CCC Max number of ‘ClientCharacteristicConfiguration’ valuesthat can be stored byGATT Server

    0.8.6. SEGGER Real Time Transfer (RTT) directives. SEGGER RTT improveson the use of an UART for debugging with higher throughput and less overhead.In addition, it allows for direct logging in PacketLogger/BlueZ format via theprovided JLinkRTTLogger tool.

    When enabled with ENABLE SEGGER RTT and hci dump init() can be called withan hci dunp segger stdout get instance() for textual output and hci dump segger binary get instance() for binary output. With the latter, you can select HCI DUMP BLUEZ or HCI DUMP PACKETLOGGER, format. For RTT, the following directives are used to configure the up channel:

    #define Default Description

    SEGGER RTT PACKETLOG MODESEGGER RTT MODE NO BLOCK SKIPSEGGER RTT MODE NO BLOCK SKIPto skip messages ifbuffer is full, or,SEG-GER RTT MODE BLOCK IF FIFO FULLto block

    SEGGER RTT PACKETLOG CHANNEL1 Channel to use forpacket log.Channel 0 is usedfor terminal

    SEGGER RTT PACKETLOG BUFFER SIZE1024 Size of outgoingring buffer.Increase if youcannot block butget ‘messageskipped’ warnings.

    0.9. Run-time configuration. To allow code-reuse with different platforms aswell as with new ports, the low-level initialization of BTstack and the hardwareconfiguration has been extracted to the various platforms/PLATFORM/main.c

    https://www.segger.com/products/debug-probes/j-link/technology/about-real-time-transfer/

  • 25

    files. The examples only contain the platform-independent Bluetooth logic. Butlet’s have a look at the common init code.

    Listing below shows a minimal platform setup for an embedded system witha Bluetooth chipset connected via UART.

    int main ( ) {// . . . hardware i n i t : watchdoch , IOs , t imers , e t c . . .

    // se tup BTstack memory poo l sbtstack memory in i t ( ) ;

    // s e l e c t embedded run loopb t s t a c k r u n l o o p i n i t ( b t s tack run loop embedded ge t in s tance ( ) ) ;

    // enab l e l o g g i n ghc i dump in i t ( hc i dump embedded stdout get instance ( ) ) ;

    // i n i t HCIhci transport t ∗ t r anspor t = h c i t r a n s p o r t h 4 i n s t a n c e ( ) ;h c i i n i t ( t ransport , NULL) ;

    // se tup examplebtstack main ( argc , argv ) ;

    // gob t s t a c k r u n l o o p e x e c u t e ( ) ;

    }

    First, BTstack’s memory pools are setup up. Then, the standard run loopimplementation for embedded systems is selected.

    The call to hci dump init configures BTstack to output all Bluetooth packetsand its own debug and error message using printf with BTstack’s millisecondtiomestamps.s as tim. The Python script tools/create packet log.py can be usedto convert the console output into a Bluetooth PacketLogger format that canbe opened by the OS X PacketLogger tool as well as by Wireshark for furtherinspection. When asking for help, please always include a log created with HCIdump.

    The hci init function sets up HCI to use the HCI H4 Transport implementa-tion. It doesn’t provide a special transport configuration nor a special implemen-tation for a particular Bluetooth chipset. It makes use of the remote device db memoryimplementation that allows for re-connects without a new pairing but doesn’tpersist the bonding information.

    Finally, it calls btstack main() of the actual example before executing the runloop.

    0.10. Source tree structure. The source tree has been organized to easilysetup new projects.

  • 26

    Path Description

    chipset Support for individual Bluetooth Controller chipsetsdoc Sources for BTstack documentationexample Example applications available for all portsplatform Support for special OSs and/or MCU architecturesport Complete port for a MCU + Chipset combinationssrc Bluetooth stack implementationtest Unit and PTS teststool Helper tools for BTstack

    The core of BTstack, including all protocol and profiles, is in src/.Support for a particular platform is provided by the platform/ subfolder. For

    most embedded ports, platform/embedded/ provides btstack run loop embeddedand the hci transport h4 embedded implementation that require hal cpu.h, hal led.h,and hal uart dma.h plus hal tick.h or hal time ms to be implemented by the user.

    To accommodate a particular Bluetooth chipset, the chipset/ subfolders pro-vide various btstack chipset * implementations. Please have a look at the exist-ing ports in port/.

    0.11. Run loop configuration. To initialize BTstack you need to initialize thememory and the run loop respectively, then setup HCI and all needed higher levelprotocols.

    BTstack uses the concept of a run loop to handle incoming data and to schedulework. The run loop handles events from two different types of sources: datasources and timers. Data sources represent communication interfaces like anUART or an USB driver. Timers are used by BTstack to implement variousBluetooth-related timeouts. They can also be used to handle periodic events.

    Data sources and timers are represented by the btstack data source t and bt-stack timer source t structs respectively. Each of these structs contain at leasta linked list node and a pointer to a callback function. All active timers anddata sources are kept in link lists. While the list of data sources is unsorted, thetimers are sorted by expiration timeout for efficient processing.

    Timers are single shot: a timer will be removed from the timer list beforeits event handler callback is executed. If you need a periodic timer, you canre-register the same timer source in the callback function, as shown in Listing[PeriodicTimerHandler]. Note that BTstack expects to get called periodicallyto keep its time, see Section on time abstraction for more on the tick hardwareabstraction.

    BTstack provides different run loop implementations that implement the bt-stack run loop t interface:

    • Embedded: the main implementation for embedded systems, especiallywithout an RTOS.• FreeRTOS: implementation to run BTstack on a dedicated FreeRTOS

    thread• POSIX: implementation for POSIX systems based on the select() call.• CoreFoundation: implementation for iOS and OS X applications

  • 27

    • WICED: implementation for the Broadcom WICED SDK RTOS abstrac-tion that wraps FreeRTOS or ThreadX.• Windows: implementation for Windows based on Event objects and

    WaitForMultipleObjects() call.

    Depending on the platform, data sources are either polled (embedded, FreeR-TOS), or the platform provides a way to wait for a data source to becomeready for read or write (POSIX, CoreFoundation, Windows), or, are not usedas the HCI transport driver and the run loop is implemented in a different way(WICED). In any case, the callbacks must be to explicitly enabled with thebtstack run loop enable data source callbacks(..) function.

    In your code, you’ll have to configure the run loop before you start it as shownin Listing [listing:btstackInit]. The application can register data sources as wellas timers, e.g., for periodical sampling of sensors, or for communication over theUART.

    The run loop is set up by calling btstack run loop init function and providingan instance of the actual run loop. E.g. for the embedded platform, it is:

    b t s t a c k r u n l o o p i n i t ( b t s tack run loop embedded ge t in s tance ( ) ) ;

    The complete Run loop API is provided here.

    0.11.1. Run loop embedded. In the embedded run loop implementation, datasources are constantly polled and the system is put to sleep if no IRQ happensduring the poll of all data sources.

    The complete run loop cycle looks like this: first, the callback function ofall registered data sources are called in a round robin way. Then, the callbackfunctions of timers that are ready are executed. Finally, it will be checked ifanother run loop iteration has been requested by an interrupt handler. If not,the run loop will put the MCU into sleep mode.

    Incoming data over the UART, USB, or timer ticks will generate an interruptand wake up the microcontroller. In order to avoid the situation where a datasource becomes ready just before the run loop enters sleep mode, an interrupt-driven data source has to call the btstack run loop embedded trigger function.The call to btstack run loop embedded trigger sets an internal flag that is checkedin the critical section just before entering sleep mode causing another run loopcycle.

    To enable the use of timers, make sure that you defined HAVE EMBEDDED TICKor HAVE EMBEDDED TIME MS in the config file.

    0.11.2. Run loop FreeRTOS. The FreeRTOS run loop is used on a dedicatedFreeRTOS thread and it uses a FreeRTOS queue to schedule callbacks on therun loop. In each iteration:

    • all data sources are polled• all scheduled callbacks are executed• all expired timers are called

  • 28

    • finally, it gets the next timeout. It then waits for a ‘trigger’ or the nexttimeout, if set.

    To trigger the run loop, btstack run loop freertos trigger and btstack run loop freertos trigger from isrcan be called. This causes the data sources to get polled.

    Alternatively. btstack run loop freertos execute code on main thread can beused to schedule a callback on the main loop. Please note that the queue isfinite (see RUN LOOP QUEUE LENGTH in btstack run loop embedded).

    0.11.3. Run loop POSIX. The data sources are standard File Descriptors. In therun loop execute implementation, select() call is used to wait for file descriptorsto become ready to read or write, while waiting for the next timeout.

    To enable the use of timers, make sure that you defined HAVE POSIX TIMEin the config file.

    0.11.4. Run loop CoreFoundation (OS X/iOS). This run loop directly maps BT-stack’s data source and timer source with CoreFoundation objects. It supportsready to read and write similar to the POSIX implementation. The call to bt-stack run loop execute() then just calls CFRunLoopRun().

    To enable the use of timers, make sure that you defined HAVE POSIX TIMEin the config file.

    0.11.5. Run loop Windows. The data sources are Event objects. In the run loopimplementation WaitForMultipleObjects() call is all is used to wait for the Eventobject to become ready while waiting for the next timeout.

    0.11.6. Run loop WICED. WICED SDK API does not provide asynchronousread and write to the UART and no direct way to wait for one or more peripher-als to become ready. Therefore, BTstack does not provide direct support for datasources. Instead, the run loop provides a message queue that allows to schedulefunctions calls on its thread via btstack run loop wiced execute code on main thread().

    The HCI transport H4 implementation then uses two lightweight threads todo the blocking read and write operations. When a read or write is complete onthe helper threads, a callback to BTstack is scheduled.

    0.12. HCI Transport configuration. The HCI initialization has to adapt BT-stack to the used platform. The first call is to hci init() and requires informationabout the HCI Transport to use. The arguments are:

    • HCI Transport implementation: On embedded systems, a Bluetooth mod-ule can be connected via USB or an UART port. On embedded, BTstackimplements HCI UART Transport Layer (H4) and H4 with eHCILL sup-port, a lightweight low-power variant by Texas Instruments. For POSIX,there is an implementation for HCI H4, HCI H5 and H2 libUSB, and forWICED HCI H4 WICED. These are accessed by linking the appropriatefile, e.g., platform/embedded/hci\_transport\_h4\_embedded.c andthen getting a pointer to HCI Transport implementation. For more in-formation on adapting HCI Transport to different environments, see here.

    hci transport t ∗ t r anspor t = h c i t r a n s p o r t h 4 i n s t a n c e ( ) ;

  • 29

    • HCI Transport configuration: As the configuration of the UART used inthe H4 transport interface are not standardized, it has to be provided bythe main application to BTstack. In addition to the initial UART baudrate, the main baud rate can be specified. The HCI layer of BTstack willchange the init baud rate to the main one after the basic setup of theBluetooth module. A baud rate change has to be done in a coordinatedway at both HCI and hardware level. For example, on the CC256x, theHCI command to change the baud rate is sent first, then it is necessaryto wait for the confirmation event from the Bluetooth module. Only now,can the UART baud rate changed.

    hci uart config t ∗ c o n f i g = &h c i u a r t c o n f i g ;

    After these are ready, HCI is initialized like this:

    h c i i n i t ( t ransport , c o n f i g ) ;

    In addition to these, most UART-based Bluetooth chipset require some speciallogic for correct initialization that is not covered by the Bluetooth specification.In particular, this covers:

    • setting the baudrate• setting the BD ADDR for devices without an internal persistent storage• upload of some firmware patches.

    This is provided by the various btstack chipset t implementation in the chipset/subfolders. As an example, the bstack chipset cc256x instance function returnsa pointer to a chipset struct suitable for the CC256x chipset.

    b t s t a c k c h i p s e t t ∗ c h i p s e t = b t s t a c k c h i p s e t c c 2 5 6 x i n s t a n c e ( ) ;h c i s e t c h i p s e t ( c h i p s e t ) ;

    In some setups, the hardware setup provides explicit control of Bluetoothpower and sleep modes. In this case, a btstack control t struct can be set withhci set control.

    Finally, the HCI implementation requires some form of persistent storage forlink keys generated during either legacy pairing or the Secure Simple Pairing(SSP). This commonly requires platform specific code to access the MCU’s EEP-ROM of Flash storage. For the first steps, BTstack provides a (non) persistentstore in memory. For more see here.

    btstack link key db t ∗ l i nk key db = &bts tack l ink key db memory ins tance ( ) ;

    b t s t a c k s e t l i n k k e y d b ( l i nk key db ) ;

  • 30

    The higher layers only rely on BTstack and are initialized by calling the re-spective ** init* function. These init functions register themselves with theunderlying layer. In addition, the application can register packet handlers to getevents and data as explained in the following section.

    0.13. Services. One important construct of BTstack is service. A service rep-resents a server side component that handles incoming connections. So far,BTstack provides L2CAP, BNEP, and RFCOMM services. An L2CAP servicehandles incoming connections for an L2CAP channel and is registered with itsprotocol service multiplexer ID (PSM). Similarly, an RFCOMM service handlesincoming RFCOMM connections and is registered with the RFCOMM channelID. Outgoing connections require no special registration, they are created by theapplication when needed.

    0.14. Packet handlers configuration. After the hardware and BTstack areset up, the run loop is entered. From now on everything is event driven. Theapplication calls BTstack functions, which in turn may send commands to theBluetooth module. The resulting events are delivered back to the application.Instead of writing a single callback handler for each possible event (as it is donein some other Bluetooth stacks), BTstack groups events logically and providesthem over a single generic interface. Appendix Events and Errors summarizesthe parameters and event codes of L2CAP and RFCOMM events, as well aspossible errors and the corresponding error codes.

    Here is summarized list of packet handlers that an application might use:

    • HCI event handler - allows to observer HCI, GAP, and general BTstackevents.• L2CAP packet handler - handles LE Connection parameter requeset up-

    dates• L2CAP service packet handler - handles incoming L2CAP connections,

    i.e., channels initiated by the remote.• L2CAP channel packet handler - handles outgoing L2CAP connections,

    i.e., channels initiated internally.• RFCOMM service packet handler - handles incoming RFCOMM connec-

    tions, i.e., channels initiated by the remote.• RFCOMM channel packet handler - handles outgoing RFCOMM connec-

    tions, i.e., channels initiated internally.

    These handlers are registered with the functions listed in Table below.

    Packet Handler Registering Function

    HCI packet handler hci add event handlerL2CAP packet handler l2cap register packet handlerL2CAP service packet handler l2cap register serviceL2CAP channel packet handler l2cap create channelRFCOMM service packet handler rfcomm register service and rf-

    comm register service with initial creditsRFCOMM channel packethandler

    rfcomm create channel and rf-comm create channel with initial credits

  • 31

    Table: Functions for registering packet handlers.HCI, GAP, and general BTstack events are delivered to the packet handler

    specified by hci add event handler function. In L2CAP, BTstack discriminatesincoming and outgoing connections, i.e., event and data packets are delivered todifferent packet handlers. Outgoing connections are used access remote services,incoming connections are used to provide services. For incoming connections,the packet handler specified by l2cap register service is used. For outgoing con-nections, the handler provided by l2cap create channel is used. RFCOMM andBNEP are similar.

    The application can register a single shared packet handler for all protocolsand services, or use separate packet handlers for each protocol layer and service.A shared packet handler is often used for stack initialization and connectionmanagement.

    Separate packet handlers can be used for each L2CAP service and outgoingconnection. For example, to connect with a Bluetooth HID keyboard, yourapplication could use three packet handlers: one to handle HCI events duringdiscovery of a keyboard registered by l2cap register packet handler ; one that willbe registered to an outgoing L2CAP channel to connect to keyboard and toreceive keyboard data registered by l2cap create channel ; after that keyboardcan reconnect by itself. For this, you need to register L2CAP services for theHID Control and HID Interrupt PSMs using l2cap register service. In this call,you’ll also specify a packet handler to accept and receive keyboard data.

    All events names have the form MODULE EVENT NAME now, e.g., gap event -advertising report. To facilitate working with events and get rid of manuallycalculating offsets into packets, BTstack provides auto-generated getters for allfields of all events in src/hci event.h. All functions are defined as static inline,so they are not wasting any program memory if not used. If used, the mem-ory footprint should be identical to accessing the field directly via offsets intothe packet. For example, to access fields address type and address from thegap event advertising report event use following getters:

    uint8 t address type = g a p e v e n t a d v e r t i s i n g r e p o r t g e t a d d r e s s t y p e( event ) ;

    bd addr t address ;g a p e v e n t a d v e r t i s i n g r e p o r t g e t a d d r e s s ( event , address ) ;

    0.15. Bluetooth HCI Packet Logs. If things don’t work as expected, havinga look at the data exchanged between BTstack and the Bluetooth chipset oftenhelps.

    For this, BTstack provides a configurable packet logging mechanism via hci dump.hand the following implementations:

    void hc i dump in i t ( const hci dump t ∗ hci dump implementation ) ;

  • 32

    Platform File Description

    POSIX hci dump posix fs.c HCI log file forApplePacketLoggerand Wireshark

    POSIX hci dump posix stdout.c Console outputvia printf

    Embedded hci dump embedded stdout.c Console outputvia printf

    Embedded hci dump segger stdout.c Console outputvia SEGGERRTT

    Embedded hci dump segger binary.c HCI log file forApplePacketLoggervia SEGGERRTT

    On POSIX systems, you can call hci dump init with a hci dump posix fs get instance()and configure the path and output format with hci dump posix fs open(constchar path, hci dump format t format) where format can be HCI DUMP BLUEZ*or HCI DUMP PACKETLOGGER. The resulting file can be analyzed with Wire-shark or the Apple’s PacketLogger tool.

    On embedded systems without a file system, you either log to an UART consolevia printf or use SEGGER RTT. For printf output you pass hci dump embedded stdout get instance()to hci dump init(). With RTT, you can choose between textual output sim-ilar to printf, and binary output. For textual output, you can provide thehci dump segger stdout get instance().

    It will log all HCI packets to the UART console via printf or RTT Terminal.If you capture the console output, incl. your own debug messages, you can usethe create packet log.py tool in the tools folder to convert a text output into aPacketLogger file.

    For less overhead and higher logging speed, you can directly log in binaryformat by passing hci dump segger rtt binary get instance() and selecting theoutput format by calling hci dump segger rtt binary open(hci dump format t for-mat) with the same format as above.

    In addition to the HCI packets, you can also enable BTstack’s debug informa-tion by adding

    #define ENABLE LOG INFO#define ENABLE LOG ERROR

    to the btstack config.h and recompiling your application.

  • 33

    0.16. Bluetooth Power Control. In most BTstack examples, the device isset to be discoverable and connectable. In this mode, even when there’s noactive connection, the Bluetooth Controller will periodically activate its receiverin order to listen for inquiries or connecting requests from another device. Theability to be discoverable requires more energy than the ability to be connected.Being discoverable also announces the device to anybody in the area. Therefore,it is a good idea to pause listening for inquiries when not needed. Other devicesthat have your Bluetooth address can still connect to your device.

    To enable/disable discoverability, you can call:

    /∗∗∗ @br ie f Al lows to con t r o l i f d ev i c e i s d i s c o v e r a b l e . OFF by

    d e f a u l t .∗/

    void g a p d i s c o v e r a b l e c o n t r o l ( uint8 t enable ) ;

    If you don’t need to become connected from other devices for a longer periodof time, you can also disable the listening to connection requests.

    To enable/disable connectability, you can call:

    /∗∗∗ @br ie f Override page scan mode . Page scan mode enab led by l2cap

    when s e r v i c e s are r e g i s t e r e d∗ @note Might be used to reduce power consumption wh i l e B lue too th

    module s t a y s powered but no (new)∗ connec t ions are expec ted∗/

    void g a p c o n n e c t a b l e c o n t r o l ( uint8 t enable ) ;

    For Bluetooth Low Energy, the radio is periodically used to broadcast adver-tisements that are used for both discovery and connection establishment.

    To enable/disable advertisements, you can call:

    /∗∗∗ @br ie f Enable /Di sab l e Advert i sements . OFF by d e f a u l t .∗ @param enab led∗/

    void gap adver t i s ement s enab l e ( int enabled ) ;

    If a Bluetooth Controller is neither discoverable nor connectable, it does notneed to periodically turn on its radio and it only needs to respond to commandsfrom the Host. In this case, the Bluetooth Controller is free to enter some kindof deep sleep where the power consumption is minimal.

    Finally, if that’s not sufficient for your application, you could request BTstackto shutdown the Bluetooth Controller. For this, the “on” and “off” functions in

  • 34

    the btstack control t struct must be implemented. To shutdown the BluetoothController, you can call:

    /∗∗∗ @br ie f Requests the change o f BTstack power mode .∗/

    int h c i p o w e r c o n t r o l (HCI POWER MODE mode) ;

    with mode set to HCI POWER OFF. When needed later, Bluetooth can bestarted again via by calling it with mode HCI POWER ON, as seen in all exam-ples.

    #ProtocolsBTstack is a modular dual-mode Bluetooth stack, supporting both Bluetooth

    Basic Rate/Enhanced Date Rate (BR/EDR) as well as Bluetooth Low Energy(LE). The BR/EDR technology, also known as Classic Bluetooth, provides arobust wireless connection between devices designed for high data rates. Incontrast, the LE technology has a lower throughput but also lower energy con-sumption, faster connection setup, and the ability to connect to more devices inparallel.

    Whether Classic or LE, a Bluetooth device implements one or more Bluetoothprofiles. A Bluetooth profile specifies how one or more Bluetooth protocols areused to achieve its goals. For example, every Bluetooth device must implementthe Generic Access Profile (GAP), which defines how devices find each otherand how they establish a connection. This profile mainly make use of the HostController Interface (HCI) protocol, the lowest protocol in the stack hierarchywhich implements a command interface to the Bluetooth chipset.

    In addition to GAP, a popular Classic Bluetooth example would be a peripheraldevices that can be connected via the Serial Port Profile (SPP). SPP basicallyspecifies that a compatible device should provide a Service Discovery Protocol(SDP) record containing an RFCOMM channel number, which will be used forthe actual communication.

    Similarly, for every LE device, the Generic Attribute Profile (GATT) profilemust be implemented in addition to GAP. GATT is built on top of the AttributeProtocol (ATT), and defines how one device can interact with GATT Serviceson a remote device.

    So far, the most popular use of BTstack is in peripheral devices that can beconnected via SPP (Android 2.0 or higher) and GATT (Android 4.3 or higher,and iOS 5 or higher). If higher data rates are required between a peripheral andiOS device, the iAP1 and iAP2 protocols of the Made for iPhone program canbe used instead of GATT. Please contact us directly for information on BTstackand MFi.

    Figure below depicts Bluetooth protocols and profiles that are currently imple-mented by BTstack. In the following, we first explain how the various Bluetoothprotocols are used in BTstack. In the next chapter, we go over the profiles.

    0.17. HCI - Host Controller Interface. The HCI protocol provides a com-mand interface to the Bluetooth chipset. In BTstack, the HCI implementation

  • 35

    SPP GATT

    SMP ATT RFCOMM

    L2CAP LE

    HCI

    TRANSPORT…H4 UART eHCILL UART H2 USBH5 UART

    PROFILES

    PROTOCOLS

    Bluetooth Single/Dual Mode Controller

    SDP BNEP AVDTP AVCTP

    L2CAP

    HSP HFPMFi

    iARP2 PBAPSDAP PAN A2DP AVRCP HID GAP MESH

    Architecture of a BTstack-based application.

    also keeps track of all active connections and handles the fragmentation andre-assembly of higher layer (L2CAP) packets.

    Please note, that an application rarely has to send HCI commands on its own.Instead, BTstack provides convenience functions in GAP and higher level proto-cols that use HCI automatically. E.g. to set the name, you call gap set local name()before powering up. The main use of HCI commands in application is during thestartup phase to configure special features that are not available via the GAPAPI yet. How to send a custom HCI command is explained in the followingsection.

    0.17.1. Defining custom HCI command templates. Each HCI command is as-signed a 2-byte OpCode used to uniquely identify different types of commands.The OpCode parameter is divided into two fields, called the OpCode Group Field(OGF) and OpCode Command Field (OCF), see Bluetooth Specification - CoreVersion 4.0, Volume 2, Part E, Chapter 5.4.

    Listing below shows the OGFs provided by BTstack in file src/hci.h:

    #define OGF LINK CONTROL 0x01#define OGF LINK POLICY 0x02#define OGF CONTROLLER BASEBAND 0x03#define OGF INFORMATIONAL PARAMETERS 0x04#define OGF LE CONTROLLER 0x08#define OGF BTSTACK 0x3d#define OGF VENDOR 0 x3f

    For all existing Bluetooth commands and their OCFs see Bluetooth Specifica-tion - Core Version 4.0, Volume 2, Part E, Chapter 7.

    In a HCI command packet, the OpCode is followed by parameter total length,and the actual parameters. The OpCode of a command can be calculated usingthe OPCODE macro. BTstack provides the hci cmd t struct as a compact formatto define HCI command packets, see Listing below, and include/btstack/hci\_cmd.h file in the source code.

    https://www.bluetooth.org/Technical/Specifications/adopted.htmhttps://www.bluetooth.org/Technical/Specifications/adopted.htmhttps://www.bluetooth.org/Technical/Specifications/adopted.htm

  • 36

    // Ca l cu l a t e combined og f / oc f va lue .#define OPCODE( ogf , o c f ) ( o c f | og f

  • 37

    hci send cmd(& h c i w r i t e l o c a l n a m e , ”BTstack Demo” ) ;}

    Please note, that an application rarely has to send HCI commands on itsown. Instead, BTstack provides convenience functions in GAP and higher levelprotocols that use HCI automatically.

    0.18. L2CAP - Logical Link Control and Adaptation Protocol. TheL2CAP protocol supports higher level protocol multiplexing and packet frag-mentation. It provides the base for the RFCOMM and BNEP protocols. For allprofiles that are officially supported by BTstack, L2CAP does not need to beused directly. For testing or the development of custom protocols, it’s helpful tobe able to access and provide L2CAP services however.

    0.18.1. Access an L2CAP service on a remote device. L2CAP is based aroundthe concept of channels. A channel is a logical connection on top of a basebandconnection. Each channel is bound to a single protocol in a many-to-one fashion.Multiple channels can be bound to the same protocol, but a channel cannot bebound to multiple protocols. Multiple channels can share the same basebandconnection.

    To communicate with an L2CAP service on a remote device, the application ona local Bluetooth device initiates the L2CAP layer using the l2cap init function,and then creates an outgoing L2CAP channel to the PSM of a remote deviceusing the l2cap create channel function. The l2cap create channel function willinitiate a new baseband connection if it does not already exist. The packet han-dler that is given as an input parameter of the L2CAP create channel functionwill be assigned to the new outgoing L2CAP channel. This handler receives theL2CAP EVENT CHANNEL OPENED and L2CAP EVENT CHANNEL CLOSEDevents and L2CAP data packets, as shown in Listing below.

    btstack packet handler t l 2 cap packe t hand l e r ;

    void l 2 cap packe t hand l e r ( uint8 t packet type , uint16 t channel ,uint8 t ∗packet , uint16 t s i z e ) {bd addr t event addr ;switch ( packet type ) {

    case HCI EVENT PACKET:switch ( h c i e v e n t p a c k e t g e t t y p e ( packet ) ) {

    case L2CAP EVENT CHANNEL OPENED:l 2 c ap e ve n t c ha nn e l op e ne d g e t a dd r e s s ( packet , &

    event addr ) ;psm = l2cap event channe l opened get psm (

    packet ) ;l o c a l c i d =

    l 2 c a p e v e n t c h a n n e l o p e n e d g e t l o c a l c i d (packet ) ;

    handle =l2cap event channe l opened ge t hand l e ( packet) ;

  • 38

    i f ( l 2 c a p e v e n t c h a n n e l o p e n e d g e t s t a t u s ( packet) ) {p r i n t f ( ” Connection f a i l e d \n\ r ” ) ;

    } elsep r i n t f ( ”Connected\n\ r ” ) ;

    }break ;

    case L2CAP EVENT CHANNEL CLOSED:break ;. . .

    }case L2CAP DATA PACKET:

    // handle L2CAP data packe tbreak ;

    . . .}

    }

    void c r e a t e o u t g o i n g l 2 c a p c h a n n e l (bd addr t address , uint16 t psm ,uint16 t mtu) {

    l 2 c a p c r e a t e c h a n n e l (NULL, l2cap packe t hand l e r , remote bd addr, psm , mtu) ;

    }

    void bt s ta ck s e tup ( ) {. . .l 2 c a p i n i t ( ) ;

    }

    0.18.2. Provide an L2CAP service. To provide an L2CAP service, the applica-tion on a local Bluetooth device must init the L2CAP layer and register the ser-vice with l2cap register service. From there on, it can wait for incoming L2CAPconnections. The application can accept or deny an incoming connection bycalling the l2cap accept connection and l2cap deny connection functions respec-tively.

    If a connection is accepted and the incoming L2CAP channel gets successfullyopened, the L2CAP service can send and receive L2CAP data packets to theconnected device with l2cap send.

    Listing below provides L2CAP service example code.

    void packet hand le r ( uint8 t packet type , uint16 t channel , uint8 t∗packet , uint16 t s i z e ) {bd addr t event addr ;switch ( packet type ) {

    case HCI EVENT PACKET:switch ( h c i e v e n t p a c k e t g e t t y p e ( packet ) ) {

    case L2CAP EVENT INCOMING CONNECTION:l o c a l c i d =

    l 2 c a p e v e n t i n c o m i n g c o n n e c t i o n g e t l o c a l c i d( packet ) ;

  • 39

    l 2 c a p a c c e p t c o n n e c t i o n ( l o c a l c i d ) ;break ;

    case L2CAP EVENT CHANNEL OPENED:l 2 c ap e ve n t c ha nn e l op e ne d g e t a dd r e s s ( packet , &

    event addr ) ;psm = l2cap event channe l opened get psm (

    packet ) ;l o c a l c i d =

    l 2 c a p e v e n t c h a n n e l o p e n e d g e t l o c a l c i d (packet ) ;

    handle =l2cap event channe l opened ge t hand l e ( packet) ;

    i f ( l 2 c a p e v e n t c h a n n e l o p e n e d g e t s t a t u s ( packet) ) {p r i n t f ( ” Connection f a i l e d \n\ r ” ) ;

    } elsep r i n t f ( ”Connected\n\ r ” ) ;

    }break ;

    case L2CAP EVENT CHANNEL CLOSED:break ;. . .

    }case L2CAP DATA PACKET:

    // handle L2CAP data packe tbreak ;

    . . .}

    }

    void bt s ta ck s e tup ( ) {. . .l 2 c a p i n i t ( ) ;l 2 c a p r e g i s t e r s e r v i c e (NULL, packet handler , 0x11 , 1 0 0 ) ;

    }

    0.18.3. Sending L2CAP Data. Sending of L2CAP data packets may fail due toa full internal BTstack outgoing packet buffer, or if the ACL buffers in theBluetooth module become full, i.e., if the application is sending faster than thepackets can be transferred over the air.

    Instead of directly calling l2cap send, it is recommended to call l2cap request can send now event(cahnnel id)which will trigger an L2CAP EVENT CAN SEND NOW as soon as possible. Itmight happen that the event is received via packet handler before the l2cap request can send now eventfunction returns. The L2CAP EVENT CAN SEND NOW indicates a channelID on which sending is possible.

    Please note that the guarantee that a packet can be sent is only valid whenthe event is received. After returning from the packet handler, BTstack mightneed to send itself.

    0.18.4. LE Data Channels. The full title for LE Data Channels is actually LEConnection-Oriented Channels with LE Credit-Based Flow-Control Mode. In

  • 40

    this mode, data is sent as Service Data Units (SDUs) that can be larger than anindividual HCI LE ACL packet.

    LE Data Channels are similar to Classic L2CAP Channels but also provide acredit-based flow control similar to RFCOMM Channels. Unless the LE DataPacket Extension of Bluetooth Core 4.2 specification is used, the maximumpacket 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 thereceiving side.

    Since multiple SDUs can be transmitted at the same time and the individualACL LE packets can be sent interleaved, BTstack requires a dedicated receivebuffer per channel that has to be passed when creating the channel or acceptingit. Similarly, when sending SDUs, the data provided to the l2cap le send datamust stay valid until the L2CAP EVENT LE PACKET SENT is received.

    When creating an outgoing connection of accepting an incoming, the ini-tial credits allows to provide a fixed number of credits to the remote side. Furthercredits can be provided anytime with l2cap le provide credits. If L2CAP LE AUTOMATIC CREDITSis used, BTstack automatically provides credits as needed - effectively trading inthe flow-control functionality for convenience.

    The remainder of the API is similar to the one of L2CAP:

    • l2cap le register service and l2cap le unregister service are used to man-age local services.• l2cap le accept connection and l2cap le decline connection are used to ac-

    cept or deny an incoming connection request.• l2cap le create channel creates an outgoing connections.• l2cap le can send now checks if a packet can be scheduled for transmis-

    sion now.• l2cap le request can send now event requests an L2CAP EVENT LE CAN SEND NOW

    event as soon as possible.• l2cap le disconnect closes the connection.

    0.19. RFCOMM - Radio Frequency Communication Protocol. The Ra-dio frequency communication (RFCOMM) protocol provides emulation of serialports over the L2CAP protocol and reassembly. It is the base for the SerialPort Profile and other profiles used for telecommunication like Head-Set Profile,Hands-Free Profile, Object Exchange (OBEX) etc.

    0.19.1. No RFCOMM packet boundaries. As RFCOMM emulates a serial port,it does not preserve packet boundaries.

    On most operating systems, RFCOMM/SPP will be modeled as a pipe thatallows to write a block of bytes. The OS and the Bluetooth Stack are free tobuffer and chunk this data in any way it seems fit. In your BTstack application,you will therefore receive this data in the same order, but there are no guaranteesas how it might be fragmented into multiple chunks.

    If you need to preserve the concept of sending a packet with a specific sizeover RFCOMM, the simplest way is to prefix the data with a 2 or 4 byte lengthfield and then reconstruct the packet on the receiving side.

    Please note, that due to BTstack’s ‘no buffers’ policy, BTstack will send outgo-ing RFCOMM data immediately and implicitly preserve the packet boundaries,

  • 41

    i.e., it will send the data as a single RFCOMM packet in a single L2CAP packet,which will arrive in one piece. While this will hold between two BTstack in-stances, it’s not a good idea to rely on implementation details and rather prefixthe data as described.

    0.19.2. RFCOMM flow control. RFCOMM has a mandatory credit-based flow-control. This means that two devices that established RFCOMM connection,use credits to keep track of how many more RFCOMM data packets can besent to each. If a device has no (outgoing) credits left, it cannot send anotherRFCOMM packet, the transmission must be paused. During the connectionestablishment, initial credits are provided. BTstack tracks the number of creditsin both directions. If no outgoing credits are available, the RFCOMM sendfunction will return an error, and you can try later. For incoming data, BTstackprovides channels and services with and without automatic credit managementvia different functions to create/register them respectively. If the management ofcredits is automatic, the new credits are provided when needed relying on ACLflow control - this is only useful if there is not much data transmitted and/oronly one physical connection is used. If the management of credits is manual,credits are provided by the application such that it can manage its receive buffersexplicitly.

    0.19.3. Access an RFCOMM service on a remote device. To communicate withan RFCOMM service on a remote device, the application on a local Bluetoothdevice initiates the RFCOMM layer using the rfcomm init function, and thencreates an outgoing RFCOMM channel to a given server channel on a remotedevice using the rfcomm create channel function. The rfcomm create channelfunction will initiate a new L2CAP connection for the RFCOMM multiplexer,if it does not already exist. The channel will automatically provide enoughcredits to the remote side. To provide credits manually, you have to create theRFCOMM connection by calling rfcomm create channel with initial credits - seeSection on manual credit assignement.

    The packet handler that is given as an input parameter of the RFCOMM createchannel function will be assigned to the new outgoing channel. This handler re-ceives the RFCOMM EVENT CHANNEL OPENED and RFCOMM EVENT CHANNEL CLOSEDevents, and RFCOMM data packets, as shown in Listing below.

    void r fcomm packet handler ( uint8 t packet type , uint16 t channel ,uint8 t ∗packet , uint16 t s i z e ) {switch ( packet type ) {

    case HCI EVENT PACKET:switch ( h c i e v e n t p a c k e t g e t t y p e ( packet ) ) {

    case RFCOMM EVENT CHANNEL OPENED:i f (

    r f comm event open channe l comple t e ge t s ta tus( packet ) ) {p r i n t f ( ” Connection f a i l e d \n\ r ” ) ;

    } else {p r i n t f ( ”Connected\n\ r ” ) ;

    }

  • 42

    break ;case RFCOMM EVENT CHANNEL CLOSED:

    break ;. . .

    }break ;

    case RFCOMM DATA PACKET:// handle RFCOMM data packe t sreturn ;

    }}

    void create r fcomm channe l ( uint8 t packet type , uint8 t ∗packet ,uint16 t s i z e ) {r f comm create channe l ( r fcomm packet handler , addr ,

    rfcomm channel ) ;}

    void bt s ta ck s e tup ( ) {. . .l 2 c a p i n i t ( ) ;r f comm init ( ) ;

    }

    0.19.4. Provide an RFCOMM service. To provide an RFCOMM service, the ap-plication on a local Bluetooth device must first init the L2CAP and RFCOMMlayers and then register the service with rfcomm register service. From there on,it can wait for incoming RFCOMM connections. The application can acceptor deny an incoming connection by calling the rfcomm accept connection and rf-comm deny connection functions respectively. If a connection is accepted and theincoming RFCOMM channel gets successfully opened, the RFCOMM service cansend RFCOMM data packets to the connected device with rfcomm send and re-ceive data packets by the packet handler provided by the rfcomm register servicecall.

    Listing below provides the RFCOMM service example code.

    void packet hand le r ( uint8 t packet type , uint16 t channel , uint8 t ∗packet , uint16 t s i z e ) {switch ( packet type ) {

    case HCI EVENT PACKET:switch ( h c i e v e n t p a c k e t g e t t y p e ( packet ) ) {

    case RFCOMM EVENT INCOMING CONNECTION:rfcomm channel id =

    r fcomm event incoming connect ion get r f comm cid( packet ) ;

    r fcomm accept connect ion ( r fcomm channel id ) ;break ;

    case RFCOMM EVENT CHANNEL OPENED:

  • 43

    i f (r f comm event open channe l comple t e ge t s ta tus( packet ) ) {p r i n t f ( ”RFCOMM channel open f a i l e d . ” ) ;break ;

    }r fcomm channel id =

    rfcomm event open channe l complete get r f comm cid( packet ) ;

    mtu =r fcomm event open channe l comple te get max f rame s i ze( packet ) ;

    p r i n t f ( ”RFCOMM channel open succeeded , max frames i z e %u . ” , mtu) ;

    break ;case RFCOMM EVENT CHANNEL CLOSED:

    p r i n t f ( ”Channel c l o s e d . ” ) ;break ;

    . . .}break ;

    case RFCOMM DATA PACKET:// handle RFCOMM data packe t sreturn ;

    . . .}. . .

    }

    void bt s ta ck s e tup ( ) {. . .l 2 c a p i n i t ( ) ;r f comm init ( ) ;r f c o m m r e g i s t e r s e r v i c e ( packet handler , rfcomm channel nr , mtu) ;

    }

    0.19.5. Slowing down RFCOMM data reception. RFCOMM’s credit-based flow-control can be used to adapt, i.e., slow down the RFCOMM data to your process-ing speed. For incoming data, BTstack provides channels and services with andwithout automatic credit management. If the management of credits is auto-matic, new credits are provided when needed relying on ACL flow control. Thisis only useful if there is not much data transmitted and/or only one physicalconnection is used. See Listing below.

    void bt s ta ck s e tup (void ) {. . .// i n i t RFCOMMr f comm init ( ) ;r f c o m m r e g i s t e r s e r v i c e ( packet handler , rfcomm channel nr , 100) ;

    }

  • 44

    If the management of credits is manual, credits are provided by the applicationsuch that it can manage its receive buffers explicitly, see Listing below.

    Manual credit management is recommended when received RFCOMM datacannot be processed immediately. In the SPP flow control example, delayedprocessing of received data is simulated with the help of a periodic timer. Toprovide new credits, you call the rfcomm grant credits function with the RF-COMM channel ID and the number of credits as shown in Listing below.

    void bt s ta ck s e tup (void ) {. . .// i n i t RFCOMMr f comm init ( ) ;// re se rved channel , mtu=100, 1 c r e d i tr f c o m m r e g i s t e r s e r v i c e w i t h i n i t i a l c r e d i t s ( packet handler ,

    rfcomm channel nr , 100 , 1) ;}

    void p r o c e s s i n g ( ) {// proces s incoming data packe t. . .// prov ide new c r e d i tr f comm grant c r ed i t s ( r fcomm channel id , 1) ;

    }

    Please note that providing single credits effectively reduces the credit-based(sliding window) flow control to a stop-and-wait flow-control that limits the datathroughput substantially. On the plus side, it allows for a minimal memoryfootprint. If possible, multiple RFCOMM buffers should be used to avoid pauseswhile the sender has to wait for a new credit.

    0.19.6. Sending RFCOMM data. Outgoing packets, both commands and data,are not queued in BTstack. This section explains the consequences of this designdecision for sending data and why it is not as bad as it sounds.

    Independent from the number of output buffers, packet generation has to beadapted to the remote receiver and/or maximal link speed. Therefore, a packetcan only be generated when it can get sent. With this assumption, the singleoutput buffer design does not impose additional restrictions. In the following,we show how this is used for adapting the RFCOMM send rate.

    When there is a need to send a packet, call rcomm request can send now andwait for the reception of the RFCOMM EVENT CAN SEND NOW event tosend the packet, as shown in Listing below.

    Please note that the guarantee that a packet can be sent is only valid whenthe event is received. After returning from the packet handler, BTstack mightneed to send itself.

  • 45

    void prepare data (uint16 t r fcomm channel id ) {. . .// prepare data in d a t a b u f f e rr fcomm request can send now event ( r fcomm channel id ) ;

    }

    void send data (uint16 t r fcomm channel id ) {rfcomm send ( rfcomm channel id , da ta bu f f e r , da ta l en ) ;// packe t i s handed over to BTstack , we can prepare the next oneprepare data ( r fcomm channel id ) ;

    }

    void packet hand le r ( uint8 t packet type , uint16 t channel , uint8 t ∗packet , uint16 t s i z e ) {switch ( packet type ) {

    case HCI EVENT PACKET:switch ( h c i e v e n t p a c k e t g e t t y p e ( packet ) ) {

    . . .case RFCOMM EVENT CAN SEND NOW:

    rfcomm channel id =rfcomm event can send now get r fcomm cid (packet ) ;

    send data ( r fcomm channel id ) ;break ;

    . . .}. . .

    }}

    }

    0.19.7. Optimized sending of RFCOMM data. When sending RFCOMM datavia rfcomm send, BTstack needs to copy the data from the user provided bufferinto the outgoing buffer. This requires both an additional buffer for the userdata as well requires a copy operation.

    To avoid this, it is possible to directly write the user data into the outgoingbuffer.

    When get the RFCOMM CAN SEND NOW event, you call rfcomm reserve packet bufferto lock the buffer for your send operation. Then, you can ask how many bytesyou can send with rfcomm get max frame size and get a pointer to BTstack’sbuffer with rfcomm get outgoing buffer. Now, you can fill that buffer and finallysend the data with rfcomm send prepared.

    0.20. SDP - Service Discovery Protocol. The SDP protocol allows to an-nounce services and discover services provided by a remote Bluetooth device.

    0.20.1. Create and announce SDP records. BTstack contains a complete SDPserver and allows to register SDP records. An SDP record is a list of SDPAttribute {ID, Value} pairs that are stored in a Data Element Sequence (DES).The Attribute ID is a 16-bit number, the value can be of other simple types likeintegers or strings or can itself contain other DES.

  • 46

    To create an SDP record for an SPP service, you can call spp create sdp recordfrom with a pointer to a buffer to store the record, the server channel number,and a record name.

    For other types of records, you can use the other functions in, using the dataelement de functions. Listing [sdpCreate] shows how an SDP record contain