組み込みLinuxシステムにおけるGSM/3G/4Gの使い方

2016年5月18日水曜日

Linux

はじめに

インターネットに接続された組み込みデバイスは、日々成長しています。こうしたデバイスが、有線または無線ネットワーク接続の存在しない場所へ導入されることも多々あります。そのような状況でデバイスをインターネットに接続するには、モバイルネットワークの利用をするのが良い方法です。このため、今回のブログ投稿では、Linuxを実行しているデバイスを、PPP(Point-to-Point Protocol)リンクを介してインターネットに接続するために必要な設定についてお話します。

GSM/3G/4G in Embedded Linux Systems
使用するハードウェア

本記事では、Colibri iMX6Sおよび「Colibri Evaluation Board」と呼ばれるベースボードを使います。双方ともToradexの製品です。Colibri Evaluation Board(Colibri 評価ボード)は、特にプロジェクト評価および開発用に推奨されています。この製品には、USB、Ethernet、I2C、PSI、RS242、RS485、CAN他、多数のインターフェイスがあります。また、この評価ボードには、HDML、LVDS、VGA、LCDなどいくつかのマルチメディアインターフェイスのサポートも最初から含まれています。

このチュートリアルの手順を追うにあたり、どのようなUSBまたはシリアルモデムでもインターネット接続に利用することができます。必要なのは、「/dev/」で作成されるインターフェイスを順応させることです。また、各モデムには特定の「AT」コマンドがあるため、自分のモデムがサポートし実装している「AT」コマンドを確認する必要があります。本チュートリアルでは、Huawei E173s 3Gモデムおよびデータプランを有効にした互換SIMカードを使用しました。

カーネルの準備

PPPプロトコルを介して3G USBモデムを利用するには、カーネル設定で機能をいくつか選択し、カーネルをコンパイルする必要があります。カーネルのコンパイル方法について理解するには、下のリンクをご覧になることをお勧めします。
http://developer.toradex.com/software-resources/arm-family/linux/board-support-package/build-u-boot-and-linux-kernel-from-source-code

カーネルをコンパイルする処理の基本は、おおまかに言うと次のようになります。

カーネル機能を設定する際、menuconfigへ行き、次のオプションを有効にします。

CONFIG_PPP:
PPP (Point to Point Protocol) is a newer and better SLIP.  It serves the same purpose: sending Internet traffic over telephone (and other serial) lines.  Ask your access provider if they support it, because otherwise you can't use it; most Internet access providers these days support PPP rather than SLIP. 
Device Drivers  ---> 
   [*] Network device support  --->
          PPP (point-to-point protocol) support
            PPP BSD-Compress compression
             PPP Deflate compression 
       [*]     PPP filtering
            PPP MPPE compression (encryption)
       [*]     PPP multilink support 
            PPP over Ethernet  
            PPP support for async serial ports
            PPP support for sync tty ports

CONFIG_USB_ACM:
This driver supports USB modems and ISDN adapters which support the
Communication Device Class Abstract Control Model interface.
Please read <file:Documentation/usb/acm.txt> for details.      
Device Drivers  --->
    [*] USB support  --->
            USB Modem (CDC ACM) support 

必要なソフトウェアパッケージ

3Gモデムを設定しインターネットへ接続するには、Linuxは、カーネルドライバの他、接続を管理するソフトウェアを使用します。このソフトウェアがPPPです。Toradexのイメージには、通常、デフォルトでPPPソフトウェアがインストールされています。

PPPがインストールされていない場合は、Yocto/OpenEmbeddedベースのビルド環境のlocal.confファイルに下記を追加します。

IMAGE_INSTALL_append = " ppp"

Modemとの通信の検証

必要なドライバおよびソフトウェアを全てインストールすると、モジュールが3Gモデムを認識するかどうかを確認することができます。モデムインターフェイスは、/devに表示されるはずです。要するに、ドライバが、USB接続を多くのシリアル接続としてシミュレーションするのです。

次のコマンドを実行して、/dev/ttyUSBのインターフェイスを検索します。

$ ls -l /dev/ttyUSB*

ttyUSB0、ttyUSB1、・・・e ttyUSB2 というファイルが見つかれば、システムがモデムを認識したということになります。

より詳しい検証を行いたい場合は、「minicom」といったシリアルターミナルを使い、モデムとの通信を開始して正常に動作しているかの確認をすることも可能です。今回、モデムのボーレートは115200でした。

$ minicom -D /dev/ttyACM0
___________________________
AT
OK

PPPファイルの設定

モデムとの通信を確認したら、インターネットへ接続するための設定ファイルを作成します。

