QMI(Qualcomm MSM Interface,官方名称应该是Qualcomm Message Interface)是高通用来替代OneRPC/DM的协议,用来与modem通信。
QMI协议定义了多个服务: DMS(设备管理Device Management) 提供载入 设备信息的功能 NAS(网络访问Network Access)提供欧冠你注册网络的动作 WDS(数据连接) PDS(GPS定位报告) UIM(管理User Identity Module) CTL(控制服务:用户发起其他服务请求前,必须先申请 ClientID, 这个ID就是由控制服务分配的, 这个服务永远在线)
协议里的每个服务都定义了 请求和响应 (也叫做 Indication) 每个请求响应都有一个匹配的ID,这样用户可以一次发出多个请求。并且响应也不必严格按照请求的顺序进行回应。
Indication作为主动提供的消息, 要么发送给某个特定的客户端, 要么是广播消息(广播给所有使用这个服务的客户)。 通常情况下,用户需要通过一些请求/响应 来打开indication
协议中的每条消息都定义了一系列输入(在请求中才有输入)参数,或者输出(在响应或者indications中才有输出)参数。 这些参数,我们命名为TLV
QMI协议可以通过Linux kernels (>= 3.4)来访问。载入cdc-wdm和qmi_wwan之后即可
$ lsmod ... qmi_wwan 20971 0 cdc_wdm 17427 1 qmi_wwan ... usbnet 30844 3 rndis_host,qmi_wwan,cdc_ether usbcore 195340 14 rndis_host,rt2x00usb,usb_storage,rt2800usb,ehci_hcd,ehci_pci,qmi_wwan,usbhid,usbnet,cdc_wdm,xhci_hcd,cdc_ether
https://packages.debian.org/sid/libqmi-glib1 (/usr/lib/x86_64-linux-gnu/libqmi-glib.so.1) https://packages.debian.org/jessie/libqmi-utils (/usr/bin/qmi-network) (/usr/bin/qmicli) https://packages.debian.org/sid/libqmi-glib-dev
设置适当的usb模式
# setprop sys.usb.config diag,serial_smd,serial_tty,rmnet_bam,mass_storage,adb
在PC上可以看到
$ ls -la /dev/cdc* crw------- 1 root root 180, 0 10月 12 20:29 /dev/cdc-wdm0
演示
# qmicli -d /dev/cdc-wdm0 --dms-get-revision [/dev/cdc-wdm0] Device revision retrieved: Revision: ‘M8626A-AAAANAZM-1.1.00759 1 [Dec 31 2013 03:00:00]‘ # qmicli -d /dev/cdc-wdm0 --dms-uim-get-imsi [/dev/cdc-wdm0] UIM IMSI retrieved: IMSI: ‘204043154974997‘ # qmicli -d /dev/cdc-wdm0 --dms-uim-get-iccid [/dev/cdc-wdm0] UIM ICCID retrieved: ICCID: ‘89860313100205205744‘ # qmicli -d /dev/cdc-wdm0 --dms-get-capabilities [/dev/cdc-wdm0] Device capabilities retrieved: Max TX channel rate: ‘1800000‘ Max RX channel rate: ‘3100000‘ Data Service: ‘non-simultaneous-cs-ps‘ SIM: ‘supported‘ Networks: ‘cdma20001x, evdo, gsm‘ # qmicli -d /dev/cdc-wdm0 --dms-get-ids [/dev/cdc-wdm0] Device IDs retrieved: ESN: ‘C33BA980‘ IMEI: ‘355991020927480‘ MEID: ‘A1000051CA0BE1‘ # qmicli -d /dev/cdc-wdm0 --dms-get-band-capabilities [/dev/cdc-wdm0] Device band capabilities retrieved: Bands: ‘bc-0-a-system, bc-0-b-system, gsm-dcs-1800, gsm-900-extended, gsm-850, gsm-pcs-1900‘ LTE bands: ‘(null)‘ v# qmicli -d /dev/cdc-wdm0 --nas-get-system-selection-preference [/dev/cdc-wdm0] Successfully got system selection preference Emergency mode: ‘no‘ Mode preference: ‘cdma-1x, cdma-1xevdo, gsm‘ Band preference: ‘bc-0-a-system, bc-0-b-system, bc-1-all-blocks, bc-2, bc-3-a-system, bc-4-all-blocks, bc-5-all-blocks, gsm-dcs-1800, gsm-900-extended, gsm-900-primary, bc-6, bc-7, bc-8, bc-9, bc-10, bc-11, gsm-450, gsm-480, gsm-750, gsm-850, gsm-900-railways, gsm-pcs-1900, wcdma-2100, wcdma-pcs-1900, wcdma-dcs-1800, wcdma-1700-us, wcdma-850-us, wcdma-800, bc-12, bc-14, wcdma-2600, wcdma-900, wcdma-1700-japan, bc-16, bc-17, bc-18, bc-19‘ LTE band preference: ‘(null)‘ TD-SCDMA band preference: ‘a, b, c, d, e, f‘ CDMA PRL preference: ‘any‘ Roaming preference: ‘any‘ Network selection preference: ‘automatic‘ Service domain preference: ‘cs-ps‘ Service selection preference: ‘wcdma‘
代码 http://cgit.freedesktop.org/libqmi
详细调试信息
v# qmicli -d /dev/cdc-wdm0 -v --dms-get-ids [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Opening device with flags ‘none‘... [12 10月 2014, 20:55:31] [Debug] QMI Device at ‘/dev/cdc-wdm0‘ ready [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Assuming service ‘dms‘ is supported... [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Allocating new client ID... [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Sent message... <<<<<< RAW: <<<<<< length = 16 <<<<<< data = 01:0F:00:00:00:00:00:01:22:00:04:00:01:01:00:02 [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Sent message (translated)... <<<<<< QMUX: <<<<<< length = 15 <<<<<< flags = 0x00 <<<<<< service = "ctl" <<<<<< client = 0 <<<<<< QMI: <<<<<< flags = "none" <<<<<< transaction = 1 <<<<<< tlv_length = 4 <<<<<< message = "Allocate CID" (0x0022) <<<<<< TLV: <<<<<< type = "Service" (0x01) <<<<<< length = 1 <<<<<< value = 02 <<<<<< translated = dms [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Received message... >>>>>> RAW: >>>>>> length = 24 >>>>>> data = 01:17:00:80:00:00:01:01:22:00:0C:00:02:04:00:00:00:00:00:01:02:00:02:03 [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Received message (translated)... >>>>>> QMUX: >>>>>> length = 23 >>>>>> flags = 0x80 >>>>>> service = "ctl" >>>>>> client = 0 >>>>>> QMI: >>>>>> flags = "response" >>>>>> transaction = 1 >>>>>> tlv_length = 12 >>>>>> message = "Allocate CID" (0x0022) >>>>>> TLV: >>>>>> type = "Result" (0x02) >>>>>> length = 4 >>>>>> value = 00:00:00:00 >>>>>> translated = SUCCESS >>>>>> TLV: >>>>>> type = "Allocation Info" (0x01) >>>>>> length = 2 >>>>>> value = 02:03 >>>>>> translated = [ service = ‘dms‘ cid = ‘3‘ ] [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Registered ‘dms‘ (version unknown) client with ID ‘3‘ [12 10月 2014, 20:55:31] [Debug] Asynchronously getting IDs... [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Sent message... <<<<<< RAW: <<<<<< length = 13 <<<<<< data = 01:0C:00:00:02:03:00:01:00:25:00:00:00 [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Sent message (translated)... <<<<<< QMUX: <<<<<< length = 12 <<<<<< flags = 0x00 <<<<<< service = "dms" <<<<<< client = 3 <<<<<< QMI: <<<<<< flags = "none" <<<<<< transaction = 1 <<<<<< tlv_length = 0 <<<<<< message = "Get IDs" (0x0025) [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Received message... >>>>>> RAW: >>>>>> length = 66 >>>>>> data = 01:41:00:80:02:03:02:01:00:25:00:35:00:02:04:00:00:00:00:00:12:0E:00:41:31:30:30:30:30:35:31:43:41:30:42:45:31:10:08:00:43:33:33:42:41:39:38:30:11:0F:00:33:35:35:39:39:31:30:32:30:39:32:37:34:38:30 [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Received message (translated)... >>>>>> QMUX: >>>>>> length = 65 >>>>>> flags = 0x80 >>>>>> service = "dms" >>>>>> client = 3 >>>>>> QMI: >>>>>> flags = "response" >>>>>> transaction = 1 >>>>>> tlv_length = 53 >>>>>> message = "Get IDs" (0x0025) >>>>>> TLV: >>>>>> type = "Result" (0x02) >>>>>> length = 4 >>>>>> value = 00:00:00:00 >>>>>> translated = SUCCESS >>>>>> TLV: >>>>>> type = "Meid" (0x12) >>>>>> length = 14 >>>>>> value = 41:31:30:30:30:30:35:31:43:41:30:42:45:31 >>>>>> translated = A1000051CA0BE1 >>>>>> TLV: >>>>>> type = "Esn" (0x10) >>>>>> length = 8 >>>>>> value = 43:33:33:42:41:39:38:30 >>>>>> translated = C33BA980 >>>>>> TLV: >>>>>> type = "Imei" (0x11) >>>>>> length = 15 >>>>>> value = 33:35:35:39:39:31:30:32:30:39:32:37:34:38:30 >>>>>> translated = 355991020927480 [/dev/cdc-wdm0] Device IDs retrieved: ESN: ‘C33BA980‘ IMEI: ‘355991020927480‘ MEID: ‘A1000051CA0BE1‘ [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Releasing ‘dms‘ client with flags ‘release-cid‘... [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Unregistered ‘dms‘ client with ID ‘3‘ [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Sent message... <<<<<< RAW: <<<<<< length = 17 <<<<<< data = 01:10:00:00:00:00:00:02:23:00:05:00:01:02:00:02:03 [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Sent message (translated)... <<<<<< QMUX: <<<<<< length = 16 <<<<<< flags = 0x00 <<<<<< service = "ctl" <<<<<< client = 0 <<<<<< QMI: <<<<<< flags = "none" <<<<<< transaction = 2 <<<<<< tlv_length = 5 <<<<<< message = "Release CID" (0x0023) <<<<<< TLV: <<<<<< type = "Release Info" (0x01) <<<<<< length = 2 <<<<<< value = 02:03 <<<<<< translated = [ service = ‘dms‘ cid = ‘3‘ ] [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Received message... >>>>>> RAW: >>>>>> length = 24 >>>>>> data = 01:17:00:80:00:00:01:02:23:00:0C:00:02:04:00:00:00:00:00:01:02:00:02:03 [12 10月 2014, 20:55:31] [Debug] [/dev/cdc-wdm0] Received message (translated)... >>>>>> QMUX: >>>>>> length = 23 >>>>>> flags = 0x80 >>>>>> service = "ctl" >>>>>> client = 0 >>>>>> QMI: >>>>>> flags = "response" >>>>>> transaction = 2 >>>>>> tlv_length = 12 >>>>>> message = "Release CID" (0x0023) >>>>>> TLV: >>>>>> type = "Result" (0x02) >>>>>> length = 4 >>>>>> value = 00:00:00:00 >>>>>> translated = SUCCESS >>>>>> TLV: >>>>>> type = "Release Info" (0x01) >>>>>> length = 2 >>>>>> value = 02:03 >>>>>> translated = [ service = ‘dms‘ cid = ‘3‘ ] [12 10月 2014, 20:55:31] [Debug] Client released
参考资料 http://sigquit.wordpress.com/2012/08/20/an-introduction-to-libqmi/ http://www.lanedo.com/users/amorgado/talks/FOSDEM2013%20-%20Mobile%20broadband%20modem%20control%20protocols.pdf http://blogs.gnome.org/dcbw/2010/04/15/mobile-broadband-and-qualcomm-proprietary-protocols/
usb网络接口 ECM: Ethernet Control Model 802.3 ethernet frames 以太网控制模型
NCM: Network Control Model
MBIM协议 (由高通,爱立信,微软等开发, USB论坛发布) 内核驱动是 cdc_mbim (Linux Kernel >= 3.8) 设备是 /dev/cdc-wdm libmbim mbimcli(libmbim-utils)
mbimcli -d /dev/cdc-wdm1 --basic-connect-query-subscriber-ready-status
在ChromiumOS上也实现了部分QMI协议 https://chromium.googlesource.com/chromiumos/platform/libqmi/+/master/src/