linux rfcomm协议,一文彻底明白 传统蓝牙协议栈RFCOMM协议(bluetooth rfcomm)帧格式...

零. 概述

本文章主要讲下蓝牙RFCOMM协议(bluetooth rfcomm)的帧格式,包括Address,Control,Length Indicator,Information,FCS等

一. 声明

本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下:

6c1caa55979fc879969decad820c5e23.png

第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些概念,产生背景,发展轨迹,市面蓝牙介绍,以及蓝牙开发板介绍。

第二篇:Transport层介绍,主要介绍蓝牙协议栈跟蓝牙芯片之前的硬件传输协议,比如基于UART的H4,H5,BCSP,基于USB的H2等

第三篇:传统蓝牙controller介绍,主要介绍传统蓝牙芯片的介绍,包括射频层(RF),基带层(baseband),链路管理层(LMP)等

第四篇:传统蓝牙host介绍,主要介绍传统蓝牙的协议栈,比如HCI,L2CAP,SDP,RFCOMM,HFP,SPP,HID,AVDTP,AVCTP,A2DP,AVRCP,OBEX,PBAP,MAP等等一系列的协议吧。

第五篇:低功耗蓝牙controller介绍,主要介绍低功耗蓝牙芯片,包括物理层(PHY),链路层(LL)

第六篇:低功耗蓝牙host介绍,低功耗蓝牙协议栈的介绍,包括HCI,L2CAP,ATT,GATT,SM等

第七篇:蓝牙芯片介绍,主要介绍一些蓝牙芯片的初始化流程,基于HCI vendor command的扩展

第八篇:附录,主要介绍以上常用名词的介绍以及一些特殊流程的介绍等。

另外,开发板如下所示,对于想学习蓝牙协议栈的最好人手一套。以便更好的学习蓝牙协议栈,相信我,学完这一套视频你将拥有修改任何协议栈的能力(比如Linux下的bluez,Android下的bluedroid)。

10c67ac881b7c3c3feb06fc801017bab.png

-------------------------------------------------------------------------------------------------------------------------

蓝牙交流扣扣群:970324688

--------------------------------------------------------------------------------------------------------------------------

二.RFCOMM帧格式

a18c750da6a5329104ea4f089b37703d.png

2.1 参数Address:

0f72ee32e3bfd89f85d56152132d10cb.png

EA参数:这部分在蓝牙RFCOMM协议中一直为1

a095f67a8e59047c0f1e63e45181bc0c.png

C/R参数:此部分是代表RFCOMM的command还是response,官方解释如下:

44872ce58225949bd8315301cf0daa4a.png

这个理解起来稍微我有绕,我翻译一下:

C/R(命令/响应)位表示帧是命令还是响应,它的值不仅取决于帧是否携带命令或响应,还有信道的哪一端发送帧。建立连接的设备(通过在DLCI 0上发送SABM命令)称为initiator。响应的设备(通过在DLCI 0上发送UA响应)称为responder。网络上都对这个地方说明的模凌两可,对于上面的这段话其实也说的模棱两可,我来总结下:

1)对于(SABM,UA,DM,DISC)帧,这些统称为命令帧,initiator发送给responder,C/R=1,response相应initiator C/R也为1。

2)对于(SABM,UA,DM,DISC)帧,这些统称为命令帧,response发送给initiator C/R为0,initiator响应给responder,C/R=0.

3)对于UIH帧,这个称为数据帧,initiator发送给responder,C/R=1,response发送给initiator C/R为0.

总结图标如下:

63dfc655abdbd9e725b18d03f9ae7a8f.png

为了便于我上面的总结理解,那么加一个流程图,来加深你们的印象

f61975cc5ddc842fb4b6c5beb2d07c8a.png

下面我们用BTsnopp来一一看下以上个3case:

9e1f730b7d59d4717a0fda090ff3ae46.png

1)对于(SABM,UA,DM,DISC)帧,这些统称为命令帧,initiator发送给responder,C/R=1,response相应initiator C/R也为1。

60426efb2b7cafe9ea64d725fcacdb4d.png

f133924b933aed2a9fd005a8a83e19b2.png

分别解析如下:

3ae3035f3155b1ee79c5b38c1ff5d488.png

0797aeaadae11ea675b5b3271da535c4.png

从截图看出是对方来连接我们signaling,所以对方是initiator,所以对方发送SABM种的C/R是1,而我们回复的UA帧中的C/R也为1

以下例子都是以对方为initiator来说明

2)对于(SABM,UA,DM,DISC)帧,这些统称为命令帧,response发送给initiator C/R为0,initiator响应给responder,C/R=0.

3888d8809c73732400a605eef06899a0.png

9d1847303a59adf41c63fe1b9ef6a556.png

c24232963de4d301f89d583886ad1604.png

从1)中我们可以看到我们是responder,对方是initiator,所以按照我们发送给对方的SABM帧的C/R是0,对方回应我们的也是0

3)对于UIH帧,这个称为数据帧,initiator发送给responder,C/R=1,response发送给initiator C/R为0.

