Added HTTP API to C027_Support library.
Fork of C027_Support by
Revision 79:291df065e345, committed 2014-05-26
- Comitter:
- mazgch
- Date:
- Mon May 26 11:55:16 2014 +0000
- Parent:
- 78:caf0014375cb
- Child:
- 80:34985b4d821e
- Commit message:
- added different Authentication protocols handle gprs registration
Changed in this revision
MDM.cpp | Show annotated file Show diff for this revision Revisions of this file |
MDM.h | Show annotated file Show diff for this revision Revisions of this file |
--- 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]);
--- a/MDM.h Tue May 20 11:40:07 2014 +0000 +++ b/MDM.h Mon May 26 11:55:16 2014 +0000 @@ -53,12 +53,10 @@ typedef enum { REG_UNKNOWN, REG_DENIED, REG_NONE, REG_HOME, REG_ROAMING } Reg; //! Access Technology typedef enum { ACT_UNKNOWN, ACT_GSM, ACT_EDGE, ACT_UTRAN, ACT_CDMA } AcT; - //! Gprs Attach Status - typedef enum { GPRS_UNKNOWN, GPRS_DETACHED, GPRS_ATTACHED } Gprs; //! Network Status typedef struct { - Reg reg; //!< Registration Status - Gprs gprs; //!< Gprs Attach status + Reg csd; //!< CSD Registration Status (Circuit Switched Data) + Reg psd; //!< PSD Registration status (Packet Switched Data) AcT act; //!< Access Technology int rssi; //!< Received Signal Strength Indication (in dBm, range -113..-53) int ber; //!< Bit Error Rate (BER), see 3GPP TS 45.008 [20] subclause 8.2.4 @@ -129,6 +127,8 @@ // Data Connection (GPRS) // ---------------------------------------------------------------- + typedef enum { AUTH_NONE, AUTH_PAP, AUTH_CHAP, AUTH_DETECT } Auth; + /** register (Attach) the MT to the GPRS service. \param apn the of the network provider e.g. "internet" or "apn.provider.com" \param username is the user name text string for the authentication phase @@ -136,7 +136,8 @@ \param dump set to true if you like to dump the status if successful \return the ip that is assigned */ - MDMParser::IP join(const char* apn = NULL, const char* username = NULL, const char* password = NULL); + MDMParser::IP join(const char* apn = NULL, const char* username = NULL, + const char* password = NULL, Auth auth = AUTH_DETECT); /** deregister (detach) the MT from the GPRS service. \return true if successful, false otherwise @@ -476,7 +477,6 @@ static int _cbCSQ(int type, const char* buf, int len, NetStatus* status); static int _cbCOPS(int type, const char* buf, int len, NetStatus* status); static int _cbCNUM(int type, const char* buf, int len, char* num); - static int _cbCGATT(int type, const char* buf, int len, Gprs* gprs); // sockets static int _cbCMIP(int type, const char* buf, int len, IP* ip); static int _cbUPSND(int type, const char* buf, int len, int* act);