/etc/ の下にpppというフォルダがあるはずです。 このフォルダ内にファイルをいくつか作成する必要があります。

まず、PPP optionsファイルを作成します。

$ vi /etc/ppp/options
_____________________________________
auth
crtscts
lock
hide-password
modem
mru 296
mtu 296
lcp-echo-interval 30
lcp-echo-failure 4
noipx
persist
asyncmap 0xa0000
mru 1500
refuse-chap
ipcp-max-failure 30
logfile /home/root/ppp

ここでは、PAP認証ファイルを使います。(これはネットワークプロバイダによって異なる可能性があります。)

$ vi /etc/ppp/pap-secrets
_____________________________________
#    *      password
vivo vivo vivo

次に、/etc/ppp/peer内にファイルをもう1つ作成します。このファイルには、ネットワークプロバイダの設定およびchatファイルへのパスを記します。

$ vi /etc/ppp/peers/vivo-3g.provider
_____________________________________
hide-password
noauth
debug
defaultroute
noipdefault
user vivo
remotename vivo
ipparam vivo
persist
usepeerdns
/dev/ttyUSB0 115200 crtscts
replacedefaultroute
connect 'chat -v -f /etc/ppp/chat/vivo-3g.chat'

ここで、モデムがインターネットに接続できるよう、モデムにATコマンドを送信するためのファイルを作成します。このファイルは、モデムのモデルやブランドにより異なります。

$ vi /etc/ppp/chat/vivo-3g.chat
_____________________________________
ECHO
ON
ABORT
'BUSY'
ABORT
'NO CARRIER'
ABORT
'ERROR'
""
ATZ OK
\d\dAT+CGDCONT=1,"IP","zap.vivo.com.br" OK
\d\d\dATDT*99# CONNECT

インターネットへの接続

次にpppを実行し、ログファイルを分析します。ログファイルでは、それぞれのATコマンドがいつ実行されたのかを見ることができます。

$ pon vivo-3g.provider

pppを実行した後、ログファイルを開きます。

$ tail -f "/home/root/ppp"

今回は、次のような出力となりました。

tail -f ppp.log 
Sent 3940 bytes, received 2843 bytes.
restoring old default route to eth0 [192.168.10.1]
restore default route ioctl(SIOCADDRT): Network is unreachable(101)
Script /etc/ppp/ip-down started (pid 778)
sent [LCP TermReq id=0x2 "User request"]
rcvd [LCP TermAck id=0x2]
Connection terminated.
Script /etc/ppp/ip-down finished (pid 778), status = 0x0
ATZ
OK
AT+CGDCONT=1,"IP","zap.vivo.com.br"
OK
ATDT*99#
CONNECT
Script chat -v -f /etc/ppp/chat/vivo-3g.chat finished (pid 795), status = 0x0
Serial connection established.
using channel 2
Using interface ppp0
Connect: ppp0  /dev/ttyACM0
rcvd [LCP ConfReq id=0x1     ]
sent [LCP ConfReq id=0x1    ]
sent [LCP ConfAck id=0x1     ]
rcvd [LCP ConfAck id=0x1    ]
sent [LCP EchoReq id=0x0 magic=0xa068db01]
sent [PAP AuthReq id=0x1 user="vivo" password=]
rcvd [LCP EchoRep id=0x0 magic=0x96baf40f]
rcvd [PAP AuthAck id=0x1 ""]
PAP authentication succeeded
sent [CCP ConfReq id=0x1   ]
sent [IPCP ConfReq id=0x1    ]
rcvd [LCP ProtRej id=0x2 80 fd 01 01 00 0f 1a 04 78 00 18 04 78 00 15]
Protocol-Reject for 'Compression Control Protocol' (0x80fd) received
rcvd [IPCP ConfNak id=0x1  ]
sent [IPCP ConfReq id=0x2    ]
rcvd [IPCP ConfNak id=0x2  ]
sent [IPCP ConfReq id=0x3    ]
rcvd [IPCP ConfNak id=0x3  ]
sent [IPCP ConfReq id=0x4    ]
rcvd [IPCP ConfNak id=0x4  ]
sent [IPCP ConfReq id=0x5    ]
rcvd [IPCP ConfNak id=0x5  ]
sent [IPCP ConfReq id=0x6    ]
rcvd [IPCP ConfReq id=0x1]
sent [IPCP ConfNak id=0x1 ]
rcvd [IPCP ConfRej id=0x6 ]
sent [IPCP ConfReq id=0x7   ]
rcvd [IPCP ConfReq id=0x2 ]
sent [IPCP ConfAck id=0x2 ]
rcvd [IPCP ConfNak id=0x7   ]
sent [IPCP ConfReq id=0x8   ]
rcvd [IPCP ConfAck id=0x8   ]
local  IP address 179.133.47.109
remote IP address 179.133.47.109
primary   DNS address 187.100.246.254
secondary DNS address 187.100.246.251
Script /etc/ppp/ip-up started (pid 805)
Script /etc/ppp/ip-up finished (pid 805), status = 0x0

