1. 程式人生 > >5 android QMI機制---底層訊息傳送

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側的。