5 android QMI機制---底層訊息傳送
原文: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側的。