16
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Raspberry Piで、L-03DをEthernetとして認識する

Posted at

やっぱり

前回USBモデムL-03Dの認識ができたが、ttyとして認識し、PPPを使う。世は既にPDPtype=IPで、本来PPPは不要。さらに、L-03Dの取説によると、

L-03D Connection Manager でのパケット通信は、より高速な NDIS 方式(無線LANのような方式)となっております。従来のダイヤルアップでの接続を行うこともできます。

とあり、NDIS方式のほうが高速そうな書きぶりだ。

QMI

Qualcomm社のモデムインターフェースはQMIで、ttyとは異なる専用インターフェース。これを扱えるオープンソースlibqmiがあると友人が教えてくれた。ありがとう & びっくり。
Raspberry Pi + UX302NCの例はこちらが答えそのもので、このエントリーも不要なくらい。これをL-03Dでやってみる。

まるっきり真似

登録するドライバーは2つ。

  1. qmi_wwan: 取説で言うNDIS相当のドライバーで、制御用の/dev/cdc-wdm0とNICのwwan0ができる
  2. qcserial: ATコマンド等が使える従来のttyUSB*ができる
/etc/udev/rules.d/99-l03d.rules
ATTRS{idVendor}=="1004", ATTRS{idProduct}=="6327", RUN+="/usr/bin/eject /dev/sr0"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1004", ATTRS{idProduct}=="6326", RUN+="/sbin/modprobe -b qmi_wwan"
SUBSYSTEM=="drivers", ENV{DEVPATH}=="/bus/usb/drivers/qmi_wwan", ATTR{new_id}="1004 6326"
ATTRS{idVendor}=="1004", ATTRS{idProduct}=="6326", RUN+="/sbin/modprobe -b qcserial"
SUBSYSTEM=="drivers", ENV{DEVPATH}=="/bus/usb-serial/drivers/qcserial", ATTR{new_id}="1004 6326"

ATTR{new_id}は、VID/PIDをL-03Dに合わせて変更した。

動作確認

pi@raspberrypi:~ $ lsmod
Module                  Size  Used by
:
qcserial                5129  0
usb_wwan                7104  1 qcserial
usbserial              29640  2 qcserial,usb_wwan
:
qmi_wwan               11679  
cdc_wdm                10749  1 qmi_wwan
:
pi@raspberrypi:~ $ usb-devices
:
T:  Bus=01 Lev=02 Prnt=02 Port=01 Cnt=02 Dev#=  5 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=1004 ProdID=6326 Rev=00.00
S:  Manufacturer=NTT DOCOMO, INC.
S:  Product=docomo L03D
C:  #Ifs= 4 Cfg#= 1 Atr=80 MxPwr=500mA
I:  If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
I:  If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=qcserial
I:  If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
I:  If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan

うーむ、qmi_wwanが2個できるのは変。

root@raspberrypi:~# qmicli -d /dev/cdc-wdm0 --dms-get-manufactuarer
(しーん)
^Z
root@raspberrypi:~# qmicli -d /dev/cdc-wdm1 --dms-get-manufactuarer
[/dev/cdc-wdm1] Device manufacturer retrieved:
	Manufacturer: 'QUALCOMM INCORPORATED'

1つは生きているようだが、気持ち悪い。

再調査

Windowsでは

Windowsの公式ドライバではどうか。
ドライバのプロパティの詳細などを見ると…

  • USB Serial Port = MI_00 (COMポート)
  • NMEA Serial Port = MI_01 (COMポート)
  • Modem Driver = MI_02 (ATコマンドのCOMポート)
  • USB NDIS Driver = MI_03

というUSB Composite Deviceの構成。これを認識するには…。

udevのnew_id

そもそも、udevで設定しているATTR{new_id}="1004 6326"とは何なのか。
こちらにある通り、ドライバーに書かれていないVID/PIDを持ったデバイスを、特定のドライバーで登録できるようになっている。これは便利。だが、USB Composite Deviceの順番は指定できないのか。
本家によると、

idVendor idProduct bInterfaceClass RefIdVendor RefIdProduct

の並びが指定できる。今回はClassは全部0xffっぽいし、ダメか…。