844a58a472fcd3ba0ad8f952dac857be.png

上图解析如下:

56bd21b7c7dec3da66c97356706fab1a.png

8fdd0b0204878eafbd863b5bc5a19dd5.png

0f4105fdc2a7dab1939ec56869b82982.png

可以看到对方给我们的UIH帧C/R为1,我们给对方的UIH帧C/R为0

讲到这里你应该明白了C/R位了吧,我感觉我是全网在这里说明最清晰的。

D参数:这个同样比较绕,我们来看下官方解释

D其实就是DLCI中的direction bit

e1492a425865dd18d521acba272a28fc.png

网上也没有一个特别明确的说明,我自己总结了下,感觉也是比较清晰:

建立连接的设备(通过在DLCI 0上发送SABM命令)称为initiator。响应的设备(通过在DLCI 0上发送UA响应)称为responder,这点在上面我们也已经说明了。initiator自己的D=1,responder自己的D=0,所以如果在DLCI已经建立连接后,后续initiator连接responder某一个profile的时候(比如HFP),那么应该是DCLI=0+ server chanel<<1,如果是responder连接initiator的某一个profile,那么应该是DCLI=1+ server channel<<1

后续交互封包的UIH的DCLI一直不变

举几个例子来说明下这里(remote是initiator,local是responder):

bf5f62c95b8358d01eb2a06af739b613.png

来一个initiator连接responder的btsnoop

e909fb761ea958c0cada66fb862bfe75.png

可以发现server channel是9,那么按照算法应该是0+9<<1,所以DCLI应该是0x12

来一个responder连接initiator的btsnoop

e16398bf48272654b079a507d171e667.png

可以发现server channel是13,那么按照算法应该是1+13<<1,所以DCLI应该是0x1B

Server channel:说白了就是上层profile的rfcomm channel

注册到SDP中,整个流程就是SDP问询对方的RFCOMM channel,然后再发起RFCOMM的连接(比如HFP,HSP,SPP,OPP等),连接完毕交互完参数,就相当于上层profile连接成功

2.2 Control参数

主要是标示RFCOMM frame type是什么,截图如下:

0234f19d76d5d6389be325e8cc5019b5.png

帧分别作用如下:

SABM:异步平衡模式设置指令 SABM 命令可以用在异步平衡模式下,并且它的控制字段只能有一个字节。设备通过首先发送 UA 应答来确认接收到 SABM命令,DLC 发送和接收状态变量都必须设定为 0。用大白话讲就是连接命令

UA:未加编号的确认应答。 UA 应答用在设备对接收到 SABM 和 DISC 后的确认应答

DM:断开连接模式应答。DM 应答是用来报告设备从数据链路逻辑地断开连接这么一种状态的。在断开模式下,不支持任何命令,直到收到了 SABM 命令,然后停止断开模式。在断开模式下,接收到了 DISC 命令,则要向对方发送一个 DM 应答。

DISC:断开连接指令。用 DISC 命令可以用来结束一个正在运行或者刚刚开始的模式。它就是通知一方另一方悬置操作,设备必须假定一个逻辑断开模式。在执行这个命令之前,接收设备要通过发送 UA 应答来确认接受 DISC 命令。在DLCI0 中,DISC 命令的发送也和其他的 DLCI 具有同意的意思。

UIH:带头校验的未编号信息命令和应答用 UIH 命令/应答可以通过不影响V(S)或 V(R)变量来相互发送信息。UIH 是用在传输一些信息的完整性没有它要在正确的 DLCI 上传输重要的情况下的。 FCS 只在地址和控制字段进行计算。 UIH用于对差错码要求不是很高的场合,如语音。

P/F Bit:P/F是Poll/Final位

在Commands中,被称为P(poll)位;而在Responses中则被称为F(final)位,大概用法我自己总结如下:

1)对于(SABM,UA,DM,DISC)帧,这些统称为命令帧,command跟response都设置为1就好。

2)对于UIH帧,除了给对方credit设置为1外,UIH user帧以及UIH多路控制帧都设置为0就好了。

2.3 Length Indicator参数

e740e3d7b38809a24de5af5b2907ab03.png

54b2922e123f93c1ceeada8b03dfca64.png

L1 到 L7 位表示数据字段的长度,其默认值为 31 字节。同样,它可以根据 EA位进行扩展。当 EA=0 时,它接下来的字节如下表表示就可以表示 15 个数字。也就是RFCOMM的后续len是32~32767 byte的字节。

2.4 Information Field参数

UIH帧数据,只对UIH帧有效,后续再一一介绍下UIH的格式

2.5 FCS参数

帧校验序列(FCS)根据不同帧类型在不同域集上进行运算.下面列出需要进行帧运算的字段:

对于 SABM、DISC、UA、DM 帧:在地址、控制和长度标志字段上进行运算;

