当前位置:   article > 正文

android5.1 蓝牙子系统介绍(一)Android下bluedroid、bluetooth apk介绍_android bta

android bta

前言

本文档主要介绍android平台下bluetooth的应用层软件,先介绍bluetooth应用层的框架,接着分别介绍Bluedroid层软件、Bluetooth应用程序(Bluetooth.apk),Bluetooth framework层,最后完整分析一些蓝牙的操作流程。基于android 5.1的平台,涉及的bluetooth硬件为realtek的蓝牙。文档主要针对蓝牙的初学者,提供基础的学习指导。

1 Bluetooth应用层框架介绍

要介绍android平台bluetooth应用层的软件,首先介绍一下bluetooth的应用层整体框架,如图1为android下的bluetooth的框架。 
这里写图片描述
图1 bluetooth应用层框架 
 Applications:Android蓝牙应用程序,就是使用蓝牙的API的程序; 
 java Framework:提供给应用使用的API,我们平时使用的BluetoothAdapter,BluetoothDevice,BluetoothSocket等; 
 BluetoothAPP:这个应该也是属于java framework范畴,不过由于它比较特殊,所以独立出来,提供所有的上层服务以及与Bluedroid底层进行交互。其中btAdapter主要提供蓝牙的基本操作,比如enable, disable, discovery, pair, unpair, createRfcomm等,其他的就都是Profile的各自的Service了; 
 Bluedroid:蓝牙协议栈,提供所有蓝牙的实际操作,开关蓝牙,蓝牙的管理,搜索管理,链路管理,各种profile的实现,包括HCI,ACL,SCO,L2CAP,各种profile等; 
这里Bluedroid分为三部分: 
 BTIF(Bluetooth Interface):提供所有Bluetooth.apk需要的API(使用HAL) 
 BTA(Bluetooth Application):蓝牙应用,一般指蓝牙的Profile的Bluedroid实现。 
 Stack:实现所有蓝牙底层的操作,其中还要分为btm(Bluetooth manager),btu(Bluetooth Upper Layer)等。

2 Bluedroid软件介绍

在第一节的bluetooth应用层框架图中,已可看到bluedroid的一个架构,但bluedroid与底层的接口就没表示出来。图2为bluedroid各层交互的框架图。 
这里写图片描述

图2 bluedroid框架图 
下面再看一下bluedroid下的目录结构及每个目录的功能。 
这里写图片描述

图3 bluedroid目录结构 
 audio_a2dp_hw: Implements hal for bluedroid a2dp audio device。 a2dp在bluedroid中的hal层实现。它通过socket与stack通信(通信机制实现参考udv目录下的uipc); 
 bta:buetooth application layer,实现应用层的一些接口,但都由Btif层进行管理和调用。 
Ag:audio gateway (AG) subsystem of BTA 
Ar:implementation for the audio/video registration module. 
Av:implementation of the API for the advanced audio/video (AV) 
* subsystem of BTA, Broadcom’s Bluetooth application layer for mobile 
* phones. 
Dm:API implementation file for the BTA device manager 
Fs: implementation file for the file system call-in functions. //phone 
Gattr: the GATT server and client implementation 
Hh:host hid 
 btif:all BTIF functions accessed from main bluetooth HAL(与android的Bluetooth apk的jni层通信的接口,真正的为app提供interface的接口); 
 conf:是Bluedroid的一些配置文件; 
 embdrv: 主要负责sbc编码,SBC是由蓝牙特别兴趣组(SIG)提出的一种用于蓝牙设备标准音频编解码器的高效编码方法。在蓝牙技术的A2DP的音频数据规格中,SBC是用来保持互连能力的一个十分重要的音频数据编码方法,它是MP3和MPEG-4 AAC的规定选项; 
 gki/osi:general kernel interface/os interface,针对os的移植层,包括多任务和timer实现,实际就是为stack代码提供一个抽象的多任务和时间控制环境,达到可移植的目的; 
 hci:host control interface,实现hci的协议,并连接stack层与底层通信的实现; 
 main:处理配置信息,各个模块的初始化,连接btif与hci,提供btif控制hci的接口; 
 stack: 协议栈代码,各种profile; 
 udrv:代码作用是跟a2dp端进行socket通信,处理命令和a2dp数据pcm流,media task调用这里的接口,实际就是跟audio_a2dp_hw 的audio hal通信; 
 utils:杂项,很简单,目前就是提高a2dp任务优先级的函数; 
 vnd: vendor specific feature for BLE;

其中还有一个bt vendor没包含在bluedroid中,对于realtek的蓝牙,都是使用相同的bluedroid,但不同的蓝牙模块有不同的bt vendor库,该vendor库的功能是给蓝牙模块上、掉电,打开、关闭、配置串口,download fw(usb接口蓝牙的download fw在驱动内实现)。

2.1 Bluedroid对上层接口