ログファイルからわかるように、下記の部分に到達するまで、chatスクリプトが段階的に実行されます。

ATDT*99#
CONNECT

これでシリアルターミナルを利用して接続するために必要な一連のコマンドを確認することができます。この確認ができれば自分だけのchatスクリプトを作成できます。

ネットワークプロバイダからのIPアドレスを確かめた後、ppp0ネットワークインターフェイスが有効になっているかどうかを確かめます。

root@apalis-imx6:/etc/ppp# ifconfig 
eth0      Link encap:Ethernet  HWaddr 00:14:2D:C0:00:4C  
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:1181 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1223 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
         RX bytes:107025 (104.5 KiB)  TX bytes:149841 (146.3 KiB)
 
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:22 errors:0 dropped:0 overruns:0 frame:0
          TX packets:22 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
         RX bytes:1536 (1.5 KiB)  TX bytes:1536 (1.5 KiB)
 
ppp0      Link encap:Point-to-Point Protocol  
          inet addr:179.133.47.109  P-t-P:179.133.47.109  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:296  Metric:1
          RX packets:13 errors:0 dropped:0 overruns:0 frame:0
          TX packets:35 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3 
         RX bytes:1330 (1.2 KiB)  TX bytes:2131 (2.0 KiB)

接続の検証

接続の確立に成功したかどうかを検証するには、外部のIPアドレスをpingしてください。

root@apalis-imx6:/etc/ppp# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=45 time=182.304 ms
64 bytes from 8.8.8.8: seq=1 ttl=45 time=34164.126 ms
64 bytes from 8.8.8.8: seq=2 ttl=45 time=33164.085 ms

DNSを設定するには、次のコマンドを使用してからURLをpingします。例えば次のようになります。

$ echo nameserver 8.8.8.8 > /etc/resolv.conf
$ ping google.com
A running web browser using 3G connection
画像1:3G接続を使いウェブブラウザを実行

システムの再起動時にファイルが書き換えられないようにするには、次のコマンドが使えます。

$ chattr +i /etc/resolv.conf

これで、SSHを使って外部コンピュータから接続できるようになりました。

$ ssh root@179.133.47.109

IPアドレス用のホスト名の設定

もう1つ実行可能なことに、IPアドレスをホスト名と関連付けることがあります。この目的を達成するためには、NoIPサービス(www.noip.com)を利用しました。無料アカウントを作成し、ホストを追加します。今回は、toradex.noip.meを選択しました。

NoIP Add Host page
画像2:NoIPのホスト追加ページ

ホスト名を作成したら、SSHを使ってモジュールへ再度接続できます。

$ ssh root@toradex.noip.me

この検証では、3Gモデムの接続が再起動されるたびに、いつも新しいたなIPアドレスを受け取っていました。このためモジュールに再接続しようしても、アクセスできませんでした。これを回避する方法は、Dynamic DNS(Dynamic Domain Name System)という手段を使うことです。NoIPは、Dynamic DNSサービスも提供しています。この方法を使うための詳細は、ここでご確認ください。要するに、IP、ホスト名、ユーザ名、パスワードといった情報と共にhttp要求をNoIPへ送信することになります。

この要求を実行するため、小さなPythonプログラムを作成しました。プログラムは3Gモデム接続を開始すると実行され、次に示す流れに従います。

Python Application Fluxogram


画像3:Pythonアプリケーションのフローチャート
#!/usr/bin/python
 
import sys
import requests
import netifaces as ni
 
user = 'xxxxxxx'
pswd = 'xxxxxxx'
 
ni.ifaddresses('ppp0')
ip = ni.ifaddresses('ppp0')[2][0]['addr']
myhostname = 'toradex.noip.me'
 
payload = {'hostname' : myhostname , 'myip' : ip}
r = requests.get("http://dynupdate.no-ip.com/nic/update", params=payload, auth=(user,pswd))
 
print " " 
if "good" in r.text:
print "Hello", user, "!"
print "Your IP was successfully updated to:", ip
print myhostname, "is up and running!"
if "nochg" in r.text:
print "Hello", user, "!"
print "Your IP", ip, "is still active, no change needed"
if "nohost" in r.text:
print "The given Host name", myhostname, "does not exist under specified account"
print "Please review your Host name and try again"
if "badauth" in r.text:
print "Login and/or Username incorrect"
print "Please correct your credentials and try again"
if "911" in r.text:
print "Sorry for the incovenience but we are experiencing some problems right now"
print "Please try again later"
print "noip.com says:", r.text
print " "

