编程语言
首页 > 编程语言> > hci层编程

hci层编程

作者:互联网

主机控制器接口协议(hci)

一.概述

Hci是主机与控制器之间的接口,即主机与控制器之间通信的协议规范,其规定了指令、事件和数据的封装格式。在物理链路上又规定如何传输这些数据报。其主要的两个任务:

1. 发送命令给控制器和接收来自控制器的事件,达到对本地的配置和状态的监控。

2. 接收和发送来自对端设备的数据,设备之间信息传输。

在蓝牙规范中,描述了四种主机与控制器间传输数据的方法:

1)UART

2)USB

3)RS232

4)SD

 

二.HCI数据格式

1) HCI指令分组  (针对指令):HCI指令分组用于从主机向控制器发送指令,一般当控制器完成主机发送来的命令时,将返回一个指令完成状态事件给主机,让主机知道指令执行的结果。其数据报格式如下:

 

 

操作码(OpCode)用来唯一标识HCI Command.它由2部分组成10bit的Opcode Command. 6bit的Opcode Group

OpCode Group Flag(OGF)  表明指令的类型,在bluez中定义以下的OGF

0X01 OGF_LINK_CTL  链路控制
0X02 OGF_LINK_POLICY  链路策略
0X03 OGF_HOST_CTL 主机控制  
0X04 OGF_INFO_PARAM  主机策略
0X05 OGF_STATUS_PARAM 状态策略
0X08 OGF_LE_CTL  ble设备控制
0X3E OGF_TESTING_CMD 测试命令
0X3F OGF_VENDOR_CMD   

厂商测试

Opcode Command Flag (OCF)表明了所要执行的指令,每个不同类型的指令(OGF)都有一系列OCF来指明要操作的

参数:每个指令都有与之关联的参数,这些参数及其大小有指令定义。

例:对于蓝牙查询模式(搜索附近蓝牙设备的指令)bluez有以下声明:

#define OGF_LINK_CTL            0x01    //OGF,查询模式为链路控制的指令

#define OCF_INQUIRY         0x0001      //查询模式指令的OCF

typedef struct {

    uint8_t       lap[3];    //24位地址低端部分

    uint8_t       length;       /* 1.28s units */

    uint8_t       num_rsp;  

} __attribute__ ((packed)) inquiry_cp;   //定义的参数

 #define INQUIRY_CP_SIZE 5        //参数长度

1) HCI数据分组   (针对数据)

HCI数据分组用于在主机和控制器之间交换数据。数据分组根据ACL和SCO数据分组类型进行定义

1.HCI ACL分组数据包格式及解析

                                                                                                                   

  PB  flag  
参数描述
00 保留
01

用于高层报文的数据分组分段

10

高层报文的第一个数据分段  

11 保留
  BC flag
参数描述
00 没有广播
01 激活广播:数据报发往所有激活的从单元
10 比克网广播:数据报发往所有的从单元,包括休眠单元
11 保留

 连接句柄:

参数描述
0xXXX 范围:0x0000-0xEFFF.一个连接句柄就是用于唯一标识蓝牙设备之间SCO或ACL连接的12bit的标识符,连接句柄通过唯一标识两蓝牙设备之间的数据管道进行访问。每个设备应在建立远程连接的整个周期内保持连接句柄。在两个设备间可以拥有多个连接句柄但只能保持一个ACL连接。

 

 

 

 

 

 

2.HCI SCO分组

 

0                                        11                    19                 31
连接句柄 保留 数据
数据

保留位:由HCI SCO数据分组中第2字节的4~7bit组成

 

 

2) HCI 事件分组

HCI事件分组用于在事件发生时通知主机,由控制器发往主机。当主机接收到事件分组时解析分组以确定发生了那个事件。

 

事件码:每个事件都指定1字节事件码,以唯一标识不停事件类型。

参数总长:所有参数总长,单位为字节

事件参数:每个指令都有与之关联的参数,根据指令定义。 

三.HCI 编程——搜索发现远程设备

1.相关函数讲解

1)int hci_get_route(bdaddr_t *bdaddr)

/*根据其bdaddr得到相应的设备id

*如果 bdaddr 为 NULL,则返回第一可用设备的ID 

*返回值小于0获取失败*/

2)int hci_open_dev(int dev_id)

/* hci_open_dev会使用socket()创建一个AF_BLUETOOTH域的套接字描述符,并与指定的本地设备绑定,这样就可以用通过创建的描述符操作该设备。

* dev_id  :打开的本地设备的设备ID

 * Returns :创建的套接字描述符,小于0则创建失败*/

3int hci_close_dev(int dd)

    /*关闭套接字描述符*/

4)int hci_send_req(int dd, struct hci_request *r, int to)

/*该函数用于向控制器发送一个指令

 *dd :hci_open_dev创建的描述符

 * r :要发送的HCI指令分组以及返回的事件分组,格式如下

* struct hci_request {

*       uint16_t ogf;            //操作组段

*       uint16_t ocf;            //操作码指令段

*       int      event;          //返回事件类型

*       void     *cparam;        //参数

*       int      clen;           //参数长度

*       void     *rparam;        //返回的事件分组参数

*       int      rlen;           //事件分组长度

*}

 *to :超时时间,单位ms*/

/* Filter types */

#define FLT_CLEAR_ALL       0x00

#define FLT_INQ_RESULT         0x01

#define FLT_CONN_SETUP         0x02

5int hci_le_set_scan_parameters(int dd, uint8_t type,uint16_t interval, uint16_t window,uint8_t own_type, uint8_t filter, int to)

/* hci_le_set_scan_parameters函数会向主机发送一个HCI指令分组用于对搜索参的配置

* dd  : hci_open_dev函数打开的套接字

* type:搜索类型,为0是被动搜索

* interval:  搜索的时间  =N*1.25

* window : 搜索数量

* own_tpe: 地址类型

* filter :过滤器     FLT_CLEAR_ALL(清除所有过滤器)FLT_INQ_RESULT(过滤已经搜索到的设备)

* to :超时时间,单位ms

*/

6int hci_le_set_scan_enable(int dd, uint8_t enable, uint8_t filter_dup, int to)

/*dd :hci_open_dev函数打开的套接字

 *enable : 为1是开始扫描,0停止扫描

 *filter_dup:事件过滤器   为0是每次返回所有事件(返回所有搜索到的设备信息),为1是过滤已出现的事件(不返回前面已经得到的设备信息)

 *to :超时时间,单位ms

*/

 

标签:hci,int,编程,指令,分组,HCI,OGF
来源: https://www.cnblogs.com/amateur-writer-2019-1-12/p/11198026.html