Bluedroid与上层有多个接口, bluedroid\btif\src\bluetooth.c为一个主要接口,负责蓝牙的开关及基本控制, bluedroid\audio_a2dp_hw\audio_a2dp_hw.c专门针对a2dp的控制,还有部分profile也提供一些接口,这些接口为不同profile的独立接口。其中bluetooth.c实现一系列接口,由上层调用来控制蓝牙,同时在初始化的时候,上层会传递过来一个回调接口,当bluedroid有消息或结果需要通知上层时,就通过该回调接口。但像蓝牙的opp、hid等profile的数据就不是通过接口传递的,都是创建socket接口来交互数据的。

  1. \bluedroid\btif\src\bluetooth.c
  2. static const bt_interface_t bluetoothInterface = {
  3. sizeof(bluetoothInterface),
  4. init,
  5. enable,
  6. disable,
  7. get_recv_byte,
  8. get_send_byte,
  9. cleanup,
  10. get_adapter_properties,
  11. get_adapter_property,
  12. set_adapter_property,
  13. get_remote_device_properties,
  14. get_remote_device_property,
  15. set_remote_device_property,
  16. get_remote_service_record,
  17. get_remote_services,
  18. start_discovery,
  19. cancel_discovery,
  20. create_bond,
  21. remove_bond,
  22. cancel_bond,
  23. get_connection_state,
  24. pin_reply,
  25. ssp_reply,
  26. get_profile_interface,
  27. dut_mode_configure,
  28. dut_mode_send,
  29. #if BLE_INCLUDED == TRUE
  30. le_test_mode,
  31. #else
  32. NULL,
  33. #endif
  34. config_hci_snoop_log,
  35. set_os_callouts,
  36. read_energy_info,
  37. };
  38. hardware\libhardware\include\hardware\bluetooth.h
  39. typedef struct { /* 蓝牙接口结构体定义 */
  40. /** set to sizeof(bt_interface_t) */
  41. size_t size;
  42. /**
  43. * Opens the interface and provides the callback routines
  44. * to the implemenation of this interface.
  45. */
  46. int (*init)(bt_callbacks_t* callbacks );
  47. /** Enable Bluetooth. */
  48. int (*enable)(void);
  49. /** Disable Bluetooth. */
  50. int (*disable)(void);
  51. /** Get Bluetooth recv */
  52. int (*get_recv_byte)(void);
  53. …… /* 省略中间代码 */
  54. int (*read_energy_info)();
  55. } bt_interface_t;
  56. \bluedroid\btif\src\bluetooth.c
  57. static int init(bt_callbacks_t* callbacks ) /* 初始化时,上层传递下来的回调接口结构体 */
  58. {
  59. ALOGI(“init”);
  60. /* sanity check */
  61. if (interface_ready() == TRUE)
  62. return BT_STATUS_DONE;
  63. /* store reference to user callbacks */
  64. Bt_hal_cbacks = callbacks;
  65. /* add checks for individual callbacks ? */
  66. bt_utils_init();
  67. /* init btif */
  68. btif_init_bluetooth();
  69. return BT_STATUS_SUCCESS;
  70. }
  71. hardware\libhardware\include\hardware\bluetooth.h
  72. /** Bluetooth DM callback structure. */ /* 回调结构体 */
  73. typedef struct {
  74. /** set to sizeof(bt_callbacks_t) */
  75. size_t size;
  76. adapter_state_changed_callback adapter_state_changed_cb;
  77. adapter_properties_callback adapter_properties_cb;
  78. remote_device_properties_callback remote_device_properties_cb;
  79. device_found_callback device_found_cb;
  80. discovery_state_changed_callback discovery_state_changed_cb;
  81. pin_request_callback pin_request_cb;
  82. ssp_request_callback ssp_request_cb;
  83. bond_state_changed_callback bond_state_changed_cb;
  84. acl_state_changed_callback acl_state_changed_cb;
  85. callback_thread_event thread_evt_cb;
  86. dut_mode_recv_callback dut_mode_recv_cb;
  87. le_test_mode_callback le_test_mode_cb;
  88. energy_info_callback energy_info_cb;
  89. } bt_callbacks_t;
  90. 其中在get_profile_interface函数中会返回各种profile提供的接口。
  91. \bluedroid\btif\src\bluetooth.c
  92. static const void* get_profile_interface (const char *profile_id)
  93. {
  94. ALOGI("get_profile_interface %s", profile_id);
  95. /* sanity check */
  96. if (interface_ready() == FALSE)
  97. return NULL;
  98. /* check for supported profile interfaces */
  99. if (is_profile(profile_id, BT_PROFILE_HANDSFREE_ID))
  100. return btif_hf_get_interface();
  101. if (is_profile(profile_id, BT_PROFILE_HANDSFREE_CLIENT_ID))
  102. return btif_hf_client_get_interface();
  103. if (is_profile(profile_id, BT_PROFILE_SOCKETS_ID)) /* rfcomm使用 */
  104. return btif_sock_get_interface();
  105. if (is_profile(profile_id, BT_PROFILE_PAN_ID))
  106. return btif_pan_get_interface();
  107. if (is_profile(profile_id, BT_PROFILE_ADVANCED_AUDIO_ID))
  108. return btif_av_get_src_interface();
  109. if (is_profile(profile_id, BT_PROFILE_ADVANCED_AUDIO_SINK_ID))
  110. return btif_av_get_sink_interface();
  111. if (is_profile(profile_id, BT_PROFILE_HIDHOST_ID))
  112. return btif_hh_get_interface();
  113. if (is_profile(profile_id, BT_PROFILE_HEALTH_ID))
  114. return btif_hl_get_interface();
  115. if (is_profile(profile_id, BT_PROFILE_MAP_CLIENT_ID))
  116. return btif_mce_get_interface();
  117. #if ( BTA_GATT_INCLUDED == TRUE && BLE_INCLUDED == TRUE)
  118. if (is_profile(profile_id, BT_PROFILE_GATT_ID))
  119. return btif_gatt_get_interface();
  120. #endif
  121. if (is_profile(profile_id, BT_PROFILE_AV_RC_ID))
  122. return btif_rc_get_interface();
  123. if (is_profile(profile_id, BT_PROFILE_AV_RC_CTRL_ID))
  124. return btif_rc_ctrl_get_interface();
  125. return NULL;
  126. }
  127. 下面为使用rfcomm通信时的使用的接口:
  128. \bluedroid\btif\src\btif_sock.c
  129. static btsock_interface_t sock_if = {
  130. sizeof(sock_if),
  131. btsock_listen,
  132. btsock_connect
  133. };
  134. btsock_interface_t *btif_sock_get_interface()
  135. {
  136. return &sock_if;
  137. }
  138. audio_a2dp_hw.c的接口就没有看到回调函数,但audio_a2dp_hw.c中创建了2个socket接口,一个用于控制命令,一个用于a2dp数据的传输。
  139. \bluedroid\audio_a2dp_hw\audio_a2dp_hw.c
  140. static int adev_open(const hw_module_t* module, const char* name,
  141. hw_device_t** device)
  142. {
  143. …… /* 省略中间代码 */
  144. adev->device.get_parameters = adev_get_parameters;
  145. adev->device.get_input_buffer_size = adev_get_input_buffer_size;
  146. adev->device.open_output_stream = adev_open_output_stream;
  147. adev->device.close_output_stream = adev_close_output_stream;
  148. adev->device.open_input_stream = adev_open_input_stream;
  149. adev->device.close_input_stream = adev_close_input_stream;
  150. adev->device.dump = adev_dump;
  151. …… /* 省略中间代码 */
  152. static struct hw_module_methods_t hal_module_methods = {
  153. .open = adev_open,
  154. };
  155. struct audio_module HAL_MODULE_INFO_SYM = {
  156. .common = {
  157. .tag = HARDWARE_MODULE_TAG,
  158. .version_major = 1,
  159. .version_minor = 0,
  160. .id = AUDIO_HARDWARE_MODULE_ID,
  161. .name = "A2DP Audio HW HAL",
  162. .author = "The Android Open Source Project",
  163. .methods = &hal_module_methods,
  164. },
  165. };
  166. \bluedroid\audio_a2dp_hw\audio_a2dp_hw.c
  167. static int adev_open_input_stream(struct audio_hw_device *dev,
  168. audio_io_handle_t handle,
  169. audio_devices_t devices,
  170. struct audio_config *config,
  171. struct audio_stream_in **stream_in,
  172. audio_input_flags_t flags __unused,
  173. const char *address __unused,
  174. audio_source_t source __unused)
  175. {
  176. …… /* 省略中间代码 */
  177. in->stream.common.set_parameters = in_set_parameters;
  178. in->stream.common.get_parameters = in_get_parameters;
  179. in->stream.common.add_audio_effect = in_add_audio_effect;
  180. in->stream.common.remove_audio_effect = in_remove_audio_effect;
  181. in->stream.set_gain = in_set_gain;
  182. in->stream.read = in_read; /* 该函数会打开data socket */
  183. in->stream.get_input_frames_lost = in_get_input_frames_lost;
  184. /* initialize a2dp specifics */
  185. a2dp_stream_common_init(&in->common);
  186. *stream_in = &in->stream;
  187. a2dp_dev->input = in;
  188. a2dp_open_ctrl_path(&in->common);
  189. \bluedroid\audio_a2dp_hw\audio_a2dp_hw.c
  190. static void a2dp_open_ctrl_path(struct a2dp_stream_common *common)
  191. {
  192. int i;
  193. /* retry logic to catch any timing variations on control channel */
  194. for (i = 0; i < CTRL_CHAN_RETRY_COUNT; i++)
  195. {
  196. /* connect control channel if not already connected */
  197. if ((common->ctrl_fd = skt_connect(A2DP_CTRL_PATH, common->buffer_sz)) > 0)
  198. {
  199. \bluedroid\audio_a2dp_hw\audio_a2dp_hw.c
  200. static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
  201. size_t bytes)
  202. {
  203. …… /* 省略中间代码 */
  204. /* only allow autostarting if we are in stopped or standby */
  205. if ((in->common.state == AUDIO_A2DP_STATE_STOPPED) ||
  206. (in->common.state == AUDIO_A2DP_STATE_STANDBY))
  207. {
  208. pthread_mutex_lock(&in->common.lock);
  209. if (start_audio_datapath(&in->common) < 0)
  210. \bluedroid\audio_a2dp_hw\audio_a2dp_hw.c
  211. static int start_audio_datapath(struct a2dp_stream_common *common)
  212. {
  213. …… /* 省略中间代码 */
  214. /* connect socket if not yet connected */
  215. if (common->audio_fd == AUDIO_SKT_DISCONNECTED)
  216. {
  217. common->audio_fd = skt_connect(A2DP_DATA_PATH, common->buffer_sz);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235

2.2 Bluedroid中HCI层接口

Hci层处于bluedroid架构的最下面,向下与bt-vendor、内核交互,向上与bluedroid核心层交互。

2.2.1 Bluedroid中HCI与bt-vendor接口

Bluedroid与下层的交互接口全由hci目录的代码实现,在vendor.c文件中加载bt-vendor库,使用bt-vendor提供的接口,并把一个回调结构体传递给bt-vendor。

  1. \bluedroid\hci\src\vendor.c
  2. static const char *VENDOR_LIBRARY_NAME = "libbt-vendor.so"; /* 固定的bt-vendor库名 */
  3. bool vendor_open(const uint8_t *local_bdaddr) {
  4. assert(lib_handle == NULL);
  5. lib_handle = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW);
  6. if (!lib_handle) {
  7. ALOGE("%s unable to open %s: %s", __func__, VENDOR_LIBRARY_NAME, dlerror());
  8. goto error;
  9. }
  10. vendor_interface = (bt_vendor_interface_t *)dlsym(lib_handle, VENDOR_LIBRARY_SYMBOL_NAME);
  11. if (!vendor_interface) {
  12. ALOGE("%s unable to find symbol %s in %s: %s", __func__, VENDOR_LIBRARY_SYMBOL_NAME, VENDOR_LIBRARY_NAME, dlerror());
  13. goto error;
  14. }
  15. /* 调用bt-vendor的初始化并传递回调结构体 */
  16. int status = vendor_interface->init(&vendor_callbacks, (unsigned char *)local_bdaddr);
  17. \bluedroid\hci\include\bt_vendor_lib.h
  18. typedef struct { /* bt-vendor提供的3个接口 */
  19. /** Set to sizeof(bt_vndor_interface_t) */
  20. size_t size;
  21. /**
  22. * Caller will open the interface and pass in the callback routines
  23. * to the implemenation of this interface.
  24. */
  25. int (*init)(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr);
  26. /** Vendor specific operations */
  27. int (*op)(bt_vendor_opcode_t opcode, void *param);
  28. /** Closes the interface */
  29. void (*cleanup)(void);
  30. } bt_vendor_interface_t;
  31. \bluedroid\hci\src\vendor.c
  32. static const bt_vendor_callbacks_t vendor_callbacks = { /* hci传递给bt-vendor的回调结构体 */
  33. sizeof(vendor_callbacks),
  34. firmware_config_cb,
  35. sco_config_cb,
  36. low_power_mode_cb,
  37. sco_audiostate_cb,
  38. buffer_alloc,
  39. buffer_free,
  40. transmit_cb,
  41. epilog_cb
  42. };
  43. Bt-vendor库中,init和cleanup函数只是做开始时初始化及退出时清理的工作,主要工作都在op函数中实现。
  44. \modules\rtl8723bs\libbt\src\bt_vendor_rtk.c
  45. static int op(bt_vendor_opcode_t opcode, void *param)
  46. {
  47. switch(opcode)
  48. {
  49. case BT_VND_OP_POWER_CTRL:
  50. …… /* 省略中间代码 */ /* 控制蓝牙模块的上掉电 */
  51. break;
  52. case BT_VND_OP_FW_CFG:
  53. /* uart接口蓝牙加载fw */
  54. /* usb接口蓝牙fw在驱动中加载,蓝牙上电时就自动加载,这里直接返回成功 */
  55. …… /* 省略中间代码 */
  56. break;
  57. case BT_VND_OP_SCO_CFG:
  58. …… /* 省略中间代码 */
  59. break;
  60. case BT_VND_OP_USERIAL_OPEN:
  61. /* 打开uart口,把打开的fd传回给hci层。无论是uart接口蓝牙,还是usb接口蓝牙(usb接口蓝牙在驱动层虚拟出一个uart口),对bt-vendor层都是打开一个串口,所以从bluedroid层看,与底层的数据收发就是对uart口的收发 */
  62. …… /* 省略中间代码 */
  63. break;
  64. case BT_VND_OP_USERIAL_CLOSE:
  65. …… /* 省略中间代码 */ /* 关闭uart口 */
  66. break;
  67. case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
  68. …… /* 省略中间代码 */
  69. break;
  70. case BT_VND_OP_LPM_SET_MODE:
  71. …… /* 省略中间代码 */
  72. break;
  73. case BT_VND_OP_LPM_WAKE_SET_STATE:
  74. …… /* 省略中间代码 */
  75. break;
  76. case BT_VND_OP_EPILOG:
  77. …… /* 省略中间代码 */
  78. break;
  79. }
  80. \bluedroid\hci\src\userial.c
  81. bool userial_open(userial_port_t port) {
  82. /* hci层调用bt-vendor层打开uart口,返回uart口句柄,hci层对数据的收发就使用该句柄 */
  83. …… /* 省略中间代码 */
  84. int num_ports = vendor_send_command(BT_VND_OP_USERIAL_OPEN, &fd_array);
  85. if (num_ports != 1) {
  86. ALOGE("%s opened wrong number of ports: got %d, expected 1.", __func__, num_ports);
  87. goto error;
  88. }
  89. userial_cb.fd = fd_array[0];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100

2.2.2 Bluedroid中HCI层协议

Hci层有两个功能,一个为实现hci层协议,就是所见的h4、h5协议,另一个为连接stack层与bt-vendor层,实现stack层与硬件的通信传递。 
HCI有4种分组类型(有资料介绍通过uart传输时,还有错误消息分组和协商分组,但从现在的代码看,都没有使用了,只是增加了厂商自定义的操作码,用于发送错误消息或协商通信等),分组类型如表1,4种分组的数据格式如图4~图7。

表1 HCI封包类型 
这里写图片描述
这里写图片描述 
这里写图片描述 
HCI本身的分组是不带包类型识别头的,在传输的时候就需要双方能识别出传输的分组类型,h4的协议就是在hci分组前增加一个字节的用于区别分组类型,现在使用的boardcom的蓝牙就是使用h4协议通过uart传输。从上面的各种分组结构看,都没有唯一的识别标志,在通过uart传输时,由于共用一个通道,就有数据同步问题,否则就无法找到分组头及解析数据分组。所以h4协议使用uart传输时,就需要有Error Recovery机制,只要通信双方有一个丢失同步,就需要进行同步恢复。如果h4协议使用usb传输,就不会存在该问题,usb通过不同的端点传输不同的分组类型,并且usb协议可以保证分组的完整。由于h4使用uart传输存在同步问题,后面有了h5协议,h5协议其实就是把h4协议的包重新封装一下,加入字符转换来实现唯一的分组头、分组尾标识,同时加入完整性校验,这样,即使一个分组数据出错了,下一个分组数据还是能正确解析的,不需要什么同步恢复机制。H5的封包如图8~图10。 
这里写图片描述 
从上面可以看出,H5协议比H4协议在可靠性方面有增强,但同时需要处理的工作量也增多了,所以H5的传输效率会比H4低一些。 
H4或H5的协议都提供相同的使用接口,HCI层实际使用哪种协议,现在bluedroid的做法是在代码编译的时候就固定的,如下面代码所示。

  1. \bluedroid\hci\src\bt_hci_bdroid.c
  2. static int init(const bt_hc_callbacks_t* p_cb, unsigned char *local_bdaddr)
  3. {
  4. …… /* 省略中间代码 */
  5. vendor_open(local_bdaddr); /* 加载bt-vendor库 */
  6. utils_init();
  7. #ifdef HCI_USE_MCT
  8. extern tHCI_IF hci_mct_func_table;
  9. p_hci_if = &hci_mct_func_table;
  10. #elif defined HCI_USE_RTK_H5
  11. extern tHCI_IF hci_h5_func_table;
  12. p_hci_if = &hci_h5_func_table; /* 使用h5协议 */
  13. #else
  14. extern tHCI_IF hci_h4_func_table;
  15. p_hci_if = &hci_h4_func_table; /* 使用h4协议 */
  16. #endif
  17. \bluedroid\hci\include\hci.h
  18. typedef struct { /* h4,h5的结构体 */
  19. tHCI_INIT init;
  20. tHCI_CLEANUP cleanup;
  21. tHCI_SEND send; /* 发送接口 */
  22. tHCI_SEND_INT send_int_cmd; /* 为厂商专用发送接口 */
  23. tHCI_ACL_DATA_LEN_HDLR get_acl_max_len;
  24. #ifdef HCI_USE_MCT
  25. tHCI_RCV evt_rcv;
  26. tHCI_RCV acl_rcv;
  27. #else
  28. tHCI_RCV rcv; /* 接收接口 */
  29. #endif
  30. } tHCI_IF;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

2.2.3 Bluedroid中HCI与核心层接口

Hci层与bluedroid的核心层的交互接口,也是通过把接口封装在一个结构体提供给核心层,同时核心层提供一个回调的结构体。

  1. \bluedroid\hci\src\bt_hci_bdroid.c
  2. static const bt_hc_interface_t bluetoothHCLibInterface = {
  3. sizeof(bt_hc_interface_t),
  4. init, /* 加载bt-vendor库,选择使用的hci层协议 */
  5. set_power, /* 蓝牙上掉电控制 */
  6. lpm,
  7. preload, /* 打开uart,加载fw */
  8. postload,
  9. transmit_buf, /* 发送数据 */
  10. logging,
  11. cleanup,
  12. tx_hc_cmd,
  13. };
  14. const bt_hc_interface_t *bt_hc_get_interface(void) /* 获取hci接口的结构体 */
  15. {
  16. return &bluetoothHCLibInterface;
  17. }
  18. \bluedroid\main\bte_main.c
  19. static void bte_main_in_hw_init(void)
  20. {
  21. if ( (bt_hc_if = (bt_hc_interface_t *) bt_hc_get_interface()) \
  22. == NULL)
  23. …… /* 省略中间代码 */
  24. static void bte_hci_enable(void)
  25. {
  26. APPL_TRACE_DEBUG("%s", __FUNCTION__);
  27. preload_start_wait_timer();
  28. if (bt_hc_if)
  29. {
  30. /* 初始化hci接口,传递回调结构体 */
  31. int result = bt_hc_if->init(&hc_callbacks, btif_local_bd_addr.address);
  32. \bluedroid\hci\include\bt_hci_lib.h
  33. typedef struct {
  34. /** set to sizeof(bt_hc_callbacks_t) */
  35. size_t size;
  36. /* notifies caller result of preload request */
  37. preload_result_cb preload_cb;
  38. /* notifies caller result of postload request */
  39. postload_result_cb postload_cb;
  40. /* notifies caller result of lpm enable/disable */
  41. lpm_result_cb lpm_cb;
  42. /* notifies hardware on host wake state */
  43. hostwake_ind_cb hostwake_ind;
  44. /* buffer allocation request */
  45. alloc_mem_cb alloc;
  46. /* buffer deallocation request */
  47. dealloc_mem_cb dealloc;
  48. /* notifies stack data is available */
  49. data_ind_cb data_ind; /* hci层往上提交数据接口 */
  50. /* notifies caller when a buffer is transmitted (or failed) */
  51. tx_result_cb tx_result;
  52. } bt_hc_callbacks_t;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

2.2.4 Bluedroid中HCI层流程例子

如图11为HCI层初始化的流程,包含接口的初始化,给蓝牙上电,打开串口,加载fw,由于加载fw过程涉及多重回调,没放到下面的框图。

这里写图片描述 
这里写图片描述 
这里写图片描述

2.3 Bluedroid的核心层

Bluedroid的核心层负责蓝牙的管理,蓝牙协议的处理,状态的管理等,整个核心层的运行都是由事件驱动的,由上层发送的事件,底层处理结果的事件,底层接收数据的事件,底层状态变化的事件,加上定时器的超时事件,维护着整个核心层的正常运行。由于蓝牙核心层还不能很好理清流程及整理一个直观的框图,这里没给出核心层的架构图,后面从代码流程及整体的运行流程从侧面了解一下核心层的架构。

2.3.1 Bluedroid核心层的启动

Bluedroid的整个功能及运行,都是从enable Bluetooth开始,到disable Bluetooth结束。

  1. \bluedroid\btif\src\bluetooth.c
  2. static int init(bt_callbacks_t* callbacks )
  3. {
  4. …… /* 省略中间代码 */
  5. bt_utils_init();
  6. /* init btif */
  7. btif_init_bluetooth();
  8. return BT_STATUS_SUCCESS;
  9. }
  10. \bluedroid\btif\src\btif_core.c
  11. bt_status_t btif_init_bluetooth()
  12. {
  13. UINT8 status;
  14. btif_config_init(); /* 配置初始化 */
  15. bte_main_boot_entry(); /* Entry point for BTE chip/stack initialization */
  16. /* As part of the init, fetch the local BD ADDR */
  17. memset(&btif_local_bd_addr, 0, sizeof(bt_bdaddr_t));
  18. btif_fetch_local_bdaddr(&btif_local_bd_addr);
  19. /* start btif task */
  20. status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR,
  21. (UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE),
  22. sizeof(btif_task_stack));
  23. if (status != GKI_SUCCESS)
  24. return BT_STATUS_FAIL;
  25. return BT_STATUS_SUCCESS;
  26. }
  27. \bluedroid\btif\src\bluetooth.c
  28. static int enable( void )
  29. {
  30. ALOGI("enable");
  31. /* sanity check */
  32. if (interface_ready() == FALSE)
  33. return BT_STATUS_NOT_READY;
  34. return btif_enable_bluetooth();
  35. }
  36. \bluedroid\btif\src\btif_core.c
  37. bt_status_t btif_enable_bluetooth(void)
  38. {
  39. …… /* 省略中间代码 */
  40. /* Create the GKI tasks and run them */
  41. bte_main_enable();
  42. return BT_STATUS_SUCCESS;
  43. }
  44. \bluedroid\main\bte_main.c
  45. void bte_main_enable()
  46. {
  47. APPL_TRACE_DEBUG("%s", __FUNCTION__);
  48. /* Initialize BTE control block */
  49. BTE_Init();
  50. lpm_enabled = FALSE;
  51. GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,
  52. (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),
  53. sizeof(bte_btu_stack));
  54. bte_hci_enable(); /* 初始化hci层接口,上一节内容 */
  55. GKI_run();
  56. }
  57. \bluedroid\stack\btu\btu_task.c
  58. BTU_API UINT32 btu_task (UINT32 param) /* 初始化工作及进行消息处理 */
  59. {
  60. …… /* 省略中间代码 */
  61. /* Initialize the mandatory core stack control blocks
  62. (BTU, BTM, L2CAP, and SDP)
  63. */
  64. btu_init_core();
  65. /* Initialize any optional stack components */
  66. BTE_InitStack();
  67. #if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)
  68. bta_sys_init();
  69. #endif
  70. /* Initialise platform trace levels at this point as BTE_InitStack() and bta_sys_init()
  71. * reset the control blocks and preset the trace level with XXX_INITIAL_TRACE_LEVEL
  72. */
  73. #if ( BT_USE_TRACES==TRUE )
  74. BTE_InitTraceLevels();
  75. #endif
  76. /* Send a startup evt message to BTIF_TASK to kickstart the init procedure */
  77. GKI_send_event(BTIF_TASK, BT_EVT_TRIGGER_STACK_INIT);
  78. prctl(PR_SET_NAME, (unsigned long)"BTU TASK", 0, 0, 0);
  79. raise_priority_a2dp(TASK_HIGH_BTU);
  80. /* Wait for, and process, events */
  81. for (;;)
  82. \bluedroid\btif\src\btif_core.c
  83. void btif_enable_bluetooth_evt(tBTA_STATUS status, BD_ADDR local_bd)
  84. { /* Bluetooth enable完成时收到事件,会调用该函数 */
  85. …… /* 省略中间代码 */
  86. bte_main_postload_cfg();
  87. #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
  88. bte_main_enable_lpm(TRUE);
  89. #endif
  90. /* add passing up bd address as well ? */
  91. /* callback to HAL */
  92. if (status == BTA_SUCCESS)
  93. {
  94. /* initialize a2dp service */
  95. btif_av_init();
  96. /* init rfcomm & l2cap api */
  97. btif_sock_init();
  98. /* init pan */
  99. btif_pan_init();
  100. /* load did configuration */
  101. bte_load_did_conf(BTE_DID_CONF_FILE);
  102. \bluedroid\btif\src\btif_av.c
  103. bt_status_t btif_av_init()
  104. {
  105. if (btif_av_cb.sm_handle == NULL)
  106. {
  107. if (btif_a2dp_start_media_task() != GKI_SUCCESS)
  108. return BT_STATUS_FAIL;
  109. btif_enable_service(BTA_A2DP_SERVICE_ID);
  110. /* Also initialize the AV state machine */
  111. btif_av_cb.sm_handle = btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);
  112. btif_a2dp_on_init();
  113. \bluedroid\btif\src\btif_media_task.c
  114. int btif_a2dp_start_media_task(void)
  115. {
  116. …… /* 省略中间代码 */
  117. /* start a2dp media task */
  118. retval = GKI_create_task((TASKPTR)btif_media_task, A2DP_MEDIA_TASK,
  119. A2DP_MEDIA_TASK_TASK_STR,
  120. (UINT16 *) ((UINT8 *)a2dp_media_task_stack + A2DP_MEDIA_TASK_STACK_SIZE),
  121. sizeof(a2dp_media_task_stack));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149

前面说到整个蓝牙核心层由事件驱动,所有事件的处理全部由3个task来完成。 
btu_task:处理发送给上层的事件,定时器超时事件,部分上层发送下来的事件,同时也会把部分事件转给btif_task处理; 
btif_task:主要用于蓝牙协议处理,处理协议状态的流转,根据不同状态调用不同的处理函数; 
btif_media_task:用于a2dp的控制及音频处理;

2.3.2 Bluedroid核心层部分profile的流程

对于A2DP的流程,只给出概要框图,如下图所示。

这里写图片描述 
对于opp文件传输,在bluedroid层就是使用rfcomm协议,rfcomm协议实质就是在两个蓝牙设备之间提供一条逻辑的数据通道,上层只需要使用rfcomm提供的链路就可以在两个蓝牙设备之间传递数据。Opp文件传输过程,先是两个设备进行连接,然后建立一条rfcomm通道,同时创建rfcomm与上层传输数据的socket,后面就可以进行数据传输,设备的连接、rfcomm通道的建立在后面介绍。 
对于蓝牙鼠标、蓝牙键盘这些输入设备,使用的是hid(human interface Device)profile,建立连接后,注册一个uhid(dev_path = “/dev/uhid”)设备,把输入设备发送过来的数据发给uhid设备,由内核的hid驱动负责进行输入事件的处理,下图给出一个输入数据的流程框图。

3 Bluetooth应用程序介绍(Bluetooth.apk)

Bluetooth应用程序的主要功能是负责蓝牙状态的管理,连接bluedroid,提供各种蓝牙服务。其中btservice提供蓝牙基本服务,各个profile提供自身独立的服务,除了opp和pabp自成一体外,其它的profile由btservice管理。

3.1 Bluetooth应用程序框图及对外的接口

由于opp与pbap实质都是文件传输,但涉及UI交互操作等,作为两个相对独立的service存在,后面给出opp的一个框架。

这里写图片描述

这里写图片描述

3.2 Bluetooth应用程序与bluedroid的接口

Bluetooth app与bluedroid通过jni接口交互,bluetooth app在开始时加载bluedroid库(bluetooth.default.so),使用bluedroid提供的操作接口,同时在调用bluedroid接口提供的init函数时,传递回调结构体给bluedroid。

  1. packages\apps\bluetooth\jni\com_android_bluetooth_btservice_AdapterService.cpp
  2. jint JNI_OnLoad(JavaVM *jvm, void *reserved)
  3. {
  4. …… /* 省略中间代码 */
  5. if ((status = android::register_com_android_bluetooth_btservice_AdapterService(e)) < 0) {
  6. ALOGE("jni adapter service registration failure, status: %d", status);
  7. return JNI_ERR;
  8. }
  9. if ((status = android::register_com_android_bluetooth_hfp(e)) < 0) {
  10. ALOGE("jni hfp registration failure, status: %d", status);
  11. return JNI_ERR;
  12. }
  13. if ((status = android::register_com_android_bluetooth_hfpclient(e)) < 0) {
  14. ALOGE("jni hfp client registration failure, status: %d", status);
  15. return JNI_ERR;
  16. }
  17. if ((status = android::register_com_android_bluetooth_a2dp(e)) < 0) {
  18. ALOGE("jni a2dp source registration failure: %d", status);
  19. return JNI_ERR;
  20. }
  21. if ((status = android::register_com_android_bluetooth_a2dp_sink(e)) < 0) {
  22. ALOGE("jni a2dp sink registration failure: %d", status);
  23. return JNI_ERR;
  24. }
  25. if ((status = android::register_com_android_bluetooth_avrcp(e)) < 0) {
  26. ALOGE("jni avrcp target registration failure: %d", status);
  27. return JNI_ERR;
  28. }
  29. if ((status = android::register_com_android_bluetooth_avrcp_controller(e)) < 0) {
  30. ALOGE("jni avrcp controller registration failure: %d", status);
  31. return JNI_ERR;
  32. }
  33. if ((status = android::register_com_android_bluetooth_hid(e)) < 0) {
  34. ALOGE("jni hid registration failure: %d", status);
  35. return JNI_ERR;
  36. }
  37. if ((status = android::register_com_android_bluetooth_hdp(e)) < 0) {
  38. ALOGE("jni hdp registration failure: %d", status);
  39. return JNI_ERR;
  40. }
  41. if ((status = android::register_com_android_bluetooth_pan(e)) < 0) {
  42. ALOGE("jni pan registration failure: %d", status);
  43. return JNI_ERR;
  44. }
  45. if ((status = android::register_com_android_bluetooth_gatt(e)) < 0) {
  46. ALOGE("jni gatt registration failure: %d", status);
  47. return JNI_ERR;
  48. }
  49. packages\apps\bluetooth\jni\com_android_bluetooth_btservice_AdapterService.cpp
  50. static JNINativeMethod sMethods[] = { /* 各个Native接口 */
  51. /* name, signature, funcPtr */
  52. {"classInitNative", "()V", (void *) classInitNative},
  53. {"initNative", "()Z", (void *) initNative},
  54. {"cleanupNative", "()V", (void*) cleanupNative},
  55. {"enableNative", "()Z", (void*) enableNative},
  56. {"disableNative", "()Z", (void*) disableNative},
  57. {"getRecvByteNative", "()I", (void*) getRecvByteNative},
  58. {"getSendByteNative", "()I", (void*) getSendByteNative},
  59. {"setAdapterPropertyNative", "(I[B)Z", (void*) setAdapterPropertyNative},
  60. {"getAdapterPropertiesNative", "()Z", (void*) getAdapterPropertiesNative},
  61. {"getAdapterPropertyNative", "(I)Z", (void*) getAdapterPropertyNative},
  62. {"getDevicePropertyNative", "([BI)Z", (void*) getDevicePropertyNative},
  63. {"setDevicePropertyNative", "([BI[B)Z", (void*) setDevicePropertyNative},
  64. {"startDiscoveryNative", "()Z", (void*) startDiscoveryNative},
  65. {"cancelDiscoveryNative", "()Z", (void*) cancelDiscoveryNative},
  66. {"createBondNative", "([BI)Z", (void*) createBondNative},
  67. {"removeBondNative", "([B)Z", (void*) removeBondNative},
  68. {"cancelBondNative", "([B)Z", (void*) cancelBondNative},
  69. {"getConnectionStateNative", "([B)I", (void*) getConnectionStateNative},
  70. {"pinReplyNative", "([BZI[B)Z", (void*) pinReplyNative},
  71. {"sspReplyNative", "([BIZI)Z", (void*) sspReplyNative},
  72. {"getRemoteServicesNative", "([B)Z", (void*) getRemoteServicesNative},
  73. {"getRemoteMasInstancesNative", "([B)Z", (void*) getRemoteMasInstancesNative},
  74. {"connectSocketNative", "([BI[BII)I", (void*) connectSocketNative},
  75. {"createSocketChannelNative", "(ILjava/lang/String;[BII)I",
  76. (void*) createSocketChannelNative},
  77. {"configHciSnoopLogNative", "(Z)Z", (void*) configHciSnoopLogNative},
  78. {"alarmFiredNative", "()V", (void *) alarmFiredNative},
  79. {"readEnergyInfo", "()I", (void*) readEnergyInfo},
  80. };
  81. int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env)
  82. {
  83. return jniRegisterNativeMethods(env, "com/android/bluetooth/btservice/AdapterService",
  84. sMethods, NELEM(sMethods));
  85. }
  86. packages\apps\bluetooth\jni\com_android_bluetooth_btservice_AdapterService.cpp
  87. static bool initNative(JNIEnv* env, jobject obj) {
  88. ALOGV("%s:",__FUNCTION__);
  89. sJniAdapterServiceObj = env->NewGlobalRef(obj);
  90. sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
  91. if (sBluetoothInterface) {
  92. int ret = sBluetoothInterface->init(&sBluetoothCallbacks); /* 传递给bluedroid的回调接口 */
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95

3.3 Bluetooth 的状态图

整个bluetooth存在多个状态机,除了有维护蓝牙开关的状态机及设备配对状态,还有部分profile使用状态机维护设备的连接状态。

这里写图片描述 
这里写图片描述 
蓝牙Bond状态说明:

  1. /**
  2. * Indicates the remote device is not bonded (paired).
  3. * <p>There is no shared link key with the remote device, so communication
  4. * (if it is allowed at all) will be unauthenticated and unencrypted.
  5. */
  6. public static final int BOND_NONE = 10;
  7. /**
  8. * Indicates bonding (pairing) is in progress with the remote device.
  9. */
  10. public static final int BOND_BONDING = 11;
  11. /**
  12. * Indicates the remote device is bonded (paired).
  13. * <p>A shared link keys exists locally for the remote device, so
  14. * communication can be authenticated and encrypted.
  15. * <p><i>Being bonded (paired) with a remote device does not necessarily
  16. * mean the device is currently connected. It just means that the pending
  17. * procedure was completed at some earlier time, and the link key is still
  18. * stored locally, ready to use on the next connection.
  19. * </i>
  20. */
  21. public static final int BOND_BONDED = 12;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
例如:
  • 1
  • 2
  • 1
  • 2

 两台平板配对,配对完成后,处于已配对状态,但还不是连接的状态,当需要传输文件时,才建立连接,文件传输完成后,连接会断开。 
 当平板与蓝牙耳机或蓝牙输入设备(蓝牙鼠标、键盘)配对时,配对完成后,马上会建立连接,这是由于蓝牙耳机或输入设备随时有数据传输。

这里写图片描述

3.4 Bluetooth 部分操作的流程图

这里写图片描述
这里写图片描述

4 Bluetooth framework层介绍

Bluetooth framework层的作用只要是连接bluetooth service,为其它应用提供使用蓝牙的接口,起连接上下层的作用,没有太多的逻辑,下面只给出概要框图,不做过多描述。 
这里写图片描述

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zjli321/article/details/52402968

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/326567
推荐阅读
相关标签
  

闽ICP备14008679号