原文:https://blog.csdn.net/u012439416/article/details/74276967?utm_source=blogxgwz0
5 底层消息发送
在linux_qmi_qmux_if_server.c文件的入口main()函数,通过一个select来监听所有从
linux_qmi_client端发出的socket,通过for循环调用linux_qmi_qmux_if_server_process_client_msg()
处理这些监听的消息。进入到函数linux_qmi_qmux_if_server_process_client_msg()后,
通过recv函数将监听的socket的消息写入buf_size这个buffer里面。调用流程图如下,if ((buf_size = recv (fd, (void*)&platform_msg_hdr,
QMI_QMUX_IF_PLATFORM_SPECIFIC_HDR_SIZE,0))<= 0)
if ((buf_size = recv (fd, (void*)&platform_msg_hdr,
QMI_QMUX_IF_PLATFORM_SPECIFIC_HDR_SIZE,0))<= 0)
recv方法在接收socket时,并没有全部接收。而且只接收了platform_msg_hdr。这个platform_msg_hdr
是在linux_qmi_qmux_client里面定义的,server接收到后,首先会判断从client端发过来的这个消息是否正常,
包括client_id和消息长度。
remaining_bytes = (size_t) platform_msg_hdr.total_msg_size - QMI_QMUX_IF_PLATFORM_SPECIFIC_HDR_SIZE;
if ((buf_size = recv (fd, (void *)linux_qmi_qmux_if_rx_buf, remaining_bytes, 0)) <= 0)
如果client_id匹配不上 或时消息长度溢出,都会将消息丢弃,不会发送。如果判断消息没问题,就会将其余的消息
(除去platform_msg_hdr)再次通过recv()函数从socket中接受,放到remaining_bytes这个buffer中,
用qmi_qmux_tx_msg方法继续处理。
在qmi_qmux_tx_msg()函数中,又会对之前打包好的QMUX消息进行去头,拆分。
判断QMUX header中的message_id,如果是QMI_MSG,则会调用函数qmi_qmux_tx_to_modem(),
将拆分后的service_id,client_id等发送到下层。
{
rc = qmi_qmux_tx_to_modem( msg_hdr.qmi_conn_id,
msg_hdr.qmi_service_id,
msg_hdr.qmi_client_id,
msg,
msg_len );
}
接下来在函数qmi_qmux_tx_to_modem(),对QMUX整个控制信道消息的头进行一个重组,包括I/F Type。
完成QMI整个control channel message的构建。
/* I/F type is 1 for a QMUX message */
WRITE_8_BIT_VAL (tmp_msg_ptr, 1);
/* Length is length of message to send which includes the QMUX header, but since
** QMI_QMUX_HDR_SIZE includes the I/F byte and the length field in a QMUX
** message doesn't include this, we need to subtract 1
*/
WRITE_16_BIT_VAL (tmp_msg_ptr, (msg_len - 1));
/* Control flags byte should be set to 0 for control point */
WRITE_8_BIT_VAL (tmp_msg_ptr, 0);
/* Now put in service type and client ID */
WRITE_8_BIT_VAL (tmp_msg_ptr, service_id);
WRITE_8_BIT_VAL (tmp_msg_ptr, client_id);
然后通过宏QMI_QMUX_IO_PLATFORM_SEND_QMI_MSG调用ARM侧进入共享内存和BP侧交互的
IO口函数linux_qmi_qmux_io_send_qmi_msg(),
qmi_platform_qmux_io.h中的宏定义如下,
#define QMI_QMUX_IO_PLATFORM_SEND_QMI_MSG(conn_id,msg_buf,len) \
linux_qmi_qmux_io_send_qmi_msg (conn_id,msg_buf,len)
在这个linux_qmi_qmux_io_send_qmi_msg读写函数中,判断如果当前AP侧和BP侧的连接通道是
激活状态的话,就通过write函数,将打包好的QMI消息,写入连接通道信息里面的f_desc参数,
ret = write(conn_info->f_desc, (void*) msg_ptr, (size_t)msg_len);
到此,整个ARM流程结束。以上主要介绍AP侧要发送一个请求到BP侧,QMI是怎么对请求进行编码
成QMUX消息,怎么将编码后的QMUX消息加头组合成一种AP和BP可共同识别的消息格式,
最后是怎么发送到BP侧的。