Ho una casa in montagna…. sono in viaggio in camper… sono in affitto e non voglio stipulare un contratto ADSL… Tutti buoni motivi per utilizzare un router UMTS che incorpori la telefonia VoIP ! Con questo articolo scopriremo passo passo come poter collegare un modem usb umts al router Fritz 7170, capendo che problemi ci sono e come risolverli. Inoltre spiegheremo le righe di codice piu’ significative, vi indicheremo dove andare a “mettere le mani” e che strumenti utilizzare per indagare i problemi riscontrati. Alla fine otterrete una configurazione perfettamente funzionante.
Da oggi questo è realtà !!
Cominciamo con la descrizione dei driver necessari.
Fritz 7170 Firmware di base 29.04.59 DE
Questo frimware si basa sui sorgenti del kernel linux 2.6.13.1, versione priva del driver usbserial “corretto” per il funzionamento dei modem UMTS ad alta velocità ed equipaggiato con una versione del driver option capace di “riconoscere” pochi prodotti del costruttore in modo automatico.
In rete si trovano diverse patch per le versioni successive di usbserial ed è quindi servito uno studio più accurato dei sorgenti del driver per capire come integrare la patch al buffer IN e OUT (principale nota dolente del vecchio driver). Questa limitazione, per l’appunto dovuta alla dimensione esigua del buffer in ricezione, permetteva di instaurare connessioni dati alla velocità massima di 64Kbit/sec. Dopo un attento esame dei sorgenti e grazie a diversi spunti presenti in rete sono riuscito a trovare il modo di impostare il buffer IN a 4096 ed il buffer OUT a 512 e ad impostare gli slot URB in e out a 4 anzichè 3 e 2.
Queste modifiche consentono, in linea teorica, di potersi collegare a 7,2Mb in download e a 1Mb in upload.
Riporto qui sotto le modifiche fatte a usbserial.c :
static int debu static ushort maxSize = 4096; /* riga aggiunta e valore impostato fisso */ static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ static LIST_HEAD(usb_serial_driver_list);
goto probe_error; } buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); buffer_size = (endpoint->wMaxPacketSize > maxSize)?endpoint->wMaxPacketSize:maxSize; /*riga aggiunta*/ port->bulk_in_size = buffer_size; port->bulk_in_endpointAddress = endpoint->bEndpointAddress; port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
module_param(debug, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug enabled or not"); module_param(maxSize, ushort, 0); /*riga aggiunta*/ MODULE_PARM_DESC(maxSize, "User specified USB endpoint size"); /*riga aggiunta*/
Le prime due modifiche sono fondamentali in quanto permettono di aumentare la dimensione del buffer IN, la terza è solo “di contorno” in quanto aggiunge la descrizione del nuovo parametro che viene “passato” al “caricamento” del modulo usbserial:
modprobe usbserial vendor=0xabcd product=0xdfeg maxSize=4096
Come potete notare, a differenza delle indicazioni reperite in rete, ho previsto un valore di inizializzazione diverso da 0 per evitare il rischio che il modulo option possa andare a “caricare” usbserial senza il nuovo parametro, che invece in questo modo è gia preimpostato in modo corretto.
Ora riporto le modifiche al driver option.c :
/* Vendor and product IDs */
#define OPTION_VENDOR_ID 0x0AF0
#define HUAWEI_VENDOR_ID 0x12D1
#define AUDIOVOX_VENDOR_ID 0x0F3D
#define NOVATELWIRELESS_VENDOR_ID 0x1410
#define ANYDATA_VENDOR_ID 0x16d5
#define OPTION_PRODUCT_OLD 0x5000
#define OPTION_PRODUCT_FUSION 0x6000
#define OPTION_PRODUCT_FUSION2 0x6300
#define OPTION_PRODUCT_COBRA 0x6500
#define OPTION_PRODUCT_COBRA2 0x6600
#define HUAWEI_PRODUCT_E600 0x1001
#define AUDIOVOX_PRODUCT_AIRCARD 0x0112
#define NOVATELWIRELESS_PRODUCT_U740 0x1400
#define ANYDATA_PRODUCT_ID 0x6501
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
{ USB_DEVICE(0x05c6, 0x6613) }, /* ONDA M1HS <- aggiunta*/
{ USB_DEVICE(0x12d1, 0x1003) }, /* Huawei E220 <- aggiunta*/
{ USB_DEVICE(0x19D2, 0x0001) }, /* ONDA mh602hs <- aggiunta*/
{ } /* Terminating entry */
};
/* per port private data */ #define N_IN_URB 4 #define N_OUT_URB 4 #define IN_BUFLEN 4096 #define OUT_BUFLEN 512
La prima modifica permette il riconoscimento automatico di un maggior numero di modem UMTS, la seconda modifica i valori dei buffer e degli URB.
Una volta compilati i driver usbserial.ko e option.ko li ho copiati nella cartella
/lib/modules/2.6.13.1-ohio/kernel/drivers/usb/serial/
Fatto questo sono andato a modificare il file modules.dep, l’elenco delle dipendenze dei driver.
Nel file modules.dep vanno aggiunte queste righe:
/lib/modules/2.6.13.1-ohio/kernel/drivers/usb/serial/usbserial.ko: /lib/modules/2.6.13.1-ohio/kernel/drivers/usb/core/usbcore.ko
/lib/modules/2.6.13.1-ohio/kernel/drivers/usb/serial/option.ko: /lib/modules/2.6.13.1-ohio/kernel/drivers/usb/serial/usbserial.ko
Ora abbiamo tutto l’occorrente per cominciare !
Cosa succede quando si collega il modem umts alla porta usb ?
Il GRANDE problema sta nel fatto che questi modem UMTS incorporano un Virtual CD contenete driver e programmi per windows; il kernel di conseguenza li rileva come CDROM Usb e lancia gli script che atti a “montare” i driver usbstorage. Processo che ovviamente fallisce. Quanto affermato è constatabile digitando in successione da consolle i 3 comandi lsusb, lsmod e dmesg (il primo elenca le periferiche USB connesse, il secondo i moduli “caricati”, il terzo i messaggi del kernel).
lsusb
BUS=001 DEV=004 VID=12d1 PID=1003 CLS=00 SCL=00 ISOC=0 INUM=1 ICLS1=08 <-- MassStorage ISCL1=06 <-- CDROM
lsmod
Module Size Used by Tainted: P vfat 11392 0 fat 49072 1 vfat nls_cp437 5248 0 nls_iso8859_1 3584 0 usb_storage 33296 0 <-- Questo è il nostro problema/salvatore sd_mod 14864 0 scsi_mod 92560 2 usb_storage,sd_mod mbcache 8080 1 ext2 usbahcicore 26064 0 usbcore 113328 3 usb_storage,usbahcicore
Ora il modem come fa ad esporre le seriali ? In rete è reperibile un piccolo programmino che agendo a livello usb permette al modem di commutare da cdrom a serial. Questa “strada” ad ogni modo non è percorribile dal momento che questo programmino è stato scritto per kernel molto superiori rispetto a quello che equipaggia i Fritz. Ad ogni modo osservando attentamente il comportamento del modem usb in mio possesso ho notato che dopo una decina di secondi automaticamente si scollega come CDROM per andare a ricollegarsi come serial… Questa è la soluzione !
Ma perchè avviene questo ?
Dal momento che il Fritz non “carica” i driver per il CDROM (non li possiede), presumo che il modem non vedendo “montare” la sezione cdrom entro un tempo prestabilito commuti automaticamente la periferica in seriale. Questo supposizione è ulteriormente confermata dalla prova che ho effettuato inserendo il modem tra le periferiche unusual, lasciando a me il compito di specificare il driver appropriato per l’hardware connesso: il kernel infatti è istruito in modo tale da non ritenere il modem una valida unità disco e conseguentemente non “carica” il modulo usbstorage e non tenta di “montare” l’unita. Il risultato è che il modem rimane in modalita CDROM e non commuta in seriale. E’ dunque necessario modificare gli script di hotplug, intercettando il momento in cui il modem commuta il proprio “status” per andare a caricare il driver usbserial.
Ecco l’output di lsusb dopo la commutazione del modem da CDROM in seriale:
lsusb
BUS=001 DEV=005 VID=12d1 PID=1003 CLS=00 SCL=00 ISOC=0 INUM=3 ICLS1=255 ISCL1=255 ICLS2=255 ISCL2=255 ICLS3=08 ISCL3=06
L’output di lsmod resta immutato.
Bene, ora che abbiamo capito il comportamento del modem usb andremo a seguire l’iter di inizializzazione di una periferica usbstorage investigandone gli script ed il loro funzionamento.
Per scoprire l’arcano ho connesso una memoria di massa usb al Fritz ed ho inviato in continuazione il comando ps in modo da vedere i processi che vengono inizializzati.
1611 root 1196 S N /bin/sh /etc/hotplug/storage add 007 /proc/bus/usb/001/ 1612 root 1180 S N /bin/sh /etc/hotplug/run_mount 007 /proc/bus/usb/001/
“Diamo uno sguardo” a questi script… il primo è quello che viene “lanciato” quando si inserisce la periferica usb, il secondo si preoccupa di “montare” le partizioni trovate ed i servizi associati. Si può notare immediatamente che lo script storage è parametrizzato in AZIONE DEV-ID BUS-ID che di volta in volta gli sono passati dal kernel.
Bhe siamo proprio fortunati, abbiamo gia tutte le informazioni necessarie ! Basta andare a modificare la sezione add in modo tale che qualora venga rilevata una periferica che espone le seriali (che il sistema ha identificato come unità disco) venga “lanciato” il nostro script personalizzato per il modem UMTS senza che sia montato usbstorage o siano cercate ulteriori partizioni.
Analizziamo quindi lo script storage in /etc/hotplug/
[cut]
add) passeeren
#------------------ aggiunto ------------------ if lsusb -h $3 | grep -e 'ICLS.=255' > /dev/null ; then /etc/hotplug/usbgsm add $3 vrijgeven else #----- ovvio che if va chiuso a fine routine add ------
if test $FIRST -eq 0; then lsmod | grep usb-storage || FIRST=1 fi if test $FIRST -eq 1; then touch /var/STARTING modprobe sd_mod modprobe usb-storage
#tune write behaviour echo 2 > /proc/sys/vm/laptop_mode echo 100 > /proc/sys/vm/dirty_expire_centisecs echo 100 > /proc/sys/vm/dirty_writeback_centisecs
wait4exist /proc/scsi/usb-storage 5 # Let SCSI settle... modprobe nls_iso8859-1 modprobe nls_cp437 modprobe vfat modprobe ext2 modprobe ext3
if ! test -d $SYSFS; then # Temporary patch, this should be handled mkdir -p $SYSFS # globally... mount -t sysfs sysfs $SYSFS fi if ! test -d /var/media/ftp; then mkdir -p /var/media/ftp # be sure only root is allowed to write to /var/media/ftp chmod 755 /var/media/ftp touch $DEVMAP fi rm /var/STARTING fi
vrijgeven
[cut]
Descriviamo le prime righe…
la prima istruzione della sezione add è passeeren e l’ultima vrijgeven.
In un primo momento le ho ignorate, successivamente ne ho approfondito il funzionamento poichè sono istruzioni che vengono utilizzate in tutte le sezioni del file ed anche in altri script… saranno certamente importanti!!!.
Controllando l’ inizio del file storage poche righe prima della sezione add:
# Simple semaphore stuff: # includes /etc/hotplug/rc.usbsema # needs $USBLOCKFILE # functions available: # passeeren (); # vrijgeven (); # atomic_touch (Filename) USBLOCKFILE=/var/USBLOCK_storage test -f /etc/hotplug/rc.usbsema && . /etc/hotplug/rc.usbsema
Notate i commenti che gentilmente AVM ha aggiunto?! Quelle sono delle funzioni per il controllo del corretto flusso di esecuzione degli script: passeeren avvio ed impegno dell’incrocio, vrijgeven stop e disimpegno dell’incrocio (sto utilizzando il gergo stradale visto che si chiama semaforo – Simple semaphore stuff – ). Bene ora che mi sono tolto questa curiosità continuiamo l’inserimento dei nostri controlli.
Cosa distingue una perifericha seriale usb ? Controlliamo lsusb… ICLS1=255 indica periferica con componente seriale.
Non ci resta che prendere nota di quel valore prima di proseguire con lo script storage. Come si nota dalle istruzioni aggiunte è sufficiente lanciare lsusb facendogli elencare solo la DEV-ID di nostro interesse (nel nostro caso è il terzo parametro – $3 – passato a storage). Se la troviamo avviamo il nostro script usbgsm in stile come AVM, AZIONE DEV-ID. Poi chiaramente diamo il via libera al semaforo.
Ok, visto che stiamo lavorando sullo script storage, abbiamo gestito il plug del modem, ma quanto si fa l’unplug che succede ? Dobbiamo scaricare i driver umts e fare altre cose, dove lanciamo il nostro script di unplug ?
Ripetendo la procedura precedente, scolleghiamo la penna usb storage e controlliamo cosa viene eseguito con ps:
1984 root 1192 S N /bin/sh /etc/hotplug/storage remove 007 /proc/bus/usb/001/
Trovato!!… come potevamo immaginare viene lanciato storage con azione remove e DEV-ID e BUS-ID. La sezione da controllare è quindi remove.
remove) # Unmounting lost partitions
#---------- aggiunta ----------------- if [ "`cat /var/usbgsm-pid`" = "$3" ] ; then passeeren /etc/hotplug/usbgsm remove $3 vrijgeven else #-------- if da chiudere alla fine --------- test -x $MSTOP && $MSTOP MAPS=`grep "^$3=" $DEVMAP`
quindi come prima cosa vediamo se la periferica rimossa è il modem e lanciamo il nostro script, altrimenti lasciamo che faccia il suo dovere. In un secondo momento spiegherò come sia possibile capire se sia o meno il modem.
Fin ora cosa siamo riusciti a fare:
- i driver necessari per il fuzionamento
- il catch degli eventi di plug e unplug del modem
Concludiamo qui questo lungo e tedioso articolo, nella prossima puntata scriveremo lo script usbgsm e vedremo come gestire corretamente il plug&play. Successivamente seguiranno altri articoli relativi l’instaurazione della connessione dati UMTS, la configurazione delle interfaccie di rete del fritz e la realizzazione di una interfaccia grafica.
Ciao Skizzo300






