高通QMI架構簡介

 

 

什麼是QMI?

Qualcom Message Interface  高通信息接口

 

背景:2005-2006年部署(原高通MSMTM接口),所有服務最初都是由DATA團隊設計和維護的,功能是按照AT命令標準構建的,主要用於連接管理器類型應用程序,可通過USB連接(QMUX傳輸)連接到電腦。

2009年QMI取代RPC(Remote Procedure Call),QMI的範圍開始擴大,無線電接口層(RILs)開始向QMI過渡,並定義了必要的支持;底層由更健壯的通信(IPC路由器傳輸)替代,通過共享內存方式(SMD)在片上SOC之間可用。

 

高通平臺目前都是非對稱多核心,最主要的是AP和Modem。兩個處理器怎麼進行通信呢,我們把AP和Modem當作兩個主機,問題就變得了很簡單,TCP/IP協議不是一種非常成功的進程間跨主機通信方式。高通沒有采用這種方式,但是借鑑了TCP/IP的框架設計。它的框架是這樣的,內核態:基於共享內存(SMD)實現鏈路層,擴展協議域;用戶態,封裝出類似於socket函數的接口,用於用戶態使用。而我所描述的QMI就是用戶態使用的API接口,這些接口非常類似於socket,只要有個socket編程的經驗的是會容易理解的。

 

 

QMI提供什麼?

支持同步和異步接口;

支持在在多個處理器之間進行通信;

具有良好的可擴展性;

支持多客戶端併發運行;

支持多個服務端併發運行,且每個服務端還對應多個客戶端;

每個服務端還支持版本信息;

QMI架構

 

Messages

Request message ——一條request消息由客戶端發往服務端,並由服務端進行處理。

 

Reponse message——每一個request的消息都會有一個reponse消息與之對應,類似於一個函數的返回值。如果請求消息等效於調用函數,則響應消息等效於返回給調用方的結果。

 

Indiction message——這類消息是由服務端發給客戶端的異步消息,在任何indication message發送之前,客戶端首先需要通過request message與服務端建立連接,indication消息可以在任何時候發送。

消息的特點:

  1. 消息由Type-Length-Value(TLV)單元構成;
  2. 類型和長度是固定大小,而值是可變長度的;
  3. 每個消息中可以出現多個tlv值;
  4. 可以在該值中顯示多個數據元素;
  5. 對於每個消息的TLV id都是唯一的;

消息的結構:

  1. 由傳輸頭和服務級消息組成
  2. 每個傳輸的傳輸頭都是唯一的

Service Message服務級負載對於所有傳輸都是通用的,幷包含以下元素

消息ID

消息長度

零或多個可變長度的tlv

Clients

  1. 任何想要使用QMI的內部或外部客戶端應用程序

 

Services

  1. 任何想要使用QMI的內部應用服務程序

Common Libraries

  1. 爲客戶端(QCCI)和服務(QCSI)提供功能
  2. 通用API適用於所有平臺/傳輸
  3. 封裝傳輸和特定於平臺的更改,以便共享客戶機/服務代碼
  4. 爲每個服務消息提供編碼/解碼支持

 

Transports

QMUX

  1. 高通多路複用協議(QMUX);
  2. 原始傳輸通過一個有線USB以太網適配器;
  3. 支持MPSS處理器上的服務;
  4. 支持在應用程序(APPS)處理器或usb連接的主PC上的客戶端;
  5. QMUX的客戶端是用於特定於平臺的,不同平臺可能有差異;

 

IPC Router

  1. IPC路由器是一個面向消息(message-oriented)的路由器,用於支持Qualcomm QCCI QCSI;
  2. 增強了同一設備上處理器之間的傳輸;
  3. 通過SMD在路由節點之間傳遞QMI有效負載;
  4. 支持任何處理器上的客戶端和服務;
  5. API對於所有平臺都是通用的,即使實現不同;

 

QMI IDL

QMI接口是用接口定義語言(IDL)編寫的,IDL編譯器自動生成文件 .c和.h

 

編碼/解碼庫

  1. 庫是獨立的,並且與自動生成的文件解耦
  2. 編碼/解碼消息的元信息將在.c作爲Service_Object生成
  3. 在服務/客戶機啓動期間,元信息將註冊到QCSI/QCCI進行消息編碼/解碼
  4. 客戶端/服務可以使用QCCI/QCSI API發送/接收消息

QMI消息編碼標準

1. 不使用浮點型數據,而是使用Q16類型的固定點數,即提供16位2位補碼整數部分和16位小數部分的定點實現。

2. 命名約定

  1. 爲了使所有消息實現保持一致,service端需要固定的獨有的前綴
  2. 結構體以_type結尾
  3. 枚舉以_enum結尾
  4. 請求消息以_req_msg結尾,類型以_REQ結尾
  5. 消息迴應以_resp_msg結尾,類型以_RESP結尾
  6. 指示消息以_ind_msg結尾,類型以_IND結尾

 

 

QMI QCCI

QCCI是一套用於客戶端從服務器接收信息或者發送消息到服務器的API集合。

 