Phythonプログラムを作成し、chmod +xで実行できるようにしたら、ppp接続後にスクリプトが実行されるフォルダ、/etc/ppp/ip-up.d/へ移動させるか、または、Pythonプログラムを呼び出す小さなスクリプトを作成します。

/etc/ppp/内には、本記事の最初に作成したファイル並びにip-down、ip-up、ppp_on_bootなど他のファイルもあります。こうした各ファイルの内容も確認してみてください。

ip-upが、ip-up.dフォルダ内にあるスクリプトやプログラムを呼び出すスクリプトです。

今回は、ip-up.d内に小さなスクリプトを作成しました。

#!/bin/bash
python /home/root/noipReq.py > /home/root/noipLog.log

注意:このスクリプトは.shで終了されていません


Phythonプログラム内のprintコマンドの全てがログファイルで見られることに留意してください。

root@colibri-imx6:~# cat noipLog.log 
Hello giovannibauer !
Your IP was successfully updated to: 179.92.172.193
toradex.noip.me is up and running!
noip.com says: good 179.92.172.193

全てが適切に設定されていれば、ネットワークプロバイダから新しいIPを受け取った際に、システムがNoIPで作成されたホストを自動的に更新するため、IPアドレスが変更されてもモジュールへ接続することができます。

本記事で提供した情報を参考にすれば、他にも多数のネットワーク動作を実現できます。例えば、3Gモデムのネットワークを、イーサネットを介して他のコンピュータと共有することもできます。これには、2台のマシン間で基本的なLANネットワークを設定し、次のコマンドを実行しました。

iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

インターネット共有の他、ポートフォワーディングなど、その他多数のネットワーク機能を実装できます。


最後に

本記事でご紹介したように、Linuxシステムには多数のネットワーク機能が備わっています。必要なのは正しい設定を行い、ppp0ネットワークへのアクセスを持つことです。もう1つの重要なポイントは、どのインターフェイスを利用するにしてもプログラミングの手段は同じだ、ということです。利用するインターフェイスを選択する作業は、ルートによりLinuxが自動的に行います。ネットワーク接続が必須であり、システムの柔軟性も必要なプロジェクトにおいては、組み込みシステムでのLinuxの利用が最適な方法です。

リファレンス:

当ブログ投稿は、当初ポルトガル語でEmbarcados.comに掲載されました。こちらからご覧ください。

#Embedded Linux #GSM #Yocto
Author Raul Rosetto Muñoz, Application Engineer, Toradex Brasil

3 comments

Justin Tom - 3 years | Reply

I like this article alot as it provided the essential points in setting up a 3g/4g modem beacuse generally people will mess it up or look for a tutorial up on youtube never to give a thought what they were doing wrong.

Justin Tom - 3 years 1 month | Reply

its a very helpful article, thanks for sharing it.
Regards:
Justin Tom
3G Serial Modems
http://www.intercel.com.au/

Thin - 2 years 6 months | Reply

Thanks for sharing it.I used SIM800. My module ran.
I have a question: how do i make a call or sms?
I want to use internet and call together.
Thanks

Toradex - 2 years 5 months | Reply

Hello Thin,

Each module has its own configuration. As far as I remember from the modules I worked on in the past, if you use UART modules, you can just use internet or call/sms.

For the USB modules, I remember it emulates more than one UART channel (ttyACM0,1,2...). In that case, it was possible to use one UART to the ppp and the other to send some AT commands. Using the correct AT Commands you can accept calls, receive, and send SMS.

Again, it really depends more on what GSM module you are using.
If you need more help, please feel free to contact us: support.arm@toradex.com

Thank you,
Raul

Lakshmi Naidu - 2 years 5 months | Reply

Hello Thin,

Each module has its own configuration. As far as I remember from the modules I worked on in the past, if you use UART modules, you can just use internet or call/sms.

For the USB modules, I remember it emulates more than one UART channel (ttyACM0,1,2...). In that case, it was possible to use one UART to the ppp and the other to send some AT commands. Using the correct AT Commands you can accept calls, receive, and send SMS.

Again, it really depends more on what GSM module you are using.
If you need more help, please feel free to contact us: support.arm@toradex.com

Thank you,
Raul

Leave a comment

Your email ID will be kept confidential. Required fields are marked *



* Your comment will be reviewed and then added. Thank you.