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 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);
