Add a bunch of APNs
Fork of C027_Support by
Diff: MDM.cpp
- Revision:
- 84:a05edb010176
- Parent:
- 82:055dcfcf9dcc
- Child:
- 85:dd8f4f0d0ca9
--- a/MDM.cpp Wed May 28 07:14:21 2014 +0000 +++ b/MDM.cpp Thu Jun 05 15:16:57 2014 +0000 @@ -5,6 +5,42 @@ #include "C027_api.h" #endif +/* ---------------------------------------------------------------- + APN stands for Access Point Name, a setting on your modem or phone + that identifies an external network your phone can access for data + (e.g., 3G or 4G Internet service on your phone). + + The APN settings can be forced when calling the join function. + Below is a list of known APNs that us used if no apn config + is forced. This list could be extended by other settings. + + For further reading: + wiki apn: http://en.wikipedia.org/wiki/Access_Point_Name + wiki mcc/mnc: http://en.wikipedia.org/wiki/Mobile_country_code + google: https://www.google.de/search?q=APN+list +---------------------------------------------------------------- */ +//! helper +#define _APN(a,u,p) a "\0" u "\0" p "\0" +//! default APN settings used by many networks +static const char* apndef = _APN("internet",,); +//! this is a list of special APNs for different network operators +static const struct { const char* mccmnc; const char* cfg; } apnlut[] = { +// Germany + { /*T-Mobile*/ "26201", _APN("internet.t-mobile","t-mobile","tm") }, +// Switzerland + { /*Swisscom*/ "22801", _APN("gprs.swisscom.ch",,) }, +// USA + { /*T-Mobile*/ "310026|310260|310490", + _APN("epc.tmobile.com",,) + _APN("fast.tmobile.com",,) /*LTE*/ }, + { /*AT&T*/ "310030|310150|310170|310260|310410|310560|310680", + _APN("phone",,) + _APN("wap.cingular","WAP@CINGULARGPRS.COM","CINGULAR1") + _APN("isp.cingular","ISP@CINGULARGPRS.COM","CINGULAR1") }, + // ... +}; +// ---------------------------------------------------------------- + #define PROFILE "0" //!< this is the psd profile used #define MAX_SIZE 128 //!< max expected messages //! test if it is a socket @@ -173,7 +209,7 @@ else if (c == 5) _net.csd = REG_ROAMING; // registered, roaming _net.psd = _net.csd; // fake PSD registration (CDMA is always registered) _net.act = ACT_CDMA; - // +CSS: <mode>[,<format>,<oper>[,<AcT>]] + // +CSS: <mode>[,<format>,<oper>[,<AcT>]] } else if (sscanf(cmd, "CSS %*c,%2s,%*d",s) == 1) { //_net.reg = (strcmp("Z", s) == 0) ? REG_UNKNOWN : REG_HOME; } @@ -430,6 +466,10 @@ sendFormated("AT+CGREG=2\r\n"); if (RESP_OK != waitFinalResp()) return false; + // set operator selection + sendFormated("AT+COPS=0,0\r\n"); + if (RESP_OK != waitFinalResp(NULL,NULL,180*1000)) + return false; } // enable the network registration unsolicited result code sendFormated("AT+CREG=%d\r\n", (_dev.dev == DEV_LISA_C200) ? 1 : 2); @@ -585,7 +625,6 @@ if (RESP_OK != waitFinalResp(_cbString, nai)) return false; } else { - // check operator selection sendFormated("AT+COPS?\r\n"); if (RESP_OK != waitFinalResp(_cbCOPS, &_net)) return false; @@ -689,50 +728,73 @@ // disconnect the profile already if it is connected sendFormated("AT+UPSDA=" PROFILE ",4\r\n"); if (RESP_OK != waitFinalResp(NULL,NULL,40*1000)) - return NOIP;; + return NOIP; a = 0; } if (a == 0) { - // Set up the APN - if (apn) { - sendFormated("AT+UPSD=" PROFILE ",1,\"%s\"\r\n", apn); - if (RESP_OK != waitFinalResp()) - return NOIP; + bool ok = false; + // try to lookup the apn settings from our local database by mccmnc + const char* config = NULL; + if (!apn && !username && !password) { + char mccmnc[8] = ""; + config = apndef; + sendFormated("AT+UDOPN=0\r\n"); + if ((RESP_OK == waitFinalResp(_cbUDOPN, mccmnc)) && *mccmnc) { + // many carriers use internet without username and password, os use this as default + // now try to lookup the setting for our table + for (int i = 0; i < sizeof(apnlut)/sizeof(*apnlut); i ++) { + if (strstr(apnlut[i].mccmnc, mccmnc)) { + config = apnlut[i].cfg; + break; + } + } + } } - if (username) { - sendFormated("AT+UPSD=" PROFILE ",2,\"%s\"\r\n", username); - if (RESP_OK != waitFinalResp()) - return NOIP; - } - if (password) { - sendFormated("AT+UPSD=" PROFILE ",3,\"%s\"\r\n", password); - if (RESP_OK != waitFinalResp()) - return NOIP; - } + // Set up the dynamic IP address assignment. sendFormated("AT+UPSD=" PROFILE ",7,\"0.0.0.0\"\r\n"); if (RESP_OK != waitFinalResp()) return NOIP; - // try different Authentication Protocols - // 0 = none - // 1 = PAP (Password Authentication Protocol) - // 2 = CHAP (Challenge Handshake Authentication Protocol) - int i = AUTH_NONE; - while (i <= AUTH_CHAP) - { - if ((auth == AUTH_DETECT) || (auth == i)) { - // Set up the dynamic IP address assignment. - sendFormated("AT+UPSD=" PROFILE ",6,%d\r\n", i); - if (RESP_OK != waitFinalResp()) - return NOIP; - // Activate the profile and make connection - sendFormated("AT+UPSDA=" PROFILE ",3\r\n"); - if (RESP_OK == waitFinalResp(NULL,NULL,150*1000)) - break; + + do { + if (config) { + apn = *config ? config : ""; + config += strlen(config)+1; + username = *config ? config : ""; + config += strlen(config)+1; + password = *config ? config : ""; + config += strlen(config)+1; + if (!*config) config = NULL; + TRACE("Testing APN Settings(\"%s\",\"%s\",\"%s\")\r\n", apn, username, password); } - i ++; - } - if (i > AUTH_CHAP) { + // Set up the APN + sendFormated("AT+UPSD=" PROFILE ",1,\"%s\"\r\n", apn?apn:""); + if (RESP_OK != waitFinalResp()) + return NOIP; + sendFormated("AT+UPSD=" PROFILE ",2,\"%s\"\r\n", username?username:""); + if (RESP_OK != waitFinalResp()) + return NOIP; + sendFormated("AT+UPSD=" PROFILE ",3,\"%s\"\r\n", password?password:""); + if (RESP_OK != waitFinalResp()) + return NOIP; + // try different Authentication Protocols + // 0 = none + // 1 = PAP (Password Authentication Protocol) + // 2 = CHAP (Challenge Handshake Authentication Protocol) + for (int i = AUTH_NONE; i <= AUTH_CHAP && !ok; i ++) { + if ((auth == AUTH_DETECT) || (auth == i)) { + // Set up the Authentication Protocol + sendFormated("AT+UPSD=" PROFILE ",6,%d\r\n", i); + if (RESP_OK != waitFinalResp()) + return NOIP; + // Activate the profile and make connection + sendFormated("AT+UPSDA=" PROFILE ",3\r\n"); + if (RESP_OK == waitFinalResp(NULL,NULL,150*1000)) + ok = true; + } + } + } while (config); // maybe use next setting ? + if (!ok) { ERROR("Your modem APN/password/username may be wrong\r\n"); return NOIP; } @@ -745,6 +807,15 @@ return _ip; } +int MDMParser::_cbUDOPN(int type, const char* buf, int len, char* mccmnc) +{ + if ((type == TYPE_PLUS) && mccmnc) { + if (sscanf(buf, "\r\n+UDOPN: 0,\"%[^\"]\"", mccmnc) == 1) + ; + } + return WAIT; +} + int MDMParser::_cbCMIP(int type, const char* buf, int len, IP* ip) { if ((type == TYPE_PLUS) && ip) {