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:
- 75:ce6e12067d0c
- Parent:
- 74:208e3e32d263
- Child:
- 76:f7c3dd568dae
diff -r 208e3e32d263 -r ce6e12067d0c MDM.cpp
--- a/MDM.cpp Thu May 15 22:20:42 2014 +0000
+++ b/MDM.cpp Fri May 16 14:13:00 2014 +0000
@@ -11,27 +11,40 @@
#define MAX_SIZE 128 //!< max expected messages
//! test if it is a socket
#define ISSOCKET(s) (((s) >= 0) && ((s) < (sizeof(_sockets)/sizeof(*_sockets))))
-
+//! check for timeout
+#define TIMEOUT(t, ms) ((ms != TIMEOUT_BLOCKING) && (ms < t.read_ms()))
#ifdef MDM_DEBUG
void dumpAtCmd(const char* buf, int len)
{
- printf(" %3d \"", len);
+ ::printf(" %3d \"", len);
while (len --) {
char ch = *buf++;
- if (ch == '\r') puts("\\r");
- else if (ch == '\n') puts("\\n");
- else if (ch >= 0x20) putchar(ch);
- else printf("\\x%02x", ch);
+ if ((ch > 0x1F) && (ch != 0x7F)) { // is printable
+ if (ch == '%') ::printf("%%");
+ else if (ch == '"') ::printf("\\\"");
+ else if (ch == '\\') ::printf("\\\\");
+ else putchar(ch);
+ } else {
+ if (ch == '\a') ::printf("\\a"); // BEL (0x07)
+ else if (ch == '\b') ::printf("\\b"); // Backspace (0x08)
+ else if (ch == '\t') ::printf("\\t"); // Horizontal Tab (0x09)
+ else if (ch == '\n') ::printf("\\n"); // Linefeed (0x0A)
+ else if (ch == '\v') ::printf("\\v"); // Vertical Tab (0x0B)
+ else if (ch == '\f') ::printf("\\f"); // Formfeed (0x0C)
+ else if (ch == '\r') ::printf("\\r"); // Carriage Return (0x0D)
+ else ::printf("\\x%02x", ch);
+ }
}
- puts("\"\r\n");
+ ::printf("\"\r\n");
}
- #define INFO (_debugLevel >= 1) ? : printf
- #define TRACE (_debugLevel >= 2) ? : printf
+ #define ERROR(fmt) (_debugLevel < 0) ? : ::printf(RED(fmt))
+ #define INFO(fmt) (_debugLevel < 1) ? : ::printf(GRE(fmt))
+ #define TRACE(...) (_debugLevel < 2) ? : ::printf(__VA_ARGS__)
#if 1 // colored terminal output using ANSI escape sequences
- #define COL(c,t) "\33[" c t "\33[" "39m"
+ #define COL(c,t) "\033[" c t "\033[" "39m"
#else
#define COL(c,t) t
#endif
@@ -46,6 +59,7 @@
#else
+ #define ERROR(...) (void)0 // no tracing
#define INFO(...) (void)0 // no tracing
#define TRACE(...) (void)0 // no tracing
@@ -80,7 +94,7 @@
{
#ifdef MDM_DEBUG
if (_debugLevel >= 3) {
- printf("%10.3f AT send ", _debugTime.read_ms()*0.001);
+ ::printf("%10.3f AT send ", _debugTime.read_ms()*0.001);
dumpAtCmd(buf,len);
}
#endif
@@ -117,16 +131,13 @@
(type == TYPE_PLUS) ? CYA(" + ") :
(type == TYPE_PROMPT) ? BLU(" > ") :
"..." ;
- printf("%10.3f AT read %s", _debugTime.read_ms()*0.001, s);
+ ::printf("%10.3f AT read %s", _debugTime.read_ms()*0.001, s);
dumpAtCmd(buf, len);
}
#endif
if ((ret != WAIT) && (ret != NOT_FOUND))
{
int type = TYPE(ret);
- if (type == TYPE_OK) return RESP_OK;
- if (type == TYPE_ERROR) return RESP_ERROR;
- if (type == TYPE_PROMPT) return RESP_PROMPT;
// handle unsolicited commands here
if (type == TYPE_PLUS) {
const char* cmd = buf+3;
@@ -208,14 +219,14 @@
if (WAIT != ret)
return ret;
}
+ if (type == TYPE_OK) return RESP_OK;
+ if (type == TYPE_ERROR) return RESP_ERROR;
+ if (type == TYPE_PROMPT) return RESP_PROMPT;
}
// relax a bit
RELAX_MS(10);
}
- while ((timeout_ms == TIMEOUT_BLOCKING) ||
- (timer.read_ms() < timeout_ms));
- timer.stop();
- timer.reset();
+ while (!TIMEOUT(timer, timeout_ms));
return WAIT;
}
@@ -244,28 +255,17 @@
const char* apn, const char* username, const char* password,
PinName pn)
{
- DevStatus devStatus = {};
- bool mdmOk = init(simpin, &devStatus, pn);
+ bool ok = init(simpin, NULL, pn);
#ifdef MDM_DEBUG
- if (_debugLevel >= 1) dumpDevStatus(&devStatus);
+ if (_debugLevel >= 1) dumpDevStatus(&_dev);
#endif
- if (!mdmOk)
+ if (!ok)
return false;
- // wait until we are connected
- int i = 180;
- NetStatus netStatus = {};
- INFO("Modem::register\r\n");
- while (!checkNetStatus(&netStatus))
- {
- if ((netStatus.reg == REG_DENIED) || (i == 0))
- break;;
- i --;
- RELAX_MS(1000);
- }
+ ok = registerNet();
#ifdef MDM_DEBUG
- if (_debugLevel >= 1) dumpNetStatus(&netStatus);
+ if (_debugLevel >= 1) dumpNetStatus(&_net);
#endif
- if ((netStatus.reg == REG_DENIED) || (i == 0))
+ if (!ok)
return false;
IP ip = join(apn,username,password);
#ifdef MDM_DEBUG
@@ -292,9 +292,12 @@
if(RESP_OK == waitFinalResp(NULL,NULL,500))
break;
}
- if (i < 0)
+ if (i < 0) {
+ ERROR("No Reply from Modem");
return false;
+ }
}
+
INFO("Modem::init\r\n");
// echo off
sendFormated("AT E0\r\n");
@@ -363,9 +366,12 @@
if ((RESP_OK != ret) && (RESP_ERROR != ret))
return false;
// Enter PIN if needed
- if (_dev.sim == SIM_PIN) {
+ if (_dev.sim == SIM_MISSING) {
+ ERROR("SIM not inserted\r\n");
+ return false;
+ } else if (_dev.sim == SIM_PIN) {
if (!simpin) {
- INFO("SIM PIN not available\r\n");
+ ERROR("SIM PIN not available\r\n");
return false;
}
sendFormated("AT+CPIN=%s\r\n", simpin);
@@ -398,12 +404,6 @@
sendFormated("AT+CGSN\r\n");
if (RESP_OK != waitFinalResp(_cbString, _dev.imei))
return false;
-#if 0
- // Configure New message indication
- sendFormated("AT+CNMI=2,1,0,0,0\r\n");
- if (RESP_OK != waitFinalResp())
- return false;
-#endif
// enable power saving
if (_dev.lpm != LPM_DISABLED) {
// enable power saving (requires flow control, cts at least)
@@ -418,7 +418,7 @@
if (RESP_OK != waitFinalResp())
return false;
// setup new message indication
- sendFormated("AT+CNMI=1,1\r\n");
+ sendFormated("AT+CNMI=2,1\r\n");
if (RESP_OK != waitFinalResp())
return false;
// Request IMSI (International Mobile Subscriber Identification)
@@ -462,10 +462,14 @@
int MDMParser::_cbCPIN(int type, const char* buf, int len, Sim* sim)
{
- if ((type == TYPE_PLUS) && sim){
- char s[16];
- if (sscanf(buf, "\r\n+CPIN: %[^\r]\r<n", s) >= 1) {
- *sim = (strcmp("READY", s) == 0) ? SIM_READY : SIM_PIN;
+ if (sim) {
+ if (type == TYPE_PLUS){
+ char s[16];
+ if (sscanf(buf, "\r\n+CPIN: %[^\r]\r\n", s) >= 1)
+ *sim = (0 == strcmp("READY", s)) ? SIM_READY : SIM_PIN;
+ } else if (type == TYPE_ERROR) {
+ if (strstr(buf, "+CME ERROR: SIM not inserted"))
+ *sim = SIM_MISSING;
}
}
return WAIT;
@@ -480,53 +484,69 @@
return WAIT;
}
+bool MDMParser::registerNet(NetStatus* status /*= NULL*/, int timeout_ms /*= 180000*/)
+{
+ Timer timer;
+ timer.start();
+ 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);
+}
+
bool MDMParser::checkNetStatus(NetStatus* status /*= NULL*/)
{
+ memset(&_net, 0, sizeof(_net));
+ _net.lac = 0xFFFF;
+ _net.ci = 0xFFFFFFFF;
// check registration
sendFormated("AT+CREG?\r\n");
if (RESP_OK != waitFinalResp())
return false;
- if ((_net.reg != REG_ROAMING) && (_net.reg != REG_HOME))
- return false;
- // check modem specific status messages
- if (_dev.dev == DEV_LISA_C200) {
- sendFormated("AT+CSS?\r\n");
- if (RESP_OK != waitFinalResp())
- return false;
- // get the Telephone number
- sendFormated("AT$MDN?\r\n");
- if (RESP_OK != waitFinalResp(_cbString, _net.num))
- return false;
- // check if we have a Mobile Directory Number
- if (memcmp(_net.num, "0000", 4) == 0)
- return false;
- // get the the Network access identifier string
- char nai[64];
- sendFormated("AT$QCMIPNAI?\r\n");
- if (RESP_OK != waitFinalResp(_cbString, nai))
+ if ((_net.reg == REG_ROAMING) || (_net.reg == REG_HOME))
+ {
+ // check modem specific status messages
+ if (_dev.dev == DEV_LISA_C200) {
+ sendFormated("AT+CSS?\r\n");
+ if (RESP_OK != waitFinalResp())
+ return false;
+ // get the Telephone number
+ sendFormated("AT$MDN?\r\n");
+ 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))
+ return false;
+ // get the the Network access identifier string
+ char nai[64];
+ sendFormated("AT$QCMIPNAI?\r\n");
+ 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))
+ return false;
+ // Returns the MSISDNs related to this subscriber
+ sendFormated("AT+CNUM\r\n");
+ if (RESP_OK != waitFinalResp(_cbCNUM, _net.num))
+ return false;
+ }
+ // Returns the signal strength indication
+ sendFormated("AT+CSQ\r\n");
+ if (RESP_OK != waitFinalResp(_cbCSQ, &_net))
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))
- return false;
- // Returns the MSISDNs related to this subscriber
- sendFormated("AT+CNUM\r\n");
- if (RESP_OK != waitFinalResp(_cbCNUM, _net.num))
- return false;
- }
- // Returns the signal strength indication
- sendFormated("AT+CSQ\r\n");
- if (RESP_OK != waitFinalResp(_cbCSQ, &_net))
- return false;
+ }
if (status) {
memcpy(status, &_net, sizeof(NetStatus));
}
- return true;
+ 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)
@@ -636,7 +656,7 @@
// Activate the profile and make connection
sendFormated("AT+UPSDA=" PROFILE ",3\r\n");
if (RESP_OK != waitFinalResp(NULL,NULL,150*1000)) {
- INFO("Your modem APN/password/username may be wrong\r\n");
+ ERROR("Your modem APN/password/username may be wrong\r\n");
return NOIP;
}
//Get local IP address
@@ -900,18 +920,14 @@
cnt += blk;
buf += blk;
_sockets[socket].pending -= blk;
- } else if ((_sockets[socket].state == SOCK_CONNECTED) && (
- (_sockets[socket].timeout_ms == TIMEOUT_BLOCKING) ||
- (timer.read_ms() < _sockets[socket].timeout_ms))){
+ } else if ((_sockets[socket].state == SOCK_CONNECTED) &&
+ !TIMEOUT(timer, _sockets[socket].timeout_ms)) {
// allow to receive unsolicited commands
waitFinalResp(NULL, NULL, 10);
} else {
len = 0; // no more data and socket closed or timed-out
}
}
-
- timer.stop();
- timer.reset();
return cnt;
}
@@ -957,13 +973,11 @@
cnt += blk;
buf += blk;
_sockets[socket].pending -= blk;
- } else if ((_sockets[socket].timeout_ms == TIMEOUT_BLOCKING) ||
- (timer.read_ms() < _sockets[socket].timeout_ms)) {
+ } else if (!TIMEOUT(timer, _sockets[socket].timeout_ms)) {
// allow to receive unsolicited commands
waitFinalResp(NULL, NULL, 10);
- } else {
+ } else
len = 0; // no more data and socket closed or timed-out
- }
}
timer.stop();
timer.reset();
@@ -1084,14 +1098,14 @@
void MDMParser::dumpDevStatus(MDMParser::DevStatus* status,
_DPRINT dprint, void* param)
{
- dprint(param, "Modem Device Status:\r\n");
+ dprint(param, "Modem::devStatus\r\n");
const char* txtDev[] = { "Unknown", "SARA-G350", "LISA-U200", "LISA-C200" };
if (status->dev < sizeof(txtDev)/sizeof(*txtDev) && (status->dev != MDMParser::DEV_UNKNOWN))
dprint(param, " Device: %s\r\n", txtDev[status->dev]);
const char* txtLpm[] = { "Disabled", "Enabled", "Active" };
if (status->lpm < sizeof(txtLpm)/sizeof(*txtLpm))
dprint(param, " Power Save: %s\r\n", txtLpm[status->lpm]);
- const char* txtSim[] = { "Unknown", "Pin", "Ready" };
+ const char* txtSim[] = { "Unknown", "Missing", "Pin", "Ready" };
if (status->sim < sizeof(txtSim)/sizeof(*txtSim) && (status->sim != MDMParser::SIM_UNKNOWN))
dprint(param, " SIM: %s\r\n", txtSim[status->sim]);
if (*status->ccid)
@@ -1113,7 +1127,7 @@
void MDMParser::dumpNetStatus(MDMParser::NetStatus *status,
_DPRINT dprint, void* param)
{
- dprint(param, "Modem Network Status:\r\n");
+ 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]);
@@ -1141,7 +1155,7 @@
_DPRINT dprint, void* param)
{
if (ip != NOIP)
- dprint(param, "Modem IP Address: " IPSTR "\r\n", IPNUM(ip));
+ dprint(param, "Modem:IP " IPSTR "\r\n", IPNUM(ip));
}
// ----------------------------------------------------------------