Ottimo articolo!!! Grazie Skizzo
Commentato da Skumpic | ottobre 3, 2008, 11:31 |Che dire..
Se ti sei fatto un nome tra gli appassionati del VoIP ,per essere stato il primo a tradurre l’ostica interfaccia crucca del Fritz in ITALIANO ;e poi come collaboratore di LIberailvoip ,ecc ecc ecc
Con questa tua intuizione ed (ora) anche applicazione pratica ;arrivi al tuo acuto.
Quello che ti proietta definitivamente nell’olimpo del VoIP.
Grazie per tutto quello che hai gia fatto ,e per quello che farai..
surfer
Commentato da Surfer | ottobre 3, 2008, 18:15 |sai che questi aggeggi mi stimolano
e per me condividere quello che scopro è sempre un piacere 
Ciao Sk3
Commentato da skizzo3000 | ottobre 4, 2008, 01:04 |ciao,
complimenti per la modifica. si vede che sei uno smanettone di questi sistemi !. volevo chiederti: è possibile collegare un modem di tipo hsdpa al posto di quello umts ? grazie . saluti
Commentato da carmine | ottobre 4, 2008, 09:12 |ciao Carmine,
la guida di Skizzo è indipendente dalla tecnologia connettiva utilizzata (gprs, umts o hsdpa che sia).
La cosa fondamentale (e che forse è data per scontato nella guida) e che l’hardware utilizzato sia supportato dal kernel linux che monta il fritz.
Nello specifico Skizzo utilizza un modem usb supportato dal driver airprime (visto che il sistema monta in automatico un virtual cd ipotizzo sia un huawei e220), ma questo non vieta di utilizzare modem usb differenti e che non integrino un virtual cd (in questo caso ovviamente tutta la seconda parte della guida sarebbe da omettere dal momento che il sistema attribuisce automaticamente e direttamente le porta seriali senza bisogno di alcun “hack”).
La cosa fondamentale è appunto che il kernel supporti l’hardware che intendi utilizzare!! (ed ormai questo si può quasi dare per dato di fatto soprattutto per quanto riguarda gli ultimi modem rilasciati sul mercato).
ciao
Skumpic
Commentato da skumpic | ottobre 4, 2008, 12:43 |Ciao carmine,
la mia modifica è testata per i modem della huawei ma sicuramente va anche con gli altri, chiaramente se quello che vuoi utilizzare non è presente tra quelli listati nella sezione del driver option.c ad inizio articolo bisogna aggiungerlo.
Cmq ho sempre scritto UMTS per semplicità, HSDPA è solo una modalità di connessione di rete che non cambia nulla dal punto di vista del router.
Ciao Sk3
Commentato da skizzo3000 | ottobre 4, 2008, 16:04 |@Skizzo,
mi permetto di correggerti. Non è affatto detto che sia necessario aggiungere il proprio modem se non presente nel listato del driver option.c
Il kernel linux utilizza 3 driver “specifici” (Sierra, Option, Airprime) e 1 “generico” (usbserial) per questi dispositivi mobili, quindi potrebbe accadere che il proprio hardware venga riconosciuto automaticamente dal Kernel ricorrendo ad uno degli altri driver presenti (o che si possono compilare). Ad esempio quasi tutti i prodotti ONDA funzionano con il modulo Airprime.
Per maggiori informazioni vi rimando a questi post (e sopratutto ai commenti che ne sono seguiti):
http://blog.liberailvoip.it/2008/03/04/onda-n501hs-et501hs-ed-altri-modem-usb-pcmcia-ed-express-card-con-linux-usbserial/
ciao
Commentato da skumpic | ottobre 5, 2008, 09:50 |@skumpic
L’articolo che mi hai linkato l’avevo letto ma non è per nulla applicabile sul fritz per 2 motivi:
1) il kernel del fritz in questione è 2.6.13.1 debian quindi notevolmente + arretrato (anno 2005) di quelli trattati nell’articolo.
2) la struttura HW del fritz è molto diversa da un PC, tutto è ritagliato e patchato per quel HW. Se vuoi aggiungere quancosa che il fritz non ha devi partire dal kernel, poi i moduli e poi gli script.
Come avevo scritto nell’articolo, dalla rete si possono prendere solo degli spunti ma nessuna patch!
I comportamenti del kernel sono da studiare caso x caso, xkè il kernel è essenziale, non ha nulla in più. Bisogna studiarsi i sorgenti e la struttura del kernel.
Per quanto riguarda i driver…
tutti i modem adottano un protocollo standard ETSI, usbserial è quello che crea le seriali di sistema necessarie ad option che è quello che si preoccupa di gestire la comunicazione dei comandi AT.
Quindi nel firmware che ho fatto io, tutti i modem vengono installati con il driver option che a sua volta carica usbserial.
Sono io che ho scritto lo script di hotplug che carica i driver! Il kernel mi passa solo l’evento di plug e unplug… non fa altro !
Il fritz mi piace appunto perchè gli fai fare quello che vuoi tu e non devi sottostare a comportamenti preimpostati (tranne quelli essenziali che sono veramente pochi).
Quindi tutte le considerazioni dell’articolo da te scritto e commentato linkatomi è molto interessante e corretto x PC con kernel 2.6.22 in su. Gia sul kernel 2.6.19 le patch non sono più valide.
Ciao Sk3
Commentato da skizzo3000 | ottobre 5, 2008, 12:18 |Complimenti Skizzo, non vedo l’ora di leggere la seconda parte, ovvero come hai risolto l’arcano……
Commentato da bbx | ottobre 6, 2008, 00:03 |Molto buono, i miei complimenti, la guida sembra esaustiva e completa!!
Appena mi sara’possibile voglio proprio provare!!!
Complimenti
Commentato da Emblema | ottobre 13, 2008, 15:22 |Ciao
Ho un problema con il mio fritz!box in quanto vorrei utilizzare la sua porta usb e collegarla tramite un convertitore usb/serial al mio impianto di domotica.
Qualcuno mi puo’ dare delle indicazioni in merito.
Grazie
Commentato da lnsd | gennaio 23, 2009, 10:05 |@lnsd
Ti consiglio di controllare il forum di vocesuip (www.vocesuip.com).
Li troverai sicuramente l’assistenza che cerchi!
Commentato da skumpic | gennaio 27, 2009, 12:51 |Scusatemi…. Io ho un Fritz 7170 e vorrei collegarlo alla mia pennina della 3 per avere la connettività wireless in casa.
La guida l’ho trovata ottima e molto dettagliata, ma non è possibile avere il firmware da applicare al router stesso?
Grazie a chi mi risponderà!
Commentato da Enzo | gennaio 30, 2009, 23:01 |@Enzo
Da quanto ricordo la procedura di Skizzo per ora è poco più di un proof of concept e ad oggi non è utilizzabile in modo continuativo.
ciao
Commentato da skumpic | gennaio 31, 2009, 12:22 |