以下步驟描述初始化客戶機:

 

1. QMI客戶機創建一個通知句柄來接收服務到達和退出事件通知。然後是客戶端

用notifier句柄註冊一個通知回調函數;

 

2. 當服務到達時,將設置信號,並調用通知回調函數來客戶端關於服務到達的消息;

 

3.QMI客戶機在收到服務到達通知後解析服務地址;

 

4. QMI客戶機初始化服務的客戶機句柄,該服務的地址在步驟3中解析。然後,這個客戶端句柄用於與相關的QMI服務交換QMI消息;

 

5. 初始化客戶端句柄時,將向客戶端句柄註冊一個錯誤回調函數。此錯誤回調用於接收關於服務重啓或子系統重啓的任何通知;

 

6. 此時,QMI客戶機可以釋放notifier句柄,以避免任何資源泄漏;

 

7. QMI客戶機同步或異步發送請求消息,如上圖所示;

 

8. 當所有相關的QMI消息通信完成時,QMI客戶機釋放客戶機句柄。

 

QCCI APIs Callback function prototypes

  1. qmi_client_recv_raw_msg_async_cb
  2. qmi_client_recv_msg_async_cb
  3. qmi_client_ind_cb

Connection APIs

  1. qmi_client_notifier_init
  2. qmi_client_init
  3. qmi_client_get_service_list

Message sending APIs

  1. qmi_client_send_raw_msg_sync
  2. qmi_client_send_msg_sync
  3. qmi_client_delete_async_txn

Release connection APIs

  1. qmi_client_release

Encode and decode APIs

  1. qmi_client_message_encode
  2. qmi_client_message_decode

QMI QCSI

QCSI是用於接收客戶端的請求及對其作出響應。另外,它也用來發送指示消息(indication message)以及對消息進行編解碼(encode/decode),這個消息由server端主動發出。

消息的類型有如下三種:

Request message ——一條request消息由客戶端發往服務端,並由服務端進行處理。

Reponse message——每一個request的消息都會有一個reponse消息與之對應,類似於一個函數的返回值。如果請求消息等效於調用函數,則響應消息等效於返回給調用方的結果。

Indiction message——這類消息是由服務端發給客戶端的異步消息。在任何indication message發送之前,客戶端首先需要通過request message與服務端建立連接。indication消息可以在任何時候發送。Callback function prototypes

  1. qmi_csi_connect
  2. qmi_csi_disconnect
  3. qmi_csi_process_req

Registration APIs

  1. qmi_csi_register
  2. qmi_csi_unregister

Message sending APIs

  1. qmi_csi_send_resp
  2. qmi_csi_send_ind
  3. qmi_csi_send_broadcast_ind

Event handling APIs

  1. qmi_csi_handle_event

QMI SERVER

這個api構建在QCSI框架之上

其主要目的是方便客戶機以更少的工作量實現服務器

該框架允許用戶編寫基於對象的服務器,擴展核心服務器對象。核心服務器對象提供每個服務都需要的通用功能

 

Callback Function Prototypes

  1. qmi_csi_connect
  2. qmi_csi_disconnect
  3. qmi_csi_process_req

Constructor/Destructor APIs

  1. qmi_core_server_new
  2. qmi_core_server_delete

Registration APIs

  1. qmi_core_server_register
  2. qmi_core_server_unregister
  3. qmi_core_server_register_client
  4. qmi_core_server_unregister_client

Message Dispatch APIs

  1. qmi_core_server_dispatch_msg
  2. qmi_core_server_send_ind
  3. qmi_core_server_send_resp

QMUX

QMI Multiplexing Protocol(QMUX):QMI的複用協議

消息從控制點經過類似socket的線程傳到QMI接口後,QMI負責對數據進行封裝,加上QMUX消息的頭,發送到QMUX層,

再通過QMUX層傳到共享內存到BP側。

QMUX消息的格式:

 

整個QMUX控制信道的結構如上圖,

  1. I/FType:QMI將控制點數據封裝後,發送到QMUX前,加的消息頭,長度爲一個byte,值通常爲0x01,表示這個消息爲QMUX消息,如果是其他值,則爲其他消息。
  2. Length: QMUX消息的長度,不包括I/F Type。
  3. ControlFlags:控制位,表示消息傳輸的方向。長度爲1個byte,只有第7個bit是標誌位,其他位爲0,bit7=1說明QMUX消息由服務端發送,bit7=0由控制點發送。
  4. Clien ID: 控制點的標識,在控制點和服務端都需要賦值,當在服務端發出的消息Client ID的值爲0xFF,表示該消息爲廣播消息,由服務端主動發出,被所有控制點搜到。

QMUX SDU和TLV結構:

在整個控制信道的消息中,出去消息標識頭I/F Type,和QMUX消息頭,數據傳輸在QMUXSDU中完成,QMUX SDU裏面的數據需要支持Type Length Value(TLV)的格式。

 

TLV格式的數據存放在QMI Service Message裏面的Value中。

  1. Control Flags:表示消息是請求、響應還是指示。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章