图3 A2DP框架具体模块划分
2 消息传递机制
该轻型框架模块协议层之间的交互是通过消息传递机制来实现的,消息的种类可分为以下4种。
①请求消息REQ
该消息是上层协议向下层协议主动发出的请求。
②确认消息CFM
上层协议发出的每个REQ消息,都会收到下层协议发上来的确认。
③指示消息IND
该消息是下层协议向上层协议主动发起的告知。
④响应消息REP
对于每个下层协议主动发上来的IND消息,上层协议都对此消息进行响应。
图4 协议间的消息传递
协议间的消息传递如图4所示。
采用基于消息传递机制的实现方法的优点如下:
①协议层之间交互通过固定的消息接口,即使上下层协议模块升级,也不会影响本层协议模块的功能,有很好的移植性和可复用性。
②各层协议都是异步通信,可以大大降低拥塞情况的发生。
③协议栈进程可以在上层管理一个消息队列,统一进行消息收发,当消息向下传递过程中遭到拒绝时,可以实现消息的重传功能。
④与每层协议都用一个单独的任务来实现相应功能相比,采用消息机制的方法节省了系统调度时间,更具有实时性,同时避免了死锁的发生。
3 重要数据结构
①消息结构体
消息结构体分为3个域:发送模块Id、接收模块Id、消息枚举类型。具体定义如下:
typedef struct
{
BT_ModuleId sender;
BT_ModuleId receiver;
BT_Primitive primitive;
} BT_Header;
②流端点结构体
流端点SEP存在于应用层中,而应用层又在AVDTP中注册它的SEP,使其他设备可以发现和连接。SEP在3个模块—A2DP、GAVDP、AVDTP中有着不同的结构体类型,以适应本层协议的特殊作用。以A2DP模块为例,其SEP结构体具体定义如下:
typedef struct
{
GAVDP_Handle streamHandle;
BT_U8 *codecInfoElement;
BT_U8 lengthInfoElements;
AVDT_MediaCodecType codecType;
ChannelConfig configuration;
AVDT_ResponseCode pendingRspCode;
BT_TimerId resendTimerId;
} StreamEndPoint;
4 各模块主要功能及消息接口
各模块是通过自己的消息函数来接收不同的枚举消息,并转向各自的消息处理函数,下面具体分析每个模块所实现功能。
①A2DP模块
A2DP模块实现了通过GAVDP管理SEP和SEP能力的功能,并且在SRC和SNK之间为音频流文本设置和配置了流通道。根据A2DP模块的通信流程把它的消息接口分为6种类型:流设置消息,它又可分为对等流端点发现和流配置两个步骤;流通道释放消息;开始/挂起流消息;配置/重新配置消息;发现/得到能力消息;媒体流开始消息。
②GAVDP模块
GAVDP模块从多个使用者角度出发,管理本地流SEP和SEP能力的注册,处理从远程设备发来的发现查询请求和得到能力请求,同时基于用户注册的SEP信息,自动发送响应。
由于GAVDP模块的功能是上层A2DP模块的细化,因此可以将GAVDP的消息接口和A2DP模块的接口类型作一致性设计,两者消息接口类型基本相同。
③AVDTP模块
AVDTP模块负责建立一个到远程蓝牙设备的AVDTP信令通道,并借助于AVDTP协议发送所有的信令命令,同时为媒体流建立传输通道,必要的话为校验和报告也建立通道,另外还支持信令和媒体消息的分段。AVDTP模块数据通信最基本的流程为SEP发现→获取SNK能力→数据流配置→数据流建立→数据流开始→数据流挂起→数据流重新配置→数据流释放。相应的SEP在AVDTP模块中的状态机如图5所示。
图5 SEP在AVDTP模块中的状态机
整个通信过程各个状态之间的跃迁靠下列消息来触发:
A:AVDT_SET_CONFIGURATION _REQ
B:AVDT_OPEN_REQ
C:AVDT_START_REQ
D:AVDT_SUSPEND_REQ
E:AVDT_CLOSE_REQ
F:AVDT_ABORT_REQ
G:AVDT_RECONFIGURE_REQ
H:AVDT_MEDIA_REQ
在空闲状态下,发送A消息之前,空闲状态下要发出一系列动作,包括连接请求、发现请求和获取SNK能力请求等。从空闲态到配置态的跃迁过程,本协议栈统称为流设置过程。
在打开状态下发送C消息之后,就进入了流控状态,此时通过H消息就可以发送从SRC到SNK的媒体流数据包。
在通信过程中的任何状态下,都可以通过发送F消息,进入中止态,进而回到没有连接任何远程SEP的空闲状态。
测试及结论
该轻型协议栈的实现与测试,可以基于CSR先进的BlueCore4蓝牙芯片来完成。该芯片支持蓝牙2.0+EDR规范,并提供2.1Mb/s的数据传输速率,比标准蓝牙快3倍,可实现更快速的连接,同步支持多个蓝牙链路,以及音频流等更宽带宽的新兴应用。最上层的音频应用程序实现了一个简单的具有处理SBC格式编解码信息的播放器,该应用程序和部分高层协议栈通过交叉编译,下载到硬件平台主机端。而播放器程序是通过调用本协议栈提供的API,进行音频数据流分发。对于音频数据的接收端SNK,采用摩托罗拉HT820立体声耳机进行测试,在长时间播放音频数据的情况下,仍然会存在音频停顿的现象。使用一种截获空中蓝牙信号并进行协议分析的工具Airsniffer,抓取流媒体传输数据包,经分析,音频数据并未丢失,而是流控机制存在问题,需要进一步完善。