(Tech corner, Tutorials) 3G in Afrika

April 16, 2012

Introductie

Als vrijwilliger voor de stichting Viafrica heb ik de mogelijkheid bestudeerd om met een 3G (mobiel breedband) usb-modem en een Ubuntu server gemakkelijk een verbinding te maken met het Internet. Vooral in Afrika is het gebruik van 3G Internet populair vanwege het ontbreken van vaste lijnen (die periode heeft men in Afrika “overgeslagen”).

Viafrica

Viafrica heeft als missie om ICT in te zetten ten bate van duurzame ontwikkeling in Afrika. Als onderdeel hiervan is het programma CLASSworks ontwikkeld. Dit programma voorziet in de begeleiding van middelbare scholen in Sub Sahara Afrika bij alle essentiële onderdelen die samenhangen met het beheer en gebruik van een computerlokaal. CLASSworks begint met de voorbereidingen van een geschikt computerlokaal tot het opleiden van de docenten en het beheer van de hard- en software.

Belangrijk hierbij is dat de vraag vanuit de school zelf komt en dat men ook gewoon moet betalen voor de diensten. Op deze manier is een blijvende kwaliteit van de mensen en de apparatuur het best gewaarborgd.

Op dit moment heeft Viafrica kantoren in Amsterdam, Moshi (Tanzania) en in Thika (Kenia). Amsterdam draait grotendeels op vrijwilligers en in Moshi en Thika zijn op dit moment ca. 25 betaalde lokale medewerkers in dienst. Inmiddels zijn ca. 200 scholen van een computerlokaal voorzien.