ドライバーのソースを読む

linux/drivers/usb/serial/qcserial.c
        /*
         * Composite mode; don't bind to the QMI/net interface as that
         * gets handled by other drivers.
         */

        switch (id->driver_info) {
        case QCSERIAL_G1K:
                /*
                 * Gobi 1K USB layout:
                 * 0: DM/DIAG (use libqcdm from ModemManager for communication)
                 * 1: serial port (doesn't respond)
                 * 2: AT-capable modem port
                 * 3: QMI/net
                 */
                if (nintf < 3 || nintf > 4) {
                        dev_err(dev, "unknown number of interfaces: %d\n", nintf);
                        altsetting = -1;
                        goto done;
                }

                if (ifnum == 0) {
                        dev_dbg(dev, "Gobi 1K DM/DIAG interface found\n");
                        altsetting = 1;
                } else if (ifnum == 2)
                        dev_dbg(dev, "Modem port found\n");
                else
                        altsetting = -1;
                break;

nintfの0〜2がCOMポートと認識するようにすれば良さそうだが、同じ並びのものはこのソースには無さそう…。新しいdriver_infoを定義しようと思ったが、面倒になった。そこで…。

ドライバ改造(インチキ)

何故インチキかと言うと、L-03DはGOBI1Kではないが、USB Composite Deviceの構成が似ているGOBI1Kの定義をそのまま使っているから…。

qcserial

drivers/usb/serial/qcserial.c
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -74,6 +74,7 @@ static const struct usb_device_id id_table[] = {
        {DEVICE_G1K(0x05c6, 0x9231)},   /* Generic Gobi QDL device */
        {DEVICE_G1K(0x1f45, 0x0001)},   /* Unknown Gobi QDL device */
        {DEVICE_G1K(0x1bc7, 0x900e)},   /* Telit Gobi QDL device */
+       {DEVICE_G1K(0x1004, 0x6326)},   /* NTT docomo L-03D */

        /* Gobi 2000 devices */
        {USB_DEVICE(0x1410, 0xa010)},   /* Novatel Gobi 2000 QDL device */

qmi_wwan

drivers/net/usb/qmi_wwan.c
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -812,6 +812,7 @@ static const struct usb_device_id products[] = {
        {QMI_GOBI1K_DEVICE(0x05c6, 0x9203)},    /* Generic Gobi Modem device */
        {QMI_GOBI1K_DEVICE(0x05c6, 0x9222)},    /* Generic Gobi Modem device */
        {QMI_GOBI1K_DEVICE(0x05c6, 0x9009)},    /* Generic Gobi Modem device */
+       {QMI_GOBI1K_DEVICE(0x1004, 0x6326)},    /* NTT docomo L-03D */

        /* 5. Gobi 2000 and 3000 devices */
        {QMI_GOBI_DEVICE(0x413c, 0x8186)},      /* Dell Gobi 2000 Modem device (N0218, VU936) */

動作再確認

デバイス認識

pi@raspberrypi:~ $ lsmod
Module                  Size  Used by
qcserial                5225  0
usb_wwan                7104  1 qcserial
qmi_wwan               11703  0
cdc_wdm                10749  1 qmi_wwan
usbserial              29640  2 qcserial,usb_wwan
:
pi@raspberrypi:~$ usb-devices
:
T:  Bus=01 Lev=02 Prnt=02 Port=02 Cnt=02 Dev#=  5 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=1004 ProdID=6326 Rev=00.00
S:  Manufacturer=NTT DOCOMO, INC.
S:  Product=docomo L03D
C:  #Ifs= 4 Cfg#= 1 Atr=80 MxPwr=500mA
I:  If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
I:  If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
I:  If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qcserial
I:  If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan

If#=0と1が(none)になっているが、とりあえず、If#=2のATコマンドポートと、If#=3のwwanが現れた。

iijmioで接続

qmicliインストール

sudo apt-get install libqmi-utils

設定ファイル設置

/etc/qmi-network.conf
APN=iijmio.jp,CHAP,mio@iij,iij

APN接続

pi@raspberrypi:~$ sudo qmi-network /dev/cdc-wdm0 start
Loading profile...
    APN: iijmio.jp,CHAP,mio@iij,iij
Starting network with 'qmicli -d /dev/cdc-wdm0 --wds-start-network=iijmio.jp,CHAP,mio@iij,iij  --client-no-release-cid'...
error: couldn't start network: QMI protocol error (14): 'CallFailed'
call end reason (3): generic-no-service
verbose call end reason (3,2001): [cm] no-service
Saving state... (CID: 1)
error: network start failed, no packet data handle
Clearing state...

つながらん。qmicli --help-allしたコマンドを片っ端から打っても、つながらん。最新のlibqmiをビルドして使っても、つながらん。

pi@raspberrypi:~ $ sudo qmicli -d /dev/cdc-wdm0 --nas-get-system-info
[/dev/cdc-wdm0] Successfully got system info:
	GSM service:
		Status: 'none'
		True Status: 'none'
		Preferred data path: 'no'
	WCDMA service:
		Status: 'none'
		True Status: 'none'
		Preferred data path: 'no'
	LTE service:
		Status: 'limited'
		True Status: 'limited-regional'
		Preferred data path: 'no'
		Domain: 'unknown'
		Service capability: 'ps'
		Roaming status: 'off'
		Forbidden: 'no'
		Location Area Code: 'xxxxx'
		Cell ID: 'xxxxxxxx'
		MCC: '440'
		MNC: '10'
		Tracking Area Code: '0'
		Voice support: 'yes'

このlimitedが問題のようだ。

PPP接続

この状態で、PPP接続してみる。

pi@raspberrypi:~ $ sudo pon iijmio.jp
pi@raspberrypi:~ $ ifconfig ppp0
ppp0      Link encap:Point-to-Point Protocol
          inet addr:100.xx.xx.xx  P-t-P:10.64.64.64  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:17 errors:0 dropped:0 overruns:0 frame:0
          TX packets:18 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3
          RX bytes:1435 (1.4 KiB)  TX bytes:941 (941.0 B)

ちゃんとつながる。

sudo poffした後、もう一度sudo qmicli -d /dev/cdc-wdm0 --nas-get-system-infoすると、LTE serviceStatus: 'available'となる。一旦availableになると、

pi@raspberrypi:~ $ sudo qmi-network /dev/cdc-wdm0 start
Loading profile...
    APN: iijmio.jp,CHAP,mio@iij,iij
Starting network with 'qmicli -d /dev/cdc-wdm0 --wds-start-network=iijmio.jp,CHAP,mio@iij,iij  --client-no-release-cid'...
Saving state... (CID: 1)
Saving state... (PDH: 36003144)
Network started successfully

…となり、QMIでつながる。

pi@raspberrypi:~ $ ifconfig wwan0
wwan0     Link encap:Ethernet  HWaddr xx:xx:xx:xx:xx:xx
          inet addr:100.xx.xxx.xxx  Bcast:100.255.255.255  Mask:255.0.0.0
          inet6 addr: fe80::d058:5531:253a:32e3/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:34 errors:0 dropped:0 overruns:0 frame:0
          TX packets:98 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:3525 (3.4 KiB)  TX bytes:14876 (14.5 KiB)

うーむ、何をすればavailableになるのか。

USBキャプチャ

WindowsのWiresharkでは、usbpcapが使える。これと同じQMI制御を行えば、PPP接続しなくてもネットワークにつながるはず。
実際にUSBキャプチャは動作したのだが、ここまでやって、気づいてしまったのだ。

pi@raspberrypi:~ $ sudo qmicli -d /dev/cdc-wdm0 --dms-get-band-capabilities
[/dev/cdc-wdm0] Device band capabilities retrieved:
	Bands: 'gsm-dcs-1800, gsm-900-extended, gsm-900-primary, gsm-pcs-1900, wcdma-2100, wcdma-850-us, wcdma-800'
	LTE bands: '1'

Band1しか使えないのかよ! そもそも、2012年発売と、かなり古いのであった…。

オチ

面倒なので、UX302NC買います!
でも、YAMAHASEIL(L-02Cだが)も使えるので、絶対使う方法はあるはずなのだが…くやしい。

16
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?