USBでQMIを学ぶ

# 認識できたが接続できず
[前の記事](http://qiita.com/air-gh/items/6add3c0b19e8fe9469aa)で、L-03Dの認識はできたものの、`qmicli`の`--wds-start-network`ではAPNに接続できなかった。
何だかくやしい。USBモデムの制御インターフェースである、QMIを勉強するモチベーションになりそう。

# libqmi
## qmicli
`qmicli --verbose`とすると、QMIのバイト列の意味をご丁寧に説明してくれる。

```shell-session
# qmicli --verbose -d /dev/cdc-wdm0 --get-service-version-info
[26 Apr 2016, 22:57:24] [Debug] [/dev/cdc-wdm0] Opening device with flags 'none'...
[26 Apr 2016, 22:57:24] [Debug] QMI Device at '/dev/cdc-wdm0' ready
[26 Apr 2016, 22:57:24] [Debug] Getting service version info...
[26 Apr 2016, 22:57:24] [Debug] [/dev/cdc-wdm0] Sent message...
<<<<<< RAW:
<<<<<<   length = 12
<<<<<<   data   = 01:0B:00:00:00:00:00:01:21:00:00:00

[26 Apr 2016, 22:57:24] [Debug] [/dev/cdc-wdm0] Sent message (translated)...
<<<<<< QMUX:
<<<<<<   length  = 11
<<<<<<   flags   = 0x00
<<<<<<   service = "ctl"
<<<<<<   client  = 0
<<<<<< QMI:
<<<<<<   flags       = "none"
<<<<<<   transaction = 1
<<<<<<   tlv_length  = 0
<<<<<<   message     = "Get Version Info" (0x0021)
:
```

ふーん。雰囲気はわかった。0x0021はGet Version Infoなのね。

## `qmi_message_get_printable()`
libqmiに、[`qmi_message_get_printable()`](https://www.freedesktop.org/software/libqmi/libqmi-gli![qmi1.tiff](https://qiita-image-store.s3.amazonaws.com/0/104225/4397780f-2be5-5caa-f0dd-2e6e8f36c455.tiff)
b/latest/libqmi-glib-QmiMessage.html#qmi-message-get-printable)という便利関数があるのを発見。

> Gets a printable string with the contents of the whole QMI message.
> If known, the printable string will contain translated TLV values as well as the raw data buffer contents.

とのことで、きっとバイナリ列を食わせると`qmicli --verbose`みたいな表示をしてくれるはず。

# USBPcap
USBプロアナはさすがに持っていないが、Windowsで動かしながらなら、[USBPcap](http://desowin.org/usbpcap/)でできる。
最近はWiresharkのデフォルトインストーラーから簡単に入れられるはず。

## Wiresharkでキャプチャする
Ethernetのキャプチャと同じ。USBを選ぶだけ。
QMIは、USBのControl転送を用いている模様。
実際にWindowsでL-03Dを動かして、表示をフィルタした様子がこれ。

<img width="919" alt="qmi1.png" src="https://qiita-image-store.s3.amazonaws.com/0/104225/4d88ab5f-2f24-82a5-6f4f-c0eb66276bb3.png">

よーく見ると、さっきの`qmicli --get-service-version-info`に出てくる、'21:00'というのが入っている。その先がちょっと違うけど。
これをExportして`qmi_message_get_printable()`に食わせれば、色々わかるのでは。

## WiresharkでExportする
フィルタしたパケットだけをPlain Textで、かつUSBヘッダは取り除いてペイロードだけをExportする。

<img width="523" alt="qmi2.png" src="https://qiita-image-store.s3.amazonaws.com/0/104225/dd11a63d-9d6e-f3c5-a539-b39a3a71709b.png">

結果はこんな感じ。

```
0000  1c 00 e0 cd 84 af ff ff ff ff 00 00 00 00 08 00   ................
0010  01 03 00 05 00 80 02 01 00 00 00 01 00            .............

0000  1c 00 58 28 79 bc ff ff ff ff 00 00 00 00 08 00   ..X(y...........
0010  01 03 00 05 00 00 02 10 00 00 00 01 01 0f 00 00   ................
0020  00 00 00 01 21 00 04 00 01 01 00 ff               ....!.......
:
```

ほほう。パケットの切れ目も、わかりやすい。

# 適当パーサー + `qmi_message_get_printable()`

qmicliを下敷きに適当に作ってみたのが、[これ](https://github.com/air-gh/qmiparse)。
下敷きにしすぎて、libqmiのbuild環境に依存。

ExportしたPlain Textを食わせた結果は…

```
len = 1
bin = 00
(null)---------------------------------------------------------------------------
len = 16
bin = 01 0f 00 00 00 00 00 01 21 00 04 00 01 01 00 ff
QMUX:
  length  = 15
  flags   = 0x00
  service = "ctl"
  client  = 0
QMI:
  flags       = "none"
  transaction = 1
  tlv_length  = 4
  message     = "Get Version Info" (0x0021)
TLV:
  type   = 0x01
  length = 1
  value  = FF
:
```

おお! qmicliが生成したメッセージと比べて、TLV1個分のパラメーターが追加になっているのね。みたいなことがわかる。

# 次回はいよいよ
L-03DでATコマンドを使わずにネットワークにAttach!