Een computerlokaal wordt doorgaans voorzien van 1 server verbonden in een LAN met ongeveer 20 a 30 clients. De server runt Ubuntu en dient o.a. als file- en printserver (met samba) en webserver voor offline content (geen enkele school heeft op dit moment Internet). De webserver heeft dezelfde content als de online versie (http://www.classworksacademy.net). Deze website bevat naast een “file library” met allerhande educatieve content ook een aantal gemirrorde sites waardoor deze ook offline te zien zijn. De clients kunnen zowel Windows als Edubuntu zijn.

Internet

Indien de server op een school met een 3G usb-modem is uitgerust kan deze server fungeren als gateway naar het Internet voor het computerlokaal. Hoewel de server zelf dus al wel content off-line beschikbaar heeft is het hebben van Internet uiteraard iets extra’s.

Het modem en OS

Het modem wat ik heb gebruikt is een Huawei E173 van T-Mobile
Het OS: ubuntu 10.04.4 LTS server editie
Met een ubuntu desktop omgeving heb je standaard de network-manager (met de bijbehorende applet) die het meeste (zo niet alle) werk op zich neemt. Deze grafische network-manager ontbreekt in de server editie. Hier moeten we dus op een andere manier de connectie tot stand brengen. Maar voordat ik uitleg hoe e.e.a. te configureren eerst wat uitleg over usb modi.

usb modi

Een usb modem kan in verschillende modi opereren: als usb storage of als serieel modem. Dit laatste willen we om in te kunnen bellen en zo een Internet connectie op te zetten. Udev speelt een grote rol bij het automatisch herkennen van dynamische randapparaten, waaronder ook usb-modems. Hiertoe gebruikt udev rules (standaard onder /lib/udev/rules.d) welke een type modem kunnen identificeren. Indien een rule matcht kan een actie worden uitgevoerd. Voor een usb-modem betekent dit veelal het aanroepen van usb_modeswitch om de mode van storage naar serieel modem te wijzigen zodat het modem klaar is om in te gaan bellen.

In dit artikel zal ik eerst wat info over het modem achterhalen. Vervolgens maken we zelf het juiste config file voor het commando usb_modeswitch om de modes handmatig van storage naar serieel modem om te zetten en daarna kunnen we gaan inbellen.
Belangrijk, vooral vanuit onderhouds oogpunt, is dat leraren (en studenten) niet kunnen inloggen op de server. Aan het eind van dit artikel zal ik laten zien hoe je met een udev-rule en een eenvoudig script de modeswitch en het inbellen kan automatiseren zodat een connectie wordt opgezet als het modem in de usb poort geprikt wordt. Voor bovenstaand modem en OS bleek er geen udev rule te bestaan, die moeten we dus zelf maken.

Het modem als modem herkennen

Belangrijk om te achterhalen zijn het vendor-id en product-id van het modem.
Als je het modem in de usb-poort steekt kun je deze met het commando lsusb zien:

  # lsusb
  ...
  Bus 001 Device 002: ID 12d1:1c0b Huawei Technologies Co., Ltd.
  ...

De hexadecimale codes 12d1:1c0b staan respectievelijk voor het vendor-id (12d1) en het product-id (1c0b).
Meer info zie je met het commando usb-devices:

  # usb-devices
  ...
  S:  Manufacturer=HUAWEI
  S:  Product=HUAWEI Mobile
  C:  #Ifs= 5 Cfg#= 1 Atr=80 MxPwr=500mA
  I:  If#= 3 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
  I:  If#= 4 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage

We zien dat in dit geval het modem als opslag word gezien: de driver “usb_storage” is geladen. Kennelijk is usb_modeswitch niet geinstalleerd en/of wordt ons modem niet door udev herkend, anders zouden we wel zien dat een seriële driver was geladen.

Indien het package usb-modeswitch nog niet is geinstalleerd doen we dit eerst: apt-get install usb-modeswitch.
De configfiles voor diverse modems zijn te vinden in de de directory /etc/usb_modeswitch.d. Vanaf versie 1.1.7 van usb_modeswitch zijn deze configfiles gecomprimeerd te vinden in /usr/share/usb_modeswitch/configPack.tar.gz (maar als een configfile bestaat in /etc/usb_modeswitch.d gaat deze voor).
Voor ons modem bestaat op ubuntu 10.04 geen configfile en deze moest ik dus zelf maken. Ik heb even afgekeken op een ubuntu 11.10 desktop systeem wat wel de juiste configfile voor dit modem bevat:
ubuntu-11.10~# tar zxvf /usr/share/usb_modeswitch/configPack.tar.gz 12d1:1c0b.

Deze “12d1:1c0b” kun je plaatsen in /etc/usb_modeswitch.d (of hernoemen naar bv. /etc/usb_modeswitch.conf en dan met de optie -c meegeven aan het commando usb_modeswitch).
De inhoud:

  DefaultVendor=12d1
  DefaultProduct=1c0b
  TargetVendor=12d1
  TargetProduct=1c05
  MessageContent="55534243123456780000000000000011060000000000000000000000000000"
  CheckSuccess=20

Dit behoeft wat uitleg:
DefaultVendor en DefaultProduct zijn de id’s wanneer het modem nog gezien wordt als storage. Dit klopt ook met de eerder geveven output van lsusb. Na usb-modeswitch gelden TargetVendor en TargetProduct (waarbij alleen het product-id gewijzigd is, in 1c05).

De MessageContent is een hex-string om de modeswitch te initiëren. Deze verzin je ook niet zelf maar komt ook van ons Ubuntu 11.10 voorbeeld. Verder is er op Internet ook een lijst te vinden met MessageContents voor de meeste modems: www.draisberghof.de/usb_modeswitch/device_reference.txt

Tenslotte CheckSucces: wacht maximaal n seconden voor de switch om te lukken.

We zijn nu klaar om de mode te switchen: usb_modeswitch -c /etc/usb_modeswitch.conf

Wanneer we daarna het commando lsusb geven zien we dat het product-id veranderd is:

  # lsusb
  ...
  Bus 001 Device 002: ID 12d1:1c05 Huawei Technologies Co., Ltd.
  ...

Om een connectie te maken gebruik je het usb-modem dus als een serieel analoog modem. Hiervoor is tevens de kernel-module usbserial nodig. Bij het laden van deze module geef je het vendor-id en het (nieuwe!) product-id mee als parameters: modprobe usbserial vendor=0x12d1 product=0x1c05
Met het laden van usbserial worden ook de usb seriële device_nodes /dev/tyyUSB* gemaakt.

Nu laat het commando usb-devices zien dat het product-id gewijzigd is en ook dat de driver “usbserial_generic” geladen is in de HUAWEI sectie:

# usb-devices
  T:  Bus=01 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 29 Spd=480 MxCh= 0
  D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
  P:  Vendor=12d1 ProdID=1c05 Rev=01.02
  S:  Manufacturer=HUAWEI
  S:  Product=HUAWEI Mobile
  C:  #Ifs= 5 Cfg#= 1 Atr=80 MxPwr=500mA
  I:  If#= 0 Alt= 0 #EPs= 3 Cls=02(commc) Sub=02 Prot=ff Driver=usbserial_generic
  I:  If#= 1 Alt= 0 #EPs= 2 Cls=02(commc) Sub=02 Prot=ff Driver=usbserial_generic
  I:  If#= 2 Alt= 0 #EPs= 2 Cls=02(commc) Sub=02 Prot=ff Driver=usbserial_generic
  I:  If#= 3 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
  I:  If#= 4 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage

We zijn klaar om te gaan inbellen!

Inbellen

Eerst moeten we onze dial programma’s installeren: apt-get install wvdial comgt
Met wvdial kun je inbellen en met comgt kun je een pin-code opgeven mits dat voor je simkaart nodig is.

Nu kun je met de utility wvdialconf proberen of je modem herkend wordt. Dat zou nu moeten lukken aangezien we het modem in de juiste modes hebben en de module usbserial hebben geladen waarmee we tevens beschikken over de nodes /dev/tyyUSB*. Zo ja, dan wordt dan wordt een config weggeschreven in /etc/wvdial.conf:

  # wvdialconf
  ...
  ...
  Found a modem on /dev/ttyUSB0.
  Modem configuration written to /etc/wvdial.conf.
  ttyUSB0: Speed 9600; init "ATQ0 V1 E1 S0=0 &C1 &D2"

Hieruit maken we op dat het modem zit op /dev/ttyUSB0.
Nu nog de config (in /etc/wvdial.conf) aanpassen voor onze situatie (uitleg volgt):

listing 1: /etc/wvdial.conf
[Dialer tmobile]
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2
Init3 = AT+CGDCONT=1,”IP”,”internet”
Modem Type = Analog Modem
ISDN = 0
Phone = *99#
Modem = /dev/ttyUSB0
Username = none
Password = none
Dial Attempts = 10
Stupid Mode = on
Baud = 1000000
Ask Password = off

Ik heb een sectie met de naam “tmobile” gemaakt. Deze naam dient als argument voor het commando wvdial.
Voor er gebeld gaat worden kun je maximaal 9 init strings gebruik om je modem te initialiseren. Deze strings worden in (numerieke) volgorde gestuurd (dus eerst Init1 etc..). Deze strings beginnen altijd met “AT”: ATtention!
De default voor Init1 is “ATZ” (“reset”).
Init2 bevat ook allemaal defaults. “Q0”: zorgt er bv. voor dat het modem met een computer kan praten. Dit is nodig zodat we met ppp (Point-to-Point Protocol) een IP-adres kunnen krijgen.
Met AT +CGDCONT definieer je je “PDP” (Packet Data Protocol, bv. IP, X.25 of FrameRelay) context. We kiezen natuurlijk voor “IP”. Verder heb je een APN (Access Point Name) nodig. Veelal is dit “internet”. Bij twijfel vraag/zoek dit na/op voor jouw modem en provider.

Met Phone geef je het nummer aan dat je wilt draaien, voor de meeste providers is dit *99#.
Username en password zijn waarschijnlijk niet nodig, dit zou op de website van je provider moeten staan. Echter weglaten kan niet.. Het volstaat wel om een dummy naam als “none” in te vullen.

Sommige ISP’s komen met een login-prompt als je een ppp-sessie wilt opzetten, Stupid mode = 1 (of on) negeert dit.

Baud = 1000000 zet de snelheid op 1Mbits per seconde. Dit is de snelheid tussen wvdial en het modem, niet de snelheid van je 3G verbinding! Een hogere waarde dan je maximale 3G verbindingssnelheid maakt je verbinding niet sneller, een te lage waarde kan je verbinding wel langzamer maken. Kies dus een waarde die hoog genoeg is. Om een idee te krijgen waartoe jouw 3G verbinding in staat is, is iperf1 een handige en goede tool.

Om een pin-code in te voeren kun je een aparte sectie maken in /etc/wvdial.conf:
[Dialer pin]
Modem = /dev/ttyUSB0
Baud = 1000000
Init1 = AT+CPIN=1234

En dan het commando wvdial pin om zo de pincode te geven.
Dit kun je ook doen met het commando comgt:

  # apt-get install comgt
  # comgt -d /dev/ttyUSB0
  Enter PIN number: 1234 (geef hier je eigen pincode)
  Waiting for Registration..(120 sec max)...
  Registered on Home network: "T-Mobile  NL",2
  Signal Quality: 20,99

Deze methode gebruik ik in het script wat verderop beschreven wordt. Overigens kun je ook de simkaart in je mobiele telefoon doen en via het telefoonmenu (meestal ergens onder “beveiliging”) de pincode verwijderen.

Is je pincode eenmaal ingevoerd (met wvdial pin of comgt -d /dev/ttyUSB0) of je hebt helemaal geen pincode nodig dan is het tijd om online te komen:

listing 2: inbellen
# wvdial tmobile
–> WvDial: Internet dialer version 1.60
–> Cannot get information for serial port.
–> Initializing modem.
–> Sending: ATZ
ATZ
OK
–> Sending: ATQ0 V1 E1 S0=0 &C1 &D2
ATQ0 V1 E1 S0=0 &C1 &D2
OK
–> Sending: AT+CGDCONT=1,”IP”,”internet”
AT+CGDCONT=1,”IP”,”internet”
OK
–> Modem initialized.
–> Sending: ATDT*99#
–> Waiting for carrier.
ATDT*99#
CONNECT 7200000
–> Carrier detected. Starting PPP immediately.
–> Starting pppd at Wed Aug 18 18:57:26 2010
–> Pid of pppd: 3430
–> Using interface ppp0
–> pppd: p�v ��v ءv
–> pppd: p�v ��v ءv
–> pppd: p�v ��v ءv
–> pppd: p�v ��v ءv
–> local IP address 188.89.154.248
–> pppd: p�v ��v ءv
–> remote IP address 10.64.64.64
–> pppd: p�v ��v ءv
–> primary DNS address 84.241.226.9
–> pppd: p�v ��v ءv
–> secondary DNS address 84.241.226.140

Dat ziet er goed uit!
Tijd om bovenstaande handelingen te automatiseren zodat we alleen maar het modem hoeven in te prikken om een verbinding te maken. De leraren op de scholen zijn tenslotte niet in staat in te loggen en kunnen dus ook geen commando’s geven.
Udev is hierbij onze vriend!

Automatiseer met gebruik van udev

Eerst maken we een eenvoudig script: /usr/local/bin/dial:

listing 3: script
#!/bin/bash
# script voor connectie met HUAWEI E173 modem
PATH=/sbin:/usr/sbin:/usr/bin:/bin
export PATH
# jouw pincode
COMGTPIN=1234
export COMGTPIN
# switch de mode van het modem naar serieel
usb_modeswitch -c /etc/usb_modeswitch.conf &
echo “wacht op mode_switch”
wait $!
echo “modeswitch klaar”
# laad de kernel-module usbserial
modprobe usbserial vendor=0x12d1 product=0x1c05
# geef de pincode
comgt PIN -d /dev/ttyUSB0
# start inbellen
wvdial tmobile &
while ! ifconfig | grep ppp0 >/dev/null 2>&1
do
  sleep 3
done
shorewall restart
# klaar

Merk op dat wvdial in de achtergrond wordt gestart om deze zo “los te koppelen” van het script. Dit script, zoals we zo zullen zien, wordt aangeroepen door udev en terwijl dit script runt kan udev niks doen. Door wvdial in de achtergrond te starten kan het script gewoon eindigen en is udev weer actief.
Merk verder op dat we na het inbellen natuurlijk vrij zijn om nog meer te doen, zoals bv. het starten van een packetfilter (in dit geval shorewall).

Nu willen we dit script aanroepen telkens als het modem ingeprikt wordt. Hiertoe maken we een udev rule voor ons modem. De standaard udev-rules staan in /lib/udev/rules.d/. Door een rule-file te maken in /etc/udev/rules.d kunnen we deze overrulen. De inhoud van ons rule-file (/etc/udev/rules.d/E173modem.rules):

  ACTION=="add", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="1c0b", RUN+="/usr/local/bin/dial"

Merk op: ons rule-file heeft geen nummer waardoor deze wordt uitgevoerd na andere eventuele matching rule files. Dus ook al zou het modem standaard herkend dan zal ons eigen rule-file als laatste worden uitgevoerd. De naam van het rule-file moet eindigen op .rules anders pikt udev het niet op.

Met de variable ACTION kun je kijken of een device geconnect of ge-disconnect wordt. We kijken in dit geval of de ACTION gelijk is aan “add” (“connect”). Merk op dat ATTRS{idProduct} het “storage” product-id (1c0b, niet 1c05) moet matchen! De modeswitch heeft tenslotte nog niet plaatsgevonden (dit gebeurd namelijk met ons script :)). Merk hierbij tevens op dat ook al wordt de modeswitch gedaan door een eerdere matching rule (en het product-id op “1c05” zal zetten) dan nog zal onze rule matchen op ATTRS{idProduct}=="1c0b" omdat eerst alle RUN-acties voor alle rules verzameld worden door udev en dan pas worden uitgevoerd. De modeswitch in ons script zal dan wel falen (die is immers reeds gebeurd) en het is dan netter om de eerdere matching rule te deleten of wel/geen modeswitch af te vangen in het script. Overigens is er in ons geval geen eerdere matching rule.

