Android Bluetooth(一) — 蓝牙模块代码整体架构

0. 前言

  我之前提过,我目前接触的最多的Android 版本是 Android kk(4.4)与Android P(9.0),因为最近在Android kk上做了一个wifi模组的移植适配工作,因此对WiFi&BT模块有了些了解,本系列主要基于Android kk进行了解分析,也许其他版本有些出入,但不影响我们理解主要流程,蓝牙工作的主干流程是没有变的,上电、加载驱动这些动作少不了的,只是这些功能的实现代码位置变了不少。希望本文可以让大家对android 4.4的蓝牙部分代码有一个初步的了解。

  入手一个新的模块或应用,当然首先要知道它都有什么了,与它相关的代码在那里,所以先一起看下蓝牙代码分布吧。

1. 代码分布

  • packages/apps/settings/
    settings下面有BluetoothUI部分代码。主要负责蓝牙的开/关和蓝牙设备查找等。
  • packages/apps/Bluetooth/
    看这路径肯定是蓝牙应用方面的代码了,主要是关于蓝牙应用协议的表现代码,包括opp、hfp、hdp、a2dp、pan等等,这些名词后面再解释
    编译出来便是蓝牙的Bluetooth.apk文件,提供上层服务和底层交互。这个目录里的代码更像一个桥梁承上启下的作用,承上:通过Binder和framework/base/core/java/android/bluetooth蓝牙服务通信。启下:通过 JNI和external/bluetooth/blueroid蓝牙协议通信。
  • frameworks/base/core/java/android/server/
    4.2以后这个目录虽然还有了,但里面代码已经转移到应用层了,就是前面那个目录,所以4.2.2上的蓝牙这里可以忽略。
  • framework/base/core/java/android/bluetooth
    这个目录里面有供java层使用一些类,也有对应的aidl文件联系C、C++部分的代码,还是挺重要的。
  • kernel\drivers\bluetooth Bluetooth
    具体协议实现。包括hci,hid,rfcomm,sco,SDP等协议
  • kernel\net\bluetooth Linux kernel
    对各种接口的Bluetoothdevice的驱动。例如:USB接口,串口等,上面kernel这两个目录有可能看不到的,但一定会有的。
  • external\bluetooth\bluedroid 官方蓝牙协议栈。相当于蓝牙HAL操作。供所有蓝牙的实际操作,开关蓝牙,HCI,ACL,SCO,L2CAP,RFComm,蓝牙的所有Profile等。
  • system\bluetoothBluetooth 适配层代码,和framework那个作用类似,是串联framework与blueZ的工具。

  大致代码分布就是这些,协议栈的代码也可包含在模组商提供的蓝牙驱动代码里,这些代码可能因为项目的原因放置在不同路径里,但是应该都存在,不会缺少,初步查看后让我们再来看下蓝牙的整体结构。

2. 整体结构

在这里插入图片描述

  1. Applications是蓝牙相关的上层应用UI部分,这里我们主要分析 Settings APP下面有关蓝牙的部分。

  2. Java Framework主要是蓝牙服务的API 接口,提供给Settings APP下蓝牙设置调用。

  3. Bluetooth APP是 packages/apps/Bluetooth/ 下面的代码,提供蓝牙的核心服务,主要是通过JNI 调用 Bluedroid 蓝牙协议栈。

  4. Bluedroid 蓝牙协议栈,是external\bluetooth\bluedroid下面的代码,实现了具体蓝牙打开,关闭,查找等功能。

