MediaTek LinkIt™ Development Platform For RTOS Bluetooth Developer's Guide Link It Developers
LinkIt_for_RTOS_Bluetooth_Developers_Guide
LinkIt_for_RTOS_Bluetooth_Developers_Guide
LinkIt_for_RTOS_Bluetooth_Developers_Guide
User Manual:
Open the PDF directly: View PDF
.
Page Count: 129
| Download | |
| Open PDF In Browser | View PDF |
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Version:
1.5
Release date:
15 September 2017
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s). MediaTek cannot grant you
permission for any material that is owned by third parties. You may only use or reproduce this document if you have agreed to and been
bound by the applicable license agreement with MediaTek (“License Agreement”) and been granted explicit permission within the License
Agreement (“Permitted User”). If you are not a Permitted User, please cease any access or use of this document immediately. Any
unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited. THIS DOCUMENT IS PROVIDED ON AN
“AS-IS” BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES OF ANY KIND AND SHALL IN NO EVENT BE LIABLE FOR ANY
CLAIMS RELATING TO OR ARISING OUT OF THIS DOCUMENT OR ANY USE OR INABILITY TO USE THEREOF. Specifications contained herein are
subject to change without notice.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Document Revision History
Revision
Date
Description
1.0
2 September 2016
Initial release
1.1
4 November 2016
Added description for multi-advertising support, see section 4.1.8,
"Multiple advertising".
1.2
13 January 2017
Added description for AWS, see section 3.8, “AWS”
Added Bluetooth panic mechanism, see section 5.4, “Bluetooth
panic mechanism”
1.3
5 May 2017
Refine the issues in table of contents (TOC).
1.4
30 June 2017
•
•
1.5
15 September 2017
Updated description for AWS, see section 3.8 “AWS”.
Updated AVRCP version from 1.3 to 1.6, added section 3.5.2.4,
“Absolute volume”.
•
Added description to get play status, added section 3.5.2.7,
“Get play status”.
•
Added description for get capabilities, see section 3.5.2.8,
“Get capabilities”.
•
Added description for A2DP source and sink, see section 3.4,
“A2DP”
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page i of v
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Table of Contents
1.
Overview ............................................................................................................................................... 1
1.1.
2.
Support for Bluetooth............................................................................................................................ 4
2.1.
3.
Memory management .................................................................................................................... 114
Create an application task .............................................................................................................. 117
Interaction with the Bluetooth host stack ...................................................................................... 118
Bluetooth panic mechanism ........................................................................................................... 120
Debugging and Porting Layer ..............................................................................................................122
6.1.
6.2.
7.
GAP ................................................................................................................................................... 71
SM ..................................................................................................................................................... 83
GATT ................................................................................................................................................. 93
Creating a Custom Bluetooth Application ...........................................................................................114
5.1.
5.2.
5.3.
5.4.
6.
GAP ..................................................................................................................................................... 7
SDP .................................................................................................................................................... 16
HFP.................................................................................................................................................... 21
A2DP ................................................................................................................................................. 35
AVRCP ............................................................................................................................................... 45
PBAP ................................................................................................................................................. 53
SPP .................................................................................................................................................... 60
AWS .................................................................................................................................................. 63
The Bluetooth Low Energy Protocol or Profiles .....................................................................................71
4.1.
4.2.
4.3.
5.
LinkIt SDK library ................................................................................................................................. 4
The Bluetooth BR/EDR Protocol and Profiles ......................................................................................... 7
3.1.
3.2.
3.3.
3.4.
3.5.
3.6.
3.7.
3.8.
4.
Bluetooth protocol stack .................................................................................................................... 1
Debugging ....................................................................................................................................... 122
Porting layer ................................................................................................................................... 122
Appendix A: Acronyms and Abbreviations ..........................................................................................123
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page ii of v
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Lists of Tables and Figures
Table 1. LinkIt SDK library support for Bluetooth ...................................................................................................4
Table 2. Player application settings and values ....................................................................................................49
Table 3. Media element attributes .......................................................................................................................49
Table 4. List of notification events ........................................................................................................................50
Table 5. Fixed size control blocks ........................................................................................................................114
Table 6. Acronyms and abbreviations .................................................................................................................123
Figure 1. BR/EDR protocol stack .............................................................................................................................1
Figure 2. Bluetooth Low Energy protocol stack ......................................................................................................3
Figure 3. The GAP abstraction layout......................................................................................................................7
Figure 4. Set the scan mode message sequence.....................................................................................................8
Figure 5. GAP inquiry message sequence ...............................................................................................................8
Figure 6. Bonding using auto-confirmation message sequence .............................................................................9
Figure 7. Bonding using numeric comparison message sequence........................................................................10
Figure 8. Bonding using passkey entry message sequence...................................................................................11
Figure 9. Bonding using pin code message sequence ...........................................................................................11
Figure 10. GAP disconnect message sequence .....................................................................................................12
Figure 11. SDP abstraction layout .........................................................................................................................16
Figure 12. SDP client-server architecture .............................................................................................................17
Figure 13. SDP service record ...............................................................................................................................17
Figure 14. SDP server role .....................................................................................................................................18
Figure 15. HFP abstraction layout .........................................................................................................................21
Figure 16. HFP connection establishment message sequence .............................................................................23
Figure 17. HFP connection release message sequence ........................................................................................24
Figure 18. Initiate an outgoing voice call message sequence ...............................................................................25
Figure 19. Audio connection setup message sequence ........................................................................................26
Figure 20. Audio connection release message sequence .....................................................................................27
Figure 21. Enable or disable the voice recognition message sequence ................................................................28
Figure 22. The actions of an incoming call message sequence .............................................................................29
Figure 23. The three way call handling message sequence ..................................................................................30
Figure 24. The remote speaker volume control message sequence ....................................................................31
Figure 25. The remote microphone volume control message sequence ..............................................................32
Figure 26. Transmit DTMF codes message sequence ...........................................................................................33
Figure 27. Query a list of current calls message sequence ...................................................................................34
Figure 28. The A2DP state diagram .......................................................................................................................36
Figure 29. The A2DP abstraction layout................................................................................................................36
Figure 30. The A2DP connection establishment message sequence ....................................................................37
Figure 31. The A2DP connection release message sequence ...............................................................................38
Figure 32. The A2DP start streaming message sequence .....................................................................................39
Figure 33. The A2DP suspend streaming message sequence ...............................................................................39
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page iii of v
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Figure 34. The A2DP reconfiguration message sequence .....................................................................................40
Figure 35. The A2DP codec operation message sequence (Sink) .........................................................................41
Figure 36. The A2DP codec operation message sequence (Source) .....................................................................42
Figure 37. The AVRCP abstraction layout..............................................................................................................45
Figure 38. AVRCP connection establishment ........................................................................................................46
Figure 39. AVRCP connection release ...................................................................................................................47
Figure 40. AV/C command procedure...................................................................................................................48
Figure 41. PBAPC abstraction layout.....................................................................................................................53
Figure 42. PBAPC connection establishment without authentication message sequence ...................................54
Figure 43. PBAPC get phone book object message sequence ..............................................................................55
Figure 44. PBAPC get the number of phonebook objects message sequence......................................................56
Figure 45. PBAPC get caller name by number message sequence .......................................................................57
Figure 46. PBAPC PullvCardEntry message sequence ....................................................................................58
Figure 47. Disconnect message sequence ............................................................................................................58
Figure 48. SPP abstraction layout .........................................................................................................................60
Figure 49. SPP connection establishment message sequence ..............................................................................61
Figure 50. SPP connection release message sequence .........................................................................................61
Figure 51. SPP data transfer message sequence...................................................................................................62
Figure 52. The AWS abstraction layout .................................................................................................................63
Figure 53. The AWS connection establishment message sequence .....................................................................64
Figure 54. The AWS connection release message sequence ................................................................................65
Figure 55. The AWS start streaming message sequence ......................................................................................66
Figure 56. The AWS suspend streaming message sequence ................................................................................67
Figure 57. The AWS voice message synchronization sequence ............................................................................68
Figure 58. GAP state diagram................................................................................................................................71
Figure 59. GAP abstraction layout ........................................................................................................................72
Figure 60. Powering on the Bluetooth message sequence ...................................................................................73
Figure 61. GAP active scan message sequence .....................................................................................................74
Figure 62. GAP passive scan message sequence ...................................................................................................74
Figure 63. GAP general connection message sequence........................................................................................75
Figure 64. GAP auto connection message sequence ............................................................................................76
Figure 65. Connection interval and event .............................................................................................................78
Figure 66. Slave latency ........................................................................................................................................78
Figure 67. Connection timeout error occurred (error code -0x08) .......................................................................79
Figure 68. Connection timeout error occurred (error code -0x3E) .......................................................................79
Figure 69. SM abstraction layout ..........................................................................................................................85
Figure 70. Just Works (central role) ......................................................................................................................86
Figure 71. Just Works (peripheral role) .................................................................................................................86
Figure 72. Numeric Comparison (central role) ......................................................................................................87
Figure 73. Numeric Comparison (peripheral role) ................................................................................................88
Figure 74. Passkey entry (central role)..................................................................................................................89
Figure 75. Passkey entry (peripheral role) ............................................................................................................90
Figure 76. Encryption (central role) ......................................................................................................................90
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page iv of v
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Figure 77. Encryption (peripheral role) .................................................................................................................91
Figure 78. GATT Client and Server ........................................................................................................................93
Figure 79. GATT profile hierarchy .........................................................................................................................94
Figure 80. Logical representation of the attribute ................................................................................................94
Figure 81. Exchange MTU event sequence .........................................................................................................100
Figure 82. Primary service discovery event sequence ........................................................................................101
Figure 83. Find included services event sequence ..............................................................................................103
Figure 84. Discover characteristic event sequence .............................................................................................104
Figure 85. Characteristic descriptor discovery event sequence .........................................................................105
Figure 86. Characteristic value read event sequence .........................................................................................107
Figure 87. Read characteristic value using UUID event sequence ......................................................................108
Figure 88. Read multiple characteristic value event sequence...........................................................................109
Figure 89. Characteristic value write event sequence ........................................................................................110
Figure 90. Long value write event sequence ......................................................................................................111
Figure 91. Characteristic value indication event sequence.................................................................................112
Figure 92. Application interaction with the Bluetooth API .................................................................................119
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page v of v
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
1.
Overview
MediaTek LinkIt™ development platform for RTOS provides Bluetooth and Bluetooth Low Energy (LE) connectivity
support for IoT and Wearable’s applications. Bluetooth standard offers basic rate (BR) or enhanced data rate (EDR)
and Bluetooth Low Energy (LE) support. Devices that can support BR/EDR and Bluetooth LE are referred to as dualmode devices. Typically, in a Bluetooth system, a mobile phone or laptop computer acts as a dual-mode device.
Devices that only support Bluetooth LE are referred to as single-mode devices where the low power consumption
is the primary concern for application development, such as those that run on coin cell batteries.
This document guides you through:
•
Support for Bluetooth with the library description and supported reference examples.
•
Detailed description of the BR/EDR profiles.
•
Bluetooth LE profiles.
•
Custom application development and debugging logs.
1.1.
Bluetooth protocol stack
The Bluetooth protocol stack consists of two sections, the controller and the host, derived from the original
Bluetooth core specification where the two sections were often implemented separately.
1.1.1.
BR/EDR protocol stack
The BR/EDR protocol stack architecture is illustrated in Figure 1.
Host
PBAP
SPP
OBEX
RFCOMM
A2DP
AVRCP
AVDTP
AVCTP
GAP
SDP
HFP
L2CAP
Host-Controller Interface (HCI)
Link Layer (LL)
Physical Layer (PHY)
Controller
Figure 1. BR/EDR protocol stack
The controller section includes the Physical Layer (PHY), Link Layer (LL) and Host-Controller Interface (HCI).
The physical layer (PHY) is the lowest layer of the Bluetooth protocol stack to manage physical channels
and links.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 1 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
The link layer (LL) is used to control the radio link between two devices, handling matters such as link
establishment, querying device abilities and providing power control.
The host control interface (HCI) provides a means of communication between the host and controller
using a standardized interface.
The host includes various communication protocols, as described below.
The logical link control and adaption protocol (L2CAP) provides data encapsulation services to the upper
layers that enable logical end-to-end data communication.
The radio frequency communication (RFCOMM) is a set of transport protocols on top of the L2CAP
protocol, providing emulated RS-232 serial ports.
The generic access profile (GAP) defines the generic procedures related to discovery of Bluetooth devices
and link management aspects of connecting to Bluetooth devices.
The service discovery protocol (SDP) is used to allow devices to discover the supported services, and
parameters to use to connect to them.
The hands-free profile (HFP) allows hands-free kits to control the mobile phone of calling functions and
provide the voice connection between devices.
The object exchange (OBEX) is a communications protocol that facilitates the exchange of binary objects
between devices.
The phonebook access profile (PBAP) defines the procedures and protocols to exchange phonebook
objects between devices.
The Advanced Audio Distribution Profile (A2DP) defines how multimedia audio is streamed from one
device to another via Bluetooth connection
The audio/video distribution transport protocol (AVDTP) is used by the advanced audio distribution profile
to stream music to stereo headsets over the L2CAP channel intended for video distribution profile in the
Bluetooth transmission.
The audio/video control transport protocol (AVCTP) is used to transport the command/response
messages exchanged for the control of distant A/V devices over point-to-point connections.
The audio/video remote control profile (AVRCP) defines the features and procedures required in order to
ensure interoperability between Bluetooth devices with audio/video control functions in the audio/video
distribution scenarios.
The serial port profile (SPP) emulates a serial cable to provide a simple substitute for existing RS-232.
1.1.2.
Bluetooth LE protocol stack
The Bluetooth LE protocol stack architecture is shown in Figure 2.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 2 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Host
GATT
GAP
SM
ATT
L2CAP
Host-Controller Interface (HCI)
Link Layer (LL)
Physical Layer (PHY)
Controller
Figure 2. Bluetooth Low Energy protocol stack
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 3 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
2.
Support for Bluetooth
The platform includes MediaTek LinkIt™ SDK v4 that can be extended to develop Bluetooth applications. The
controller, host and application are implemented as a true single chip solution to enable cost effective and
application development with low power consumption.
The SDK is designed to support custom Bluetooth application development with protocol-layer access to the
following:
•
GAP
•
SDP
•
HFP
•
A2DP
•
AVRCP
•
PBAP
•
SPP
•
GAP LE
•
SM
•
GATT
For more information on the protocol specifications, refer to the Bluetooth Special Interest Group website.
The SDK includes the following content along with this document:
•
Binary libraries
•
C header files
•
Example applications
•
API reference guides
2.1.
LinkIt SDK library
The SDK provides a library file interface to the Bluetooth with C source and header files related to the platform, as
shown in Table 1.
Table 1. LinkIt SDK library support for Bluetooth
Module
Bluetooth
File Name
Location
Function
libbt.a
BR/EDR and Bluetooth LE stack
library
libbtdriver_[chip]
.a
Bluetooth driver library
libbt_hfp.a
/middleware/bluetooth/lib/
HFP library
libbt_a2dp.a
A2DP library
libbt_avrcp.a
AVRCP library, including the PASS
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 4 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Module
File Name
Location
Function
THROUGH command.
libbt_avrcp_enhanc
e.a
AVRCP library, including all
VENDOR DEPENDENT commands.
libbt_pbapc.a
PBAP library
libbt_spp.a
SPP library
bt_platform.h
Interface for Bluetooth tasks
bt_type.h
Common data types
bt_system.h
Interface for the system, such as
power on or off, memory initiation
and callback APIs for event
handling.
bt_uuid.h
Interface for the UUID
bt_spp.h
Interface for the SPP
bt_a2dp.h
Interface for the A2DP
bt_codec.h
Interface for the codec
bt_hfp.h
Interface for the HFP
bt_avrcp.h
Interface for the AVRCP
bt_pbapc.h
Interface for the PBAP client
bt_gap.h
bt_sdp.h
/middleware/bluetooth/inc/
Interface for the GAP
Interface for the SDP
bt_gap_le.h
Interface for the GAP for Bluetooth
LE support
bt_hci_le.h
HCI structures and events for
Bluetooth LE support
bt_gatt.h
GATT UUID
bt_gattc.h
Interface for the GATT client
bt_gatts.h
Interface for the GATT server
bt_att.h
Interface for the Attribute protocol
bt_os_layer_api.h
Wrapper APIs for RTOS, memory,
advanced encryption standard
(AES) and rand
bt_debug.h
Encapsulated debugging interface
bt_hci_log.h
Encapsulated interface for the HCI
logging
bt_os_layer_api.c
Encapsulated interface for system,
memory or AES. Developers can
replace the implementation when
porting to other platforms.
bt_debug.c
/middleware/bluetooth/src/
© 2015 - 2017 MediaTek Inc.
Encapsulated debugging interface.
Developers can replace the
implementation when porting to
other platforms.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 5 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Module
File Name
Location
Function
bt_hci.c
Encapsulated interface for the HCI
logging. Developers can replace
the implementation when porting
to other platforms.
bt_task.c
The default Bluetooth task entry
function.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 6 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
3.
The Bluetooth BR/EDR Protocol and Profiles
The Bluetooth support is provided as a collection of binary library files. This section provides details on the GAP,
SDP, HFP, A2DP, AVRCP, SPP and PBAP profiles for which application has direct access to the APIs.
3.1.
GAP
GAP services include device discovery, connection modes, security, authentication, association models and service
discovery. Implement a user-defined API bt_gap_get_local_configuration() in your application when
turning the Bluetooth on. The GAP profile then calls the function bt_gap_get_local_configuration() to get
the local configuration from the application.
The purpose of the inquiry is to discover other Bluetooth-enabled devices in general or limited discoverable modes.
The purpose of the bonding procedure is to create a connection between two Bluetooth-enabled devices based on
a common link key. The link key will be used for future authentication.
The GAP profile provides a user interface, sends related commands to the controller and receives events from the
controller, as shown in Figure 3.
Application
Send indication
or
confirmation
event
Call SDK API
GAP
Send command
Receive event
Host-Controller Interface (HCI)
Controller
Figure 3. The GAP abstraction layout
3.1.1.
The GAP message sequences
This section introduces typical message sequences to provide more details about the events and procedures. For
more details, refer to the bt_gap.h.
3.1.1.1.
Set the scan mode
The scan mode controls whether the device can be discovered or connected by other Bluetooth-enabled devices,
as shown in Figure 4. If set the scan mode is enabled, the device can be discovered by other Bluetooth devices. If
the page scan is enabled, the device can be connected by other Bluetooth devices.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 7 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
GAP
GAP
Application
bt_gap_set_scan_mode()
BT_GAP_SET_SCAN_MODE_CNF
bt_gap_inquiry()
Inquiry
Inquiry response
BT_GAP_DISCOVERY_RESULT_IND
Air transition
Function call
Messages
Figure 4. Set the scan mode message sequence
3.1.1.2.
Inquiry
The purpose of the inquiry is to discover other Bluetooth devices in general or limited discoverable mode, as
shown in Figure 5.
GAP
Application
GAP
Application
bt_gap_set_scan_mode()
bt_gap_inquiry()
BT_GAP_SET_SCAN_MODE_CNF
BT_GAP_INQUIRY_CNF
Inquiry
Inquiry response
BT_GAP_INQUIRY_IND
BT_GAP_INQUIRY_IND
……
BT_GAP_INQUIRY_COMPLETE_IND
Messages
Function call
Air transition
Figure 5. GAP inquiry message sequence
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 8 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
3.1.1.3.
Bonding
The purpose of bonding procedure is to create a connection between two Bluetooth-enabled devices based on a
common link key. The application should implement the user-defined API bt_gap_get_link_key(). After the
bonding procedure starts, the GAP profile calls the function bt_gap_get_link_key() to get the link key from
the application. If the link key already exists, proceed to authentication. Otherwise, the application receives
BT_GAP_BONDING_START_IND event and begins the pairing. After the pairing is complete, the application can
store the link key by handling the BT_GAP_LINK_KEY_NOTIFICATION_IND event, and
BT_GAP_BONDING_COMPLETE_IND event will be sent to notify the bonding result. There is no bonding API to start
a bonding procedure, it starts when connecting devices with authentication requirement. There are four bonding
modes: auto-confirmation, numeric comparison, passkey entry and pin code.
The auto-confirmation model is applied where the local I/O capability is either
BT_GAP_IO_CAPABILITY_NO_INPUT_NO_OUTPUT or BT_GAP_IO_CAPABILITY_DISPLAY_ONLY and the
remote I/O capability isn’t BT_GAP_IO_CAPABILITY_KEYBOARD_ONLY, as shown in Figure 6.
Application
Master
GAP
Slave
GAP
IO capability set to “no input no output”
Application
IO capability set to “no input no output”
bt_gap_get_link_key()
bt_gap_get_link_key()
BT_GAP_BONDING_START_IND
BT_GAP_BONDING_START_IND
BT_GAP_IO_CAPABILITY_REQ_IND
BT_GAP_IO_CAPABILITY_REQ_IND
bt_gap_reply_io_capability_request()
Pairing
BT_GAP_LINK_KEY_NOTIFICATION_IND
bt_gap_reply_io_capability_request()
BT_GAP_LINK_KEY_NOTIFICATION_IND
BT_GAP_BONDING_COMPLETE_IND
BT_GAP_BONDING_COMPLETE_IND
Messages
Function call
Figure 6. Bonding using auto-confirmation message sequence
The numeric comparison model is applied when the local I/O capability is
BT_GAP_IO_CAPABILITY_DISPLAY_YES_NO, as shown in Figure 7.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 9 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
Master
GAP
Slave
GAP
Application
IO capability set to “display yes no”
IO capability set to “display yes no”
bt_gap_get_link_key()
bt_gap_get_link_key()
BT_GAP_BONDING_START_IND
BT_GAP_BONDING_START_IND
BT_GAP_IO_CAPABILITY_REQ_IND
BT_GAP_IO_CAPABILITY_REQ_IND
bt_gap_reply_io_capability_request()
bt_gap_reply_io_capability_request()
Pairing
BT_GAP_USER_CONFIRM_REQ_IND
BT_GAP_USER_CONFIRM_REQ_IND
bt_gap_reply_user_confirm_request()
bt_gap_reply_user_confirm_request()
BT_GAP_LINK_KEY_NOTIFICATION_IND
BT_GAP_LINK_KEY_NOTIFICATION_IND
BT_GAP_BONDING_COMPLETE_IND
BT_GAP_BONDING_COMPLETE_IND
Messages
Function call
Figure 7. Bonding using numeric comparison message sequence
The passkey entry model is used when one device has input capability but does not have the capability to
display six digits and the other device has output capabilities, as shown in Figure 8.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 10 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
Master
GAP
Slave
GAP
Application
IO capability set to “keyboard only”
IO capability set to “display yes no”
bt_gap_get_link_key()
bt_gap_get_link_key()
BT_GAP_BONDING_START_IND
BT_GAP_BONDING_START_IND
BT_GAP_IO_CAPABILITY_REQ_IND
BT_GAP_IO_CAPABILITY_REQ_IND
bt_gap_reply_io_capability_request()
bt_gap_reply_io_capability_request()
Pairing
BT_GAP_USER_PASSKEY_NOTIFICATION_IND
BT_GAP_USER_REPLY_PASSKEY_IND
BT_GAP_USER_PASSKEY_NOTIFICATION_END_IND
bt_gap_reply_user_confirm_request()
BT_GAP_LINK_KEY_NOTIFICATION_IND
BT_GAP_LINK_KEY_NOTIFICATION_IND
BT_GAP_BONDING_COMPLETE_IND
BT_GAP_BONDING_COMPLETE_IND
Messages
Function call
Figure 8. Bonding using passkey entry message sequence
The pin code model is used when one of the devices doesn’t support SSP. The default pin code is “0000”,
this value can be modified by calling a user-defined API bt_gap_get_pin_code(), as shown in Figure 9.
Application
Master
GAP
Slave
GAP
Application
bt_gap_get_link_key()
bt_gap_get_link_key()
BT_GAP_BONDING_START_IND
BT_GAP_BONDING_START_IND
bt_gap_get_pin_code()
bt_gap_get_pin_code()
BT_GAP_LINK_KEY_NOTIFICATION_IND
BT_GAP_LINK_KEY_NOTIFICATION_IND
Pairing
BT_GAP_BONDING_COMPLETE_IND
Messages
BT_GAP_BONDING_COMPLETE_IND
Function call
Figure 9. Bonding using pin code message sequence
3.1.1.4.
Disconnect
The disconnect procedure terminates an existing ACL link, as shown in Figure 10.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 11 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
GAP
Application
GAP
bt_gap_disconnect()
BT_GAP_LINK_STATUS_UPDATED_IND
Messages
Disconnect
BT_GAP_LINK_STATUS_UPDATED_IND
Function call
Air transition
Figure 10. GAP disconnect message sequence
3.1.2.
Using the GAP APIs
This section describes how to use the GAP profile APIs. An example implementation is shown below.
1) Implement the required bt_app_event_callback() function to handle the GAP events, see section
3.1.2.1, “Full source code for bt_app_event_callback()”.
2) Implement the required user-defined API bt_gap_get_link_key() to provide the link key stored
during the last pairing procedure.
// The application may store the key in RAM, NVDM or permanent storage.
bt_gap_link_key_notification_ind_t edr_key;
void bt_gap_get_link_key(bt_gap_link_key_notification_ind_t*
key_information)
{
if (memcmp(key_information->address, edr_key.address, 6) == 0) {
memcpy(key_information, &edr_key,
sizeof(bt_gap_link_key_notification_ind_t));
} else {
// No link key, Do nothing
}
}
3) Implement the required user-defined API bt_gap_get_local_configuration() to provide the GAP
profile configuration.
static const bt_gap_config_t bt_config_default = {
.inquiry_mode = 2, // Inquiry result with RSSI format or Extended
Inquiry Result (EIR) format.
.io_capability = BT_GAP_IO_CAPABILITY_NO_INPUT_NO_OUTPUT,
.cod = 0x240404, // Audio device type.
.device_name = {"HB Duo device"},
};
// Define GAP configuration callback, it’s invoked when Bluetooth is
powered on.
const bt_gap_config_t* bt_gap_get_local_configuration(void)
{
return &bt_config_default; // Must return a global variable address.
}
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 12 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
4) Optional, implement the required user-defined API bt_gap_get_pin_code() to provide the pin code
(default value is “0000”).
// If local or remote device doesn't support SSP, the pin code pairing is
used.
// Default pin code is "0000", to replace it, implement the function
bt_gap_get_pin_code().
static const bt_gap_pin_code_information_t bt_gap_my_pin_code =
{
.pin_len = 4,
.pin_code = {"1234"},
};
const bt_gap_pin_code_information_t* bt_gap_get_pin_code(void)
{
return &bt_gap_my_pin_code; // Change the pin code from ”0000” to
"1234".
}
5) Call the function bt_gap_set_scan_mode() to set the device’s scan mode in order to let other devices
to discover it.
bt_gap_set_scan_mode(BT_GAP_MODE_GENERAL_ACCESSIBLE);
6)
Call the function bt_gap_inquiry() to set the device in the inquiry mode to discover the nearby
devices.
bt_gap_inquiry(10, 0);
7)
Call the function bt_gap_cancel_inquiry() to cancel and exit the inquiry mode.
bt_gap_cancel_inquiry();
8) After the link is established, call related bt_gap_get_remote_address() to get the address.
const bt_bd_addr_t* address = bt_gap_get_remote_address(link_handle);
9) Call the function bt_gap_read_remote_name() to get the name of the remote device.
const bt_bd_addr_t address = {0xF1,0x24,0x0,0x22,0x48,0xFe};
bt_gap_read_remote_name(&address);
10) Call the function bt_gap_disconnect() to disconnect the link.
bt_gap_disconnect(link_handle);
3.1.2.1.
Full source code for bt_app_event_callback()
void bt_app_event_callback(bt_msg_type_t msg, bt_status_t status, void
*buff)
{
switch (msg) {
case BT_GAP_INQUIRY_CNF:
{
if (status == BT_STATUS_SUCCESS) {
// Inquiry command executes successfully.
} else {
// Inquiry command failed.
}
break;
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 13 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
}
case BT_GAP_INQUIRY_IND:
{
// Find a nearby device.
bt_gap_inquiry_ind_t* device = (bt_gap_inquiry_ind_t*) buff;
// Handle the event, example connecting to the device.
break;
}
case BT_GAP_INQUIRY_COMPLETE_IND:
{
// Inquiry is complete.
break;
}
case BT_GAP_SET_SCAN_MODE_CNF:
{
if (status == BT_STATUS_SUCCESS) {
// bt_gap_set_scan_mode() executes successfully, it
should be found by nearby devices.
} else {
// Setting the scan mode has failed.
}
break;
}
case BT_GAP_LINK_STATUS_UPDATED_IND:
{
bt_gap_link_status_updated_ind_t* param =
(bt_gap_link_status_updated_ind_t*) buff;
// Handle link status update event.
if (param->link_status == BT_GAP_LINK_STATUS_DISCONNECTED) {
// The link is disconnected and it cannot re-connect in
this function callstack.
} elseif (param->link_status >=
BT_GAP_LINK_STATUS_CONNECTED_0) {
// The link is connected.
}
break;
}
case BT_GAP_BONDING_START_IND:
{
bt_gap_connection_handle_t* link_handle =
(bt_gap_connection_handle_t*) buff;
// link_handle is going to bond.
break;
}
case BT_GAP_IO_CAPABILITY_REQ_IND:
{
// This event will be received after BT_GAP_BONDING_START_IND
and both devices are support SSP.
bt_gap_connection_handle_t handle;
handle = (bt_gap_connection_handle_t)buff;
// Call bt_gap_reply_io_capability_request() to accept
bongding, or call bt_gap_reject_io_capability_request() to terminate
bonding.
break;
}
case BT_GAP_USER_CONFIRM_REQ_IND:
{
// This event will be received after
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 14 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
BT_GAP_IO_CAPABILITY_REQ_IND and IO Capability of both devices are
BT_GAP_IO_CAPABILITY_DISPLAY_YES_NO.
// Call bt_gap_reply_user_confirm_request(true) to accept
bongding, or call bt_gap_reply_user_confirm_request(false) to terminate
bonding.
break;
}
case BT_GAP_USER_PASSKEY_NOTIFICATION_IND:
{
// This event will be received after
BT_GAP_IO_CAPABILITY_REQ_IND, and local IO Capability is
BT_GAP_IO_CAPABILITY_DISPLAY_ONLY or BT_GAP_IO_CAPABILITY_DISPLAY_YES_NO
and remote IO Capability is BT_GAP_IO_CAPABILITY_KEYBOARD_ONLY
// User should display the passkey on the screen.
uint32_t* passkey = (uint32_t*) buff;
// Call GDI APIs to show the passkey.
break;
}
case BT_GAP_USER_PASSKEY_NOTIFICATION_END_IND:
{
// This event will be received after
BT_GAP_USER_PASSKEY_NOTIFICATION_IND.
// User should stop showing the passkey.
break;
}
case BT_GAP_USER_REPLY_PASSKEY_IND:
{
// This event will be received after
BT_GAP_IO_CAPABILITY_REQ_IND, and remote IO Capability is
BT_GAP_IO_CAPABILITY_DISPLAY_ONLY or BT_GAP_IO_CAPABILITY_DISPLAY_YES_NO
and local IO Capability is BT_GAP_IO_CAPABILITY_KEYBOARD_ONLY
// Call bt_gap_reply_passkey_request() to replay the passkey
before passkey timeout (25 seconds).
break;
}
case BT_GAP_LINK_KEY_NOTIFICATION_IND:
{
// This event will be received before
BT_GAP_BONDING_COMPLETE_IND and bonding success, or the old link key is
phased out.
bt_gap_link_key_notification_ind_t * key_info =
(bt_gap_link_key_notification_ind_t *) buff;
if (key_info->key_type == BT_GAP_LINK_KEY_TYPE_INVALID) {
// The old link key is phased out, delete it from
link key database.
} else {
// Save the new link key, and key_type to link key data
base.
}
break;
}
case BT_GAP_BONDING_COMPLETE_IND:
{
// Bonding is complete.
if (status == BT_STATUS_SUCCESS) {
// Bonding completed successfully.
} else {
// An error occurred.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 15 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
}
break;
}
default:
break;
}
}
3.2.
SDP
Service Discovery Protocol is used to locate the available services of the remote device and manage the local
available services, as shown in Figure 11.
Application
Function call
Host
Generic
Access
Profile
(GAP)
RFCOMM
Service Discovery Protocol
(SDP)
Event
Logical Link Control and
Adaptation Protocol (L2CAP)
Host-Controller Interface (HCI)
Link Layer (LL)
Physical Layer (PHY)
Controller
Figure 11. SDP abstraction layout
SDP is a client-server architecture shown in Figure 12. The client implementation is included in the profiles in the
Bluetooth stack and it’s not available to the user. On the other hand, the user can customize service records on the
server.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 16 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Client
Application
Server
Application
SDP requests
SDP Client
SDP responds
SDP Server
Figure 12. SDP client-server architecture
A service record in the SDP server contains a list of service attributes, as shown in Figure 13.
Service Record
Service Attribute 1
Service Attribute 2
Service Attribute 3
...
Service Attribute N
Figure 13. SDP service record
3.2.1.
The SDP message sequences
The SDP API headers can be found in the bt_sdp.h header file with only one interface API
bt_sdps_get_customized_record(). It’s mandatory to implement this function if any customized service
record needs to be discovered by a remote device.
The application on the remote device usually checks if the specific profile is supported on a peer device by sending
an SDP query before it connects. In this case, the SDP acts as a server and calls
bt_sdps_get_customized_record() from the Bluetooth stack to check if there is any customized record, as
shown in Figure 14.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 17 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
bt_*_connect()
Service/attribute
request
bt_sdps_get_customized_record()
Application
Profile
SDP server
Service/attribute
response
Event
Function call
Figure 14. SDP server role
3.2.2.
Add a customized record
Here is an example (see section 3.2.2.1, “Full source code to add a custom record”) to add a custom record that
contains the service name, language list, service class ID list and protocol description list for a sample profile. Add
your own record according to the SDP profile specification. For more information about the service attributes,
refer to the Bluetooth core specifications version 4.2 [VOL 3, part B, chapter 5]. More details about the API can be
found in the header file bt_sdp.h.
Details of an example are explained below.
Define a service name with a given length.
static const uint8_t bt_sample_service_name[] =
{
BT_SDP_TEXT_8BIT(7), // The string length of the service name.
'S', 'a', 'm', 'p', 'l', 'e','\0'
};
Define a sample language for the profile.
a)
In this example, each item is 3 bytes and the total length of the list items is 9 bytes.
b) The language is defined as "en". A language identifier represents natural language. Please refer to the
ISO 639:1988 (E/F): "Code for the representation of names of languages" and ISO 639 Codes (Names
of Languages).
c)
The encoding is defined as UTF-8, a character encoding identifier that can be found in IANA'S
database and the Character Sets.
d) Define a base attribute ID for the natural language in the service record.
static const uint8_t bt_sample_language_list[] =
{
BT_SDP_ATTRIBUTE_HEADER_8BIT(9),
BT_SDP_UINT_16BIT(0x656E),
BT_SDP_UINT_16BIT(0x006A),
BT_SDP_UINT_16BIT(0x0100)
};
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 18 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Define the service class ID. In this example, each item is 3 bytes and the total length of the following list
items is 6 bytes (see BT_SDP_ATTRIBUTE_HEADER_8BIT(6)).
static const uint8_t bt_sample_service_class_id_list[] =
{
BT_SDP_ATTRIBUTE_HEADER_8BIT(6),
BT_SDP_UUID_16BIT(BT_SDP_SERVICE_CLASS_HANDSFREE),
BT_SDP_UUID_16BIT(BT_SDP_SERVICE_CLASS_GENERIC_AUDIO)
};
Define the attribute header for a protocol RFCOMM.
static const uint8_t bt_sample_protocol_description_list[] =
{
BT_SDP_ATTRIBUTE_HEADER_8BIT(12), // The total length of all list items
is 12 bytes.
BT_SDP_ATTRIBUTE_HEADER_8BIT(3), // The total length of the following
list item is 3 bytes.
BT_SDP_UUID_16BIT(BT_SDP_PROTOCOL_L2CAP),
BT_SDP_ATTRIBUTE_HEADER_8BIT(5), // The total length of the following
two list items is 5 bytes.
BT_SDP_UUID_16BIT(BT_SDP_PROTOCOL_RFCOMM),
BT_SDP_UINT_8BIT(0x01)
};
Define the SDP protocol attributes.
In this example the service name must add a base attribute ID, default value is 0x0100 (see
BT_SDP_ATTRIBUTE(BT_SDP_ATTRIBUTE_ID_SERVICE_NAME+0x0100, bt_sample_service_name))
depending on your profile.
static const bt_sdps_attribute_t bt_sample_sdp_attributes[] =
{
BT_SDP_ATTRIBUTE(BT_SDP_ATTRIBUTE_ID_SERVICE_CLASS_ID_LIST,
bt_sample_service_class_id_list),
BT_SDP_ATTRIBUTE(BT_SDP_ATTRIBUTE_ID_PROTOCOL_DESC_LIST,
bt_sample_protocol_description_list),
BT_SDP_ATTRIBUTE(BT_SDP_ATTRIBUTE_ID_LANG_BASE_ID_LIST,
bt_sample_language_list),
BT_SDP_ATTRIBUTE(BT_SDP_ATTRIBUTE_ID_SERVICE_NAME+0x0100,
bt_sample_service_name)
};
Create an attribute list with records.
static const bt_sdps_record_t bt_sample_sdp_record =
{
.attribute_list_length = sizeof(bt_sample_sdp_attributes),
.attribute_list = bt_sample_sdp_attributes,
};
Define an SDP sample record.
static const bt_sdps_record_t *sdps_sample_record[]= {
&bt_sample_sdp_record,
};
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 19 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Get a customized record.
This API invoked by the SDK process should be implemented by the application. If no records to be found by the
remote device, set the record_list to NULL and return 0.
uint8_t bt_sdps_get_customized_record(const bt_sdps_record_t ***
record_list)
{
*record_list = &sdps_sample_record;
return sizeof(sdps_sample_record)/sizeof(bt_sdps_record_t*);
}
3.2.2.1.
Full source code to add a custom record
static const uint8_t bt_sample_service_name[] =
{
BT_SDP_TEXT_8BIT(7), // The string length of the service name.
'S', 'a', 'm', 'p', 'l', 'e','\0'
};
static const uint8_t bt_sample_language_list[] =
{
BT_SDP_ATTRIBUTE_HEADER_8BIT(9),
BT_SDP_UINT_16BIT(0x656E),
BT_SDP_UINT_16BIT(0x006A),
BT_SDP_UINT_16BIT(0x0100)
};
static const uint8_t bt_sample_service_class_id_list[] =
{
BT_SDP_ATTRIBUTE_HEADER_8BIT(6),
BT_SDP_UUID_16BIT(BT_SDP_SERVICE_CLASS_HANDSFREE),
BT_SDP_UUID_16BIT(BT_SDP_SERVICE_CLASS_GENERIC_AUDIO)
};
static const uint8_t bt_sample_protocol_description_list[] =
{
BT_SDP_ATTRIBUTE_HEADER_8BIT(12),
BT_SDP_ATTRIBUTE_HEADER_8BIT(3),
BT_SDP_UUID_16BIT(BT_SDP_PROTOCOL_L2CAP),
BT_SDP_ATTRIBUTE_HEADER_8BIT(5),
BT_SDP_UUID_16BIT(BT_SDP_PROTOCOL_RFCOMM),
BT_SDP_UINT_8BIT(0x01)
};
static const bt_sdps_attribute_t bt_sample_sdp_attributes[] =
{
BT_SDP_ATTRIBUTE(BT_SDP_ATTRIBUTE_ID_SERVICE_CLASS_ID_LIST,
bt_sample_service_class_id_list),
BT_SDP_ATTRIBUTE(BT_SDP_ATTRIBUTE_ID_PROTOCOL_DESC_LIST,
bt_sample_protocol_description_list),
BT_SDP_ATTRIBUTE(BT_SDP_ATTRIBUTE_ID_LANG_BASE_ID_LIST,
bt_sample_language_list),
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 20 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
BT_SDP_ATTRIBUTE(BT_SDP_ATTRIBUTE_ID_SERVICE_NAME+0x0100,
bt_sample_service_name)
};
static const bt_sdps_record_t bt_sample_sdp_record =
{
.attribute_list_length = sizeof(bt_sample_sdp_attributes),
.attribute_list = bt_sample_sdp_attributes,
};
static const bt_sdps_record_t *sdps_sample_record[]= {
&bt_sample_sdp_record,
};
uint8_t bt_sdps_get_customized_record(const bt_sdps_record_t ***
record_list)
{
*record_list = &sdps_sample_record;
return sizeof(sdps_sample_record)/sizeof(bt_sdps_record_t*);
}
3.3.
HFP
The profile defines details on how two devices supporting HFP interact on a point-to-point basis. An
implementation of the HFP typically enables a headset or an embedded hands-free unit to connect wirelessly to a
cellular phone for the purposes of acting as the cellular phone‘s audio input and output and allowing typical
telephony functions to be performed without access to the actual phone.
The following roles are defined for this profile:
•
Audio Gateway (AG) — a device that acts as input and output gateway of the audio. Typical devices acting
as AG are cellular phones.
•
Hands-Free unit (HF) — a device that acts as the AG’s remote audio input and output. It also provides
remote control capabilities.
Note: Only the HF role is supported in the LinkIt SDK v4.
Application
HFP
SDP
RFCOMM
L2CAP
Figure 15. HFP abstraction layout
The HFP depends on RFCOMM, which defines procedures required to send and receive files between two
Bluetooth-enabled devices. HFP APIs are called in the Application to implement the features related to the HFP.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 21 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
The HF is responsible for HFP connection management, audio connection management and call related action
handling.
3.3.1.
HFP message sequences
The HFP procedure can be established using the message sequence. The message sequence for each process is
described below.
•
Connection establishment
•
Connection release
•
Initiate an outgoing voice call
•
Audio connection setup
•
Audio connection release
•
Enable or disable the voice recognition
•
Incoming call actions
•
Three way call handling
•
Remote speaker volume control
•
Remote microphone volume control
•
Transmit DTMF codes
•
Remote speaker volume control
3.3.1.1.
Connection establishment
Apply this process to establish HFP connection between devices, as shown in Figure 16. The SDK provides two
different message sequences; either application driven or remote device driven. For more details, refer to the
header file bt_hfp.h.
bt_status_t status;
uint32_t hfp_handle;
status = bt_hfp_connect(&hfp_handle, bt_addr);
bt_status_t bt_app_event_callback(bt_msg_type_t msg, bt_status_t status,
void *buff)
{
switch (msg) {
case BT_HFP_SLC_CONNECTING_IND:
{
break;
}
case BT_HFP_SLC_CONNECTED_IND:
{
break;
}
}
return BT_STATUS_SUCCESS;
}
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 22 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Remote driven message sequence
Application driven message sequence
Application
HFP
HFP
Application
bt_hfp_connect()
BT_HFP_CONNECT_REQUEST_IND
BT_HFP_SLC_CONNECTING_IND
bt_hfp_connect_response()
BT_HFP_SLC_CONNECTED_IND
BT_HFP_SLC_CONNECTING_IND
BT_HFP_SLC_CONNECTED_IND
Messages
Function call
Figure 16. HFP connection establishment message sequence
3.3.1.2.
Connection release
Apply this procedure to release the HFP connection, as shown in Figure 17. The SDK provides two different
message sequences; either application driven or remote device driven. For more details, refer to the bt_hfp.h.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 23 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application driven message sequence
Application
HFP
Remote driven message sequence
HFP
Application
bt_hfp_disconnect()
BT_HFP_SLC_DISCONNECT_IND
BT_HFP_SLC_DISCONNECT_IND
Messages
Function call
Figure 17. HFP connection release message sequence
3.3.1.3.
Initiate an outgoing voice call
Apply this procedure to initiate an outgoing voice call from the HF. Application uses the API
bt_hfp_send_command() and passes the command “ATDnnn”, (where nnn is the phone number to dial) to
make an outgoing call, as shown in Figure 18. For more details, refer to the bt_hfp.h and HFP specification
version 1.6.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 24 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
HFP
HFP connection
bt_hfp_send_command()
BT_HFP_ACTION_CMD_CNF
BT_HFP_CIEV_CALL_SETUP_IND
BT_HFP_CIEV_CALL_IND
BT_HFP_AUDIO_CONNECT_IND
Messages
Function call
Procedure
Figure 18. Initiate an outgoing voice call message sequence
3.3.1.4.
Audio connection setup
Apply this procedure to create an SCO link, as shown in Figure 19. The SDK provides two different message
sequences; either application driven or remote device driven. The application driven message sequence uses the
API bt_hfp_audio_transfer() and passes the director parameter of "BT_HFP_AUDIO_TO_HF" to create
audio connection. For more details, refer to the bt_hfp.h and HFP specification version 1.6.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 25 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application driven message sequence
Application
Remote driven message sequence
HFP
HFP
Application
HFP connection
HFP connection
bt_hfp_audio_transfer()
BT_HFP_AUDIO_CONNECT_IND
BT_HFP_AUDIO_CONNECT_IND
Messages
Function call
Procedure
Figure 19. Audio connection setup message sequence
3.3.1.5.
Audio connection release
Apply this process to release the SCO link, as shown in Figure 20. The SDK provides two different message
sequences; either application driven or remote device driven. The application driven message sequence uses the
API bt_hfp_audio_transfer() and passes the director parameter of "BT_HFP_AUDIO_TO_AG" to release the
audio connection. For more details, refer to the bt_hfp.h and HFP specification version 1.6.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 26 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application driven message sequence
Application
Remote driven message sequence
HFP
HFP
Application
HFP audio connection
HFP audio connection
bt_hfp_audio_transfer()
BT_HFP_AUDIO_DISCONNECT_IND
BT_HFP_AUDIO_DISCONNECT_IND
Messages
Function call
Procedure
Figure 20. Audio connection release message sequence
3.3.1.6.
Enable or disable the voice recognition
Apply this process to enable or disable voice recognition, as shown in Figure 21. The SDK provides two different
message sequences; either application driven or remote device driven. The application driven message sequence
uses the API bt_hfp_send_command() and passes the command "AT+BVRA=1" or "AT+BVRA=0" to enable or
disable the voice recognition. For more details, refer to the bt_hfp.h and HFP specification version 1.6.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 27 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application driven message sequence
Application
Remote driven message sequence
Application
HFP
HFP
HFP connection
HFP connection
bt_hfp_send_command()
BT_HFP_VOICE_RECOGNITION_IND
BT_HFP_ACTION_CMD_CNF
BT_HFP_VOICE_RECOGNITION_IND
Messages
Function call
Procedure
Figure 21. Enable or disable the voice recognition message sequence
3.3.1.7.
Incoming call actions
Apply this procedure to accept or reject an incoming call, as shown in Figure 22. Application uses the API
bt_hfp_send_command() and passes the command "ATA" or "AT+CHUP" to accept or reject the incoming call.
For more details, refer to the bt_hfp.h and HFP specification version 1.6.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 28 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Accept call message sequence
Application
Reject call message sequence
HFP
Application
HFP
HFP connection
HFP connection
BT_HFP_CIEV_CALL_SETUP_IND
BT_HFP_CIEV_CALL_SETUP_IND
bt_hfp_send_command()
bt_hfp_send_command()
BT_HFP_ACTION_CMD_CNF
BT_HFP_ACTION_CMD_CNF
BT_HFP_CIEV_CALL_SETUP_IND
BT_HFP_CIEV_CALL_IND
Messages
BT_HFP_CIEV_CALL_SETUP_IND
Function call
Procedure
Figure 22. The actions of an incoming call message sequence
3.3.1.8.
Three way call handling
Apply this process to hold the call, as shown in Figure 23. The application calls bt_hfp_send_command() and
passes the command "AT+CHLD=0" or "AT+CHLD=1" or any other command to make the call hold actions. For
more details, refer to the bt_hfp.h and HFP specification version 1.6.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 29 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
HFP
HFP connection
Active a call
BT_HFP_CIEV_CALL_SETUP_IND
bt_hfp_send_command()
BT_HFP_ACTION_CMD_CNF
BT_HFP_CIEV_CALL_HELD_IND
Messages
Function call
Procedure
Figure 23. The three way call handling message sequence
3.3.1.9.
Remote speaker volume control
Apply this procedure to synchronize the speaker volume on a remote device, as shown in Figure 24. There are two
different message sequences; either application driven or remote device driven. The application driven message
sequence calls bt_hfp_send_command() and passes the command “AT+VGS=XX” (XX is the volume value to set)
to synchronize the speaker volume. For more details, refer to the bt_hfp.h and HFP specification version 1.6.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 30 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application driven message sequence
Application
Remote driven message sequence
Application
HFP
HFP connection
HFP
HFP connection
bt_hfp_send_command()
BT_HFP_VOLUME_SYNC_SPEAKER_GAIN_IND
BT_HFP_ACTION_CMD_CNF
BT_HFP_VOLUME_SYNC_SPEAKER_GAIN_IND
Messages
Function call
Procedure
Figure 24. The remote speaker volume control message sequence
3.3.1.10.
Remote microphone volume control
Apply this process to synchronize the microphone volume with a remote device, as shown in Figure 25. There are
two different message sequences; either application driven or remote device driven. The application driven
message sequence calls bt_hfp_send_command() and passes the command "AT+VGM=XX" (XX is the volume
value to set) to synchronize the microphone volume. For more details, refer to the bt_hfp.h and HFP
specification version 1.6.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 31 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application driven message sequence
Application
Remote driven message sequence
Application
HFP
HFP connection
HFP
HFP connection
bt_hfp_send_command()
BT_HFP_VOLUME_SYNC_MIC_GAIN_IND
BT_HFP_ACTION_CMD_CNF
BT_HFP_VOLUME_SYNC_MIC_GAIN_IND
Messages
Function call
Procedure
Figure 25. The remote microphone volume control message sequence
3.3.1.11.
Transmit DTMF codes
Apply this process to transmit DTMF codes through AG using the HDK, as shown in Figure 26. Application uses the
API bt_hfp_send_command() and passes the command "AT+VTS=X" (X is the DTMF code to send) to send the
DTMF code. For more details, refer to the bt_hfp.h and HFP specification version 1.6.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 32 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
HFP
HFP connection
Active a call
bt_hfp_send_command()
BT_HFP_ACTION_CMD_CNF
Messages
Function call
Procedure
Figure 26. Transmit DTMF codes message sequence
3.3.1.12.
Query a list of current calls
Apply this process to query the calls' detailed information, as shown in Figure 27. Application uses the API
bt_hfp_send_command() and passes the command "AT+CLCC" to fetch current calls’ detailed information. For
more details, refer to the bt_hfp.h andHFP specification version 1.6.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 33 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
HFP
HFP connection
bt_hfp_send_command()
BT_HFP_CURRENT_CALLS_IND
.
.
.
BT_HFP_CURRENT_CALLS_IND
BT_HFP_ACTION_CMD_CNF
Messages
Function call
Procedure
Figure 27. Query a list of current calls message sequence
3.3.2.
Using the HFP APIs
This section describes how to use the HFP APIs for an application development. The source code of the HFP API is
implemented in a binary library code but the headers can be found in bt_hfp.h.
To use the HFP APIs:
Implement the API bt_hfp_get_init_params(). This function is called when the HFP channel is
initialized and the HFP will create SLC connection with a remote device according to the initialization
parameters. If this function is not implemented or the API’s return value is not BT_STATUS_SUCCESS,
the HFP channel cannot be created.
bt_status_t bt_hfp_get_init_params(bt_hfp_init_params_t *param);
Implement the API bt_app_event_callback(). This function is called to provide notifications to the
application. If a remote device sent a connection request to the HDK, this function will be called with
event ID BT_HFP_CONNECT_REQUEST_IND, and the application should call
bt_hfp_connect_response() API to accept or reject the connection.
void bt_app_event_callback(bt_event_t event_id, const void *param);
•
Call bt_hfp_connect() to connect to a remote device, the return value is the connection result:
o
BT_STATUS_SUCCESS, the command is successfully sent.
o
BT_STATUS_FAIL, the connection request has failed.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 34 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
o
BT_STATUS_OUT_OF_MEMORY, the connection request has failed as there is not enough memory to
complete the operation. To solve the out of memory issue, refer to section 5.1.2, “Out of Memory
(OOM) ”.
o
If the connection is complete, the application will receive BT_HFP_SLC_CONNECTED_IND with the
connection result.
To send the HFP command to a remote device:
Connect the HFP to a remote device and wait until connection is established, get the event ID
BT_HFP_SLC_CONNECTED_IND.
Use the API bt_hfp_send_command() to send an HFP command to a remote device. The return value is
the result of sending a command.
a)
BT_STATUS_SUCCESS, the command is successfully sent.
b) BT_STATUS_FAIL, sending a command has failed.
c)
BT_STATUS_OUT_OF_MEMORY, sending a command has failed, as there is not enough memory to
complete the operation. To solve the out of memory issue, refer to section 5.1.2, “Out of Memory
(OOM) ”.
Application gets the event ID BT_HFP_ACTION_CMD_CNF to get the response from a remote device.
Call bt_hfp_disconnect() to disconnect from a remote device and then get the event
BT_HFP_DISCONNECT_IND with the disconnect result. If the remote device initiates the disconnection,
the application will directly get the event BT_HFP_DISCONNECT_IND result.
3.4.
A2DP
The A2DP provides protocols and procedures to implement distribution of high-quality audio content on ACL
channels. For more information about this profile, refer to the A2DP specification version 1.2.
According to the A2DP specification, there are two roles (Sink and Source) defined for smart devices. The Source
(SRC) acts as a digital audio streaming source that is delivered to the Sink (SNK) of the piconet. The SNK acts as a
sink of a digital audio streaming delivered from the SRC on the same piconet.
Note: Only SNK is supported on the LinkIt SDK v4.
Whichever role the device is configured for, there are certain states to operate on, as described in the state
machine diagram shown in Figure 28.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 35 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Connection Release
Connection Release
Suspend
Reconfiguration
IDLE
OPEN
STREAMING
Connection Establishment
Start Streaming
Figure 28. The A2DP state diagram
•
IDLE — the initial state where the A2DP is not connected with or A2DP is disconnected from a remote
device.
•
OPEN — the A2DP is connected with a remote device, but both devices are not ready for streaming.
•
STREAMING — both devices are ready for streaming.
The SDK supports two types of A2DP audio codecs, SBC and AAC. If Bluetooth is enabled and powered on, the
application is requested to configure the codec information with bt_a2dp_get_init_params().
The A2DP stack architecture layout is shown in Figure 29.
Application
A2DP
GAVDP
SDP
AVDTP
L2CAP
Figure 29. The A2DP abstraction layout
The A2DP depends on the Generic Audio/Video Distribution Profile (GAVDP), which defines procedures required to
set up an audio/video streaming. Compared to GAVDP, there are fewer procedures involved in the application, and
messages are simplified.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 36 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
3.4.1.
The A2DP message sequences
There are five operations available for the A2DP; connection establishment, connection release, start streaming,
suspend steaming and reconfiguration. The message sequence for each procedure is described in the following
sections.
3.4.1.1.
Connection establishment
Apply this process to establish a streaming connection with another device. The initial state of both devices is
IDLE, and it becomes Open after connection is established, as shown in Figure 30. The SDK provides two different
message sequences for application from a different initiator that initiates a signaling procedure. For more details,
refer to the bt_a2dp.h.
Application driven
Application
Remote device driven
A2DP
A2DP
Application
IDLE
IDLE
bt_a2dp_connect()
BT_A2DP_CONNECT_IND
bt_a2dp_connect_response()
BT_A2DP_CONNECT_CNF
BT_A2DP_CONNECT_CNF
OPEN
OPEN
Messages
Function call
Figure 30. The A2DP connection establishment message sequence
3.4.1.2.
Connection release
The A2DP connection is disconnected if a connection is released. It could be applied to OPEN and STREAMING
states. The current state is set to IDLE for both devices, as shown in Figure 31. The HDK can initiate A2DP
disconnection and accept the remote device’s request to release the connection. For more details, refer to the
bt_a2dp.h.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 37 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application driven
Application
Remote device driven
A2DP
A2DP
Application
OPEN or STREAMING
OPEN or STREAMING
bt_a2dp_disconnect()
BT_A2DP_DISCONNECT_IND
BT_A2DP_DISCONNECT_CNF
IDLE
IDLE
Messages
Function call
Figure 31. The A2DP connection release message sequence
3.4.1.3.
Start streaming
To start or resume the audio streaming, initiate start streaming to change the state from OPEN to STREAMING,
as shown in Figure 32. The device plays both acceptor and initiator role to accept the start streaming request and
initiate the streaming. For more details, refer to the bt_a2dp.h.
In the STREAMING state, the application interacts with audio module to open the codec configured previously
and send streaming data to audio or send SBC encoded data to the A2DP. For more details, see section 3.4.2,
“Interaction with audio”.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 38 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Figure 32. The A2DP start streaming message sequence
3.4.1.4.
Suspend streaming
Apply this process to suspend the audio streaming and change the state from STREAMING to OPEN, as shown in
Figure 33. In the meantime, the application notifies the audio module to close the codec and pause the audio so
that the audio resource is released. For more details, refer to the bt_a2dp.h.
The SRC initiates streaming suspend by a user initiated action or an internal event.
Figure 33. The A2DP suspend streaming message sequence
3.4.1.5.
Reconfiguration
Apply this process, if the codec information is changed for a special audio streaming at SRC, before the streaming is
sent to SNK. To process the reconfiguration, both devices should be in OPEN state. Execute suspend operation, if
the state is STREAMING and change the state to OPEN for both devices, as shown in Figure 34. For more details,
refer to the bt_a2dp.h.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 39 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
At the end of this process, the device’s state remains OPEN. Initiate Start streaming procedure to resume the
streaming see section 3.4.2, “Interaction with audio”.
Figure 34. The A2DP reconfiguration message sequence
You’ve now successfully processed the A2DP message sequences.
3.4.2.
Interaction with audio
To establish A2DP connection, both SRC and SNK devices need to negotiate and configure service parameters, such
as the media transport, and the A2DP audio codec. The media codec enables to encode or decode digital data
stream using Bluetooth protocol. The received data is decoded and passed through digital-to-analog converter
(DAC).
Once the A2DP connection is established and Start streaming procedure is executed, the SRC and SNK switch to
STREAMING state. At the SRC, the audio module encodes the raw audio data with a codec. This data is then
passed to the SNK using A2DP over Bluetooth. At the SNK, the received data passes through the audio module and
the raw data is decoded using the same codec. The A2DP audio codec must be opened before media data is
streaming, and be closed after suspended. There are four main operations during the interaction between A2DP
streaming and the audio codec; open codec, play, get data, close codec. For more details, refer to the
bt_codec.h.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 40 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
Audio
handle = bt_a2dp_open_codec()
Open codec
handle->set_buffer()
…
handle-> get_free_space()
Fill data
handle-> get_write_buffer()
handle-> write_data_done()
handle-> finish_write_data()
…
Play
handle-> play()
…
handle-> get_free_space()
Fill data
handle-> get_write_buffer()
handle-> write_data_done()
handle-> finish_write_data()
…
handle->stop()
Close codec
handle->reset_share_buffer ()
bt_a2dp_close_codec()
Function call
Figure 35. The A2DP codec operation message sequence (Sink)
3.4.2.1.
Open codec
Bluetooth parameters, such as callback function and codec related parameters must be sent to configure the
codec properties during open codec operation. If requested capability is available, a handle is returned and
functions to share the buffer are provided. The Get data function sets the A2DP codec driver after opening the
codec.
For A2DP sink operation, Bluetooth data is held before it is consumed. Codec driver fetches Bluetooth data with
get data function for decoding (see Figure 35).
For A2DP source operation, the audio data is encoded with encoder, wrapped with Bluetooth header and then
sent to the remote device (see Figure 36).
3.4.2.2.
Play and Get data
For A2DP sink, it’s recommended to keep enough Bluetooth data before playing the audio. The application will
provide a callback function to fetch the data. To start the Bluetooth audio, call the play function (see Figure 35).
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 41 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
For A2DP source, application will be notified to get audio data after codec play is called, and the function
get_payload_done() should be called after application gets and sends audio data.
Application
Open codec
Audio
handle = bt_a2dp_open_codec()
handle->set_buffer()
…
handle-> play()
Play
…
bt_codec_get_data_callback()
Get data
handle->get_payload_done()
…
handle->stop()
Close codec
bt_a2dp_close_codec()
Function call
Figure 36. The A2DP codec operation message sequence (Source)
3.4.2.3.
Stop and Close the codec
Apply this operation if the audio is close to an end or an error occurred during playback. If the Bluetooth audio link
is no longer needed, the codec can be closed (see Figure 35).
3.4.3.
Using the A2DP APIs
This section describes how to use the A2DP APIs in your application. The functionality of the A2DP APIs is
implemented in the library code but header functions can be found in bt_a2dp.h.
Implement bt_a2dp_get_init_params() to configure the codec information and role when the
Bluetooth is powered on by calling bt_gap_power_on().
bt_a2dp_codec_capability_t cap[2]; // Support 2 codec.
int32_t bt_a2dp_get_init_params(bt_a2dp_init_params_t* params) {
(A2DP SINK)
params->codec_number = 2;
// Fill supported audio codec capability in init_codec, and then pass
to params-> codec_list.
params->codec_list = &init_codec;
(A2DP SOURCE)
params->codec_number = 1;
// Fill supported audio codec capability in init_codec, and then pass
to params-> codec_list.
params->codec_list = &init_codec;
return Bluetooth_STATUS_A2DP_OK;
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 42 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
}
The application connects to a remote device by calling the bt_a2dp_connect() function, and then the
event BT_A2DP_CONNECT_CNF is expected to be received, as shown in
bt_app_event_callback(bt_msg_type_t msg_id, bt_status_t status, void *buff).
(A2DP
ret =
(A2DP
ret =
SINK)
bt_a2dp_connect(&a2dp_handle, address, BT_A2DP_SINK);
SOURCE)
bt_a2dp_connect(&a2dp_handle, address, BT_A2DP_SOURCE);
The HDK disconnects from a remote device using the following API and then the event
BT_A2DP_DISCONNECT_CNF is expected to be received, as shown in bt_app_event_callback
(bt_msg_type_t msg_id, bt_status_t status, void *buff).
bt_a2dp_disconnect(a2dp_handle);
(A2DP SINK and A2DP Media Payload)
•
A2DP SINK
Implement a utility function to hold the media data node and fetch data callback. If media data is received
from the A2DP SDK layer when playing music, the data node is needed to keep in a buffer and locate the
valid media data. Fetch data callback is called to fill the media data from data node in the buffer when the
codec driver starts decoding. Remember to release the data node if the media data is fully copied.
a)
Hold the media data node.
#define MEDIA_PKT_HEADER_LEN 12 // Media packet header 12 Bytes.
typedef struct _bt_media_packet_node{
_bt_media_packet_node *node;
uint16_t
packet_length;
uint16_t
offset;
} bt_media_packet_node_t;
void bt_a2dp_keep_media_data_node(bt_media_packet_node_t *data_node,
int16_t offset, int16_t total_len)
{
void* p_payload = data_node + offset + MEDIA_PKT_HEADER_LEN;
*payload_len = total_len – offset - MEDIA_PKT_HEADER_LEN;
// Search the payload start pointer for AAC.
if (g_a2dp_codec.type == BT_A2DP_CODEC_AAC) {
uint8_t payload_offset = 9;
uint8_t media_start_pos = 0;
do {
media_start_pos = ((uint8_t *) p_payload)[payload_offset];
payload_offset++;
} while (media_start_pos == 0xFF);
*payload_len -= payload_offset;
p_payload += payload_offset;
}
data_node->offset = p_payload – (void *)data_node;
data_node->packet_length = total_len;
// Insert the data_node at the end of data node buffer list.
bt_a2dp_hold_media_data_node(data_node);
}
b) Implement fetch data callback.
Fetch the data node from the data buffer list to data_node and copy the media data to dsp_buff. If the media
data length in data node is less than dsp_buff length, then
i)
Remove the data node from the list and release it;
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 43 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
ii)
Fetch the data node and copy again, till the buffer is empty or the dsp_buffer is full.
If the media length is larger than dsp_buff length, then
i)
Do not remove data_node before it’s filled with received data.
ii)
Modify the remaining media offset only.
int32_t bt_sink_codec_get_data_callback(volatile uint16_t *dsp_buff,
uint32_t len)
{
bt_media_packet_node_t *data_node = NULL;
int16_t media_len;
uint32_t filled_length;
// Fetch the bt media packet node and fill the received data in the
node to dsp_buffer.
// Note: The data should be filled in units of Word.
return filled_length;
}
•
A2DP SOURCE
Implement bt_app_event_callback() in your application.
bt_status_t bt_app_event_callback (bt_msg_type_t msg_id, bt_status_t
status, void *buff)
{
switch (msg_id) {
case BT_A2DP_START_STREAMING_IND: {
// Open a2dp codec according to the specified codec, and
then set the fetch data function callback for codec driver.
g_media_handle = bt_codec_a2dp_open(bt_audio_callback,
&a2dp_codec);
g_media_handle->
set_get_data_function(handle,bt_sink_codec_get_data_callback);
bt_a2dp_start_streaming_response(params->conn_id, true);
}
break;
case BT_A2DP_SUSPEND_STREAMING_IND: {
// Stop music, close codec.
g_media_handle->stop(g_media_handle);
bt_a2dp_close_codec(g_media_handle);
bt_a2dp_suspend_streaming_response(params->conn_id, true);
}
break;
case BT_A2DP_STREAMING_RECEIVED_IND: {
bt_a2dp_keep_media_data_node(params->data_node, params->
media_offset, params->total_length);
// Call g_media_handle->play(); if this is the streaming
data received first time after BT_A2DP_START_STREAMING_IND.
}
break;
}
}
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 44 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
3.5.
AVRCP
The AVRCP defines the features and procedures to ensure interoperability between Bluetooth devices with
audio/video control functions. For more information about this profile, refer to the AVRCP specification version
1.6.1.
In the AVRCP, there are two roles configured, controller (CT) and target (TG). The CT transmits AV/C (the AV/C
Digital Interface Command Set) command to a remote Bluetooth device (TG). Hence, the CT should initiate a
transaction by sending a command frame to a TG while the TG should receive a command frame and generate a
corresponding response frame.
AVRCP does not handle A/V streaming, to handle streaming, refer to the A2DP profile. Note, smartphone may not
support connect AVRCP without A2DP. It’s recommended to connect both profiles.
Application
AVRCP
SDP
AVCTP
L2CAP
Figure 37. The AVRCP abstraction layout
The packets between CT and TG are transported by the Audio/Video Control Transport Protocol (AVCTP), as shown
in Figure 37.
3.5.1.
3.5.1.1.
The AVRCP procedure and message sequences
Connection establishment
The AVRCP establishes an L2CAP connection for AVCTP channel that can be initiated by CT or TG. At the same time,
there should be only one AVCTP channel per ACL link. If the channel already exists, the new connections will be
rejected. This process is shown in Figure 38.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 45 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
CT initiated
TG initiated
Application
AVRCP(CT)
AVRCP(CT)
Application
BT_AVRCP_CONNECT_IND
bt_avrcp_connect()
bt_avrcp_connect_response()
BT_AVRCP_CONNECT_CNF
BT_AVRCP_CONNECT_CNF
Messages
Function call
Figure 38. AVRCP connection establishment
3.5.1.2.
Connection release
The CT or the TG can both initiate the process to release AVCTP connection. The process is shown in Figure 39.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 46 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
CT initiated
TG initiated
Application
AVRCP(CT)
AVRCP(CT)
Application
bt_avrcp_disconnect()
BT_AVRCP_DISCONNECT_IND
BT_AVRCP_DISCONNECT_IND
Messages
Function call
Figure 39. AVRCP connection release
3.5.1.3.
AV/C command procedure
The CT can send AV/C command once the connection is established. The process is shown in Figure 40. The AVRCP
supports two types of commands; PASS THROUGH and VENDOR DEPENDENT. Each command should receive a
response from TG. Only VENDOR DEPENDENT commands may receive an interim response. Note, the application
should only send one command and wait for its response. The AVRCP returns a busy status, if a command is sent
without waiting for the arrival of the previous command’s response.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 47 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
AVRCP(CT)
AVRCP(TG)
Application
AVRCP connection
AVRCP connection
AV/C command
AV/C command
AV/C interim response
AV/C interim response
AV/C response
AV/C response
Messages
Function call
Procedure
Figure 40. AV/C command procedure
3.5.2.
AV/C commands
This section specifies two types of commands: PASS THROUGH and VENDOR DEPENDENT. The library
libbt_avrcp.a provides only PASS THROUGH type of functions. To use VENDOR DEPENDENT type of commands,
include libbt_avrcp_enhence.a library in your application. VENDOR DEPENDENT commands are mainly used
for metadata transfer, for example, to get TG player application settings or metadata attributes.
3.5.2.1.
PASS THROUGH
The PASS THROUGH command is mainly used to transfer a user operation from CT device to a TG device. To send a
user operation from CT device, application can call bt_avrcp_send_pass_through_command() with operation
ID and state. The operation ID specifies the given operation and the state defines the operation key status (see
bt_avrcp.h). Since the TG may reject the PASS THROUGH command, application should check the response of
the command. On TG device, the application receives the event BT_AVRCP_PASS_THROUGH_COMMAND_IND with
operation ID and state from CT. Application should call bt_avrcp_send_pass_through_response()
immediately after receiving the event, to send a response to the CT device (accepted or rejected).
Note, when sending the key, the key status can be either push or release and the TG device may respond to either
one of them. It’s recommended that application tries both push and release when sending the PASS THROUGH
command.
3.5.2.2.
Player application settings
CT provides commands for application to query player application attribute settings and get and set attribute
values according to the attributes on the TG. All available settings on the TG are in pair.
That means each setting has a unique attribute ID and a corresponding value.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 48 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Note, the TG may accept the application attribute value setting commands sent from the CT, but it might not take
any action with the attribute values depending on the implementation of TG.
The related attributes and values are listed in Table 2. For more details, please refer to Appendix F of AVRCP
specification version 1.6.1.
Table 2. Player application settings and values
Attribute ID
BT_AVRCP_SETTING_ATTRIBUTE_EQUALIZER
Attribute
Description
Equalizer status
BT_AVRCP_ SETTING_ATTRIBUTE
_REPEAT_MODE
Repeat status
BT_AVRCP_ SETTING_ATTRIBUTE
_SHUFFLE_MODE
Shuffle status
BT_AVRCP_ SETTING_ATTRIBUTE
_SCAN_MODE
Scan status
3.5.2.3.
Supported
Value
0x01
0x02
0x01
0x02
0x03
0x04
0x01
0x02
0x03
0x01
0x02
0x03
Value Description
OFF
ON
OFF
Single track repeat
All tracks repeat
Group repeat
OFF
All tracks shuffle
Group shuffle
OFF
All tracks scan
Group Scan
Metadata attributes
CT enables access to metadata attributes for current media track by calling the Get Element attribute API. TG
responds back with attribute values when receiving a request from the CT.
The related media attributes are listed in Table 3. For more details, please refer to Appendix E of AVRCP
specification version 1.6.1.
Table 3. Media element attributes
Attribute ID
BT_AVRCP_MEDIA_ATTRIBUTE_TITLE
Value
0x01
Description
Title
BT_AVRCP_ MEDIA_ATTRIBUTE _ARTIST_NAME
0x02
Artist Name
BT_AVRCP_ MEDIA_ATTRIBUTE _ALBUM_NAME
0x03
Album Name
BT_AVRCP_ MEDIA_ATTRIBUTE _MEDIA_NUMBER
0x04
Current media number
BT_AVRCP_ MEDIA_ATTRIBUTE _TOTAL_MEDIA_NUMBER
0x05
Total number of media
BT_AVRCP_ MEDIA_ATTRIBUTE _GENRE
0x06
Genre category
BT_AVRCP_ MEDIA_ATTRIBUTE _PLAYING_TIME
0x07
Length of the audio file in
milliseconds
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 49 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
3.5.2.4.
Absolute volume
The absolute audio volume is applied to adjust the volume (in percentage) between CT and TG devices. The
application uses bt_avrcp_set_absolute_volume() to set TG volume from CT. Meanwhile, the application
should call an event notification function to register the absolute volume change at TG device.
The TG device should use bt_avrcp_send_set_absolute_volume_response() after receiving the event
BT_AVRCP_SET_ABSOLUTE_VOLUME_CNF. And also the event notification response API with absolute volume
change event if local volume in TG device changes.
Note, the AVRCP CT role is along with A2DP sink role, while TG is with A2DP source role. However, the CT role of
absolute volume is with A2DP source role, while TG is along with A2DP sink role.
3.5.2.5.
Event notification
CT enables the application to register for an event to detect whether the attribute value on TG has changed. CT
receives an interim response from TG to get the current value of the attribute. If the value has changed, the CT will
receive the final response from TG for the updated value. For CT device, the application should register for
additional events (see Table 4), after the last event receives an interim response. If the application needs to listen
to the same attribute repeatedly, it can register for the same event again after receiving the final response. For TG
device, the application should send an interim response with the current value for which the CT device is
registered. TG device should send the updated value to CT device anytime the value changes.
The related event IDs are listed in Table 4. For more details, please refer to Appendix H of the AVRCP specification
version 1.6.1.
Table 4. List of notification events
Event ID
BT_AVRCP_EVENT_PLAYBACK_STATUS_CHANGED
BT_AVRCP_EVENT_TRACK_CHANGED
Description
Change in the playback status of the current
track
Change of current track
BT_AVRCP_EVENT_TRACK_REACHED_END
Reached end of a track
BT_AVRCP_EVENT_TRACK_REACHED_START
Reached start of a track
BT_AVRCP_EVENT_PLAYBACK_POS_CHANGED
BT_AVRCP_EVENT_BATT_STATUS_CHANGED
Change in playback position. Return the
playback position after a specified playback
interval in seconds.
Change in the battery status
BT_AVRCP_EVENT_SYSTEM_STATUS_CHANGED
Change in the system status
BT_AVRCP_EVENT_PLAYER_APP_SETTING_CHANGED
Change in the player application setting
BT_AVRCP_EVENT_VOLUME_CHANGED
Change the absolute volume
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 50 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
3.5.2.6.
Continuation packets
All metadata transfers related to VENDOR DEPENDENT commands support continuation packets. That means CT
may receive more than one packet for a command to avoid sending large packets. Each response for these
commands has a packet type parameter, which indicates whether the packet is continuation.
On the CT device, application should continue calling bt_avrcp_request_continuing_response() to get
more packets until the data transfer is complete or call bt_avrcp_abort_continuing_response() to abort
this operation.
Note, TG does not allow CT to send another metadata transfer command while still receiving continuation packets.
3.5.2.7.
Get play status
CT provides commands to get the status of currently playing media. TG device responds with the corresponding
status when receiving a request from the CT.
3.5.2.8.
Get capabilities
CT provides commands to get the capabilities supported by TG device. There are two capabilities to query;
company and event supported. TG responds back with its capability.
3.5.3.
Using the AVRCP APIs
This section describes details on using the AVRCP APIs for application development. The AVRCP APIs are
implemented in the library code but header functions can be found in bt_avrcp.h.
1) Initiate a connection to a TG device. The BT_AVRCP_CONNECT_CNF event is sent to
bt_app_event_callback() to indicate the connection result.
bt_status_t bt_avrcp_connect(uint32_t *handle, const bt_bd_addr_t
*address);
2) Release a connection to a TG device. The BT_AVRCP_DISCONNECT_IND event is sent to
bt_app_event_callback().
bt_status_t bt_avrcp_disconnect(uint32_t *handle);
3) Send a pass through command to a TG device. Call this API after connection is established. The
BT_AVRCP_PASS_THROUGH_CNF event is sent to bt_app_event_callback() to indicate the result of
the command.
bt_status_t bt_avrcp_send_pass_through_command(
uint32_t handle,
bt_avrcp_operation_id_t op_id,
t_avrcp_operation_state_t op_state);
4) Respond the pass through to CT device. Call this API after receiving
BT_AVRCP_PASS_THROUGH_COMMAND_IND.
bt_status_t bt_avrcp_send_pass_through_response(
uint32_t handle,
bt_avrcp_response_t response,
bt_avrcp_operation_id_t op_id,
t_avrcp_operation_state_t op_state);
5) List player application setting attribute IDs of a TG device. Call this API after connection is established. The
BT_AVRCP_LIST_APP_SETTING_ATTRIBUTES_CNF event is sent to bt_app_event_callback() to
indicate the result of the command.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 51 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
bt_status_t bt_avrcp_list_app_setting_attributes(uint32_t handle);
6) Get player application setting attribute value for a specified value ID. Call this API after connection is
established. The BT_AVRCP_GET_APP_SETTING_VALUE_CNF event is sent to
bt_app_event_callback() to indicate the result of the command.
bt_status_t bt_avrcp_get_app_setting_value(
uint32_t handle,
uint16_t attribute_size,
bt_avrcp_get_app_setting_value_t *attribute_list);
7) Set player application setting attribute value for a specified value ID. Call this API after connection is
established. The BT_AVRCP_SET_APP_SETTING_VALUE_CNF event is sent to
bt_app_event_callback() to indicate the result of the command.
bt_status_t bt_avrcp_set_app_setting_value(
uint32_t handle,
uint16_t attribute_size,
bt_avrcp_app_setting_value_t *attribute_value_list);
8) Get metadata attribute of a TG device. Call this API after connection is established. The
BT_AVRCP_GET_ELEMENT_ATTRIBUTES_CNF event is sent to bt_app_event_callback() to
indicate the result of the command.
bt_status_t bt_avrcp_get_element_attributes(
uint32_t handle,
uint16_t attribute_size,
bt_avrcp_get_element_attributes_t *attribute_list);
9) Set absolute volume to a TG device. Call this API at volume change in CT device. The
BT_AVRCP_SET_ABSOLUTE_VOLUME_CNF event is sent to bt_app_event_callback() to indicate the
result of the command.
bt_status_t bt_avrcp_set_absolute_volume(
uint32_t handle,
uint8_t volume);
10) Send the set absolute volume to a CT device. Call this API after receiving
BT_AVRCP_SET_ABSOLUTE_VOLUME_COMMAND_IND.
bt_status_t bt_avrcp_set_absolute_volume_response(
uint32_t handle,
uint8_t volume);
11) Register a notification event of a TG device. Call this API after connection is established. The
BT_AVRCP_EVENT_NOTIFICATION_IND event is sent to bt_app_event_callback() to indicate the
result of the command.
bt_status_t bt_avrcp_register_notification(
uint32_t handle,
bt_avrcp_event_t event_id,
uint32_t play_back_interval);
12) Request a TG device to send next packet when received metadata response indicates the packet is not
complete. Call this API after connection is established and if the received packet is not the last one. The
corresponding metadata event is sent to bt_app_event_callback() to indicate the result of the
next packet.
bt_status_t bt_avrcp_request_continuing_response(
uint32_t handle,
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 52 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
bt_avrcp_pdu_id_t pdu_id);
13) Abort a TG device to send next packet when received metadata response indicates the packet is not
complete. Call this API after connection is established and if the received packet is not the last one. The
BT_AVRCP_ABORT_CONTINUING_CNF event is sent to bt_app_event_callback() to indicate the
result of the command.
bt_status_t bt_avrcp_abort_continuing_response(
uint32_t handle,
bt_avrcp_pdu_id_t pdu_id);
3.6.
PBAP
The PBAP defines the protocols and procedures to retrieve phonebook objects on smart devices. For more
information about this profile, refer to PBAP specification.
The following roles are defined for this profile:
•
PBAP Server (PBAPS) — provides the source phone book objects.
•
PBAP Client (PBAPC) — pulls the phone book objects.
Note: The term PBAPC is used in the rest of this document to designate the role of the PCE. Only PBAPC role is
supported in the SDK.
Application
PBAPC
OBEX
SDP
RFCOMM
L2CAP
Figure 41. PBAPC abstraction layout
The PBAPC depends on OBEX, as shown Figure 41. It defines procedures required to send and receive files
between two Bluetooth-enabled devices. Similar features are shared between these two profiles, such as connect,
get (download and browsing) and disconnect.
3.6.1.
3.6.1.1.
The PBAPC features and message sequences
PBAP connection
This feature establishes PBAP connection with or without authentication using PBAP Client as an initiator.
1) Establish connection without authentication.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 53 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
The message sequence is shown in Figure 42. For more details, see bt_pbapc.h.
Application
PBAPC
bt_pbapc_connect()
BT_PBAPC_CONNECT_CNF
Function call
Messages
Figure 42. PBAPC connection establishment without authentication message sequence
3.6.1.2.
Get phonebook objects
This feature is used to pull phonebook object’s content. The data is in vCard format and the attribute of vCard
depends on the PBAP Client’s request parameter, such as the version number of the vCard (2.1 or 3.0) or the offset
in the vCard. vCard 3.0 is used in LinkIt SDK v4.0.0 for RTOS. The message sequence is shown in Figure 43 . For
more details, see bt_pbapc.h.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 54 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
PBAPC
bt_pbapc_get_phonebook_objects()
BT_PBAPC_GET_PHONEBOOK_OBJECTS_IND
.
.
.
BT_PBAPC_GET_PHONEBOOK_OBJECTS_IND
BT_PBAPC_GET_PHONEBOOK_OBJECTS_CNF
Function call
Messages
Figure 43. PBAPC get phone book object message sequence
3.6.1.3.
Get the number of phonebook objects by PullPhonebook
This feature is used to obtain the number of phonebook objects of type “Missed Calls History” or “Main Phone
Book” from the PBAP Server by calling the PullPhonebook function after connection is established. For more
information about this feature, refer to PBAP specification. The message sequence is shown in Figure 44. For more
details, see bt_pbapc.h.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 55 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
PBAPC
bt_pbapc_get_num_of_phonebook_objects()
BT_PBAPC_GET_NUMBER_OF_PHONEBOOK_OBJECTS_IND
BT_PBAPC_GET_NUMBER_OF_PHONEBOOK_OBJECTS_CNF
Function call
Messages
Figure 44. PBAPC get the number of phonebook objects message sequence
3.6.1.4.
Get the caller name by number
This feature is used to get the caller name by number by calling the PullvCardListing function. First, get the
phonebook listing object from the PBAP Server. Then get the name field by parsing an XML file. The sequence is
shown in Figure 45. For more details, see bt_pbapc.h.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 56 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
PBAPC
Application
bt_pbapc_get_caller_name_by_number()
BT_PBAPC_GET_CALLER_NAME_IND
.
.
.
BT_PBAPC_GET_CALLER_NAME_IND
BT_PBAPC_GET_CALLER_NAME_CNF
Function call
Messages
Figure 45. PBAPC get caller name by number message sequence
3.6.1.5.
PullvCardEntry Function
This function is used to retrieve a specific vCard from the PBAP Server. The sequence is shown in Figure 46. For
more details, refer to bt_pbapc.h.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 57 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
PBAPC
bt_pbapc_pull_vcard_entry()
BT_PBAPC_GET_PHONEBOOK_OBJECTS_IND
.
.
.
BT_PBAPC_GET_PHONEBOOK_OBJECTS_IND
BT_PBAPC_GET_PHONEBOOK_OBJECTS_CNF
Function call
Messages
Figure 46. PBAPC PullvCardEntry message sequence
3.6.1.6.
Connection release
This feature disconnects the PBAPC connection (see Figure 47). For more details, refer to bt_pbapc.h.
Application
PBAPC
bt_pbapc_disconnect()
BT_PBAPC_DISCONNECT_IND
Function call
Messages
Figure 47. Disconnect message sequence
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 58 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
3.6.2.
Using the PBAPC APIs
This section describes the PBAPC API usage for your application development. The source code of the PBAPC APIs
is implemented in the library code but header functions can be found in bt_pbapc.h.
Initiate a connection to PBAP server from the PBAPC, call the APIs as follows:
a)
Call bt_pbapc_connect() API to send a connect request.
b) The application gets the event BT_PBAPC_CONNECT_CNF to indicate the connection request result.
Implement the bt_app_event_callback () API. The API is called for events to notify the application or
perform a task in this callback.
void bt_app_event_callback(bt_msg_type_t event_id, bt_status_t status,
const void *param);
Get the number of phonebook objects by calling the following function.
bt_status_t bt_pbapc_get_num_of_phonebook_objects(uint32_t handle,
bt_pbapc_phonebook_type_t type);
a)
The BT_PBAPC_GET_NUMBER_OF_PHONEBOOK_OBJECTS_IND event will notify application callback
function with the data including the number of phonebook objects received from the remote device.
b) The BT_PBAPC_GET_NUMBER_OF_PHONEBOOK_OBJECTS_CNF event will notify the application
callback function to indicate the result of the request.
Retrieve vCard objects from the remote device by calling the following function.
bt_status_t bt_pbapc_get_phonebook_objects(uint32_t handle, uint16_t
offset, bt_pbapc_phonebook_type_t type);
a)
The BT_PBAPC_GET_PHONEBOOK_OBJECTS_IND event will notify application callback function to
indicate there is data received from a remote device. It will include name field, name length, number
field and number length.
b) The BT_PBAPC_GET_PHONEBOOK_OBJECTS_CNF event will notify the application callback function
to indicate the result of the request.
Get caller name by number with the following function.
bt_status_t bt_pbapc_get_phonebook_objects(uint32_t handle,
uint8_t*number);
a)
The BT_PBAPC_GET_CALLER_NAME_IND event will notify application callback function to indicate there
is data received from the remote device, it will include name field, name length.
b) The BT_PBAPC_GET_CALLER_NAME_CNF event will notify the application callback function to indicate
the result of the request.
Pull the specific vCard with the following function.
bt_status_t bt_pbapc_pull_vcard_entry(uint32_t handle, uint8_t index);
a)
The BT_PBAPC_GET_PHONEBOOK_OBJECTS_IND event will notify application callback function to
indicate there is data received from a remote device, it will include name field, name length, number
field and number length.
b) The BT_PBAPC_GET_PHONEBOOK_OBJECTS_CNF event will notify the application callback function
to indicate the result of the request.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 59 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
To disconnect the current connection, call this function in the application.
bt_status_t bt_pbapc_disconnect(uint32_t handle);
a)
3.7.
The BT_PBAPC_DISCONNECT_IND event will notify the application callback function to indicate the
result of the request.
SPP
The SPP provides protocols and procedures for devices using Bluetooth for RS232 (or similar) serial cable
emulation.
The SPP defines two roles, SPP client (Device A) and SPP server (Device B).
•
SPP client — a device that takes the initiates connection with another device.
•
SPP server — a device that waits for another device to take the initiative to connect.
Application
SPP
SDP
RFCOMM
L2CAP
Figure 48. SPP abstraction layout
The SPP is dependent upon the RFCOMM and SDP, as shown in Figure 48. RFCOMM is the Bluetooth adaptation of
GSM TS 07.10, providing a transport protocol for serial port emulation. SDP is the Bluetooth Service Discovery
Protocol.
3.7.1.
The SPP message sequences
SPP enables the following functionality.
Connection establishment
Connection release
Data transfer
The message sequence for each procedure will be described in the upcoming sections.
3.7.1.1.
Connection establishment
According to the SPP specification, SPP connection is initiated by the SPP client. The SPP server must implement an
SDP record for an emulated serial port before the connection is initiated. For more details about SPP record
implementation, refer to bt_spp.h.
The connection establishment procedure between the SPP client and the SPP server is shown in Figure 49. For
more details, refer to bt_spp.h.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 60 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
Client
SPP
Application
Server
SPP
Implement the SDP
record of a SPP server
Disconnected
bt_spp_connect()
BT_SPP_CONNECT_IND
bt_spp_connect_response()
Connect
BT_SPP_CONNECT_CNF
BT_SPP_CONNECT_CNF
Connected
Messages
Function call
Figure 49. SPP connection establishment message sequence
3.7.1.2.
Connection release
The SPP connection release can be initiated by both the SPP client and the SPP server, as shown in Figure 50. More
details can be found in the header file bt_spp.h.
Application
Client
SPP
Application
Server
SPP
Connected
bt_spp_disconnect()
Disconnect
BT_SPP_DISCONNECT_IND
BT_SPP_DISCONNECT_IND
Disconnected
Messages
Function call
Figure 50. SPP connection release message sequence
3.7.1.3.
Data transfer
During the SPP connection, the application data can be transferred between the SPP server and the SPP client, as
shown in Figure 51. There is no order restriction, both the SPP server and the SPP client are able to initiate to send
and receive data. More details can be found in the header file bt_spp.h.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 61 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
Client
SPP
Application
Server
SPP
Connected
bt_spp_send()
BT_SPP_DATA_RECEIVED_IND
Data transfer
BT_SPP_READY_TO_SEND_IND
Messages
Function call
Figure 51. SPP data transfer message sequence
3.7.2.
Using the SPP APIs
This section describes how to use the SPP APIs for the application development. The source code of the SPP APIs is
implemented in the binary library code but the headers can be found in bt_spp.h.
The SDK supports client and server roles and all SPP APIs can be classified into three categories.
Common APIs
Server-specific APIs
Client-specific APIs
3.7.2.1.
Common APIs
Implement the API bt_app_event_callback(). All SPP events will be generated to trigger this
function to notify the application.
void bt_app_event_callback(bt_event_t event_id, const void *param);
Disconnect the SPP connection from the SPP server or client. The BT_SPP_DISCONNECT_IND event
notifies bt_app_event_callback() to indicate the result of the disconnection.
bt_status_t bt_spp_disconnect(uint32_t handle);
Application can send data to the remote device using the SPP connection.
bt_status_t bt_spp_send(
uint32_t handle,
uint8_t *packet,
uint16_t packet_length);
Application call hold the SPP data to the Bluetooth RX buffer if it is no free buffer to save the SPP data
from the BT_SPP_DATA_RECEIVED_IND.
void bt_spp_hold_data(uint8_t *data);
Call this function to release the data once it’s saved in the application.
void bt_spp_release_data(uint8_t *data);
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 62 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
3.7.2.2.
Server-specific APIs
Implement the API bt_sdps_get_customized_record() to provide the SPP record and record
number. More details can be found in the header file bt_sdp.h. More details about SPP record
implementation can be found in the header file bt_spp.h.
uint8_t bt_sdps_get_customized_record(const bt_sdps_record***
record_list);
If the BT_SPP_CONNECT_IND event is generated to trigger bt_app_event_callback(), that means
the remote SPP client has initiated a connection request to the SPP server. Then the SPP server can
respond (accept or reject) this connection request. Finally, the BT_SPP_CONNECT_CNF event is generated
to trigger bt_app_event_callback(). It then notifies the application with the result of this SPP
connection establishment.
bt_status_t bt_spp_connect_response(uint32_t handle, bool accept);
3.7.2.3.
Client-specific APIs
Initiate a connection to a remote SPP server using the SPP client. The BT_SPP_CONNECT_CNF event is generated
to trigger bt_app_event_callback(). Then it notifies the application with the result of this SPP connection
establishment.
bt_status_t bt_spp_connect(
uint32_t *handle,
const bt_bd_addr_t *address,
const uint8_t *uuid128);
3.8.
AWS
The Advanced Wireless Stereo (AWS) is MediaTek proprietary profile that defines the minimum set of functions
such that two devices can transfer audio data and synchronize the audio status.
The AWS has two roles (Sink and Source) defined for smart devices. The Source (SRC) acts as a digital audio
streaming source that is delivered to the Sink (SNK) of the piconet. The SNK acts as a sink of a digital audio
streaming delivered from the SRC on the same piconet.
The AWS stack architecture layout is shown in Figure 52.
Application
A2DP
AWS
L2CAP
Figure 52. The AWS abstraction layout
The AWS relies on the L2CAP, which defines procedures to transfer data..
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 63 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
3.8.1.
The AWS message sequences
There are five operations available for the AWS: connection establishment, connection release, start streaming,
suspend steaming and reconfiguration. The message sequence for each procedure is described in the following
sections.
3.8.1.1.
Connection establishment
Apply this process to establish a streaming connection with both devices, as shown in Figure 53.The SDK provides
two different message sequences, one for initiator (left) and another for acceptor (right). For more details, refer to
bt_aws.h.
Application
GAP
AWS
AWS
Application
bt_gap_inquiry()
BT_GAP_INQUERY_IND
bt_aws_connect()
BT_AWS_CONNECT_IND
bt_aws_connect_reponse()
BT_AWS_CONNECT_CNF
BT_AWS_CONNECT_CNF
BT_AWS_GET_A2DP_SNK_STATUS_IND
BT_AWS_GET_A2DP_SNK_STATUS_IND
Messages
Function call
Figure 53. The AWS connection establishment message sequence
3.8.1.2.
Connection release
Connection release procedure disconnects the AWS connection, as shown in Figure 31. Both devices can initiate
AWS disconnection and accept the remote device’s request to release the connection. For more details, refer to
bt_aws.h.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 64 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
AWS
AWS
Application
bt_aws_disconnect()
BT_AWS_DISCONNECT_IND
BT_AWS_DISCONNECT_IND
Messages
Function call
Figure 54. The AWS connection release message sequence
3.8.1.3.
Start streaming
The sequence to start or resume the audio streaming is shown in Figure 55. The AWS SRC device plays an acceptor
role that responds to an incoming request from the initiator, such as smartphone. The AWS SNK device plays an
acceptor role that responds to an incoming request from the AWS SRC. For more details, refer to bt_aws.h.
Once the streaming starts, the application interacts with audio module to open the codec configured previously
and send streaming data to audio module. For more details, see section 3.8.2, “Interaction with audio”.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 65 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
AWS Source
Application
A2DP
AWS Sink
AWS
AWS
Application
AWS Role Set
BT_A2DP_START_STREAMING_IND
bt_aws_start_streaming_request()
BT_AWS_START_STREAMING_IND
bt_aws_start_streaming_reponse()
BT_AWS_START_STREAMING_CNF
bt_a2dp_start_streaming_response()
A2DP_NOTIFY_STREAMING_RECEIVED
BT_AWS_STREAMING_RECEIVED_IND
BT_A2DP_STREAMING_RECEIVED_IND
Messages
Function call
Figure 55. The AWS start streaming message sequence
3.8.1.4.
Suspend streaming
The sequence to suspend the audio streaming is shown in Figure 56. In the meantime, the application notifies the
audio module to close the codec and pause the audio so that the audio resource is released. For more details, refer
to bt_aws.h.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 66 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
AWS Source
Application
AWS Sink
A2DP
AWS
AWS
Application
AWS Streaming
BT_A2DP_START_SUSPEND_IND
bt_aws_suspend_streaming_request()
BT_AWS_SUSPEND_STREAMING_IND
bt_aws_suspend_streaming_reponse()
BT_AWS_SUSPEND_STREAMING_CNF
bt_a2dp_suspend_streaming_response()
Messages
Function call
Figure 56. The AWS suspend streaming message sequence
3.8.2.
Interaction with audio
To play the audio, both SRC and SNK devices need to negotiate and configure the A2DP audio codec. The audio
codec type is the same as for A2DP streaming. The application needs to handle the AWS audio packet with audio
manager.
3.8.2.1.
Open and close the codec
The format of the AWS streaming data is the same as for A2DP. To learn more on how to open and close the codec,
refer to section 3.4.2, “Interaction with audio”.
3.8.2.2.
Synchronize the voice
In order to synchronize the voice between two AWS devices, it’s recommended to buffer enough audio data and
set a delay play time before playing the audio. The AWS provides a notification ID
BT_AWS_NOTIFY_ID_READY_TO_PLAY to calculate how long the AWS SNK needs to start playing the music (see
Figure 57).
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 67 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
AWS Source
Application
Audio
AWS Sink
A2DP
AWS
AWS
Audio
Application
AWS Streaming
A2DP_NOTIFY_STREAMING_RECEIVED
BT_AWS_STREAMING_RECEIVED_IND
.
.
.
.
.
.
BT_AWS_STREAMING_RECEIVED_IND
.
.
.
A2DP_NOTIFY_STREAMING_RECEIVED
BT_AWS_STREAMING_RECEIVED_IND
BT_AWS_STREAMING_RECEIVED_IND
bt_aws_notify()
BT_AWS_NOTIFY_IND
Start Timer
with T1
Start Timer
with T2
Play the music
Play the music
Messages
Function call
Figure 57. The AWS voice message synchronization sequence
3.8.3.
Using the AWS APIs
This section describes how to use the AWS APIs in your application. The functionality of the AWS APIs is
implemented in the library code but header functions can be found in bt_aws.h.
1) Call the bt_aws_connect() function to connect to a remote device and then expect to receive the
event BT_AWS_CONNECT_CNF, as shown in bt_app_event_callback(bt_msg_type_t msg_id,
bt_status_t status, void *buff).
ret = bt_aws_connect(&aws_handle, address);
2) Call the following API to disconnect from a remote device and then expect to receive the event
BT_AWS_DISCONNECT_IND, as shown in bt_app_event_callback(bt_msg_type_t msg_id,
bt_status_t status, void *buff).
bt_aws_disconnect(aws_handle);
3) Both of the AWS devices need to play the first packet at the same time. The SRC needs to pass the current
Bluetooth clock and play time to SNK and start a timer to play. The SNK needs to start a timer to play after
receiving the notification ID BT_AWS_NOTIFY_ID_READY_TO_PLAY.
//Device SRC
//get current bt clock.
bt_aws_get_bt_local_time(&sink_loc_play_nclk, &sink_loc_play_nclk_intra);
aws_notify.op_id = BT_AWS_NOTIFY_ID_READY_TO_PLAY;
aws_notify.play_time.play_time = time_dur;
aws_notify.play_time.loc_play_nclk = sink_loc_play_nclk;
aws_notify.play_time.loc_play_nclk_intra = sink_loc_play_nclk_intra;
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 68 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
//notify remote device ready to play
err = bt_aws_notify(aws_dev->aws_hd, &aws_notify);
//start timer to wait to play
hal_gpt_start_timer_us(cntx->gpt_port, time_dur,
HAL_GPT_TIMER_TYPE_ONE_SHOT);
//play the music when the time is up.
//-----------------------------------------------------------------------// Device SNK
// after receiving the notify ID BT_AWS_NOTIFY_ID_READY_TO_PLAY, start a
timer to play the music.
time_dur = notify_ind->param->play_time.play_time;
hal_gpt_register_callback(cntx->gpt_port,
bt_sink_srv_aws_gpt_cb, (void *)dev);
gpt_ret = hal_gpt_start_timer_us(cntx->gpt_port, time_dur,
HAL_GPT_TIMER_TYPE_ONE_SHOT);
//play the music when the time is up
4) The application needs to implement a utility function to hold the media data node and fetch data callback.
If media data is received from the A2DP or AWS, the data node serves as a buffer to store the received
data to later identify and locate it. Fetch data callback is called to fill the media data from data node in a
buffer when the codec driver starts decoding. Remember to release the data node if the media data is
fully copied.
a)
Hold the media data node.
#define MEDIA_PKT_HEADER_LEN 12 // Media packet header 12 Bytes.
typedef struct _bt_media_packet_node{
_bt_media_packet_node *node;
uint16_t
packet_length;
uint16_t
offset;
} bt_media_packet_node_t;
void bt_a2dp_keep_media_data_node(bt_media_packet_node_t *data_node,
int16_t offset, int16_t total_len)
{
void* p_payload = data_node + offset + MEDIA_PKT_HEADER_LEN;
*payload_len = total_len – offset - MEDIA_PKT_HEADER_LEN;
// Search the payload start pointer for AAC.
if (g_a2dp_codec.type == BT_A2DP_CODEC_AAC) {
uint8_t payload_offset = 9;
uint8_t media_start_pos = 0;
do {
media_start_pos = ((uint8_t *) p_payload)[payload_offset];
payload_offset++;
} while (media_start_pos == 0xFF);
*payload_len -= payload_offset;
p_payload += payload_offset;
}
data_node->offset = p_payload – (void *)data_node;
data_node->packet_length = total_len;
// Insert the data_node at the end of data node buffer list.
bt_a2dp_hold_media_data_node(data_node);
}
b) Implement fetch data callback.
Fetch the data node from data buffer list to data_node and copy the media data to dsp_buff. If the media data
length in data node is less than dsp_buff length, then
i)
Remove the data node from the list and release it;
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 69 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
ii)
Fetch the data node and copy again, until the buffer is empty or the dsp_buffer is full.
If the media length is more than dsp_buff length, then
iii) Do not remove data_node before it’s filled with received data.
iv) Modify the remaining media offset only.
int32_t bt_sink_codec_get_data_callback(volatile uint16_t *dsp_buff,
uint32_t len)
{
bt_media_packet_node_t *data_node = NULL;
int16_t media_len;
uint32_t filled_length;
// Fetch the bt media packet node and fill the received data in the
node to dsp_buffer.
// Note: The data should be filled in units of Word.
return filled_length;
}
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 70 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
4.
The Bluetooth Low Energy Protocol or Profiles
The addition to the LinkIt SDK for Bluetooth support is provided as a collection of binary library files. This section
provides details on the GAP, SM and GATT profiles.
4.1.
GAP
The Bluetooth LE GAP is responsible for connection and device management, including device configuration,
device discovery, and connection establishment and termination, as shown in Figure 15.
Idle
Standby
Device Discovery
Advertiser
Scanner
Connection
Peripheral
Central
Figure 58. GAP state diagram
•
Standby — initial idle state when the Bluetooth powers on.
•
Advertiser — the device is advertising with specific data to provide information to nearby devices about
the advertiser, including the device address, advertising type and advertising data.
•
Scanner — the device searches for nearby devices, based on the type of scanning and advertisement, it
may send a scan request to the advertiser. The scanner can get more information in the scan response
from the advertiser. Once the discovery is complete, the scanner can initiate a connection or not with the
advertiser based on the advertising type.
•
Peripheral/Central — once the scanner initiates a connection to the advertiser, the advertiser device
will function as a peripheral device and the scanner device will be a central device.
The application and profiles can directly invoke Bluetooth LE GAP API functions to perform Bluetooth LE related
functions, such as scan or connect, as shown in Figure 59. More details can be found in the header file
bt_gap_le.h.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 71 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
Host
Generic Access Profile
(GAP)
Host-Controller Interface (HCI)
Function call
Link Layer (LL)
Physical Layer (PHY)
Controller
Figure 59. GAP abstraction layout
4.1.1.
Power on
Call the bt_power_on() function in the main() function to enable the Bluetooth. The BT_POWER_ON_CNF event
is received after successful completion, as shown in Figure 16. More details can be found in the header file
bt_system.h.
bt_status_t bt_app_event_callback(bt_msg_type_t msg, bt_status_t status,
void *buff)
{
switch (msg) {
case BT_POWER_ON_CNF:
{
break;
}
}
return BT_STATUS_SUCCESS;
}
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 72 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
GAP
bt_power_on()
BT_POWER_ON_CNF
Event
Function call
Figure 60. Powering on the Bluetooth message sequence
4.1.2.
Start advertising
Start advertising to enable device discovery and connectivity, as shown below.
void app_fun(void)
{
bt_hci_cmd_le_set_advertising_enable_t adv_enable = {
.advertising_enable = BT_HCI_ENABLE,
};
bt_hci_cmd_le_set_advertising_parameters_t adv_para = {
.advertising_interval_min = 0x0800,
.advertising_interval_max = 0x0800,
.advertising_type = BT_HCI_ADV_TYPE_CONNECTABLE_UNDIRECTED,
.advertising_channel_map = 7,
.advertising_filter_policy = 0
};
bt_hci_cmd_le_set_advertising_data_t adv_data = {0};
char dev_name[] = ”My Device”;
adv_data.advertising_data_length = strlen(dev_name) + 2;
adv_data.advertising_data[0] = strlen(dev_name) + 1;
adv_data.advertising_data[1] = BT_GAP_LE_AD_TYPE_NAME_COMPLETE;
memcpy(adv_data.advertising_data + 2, dev_name, strlen(dev_name));
bt_gap_le_set_advertising(&adv_enable, &adv_para, &adv_data, NULL);
return;
}
4.1.2.1.
Advertising and scan response data format
The format of advertising data can be found in the Bluetooth Core Specifications version 4.2 [VOL 3, Part C, 11],
Bluetooth GAP and in the Specification of the Bluetooth system.
4.1.3.
Searching the nearby devices
The device scans for the nearby devices, as shown in Figure 61 and Figure 62. More details can be found in the
header file bt_gap_le.h.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 73 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
GAP
GAP
Application
bt_gap_le_set_scan()
bt_gap_le_set_advertising()
BT_GAP_LE_SET_SCAN_CNF
BT_GAP_LE_SET_ADVERTISING_CNF
Advertising
BT_GAP_LE_ADVERTISING_REPORT_IND
Scan request
Scan response
BT_GAP_LE_ADVERTISING_REPORT_IND
Event
Function call
Air transition
Figure 61. GAP active scan message sequence
GAP
GAP
Application
Application
bt_gap_le_set_scan()
bt_gap_le_set_advertising()
BT_GAP_LE_SET_SCAN_CNF
BT_GAP_LE_SET_ADVERTISING_CNF
Advertising
BT_GAP_LE_ADVERTISING_REPORT_IND
Event
Function call
Air transition
Figure 62. GAP passive scan message sequence
An example code to provide GAP active scan (see Figure 61) is shown below:
void app_fun(void)
{
bt_hci_cmd_le_set_scan_parameters_t scan_params;
//Set scan parameters.
scan_params.le_scan_type = BT_HCI_SCAN_TYPE_PASSIVE;
scan_params.own_address_type = BT_HCI_SCAN_ADDR_PUBLIC;
scan_params.le_scan_interval = 0x0024;
scan_params.le_scan_window = 0x0011;
scan_params.scanning_filter_policy = 0x00;
bt_hci_cmd_le_set_scan_enable_t enalbe;
enable.le_scan_enable = BT_HCI_ENABLE;
enable.filter_duplicates = BT_HCI_ENABLE;
//Start the scanner.
bt_gap_set_scan(&enable, ¶m);
}
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 74 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
bt_status_t bt_app_event_callback(bt_msg_type_t msg, bt_status_t status,
void *buff)
{
switch (msg) {
case BT_GAP_LE_ADVERTISING_REPORT_IND:
{
const bt_gap_le_advertising_report_ind_t *report =
(bt_gap_le_advertising_report_ind_t *)buff;
// Log advertising report information.
}
}
return BT_STATUS_SUCCESS;
}
4.1.4.
Connecting
There are two ways to create a Bluetooth LE connection, a general connection and auto connection.
1) General connection. It enables the host to establish a connection with a specified device, as shown in
Figure 63. More details can be found in the header file bt_gap_le.h.
Peripheral device
Central device
Application
GAP
GAP
Application
Advertising
bt_gap_le_connect()
BT_GAP_LE_CONNECT_CNF
Connection request
Accept
BT_GAP_LE_CONNECT_IND
Event
BT_GAP_LE_CONNECT_IND
Function call
Air transition
Figure 63. GAP general connection message sequence
An example code to provide general connection (see Figure 63) is shown below.
void app_fun(void)
{
bt_hci_cmd_le_create_connection_t conn_params;
uint8_t addr[6] = {0xC0, 0x74, 0x3A, 0x2A, 0x09, 0xFF};
//Set connection parameters.
conn_params.le_scan_interval = 0x0060;
conn_params.le_scan_window = 0x0030;
conn_params.initiator_filter_policy =
BT_HCI_CONN_FILTER_ASSIGNED_ADDRESS;
conn_params.peer_address.type = 0x00;
memcpy(conn_params.peer_address.addr, addr,sizeof(addr));
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 75 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
conn_params.own_address_type = BT_ADDR_RANDOM;
conn_params.conn_interval_min = 0x0018;
conn_params.conn_interval_max = 0x0028;
conn_params.conn_latency = 0x0000;
conn_params.supervision_timeout = 0x0C80;
conn_params.minimum_ce_length = 0x0060;
conn_params.maximum_ce_length = 0x0140;
//Start connecting.
bt_gap_le_connect(&conn_params);
return;
}
2) Auto-connection. It enables the host to configure the controller to establish a connection automatically
with one or more devices. A white list in the controller stores device addresses. The controller
automatically establishes a connection with devices in the white list, as shown in Figure 64. More details
can be found in the header file bt_gap_le.h.
Peripheral device
Central device
Application
GAP
GAP
Application
Advertising
bt_gap_le_set_white_list()
BT_GAP_LE_SET_WHITE_LIST_CNF
bt_gap_le_connect()
BT_GAP_LE_CONNECT_CNF
Connection request
Accept
BT_GAP_LE_CONNECT_IND
BT_GAP_LE_CONNECT_IND
Event
Function call
Air transition
Figure 64. GAP auto connection message sequence
void app_fun(void)
{
uint8_t addr[6] = {0xC0, 0x74, 0x3A, 0x2A, 0x09, 0xFF};
bt_addr_t device;
device.type = 0x00;
memcpy(device.addr, addr, sizeof(addr));
//Add the device to the white list
bt_gap_le_set_white_list(BT_GAP_LE_ADD_TO_WHITE_LIST, &device);
return;
}
bt_status_t bt_app_event_callback(bt_msg_type_t msg, bt_status_t status,
void *buff)
{
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 76 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
switch (msg) {
case BT_GAP_LE_ADVERTISING_REPORT_IND:
{
bt_hci_cmd_le_create_connection_t conn_params;
//Set connection parameters.
conn_params.le_scan_interval = 0x0060;
conn_params.le_scan_window = 0x0030;
conn_params.initiator_filter_policy =
BT_HCI_CONN_FILTER_WHITE_LIST_ONLY;
conn_params.own_address_type = BT_ADDR_RANDOM;
conn_params.conn_interval_min = 0x0018;
conn_params.conn_interval_max = 0x0028;
conn_params.conn_latency = 0x0000;
conn_params.supervision_timeout = 0x0C80;
conn_params.minimum_ce_length = 0x0060;
conn_params.maximum_ce_length = 0x0140;
//Start connecting.
bt_gap_le_connect(&conn_params);
break;
}
}
return BT_STATUS_SUCCESS;
}
Calling the bt_gap_le_connect() function again, while the GAP is connecting, will result in failure
(BT_STATUS_FAIL). In this case, the application should call bt_gap_le_cancel_connection() to cancel the
connection and then call bt_gap_le_connect() to re-connect.
BT_GAP_LE_CONNECT_IND event is received, when connecting or being connected successfully.
bt_status_t bt_app_event_callback(bt_msg_type_t msg, bt_status_t status,
void *buff)
{
switch (msg) {
case BT_GAP_LE_CONNECT_IND:
{
bt_gap_le_connect_ind_t *event;
event = (bt_gap_le_connect_ind_t *)buff;
//Handle connected event.
break;
}
}
return;
}
4.1.4.1.
Connection parameters
The connection parameters in this section affect the power consumption and performance. They are sent by the
central device with the connection request and can be modified by a peripheral device, once the connection is
established.
1) Connection Interval. During the connection interval, the two devices send and receive data only in
Bluetooth LE connection state. If there is no data to send, the two devices will still keep sending link layer
data to notify the peer device that it is still alive. The current increases if there is data to send in the
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 77 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
connection event, as shown in Figure 65. The range of connection interval is from 7.5ms to 4s. The larger
the connection interval, the lower the power consumption and the throughput are. The ideal throughput
(conn_interval/0.625ms−3)slot ∗ 23 bytes/1.1slot
, where 23 bytes are useful bytes in the PDU. Three
is defined as
conn_interval
slots deducted in the expression are reserved in each connection interval and 23 bytes per 1.1 slot is the
maximum BLE baseband capacity for Bluetooth 4.1.
More details can be found in the header file bt_hci_le.h.
Current [mA]
Connection Interval
Connection Event
Time [s]
Figure 65. Connection interval and event
2) Connection Latency. Enables the peripheral device to skip a number of connection events. If the
peripheral device has no data to send. It can skip no more than connection latency of connection events
𝑐𝑐𝑐𝑐𝑐𝑐𝑐𝑐_𝑡𝑡𝑡𝑡𝑡𝑡𝑡𝑡𝑡𝑡𝑡𝑡𝑡𝑡
and stay asleep, as shown in Figure 66. The range of connection latency is from 0 to
− 1.
2∗𝑐𝑐𝑐𝑐𝑐𝑐𝑐𝑐_𝑖𝑖𝑖𝑖𝑖𝑖𝑖𝑖𝑖𝑖𝑖𝑖𝑖𝑖𝑖𝑖
The value of the latency should be less than 311.875ms.
More details can be found in the header file bt_hci_le.h.
Central data
Peripheral data
Latency = 0
Time [s]
Connection Interval
Skipped
Latency > 0
Time [s]
Figure 66. Slave latency
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 78 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
3) Connection Timeout. A connection might fail with an error code of -0x08 due to not getting connection
event data from the peer device before the connection times out. The range of the connection timeout is
from 100ms to 32s. It defines the maximum time between two received connection data events before
the connection is considered as failed, as shown in Figure 67.
More details can be found in the header file bt_hci_le.h.
Report link disconnected
with error code(-0x08)
Time [s]
conn_timeout
Figure 67. Connection timeout error occurred (error code -0x08)
If the master fails to receive six continuous packet data units (PDU) after the connection is created, the connection
is considered lost. This enables fast termination of connections that fail to establish, as shown in Figure 68.
Report link disconnected
with error code(-0x3E)
Link created point
Lost 6 continuous connection events from the slave
Time [s]
Figure 68. Connection timeout error occurred (error code -0x3E)
4.1.5.
Resolvable private address resolution
This feature makes it more difficult for an attacker to track a device over a certain period of time. The user should
enable address resolution and add the device to the resolving list in the controller.
4.1.5.1.
Enable address resolution
Call the function bt_gap_le_set_address_resolution_enable() to enable the resolution of the resolvable
private addresses in the controller.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 79 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
4.1.5.2.
Set resolvable private address timeout
Call the function bt_gap_le_set_resolvable_private_address_timeout() to set the resolvable private
address timeout in the controller. The controller will generate a new resolvable private address and use it at
timeout.
4.1.5.3.
Set resolving list
Call the function bt_gap_le_set_resolving_list() to add a device identity to the resolving list, remove a
device identity from the resolving list or clear the resolving list. The device identity contains the peer’s identity
address and local and peer’s IRK pair.
bt_status_t app_add_dev_to_resolving_list(const bt_gap_le_bonding_info_t
*bonded_info)
{
bt_status_t st = BT_STATUS_SUCCESS;
if (BT_ADDR_TYPE_UNKNOW != bonded_info->identity_addr.address.type) {
bt_hci_cmd_le_add_device_to_resolving_list_t dev;
dev.peer_identity_address = bonded_info->identity_addr.address;
memcpy(dev.peer_irk, &(bonded_info->identity_info),
sizeof(dev.peer_irk));
memcpy(dev.local_irk, &(local_key_req.identity_info),
sizeof(dev.local_irk));
st =
bt_gap_le_set_resolving_list(BT_GAP_LE_ADD_TO_RESOLVING_LIST,
(void*)&dev);
}
return st;
}
bt_status_t app_delete_dev_from_resolving_list(const
bt_gap_le_bonding_info_t *bonded_info)
{
bt_status_t st = BT_STATUS_SUCCESS;
if (BT_ADDR_TYPE_UNKNOW != bonded_info->identity_addr.address.type) {
bt_hci_cmd_le_remove_device_from_resolving_list_t dev;
dev.peer_identity_address = bonded_info->identity_addr.address;
st =
bt_gap_le_set_resolving_list(BT_GAP_LE_REMOVE_FROM_RESOLVING_LIST,
(void*)&dev);
}
return st;
}
bt_status_t app_clear_resolving_list()
{
bt_status_t st = BT_STATUS_SUCCESS;
st = bt_gap_le_set_resolving_list(BT_GAP_LE_CLEAR_RESOLVING_LIST,
NULL);
return st;
}
4.1.6.
Read the RSSI
Call the function bt_gap_le_read_rssi() to read the Received Signal Strength Indication (RSSI) of a given
connection. More details can be found in the Bluetooth Core Specifications version 4.2 [vol2, Part E, 7.5.4],
Bluetooth GAP.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 80 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
4.1.7.
Update data length
Call the function bt_gap_le_update_data_length() to suggest data length for a given connection. More
details can be found in the Bluetooth Core Specifications version 4.2 [vol2, Part E, 7.8.33], Bluetooth GAP.
4.1.8.
Multiple advertising
The multiple advertising is supported on the MT7697 chip only; the objectives of multiple advertising are the
following:
•
Ability to support multiple non-connectable advertising
•
Different advertising content and address
•
An individualized response for each advertising
•
Configurable transmission power (the range is from -70 dBm to 20 dBm)
•
Ability to perform single (connectable) and multi-advertising (non-connectable), simultaneously, by calling
the functions bt_gap_le_set_advertising() and
bt_gap_le_start_multiple_advertising(), respectively.
With multiple advertising, different applications can start advertising without frequent modification of the
advertising content. After it starts, the host can remain in sleep mode to save power. It requires adding the library
“libble_multi_adv.a” to the project’s makefile. The application can start multiple advertising by using the
multiple advertising APIs.
4.1.8.1.
Limitations
•
Multiple advertising does not support connectable type advertising.
•
After adding the library “libble_multi_adv.a” to the project makefile, the
BT_HCI_ADV_TYPE_CONNECTABLE_DIRECTED_HIGH and
BT_HCI_ADV_TYPE_CONNECTABLE_DIRECTED_HIGH types of advertising are no longer supported by
bt_gap_le_set_advertising().
4.1.8.2.
Get maximum advertising instances
Call the function bt_gap_le_get_max_multiple_advertising_instances() to get the maximum number
of supported advertising instances, as shown below.
uint8_t max_instances =
bt_gap_le_get_max_multiple_advertising_instances();
4.1.8.3.
Start multiple advertising
Set different advertising parameters and data for each advertising instance and start multiple advertising, as
shown below. Multiple instances can start concurrently.
void app_start_instance_1(void)
{
bt_bd_addr_t adv_addr = {0x13, 0x71, 0xDA, 0x7D, 0x1A, 0x0};
bt_hci_cmd_le_set_advertising_parameters_t adv_para = {
.advertising_interval_min = 0x0800,
.advertising_interval_max = 0x0800,
.advertising_type = BT_HCI_ADV_TYPE_SCANNABLE_UNDIRECTED,
.advertising_channel_map = 7,
.advertising_filter_policy = 0
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 81 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
};
bt_hci_cmd_le_set_advertising_data_t adv_data = {
.advertising_data = {2, 1, 0x1A, 8, 9, ‘a’, ‘d’, ’v’, ’o’, ’n’,
’e’,0},
.advertising_data_length = 12,
.};
bt_hci_cmd_le_set_scan_response_data_t scan_res_data = {
.scan_response data = {2, 1, 0x1A},
.scan_response_data_length = 3,
.};
// Start advertising on instance 1. Each advertising instance needs to
start individually.
bt_gap_le_start_multiple_advertising(
1, /* Instance 1. The range is from 1 to (max_instance - 1). */
5,
(bt_bd_addr_ptr_t)adv_addr,
&adv_para,
&adv_data,
&scan_res_data
);
return;
}
void app_start_instance_2(void)
{
bt_bd_addr_t adv_addr = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11};
bt_hci_cmd_le_set_advertising_parameters_t adv_para = {
.advertising_interval_min = 0x0800,
.advertising_interval_max = 0x0800,
.advertising_type = BT_HCI_ADV_TYPE_SCANNABLE_UNDIRECTED,
.advertising_channel_map = 7,
.advertising_filter_policy = 0
};
bt_hci_cmd_le_set_advertising_data_t adv_data = {
.advertising_data = {2,1,0x1A, 8, 9, ‘a’, ‘d’, ’v’,
’t’,’w’,’0’,0},
.advertising_data_length = 12,
.};
bt_hci_cmd_le_set_scan_response_data_t scan_res_data = {
.scan_response data = {2, 1, 0x1A},
.scan_response_data_length = 3,
.};
// Start advertising on instance 2. Each advertising instance needs to
start individually.
bt_gap_le_start_multiple_advertising(
2, // Instance 2. The range is from 1 to (max_instance - 1).
5,
(bt_bd_addr_ptr_t)adv_addr,
&adv_para,
&adv_data,
&scan_res_data
);
return;
}
bt_status_t bt_app_event_callback(bt_msg_type_t msg, bt_status_t status,
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 82 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
void *buff)
{
switch (msg) {
case BT_GAP_LE_START_MULTIPLE_ADVERTISING_CNF:
{
bt_gap_le_start_multiple_advertising_cnf_t *event;
event = (bt_gap_le_start_multiple_advertising_cnf_t *)buff;
//Check the result of starting multi-advertising instance.
break;
}
}
return;
}
4.1.8.4.
Stop multiple advertising
Call the function bt_gap_le_stop_multiple_advertising () to stop the advertising instance, as shown
below. Multiple instances can stop concurrently.
void app_stop_instance(void)
{
// Stop advertising instance 1. Each advertising instance needs to be
stopped individually.
bt_gap_le_stop_multiple_advertising(1);
return;
}
bt_status_t bt_app_event_callback(bt_msg_type_t msg, bt_status_t status,
void *buff)
{
switch (msg) {
case BT_GAP_LE_START_MULTIPLE_ADVERTISING_CNF:
{
bt_gap_le_stop_multiple_advertising_cnf_t *event;
event = (bt_gap_le_stop_multiple_advertising_cnf_t *)buff;
//Check the result of stopping multi-advertising instance.
break;
}
}
return;
}
4.2.
SM
The SM manages pairing, authentication and encryption between Bluetooth LE devices.
Pairing process has three phases. The first two are mandatory while the third one is optional.
Pairing Feature Exchange. Pairing feature includes I/O capability, Out-of-Band data flag, authentication
requirements (bonding flag, man-in-the-middle (MITM) flag and Secure Connections (SC) flag),
maximum encryption key size, initiator key distribution and responder key distribution. At this phase, only
the I/O capability, Out-of-Band data flag and authentication requirements are configurable.
a)
The Bonding flag is set to false to delete the keys (described in step (d)), after disconnecting. If it’s set
to true, store the keys to the NAND flash so that they can be used again, when the two devices
reconnect.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 83 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
b) The MITM flag and the SC flag are used to determine whether to use the MITM protection and LE SC
Pairing separately or not.
c)
Maximum encryption key size is set to be 16 octets.
d)
The key distribution in the pairing request from the initiator can be one of the following:
i)
LTK, EDIV, and Rand (only for legacy pairing)
ii)
IRK
iii) CSRK
The responder will set the key distribution to be the minimum subset of Central and Peripheral devices.
i)
Short Term Key (STK) Generation for LE legacy pairing or LTK Generation for LE SC. The devices
determine which of the following methods to use after exchanging I/O capabilities.
ii)
Just Works
iii) Numeric Comparison (only for LE SC)
Passkey Entry. It varies depending on the I/O capability. One device displays the passkey and the other
inputs the passkey. The passkey is generated randomly but can be modified to be fixed or variable before
display.
Out-of-Band. The keys are not exchanged over the air, but rather over some other source such as serial
port or near field communication (NFC). For more information about how to determine the method, refer
to the Bluetooth core specifications version 4.2 [VOL 3, part H, 2.3.5.1].
Transport Specific Key Distribution. Phase 3 is optional to distribute specific keys, such as the Identity
Address information and IRK. Phase 1 and Phase 3 are identical regardless of the method used in Phase 2.
Phase 3 is only performed on an encrypted link using the STK or LTK generated in Phase 2. Phase 1 and Phase 2 can
be performed on a link with no encryption.
The keys distributed in Phase 3 need to be stored in the application. If the keys aren’t stored, the pairing starts,
otherwise the pairing is skipped and only the encryption is performed. Once the keys are stored for each device,
the resolvable address needs to be considered when searching for the keys for that device. The resolvable address
can be modified at any time. Keys are stored for a remote device with their resolvable addresses. The keys might
change when the two devices are reconnected. In that case, during the search for keys, if both resolvable
addresses can be resolved to the same identity address, the keys are found and can be used to encrypt the link so
that the pairing process can be skipped.
Note. The Out-of-Band method is only supported in the LE legacy pairing, but not in the LE SC.
Encryption is implemented when the STK or LTK is generated. Usually the link is encrypted with the LTK again when
reconnecting to the paired remote device. If the local device only initiates the encryption but the LTK doesn’t exist
on the remote device, then it’s suggested to apply the pairing again.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 84 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
Host
Generic Access Profile
(GAP)
Security Manager
(SM)
Function call
Event
Logical Link Control and
Adaptation Protocol (L2CAP)
Host-Controller Interface (HCI)
Link Layer (LL)
Physical Layer (PHY)
Controller
Figure 69. SM abstraction layout
It’s possible for the application and profiles to directly call GAP API functions to perform authentication and
encryption after connection is established. GAP is based on SM, and the SM is based on L2CAP and HCI. GAP
manages links and encapsulates the SM code, and the SM uses an L2CAP channel to send data to the remote
device and receive data from the remote device, as shown in Figure 69.
4.2.1.
The SM message sequences
This section introduces typical message sequences to provide more details about the events and procedures of the
SM.
4.2.1.1.
Just Works
The central role can initiate the pairing by calling the function bt_gap_le_bond(), and Just Works is used if the
Out-of-Band flag of both devices is “OOB not present” and the I/O capability of one of these two devices is
“no input no output” or the MITM flag of both devices is “non-MITM”. An example where the I/O
capabilities of both devices are “no input no output” is shown in Figure 70.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 85 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
Central
SM
Peripheral
SM
Application
bt_gap_le_get_local_config()
bt_gap_le_get_local_config()
local key
powered on successfully
local key
bt_gap_le_get_bonding_info()
bt_gap_le_get_bonding_info()
bonding info
bonding info
connection is complete
ble_gap_le_bond()
received a pairing request
from a remote device
bt_gap_le_get_pairing_config()
bt_gap_le_get_pairing_config()
pairing info (no input no output)
pairing info (no input no output)
BT_GAP_LE_BONDING_COMPLETE_IND
BT_GAP_LE_BONDING_COMPLETE_IND
Event
Function call
User’s buffer
Figure 70. Just Works (central role)
The peripheral role can request the central role to initiate pairing by calling the function
bt_gap_le_bond(), and Just Works is used if the Out-of-Band flag of both devices is “OOB not
present” and the I/O capability of one of these two devices is “no input no output” or the MITM
flag of both devices is “non-MITM”. An example where the I/O capabilities of both devices are “no
input no output” is shown in Figure 71.
Application
Peripheral
SM
Central
SM
Application
bt_gap_le_get_local_config()
bt_gap_le_get_local_config()
powered on successfully
local key
local key
bt_gap_le_get_bonding_info()
bt_gap_le_get_bonding_info()
connection is complete
bonding info
bonding info
ble_gap_le_bond()
received a secure request
from a remote device
bt_gap_le_get_pairing_config()
bt_gap_le_get_pairing_config()
pairing info (no input no output)
pairing info (no input no output)
BT_GAP_LE_BONDING_COMPLETE_IND
Event
BT_GAP_LE_BONDING_COMPLETE_IND
Function call
User’s buffer
Figure 71. Just Works (peripheral role)
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 86 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
4.2.1.2.
Numeric Comparison (only for LE SC)
The central role can initiate the pairing by calling the function bt_gap_le_bond(), and passkey entry is used if
the Out-of-Band flag of both devices is “OOB not present”, the MITM flag of at least one device is “has
MITM” and the I/O capability of one of these two devices is “Display Yes No”. An example is shown in.
Application
Central
SM
bt_gap_le_get_local_config()
local key
bt_gap_le_get_bonding_info()
bonding info
Peripheral
SM
powered on successfully
Application
bt_gap_le_get_local_config()
local key
bt_gap_le_get_bonding_info()
connection is complete
bonding info
ble_gap_le_bond()
bt_gap_le_get_pairing_config()
received a pairing request
from a remote device
bt_gap_le_get_pairing_config()
pairing info (Display YesNo)
pairing info (Display YesNo)
BT_GAP_LE_BONDING_REPLY_IND
BT_GAP_LE_BONDING_REPLY_IND
ble_gap_le_bonding_reply(YesNo)
ble_gap_le_bonding_reply(YesNo)
BT_GAP_LE_BONDING_COMPLETE_IND
Event
BT_GAP_LE_BONDING_COMPLETE_IND
Function call
User’s buffer
Figure 72. Numeric Comparison (central role)
The peripheral role can request the central role to initiate the pairing by calling the function bt_gap_le_bond()
and passkey entry is used if the Out-of-Band flag of both devices is “OOB not present”, the MITM flag of at least
one of the devices is “has MITM”, the I/O capability of one of these two devices is “Display Yes No”.
An example is shown in Figure 73.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 87 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
Peripheral
SM
local key
powered on successfully
bt_gap_le_get_bonding_info()
bt_gap_le_get_bonding_info()
connection is complete
bonding info
Application
bt_gap_le_get_local_config()
bt_gap_le_get_local_config()
local key
Central
SM
bonding info
ble_gap_le_bond()
bt_gap_le_get_pairing_config()
received a secure request
from a remote device
bt_gap_le_get_pairing_config()
pairing info (Display YesNo)
pairing info (Display YesNo)
BT_GAP_LE_BONDING_REPLY_IND
BT_GAP_LE_BONDING_REPLY_IND
ble_gap_le_bonding_reply(YesNo)
ble_gap_le_bonding_reply(YesNo)
BT_GAP_LE_BONDING_COMPLETE_IND
Event
BT_GAP_LE_BONDING_COMPLETE_IND
Function call
User’s buffer
Figure 73. Numeric Comparison (peripheral role)
4.2.1.3.
Passkey entry
The central role can initiate the pairing by calling the function bt_gap_le_bond(), and passkey entry is
used if the Out-of-Band flag of both devices is “OOB not present”, the MITM flag of at least one
device is “has MITM” and the I/O capabilities of these two devices are any except “no input no
output” and “display only”. An example where the I/O capabilities of both devices are “keyboard
only” is shown in Figure 74.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 88 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
Central
SM
Peripheral
SM
Application
bt_gap_le_get_local_config()
bt_gap_le_get_local_config()
local key
local key
power on successfully
bt_gap_le_get_bonding_info()
bt_gap_le_get_bonding_info()
bonding info
connect complete
bonding info
ble_gap_le_bond()
receive a pairing request from
a remote device
bt_gap_le_get_pairing_config()
bt_gap_le_get_pairing_config()
pairing info (keyboard only)
pairing info (keyboard only)
BT_GAP_LE_BONDING_REPLY_IND
BT_GAP_LE_BONDING_REPLY_IND
ble_gap_le_bonding_reply(passkey)
ble_gap_le_bonding_reply(passkey)
BT_GAP_LE_BONDING_COMPLETE_IND
Event
BT_GAP_LE_BONDING_COMPLETE_IND
Function call
User’s buffer
Figure 74. Passkey entry (central role)
The peripheral role can request the central role to initiate pairing by calling the function
bt_gap_le_bond() and passkey entry is used if the Out-of-Band flag of both devices is “OOB not
present”, the MITM flag of at least one of the devices is “has MITM”, the I/O capabilities of these two
devices are anything except “no input no output” and “display only”. An example where the
I/O capabilities of both devices are “keyboard only” is shown in Figure 75.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 89 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
Peripheral
SM
Central
SM
Application
bt_gap_le_get_local_config()
bt_gap_le_get_local_config()
local key
local key
power on successfully
bt_gap_le_get_bonding_info()
bt_gap_le_get_bonding_info()
connect complete
bonding info
bonding info
ble_gap_le_bond()
receive a secure request from
a remote device
bt_gap_le_get_pairing_config()
bt_gap_le_get_pairing_config()
pairing info (keyboard only)
pairing info (keyboard only)
BT_GAP_LE_BONDING_REPLY_IND
BT_GAP_LE_BONDING_REPLY_IND
ble_gap_le_bonding_reply(passkey)
ble_gap_le_bonding_reply(passkey)
BT_GAP_LE_BONDING_COMPLETE_IND
BT_GAP_LE_BONDING_COMPLETE_IND
Event
Function call
User’s buffer
Figure 75. Passkey entry (peripheral role)
4.2.1.4.
Encryption
The central role requests to initiate the encryption by calling the function bt_gap_le_bond(). After the
pairing is complete, the link is already encrypted with the STK in LE legacy pairing or LTK in LE S C pairing.
Usually the encryption with the LTK is performed if higher security level is required or after reconnecting.
An example where the LTK is used to encrypt the link is shown in Figure 76.
Application
Central
SM
SM
Peripheral
Application
Both are bonded devices
Both are bonded devices
bt_gap_le_get_bonding_info()
bt_gap_le_get_bonding_info()
reconnect complete
bonding info
bonding info
bt_gap_le_bond()
BT_GAP_LE_BONDING_COMPLETE_IND
BT_GAP_LE_BONDING_COMPLETE_IND
Event
Function call
User’s buffer
Figure 76. Encryption (central role)
The peripheral role initiates the encryption by calling the function bt_gap_le_bond(). After the pairing
is complete, the link is already encrypted with STK in LE legacy pairing or LTK in LE SC pairing. Usually the
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 90 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
encryption with the LTK is performed if higher security level is required or after reconnecting. An example
where the LTK is used for link encryption is shown in Figure 77.
Application
Peripheral
SM
Central
SM
Both are bonded devices
Both are bonded devices
bt_gap_le_get_bonding_info()
bt_gap_le_get_bonding_info()
reconnect complete
bonding info
bonding info
receive a secure request from
a remote device
bt_gap_le_bond()
BT_GAP_LE_BONDING_COMPLETE_IND
BT_GAP_LE_BONDING_COMPLETE_IND
Event
Application
Function call
User’s buffer
Figure 77. Encryption (peripheral role)
4.2.2.
Using the SM APIs
The SM API headers can be found in the bt_gap_le.h header file with only two interface APIs for pairing,
bt_gap_le_bond() and bt_gap_le_bonding_reply(). Apply the following function calls to use the SM in
your application development.
Optional, call the bt_gap_le_bond() API to pair with a remote device and perform the encryption once
the pairing is finished. Also call the bt_gap_le_bond() API to encrypt only, if these two devices are still
bonded, which is usually performed after reconnecting with the bonded remote device.
bt_status_t status;
bt_smp_pairing_config_t pairing_config = {//mitm, bond, oob
.maximum_encryption_key_size = 16,
.io_capability = BT_SMP_DISPLAY_YES_NO,
.auth_req = BT_SMP_AUTH_REQ_MITM | BT_SMP_AUTH_REQ_SECURE_CONNECTION,
};
uint32_t connection_handle = 0x0200;
status = bt_gap_le_bond(connection_handle, & pairing_config);
Optional, call the bt_gap_le_bonding_reply() API to send the Out-of-Band data for the Out-of-Band
pairing method or passkey for the Passkey Input pairing method (see 4.2.1.3, “Passkey entry”), or Numeric
Comparison result (see 4.2.1.2, “Numeric Comparison (only for LE SC)”), when
BT_GAP_LE_BONDING_REPLY event is received.
bt_status_t status;
bt_gap_le_bonding_reply_t rsp = {.passkey = 123456};
uint32_t connection_handle = 0x0200;
status = bt_gap_le_bonding_reply(connection_handle, &rsp);
Mandatory, implement the bt_app_event_callback () API to handle the events sent by the stack.
bt_status_t bt_app_event_callback(bt_msg_type_t msg, bt_status_t status,
void *buff)
{
bt_status_t status;
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 91 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
switch (msg) {
case BT_GAP_LE_BONDING_REPLY_IND: {
//Reply OOB data or Passkey or Numeric Comparison result, call
bt_gap_le_bonding_reply() API.
}
case BT_GAP_LE_BONDING_COMPLETE_IND: {
// indicates a pairing procedure has finished.
}
default:
break;
}
return status;
}
Mandatory, implement the bt_gap_le_get_local_config() API to return the local configuration
field to stack. All configuration fields must be a global buffer.
static bt_gap_le_local_config_req_ind_t g_app_local_config;
bt_gap_le_local_key_t local_key_req = {
.encryption_info = {0};
.master_id = {0};
.identity_info =
{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x19,0x28,0x55,0x33,0x68,0x33,0x5
6,0xde};
.signing.info = {0};
};
Bool sc_omly = false;
bt_gap_le_local_config_req_ind_t bt_gap_le_get_local_config(void)
{
g_app_local_config.local_key_req = &local_key_req;
g_app_local_config.sc_only_mode_req = sc_only;
return &g_app_local_config;
}
Mandatory, implement the bt_gap_le_get_bonding_info() API to return the bonding info field to
stack. Bonding info field must be a global buffer.
static bt_gap_le_bonding_info_t bongding_info = {0};
bt_gap_le_bonding_info_t bt_gap_le_get_bonding_info(const bt_addr_t
remote_addr)
{
return &bongding_info;
}
Mandatory, implement the bt_gap_le_get_pairing_config() API to return the pairing info field to
stack. Pairing info field must be a global buffer.
static bt_gap_le_smp_pairing_config_req = {
.auth_req = BT_GAP_LE_SMP_AUTH_REQ_BONDING,
.maximum_encryption_key_size = 16,
.io_capability = BT_GAP_LE_SMP_NO_INPUT_NO_OUTPUT,
};
bt_status_t bt_gap_le_get_pairing_config(bt_gap_le_bonding_start_ind_t
*ind)
{
ind->pairing_config_req = pairing_config_req;
return BT_STATUS_SUCCESS;
}
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 92 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
4.3.
GATT
GATT describes a service framework using the Attribute Protocol (ATT) to discover, read, write, notify and indicate
characteristics, as well as to configure the broadcast of characteristics. GATT is designed for an application or
another profile to communicate with a peer device. There are two roles defined for devices that implement this
profile, as shown in Figure 78.
•
Client — the device that sends commands and requests to the server and can receive responds,
indications and notifications from the server.
•
Server — the device that accepts commands and requests from the client and sends responds,
indications and notifications to a client.
Requests or Commands
Client
Responds
Server
Figure 78. GATT Client and Server
The ATT request-response or indication-confirmation pair is considered as a single transaction. The two roles are
not fixed to the device, but are determined when a device initiates a transaction, and are released when the
transaction ends. A device can act in both roles at the same time.
A profile should have one or more services. The service is composed of one or more characteristics or included
services. Each characteristic contains a value and may contain optional information known as descriptors of the
value, as shown in Figure 79. All information (service, characteristic and the components of the characteristic) is
stored in Attributes on the Server.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 93 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Profile
Service
Service
Include
Include
…
…
Include
Include
Characteristic
Characteristic
Declaration
Declaration
Value
Value
…
Descriptor
Descriptor
…
…
Descriptor
Descriptor
…
…
Characteristic
Characteristic
Declaration
Declaration
Value
Value
Descriptor
Descriptor
…
…
Descriptor
Descriptor
Figure 79. GATT profile hierarchy
The Attribute consists of: Attribute Handle, Attribute Type, Attribute Value and Attribute Permissions,
as shown in Figure 80.
2 Octets
2 or 16 Octets
Variable length
Attribute Handle
Attribute Type
Attribute Value
Implementation specific
Attribute Permissions
Figure 80. Logical representation of the attribute
The Attribute Handle is an index corresponding to a specific Attribute. The Attribute Type is a UUID that
describes the Attribute Value. The Attribute Value is the data described by the Attribute Type and indexed
by the Attribute Handle. The Attributes are ordered by ascending Attribute Handle values. The Attribute
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 94 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Handle values are in a range from 0x0001 to 0xFFFF. Attribute Permissions are part of the Attribute that
cannot be read from or written to using ATT. The permissions are used by the Server to determine whether read
or write access is permitted for a given Attribute.
4.3.1.
Create a GATT Server
The GATT Server stores and manages an application-wide attribute table. This section describes the process to
create a user-defined GATT Server.
GATT Server's database is divided into three levels, from top to bottom, the server, the service and the record.
Each server can have more than one service. Each service can have more than one record.
An example of a GATT Server that has two services, bt_if_gap_service with four records and
bt_if_gatt_service with five records, is shown below.
|server
|service
|handle|record|
|bt_if_gatt_server
|bt_if_gap_service
|0x0001|bt_if_gap_primary_service|
|0x0002|bt_if_gap_included_manufacturer_service|
|0x0003|bt_if_gap_char4_dev_name|
|0x0004|bt_if_gap_dev_name|
|bt_if_gatt_service
|0x0011|bt_if_gatt_primary_service|
|0x0012|bt_if_gatt_char4_service_changed|
|0x0013|bt_if_gatt_service_changed|
|0x0014|bt_if_gatt_client_config|
|0x0015|bt_if_gatt_server_config|
Follow the steps below to implement GATT Server with the defined services and records.
Implement a callback is required to handle the device name read and write requests when creating a
device name characteristic, as shown below.
char gatts_device_name[256]={"MTKHB"};
static uint32_t bt_if_gap_dev_name_callback (const uint8_t rw, uint16_t
handle, void *data, uint16_t size, uint16_t offset)
{
uint32_t str_size = strlen(gatts_device_name);
uint32_t buf_size = sizeof(gatts_device_name);
uint32_t copy_size;
switch (rw) {
case BT_GATTS_CALLBACK_READ:
/* To handle read request. */
copy_size = (str_size> offset)?(str_size-offset):0;
if (size==0){
return str_size;
}
copy_size = (size > copy_size)? copy_size:size;
memcpy(data, gatts_device_name+offset, copy_size);
return copy_size;
case BT_GATTS_CALLBACK_WRITE:
/* To handle write request. */
copy_size = (size > buf_size)? buf_size:size;
memcpy(gatts_device_name, data, copy_size);
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 95 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
return copy_size;
default:
return BT_STATUS_SUCCESS;
}
}
Create the four (4) records of the GAP service and store them in the bt_if_gap_service_rec, as
shown below.
/* To create records of GAP primary service. */
enum {
GAP_HANDLE_START = 0x0001,
GAP_HANDLE_PRIMARY_SERVICE = GAP_HANDLE_START,
GAP_HANDLE_INCLUDED_MANUFACTURER_SERVICE,
GAP_HANDLE_CHAR4_DEV_NAME,
GAP_HANDLE_DEV_NAME,
GAP_HANDLE_END
};
/* The record of primary service. */
BT_GATTS_NEW_PRIMARY_SERVICE_16(bt_if_gap_primary_service,
BT_GATT_UUID16_GAP_SERVICE);
/* The record of included service. */
BT_GATTS_NEW_INCLUDED_SERVICE_128(bt_if_gap_included_manufacturer_service,
0x0500, 0x0522);
/* The record of device name characteristic declaration. */
BT_GATTS_NEW_CHARC_16_WRITABLE(bt_if_gap_char4_dev_name,
BT_GATT_CHARC_PROP_READ, GAP_HANDLE_DEV_NAME,
BT_SIG_UUID16_DEVICE_NAME);
/* The record of device name characteristic value. */
BT_GATTS_NEW_CHARC_VALUE_CALLBACK(bt_if_gap_dev_name,
BT_SIG_UUID_DEVICE_NAME,
BT_GATTS_REC_PERM_READABLE|BT_GATTS_REC_PERM_WRITABLE,
bt_if_gap_dev_name_callback);
/* The bt_if_gap_service_rec to hold all records of GAP service. */
static const bt_gatts_service_rec_t *bt_if_gap_service_rec[] = {
(const bt_gatts_service_rec_t*) &bt_if_gap_primary_service,
(const bt_gatts_service_rec_t*)
&bt_if_gap_include_manufacturer_service,
(const bt_gatts_service_rec_t*) &bt_if_gap_char4_dev_name,
(const bt_gatts_service_rec_t*) &bt_if_gap_dev_name
};
Create a GAP service named as bt_if_gap_service and stored in bt_if_gatt_server, as shown
below.
/* The value of the starting_handle is assigned to the first record:
bt_if_gap_primary_service.
The value of the ending_handle is assigned to the last record:
bt_if_gap_dev_name.
(ending_handle - starting_handle + 1) should equal to the number of
records.
The required_encryption_key_size defines the encryption key size this
service requires. If record's perm is set as
BT_GATTS_REC_PERM_READABLE_ENCRYPTION or
BT_GATTS_REC_PERM_WRITABLE_ENCRYPTION, GATTS will check if the channel is
encrypted and the encryption key size is greater than or equal to
required_encryption_key_size. */
static const bt_gatts_service_t bt_if_gap_service = {
.starting_handle = GAP_HANDLE_START,
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 96 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
.ending_handle = GAP_HANDLE_END - 1,
.required_encryption_key_size = 7,
/* If record needs channel encryption, the size of encryption key
should be equal to or greater than 7. */
.records = bt_if_gap_service_rec
};
Implement a callback is required to handle the client characteristic configuration read and write requests
when creating the client characteristic configuration descriptor.
static uint16_t bt_if_gatt_notify=0; //Client Characteristic Configuration
static uint32_t bt_if_gatt_client_config_callback (const uint8_t rw,
uint16_t handle, void *data, uint16_t size, uint16_t
offset)
{
if (rw == BT_GATTS_CALLBACK_WRITE){
/* To handle write request. */
if (size != sizeof(bt_if_gatt_notify)){ //Size check
return 0;
}
bt_if_gatt_notify = *(uint16_t*)data;
} else {
/* To handle read request. */
if (size!=0){
uint16_t *buf = (uint16_t*) data;
*buf = bt_if_gatt_notify;
}
}
return sizeof(bt_if_gatt_notify);
}
Create five (5) records of the GATT service stored in bt_if_gatt_service_rec, as shown below.
/* To create records of GATT primary service. */
enum {
GATT_HANDLE_START = 0x0011,
GATT_HANDLE_PRIMARY_SERVICE = GATT_HANDLE_START,
GATT_HANDLE_CHAR4_SERVICE_CHANGED,
GATT_HANDLE_SERVICE_CHANGED,
GATT_HANDLE_CLIENT_CONFIG,
GATT_HANDLE_END
};
BT_GATTS_NEW_PRIMARY_SERVICE_16(bt_if_gatt_primary_service,
BT_GATT_UUID16_GATT_SERVICE);
/* The record of service changed characteristic declaration. */
BT_GATTS_NEW_CHARC_16(bt_if_gatt_char4_service_changed,
BT_GATT_CHARC_PROP_READ|BT_GATT_CHARC_PROP_NOTIFY|
BT_GATT_CHARC_PROP_INDICATE,GATT_HANDLE_SERVICE_CHANGED,
BT_SIG_UUID16_SERVICE_CHANGED);
/* The record of service changed characteristic value. */
BT_GATTS_NEW_CHARC_VALUE_UINT32_WRITABLE(bt_if_gatt_service_changed,
BT_SIG_UUID_SERVICE_CHANGED, 0x2, 0x0001050F);
/* The record of client configuration descriptor. */
BT_GATTS_NEW_CLIENT_CHARC_CONFIG(bt_if_gatt_client_config,
BT_GATTS_REC_PERM_READABLE|BT_GATTS_REC_PERM_WRITABLE,
bt_if_gatt_client_config_callback);
static const bt_gatts_service_rec_t *bt_if_gatt_service_rec[] = {
(const bt_gatts_service_rec_t*) &bt_if_gatt_primary_service,
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 97 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
(const bt_gatts_service_rec_t*) &bt_if_gatt_char4_service_changed,
(const bt_gatts_service_rec_t*) &bt_if_gatt_service_changed,
(const bt_gatts_service_rec_t*) &bt_if_gatt_client_config
};
Create a GATT service named as bt_if_gatt_service and store it in bt_if_gatt_server, as shown
below.
/* Value of starting_handle will be assigned to first record:
bt_if_gatt_primary_service.
Value of ending_handle will be assigned to end record:
bt_if_gatt_client_config.
(ending_handle - starting_handle + 1) should equal to number of records.
The required_encryption_key_size is used to define encryption key size
this service requires. If record's perm was setted with
BT_GATTS_REC_PERM_READABLE_ENCRYPTION or
BT_GATTS_REC_PERM_WRITABLE_ENCRYPTION, GATTS will check if the channel is
encrypted and the encryption key size is greater than or equal to
required_encryption_key_size. */
static const bt_gatts_service_t bt_if_gatt_service = {
.starting_handle = GATT_HANDLE_START,
.ending_handle = GATT_HANDLE_END - 1,
.required_encryption_key_size = 9,
/* If record need channel encryption, the size of encryption key
should be equal to or greater than 9. */
.records = bt_if_gatt_service_rec
};
Create a GATT Server named as bt_if_gatt_server to collect all services and implement
/* - Create bt_if_gatt_server and collect all services. */
// Server collects all service.
const bt_gatts_service_t * bt_if_gatt_server[] = {
&bt_if_gap_service,
&bt_if_gatt_service_ro,
NULL
};
/* This server should be provided to GATTS via bt_get_gatt_server(). */
const bt_gatts_service_t** bt_get_gatt_server()
{
return bt_if_gatt_server;
}
bt_get_gatt_server() to return the final constructed server.
If service or characteristic want to use 128 bit UUID, please refer to the following sample code.
/* - How to Add characteristic with 128 bit UUID. */
/* If uuid is 16 bit, convert it as 128 bit. */
bt_uuid_t uuid128_xxx = BT_UUID_INIT_WITH_UUID16(uuid16_xxx);
/* Define 128 UUID characteristic, and add to service as before. */
BT_GATTS_NEW_CHARC_128(name, prop, _handle, uuid128_xxx);
/* - How to add a secondary service with 128bit UUID. */
/* Define a secondary service with 128 bit UUID, and some characteristic
for this service */
#define BT_SIG_UUID_VENDOR_SERVICE
{{0x12,0x34,0x56,0x78,0x90,0x13,0x57,0x91,0x24,0x68,0x82,0x11,0x22,0x33,0x
44,0x55}}
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 98 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
BT_GATTS_NEW_SECONDARY_SERVICE_128(bt_if_vendor_secondary_service,BT_SIG_U
UID_VENDOR_SERVICE);
BT_GATTS_NEW_CHARC_16(bt_if_vendor_char1_manufacture_name, ...) ;
......
/* Add service records array into gatt server "bt_if_gatt_server[]" */
static const bt_gatts_service_rec_t *bt_if_vendor_service_rec[] = {
(const bt_gatts_service_rec_t*) &bt_if_vendor_secondary_service,
(const bt_gatts_service_rec_t*) &bt_if_vendor_char1_manufacture_name,
......
};
static const bt_gatts_service_t bt_if_vendor_service = {
.starting_handle = 0x0500,
.ending_handle = 0x0522,
.required_encryption_key_size = 16,
.records = bt_if_vendor_service_rec
};
const bt_gatts_service_t * bt_if_gatt_server[] = {
&bt_if_gap_service,//0x0001
&bt_if_gatt_service_ro,//0x0010
&bt_if_bas_service,//0x0020
&bt_if_vendor_service,//0x500
NULL
};
/* Define include service which start/end handle same with secondary
service, and add include service into primary service. */
BT_GATTS_NEW_INCLUDED_SERVICE_128(bt_if_included_vendor_secondary_service,
0x0500, 0x0522);
static const bt_gatts_service_rec_t *bt_if_bas_service_rec[] = {
(const bt_gatts_service_rec_t*) &bt_if_bas_primary_service,
(const bt_gatts_service_rec_t*)&bt_if_included_vendor_secondary_service,
......
};
4.3.1.1.
GATT Server callbacks
•
Implement the bt_gatts_get_authorization_check_result() API, if the GATT Server requires to
check for an attribute authorization. The API confirms with a user whether to give authorization to a
specified attribute. If the server accepts peer access to this attribute, the returned value is
BT_STATUS_SUCCESS; otherwise, the returned value is BT_STATUS_UNSUPPORTED.
•
If the GATT server has a long attribute, bt_gatts_get_execute_write_result() should be
implemented, to confirm with the server whether execute write request completed successfully. If the
execute write request completed successfully, the returned value is BT_STATUS_SUCCESS; otherwise,
the returned value is BT_ATT_ERRCODE_XXX.
4.3.2.
Using the GATT APIs
This section describes how to use the GATT APIs in your application development. The APIs can be found in
bt_gattc.h and bt_gatts.h header files.
Most of the GATT APIs require a connection handle as the first parameter obtained from listening to the
BLE_GAP_CONNECT_IND event from the bt_app_event_callback() callback function.
© 2015 - 2017 MediaTek Inc.
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Page 99 of 123
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
4.3.2.1.
Exchanging MTU
Initialize the Exchange MTU only once during a connection. The message flow for Exchange MTU is shown in Figure
81. More details can be found in the bt_gattc.h header file.
The default MTU size is 23. Neither client nor server should use MTU size of less than 23. When the client supports
a value greater than the default MTU, the client should inform the server of the client’s maximum receive MTU
size by calling the function bt_gattc_exchange_mtu().
The server can set the maximum MTU size it can support by calling bt_gatts_set_max_mtu(). Once the
messages are exchanged, the final MTU between the two devices is set to the minimum of the client receive MTU
and server receive MTU values. The GATT client or server can call the function bt_gattc_get_mtu() to get the
current MTU.
Client
GATT
Server
GATT
bt_gattc_exchange_mtu()
The Server checks if the MTU requested
by the Client is greater than the user
defined maximum MTU size in the
bt_gatts_set_max_mtu() API.
BT_GATTC_EXCHANGE_MTU
Function call
Events
Figure 81. Exchange MTU event sequence
An example implementation to Exchange MTU:
/* BLE devices is connected, and conn_handle has been obtained from
BLE_GAP. */
BT_GATTC_NEW_EXCHANGE_MTU_REQ(req);
bt_gattc_exchange_mtu(conn_handle, &req);
void bt_app_event_callback(bt_msg_type_t msg, bt_status_t status, void
*buff)
{
switch (msg) {
case BT_GATTC_EXCHANGE_MTU: {
if (status != BT_STATUS_SUCCESS) {
printf ("BT_GATTC_EXCHANGE_MTU FINISHED!!");
break;
}
bt_gatt_exchange_mtu_rsp_t *rsp = (bt_gatt_exchange_mtu_rsp_t *)buff;
printf("mtu=%d", rsp->server_rx_mtu);
break;
}
}
© 2015 - 2017 MediaTek Inc.
Page 100 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
4.3.2.2.
Primary service discovery
The Primary service discovery message flow is shown in Figure 82. More details can be found in the bt_gattc.h
header file.
There are two APIs bt_gattc_discover_primary_service() and
bt_gattc_discover_primary_service_by_uuid() used by a client to discover primary services on a server.
Once the primary services are discovered, additional information about the primary services can be accessed using
other APIs.
Client
GATT
GATT
Server
bt_gattc_discover_primary_service()
BT_GATTC_DISCOVER_PRIMARY_SERVICE
bt_gattc_discover_primary_service_by_uuid()
The stack will handle the request and
give response according to the service
table constructed by application
BT_GATTC_DISCOVER_PRIMARY_SERVICE_BY_UUID
Function call
Events
Figure 82. Primary service discovery event sequence
These two APIs will discover all primary services between the given starting handle and ending handle and then
notify the upper layer about each received response.
An example implementation to discover a primary service:
/* BLE devices is connected, and conn_handle has been obtained from
BLE_GAP. */
BT_GATTC_NEW_DISCOVER_PRIMARY_SERVICE_REQ(req);
bt_gattc_discover_primary_service(conn_handle, &req);
void bt_app_event_callback(bt_msg_type_t msg, bt_status_t status, void
*buff)
{
switch (msg) {
case BT_GATTC_DISCOVER_PRIMARY_SERVICE: {
if (status != BT_STATUS_SUCCESS && status != BT_ATT_ERRCODE_CONTINUE)
{
printf("BT_GATTC_DISCOVER_PRIMARY_SERVICE FINISHED!!");
break;
}
bt_gattc_read_by_group_type_rsp_t *rsp =
(bt_gattc_read_by_group_type_rsp_t *)buff;
uint16_t end_group_handle = 0, starting_handle = 0, uuid = 0;
bt_uuid_t uuid128;
uint8_t *attribute_data_list = rsp->att_rsp->attribute_data_list;
uint8_t num_of_data = (rsp->length - 2) / rsp->att_rsp->length;
int i, j;
for (i = 0; i < num_of_data; i++) {
memcpy(&starting_handle,
© 2015 - 2017 MediaTek Inc.
Page 101 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
attribute_data_list + i * rsp->att_rsp->length, 2);
memcpy(&end_group_handle,
attribute_data_list + i * rsp->att_rsp->length + 2, 2);
if (rsp->att_rsp->length == 6) {
memcpy(&uuid, attribute_data_list + i * rsp->att_rsp->length + 4,
rsp->att_rsp->length - 4);
} else {
memcpy(&uuid128.uuid, attribute_data_list+i*rsp->att_rsp->length +
4,
rsp->att_rsp->length - 4);
}
}
break;
}
}
To discover a primary service by the UUID:
/* BLE devices is connected, and conn_handle has been obtained from
BLE_GAP. */
BT_GATTC_NEW_DISCOVER_PRIMARI_SERVICE_BY_UUID16_REQ(req, 0xABCD);
bt_gattc_discover_primary_service_by_uuid(conn_handle, &req);
void bt_app_event_callback(bt_msg_type_t msg, bt_status_t status, void
*buff)
{
switch (msg) {
case BT_GATTC_DISCOVER_PRIMARY_SERVICE_BY_UUID: {
if (status != BT_STATUS_SUCCESS && status != BT_ATT_ERRCODE_CONTINUE)
{
printf("BT_GATTC_DISCOVER_PRIMARY_SERVICE BY UUID FINISHED!!");
break;
}
bt_gattc_find_by_type_value_rsp_t *rsp =
(bt_gattc_find_by_type_value_rsp_t *)buff;
uint16_t attribute_handle = 0, end_group_handle = 0;
uint8_t *handles_info_list = rsp->att_rsp->handles_info_list;
uint8_t num_of_info = (rsp->length - 1) / 4;
int i;
for (i = 0 ; i < num_of_info; i++) {
memcpy(&attribute_handle, handles_info_list + 4 * i, 2);
memcpy(&end_group_handle, handles_info_list + 4 * i + 2, 2);
}
break;
}
}
When the server receives a Primary service discovery request, the stack handles this message and sends a
response to the client. The server only constructs a profile as described in section 4.3.1, “Create a GATT Server”.
© 2015 - 2017 MediaTek Inc.
Page 102 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
4.3.2.3.
Find included services
Client
GATT
GATT
Server
bt_gattc_find_included_services()
The stack will handle the request and
give response according to the service
table constructed by application
BT_GATTC_FIND_INCLUDED_SERVICES
Function call
Events
Figure 83. Find included services event sequence
The Find included services message flow is shown in Figure 83. More details can be found in the bt_gattc.h
header file.
Call the function bt_gattc_find_included_services() to find the included services. The response is in
BT_GATTC_FIND_INCLUDED_SERVICES.
An example implementation to find included services:
/* BLE devices is connected, and conn_handle has been obtained from
BLE_GAP. */
BT_GATTC_NEW_FIND_INCLUDED_SERVICE_REQ(req, 0x0001, 0x0010);
bt_gattc_find_included_services(conn_handle, &req);
void bt_app_event_callback(bt_msg_type_t msg, bt_status_t status, void
*buff)
{
switch (msg) {
case BT_GATTC_FIND_INCLUDED_SERVICES: {
if (status != BT_STATUS_SUCCESS && status != BT_ATT_ERRCODE_CONTINUE)
{
printf("BT_GATTC_FIND_INCLUDED_SERVICES FINISHED!!");
break;
}
bt_gattc_read_by_type_rsp_t *rsp = (bt_gattc_read_by_type_rsp_t
*)buff;
uint8_t *attribute_data_list = rsp->att_rsp->attribute_data_list;
uint16_t attribute_handle = 0, starting_handle = 0, ending_handle = 0;
uint16_t uuid = 0;
bt_uuid_t uuid128;
int i;
if (rsp->att_rsp->length <= 8) {
uint8_t num_of_data = (rsp->length - 2) / rsp->att_rsp->length;
for (i = 0 ; i < num_of_data; i++) {
memcpy(&attribute_handle,
© 2015 - 2017 MediaTek Inc.
Page 103 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
attribute_data_list + rsp->att_rsp->length*i, 2);
memcpy(&starting_handle,
attribute_data_list + rsp->att_rsp->length*i + 2, 2);
memcpy(&ending_handle,
attribute_data_list + rsp->att_rsp->length*i + 4, 2);
memcpy(&uuid, attribute_data_list + rsp->att_rsp->length*i + 6,
2);
}
} else {
memcpy(&attribute_handle, attribute_data_list, 2);
memcpy(&starting_handle, attribute_data_list + 2, 2);
memcpy(&ending_handle, attribute_data_list + 4, 2);
memcpy(&uuid128.uuid, attribute_data_list + 6, 16);
}
break;
}
}
When the server receives Find included services request, the stack handles this message and responds to the client
according to the profile constructed by the application, as described in section 4.3.1, “Create a GATT Server”.
4.3.2.4.
Characteristic discovery
The Characteristic discovery message flow is shown in Figure 84. More details can be found in the bt_gattc.h
header file.
Client
GATT
GATT
Server
bt_gattc_discover_charc()
The stack will handle the request and
give response according to the service
table constructed by application
BT_GATTC_DISCOVER_CHARC
Function call
Events
Figure 84. Discover characteristic event sequence
Call the function bt_gattc_discover_charc() for characteristic discovery. The response is in the
BT_GATTC_DISCOVER_CHARC.
An example implementation for the Characteristic discovery:
/* BLE devices is connected, and conn_handle has been obtained from
BLE_GAP. */
BT_GATTC_NEW_DISCOVER_CHARC_REQ(req, 0x0001, 0x0010);
bt_gattc_discover_charc(conn_handle, &req);
void bt_app_event_callback(bt_msg_type_t msg, bt_status_t status, void
*buff)
{
© 2015 - 2017 MediaTek Inc.
Page 104 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
switch (msg) {
case BT_GATTC_DISCOVER_CHARC: {
if (status != BT_STATUS_SUCCESS && status != BT_ATT_ERRCODE_CONTINUE)
{
printf("BT_GATTC_DISCOVER_CHARC FINISHED!!");
break;
}
bt_gattc_read_by_type_rsp_t *rsp = (bt_gattc_read_by_type_rsp_t
*)buff;
uint8_t *attribute_data_list = rsp->att_rsp->attribute_data_list;
uint16_t attribute_handle = 0;
uint8_t attribute_value[30] = {0};
uint8_t num_of_data = (rsp->length - 2) / rsp->att_rsp->length;
bt_uuid_t uuid128;
int i, j;
if (rsp->att_rsp->length < 20) {
for (i = 0 ; i < num_of_data; i++) {
memcpy(&attribute_handle,
attribute_data_list + i * rsp->att_rsp->length, 2);
memcpy(&attribute_value, attribute_data_list+i*rsp->att_rsp>length+2,
rsp->att_rsp->length - 2);
}
} else {
memcpy(&attribute_handle, attribute_data_list, 2);
memcpy(&attribute_value, attribute_data_list + 3, 2);
memcpy(&uuid128.uuid, attribute_data_list + 5, 16);
}
break;
}
}
When the server receives a Characteristic discovery request, the stack handles this message and responds to the
client according to the profile constructed by the application, as described in section 4.3.1, “Create a GATT Server”.
4.3.2.5.
Characteristic descriptor discovery
Client
GATT
GATT
Server
bt_gattc_discover_charc_descriptor()
BT_GATTC_DISCOVER_CHARC_DESCRIPTOR
Function call
The stack will handle the request and give
response according to the service table
constructed by application
Events
Figure 85. Characteristic descriptor discovery event sequence
The Characteristic descriptor discovery message flow is shown in Figure 85. More details can be found in the
header file bt_gattc.h.
© 2015 - 2017 MediaTek Inc.
Page 105 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
bt_gattc_discover_charc_descriptor() is used by a client to find all the characteristic descriptors’
Attribute Handles and Attribute Types within a characteristic definition when only the characteristic handle
range is known. The start handle should be set to the handle of the specified characteristic value + 1, and the end
handle should be set to the ending handle of the specified characteristic or service. The response will be stored in
BT_GATTC_DISCOVER_CHARC_DESCRIPTOR.
An example implementation for the Characteristic descriptor discovery:
/* BLE devices is connected, and conn_handle has been obtained from
BLE_GAP. */
BT_GATTC_NEW_DISCOVER_CHARC_DESCRIPTOR_REQ(req, 0x0003, 0x0005);
bt_gattc_discover_charc_descriptor(conn_handle, &req);
void bt_app_event_callback(bt_msg_type_t msg, bt_status_t status, void
*buff)
{
switch (msg) {
case BT_GATTC_DISCOVER_CHARC_DESCRIPTOR: {
if (status != BT_STATUS_SUCCESS && status != BT_ATT_ERRCODE_CONTINUE)
{
printf("BT_GATTC_DISCOVER_CHARC_DESCRIPTOR FINISHED!!");
break;
}
bt_gattc_find_info_rsp_t *rsp = (bt_gattc_find_info_rsp_t *)buff;
uint8_t format = rsp->att_rsp->format;
uint16_t attribute_handle = 0, attribute_value = 0;
uint8_t attribute_length = 0;
uint8_t num_of_attribute;
bt_uuid_t uuid128;
int i, j;
if ( format == 0x02 ) {
/* 128-bit UUID. */
attribute_length = 18;
num_of_attribute = (rsp->length - 2) / attribute_length;
for (i = 0; i < num_of_attribute; ++i) {
memcpy(&attribute_handle,
rsp->att_rsp->info_data + i * attribute_length, 2);
memcpy(&uuid128,
rsp->att_rsp->info_data + i * attribute_length + 2, 16);
}
} else {
/* 16-bit UUID. */
attribute_length = 4;
num_of_attribute = (rsp->length - 2) / attribute_length;
memcpy(&attribute_handle,
rsp->att_rsp->info_data+(num_of_attribute1)*attribute_length, 2);
memcpy(&attribute_value,
rsp->att_rsp->info_data+(num_of_attribute1)*attribute_length+2, 2);
}
break;
}
}
When the server receives the Characteristic descriptor discovery request, the stack handles this message and
sends a response to the client according to the profile constructed by the application, as described in section 4.3.1,
“Create a GATT Server”.
© 2015 - 2017 MediaTek Inc.
Page 106 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
4.3.2.6.
Read the characteristic value
There are four APIs to read a characteristic value, bt_gattc_read_charc(), bt_gattc_read_long_charc(),
bt_gattc_read_using_charc_uuid() and bt_gattc_read_multi_charc_values().
1) Call the function bt_gattc_read_charc() to read a characteristic value from the server, if the client
knows the characteristic value handle only. The handle parameter should be set to the characteristic
value handle. The BT_GATTC_READ_CHARC returns the characteristic value.
2) Call the function bt_gattc_read_long_charc() to read the characteristic value, if the client
knows the characteristic value handle and the length of the characteristic value is more than MTU – 1. The
Bluetooth stack will continuously send read blob request until all the values of the characteristic are read.
It will provide a response in BT_GATTC_READ_LONG_CHARC one by one, user is responsible to merge
them together.
3) Call the function bt_gattc_read_using_charc_uuid() to read a characteristic value, if the client
knows only the characteristic UUID and does not know the handle of the characteristic.
4) Call the function bt_gattc_read_multi_charc_values() to read multiple characteristic values in
one request, if the handle parameter is set to the characteristic value handles.
The message flow to read the characteristic value is shown in Figure 86. More details can be found in the
bt_gattc.h header file.
Client
GATT
GATT
Server
bt_gattc_read_long_charc()
The stack will handle the request and give
response according to the service table
constructed by application
BT_GATTC_READ_LONG_CHARC
BT_GATTC_READ_LONG_CHARC
Function call
Events
Figure 86. Characteristic value read event sequence
An example implementation to apply the function bt_gattc_read_long_charc():
/* BLE devices is connected, and conn_handle has been obtained from
BLE_GAP. */
BT_GATTC_NEW_READ_LONG_CHARC_REQ(req, 0x0008, 0);
bt_gattc_read_long_charc(conn_handle, &req);
void bt_app_event_callback(bt_msg_type_t msg, bt_status_t status, void
© 2015 - 2017 MediaTek Inc.
Page 107 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
*buff)
{
switch (msg) {
case BT_GATTC_READ_LONG_CHARC: {
if (status != BT_STATUS_SUCCESS) {
printf("BT_GATTC_READ_LONG_CHARC FINISHED!!");
break;
}
bt_gattc_read_blob_rsp_t *rsp = (bt_gattc_read_blob_rsp_t*)buff;
uint8_t length = rsp->length - 1;
int i;
for (i = 0; i < length ; i++)
printf("0x%02x ", rsp->att_rsp->attribute_value[i]);
break;
}
}
The message flow to read the characteristic value by UUID is shown in Figure 87. More details can be found in the
bt_gattc.h header file.
Client
GATT
Server
GATT
bt_gattc_read_using_charc_uuid()
The stack will handle the request and give
response according to the service table
constructed by application
BT_GATTC_READ_USING_CHARC_UUID
BT_GATTC_READ_USING_CHARC_UUID
Function call
Events
Figure 87. Read characteristic value using UUID event sequence
An example implementation to apply the function bt_gattc_read_using_charc_uuid():
/* BLE devices is connected, and conn_handle has been obtained from
BLE_GAP. */
uint8_t uuid16[2] = {0x2A, 0x01};
BT_GATTC_NEW_READ_USING_CHARC_UUID_REQ(req, 0x0001, 0xFFFF, uuid16, 2);
bt_gattc_read_using_charc_uuid(conn_handle, &req);
void bt_app_event_callback(bt_msg_type_t msg, bt_status_t status, void
*buff)
{
switch (msg) {
case BT_GATTC_READ_USING_CHARC_UUID: {
if (status != BT_STATUS_SUCCESS) {
printf("BT_GATTC_READ_USING_CHARC_UUID FINISHED!!");
break;
}
bt_gattc_read_by_type_rsp_t *rsp = (bt_gattc_read_by_type_rsp_t
*)buff;
uint8_t *attribute_data_list = rsp->att_rsp->attribute_data_list;
uint16_t attribute_handle = 0;
uint8_t attribute_value[30] = {0};
© 2015 - 2017 MediaTek Inc.
Page 108 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
int i, j;
uint8_t num_of_data = (rsp->length - 2) / rsp->att_rsp->length;
for (i = 0 ; i < num_of_data; i++) {
memcpy(&attribute_handle,
attribute_data_list + i * rsp->att_rsp->length, 2);
memcpy(&attribute_value, attribute_data_list + i*rsp->att_rsp>length + 2,
rsp->att_rsp->length - 2);
for (j = 0; j < rsp->att_rsp->length - 2; j++) {
printf("0x%02x ", attribute_value[j]);
}
}
break;
}
}
The message sequence to read multiple characteristic values is shown in Figure 88. More details can be found in
the bt_gattc.h header file.
Client
GATT
Server
GATT
bt_gattc_read_multi_charc_values()
BT_GATTC_READ_MULTI_CHARC_VALUES
Function call
The stack will handle the request and
give response according to the service
table constructed by application
Events
Figure 88. Read multiple characteristic value event sequence
An example implementation to apply the function bt_gattc_read_multi_charc_values():
/* BLE devices is connected, and conn_handle has been obtained from
BLE_GAP. */
bt_gattc_read_multi_charc_values_req_t req;
req.handle_length = 4;
/* The length of value handles. 4 means there
are two handles. */
uint8_t buffer[5] = {0};
/* Buffer length = 1 + handle_length. */
req.att_req = (bt_att_read_multiple_req_t *)buffer;
req.att_req->opcode = BT_ATT_OPCODE_READ_MULTIPLE_REQUEST;
req.att_req->set_of_handles[0] = 0x0003;
req.att_req->set_of_handles[1] = 0x0005;
bt_gattc_read_multi_charc_values(conn_handle, &req);
void bt_app_event_callback(bt_msg_type_t msg, bt_status_t status, void
*buff)
{
switch (msg) {
case BT_GATTC_READ_MULTI_CHARC_VALUES: {
if (status != BT_STATUS_SUCCESS) {
printf("BT_GATTC_READ_MULTI_CHARC_VALUES FINISHED!!");
© 2015 - 2017 MediaTek Inc.
Page 109 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
break;
}
bt_gattc_read_multiple_rsp_t *rsp = (bt_gattc_read_multiple_rsp_t
*)buff;
uint8_t op_code = rsp->att_rsp->opcode;
uint8_t length = rsp->length - 1;
int i;
for (i = 0; i < length; i++) {
printf("0x%02x ", rsp->att_rsp->set_of_values[i]);
}
break;
}
}
4.3.2.7.
Characteristic value write
Client
GATT
GATT
Server
bt_gattc_write_without_rsp()
There is no response from server
The stack will handle the request and give
response according to the service table
constructed by application
bt_gattc_write_charc()
BT_GATTC_WRITE_CHARC
Function call
Events
Figure 89. Characteristic value write event sequence
There are two types for write characteristic value requests to write a characteristic value no longer than the MTU,
as shown in Figure 89. More details can be found in the bt_gattc.h header file.
1) Call the function bt_gattc_wrote_without_rsp(), if the client knows the characteristic value handle
and does not need an acknowledgement that the write was successfully performed.
2) Call the function bt_gattc_write_charc(), if the client requires the status of a write request.
An example implementation of these two APIs:
/* BLE devices is connected, and conn_handle has been obtained from
BLE_GAP. */
static uint8_t buff[40] = {0};
static uint8_t *value = "TestWriteCmd";
BT_GATTC_NEW_WRITE_WITHOUT_RSP_REQ(req, buff, 0, 0x0008, value,
strlen(value));
/* 0 means it is WRITE_COMMAND, 1 means SIGNED_WRITE_COMMAND. */
bt_gattc_write_without_rsp(conn_handle, 0, &req);
/* There is no response to handle for this request. */
static uint8_t buff2[40] = {0};
© 2015 - 2017 MediaTek Inc.
Page 110 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
BT_GATTC_NEW_WRITE_CHARC_REQ(wreq, buff2, 0x0011, value, strlen(value));
bt_gattc_write_charc(conn_handle, &wreq);
void bt_app_event_callback(bt_msg_type_t msg, bt_status_t status, void
*buff)
{
switch (msg) {
case BT_GATTC_WRITE_CHARC: {
printf("bt_gattc_write_charc, status = %d!!", status);
break;
}
}
4.3.2.8.
Long characteristic value or descriptor write
Client
GATT
GATT
Server
bt_gattc_prepare_write_charc()
Prepare write request
The stack will handle the request and give
response according to the service table
constructed by application
Execute write request
BT_GATTC_WRITE_LONG_CHARC
Function call
Events
Figure 90. Long value write event sequence
Apply the function bt_gattc_prepare_write_charc(), if the length of a characteristic value or descriptor is
greater than the MTU size, as shown in Figure 90. More details can be found in the bt_gattc.h header file.
To write the complete characteristic value or descriptor, the offset should be set to 0. The Bluetooth stack will
update the offset and send a subsequent Prepare write request. The Prepare write request is repeated until
the characteristic value or descriptor is completely transferred, after which the Execute write request is used to
write the complete value.
The second parameter of bt_gattc_prepare_write_charc() is to decide whether it is a reliable write or not.
If set to 1, the Bluetooth stack will check if the value in the Prepare write response is the same as Prepare write
request, if so, it will send a subsequent Prepare write request, else, it will send Cancel the execute write
request to abort the write long procedure.
An example implementation is shown below:
/* BLE devices is connected, and conn_handle has been obtained from
BLE_GAP. */
static uint8_t *gatt_long_charc =
"ABCDEF1234567890FEDCBA098765432104134545563535";
BT_GATTC_NEW_PREPARE_WRITE_REQ(req, 0x0022, 0, gatt_long_charc,
© 2015 - 2017 MediaTek Inc.
Page 111 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
strlen(gatt_long_charc));
bt_gattc_prepare_write_charc(conn_handle, 0, 0, &req);
void bt_app_event_callback(bt_msg_type_t msg, bt_status_t status, void
*buff)
{
switch (msg) {
case BT_GATTC_WRITE_LONG_CHARC:
case BT_GATTC_RELIABLE_WRITE_CHARC: {
printf("bt_gattc_prepare_write_charc, status = %d!!", status);
break;
}
}
4.3.2.9.
Characteristic value indication
Call the function bt_gatts_send_charc_value_notification_indication(), if the server requires to
indicate a characteristic value to a client and expects an acknowledgement. The message flow is shown in Figure
91. More details can be found in the bt_gatts.h header file.
Client
GATT
Server
GATT
bt_gatts_send_charc_value_notification_indication()
BT_GATTC_CHARC_VALUE_NOTIFICATION
with opcode=
BT_ATT_OPCODE_HANDLE_VALUE_NOTIFICATION
bt_gatts_send_charc_value_notification_indication()
BT_GATTC_CHARC_VALUE_INDICATION
with opcode=
BT_ATT_OPCODE_HANDLE_VALUE_INDICATION
HANDLE_VALUE_CONFIRMATION
Function call
Events
Figure 91. Characteristic value indication event sequence
An example implementation for the server to notify and indicate a characteristic value:
/* BLE devices is connected, and conn_handle has been obtained from
BLE_GAP. */
static uint8_t buf[64] = {0};
static uint8_t *noti_value = “notification”; /* The value to notify. */
bt_gattc_charc_value_notification_indication_t *bas_noti =
(bt_gattc_charc_value_notification_indication_t *)buf;
bas_noti->att_req.opcode = BT_ATT_OPCODE_HANDLE_VALUNE_NOTIFICATION;
bas_noti->att_req.handle = 0x0013; /* The value handle to notify. */
bas_noti->attribute_value_length = strlen(noti_value);
memcpy((void *)(bas_noti->att_req.attribute_value), noti_value,
strlen(noti_value));
bt_gatts_send_charc_value_notification_indication(conn_handle, bas_noti);
static uint8_t *ind_value = “indication”; /* The value to indicate. */
bt_gattc_charc_value_notification_indication_t *bas_ind =
(bt_gattc_charc_value_notification_indication_t *)buf;
bas_ind->att_req.opcode = BT_ATT_OPCODE_HANDLE_VALUNE_INDICATION;
bas_ind ->att_req.handle = 0x0015; /* The value handle to indicate. */
© 2015 - 2017 MediaTek Inc.
Page 112 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
bas_ind ->attribute_value_length = strlen(ind_value);
memcpy((void *)( bas_ind ->att_req.attribute_value), ind_value,
strlen(ind_value));
bt_gatts_send_charc_value_notification_indication(conn_handle, bas_ind);
An example implementation for the client to handle a characteristic value notification and indication:
void bt_app_event_callback(bt_msg_type_t msg, bt_status_t status, void
*buff)
{
switch (msg) {
case BT_GATTC_CHARC_VALUE_NOTIFICATION:
case BT_GATTC_CHARC_VALUE_INDICATION: {
bt_gatt_handle_value_notification_t *rsp =
(bt_gatt_handle_value_notification_t
*)buff;
uint8_t op_code = rsp->att_rsp->opcode;
uint16_t attribute_handle = rsp->att_rsp->handle;
uint8_t length = rsp->length - 3;
int i;
printf("op_code = 0x%08x", op_code);
printf("attribute_handle = 0x%08x", attribute_handle);
for (i = 0; i < length ; i++)
printf("0x%02x ", rsp->att_rsp->attribute_value[i]);
printf("\n");
break;
}
}
© 2015 - 2017 MediaTek Inc.
Page 113 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
5.
Creating a Custom Bluetooth Application
This section guides you through creating your own Bluetooth project including:
•
Memory management for the SDK according to the application requirements.
•
Creating a task. The task provides access to the system resources such as CPU and queues. The application
can adjust task priorities to optimize the CPU usage.
•
How to interact with the SDK stack task — a special, high priority task.
•
Bluetooth panic mechanism for restoring Bluetooth function when Bluetooth works no normal.
5.1.
Memory management
5.1.1.
Memory configuration
Memory configuration of the application should be applied before the Bluetooth powers on. There are two types
of memory resources:
TX/RX buffer.
•
BT_MEMORY_TX_BUFFER — Bluetooth transmit buffer. The buffer size determines the transmit
speed and probability of out of memory (OOM) occurrence.
•
BT_MEMORY_RX_BUFFER — Bluetooth receive buffer. The buffer size determines the speed and
probability of the OOM occurrence.
Fixed size control blocks are shown in Table 5.
Table 5. Fixed size control blocks
Control block
Description
BT_MEMORY_CONTROL_BLOCK_TIMER
Control block for the timer. The maximum allocated
timer value is ACL Link number added with 3 and
normally it’s the same as the value for
BT_MEMORY_CONTROL_BLOCK_LE_CONNECTION
and
BT_MEMORY_CONTROL_BLOCK_EDR_CONNECTION
BT_MEMORY_CONTROL_BLOCK_LE_CONNECTION
Control block for LE connection. Each ACL link
allocates a portion of this memory.
BT_MEMORY_CONTROL_BLOCK_EDR_CONNECTION
Control block for EDR connection. Each ACL link
allocates a portion of this memory.
BT_MEMORY_CONTROL_BLOCK_RFCOMM
Control block for RFCOMM
BT_MEMORY_CONTROL_BLOCK_AVRCP
Control block for AVRCP
BT_MEMORY_CONTROL_BLOCK_PBAPC
Control block for PBAPC
BT_MEMORY_CONTROL_BLOCK_A2DP_SEP
Control block for A2DP SEP
BT_MEMORY_CONTROL_BLOCK_A2DP
Control block for A2DP
BT_MEMORY_CONTROL_BLOCK_HFP
Control block for HFP
BT_MEMORY_CONTROL_BLOCK_SPP
Control block for SPP
© 2015 - 2017 MediaTek Inc.
Page 114 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
The application should configure the memory for the control block, if the module is enabled. To improve memory
utilization, the SDK enables an OOM mechanism. If OOM occurs, the device operation may fail or the throughput
may slow down. To increase the performance of Bluetooth stack, application should ensure there is enough
memory allocated in TX/RX buffers.
An example implementation to configure the memory size for each memory block is shown below.
/*To configure the max EDR ACL link number, please refer to the datasheet
chapter 1.3 for the maximum link number.*/
#define BT_CONNECTION_MAX 2
#define BT_CONNECTION_BUF_SIZE \
(BT_CONNECTION_MAX*
BT_CONTROL_BLOCK_SIZE_OF_EDR_CONNECTION)
static char bt_connection_cb_buf[BT_CONNECTION_BUF_SIZE];
/*To configure the timer, the suggested value is between BT_MAX_ACL_LINK
to
BT_MAX_ACL_LINK+3 */
#define BT_TIMER_NUM 5
#define BT_TIMER_BUF_SIZE (BT_TIMER_NUM * BT_CONTROL_BLOCK_SIZE_OF_TIMER)
static char timer_cb_buf[BT_TIMER_BUF_SIZE];
/*To configure the transmit packet buffer, the vaule depends on the ACL
link and the GATT MTU size. Usually it’s difficult to send data in All ACL
links. The suggest TX buffer size is about 2~3 times the MTU size.*/
#define BT_TX_BUFFER_SIZE 256 * BT_MAX_ACL_LINK
static tx_buf[BT_TX_BUFFER_SIZE];
/*To configure the receive packet buffer, the value depends on the ACL
link and the GATT MTU size. Receive buffer may recive data from all ACL
links and advertising data. The suggested RX buffer size is more than
1Kbytes or ACL link num * MTU size) */
#define BT_RX_BUFFER_SIZE 1024 * BT_MAX_ACL_LINK
static rx_buf[BT_RX_BUFFER_SIZE];
/*To configure the max LE link number, please refer to the datasheet
chapter 1.3 for the maximum link number. */
#define BT_LE_CONNECTION_MAX 10
#define BT_LE_CONNECTION_BUF_SIZE \
(_LE_CONNECTION_MAX * BT_CONTROL_BLOCK_SIZE_OF_LE_CONNECTION)
static char le_conn_cb_buf[BT_LE_CONNECTION_BUF_SIZE];
/*To configure the rfcomm buffer size, the value of
BT_RFCOMM_TOTAL_LINK_NUM is the supported rfcomm link number*/
#define BT_RFCOMM_TOTAL_LINK_NUM 2
#define BT_RFCOMM_BUF_SIZE \
(BT_RFCOMM_TOTAL_LINK_NUM *
BT_CONTROL_BLOCK_SIZE_OF_RFCOMM)
static char bt_rfcomm_cb_buf[BT_RFCOMM_BUF_SIZE];
/*To configure the hfp buffer size, the value of BT_HFP_TOTAL_LINK_NUM is
the supported hfp link number*/
#define BT_HFP_TOTAL_LINK_NUM 2
#define BT_HFP_BUF_SIZE \
(BT_HFP_TOTAL_LINK_NUM * BT_CONTROL_BLOCK_SIZE_OF_HFP)
static char bt_hfp_cb_buf[BT_HFP_BUF_SIZE];
/*To configure the avrcp buffer size, the value of BT_AVRCP_TOTAL_LINK_NUM
© 2015 - 2017 MediaTek Inc.
Page 115 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
is the supported avrcp link number*/
#define BT_AVRCP_TOTAL_LINK_NUM 2
#define BT_AVRCP_BUF_SIZE \
(BT_AVRCP_TOTAL_LINK_NUM *
BT_CONTROL_BLOCK_SIZE_OF_AVRCP)
static char bt_avrcp_cb_buf[BT_AVRCP_BUF_SIZE];
/* To configure the a2dp streaming end point(sep) buffer size, the value
of BT_A2DP_SINK_CODEC_NUM is the supported sink codec number. The value of
BT_A2DP_SEP_TOTAL_NUM is the supoported a2dp link number *
BT_A2DP_SINK_CODEC_NUM. */
#define BT_A2DP_SINK_CODEC_NUM (2)
#define BT_A2DP_SEP_TOTAL_NUM (2 * BT_A2DP_SINK_CODEC_NUM)
#define BT_A2DP_SEP_BUF_SIZE (BT_A2DP_SEP_TOTAL_NUM *
BT_CONTROL_BLOCK_SIZE_OF_A2DP_SEP) static char
bt_a2dp_sep_cb_buf[BT_A2DP_SEP_BUF_SIZE];
/*To configure the a2dp buffer size, the value of BT_A2DP_TOTAL_LINK_NUM
is the supported a2dp link number*/
#define BT_A2DP_TOTAL_LINK_NUM 2
#define BT_A2DP_BUF_SIZE \
(BT_A2DP_TOTAL_LINK_NUM *
BT_CONTROL_BLOCK_SIZE_OF_A2DP)
static char bt_a2dp_cb_buf[BT_A2DP_BUF_SIZE];
/*To configure the spp buffer size, the value of
BT_SPP_TOTAL_CONNECTION_NUM is the supported spp total connection number*/
#define BT_SPP_TOTAL_CONNECTION_NUM 5
#define BT_SPP_BUF_SIZE \
(BT_SPP_TOTAL_CONNECTION_NUM *
BT_CONTROL_BLOCK_SIZE_OF_SPP)
static char bt_spp_cb_buf[BT_SPP_BUF_SIZE];
/*To configure the pbapc buffer size, the value of
BT_PBAPC_TOTAL_CONNECTION_NUM is the supported pbapc link number*/
#define BT_PBAPC_TOTAL_CONNECTION_NUM 2
#define BT_PBAPC_BUF_SIZE \
(BT_PBAPC_TOTAL_CONNECTION_NUM *
BT_CONTROL_BLOCK_SIZE_OF_PBAPC)
static char bt_pbapc_cb_buf[BT_PBAPC_BUF_SIZE];
void bt_mm_init(void)
{
bt_memory_init_packet(BT_MEMORY_TX_BUFFER, tx_buf, BT_TX_BUFFER_SIZE);
bt_memory_init_packet(BT_MEMORY_TX_BUFFER, tx_buf, BT_TX_BUFFER_SIZE);
bt_memory_init_control_block(BT_MEMORY_CONTROL_BLOCK_TIMER,
timer_cb_buf,
BT_TIMER_BUF_SIZE);
bt_memory_init_control_block(BT_MEMORY_CONTROL_BLOCK_LE_CONNECTION,
le_conn_cb_buf,
BT_LE_CONNECTION_BUF_SIZE);
bt_memory_init_control_block(BT_MEMORY_CONTROL_BLOCK_EDR_CONNECTION,
bt_connection_cb_buf,
BT_CONNECTION_BUF_SIZE);
bt_memory_init_control_block(BT_MEMORY_CONTROL_BLOCK_RFCOMM,
bt_rfcomm_cb_buf, BT_RFCOMM_BUF_SIZE);
bt_memory_init_control_block(BT_MEMORY_CONTROL_BLOCK_HFP,
bt_hfp_cb_buf, BT_HFP_BUF_SIZE);
© 2015 - 2017 MediaTek Inc.
Page 116 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
bt_memory_init_control_block(BT_MEMORY_CONTROL_BLOCK_AVRCP,
bt_avrcp_cb_buf, BT_AVRCP_BUF_SIZE);
bt_memory_init_control_block(BT_MEMORY_CONTROL_BLOCK_A2DP_SEP,
bt_a2dp_sep_cb_buf,
BT_A2DP_SEP_BUF_SIZE);
bt_memory_init_control_block(BT_MEMORY_CONTROL_BLOCK_A2DP,
bt_a2dp_cb_buf, BT_A2DP_BUF_SIZE);
bt_memory_init_control_block(BT_MEMORY_CONTROL_BLOCK_SPP,
bt_spp_cb_buf, BT_SPP_BUF_SIZE);
bt_memory_init_control_block(BT_MEMORY_CONTROL_BLOCK_PBAPC,
bt_pbapc_cb_buf, BT_PBAPC_BUF_SIZE);
}
int main(void)
{
/*Configure the system */
/*Configure memory of the SDK.*/
bt_mm_init();
}
5.1.2.
Out of Memory (OOM) handle
Reasons OOM occurs:
•
The control block memory is not enough. If the connect request API returns OOM, there may be not
enough memory allocated for the control block memory. The application should enlarge the control block
memory.
•
The TX memory is not enough. User can check the system log for a message, such as . If TX OOM occurs rarely, the
application can delay for a while and retry the TX request. If the error message persists, the application
should enlarge the TX buffer.
•
The RX memory is not enough. User can check the system log for a message, such as . If the RX performance is poor
due to RX OOM, the application should enlarge the RX buffer.
5.2.
Create an application task
LinkIt platform for RTOS enables to create a task at runtime. The application can create a queue or semaphore to
communicate with other tasks, as shown below.
void app_task(void *arg)
{
/*Application can implment its code here */
}
void bt_task(void * arg)
{
uint32_t i;
bt_bd_addr_t random_addr;
for(i = 0; i < 6; i++) {
* (((uint8_t*)random_addr) + i) =
© 2015 - 2017 MediaTek Inc.
Page 117 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
(uint8_t)(bt_os_layer_generate_random() & 0xFF);
}
* (((uint8_t*)random_addr) + 5) |= 0xC0;
bt_task_semaphore = bt_os_layer_create_semaphore();
//bt_os_layer_sleep_task(500);
if (arg != NULL) {
// If arg is NULL means user does not want to power on BT
bt_power_on((bt_bd_addr_ptr_t)arg,
(bt_bd_addr_ptr_t)&random_addr);
}
/* main loop */
do {
bt_os_layer_take_semaphore(bt_task_semaphore);
/* handle events */
if (BT_STATUS_SUCCESS != bt_handle_interrupt()) {
break;
}
} while (1);
}
int main(void)
{
/*first need configure hardware and system*/
/*Task API usage please refer RTOS dev guider*/
xTaskCreate(app_task, ”app_t”, 512, NULL, 1, NULL);
/*bt_task is the main function implmented in SDK that application need
use it
as entry function. After bt task running, bt will power on
automaticlly. */
xTaskCreate(bt_task, ”bt_task”, 1024, local_pulblic_addr, 5, NULL);
/*All task will truely construtor after this function executed*/
vTaskStartScheduler();
}
The default implementation of Bluetooth task entry function bt_task() is provided in bt_platform.c. A userdefined entry function implementation can also be provided in that source file. Call the function bt_task() in the
bt_platform.h as a task entry function to create a stack task. The stack size of bt_task() should be no less
than 1024 words. Call the API bt_handle_interrupt() to handle the Bluetooth stack interrupt, such as timer
and events in stack task.
5.3.
Interaction with the Bluetooth host stack
The application task can call Bluetooth APIs directly. Callback functions are invoked in the Bluetooth host stack to
process the events that are input as parameter to the callback (see Figure 92). Note, that the stack task needs to
be created by the application and the entry function should handle the Bluetooth stack interrupt.
© 2015 - 2017 MediaTek Inc.
Page 118 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
Application
bt_app_event_callback
Bluetooth API
Bluetooth Host Stack
Host-Controller Interface (HCI)
Application task flow
Bluetooth stack task flow
Figure 92. Application interaction with the Bluetooth API
5.3.1.
Calling the APIs
The LinkIt SDK provides a set of thread-safe APIs for the application task. The application can call the SDK APIs in
any task even including the stack task self. Note, that the SDK APIs run in the caller task.
void app_task(void *arg)
{
/*Application can implement the code here */
while(1) {
/*Application should make task non-block, like receive queue here*/
{
bt_bd_addr_t addr[] = {0xC3,0x01,0x02,0x03,0x05,0x11};
/*set random address API run in app task*/
bt_gap_le_set_random_address(addr);
}
}
}
5.3.2.
Processing the events
The SDK will send an event to bt_app_event_callback() which needs to be implemented in the application.
The callback will be called in the SDK task, so the application has to consider which task will process the event. It’s
recommended to send the event to its own task. Note, that if processing an event in the stack task takes too long,
© 2015 - 2017 MediaTek Inc.
Page 119 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
it may cause Bluetooth connection failure or reduce the data transmission rate. The application can use queue or
semaphore in RTOS to switch task from stack to its own task.
An example implementation on getting the event from Bluetooth stack task is shown below.
typedef struct {
uint16_t event_id
void *parameter;
} bt_app_event_t;
PRIVILEGED_DATA static QueueHandle_t bt_app_queue_p;
bt_status_t bt_app_event_callback(bt_msg_type_t msg, bt_status_t status,
void *buff){
bt_app_event_t event;
switch(msg) {
/*Handle event and convert to message sending to application
task*/
xQueueSend(bt_app_queue_p, &event, 0);
}
}
void app_task(void *arg)
{
/*Application can implment its code here */
bt_app_queue_p = xQueueCreate(20, sizeof(bt_app_event_t));
while(1) {
/*Application should make task non-block, like receive queue*/
if (xQueueReceive(bt_app_queue_p, &queue_event, portMAX_DELAY) ==
pdPASS){
/*Handle message here*/
}
}
}
5.4.
Bluetooth panic mechanism
The application will receive Bluetooth panic event from bt_app_event_callback(), in case Bluetooth host or
controller malfunction. The application should reboot the Bluetooth with the bt_power_off() and
bt_power_on() APIs to run the module successfully, as shown in the code below. It’s also required to clear
unused data or reset the state machine of the application to release all resources and reset the system to the
default state.
An example implementation to restore Bluetooth when Bluetooth panic event is received is shown below.
bool is_panic = false;
bt_status_t bt_app_event_callback(bt_msg_type_t msg, bt_status_t status,
void *buff){
switch(msg) {
case BT_PANIC: {
is_panic = true;
if (((bt_panic_t *)buff)->source == BT_PANIC_SOURCE_HOST) {
© 2015 - 2017 MediaTek Inc.
Page 120 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
/* The panic event source is Bluetooth host */
/* The application should */
/* clear unused data or reset state machine of the
application, and reboot Bluetooth (or reboot device). */
bt_power_off();
} else {
/* The panic event source is Bluetooth controller */
/* The application should */
/* clear unused data or reset state machine of the
application, and reboot Bluetooth (or reboot device). */
bt_power_off();
}
}
case BT_POWER_OFF_CNF: {
if (is_panic == true) {
bt_power_on(NULL,NULL);
}
}
case BT_POWER_ON_CNF: {
if (is_panic == true) {
is_panic = false;
/*reboot Bluetooth success, start to run application again.*/
}
}
}
}
© 2015 - 2017 MediaTek Inc.
Page 121 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
6.
Debugging and Porting Layer
6.1.
Debugging
The LinkIt SDK provides two ways to debug the application:
•
System log — provides the host information.
•
HCI log — provides the HCI communication log between host and controller.
6.1.1.
System log
The Bluetooth stack calls bt_debug_log() in the bt_debug.c source file to provide the host information.
Application can set a filter or disable logging in this function. The application can also output these logs to any
UART or USB port.
6.1.2.
HCI log
The LinkIt SDK provides HCI information by calling the bt_hci_log() function in the bt_hci_log.c source file.
The HCI information follows the standard HCI data format in Bluetooth core specification. The application can
receive this information in the bt_hci_log() function and then send the output to UART. Users can analyze the
data using standard HCI data or parse these data to a file that commercial tools like Frontline can recognize.
6.2.
Porting layer
The Bluetooth stack has flexibility to integrate with third-party RTOS APIs. These APIs can be implemented in the
source file bt_os_layer_api.c.
© 2015 - 2017 MediaTek Inc.
Page 122 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
MediaTek LinkIt™ Development
Platform for RTOS Bluetooth
Developer's Guide
7.
Appendix A: Acronyms and Abbreviations
The acronyms and abbreviations used in this developer’s guide are listed in Table 6.
Table 6. Acronyms and abbreviations
Abbreviation/Term
Expansion/Definition
GAP
Generic Access Profile defines the generic procedures related to the
discovery of Bluetooth devices and link management aspects of
connecting to Bluetooth devices. It also defines procedures related
to use of different security levels.
SM
Security Manager
GATT
Generic Attribute Profile defines a service framework using the
Attribute Protocol for discovering services and for reading and
writing characteristic value on a remote device.
MTU
The Maximum Transmission Unit (MTU) is the size of the largest
protocol data unit that the communications layer can pass onwards.
LTK
Long Term Key, is a 128-bit key used to generate the contributory
session key for an encrypted connection.
MITM
Man-in-the-middle attack is an attack where the attacker secretly
relays and possibly alters the communication between two parties
who believe they are directly communicating with each other.
STK
Short Term Key, is a 128-bit key used to encrypt a connection
following pairing.
EDIV
Encrypted Diversifier is a 16-bit stored value used to identify the LTK
distributed during the low energy legacy pairing.
IRK
Identity Resolving Key is a 128-bit key used to generate and resolve
random addresses.
CSRK
Connection Signature Resolving Key is a 128-bit key that signs data
and verifies signatures on the receiving device.
Out-Of-Band
The model is primarily designed for scenarios where an Out of Band
mechanism is used to discover the devices and to exchange or
transfer cryptographic numbers used in the pairing process.
AES
Advanced Encryption Standard
© 2015 - 2017 MediaTek Inc.
Page 123 of 123
This document contains information that is proprietary to MediaTek Inc. (“MediaTek”) and/or its licensor(s).
Any unauthorized use, reproduction or disclosure of this document in whole or in part is strictly prohibited.
Source Exif Data:
File Type : PDF File Type Extension : pdf MIME Type : application/pdf PDF Version : 1.5 Linearized : Yes Author : MediaTek Inc. Company : MediaTek Inc. Content Type Id : 0x010100C01574E716B48540A2901D80B9DAC368 Create Date : 2017:11:10 11:50:59+08:00 Keywords : "MediaTek, LinkIt, development, platform, RTOS, 7697, MT7697, MT7697D, 2523, MT2523D, MT2523G, Bluetooth, BLE, EDR, SDK, IoT, IOT, low, energy, HFP, SPP, PBAP, A2DP, AVRCP, GAP, SM, GATT; " Modify Date : 2017:11:10 11:51:20+08:00 Source Modified : D:20171110035046 Subject : This document guides you through: Support for Bluetooth Low Energy with the library description, and Bluetooth Low Energy profiles. Language : EN-US Tagged PDF : Yes XMP Toolkit : Adobe XMP Core 5.6-c015 84.159810, 2016/09/10-02:41:30 Metadata Date : 2017:11:10 11:51:20+08:00 Creator Tool : Acrobat PDFMaker 15 for Word Document ID : uuid:b4af77a1-4c90-4cd2-8d59-7e4e67b7a129 Instance ID : uuid:43d53d8f-b097-4e1f-9fe0-e2206dd17cc4 Format : application/pdf Title : MediaTek LinkIt™ Development Platform for RTOS Bluetooth Developer's Guide Description : This document guides you through: Support for Bluetooth Low Energy with the library description, and Bluetooth Low Energy profiles. Creator : MediaTek Inc. Producer : Adobe PDF Library 15.0 Headline : This document guides you through: Support for Bluetooth Low Energy with the library description, and Bluetooth Low Energy profiles. Page Layout : OneColumn Page Count : 129EXIF Metadata provided by EXIF.tools