Android Bluetooth HID Host的理解及Report Data如何写入Android 节点之二

问题点5原生BT中,HID Host如何主动连接HID Device的控制通道和中断通道;

因HID 的控制通道(Control Channel)和中断通道(Interrupt Channel)实际上是两条L2CAP 通道,这两条通道有固定的PSM(控制通道的PSM 0x0011, 中断通道的PSM值是0x0013)

原生BT 中,主动发起L2CAP 连接的API L2CA_ConnectReq

PSM的宏定义是:

#define HID_PSM_CONTROL 0x0011

#define HID_PSM_INTERRUPT 0x0013

基于HID Spec,HID 的两条通道,先建立控制通道,再建立中断通道;断开时,先断开中

断通道,再断开控制通道;

Tracing 发现:原生BT HID Host主动连接时执行控制通道建立的API是:

hidh_conn_initiate

控制通道建立后,再建立中断通道。当前中断通道是在API hidh_l2cif_config_ind中建立,其是其控制通道建立后,执行L2CAP 配置,然后触发的中断通道建立;

每条通道建立后,将得到对应的CID(Channel ID);

表示控制通道的CID是“p_hcon->ctrl_cid”;

表示中断通道的CID是“p_hcon->intr_cid”

问题点6原生BT中,HID Host通过L2CAP 中断通道发送Data的API

基于以上找到的CID 表示“p_hcon->intr_cid”, 我们定位到最终通过L2CAP 发送的实现是基于API L2CA_DataWrite

所以当前中断通道发送中断dataAPI是:hidh_conn_snd_data

问题点7原生BT中,HID Host如何接收Data;

API hidh_l2cif_data_ind(HID Device 的是:hidd_l2cif_data_ind)中接收到L2CAP 数据,并通过CID值来判别收到的是控制通道还是中断通道Data;此API是通过API

L2CA_Register注册的函数指针,作为L2CAP层的callback返回;

在注册位置hidh_conn_reg,我们可以看到原生Android BT中默认支援7个HID Device的连接(宏定义:HID_HOST_MAX_DEVICES),注意:虽然直接连接最多7HID Device,但其初始化只需一次;

 

-->如当前收到中断通道Data时,将在API hidh_l2cif_data_ind中执行callback ,对应消息ID HID_HDEV_EVT_INTR_DATA(如果是控制通道的DATA指令消息,则evt

HID_HDEV_EVT_CTRL_DATA)

-->触发Callback对应API bta_hh_cback, 转发发出event BTA_HH_INT_DATA_EVT

bta_hh_cback in bta_hh_act.cc (system\bt\bta\hh)

通过关联到表示连接上后的“event + action + next state”数组bta_hh_st_connected,得到其对应的Action是“BTA_HH_DATA_ACT”;

/**************************************************************/

延伸问题点:bta_hh_st_connected数组,如何理解并对应到具体API

当前中断通道收到的data,最终触发event BTA_HH_INT_DATA_EVT,但我们发现event是被包含在数组bta_hh_st_idlebta_hh_st_w4_connbta_hh_st_connectedbta_hh_st_w4_sec当中;

以上数组实际上就是一个状态机,但其不直接对应API,而是通过问询形式得到具体的action, 然后把action值传递给函数数组,如当前的bta_hh_action

/**************************************************************/

-->通过bta_hh_action 和索引BTA_HH_DATA_ACT,执行到bta_hh_data_act

 -->执行到API bta_hh_data_act,函数内部执行bta_hh_co_data

从bta_hh_co_data的实现可以看到,在hidh_l2cif_data_ind把data 传给

bta_hh_co_data前,进行了偏移1Byte的动作,原因是:基于HID Spec:所有的HID Message 的第1个Byte都是Header;  

 

 

-->执行API bta_hh_co_data,此函数的重点是bta_hh_co_write

-->执行到函数bta_hh_co_write,把收到的中断report data 直接写给了节点"/dev/uhid"

(Note:关于节点"/dev/uhid"部分,后续有更详细的描述);

### Android 平台下的蓝牙 HID 实现与配置 #### 蓝牙堆栈架构概述 在 Android 中,默认提供了名为 Bluedroid 的蓝牙协议栈,该协议栈被划分为两个主要层次:嵌入式系统层(BTE)以及应用层(BTA)。其中 BTE 层负责核心的蓝牙功能实现,而 BTA 则作为桥梁连接至 Android Framework 应用程序[^3]。 #### 蓝牙 HAL 接口定义 为了支持不同的硬件抽象层(HAL),Android 提供了一个可扩展的框架用于自定义蓝牙堆栈。通过实现特定的 HAL 接口,可以适配不同厂商的蓝牙芯片组并提供一致的功能调用接口给上层应用程序使用[^1]。 #### 配置与初始化流程 当启用蓝牙服务时,整个蓝芽系统的启动过程会从 `enable Bluetooth` 开始直到最终关闭为止完成一系列操作。在此期间包含了加载必要的驱动模块、建立通信链路等关键环节[^2]。 对于具体的人机界面设备(Human Interface Device,HID),其工作原理主要是基于标准的蓝牙协议来传输键盘鼠标等相关输入数据包。以下是关于如何设置和管理这些类型的外设的一些要点: - **权限声明**: 确保 Manifest 文件中有适当的安全许可请求以便能够访问本地蓝牙资源。 ```xml <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> ``` - **绑定远程HID设备**: 使用 API 方法如 `connectGatt()` 或者其他专门针对经典蓝牙版本的服务发现机制找到目标 HIDs 设备地址和服务 UUIDs. - **处理回调事件**: 当成功建立了 GATT 连接之后, 可以监听来自远端节点的数据更新通知并通过相应的解析逻辑将其转换成实际的操作指令集发送回主机操作系统进行进一步处理。 下面展示了一段简单的伪代码片段用来演示基本概念: ```java public class BluetoothHidManager { private BluetoothAdapter mBluetoothAdapter; private BluetoothDevice mRemoteDevice; public void connectToDevice(String deviceAddress){ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if(mBluetoothAdapter != null && !mBluetoothAdapter.isEnabled()){ Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); // Start activity to request user enabling BT. } mRemoteDevice = mBluetoothAdapter.getRemoteDevice(deviceAddress); try{ BluetoothSocket socket = mRemoteDevice.createRfcommSocketToServiceRecord(UUID.fromString("00001124-0000-1000-8000-0123456789AB")); socket.connect(); InputStream inputStream = socket.getInputStream(); OutputStream outputStream=socket.getOutputStream(); byte[] buffer=new byte[1024]; int bytes=inputStream.read(buffer); processInputData(buffer,bytes); // Custom method defined elsewhere }catch(IOException e){ Log.e(TAG,"Error during connection",e ); } } } ``` 上述例子仅作为一个基础示范,并未考虑所有可能发生的异常情况或者最佳实践建议,在真实项目开发过程中还需要更加严谨的设计思路和技术手段加以完善优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值