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.
Dependents: GPS_6Axis_DataLogger_SD_UDP
Fork of C027_Support 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]);