Indien nu een usb-device geconnect wordt en matcht met de ATTR-values dan wordt het script /usr/local/bin/dial toegevoegd (met key-value pair: RUN+=/usr/local/bin/dial) aan de uit te voeren acties. Dit is wat we willen!

Nu nog het script executable maken: chmod 700 /usr/local/bin/dial en klaar zijn we!
Een reload van udev (met service udev reload) is niet nodig (maar mag gerust) omdat de udev daemon wijzigingen in /etc/udev/rules.d (en ook onder /lib/udev/rules.d) automatisch oppakt.

Nu testen door alleen ons modem aan te prikken en wachten tot het lampje groen (om een GPRS (2G) verbinding aan te geven) of blauw (om een UMTS/HDSPA (3G/3G+) verbinding aan te geven) wordt 🙂

Conclusie

Met een goedkoop 3G-modem is een server op deze manier eenvoudig van een 3G Internet verbinding te voorzien. Op dit moment is Viafrica hard bezig met fondsenwerving voor dit project en het is de bedoeling dat nog dit jaar de eerste scholen ontsloten kunnen worden.

De volgende keer zal ik uitleggen hoe we, gebruik makend van Internet, met technieken als “dynamic DNS” en openVPN de servers remote kunnen monitoren en ook remote kunnen inloggen om (proactief) onderhoud te kunnen doen (mits de server online is natuurlijk). Gezien de condities van de weg en de afstanden in bv. Tanzania kan hierdoor flink bespaard worden op tijd en geld.

Succes met 3G!

Appendix: referenties

tags:

 
"24 hours in a day. 24 beers in a case ... coincidence?"

Powered by Wordpress. Theme by Shlomi Noach, openark.org
© 2017 KwaLinux Trainingen | Algemene voorwaarden | KvK: 10147727 | Disclaimer