蓝牙技术在音频网关中的应用
在软件中,一个服务原语是一个结构。结构名一般采用原语_T。结构成员包括这些原语的类型及相关的载荷数据,如CM的查询请求服务结构定义如下:
在软件中,一个服务原语是一个结构。结构名一般采用原语_T。结构成员包括这些原语的类型及相关的载荷数据,如CM的查询请求服务结构定义如下:
typedef struct{
uint8 max_response; //可被接收的最大查询响应数
Delay inq_timeout; //用户提供的查询处理超时时长
uint32 class_of_device; //设备类型
uint16 remote_name_request_enabled; //标志位指示是否完成远程名的请求
}CM_INQUIRY_REQ_T;
以下给出了消息的提交。其中,宏MAKE_MSG表示创建该消息,msg为该消息结构的指针,将消息送入队列用MessagePut函数来完成。
*AG客户机
MAKE_MSG(CM_INQUIRY_REQ);
msg->max_responses=num_responses;
msg->inq_timeout=D_SEC(timeout);
msg->class_of_device=CoD_filter;
msg->remote_name_request_enabled=rnr_en;
MessagePut(0,msg);
}
*CM
{
MAKE_MSG(CM_INQUIRY_COMPLETE_CFM);
msg->status=status;
MessagePut(1,msg);
}
(3)消息处理
对某一消息队列中的消息,由相应的任务来完成,调度程序运行消息队列不为空的任务。在应用程序中,任务用宏定义“DECLARE_TASK”来声明,用参数来标识某个任务。参数必须为整数,表示其任务号。分别在AG客户机程序和CM中声明任务1和任务0。程序结构如下:
*AG客户机程序中的任务1:处理来自CM的消息DECLARE_TASK(1)
{
void *msg;
MessageType type;
/*取出队列中的消息,其中的参数必须与DECLARE_TASK中的一致*/
msg=MessageGet(1,&type);
if(msg)
{
switch(type)
{
/*Connection Manager is ready to be used*/
case CM_INIT_CFM:
agInitCfm();
break;
/*Connection Manager has been initializedand is ready for action*/
case CM_OPEN_CFM:
.
.
.
}
MessageDestroy(msg);/*释放消息*/
}
}
*CM程序中的任务0:处理来自AG客户机的消息DECLARE_TASK(0)
DECLARE_TASK(0)
{
MessageType type;
Void *msg=MessageGet(0,&type);
if(!msg)return;
switch(type)
{
/*Request to initialise the connection manager*/
case CM_INIT_REQ:
cmInitAction((CM_INIT_REQ_T*)msg);
break;
.
.
.
}
MessageDestroy(msg);
}
javascript:window.open(this.src);" style="cursor:pointer;"/>
3.3 调度
整个应用程序的实现是事件驱动的。在AG应用中,事件包括BlueStack事件、PIO事件、RFCOMM源端及目的端事件。所有事件的处理以及前面介绍的消息队列中的消息处理均由调度程序来执行。调度程序由高层应用程序启动,而各事件及消息处理分布在各软件层中。图5给出调度程序的流程。
4 结论
本文提出的音频网关,通过普通手机的音频口进行连接。经测试,可与市售的蓝牙耳麦及自行研制的蓝牙耳麦进行配对、通话。操作过程如下。①当AG启动时,若AG原先已经配对,则直接进入连接模式。②若原先未配对,有两种情况:如果AG内已经存储有识别码(PINcode),则开始查询耳麦与之配对;如果无PIN码,则进入PIN输入模式,输入PIN码。此PIN码要与所要配对的耳麦的PIN码一致。当配对成功后,AG即进入可连接模式(作为子设备连接)。在此种模式下,AG处于寻呼扫描状态,耳麦可与之连接。AG也可作为主设备连接耳麦。此时,AG与耳麦建立一个RFCOMM连接,AG可发送AT命令给耳麦。AG和HS之间也可建立SCO连接,进行音频传输。