BT Stack
BT Stack
BTstack Manual
Including Quickstart Guide
Contents
0.1. General Tools 2
0.2. Getting BTstack from GitHub 2
0.3. Let’s Go 2
0.4. Single threaded design 3
0.5. No blocking anywhere 4
0.6. No artificially limited buffers/pools 4
0.7. Statically bounded memory 4
0.8. Configuration in btstack config.h 5
0.8.1. HAVE * directives 5
0.8.2. ENABLE * directives 6
0.8.3. HCI Controller to Host Flow Control 9
0.8.4. Memory configuration directives 9
0.8.5. Non-volatile memory (NVM) directives 10
0.8.6. HCI Dump Stdout directives 11
0.8.7. SEGGER Real Time Transfer (RTT) directives 11
0.9. Run-time configuration 11
0.10. Source tree structure 12
0.11. Run loop configuration 13
0.11.1. Run Loop Embedded 14
0.11.2. Run Loop FreeRTOS 14
0.11.3. Run Loop POSIX 15
0.11.4. Run loop CoreFoundation (OS X/iOS) 15
0.11.5. Run Lop Qt 15
0.11.6. Run loop Windows 15
0.11.7. Run loop WICED 15
0.12. HCI Transport configuration 15
0.13. Services 17
0.14. Packet handlers configuration 17
0.15. Bluetooth HCI Packet Logs 19
0.16. Bluetooth Power Control 20
0.17. HCI - Host Controller Interface 22
0.17.1. Defining custom HCI command templates 22
0.17.2. Sending HCI command based on a template 23
0.18. L2CAP - Logical Link Control and Adaptation Protocol 24
0.18.1. Access an L2CAP service on a remote device 24
0.18.2. Provide an L2CAP service 25
0.18.3. Sending L2CAP Data 26
0.18.4. LE Data Channels 27
0.19. RFCOMM - Radio Frequency Communication Protocol 27
0.19.1. No RFCOMM packet boundaries 27
0.19.2. RFCOMM flow control 28
0.19.3. Access an RFCOMM service on a remote device 28
0.19.4. Provide an RFCOMM service 29
0.19.5. Slowing down RFCOMM data reception 30
0.19.6. Sending RFCOMM data 31
2
g i t c l o n e h t t p s : // g i t h u b . com/ b l u e k i t c h e n / b t s t a c k . g i t
Main Applica/on
Communica/on Logic PH
BTstack
#define Description
HAVE AES128 Use platform AES128 engine
HAVE BTSTACK STDIN
STDIN is available for CLI interface
HAVE LWIP lwIP is available
HAVE MALLOC Use dynamic memory
HAVE MBEDTLS ECC
mbedTLS
P256 provides NIST P-256 operations e.g. for LE
Secure Connections
#define Description
HAVE EMBEDDED TIME MS System provides time in milliseconds
HAVE EMBEDDED TICK System provides tick interrupt
HAVE HAL AUDIO Audio HAL is available
HAVE HAL AUDIO SINK STEREO ONLY Duplicate samples for mono playback
#define Description
HAVE FREERTOS INCLUDE
FreeRTOS
PREFIX
headers are in ‘freertos’ folder
(e.g. ESP32’s esp-idf)
#define Description
HAVE POSIX FILE IO POSIX File i/o used for hci dump
HAVE POSIX TIME System provides time function
LINK KEY PATH Path to stored link keys
LE DEVICE DB PATH Path to stored LE device information
Chipset properties:
#define Description
HAVE BCM PCM2 PCM2 is used and requires additional configuration
HAVE BCM PCM NBS 16KHZ
NBS is up/downsampled, use 16 kHz sample rate for
NBS
#define Description
ENABLE CLASSIC Enable Classic related code in HCI and
L2CAP
ENABLE BLE Enable BLE related code in HCI and L2CAP
ENABLE EHCILL Enable eHCILL low power mode on TI
CC256x/WL18xx chipsets
ENABLE H5 Enable support for SLIP mode in btstack uart .h
drivers for HCI H5 (‘Three-Wire Mode’)
ENABLE LOG DEBUG Enable log debug messages
ENABLE LOG ERROR Enable log error messages
ENABLE LOG INFO Enable log info messages
ENABLE LOG BTSTACK EVENTS
Log internal/custom BTstack events
ENABLE 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 BANDEnable
SPEECH support for mSBC codec used in HFP
profile for Wide-Band Speech
ENABLE HFP AT MESSAGES
Enable HFP SUBEVENT AT MESSAGE SENT
and HFP SUBEVENT AT MESSAGE RECEIVED
events
ENABLE LE PERIPHERAL Enable support for LE Peripheral Role in HCI
and Security Manager
ENABLE LE CENTRAL Enable support for LE Central Role in HCI
and Security Manager
ENABLE LE SECURE CONNECTIONS
Enable LE Secure Connections
ENABLE LE SECURE CONNECTIONS
Enable support
DEBUG
for LEKEY
Secure Connection
debug keys for testing
ENABLE LE PROACTIVE AUTHENTICATION
Enable automatic encryption for bonded
devices on re-connect
22
#define Description
ENABLE GATT CLIENT PAIRING
Enable GATT Client to start pairing and retry
operation on security error
ENABLE MICRO ECC FORUseLE micro-ecc
SECURE library
CONNECTIONS
for ECC operations
ENABLE LE DATA LENGTH Enable
EXTENSION
LE Data Length Extension support
ENABLE LE ENHANCED CONNECTION
Enable LE Enhanced
COMPLETE
Connection
EVENTComplete
Event v1 & v2
ENABLE LE EXTENDED ADVERTISING
Enable extended advertising and scanning
ENABLE LE PERIODIC ADVERTISING
Enable periodic advertising and scanning
ENABLE LE SIGNED WRITEEnable LE Signed Writes in ATT/GATT
ENABLE LE PRIVACY ADDRESS
Enable RESOLUTION
address resolution for resolvable
private addresses in Controller
ENABLE CROSS TRANSPORTEnable
KEYCross-Transport
DERIVATIONKey Derivation
(CTKD) for Secure Connections
ENABLE L2CAP ENHANCED Enable
RETRANSMISSION
Enhanced Retransmission
MODE Mode for
L2CAP Channels. Mandatory for AVRCP
Browsing
ENABLE L2CAP LE CREDITEnable
BASEDLE FLOW
credit-based
CONTROL
flow-control
MODE mode for
L2CAP channels
ENABLE L2CAP ENHANCED Enable
CREDIT
Enhanced
BASEDcredit-based
FLOW CONTROL
flow-controlMODE
mode for L2CAP Channels
ENABLE HCI CONTROLLER Enable
TO HOST
HCI Controller
FLOW CONTROL
to Host Flow Control,
see below
ENABLE HCI SERIALIZED Serialize
CONTROLLER
Inquiry, OPERATIONS
Remote Name Request, and
Create Connection operations
ENABLE ATT DELAYED RESPONSE
Enable support for delayed ATT operations,
see GATT Server
ENABLE BCM PCM WBS Enable support for Wide-Band Speech codec
in BCM controller, requires
ENABLE SCO OVER PCM
ENABLE CC256X ASSISTEDEnable
HFP support for Assisted HFP mode in
CC256x Controller, requires
ENABLE SCO OVER PCM
ENABLE RTK PCM WBS Enable support for Wide-Band Speech codec
in Realtek controller, requires
ENABLE SCO OVER PCM
ENABLE CC256X BAUDRATEEnable
CHANGE
workaround
FLOWCONTROL
for bug in CC256x
BUG Flow
WORKAROUND
Control during baud rate change, see chipset
docs.
ENABLE CYPRESS BAUDRATE
EnableCHANGE
workaroundFLOWCONTROL
for bug in CYW2070x
BUG WORKAROUND
Flow Control during baud rate change, similar
to CC256x.
ENABLE LE LIMIT ACL FRAGMENT
Force HCI toBY fragment
MAX OCTETS
ACL-LE packets to fit
into over-the-air packet
23
#define Description
ENABLE TLV FLASH EXPLICIT
EnableDELETE
use of explicit
FIELD delete field in TLV Flash
implementation - required when flash value
cannot be overwritten with zero
ENABLE TLV FLASH WRITE
Enable
ONCEstoring of emtpy tag instead of
overwriting existing tag - required when flash
value cannot be overwritten at all
ENABLE CONTROLLER WARM
EnableBOOT
stack startup without power cycle (if
supported/possible)
ENABLE SEGGER RTT Use SEGGER RTT for console output and
packet log, see additional options
ENABLE EXPLICIT CONNECTABLE
Disable calls
MODE
to control
CONTROL
Connectable Mode by
L2CAP
ENABLE EXPLICIT IO CAPABILITIES
Let application
REPLY
trigger sending IO Capabilities
(Negative) Reply
ENABLE EXPLICIT LINK KEY
Let application
REPLY trigger sending Link Key
(Negative) Response, allows for asynchronous
link key lookup
ENABLE EXPLICIT BR EDR
Report
SECURITY
BR/EDR MANAGER
Security Manager support in
L2CAP Information Response
ENABLE EXPLICIT DEDICATED
Keep connection
BONDING after
DISCONNECT
dedicated bonding is
complete
ENABLE CLASSIC OOB PAIRING
Enable support for classic Out-of-Band (OOB)
pairing
ENABLE A2DP EXPLICIT CONFIG
Let application configure stream endpoint
(skip auto-config of SBC endpoint)
ENABLE AVDTP ACCEPTORallow
EXPLICIT
accept or START
reject ofSTREAM
stream start
CONFIRMATION
on
A2DP SUBEVENT START STREAM REQUESTED
ENABLE LE WHITELIST TOUCH
Enable Workaround
AFTER RESOLVINGfor Controller
LIST bug
UPDATE
ENABLE LE SET ADV PARAMS
Send HCI
ON LE
RANDOM
Set Advertising
ADDRESS Params
CHANGEafter
HCI LE Set Random Address - workaround for
Controller Bug
ENABLE CONTROLLER DUMP
DumpPACKETS
number of packets in Controller per
type for debugging
ENABLE HCI COMMAND STATUS
Track connection
DISCARDED handleFORfor HCI
FAILED
Commands
CONNECTIONS
WORKAROUND and assume command has failed if disonnect
event for connection is received
ENABLE MUTUAL AUTHENTICATION
Re-authentication
FORafter
LEGACY
connection
SECUREwas CONNECTIONS
encrypted to avoid BIAS Attack. Not needed
for min encryption key size of 16
Notes:
• ENABLE MICRO ECC FOR LE SECURE CONNECTIONS: Only some
Bluetooth 4.2+ controllers (e.g., EM9304, ESP32) support the necessary
HCI 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 is
24
#define Description
HCI HOST ACL PACKET NUM Max number of ACL packets
HCI HOST ACL PACKET LEN Max size of HCI Host ACL packets
HCI HOST SCO PACKET NUM Max number of ACL packets
HCI 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 of
elements is defined in the btstack config.h file. To initialize the static
pools, you need to call at runtime btstack memory init function. An
example of memory configuration for a single SPP service with a minimal
L2CAP 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 is
recommended. The large ACL buffer is required for 3-DH5 packets to be used.
#define Description
HCI ACL PAYLOAD SIZE Max size of HCI ACL payloads
HCI ACL CHUNK SIZE ALIGNMENT
Alignment of ACL chunk size, can be used to
align HCI transport writes
HCI INCOMING PRE BUFFER
Number
SIZE
of bytes reserved before actual data for
incoming HCI packets
MAX NR BNEP CHANNELS Max number of BNEP channels
MAX NR BNEP SERVICESMax number of BNEP services
MAX NR GATT CLIENTS Max number of GATT clients
MAX NR HCI CONNECTIONS
Max number of HCI connections
MAX NR HFP CONNECTIONS
Max number of HFP connections
MAX NR L2CAP CHANNELSMax number of L2CAP connections
MAX NR L2CAP SERVICESMax number of L2CAP services
MAX NR RFCOMM CHANNELS
Max number of RFOMMM connections
25
#define Description
MAX NR RFCOMM MULTIPLEXERS
Max number of RFCOMM multiplexers, with
one multiplexer per HCI connection
MAX NR RFCOMM SERVICES
Max number of RFCOMM services
MAX NR SERVICE RECORD
MaxITEMS
number of SDP service records
MAX NR SM LOOKUP ENTRIES
Max number of items in Security Manager
lookup queue
MAX NR WHITELIST ENTRIES
Max number of items in GAP LE Whitelist to
connect to
#define Description
NVM NUM LINK Max
KEYSnumber of Classic Link Keys that can be stored
NVM NUM DEVICE
MaxDB
number
ENTRIES
of LE Device DB entries that can be stored
26
#define Description
NVN NUM GATTMax
SERVER
numberCCCof ‘Client Characteristic Configuration’
values that can be stored by GATT Server
0.8.6. HCI Dump Stdout directives. Allow to truncate HCI ACL and SCO pack-
ets to reduce console output for debugging audio applications.
#define Description
HCI DUMP STDOUT MAX SIZE ACL Max size of ACL packets to log via stdout
HCI DUMP STDOUT MAX SIZE SCO Max size of SCO packets to log via stdout
HCI DUMP STDOUT MAX SIZE ISO Max size of ISO packets to log via stdout
0.8.7. SEGGER Real Time Transfer (RTT) directives. SEGGER RTT improves
on 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 the
provided JLinkRTTLogger tool.
When enabled with ENABLE SEGGER RTT and hci dump init() can be called with
an 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:
int main ( ) {
// . . . hardware i n i t : watchdoch , IOs , t i m e r s , e t c . . .
// s e t u p BTstack memory p o o l s
27
// s e l e c t embedded run l o o p
btstack run loop init ( btstack run loop embedded get instance () ) ;
// e n a b l e l o g g i n g
hci dump init ( hci dump embedded stdout get instance () ) ;
// i n i t HCI
hci transport t ∗ transport = hci transport h4 instance () ;
h c i i n i t ( t r a n s p o r t , NULL) ;
// s e t u p example
b t s t a c k m a i n ( argc , argv ) ;
// go
btstack run loop execute () ;
}
First, BTstack’s memory pools are set up. Then, the standard run loop im-
plementation for embedded systems is selected.
The call to hci dump init configures BTstack to output all Bluetooth packets
and its own debug and error message using printf with BTstack’s millisecond
tiomestamps.s as tim. The Python script tools/create packet log.py can be used
to convert the console output into a Bluetooth PacketLogger format that can
be opened by the OS X PacketLogger tool as well as by Wireshark for further
inspection. When asking for help, please always include a log created with HCI
dump.
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 memory
implementation that allows for re-connects without a new pairing but doesn’t
persist the bonding information.
Finally, it calls btstack main() of the actual example before executing the run
loop.
0.10. Source tree structure. The source tree has been organized to easily
setup new projects.
Path Description
chipset Support for individual Bluetooth Controller chipsets
doc Sources for BTstack documentation
example Example applications available for all ports
platform Support for special OSs and/or MCU architectures
port Complete port for a MCU + Chipset combinations
src Bluetooth stack implementation
test Unit and PTS tests
tool Helper tools for BTstack
28
0.11. Run loop configuration. To initialize BTstack you need to initialize the
memory and the run loop respectively, then setup HCI and all needed higher level
protocols.
BTstack uses the concept of a run loop to handle incoming data and to schedule
work. The run loop handles events from two different types of sources: data
sources and timers. Data sources represent communication interfaces like an
UART or an USB driver. Timers are used by BTstack to implement various
Bluetooth-related timeouts. They can also be used to handle periodic events. In
addition, most implementations also allow to trigger a poll of the data sources
from interrupt context, or, execute a function from a different thread.
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 least
a linked list node and a pointer to a callback function. All active timers and
data sources are kept in link lists. While the list of data sources is unsorted, the
timers are sorted by expiration timeout for efficient processing. Data sources
need to be configured upon what event they are called back. They can be
configured to be polled (DATA SOURCE CALLBACK POLL), on read ready
(DATA SOURCE CALLBACK READ), or on write ready (DATA SOURCE CALLBACK WRITE
Timers are single shot: a timer will be removed from the timer list before
its event handler callback is executed. If you need a periodic timer, you can
re-register the same timer source in the callback function, as shown in Listing
[PeriodicTimerHandler]. Note that BTstack expects to get called periodically
to keep its time, see Section on time abstraction for more on the tick hardware
abstraction.
BTstack provides different run loop implementations that implement the bt-
stack run loop t interface:
• CoreFoundation: implementation for iOS and OS X applications
• Embedded: the main implementation for embedded systems, especially
without an RTOS.
• FreeRTOS: implementation to run BTstack on a dedicated FreeRTOS
thread
• POSIX: implementation for POSIX systems based on the select() call.
• Qt: implementation for the Qt applications
• 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.
29
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 become ready
for read or write (CoreFoundation, POSIX, Qt, Windows), or, are not used as
the HCI transport driver and the run loop is implemented in a different way
(WICED). In any case, the callbacks must be explicitly enabled with the bt-
stack run loop enable data source callbacks(..) function.
In your code, you’ll have to configure the run loop before you start it as shown
in Listing [listing:btstackInit]. The application can register data sources as well
as timers, e.g., for periodical sampling of sensors, or for communication over the
UART.
The run loop is set up by calling btstack run loop init function and providing
an instance of the actual run loop. E.g. for the embedded platform, it is:
btstack run loop init ( btstack run loop embedded get instance () ) ;
If the run loop allows to trigger polling of data sources from interrupt context,
btstack run loop poll data sources from irq.
On multi-threaded environments, e.g., FreeRTOS, POSIX, WINDOWS, bt-
stack run loop execute code on main thread can be used to schedule a callback
on the main loop.
The complete Run loop API is provided here.
0.11.1. Run Loop Embedded. In the embedded run loop implementation, data
sources are constantly polled and the system is put to sleep if no IRQ happens
during the poll of all data sources.
The complete run loop cycle looks like this: first, the callback function of
all registered data sources are called in a round robin way. Then, the callback
functions of timers that are ready are executed. Finally, it will be checked if
another 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 interrupt
and wake up the microcontroller. In order to avoid the situation where a data
source becomes ready just before the run loop enters sleep mode, an interrupt-
driven data source has to call the btstack run loop poll data sources from irq func-
tion. The call to btstack run loop poll data sources from irq sets an internal flag
that is checked in the critical section just before entering sleep mode causing
another run loop cycle.
To enable the use of timers, make sure that you defined HAVE EMBEDDED TICK
or HAVE EMBEDDED TIME MS in the config file.
While there is no threading, btstack run loop poll data sources from irq allows
to reduce stack size by scheduling a continuation.
0.11.2. Run Loop FreeRTOS. The FreeRTOS run loop is used on a dedicated
FreeRTOS thread and it uses a FreeRTOS queue to schedule callbacks on the
run loop. In each iteration:
• all data sources are polled
• all scheduled callbacks are executed
30
there is an implementation for HCI H4, HCI H5 and H2 libUSB, and for
WICED HCI H4 WICED. These are accessed by linking the appropriate
file, e.g., platform/embedded/hci\_transport\_h4\_embedded.c and
then 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 a n s p o r 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 u a r t c o n f i g t ∗ c o n f i g = &h c i u a r t c o n f i g ;
h c i i n i t ( transport , config ) ;
Finally, the HCI implementation requires some form of persistent storage for
link 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) persistent
store in memory. For more see here.
The higher layers only rely on BTstack and are initialized by calling the re-
spective ** init* function. These init functions register themselves with the
underlying layer. In addition, the application can register packet handlers to get
events 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 service
handles incoming connections for an L2CAP channel and is registered with its
protocol service multiplexer ID (PSM). Similarly, an RFCOMM service handles
incoming RFCOMM connections and is registered with the RFCOMM channel
ID. Outgoing connections require no special registration, they are created by the
application when needed.
0.14. Packet handlers configuration. After the hardware and BTstack are
set up, the run loop is entered. From now on everything is event driven. The
application calls BTstack functions, which in turn may send commands to the
Bluetooth module. The resulting events are delivered back to the application.
Instead of writing a single callback handler for each possible event (as it is done
in some other Bluetooth stacks), BTstack groups events logically and provides
them over a single generic interface. Appendix Events and Errors summarizes
the parameters and event codes of L2CAP and RFCOMM events, as well as
possible 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 BTstack
events.
• 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.
33
uint8 t a d d r e s s 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 a d d r e s s ;
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 , a d d r e s s ) ;
0.15. Bluetooth HCI Packet Logs. If things don’t work as expected, having
a look at the data exchanged between BTstack and the Bluetooth chipset often
helps.
For this, BTstack provides a configurable packet logging mechanism via hci dump.h
and the following implementations:
void h c i d u m p i n i t ( const h c i d u m p t ∗ h c i d u m p i m p l e m e n t a t i o n ) ;
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(const
char 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 console
via 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 the
hci 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 use
the create packet log.py tool in the tools folder to convert a text output into a
PacketLogger file.
For less overhead and higher logging speed, you can directly log in binary
format by passing hci dump segger rtt binary get instance() and selecting the
output 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
35
/∗ ∗
∗ @ b r i e f A l l o w s t o c o n t r o l i f d e v i c e i s d i s c o v e r a b l e . OFF by
default .
∗/
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 e n a b l e ) ;
If you don’t need to become connected from other devices for a longer period
of time, you can also disable the listening to connection requests.
To enable/disable connectability, you can call:
/∗ ∗
∗ @ b r i e f O v e r r i d e page scan mode . Page scan mode e n a b l e d by l 2 c a p
when s e r v i c e s a r e r e g i s t e r e d
∗ @note Might be used t o r e d u c e power consumption w h i l e B l u e t o o t h
module s t a y s powered b u t no ( new )
∗ connections are expected
∗/
void g a p c o n n e c t a b l e c o n t r o l ( uint8 t e n a b l e ) ;
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:
/∗ ∗
∗ @ b r i e f Enable / D i s a b l e A d v e r t i s e m e n t s . OFF by d e f a u l t .
∗ @param e n a b l e d
∗/
void g a p a d v e r t i s e m e n t s e n a b l e ( int e n a b l e d ) ;
from the Host. In this case, the Bluetooth Controller is free to enter some kind
of deep sleep where the power consumption is minimal.
Finally, if that’s not sufficient for your application, you could request BTstack
to shutdown the Bluetooth Controller. For this, the “on” and “off” functions in
the btstack control t struct must be implemented. To shutdown the Bluetooth
Controller, you can call:
/∗ ∗
∗ @ b r i e f R e q u e s t s t h e 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 be
started again via by calling it with mode HCI POWER ON, as seen in all exam-
ples.
#Protocols
BTstack 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 a
robust wireless connection between devices designed for high data rates. In
contrast, the LE technology has a lower throughput but also lower energy con-
sumption, faster connection setup, and the ability to connect to more devices in
parallel.
Whether Classic or LE, a Bluetooth device implements one or more Bluetooth
profiles. A Bluetooth profile specifies how one or more Bluetooth protocols are
used to achieve its goals. For example, every Bluetooth device must implement
the Generic Access Profile (GAP), which defines how devices find each other
and how they establish a connection. This profile mainly make use of the Host
Controller Interface (HCI) protocol, the lowest protocol in the stack hierarchy
which implements a command interface to the Bluetooth chipset.
In addition to GAP, a popular Classic Bluetooth example would be a peripheral
devices that can be connected via the Serial Port Profile (SPP). SPP basically
specifies that a compatible device should provide a Service Discovery Protocol
(SDP) record containing an RFCOMM channel number, which will be used for
the actual communication.
Similarly, for every LE device, the Generic Attribute Profile (GATT) profile
must be implemented in addition to GAP. GATT is built on top of the Attribute
Protocol (ATT), and defines how one device can interact with GATT Services
on a remote device.
So far, the most popular use of BTstack is in peripheral devices that can be
connected 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 and
iOS device, the iAP1 and iAP2 protocols of the Made for iPhone program can
be used instead of GATT. Please contact us directly for information on BTstack
and MFi.
37
PROFILES MFi
GATT SPP HSP HFP PBAP SDAP PAN A2DP AVRCP HID GAP MESH
iARP2
PROTOCOLS
L2CAP LE L2CAP
HCI
Figure below depicts Bluetooth protocols and profiles that are currently imple-
mented by BTstack. In the following, we first explain how the various Bluetooth
protocols 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
also keeps track of all active connections and handles the fragmentation and
re-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 the
startup phase to configure special features that are not available via the GAP
API yet. How to send a custom HCI command is explained in the following
section.
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 - Core
Version 4.0, Volume 2, Part E, Chapter 5.4.
Listing below shows the OGFs provided by BTstack in file src/hci.h:
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 using
38
the OPCODE macro. BTstack provides the hci cmd t struct as a compact format
to define HCI command packets, see Listing below, and src/hci cmd.h file in the
source code.
// C a l c u l a t e combined o g f / o c f v a l u e .
#define OPCODE( ogf , o c f ) ( o c f | o g f << 1 0 )
Listing below illustrates the hci write local name HCI command template from
library:
// S e t s l o c a l B l u e t o o t h name
const hci cmd t h c i w r i t e l o c a l n a m e = {
OPCODE(OGF CONTROLLER BASEBAND, 0 x13 ) , ”N”
// L o c a l name (UTF−8, N u l l Terminated , max 248 o c t e t s )
};
Listing below illustrates how to manually set the device name with the HCI
Write Local Name command.
Please note, that an application rarely has to send HCI commands on its
own. Instead, BTstack provides convenience functions in GAP and higher level
protocols that use HCI automatically.
local cid =
l2cap event channel opened get local cid (
packet ) ;
handle =
l2cap event channel opened get handle ( 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 ” ) ;
} else
p r i n t f ( ” Connected \n\ r ” ) ;
}
break ;
case L2CAP EVENT CHANNEL CLOSED :
break ;
...
}
case L2CAP DATA PACKET:
// h a n d l e L2CAP d a t a p a c k e t
break ;
...
}
}
void b t s t a c k s e t u p ( ) {
...
l2cap init () ;
}
void b t s t a c k s e t u p ( ) {
...
l2cap init () ;
l 2 c a p r e g i s t e r s e r v i c e (NULL, p a c k e t h a n d l e r , 0 x11 , 1 0 0 ) ;
}
0.18.3. Sending L2CAP Data. Sending of L2CAP data packets may fail due to
a full internal BTstack outgoing packet buffer, or if the ACL buffers in the
Bluetooth module become full, i.e., if the application is sending faster than the
packets can be transferred over the air.
Instead of directly calling l2cap send, it is recommended to call l2cap request can send now event(c
which will trigger an L2CAP EVENT CAN SEND NOW as soon as possible. It
might happen that the event is received via packet handler before the l2cap request can send now eve
function returns. The L2CAP EVENT CAN SEND NOW indicates a channel
ID on which sending is possible.
42
Please note that the guarantee that a packet can be sent is only valid when
the event is received. After returning from the packet handler, BTstack might
need to send itself.
0.18.4. LE Data Channels. The 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.
LE Data Channels are similar to Classic L2CAP Channels but also provide a
credit-based flow control similar to RFCOMM Channels. Unless 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.
Since 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.
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. Further
credits can be provided anytime with l2cap cbm provide credits. If L2CAP LE AUTOMATIC CRED
is used, BTstack automatically provides credits as needed - effectively trading in
the flow-control functionality for convenience.
The remainder of the API is similar to the one of L2CAP:
• l2cap cbm register service and l2cap cbm unregister service are used to
manage local services.
• l2cap cbm accept connection and l2cap cbm decline connection are used
to accept or deny an incoming connection request.
• l2cap cbm create channel creates an outgoing connections.
• l2cap cbm can send now checks if a packet can be scheduled for trans-
mission now.
• l2cap cbm request can send now event requests an L2CAP EVENT LE CAN SEND NOW
event as soon as possible.
• l2cap cbm disconnect closes the connection.
you will therefore receive this data in the same order, but there are no guarantees
as how it might be fragmented into multiple chunks.
If you need to preserve the concept of sending a packet with a specific size
over RFCOMM, the simplest way is to prefix the data with a 2 or 4 byte length
field 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,
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 prefix
the data as described.
switch ( h c i e v e n t p a c k e t g e t t y p e ( p a c k e t ) ) {
case RFCOMM EVENT CHANNEL OPENED:
if (
rfcomm event open channel complete get status
( 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 ” ) ;
}
break ;
case RFCOMM EVENT CHANNEL CLOSED:
break ;
...
}
break ;
case RFCOMM DATA PACKET:
// h a n d l e RFCOMM d a t a p a c k e t s
return ;
}
}
void b t s t a c k s e t u p ( ) {
...
l2cap init () ;
rfcomm init () ;
}
The RFCOMM channel will stay open until either side closes it with rf-
comm disconnect. BTstack will close the multiplexer after 60 seconds without
an active RFCOMM channel.
switch ( p a c k e t t y p e ) {
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 ( p a c k e t ) ) {
case RFCOMM EVENT INCOMING CONNECTION:
rfcomm channel id =
rfcomm event incoming connection get rfcomm cid
( packet ) ;
rfcomm accept connection ( rfcomm channel id ) ;
break ;
case RFCOMM EVENT CHANNEL OPENED:
if (
rfcomm event open channel complete get status
( packet ) ) {
p r i n t f ( ”RFCOMM c h a n n e l open f a i l e d . ” ) ;
break ;
}
rfcomm channel id =
rfcomm event open channel complete get rfcomm cid
( packet ) ;
mtu =
rfcomm event open channel complete get max frame size
( packet ) ;
p r i n t f ( ”RFCOMM c h a n n e l open s u c c e e d e d , max frame
s 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:
// h a n d l e RFCOMM d a t a p a c k e t s
return ;
...
}
...
}
void b t s t a c k s e t u p ( ) {
...
l2cap init () ;
rfcomm init () ;
r f c o m m r e g i s t e r s e r v i c e ( p a c k e t h a n d l e r , rf co m m c ha nn el nr , mtu ) ;
}
is only useful if there is not much data transmitted and/or only one physical
connection is used. See Listing below.
void b t s t a c k s e t u p ( void ) {
...
// i n i t RFCOMM
rfcomm init () ;
r f c o m m r e g i s t e r s e r v i c e ( p a c k e t h a n d l e r , rf co m m c ha nn el nr , 1 0 0 ) ;
}
void b t s t a c k s e t u p ( void ) {
...
// i n i t RFCOMM
rfcomm init () ;
// r e s e r v e d channel , mtu=100 , 1 c r e d i t
r 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 ,
rf c om m c ha nn el n r , 1 0 0 , 1 ) ;
}
void p r o c e s s i n g ( ) {
// p r o c e s s incoming d a t a p a c k e t
...
// p r o v i d e new c r e d i t
rfcomm grant credits ( rfcomm 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 data
throughput substantially. On the plus side, it allows for a minimal memory
footprint. If possible, multiple RFCOMM buffers should be used to avoid pauses
while 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 design
decision for sending data and why it is not as bad as it sounds.
Independent from the number of output buffers, packet generation has to be
adapted to the remote receiver and/or maximal link speed. Therefore, a packet
can only be generated when it can get sent. With this assumption, the single
47
output 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 and
wait for the reception of the RFCOMM EVENT CAN SEND NOW event to
send the packet, as shown in Listing below.
Please note that the guarantee that a packet can be sent is only valid when
the event is received. After returning from the packet handler, BTstack might
need to send itself.
void p r e p a r e d a t a ( uint16 t r f c o m m c h a n n e l i d ) {
...
// p r e p a r e d a t a i n d a t a b u f f e r
rfcomm request can send now event ( rfcomm channel id ) ;
}
void s e n d d a t a ( uint16 t r f c o m m c h a n n e l i d ) {
rfcomm send ( r f c o m m c h a n n e l i d , d a t a b u f f e r , d a t a l e n ) ;
// p a c k e t i s handed o v e r t o BTstack , we can p r e p a r e t h e n e x t one
prepare data ( rfcomm channel id ) ;
}
buffer with rfcomm get outgoing buffer. Now, you can fill that buffer and finally
send 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 SDP
server and allows to register SDP records. An SDP record is a list of SDP
Attribute {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 like
integers or strings or can itself contain other DES.
To create an SDP record for an SPP service, you can call spp create sdp record
from 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 data
element de functions. Listing [sdpCreate] shows how an SDP record containing
two SDP attributes can be created. First, a DES is created and then the Service
Record Handle and Service Class ID List attributes are added to it. The Service
Record Handle attribute is added by calling the de add number function twice:
the first time to add 0x0000 as attribute ID, and the second time to add the
actual record handle (here 0x1000) as attribute value. The Service Class ID
List attribute has ID 0x0001, and it requires a list of UUIDs as attribute value.
To create the list, de push sequence is called, which “opens” a sub-DES. The
returned pointer is used to add elements to this sub-DES. After adding all UUIDs,
the sub-DES is “closed” with de pop sequence.
To register an SDP record, you call sdp register service with a pointer to it.
The SDP record can be stored in FLASH since BTstack only stores the pointer.
Please note that the buffer needs to persist (e.g. global storage, dynamically
allocated from the heap or in FLASH) and cannot be used to create another
SDP record.
0.20.2. Query remote SDP service. BTstack provides an SDP client to query
SDP services of a remote device. The SDP Client API is shown in here. The
sdp client query function initiates an L2CAP connection to the remote SDP
server. Upon connect, a Service Search Attribute request with a Service Search
Pattern and a Attribute ID List is sent. The result of the Service Search Attribute
query contains a list of Service Records, and each of them contains the requested
attributes. These records are handled by the SDP parser. The parser delivers
SDP PARSER ATTRIBUTE VALUE and SDP PARSER COMPLETE events
via a registered callback. The SDP PARSER ATTRIBUTE VALUE event de-
livers the attribute value byte by byte.
On top of this, you can implement specific SDP queries. For example, BT-
stack provides a query for RFCOMM service name and channel number. This
information is needed, e.g., if you want to connect to a remote SPP service.
The query delivers all matching RFCOMM services, including its name and the
channel number, as well as a query complete event via a registered callback, as
shown in Listing below.
49
uint8 t e v e n t = p a c k e t [ 0 ] ;
switch ( e v e n t ) {
case BTSTACK EVENT STATE:
// b t s t a c k a c t i v a t e d , g e t s t a r t e d
i f ( b t s t a c k e v e n t s t a t e g e t s t a t e ( p a c k e t ) ==
HCI STATE WORKING) {
sdp client query rfcomm channel and name for uuid (
remote , 0 x0003 ) ;
}
break ;
default :
break ;
}
}
s t a t i c void b t s t a c k s e t u p ( ) {
...
// i n i t L2CAP
l2cap init () ;
l2cap register packet handler ( packet handler ) ;
}
switch ( event−>type ) {
case SDP EVENT QUERY RFCOMM SERVICE:
ve = ( sdp client query rfcomm service event t ∗ ) e v e n t ;
p r i n t f ( ” S e r v i c e name : ’% s ’ , RFCOMM p o r t %u\n” , ve−>
s e r v i c e n a m e , ve−>c h a n n e l n r ) ;
break ;
case SDP EVENT QUERY COMPLETE:
report found services () ;
p r i n t f ( ” C l i e n t query r e s p o n s e done with s t a t u s %d . \n” ,
ce−>s t a t u s ) ;
break ;
}
}
// t u r n on !
h c i p o w e r c o n t r o l (HCI POWER ON) ;
// go !
btstack run loop execute () ;
return 0 ;
}
0.21.1. Receive BNEP events. To receive BNEP events, please register a packet
handler with bnep register packet handler.
0.21.3. Provide BNEP service. To provide a BNEP service, call bnep register service
with the provided service UUID and a max frame size.
A BNEP EVENT INCOMING CONNECTION event will mark that an in-
coming connection is established. At this point you can start sending and re-
ceiving Ethernet packets as described in the previous section.
0.21.4. Sending Ethernet packets. Similar to L2CAP and RFOMM, directly send-
ing an Ethernet packet via BNEP might fail, if the outgoing packet buffer or the
ACL buffers in the Bluetooth module are full.
When there’s a need to send an Ethernet packet, call bnep request can send now
and send the packet when the BNEP EVENT CAN SEND NOW event gets re-
ceived.
0.22. ATT - Attribute Protocol. The ATT protocol is used by an ATT client
to read and write attribute values stored on an ATT server. In addition, the ATT
server can notify the client about attribute value changes. An attribute has a
handle, a type, and a set of properties.
51
The Generic Attribute (GATT) profile is built upon ATT and provides higher
level organization of the ATT attributes into GATT Services and GATT Char-
acteristics. In BTstack, the complete ATT client functionality is included within
the GATT Client. See GATT client for more.
On the server side, one ore more GATT profiles are converted ahead of time
into the corresponding ATT attribute database and provided by the att server
implementation. The constant data are automatically served by the ATT server
upon client request. To receive the dynamic data, such is characteristic value, the
application needs to register read and/or write callback. In addition, notifications
and indications can be sent. Please see Section on GATT server for more.
0.23. SMP - Security Manager Protocol. The SMP protocol allows to setup
authenticated and encrypted LE connection. After initialization and configura-
tion, SMP handles security related functions on its own but emits events when
feedback from the main app or the user is required. The two main tasks of the
SMP protocol are: bonding and identity resolving.
0.23.1. LE Legacy Pairing and LE Secure Connections. The original pairing al-
gorithm introduced in Bluetooth Core V4.0 does not provide security in case of
an attacker present during the initial pairing. To fix this, the Bluetooth Core
V4.2 specification introduced the new LE Secure Connections method, while
referring to the original method as LE Legacy Pairing.
BTstack supports both pairing methods. To enable the more secure LE Se-
cure Connections method, ENABLE LE SECURE CONNECTIONS needs to be
defined in btstack config.h.
LE Secure Connections are based on Elliptic Curve Diffie-Hellman (ECDH)
algorithm for the key exchange. On start, a new public/private key pair is
generated. During pairing, the Long Term Key (LTK) is generated based on
the local keypair and the remote public key. To facilitate the creation of such a
keypairs and the calculation of the LTK, the Bluetooth Core V4.2 specification
introduced appropriate commands for the Bluetooth controller.
As 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. When using using LE Secure Connections, the Pe-
ripheral must store LTK in non-volatile memory.
To only allow LE Secure Connections, you can call sm set secure connections only mode(true).
0.26.2. Discover remote devices. To scan for remote devices, the hci inquiry com-
mand is used. Found remote devices are reported as a part of:
• HCI EVENT INQUIRY RESULT,
• HCI EVENT- INQUIRY RESULT WITH RSSI, or
• HCI EVENT EXTENDED INQUIRY RESPONSE events.
Each response contains at least the Bluetooth address, the class of device, the
page scan repetition mode, and the clock offset of found device. The latter events
add information about the received signal strength or provide the Extended
Inquiry Result (EIR). A code snippet is shown in Listing below.
void p r i n t i n q u i r y r e s u l t s ( uint8 t ∗ p a c k e t ) {
int e v e n t = p a c k e t [ 0 ] ;
int numResponses = h c i e v e n t i n q u i r y r e s u l t g e t n u m r e s p o n s e s (
packet ) ;
uint16 t c l a s s O f D e v i c e , c l o c k O f f s e t ;
uint8 t r s s i , pageScanRepetitionMode ;
f o r ( i =0; i <numResponses ; i ++){
b t f l i p a d d r ( addr , &p a c k e t [3+ i ∗ 6 ] ) ;
pageScanRepetitionMode = p a c k e t [ 3 + numResponses ∗6 + i ] ;
i f ( e v e n t == HCI EVENT INQUIRY RESULT) {
c l a s s O f D e v i c e = l i t t l e e n d i a n r e a d 2 4 ( packet , 3 +
numResponses∗(6+1+1+1) + i ∗ 3 ) ;
clockOffset = l i t t l e e n d i a n r e a d 1 6 ( packet , 3 +
numResponses∗(6+1+1+1+3) + i ∗ 2 ) & 0 x 7 f f f ;
r s s i = 0;
} else {
c l a s s O f D e v i c e = l i t t l e e n d i a n r e a d 2 4 ( packet , 3 +
numResponses ∗(6+1+1) + i ∗3) ;
clockOffset = l i t t l e e n d i a n r e a d 1 6 ( packet , 3 +
numResponses∗(6+1+1+3) + i ∗2) & 0 x 7 f f f ;
r s s i = p a c k e t [ 3 + numResponses∗(6+1+1+3+2) + i ∗ 1 ] ;
}
56
By default, neither RSSI values nor EIR are reported. If the Bluetooth de-
vice implements Bluetooth Specification 2.1 or higher, the hci write inquiry mode
command enables reporting of this advanced features (0 for standard results, 1
for RSSI, 2 for RSSI and EIR).
A complete GAP inquiry example is provided here.
// b a s e b a n d a d d r e s s , p i n l e n g t h , PIN : c−s t r i n g
h c i s e n d c m d (& h c i p i n c o d e r e q u e s t r e p l y , &bd addr , 4 , ”
0000 ” ) ;
break ;
...
}
}
0.26.4. Dedicated Bonding. Aside from the regular bonding, Bluetooth also pro-
vides the concept of “dedicated bonding”, where a connection is established for
the sole purpose of bonding the device. After the bonding process is over, the
connection will be automatically terminated. BTstack supports dedicated bond-
ing via the gap dedicated bonding function.
0.27. SPP - Serial Port Profile. The SPP profile defines how to set up virtual
serial ports and connect two Bluetooth enabled devices. Please keep in mind
that a serial port does not preserve packet boundaries if you try to send data as
packets and read about RFCOMM packet boundaries.
you have identified the correct RFCOMM channel, you can create an RFCOMM
connection as shown here.
0.27.2. Providing an SPP Server. To provide an SPP Server, you need to provide
an RFCOMM service with a specific RFCOMM channel number as explained in
section on RFCOMM service. Then, you need to create an SDP record for
it and publish it with the SDP server by calling sdp register service. BTstack
provides the spp create sdp record function in that requires an empty buffer of
approximately 200 bytes, the service channel number, and a service name. Have
a look at the SPP Counter example.
0.28. PAN - Personal Area Networking Profile. The PAN profile uses
BNEP to provide on-demand networking capabilities between Bluetooth devices.
The PAN profile defines the following roles:
• PAN User (PANU)
• Network Access Point (NAP)
• Group Ad-hoc Network (GN)
PANU is a Bluetooth device that communicates as a client with GN, or NAP,
or with another PANU Bluetooth device, through a point-to-point connection.
Either the PANU or the other Bluetooth device may terminate the connection
at anytime.
NAP is a Bluetooth device that provides the service of routing network packets
between PANU by using BNEP and the IP routing mechanism. A NAP can also
act as a bridge between Bluetooth networks and other network technologies by
using the Ethernet packets.
The GN role enables two or more PANUs to interact with each other through
a wireless network without using additional networking hardware. The devices
are connected in a piconet where the GN acts as a master and communicates
either point-to-point or a point-to-multipoint with a maximum of seven PANU
slaves by using BNEP.
Currently, BTstack supports only PANU.
0.29. HSP - Headset Profile. The HSP profile defines how a Bluetooth-
enabled headset should communicate with another Bluetooth enabled device.
It relies on SCO for audio encoded in 64 kbit/s CVSD and a subset of AT com-
mands from GSM 07.07 for minimal controls including the ability to ring, answer
a call, hang up and adjust the volume.
The HSP defines two roles:
• Audio Gateway (AG) - a device that acts as the gateway of the audio,
typically a mobile phone or PC.
• Headset (HS) - a device that acts as the AG’s remote audio input and
output control.
There are following restrictions: - The CVSD is used for audio transmission.
• Between headset and audio gateway, only one audio connection at a time
is supported.
• The profile offers only basic interoperability – for example, handling of
multiple calls at the audio gateway is not included.
• The only assumption on the headset’s user interface is the possibility to
detect a user initiated action (e.g. pressing a button).
%TODO: audio paths
0.30. HFP - Hands-Free Profile. The HFP profile defines how a Bluetooth-
enabled device, e.g. a car kit or a headset, can be used to place and receive
calls via a audio gateway device, typically a mobile phone. It relies on SCO for
audio encoded in 64 kbit/s CVSD and a bigger subset of AT commands from
GSM 07.07 then HSP for controls including the ability to ring, to place and
receive calls, join a conference call, to answer, hold or reject a call, and adjust
the volume.
The HFP defines two roles:
• Audio Gateway (AG) – a device that acts as the gateway of the audio,,
typically a mobile phone.
• Hands-Free Unit (HF) – a device that acts as the AG’s remote audio
input and output control.
0.30.1. Supported Features. The supported features define the HFP capabilities
of the device. The enumeration unfortunately differs between HF and AG sides.
The AG supported features are set by combining the flags that start with
HFP AGSF xx and calling hfp ag init supported features, followed by creating
SDP record for the service using the same feature set.
Similarly, the HF supported features are a combination of HFP HFSF xx flags
and are configured by calling hfp hf init supported features, as well as creating
an SDP record.
Define for AG Supported Feature Description
HFP AGSF THREE WAY CALLING Three-way calling
HFP AGSF EC NR FUNCTION Echo Canceling and/or Noise
Reduction function
HFP AGSF VOICE RECOGNITION FUNCTION
Voice recognition function
HFP AGSF IN BAND RING TONE In-band ring tone capability
60
0.30.2. Audio Voice Recognition Activation. Audio voice recognition (AVR) re-
quires that HF and AG have the following features enabled:
• HF: HFP HFSF VOICE RECOGNITION FUNCTION and
• AG: HFP AGSF VOICE RECOGNITION FUNCTION.
It can be activated or deactivated on both sides by calling:
// AG
uint8 t h f p a g a c t i v a t e v o i c e r e c o g n i t i o n ( h c i c o n h a n d l e t
acl handle ) ;
uint8 t h f p a g d e a c t i v a t e v o i c e r e c o g n i t i o n ( h c i c o n h a n d l e t
acl handle ) ;
61
// HF
uint8 t h f p h f a c t i v a t e v o i c e r e c o g n i t i o n ( h c i c o n h a n d l e t
acl handle ) ;
uint8 t h f p h f d e a c t i v a t e v o i c e r e c o g n i t i o n ( h c i c o n h a n d l e t
acl handle ) ;
Beyond the audio routing and voice recognition activation capabilities, the
rest of the voice recognition functionality is implementation dependent - the
stack only provides the signaling for this.
When eAVR and audio channel are established there are several additional
commands that can be sent:
HFP Role eVRA API Description
HF hfp hf enhanced voice recognition
Ready to accept
reportaudio
ready for audio
input.
AG hfp ag enhanced voice recognition
Voice recognition
report engine
ready for
is audio
ready to accept audio
input.
AG hfp ag enhanced voice recognition
The voice recognition
report sending audio
engine will play a sound,
e.g. starting sound.
AG hfp ag enhanced voice recognition
Voice recognition
report engine
processing
is input
processing the audio input.
AG hfp ag enhanced voice recognition
Report textual
send message
representation from the
voice recognition engine.
0.32. GAP LE - Generic Access Profile for Low Energy. As with GAP
for Classic, the GAP LE profile defines how to discover and how to connect to
a Bluetooth Low Energy device. There are several GAP roles that a Bluetooth
device can take, but the most important ones are the Central and the Peripheral
role. Peripheral devices are those that provide information or can be controlled.
Central devices are those that consume information or control the peripherals.
Before the connection can be established, devices are first going through an
advertising process.
0.33. GATT Client. The GATT profile uses ATT Attributes to represent a hi-
erarchical structure of GATT Services and GATT Characteristics. Each Service
has one or more Characteristics. Each Characteristic has meta data attached
like its type or its properties. This hierarchy of Characteristics and Services are
queried and modified via ATT operations.
GATT defines both a server and a client role. A device can implement one or
both GATT roles.
The GATT Client is used to discover services, characteristics and their de-
scriptors on a peer device. It allows to subscribe for notifications or indications
that the characteristic on the GATT server has changed its value.
To perform GATT queries, it provides a rich interface. Before calling queries,
the GATT client must be initialized with gatt client init once.
To allow for modular profile implementations, GATT client can be used inde-
pendently by multiple entities.
After an LE connection was created using the GAP LE API, you can query
for the connection MTU with gatt client get mtu.
Multiple GATT queries to the same GATT Server cannot be interleaved.
Therefore, you can either use a state machine or similar to perform the queries
in sequence, or you can check if you can perform a GATT query on a particular
connection right now using gatt client is ready, and retry later if it is not ready.
As a result to a GATT query, zero to many GATT EVENT X s are returned
before a GATT EVENT QUERY COMPLETE event completes the query.
For more details on the available GATT queries, please consult GATT Client
API.
64
0.34. GATT Server. The GATT server stores data and accepts GATT client
requests, commands and confirmations. The GATT server sends responses to
requests and when configured, sends indication and notifications asynchronously
to the GATT client.
To save on both code space and memory, BTstack does not provide a GATT
Server implementation. Instead, a textual description of the GATT profile is
directly converted into a compact internal ATT Attribute database by a GATT
profile compiler. The ATT protocol server - implemented by and - answers
incoming ATT requests based on information provided in the compiled database
and provides read- and write-callbacks for dynamic attributes.
GATT profiles are defined by a simple textual comma separated value (.csv)
representation. While the description is easy to read and edit, it is compact and
can be placed in ROM.
The current format is shown in Listing below.
65
// i m p o r t s e r v i c e n a m e
#import <s e r v i c e n a m e . g a t t >
Property Description
READ Characteristic can be read
WRITE Characteristic can be written using Write Request
WRITE WITHOUT RESPONSE Characteristic can be written using Write Command
NOTIFY Characteristic allows notifications by server
INDICATE Characteristic allows indication by server
DYNAMIC Read or writes to Characteristic are handled by application
Property Description
AUTHENTICATION REQUIRED Read and Write operations require Authentication
READ ENCRYPTED Read operations require Encryption
READ AUTHENTICATED Read operations require Authentication
WRITE ENCRYPTED Write operations require Encryption
WRITE AUTHENTICATED Write operations require Authentication
ENCRYPTION KEY SIZE X Require encryption size >= X, with W in [7..16]
To use already implemented GATT Services, you can import it using the
#import <service name.gatt> command. See list of provided services.
BTstack only provides an ATT Server, while the GATT Server logic is mainly
provided by the GATT compiler. While GATT identifies Characteristics by
UUIDs, ATT uses Handles (16 bit values). To allow to identify a Characteristic
without hard-coding the attribute ID, the GATT compiler creates a list of defines
in the generated *.h file.
Similar to other protocols, it might be not possible to send any time. To send
a Notification, you can call att server request to send notification to request a
callback, when yuo can send the Notification.
If your application cannot handle an ATT Read Request in the att read callback
in some situations, you can enable support for this by adding ENABLE ATT DELAYED RESPONS
to btstack config.h. Now, you can store the requested attribute handle and re-
turn ATT READ RESPONSE PENDING instead of the length of the provided
data when you don’t have the data ready. For ATT operations that read more
than one attribute, your att read callback might get called multiple times as
well. To let you know that all necessary attribute handles have been ‘requested’
by the att server, you’ll get a final att read callback with the attribute handle of
ATT READ RESPONSE PENDING. When you’ve got the data for all requested
attributes ready, you can call att server response ready, which will trigger pro-
cessing of the current request. Please keep in mind that there is only one active
ATT operation and that it has a 30 second timeout after which the ATT server
is considered defunct by the GATT Client.
$ t o o l / c o n v e r t g a t t s e r v i c e . py
F e t c h i n g l i s t o f s e r v i c e s from h t t p s : //www. b l u e t o o t h . com/
specifications / gatt / services
S p e c i f i c a t i o n Type |
S p e c i f i c a t i o n Name | UUID
67
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
To c o n v e r t a s e r v i c e i n t o a . g a t t f i l e template , p l e a s e c a l l t h e
s c r i p t a g a i n with t h e r e q u e s t e d S p e c i f i c a t i o n Type and t h e
output f i l e name
Usage : t o o l / c o n v e r t g a t t s e r v i c e . py SPECIFICATION TYPE [ s e r v i c e n a m e
. gatt ]
Step 2:
To convert service into .gatt file, call *tool/convert gatt service.py with the
requested Specification Type and the output file name.
$ t o o l / c o n v e r t g a t t s e r v i c e . py o r g . b l u e t o o t h . s e r v i c e . b a t t e r y s e r v i c e
battery service . gatt
F e t c h i n g o r g . b l u e t o o t h . s e r v i c e . b a t t e r y s e r v i c e from
h t t p s : //www. b l u e t o o t h . com/ a p i / g a t t / x m l f i l e ? xmlFileName=o r g . b l u e t o o t h
. s e r v i c e . b a t t e r y s e r v i c e . xml
S e r v i c e Battery S e r v i c e
− C h a r a c t e r i s t i c B a t t e r y L e v e l − p r o p e r t i e s [ ’ Read ’ , ’ N o t i f y ’ ]
−− D e s c r i p t o r C h a r a c t e r i s t i c P r e s e n t a t i o n Format − TODO:
Please set values
−− D e s c r i p t o r C l i e n t C h a r a c t e r i s t i c C o n f i g u r a t i o n
Step 3:
In most cases, you will need to customize the .gatt file. Please pay attention
to the tool output and have a look at the generated .gatt file.
E.g. in the generated .gatt file for the Battery Service
// S p e c i f i c a t i o n Type o r g . b l u e t o o t h . s e r v i c e . b a t t e r y s e r v i c e
// h t t p s : / /www. b l u e t o o t h . com/ a p i / g a t t / x m l f i l e ? xmlFileName=o r g .
b l u e t o o t h . s e r v i c e . b a t t e r y s e r v i c e . xml
// B a t t e r y S e r v i c e 180F
PRIMARY SERVICE, ORG BLUETOOTH SERVICE BATTERY SERVICE
CHARACTERISTIC, ORG BLUETOOTH CHARACTERISTIC BATTERY LEVEL, DYNAMIC
| READ | NOTIFY,
68
// TODO: C h a r a c t e r i s t i c P r e s e n t a t i o n Format : p l e a s e s e t v a l u e s
#TODO CHARACTERISTIC FORMAT, READ, f o r m a t , e x p o n e n t , u n i t ,
name space , d e s c r i p t i o n
CLIENT CHARACTERISTIC CONFIGURATION, READ | WRITE,
you could delete the line regarding the CHARACTERISTIC FORMAT, since
it’s not required if there is a single instance of the service. Please compare the
.gatt file against the Adopted Specifications.
Step 4:
As described above all read/write requests are handled by the application. To
implement the new services as a reusable module, it’s necessary to get access to
all read/write requests related to this service.
For this, the ATT DB allows to register read/write callbacks for a specific
handle range with att server register service handler().
Since the handle range depends on the application’s .gatt file, the handle range
for Primary and Secondary Services can be queried with gatt server get get handle range for service
Similarly, you will need to know the attribute handle for particular Charac-
teristics to handle Characteristic read/writes requests. You can get the attribute
value handle for a Characteristics gatt server get value handle for characteristic with uuid16().
In addition to the attribute value handle, the handle for the Client Characteris-
tic Configuration is needed to support Indications/Notifications. You can get this
attribute handle with gatt server get client configuration handle for characteristic with uuid16()
Finally, in order to send Notifications and Indications independently from
the main application, att server register can send now callback can be used to
request a callback when it’s possible to send a Notification or Indication.
To see how this works together, please check out the Battery Service Server in
src/ble/battery service server.c.
0.34.2. GATT Database Hash. When a GATT Client connects to a GATT Server,
it cannot know if the GATT Database has changed and has to discover the pro-
vided GATT Services and Characteristics after each connect.
To speed this up, the Bluetooth specification defines a GATT Service Changed
Characteristic, with the idea that a GATT Server would notify a bonded GATT
Client if its database changed. However, this is quite fragile and it is not clear
how it can be implemented in a robust way.
The Bluetooth Core Spec 5.1 introduced the GATT Database Hash Charac-
teristic, which allows for a simple robust mechanism to cache a remote GATT
Database. The GATT Database Hash is a 16-byte value that is calculated over
the list of Services and Characteristics. If there is any change to the database,
the hash will change as well.
To support this on the GATT Server, you only need to add a GATT Service
with the GATT Database Characteristic to your .gatt file. The hash value is
then calculated by the GATT compiler.
Note: make sure to install the PyCryptodome python package as the hash is
calculated using AES-CMAC, e.g. with:
p i p i n s t a l l pycryptodomex
0.40. Heart Rate Service Server. The heart rate service server provides heart
rate measurements via notifications.
Each notification reports the heart rate measurement in beats per minute, and
if enabled, the total energy expended in kilo Joules, as well as RR-intervals in
1/1024 seconds resolution.
The Energy Expended field represents the accumulated energy expended in
kilo Joules since the last time it was reset. If the maximum value of 65535 kilo
Joules is reached, it will remain at this value, until a reset command from the
client is received.
The RR-Interval represents the time between two consecutive R waves in an
Electrocardiogram (ECG) waveform. If needed, the RR-Intervals are sent in
multiple notifications.
To use with your application, add #import <heart rate service.gatt> to your .gatt
file. After adding it to your .gatt file, you call heart rate server init(body sensor location,
energy expended supported) with the intended sensor location, and a flag indicat-
ing if energy expanded is supported.
If heart rate measurement changes, you can call heart rate service server update heart rate values(
service sensor contact status, rr interval count, rr intervals). This function will
trigger sending Notifications if the client enables them.
If energy expanded is supported, you can call heart rate service add energy expended(energy expen
with the newly expanded energy. The accumulated energy expended value will
be emitted with the next heart rate measurement.
See Heart Rate Service Server API.
0.41. HIDS Device. Implementation of the GATT HIDS Device To use with
your application, add ‘#import <hids.gatt>’ to your .gatt file
See HIDS Device API.
0.42. Nordic SPP Service Server. The Nordic SPP Service is implementation
of the Nordic SPP-like profile.
To use with your application, add #import <nordic spp service.gatt> to your .gatt
file and call all functions below. All strings and blobs need to stay valid after
calling the functions.
See Nordic SPP Service Server API.
0.43. Scan Parameters Service Server. The Scan Parameters Service enables
a remote GATT Client to store the LE scan parameters it is using locally. These
parameters can be utilized by the application to optimize power consumption
and/or reconnection latency.
71
To use with your application, add #import <scan parameters service.gatt> to your
.gatt file and call all functions below. All strings and blobs need to stay valid
after calling the functions.
See Scan Parameters Service Server API.
0.44. Tx Power Service Server. The TX Power service exposes a device’s
current transmit power level when in a connection. There shall only be one
instance of the Tx Power service on a device.
To use with your application, add #import <tx power service.gatt> to your .gatt
file. After adding it to your .gatt file, you call tx power service server init(value)
with the device’s current transmit power level value.
If the power level value changes, you can call tx power service server set level(tx power level dBm)
The service does not support sending Notifications.
See Tx Power Service Server API.
0.45. u-blox SPP Service Server. The u-blox SPP Service is implementation
of the u-Blox SPP-like profile.
To use with your application, add #import <ublox spp service.gatt> to your .gatt
file and call all functions below. All strings and blobs need to stay valid after
calling the functions.
See u-blox SPP Service Server API.
#Implemented GATT Clients
BTstack allows to implement and use GATT Clients in a modular way.
0.46. ANCS Client. The ANCS Client implements Notification Consumer (NC)
of the Apple Notification Center Service (ANCS).
See ANCS Client API.
0.47. Battery Service Client. The Battery Service Client connects to the Bat-
tery Services of a remote device and queries its battery level values. Level updates
are either received via notifications (if supported by the remote Battery Service),
or by manual polling.
See Battery Service Client API.
0.48. Device Information Service Client. The Device Information Service
Client retrieves the following information from a remote device: - manufacturer
name- model number - serial number - hardware revision- firmware revision-
software revision- system ID - IEEE regulatory certification- PNP ID
See Device Information Service Client API.
0.49. HIDS Client. The HID Service Client is used on the HID Host to receive
reports and other HID data.
See HIDS Client API.
0.50. Scan Parameters Service Client. The Scan Parameters Service Client
allows to store its LE scan parameters on a remote device such that the re-
mote device can utilize this information to optimize power consumption and/or
reconnection latency.
See Scan Parameters Service Client API.
#Examples
72
In this section, we will describe a number of examples from the example folder.
Here is a list of existing examples:
• Hello World example:
– led counter: Hello World - Blinking an LED without Bluetooth.
• GAP examples:
– gap inquiry: GAP Classic Inquiry.
– gap link keys: GAP Link Key Management (Classic).
• Low Energy examples:
– gap le advertisements: GAP LE Advertisements Scanner.
– gatt browser: GATT Client - Discover Primary Services.
– gatt counter: GATT Server - Heartbeat Counter over GATT.
– gatt streamer server: Performance - Stream Data over GATT (Server).
– gatt battery query: GATT Battery Service Client.
– gatt device information query: GATT Device Information Service
Client.
– gatt heart rate client: GATT Heart Rate Sensor Client .
– nordic spp le counter: LE Nordic SPP-like Heartbeat Server .
– nordic spp le streamer: LE Nordic SPP-like Streamer Server .
– ublox spp le counter: LE u-blox SPP-like Heartbeat Server.
– sm pairing central: LE Central - Test Pairing Methods.
– sm pairing peripheral: LE Peripheral - Test Pairing Methods.
– le credit based flow control mode client: LE Credit-Based Flow-Control
Mode Client - Send Data over L2CAP.
– le credit based flow control mode server: LE Credit-Based Flow-Control
Mode Server - Receive data over L2CAP.
– att delayed response: LE Peripheral - Delayed Response.
– ancs client demo: LE ANCS Client - Apple Notification Service.
– le mitm: LE Man-in-the-Middle Tool.
• Performance examples:
– le streamer client: Performance - Stream Data over GATT (Client).
– gatt streamer server: Performance - Stream Data over GATT (Server).
– le credit based flow control mode client: LE Credit-Based Flow-Control
Mode Client - Send Data over L2CAP.
– le credit based flow control mode server: LE Credit-Based Flow-Control
Mode Server - Receive data over L2CAP.
– spp streamer client: Performance - Stream Data over SPP (Client).
– spp streamer: Performance - Stream Data over SPP (Server).
• Audio examples:
– a2dp sink demo: A2DP Sink - Receive Audio Stream and Control
Playback.
– a2dp source demo: A2DP Source - Stream Audio and Control Vol-
ume.
– avrcp browsing client: AVRCP Browsing - Browse Media Players
and Media Information.
– hfp ag demo: HFP AG - Audio Gateway.
– hfp hf demo: HFP HF - Hands-Free.
– hsp ag demo: HSP AG - Audio Gateway.
73
// i n c r e m e n t c o u n t e r
c o u n t e r ++;
// p r i n t and l o g
74
// t o g g l e LED
hal led toggle () ;
// re−r e g i s t e r t i m e r
b t s t a c k r u n l o o p s e t t i m e r (& h e a r t b e a t , HEARTBEAT PERIOD MS) ;
b t s t a c k r u n l o o p a d d t i m e r (& h e a r t b e a t ) ;
}
0.51.2. Main Application Setup. Listing here shows main application code. It
configures the heartbeat tier and adds it to the run loop.
// s e t one−s h o t t i m e r
h e a r t b e a t . p r o c e s s = &h e a r t b e a t h a n d l e r ;
b t s t a c k r u n l o o p s e t t i m e r (& h e a r t b e a t , HEARTBEAT PERIOD MS) ;
b t s t a c k r u n l o o p a d d t i m e r (& h e a r t b e a t ) ;
p r i n t f ( ” Running . . . \ n\ r ” ) ;
return 0 ;
}
• Inquiry complete event: the remote name is requested for devices with-
out a fetched name. The state of a remote name can be one of the fol-
lowing: REMOTE NAME REQUEST, REMOTE NAME INQUIRED,
or REMOTE NAME FETCHED.
• Remote name request complete event: the remote name is stored in the
table and the state is updated to REMOTE NAME FETCHED. The
query of remote names is continued.
For more details on discovering remote devices, please see Section on
GAP.
0.52.2. Main Application Setup. Listing here shows main application code. It
registers the HCI packet handler and starts the Bluetooth stack.
// e n a b l e d EIR
h c i s e t i n q u i r y m o d e (INQUIRY MODE RSSI AND EIR) ;
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
// t u r n on !
h c i p o w e r c o n t r o l (HCI POWER ON) ;
return 0 ;
}
0.53. GAP Link Key Management (Classic). Source Code: gap link keys.c
Shows how to iterate over the Classic Link Keys stored in NVS Link Keys are
per device-device bonding. If the Bluetooth Controller can be swapped, e.g. on
desktop systems, a Link Key DB for each Controller is needed. We need to wait
until the Bluetooth Stack has started up and selected the correct Link Key DB
based on the Controller’s BD ADDR.
0.53.1. GAP Link Key Logic. List stored link keys
0.53.2. Bluetooth Logic. Wait for Bluetooth startup before listing the stored link
keys
0.53.3. Main Application Setup. Listing here shows main application code. It
registers the HCI packet handler and starts the Bluetooth stack.
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
// t u r n on !
h c i p o w e r c o n t r o l (HCI POWER ON) ;
return 0 ;
}
s t a t i c void g a p l e a d v e r t i s e m e n t s s e t u p ( void ) {
// A c t i v e scanning , 100% ( scan i n t e r v a l = scan window )
gap set scan parameters (1 ,48 ,48) ;
gap start scan () ;
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
}
0.54.2. GAP LE Advertising Data Dumper. Here, we use the definition of ad-
vertising data types and flags as specified in Assigned Numbers GAP and Sup-
plement to the Bluetooth Core Specification, v4.
s t a t i c const char ∗ a d t y p e s [ ] = {
”” ,
” Flags ” ,
” I n c o m p l e t e L i s t o f 16− b i t S e r v i c e C l a s s UUIDs” ,
” Complete L i s t o f 16− b i t S e r v i c e C l a s s UUIDs” ,
” I n c o m p l e t e L i s t o f 32− b i t S e r v i c e C l a s s UUIDs” ,
” Complete L i s t o f 32− b i t S e r v i c e C l a s s UUIDs” ,
” I n c o m p l e t e L i s t o f 128− b i t S e r v i c e C l a s s UUIDs” ,
” Complete L i s t o f 128− b i t S e r v i c e C l a s s UUIDs” ,
” S h o r t e n e d L o c a l Name” ,
” Complete L o c a l Name” ,
”Tx Power L e v e l ” ,
”” ,
”” ,
” C l a s s o f D e vi ce ” ,
77
” Simple P a i r i n g Hash C” ,
” Simple P a i r i n g Randomizer R” ,
” De vi c e ID” ,
” S e c u r i t y Manager TK Value ” ,
” S l a v e Connection I n t e r v a l Range” ,
”” ,
” L i s t o f 16− b i t S e r v i c e S o l i c i t a t i o n UUIDs” ,
” L i s t o f 128− b i t S e r v i c e S o l i c i t a t i o n UUIDs” ,
” S e r v i c e Data” ,
” P u b l i c Target Address ” ,
”Random Target Address ” ,
” Appearance ” ,
” Advertising Interval ”
};
s t a t i c const char ∗ f l a g s [ ] = {
”LE L im i te d D i s c o v e r a b l e Mode” ,
”LE G e n e r a l D i s c o v e r a b l e Mode” ,
”BR/EDR Not Supported ” ,
” S i m u l t a n e o u s LE and BR/EDR t o Same De v ic e Capable ( C o n t r o l l e r ) ” ,
” S i m u l t a n e o u s LE and BR/EDR t o Same De v ic e Capable ( Host ) ” ,
” Reserved ” ,
” Reserved ” ,
” Reserved ”
};
BTstack offers an iterator for parsing sequence of advertising data (AD) struc-
tures, see BLE advertisements parser API. After initializing the iterator, each
AD structure is dumped according to its type.
switch ( d a t a t y p e ) {
case BLUETOOTH DATA TYPE FLAGS:
// show o n l y f i r s t o c t e t , i g n o r e r e s t
f o r ( i =0; i <8; i ++){
i f ( data [ 0 ] & (1<< i ) ) {
78
p r i n t f ( ”%s ; ” , f l a g s [ i ] ) ;
}
}
break ;
case
BLUETOOTH DATA TYPE INCOMPLETE LIST OF 16 BIT SERVICE CLASS UUIDS
:
case
BLUETOOTH DATA TYPE COMPLETE LIST OF 16 BIT SERVICE CLASS UUIDS
:
case
BLUETOOTH DATA TYPE LIST OF 16 BIT SERVICE SOLICITATION UUIDS
:
f o r ( i =0; i <s i z e ; i +=2){
p r i n t f ( ”%02X ” , l i t t l e e n d i a n r e a d 1 6 ( data , i ) ) ;
}
break ;
case
BLUETOOTH DATA TYPE INCOMPLETE LIST OF 32 BIT SERVICE CLASS UUIDS
:
case
BLUETOOTH DATA TYPE COMPLETE LIST OF 32 BIT SERVICE CLASS UUIDS
:
case
BLUETOOTH DATA TYPE LIST OF 32 BIT SERVICE SOLICITATION UUIDS
:
f o r ( i =0; i <s i z e ; i +=4){
p r i n t f ( ”%04”PRIX32 , l i t t l e e n d i a n r e a d 3 2 ( data , i ) ) ;
}
break ;
case
BLUETOOTH DATA TYPE INCOMPLETE LIST OF 128 BIT SERVICE CLASS UUIDS
:
case
BLUETOOTH DATA TYPE COMPLETE LIST OF 128 BIT SERVICE CLASS UUIDS
:
case
BLUETOOTH DATA TYPE LIST OF 128 BIT SERVICE SOLICITATION UUIDS
:
r e v e r s e 1 2 8 ( data , u u i d 1 2 8 ) ;
p r i n t f ( ”%s ” , u u i d 1 2 8 t o s t r ( u u i d 1 2 8 ) ) ;
break ;
case BLUETOOTH DATA TYPE SHORTENED LOCAL NAME:
case BLUETOOTH DATA TYPE COMPLETE LOCAL NAME:
f o r ( i =0; i <s i z e ; i ++){
p r i n t f ( ”%c ” , ( char ) ( data [ i ] ) ) ;
}
break ;
case BLUETOOTH DATA TYPE TX POWER LEVEL:
p r i n t f ( ”%d dBm” , ∗ ( i n t 8 t ∗ ) data ) ;
break ;
case BLUETOOTH DATA TYPE SLAVE CONNECTION INTERVAL RANGE:
79
0.54.3. HCI packet handler. The HCI packet handler has to start the scanning,
and to handle received advertisements. Advertisements are received as HCI event
packets of the GAP EVENT ADVERTISING REPORT type, see Listing here.
bd addr t a d d r e s s ;
uint8 t a d d r e s s t y p e ;
uint8 t e v e n t t y p e ;
int8 t rssi ;
uint8 t l e n g t h ;
const uint8 t ∗ data ;
switch ( h c i e v e n t p a c k e t g e t t y p e ( p a c k e t ) ) {
case GAP EVENT ADVERTISING REPORT :
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 ( packet , a d d r e s s ) ;
event type =
gap event advertising report get advertising event type (
packet ) ;
address type = gap event advertising report get address type (
packet ) ;
r s s i = 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 r s s i ( packet ) ;
length = 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 d a t a l e n g t h ( packet ) ;
data = 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 d a t a ( p a c k e t ) ;
p r i n t f ( ” A d v e r t i s e m e n t ( l e g a c y ) e v e n t : evt−type %u , addr−type %
u , addr %s , r s s i %d , data [%u ] ” , e v e n t t y p e ,
address type , bd addr to str ( address ) , r s s i , length ) ;
p r i n t f h e x d u m p ( data , l e n g t h ) ;
d u m p a d v e r t i s e m e n t d a t a ( data , l e n g t h ) ;
break ;
#i f d e f ENABLE LE EXTENDED ADVERTISING
case GAP EVENT EXTENDED ADVERTISING REPORT:
g a p e v e n t e x t e n d e d 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 ( packet ,
address ) ;
event type =
gap event extended advertising report get advertising event type
( packet ) ;
address type =
gap event extended advertising report get address type (
packet ) ;
r s s i = g a p e v e n t e x t e n d e d a d v e r t i s i n g r e p o r t g e t r s s i ( packet ) ;
length = gap event extended advertising report get data length
( packet ) ;
data = g a p e v e n t e x t e n d e d a d v e r t i s i n g r e p o r t g e t d a t a ( p a c k e t ) ;
p r i n t f ( ” A d v e r t i s e m e n t ( extended ) e v e n t : evt−type %u , addr−type
%u , addr %s , r s s i %d , data [%u ] ” , e v e n t t y p e ,
address type , bd addr to str ( address ) , r s s i , length ) ;
p r i n t f h e x d u m p ( data , l e n g t h ) ;
d u m p a d v e r t i s e m e n t d a t a ( data , l e n g t h ) ;
break ;
#endif
default :
break ;
}
}
0.55. GATT Client - Discover Primary Services. Source Code: gatt browser.c
81
This example shows how to use the GATT Client API to discover primary
services and their characteristics of the first found device that is advertising its
services.
The logic is divided between the HCI and GATT client packet handlers. The
HCI packet handler is responsible for finding a remote device, connecting to it,
and for starting the first GATT client query. Then, the GATT client packet
handler receives all primary services and requests the characteristics of the last
one to keep the example short.
0.55.1. GATT client setup. In the setup phase, a GATT client must register the
HCI and GATT client packet handlers, as shown in Listing here. Additionally,
the security manager can be setup, if signed writes, or encrypted, or authen-
ticated connection are required, to access the characteristics, as explained in
Section on SMP.
s t a t i c void g a t t c l i e n t s e t u p ( void ) {
// I n i t i a l i z e GATT c l i e n t
g a t t c l i e n t i n i t () ;
// O p t i n o a l l y , Se t up s e c u r i t y manager
sm init () ;
s m s e t i o c a p a b i l i t i e s (IO CAPABILITY NO INPUT NO OUTPUT) ;
// r e g i s t e r f o r HCI e v e n t s
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &h a n d l e h c i e v e n t ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
}
0.55.2. HCI packet handler. The HCI packet handler has to start the scanning,
to find the first advertising device, to stop scanning, to connect to and later to dis-
connect from it, to start the GATT client upon the connection is completed, and
to send the first query - in this case the gatt client discover primary services()
is called, see Listing here.
82
uint8 t e v e n t = h c i e v e n t p a c k e t g e t t y p e ( p a c k e t ) ;
switch ( e v e n t ) {
case BTSTACK EVENT STATE:
// BTstack a c t i v a t e d , g e t s t a r t e d
i f ( b t s t a c k e v e n t s t a t e g e t s t a t e ( p a c k e t ) != HCI STATE WORKING
) break ;
i f ( cmdline addr found ) {
p r i n t f ( ” Trying t o c o n n e c t t o %s \n” , b d a d d r t o s t r (
cmdline addr ) ) ;
gap connect ( cmdline addr , 0) ;
break ;
}
p r i n t f ( ” BTstack a c t i v a t e d , s t a r t s c a n n i n g ! \ n” ) ;
g a p s e t s c a n p a r a m e t e r s ( 0 , 0 x0030 , 0 x0030 ) ;
gap start scan () ;
break ;
case GAP EVENT ADVERTISING REPORT :
f i l l a d v e r t i s i n g r e p o r t f r o m p a c k e t (& r e p o r t , p a c k e t ) ;
d u m p a d v e r t i s i n g r e p o r t (& r e p o r t ) ;
// s t o p scanning , and c o n n e c t t o t h e d e v i c e
gap stop scan () ;
gap connect ( report . address , report . address type ) ;
break ;
case HCI EVENT META GAP :
// w a i t f o r c o n n e c t i o n c o m p l e t e
i f ( h c i e v e n t g a p m e t a g e t s u b e v e n t c o d e ( p a c k e t ) !=
GAP SUBEVENT LE CONNECTION COMPLETE) break ;
p r i n t f ( ” \nGATT b r o w s e r − CONNECTED\n” ) ;
connection handle =
gap subevent le connection complete get connection handle (
packet ) ;
// q u e r y primary s e r v i c e s
gatt client discover primary services ( handle gatt client event
, connection handle ) ;
break ;
case HCI EVENT DISCONNECTION COMPLETE :
p r i n t f ( ” \nGATT b r o w s e r − DISCONNECTED\n” ) ;
break ;
default :
break ;
}
}
83
0.55.3. GATT Client event handler. Query results and further queries are han-
dled by the GATT client packet handler, as shown in Listing here. Here, upon re-
ceiving the primary services, the gatt client discover characteristics for service()
query for the last received service is sent. After receiving the characteristics for
the service, gap disconnect is called to terminate the connection. Upon discon-
nect, the HCI packet handler receives the disconnect complete event.
0.56. GATT Server - Heartbeat Counter over GATT. Source Code: gatt counter.c
All newer operating systems provide GATT Client functionality. The LE
Counter examples demonstrates how to specify a minimal GATT Database with
a custom GATT Service and a custom Characteristic that sends periodic notifi-
cations.
84
0.56.1. Main Application Setup. Listing here shows main application code. It
initializes L2CAP, the Security Manager and configures the ATT Server with
the pre-compiled ATT Database generated from lec ounter.gatt. Additionally,
it enables the Battery Service Server with the current battery level. Finally, it
configures the advertisements and the heartbeat handler and boots the Bluetooth
stack. In this example, the Advertisement contains the Flags attribute and
the device name. The flag 0x06 indicates: LE General Discoverable Mode and
BR/EDR not supported.
static int l e n o t i f i c a t i o n e n a b l e d ;
static btstack timer source t h e a r t b e a t ;
static btstack packet callback registration t
hci event callback registration ;
static hci con handle t con handle ;
static uint8 t b a t t e r y = 1 0 0 ;
const uint8 t a d v d a t a [ ] = {
// F l a g s g e n e r a l d i s c o v e r a b l e
0 x02 , BLUETOOTH DATA TYPE FLAGS, APP AD FLAGS,
// Name
0x0b , BLUETOOTH DATA TYPE COMPLETE LOCAL NAME, ’L ’ , ’E ’ , ’ ’ , ’C ’ ,
’o ’ , ’u ’ , ’n ’ , ’ t ’ , ’ e ’ , ’ r ’ ,
// I n c o m p l e t e L i s t o f 16− b i t S e r v i c e C l a s s UUIDs −− FF10 − o n l y
valid for testing !
0 x03 ,
BLUETOOTH DATA TYPE INCOMPLETE LIST OF 16 BIT SERVICE CLASS UUIDS
, 0 x10 , 0 x f f ,
};
const uint8 t a d v d a t a l e n = s i z e o f ( a d v d a t a ) ;
85
s t a t i c void l e c o u n t e r s e t u p ( void ) {
l2cap init () ;
// s e t u p SM: D i s p l a y o n l y
sm init () ;
// c o n f i g u r e C l a s s i c GAP
g a p s e t l o c a l n a m e ( ”GATT Counter BR/EDR 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 ” ) ;
g a p s s p s e t i o c a p a b i l i t y ( SSP IO CAPABILITY DISPLAY YES NO ) ;
gap discoverable control (1) ;
#endif
// s e t u p ATT s e r v e r
att server init ( profile data , att read callback ,
att write callback ) ;
// s e t u p b a t t e r y s e r v i c e
b a t t e r y s e r v i c e s e r v e r i n i t ( battery ) ;
// s e t u p a d v e r t i s e m e n t s
uint16 t a d v i n t m i n = 0 x0030 ;
uint16 t a d v i n t m a x = 0 x0030 ;
uint8 t a d v t y p e = 0 ;
bd addr t n u l l a d d r ;
memset ( n u l l a d d r , 0 , 6 ) ;
g a p a d v e r t i s e m e n t s s e t p a r a m s ( a d v i n t m i n , adv int max , adv type ,
0 , n u l l a d d r , 0 x07 , 0 x00 ) ;
g a p a d v e r t i s e m e n t s s e t d a t a ( a d v d a t a l e n , ( uint8 t ∗ ) a d v d a t a ) ;
gap advertisements enable (1) ;
// r e g i s t e r f o r HCI e v e n t s
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
// r e g i s t e r f o r ATT e v e n t
att se rver re giste r pac ket han dler ( packet handler ) ;
// s e t one−s h o t t i m e r
h e a r t b e a t . p r o c e s s = &h e a r t b e a t h a n d l e r ;
b t s t a c k r u n l o o p s e t t i m e r (& h e a r t b e a t , HEARTBEAT PERIOD MS) ;
86
b t s t a c k r u n l o o p a d d t i m e r (& h e a r t b e a t ) ;
// b e a t once
beat ( ) ;
}
0.56.2. Heartbeat Handler. The heartbeat handler updates the value of the single
Characteristic provided in this example, and request a ATT EVENT CAN SEND NOW
to send a notification if enabled see Listing here.
s t a t i c int c o u n t e r = 0 ;
s t a t i c char c o u n t e r s t r i n g [ 3 0 ] ;
s t a t i c int c o u n t e r s t r i n g l e n ;
s t a t i c void b e a t ( void ) {
c o u n t e r ++;
counter string len = snprintf ( counter string , sizeof (
c o u n t e r s t r i n g ) , ” BTstack c o u n t e r %04u” , c o u n t e r ) ;
puts ( c o u n t e r s t r i n g ) ;
}
s t a t i c void h e a r t b e a t h a n d l e r ( struct b t s t a c k t i m e r s o u r c e ∗ t s ) {
if ( le notification enabled ) {
beat ( ) ;
att server request can send now event ( con handle ) ;
}
// s i m u l a t e b a t t e r y d r a i n
b a t t e r y −−;
i f ( battery < 50) {
battery = 100;
}
b a t t e r y s e r v i c e s e r v e r s e t b a t t e r y v a l u e ( battery ) ;
switch ( h c i e v e n t p a c k e t g e t t y p e ( p a c k e t ) ) {
case HCI EVENT DISCONNECTION COMPLETE :
le notification enabled = 0;
break ;
case ATT EVENT CAN SEND NOW:
a t t s e r v e r n o t i f y ( con handle ,
ATT CHARACTERISTIC 0000FF11 0000 1000 8000 00805F9B34FB 01 VALUE HANDLE
, ( uint8 t ∗ ) c o u n t e r s t r i n g , c o u n t e r s t r i n g l e n ) ;
break ;
default :
break ;
}
}
0.56.4. ATT Read. The ATT Server handles all reads to constant data. For
dynamic data like the custom characteristic, the registered att read callback is
called. To handle long characteristics and long reads, the att read callback is
first called with buffer == NULL, to request the total value length. Then it will
be called again requesting a chunk of the value. See Listing here.
i f ( a t t h a n d l e ==
ATT CHARACTERISTIC 0000FF11 0000 1000 8000 00805F9B34FB 01 VALUE HANDLE
){
return a t t r e a d c a l l b a c k h a n d l e b l o b ( ( const uint8 t ∗ )
counter string , counter string len , offset , buffer ,
buffer size ) ;
}
return 0 ;
}
0.56.5. ATT Write. The only valid ATT writes in this example are to the Client
Characteristic Configuration, which configures notification and indication and to
the the Characteristic Value. If the ATT handle matches the client configuration
handle, the new configuration value is stored and used in the heartbeat handler to
decide if a new value should be sent. If the ATT handle matches the characteristic
value handle, we print the write as hexdump See Listing here.
88
s t a t i c int a t t w r i t e c a l l b a c k ( h c i c o n h a n d l e t c o n n e c t i o n h a n d l e ,
uint16 t a t t h a n d l e , uint16 t t r a n s a c t i o n m o d e , uint16 t o f f s e t ,
uint8 t ∗ b u f f e r , uint16 t b u f f e r s i z e ) {
switch ( a t t h a n d l e ) {
case
ATT CHARACTERISTIC 0000FF11 0000 1000 8000 00805F9B34FB 01 CLIENT CONFIGURATIO
:
l e n o t i f i c a t i o n e n a b l e d = l i t t l e e n d i a n r e a d 1 6 ( b u f f e r , 0 ) ==
GATT CLIENT CHARACTERISTICS CONFIGURATION NOTIFICATION ;
con handle = connection handle ;
break ;
case
ATT CHARACTERISTIC 0000FF11 0000 1000 8000 00805F9B34FB 01 VALUE HANDLE
:
p r i n t f ( ” Write : t r a n s a c t i o n mode %u , o f f s e t %u , data (%u b y t e s )
: ” , transaction mode , o f f s e t , b u f f e r s i z e ) ;
printf hexdump ( buffer , b u f f e r s i z e ) ;
break ;
default :
break ;
}
return 0 ;
}
s t a t i c void l e s t r e a m e r s e t u p ( void ) {
l2cap init () ;
// s e t u p SM: D i s p l a y o n l y
sm init () ;
sdp init () ;
memset ( g a t t s e r v i c e b u f f e r , 0 , s i z e o f ( g a t t s e r v i c e b u f f e r ) ) ;
g a t t c r e a t e s d p r e c o r d ( g a t t s e r v i c e b u f f e r , 0 x10001 ,
ATT SERVICE GATT SERVICE START HANDLE,
ATT SERVICE GATT SERVICE END HANDLE) ;
sdp register service ( gatt service buffer ) ;
p r i n t f ( ”SDP s e r v i c e r e c o r d s i z e : %u\n” , d e g e t l e n (
gatt service buffer )) ;
// c o n f i g u r e C l a s s i c GAP
g a p s e t l o c a l n a m e ( ”GATT Streamer BR/EDR 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 ” ) ;
g a p s s p s e t i o c a p a b i l i t y ( SSP IO CAPABILITY DISPLAY YES NO ) ;
gap discoverable control (1) ;
#endif
// s e t u p ATT s e r v e r
a t t s e r v e r i n i t ( p r o f i l e d a t a , NULL, a t t w r i t e c a l l b a c k ) ;
// r e g i s t e r f o r HCI e v e n t s
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &h c i p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
// r e g i s t e r f o r ATT e v e n t s
att server register packet handler ( att packet handler ) ;
// s e t u p a d v e r t i s e m e n t s
uint16 t a d v i n t m i n = 0 x0030 ;
uint16 t a d v i n t m a x = 0 x0030 ;
uint8 t a d v t y p e = 0 ;
bd addr t n u l l a d d r ;
memset ( n u l l a d d r , 0 , 6 ) ;
g a p a d v e r t i s e m e n t s s e t p a r a m s ( a d v i n t m i n , adv int max , adv type ,
0 , n u l l a d d r , 0 x07 , 0 x00 ) ;
g a p a d v e r t i s e m e n t s s e t d a t a ( a d v d a t a l e n , ( uint8 t ∗ ) a d v d a t a ) ;
gap advertisements enable (1) ;
// i n i t c l i e n t s t a t e
init connections () ;
}
s t a t i c void t e s t r e s e t ( l e s t r e a m e r c o n n e c t i o n t ∗ c o n t e x t ) {
c o n t e x t −>t e s t d a t a s t a r t = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
}
s t a t i c void t e s t t r a c k s e n t ( l e s t r e a m e r c o n n e c t i o n t ∗ c o n t e x t , int
bytes sent ){
c o n t e x t −>t e s t d a t a s e n t += b y t e s s e n t ;
90
// e v a l u a t e
uint32 t now = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
uint32 t t i m e p a s s e d = now − c o n t e x t −>t e s t d a t a s t a r t ;
i f ( t i m e p a s s e d < REPORT INTERVAL MS) return ;
// p r i n t s p e e d
int b y t e s p e r s e c o n d = c o n t e x t −>t e s t d a t a s e n t ∗ 1000 /
time passed ;
p r i n t f ( ”%c : %”PRIu32” b y t e s s e n t −> %u.%03u kB/ s \n” , c o n t e x t −>name ,
c o n t e x t −>t e s t d a t a s e n t , b y t e s p e r s e c o n d / 1 0 0 0 ,
b y t e s p e r s e c o n d % 1000) ;
// r e s t a r t
c o n t e x t −>t e s t d a t a s t a r t = now ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
}
0.57.3. HCI Packet Handler. The packet handler is used track incoming connec-
tions and to stop notifications on disconnect It is also a good place to request
the connection parameter update as indicated in the commented code block.
uint16 t c o n n i n t e r v a l ;
hci con handle t con handle ;
s t a t i c const char ∗ const phy names [ ] = {
” Reserved ” , ” 1 M” , ” 2 M” , ” Codec ”
};
switch ( h c i e v e n t p a c k e t g e t t y p e ( packet ) ) {
case BTSTACK EVENT STATE:
// BTstack a c t i v a t e d , g e t s t a r t e d
if ( b t s t a c k e v e n t s t a t e g e t s t a t e ( p a c k e t ) == HCI STATE WORKING
) {
p r i n t f ( ”To s t a r t t h e s t r e a m i n g , p l e a s e run t h e
l e s t r e a m e r c l i e n t example on o t h e r d e v i c e , o r u s e some
GATT E x p l o r e r , e . g . LightBlue , BLExplr . \ n” ) ;
}
break ;
case HCI EVENT DISCONNECTION COMPLETE :
con handle =
hci event disconnection complete get connection handle (
packet ) ;
p r i n t f ( ”− LE Connection 0x%04x : d i s c o n n e c t , r e a s o n %02x\n” ,
con handle , h c i e v e n t d i s c o n n e c t i o n c o m p l e t e g e t r e a s o n (
packet ) ) ;
break ;
case HCI EVENT META GAP :
91
switch ( h c i e v e n t g a p m e t a g e t s u b e v e n t c o d e ( p a c k e t ) ) {
case GAP SUBEVENT LE CONNECTION COMPLETE:
// p r i n t c o n n e c t i o n p a r a m e t e r s ( w i t h o u t u s i n g f l o a t
operations )
con handle =
gap subevent le connection complete get connection handle
( packet ) ;
conn interval =
gap subevent le connection complete get conn interval (
packet ) ;
p r i n t f ( ”− LE Connection 0x%04x : c o n n e c t e d − c o n n e c t i o n
i n t e r v a l %u.%02u ms , l a t e n c y %u\n” , c o n h a n d l e ,
c o n n i n t e r v a l ∗ 125 / 1 0 0 ,
25 ∗ ( c o n n i n t e r v a l & 3 ) ,
gap subevent le connection complete get conn latency
( packet ) ) ;
default :
break ;
}
}
0.57.4. ATT Packet Handler. The packet handler is used to track the ATT MTU
Exchange and trigger ATT send
int mtu ;
le streamer connection t ∗ context ;
switch ( p a c k e t t y p e ) {
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 ( p a c k e t ) ) {
case ATT EVENT CONNECTED:
// s e t u p new
context = connection for conn handle (
HCI CON HANDLE INVALID) ;
i f ( ! c o n t e x t ) break ;
c o n t e x t −>c o u n t e r = ’A ’ ;
c o n t e x t −>c o n n e c t i o n h a n d l e =
a t t e v e n t c o n n e c t e d g e t h a n d l e ( packet ) ;
c o n t e x t −>t e s t d a t a l e n = b t s t a c k m i n ( a t t s e r v e r g e t m t u (
c o n t e x t −>c o n n e c t i o n h a n d l e ) − 3 , s i z e o f ( c o n t e x t −>
test data ) ) ;
p r i n t f ( ”%c : ATT connected , h a n d l e 0x%04x , t e s t data l e n %u
\n” , c o n t e x t −>name , c o n t e x t −>c o n n e c t i o n h a n d l e ,
c o n t e x t −>t e s t d a t a l e n ) ;
break ;
case ATT EVENT MTU EXCHANGE COMPLETE:
mtu = a t t e v e n t m t u e x c h a n g e c o m p l e t e g e t M T U ( p a c k e t ) − 3 ;
context = connection for conn handle (
att event mtu exchange complete get handle ( packet ) ) ;
93
i f ( ! c o n t e x t ) break ;
c o n t e x t −>t e s t d a t a l e n = b t s t a c k m i n ( mtu − 3 , s i z e o f (
c o n t e x t −>t e s t d a t a ) ) ;
p r i n t f ( ”%c : ATT MTU = %u => u s e t e s t data o f l e n %u\n” ,
c o n t e x t −>name , mtu , c o n t e x t −>t e s t d a t a l e n ) ;
break ;
case ATT EVENT CAN SEND NOW:
streamer () ;
break ;
case ATT EVENT DISCONNECTED:
context = connection for conn handle (
a t t e v e n t d i s c o n n e c t e d g e t h a n d l e ( packet ) ) ;
i f ( ! c o n t e x t ) break ;
// f r e e c o n n e c t i o n
p r i n t f ( ”%c : ATT d i s c o n n e c t e d , h a n d l e 0x%04x\n” , c o n t e x t −>
name , c o n t e x t −>c o n n e c t i o n h a n d l e ) ;
c o n t e x t −>l e n o t i f i c a t i o n e n a b l e d = 0 ;
c o n t e x t −>c o n n e c t i o n h a n d l e = HCI CON HANDLE INVALID ;
break ;
default :
break ;
}
break ;
default :
break ;
}
}
0.57.5. Streamer. The streamer function checks if notifications are enabled and
if a notification can be sent now. It creates some test data - a single letter that
gets increased every time - and tracks the data sent.
s t a t i c void s t r e a m e r ( void ) {
// f i n d n e x t a c t i v e s t r e a m i n g c o n n e c t i o n
int o l d c o n n e c t i o n i n d e x = c o n n e c t i o n i n d e x ;
while ( 1 ) {
// a c t i v e found ?
i f (( le streamer connections [ connection index ] . connection handle
!= HCI CON HANDLE INVALID) &&
( le streamer connections [ connection index ] .
l e n o t i f i c a t i o n e n a b l e d ) ) break ;
// c h e c k n e x t
next connection index () ;
// none found
i f ( c o n n e c t i o n i n d e x == o l d c o n n e c t i o n i n d e x ) return ;
}
l e s t r e a m e r c o n n e c t i o n t ∗ c o n t e x t = &l e s t r e a m e r c o n n e c t i o n s [
connection index ] ;
94
// c r e a t e t e s t d a t a
c o n t e x t −>c o u n t e r ++;
i f ( c o n t e x t −>c o u n t e r > ’ Z ’ ) c o n t e x t −>c o u n t e r = ’A ’ ;
memset ( c o n t e x t −>t e s t d a t a , c o n t e x t −>c o u n t e r , c o n t e x t −>
test data len ) ;
// send
a t t s e r v e r n o t i f y ( c o n t e x t −>c o n n e c t i o n h a n d l e , c o n t e x t −>
v a l u e h a n d l e , ( uint8 t ∗ ) c o n t e x t −>t e s t d a t a , c o n t e x t −>
test data len ) ;
// t r a c k
t e s t t r a c k s e n t ( c o n t e x t , c o n t e x t −>t e s t d a t a l e n ) ;
// r e q u e s t n e x t send e v e n t
a t t s e r v e r r e q u e s t c a n s e n d n o w e v e n t ( c o n t e x t −>c o n n e c t i o n h a n d l e ) ;
// c h e c k n e x t
next connection index () ;
}
0.57.6. ATT Write. The only valid ATT write in this example is to the Client
Characteristic Configuration, which configures notification and indication. If
the ATT handle matches the client configuration handle, the new configuration
value is stored. If notifications get enabled, an ATT EVENT CAN SEND NOW
is requested. See Listing here.
s t a t i c int a t t w r i t e c a l l b a c k ( h c i c o n h a n d l e t c o n h a n d l e , uint16 t
a t t h a n d l e , uint16 t t r a n s a c t i o n m o d e , uint16 t o f f s e t , uint8 t
∗ b u f f e r , uint16 t b u f f e r s i z e ) {
UNUSED( o f f s e t ) ;
// p r i n t f (” a t t w r i t e c a l l b a c k a t t h a n d l e 0 x%04x , t r a n s a c t i o n mode
%u\n ” , a t t h a n d l e , t r a n s a c t i o n m o d e ) ;
i f ( t r a n s a c t i o n m o d e != ATT TRANSACTION MODE NONE) return 0 ;
le streamer connection t ∗ context = connection for conn handle (
con handle ) ;
switch ( a t t h a n d l e ) {
case
ATT CHARACTERISTIC 0000FF11 0000 1000 8000 00805F9B34FB 01 CLIENT CONFIGURATIO
:
case
ATT CHARACTERISTIC 0000FF12 0000 1000 8000 00805F9B34FB 01 CLIENT CONFIGURATIO
:
c o n t e x t −>l e n o t i f i c a t i o n e n a b l e d = l i t t l e e n d i a n r e a d 1 6 (
b u f f e r , 0 ) ==
GATT CLIENT CHARACTERISTICS CONFIGURATION NOTIFICATION ;
p r i n t f ( ”%c : N o t i f i c a t i o n s e n a b l e d %u\n” , c o n t e x t −>name ,
c o n t e x t −>l e n o t i f i c a t i o n e n a b l e d ) ;
i f ( c o n t e x t −>l e n o t i f i c a t i o n e n a b l e d ) {
95
switch ( a t t h a n d l e ) {
case
ATT CHARACTERISTIC 0000FF11 0000 1000 8000 00805F9B34FB 01 CLIENT CONFIGU
:
c o n t e x t −>v a l u e h a n d l e =
ATT CHARACTERISTIC 0000FF11 0000 1000 8000 00805F9B34FB 01 VALUE HAND
;
break ;
case
ATT CHARACTERISTIC 0000FF12 0000 1000 8000 00805F9B34FB 01 CLIENT CONFIGU
:
c o n t e x t −>v a l u e h a n d l e =
ATT CHARACTERISTIC 0000FF12 0000 1000 8000 00805F9B34FB 01 VALUE HAND
;
break ;
default :
break ;
}
a t t s e r v e r r e q u e s t c a n s e n d n o w e v e n t ( c o n t e x t −>
connection handle ) ;
}
t e s t r e s e t ( context ) ;
break ;
case
ATT CHARACTERISTIC 0000FF11 0000 1000 8000 00805F9B34FB 01 VALUE HANDLE
:
case
ATT CHARACTERISTIC 0000FF12 0000 1000 8000 00805F9B34FB 01 VALUE HANDLE
:
t e s t t r a c k s e n t ( context , b u f f e r s i z e ) ;
break ;
default :
p r i n t f ( ” Write t o 0x%04x , l e n %u\n” , a t t h a n d l e , b u f f e r s i z e ) ;
break ;
}
return 0 ;
}
0.58. GATT Battery Service Client. Source Code: gatt battery query.c
This example demonstrates how to use the GATT Battery Service client to re-
ceive battery level information. The client supports querying of multiple battery
services instances of on the remote device. The example scans for remote devices
and connects to the first found device and starts the battery service client.
0.58.1. Main Application Setup. The Listing here shows how to setup Battery
Service client. Besides calling init() method for each service, you’ll also need to
register HCI packet handler to handle advertisements, as well as connect and
disconect events.
Handling of GATT Battery Service events will be later delegated to a sepparate
packet handler, i.e. gatt client event handler.
@note There are two additional files associated with this client to allow a
remote device to query out GATT database:
96
s t a t i c void b a t t e r y s e r v i c e c l i e n t s e t u p ( void ) {
// I n i t L2CAP
l2cap init () ;
// GATT C l i e n t s e t u p
g a t t c l i e n t i n i t () ;
// D e v ic e I n f o r m a t i o n S e r v i c e C l i e n t s e t u p
battery service client init () ;
sm init () ;
s m s e t i o c a p a b i l i t i e s (IO CAPABILITY NO INPUT NO OUTPUT) ;
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &h c i e v e n t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
}
switch ( h c i e v e n t p a c k e t g e t t y p e ( packet ) ) {
...
case HCI EVENT META GAP :
// Wait f o r c o n n e c t i o n c o m p l e t e
if ( h c i e v e n t g a p m e t a g e t s u b e v e n t c o d e ( p a c k e t ) !=
GAP SUBEVENT LE CONNECTION COMPLETE) break ;
...
// Get c o n n e c t i o n h a n d l e from e v e n t
connection handle =
gap subevent le connection complete get connection handle (
packet ) ;
97
// Connect t o remote B a t t e r y S e r v i c e .
// On s u c c e s f u l c o n n e c t i o n , t h e c l i e n t t r i e s t o r e g i s t e r f o r
notifications . If notifications
// a r e not s u p p o r t e d by remote B a t t e r y S e r v i c e , t h e c l i e n t
w i l l automatically p o l l the b a t t e r y l e v e l − here every 2
seconds .
// I f p o l l i n t e r v a l m s i s 0 , p o l l i n g i s d i s a b l e d , and o n l y
n o t i f i c a t i o n s w i l l be r e c e i v e d ( f o r manual p o l l i n g ,
// s e e b a t t e r y s e r v i c e c l i e n t . h ) .
// A l l GATT B a t t e r y S e r v i c e e v e n t s a r e h a n d l e d by t h e
gatt client event handler .
( void ) b a t t e r y s e r v i c e c l i e n t c o n n e c t ( c o n n e c t i o n h a n d l e ,
g a t t c l i e n t e v e n t h a n d l e r , 2 0 0 0 , &b a t t e r y s e r v i c e c i d ) ;
...
p r i n t f ( ” D i s c o n n e c t e d %s \n” , b d a d d r t o s t r ( r e p o r t . a d d r e s s ) ) ;
p r i n t f ( ” R e s t a r t s c a n . \ n” ) ;
a p p s t a t e = APP STATE W4 SCAN RESULT ;
gap start scan () ;
break ;
default :
break ;
}
}
// The g a t t c l i e n t e v e n t h a n d l e r r e c e i v e s f o l l o w i n g e v e n t s from
remote d e v i c e :
// − GATTSERVICE SUBEVENT BATTERY SERVICE CONNECTED
// − GATTSERVICE SUBEVENT BATTERY SERVICE LEVEL
//
s t a t i c void g a t t c l i e n t e v e n t h a n d l e r ( uint8 t p a c k e t t y p e , uint16 t
channel , uint8 t ∗ packet , uint16 t s i z e ) {
...
uint8 t s t a t u s ;
uint8 t a t t s t a t u s ;
i f ( h c i e v e n t p a c k e t g e t t y p e ( p a c k e t ) !=
HCI EVENT GATTSERVICE META) {
return ;
}
switch ( h c i e v e n t g a t t s e r v i c e m e t a g e t s u b e v e n t c o d e ( p a c k e t ) ) {
case GATTSERVICE SUBEVENT BATTERY SERVICE CONNECTED:
98
status =
gattservice subevent battery service connected get status (
packet ) ;
switch ( s t a t u s ) {
case ERROR CODE SUCCESS :
p r i n t f ( ” B a t t e r y s e r v i c e c l i e n t connected , found %d
s e r v i c e s , p o l l bitmap 0x%02x\n” ,
gattservice subevent battery service connected get num instances
( packet ) ,
gattservice subevent battery service connected get poll bitmap
( packet ) ) ;
battery service client read battery level (
b a t t e r y s e r v i c e c i d , 0) ;
break ;
default :
p r i n t f ( ” Battery s e r v i c e c l i e n t connection f a i l e d , s t a t u s 0
x%02x . \ n” , s t a t u s ) ;
a d d t o b l a c k l i s t ( report . address ) ;
gap disconnect ( connection handle ) ;
break ;
}
break ;
}
break ;
default :
break ;
}
}
0.59. GATT Device Information Service Client. Source Code: gatt device information query.
This example demonstrates how to use the GATT Device Information Service
client to receive device information such as various IDs and revisions. The exam-
ple scans for remote devices and connects to the first found device. If the remote
device provides a Device Information Service, the information is collected and
printed in console output, otherwise, the device will be blacklisted and the scan
restarted.
99
0.59.1. Main Application Setup. The Listing here shows how to setup Device
Information Service client. Besides calling init() method for each service, you’ll
also need to register HCI packet handler to handle advertisements, as well as
connect and disconect events.
Handling of GATT Device Information Service events will be later delegated
to a sepparate packet handler, i.e. gatt client event handler.
@note There are two additional files associated with this client to allow a
remote device to query out GATT database:
• gatt device information query.gatt - contains the declaration of the pro-
vided GATT Services and Characteristics.
• gatt device information query.h - contains the binary representation of
gatt device information query.gatt.
s t a t i c void d e v i c e i n f o r m a t i o n s e r v i c e c l i e n t s e t u p ( void ) {
// I n i t L2CAP
l2cap init () ;
// GATT C l i e n t s e t u p
g a t t c l i e n t i n i t () ;
// D e v ic e I n f o r m a t i o n S e r v i c e C l i e n t s e t u p
device information service client init () ;
sm init () ;
s m s e t i o c a p a b i l i t i e s (IO CAPABILITY NO INPUT NO OUTPUT) ;
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &h c i p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
}
...
// g e t c o n n e c t i o n h a n d l e from e v e n t
100
connection handle =
gap subevent le connection complete get connection handle (
packet ) ;
p r i n t f ( ” De v ic e I n f o r m a t i o n c o n n e c t e d . \ n” ) ;
i f ( h c i e v e n t p a c k e t g e t t y p e ( p a c k e t ) !=
HCI EVENT GATTSERVICE META) {
return ;
}
switch ( h c i e v e n t g a t t s e r v i c e m e t a g e t s u b e v e n t c o d e ( p a c k e t ) ) {
case GATTSERVICE SUBEVENT DEVICE INFORMATION MANUFACTURER NAME:
att status =
gattservice subevent device information manufacturer name get att status
( packet ) ;
i f ( a t t s t a t u s != ATT ERROR SUCCESS) {
p r i n t f ( ” Manufacturer Name r e a d f a i l e d , ATT E r r o r 0x%02x\n” ,
att status ) ;
} else {
p r i n t f ( ” Manufacturer Name : %s \n” ,
gattservice subevent device information manufacturer name get value
( packet ) ) ;
}
break ;
// . . .
...
case GATTSERVICE SUBEVENT DEVICE INFORMATION DONE :
att status =
gattservice subevent device information serial number get att status
( packet ) ;
switch ( a t t s t a t u s ) {
case ERROR CODE UNSUPPORTED FEATURE OR PARAMETER VALUE:
p r i n t f ( ” De v ic e I n f o r m a t i o n s e r v i c e c l i e n t not found . \ n” ) ;
a d d t o b l a c k l i s t ( report . address ) ;
gap disconnect ( connection handle ) ;
break ;
case ATT ERROR SUCCESS :
p r i n t f ( ” Query done \n” ) ;
break ;
default :
101
}
i f ( a t t s t a t u s != ATT ERROR SUCCESS) {
i f ( a t t s t a t u s ==
ERROR CODE UNSUPPORTED FEATURE OR PARAMETER VALUE)
p r i n t f ( ” Query f a i l e d , ATT E r r o r 0x%02x\n” , a t t s t a t u s ) ;
} else {
p r i n t f ( ” Query done \n” ) ;
}
break ;
default :
break ;
}
}
0.60. GATT Heart Rate Sensor Client. Source Code: gatt heart rate client.c
Connects for Heart Rate Sensor and reports measurements.
0.61. LE Nordic SPP-like Heartbeat Server. Source Code: nordic ssp le counter.c
0.61.1. Main Application Setup. Listing here shows main application code. It
initializes L2CAP, the Security Manager and configures the ATT Server with
the pre-compiled ATT Database generated from nordics spl ec ounter.gatt. Ad-
ditionally, it enables the Battery Service Server with the current battery level.
Finally, it configures the advertisements and the heartbeat handler and boots
the Bluetooth stack. In this example, the Advertisement contains the Flags at-
tribute and the device name. The flag 0x06 indicates: LE General Discoverable
Mode and BR/EDR not supported.
const uint8 t a d v d a t a [ ] = {
// F l a g s g e n e r a l d i s c o v e r a b l e , BR/EDR not s u p p o r t e d
2 , BLUETOOTH DATA TYPE FLAGS, 0 x06 ,
// Name
8 , BLUETOOTH DATA TYPE COMPLETE LOCAL NAME, ’ n ’ , ’R ’ , ’F ’ , ’ ’ , ’ S ’
, ’P ’ , ’P ’ ,
// UUID . . .
17 ,
BLUETOOTH DATA TYPE COMPLETE LIST OF 128 BIT SERVICE CLASS UUIDS
, 0 x9e , 0 xca , 0 xdc , 0 x24 , 0 xe , 0 xe5 , 0 xa9 , 0 xe0 , 0 x93 , 0 xf3 , 0
xa3 , 0xb5 , 0x1 , 0x0 , 0 x40 , 0 x6e ,
};
const uint8 t a d v d a t a l e n = s i z e o f ( a d v d a t a ) ;
102
0.61.2. Heartbeat Handler. The heartbeat handler updates the value of the single
Characteristic provided in this example, and request a ATT EVENT CAN SEND NOW
to send a notification if enabled see Listing here.
s t a t i c int c o u n t e r = 0 ;
s t a t i c char c o u n t e r s t r i n g [ 3 0 ] ;
s t a t i c int c o u n t e r s t r i n g l e n ;
s t a t i c void b e a t ( void ) {
c o u n t e r ++;
counter string len = snprintf ( counter string , sizeof (
c o u n t e r s t r i n g ) , ” BTstack c o u n t e r %03u” , c o u n t e r ) ;
}
s t a t i c void n o r d i c c a n s e n d ( void ∗ c o n t e x t ) {
UNUSED( c o n t e x t ) ;
p r i n t f ( ”SEND: %s \n” , c o u n t e r s t r i n g ) ;
n o r d i c s p p s e r v i c e s e r v e r s e n d ( c o n h a n d l e , ( uint8 t ∗ )
counter string , counter string len ) ;
}
s t a t i c void h e a r t b e a t h a n d l e r ( struct b t s t a c k t i m e r s o u r c e ∗ t s ) {
i f ( c o n h a n d l e != HCI CON HANDLE INVALID) {
beat ( ) ;
s e n d r e q u e s t . c a l l b a c k = &n o r d i c c a n s e n d ;
n o r d i c s p p s e r v i c e s e r v e r r e q u e s t c a n s e n d n o w (& s e n d r e q u e s t ,
con handle ) ;
}
b t s t a c k r u n l o o p s e t t i m e r ( t s , HEARTBEAT PERIOD MS) ;
btstack run loop add timer ( ts ) ;
}
0.62. LE Nordic SPP-like Streamer Server. Source Code: nordic spp le streamer.c
All newer operating systems provide GATT Client functionality. This example
shows how to get a maximal throughput via BLE:
• send whenever possible,
• use the max ATT MTU.
In theory, we should also update the connection parameters, but we
already get a connection interval of 30 ms and there’s no public way to
use a shorter interval with iOS (if we’re not implementing an HID device).
Note: To start the streaming, run the example. On remote device use
some GATT Explorer, e.g. LightBlue, BLExplr to enable notifications.
s t a t i c void t e s t r e s e t ( n o r d i c s p p l e s t r e a m e r c o n n e c t i o n t ∗ c o n t e x t
){
c o n t e x t −>t e s t d a t a s t a r t = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
}
s t a t i c void t e s t t r a c k s e n t ( n o r d i c s p p l e s t r e a m e r c o n n e c t i o n t ∗
c o n t e x t , int b y t e s s e n t ) {
c o n t e x t −>t e s t d a t a s e n t += b y t e s s e n t ;
// e v a l u a t e
uint32 t now = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
uint32 t t i m e p a s s e d = now − c o n t e x t −>t e s t d a t a s t a r t ;
i f ( t i m e p a s s e d < REPORT INTERVAL MS) return ;
// p r i n t s p e e d
int b y t e s p e r s e c o n d = c o n t e x t −>t e s t d a t a s e n t ∗ 1000 /
time passed ;
p r i n t f ( ”%c : %”PRIu32” b y t e s s e n t −> %u.%03u kB/ s \n” , c o n t e x t −>name ,
c o n t e x t −>t e s t d a t a s e n t , b y t e s p e r s e c o n d / 1 0 0 0 ,
b y t e s p e r s e c o n d % 1000) ;
// r e s t a r t
c o n t e x t −>t e s t d a t a s t a r t = now ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
}
0.62.2. HCI Packet Handler. The packet handler prints the welcome message
and requests a connection paramter update for LE Connections
uint16 t c o n n i n t e r v a l ;
hci con handle t con handle ;
switch ( h c i e v e n t p a c k e t g e t t y p e ( packet ) ) {
case BTSTACK EVENT STATE:
// BTstack a c t i v a t e d , g e t s t a r t e d
if ( b t s t a c k e v e n t s t a t e g e t s t a t e ( p a c k e t ) == HCI STATE WORKING
) {
p r i n t f ( ”To s t a r t t h e s t r e a m i n g , p l e a s e run nRF Toolbox −>
UART t o c o n n e c t . \ n” ) ;
}
break ;
case HCI EVENT META GAP :
switch ( h c i e v e n t g a p m e t a g e t s u b e v e n t c o d e ( p a c k e t ) ) {
case GAP SUBEVENT LE CONNECTION COMPLETE:
// p r i n t c o n n e c t i o n p a r a m e t e r s ( w i t h o u t u s i n g f l o a t
operations )
104
con handle =
gap subevent le connection complete get connection handle
( packet ) ;
conn interval =
gap subevent le connection complete get conn interval (
packet ) ;
p r i n t f ( ”LE Connection − Connection I n t e r v a l : %u.%02u ms\n”
, c o n n i n t e r v a l ∗ 125 / 1 0 0 , 25 ∗ ( c o n n i n t e r v a l & 3 ) )
;
p r i n t f ( ”LE Connection − Connection Latency : %u\n” ,
gap subevent le connection complete get conn latency (
packet ) ) ;
0.62.3. ATT Packet Handler. The packet handler is used to setup and tear down
the spp-over-gatt connection and its MTU
105
int mtu ;
nordic spp le streamer connection t ∗ context ;
switch ( h c i e v e n t p a c k e t g e t t y p e ( p a c k e t ) ) {
case ATT EVENT CONNECTED:
// s e t u p new
c o n t e x t = c o n n e c t i o n f o r c o n n h a n d l e (HCI CON HANDLE INVALID) ;
i f ( ! c o n t e x t ) break ;
c o n t e x t −>c o u n t e r = ’A ’ ;
c o n t e x t −>t e s t d a t a l e n = ATT DEFAULT MTU − 4 ; // −1 f o r
n o r d i c 0 x01 p a c k e t t y p e
c o n t e x t −>c o n n e c t i o n h a n d l e = a t t e v e n t c o n n e c t e d g e t h a n d l e (
packet ) ;
break ;
case ATT EVENT MTU EXCHANGE COMPLETE:
mtu = a t t e v e n t m t u e x c h a n g e c o m p l e t e g e t M T U ( p a c k e t ) − 3 ;
context = connection for conn handle (
att event mtu exchange complete get handle ( packet ) ) ;
i f ( ! c o n t e x t ) break ;
c o n t e x t −>t e s t d a t a l e n = b t s t a c k m i n ( mtu − 3 , s i z e o f ( c o n t e x t −>
test data ) ) ;
p r i n t f ( ”%c : ATT MTU = %u => u s e t e s t data o f l e n %u\n” ,
c o n t e x t −>name , mtu , c o n t e x t −>t e s t d a t a l e n ) ;
break ;
default :
break ;
}
}
0.62.4. Streamer. The streamer function checks if notifications are enabled and
if a notification can be sent now. It creates some test data - a single letter that
gets increased every time - and tracks the data sent.
s t a t i c void n o r d i c c a n s e n d ( void ∗ s o m e c o n t e x t ) {
UNUSED( s o m e c o n t e x t ) ;
// f i n d n e x t a c t i v e s t r e a m i n g c o n n e c t i o n
int o l d c o n n e c t i o n i n d e x = c o n n e c t i o n i n d e x ;
while ( 1 ) {
// a c t i v e found ?
106
// c h e c k n e x t
next connection index () ;
// none found
i f ( c o n n e c t i o n i n d e x == o l d c o n n e c t i o n i n d e x ) return ;
}
// c r e a t e t e s t d a t a
c o n t e x t −>c o u n t e r ++;
i f ( c o n t e x t −>c o u n t e r > ’ Z ’ ) c o n t e x t −>c o u n t e r = ’A ’ ;
memset ( c o n t e x t −>t e s t d a t a , c o n t e x t −>c o u n t e r , c o n t e x t −>
test data len ) ;
// send
n o r d i c s p p s e r v i c e s e r v e r s e n d ( c o n t e x t −>c o n n e c t i o n h a n d l e , (
uint8 t ∗ ) c o n t e x t −>t e s t d a t a , c o n t e x t −>t e s t d a t a l e n ) ;
// t r a c k
t e s t t r a c k s e n t ( c o n t e x t , c o n t e x t −>t e s t d a t a l e n ) ;
// r e q u e s t n e x t send e v e n t
n o r d i c s p p s e r v i c e s e r v e r r e q u e s t c a n s e n d n o w (& c o n t e x t −>
s e n d r e q u e s t , c o n t e x t −>c o n n e c t i o n h a n d l e ) ;
// c h e c k n e x t
next connection index () ;
}
0.63. LE u-blox SPP-like Heartbeat Server. Source Code: ublox spp le counter.c
0.63.1. Main Application Setup. Listing here shows main application code. It
initializes L2CAP, the Security Manager and configures the ATT Server with the
pre-compiled ATT Database generated from ubloxl ec ounter.gatt. Additionally,
it enables the Battery Service Server with the current battery level. Finally, it
configures the advertisements and the heartbeat handler and boots the Bluetooth
stack. In this example, the Advertisement contains the Flags attribute and
the device name. The flag 0x06 indicates: LE General Discoverable Mode and
BR/EDR not supported.
static b t s t a c k p a c k e t c a l l b a c k r e g i s t r a t i o n t
hci event callback registration ;
const uint8 t a d v d a t a [ ] = {
// F l a g s g e n e r a l d i s c o v e r a b l e , BR/EDR not s u p p o r t e d
2 , BLUETOOTH DATA TYPE FLAGS, 0 x06 ,
// Name
5 , BLUETOOTH DATA TYPE COMPLETE LOCAL NAME, ’ 6 ’ , ’− ’ , ’ 5 ’ , ’ 6 ’ ,
// UUID . . .
17 ,
BLUETOOTH DATA TYPE COMPLETE LIST OF 128 BIT SERVICE CLASS UUIDS
, 0x1 , 0xd7 , 0 xe9 , 0x1 , 0 x4f , 0 xf3 , 0 x44 , 0 xe7 , 0 x83 , 0 x8f , 0
xe2 , 0 x26 , 0xb9 , 0 xe1 , 0 x56 , 0 x24 ,
};
const uint8 t a d v d a t a l e n = s i z e o f ( a d v d a t a ) ;
0.63.2. Heartbeat Handler. The heartbeat handler updates the value of the single
Characteristic provided in this example, and request a ATT EVENT CAN SEND NOW
to send a notification if enabled see Listing here.
s t a t i c int c o u n t e r = 0 ;
s t a t i c char c o u n t e r s t r i n g [ 3 0 ] ;
s t a t i c int c o u n t e r s t r i n g l e n ;
s t a t i c void b e a t ( void ) {
c o u n t e r ++;
counter string len = snprintf ( counter string , sizeof (
c o u n t e r s t r i n g ) , ” BTstack c o u n t e r %03u” , c o u n t e r ) ;
}
s t a t i c void u b l o x c a n s e n d ( void ∗ c o n t e x t ) {
UNUSED( c o n t e x t ) ;
beat ( ) ;
p r i n t f ( ”SEND: %s \n” , c o u n t e r s t r i n g ) ;
u b l o x s p p s e r v i c e s e r v e r s e n d ( c o n h a n d l e , ( uint8 t ∗ )
counter string , counter string len ) ;
}
s t a t i c void h e a r t b e a t h a n d l e r ( struct b t s t a c k t i m e r s o u r c e ∗ t s ) {
i f ( c o n h a n d l e != HCI CON HANDLE INVALID) {
s e n d r e q u e s t . c a l l b a c k = &u b l o x c a n s e n d ;
u b l o x s p p s e r v i c e s e r v e r r e q u e s t c a n s e n d n o w (& s e n d r e q u e s t ,
con handle ) ;
}
b t s t a c k r u n l o o p s e t t i m e r ( t s , HEARTBEAT PERIOD MS) ;
btstack run loop add timer ( ts ) ;
}
switch ( p a c k e t t y p e ) {
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 ( p a c k e t ) ) {
case HCI EVENT DISCONNECTION COMPLETE :
c o n h a n d l e = HCI CON HANDLE INVALID ;
break ;
default :
break ;
}
break ;
default :
break ;
}
}
s t a t i c void s m p a i r i n g c e n t r a l s e t u p ( void ) {
l2cap init () ;
// s e t u p SM: D i s p l a y o n l y
sm init () ;
// s e t u p ATT s e r v e r
a t t s e r v e r i n i t ( p r o f i l e d a t a , NULL, NULL) ;
// s e t u p GATT C l i e n t
g a t t c l i e n t i n i t () ;
109
// r e g i s t e r h a n d l e r
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &h c i p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
s m e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &s m p a c k e t h a n d l e r ;
s m a d d e v e n t h a n d l e r (& s m e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
// C o n f i g u r a t i o n
/∗ ∗
∗ Choose ONE o f t h e f o l l o w i n g c o n f i g u r a t i o n s
∗ Bonding i s d i s a b l e d t o a l l o w f o r r e p e a t e d t e s t i n g . I t can be
e n a b l e d by or ’ i n g
∗ SM AUTHREQ BONDING t o t h e a u t h e n t i c a t i o n r e q u i r e m e n t s l i k e t h i s
:
∗ s m s e t a u t h e n t i c a t i o n r e q u i r e m e n t s ( X | SM AUTHREQ BONDING)
// LE Legacy P a i r i n g , J u s t Works
// s m s e t i o c a p a b i l i t i e s (IO CAPABILITY DISPLAY YES NO) ;
// s m s e t a u t h e n t i c a t i o n r e q u i r e m e n t s ( 0 ) ;
// LE Legacy P a i r i n g , Passkey e n t r y i n i t i a t o r e n t e r , r e s p o n d e r ( us
) displays
// s m s e t i o c a p a b i l i t i e s (IO CAPABILITY DISPLAY ONLY) ;
// s m s e t a u t h e n t i c a t i o n r e q u i r e m e n t s (SM AUTHREQ MITM PROTECTION) ;
// s m u s e f i x e d p a s s k e y i n d i s p l a y r o l e (FIXED PASSKEY) ;
// LE S e c u r e Connections , J u s t Works
// s m s e t i o c a p a b i l i t i e s (IO CAPABILITY DISPLAY YES NO) ;
// s m s e t a u t h e n t i c a t i o n r e q u i r e m e n t s (SM AUTHREQ SECURE CONNECTION
);
// LE S e c u r e P a i r i n g , Passkey e n t r y i n i t i a t o r ( us ) e n t e r s ,
responder d i s p l a y s
// s m s e t i o c a p a b i l i t i e s (IO CAPABILITY KEYBOARD ONLY) ;
110
// LE S e c u r e P a i r i n g , Passkey e n t r y i n i t i a t o r ( us ) d i s p l a y s ,
responder enters
// s m s e t i o c a p a b i l i t i e s (IO CAPABILITY DISPLAY ONLY) ;
// s m s e t a u t h e n t i c a t i o n r e q u i r e m e n t s (SM AUTHREQ SECURE CONNECTION
|SM AUTHREQ MITM PROTECTION) ;
#e n d i f
}
0.64.2. HCI packet handler. The HCI packet handler has to start the scanning,
and to handle received advertisements. Advertisements are received as HCI event
packets of the GAP EVENT ADVERTISING REPORT type, see Listing here.
switch ( h c i e v e n t p a c k e t g e t t y p e ( packet ) ) {
case BTSTACK EVENT STATE:
// BTstack a c t i v a t e d , g e t s t a r t e d
if ( b t s t a c k e v e n t s t a t e g e t s t a t e ( p a c k e t ) == HCI STATE WORKING
){
p r i n t f ( ” S t a r t s c a n i n g ! \ n” ) ;
g a p s e t s c a n p a r a m e t e r s ( 1 , 0 x0030 , 0 x0030 ) ;
gap start scan () ;
}
break ;
case GAP EVENT ADVERTISING REPORT: {
bd addr t a d d r e s s ;
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 ( packet , a d d r e s s ) ;
uint8 t a d d r e s s t y p e =
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 ( packet ) ;
uint8 t l e n g t h = 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 d a t a l e n g t h (
packet ) ;
const uint8 t ∗ data = 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 d a t a (
packet ) ;
// p r i n t f (” A d v e r t i s e m e n t e v e n t : addr−t y p e %u , addr %s , d a t a [%u
] ”,
// address type , b d a d d r t o s t r ( address ) , length ) ;
// p r i n t f h e x d u m p ( data , l e n g t h ) ;
i f ( ! a d d a t a c o n t a i n s u u i d 1 6 ( l e n g t h , ( uint8 t ∗ ) data ,
REMOTE SERVICE) ) break ;
111
// f o r t e s t i n g , c h o o s e one o f t h e f o l l o w i n g a c t i o n s
// manually s t a r t p a i r i n g
sm request pairing ( con handle ) ;
// g a t t c l i e n t r e q u e s t t o authenticated c h a r a c t e r i s t i c in
sm pairing peripheral ( s h o r t cut , u s e s hard−coded v a l u e
handle )
// g a t t c l i e n t r e a d v a l u e of characteristic using value handle
(& h c i p a c k e t h a n d l e r , c o n h a n d l e , 0 x0009 ) ;
// g e n e r a l g a t t c l i e n t r e q u e s t t o t r i g g e r mandatory
authentication
// g a t t c l i e n t d i s c o v e r p r i m a r y s e r v i c e s (& h c i p a c k e t h a n d l e r ,
con handle ) ;
break ;
case GATT EVENT QUERY COMPLETE:
s t a t u s = g a t t e v e n t q u e r y c o m p l e t e g e t a t t s t a t u s ( packet ) ;
switch ( s t a t u s ) {
case ATT ERROR INSUFFICIENT ENCRYPTION :
p r i n t f ( ”GATT Query r e s u l t : I n s u f f i c i e n t E n c r y p t i o n \n” ) ;
break ;
case ATT ERROR INSUFFICIENT AUTHENTICATION :
p r i n t f ( ”GATT Query r e s u l t : I n s u f f i c i e n t A u t h e n t i c a t i o n \n” )
;
break ;
case ATT ERROR BONDING INFORMATION MISSING :
p r i n t f ( ”GATT Query r e s u l t : Bonding I n f o r m a t i o n M i s s i n g \n” )
;
break ;
case ATT ERROR SUCCESS :
p r i n t f ( ”GATT Query r e s u l t : OK\n” ) ;
break ;
default :
p r i n t f ( ”GATT Query r e s u l t : 0x%02x\n” ,
g a t t e v e n t q u e r y c o m p l e t e g e t a t t s t a t u s ( packet ) ) ;
break ;
}
break ;
112
default :
break ;
}
}
bd addr t addr ;
bd addr type t addr type ;
switch ( h c i e v e n t p a c k e t g e t t y p e ( p a c k e t ) ) {
case SM EVENT JUST WORKS REQUEST :
p r i n t f ( ” J u s t works r e q u e s t e d \n” ) ;
sm just works confirm ( sm event just works request get handle (
packet ) ) ;
break ;
case SM EVENT NUMERIC COMPARISON REQUEST:
p r i n t f ( ” Confirming numeric comparison : %”PRIu32”\n” ,
sm event numeric comparison request get passkey ( packet ) ) ;
sm numeric comparison confirm (
sm event passkey display number get handle ( packet ) ) ;
break ;
case SM EVENT PASSKEY DISPLAY NUMBER :
p r i n t f ( ” D i s p l a y Passkey : %”PRIu32” \n” ,
sm event passkey display number get passkey ( packet ) ) ;
break ;
case SM EVENT PASSKEY INPUT NUMBER :
p r i n t f ( ” Passkey Input r e q u e s t e d \n” ) ;
p r i n t f ( ” Sending f i x e d p a s s k e y %”PRIu32”\n” , ( uint32 t )
FIXED PASSKEY) ;
sm passkey input ( sm event passkey input number get handle (
p a c k e t ) , FIXED PASSKEY) ;
break ;
case SM EVENT PAIRING STARTED :
p r i n t f ( ” P a i r i n g s t a r t e d \n” ) ;
break ;
case SM EVENT PAIRING COMPLETE :
switch ( s m e v e n t p a i r i n g c o m p l e t e g e t s t a t u s ( p a c k e t ) ) {
case ERROR CODE SUCCESS :
p r i n t f ( ” P a i r i n g complete , s u c c e s s \n” ) ;
break ;
case ERROR CODE CONNECTION TIMEOUT:
p r i n t f ( ” P a i r i n g f a i l e d , t i m e o u t \n” ) ;
break ;
case ERROR CODE REMOTE USER TERMINATED CONNECTION:
p r i n t f ( ” P a i r i n g f a i l e d , d i s c o n n e c t e d \n” ) ;
113
break ;
case ERROR CODE AUTHENTICATION FAILURE :
p r i n t f ( ” P a i r i n g f a i l e d , a u t h e n t i c a t i o n f a i l u r e with r e a s o n
= %u\n” , s m e v e n t p a i r i n g c o m p l e t e g e t r e a s o n ( p a c k e t )
);
break ;
default :
break ;
}
break ;
case SM EVENT REENCRYPTION STARTED:
s m e v e n t r e e n c r y p t i o n c o m p l e t e g e t a d d r e s s ( packet , addr ) ;
p r i n t f ( ” Bonding i n f o r m a t i o n e x i s t s f o r addr type %u , i d e n t i t y
addr %s −> s t a r t re−e n c r y p t i o n \n” ,
s m e v e n t r e e n c r y p t i o n s t a r t e d g e t a d d r t y p e ( packet ) ,
b d a d d r t o s t r ( addr ) ) ;
break ;
case SM EVENT REENCRYPTION COMPLETE:
switch ( s m e v e n t r e e n c r y p t i o n c o m p l e t e g e t s t a t u s ( p a c k e t ) ) {
case ERROR CODE SUCCESS :
p r i n t f ( ”Re−e n c r y p t i o n complete , s u c c e s s \n” ) ;
break ;
case ERROR CODE CONNECTION TIMEOUT:
p r i n t f ( ”Re−e n c r y p t i o n f a i l e d , t i m e o u t \n” ) ;
break ;
case ERROR CODE REMOTE USER TERMINATED CONNECTION:
p r i n t f ( ”Re−e n c r y p t i o n f a i l e d , d i s c o n n e c t e d \n” ) ;
break ;
case ERROR CODE PIN OR KEY MISSING :
p r i n t f ( ”Re−e n c r y p t i o n f a i l e d , bonding i n f o r m a t i o n m i s s i n g \
n\n” ) ;
p r i n t f ( ” Assuming remote l o s t bonding i n f o r m a t i o n \n” ) ;
p r i n t f ( ” D e l e t i n g l o c a l bonding i n f o r m a t i o n and s t a r t new
p a i r i n g . . . \ n” ) ;
s m e v e n t r e e n c r y p t i o n c o m p l e t e g e t a d d r e s s ( packet , addr ) ;
addr type = sm event reencryption started get addr type (
packet ) ;
g a p d e l e t e b o n d i n g ( a d d r t y p e , addr ) ;
sm request pairing (
sm event reencryption complete get handle ( packet ) ) ;
break ;
default :
break ;
}
break ;
default :
break ;
}
}
The SM packet handler receives Security Manager Events required for pairing.
It also receives events generated during Identity Resolving see Listing here.
0.65.1. Main Application Setup. Listing here shows main application code. It
initializes L2CAP, the Security Manager and configures the ATT Server with
the pre-compiled ATT Database generated from smp airingp eripheral.gatt. Fi-
nally, it configures the advertisements and boots the Bluetooth stack. In this
example, the Advertisement contains the Flags attribute, the device name, and
a 16-bit (test) service 0x1111 The flag 0x06 indicates: LE General Discoverable
Mode and BR/EDR not supported. Various examples for IO Capabilites and
Authentication Requirements are given below.
const uint8 t a d v d a t a [ ] = {
// F l a g s g e n e r a l d i s c o v e r a b l e , BR/EDR not s u p p o r t e d
0 x02 , BLUETOOTH DATA TYPE FLAGS, 0 x06 ,
// Name
0x0b , BLUETOOTH DATA TYPE COMPLETE LOCAL NAME, ’ S ’ , ’M’ , ’ ’ , ’P ’ ,
’a ’ , ’ i ’ , ’ r ’ , ’ i ’ , ’n ’ , ’g ’ ,
// I n c o m p l e t e L i s t o f 16− b i t S e r v i c e C l a s s UUIDs −− 1111 − o n l y
valid for testing !
0 x03 ,
BLUETOOTH DATA TYPE INCOMPLETE LIST OF 16 BIT SERVICE CLASS UUIDS
, 0 x11 , 0 x11 ,
};
const uint8 t a d v d a t a l e n = s i z e o f ( a d v d a t a ) ;
s t a t i c void s m p e r i p h e r a l s e t u p ( void ) {
l2cap init () ;
// s e t u p SM: D i s p l a y o n l y
sm init () ;
// s e t u p ATT s e r v e r
a t t s e r v e r i n i t ( p r o f i l e d a t a , NULL, NULL) ;
// s e t u p GATT C l i e n t
g a t t c l i e n t i n i t () ;
// s e t u p a d v e r t i s e m e n t s
uint16 t a d v i n t m i n = 0 x0030 ;
115
uint16 t a d v i n t m a x = 0 x0030 ;
uint8 t a d v t y p e = 0 ;
bd addr t n u l l a d d r ;
memset ( n u l l a d d r , 0 , 6 ) ;
g a p a d v e r t i s e m e n t s s e t p a r a m s ( a d v i n t m i n , adv int max , adv type ,
0 , n u l l a d d r , 0 x07 , 0 x00 ) ;
g a p a d v e r t i s e m e n t s s e t d a t a ( a d v d a t a l e n , ( uint8 t ∗ ) a d v d a t a ) ;
gap advertisements enable (1) ;
// r e g i s t e r h a n d l e r
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &h c i p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
s m e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &s m p a c k e t h a n d l e r ;
s m a d d e v e n t h a n d l e r (& s m e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
// C o n f i g u r a t i o n
/∗ ∗
∗ Choose ONE o f t h e f o l l o w i n g c o n f i g u r a t i o n s
∗ Bonding i s d i s a b l e d t o a l l o w f o r r e p e a t e d t e s t i n g . I t can be
e n a b l e d by or ’ i n g
∗ SM AUTHREQ BONDING t o t h e a u t h e n t i c a t i o n r e q u i r e m e n t s l i k e t h i s
:
∗ s m s e t a u t h e n t i c a t i o n r e q u i r e m e n t s ( X | SM AUTHREQ BONDING)
// LE Legacy P a i r i n g , J u s t Works
// s m s e t i o c a p a b i l i t i e s (IO CAPABILITY NO INPUT NO OUTPUT) ;
// s m s e t a u t h e n t i c a t i o n r e q u i r e m e n t s ( 0 ) ;
// LE Legacy P a i r i n g , Passkey e n t r y i n i t i a t o r e n t e r , r e s p o n d e r ( us
) displays
// s m s e t i o c a p a b i l i t i e s (IO CAPABILITY DISPLAY ONLY) ;
// s m s e t a u t h e n t i c a t i o n r e q u i r e m e n t s (SM AUTHREQ MITM PROTECTION) ;
// s m u s e f i x e d p a s s k e y i n d i s p l a y r o l e ( 1 2 3 4 5 6 ) ;
// LE S e c u r e Connections , J u s t Works
// s m s e t i o c a p a b i l i t i e s (IO CAPABILITY NO INPUT NO OUTPUT) ;
// s m s e t a u t h e n t i c a t i o n r e q u i r e m e n t s (SM AUTHREQ SECURE CONNECTION
);
// LE S e c u r e P a i r i n g , Passkey e n t r y i n i t i a t o r e n t e r , r e s p o n d e r ( us
) displays
// s m s e t i o c a p a b i l i t i e s (IO CAPABILITY DISPLAY ONLY) ;
// s m s e t a u t h e n t i c a t i o n r e q u i r e m e n t s (SM AUTHREQ SECURE CONNECTION
|SM AUTHREQ MITM PROTECTION) ;
// s m u s e f i x e d p a s s k e y i n d i s p l a y r o l e ( 1 2 3 4 5 6 ) ;
// LE S e c u r e P a i r i n g , Passkey e n t r y i n i t i a t o r d i s p l a y s , r e s p o n d e r
( us ) e n t e r
// s m s e t i o c a p a b i l i t i e s (IO CAPABILITY KEYBOARD ONLY) ;
// s m s e t a u t h e n t i c a t i o n r e q u i r e m e n t s (SM AUTHREQ SECURE CONNECTION
|SM AUTHREQ MITM PROTECTION) ;
#e n d i f
}
0.65.2. Security Manager Packet Handler. The packet handler is used to handle
Security Manager events
switch ( h c i e v e n t p a c k e t g e t t y p e ( p a c k e t ) ) {
case HCI EVENT META GAP :
switch ( h c i e v e n t g a p m e t a g e t s u b e v e n t c o d e ( p a c k e t ) ) {
case GAP SUBEVENT LE CONNECTION COMPLETE:
p r i n t f ( ” Connection c o m p l e t e \n” ) ;
con handle =
gap subevent le connection complete get connection handle
( packet ) ;
UNUSED( c o n h a n d l e ) ;
// f o r t e s t i n g , c h o o s e one o f t h e f o l l o w i n g a c t i o n s
// manually s t a r t p a i r i n g
// s m r e q u e s t p a i r i n g ( c o n h a n d l e ) ;
// g a t t c l i e n t r e q u e s t t o a u t h e n t i c a t e d c h a r a c t e r i s t i c i n
s m p a i r i n g c e n t r a l ( s h o r t cut , u s e s hard−coded v a l u e
handle )
117
//
gatt client read value of characteristic using value handle
(& p a c k e t h a n d l e r , c o n h a n d l e , 0 x0009 ) ;
// g e n e r a l g a t t c l i e n t r e q u e s t t o t r i g g e r mandatory
authentication
// g a t t c l i e n t d i s c o v e r p r i m a r y s e r v i c e s (& p a c k e t h a n d l e r ,
con handle ) ;
break ;
default :
break ;
}
break ;
case SM EVENT JUST WORKS REQUEST :
p r i n t f ( ” J u s t Works r e q u e s t e d \n” ) ;
sm just works confirm ( sm event just works request get handle (
packet ) ) ;
break ;
case SM EVENT NUMERIC COMPARISON REQUEST:
p r i n t f ( ” Confirming numeric comparison : %”PRIu32”\n” ,
sm event numeric comparison request get passkey ( packet ) ) ;
sm numeric comparison confirm (
sm event passkey display number get handle ( packet ) ) ;
break ;
case SM EVENT PASSKEY DISPLAY NUMBER :
p r i n t f ( ” D i s p l a y Passkey : %”PRIu32” \n” ,
sm event passkey display number get passkey ( packet ) ) ;
break ;
case SM EVENT IDENTITY CREATED :
s m e v e n t i d e n t i t y c r e a t e d g e t i d e n t i t y a d d r e s s ( packet , addr ) ;
p r i n t f ( ” I d e n t i t y c r e a t e d : type %u a d d r e s s %s \n” ,
s m e v e n t i d e n t i t y c r e a t e d g e t i d e n t i t y a d d r t y p e ( packet ) ,
b d a d d r t o s t r ( addr ) ) ;
break ;
case SM EVENT IDENTITY RESOLVING SUCCEEDED :
sm event identity resolving succeeded get identity address (
packet , addr ) ;
p r i n t f ( ” I d e n t i t y r e s o l v e d : type %u a d d r e s s %s \n” ,
sm event identity resolving succeeded get identity addr type
( p a c k e t ) , b d a d d r t o s t r ( addr ) ) ;
break ;
case SM EVENT IDENTITY RESOLVING FAILED :
s m e v e n t i d e n t i t y c r e a t e d g e t a d d r e s s ( packet , addr ) ;
p r i n t f ( ” I d e n t i t y r e s o l v i n g f a i l e d \n” ) ;
break ;
case SM EVENT PAIRING STARTED :
p r i n t f ( ” P a i r i n g s t a r t e d \n” ) ;
break ;
case SM EVENT PAIRING COMPLETE :
switch ( s m e v e n t p a i r i n g c o m p l e t e g e t s t a t u s ( p a c k e t ) ) {
case ERROR CODE SUCCESS :
p r i n t f ( ” P a i r i n g complete , s u c c e s s \n” ) ;
break ;
case ERROR CODE CONNECTION TIMEOUT:
118
p r i n t f ( ” P a i r i n g f a i l e d , t i m e o u t \n” ) ;
break ;
case ERROR CODE REMOTE USER TERMINATED CONNECTION:
p r i n t f ( ” P a i r i n g f a i l e d , d i s c o n n e c t e d \n” ) ;
break ;
case ERROR CODE AUTHENTICATION FAILURE :
p r i n t f ( ” P a i r i n g f a i l e d , a u t h e n t i c a t i o n f a i l u r e with r e a s o n
= %u\n” , s m e v e n t p a i r i n g c o m p l e t e g e t r e a s o n ( p a c k e t )
);
break ;
default :
break ;
}
break ;
case SM EVENT REENCRYPTION STARTED:
s m e v e n t r e e n c r y p t i o n c o m p l e t e g e t a d d r e s s ( packet , addr ) ;
p r i n t f ( ” Bonding i n f o r m a t i o n e x i s t s f o r addr type %u , i d e n t i t y
addr %s −> re−e n c r y p t i o n s t a r t e d \n” ,
s m e v e n t r e e n c r y p t i o n s t a r t e d g e t a d d r t y p e ( packet ) ,
b d a d d r t o s t r ( addr ) ) ;
break ;
case SM EVENT REENCRYPTION COMPLETE:
switch ( s m e v e n t r e e n c r y p t i o n c o m p l e t e g e t s t a t u s ( p a c k e t ) ) {
case ERROR CODE SUCCESS :
p r i n t f ( ”Re−e n c r y p t i o n complete , s u c c e s s \n” ) ;
break ;
case ERROR CODE CONNECTION TIMEOUT:
p r i n t f ( ”Re−e n c r y p t i o n f a i l e d , t i m e o u t \n” ) ;
break ;
case ERROR CODE REMOTE USER TERMINATED CONNECTION:
p r i n t f ( ”Re−e n c r y p t i o n f a i l e d , d i s c o n n e c t e d \n” ) ;
break ;
case ERROR CODE PIN OR KEY MISSING :
p r i n t f ( ”Re−e n c r y p t i o n f a i l e d , bonding i n f o r m a t i o n m i s s i n g \
n\n” ) ;
p r i n t f ( ” Assuming remote l o s t bonding i n f o r m a t i o n \n” ) ;
p r i n t f ( ” D e l e t i n g l o c a l bonding i n f o r m a t i o n t o a l l o w f o r
new p a i r i n g . . . \ n” ) ;
s m e v e n t r e e n c r y p t i o n c o m p l e t e g e t a d d r e s s ( packet , addr ) ;
addr type = sm event reencryption started get addr type (
packet ) ;
g a p d e l e t e b o n d i n g ( a d d r t y p e , addr ) ;
break ;
default :
break ;
}
break ;
case GATT EVENT QUERY COMPLETE:
s t a t u s = g a t t e v e n t q u e r y c o m p l e t e g e t a t t s t a t u s ( packet ) ;
switch ( s t a t u s ) {
case ATT ERROR INSUFFICIENT ENCRYPTION :
p r i n t f ( ”GATT Query f a i l e d , I n s u f f i c i e n t E n c r y p t i o n \n” ) ;
break ;
case ATT ERROR INSUFFICIENT AUTHENTICATION :
119
/∗
∗
s t a t i c void hci packet handler ( uint8 t packet type , uint16 t
channel , u i n t 8 t ∗ p a c k e t , u i n t 1 6 t s i z e ) {
UNUSED( c h a n n e l ) ;
UNUSED( s i z e ) ;
switch ( h c i e v e n t p a c k e t g e t t y p e ( packet ) ) {
c a s e HCI EVENT META GAP:
switch ( hci event gap meta get subevent code ( packet ) ) {
c a s e GAP SUBEVENT LE CONNECTION COMPLETE:
p r i n t f (” Connection c o m p l e t e \n ”) ;
con handle =
gap subevent le connection complete get connection handle
( packet ) ;
UNUSED( c o n h a n d l e ) ;
// f o r t e s t i n g , c h o o s e one o f t h e f o l l o w i n g a c t i o n s
// manually s t a r t p a i r i n g
// s m r e q u e s t p a i r i n g ( c o n h a n d l e ) ;
// g a t t c l i e n t r e q u e s t t o a u t h e n t i c a t e d c h a r a c t e r i s t i c i n
s m p a i r i n g c e n t r a l ( s h o r t cut , u s e s hard−coded v a l u e
handle )
//
gatt client read value of characteristic using value handle
(& p a c k e t h a n d l e r , c o n h a n d l e , 0 x0009 ) ;
120
// g e n e r a l g a t t c l i e n t r e q u e s t t o t r i g g e r mandatory
authentication
// g a t t c l i e n t d i s c o v e r p r i m a r y s e r v i c e s (& p a c k e t h a n d l e r ,
con handle ) ;
break ;
default :
break ;
}
break ;
default :
break ;
}
}
The packet handler is used to handle new connections, can trigger Security
Request
// s u p p o r t f o r m u l t i p l e c l i e n t s
typedef struct {
char name ;
hci con handle t connection handle ;
uint16 t c i d ;
int c o u n t e r ;
char t e s t d a t a [ TEST PACKET SIZE ] ;
int t e s t d a t a l e n ;
uint32 t t e s t d a t a s e n t ;
uint32 t t e s t d a t a s t a r t ;
} le cbm connection t ;
s t a t i c void t e s t r e s e t ( l e c b m c o n n e c t i o n t ∗ c o n t e x t ) {
c o n t e x t −>t e s t d a t a s t a r t = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
}
s t a t i c void t e s t t r a c k d a t a ( l e c b m c o n n e c t i o n t ∗ c o n t e x t , int
bytes transferred ){
c o n t e x t −>t e s t d a t a s e n t += b y t e s t r a n s f e r r e d ;
// e v a l u a t e
uint32 t now = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
121
// r e s t a r t
c o n t e x t −>t e s t d a t a s t a r t = now ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
}
0.66.2. Streamer. The streamer function checks if notifications are enabled and
if a notification can be sent now. It creates some test data - a single letter that
gets increased every time - and tracks the data sent.
s t a t i c void s t r e a m e r ( void ) {
// c r e a t e t e s t d a t a
l e c b m c o n n e c t i o n . c o u n t e r ++;
i f ( le cbm connection . counter > ’Z ’ ) le cbm connection . counter = ’
A’ ;
memset ( l e c b m c o n n e c t i o n . t e s t d a t a , l e c b m c o n n e c t i o n . c o u n t e r ,
le cbm connection . test data len ) ;
// send
l 2 c a p s e n d ( l e c b m c o n n e c t i o n . c i d , ( uint8 t ∗ ) l e c b m c o n n e c t i o n .
test data , le cbm connection . test data len ) ;
// t r a c k
t e s t t r a c k d a t a (& l e c b m c o n n e c t i o n , l e c b m c o n n e c t i o n .
test data len ) ;
// r e q u e s t a n o t h e r p a c k e t
l2cap request can send now event ( le cbm connection . cid ) ;
}
0.66.3. SM Packet Handler. The packet handler is used to handle pairing re-
quests
s t a t i c void t e s t r e s e t ( l e c b m c o n n e c t i o n t ∗ c o n t e x t ) {
c o n t e x t −>t e s t d a t a s t a r t = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
}
s t a t i c void t e s t t r a c k d a t a ( l e c b m c o n n e c t i o n t ∗ c o n t e x t , int
bytes transferred ){
c o n t e x t −>t e s t d a t a s e n t += b y t e s t r a n s f e r r e d ;
// e v a l u a t e
uint32 t now = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
uint32 t t i m e p a s s e d = now − c o n t e x t −>t e s t d a t a s t a r t ;
i f ( t i m e p a s s e d < REPORT INTERVAL MS) return ;
// p r i n t s p e e d
int b y t e s p e r s e c o n d = c o n t e x t −>t e s t d a t a s e n t ∗ 1000 /
time passed ;
p r i n t f ( ”%c : %”PRIu32” b y t e s s e n t −> %u.%03u kB/ s \n” , c o n t e x t −>name ,
c o n t e x t −>t e s t d a t a s e n t , b y t e s p e r s e c o n d / 1 0 0 0 ,
b y t e s p e r s e c o n d % 1000) ;
// r e s t a r t
c o n t e x t −>t e s t d a t a s t a r t = now ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
}
0.67.2. Streamer. The streamer function checks if notifications are enabled and
if a notification can be sent now. It creates some test data - a single letter that
gets increased every time - and tracks the data sent.
s t a t i c void s t r e a m e r ( void ) {
i f ( l e c b m c o n n e c t i o n . c i d == 0 ) return ;
// c r e a t e t e s t d a t a
l e c b m c o n n e c t i o n . c o u n t e r ++;
i f ( le cbm connection . counter > ’Z ’ ) le cbm connection . counter = ’
A’ ;
memset ( l e c b m c o n n e c t i o n . t e s t d a t a , l e c b m c o n n e c t i o n . c o u n t e r ,
le cbm connection . test data len ) ;
// send
l 2 c a p s e n d ( l e c b m c o n n e c t i o n . c i d , ( uint8 t ∗ ) l e c b m c o n n e c t i o n .
test data , le cbm connection . test data len ) ;
// t r a c k
t e s t t r a c k d a t a (& l e c b m c o n n e c t i o n , l e c b m c o n n e c t i o n .
test data len ) ;
123
// r e q u e s t a n o t h e r p a c k e t
l2cap request can send now event ( le cbm connection . cid ) ;
}
0.67.3. HCI + L2CAP Packet Handler. The packet handler is used to stop the
notifications and reset the MTU on connect It would also be a good place to
request the connection parameter update as indicated in the commented code
block.
0.67.4. SM Packet Handler.
0.67.5. Main Application Setup.
0.68. LE Peripheral - Delayed Response. Source Code: att delayed response.c
The packet handler is used to handle pairing requests
Listing here shows main application code. It initializes L2CAP, the Security
Manager, and configures the ATT Server with the pre-compiled ATT Database
generated from lec reditb asedf lowc ontrolm odes erver.gatt. Finally, it configures
the advertisements and boots the Bluetooth stack.
If the value for a GATT Chararacteristic isn’t availabl for read, the value
ATT READ RESPONSE PENDING can be returned. When the value is avail-
able, att server response ready is then called to complete the ATT request.
Similarly, the error code ATT ERROR WRITE RESPONSE PENING can be
returned when it is unclear if a write can be performed or not. When the deci-
sion was made, att server response ready is is then called to complete the ATT
request.
0.68.1. Main Application Setup. Listing here shows main application code. It
initializes L2CAP, the Security Manager and configures the ATT Server with
the pre-compiled ATT Database generated from attd elayedr esponse.gatt. Ad-
ditionally, it enables the Battery Service Server with the current battery level.
Finally, it configures the advertisements and boots the Bluetooth stack. In this
example, the Advertisement contains the Flags attribute and the device name.
The flag 0x06 indicates: LE General Discoverable Mode and BR/EDR not sup-
ported.
s t a t i c uint16 t a t t r e a d c a l l b a c k ( h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t a t t h a n d l e , uint16 t o f f s e t , uint8 t ∗ b u f f e r , uint16 t
buffer size ) ;
s t a t i c int a t t w r i t e c a l l b a c k ( h c i c o n h a n d l e t c o n n e c t i o n h a n d l e ,
uint16 t a t t h a n d l e , uint16 t t r a n s a c t i o n m o d e , uint16 t o f f s e t ,
uint8 t ∗ b u f f e r , uint16 t b u f f e r s i z e ) ;
124
const uint8 t a d v d a t a [ ] = {
// F l a g s g e n e r a l d i s c o v e r a b l e , BR/EDR not s u p p o r t e d
0 x02 , 0 x01 , 0 x06 ,
// Name
0 x08 , 0 x09 , ’D ’ , ’ e ’ , ’ l ’ , ’ a ’ , ’ y ’ , ’ e ’ , ’ d ’ ,
};
const uint8 t a d v d a t a l e n = s i z e o f ( a d v d a t a ) ;
s t a t i c void e x a m p l e s e t u p ( void ) {
l2cap init () ;
// s e t u p SM: D i s p l a y o n l y
sm init () ;
// s e t u p ATT s e r v e r
att server init ( profile data , att read callback ,
att write callback ) ;
// s e t u p a d v e r t i s e m e n t s
uint16 t a d v i n t m i n = 0 x0030 ;
uint16 t a d v i n t m a x = 0 x0030 ;
uint8 t a d v t y p e = 0 ;
bd addr t n u l l a d d r ;
memset ( n u l l a d d r , 0 , 6 ) ;
g a p a d v e r t i s e m e n t s s e t p a r a m s ( a d v i n t m i n , adv int max , adv type ,
0 , n u l l a d d r , 0 x07 , 0 x00 ) ;
g a p a d v e r t i s e m e n t s s e t d a t a ( a d v d a t a l e n , ( uint8 t ∗ ) a d v d a t a ) ;
gap advertisements enable (1) ;
}
0.68.2. att invalidate value Handler. The att invalidate value handler ‘invalidates’
the value of the single Characteristic provided in this example
0.68.3. att update value Handler. The att update value handler ‘updates’ the
value of the single Characteristic provided in this example
// t r i g g e r ATT S e r v e r t o t r y r e q u e s t a g a i n
int s t a t u s = a t t s e r v e r r e s p o n s e r e a d y ( c o n h a n d l e ) ;
// s i m u l a t e d v a l u e becoming s t a l e a g a i n
125
a t t t i m e r . p r o c e s s = &a t t i n v a l i d a t e v a l u e ;
b t s t a c k r u n l o o p s e t t i m e r (& a t t t i m e r , ATT VALUE DELAY MS) ;
b t s t a c k r u n l o o p a d d t i m e r (& a t t t i m e r ) ;
}
#endif
0.68.4. ATT Read. The ATT Server handles all reads to constant data. For
dynamic data like the custom characteristic, the registered att read callback is
called. To handle long characteristics and long reads, the att read callback is
first called with buffer == NULL, to request the total value length. Then it will
be called again requesting a chunk of the value. See Listing here.
0.68.5. ATT Write.
return 0 ;
}
/∗
i f ( a t t h a n d l e ==
ATT CHARACTERISTIC 0000FF11 0000 1000 8000 00805F9B34FB 01 VALUE HANDLE
) {
p r i n t f (” Write r e q u e s t , v a l u e : ”) ;
printf hexdump ( buffer , b u f f e r s i z e ) ;
#i f d e f ENABLE ATT DELAYED RESPONSE
i f ( value ready ){
p r i n t f (” Write c a l l b a c k , v a l u e r e a d y \n ”) ;
return 0;
} else {
p r i n t f (” Write c a l l b a c k f o r h a n d l e 0 x%02x , b u t not r e a d y −>
r e t u r n r e s p o n s e p e n d i n g \n ” , a t t h a n d l e ) ;
}
// s i m u l a t e d d e l a y e d r e s p o n s e f o r example
a t t t i m e r . p r o c e s s = &a t t u p d a t e v a l u e ;
b t s t a c k r u n l o o p s e t t i m e r (& a t t t i m e r , ATT VALUE DELAY MS) ;
b t s t a c k r u n l o o p a d d t i m e r (& a t t t i m e r ) ;
r e t u r n ATT ERROR WRITE RESPONSE PENDING;
#e l s e
p r i n t f (”ENABLE ATT DELAYED RESPONSE not d e f i n e d i n
b t s t a c k c o n f i g . h , r e s p o n d i n g r i g h t away ”) ;
return 0;
#e n d i f
}
return 0;
}
127
0.69. LE ANCS Client - Apple Notification Service. Source Code: ancs client demo.c
0.70. LE Man-in-the-Middle Tool. Source Code: le mitm.c
The example first does an LE scan and allows the user to select a Peripheral
device. Then, it connects to the Peripheral and starts advertising with the
same data as the Peripheral device. ATT Requests and responses are forwarded
between the peripheral and the central Security requests are handled locally.
@note A Bluetooth Controller that supports Central and Peripheral Role at
the same time is required for this example. See chipset/README.md
0.71. Performance - Stream Data over GATT (Client). Source Code:
le streamer client.c
Connects to ‘LE Streamer’ and subscribes to test characteristic
0.71.1. Track throughput. We calculate the throughput by setting a start time
and measuring the amount of data sent. After a configurable REPORT INTERVAL MS,
we print the throughput in kB/s and reset the counter and start time.
// s u p p o r t f o r m u l t i p l e c l i e n t s
static le streamer connection t le streamer connection ;
s t a t i c void t e s t r e s e t ( l e s t r e a m e r c o n n e c t i o n t ∗ c o n t e x t ) {
c o n t e x t −>t e s t d a t a s t a r t = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
}
s t a t i c void t e s t t r a c k d a t a ( l e s t r e a m e r c o n n e c t i o n t ∗ c o n t e x t , int
bytes sent ){
c o n t e x t −>t e s t d a t a s e n t += b y t e s s e n t ;
// e v a l u a t e
uint32 t now = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
uint32 t t i m e p a s s e d = now − c o n t e x t −>t e s t d a t a s t a r t ;
i f ( t i m e p a s s e d < REPORT INTERVAL MS) return ;
// p r i n t s p e e d
int b y t e s p e r s e c o n d = c o n t e x t −>t e s t d a t a s e n t ∗ 1000 /
time passed ;
p r i n t f ( ”%c : %”PRIu32” b y t e s −> %u.%03u kB/ s \n” , c o n t e x t −>name ,
c o n t e x t −>t e s t d a t a s e n t , b y t e s p e r s e c o n d / 1 0 0 0 ,
b y t e s p e r s e c o n d % 1000) ;
// r e s t a r t
c o n t e x t −>t e s t d a t a s t a r t = now ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
128
s t a t i c void l e s t r e a m e r s e t u p ( void ) {
l2cap init () ;
// s e t u p SM: D i s p l a y o n l y
sm init () ;
// c o n f i g u r e C l a s s i c GAP
g a p s e t l o c a l n a m e ( ”GATT Streamer BR/EDR 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 ” ) ;
g a p s s p s e t i o c a p a b i l i t y ( SSP IO CAPABILITY DISPLAY YES NO ) ;
gap discoverable control (1) ;
#endif
// s e t u p ATT s e r v e r
a t t s e r v e r i n i t ( p r o f i l e d a t a , NULL, a t t w r i t e c a l l b a c k ) ;
// r e g i s t e r f o r HCI e v e n t s
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &h c i p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
129
// r e g i s t e r f o r ATT e v e n t s
att server register packet handler ( att packet handler ) ;
// s e t u p a d v e r t i s e m e n t s
uint16 t a d v i n t m i n = 0 x0030 ;
uint16 t a d v i n t m a x = 0 x0030 ;
uint8 t a d v t y p e = 0 ;
bd addr t n u l l a d d r ;
memset ( n u l l a d d r , 0 , 6 ) ;
g a p a d v e r t i s e m e n t s s e t p a r a m s ( a d v i n t m i n , adv int max , adv type ,
0 , n u l l a d d r , 0 x07 , 0 x00 ) ;
g a p a d v e r t i s e m e n t s s e t d a t a ( a d v d a t a l e n , ( uint8 t ∗ ) a d v d a t a ) ;
gap advertisements enable (1) ;
// i n i t c l i e n t s t a t e
init connections () ;
}
s t a t i c void t e s t r e s e t ( l e s t r e a m e r c o n n e c t i o n t ∗ c o n t e x t ) {
c o n t e x t −>t e s t d a t a s t a r t = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
}
s t a t i c void t e s t t r a c k s e n t ( l e s t r e a m e r c o n n e c t i o n t ∗ c o n t e x t , int
bytes sent ){
c o n t e x t −>t e s t d a t a s e n t += b y t e s s e n t ;
// e v a l u a t e
uint32 t now = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
uint32 t t i m e p a s s e d = now − c o n t e x t −>t e s t d a t a s t a r t ;
i f ( t i m e p a s s e d < REPORT INTERVAL MS) return ;
// p r i n t s p e e d
int b y t e s p e r s e c o n d = c o n t e x t −>t e s t d a t a s e n t ∗ 1000 /
time passed ;
p r i n t f ( ”%c : %”PRIu32” b y t e s s e n t −> %u.%03u kB/ s \n” , c o n t e x t −>name ,
c o n t e x t −>t e s t d a t a s e n t , b y t e s p e r s e c o n d / 1 0 0 0 ,
b y t e s p e r s e c o n d % 1000) ;
// r e s t a r t
c o n t e x t −>t e s t d a t a s t a r t = now ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
}
0.72.3. HCI Packet Handler. The packet handler is used track incoming connec-
tions and to stop notifications on disconnect It is also a good place to request
the connection parameter update as indicated in the commented code block.
130
uint16 t c o n n i n t e r v a l ;
hci con handle t con handle ;
s t a t i c const char ∗ const phy names [ ] = {
” Reserved ” , ” 1 M” , ” 2 M” , ” Codec ”
};
switch ( h c i e v e n t p a c k e t g e t t y p e ( packet ) ) {
case BTSTACK EVENT STATE:
// BTstack a c t i v a t e d , g e t s t a r t e d
if ( b t s t a c k e v e n t s t a t e g e t s t a t e ( p a c k e t ) == HCI STATE WORKING
) {
p r i n t f ( ”To s t a r t t h e s t r e a m i n g , p l e a s e run t h e
l e s t r e a m e r c l i e n t example on o t h e r d e v i c e , o r u s e some
GATT E x p l o r e r , e . g . LightBlue , BLExplr . \ n” ) ;
}
break ;
case HCI EVENT DISCONNECTION COMPLETE :
con handle =
hci event disconnection complete get connection handle (
packet ) ;
p r i n t f ( ”− LE Connection 0x%04x : d i s c o n n e c t , r e a s o n %02x\n” ,
con handle , h c i e v e n t d i s c o n n e c t i o n c o m p l e t e g e t r e a s o n (
packet ) ) ;
break ;
case HCI EVENT META GAP :
switch ( h c i e v e n t g a p m e t a g e t s u b e v e n t c o d e ( p a c k e t ) ) {
case GAP SUBEVENT LE CONNECTION COMPLETE:
// p r i n t c o n n e c t i o n p a r a m e t e r s ( w i t h o u t u s i n g f l o a t
operations )
con handle =
gap subevent le connection complete get connection handle
( packet ) ;
conn interval =
gap subevent le connection complete get conn interval (
packet ) ;
p r i n t f ( ”− LE Connection 0x%04x : c o n n e c t e d − c o n n e c t i o n
i n t e r v a l %u.%02u ms , l a t e n c y %u\n” , c o n h a n d l e ,
c o n n i n t e r v a l ∗ 125 / 1 0 0 ,
25 ∗ ( c o n n i n t e r v a l & 3 ) ,
gap subevent le connection complete get conn latency
( packet ) ) ;
break ;
default :
break ;
}
break ;
case HCI EVENT LE META :
switch ( h c i e v e n t l e m e t a g e t s u b e v e n t c o d e ( p a c k e t ) ) {
case HCI SUBEVENT LE CONNECTION UPDATE COMPLETE :
// p r i n t c o n n e c t i o n p a r a m e t e r s ( w i t h o u t u s i n g f l o a t
operations )
con handle =
hci subevent le connection update complete get connection handle
( packet ) ;
conn interval =
hci subevent le connection update complete get conn interval
( packet ) ;
p r i n t f ( ”− LE Connection 0x%04x : c o n n e c t i o n update −
c o n n e c t i o n i n t e r v a l %u.%02u ms , l a t e n c y %u\n” ,
c o n h a n d l e , c o n n i n t e r v a l ∗ 125 / 1 0 0 ,
25 ∗ ( c o n n i n t e r v a l & 3 ) ,
hci subevent le connection update complete get conn latency
( packet ) ) ;
break ;
case HCI SUBEVENT LE DATA LENGTH CHANGE :
con handle =
hci subevent le data length change get connection handle
( packet ) ;
p r i n t f ( ”− LE Connection 0x%04x : data l e n g t h change − max %
u b y t e s p e r p a c k e t \n” , c o n h a n d l e ,
hci subevent le data length change get max tx octets (
packet ) ) ;
break ;
case HCI SUBEVENT LE PHY UPDATE COMPLETE :
con handle =
hci subevent le phy update complete get connection handle
( packet ) ;
p r i n t f ( ”− LE Connection 0x%04x : PHY update − u s i n g LE %s
PHY now\n” , c o n h a n d l e ,
phy names [
hci subevent le phy update complete get tx phy (
packet ) ] ) ;
break ;
default :
break ;
}
break ;
default :
break ;
}
}
132
0.72.4. ATT Packet Handler. The packet handler is used to track the ATT MTU
Exchange and trigger ATT send
int mtu ;
le streamer connection t ∗ context ;
switch ( p a c k e t t y p e ) {
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 ( p a c k e t ) ) {
case ATT EVENT CONNECTED:
// s e t u p new
context = connection for conn handle (
HCI CON HANDLE INVALID) ;
i f ( ! c o n t e x t ) break ;
c o n t e x t −>c o u n t e r = ’A ’ ;
c o n t e x t −>c o n n e c t i o n h a n d l e =
a t t e v e n t c o n n e c t e d g e t h a n d l e ( packet ) ;
c o n t e x t −>t e s t d a t a l e n = b t s t a c k m i n ( a t t s e r v e r g e t m t u (
c o n t e x t −>c o n n e c t i o n h a n d l e ) − 3 , s i z e o f ( c o n t e x t −>
test data ) ) ;
p r i n t f ( ”%c : ATT connected , h a n d l e 0x%04x , t e s t data l e n %u
\n” , c o n t e x t −>name , c o n t e x t −>c o n n e c t i o n h a n d l e ,
c o n t e x t −>t e s t d a t a l e n ) ;
break ;
case ATT EVENT MTU EXCHANGE COMPLETE:
mtu = a t t e v e n t m t u e x c h a n g e c o m p l e t e g e t M T U ( p a c k e t ) − 3 ;
context = connection for conn handle (
att event mtu exchange complete get handle ( packet ) ) ;
i f ( ! c o n t e x t ) break ;
c o n t e x t −>t e s t d a t a l e n = b t s t a c k m i n ( mtu − 3 , s i z e o f (
c o n t e x t −>t e s t d a t a ) ) ;
p r i n t f ( ”%c : ATT MTU = %u => u s e t e s t data o f l e n %u\n” ,
c o n t e x t −>name , mtu , c o n t e x t −>t e s t d a t a l e n ) ;
break ;
case ATT EVENT CAN SEND NOW:
streamer () ;
break ;
case ATT EVENT DISCONNECTED:
context = connection for conn handle (
a t t e v e n t d i s c o n n e c t e d g e t h a n d l e ( packet ) ) ;
i f ( ! c o n t e x t ) break ;
// f r e e c o n n e c t i o n
p r i n t f ( ”%c : ATT d i s c o n n e c t e d , h a n d l e 0x%04x\n” , c o n t e x t −>
name , c o n t e x t −>c o n n e c t i o n h a n d l e ) ;
c o n t e x t −>l e n o t i f i c a t i o n e n a b l e d = 0 ;
c o n t e x t −>c o n n e c t i o n h a n d l e = HCI CON HANDLE INVALID ;
break ;
default :
break ;
133
}
break ;
default :
break ;
}
}
0.72.5. Streamer. The streamer function checks if notifications are enabled and
if a notification can be sent now. It creates some test data - a single letter that
gets increased every time - and tracks the data sent.
s t a t i c void s t r e a m e r ( void ) {
// f i n d n e x t a c t i v e s t r e a m i n g c o n n e c t i o n
int o l d c o n n e c t i o n i n d e x = c o n n e c t i o n i n d e x ;
while ( 1 ) {
// a c t i v e found ?
i f (( le streamer connections [ connection index ] . connection handle
!= HCI CON HANDLE INVALID) &&
( le streamer connections [ connection index ] .
l e n o t i f i c a t i o n e n a b l e d ) ) break ;
// c h e c k n e x t
next connection index () ;
// none found
i f ( c o n n e c t i o n i n d e x == o l d c o n n e c t i o n i n d e x ) return ;
}
l e s t r e a m e r c o n n e c t i o n t ∗ c o n t e x t = &l e s t r e a m e r c o n n e c t i o n s [
connection index ] ;
// c r e a t e t e s t d a t a
c o n t e x t −>c o u n t e r ++;
i f ( c o n t e x t −>c o u n t e r > ’ Z ’ ) c o n t e x t −>c o u n t e r = ’A ’ ;
memset ( c o n t e x t −>t e s t d a t a , c o n t e x t −>c o u n t e r , c o n t e x t −>
test data len ) ;
// send
a t t s e r v e r n o t i f y ( c o n t e x t −>c o n n e c t i o n h a n d l e , c o n t e x t −>
v a l u e h a n d l e , ( uint8 t ∗ ) c o n t e x t −>t e s t d a t a , c o n t e x t −>
test data len ) ;
// t r a c k
t e s t t r a c k s e n t ( c o n t e x t , c o n t e x t −>t e s t d a t a l e n ) ;
// r e q u e s t n e x t send e v e n t
a t t s e r v e r r e q u e s t c a n s e n d n o w e v e n t ( c o n t e x t −>c o n n e c t i o n h a n d l e ) ;
// c h e c k n e x t
next connection index () ;
}
134
0.72.6. ATT Write. The only valid ATT write in this example is to the Client
Characteristic Configuration, which configures notification and indication. If
the ATT handle matches the client configuration handle, the new configuration
value is stored. If notifications get enabled, an ATT EVENT CAN SEND NOW
is requested. See Listing here.
s t a t i c int a t t w r i t e c a l l b a c k ( h c i c o n h a n d l e t c o n h a n d l e , uint16 t
a t t h a n d l e , uint16 t t r a n s a c t i o n m o d e , uint16 t o f f s e t , uint8 t
∗ b u f f e r , uint16 t b u f f e r s i z e ) {
UNUSED( o f f s e t ) ;
// p r i n t f (” a t t w r i t e c a l l b a c k a t t h a n d l e 0 x%04x , t r a n s a c t i o n mode
%u\n ” , a t t h a n d l e , t r a n s a c t i o n m o d e ) ;
i f ( t r a n s a c t i o n m o d e != ATT TRANSACTION MODE NONE) return 0 ;
le streamer connection t ∗ context = connection for conn handle (
con handle ) ;
switch ( a t t h a n d l e ) {
case
ATT CHARACTERISTIC 0000FF11 0000 1000 8000 00805F9B34FB 01 CLIENT CONFIGURATIO
:
case
ATT CHARACTERISTIC 0000FF12 0000 1000 8000 00805F9B34FB 01 CLIENT CONFIGURATIO
:
c o n t e x t −>l e n o t i f i c a t i o n e n a b l e d = l i t t l e e n d i a n r e a d 1 6 (
b u f f e r , 0 ) ==
GATT CLIENT CHARACTERISTICS CONFIGURATION NOTIFICATION ;
p r i n t f ( ”%c : N o t i f i c a t i o n s e n a b l e d %u\n” , c o n t e x t −>name ,
c o n t e x t −>l e n o t i f i c a t i o n e n a b l e d ) ;
i f ( c o n t e x t −>l e n o t i f i c a t i o n e n a b l e d ) {
switch ( a t t h a n d l e ) {
case
ATT CHARACTERISTIC 0000FF11 0000 1000 8000 00805F9B34FB 01 CLIENT CONFIGU
:
c o n t e x t −>v a l u e h a n d l e =
ATT CHARACTERISTIC 0000FF11 0000 1000 8000 00805F9B34FB 01 VALUE HAND
;
break ;
case
ATT CHARACTERISTIC 0000FF12 0000 1000 8000 00805F9B34FB 01 CLIENT CONFIGU
:
c o n t e x t −>v a l u e h a n d l e =
ATT CHARACTERISTIC 0000FF12 0000 1000 8000 00805F9B34FB 01 VALUE HAND
;
break ;
default :
break ;
}
a t t s e r v e r r e q u e s t c a n s e n d n o w e v e n t ( c o n t e x t −>
connection handle ) ;
}
135
t e s t r e s e t ( context ) ;
break ;
case
ATT CHARACTERISTIC 0000FF11 0000 1000 8000 00805F9B34FB 01 VALUE HANDLE
:
case
ATT CHARACTERISTIC 0000FF12 0000 1000 8000 00805F9B34FB 01 VALUE HANDLE
:
t e s t t r a c k s e n t ( context , b u f f e r s i z e ) ;
break ;
default :
p r i n t f ( ” Write t o 0x%04x , l e n %u\n” , a t t h a n d l e , b u f f e r s i z e ) ;
break ;
}
return 0 ;
}
// s u p p o r t f o r m u l t i p l e c l i e n t s
typedef struct {
char name ;
hci con handle t connection handle ;
uint16 t c i d ;
int c o u n t e r ;
char t e s t d a t a [ TEST PACKET SIZE ] ;
int t e s t d a t a l e n ;
uint32 t t e s t d a t a s e n t ;
uint32 t t e s t d a t a s t a r t ;
} le cbm connection t ;
s t a t i c void t e s t r e s e t ( l e c b m c o n n e c t i o n t ∗ c o n t e x t ) {
c o n t e x t −>t e s t d a t a s t a r t = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
}
s t a t i c void t e s t t r a c k d a t a ( l e c b m c o n n e c t i o n t ∗ c o n t e x t , int
bytes transferred ){
c o n t e x t −>t e s t d a t a s e n t += b y t e s t r a n s f e r r e d ;
// e v a l u a t e
136
uint32 t now = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
uint32 t t i m e p a s s e d = now − c o n t e x t −>t e s t d a t a s t a r t ;
i f ( t i m e p a s s e d < REPORT INTERVAL MS) return ;
// p r i n t s p e e d
int b y t e s p e r s e c o n d = c o n t e x t −>t e s t d a t a s e n t ∗ 1000 /
time passed ;
p r i n t f ( ”%c : %”PRIu32” b y t e s −> %u.%03u kB/ s \n” , c o n t e x t −>name ,
c o n t e x t −>t e s t d a t a s e n t , b y t e s p e r s e c o n d / 1 0 0 0 ,
b y t e s p e r s e c o n d % 1000) ;
// r e s t a r t
c o n t e x t −>t e s t d a t a s t a r t = now ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
}
0.73.2. Streamer. The streamer function checks if notifications are enabled and
if a notification can be sent now. It creates some test data - a single letter that
gets increased every time - and tracks the data sent.
s t a t i c void s t r e a m e r ( void ) {
// c r e a t e t e s t d a t a
l e c b m c o n n e c t i o n . c o u n t e r ++;
i f ( le cbm connection . counter > ’Z ’ ) le cbm connection . counter = ’
A’ ;
memset ( l e c b m c o n n e c t i o n . t e s t d a t a , l e c b m c o n n e c t i o n . c o u n t e r ,
le cbm connection . test data len ) ;
// send
l 2 c a p s e n d ( l e c b m c o n n e c t i o n . c i d , ( uint8 t ∗ ) l e c b m c o n n e c t i o n .
test data , le cbm connection . test data len ) ;
// t r a c k
t e s t t r a c k d a t a (& l e c b m c o n n e c t i o n , l e c b m c o n n e c t i o n .
test data len ) ;
// r e q u e s t a n o t h e r p a c k e t
l2cap request can send now event ( le cbm connection . cid ) ;
}
0.73.3. SM Packet Handler. The packet handler is used to handle pairing re-
quests
s t a t i c void t e s t r e s e t ( l e c b m c o n n e c t i o n t ∗ c o n t e x t ) {
c o n t e x t −>t e s t d a t a s t a r t = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
}
s t a t i c void t e s t t r a c k d a t a ( l e c b m c o n n e c t i o n t ∗ c o n t e x t , int
bytes transferred ){
c o n t e x t −>t e s t d a t a s e n t += b y t e s t r a n s f e r r e d ;
// e v a l u a t e
uint32 t now = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
uint32 t t i m e p a s s e d = now − c o n t e x t −>t e s t d a t a s t a r t ;
i f ( t i m e p a s s e d < REPORT INTERVAL MS) return ;
// p r i n t s p e e d
int b y t e s p e r s e c o n d = c o n t e x t −>t e s t d a t a s e n t ∗ 1000 /
time passed ;
p r i n t f ( ”%c : %”PRIu32” b y t e s s e n t −> %u.%03u kB/ s \n” , c o n t e x t −>name ,
c o n t e x t −>t e s t d a t a s e n t , b y t e s p e r s e c o n d / 1 0 0 0 ,
b y t e s p e r s e c o n d % 1000) ;
// r e s t a r t
c o n t e x t −>t e s t d a t a s t a r t = now ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
}
0.74.2. Streamer. The streamer function checks if notifications are enabled and
if a notification can be sent now. It creates some test data - a single letter that
gets increased every time - and tracks the data sent.
s t a t i c void s t r e a m e r ( void ) {
i f ( l e c b m c o n n e c t i o n . c i d == 0 ) return ;
// c r e a t e t e s t d a t a
l e c b m c o n n e c t i o n . c o u n t e r ++;
i f ( le cbm connection . counter > ’Z ’ ) le cbm connection . counter = ’
A’ ;
memset ( l e c b m c o n n e c t i o n . t e s t d a t a , l e c b m c o n n e c t i o n . c o u n t e r ,
le cbm connection . test data len ) ;
// send
l 2 c a p s e n d ( l e c b m c o n n e c t i o n . c i d , ( uint8 t ∗ ) l e c b m c o n n e c t i o n .
test data , le cbm connection . test data len ) ;
// t r a c k
t e s t t r a c k d a t a (& l e c b m c o n n e c t i o n , l e c b m c o n n e c t i o n .
test data len ) ;
138
// r e q u e s t a n o t h e r p a c k e t
l2cap request can send now event ( le cbm connection . cid ) ;
}
0.74.3. HCI + L2CAP Packet Handler. The packet handler is used to stop the
notifications and reset the MTU on connect It would also be a good place to
request the connection parameter update as indicated in the commented code
block.
0.74.4. SM Packet Handler.
0.74.5. Main Application Setup.
0.75. Performance - Stream Data over SPP (Client). Source Code: spp streamer client.c
The packet handler is used to handle pairing requests
Listing here shows main application code. It initializes L2CAP, the Security
Manager, and configures the ATT Server with the pre-compiled ATT Database
generated from lec reditb asedf lowc ontrolm odes erver.gatt. Finally, it configures
the advertisements and boots the Bluetooth stack.
Note: The SPP Streamer Client scans for and connects to SPP Streamer, and
measures the throughput.
0.75.1. Track throughput. We calculate the throughput by setting a start time
and measuring the amount of data sent. After a configurable REPORT INTERVAL MS,
we print the throughput in kB/s and reset the counter and start time.
s t a t i c void t e s t r e s e t ( void ) {
test data start = btstack run loop get time ms () ;
test data transferred = 0;
}
s t a t i c void t e s t t r a c k t r a n s f e r r e d ( int b y t e s s e n t ) {
t e s t d a t a t r a n s f e r r e d += b y t e s s e n t ;
// e v a l u a t e
uint32 t now = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
uint32 t t i m e p a s s e d = now − t e s t d a t a s t a r t ;
i f ( t i m e p a s s e d < REPORT INTERVAL MS) return ;
// p r i n t s p e e d
int b y t e s p e r s e c o n d = t e s t d a t a t r a n s f e r r e d ∗ 1000 / t i m e p a s s e d ;
p r i n t f ( ”%u b y t e s −> %u.%03u kB/ s \n” , ( int ) t e s t d a t a t r a n s f e r r e d ,
( int ) b y t e s p e r s e c o n d / 1 0 0 0 , b y t e s p e r s e c o n d % 1 0 0 0 ) ;
// r e s t a r t
t e s t d a t a s t a r t = now ;
test data transferred = 0;
}
139
0.75.2. SDP Query Packet Handler. Store RFCOMM Channel for SPP service
and initiates RFCOMM connection
0.75.4. Main Application Setup. As with the packet and the heartbeat handlers,
the combined app setup contains the code from the individual example setups.
l2cap init () ;
#i f d e f ENABLE BLE
// I n i t i a l i z e LE S e c u r i t y Manager . Needed f o r c r o s s −t r a n s p o r t key
derivation
sm init () ;
#endif
rfcomm init () ;
// r e g i s t e r f o r HCI e v e n t s
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
// i n i t SDP
g a p s s p s e t i o c a p a b i l i t y ( SSP IO CAPABILITY DISPLAY YES NO ) ;
// t u r n on !
h c i p o w e r c o n t r o l (HCI POWER ON) ;
return 0 ;
}
0.76. Performance - Stream Data over SPP (Server). Source Code: spp streamer.c
After RFCOMM connections gets open, request a RFCOMM EVENT CAN SEND NOW
via rfcomm request can send now event().
When we get the RFCOMM EVENT CAN SEND NOW, send data and re-
quest another one.
Note: To test, run the example, pair from a remote device, and open the
Virtual Serial Port.
140
s t a t i c void t e s t r e s e t ( void ) {
test data start = btstack run loop get time ms () ;
test data transferred = 0;
}
s t a t i c void t e s t t r a c k t r a n s f e r r e d ( int b y t e s s e n t ) {
t e s t d a t a t r a n s f e r r e d += b y t e s s e n t ;
// e v a l u a t e
uint32 t now = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
uint32 t t i m e p a s s e d = now − t e s t d a t a s t a r t ;
i f ( t i m e p a s s e d < REPORT INTERVAL MS) return ;
// p r i n t s p e e d
int b y t e s p e r s e c o n d = t e s t d a t a t r a n s f e r r e d ∗ 1000 / t i m e p a s s e d ;
p r i n t f ( ”%u b y t e s −> %u.%03u kB/ s \n” , ( int ) t e s t d a t a t r a n s f e r r e d ,
( int ) b y t e s p e r s e c o n d / 1 0 0 0 , b y t e s p e r s e c o n d % 1 0 0 0 ) ;
// r e s t a r t
t e s t d a t a s t a r t = now ;
test data transferred = 0;
}
0.76.2. Packet Handler. The packet handler of the combined example is just the
combination of the individual packet handlers.
0.76.3. Main Application Setup. As with the packet and the heartbeat handlers,
the combined app setup contains the code from the individual example setups.
l2cap init () ;
#i f d e f ENABLE BLE
// I n i t i a l i z e LE S e c u r i t y Manager . Needed f o r c r o s s −t r a n s p o r t key
derivation
sm init () ;
#endif
rfcomm init () ;
141
// r e g i s t e r f o r HCI e v e n t s
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
// s h o r t −c u t t o f i n d o t h e r SPP Streamer
g a p s e t c l a s s o f d e v i c e (TEST COD) ;
// t u r n on !
h c i p o w e r c o n t r o l (HCI POWER ON) ;
return 0 ;
}
0.77. A2DP Sink - Receive Audio Stream and Control Playback. Source
Code: a2dp sink demo.c
This A2DP Sink example demonstrates how to use the A2DP Sink service to
receive an audio data stream from a remote A2DP Source device. In addition,
the AVRCP Controller is used to get information on currently played media, such
are title, artist and album, as well as to control the playback, i.e. to play, stop,
repeat, etc. If HAVE BTSTACK STDIN is set, press SPACE on the console to
show the available AVDTP and AVRCP commands.
To test with a remote device, e.g. a mobile phone, pair from the remote device
with the demo, then start playing music on the remote device. Alternatively,
set the device addr string to the Bluetooth address of your remote device in the
code, and call connect from the UI.
142
For more info on BTstack audio, see our blog post A2DP Sink and Source on
STM32 F4 Discovery Board.
0.77.1. Main Application Setup. The Listing here shows how to set up AD2P
Sink and AVRCP services. Besides calling init() method for each service, you’ll
also need to register several packet handlers:
• hci packet handler - handles legacy pairing, here by using fixed ‘0000’ pin
code.
• a2dp sink packet handler - handles events on stream connection status
(established, released), the media codec configuration, and, the status of
the stream itself (opened, paused, stopped).
• handle l2cap media data packet - used to receive streaming data. If STORE TO WAV FILE
directive (check btstack config.h) is used, the SBC decoder will be used
to decode the SBC data into PCM frames. The resulting PCM frames
are then processed in the SBC Decoder callback.
• avrcp packet handler - receives AVRCP connect/disconnect event.
• avrcp controller packet handler - receives answers for sent AVRCP com-
mands.
• avrcp target packet handler - receives AVRCP commands, and registered
notifications.
• stdin process - used to trigger AVRCP commands to the A2DP Source
device, such are get now playing info, start, stop, volume control. Re-
quires HAVE BTSTACK STDIN.
To announce A2DP Sink and AVRCP services, you need to create
corresponding SDP records and register them with the SDP service.
Note, currently only the SBC codec is supported. If you want to store
the audio data in a file, you’ll need to define STORE TO WAV FILE. If
STORE TO WAV FILE directive is defined, the SBC decoder needs to
get initialized when a2dp sink packet handler receives event A2DP SUBEVENT STREAM S
The initialization of the SBC decoder requires a callback that handles
PCM data:
• handle pcm data - handles PCM audio frames. Here, they are stored in
a wav file if STORE TO WAV FILE is defined, and/or played using the
audio library.
// i n i t p r o t o c o l s
l2cap init () ;
sdp init () ;
#i f d e f ENABLE BLE
// I n i t i a l i z e LE S e c u r i t y Manager . Needed f o r c r o s s −t r a n s p o r t key
derivation
sm init () ;
#endif
#i f d e f ENABLE AVRCP COVER ART
goep client init () ;
avrcp cover art client init () ;
#endif
// I n i t p r o f i l e s
a2dp sink init () ;
avrcp init () ;
avrcp controller init () ;
avrcp target init () ;
// C o n f i g u r e A2DP S i n k
a 2 d p s i n k r e g i s t e r p a c k e t h a n d l e r (& a 2 d p s i n k p a c k e t h a n d l e r ) ;
a 2 d p s i n k r e g i s t e r m e d i a h a n d l e r (& h a n d l e l 2 c a p m e d i a d a t a p a c k e t ) ;
a2dp sink demo stream endpoint t ∗ stream endpoint = &
a2dp sink demo stream endpoint ;
avdtp stream endpoint t ∗ local stream endpoint =
a 2 d p s i n k c r e a t e s t r e a m e n d p o i n t (AVDTP AUDIO,
AVDTP CODEC SBC,
media sbc codec capabilities
, sizeof (
media sbc codec capabilities
),
s t r e a m e n d p o i n t −>
media sbc codec configuration
, sizeof (
s t r e a m e n d p o i n t −>
media sbc codec configuration
));
b t s t a c k a s s e r t ( l o c a l s t r e a m e n d p o i n t != NULL) ;
// − S t o r e stream e n p o i n t ’ s SEP ID , as i t i s used by A2DP API t o
i d e n t i f y t h e stream e n d p o i n t
s t r e a m e n d p o i n t −>a 2 d p l o c a l s e i d = a v d t p l o c a l s e i d (
local stream endpoint ) ;
// C o n f i g u r e AVRCP C o n t r o l l e r + Ta r g e t
a v r c p r e g i s t e r p a c k e t h a n d l e r (& a v r c p p a c k e t h a n d l e r ) ;
a v r c p c o n t r o l l e r r e g i s t e r p a c k e t h a n d l e r (&
avrcp controller packet handler ) ;
144
a v r c p t a r g e t r e g i s t e r p a c k e t h a n d l e r (& a v r c p t a r g e t p a c k e t h a n d l e r )
;
// C o n f i g u r e SDP
// − C r e a t e and r e g i s t e r A2DP S i n k s e r v i c e r e c o r d
memset ( s d p a v d t p s i n k s e r v i c e b u f f e r , 0 , s i z e o f (
sdp avdtp sink service buffer ) ) ;
a2dp sink create sdp record ( sdp avdtp sink service buffer ,
sdp create service record handle () ,
AVDTP SINK FEATURE MASK HEADPHONE, NULL, NULL) ;
b t s t a c k a s s e r t ( d e g e t l e n ( s d p a v d t p s i n k s e r v i c e b u f f e r ) <=
sizeof ( sdp avdtp sink service buffer ) ) ;
sdp register service ( sdp avdtp sink service buffer ) ;
// − C r e a t e AVRCP C o n t r o l l e r s e r v i c e r e c o r d and r e g i s t e r i t w i t h
SDP. We send C a t e g o r y 1 commands t o t h e media p l a y e r , e . g .
p l a y / pause
memset ( s d p a v r c p c o n t r o l l e r s e r v i c e b u f f e r , 0 , s i z e o f (
sdp avrcp controller service buffer )) ;
uint16 t c o n t r o l l e r s u p p o r t e d f e a t u r e s = 1 <<
AVRCP CONTROLLER SUPPORTED FEATURE CATEGORY PLAYER OR RECORDER
;
#i f d e f AVRCP BROWSING ENABLED
c o n t r o l l e r s u p p o r t e d f e a t u r e s |= 1 <<
AVRCP CONTROLLER SUPPORTED FEATURE BROWSING;
#endif
#i f d e f ENABLE AVRCP COVER ART
c o n t r o l l e r s u p p o r t e d f e a t u r e s |= 1 <<
AVRCP CONTROLLER SUPPORTED FEATURE COVER ART GET LINKED THUMBNAIL
;
#endif
avrcp controller create sdp record (
sdp avrcp controller service buffer ,
sdp create service record handle () ,
c o n t r o l l e r s u p p o r t e d f e a t u r e s , NULL, NULL) ;
b t s t a c k a s s e r t ( d e g e t l e n ( s d p a v r c p c o n t r o l l e r s e r v i c e b u f f e r ) <=
sizeof ( s d p a v r c p c o n t r o l l e r s e r v i c e b u f f e r ) ) ;
sdp register service ( sdp avrcp controller service buffer ) ;
// − C r e a t e and r e g i s t e r A2DP S i n k s e r v i c e r e c o r d
// − We r e c e i v e C a t e g o r y 2 commands from t h e media p l a y e r , e . g .
volume up/down
memset ( s d p a v r c p t a r g e t s e r v i c e b u f f e r , 0 , s i z e o f (
sdp avrcp target service buffer ) ) ;
uint16 t t a r g e t s u p p o r t e d f e a t u r e s = 1 <<
AVRCP TARGET SUPPORTED FEATURE CATEGORY MONITOR OR AMPLIFIER;
avrcp target create sdp record ( sdp avrcp target service buffer ,
sdp create service record handle () ,
t a r g e t s u p p o r t e d f e a t u r e s , NULL, NULL) ;
b t s t a c k a s s e r t ( d e g e t l e n ( s d p a v r c p t a r g e t s e r v i c e b u f f e r ) <=
sizeof ( s d p a v r c p t a r g e t s e r v i c e b u f f e r ) ) ;
sdp register service ( sdp avrcp target service buffer ) ;
145
// − C r e a t e and r e g i s t e r D ev i c e ID (PnP) s e r v i c e r e c o r d
memset ( d e v i c e i d s d p s e r v i c e b u f f e r , 0 , s i z e o f (
device id sdp service buffer )) ;
device id create sdp record ( device id sdp service buffer ,
sdp create service record handle () ,
DEVICE ID VENDOR ID SOURCE BLUETOOTH,
BLUETOOTH COMPANY ID BLUEKITCHEN GMBH, 1 , 1 ) ;
b t s t a c k a s s e r t ( d e g e t l e n ( d e v i c e i d s d p s e r v i c e b u f f e r ) <= s i z e o f
( device id sdp service buffer )) ;
sdp register service ( device id sdp service buffer ) ;
// C o n f i g u r e GAP − d i s c o v e r y / c o n n e c t i o n
// − S e t l o c a l name w i t h a t e m p l a t e B l u e t o o t h a d d r e s s , t h a t w i l l
be a u t o m a t i c a l l y
// r e p l a c e d w i t h an a c t u a l a d d r e s s once i t i s a v a i l a b l e , i . e .
when BTstack b o o t s
// up and s t a r t s t a l k i n g t o a B l u e t o o t h module .
g a p s e t l o c a l n a m e ( ”A2DP Sink Demo 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 ” ) ;
// − Allow t o show up i n B l u e t o o t h i n q u i r y
gap discoverable control (1) ;
// − S e t C l a s s o f D e vi c e − S e r v i c e C l a s s : Audio , Major D e vi c e
C l a s s : Audio , Minor : Headphone
g a p s e t c l a s s o f d e v i c e ( 0 x200404 ) ;
// − Allow f o r r o l e s w i t c h on o u t g o i n g c o n n e c t i o n s
// − This a l l o w s A2DP Source , e . g . smartphone , t o become master
when we re−c o n n e c t t o i t .
gap set allow role switch ( true ) ;
// R e g i s t e r f o r HCI e v e n t s
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &h c i p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
// Inform a b o u t a u d i o p l a y b a c k / t e s t o p t i o n s
#i f d e f HAVE POSIX FILE IO
if (! btstack audio sink get instance () ){
p r i n t f ( ”No a u d i o p l a y b a c k . \ n” ) ;
} else {
p r i n t f ( ” Audio p l a y b a c k s u p p o r t e d . \ n” ) ;
}
#i f d e f STORE TO WAV FILE
p r i n t f ( ” Audio w i l l be s t o r e d t o \’% s \ ’ f i l e . \ n” , wav filename ) ;
#endif
146
#endif
return 0 ;
}
0.77.2. Handle Media Data Packet. Here the audio data, are received through
the handle l2cap media data packet callback. Currently, only the SBC media
codec is supported. Hence, the media data consists of the media packet header
and the SBC packet. The SBC frame will be stored in a ring buffer for later
processing (instead of decoding it to PCM right away which would require a
much larger buffer). If the audio stream wasn’t started already and there are
enough SBC frames in the ring buffer, start playback.
0.78. A2DP Source - Stream Audio and Control Volume. Source Code:
a2dp source demo.c
This A2DP Source example demonstrates how to send an audio data stream to
a remote A2DP Sink device and how to switch between two audio data sources.
In addition, the AVRCP Target is used to answer queries on currently played
media, as well as to handle remote playback control, i.e. play, stop, repeat, etc.
If HAVE BTSTACK STDIN is set, press SPACE on the console to show the
available AVDTP and AVRCP commands.
To test with a remote device, e.g. a Bluetooth speaker, set the device addr string
to the Bluetooth address of your remote device in the code, and use the UI to
connect and start playback.
For more info on BTstack audio, see our blog post A2DP Sink and Source on
STM32 F4 Discovery Board.
0.78.1. Main Application Setup. The Listing here shows how to setup AD2P
Source and AVRCP services. Besides calling init() method for each service,
you’ll also need to register several packet handlers:
• hci packet handler - handles legacy pairing, here by using fixed ‘0000’ pin
code.
• a2dp source packet handler - handles events on stream connection sta-
tus (established, released), the media codec configuration, and, the com-
mands on stream itself (open, pause, stopp).
• avrcp packet handler - receives connect/disconnect event.
• avrcp controller packet handler - receives answers for sent AVRCP com-
mands.
• avrcp target packet handler - receives AVRCP commands, and registered
notifications.
• stdin process - used to trigger AVRCP commands to the A2DP Source
device, such are get now playing info, start, stop, volume control. Re-
quires HAVE BTSTACK STDIN.
To announce A2DP Source and AVRCP services, you need to create
corresponding SDP records and register them with the SDP service.
147
s t a t i c void a 2 d p d e m o h e x c m o d c o n f i g u r e s a m p l e r a t e ( int s a m p l e r a t e )
;
s t a t i c int a 2 d p s o u r c e a n d a v r c p s e r v i c e s i n i t ( void ) {
l2cap init () ;
#i f d e f ENABLE BLE
// I n i t i a l i z e LE S e c u r i t y Manager . Needed f o r c r o s s −t r a n s p o r t key
derivation
sm init () ;
#endif
// I n i t i a l i z e A2DP Source
a2dp source init () ;
a 2 d p s o u r c e r e g i s t e r p a c k e t h a n d l e r (& a 2 d p s o u r c e p a c k e t h a n d l e r ) ;
// C r e a t e stream e n d p o i n t
avdtp stream endpoint t ∗ local stream endpoint =
a 2 d p s o u r c e c r e a t e s t r e a m e n d p o i n t (AVDTP AUDIO,
AVDTP CODEC SBC, m e d i a s b c c o d e c c a p a b i l i t i e s , s i z e o f (
media sbc codec capabilities ) , media sbc codec configuration ,
sizeof ( media sbc codec configuration ) ) ;
if (! local stream endpoint ){
p r i n t f ( ”A2DP S o u r c e : not enough memory t o c r e a t e l o c a l stream
e n d p o i n t \n” ) ;
return 1 ;
}
// I n i t i a l i z e AVRCP S e r v i c e
avrcp init () ;
a v r c p r e g i s t e r p a c k e t h a n d l e r (& a v r c p p a c k e t h a n d l e r ) ;
// I n i t i a l i z e AVRCP T a r g et
avrcp target init () ;
a v r c p t a r g e t r e g i s t e r p a c k e t h a n d l e r (& a v r c p t a r g e t p a c k e t h a n d l e r )
;
// I n i t i a l i z e AVRCP C o n t r o l l e r
avrcp controller init () ;
a v r c p c o n t r o l l e r r e g i s t e r p a c k e t h a n d l e r (&
avrcp controller packet handler ) ;
// I n i t i a l i z e SDP,
sdp init () ;
uint16 t c o n t r o l l e r s u p p o r t e d f e a t u r e s =
AVRCP FEATURE MASK CATEGORY MONITOR OR AMPLIFIER;
avrcp controller create sdp record (
sdp avrcp controller service buffer ,
sdp create service record handle () ,
c o n t r o l l e r s u p p o r t e d f e a t u r e s , NULL, NULL) ;
b t s t a c k a s s e r t ( d e g e t l e n ( s d p a v r c p c o n t r o l l e r s e r v i c e b u f f e r ) <=
sizeof ( s d p a v r c p c o n t r o l l e r s e r v i c e b u f f e r ) ) ;
sdp register service ( sdp avrcp controller service buffer ) ;
// R e g i s t e r D e v i ce ID (PnP) s e r v i c e SDP r e c o r d
memset ( d e v i c e i d s d p s e r v i c e b u f f e r , 0 , s i z e o f (
device id sdp service buffer )) ;
device id create sdp record ( device id sdp service buffer ,
sdp create service record handle () ,
DEVICE ID VENDOR ID SOURCE BLUETOOTH,
BLUETOOTH COMPANY ID BLUEKITCHEN GMBH, 1 , 1 ) ;
b t s t a c k a s s e r t ( d e g e t l e n ( d e v i c e i d s d p s e r v i c e b u f f e r ) <= s i z e o f
( device id sdp service buffer )) ;
sdp register service ( device id sdp service buffer ) ;
// S e t l o c a l name w i t h a t e m p l a t e B l u e t o o t h a d d r e s s , t h a t w i l l be
automatically
// r e p l a c e d w i t h a a c t u a l a d d r e s s once i t i s a v a i l a b l e , i . e . when
BTstack b o o t s
// up and s t a r t s t a l k i n g t o a B l u e t o o t h module .
g a p s e t l o c a l n a m e ( ”A2DP S o u r c e 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 ” ) ;
gap discoverable control (1) ;
g a p s e t c l a s s o f d e v i c e ( 0 x200408 ) ;
// R e g i s t e r f o r HCI e v e n t s .
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &h c i p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
d a t a s o u r c e = STREAM MOD;
// Parse human r e a d a b l e B l u e t o o t h a d d r e s s .
sscanf bd addr ( device addr string , device addr ) ;
set, press SPACE on the console to show the available AVDTP and AVRCP
commands.
0.79.1. Main Application Setup. The Listing here shows how to setup AVRCP
Controller Browsing service. To announce AVRCP Controller Browsing service,
you need to create corresponding SDP record and register it with the SDP service.
You’ll also need to register several packet handlers:
• stdin process callback - used to trigger AVRCP commands, such are get
media players, playlists, albums, etc. Requires HAVE BTSTACK STDIN.
• avrcp browsing controller packet handler - used to receive answers for
AVRCP commands.
s t a t i c void a v r c p b r o w s i n g c o n t r o l l e r p a c k e t h a n d l e r ( uint8 t
p a c k e t t y p e , uint16 t channel , uint8 t ∗ packet , uint16 t s i z e ) ;
s t a t i c void a v r c p p a c k e t h a n d l e r ( uint8 t p a c k e t t y p e , uint16 t
channel , uint8 t ∗ packet , uint16 t s i z e ) ;
s t a t i c void a 2 d p s i n k p a c k e t h a n d l e r ( uint8 t p a c k e t t y p e , uint16 t
channel , uint8 t ∗ packet , uint16 t s i z e ) ;
// I n i t i a l i z e L2CAP .
l2cap init () ;
#i f d e f ENABLE BLE
// I n i t i a l i z e LE S e c u r i t y Manager . Needed f o r c r o s s −t r a n s p o r t key
derivation
sm init () ;
#endif
// I n i t i a l i z e AVRCP s e r v i c e .
avrcp init () ;
// I n i t i a l i z e AVRCP C o n t r o l l e r & T ar g e t S e r v i c e .
avrcp controller init () ;
avrcp target init () ;
a v r c p r e g i s t e r p a c k e t h a n d l e r (& a v r c p p a c k e t h a n d l e r ) ;
a v r c p c o n t r o l l e r r e g i s t e r p a c k e t h a n d l e r (& a v r c p p a c k e t h a n d l e r ) ;
a v r c p t a r g e t r e g i s t e r p a c k e t h a n d l e r (& a v r c p p a c k e t h a n d l e r ) ;
// I n i t i a l i z e AVRCP Browsing S e r v i c e .
avrcp browsing init () ;
avrcp browsing controller init () ;
avrcp browsing target init () ;
// R e g i s t e r f o r HCI e v e n t s .
a v r c p b r o w s i n g c o n t r o l l e r r e g i s t e r p a c k e t h a n d l e r (&
avrcp browsing controller packet handler ) ;
a v r c p b r o w s i n g t a r g e t r e g i s t e r p a c k e t h a n d l e r (&
avrcp browsing controller packet handler ) ;
a v r c p b r o w s i n g r e g i s t e r p a c k e t h a n d l e r (&
avrcp browsing controller packet handler ) ;
// I n i t i a l i z e SDP.
sdp init () ;
// s e t u p AVDTP s i n k
memset ( s d p a v d t p s i n k s e r v i c e b u f f e r , 0 , s i z e o f (
sdp avdtp sink service buffer ) ) ;
a2dp sink create sdp record ( sdp avdtp sink service buffer ,
sdp create service record handle () ,
AVDTP SINK FEATURE MASK HEADPHONE, NULL, NULL) ;
b t s t a c k a s s e r t ( d e g e t l e n ( s d p a v d t p s i n k s e r v i c e b u f f e r ) <=
sizeof ( sdp avdtp sink service buffer ) ) ;
sdp register service ( sdp avdtp sink service buffer ) ;
uint16 t s u p p o r t e d f e a t u r e s =
AVRCP FEATURE MASK CATEGORY PLAYER OR RECORDER;
#i f d e f AVRCP BROWSING ENABLED
s u p p o r t e d f e a t u r e s |= AVRCP FEATURE MASK BROWSING;
#endif
avrcp controller create sdp record (
sdp avrcp browsing controller service buffer ,
s d p c r e a t e s e r v i c e r e c o r d h a n d l e ( ) , s u p p o r t e d f e a t u r e s , NULL,
NULL) ;
btstack assert ( de get len (
s d p a v r c p b r o w s i n g c o n t r o l l e r s e r v i c e b u f f e r ) <= s i z e o f (
sdp avrcp browsing controller service buffer ) ) ;
152
// S e t l o c a l name w i t h a t e m p l a t e B l u e t o o t h a d d r e s s , t h a t w i l l be
automatically
// r e p l a c e d w i t h a a c t u a l a d d r e s s once i t i s a v a i l a b l e , i . e . when
BTstack b o o t s
// up and s t a r t s t a l k i n g t o a B l u e t o o t h module .
g a p s e t l o c a l n a m e ( ”AVRCP Browsing C l i e n t 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 ” ) ;
gap discoverable control (1) ;
g a p s e t c l a s s o f d e v i c e ( 0 x200408 ) ;
// R e g i s t e r f o r HCI e v e n t s .
hci event callback registration . callback = &
avrcp browsing controller packet handler ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
g a p s e t l o c a l n a m e ( ”HFP AG Demo 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 ” ) ;
gap discoverable control (1) ;
// L2CAP
l2cap init () ;
#i f d e f ENABLE BLE
// I n i t i a l i z e LE S e c u r i t y Manager . Needed f o r c r o s s −t r a n s p o r t key
derivation
sm init () ;
#endif
uint16 t s u p p o r t e d f e a t u r e s =
(1<<HFP AGSF ESCO S4 ) |
(1<<HFP AGSF HF INDICATORS) |
(1<<HFP AGSF CODEC NEGOTIATION) |
(1<<HFP AGSF EXTENDED ERROR RESULT CODES) |
(1<<HFP AGSF ENHANCED CALL CONTROL) |
(1<<HFP AGSF ENHANCED CALL STATUS) |
(1<<HFP AGSF ABILITY TO REJECT A CALL) |
(1<<HFP AGSF IN BAND RING TONE) |
(1<<HFP AGSF VOICE RECOGNITION FUNCTION) |
(1<<HFP AGSF ENHANCED VOICE RECOGNITION STATUS) |
(1<<HFP AGSF VOICE RECOGNITION TEXT) |
(1<<HFP AGSF EC NR FUNCTION) |
(1<<HFP AGSF THREE WAY CALLING) ;
// HFP
rfcomm init () ;
h f p a g i n i t ( rfcomm channel nr ) ;
hfp ag init supported features ( supported features ) ;
h f p a g i n i t c o d e c s ( sizeof ( codecs ) , codecs ) ;
hfp ag init ag indicators ( ag indicators nr , ag indicators ) ;
hfp ag init hf indicators ( hf indicators nr , hf indicators ) ;
hfp ag init call hold services ( call hold services nr ,
call hold services ) ;
h f p a g s e t s u b c r i b e r n u m b e r i n f o r m a t i o n (& s u b s c r i b e r n u m b e r , 1 ) ;
// SDP S e r v e r
sdp init () ;
memset ( h f p s e r v i c e b u f f e r , 0 , s i z e o f ( h f p s e r v i c e b u f f e r ) ) ;
hfp ag create sdp record with codecs ( hfp service buffer ,
sdp create service record handle () ,
r fc om m c ha nn el nr , h f p a g s e r v i c e n a m e , 0 ,
supported features , sizeof ( codecs ) , codecs
);
b t s t a c k a s s e r t ( d e g e t l e n ( h f p s e r v i c e b u f f e r ) <= s i z e o f (
hfp service buffer )) ;
sdp register service ( hfp service buffer ) ;
// r e g i s t e r f o r HFP e v e n t s
h f p a g r e g i s t e r p a c k e t h a n d l e r (& p a c k e t h a n d l e r ) ;
// p a r s e human r e a d a b l e B l u e t o o t h a d d r e s s
sscanf bd addr ( device addr string , device addr ) ;
// I n i t p r o t o c o l s
// i n i t L2CAP
l2cap init () ;
rfcomm init () ;
sdp init () ;
#i f d e f ENABLE BLE
// I n i t i a l i z e LE S e c u r i t y Manager . Needed f o r c r o s s −t r a n s p o r t key
derivation
sm init () ;
#endif
// I n i t p r o f i l e s
uint16 t h f s u p p o r t e d f e a t u r e s =
(1<<HFP HFSF ESCO S4 ) |
(1<<HFP HFSF CLI PRESENTATION CAPABILITY) |
(1<<HFP HFSF HF INDICATORS) |
(1<<HFP HFSF CODEC NEGOTIATION) |
(1<<HFP HFSF ENHANCED CALL STATUS) |
(1<<HFP HFSF VOICE RECOGNITION FUNCTION) |
155
h f p h f i n i t ( rfcomm channel nr ) ;
hfp hf init supported features ( hf supported features ) ;
h f p h f i n i t h f i n d i c a t o r s ( s i z e o f ( i n d i c a t o r s ) / s i z e o f ( uint16 t ) ,
indicators ) ;
h f p h f i n i t c o d e c s ( sizeof ( codecs ) , codecs ) ;
hfp hf register packet handler ( hfp hf packet handler ) ;
// C o n f i g u r e SDP
// − C r e a t e and r e g i s t e r HFP HF s e r v i c e r e c o r d
memset ( h f p s e r v i c e b u f f e r , 0 , s i z e o f ( h f p s e r v i c e b u f f e r ) ) ;
hfp hf create sdp record with codecs ( hfp service buffer ,
sdp create service record handle () ,
rf c om m c ha nn el n r , h f p h f s e r v i c e n a m e ,
hf supported features , sizeof ( codecs ) , codecs ) ;
b t s t a c k a s s e r t ( d e g e t l e n ( h f p s e r v i c e b u f f e r ) <= s i z e o f (
hfp service buffer )) ;
sdp register service ( hfp service buffer ) ;
// C o n f i g u r e GAP − d i s c o v e r y / c o n n e c t i o n
// − S e t l o c a l name w i t h a t e m p l a t e B l u e t o o t h a d d r e s s , t h a t w i l l
be a u t o m a t i c a l l y
// r e p l a c e d w i t h an a c t u a l a d d r e s s once i t i s a v a i l a b l e , i . e .
when BTstack b o o t s
// up and s t a r t s t a l k i n g t o a B l u e t o o t h module .
g a p s e t l o c a l n a m e ( ”HFP HF Demo 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 ” ) ;
// − Allow t o show up i n B l u e t o o t h i n q u i r y
gap discoverable control (1) ;
// − S e t C l a s s o f D e vi c e − S e r v i c e C l a s s : Audio , Major D e vi c e
C l a s s : Audio , Minor : Hands−Free d e v i c e
g a p s e t c l a s s o f d e v i c e ( 0 x200408 ) ;
// − Allow f o r r o l e s w i t c h on o u t g o i n g c o n n e c t i o n s − t h i s a l l o w s
HFP AG, e . g . smartphone , t o become master when we re−c o n n e c t
to i t
gap set allow role switch ( true ) ;
h c i r e g i s t e r s c o p a c k e t h a n d l e r (& h c i p a c k e t h a n d l e r ) ;
// I n i t SCO / HFP a u d i o p r o c e s s i n g
sco demo init () ;
// t u r n on !
h c i p o w e r c o n t r o l (HCI POWER ON) ;
return 0 ;
}
l2cap init () ;
#i f d e f ENABLE BLE
// I n i t i a l i z e LE S e c u r i t y Manager . Needed f o r c r o s s −t r a n s p o r t key
derivation
sm init () ;
#endif
sdp init () ;
memset ( ( uint8 t ∗ ) h s p s e r v i c e b u f f e r , 0 , s i z e o f ( h s p s e r v i c e b u f f e r
));
hsp ag create sdp record ( hsp service buffer ,
s d p c r e a t e s e r v i c e r e c o r d h a n d l e ( ) , rf c om m c ha nn el n r ,
hsp ag service name ) ;
b t s t a c k a s s e r t ( d e g e t l e n ( h s p s e r v i c e b u f f e r ) <= s i z e o f (
hsp service buffer ) ) ;
sdp register service ( hsp service buffer ) ;
rfcomm init () ;
h s p a g i n i t ( rfcomm channel nr ) ;
h s p a g r e g i s t e r p a c k e t h a n d l e r (& p a c k e t h a n d l e r ) ;
// r e g i s t e r f o r SCO p a c k e t s
h c i r e g i s t e r s c o p a c k e t h a n d l e r (& p a c k e t h a n d l e r ) ;
// p a r s e human r e a d a b l e B l u e t o o t h a d d r e s s
sscanf bd addr ( device addr string , device addr ) ;
// t u r n on !
h c i p o w e r c o n t r o l (HCI POWER ON) ;
return 0 ;
}
l2cap init () ;
#i f d e f ENABLE BLE
// I n i t i a l i z e LE S e c u r i t y Manager . Needed f o r c r o s s −t r a n s p o r t key
derivation
sm init () ;
#endif
sdp init () ;
memset ( h s p s e r v i c e b u f f e r , 0 , s i z e o f ( h s p s e r v i c e b u f f e r ) ) ;
hsp hs create sdp record ( hsp service buffer ,
s d p c r e a t e s e r v i c e r e c o r d h a n d l e ( ) , rf c om m c ha nn el n r ,
hsp hs service name , 0) ;
b t s t a c k a s s e r t ( d e g e t l e n ( h s p s e r v i c e b u f f e r ) <= s i z e o f (
hsp service buffer ) ) ;
sdp register service ( hsp service buffer ) ;
rfcomm init () ;
h s p h s i n i t ( rfcomm channel nr ) ;
// r e g i s t e r f o r HSP e v e n t s
hsp hs register packet handler ( packet handler ) ;
159
// Parse human r e a d a b l e B l u e t o o t h a d d r e s s .
sscanf bd addr ( device addr string , device addr ) ;
// t u r n on !
h c i p o w e r c o n t r o l (HCI POWER ON) ;
return 0 ;
}
s t a t i c void s p p s e r v i c e s e t u p ( void ) {
// r e g i s t e r f o r HCI e v e n t s
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
160
l2cap init () ;
#i f d e f ENABLE BLE
// I n i t i a l i z e LE S e c u r i t y Manager . Needed f o r c r o s s −t r a n s p o r t key
derivation
sm init () ;
#endif
rfcomm init () ;
r f c o m m r e g i s t e r s e r v i c e ( p a c k e t h a n d l e r , RFCOMM SERVER CHANNEL, 0
x f f f f ) ; // r e s e r v e d channel , mtu l i m i t e d by l 2 c a p
0.87.2. Periodic Timer Setup. The heartbeat handler increases the real counter
every second, and sends a text string with the counter value, as shown in Listing
here.
i f ( rfcomm channel id ) {
s n p r i n t f ( l i n e B u f f e r , s i z e o f ( l i n e B u f f e r ) , ” BTstack c o u n t e r %04u\n
” , ++c o u n t e r ) ;
p r i n t f ( ”%s ” , l i n e B u f f e r ) ;
s t a t i c void o n e s h o t t i m e r s e t u p ( void ) {
// s e t one−s h o t t i m e r
h e a r t b e a t . p r o c e s s = &h e a r t b e a t h a n d l e r ;
b t s t a c k r u n l o o p s e t t i m e r (& h e a r t b e a t , HEARTBEAT PERIOD MS) ;
b t s t a c k r u n l o o p a d d t i m e r (& h e a r t b e a t ) ;
}
161
0.87.3. Bluetooth Logic. The Bluetooth logic is implemented within the packet
handler, see Listing here. In this example, the following events are passed se-
quentially:
• BTSTACK EVENT STATE,
• HCI EVENT PIN CODE REQUEST (Standard pairing) or
• HCI EVENT USER CONFIRMATION REQUEST (Secure Simple Pair-
ing),
• RFCOMM EVENT INCOMING CONNECTION,
• RFCOMM EVENT CHANNEL OPENED,
• RFCOMM EVENT CHANNEL CLOSED
Upon receiving HCI EVENT PIN CODE REQUEST event, we need
to handle authentication. Here, we use a fixed PIN code “0000”.
When HCI EVENT USER CONFIRMATION REQUEST is received, the user
will be asked to accept the pairing request. If the IO capability is set to
SSP IO CAPABILITY DISPLAY YES NO, the request will be automatically
accepted.
The RFCOMM EVENT INCOMING CONNECTION event indicates an in-
coming connection. Here, the connection is accepted. More logic is need, if
you want to handle connections from multiple clients. The incoming RFCOMM
connection event contains the RFCOMM channel number used during the SPP
setup phase and the newly assigned RFCOMM channel ID that is used by all
BTstack commands and events.
If RFCOMM EVENT CHANNEL OPENED event returns status greater then
0, then the channel establishment has failed (rare case, e.g., client crashes). On
successful connection, the RFCOMM channel ID and MTU for this channel are
made available to the heartbeat counter. After opening the RFCOMM chan-
nel, the communication between client and the application takes place. In this
example, the timer handler increases the real counter every second.
RFCOMM EVENT CAN SEND NOW indicates that it’s possible to send an
RFCOMM packet on the rfcomm cid that is include
...
case HCI EVENT PIN CODE REQUEST :
// inform a b o u t p i n code r e q u e s t
p r i n t f ( ” Pin code r e q u e s t − u s i n g ’ 0 0 0 0 ’ \ n” ) ;
h c i e v e n t p i n c o d e r e q u e s t g e t b d a d d r ( packet , e v e n t a d d r )
;
g a p p i n c o d e r e s p o n s e ( e v e n t a d d r , ” 0000 ” ) ;
break ;
...
}
0.88. SPP Server - RFCOMM Flow Control. Source Code: spp flowcontrol.c
This example adds explicit flow control for incoming RFCOMM data to the
SPP heartbeat counter example. We will highlight the changes compared to the
SPP counter example.
0.88.1. SPP Service Setup. Listing here shows how to provide one initial credit
during RFCOMM service initialization. Please note that providing a single credit
effectively reduces the credit-based (sliding window) flow control to a stop-and-
wait flow control that limits the data throughput substantially.
s t a t i c void s p p s e r v i c e s e t u p ( void ) {
163
// r e g i s t e r f o r HCI e v e n t s
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
// i n i t L2CAP
l2cap init () ;
// i n i t RFCOMM
rfcomm init () ;
// r e s e r v e d channel , mtu l i m i t e d by l 2 c a p , 1 c r e d i t
r 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 (& p a c k e t h a n d l e r ,
RFCOMM SERVER CHANNEL, 0 x f f f f , 1 ) ;
s t a t i c void h e a r t b e a t h a n d l e r ( struct b t s t a c k t i m e r s o u r c e ∗ t s ) {
i f ( rfcomm send credit ){
rfcomm grant credits ( rfcomm channel id , 1) ;
rfcomm send credit = 0;
}
b t s t a c k r u n l o o p s e t t i m e r ( t s , HEARTBEAT PERIOD MS) ;
btstack run loop add timer ( ts ) ;
}
// B l u e t o o t h l o g i c
s t a t i c void p a c k e t h a n d l e r ( uint8 t p a c k e t t y p e , uint16 t channel ,
uint8 t ∗ packet , uint16 t s i z e ) {
...
case RFCOMM DATA PACKET:
f o r ( i =0; i <s i z e ; i ++){
putchar ( packet [ i ] ) ;
};
164
p u t c h a r ( ’ \n ’ ) ;
rfcomm send credit = 1;
break ;
...
}
0.89. PAN - lwIP HTTP and DHCP Server. Source Code: pan lwip http server.c
Bluetooth PAN is mainly used for Internet Tethering, where e.g. a mobile
phone provides internet connection to a laptop or a tablet.
Instead of regular internet access, it’s also possible to provide a Web app
on a Bluetooth device, e.g. for configuration or maintenance. For some device,
this can be a more effective way to provide an interface compared to dedicated
smartphone applications (for Android and iOS).
Before iOS 11, accessing an HTTP server via Bluetooth PAN was not sup-
ported on the iPhone, but on iPod and iPad. With iOS 11, this works as ex-
pected.
After pairing your device, please open the URL http://192.168.7.1 in your web
browser.
0.89.1. Packet Handler. All BNEP events are handled in the platform/bnep lwip.c
BNEP-LWIP Adapter. Here, we only print status information and handle pairing
requests.
0.89.2. PAN BNEP Setup.
0.89.3. DHCP Server Configuration.
0.89.4. Large File Download.
0.89.5. DHCP Server Setup.
0.89.6. Main.
0.90. BNEP/PANU (Linux only). Source Code: panu demo.c
BNEP EVENT CHANNEL OPENED is received after a BNEP connection
was established or or when the connection fails. The status field returns the
error code.
BNEP EVENT CHANNEL CLOSED is received when the connection gets
closed.
Listing here shows the setup of the PAN setup
Listing here shows the DHCP Server configuration for network 192.168.7.0/8
Listing here Shows how a configurable test file for performance tests is gener-
ated on the fly. The filename is the number of bytes to generate, e.g. /1048576.txt
results in a 1MB file.
Listing here shows the setup of the lwIP network stack and starts the DHCP
Server
Setup the lwIP network and PAN NAP
This example implements both a PANU client and a server. In server mode, it
sets up a BNEP server and registers a PANU SDP record and waits for incoming
165
s t a t i c void p a n u s e t u p ( void ) {
// I n i t i a l i z e L2CAP
l2cap init () ;
#i f d e f ENABLE BLE
// I n i t i a l i z e LE S e c u r i t y Manager . Needed f o r c r o s s −t r a n s p o r t key
derivation
sm init () ;
#endif
// I n i t i a l i s e BNEP
bnep init () ;
// Minimum L2CAP MTU f o r bnep i s 1691 b y t e s
#i f d e f ENABLE PANU CLIENT
b n e p r e g i s t e r s e r v i c e ( p a c k e t h a n d l e r , BLUETOOTH SERVICE CLASS PANU
, 1691) ;
// PANU
pan create panu sdp record ( panu sdp record ,
s d p c r e a t e s e r v i c e r e c o r d h a n d l e ( ) , n e t w o r k p a c k e t t y p e s , NULL
, NULL, BNEP SECURITY NONE) ;
#e l s e
b n e p r e g i s t e r s e r v i c e ( p a c k e t h a n d l e r , BLUETOOTH SERVICE CLASS NAP,
1691) ;
// NAP Network Access Type : Other , 1 MB/ s
pan create nap sdp record ( panu sdp record ,
s d p c r e a t e s e r v i c e r e c o r d h a n d l e ( ) , n e t w o r k p a c k e t t y p e s , NULL
, NULL, BNEP SECURITY NONE, PAN NET ACCESS TYPE OTHER,
1 0 0 0 0 0 0 , NULL, NULL) ;
166
#endif
b t s t a c k a s s e r t ( d e g e t l e n ( p a n u s d p r e c o r d ) <= s i z e o f (
panu sdp record ) ) ;
s d p r e g i s t e r s e r v i c e ( panu sdp record ) ;
// I n i t i a l i z e network i n t e r f a c e
b t s t a c k n e t w o r k i n i t (& n e t w o r k s e n d p a c k e t c a l l b a c k ) ;
// r e g i s t e r f o r HCI e v e n t s
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
}
0.90.2. SDP parser callback. The SDP parsers retrieves the BNEP PAN UUID as
explained in Section [on SDP BNEP Query example](#sec:sdpbnepqueryExample}.
0.90.3. Packet Handler. The packet handler responds to various HCI Events.
b n e p e v e n t c h a n n e l o p e n e d g e t r e m o t e a d d r e s s ( packet ,
event addr ) ;
p r i n t f ( ”BNEP c o n n e c t i o n open s u c c e e d e d t o %s s o u r c e UUID
0x%04x d e s t UUID : 0x%04x , max frame s i z e %u\n” ,
bd addr to str ( event addr ) , uuid source , uuid dest ,
mtu ) ;
default :
break ;
}
break ;
default :
break ;
}
}
When BTSTACK EVENT STATE with state HCI STATE WORKING is re-
ceived and the example is started in client mode, the remote SDP BNEP query
is started.
BNEP EVENT CHANNEL OPENED is received after a BNEP connection
was established or or when the connection fails. The status field returns the
error code.
168
The TAP network interface is then configured. A data source is set up and
registered with the run loop to receive Ethernet packets from the TAP interface.
The event contains both the source and destination UUIDs, as well as the
MTU for this connection and the BNEP Channel ID, which is used for sending
Ethernet packets over BNEP.
If there is a timeout during the connection setup, BNEP EVENT CHANNEL TIMEOUT
will be received and the BNEP connection will be closed
BNEP EVENT CHANNEL CLOSED is received when the connection gets
closed.
BNEP EVENT CAN SEND NOW indicates that a new packet can be send.
This triggers the send of a stored network packet. The tap datas source can be
enabled again
Ethernet packets from the remote device are received in the packet handler
with type BNEP DATA PACKET. It is forwarded to the TAP interface.
0.90.4. Network packet handler. A pointer to the network packet is stored and
a BNEP EVENT CAN SEND NOW requested
0.91.1. Main Application Setup. Listing here shows main application code. To
run a HID Device service you need to initialize the SDP, and to create and
register HID Device record with it. At the end the Bluetooth stack is started.
// a l l o w t o g e t found by i n q u i r y
gap discoverable control (1) ;
// use L i m i t e d D i s c o v e r a b l e Mode ; P e r i p h e r a l ; Keyboard as CoD
g a p s e t c l a s s o f d e v i c e ( 0 x2540 ) ;
// s e t l o c a l name t o be i d e n t i f i e d − z e r o e s w i l l be r e p l a c e d by
a c t u a l BD ADDR
g a p s e t l o c a l n a m e ( ”HID Keyboard Demo 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 ” ) ;
// a l l o w f o r r o l e s w i t c h i n g e n e r a l and s n i f f mode
169
// L2CAP
l2cap init () ;
#i f d e f ENABLE BLE
// I n i t i a l i z e LE S e c u r i t y Manager . Needed f o r c r o s s −t r a n s p o r t key
derivation
sm init () ;
#endif
// SDP S e r v e r
sdp init () ;
memset ( h i d s e r v i c e b u f f e r , 0 , s i z e o f ( h i d s e r v i c e b u f f e r ) ) ;
h i d s d p r e c o r d t hid params = {
// h i d s e v i c e s u b c l a s s 2540 Keyboard , h i d c o u n n t r y code 33 US
0 x2540 , 3 3 ,
h i d v i r t u a l c a b l e , h i d r em o te w ak e ,
hid reconnect initiate , hid normally connectable ,
hid boot device ,
host max latency , host min timeout ,
3200 ,
hid descriptor keyboard ,
sizeof ( hid descriptor keyboard ) ,
hid device name
};
// HID D e v i ce
h i d d e v i c e i n i t ( hid boot device , sizeof ( hid descriptor keyboard ) ,
hid descriptor keyboard ) ;
// r e g i s t e r f o r HCI e v e n t s
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
// r e g i s t e r f o r HID e v e n t s
h i d d e v i c e r e g i s t e r p a c k e t h a n d l e r (& p a c k e t h a n d l e r ) ;
b t s t a c k r i n g b u f f e r i n i t (& s e n d b u f f e r , s e n d b u f f e r s t o r a g e , s i z e o f
( send buffer storage ) ) ;
// t u r n on !
h c i p o w e r c o n t r o l (HCI POWER ON) ;
return 0 ;
}
0.92.1. Main Application Setup. Listing here shows main application code. To
run a HID Device service you need to initialize the SDP, and to create and
register HID Device record with it. At the end the Bluetooth stack is started.
// a l l o w t o g e t found by i n q u i r y
gap discoverable control (1) ;
// use L i m i t e d D i s c o v e r a b l e Mode ; P e r i p h e r a l ; P o i n t i n g D e v ic e as
CoD
g a p s e t c l a s s o f d e v i c e ( 0 x2580 ) ;
// s e t l o c a l name t o be i d e n t i f i e d − z e r o e s w i l l be r e p l a c e d by
a c t u a l BD ADDR
g a p s e t l o c a l n a m e ( ”HID Mouse Demo 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 ” ) ;
// a l l o w f o r r o l e s w i t c h i n g e n e r a l and s n i f f mode
171
// L2CAP
l2cap init () ;
#i f d e f ENABLE BLE
// I n i t i a l i z e LE S e c u r i t y Manager . Needed f o r c r o s s −t r a n s p o r t key
derivation
sm init () ;
#endif
// SDP S e r v e r
sdp init () ;
h i d s d p r e c o r d t hid params = {
// h i d s e v i c e s u b c l a s s 2580 Mouse , h i d c o u n n t r y code 33 US
0 x2580 , 3 3 ,
h i d v i r t u a l c a b l e , h i d r em o te w ak e ,
hid reconnect initiate , hid normally connectable ,
hid boot device ,
0xFFFF , 0xFFFF , 3 2 0 0 ,
hid descriptor mouse boot mode ,
sizeof ( hid descriptor mouse boot mode ) ,
hid device name
};
memset ( h i d s e r v i c e b u f f e r , 0 , s i z e o f ( h i d s e r v i c e b u f f e r ) ) ;
hid create sdp record ( hid service buffer ,
s d p c r e a t e s e r v i c e r e c o r d h a n d l e ( ) , &hid params ) ;
b t s t a c k a s s e r t ( d e g e t l e n ( h i d s e r v i c e b u f f e r ) <= s i z e o f (
hid service buffer )) ;
sdp register service ( hid service buffer ) ;
// HID D e v i ce
h i d d e v i c e i n i t ( hid boot device , sizeof (
hid descriptor mouse boot mode ) ,
hid descriptor mouse boot mode ) ;
// r e g i s t e r f o r HCI e v e n t s
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
// r e g i s t e r f o r HID
h i d d e v i c e r e g i s t e r p a c k e t h a n d l e r (& p a c k e t h a n d l e r ) ;
s t a t i c void h i d h o s t s e t u p ( void ) {
// I n i t i a l i z e L2CAP
l2cap init () ;
#i f d e f ENABLE BLE
// I n i t i a l i z e LE S e c u r i t y Manager . Needed f o r c r o s s −t r a n s p o r t key
derivation
sm init () ;
#endif
// I n i t i a l i z e HID Host
h i d h o s t i n i t ( hid descriptor storage , sizeof (
hid descriptor storage ) ) ;
hid host register packet handler ( packet handler ) ;
// r e g i s t e r f o r HCI e v e n t s
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
// D i s a b l e s t d o u t b u f f e r i n g
s e t v b u f ( s t d i n , NULL, IONBF , 0 ) ;
}
0.93.2. HID Report Handler. Use BTstack’s compact HID Parser to process in-
coming HID Report in Report protocol mode. Iterate over all fields and process
fields with usage page = 0x07 / Keyboard Check if SHIFT is down and process
first character (don’t handle multiple key presses)
0.93.3. Packet Handler. The packet handler responds to various HID events.
switch ( e v e n t ) {
#i f n d e f HAVE BTSTACK STDIN
case BTSTACK EVENT STATE:
i f ( b t s t a c k e v e n t s t a t e g e t s t a t e ( p a c k e t ) ==
HCI STATE WORKING) {
s t a t u s = h i d h o s t c o n n e c t ( remote addr ,
h i d h o s t r e p o r t m o d e , &h i d h o s t c i d ) ;
i f ( s t a t u s != ERROR CODE SUCCESS) {
p r i n t f ( ”HID h o s t c o n n e c t f a i l e d , s t a t u s 0x%02x . \ n” ,
status ) ;
}
}
break ;
#endif
...
case HCI EVENT HID META :
switch ( h c i e v e n t h i d m e t a g e t s u b e v e n t c o d e ( p a c k e t ) ) {
// The h i d h o s t r e p o r t m o d e i n t h e
hid host accept connection function
// a l l o w s t h e a p p l i c a t i o n t o r e q u e s t a p r o t o c o l mode .
// For a v a i l a b l e p r o t o c o l modes , s e e
hid protocol mode t in b t s t a c k h i d . h f i l e .
hid host accept connection (
hid subevent incoming connection get hid cid (
packet ) , hid host report mode ) ;
break ;
default :
break ;
176
}
break ;
default :
break ;
}
break ;
default :
break ;
}
}
When BTSTACK EVENT STATE with state HCI STATE WORKING is re-
ceived and the example is started in client mode, the remote SDP HID query is
started.
0.94. HID Keyboard LE. Source Code: hog keyboard demo.c
0.95. HID Mouse LE. Source Code: hog mouse demo.c
0.96. HID Boot Host LE. Source Code: hog boot host demo.c
This example implements a minimal HID-over-GATT Boot Host. It scans for
LE HID devices, connects to it, discovers the Characteristics relevant for the HID
Service and enables Notifications on them. It then dumps all Boot Keyboard
and Mouse Input Reports
0.96.1. HOG Boot Keyboard Handler. Boot Keyboard Input Report contains a
report of format [ modifier, reserved, 6 x usage for key 1..6 from keyboard usage]
Track new usages, map key usage to actual character and simulate terminal
0.96.2. HOG Boot Mouse Handler. Boot Mouse Input Report contains a report
of format [ buttons, dx, dy, dz = scroll wheel] Decode packet and print on stdout
@param packet type @param channel @param packet @param size
0.96.3. Test if advertisement contains HID UUID.
// s t o r e remote d e v i c e a d d r e s s and t y p e
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 ( packet ,
r e m o t e d e v i c e . addr ) ;
remote device . addr 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 ( packet ) ;
// c o n n e c t
p r i n t f ( ”Found , c o n n e c t t o d e v i c e with %s a d d r e s s %s . . . \ n”
, r e m o t e d e v i c e . a d d r t y p e == 0 ? ” p u b l i c ” : ”random” ,
b d a d d r t o s t r ( r e m o t e d e v i c e . addr ) ) ;
hog connect () ;
break ;
case HCI EVENT DISCONNECTION COMPLETE :
i f ( a p p s t a t e != READY) break ;
0.96.4. HCI packet handler. The SM packet handler receives Security Manager
Events required for pairing. It also receives events generated during Identity
Resolving see Listing here.
bool c o n n e c t t o s e r v i c e = f a l s e ;
switch ( h c i e v e n t p a c k e t g e t t y p e ( p a c k e t ) ) {
case SM EVENT JUST WORKS REQUEST :
p r i n t f ( ” J u s t works r e q u e s t e d \n” ) ;
sm just works confirm ( sm event just works request get handle (
packet ) ) ;
break ;
case SM EVENT NUMERIC COMPARISON REQUEST:
p r i n t f ( ” Confirming numeric comparison : %”PRIu32”\n” ,
sm event numeric comparison request get passkey ( packet ) ) ;
sm numeric comparison confirm (
sm event passkey display number get handle ( packet ) ) ;
break ;
case SM EVENT PASSKEY DISPLAY NUMBER :
p r i n t f ( ” D i s p l a y Passkey : %”PRIu32” \n” ,
sm event passkey display number get passkey ( packet ) ) ;
break ;
case SM EVENT PAIRING COMPLETE :
switch ( s m e v e n t p a i r i n g c o m p l e t e g e t s t a t u s ( p a c k e t ) ) {
case ERROR CODE SUCCESS :
p r i n t f ( ” P a i r i n g complete , s u c c e s s \n” ) ;
connect to service = true ;
break ;
case ERROR CODE CONNECTION TIMEOUT:
p r i n t f ( ” P a i r i n g f a i l e d , t i m e o u t \n” ) ;
break ;
case ERROR CODE REMOTE USER TERMINATED CONNECTION:
p r i n t f ( ” P a i r i n g f a i l e d , d i s c o n n e c t e d \n” ) ;
break ;
case ERROR CODE AUTHENTICATION FAILURE :
p r i n t f ( ” P a i r i n g f a i l e d , r e a s o n = %u\n” ,
s m e v e n t p a i r i n g c o m p l e t e g e t r e a s o n ( packet ) ) ;
break ;
default :
break ;
}
break ;
case SM EVENT REENCRYPTION COMPLETE:
p r i n t f ( ”Re−e n c r y p t i o n complete , s u c c e s s \n” ) ;
connect to service = true ;
break ;
179
default :
break ;
}
if ( connect to service ){
// c o n t i n u e − q u e r y primary s e r v i c e s
p r i n t f ( ” S e a r c h f o r HID s e r v i c e . \ n” ) ;
a p p s t a t e = W4 HID SERVICE FOUND ;
gatt client discover primary services by uuid16 (
handle gatt client event , connection handle ,
ORG BLUETOOTH SERVICE HUMAN INTERFACE DEVICE) ;
}
}
l2cap init () ;
// s e t u p SM: D i s p l a y o n l y
sm init () ;
sm s e t i o c a p a b i l i t i e s (IO CAPABILITY DISPLAY ONLY) ;
sm s e t a u t h e n t i c a t i o n r e q u i r e m e n t s (SM AUTHREQ SECURE CONNECTION |
SM AUTHREQ BONDING) ;
//
g a t t c l i e n t i n i t () ;
// r e g i s t e r f o r e v e n t s from HCI
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
// r e g i s t e r f o r e v e n t s from S e c u r i t y Manager
s m e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &s m p a c k e t h a n d l e r ;
s m a d d e v e n t h a n d l e r (& s m e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
0.97. Dual Mode - SPP and LE Counter. Source Code: spp and le counter.c
The SPP and LE Counter example combines the Bluetooth Classic SPP Counter
and the Bluetooth LE Counter into a single application.
In this Section, we only point out the differences to the individual examples
and how the stack is configured.
Note: To test, please run the example, and then:
• for SPP pair from a remote device, and open the Virtual Serial Port,
• for LE use some GATT Explorer, e.g. LightBlue, BLExplr, to enable
notifications.
0.97.1. Advertisements. The Flags attribute in the Advertisement Data indicates
if a device is dual-mode or le-only.
const uint8 t a d v d a t a [ ] = {
// F l a g s g e n e r a l d i s c o v e r a b l e
180
0.97.2. Packet Handler. The packet handler of the combined example is just the
combination of the individual packet handlers.
0.97.3. Heartbeat Handler. Similar to the packet handler, the heartbeat handler
is the combination of the individual ones. After updating the counter, it requests
an ATT EVENT CAN SEND NOW and/or RFCOMM EVENT CAN SEND NOW
s t a t i c void h e a r t b e a t h a n d l e r ( struct b t s t a c k t i m e r s o u r c e ∗ t s ) {
i f ( rfcomm channel id | | l e n o t i f i c a t i o n e n a b l e d ) {
beat ( ) ;
}
i f ( rfcomm channel id ) {
rfcomm request can send now event ( rfcomm channel id ) ;
}
if ( le notification enabled ) {
att server request can send now event ( att con handle ) ;
}
0.97.4. Main Application Setup. As with the packet and the heartbeat handlers,
the combined app setup contains the code from the individual example setups.
int b t s t a c k m a i n ( void ) ;
int b t s t a c k m a i n ( void )
{
l2cap init () ;
rfcomm init () ;
r f c o m m r e g i s t e r s e r v i c e ( p a c k e t h a n d l e r , RFCOMM SERVER CHANNEL, 0
xffff );
sdp init () ;
memset ( s p p s e r v i c e b u f f e r , 0 , s i z e o f ( s p p s e r v i c e b u f f e r ) ) ;
spp create sdp record ( spp service buffer ,
s d p c r e a t e s e r v i c e r e c o r d h a n d l e ( ) , RFCOMM SERVER CHANNEL, ”
SPP Counter ” ) ;
b t s t a c k a s s e r t ( d e g e t l e n ( s p p s e r v i c e b u f f e r ) <= s i z e o f (
spp service buffer ) ) ;
sdp register service ( spp service buffer ) ;
// s e t u p SM: D i s p l a y o n l y
sm init () ;
// s e t u p ATT s e r v e r
att server init ( profile data , att read callback ,
att write callback ) ;
// r e g i s t e r f o r HCI e v e n t s
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
// r e g i s t e r f o r ATT e v e n t s
att se rver re giste r pac ket han dler ( packet handler ) ;
// s e t u p a d v e r t i s e m e n t s
uint16 t a d v i n t m i n = 0 x0030 ;
uint16 t a d v i n t m a x = 0 x0030 ;
uint8 t a d v t y p e = 0 ;
bd addr t n u l l a d d r ;
memset ( n u l l a d d r , 0 , 6 ) ;
g a p a d v e r t i s e m e n t s s e t p a r a m s ( a d v i n t m i n , adv int max , adv type ,
0 , n u l l a d d r , 0 x07 , 0 x00 ) ;
g a p a d v e r t i s e m e n t s s e t d a t a ( a d v d a t a l e n , ( uint8 t ∗ ) a d v d a t a ) ;
gap advertisements enable (1) ;
// s e t one−s h o t t i m e r
h e a r t b e a t . p r o c e s s = &h e a r t b e a t h a n d l e r ;
b t s t a c k r u n l o o p s e t t i m e r (& h e a r t b e a t , HEARTBEAT PERIOD MS) ;
b t s t a c k r u n l o o p a d d t i m e r (& h e a r t b e a t ) ;
182
// b e a t once
beat ( ) ;
// t u r n on !
h c i p o w e r c o n t r o l (HCI POWER ON) ;
return 0 ;
}
s t a t i c void l e s t r e a m e r s e t u p ( void ) {
l2cap init () ;
// s e t u p SM: D i s p l a y o n l y
sm init () ;
// c o n f i g u r e C l a s s i c GAP
g a p s e t l o c a l n a m e ( ”GATT Streamer BR/EDR 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 ” ) ;
g a p s s p s e t i o c a p a b i l i t y ( SSP IO CAPABILITY DISPLAY YES NO ) ;
gap discoverable control (1) ;
#endif
183
// s e t u p ATT s e r v e r
a t t s e r v e r i n i t ( p r o f i l e d a t a , NULL, a t t w r i t e c a l l b a c k ) ;
// r e g i s t e r f o r HCI e v e n t s
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &h c i p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
// r e g i s t e r f o r ATT e v e n t s
att server register packet handler ( att packet handler ) ;
// s e t u p a d v e r t i s e m e n t s
uint16 t a d v i n t m i n = 0 x0030 ;
uint16 t a d v i n t m a x = 0 x0030 ;
uint8 t a d v t y p e = 0 ;
bd addr t n u l l a d d r ;
memset ( n u l l a d d r , 0 , 6 ) ;
g a p a d v e r t i s e m e n t s s e t p a r a m s ( a d v i n t m i n , adv int max , adv type ,
0 , n u l l a d d r , 0 x07 , 0 x00 ) ;
g a p a d v e r t i s e m e n t s s e t d a t a ( a d v d a t a l e n , ( uint8 t ∗ ) a d v d a t a ) ;
gap advertisements enable (1) ;
// i n i t c l i e n t s t a t e
init connections () ;
}
s t a t i c void t e s t r e s e t ( l e s t r e a m e r c o n n e c t i o n t ∗ c o n t e x t ) {
c o n t e x t −>t e s t d a t a s t a r t = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
}
s t a t i c void t e s t t r a c k s e n t ( l e s t r e a m e r c o n n e c t i o n t ∗ c o n t e x t , int
bytes sent ){
c o n t e x t −>t e s t d a t a s e n t += b y t e s s e n t ;
// e v a l u a t e
uint32 t now = b t s t a c k r u n l o o p g e t t i m e m s ( ) ;
uint32 t t i m e p a s s e d = now − c o n t e x t −>t e s t d a t a s t a r t ;
i f ( t i m e p a s s e d < REPORT INTERVAL MS) return ;
// p r i n t s p e e d
int b y t e s p e r s e c o n d = c o n t e x t −>t e s t d a t a s e n t ∗ 1000 /
time passed ;
p r i n t f ( ”%c : %”PRIu32” b y t e s s e n t −> %u.%03u kB/ s \n” , c o n t e x t −>name ,
c o n t e x t −>t e s t d a t a s e n t , b y t e s p e r s e c o n d / 1 0 0 0 ,
b y t e s p e r s e c o n d % 1000) ;
// r e s t a r t
c o n t e x t −>t e s t d a t a s t a r t = now ;
c o n t e x t −>t e s t d a t a s e n t = 0 ;
}
184
0.98.3. HCI Packet Handler. The packet handler is used track incoming connec-
tions and to stop notifications on disconnect It is also a good place to request
the connection parameter update as indicated in the commented code block.
uint16 t c o n n i n t e r v a l ;
hci con handle t con handle ;
s t a t i c const char ∗ const phy names [ ] = {
” Reserved ” , ” 1 M” , ” 2 M” , ” Codec ”
};
switch ( h c i e v e n t p a c k e t g e t t y p e ( packet ) ) {
case BTSTACK EVENT STATE:
// BTstack a c t i v a t e d , g e t s t a r t e d
if ( b t s t a c k e v e n t s t a t e g e t s t a t e ( p a c k e t ) == HCI STATE WORKING
) {
p r i n t f ( ”To s t a r t t h e s t r e a m i n g , p l e a s e run t h e
l e s t r e a m e r c l i e n t example on o t h e r d e v i c e , o r u s e some
GATT E x p l o r e r , e . g . LightBlue , BLExplr . \ n” ) ;
}
break ;
case HCI EVENT DISCONNECTION COMPLETE :
con handle =
hci event disconnection complete get connection handle (
packet ) ;
p r i n t f ( ”− LE Connection 0x%04x : d i s c o n n e c t , r e a s o n %02x\n” ,
con handle , h c i e v e n t d i s c o n n e c t i o n c o m p l e t e g e t r e a s o n (
packet ) ) ;
break ;
case HCI EVENT META GAP :
switch ( h c i e v e n t g a p m e t a g e t s u b e v e n t c o d e ( p a c k e t ) ) {
case GAP SUBEVENT LE CONNECTION COMPLETE:
// p r i n t c o n n e c t i o n p a r a m e t e r s ( w i t h o u t u s i n g f l o a t
operations )
con handle =
gap subevent le connection complete get connection handle
( packet ) ;
conn interval =
gap subevent le connection complete get conn interval (
packet ) ;
p r i n t f ( ”− LE Connection 0x%04x : c o n n e c t e d − c o n n e c t i o n
i n t e r v a l %u.%02u ms , l a t e n c y %u\n” , c o n h a n d l e ,
c o n n i n t e r v a l ∗ 125 / 1 0 0 ,
185
25 ∗ ( c o n n i n t e r v a l & 3 ) ,
gap subevent le connection complete get conn latency
( packet ) ) ;
break ;
default :
break ;
}
}
0.98.4. ATT Packet Handler. The packet handler is used to track the ATT MTU
Exchange and trigger ATT send
int mtu ;
le streamer connection t ∗ context ;
switch ( p a c k e t t y p e ) {
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 ( p a c k e t ) ) {
case ATT EVENT CONNECTED:
// s e t u p new
context = connection for conn handle (
HCI CON HANDLE INVALID) ;
i f ( ! c o n t e x t ) break ;
c o n t e x t −>c o u n t e r = ’A ’ ;
c o n t e x t −>c o n n e c t i o n h a n d l e =
a t t e v e n t c o n n e c t e d g e t h a n d l e ( packet ) ;
c o n t e x t −>t e s t d a t a l e n = b t s t a c k m i n ( a t t s e r v e r g e t m t u (
c o n t e x t −>c o n n e c t i o n h a n d l e ) − 3 , s i z e o f ( c o n t e x t −>
test data ) ) ;
p r i n t f ( ”%c : ATT connected , h a n d l e 0x%04x , t e s t data l e n %u
\n” , c o n t e x t −>name , c o n t e x t −>c o n n e c t i o n h a n d l e ,
c o n t e x t −>t e s t d a t a l e n ) ;
break ;
case ATT EVENT MTU EXCHANGE COMPLETE:
mtu = a t t e v e n t m t u e x c h a n g e c o m p l e t e g e t M T U ( p a c k e t ) − 3 ;
context = connection for conn handle (
att event mtu exchange complete get handle ( packet ) ) ;
i f ( ! c o n t e x t ) break ;
c o n t e x t −>t e s t d a t a l e n = b t s t a c k m i n ( mtu − 3 , s i z e o f (
c o n t e x t −>t e s t d a t a ) ) ;
p r i n t f ( ”%c : ATT MTU = %u => u s e t e s t data o f l e n %u\n” ,
c o n t e x t −>name , mtu , c o n t e x t −>t e s t d a t a l e n ) ;
break ;
case ATT EVENT CAN SEND NOW:
streamer () ;
break ;
case ATT EVENT DISCONNECTED:
context = connection for conn handle (
a t t e v e n t d i s c o n n e c t e d g e t h a n d l e ( packet ) ) ;
i f ( ! c o n t e x t ) break ;
187
// f r e e c o n n e c t i o n
p r i n t f ( ”%c : ATT d i s c o n n e c t e d , h a n d l e 0x%04x\n” , c o n t e x t −>
name , c o n t e x t −>c o n n e c t i o n h a n d l e ) ;
c o n t e x t −>l e n o t i f i c a t i o n e n a b l e d = 0 ;
c o n t e x t −>c o n n e c t i o n h a n d l e = HCI CON HANDLE INVALID ;
break ;
default :
break ;
}
break ;
default :
break ;
}
}
0.98.5. Streamer. The streamer function checks if notifications are enabled and
if a notification can be sent now. It creates some test data - a single letter that
gets increased every time - and tracks the data sent.
s t a t i c void s t r e a m e r ( void ) {
// f i n d n e x t a c t i v e s t r e a m i n g c o n n e c t i o n
int o l d c o n n e c t i o n i n d e x = c o n n e c t i o n i n d e x ;
while ( 1 ) {
// a c t i v e found ?
i f (( le streamer connections [ connection index ] . connection handle
!= HCI CON HANDLE INVALID) &&
( le streamer connections [ connection index ] .
l e n o t i f i c a t i o n e n a b l e d ) ) break ;
// c h e c k n e x t
next connection index () ;
// none found
i f ( c o n n e c t i o n i n d e x == o l d c o n n e c t i o n i n d e x ) return ;
}
l e s t r e a m e r c o n n e c t i o n t ∗ c o n t e x t = &l e s t r e a m e r c o n n e c t i o n s [
connection index ] ;
// c r e a t e t e s t d a t a
c o n t e x t −>c o u n t e r ++;
i f ( c o n t e x t −>c o u n t e r > ’ Z ’ ) c o n t e x t −>c o u n t e r = ’A ’ ;
memset ( c o n t e x t −>t e s t d a t a , c o n t e x t −>c o u n t e r , c o n t e x t −>
test data len ) ;
// send
a t t s e r v e r n o t i f y ( c o n t e x t −>c o n n e c t i o n h a n d l e , c o n t e x t −>
v a l u e h a n d l e , ( uint8 t ∗ ) c o n t e x t −>t e s t d a t a , c o n t e x t −>
test data len ) ;
// t r a c k
188
t e s t t r a c k s e n t ( c o n t e x t , c o n t e x t −>t e s t d a t a l e n ) ;
// r e q u e s t n e x t send e v e n t
a t t s e r v e r r e q u e s t c a n s e n d n o w e v e n t ( c o n t e x t −>c o n n e c t i o n h a n d l e ) ;
// c h e c k n e x t
next connection index () ;
}
0.98.6. ATT Write. The only valid ATT write in this example is to the Client
Characteristic Configuration, which configures notification and indication. If
the ATT handle matches the client configuration handle, the new configuration
value is stored. If notifications get enabled, an ATT EVENT CAN SEND NOW
is requested. See Listing here.
s t a t i c int a t t w r i t e c a l l b a c k ( h c i c o n h a n d l e t c o n h a n d l e , uint16 t
a t t h a n d l e , uint16 t t r a n s a c t i o n m o d e , uint16 t o f f s e t , uint8 t
∗ b u f f e r , uint16 t b u f f e r s i z e ) {
UNUSED( o f f s e t ) ;
// p r i n t f (” a t t w r i t e c a l l b a c k a t t h a n d l e 0 x%04x , t r a n s a c t i o n mode
%u\n ” , a t t h a n d l e , t r a n s a c t i o n m o d e ) ;
i f ( t r a n s a c t i o n m o d e != ATT TRANSACTION MODE NONE) return 0 ;
le streamer connection t ∗ context = connection for conn handle (
con handle ) ;
switch ( a t t h a n d l e ) {
case
ATT CHARACTERISTIC 0000FF11 0000 1000 8000 00805F9B34FB 01 CLIENT CONFIGURATIO
:
case
ATT CHARACTERISTIC 0000FF12 0000 1000 8000 00805F9B34FB 01 CLIENT CONFIGURATIO
:
c o n t e x t −>l e n o t i f i c a t i o n e n a b l e d = l i t t l e e n d i a n r e a d 1 6 (
b u f f e r , 0 ) ==
GATT CLIENT CHARACTERISTICS CONFIGURATION NOTIFICATION ;
p r i n t f ( ”%c : N o t i f i c a t i o n s e n a b l e d %u\n” , c o n t e x t −>name ,
c o n t e x t −>l e n o t i f i c a t i o n e n a b l e d ) ;
i f ( c o n t e x t −>l e n o t i f i c a t i o n e n a b l e d ) {
switch ( a t t h a n d l e ) {
case
ATT CHARACTERISTIC 0000FF11 0000 1000 8000 00805F9B34FB 01 CLIENT CONFIGU
:
c o n t e x t −>v a l u e h a n d l e =
ATT CHARACTERISTIC 0000FF11 0000 1000 8000 00805F9B34FB 01 VALUE HAND
;
break ;
case
ATT CHARACTERISTIC 0000FF12 0000 1000 8000 00805F9B34FB 01 CLIENT CONFIGU
:
189
c o n t e x t −>v a l u e h a n d l e =
ATT CHARACTERISTIC 0000FF12 0000 1000 8000 00805F9B34FB 01 VALUE HAND
;
break ;
default :
break ;
}
a t t s e r v e r r e q u e s t c a n s e n d n o w e v e n t ( c o n t e x t −>
connection handle ) ;
}
t e s t r e s e t ( context ) ;
break ;
case
ATT CHARACTERISTIC 0000FF11 0000 1000 8000 00805F9B34FB 01 VALUE HANDLE
:
case
ATT CHARACTERISTIC 0000FF12 0000 1000 8000 00805F9B34FB 01 VALUE HANDLE
:
t e s t t r a c k s e n t ( context , b u f f e r s i z e ) ;
break ;
default :
p r i n t f ( ” Write t o 0x%04x , l e n %u\n” , a t t h a n d l e , b u f f e r s i z e ) ;
break ;
}
return 0 ;
}
0.99. SDP Client - Query Remote SDP Records. Source Code: sdp general query.c
The example shows how the SDP Client is used to get a list of service records
on a remote device.
0.99.1. SDP Client Setup. SDP is based on L2CAP. To receive SDP query events
you must register a callback, i.e. query handler, with the SPD parser, as shown
in Listing here. Via this handler, the SDP client will receive the following events:
• SDP EVENT QUERY ATTRIBUTE VALUE containing the results of
the query in chunks,
• SDP EVENT QUERY COMPLETE indicating the end of the query and
the status
s t a t i c void s d p g e n e r a l q u e r y i n i t ( void ) {
// i n i t L2CAP
l2cap init () ;
// r e g i s t e r f o r HCI e v e n t s
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
190
0.99.2. SDP Client Query. To trigger an SDP query to get the a list of service
records on a remote device, you need to call sdp client query uuid16() with the
remote address and the UUID of the public browse group, as shown in Listing
here. In this example we used fixed address of the remote device shown in
Listing here. Please update it with the address of a device in your vicinity, e.g.,
one reported by the GAP Inquiry example in the previous section.
switch ( event ) {
case BTSTACK EVENT STATE:
// BTstack a c t i v a t e d , g e t s t a r t e d
if ( b t s t a c k e v e n t s t a t e g e t s t a t e ( p a c k e t ) == HCI STATE WORKING
){
p r i n t f ( ” Connecting t o %s \n” , b d a d d r t o s t r ( r e m o t e a d d r ) ) ;
s d p c l i e n t q u e r y u u i d 1 6 (& h a n d l e s d p c l i e n t q u e r y r e s u l t ,
remote addr , BLUETOOTH PROTOCOL L2CAP) ;
}
break ;
default :
break ;
}
}
0.99.3. Handling SDP Client Query Results. The SDP Client returns the results
of the query in chunks. Each result packet contains the record ID, the Attribute
ID, and a chunk of the Attribute value. In this example, we append new chunks
for the same Attribute ID in a large buffer, see Listing here.
To save memory, it’s also possible to process these chunks directly by a custom
stream parser, similar to the way XML files are parsed by a SAX parser. Have a
look at src/sdp client rfcomm.c which retrieves the RFCOMM channel number
and the service name.
s t a t i c void h a n d l e s d p c l i e n t q u e r y r e s u l t ( uint8 t p a c k e t t y p e ,
uint16 t channel , uint8 t ∗ packet , uint16 t s i z e ) {
UNUSED( p a c k e t t y p e ) ;
UNUSED( c h a n n e l ) ;
UNUSED( s i z e ) ;
switch ( h c i e v e n t p a c k e t g e t t y p e ( p a c k e t ) ) {
191
assertBuffer (
s d p e v e n t q u e r y a t t r i b u t e b y t e g e t a t t r i b u t e l e n g t h ( packet
));
attribute value [ sdp event query attribute byte get data offset
( packet ) ] = s d p e v e n t q u e r y a t t r i b u t e b y t e g e t d a t a ( packet
);
i f ( ( uint16 t ) ( s d p e v e n t q u e r y a t t r i b u t e b y t e g e t d a t a o f f s e t (
p a c k e t ) +1) ==
s d p e v e n t q u e r y a t t r i b u t e b y t e g e t a t t r i b u t e l e n g t h ( packet
) ){
p r i n t f ( ” A t t r i b u t e 0x%04x : ” ,
s d p e v e n t q u e r y a t t r i b u t e b y t e g e t a t t r i b u t e i d ( packet )
);
de du mp da ta el em ent ( a t t r i b u t e v a l u e ) ;
}
break ;
case SDP EVENT QUERY COMPLETE:
i f ( s d p e v e n t q u e r y c o m p l e t e g e t s t a t u s ( packet ) ) {
p r i n t f ( ”SDP query f a i l e d 0x%02x\n” ,
s d p e v e n t q u e r y c o m p l e t e g e t s t a t u s ( packet ) ) ;
break ;
}
p r i n t f ( ”SDP query done . \ n” ) ;
break ;
default :
break ;
}
}
0.100. SDP Client - Query RFCOMM SDP record. Source Code: sdp rfcomm query.c
The example shows how the SDP Client is used to get all RFCOMM service
records from a remote device. It extracts the remote RFCOMM Server Channel,
which are needed to connect to a remote RFCOMM service.
0.101. SDP Client - Query BNEP SDP record. Source Code: sdp bnep query.c
The example shows how the SDP Client is used to get all BNEP service records
from a remote device. It extracts the remote BNEP PAN protocol UUID and
the L2CAP PSM, which are needed to connect to a remote BNEP service.
0.101.1. SDP Client Setup. As with the previous example, you must register a
callback, i.e. query handler, with the SPD parser, as shown in Listing here. Via
this handler, the SDP client will receive events:
192
s t a t i c void s d p b n e p q e u r y i n i t ( void ) {
// i n i t L2CAP
l2cap init () ;
// r e g i s t e r f o r HCI e v e n t s
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
}
switch ( event ) {
case BTSTACK EVENT STATE:
// BTstack a c t i v a t e d , g e t s t a r t e d
if ( b t s t a c k e v e n t s t a t e g e t s t a t e ( p a c k e t ) == HCI STATE WORKING
){
p r i n t f ( ” S t a r t SDP BNEP query . \ n” ) ;
s d p c l i e n t q u e r y u u i d 1 6 (& h a n d l e s d p c l i e n t q u e r y r e s u l t ,
remote , BLUETOOTH PROTOCOL BNEP) ;
}
break ;
default :
break ;
}
}
0.101.3. Handling SDP Client Query Result. The SDP Client returns the result
of the query in chunks. Each result packet contains the record ID, the Attribute
ID, and a chunk of the Attribute value, see Listing here. Here, we show how to
parse the Service Class ID List and Protocol Descriptor List, as they contain the
BNEP Protocol UUID and L2CAP PSM respectively.
193
s t a t i c void h a n d l e s d p c l i e n t q u e r y r e s u l t ( uint8 t p a c k e t t y p e ,
uint16 t channel , uint8 t ∗ packet , uint16 t s i z e ) {
UNUSED( p a c k e t t y p e ) ;
UNUSED( c h a n n e l ) ;
UNUSED( s i z e ) ;
...
switch ( s d p e v e n t q u e r y a t t r i b u t e b y t e g e t a t t r i b u t e i d (
packet ) ) {
// 0 x0001 ” S e r v i c e C l a s s ID L i s t ”
case BLUETOOTH ATTRIBUTE SERVICE CLASS ID LIST :
i f ( d e g e t e l e m e n t t y p e ( a t t r i b u t e v a l u e ) != DE DES)
break ;
f o r ( d e s i t e r a t o r i n i t (& d e s l i s t i t , a t t r i b u t e v a l u e ) ;
d e s i t e r a t o r h a s m o r e (& d e s l i s t i t ) ;
d e s i t e r a t o r n e x t (& d e s l i s t i t ) ) {
uint8 t ∗ e l e m e n t = d e s i t e r a t o r g e t e l e m e n t (&
des list it );
i f ( d e g e t e l e m e n t t y p e ( e l e m e n t ) != DE UUID) continue ;
uint32 t uuid = d e g e t u u i d 3 2 ( e l e m e n t ) ;
switch ( uuid ) {
case BLUETOOTH SERVICE CLASS PANU :
case BLUETOOTH SERVICE CLASS NAP :
case BLUETOOTH SERVICE CLASS GN :
p r i n t f ( ” ∗∗ A t t r i b u t e 0x%04x : BNEP PAN p r o t o c o l
UUID : %04x\n” ,
sdp event query attribute byte get attribute id
( p a c k e t ) , ( int ) uuid ) ;
break ;
default :
break ;
}
}
break ;
...
case BLUETOOTH ATTRIBUTE PROTOCOL DESCRIPTOR LIST: {
p r i n t f ( ” ∗∗ A t t r i b u t e 0x%04x : ” ,
sdp event query attribute byte get attribute id (
packet ) ) ;
uint8 t ∗ e l e m e n t = d e s i t e r a t o r g e t e l e m e n t (&
prot it ) ;
i f ( d e g e t e l e m e n t t y p e ( e l e m e n t ) != DE UUID)
continue ;
uint32 t uuid = d e g e t u u i d 3 2 ( e l e m e n t ) ;
d e s i t e r a t o r n e x t (& p r o t i t ) ;
switch ( uuid ) {
case BLUETOOTH PROTOCOL L2CAP:
i f ( ! d e s i t e r a t o r h a s m o r e (& p r o t i t ) ) continue ;
d e e l e m e n t g e t u i n t 1 6 ( d e s i t e r a t o r g e t e l e m e n t (&
p r o t i t ) , &l2cap psm ) ;
break ;
case BLUETOOTH PROTOCOL BNEP:
i f ( ! d e s i t e r a t o r h a s m o r e (& p r o t i t ) ) continue ;
d e e l e m e n t g e t u i n t 1 6 ( d e s i t e r a t o r g e t e l e m e n t (&
p r o t i t ) , &b n e p v e r s i o n ) ;
break ;
default :
break ;
}
}
p r i n t f ( ” l2cap psm 0x%04x , b n e p v e r s i o n 0x%04x\n” ,
l2cap psm , b n e p v e r s i o n ) ;
}
break ;
...
}
The Service Class ID List is a Data Element Sequence (DES) of UUIDs. The
BNEP PAN protocol UUID is within this list.
The Protocol Descriptor List is DES which contains one DES for each protocol.
For PAN serivces, it contains a DES with the L2CAP Protocol UUID and a PSM,
and another DES with the BNEP UUID and the the BNEP version.
0.103. Testing - Enable Device Under Test (DUT) Mode for Classic.
Source Code: dut mode classic.c
DUT mode can be used for production testing. This example just configures
the Bluetooth Controller for DUT mode.
0.103.1. Bluetooth Logic. When BTstack is up and running, send Enable Device
Under Test Mode Command and print its result.
For more details on discovering remote devices, please see Section on GAP.
0.103.2. Main Application Setup. Listing here shows main application code. It
registers the HCI packet handler and starts the Bluetooth stack.
195
// d i s a b l e S e c u r e Simple P a i r i n n g
gap ssp set enable (0) ;
// make d e v i c e c o n n e c t a b l e
// @note : g a p c o n n e c t a b l e c o n t r o l w i l l be e n a b l e d when an L2CAP
service
// ( e . g . RFCOMM) i s i n i t i a l i z e d ) . T h e r e f o r e , i t ’ s not needed i n
regular applications
gap connectable control (1) ;
// make d e v i c e d i s c o v e r a b l e
gap discoverable control (1) ;
h c i e v e n t c a l l b a c k r e g i s t r a t i o n . c a l l b a c k = &p a c k e t h a n d l e r ;
h c i a d d e v e n t h a n d l e r (& h c i e v e n t c a l l b a c k r e g i s t r a t i o n ) ;
// t u r n on !
h c i p o w e r c o n t r o l (HCI POWER ON) ;
return 0 ;
}
#Chipsets
In this chapter, we first explain how Bluetooth chipsets are connected phys-
ically and then provide information about popular Bluetooth chipset and their
use with BTstack.
0.104. HCI Interface. The communication between a Host (a computer or an
MCU) and a Host Controller (the actual Bluetooth chipset) follows the Host
Controller Interface (HCI), see below. HCI defines how commands, events, asyn-
chronous and synchronous data packets are exchanged. Asynchronous packets
(ACL) are used for data transfer, while synchronous packets (SCO) are used for
Voice with the Headset and the Hands-Free Profiles.
0.104.1. HCI H2. On desktop-class computers incl. laptops, USB is mainly used
as HCI transport layer. For USB Bluetooth chipsets, there is little variation:
most USB dongles on the market currently contain a Broadcom BCM20702 or a
CSR 851x chipset. It is also called H2.
On embedded systems, UART connections are used instead, although USB
could be used as well.
For UART connections, different transport layer variants exist.
0.104.2. HCI H4. The most common one is the official “UART Transport”, also
called H4. It requires hardware flow control via the CTS/RTS lines and assumes
no errors on the UART lines.
196
0.104.3. HCI H5. The “Three-Wire UART Transport”, also called H5, makes
use of the SLIP protocol to transmit a packet and can deal with packet loss and
bit-errors by retransmission. While it is possible to use H5 really with “three
wires” without hardware handshake, we recommend to use a full UART with
hardware handshake. If your design lacks the hardware handshake, H5 is your
only option.
0.104.4. BCSP. The predecessor of H5. The main difference to H5 is that Even
Parity is used for BCSP. To use BCSP with BTstack, you use the H5 transport
and can call hci transport h5 enable bcsp mode
0.104.6. H4 over SPI. Chipsets from Dialog Semiconductor and EM Marin allow
to send H4 formatted HCI packets via SPI. SPI has the benefit of a simpler
implementation for both Host Controller and Host as it does not require an
exact clock. The SPI Master, here the Host, provides the SPI Clock and the
SPI Slave (Host Controller) only has to read and update it’s data lines when the
clock line changes. The EM9304 supports an SPI clock of up to 8 Mhz. However,
an additional protocol is needed to let the Host know when the Host Controller
has HCI packet for it. Often, an additional GPIO is used to signal this.
0.104.7. HCI Shortcomings. Unfortunately, the HCI standard misses a few rele-
vant details:
• For UART based connections, the initial baud rate isn’t defined but most
Bluetooth chipsets use 115200 baud. For better throughput, a higher
baud rate is necessary, but there’s no standard HCI command to change
it. Instead, each vendor had to come up with their own set of vendor-
specific commands. Sometimes, additional steps, e.g. doing a warm reset,
are necessary to activate the baud rate change as well.
• Some Bluetooth chipsets don’t have a unique MAC address. On start,
the MAC address needs to be set, but there’s no standard HCI command
to set it.
• SCO data for Voice can either be transmitted via the HCI interface or
via an explicit PCM/I2S interface on the chipset. Most chipsets default
to the PCM/I2S interface. To use it via USB or for Wide-Band Speech in
the Hands-Free Profile, the data needs to be delivered to the host MCU.
Newer Bluetooth standards define a HCI command to configure the SCO
routing, but it is not implemented in the chipsets we’ve tested so far.
Instead, this is configured in a vendor-specific way as well.
• In addition, most vendors allow to patch or configure their chipsets at
run time by sending custom commands to the chipset. Obviously, this is
also vendor dependent.
0.105. Documentation and Support. The level of developer documentation
and support varies widely between the various Bluetooth chipset providers.
From our experience, only Texas Instruments and EM Microelectronics provide
all relevant information directly on their website. Nordic Semiconductor does not
officially have Bluetooth chipsets with HCI interface, but their documentation
on the nRF5 series is complete and very informative. TI and Nordic also provide
excellent support via their respective web forum.
Infineon acquired Cypress Semiconductor Corporation in 2020, which acquired
the Bluetooth + Wifi division of Broadcom in 2016 provides support via their
Community Forum. In addition, firmware updates (PatchRAM files) for Blue-
tooth + Wifi controllers are available via Murata’s Cypress GitHub.
CSR, which has been acquired by Qualcomm, provides all relevant information
on their Support website after signing an NDA.
198
SCO Multiple
over LE ClassicLE
HCI BD ADDR
HCI LE Roles SC Addr BTstack
Chipset (1) (2) DLE (3)
Type Transport (4) Resolution
folder Comment
Atmel LE H4 Yes n.a No No n.a. Don’t atwilc3000
BLE
ATWILC3000 know Firmware
size: 60 kB
Broadcom Dual H4, Rarely
Partially
No Maybe 43438: bcm Max UART
UART mode H5 (2) (3) Yes baudrate 2
mbps
Broadcom Dual USB Yes Yes No No BCM20702: bcm
USB mode No
Dongles
CSR Dual H4, Rarely
Partially
No No CSR8811: csr
UART mode H5, (2) No
BCSP
CSR Dual USB Mostly
Yes No No CSR8510: csr
USB mode No
Dongles
Infineon Dual H4, Don’tPartially
Yes Yes Yes Yes bcm
CYW207xxmode H5, know(2)
USB
Infineon Dual H4, Don’tPartially
Yes Yes Yes Don’t bcm Keep CTS
CYW208xxmode H5, know(2) know high during
USB power cycle
Infineon Dual H4, Don’tPartially
Don’tOn On On bcm Bluetooth
CYW43xxxmode H5 know(2) knownewer wewer newer + Wifi
+ versions
versionsversions Combo
Wifi Controller
Infineon Dual H4, No Yes Yes Yes Yes Yes bcm Bautobaud-
CYW5557xmode H5 mode
+ needed, see
Wifi posix-h4-
bcm
Cypress LE H4 Don’tn.a. Yes Don’t n.a. Don’t HCI
PSoC 4 know know know Firmware
part of
PSoC
Creator kits
examples
Dialog LE H4 No n.a. Yes Yes n.a. Don’t da145xx Official
DA14531 know HCI
firmware
included in
BTstack
199
SCO Multiple
over LE ClassicLE
HCI BD ADDR
HCI LE Roles SC Addr BTstack
Chipset (1) (2) DLE (3)
Type Transport (4) Resolution
folder Comment
Dialog LE H4, No n.a. No No n.a. Don’t da145xx
Official
DA14581 SPI know HCI
firmware
included in
BTstack
Dialog LE H4, No n.a. Yes Yes n.a. Yes da145xxOfficial
DA14585 SPI HCI
firmware
included in
BTstack
Dialog LE H4, No n.a. Yes Yes n.a. Yes da145xxHCI
DA1469x SPI Firmware
part of
DA1469x
SDK
Espressif Dual VHCI,Yes Yes Yes Yes Yes Don’t SoC with
ESP32 mode H4 know Bluetooth
+ and Wifi
Wifi
Espressif LE VHCI,Yes No Yes Yes Yes Yes SoC with
ESP32- + H4 Bluetooth
S3,C3 Wifi and Wifi
EM LE SPI, No n.a. No No n.a. Don’t em9301Custom
9301 H4 know HCI SPI
implementation
EM LE SPI, Yes n.a. Yes Yes n.a. Don’t em9301Custom
9304 H4 know HCI SPI
implementation
EM LE SPI, Yes n.a. Yes Yes n.a. Yes em9301Custom
9305 H4 HCI SPI
implementation
Intel Dual USB Yes Probably
Don’tDon’t Don’t Don’t intel Firmware
Dual mode knowknow know know size: 400
Wireless kB
3165,
8260,
8265
Nordic LE H4 Fixedn.a. Yes Yes n.a. Yes Requires
nRF Random HCI
firmware
200
SCO Multiple
over LE ClassicLE
HCI BD ADDR
HCI LE Roles SC Addr BTstack
Chipset (1) (2) DLE (3)
Type Transport (4) Resolution
folder Comment
NXP Dual H4 Yes Partially(2)
Yes Yes No Yes nxp Requires
88W8997 mode initial
firmware
NXP Dual H4 Yes No Yes Yes No Yes nxp Requires
IW416 mode initial
firmware
NXP Dual H4 Yes Partially(2)
Yes Yes No Yes nxp Requires
IW61x mode initial
firmware
STM ClassicH4 No Don’t n.a n.a. No n.a. stlc2500d
Custom
STLC2500D know deep sleep
manage-
ment not
supported
Renesas LE H4 No n.a. Yes Yes n.a . Don’t HCI
RX23W know Firmware
part of
BTTS
Realtek Dual H5 Yes Yes Don’tDon’t Don’t Don’t Requires
RTL8822CS
mode knowknow know know initial
+ firmware +
Wifi config
Realtek Dual USB Yes Yes Don’tDon’t Don’t Don’t realtekRequires
USB mode knowknow know know initial
Dongles + firmware +
Wifi config
Toshiba Dual H4 No No No No No No tc3566Only
TC35661 mode -007/009
models
provide full
HCI. See
below
TI Dual H4, Yes Yes No Yes No No cc256xAlso
CC256x, mode H5, for WL185x,
WL183x eHCILL CC256XC WL187x,
and
WL189x
address from the dongle manufacturer, but cheaper ones might come with
identical addresses.
2. SCO over HCI: All Bluetooth Classic chipsets support SCO over HCI in
general. BTstack can receive SCO packets without problems. However,
only TI CC256x has support for using SCO buffers in the Controller and
a useful flow control. On CSR/Broadcom/Cypress Controllers, BTstack
cannot queue multiple SCO packets in the Controller. Instead, the SCO
packet must be sent periodically at the right time - without a clear in-
dication about when this time is. The current implementation observes
the timestamps of the received SCO packets to schedule sending packets.
With full control over the system and no other Bluetooth data, this can
be flawless, but it’s rather fragile in general. For these, it’s necessary
to use the I2S/PCM interface for stable operation. , for those that are
marked with No, we either didn’t try or didn’t found enough information
to configure it correctly.
3. Multiple LE Roles: Apple uses Broadcom Bluetooth+Wifi in their iOS
devices and newer iOS versions support multiple concurrent LE roles, so
at least some Broadcom models support multiple concurrent LE roles.
0.107. Atmel/Microchip. The ATILC3000 Bluetooth/Wifi combo controller
has been used with Linux on embedded devices by Atmel/Microchip. Drivers
and documentation are available from a GitHub repository. The ATWILC3000
has a basic HCI implementation stored in ROM and requires a firmware image
to be uploaded before it can be used. The BLE Controller is qualified as QDID
99659. Please note: the BLE firmware is around 60 kB. It might need a separate
Wifi firmware as well.
BD Addr can be set with vendor-specific command although all chipsets have
an official address stored. The BD ADDR lookup results in “Newport Media
Inc.” which was acquired by Atmel in 2014.
Baud rate can be set with a custom command.
BTstack integration: btstack chipset atwilc3000.c contains the code to down-
load the Bluetooth firmware image into the RAM of the ATWILC3000. After
that, it can be normally used by BTstack.
0.108. Broadcom/Cypress/Infineon Semiconductor. Before the Broadcom
Wifi+Bluetooth division was taken over by Cypress Semiconductor, it was not
possible to buy Broadcom chipset in low quantities. Nevertheless, module man-
ufacturers like Ampak created modules that contained Broadcom BCM chipsets
(Bluetooth as well as Bluetooth+Wifi combos) that might already have been
pre-tested for FCC and similar certifications.
A popular example is the Ampak AP6212A module that contains an BCM
43438A1 and is used on the Raspberry Pi 3, the RedBear Duo, and the RedBear
IoT pHAT for older Raspberry Pi models.
The CYW20704 A2 controller supports both DLE as well as multiple LE roles
and is available e.g. from LairdTech as UART module (BT860), USB module
(BT850), and USB dongle.
Interestingly, the CYW20704 exhibits the same UART flow control bug as the
CC2564. You can add ENABLE CYPRESS BAUDRATE CHANGE FLOWCONTROL BUG WO
202
to activate a workaround and/or read the bug & workardound description in the
TI section below.
The best source for documentation on vendor specific commands so far has
been the source code for blueZ and the Bluedroid Bluetooth stack from Android,
but with the takeover by Cypress, documentation is directly available.
Broadcom USB dongles do not require special configuration, however SCO
data is not routed over USB by default.
The PSoC 4 SoCs can be programmed with the “BLE DTM” HCI Firmware
from the PSoC Creator Kit Examples. The UART baudrate is set to 115200.
For higher baud rates, the clocks probably need to be configured differently, as
the IDE gives a warning about this.
The CYW20819 can be used as a SoC with Cypress’ Bluetooth stack. To use
it as a regular Bluetooth Controller over HCI H4, CTS must be asserted during
Power-Up / Reset.
The CYW43xxx series contains a Wifi and Bluetooth Controller. The Blue-
tooth Controller can be used independent from the Wifi part.
Newer Controller likes the CYW5557x series requires to enter a so-called au-
tobaud mode by asserting CTS (low) during reset/power-up. In this mode, only
a subset of HCI commands are available. Please see posix-h4-bcm port to get
started.
Init scripts: For UART connected chipsets, an init script has to be up-
loaded after power on. For Bluetooth chipsets that are used in Broadcom
Wifi+Bluetooth combos, this file often can be found as a binary file in Linux
distributions with the ending ‘.hcd’ or as part of the WICED SDK as C source
file that contains the init script as a data array for use without a file system.
To find the correct file, Broadcom chipsets return their model number when
asked for their local name.
BTstack supports uploading of the init script in two variants: using .hcd files
looked up by name in the posix-h4 port and by linking against the init script in
the WICED port. While the init script is processed, the chipsets RTS line goes
high, but only 2 ms after the command complete event for the last command from
the init script was sent. BTstack waits for 10 ms after receiving the command
complete event for the last command to avoid sending before RTS goes high and
the command fails.
BD Addr can be set with a custom command. A fixed address is provided
on some modules, e.g. the AP6212A, but not on others.
SCO data can be configured with a custom command found in the bluez
sources. It works with USB chipsets. The chipsets don’t implement the SCO
Flow Control that is used by BTstack for UART connected devices. A forum
suggests to send SCO packets as fast as they are received since both directions
have the same constant speed.
Baud rate can be set with custom command. The baud rate resets during the
warm start after uploading the init script. So, the overall scheme is this: start
at default baud rate, get local version info, send custom Broadcom baud rate
change command, wait for response, set local UART to high baud rate, and then
send init script. After sending the last command from the init script, reset the
203
local UART. Finally, send custom baud rate change command, wait for response,
and set local UART to high baud rate.
BTstack integration: The common code for all Broadcom chipsets is pro-
vided by btstack chipset bcm.c. During the setup, btstack chipset bcm instance
function is used to get a btstack chipset t instance and passed to hci init function.
SCO Data can be routed over HCI for both USB dongles and UART con-
nections, however BTstack only can send audio correctly over UART with newer
Controllers that support SCO Flow Control. HSP and HFP Narrow Band Speech
is supported via I2C/PCM pins. Newer Controllers provide an mSBC codec that
allows to use HSP/HFP incl. WBS over PCM/I2S with ENABLE BCM PCM WBS.
0.109. CSR / Qualcomm Incorporated. CSR plc has been acquired by Qual-
comm Incorporated in August 2015.
Similar to Broadcom, the best source for documentation is the source code for
blueZ.
CSR USB dongles do not require special configuration and SCO data is routed
over USB by default.
CSR chipset do not require an actual init script in general, but they allow to
configure the chipset via so-called PSKEYs. After setting one or more PSKEYs,
a warm reset activates the new setting.
BD Addr can be set via PSKEY. A fixed address can be provided if the
chipset has some kind of persistent memory to store it. Most USB Bluetooth
dongles have a fixed BD ADDR.
SCO data can be configured via a set of PSKEYs. We haven’t been able to
route SCO data over HCI for UART connections yet.
Baud rate can be set as part of the initial configuration and gets actived by
the warm reset.
BTstack integration: The common code for all Broadcom chipsets is pro-
vided by btstack chipset csr.c. During the setup, btstack chipset csr instance
function is used to get a btstack chipset t instance and passed to hci init function.
The baud rate is set during the general configuration.
SCO Data is routed over HCI for USB dongles, but not for UART connections.
HSP and HFP Narrow Band Speech is supported via I2C/PCM pins.
BTstack integration: The common code for the EM9304 is provided by bt-
stack chipset em9301.c. During the setup, btstack chipset em9301 instance func-
tion is used to get a btstack chipset t instance and passed to hci init function.
It enables to set the BD Addr during start.
0.113. Intel Dual Wireless 8260, 8265. Wifi/Bluetooth combo cards mainly
used in mobile computers. The Bluetooth part requires the upload of a firmware
file and a configuration file. SCO, DLE, Multiple roles not tested.
0.114. Nordic nRF5 series. The Single-Mode LE chipsets from the Nordic
nRF5 series chipsets usually do not have an HCI interface. Instead, they provide
an LE Bluetooth Stack as a binary library, the so-called SoftDevices. Developer
can write their Bluetooth application on top of this library. Since the chipset can
be programmed, it can also be loaded with a firmware that provides a regular
HCI H4 interface for a Host.
An interesting feature of the nRF5 chipsets is that they can support multiple
LE roles at the same time, e.g. being Central in one connection and a Peripheral
in another connection. Also, the nRF52 SoftDevice implementation supports the
Bluetooth 4.2 Data Length Extension.
Both nRF5 series, the nRF51 and the nRF52, can be used with an HCI
firmware. The nRF51 does not support encrypted connections at the moment
(November 18th, 2016) although this might become supported as well.
BD ADDR is not set automatically. However, during production, a 64-bit
random number is stored in the each chip. Nordic uses this random number as
a random static address in their SoftDevice implementation.
SCO data is not supported since it is LE only.
Baud rate is fixed to 115200 by the patch although the firmware could be
extended to support a baud rate change.
Init script is not required.
BTstack integration: Support for a nRF5 chipset with the Zephyr Con-
troller is provided by btstack chipset zephyr.c. It queries the static random ad-
dress during init.
To use these chipsets with BTstack, you need to install an arm-none-eabi gcc
toolchain and the nRF5x Command Line Tools incl. the J-Link drivers, checkout
the Zephyr project, apply a minimal patch to help with using a random static
address, and flash it onto the chipset:
• Install J-Link Software and documentation pack.
• Get nrfjprog as part of the nRFx-Command-Line-Tools. Click on Down-
loads tab on the top and look for your OS.
• Checkout Zephyr and install toolchain. We recommend using the arm-
non-eabi gcc binaries instead of compiling it yourself. At least on OS X,
this failed for us.
• In samples/bluetooth/hci uart compile the firmware for nRF52 Dev Kit
$ make BOARD=n r f 5 2 p c a 1 0 0 4 0
206
Baud rate: The baud rate is fixed at 115200 resp. 2000000 with the provided
firmware images. With 2 mbps, there’s no need to update the baudrate at run-
time.
BTstack integration: No special support needed.
0.118. STMicroelectronics. STMicroelectronics has several different Bluetooth
series.
0.118.1. STLC2500D. It offers the Bluetooth V2.1 + EDR chipset STLC2500D
that supports SPI and UART H4 connection.
BD Addr can be set with custom command although all chipsets have an
official address stored.
SCO data might work. We didn’t try.
Baud rate can be set with custom command. The baud rate change of the
chipset happens within 0.5 seconds. At least on BTstack, knowning exactly when
the command was fully sent over the UART is non-trivial, so BTstack switches
to the new baud rate after 100 ms to expect the command response on the new
speed.
Init scripts are not required although it is possible to upload firmware patches.
BTstack integration: Support for the STLC2500C is provided by btstack chipset stlc.c.
During the setup, btstack chipset stlc2500d instance function is used to get a bt-
stack chipset t instance and passed to hci init function. It enables higher UART
baud rate and to set the BD Addr during startup.
0.118.2. BlueNRG. The BlueNRG series is an LE-only SoC which can be used
with an HCI Firmware over a custom SPI interface.
0.118.3. STM32-WB5x. The new STM32-WB5x series microcontroller is an SoC
with a multi-protocol 2.4 Ghz radio co-processor. It provides a virtual HCI
interface.
0.119. Texas Instruments CC256x series. The Texas Instruments CC256x
series is currently in its fourth iteration and provides a Classic-only (CC2560), a
Dual-mode (CC2564), and a Classic + ANT (CC2567) model. A variant of the
Dual-mode chipset is also integrated into TI’s WiLink 8 Wifi+Bluetooth combo
modules of the WL183x, WL185x, WL187x, and WL189x series. Some of the
latter support ANT as well.
The CC256x chipset is connected via an UART connection and supports the
H4, H5 (since third iteration), and eHCILL.
The latest generation CC256xC chipsets support multiple LE roles in parallel.
TI provides an alternative firmware that integrates an SBC Codec in the Blue-
tooth Controller itself for Assisted A2DP (A3DP) and Assisted HFP (Wide-band
speech support). While this can save computation and code size on the main
host, it cannot be used together with BLE, making it useless in most projects.
The different CC256x chipset can be identified by the LMP Subversion re-
turned by the hci read local version information command. TI also uses a nu-
meric way (AKA) to identify their chipsets. The table shows the LMP Subversion
and AKA number for the CC256x and the WL18xx series.
208
SCO data: Routing of SCO data can be configured with the HCI VS Write SCO Configuration
command.
Baud rate can be set with HCI VS Update UART HCI Baudrate. The chipset
confirms the change with a command complete event after which the local UART
is set to the new speed. Oddly enough, the CC256x chipsets ignore the incoming
CTS line during this particular command complete response.
If you’ve implemented the hal uart dma.h without an additional ring buffer
(as recommended!) and you have a bit of delay, e.g. because of thread switch-
ing on a RTOS, this could cause a UART overrun. If this happens, BTstack
provides a workaround in the HCI H4 transport implementation by adding
ENABLE CC256X BAUDRATE CHANGE FLOWCONTROL BUG WORKAROUND. If this
is enabled, the H4 transport layer will resort to “deep packet inspection” to first
check if its a TI controller and then wait for the HCI VS Update UART HCI Baudrate.
When detected, it will tweak the next UART read to expect the HCI Command
Complete event.
BD Addr can be set with HCI VS Write BD Addr although all chipsets have an
official address stored.
Init Scripts. In order to use the CC256x chipset an initialization script must
be obtained and converted into a C file for use with BTstack. For newer revisions,
TI provides a main.bts and a ble add on.bts that need to be combined.
The Makefile at chipset/cc256x/Makefile.inc is able to automatically download
and convert the requested file. It does this by:
• Downloading one or more BTS files for your chipset.
• Running the Python script:
. / c o n v e r t b t s i n i t s c r i p t s . py main . b t s [ b l e a d d o n . b t s ] o u t p u t f i l e .
c
BTstack integration: - The common code for all CC256x chipsets is pro-
vided by btstack chipset cc256x.c. During the setup, btstack chipset cc256x instance
function is used to get a btstack chipset t instance and passed to hci init function.
btstack chipset cc256x lmp subversion provides the LMP Subversion for the se-
lected init script. - SCO Data is be routed over HCI with ENABLE SCO OVER HCI
or to PCM/I2S with ENABLE SCO OVER PCM. Wide-band speech is supported
in both cases. For SCO-over-HCI, BTstack implements the mSBC Codec. For
SCO-over-I2S, Assisted HFP can be used. - Assisted HFP: BTstack provides sup-
port for Assisted HFP mode if enabled with ENABLE CC256X ASSISTED HFP and
SCO is routed over PCM/I2S with ENABLE SCO OVER PCM. During startup,
209
the PCM/I2S is configured and the HFP implementation will enable/disable the
mSBC Codec for Wide-band-speech when needed.
Known issues: - The CC2564C v1.5 may loose the connection in Peripheral
role with a Slave Latency > 0 when the Central updates Connection Parameters.
See https://github.com/bluekitchen/btstack/issues/429
0.120. Toshiba. The Toshiba TC35661 Dual-Mode chipset is available in three
variants: standalone incl. binary Bluetooth stack, as a module with embedded
stack or with a regular HCI interface. The HCI variant has the model number
TC35661–007 resp TC35561-009 for the newer silicon.
We first tried their USB Evaluation Stick that contains an USB-to-UART
adapter and the PAN1026 module that contains the TC35661 -501. While it does
support the HCI interface and Bluetooth Classic operations worked as expected,
LE HCI Commands are not supported. With the -007 and the -009 models,
everything works as expected.
SCO data does not seem to be supported.
Baud rate can be set with custom command.
BD Addr must be set with custom command. It does not have a stored
valid public BD Addr.
Init Script is not required. A patch file might be uploaded.
BTstack integration: Support for the TC35661 series is provided by bt-
stack chipset tc3566x.c. During the setup, btstack chipset tc3566x instance func-
tion is used to get a btstack chipset t instance and passed to hci init function.
It enables higher UART baud rate and sets the BD Addr during startup.
#Porting to Other Platforms
In this section, we highlight the BTstack components that need to be adjusted
for different hardware platforms.
0.121. Time Abstraction Layer. BTstack requires a way to learn about pass-
ing time. btstack run loop embedded.c supports two different modes: system ticks
or a system clock with millisecond resolution. BTstack’s timing requirements are
quite low as only Bluetooth timeouts in the second range need to be handled.
0.121.1. Tick Hardware Abstraction. If your platform doesn’t require a system
clock or if you already have a system tick (as it is the default with CMSIS on
ARM Cortex devices), you can use that to implement BTstack’s time abstraction
in include/btstack/hal tick.h>.
For this, you need to define HAVE EMBEDDED TICK in btstack config.h:
Then, you need to implement the functions hal tick init and hal tick set handler,
which will be called during the initialization of the run loop.
void h a l t i c k i n i t ( void ) ;
void h a l t i c k s e t h a n d l e r ( void ( ∗ t i c k h a n d l e r ) ( void ) ) ;
int h a l t i c k g e t t i c k p e r i o d i n m s ( void ) ;
210
After BTstack calls hal tick init() and hal tick set handler(tick handler), it ex-
pects that the tick handler gets called every hal tick get tick period in ms() ms.
0.121.2. Time MS Hardware Abstraction. If your platform already has a system
clock or it is more convenient to provide such a clock, you can use the Time MS
Hardware Abstraction in include/btstack/hal time ms.h.
For this, you need to define HAVE EMBEDDED TIME MS in btstack config.h:
Then, you need to implement the function hal time ms(), which will be called
from BTstack’s run loop and when setting a timer for the future. It has to return
the time in milliseconds.
uint32 t h a l t i m e m s ( void ) ;
Even better would be the use of on-chip DMA modules for these block reads, if
available.
The BTstack UART Hardware Abstraction Layer API reflects this design ap-
proach and the underlying UART driver has to implement the following API:
0.123.3. H5. H5, makes use of the SLIP protocol to transmit a packet and can
deal with packet loss and bit-errors by retransmission. Since it can recover from
packet loss, it’s also possible for either side to enter sleep mode without loosing
synchronization.
The use of hardware flow control in H5 is optional, however, since BTstack
uses hardware flow control to avoid packet buffers, it’s recommended to only use
H5 with RTS/CTS as well.
For porting, the implementation follows the regular H4 protocol described
above.
0.124. Persistent Storage APIs. On embedded systems there is no generic
way to persist data like link keys or remote device names, as every type of a
212
device has its own capabilities, particularities and limitations. The persistent
storage APIs provides an interface to implement concrete drivers for a particular
system.
0.124.1. Link Key DB. As an example and for testing purposes, BTstack pro-
vides the memory-only implementation btstack link key db memory. An imple-
mentation has to conform to the interface in Listing below.
typedef struct {
// management
void ( ∗ open ) ( ) ;
void ( ∗ c l o s e ) ( ) ;
// l i n k key
int ( ∗ g e t l i n k k e y ) ( bd addr t bd addr , l i n k k e y t l i n k k e y ) ;
void ( ∗ p u t l i n k k e y ) ( bd addr t bd addr , l i n k k e y t key ) ;
void ( ∗ d e l e t e l i n k k e y ) ( bd addr t bd addr ) ;
} btstack link key db t ;
#Existing Ports
$ cd p o r t / a p o l l o 2 −em9304
$ . / c r e a t e e x a m p l e s . py
214
0.126.4. Compile & Run Example Project. Go to to the gcc folder of one of the
example folders and run make
$ make
To upload, please follow the instructions in the Apollo Getting Started docu-
ments.
0.126.5. Debug output. printf is routed over the USB connector of the EVB at
115200.
In port/apollo2-em9304/btstack config.h additional debug information can be
enabled by uncommenting ENABLE LOG INFO.
Also, the full packet log can be enabled in src/btstack port.c by uncommenting
the hci dump init(..) line. The console output can then be converted into .pklg
files for OS X PacketLogger or WireShark by running tool/create packet log.py
0.126.6. TODO.
• BTstack’s TLV persisten storage via Flash memory is not implemented
yet.
• SPI Fullduplex: Newer Apollo 2 revisions supports SPI Full Duplex. The
Ambiq Suite 1.2.11 does not cover Full Duplex with IRQ callback. It
could be emulated by setting the Full Duplex mode and doing a regular
write operation. When the write is complete, the received data can be
read from the IOM FIFO.
• During MCU sleep without an ongoing SPI operation, the SPI could be
fully disabled, which would reduce enrgey consumption.
0.127. Archive of earlier ports. The ports in this folder are not recommended
for new designs. This does not mean that the target hardware is not suitable for
new designs, just that the ports would need to reworked/refreshed.
List of ports with reason for move to this archive:
• MSP430 ports: The ports used the not-maintained version of the com-
munity MSP430 gcc port, which does not support more than 64 kB of
FLASH RAM. A current port should use the official GCC version spon-
sored by TI. In addition, the MSP430 UART does not support hardware
RTS/CTS. For a new port, our ringbuffer approach should be used. In-
dividual ports:
– EZ430-RF256x Bluetooth Evaluation Tool for MSP430
– MSP430F5438 Experimenter Board for MSP430 with Bluetooth CC2564
Module Evaluation Board
– MSP-EXP430F5529LP LaunchPad with Bluetooth CC2564 Mod-
ule Evaluation Board and EM Adapter BoosterPack with additional
32768Hz quartz oscillator
215
0.128. BTstack Port for the Espressif ESP32 Platform. Status: Basic
port incl. all examples. BTstack runs on dedicated FreeRTOS thread. Multi
threading (calling BTstack functions from a different thread) is not supported.
0.128.1. Setup.
• Follow Espressif IoT Development Framework (ESP-IDF) setup to install
XTensa toolchain and the ESP-IDF.
• Currently used for testing: ESP-IDF v4.4 or v5.0
. / i n t e g r a t e b t s t a c k . py
The script will copy parts of the BTstack tree into the ESP-IDF as $IDF PATH/components/btsta
and then create project folders for all examples.
Each example project folder, e.g. port/esp32/examples/spp and le counter,
contains a CMake project file. Please run the integrate btstack .py command again
after updating the BTstack tree (e.g. by git pull) to also update the copy in the
ESP-IDF.
The examples are configure for the original ESP32. IF you want to use the
newer ESP32-C3 or ESP32-S3 - both only support Bluetooth LE - you need to:
1. set target:
‘ i d f . py s e t −t a r g e t esp32c3 ‘
or
‘ i d f . py s e t −t a r g e t e s p 3 2 s 3 ‘
i d f . py
i d f . py −p PATH−TO−DEVICE f l a s h
i d f . py monitor
If support for the LyraT v4.3 is enabled via menuconfig - Example Board Con-
figuration –> ESP32 board –> ESP32-LyraT V4.3, CONFIG ESP LYRAT V4 3 BOARD
gets defined and the ES8388 will be configured as well.
217
We’ve also used the MAX98357A on the Adafruit breakout board. The sim-
plest audio example is the mod player, which plays back an 8 kB sound file and
the a2dp sink demo that implements a basic Bluetooth loudspeaker.
0.128.7. ESP32 printf/log. The BTstack port setups a buffered output for print-
f/ESP log macros. However, if that gets full, the main thread will get blocked.
If you’re playing audio, e.g. a2dp sink demo, and a lot of text is sent over the
UART, this will cause audio glitches as the I2S DMA driver isn’t re-filled on
time. If this happens, you can increase the UART baudrate, reduce the debug
output or increase the output buffer size - or any combination of these. :)
0.129.1. Overview. This port assumes that FreeBSD provides an ng hci netgraph
node for a connected Bluetooth Controller. In most cases, these are Bluetooth
USB dongles or built-in Bluetooth Controller connected via USB.
For Bluetooth Controllers connected via UART, the POSX-H4 port might be
a better option als
0.129.3. Compilation. BTstack’s FeeeBSD port does not have additional depen-
dencies. To compile the cmake project with make
mkdir b u i l d
cd b u i l d
cmake . .
make
or using Ninja:
218
mkdir n i n j a
cd n i n j a
cmake . .
ninja
0.129.4. Running the examples. As the port needs to reconfigure the Bluetooth
netgraph node, it needs to run with root privileges. It tries to connect to ‘ubt0hci’
by default. If your Bluetooth Controller is different, you can select it with ‘-
u node’ On start, BTstack prints the path to the packet log and prints the
information on the detected Buetooth Controller.
$ sudo g a t t c o u n t e r
Packet Log : /tmp/ hci dump . p k l g
BTstack c o u n t e r 0001
BTstack up and r u n n i n g on 0 0 : 1A: 7D:DA: 7 1 : 1 3 .
0.129.5. ToDO.
• drop privileges after startup
• auto-detect ng hci node
• support for profiles that require SCO: HFP & HSP
0.130. BTstack Port for POSIX Systems with libusb Library.
0.130.1. Compilation. The quickest way to try BTstack is on a Linux or OS X
system with an additional USB Bluetooth dongle. It requires pkg-config and
libusb-1.0 or higher to be installed.
On a recent Debian-based system, all you need is:
make
mkdir b u i l d
cd b u i l d
cmake −G N i n j a
ninja
0.130.3. Linux. On Linux, the USB Bluetooth dongle is usually not accessible
to a regular user.
You can add a udev rule for your dongle to extend access rights to user pro-
cesses.
For this, create /etc/udev/rules.d/btstack.rules and add this
# Match a l l d e v i c e s from R e a l t e k
SUBSYSTEM==” usb ” , ATTRS{ idVendor}==” 0bda” , MODE=” 0666 ”
0.130.4. macOS. On macOS, the OS will try to use a plugged-in Bluetooth Con-
troller if one is available. It’s best to to tell the OS to always use the internal
Bluetooth Contoller.
For this, execute:
and you didn’t start another instance and you didn’t assign the USB Controller
to a virtual machine, macOS uses the plugged-in Bluetooth Controller. Please
configure NVRAM as explained and try again after a reboot.
’BCM20702A). The chipset support uses this information to look for a local
PatchRAM file of that name and uploads it.
0.130.6. Realtek Controllers. During startup, the libusb HCI transport imple-
mentations reports the USB Vendor/Product ID, which is then forwarded to the
Realtek chipset support. The chipset support contains a mapping between USB
Product ID and ( Patch, Configuration ) files. If found, these are uploaded.
0.130.7. Running the examples. BTstack’s HCI USB transport will try to find a
suitable Bluetooth module and use it.
On start, BTstack will try to find a suitable Bluetooth module. It will also
print the path to the packet log as well as the USB path.
$ ./ le counter
Packet Log : /tmp/ hci dump . p k l g
BTstack c o u n t e r 0001
Packet Log : /tmp/ hci dump 6 . p k l g
USB d e v i c e 0 x0a12 /0 x0001 , path : 06
Local version information :
− HCI V e r s i o n 0 x0006
− HCI R e v i s i o n 0 x22bb
− LMP V e r s i o n 0 x0006
− LMP S u b v e r s i o n 0 x22bb
− Manufacturer 0 x000a
BTstack up and r u n n i n g on 0 0 : 1A: 7D:DA: 7 1 : 0 1 .
If you want to run multiple examples at the same time, it helps to fix the path
to the used Bluetooth module by passing -u usb-path to the executable.
Example running le streamer and le streamer client in two processes, using
CSR Bluetooth dongles at USB path 6 and 4:
. / l e s t r e a m e r −u 6
S p e c i f i e d USB Path : 06
Packet Log : /tmp/ hci dump 6 . p k l g
USB d e v i c e 0 x0a12 /0 x0001 , path : 06
Local version information :
− HCI V e r s i o n 0 x0006
− HCI R e v i s i o n 0 x22bb
− LMP V e r s i o n 0 x0006
− LMP S u b v e r s i o n 0 x22bb
− Manufacturer 0 x000a
BTstack up and r u n n i n g on 0 0 : 1A: 7D:DA: 7 1 : 0 1 .
To s t a r t t h e s t r e a m i n g , p l e a s e run t h e l e s t r e a m e r c l i e n t example on
o t h e r d e v i c e , o r u s e some GATT E x p l o r e r , e . g . LightBlue ,
BLExplr .
$ . / l e s t r e a m e r c l i e n t −u 4
S p e c i f i e d USB Path : 04
Packet Log : /tmp/ hci dump 4 . p k l g
USB d e v i c e 0 x0a12 /0 x0001 , path : 04
221
0.131. BTstack Port for POSIX Systems with Intel Wireless 8260/8265
Controllers. Same as port/libusb, but customized for Intel Wireless 8260 and
8265 Controllers. These controller require firmware upload and configuration to
work. Firmware and config is downloaded from the Linux firmware repository.
make
0.131.2. Environment. On Linux, the USB Bluetooth dongle is usually not ac-
cessible to a regular user. You can either: - run the examples as root - add a
udev rule for your dongle to extend access rights to user processes
To add an udev rule, please create /etc/udev/rules.d/btstack.rules and add this
# Match DeLOCK B l u e t o o t h 4 . 0 d o n g l e
SUBSYSTEM==” usb ” , ATTRS{ idVendor}==” 0 a5c ” , ATTRS{ d e v i c e}==” 21 e8 ” ,
MODE=” 0666 ”
0.131.3. Running the examples. BTstack’s HCI USB transport will try to find a
suitable Bluetooth module and use it.
On start, BTstack will try to find a suitable Bluetooth module. It will also
print the path to the packet log as well as the USB path.
$ ./ le counter
Packet Log : /tmp/ hci dump . p k l g
USB Path : 03−01−04−03
Firwmare . / i b t −12−16. s f i
Firmware upload c o m p l e t e
Firmware o p e r a t i o n a l
Done 1
BTstack c o u n t e r 0001
USB Path : 03−01−04−03
. / l e s t r e a m e r −u 6
S p e c i f i e d USB Path : 06
Packet Log : /tmp/ hci dump 6 . p k l g
USB Path : 06
BTstack up and r u n n i n g on 0 0 : 1A: 7D:DA: 7 1 : 1 3 .
To s t a r t t h e s t r e a m i n g , p l e a s e run t h e l e s t r e a m e r c l i e n t example on
o t h e r d e v i c e , o r u s e some GATT E x p l o r e r , e . g . LightBlue ,
BLExplr .
$ . / l e s t r e a m e r c l i e n t −u 4
S p e c i f i e d USB Path : 04
Packet Log : /tmp/ hci dump 4 . p k l g
USB Path : 04
BTstack up and r u n n i n g on 0 0 : 1A: 7D:DA: 7 1 : 1 3 .
Start scanning !
223
0.132.1. Software. The Maxim ARM Toolchain is free software that provides
peripheral libraries, linker files, initial code and some board files. It also provides
Eclipse Neon and Maxim modified OpenOCD to program the microcontroller
together with various examples for Maxim Cortex M4F ARM processors.
For debugging, OpenOCD can be used. The regular OpenOCD does not sup-
port Maxim ARM microcontrollers yet, but a modified OpenOCD for use with
Maxim devices can be found in the Maxim ARM Toolchain.
0.132.3. Usage. The examples can be compiled using GNU ARM Toolchain. A
firmware binary can be flashed either by copying the .bin file to the DAPLINK
mass storage drive, or by using OpenOCD on the command line, or from Eclipse
CDT.
0.132.4. Build. Checkt that MAXIM PATH points to the root directory where
the tool chain installed. Then, go to the port/max32630-fthr folder and run
“make” command in terminal to generate example projects in the example folder.
In each example folder, e.g. port/max323630-fthr/example/spp and le streamer,
you can run “make” again to build an .elf file in the build folder which is conve-
nient for debugging using Eclipse or GDB.
For flashing via the virtual USB drive, the “make release” command will gen-
erate .bin file in the build folder.
0.132.5. Eclipse. Toolchain and Eclipse guide can be found in README.pdf file
where the Maxim Toolchain is installed. Please note that this port was done
using Makefiles.
0.132.6. Flashing Max32630 ARM Processor. There are two ways to program
the board. The simplest way is drag and drop the generated .bin file to the
DAPLINK mass storage drive. Once the file is copied to the mass storage device,
the DAPLINK should program and then run the new firmware.
Alternatively, OpenOCD can be used to flash and debug the device. A suitable
programming script can be found in the scripts folder.
224
0.132.7. Debugging. OpenOCD can also be used for developing and especially
for debugging. Eclipse or GDB via OpenOCD could be used for step by step
debugging.
0.132.9. TODOs.
• Support for BTSTACK STDIN
• Add flash-openocd to Makefile template
• Add Eclipse CDT projects for max32630fthr
• Implement hal led.h to control LED on board
0.133.2. Software. To build all examples, you need the regular ARM GCC toolc-
ahin installed. Run make
$ make
All examples and the .jdebug Ozone project files are placed in the ‘gcc’ folder.
0.133.3. Flash And Run The Examples. The Makefile builds different versions: -
example.elf: .elf file with all debug information - example.bin: .bin file that can
be used for flashing
There are different options to flash and debug the MSP432P401R LaunchPad.
If all but the jumpers for power (the left three) are removed on J101, an external
JTAG like SEGGER’s J-Link can be connected via J8 ‘MSP432 IN’.
0.133.4. Run Example Project using Ozone. When using an external J-Link pro-
grammer, you can flash and debug using the cross-platform SEGGER Ozone
Debugger. It is included in some J-Link programmers or can be used for free for
evaluation usage.
Just start Ozone and open the .jdebug file in the build folder. When compiled
with ENABLE SEGGER RTT, the debug output shows up in the Terminal window
of Ozone.
0.133.5. Debug output. All debug output is send via SEGGER RTT or via US-
ART2. To get the console from USART2, remove ENABLE SEGGER RTT from
btstack config.h and open a terminal to the virtual serial port of the Launchpad
at 115200.
In btstack config.h resp. in example/btstack config.h of the generated projects,
additional debug information can be disabled/enabled via ENABLE LOG INFO.
Also, the full packet log can be enabled in main.c by uncommenting the
hci dump init(..) line. The output can then be converted into .pklg files for
OS X PacketLogger or WireShark by running tool/create packet log.py
0.133.6. GATT Database. In BTstack, the GATT Database is defined via the
.gatt file in the example folder. The Makefile contains rules to update the .h file
when the .gatt was modified.
0.134. BTstack Port with Cinnamon for Nordic nRF5 Series. Cinnamon
is BlueKitchen’s minimal, yet robust Controller/Link Layer implementation for
use with BTstack.
In contrast to common Link Layer implementations, our focus is on a ro-
bust and compact implementation for production use, where code size matters
(e.g. current code size about 8 kB).
0.134.1. Status. The current implementation supports a single Peripheral role,
or, passive scanning in Observer role. In the Peripheral role, channel map up-
dates, as well as connection param updates are supported.
Support for LE Central Role as well as Encryption is planned but not sup-
ported yet.
226
0.134.2. Requirements.
• arm-none-eabi toolchain
• Nordic’s nRF5-SDK
0.134.3. Supported Hardware. All nNRF5x SOCs. Built files are provided for
PCA10040 (52832 DK), but others can be supported with minimal changes.
0.134.4. Use.
• Provide path to nRF5-SDK either in NRF5 SDK ROOT environment vari-
able or directly in pca10040/armgcc/Makefile.
• run make
• All supported examples are built in the build folder.
• You can use Segger’s OZONE with the provided EXAMPLE.jdebug project
file to flash and run the examples.
0.135.2. TI CC256x. The CC2564x needs the correct init script to start up. The
Makfile already has entries for most silicon revisions:
• CC2560: bluetooth init cc2564 2.14.c
• CC2564B: bluetooth init cc2564B 1.8 BT Spec 4.1.c
• CC2564C: bluetooth init cc2564C 1.5.c
Please pick the correct one. The main.c verifies that the correct script is
loaded, but the init script is linked to the executable.
make
227
0.135.5. Running the examples. On start, BTstack prints the path to the packet
log and prints the information on the detected Buetooth Controller.
$ ./ le counter
Packet Log : /tmp/ hci dump . p k l g
BTstack c o u n t e r 0001
BTstack up and r u n n i n g on 0 0 : 1A: 7D:DA: 7 1 : 1 3 .
Please note that BTstack will increase the baudrate. Before starting again,
you should reset or power-cycle the Bluetooth Controller.
0.137. BTstack Port for POSIX Systems with modern Infineon (CYW)
H4 Bluetooth Controller.
0.137.1. Configuration. Newer Infineon Airoc (tm) Controllers like the CYW5557x
series accept PatchRAM upload only in a so-called ‘auto-baud mode’ which is en-
tered by asserting CTS (low) and starting/resetting the controller via BT REG EN.
This port currently only supports the CYW5557x Controllers.
0.137.2. Compilation. BTstack’s posix-h4-bcm port does not have additional de-
pendencies. You can directly run cmake and then your default build system. E.g.
with Ninja:
mkdir b u i l d
cd b u i l d
cmake −G N i n j a . .
ninja
0.137.3. Running the examples. On start, BTstack opens the serial port, which
asserts CTS, and requests you to reset the Controller with a countdown.
$ ./ gatt counter
Packet Log : /tmp/ hci dump . p k l g
Phase 1 : Download f i r m w a r e
P l e a s e r e s e t B l u e t o o t h C o n t r o l l e r , e . g . v i a RESET button . Firmware
download s t a r t s i n :
3
2
1
Firmware download s t a r t e d
Local version information :
− HCI V e r s i o n 0 x000a
− HCI R e v i s i o n 0 x0b73
− LMP V e r s i o n 0 x000a
− LMP S u b v e r s i o n 0 x2257
− Manufacturer 0 x0009
Phase 2 : Main app
BTstack up and r u n n i n g a t 5 5 : 5 6 : 0A: 0A: 7 6 : 9 3
...
0.137.4. ToDo.
• select PatchRAM file based on HCI Read Local Version Information
After Power Cycle, please start one of the test applications and press the Reset
button to trigger firmware download.
Please note that it does not detect if the firmware has already been down-
loaded, so you need to Power Cycle the DA14531 before starting an example
again.
Alternatively, after running one of the examples once to upload the firmware,
you can use the regular ‘posix-h4’ port and change the initial UART baud rate
to 460800 as long as you don’t power cycle the dev kit.
For production use, the DA14531 could be power cycled from the main CPU
during startup, e.g. after the call to btstack chipset da145xx download firmware with uart,
or, the HCI firmware could be burned into the OTP.
After compilation with Keil uVision 5, the generated .hex file is copied into bt-
stack/chipset/da145xx as hci 531 active uart 460800 .hex, and then ‘convert hex files”
is used to convert it into a C data array.
0.140. Hardware Setup - Dev Kit Pro. To use the DA14531 Dev Kit Pro
with BTstack, please make the following modifications: - Follow Chapter 4.1 and
Figure 4 in the DA14531 Development Kit Pro Hardware User Manual UM-B-
114 and set SW1 of the 14531 daughter board into position “BUCK” position
231
marked with an “H” on the left side. - configure the dev kit for Full UART
(4-wire) Configuration by adding jumper wires between J1 and J2
0.141. Hardware Setup - Dev Kit USB. To use the Dev Kit USB with
BTstack, please make the following modifications: - Follow Chapter 5.6 in the
DA14531 USB Development Kit Hardware UM-B-125 and set the DIP switches
as described.
# Example Run
$ ./ gatt counter
Packet Log : /tmp/ hci dump . p k l g
Phase 1 : Download f i r m w a r e
Phase 2 : Main app
BTstack c o u n t e r 0001
BTstack up and r u n n i n g on 8 0 :EA:CA: 7 0 : 0 0 : 0 8 .
For newer Controllers, e.g. IW416 or IW612, the firmware can be selected auto-
matically.
0.144.2. Compilation. BTstack’s posix-h4-nxp port does not have additional de-
pendencies. You can directly run cmake and then your default build system.
E.g. with Ninja:
mkdir b u i l d
cd b u i l d
cmake −G N i n j a . .
ninja
0.144.3. Running the examples. Please reset the Controller first. On start, BT-
stack prints the path to the packet log.
$ ./ gatt counter
Packet Log : /tmp/ hci dump . p k l g
BTstack c o u n t e r 0001
BTstack up and r u n n i n g on 0 0 : 1A: 7D:DA: 7 1 : 1 3 .
0.144.4. Issues.
• NXP 88W8997 does not support SCO Flow Control which causes glitches
when sending audio
0.144.5. ToDo.
• increase baud rate for firmware upload
• skip firmware upload if firmware already present
• increase baud rate for application
0.145.1. Prepare Zephyr Controller. Please follow this blog post about how to
compile and flash samples/bluetooth/hci uart to a connected nRF5 dev kit.
In short: you need to install an arm-none-eabi gcc toolchain and the nRF5x
Command Line Tools incl. the J-Link drivers, checkout the Zephyr project, and
flash an example project onto the chipset:
• Install J-Link Software and documentation pack.
• Get nrfjprog as part of the nRFx-Command-Line-Tools. Click on Down-
loads tab on the top and look for your OS.
• Checkout Zephyr and install toolchain. We recommend using the arm-
non-eabi gcc binaries instead of compiling it yourself. At least on OS X,
this failed for us.
233
0.145.2. Configure serial port. To set the serial port of your Zephyr Controller,
you can either update config.device name in main.c or always start the examples
with the −u /path/to/serialport option.
$ make
0.145.4. Run example. Just run any of the created binaries, e.g.
$ ./ le counter
0.146.2. TI CC256x. The CC2564x needs the correct init script to start up. The
Makfile already has entries for most silicon revisions:
• CC2560: bluetooth init cc2564 2.14.c
• CC2564B: bluetooth init cc2564B 1.8 BT Spec 4.1.c
• CC2564C: bluetooth init cc2564C 1.5.c
Please pick the correct one. The main.c verifies that the correct script is
loaded, but the init script is linked to the executable.
$ ./ le counter
Packet Log : /tmp/ hci dump . p k l g
BTstack c o u n t e r 0001
USB Path : 06
BTstack up and r u n n i n g on 0 0 : 1A: 7D:DA: 7 1 : 1 3 .
0.147. BTstack Port for QT with USB Bluetooth Dongle. Uses libusb
Library on macOS and Linux and WinUSB on Windows. Windows is supported
with the MinGW Kit.
Windows with MSVC or Embedded (bare metal) platforms not supported yet.
0.147.1. Compilation. On all platforms, you’ll need Qt Python 3 installed. On
macOS/Linux libusb-1.0 or higher is required, too.
When everything is ready, you can open the provided CMakelists.txt project
in Qt Creator and run any of the provided examples. See Qt documentation on
how to compile on the command line or with other IDEs
0.147.2. Environment Setup.
0.147.3. Windows. To allow WinUSB to access an USB Bluetooth dongle, you
need to install a special device driver to make it accessible to user space processes.
It works like this:
• Download Zadig
• Start Zadig
• Select Options -> “List all devices”
• Select USB Bluetooth dongle in the big pull down list
• Select WinUSB in the right pull down list
• Select “Replace Driver”
0.147.4. Linux. On Linux, the USB Bluetooth dongle is usually not accessible
to a regular user. You can either: - run the examples as root - add a udev rule
for your dongle to extend access rights to user processes
To add an udev rule, please create /etc/udev/rules.d/btstack.rules and add this
# Match DeLOCK B l u e t o o t h 4 . 0 d o n g l e
SUBSYSTEM==” usb ” , ATTRS{ idVendor}==” 0 a5c ” , ATTRS{ d e v i c e}==” 21 e8 ” ,
MODE=” 0666 ”
0.147.5. macOS. On macOS, the OS will try to use a plugged-in Bluetooth Con-
troller if one is available. It’s best to to tell the OS to always use the internal
Bluetooth Contoller.
For this, execute:
and you didn’t start another instance and you didn’t assign the USB Controller
to a virtual machine, macOS uses the plugged-in Bluetooth Controller. Please
configure NVRAM as explained and try again after a reboot.
0.147.6. Running the examples. BTstack’s HCI USB transport will try to find a
suitable Bluetooth module and use it.
On start, BTstack will try to find a suitable Bluetooth module. It will also
print the path to the packet log as well as the USB path.
$ ./ le counter
Packet Log : /tmp/ hci dump . p k l g
BTstack c o u n t e r 0001
USB Path : 06
BTstack up and r u n n i n g on 0 0 : 1A: 7D:DA: 7 1 : 1 3 .
If you want to run multiple examples at the same time, it helps to fix the path
to the used Bluetooth module by passing -u usb-path to the executable.
236
. / l e s t r e a m e r −u 6
S p e c i f i e d USB Path : 06
Packet Log : /tmp/ hci dump 6 . p k l g
USB Path : 06
BTstack up and r u n n i n g on 0 0 : 1A: 7D:DA: 7 1 : 1 3 .
To s t a r t t h e s t r e a m i n g , p l e a s e run t h e l e s t r e a m e r c l i e n t example on
o t h e r d e v i c e , o r u s e some GATT E x p l o r e r , e . g . LightBlue ,
BLExplr .
$ . / l e s t r e a m e r c l i e n t −u 4
S p e c i f i e d USB Path : 04
Packet Log : /tmp/ hci dump 4 . p k l g
USB Path : 04
BTstack up and r u n n i n g on 0 0 : 1A: 7D:DA: 7 1 : 1 3 .
Start scanning !
0.148.1. Raspberry Pi 3 / Zero W Setup. There are various options for setting
up the Raspberry Pi, have a look at the Internet. Here’s what we did:
0.148.3. Configure Wifi. Create the file wpa supplicant.conf in the root folder of
the SD Card with your Wifi credentials:
0.148.4. Enable SSH. Create an empty file called ‘ssh’ in the root folder of the
SD Card to enable SSH.
0.148.5. Boot. If everything was setup correctly, it should now boot up and join
your Wifi network. You can reach it via mDSN as ‘raspberrypi.local’ and log in
with user: pi, password: raspberry.
0.148.6. Disable bluez. By default, bluez will start up using the the BCM4343.
To make it available to BTstack, you can disable its system services:
$ sudo s y s t e m c t l d i s a b l e h c i u a r t
$ sudo s y s t e m c t l d i s a b l e b t h e l p e r
$ sudo s y s t e m c t l d i s a b l e b l u e t o o t h
and if you don’t want to restart, you can stop them right away. Otherwise,
please reboot here.
$ sudo s y s t e m c t l s t o p h c i u a r t
$ sudo s y s t e m c t l s t o p b t h e l p e r
$ sudo s y s t e m c t l s t o p b l u e t o o t h
$ rpxc bash
$ cd b t s t a c k / p o r t / r a s p i
$ make
For regular use, it makes sense to add Python permanently to the Docker
container. See documentation at GitHub.
0.148.9. Running the examples. Copy one of the examples to the Rasperry Pi
and just run them. BTstack will power cycle the Bluetooth Controller on models
without hardware flowcontrol, i.e., Pi 3 A/B. With flowcontrol, e.g Pi Zero W
and Pi 3 A+/B+, the firmware will only uploaded on first start.
pi@raspberrypi :˜ $ ./ le counter
Packet Log : /tmp/ hci dump . p k l g
Hardware UART w i t h o u t f l o w c o n t r o l
Phase 1 : Download f i r m w a r e
Phase 2 : Main app
BTstack c o u n t e r 0001
BTstack up and r u n n i n g a t B8 : 2 7 : EB : 2 7 : AF: 5 6
0.148.11. TODO.
239
// 0 x1000 main s t a c k
#define BSP CFG STACK MAIN BYTES ( 0 x1000 )
0.149.3. Renesas DA14531 Module on MikroE BLE Tiny Click board with.
• The board comes with some demo application and needs to be pro-
grammed with an HCI firmware to use it with a regular Bluetooth stack.
• Firmware details:
– Keil uVision project DA145xx SDK/x.x.xx.xxxx/projects/target apps/hci
on Windows
240
// C o n f i g : u s e r p e r i p h s e t u p . h
#define UART1 TX PORT GPIO PORT 0
#define UART1 TX PIN GPIO PIN 6
#define UART1 RX PORT GPIO PORT 0
#define UART1 RX PIN GPIO PIN 5
#define UART1 RTSN PORT GPIO PORT 0
#define UART1 RTSN PIN GPIO PIN 7
#define UART1 CTSN PORT GPIO PORT 0
#define UART1 CTSN PIN GPIO PIN 8
#define UART1 BAUDRATE UART BAUDRATE 460800
#define UART1 DATABITS UART DATABITS 8
// C o n f i g : u s e r c o n f i g . h
s t a t i c const s l e e p s t a t e t a p p d e f a u l t s l e e p m o d e = ARCH SLEEP OFF ;
• Firmware installation:
– Connect GND (pin 5) and VCC (pin 6) with jumper wires to the
RA6 dev board.
– Connect it with a ARM-Cortex 10-pin connector to a J-Link device
– Start SmartBond Flash Programmer
– The Programmer should auto-detect the DA14531 via the J-Link.
– Select firmware/hci 531 rx05 tx06 rts07 cts08 468000.hex as firmware file
and click Program
0.149.4. Software. The port provides a CMake project file that uses the installed
Arm Gnu Toolchain.
• Install Arm GNU Toolchain
• Install CMake
• Install Ninja
• To compile, go to the port folder:
cd btstack/port/renesas−ek−ra6me4a−da14531
• Create a build folder and go to build folder
mkdir build && cd build
• Create Ninja build files
cmake −G Ninja ..
• Build all examples
ninja
This will build all examples as .elf files as well as .jdebug Ozone debug project
files Alternatively, the CMakeLists.txt can be used to compile using Make (cmake
−G ”Unix Makefiles”.. and make) or or use the project in most modern IDEs (CLion,
Visual Studio, Visual Studio Code, . . . )
0.149.5. Run Example Project using Ozone. After building the examples, the
generated .elf file can be used with Ozone. Start Ozone and open the provided
.jdebug file. The debug output is readily available in the RTT Terminal.
0.149.6. Debug output. All debug output is send via SEGGER RTT.
In src/btstack config.h resp. in example/btstack config.h of the generated
projects.
241
Also, the full packet log with addtional log information can be enabled in
src/hal entry.c by uncommenting the hci dump init(. . . ) call.
The console output can then be converted into .pklg files by running tool/cre-
ate packet log.py. The .pklg file can be analyzed with the macOS X PacketLogger
or WireShark.
0.149.7. Setup.
0.150. BTstack Port for Renesas Target Board TB-S1JA with CC256x.
This port uses the Renesas TB-S1JA with TI’s CC256XEM ST Adapter Kit that
allows to plug in a CC256xB or CC256xC Bluetooth module. Renesas e2 Studio
(Eclise-based) was used with the SSP HAL and without an RTOS. For easy
debugging, Ozone project files are generated as well.
Connct the Target Board to the TI Boosterpack, see Booster Pack Pinout:
http://www.ti.com/ww/en/launchpad/dl/boosterpack-pinout-v2.pdf
$ python c r e a t e e x a m p l e s . py
0.150.8. Notes.
• HCI UART is set to 2 mbps. Using 3 or 4 mbps causes hang during
startup
0.151.1. Create Example Projects. To create all example projects in the example
folder, you can run:
$ make
$ make
$ make f l a s h
0.151.4. TODOs.
− Implement h a l f l a s h s e c t o r . h t o p e r s i s t l i n k k e y s
245
0.151.5. Issues.
0.152. BTstack Port for STM32 F4 Discovery Board with CC256x. This
port uses the STM32 F4 Discovery Board with TI’s CC256XEM ST Adapter Kit
that allows to plug in a CC256xB or CC256xC Bluetooth module. STCubeMX
was used to provide the HAL, initialize the device, and the Makefile. For easy
development, Ozone project files are generated as well.
0.152.1. Hardware. STM32 Development kit and adapter for CC256x module: -
STM32 F4 Discovery Board - CC256xEM Bluetooth Adatper Kit for ST
CC256x Bluetooth module: - CC2564B Dual-mode Bluetooth Controller Eval-
uation Module - CC2564C Dual-mode Bluetooth Controller Evaluation Module
The module with the older CC2564B is around USD 20, while the one with
the new CC2564C costs around USD 60. The projects are configured for the
CC2564C. When using the CC2564B, bluetooth init cc2564B 1.8 BT Spec 4.1.c
should be used as cc256x init script.
0.152.2. Software. To build all examples, run make
$ make
All examples and the .jedbug Ozone project files are placed in the ‘build’
folder.
0.152.3. Flash And Run The Examples. The Makefile builds different versions: -
example.elf: .elf file with all debug information - example.bin: .bin file that can
be used for flashing
There are different options to flash and debug the F4 Discovery board. The F4
Discovery boards comes with an on-board ST-Link programmer and debugger.
As an alternative, the ST-Link programmer can be replaced by an SEGGER J-
Link OB. Finally, the STM32 can be programmed with any ARM Cortex JTAG
or SWD programmer via the SWD jumper.
0.152.4. Run Example Project using Ozone. When using an external J-Link pro-
grammer or after installing J-Link OB on the F4 Discovery board, you can flash
and debug using the cross-platform SEGGER Ozone Debugger. It is included in
some J-Link programmers or can be used for free for evaluation usage.
Just start Ozone and open the .jdebug file in the build folder. When compiled
with “ENABLE SEGGER RTT”, the debug output shows up in the Terminal
window of Ozone.
246
0.152.5. Debug output. All debug output can be either send via SEGGER RTT
or via USART2. To get the console from USART2, connect PA2 (USART2
TX) of the Discovery board to an USB-2-UART adapter and open a terminal at
115200.
In src/btstack config.h resp. in example/btstack config.h of the generated
projects, additional debug information can be enabled by uncommenting EN-
ABLE LOG INFO.
Also, the full packet log can be enabled in src/port.c resp. btstack/port/stm32-
f4discovery-cc256x/src/port.c by uncommenting the hci dump init(..) line. The
console output can then be converted into .pklg files for OS X PacketLogger or
WireShark by running tool/create packet log.py
0.152.6. GATT Database. In BTstack, the GATT Database is defined via the
.gatt file in the example folder. The Makefile contains rules to update the .h file
when the .gatt was modified.
0.152.7. Maintainer Notes - Updating The Port. The Audio BSP is from the
STM32F4Cube V1.16 firmware and not generated from STM32CubeMX. To up-
date the HAL, run ‘generate code’ in CubeMX. After that, make sure to re-apply
the patches to the UART and check if the hal config was changed.
0.153. BTstack Port for STM32 F4 Discovery Board with USB Blue-
tooth Controller. This port uses the STM32 F4 Discovery Board with an USB
Bluetooth Controller plugged into its USB UTG port. See blog post for details.
STCubeMX was used to provide the HAL, initialize the device, and the Make-
file. For easy development, Ozone project files are generated as well.
0.153.1. Hardware. STM32 Development kit with USB OTG adapter and USB
CSR8510 Bluetooth Controller - STM32 F4 Discovery Board
$ make
All examples and the .jedbug Ozone project files are placed in the ‘build’
folder.
0.153.3. Flash And Run The Examples. The Makefile builds different versions: -
example.elf: .elf file with all debug information - example.bin: .bin file that can
be used for flashing
There are different options to flash and debug the F4 Discovery board. The F4
Discovery boards comes with an on-board ST-Link programmer and debugger.
As an alternative, the ST-Link programmer can be replaced by an SEGGER J-
Link OB. Finally, the STM32 can be programmed with any ARM Cortex JTAG
or SWD programmer via the SWD jumper.
247
0.153.4. Run Example Project using Ozone. When using an external J-Link pro-
grammer or after installing J-Link OB on the F4 Discovery board, you can flash
and debug using the cross-platform SEGGER Ozone Debugger. It is included in
some J-Link programmers or can be used for free for evaluation usage.
Just start Ozone and open the .jdebug file in the build folder. When compiled
with “ENABLE SEGGER RTT”, the debug output shows up in the Terminal
window of Ozone.
0.153.5. Debug output. The debug output can send via SEGGER RTT.
In src/btstack config.h resp. in example/btstack config.h of the generated
projects, additional debug information can be enabled by uncommenting EN-
ABLE LOG INFO.
Also, the full packet log can be enabled in src/port.c resp. btstack/port/stm32-
f4discovery-cc256x/src/port.c by uncommenting the hci dump init(..) line. The
console output can then be converted into .pklg files for OS X PacketLogger or
WireShark by running tool/create packet log.py
0.153.6. GATT Database. In BTstack, the GATT Database is defined via the
.gatt file in the example folder. The Makefile contains rules to update the .h file
when the .gatt was modified.
0.153.7. Maintainer Notes - Updating The Port. The Audio BSP is from the
STM32F4Cube V1.16 firmware and not generated from STM32CubeMX. To up-
date the HAL, run ‘generate code’ in CubeMX. After that, make sure to re-apply
the patches to the UART and check if the hal config was changed.
0.154. BTstack Port for STM32 Nucleo L073RZ Board with EM9304
Controller. This port uses the STM32 Nucleo-L073RZ Board with EM’s EM9304
Shield.
The STM32CubeMX tool was used to provide the HAL, initialize the device,
and create a basic Makefile. The Makefile has been exteneded to compile all
BTstack LE examples. For easy development, Ozone project files are generated
as well.
0.154.1. Hardware. In this port, the EM9304 is conencted via the SPI1 interface
and configured for 8 Mhz. Datasheet for the EM9304
It assumes that the EM9304 does not contain any patches and uploads the
latest Metapatch during startup.
$ make
All examples and the .jedbug Ozone project files are placed in the ‘build’
folder.
248
0.154.3. Flash And Run The Examples. The Makefile builds different versions: -
example.elf: .elf file with all debug information - example.bin: .bin file that can
be used for flashing
There are different options to flash and debug the F4 Discovery board. The F4
Discovery boards comes with an on-board ST-Link programmer and debugger.
As an alternative, the ST-Link programmer can be replaced by an SEGGER J-
Link OB. Finally, the STM32 can be programmed with any ARM Cortex JTAG
or SWD programmer via the SWD jumper.
0.154.4. Run Example Project using Ozone. When using an external J-Link pro-
grammer or after installing J-Link OB on the F4 Discovery board, you can flash
and debug using the cross-platform SEGGER Ozone Debugger. It is included in
some J-Link programmers or can be used for free for evaluation usage.
Just start Ozone and open the .jdebug file in the build folder. When compiled
with “ENABLE SEGGER RTT”, the debug output shows up in the Terminal
window of Ozone.
0.154.5. Debug output. All debug output can be either send via SEGGER RTT
or via USART2. To get the console from USART2, connect PA2 (USART2
TX) of the Discovery board to an USB-2-UART adapter and open a terminal at
115200.
In src/btstack config.h resp. in example/btstack config.h of the generated
projects, additional debug information can be enabled by uncommenting EN-
ABLE LOG INFO.
Also, the full packet log can be enabled in src/port.c by uncommenting the
hci dump init(..) line. The console output can then be converted into .pklg files
for OS X PacketLogger or WireShark by running tool/create packet log.py
0.154.6. GATT Database. In BTstack, the GATT Database is defined via the
.gatt file in the example folder. During the build, the .gatt file is converted into
a .h file with a binary representation of the GATT Database and useful defines
for the application.
249
250
251
0.155.11. General.
• indicate random address in advertising pdus
• allow to set random BD ADDR via HCI command and use in Advertise-
ments
• support other regular adv types
• handle Encryption
0.155.12. Low Power.
• enter STANDY RC mode when idle
• implement MCU sleep (if next wakeup isn’t immediate)
• sleep after connection request until first packet from Central
• replace SysTick with tick counter based on LPTIM1
• disable SPI on MCU sleep
0.156. BTstack Port with Cinnamon for Semtech SX1280 Controller on
STM32L476 Nucleo. Cinnamon is BlueKitchen’s minimal, yet robust Con-
troller/Link Layer implementation for use with BTstack.
In contrast to common Link Layer implementations, our focus is on a ro-
bust and compact implementation for production use, where code size matters
(e.g. current code size about 8 kB).
0.156.1. Overview. This port targets the Semtech SX1280 radio controller. The
Host Stack and the Controller (incl. Link Layer) run on a STM32 MCU, with
the SX1280 connected via SPI.
It uses the SX1280 C-Driver from Semtech to communicate with the SX1280.
The main modification was to the SPI driver that uses DMA for full packets.
0.156.2. Status. Tested with theMiromico FMLR-80-P-STL4E module (see port/stm32-
l451-miromico-sx1280) and the STM32 L476 Nucleo dev kit with our SX1280
Shield.
SEGGER RTT is used for debug output, so a Segger J-Link programmer is
required, but the on-board ST-Link programmer and debugger can be replaced
by an SEGGER J-Link OB.
Uses 32.768 kHz crytstal as LSE for timing
Support for Broadcast and Peripheral roles.
The Makefile project compiles gatt counter, gatt streamer server, hog mouse
and hog keyboard examples.
0.156.3. Limitation.
0.156.4. Advertising State:
• Only Connectable Advertising supported
• Only fixed public BD ADDR of 33:33:33:33:33:33 is used
0.156.5. Connection State:
• Encryption not implemented
• Some LL PDUs not supported
0.156.6. Central Role:
• Not implemented
253
• Not implemented
0.156.9. Getting Started. Just run make. You can upload the EXAMPLE.elf file
created in build folder, e.g. with Ozone using the provided EXAMPLE.jdebug,
and run it.
0.156.10. TODO.
0.156.11. General.
0.157.1. Hardware. In this port, the Nucelo68 or the USB Dongle from the P-
NUCLEO-WB55 can be used.
Last test was done using FUS v1.2 and HCI BLE Firmware v1.13 on Nucleo68
See STM32Cube FW WB V1.13.0/Projects/STM32WB Copro Wireless Binaries/Release Notes.ht
for firmware install instructions.
Note: Segger RTT is currently not really usable. When sleep modes ared
disabled for debuggin (see port thread()) RTT works, but the output buffer
quickly overflows. In Block mode, radio stops working.
0.157.2. Nucleo68. The debug output is sent over USART1 and is available via
the ST-Link v2.
0.157.3. USB Dongle. To flash the dongle, SWD can be used via the lower 6 pins
on CN1: - 3V3 - PB3 - SWO (semi hosting not used) - PA14 - SCLK - PA13 -
SWDIO - NRST - GND
The debug output is sent over USART1 and is available via PB6.
0.157.4. Software. FreeRTOS V10.2.0 is used to run stack, you can get this ex-
ample version by checking out official repo:
$ cd Middlewares
$ g i t submodule add h t t p s : // g i t h u b . com/aws/amazon−f r e e r t o s . g i t
$ g i t submodule update
& cd amazon−f r e e r t o s && g i t c h e c k o u t v1 . 4 . 8
$ make
All examples and the .jedbug Ozone project files are placed in the ‘build’
folder.
0.157.5. Flash And Run The Examples. The Makefile builds different versions: -
example.elf: .elf file with all debug information - example.bin: .bin file that can
be used for flashing
256
0.157.6. Nucleo68. There are different options to flash and debug the Nucleo68
board. The Nucleo68 boards comes with an on-board ST-Link programmer and
debugger. As an alternative, the ST-Link programmer can be replaced by an
SEGGER J-Link OB. Finally, the STM32 can be programmed with any ARM
Cortex JTAG or SWD programmer via the SWD jumper.
0.157.7. USB Dongle. Please use any ARM Cortex SWD programmer via the
SWD interface desribed in the hardware section.
0.157.8. Run Example Project using Ozone. When using an external J-Link pro-
grammer or after installing J-Link OB on the Nucleo68 board, you can flash
and debug using the cross-platform SEGGER Ozone Debugger. It is included in
some J-Link programmers or can be used for free for evaluation usage.
Just start Ozone and open the .jdebug file in the build folder. When compiled
with “ENABLE SEGGER RTT”, the debug output shows up in the Terminal
window of Ozone. Note: as mentioned before, Segger RTT currently stops work-
ing when CPU2 has started up.
0.157.9. Debug output. All debug output can be either send via SEGGER RTT
or via USART1. To get the console from USART1, simply connect your board
under STLink-v2 to your PC or connect PB6 (USART1 TX) of the Nucleo board
to an USB-2-UART adapter and open a terminal at 115200.
In src/btstack config.h resp. in example/btstack config.h of the generated
projects, additional debug information can be enabled by uncommenting EN-
ABLE LOG INFO.
Also, the full packet log can be enabled in src/btstack port.c by uncommenting
the hci dump init(..) line. The console output can then be converted into .pklg
files for OS X PacketLogger or WireShark by running tool/create packet log.py
0.157.10. GATT Database. In BTstack, the GATT Database is defined via the
.gatt file in the example folder. During the build, the .gatt file is converted into
a .h file with a binary representation of the GATT Database and useful defines
for the application.
0.158. BTstack Port for WICED platform. Tested with: - WICED SDK
3.4-6.2.1 - RedBear Duo: Please install RedBear WICED Add-On - Inventek
Systems ISM4334x - Please contact Inventek Systems for WICED platform files
- Inventek Systems ISM4343 (BCM43438 A1) - Please contact Inventek Systems
for WICED platform files
To integrate BTstack into the WICED SDK, please move the BTstack project
into WICED-SDK-6.2.1/libraries.
Then create projects for BTstack examples in WICED/apps/btstack by run-
ning:
. / c r e a t e e x a m p l e s . py
Now, the BTstack examples can be build from the WICED root in the same
way as other examples, e.g.:
257
to build the SPP-and-LE-Counter example for the RedBear Duo (or use ISM43340 M4G L44
/ ISM4343 WBM L151 for the Inventek Systems devices).
See WICED documentation about how to upload the firmware.
It should work with all WICED platforms that contain a Broadcom Bluetooth
chipset.
The maximal baud rate is currenty limited to 1 mbps.
The port uses the generated WIFI address plus 1 as Bluetooth MAC address.
It persists the LE Device DB and Classic Link Keys via the DCT mechanism.
All examples that rovide a GATT Server use the GATT DB in the .gatt file.
Therefore you need to run ./update gatt db.sh in the apps/btstack/$(EXAMPLE)
folder after modifying the .gatt file.
0.159.1. Visual Studio 2022. Visual Studio can directly open the provided port/
windows−windows−h4/CMakeLists.txt and allows to compile and run all examples.
0.159.2. mingw64. It can also be compiles with a regular Unix-style toolchain like
mingw-w64. mingw64-w64 is based on MinGW, which ‘. . . provides a complete
Open Source programming tool set which is suitable for the development of
native MS-Windows applications, and which do not depend on any 3rd-party
C-Runtime DLLs.’
We’ve used the Msys2 package available from the downloads page on Windows
10, 64-bit and use the MSYS2 MinGW 64-bit start menu item to compile 64-bit
binaries.
In the MSYS2 shell, you can install everything with pacman:
$ pacman −S git
$ pacman −S cmake
$ pacman −S make
$ pacman −S mingw−w64−x86 64−t o o l c h a i n
$ pacman −S mingw−w64−x86 64−p o r t a u d i o
$ pacman −S python
$ pacman −S winpty
258
$ cd p o r t / windows−h4
$ mkdir b u i l d
$ cd b u i l d
$ cmake . .
$ make
Note: When compiling with msys2-32 bit and/or the 32-bit toolchain, com-
pilation fails as conio.h seems to be mission. Please use msys2-64 bit with the
64-bit toolchain for now.
0.159.4. Console Output. When running the examples in the MSYS2 shell, the
console input (via btstack stdin support) doesn’t work. It works in the older
MSYS and also the regular CMD.exe environment. Another option is to install
WinPTY and then start the example via WinPTY like this:
$ winpty . / g a t t c o u n t e r . exe
0.160.1. Visual Studio 2022. Visual Studio can directly open the provided port
/windows−windows−h4−da14585/CMakeLists.txt and allows to compile and run all
examples.
0.160.2. mingw64. It can also be compiles with a regular Unix-style toolchain like
mingw-w64. mingw64-w64 is based on MinGW, which ‘. . . provides a complete
Open Source programming tool set which is suitable for the development of
native MS-Windows applications, and which do not depend on any 3rd-party
C-Runtime DLLs.’
259
We’ve used the Msys2 package available from the downloads page on Windows
10, 64-bit and use the MSYS2 MinGW 64-bit start menu item to compile 64-bit
binaries.
In the MSYS2 shell, you can install everything with pacman:
$ pacman −S git
$ pacman −S cmake
$ pacman −S make
$ pacman −S mingw−w64−x86 64−t o o l c h a i n
$ pacman −S mingw−w64−x86 64−p o r t a u d i o
$ pacman −S python
$ pacman −S winpty
$ cd p o r t / windows−h4
$ mkdir b u i l d
$ cd b u i l d
$ cmake . .
$ make
Note: When compiling with msys2-32 bit and/or the 32-bit toolchain, com-
pilation fails as conio.h seems to be mission. Please use msys2-64 bit with the
64-bit toolchain for now.
0.160.4. Console Output. When running the examples in the MSYS2 shell, the
console input (via btstack stdin support) doesn’t work. It works in the older
MSYS and also the regular CMD.exe environment. Another option is to install
WinPTY and then start the example via WinPTY like this:
$ winpty . / g a t t c o u n t e r . exe
In short: you need to install an arm-none-eabi gcc toolchain and the nRF5x
Command Line Tools incl. the J-Link drivers, checkout the Zephyr project, and
flash an example project onto the chipset:
• Install J-Link Software and documentation pack.
• Get nrfjprog as part of the nRFx-Command-Line-Tools. Click on Down-
loads tab on the top and look for your OS.
• Checkout Zephyr and install toolchain. We recommend using the arm-
non-eabi gcc binaries instead of compiling it yourself. At least on OS X,
this failed for us.
• In samples/bluetooth/hci uart, compile the firmware for nRF52 Dev Kit
$ make BOARD=nrf52 pca10040
• Upload the firmware
$ make flash
• For the nRF51 Dev Kit, use make BOARD=nrf51 pca10028.
0.161.2. Configure serial port. To set the serial port of your Zephyr Controller,
you can either update config.device name in main.c or always start the examples
with the correct −u COMx option.
0.161.3. Visual Studio 2022. Visual Studio can directly open the provided port
/windows−windows−h4−zephyr/CMakeLists.txt and allows to compile and run all ex-
amples.
0.161.4. mingw64. It can also be compiles with a regular Unix-style toolchain like
mingw-w64. mingw64-w64 is based on MinGW, which ‘. . . provides a complete
Open Source programming tool set which is suitable for the development of
native MS-Windows applications, and which do not depend on any 3rd-party
C-Runtime DLLs.’
In the MSYS2 shell, you can install everything with pacman:
$ pacman −S git
$ pacman −S cmake
$ pacman −S make
$ pacman −S mingw−w64−x86 64−t o o l c h a i n
$ pacman −S mingw−w64−x86 64−p o r t a u d i o
$ pacman −S python
$ pacman −S winpty
$ cd p o r t / windows−h4
$ mkdir b u i l d
$ cd b u i l d
$ cmake . .
$ make
261
Note: When compiling with msys2-32 bit and/or the 32-bit toolchain, com-
pilation fails as conio.h seems to be mission. Please use msys2-64 bit with the
64-bit toolchain for now.
0.161.6. Console Output. When running the examples in the MSYS2 shell, the
console input (via btstack stdin support) doesn’t work. It works in the older
MSYS and also the regular CMD.exe environment. Another option is to install
WinPTY and then start the example via WinPTY like this:
$ winpty . / g a t t c o u n t e r . exe
0.162. BTstack Port for Windows Systems using the WinUSB Driver.
The Windows-WinUSB port uses the native run loop and WinUSB API to access
a USB Bluetooth dongle.
The port provides both a regular Makefile as well as a CMake build file. It uses
native Win32 APIs for file access and does not require the Cygwin or mingw64
build/runtine. All examples can also be build with Visual Studio 2022 (e.g. Com-
munity Edition).
0.162.1. Access to Bluetooth USB Dongle with Zadig. To allow WinUSB to access
an USB Bluetooth dongle, you need to install a special device driver to make it
accessible to user space processes.
It works like this:
• Download Zadig
• Start Zadig
• Select Options -> “List all devices”
• Select USB Bluetooth dongle in the big pull down list
• Select WinUSB in the right pull down list
• Select “Replace Driver”
After the new driver was installed, your device is shown in the Device Manager
with Device Provider ‘libwdi’
0.162.2. Visual Studio 2022. Visual Studio can directly open the provided port
/windows−winusb/CMakeLists.txt and allows to compile and run all examples. For
this, the C++ CMake tools for Windows is required. They are part of the
Desktop development with C++ workloads.
0.162.3. mingw64. It can also be compiles with a regular Unix-style toolchain like
mingw-w64. mingw64-w64 is based on MinGW, which ‘. . . provides a complete
Open Source programming tool set which is suitable for the development of
native MS-Windows applications, and which do not depend on any 3rd-party
C-Runtime DLLs.’
In the MSYS2 shell, you can install everything with pacman:
262
$ pacman −S git
$ pacman −S cmake
$ pacman −S make
$ pacman −S mingw−w64−x86 64−t o o l c h a i n
$ pacman −S mingw−w64−x86 64−p o r t a u d i o
$ pacman −S python
$ pacman −S winpty
$ cd p o r t / windows−h4
$ mkdir b u i l d
$ cd b u i l d
$ cmake . .
$ make
Note: When compiling with msys2-32 bit and/or the 32-bit toolchain, com-
pilation fails as conio.h seems to be mission. Please use msys2-64 bit with the
64-bit toolchain for now.
0.162.5. Console Output. When running the examples in the MSYS2 shell, the
console input (via btstack stdin support) doesn’t work. It works in the older
MSYS and also the regular CMD.exe environment. Another option is to install
WinPTY and then start the example via WinPTY like this:
263
$ winpty . / s p p a n d l e c o u n t e r . exe
0.163. BTstack Port for Windows Systems with Intel Wireless 8260/8265
Controllers. Same as port/windows-winusb, but customized for Intel Wireless
8260 and 8265 Controllers. These controller require firmware upload and config-
uration to work. Firmware and config is downloaded from the Linux firmware
repository.
The port provides both a regular Makefile as well as a CMake build file. It uses
native Win32 APIs for file access and does not require the Cygwin or mingw64
264
build/runtine. All examples can also be build with Visual Studio 2022 (e.g. Com-
munity Edition).
0.163.1. Access to Bluetooth USB Dongle with Zadig. To allow WinUSB to access
an USB Bluetooth dongle, you need to install a special device driver to make it
accessible to user space processes.
It works like this:
• Download Zadig
• Start Zadig
• Select Options -> “List all devices”
• Select USB Bluetooth dongle in the big pull down list
• Select WinUSB in the right pull down list
• Select “Replace Driver”
After the new driver was installed, your device is shown in the Device Manager
with Device Provider ‘libwdi’
0.163.2. Visual Studio 2022. Visual Studio can directly open the provided port/
windows−winusb−intel/CMakeLists.txt and allows to compile and run all examples.
0.163.3. mingw64. It can also be compiles with a regular Unix-style toolchain like
mingw-w64. mingw64-w64 is based on MinGW, which ‘. . . provides a complete
Open Source programming tool set which is suitable for the development of
native MS-Windows applications, and which do not depend on any 3rd-party
C-Runtime DLLs.’
In the MSYS2 shell, you can install everything with pacman:
265
$ pacman −S git
$ pacman −S cmake
$ pacman −S make
$ pacman −S mingw−w64−x86 64−t o o l c h a i n
$ pacman −S mingw−w64−x86 64−p o r t a u d i o
$ pacman −S python
$ pacman −S winpty
$ cd p o r t / windows−h4
$ mkdir b u i l d
$ cd b u i l d
$ cmake . .
$ make
Note: When compiling with msys2-32 bit and/or the 32-bit toolchain, com-
pilation fails as conio.h seems to be mission. Please use msys2-64 bit with the
64-bit toolchain for now.
0.163.5. Console Output. When running the examples in the MSYS2 shell, the
console input (via btstack stdin support) doesn’t work. It works in the older
MSYS and also the regular CMD.exe environment. Another option is to install
WinPTY and then start the example via WinPTY like this:
$ winpty . / g a t t c o u n t e r . exe
0.164.1. Overview. This port targets any platform supported by Zephyr that
either contains a built-in Bluetooth Controller or is connected to an external
Controller via one of the supported Zephyr HCI Transports drivers (see zephyr/
drivers/bluetooth/hci)
0.164.3. Build Environment. The first step needs to done once. Step two is
needed every time to setup the environment.
s o u r c e env . sh
west b u i l d −b n r f 5 2 8 4 0 d k n r f 5 2 8 4 0
nrf52840dk nrf52840 selected the Nordic nRF52840 DK. For the older nRF52 DK
with nRF52832, you can specify nrf52dk nrf52832. To get a list of all supported
Zephyr targets, run west boards
To change zephyr platform settings use:
west b u i l d −b n r f 5 2 8 4 0 d k n r f 5 2 8 4 0 −t menuconfig
To build a different example, e.g. the gatt streamer server , set the EXAMPLE
environment variable:
EXAMPLE=g a t t s t r e a m e r s e r v e r west b u i l d −b n r f 5 2 8 4 0 d k n r f 5 2 8 4 0
west f l a s h
0.164.9. Buiding and Running on nRF5340. The nrf5340 is a dual core SoC,
where one core is used for Bluetooth HCI functionality and the other for the high
level application logic. So both cores need to be programmed separately. Using
the nRF5340-DK for example allows debug output on both cores to separate
UART ports. For the nRF5340 a network core firmware is required, which one
depends on the use-case. With 2a and 2b two options are given.
0.164.10. 1. Building the application. build using:
west b u i l d −b n r f 5 3 4 0 d k n r f 5 3 4 0 c p u a p p
with debug:
0.164.11. 2a. Using zephyr network core image. the hci rgmsg application needs
to be loaded first to the network core. Configure network core by selecting the ap-
propriate config file, for example nrf5340 cpunet iso− bt ll sw split .conf. additionally
it’s required to increase the main stack size from
268
to
or with debugging
0.164.12. 2b. Using Packetcraft binary network core image. for nrf5340 the latest
netcore firmware is located at sdk-nrf to program it:
0.164.13. TODO.
• Allow/document use of Zephyr HCI Drivers
#Integrating with Existing Systems
While the run loop provided by BTstack is sufficient for new designs, BTstack
is often used with or added to existing projects. In this case, the run loop, data
sources, and timers may need to be adapted. The following two sections provides
a guideline for single and multi-threaded environments.
To simplify the discussion, we’ll consider an application split into “Main”,
“Communication Logic”, and “BTstack”. The Communication Logic contains
the packet handler (PH) that handles all asynchronous events and data packets
from BTstack. The Main Application makes use of the Communication Logic
for its Bluetooth communication.
0.165. Adapting BTstack for Single-Threaded Environments. In a single-
threaded environment, all application components run on the same (single)
thread and use direct function calls as shown in Figure below.
269
Main Applica*on
Communica*on.
Logic
PH
BTstack
BTstack provides a basic run loop that supports the concept of data sources
and timers, which can be registered centrally. This works well when working with
a small MCU and without an operating system. To adapt to a basic operating
system or a different scheduler, BTstack’s run loop can be implemented based
on the functions and mechanism of the existing system.
Currently, we have two examples for this:
• btstack run loop posix.c is an implementation for POSIX compliant sys-
tems. The data sources are modeled as file descriptors and managed in
a linked list. Then, the select function is used to wait for the next file
descriptor to become ready or timer to expire.
• btstack run loop cocoa.c is an integration for the CoreFoundation Frame-
work used in OS X and iOS. All run loop functions are implemented in
terms of CoreFoundation calls, data sources and timers are modeled as
CFSockets and CFRunLoopTimer respectively.
• btstack run loop windows is an implementation for Windows environment.
The data sources are modeled with Event objects and managed in a linked
list. Then, the WaitForMultipleObjects is used to wait for the next Event
to becomre ready or timer to expire.
• btstack run loop qt is an integration for the Qt run loop. The data sources
on Windows systems use Event objects via Qt’s QEventNotifier adapter,
while a QSocketNotifier is used for Mac/Linux to handle file descriptors.
With these in place, the Windows/POSIX implemenations for HCI US-
B/H2 and HCI H4 can be used.
Communica)on
Logic
IPC
Main
PH
application custom IPC
commands
Applica)on
BTstack
Daemon
Main
IPC
Applica6on
PH
Bluetooth IPC
commands and Communica6on
events Logic
BTstack
PH
PH
1. APIs
1.1. AD Data Parser API. ad parser.h : AD Data (Advertisements and
EIR) Parser
typedef struct a d c o n t e x t {
const uint8 t ∗ data ;
uint8 t offset ;
uint8 t length ;
} ad context t ;
// A d v e r t i s i n g or Scan Response d a t a i t e r a t o r
void a d i t e r a t o r i n i t ( a d c o n t e x t t ∗ c o n t e x t , uint8 t a d l e n , const
uint8 t ∗ a d d a t a ) ;
b o o l a d i t e r a t o r h a s m o r e ( const a d c o n t e x t t ∗ c o n t e x t ) ;
void a d i t e r a t o r n e x t ( a d c o n t e x t t ∗ c o n t e x t ) ;
// Access f u n c t i o n s
uint8 t a d i t e r a t o r g e t d a t a t y p e ( const a d c o n t e x t t ∗
context ) ;
uint8 t a d i t e r a t o r g e t d a t a l e n ( const a d c o n t e x t t ∗
context ) ;
const uint8 t ∗ a d i t e r a t o r g e t d a t a ( const a d c o n t e x t t ∗ c o n t e x t ) ;
// c o n v e n i e n c e f u n c t i o n on c o m p l e t e a d v e r t i s e m e n t s
b o o l a d d a t a c o n t a i n s u u i d 1 6 ( uint8 t a d l e n , const uint8 t ∗ ad data
, uint16 t uuid16 ) ;
b o o l a d d a t a c o n t a i n s u u i d 1 2 8 ( uint8 t a d l e n , const uint8 t ∗
ad data , const uint8 t ∗ uuid128 ) ;
// i n t e r n a l l y used t o s i g n a l w r i t e r e s p o n s e p e n d i n g
#define ATT INTERNAL WRITE RESPONSE PENDING 0 xfffeu
/∗ ∗
∗ @ b r i e f ATT C l i e n t Read C a l l b a c k f o r Dynamic Data
∗ − i f b u f f e r == NULL, don ’ t copy data , j u s t r e t u r n s i z e o f v a l u e
∗ − i f b u f f e r != NULL, copy d a t a and r e t u r n number b y t e s c o p i e d
∗ I f ENABLE ATT DELAYED READ RESPONSE i s d e f i n e d , you may r e t u r n
ATT READ RESPONSE PENDING i f d a t a i s n ’ t a v a i l a b l e y e t
∗ @param c o n h a n d l e o f h c i l e c o n n e c t i o n
∗ @param a t t r i b u t e h a n d l e t o be rea d
∗ @param o f f s e t d e f i n e s s t a r t o f a t t r i b u t e v a l u e
∗ @param b u f f e r
272
∗ @param b u f f e r s i z e
∗ @return s i z e o f v a l u e i f b u f f e r i s NULL, o t h e r w i s e number o f
bytes copied
∗/
typedef uint16 t ( ∗ a t t r e a d c a l l b a c k t ) ( h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t a t t r i b u t e h a n d l e , uint16 t o f f s e t , uint8 t ∗ b u f f e r ,
uint16 t b u f f e r s i z e ) ;
/∗ ∗
∗ @ b r i e f ATT C l i e n t Write C a l l b a c k f o r Dynamic Data
∗ Each Prepared Write R e q u e s t t r i g g e r s a c a l l b a c k w i t h t r a n s a c t i o n
mode ATT TRANSACTION MODE ACTIVE.
∗ On E x e c u t e Write , t h e c a l l b a c k w i l l be c a l l e d w i t h
ATT TRANSACTION MODE VALIDATE and a l l o w s t o v a l i d a t e a l l queued
w r i t e s and r e t u r n an a p p l i c a t i o n e r r o r .
∗ I f none o f t h e r e g i s t e r e d c a l l b a c k s r e t u r n an e r r o r f o r
ATT TRANSACTION MODE VALIDATE and t h e c a l l b a c k w i l l be c a l l e d
w i t h ATT TRANSACTION MODE EXECUTE.
∗ Otherwise , a l l c a l l b a c k s w i l l be c a l l e d w i t h
ATT TRANSACTION MODE CANCEL.
∗
∗ I f t h e a d d i t i o n a l v a l i d a t i o n s t e p i s not needed , j u s t r e t u r n 0
f o r a l l c a l l b a c k s w i t h t r a n s a c t i o n mode
ATT TRANSACTION MODE VALIDATE.
∗
∗ @param c o n h a n d l e o f h c i l e c o n n e c t i o n
∗ @param a t t r i b u t e h a n d l e t o be w r i t t e n
∗ @param t r a n s a c t i o n − ATT TRANSACTION MODE NONE f o r r e g u l a r w r i t e s
. For p r e p a r e d w r i t e s : ATT TRANSACTION MODE ACTIVE,
ATT TRANSACTION MODE VALIDATE, ATT TRANSACTION MODE EXECUTE,
ATT TRANSACTION MODE CANCEL
∗ @param o f f s e t i n t o t h e v a l u e − used f o r queued w r i t e s and l o n g
attributes
∗ @param b u f f e r
∗ @param b u f f e r s i z e
∗ @param s i g n a t u r e used f o r s i g n e d w r i t e commmands
∗ @return 0 i f w r i t e was ok , ATT ERROR PREPARE QUEUE FULL i f no
s p a c e i n queue , ATT ERROR INVALID OFFSET i f o f f s e t i s l a r g e r
than max b u f f e r
∗/
typedef int ( ∗ a t t w r i t e c a l l b a c k t ) ( h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t a t t r i b u t e h a n d l e , uint16 t t r a n s a c t i o n m o d e , uint16 t
o f f s e t , uint8 t ∗ b u f f e r , uint16 t b u f f e r s i z e ) ;
// MARK: ATT O p e r a t i o n s
/∗ ∗
∗ @ b r i e f s e t u p ATT d a t a b a s e
∗ @param db
∗/
void a t t s e t d b ( uint8 t const ∗ db ) ;
/∗
∗ @ b r i e f s e t c a l l b a c k f o r re ad o f dynamic a t t r i b u t e s
∗ @param c a l l b a c k
∗/
void a t t s e t r e a d c a l l b a c k ( a t t r e a d c a l l b a c k t c a l l b a c k ) ;
/∗ ∗
∗ @ b r i e f s e t c a l l b a c k f o r w r i t e o f dynamic a t t r i b u t e s
∗ @param c a l l b a c k
∗/
void a t t s e t w r i t e c a l l b a c k ( a t t w r i t e c a l l b a c k t c a l l b a c k ) ;
/∗ ∗
∗ @ b r i e f debug h e l p e r , dump ATT d a t a b a s e t o s t d o u t u s i n g l o g i n f o
∗/
void a t t d u m p a t t r i b u t e s ( void ) ;
/∗ ∗
∗ @ b r i e f p r o c e s s ATT r e q u e s t a g a i n s t d a t a b a s e and p u t r e s p o n s e i n t o
response b u f f e r
∗ @param a t t c o n n e c t i o n used f o r mtu and s e c u r i t y p r o p e r t i e s
∗ @param r e q u e s t b u f f e r , r e q u e s t l e n : ATT r e q u e s t from c l i n e t
∗ @param r e s p o n s e b u f f e r f o r r e s u l t
∗ @return l e n o f d a t a i n r e s p o n s e b u f f e r . 0 = no r e s p o n s e ,
∗ ATT READ RESPONSE PENDING i f i t was r e t u r n e d a t l e a s t
once f o r dynamic d a t a ( r e q u i r e s
ENABLE ATT DELAYED READ RESPONSE)
∗/
uint16 t a t t h a n d l e r e q u e s t ( a t t c o n n e c t i o n t ∗ a t t c o n n e c t i o n ,
uint8 t ∗ r e q u e s t b u f f e r ,
uint16 t r e q u e s t l e n ,
uint8 t ∗ r e s p o n s e b u f f e r ) ;
/∗ ∗
∗ @brief setup value n o t i f i c a t i o n in response b u f f e r for a given
h a n d l e and v a l u e
∗ @param a t t c o n n e c t i o n
∗ @param a t t r i b u t e h a n d l e
∗ @param v a l u e
∗ @param v a l u e l e n
∗ @param r e s p o n s e b u f f e r f o r n o t i f i c a t i o n
∗/
uint16 t a t t p r e p a r e h a n d l e v a l u e n o t i f i c a t i o n ( a t t c o n n e c t i o n t ∗
att connection ,
274
uint16 t
attribute handle ,
const uint8 t ∗ val ue ,
uint16 t v a l u e l e n ,
uint8 t ∗
response buffer ) ;
/∗ ∗
∗ @brief setup value n o t i f i c a t i o n in response b u f f e r for m u l t i p l e
h a n d l e s and v a l u e s
∗ @param a t t c o n n e c t i o n
∗ @param a t t r i b u t e h a n d l e
∗ @param v a l u e
∗ @param v a l u e l e n
∗ @param r e s p o n s e b u f f e r f o r n o t i f i c a t i o n
∗/
uint16 t a t t p r e p a r e h a n d l e v a l u e m u l t i p l e n o t i f i c a t i o n (
att connection t ∗ att connection ,
uint8 t
num attributes
,
const
uint16 t
∗
attribute handles
,
const
uint8 t
∗∗
values data
,
const
uint16 t
∗
values len
,
uint8 t ∗
response buffer
);
/∗ ∗
∗ @brief setup value i n d i c a t i o n in response b u f f e r for a given
h a n d l e and v a l u e
∗ @param a t t c o n n e c t i o n
∗ @param a t t r i b u t e h a n d l e
∗ @param v a l u e
∗ @param v a l u e l e n
∗ @param r e s p o n s e b u f f e r f o r i n d i c a t i o n
∗/
uint16 t a t t p r e p a r e h a n d l e v a l u e i n d i c a t i o n ( a t t c o n n e c t i o n t ∗
att connection ,
uint16 t
attribute handle ,
const uint8 t ∗ val ue ,
275
uint16 t v a l u e l e n ,
uint8 t ∗
response buffer ) ;
/∗ ∗
∗ @ b r i e f t r a n s c a t i o n queue o f p r e p a r e d w r i t e s , e . g . , a f t e r
disconnect
∗ @return a t t c o n n e c t i o n
∗/
void a t t c l e a r t r a n s a c t i o n q u e u e ( a t t c o n n e c t i o n t ∗ a t t c o n n e c t i o n ) ;
// a t t r e a d c a l l b a c k h e l p e r s f o r a v a r i o u s d a t a t y p e s
/∗ ∗
∗ @ b r i e f Handle read o f b l o b l i k e d a t a f o r a t t r e a d c a l l b a c k
∗ @param b l o b o f d a t a
∗ @param b l o b s i z e o f b l o b
∗ @param o f f s e t from a t t r e a d c a l l b a c k
∗ @param b u f f e r from a t t r e a d c a l l b a c k
∗ @param b u f f e r s i z e from a t t r e a d c a l l b a c k
∗ @return v a l u e s i z e f o r b u f f e r == 0 and num b y t e s c o p i e d o t h e r w i s e
∗/
uint16 t a t t r e a d c a l l b a c k h a n d l e b l o b ( const uint8 t ∗ blob ,
uint16 t b l o b s i z e , uint16 t o f f s e t , uint8 t ∗ b u f f e r , uint16 t
buffer size ) ;
/∗ ∗
∗ @ b r i e f Handle read o f l i t t l e endian u n s i g n e d 32 b i t v a l u e f o r
att read callback
∗ @param v a l u e
∗ @param o f f s e t from a t t r e a d c a l l b a c k
∗ @param b u f f e r from a t t r e a d c a l l b a c k
∗ @param b u f f e r s i z e from a t t r e a d c a l l b a c k
∗ @return v a l u e s i z e f o r b u f f e r == 0 and num b y t e s c o p i e d o t h e r w i s e
∗/
uint16 t a t t r e a d c a l l b a c k h a n d l e l i t t l e e n d i a n 3 2 ( uint32 t val ue ,
uint16 t o f f s e t , uint8 t ∗ b u f f e r , uint16 t b u f f e r s i z e ) ;
/∗ ∗
∗ @ b r i e f Handle read o f l i t t l e endian u n s i g n e d 16 b i t v a l u e f o r
att read callback
∗ @param v a l u e
∗ @param o f f s e t from a t t r e a d c a l l b a c k
∗ @param b u f f e r from a t t r e a d c a l l b a c k
∗ @param b u f f e r s i z e from a t t r e a d c a l l b a c k
∗ @return v a l u e s i z e f o r b u f f e r == 0 and num b y t e s c o p i e d o t h e r w i s e
∗/
uint16 t a t t r e a d c a l l b a c k h a n d l e l i t t l e e n d i a n 1 6 ( uint16 t val ue ,
uint16 t o f f s e t , uint8 t ∗ b u f f e r , uint16 t b u f f e r s i z e ) ;
/∗ ∗
∗ @ b r i e f Handle read o f s i n g l e b y t e f o r a t t r e a d c a l l b a c k
∗ @param b l o b o f d a t a
∗ @param b l o b s i z e o f b l o b
276
∗ @param o f f s e t from a t t r e a d c a l l b a c k
∗ @param b u f f e r from a t t r e a d c a l l b a c k
∗ @param b u f f e r s i z e from a t t r e a d c a l l b a c k
∗ @return v a l u e s i z e f o r b u f f e r == 0 and num b y t e s c o p i e d o t h e r w i s e
∗/
uint16 t a t t r e a d c a l l b a c k h a n d l e b y t e ( uint8 t val ue , uint16 t
o f f s e t , uint8 t ∗ b u f f e r , uint16 t b u f f e r s i z e ) ;
// e x p e r i m e n t a l c l i e n t API
/∗ ∗
∗ @ b r i e f Get UUID f o r h a n d l e
∗ @param a t t r i b u t e h a n d l e
∗ @return 0 i f not found
∗/
uint16 t a t t u u i d f o r h a n d l e ( uint16 t a t t r i b u t e h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Get c o n s t v a l u e f o r h a n d l e
∗ @param a t t r i b u t e h a n d l e
∗ @param o u t v a l u e l e n o u t p u t v a r i a b l e t h a t h o l d v a l u e l e n
∗ @return v a l u e
∗/
// e x p e r i m e n t a l GATT S e r v e r API
/∗ ∗
∗ @ b r i e f Get h a n d l e range f o r primary s e r v i c e .
∗ @param uuid16
∗ @param s t a r t h a n d l e
∗ @param e n d h a n d l e
∗ @return f a l s e i f not found
∗/
b o o l g a t t s e r v e r g e t h a n d l e r a n g e f o r s e r v i c e w i t h u u i d 1 6 ( uint16 t
uuid16 , uint16 t ∗ s t a r t h a n d l e , uint16 t ∗ e n d h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Get h a n d l e range f o r i n c l u d e d s e r v i c e .
∗ @param s t a r t h a n d l e
∗ @param e n d h a n d l e
∗ @param uuid16
∗ @param o u t i n c l u d e d s e r v i c e h a n d l e
∗ @param o u t i n c l u d e d s e r v i c e s t a r t h a n d l e
∗ @param o u t i n c l u d e d s e r v i c e e n d h a n d l e
∗ @return f a l s e i f not found
∗/
b o o l g a t t s e r v e r g e t i n c l u d e d s e r v i c e w i t h u u i d 1 6 ( uint16 t
s t a r t h a n d l e , uint16 t e nd h an dl e , uint16 t uuid16 ,
uint16 t ∗ o u t i n c l u d e d s e r v i c e h a n d l e , uint16 t ∗
o u t i n c l u d e d s e r v i c e s t a r t h a n d l e , uint16 t ∗
out included service end handle ) ;
277
/∗ ∗
∗ @ b r i e f Get v a l u e h a n d l e f o r c h a r a c t e r i s t i c .
∗ @param s t a r t h a n d l e
∗ @param e n d h a n d l e
∗ @param uuid16
∗ @return 0 i f not found
∗/
uint16 t g a t t s e r v e r g e t v a l u e h a n d l e f o r c h a r a c t e r i s t i c w i t h u u i d 1 6
( uint16 t s t a r t h a n d l e , uint16 t e nd h an dl e , uint16 t uuid16 ) ;
/∗ ∗
∗ @ b r i e f Get d e s c r i p t o r h a n d l e f o r c h a r a c t e r i s t i c .
∗ @param s t a r t h a n d l e
∗ @param e n d h a n d l e
∗ @param c h a r a c t e r i s t i c u u i d 1 6
∗ @param d e s c r i p t o r u u i d 1 6
∗ @return 0 i f not found
∗/
uint16 t
gatt server get descriptor handle for characteristic with uuid16
( uint16 t s t a r t h a n d l e , uint16 t e nd h an dl e , uint16 t
c h a r a c t e r i s t i c u u i d 1 6 , uint16 t d e s c r i p t o r u u i d 1 6 ) ;
/∗ ∗
∗ @ b r i e f Get c l i e n t c o n f i g u r a t i o n h a n d l e f o r c h a r a c t e r i s t i c .
∗ @param s t a r t h a n d l e
∗ @param e n d h a n d l e
∗ @param c h a r a c t e r i s t i c u u i d 1 6
∗ @return 0 i f not found
∗/
uint16 t
gatt server get client configuration handle for characteristic with uuid16
( uint16 t s t a r t h a n d l e , uint16 t e nd h an dl e , uint16 t
characteristic uuid16 ) ;
/∗ ∗
∗ @ b r i e f Get s e r v e r c o n f i g u r a t i o n h a n d l e f o r c h a r a c t e r i s t i c .
∗ @param s t a r t h a n d l e
∗ @param e n d h a n d l e
∗ @param c h a r a c t e r i s t i c u u i d 1 6
∗ @param d e s c r i p t o r u u i d 1 6
∗ @return 0 i f not found
∗/
uint16 t
gatt server get server configuration handle for characteristic with uuid16
( uint16 t s t a r t h a n d l e , uint16 t e nd h an dl e , uint16 t
characteristic uuid16 ) ;
/∗ ∗
∗ @ b r i e f Get h a n d l e range f o r primary s e r v i c e .
∗ @param uuid128
∗ @param s t a r t h a n d l e
278
∗ @param e n d h a n d l e
∗ @return f a l s e i f not found
∗/
b o o l g a t t s e r v e r g e t h a n d l e r a n g e f o r s e r v i c e w i t h u u i d 1 2 8 ( const
uint8 t ∗ uuid128 , uint16 t ∗ s t a r t h a n d l e , uint16 t ∗
end handle ) ;
/∗ ∗
∗ @ b r i e f Get v a l u e h a n d l e .
∗ @param s t a r t h a n d l e
∗ @param e n d h a n d l e
∗ @param uuid128
∗ @return 0 i f not found
∗/
uint16 t
gatt server get value handle for characteristic with uuid128 (
uint16 t s t a r t h a n d l e , uint16 t e nd h an dl e , const uint8 t ∗
uuid128 ) ;
/∗ ∗
∗ @ b r i e f Get c l i e n t c o n f i g u r a t i o n h a n d l e .
∗ @param s t a r t h a n d l e
∗ @param e n d h a n d l e
∗ @param uuid128
∗ @return 0 i f not found
∗/
uint16 t
gatt server get client configuration handle for characteristic with uuid128
( uint16 t s t a r t h a n d l e , uint16 t e nd h an dl e , const uint8 t ∗
uuid128 ) ;
1.3. Runtine ATT Database Setup API. att db util.h : Helper to con-
struct ATT DB at runtime (BTstack GATT Compiler is not used).
/∗ ∗
∗ @ b r i e f I n i t ATT DB s t o r a g e
∗/
void a t t d b u t i l i n i t ( void ) ;
/∗ ∗
∗ @brief Set handle value for next t a b l e entry
∗ @param h a n d l e
∗ @note new h a n d l e must be >= p r e v i o u s t o a v o i d r e u s i n g a s s i g n e d
handles
∗/
void a t t d b u t i l s e t n e x t h a n d l e ( uint16 t h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Add primary s e r v i c e f o r 16− b i t UUID
∗ @param uuid16
∗ @return a t t r i b u t e h a n d l e f o r t h e new s e r v i c e d e f i n i t i o n
∗/
279
/∗ ∗
∗ @ b r i e f Add primary s e r v i c e f o r 128− b i t UUID
∗ @param uuid128
∗ @return a t t r i b u t e h a n d l e f o r t h e new s e r v i c e d e f i n i t i o n
∗/
uint16 t a t t d b u t i l a d d s e r v i c e u u i d 1 2 8 ( const uint8 t ∗ uuid128 ) ;
/∗ ∗
∗ @ b r i e f Add s e c o n d a r y s e r v i c e f o r 16− b i t UUID
∗ @param uuid16
∗ @return a t t r i b u t e h a n d l e f o r t h e new s e r v i c e d e f i n i t i o n
∗/
uint16 t a t t d b u t i l a d d s e c o n d a r y s e r v i c e u u i d 1 6 ( uint16 t uuid16 ) ;
/∗ ∗
∗ @ b r i e f Add s e c o n d a r y s e r v i c e f o r 128− b i t UUID
∗ @param uuid128
∗ @return a t t r i b u t e h a n d l e f o r t h e new s e r v i c e d e f i n i t i o n
∗/
uint16 t a t t d b u t i l a d d s e c o n d a r y s e r v i c e u u i d 1 2 8 ( const uint8 t ∗
uuid128 ) ;
/∗ ∗
∗ @ b r i e f Add i n c l u d e d s e r v i c e w i t h 16− b i t UUID
∗ @param s t a r t g r o u p h a n d l e
∗ @param e n d g r o u p h a n d l e
∗ @param uuid16
∗ @return a t t r i b u t e h a n d l e f o r t h e new s e r v i c e d e f i n i t i o n
∗/
uint16 t a t t d b u t i l a d d i n c l u d e d s e r v i c e u u i d 1 6 ( uint16 t
s t a r t g r o u p h a n d l e , uint16 t e n d g r o u p h a n d l e , uint16 t uuid16 )
;
/∗ ∗
∗ @ b r i e f Add C h a r a c t e r i s t i c w i t h 16− b i t UUID, p r o p e r t i e s , and d a t a
∗ @param uuid16
∗ @param p r o p e r t i e s − s e e ATT PROPERTY ∗ i n s r c / b l u e t o o t h . h
∗ @param r e a d p e r m i s s i o n s − s e e ATT SECURITY ∗ i n s r c / b l u e t o o t h . h
∗ @param w r i t e p e r m i s s i o n s − s e e ATT SECURITY ∗ i n s r c / b l u e t o o t h . h
∗ @param d a t a r e t u r n e d i n re ad o p e r a t i o n s i f ATT PROPERTY DYNAMIC
i s not s p e c i f i e d
∗ @param d a t a l e n
∗ @return a t t r i b u t e h a n d l e o f t h e new c h a r a c t e r i s t i c v a l u e
declaration
∗ @note I f p r o p e r t i e s c o n t a i n s ATT PROPERTY NOTIFY or
ATT PROPERTY INDICATE f l a g s , a C l i e n t C o n f i g u r a t i o n
C h a r a c t e r i s t i c D e s c r i p t o r (CCCD)
∗ i s c r e a t e d as w e l l . The a t t r i b u t e v a l u e h a n d l e o f t h e CCCD
i s the a t t r i b u t e value handle plus 1
∗/
280
/∗ ∗
∗ @ b r i e f Add C h a r a c t e r i s t i c w i t h 128− b i t UUID, p r o p e r t i e s , and d a t a
∗ @param uuid128
∗ @param p r o p e r t i e s − s e e ATT PROPERTY ∗ i n s r c / b l u e t o o t h . h
∗ @param r e a d p e r m i s s i o n s − s e e ATT SECURITY ∗ i n s r c / b l u e t o o t h . h
∗ @param w r i t e p e r m i s s i o n s − s e e ATT SECURITY ∗ i n s r c / b l u e t o o t h . h
∗ @param d a t a r e t u r n e d i n re ad o p e r a t i o n s i f ATT PROPERTY DYNAMIC
i s not s p e c i f i e d
∗ @param d a t a l e n
∗ @return a t t r i b u t e h a n d l e o f t h e new c h a r a c t e r i s t i c v a l u e
declaration
∗ @note I f p r o p e r t i e s c o n t a i n s ATT PROPERTY NOTIFY or
ATT PROPERTY INDICATE f l a g s , a C l i e n t C o n f i g u r a t i o n
C h a r a c t e r i s t i c D e s c r i p t o r (CCCD)
∗ i s c r e a t e d as w e l l . The a t t r i b u t e v a l u e h a n d l e o f t h e CCCD
i s the a t t r i b u t e value handle plus 1
∗/
uint16 t a t t d b u t i l a d d c h a r a c t e r i s t i c u u i d 1 2 8 ( const uint8 t ∗
uuid128 , uint16 t p r o p e r t i e s , uint8 t r e a d p e r m i s s i o n , uint8 t
w r i t e p e r m i s s i o n , uint8 t ∗ data , uint16 t d a t a l e n ) ;
/∗ ∗
∗ @ b r i e f Add d e s c r i p t o r w i t h 16− b i t UUID, p r o p e r t i e s , and d a t a
∗ @param uuid16
∗ @param p r o p e r t i e s − s e e ATT PROPERTY ∗ i n s r c / b l u e t o o t h . h
∗ @param r e a d p e r m i s s i o n s − s e e ATT SECURITY ∗ i n s r c / b l u e t o o t h . h
∗ @param w r i t e p e r m i s s i o n s − s e e ATT SECURITY ∗ i n s r c / b l u e t o o t h . h
∗ @param d a t a r e t u r n e d i n re ad o p e r a t i o n s i f ATT PROPERTY DYNAMIC i s
not s p e c i f i e d
∗ @param d a t a l e n
∗ @return a t t r i b u t e h a n d l e o f t h e new c h a r a c t e r i s t i c d e s c r i p t o r
declaration
∗/
uint16 t a t t d b u t i l a d d d e s c r i p t o r u u i d 1 6 ( uint16 t uuid16 , uint16 t
p r o p e r t i e s , uint8 t r e a d p e r m i s s i o n , uint8 t w r i t e p e r m i s s i o n ,
uint8 t ∗ data , uint16 t d a t a l e n ) ;
/∗ ∗
∗ @ b r i e f Add d e s c r i p t o r w i t h 128− b i t UUID, p r o p e r t i e s , and d a t a
∗ @param uuid128
∗ @param p r o p e r t i e s − s e e ATT PROPERTY ∗ i n s r c / b l u e t o o t h . h
∗ @param r e a d p e r m i s s i o n s − s e e ATT SECURITY ∗ i n s r c / b l u e t o o t h . h
∗ @param w r i t e p e r m i s s i o n s − s e e ATT SECURITY ∗ i n s r c / b l u e t o o t h . h
∗ @param d a t a r e t u r n e d i n re ad o p e r a t i o n s i f ATT PROPERTY DYNAMIC i s
not s p e c i f i e d
∗ @param d a t a l e n
∗ @return a t t r i b u t e h a n d l e o f t h e new c h a r a c t e r i s t i c d e s c r i p t o r
declaration
∗/
281
/∗ ∗
∗ @ b r i e f Get a d d r e s s o f c o n s t r u c t e d ATT DB
∗/
uint8 t ∗ a t t d b u t i l g e t a d d r e s s ( void ) ;
/∗ ∗
∗ @ b r i e f Get s i z e o f c o n s t r u c t e d ATT DB
∗/
uint16 t a t t d b u t i l g e t s i z e ( void ) ;
/∗ ∗
∗ @ b r i e f Get number o f b y t e s t h a t a r e i n c l u d e d i n GATT Database
Hash
∗/
uint16 t a t t d b u t i l h a s h l e n ( void ) ;
/∗ ∗
∗ @ b r i e f i n i t g e n e r a t o r f o r GATT Database Hash
∗/
void a t t d b u t i l h a s h i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f g e t n e x t b y t e from g e n e r a t o r f o r GATT Database Hash
∗/
uint8 t a t t d b u t i l h a s h g e t n e x t ( void ) ;
/∗ ∗
∗ @ b r i e f C a l c u l a t e GATT Database Hash u s i n g c r y p t o e n g i n e
∗ @param r e q u e s t
∗ @param d b h a s h
∗ @param c a l l b a c k
∗ @param c a l l b a c k a r g
∗/
void a t t d b u t i l h a s h c a l c ( b t s t a c k c r y p t o a e s 1 2 8 c m a c t ∗ r e q u e s t ,
uint8 t ∗ db hash , void ( ∗ c a l l b a c k ) ( void ∗ a r g ) , void ∗
callback arg ) ;
1.4. ATT Dispatch API. att dispatch.h : Dispatcher for independent im-
plementation of ATT client and server.
/∗
∗ @brief s e t u p ATT s e r v e r
∗ @param db a t t r i b u t e d a t a b a s e c r e a t e d by compile −g a t t . py
∗ @param r e a d c a l l b a c k , s e e a t t d b . h , can be NULL
∗ @param w r i t e c a l l b a c k , s e e a t t l . h , can be NULL
∗/
282
/∗ ∗
∗ @ b r i e f Enable s u p p o r t f o r Enhanced ATT b e a r e r
∗ @note R e q u i r e s ENABLE GATT OVER EATT
∗ @param n u m e a t t b e a r e r s
∗ @param s t o r a g e b u f f e r
∗ @param s t o r a g e s i z e
∗ @return
∗/
uint8 t a t t s e r v e r e a t t i n i t ( uint8 t n u m e a t t b e a r e r s , uint8 t ∗
s t o r a g e b u f f e r , uint16 t s t o r a g e s i z e ) ;
/∗
∗ @ b r i e f r e g i s t e r p a c k e t h a n d l e r f o r ATT s e r v e r e v e n t s :
∗ − ATT EVENT CAN SEND NOW
∗ − ATT EVENT HANDLE VALUE INDICATION COMPLETE
∗ − ATT EVENT MTU EXCHANGE COMPLETE
∗ @param h a n d l e r
∗/
void a t t s e r v e r r e g i s t e r p a c k e t h a n d l e r ( btstack packet handler t
handler ) ;
/∗ ∗
∗ @ b r i e f r e g i s t e r rea d / w r i t e c a l l b a c k s f o r s p e c i f i c h a n d l e range
∗ @param a t t s e r v i c e h a n d l e r t
∗/
void a t t s e r v e r r e g i s t e r s e r v i c e h a n d l e r ( a t t s e r v i c e h a n d l e r t ∗
handler ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t c a l l b a c k when s e n d i n g i s p o s s i b l e
∗ @note c a l l b a c k might happend d u r i n g c a l l t o t h i s f u n c t i o n
∗ @param c a l l b a c k r e g i s t r a t i o n t o p o i n t t o c a l l b a c k f u n c t i o n and
context information
∗ @param c o n h a n d l e
∗ @return 0 i f ok , e r r o r o t h e r w i s e
∗/
uint8 t a t t s e r v e r r e g i s t e r c a n s e n d n o w c a l l b a c k (
btstack context callback registration t ∗ callback registration ,
hci con handle t con handle ) ;
/∗ ∗
∗ @ b r i e f Return ATT MTU
∗ @param c o n h a n d l e
∗ @return mtu i f ok , 0 o t h e r w i s e
∗/
uint16 t a t t s e r v e r g e t m t u ( h c i c o n h a n d l e t c o n h a n d l e ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t c a l l b a c k when s e n d i n g n o t i f c a t i o n i s p o s s i b l e
∗ @note c a l l b a c k might happend d u r i n g c a l l t o t h i s f u n c t i o n
283
∗ @param c a l l b a c k r e g i s t r a t i o n t o p o i n t t o c a l l b a c k f u n c t i o n and
context information
∗ @param c o n h a n d l e
∗ @return ERROR CODE SUCCESS i f ok ,
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f h a n d l e unknown , and
ERROR CODE COMMAND DISALLOWED i f c a l l b a c k a l r e a d y r e g i s t e r e d
∗/
uint8 t a t t s e r v e r r e q u e s t t o s e n d n o t i f i c a t i o n (
btstack context callback registration t ∗ callback registration ,
hci con handle t con handle ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t c a l l b a c k when s e n d i n g i n d i c a t i o n i s p o s s i b l e
∗ @note c a l l b a c k might happend d u r i n g c a l l t o t h i s f u n c t i o n
∗ @param c a l l b a c k r e g i s t r a t i o n t o p o i n t t o c a l l b a c k f u n c t i o n and
context information
∗ @param c o n h a n d l e
∗ @return ERROR CODE SUCCESS i f ok ,
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f h a n d l e unknown , and
ERROR CODE COMMAND DISALLOWED i f c a l l b a c k a l r e a d y r e g i s t e r e d
∗/
uint8 t a t t s e r v e r r e q u e s t t o s e n d i n d i c a t i o n (
btstack context callback registration t ∗ callback registration ,
hci con handle t con handle ) ;
/∗ ∗
∗ @ b r i e f n o t i f y c l i e n t a b o u t a t t r i b u t e v a l u e change
∗ @param c o n h a n d l e
∗ @param a t t r i b u t e h a n d l e
∗ @param v a l u e
∗ @param v a l u e l e n
∗ @return 0 i f ok , e r r o r o t h e r w i s e
∗/
uint8 t a t t s e r v e r n o t i f y ( h c i c o n h a n d l e t c o n h a n d l e , uint16 t
a t t r i b u t e h a n d l e , const uint8 t ∗ val ue , uint16 t v a l u e l e n ) ;
/∗ ∗
∗ @brief n o t i f y c l i e n t about m u l t i p l e a t t r i b u t e value changes
∗ @param c o n h a n d l e
∗ @param n u m a t t r i b u t e s
∗ @param a t t r i b u t e h a n d l e s [ ]
∗ @param v a l u e s d a t a [ ]
∗ @param v a l u e s l e n [ ]
∗ @return 0 i f ok , e r r o r o t h e r w i s e
∗/
uint8 t a t t s e r v e r m u l t i p l e n o t i f y ( h c i c o n h a n d l e t c o n h a n d l e ,
uint8 t n u m a t t r i b u t e s ,
const uint16 t ∗
a t t r i b u t e h a n d l e s , const
uint8 t ∗∗ v a l u e s d a t a , const
uint16 t ∗ v a l u e s l e n ) ;
/∗ ∗
284
∗ @ b r i e f i n d i c a t e v a l u e change t o c l i e n t . c l i e n t i s s u p p o s e d t o
r e p l y w i t h an i n d i c a t i o n r e s p o n s e
∗ @param c o n h a n d l e
∗ @param a t t r i b u t e h a n d l e
∗ @param v a l u e
∗ @param v a l u e l e n
∗ @return 0 i f ok , e r r o r o t h e r w i s e
∗/
uint8 t a t t s e r v e r i n d i c a t e ( h c i c o n h a n d l e t c o n h a n d l e , uint16 t
a t t r i b u t e h a n d l e , const uint8 t ∗ val ue , uint16 t v a l u e l e n ) ;
/∗ ∗
∗ De−I n i t ATT S e r v e r
∗/
void a t t s e r v e r d e i n i t ( void ) ;
// t h e f o l l o w i n g f u n c t i o n s w i l l be removed soon
/∗ ∗
∗ @ b r i e f t e s t s i f a n o t i f i c a t i o n or i n d i c a t i o n can be send r i g h t
now
∗ @param c o n h a n d l e
∗ @return 1 , i f p a c k e t can be s e n t
∗/
int a t t s e r v e r c a n s e n d p a c k e t n o w ( h c i c o n h a n d l e t c o n h a n d l e ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t e m i s s i o n o f ATT EVENT CAN SEND NOW as soon as
possible
∗ @note ATT EVENT CAN SEND NOW might be e m i t t e d d u r i n g c a l l t o t h i s
function
∗ so p a c k e t h a n d l e r s h o u l d be r e a d y t o h a n d l e i t
∗ @param c o n h a n d l e
∗/
void a t t s e r v e r r e q u e s t c a n s e n d n o w e v e n t ( h c i c o n h a n d l e t
con handle ) ;
// end o f d e p r e c a t e d f u n c t i o n s
void a n c s c l i e n t i n i t ( void ) ;
void a n c s c l i e n t r e g i s t e r c a l l b a c k ( btstack packet handler t c a l l b a c k
);
const char ∗ a n c s c l i e n t a t t r i b u t e n a m e f o r i d ( int i d ) ;
/∗ ∗
∗ @brief I n i t i a l i z e Battery Service .
∗/
void b a t t e r y s e r v i c e c l i e n t i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f Connect t o B a t t e r y S e r v i c e s o f remote d e v i c e . The c l i e n t
w i l l try to r e g i s t e r for n o t i f i c a t i o n s .
∗ I f n o t i f i c a t i o n s a r e not s u p p o r t e d by remote B a t t e r y S e r v i c e , t h e
client will poll battery level
∗ I f p o l l i n t e r v a l m s i s 0 , p o l l i n g i s d i s a b l e d , and o n l y
n o t i f i c a t i o n s w i l l be r e c e i v e d .
∗ In e i t h e r case , t h e b a t t e r y l e v e l i s r e c e i v e d v i a
GATTSERVICE SUBEVENT BATTERY SERVICE LEVEL e v e n t .
∗ The b a t t e r y l e v e l i s r e p o r t e d as p e r c e n t a g e , i . e . 100 = f u l l and
i t i s v a l i d i f t h e ATTT s t a t u s i s e q u a l t o ATT ERROR SUCCESS,
∗ s e e ATT e r r o r s ( s e e b l u e t o o t h . h ) f o r o t h e r v a l u e s .
∗
∗ For manual p o l l i n g , s e e b a t t e r y s e r v i c e c l i e n t r e a d b a t t e r y l e v e l
below .
∗
∗ Event GATTSERVICE SUBEVENT BATTERY SERVICE CONNECTED i s e m i t t e d
w i t h s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
∗ GATT CLIENT IN WRONG STATE,
ERROR CODE UNSUPPORTED FEATURE OR PARAMETER VALUE i f no b a t t e r y
s e r v i c e i s found , or ATT e r r o r s ( s e e b l u e t o o t h . h ) .
∗ This e v e n t e v e n t a l s o r e t u r n s number o f b a t t e r y i n s t a n c e s found
on remote s e r v e r , as w e l l as p o l l bitmap t h a t i n d i c a t e s which
indexes
∗ o f s e r v i c e s r e q u i r e p o l l i n g , i . e . t h e y do not s u p p o r t
n o t i f i c a t i o n on b a t t e r y l e v e l change ,
∗
∗ @param c o n h a n d l e
∗ @param p a c k e t h a n d l e r
∗ @param p o l l i n t e r v a l m s or 0 t o d i s a b l e p o l l i n g
∗ @param b a t t e r y s e r v i c e c i d
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE COMMAND DISALLOWED i f t h e r e i s a l r e a d y a c l i e n t
a s s o c i a t e d w i t h c o n h a n d l e , or BTSTACK MEMORY ALLOC FAILED
∗/
uint8 t b a t t e r y s e r v i c e c l i e n t c o n n e c t ( h c i c o n h a n d l e t c o n h a n d l e ,
btstack packet handler t p a c k e t h a n d l e r , uint32 t
p o l l i n t e r v a l m s , uint16 t ∗ b a t t e r y s e r v i c e c i d ) ;
286
/∗ ∗
∗ @ b r i e f Read b a t t e r y l e v e l f o r s e r v i c e w i t h g i v e n i n d e x . Event
GATTSERVICE SUBEVENT BATTERY SERVICE LEVEL i s
∗ r e c e i v e d w i t h b a t t e r y l e v e l ( u n i t i s i n p e r c e n t a g e , i . e . 100 =
f u l l ) . The b a t t e r y l e v e l i s v a l i d i f t h e ATTT s t a t u s
∗ i s e q u a l t o ATT ERROR SUCCESS, s e e ATT e r r o r s ( s e e b l u e t o o t h . h )
for other values .
∗ @param b a t t e r y s e r v i c e c i d
∗ @param s e r v i c e i n d e x
∗ @return s t a t u s
∗/
uint8 t b a t t e r y s e r v i c e c l i e n t r e a d b a t t e r y l e v e l ( uint16 t
b a t t e r y s e r v i c e c i d , uint8 t s e r v i c e i n d e x ) ;
/∗ ∗
∗ @ b r i e f D i s c o n n e c t from B a t t e r y S e r v i c e .
∗ @param b a t t e r y s e r v i c e c i d
∗ @return s t a t u s
∗/
uint8 t b a t t e r y s e r v i c e c l i e n t d i s c o n n e c t ( uint16 t
battery service cid ) ;
/∗ ∗
∗ @ b r i e f De− i n i t i a l i z e B a t t e r y S e r v i c e .
∗/
void b a t t e r y s e r v i c e c l i e n t d e i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f I n i t B a t t e r y S e r v i c e S e r v e r w i t h ATT DB
∗ @param b a t t e r y v a l u e i n range 0−100
∗/
void b a t t e r y s e r v i c e s e r v e r i n i t ( uint8 t b a t t e r y v a l u e ) ;
/∗ ∗
∗ @ b r i e f Update b a t t e r y v a l u e
∗ @note t r i g g e r s n o t i f i c a t i o n s i f s u b s c r i b e d
∗ @param b a t t e r y v a l u e i n range 0−100
∗/
void b a t t e r y s e r v i c e s e r v e r s e t b a t t e r y v a l u e ( uint8 t b a t t e r y v a l u e )
;
1.9. Bond Management Service Server API. bond management service server.h
typedef enum {
BOND MANAGEMENT CMD DELETE ACTIVE BOND CLASSIC AND LE = 0 x01 ,
BOND MANAGEMENT CMD DELETE ACTIVE BOND CLASSIC,
BOND MANAGEMENT CMD DELETE ACTIVE BOND LE,
BOND MANAGEMENT CMD DELETE ALL BONDS CLASSIC AND LE,
BOND MANAGEMENT CMD DELETE ALL BONDS CLASSIC,
BOND MANAGEMENT CMD DELETE ALL BONDS LE,
BOND MANAGEMENT CMD DELETE ALL BUT ACTIVE BOND CLASSIC AND LE,
BOND MANAGEMENT CMD DELETE ALL BUT ACTIVE BOND CLASSIC,
BOND MANAGEMENT CMD DELETE ALL BUT ACTIVE BOND LE
} bond management cmd t ;
/∗ ∗
∗ @ b r i e f I n i t Bond Management S e r v i c e w i t h ATT DB
∗ @param s u p p o r t e d f e a t u r e s
∗/
void b o n d m a n a g e m e n t s e r v i c e s e r v e r i n i t ( uint32 t s u p p o r t e d f e a t u r e s
);
288
/∗ ∗
∗ @brief Set a u t h o r i s a t i o n s t r i n g
∗ @note S t r i n g i s not c o p i e d
∗ @param a u t h o r i s a t i o n s t r i n g
∗/
void b o n d m a n a g e m e n t s e r v i c e s e r v e r s e t a u t h o r i s a t i o n s t r i n g ( const
char ∗ a u t h o r i s a t i o n s t r i n g ) ;
1.10. Cycling Power Service Server API. cycling power service server.h
typedef enum {
CP PEDAL POWER BALANCE REFERENCE UNKNOWN = 0 ,
CP PEDAL POWER BALANCE REFERENCE LEFT,
CP PEDAL POWER BALANCE REFERENCE NOT SUPPORTED
} cycling power pedal power balance reference t ;
typedef enum {
CP TORQUE SOURCE WHEEL = 0 ,
CP TORQUE SOURCE CRANK,
CP TORQUE SOURCE NOT SUPPORTED
} cycling power torque source t ;
typedef enum {
CP SENSOR MEASUREMENT CONTEXT FORCE = 0 ,
CP SENSOR MEASUREMENT CONTEXT TORQUE
} cycling power sensor measurement context t ;
typedef enum {
CP DISTRIBUTED SYSTEM UNSPECIFIED = 0 ,
CP DISTRIBUTED SYSTEM NOT SUPPORTED,
CP DISTRIBUTED SYSTEM SUPPORTED
} cycling power distributed system t ;
typedef enum {
CP MEASUREMENT FLAG PEDAL POWER BALANCE PRESENT = 0 ,
CP MEASUREMENT FLAG PEDAL POWER BALANCE REFERENCE, // 0 −
unknown , 1 − l e f t
CP MEASUREMENT FLAG ACCUMULATED TORQUE PRESENT,
CP MEASUREMENT FLAG ACCUMULATED TORQUE SOURCE, // 0 − w h e e l
based , 1 − crank b a s e d
CP MEASUREMENT FLAG WHEEL REVOLUTION DATA PRESENT,
CP MEASUREMENT FLAG CRANK REVOLUTION DATA PRESENT,
CP MEASUREMENT FLAG EXTREME FORCE MAGNITUDES PRESENT,
CP MEASUREMENT FLAG EXTREME TORQUE MAGNITUDES PRESENT,
CP MEASUREMENT FLAG EXTREME ANGLES PRESENT,
CP MEASUREMENT FLAG TOP DEAD SPOT ANGLE PRESENT,
CP MEASUREMENT FLAG BOTTOM DEAD SPOT ANGLE PRESENT,
CP MEASUREMENT FLAG ACCUMULATED ENERGY PRESENT,
CP MEASUREMENT FLAG OFFSET COMPENSATION INDICATOR,
CP MEASUREMENT FLAG RESERVED
289
typedef enum {
CP INSTANTANEOUS MEASUREMENT DIRECTION UNKNOWN = 0 ,
CP INSTANTANEOUS MEASUREMENT DIRECTION TANGENTIAL COMPONENT,
CP INSTANTANEOUS MEASUREMENT DIRECTION RADIAL COMPONENT,
CP INSTANTANEOUS MEASUREMENT DIRECTION LATERAL COMPONENT
} cycling power instantaneous measurement direction t ;
typedef enum {
CP VECTOR FLAG CRANK REVOLUTION DATA PRESENT = 0 ,
CP VECTOR FLAG FIRST CRANK MEASUREMENT ANGLE PRESENT,
CP VECTOR FLAG INSTANTANEOUS FORCE MAGNITUDE ARRAY PRESENT,
CP VECTOR FLAG INSTANTANEOUS TORQUE MAGNITUDE ARRAY PRESENT,
CP VECTOR FLAG INSTANTANEOUS MEASUREMENT DIRECTION = 4 , // 2 b i t
CP VECTOR FLAG RESERVED = 6
} cycling power vector flag t ;
typedef enum {
CP SENSOR LOCATION OTHER,
CP SENSOR LOCATION TOP OF SHOE,
CP SENSOR LOCATION IN SHOE ,
CP SENSOR LOCATION HIP ,
CP SENSOR LOCATION FRONT WHEEL,
CP SENSOR LOCATION LEFT CRANK,
CP SENSOR LOCATION RIGHT CRANK,
CP SENSOR LOCATION LEFT PEDAL,
CP SENSOR LOCATION RIGHT PEDAL,
CP SENSOR LOCATION FRONT HUB,
CP SENSOR LOCATION REAR DROPOUT,
CP SENSOR LOCATION CHAINSTAY,
CP SENSOR LOCATION REAR WHEEL,
CP SENSOR LOCATION REAR HUB,
CP SENSOR LOCATION CHEST,
CP SENSOR LOCATION SPIDER ,
CP SENSOR LOCATION CHAIN RING ,
CP SENSOR LOCATION RESERVED
} cycling power sensor location t ;
typedef enum {
CP FEATURE FLAG PEDAL POWER BALANCE SUPPORTED = 0 ,
CP FEATURE FLAG ACCUMULATED TORQUE SUPPORTED,
CP FEATURE FLAG WHEEL REVOLUTION DATA SUPPORTED,
CP FEATURE FLAG CRANK REVOLUTION DATA SUPPORTED,
CP FEATURE FLAG EXTREME MAGNITUDES SUPPORTED,
CP FEATURE FLAG EXTREME ANGLES SUPPORTED,
CP FEATURE FLAG TOP AND BOTTOM DEAD SPOT ANGLE SUPPORTED,
CP FEATURE FLAG ACCUMULATED ENERGY SUPPORTED,
CP FEATURE FLAG OFFSET COMPENSATION INDICATOR SUPPORTED,
CP FEATURE FLAG OFFSET COMPENSATION SUPPORTED,
CP FEATURE FLAG CYCLING POWER MEASUREMENT CHARACTERISTIC CONTENT MASKING SUPPORT
,
CP FEATURE FLAG MULTIPLE SENSOR LOCATIONS SUPPORTED,
CP FEATURE FLAG CRANK LENGTH ADJUSTMENT SUPPORTED,
290
typedef enum {
CP CALIBRATION STATUS INCORRECT CALIBRATION POSITION = 0 x01 ,
CP CALIBRATION STATUS MANUFACTURER SPECIFIC ERROR FOLLOWS = 0xFF
} cycling power calibration status t ;
/∗ ∗
∗ @ b r i e f I n i t S e r v e r w i t h ATT DB
∗
∗ @param f e a t u r e f l a g s
∗ @param p e d a l p o w e r b a l a n c e r e f e r e n c e
∗ @param t o r q u e s o u r c e
∗ @param s u p p o r t e d s e n s o r l o c a t i o n s
∗ @param n u m s u p p o r t e d s e n s o r l o c a t i o n s
∗ @param c u r r e n t s e n s o r l o c a t i o n
∗/
void c y c l i n g p o w e r s e r v i c e s e r v e r i n i t ( uint32 t f e a t u r e f l a g s ,
cycling power pedal power balance reference t
/∗ ∗
∗ @ b r i e f S e tu p measurement as a d v e r t i s e m e n t d a t a
∗ @param a d v i n t e r v a l
∗ @param a d v b u f f e r
∗ @param a d v s i z e
∗ @return
∗/
291
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k f o r t h e c a l i b r a t i o n and b r o a d c a s t
updates .
∗
∗ @param c a l l b a c k
∗/
void c y c l i n g p o w e r s e r v i c e s e r v e r p a c k e t h a n d l e r (
btstack packet handler t c a l l b a c k ) ;
/∗ ∗
∗ @ b r i e f Report c a l i b r a t i o n done .
∗ @param measurement type
∗ @param c a l i b r a t e d v a l u e
∗/
void c y c l i n g p o w e r s e r v e r c a l i b r a t i o n d o n e (
c y c l i n g p o w e r s e n s o r m e a s u r e m e n t c o n t e x t t measurement type ,
uint16 t c a l i b r a t e d v a l u e ) ;
/∗ ∗
∗ @ b r i e f Report enhanced c a l i b r a t i o n done .
∗
∗ @param measurement type
∗ @param c a l i b r a t e d v a l u e
∗ @param m a n u f a c t u r e r c o m p a n y i d
∗ @param n u m m a n u f a c t u r e r s p e c i f i c d a t a
∗ @param m a n u f a c t u r e r s p e c i f i c d a t a
∗/
void c y c l i n g p o w e r s e r v e r e n h a n c e d c a l i b r a t i o n d o n e (
c y c l i n g p o w e r s e n s o r m e a s u r e m e n t c o n t e x t t measurement type ,
uint16 t
calibrated value
, uint16 t
manufacturer company id
,
uint8 t
num manufacturer specific dat
, uint8 t ∗
manufacturer specific data
);
/∗ ∗
∗ @brief Set f a c t o r y c a l i b r a t i o n date .
∗ @param d a t e
∗ @return 1 i f s u c c e s s f u l
∗/
int c y c l i n g p o w e r s e r v i c e s e r v e r s e t f a c t o r y c a l i b r a t i o n d a t e (
g a t t d a t e t i m e t date ) ;
/∗ ∗
∗ @brief Set sampling rate .
∗ @param s a m p l i n g r a t e H z
292
∗/
void c y c l i n g p o w e r s e r v i c e s e r v e r s e t s a m p l i n g r a t e ( uint8 t
sampling rate Hz ) ;
/∗ ∗
∗ @ b r i e f Accumulate t o r q u e v a l u e .
∗ @param torque Nm
∗/
void c y c l i n g p o w e r s e r v i c e s e r v e r a d d t o r q u e ( i n t 1 6 t torque Nm ) ;
/∗ ∗
∗ @ b r i e f Accumulate w h e e l r e v o l u t i o n v a l u e and s e t t h e time o f t h e
l a s t measurement .
∗ @param w h e e l r e v o l u t i o n
∗ @param w h e e l e v e n t t i m e s u n i t : s e c o n d s
∗/
void c y c l i n g p o w e r s e r v i c e s e r v e r a d d w h e e l r e v o l u t i o n ( i n t 3 2 t
w h e e l r e v o l u t i o n , uint16 t w h e e l e v e n t t i m e s ) ;
/∗ ∗
∗ @ b r i e f Accumulate crank r e v o l u t i o n v a l u e and s e t t h e time o f t h e
l a s t measurement .
∗ @param c r a n k r e v o l u t i o n
∗ @param c r a n k e v e n t t i m e s u n i t : s e c o n d s
∗/
void c y c l i n g p o w e r s e r v i c e s e r v e r a d d c r a n k r e v o l u t i o n ( uint16 t
c r a n k r e v o l u t i o n , uint16 t c r a n k e v e n t t i m e s ) ;
/∗ ∗
∗ @ b r i e f Accumulate e n e r g y .
∗ @param e n e r g y k J u n i t : k i l o J o u l e
∗/
void c y c l i n g p o w e r s e r v i c e a d d e n e r g y ( uint16 t e n e r g y k J ) ;
/∗ ∗
∗ @ b r i e f S e t t h e v a l u e o f t h e power . The I n s t a n t a n e o u s Power f i e l d
represents either
∗ t h e t o t a l power t h e u s e r i s p r o d u c i n g or a p a r t o f t h e t o t a l
power d e p e n d i n g on t h e
∗ t y p e o f s e n s o r ( e . g . , s i n g l e s e n s o r or d i s t r i b u t e d power s e n s o r
system ) .
∗
∗ @param i n s t a n t a n e o u s p o w e r W u n i t : w a t t
∗/
void c y c l i n g p o w e r s e r v i c e s e r v e r s e t i n s t a n t a n e o u s p o w e r ( i n t 1 6 t
instantaneous power W ) ;
/∗ ∗
∗ @ b r i e f S e t t h e p e d a l power b a l a n c e v a l u e . The Pedal Power Balance
f i e l d r e p r e s e n t s the r a t i o between
∗ t h e t o t a l amount o f power measured by t h e s e n s o r and a r e f e r e n c e
( e i t h e r unknown or l e f t ) .
∗
∗ @param p e d a l p o w e r b a l a n c e p e r c e n t a g e
293
∗/
void c y c l i n g p o w e r s e r v i c e s e r v e r s e t p e d a l p o w e r b a l a n c e ( uint8 t
pedal power balance percentage ) ;
/∗ ∗
∗ @ b r i e f S e t t h e minimum and maximum f o r c e v a l u e measured i n a
s i n g l e crank r e v o l u t i o n .
∗
∗ This , so c a l l e d , Extreme Force Magnitude f i e l d p a i r w i l l be
i n c l u d e d i n t h e C y c l i n g Power Measurement
∗ c h a r a c t e r i s t i c o n l y i f t h e d e v i c e s u p p o r t s t h e Extreme Magnitudes
f e a t u r e and
∗ t h e Sensor Measurement C o n t e x t o f t h e C y c l i n g Power F e a t u r e
c h a r a c t e r i s t i c i s s e t t o 0 ( Force−b a s e d ) .
∗
∗ @param m i n f o r c e m a g n i t u d e N u n i t : newton
∗ @param m a x f o r c e m a g n i t u d e N u n i t : newton
∗/
void c y c l i n g p o w e r s e r v i c e s e r v e r s e t f o r c e m a g n i t u d e ( i n t 1 6 t
min force magnitude N , i n t 1 6 t max force magnitude N ) ;
/∗ ∗
∗ @ b r i e f S e t t h e minimum and maximum t o r q u e v a l u e measured i n a
s i n g l e crank r e v o l u t i o n .
∗
∗ This , so c a l l e d , Extreme Torque Magnitude f i e l d p a i r w i l l be
i n c l u d e d i n t h e C y c l i n g Power Measurement
∗ c h a r a c t e r i s t i c o n l y i f t h e d e v i c e s u p p o r t s t h e Extreme Magnitudes
f e a t u r e and
∗ t h e Sensor Measurement C o n t e x t o f t h e C y c l i n g Power F e a t u r e
c h a r a c t e r i s t i c i s s e t t o 1 ( Torque−b a s e d ) .
∗
∗ @param min torque magnitude Nm u n i t : newton meter
∗ @param max torque magnitude Nm u n i t : newton meter
∗/
void c y c l i n g p o w e r s e r v i c e s e r v e r s e t t o r q u e m a g n i t u d e ( i n t 1 6 t
min torque magnitude Nm , i n t 1 6 t max torque magnitude Nm ) ;
/∗ ∗
∗ @ b r i e f S e t t h e minimum and maximum a n g l e o f t h e crank measured i n
a s i n g l e crank r e v o l u t i o n ( u n i t : d e g r e e ) .
∗
∗ This , so c a l l e d , Extreme A n g l e s Magnitude f i e l d p a i r w i l l be
i n c l u d e d i n t h e C y c l i n g Power Measurement
∗ c h a r a c t e r i s t i c o n l y i f t h e d e v i c e s u p p o r t s t h e Extreme A n g l e s
feature .
∗
∗ @param m i n a n g l e d e g r e e
∗ @param m a x a n g l e d e g r e e
∗/
void c y c l i n g p o w e r s e r v i c e s e r v e r s e t a n g l e ( uint16 t
m i n a n g l e d e g r e e , uint16 t m a x a n g l e d e g r e e ) ;
/∗ ∗
294
/∗ ∗
∗ @ b r i e f S e t t h e v a l u e o f t h e crank a n g l e measured when t h e v a l u e
o f t h e I n s t a n t a n e o u s Power v a l u e becomes n e g a t i v e .
∗
∗ This f i e l d w i l l be i n c l u d e d i n t h e C y c l i n g Power Measurement
characteristic
∗ o n l y i f t h e d e v i c e s u p p o r t s t h e Top and Bottom Dead Spot A n g l e s
feature .
∗
∗ @param b o t t o m d e a d s p o t a n g l e d e g r e e
∗/
void c y c l i n g p o w e r s e r v i c e s e r v e r s e t b o t t o m d e a d s p o t a n g l e (
uint16 t b o t t o m d e a d s p o t a n g l e d e g r e e ) ;
/∗ ∗
∗ @ b r i e f S e t t h e raw s e n s o r f o r c e magnitude measurements .
∗
∗ @param f o r c e m a g n i t u d e c o u n t
∗ @param f o r c e m a g n i t u d e N a r r a y u n i t : newton
∗/
void c y c l i n g p o w e r s e r v i c e s e r v e r s e t f o r c e m a g n i t u d e v a l u e s ( int
force magnitude count , int16 t ∗ force magnitude N array ) ;
/∗ ∗
∗ @ b r i e f S e t t h e raw s e n s o r t o r q u e magnitude measurements .
∗
∗ @param f o r c e m a g n i t u d e c o u n t
∗ @param f o r c e m a g n i t u d e N a r r a y u n i t : newton meter
∗/
void c y c l i n g p o w e r s e r v i c e s e r v e r s e t t o r q u e m a g n i t u d e v a l u e s ( int
torque magnitude count , i n t 1 6 t ∗ torque magnitude Nm array ) ;
/∗ ∗
∗ @ b r i e f S e t t h e i n s t a n t a n e o u s measurement d i r e c t i o n . The f i e l d
describes
∗ t h e d i r e c t i o n o f t h e I n s t a n t a n e o u s Magnitude v a l u e s t h e S e r v e r
measures
∗ ( e . g . , Unknown , T a n g e n t i a l Component , R a d i a l Component , or
L a t e r a l Component ) .
∗
∗ @param d i r e c t i o n
295
∗/
void
cycling power service server set instantaneous measurement direction
( cycling power instantaneous measurement direction t direction ) ;
/∗ ∗
∗ S e t f i r s t crank measurement a n g l e . The v a l u e w i l l be p r e s e n t o n l y
in the f i r s t packet of
∗ t h e C y c l i n g Power Vector n o t i f i c a t i o n .
∗
∗ @param f i r s t c r a n k m e a s u r e m e n t a n g l e d e g r e e
∗/
void c y c l i n g p o w e r s e r v i c e s e r v e r s e t f i r s t c r a n k m e a s u r e m e n t a n g l e (
uint16 t f i r s t c r a n k m e a s u r e m e n t a n g l e d e g r e e ) ;
/∗ ∗
∗ Get measurement f l a g s b i t m a s k .
∗ @return m e a s u r e m e n t f l a g s b i t m a s k , s e e
cycling power measurement flag t
∗/
uint16 t c y c l i n g p o w e r s e r v i c e m e a s u r e m e n t f l a g s ( void ) ;
/∗ ∗
∗ Get v e c t o r f l a g s b i t m a s k .
∗ @return v e c t o r f l a g s b i t m a s k , s e e c y c l i n g p o w e r v e c t o r f l a g t
∗/
uint8 t c y c l i n g p o w e r s e r v i c e v e c t o r f l a g s ( void ) ;
/∗ ∗
∗ @brief Trigger n o t i f i c a t i o n i f subscribed
∗/
void c y c l i n g p o w e r s e r v i c e s e r v e r u p d a t e v a l u e s ( void ) ;
1.11. Cycling Speed and Cadence Service Server API. cycling speed and cadence servic
typedef enum {
CSC SERVICE SENSOR LOCATION OTHER = 0 ,
CSC SERVICE SENSOR LOCATION TOP OF SHOE ,
CSC SERVICE SENSOR LOCATION IN SHOE ,
CSC SERVICE SENSOR LOCATION HIP ,
CSC SERVICE SENSOR LOCATION FRONT WHEEL,
CSC SERVICE SENSOR LOCATION LEFT CRANK,
CSC SERVICE SENSOR LOCATION RIGHT CRANK,
CSC SERVICE SENSOR LOCATION LEFT PEDAL ,
CSC SERVICE SENSOR LOCATION RIGHT PEDAL,
CSC SERVICE SENSOR LOCATION FRONT HUB,
CSC SERVICE SENSOR LOCATION REAR DROPOUT,
CSC SERVICE SENSOR LOCATION CHAINSTAY,
CSC SERVICE SENSOR LOCATION REAR WHEEL,
CSC SERVICE SENSOR LOCATION REAR HUB,
CSC SERVICE SENSOR LOCATION CHEST,
CSC SERVICE SENSOR LOCATION SPIDER ,
296
typedef enum {
CSC FLAG WHEEL REVOLUTION DATA SUPPORTED = 0 ,
CSC FLAG CRANK REVOLUTION DATA SUPPORTED,
CSC FLAG MULTIPLE SENSOR LOCATIONS SUPPORTED
} csc feature flag bit t ;
typedef enum {
CSC OPCODE IDLE = 0 ,
CSC OPCODE SET CUMULATIVE VALUE = 1 ,
CSC OPCODE START SENSOR CALIBRATION,
CSC OPCODE UPDATE SENSOR LOCATION,
CSC OPCODE REQUEST SUPPORTED SENSOR LOCATIONS,
CSC OPCODE RESPONSE CODE = 16
} csc opcode t ;
/∗ ∗
∗ @ b r i e f I n i t S e r v e r w i t h ATT DB
∗/
void c y c l i n g s p e e d a n d c a d e n c e s e r v i c e s e r v e r i n i t ( uint32 t
supported sensor locations ,
uint8 t m u l t i p l e s e n s o r l o c a t i o n s s u p p o r t e d , uint8 t
w h e e l r e v o l u t i o n d a t a s u p p o r t e d , uint8 t
crank revolution data supported ) ;
/∗ ∗
∗ @ b r i e f Update h e a r t r a t e ( u n i t : b e a t s p e r minute )
∗ @note t r i g g e r s n o t i f i c a t i o n s i f s u b s c r i b e d
∗/
void c y c l i n g s p e e d a n d c a d e n c e s e r v i c e s e r v e r u p d a t e v a l u e s ( i n t 3 2 t
w h e e l r e v o l u t i o n s , uint16 t l a s t w h e e l e v e n t t i m e , uint16 t
c r a n k r e v o l u t i o n s , uint16 t l a s t c r a n k e v e n t t i m e ) ;
1.12. Device Information Service Client API. device information service client.h
/∗ ∗
∗ @ b r i e f I n i t i a l i z e D e vi c e I n f o r m a t i o n S e r v i c e .
∗/
void d e v i c e i n f o r m a t i o n s e r v i c e c l i e n t i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f Query D ev i c e I n f o r m a t i o n S e r v i c e . The c l i e n t w i l l q u e r y
t h e remote s e r v i c e and emit e v e n t s :
∗
∗ − GATTSERVICE SUBEVENT DEVICE INFORMATION MANUFACTURER NAME
∗ − GATTSERVICE SUBEVENT DEVICE INFORMATION MODEL NUMBER
∗ − GATTSERVICE SUBEVENT DEVICE INFORMATION SERIAL NUMBER
∗ − GATTSERVICE SUBEVENT DEVICE INFORMATION HARDWARE REVISION
∗ − GATTSERVICE SUBEVENT DEVICE INFORMATION FIRMWARE REVISION
297
/∗ ∗
∗ @ b r i e f De− i n i t i a l i z e D e vi c e I n f o r m a t i o n S e r v i c e .
∗/
void d e v i c e i n f o r m a t i o n s e r v i c e c l i e n t d e i n i t ( void ) ;
1.13. Device Information Service Server API. device information service server.h
/∗ ∗
∗ @ t e x t Th e D e v i c e I n f o r m a t i o n S e r v i c e a l l o w s t o q u e r y m a n u f a c t u r e r
and/ or
∗ vendor i n f o r m a t i o n a b o u t a d e v i c e .
∗
∗ To use w i t h your a p p l i c a t i o n , add ‘# i m p o rt <
d e v i c e i n f o r m a t i o n s e r v i c e . g a t t >‘ t o your . g a t t f i l e .
∗
∗ ∗ Note ∗ : i n s t e a d o f c a l l i n g a l l s e t t e r s , you can c r e a t e a l o c a l
copy o f t h e . g a t t f i l e and remove
∗ a l l C h a r a c t e r i s t i c s t h a t a r e not r e l e v a n t f o r your a p p l i c a t i o n
and d e f i n e a l l f i x e d v a l u e s i n t h e . g a t t f i l e .
∗/
/∗ ∗
∗ @ b r i e f I n i t D ev i c e I n f o r m a t i o n S e r v i c e S e r v e r w i t h ATT DB
∗ @param b a t t e r y v a l u e i n range 0−100
∗/
void d e v i c e i n f o r m a t i o n s e r v i c e s e r v e r i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f S e t Manufacturer Name
∗ @param manufacturer name
∗/
298
void d e v i c e i n f o r m a t i o n s e r v i c e s e r v e r s e t m a n u f a c t u r e r n a m e ( const
char ∗ manufacturer name ) ;
/∗ ∗
∗ @ b r i e f S e t Model Number
∗ @param model number
∗/
void d e v i c e i n f o r m a t i o n s e r v i c e s e r v e r s e t m o d e l n u m b e r ( const char ∗
model number ) ;
/∗ ∗
∗ @ b r i e f S e t S e r i a l Number
∗ @param s e r i a l n u m b e r
∗/
void d e v i c e i n f o r m a t i o n s e r v i c e s e r v e r s e t s e r i a l n u m b e r ( const char
∗ serial number ) ;
/∗ ∗
∗ @ b r i e f S e t Hardware R e v i s i o n
∗ @param h a r d w a r e r e v i s i o n
∗/
void d e v i c e i n f o r m a t i o n s e r v i c e s e r v e r s e t h a r d w a r e r e v i s i o n ( const
char ∗ h a r d w a r e r e v i s i o n ) ;
/∗ ∗
∗ @ b r i e f S e t Firmware R e v i s i o n
∗ @param f i r m w a r e r e v i s i o n
∗/
void d e v i c e i n f o r m a t i o n s e r v i c e s e r v e r s e t f i r m w a r e r e v i s i o n ( const
char ∗ f i r m w a r e r e v i s i o n ) ;
/∗ ∗
∗ @brief Set Software Revision
∗ @param s o f t w a r e r e v i s i o n
∗/
void d e v i c e i n f o r m a t i o n s e r v i c e s e r v e r s e t s o f t w a r e r e v i s i o n ( const
char ∗ s o f t w a r e r e v i s i o n ) ;
/∗ ∗
∗ @ b r i e f S e t System ID
∗ @param m a n u f a c t u r e r i d e n t i f i e r u i n t 4 0
∗ @param o r g a n i z a t i o n a l l y u n i q u e i d e n t i f i e r u i n t 2 4
∗/
void d e v i c e i n f o r m a t i o n s e r v i c e s e r v e r s e t s y s t e m i d ( u i n t 6 4 t
m a n u f a c t u r e r i d e n t i f i e r , uint32 t
organizationally unique identifier ) ;
/∗ ∗
∗ @ b r i e f S e t IEEE 11073 −20601 r e g u l a t o r y c e r t i f i c a t i o n d a t a l i s t
∗ @note : f o r ma t d u i n t 1 6 . d u i n t 1 6 i s two u i n t 1 6 v a l u e s c o n c a t e n a t e d
together .
∗ @param v a l u e a
∗ @param v a l u e b
∗/
299
void
device information service server set ieee regulatory certification
( uint16 t v a l u e a , uint16 t v a l u e b ) ;
/∗ ∗
∗ @ b r i e f S e t PnP ID
∗ @param v e n d o r s o u r c e i d
∗ @param v e n d o r i d
∗ @param p r o d u c t i d
∗ @Param p r o d u c t v e r s o i n
∗/
void d e v i c e i n f o r m a t i o n s e r v i c e s e r v e r s e t p n p i d ( uint8 t
v e n d o r s o u r c e i d , uint16 t v e n d o r i d , uint16 t p r o d u c t i d ,
uint16 t p r o d u c t v e r s i o n ) ;
1.14. Heart Rate Service Server API. heart rate service server.h
typedef enum {
HEART RATE SERVICE BODY SENSOR LOCATION OTHER = 0 ,
HEART RATE SERVICE BODY SENSOR LOCATION CHEST,
HEART RATE SERVICE BODY SENSOR LOCATION WRIST,
HEART RATE SERVICE BODY SENSOR LOCATION FINGER,
HEART RATE SERVICE BODY SENSOR LOCATION HAND,
HEART RATE SERVICE BODY SENSOR LOCATION EAR LOBE,
HEART RATE SERVICE BODY SENSOR LOCATION FOOT
} heart rate service body sensor location t ;
typedef enum {
HEART RATE SERVICE SENSOR CONTACT UNKNOWN = 0 ,
HEART RATE SERVICE SENSOR CONTACT UNSUPPORTED,
HEART RATE SERVICE SENSOR CONTACT NO CONTACT,
HEART RATE SERVICE SENSOR CONTACT HAVE CONTACT
} heart rate service sensor contact status t ;
/∗ ∗
∗ @ b r i e f I n i t B a t t e r y S e r v i c e S e r v e r w i t h ATT DB
∗ @param b o d y s e n s o r l o c a t i o n
∗ @param e n e r g y e x p e n d e d s u p p o r t e d
∗/
void h e a r t r a t e s e r v i c e s e r v e r i n i t (
heart rate service body sensor location t body sensor location ,
int e n e r g y e x p e n d e d s u p p o r t e d ) ;
/∗ ∗
∗ @ b r i e f Add Energy Expended t o t h e i n t e r n a l a c c u m u l a t o r .
∗ @param e n e r g y e x p e n d e d k J e n e r g y expended i n k i l o J o u l e s s i n c e
the l a s t update
∗/
void h e a r t r a t e s e r v i c e a d d e n e r g y e x p e n d e d ( uint16 t
energy expended kJ ) ;
300
/∗ ∗
∗ @ b r i e f Update h e a r t r a t e ( u n i t : b e a t s p e r minute )
∗ @note t r i g g e r s n o t i f i c a t i o n s i f s u b s c r i b e d
∗ @param h e a r t r a t e b p m b e a t s p e r minute
∗ @param c o n t a c t
∗ @param r r i n t e r v a l c o u n t
∗ @param r r i n t e r v a l s r e s o l u t i o n i n 1/1024 s e c o n d s
∗/
void h e a r t r a t e s e r v i c e s e r v e r u p d a t e h e a r t r a t e v a l u e s ( uint16 t
heart rate bpm ,
h e a r t r a t e s e r v i c e s e n s o r c o n t a c t s t a t u s t c o n t a c t , int
r r i n t e r v a l c o u n t , uint16 t ∗ r r i n t e r v a l s ) ;
/∗ ∗
∗ @ b r i e f I n i t i a l i z e HID S e r v i c e C l i e n t . The HID D e s c r i p t o r s t o r a g e
i s shared between a l l connections .
∗
∗ @param h i d d e s c r i p t o r s t o r a g e
∗ @param h i d d e s c r i p t o r s t o r a g e l e n
∗/
void h i d s c l i e n t i n i t ( uint8 t ∗ h i d d e s c r i p t o r s t o r a g e , uint16 t
hid descriptor storage len ) ;
/∗ ∗
∗ @ b r i e f Connect t o HID S e r v i c e s o f remote d e v i c e . Event
GATTSERVICE SUBEVENT HID SERVICE CONNECTED w i l l be e m i t t e d
∗ a f t e r a l l remote HID s e r v i c e s and c h a r a c t e r i s t i c s a r e found , and
n o t i f i c a t i o n s f o r a l l input r e p o r t s are enabled .
∗ S t a t u s code can be ERROR CODE SUCCES i f a t l e a s t one HID s e r v i c e
i s found , o t h e r w i s e e i t h e r ATT e r r o r s or
∗ ERROR CODE UNSUPPORTED FEATURE OR PARAMETER VALUE i f no s e r v i c e
or r e p o r t map or r e p o r t a r e found .
∗ I t a l s o c o n t a i n s t h e number o f i n d i v i d u a l HIDS S e r v i c e s .
∗
∗ @param c o n h a n d l e
∗ @param p a c k e t h a n d l e r
∗ @param p r o t o c o l m o d e s e e h i d p r o t o c o l m o d e t i n b t s t a c k h i d . h
∗ @param h i d s c i d ( o u t ) t o use f o r o t h e r f u n c t i o n s
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE COMMAND DISALLOWED i f t h e r e i s a l r e a d y a c l i e n t
∗ a s s o c i a t e d w i t h c o n h a n d l e , or
BTSTACK MEMORY ALLOC FAILED.
∗/
uint8 t h i d s c l i e n t c o n n e c t ( h c i c o n h a n d l e t c o n h a n d l e ,
btstack packet handler t p a c k e t h a n d l e r , h i d p r o t o c o l m o d e t
p r o t o c o l m o d e , uint16 t ∗ h i d s c i d ) ;
/∗ ∗
301
/∗ ∗
∗ @ b r i e f Get HID r e p o r t . Event GATTSERVICE SUBEVENT HID REPORT i s
emitted .
∗
∗ @param h i d s c i d
∗ @param r e p o r t i d
∗ @param r e p o r t t y p e
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
∗ ERROR CODE COMMAND DISALLOWED i f c l i e n t i s i n wrong s t a t e ,
∗ ERROR CODE UNSUPPORTED FEATURE OR PARAMETER VALUE i f no r e p o r t
w i t h g i v e n t y p e and ID i s found , or
∗ ERROR CODE PARAMETER OUT OF MANDATORY RANGE i f r e p o r t l e n g t h
e x c e e d s MTU.
∗/
uint8 t h i d s c l i e n t s e n d g e t r e p o r t ( uint16 t h i d s c i d , uint8 t
report id , hid report type t report type ) ;
/∗ ∗
∗ @ b r i e f Get HID I n f o r m a t i o n . Event
GATTSERVICE SUBEVENT HID INFORMATION i s e m i t t e d .
∗
∗ @param h i d s c i d
∗ @param s e r v i c e i n d e x
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
∗ ERROR CODE COMMAND DISALLOWED i f c l i e n t i s i n wrong s t a t e , or
∗ ERROR CODE UNSUPPORTED FEATURE OR PARAMETER VALUE i f no r e p o r t
w i t h g i v e n t y p e and ID i s found .
∗/
uint8 t h i d s c l i e n t g e t h i d i n f o r m a t i o n ( uint16 t h i d s c i d , uint8 t
service index ) ;
/∗ ∗
302
/∗ ∗
∗ @ b r i e f S e t P r o t o c o l Mode .
∗
∗ @param h i d s c i d
∗ @param s e r v i c e i n d e x
∗ @param p r o t o c o l m o d e
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
∗ ERROR CODE COMMAND DISALLOWED i f c l i e n t i s i n wrong s t a t e , or
∗ ERROR CODE UNSUPPORTED FEATURE OR PARAMETER VALUE i f no r e p o r t
w i t h g i v e n t y p e and ID i s found .
∗/
uint8 t h i d s c l i e n t s e n d s e t p r o t o c o l m o d e ( uint16 t h i d s c i d ,
uint8 t s e r v i c e i n d e x , h i d p r o t o c o l m o d e t p r o t o c o l m o d e ) ;
/∗ ∗
∗ @ b r i e f Send Suspend t o remote HID s e r v i c e .
∗
∗ @param h i d s c i d
∗ @param s e r v i c e i n d e x
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
∗ ERROR CODE COMMAND DISALLOWED i f c l i e n t i s i n wrong s t a t e , or
∗ ERROR CODE UNSUPPORTED FEATURE OR PARAMETER VALUE i f no r e p o r t
w i t h g i v e n t y p e and ID i s found .
∗/
uint8 t h i d s c l i e n t s e n d s u s p e n d ( uint16 t h i d s c i d , uint8 t
service index ) ;
/∗ ∗
∗ @ b r i e f Send E x i t Suspend t o remote HID s e r v i c e .
∗
∗ @param h i d s c i d
∗ @param s e r v i c e i n d e x
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
∗ ERROR CODE COMMAND DISALLOWED i f c l i e n t i s i n wrong s t a t e , or
∗ ERROR CODE UNSUPPORTED FEATURE OR PARAMETER VALUE i f no r e p o r t
w i t h g i v e n t y p e and ID i s found .
∗/
303
/∗ ∗
∗ @ b r i e f Enable a l l n o t i f i c a t i o n s . Event
GATTSERVICE SUBEVENT HID SERVICE REPORTS NOTIFICATION r e p o r t s
current configuration .
∗
∗ @param h i d s c i d
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER, or
∗ ERROR CODE COMMAND DISALLOWED i f c l i e n t i s i n wrong s t a t e .
∗/
uint8 t h i d s c l i e n t e n a b l e n o t i f i c a t i o n s ( uint16 t h i d s c i d ) ;
/∗ ∗
∗ @ b r i e f D i s a b l e a l l n o t i f i c a t i o n s . Event
GATTSERVICE SUBEVENT HID SERVICE REPORTS NOTIFICATION r e p o r t s
current configuration .
∗
∗ @param h i d s c i d
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER, or
∗ ERROR CODE COMMAND DISALLOWED i f c l i e n t i s i n wrong s t a t e .
∗/
uint8 t h i d s c l i e n t d i s a b l e n o t i f i c a t i o n s ( uint16 t h i d s c i d ) ;
/∗ ∗
∗ @ b r i e f D i s c o n n e c t from HID S e r v i c e .
∗
∗ @param h i d s c i d
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER
∗/
uint8 t h i d s c l i e n t d i s c o n n e c t ( uint16 t h i d s c i d ) ;
/∗
∗ @ b r i e f Get d e s c r i p t o r d a t a . For s e r v i c e s i n b o o t mode w i t h o u t a
Report Map, a d e f a u l t HID D e s c r i p t o r f o r Keyboard /Mouse i s
provided .
∗
∗ @param h i d c i d
∗ @return d a t a
∗/
const uint8 t ∗ h i d s c l i e n t d e s c r i p t o r s t o r a g e g e t d e s c r i p t o r d a t a (
uint16 t h i d s c i d , uint8 t s e r v i c e i n d e x ) ;
/∗
∗ @ b r i e f Get d e s c r i p t o r l e n g t h
∗
∗ @param h i d c i d
∗ @return l e n g t h
∗/
304
uint16 t h i d s c l i e n t d e s c r i p t o r s t o r a g e g e t d e s c r i p t o r l e n ( uint16 t
h i d s c i d , uint8 t s e r v i c e i n d e x ) ;
/∗ ∗
∗ @ b r i e f De− i n i t i a l i z e HID S e r v i c e C l i e n t .
∗
∗/
void h i d s c l i e n t d e i n i t ( void ) ;
typedef struct {
uint16 t v a l u e h a n d l e ;
uint16 t c l i e n t c o n f i g u r a t i o n h a n d l e ;
uint16 t c l i e n t c o n f i g u r a t i o n v a l u e ;
h i d r e p o r t t y p e t type ;
uint8 t i d ;
uint8 t s i z e ;
} hids device report t ;
/∗ ∗
∗ @ t e x t I m p l e m e n t a t i o n o f t h e GATT HIDS De v i ce
∗ To use w i t h your a p p l i c a t i o n , add ’# i m p o rt <h i d s . g a t t >’ t o your .
gatt f i l e
∗/
/∗ ∗
∗ @ b r i e f S e t up HIDS D e v ic e w i t h s i n g l e INPUT, OUTPUT and FEATURE
report
∗/
void h i d s d e v i c e i n i t ( uint8 t h i d c o u n t r y c o d e , const uint8 t ∗
h i d d e s c r i p t o r , uint16 t h i d d e s c r i p t o r s i z e ) ;
/∗ ∗
∗ @ b r i e f S e t up HIDS D e v ic e f o r m u l t i p l e i n s t a n c e s o f INPUT, OUTPUT
and FEATURE r e p o r t s
∗/
void h i d s d e v i c e i n i t w i t h s t o r a g e ( uint8 t h i d c o u n t r y c o d e , const
uint8 t ∗ h i d d e s c r i p t o r , uint16 t h i d d e s c r i p t o r s i z e ,
uint16 t num reports , h i d s d e v i c e r e p o r t t ∗ r e p o r t s t o r a g e ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k f o r t h e HIDS De v i ce c l i e n t .
∗ @param c a l l b a c k
∗/
void h i d s d e v i c e r e g i s t e r p a c k e t h a n d l e r ( btstack packet handler t
callback ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r r e p o r t c a l l b a c k f o r Get Report o p e r a t i o n
∗ @param c a l l b a c k
305
∗/
void h i d s d e v i c e r e g i s t e r g e t r e p o r t c a l l b a c k ( void ( ∗ c a l l b a c k ) (
h c i c o n h a n d l e t con handle , h i d r e p o r t t y p e t report type ,
uint16 t r e p o r t i d , uint16 t m a x r e p o r t s i z e , uint8 t ∗
out report ) ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t can send now e v e n t t o send HID Report
∗ G e n e r a t e s an HIDS SUBEVENT CAN SEND NOW s u b e v e n t
∗ @param h i d c i d
∗/
void h i d s d e v i c e r e q u e s t c a n s e n d n o w e v e n t ( h c i c o n h a n d l e t
con handle ) ;
/∗ ∗
∗ @ b r i e f Send HID I n p u t Report f o r Report ID
∗ @param c o n h a n d l e
∗ @param r e p o r t i d
∗ @param r e p o r t
∗ @param r e p o r t l e n
∗ @returns s t a t u s
∗/
uint8 t h i d s d e v i c e s e n d i n p u t r e p o r t f o r i d ( h c i c o n h a n d l e t
c o n h a n d l e , uint16 t r e p o r t i d , const uint8 t ∗ r e p o r t , uint16 t
report len ) ;
/∗ ∗
∗ @ b r i e f Send HID I n p u t Report f o r f i r s t I n p u t Report
∗ @param c o n h a n d l e
∗ @param r e p o r t
∗ @param r e p o r t l e n
∗ @returns s t a t u s
∗/
uint8 t h i d s d e v i c e s e n d i n p u t r e p o r t ( h c i c o n h a n d l e t c o n h a n d l e ,
const uint8 t ∗ r e p o r t , uint16 t r e p o r t l e n ) ;
/∗ ∗
∗ @ b r i e f Send HID Boot Mouse I n p u t Report
∗ @param c o n h a n d l e
∗ @param r e p o r t
∗ @param r e p o r t l e n
∗ @returns s t a t u s
∗/
uint8 t h i d s d e v i c e s e n d b o o t m o u s e i n p u t r e p o r t ( h c i c o n h a n d l e t
c o n h a n d l e , const uint8 t ∗ r e p o r t , uint16 t r e p o r t l e n ) ;
/∗ ∗
∗ @ b r i e f Send HID Boot Mouse I n p u t Report
∗ @param c o n h a n d l e
∗ @param r e p o r t
∗ @param r e p o r t l e n
∗ @returns s t a t u s
∗/
306
uint8 t h i d s d e v i c e s e n d b o o t k e y b o a r d i n p u t r e p o r t ( h c i c o n h a n d l e t
c o n h a n d l e , const uint8 t ∗ r e p o r t , uint16 t r e p o r t l e n ) ;
1.17. Nordic SPP Service Server API. nordic spp service server.h
/∗ ∗
∗ @ t e x t The Nordic SPP S e r v i c e i s i m p l e m e n t a t i o n o f t h e Nordic SPP−
like profile .
∗
∗ To use w i t h your a p p l i c a t i o n , add ‘# i m p o rt <n o r d i c s p p s e r v i c e .
g a t t >‘ t o your . g a t t f i l e
∗ and c a l l a l l f u n c t i o n s b e l o w . A l l s t r i n g s and b l o b s need t o s t a y
valid aft er c a l l i n g the functions .
∗/
/∗ ∗
∗ @ b r i e f I n i t Nordic SPP S e r v i c e S e r v e r w i t h ATT DB
∗ @param p a c k e t h a n d l e r f o r e v e n t s and t x d a t a from p e e r as
RFCOMM DATA PACKET
∗/
void n o r d i c s p p s e r v i c e s e r v e r i n i t ( btstack packet handler t
packet handler ) ;
/∗ ∗
∗ @ b r i e f Queue send r e q u e s t . When c a l l e d , one p a c k e t can be send
via n o r d i c s p p s e r v i c e s e n d below
∗ @param r e q u e s t
∗ @param c o n h a n d l e
∗/
void n o r d i c s p p s e r v i c e s e r v e r r e q u e s t c a n s e n d n o w (
b t s t a c k c o n t e x t c a l l b a c k r e g i s t r a t i o n t ∗ request ,
hci con handle t con handle ) ;
/∗ ∗
∗ @ b r i e f Send d a t a
∗ @param c o n h a n d l e
∗ @param d a t a
∗ @param s i z e
∗/
int n o r d i c s p p s e r v i c e s e r v e r s e n d ( h c i c o n h a n d l e t c o n h a n d l e ,
const uint8 t ∗ data , uint16 t s i z e ) ;
1.18. Scan Parameters Service Client API. scan parameters service client.h
/∗ ∗
∗ @ b r i e f I n i t i a l i z e Scan Parameters S e r v i c e .
∗/
void s c a n p a r a m e t e r s s e r v i c e c l i e n t i n i t ( void ) ;
/∗ ∗
307
∗ @ b r i e f S e t Scan Parameters S e r v i c e . I t w i l l u p d a t e a l l c o n n e c t e d
devices .
∗ @param s c a n i n t e r v a l
∗ @param scan window
∗/
void s c a n p a r a m e t e r s s e r v i c e c l i e n t s e t ( uint16 t s c a n i n t e r v a l ,
uint16 t scan window ) ;
/∗ ∗
∗ @ b r i e f Connect t o Scan Parameters S e r v i c e o f remote d e v i c e .
∗
∗ The GATTSERVICE SUBEVENT SCAN PARAMETERS SERVICE CONNECTED e v e n t
completes the request .
∗ I t s s t a t u s i s s e t t o ERROR CODE SUCCESS i f remote s e r v i c e and
SCAN INTERVAL WINDOW c h a r a c t e r i s t i c a r e found .
∗ Other s t a t u s c o d e s o f t h i s e v e n t :
∗ − GATT CLIENT IN WRONG STATE : c l i e n t i n wrong s t a t e
∗ − ERROR CODE UNSUPPORTED FEATURE OR PARAMETER VALUE: s e r v i c e or
c h a r a c t e r i s t i c not found
∗ − ATT e r r o r s , s e e b l u e t o o t h . h
∗
∗ @param c o n h a n d l e
∗ @param p a c k e t h a n d l e r
∗ @param s c a n p a r a m e t e r s c i d
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c l i e n t w i t h
c o n h a n d l e not found
∗/
uint8 t s c a n p a r a m e t e r s s e r v i c e c l i e n t c o n n e c t ( h c i c o n h a n d l e t
c o n h a n d l e , btstack packet handler t p a c k e t h a n d l e r , uint16 t ∗
scan parameters cid ) ;
/∗ ∗
∗ @ b r i e f Enable n o t i f i c a t i o n s
∗ @param s c a n p a r a m e t e r s c i d
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c l i e n t w i t h
c o n h a n d l e i s not found
∗/
uint8 t s c a n p a r a m e t e r s s e r v i c e c l i e n t e n a b l e n o t i f i c a t i o n s ( uint16 t
scan parameters cid ) ;
/∗ ∗
∗ @ b r i e f D i s c o n n e c t from Scan Parameters S e r v i c e .
∗ @param s c a n p a r a m e t e r s c i d
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c l i e n t w i t h
c o n h a n d l e i s not found
∗/
uint8 t s c a n p a r a m e t e r s s e r v i c e c l i e n t d i s c o n n e c t ( uint16 t
scan parameters cid ) ;
/∗ ∗
308
1.19. Scan Parameters Service Server API. scan parameters service server.h
/∗ ∗
∗ @ t e x t The Scan Parameters S e r v i c e e n a b l e s a remote GATT C l i e n t t o
s t o r e t h e LE scan p a r a m e t e r s i t i s u s i n g l o c a l l y . These
p a r a m e t e r s can be u t i l i z e d by t h e a p p l i c a t i o n t o o p t i m i z e power
consumption and/ or r e c o n n e c t i o n l a t e n c y .
∗
∗ To use w i t h your a p p l i c a t i o n , add ‘# i m p o rt <
s c a n p a r a m e t e r s s e r v i c e . g a t t >‘ t o your . g a t t f i l e
∗ and c a l l a l l f u n c t i o n s b e l o w . A l l s t r i n g s and b l o b s need t o s t a y
valid aft er c a l l i n g the functions .
∗/
/∗ ∗
∗ @brief I n i t Scan Parameters S e r v i c e S e r v e r w i t h ATT DB
∗ @param packet handler
∗/
void s c a n p a r a m e t e r s s e r v i c e s e r v e r i n i t ( btstack packet handler t
packet handler ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t scan p a r a m e t e r s from Scan Parameters C l i e n t .
∗/
void s c a n p a r a m e t e r s s e r v i c e s e r v e r r e q u e s t s c a n p a r a m e t e r s ( void ) ;
/∗ ∗
∗ @ b r i e f I n i t TX Power S e r v i c e S e r v e r w i t h ATT DB
∗ @param t x p o w e r l e v e l
∗/
void t x p o w e r s e r v i c e s e r v e r i n i t ( i n t 8 t t x p o w e r l e v e l ) ;
/∗ ∗
∗ @ b r i e f Update TX power l e v e l
∗ @param t x p o w e r l e v e l d B m range [ −100 ,20]
∗/
void t x p o w e r s e r v i c e s e r v e r s e t l e v e l ( i n t 8 t t x p o w e r l e v e l d B m ) ;
1.21. u-blox SPP Service Server API. ublox spp service server.h
/∗ ∗
309
/∗ ∗
∗ @ b r i e f I n i t u b l o x SPP S e r v i c e S e r v e r w i t h ATT DB
∗ @param p a c k e t h a n d l e r f o r e v e n t s and t x d a t a from p e e r as
RFCOMM DATA PACKET
∗/
void u b l o x s p p s e r v i c e s e r v e r i n i t ( btstack packet handler t
packet handler ) ;
/∗ ∗
∗ @ b r i e f Queue send r e q u e s t . When c a l l e d , one p a c k e t can be send
via u b l o x s p p s e r v i c e s e n d below
∗ @param r e q u e s t
∗ @param c o n h a n d l e
∗/
void u b l o x s p p s e r v i c e s e r v e r r e q u e s t c a n s e n d n o w (
b t s t a c k c o n t e x t c a l l b a c k r e g i s t r a t i o n t ∗ request ,
hci con handle t con handle ) ;
/∗ ∗
∗ @brief Send d a t a
∗ @param con handle
∗ @param data
∗ @param size
∗/
int u b l o x s p p s e r v i c e s e r v e r s e n d ( h c i c o n h a n d l e t c o n h a n d l e , const
uint8 t ∗ data , uint16 t s i z e ) ;
typedef struct {
uint16 t s t a r t g r o u p h a n d l e ;
uint16 t e n d g r o u p h a n d l e ;
uint16 t uuid16 ;
uint8 t uuid128 [ 1 6 ] ;
} gatt client service t ;
typedef struct {
uint16 t s t a r t h a n d l e ;
uint16 t v a l u e h a n d l e ;
uint16 t e n d h a n d l e ;
uint16 t p r o p e r t i e s ;
uint16 t uuid16 ;
uint8 t uuid128 [ 1 6 ] ;
310
typedef struct {
uint16 t h a n d l e ;
uint16 t uuid16 ;
uint8 t uuid128 [ 1 6 ] ;
} gatt client characteristic descriptor t ;
/∗ ∗
∗ @ b r i e f S e t up GATT c l i e n t .
∗/
void g a t t c l i e n t i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f S e t minimum r e q u i r e d s e c u r i t y l e v e l f o r GATT C l i e n t
∗ @note The B l u e t o o t h s p e c i f i c a t i o n makes t h e GATT S e r v e r
r e s p o n s i b l e to check for s e c u r i t y .
∗ This a l l o w s an a t t a c k e r t o s p o o f an e x i s t i n g d e v i c e w i t h a
GATT S e r v e r s , b u t s k i p t h e a u t h e n t i c a t i o n p a r t .
∗ I f your a p p l i c a t i o n i s e x c h a n g i n g s e n s i t i v e d a t a w i t h a
remote d e v i c e , you would need t o manually c h e c k
∗ t h e s e c u r i t y l e v e l b e f o r e s e n d i n g / r e c e i v e such d a t a .
∗ With l e v e l > 0 , t h e GATT C l i e n t t r i g g e r s a u t h e n t i c a t i o n
f o r a l l GATT R e q u e s t s and d e f e r s any e x c h a n g e
∗ u n t i l the required security l e v e l i s e s t a b l i s h e d .
∗ g a t t c l i e n t r e q u e s t c a n w r i t e w i t h o u t r e s p o n s e e v e n t does
not t r i g g e r a u t h e n t i c a t i o n
∗ g a t t c l i e n t r e q u e s t t o w r i t e w i t h o u t r e s p o n s e d o e s not
trigger authentication
∗ @pram l e v e l , d e f a u l t LEVEL 0 ( no e n c r y p t i o n r e q u i r e d )
∗/
void g a t t c l i e n t s e t r e q u i r e d s e c u r i t y l e v e l ( g a p s e c u r i t y l e v e l t
level ) ;
/∗ ∗
∗ @ b r i e f Connect t o remote GATT S e r v e r o v e r C l a s s i c (BR/EDR)
Connection
∗ GATT EVENT CONNECTED w i t h s t a t u s and c o n h a n d l e f o r o t h e r
API f u n c t i o n s
∗ i s e m i t t e d on c o n n e c t i o n c o m p l e t e .
∗ @note r e q u i r e s ENABLE GATT OVER CLASSIC .
∗ @param addr
∗ @return s t a t u s
∗/
uint8 t g a t t c l i e n t c l a s s i c c o n n e c t ( btstack packet handler t
c a l l b a c k , bd addr t addr ) ;
/∗ ∗
∗ @ b r i e f D i s c o n n e c t o C l a s s i c (BR/EDR) c o n n e c t i o n t o a remote GATT
Server
∗ @note r e q u i r e s ENABLE GATT OVER CLASSIC
∗ @param c o n h a n d l e
∗ @return s t a t u s
∗/
311
/∗ ∗
∗ @ b r i e f S e tu p Enhanced LE Bearer w i t h up t o 5 c h a n n e l s on e x i s t i n g
LE c o n n e c t i o n
∗ @param c a l l b a c k f o r GATT EVENT CONNECTED and
GATT EVENT DISCONNECTED e v e n t s
∗ @param c o n h a n d l e
∗ @param num channels
∗ @param s t o r a g e b u f f e r f o r L2CAP c o n n e c t i o n
∗ @param s t o r a g e s i z e − each c h a n n e l r e q u i r e s (2 ∗ ATT MTU) + 10
bytes
∗ @return
∗/
uint8 t g a t t c l i e n t l e e n h a n c e d c o n n e c t ( btstack packet handler t
c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e , uint8 t num channels ,
uint8 t ∗ s t o r a g e b u f f e r , uint16 t s t o r a g e s i z e ) ;
/∗ ∗
∗ @ b r i e f MTU i s a v a i l a b l e a f t e r t h e f i r s t q u e r y has c o m p l e t e d . I f
s t a t u s i s e q u a l t o ERROR CODE SUCCESS, i t r e t u r n s t h e r e a l
value ,
∗ o t h e r w i s e t h e d e f a u l t v a l u e ATT DEFAULT MTU ( s e e b l u e t o o t h . h ) .
∗ @param c o n h a n d l e
∗ @param mtu
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER
i f no HCI c o n n e c t i o n f o r c o n h a n d l e i s found
∗ BTSTACK MEMORY ALLOC FAILED
i f no GATT c l i e n t f o r c o n h a n d l e
c o u l d be a l l o c a t e d
∗ GATT CLIENT IN WRONG STATE
i f MTU i s not e x c h a n g e d and MTU
auto−e x c h a n g e i s d i s a b l e d
∗ ERROR CODE SUCCESS
i f query i s s u c c e s s f u l l y
registered
∗/
uint8 t g a t t c l i e n t g e t m t u ( h c i c o n h a n d l e t c o n h a n d l e , uint16 t ∗
mtu ) ;
/∗ ∗
∗ @ b r i e f S e t s w h e t h e r a MTU Exchange R e q u e s t s h a l l be a u t o m a t i c a l l y
send b e f o r e t h e
∗ f i r s t a t t r i b u t e r ead r e q u e s t i s send . D e f a u l t i s e n a b l e d .
∗ @param e n a b l e d
∗/
void g a t t c l i e n t m t u e n a b l e a u t o n e g o t i a t i o n ( uint8 t e n a b l e d ) ;
/∗ ∗
∗ @ b r i e f Sends a MTU Exchange Request , t h i s a l l o w s f o r t h e c l i e n t
t o e x c h a n g e MTU
∗ when g a t t c l i e n t m t u e n a b l e a u t o n e g o t i a t i o n i s d i s a b l e d .
∗ @param c a l l b a c k
312
∗ @param c o n h a n d l e
∗/
void g a t t c l i e n t s e n d m t u n e g o t i a t i o n ( btstack packet handler t
callback , hci con handle t con handle ) ;
/∗ ∗
∗ @ b r i e f Returns 1 i f t h e GATT c l i e n t i s r e a d y t o r e c e i v e a q u e r y .
I t i s used w i t h daemon .
∗ @param c o n h a n d l e
∗ @return i s r e a d y s t a t u s 0 − i f no GATT c l i e n t f o r c o n h a n d l e
i s found , or i s not ready , o t h e r w i s e 1
∗/
int g a t t c l i e n t i s r e a d y ( h c i c o n h a n d l e t c o n h a n d l e ) ;
/∗ ∗
∗ @ b r i e f D i s c o v e r s a l l primary s e r v i c e s .
∗ For each found s e r v i c e a GATT EVENT SERVICE QUERY RESULT e v e n t
w i l l be e m i t t e d .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f d i s c o v e r y .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
∗ ERROR CODE SUCCESS , i f query i s
successfully registered
∗/
uint8 t g a t t c l i e n t d i s c o v e r p r i m a r y s e r v i c e s (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ) ;
/∗ ∗
∗ @brief Discovers a l l secondary s e r v i c e s .
∗ For each found s e r v i c e a GATT EVENT SERVICE QUERY RESULT e v e n t
w i l l be e m i t t e d .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f d i s c o v e r y .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
∗ ERROR CODE SUCCESS , i f query i s
successfully registered
∗/
uint8 t g a t t c l i e n t d i s c o v e r s e c o n d a r y s e r v i c e s (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ) ;
/∗ ∗
∗ @ b r i e f D i s c o v e r s a s p e c i f i c primary s e r v i c e g i v e n i t s UUID . This
s e r v i c e may e x i s t m u l t i p l e t i m e s .
∗ For each found s e r v i c e a GATT EVENT SERVICE QUERY RESULT e v e n t
w i l l be e m i t t e d .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f d i s c o v e r y .
313
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param uuid16
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
∗ ERROR CODE SUCCESS , i f query i s
successfully registered
∗/
uint8 t g a t t c l i e n t d i s c o v e r p r i m a r y s e r v i c e s b y u u i d 1 6 (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t uuid16 ) ;
/∗ ∗
∗ @ b r i e f D i s c o v e r s a s p e c i f i c primary s e r v i c e g i v e n i t s UUID . This
s e r v i c e may e x i s t m u l t i p l e t i m e s .
∗ For each found s e r v i c e a GATT EVENT SERVICE QUERY RESULT e v e n t
w i l l be e m i t t e d .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f d i s c o v e r y .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param uuid128
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
∗ ERROR CODE SUCCESS , i f query i s
successfully registered
∗/
uint8 t g a t t c l i e n t d i s c o v e r p r i m a r y s e r v i c e s b y u u i d 1 2 8 (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
const uint8 t ∗ uuid128 ) ;
/∗ ∗
∗ @ b r i e f Finds i n c l u d e d s e r v i c e s w i t h i n t h e s p e c i f i e d s e r v i c e .
∗ For each found i n c l u d e d s e r v i c e a
GATT EVENT INCLUDED SERVICE QUERY RESULT e v e n t w i l l be e m i t t e d .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f d i s c o v e r y .
∗ I n f o r m a t i o n a b o u t i n c l u d e d s e r v i c e t y p e ( primary / s e c o n d a r y ) can
be r e t r i e v e d e i t h e r by s e n d i n g
∗ an ATT f i n d i n f o r m a t i o n r e q u e s t f o r t h e r e t u r n e d s t a r t group
handle
∗ ( r e t u r n i n g t h e h a n d l e and t h e UUID f o r primary or s e c o n d a r y
s e r v i c e ) or by comparing t h e s e r v i c e
∗ t o t h e l i s t o f a l l primary s e r v i c e s .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param s e r v i c e
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
314
/∗ ∗
∗ @brief Discovers a l l c h a r a c t e r i s t i c s within the s p e c i f i e d service
.
∗ For each found c h a r a c t e r i s t i c a
GATT EVENT CHARACTERISTIC QUERY RESULT e v e n t w i l l be e m i t e d .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f d i s c o v e r y .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param s e r v i c e
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
∗ ERROR CODE SUCCESS , i f query i s
successfully registered
∗/
uint8 t g a t t c l i e n t d i s c o v e r c h a r a c t e r i s t i c s f o r s e r v i c e (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
gatt client service t ∗ s e r v i c e ) ;
/∗ ∗
∗ @ b r i e f The f o l l o w i n g f o u r f u n c t i o n s a r e used t o d i s c o v e r a l l
characteristics within
∗ t h e s p e c i f i e d s e r v i c e or h a n d l e range , and r e t u r n t h o s e t h a t
match t h e g i v e n UUID .
∗
∗ For each found c h a r a c t e r i s t i c a
GATT EVENT CHARACTERISTIC QUERY RESULT e v e n t w i l l e m i t t e d .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f d i s c o v e r y .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param s t a r t h a n d l e
∗ @param e n d h a n d l e
∗ @param uuid16
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
∗ ERROR CODE SUCCESS , i f query i s
successfully registered
∗/
uint8 t
gatt client discover characteristics for handle range by uuid16 (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t s t a r t h a n d l e , uint16 t e nd h an dl e , uint16 t uuid16 ) ;
/∗ ∗
315
∗ @ b r i e f The f o l l o w i n g f o u r f u n c t i o n s a r e used t o d i s c o v e r a l l
c h a r a c t e r i s t i c s within the
∗ s p e c i f i e d s e r v i c e or h a n d l e range , and r e t u r n t h o s e t h a t match
t h e g i v e n UUID .
∗ For each found c h a r a c t e r i s t i c a
GATT EVENT CHARACTERISTIC QUERY RESULT e v e n t w i l l e m i t t e d .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f d i s c o v e r y .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param s t a r t h a n d l e
∗ @param e n d h a n d l e
∗ @param uuid128
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
∗ ERROR CODE SUCCESS , i f query i s
successfully registered
∗/
uint8 t
gatt client discover characteristics for handle range by uuid128
( btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t s t a r t h a n d l e , uint16 t e nd h an dl e , const uint8 t ∗
uuid128 ) ;
/∗ ∗
∗ @ b r i e f The f o l l o w i n g f o u r f u n c t i o n s a r e used t o d i s c o v e r a l l
c h a r a c t e r i s t i c s within the
∗ s p e c i f i e d s e r v i c e or h a n d l e range , and r e t u r n t h o s e t h a t match
t h e g i v e n UUID .
∗ For each found c h a r a c t e r i s t i c a
GATT EVENT CHARACTERISTIC QUERY RESULT e v e n t w i l l e m i t t e d .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f d i s c o v e r y .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param s e r v i c e
∗ @param uuid16
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
∗ ERROR CODE SUCCESS , i f query i s
successfully registered
∗/
uint8 t g a t t c l i e n t d i s c o v e r c h a r a c t e r i s t i c s f o r s e r v i c e b y u u i d 1 6 (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
g a t t c l i e n t s e r v i c e t ∗ s e r v i c e , uint16 t uuid16 ) ;
/∗ ∗
∗ @ b r i e f The f o l l o w i n g f o u r f u n c t i o n s a r e used t o d i s c o v e r a l l
c h a r a c t e r i s t i c s within the
∗ s p e c i f i e d s e r v i c e or h a n d l e range , and r e t u r n t h o s e t h a t match
t h e g i v e n UUID .
316
/∗ ∗
∗ @ b r i e f D i s c o v e r s a t t r i b u t e h a n d l e and UUID o f a c h a r a c t e r i s t i c
descriptor within the s p e c i f i e d c h a r a c t e r i s t i c .
∗ For each found d e s c r i p t o r a
GATT EVENT ALL CHARACTERISTIC DESCRIPTORS QUERY RESULT e v e n t
w i l l be e m i t t e d .
∗
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f d i s c o v e r y .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param c h a r a c t e r i s t i c
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
∗ ERROR CODE SUCCESS , i f query i s
successfully registered
∗/
uint8 t g a t t c l i e n t d i s c o v e r c h a r a c t e r i s t i c d e s c r i p t o r s (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
gatt client characteristic t ∗ c h a r a c t e r i s t i c ) ;
/∗ ∗
∗ @ b r i e f Reads t h e c h a r a c t e r i s t i c v a l u e u s i n g t h e c h a r a c t e r i s t i c ’ s
value handle .
∗ I f t h e c h a r a c t e r i s t i c v a l u e i s found a
GATT EVENT CHARACTERISTIC VALUE QUERY RESULT e v e n t w i l l be
emitted .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f rea d .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param c h a r a c t e r i s t i c
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
317
/∗ ∗
∗ @ b r i e f Reads t h e c h a r a c t e r i s t i c v a l u e u s i n g t h e c h a r a c t e r i s t i c ’ s
value handle .
∗ I f t h e c h a r a c t e r i s t i c v a l u e i s found a
GATT EVENT CHARACTERISTIC VALUE QUERY RESULT e v e n t w i l l be
emitted .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f rea d .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param v a l u e h a n d l e
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
∗ ERROR CODE SUCCESS , i f query i s
successfully registered
∗/
uint8 t g a t t c l i e n t r e a d v a l u e o f c h a r a c t e r i s t i c u s i n g v a l u e h a n d l e (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t v a l u e h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Reads t h e c h a r a c t e r i c v a l u e o f a l l c h a r a c t e r i s t i c s w i t h
the uuid .
∗ For each c h a r a c t e r i s t i c v a l u e found a
GATT EVENT CHARACTERISTIC VALUE QUERY RESULT e v e n t w i l l be
emitted .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f rea d .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param s t a r t h a n d l e
∗ @param e n d h a n d l e
∗ @param uuid16
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
∗ ERROR CODE SUCCESS , i f query i s
successfully registered
∗/
uint8 t g a t t c l i e n t r e a d v a l u e o f c h a r a c t e r i s t i c s b y u u i d 1 6 (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t s t a r t h a n d l e , uint16 t e nd h an dl e , uint16 t uuid16 ) ;
/∗ ∗
∗ @ b r i e f Reads t h e c h a r a c t e r i c v a l u e o f a l l c h a r a c t e r i s t i c s w i t h
the uuid .
318
/∗ ∗
∗ @ b r i e f Reads t h e l o n g c h a r a c t e r i s t i c v a l u e u s i n g t h e
c h a r a c t e r i s t i c ’ s value handle .
∗ The v a l u e w i l l be r e t u r n e d i n s e v e r a l b l o b s .
∗ For each b l o b , a
GATT EVENT LONG CHARACTERISTIC VALUE QUERY RESULT e v e n t w i t h
u p d a t e d v a l u e o f f s e t w i l l be e m i t t e d .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f rea d .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param c h a r a c t e r i s t i c
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
∗ ERROR CODE SUCCESS , i f query i s
successfully registered
∗/
uint8 t g a t t c l i e n t r e a d l o n g v a l u e o f c h a r a c t e r i s t i c (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
gatt client characteristic t ∗ c h a r a c t e r i s t i c ) ;
/∗ ∗
∗ @ b r i e f Reads t h e l o n g c h a r a c t e r i s t i c v a l u e u s i n g t h e
c h a r a c t e r i s t i c ’ s value handle .
∗ The v a l u e w i l l be r e t u r n e d i n s e v e r a l b l o b s .
∗ For each b l o b , a
GATT EVENT LONG CHARACTERISTIC VALUE QUERY RESULT e v e n t w i t h
u p d a t e d v a l u e o f f s e t w i l l be e m i t t e d .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f rea d .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param v a l u e h a n d l e
319
/∗ ∗
∗ @ b r i e f Reads t h e l o n g c h a r a c t e r i s t i c v a l u e u s i n g t h e
c h a r a c t e r i s t i c ’ s value handle .
∗ The v a l u e w i l l be r e t u r n e d i n s e v e r a l b l o b s .
∗ For each b l o b , a
GATT EVENT LONG CHARACTERISTIC VALUE QUERY RESULT e v e n t w i t h
u p d a t e d v a l u e o f f s e t w i l l be e m i t t e d .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f rea d .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param v a l u e h a n d l e
∗ @param o f f s e t
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
∗ ERROR CODE SUCCESS , i f query i s
successfully registered
∗/
uint8 t
gatt client read long value of characteristic using value handle with offset
( btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t v a l u e h a n d l e , uint16 t o f f s e t ) ;
/∗
∗ @ b r i e f Read m u l t i p l e c h a r a c t e r i s t i c v a l u e s .
∗ The a l l r e s u l t s a r e e m i t t e d v i a s i n g l e
GATT EVENT CHARACTERISTIC VALUE QUERY RESULT e v e n t ,
∗ f o l l o w e d by t h e GATT EVENT QUERY COMPLETE e v e n t , which marks t h e
end o f read .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param n u m v a l u e h a n d l e s
∗ @param v a l u e h a n d l e s l i s t o f h a n d l e s
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
∗ ERROR CODE SUCCESS , i f query i s
successfully registered
∗/
320
uint8 t g a t t c l i e n t r e a d m u l t i p l e c h a r a c t e r i s t i c v a l u e s (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
int n u m v a l u e h a n d l e s , uint16 t ∗ v a l u e h a n d l e s ) ;
/∗
∗ @ b r i e f Read m u l t i p l e v a r a i b l e c h a r a c t e r i s t i c v a l u e s . Only
s u p p o r t e d o v e r LE Enhanced Bearer
∗ The a l l r e s u l t s a r e e m i t t e d v i a s i n g l e
GATT EVENT CHARACTERISTIC VALUE QUERY RESULT e v e n t ,
∗ f o l l o w e d by t h e GATT EVENT QUERY COMPLETE e v e n t , which marks t h e
end o f read .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param n u m v a l u e h a n d l e s
∗ @param v a l u e h a n d l e s l i s t o f h a n d l e s
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
∗ ERROR CODE SUCCESS , i f query i s
successfully registered
∗/
uint8 t g a t t c l i e n t r e a d m u l t i p l e v a r i a b l e c h a r a c t e r i s t i c v a l u e s (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
int n u m v a l u e h a n d l e s , uint16 t ∗ v a l u e h a n d l e s ) ;
/∗ ∗
∗ @ b r i e f Writes t h e c h a r a c t e r i s t i c v a l u e u s i n g t h e c h a r a c t e r i s t i c ’ s
value handle without
∗ an acknowledgment t h a t t h e w r i t e was s u c c e s s f u l l y performed .
∗ @param c o n h a n d l e
∗ @param v a l u e h a n d l e
∗ @param v a l u e l e n g t h
∗ @param v a l u e i s c o p i e d on s u c c e s s and d o e s not need t o be
retained
∗ @return s t a t u s BTSTACK MEMORY ALLOC FAILED, i f no GATT c l i e n t f o r
c o n h a n d l e i s found
∗ GATT CLIENT IN WRONG STATE , i f GATT c l i e n t i s not
ready
∗ BTSTACK ACL BUFFERS FULL , i f L2CAP cannot send ,
t h e r e a r e no f r e e ACL s l o t s
∗ ERROR CODE SUCCESS , i f query i s
successfully registered
∗/
uint8 t g a t t c l i e n t w r i t e v a l u e o f c h a r a c t e r i s t i c w i t h o u t r e s p o n s e (
h c i c o n h a n d l e t c o n h a n d l e , uint16 t v a l u e h a n d l e , uint16 t
v a l u e l e n g t h , uint8 t ∗ v a l u e ) ;
/∗ ∗
∗ @ b r i e f Writes t h e a u t h e n t i c a t e d c h a r a c t e r i s t i c v a l u e u s i n g t h e
c h a r a c t e r i s t i c ’ s value handle
∗ w i t h o u t an acknowledgment t h a t t h e w r i t e was s u c c e s s f u l l y
performed .
321
/∗ ∗
∗ @ b r i e f Writes t h e c h a r a c t e r i s t i c v a l u e u s i n g t h e c h a r a c t e r i s t i c ’ s
value handle .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f w r i t e .
∗ The w r i t e i s s u c c e s s f u l l y performed , i f t h e e v e n t ’ s a t t s t a t u s
f i e l d i s set to
∗ ATT ERROR SUCCESS ( s e e b l u e t o o t h . h f o r ATT ERROR c o d e s ) .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param v a l u e h a n d l e
∗ @param v a l u e l e n g t h
∗ @param v a l u e i s not c o p i e d , make s u r e memory i s a c c e s s i b l e u n t i l
w r i t e i s done , i . e . GATT EVENT QUERY COMPLETE i s r e c e i v e d
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER
i f no HCI c o n n e c t i o n f o r c o n h a n d l e i s found
∗ BTSTACK MEMORY ALLOC FAILED
i f no GATT c l i e n t f o r c o n h a n d l e
c o u l d be a l l o c a t e d
∗ GATT CLIENT IN WRONG STATE
i f GATT c l i e n t i s not r e a d y
∗ ERROR CODE SUCCESS
i f query i s s u c c e s s f u l l y
registered
∗/
uint8 t g a t t c l i e n t w r i t e v a l u e o f c h a r a c t e r i s t i c (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t v a l u e h a n d l e , uint16 t v a l u e l e n g t h , uint8 t ∗ v a l u e ) ;
/∗ ∗
322
∗ @ b r i e f Writes t h e c h a r a c t e r i s t i c v a l u e u s i n g t h e c h a r a c t e r i s t i c ’ s
value handle .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f w r i t e .
∗ The w r i t e i s s u c c e s s f u l l y performed i f t h e e v e n t ’ s a t t s t a t u s
f i e l d i s s e t t o ATT ERROR SUCCESS ( s e e b l u e t o o t h . h f o r
ATT ERROR c o d e s ) .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param v a l u e h a n d l e
∗ @param v a l u e l e n g t h
∗ @param v a l u e i s not c o p i e d , make s u r e memory i s a c c e s s i b l e u n t i l
w r i t e i s done , i . e . GATT EVENT QUERY COMPLETE i s r e c e i v e d
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER
i f no HCI c o n n e c t i o n f o r c o n h a n d l e i s found
∗ BTSTACK MEMORY ALLOC FAILED
i f no GATT c l i e n t f o r c o n h a n d l e
c o u l d be a l l o c a t e d
∗ GATT CLIENT IN WRONG STATE
i f GATT c l i e n t i s not r e a d y
∗ ERROR CODE SUCCESS
i f query i s s u c c e s s f u l l y
registered
∗/
uint8 t g a t t c l i e n t w r i t e l o n g v a l u e o f c h a r a c t e r i s t i c (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t v a l u e h a n d l e , uint16 t v a l u e l e n g t h , uint8 t ∗ v a l u e ) ;
/∗ ∗
∗ @ b r i e f Writes t h e c h a r a c t e r i s t i c v a l u e u s i n g t h e c h a r a c t e r i s t i c ’ s
value handle .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f w r i t e .
∗ The w r i t e i s s u c c e s s f u l l y performed i f t h e e v e n t ’ s a t t s t a t u s
f i e l d i s s e t t o ATT ERROR SUCCESS ( s e e b l u e t o o t h . h f o r
ATT ERROR c o d e s ) .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param v a l u e h a n d l e
∗ @param o f f s e t o f v a l u e
∗ @param v a l u e l e n g t h
∗ @param v a l u e i s not c o p i e d , make s u r e memory i s a c c e s s i b l e u n t i l
w r i t e i s done , i . e . GATT EVENT QUERY COMPLETE i s r e c e i v e d
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER
i f no HCI c o n n e c t i o n f o r c o n h a n d l e i s found
∗ BTSTACK MEMORY ALLOC FAILED
i f no GATT c l i e n t f o r c o n h a n d l e
c o u l d be a l l o c a t e d
∗ GATT CLIENT IN WRONG STATE
i f GATT c l i e n t i s not r e a d y
∗ ERROR CODE SUCCESS
i f query i s s u c c e s s f u l l y
registered
∗/
323
uint8 t g a t t c l i e n t w r i t e l o n g v a l u e o f c h a r a c t e r i s t i c w i t h o f f s e t (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t v a l u e h a n d l e , uint16 t o f f s e t , uint16 t v a l u e l e n g t h ,
uint8 t ∗ v a l u e ) ;
/∗ ∗
∗ @ b r i e f Writes o f t h e l o n g c h a r a c t e r i s t i c v a l u e u s i n g t h e
c h a r a c t e r i s t i c ’ s value handle .
∗ I t u s e s s e r v e r r e s p o n s e t o v a l i d a t e t h a t t h e w r i t e was c o r r e c t l y
received .
∗ The GATT EVENT QUERY COMPLETE EVENT marks t h e end o f w r i t e .
∗ The w r i t e i s s u c c e s s f u l l y performed , i f t h e e v e n t ’ s a t t s t a t u s
f i e l d i s s e t t o ATT ERROR SUCCESS ( s e e b l u e t o o t h . h f o r
ATT ERROR c o d e s ) .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param v a l u e h a n d l e
∗ @param v a l u e l e n g t h
∗ @param v a l u e i s not c o p i e d , make s u r e memory i s a c c e s s i b l e u n t i l
w r i t e i s done , i . e . GATT EVENT QUERY COMPLETE i s r e c e i v e d
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER
i f no HCI c o n n e c t i o n f o r c o n h a n d l e i s found
∗ BTSTACK MEMORY ALLOC FAILED
i f no GATT c l i e n t f o r c o n h a n d l e
c o u l d be a l l o c a t e d
∗ GATT CLIENT IN WRONG STATE
i f GATT c l i e n t i s not r e a d y
∗ ERROR CODE SUCCESS
i f query i s s u c c e s s f u l l y
registered
∗/
uint8 t g a t t c l i e n t r e l i a b l e w r i t e l o n g v a l u e o f c h a r a c t e r i s t i c (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t v a l u e h a n d l e , uint16 t v a l u e l e n g t h , uint8 t ∗ v a l u e ) ;
/∗ ∗
∗ @ b r i e f Reads t h e c h a r a c t e r i s t i c d e s c r i p t o r u s i n g i t s h a n d l e .
∗ I f t h e c h a r a c t e r i s t i c d e s c r i p t o r i s found , a
GATT EVENT CHARACTERISTIC DESCRIPTOR QUERY RESULT e v e n t w i l l be
emitted .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f rea d .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param d e s c r i p t o r
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER
i f no HCI c o n n e c t i o n f o r c o n h a n d l e i s found
∗ BTSTACK MEMORY ALLOC FAILED
i f no GATT c l i e n t f o r c o n h a n d l e
c o u l d be a l l o c a t e d
∗ GATT CLIENT IN WRONG STATE
i f GATT c l i e n t i s not r e a d y
∗ ERROR CODE SUCCESS
i f query i s s u c c e s s f u l l y
registered
324
∗/
uint8 t g a t t c l i e n t r e a d c h a r a c t e r i s t i c d e s c r i p t o r (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
gatt client characteristic descriptor t ∗ descriptor ) ;
/∗ ∗
∗ @ b r i e f Reads t h e c h a r a c t e r i s t i c d e s c r i p t o r u s i n g i t s h a n d l e .
∗ I f t h e c h a r a c t e r i s t i c d e s c r i p t o r i s found , a
GATT EVENT CHARACTERISTIC DESCRIPTOR QUERY RESULT e v e n t w i l l be
emitted .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f rea d .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param d e s c r i p t o r
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER
i f no HCI c o n n e c t i o n f o r c o n h a n d l e i s found
∗ BTSTACK MEMORY ALLOC FAILED
i f no GATT c l i e n t f o r c o n h a n d l e
c o u l d be a l l o c a t e d
∗ GATT CLIENT IN WRONG STATE
i f GATT c l i e n t i s not r e a d y
∗ ERROR CODE SUCCESS
i f query i s s u c c e s s f u l l y
registered
∗/
uint8 t
gatt client read characteristic descriptor using descriptor handle
( btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t d e s c r i p t o r h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Reads t h e l o n g c h a r a c t e r i s t i c d e s c r i p t o r u s i n g i t s h a n d l e .
I t w i l l be r e t u r n e d i n s e v e r a l b l o b s .
∗ For each b l o b , a
GATT EVENT CHARACTERISTIC DESCRIPTOR QUERY RESULT e v e n t w i l l be
emitted .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f rea d .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param d e s c r i p t o r
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER
i f no HCI c o n n e c t i o n f o r c o n h a n d l e i s found
∗ BTSTACK MEMORY ALLOC FAILED
i f no GATT c l i e n t f o r c o n h a n d l e
c o u l d be a l l o c a t e d
∗ GATT CLIENT IN WRONG STATE
i f GATT c l i e n t i s not r e a d y
∗ ERROR CODE SUCCESS
i f query i s s u c c e s s f u l l y
registered
∗/
uint8 t g a t t c l i e n t r e a d l o n g c h a r a c t e r i s t i c d e s c r i p t o r (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
gatt client characteristic descriptor t ∗ descriptor ) ;
325
/∗ ∗
∗ @ b r i e f Reads t h e l o n g c h a r a c t e r i s t i c d e s c r i p t o r u s i n g i t s h a n d l e .
I t w i l l be r e t u r n e d i n s e v e r a l b l o b s .
∗ For each b l o b , a
GATT EVENT CHARACTERISTIC DESCRIPTOR QUERY RESULT e v e n t w i l l be
emitted .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f rea d .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param d e s c r i p t o r h a n d l e
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER
i f no HCI c o n n e c t i o n f o r c o n h a n d l e i s found
∗ BTSTACK MEMORY ALLOC FAILED
i f no GATT c l i e n t f o r c o n h a n d l e
c o u l d be a l l o c a t e d
∗ GATT CLIENT IN WRONG STATE
i f GATT c l i e n t i s not r e a d y
∗ ERROR CODE SUCCESS
i f query i s s u c c e s s f u l l y
registered
∗/
uint8 t
gatt client read long characteristic descriptor using descriptor handle
( btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t d e s c r i p t o r h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Reads t h e l o n g c h a r a c t e r i s t i c d e s c r i p t o r u s i n g i t s h a n d l e .
I t w i l l be r e t u r n e d i n s e v e r a l b l o b s .
∗ For each b l o b , a
GATT EVENT CHARACTERISTIC DESCRIPTOR QUERY RESULT e v e n t w i l l be
emitted .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f rea d .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param d e s c r i p t o r h a n d l e
∗ @param o f f s e t
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER
i f no HCI c o n n e c t i o n f o r c o n h a n d l e i s found
∗ BTSTACK MEMORY ALLOC FAILED
i f no GATT c l i e n t f o r c o n h a n d l e
c o u l d be a l l o c a t e d
∗ GATT CLIENT IN WRONG STATE
i f GATT c l i e n t i s not r e a d y
∗ ERROR CODE SUCCESS
i f query i s s u c c e s s f u l l y
registered
∗/
uint8 t
gatt client read long characteristic descriptor using descriptor handle with offs
( btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t d e s c r i p t o r h a n d l e , uint16 t o f f s e t ) ;
326
/∗ ∗
∗ @ b r i e f Writes t h e c h a r a c t e r i s t i c d e s c r i p t o r u s i n g i t s h a n d l e .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f w r i t e .
∗ The w r i t e i s s u c c e s s f u l l y performed i f t h e e v e n t ’ s a t t s t a t u s
f i e l d i s s e t t o ATT ERROR SUCCESS ( s e e b l u e t o o t h . h f o r
ATT ERROR c o d e s ) .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param d e s c r i p t o r
∗ @param v a l u e l e n g t h
∗ @param v a l u e i s not c o p i e d , make s u r e memory i s a c c e s s i b l e u n t i l
w r i t e i s done , i . e . GATT EVENT QUERY COMPLETE i s r e c e i v e d
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER
i f no HCI c o n n e c t i o n f o r c o n h a n d l e i s found
∗ BTSTACK MEMORY ALLOC FAILED
i f no GATT c l i e n t f o r c o n h a n d l e
c o u l d be a l l o c a t e d
∗ GATT CLIENT IN WRONG STATE
i f GATT c l i e n t i s not r e a d y
∗ ERROR CODE SUCCESS
i f query i s s u c c e s s f u l l y
registered
∗/
uint8 t g a t t c l i e n t w r i t e c h a r a c t e r i s t i c d e s c r i p t o r (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
g a t t c l i e n t c h a r a c t e r i s t i c d e s c r i p t o r t ∗ d e s c r i p t o r , uint16 t
v a l u e l e n g t h , uint8 t ∗ v a l u e ) ;
/∗ ∗
∗ @ b r i e f Writes t h e c h a r a c t e r i s t i c d e s c r i p t o r u s i n g i t s h a n d l e .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f w r i t e .
∗ The w r i t e i s s u c c e s s f u l l y performed i f t h e e v e n t ’ s a t t s t a t u s
f i e l d i s s e t t o ATT ERROR SUCCESS ( s e e b l u e t o o t h . h f o r
ATT ERROR c o d e s ) .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param d e s c r i p t o r h a n d l e
∗ @param v a l u e l e n g t h
∗ @param v a l u e i s not c o p i e d , make s u r e memory i s a c c e s s i b l e u n t i l
w r i t e i s done , i . e . GATT EVENT QUERY COMPLETE i s r e c e i v e d
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER
i f no HCI c o n n e c t i o n f o r c o n h a n d l e i s found
∗ BTSTACK MEMORY ALLOC FAILED
i f no GATT c l i e n t f o r c o n h a n d l e
c o u l d be a l l o c a t e d
∗ GATT CLIENT IN WRONG STATE
i f GATT c l i e n t i s not r e a d y
∗ ERROR CODE SUCCESS
i f query i s s u c c e s s f u l l y
registered
∗/
327
uint8 t
gatt client write characteristic descriptor using descriptor handle
( btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t d e s c r i p t o r h a n d l e , uint16 t v a l u e l e n g t h , uint8 t ∗
value ) ;
/∗ ∗
∗ @ b r i e f Writes t h e c h a r a c t e r i s t i c d e s c r i p t o r u s i n g i t s h a n d l e .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f w r i t e .
∗ The w r i t e i s s u c c e s s f u l l y performed i f t h e e v e n t ’ s a t t s t a t u s
f i e l d i s s e t t o ATT ERROR SUCCESS ( s e e b l u e t o o t h . h f o r
ATT ERROR c o d e s ) .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param d e s c r i p t o r
∗ @param v a l u e l e n g t h
∗ @param v a l u e i s not c o p i e d , make s u r e memory i s a c c e s s i b l e u n t i l
w r i t e i s done , i . e . GATT EVENT QUERY COMPLETE i s r e c e i v e d
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER
i f no HCI c o n n e c t i o n f o r c o n h a n d l e i s found
∗ BTSTACK MEMORY ALLOC FAILED
i f no GATT c l i e n t f o r c o n h a n d l e
c o u l d be a l l o c a t e d
∗ GATT CLIENT IN WRONG STATE
i f GATT c l i e n t i s not r e a d y
∗ ERROR CODE SUCCESS
i f query i s s u c c e s s f u l l y
registered
∗/
uint8 t g a t t c l i e n t w r i t e l o n g c h a r a c t e r i s t i c d e s c r i p t o r (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
g a t t c l i e n t c h a r a c t e r i s t i c d e s c r i p t o r t ∗ d e s c r i p t o r , uint16 t
v a l u e l e n g t h , uint8 t ∗ v a l u e ) ;
/∗ ∗
∗ @ b r i e f Writes t h e c h a r a c t e r i s t i c d e s c r i p t o r u s i n g i t s h a n d l e .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f w r i t e .
∗ The w r i t e i s s u c c e s s f u l l y performed i f t h e e v e n t ’ s a t t s t a t u s
f i e l d i s s e t t o ATT ERROR SUCCESS ( s e e b l u e t o o t h . h f o r
ATT ERROR c o d e s ) .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param d e s c r i p t o r h a n d l e
∗ @param v a l u e l e n g t h
∗ @param v a l u e i s not c o p i e d , make s u r e memory i s a c c e s s i b l e u n t i l
w r i t e i s done , i . e . GATT EVENT QUERY COMPLETE i s r e c e i v e d
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER
i f no HCI c o n n e c t i o n f o r c o n h a n d l e i s found
∗ BTSTACK MEMORY ALLOC FAILED
i f no GATT c l i e n t f o r c o n h a n d l e
c o u l d be a l l o c a t e d
∗ GATT CLIENT IN WRONG STATE
i f GATT c l i e n t i s not r e a d y
328
/∗ ∗
∗ @ b r i e f Writes t h e c h a r a c t e r i s t i c d e s c r i p t o r u s i n g i t s h a n d l e .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f w r i t e .
∗ The w r i t e i s s u c c e s s f u l l y performed i f t h e e v e n t ’ s a t t s t a t u s
f i e l d i s s e t t o ATT ERROR SUCCESS ( s e e b l u e t o o t h . h f o r
ATT ERROR c o d e s ) .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param d e s c r i p t o r h a n d l e
∗ @param o f f s e t o f v a l u e
∗ @param v a l u e l e n g t h
∗ @param v a l u e i s not c o p i e d , make s u r e memory i s a c c e s s i b l e u n t i l
w r i t e i s done , i . e . GATT EVENT QUERY COMPLETE i s r e c e i v e d
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER
i f no HCI c o n n e c t i o n f o r c o n h a n d l e i s found
∗ BTSTACK MEMORY ALLOC FAILED
i f no GATT c l i e n t f o r c o n h a n d l e
c o u l d be a l l o c a t e d
∗ GATT CLIENT IN WRONG STATE
i f GATT c l i e n t i s not r e a d y
∗ ERROR CODE SUCCESS
i f query i s s u c c e s s f u l l y
registered
∗/
uint8 t
gatt client write long characteristic descriptor using descriptor handle with off
( btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t d e s c r i p t o r h a n d l e , uint16 t o f f s e t , uint16 t
v a l u e l e n g t h , uint8 t ∗ v a l u e ) ;
/∗ ∗
∗ @ b r i e f Writes t h e c l i e n t c h a r a c t e r i s t i c c o n f i g u r a t i o n o f t h e
specified characteristic .
∗ I t i s used t o s u b s c r i b e f o r n o t i f i c a t i o n s or i n d i c a t i o n s o f t h e
characteristic value .
∗ For n o t i f i c a t i o n s or i n d i c a t i o n s s p e c i f y :
GATT CLIENT CHARACTERISTICS CONFIGURATION NOTIFICATION
∗ r e s p . GATT CLIENT CHARACTERISTICS CONFIGURATION INDICATION as
configuration value .
∗ The GATT EVENT QUERY COMPLETE e v e n t marks t h e end o f w r i t e .
∗ The w r i t e i s s u c c e s s f u l l y performed i f t h e e v e n t ’ s a t t s t a t u s
f i e l d i s s e t t o ATT ERROR SUCCESS ( s e e b l u e t o o t h . h f o r
ATT ERROR c o d e s ) .
∗ @param c a l l b a c k
329
/∗ ∗
∗ @ b r i e f R e g i s t e r f o r n o t i f i c a t i o n s and i n d i c a t i o n s o f a
c h a r a c t e r i s t i c e n a b l e d by
∗ the g a t t c l i e n t w r i t e c l i e n t c h a r a c t e r i s t i c c o n f i g u r a t i o n
function .
∗ @param n o t i f i c a t i o n s t r u c t used t o s t o r e r e g i s t r a t i o n
∗ @param c a l l b a c k
∗ @param c o n h a n d l e or GATT CLIENT ANY CONNECTION t o r e c e i v e
u p d a t e s from a l l c o n n e c t e d d e v i c e s
∗ @param c h a r a c t e r i s t i c or NULL t o r e c e i v e u p d a t e s f o r a l l
characteristics
∗/
void g a t t c l i e n t l i s t e n f o r c h a r a c t e r i s t i c v a l u e u p d a t e s (
gatt client notification t ∗ notification ,
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ,
gatt client characteristic t ∗ c h a r a c t e r i s t i c ) ;
/∗ ∗
∗ @ b r i e f Stop l i s t e n i n g t o c h a r a c t e r i s t i c v a l u e u p d a t e s r e g i s t e r e d
with
∗ the g a t t c l i e n t l i s t e n f o r c h a r a c t e r i s t i c v a l u e u p d a t e s function .
330
∗ @param n o t i f i c a t i o n s t r u c t used i n
gatt client listen for characteristic value updates
∗/
void g a t t c l i e n t s t o p l i s t e n i n g f o r c h a r a c t e r i s t i c v a l u e u p d a t e s (
gatt client notification t ∗ notification ) ;
/∗ ∗
∗ @ b r i e f T r a n s a c t i o n a l w r i t e . I t can be c a l l e d as many t i m e s as i t
i s needed t o w r i t e t h e c h a r a c t e r i s t i c s w i t h i n t h e same
transaction .
∗ C a l l t h e g a t t c l i e n t e x e c u t e w r i t e f u n c t i o n t o commit t h e
transaction .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @param a t t r i b u t e h a n d l e
∗ @param o f f s e t o f v a l u e
∗ @param v a l u e l e n g t h
∗ @param v a l u e i s not c o p i e d , make s u r e memory i s a c c e s s i b l e u n t i l
w r i t e i s done , i . e . GATT EVENT QUERY COMPLETE i s r e c e i v e d
∗/
uint8 t g a t t c l i e n t p r e p a r e w r i t e ( btstack packet handler t c a l l b a c k ,
h c i c o n h a n d l e t c o n h a n d l e , uint16 t a t t r i b u t e h a n d l e ,
uint16 t o f f s e t , uint16 t v a l u e l e n g t h , uint8 t ∗ v a l u e ) ;
/∗ ∗
∗ @ b r i e f Commit t r a n s a c t i o n a l w r i t e . GATT EVENT QUERY COMPLETE i s
received .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @return s t a t u s
∗/
uint8 t g a t t c l i e n t e x e c u t e w r i t e ( btstack packet handler t c a l l b a c k ,
hci con handle t con handle ) ;
/∗ ∗
∗ @ b r i e f Abort t r a n s a c t i o n a l w r i t e . GATT EVENT QUERY COMPLETE i s
received .
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @return s t a t u s
∗/
uint8 t g a t t c l i e n t c a n c e l w r i t e ( btstack packet handler t c a l l b a c k ,
hci con handle t con handle ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t c a l l b a c k when r e g u l a r g a t t q u e r y can be s e n t
∗ @note c a l l b a c k might happen d u r i n g c a l l t o t h i s f u n c t i o n
∗ @param c a l l b a c k r e g i s t r a t i o n t o p o i n t t o c a l l b a c k f u n c t i o n and
context information
∗ @param c o n h a n d l e
∗ @return ERROR CODE SUCCESS i f ok ,
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f h a n d l e unknown , and
ERROR CODE COMMAND DISALLOWED i f c a l l b a c k a l r e a d y r e g i s t e r e d
∗/
331
uint8 t g a t t c l i e n t r e q u e s t t o s e n d g a t t q u e r y (
btstack context callback registration t ∗ callback registration ,
hci con handle t con handle ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t c a l l b a c k when w r i t i n g c h a r a c t e r i s t i c v a l u e w i t h o u t
response i s p o s s i b l e
∗ @note c a l l b a c k might happen d u r i n g c a l l t o t h i s f u n c t i o n
∗ @param c a l l b a c k r e g i s t r a t i o n t o p o i n t t o c a l l b a c k f u n c t i o n and
context information
∗ @param c o n h a n d l e
∗ @return ERROR CODE SUCCESS i f ok ,
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f h a n d l e unknown , and
ERROR CODE COMMAND DISALLOWED i f c a l l b a c k a l r e a d y r e g i s t e r e d
∗/
uint8 t g a t t c l i e n t r e q u e s t t o w r i t e w i t h o u t r e s p o n s e (
btstack context callback registration t ∗ callback registration ,
hci con handle t con handle ) ;
// t h e f o l l o w i n g f u n c t i o n s a r e marked as d e p r e c a t e d and w i l l be
removed e v e n t u a l l y
/∗ ∗
∗ @ b r i e f R e q u e s t s GATT EVENT CAN WRITE WITHOUT RESPONSE t h a t
guarantees
∗ a single successful
gatt client write value of characteristic without response call
.
∗ @ de pr e ca te d p l e a s e use
gatt client request to write without response instead
∗ @param c a l l b a c k
∗ @param c o n h a n d l e
∗ @return s t a t u s
∗/
uint8 t g a t t c l i e n t r e q u e s t c a n w r i t e w i t h o u t r e s p o n s e e v e n t (
btstack packet handler t c a l l b a c k , h c i c o n h a n d l e t c o n h a n d l e ) ;
/∗ ∗
∗ @brief i n i t
∗/
void l e d e v i c e d b i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f s e t s l o c a l bd addr . a l l o w s f o r db p e r B l u e t o o t h c o n t r o l l e r
∗ @param b d a d d r
∗/
void l e d e v i c e d b s e t l o c a l b d a d d r ( bd addr t bd addr ) ;
/∗ ∗
332
∗ @ b r i e f add d e v i c e t o db
∗ @param a d d r t y p e , a d d r e s s o f t h e d e v i c e
∗ @param i r k o f t h e d e v i c e
∗ @return i n d e x i f s u c c e s s f u l , −1 o t h e r w i s e
∗/
int l e d e v i c e d b a d d ( int a d d r t y p e , bd addr t addr , s m k e y t i r k ) ;
/∗ ∗
∗ @ b r i e f g e t number o f d e v i c e s i n db
∗ @return number o f d e v i c e i n db
∗/
int l e d e v i c e d b c o u n t ( void ) ;
/∗ ∗
∗ @ b r i e f g e t max number o f d e v i c e s i n db f o r enumeration
∗ @return max number o f d e v i c e i n db
∗/
int l e d e v i c e d b m a x c o u n t ( void ) ;
/∗ ∗
∗ @ b r i e f g e t d e v i c e i n f o r m a t i o n : addr t y p e and a d d r e s s needed t o
identify device
∗ @param i n d e x
∗ @param a d d r t y p e , a d d r e s s o f t h e d e v i c e as o u t p u t
∗ @param i r k o f t h e d e v i c e
∗/
void l e d e v i c e d b i n f o ( int index , int ∗ a d d r t y p e , bd addr t addr ,
sm key t i r k ) ;
/∗ ∗
∗ @ b r i e f s e t remote e n c r y p t i o n i n f o
∗ @brief index
∗ @brief ediv
∗ @ b r i e f rand
∗ @brief l t k
∗ @ b r i e f key s i z e
∗ @brief authenticated
∗ @brief authorized
∗ @breif secure connection
∗/
void l e d e v i c e d b e n c r y p t i o n s e t ( int index , uint16 t ediv , uint8 t
rand [ 8 ] , s m k e y t l t k , int k e y s i z e , int a u t h e n t i c a t e d , int
a u t h o r i z e d , int s e c u r e c o n n e c t i o n ) ;
/∗ ∗
∗ @brief g e t remote e n c r y p t i o n i n f o
∗ @brief index
∗ @brief ediv
∗ @brief rand
∗ @brief ltk
∗ @brief key s i z e
∗ @brief authenticated
∗ @brief authorized
333
/∗ ∗
∗ @ b r i e f s e t l o c a l s i g n i n g key f o r t h i s d e v i c e
∗ @param i n d e x
∗ @param s i g n i n g key as i n p u t
∗/
void l e d e v i c e d b l o c a l c s r k s e t ( int index , s m k e y t c s r k ) ;
/∗ ∗
∗ @ b r i e f g e t l o c a l s i g n i n g key f o r t h i s d e v i c e
∗ @param i n d e x
∗ @param s i g n i n g key as o u t p u t
∗/
void l e d e v i c e d b l o c a l c s r k g e t ( int index , s m k e y t c s r k ) ;
/∗ ∗
∗ @ b r i e f s e t remote s i g n i n g key f o r t h i s d e v i c e
∗ @param i n d e x
∗ @param s i g n i n g key as i n p u t
∗/
void l e d e v i c e d b r e m o t e c s r k s e t ( int index , s m k e y t c s r k ) ;
/∗ ∗
∗ @ b r i e f g e t remote s i g n i n g key f o r t h i s d e v i c e
∗ @param i n d e x
∗ @param s i g n i n g key as o u t p u t
∗/
void l e d e v i c e d b r e m o t e c s r k g e t ( int index , s m k e y t c s r k ) ;
/∗ ∗
∗ @ b r i e f q u e r y l a s t used / s e e n s i g n i n g c o u n t e r
∗ @param i n d e x
∗ @return n e x t e x p e c t e d c o u n t e r , 0 a f t e r d e v i c e s was added
∗/
uint32 t l e d e v i c e d b r e m o t e c o u n t e r g e t ( int i n d e x ) ;
/∗ ∗
∗ @brief update s i g n i n g counter
∗ @param i n d e x
∗ @param c o u n t e r t o s t o r e
∗/
void l e d e v i c e d b r e m o t e c o u n t e r s e t ( int index , uint32 t c o u n t e r ) ;
/∗ ∗
∗ @ b r i e f q u e r y l a s t used / s e e n s i g n i n g c o u n t e r
∗ @param i n d e x
∗ @return n e x t e x p e c t e d c o u n t e r , 0 a f t e r d e v i c e s was added
334
∗/
uint32 t l e d e v i c e d b l o c a l c o u n t e r g e t ( int i n d e x ) ;
/∗ ∗
∗ @brief update s i g n i n g counter
∗ @param i n d e x
∗ @param c o u n t e r t o s t o r e
∗/
void l e d e v i c e d b l o c a l c o u n t e r s e t ( int index , uint32 t c o u n t e r ) ;
#endif
/∗ ∗
∗ @brief free device
∗ @param i n d e x
∗/
void l e d e v i c e d b r e m o v e ( int i n d e x ) ;
void l e d e v i c e d b d u m p ( void ) ;
/∗ ∗
∗ @ b r i e f c o n f i g u r e l e d e v i c e db f o r use w i t h b t s t a c k t l v i n s t a n c e
∗ @param b t s t a c k t l v i m p l t o use
∗ @param b t s t a c k t l v c o n t e x t
∗/
void l e d e v i c e d b t l v c o n f i g u r e ( const b t s t a c k t l v t ∗
b t s t a c k t l v i m p l , void ∗ b t s t a c k t l v c o n t e x t ) ;
/∗ ∗
∗ @ b r i e f I n i t i a l i z e s t h e S e c u r i t y Manager , c o n n e c t s t o L2CAP
∗/
void s m i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f S e t s e c r e t ER key f o r key g e n e r a t i o n as d e s c r i b e d i n Core
V4 . 0 , Vol 3 , Part G, 5 . 2 . 2
∗ @note I f not s e t and b t s t a c k t l v i s c o n f i g u r e d , ER key i s
g e n e r a t e d and s t o r e d i n TLV by SM
∗ @param e r key
∗/
void s m s e t e r ( s m k e y t e r ) ;
/∗ ∗
∗ @ b r i e f S e t s e c r e t IR key f o r key g e n e r a t i o n as d e s c r i b e d i n Core
V4 . 0 , Vol 3 , Part G, 5 . 2 . 2
335
/∗ ∗
∗ @ b r i e f R e g i s t e r s OOB Data C a l l b a c k . The c a l l b a c k s h o u l d s e t t h e
o o b d a t a and r e t u r n 1 i f OOB d a t a i s a v a i l b l e
∗ @param g e t o o b d a t a c a l l b a c k
∗/
void s m r e g i s t e r o o b d a t a c a l l b a c k ( int ( ∗ g e t o o b d a t a c a l l b a c k ) (
uint8 t a d d r e s s t y p e , bd addr t addr , uint8 t ∗ o o b d a t a ) ) ;
/∗ ∗
∗ @ b r i e f Add e v e n t p a c k e t h a n d l e r .
∗ @param c a l l b a c k h a n d l e r
∗/
void s m a d d e v e n t h a n d l e r ( b t s t a c k p a c k e t c a l l b a c k r e g i s t r a t i o n t ∗
callback handler ) ;
/∗ ∗
∗ @ b r i e f Remove e v e n t p a c k e t h a n d l e r .
∗ @param c a l l b a c k h a n d l e r
∗/
void s m r e m o v e e v e n t h a n d l e r ( b t s t a c k p a c k e t c a l l b a c k r e g i s t r a t i o n t
∗ callback handler ) ;
/∗ ∗
∗ @ b r i e f L i m i t t h e STK g e n e r a t i o n methods . Bonding i s s t o p p e d i f
t h e r e s u l t i n g one i s n ’ t i n t h e l i s t
∗ @param OR c o m b i n a t i o n o f SM STK GENERATION METHOD
∗/
void s m s e t a c c e p t e d s t k g e n e r a t i o n m e t h o d s ( uint8 t
accepted stk generation methods ) ;
/∗ ∗
∗ @ b r i e f S e t t h e a c c e p t e d e n c r y p t i o n key s i z e range . Bonding i s
s t o p p e d i f t h e r e s u l t i s n ’ t w i t h i n t h e range
∗ @param m i n s i z e ( d e f a u l t 7)
∗ @param m a x s i z e ( d e f a u l t 16)
∗/
void s m s e t e n c r y p t i o n k e y s i z e r a n g e ( uint8 t m i n s i z e , uint8 t
max size ) ;
/∗ ∗
∗ @brief Sets the r e q u e s t e d a u t h e n t i c a t i o n requirements , bonding
y e s /no , MITM y e s /no , SC y e s /no , k e y p r e s s y e s /no
∗ @param OR c o m b i n a t i o n o f SM AUTHREQ f l a g s
∗/
void s m s e t a u t h e n t i c a t i o n r e q u i r e m e n t s ( uint8 t a u t h r e q ) ;
/∗ ∗
∗ @ b r i e f S e t s t h e a v a i l a b l e IO C a p a b i l i t i e s
336
∗ @param IO CAPABILITY
∗/
void s m s e t i o c a p a b i l i t i e s ( i o c a p a b i l i t y t i o c a p a b i l i t y ) ;
/∗ ∗
∗ @ b r i e f Enable / d i s a b l e S e c u r e C o n n e c t i o n s Mode o n l y
∗ @param e n a b l e s e c u r e c o n n e c t i o n s o n l y mode
∗/
void s m s e t s e c u r e c o n n e c t i o n s o n l y m o d e ( b o o l e n a b l e ) ;
/∗ ∗
∗ @ b r i e f Let P e r i p h e r a l r e q u e s t an e n c r y p t e d c o n n e c t i o n r i g h t a f t e r
connecting
∗ @param e n a b l e
∗ @note Not used n o r m a l l y . Bonding i s t r i g g e r e d by a c c e s s t o
p r o t e c t e d a t t r i b u t e s i n ATT S e r v e r
∗/
void s m s e t r e q u e s t s e c u r i t y ( b o o l e n a b l e ) ;
/∗ ∗
∗ @brief Trigger S e c u r i t y Request
∗ @ de pr e ca te d p l e a s e use s m r e q u e s t p a i r i n g i n s t e a d
∗/
void s m s e n d s e c u r i t y r e q u e s t ( h c i c o n h a n d l e t c o n h a n d l e ) ;
/∗ ∗
∗ @ b r i e f D e c l i n e b o n d i n g t r i g g e r e d by e v e n t b e f o r e
∗ @param c o n h a n d l e
∗/
void s m b o n d i n g d e c l i n e ( h c i c o n h a n d l e t c o n h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Confirm J u s t Works b o n d i n g
∗ @param c o n h a n d l e
∗/
void s m j u s t w o r k s c o n f i r m ( h c i c o n h a n d l e t c o n h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Confirm v a l u e from SM EVENT NUMERIC COMPARISON REQUEST f o r
Numeric Comparison b o n d i n g
∗ @param c o n h a n d l e
∗/
void s m n u m e r i c c o m p a r i s o n c o n f i r m ( h c i c o n h a n d l e t c o n h a n d l e ) ;
/∗ ∗
∗ @ b r i e f R e p o r t s p a s s k e y i n p u t by u s e r
∗ @param c o n h a n d l e
∗ @param p a s s k e y i n [ 0 . . 9 9 9 9 9 9 ]
∗/
void s m p a s s k e y i n p u t ( h c i c o n h a n d l e t c o n h a n d l e , uint32 t p a s s k e y )
;
/∗ ∗
∗ @ b r i e f Send k e y p r e s s n o t i f i c a t i o n f o r k e y b o a r d o n l y d e v i c e s
337
∗ @param c o n h a n d l e
∗ @param a c t i o n s e e SM KEYPRESS ∗ i n b l u e t o o t h . h
∗/
void s m k e y p r e s s n o t i f i c a t i o n ( h c i c o n h a n d l e t c o n h a n d l e , uint8 t
action ) ;
/∗ ∗
∗ @ b r i e f Used by a t t s e r v e r . c and g a t t c l i e n t . c t o r e q u e s t u s e r
authentication
∗ @param c o n h a n d l e
∗/
void s m r e q u e s t p a i r i n g ( h c i c o n h a n d l e t c o n h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Report u s e r a u t h o r i z a t i o n d e c l i n e .
∗ @param c o n h a n d l e
∗/
void s m a u t h o r i z a t i o n d e c l i n e ( h c i c o n h a n d l e t c o n h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Report u s e r a u t h o r i z a t i o n g r a n t .
∗ @param c o n h a n d l e
∗/
void s m a u t h o r i z a t i o n g r a n t ( h c i c o n h a n d l e t c o n h a n d l e ) ;
/∗ ∗
∗ @ b r i e f S u p p o r t f o r s i g n e d w r i t e s , used by a t t s e r v e r .
∗ @return r e a d y
∗/
int sm cmac ready ( void ) ;
/∗ ∗
∗ @ b r i e f S u p p o r t f o r s i g n e d w r i t e s , used by a t t s e r v e r .
∗ @note Message i s i n l i t t l e endian t o a l l o w s p a s s i n g i n ATT PDU
without f l i p p i n g .
∗ @note s i g n i n g d a t a : [ opcode , a t t r i b u t e h a n d l e , message ,
sign counter ]
∗ @note c a l c u l a t e d hash i n d o n e c a l l b a c k i s b i g endian and has 16
byte .
∗ @param key
∗ @param opcde
∗ @param a t t r i b u t e h a n d l e
∗ @param m e s s a g e l e n
∗ @param message
∗ @param s i g n c o u n t e r
∗/
void s m c m a c s i g n e d w r i t e s t a r t ( const s m k e y t key , uint8 t opcode ,
uint16 t a t t r i b u t e h a n d l e , uint16 t m e s s a g e l e n , const uint8 t ∗
message , uint32 t s i g n c o u n t e r , void ( ∗ d o n e c a l l b a c k ) ( uint8 t ∗
hash ) ) ;
/∗ ∗
∗ @ b r i e f Match a d d r e s s a g a i n s t bonded d e v i c e s
∗ @param a d d r e s s t y p e
338
∗ @param a d d r e s s
∗ @return 0 i f s u c c e s s f u l l y added t o l o o k u p queue
∗ @note T r i g g e r s SM IDENTITY RESOLVING ∗ e v e n t s
∗/
int s m a d d r e s s r e s o l u t i o n l o o k u p ( uint8 t a d d r e s s t y p e , bd addr t
address ) ;
/∗ ∗
∗ @ b r i e f Get I d e n t i t y R e s o l v i n g s t a t e
∗ @param c o n h a n d l e
∗ @return i r k l o o k u p s t a t e t
∗ @note r e t u r n IRK LOOKUP IDLE i f c o n n e c t i o n d o e s not e x i s t
∗/
irk lookup state t sm identity resolving state ( hci con handle t
con handle ) ;
/∗ ∗
∗ @ b r i e f I d e n t i f y d e v i c e i n LE D e v i ce DB.
∗ @param c o n h a n d l e
∗ @return i n d e x from l e d e v i c e d b or −1 i f not found / i d e n t i f i e d
∗/
int s m l e d e v i c e i n d e x ( h c i c o n h a n d l e t c o n h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Get LTK f o r e n c r y p t e d c o n n e c t i o n
∗ @param c o n h a n d l e
∗ @param l t k b u f f e r t o s t o r e l o n g term key
∗ @return ERROR CODE SUCCESS ok
∗ ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f no c o n n e c t i o n
f o r t h i s con h a n d l e e x i s t s
∗ ERROR CODE PIN OR KEY MISSING i f c o n n e c t i o n i s not
encrypted
∗/
uint8 t s m g e t l t k ( h c i c o n h a n d l e t c o n h a n d l e , s m k e y t l t k ) ;
/∗ ∗
∗ @ b r i e f Use f i x e c p a s s k e y f o r Legacy and SC i n s t e a d o f g e n e r a t i n g
a random number
∗ @note Can be used t o improve s e c u r i t y o v e r J u s t Works i f no
k e y b o a r d or d i s p l a r y a r e p r e s e n t and
∗ i n d i v i d u a l random p a s s k e y can be p r i n t e d on t h e d e v i c e
during production
∗ @param p a s s k e y
∗/
void s m u s e f i x e d p a s s k e y i n d i s p l a y r o l e ( uint32 t p a s s k e y ) ;
/∗ ∗
∗ @ b r i e f Allow c o n n e c t i o n re−e n c r y p t i o n i n P e r i p h e r a l ( Responder )
r o l e f o r LE Legacy P a i r i n g
∗ w i t h o u t e n t r y f o r C e n t r a l d e v i c e s t o r e d i n LE D e v ic e DB
∗ @note BTstack i n P e r i p h e r a l Role ( Responder ) s u p p o r t s LE Legacy
P a i r i n g w i t h o u t a p e r s i s t e n t LE D e v ic e DB as
∗ t h e LTK i s r e c o n s t r u c t e d from a l o c a l s e c r e t IRK and EDIV +
Random s t o r e d on C e n t r a l ( I n i t i a t o r ) d e v i c e
339
∗ On t h e downside , i t ’ s not r e a l l y p o s s i b l e t o d e l e t e a
pairing i f t h i s i s enabled .
∗ @param a l l o w e n c r y p t i o n u s i n g r e c o n s t r u c t e d LTK w i t h o u t s t o r e d
e n t r y ( D e f a u l t : 1)
∗/
void s m a l l o w l t k r e c o n s t r u c t i o n w i t h o u t l e d e v i c e d b e n t r y ( int
allow ) ;
/∗ ∗
∗ @ b r i e f Generate OOB d a t a f o r LE S e c u r e C o n n e c t i o n s
∗ @note This g e n e r a t e s a 128 b i t random number ra and t h e n
c a l c u l a t e s Ca = f 4 (PKa, PKa, ra , 0)
∗ New OOB d a t a s h o u l d be g e n e r a t e d f o r each p a i r i n g . Ra i s
used f o r s u b s e q u e n t OOB p a i r i n g s
∗ @param c a l l b a c k
∗ @return s t a t u s
∗/
uint8 t s m g e n e r a t e s c o o b d a t a ( void ( ∗ c a l l b a c k ) ( const uint8 t ∗
c o n f i r m v a l u e , const uint8 t ∗ random value ) ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r s OOB Data C a l l b a c k f o r LE Se c u r e C o n e c t i o n s . The
c a l l b a c k s h o u l d s e t a l l arguments and r e t u r n 1 i f OOB d a t a i s
availble
∗ @note t h e o o b s c l o c a l r a n d o m u s u a l l y i s t h e random value
r e t u r e n d by s m g e n e r a t e s c o o b d a t a
∗ @param g e t o o b d a t a c a l l b a c k
∗/
void s m r e g i s t e r s c o o b d a t a c a l l b a c k ( int ( ∗
g e t s c o o b d a t a c a l l b a c k ) ( uint8 t a d d r e s s t y p e , bd addr t addr ,
uint8 t ∗ o o b s c p e e r c o n f i r m , uint8 t ∗ o o b s c p e e r r a n d o m ) ) ;
/∗ ∗
∗ @ b b r i e f R e g i s t e r LTK C a l l b a c k t h a t a l l o w s t o p r o v i d e a custom LTK
on re−e n c r y p t i o n . The c a l l b a c k r e t u r n s t r u e i f LTK was
modified
∗ @param g e t l t k c a l l b a c k
∗/
void s m r e g i s t e r l t k c a l l b a c k ( b o o l ( ∗ g e t l t k c a l l b a c k ) (
h c i c o n h a n d l e t c o n h a n d l e , uint8 t a d d r e s s t y p e , bd addr t
addr , uint8 t ∗ l t k ) ) ;
1.26. Audio Interface API. btstack audio.h : Abstraction layer for 16-bit
audio playback and recording within BTstack.
Most embedded implementations, e.g. the one for ESP32, use a single I2S
interface which requires that the sample rate is the same for sink and source
roles
typedef struct {
/∗ ∗
340
∗ @ b r i e f S e tu p a u d i o co d ec f o r s p e c i f i e d s a m p l e r a t e and number
of channels
∗ @param Channels (1=mono , 2= s t e r e o )
∗ @param Sample r a t e
∗ @param P l a y b a c k c a l l b a c k
∗ @return 1 on s u c c e s s
∗/
int ( ∗ i n i t ) ( uint8 t c h a n n e l s ,
uint32 t s a m p l e r a t e ,
void ( ∗ p l a y b a c k ) ( i n t 1 6 t ∗ b u f f e r , uint16 t
num samples ) ) ;
/∗ ∗
∗ @ b r i e f Get t h e c u r r e n t p l a y b a c k sample r a t e , may d i f f e r from
the
∗ s p e c i f i e d sample r a t e
∗/
uint32 t ( ∗ g e t s a m p l e r a t e ) ( void ) ;
/∗ ∗
∗ @ b r i e f S e t volume
∗ @param Volume 0 . . 1 2 7
∗/
void ( ∗ s e t v o l u m e ) ( uint8 t volume ) ;
/∗ ∗
∗ @ b r i e f S t a r t stream
∗/
void ( ∗ s t a r t s t r e a m ) ( void ) ;
/∗ ∗
∗ @ b r i e f Stop stream
∗/
void ( ∗ s t o p s t r e a m ) ( void ) ;
/∗ ∗
∗ @ b r i e f C l o s e a u d i o co d ec
∗/
void ( ∗ c l o s e ) ( void ) ;
typedef struct {
/∗ ∗
∗ @ b r i e f S e tu p a u d i o co d ec f o r s p e c i f i e d s a m p l e r a t e and number
of channels
∗ @param Channels (1=mono , 2= s t e r e o )
∗ @param Sample r a t e
∗ @param Recording c a l l b a c k
∗ @return 1 on s u c c e s s
∗/
int ( ∗ i n i t ) ( uint8 t c h a n n e l s ,
341
uint32 t s a m p l e r a t e ,
void ( ∗ r e c o r d i n g ) ( const i n t 1 6 t ∗ b u f f e r , uint16 t
num samples ) ) ;
/∗ ∗
∗ @ b r i e f Get t h e c u r r e n t r e c o r d i n g sample r a t e , may d i f f e r from
the
∗ s p e c i f i e d sameple r a t e
∗/
uint32 t ( ∗ g e t s a m p l e r a t e ) ( void ) ;
/∗ ∗
∗ @ b r i e f S e t Gain
∗ @param Gain 0 . . 1 2 7
∗/
void ( ∗ s e t g a i n ) ( uint8 t g a i n ) ;
/∗ ∗
∗ @ b r i e f S t a r t stream
∗/
void ( ∗ s t a r t s t r e a m ) ( void ) ;
/∗ ∗
∗ @ b r i e f Stop stream
∗/
void ( ∗ s t o p s t r e a m ) ( void ) ;
/∗ ∗
∗ @ b r i e f C l o s e a u d i o co d ec
∗/
void ( ∗ c l o s e ) ( void ) ;
/∗ ∗
∗ @ b r i e f Get BTstack Audio S i n k I n s t a n c e
∗ @return b t s t a c k a u d i o s i n k i m p l e m e n t a t i o n
∗/
const b t s t a c k a u d i o s i n k t ∗ b t s t a c k a u d i o s i n k g e t i n s t a n c e ( void ) ;
/∗ ∗
∗ @ b r i e f Get BTstack Audio Source I n s t a n c e
∗ @return b t s t a c k a u d i o s o u r c e i m p l e m e n t a t i o n
∗/
const b t s t a c k a u d i o s o u r c e t ∗ b t s t a c k a u d i o s o u r c e g e t i n s t a n c e (
void ) ;
/∗ ∗
∗ @ b r i e f Get BTstack Audio S i n k I n s t a n c e
∗ @param b t s t a c k a u d i o s i n k i m p l e m e n t a t i o n
∗/
342
void b t s t a c k a u d i o s i n k s e t i n s t a n c e ( const b t s t a c k a u d i o s i n k t ∗
audio sink impl ) ;
/∗ ∗
∗ @ b r i e f Get BTstack Audio Source I n s t a n c e
∗ @param b t s t a c k a u d i o s o u r c e i m p l e m e n t a t i o n
∗/
void b t s t a c k a u d i o s o u r c e s e t i n s t a n c e ( const b t s t a c k a u d i o s o u r c e t
∗ audio source impl ) ;
// common i m p l e m e n t a t i o n s
const b t s t a c k a u d i o s i n k t ∗
b t s t a c k a u d i o p o r t a u d i o s i n k g e t i n s t a n c e ( void ) ;
const b t s t a c k a u d i o s o u r c e t ∗
b t s t a c k a u d i o p o r t a u d i o s o u r c e g e t i n s t a n c e ( void ) ;
const b t s t a c k a u d i o s i n k t ∗
btstack audio embedded s i n k g e t i n s t a n c e ( void ) ;
const b t s t a c k a u d i o s o u r c e t ∗
btstack audio embedded s o u r c e g e t i n s t a n c e ( void ) ;
const b t s t a c k a u d i o s i n k t ∗
b t s t a c k a u d i o e s p 3 2 s i n k g e t i n s t a n c e ( void ) ;
const b t s t a c k a u d i o s o u r c e t ∗
b t s t a c k a u d i o e s p 3 2 s o u r c e g e t i n s t a n c e ( void ) ;
/∗ ∗
∗ @brief I n i t i a l i z e base64 decoder
∗ @param c o n t e x t
∗/
void b t s t a c k b a s e 6 4 d e c o d e r i n i t ( b t s t a c k b a s e 6 4 d e c o d e r t ∗ c o n t e x t )
;
/∗ ∗
∗ @ b r i e f Decode s i n g l e b y t e
∗ @brief context
∗ @return v a l u e , or BTSTACK BASE64 DECODER MORE,
BTSTACK BASE64 DECODER COMPLETE, BTSTACK BASE64 DECODER INVALID
∗/
int b t s t a c k b a s e 6 4 d e c o d e r p r o c e s s b y t e ( b t s t a c k b a s e 6 4 d e c o d e r t ∗
c o n t e x t , uint8 t c ) ;
/∗ ∗
∗ @ b r i e f Decode b l o c k
343
∗ @ b r i e f i n p u t d a t a b a s e 6 4 encoded message
∗ @brief i n p u t s i z e
∗ @breif output buffer
∗ @brief output max size
∗ @return o u t p u t s i z e or BTSTACK BASE64 DECODER INVALID,
BTSTACK BASE64 DECODER FULL
∗/
int b t s t a c k b a s e 6 4 d e c o d e r p r o c e s s b l o c k ( const uint8 t ∗ i n p u t d a t a ,
uint32 t i n p u t s i z e , uint8 t ∗ o u t p u t b u f f e r , uint32 t
output max size ) ;
1.28. Chipset Driver API. btstack chipset.h : The API implements custom
chipset initialization and support of proprietary extensions to set UART baud
rate, Bluetooth Address, and similar.
typedef struct {
/∗ ∗
∗ c h i p s e t d r i v e r name
∗/
const char ∗ name ;
/∗ ∗
∗ init driver
∗ allows to r e s e t i n i t s c r i p t index
∗ @param t r a n s p o r t c o n f i g
∗/
void ( ∗ i n i t ) ( const void ∗ t r a n s p o r t c o n f i g ) ;
/∗ ∗
∗ s u p p o r t custom i n i t s e q u e n c e s a f t e r RESET command
∗ @param h c i c m d b u f f e r t o s t o r e g e n e r a t e d command
∗ @return r e s u l t s e e b t s t a c k c h i p s e t r e s u l t t
∗/
b t s t a c k c h i p s e t r e s u l t t ( ∗ next command ) ( uint8 t ∗
hci cmd buffer ) ;
/∗ ∗
∗ p r o v i d e UART Baud Rate change command .
∗ @param b a u d r a t e
∗ @param h c i c m d b u f f e r t o s t o r e g e n e r a t e d command
∗/
void ( ∗ set baudrate command ) ( uint32 t baudrate , uint8 t ∗
hci cmd buffer ) ;
/∗ ∗ p r o v i d e S e t BD Addr command
∗ @param b a u d r a t e
∗ @param h c i c m d b u f f e r t o s t o r e g e n e r a t e d command
∗/
void ( ∗ set bd addr command ) ( bd addr t addr , uint8 t ∗
hci cmd buffer ) ;
} btstack chipset t ;
344
typedef struct {
void ( ∗ i n i t ) ( const void ∗ c o n f i g ) ;
int ( ∗ on ) ( void ) ; // <−− t u r n BT module on and c o n f i g u r e
int ( ∗ o f f ) ( void ) ; // <−− t u r n BT module o f f
int ( ∗ s l e e p ) ( void ) ; // <−− p u t BT module t o s l e e p − only to
be c a l l e d a f t e r ON
int ( ∗ wake ) ( void ) ; // <−− wake BT module from s l e e p − o n l y t o
be c a l l e d a f t e r SLEEP
void ( ∗ r e g i s t e r f o r p o w e r n o t i f i c a t i o n s ) ( void ( ∗ cb ) (
POWER NOTIFICATION t e v e n t ) ) ;
} btstack control t ;
1.30. Debug Messages API. btstack debug.h : Allow to funnel debug and
error messages.
/∗ ∗
∗ @ b r i e f Log S e c u r i t y Manager key v i a l o g i n f o
∗ @param name
∗ @param key t o l o g
∗/
void l o g i n f o k e y ( const char ∗ name , s m k e y t key ) ;
/∗ ∗
∗ @ b r i e f Hexdump v i a l o g i n f o
∗ @param d a t a
∗ @param s i z e
∗/
void l o g i n f o h e x d u m p ( const void ∗ data , int s i z e ) ;
/∗ ∗
∗ @ b r i e f Hexdump v i a l o g d e b u g
∗ @param d a t a
∗ @param s i z e
∗/
void log debug hexdump ( const void ∗ data , int s i z e ) ;
1.31. EM9304 SPI API. btstack em9304 spi.h : BTstack’s Hardware Ab-
straction Layer for EM9304 connected via SPI with additional RDY Interrupt
line.
typedef struct {
/∗ ∗
∗ @ b r i e f Open SPI
∗/
int ( ∗ open ) ( void ) ;
/∗ ∗
∗ @ b r i e f C l o s e SPI
∗/
int ( ∗ c l o s e ) ( void ) ;
/∗ ∗
∗ @ b r i e f Check i f f u l l d u p l e x o p e r a t i o n v i a t r a n s c e i v e i s
supported
∗ @return 1 i f s u p p o r t e d
∗/
int ( ∗ g e t f u l l d u p l e x s u p p o r t ) ( void ) ;
/∗ ∗
∗ @ b r i e f S e t c a l l b a c k f o r RDY
∗ @param c a l l b a c k or NULL t o d i s a b l e c a l l b a c k
∗/
void ( ∗ s e t r e a d y c a l l b a c k ) ( void ( ∗ c a l l b a c k ) ( void ) ) ;
/∗ ∗
∗ @brief Set c a l l b a c k for t r a n s f e r complete
∗ @param c a l l b a c k
∗/
void ( ∗ s e t t r a n s f e r d o n e c a l l b a c k ) ( void ( ∗ c a l l b a c k ) ( void ) ) ;
/∗ ∗
∗ @ b r i e f S e t Chip S e l e t
∗ @param e n a b l e
∗/
void ( ∗ s e t c h i p s e l e c t ) ( int e n a b l e ) ;
/∗ ∗
∗ @ b r i e f P o l l READY s t a t e
∗/
int ( ∗ g e t r e a d y ) ( void ) ;
/∗ ∗
∗ @ b r i e f Transmit and R e c e i v e b y t e s v i a SPI
∗ @param t x d a t a b u f f e r t o t r a n s m i t
∗ @param r x d a t a b u f f e r t o r e c e i v e i n t o
∗ @param l e n
∗/
void ( ∗ t r a n s c e i v e ) ( const uint8 t ∗ t x d a t a , uint8 t ∗ r x d a t a ,
uint16 t l e n ) ;
/∗ ∗
∗ @ b r i e f Transmit b y t e s v i a SPI
∗ @param t x d a t a b u f f e r t o t r a n s m i t
346
∗ @param l e n
∗/
void ( ∗ t r a n s m i t ) ( const uint8 t ∗ t x d a t a , uint16 t l e n ) ;
/∗ ∗
∗ @ b r i e f R e c e i v e b y t e s v i a SPI
∗ @param r x d a t a b u f f e r t o r e c e i v e i n t o
∗ @param l e n
∗/
void ( ∗ r e c e i v e ) ( uint8 t ∗ r x d a t a , uint16 t l e n ) ;
/∗ ∗
∗ @ b r i e f Get EM9304 SPI i n s t a n c e
∗/
const b t s t a c k e m 9 3 0 4 s p i t ∗ b t s t a c k e m 9 3 0 4 s p i e m b e d d e d i n s t a n c e (
void ) ;
/∗
∗ @ b r i e f R e q u e s t t h e t r a n s i t i o n from t h e c u r r e n t s t a t e t o t h e g i v e n
new s t a t e
∗ @param me t h e c u r r e n t s t a t e machine
∗ @param t a r g e t t h e new s t a t e t o t r a n s i t t o
∗ @result transition status
∗/
b t s t a c k f s m s t a t e t b t s t a c k f s m t r a n s i t ( b t s t a c k f s m t ∗ const me ,
btstack fsm state handler t target ) ;
/∗
∗ @ b r i e f C o n s t r u c t s a new s t a t e h i e r a r c h i c a l machine machine , w i t h
s t o r a g e f o r maximum h i e r a r c h y d e p t h .
∗ @param me t h e c u r r e n t s t a t e machine
∗ @param i n i t i a l t h e i n i t i a l s t a t e
∗/
void b t s t a c k f s m c o n s t r u c t o r ( b t s t a c k f s m t ∗ const me ,
btstack fsm state handler t i n i t i a l ) ;
/∗
∗ @ b r i e f Takes t h e i n i t i a l t r a n s i t i o n o f t h e s t a t e machine and
s e n d i n g i t a BTSTACK HSM INIT SIG
∗ @param me t h e c u r r e n t s t a t e machine
∗ @param e e v e n t
∗/
void b t s t a c k f s m i n i t ( b t s t a c k f s m t ∗ const me , b t s t a c k f s m e v e n t t
const ∗ const e ) ;
/∗
347
∗ @ b r i e f D i s p a t c h e s t h e g i v e n e v e n t t o t h e s t a t e machine , i f a
t r a n s i t i o n i s r e q u e s t e d , l e a v e t h e o l d s t a t e s and e n t e r t h e new
on .
∗ Handling e n t e r i n g / e x i t i n g a l l s t a t e s on t h e way .
∗ @param me t h e c u r r e n t s t a t e machine
∗ @param e e v e n t
∗/
b t s t a c k f s m s t a t e t b t s t a c k f s m d i s p a t c h ( b t s t a c k f s m t ∗ const me ,
b t s t a c k f s m e v e n t t const ∗ const e ) ;
/∗
∗ @ b r i e f D i s p a t c h e s t h e g i v e n e v e n t t o t h e s t a t e machine u n t i l i t
was h a n d l e d .
∗ @param me t h e c u r r e n t s t a t e machine
∗ @param e e v e n t
∗/
void b t s t a c k f s m d i s p a t c h u n t i l ( b t s t a c k f s m t ∗ const me ,
b t s t a c k f s m e v e n t t const ∗ const e ) ;
/∗
∗ @ b r i e f Get b o o t d e s c r i p t o r d a t a
∗ @result data
∗/
const uint8 t ∗ b t s t a c k h i d g e t b o o t d e s c r i p t o r d a t a ( void ) ;
/∗
∗ @ b r i e f Get b o o t d e s c r i p t o r l e n g t h
∗ @result length
∗/
uint16 t b t s t a c k h i d g e t b o o t d e s c r i p t o r l e n ( void ) ;
1.34. HID Parser API. btstack hid parser.h : Single-pass HID Report Parser:
HID Report is directly parsed without preprocessing HID Descriptor to minimize
memory.
/∗ ∗
∗ @brief I n i t i a l i z e HID P a rs e r .
∗ @param parser sta te
∗ @param hid descriptor
∗ @param hid descriptor len
∗ @param hid report type
∗ @param hid report
∗ @param hid report len
∗/
348
void b t s t a c k h i d p a r s e r i n i t ( b t s t a c k h i d p a r s e r t ∗ p a r s e r , const
uint8 t ∗ h i d d e s c r i p t o r , uint16 t h i d d e s c r i p t o r l e n ,
h i d r e p o r t t y p e t h i d r e p o r t t y p e , const uint8 t ∗ h i d r e p o r t ,
uint16 t h i d r e p o r t l e n ) ;
/∗ ∗
∗ @ b r i e f Checks i f more f i e l d s a r e a v a i l a b l e
∗ @param p a r s e r
∗/
bool btstack hid parser has more ( b t s t a c k h i d p a r s e r t ∗ parser ) ;
/∗ ∗
∗ @ b r i e f Get n e x t f i e l d
∗ @param p a r s e r
∗ @param u s a g e p a g e
∗ @param u s a g e
∗ @param v a l u e p r o v i d e d i n HID r e p o r t
∗/
void b t s t a c k h i d p a r s e r g e t f i e l d ( b t s t a c k h i d p a r s e r t ∗ p a r s e r ,
uint16 t ∗ u s a g e p a g e , uint16 t ∗ usage , i n t 3 2 t ∗ v a l u e ) ;
/∗ ∗
∗ @ b r i e f P a r s e s d e s c r i p t o r item
∗ @param item
∗ @param h i d d e s c r i p t o r
∗ @param h i d d e s c r i p t o r l e n
∗ @return t r u e i f item has been p a r s e d s u c c e s s f u l l y
∗/
b o o l b t s t a c k h i d p a r s e d e s c r i p t o r i t e m ( h i d d e s c r i p t o r i t e m t ∗ item ,
const uint8 t ∗ h i d d e s c r i p t o r , uint16 t h i d d e s c r i p t o r l e n ) ;
/∗ ∗
∗ @ b r i e f P a r s e s d e s c r i p t o r and r e t u r n s r e p o r t s i z e f o r g i v e n r e p o r t
ID and r e p o r t t y p e
∗ @param r e p o r t i d
∗ @param r e p o r t t y p e
∗ @param h i d d e s c r i p t o r l e n
∗ @param h i d d e s c r i p t o r
∗ @return r e p o r t s i z e i n b y t e s or 0 on p a r s i n g e r r o r
∗/
int b t s t a c k h i d g e t r e p o r t s i z e f o r i d ( int r e p o r t i d ,
h i d r e p o r t t y p e t r e p o r t t y p e , uint16 t h i d d e s c r i p t o r l e n ,
const uint8 t ∗ h i d d e s c r i p t o r ) ;
/∗ ∗
∗ @ b r i e f P a r s e s d e s c r i p t o r and r e t u r n s s t a t u s f o r g i v e n r e p o r t ID
∗ @param r e p o r t i d
∗ @param h i d d e s c r i p t o r l e n
∗ @param h i d d e s c r i p t o r
∗ @return s t a t u s f o r r e p o r t i d
∗/
h i d r e p o r t i d s t a t u s t b t s t a c k h i d i d v a l i d ( int r e p o r t i d , uint16 t
h i d d e s c r i p t o r l e n , const uint8 t ∗ h i d d e s c r i p t o r ) ;
349
/∗ ∗
∗ @ b r i e f P a r s e s d e s c r i p t o r and r e t u r n s t r u e i f r e p o r t ID found
∗ @param h i d d e s c r i p t o r l e n
∗ @param h i d d e s c r i p t o r
∗ @return t r u e i f r e p o r t ID d e c l a r e d i n d e s c r i p t o r
∗/
b o o l b t s t a c k h i d r e p o r t i d d e c l a r e d ( uint16 t h i d d e s c r i p t o r l e n ,
const uint8 t ∗ h i d d e s c r i p t o r ) ;
/∗
∗ @ b r i e f R e q u e s t t h e t r a n s i t i o n from t h e c u r r e n t s t a t e t o t h e g i v e n
new s t a t e
∗ @param me t h e c u r r e n t s t a t e machine
∗ @param t a r g e t t h e new s t a t e t o t r a n s i t t o
∗ @result transition status
∗/
b t s t a c k h s m s t a t e t b t s t a c k h s m t r a n s i t ( b t s t a c k h s m t ∗ const me ,
b t s t a c k h s m s t a t e h a n d l e r t const t a r g e t ) ;
/∗
∗ @ b r i e f S p e c i f i e s t h e upper s t a t e i n a s t a t e h i e r a r c h y
∗ @param me t h e c u r r e n t s t a t e machine
∗ @param t a r g e t t h e n e x t p a r e n t s t a t e i n t h e h i e r a r c h y
∗ @result transition status
∗/
b t s t a c k h s m s t a t e t b t s t a c k h s m s u p e r ( b t s t a c k h s m t ∗ const me ,
b t s t a c k h s m s t a t e h a n d l e r t const t a r g e t ) ;
/∗
∗ @ b r i e f P l a c e h o l d e r s t a t e t o mark t h e t o p most s t a t e i n a s t a t e
hierarchy , the root s t a t e . Ignores a l l events .
∗ @param me t h e c u r r e n t s t a t e machine
∗ @param e e v e n t
∗ @result ignored status
∗/
b t s t a c k h s m s t a t e t b t s t a c k h s m t o p ( b t s t a c k h s m t ∗ const me ,
b t s t a c k h s m e v e n t t const ∗ const e ) ;
/∗
∗ @ b r i e f C o n s t r u c t s a new s t a t e h i e r a r c h i c a l machine machine , w i t h
s t o r a g e f o r maximum h i e r a r c h y d e p t h .
∗ @param me t h e c u r r e n t s t a t e machine
∗ @param i n i t i a l t h e i n i t i a l s t a t e
∗ @param a r r a y o f b t s t a c k h s m s t a t e h a n d l e r t e l e m e n t s w i t h t h e
same number o f e l e m e n t s as t h e maximum number o f n e s t e d s t a t e
machines .
∗ @param The number o f n e s t e d s t a t e machines .
∗/
350
void b t s t a c k h s m c o n s t r u c t o r ( b t s t a c k h s m t ∗ const me ,
btstack hsm state handler t initial , btstack hsm state handler t
path [ ] , i n t 8 t depth ) ;
/∗
∗ @ b r i e f Takes t h e i n i t i a l t r a n s i t i o n o f t h e s t a t e machine and
s e n d i n g i t a BTSTACK HSM INIT SIG
∗ @param me t h e c u r r e n t s t a t e machine
∗ @param e e v e n t
∗/
void b t s t a c k h s m i n i t ( b t s t a c k h s m t ∗ const me , b t s t a c k h s m e v e n t t
const ∗ const e ) ;
/∗
∗ @ b r i e f D i s p a t c h e s t h e g i v e n e v e n t t o t h e s t a t e machine , i f a
t r a n s i t i o n i s r e q u e s t e d , l e a v e t h e o l d s t a t e s and e n t e r t h e new
on .
∗ Honoring t h e h i e r a r c h y and h a n d l i n g e n t e r i n g / e x i t i n g a l l
s t a t e s on t h e way .
∗ @param me t h e c u r r e n t s t a t e machine
∗ @param e e v e n t
∗/
b t s t a c k h s m s t a t e t b t s t a c k h s m d i s p a t c h ( b t s t a c k h s m t ∗ const me ,
b t s t a c k h s m e v e n t t const ∗ const e ) ;
1.36. LC3 Interface API. btstack lc3.h : Interface for LC3 implementations
typedef enum {
BTSTACK LC3 FRAME DURATION 10000US ,
BTSTACK LC3 FRAME DURATION 7500US
} btstack lc3 frame duration t ;
typedef struct {
/∗ ∗
∗ C o n f i g u r e Decoder
∗ @param c o n t e x t
∗ @param s a m p l e r a t e
∗ @param f r a m e d u r a t i o n
∗ @param o c t e t s p e r f r a m e
∗ @return s t a t u s
∗/
uint8 t ( ∗ c o n f i g u r e ) ( void ∗ c o n t e x t , uint32 t s a m p l e r a t e ,
b t s t a c k l c 3 f r a m e d u r a t i o n t f r a m e d u r a t i o n , uint16 t
octets per frame ) ;
/∗ ∗
∗ Decode LC3 Frame i n t o s i g n e d 16− b i t s a m p l e s
∗ @param context
∗ @param bytes
∗ @param BFI Bad Frame I n d i c a t i o n f l a g s
∗ @param pcm out b u f f e r f o r decoded PCM s a m p l e s
351
∗ @param s t r i d e c ou n t b e t w e e n two c o n s e c u t i v e s a m p l e s
∗ @param BEC detect B i t Error D e t e c t e d f l a g
∗ @return s t a t u s
∗/
uint8 t ( ∗ d e c o d e s i g n e d 1 6 ) ( void ∗ c o n t e x t , const uint8 t ∗
bytes , uint8 t BFI ,
i n t 1 6 t ∗ pcm out , uint16 t s t r i d e , uint8 t ∗
BEC detect ) ;
/∗ ∗
∗ Decode LC3 Frame i n t o s i g n e d 24− b i t samples , s i g n −e x t e n d e d t o
32− b i t
∗ @param c o n t e x t
∗ @param b y t e s
∗ @param BFI Bad Frame I n d i c a t i o n f l a g s
∗ @param pcm out b u f f e r f o r decoded PCM s a m p l e s
∗ @param s t r i d e c ou n t b e t w e e n two c o n s e c u t i v e s a m p l e s
∗ @param BEC detect B i t Error D e t e c t e d f l a g
∗ @return s t a t u s
∗/
uint8 t ( ∗ d e c o d e s i g n e d 2 4 ) ( void ∗ c o n t e x t , const uint8 t ∗ bytes
, uint8 t BFI ,
i n t 3 2 t ∗ pcm out , uint16 t s t r i d e ,
uint8 t ∗ BEC detect ) ;
typedef struct {
/∗ ∗
∗ C o n f i g u r e Decoder
∗ @param c o n t e x t
∗ @param s a m p l e r a t e
∗ @param f r a m e d u r a t i o n
∗ @param o c t e t s p e r f r a m e
∗ @return s t a t u s
∗/
uint8 t ( ∗ c o n f i g u r e ) ( void ∗ c o n t e x t , uint32 t s a m p l e r a t e ,
b t s t a c k l c 3 f r a m e d u r a t i o n t f r a m e d u r a t i o n , uint16 t
octets per frame ) ;
/∗ ∗
∗ Encode LC3 Frame w i t h 16− b i t s i g n e d PCM s a m p l e s
∗ @param c o n t e x t
∗ @param pcm in b u f f e r f o r decoded PCM s a m p l e s
∗ @param s t r i d e c ou n t b e t w e e n two c o n s e c u t i v e s a m p l e s
∗ @param b y t e s
∗ @return s t a t u s
∗/
uint8 t ( ∗ e n c o d e s i g n e d 1 6 ) ( void ∗ c o n t e x t , const i n t 1 6 t ∗
pcm in , uint16 t s t r i d e , uint8 t ∗ b y t e s ) ;
/∗ ∗
∗ Encode LC3 Frame w i t h 24− b i t s i g n e d PCM samples , s i g n −
e x t e n d e d t o 32 b i t
352
∗ @param c o n t e x t
∗ @param pcm in b u f f e r f o r decoded PCM s a m p l e s
∗ @param s t r i d e c ou n t b e t w e e n two c o n s e c u t i v e s a m p l e s
∗ @param b y t e s
∗ @return s t a t u s
∗/
uint8 t ( ∗ e n c o d e s i g n e d 2 4 ) ( void ∗ c o n t e x t , const i n t 3 2 t ∗
pcm in , uint16 t s t r i d e , uint8 t ∗ b y t e s ) ;
/∗ ∗
∗ @ b r i e f Map enum t o ISO I n t e r v a l i n us
∗ @param f r a m e d u r a t i o n enum
∗ @return f r a m e d u r a t o i n i n us or 0 f o r i n v a l i d f r a m e d u r a t i o n enum
∗/
uint16 t b t s t a c k l c 3 f r a m e d u r a t i o n i n u s (
btstack lc3 frame duration t frame duration ) ;
/∗ ∗
∗ @ b b r i e f C a l c u l a t e number o f s a m p l e s p e r ISO I n t e r v a l
∗ @param s a m p l e r a t e
∗ @param f r a m e d u r a t i o n
∗ @return
∗/
uint16 t b t s t a c k l c 3 s a m p l e s p e r f r a m e ( uint32 t s a m p l e r a t e ,
btstack lc3 frame duration t frame duration ) ;
typedef struct {
lc3 decoder mem 48k t decoder mem ;
lc3 decoder t decoder ; // p o i n t e r
uint32 t sample rate ;
btstack lc3 frame duration t frame duration ;
uint16 t octets per frame ;
} btstack lc3 decoder google t ;
typedef struct {
lc3 encoder mem 48k t encoder mem ;
lc3 encoder t encoder ; // p o i n t e r
uint32 t sample rate ;
btstack lc3 frame duration t frame duration ;
uint16 t octets per frame ;
} btstack lc3 encoder google t ;
/∗ ∗
∗ I n i t LC3 Decoder I n s t a n c e
∗ @param c o n t e x t f o r EHIMA LC3 d e c o d e r
∗/
353
const b t s t a c k l c 3 d e c o d e r t ∗
btstack lc3 decoder google init instance (
b t s t a c k l c 3 d e c o d e r g o o g l e t ∗ context ) ;
/∗ ∗
∗ I n i t LC3 Decoder I n s t a n c e
∗ @param c o n t e x t f o r EHIMA LC3 d e c o d e r
∗/
const b t s t a c k l c 3 e n c o d e r t ∗
btstack lc3 encoder google init instance (
b t s t a c k l c 3 e n c o d e r g o o g l e t ∗ context ) ;
1.38. Adapter for Fraunhofer LC3plus Coddec API. btstack lc3plus fraunhofer.h
: only uses suitable subset for lc3 testing
typedef struct {
btstack lc3 frame duration t frame duration ;
uint16 t octets per frame ;
uint16 t samples per frame ;
uint32 t sample rate ;
// d e c o d e r must be 4− b y t e a l i g n e d
uint8 t d e c o d e r [ LC3PLUS DEC MAX SIZE ] ;
} btstack lc3plus fraunhofer decoder t ;
typedef struct {
btstack lc3 frame duration t frame duration ;
uint16 t octets per frame ;
uint32 t sample rate ;
// e n c o d e r must be 4− b y t e a l i g n e d
uint8 t e n c o d e r [ LC3PLUS ENC MAX SIZE ] ;
} btstack lc3plus fraunhofer encoder t ;
/∗ ∗
∗ I n i t LC3 Decoder I n s t a n c e
∗ @param c o n t e x t f o r F r a u n h o f e r LC3plus d e c o d e r
∗/
const b t s t a c k l c 3 d e c o d e r t ∗
btstack lc3plus fraunhofer decoder init instance (
b t s t a c k l c 3 p l u s f r a u n h o f e r d e c o d e r t ∗ context ) ;
/∗ ∗
∗ I n i t LC3 Encoder I n s t a n c e
∗ @param c o n t e x t f o r F r a u n h o f e r LC3plus e n c o d e r
∗/
const b t s t a c k l c 3 e n c o d e r t ∗
btstack lc3plus fraunhofer encoder init instance (
b t s t a c k l c 3 p l u s f r a u n h o f e r e n c o d e r t ∗ context ) ;
typedef struct b t s t a c k l i n k e d i t e m {
struct b t s t a c k l i n k e d i t e m ∗ next ; // <−− n e x t e l e m e n t i n l i s t ,
or NULL
} btstack linked item t ;
typedef b t s t a c k l i n k e d i t e m t ∗ b t s t a c k l i n k e d l i s t t ;
typedef struct {
int a d v a n c e o n n e x t ;
b t s t a c k l i n k e d i t e m t ∗ prev ; // p o i n t s t o t h e item b e f o r e t h e
c u r r e n t one
btstack linked item t ∗ curr ; // p o i n t s t o t h e c u r r e n t item (
t o d e t e c t item removal )
} btstack linked list iterator t ;
/∗ ∗
∗ @ b r i e f Test i f l i s t i s empty .
∗ @param l i s t
∗ @return t r u e i f l i s t i s empty
∗/
bool b t s t a c k l i n k e d l i s t e m p t y ( b t s t a c k l i n k e d l i s t t ∗ l i s t ) ;
/∗ ∗
∗ @ b r i e f Add item t o l i s t as f i r s t e l e m e n t .
∗ @param l i s t
∗ @param item
∗ @return t r u e i f item was added , f a l s e i f item a l r e a d y i n l i s t
∗/
bool b t s t a c k l i n k e d l i s t a d d ( b t s t a c k l i n k e d l i s t t ∗ l i s t ,
b t s t a c k l i n k e d i t e m t ∗ item ) ;
/∗ ∗
∗ @ b r i e f Add item t o l i s t as l a s t e l e m e n t .
∗ @param l i s t
∗ @param item
∗ @return t r u e i f item was added , f a l s e i f item a l r e a d y i n l i s t
∗/
bool b t s t a c k l i n k e d l i s t a d d t a i l ( b t s t a c k l i n k e d l i s t t ∗ l i s t ,
b t s t a c k l i n k e d i t e m t ∗ item ) ;
/∗ ∗
∗ @ b r i e f Pop ( g e t + remove ) f i r s t e l e m e n t .
∗ @param l i s t
∗ @return f i r s t e l e m e n t or NULL i f l i s t i s empty
∗/
btstack linked item t ∗ btstack linked list pop (
btstack linked list t ∗ list ) ;
/∗ ∗
∗ @ b r i e f Remove item from l i s t
∗ @param l i s t
∗ @param item
∗ @return t r u e i f item was removed , f a l s e i f i t i s no ’ t i n l i s t
355
∗/
bool b t s t a c k l i n k e d l i s t r e m o v e ( b t s t a c k l i n k e d l i s t t ∗ l i s t ,
b t s t a c k l i n k e d i t e m t ∗ item ) ;
/∗ ∗
∗ @ b r i e f Get f i r s t e l e m e n t .
∗ @param l i s t
∗ @return f i r s t e l e m e n t or NULL i f l i s t i s empty
∗/
btstack linked item t ∗ btstack linked list get first item (
btstack linked list t ∗ list ) ;
/∗ ∗
∗ @ b r i e f Get l a s t e l e m e n t .
∗ @param l i s t
∗ @return f i r s t e l e m e n t or NULL i f l i s t i s empty
∗/
btstack linked item t ∗ btstack linked list get last item (
btstack linked list t ∗ list ) ;
/∗ ∗
∗ @ b r i e f Counts number o f i t e m s i n l i s t
∗ @return number o f i t e m s i n l i s t
∗/
int b t s t a c k l i n k e d l i s t c o u n t ( b t s t a c k l i n k e d l i s t t ∗ l i s t ) ;
/∗ ∗
∗ @ b r i e f I n i t i a l i z e Linked L i s t I t e r a t o r
∗ @note r o b u s t a g a i n s t removal o f c u r r e n t e l e m e n t by
btstack linked list remove
∗ @param i t i t e r a t o r c o n t e x t
∗ @param l i s t
∗/
void b t s t a c k l i n k e d l i s t i t e r a t o r i n i t (
b t s t a c k l i n k e d l i s t i t e r a t o r t ∗ it , b t s t a c k l i n k e d l i s t t ∗
list );
/∗ ∗
∗ @ b r i e f Has n e x t e l e m e n t
∗ @param i t i t e r a t o r c o n t e x t
∗ @return t r u e i f n e x t e l e m e n t i s a v a i l a b l e
∗/
bool b t s t a c k l i n k e d l i s t i t e r a t o r h a s n e x t (
btstack linked list iterator t ∗ it ) ;
/∗ ∗
∗ @ b r i e f Get n e x t l i s t e l e e m n t
∗ @param i t i t e r a t o r c o n t e x t
∗ @return l i s t e l e m e n t
∗/
btstack linked item t ∗ btstack linked list iterator next (
btstack linked list iterator t ∗ it ) ;
356
/∗ ∗
∗ @ b r i e f Remove c u r r e n t l i s t e l e m e n t from l i s t
∗ @param i t i t e r a t o r c o n t e x t
∗/
void b t s t a c k l i n k e d l i s t i t e r a t o r r e m o v e (
btstack linked list iterator t ∗ it ) ;
typedef struct {
b t s t a c k l i n k e d i t e m t ∗ head ;
btstack linked item t ∗ tail ;
} btstack linked queue t ;
/∗ ∗
∗ @ b r i e f T e s t s i f queue i s empty
∗ @return t r u e i f emtpy
∗/
b o o l b t s t a c k l i n k e d q u e u e e m p t y ( b t s t a c k l i n k e d q u e u e t ∗ queue ) ;
/∗ ∗
∗ @ b r i e f Append item t o queue
∗ @param queue
∗ @param item
∗/
void b t s t a c k l i n k e d q u e u e e n q u e u e ( b t s t a c k l i n k e d q u e u e t ∗ queue ,
b t s t a c k l i n k e d i t e m t ∗ item ) ;
/∗ ∗
∗ @ b r i e f Pop n e x t item from queue
∗ @param queue
∗ @return item or NULL i f queue empty
∗/
btstack linked item t ∗ btstack linked queue dequeue (
btstack linked queue t ∗ queue ) ;
/∗ ∗
∗ @ b r i e f Get f i r s t item from queue
∗ @param queue
∗ @return item or NULL i f queue empty
∗/
btstack linked item t ∗ btstack linked queue first (
b t s t a c k l i n k e d q u e u e t ∗ queue ) ;
/∗ ∗
∗ @ b r i e f I n i t i a l i z e network i n t e r f a c e
∗ @param s e n d p a c k e t c a l l b a c k
357
∗/
void b t s t a c k n e t w o r k i n i t ( void ( ∗ s e n d p a c k e t c a l l b a c k ) ( const uint8 t
∗ packet , uint16 t s i z e ) ) ;
/∗ ∗
∗ @ b r i e f Bring up network i n t e r f a c d
∗ @param n e t w o r k a d d r e s s
∗ @return 0 i f ok
∗/
int b t s t a c k n e t w o r k u p ( bd addr t n e t w o r k a d d r e s s ) ;
/∗ ∗
∗ @ b r i e f Shut down network i n t e r f a c d
∗ @param n e t w o r k a d d r e s s
∗ @return 0 i f ok
∗/
int b t s t a c k n e t w o r k d o w n ( void ) ;
/∗ ∗
∗ @ b r i e f R e c e i v e p a c k e t on network i n t e r f a c e , e . g . , f o r w a r d p a c k e t
t o TCP/IP s t a c k
∗ @param p a c k e t
∗ @param s i z e
∗/
void b t s t a c k n e t w o r k p r o c e s s p a c k e t ( const uint8 t ∗ packet , uint16 t
size ) ;
/∗ ∗
∗ @ b r i e f N o t i f y network i n t e r f a c e t h a t p a c k e t from
s e n d p a c k e t c a l l b a c k was s e n t and t h e n e x t p a c k e t can be
delivered .
∗/
void b t s t a c k n e t w o r k p a c k e t s e n t ( void ) ;
/∗ ∗
∗ @ b r i e f Get network name a f t e r network was a c t i v a t e d
∗ @note e . g . tapX on Linux , might not be u s e f u l on a l l p l a t f o r m s
∗ @return network name
∗/
const char ∗ b t s t a c k n e t w o r k g e t n a m e ( void ) ;
/∗ ∗
∗ @brief I n i t resample context
∗ @param num channels
∗ @return b t s t a c k a u d i o i m p l e m e n t a t i o n
∗/
void b t s t a c k r e s a m p l e i n i t ( b t s t a c k r e s a m p l e t ∗ c o n t e x t , int
num channels ) ;
358
/∗ ∗
∗ @brief Set resampling f a c t o r
∗ @param f a c t o r as f i x e d p o i n t v a l u e , i d e n t i t y i s 0 x10000
∗/
void b t s t a c k r e s a m p l e s e t f a c t o r ( b t s t a c k r e s a m p l e t ∗ c o n t e x t ,
uint32 t f a c t o r ) ;
/∗ ∗
∗ @brief Process b l o c k of input samples
∗ @note s i z e o f o u t p u t b u f f e r i s not c h e c k e d
∗ @param i n p u t b u f f e r
∗ @param num frames
∗ @param o u t p u t b u f f e r
∗ @return number d e s t i n a t i o n frames
∗/
uint16 t b t s t a c k r e s a m p l e b l o c k ( b t s t a c k r e s a m p l e t ∗ c o n t e x t , const
i n t 1 6 t ∗ i n p u t b u f f e r , uint32 t num frames , i n t 1 6 t ∗
output buffer ) ;
/∗ ∗
∗ Init ring buffer
∗ @param r i n g b u f f e r o b j e c t
∗ @param s t o r a g e
∗ @param s t o r a g e s i z e i n b y t e s
∗/
void b t s t a c k r i n g b u f f e r i n i t ( b t s t a c k r i n g b u f f e r t ∗ r i n g b u f f e r ,
uint8 t ∗ s t o r a g e , uint32 t s t o r a g e s i z e ) ;
/∗ ∗
∗ R e s e t r i n g b u f f e r t o i n i t i a l s t a t e ( empty )
∗ @param r i n g b u f f e r o b j e c t
∗/
void b t s t a c k r i n g b u f f e r r e s e t ( b t s t a c k r i n g b u f f e r t ∗ r i n g b u f f e r ) ;
/∗ ∗
∗ Check i f r i n g b u f f e r i s empty
∗ @param r i n g b u f f e r o b j e c t
∗ @return TRUE i f empty
∗/
int b t s t a c k r i n g b u f f e r e m p t y ( b t s t a c k r i n g b u f f e r t ∗ r i n g b u f f e r ) ;
/∗ ∗
∗ Get number o f b y t e s a v a i l a b l e f o r read
∗ @param r i n g b u f f e r o b j e c t
∗ @return number o f b y t e s a v a i l a b l e f o r r ead
∗/
uint32 t b t s t a c k r i n g b u f f e r b y t e s a v a i l a b l e ( b t s t a c k r i n g b u f f e r t ∗
ring buffer ) ;
/∗ ∗
359
∗ Get f r e e s p a c e a v a i l a b l e f o r w r i t e
∗ @param r i n g b u f f e r o b j e c t
∗ @return number o f b y t e s a v a i l a b l e f o r w r i t e
∗/
uint32 t b t s t a c k r i n g b u f f e r b y t e s f r e e ( b t s t a c k r i n g b u f f e r t ∗
ring buffer ) ;
/∗ ∗
∗ Write b y t e s i n t o r i n g b u f f e r
∗ @param r i n g b u f f e r o b j e c t
∗ @param d a t a t o s t o r e
∗ @param d a t a l e n g t h
∗ @return 0 i f ok , ERROR CODE MEMORY CAPACITY EXCEEDED i f not
enough s p a c e i n b u f f e r
∗/
int b t s t a c k r i n g b u f f e r w r i t e ( b t s t a c k r i n g b u f f e r t ∗ r i n g b u f f e r ,
uint8 t ∗ data , uint32 t d a t a l e n g t h ) ;
/∗ ∗
∗ Read from r i n g b u f f e r
∗ @param r i n g b u f f e r o b j e c t
∗ @param b u f f e r t o s t o r e re ad d a t a
∗ @param l e n g t h t o rea d
∗ @param n u m b e r o f b y t e s r e a d
∗/
void b t s t a c k r i n g b u f f e r r e a d ( b t s t a c k r i n g b u f f e r t ∗ r i n g b u f f e r ,
uint8 t ∗ b u f f e r , uint32 t l e n g t h , uint32 t ∗
number of bytes read ) ;
typedef struct {
uint32 t count ; // 17 b i t a r e u s a b l e t o co u nt samples ,
recommended f o r max 96 kHz
360
/∗ ∗
∗ @ b r i e f I n i t i a l i z e sample r a t e compensation
∗ @param s e l f p o i n t e r t o c u r r e n t i n s t a n c e
∗ @param time stamp a t which t o s t a r t sample r a t e measurement
∗/
void b t s t a c k s a m p l e r a t e c o m p e n s a t i o n i n i t (
b t s t a c k s a m p l e r a t e c o m p e n s a t i o n t ∗ s e l f , uint32 t timestamp ms ,
uint32 t s a m p l e r a t e , uint32 t r a t i o Q 1 5 ) ;
/∗ ∗
∗ @ b r i e f r e s e t sample r a t e compensation
∗ @param s e l f p o i n t e r t o c u r r e n t i n s t a n c e
∗ @param time stamp a t which t o s t a r t sample r a t e measurement
∗/
void b t s t a c k s a m p l e r a t e c o m p e n s a t i o n r e s e t (
b t s t a c k s a m p l e r a t e c o m p e n s a t i o n t ∗ s e l f , uint32 t timestamp ms
);
/∗ ∗
∗ @ b r i e f u p d a t e sample r a t e compensation w i t h t h e c u r r e n t p l a y b a c k
sample r a t e decoded s a m p l e s
∗ @param s e l f p o i n t e r t o c u r r e n t i n s t a n c e
∗ @param time stamp f o r c u r r e n t s a m p l e s
∗ @param s a m p l e s f o r c u r r e n t time stamp
∗ @param p l a y b a c k sample r a t e
∗/
uint32 t b t s t a c k s a m p l e r a t e c o m p e n s a t i o n u p d a t e (
b t s t a c k s a m p l e r a t e c o m p e n s a t i o n t ∗ s e l f , uint32 t timestamp ms ,
uint32 t samples , uint32 t p l a y b a c k s a m p l e r a t e ) ;
typedef struct {
/∗ ∗
∗ r e g i s t e r p a c k e t h a n d l e r f o r SCO HCI p a c k e t s
∗/
void ( ∗ r e g i s t e r p a c k e t h a n d l e r ) ( void ( ∗ h a n d l e r ) ( uint8 t
p a c k e t t y p e , uint8 t ∗ packet , uint16 t s i z e ) ) ;
361
/∗ ∗
∗ open t r a n s p o r t
∗ @param c o n h a n d l e o f SCO c o n n e c t i o n
∗ @param s c o f o r m a t
∗/
void ( ∗ open ) ( h c i c o n h a n d l e t c o n h a n d l e , s c o f o r m a t t
sco format ) ;
/∗ ∗
∗ send SCO p a c k e t
∗/
void ( ∗ s e n d p a c k e t ) ( const uint8 t ∗ b u f f e r , uint16 t l e n g t h ) ;
/∗ ∗
∗ close transport
∗ @param c o n h a n d l e o f SCO c o n n e c t i o n
∗/
void ( ∗ c l o s e ) ( h c i c o n h a n d l e t c o n h a n d l e ) ;
// ENCODER
/∗ ∗
∗ @ b r i e f I n i t i a l i s e SLIP e n c o d e r w i t h d a t a
∗ @param d a t a
∗ @param l e n
∗/
void b t s t a c k s l i p e n c o d e r s t a r t ( const uint8 t ∗ data , uint16 t l e n ) ;
/∗ ∗
∗ @ b r i e f Check i f e n c o d e r has d a t a r e a d y
∗ @return True i f d a t a r e a d y
∗/
int b t s t a c k s l i p e n c o d e r h a s d a t a ( void ) ;
/∗ ∗
∗ @ b r i e f Get n e x t b y t e from e n c o d e r
∗ @return Next b y t e s from e n c o d e r
∗/
uint8 t b t s t a c k s l i p e n c o d e r g e t b y t e ( void ) ;
// DECODER
/∗ ∗
∗ @ b r i e f I n i t i a l i s e SLIP d e c o d e r w i t h b u f f e r
∗ @param b u f f e r t o s t o r e r e c e i v e d d a t a
∗ @param m a x s i z e o f b u f f e r
∗/
void b t s t a c k s l i p d e c o d e r i n i t ( uint8 t ∗ b u f f e r , uint16 t m a x s i z e ) ;
362
/∗ ∗
∗ @brief Process r e c e i v e d byte
∗ @param i n p u t
∗/
void b t s t a c k s l i p d e c o d e r p r o c e s s ( uint8 t i n p u t ) ;
/∗ ∗
∗ @ b r i e f Get s i z e o f decoded frame
∗ @return s i z e o f frame . S i z e = 0 => frame not c o m p l e t e
∗/
uint16 t b t s t a c k s l i p d e c o d e r f r a m e s i z e ( void ) ;
typedef struct {
/∗ ∗
∗ Get Value f o r Tag
∗ @param c o n t e x t
∗ @param t a g
∗ @param b u f f e r
∗ @param b u f f e r s i z e
∗ @return s i z e o f v a l u e
∗/
int ( ∗ g e t t a g ) ( void ∗ c o n t e x t , uint32 t tag , uint8 t ∗ b u f f e r ,
uint32 t b u f f e r s i z e ) ;
/∗ ∗
∗ S t o r e Tag
∗ @param c o n t e x t
∗ @param t a g
∗ @param d a t a
∗ @param d a t a s i z e
∗ @return 0 on s u c c e s s
∗/
int ( ∗ s t o r e t a g ) ( void ∗ c o n t e x t , uint32 t tag , const uint8 t ∗
data , uint32 t d a t a s i z e ) ;
/∗ ∗
∗ D e l e t e Tag
∗ @note i t i s not e x p e c t e d t h a t d e l e t e o p e r a t i o n f a i l s , p l e a s e
use a t l e a s t l o g e r r o r i n c a s e o f e r r o r s
∗ @param c o n t e x t
∗ @param t a g
∗/
void ( ∗ d e l e t e t a g ) ( void ∗ c o n t e x t , uint32 t t a g ) ;
363
} btstack tlv t ;
/∗ ∗
∗ @ b r i e f Make TLV i m p l e m e n t a t i o n a v a i l a b l e t o BTstack components
via Singleton
∗ @note U s u a l l y c a l l e d by p o r t a f t e r BD ADDR was r e t r i e v e d from
Bluetooth Controller
∗ @param t l v i m p l
∗ @param t l v c o n t e x t
∗/
void b t s t a c k t l v s e t i n s t a n c e ( const b t s t a c k t l v t ∗ t l v i m p l , void ∗
tlv context ) ;
/∗ ∗
∗ @ b r i e f Get c u r r e n t TLV i m p l e m e n t a t i o n . Used f o r b o n d i n g
i n f o r m a t i o n , b u t can be used by a p p l i c a t i o n , t o o .
∗ @param t l v i m p l
∗ @param t l v c o n t e x t
∗/
void b t s t a c k t l v g e t i n s t a n c e ( const b t s t a c k t l v t ∗∗ t l v i m p l , void
∗∗ t l v c o n t e x t ) ;
1.48. Empty TLV Instance API. btstack tlv none.h : Empty implemen-
tation for BTstack’s Tag Value Length Persistent Storage implementations No
keys are stored. Can be used as placeholder during porting to new platform.
/∗ ∗
∗ I n i t Tag Length Value S t o r e
∗ @param c o n t e x t b t s t a c k t l v n o n e t
∗ @param h a l f l a s h b a n k i m p l of hal flash bank interface
∗ @Param h a l f l a s h b a n k c o n t e x t o f h a l f l a s h b a n k i n t e r f a c e
∗/
const b t s t a c k t l v t ∗ b t s t a c k t l v n o n e i n i t i n s t a n c e ( void ) ;
1.49. UART API. btstack uart.h : Common types for UART transports
typedef struct {
/∗ ∗
∗ init transport
∗ @param u a r t c o n f i g
∗/
int ( ∗ i n i t ) ( const b t s t a c k u a r t c o n f i g t ∗ u a r t c o n f i g ) ;
/∗ ∗
∗ open t r a n s p o r t c o n n e c t i o n
∗/
int ( ∗ open ) ( void ) ;
/∗ ∗
364
∗ c l o s e transport connection
∗/
int ( ∗ c l o s e ) ( void ) ;
/∗ ∗
∗ s e t c a l l b a c k f o r b l o c k r e c e i v e d . NULL d i s a b l e s c a l l b a c k
∗/
void ( ∗ s e t b l o c k r e c e i v e d ) ( void ( ∗ b l o c k h a n d l e r ) ( void ) ) ;
/∗ ∗
∗ s e t c a l l b a c k f o r s e n t . NULL d i s a b l e s c a l l b a c k
∗/
void ( ∗ s e t b l o c k s e n t ) ( void ( ∗ b l o c k h a n d l e r ) ( void ) ) ;
/∗ ∗
∗ set baudrate
∗/
int ( ∗ s e t b a u d r a t e ) ( uint32 t b a u d r a t e ) ;
/∗ ∗
∗ set parity
∗/
int ( ∗ s e t p a r i t y ) ( int p a r i t y ) ;
/∗ ∗
∗ set flowcontrol
∗/
int ( ∗ s e t f l o w c o n t r o l ) ( int f l o w c o n t r o l ) ;
/∗ ∗
∗ receive block
∗/
void ( ∗ r e c e i v e b l o c k ) ( uint8 t ∗ b u f f e r , uint16 t l e n ) ;
/∗ ∗
∗ send b l o c k
∗/
void ( ∗ s e n d b l o c k ) ( const uint8 t ∗ b u f f e r , uint16 t l e n g t h ) ;
/∗ ∗
∗ q u e r y s u p p o r t e d wakeup mechanisms
∗ @return s u p p o r t e d s l e e p m o d e s mask
∗/
int ( ∗ g e t s u p p o r t e d s l e e p m o d e s ) ( void ) ;
/∗ ∗
∗ s e t UART s l e e p mode − a l l o w s t o t u r n o f f UART and i t ’ s c l o c k s
to save energy
∗ S u p p o r t e d s l e e p modes :
365
/∗ ∗
∗ s e t wakeup h a n d l e r − needed t o n o t i f y h c i t r a n s p o r t o f wakeup
r e q u e s t s by B l u e t o o t h c o n t r o l l e r
∗ C a l l e d upon CTS p u l s e or RX d a t a . See s l e e p modes .
∗/
void ( ∗ s e t w a k e u p h a n d l e r ) ( void ( ∗ wakeup handler ) ( void ) ) ;
/∗ ∗
∗ H5/SLIP o n l y : s e t c a l l b a c k f o r frame r e c e i v e d . NULL d i s a b l e s
callback
∗/
void ( ∗ s e t f r a m e r e c e i v e d ) ( void ( ∗ f r a m e h a n d l e r ) ( uint16 t
frame size ) ) ;
/∗ ∗
∗ H5/SLIP o n l y : s e t c a l l b a c k f o r frame s e n t . NULL d i s a b l e s
callback
∗/
void ( ∗ s e t f r a m e s e n t ) ( void ( ∗ b l o c k h a n d l e r ) ( void ) ) ;
/∗ ∗
∗ H5/SLIP o n l y : r e c e i v e SLIP frame
∗/
void ( ∗ r e c e i v e f r a m e ) ( uint8 t ∗ b u f f e r , uint16 t l e n ) ;
/∗ ∗
∗ H5/SLIP o n l y : send SLIP frame
∗/
void ( ∗ s e n d f r a m e ) ( const uint8 t ∗ b u f f e r , uint16 t l e n g t h ) ;
} btstack uart t ;
1.50. UART Block API. btstack uart block.h : Compatibility layer for
ports that use btstack uart block t
typedef b t s t a c k u a r t t b t s t a c k u a r t b l o c k t ;
// e x i s t i n g b l o c k −o n l y i m p l e m e n t a t i o n s
366
const b t s t a c k u a r t b l o c k t ∗ b t s t a c k u a r t b l o c k w i n d o w s i n s t a n c e (
void ) ;
const b t s t a c k u a r t b l o c k t ∗ b t s t a c k u a r t b l o c k e m b e d d e d i n s t a n c e (
void ) ;
const b t s t a c k u a r t b l o c k t ∗ b t s t a c k u a r t b l o c k f r e e r t o s i n s t a n c e (
void ) ;
// mapper f o r e x t e n d e d i m p l e m e n t a t i o n
s t a t i c i n l i n e const b t s t a c k u a r t b l o c k t ∗
b t s t a c k u a r t b l o c k p o s i x i n s t a n c e ( void ) {
return ( const b t s t a c k u a r t b l o c k t ∗ )
btstack uart posix instance () ;
}
/∗ API STOP ∗/
#i f d e f i n e d cplusplus
}
#endif
#endif
1.51. UART SLIP Wrapper API. btstack uart slip wrapper.h : Com-
patibility layer to use new H5 implementation with btstack uart.h implemen-
tations without SLIP support. Using this compatibility layer caused increased
processing as it uses single byte UART reads.
If you’re using H5, please consider implement the H5/SLIP functions in your
btstack uart.h or hal uart dma.h implementation.
/∗ ∗
∗ @ b r i e f I n i t i a l i z e SLIP wrapper f o r e x i s t i n g b t s t a c k u a r t b l o c k t
i n s t a n c e w i t h o u t SLIP s u p p o r t
∗ @param u a r t b l o c k w i t h o u t s l i p
∗ @return b t s t a c k u a r t t i n s t a n c e w i t h SLIP s u p p o r t f o r use w i t h
hci trasnport h5
∗/
const b t s t a c k u a r t t ∗ b t s t a c k u a r t s l i p w r a p p e r i n s t a n c e ( const
btstack uart t ∗ uart without slip ) ;
/∗ ∗
∗ @ b r i e f Minimum f u n c t i o n f o r u i n t 3 2 t
∗ @param a
∗ @param b
∗ @return v a l u e
∗/
uint32 t b t s t a c k m i n ( uint32 t a , uint32 t b ) ;
/∗ ∗
367
∗ @ b r i e f Maximum f u n c t i o n f o r u i n t 3 2 t
∗ @param a
∗ @param b
∗ @return v a l u e
∗/
uint32 t btstack max ( uint32 t a , uint32 t b ) ;
/∗ ∗
∗ @ b r i e f C a l c u l a t e d e l t a b e t w e e n two u i n t 3 2 t p o i n t s i n time
∗ @return t i m e a − t i m e b − r e s u l t > 0 i f t i m e a i s newer than
time b
∗/
i n t 3 2 t b t s t a c k t i m e d e l t a ( uint32 t ti me a , uint32 t t i m e b ) ;
/∗ ∗
∗ @ b r i e f C a l c u l a t e d e l t a b e t w e e n two u i n t 1 6 t p o i n t s i n time
∗ @return t i m e a − t i m e b − r e s u l t > 0 i f t i m e a i s newer than
time b
∗/
i n t 1 6 t b t s t a c k t i m e 1 6 d e l t a ( uint16 t ti me a , uint16 t t i m e b ) ;
/∗ ∗
∗ @ b r i e f Read 16/24/32 b i t l i t t l e endian v a l u e from buffer
∗ @param b u f f e r
∗ @param p o s i t i o n i n b u f f e r
∗ @return v a l u e
∗/
uint16 t l i t t l e e n d i a n r e a d 1 6 ( const uint8 t ∗ b u f f e r , int p o s i t i o n )
;
uint32 t l i t t l e e n d i a n r e a d 2 4 ( const uint8 t ∗ b u f f e r , int p o s i t i o n )
;
uint32 t l i t t l e e n d i a n r e a d 3 2 ( const uint8 t ∗ b u f f e r , int p o s i t i o n )
;
/∗ ∗
∗ @ b r i e f Write 16/32 b i t l i t t l e endian v a l u e into buffer
∗ @param b u f f e r
∗ @param p o s i t i o n i n b u f f e r
∗ @param v a l u e
∗/
void l i t t l e e n d i a n s t o r e 1 6 ( uint8 t ∗ b u f f e r , uint16 t p o s i t i o n ,
uint16 t v a l u e ) ;
void l i t t l e e n d i a n s t o r e 2 4 ( uint8 t ∗ b u f f e r , uint16 t p o s i t i o n ,
uint32 t v a l u e ) ;
void l i t t l e e n d i a n s t o r e 3 2 ( uint8 t ∗ b u f f e r , uint16 t p o s i t i o n ,
uint32 t v a l u e ) ;
/∗ ∗
∗ @ b r i e f Read 16/24/32 b i t b i g endian v a l u e from b u f f e r
∗ @param b u f f e r
∗ @param p o s i t i o n i n b u f f e r
∗ @return v a l u e
∗/
uint32 t b i g e n d i a n r e a d 1 6 ( const uint8 t ∗ b u f f e r , int p o s i t i o n ) ;
368
/∗ ∗
∗ @ b r i e f Write 16/32 b i t b i g endian v a l u e i n t o b u f f e r
∗ @param b u f f e r
∗ @param p o s i t i o n i n buffer
∗ @param v a l u e
∗/
void b i g e n d i a n s t o r e 1 6 ( uint8 t ∗ b u f f e r , uint16 t p o s i t i o n ,
uint16 t v a l u e ) ;
void b i g e n d i a n s t o r e 2 4 ( uint8 t ∗ b u f f e r , uint16 t p o s i t i o n ,
uint32 t v a l u e ) ;
void b i g e n d i a n s t o r e 3 2 ( uint8 t ∗ b u f f e r , uint16 t p o s i t i o n ,
uint32 t v a l u e ) ;
/∗ ∗
∗ @ b r i e f Swap b y t e s i n 16 b i t i n t e g e r
∗/
s t a t i c i n l i n e uint16 t b t s t a c k f l i p 1 6 ( uint16 t v a l u e ) {
return ( uint16 t ) ( ( v a l u e & 0 x f f u ) << 8 ) | ( v a l u e >> 8 ) ;
}
/∗ ∗
∗ @ b r i e f Check f o r b i g endian system
∗ @return 1 i f on b i g endian
∗/
s t a t i c i n l i n e int b t s t a c k i s b i g e n d i a n ( void ) {
uint16 t sample = 0 x0100 ;
return ( int ) ∗ ( uint8 t ∗ ) &sample ;
}
/∗ ∗
∗ @ b r i e f Check f o r l i t t l e endian system
∗ @return 1 i f on l i t t l e endian
∗/
s t a t i c i n l i n e int b t s t a c k i s l i t t l e e n d i a n ( void ) {
uint16 t sample = 0 x0001 ;
return ( int ) ∗ ( uint8 t ∗ ) &sample ;
}
/∗ ∗
∗ @ b r i e f Copy from s o u r c e t o d e s t i n a t i o n and r e v e r s e b y t e o r d e r
∗ @param s r c
∗ @param d e s t
∗ @param l e n
∗/
void r e v e r s e b y t e s ( const uint8 t ∗ s r c , uint8 t ∗ d e s t , int l e n ) ;
/∗ ∗
∗ @ b r i e f Wrapper around r e v e r s e b y t e s f o r common b u f f e r s i z e s
∗ @param s r c
∗ @param d e s t
369
∗/
void reverse 2 4 ( const uint8 t ∗ src , uint8 t ∗ dest ) ;
void reverse 4 8 ( const uint8 t ∗ src , uint8 t ∗ dest ) ;
void reverse 5 6 ( const uint8 t ∗ src , uint8 t ∗ dest ) ;
void reverse 6 4 ( const uint8 t ∗ src , uint8 t ∗ dest ) ;
void reverse 1 2 8 ( const uint8 t ∗ src , uint8 t ∗ dest ) ;
void reverse 2 5 6 ( const uint8 t ∗ src , uint8 t ∗ dest ) ;
/∗ ∗
∗ @ b r i e f Check i f a l l b y t e s i n b u f f e r a r e z e r o
∗ @param b u f f e r
∗ @param s i z e
∗ @return t r u e i f a l l b y t e s i s b u f f e r a r e z e r o
∗/
b o o l b t s t a c k i s n u l l ( const uint8 t ∗ b u f f e r , uint16 t s i z e ) ;
/∗ ∗
∗ @ b r i e f Check i f a l l b y t e s i n a b d a d d r t a r e z e r o
∗ @param addr
∗ @return t r u e i f a l l b y t e s i n addr a r e z e r o
∗/
b o o l b t s t a c k i s n u l l b d a d d r ( const bd addr t addr ) ;
/∗ ∗
∗ @ b r i e f ASCII c h a r a c t e r f o r 4− b i t n i b b l e
∗ @return c h a r a c t e r
∗/
char c h a r f o r n i b b l e ( uint8 t n i b b l e ) ;
/∗ ∗
∗ @ b r i f 4− b i t n i b b l e from ASCII c h a r a c t e r
∗ @return v a l u e
∗/
int n i b b l e f o r c h a r ( char c ) ;
/∗ ∗
∗ @ b r i e f Compare two B l u e t o o t h a d d r e s s e s
∗ @param a
∗ @param b
∗ @return 0 i f e q u a l
∗/
int bd addr cmp ( const bd addr t a , const bd addr t b ) ;
/∗ ∗
∗ @ b r i e f Copy B l u e t o o t h a d d r e s s
∗ @param d e s t
∗ @param s r c
∗/
void b d a d d r c o p y ( bd addr t d e s t , const bd addr t s r c ) ;
/∗ ∗
∗ @ b r i e f Use p r i n t f t o w r i t e hexdump as s i n g l e l i n e o f d a t a
370
∗/
void p r i n t f h e x d u m p ( const void ∗ data , int s i z e ) ;
/∗ ∗
∗ @ b r i e f C r ea t e human r e a d a b l e r e p r e s e n t a t i o n f o r UUID128
∗ @note u s e s f i x e d g l o b a l b u f f e r
∗ @return p o i n t e r t o UUID128 s t r i n g
∗/
char ∗ u u i d 1 2 8 t o s t r ( const uint8 t ∗ uuid ) ;
/∗ ∗
∗ @ b r i e f C r ea t e human r e a d a b l e r e p r e s e n a t i o n t o f B l u e t o o t h a d d r e s s
∗ @note u s e s f i x e d g l o b a l b u f f e r
∗ @param d e l i m i t e r
∗ @return p o i n t e r t o B l u e t o o t h a d d r e s s s t r i n g
∗/
char ∗ b d a d d r t o s t r w i t h d e l i m i t e r ( const bd addr t addr , char
delimiter ) ;
/∗ ∗
∗ @ b r i e f C r ea t e human r e a d a b l e r e p r e s e n a t i o n t o f B l u e t o o t h a d d r e s s
∗ @note u s e s f i x e d g l o b a l b u f f e r
∗ @return p o i n t e r t o B l u e t o o t h a d d r e s s s t r i n g
∗/
char ∗ b d a d d r t o s t r ( const bd addr t addr ) ;
/∗ ∗
∗ @brief Replace address p l a c e h o l d e r ’ 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 ’ with
Bluetooth address
∗ @param b u f f e r
∗ @param s i z e
∗ @param a d d r e s s
∗/
void b t s t a c k r e p l a c e b d a d d r p l a c e h o l d e r ( uint8 t ∗ b u f f e r , uint16 t
s i z e , const bd addr t a d d r e s s ) ;
/∗ ∗
∗ @ b r i e f Parse B l u e t o o t h a d d r e s s
∗ @param a d d r e s s s t r i n g
∗ @param b u f f e r f o r p a r s e d a d d r e s s
∗ @return 1 i f s t r i n g was p a r s e d s u c c e s s f u l l y
∗/
int s s c a n f b d a d d r ( const char ∗ a d d r s t r i n g , bd addr t addr ) ;
/∗ ∗
∗ @ b r i e f C o n s t r u c t s UUID128 from 16 or 32 b i t UUID u s i n g B l u e t o o t h
b a s e UUID
∗ @param uuid128 o u t p u t b u f f e r
∗ @param s h o r t u u i d
∗/
void u u i d a d d b l u e t o o t h p r e f i x ( uint8 t ∗ uuid128 , uint32 t
short uuid ) ;
/∗ ∗
371
/∗ ∗
∗ @ b r i e f Parse u n s i g n e d number
∗ @param s t r t o p a r s e
∗ @return v a l u e
∗/
uint32 t b t s t a c k a t o i ( const char ∗ s t r ) ;
/∗ ∗
∗ @ b r i e f Return number o f d i g i t s o f a u i n t 3 2 number
∗ @param u i n t 3 2 n u m b e r
∗ @return n u m d i g i t s
∗/
int s t r i n g l e n f o r u i n t 3 2 ( uint32 t i ) ;
/∗ ∗
∗ @ b r i e f Return number o f s e t b i t s i n a u i n t 3 2 number
∗ @param u i n t 3 2 n u m b e r
∗ @return n u m s e t b i t s
∗/
int c o u n t s e t b i t s u i n t 3 2 ( uint32 t x ) ;
/∗ ∗
∗ @ b r i e f Check CRC8 u s i n g ETSI TS 101 369 V6 . 3 . 0 .
∗ @note Only used by RFCOMM
∗ @param d a t a
∗ @param l e n
∗ @param check sum
∗/
uint8 t b t s t a c k c r c 8 c h e c k ( uint8 t ∗ data , uint16 t l e n , uint8 t
check sum ) ;
/∗ ∗
∗ @ b r i e f C a l c u l a t e CRC8 u s i n g ETSI TS 101 369 V6 . 3 . 0 .
∗ @note Only used by RFCOMM
∗ @param d a t a
∗ @param l e n
∗/
uint8 t b t s t a c k c r c 8 c a l c ( uint8 t ∗ data , uint16 t l e n ) ;
/∗ ∗
∗ @ b r i e f C a l c u l a t e t h e i n i t i a l CRC32 v a l u e u s i n g ISO 3309 (HDLC) ,
p o l y n o m i a l ( normal ) 0 x04c11db7
∗ @note Used by OTS S e r v i c e .
∗
∗ @return The i n i t i a l c r c v a l u e .
∗/
uint32 t b t s t a c k c r c 3 2 i n i t ( void ) ;
372
/∗ ∗
∗ @ b r i e f Update t h e CRC32 v a l u e w i t h new d a t a .
∗
∗ @param c r c The c u r r e n t c r c v a l u e .
∗ @param d a t a P o i n t e r t o a b u f f e r o f \a d a t a l e n b y t e s .
∗ @param d a t a l e n Number o f b y t e s i n t h e \a d a t a b u f f e r .
∗ @return The u p d a t e d c r c v a l u e .
∗/
uint32 t b t s t a c k c r c 3 2 u p d a t e ( uint32 t c r c , const uint8 t ∗ data ,
uint32 t d a t a l e n ) ;
/∗ ∗
∗ @ b r i e f C a l c u l a t e t h e f i n a l CRC32 v a l u e .
∗
∗ @param c r c The c u r r e n t c r c v a l u e .
∗ @return The f i n a l c r c v a l u e .
∗/
uint32 t b t s t a c k c r c 3 2 f i n a l i z e ( uint32 t c r c ) ;
/∗ ∗
∗ @ b r i e f Get n e x t c i d
∗ @param c u r r e n t c i d
∗ @return n e x t c i d s k i p i n g 0
∗/
uint16 t b t s t a c k n e x t c i d i g n o r i n g z e r o ( uint16 t c u r r e n t c i d ) ;
/∗ ∗
∗ @ b r i e f Copy s t r i n g ( up t o d s t s i z e −1 c h a r a c t e r s ) from s r c i n t o
dst b u f f e r with terminating ’\0 ’
∗ @note r e p l a c e s s t r n c p y + d s t [ d s t s i z e −1] = ’ \ 0 ’
∗ @param d s t
∗ @param d s t s i z e
∗ @param s r c
∗ @retun b y t e s c o p i e d i n c l u d i n g t r a i l i n g 0
∗/
uint16 t b t s t a c k s t r c p y ( char ∗ dst , uint16 t d s t s i z e , const char ∗
src ) ;
/∗ ∗
∗ @ b r i e f Append s r c s t r i n g t o s t r i n g i n d s t b u f f e r w i t h t e r m i n a t i n g
’\0 ’
∗ @note max t o t a l s t r i n g l e n g t h w i l l be d s t s i z e −1 c h a r a c t e r s
∗ @param d s t
∗ @param d s t s i z e
∗ @param s r c
∗/
void b t s t a c k s t r c a t ( char ∗ dst , uint16 t d s t s i z e , const char ∗ s r c )
;
/∗ ∗
∗ Returns t h e number o f l e a d i n g 0− b i t s i n x , s t a r t i n g a t t h e most
significant bit position .
∗ I f x i s 0 , the r e s u l t i s undefined .
373
/∗ ∗
∗ @ b r i e f Copy chunk o f d a t a i n t o a v i r t u a l b u f f e r b a c k e d by a
physical buffer .
∗ Used t o p r o v i d e chunk o f d a t a o f l a r g e r b u f f e r t h a t i s
c o n s t r u c t e d on t h e f l y , e . g . s e r i a l i z i n g d a t a s t r u c t
∗
∗ For example , copy f i e l d 2 t o b u f f e r , w i t h b u f f e r o f f s e t = 11
∗
∗ field1 field2 field3 field4 field5 filed6
∗ struct :
−−−−−−−|−−−−−−−|−−−−−−−−−−|−−−−−−−−−−−−−|−−−−−−−|−−−−−−−−−−−−−−
∗ buffer : −−−−−−−−−−−−−−−−−−
∗ result : −−−−|
∗
∗ When a l s o c o p y i n g f i e l d 3 and f i e l d 4 t o b u f f e r , w i t h b u f f e r o f f s e t
= 11
∗
∗ field1 field2 field3 field4 field5 filed6
∗ struct :
−−−−−−−|−−−−−−−|−−−−−−−−−−|−−−−−−−−−−−−−|−−−−−−−|−−−−−−−−−−−−−−
∗ buffer : −−−−−−−−−−−−−−−−−−
∗ result : −−−−|−−−−−−−−−−|−−
∗
∗ @param f i e l d d a t a
∗ @param f i e l d l e n
∗ @param f i e l d o f f s e t p o s i t i o n of f i e l d in complete data b l o c k
∗ @param b u f f e r d a t a
∗ @param b u f f e r l e n
∗ @param b u f f e r o f f s e t p o s i t i o n o f b u f f e r i n c o m p l e t e d a t a b l o c k
∗ @return b y t e s c o p i e d number o f b y t e s a c t u a l l y s t o r e d i n b u f f e r
∗/
uint16 t b t s t a c k v i r t u a l m e m c p y (
const uint8 t ∗ f i e l d d a t a , uint16 t f i e l d l e n , uint16 t
field offset ,
uint8 t ∗ b u f f e r , uint16 t b u f f e r s i z e , uint16 t b u f f e r o f f s e t ) ;
/∗ ∗
∗ @ b r i e f C r ea t e A2DP S i n k s e r v i c e r e c o r d .
∗ @param s e r v i c e
∗ @param s e r v i c e r e c o r d h a n d l e
∗ @param s u p p o r t e d f e a t u r e s 16− b i t bitmap , s e e AVDTP SINK SF ∗
values in avdtp . h
374
/∗ ∗
∗ @ b r i e f I n i t i a l i z e up A2DP S i n k d e v i c e .
∗/
void a 2 d p s i n k i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f C r ea t e a stream e n d p o i n t o f t y p e SINK , and r e g i s t e r media
c od e c by s p e c i f y i n g i t s c a p a b i l i t i e s and t h e d e f a u l t
configuration .
∗ @param m e d i a t y p e see avdtp media type t values in
a v d t p . h ( audio , v i d e o or m u l t i m e d i a )
∗ @param m e d i a c o d e c t y p e see avdtp media codec type t
values in avdtp . h
∗ @param c o d e c c a p a b i l i t i e s media c od e c c a p a b i l i t i e s as
d e f i n e d i n A2DP spec , s e c t i o n 4 − Audio Codec I n t e r o p e r a b i l i t y
Requirements .
∗ @param c o d e c c a p a b i l i t i e s l e n media co d ec c a p a b i l i t i e s l e n g t h
∗ @param c o d e c c o n f i g u r a t i o n d e f a u l t media co d ec
configuration
∗ @param c o d e c c o n f i g u r a t i o n l e n media co de c c o n f i g u r a t i o n l e n g t h
∗
∗ @return l o c a l s t r e a m e n d p o i n t
∗/
avdtp stream endpoint t ∗ a2dp sink create stream endpoint (
a v d t p m e d i a t y p e t media type , a v d t p m e d i a c o d e c t y p e t
media codec type ,
const
uint8 t
∗
codec capabilities
,
uint16 t
codec configuration l
);
/∗ ∗
375
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k f o r t h e A2DP S i n k c l i e n t . I t w i l l
r e c e i v e f o l l o w i n g s u b e v e n t s o f HCI EVENT A2DP META HCI e v e n t
type :
∗ − A2DP SUBEVENT SIGNALING MEDIA CODEC SBC CONFIGURATION :
i n d i c a t e s from remote chosen SBC media c od e c c o n f i g u r a t i o n
∗ − A2DP SUBEVENT SIGNALING MEDIA CODEC OTHER CONFIGURATION:
i n d i c a t e s from remote chosen o t h e r t h e n SBC media co d ec
configuration
∗ − A2DP SUBEVENT STREAM ESTABLISHED:
r e c e i v e d when stream t o a remote d e v i c e i s e s t a b l i s h e d
∗ − A2DP SUBEVENT STREAM STARTED:
r e c e i v e d when stream i s s t a r t e d
∗ − A2DP SUBEVENT STREAM SUSPENDED:
r e c e i v e d when stream i s paused
∗ − A2DP SUBEVENT STREAM STOPED:
r e c e i v e d when stream i s a b o r t e d or s t o p p e d
∗ − A2DP SUBEVENT STREAM RELEASED:
r e c e i v e d when stream i s r e l e a s e d
∗ − A2DP SUBEVENT SIGNALING CONNECTION RELEASED :
r e c e i v e d when s i g n a l i n g c h a n n e l i s d i s c o n n e c t e d
∗
∗ @param c a l l b a c k
∗/
void a 2 d p s i n k r e g i s t e r p a c k e t h a n d l e r ( btstack packet handler t
callback ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r media h a n d l e r f o r t h e A2DP S i n k c l i e n t .
∗ @param c a l l b a c k
∗ @param p a c k e t
∗ @param s i z e
∗/
void a 2 d p s i n k r e g i s t e r m e d i a h a n d l e r ( void ( ∗ c a l l b a c k ) ( uint8 t
l o c a l s e i d , uint8 t ∗ packet , uint16 t s i z e ) ) ;
/∗ ∗
∗ @ b r i e f E s t a b l i s h stream .
∗ @param remote
∗ @param o u t a 2 d p c i d A s s i g n e d A2DP c h a n n e l i d e n t i f i e r used
f o r f u r h t e r A2DP commands .
∗/
uint8 t a 2 d p s i n k e s t a b l i s h s t r e a m ( bd addr t remote , uint16 t ∗
out a2dp cid ) ;
∗ @ b r i e f Accept s t a r t i n g t h e stream on
A2DP SUBEVENT START STREAM REQUESTED e v e n t .
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗/
uint8 t a 2 d p s i n k s t a r t s t r e a m a c c e p t ( uint16 t a 2 d p c i d , uint8 t
local seid ) ;
/∗ ∗
∗ @ b r i e f R e j e c t s t a r t i n g t h e stream on
A2DP SUBEVENT START STREAM REQUESTED e v e n t .
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗/
uint8 t a 2 d p s i n k s t a r t s t r e a m r e j e c t ( uint16 t a 2 d p c i d , uint8 t
local seid ) ;
#endif
/∗ ∗
∗ @ b r i e f R e l e a s e stream and d i s c o n n e c t from remote .
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗/
void a 2 d p s i n k d i s c o n n e c t ( uint16 t a 2 d p c i d ) ;
/∗ ∗
∗ @ b r i e f S e l e c t and c o n f i g u r e SBC e n d p o i n t
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗ @param r e m o t e s e i d ID o f a remote stream e n d p o i n t .
∗ @param c o n f i g u r a t i o n SBC C o n f i g u r a t i o n
∗ @return s t a t u s
∗/
uint8 t a 2 d p s i n k s e t c o n f i g s b c ( uint16 t a 2 d p c i d , uint8 t
l o c a l s e i d , uint8 t r e m o t e s e i d , const a v d t p c o n f i g u r a t i o n s b c t
∗ configuration ) ;
/∗ ∗
∗ @ b r i e f S e l e c t and c o n f i g u r e MPEG AUDIO e n d p o i n t
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗ @param r e m o t e s e i d ID o f a remote stream e n d p o i n t .
∗ @param c o n f i g u r a t i o n MPEG AUDIO C o n f i g u r a t i o n
∗ @return s t a t u s
∗/
uint8 t a 2 d p s i n k s e t c o n f i g m p e g a u d i o ( uint16 t a 2 d p c i d , uint8 t
l o c a l s e i d , uint8 t r e m o t e s e i d , const
avdtp configuration mpeg audio t ∗ configuration ) ;
/∗ ∗
∗ @brief S e l e c t and c o n f i g u r e MPEG AAC e n d p o i n t
∗ @param a2dp cid A2DP c h a n n e l i d e n t i f i e r .
∗ @param local seid ID o f a l o c a l stream e n d p o i n t .
∗ @param remote seid ID o f a remote stream e n d p o i n t .
∗ @param configuration MPEG AAC C o n f i g u r a t i o n
377
∗ @return s t a t u s
∗/
uint8 t a 2 d p s i n k s e t c o n f i g m p e g a a c ( uint16 t a 2 d p c i d , uint8 t
l o c a l s e i d , uint8 t r e m o t e s e i d , const
avdtp configuration mpeg aac t ∗ configuration ) ;
/∗ ∗
∗ @ b r i e f S e l e c t and c o n f i g u r e ATRAC e n d p o i n t
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗ @param r e m o t e s e i d ID o f a remote stream e n d p o i n t .
∗ @param c o n f i g u r a t i o n ATRAC C o n f i g u r a t i o n
∗ @return s t a t u s
∗/
uint8 t a 2 d p s i n k s e t c o n f i g a t r a c ( uint16 t a 2 d p c i d , uint8 t
l o c a l s e i d , uint8 t r e m o t e s e i d , const
avdtp configuration atrac t ∗ configuration ) ;
/∗ ∗
∗ @ b r i e f S e l e c t and c o n f i g u r e Non−A2DP e n d p o i n t . B y t e s 0−3 o f c od ec
i n f o r m a t i o n c o n t a i n Vendor ID , b y t e s 4−5 c o n t a i n Vendor
S p e c i f i c Codec ID ( l i t t l e endian )
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗ @param r e m o t e s e i d ID o f a remote stream e n d p o i n t .
∗ @param m e d i a c o d e c i n f o r m a t i o n
∗ @param m e d i a c o d e c i n f o r m a t i o n l e n
∗ @return s t a t u s
∗/
uint8 t a 2 d p s i n k s e t c o n f i g o t h e r ( uint16 t a 2 d p c i d , uint8 t
l o c a l s e i d , uint8 t r e m o t e s e i d , const uint8 t ∗
m e d i a c o d e c i n f o r m a t i o n , uint8 t m e d i a c o d e c i n f o r m a t i o n l e n ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r media c o n f i g u r a t i o n v a l i d a t o r . Can r e j e c t
i n s u i t a b l e c o n f i g u r a t i o n or r e p o r t stream e n d p o i n t as c u r r e n t l y
busy
∗ @note v a l i d a t o r has t o r e t u r n AVDTP e r r o r c o d e s l i k e :
AVDTP ERROR CODE SEP IN USE or
AVDTP ERROR CODE UNSUPPORTED CONFIGURATION
∗ t h e c a l l b a c k r e c e i v e s t h e media c o n f i g u r a t i o n i n t h e same
f o r m a t as t h e e x i s t i n g
A2dP SUBEVENT SIGNALING MEDIA CODEC SBC CONFIGURATION
∗ and s i m i l a r
∗ @param c a l l b a c k
∗/
void a 2 d p s i n k r e g i s t e r m e d i a c o n f i g v a l i d a t o r ( uint8 t ( ∗ c a l l b a c k ) (
const a v d t p s t r e a m e n d p o i n t t ∗ s t r e a m e n d p o i n t , const uint8 t ∗
event , uint16 t s i z e ) ) ;
/∗ ∗
∗ @ b r i e f De−I n i t A2DP S i n k d e v i c e .
∗/
void a 2 d p s i n k d e i n i t ( void ) ;
378
/∗ ∗
∗ @ b r i e f C r ea t e A2DP Source s e r v i c e r e c o r d .
∗ @param s e r v i c e
∗ @param s e r v i c e r e c o r d h a n d l e
∗ @param s u p p o r t e d f e a t u r e s 16− b i t bitmap , s e e AVDTP SOURCE SF ∗
values in avdtp . h
∗ @param s e r v i c e n a m e or NULL f o r d e f a u l t v a l u e . P r o v i d e ”” ( empty
s t r i n g ) to skip a t t r i b u t e
∗ @param s e r v i c e p r o v i d e r n a m e or NULL f o r d e f a u l t v a l u e . P r o v i d e
”” ( empty s t r i n g ) t o s k i p a t t r i b u t e
∗/
void a 2 d p s o u r c e c r e a t e s d p r e c o r d ( uint8 t ∗ s e r v i c e , uint32 t
s e r v i c e r e c o r d h a n d l e , uint16 t s u p p o r t e d f e a t u r e s , const char ∗
s e r v i c e n a m e , const char ∗ s e r v i c e p r o v i d e r n a m e ) ;
/∗ ∗
∗ @ b r i e f I n i t i a l i z e up A2DP Source d e v i c e .
∗/
void a 2 d p s o u r c e i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f C r ea t e a stream e n d p o i n t o f t y p e SOURCE, and r e g i s t e r
media c o de c by s p e c i f y i n g i t s c a p a b i l i t i e s and t h e d e f a u l t
configuration .
∗ @param m e d i a t y p e See a v d t p m e d i a t y p e t v a l u e s i n
a v d t p . h ( audio , v i d e o or m u l t i m e d i a ) .
∗ @param m e d i a c o d e c t y p e See a v d t p m e d i a c o d e c t y p e t
values in avdtp . h
∗ @param c o d e c c a p a b i l i t i e s Media c od e c c a p a b i l i t i e s as
d e f i n e d i n A2DP spec , s e c t i o n 4 − Audio Codec I n t e r o p e r a b i l i t y
Requirements .
∗ @param c o d e c c a p a b i l i t i e s l e n Media co d ec c a p a b i l i t i e s l e n g t h .
∗ @param c o d e c c o n f i g u r a t i o n D e f a u l t media co d ec
configuration .
∗ @param c o d e c c o n f i g u r a t i o n l e n Media co d ec c o n f i g u r a t i o n l e n g t h
.
∗
∗ @return l o c a l s t r e a m e n d p o i n t
∗/
avdtp stream endpoint t ∗ a2dp source create stream endpoint (
a v d t p m e d i a t y p e t media type , a v d t p m e d i a c o d e c t y p e t
media codec type ,
379
const
uint8 t
∗
codec capabilities
,
uint16 t
codec capabilities le
,
uint8 t
∗
codec configuration
,
uint16 t
codec configuration
);
/∗ ∗
∗ @ b r i e f U n r e g i s t e r stream e n d p o i n t and f r e e i t ’ s memory
∗ @param s t r e a m e n d p o i n t c r e a t e d by
a2dp source create stream endpoint
∗/
void a 2 d p s o u r c e f i n a l i z e s t r e a m e n d p o i n t ( a v d t p s t r e a m e n d p o i n t t ∗
stream endpoint ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k f o r t h e A2DP Source c l i e n t . I t w i l l
r e c e i v e f o l l o w i n g s u b e v e n t s o f HCI EVENT A2DP META HCI e v e n t
type :
∗ − A2DP SUBEVENT STREAMING CAN SEND MEDIA PACKET NOW:
I n d i c a t e s t h a t t h e n e x t media p a c k e t can be s e n t .
∗
∗ − A2DP SUBEVENT SIGNALING CONNECTION ESTABLISHED
R e c e i v e d when s i g n a l i n g c o n n e c t i o n w i t h a remote i s e s t a b l i s h e d
.
∗ − A2DP SUBEVENT SIGNALING CONNECTION RELEASED
R e c e i v e d when s i g n a l i n g c o n n e c t i o n w i t h a remote i s r e l e a s e d
∗ − A2DP SUBEVENT STREAM ESTABLISHED
R e c e i v e d when stream t o a remote d e v i c e i s e s t a b l i s h e d .
∗ − A2DP SUBEVENT STREAM STARTED
R e c e i v e d when stream i s s t a r t e d .
∗ − A2DP SUBEVENT STREAM SUSPENDED
R e c e i v e d when stream i s paused .
∗ − A2DP SUBEVENT STREAM STOPED
r e c e i v e d when stream i s a b o r t e d or s t o p p e d .
∗ − A2DP SUBEVENT STREAM RELEASED
R e c e i v e d when stream i s r e l e a s e d .
∗ − A2DP SUBEVENT SIGNALING DELAY REPORTING CAPABILITY
Currently the only c a p a b i l i t y that i s passed to c l i e n t
∗ − A2DP SUBEVENT SIGNALING CAPABILITIES DONE
S i g n a l s t h a t a l l c a p a b i l i t i e s are reported
∗ − A2DP SUBEVENT SIGNALING DELAY REPORT
Delay r e p o r t
380
/∗ ∗
∗ @ b r i e f Open stream .
∗ @param r e m o t e a d d r
∗ @param a v d t p c i d A s s i g n e d A2DP c h a n n e l i d e n t i f i e r used
f o r f u r t h e r A2DP commands .
∗/
uint8 t a 2 d p s o u r c e e s t a b l i s h s t r e a m ( bd addr t remote addr , uint16 t
∗ avdtp cid ) ;
/∗ ∗
∗ @ b r i e f R e c o n f i g u r e stream .
∗ @param l o c a l s e i d ID a s s i g n e d t o a l o c a l stream
endpoint
∗ @param s a m p l i n g f r e q u e n c y New s a m p l i n g f r e q u e n c y t o use .
Cannot be c a l l e d w h i l e stream i s a c t i v e
∗/
uint8 t a 2 d p s o u r c e r e c o n f i g u r e s t r e a m s a m p l i n g f r e q u e n c y ( uint16 t
a 2 d p c i d , uint32 t s a m p l i n g f r e q u e n c y ) ;
/∗ ∗
∗ @ b r i e f S t a r t stream .
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗/
uint8 t a 2 d p s o u r c e s t a r t s t r e a m ( uint16 t a 2 d p c i d , uint8 t
local seid ) ;
/∗ ∗
∗ @ b r i e f Pause stream .
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗/
uint8 t a 2 d p s o u r c e p a u s e s t r e a m ( uint16 t a 2 d p c i d , uint8 t
local seid ) ;
/∗ ∗
∗ @ b r i e f R e l e a s e stream and d i s c o n n e c t from remote .
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗/
uint8 t a 2 d p s o u r c e d i s c o n n e c t ( uint16 t a 2 d p c i d ) ;
/∗ ∗
381
/∗ ∗
∗ @ b r i e f Return maximal media p a y l o a d s i z e , d o e s not i n c l u d e media
header .
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗ @return m a x m e d i a p a y l o a d s i z e w i t h o u t m e d i a h e a d e r
∗/
int a 2 d p m a x m e d i a p a y l o a d s i z e ( uint16 t a 2 d p c i d , uint8 t
local seid ) ;
/∗ ∗
∗ @ b r i e f Send media p a y l o a d .
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗ @param marker
∗ @param timestamp i n sample r a t e u n i t s
∗ @param p a y l o a d
∗ @param p a y l o a d s i z e
∗ @param marker
∗ @return s t a t u s
∗/
uint8 t a 2 d p s o u r c e s t r e a m s e n d m e d i a p a y l o a d r t p ( uint16 t a 2 d p c i d ,
uint8 t l o c a l s e i d , uint8 t marker , uint32 t timestamp ,
uint8 t ∗ payload , uint16 t
payload size ) ;
/∗ ∗
∗ @ b r i e f Send media p a c k e t
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗ @param p a c k e t
∗ @param s i z e
∗ @return s t a t u s
∗/
uint8 t a 2 d p s o u r c e s t r e a m s e n d m e d i a p a c k e t ( uint16 t a 2 d p c i d ,
uint8 t l o c a l s e i d , const uint8 t ∗ packet , uint16 t s i z e ) ;
/∗ ∗
∗ @ b r i e f S e l e c t and c o n f i g u r e SBC e n d p o i n t
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗ @param r e m o t e s e i d ID o f a remote stream e n d p o i n t .
∗ @param c o n f i g u r a t i o n SBC C o n f i g u r a t i o n
∗ @return s t a t u s
∗/
382
/∗ ∗
∗ @ b r i e f S e l e c t and c o n f i g u r e MPEG AUDIO e n d p o i n t
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗ @param r e m o t e s e i d ID o f a remote stream e n d p o i n t .
∗ @param c o n f i g u r a t i o n MPEG AUDIO C o n f i g u r a t i o n
∗ @return s t a t u s
∗/
uint8 t a 2 d p s o u r c e s e t c o n f i g m p e g a u d i o ( uint16 t a 2 d p c i d , uint8 t
l o c a l s e i d , uint8 t r e m o t e s e i d , const
avdtp configuration mpeg audio t ∗ configuration ) ;
/∗ ∗
∗ @ b r i e f S e l e c t and c o n f i g u r e MPEG AAC e n d p o i n t
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗ @param r e m o t e s e i d ID o f a remote stream e n d p o i n t .
∗ @param c o n f i g u r a t i o n MPEG AAC C o n f i g u r a t i o n
∗ @return s t a t u s
∗/
uint8 t a 2 d p s o u r c e s e t c o n f i g m p e g a a c ( uint16 t a 2 d p c i d , uint8 t
l o c a l s e i d , uint8 t r e m o t e s e i d , const
avdtp configuration mpeg aac t ∗ configuration ) ;
/∗ ∗
∗ @ b r i e f S e l e c t and c o n f i g u r e ATRAC e n d p o i n t
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗ @param r e m o t e s e i d ID o f a remote stream e n d p o i n t .
∗ @param c o n f i g u r a t i o n ATRAC C o n f i g u r a t i o n
∗ @return s t a t u s
∗/
uint8 t a 2 d p s o u r c e s e t c o n f i g a t r a c ( uint16 t a 2 d p c i d , uint8 t
l o c a l s e i d , uint8 t r e m o t e s e i d , const
avdtp configuration atrac t ∗ configuration ) ;
/∗ ∗
∗ @ b r i e f S e l e c t and c o n f i g u r e Non−A2DP e n d p o i n t . B y t e s 0−3 o f c od ec
i n f o r m a t i o n c o n t a i n Vendor ID , b y t e s 4−5 c o n t a i n Vendor
S p e c i f i c Codec ID ( l i t t l e endian )
∗ @param a 2 d p c i d A2DP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗ @param r e m o t e s e i d ID o f a remote stream e n d p o i n t .
∗ @param m e d i a c o d e c i n f o r m a t i o n
∗ @param m e d i a c o d e c i n f o r m a t i o n l e n
∗ @return s t a t u s
∗/
uint8 t a 2 d p s o u r c e s e t c o n f i g o t h e r ( uint16 t a 2 d p c i d , uint8 t
l o c a l s e i d , uint8 t r e m o t e s e i d , const uint8 t ∗
m e d i a c o d e c i n f o r m a t i o n , uint8 t m e d i a c o d e c i n f o r m a t i o n l e n ) ;
383
/∗ ∗
∗ @ b r i e f R e g i s t e r media c o n f i g u r a t i o n v a l i d a t o r . Can r e j e c t
i n s u i t a b l e c o n f i g u r a t i o n or r e p o r t stream e n d p o i n t as c u r r e n t l y
busy
∗ @note v a l i d a t o r has t o r e t u r n AVDTP e r r o r c o d e s l i k e :
AVDTP ERROR CODE SEP IN USE or
AVDTP ERROR CODE UNSUPPORTED CONFIGURATION
∗ t h e c a l l b a c k r e c e i v e s t h e media c o n f i g u r a t i o n i n t h e same
f o r m a t as t h e e x i s t i n g
A2dP SUBEVENT SIGNALING MEDIA CODEC SBC CONFIGURATION
∗ and s i m i l a r
∗ @param c a l l b a c k
∗/
void a 2 d p s o u r c e r e g i s t e r m e d i a c o n f i g v a l i d a t o r ( uint8 t ( ∗ c a l l b a c k )
( const a v d t p s t r e a m e n d p o i n t t ∗ s t r e a m e n d p o i n t , const uint8 t
∗ event , uint16 t s i z e ) ) ;
/∗ ∗
∗ @ b r i e f De−I n i t A2DP Source d e v i c e .
∗/
void a 2 d p s o u r c e d e i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f S e t up AVDTP S i n k d e v i c e .
∗/
void a v d t p s i n k i n i t ( void ) ;
// r e t u r n s a v d t p s t r e a m e n d p o i n t t ∗
avdtp stream endpoint t ∗ avdtp sink create stream endpoint (
a v d t p s e p t y p e t sep type , avdtp media type t media type ) ;
/∗ ∗
∗ @ b r i e f U n r e g i s t e r stream e n d p o i n t and f r e e i t ’ s memory
∗ @param s t r e a m e n d p o i n t c r e a t e d by
avdtp sink create stream endpoint
∗/
void a v d t p s i n k f i n a l i z e s t r e a m e n d p o i n t ( a v d t p s t r e a m e n d p o i n t t ∗
stream endpoint ) ;
void a v d t p s i n k r e g i s t e r m e d i a t r a n s p o r t c a t e g o r y ( uint8 t s e i d ) ;
void a v d t p s i n k r e g i s t e r r e p o r t i n g c a t e g o r y ( uint8 t s e i d ) ;
void a v d t p s i n k r e g i s t e r d e l a y r e p o r t i n g c a t e g o r y ( uint8 t s e i d ) ;
void a v d t p s i n k r e g i s t e r r e c o v e r y c a t e g o r y ( uint8 t s e i d , uint8 t
maximum recovery window size , uint8 t
maximum number media packets ) ;
void a v d t p s i n k r e g i s t e r h e a d e r c o m p r e s s i o n c a t e g o r y ( uint8 t s e i d ,
uint8 t back ch , uint8 t media , uint8 t r e c o v e r y ) ;
384
void a v d t p s i n k r e g i s t e r m e d i a c o d e c c a t e g o r y ( uint8 t s e i d ,
a v d t p m e d i a t y p e t media type , a v d t p m e d i a c o d e c t y p e t
m e d i a c o d e c t y p e , const uint8 t ∗ m e d i a c o d e c i n f o , uint16 t
media codec info len ) ;
void a v d t p s i n k r e g i s t e r c o n t e n t p r o t e c t i o n c a t e g o r y ( uint8 t s e i d ,
uint16 t c p t y p e , const uint8 t ∗ c p t y p e v a l u e , uint8 t
cp type value len ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k f o r t h e AVDTP S i n k c l i e n t .
∗ @param c a l l b a c k
∗/
void a v d t p s i n k r e g i s t e r p a c k e t h a n d l e r ( btstack packet handler t
callback ) ;
/∗ ∗
∗ @ b r i e f Connect t o d e v i c e w i t h a b l u e t o o t h a d d r e s s . ( and perform
c o n f i g u r a t i o n ?)
∗ @param b d a d d r
∗ @param a v d t p c i d A s s i g n e d a v d t p c i d
∗/
uint8 t a v d t p s i n k c o n n e c t ( bd addr t bd addr , uint16 t ∗ a v d t p c i d ) ;
/∗ ∗
∗ @ b r i e f D i s c o v e r stream e n d p o i n t s
∗ @param a v d t p c i d
∗/
uint8 t a v d t p s i n k d i s c o v e r s t r e a m e n d p o i n t s ( uint16 t a v d t p c i d ) ;
/∗ ∗
∗ @ b r i e f Get c a p a b i l i t i e s
∗ @param a v d t p c i d
∗/
uint8 t a v d t p s i n k g e t c a p a b i l i t i e s ( uint16 t a v d t p c i d , uint8 t
acp seid ) ;
/∗ ∗
∗ @ b r i e f Get a l l c a p a b i l i t i e s
∗ @param a v d t p c i d
∗/
uint8 t a v d t p s i n k g e t a l l c a p a b i l i t i e s ( uint16 t a v d t p c i d , uint8 t
acp seid ) ;
385
/∗ ∗
∗ @brief Set configuration
∗ @param a v d t p c i d
∗/
uint8 t a v d t p s i n k s e t c o n f i g u r a t i o n ( uint16 t a v d t p c i d , uint8 t
i n t s e i d , uint8 t a c p s e i d , uint16 t c o n f i g u r e d s e r v i c e s b i t m a p ,
avdtp capabilities t configuration ) ;
/∗ ∗
∗ @ b r i e f R e c o n f i g u r e stream
∗ @param a v d t p c i d
∗ @param s e i d
∗/
uint8 t a v d t p s i n k r e c o n f i g u r e ( uint16 t a v d t p c i d , uint8 t i n t s e i d ,
uint8 t a c p s e i d , uint16 t c o n f i g u r e d s e r v i c e s b i t m a p ,
avdtp capabilities t configuration ) ;
/∗ ∗
∗ @ b r i e f Get c o n f i g u r a t i o n
∗ @param a v d t p c i d
∗/
uint8 t a v d t p s i n k g e t c o n f i g u r a t i o n ( uint16 t a v d t p c i d , uint8 t
acp seid ) ;
/∗ ∗
∗ @ b r i e f Open stream
∗ @param a v d t p c i d
∗ @param s e i d
∗/
uint8 t a v d t p s i n k o p e n s t r e a m ( uint16 t a v d t p c i d , uint8 t i n t s e i d ,
uint8 t a c p s e i d ) ;
/∗ ∗
∗ @ b r i e f S t a r t stream
∗ @param l o c a l s e i d
∗/
uint8 t a v d t p s i n k s t a r t s t r e a m ( uint16 t a v d t p c i d , uint8 t
local seid ) ;
/∗ ∗
∗ @ b r i e f Abort stream
∗ @param l o c a l s e i d
∗/
uint8 t a v d t p s i n k a b o r t s t r e a m ( uint16 t a v d t p c i d , uint8 t
local seid ) ;
/∗ ∗
∗ @ b r i e f S t a r t stream
∗ @param l o c a l s e i d
∗/
uint8 t a v d t p s i n k s t o p s t r e a m ( uint16 t a v d t p c i d , uint8 t
local seid ) ;
386
/∗ ∗
∗ @ b r i e f Suspend stream
∗ @param l o c a l s e i d
∗/
uint8 t a v d t p s i n k s u s p e n d ( uint16 t a v d t p c i d , uint8 t l o c a l s e i d ) ;
/∗ ∗
∗ @ b r i e f Report d e l a y
∗ @param l o c a l s e i d
∗ @param d e l a y 1 0 0 u s
∗/
uint8 t a v d t p s i n k d e l a y r e p o r t ( uint16 t a v d t p c i d , uint8 t
l o c a l s e i d , uint16 t d e l a y 1 0 0 u s ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r media c o n f i g u r a t i o n v a l i d a t o r . Can r e j e c t
i n s u i t a b l e c o n f i g u r a t i o n or r e p o r t stream e n d p o i n t as c u r r e n t l y
busy
∗ @note v a l i d a t o r has t o r e t u r n AVDTP e r r o r c o d e s l i k e :
AVDTP ERROR CODE SEP IN USE or
AVDTP ERROR CODE UNSUPPORTED CONFIGURATION
∗ t h e c a l l b a c k r e c e i v e s t h e media c o n f i g u r a t i o n i n t h e same
f o r m a t as t h e e x i s t i n g
AVDTP SUBEVENT SIGNALING MEDIA CODEC SBC CONFIGURATION
∗ and s i m i l a r
∗ @param c a l l b a c k
∗/
void a v d t p s i n k r e g i s t e r m e d i a c o n f i g v a l i d a t o r ( uint8 t ( ∗ c a l l b a c k ) (
const a v d t p s t r e a m e n d p o i n t t ∗ s t r e a m e n d p o i n t , const uint8 t ∗
event , uint16 t s i z e ) ) ;
/∗ ∗
∗ @ b r i e f De−I n i t AVDTP S i n k .
∗/
void a v d t p s i n k d e i n i t ( void ) ;
// AVDTP SI DELAYREPORT
/∗ ∗
∗ @ b r i e f R e g i s t e r media t r a n s p o r t c a t e g o r y w i t h l o c a l stream
e n d p o i n t i d e n t i f i e d by s e i d
∗ @param s e i d
∗/
void a v d t p s o u r c e r e g i s t e r m e d i a t r a n s p o r t c a t e g o r y ( uint8 t s e i d ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r r e p o r t i n g c a t e g o r y w i t h l o c a l stream e n d p o i n t
i d e n t i f i e d by s e i d
387
∗ @param s e i d
∗/
void a v d t p s o u r c e r e g i s t e r r e p o r t i n g c a t e g o r y ( uint8 t s e i d ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r d e l a y r e p o r t i n g c a t e g o r y w i t h l o c a l stream
e n d p o i n t i d e n t i f i e d by s e i d
∗ @param s e i d
∗/
void a v d t p s o u r c e r e g i s t e r d e l a y r e p o r t i n g c a t e g o r y ( uint8 t s e i d ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r r e c o v e r y c a t e g o r y w i t h l o c a l stream e n d p o i n t
i d e n t i f i e d by s e i d
∗ @param s e i d
∗ @param m a x i m u m r e c o v e r y w i n d o w s i z e
∗ @param maximum number media packets
∗/
void a v d t p s o u r c e r e g i s t e r r e c o v e r y c a t e g o r y ( uint8 t s e i d , uint8 t
maximum recovery window size , uint8 t
maximum number media packets ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c o n t e n t p r o t e c t i o n c a t e g o r y w i t h l o c a l stream
e n d p o i n t i d e n t i f i e d by s e i d
∗ @param s e i d
∗ @param c p t y p e
∗ @param c p t y p e v a l u e
∗ @param c p t y p e v a l u e l e n
∗/
void a v d t p s o u r c e r e g i s t e r c o n t e n t p r o t e c t i o n c a t e g o r y ( uint8 t s e i d ,
uint16 t c p t y p e , const uint8 t ∗ c p t y p e v a l u e , uint8 t
cp type value len ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r h e a d e r c o m p r e s s i o n c a t e g o r y w i t h l o c a l stream
e n d p o i n t i d e n t i f i e d by s e i d
∗ @param s e i d
∗ @param b a c k c h
∗ @param media
∗ @param r e c o v e r y
∗/
void a v d t p s o u r c e r e g i s t e r h e a d e r c o m p r e s s i o n c a t e g o r y ( uint8 t s e i d ,
uint8 t back ch , uint8 t media , uint8 t r e c o v e r y ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r media c od e c c a t e g o r y w i t h l o c a l stream e n d p o i n t
i d e n t i f i e d by s e i d
∗ @param s e i d
∗ @param m e d i a t y p e
∗ @param m e d i a c o d e c t y p e
∗ @param m e d i a c o d e c i n f o
∗ @param m e d i a c o d e c i n f o l e n
∗/
388
void a v d t p s o u r c e r e g i s t e r m e d i a c o d e c c a t e g o r y ( uint8 t s e i d ,
a v d t p m e d i a t y p e t media type , a v d t p m e d i a c o d e c t y p e t
m e d i a c o d e c t y p e , const uint8 t ∗ m e d i a c o d e c i n f o , uint16 t
media codec info len ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r m u l t i p l e x i n g c a t e g o r y w i t h l o c a l stream e n d p o i n t
i d e n t i f i e d by s e i d
∗ @param s e i d
∗ @param f r a g m e n t a t i o n
∗/
void a v d t p s o u r c e r e g i s t e r m u l t i p l e x i n g c a t e g o r y ( uint8 t s e i d ,
uint8 t f r a g m e n t a t i o n ) ;
/∗ ∗
∗ @ b r i e f I n i t i a l i z e up AVDTP Source d e v i c e .
∗/
void a v d t p s o u r c e i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k f o r t h e AVDTP Source c l i e n t . See
b t s t a c k d e f i n e s . h f o r AVDTP SUBEVENT ∗ e v e n t s
∗
∗ @param c a l l b a c k
∗/
void a v d t p s o u r c e r e g i s t e r p a c k e t h a n d l e r ( btstack packet handler t
callback ) ;
/∗ ∗
∗ @ b r i e f Connect t o d e v i c e w i t h a b l u e t o o t h a d d r e s s . ( and perform
c o n f i g u r a t i o n ?)
∗ @param b d a d d r
∗ @param a v d t p c i d A s s i g n e d a v d t p c i d
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s f u l , o t h e r w i s e
BTSTACK MEMORY ALLOC FAILED, SDP QUERY BUSY
∗/
uint8 t a v d t p s o u r c e c o n n e c t ( bd addr t bd addr , uint16 t ∗ a v d t p c i d
);
/∗ ∗
∗ @ b r i e f D i s c o n n e c t from d e v i c e w i t h c o n n e c t i o n h a n d l e .
∗ @param a v d t p c i d
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER
∗/
uint8 t a v d t p s o u r c e d i s c o n n e c t ( uint16 t a v d t p c i d ) ;
/∗ ∗
∗ @ b r i e f D i s c o v e r stream e n d p o i n t s
∗ @param a v d t p c i d
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
389
uint8 t a v d t p s o u r c e d i s c o v e r s t r e a m e n d p o i n t s ( uint16 t a v d t p c i d ) ;
/∗ ∗
∗ @ b r i e f Get c a p a b i l i t i e s
∗ @param a v d t p c i d
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
uint8 t a v d t p s o u r c e g e t c a p a b i l i t i e s ( uint16 t a v d t p c i d , uint8 t
acp seid ) ;
/∗ ∗
∗ @ b r i e f Get a l l c a p a b i l i t i e s
∗ @param a v d t p c i d
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
uint8 t a v d t p s o u r c e g e t a l l c a p a b i l i t i e s ( uint16 t a v d t p c i d ,
uint8 t a c p s e i d ) ;
/∗ ∗
∗ @brief Set configuration
∗ @param a v d t p c i d
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
uint8 t a v d t p s o u r c e s e t c o n f i g u r a t i o n ( uint16 t a v d t p c i d , uint8 t
i n t s e i d , uint8 t a c p s e i d , uint16 t c o n f i g u r e d s e r v i c e s b i t m a p ,
avdtp capabilities t configuration ) ;
/∗ ∗
∗ @ b r i e f R e c o n f i g u r e stream
∗ @param a v d t p c i d
∗ @param s e i d
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
uint8 t a v d t p s o u r c e r e c o n f i g u r e ( uint16 t a v d t p c i d , uint8 t
i n t s e i d , uint8 t a c p s e i d , uint16 t c o n f i g u r e d s e r v i c e s b i t m a p ,
avdtp capabilities t configuration ) ;
/∗ ∗
∗ @ b r i e f Get c o n f i g u r a t i o n
∗ @param a v d t p c i d
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
uint8 t a v d t p s o u r c e g e t c o n f i g u r a t i o n ( uint16 t a v d t p c i d , uint8 t
acp seid ) ;
390
/∗ ∗
∗ @ b r i e f Open stream
∗ @param a v d t p c i d
∗ @param s e i d
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
uint8 t a v d t p s o u r c e o p e n s t r e a m ( uint16 t a v d t p c i d , uint8 t
i n t s e i d , uint8 t a c p s e i d ) ;
/∗ ∗
∗ @ b r i e f S t a r t stream
∗ @param l o c a l s e i d
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
uint8 t a v d t p s o u r c e s t a r t s t r e a m ( uint16 t a v d t p c i d , uint8 t
local seid ) ;
/∗ ∗
∗ @ b r i e f Abort stream
∗ @param l o c a l s e i d
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
uint8 t a v d t p s o u r c e a b o r t s t r e a m ( uint16 t a v d t p c i d , uint8 t
local seid ) ;
/∗ ∗
∗ @ b r i e f S t a r t stream
∗ @param l o c a l s e i d
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
uint8 t a v d t p s o u r c e s t o p s t r e a m ( uint16 t a v d t p c i d , uint8 t
local seid ) ;
/∗ ∗
∗ @ b r i e f Suspend stream
∗ @param l o c a l s e i d
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
uint8 t a v d t p s o u r c e s u s p e n d ( uint16 t a v d t p c i d , uint8 t l o c a l s e i d )
;
/∗ ∗
391
∗ @ b r i e f C r ea t e stream e n d p o i n t
∗ @param s e p t y p e AVDTP SOURCE or AVDTP SINK, s e e a v d t p . h
∗ @param m e d i a t y p e AVDTP AUDIO, AVDTP VIDEO or
AVDTP MULTIMEDIA, s e e a v d t p . h
∗ @return p o i n t e r t o newly c r e a t e d stream e n d p o i n t , or NULL i f
allocation failed
∗/
avdtp stream endpoint t ∗ avdtp source create stream endpoint (
a v d t p s e p t y p e t sep type , avdtp media type t media type ) ;
/∗ ∗
∗ @ b r i e f U n r e g i s t e r stream e n d p o i n t and f r e e i t ’ s memory
∗ @param s t r e a m e n d p o i n t c r e a t e d by
avdtp sink create stream endpoint
∗/
void a v d t p s o u r c e f i n a l i z e s t r e a m e n d p o i n t ( a v d t p s t r e a m e n d p o i n t t ∗
stream endpoint ) ;
/∗ ∗
∗ @ b r i e f Send media p a c k e t
∗ @param a v d t p c i d AVDTP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗ @param p a c k e t
∗ @param s i z e
∗ @return s t a t u s
∗/
uint8 t a v d t p s o u r c e s t r e a m s e n d m e d i a p a c k e t ( uint16 t a v d t p c i d ,
uint8 t l o c a l s e i d , const uint8 t ∗ packet , uint16 t s i z e ) ;
/∗ ∗
∗ @ b r i e f Send media p a y l o a d i n c l u d i n g RTP h e a d e r
∗ @param a v d t p c i d AVDTP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗ @param marker
∗ @param timestamp i n sample r a t e u n i t s
∗ @param p a y l o a d
∗ @param s i z e
∗ @return s t a t u s
∗/
uint8 t a v d t p s o u r c e s t r e a m s e n d m e d i a p a y l o a d r t p ( uint16 t
a v d t p c i d , uint8 t l o c a l s e i d , uint8 t marker , uint32 t
timestamp ,
const uint8 t ∗ payload ,
uint16 t s i z e ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t t o send a media p a c k e t . P a c ke t can be t h e n s e n t on
reception of
AVDTP SUBEVENT STREAMING CAN SEND MEDIA PACKET NOW e v e n t .
∗ @param a v d t p c i d AVDTP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗/
void a v d t p s o u r c e s t r e a m e n d p o i n t r e q u e s t c a n s e n d n o w ( uint16 t
avddp cid , uint8 t l o c a l s e i d ) ;
392
/∗ ∗
∗ @ b r i e f Return maximal media p a y l o a d s i z e , d o e s not i n c l u d e media
header .
∗ @param a v d t p c i d AVDTP c h a n n e l i d e n t i f i e r .
∗ @param l o c a l s e i d ID o f a l o c a l stream e n d p o i n t .
∗/
int a v d t p m a x m e d i a p a y l o a d s i z e ( uint16 t a v d t p c i d , uint8 t
local seid ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r media c o n f i g u r a t i o n v a l i d a t o r . Can r e j e c t
i n s u i t a b l e c o n f i g u r a t i o n or r e p o r t stream e n d p o i n t as c u r r e n t l y
busy
∗ @note v a l i d a t o r has t o r e t u r n AVDTP e r r o r c o d e s l i k e :
AVDTP ERROR CODE SEP IN USE or
AVDTP ERROR CODE UNSUPPORTED CONFIGURATION
∗ t h e c a l l b a c k r e c e i v e s t h e media c o n f i g u r a t i o n i n t h e same
f o r m a t as t h e e x i s t i n g
AVDTP SUBEVENT SIGNALING MEDIA CODEC SBC CONFIGURATION
∗ and s i m i l a r
∗ @param c a l l b a c k
∗/
void a v d t p s o u r c e r e g i s t e r m e d i a c o n f i g v a l i d a t o r ( uint8 t ( ∗ c a l l b a c k
) ( const a v d t p s t r e a m e n d p o i n t t ∗ s t r e a m e n d p o i n t , const uint8 t
∗ event , uint16 t s i z e ) ) ;
/∗ ∗
∗ @ b r i e f De−I n i t AVDTP Source .
∗/
void a v d t p s o u r c e d e i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f S e t up AVRCP Browsing s e r v i c e
∗/
void a v r c p b r o w s i n g i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k f o r t h e AVRCP Browsing C o n t r o l l e r c l i e n t
.
∗ @param c a l l b a c k
∗/
void a v r c p b r o w s i n g r e g i s t e r p a c k e t h a n d l e r ( btstack packet handler t
callback ) ;
/∗ ∗
∗ @brief Connect t o AVRCP Browsing s e r v i c e on a remote d e v i c e ,
e m i t s AVRCP SUBEVENT BROWSING CONNECTION ESTABLISHED w i t h
status
∗ @param remote addr
393
/∗ ∗
∗ @ b r i e f C o n f i g u r e incoming c o n n e c t i o n f o r Browsing S e r v i c e .
∗ @param a v r c p b r o w s i n g c i d
∗ @param e r t m b u f f e r
∗ @param e r t m b u f f e r s i z e
∗ @param e r t m c o n f i g
∗ @return s t a t u s
∗/
uint8 t a v r c p b r o w s i n g c o n f i g u r e i n c o m i n g c o n n e c t i o n ( uint16 t
a v r c p b r o w s i n g c i d , uint8 t ∗ e r t m b u f f e r , uint32 t
ertm buffer size , l2cap ertm config t ∗ ertm config ) ;
/∗ ∗
∗ @ b r i e f D e c l i n e incoming c o n n e c t i o n Browsing S e r v i c e .
∗ @param a v r c p b r o w s i n g c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p b r o w s i n g d e c l i n e i n c o m i n g c o n n e c t i o n ( uint16 t
avrcp browsing cid ) ;
/∗ ∗
∗ @brief D i s c o n n e c t from AVRCP Browsing s e r v i c e
∗ @param avrcp browsing cid
∗ @return s t a t u s
∗/
uint8 t a v r c p b r o w s i n g d i s c o n n e c t ( uint16 t a v r c p b r o w s i n g c i d ) ;
/∗ ∗
∗ @ b r i e f De−I n i t AVRCP Browsing
∗/
void a v r c p b r o w s i n g d e i n i t ( void ) ;
typedef enum {
AVRCP BROWSING MEDIA PLAYER ITEM = 0 x01 ,
AVRCP BROWSING FOLDER ITEM,
AVRCP BROWSING MEDIA ELEMENT ITEM,
AVRCP BROWSING MEDIA ROOT FOLDER,
AVRCP BROWSING MEDIA ELEMENT ITEM ATTRIBUTE
} avrcp browsing item type t ;
394
typedef enum {
AVRCP BROWSING MEDIA PLAYER MAJOR TYPE AUDIO = 1 ,
AVRCP BROWSING MEDIA PLAYER MAJOR TYPE VIDEO = 2 ,
AVRCP BROWSING MEDIA PLAYER MAJOR TYPE BROADCASTING AUDIO = 4 ,
AVRCP BROWSING MEDIA PLAYER MAJOR TYPE BROADCASTING VIDEO = 8
} avrcp browsing media player major type t ;
typedef enum {
AVRCP BROWSING MEDIA PLAYER SUBTYPE AUDIO BOOK = 1 ,
AVRCP BROWSING MEDIA PLAYER SUBTYPE POADCAST = 2
} avrcp browsing media player subtype t ;
typedef enum {
AVRCP BROWSING MEDIA PLAYER STATUS STOPPED = 0 ,
AVRCP BROWSING MEDIA PLAYER STATUS PLAYING,
AVRCP BROWSING MEDIA PLAYER STATUS PAUSED,
AVRCP BROWSING MEDIA PLAYER STATUS FWD SEEK,
AVRCP BROWSING MEDIA PLAYER STATUS REV SEEK,
AVRCP BROWSING MEDIA PLAYER STATUS ERROR = 0xFF
} avrcp browsing media player status t ;
typedef enum {
AVRCP BROWSING FOLDER TYPE MIXED = 0 x00 ,
AVRCP BROWSING FOLDER TYPE TITLES,
AVRCP BROWSING FOLDER TYPE ALBUMS,
AVRCP BROWSING FOLDER TYPE ARTISTS,
AVRCP BROWSING FOLDER TYPE GENRES,
AVRCP BROWSING FOLDER TYPE PLAYLISTS,
AVRCP BROWSING FOLDER TYPE YEARS
} avrcp browsing folder type t ;
typedef enum {
AVRCP BROWSING MEDIA TYPE AUDIO = 0 x00 ,
AVRCP BROWSING MEDIA TYPE VIDEO
} avrcp browsing media type t ;
/∗ ∗
∗ @ b r i e f S e t up AVRCP Browsing C o n t r o l l e r d e v i c e .
∗/
void a v r c p b r o w s i n g c o n t r o l l e r i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k f o r t h e AVRCP Browsing C o n t r o l l e r c l i e n t
.
∗ @param c a l l b a c k
∗/
void a v r c p b r o w s i n g c o n t r o l l e r r e g i s t e r p a c k e t h a n d l e r (
btstack packet handler t c a l l b a c k ) ;
/∗ ∗
∗ @ b r i e f R e t r i e v e a l i s t o f media p l a y e r s .
∗ @param a v r c p b r o w s i n g c i d
∗ @param s t a r t i t e m
395
∗ @param e n d i t e m
∗ @param a t t r b i t m a p Use AVRCP MEDIA ATTR ALL f o r a l l , and
AVRCP MEDIA ATTR NONE f o r none . Otherwise , s e e
a v r c p m e d i a a t t r i b u t e i d t f o r t h e bitmap p o s i t i o n o f a t t r s .
∗ ∗/
uint8 t a v r c p b r o w s i n g c o n t r o l l e r g e t m e d i a p l a y e r s ( uint16 t
a v r c p b r o w s i n g c i d , uint32 t s t a r t i t e m , uint32 t end item ,
uint32 t a t t r b i t m a p ) ;
/∗ ∗
∗ @ b r i e f R e t r i e v e a l i s t o f f o l d e r s and media i t e m s o f t h e browsed
player .
∗ @param a v r c p b r o w s i n g c i d
∗ @param s t a r t i t e m
∗ @param e n d i t e m
∗ @param a t t r b i t m a p Use AVRCP MEDIA ATTR ALL f o r a l l , and
AVRCP MEDIA ATTR NONE f o r none . Otherwise , s e e
a v r c p m e d i a a t t r i b u t e i d t f o r t h e bitmap p o s i t i o n o f a t t r s .
∗ ∗/
uint8 t a v r c p b r o w s i n g c o n t r o l l e r b r o w s e f i l e s y s t e m ( uint16 t
a v r c p b r o w s i n g c i d , uint32 t s t a r t i t e m , uint32 t end item ,
uint32 t a t t r b i t m a p ) ;
/∗ ∗
∗ @ b r i e f R e t r i e v e a l i s t o f media i t e m s o f t h e browsed p l a y e r .
∗ @param a v r c p b r o w s i n g c i d
∗ @param s t a r t i t e m
∗ @param e n d i t e m
∗ @param a t t r b i t m a p Use AVRCP MEDIA ATTR ALL f o r a l l , and
AVRCP MEDIA ATTR NONE f o r none . Otherwise , s e e
a v r c p m e d i a a t t r i b u t e i d t f o r t h e bitmap p o s i t i o n o f a t t r s .
∗ ∗/
uint8 t a v r c p b r o w s i n g c o n t r o l l e r b r o w s e m e d i a ( uint16 t
a v r c p b r o w s i n g c i d , uint32 t s t a r t i t e m , uint32 t end item ,
uint32 t a t t r b i t m a p ) ;
/∗ ∗
∗ @ b r i e f R e t r i e v e a l i s t o f f o l d e r s and media i t e m s o f t h e
addressed player .
∗ @param a v r c p b r o w s i n g c i d
∗ @param s t a r t i t e m
∗ @param e n d i t e m
∗ @param a t t r b i t m a p Use AVRCP MEDIA ATTR ALL f o r a l l , and
AVRCP MEDIA ATTR NONE f o r none . Otherwise , s e e
a v r c p m e d i a a t t r i b u t e i d t f o r t h e bitmap p o s i t i o n o f a t t r s .
∗ ∗/
uint8 t a v r c p b r o w s i n g c o n t r o l l e r b r o w s e n o w p l a y i n g l i s t ( uint16 t
a v r c p b r o w s i n g c i d , uint32 t s t a r t i t e m , uint32 t end item ,
uint32 t a t t r b i t m a p ) ;
/∗ ∗
∗ @ b r i e f S e t browsed p l a y e r . C a l l i n g t h i s command i s r e q u i r e d p r i o r
t o b r o w s i n g t h e p l a y e r ’ s f i l e system . Some p l a y e r s may s u p p o r t
b r o w s i n g o n l y when s e t as t h e Addressed P l a y e r .
396
∗ @param a v r c p b r o w s i n g c i d
∗ @param b r o w s e d p l a y e r i d
∗/
uint8 t a v r c p b r o w s i n g c o n t r o l l e r s e t b r o w s e d p l a y e r ( uint16 t
a v r c p b r o w s i n g c i d , uint16 t b r o w s e d p l a y e r i d ) ;
/∗ ∗
∗ @ b r i e f Get t o t a l num a t t r i b u t e s
∗ @param a v r c p b r o w s i n g c i d
∗ @param s c o p e
∗/
uint8 t a v r c p b r o w s i n g c o n t r o l l e r g e t t o t a l n r i t e m s f o r s c o p e (
uint16 t a v r c p b r o w s i n g c i d , a v r c p b r o w s i n g s c o p e t s c o p e ) ;
/∗ ∗
∗ @ b r i e f N a v i g a t e one l e v e l up or down i n t h h e v i r t u a l f i l e s y s t e m .
R e q u i r e s t h a t s browsed p l a y e r i s s e t .
∗ @param a v r c p b r o w s i n g c i d
∗ @param d i r e c t i o n 0− f o l d e r up , 1− f o l d e r down
∗ @param f o l d e r u i d 8 bytes long
∗ ∗/
uint8 t a v r c p b r o w s i n g c o n t r o l l e r c h a n g e p a t h ( uint16 t
a v r c p b r o w s i n g c i d , uint8 t d i r e c t i o n , uint8 t ∗ f o l d e r u i d ) ;
uint8 t a v r c p b r o w s i n g c o n t r o l l e r g o u p o n e l e v e l ( uint16 t
avrcp browsing cid ) ;
uint8 t a v r c p b r o w s i n g c o n t r o l l e r g o d o w n o n e l e v e l ( uint16 t
a v r c p b r o w s i n g c i d , uint8 t ∗ f o l d e r u i d ) ;
/∗ ∗
∗ @ b r i e f R e t r i v e s metadata i n f o r m a t i o n ( t i t l e , a r t i s t , album , . . . )
a b o u t a media e l e m e n t w i t h g i v e n u i d .
∗ @param a v r c p b r o w s i n g c i d
∗ @param u i d media e l e m e n t u i d
∗ @param u i d c o u n t e r Used t o d e t e c t change t o t h e media d a t a b a s e
on t a r g e t d e v i c e . A TG d e v i c e t h a t s u p p o r t s t h e UID Counter
s h a l l u p d a t e t h e v a l u e o f t h e c o u n t e r on each change t o t h e
media d a t a b a s e .
∗ @param a t t r b i t m a p 0 x00000000 − r e t r i e v e a l l , c h e k
a v r c p m e d i a a t t r i b u t e i d t in avrcp . h f o r d e t a i l e d b i t p o s i t i o n
description .
∗ @param s c o p e check a v r c p b r o w s i n g s c o p e t in avrcp . h
∗ ∗/
uint8 t a v r c p b r o w s i n g c o n t r o l l e r g e t i t e m a t t r i b u t e s f o r s c o p e (
uint16 t a v r c p b r o w s i n g c i d , uint8 t ∗ uid , uint16 t u i d c o u n t e r
, uint32 t a t t r b i t m a p , a v r c p b r o w s i n g s c o p e t s c o p e ) ;
/∗ ∗
∗ @ b r i e f S e a r c h e s a r e performed from t h e c u r r e n t f o l d e r i n t h e
Browsed P l a y e r s v i r t u a l f i l e s y s t e m . The s e a r c h a p p l i e s t o t h e
c u r r e n t f o l d e r and a l l f o l d e r s b e l o w t h a t .
∗ @param a v r c p b r o w s i n g c i d
∗ @param s e a r c h s t r l e n
∗ @param s e a r c h s t r
397
∗ @return s t a t u s
∗ ∗/
uint8 t a v r c p b r o w s i n g c o n t r o l l e r s e a r c h ( uint16 t a v r c p b r o w s i n g c i d
, uint16 t s e a r c h s t r l e n , char ∗ s e a r c h s t r ) ;
/∗ ∗
∗ @ b r i e f De−I n i t AVRCP Browsing C o n t r o l l e r
∗/
void a v r c p b r o w s i n g c o n t r o l l e r d e i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f S e t up AVRCP Browsing C o n t r o l l e r d e v i c e .
∗/
void a v r c p b r o w s i n g t a r g e t i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k f o r t h e AVRCP Browsing C o n t r o l l e r c l i e n t
.
∗ @param c a l l b a c k
∗/
void a v r c p b r o w s i n g t a r g e t r e g i s t e r p a c k e t h a n d l e r (
btstack packet handler t c a l l b a c k ) ;
/∗ ∗
∗ @ b r i e f Accept s e t browsed p l a y e r
∗ @param b r o w s i n g c i d
∗ @param u i d c o u n t e r
∗ @param b r o w s e d p l a y e r i d
∗ @param r e s p o n s e
∗ @param r e s p o n s e s i z e
∗/
uint8 t a v r c p b r o w s i n g t a r g e t s e n d a c c e p t s e t b r o w s e d p l a y e r (
uint16 t b r o w s i n g c i d , uint16 t u i d c o u n t e r , uint16 t
b r o w s e d p l a y e r i d , uint8 t ∗ r e s p o n s e , uint16 t r e s p o n s e l e n ) ;
/∗ ∗
∗ @ b r i e f R e j e c t s e t browsed p l a y e r
∗ @param b r o w s i n g c i d
∗ @param s t a t u s
∗/
uint8 t a v r c p b r o w s i n g t a r g e t s e n d r e j e c t s e t b r o w s e d p l a y e r (
uint16 t b r o w s i n g c i d , a v r c p s t a t u s c o d e t s t a t u s ) ;
/∗ ∗
∗ @ b r i e f Send answer t o g e t f o l d e r i t e m s q u e r y on e v e n t
AVRCP SUBEVENT BROWSING GET FOLDER ITEMS. The f i r s t b y t e o f
t h i s e v e n t d e f i n e s t h e s c o p e o f t h e query , s e e
avrcp browsing scope t .
∗ @param b r o w s i n g c i d
∗ @param u i d c o u n t e r
398
∗ @param a t t r l i s t
∗ @param a t t r l i s t s i z e
∗/
uint8 t a v r c p b r o w s i n g t a r g e t s e n d g e t f o l d e r i t e m s r e s p o n s e (
uint16 t b r o w s i n g c i d , uint16 t u i d c o u n t e r , uint8 t ∗ a t t r l i s t
, uint16 t a t t r l i s t s i z e ) ;
/∗ ∗
∗ @ b r i e f Send answer t o g e t t o t a l number o f i t e m s q u e r y on e v e n t
AVRCP SUBEVENT BROWSING GET TOTAL NUM ITEMS. The f i r s t b y t e o f
t h i s e v e n t d e f i n e s t h e s c o p e o f t h e query , s e e
avrcp browsing scope t .
∗ @param b r o w s i n g c i d
∗ @param u i d c o u n t e r
∗ @param t o t a l n u m i t e m s
∗/
uint8 t a v r c p b r o w s i n g t a r g e t s e n d g e t t o t a l n u m i t e m s r e s p o n s e (
uint16 t b r o w s i n g c i d , uint16 t u i d c o u n t e r , uint32 t
total num items ) ;
/∗ ∗
∗ @ b r i e f De−I n i t AVRCP Browsing C o n t r o l l e r
∗/
void a v r c p b r o w s i n g t a r g e t d e i n i t ( void ) ;
typedef enum {
AVRCP CONTROLLER SUPPORTED FEATURE CATEGORY PLAYER OR RECORDER =
0,
AVRCP CONTROLLER SUPPORTED FEATURE CATEGORY MONITOR OR AMPLIFIER
,
AVRCP CONTROLLER SUPPORTED FEATURE CATEGORY TUNER,
AVRCP CONTROLLER SUPPORTED FEATURE CATEGORY MENU,
AVRCP CONTROLLER SUPPORTED FEATURE RESERVED 4,
AVRCP CONTROLLER SUPPORTED FEATURE RESERVED 5,
AVRCP CONTROLLER SUPPORTED FEATURE BROWSING,
AVRCP CONTROLLER SUPPORTED FEATURE COVER ART GET IMAGE PROPERTIES
,
AVRCP CONTROLLER SUPPORTED FEATURE COVER ART GET IMAGE,
AVRCP CONTROLLER SUPPORTED FEATURE COVER ART GET LINKED THUMBNAIL
/∗ ∗
∗ @ b r i e f AVRCP C o n t r o l l e r s e r v i c e r e c o r d .
∗ @param s e r v i c e
∗ @param s e r v i c e r e c o r d h a n d l e
∗ @param s u p p o r t e d f e a t u r e s 16− b i t bitmap , s e e AVRCP FEATURE MASK ∗
in avrcp . h
∗ @param s e r v i c e n a m e or NULL f o r d e f a u l t v a l u e . P r o v i d e ”” ( empty
s t r i n g ) to skip a t t r i b u t e
399
∗ @param s e r v i c e p r o v i d e r n a m e or NULL f o r d e f a u l t v a l u e . P r o v i d e
”” ( empty s t r i n g ) t o s k i p a t t r i b u t e
∗/
void a v r c p c o n t r o l l e r c r e a t e s d p r e c o r d ( uint8 t ∗ s e r v i c e , uint32 t
s e r v i c e r e c o r d h a n d l e , uint16 t s u p p o r t e d f e a t u r e s , const char ∗
s e r v i c e n a m e , const char ∗ s e r v i c e p r o v i d e r n a m e ) ;
/∗ ∗
∗ @ b r i e f S e t up AVRCP C o n t r o l l e r s e r v i c e .
∗/
void a v r c p c o n t r o l l e r i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k f o r t h e AVRCP C o n t r o l l e r c l i e n t .
∗ @param c a l l b a c k
∗/
void a v r c p c o n t r o l l e r r e g i s t e r p a c k e t h a n d l e r (
btstack packet handler t c a l l b a c k ) ;
/∗ ∗
∗ @ b r i e f S e t max num f r a g m e n t s i n whuch message can be t r a n s m i t e d .
∗ @param a v r c p c i d
∗ @param max num fragments
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r s e t m a x n u m f r a g m e n t s ( uint16 t a v r c p c i d ,
uint8 t max num fragments ) ;
/∗ ∗
∗ @ b r i e f Unit i n f o .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r u n i t i n f o ( uint16 t a v r c p c i d ) ;
/∗ ∗
∗ @brief Subunit info .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r s u b u n i t i n f o ( uint16 t a v r c p c i d ) ;
/∗ ∗
∗ @ b r i e f Get c a p a b i l i t i e s .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r g e t s u p p o r t e d c o m p a n y i d s ( uint16 t
avrcp cid ) ;
/∗ ∗
∗ @ b r i e f Get s u p p o r t e d E v en t s .
∗ @param a v r c p c i d
400
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r g e t s u p p o r t e d e v e n t s ( uint16 t a v r c p c i d ) ;
/∗ ∗
∗ @ b r i e f S t a r t c o n t i n u o u s cmd ( p l a y , pause , volume up , . . . ) . Event
AVRCP SUBEVENT OPERATION COMPLETE r e t u r n s o p e r a t i o n i d and
status .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r s t a r t p r e s s a n d h o l d c m d ( uint16 t a v r c p c i d
, avrcp operation id t operation id ) ;
/∗ ∗
∗ @ b r i e f S t o p s c o n t i n u o u s cmd ( p l a y , pause , volume up , . . . ) . Event
AVRCP SUBEVENT OPERATION COMPLETE r e t u r n s o p e r a t i o n i d and
status .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r r e l e a s e p r e s s a n d h o l d c m d ( uint16 t
avrcp cid ) ;
/∗ ∗
∗ @ b r i e f Play . Event AVRCP SUBEVENT OPERATION COMPLETE r e t u r n s
o p e r a t i o n i d and s t a t u s .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r p l a y ( uint16 t a v r c p c i d ) ;
uint8 t a v r c p c o n t r o l l e r p r e s s a n d h o l d p l a y ( uint16 t a v r c p c i d ) ;
/∗ ∗
∗ @ b r i e f Stop . Event AVRCP SUBEVENT OPERATION COMPLETE r e t u r n s
o p e r a t i o n i d and s t a t u s .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r s t o p ( uint16 t a v r c p c i d ) ;
uint8 t a v r c p c o n t r o l l e r p r e s s a n d h o l d s t o p ( uint16 t a v r c p c i d ) ;
/∗ ∗
∗ @ b r i e f Pause . Event AVRCP SUBEVENT OPERATION COMPLETE r e t u r n s
o p e r a t i o n i d and s t a t u s .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r p a u s e ( uint16 t a v r c p c i d ) ;
uint8 t a v r c p c o n t r o l l e r p r e s s a n d h o l d p a u s e ( uint16 t a v r c p c i d ) ;
/∗ ∗
401
∗ @ b r i e f S i n g l e s t e p − f a s t f o r w a r d . Event
AVRCP SUBEVENT OPERATION COMPLETE r e t u r n s o p e r a t i o n i d and
status .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r f a s t f o r w a r d ( uint16 t a v r c p c i d ) ;
uint8 t a v r c p c o n t r o l l e r p r e s s a n d h o l d f a s t f o r w a r d ( uint16 t
avrcp cid ) ;
/∗ ∗
∗ @ b r i e f S i n g l e s t e p rewind . Event
AVRCP SUBEVENT OPERATION COMPLETE r e t u r n s o p e r a t i o n i d and
status .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r r e w i n d ( uint16 t a v r c p c i d ) ;
uint8 t a v r c p c o n t r o l l e r p r e s s a n d h o l d r e w i n d ( uint16 t a v r c p c i d ) ;
/∗ ∗
∗ @ b r i e f Forward . Event AVRCP SUBEVENT OPERATION COMPLETE r e t u r n s
o p e r a t i o n i d and s t a t u s .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r f o r w a r d ( uint16 t a v r c p c i d ) ;
uint8 t a v r c p c o n t r o l l e r p r e s s a n d h o l d f o r w a r d ( uint16 t a v r c p c i d ) ;
/∗ ∗
∗ @ b r i e f Backward . Event AVRCP SUBEVENT OPERATION COMPLETE r e t u r n s
o p e r a t i o n i d and s t a t u s .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r b a c k w a r d ( uint16 t a v r c p c i d ) ;
uint8 t a v r c p c o n t r o l l e r p r e s s a n d h o l d b a c k w a r d ( uint16 t a v r c p c i d )
;
/∗ ∗
∗ @ b r i e f Turns t h e volume t o h i g h . Event
AVRCP SUBEVENT OPERATION COMPLETE r e t u r n s o p e r a t i o n i d and
status .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r v o l u m e u p ( uint16 t a v r c p c i d ) ;
uint8 t a v r c p c o n t r o l l e r p r e s s a n d h o l d v o l u m e u p ( uint16 t a v r c p c i d
);
/∗ ∗
∗ @ b r i e f Turns t h e volume t o low . Event
AVRCP SUBEVENT OPERATION COMPLETE r e t u r n s o p e r a t i o n i d and
status .
402
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r v o l u m e d o w n ( uint16 t a v r c p c i d ) ;
uint8 t a v r c p c o n t r o l l e r p r e s s a n d h o l d v o l u m e d o w n ( uint16 t
avrcp cid ) ;
/∗ ∗
∗ @ b r i e f Puts t h e sound o u t . Event
AVRCP SUBEVENT OPERATION COMPLETE r e t u r n s o p e r a t i o n i d and
status .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r m u t e ( uint16 t a v r c p c i d ) ;
uint8 t a v r c p c o n t r o l l e r p r e s s a n d h o l d m u t e ( uint16 t a v r c p c i d ) ;
/∗ ∗
∗ @ b r i e f Get p l a y s t a t u s . Returns e v e n t o f t y p e
AVRCP SUBEVENT PLAY STATUS ( l e n g t h , p o s i t i o n , p l a y s t a t u s ) .
∗ I f TG d o e s not s u p p o r t SongLength And S o n g P o s i t i o n on TG, t h e n TG
s h a l l r e t u r n 0xFFFFFFFF .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r g e t p l a y s t a t u s ( uint16 t a v r c p c i d ) ;
/∗ ∗
∗ @ b r i e f Enable n o t i f i c a t i o n . Response v i a
AVRCP SUBEVENT NOTIFICATION STATE.
∗ @param a v r c p c i d
∗ @param e v e n t i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r e n a b l e n o t i f i c a t i o n ( uint16 t a v r c p c i d ,
avrcp notification event id t event id ) ;
/∗ ∗
∗ @ b r i e f D i s a b l e n o t i f i c a t i o n . Response v i a
AVRCP SUBEVENT NOTIFICATION STATE.
∗ @param a v r c p c i d
∗ @param e v e n t i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r d i s a b l e n o t i f i c a t i o n ( uint16 t a v r c p c i d ,
avrcp notification event id t event id ) ;
/∗ ∗
∗ @ b r i e f Get i n f o on now p l a y i n g media u s i n g s u b s e t o f a t t r i b u t e
IDs
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
403
uint8 t a v r c p c o n t r o l l e r g e t e l e m e n t a t t r i b u t e s ( uint16 t a v r c p c i d ,
uint8 t n u m a t t r i b u t e s , a v r c p m e d i a a t t r i b u t e i d t ∗ a t t r i b u t e s )
;
/∗ ∗
∗ @ b r i e f Get i n f o on now p l a y i n g media u s i n g a l l IDs .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r g e t n o w p l a y i n g i n f o ( uint16 t a v r c p c i d ) ;
/∗ ∗
∗ @ b r i e f Get i n f o on now p l a y i n g media u s i n g s p e c i f i c media
a t t r i b u t e ID .
∗ @param m e d i a a t t r i b u t e i d
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r g e t n o w p l a y i n g i n f o f o r m e d i a a t t r i b u t e i d
( uint16 t a v r c p c i d , a v r c p m e d i a a t t r i b u t e i d t
media attribute id ) ;
/∗ ∗
∗ @ b r i e f S e t a b s o l u t e volume 0−127 ( c o r r e s p o n d s t o 0−100%) .
Response v i a AVRCP SUBEVENT SET ABSOLUTE VOLUME RESPONSE
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r s e t a b s o l u t e v o l u m e ( uint16 t a v r c p c i d ,
uint8 t volume ) ;
/∗ ∗
∗ @ b r i e f S k i p t o n e x t p l a y i n g media . Event
AVRCP SUBEVENT OPERATION COMPLETE r e t u r n s o p e r a t i o n i d and
status .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r s k i p ( uint16 t a v r c p c i d ) ;
/∗ ∗
∗ @ b r i e f Query r e p e a t and s h u f f l e mode . Response v i a
AVRCP SUBEVENT SHUFFLE AND REPEAT MODE.
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r q u e r y s h u f f l e a n d r e p e a t m o d e s ( uint16 t
avrcp cid ) ;
/∗ ∗
∗ @ b r i e f S e t s h u f f l e mode . Event AVRCP SUBEVENT OPERATION COMPLETE
r e t u r n s o p e r a t i o n i d and s t a t u s .
∗ @param a v r c p c i d
404
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r s e t s h u f f l e m o d e ( uint16 t a v r c p c i d ,
a v r c p s h u f f l e m o d e t mode ) ;
/∗ ∗
∗ @ b r i e f S e t r e p e a t mode . Event AVRCP SUBEVENT OPERATION COMPLETE
r e t u r n s o p e r a t i o n i d and s t a t u s .
∗ @param a v r c p c i d
∗ @return s t a t u s
∗/
uint8 t a v r c p c o n t r o l l e r s e t r e p e a t m o d e ( uint16 t a v r c p c i d ,
a v r c p r e p e a t m o d e t mode ) ;
/∗ ∗
∗ @ b r i e f The PlayItem command s t a r t s p l a y i n g an item i n d i c a t e d by
t h e UID . I t i s r o u t e d t o t h e Addressed P l a y e r .
∗ @param a v r c p c i d
∗ @param u i d
∗ @param u i d c o u n t e r
∗ @param s c o p e
∗ ∗/
uint8 t a v r c p c o n t r o l l e r p l a y i t e m f o r s c o p e ( uint16 t a v r c p c i d ,
uint8 t ∗ uid , uint16 t u i d c o u n t e r , a v r c p b r o w s i n g s c o p e t
scope ) ;
/∗ ∗
∗ @ b r i e f Adds an item i n d i c a t e d by t h e UID t o t h e Now P l a y i n g queue
.
∗ @param a v r c p c i d
∗ @param u i d
∗ @param u i d c o u n t e r
∗ @param s c o p e
∗ ∗/
uint8 t a v r c p c o n t r o l l e r a d d i t e m f r o m s c o p e t o n o w p l a y i n g l i s t (
uint16 t a v r c p c i d , uint8 t ∗ uid , uint16 t u i d c o u n t e r ,
avrcp browsing scope t scope ) ;
/∗ ∗
∗ @brief Set addressed player .
∗ @param a v r c p c i d
∗ @param a d d r e s s e d p l a y e r i d
∗/
uint8 t a v r c p c o n t r o l l e r s e t a d d r e s s e d p l a y e r ( uint16 t a v r c p c i d ,
uint16 t a d d r e s s e d p l a y e r i d ) ;
/∗ ∗
∗ @brief Send custom command
∗ @param avrcp cid
∗ @param command type
∗ @param subunit type
∗ @param subunit id
∗ @param pdu id
∗ @param company id
405
∗ @param d a t a
∗ @param d a t a l e n
∗/
uint8 t a v r c p c o n t r o l l e r s e n d c u s t o m c o m m a n d ( uint16 t a v r c p c i d ,
avrcp command type t command type ,
avrcp subunit type t subunit type , avrcp subunit id t subunit id
,
a v r c p p d u i d t pdu id , uint32 t company id ,
const uint8 t ∗ data , uint16 t d a t a l e n ) ;
/∗ ∗
∗ @ b r i e f De−I n i t AVRCP C o n t r o l l e r
∗/
void a v r c p c o n t r o l l e r d e i n i t ( void ) ;
1.61. AVRCP Cover Art Client API. avrcp cover art client.h
/∗ ∗
∗ @ b r i e f S e t up AVRCP Cover Art c l i e n t
∗/
void a v r c p c o v e r a r t c l i e n t i n i t ( void ) ;
/∗ ∗
∗ @brief Connect t o AVRCP Cover Art s e r v i c e on a remote d e v i c e ,
e m i t s AVRCP SUBEVENT COVER ART CONNECTION ESTABLISHED w i t h
status
∗ @param packet handler
∗ @param remote addr
∗ @param ertm buffer
∗ @param ertm buffer size
∗ @param ertm config
∗ @param a v r c p c o v e r a r t c i d o u t g o i n g parameter , v a l i d i f s t a t u s
== ERROR CODE SUCCESS
∗ @return s t a t u s
∗/
uint8 t
avrcp cover art client connect ( avrcp cover art client t ∗
c o v e r a r t c l i e n t , btstack packet handler t p a c k e t h a n d l e r ,
bd addr t remote addr , uint8 t ∗
e r t m b u f f e r , uint32 t
ertm buffer size ,
const l 2 c a p e r t m c o n f i g t ∗
e r t m c o n f i g , uint16 t ∗
avrcp cover art cid ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t c o v e r a r t t h u m b n a i l f o r c o v e r w i t h a g i v e n image
handle r e t r i e v e d via
∗ − a v r c p c o n t r o l l e r g e t n o w p l a y i n g i n f o or
∗ − avrcp controller get element attributes (...
AVRCP MEDIA ATTR DEFAULT COVER ART . . . )
∗ @param a v r c p c o v e r a r t c i d
406
∗ @param i m a g e h a n d l e
∗ @return s t a t u s
∗/
uint8 t a v r c p c o v e r a r t c l i e n t g e t l i n k e d t h u m b n a i l ( uint16 t
a v r c p c o v e r a r t c i d , const char ∗ i m a g e h a n d l e ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t c o v e r a r t image f o r g i v e n image h a n d l e r e t r i e v e d
via
∗ − a v r c p c o n t r o l l e r g e t n o w p l a y i n g i n f o or
∗ − avrcp controller get element attributes (...
AVRCP MEDIA ATTR DEFAULT COVER ART . . . )
∗ and g i v e n image d e s c r i p t o r
∗ @param a v r c p c o v e r a r t c i d
∗ @param i m a g e h a n d l e
∗ @param i m a g e d e s c r i p t o r
∗ @return s t a t u s
∗/
uint8 t a v r c p c o v e r a r t c l i e n t g e t i m a g e ( uint16 t
a v r c p c o v e r a r t c i d , const char ∗ i ma g e h an d le , const char ∗
image descriptor ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t image p r o p e r t i e s f o r g i v e n image h a n d l e r e t r i e v e d
via
∗ − a v r c p c o n t r o l l e r g e t n o w p l a y i n g i n f o or
∗ − avrcp controller get element attributes (...
AVRCP MEDIA ATTR DEFAULT COVER ART . . . )
∗ @param a v r c p c o v e r a r t c i d
∗ @param i m a g e h a n d l e
∗ @return s t a t u s
∗/
uint8 t a v r c p c o v e r a r t c l i e n t g e t i m a g e p r o p e r t i e s ( uint16 t
a v r c p c o v e r a r t c i d , const char ∗ i m a g e h a n d l e ) ;
/∗ ∗
∗ @brief D i s c o n n e c t from AVRCP Cover Art s e r v i c e
∗ @param avrcp cover art cid
∗ @return s t a t u s
∗/
uint8 t a v r c p c o v e r a r t c l i e n t d i s c o n n e c t ( uint16 t
avrcp cover art cid ) ;
/∗ ∗
∗ @ b r i e f De−I n i t AVRCP Cover Art C l i e n t
∗/
void a v r c p c o v e r a r t c l i e n t d e i n i t ( void ) ;
1.62. AVRCP Media Item Iterator API. avrcp media item iterator.h
typedef struct a v r c p m e d i a i t e m c o n t e x t {
const uint8 t ∗ data ;
407
uint16 t offset ;
uint16 t length ;
} avrcp media item context t ;
// Media item d a t a i t e r a t o r
void a v r c p m e d i a i t e m i t e r a t o r i n i t ( a v r c p m e d i a i t e m c o n t e x t t ∗
c o n t e x t , uint16 t a v r c p m e d i a i t e m l e n , const uint8 t ∗
avrcp media item data ) ;
int a v r c p m e d i a i t e m i t e r a t o r h a s m o r e ( const
avrcp media item context t ∗ context ) ;
void a v r c p m e d i a i t e m i t e r a t o r n e x t ( a v r c p m e d i a i t e m c o n t e x t t ∗
context ) ;
// Access f u n c t i o n s
uint32 t a v r c p m e d i a i t e m i t e r a t o r g e t a t t r i d ( const
avrcp media item context t ∗ context ) ;
uint16 t a v r c p m e d i a i t e m i t e r a t o r g e t a t t r c h a r s e t ( const
avrcp media item context t ∗ context ) ;
uint16 t a v r c p m e d i a i t e m i t e r a t o r g e t a t t r v a l u e l e n ( const
avrcp media item context t ∗ context ) ;
const uint8 t ∗ a v r c p m e d i a i t e m i t e r a t o r g e t a t t r v a l u e ( const
avrcp media item context t ∗ context ) ;
typedef enum {
AVRCP TARGET SUPPORTED FEATURE CATEGORY PLAYER OR RECORDER = 0 ,
AVRCP TARGET SUPPORTED FEATURE CATEGORY MONITOR OR AMPLIFIER,
AVRCP TARGET SUPPORTED FEATURE CATEGORY TUNER,
AVRCP TARGET SUPPORTED FEATURE CATEGORY MENU,
AVRCP TARGET SUPPORTED FEATURE PLAYER APPLICATION SETTINGS, //
AVRCP TARGET SUPPORTED FEATURE CATEGORY PLAYER OR RECORDER
must be 1 f o r t h i s f e a t u r e t o be s e t
AVRCP TARGET SUPPORTED FEATURE GROUP NAVIGATION, //
AVRCP TARGET SUPPORTED FEATURE CATEGORY PLAYER OR RECORDER
must be 1 f o r t h i s f e a t u r e t o be s e t
AVRCP TARGET SUPPORTED FEATURE BROWSING,
AVRCP TARGET SUPPORTED FEATURE MULTIPLE MEDIA PLAYER APPLICATIONS
,
AVRCP TARGET SUPPORTED FEATURE COVER ART,
} avrcp target supported feature t ;
/∗ ∗
∗ @ b r i e f AVRCP T a r g et s e r v i c e r e c o r d .
∗ @param s e r v i c e
∗ @param s e r v i c e r e c o r d h a n d l e
∗ @param s u p p o r t e d f e a t u r e s 16− b i t bitmap , s e e AVRCP FEATURE MASK ∗
in avrcp . h
∗ @param s e r v i c e n a m e or NULL f o r d e f a u l t v a l u e . P r o v i d e ”” ( empty
s t r i n g ) to skip a t t r i b u t e
∗ @param s e r v i c e p r o v i d e r n a m e or NULL f o r d e f a u l t v a l u e . P r o v i d e
”” ( empty s t r i n g ) t o s k i p a t t r i b u t e
408
∗/
void a v r c p t a r g e t c r e a t e s d p r e c o r d ( uint8 t ∗ s e r v i c e , uint32 t
s e r v i c e r e c o r d h a n d l e , uint16 t s u p p o r t e d f e a t u r e s , const char ∗
s e r v i c e n a m e , const char ∗ s e r v i c e p r o v i d e r n a m e ) ;
/∗ ∗
∗ @ b r i e f S e t up AVRCP T a rg e t s e r v i c e .
∗/
void a v r c p t a r g e t i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k f o r t h e AVRCP T a r g e t c l i e n t .
∗ @param c a l l b a c k
∗/
void avrcp target register packet handler (
btstack packet handler t c a l l b a c k ) ;
/∗ ∗
∗ @ b r i e f S e l e c t P l a y e r t h a t i s c o n t r o l l e d by C o n t r o l l e r
∗ @param c a l l b a c k
∗ @note C a l l b a c k s h o u l d r e t u r n i f s e l e c t e d p l a y e r i s v a l i d
∗/
void a v r c p t a r g e t r e g i s t e r s e t a d d r e s s e d p l a y e r h a n d l e r ( b o o l ( ∗
c a l l b a c k ) ( uint16 t p l a y e r i d ) ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r a l i s t o f Company IDs s u p p o r t e d by t a r g e t .
∗ @param a v r c p c i d
∗ @param num companies
∗ @param companies
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n i s not found , o t h e r w i s e ERROR CODE SUCCESS
∗/
uint8 t a v r c p t a r g e t s u p p o r t c o m p a n i e s ( uint16 t a v r c p c i d , uint8 t
num companies , const uint32 t ∗ companies ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r e v e n t ID s u p p o r t e d by t a r g e t .
∗ @param a v r c p c i d
∗ @param e v e n t i d
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n i s not found ,
ERROR CODE UNSUPPORTED FEATURE OR PARAMETER VALUE f o r
u n s u p p o r t e d e v e n t id , o t h e r w i s e ERROR CODE SUCCESS,
∗/
uint8 t a v r c p t a r g e t s u p p o r t e v e n t ( uint16 t a v r c p c i d ,
avrcp notification event id t event id ) ;
/∗ ∗
∗ @ b r i e f Send a p l a y s t a t u s .
∗ @note The a v r c p t a r g e t p a c k e t h a n d l e r w i l l r e c e i v e
AVRCP SUBEVENT PLAY STATUS QUERY e v e n t . Use t h i s f u n c t i o n t o
respond .
∗ @param a v r c p c i d
409
∗ @param s o n g l e n g t h m s
∗ @param s o n g p o s i t i o n m s
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n i s not found , o t h e r w i s e ERROR CODE SUCCESS
∗/
uint8 t a v r c p t a r g e t p l a y s t a t u s ( uint16 t a v r c p c i d , uint32 t
s o n g l e n g t h m s , uint32 t s o n g p o s i t i o n m s ,
avrcp playback status t status ) ;
/∗ ∗
∗ @ b r i e f S e t Now P l a y i n g I n f o t h a t i s send t o C o n t r o l l e r i f
n o t i f i c a t i o n s are enabled
∗ @param a v r c p c i d
∗ @param c u r r e n t t r a c k
∗ @param t o t a l t r a c k s
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n i s not found , ERROR CODE COMMAND DISALLOWED i f no
t r a c k i s p r o v i d e d , o t h e r w i s e ERROR CODE SUCCESS
∗/
uint8 t a v r c p t a r g e t s e t n o w p l a y i n g i n f o ( uint16 t a v r c p c i d , const
a v r c p t r a c k t ∗ c u r r e n t t r a c k , uint16 t t o t a l t r a c k s ) ;
/∗ ∗
∗ @ b r i e f S e t P l a y i n g s t a t u s and send t o C o n t r o l l e r
∗ @param a v r c p c i d
∗ @param p l a y b a c k s t a t u s
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n i s not found , o t h e r w i s e ERROR CODE SUCCESS
∗/
uint8 t a v r c p t a r g e t s e t p l a y b a c k s t a t u s ( uint16 t a v r c p c i d ,
avrcp playback status t playback status ) ;
/∗ ∗
∗ @ b r i e f S e t Unit I n f o
∗ @param a v r c p c i d
∗ @param u n i t t y p e
∗ @param company id
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n i s not found , o t h e r w i s e ERROR CODE SUCCESS
∗/
uint8 t a v r c p t a r g e t s e t u n i t i n f o ( uint16 t a v r c p c i d ,
a v r c p s u b u n i t t y p e t u n i t t y p e , uint32 t company id ) ;
/∗ ∗
∗ @brief Set Subunit Info
∗ @param a v r c p c i d
∗ @param s u b u n i t t y p e
∗ @param s u b u n i t i n f o d a t a
∗ @param s u b u n i t i n f o d a t a s i z e
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n i s not found , o t h e r w i s e ERROR CODE SUCCESS
∗/
410
uint8 t a v r c p t a r g e t s e t s u b u n i t i n f o ( uint16 t a v r c p c i d ,
a v r c p s u b u n i t t y p e t s u b u n i t t y p e , const uint8 t ∗
s u b u n i t i n f o d a t a , uint16 t s u b u n i t i n f o d a t a s i z e ) ;
/∗ ∗
∗ @ b r i e f Send P l a y i n g Content Changed N o t i f i c a t i o n i f e n a b l e d
∗ @param a v r c p c i d
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n i s not found , o t h e r w i s e ERROR CODE SUCCESS
∗/
uint8 t a v r c p t a r g e t p l a y i n g c o n t e n t c h a n g e d ( uint16 t a v r c p c i d ) ;
/∗ ∗
∗ @ b r i e f Send Addressed P l a y e r Changed N o t i f i c a t i o n i f e n a b l e d
∗ @param a v r c p c i d
∗ @param p l a y e r i d
∗ @param u i d c o u n t e r
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n i s not found , o t h e r w i s e ERROR CODE SUCCESS
∗/
uint8 t a v r c p t a r g e t a d d r e s s e d p l a y e r c h a n g e d ( uint16 t a v r c p c i d ,
uint16 t p l a y e r i d , uint16 t u i d c o u n t e r ) ;
/∗ ∗
∗ @ b r i e f S e t B a t t e r y S t a t u s Changed and send n o t i f i c a t i o n i f
enabled
∗ @param a v r c p c i d
∗ @param b a t t e r y s t a t u s
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n i s not found , o t h e r w i s e ERROR CODE SUCCESS
∗/
uint8 t a v r c p t a r g e t b a t t e r y s t a t u s c h a n g e d ( uint16 t a v r c p c i d ,
avrcp battery status t battery status ) ;
/∗ ∗
∗ @ b r i e f O v e r w r i t e t h e a b s o l u t e volume r e q u e s t e d by c o n t r o l l e r w i t h
t h e a c t u a l a b s o l u t e volume .
∗ This f u n c t i o n can o n l y be c a l l e d on
AVRCP SUBEVENT NOTIFICATION VOLUME CHANGED e v e n t , which
i n d i c a t e s a s e t a b s o l u t e volume r e q u e s t by c o n t r o l l e r .
∗ I f t h e a b s o l u t e volume r e q u e s t e d by c o n t r o l l e r d o e s not match t h e
g r a n u l a r i t y o f volume c o n t r o l t h e TG p r o v i d e s , you can use
t h i s function to adjust the actual value .
∗
∗ @param a v r c p c i d
∗ @param a b s o l u t e v o l u m e
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n i s not found , o t h e r w i s e ERROR CODE SUCCESS
∗/
uint8 t a v r c p t a r g e t a d j u s t a b s o l u t e v o l u m e ( uint16 t a v r c p c i d ,
uint8 t a b s o l u t e v o l u m e ) ;
/∗ ∗
411
/∗ ∗
∗ @ b r i e f S e t Track and send n o t i f i c a t i o n i f e n a b l e d
∗ @param a v r c p c i d
∗ @param t r a c k I D
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n i s not found , o t h e r w i s e ERROR CODE SUCCESS
∗/
uint8 t a v r c p t a r g e t t r a c k c h a n g e d ( uint16 t a v r c p c i d , uint8 t ∗
trackID ) ;
/∗ ∗
∗ @ b r i e f Send O p e r a t i o n R e j e c t e d message
∗ @param a v r c p c i d
∗ @param o p i d
∗ @param o p e r a n d s l e n g t h
∗ @param operand
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n i s not found , o t h e r w i s e ERROR CODE SUCCESS
∗/
uint8 t a v r c p t a r g e t o p e r a t i o n r e j e c t e d ( uint16 t a v r c p c i d ,
a v r c p o p e r a t i o n i d t opid , uint8 t o p e r a n d s l e n g t h , uint8 t
operand ) ;
/∗ ∗
∗ @ b r i e f Send O p e r a t i o n Accepted message
∗ @param a v r c p c i d
∗ @param o p i d
∗ @param o p e r a n d s l e n g t h
∗ @param operand
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n i s not found , o t h e r w i s e ERROR CODE SUCCESS
∗/
uint8 t a v r c p t a r g e t o p e r a t i o n a c c e p t e d ( uint16 t a v r c p c i d ,
a v r c p o p e r a t i o n i d t opid , uint8 t o p e r a n d s l e n g t h , uint8 t
operand ) ;
/∗ ∗
∗ @ b r i e f Send O p e r a t i o n Not Implemented message
∗ @param a v r c p c i d
∗ @param o p i d
∗ @param o p e r a n d s l e n g t h
∗ @param operand
∗ @return s t a t u s ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n i s not found , o t h e r w i s e ERROR CODE SUCCESS
∗/
412
uint8 t a v r c p t a r g e t o p e r a t i o n n o t i m p l e m e n t e d ( uint16 t a v r c p c i d ,
a v r c p o p e r a t i o n i d t opid , uint8 t o p e r a n d s l e n g t h , uint8 t
operand ) ;
/∗ ∗
∗ @ b r i e f De−I n i t AVRCP Browsing T a r g e t
∗/
void a v r c p t a r g e t d e i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f S e t up BNEP.
∗/
void b n e p i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f Check i f a d a t a p a c k e t can be send o u t .
∗/
int b n e p c a n s e n d p a c k e t n o w ( uint16 t b n e p c i d ) ;
/∗ ∗
∗ @brief Request emission o f BNEP CAN SEND NOW as soon as p o s s i b l e
∗ @note BNEP CAN SEND NOW might be e m i t t e d d u r i n g c a l l t o t h i s
function
∗ so p a c k e t h a n d l e r s h o u l d be r e a d y t o h a n d l e i t
∗ @param b n e p c i d
∗/
void b n e p r e q u e s t c a n s e n d n o w e v e n t ( uint16 t b n e p c i d ) ;
/∗ ∗
∗ @ b r i e f Send a d a t a p a c k e t .
∗/
int bnep send ( uint16 t b n e p c i d , uint8 t ∗ packet , uint16 t l e n ) ;
/∗ ∗
∗ @ b r i e f S e t t h e network p r o t o c o l f i l t e r .
∗/
int b n e p s e t n e t t y p e f i l t e r ( uint16 t b n e p c i d , b n e p n e t f i l t e r t ∗
f i l t e r , uint16 t l e n ) ;
/∗ ∗
∗ @brief Set the multicast address f i l t e r .
∗/
int b n e p s e t m u l t i c a s t f i l t e r ( uint16 t b n e p c i d , b n e p m u l t i f i l t e r t
∗ f i l t e r , uint16 t l e n ) ;
/∗ ∗
∗ @ b r i e f S e t s e c u r i t y l e v e l r e q u i r e d f o r incoming c o n n e c t i o n s , need
t o be c a l l e d b e f o r e r e g i s t e r i n g s e r v i c e s .
∗ @ de pr e ca te d use g a p s e t s e c u r i t y l e v e l i n s t e a d
∗/
413
void b n e p s e t r e q u i r e d s e c u r i t y l e v e l ( g a p s e c u r i t y l e v e l t
security level ) ;
/∗ ∗
∗ @ b r i e f C r e a t e s BNEP c o n n e c t i o n ( c h a n n e l ) t o a g i v e n s e r v e r on a
remote d e v i c e w i t h b a s e b a n d a d d r e s s . A new b a s e b a n d c o n n e c t i o n
w i l l be i n i t i a t e d i f n e c e s s a r y .
∗/
int b n e p c o n n e c t ( btstack packet handler t p a c k e t h a n d l e r , bd addr t
addr , uint16 t l2cap psm , uint16 t u u i d s r c , uint16 t u u i d d e s t )
;
/∗ ∗
∗ @ b r i e f D i s c o n n e c t s BNEP c h a n n e l w i t h g i v e n i d e n t i f i e r .
∗/
void b n e p d i s c o n n e c t ( bd addr t addr ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r s BNEP s e r v i c e , s e t a maximum frame s i z e and
a s s i g n s a p a c k e t h a n d l e r . On embedded systems , use NULL f o r
c o n n e c t i o n parameter .
∗/
uint8 t b n e p r e g i s t e r s e r v i c e ( btstack packet handler t
p a c k e t h a n d l e r , uint16 t s e r v i c e u u i d , uint16 t m a x f r a m e s i z e ) ;
/∗ ∗
∗ @ b r i e f U n r e g i s t e r BNEP s e r v i c e .
∗/
void b n e p u n r e g i s t e r s e r v i c e ( uint16 t s e r v i c e u u i d ) ;
/∗ ∗
∗ @ b r i e f De−I n i t BNEP
∗/
void b n e p d e i n i t ( void ) ;
1.65. Link Key DB API. btstack link key db.h : Interface to provide link
key storage.
typedef struct {
// management
/∗ ∗
∗ @ b r i e f Open t h e Link Key DB
∗/
void ( ∗ open ) ( void ) ;
/∗ ∗
∗ @ b r i e f S e t s BD Addr o f l o c a l B l u e t o o t h C o n t r o l l e r .
∗ @note Only needed i f B l u e t o o t h C o n t r o l l e r can be swapped , e . g
. USB Dongles on d e s k t o p s y s t e m s
∗/
414
/∗ ∗
∗ @ b r i e f C l o s e t h e Link Key DB
∗/
void ( ∗ c l o s e ) ( void ) ;
// g e t / s e t / d e l e t e l i n k key
/∗ ∗
∗ @ b r i e f Get Link Key f o r g i v e n a d d r e s s
∗ @param addr t o l o o k u p
∗ @param l i n k k e y ( o u t )
∗ @param t y p e ( o u t )
∗ @return 1 on s u c c e s s
∗/
int ( ∗ g e t l i n k k e y ) ( bd addr t bd addr , l i n k k e y t l i n k k e y ,
l i n k k e y t y p e t ∗ type ) ;
/∗ ∗
∗ @ b r i e f Update / S t o r e Link key
∗ @ b r i e f addr
∗ @brief link key
∗ @ b r i e f t y p e o f l i n k key
∗/
void ( ∗ p u t l i n k k e y ) ( bd addr t bd addr , l i n k k e y t l i n k k e y ,
l i n k k e y t y p e t type ) ;
/∗ ∗
∗ @ b r i e f D e l e t e Link Keys
∗ @ b r i e f addr
∗/
void ( ∗ d e l e t e l i n k k e y ) ( bd addr t bd addr ) ;
// i t e r a t o r : i t ’ s a l l o w e d t o d e l e t e
/∗ ∗
∗ @ b r i e f S e tu p i t e r a t o r
∗ @param i t
∗ @return 1 on s u c c e s s
∗/
int ( ∗ i t e r a t o r i n i t ) ( b t s t a c k l i n k k e y i t e r a t o r t ∗ i t ) ;
/∗ ∗
∗ @ b r i e f Get n e x t Link Key
∗ @param i t
∗ @ b r i e f addr
∗ @brief link key
∗ @ b r i e f t y p e o f l i n k key
∗ @return 1 , i f v a l i d l i n k key found
∗/
int ( ∗ i t e r a t o r g e t n e x t ) ( b t s t a c k l i n k k e y i t e r a t o r t ∗ i t ,
bd addr t bd addr , l i n k k e y t l i n k k e y , l i n k k e y t y p e t ∗
type ) ;
415
/∗ ∗
∗ @ b r i e f F re es r e s o u r c e s a l l o c a t e d by i t e r a t o r i n i t
∗ @note Must be c a l l e d a f t e r i t e r a t i o n t o f r e e r e s o u r c e s
∗ @param i t
∗/
void ( ∗ i t e r a t o r d o n e ) ( b t s t a c k l i n k k e y i t e r a t o r t ∗ i t ) ;
1.66. In-Memory Link Key Storage API. btstack link key db memory.h
/∗
∗ @brief
∗/
const btstack link key db t ∗ b t s t a c k l i n k k e y d b m e m o r y i n s t a n c e (
void ) ;
typedef struct {
b t s t a c k l i n k e d i t e m t item ;
bd addr t bd addr ;
link key t l i n k k e y ;
link key type t link key type ;
} btstack link key db memory entry t ;
1.67. Static Link Key Storage API. btstack link key db static.h : Static
Link Key Storage implementation to use during development/porting: - Link
keys have to be manually added to this file to make them usable + Link keys are
preserved on reflash in constrast to the program flash based link key store
/∗
∗ @brief
∗/
const btstack link key db t ∗ b t s t a c k l i n k k e y d b s t a t i c i n s t a n c e (
void ) ;
1.68. Link Key TLV Storage API. btstack link key db tlv.h : Interface
to provide link key storage via BTstack’s TLV storage.
/∗ ∗
∗ I n i t Link Key DB u s i n g TLV
∗ @param b t s t a c k t l v i m p l o f b t s t a c k t l v i n t e r f a c e
∗ @Param b t s t a c k t l v c o n t e x t o f b t s t a c k t l v i n t e r f a c e
∗/
416
/∗ ∗
∗ @ b r i e f C r ea t e SDP r e c o r d f o r De v i ce ID s e r v i c e
∗ @param s e r v i c e b u f f e r − n ee d s t o l a r g e enough
∗ @param s e r v i c e r e c o r d h a n d l e
∗ @param v e n d o r i d s o u r c e u s u a l l y
DEVICE ID VENDOR ID SOURCE BLUETOOTH or
DEVICE ID VENDOR ID SOURCE USB
∗ @param v e n d o r i d
∗ @param p r o d u c t i t
∗ @param v e r s i o n
∗/
void d e v i c e i d c r e a t e s d p r e c o r d ( uint8 t ∗ s e r v i c e , uint32 t
s e r v i c e r e c o r d h a n d l e , uint16 t v e n d o r i d s o u r c e , uint16 t
v e n d o r i d , uint16 t p r o d u c t i d , uint16 t v e r s i o n ) ;
/∗ ∗
∗ @ b r i e f C r e a t e s SDP r e c o r d forG ATT s e r v i c e i n p r o v i d e d empty
buffer .
∗ @note Make s u r e t h e b u f f e r i s b i g enough .
∗
∗ @param s e r v i c e i s an empty b u f f e r t o s t o r e s e r v i c e r e c o r d
∗ @param s e r v i c e r e c o r d h a n d l e f o r new s e r v i c e
∗ @param g a t t s t a r t h a n d l e
∗ @param g a t t e n d h a n d l e
∗/
void g a t t c r e a t e s d p r e c o r d ( uint8 t ∗ s e r v i c e , uint32 t
s e r v i c e r e c o r d h a n d l e , uint16 t g a t t s t a r t h a n d l e , uint16 t
gatt end handle ) ;
1.71. GOEP Client API. goep client.h : Communicate with remote OBEX
server - General Object Exchange
typedef struct {
b t s t a c k l i n k e d i t e m t item ;
uint16 t cid ;
bd addr t bd addr ;
uint16 t uuid ;
hci con handle t con handle ;
uint8 t incoming ;
/∗ ∗
∗ S et u p GOEP C l i e n t
∗/
void g o e p c l i e n t i n i t ( void ) ;
/∗ ∗
418
/∗ ∗
∗ @ b r i e f Connect t o a GEOP s e r v e r o v e r L2CAP w i t h s p e c i f i e d PSM on
a remote d e v i c e .
∗ @note In c o n t r a s t t o g o e p c l i e n t c o n n e c t which s e a r c h e s f o r a
OBEX s e r v i c e w i t h a g i v e n UUID, t h i s
∗ f u n c t i o n o n l y s u p p o r t s GOEP v2 . 0 (L2CAP) t o a s p e c i f i e d
L2CAP PSM
∗ @param g o e p c l i e n t
∗ @param l 2 c a p e r t m c o n f i g
∗ @param l 2 c a p e r t m b u f f e r s i z e
∗ @param l 2 c a p e r t m b u f f e r
∗ @param h a n d l e r
∗ @param addr
∗ @param l 2 c a p p s m
∗ @param o u t c i d
∗ @return
∗/
uint8 t
goep client connect l2cap ( goep client t ∗ goep client ,
l 2 c a p e r t m c o n f i g t ∗ l 2 c a p e r t m c o n f i g , uint8 t ∗
l2cap ertm buffer ,
uint16 t l 2 c a p e r t m b u f f e r s i z e ,
btstack packet handler t h a n d l e r , bd addr t
addr , uint16 t l2cap psm ,
uint16 t ∗ o u t c i d ) ;
/∗
∗ @ b r i e f Connect t o a GEOP s e r v e r w i t h s p e c i f i e d UUID on a remote
device .
∗ @note This f u n c t i o n s u s e s a s i n g l e g o e p c l i e n t t i n s t a n c e and
o n l y a l l o w s f o r a s i n g l e goep c o n n e c t i o n
∗ P l e a s e use g o e p c l i e n t c o n n e c t i n s t e a d
419
∗ @param h a n d l e r
∗ @param addr
∗ @param u u i d
∗ @param o u t c i d t o use f o r f u r t h e r commands
∗ @result status
∗/
uint8 t g o e p c l i e n t c r e a t e c o n n e c t i o n ( btstack packet handler t
h a n d l e r , bd addr t addr , uint16 t uuid , uint16 t ∗ o u t c i d ) ;
/∗ ∗
∗ @ b r i e f D i s c o n n e c t s GOEP c o n n e c t i o n w i t h g i v e n i d e n t i f i e r .
∗ @param g o e p c i d
∗ @return s t a t u s
∗/
uint8 t g o e p c l i e n t d i s c o n n e c t ( uint16 t g o e p c i d ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t e m i s s i o n o f GOEP SUBEVENT CAN SEND NOW as soon as
possible
∗ @note GOEP SUBEVENT CAN SEND NOW might be e m i t t e d d u r i n g c a l l t o
this function
∗ so p a c k e t h a n d l e r s h o u l d be r e a d y t o h a n d l e i t
∗ @param g o e p c i d
∗/
void g o e p c l i e n t r e q u e s t c a n s e n d n o w ( uint16 t g o e p c i d ) ;
/∗ ∗
∗ @ b r i e f Get Opcode from l a s t c r e a t e d r e q u e s t , needed f o r p a r s i n g
o f OBEX r e s p o n s e p a c k e t
∗ @param g o e p c i d
∗ @return opcode
∗/
uint8 t g o e p c l i e n t g e t r e q u e s t o p c o d e ( uint16 t g o e p c i d ) ;
/∗ ∗
∗ @ b r i e f Get PBAP S u p p o r t e d F e a t u r e s found i n SDP r e c o r d d u r i n g
connect
∗/
uint32 t g o e p c l i e n t g e t p b a p s u p p o r t e d f e a t u r e s ( uint16 t g o e p c i d ) ;
/∗ ∗
∗ @ b r i e f Get MAP S u p p o r t e d F e a t u r e s found i n SDP r e c o r d d u r i n g
connect
∗/
uint32 t g o e p c l i e n t g e t m a p s u p p o r t e d f e a t u r e s ( uint16 t g o e p c i d ) ;
/∗ ∗
∗ @ b r i e f Get MAP MAS I n s t a n c e ID found i n SDP r e c o r d d u r i n g c o n n e c t
∗/
uint8 t g o e p c l i e n t g e t m a p m a s i n s t a n c e i d ( uint16 t g o e p c i d ) ;
/∗ ∗
∗ @ b r i e f Get MAP MAS S u p p o r t e d Message Types found i n SDP r e c o r d
during connect
420
∗/
uint8 t g o e p c l i e n t g e t m a p s u p p o r t e d m e s s a g e t y p e s ( uint16 t
goep cid ) ;
/∗ ∗
∗ @ b r i e f Check i f GOEP 2 . 0 or h i g h e r f e a t u r e s can be used
∗ @return t r u e i f GOEP Version 2 . 0 or h i g h e r
∗/
b o o l g o e p c l i e n t v e r s i o n 2 0 o r h i g h e r ( uint16 t g o e p c i d ) ;
/∗ ∗
∗ @ b r i e f S e t Connection ID used f o r newly c r e a t e d r e q u e s t s
∗ @param g o e p c i d
∗/
void g o e p c l i e n t s e t c o n n e c t i o n i d ( uint16 t g o e p c i d , uint32 t
connection id ) ;
/∗ ∗
∗ @ b r i e f S t a r t Connect r e q u e s t
∗ @param g o e p c i d
∗ @param o b e x v e r s i o n n u m b e r
∗ @param f l a g s
∗ @param m a x i m u m o b e x p a c k e t l e n g t h
∗/
void g o e p c l i e n t r e q u e s t c r e a t e c o n n e c t ( uint16 t g o e p c i d , uint8 t
o b e x v e r s i o n n u m b e r , uint8 t f l a g s , uint16 t
maximum obex packet length ) ;
/∗ ∗
∗ @brief S t a r t Disconnect r e q u e s t
∗ @param g o e p c i d
∗/
void g o e p c l i e n t r e q u e s t c r e a t e d i s c o n n e c t ( uint16 t g o e p c i d ) ;
/∗ ∗
∗ @ b r i e f C r ea t e Get r e q u e s t
∗ @param g o e p c i d
∗/
void g o e p c l i e n t r e q u e s t c r e a t e g e t ( uint16 t g o e p c i d ) ;
/∗ ∗
∗ @ b r i e f C r ea t e Abort r e q u e s t
∗ @param g o e p c i d
∗/
void g o e p c l i e n t r e q u e s t c r e a t e a b o r t ( uint16 t g o e p c i d ) ;
/∗ ∗
∗ @ b r i e f S t a r t S e t Path r e q u e s t
∗ @param g o e p c i d
∗/
void g o e p c l i e n t r e q u e s t c r e a t e s e t p a t h ( uint16 t g o e p c i d , uint8 t
flags ) ;
/∗ ∗
421
∗ @ b r i e f C r ea t e Put r e q u e s t
∗ @param g o e p c i d
∗/
void g o e p c l i e n t r e q u e s t c r e a t e p u t ( uint16 t g o e p c i d ) ;
/∗ ∗
∗ @ b r i e f Get max s i z e o f body d a t a t h a t can be added t o c u r r e n t
response with g o e p c l i e n t b o d y a d d s t a t i c
∗ @param g o e p c i d
∗ @param d a t a
∗ @param l e n g t h
∗ @return s i z e i n b y t e s or 0
∗/
uint16 t g o e p c l i e n t r e q u e s t g e t m a x b o d y s i z e ( uint16 t g o e p c i d ) ;
/∗ ∗
∗ @ b r i e f Add SRM Enable
∗ @param g o e p c i d
∗/
void g o e p c l i e n t h e a d e r a d d s r m e n a b l e ( uint16 t g o e p c i d ) ;
/∗ ∗
∗ @brief Add h e a d e r w i t h s i n g l e b y t e v a l u e (8 b i t )
∗ @param goep cid
∗ @param header type
∗ @param value
∗/
void g o e p c l i e n t h e a d e r a d d b y t e ( uint16 t g o e p c i d , uint8 t
header t y p e , uint8 t v a l u e ) ;
/∗ ∗
∗ @brief Add h e a d e r w i t h word v a l u e (32 b i t )
∗ @param goep cid
∗ @param header type
∗ @param value
∗/
void g o e p c l i e n t h e a d e r a d d w o r d ( uint16 t g o e p c i d , uint8 t
header t y p e , uint32 t v a l u e ) ;
/∗ ∗
∗ @brief Add h e a d e r w i t h v a r i a b l e s i z e
∗ @param goep cid
∗ @param header type
∗ @param header data
∗ @param header data length
∗/
void g o e p c l i e n t h e a d e r a d d v a r i a b l e ( uint16 t g o e p c i d , uint8 t
header t y p e , const uint8 t ∗ h e a d e r d a t a , uint16 t
header data length ) ;
/∗ ∗
∗ @ b r i e f Add name h e a d e r t o c u r r e n t r e q u e s t
∗ @param g o e p c i d
∗ @param name
422
∗/
void g o e p c l i e n t h e a d e r a d d n a m e ( uint16 t g o e p c i d , const char ∗
name ) ;
/∗ ∗
∗ @brief Add name h e a d e r t o c u r r e n t r e q u e s t
∗ @param goep cid
∗ @param name
∗ @param name len
∗/
void g o e p c l i e n t h e a d e r a d d n a m e p r e f i x ( uint16 t g o e p c i d , const
char ∗ name , uint16 t name len ) ;
/∗ ∗
∗ @ b r i e f Add s t r i n g encoded as u n i c o d e t o c u r r e n t r e q u e s t
∗ @param g o e p c i d
∗ @param name
∗ @param name len
∗/
void g o e p c l i e n t h e a d e r a d d u n i c o d e p r e f i x ( uint16 t g o e p c i d ,
uint8 t h e a d e r i d , const char ∗ name , uint16 t name len ) ;
/∗ ∗
∗ @ b r i e f Add t a r g e t h e a d e r t o c u r r e n t r e q u e s t
∗ @param g o e p c i d
∗ @param t a r g e t
∗ @param l e n g t h o f t a r g e t
∗/
void g o e p c l i e n t h e a d e r a d d t a r g e t ( uint16 t g o e p c i d , const uint8 t
∗ t a r g e t , uint16 t l e n g t h ) ;
/∗ ∗
∗ @brief Add t y p e h e a d e r t o c u r r e n t r e q u e s t
∗ @param goep cid
∗ @param type
∗/
void g o e p c l i e n t h e a d e r a d d t y p e ( uint16 t g o e p c i d , const char ∗
type ) ;
/∗ ∗
∗ @brief Add c ou n t h e a d e r t o c u r r e n t r e q u e s t
∗ @param goep cid
∗ @param co un t
∗/
void g o e p c l i e n t h e a d e r a d d c o u n t ( uint16 t g o e p c i d , uint32 t count )
;
/∗ ∗
∗ @ b r i e f Add l e n g t h h e a d e r t o c u r r e n t r e q u e s t
∗ @param g o e p c i d
∗ @param l e n g t h
∗/
void g o e p c l i e n t h e a d e r a d d l e n g t h ( uint16 t g o e p c i d , uint32 t
length ) ;
423
/∗ ∗
∗ @ b r i e f Add a p p l i c a t i o n p a r a m e t e r s h e a d e r t o c u r r e n t r e q u e s t
∗ @param g o e p c i d
∗ @param d a t a
∗ @param l e n g h t o f a p p l i c a t i o n p a r a m e t e r s
∗/
void g o e p c l i e n t h e a d e r a d d a p p l i c a t i o n p a r a m e t e r s ( uint16 t g o e p c i d
, const uint8 t ∗ data , uint16 t l e n g t h ) ;
/∗ ∗
∗ @ b r i e f Add a p p l i c a t i o n p a r a m e t e r s h e a d e r t o c u r r e n t r e q u e s t
∗ @param g o e p c i d
∗ @param d a t a
∗ @param l e n g h t o f c h a l l e n g e r e s p o n s e
∗/
void g o e p c l i e n t h e a d e r a d d c h a l l e n g e r e s p o n s e ( uint16 t g o e p c i d ,
const uint8 t ∗ data , uint16 t l e n g t h ) ;
/∗ ∗
∗ @ b r i e f Add body
∗ @param g o e p c i d
∗ @param d a t a
∗ @param l e n g h t
∗/
void g o e p c l i e n t b o d y a d d s t a t i c ( uint16 t g o e p c i d , const uint8 t ∗
data , uint32 t l e n g t h ) ;
/∗ ∗
∗ @ b r i e f Query re mainin g b u f f e r s i z e
∗ @param g o e p c i d
∗ @return s i z e
∗/
uint16 t g o e p c l i e n t b o d y g e t o u t g o i n g b u f f e r l e n ( uint16 t g o e p c i d )
;
/∗ ∗
∗ @ b r i e f Add body
∗ @param g o e p c i d
∗ @param d a t a
∗ @param l e n g t h
∗ @param r e t l e n g t h
∗/
void g o e p c l i e n t b o d y f i l l u p s t a t i c ( uint16 t g o e p c i d , const uint8 t
∗ data , uint32 t l e n g t h , uint32 t ∗ r e t l e n g t h ) ;
/∗ ∗
∗ @brief Execute prepared r e q u e s t
∗ @param g o e p c i d
∗ @param daa
∗/
int g o e p c l i e n t e x e c u t e ( uint16 t g o e p c i d ) ;
/∗ ∗
424
/∗ ∗
∗ @ b r i e f De−I n i t GOEP C l i e n t
∗/
void g o e p c l i e n t d e i n i t ( void ) ;
typedef struct {
uint8 t type ;
const char ∗ number ;
} hfp phone number t ;
/∗ ∗
∗ @ b r i e f C r ea t e HFP Audio Gateway (AG) SDP s e r v i c e r e c o r d .
∗ @param s e r v i c e
∗ @param r f c o m m c h a n n e l n r
∗ @param name or NULL f o r d e f a u l t v a l u e . P r o v i d e ”” ( empty s t r i n g )
to skip a t t r i b u t e
∗ @param a b i l i t y t o r e j e c t c a l l
∗ @param s u p p o r t e d f e a t u r e s 32− b i t bitmap , s e e HFP AGSF ∗ v a l u e s i n
hfp . h
∗ @param c o d e c s n r
∗ @param c o d e c s
∗/
void h f p a g c r e a t e s d p r e c o r d w i t h c o d e c s ( uint8 t ∗ s e r v i c e ,
uint32 t s e r v i c e r e c o r d h a n d l e , int r fc om m c ha nn el nr ,
const char ∗ name , uint8 t
/∗ ∗
∗ @ b r i e f S e t up HFP Audio Gateway (AG) d e v i c e w i t h o u t a d d i t i o n a l
supported features .
∗ @param r f c o m m c h a n n e l n r
∗/
void h f p a g i n i t ( uint8 t r f c o m m c h a n n e l n r ) ;
/∗ ∗
∗ @brief Set codecs .
∗ @param c o d e c s n r
∗ @param c o d e c s
425
∗/
void h f p a g i n i t c o d e c s ( uint8 t c o d e c s n r , const uint8 t ∗ c o d e c s ) ;
/∗ ∗
∗ @brief Set supported f e a t u r e s .
∗ @param s u p p o r t e d f e a t u r e s 32− b i t bitmap , s e e HFP AGSF ∗ v a l u e s i n
hfp . h
∗/
void h f p a g i n i t s u p p o r t e d f e a t u r e s ( uint32 t s u p p o r t e d f e a t u r e s ) ;
/∗ ∗
∗ @ b r i e f S e t AG i n d i c a t o r s .
∗ @param i n d i c a t o r s n r
∗ @param i n d i c a t o r s
∗/
void h f p a g i n i t a g i n d i c a t o r s ( int a g i n d i c a t o r s n r , const
hfp ag indicator t ∗ ag indicators ) ;
/∗ ∗
∗ @ b r i e f S e t HF i n d i c a t o r s .
∗ @param i n d i c a t o r s n r
∗ @param i n d i c a t o r s
∗/
void h f p a g i n i t h f i n d i c a t o r s ( int h f i n d i c a t o r s n r , const
hfp generic status indicator t ∗ hf indicators ) ;
/∗ ∗
∗ @ b r i e f S e t C a l l Hold s e r v i c e s .
∗ @param i n d i c a t o r s n r
∗ @param i n d i c a t o r s
∗/
void h f p a g i n i t c a l l h o l d s e r v i c e s ( int c a l l h o l d s e r v i c e s n r , const
char ∗ c a l l h o l d s e r v i c e s [ ] ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k f o r t h e HFP Audio Gateway (AG) c l i e n t .
∗ @param c a l l b a c k
∗/
void h f p a g r e g i s t e r p a c k e t h a n d l e r ( btstack packet handler t
callback ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r custom AT command .
∗ @param hfp custom at command ( w i t h ’AT+’ p r e f i x )
∗/
void h f p a g r e g i s t e r c u s t o m a t c o m m a n d ( hfp custom at command t ∗
custom at command ) ;
/∗ ∗
∗ @ b r i e f Enable / D i s a b l e in−band r i n g t o n e .
∗
∗ @param u s e i n b a n d r i n g t o n e
∗/
426
void h f p a g s e t u s e i n b a n d r i n g t o n e ( int u s e i n b a n d r i n g t o n e ) ;
// a c t i o n s used by l o c a l d e v i c e / u s e r
/∗ ∗
∗ @ b r i e f E s t a b l i s h RFCOMM c o n n e c t i o n , and perform s e r v i c e l e v e l
c o n n e c t i o n agreement :
∗ − exchange of supported f e a t u r e s
∗ − r e p o r t Audio Gateway (AG) i n d i c a t o r s and t h e i r s t a t u s
∗ − e n a b l e i n d i c a t o r s t a t u s u p d a t e i n t h e AG
∗ − a c c e p t t h e i n f o r m a t i o n a b o u t a v a i l a b l e c o d e c s i n t h e Hands−Free
(HF) , i f s e n t
∗ − r e p o r t own i n f o r m a t i o n d e s c r i b i n g t h e c a l l h o l d and m u l t i p a r t y
services , i f possible
∗ − r e p o r t which HF i n d i c a t o r s a r e e n a b l e d on t h e AG, i f p o s s i b l e
∗ The s t a t u s o f SLC c o n n e c t i o n e s t a b l i s h m e n t i s r e p o r t e d v i a
∗ HFP SUBEVENT SERVICE LEVEL CONNECTION ESTABLISHED .
∗
∗ @param b d a d d r o f HF
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE COMMAND DISALLOWED i f c o n n e c t i o n
a l r e a d y e x i s t s or c o n n e c t i o n i n wrong s t a t e , or
∗ − BTSTACK MEMORY ALLOC FAILED
∗
∗/
uint8 t h f p a g e s t a b l i s h s e r v i c e l e v e l c o n n e c t i o n ( bd addr t bd addr )
;
/∗ ∗
∗ @ b r i e f R e l e a s e t h e RFCOMM c h a n n e l and t h e a u d i o c o n n e c t i o n
b e t w e e n t h e HF and t h e AG.
∗ I f t h e a u d i o c o n n e c t i o n e x i s t s , i t w i l l be r e l e a s e d .
∗ The s t a t u s o f r e l e a s i n g t h e SLC c o n n e c t i o n i s r e p o r t e d v i a
∗ HFP SUBEVENT SERVICE LEVEL CONNECTION RELEASED .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p a g r e l e a s e s e r v i c e l e v e l c o n n e c t i o n ( h c i c o n h a n d l e t
acl handle ) ;
/∗ ∗
∗ @brief E s t a b l i s h audio connection .
∗ The s t a t u s o f Audio c o n n e c t i o n e s t a b l i s h m e n t i s r e p o r t e d v i a
HSP SUBEVENT AUDIO CONNECTION COMPLETE.
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
427
uint8 t h f p a g e s t a b l i s h a u d i o c o n n e c t i o n ( h c i c o n h a n d l e t
acl handle ) ;
/∗ ∗
∗ @brief Release audio connection .
∗ The s t a t u s o f r e l e a s i n g t h e Audio c o n n e c t i o n i s r e p o r t e d v i a
HSP SUBEVENT AUDIO DISCONNECTION COMPLETE.
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p a g r e l e a s e a u d i o c o n n e c t i o n ( h c i c o n h a n d l e t a c l h a n d l e )
;
/∗ ∗
∗ @ b r i e f Put t h e c u r r e n t c a l l on h o l d , i f i t e x i s t s , and a c c e p t
incoming c a l l .
∗/
void h f p a g a n s w e r i n c o m i n g c a l l ( void ) ;
/∗ ∗
∗ @ b r i e f Join h e l d c a l l w i t h a c t i v e c a l l .
∗/
void h f p a g j o i n h e l d c a l l ( void ) ;
/∗ ∗
∗ @ b r i e f R e j e c t incoming c a l l , i f e x i s t s , or t e r m i n a t e a c t i v e c a l l .
∗/
void h f p a g t e r m i n a t e c a l l ( void ) ;
/∗ ∗
∗ @ b r i e f Put incoming c a l l on h o l d .
∗/
void h f p a g h o l d i n c o m i n g c a l l ( void ) ;
/∗ ∗
∗ @ b r i e f Accept t h e h e l d incoming c a l l .
∗/
void h f p a g a c c e p t h e l d i n c o m i n g c a l l ( void ) ;
/∗ ∗
∗ @ b r i e f R e j e c t t h e h e l d incoming c a l l .
∗/
void h f p a g r e j e c t h e l d i n c o m i n g c a l l ( void ) ;
/∗ ∗
∗ @ b r i e f S e t microphone g a i n .
∗
∗ @param a c l h a n d l e
∗ @param g a i n V a l i d range : [ 0 , 1 5 ]
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
428
/∗ ∗
∗ @brief Set speaker gain .
∗
∗ @param a c l h a n d l e
∗ @param g a i n V a l i d range : [ 0 , 1 5 ]
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
∗ − ERROR CODE COMMAND DISALLOWED i f i n v a l i d g a i n
range
∗/
uint8 t h f p a g s e t s p e a k e r g a i n ( h c i c o n h a n d l e t a c l h a n d l e , int
gain ) ;
/∗ ∗
∗ @brief Set b a t t e r y l e v e l .
∗
∗ @param b a t t e r y l e v e l V a l i d range : [ 0 , 5 ]
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
∗ − ERROR CODE COMMAND DISALLOWED i f i n v a l i d b a t t e r y
l e v e l range
∗/
uint8 t h f p a g s e t b a t t e r y l e v e l ( int b a t t e r y l e v e l ) ;
/∗ ∗
∗ @ b r i e f C l e a r l a s t d i a l e d number .
∗/
void h f p a g c l e a r l a s t d i a l e d n u m b e r ( void ) ;
/∗ ∗
∗ @ b r i e f S e t l a s t d i a l e d number .
∗/
void h f p a g s e t l a s t d i a l e d n u m b e r ( const char ∗ number ) ;
/∗ ∗
∗ @ b r i e f N o t i f y t h e HF t h a t an incoming c a l l i s w a i t i n g
∗ d u r i n g an o n g o i n g c a l l . The n o t i f i c a t i o n w i l l be s e n t o n l y i f t h e
HF has
∗ has p r e v i o u s l y e n a b l e d t h e ” C a l l Waiting n o t i f i c a t i o n ” i n t h e AG.
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
429
// Voice R e c o g n i t i o n
/∗ ∗
∗ @ b r i e f A c t i v a t e v o i c e r e c o g n i t i o n and emit
HFP SUBEVENT VOICE RECOGNITION ACTIVATED e v e n t w i t h s t a t u s
ERROR CODE SUCCESS
∗ i f s u c c e s s f u l . P r e r e q u i s i t e i s e s t a b l i s h e d SLC .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
∗ − ERROR CODE COMMAND DISALLOWED i f f e a t u r e HFP (HF/
AG)SF VOICE RECOGNITION FUNCTION i s not s u p p o r t e d by HF and AG,
or a l r e a d y a c t i v a t e d
∗/
uint8 t h f p a g a c t i v a t e v o i c e r e c o g n i t i o n ( h c i c o n h a n d l e t
acl handle ) ;
/∗ ∗
∗ @ b r i e f D e a c t i v a t e v o i c e r e c o g n i t i o n and emit
HFP SUBEVENT VOICE RECOGNITION DEACTIVATED e v e n t w i t h s t a t u s
ERROR CODE SUCCESS
∗ i f s u c c e s s f u l . P r e r e q u i s i t e i s e s t a b l i s h e d SLC .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
∗ − ERROR CODE COMMAND DISALLOWED i f f e a t u r e HFP (HF/
AG)SF VOICE RECOGNITION FUNCTION i s not s u p p o r t e d by HF and AG,
or a l r e a d y d e a c t i v a t e d
∗/
uint8 t h f p a g d e a c t i v a t e v o i c e r e c o g n i t i o n ( h c i c o n h a n d l e t
acl handle ) ;
/∗ ∗
∗ @ b r i e f N o t i f y HF t h a t sound w i l l be p l a y e d and
HFP SUBEVENT ENHANCED VOICE RECOGNITION AG IS STARTING SOUND
e v e n t w i t h s t a t u s ERROR CODE SUCCESS
∗ i f s u c c e s s f u l , o t h e r w i s e ERROR CODE COMMAND DISALLOWED.
∗
∗ @param a c l h a n d l e
∗ @param a c t i v a t e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
430
/∗ ∗
∗ @ b r i e f N o t i f y HF t h a t AG i s r e a d y f o r i n p u t and emit
HFP SUBEVENT ENHANCED VOICE RECOGNITION AG READY TO ACCEPT AUDIO INPUT
e v e n t w i t h s t a t u s ERROR CODE SUCCESS
∗ i f s u c c e s s f u l , o t h e r w i s e ERROR CODE COMMAND DISALLOWED.
∗
∗ @param a c l h a n d l e
∗ @param a c t i v a t e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
∗ − ERROR CODE COMMAND DISALLOWED i f f e a t u r e HFP (HF/
AG)SF ENHANCED VOICE RECOGNITION STATUS i s not s u p p o r t e d by HF
and AG
∗/
uint8 t h f p a g e n h a n c e d v o i c e r e c o g n i t i o n r e p o r t r e a d y f o r a u d i o (
hci con handle t acl handle ) ;
/∗ ∗
∗ @ b r i e f N o t i f y t h a t AG i s p r o c e s s i n g i n p u t and emit
HFP SUBEVENT ENHANCED VOICE RECOGNITION AG IS PROCESSING AUDIO INPUT
e v e n t w i t h s t a t u s ERROR CODE SUCCESS
∗ i f s u c c e s s f u l , o t h e r w i s e ERROR CODE COMMAND DISALLOWED.
∗
∗ @param a c l h a n d l e
∗ @param a c t i v a t e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
∗ − ERROR CODE COMMAND DISALLOWED i f f e a t u r e HFP (HF/
AG)SF ENHANCED VOICE RECOGNITION STATUS i s not s u p p o r t e d by HF
and AG
∗/
uint8 t h f p a g e n h a n c e d v o i c e r e c o g n i t i o n r e p o r t p r o c e s s i n g i n p u t (
hci con handle t acl handle ) ;
/∗ ∗
∗ @ b r i e f Send enhanced a u d i o r e c o g n i t i o n message and
HFP SUBEVENT ENHANCED VOICE RECOGNITION AG MESSAGE SENT e v e n t
w i t h s t a t u s ERROR CODE SUCCESS
∗ i f s u c c e s s f u l , o t h e r w i s e ERROR CODE COMMAND DISALLOWED.
∗
∗ @param a c l h a n d l e
∗ @param a c t i v a t e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t ,
431
/∗ ∗
∗ @ b r i e f Send a phone number b a c k t o t h e HF.
∗
∗ @param a c l h a n d l e
∗ @param phone number
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p a g s e n d p h o n e n u m b e r f o r v o i c e t a g ( h c i c o n h a n d l e t
a c l h a n d l e , const char ∗ phone number ) ;
/∗ ∗
∗ @ b r i e f R e j e c t s e n d i n g a phone number t o t h e HF.
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p a g r e j e c t p h o n e n u m b e r f o r v o i c e t a g ( h c i c o n h a n d l e t
acl handle ) ;
/∗ ∗
∗ @ b r i e f S t o r e phone number w i t h i n i t i a t e d c a l l .
∗ @param t y p e
∗ @param number
∗/
void h f p a g s e t c l i p ( uint8 t type , const char ∗ number ) ;
// C e l l u l a r A c t i o n s
/∗ ∗
∗ @ b r i e f Pass t h e a c c e p t incoming c a l l e v e n t t o t h e AG.
∗/
void h f p a g i n c o m i n g c a l l ( void ) ;
/∗ ∗
∗ @ b r i e f Outgoing c a l l i n i t i a t e d
∗/
432
void h f p a g o u t g o i n g c a l l i n i t i a t e d ( void ) ;
/∗ ∗
∗ @ b r i e f Pass t h e r e j e c t o u t g o i n g c a l l e v e n t t o t h e AG.
∗/
void h f p a g o u t g o i n g c a l l r e j e c t e d ( void ) ;
/∗ ∗
∗ @ b r i e f Pass t h e a c c e p t o u t g o i n g c a l l e v e n t t o t h e AG.
∗/
void h f p a g o u t g o i n g c a l l a c c e p t e d ( void ) ;
/∗ ∗
∗ @ b r i e f Pass t h e o u t g o i n g c a l l r i n g i n g e v e n t t o t h e AG.
∗/
void h f p a g o u t g o i n g c a l l r i n g i n g ( void ) ;
/∗ ∗
∗ @ b r i e f Pass t h e o u t g o i n g c a l l e s t a b l i s h e d e v e n t t o t h e AG.
∗/
void h f p a g o u t g o i n g c a l l e s t a b l i s h e d ( void ) ;
/∗ ∗
∗ @ b r i e f Pass t h e c a l l dropped e v e n t t o t h e AG.
∗/
void h f p a g c a l l d r o p p e d ( void ) ;
/∗ ∗
∗ @ b r i e f S e t network r e g i s t r a t i o n s t a t u s .
∗ @param s t a t u s 0 − not r e g i s t e r e d , 1 − r e g i s t e r e d
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
∗ − ERROR CODE COMMAND DISALLOWED i f i n v a l i d
registration status
∗/
uint8 t h f p a g s e t r e g i s t r a t i o n s t a t u s ( int r e g i s t r a t i o n s t a t u s ) ;
/∗ ∗
∗ @ b r i e f S e t network s i g n a l s t r e n g t h .
∗
∗ @param s i g n a l s t r e n g t h [0 −5]
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
∗ − ERROR CODE COMMAND DISALLOWED i f i n v a l i d s i g n a l
s t r e n g t h range
∗/
uint8 t h f p a g s e t s i g n a l s t r e n g t h ( int s i g n a l s t r e n g t h ) ;
/∗ ∗
∗ @ b r i e f S e t roaming s t a t u s .
∗
∗ @param r o a m i n g s t a t u s 0 − no roaming , 1 − roaming a c t i v e
433
/∗ ∗
∗ @ b r i e f S e t s u b c r i b e r number i n f o r m a t i o n , e . g . t h e phone number
∗ @param numbers
∗ @param numbers count
∗/
void h f p a g s e t s u b c r i b e r n u m b e r i n f o r m a t i o n ( h f p p h o n e n u m b e r t ∗
numbers , int numbers count ) ;
/∗ ∗
∗ @ b r i e f C a l l e d by c e l l u l a r u n i t a f t e r a DTMF code was t r a n s m i t t e d ,
so t h a t t h e n e x t one can be e m i t t e d .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p a g s e n d d t m f c o d e d o n e ( h c i c o n h a n d l e t a c l h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Report Extended Audio Gateway Error r e s u l t c o d e s i n t h e AG
.
∗ Whenever t h e r e i s an e r r o r r e l a t i n g t o t h e f u n c t i o n a l i t y o f t h e
AG as a
∗ r e s u l t o f AT command , t h e AG s h a l l send +CME ERROR:
∗ − +CME ERROR: 0 − AG f a i l u r e
∗ − +CME ERROR: 1 − no c o n n e c t i o n t o phone
∗ − +CME ERROR: 3 − o p e r a t i o n not a l l o w e d
∗ − +CME ERROR: 4 − o p e r a t i o n not s u p p o r t e d
∗ − +CME ERROR: 5 − PH−SIM PIN r e q u i r e d
∗ − +CME ERROR: 10 − SIM not i n s e r t e d
∗ − +CME ERROR: 11 − SIM PIN r e q u i r e d
∗ − +CME ERROR: 12 − SIM PUK r e q u i r e d
∗ − +CME ERROR: 13 − SIM f a i l u r e
∗ − +CME ERROR: 14 − SIM b u s y
∗ − +CME ERROR: 16 − i n c o r r e c t password
∗ − +CME ERROR: 17 − SIM PIN2 r e q u i r e d
∗ − +CME ERROR: 18 − SIM PUK2 r e q u i r e d
∗ − +CME ERROR: 20 − memory f u l l
∗ − +CME ERROR: 21 − i n v a l i d i n d e x
∗ − +CME ERROR: 23 − memory f a i l u r e
∗ − +CME ERROR: 24 − t e x t s t r i n g t o o l o n g
∗ − +CME ERROR: 25 − i n v a l i d c h a r a c t e r s i n t e x t s t r i n g
∗ − +CME ERROR: 26 − d i a l s t r i n g t o o l o n g
∗ − +CME ERROR: 27 − i n v a l i d c h a r a c t e r s i n d i a l s t r i n g
∗ − +CME ERROR: 30 − no network s e r v i c e
434
/∗ ∗
∗ @ b r i e f Send u n s o l i c i t e d r e s u l t code ( most l i k e l y a r e s p o n s e t o a
vendor−s p e c i f i c command not p a r t o f s t a n d a r d HFP) .
∗ @note Emits HFP SUBEVENT CUSTOM AT MESSAGE SENT when r e s u l t code
was s e n t
∗
∗ @param u n s o l i c i t e d r e s u l t c o d e t o send
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
∗ − ERROR CODE COMMAND DISALLOWED i f e x t e n d e d a u d i o
gateway e r r o r r e p o r t i s d i s a b l e d
∗/
uint8 t h f p a g s e n d u n s o l i c i t e d r e s u l t c o d e ( h c i c o n h a n d l e t
a c l h a n d l e , const char ∗ u n s o l i c i t e d r e s u l t c o d e ) ;
/∗ ∗
∗ @ b r i e f Send r e s u l t code f o r AT command r e c e i v e d v i a
HFP SUBEVENT CUSTOM AT COMMAND
∗ @note Emits HFP SUBEVENT COMPLETE when r e s u l t code was s e n t
∗
∗ @param ok f o r OK, or ERROR
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
∗ − ERROR CODE COMMAND DISALLOWED i f e x t e n d e d a u d i o
gateway e r r o r r e p o r t i s d i s a b l e d
∗/
uint8 t h f p a g s e n d c o m m a n d r e s u l t c o d e ( h c i c o n h a n d l e t a c l h a n d l e ,
b o o l ok ) ;
/∗ ∗
∗ @ b r i e f De−I n i t HFP AG
∗/
void h f p a g d e i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f C r ea t e HFP Audio Gateway (AG) SDP s e r v i c e r e c o r d .
∗ @ de pr e ca te d Use h f p a g c r e a t e s d p r e c o r d w i t h c o d e c s i n s t e a d
∗ @param s e r v i c e
435
∗ @param r f c o m m c h a n n e l n r
∗ @param name
∗ @param a b i l i t y t o r e j e c t c a l l
∗ @param s u p o r t e d f e a t u r e s 32− b i t bitmap , s e e HFP AGSF ∗ v a l u e s i n
hfp . h
∗ @param w i d e b a n d s p e e c h s u p p o r t e d
∗/
void h f p a g c r e a t e s d p r e c o r d ( uint8 t ∗ s e r v i c e , uint32 t
s e r v i c e r e c o r d h a n d l e , int rf c om m c ha nn el n r , const char ∗ name ,
uint8 t a b i l i t y t o r e j e c t c a l l , uint16 t s u p p o r t e d f e a t u r e s ,
int w i d e b a n d s p e e c h ) ;
1.73. HFP Audio Encoder API. hfp codec.h : @brief Create SCO packet
with H2 Synchronization Header and encoded audio samples
typedef struct h f p c o d e c h f p c o d e c t ;
/∗ ∗
∗ @ b r i e f I n i t i a l i z e HFP Audio Codec f o r mSBC
∗ @ de pr e ca te d P l e a s e use h f p c o d e c i n i t m s b c w i t h c o d e c
∗ @param h f p c o d e c
∗ @param m s b c e n c o d e r c o n t e x t f o r msbc e n c o d e r
∗ @return s t a t u s
∗/
void h f p c o d e c i n i t m s b c ( h f p c o d e c t ∗ h f p c o d e c ,
b t s t a c k s b c e n c o d e r s t a t e t ∗ msbc encoder context ) ;
#endif
/∗ ∗
∗ @ b r i e f Get number o f a u d i o s a m p l e s p e r HFP SCO frame
∗ @param h f p c o d e c
∗ @return num a u d i o s a m p l e s p e r 7 . 5 ms SCO p a c k e t
∗/
uint16 t h f p c o d e c n u m a u d i o s a m p l e s p e r f r a m e ( const h f p c o d e c t ∗
hfp codec ) ;
/∗ ∗
∗ @ b r i e f Checks i f n e x t frame can be encoded
∗ @param h f p c o d e c
∗/
b o o l h f p c o d e c c a n e n c o d e a u d i o f r a m e n o w ( const h f p c o d e c t ∗
hfp codec ) ;
/∗ ∗
∗ Get number o f b y t e s r e a d y f o r s e n d i n g
∗ @param h f p c o d e c
∗ @return num b y t e s r e a d y f o r c u r r e n t p a c k e t
∗/
uint16 t h f p c o d e c n u m b y t e s a v a i l a b l e ( const h f p c o d e c t ∗ h f p c o d e c
);
/∗ ∗
∗ Encode a u d i o s a m p l e s f o r HFP SCO p a c k e t
∗ @param h f p c o d e c
∗ @param pcm samples − c o m p l e t e a u d i o frame o f
hfp msbc num audio samples per frame int16 samples
∗/
void h f p c o d e c e n c o d e a u d i o f r a m e ( h f p c o d e c t ∗ h f p c o d e c , i n t 1 6 t ∗
pcm samples ) ;
/∗ ∗
∗ Read from stream i n t o SCO p a c k e t b u f f e r
∗ @param h f p c o d e c
∗ @param b u f f e r t o s t o r e stream
∗ @param s i z e num b y t e s t o re ad from stream
∗/
void h f p c o d e c r e a d f r o m s t r e a m ( h f p c o d e c t ∗ h f p c o d e c , uint8 t ∗
b u f f e r , uint16 t s i z e ) ;
/∗ ∗
∗ @param h f p c o d e c
∗/
void h f p c o d e c d e i n i t ( h f p c o d e c t ∗ h f p c o d e c ) ;
typedef struct {
bool u s e d s l o t ;
hfp enhanced call status t enhanced status ;
hfp enhanced call dir t direction ;
437
h f p e n h a n c e d c a l l m o d e t mode ;
h f p e n h a n c e d c a l l m p t y t mpty ;
// TODO: s o r t on drop c a l l , so t h a t i n d e x c o r r e s p o n d s t o t a b l e
index
int i n d e x ;
uint8 t c l i p t y p e ;
char clip number [ 2 5 ] ;
} hfp gsm call t ;
h f p c a l l h e l d s t a t u s t h f p g s m c a l l h e l d s t a t u s ( void ) ;
h f p c a l l s t a t u s t h f p g s m c a l l s t a t u s ( void ) ;
h f p c a l l s e t u p s t a t u s t h f p g s m c a l l s e t u p s t a t u s ( void ) ;
int h f p g s m g e t n u m b e r o f c a l l s ( void ) ;
char ∗ h f p g s m l a s t d i a l e d n u m b e r ( void ) ;
void h f p g s m c l e a r l a s t d i a l e d n u m b e r ( void ) ;
void h f p g s m s e t l a s t d i a l e d n u m b e r ( const char∗ number ) ;
h f p g s m c a l l t ∗ h f p g s m c a l l ( int i n d e x ) ;
int h f p g s m c a l l p o s s i b l e ( void ) ;
uint8 t h f p g s m c l i p t y p e ( void ) ;
char ∗ h f p g s m c l i p n u m b e r ( void ) ;
void h f p g s m i n i t ( void ) ;
void h f p g s m d e i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f C r ea t e HFP Hands−Free (HF) SDP s e r v i c e r e c o r d .
∗ @param s e r v i c e
∗ @param r f c o m m c h a n n e l n r
∗ @param name or NULL f o r d e f a u l t v a l u e . P r o v i d e ”” ( empty s t r i n g )
to skip a t t r i b u t e
∗ @param s u p p o r t e d f e a t u r e s 32− b i t bitmap , s e e HFP HFSF ∗ v a l u e s i n
hfp . h
∗ @param c o d e c s n r number o f c o d e c s i n c o d e c s argument
∗ @param c o d e c s
∗/
void h f p h f c r e a t e s d p r e c o r d w i t h c o d e c s ( uint8 t ∗ s e r v i c e ,
uint32 t s e r v i c e r e c o r d h a n d l e , int r fc om m c ha nn el nr ,
const char ∗ name ,
uint16 t
supported features ,
uint8 t c o d e c s n r ,
const uint8 t ∗
codecs ) ;
438
/∗ ∗
∗ @ b r i e f S e t up HFP Hands−Free (HF) d e v i c e w i t h o u t a d d i t i o n a l
supported features .
∗ @param r f c o m m c h a n n e l n r
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − L2CAP SERVICE ALREADY REGISTERED,
∗ − RFCOMM SERVICE ALREADY REGISTERED or
∗ − BTSTACK MEMORY ALLOC FAILED i f a l l o c a t i o n o f
any o f RFCOMM or L2CAP s e r v i c e s f a i l e d
∗/
uint8 t h f p h f i n i t ( uint8 t r f c o m m c h a n n e l n r ) ;
/∗ ∗
∗ @brief Set codecs .
∗ @param c o d e c s n r number o f c o d e c s i n c o d e c s argument
∗ @param c o d e c s
∗/
void h f p h f i n i t c o d e c s ( uint8 t c o d e c s n r , const uint8 t ∗ c o d e c s ) ;
/∗ ∗
∗ @brief Set supported f e a t u r e s .
∗ @param s u p p o r t e d f e a t u r e s 32− b i t bitmap , s e e HFP HFSF ∗ v a l u e s i n
hfp . h
∗/
void h f p h f i n i t s u p p o r t e d f e a t u r e s ( uint32 t s u p p o r t e d f e a t u r e s ) ;
/∗ ∗
∗ @ b r i e f S e t HF i n d i c a t o r s .
∗ @param i n d i c a t o r s n r
∗ @param i n d i c a t o r s
∗/
void h f p h f i n i t h f i n d i c a t o r s ( int i n d i c a t o r s n r , const uint16 t ∗
indicators ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k f o r t h e HFP Hands−Free (HF) c l i e n t .
∗ @param c a l l b a c k
∗/
void h f p h f r e g i s t e r p a c k e t h a n d l e r ( btstack packet handler t
callback ) ;
/∗ ∗
∗ @ b r i e f S e t microphone g a i n used d u r i n g SLC f o r Volume
Synchronization .
∗
∗ @param g a i n V a l i d range : [ 0 , 1 5 ]
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE INVALID HCI COMMAND PARAMETERS i f
i n v a l i d g a i n range
∗/
uint8 t h f p h f s e t d e f a u l t m i c r o p h o n e g a i n ( uint8 t g a i n ) ;
439
/∗ ∗
∗ @ b r i e f S e t s p e a k e r g a i n used d u r i n g SLC f o r Volume
Synchronization .
∗
∗ @param g a i n V a l i d range : [ 0 , 1 5 ]
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE INVALID HCI COMMAND PARAMETERS i f
i n v a l i d g a i n range
∗/
uint8 t h f p h f s e t d e f a u l t s p e a k e r g a i n ( uint8 t g a i n ) ;
/∗ ∗
∗ @ b r i e f E s t a b l i s h RFCOMM c o n n e c t i o n w i t h t h e AG w i t h g i v e n
Bluetooth address ,
∗ and perform s e r v i c e l e v e l c o n n e c t i o n (SLC) agreement :
∗ − exchange supported f e a t u r e s
∗ − r e t r i e v e Audio Gateway (AG) i n d i c a t o r s and t h e i r s t a t u s
∗ − e n a b l e i n d i c a t o r s t a t u s u p d a t e i n t h e AG
∗ − n o t i f y t h e AG a b o u t i t s own a v a i l a b l e codecs , i f p o s s i b l e
∗ − r e t r i e v e t h e AG i n f o r m a t i o n d e s c r i b i n g t h e c a l l h o l d and
multiparty services , i f possible
∗ − r e t r i e v e which HF i n d i c a t o r s a r e e n a b l e d on t h e AG, i f p o s s i b l e
∗ The s t a t u s o f SLC c o n n e c t i o n e s t a b l i s h m e n t i s r e p o r t e d v i a
∗ HFP SUBEVENT SERVICE LEVEL CONNECTION ESTABLISHED .
∗
∗ @param b d a d d r B l u e t o o t h a d d r e s s o f t h e AG
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE COMMAND DISALLOWED i f c o n n e c t i o n
a l r e a d y e x i s t s , or
∗ − BTSTACK MEMORY ALLOC FAILED
∗/
uint8 t h f p h f e s t a b l i s h s e r v i c e l e v e l c o n n e c t i o n ( bd addr t bd addr )
;
/∗ ∗
∗ @ b r i e f R e l e a s e t h e RFCOMM c h a n n e l and t h e a u d i o c o n n e c t i o n
b e t w e e n t h e HF and t h e AG.
∗ The s t a t u s o f r e l e a s i n g t h e SLC c o n n e c t i o n i s r e p o r t e d v i a
∗ HFP SUBEVENT SERVICE LEVEL CONNECTION RELEASED .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f r e l e a s e s e r v i c e l e v e l c o n n e c t i o n ( h c i c o n h a n d l e t
acl handle ) ;
/∗ ∗
∗ @ b r i e f Enable s t a t u s u p d a t e f o r a l l i n d i c a t o r s i n t h e AG.
∗ The s t a t u s f i e l d o f t h e HFP SUBEVENT COMPLETE r e p o r t s i f t h e
command was a c c e p t e d .
∗ The s t a t u s o f an AG i n d i c a t o r i s r e p o r t e d v i a
HFP SUBEVENT AG INDICATOR STATUS CHANGED.
440
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f e n a b l e s t a t u s u p d a t e f o r a l l a g i n d i c a t o r s (
hci con handle t acl handle ) ;
/∗ ∗
∗ @ b r i e f D i s a b l e s t a t u s u p d a t e f o r a l l i n d i c a t o r s i n t h e AG.
∗ The s t a t u s f i e l d o f t h e HFP SUBEVENT COMPLETE r e p o r t s i f t h e
command was a c c e p t e d .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f d i s a b l e s t a t u s u p d a t e f o r a l l a g i n d i c a t o r s (
hci con handle t acl handle ) ;
/∗ ∗
∗ @ b r i e f Enable or d i s a b l e s t a t u s u p d a t e f o r t h e i n d i v i d u a l
i n d i c a t o r s i n t h e AG u s i n g bitmap .
∗ The s t a t u s f i e l d o f t h e HFP SUBEVENT COMPLETE r e p o r t s i f t h e
command was a c c e p t e d .
∗ The s t a t u s o f an AG i n d i c a t o r i s r e p o r t e d v i a
HFP SUBEVENT AG INDICATOR STATUS CHANGED.
∗
∗ @param a c l h a n d l e
∗ @param i n d i c a t o r s s t a t u s b i t m a p 32− b i t bitmap , 0 − i n d i c a t o r i s
disabled , 1 − indicator i s enabled
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f s e t s t a t u s u p d a t e f o r i n d i v i d u a l a g i n d i c a t o r s (
h c i c o n h a n d l e t a c l h a n d l e , uint32 t i n d i c a t o r s s t a t u s b i t m a p ) ;
/∗ ∗
∗ @ b r i e f Query t h e name o f t h e c u r r e n t l y s e l e c t e d Network o p e r a t o r
by AG.
∗
∗ The name i s r e s t r i c t e d t o max 16 c h a r a c t e r s . The r e s u l t i s
reported via
∗ HFP SUBEVENT NETWORK OPERATOR CHANGED s u b t y p e
∗ c o n t a i n i n g network o p e r a t o r mode , f o r m at and name .
∗ I f no o p e r a t o r i s s e l e c t e d , f o r m a t and o p e r a t o r a r e o m i t t e d .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
441
/∗ ∗
∗ @ b r i e f Enable Extended Audio Gateway Error r e s u l t c o d e s i n t h e AG
.
∗ Whenever t h e r e i s an e r r o r r e l a t i n g t o t h e f u n c t i o n a l i t y o f t h e
AG as a
∗ r e s u l t o f AT command , t h e AG s h a l l send +CME ERROR. This e r r o r i s
reported via
∗ HFP SUBEVENT EXTENDED AUDIO GATEWAY ERROR, s e e h f p c m e e r r o r t i n
hfp . h
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t
hfp hf enable report extended audio gateway error result code (
hci con handle t acl handle ) ;
/∗ ∗
∗ @ b r i e f D i s a b l e Extended Audio Gateway Error r e s u l t c o d e s i n t h e
AG.
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t
hfp hf disable report extended audio gateway error result code (
hci con handle t acl handle ) ;
/∗ ∗
∗ @brief E s t a b l i s h audio connection .
∗ The s t a t u s o f a u d i o c o n n e c t i o n e s t a b l i s h m e n t i s r e p o r t e d v i a
HFP SUBEVENT AUDIO CONNECTION ESTABLISHED.
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
∗ − ERROR CODE COMMAND DISALLOWED i f c o n n e c t i o n i n
wrong s t a t e
∗/
uint8 t h f p h f e s t a b l i s h a u d i o c o n n e c t i o n ( h c i c o n h a n d l e t
acl handle ) ;
/∗ ∗
442
/∗ ∗
∗ @ b r i e f Answer incoming c a l l .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
∗ − ERROR CODE COMMAND DISALLOWED i f a n s w e r i n g
incoming c a l l w i t h wrong c a l l s e t u p s t a t u s
∗/
uint8 t h f p h f a n s w e r i n c o m i n g c a l l ( h c i c o n h a n d l e t a c l h a n d l e ) ;
/∗ ∗
∗ @ b r i e f R e j e c t incoming c a l l .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f r e j e c t i n c o m i n g c a l l ( h c i c o n h a n d l e t a c l h a n d l e ) ;
/∗ ∗
∗ @ b r i e f R e l e a s e a l l h e l d c a l l s or s e t s User Determined User Busy (
UDUB) f o r a w a i t i n g c a l l .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f u s e r b u s y ( h c i c o n h a n d l e t a c l h a n d l e ) ;
/∗ ∗
∗ @ b r i e f R e l e a s e a l l a c t i v e c a l l s ( i f any e x i s t ) and a c c e p t s t h e
o t h e r ( h e l d or w a i t i n g ) c a l l .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
443
uint8 t h f p h f e n d a c t i v e a n d a c c e p t o t h e r ( h c i c o n h a n d l e t
acl handle ) ;
/∗ ∗
∗ @ b r i e f P l a c e a l l a c t i v e c a l l s ( i f any e x i s t ) on h o l d and a c c e p t s
t h e o t h e r ( h e l d or w a i t i n g ) c a l l .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f s w a p c a l l s ( h c i c o n h a n d l e t a c l h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Add a h e l d c a l l t o t h e c o n v e r s a t i o n .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f j o i n h e l d c a l l ( h c i c o n h a n d l e t a c l h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Connect t h e two c a l l s and d i s c o n n e c t s t h e s u b s c r i b e r from
both c a l l s ( E x p l i c i t Call Transfer ) .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f c o n n e c t c a l l s ( h c i c o n h a n d l e t a c l h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Terminate an incoming or an o u t g o i n g c a l l .
HFP SUBEVENT CALL TERMINATED i s s e n t upon c a l l t e r m i n a t i o n .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f t e r m i n a t e c a l l ( h c i c o n h a n d l e t a c l h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Terminate a l l h e l d c a l l s .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
444
uint8 t h f p h f t e r m i n a t e h e l d c a l l s ( h c i c o n h a n d l e t a c l h a n d l e ) ;
/∗ ∗
∗ @ b r i e f I n i t i a t e o u t g o i n g v o i c e c a l l by p r o v i d i n g t h e d e s t i n a t i o n
phone number t o t h e AG.
∗
∗ @param a c l h a n d l e
∗ @param number
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f d i a l n u m b e r ( h c i c o n h a n d l e t a c l h a n d l e , char ∗
number ) ;
/∗ ∗
∗ @ b r i e f I n i t i a t e o u t g o i n g v o i c e c a l l u s i n g t h e memory d i a l i n g
f e a t u r e o f t h e AG.
∗
∗ @param a c l h a n d l e
∗ @param memory id
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f d i a l m e m o r y ( h c i c o n h a n d l e t a c l h a n d l e , int
memory id ) ;
/∗ ∗
∗ @ b r i e f I n i t i a t e o u t g o i n g v o i c e c a l l by r e c a l l i n g t h e l a s t number
d i a l e d by t h e AG.
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f r e d i a l l a s t n u m b e r ( h c i c o n h a n d l e t a c l h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Enable t h e C a l l Waiting n o t i f i c a t i o n function in the
AG.
∗ The AG s h a l l send t h e c o r r e s p o n d i n g r e s u l t code t o t h e HF
whenever
∗ an incoming c a l l i s w a i t i n g d u r i n g an o n g o i n g c a l l . In t h a t e v e n t
,
∗ t h e HFP SUBEVENT CALL WAITING NOTIFICATION i s e m i t t e d .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
445
uint8 t h f p h f a c t i v a t e c a l l w a i t i n g n o t i f i c a t i o n ( h c i c o n h a n d l e t
acl handle ) ;
/∗ ∗
∗ @brief Disable the C a l l Waiting n o t i f i c a t i o n function in
t h e AG.
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f d e a c t i v a t e c a l l w a i t i n g n o t i f i c a t i o n ( h c i c o n h a n d l e t
acl handle ) ;
/∗ ∗
∗ @ b r i e f Enable t h e C a l l i n g Line I d e n t i f i c a t i o n n o t i f i c a t i o n
f u n c t i o n i n t h e AG.
∗ The AG s h a l l i s s u e t h e c o r r e s p o n d i n g r e s u l t code j u s t a f t e r e v e r y
RING i n d i c a t i o n ,
∗ when t h e HF i s a l e r t e d i n an incoming c a l l . In t h a t e v e n t ,
∗ t h e HFP SUBEVENT CALLING LINE INDETIFICATION NOTIFICATION i s
emitted .
∗ @param a c l h a n d l e
∗/
uint8 t h f p h f a c t i v a t e c a l l i n g l i n e n o t i f i c a t i o n ( h c i c o n h a n d l e t
acl handle ) ;
/∗ ∗
∗ @brief Disable the C a l l i n g Line I d e n t i f i c a t i o n n o t i f i c a t i o n
f u n c t i o n i n t h e AG.
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f d e a c t i v a t e c a l l i n g l i n e n o t i f i c a t i o n ( h c i c o n h a n d l e t
acl handle ) ;
/∗ ∗
∗ @ b r i e f D e a c t i v a t e echo c a n c e l i n g (EC) and n o i s e r e d u c t i o n (NR) i n
t h e AG and emit
∗ HFP SUBEVENT ECHO CANCELING NOISE REDUCTION DEACTIVATE w i t h
s t a t u s ERROR CODE SUCCESS i f AG s u p p o r t s EC and AG.
∗ I f t h e AG s u p p o r t s i t s own embedded echo c a n c e l i n g and/ or n o i s e
reduction function ,
∗ i t s h a l l have EC and NR a c t i v a t e d u n t i l t h i s f u n c t i o n i s c a l l e d .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
446
/∗ ∗
∗ @ b r i e f A c t i v a t e v o i c e r e c o g n i t i o n and emit
HFP SUBEVENT VOICE RECOGNITION ACTIVATED e v e n t w i t h s t a t u s
ERROR CODE SUCCESS
∗ i f s u c c e s s f u l , o t h e r w i s e ERROR CODE COMMAND DISALLOWED.
P r e r e q u i s i t e i s e s t a b l i s h e d SLC .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
∗ − ERROR CODE COMMAND DISALLOWED i f f e a t u r e HFP (HF/
AG)SF VOICE RECOGNITION FUNCTION i s not s u p p o r t e d by HF and AG,
or a l r e a d y a c t i v a t e d
∗/
uint8 t h f p h f a c t i v a t e v o i c e r e c o g n i t i o n ( h c i c o n h a n d l e t
acl handle ) ;
/∗ ∗
∗ @ b r i e f D e c t i v a t e v o i c e r e c o g n i t i o n and emit
HFP SUBEVENT VOICE RECOGNITION DEACTIVATED e v e n t w i t h s t a t u s
ERROR CODE SUCCESS
∗ i f s u c c e s s f u l , o t h e r w i s e ERROR CODE COMMAND DISALLOWED.
P r e r e q u i s i t e i s e s t a b l i s h e d SLC .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
∗ − ERROR CODE COMMAND DISALLOWED i f f e a t u r e HFP (HF/
AG)SF VOICE RECOGNITION FUNCTION i s not s u p p o r t e d by HF and AG,
or a l r e a d y a c t i v a t e d
∗/
uint8 t h f p h f d e a c t i v a t e v o i c e r e c o g n i t i o n ( h c i c o n h a n d l e t
acl handle ) ;
/∗ ∗
∗ @ b r i e f I n d i c a t e t h a t t h e HF i s r e a d y t o a c c e p t a u d i o .
Prerequisite is established voice recognition session .
∗ The HF may c a l l t h i s f u n c t i o n d u r i n g an o n g o i n g AVR ( Audio Voice
R e c o g n i t i o n ) s e s s i o n t o t e r m i n a t e a u d i o o u t p u t from
∗ t h e AG ( i f t h e r e i s any ) and p r e p a r e t h e AG f o r new a u d i o i n p u t .
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
447
/∗ ∗
∗ @ b r i e f S e t microphone g a i n .
∗
∗ @param a c l h a n d l e
∗ @param g a i n V a l i d range : [ 0 , 1 5 ]
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
∗ − ERROR CODE COMMAND DISALLOWED i f i n v a l i d g a i n
range
∗/
uint8 t h f p h f s e t m i c r o p h o n e g a i n ( h c i c o n h a n d l e t a c l h a n d l e , int
gain ) ;
/∗ ∗
∗ @brief Set speaker gain .
∗
∗ @param a c l h a n d l e
∗ @param g a i n V a l i d range : [ 0 , 1 5 ]
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
∗ − ERROR CODE COMMAND DISALLOWED i f i n v a l i d g a i n
range
∗/
uint8 t h f p h f s e t s p e a k e r g a i n ( h c i c o n h a n d l e t a c l h a n d l e , int
gain ) ;
/∗ ∗
∗ @ b r i e f I n s t r u c t t h e AG t o t r a n s m i t a DTMF code .
∗
∗ @param a c l h a n d l e
∗ @param d t m f c o d e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f s e n d d t m f c o d e ( h c i c o n h a n d l e t a c l h a n d l e , char code
);
/∗ ∗
∗ @ b r i e f Read numbers from t h e AG f o r t h e p u r p o s e o f c r e a t i n g
∗ a u n i q u e v o i c e t a g and s t o r i n g t h e number and i t s l i n k e d v o i c e
∗ t a g i n t h e H F s memory .
∗ The number i s r e p o r t e d v i a HFP SUBEVENT NUMBER FOR VOICE TAG.
∗
448
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f r e q u e s t p h o n e n u m b e r f o r v o i c e t a g ( h c i c o n h a n d l e t
acl handle ) ;
/∗ ∗
∗ @ b r i e f Query t h e l i s t o f c u r r e n t c a l l s i n AG.
∗ The r e s u l t i s r e c e i v e d v i a HFP SUBEVENT ENHANCED CALL STATUS.
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f q u e r y c u r r e n t c a l l s t a t u s ( h c i c o n h a n d l e t a c l h a n d l e
);
/∗ ∗
∗ @ b r i e f R e l e a s e a c a l l w i t h i n d e x i n t h e AG.
∗
∗ @param a c l h a n d l e
∗ @param i n d e x
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f r e l e a s e c a l l w i t h i n d e x ( h c i c o n h a n d l e t a c l h a n d l e ,
int i n d e x ) ;
/∗ ∗
∗ @ b r i e f P l a c e a l l p a r t i e s o f a m u l t i p a r t y c a l l on h o l d w i t h t h e
∗ exception of the s p e c i f i e d c a l l .
∗
∗ @param a c l h a n d l e
∗ @param i n d e x
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f p r i v a t e c o n s u l t a t i o n w i t h c a l l ( h c i c o n h a n d l e t
a c l h a n d l e , int i n d e x ) ;
/∗ ∗
∗ @ b r i e f Query t h e s t a t u s o f t h e R e s p o n s e and H o l d state of
t h e AG.
∗ The r e s u l t i s r e p o r t e d v i a HFP SUBEVENT RESPONSE AND HOLD STATUS.
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
449
∗/
uint8 t h f p h f r r h q u e r y s t a t u s ( h c i c o n h a n d l e t a c l h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Put an incoming c a l l on h o l d i n t h e AG.
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f r r h h o l d c a l l ( h c i c o n h a n d l e t a c l h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Accept h e l d incoming c a l l i n t h e AG.
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f r r h a c c e p t h e l d c a l l ( h c i c o n h a n d l e t a c l h a n d l e ) ;
/∗ ∗
∗ @ b r i e f R e j e c t h e l d incoming c a l l i n t h e AG.
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f r r h r e j e c t h e l d c a l l ( h c i c o n h a n d l e t a c l h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Query t h e AG s u b s c r i b e r number . The r e s u l t i s r e p o r t e d v i a
HFP SUBEVENT SUBSCRIBER NUMBER INFORMATION.
∗
∗ @param a c l h a n d l e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
uint8 t h f p h f q u e r y s u b s c r i b e r n u m b e r ( h c i c o n h a n d l e t a c l h a n d l e ) ;
/∗ ∗
∗ @ b r i e f S e t HF i n d i c a t o r .
∗
∗ @param a c l h a n d l e
∗ @param a s s i g n e d n u m b e r
∗ @param v a l u e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f c o n n e c t i o n d o e s not
exist
∗/
450
uint8 t h f p h f s e t h f i n d i c a t o r ( h c i c o n h a n d l e t a c l h a n d l e , int
assigned number , int v a l u e ) ;
/∗ ∗
∗ @ b r i e f T e s t s i f in−band r i n g t o n e i s a c t i v e on AG ( r e q u i r e s SLC)
∗
∗ @param a c l h a n d l e r
∗ @return 0 i f unknown a c l h a n d l e or in−band r i n g −t o n e d i s a b l e d ,
otherwise 1
∗/
int h f p h f i n b a n d r i n g t o n e a c t i v e ( h c i c o n h a n d l e t a c l h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Send AT command ( most l i k e l y a vendor−s p e c i f i c command not
p a r t o f s t a n d a r d HFP) .
∗ @note R e s u l t (OK/ERROR) i s r e p o r t e d v i a
HFP SUBEVENT CUSTOM AT MESSAGE SENT
∗ To r e c e i v e p o t e n t i a l u n s o l i c i t e d r e s u l t code , add
ENABLE HFP AT MESSAGES t o g e t a l l message v i a
HFP SUBEVENT AT MESSAGE RECEIVED
∗
∗ @param a c l h a n d l e
∗ @param at command t o send
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e :
∗ − ERROR CODE UNKNOWN CONNECTION IDENTIFIER i f
c o n n e c t i o n d o e s not e x i s t , or
∗ − ERROR CODE COMMAND DISALLOWED i f e x t e n d e d a u d i o
gateway e r r o r r e p o r t i s d i s a b l e d
∗/
uint8 t h f p h f s e n d a t c o m m a n d ( h c i c o n h a n d l e t a c l h a n d l e , const
char ∗ at command ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r custom AT command .
∗ @param hfp custom at command ( w i t h ’+ ’ p r e f i x )
∗/
void h f p h f r e g i s t e r c u s t o m a t c o m m a n d ( hfp custom at command t ∗
custom at command ) ;
/∗ ∗
∗ @ b r i e f De−I n i t HFP HF
∗/
void h f p h f d e i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f C r ea t e HFP Hands−Free (HF) SDP s e r v i c e r e c o r d .
∗ @ de pr e ca te d Use h f p h f c r e a t e s d p r e c o r d w i t h c o d e c s i n s t e a d
∗ @param s e r v i c e
∗ @param r f c o m m c h a n n e l n r
∗ @param name
∗ @param s u p o r t e d f e a t u r e s 32− b i t bitmap , s e e HFP HFSF ∗ v a l u e s i n
hfp . h
∗ @param w i d e b a n d s p e e c h s u p p o r t e d
∗/
451
/∗ ∗
∗
∗/
void h f p m s b c i n i t ( void ) ;
/∗ ∗
∗
∗/
int h f p m s b c n u m a u d i o s a m p l e s p e r f r a m e ( void ) ;
/∗ ∗
∗
∗/
int h f p m s b c c a n e n c o d e a u d i o f r a m e n o w ( void ) ;
/∗ ∗
∗ @param pcm samples − c o m p l e t e a u d i o frame o f
hfp msbc num audio samples per frame int16 samples
∗/
void h f p m s b c e n c o d e a u d i o f r a m e ( i n t 1 6 t ∗ pcm samples ) ;
/∗ ∗
∗
∗/
int h f p m s b c n u m b y t e s i n s t r e a m ( void ) ;
/∗ ∗
∗
∗ @param b u f f e r t o s t o r e stream
∗ @param s i z e num b y t e s t o re ad from stream
∗/
void h f p m s b c r e a d f r o m s t r e a m ( uint8 t ∗ b u f f e r , int s i z e ) ;
/∗ ∗
∗ @ b r i e f De−I n i t HFP mSBC Codec
∗/
void h f p m s b c d e i n i t ( void ) ;
typedef struct {
uint16 t hid device subclass ;
uint8 t hid country code ;
uint8 t hid virtual cable ;
452
/∗ ∗
∗ @ b r i e f C r ea t e HID D e vi c e SDP s e r v i c e r e c o r d .
∗ @param s e r v i c e Empty b u f f e r i n which a new s e r v i c e r e c o r d w i l l be
stored .
∗ @param h a v e r e m o t e a u d i o c o n t r o l
∗ @param s e r v i c e
∗ @param s e r v i c e r e c o r d h a n d l e
∗ @param params
∗/
void h i d c r e a t e s d p r e c o r d ( uint8 t ∗ s e r v i c e , uint32 t
s e r v i c e r e c o r d h a n d l e , const h i d s d p r e c o r d t ∗ params ) ;
/∗ ∗
∗ @ b r i e f S e t up HID De v i ce
∗ @param b o o t p r o t o c o l m o d e s u p p o r t e d
∗ @param h i d d e s c r i p t o r l e n
∗ @param h i d d e s c r i p t o r
∗/
void h i d d e v i c e i n i t ( b o o l b o o t p r o t o c o l m o d e s u p p o r t e d , uint16 t
h i d d e s c r i p t o r l e n , const uint8 t ∗ h i d d e s c r i p t o r ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k f o r t h e HID D ev i c e c l i e n t .
∗ @param c a l l b a c k
∗/
void h i d d e v i c e r e g i s t e r p a c k e t h a n d l e r ( btstack packet handler t
callback ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r g e t r e p o r t c a l l b a c k f o r t h e HID D ev i c e c l i e n t .
∗ @param c a l l b a c k
∗/
void h i d d e v i c e r e g i s t e r r e p o r t r e q u e s t c a l l b a c k ( int ( ∗ c a l l b a c k ) (
uint16 t h i d c i d , h i d r e p o r t t y p e t r e p o r t t y p e , uint16 t
r e p o r t i d , int ∗ o u t r e p o r t s i z e , uint8 t ∗ o u t r e p o r t ) ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r s e t r e p o r t c a l l b a c k f o r t h e HID D e vi c e c l i e n t .
∗ @param c a l l b a c k
∗/
453
void h i d d e v i c e r e g i s t e r s e t r e p o r t c a l l b a c k ( void ( ∗ c a l l b a c k ) (
uint16 t h i d c i d , h i d r e p o r t t y p e t r e p o r t t y p e , int r e p o r t s i z e
, uint8 t ∗ r e p o r t ) ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k t o r e c e i v e r e p o r t d a t a f o r t h e HID
D e vi c e c l i e n t .
∗ @param c a l l b a c k
∗/
void h i d d e v i c e r e g i s t e r r e p o r t d a t a c a l l b a c k ( void ( ∗ c a l l b a c k ) (
uint16 t c i d , h i d r e p o r t t y p e t r e p o r t t y p e , uint16 t r e p o r t i d ,
int r e p o r t s i z e , uint8 t ∗ r e p o r t ) ) ;
/∗
∗ @ b r i e f C r ea t e HID c o n n e c t i o n t o HID Host
∗ @param addr
∗ @param h i d c i d t o use f o r o t h e r commands
∗ @result status
∗/
uint8 t h i d d e v i c e c o n n e c t ( bd addr t addr , uint16 t ∗ h i d c i d ) ;
/∗
∗ @ b r i e f D i s c o n n e c t from HID Host
∗ @param h i d c i d
∗/
void h i d d e v i c e d i s c o n n e c t ( uint16 t h i d c i d ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t can send now e v e n t t o send HID Report
∗ G e n e r a t e s an HID SUBEVENT CAN SEND NOW s u b e v e n t
∗ @param h i d c i d
∗/
void h i d d e v i c e r e q u e s t c a n s e n d n o w e v e n t ( uint16 t h i d c i d ) ;
/∗ ∗
∗ @ b r i e f Send HID message on i n t e r r u p t c h a n n e l
∗ @param h i d c i d
∗/
void h i d d e v i c e s e n d i n t e r r u p t m e s s a g e ( uint16 t h i d c i d , const
uint8 t ∗ message , uint16 t m e s s a g e l e n ) ;
/∗ ∗
∗ @ b r i e f Send HID message on c o n t r o l c h a n n e l
∗ @param h i d c i d
∗/
void h i d d e v i c e s e n d c o n t r o l m e s s a g e ( uint16 t h i d c i d , const uint8 t
∗ message , uint16 t m e s s a g e l e n ) ;
/∗ ∗
∗ @ b r i e f Retutn 1 i f b o o t p r o t o c o l mode a c t i v e
∗ @param h i d c i d
∗/
int h i d d e v i c e i n b o o t p r o t o c o l m o d e ( uint16 t h i d c i d ) ;
454
/∗ ∗
∗ @ b r i e f De−I n i t HID De v i ce
∗/
void h i d d e v i c e d e i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f S e t up HID Host
∗ @param h i d d e s c r i p t o r s t o r a g e
∗ @param h i d d e s c r i p t o r s t o r a g e l e n
∗/
void h i d h o s t i n i t ( uint8 t ∗ h i d d e s c r i p t o r s t o r a g e , uint16 t
hid descriptor storage len ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k f o r t h e HID Host .
∗ @param c a l l b a c k
∗/
void h i d h o s t r e g i s t e r p a c k e t h a n d l e r ( btstack packet handler t
callback ) ;
/∗
∗ @ b r i e f C r ea t e HID c o n n e c t i o n t o HID D e v ic e and emit
HID SUBEVENT CONNECTION OPENED e v e n t w i t h s t a t u s code ,
∗ f o l l o w e d by HID SUBEVENT DESCRIPTOR AVAILABLE t h a t i n f o r m s i f t h e
HID D e s c r i p t o r was found . In t h e c a s e o f incoming
∗ c o n n e c t i o n , i . e . HID De v i ce i n i t i a t i n g t h e c o n n e c t i o n , t h e
HID SUBEVENT DESCRIPTOR AVAILABLE i s d e l a y e d , and t h e r e p o r t s
∗ may a l r e a d y come v i a HID SUBEVENT REPORT e v e n t . I t i s up t o t h e
a p p l i c a t i o n code i f
∗ t h e s e r e p o r t s s h o u l d be b u f f e r e d or i g n o r e d u n t i l t h e d e s c r i p t o r
is available .
∗ @note HID PROTOCOL MODE REPORT WITH FALLBACK TO BOOT w i l l t r y t i
s e t up REPORT mode , b u t f a l l b a c k t o BOOT mode i f n e c e s s a r y .
∗ @note HID SUBEVENT DESCRIPTOR AVAILABLE p o s s i b l e s t a t u s v a l u e s
are :
∗ − ERROR CODE SUCCESS i f d e s c r i p t o r a v a i l a b l e ,
∗ − ERROR CODE UNSUPPORTED FEATURE OR PARAMETER VALUE i f not , and
∗ − ERROR CODE MEMORY CAPACITY EXCEEDED i f d e s c r i p t o r i s l a r g e r
then the a v a i l a b l e space
∗ @param r e m o t e a d d r
∗ @param p r o t o c o l m o d e s e e h i d p r o t o c o l m o d e t i n b t s t a c k h i d . h
∗ @param h i d c i d t o use f o r o t h e r commands
∗ @ r e s u l t s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE COMMAND DISALLOWED, BTSTACK MEMORY ALLOC FAILED
∗/
uint8 t h i d h o s t c o n n e c t ( bd addr t remote addr , h i d p r o t o c o l m o d e t
p r o t o c o l m o d e , uint16 t ∗ h i d c i d ) ;
/∗
455
/∗
∗ @ b r i e f D e c l i n e incoming HID c o n n e c t i o n , t h i s s h o u l d be c a l l e d
upon r e c e i v i n g HID SUBEVENT INCOMING CONNECTION e v e n t .
∗ @param h i d c i d
∗ @ r e s u l t s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
uint8 t h i d h o s t d e c l i n e c o n n e c t i o n ( uint16 t h i d c i d ) ;
/∗
∗ @ b r i e f D i s c o n n e c t from HID D e v ic e and emit
HID SUBEVENT CONNECTION CLOSED e v e n t .
∗ @param h i d c i d
∗/
void h i d h o s t d i s c o n n e c t ( uint16 t h i d c i d ) ;
// C o n t r o l messages :
/∗
∗ @ b r i e f Send SUSPEND c o n t r o l s i g n a l t o c o n n e c t e d HID D e v ic e . A
B l u e t o o t h HID D e v ic e which r e c e i v e s a SUSPEND c o n t r o l s i g n a l
∗ may o p t i o n a l l y d i s c o n n e c t from t h e B l u e t o o t h HID Host .
∗ @param h i d c i d
∗ @ r e s u l t s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
uint8 t h i d h o s t s e n d s u s p e n d ( uint16 t h i d c i d ) ;
/∗
∗ @ b r i e f Order c o n n e c t e d HID D ev i c e t o e x i t s u s p e n d mode .
∗ The B l u e t o o t h HID D e vi c e s h a l l send a r e p o r t t o t h e B l u e t o o t h HID
Host .
∗ @param h i d c i d
∗ @ r e s u l t s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
uint8 t h i d h o s t s e n d e x i t s u s p e n d ( uint16 t h i d c i d ) ;
/∗
∗ @ b r i e f Unplug c o n n e c t e d HID D e vi c e .
456
/∗
∗ @ b r i e f S e t P r o t o c o l Mode on t h e B l u e t o o t h HID D e vi c e and emit
HID SUBEVENT SET PROTOCOL RESPONSE e v e n t w i t h h a n d s h a k e s t a t u s ,
see hid handshake param type t
∗ @param h i d c i d
∗ @param p r o t o c o l m o d e s e e h i d p r o t o c o l m o d e t i n b t s t a c k h i d . h
∗ @ r e s u l t s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
uint8 t h i d h o s t s e n d s e t p r o t o c o l m o d e ( uint16 t h i d c i d ,
hid protocol mode t protocol mode ) ;
/∗
∗ @ b r i e f R e t r i e v e t h e P r o t o c o l Mode o f t h e B l u e t o o t h HID D ev i c e and
emit HID SUBEVENT GET PROTOCOL RESPONSE w i t h h a n d s h a k e s t a t u s ,
see hid handshake param type t
∗ @param h i d c i d
∗ @param p r o t o c o l m o d e s e e h i d p r o t o c o l m o d e t i n b t s t a c k h i d . h
∗ @ r e s u l t s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
uint8 t h i d h o s t s e n d g e t p r o t o c o l ( uint16 t h i d c i d ) ;
/∗
/∗
∗ @ b r i e f R e q u e s t a HID r e p o r t from t h e B l u e t o o t h HID De v i ce and
emit HID SUBEVENT GET REPORT RESPONSE e v e n t w i t h w i t h
handshake status , see hid handshake param type t .
∗ P o l l i n g B l u e t o o t h HID D e v i c e s u s i n g t h e GET REPORT t r a n s f e r i s
c o s t l y i n terms o f time and overhead ,
∗ and s h o u l d be a v o i d e d whenever p o s s i b l e . The GET REPORT t r a n s f e r
i s t y p i c a l l y o n l y used by a p p l i c a t i o n s
∗ t o d e t e r m i n e t h e i n i t i a l s t a t e o f a B l u e t o o t h HID De v i ce . I f t h e
s t a t e of a r e p o r t changes f r e q u e n t l y ,
∗ t h e n t h e r e p o r t s h o u l d be r e p o r t e d o v e r t h e more e f f i c i e n t
I n t e r r u p t channel , s e e h i d h o s t s e n d r e p o r t .
∗ @param h i d c i d
∗ @param r e p o r t t y p e s e e h i d r e p o r t t y p e t i n b t s t a c k h i d . h
∗ @param r e p o r t i d
∗ @ r e s u l t s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
uint8 t h i d h o s t s e n d g e t r e p o r t ( uint16 t h i d c i d , h i d r e p o r t t y p e t
r e p o r t t y p e , uint8 t r e p o r t i d ) ;
/∗ ∗
∗ @ b r i e f Send HID o u t p u t r e p o r t on i n t e r r u p t c h a n n e l .
∗ @param h i d c i d
∗ @param r e p o r t i d
∗ @param r e p o r t
∗ @param r e p o r t l e n
∗ @ r e s u l t s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
ERROR CODE UNKNOWN CONNECTION IDENTIFIER,
ERROR CODE COMMAND DISALLOWED
∗/
uint8 t h i d h o s t s e n d r e p o r t ( uint16 t h i d c i d , uint8 t r e p o r t i d ,
const uint8 t ∗ r e p o r t , uint8 t r e p o r t l e n ) ;
/∗
∗ @ b r i e f Get d e s c r i p t o r d a t a
∗ @param h i d c i d
∗ @result data
∗/
const uint8 t ∗ h i d d e s c r i p t o r s t o r a g e g e t d e s c r i p t o r d a t a ( uint16 t
hid cid ) ;
/∗
∗ @ b r i e f Get d e s c r i p t o r l e n g t h
∗ @param h i d c i d
∗ @result length
∗/
uint16 t h i d d e s c r i p t o r s t o r a g e g e t d e s c r i p t o r l e n ( uint16 t h i d c i d )
;
/∗ ∗
∗ @ b r i e f De−I n i t HID De v i ce
458
∗/
void h i d h o s t d e i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f S e t up HSP AG.
∗ @param r f c o m m c h a n n e l n r
∗/
void h s p a g i n i t ( uint8 t r f c o m m c h a n n e l n r ) ;
/∗ ∗
∗ @ b r i e f C r ea t e HSP Audio Gateway (AG) SDP s e r v i c e r e c o r d .
∗ @param s e r v i c e Empty b u f f e r i n which a new s e r v i c e r e c o r d w i l l be
stored .
∗ @param s e r v i c e r e c o r d h a n d l e
∗ @param r f c o m m c h a n n e l n r
∗ @param name
∗/
void h s p a g c r e a t e s d p r e c o r d ( uint8 t ∗ s e r v i c e , uint32 t
s e r v i c e r e c o r d h a n d l e , int rf c om m c ha nn el n r , const char ∗ name )
;
/∗ ∗
∗ @ b r i e f R e g i s t e r p a c k e t h a n d l e r t o r e c e i v e HSP AG e v e n t s .
/∗ ∗
∗ @ b r i e f Connect t o HSP Headset .
∗
∗ Perform SDP q u e r y f o r an RFCOMM s e r v i c e on a remote d e v i c e ,
∗ and e s t a b l i s h an RFCOMM c o n n e c t i o n i f such s e r v i c e i s found .
Reception of the
∗ HSP SUBEVENT RFCOMM CONNECTION COMPLETE w i t h s t a t u s 0
∗ i n d i c a t e s i f the connection i s s u c c e s s f u l l y e s t a b l i s h e d .
∗
∗ @param b d a d d r
∗/
459
/∗ ∗
∗ @ b r i e f D i s c o n n e c t from HSP Headset
∗
∗ R e c e p t i o n o f t h e HSP SUBEVENT RFCOMM DISCONNECTION COMPLETE w i t h
status 0
∗ i n d i c a t e s i f the connection i s s u c c e s s f u l l y released .
∗ @param b d a d d r
∗/
void h s p a g d i s c o n n e c t ( void ) ;
/∗ ∗
∗ @brief E s t a b l i s h audio connection .
∗
∗ R e c e p t i o n o f t h e HSP SUBEVENT AUDIO CONNECTION COMPLETE w i t h
status 0
∗ i n d i c a t e s i f the audio connection i s s u c c e s s f u l l y e s t a b l i s h e d .
∗ @param b d a d d r
∗/
void h s p a g e s t a b l i s h a u d i o c o n n e c t i o n ( void ) ;
/∗ ∗
∗ @brief Release audio connection .
∗
∗ R e c e p t i o n o f t h e HSP SUBEVENT AUDIO DISCONNECTION COMPLETE w i t h
status 0
∗ i n d i c a t e s i f the connection i s s u c c e s s f u l l y released .
∗ @param b d a d d r
∗/
void h s p a g r e l e a s e a u d i o c o n n e c t i o n ( void ) ;
/∗ ∗
∗ @ b r i e f S e t microphone g a i n .
∗ @param g a i n V a l i d range : [ 0 , 1 5 ]
∗/
void h s p a g s e t m i c r o p h o n e g a i n ( uint8 t g a i n ) ;
/∗ ∗
∗ @brief Set speaker gain .
∗ @param g a i n V a l i d range : [ 0 , 1 5 ]
∗/
void h s p a g s e t s p e a k e r g a i n ( uint8 t g a i n ) ;
/∗ ∗
∗ @ b r i e f S t a r t r i n g i n g b e c a u s e o f incoming c a l l .
∗/
void h s p a g s t a r t r i n g i n g ( void ) ;
/∗ ∗
∗ @ b r i e f Stop r i n g i n g ( e . g . c a l l was t e r m i n a t e d ) .
∗/
void h s p a g s t o p r i n g i n g ( void ) ;
460
/∗ ∗
∗ @ b r i e f Enable custom AT commands .
∗
∗ Custom commands a r e d i s a b l e d by d e f a u l t .
∗ When e n a b l e d , custom AT commands a r e r e c e i v e d v i a t h e
HSP SUBEVENT HS COMMAND.
∗ @param e n a b l e
∗/
void hsp ag enable custom commands ( int e n a b l e ) ;
/∗ ∗
∗ @ b r i e f Send a custom AT command t o HSP Headset .
∗
∗ On HSP SUBEVENT AG INDICATION, t h e c l i e n t n e ed s t o r e s p o n d
∗ w i t h t h i s f u n c t i o n w i t h t h e r e s u l t t o t h e custom command .
∗ @param r e s u l t
∗/
int h s p a g s e n d r e s u l t ( char ∗ r e s u l t ) ;
/∗ ∗
∗ @ b r i e f S e t p a c k e t t y p e s used f o r o u t g o i n g SCO c o n n e c t i o n r e q u e s t s
∗ @param common s i n g l e p a c k e t t y p e s : SCO PACKET TYPES ∗
∗/
void h s p a g s e t s c o p a c k e t t y p e s ( uint16 t p a c k e t t y p e s ) ;
/∗ ∗
∗ @ b r i e f De−I n i t HSP AG
∗/
void h s p a g d e i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f S e t up HSP HS .
∗ @param r f c o m m c h a n n e l n r
∗/
void h s p h s i n i t ( uint8 t r f c o m m c h a n n e l n r ) ;
/∗ ∗
∗ @ b r i e f C r ea t e HSP Headset (HS) SDP s e r v i c e r e c o r d .
∗ @param s e r v i c e Empty b u f f e r i n which a new s e r v i c e r e c o r d w i l l be
stored .
∗ @param r f c o m m c h a n n e l n r
∗ @param name
∗ @param h a v e r e m o t e a u d i o c o n t r o l
∗/
void h s p h s c r e a t e s d p r e c o r d ( uint8 t ∗ s e r v i c e , uint32 t
s e r v i c e r e c o r d h a n d l e , int rf c om m c ha nn el n r , const char ∗ name ,
uint8 t h a v e r e m o t e a u d i o c o n t r o l ) ;
/∗ ∗
461
∗ @ b r i e f R e g i s t e r p a c k e t h a n d l e r t o r e c e i v e HSP HS e v e n t s .
∗
∗ The HSP HS e v e n t has t y p e HCI EVENT HSP META w i t h f o l l o w i n g
subtypes :
∗ − HSP SUBEVENT RFCOMM CONNECTION COMPLETE
∗ − HSP SUBEVENT RFCOMM DISCONNECTION COMPLETE
∗ − HSP SUBEVENT AUDIO CONNECTION COMPLETE
∗ − HSP SUBEVENT AUDIO DISCONNECTION COMPLETE
∗ − HSP SUBEVENT RING
∗ − HSP SUBEVENT MICROPHONE GAIN CHANGED
∗ − HSP SUBEVENT SPEAKER GAIN CHANGED
∗ − HSP SUBEVENT AG INDICATION
∗
∗ @param c a l l b a c k
∗/
void h s p h s r e g i s t e r p a c k e t h a n d l e r ( btstack packet handler t
callback ) ;
/∗ ∗
∗ @ b r i e f Connect t o HSP Audio Gateway .
∗
∗ Perform SDP q u e r y f o r an RFCOMM s e r v i c e on a remote d e v i c e ,
∗ and e s t a b l i s h an RFCOMM c o n n e c t i o n i f such s e r v i c e i s found .
Reception of the
∗ HSP SUBEVENT RFCOMM CONNECTION COMPLETE w i t h s t a t u s 0
∗ i n d i c a t e s i f the connection i s s u c c e s s f u l l y e s t a b l i s h e d .
∗
∗ @param b d a d d r
∗/
void h s p h s c o n n e c t ( bd addr t bd addr ) ;
/∗ ∗
∗ @ b r i e f D i s c o n n e c t from HSP Audio Gateway
∗
∗ R e l e a s e s t h e RFCOMM c h a n n e l . R e c e p t i o n o f t h e
∗ HSP SUBEVENT RFCOMM DISCONNECTION COMPLETE w i t h s t a t u s 0
∗ i n d i c a t e s i f the connection i s s u c c e s s f u l l y released .
∗ @param b d a d d r
∗/
void h s p h s d i s c o n n e c t ( void ) ;
/∗ ∗
∗ @ b r i e f Send b u t t o n p r e s s a c t i o n . T o g g l e e s t a b l i s h / r e l e a s e o f
audio connection .
∗/
void h s p h s s e n d b u t t o n p r e s s ( void ) ;
/∗ ∗
∗ @brief Triger e s t a b l i s h i n g audio connection .
∗
∗ R e c e p t i o n o f t h e HSP SUBEVENT AUDIO CONNECTION COMPLETE w i t h
status 0
∗ i n d i c a t e s i f the audio connection i s s u c c e s s f u l l y e s t a b l i s h e d .
462
∗ @param b d a d d r
∗/
void h s p h s e s t a b l i s h a u d i o c o n n e c t i o n ( void ) ;
/∗ ∗
∗ @brief Trigger r e l e a s i n g audio connection .
∗
∗ R e c e p t i o n o f t h e HSP SUBEVENT AUDIO DISCONNECTION COMPLETE w i t h
status 0
∗ i n d i c a t e s i f the connection i s s u c c e s s f u l l y released .
∗ @param b d a d d r
∗/
void h s p h s r e l e a s e a u d i o c o n n e c t i o n ( void ) ;
/∗ ∗
∗ @ b r i e f S e t microphone g a i n .
∗
∗ The new g a i n v a l u e w i l l be c o n f i r m e d by t h e HSP Audio Gateway .
∗ A HSP SUBEVENT MICROPHONE GAIN CHANGED e v e n t w i l l be r e c e i v e d .
∗ @param g a i n V a l i d range : [ 0 , 1 5 ]
∗/
void h s p h s s e t m i c r o p h o n e g a i n ( uint8 t g a i n ) ;
/∗ ∗
∗ @brief Set speaker gain .
∗
∗ The new g a i n v a l u e w i l l be c o n f i r m e d by t h e HSP Audio Gateway .
∗ A HSP SUBEVENT SPEAKER GAIN CHANGED e v e n t w i l l be r e c e i v e d .
∗ @param g a i n − v a l i d range : [ 0 , 1 5 ]
∗/
void h s p h s s e t s p e a k e r g a i n ( uint8 t g a i n ) ;
/∗ ∗
∗ @ b r i e f Enable custom i n d i c a t i o n s .
∗
∗ Custom i n d i c a t i o n s a r e d i s a b l e d by d e f a u l t .
∗ When e n a b l e d , custom i n d i c a t i o n s a r e r e c e i v e d v i a t h e
HSP SUBEVENT AG INDICATION .
∗ @param e n a b l e
∗/
void h s p h s e n a b l e c u s t o m i n d i c a t i o n s ( int e n a b l e ) ;
/∗ ∗
∗ @ b r i e f Send answer t o custom i n d i c a t i o n .
∗
∗ On HSP SUBEVENT AG INDICATION, t h e c l i e n t n e ed s t o r e s p o n d
∗ w i t h t h i s f u n c t i o n w i t h t h e r e s u l t t o t h e custom i n d i c a t i o n
∗ @param r e s u l t
∗/
int h s p h s s e n d r e s u l t ( const char ∗ r e s u l t ) ;
/∗ ∗
463
/∗ ∗
∗ @ b r i e f De−I n i t HSP AG
∗/
void h s p h s d e i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f C r e a t e s SDP r e c o r d f o r PANU BNEP s e r v i c e i n p r o v i d e d empty
buffer .
∗ @note Make s u r e t h e b u f f e r i s b i g enough .
∗
∗ @param s e r v i c e i s an empty b u f f e r t o s t o r e s e r v i c e r e c o r d
∗ @param s e r v i c e r e c o r d h a n d l e f o r new s e r v i c e
∗ @param n e t w o r k p a c k e t t y p e s a r r a y o f t y p e s t e r m i n a t e d by a 0 x0000
entry
∗ @param name i f NULL, t h e d e f a u l t s e r v i c e name w i l l be a s s i g n e d
∗ @param d e s c r i p t i o n i f NULL, t h e d e f a u l t s e r v i c e d e s c r i p t i o n w i l l
be a s s i g n e d
∗ @param s e c u r i t y d e s c
∗/
void p a n c r e a t e p a n u s d p r e c o r d ( uint8 t ∗ s e r v i c e , uint32 t
s e r v i c e r e c o r d h a n d l e , uint16 t ∗ n e t w o r k p a c k e t t y p e s , const
char ∗name ,
const char ∗ d e s c r i p t i o n , s e c u r i t y d e s c r i p t i o n t s e c u r i t y d e s c ) ;
/∗ ∗
∗ @ b r i e f C r e a t e s SDP r e c o r d f o r GN BNEP s e r v i c e i n p r o v i d e d empty
buffer .
∗ @note Make s u r e t h e b u f f e r i s b i g enough .
∗
∗ @param s e r v i c e i s an empty b u f f e r t o s t o r e s e r v i c e r e c o r d
∗ @param s e r v i c e r e c o r d h a n d l e f o r new s e r v i c e
∗ @param n e t w o r k p a c k e t t y p e s a r r a y o f t y p e s t e r m i n a t e d by a 0 x0000
entry
∗ @param name i f NULL, t h e d e f a u l t s e r v i c e name w i l l be a s s i g n e d
∗ @param d e s c r i p t i o n i f NULL, t h e d e f a u l t s e r v i c e d e s c r i p t i o n w i l l
be a s s i g n e d
∗ @param s e c u r i t y d e s c
∗ @param IPv4Subnet i s o p t i o n a l s u b n e t d e f i n i t i o n , e . g .
”10.0.0.0/8”
∗ @param IPv6Subnet i s o p t i o n a l s u b n e t d e f i n i t i o n g i v e n i n t h e
s t a n d a r d IETF f o r ma t w i t h t h e a b s o l u t e a t t r i b u t e IDs
∗/
void p a n c r e a t e g n s d p r e c o r d ( uint8 t ∗ s e r v i c e , uint32 t
s e r v i c e r e c o r d h a n d l e , uint16 t ∗ n e t w o r k p a c k e t t y p e s , const
char ∗name ,
464
const char ∗ d e s c r i p t i o n , s e c u r i t y d e s c r i p t i o n t s e c u r i t y d e s c ,
const char ∗ IPv4Subnet ,
const char ∗ IPv6Subnet ) ;
/∗ ∗
∗ @ b r i e f C r e a t e s SDP r e c o r d f o r NAP BNEP s e r v i c e i n p r o v i d e d empty
buffer .
∗ @note Make s u r e t h e b u f f e r i s b i g enough .
∗
∗ @param s e r v i c e i s an empty b u f f e r t o s t o r e s e r v i c e r e c o r d
∗ @param s e r v i c e r e c o r d h a n d l e f o r new s e r v i c e
∗ @param name i f NULL, t h e d e f a u l t s e r v i c e name w i l l be a s s i g n e d
∗ @param n e t w o r k p a c k e t t y p e s a r r a y o f t y p e s t e r m i n a t e d by a 0 x0000
entry
∗ @param d e s c r i p t i o n i f NULL, t h e d e f a u l t s e r v i c e d e s c r i p t i o n w i l l
be a s s i g n e d
∗ @param s e c u r i t y d e s c
∗ @param n e t a c c e s s t y p e t y p e o f a v a i l a b l e network a c c e s s
∗ @param m a x n e t a c c e s s r a t e b a s e d on n e t a c c e s s t y p e measured i n
byte /s
∗ @param IPv4Subnet i s o p t i o n a l s u b n e t d e f i n i t i o n , e . g .
”10.0.0.0/8”
∗ @param IPv6Subnet i s o p t i o n a l s u b n e t d e f i n i t i o n g i v e n i n t h e
s t a n d a r d IETF f o r ma t w i t h t h e a b s o l u t e a t t r i b u t e IDs
∗/
void p a n c r e a t e n a p s d p r e c o r d ( uint8 t ∗ s e r v i c e , uint32 t
s e r v i c e r e c o r d h a n d l e , uint16 t ∗ n e t w o r k p a c k e t t y p e s , const
char ∗name ,
const char ∗ d e s c r i p t i o n , s e c u r i t y d e s c r i p t i o n t s e c u r i t y d e s c ,
net access type t net access type ,
uint32 t m a x n e t a c c e s s r a t e , const char ∗ IPv4Subnet , const char
∗ IPv6Subnet ) ;
// PBAP S u p p o r t e d F e a t u r e s
// PBAP v C a r d S e l e c t o r O p e r a t o r
#define PBAP VCARD SELECTOR OPERATOR OR 0
#define PBAP VCARD SELECTOR OPERATOR AND 1
// PBAP Format
typedef enum {
PBAP FORMAT VCARD 21 = 0 ,
PBAP FORMAT VCRAD 30
} pbap format vcard t ;
// PBAP O b j e c t Types
typedef enum {
PBAP OBJECT TYPE INVALID = 0 ,
PBAP OBJECT TYPE PHONEBOOOK,
PBAP OBJECT TYPE VCARD LISTING,
PBAP OBJECT TYPE VCARD,
} pbap object type t ;
// PBAP Phonebooks
typedef enum {
PBAP PHONEBOOK INVALID = 0 ,
PBAP PHONEBOOK TELECOM CCH,
PBAP PHONEBOOK TELECOM FAV,
PBAP PHONEBOOK TELECOM ICH,
PBAP PHONEBOOK TELECOM MCH,
PBAP PHONEBOOK TELECOM OCH,
PBAP PHONEBOOK TELECOM PB,
PBAP PHONEBOOK TELECOM SPD,
PBAP PHONEBOOK SIM TELECOM CCH,
PBAP PHONEBOOK SIM TELECOM ICH,
PBAP PHONEBOOK SIM TELECOM MCH,
PBAP PHONEBOOK SIM TELECOM OCH,
PBAP PHONEBOOK SIM TELECOM PB
} pbap phonebook t ;
// l e n g t h s
#define PBAP DATABASE IDENTIFIER LEN 16
#define PBAP FOLDER VERSION LEN 16
/∗ ∗
∗ S et u p PhoneBook Access C l i e n t
∗/
void p b a p c l i e n t i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f C r ea t e PBAP c o n n e c t i o n t o a Phone Book S e r v e r (PSE) s e r v e r
on a remote d e v i c e .
∗ I f the server requires authentication , a
PBAP SUBEVENT AUTHENTICATION REQUEST i s e m i t t e d , which
∗ can be answered w i t h p b a p a u t h e n t i c a t i o n p a s s w o r d ( . . ) .
∗ The s t a t u s o f PBAP c o n n e c t i o n e s t a b l i s h m e n t i s r e p o r t e d v i a
PBAP SUBEVENT CONNECTION OPENED e v e n t ,
∗ i . e . on s u c c e s s s t a t u s f i e l d i s s e t t o ERROR CODE SUCCESS.
∗
∗ @param h a n d l e r
∗ @param addr
∗ @param o u t c i d t o use f o r f u r t h e r commands
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
BTSTACK MEMORY ALLOC FAILED i f PBAP or GOEP c o n n e c t i o n a l r e a d y
exists .
∗/
uint8 t p b a p c o n n e c t ( btstack packet handler t h a n d l e r , bd addr t
addr , uint16 t ∗ o u t c i d ) ;
/∗ ∗
∗ @ b r i e f P r o v i d e password f o r OBEX A u t h e n t i c a t i o n a f t e r r e c e i v i n g
PBAP SUBEVENT AUTHENTICATION REQUEST.
∗ The s t a t u s o f PBAP c o n n e c t i o n e s t a b l i s h m e n t i s r e p o r t e d v i a
PBAP SUBEVENT CONNECTION OPENED e v e n t ,
∗ i . e . on s u c c e s s s t a t u s f i e l d i s s e t t o ERROR CODE SUCCESS.
∗
∗ @param p b a p c i d
∗ @param password ( n u l l t e r m i n a t e d s t r i n g ) − not c o p i e d , n ee d s t o
stay v a l i d u n t i l connection completed
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
BTSTACK BUSY i f i n a wrong s t a t e .
∗/
uint8 t p b a p a u t h e n t i c a t i o n p a s s w o r d ( uint16 t pb a p c id , const char ∗
password ) ;
/∗ ∗
∗ @ b r i e f D i s c o n n e c t s PBAP c o n n e c t i o n w i t h g i v e n i d e n t i f i e r .
∗ Event PBAP SUBEVENT CONNECTION CLOSED i n d i c a t e s t h a t PBAP
connection i s closed .
∗
∗ @param p b a p c i d
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
BTSTACK BUSY i f i n a wrong s t a t e .
∗/
uint8 t p b a p d i s c o n n e c t ( uint16 t p b a p c i d ) ;
/∗ ∗
468
∗ @ b r i e f S e t c u r r e n t f o l d e r on PSE . The s t a t u s i s r e p o r t e d v i a
PBAP SUBEVENT OPERATION COMPLETED e v e n t .
∗
∗ @param p b a p c i d
∗ @param p a t h − n o t e : p a t h i s not c o p i e d
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
BTSTACK BUSY i f i n a wrong s t a t e .
∗/
uint8 t p b a p s e t p h o n e b o o k ( uint16 t p ba p c id , const char ∗ path ) ;
/∗ ∗
∗ @ b r i e f S e t vCard S e l e c t o r f o r g e t / p u l l phonebook . No e v e n t i s
emitted .
∗
∗ @param p b a p c i d
∗ @param v c a r d s e l e c t o r − c o m b i n a t i o n o f PBAP PROPERTY MASK ∗
properties
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
BTSTACK BUSY i f i n a wrong s t a t e .
∗/
uint8 t p b a p s e t v c a r d s e l e c t o r ( uint16 t pb a p c id , uint32 t
vcard selector ) ;
/∗ ∗
∗ @ b r i e f S e t vCard S e l e c t o r f o r g e t / p u l l phonebook . No e v e n t i s
emitted .
∗
∗ @param p b a p c i d
∗ @param v c a r d s e l e c t o r o p e r a t o r − PBAP VCARD SELECTOR OPERATOR OR
( d e f a u l t ) or PBAP VCARD SELECTOR OPERATOR AND
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
BTSTACK BUSY i f i n a wrong s t a t e .
∗/
uint8 t p b a p s e t v c a r d s e l e c t o r o p e r a t o r ( uint16 t p ba p c id , int
vcard selector operator ) ;
/∗ ∗
∗ @ b r i e f S e t P r o p e r t y S e l e c t o r . No e v e n t i s e m i t t e d .
∗ @param p b a p c i d
∗ @param p r o p e r t y s e l e c t o r − c o m b i n a t i o n o f PBAP PROPERTY MASK ∗
properties
∗ @return
∗/
uint8 t p b a p s e t p r o p e r t y s e l e c t o r ( uint16 t p ba p c id , uint32 t
property selector ) ;
/∗ ∗
∗ @ b r i e f Get s i z e o f phone book from PSE . The r e s u l t i s r e p o r t e d
v i a PBAP SUBEVENT PHONEBOOK SIZE e v e n t .
∗
∗ @param p b a p c i d
∗ @param p a t h − n o t e : p a t h i s not c o p i e d , common p a t h ’ t e l e c o m / pb .
vcf ’
469
/∗ ∗
∗ @ b r i e f P u l l phone book from PSE . The r e s u l t i s r e p o r t e d v i a
r e g i s t e r e d packet handler ( see pbap connect function ) ,
∗ w i t h p a c k e t t y p e s e t t o PBAP DATA PACKET. Event
PBAP SUBEVENT OPERATION COMPLETED marks t h e end o f t h e phone
book .
∗
∗ @param p b a p c i d
∗ @param p a t h − n o t e : p a t h i s not c o p i e d , common p a t h ’ t e l e c o m / pb .
vcf ’
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
BTSTACK BUSY i f i n a wrong s t a t e .
∗/
uint8 t p b a p p u l l p h o n e b o o k ( uint16 t p ba p c id , const char ∗ path ) ;
/∗ ∗
∗ @ b r i e f P u l l vCard l i s t i n g . vCard d a t a i s e m i t t e d v i a
PBAP SUBEVENT CARD RESULT e v e n t .
∗ Event PBAP SUBEVENT OPERATION COMPLETED marks t h e end o f vCard
listing .
∗
∗ @param p b a p c i d
∗ @param p a t h
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
BTSTACK BUSY i f i n a wrong s t a t e .
∗/
uint8 t p b a p p u l l v c a r d l i s t i n g ( uint16 t pb a p c id , const char ∗ path
);
/∗ ∗
∗ @ b r i e f P u l l vCard e n t r y . The r e s u l t i s r e p o r t e d v i a c a l l b a c k ( s e e
pbap connect function ) ,
∗ w i t h p a c k e t t y p e s e t t o PBAP DATA PACKET.
∗ Event PBAP SUBEVENT OPERATION COMPLETED marks t h e end o f t h e
vCard e n t r y .
∗
∗ @param p b a p c i d
∗ @param p a t h
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
BTSTACK BUSY i f i n a wrong s t a t e .
∗/
uint8 t p b a p p u l l v c a r d e n t r y ( uint16 t p ba p c id , const char ∗ path ) ;
/∗ ∗
∗ @ b r i e f Lookup c o n t a c t ( s ) by phone number . vCard d a t a i s e m i t t e d
v i a PBAP SUBEVENT CARD RESULT e v e n t .
∗ Event PBAP SUBEVENT OPERATION COMPLETED marks t h e end o f t h e
lookup .
470
∗
∗ @param p b a p c i d
∗ @param phone number
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
BTSTACK BUSY i f i n a wrong s t a t e .
∗/
uint8 t pbap lookup by number ( uint16 t p ba p c id , const char ∗
phone number ) ;
/∗ ∗
∗ @ b r i e f Abort c u r r e n t o p e r a t i o n . No e v e n t i s e m i t t e d .
∗
∗ @param p b a p c i d
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
BTSTACK BUSY i f i n a wrong s t a t e .
∗/
uint8 t p b a p a b o r t ( uint16 t p b a p c i d ) ;
/∗ ∗
∗ @ b r i e f S e t f l o w c o n t r o l mode − d e f a u l t i s o f f . No e v e n t i s
emitted .
∗ @note When e n a b l e d , p b a p n e x t p a c k e t ne e ds t o be c a l l e d a f t e r a
p a c k e t was p r o c e s s e d t o r e c e i v e t h e n e x t one
∗
∗ @param p b a p c i d
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
BTSTACK BUSY i f i n a wrong s t a t e .
∗/
uint8 t p b a p s e t f l o w c o n t r o l m o d e ( uint16 t p ba p c id , int e n a b l e ) ;
/∗ ∗
∗ @ b r i e f T r i g g e r n e x t p a c k e t from PSE when Flow C o n t r o l Mode i s
enabled .
∗ @param p b a p c i d
∗ @return s t a t u s ERROR CODE SUCCESS on s u c c e s s , o t h e r w i s e
BTSTACK BUSY i f i n a wrong s t a t e .
∗/
uint8 t p b a p n e x t p a c k e t ( uint16 t p b a p c i d ) ;
/∗ ∗
∗ @ b r i e f De−I n i t PBAP C l i e n t
∗/
void p b a p c l i e n t d e i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f S e t up RFCOMM.
∗/
void r f c o m m i n i t ( void ) ;
471
/∗ ∗
∗ @ b r i e f S e t s e c u r i t y l e v e l r e q u i r e d f o r incoming c o n n e c t i o n s , need
t o be c a l l e d b e f o r e r e g i s t e r i n g s e r v i c e s .
∗ @ de pr e ca te d use g a p s e t s e c u r i t y l e v e l i n s t e a d
∗/
void r f c o m m s e t r e q u i r e d s e c u r i t y l e v e l ( g a p s e c u r i t y l e v e l t
security level ) ;
/∗
∗ @ b r i e f C r ea t e RFCOMM c o n n e c t i o n t o a g i v e n s e r v e r c h a n n e l on a
remote d e i v c e .
∗ This c h a n n e l w i l l a u t o m a t i c a l l y p r o v i d e enough c r e d i t s t o t h e
remote s i d e .
∗ @param addr
∗ @param s e r v e r c h a n n e l
∗ @param o u t c i d
∗ @result status
∗/
uint8 t r f c o m m c r e a t e c h a n n e l ( btstack packet handler t
p a c k e t h a n d l e r , bd addr t addr , uint8 t s e r v e r c h a n n e l , uint16 t
∗ out cid ) ;
/∗
∗ @ b r i e f C r ea t e RFCOMM c o n n e c t i o n t o a g i v e n s e r v e r c h a n n e l on a
remote d e i v c e .
∗ This c h a n n e l w i l l use e x p l i c i t c r e d i t management . During c h a n n e l
e s t a b l i s h m e n t , an i n i t i a l amount o f c r e d i t s i s provided .
∗ @param addr
∗ @param s e r v e r c h a n n e l
∗ @param i n i t i a l c r e d i t s
∗ @param o u t c i d
∗ @result status
∗/
uint8 t r f c o m m c r e a t e c h a n n e l w i t h i n i t i a l c r e d i t s (
btstack packet handler t p a c k e t h a n d l e r , bd addr t addr , uint8 t
s e r v e r c h a n n e l , uint8 t i n i t i a l c r e d i t s , uint16 t ∗ out cid ) ;
/∗ ∗
∗ @ b r i e f D i s c o n n e c t s RFCOMM c h a n n e l w i t h g i v e n i d e n t i f i e r .
∗ @return s t a t u s
∗/
uint8 t r f c o m m d i s c o n n e c t ( uint16 t rfcomm cid ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r s RFCOMM s e r v i c e f o r a s e r v e r c h a n n e l and a
maximum frame s i z e , and a s s i g n s a p a c k e t h a n d l e r .
∗ This c h a n n e l p r o v i d e s c r e d i t s a u t o m a t i c a l l y t o t h e remote s i d e −>
no f l o w c o n t r o l
∗ @param p a c k e t h a n d l e r f o r a l l c h a n n e l s o f t h i s s e r v i c e
∗ @param c h a n n e l
∗ @param m a x f r a m e s i z e
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
L2CAP SERVICE ALREADY REGISTERED or BTSTACK MEMORY ALLOC FAILED
∗/
472
/∗ ∗
∗ @ b r i e f R e g i s t e r s RFCOMM s e r v i c e f o r a s e r v e r c h a n n e l and a
maximum frame s i z e , and a s s i g n s a p a c k e t h a n d l e r .
∗ This c h a n n e l w i l l use e x p l i c i t c r e d i t management . During c h a n n e l
e s t a b l i s h m e n t , an i n i t i a l amount o f c r e d i t s i s p r o v i d e d .
∗ @param p a c k e t h a n d l e r f o r a l l c h a n n e l s o f t h i s s e r v i c e
∗ @param c h a n n e l
∗ @param m a x f r a m e s i z e
∗ @param i n i t i a l c r e d i t s
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
L2CAP SERVICE ALREADY REGISTERED or BTSTACK MEMORY ALLOC FAILED
∗/
uint8 t r 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 (
btstack packet handler t p a c k e t h a n d l e r , uint8 t channel ,
uint16 t m a x f r a m e s i z e , uint8 t i n i t i a l c r e d i t s ) ;
/∗ ∗
∗ @ b r i e f U n r e g i s t e r RFCOMM s e r v i c e .
∗/
void r f c o m m u n r e g i s t e r s e r v i c e ( uint8 t s e r v i c e c h a n n e l ) ;
/∗ ∗
∗ @ b r i e f A c c e p t s incoming RFCOMM c o n n e c t i o n .
∗ @return s t a t u s
∗/
uint8 t r f c o m m a c c e p t c o n n e c t i o n ( uint16 t rfcomm cid ) ;
/∗ ∗
∗ @ b r i e f Deny incoming RFCOMM c o n n e c t i o n .
∗ @return s t a t u s
∗/
uint8 t r f c o m m d e c l i n e c o n n e c t i o n ( uint16 t rfcomm cid ) ;
/∗ ∗
∗ @ b r i e f Grant more incoming c r e d i t s t o t h e remote s i d e f o r t h e
g i v e n RFCOMM c h a n n e l i d e n t i f i e r .
∗ @return s t a t u s
∗/
uint8 t r f c o m m g r a n t c r e d i t s ( uint16 t rfcomm cid , uint8 t c r e d i t s ) ;
/∗ ∗
∗ @ b r i e f Checks i f RFCOMM can send p a c k e t .
∗ @param rfcomm cid
∗ @ r e s u l t t r u e i f can send now
∗/
b o o l r f c o m m c a n s e n d p a c k e t n o w ( uint16 t rfcomm cid ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t e m i s s i o n o f RFCOMM EVENT CAN SEND NOW as soon as
possible
473
/∗ ∗
∗ @ b r i e f Sends RFCOMM d a t a p a c k e t t o t h e RFCOMM c h a n n e l w i t h g i v e n
identifier .
∗ @param rfcomm cid
∗ @return s t a t u s
∗/
uint8 t rfcomm send ( uint16 t rfcomm cid , uint8 t ∗ data , uint16 t l e n
);
/∗ ∗
∗ @ b r i e f Sends L o c a l Line S t a t u s , s e e LINE STATUS . .
∗ @param rfcomm cid
∗ @param l i n e s t a t u s
∗ @return s t a t u s
∗/
uint8 t r f c o m m s e n d l o c a l l i n e s t a t u s ( uint16 t rfcomm cid , uint8 t
line status ) ;
/∗ ∗
∗ @ b r i e f Send l o c a l modem s t a t u s . s e e MODEM STAUS . .
∗ @param rfcomm cid
∗ @param modem status
∗ @return s t a t u s
∗/
uint8 t rfcomm send modem status ( uint16 t rfcomm cid , uint8 t
modem status ) ;
/∗ ∗
∗ @ b r i e f C o n f i g u r e remote p o r t
∗ @param rfcomm cid
∗ @param b a u d r a t e
∗ @param d a t a b i t s
∗ @param s t o p b i t s
∗ @param p a r i t y
∗ @param f l o w c o n t r o l
∗ @return s t a t u s
∗/
uint8 t r f c o m m s e n d p o r t c o n f i g u r a t i o n ( uint16 t rfcomm cid ,
rpn baud t baud rate , r p n d a t a b i t s t data bits , r p n s t o p b i t s t
s t o p b i t s , r p n p a r i t y t p a r i t y , uint8 t f l o w c o n t r o l ) ;
/∗ ∗
∗ @ b r i e f Query remote p o r t
∗ @param rfcomm cid
∗ @return s t a t u s
∗/
474
/∗ ∗
∗ @ b r i e f Query max frame s i z e
∗ @param rfcomm cid
∗ @return max frame s i z e
∗/
uint16 t r f c o m m g e t m a x f r a m e s i z e ( uint16 t rfcomm cid ) ;
/∗ ∗
∗ @ b r i e f R e s e r v e p a c k e t b u f f e r t o a l l o w t o c r e a t e RFCOMM p a c k e t i n
place
∗ @note Must o n l y be c a l l e d a f t e r a ’ can send now ’ c h e c k or e v e n t
∗ @note A s s e r t s i f p a c k e t b u f f e r i s a l r e a d y r e s e r v e d
∗
∗ i f ( rfcomm can send packet now ( cid ) ) {
∗ rfcomm reserve packet buffer () ;
∗ uint8 t ∗ buffer = rfcomm get outgoing buffer () ;
∗ uint16 t b u f f e r s i z e = rfcomm get max frame size ( cid ) ;
∗ . . setup data in b u f f e r with len . .
∗ rfcomm send prepared ( cid , len )
∗ }
∗/
void r f c o m m r e s e r v e p a c k e t b u f f e r ( void ) ;
/∗ ∗
∗ @ b r i e f Get o u t g o i n g b u f f e r
∗ @return p o i n t e r t o o u t g o i n g rfcomm b u f f e r
∗/
uint8 t ∗ r f c o m m g e t o u t g o i n g b u f f e r ( void ) ;
/∗ ∗
∗ @ b r i e f Send p a c k e t p r e p a r e d i n o u t g o i n g b u f f e r
∗ @note This r e l e a s e s t h e o u t g o i n g rfcomm b u f f e r
∗ @param rfcomm cid
∗ @param l e n
∗ @return s t a t u s
∗/
uint8 t r f c o m m s e n d p r e p a r e d ( uint16 t rfcomm cid , uint16 t l e n ) ;
/∗ ∗
∗ @ b r i e f R e l e a s e o u t g o i n g b u f f e r i n c a s e r f c o m m s e n d p r e p a r e d was
not c a l l e d
∗/
void r f c o m m r e l e a s e p a c k e t b u f f e r ( void ) ;
/∗ ∗
∗ @ b r i e f Enable L2CAP ERTM mode f o r RFCOMM. r e q u e s t c a l l b a c k i s
used t o p r o v i d e ERTM b u f f e r . r e l e a s e d c a l l b a c k r e t u r n s b u f f e r
∗
∗ @note on r e q u e s t c a l l b a c k , t h e app must s e t t h e e r t m c o n f i g ,
b u f f e r , s i z e f i e l d s t o e n a b l e ERTM f o r t h e c u r r e n t c o n n e c t i o n
∗ @note i f b u f f e r i s not s e t , BASIC mode w i l l be used i n s t e a d
∗
475
∗ @note r e l e a s e d c a l l b a c k p r o v i d e s e r t m i d from e a r l i e r r e q u e s t t o
match r e q u e s t and r e l e a s e
∗
∗ @param r e q u e s t c a l l b a c k
∗ @param r e l e a s e d c a l l b a c k
∗/
void r f c o m m e n a b l e l 2 c a p e r t m ( void r e q u e s t c a l l b a c k (
r f c o m m e r t m r e q u e s t t ∗ r e q u e s t ) , void r e l e a s e d c a l l b a c k (
uint16 t e r t m i d ) ) ;
/∗ ∗
∗ @ b r i e f Get f i e l d rfcomm cid from e v e n t
RFCOMM EVENT PORT CONFIGURATION
∗ @param e v e n t p a c k e t
∗ @return rfcomm cid
∗/
s t a t i c i n l i n e uint16 t
r f c o m m e v e n t p o r t c o n f i g u r a t i o n g e t r f c o m m c i d ( const uint8 t ∗
event ) {
return l i t t l e e n d i a n r e a d 1 6 ( event , 2 ) ;
}
/∗ ∗
∗ @ b r i e f Get f i e l d l o c a l from e v e n t RFCOMM EVENT PORT CONFIGURATION
∗ @param e v e n t p a c k e t
∗ @return remote − f a l s e f o r l o c a l p o r t , t r u e f o r remote p o r t
∗/
s t a t i c i n l i n e b o o l r f c o m m e v e n t p o r t c o n f i g u r a t i o n g e t r e m o t e ( const
uint8 t ∗ e v e n t ) {
return e v e n t [ 4 ] != 0 ;
}
/∗ ∗
∗ @ b r i e f Get f i e l d b a u d r a t e from e v e n t
RFCOMM EVENT PORT CONFIGURATION
∗ @param e v e n t p a c k e t
∗ @return b a u d r a t e
∗/
/∗ ∗
∗ @ b r i e f Get f i e l d d a t a b i t s from e v e n t
RFCOMM EVENT PORT CONFIGURATION
∗ @param e v e n t p a c k e t
∗ @return d a t a b i t s
∗/
476
/∗ ∗
∗ @ b r i e f Get f i e l d p a r i t y from e v e n t
RFCOMM EVENT PORT CONFIGURATION
∗ @param e v e n t p a c k e t
∗ @return p a r i t y
∗/
static i n l i n e rpn parity t
r f c o m m e v e n t p o r t c o n f i g u r a t i o n g e t p a r i t y ( const uint8 t ∗ e v e n t
){
return ( r p n p a r i t y t ) ( ( e v e n t [ 6 ] >> 3 ) & 7 ) ;
}
/∗ ∗
∗ @ b r i e f Get f i e l d f l o w c o n t r o l from e v e n t
RFCOMM EVENT PORT CONFIGURATION
∗ @param e v e n t p a c k e t
∗ @return f l o w c o n t r o l
∗/
s t a t i c i n l i n e uint8 t
r f c o m m e v e n t p o r t c o n f i g u r a t i o n g e t f l o w c o n t r o l ( const uint8 t ∗
event ) {
return e v e n t [ 7 ] & 0 x 3 f ;
}
/∗ ∗
∗ @ b r i e f Get f i e l d xon from e v e n t RFCOMM EVENT PORT CONFIGURATION
∗ @param e v e n t p a c k e t
∗ @return xon
∗/
s t a t i c i n l i n e uint8 t r f c o m m e v e n t p o r t c o n f i g u r a t i o n g e t x o n ( const
uint8 t ∗ e v e n t ) {
return e v e n t [ 8 ] ;
}
/∗ ∗
477
/∗ ∗
∗ @ b r i e f De−I n i t RFCOMM
∗/
void r f c o m m d e i n i t ( void ) ;
typedef struct d e s t a t e {
uint8 t in state GET DE HEADER LENGTH ;
uint32 t a d d o n h e a d e r b y t e s ;
uint32 t d e s i z e ;
uint32 t d e o f f s e t ;
} de state t ;
void d e s t a t e i n i t ( d e s t a t e t ∗ s t a t e ) ;
int d e s t a t e s i z e ( uint8 t eventByte , d e s t a t e t ∗ d e s t a t e ) ;
/∗ ∗
∗ @ b r i e f SDP C l i e n t I n i t
∗/
void s d p c l i e n t i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f Checks i f t h e SDP C l i e n t i s r e a d y
∗ @ de pr e ca te d P l e a s e use s d p c l i e n t r e g i s t e r q u e r y c a l l b a c k i n s t e a d
∗ @return t r u e when no q u e r y i s a c t i v e
∗/
b o o l s d p c l i e n t r e a d y ( void ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t s a c a l l b a c k , when t h e SDP C l i e n t i s r e a d y and can
be used
∗ @note The c a l l b a c k might happens b e f o r e
s d p c l i e n t r e g i s t e r q u e r y c a l l b a c k has r e t u r n e d
∗ @param c a l l b a c k r e g i s t r a t i o n
∗/
uint8 t s d p c l i e n t r e g i s t e r q u e r y c a l l b a c k (
btstack context callback registration t ∗ callback registration )
;
/∗ ∗
∗ @ b r i e f Q u e r i e s t h e SDP s e r v i c e o f t h e remote d e v i c e g i v e n a
s e r v i c e s e a r c h p a t t e r n and a l i s t o f a t t r i b u t e IDs .
478
/∗
∗ @ b r i e f S e a r c h e s SDP r e c o r d s on a remote d e v i c e f o r a l l s e r v i c e s
w i t h a g i v e n UUID .
∗ @note c a l l s s d p c l i e n t q u e r y w i t h s e r v i c e s e a r c h p a t t e r n b a s e d on
uuid16
∗/
uint8 t s d p c l i e n t q u e r y u u i d 1 6 ( btstack packet handler t c a l l b a c k ,
bd addr t remote , uint16 t uuid16 ) ;
/∗
∗ @ b r i e f S e a r c h e s SDP r e c o r d s on a remote d e v i c e f o r a l l s e r v i c e s
w i t h a g i v e n UUID .
∗ @note c a l l s s d p c l i e n t q u e r y w i t h s e r v i c e s e a r c h p a t t e r n b a s e d on
uuid128
∗/
uint8 t s d p c l i e n t q u e r y u u i d 1 2 8 ( btstack packet handler t c a l l b a c k ,
bd addr t remote , const uint8 t ∗ uuid128 ) ;
/∗ ∗
∗ @ b r i e f R e t r i e v e s a l l a t t r i b u t e IDs o f a SDP r e c o r d s p e c i f i e d by
i t s s e r v i c e r e c o r d h a n d l e and a l i s t o f a t t r i b u t e IDs .
∗ The remote d a t a i s h a n d l e d by t h e SDP p a r s e r . The SDP p a r s e r
d e l i v e r s a t t r i b u t e v a l u e s and done e v e n t v i a t h e c a l l b a c k .
∗ @note o n l y p r o v i d e d i f ENABLE SDP EXTRA QUERIES i s d e f i n e d
∗ @param c a l l b a c k f o r a t t r i b u t e s v a l u e s and done e v e n t
∗ @param remote a d d r e s s
∗ @param s e a r c h s e r v i c e r e c o r d h a n d l e
∗ @param d e s a t t r i b u t e I D L i s t
∗/
uint8 t s d p c l i e n t s e r v i c e a t t r i b u t e s e a r c h ( btstack packet handler t
c a l l b a c k , bd addr t remote , uint32 t
s e a r c h s e r v i c e r e c o r d h a n d l e , const uint8 t ∗
des attributeIDList ) ;
/∗ ∗
∗ @ b r i e f Query t h e l i s t o f SDP r e c o r d s t h a t match a g i v e n s e r v i c e
search pattern .
∗ The remote d a t a i s h a n d l e d by t h e SDP p a r s e r . The SDP p a r s e r
d e l i v e r s a t t r i b u t e v a l u e s and done e v e n t v i a t h e c a l l b a c k .
∗ @note o n l y p r o v i d e d i f ENABLE SDP EXTRA QUERIES i s d e f i n e d
∗ @param c a l l b a c k f o r a t t r i b u t e s v a l u e s and done e v e n t
∗ @param remote a d d r e s s
479
∗ @param d e s s e r v i c e s e a r c h p a t t e r n
∗/
uint8 t s d p c l i e n t s e r v i c e s e a r c h ( btstack packet handler t c a l l b a c k ,
bd addr t remote , const uint8 t ∗ d e s s e r v i c e s e a r c h p a t t e r n ) ;
/∗ ∗
∗ @ b r i e f De−I n i t SDP C l i e n t
∗/
void s d p c l i e n t d e i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f S e a r c h e s SDP r e c o r d s on a remote d e v i c e f o r RFCOMM
s e r v i c e s w i t h a g i v e n 16− b i t UUID anywhere .
∗ @note c a l l s s d p s e r v i c e s e a r c h p a t t e r n f o r u u i d 1 6 t h a t u s e s
global buffer
∗ @param c a l l b a c k h a n d l e r
∗ @param remote BD ADDR
∗ @param uuid16
∗/
uint8 t s d p c l i e n t q u e r y r f c o m m c h a n n e l a n d n a m e f o r u u i d (
btstack packet handler t c a l l b a c k , bd addr t remote , uint16 t
uuid16 ) ;
/∗ ∗
∗ @ b r i e f S e a r c h e s SDP r e c o r d s on a remote d e v i c e f o r RFCOMM
s e r v i c e s w i t h a g i v e n 16− b i t UUID i n i t s S e r v i c e C l a s s I D L i s t
∗ @note c a l l s s d p s e r v i c e s e a r c h p a t t e r n f o r u u i d 1 6 t h a t u s e s
global buffer
∗ @param c a l l b a c k h a n d l e r
∗ @param remote BD ADDR
∗ @param uuid16
∗/
uint8 t
sdp client query rfcomm channel and name for service class uuid (
btstack packet handler t c a l l b a c k , bd addr t remote , uint16 t
uuid16 ) ;
/∗ ∗
∗ @ b r i e f S e a r c h e s SDP r e c o r d s on a remote d e v i c e f o r RFCOMM
s e r v i c e s w i t h a g i v e n 128− b i t UUID anywhere
∗ @note c a l l s s d p s e r v i c e s e a r c h p a t t e r n f o r u u i d 1 2 8 t h a t u s e s
global buffer
∗ @param c a l l b a c k h a n d l e r
∗ @param remote BD ADDR
∗ @param uuid128
480
∗/
uint8 t s d p c l i e n t q u e r y r f c o m m c h a n n e l a n d n a m e f o r u u i d 1 2 8 (
btstack packet handler t c a l l b a c k , bd addr t remote , const
uint8 t ∗ uuid128 ) ;
/∗ ∗
∗ @ b r i e f S e a r c h e s SDP r e c o r d s on a remote d e v i c e f o r RFCOMM
s e r v i c e s with a given s e r v i ce search pattern .
∗/
uint8 t s d p c l i e n t q u e r y r f c o m m c h a n n e l a n d n a m e f o r s e a r c h p a t t e r n (
btstack packet handler t c a l l b a c k , bd addr t remote , const
uint8 t ∗ d e s s e r v i c e S e a r c h P a t t e r n ) ;
/∗ ∗
∗ @ b r i e f S e t up SDP S e r v e r .
∗/
void s d p i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r S e r v i c e Record w i t h d a t a b a s e u s i n g
ServiceRecordHandle stored in record
∗ @pre A t t r i b u t e I D s a r e i n a s c e n d i n g o r d e r
∗ @pre S e r v i c e R e c o r d H a n d l e i s f i r s t a t t r i b u t e and v a l i d
∗ @param r e c o r d i s not c o p i e d !
∗ @result status
∗/
uint8 t s d p r e g i s t e r s e r v i c e ( const uint8 t ∗ r e c o r d ) ;
/∗ ∗
∗ @brief Unregister s e r v i c e record i n t e r n a l l y .
∗/
void s d p u n r e g i s t e r s e r v i c e ( uint32 t s e r v i c e r e c o r d h a n d l e ) ;
/∗ ∗
∗ @ b r i e f g e t s s e r v i c e r e c o r d h a n d l e from r e c o r d
∗ @ r e s u t l s e r v i c e r e c o r d h a n d l e or 0
∗/
uint32 t s d p g e t s e r v i c e r e c o r d h a n d l e ( const uint8 t ∗ r e c o r d ) ;
/∗ ∗
∗ @ b r i e f Finds an unused v a l i d s e r v i c e r e c o r d h a n d l e
∗ @result handle
∗/
uint32 t s d p c r e a t e s e r v i c e r e c o r d h a n d l e ( void ) ;
/∗ ∗
∗ @brief g e t s record for handle
∗ @result record
∗/
481
uint8 t ∗ s d p g e t r e c o r d f o r h a n d l e ( uint32 t h a n d l e ) ;
/∗ ∗
∗ @ b r i e f De−I n i t SDP S e r v e r
∗/
void s d p d e i n i t ( void ) ;
typedef enum {
DE NIL = 0 ,
DE UINT ,
DE INT ,
DE UUID ,
DE STRING ,
DE BOOL,
DE DES ,
DE DEA,
DE URL
} de type t ;
typedef enum {
DE SIZE 8 = 0 ,
DE SIZE 16 ,
DE SIZE 32 ,
DE SIZE 64 ,
DE SIZE 128 ,
DE SIZE VAR 8 ,
DE SIZE VAR 16 ,
DE SIZE VAR 32
} de size t ;
// MARK: DateElement
void de du mp da ta el em ent ( const uint8 t ∗ r e c o r d ) ;
uint32 t d e g e t l e n ( const uint8 t ∗ h e a d e r ) ;
d e s i z e t d e g e t s i z e t y p e ( const uint8 t ∗ h e a d e r ) ;
d e t y p e t d e g e t e l e m e n t t y p e ( const uint8 t ∗ h e a d e r ) ;
uint32 t d e g e t h e a d e r s i z e ( const uint8 t ∗ h e a d e r ) ;
// r e t u r n s t r u e i f u i n t 1 6 was re ad
bool d e e l e m e n t g e t u i n t 1 6 ( const uint8 t ∗ element , uint16 t ∗
value ) ;
482
void d e c r e a t e s e q u e n c e ( uint8 t ∗ h e a d e r ) ;
void d e s t o r e d e s c r i p t o r w i t h l e n ( uint8 t ∗ header , d e t y p e t
type , d e s i z e t s i z e , uint32 t l e n ) ;
uint8 t ∗ d e p u s h s e q u e n c e ( uint8 t ∗ s e q u e n c e ) ;
void d e p o p s e q u e n c e ( uint8 t ∗ parent , uint8 t ∗ c h i l d ) ;
void de add number ( uint8 t ∗ sequence , d e t y p e t type , d e s i z e t
s i z e , uint32 t v a l u e ) ;
void d e a d d d a t a ( uint8 t ∗ sequence , d e t y p e t type , uint16 t
s i z e , uint8 t ∗ data ) ;
void d e a d d u u i d 1 2 8 ( uint8 t ∗ sequence , uint8 t ∗ uuid ) ;
// r e t u r n s d a t a e l e m e n t l e n i f d a t e e l e m e n t i s s m a l l e r than s i z e
uint32 t d e g e t l e n s a f e ( const uint8 t ∗ header , uint32 t s i z e ) ;
// MARK: DES i t e r a t o r
typedef struct {
uint8 t ∗ e l e m e n t ;
uint16 t pos ;
uint16 t l e n g t h ;
} des iterator t ;
// MARK: SDP
uint16 t s d p a p p e n d a t t r i b u t e s i n a t t r i b u t e I D L i s t ( uint8 t ∗ r e c o r d ,
uint8 t ∗ a t t r i b u t e I D L i s t , uint16 t s t a r t O f f s e t , uint16 t
maxBytes , uint8 t ∗ b u f f e r ) ;
uint8 t ∗ s d p g e t a t t r i b u t e v a l u e f o r a t t r i b u t e i d ( uint8 t ∗ r e c o r d ,
uint16 t a t t r i b u t e I D ) ;
bool s d p s e t a t t r i b u t e v a l u e f o r a t t r i b u t e i d ( uint8 t ∗ r e c o r d ,
uint16 t a t t r i b u t e I D , uint32 t v a l u e ) ;
bool s d p r e c o r d m a t c h e s s e r v i c e s e a r c h p a t t e r n ( uint8 t ∗ r e c o r d ,
uint8 t ∗ s e r v i c e S e a r c h P a t t e r n ) ;
uint16 t s d p g e t f i l t e r e d s i z e ( uint8 t ∗ r e c o r d , uint8 t ∗
attributeIDList ) ;
bool s d p f i l t e r a t t r i b u t e s i n a t t r i b u t e I D L i s t ( uint8 t ∗ r e c o r d ,
uint8 t ∗ a t t r i b u t e I D L i s t , uint16 t s t a r t O f f s e t , uint16 t
maxBytes , uint16 t ∗ usedBytes , uint8 t ∗ b u f f e r ) ;
bool s d p a t t r i b u t e l i s t c o n t a i n s i d ( uint8 t ∗ a t t r i b u t e I D L i s t ,
uint16 t a t t r i b u t e I D ) ;
/∗
∗ @ b r i e f Returns s e r v i c e s e a r c h p a t t e r n f o r g i v e n UUID−16
483
∗ @note Uses f i x e d b u f f e r
∗/
uint8 t ∗ s d p s e r v i c e s e a r c h p a t t e r n f o r u u i d 1 6 ( uint16 t uuid16 ) ;
/∗
∗ @ b r i e f Returns s e r v i c e s e a r c h p a t t e r n f o r g i v e n UUID−128
∗ @note Uses f i x e d b u f f e r
∗/
uint8 t ∗ s d p s e r v i c e s e a r c h p a t t e r n f o r u u i d 1 2 8 ( const uint8 t ∗
uuid128 ) ;
1.89. SPP Server API. spp server.h : Create SPP SDP Records.
/∗ ∗
∗ @ b r i e f C r ea t e SDP r e c o r d f o r SPP s e r v i c e w i t h o f f i c i a l SPP
Service Class
∗ @param s e r v i c e b u f f e r − n ee d s t o l a r g e enough
∗ @param s e r v i c e r e c o r d h a n d l e
∗ @param rfcomm channel
∗ @param name or NULL f o r d e f a u l t v a l u e . P r o v i d e ”” ( empty s t r i n g )
to skip a t t r i b u t e
∗/
void s p p c r e a t e s d p r e c o r d ( uint8 t ∗ s e r v i c e , uint32 t
s e r v i c e r e c o r d h a n d l e , int rfcomm channel , const char ∗name ) ;
/∗ ∗
∗ @ b r i e f C r ea t e SDP r e c o r d f o r SPP s e r v i c e w i t h custom s e r v i c e UUID
( e . g . f o r use w i t h Android )
∗ @param s e r v i c e b u f f e r − n ee d s t o l a r g e enough
∗ @param s e r v i c e r e c o r d h a n d l e
∗ @param s e r v i c e u u i d 1 2 8 b u f f e r
∗ @param rfcomm channel
∗ @param name
∗/
void s p p c r e a t e c u s t o m s d p r e c o r d ( uint8 t ∗ s e r v i c e , uint32 t
s e r v i c e r e c o r d h a n d l e , const uint8 t ∗ s e r v i c e u u i d 1 2 8 , int
rfcomm channel , const char ∗name ) ;
// C l a s s i c + LE
/∗ ∗
∗ @ b r i e f Read RSSI
∗ @param c o n h a n d l e
∗ @events : GAP EVENT RSSI MEASUREMENT
∗/
int g a p r e a d r s s i ( h c i c o n h a n d l e t c o n h a n d l e ) ;
484
/∗ ∗
∗ @ b r i e f Gets l o c a l a d d r e s s .
∗/
void g a p l o c a l b d a d d r ( bd addr t a d d r e s s b u f f e r ) ;
/∗ ∗
∗ @brief Disconnect connection with handle
∗ @param h a n d l e
∗ @return s t a t u s
∗/
uint8 t g a p d i s c o n n e c t ( h c i c o n h a n d l e t h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Get c o n n e c t i o n t y p e
∗ @param c o n h a n d l e
∗ @result connection type
∗/
gap connection type t gap get connection type ( hci con handle t
connection handle ) ;
/∗ ∗
∗ @ b r i e f Get HCI c o n n e c t i o n r o l e
∗ @param c o n h a n d l e
∗ @ r e s u l t h c i r o l e t HCI ROLE MASTER / HCI ROLE SLAVE /
HCI ROLE INVALID ( i f c o n n e c t i o n d o e s not e x i s t )
∗/
h c i r o l e t gap get role ( hci con handle t connection handle ) ;
// C l a s s i c
/∗ ∗
∗ @brief Request r o l e switch
∗ @note t h i s o n l y r e q u e s t s t h e r o l e s w i t c h . A HCI EVENT ROLE CHANGE
i s e m i t t e d and i t s s t a t u s f i e l d w i l l i n d i c a t e i f t h e s w i t c h
was s u c c e s f u l
∗ @param addr
∗ @param h c i r o l e t HCI ROLE MASTER / HCI ROLE SLAVE
∗ @result status
∗/
uint8 t g a p r e q u e s t r o l e ( const bd addr t addr , h c i r o l e t r o l e ) ;
/∗ ∗
∗ @ b r i e f S e t s l o c a l name .
∗ @note D e f a u l t name i s ’ BTstack 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 ’
∗ @note ’ 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 ’ i n l o c a l n a m e w i l l be r e p l a c e d w i t h
a c t u a l bd addr
∗ @param name i s not c o p i e d , make s u r e memory s t a y s v a l i d
∗/
void g a p s e t l o c a l n a m e ( const char ∗ l o c a l n a m e ) ;
/∗ ∗
∗ @ b r i e f S e t Extended I n q u i r y Response d a t a
∗ @note I f not s e t , l o c a l name w i l l be used f o r EIR d a t a ( s e e
gap set local name )
485
∗ @note ’ 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 ’ i n l o c a l n a m e w i l l be r e p l a c e d w i t h
a c t u a l bd addr
∗ @param e i r d a t a s i z e HCI EXTENDED INQUIRY RESPONSE DATA LEN ( 2 4 0 )
b y t e s , i s not c o p i e d make s u r e memory s t a y s v a l i d
∗/
void g a p s e t e x t e n d e d i n q u i r y r e s p o n s e ( const uint8 t ∗ data ) ;
/∗ ∗
∗ @brief Set c l a s s of device
∗/
void g a p s e t c l a s s o f d e v i c e ( uint32 t c l a s s o f d e v i c e ) ;
/∗ ∗
∗ @ b r i e f S e t d e f a u l t l i n k p o l i c y s e t t i n g s f o r a l l c l a s s i c ACL l i n k s
∗ @param d e f a u l t l i n k p o l i c y s e t t i n g s − s e e LM LINK POLICY ∗ i n
bluetooth .h
∗ @note common v a l u e : LM LINK POLICY ENABLE ROLE SWITCH |
LM LINK POLICY ENABLE SNIFF MODE t o e n a b l e r o l e s w i t c h and
s n i f f mode
∗/
void g a p s e t d e f a u l t l i n k p o l i c y s e t t i n g s ( uint16 t
default link policy settings ) ;
/∗ ∗
∗ @brief S e t Allow Role S w i t c h param f o r o u t g o i n g c l a s s i c ACL l i n k s
∗ @param a l l o w r o l e s w i t c h − t r u e : a l l o w remote d e v i c e t o r e q u e s t
role s w i t c h , f a l s e : s t a y master
∗/
void g a p s e t a l l o w r o l e s w i t c h ( bool a l l o w r o l e s w i t c h ) ;
/∗ ∗
∗ @ b r i e f S e t l i n k s u p e r v i s i o n t i m e o u t f o r o u t g o i n g c l a s s i c ACL
links
∗ @param d e f a u l t l i n k s u p e r v i s i o n t i m e o u t ∗ 0 . 6 2 5 ms , d e f a u l t 0
x7d00 = 20 seconds , 0 = no l i n k s u p e r v i s i o n t i m e o u t
∗/
void g a p s e t l i n k s u p e r v i s i o n t i m e o u t ( uint16 t
link supervision timeout ) ;
/∗ ∗
∗ @ b r i e f Enable l i n k watchdog . I f no ACL p a c k e t i s s e n t w i t h i n
timeout ms , t h e l i n k w i l l g e t d i s c o n n e c t e d
∗ note : current implementation uses the automatic f l u s h timeout
c o n t r o l l e r f e a t u r e w i t h a max t i m e o u t o f 1 . 2 8 s
∗ @param t i m e o u t m s
∗/
void g a p e n a b l e l i n k w a t c h d o g ( uint16 t timeout ms ) ;
/∗ ∗
∗ @ b r i e f Enable / d i s a b l e b o n d i n g . D e f a u l t i s e n a b l e d .
∗ @param e n a b l e d
∗/
void g a p s e t b o n d a b l e m o d e ( int e n a b l e d ) ;
486
/∗ ∗
∗ @ b r i e f Get b o n d a b l e mode .
∗ @return 1 i f b o n d a b l e
∗/
int g a p g e t b o n d a b l e m o d e ( void ) ;
/∗ ∗
∗ @ b r i e f S e t s e c u r i t y mode f o r a l l o u t g o i n g and incoming
c o n n e c t i o n s . D e f a u l t : GAP SECURITY MODE 4
∗ @param s e c u r i t y m o d e i s GAP SECURITY MODE 2 or
GAP SECURITY MODE 4
∗ @return s t a t u s ERROR CODE SUCCESS or
ERROR CODE UNSUPPORTED FEATURE OR PARAMETER VALUE
∗/
uint8 t g a p s e t s e c u r i t y m o d e ( g a p s e c u r i t y m o d e t s e c u r i t y m o d e ) ;
/∗ ∗
∗ @ b r i e f Get s e c u r i t y mode
∗ @return s e c u r i t y m o d e
∗/
g a p s e c u r i t y m o d e t g a p g e t s e c u r i t y m o d e ( void ) ;
/∗ ∗
∗ @brief Set s e c u r i t y l e v e l for a l l o u t g o i n g and incoming
c o n n e c t i o n s . D e f a u l t : LEVEL 2
∗ @param s e c u r i t y l e v e l
∗ @note has t o be c a l l e d b e f o r e s e r v i c e s or p r o f i l e s a r e
initialized
∗/
void g a p s e t s e c u r i t y l e v e l ( g a p security level t security level ) ;
/∗ ∗
∗ @ b r i e f Get s e c u r i t y l e v e l
∗ @return s e c u r i t y l e v e l
∗/
g a p s e c u r i t y l e v e l t g a p g e t s e c u r i t y l e v e l ( void ) ;
/∗ ∗
∗ @ b r i e f S e t S e c u r e C o n n e c t i o n s Only Mode f o r BR/EDR ( C l a s s i c )
Default : f a l s e
∗ @param e n a b l e
∗/
void g a p s e t s e c u r e c o n n e c t i o n s o n l y m o d e ( b o o l e n a b l e ) ;
/∗ ∗
∗ @ b r e i f Get S e c u r e C o n n e c t i o n s Only Mode
∗ @param e n a b l e d
∗/
b o o l g a p g e t s e c u r e c o n n e c t i o n s o n l y m o d e ( void ) ;
/∗ ∗
∗ @ b r i e f S e t minimal s e c u r i t y l e v e l f o r r e g i s t e r e d s e r v i c e s
∗ @param s e c u r i t y l e v e l
∗ @note C a l l e d by L2CAP b a s e d on r e g i s t e r e d s e r v i c e s
487
∗/
void g a p s e t m i n i m a l s e r v i c e s e c u r i t y l e v e l ( g a p s e c u r i t y l e v e l t
security level ) ;
/∗ ∗
∗ @brief Register f i l t e r for r e j e c t i n g c l a s s i c connections .
C a l l b a c k w i l l r e t u r n 1 a c c e p t c o n n e c t i o n , 0 on r e j e c t .
∗/
void g a p r e g i s t e r c l a s s i c c o n n e c t i o n f i l t e r ( int ( ∗ a c c e p t c a l l b a c k ) (
bd addr t addr , h c i l i n k t y p e t l i n k t y p e ) ) ;
/∗ C o n f i g u r e S e c u r e Simple P a i r i n g ∗/
/∗ ∗
∗ @ b r i e f Enable w i l l e n a b l e SSP d u r i n g i n i t . D e f a u l t : t r u e
∗/
void g a p s s p s e t e n a b l e ( int e n a b l e ) ;
/∗ ∗
∗ @ b r i e f S e t IO C a p a b i l i t y . BTstack w i l l r e t u r n c a p a b i l i t y t o SSP
requests
∗/
void g a p s s p s e t i o c a p a b i l i t y ( int s s p i o c a p a b i l i t y ) ;
/∗ ∗
∗ @ b r i e f S e t A u t h e n t i c a t i o n Requirements u s i n g d u r i n g SSP
∗/
void g a p s s p s e t a u t h e n t i c a t i o n r e q u i r e m e n t ( int
authentication requirement ) ;
/∗ ∗
∗ @ b r i e f Enable / d i s a b l e S e c u r e C o n n e c t i o n s . D e f a u l t : t r u e i f
s u p p o r t e d by C o n t r o l l e r
∗/
void g a p s e c u r e c o n n e c t i o n s e n a b l e ( b o o l e n a b l e ) ;
/∗ ∗
∗ @ b r i e f Query i f S e c ur e C o n n e c t i o n s can be used f o r C l a s s i c
connections .
∗ @note R e q u i r e s g a p s e c u r e c o n n e c t i o n s e n a b l e == t r u e and
Controller to support i t
∗/
b o o l g a p s e c u r e c o n n e c t i o n s a c t i v e ( void ) ;
/∗ ∗
∗ @ b r i e f I f s e t , BTstack w i l l c o n f i r m a numeric comparison and
enter ’000000 ’ i f r e q u e s t e d .
∗/
void g a p s s p s e t a u t o a c c e p t ( int a u t o a c c e p t ) ;
/∗ ∗
∗ @ b r i e f S e t r e q u i r e d e n c r y p t i o n key s i z e f o r GAP L e v e l s 1−3 on
c l a s s i c connections .
488
/∗ ∗
∗ @brief S t a r t d ed i ca t e d bonding with d e v i c e . Disconnect a f t e r
bonding .
∗ @param d e v i c e
∗ @param r e q u e s t MITM p r o t e c t i o n
∗ @return e r r o r , i f max num a c l c o n n e c t i o n s a c t i v e
∗ @ r e s u l t GAP DEDICATED BONDING COMPLETE
∗/
int g a p d e d i c a t e d b o n d i n g ( bd addr t d e v i c e , int
mitm protection required ) ;
gap security level t gap security level for link key type (
link key type t link key type ) ;
/∗ ∗
∗ @ b r i e f map l i n k k e y s t o s e c u r e c o n n e c t i o n y e s /no
∗/
bool g a p s e c u r e c o n n e c t i o n f o r l i n k k e y t y p e ( l i n k k e y t y p e t
link key type ) ;
/∗ ∗
∗ @ b r i e f map l i n k k e y s t o a u t h e n t i c a t e d
∗/
bool g a p a u t h e n t i c a t e d f o r l i n k k e y t y p e ( l i n k k e y t y p e t
link key type ) ;
void g a p r e q u e s t s e c u r i t y l e v e l ( h c i c o n h a n d l e t c o n h a n d l e ,
gap security level t level ) ;
bool g a p m i t m p r o t e c t i o n r e q u i r e d f o r s e c u r i t y l e v e l (
gap security level t level ) ;
/∗ ∗
∗ @ b r i e f S e t Page Scan Type
∗ @param p a g e s c a n i n t e r v a l ∗ 0 . 6 2 5 ms , range : 0 x0012 . . 0 x1000 ,
d e f a u l t : 0 x0800
∗ @param p a g e s c a n w i n d o w s ∗ 0 . 6 2 5 ms , range : 0 x0011 . .
p a g e s c a n i n t e r v a l , d e f a u l t : 0 x0012
∗/
489
void g a p s e t p a g e s c a n a c t i v i t y ( uint16 t p a g e s c a n i n t e r v a l ,
uint16 t page scan window ) ;
/∗ ∗
∗ @ b r i e f S e t Page Scan Type
∗ @param page scan mode
∗/
void g a p s e t p a g e s c a n t y p e ( p a g e s c a n t y p e t p a g e s c a n t y p e ) ;
/∗ ∗
∗ @ b r i e f S e t Page Timeout
∗ @param p a g e t i m e o u t ∗ 0 . 6 2 5 ms , range : 0 x0001 . . 0 x f f f f , d e f a u l t : 0
x6000 ( ca 15 s e c o n d s )
∗/
void g a p s e t p a g e t i m e o u t ( uint16 t p a g e t i m e o u t ) ;
// LE
/∗ ∗
∗ @ b r i e f S e t p a r a m e t e r s f o r LE Scan
∗ @param s c a n t y p e 0 = p a s s i v e , 1 = a c t i v e
∗ @param s c a n i n t e r v a l range 0 x0004 . . 0 x4000 , u n i t 0 . 6 2 5 ms
∗ @param scan window range 0 x0004 . . 0 x4000 , u n i t 0 . 6 2 5 ms
∗ @param s c a n n i n g f i l t e r p o l i c y 0 = a l l d e v i c e s , 1 = a l l from
whitelist
∗/
void g a p s e t s c a n p a r a m s ( uint8 t s c a n t y p e , uint16 t s c a n i n t e r v a l ,
uint16 t scan window , uint8 t s c a n n i n g f i l t e r p o l i c y ) ;
/∗ ∗
∗ @ b r i e f S e t p a r a m e t e r s f o r LE Scan
∗ @ de pr e ca te d Use g a p s e t s c a n p a r a m s i n s t e a d
∗/
void g a p s e t s c a n p a r a m e t e r s ( uint8 t s c a n t y p e , uint16 t
s c a n i n t e r v a l , uint16 t scan window ) ;
/∗ ∗
∗ @ b r i e f S e t d u p l i c a t e f i l t e r f o r LE Scan
∗ @param e n a b l e d i f e n a b l e d , o n l y one a d v e r t i s e m e n t s p e r BD ADDR i s
reported , d e f a u l t : f a l s e
∗/
void g a p s e t s c a n d u p l i c a t e f i l t e r ( b o o l e n a b l e d ) ;
/∗ ∗
∗ @ b r i e f S e t PHYs f o r LE Scan
∗ @param phy b i t m a s k : 1 = LE 1M PHY, 4 = LE Coded PHY
∗/
void g a p s e t s c a n p h y s ( uint8 t phys ) ;
/∗ ∗
∗ @ b r i e f S t a r t LE Scan
∗/
void g a p s t a r t s c a n ( void ) ;
490
/∗ ∗
∗ @ b r i e f Stop LE Scan
∗/
void g a p s t o p s c a n ( void ) ;
/∗ ∗
∗ @ b r i e f Enable p r i v a c y by u s i n g random a d d r e s s e s
∗ @param r a n d o m a d d r e s s t y p e t o use ( i n c l . OFF)
∗/
void g a p r a n d o m a d d r e s s s e t m o d e ( g a p r a n d o m a d d r e s s t y p e t
random address type ) ;
/∗ ∗
∗ @ b r i e f Get p r i v a c y mode
∗/
g a p r a n d o m a d d r e s s t y p e t g a p r a n d o m a d d r e s s g e t m o d e ( void ) ;
/∗ ∗
∗ @ b r i e f S e t s u p d a t e p e r i o d f o r random a d d r e s s
∗ @param p e r i o d m s i n ms
∗/
void g a p r a n d o m a d d r e s s s e t u p d a t e p e r i o d ( int p e r i o d m s ) ;
/∗ ∗
∗ @ b r i e f S e t s a f i x e d random a d d r e s s f o r a d v e r t i s i n g
∗ @param addr
∗ @note S e t s random a d d r e s s mode t o t y p e s t a t i c
∗/
void g a p r a n d o m a d d r e s s s e t ( const bd addr t addr ) ;
/∗ ∗
∗ @ b r i e f S e t A d v e r t i s e m e n t Data
∗ @param a d v e r t i s i n g d a t a l e n g t h
∗ @param a d v e r t i s i n g d a t a (max 31 o c t e t s )
∗ @note d a t a i s not c o p i e d , p o i n t e r has t o s t a y v a l i d
∗ @note ’ 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 ’ i n a d v e r t i s i n g d a t a w i l l be r e p l a c e d
w i t h a c t u a l bd addr
∗/
void g a p a d v e r t i s e m e n t s s e t d a t a ( uint8 t a d v e r t i s i n g d a t a l e n g t h ,
uint8 t ∗ a d v e r t i s i n g d a t a ) ;
/∗ ∗
∗ @ b r i e f S e t A d v e r t i s e m e n t Parameters
∗ @param a d v i n t m i n
∗ @param a d v i n t m a x
∗ @param a d v t y p e
∗ @param d i r e c t a d d r e s s t y p e
∗ @param d i r e c t a d d r e s s
∗ @param channel map
∗ @param f i l t e r p o l i c y
∗ @note o w n a d d r e s s t y p e i s used from g a p r a n d o m a d d r e s s s e t m o d e
∗/
void g a p a d v e r t i s e m e n t s s e t p a r a m s ( uint16 t a d v i n t m i n , uint16 t
adv int max , uint8 t adv type ,
491
/∗ ∗
∗ @ b r i e f Enable / D i s a b l e A d v e r t i s e m e n t s . OFF by d e f a u l t .
∗ @param e n a b l e d
∗/
void g a p a d v e r t i s e m e n t s e n a b l e ( int e n a b l e d ) ;
/∗ ∗
∗ @ b r i e f S e t Scan Response Data
∗
∗ @note For scan r e s p o n s e data , s c a n n a b l e u n d i r e c t e d a d v e r t i s i n g (
ADV SCAN IND) need t o be used
∗
∗ @param a d v e r t i s i n g d a t a l e n g t h
∗ @param a d v e r t i s i n g d a t a (max 31 o c t e t s )
∗ @note d a t a i s not c o p i e d , p o i n t e r has t o s t a y v a l i d
∗ @note ’ 0 0 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0 ’ i n s c a n r e s p o n s e d a t a w i l l be r e p l a c e d
w i t h a c t u a l bd addr
∗/
void g a p s c a n r e s p o n s e s e t d a t a ( uint8 t s c a n r e s p o n s e d a t a l e n g t h ,
uint8 t ∗ s c a n r e s p o n s e d a t a ) ;
/∗ ∗
∗ @brief Set update i n t e r v a l f o r r e s o l v a b l e p r i v a t e addresses
g e n e r a t e d by t h e C o n t r o l l e r
∗ @param u p d a t e s t i m e o u t f o r u p d a t e s i n s e c o n d s
∗ @return s t a t u s
∗/
uint8 t
gap extended advertising set resolvable private address update (
uint16 t u p d a t e s ) ;
/∗ ∗
∗ @ b r i e f P r o v i d e s t o r a g e f o r new a d v e r t i s i n g s e t and s e t u p on
Controller
∗ @note Using RPA as o w n a d d r e s s t y p e r e q u i r e s
ENABLE LE ENHANCED CONNECTION COMPLETE EVENT i s r e q u i r e d f o r
pairing
∗ @param s t o r a g e t o use by s t a c k , n e ed s t o s t a y v a l i d u n t i l adv s e t
i s removed w i t h g a p e x t e n d e d a d v e r t i s i n g r e m o v e
∗ @param a d v e r t i s i n g p a r a m e t e r s
∗ @param o u t a d v e r t i s i n g h a n d l e t o use w i t h o t h e r adv c o n f i g
commands
∗ @return s t a t u s
∗ @events : GAP SUBEVENT ADVERTISING SET INSTALLED
∗/
uint8 t g a p e x t e n d e d a d v e r t i s i n g s e t u p ( l e a d v e r t i s i n g s e t t ∗
s t o r a g e , const l e e x t e n d e d a d v e r t i s i n g p a r a m e t e r s t ∗
a d v e r t i s i n g p a r a m e t e r s , uint8 t ∗ o u t a d v e r t i s i n g h a n d l e ) ;
/∗ ∗
492
∗ @param S e t a d v e r t i s i n g params f o r a d v e r t i s i n g s e t
∗ @note Using RPA as o w n a d d r e s s t y p e r e q u i r e s
ENABLE LE ENHANCED CONNECTION COMPLETE EVENT i s r e q u i r e d f o r
pairing
∗ @param a d v e r t i s i n g h a n d l e
∗ @param a d v e r t i s i n g p a r a m e t e r s
∗ @return s t a t u s
∗/
uint8 t g a p e x t e n d e d a d v e r t i s i n g s e t p a r a m s ( uint8 t
a d v e r t i s i n g h a n d l e , const l e e x t e n d e d a d v e r t i s i n g p a r a m e t e r s t ∗
advertising parameters ) ;
/∗ ∗
∗ @param Get a d v e r t i s i n g params f o r a d v e r t i s i n g s e t , e . g . t o u p d a t e
params
∗ @param a d v e r t i s i n g h a n d l e
∗ @param a d v e r t i s i n g p a r a m e t e r s
∗ @return s t a t u s
∗/
uint8 t g a p e x t e n d e d a d v e r t i s i n g g e t p a r a m s ( uint8 t
advertising handle , le extended advertising parameters t ∗
advertising parameters ) ;
/∗ ∗
∗ @param S e t p e r i o d i c a d v e r t i s i n g params f o r a d v e r t i s i n g s e t
∗ @param a d v e r t i s i n g h a n d l e
∗ @param a d v e r t i s i n g p a r a m e t e r s
∗ @return s t a t u s
∗/
uint8 t g a p p e r i o d i c a d v e r t i s i n g s e t p a r a m s ( uint8 t
a d v e r t i s i n g h a n d l e , const l e p e r i o d i c a d v e r t i s i n g p a r a m e t e r s t ∗
advertising parameters ) ;
/∗ ∗
∗ @param Get params f o r p e r i o d i c a d v e r t i s i n g s e t , e . g . t o u p d a t e
params
∗ @param a d v e r t i s i n g h a n d l e
∗ @param a d v e r t i s i n g p a r a m e t e r s
∗ @return s t a t u s
∗/
uint8 t g a p p e r i o d i c a d v e r t i s i n g g e t p a r a m s ( uint8 t
advertising handle , le periodic advertising parameters t ∗
advertising parameters ) ;
/∗ ∗
∗ @param S e t random a d d r r e s s f o r a d v e r t i s i n g s e t
∗ @param a d v e r t i s i n g h a n d l e
∗ @param random address
∗ @return s t a t u s
∗/
uint8 t g a p e x t e n d e d a d v e r t i s i n g s e t r a n d o m a d d r e s s ( uint8 t
a d v e r t i s i n g h a n d l e , bd addr t random address ) ;
/∗ ∗
493
∗ @ b r i e f S e t A d v e r t i s i n g Data f o r a a d v e r t i s e m e n t s e t
∗ @param a d v e r t i s i n g h a n d l e
∗ @param a d v e r t i s i n g d a t a l e n g t h
∗ @param a d v e r t i s i n g d a t a
∗ @return s t a t u s
∗/
uint8 t g a p e x t e n d e d a d v e r t i s i n g s e t a d v d a t a ( uint8 t
a d v e r t i s i n g h a n d l e , uint16 t a d v e r t i s i n g d a t a l e n g t h , const
uint8 t ∗ a d v e r t i s i n g d a t a ) ;
/∗ ∗
∗ @ b r i e f S e t Scan Response Data f o r a a d v e r t i s e m e n t s e t
∗ @param a d v e r t i s i n g h a n d l e
∗ @param s c a n r e s p o n s e d a t a l e n g t h
∗ @param s c a n r e s p o n s e d a t a
∗ @return s t a t u s
∗/
uint8 t g a p e x t e n d e d a d v e r t i s i n g s e t s c a n r e s p o n s e d a t a ( uint8 t
a d v e r t i s i n g h a n d l e , uint16 t s c a n r e s p o n s e d a t a l e n g t h , const
uint8 t ∗ s c a n r e s p o n s e d a t a ) ;
/∗ ∗
∗ @brief Set data f o r p e r i o d i c advertisement s e t
∗ @param a d v e r t i s i n g h a n d l e
∗ @param p e r i o d i c d a t a l e n g t h
∗ @param p e r i o d i c d a t a
∗ @return s t a t u s
∗/
uint8 t g a p p e r i o d i c a d v e r t i s i n g s e t d a t a ( uint8 t a d v e r t i s i n g h a n d l e
, uint16 t p e r i o d i c d a t a l e n g t h , const uint8 t ∗ p e r i o d i c d a t a ) ;
/∗ ∗
∗ @brief Start advertising advertising set
∗ @param a d v e r t i s i n g h a n d l e
∗ @param t i m e o u t i n 10ms , or 0 == no t i m e o u t
∗ @param n u m e x t e n d e d a d v e r t i s i n g e v e n t s C o n t r o l l e r s h a l l send , or
0 == no max number
∗ @return s t a t u s
∗/
uint8 t g a p e x t e n d e d a d v e r t i s i n g s t a r t ( uint8 t a d v e r t i s i n g h a n d l e ,
uint16 t timeout , uint8 t n u m e x t e n d e d a d v e r t i s i n g e v e n t s ) ;
/∗ ∗
∗ @ b r i e f Stop a d v e r t i s i n g
∗ @param a d v e r t i s i n g h a n d l e
∗ @return s t a t u s
∗/
uint8 t g a p e x t e n d e d a d v e r t i s i n g s t o p ( uint8 t a d v e r t i s i n g h a n d l e ) ;
/∗ ∗
∗ @brief Start periodic advertising for given advertising set
∗ @param a d v e r t i s i n g h a n d l e
∗ @param i n c l u d e a d i
∗ @return s t a t u s
494
∗/
uint8 t g a p p e r i o d i c a d v e r t i s i n g s t a r t ( uint8 t a d v e r t i s i n g h a n d l e ,
bool i n c l u d e a d i ) ;
/∗ ∗
∗ @ b r i e f Stop p e r i o d i c a d v e r t i s i n g f o r g i v e n a d v e r t i s i n g s e t
∗ @param a d v e r t i s i n g h a n d l e
∗ @return s t a t u s
∗/
uint8 t g a p p e r i o d i c a d v e r t i s i n g s t o p ( uint8 t a d v e r t i s i n g h a n d l e ) ;
/∗ ∗
∗ @ b r i e f S e t D e f a u l t P e r i o d i c A d v e r t i s i n g Sync T r a n s f e r Parameters
∗ @note The p a r a m e t e r s a r e used f o r a l l s u b s e q u e n t c o n n e c t i o n s o v e r
t h e LE t r a n s p o r t .
∗ I f mode != 0 , an
HCI LE Periodic Advertising Sync Transfer Received event w i l l
be e m i t t e d by t h e C o n t r o l l e r
∗ @param mode 0 = i g n o r e ( d e f a u l t ) , 1 = p e r i o d i c a d v e r t i s i n g e v e n t s
disabled
∗ 2 = periodic a d v e r t i s i n g events enabled with
duplicate f i l t e r i n g
∗ 3 = periodic a d v e r t i s i n g events enabled with
duplicate f i l t e r i n g
∗ @param s k i p The number o f p e r i o d i c a d v e r t i s i n g p a c k e t s t h a t can
be s k i p p e d a f t e r a s u c c e s s f u l r e c e i v e
∗ @param s y n c t i m e o u t Range : 0x000A t o 0 x4000 , Time = N∗10 ms , Time
Range : 100 ms t o 1 6 3 . 8 4 s
∗ @param c t e t y p e b i t 0 = Do not sync t o p a c k e t s w i t h an AoA
Constant Tone E x t e n s i o n
∗ b i t 1 = Do not sync t o p a c k e t s w i t h an AoD
Constant Tone E x t e n s i o n w i t h 1 s slots
∗ b i t 2 = Do not sync t o p a c k e t s w i t h an AoD
Constant Tone E x t e n s i o n w i t h 2 s slots
∗ b i t 3 = Do not sync t o p a c k e t s w i t h o u t a
Constant Tone E x t e n s i o n
∗ @return s t a t u s
∗/
uint8 t
gap periodic advertising sync transfer set default parameters (
uint8 t mode , uint16 t s k i p , uint16 t s y n c t i m e o u t , uint8 t
cte type ) ;
/∗ ∗
∗ @ b r i e f Send P e r i o d i c A d v e r t i s i n g Sync T r a n s f e r t o c o n n e c t e d
device
∗ @param c o n h a n d l e o f c o n n e c t e d d e v i c e
∗ @param s e r v i c e d a t a 16− b i t d a t a t o t r a n s f e r t o remote h o s t
∗ @param s y n c h a n d l e o f s y n c h r o n i z e d p e r i o d i c a d v e r t i s i n g t r a i n t o
transfer
∗ @return s t a t u s
∗/
495
uint8 t g a p p e r i o d i c a d v e r t i s i n g s y n c t r a n s f e r s e n d ( h c i c o n h a n d l e t
c o n h a n d l e , uint16 t s e r v i c e d a t a , h c i c o n h a n d l e t s y n c h a n d l e
);
/∗ ∗
∗ @ b r i e f Send P e r i o d i c A d v e r t i s i n g S e t I n f o T r a n s f e r t o c o n n e c t e d
device
∗ @param c o n h a n d l e o f c o n n e c t e d d e v i c e
∗ @param s e r v i c e d a t a 16− b i t d a t a t o t r a n s f e r t o remote h o s t
∗ @param a d v e r t i s i n g h a n d l e o f l o c a l p e r i o d i c a d v e r t i s i n g t r a i n t o
transfer
∗ @return s t a t u s
∗/
uint8 t g a p p e r i o d i c a d v e r t i s i n g s e t i n f o t r a n s f e r s e n d (
h c i c o n h a n d l e t c o n h a n d l e , uint16 t s e r v i c e d a t a , uint8 t
advertising handle ) ;
/∗ ∗
∗ @ b r i e f Remove a d v e r t i s i n g s e t from C o n t r o l l e r
∗ @param a d v e r t i s i n g h a n d l e
∗ @return s t a t u s
∗ @events GAP SUBEVENT ADVERTISING SET REMOVED
∗/
uint8 t g a p e x t e n d e d a d v e r t i s i n g r e m o v e ( uint8 t a d v e r t i s i n g h a n d l e ) ;
/∗ ∗
∗ @ b r i e f C r ea t e B r o a d c a s t I s o c h r o n o u s Group (BIG)
∗ @param s t o r a g e t o use by s t a c k , n e ed s t o s t a y v a l i d u n t i l adv s e t
i s removed w i t h g a p b i g t e r m i n a t e
∗ @param b i g p a r a m s
∗ @return s t a t u s
∗ @events GAP SUBEVENT BIG CREATED u n l e s s i n t e r r u p t e d by c a l l t o
gap big terminate
∗/
uint8 t g a p b i g c r e a t e ( l e a u d i o b i g t ∗ s t o r a g e ,
l e a u d i o b i g p a r a m s t ∗ big params ) ;
/∗ ∗
∗ @ b r i e f Terminate B r o a d c a s t I s o c h r o n o u s Group (BIG)
∗ @param b i g h a n d l e
∗ @return s t a t u s
∗ @events GAP SUBEVENT BIG TERMINATED
∗/
uint8 t g a p b i g t e r m i n a t e ( uint8 t b i g h a n d l e ) ;
/∗ ∗
∗ @ b r i e f S y n c h r o n i z e t o B r o a d c a s t I s o c h r o n o u s Group (BIG)
∗ @param s t o r a g e t o use by s t a c k , n e ed s t o s t a y v a l i d u n t i l adv s e t
i s removed w i t h g a p b i g t e r m i n a t e
∗ @param b i g s y n c p a r a m s
∗ @return s t a t u s
∗ @events GAP SUBEVENT BIG SYNC CREATED u n l e s s i n t e r r u p t e d by c a l l
to gap big sync terminate
∗/
496
uint8 t g a p b i g s y n c c r e a t e ( l e a u d i o b i g s y n c t ∗ s t o r a g e ,
le audio big sync params t ∗ big sync params ) ;
/∗ ∗
∗ @ b r i e f Stop s y n c h r o n i z i n g t o B r o a d c a s t I s o c h r o n o u s Group (BIG) .
T r i g g e r s GAP SUBEVENT BIG SYNC STOPPED
∗ @note Also used t o s t o p s y n c h r o n i z i n g b e f o r e BIG Sync was
established
∗ @param b i g h a n d l e
∗ @return s t a t u s
∗ @events GAP SUBEVENT BIG SYNC STOPPED
∗/
uint8 t g a p b i g s y n c t e r m i n a t e ( uint8 t b i g h a n d l e ) ;
/∗ ∗
∗ @ b r i e f C r ea t e Connected I s o c h r o n o u s Group (CIG)
∗ @param s t o r a g e t o use by s t a c k , n e ed s t o s t a y v a l i d u n t i l CIG
removed w i t h g a p c i g r e m o v e
∗ @param c i g p a r a m s
∗ @return s t a t u s
∗ @events GAP SUBEVENT CIG CREATED u n l e s s i n t e r r u p t e d by c a l l t o
gap cig remove
∗/
uint8 t g a p c i g c r e a t e ( l e a u d i o c i g t ∗ s t o r a g e ,
l e a u d i o c i g p a r a m s t ∗ cig params ) ;
/∗ ∗
∗ @ b r i e f Remove Connected I s o c h r o n o u s Group (CIG)
∗ @param c i g i d
∗ @return s t a t u s
∗ @events GAP SUBEVENT CIG TERMINATED
∗/
uint8 t g a p c i g r e m o v e ( uint8 t c i g i d ) ;
/∗ ∗
∗ @ b r i e f C r ea t e Connected I s o c h r o n o u s Streams ( CIS )
∗ @note number o f CIS from c i g p a r a m s i n g a p c i g c r e a t e i s used
∗ @param c i g i d
∗ @param c i s c o n h a n d l e s a r r a y o f CIS Connection Handles
∗ @param a c l c o n h a n d l e s a r r a y o f ACL Connection Handles
∗ @return s t a t u s
∗ @events GAP SUBEVENT CIS CREATED u n l e s s i n t e r r u p t e d by c a l l t o
gap cig remove
∗/
uint8 t g a p c i s c r e a t e ( uint8 t c i g i d , h c i c o n h a n d l e t
cis con handles [ ] , hci con handle t acl con handles [ ] ) ;
/∗ ∗
∗ @ b r i e f Accept Connected I s o c h r o n o u s Stream ( CIS )
∗ @param c i s c o n h a n d l e
∗ @return s t a t u s
∗ @events GAP SUBEVENT CIS CREATED
∗/
uint8 t g a p c i s a c c e p t ( h c i c o n h a n d l e t c i s c o n h a n d l e ) ;
497
/∗ ∗
∗ @ b r i e f R e j e c t Connected I s o c h r o n o u s Stream ( CIS )
∗ @param c i s c o n h a n d l e
∗ @return s t a t u s
∗ @events GAP SUBEVENT CIS CREATED
∗/
uint8 t g a p c i s r e j e c t ( h c i c o n h a n d l e t c i s c o n h a n d l e ) ;
/∗ ∗
∗ @ b r i e f S e t c o n n e c t i o n p a r a m e t e r s f o r o u t g o i n g c o n n e c t i o n s and
c o n n e c t i o n parameter u p d a t e s
∗ @param c o n n s c a n i n t e r v a l ( u n i t : 0 . 6 2 5 msec ) , d e f a u l t : 60 ms
∗ @param conn scan window ( u n i t : 0 . 6 2 5 msec ) , d e f a u l t : 30 ms
∗ @param c o n n i n t e r v a l m i n ( u n i t : 1 . 2 5 ms) , d e f a u l t : 10 ms
∗ @param c o n n i n t e r v a l m a x ( u n i t : 1 . 2 5 ms) , d e f a u l t : 30 ms
∗ @param c o n n l a t e n c y , d e f a u l t : 4
∗ @param s u p e r v i s i o n t i m e o u t ( u n i t : 10ms) , d e f a u l t : 720 ms
∗ @param m i n c e l e n g t h ( u n i t : 0 . 6 2 5ms) , d e f a u l t : 10 ms
∗ @param m a x c e l e n g t h ( u n i t : 0 . 6 2 5ms) , d e f a u l t : 30 ms
∗/
void g a p s e t c o n n e c t i o n p a r a m e t e r s ( uint16 t c o n n s c a n i n t e r v a l ,
uint16 t conn scan window ,
uint16 t c o n n i n t e r v a l m i n , uint16 t c o n n i n t e r v a l m a x , uint16 t
conn latency ,
uint16 t s u p e r v i s i o n t i m e o u t , uint16 t m i n c e l e n g t h , uint16 t
max ce length ) ;
/∗ ∗
∗ @ b r i e f S e t i n i t i a t i n g PHYs f o r o u t g o i n g c o n n e c t i o n s
∗ @param phy b i t m a s k : 1 = LE 1M PHY, 2 = LE 2M PHY, 4 = LE Coded
PHY
∗/
void g a p s e t c o n n e c t i o n p h y s ( uint8 t phys ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t an u p d a t e o f t h e c o n n e c t i o n parameter f o r a g i v e n
LE c o n n e c t i o n
∗ @param h a n d l e
∗ @param c o n n i n t e r v a l m i n ( u n i t : 1 . 2 5 ms)
∗ @param c o n n i n t e r v a l m a x ( u n i t : 1 . 2 5 ms)
∗ @param c o n n l a t e n c y
∗ @param s u p e r v i s i o n t i m e o u t ( u n i t : 10ms)
∗ @return 0 i f ok
∗/
int g a p r e q u e s t c o n n e c t i o n p a r a m e t e r u p d a t e ( h c i c o n h a n d l e t
c o n h a n d l e , uint16 t c o n n i n t e r v a l m i n ,
uint16 t c o n n i n t e r v a l m a x , uint16 t c o n n l a t e n c y , uint16 t
supervision timeout ) ;
/∗ ∗
∗ @ b r i e f Updates t h e c o n n e c t i o n p a r a m e t e r s f o r a g i v e n LE
connection
∗ @param h a n d l e
498
∗ @param c o n n i n t e r v a l m i n ( u n i t : 1 . 2 5 ms)
∗ @param c o n n i n t e r v a l m a x ( u n i t : 1 . 2 5 ms)
∗ @param c o n n l a t e n c y
∗ @param s u p e r v i s i o n t i m e o u t ( u n i t : 10ms)
∗ @return 0 i f ok
∗/
int g a p u p d a t e c o n n e c t i o n p a r a m e t e r s ( h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t c o n n i n t e r v a l m i n ,
uint16 t c o n n i n t e r v a l m a x , uint16 t c o n n l a t e n c y , uint16 t
supervision timeout ) ;
/∗ ∗
∗ @ b r i e f S e t a c c e p t e d c o n n e c t i o n parameter range
∗ @param range
∗/
void g a p g e t c o n n e c t i o n p a r a m e t e r r a n g e (
l e c o n n e c t i o n p a r a m e t e r r a n g e t ∗ range ) ;
/∗ ∗
∗ @ b r i e f Get a c c e p t e d c o n n e c t i o n parameter range
∗ @param range
∗/
void g a p s e t c o n n e c t i o n p a r a m e t e r r a n g e (
l e c o n n e c t i o n p a r a m e t e r r a n g e t ∗ range ) ;
/∗ ∗
∗ @ b r i e f Test i f c o n n e c t i o n p a r a m e t e r s a r e i n s i d e i n e x i s t i n g r a g e
∗ @param c o n n i n t e r v a l m i n ( u n i t : 1 . 2 5 ms)
∗ @param c o n n i n t e r v a l m a x ( u n i t : 1 . 2 5 ms)
∗ @param c o n n l a t e n c y
∗ @param s u p e r v i s i o n t i m e o u t ( u n i t : 10ms)
∗ @return 1 i f i n c l u d e d
∗/
int g a p c o n n e c t i o n p a r a m e t e r r a n g e i n c l u d e d (
l e c o n n e c t i o n p a r a m e t e r r a n g e t ∗ e x i s t i n g r a n g e , uint16 t
l e c o n n i n t e r v a l m i n , uint16 t l e c o n n i n t e r v a l m a x , uint16 t
l e c o n n l a t e n c y , uint16 t l e s u p e r v i s i o n t i m e o u t ) ;
/∗ ∗
∗ @ b r i e f S e t max number o f c o n n e c t i o n s i n LE P e r i p h e r a l r o l e ( i f
Bluetooth Controller supports i t )
∗ @note : d e f a u l t : 1
∗ @param m a x p e r i p h e r a l c o n n e c t i o n s
∗/
void g a p s e t m a x n u m b e r p e r i p h e r a l c o n n e c t i o n s ( int
max peripheral connections ) ;
/∗ ∗
∗ @ b r i e f Add D e vi c e t o W h i t e l i s t
∗ @param a d d r e s s t y p
∗ @param a d d r e s s
∗ @return s t a t u s
∗/
499
uint8 t g a p w h i t e l i s t a d d ( b d a d d r t y p e t a d d r e s s t y p e , const
bd addr t a d d r e s s ) ;
/∗ ∗
∗ @ b r i e f Remove D e v ic e from W h i t e l i s t
∗ @param a d d r e s s t y p
∗ @param a d d r e s s
∗ @return s t a t u s
∗/
uint8 t g a p w h i t e l i s t r e m o v e ( b d a d d r t y p e t a d d r e s s t y p e , const
bd addr t a d d r e s s ) ;
/∗ ∗
∗ @brief Clear W h i t e l i s t
∗ @return s t a t u s
∗/
uint8 t g a p w h i t e l i s t c l e a r ( void ) ;
/∗ ∗
∗ @ b r i e f Connect t o remote LE d e v i c e
∗ @return s t a t u s
∗/
uint8 t g a p c o n n e c t ( const bd addr t addr , b d a d d r t y p e t a d d r t y p e ) ;
/∗ ∗
∗ @ b r i e f Connect w i t h W h i t e l i s t
∗ @note E x p l i c i t w h i t e l i s t management and t h i s c o n n e c t w i t h
w h i t e l i s t replace deprecated gap auto connection ∗ functions
∗ @return s t a t u s
∗/
uint8 t g a p c o n n e c t w i t h w h i t e l i s t ( void ) ;
/∗ ∗
∗ @ b r i e f Cancel c o n n e c t i o n p r o c e s s i n i t i a t e d by g a p c o n n e c t
∗ @return s t a t u s
∗/
uint8 t g a p c o n n e c t c a n c e l ( void ) ;
/∗ ∗
∗ @ b r i e f Auto Connection E s t a b l i s h m e n t − S t a r t Connecting t o d e v i c e
∗ @ de pr e ca te d P l e a s e s e t u p W h i t e l i s t w i t h g a p w h i t e l i s t ∗ and s t a r t
connecting with g a p c o n n e c t w i t h w h i t e l i s t
∗ @param a d d r e s s t y p e
∗ @param a d d r e s s
∗ @return s t a t u s
∗/
uint8 t g a p a u t o c o n n e c t i o n s t a r t ( b d a d d r t y p e t a d d r e s s t y p e , const
bd addr t a d d r e s s ) ;
/∗ ∗
∗ @ b r i e f Auto Connection E s t a b l i s h m e n t − Stop Connecting t o d e v i c e
∗ @ de pr e ca te d P l e a s e s e t u p W h i t e l i s t w i t h g a p w h i t e l i s t ∗ and s t a r t
connecting with g a p c o n n e c t w i t h w h i t e l i s t
∗ @param a d d r e s s t y p e
500
∗ @param a d d r e s s
∗ @return s t a t u s
∗/
uint8 t g a p a u t o c o n n e c t i o n s t o p ( b d a d d r t y p e t a d d r e s s t y p e , const
bd addr t a d d r e s s ) ;
/∗ ∗
∗ @ b r i e f Auto Connection E s t a b l i s h m e n t − Stop e v e r y t h i n g
∗ @ de pr e ca te d P l e a s e s e t u p W h i t e l i s t w i t h g a p w h i t e l i s t ∗ and s t a r t
connecting with g a p c o n n e c t w i t h w h i t e l i s t
∗ @note Convenience f u n c t i o n t o s t o p a l l a c t i v e a u t o c o n n e c t i o n
attempts
∗ @return s t a t u s
∗/
uint8 t g a p a u t o c o n n e c t i o n s t o p a l l ( void ) ;
/∗ ∗
∗ @ b r i e f S e t LE PHY
∗ @param c o n h a n d l e
∗ @param a l l p h y s 0 = s e t r x / t x , 1 = s e t o n l y rx , 2 = s e t o n l y t x
∗ @param t x p h y s 1 = 1M, 2 = 2M, 4 = Coded
∗ @param r x p h y s 1 = 1M, 2 = 2M, 4 = Coded
∗ @param p h y o p t i o n s 0 = no p r e f e r r e d c o d i n g f o r Coded , 1 = S=2
c o d i n g (500 k b i t ) , 2 = S=8 c o d i n g (125 k b i t )
∗ @return s t a t u s
∗/
uint8 t g a p l e s e t p h y ( h c i c o n h a n d l e t c o n h a n d l e , uint8 t a l l p h y s
, uint8 t tx phys , uint8 t rx phys , uint16 t p h y o p t i o n s ) ;
/∗ ∗
∗ @ b r i e f Get c o n n e c t i o n i n t e r v a l
∗ @param c o n h a n d l e
∗ @return c o n n e c t i o n i n t e r v a l , o t h e r w i s e 0 i f e r r o r
∗/
uint16 t g a p l e c o n n e c t i o n i n t e r v a l ( h c i c o n h a n d l e t c o n h a n d l e ) ;
/∗ ∗
∗
∗ @ b r i e f Get e n c r y p t i o n key s i z e .
∗ @param c o n h a n d l e
∗ @return 0 i f not e n c r y p t e d , 7−16 o t h e r w i s e
∗/
uint8 t g a p e n c r y p t i o n k e y s i z e ( h c i c o n h a n d l e t c o n h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Get a u t h e n t i c a t i o n p r o p e r t y .
∗ @param c o n h a n d l e
∗ @return t r u e i f bonded w i t h OOB/ Passkey (AND MITM p r o t e c t i o n )
∗/
bool gap authenticated ( hci con handle t con handle ) ;
/∗ ∗
∗ @ b r i e f Get s e c u r e c o n n e c t i o n p r o p e r t y
∗ @param c o n h a n d l e
501
∗ @return t r u e i f bonded u s i u n g LE S e c u r e C o n n e c t i o n s
∗/
bool gap secure connection ( hci con handle t con handle ) ;
/∗ ∗
∗ @brief Queries a u t h o r i z a t i o n s t a t e .
∗ @param c o n h a n d l e
∗ @return a u t h o r i z a t i o n s t a t e f o r t h e c u r r e n t s e s s i o n
∗/
authorization state t gap authorization state ( hci con handle t
con handle ) ;
/∗ ∗
∗ @ b r i e f Get bonded p r o p e r t y (BR/EDR/LE)
∗ @note LE : has t o be c a l l e d a f t e r i d e n t i t y r e s o l v i n g i s c o m p l e t e
∗ @param c o n h a n d l e
∗ @return t r u e i f bonded
∗/
b o o l gap bonded ( h c i c o n h a n d l e t c o n h a n d l e ) ;
// C l a s s i c
#i f d e f ENABLE CLASSIC
/∗ ∗
∗ @ b r i e f O v e r r i d e page scan mode . Page scan mode e n a b l e d by l 2 c a p
when s e r v i c e s a r e r e g i s t e r e d
∗ @note Might be used t o r e d u c e power consumption w h i l e B l u e t o o t h
module s t a y s powered b u t no ( new )
∗ connections are expected
∗/
void g a p c o n n e c t a b l e c o n t r o l ( uint8 t e n a b l e ) ;
/∗ ∗
∗ @ b r i e f A l l o w s t o c o n t r o l i f d e v i c e i s d i s c o v e r a b l e . OFF by
default .
∗/
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 e n a b l e ) ;
/∗ ∗
∗ @ b r i e f D e l e t e s l i n k key f o r remote d e v i c e w i t h b a s e b a n d a d d r e s s .
∗ @param addr
∗ @note On most d e s k t o p p o r t s , t h e Link Key DB u s e s a TLV and t h e r e
i s one TLV s t o r a g e p e r
∗ C o n t r o l l e r r e s p . i t s B l u e t o o t h Address . As t h e B l u e t o o t h
Address i s r e t r i e v e d d u r i n g
∗ power up , t h i s f u n c t i o n o n l y works , when t h e s t a c k i s i n
working s t a t e f o r t h e s e p o r t s .
∗/
void g a p d r o p l i n k k e y f o r b d a d d r ( bd addr t addr ) ;
/∗ ∗
∗ @brief Delete a l l stored l i n k keys
∗ @note On most d e s k t o p p o r t s , t h e Link Key DB u s e s a TLV and t h e r e
i s one TLV s t o r a g e p e r
502
∗ C o n t r o l l e r r e s p . i t s B l u e t o o t h Address . As t h e B l u e t o o t h
Address i s r e t r i e v e d d u r i n g
∗ power up , t h i s f u n c t i o n o n l y works , when t h e s t a c k i s i n
working s t a t e f o r t h e s e p o r t s .
∗/
void g a p d e l e t e a l l l i n k k e y s ( void ) ;
/∗ ∗
∗ @ b r i e f S t o r e l i n k key f o r remote d e v i c e w i t h b a s e b a n d a d d r e s s
∗ @param addr
∗ @param l i n k k e y
∗ @param l i n k k e y t y p e
∗ @note On most d e s k t o p p o r t s , t h e Link Key DB u s e s a TLV and t h e r e
i s one TLV s t o r a g e p e r
∗ C o n t r o l l e r r e s p . i t s B l u e t o o t h Address . As t h e B l u e t o o t h
Address i s r e t r i e v e d d u r i n g
∗ power up , t h i s f u n c t i o n o n l y works , when t h e s t a c k i s i n
working s t a t e f o r t h e s e p o r t s .
∗/
void g a p s t o r e l i n k k e y f o r b d a d d r ( bd addr t addr , l i n k k e y t
l i n k k e y , l i n k k e y t y p e t type ) ;
/∗ ∗
∗ @ b r i e f Get l i n k f o r remote d e v i c e w i t h basband a d d r e s s
∗ @param addr
∗ @param l i n k k e y ( o u t ) i s s t o r e d h e r e
∗ @param l i n k k e y t y p e ( o u t ) i s s t o r e d h e r e
∗ @note On most d e s k t o p p o r t s , t h e Link Key DB u s e s a TLV and t h e r e
i s one TLV s t o r a g e p e r
∗ C o n t r o l l e r r e s p . i t s B l u e t o o t h Address . As t h e B l u e t o o t h
Address i s r e t r i e v e d d u r i n g
∗ power up , t h i s f u n c t i o n o n l y works , when t h e s t a c k i s i n
working s t a t e f o r t h e s e p o r t s .
∗/
b o o l g a p g e t l i n k k e y f o r b d a d d r ( bd addr t addr , l i n k k e y t
l i n k k e y , l i n k k e y t y p e t ∗ type ) ;
/∗ ∗
∗ @ b r i e f S e tu p Link Key i t e r a t o r
∗ @param i t
∗ @return 1 on s u c c e s s
∗ @note On most d e s k t o p p o r t s , t h e Link Key DB u s e s a TLV and t h e r e
i s one TLV s t o r a g e p e r
∗ C o n t r o l l e r r e s p . i t s B l u e t o o t h Address . As t h e B l u e t o o t h
Address i s r e t r i e v e d d u r i n g
∗ power up , t h i s f u n c t i o n o n l y works , when t h e s t a c k i s i n
working s t a t e f o r t h e s e p o r t s .
∗/
int g a p l i n k k e y i t e r a t o r i n i t ( b t s t a c k l i n k k e y i t e r a t o r t ∗ i t ) ;
/∗ ∗
∗ @ b r i e f Get n e x t Link Key
∗ @param i t
∗ @ b r i e f addr
503
/∗ ∗
∗ @ b r i e f F re es r e s o u r c e s a l l o c a t e d by i t e r a t o r i n i t
∗ @note Must be c a l l e d a f t e r i t e r a t i o n t o f r e e r e s o u r c e s
∗ @param i t
∗ @see n o t e on g a p l i n k k e y i t e r a t o r i n i t
∗/
void g a p l i n k k e y i t e r a t o r d o n e ( b t s t a c k l i n k k e y i t e r a t o r t ∗ i t ) ;
/∗ ∗
∗ @ b r i e f S t a r t GAP C l a s s i c I n q u i r y
∗ @param d u r a t i o n i n 1 . 2 8 s u n i t s
∗ @return s t a t u s
∗ @events : GAP EVENT INQUIRY RESULT, GAP EVENT INQUIRY COMPLETE
∗/
int g a p i n q u i r y s t a r t ( uint8 t d u r a t i o n i n 1 2 8 0 m s u n i t s ) ;
/∗ ∗
∗ @ b r i e f S t a r t GAP C l a s s i c P e r i o d i c I n q u i r y
∗ @param d u r a t i o n i n 1 . 2 8 s u n i t s
∗ @param m a x p e r i o d l e n g t h b e t w e e n c o n s e c u t i v e i n q u i r i e s i n 1 . 2 8 s
units
∗ @param m i n p e r i o d l e n g t h b e t w e e n c o n s e c u t i v e i n q u i r i e s i n 1 . 2 8 s
units
∗ @return s t a t u s
∗ @events : GAP EVENT INQUIRY RESULT, GAP EVENT INQUIRY COMPLETE
∗/
uint8 t g a p i n q u i r y p e r i o d i c s t a r t ( uint8 t d u r a t i o n , uint16 t
m a x p e r i o d l e n g t h , uint16 t m i n p e r i o d l e n g t h ) ;
/∗ ∗
∗ @ b r i e f Stop GAP C l a s s i c I n q u i r y ( r e g u l a r or p e r i o d i c )
∗ @return 0 i f ok
∗ @events GAP EVENT INQUIRY COMPLETE
∗/
int g a p i n q u i r y s t o p ( void ) ;
/∗ ∗
∗ @ b r i e f S e t LAP f o r GAP C l a s s i c I n q u i r y
∗ @param l a p GAP IAC GENERAL INQUIRY ( d e f a u l t ) ,
GAP IAC LIMITED INQUIRY
∗/
void g a p i n q u i r y s e t l a p ( uint32 t l a p ) ;
/∗ ∗
∗ @ b r i e f S e t I n q u i r y Scan A c t i v i t y
504
/∗ ∗
∗ @ b r i e f S e t I n q u i r y Transmit Power L e v e l
∗ @param t x p o w e r range : −70 t o 20 dBm
∗/
void g a p i n q u i r y s e t t r a n s m i t p o w e r l e v e l ( i n t 8 t t x p o w e r ) ;
/∗ ∗
∗ @ b r i e f Remote Name R e q u e s t
∗ @param addr
∗ @param p a g e s c a n r e p e t i t i o n m o d e
∗ @param c l o c k o f f s e t o n l y used when b i t 15 i s s e t − p a s s 0 i f not
known
∗ @events HCI EVENT REMOTE NAME REQUEST COMPLETE
∗/
int g a p r e m o t e n a m e r e q u e s t ( const bd addr t addr , uint8 t
p a g e s c a n r e p e t i t i o n m o d e , uint16 t c l o c k o f f s e t ) ;
/∗ ∗
∗ @ b r i e f Legacy P a i r i n g Pin Code Response
∗ @note d a t a i s not c o p i e d , p o i n t e r has t o s t a y v a l i d
∗ @param addr
∗ @param p i n
∗ @return 0 i f ok
∗/
int g a p p i n c o d e r e s p o n s e ( const bd addr t addr , const char ∗ p i n ) ;
/∗ ∗
∗ @ b r i e f Legacy P a i r i n g Pin Code Response f o r b i n a r y d a t a / non−
strings
∗ @note d a t a i s not c o p i e d , p o i n t e r has t o s t a y v a l i d
∗ @param addr
∗ @param p i n d a t a
∗ @param p i n l e n
∗ @return 0 i f ok
∗/
int g a p p i n c o d e r e s p o n s e b i n a r y ( const bd addr t addr , const uint8 t
∗ p i n d a t a , uint8 t p i n l e n ) ;
/∗ ∗
∗ @ b r i e f Abort Legacy P a i r i n g
∗ @param addr
∗ @param p i n
∗ @return 0 i f ok
∗/
int g a p p i n c o d e n e g a t i v e ( bd addr t addr ) ;
505
/∗ ∗
∗ @ b r i e f SSP Passkey Response
∗ @param addr
∗ @param p a s s k e y [ 0 . . 9 9 9 9 9 9 ]
∗ @return 0 i f ok
∗/
int g a p s s p p a s s k e y r e s p o n s e ( const bd addr t addr , uint32 t p a s s k e y )
;
/∗ ∗
∗ @ b r i e f Abort SSP Passkey Entry / P a i r i n g
∗ @param addr
∗ @param p i n
∗ @return 0 i f ok
∗/
int g a p s s p p a s s k e y n e g a t i v e ( const bd addr t addr ) ;
/∗ ∗
∗ @ b r i e f Accept SSP Numeric Comparison
∗ @param addr
∗ @param p a s s k e y
∗ @return 0 i f ok
∗/
int g a p s s p c o n f i r m a t i o n r e s p o n s e ( const bd addr t addr ) ;
/∗ ∗
∗ @ b r i e f Abort SSP Numeric Comparison / P a i r i n g
∗ @param addr
∗ @param p i n
∗ @return 0 i f ok
∗/
int g a p s s p c o n f i r m a t i o n n e g a t i v e ( const bd addr t addr ) ;
/∗ ∗
∗ @ b r i e f Generate new OOB d a t a
∗ @note OOB d a t a w i l l be p r o v i d e d i n GAP EVENT LOCAL OOB DATA and
be used i n f u t u r e p a i r i n g p r o c e d u r e s
∗/
void g a p s s p g e n e r a t e o o b d a t a ( void ) ;
/∗ ∗
∗ @ b r i e f Report Remote OOB Data
∗ @note P a i r i n g Hash and Randomizer a r e e x p e c t e d i n b i g −endian b y t e
format
∗ @param b d a d d r
∗ @param c 1 9 2 Simple P a i r i n g Hash C d e r i v e d from P−192 p u b l i c key
∗ @param r 1 9 2 Simple P a i r i n g Randomizer d e r i v e d from P−192 p u b l i c
key
∗ @param c 2 5 6 Simple P a i r i n g Hash C d e r i v e d from P−256 p u b l i c key
∗ @param r 2 5 6 Simple P a i r i n g Randomizer d e r i v e d from P−256 p u b l i c
key
∗ @return s t a t u s
∗/
506
/∗ ∗
∗ Send SSP IO C a p a b i l i t i e s Reply
∗ @note IO C a p a b i l i t i e s ( N e g a t i v e ) Reply i s s e n t a u t o m a t i c a l l y
u n l e s s ENABLE EXPLICIT IO CAPABILITIES REPLY
∗ @param addr
∗ @return s t a t u s
∗/
uint8 t g a p s s p i o c a p a b i l i t i e s r e s p o n s e ( const bd addr t addr ) ;
/∗ ∗
∗ Send SSP IO C a p a b i l i t i e s N e g a t i v e Reply
∗ @note IO C a p a b i l i t i e s ( N e g a t i v e ) Reply i s s e n t a u t o m a t i c a l l y
u n l e s s ENABLE EXPLICIT IO CAPABILITIES REPLY
∗ @param addr
∗ @return s t a t u s
∗/
uint8 t g a p s s p i o c a p a b i l i t i e s n e g a t i v e ( const bd addr t addr ) ;
/∗ ∗
∗ Send Link Key Reponse
∗ @note Link Key ( N e g a t i v e ) Reply i s s e n t a u t o m a t i c a l l y u n l e s s
ENABLE EXPLICIT LINK KEY RESPONSE
∗ @param addr
∗ @param l i n k k e y
∗ @param t y p e or INVALID LINK KEY i f l i n k key not a v a i l a b l e
∗ @return s t a t u s
∗/
uint8 t g a p s e n d l i n k k e y r e s p o n s e ( const bd addr t addr , l i n k k e y t
l i n k k e y , l i n k k e y t y p e t type ) ;
/∗ ∗
∗ @ b r i e f Enter S n i f f mode
∗ @param c o n h a n d l e
∗ @param s n i f f m i n i n t e r v a l range : 0 x0002 t o 0xFFFE ; o n l y even
v a l u e s a r e v a l i d , Time = N ∗ 0 . 6 2 5 ms
∗ @param s n i f f m a x i n t e r v a l range : 0 x0002 t o 0xFFFE ; o n l y even
v a l u e s a r e v a l i d , Time = N ∗ 0 . 6 2 5 ms
∗ @param s n i f f a t t e m p t Number o f Baseband r e c e i v e s l o t s f o r s n i f f
attempt .
∗ @param s n i f f t i m e o u t Number o f Baseband r e c e i v e s l o t s f o r s n i f f
timeout .
∗ @return s t a t u s
∗/
uint8 t g a p s n i f f m o d e e n t e r ( h c i c o n h a n d l e t c o n h a n d l e , uint16 t
s n i f f m i n i n t e r v a l , uint16 t s n i f f m a x i n t e r v a l , uint16 t
s n i f f a t t e m p t , uint16 t s n i f f t i m e o u t ) ;
/∗ ∗
∗ @ b r i e f E x i t S n i f f mode
∗ @param c o n h a n d l e
507
∗ @return s t a t u s
∗/
uint8 t g a p s n i f f m o d e e x i t ( h c i c o n h a n d l e t c o n h a n d l e ) ;
/∗ ∗
∗ @brief Configure S n i f f Subrating
∗ @param c o n h a n d l e
∗ @param m a x l a t e n c y range : 0 x0002 t o 0xFFFE ; Time = N ∗ 0 . 6 2 5 ms
∗ @param m i n r e m o t e t i m e o u t range : 0 x0002 t o 0xFFFE ; Time = N ∗
0 . 6 2 5 ms
∗ @param m i n l o c a l t i m e o u t range : 0 x0002 t o 0xFFFE ; Time = N ∗
0 . 6 2 5 ms
∗ @return s t a t u s
∗/
uint8 t g a p s n i f f s u b r a t i n g c o n f i g u r e ( h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t max latency , uint16 t m i n r e m o t e t i m e o u t , uint16 t
min local timeout ) ;
/∗ ∗
∗ @Brief S e t QoS
∗ @param c o n h a n d l e
∗ @param s e r v i c e t y p e
∗ @param t o k e n r a t e
∗ @param p e a k b a n d w i d t h
∗ @param l a t e n c y
∗ @param d e l a y v a r i a t i o n
∗ @return s t a t u s
∗/
uint8 t g a p q o s s e t ( h c i c o n h a n d l e t c o n h a n d l e , h c i s e r v i c e t y p e t
s e r v i c e t y p e , uint32 t t o k e n r a t e , uint32 t peak bandwidth ,
uint32 t l a t e n c y , uint32 t d e l a y v a r i a t i o n ) ;
#endif
// LE
/∗ ∗
∗ @ b r i e f Get own addr t y p e and a d d r e s s used f o r LE f o r n e x t scan /
advertisement / connect operation
∗/
void g a p l e g e t o w n a d d r e s s ( uint8 t ∗ a d d r t y p e , bd addr t addr ) ;
/∗ ∗
∗ @ b r i e f Get own addr t y p e and a d d r e s s used f o r LE a d v e r t i s e m e n t s (
Peripheral )
∗/
void g a p l e g e t o w n a d v e r t i s e m e n t s a d d r e s s ( uint8 t ∗ a d d r t y p e ,
bd addr t addr ) ;
/∗ ∗
∗ @ b r i e f Get own addr t y p e and a d d r e s s used f o r LE Extended
Advertisiing ( Peripheral )
∗/
508
void g a p l e g e t o w n a d v e r t i s i n g s e t a d d r e s s ( uint8 t ∗ a d d r t y p e ,
bd addr t addr , uint8 t a d v e r t i s i n g h a n d l e ) ;
/∗ ∗
∗ @ b r i e f Get own addr t y p e and a d d r e s s used f o r LE c o n n e c t i o n s (
Central )
∗/
void g a p l e g e t o w n c o n n e c t i o n a d d r e s s ( uint8 t ∗ a d d r t y p e ,
bd addr t addr ) ;
/∗ ∗
∗ @ b r i e f Get s t a t e o f c o n n e c t i o n re−e n c r y p t i o n f o r bonded d e v i c e s
when i n c e n t r a l r o l e
∗ @note used by g a t t c l i e n t and a t t s e r v e r t o w a i t f o r re−
encryption
∗ @param c o n h a n d l e
∗ @return 1 i f s e c u r i t y s e t u p i s a c t i v e
∗/
bool g a p r e c o n n e c t s e c u r i t y s e t u p a c t i v e ( hci con handle t con handle
);
/∗ ∗
∗ @ b r i e f D e l e t e b o n d i n g i n f o r m a t i o n f o r remote d e v i c e
∗ @note On most d e s k t o p p o r t s , t h e LE D ev i c e DB u s e s a TLV and
t h e r e i s one TLV s t o r a g e p e r
∗ C o n t r o l l e r r e s p . i t s B l u e t o o t h Address . As t h e B l u e t o o t h
Address i s r e t r i e v e d d u r i n g
∗ power up , t h i s f u n c t i o n o n l y works , when t h e s t a c k i s i n
working s t a t e f o r t h e s e p o r t s .
∗ @param a d d r e s s t y p e
∗ @param a d d r e s s
∗/
void g a p d e l e t e b o n d i n g ( b d a d d r t y p e t a d d r e s s t y p e , bd addr t
address ) ;
/∗ ∗
∗ LE P r i v a c y 1 . 2 − r e q u i r e s s u p p o r t by C o n t r o l l e r and
ENABLE LE RESOLVING LIST t o be d e f i n e d
∗/
/∗ ∗
∗ S e t P r i v a c y Mode f o r use i n R e s o l v i n g L i s t . D e f a u l t :
LE PRIVACY MODE DEVICE
∗ @note Only a p p l i e s f o r new d e v i c e s added t o r e s o l v i n g l i s t ,
please c a l l before startup
∗ @param p r i v a c y m o d e
∗/
void g a p s e t p e e r p r i v a c y m o d e ( l e p r i v a c y m o d e t privacy mode ) ;
/∗ ∗
∗ @ b r i e f Load LE De v i ce DB e n t r i e s i n t o C o n t r o l l e r R e s o l v i n g L i s t
t o a l l o w f i l t e r i n g on
∗ bonded d e v i e s w i t h r e s o l v a b l e p r i v a t e a d d r e s s e s
∗ @return EROOR CODE SUCCESS i f s u p p o r t e d by C o n t r o l l e r
509
∗/
uint8 t g a p l o a d r e s o l v i n g l i s t f r o m l e d e v i c e d b ( void ) ;
typedef enum {
GAP PRIVACY CLIENT STATE IDLE ,
GAP PRIVACY CLIENT STATE PENDING,
GAP PRIVACY CLIENT STATE READY
} gap privacy client state t ;
struct g a p p r i v a c y c l i e n t {
b t s t a c k l i n k e d i t e m t ∗ next ;
void ( ∗ c a l l b a c k ) ( struct g a p p r i v a c y c l i e n t ∗ c l i e n t , bd addr t
random addr ) ;
gap privacy client state t state ;
};
typedef struct g a p p r i v a c y c l i e n t g a p p r i v a c y c l i e n t t ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k t h a t g e t s e x e c u t e d d u r i n g random a d d r e s s
update
∗ @note g a p p r i v a c y c l i e n t r e a d y n ee d s t o be c a l l e d a f t e r c a l l b a c k
is received
∗ @param c l i e n t
∗ @return s t a t u s
∗/
void g a p p r i v a c y c l i e n t r e g i s t e r ( g a p p r i v a c y c l i e n t t ∗ c l i e n t ) ;
/∗ ∗
∗ @ b r i e f Acknowledge upcoming random a d d r e s s change
∗ @param c l i e n t
∗ @return s t a t u s
∗/
void g a p p r i v a c y c l i e n t r e a d y ( g a p p r i v a c y c l i e n t t ∗ c l i e n t ) ;
/∗ ∗
∗ @ b r i e f U n r e g i s t e r c a l l b a c k from random a d d r e s s u p d a t e s
∗ @param c l i e n t
∗ @return s t a t u s
∗/
void g a p p r i v a c y c l i e n t u n r e g i s t e r ( g a p p r i v a c y c l i e n t t ∗ c l i e n t ) ;
/∗ ∗
∗ @ b r i e f Get l o c a l p e r s i s t e n t IRK
∗/
const uint8 t ∗ g a p g e t p e r s i s t e n t i r k ( void ) ;
// HCI i n i t and c o n f i g u r a t i o n
/∗ ∗
510
/∗ ∗
∗ @ b r i e f C o n f i g u r e B l u e t o o t h c h i p s e t d r i v e r . Has t o be c a l l e d
b e f o r e power on , or r i g h t a f t e r r e c e i v i n g t h e l o c a l v e r s i o n
information .
∗/
void h c i s e t c h i p s e t ( const b t s t a c k c h i p s e t t ∗ c h i p s e t d r i v e r ) ;
/∗ ∗
∗ @ b r i e f Enable custom i n i t f o r c h i p s e t d r i v e r t o send HCI commands
b e f o r e HCI R e s e t
∗/
void h c i e n a b l e c u s t o m p r e i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f C o n f i g u r e B l u e t o o t h hardware c o n t r o l . Has t o be c a l l e d
b e f o r e power on .
∗ @[ aram h a r d w a r e c o n t r o l i m p l e m e n t a t i o n
∗/
void h c i s e t c o n t r o l ( const btstack control t ∗ h a r d w a r e c o n t r o l ) ;
#i f d e f ENABLE CLASSIC
/∗ ∗
∗ @ b r i e f C o n f i g u r e B l u e t o o t h hardware c o n t r o l . Has t o be c a l l e d
b e f o r e power on .
∗/
void h c i s e t l i n k k e y d b ( btstack link key db t const ∗ l i n k k e y d b ) ;
#endif
/∗ ∗
∗ @ b r i e f S e t c a l l b a c k f o r B l u e t o o t h Hardware Error
∗/
void h c i s e t h a r d w a r e e r r o r c a l l b a c k ( void ( ∗ f n ) ( uint8 t e r r o r ) ) ;
/∗ ∗
∗ @ b r i e f S e t P u b l i c BD ADDR − p a s s e d on t o B l u e t o o t h c h i p s e t d u r i n g
i n i t i f supported in b t c o n t r o l h
∗/
void h c i s e t b d a d d r ( bd addr t addr ) ;
/∗ ∗
∗ @ b r i e f C o n f i g u r e Voice S e t t i n g f o r use w i t h SCO d a t a i n HSP/HFP
511
∗/
void h c i s e t s c o v o i c e s e t t i n g ( uint16 t v o i c e s e t t i n g ) ;
/∗ ∗
∗ @ b r i e f Get SCO Voice S e t t i n g
∗ @return c u r r e n t v o i c e s e t t i n g
∗/
uint16 t h c i g e t s c o v o i c e s e t t i n g ( void ) ;
/∗ ∗
∗ @ b r i e f S e t number o f ISO p a c k e t s t o b u f f e r f o r BIS/CIS
∗ @param num packets ( d e f a u l t = 1)
∗/
void h c i s e t n u m i s o p a c k e t s t o q u e u e ( uint8 t num packets ) ;
/∗ ∗
∗ @ b r i e f S e t i n q u i r y mode : s t a n d a r d , w i t h RSSI , w i t h RSSI +
Extended I n q u i r y R e s u l t s . Has t o be c a l l e d b e f o r e power on .
∗ @param i n q u r i y m o d e s e e b l u e t o o t h d e f i n e s . h
∗/
void h c i s e t i n q u i r y m o d e ( i n q u i r y m o d e t i n q u r i y m o d e ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t s t h e change o f BTstack power mode .
∗ @param power mode
∗ @return 0 i f s u c c e s s , o t h e r w i s e e r r o r
∗/
int h c i p o w e r c o n t r o l (HCI POWER MODE power mode ) ;
/∗ ∗
∗ @ b r i e f Shutdown HCI
∗/
void h c i c l o s e ( void ) ;
// C a l l b a c k r e g i s t r a t i o n
/∗ ∗
∗ @ b r i e f Add e v e n t p a c k e t h a n d l e r .
∗/
void h c i a d d e v e n t h a n d l e r ( b t s t a c k p a c k e t c a l l b a c k r e g i s t r a t i o n t ∗
callback handler ) ;
/∗ ∗
∗ @ b r i e f Remove e v e n t p a c k e t h a n d l e r .
∗/
void h c i r e m o v e e v e n t h a n d l e r ( b t s t a c k p a c k e t c a l l b a c k r e g i s t r a t i o n t
∗ callback handler ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r s a p a c k e t h a n d l e r f o r ACL d a t a . Used by L2CAP
∗/
512
/∗ ∗
∗ @ b r i e f R e g i s t e r s a p a c k e t h a n d l e r f o r SCO d a t a . Used f o r HSP and
HFP p r o f i l e s .
∗/
void h c i r e g i s t e r s c o p a c k e t h a n d l e r ( btstack packet handler t
handler ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r s a p a c k e t h a n d l e r f o r ISO d a t a . Used f o r LE Audio
profiles
∗/
void h c i r e g i s t e r i s o p a c k e t h a n d l e r ( btstack packet handler t
handler ) ;
/∗ ∗
∗ @ b r i e f Check i f CMD p a c k e t can be s e n t t o c o n t r o l l e r
∗ @return t r u e i f command can be s e n t
∗/
b o o l h c i c a n s e n d c o m m a n d p a c k e t n o w ( void ) ;
/∗ ∗
∗ @ b r i e f C r e a t e s and s e n d s HCI command p a c k e t s b a s e d on a t e m p l a t e
and a l i s t o f p a r a m e t e r s . W i l l r e t u r n e r r o r i f o u t g o i n g d a t a
b u f f e r i s occupied .
∗ @return s t a t u s
∗/
uint8 t h c i s e n d c m d ( const hci cmd t ∗ cmd , . . . ) ;
// Sending SCO P a c k e t s
/∗ ∗
∗ @ b r i e f R e q u e s t e m i s s i o n o f HCI EVENT SCO CAN SEND NOW as soon as
possible
∗ @note HCI EVENT SCO CAN SEND NOW might be e m i t t e d d u r i n g c a l l t o
this function
∗ so p a c k e t h a n d l e r s h o u l d be r e a d y t o h a n d l e i t
∗/
void h c i r e q u e s t s c o c a n s e n d n o w e v e n t ( void ) ;
/∗ ∗
∗ @ b r i e f Check HCI p a c k e t b u f f e r and i f SCO p a c k e t can be s e n t t o
controller
∗ @return t r u e i f s c o p a c k e t can be s e n t
∗/
b o o l h c i c a n s e n d s c o p a c k e t n o w ( void ) ;
/∗ ∗
∗ @ b r i e f Check i f SCO p a c k e t can be s e n t t o c o n t r o l l e r
∗ @return t r u e i f s c o p a c k e t can be s e n t
∗/
b o o l h c i c a n s e n d p r e p a r e d s c o p a c k e t n o w ( void ) ;
/∗ ∗
∗ @ b r i e f Send SCO p a c k e t p r e p a r e d i n HCI p a c k e t b u f f e r
∗/
uint8 t h c i s e n d s c o p a c k e t b u f f e r ( int s i z e ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t e m i s s i o n o f HCI EVENT BIS CAN SEND NOW f o r a l l BIS
as soon as p o s s i b l e
∗ @param b i g h a n d l e
∗ @note HCI EVENT ISO CAN SEND NOW might be e m i t t e d d u r i n g c a l l t o
this function
∗ so p a c k e t h a n d l e r s h o u l d be r e a d y t o h a n d l e i t
∗/
uint8 t h c i r e q u e s t b i s c a n s e n d n o w e v e n t s ( uint8 t b i g h a n d l e ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t e m i s s i o n o f HCI EVENT CIS CAN SEND NOW f o r CIS as
soon as p o s s i b l e
∗ @param c i s c o n h a n d l e
∗ @note HCI EVENT CIS CAN SEND NOW might be e m i t t e d d u r i n g c a l l t o
this function
∗ so p a c k e t h a n d l e r s h o u l d be r e a d y t o h a n d l e i t
∗/
uint8 t h c i r e q u e s t c i s c a n s e n d n o w e v e n t s ( h c i c o n h a n d l e t
cis con handle ) ;
/∗ ∗
514
/∗ ∗
∗ Reserves outgoing packet b u f f e r .
∗ @note Must o n l y be c a l l e d a f t e r a ’ can send now ’ c h e c k or e v e n t
∗ @note A s s e r t s i f p a c k e t b u f f e r i s a l r e a d y r e s e r v e d
∗/
void h c i r e s e r v e p a c k e t b u f f e r ( void ) ;
/∗ ∗
∗ Get p o i n t e r f o r o u t g o i n g p a c k e t b u f f e r
∗/
uint8 t ∗ h c i g e t o u t g o i n g p a c k e t b u f f e r ( void ) ;
/∗ ∗
∗ Release outgoing packet b u f f e r \
∗ @note o n l y c a l l e d i n s t e a d o f h c i s e n d p r e p a r e d
∗/
void h c i r e l e a s e p a c k e t b u f f e r ( void ) ;
/∗ ∗
∗ @ b r i e f S e t s t h e master / s l a v e p o l i c y
∗ @param p o l i c y ( 0 : a t t e m p t t o become master , 1 : l e t c o n n e c t i n g
device decide )
∗/
void h c i s e t m a s t e r s l a v e p o l i c y ( uint8 t p o l i c y ) ;
/∗ ∗
∗ @ b r i e f Check i f C o n t r o l l e r s u p p o r t s BR/EDR ( B l u e t o o t h C l a s s i c )
∗ @return t r u e i f s u p p o r t e d
∗ @note o n l y v a l i d i n w o r k i n g s t a t e
∗/
b o o l h c i c l a s s i c s u p p o r t e d ( void ) ;
/∗ ∗
∗ @ b r i e f Check i f C o n t r o l l e r s u p p o r t s LE ( B l u e t o o t h Low Energy )
∗ @return t r u e i f s u p p o r t e d
∗ @note o n l y v a l i d i n w o r k i n g s t a t e
∗/
b o o l h c i l e s u p p o r t e d ( void ) ;
/∗ ∗
∗ @ b r i e f Check i f LE Extended A d v e r t i s i n g i s s u p p o r t e d
∗ @return t r u e i f s u p p o r t e d
∗/
b o o l h c i l e e x t e n d e d a d v e r t i s i n g s u p p o r t e d ( void ) ;
/∗ ∗ @ b r i e f Check i f a d d r e s s t y p e c o r r e s p o n d s t o LE c o n n e c t i o n
∗ @bparam a d d r e s s t y p e
∗ @erturn t r u e i f LE c o n n e c t i o n
∗/
bool h c i i s l e c o n n e c t i o n t y p e ( bd addr type t address type ) ;
515
/∗ ∗ @ b r i e f Check i f a d d r e s s t y p e c o r r e s p o n d s t o I d e n t i t y Address
∗ @bparam a d d r e s s t y p e
∗ @erturn t r u e i f LE c o n n e c t i o n
∗/
bool h c i i s l e i d e n t i t y a d d r e s s t y p e ( bd addr type t address type ) ;
1.92. HCI Logging API. hci dump.h : Dump HCI trace as BlueZ’s hcidump
format, Apple’s PacketLogger, or stdout.
typedef enum {
HCI DUMP INVALID = 0 ,
HCI DUMP BLUEZ,
HCI DUMP PACKETLOGGER,
HCI DUMP BTSNOOP,
} hci dump format t ;
typedef struct {
// r e s e t o u t p u t , c a l l e d i f max p a c k e t s i s reached , t o l i m i t f i l e
size
void ( ∗ r e s e t ) ( void ) ;
// l o g p a c k e t
void ( ∗ l o g p a c k e t ) ( uint8 t p a c k e t t y p e , uint8 t in , uint8 t ∗
packet , uint16 t l e n ) ;
// l o g message
void ( ∗ l o g m e s s a g e ) ( int l o g l e v e l , const char ∗ format , v a l i s t
argptr ) ;
#i f d e f AVR \
// l o g message − AVR
void ( ∗ l o g m e s s a g e P ) ( int l o g l e v e l , PGM P ∗ format , v a l i s t
argptr ) ;
#endif
} hci dump t ;
/∗ ∗
∗ @ b r i e f I n i t HCI Dump
∗ @param h c i d u m p i m p l − p l a t f o r m −s p e c i f i c i m p l e m e n t a t i o n
∗/
void h c i d u m p i n i t ( const h c i d u m p t ∗ hci dump impl ) ;
/∗ ∗
∗ @ b r i e f Enable p a c k e t l o g g i n g
∗ @param e n a b l e d d e f a u l t : t r u e
∗/
void h c i d u m p e n a b l e p a c k e t l o g ( b o o l e n a b l e d ) ;
/∗ ∗
∗ @brief
∗/
void h c i d u m p e n a b l e l o g l e v e l ( int l o g l e v e l , int e n a b l e ) ;
/∗
516
/∗ ∗
∗ @ b r i e f Dump P a ck e t
∗ @param p a c k e t t y p e
∗ @param i n i s 1 f o r incoming , 0 f o r o u t o i n g
∗ @param p a c k e t
∗ @param l e n
∗/
void h c i d u m p p a c k e t ( uint8 t p a c k e t t y p e , uint8 t in , uint8 t ∗
packet , uint16 t l e n ) ;
/∗ ∗
∗ @ b r i e f Dump Message
∗ @param l o g l e v e l
∗ @param f o r m at
∗/
void h c i d u m p l o g ( int l o g l e v e l , const char ∗ format , . . . )
#i f d e f GNUC
attribute ( ( format ( p r i n t f , 2 , 3) ) )
#endif
;
#i f d e f AVR
/∗
∗ @ b r i e f Dump Message u s i n g f o r m a t s t r i n g s t o r e d i n PGM memory (
a l l o w s t o s a v e RAM)
∗ @param l o g l e v e l
∗ @param f o r m at
∗/
void h c i d u m p l o g P ( int l o g l e v e l , PGM P format , . . . )
#i f d e f GNUC
attribute ( ( format ( p r i n t f , 2 , 3) ) )
#endif
;
#endif
/∗ ∗
∗ @ b r i e f Dump i n t e r n a l BTstack e v e n t
∗ @note o n l y l o g g e d i f ENABLE LOG BTSTACK EVENTS i s d e f i n e d
∗ @param p a c k e t
∗ @param l e n
∗/
void h c i d u m p b t s t a c k e v e n t ( const uint8 t ∗ packet , uint16 t l e n ) ;
/∗ ∗
∗ @brief S e tu p h e a d e r f o r P a c k e t L o g g e r f o rm a t
∗ @param buffer
∗ @param tv sec
∗ @param tv us
∗ @param packet type
∗ @param in
517
∗ @param l e n
∗/
void h c i d u m p s e t u p h e a d e r p a c k e t l o g g e r ( uint8 t ∗ b u f f e r , uint32 t
t v s e c , uint32 t t v u s , uint8 t p a c k e t t y p e , uint8 t in ,
uint16 t l e n ) ;
/∗ ∗
∗ @ b r i e f S e tu p h e a d e r f o r BLUEZ ( hcidump ) f o r m a t
∗ @param b u f f e r
∗ @param t v s e c
∗ @param t v u s
∗ @param p a c k e t t y p e
∗ @param i n
∗ @param l e n
∗/
void h c i d u m p s e t u p h e a d e r b l u e z ( uint8 t ∗ b u f f e r , uint32 t t v s e c ,
uint32 t t v u s , uint8 t p a c k e t t y p e , uint8 t in , uint16 t l e n ) ;
/∗ ∗
∗ @ b r i e f S e tu p h e a d e r f o r BT Snoop f o r m a t
∗ @param b u f f e r
∗ @param t s u s e c h i g h upper 32− b i t o f 64− b i t microsecond timestamp
∗ @param t s u s e c l o w l o w e r 2− b i t o f 64− b i t microsecond timestamp
∗ @param c u m u l a t i v e d r o p s s i n c e l a s t p a c k e t was r e c o r d e d
∗ @param p a c k e t t y p e
∗ @param i n
∗ @param l e n
∗/
void h c i d u m p s e t u p h e a d e r b t s n o o p ( uint8 t ∗ b u f f e r , uint32 t
t s u s e c h i g h , uint32 t t s u s e c l o w , uint32 t c u m u l a t i v e d r o p s ,
uint8 t p a c k e t t y p e , uint8 t in , uint16 t l e n ) ;
1.93. HCI Transport API. hci transport.h : The API allows BTstack to
use different transport interfaces.
/∗ HCI p a c k e t t y p e s ∗/
typedef struct {
/∗ ∗
∗ t r a n s p o r t name
∗/
const char ∗ name ;
/∗ ∗
∗ init transport
∗ @param t r a n s p o r t c o n f i g
∗/
void ( ∗ i n i t ) ( const void ∗ t r a n s p o r t c o n f i g ) ;
/∗ ∗
∗ open t r a n s p o r t c o n n e c t i o n
∗/
int ( ∗ open ) ( void ) ;
518
/∗ ∗
∗ c l o s e transport connection
∗/
int ( ∗ c l o s e ) ( void ) ;
/∗ ∗
∗ r e g i s t e r p a c k e t h a n d l e r f o r HCI p a c k e t s : ACL, SCO, and Ev e n ts
∗/
void ( ∗ r e g i s t e r p a c k e t h a n d l e r ) ( void ( ∗ h a n d l e r ) ( uint8 t
p a c k e t t y p e , uint8 t ∗ packet , uint16 t s i z e ) ) ;
/∗ ∗
∗ s u p p o r t async t r a n s p o r t l a y e r s , e . g . IRQ d r i v e n w i t h o u t
buffers
∗/
int ( ∗ c a n s e n d p a c k e t n o w ) ( uint8 t p a c k e t t y p e ) ;
/∗ ∗
∗ send p a c k e t
∗/
int ( ∗ s e n d p a c k e t ) ( uint8 t p a c k e t t y p e , uint8 t ∗ packet , int
size ) ;
/∗ ∗
∗ e x t e n s i o n f o r UART t r a n s p o r t i m p l e m e n t a t i o n s
∗/
int ( ∗ s e t b a u d r a t e ) ( uint32 t b a u d r a t e ) ;
/∗ ∗
∗ e x t e n s i o n f o r UART H5 on CSR: r e s e t BCSP/H5 Link
∗/
void ( ∗ r e s e t l i n k ) ( void ) ;
/∗ ∗
∗ e x t e n s i o n f o r USB t r a n s p o r t i m p l e m e n t a t i o n s : c o n f i g SCO
connections
∗/
void ( ∗ s e t s c o c o n f i g ) ( uint16 t v o i c e s e t t i n g , int
num connections ) ;
} hci transport t ;
typedef enum {
HCI TRANSPORT CONFIG UART,
HCI TRANSPORT CONFIG USB
} hci transport config type t ;
typedef struct {
h c i t r a n s p o r t c o n f i g t y p e t type ;
} hci transport config t ;
typedef struct {
519
h c i t r a n s p o r t c o n f i g t y p e t type ; // ==
HCI TRANSPORT CONFIG UART
uint32 t b a u d r a t e i n i t ; // i n i t i a l baud r a t e
uint32 t baudrate main ; // = 0 : same as i n i t i a l b a u d r a t e
int flowcontrol ; //
const char ∗ d e v i c e n a m e ;
int parity ; // s e e b t s t a c k u a r t . h
BTSTACK UART PARITY
} hci transport config uart t ;
1.94. HCI Transport EM9304 API API. hci transport em9304 spi.h :
The EM9304 uses an extended SPI interface and this HCI Transport is based on
the the btstack em9304.h interface.
/∗
∗ @ b r i e f S e tu p H4 o v e r SPI i n s t a n c e f o r EM9304 w i t h
em9304 spi driver
∗ @param e m 9 3 0 4 s p i d r i v e r t o use
∗/
const hci transport t ∗ h c i t r a n s p o r t e m 9 3 0 4 s p i i n s t a n c e ( const
btstack em9304 spi t ∗ em9304 spi driver ) ;
/∗
∗ @ b r i e f S e tu p H4 i n s t a n c e w i t h b t s t a c k u a r t i m p l e m e n t a t i o n
∗ @param b t s t a c k u a r t b l o c k d r i v e r t o use
∗/
const hci transport t ∗ h c i t r a n s p o r t h 4 i n s t a n c e f o r u a r t ( const
btstack uart t ∗ uart driver ) ;
/∗
∗ @ b r i e f S e tu p H4 i n s t a n c e w i t h b t s t a c k u a r t b l o c k i m p l e m e n t a t i o n
∗ @param b t s t a c k u a r t b l o c k d r i v e r t o use
∗ @ de pr e ca te d use h c i t r a n s p o r t h 4 i n s t a n c e f o r u a r t i n s t e a d
∗/
const hci transport t ∗ h c i t r a n s p o r t h 4 i n s t a n c e ( const
btstack uart block t ∗ uart driver ) ;
/∗
∗ @ b r i e f S e tu p H5 i n s t a n c e w i t h b t s t a c k u a r t i m p l e m e n t a t i o n t h a t
s u p p o r t s SLIP frames
∗ @param u a r t d r i v e r t o use
∗/
520
/∗
∗ @ b r i e f Enable H5 Low Power Mode : e n t e r s l e e p mode a f t e r x ms o f
inactivity
∗ @param i n a c t i v i t y t i m e o u t m s or 0 f o r o f f
∗/
void h c i t r a n s p o r t h 5 s e t a u t o s l e e p ( uint16 t i n a c t i v i t y t i m e o u t m s )
;
/∗
∗ @ b r i e f Enable BSCP mode H5 , by e n a b l i n g e v e n t p a r i t y
∗ @ de pr e ca te d P a r i t y can be e n a b l e d i n UART d r i v e r c o n f i g u r a t i o n
∗/
void h c i t r a n s p o r t h 5 e n a b l e b c s p m o d e ( void ) ;
/∗
∗ @brief
∗/
const hci transport t ∗ h c i t r a n s p o r t u s b i n s t a n c e ( void ) ;
/∗ ∗
∗ @ b r i e f S p e c i f y USB B l u e t o o t h d e v i c e v i a p o r t numbers from r o o t t o
device
∗/
void h c i t r a n s p o r t u s b s e t p a t h ( int l e n , uint8 t ∗ port numbers ) ;
/∗ ∗
∗ @ b r i e f Add d e v i c e t o l i s t o f known B l u e t o o t h USB C o n t r o l l e r
∗ @param v e n d o r i d
∗ @param p r o d u c t i d
∗/
void h c i t r a n s p o r t u s b a d d d e v i c e ( uint16 t v e n d o r i d , uint16 t
product id ) ;
1.98. L2CAP API. l2cap.h : Logical Link Control and Adaption Protocol
//
// PSM numbers from h t t p s : / /www. b l u e t o o t h . com/ s p e c i f i c a t i o n s /
a s s i g n e d −numbers / l o g i c a l −l i n k −c o n t r o l
//
#define PSM SDP BLUETOOTH PROTOCOL SDP
#define PSM RFCOMM BLUETOOTH PROTOCOL RFCOMM
#define PSM BNEP BLUETOOTH PROTOCOL BNEP
// @TODO: s c r a p e PSMs B l u e t o o t h SIG s i t e and p u t i n b l u e t o o t h p s m . h
or b l u e t o o t h l 2 c a p . h
#define PSM HID CONTROL 0 x11
521
/∗ ∗
∗ @ b r i e f S e t up L2CAP and r e g i s t e r L2CAP w i t h HCI l a y e r .
∗/
void l 2 c a p i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f Add e v e n t p a c k e t h a n d l e r f o r LE Connection Parameter
Update e v e n t s
∗/
void l 2 c a p a d d e v e n t h a n d l e r ( b t s t a c k p a c k e t c a l l b a c k r e g i s t r a t i o n t
∗ callback handler ) ;
/∗ ∗
∗ @ b r i e f Remove e v e n t p a c k e t h a n d l e r .
∗/
void l 2 c a p r e m o v e e v e n t h a n d l e r (
btstack packet callback registration t ∗ callback handler ) ;
/∗ ∗
∗ @ b r i e f Get max MTU f o r C l a s s i c c o n n e c t i o n s b a s e d on b t s t a c k
configuration
∗/
uint16 t l2cap max mtu ( void ) ;
/∗ ∗
∗ @ b r i e f Get max MTU f o r LE c o n n e c t i o n s b a s e d on b t s t a c k
configuration
∗/
uint16 t l 2 c a p m a x l e m t u ( void ) ;
/∗ ∗
∗ @ b r i e f S e t t h e max MTU f o r LE c o n n e c t i o n s , i f not s e t
l2cap max mtu ( ) w i l l be used .
∗/
void l 2 c a p s e t m a x l e m t u ( uint16 t max mtu ) ;
/∗ ∗
∗ @ b r i e f C r e a t e s L2CAP c h a n n e l t o t h e PSM o f a remote d e v i c e w i t h
b a s e b a n d a d d r e s s . A new b a s e b a n d c o n n e c t i o n w i l l be i n i t i a t e d
i f necessary .
∗ @param p a c k e t h a n d l e r
∗ @param a d d r e s s
∗ @param psm
∗ @param mtu
∗ @param l o c a l c i d
∗ @return s t a t u s
∗/
uint8 t l 2 c a p c r e a t e c h a n n e l ( btstack packet handler t p a c k e t h a n d l e r
, bd addr t a d d r e s s , uint16 t psm , uint16 t mtu , uint16 t ∗
out local cid ) ;
522
/∗ ∗
∗ @ b r i e f D i s c o n n e c t s L2CAP c h a n n e l w i t h g i v e n i d e n t i f i e r .
∗ @param l o c a l c i d
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l or
L2CAP LOCAL CID DOES NOT EXIST
∗/
uint8 t l 2 c a p d i s c o n n e c t ( uint16 t l o c a l c i d ) ;
/∗ ∗
∗ @ b r i e f Q u e r i e s t h e maximal t r a n s f e r u n i t (MTU) f o r L2CAP c h a n n e l
with given i d e n t i f i e r .
∗/
uint16 t l 2 c a p g e t r e m o t e m t u f o r l o c a l c i d ( uint16 t l o c a l c i d ) ;
/∗ ∗
∗ @ b r i e f Sends L2CAP d a t a p a c k e t t o t h e c h a n n e l w i t h g i v e n
identifier .
∗ @note For c h a n n e l i n c r e d i t −b a s e d f l o w c o n t r o l mode , d a t a ne e ds
to stay v a l i d u n t i l . . event
∗ @param l o c a l c i d
∗ @param d a t a t o send
∗ @param l e n o f d a t a
∗ @return s t a t u s
∗/
uint8 t l 2 c a p s e n d ( uint16 t l o c a l c i d , const uint8 t ∗ data , uint16 t
len ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r s L2CAP s e r v i c e w i t h g i v e n PSM and MTU, and
assigns a packet handler .
∗ @param p a c k e t h a n d l e r
∗ @param psm
∗ @param mtu
∗ @param s e c u r i t y l e v e l
∗ @return s t a t u s ERROR CODE SUCCESS i f s u c c e s s f u l , o t h e r w i s e
L2CAP SERVICE ALREADY REGISTERED or BTSTACK MEMORY ALLOC FAILED
∗/
uint8 t l 2 c a p r e g i s t e r s e r v i c e ( btstack packet handler t
p a c k e t h a n d l e r , uint16 t psm , uint16 t mtu , g a p s e c u r i t y l e v e l t
security level ) ;
/∗ ∗
∗ @ b r i e f U n r e g i s t e r s L2CAP s e r v i c e w i t h g i v e n PSM.
∗/
uint8 t l 2 c a p u n r e g i s t e r s e r v i c e ( uint16 t psm ) ;
/∗ ∗
∗ @ b r i e f A c c e p t s incoming L2CAP c o n n e c t i o n .
∗/
void l 2 c a p a c c e p t c o n n e c t i o n ( uint16 t l o c a l c i d ) ;
/∗ ∗
∗ @ b r i e f Deny incoming L2CAP c o n n e c t i o n .
523
∗/
void l 2 c a p d e c l i n e c o n n e c t i o n ( uint16 t l o c a l c i d ) ;
/∗ ∗
∗ @ b r i e f Check i f o u t g o i n g b u f f e r i s a v a i l a b l e and t h a t t h e r e ’ s
s p a c e on t h e B l u e t o o t h module
∗ @return t r u e i f p a c k e t can be s e n t
∗/
b o o l l 2 c a p c a n s e n d p a c k e t n o w ( uint16 t l o c a l c i d ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t e m i s s i o n o f L2CAP EVENT CAN SEND NOW as soon as
possible
∗ @note L2CAP EVENT CAN SEND NOW might be e m i t t e d d u r i n g c a l l t o
this function
∗ so p a c k e t h a n d l e r s h o u l d be r e a d y t o h a n d l e i t
∗ @param l o c a l c i d
∗ @return s t a t u s
∗/
uint8 t l 2 c a p r e q u e s t c a n s e n d n o w e v e n t ( uint16 t l o c a l c i d ) ;
/∗ ∗
∗ @brief Reserve outgoing b u f f e r
∗ @note Only f o r L2CAP B a s i c Mode Channels
∗ @note Must o n l y be c a l l e d a f t e r a ’ can send now ’ c h e c k or e v e n t
∗ @note A s s e r t s i f p a c k e t b u f f e r i s a l r e a d y r e s e r v e d
∗/
void l 2 c a p r e s e r v e p a c k e t b u f f e r ( void ) ;
/∗ ∗
∗ @ b r i e f Get o u t g o i n g b u f f e r and p r e p a r e d a t a .
∗ @note Only f o r L2CAP B a s i c Mode Channels
∗/
uint8 t ∗ l 2 c a p g e t o u t g o i n g b u f f e r ( void ) ;
/∗ ∗
∗ @ b r i e f Send L2CAP p a c k e t p r e p a r e d i n o u t g o i n g b u f f e r t o c h a n n e l
∗ @note Only f o r L2CAP B a s i c Mode Channels
∗/
uint8 t l 2 c a p s e n d p r e p a r e d ( uint16 t l o c a l c i d , uint16 t l e n ) ;
/∗ ∗
∗ @ b r i e f R e l e a s e o u t g o i n g b u f f e r ( o n l y needed i f
l 2 c a p s e n d p r e p a r e d i s not c a l l e d )
∗ @note Only f o r L2CAP B a s i c Mode Channels
∗/
void l 2 c a p r e l e a s e p a c k e t b u f f e r ( void ) ;
//
// Connection−O r i e n t e d Channels i n Enhanced R e t r a n s m i s s i o n Mode −
ERTM
//
/∗ ∗
524
/∗ ∗
∗ @ b r i e f A c c e p t s incoming L2CAP c o n n e c t i o n f o r Enhanced
R e t r a n s m i s s i o n Mode
∗ @param l o c a l c i d
∗ @param e r t m c o n f i g
∗ @param b u f f e r t o s t o r e r e a s s e m b l e d r x p a c k e t , out−of −o r d e r
p a c k e t s and unacknowledged o u t g o i n g p a c k e t s w i t h t h e i r
tretransmission timers
∗ @param s i z e o f b u f f e r
∗ @return s t a t u s
∗/
uint8 t l 2 c a p e r t m a c c e p t c o n n e c t i o n ( uint16 t l o c a l c i d ,
l 2 c a p e r t m c o n f i g t ∗ e r t m c o n t i g , uint8 t ∗ b u f f e r , uint32 t
size ) ;
/∗ ∗
∗ @ b r i e f Deny incoming incoming L2CAP c o n n e c t i o n f o r Enhanced
R e t r a n s m i s s i o n Mode
∗ @param l o c a l c i d
∗ @return s t a t u s
∗/
uint8 t l 2 c a p e r t m d e c l i n e c o n n e c t i o n ( uint16 t l o c a l c i d ) ;
/∗ ∗
∗ @ b r i e f ERTM S e t c h a n n e l as b u s y .
∗ @note Can be c l e a r e d by l 2 c a p e r t m s e t r e a d y
∗ @param l o c a l c i d
∗ @return s t a t u s
∗/
uint8 t l 2 c a p e r t m s e t b u s y ( uint16 t l o c a l c i d ) ;
/∗ ∗
∗ @ b r i e f ERTM S e t c h a n n e l as r e a d y
525
∗ @note Used a f t e r l 2 c a p e r t m s e t b u s y
∗ @param l o c a l c i d
∗ @return s t a t u s
∗/
uint8 t l 2 c a p e r t m s e t r e a d y ( uint16 t l o c a l c i d ) ;
//
// L2CAP Connection−O r i e n t e d Channels i n LE C r e d i t −Based Flow−
C o n t r o l Mode − CBM
//
/∗ ∗
∗ @ b r i e f R e g i s t e r L2CAP s e r v i c e i n LE C r e d i t −Based Flow−C o n t r o l
Mode
∗ @note MTU and i n i t i a l c r e d i t s a r e s p e c i f i e d i n
l2cap cbm accept connection ( . . ) c a l l
∗ @param p a c k e t h a n d l e r
∗ @param psm
∗ @param s e c u r i t y l e v e l
∗/
uint8 t l 2 c a p c b m r e g i s t e r s e r v i c e ( btstack packet handler t
p a c k e t h a n d l e r , uint16 t psm , g a p s e c u r i t y l e v e l t
security level ) ;
/∗ ∗
∗ @ b r i e f U n r e g i s t e r L2CAP s e r v i c e i n LE C r e d i t −Based Flow−C o n t r o l
Mode
∗ @param psm
∗/
/∗
∗ @ b r i e f Accept incoming c o n n e c t i o n LE C r e d i t −Based Flow−C o n t r o l
Mode
∗ @param l o c a l c i d L2CAP Channel I d e n t i f i e r
∗ @param r e c e i v e b u f f e r b u f f e r used f o r r e a s s e m b l y o f L2CAP
LE I n f o r m a t i o n Frames i n t o s e r v i c e d a t a u n i t (SDU) w i t h g i v e n
MTU
∗ @param r e c e i v e b u f f e r s i z e b u f f e r s i z e e q u a l s MTU
∗ @param i n i t i a l c r e d i t s Number o f i n i t i a l c r e d i t s p r o v i d e d
t o p e e r or L2CAP LE AUTOMATIC CREDITS t o e n a b l e a u t o m a t i c
credits
∗/
/∗ ∗
∗ @ b r i e f D e e c l i n e c o n n e c t i o n i n LE C r e d i t −Based Flow−C o n t r o l Mode
∗ @param l o c a l c i d L2CAP Channel I d e n t i f i e r
∗ @param r e s u l t result , see
L2CAP CBM CONNECTION RESULT SUCCESS i n b l u e t o o t h . h
526
∗/
/∗ ∗
∗ @ b r i e f C r ea t e o u t g o i n g c h a n n e l i n LE C r e d i t −Based Flow−C o n t r o l
Mode
∗ @param p a c k e t h a n d l e r P a c k et h a n d l e r f o r t h i s c o n n e c t i o n
∗ @param c o n h a n d l e HCI Connection Handle , LE t r a n s p o r t
∗ @param psm S e r v i c e PSM t o c o n n e c t t o
∗ @param r e c e i v e b u f f e r b u f f e r used f o r r e a s s e m b l y o f L2CAP
LE I n f o r m a t i o n Frames i n t o s e r v i c e d a t a u n i t (SDU) w i t h g i v e n
MTU
∗ @param r e c e i v e b u f f e r s i z e b u f f e r s i z e e q u a l s MTU
∗ @param i n i t i a l c r e d i t s Number o f i n i t i a l c r e d i t s p r o v i d e d
t o p e e r or L2CAP LE AUTOMATIC CREDITS t o e n a b l e a u t o m a t i c
credits
∗ @param s e c u r i t y l e v e l Minimum r e q u i r e d s e c u r i t y l e v e l
∗ @param o u t l o c a l c i d L2CAP LE Channel I d e n t i f i e r i s
stored here
∗/
uint8 t l 2 c a p c b m c r e a t e c h a n n e l ( btstack packet handler t
packet handler , h c i c o n h a n d l e t con handle ,
uint16 t psm , uint8 t ∗ r e c e i v e s d u b u f f e r , uint16 t mtu ,
uint16 t i n i t i a l c r e d i t s , g a p s e c u r i t y l e v e l t
security level ,
uint16 t ∗ o u t l o c a l c i d ) ;
/∗ ∗
∗ @ b r i e f P r o v i d e c r e d i t s f o r c h a n n e l i n LE C r e d i t −Based Flow−
C o n t r o l Mode
∗ @param l o c a l c i d L2CAP Channel I d e n t i f i e r
∗ @param c r e d i t s Number a d d i t i o n a l c r e d i t s f o r p e e r
∗/
uint8 t l 2 c a p c b m p r o v i d e c r e d i t s ( uint16 t l o c a l c i d , uint16 t
credits ) ;
//
// L2CAP Connection−O r i e n t e d Channels i n Enhanced C r e d i t −Based Flow−
C o n t r o l Mode − ECBM
//
/∗ ∗
∗ @ b r i e f R e g i s t e r L2CAP s e r v i c e i n Enhanced C r e d i t −Based Flow−
C o n t r o l Mode
∗ @note MTU and i n i t i a l c r e d i t s a r e s p e c i f i e d i n
l2cap enhanced accept connection ( . . ) c a l l
∗ @param p a c k e t h a n d l e r
∗ @param psm
∗ @param min remote mtu
∗ @param s e c u r i t y l e v e l
∗ @oaram a u t h o r i z a t i o n r e q u i r e d
∗ @return s t a t u s
527
∗/
uint8 t l 2 c a p e c b m r e g i s t e r s e r v i c e ( btstack packet handler t
p a c k e t h a n d l e r , uint16 t psm , uint16 t min remote mtu ,
gap security level t
s e c u r i t y l e v e l , bool
authorization required ) ;
/∗ ∗
∗ @ b r i e f U n r e g i s t e r L2CAP s e r v i c e i n Enhanced C r e d i t −Based Flow−
C o n t r o l Mode
∗ @param psm
∗ @return s t a t u s
∗/
/∗ ∗
∗ @ b r i e f S e t Minimal MPS f o r c h a n n e l i n Enhanced C r e d i t −Based Flow−
C o n t r o l Mode
∗ @param mps min
∗/
void l 2 c a p e c b m m p s s e t m i n ( uint16 t mps min ) ;
/∗ ∗
∗ @ b r i e f S e t Minimal MPS f o r c h a n n e l i n Enhanced C r e d i t −Based Flow−
C o n t r o l Mode
∗ @param mps max
∗/
void l 2 c a p e c b m m p s s e t m a x ( uint16 t mps max ) ;
/∗ ∗
∗ @ b r i e f C r ea t e o u t g o i n g c h a n n e l i n Enhanced C r e d i t −Based Flow−
C o n t r o l Mode
∗ @note r e c e i v e b u f f e r p o i n t s t o an a r r a y o f r e c e i v e b u f f e r s w i t h
num channels e l e m e n t s
∗ @note o u t l o c a l c i d p o i n t s t o an a r r a y where CID i s s t o r e d w i t h
num channel e l e m e n t s
∗ @param p a c k e t h a n d l e r P a c k et h a n d l e r f o r t h i s c o n n e c t i o n
∗ @param c o n h a n d l e HCI Connection Handle
∗ @param s e c u r i t y l e v e l Minimum r e q u i r e d s e c u r i t y l e v e l
∗ @param psm S e r v i c e PSM t o c o n n e c t t o
∗ @param num channels number o f c h a n n e l s t o c r e a t e
∗ @param i n i t i a l c r e d i t s Number o f i n i t i a l c r e d i t s p r o v i d e d
t o p e e r p e r c h a n n e l or L2CAP LE AUTOMATIC CREDITS t o e n a b l e
automatic c r e d i t s
∗ @param r e c e i v e b u f f e r s i z e b u f f e r s i z e e q u a l s MTU
∗ @param r e c e i v e b u f f e r s Array o f b u f f e r s used f o r r e a s s e m b l y
o f L2CAP I n f o r m a t i o n Frames i n t o s e r v i c e d a t a u n i t (SDU) w i t h
g i v e n MTU
∗ @param o u t l o c a l c i d s Array o f L2CAP Channel I d e n t i f i e r s
i s s t o r e d h e r e on s u c c e s s
∗ @return s t a t u s
∗/
528
/∗ ∗
∗ @ b r i e f Accept incoming c o n n e c t i o n Enhanced C r e d i t −Based Flow−
C o n t r o l Mode
∗ @param l o c a l c i d from
L2CAP EVENT INCOMING DATA CONNECTION
∗ @param num channels
∗ @param i n i t i a l c r e d i t s Number o f i n i t i a l c r e d i t s p r o v i d e d t o
p e e r p e r c h a n n e l or L2CAP LE AUTOMATIC CREDITS t o e n a b l e
automatic c r e d i t s
∗ @param r e c e i v e b u f f e r s i z e
∗ @param r e c e i v e b u f f e r s Array o f b u f f e r s used f o r r e a s s e m b l y
o f L2CAP I n f o r m a t i o n Frames i n t o s e r v i c e d a t a u n i t (SDU) w i t h
g i v e n MTU
∗ @param o u t l o c a l c i d s Array o f L2CAP Channel I d e n t i f i e r s i s
s t o r e d h e r e on s u c c e s s
∗ @return s t a t u s
∗/
uint8 t l 2 c a p e c b m a c c e p t c h a n n e l s ( uint16 t l o c a l c i d , uint8 t
num channels , uint16 t i n i t i a l c r e d i t s ,
uint16 t
receive buffer size ,
uint8 t ∗∗
receive buffers ,
uint16 t ∗
out local cids ) ;
/∗ ∗
∗ @ b r i e f D e c l i n e c o n n e c t i o n i n Enhanced C r e d i t −Based Flow−C o n t r o l
Mode
∗ @param l o c a l c i d from
L2CAP EVENT INCOMING DATA CONNECTION
∗ @param r e s u l t See
L2CAP ECBM CONNECTION RESULT ALL SUCCESS i n b l u e t o o t h . h
∗ @return s t a t u s
∗/
uint8 t l 2 c a p e c b m d e c l i n e c h a n n e l s ( uint16 t l o c a l c i d , uint16 t
result ) ;
/∗ ∗
∗ @ b r i e f P r o v i d e c r e d i t s f o r c h a n n e l i n Enhanced C r e d i t −Based Flow−
C o n t r o l Mode
∗ @param l o c a l c i d L2CAP Channel I d e n t i f i e r
∗ @param c r e d i t s Number a d d i t i o n a l c r e d i t s f o r p e e r
529
∗ @return s t a t u s
∗/
uint8 t l 2 c a p e c b m p r o v i d e c r e d i t s ( uint16 t l o c a l c i d , uint16 t
credits ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t e m i s s i o n o f L2CAP EVENT ECBM CAN SEND NOW as soon
as p o s s i b l e
∗ @note L2CAP EVENT ECBM CAN SEND NOW might be e m i t t e d d u r i n g c a l l
to t h i s function
∗ so p a c k e t h a n d l e r s h o u l d be r e a d y t o h a n d l e i t
∗ @param l o c a l c i d L2CAP Channel I d e n t i f i e r
∗ @return s t a t u s
∗/
uint8 t l 2 c a p e c b m r e q u e s t c a n s e n d n o w e v e n t ( uint16 t l o c a l c i d ) ;
/∗ ∗
∗ @ b r i e f R e c o n f i g u r e MPS/MTU o f l o c a l c h a n n e l s
∗ @param num cids
∗ @param l o c a l c i d s array of l o c a l c i d s to r e c o n f i g u r e
∗ @param r e c e i v e b u f f e r s i z e b u f f e r s i z e e q u a l s MTU
∗ @param r e c e i v e b u f f e r s Array o f b u f f e r s used f o r r e a s s e m b l y
o f L2CAP I n f o r m a t i o n Frames i n t o s e r v i c e d a t a u n i t (SDU) w i t h
g i v e n MTU
∗ @return s t a t u s
∗/
uint8 t l 2 c a p e c b m r e c o n f i g u r e c h a n n e l s ( uint8 t num cids , uint16 t ∗
l o c a l c i d s , i n t 1 6 t r e c e i v e b u f f e r s i z e , uint8 t ∗∗
receive buffers ) ;
/∗ ∗
∗ @brief Trigger pending connection responses a f t e r p a i r i n g
completed
∗ @note Must be c a l l e d a f t e r r e c e i v i n g an SM PAIRING COMPLETE e v e n t
, w i l l be removed e v e n t u a l l y
∗ @param c o n h a n d l e
∗/
void l 2 c a p e c b m t r i g g e r p e n d i n g c o n n e c t i o n r e s p o n s e s (
hci con handle t con handle ) ;
/∗ ∗
∗ @ b r i e f De−I n i t L2CAP
∗/
void l 2 c a p d e i n i t ( void ) ;
1.99. Audio Stream Control Service Client API. broadcast audio scan service client.h
typedef enum {
BROADCAST AUDIO SCAN SERVICE CLIENT STATE IDLE ,
BROADCAST AUDIO SCAN SERVICE CLIENT STATE W2 QUERY SERVICE,
BROADCAST AUDIO SCAN SERVICE CLIENT STATE W4 SERVICE RESULT,
530
BROADCAST AUDIO SCAN SERVICE CLIENT W2 WRITE CONTROL POINT START SCAN
,
BROADCAST AUDIO SCAN SERVICE CLIENT W4 WRITE CONTROL POINT START SCAN
,
BROADCAST AUDIO SCAN SERVICE CLIENT W2 WRITE CONTROL POINT STOP SCAN
,
BROADCAST AUDIO SCAN SERVICE CLIENT W4 WRITE CONTROL POINT STOP SCAN
,
BROADCAST AUDIO SCAN SERVICE CLIENT W2 WRITE CONTROL POINT ADD SOURCE
,
BROADCAST AUDIO SCAN SERVICE CLIENT W4 WRITE CONTROL POINT ADD SOURCE
,
BROADCAST AUDIO SCAN SERVICE CLIENT W2 WRITE CONTROL POINT MODIFY SOURCE
,
BROADCAST AUDIO SCAN SERVICE CLIENT W4 WRITE CONTROL POINT MODIFY SOURCE
,
BROADCAST AUDIO SCAN SERVICE CLIENT W2 WRITE CONTROL POINT SET BROADCAST CODE
,
BROADCAST AUDIO SCAN SERVICE CLIENT W4 WRITE CONTROL POINT SET BROADCAST CODE
,
BROADCAST AUDIO SCAN SERVICE CLIENT W2 WRITE CONTROL POINT REMOVE SOURCE
,
BROADCAST AUDIO SCAN SERVICE CLIENT W4 WRITE CONTROL POINT REMOVE SOURCE
,
typedef struct {
// used f o r add s o u r c e command
b a s s s o u r c e d a t a t data ;
// r e c e i v e d v i a n o t i f i c a t i o n
bool in use ;
uint8 t s o u r c e i d ;
le audio big encryption t big encryption ;
uint8 t bad code [ 1 6 ] ;
// c h a r a c t e r i s t i c
uint16 t r e c e i v e s t a t e value handle ;
uint16 t r e c e i v e s t a t e ccc handle ;
uint16 t r e c e i v e s t a t e properties ;
uint16 t r e c e i v e s t a t e end handle ;
} bass client source t ;
typedef struct {
b t s t a c k l i n k e d i t e m t item ;
// s e r v i c e
uint16 t s t a r t h a n d l e ;
uint16 t e n d h a n d l e ;
uint16 t c o n t r o l p o i n t v a l u e h a n d l e ;
// used f o r memory c a p a c i t y c h e c k i n g
uint8 t s e r v i c e i n s t a n c e s n u m ;
uint8 t r e c e i v e s t a t e s i n s t a n c e s n u m ;
// used f o r n o t i f i c a t i o n r e g i s t r a t i o n
uint8 t r e c e i v e s t a t e s i n d e x ;
uint8 t m a x r e c e i v e s t a t e s n u m ;
bass client source t ∗ receive states ;
// used f o r w r i t e s e g m e n t a t i o n
uint8 t b u f f e r [ BASS CLIENT MAX ATT BUFFER SIZE ] ;
uint16 t b u f f e r o f f s e t ;
uint16 t d a t a s i z e ;
// used f o r a d d i n g and m o d i f y i n g s o u r c e
const b a s s s o u r c e d a t a t ∗ c o n t r o l p o i n t o p e r a t i o n d a t a ;
uint8 t c o n t r o l p o i n t o p e r a t i o n s o u r c e i d ;
// used f o r s e t t i n g t h e b r o a d c a s t code
const uint8 t ∗ b r o a d c a s t c o d e ;
} bass client connection t ;
532
/∗ ∗
∗ @ b r i e f I n i t B r o a d c a s t Audio Scan S e r v i c e C l i e n t . R e g i s t e r p a c k e t
handler to receive events :
∗ − GATTSERVICE SUBEVENT BASS CLIENT CONNECTED
∗ − GATTSERVICE SUBEVENT BASS CLIENT DISCONNECTED
∗ − GATTSERVICE SUBEVENT BASS CLIENT SCAN OPERATION COMPLETE
∗ − GATTSERVICE SUBEVENT BASS CLIENT SOURCE OPERATION COMPLETE
∗ − GATTSERVICE SUBEVENT BASS CLIENT NOTIFICATION COMPLETE
∗ @param p a c k e t h a n d l e r f o r e v e n t s
∗/
void b r o a d c a s t a u d i o s c a n s e r v i c e c l i e n t i n i t (
btstack packet handler t p a c k e t h a n d l e r ) ;
/∗ ∗
∗ @ b r i e f Connect t o BASS S e r v i c e on remote d e v i c e
∗ @note GATTSERVICE SUBEVENT BASS CLIENT CONNECTED w i l l be e m i t t e d
∗ @param c o n n e c t i o n s t r u c t p r o v i d e d by user , n ee d s t o s t a y v a l i d
u n t i l disconnect event i s received
∗ @param s o u r c e s b u f f e r t o s t o r e i n f o r m a t i o n on B r o a d c a s t S o u r c e s
on t h e s e r v i c e
∗ @param num sources
∗ @param c o n h a n d l e t o c o n n e c t t o
∗ @param b a s s c i d c o n n e c t i o n i d f o r t h i s c o n n e c t i o n f o r o t h e r
functions
∗ @return s t a t u s
∗/
uint8 t b r o a d c a s t a u d i o s c a n s e r v i c e c l i e n t c o n n e c t (
b a s s c l i e n t c o n n e c t i o n t ∗ connection , b a s s c l i e n t s o u r c e t ∗
s o u r c e s , uint8 t num sources , h c i c o n h a n d l e t c o n h a n d l e ,
uint16 t ∗ b a s s c i d ) ;
/∗ ∗
∗ @ b r i e f N o t i f y BASS S e r v i c e t h a t s c a n n i n g has s t a r t e d
∗ @param b a s s c i d
∗ @return s t a t u s
∗/
uint8 t b r o a d c a s t a u d i o s c a n s e r v i c e c l i e n t s c a n n i n g s t a r t e d (
uint16 t b a s s c i d ) ;
/∗ ∗
∗ @ b r i e f N o t i f y BASS S e r v i c e t h a t s c a n n i n g has s t o p p e d
∗ @note e m i t s
GATTSERVICE SUBEVENT BASS CLIENT SOURCE OPERATION COMPLETE
∗ @param b a s s c i d
∗ @return s t a t u s
∗/
uint8 t b r o a d c a s t a u d i o s c a n s e r v i c e c l i e n t s c a n n i n g s t o p p e d (
uint16 t b a s s c i d ) ;
/∗ ∗
∗ @ b r i e f Add B r o a d c a s t Source on s e r v i c e
∗ @note GATTSERVICE SUBEVENT BASS NOTIFICATION COMPLETE w i l l
contain source id for other functions
533
∗ @param b a s s c i d
∗ @param a d d s o u r c e d a t a d a t a t o add , ne e ds t o s t a y v a l i d u n t i l
GATTSERVICE SUBEVENT BASS CLIENT SOURCE OPERATION COMPLETE
∗ @return s t a t u s
∗/
uint8 t b r o a d c a s t a u d i o s c a n s e r v i c e c l i e n t a d d s o u r c e ( uint16 t
b a s s c i d , const b a s s s o u r c e d a t a t ∗ a d d s o u r c e d a t a ) ;
/∗ ∗
∗ @ b r i e f Modify i n f o r m a t i o n a b o u t B r o a d c a s t Source on s e r v i c e
∗ @param b a s s c i d
∗ @param s o u r c e i d
∗ @param m o d i f y s o u r c e d a t a d a t a t o modify , ne ed s t o s t a y v a l i d
until
GATTSERVICE SUBEVENT BASS CLIENT SOURCE OPERATION COMPLETE
∗ @return s t a t u s
∗/
uint8 t b r o a d c a s t a u d i o s c a n s e r v i c e c l i e n t m o d i f y s o u r c e ( uint16 t
b a s s c i d , uint8 t s o u r c e i d , const b a s s s o u r c e d a t a t ∗
modify source data ) ;
/∗ ∗
∗ @ b r i e f S e t B r o a d c a s t Code f o r a B r o a d c a s t Source t o a l l o w remote
do d e c r y p t a u d i o stream
∗ @param b a s s c i d
∗ @param s o u r c e i d
∗ @param b r o a d c a s t c o d e
∗ @return s t a t u s
∗/
uint8 t b r o a d c a s t a u d i o s c a n s e r v i c e c l i e n t s e t b r o a d c a s t c o d e (
uint16 t b a s s c i d , uint8 t s o u r c e i d , const uint8 t ∗
broadcast code ) ;
/∗ ∗
∗ @ b r i e f Remove i n f o r m a t i o n a b o u t B r o a d c a s t Source
∗ @param b a s s c i d
∗ @param s o u r c e i d
∗ @return s t a t u s
∗/
uint8 t b r o a d c a s t a u d i o s c a n s e r v i c e c l i e n t r e m o v e s o u r c e ( uint16 t
b a s s c i d , uint8 t s o u r c e i d ) ;
/∗ ∗
∗ @param P r o v i d e read−o n l y a c c e s s t o B r o a d c a s t R e c e i v e S t a t e o f
g i v e n B r o a d c a s t Source on s e r v i c e
∗ @param b a s s c i d
∗ @param s o u r c e i d
∗ @return p o i n t e r t o s o u r c e d a t a or NULL, i f s o u r c e i d not found
∗/
const b a s s s o u r c e d a t a t ∗
b r o a d c a s t a u d i o s c a n s e r v i c e c l i e n t g e t s o u r c e d a t a ( uint16 t
b a s s c i d , uint8 t s o u r c e i d ) ;
/∗ ∗
534
uint8 t
/∗ ∗
∗ @ b r i e f D e i n i t B r o a d c a s t Audio Scan S e r v i c e C l i e n t
∗/
void b r o a d c a s t a u d i o s c a n s e r v i c e c l i e n t d e i n i t ( uint16 t b a s s c i d ) ;
1.100. Broadcast Audio Scan Service Server (BASS) API. broadcast audio scan service
: @text The Broadcast Audio Scan Service is used by servers to expose their sta-
tus with respect to synchronization to broadcast Audio Streams and associated
data, including Broadcast Codes used to decrypt encrypted broadcast Audio
Streams. Clients can use the attributes exposed by servers to observe and/or
request changes in server behavior.
To use with your application, add #import <broadcast audio scan service.gatt> to
your .gatt file.
// memory f o r l i s t o f t h e s e s t r u c t s i s a l l o c a t e d by t h e a p p l i c a t i o n
typedef struct {
// a s s i g n e d by c l i e n t v i a c o n t r o l p o i n t
b a s s s o u r c e d a t a t data ;
uint16 t b a s s r e c e i v e s t a t e h a n d l e ;
uint16 t b a s s r e c e i v e s t a t e c l i e n t c o n f i g u r a t i o n h a n d l e ;
uint16 t b a s s r e c e i v e s t a t e c l i e n t c o n f i g u r a t i o n ;
} bass server source t ;
typedef struct {
hci con handle t con handle ;
uint16 t s o u r c e s t o n o t i f y ;
// used f o r c a c h i n g l o n g w r i t e
uint8 t l o n g w r i t e b u f f e r [ 5 1 2 ] ;
uint16 t l o n g w r i t e v a l u e s i z e ;
uint16 t l o n g w r i t e a t t r i b u t e h a n d l e ;
} bass server connection t ;
/∗ ∗
∗ @ b r i e f I n i t B r o a d c a s t Audio Scan S e r v i c e S e r v e r w i t h ATT DB
∗ @param sources num
∗ @param s o u r c e s
∗ @param c l i e n t s n u m
∗ @param c l i e n t s
∗/
void b r o a d c a s t a u d i o s c a n s e r v i c e s e r v e r i n i t ( uint8 t const
sources num , b a s s s e r v e r s o u r c e t ∗ s o u r c e s , uint8 t const
clients num , b a s s s e r v e r c o n n e c t i o n t ∗ c l i e n t s ) ;
/∗ ∗
∗ @brief Register packet handler to receive events :
∗ − GATTSERVICE SUBEVENT BASS SERVER SCAN STOPPED
∗ − GATTSERVICE SUBEVENT BASS SERVER SCAN STARTED
∗ − GATTSERVICE SUBEVENT BASS SERVER BROADCAST CODE
∗ − GATTSERVICE SUBEVENT BASS SERVER SOURCE ADDED
∗ − GATTSERVICE SUBEVENT BASS SERVER SOURCE MODIFIED
∗ − GATTSERVICE SUBEVENT BASS SERVER SOURCE DELETED
∗ @param p a c k e t h a n d l e r
∗/
void b r o a d c a s t a u d i o s c a n s e r v i c e s e r v e r r e g i s t e r p a c k e t h a n d l e r (
btstack packet handler t p a c k e t h a n d l e r ) ;
/∗ ∗
∗ @ b r i e f S e t PA s t a t e o f s o u r c e .
∗ @param s o u r c e i n d e x
∗ @param s y n c s t a t e
∗/
void b r o a d c a s t a u d i o s c a n s e r v i c e s e r v e r s e t p a s y n c s t a t e ( uint8 t
source index , le audio pa sync state t sync state ) ;
/∗ ∗
∗ @ b r i e f Add s o u r c e .
∗ @param s o u r c e d a t a
∗ @param s o u r c e i n d e x
∗/
536
void b r o a d c a s t a u d i o s c a n s e r v i c e s e r v e r a d d s o u r c e ( const
b a s s s o u r c e d a t a t ∗ s o u r c e d a t a , uint8 t ∗ s o u r c e i n d e x ) ;
/∗ ∗
∗ @ b r i e f D e i n i t B r o a d c a s t Audio Scan S e r v i c e S e r v e r
∗/
void b r o a d c a s t a u d i o s c a n s e r v i c e s e r v e r d e i n i t ( void ) ;
1.102. Broadcast Audio Source Endpoint AD Builder API. le audio base builder.h
1.103. Broadcast Audio Source Endpoint AD Parser API. le audio base parser.h
1.105. Mesh Provisioning Service Server API. mesh provisioning service server.h
/∗ ∗
∗ @ b r i e f I n i t Mesh P r o v i s i o n i n g S e r v i c e S e r v e r w i t h ATT DB
∗/
void m e s h p r o v i s i o n i n g s e r v i c e s e r v e r i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f Send a Proxy PDU message c o n t a i n i n g P r o v i s i o n i n g PDU from
a Provisioning Server to a Provisioning Client .
∗ @param c o n h a n d l e
∗ @param p r o x y p d u
∗ @param p r o x y p d u s i z e max l e n g h t MESH PROV MAX PROXY PDU
∗/
void m e s h p r o v i s i o n i n g s e r v i c e s e r v e r s e n d p r o x y p d u ( uint16 t
c o n h a n d l e , const uint8 t ∗ proxy pdu , uint16 t p r o x y p d u s i z e ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k f o r t h e PB−GATT.
∗ @param c a l l b a c k
∗/
void m e s h p r o v i s i o n i n g s e r v i c e s e r v e r r e g i s t e r p a c k e t h a n d l e r (
btstack packet handler t c a l l b a c k ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t can send now e v e n t t o send PDU
∗ G e n e r a t e s an MESH SUBEVENT CAN SEND NOW s u b e v e n t
∗ @param c o n h a n d l e
∗/
void m e s h p r o v i s i o n i n g s e r v i c e s e r v e r r e q u e s t c a n s e n d n o w (
hci con handle t con handle ) ;
537
1.106. Mesh Proxy Service Server API. mesh proxy service server.h
/∗ ∗
∗ @ b r i e f I n i t Mesh Proxy S e r v i c e S e r v e r w i t h ATT DB
∗/
void m e s h p r o x y s e r v i c e s e r v e r i n i t ( void ) ;
/∗ ∗
∗ @ b r i e f Send a Proxy PDU message c o n t a i n i n g p r o x y PDU from a p r o x y
Server to a proxy C l i e n t .
∗ @param c o n h a n d l e
∗ @param p r o x y p d u
∗ @param p r o x y p d u s i z e max l e n g h t MESH PROV MAX PROXY PDU
∗/
void m e s h p r o x y s e r v i c e s e r v e r s e n d p r o x y p d u ( uint16 t c o n h a n d l e ,
const uint8 t ∗ proxy pdu , uint16 t p r o x y p d u s i z e ) ;
/∗ ∗
∗ @ b r i e f R e g i s t e r c a l l b a c k f o r t h e PB−GATT.
∗ @param c a l l b a c k
∗/
void m e s h p r o x y s e r v i c e s e r v e r r e g i s t e r p a c k e t h a n d l e r (
btstack packet handler t c a l l b a c k ) ;
/∗ ∗
∗ @ b r i e f R e q u e s t can send now e v e n t t o send PDU
∗ G e n e r a t e s an MESH SUBEVENT CAN SEND NOW s u b e v e n t
∗ @param c o n h a n d l e
∗/
void m e s h p r o x y s e r v i c e s e r v e r r e q u e s t c a n s e n d n o w ( h c i c o n h a n d l e t
con handle ) ;
1.107. L2CAP Events. L2CAP events and data packets are delivered to the
packet handler specified by l2cap register service resp. l2cap create channel. Data
packets have the L2CAP DATA PACKET packet type. L2CAP provides the fol-
lowing events:
• L2CAP EVENT CHANNEL OPENED - sent if channel establishment is
done. Status not equal zero indicates an error. Possible errors: out of
memory; connection terminated by local host, when the connection to
remote device fails.
• L2CAP EVENT CHANNEL CLOSED - emitted when channel is closed.
No status information is provided.
• L2CAP EVENT INCOMING CONNECTION - received when the con-
nection is requested by remote. Connection accept and decline are per-
formed with l2cap accept connection and l2cap decline connecti-on re-
spectively.
• L2CAP EVENT CAN SEND NOW - Indicates that an L2CAP data packet
could be sent on the reported l2cap cid. It is emitted after a call to
538
l2cap request can send now. See Sending L2CAP Data Please note that
the guarantee that a packet can be sent is only valid when the event is
received. After returning from the packet handler, BTstack might need
to send itself.
as an alternative a Web service, that can simplify the migration to the new v1.0
API.
2. Changes
2.1. Repository structure.
2.1.1. include/btstack folder. The header files had been split between src/ and
include/btstack /. Now, the include/ folder is gone and the headers are pro-
vided in src/, src/classic/, src/ble/ or by the platform/ folders. There’s a new
src/btstack.h header that includes all BTstack headers.
2.1.2. Plural folder names. Folder with plural names have been renamed to the
singular form, examples: doc, chipset, platform, tool.
2.1.3. ble and src folders. The ble folder has been renamed into src/ble. Files
that are relevant for using BTstack in Classic mode, have been moved to src/-
classic. Files in src that are specific to individual platforms have been moved to
platform or port.
2.1.4. platform and port folders. The platforms folder has been split into plat-
form and “port” folders. The port folder contains a complete BTstack port of
for a specific setup consisting of an MCU and a Bluetooth chipset. Code that
didn’t belong to the BTstack core in src have been moved to platform or port as
well, e.g. hci transport h4 dma.c.
2.1.5. Common file names. Types with generic names like linked list have been
prefixed with btstack (e.g. btstack linked list.h) to avoid problems when inte-
grating with other environments like vendor SDKs.
2.2. Defines and event names. All defines that originate from the Blue-
tooth Specification are now in src/bluetooth.h. Addition defines by BTstack
are collected in src/btstack defines.h. All events names have the form MOD-
ULE EVENT NAME now.
2.3. Function names.
• The internal suffix has been an artifact from the iOS port. All public
functions with the internal suffix have been stripped of this suffix.
• Types with generic names like linked list have been prefixed with btstack
(e.g. btstack linked list) to avoid problems when integrating with other
environments like vendor SDKs.
2.4. Packet Handlers. We streamlined the use of packet handlers and their
types. Most callbacks are now of type btstack packet handler t and receive a
pointer to an HCI Event packet. Often a void * connection was the first argument
- this has been removed.
To facilitate working with HCI Events and get rid of manually calculating
offsets into packets, we’re providing auto-generated getters for all fields 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 memory footprint
541
should be identical to accessing the field directly via offsets into the packet. Feel
free to start using these getters as needed.
2.5. Event Forwarding. In the past, events have been forwarded up the stack
from layer to layer, with the undesired effect that an app that used both att server
and security manager would get each HCI event twice. To fix this and other
potential issues, this has been cleaned up by providing a way to register multiple
listeners for HCI events. If you need to receive HCI or GAP events, you can now
directly register your callback with hci add event handler.
2.6. util folder. The utils folder has been renamed into btstack util to avoid
compile issues with other frameworks.
• The functions to read/store values in little/bit endian have been renamed
into big/little endian read/write 16/24/32.
• The functions to reverse bytes swap16/24/32/48/64/128/X habe been
renamed to reverse 16/24/32/48/64/128/X.
2.7. btstack config.h.
• btstack-config.h is now btstack config.h
• Defines have been sorted: HAVE specify features that are particular to
your port. ENABLE features can be added as needed.
• NO has been replaced with NR for the BTstack static memory allocation,
e.g., MAX NO HCI CONNECTIONS8 -> MAX NR HCI CONNECTIONS
• The #define EMBEDDED is dropped, i.e. the distinction if the API is
for embedded or not has been removed.
2.8. Linked List.
• The file has been renamed to btstack linked list.
• All functions are prefixed with btstack .
• The user data field has been removed as well.
2.9. Run Loop.
• The files have been renamed to btstack run loop
• To allow for simpler integration of custom run loop implementations,
run loop init(. . . ) is now called with a pointer to a run loop t function
table instead of using an enum that needs to be defined inside the BTstack
sources.
• Timers now have a new context field that can be used by the user.
2.10. HCI Setup. In the past, hci init(. . . ) was called with an hci transport t,
the transport configuration, remote device t and a bt control t objects. Besides
cleaning up the types (see remote device db and bt control below), hci init only
requires the hci transport t and it’s configuration.
The used btstack chipset t, bt control t, or link key db t can now be set with
hci set chipset, hci set control, and hci set link key db respectively.
2.10.1. remote device db. Has been split into src/classic/btstack link key db, plat-
form/daemon/btstack device name db, and platform/daemon/rfcomm service db.
2.10.2. bt control. Has been split into src/btstack chipset.h and src/bstack control.h
542
2.11. HCI / GAP. HCI functions that are commonly placed in GAP have been
moved from src/hci.h to src/gap.h
2.13. SPP Server. The function to create an SPP SDP record has been moved
into spp server.h
2.20. Daemon.
• Not tested since API migration!
• Moved into platform/daemon/
• Header for clients: platform/daemon/btstack client.h
• Java bindings are now at platform/daemon/bindings
2.21. Migration to v1.0 with a script. To simplify the migration to the new
v1.0 API, we’ve provided a tool in tool/migration to v1.0 that fixes include path
changes, handles all function renames and also updates the packet handlers to
the btstack packet handler t type. It also has a few rules that try to rename file
names in Makefile as good as possible.
It’s possible to migrate most of the provided embedded examples to v1.0. The
one change that it cannot handle is the switch from structs to HCI Events for the
SDP, GATT, and ANCS clients. The migration tool updates the packet handler
signature to btstack packet handler t, but it does not convert the field accesses to
sue the appropriate getters in btstack event.h. This has to be done manually, but
it is straight forward. E.g., to read the field status of the GATT EVENT QUERY COMPLETE,
you call call gatt event query complete get status(packet).
2.21.1. Requirements.
• bash
• sed
• Coccinelle. On Debian-based distributions, it’s available via apt. On OS
X, it can be installed via Homebrew.
2.21.2. Usage.
The tool first creates a copy of the original project and then uses sed and
coccinelle to update the source files.
2.22. Migration to v1.0 with a Web Service. BlueKitchen GmbH is pro-
viding a web service to help migrate your sources if you don’t want or cannot
install Coccinelle yourself.