硬件平台:MT2503A
软件平台:CORETEK03A_11C_PCB01_gprs_MT6261_S00.MAUI_11C_W13_52_SP3_V2_F32
想在MT2503A上 使用蓝牙串口收发数据,用手机蓝牙助手测试,发现每次发送数据,都是原样返回,且MMI不能接收到ready to read的消息,MMI只能接收到Connect 和
disconnect事件。
BT SPP从底层到应用层的消息传递顺序:
Driver-->MOD_BT-->SppSrv.c-->BTMMISpp.c
后来看文档发现,BT SPP server默认将数据发送给MOD_ATCI,而不是MOD_MMI。
如果接收到的数据是 AT开头、\r\n结尾的,则进入custom_command_hdlr()处理,否则进入L4 ATCI的流程中,这个流程是被封装的,代码不可见。
经过多次测试发现,mtk是这么管理uart的,每个uart都有一个owner,一个模块只能当uart属于自己的时候,读写操作才能成功。
使用srv_spp_write()来发送数据是不会成功的,因为BT SPP uart默认属于MOD_ATCI. 同样ready to read 消息也不会发送到MMI。
在custom_command_hdlr()中是使用rmmi_write_to_uart()来发送数据,但是这个函数在mmi_bt_spp_connect_ind()中调用,不能成功发送数据,
这个函数是被MTK封装好的,不可见。
U32 srv_spp_write(U32 conn_id, void* buf, U32 size)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
UART_CTRL_OWNER_T port_owner;
UART_CTRL_PUT_BYTES_T data;
srv_spp_conn_cntx* conn = srv_spp_get_conn_by_conn_id(conn_id);
DCL_HANDLE dcl_handle = DclSerialPort_Open(conn->port, 0);
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
DclSerialPort_Control(dcl_handle, SIO_CMD_GET_OWNER_ID, (DCL_CTRL_DATA_T*)&port_owner);
if (
port_owner.u4OwenrId != MOD_MMI || conn->conn_state != SRV_SPP_CONN_STATE_CONNECTED)
return 0;
data.u4OwenrId = MOD_MMI;
data.puBuffaddr = buf;
data.u2Length = size;
DclSerialPort_Control(dcl_handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*)&data);
SRV_SPP_LOG4(SRV_BT_SPP_WRITE, conn_id, buf, size, data.u2RetSize);
return data.u2RetSize;
}
要想成功接收、发送蓝牙串口数据,测试有效的做法是:
1 接收:
在custom_cmd_table【】中添加command string和相应的handler function,这样就能在custom_command_hdlr()接收。
发送AT开头,\r\n结尾的数据给设备;
2 发送:
以MOD_ATCI为owner 去发送数据。
example:
{
CHAR buf[] = "hello";
UART_CTRL_OWNER_T port_owner;
UART_CTRL_PUT_BYTES_T data;
DCL_HANDLE dcl_handle = DclSerialPort_Open(conn_ind->port, 0);
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
DclSerialPort_Control(dcl_handle, SIO_CMD_GET_OWNER_ID, (DCL_CTRL_DATA_T*)&port_owner);
// if (conn->conn_state != SRV_SPP_CONN_STATE_CONNECTED)
// return ;
kal_prompt_trace(MOD_TST, "%s: ownerid is %d", __func__, port_owner.u4OwenrId);
kal_prompt_trace(MOD_TST, "%s: MOD_ATCI is %d", __func__, MOD_ATCI);
kal_prompt_trace(MOD_TST, "%s: MOD_MMI is %d", __func__, MOD_MMI);
kal_prompt_trace(MOD_TST, "%s: MOD_BT is %d", __func__, MOD_BT);
data.u4OwenrId = MOD_ATCI;
data.puBuffaddr = buf;
data.u2Length = strlen(buf);
DclSerialPort_Control(dcl_handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*)&data);
}