转发自https://blog.csdn.net/xiaojsj111/article/details/37597859
蓝牙pan就是我们熟知的蓝牙网络,他在蓝牙协议体系中的层次结构见如下图:
BNEP相当于网络协议栈中的链路层,由该层虚拟出一个网络接口,而BNEP层以下就是蓝牙核心协议之一的L2CAP。这个是在蓝牙协议中的层次结构,具体在bluedroid中的层次结构,跟这个有点出入。但基本都差不多的。
上图中的BNEP层收到的数据包是以太网格式的,需要将他重现拆分打包成适合BNEP over L2CAP来传输,所以在BNEP层需要将ip层下来的以太网头去掉,再加上BNEP的头,当这个BNEP包传输到l2cap层时,又会被加上L2cap的头,他们的包头格式的变换如下图所示:
上图中的BNEP Header的格式基本是遵循如下图所示的格式,但具体的格式是依赖于BNEP TYPE的,不同的type他们的BNEP header是有所不同的。
0 8 12 16 20 24 28 31
BNEP TYPEEBNEP Packet based on BNEP Type ...
以上各字段的解析如下:
BNEP
Type:取值范围:0x00 –0x7F,Seven bit Bluetooth Network Encapsulation Protocol
Type value identifies the type of BNEP header contained in this
packet.Values are defined in the following Table 1
Extension
Flag (E):One bit extension flag that indicates if one or more extension
headers follow the BNEP Header before the data payload. If the
extension flag is equal to 0x1 then one or more extension headers
follows the BNEP header. If the extension flag is equal to 0x0 then the
BNEP payload follows the BNEP header
以上各种BNEP包类型,重点描述0x01和0x2类型,其他的请详见BNEP的协议描述。
BNEP_ CONTROL Packet Type Header Format:The BNEP_ CONTROL packet type header format is shown in the following Figure。
This
packet type is mandatory to recognize and respond to accordingly. The
BNEP_CONTROL packet type is used to exchange control information
上图中的BNEP control type有如下种类,他们主要用于BNEP连接的建立和断开,及设置网络滤包。但需要注意的是,由于BNEP连接是建立在l2cap连接之上的,所以需要先建立l2cap连接。
1.4.1 BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD
BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD Control Command Packet:
This
packet shall be used to reply to any control message received, which
contains an unknown BNEP control type value. This allows devices to
response to control message that may be used in the future
1.4.2 BNEP_SETUP_CONTROL Packets
This
packet type shall contain control messages used to setup the initial
connection information about the BNEP connection. All devices that
support BNEP shall be able to recognize and respond to
accordingly to all BNEP_SETUP_CONTROL packets BNEP_SETUP_CONTROL packet
types must be processed in order that they are received. For each
connection, only one outstanding BNEP_SETUP_CONTROL message is
allowed. A response message must be used to respond
to each control message received. If a response message is not
received, after Tcrt time has elapsed, then the outstanding
BNEP_SETUP_CONTROL message can be assumed to be lost and the same
BNEP_SETUP_CONTROL message can be retransmitted. The range for Tcrt
is from 1 second to 30 seconds, with a suggested timeout value to be 10
seconds. BNEP packets of type BNEP_SETUP_CONTROL are for the device
with direct connection communication only, and must never be forwarded.
1.4.2.1 BNEP_SETUP_CONNECTION_REQUEST_MSG
BNEP_SETUP_CONNECTION_REQUEST_MSG setup control message format:
The BNEP_SETUP_CONNECTION_REQUEST_MSG setup control message format is shown in the following Figure:
The
purpose of this control message is to inform the peer entity the
destination and source SDP service UUIDs [8] whichare being used for
this BNEP connection. The device, which is establishing the
L2CAP connection for BNEP, is required to send this packet and receive a
successful response before sending any additional packets with other
BNEP packet types. This setup packet SHALL be successfully transmitted
to the other device and successfully responded
to by that device before sending any other BNEP packets. In addition,
the BNEP setup message can be used to switch the current roles for the
BNEP connection
1.4.2.2 BNEP_SETUP_ CONNECTION_RESPONSE_MSG
BNEP_SETUP_ CONNECTION_RESPONSE_MSG response message format:
The
BNEP_SETUP_ CONNECTION_RESPONSE_MSG response message format is shown in
the following Figure,The response message shall be used to respond to
each BNEP_SETUP_CONNECTION_REQUEST_MSG control message.
Each of the received setup control messages must be responded to by one
response message.
控制类型的包的解析就到此为止,因为其他的控制包类型都是可选的,就不再累述了。下面描述第二种包。
1.5 BNEP_COMPRESSED_ETHERNET Packet Type
BNEP_COMPRESSED_ETHERNET Packet Type Header Format:
The BNEP_COMPRESSED_ETHERNET packet type header format is shown in the following Figure
his packet type shall be used to carry Ethernet packets to and from devices that are directly connected at
L2CAP
level (have a valid L2CAP connection handle) using BNEP. This
compressed header may be used when two Bluetooth devices are exchanging
packets, in which the source address is set to the local device’s
address which is the source device sending the packet and destination
addresses is set to the other device’s address which is the final
destination for the packet. Devices do not need to include the source
or destination addresses in the packet because the destination address
is always the device’s address that received the packet and the source
address is always the device’s address that sent the packet
1.6 BNEP_COMPRESSED_ETHERNET_SOURCE_ONLY
BNEP_COMPRESSED_ETHERNET_SOURCE_ONLY Packet Type Header:
The header format is based on one of the compressed versions of the Ethernet header supported by BNEP. This
packet
type will be used to carry Ethernet packets to a device using BNEP,
which is the final destination for that packet. Devices do not need to
include the destination address in the packet, because the destination
address of the BNEP packet is the same as the address corresponding to
the L2CAP channel over which the packet is sent.
1.7 BNEP_COMPRESSED_ETHERNET_DEST_ONLY
BNEP_COMPRESSED_ETHERNET_DEST_ONLY Packet Type Header:
This
packet type shall be used to carry Ethernet packets from a device using
BNEP, which is the originator of that packet. Devices do not need to
include the source address in the packet, because the source address can
be determined from the L2CAP connection and which device sent the
packet.The destination may be an IEEE Ethernet address, if the actual
destination is an
IEEE device and not a Bluetooth device.
至此我们在bluedroid BNEP协议的实现中要用到的主要包类型已经描述完毕。下面开始具体的实现环节。
蓝牙pan profile在android bluedroid代码结构中的层次关系如下:
从上到下:hal层提供给上层的调用接口为(callin):btpan_interface_t pan_if,同时上层提供给pan profile的回调接口(callback)为:btpan_callbacks_t。
callin接口用来接收上层的命令,而callback接口用来给上层返回状态等事件。PAN
HAL层以下就是PAN BTA层,也就是pan的应用层,而BTA层以下就是pan 的核心stack层,包含两部分,一个部分是stack
pan,一个部分是stack bnep,前者基于后者,最后bnep是基于l2cap层。
而层与层之间,都是通过callin 和callback来进行交互,最终达到信息在各层次间的交流。
具体到每层的实现,基本都是分为三个子模块:api
submod,main submod,utils submod。其中api submod提供给上层调用该层的接口,而main
submod会提供给上层一个注册函数,用于注册上层的回调函数,另外一个主要功能就是状态机的维护和迁移;在有状态机的模块通常还包含一个action
submod,该模块就是在状态迁移时,需要执行的动作都定义在该模块中;而utils
subsys就是工具和辅助函数。
下图再结合上图,你就可以清楚的看到,一个命令是如何在上层传递到下层,并且命令的事件是如何通过各层的callback从下层传递回上层的。
前面我们知道,BNEP的连接是建立在l2cap连接之上的,从上面的连接时序图中,我们可以清楚的看到,BNEP的连接过程的半段就是l2cap的连接(连接情况的发起,链路的配置等),然后才是BNEP链路的连接。上图中,箭头从左到右的是上层命令传递到下层的一个流程;而箭头从右到左就是命令的事件从下层通过回调传递到上层的流程。
上述的过程,需要注意以太网的头是如何在这个过程被去掉的,并且BNEP的头是如何被添加进来的,最后传递到l2cap层,并由l2cap层添加l2cap的头。
数据接收的过程,就是进来的数据一路从下层回调到上层的过程。
5 从sniffer log看bnep的连接过程(role:panu)
下图就是bnep连接过程,对应的l2cap连接的过程,对应下图包序号的348到355.简单的描述就是链路连接的发起和配置过程。
下面就是在l2cap连接建立的基础上,发起Bnep层的连接的过程,很简单就两个包,然后数据在通讯过程中,基本都是使用的compressed ethernet package,因为发送和接受放都是l2cap的两端,所以src和dest地址都可以省略掉。
在上图中,我们可以看到还有好几个compressed
ethernet dest only 包,这些包其实就是对应的arp request包,因为这些包的dest
地址都是广播地址,并不是l2cap接收端的蓝牙mac地址,所以需要使用这个只包含dest only的compressed ethernet包。