Ciao a tutti, è giunta l'ora che anche la sezione dedicata agli sviluppatori di Android-dev.it abbia una nuova guida!

E siccome per risolvere il problema in oggetto ho dovuto fare una piccola modifica al sorgente di Android e ricompilare, direi che quanto segue può stare in questa sezione a buon titolo.
Il problema è noto, ci sono diversi post qui nel forum e se ne trovano molti altri simili anche nei forum internazionali:
alcuni APN che richiedono l'impostazione di username e password non funzionano negli attuali smartphone che montano Android (e questo vale per tutte le versioni: 1.0, 1.5, 1.6 e anche l'ultima, la Eclair 2.0). .
Purtroppo l'APN della mia azienda è tra quelli che danno problemi...
Facendo il debug dei messaggi che la libreria RIL invia al modem radio, già da tempo si era capito che il problema risiedeva proprio nella procedura di autenticazione, con un messaggio di errore del tipo:
Quote:
D/HTC_RIL ( 29): (t=1230210363)XX +HTCerror: 3,1D ...
D/GSM ( 92): [PdpConnection] Notify PDP fail at 1230210372261 due to Authentication Fail
Prima della soluzione al problema, un po' di teoria di base sui metodi di autenticazione usati dagli APN (o meglio usati dal protocollo PPP che crea un link punto-punto tra telefono e APN server); questi metodi possono essere:
-
nessuno (non è richiesto l'inserimento di username e password)
-
PAP (Password Authentication Protocol: è il metodo piu' seplice perchè prevede l'invio da parte del client di username/password in codifica ASCII in chiaro: d'altronde e' il canale wireless ad essere criptato, nel mondo radiomobile)
-
CHAP (Challenge-Handshake Authentication Protocol: è un metodo piu' sicuro, perchè basato sull'invio da parte del client di una risposta al challenge inviato dal server e quindi la password non è mai inviata)
-
PAP/CHAP : è un'impostazione utilizzabile quando l'APN supporta entrambi i metodi di autenticazione e puoò negoziare quale usare con il client
Ora, come già segnalato a suo tempo, allo stato attuale la piattaforma Android gestisce l'autenticazione con l'APN nel modo seguente:
- nessuna autenticazione se si lasciano vuoti i campi username e password nei settings delle impostazioni wireless
- metodo di autenticazione PAP/CHAP se invece si impostano i campi username e password
Ecco infatti cosa si trova nel codice sorgente:
[platform/frameworks/base.git]/telephony/java/com/android/internal/telephony/RIL.javaCode:
1255 /**
1256 * The preferred new alternative to setupDefaultPDP that is1257 * CDMA-compatible.
1258 *
1259 */
1260 public void
1261 setupDataCall(String radioTechnology, String profile, String apn,
1262 String user, String password, Message result) {
1263 RILRequest rr
1264 = RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result);
1265
1266 rr.mp.writeInt(6);
1267
1268 rr.mp.writeString(radioTechnology);
1269 rr.mp.writeString(profile);
1270 rr.mp.writeString(apn);
1271 rr.mp.writeString(user);
1272 rr.mp.writeString(password);
1273 //TODO(): Add to the APN database, AuthType is set to CHAP/PAP
1274 // 0 => Neither PAP nor CHAP will be performed, 3 => PAP / CHAP will be performed.
1275 if (user != null)
1276 rr.mp.writeString("3");
1277 else
1278 rr.mp.writeString("0");
1279
1280 if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " "
1281 + apn);
1282
1283 send(rr);
1284 }
platform/hardware/ril.git]/include/telephony/ril.hCode:
1234 * ((const char **)data)[5] is the PAP / CHAP auth type. Values:
1235 * 0 => PAP and CHAP is never performed.
1236 * 1 => PAP may be performed; CHAP is never performed.
1237 * 2 => CHAP may be performed; PAP is never performed.
1238 * 3 => PAP / CHAP may be performed - baseband dependent.
Purtroppo impostare l'autenticazione PAP/CHAP non va sempre bene, perchè non è detto che il client ed il server siano in grado di negoziare quale dei due metodi di autenticazione utilizzare. Se un APN prevede solo l'autenticazione PAP, impostare PAP/CHAP non sempre va bene...Ora, grazie all'utilizzo di una libreria RIL con il debug dei comandi AT attivo, sono stato in grado di capire quanto segue: sull' HTC Dream cosi' come su molti altri smartphone Android basati su processore QUALCOMM, il PDP Context (ovvero la conenssione dati) viene messa in piedi attraverso questo comando inviato al device
/dev/qmi (
Qualcomm Modem Interface):
Quote:
up <nome_APN> <username> <password> <AuthType>
dove AuthType vale appunto 0, 1, 2, 3.
Se si invia
Quote:
up <nome_APN> <username> <password> 3
ad un APN che supporta solo PAP, si ottiene l'errore riportato sopra ed il setup della connessione dati non riesce. Fortunatamente il campo
AuthType che la libreria RIL invia all'interfacccia QMI è quello che gli viene passato da
RIL.java, che si trova nel package
framework.jar di Android.
E' sufficiente quindi cambiare 3 in 1 nelle righe di codice del file RIL.java sopra riportato ed il gioco è fatto.
Ecco il log relativo all'attivazione con successo di una connessione dati con metodo di autenticazione PAP attivato (privo dei dati confidenziali):
Code:
D/GSM ( 2101): [PdpConnection] DataConnection.getState()
D/GSM ( 2101): [PdpConnection] Connecting to carrier: 'MioAPN' APN: 'XXX' proxy: '' port: '
D/RILJ ( 2101): [0052]> SETUP_DATA_CALL XXX
D/GSM ( 2101): [GsmDataConnectionTracker] setState: INITING
D/HTC_RIL (24571): ril_func_config_and_activate_pdp():called
D/HTC_RIL (24571): ril_func_config_and_activate_pdp():0,XXX
D/HTC_RIL (24571): @(t=1263303048)>> 9:up:<APN> <username> <password> 1
D/RILJ ( 2101): [0053]> REQUEST_GET_NEIGHBORING_CELL_IDS
D/RILJ ( 2101): WAKE_LOCK_TIMEOUT mReqPending=1 mRequestList=1
D/RILJ ( 2101): 0: [52] SETUP_DATA_CALL
D/HTC_RIL (24571): ril_func_config_and_activate_pdp():0, pdp_infos[qmi_idx].apn=XXX
D/HTC_RIL (24571): @(t=1263303076)>> 9:poll
D/HTC_RIL (24571): qmi0_read_thread():qmi read thread got [[STATE=up
D/HTC_RIL (24571): CID=1
D/HTC_RIL (24571): ADDR=XX.XX.XX.XX
D/HTC_RIL (24571): MASK=255.255.255.252
D/HTC_RIL (24571): GATEWAY=XX.XX.XX.XX
D/HTC_RIL (24571): DNS1=XX.XX.XX.XX
D/HTC_RIL (24571): DNS2=XX.XX.XX.XX
D/HTC_RIL (24571): (115)]] data from qmi fd 9.
D/HTC_RIL (24571): @(t=1263303076)< 9:STATE=up
D/HTC_RIL (24571): config_and_activate_pdp_rsp_handler():0,[1],[-1],[-1]
D/HTC_RIL (24571): config_and_activate_pdp_rsp_handler():out_pdp=1,rmnet0,XX.XX.XX.XX
D/RILJ ( 2101): [0061]< SETUP_DATA_CALL {1, rmnet0, XX.XX.XX.XX}
D/GSM ( 2101): [PdpConnection] DataConnection.handleMessage()
D/GSM ( 2101): [PdpConnection] interface=rmnet0 ipAddress=XX.XX.XX.XX gateway=XX.XX.XX.XX DNS1=XX.XX.XX.XX DNS2=XX.XX.XX.XX
D/GSM ( 2101): [PdpConnection] Notify PDP success at 1263303076569
D/GSM ( 2101): [PdpConnection] PDP setup on cid = 1
D/GSM ( 2101): [GsmDataConnectionTracker] setState: CONNECTED
D/GSM ( 2101): [DataConnection] Start poll NetStat
La modifica al codice di RIL.java è quindi di per se' banale a dirsi, un po' meno a farsi perchè nella pratica questo significa ricompilarsi il codice Android per il processore ARM usando Linux e la relativa toolchain per fare una cross-compilazione, ecc. ecc.
Io ho fatto tutto questo per
CyanogenMod 4.2.12.2 e se avete lo stesso firmware trovate framewrok.jar già bello patchato. Credo (ma non ne sono sicuro, che la nuova libreria possa funzionare anche con qualsiasi altro firmware basato su Android 1.6 Donut).
Per installare la versione di framework.jar a cui è stata applicata la patch in modo da supportare l'autenticazioe PAP, dovete fare cosi' (ovviamente dovete avere i permessi di root per il vostro telefonino):
1. Fate un backup con nandroid del telefono (non scherzo!, a me la 1ma volta il telefono andava in boot continuo ed ho dovuto ripristinare il firmware, quindi siete avvisati!)
2. Scaricate l'archivio in allegato e copiate la versione patched di framework.jar sulla sdcard:
Code:
adb push framework.jar /sdcard
3. Sostituite la versione di framework.jar originale con quella patched:Code:
adb remount
adb shell
eppoi dalla shell del telefonino:Code:
cd /system/framework
mv framework.jar framework.jar.original
cp /sdcard/framework.jar .
4. Da ultimo dovete cancellare la dalvik-cache e riavviare.Code:
cd <PATH>\dalvik-cache
rm *
exit
La prossima guida credo proprio sarà come usare il PROXY aziendale...
