博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

如何获取并分析L2CAP包

Posted on 2011-11-12 21:17  RunForever  阅读(4417)  评论(0编辑  收藏  举报

本文中的分析与软件相关的内容,都是以WinCE中的 Microsoft Bluetooth Core Stack为例进行分析;与协议有关的内容,是基于Bluetooth Core 2.1 + EDR Spec进行分析。

1. 如何获取L2CAP包

  • 从HCI_ReadPacket()/HCI_WritePacket()中截获

在HCI_ReadPacket()/HCI_WritePacket()中判断eType为2的即是ACL-u数据,也即L2CAP数据。

ACL-u包中包括了Connection Handle,Flag,Data Length以及Data Domain,如下图所示:

clip_image002

其中,Data Domain即是L2CAP包的数据。

  • 从MS-Stack中获取

编译Debug版本的MS-Stack,即btd.dll,并打开Debug Zone DEBUG_L2CAP_PACKETS,即可以截取到L2CAP的数据。

#define DEBUG_L2CAP_PACKETS 0x00040000

一个MS-Stack中截获的L2CAP数据形如:

clip_image004

2. 如何分析L2CAP包

L2CAP是基于Packet进行数据传输的,其传输模型基于Channel。 Channel Identifier(CID)的分类如下图所示:

clip_image006

可以将Channel理解为USB协议中的Endpoint,不同的Channel用做不同的传输,总体上可以分为Connection-oriented channel,Connectionless data channel和Singling Channel,如下图所示:

clip_image008

2.1 Signaling Packet分析

  • 如何判别一个包为Signaling Packet

如果L2CAP包的CID为0x0001,则该包即为Signaling Packet。

  • Signaling包的结构

如下:

clip_image010

其中Commands域的格式如下:

clip_image012

上面的Code域可能的值如下:

clip_image014

  • 各个Code的具体分析方式

可以参照BlueCore Spec中有关各个Code的详细格式来对数据进行分析,以Disconnection Request为例,分析如下:

clip_image016

Destination CID - DCID (2 octets)

This field specifies the endpoint of the channel to be disconnected on the

device receiving this request.

Source CID - SCID (2 octets)

This field specifies the endpoint of the channel to be disconnected on the

device sending this request.

Identifier:

该域为1字节长,Request和Response中的该值是一样的,用来在一对设备之间进行通信的时候判别使用。每一组连续的Response-Request命令都必须有一个不一样的Identifier,长度为2个字节。在其它的通信协议中也经常会存在一个类似的Identifier,显然,0~0xff用完的时候,可以回收之前用过的值。

2.2 分析Data Packet

  • 如何判别一个包为Data Packet

Data Packet包括Connection-oriented和Connectionless data两种,它们的CID范围不一样,可以通过CID来进行区分。如果CID为0x2,则是Connectionless data,如果介于0x40和0xfff之间,则为Connection-oriented data Packet。

  • Data Packet的结构

两者的结构分别如下图所示:

Connection-oriented结构如下图:

clip_image018

clip_image020

Connectionless结构如下图:

clip_image022

可以看到,Connection-oriented Frame包括三种,Basic Frame(B-FRAME),Supervisory Frame(S-FRAME)和Information Frame(I-FRAME)。通过Control域中的Bit0来区分S-FRAME和I-FRAME,即Bit0=0为I-FRAME,为1是S-FRAME。

那么,如何来区分B-FRAME呢?这些就留到以后进行深究吧!