Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of C027_Support_New 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) {