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_Plus_Dialing by
Diff: MDM.cpp
- Revision:
- 79:291df065e345
- Parent:
- 78:caf0014375cb
- Child:
- 80:34985b4d821e
diff -r caf0014375cb -r 291df065e345 MDM.cpp --- a/MDM.cpp Tue May 20 11:40:07 2014 +0000 +++ b/MDM.cpp Mon May 26 11:55:16 2014 +0000 @@ -12,6 +12,9 @@ //! check for timeout #define TIMEOUT(t, ms) ((ms != TIMEOUT_BLOCKING) && (ms < t.read_ms())) +#define REG_OK(r) ((r == REG_HOME) || (r == REG_ROAMING)) +#define REG_DONE(r) ((r == REG_HOME) || (r == REG_ROAMING) || (r == REG_DENIED)) + #ifdef MDM_DEBUG void dumpAtCmd(const char* buf, int len) { @@ -162,11 +165,12 @@ if (sscanf(cmd, "CREG: %*d,%d,%d,%d",&a,&b,&c) == 3) { // _net.sid = a; // _net.nid = b; - if (c == 0) _net.reg = REG_NONE; // not registered, home network - else if (c == 1) _net.reg = REG_HOME; // registered, home network - else if (c == 2) _net.reg = REG_NONE; // not registered, but MT is currently searching a new operator to register to - else if (c == 3) _net.reg = REG_DENIED; // registration denied - else if (c == 5) _net.reg = REG_ROAMING; // registered, roaming + if (c == 0) _net.csd = REG_NONE; // not registered, home network + else if (c == 1) _net.csd = REG_HOME; // registered, home network + else if (c == 2) _net.csd = REG_NONE; // not registered, but MT is currently searching a new operator to register to + else if (c == 3) _net.csd = REG_DENIED; // registration denied + 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>]] } else if (sscanf(cmd, "CSS %*c,%2s,%*d",s) == 1) { @@ -174,35 +178,41 @@ } } else { // GSM/UMTS Specific ------------------------------------------- - // +CREG: <n>,<stat>[,<lac>,<ci>[,AcT]] // reply to AT+CREG - // +CREG: <stat>[,<lac>,<ci>[,AcT]] // URC - b = 255; - r = sscanf(cmd, "CREG: %*d,%d,\"%X\",\"%X\",%d",&a,&b,&c,&d); - if (r <= 0) - r = sscanf(cmd, "CREG: %d,\"%X\",\"%X\",%d",&a,&b,&c,&d); - if (r >= 1) { - // network status - if (a == 0) _net.reg = REG_NONE; // 0: not registered, home network - else if (a == 1) _net.reg = REG_HOME; // 1: registered, home network - else if (a == 2) _net.reg = REG_NONE; // 2: not registered, but MT is currently searching a new operator to register to - else if (a == 3) _net.reg = REG_DENIED; // 3: registration denied - else if (a == 4) _net.reg = REG_UNKNOWN; // 4: unknown - else if (a == 5) _net.reg = REG_ROAMING; // 5: registered, roaming - if ((r >= 2) && (b != 0xFFFF)) _net.lac = b; // location area code - if ((r >= 3) && (c != 0xFFFFFFFF)) _net.ci = c; // cell ID - // access technology - if (r >= 4) { - if (d == 0) _net.act = ACT_GSM; // 0: GSM - else if (d == 1) _net.act = ACT_GSM; // 1: GSM COMPACT - else if (d == 2) _net.act = ACT_UTRAN; // 2: UTRAN - else if (d == 3) _net.act = ACT_EDGE; // 3: GSM with EDGE availability - else if (d == 4) _net.act = ACT_UTRAN; // 4: UTRAN with HSDPA availability - else if (d == 5) _net.act = ACT_UTRAN; // 5: UTRAN with HSUPA availability - else if (d == 6) _net.act = ACT_UTRAN; // 6: UTRAN with HSDPA and HSUPA availability + // +UUPSDD: <profile_id> + if (sscanf(cmd, "UUPSDD: %d",&a) == 1) { + if (*PROFILE == a) _ip = NOIP; + } else { + // +CREG|CGREG: <n>,<stat>[,<lac>,<ci>[,AcT[,<rac>]]] // reply to AT+CREG|AT+CGREG + // +CREG|CGREG: <stat>[,<lac>,<ci>[,AcT[,<rac>]]] // URC + b = 0xFFFF; c = 0xFFFFFFFF; d = -1; + r = sscanf(cmd, "%s %*d,%d,\"%X\",\"%X\",%d",s,&a,&b,&c,&d); + if (r <= 1) + r = sscanf(cmd, "%s %d,\"%X\",\"%X\",%d",s,&a,&b,&c,&d); + if (r >= 2) { + Reg *reg = !strcmp(s, "CREG:") ? &_net.csd : + !strcmp(s, "CGREG:") ? &_net.psd : NULL; + if (reg) { + // network status + if (a == 0) *reg = REG_NONE; // 0: not registered, home network + else if (a == 1) *reg = REG_HOME; // 1: registered, home network + else if (a == 2) *reg = REG_NONE; // 2: not registered, but MT is currently searching a new operator to register to + else if (a == 3) *reg = REG_DENIED; // 3: registration denied + else if (a == 4) *reg = REG_UNKNOWN; // 4: unknown + else if (a == 5) *reg = REG_ROAMING; // 5: registered, roaming + if ((r >= 3) && (b != 0xFFFF)) _net.lac = b; // location area code + if ((r >= 4) && (c != 0xFFFFFFFF)) _net.ci = c; // cell ID + // access technology + if (r >= 5) { + if (d == 0) _net.act = ACT_GSM; // 0: GSM + else if (d == 1) _net.act = ACT_GSM; // 1: GSM COMPACT + else if (d == 2) _net.act = ACT_UTRAN; // 2: UTRAN + else if (d == 3) _net.act = ACT_EDGE; // 3: GSM with EDGE availability + else if (d == 4) _net.act = ACT_UTRAN; // 4: UTRAN with HSDPA availability + else if (d == 5) _net.act = ACT_UTRAN; // 5: UTRAN with HSUPA availability + else if (d == 6) _net.act = ACT_UTRAN; // 6: UTRAN with HSDPA and HSUPA availability + } + } } - // +UUPSDD: <profile_id> - } else if (sscanf(cmd, "UUPSDD: %d",&a) == 1) { - if (*PROFILE == a) _ip = NOIP; } } } @@ -277,10 +287,17 @@ INFO("Modem::wakeup\r\n"); DigitalOut pin(pn, 1); while (i--) { - pin = 0; - RELAX_MS(5); // SARA-G/U - pin = 1; - RELAX_MS(100); + // SARA-U2/LISA-U2 50..80us + pin = 0; wait_us(50); + pin = 1; wait_ms(10); + + // SARA-G35 >5ms, LISA-C2 > 150ms + pin = 0; wait_ms(150); + pin = 1; wait_ms(100); + + // purge any messages + while (WAIT != waitFinalResp(NULL,NULL,0)) + /* nothing */; // check interface and disable local echo sendFormated("AT\r\n"); if(RESP_OK == waitFinalResp(NULL,NULL,500)) @@ -407,7 +424,15 @@ return false; _dev.lpm = LPM_ACTIVE; } + // enable the psd registration unsolicited result code + sendFormated("AT+CGREG=2\r\n"); + if (RESP_OK != waitFinalResp()) + return false; } + // enable the network registration unsolicited result code + sendFormated("AT+CREG=%d\r\n", (_dev.dev == DEV_LISA_C200) ? 1 : 2); + if (RESP_OK != waitFinalResp()) + return false; // Setup SMS in text mode sendFormated("AT+CMGF=1\r\n"); if (RESP_OK != waitFinalResp()) @@ -420,10 +445,6 @@ sendFormated("AT+CIMI\r\n"); if (RESP_OK != waitFinalResp(_cbString, _dev.imsi)) return false; - // enable the network registration unsolicited result code - sendFormated("AT+CREG=%d\r\n", (_dev.dev == DEV_LISA_C200) ? 1 : 2); - if (RESP_OK != waitFinalResp()) - return false; if (status) memcpy(status, &_dev, sizeof(DevStatus)); return true; @@ -489,9 +510,9 @@ INFO("Modem::register\r\n"); while (!checkNetStatus(status) && !TIMEOUT(timer, timeout_ms)) RELAX_MS(1000); - if (_net.reg == REG_DENIED) - ERROR("Network Registration Denied\r\n"); - return (_net.reg == REG_ROAMING) || (_net.reg == REG_HOME); + if (_net.csd == REG_DENIED) ERROR("CSD Registration Denied\r\n"); + if (_net.psd == REG_DENIED) ERROR("PSD Registration Denied\r\n"); + return REG_OK(_net.csd) || REG_OK(_net.psd); } bool MDMParser::checkNetStatus(NetStatus* status /*= NULL*/) @@ -503,7 +524,13 @@ sendFormated("AT+CREG?\r\n"); if (RESP_OK != waitFinalResp()) return false; - if ((_net.reg == REG_ROAMING) || (_net.reg == REG_HOME)) + if (_dev.dev != DEV_LISA_C200) { + // check PSD registration + sendFormated("AT+CGREG?\r\n"); + if (RESP_OK != waitFinalResp()) + return false; + } + if (REG_OK(_net.csd) || REG_OK(_net.psd)) { // check modem specific status messages if (_dev.dev == DEV_LISA_C200) { @@ -515,7 +542,7 @@ if (RESP_OK != waitFinalResp(_cbString, _net.num)) return false; // check if we have a Mobile Directory Number - if (!*_net.num || (memcmp(_net.num, "0000", 4) == 0)) + if (!*_net.num || (memcmp(_net.num, "000000", 6) == 0)) return false; // get the the Network access identifier string char nai[64]; @@ -523,10 +550,6 @@ if (RESP_OK != waitFinalResp(_cbString, nai)) return false; } else { - // check GPRS attach status - sendFormated("AT+CGATT?\r\n"); - if (RESP_OK != waitFinalResp(_cbCGATT, &_net.gprs)) - return false; // check operator selection sendFormated("AT+COPS?\r\n"); if (RESP_OK != waitFinalResp(_cbCOPS, &_net)) @@ -544,19 +567,7 @@ if (status) { memcpy(status, &_net, sizeof(NetStatus)); } - return ((_net.reg == REG_HOME) || (_net.reg == REG_ROAMING) || (_net.reg == REG_DENIED)); -} - -int MDMParser::_cbCGATT(int type, const char* buf, int len, Gprs* gprs) -{ - if ((type == TYPE_PLUS) && gprs){ - int i; - if (sscanf(buf, "\r\n+CGATT: %d\r\n", &i) == 1) { - if (i == 0) *gprs = GPRS_DETACHED; - else if (i == 1) *gprs = GPRS_ATTACHED; - } - } - return WAIT; + return REG_DONE(_net.csd) && REG_DONE(_net.psd); } int MDMParser::_cbCOPS(int type, const char* buf, int len, NetStatus* status) @@ -600,7 +611,8 @@ // ---------------------------------------------------------------- // internet connection -MDMParser::IP MDMParser::join(const char* apn /*= NULL*/, const char* username /*= NULL*/, const char* password /*= NULL*/) +MDMParser::IP MDMParser::join(const char* apn /*= NULL*/, const char* username /*= NULL*/, + const char* password /*= NULL*/, Auth auth /*= AUTH_DETECT*/) { INFO("Modem::join\r\n"); _ip = NOIP; @@ -623,40 +635,61 @@ // Check the profile int a = 0; + bool force = true; sendFormated("AT+UPSND=" PROFILE ",8\r\n"); if (RESP_OK != waitFinalResp(_cbUPSND, &a)) return NOIP; - if (a == 1) { + if (a == 1 && force) { // 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;; + a = 0; } - // Set up the APN - if (apn) { - sendFormated("AT+UPSD=" PROFILE ",1,\"%s\"\r\n", apn); - if (RESP_OK != waitFinalResp()) - return NOIP; - } - if (username) { - sendFormated("AT+UPSD=" PROFILE ",2,\"%s\"\r\n", username); + if (a == 0) { + // Set up the APN + if (apn) { + sendFormated("AT+UPSD=" PROFILE ",1,\"%s\"\r\n", apn); + if (RESP_OK != waitFinalResp()) + return NOIP; + } + 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; - } - if (password) { - sendFormated("AT+UPSD=" PROFILE ",3,\"%s\"\r\n", password); - if (RESP_OK != waitFinalResp()) + // 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; + } + i ++; + } + if (i > AUTH_CHAP) { + ERROR("Your modem APN/password/username may be wrong\r\n"); 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; - // Activate the profile and make connection - sendFormated("AT+UPSDA=" PROFILE ",3\r\n"); - if (RESP_OK != waitFinalResp(NULL,NULL,150*1000)) { - ERROR("Your modem APN/password/username may be wrong\r\n"); - return NOIP; + } } //Get local IP address sendFormated("AT+UPSND=" PROFILE ",0\r\n"); @@ -1128,11 +1161,10 @@ { dprint(param, "Modem::netStatus\r\n"); const char* txtReg[] = { "Unknown", "Denied", "None", "Home", "Roaming" }; - if (status->reg < sizeof(txtReg)/sizeof(*txtReg) && (status->reg != MDMParser::REG_UNKNOWN)) - dprint(param, " Registration: %s\r\n", txtReg[status->reg]); - const char* txtGprs[] = { "Unknown", "Detached", "Attached" }; - if (status->gprs < sizeof(txtGprs)/sizeof(*txtGprs) && (status->gprs != MDMParser::GPRS_UNKNOWN)) - dprint(param, " Gprs: %s\r\n", txtGprs[status->gprs]); + if (status->csd < sizeof(txtReg)/sizeof(*txtReg) && (status->csd != MDMParser::REG_UNKNOWN)) + dprint(param, " CSD Registration: %s\r\n", txtReg[status->csd]); + if (status->psd < sizeof(txtReg)/sizeof(*txtReg) && (status->psd != MDMParser::REG_UNKNOWN)) + dprint(param, " PSD Registration: %s\r\n", txtReg[status->psd]); const char* txtAct[] = { "Unknown", "GSM", "Edge", "3G", "CDMA" }; if (status->act < sizeof(txtAct)/sizeof(*txtAct) && (status->act != MDMParser::ACT_UNKNOWN)) dprint(param, " Access Technology: %s\r\n", txtAct[status->act]);