zoukankan      html  css  js  c++  java
  • 第12节-BLE协议HCI层的数据格式

    学习资料:

    1. 蓝牙协议core_v5.0.pdf 《Vol 2: Core System Package [BR/EDR Controller volume]》的“Part E: Host Controller Interface Functional Specification”

    2. BTStack源码

    对于被动扫描,周边的外设会给controller发送各种广播包,解析广播包,从而得到设备的信息。

    对于主动扫描,除了被动的获得广播包外,controller还可以给某个设备发出扫描请求,设备就会返回一个扫描回应,将更多的信息给controller。

    两个蓝牙设备互相通信,涉及两个Controller。Controller是具备一定智能的,它可以自行决定做什么事情:不需要Host决定它的每一个细节。比如说:要想让Controller发出扫描请求(SCAN REQ),Host只需要向Controller发出一个“scan enable”的命令即可,Controller就会根据预设的参数自动发出扫描请求(SCAN REQ)广播包。

    Controller就是一个芯片,它封装了LL层、PHY层那些复杂的操作;Host不需要理解芯片内部复杂的操作,只需要遵守Controller的规范,向它提供command,从它获得event,与它交互acl data。

    HCI层跟LL层的关系:

    a. 有些HCI command只是用来设置本地Controller,不导致无线传输

    b. 有些HCI command会导致LL层发出各类广播包,

       比如“LE Set Scan Enable Command”在主动扫描时会导致LL层发出SCAN_REQ广播包,

       比如“LE Create Connection Command”会导致LL层发出CONNECT_REQ广播包

    c. 有些HCI command会导致LL层发出数据包,其中的LLID=11b,表示是“LL Control PDU”

       比如“LE Read Channel Map Command”就会导致LL层发数据给对端设备,以便读取对端设备的信道图。

    d. ACL Data是必定导致LL层发数据给对端设备的

    这时的LL层数据,有可能是起始包,LLID=10b;

    也可能是延续包,LLID=01b;

    也可能是空包,LLID=01b

    在上一篇博客里,在传递Command/Event/ACL Data这3类数据时:

    1. 对于UART接口的Controller,会在数据前面加上1字节的头部用来分辨是哪一类数据

    2. 对于USB接中里的Controller,每类数据对应一个Endpoint,数据会直接发给Endpoint

    下面,介绍Command/Event/ACL Data这3类数据的格式。

    一、Command格式:

     

    Command前有2字节的头部OpCode,用来表示是哪一个Command。

    OGF表示“OpCode Group Field”,即“哪一组命令”,它占据高6位。

    OCF表示“OpCode Command Field”,即“这组里的哪一个命令”,它占据低10位。

     

    在蓝牙协议里,每一个OGF用一节来描述,在这节里会描述该组(OGF)的所有命令(OCF),位置如下图:

     

    BTStack示例:

    btstack-mastersrchci_cmd.c

     12211分别表示1个字节用来表示扫描类型、2个字节用来表示扫描间隔、2个字节用来表示scan_window、1个字节用来表示own_address_type、1个字节用来表示scanning_filter_policy。

    以后发送命令的时候,就需要根据12211这个格式来组装这些参数。在代码中搜索hci_le_set_scan_parameters.

    hci_send_cmd(&hci_le_set_scan_parameters, 1, 0x1e0, 0x30, hci_stack->le_own_addr_type, 0);

     

    代码中和文档中OCF的值刚好对应,正好是B。

     再来看一个例子:

     

     它带有两个参数,每个参数占一个字节,即hci_stack->le_scanning_enabled占一个自己;0占一个字节

     其他的命令也是类似的,具体需要查看蓝牙文档core_5.0

    二、Event格式:

    在官方协议中对于Event并没有明确的分类,按我的理解可以分为以下3类

    Event分类

    说明

    Command Status Event

    命令状态事件,

    表示控制器已经接收到命令并正在处理

    Command Complete Event

    命令完成事件,

    表示命令已经处理完毕并返回结果

    Advertising Report Event

    广播上报事件,本Event是Controller主动上报的

    而上述2个Event都是由command导致的

    示例:

    有些命令需要一定时间才能执行完,比如LE Create Connection命令。控制器接收到该命令后会首先返回一个“命令状态事件”,随后等待连接建议完成或者失败,再返回“命令完成事件”。

    Event的格式:

    三、ACL Data格式:

    ACL Data是传递给对端设备的数据,在建立连接之后才可以传输ACL Data,格式如下:

     

    Handle表示对端设备:主设备的Controller要与对端设备连接时,会生成一个32位的随机数,它被称为Access Address。在LL层的数据包中,Access Address被用来表示对端设备。但是Host程序并不想使用这个32位的数据,于是Controller又分配一个12位的Handle来表示这个Access Address、表示对端的设备。

    Packet_Boundary_Flag:

    PB Flag

    描述

    Host to Controller

    Controller to Host

    00b

    L2CAP PDU起始包

    P

    01b

    L2CAP PDU延续包

    P

    P

    10b

    L2CAP PDU起始包

    P

    Controller在传输ACL Data时,每次传输的字节数是有限制的,这可以通过“Read Buffer Size”命令读到这个值。

    当要传输非常大的ACL Data时,需要把数据拆分来传输,这就要用到上面表格中的“PB Flag”来分辨起始包、延续包。

    这些起始包、延续包由Host送到Controller后,会马上通过LL层重新编码、发给PHY层发给对端设备,对端设备的L2CAP层再把这些起始包、延续包组装起来。

    注意,在LL层的数据包里有LLID域,10b表示起始包、01b表示延续包。

    Broadcast_Flag在BLE协议中都是00b,表示“Point-to-point”。

    四、示例:

    Broadcast_Flag在BLE协议中都是00b,表示“Point-to-point”。

    1. 扫描设备

    a. Host向Controller发出“LE Set Scan Parameters Command”

    b. Controller向Host发送“Command Complete Event”

    c. Host向Controller发出“LE Set Scan Enable Command”

    d. Controller向Host发送“Command Complete Event”

    e. 如果扫描参数为“主动扫描”,对于新发现的设备会,LL层发出“SCAN REQ”广播包

    f. Controller接收到各类广播包,比如ADV_IND、SCAN_RSP

       LL层解析后,会通过HCI上报EVENT

    2. 连接设备

    a. Host向Controller发出“LE Create Connection Command”

    b. 不需要对端设备回应数据,发起方就认为连接已经建立

    c. Controller向Host发送“Command Status Event”

    d. Controller向Host发送“Command Complete Event”

    3. 写数据

    a. Host向Controller发出ACL数据:Write Command, Handle….

    b. Controller的LL层构造数据包(LLID=10b),通过PHY发出无线信号

    c. Controller向Host发送“Number of Completed Packets”事件

    4. 读数据

    a. Host向Controller发出ACL数据:Read Request, Handle….

    b. Controller的LL层构造数据包(LLID=10b),通过PHY发出无线信号

    c. Controller向Host发送“Number of Completed Packets”事件

    d. 对端设备的LL层通过PHY返回数据(LLID=10b)

    e. Controller向Host发送ACL数据:Read Response

     问题:右边抓取的空中数据包,在对端设备接收到读请求后,过了一会才回复一个无线信号给本地设备,中间有很多空包,这些空包是谁发起的呢?

    是由master发给slave的,

    这些空包起什么作用呢?

    两个设备建立连接之后,本地设备要知道对端设备什么时候要断开,它是怎么判断对端设备有没有断开呢?

    不断的发送空包给对端设备,对端设备收到空包后,要回复一个空包,这样本地设备才知道对端设备还没有断开。当然为了省电,对端设备没有必要每次收到空包都要回复,可以在收到几个空包后回复,但是一定要有回复。这些空包是是由controller自主发起的,与host层没有什么关系。

  • 相关阅读:
    第5节 两牵引轴同步运动
    第4节 动一个牵引轴
    第3节 电控配置简介
    第2节 控制方案的制定
    第1节 中型PLC基本编程思路
    1200与VM(主动)之间的TCP/IP通讯
    西门子1200和温度计的模拟量应用
    西门子1200的高速计数功能和增量编码器功能
    西门子1200和V90之间(位置模式)的PID应用
    面试题68
  • 原文地址:https://www.cnblogs.com/-glb/p/11617685.html
Copyright © 2011-2022 走看看