3. 常用类和名词解释

  1. \packages\apps\Settings\src\com\android\settings\bluetooth

    • BluetoothEnabler.java 界面上蓝牙开启、关闭的开关就是它了,
    • BluetoothSettings.java 主界面,用于管理配对和连接设备
    • LocalBluetoothManager.java 提供了蓝牙API上的简单调用接口,这里只是开始。
    • CachedBluetoothDevice.java 描述蓝牙设备的类,对BluetoothDevice的再封装
    • BluetoothPairingDialog.java 那个配对提示的对话框
  2. /packages/apps/Phone/src/com/android/phone/

    • BluetoothPhoneService.java 在phone的目录肯定和电话相关了,蓝牙接听挂断电话会用到这个
  3. /packages/apps/Bluetooth/src/com/android/bluetooth/btservice/

    • AdapterService.java 4.2后才有的代码,蓝牙打开、关闭、扫描、配对都会走到这里,其实更准确的说它替代了4.1之前的BluetoothService.java,原来的工作就由这个类来完成了。说到这里不能不说4.2蓝牙的目录变了,在4.1及以前的代码中packages层的代码只有opp协议相关应用的代码,也就是文件传输那部分,而4.2的代码应用层的代码则丰富了许多,按具体的蓝牙应用协议来区别,分为以下文件夹(这里一并对蓝牙一些名词作个简单解释):

      • a2dp 蓝牙立体声,和蓝牙耳机听歌有关那些,另还有个avrcp–音频/视频远程控制配置文件,是用来听歌时暂停,上下歌曲选择的。
      • btservice 这个前面AdapterService.java的描述大家应该能猜到一些,关于蓝牙基本操作的目录,一切由此开始。
      • hdp 蓝牙关于医疗方面的应用 Bluetooth Health Device Profile
      • hfp 和电话相关,蓝牙接听、挂断电话 Hands-free Profile
      • hid 人机交互接口,蓝牙鼠标键盘什么的就是这个了
      • opp 不多解释,以前就有。
      • pan 描述了两个或更多个 Bluetooth 设备如何构成一个即时网络,和网络有关的还有串行端口功能(SPP),拨号网络功能(DUN)
      • pbap 电话号码簿访问协议(Phonebook Access Profile)

  android 4.4的蓝牙应用层部分代码更丰富了,虽然有些目录还没具体代码,不过说不准哪个版本更新就有了,就像4.0添加了hdp医疗那部分一样。

  另外原本在framework的JNI代码也被移到packages/apps/bluetooth当中。

  1. /frameworks/base/core/java/android/bluetooth/

    • BluetoothA2dp.java A2DP的功能实现
    • BluetoothAdapter.java 蓝牙action的定义,虚拟设备属性以及操作方法
    • BluetoothAudioGateway.java 蓝牙语音网关
    • BluetoothClass.java 蓝牙设备类型的定义
    • BluetoothDevice.java 蓝牙设备属性
    • BluetoothDevicePicker.java 定义远程蓝牙设备的特性,比如需要认证,设备类型
    • BluetoothHeadset.java 定义蓝牙headset功能的属性以及接口
    • BluetoothInputStream.java 蓝牙流接口的实现(输入流)
    • BluetoothOutputStream.java 蓝牙流接口的实现(输出流)
    • BluetoothServerSocket.java 蓝牙socket服务端具备的方法
    • BluetoothSocket.java 蓝牙socket的封装
    • BluetoothUuid.java 蓝牙uuid的定义以及uuid的解析

  以上java文件在使用具体功能会用到,现在只是简单描述下,至于具体使用在后续文章用到时再给出。同时代码说明部分也就写这些了

  对于C、C++部分的代码一方面没看那么多,另一方面根据android JNI的命名习惯,大家找起来也很容易。

4. 以蓝牙 打开 enable 为例简单说明下蓝牙工作的整个过程:

Settings UI enable() ----->> Framwork BluetoothManagerService enable()------>>> Bluetooth APP AdapterService enable()------>>>Bluedroid enableNative().

5. 后续分析

  前面从整体上描述蓝牙的基本知识,落实在具体的代码分析上,我们按几个主线功能来走,蓝牙的开关、搜索配对、蓝牙耳机与电话和文件传输

  这几个也算是蓝牙的常用必备功能了,所以在后续文章中将按着这个顺序来跟一下它们代码调用流程。希望可以让你快速的了解蓝牙,当然如果有失误写错的地方,欢迎反馈,谢谢。

  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
以下是一个基本的STM32HAL库蓝牙模块代码,可以用于发送和接收数据: ```c #include "stm32f1xx_hal.h" #include <string.h> UART_HandleTypeDef huart2; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART2_UART_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART2_UART_Init(); uint8_t txData[] = "Hello, Bluetooth!"; uint8_t rxData[20]; while (1) { HAL_UART_Transmit(&huart2, txData, strlen((char*)txData), HAL_MAX_DELAY); HAL_StatusTypeDef status = HAL_UART_Receive(&huart2, rxData, 20, 1000); if(status == HAL_OK){ //接收到数据 //处理接收到的数据 } else if(status == HAL_TIMEOUT){ //未接收到数据,超时 } } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } static void MX_USART2_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } } static void MX_GPIO_Init(void) { __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } ``` 请注意,此代码仅适用于使用USART2作为蓝牙模块通信端口的情况。如果您使用的是不同的端口或不同的蓝牙模块,请相应更改代码
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ʚ兔子的先森ɞ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值