实战Linux Bluetooth编程(四) L2CAP层编程

(L2CAP协议简介,L2CAP在BlueZ中的实现以及L2CAP编程接口)

 

一:L2CAP协议简介:

Logical Link Control and Adaptation Protocol(L2CAP)

 

逻辑连接控制和适配协议 (L2CAP) 为上层协议提供面向连接和无连接的数据服务,并提供多协议功能和分割重组操作。L2CAP 充许上层协议和应用软件传输和接收最大长度为 64KL2CAP 数据包。

  L2CAP 基于 通道(channel) 的概念。 通道 (Channel) 是位于基带 (baseband) 连接之上的逻辑连接。每个通道以多对一的方式绑定一个单一协议 (single protocol)。多个通道可以绑定同一个协议,但一个通道不可以绑定多个协议。 每个在通道里接收到的 L2CAP 数据包被传到相应的上层协议。 多个通道可共享同一个基带连接。

 

L2CAP处于Bluetooth协议栈的位置如下:

也就是说,所有L2CAP数据均通过HCI传输到Remote Device。且上层协议的数据,大都也通过L2CAP来传送。

 

 

L2CAP可以发送Command。例如连接,断连等等。

 

下面看Command例子:Connection Request:

 

其中PSM比较需要注意,L2CAP 使用L2CAP连接请求(Connection Request )命令中的PSM字段实现协议复用。L2CAP可以复用发给上层协议的连接请求,这些上层协议包括服务发现协议SDP(PSM = 0x0001)、RFCOMM(PSM = 0x0003)和电话控制(PSM = 0x0005)等。

 

 

ProtocolPSMReference
SDP0x0001See Bluetooth Service Discovery Protocol (SDP), Bluetooth SIG.
RFCOMM0x0003See RFCOMM with TS 07.10, Bluetooth SIG.
TCS-BIN0x0005See Bluetooth Telephony Control Specification / TCS Binary, Bluetooth SIG.
TCS-BIN-CORDLESS0x0007See Bluetooth Telephony Control Specification / TCS Binary, Bluetooth SIG.
BNEP0x000FSee Bluetooth Network Encapsulation Protocal, Bluetooth SIG.
HID_Control0x0011See Human Interface Device , Bluetooth SIG.
HID_Interrupt0x0013See Human Interface Device, Bluetooth SIG.
UPnP0x0015See [ESDP] , Bluetooth SIG.
AVCTP0x0017See Audio/Video Control Transport Protocol , Bluetooth SIG.
AVDTP0x0019See Audio/Video Distribution Transport Protocol , Bluetooth SIG.
AVCTP_Browsing0x001BSee Audio/Video Remote Control Profile, Bluetooth SIG
UDI_C-Plane0x001DSee the Unrestricted Digital Information Profile [UDI], Bluetooth SIG

 

 

 

 

二:L2CAP编程方法:

 

L2CAP编程非常重要,它和HCI基本就是Linux Bluetooth编程的基础了。几乎所有协议的连接,断连,读写都是用L2CAP连接来做的。

 

1.创建L2CAP Socket:

socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP);

domain=PF_BLUETOOTH, type可以是多种类型。protocol=BTPROTO_L2CAP.

 

2.绑定:

// Bind to local address
 memset(&addr, 0, sizeof(addr));
 addr.l2_family = AF_BLUETOOTH;
 bacpy(&addr.l2_bdaddr, &bdaddr); //bdaddr为本地Dongle BDAddr

 if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  perror("Can't bind socket");
  goto error;
 }

 

3.连接

memset(&addr, 0, sizeof(addr));
addr.l2_family = AF_BLUETOOTH;
bacpy(addr.l2_bdaddr, src);

addr.l2_psm = xxx; 

 if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  perror("Can't connect");
  goto error;
 }

 

注意:

struct sockaddr_l2 {
 sa_family_t l2_family;  //必须为 AF_BLUETOOTH
 unsigned short l2_psm;  //与前面PSM对应,这一项很重要
 bdaddr_t l2_bdaddr;     //Remote Device BDADDR
 unsigned short l2_cid; 
};

 

4. 发送数据到Remote Device:

send()或write()都可以。

 

5. 接收数据:

revc() 或read()

 

 

以下为实例:

注:在Bluetooth下,主动去连接的一端作为主机端。被动等别人连接的作为Client端。

 

 

 

 

 

 

背景知识1:Bluetooth设备的状态

之前HCI编程时,是用 ioctl(HCIGETDEVINFO)得到某个Device Info(hci_dev_info).其中flags当时解释的很简单。其实它存放着Bluetooth Device(例如:USB Bluetooth Dongle)的当前状态:

其中,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了。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux蓝牙内核协议是指作为Linux操作系统的一部分,在其内核中实现的一系列蓝牙相关协议和功能。这些协议包括了蓝牙核心规范以及各种蓝牙协议的实现,用于支持Linux系统与蓝牙设备之间的通信和交互。 蓝牙内核协议主要包括以下组成部分: 1. L2CAP(逻辑链路控制和适配):提供面向连接和面向无连接的逻辑数据链路,并在数据包上提供流控制、定时和可靠数据传输等功能。 2. SCO(同步连接导向):用于支持蓝牙音频和传真等应用,提供一种带宽有限但实时性要求高的同步数据通信。 3. HCI(主机控制接口):作为内核和蓝牙控制器之间的接口,提供控制和配置蓝牙硬件设备的功能。 4. RFCOMM(串行端口传输协议):用于模拟串行端口的传输方式,使得蓝牙设备可以像传统串口设备一样进行通信。 5. SDP(服务发现协议):用于在蓝牙设备之间发现和获取服务的信息,以便进行通信和配对。 6. HID(人机接口设备协议):用于支持蓝牙键盘和鼠标等人机接口设备的连接和通信。 蓝牙内核协议Linux操作系统中实现蓝牙功能的重要组成部分,它使得Linux能够与各种蓝牙设备进行通信,并提供了一系列协议和功能支持。通过这些协议Linux用户可以方便地连接、配对和传输数据到蓝牙设备,实现无线通信和接口控制。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值