一:L2CAP协议简介:
Logical Link Control and Adaptation Protocol(L2CAP)
<wbr></wbr>
逻辑连接控制和适配协议(L2CAP)
为上层协议提供面向连接和无连接的数据服务,并提供多协议功能和分割重组操作。L2CAP充许上层协议和应用软件传输和接收最大长度为
64K的
L2CAP数据包。
L2CAP基于
通道(channel)的概念。
通道 (Channel)是位于基带
(baseband)连接之上的逻辑连接。每个通道以多对一的方式绑定一个单一协议
(single protocol)。多个通道可以绑定同一个协议,但一个通道不可以绑定多个协议。每个在通道里接收到的
L2CAP数据包被传到相应的上层协议。
多个通道可共享同一个基带连接。
<wbr></wbr>
L2CAP处于Bluetooth协议栈的位置如下:
也就是说,所有L2CAP数据均通过HCI传输到Remote Device。且上层协议的数据,大都也通过L2CAP来传送。
<wbr></wbr>
<wbr></wbr>
L2CAP可以发送Command。例如连接,断连等等。
<wbr></wbr>
下面看Command例子:Connection Request:
<wbr></wbr>
其中PSM比较需要注意,L2CAP 使用L2CAP连接请求(Connection Request )命令中的PSM字段实现协议复用。L2CAP可以复用发给上层协议的连接请求,这些上层协议包括服务发现协议SDP(PSM = 0x0001)、RFCOMM(PSM = 0x0003)和电话控制(PSM = 0x0005)等。
<wbr></wbr>
<wbr></wbr>
Protocol
PSM
Reference
SDP |
0x0001 |
SeeBluetooth Service Discovery Protocol (SDP), Bluetooth SIG. |
RFCOMM |
0x0003 |
See RFCOMM with TS 07.10, Bluetooth SIG. |
TCS-BIN |
0x0005 |
SeeBluetooth Telephony Control Specification / TCS Binary, Bluetooth SIG. |
TCS-BIN-CORDLESS |
0x0007 |
SeeBluetooth Telephony Control Specification / TCS Binary, Bluetooth SIG. |
BNEP |
0x000F |
SeeBluetooth Network Encapsulation Protocal, Bluetooth SIG. |
HID_Control |
0x0011 |
See Human Interface Device , Bluetooth SIG. |
HID_Interrupt |
0x0013 |
See Human Interface Device, Bluetooth SIG. |
UPnP |
0x0015 |
See [ESDP] , Bluetooth SIG. |
AVCTP |
0x0017 |
See Audio/Video Control Transport Protocol , Bluetooth SIG. |
AVDTP |
0x0019 |
See Audio/Video Distribution Transport Protocol , Bluetooth SIG. |
AVCTP_Browsing |
0x001B |
See Audio/Video Remote Control Profile, Bluetooth SIG |
UDI_C-Plane |
0x001D |
See the Unrestricted Digital Information Profile [UDI], Bluetooth SIG |
<wbr></wbr>
<wbr></wbr>
<wbr></wbr>
<wbr></wbr>
二:L2CAP编程方法:
<wbr></wbr>
L2CAP编程非常重要,它和HCI基本就是Linux Bluetooth编程的基础了。几乎所有协议的连接,断连,读写都是用L2CAP连接来做的。
<wbr></wbr>
1.创建L2CAP Socket:
socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP);
domain=PF_BLUETOOTH, type可以是多种类型。protocol=BTPROTO_L2CAP.
<wbr></wbr>
2.绑定:
// Bind to local address
<wbr>memset(&addr, 0, sizeof(addr));<br><wbr>addr.l2_family = AF_BLUETOOTH;<br><wbr>bacpy(&addr.l2_bdaddr, &bdaddr); //bdaddr为本地Dongle BDAddr</wbr></wbr></wbr>
<wbr>if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {<br><wbr><wbr>perror("Can't bind socket");<br><wbr><wbr>goto error;<br><wbr>}</wbr></wbr></wbr></wbr></wbr></wbr>
<wbr></wbr>
3.连接
memset(&addr, 0, sizeof(addr));
addr.l2_family = AF_BLUETOOTH;
bacpy(addr.l2_bdaddr, src);
addr.l2_psm = xxx;<wbr></wbr>
<wbr>if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {<br><wbr><wbr>perror("Can't connect");<br><wbr><wbr>goto error;<br><wbr>}</wbr></wbr></wbr></wbr></wbr></wbr>
<wbr></wbr>
注意:
struct sockaddr_l2 {
<wbr>sa_family_t<wbr>l2_family;<wbr> //必须为 AF_BLUETOOTH<br><wbr>unsigned short<wbr>l2_psm;<wbr> //与前面PSM对应,这一项很重要<br><wbr>bdaddr_t<wbr>l2_bdaddr;<wbr><wbr><wbr><wbr><wbr>//Remote Device BDADDR<br><wbr>unsigned short<wbr>l2_cid;<wbr><br>
};</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr></wbr>
4. 发送数据到Remote Device:
send()或write()都可以。
<wbr></wbr>
5. 接收数据:
revc() 或read()
<wbr></wbr>
<wbr></wbr>
以下为实例:
注:在Bluetooth下,主动去连接的一端作为主机端。被动等别人连接的作为Client端。
<wbr></wbr>
<wbr></wbr>
<wbr></wbr>
<wbr></wbr>
<wbr></wbr>
<wbr></wbr>
背景知识1:Bluetooth设备的状态
之前HCI编程时,是用<wbr>ioctl(HCIGETDEVINFO)得到某个Device Info(hci_dev_info).其中flags当时解释的很简单。其实它存放着Bluetooth Device(例如:USB Bluetooth Dongle)的当前状态:</wbr>
其中,UP,Down状态表示此Device是否启动起来。可以使用ioctl(HCIDEVUP)等修改这些状态。
另外:就是Inquiry Scan, PAGE Scan这些状态:
Sam在刚开始自己做L2CAP层连接时,使用另一台Linux机器插USB Bluetooth Dongle作Remote Device。怎么也没法使用inquiry扫描到remote设备,也没法连接remote设备,甚至无法使用l2ping ping到remote设备。觉得非常奇怪,后来才发现Remote Device状态设置有问题。没有设置PSCAN和ISCAN。
Inquiry Scan状态表示设备可被inquiry. Page Scan状态表示设备可被连接。
#hciconfig hci0 iscan
#hciconfig hci0 pscan
或者:#hciconfig hci0 piscan
就可以设置为PSCAN或者iSCAN状态了。
编程则可以使用ioctl(HCISETSCAN) . dev_opt = SCAN_INQUIRY;dr.dev_opt = SCAN_PAGE;dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
则可以inquiry或者connect了。
分享到:
相关推荐
实战Linux Bluetooth编程, 用了bluez,有图有真相
this source code contains the way of data transmission over l2cap sockets of bluetooth under Linux Environment.
Linux Bluetooth 编程介绍
实战Linux_Bluetooth编程,熟悉蓝牙开发...
Linux Bluetooth编程原理和实践
驱动层、蓝牙核心及 HCI 层、L2CAP 与 SCO 音频层、 RFCOMM, BNEP, CMTP 与 HIDP 层、通用蓝牙 SDP 库和后 台服务及面向所有层的标准套接字接口;在用户空间提供了 蓝牙配置、测试及协议分析等工具。其组织结构如图 ...
最详细的linux蓝牙协议栈的讲解,完全从代码的角度分析,从运行态log进行总结
EEE
5.2 L2CAP层编程 5.3 SDP层编程 六Bluetooth 之启动过程实 6.1 Bluetooth 启动步骤 6.2 Bluetooth 启动流程 6.3 Bluetooth数据流向 6.4 Bluez控制流程 .6.5 Bluetooth 启动过程分 七 Bluetooth 之驱动移植 7.1 ...
一份介绍bluetooth编程的pdf资料,很详细。介绍了在linux windows等OS上如何对bluetooth进行操作。
蓝牙协议l2cap层封包细节文档,方便底层开发
Affix is a Bluetooth Protocol Stack for Linux developed by Nokia Research Center in Helsinki and released under GPL. See CREDITS. Affix supports core Bluetooth protocols like HCI, L2CAP 1.1, L2CAP 1.2...
基于嵌入式Linux的Bluetooth数据通信.pdf
蓝牙协议栈 Bluetooth stack 这是一个包含传统蓝牙跟低功耗蓝牙的协议栈,属于超轻量级蓝牙协议栈,用作学习蓝牙协议栈的人使用 我根据此部分也搭建了一个开发环境,来作为额外收入,希望大家多多支持。有不足支持...
realtek 蓝牙 linux驱动源码和移植指导文档
linux下蓝牙驱动代码的阅读笔记,希望能够给需要的人带来启发。
BlueZ - Bluetooth protocol stack for Linux for Linux v2.13.6.
Linux网络系统中 蓝牙部分的相关程序
BlueZ,Linux Bluetooth Development,Linux 蓝牙开发
Bluetooth 蓝牙编程必备知识,你可以从中得到你想要的蓝牙相关知识。事例丰富。