对于 UIH 帧:在地址和控制字段上进行运算。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
摘 要:基于对Linux蓝牙协议BlueZ 源代码的分析,给出BlueZ的组织结构和特点。分析蓝牙USB 传输驱动机制和数据处理过程, 给出实现蓝牙设备驱动的重要数据结构和流程,并总结Linux 下开发蓝牙USB 设备驱动的一般方法和关键技术。 关键词:Linux 系统;蓝牙协议;设备驱动 USB Device Driver for Linux Bluetooth Stack LIANG Jun-xue, YU Bin (Institute of Electronic Technology, PLA Information Engineering University, Zhengzhou 450004) 【Abstract】This paper depicts the structure and characteristics of BlueZ based on analyzing the source code of Linux bluetooth stack BlueZ. It analyzes the implementation of bluetooth USB transport driver scheme and data processing procedure in detail, and gives the key data structure and implementation of bluetooth device driver. It summarizes the approach of developing Linux bluetooth USB device driver and the key technology. 【Key words】Linux system; bluetooth stack; device driver 计 算 机 工 程 Computer Engineering 第 34 卷 第 9 期 Vol.34 No.9 2008 年 5 月 May 2008 ·开发研究与设计技术· 章编号:1000—3428(2008)09—0273—03 献标识码:A 中图分类号:TP391 1 概述 蓝牙技术是开放式通信规范,而 Linux 是开放源码的操 作系统。廉价设备与免费软件的结合,促进了蓝牙技术和 Linux 的发展与融合。 Linux最早的蓝牙协议是由Axis Communication Inc在 1999 年发布的 OpenBT 协议。 随后, IBM 发布了 BlueDrekar 协议,但没有公开其源码。Qualcomm Incorporated 在 2001 年发布的 BlueZ 协议被接纳为 2.4.6 内核的一部分。此外, Rappore Technology 及 Nokia 的 Affix Bluetooth Stack 都是 Linux 系统下的蓝牙协议,应用在不同的设备和领域中。 BlueZ 是 Linux 的官方蓝牙协议,也是目前应用最广 泛的协议,几乎支持所有已通过认证的蓝牙设备。对于基 于主机的蓝牙应用,目前常见的硬件接口有 UART, USB 和 PC 卡等,USB 作为 PC 的标准外设接口,具有连接方便、兼 容性好和支持高速设备等特点,已广泛应用于蓝牙设备。 目前对 Linux 下 USB 设备驱动的研究已较为广泛而深 入[1-4] ,但对 Linux 下的蓝牙设备驱动还没有专门的研究。本 在分析 USB 设备驱动和蓝牙协议的基础上,总结了 Linux 下开发蓝牙 USB 驱动程序的一般方法,并深入剖析了 其关键技术。 2 Linux 蓝牙协议 BlueZ 简介 BlueZ 目前已成为一个开放性的源码工程。它可以很好 地在 Linux 支持的各种体系的硬件平台下运行,包括各种单 处理器平台、多处理器平台及超线程系统。 BlueZ 由多个独立的模块组成,内核空间主要包括设备 驱动层、蓝牙核心及 HCI 层、L2CAP 与 SCO 音频层、 RFCOMM, BNEP, CMTP 与 HIDP 层、通用蓝牙 SDP 库和后 台服务及面向所有层的标准套接字接口;在用户空间提供了 蓝牙配置、测试及协议分析等工具。其组织结构如图 1 所示, BlueZ 没有实现专门的 SDP 层,而是将其实现为运行在后台 的蓝牙服务库例程(图 1 没有描述该后台服务)。 RFOMM 层支 持标准的套接口,并提供了串行仿真 TTY 接口,这使串行端 口应用程序和协议可以不加更改地运行在蓝牙设备上,例如 通过点对点协议 PPP 可实现基于 TCP/IP 协议簇的所有网络 应用。BNEP 层实现了蓝牙的以太网仿真,TCP/IP 可以直接 运行于其上。 USB设备驱动 (hci_usb.o) L2CAP层(l2cap.o) RFCOMM层 (rfcomm.o) BNEP层 (bnep.o) CMTP层 (cmtp.o) 串口设备驱动 (hci_uart.o) 虚拟串口设备驱动 (hci_vhci.o) 音频 socket RFCOMM socket BNEP socket CMTP socket L2CAP socket HCI socket 内核 空间 用户 空间 串口设备 CAPI设备 输入设备 网络设备 HDIP socket 音频设备 AF_BLUETOOTH socket 音频层(sco.o) PPP TCP/IP AF_INET socket BNEP层 (bnep.o) 其他设备驱动 (bluecard_cs.o等) BlueZ工具和实用程序 HDIP层 (hdip.o) BlueZ核心 及HCI层(bluez.o/bluetooth.o) 图 1 BlueZ 组织结构 3 蓝牙 USB 设备驱动 设备驱动程序在 Linux 内核中起着重要作用,它使某个 硬件能响应一个定义良好的内部编程接口。这些接口隐藏了 设备的工作细节,用户通过一组独立于特定驱动程序的标准 调用来操作设备。而将这些调用映射到作用于实际硬件设备 的特有操作上,则是驱动程序的任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值