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
Diff: MDM.cpp
- Revision:
- 31:a0bed6c1e05d
- Parent:
- 30:1a647403171b
- Child:
- 32:8f12ac182bbb
--- a/MDM.cpp Tue Apr 08 15:49:04 2014 +0000 +++ b/MDM.cpp Wed Apr 09 11:48:04 2014 +0000 @@ -1,5 +1,6 @@ #include "mbed.h" #include <ctype.h> +#include <string.h> #include "MDM.h" #define TRACE (0)?:printf @@ -8,9 +9,6 @@ #define MAX_SIZE 256 // max expected messages // some helper #define ISSOCKET(s) (((s) >= 0) && ((s) < (sizeof(_sockets)/sizeof(*_sockets)))) -#define IPSTR "%d.%d.%d.%d" -#define IPNUM(addr) (addr>>24)&0xff, (addr>>16)&0xff, (addr>>8)&0xff, addr&0xff -#define IPADR(a,b,c,d) ((a<<24) | (b<<16) | (c<<8) | d) #ifdef DEBUG void dump(const char* buf, int len) @@ -23,36 +21,35 @@ else printf("\\x%02x", ch); } } -#endif + #if 1 // colored terminal output using ANSI escape sequences + #define COL(c,t) "\33[" c t "\33[" "39m" + #else + #define COL(c,t) t + #endif + #define BLA(t) COL("30m",t) + #define RED(t) COL("31m",t) + #define GRE(t) COL("32m",t) + #define YEL(t) COL("33m",t) + #define BLU(t) COL("34m",t) + #define MAG(t) COL("35m",t) + #define CYA(t) COL("36m",t) + #define WHY(t) COL("37m",t) +#endif MDMParser::MDMParser(void) { - // device info - _model = MODEL_UNKNOWN; - _sim = SIM_UNKNOWN; - *_ccid = '\0'; - *_imsi = '\0'; - *_imei = '\0'; - // network info - _net = NET_UNKNOWN; - _act = ACT_UNKNOWN; - _rssi = 0; - *_num = '\0'; - *_opr = '\0'; - // data network info - _ip = 0; - for (int socket = 0; socket < sizeof(_sockets)/sizeof(*_sockets); socket++) { - _sockets[socket].state = SOCK_FREE; - _sockets[socket].pending = 0; - } + memset(&_dev, 0, sizeof(_dev)); + memset(&_net, 0, sizeof(_net)); + _ip = NOIP; + memset(_sockets, 0, sizeof(_sockets)); } int MDMParser::send(const char* buf, int len) { #ifdef DEBUG - printf(" send \""); + printf("AT send %4d \"", len); dump(buf,len); - printf("\"\n"); + printf("\"\r\n"); #endif return _send(buf, len); } @@ -78,9 +75,17 @@ #ifdef DEBUG if ((ret != WAIT) && (ret != NOT_FOUND)) { - printf(" line %06X \"", ret); - dump(buf, LENGTH(ret)); - printf("\"\n"); + int len = LENGTH(ret); + int type = TYPE(ret); + const char* s = (type == TYPE_UNKNOWN)? YEL("UNK") : + (type == TYPE_OK ) ? GRE("OK ") : + (type == TYPE_ERROR) ? RED("ERR") : + (type == TYPE_PLUS) ? CYA(" + ") : + (type == TYPE_PROMPT) ? BLU(" > ") : + "..." ; + printf("AT read %s %3d \"", s, len); + dump(buf, len); + printf("\"\r\n"); } #endif if ((ret != WAIT) && (ret != NOT_FOUND)) @@ -92,46 +97,43 @@ // handle unsolicited commands here if (type == TYPE_PLUS) { const char* cmd = buf+3; - int a, b, c, d; + int a, b; char s[32]; - // +CSQ: <rssi>,<qual> - if (sscanf(cmd, "CSQ: %d,%d",&a,&b) == 2) { - if (a != 99) _rssi = -113 + 2*a; // 0: -113 1: -111 ... 30: -53 dBm with 2 dBm steps - //if (b != 99) int qual = b; // + // SMS Command --------------------------------- + // +CNMI: <mem>,<index> + if (sscanf(cmd, "CMTI: \"%*[^\"]\",%d", &a) == 1) { + TRACE("New SMS at index %d\r\n", a); // Socket Specific Command --------------------------------- // +UUSORD: <socket>,<length> } else if ((sscanf(cmd, "UUSORD: %d,%d", &a, &b) == 2) && ISSOCKET(a) && (_sockets[a].state == SOCK_CONNECTED)) { - TRACE("Socket %d: %d bytes pending\n", a, b); + TRACE("Socket %d: %d bytes pending\r\n", a, b); _sockets[a].pending = b; // +UUSORF: <socket>,<length> } else if ((sscanf(cmd, "UUSORF: %d,%d", &a, &b) == 2) && ISSOCKET(a) && (_sockets[a].state == SOCK_CONNECTED)) { - TRACE("Socket %d: %d bytes pending\n", a, b); + TRACE("Socket %d: %d bytes pending\r\n", a, b); _sockets[a].pending = b; // +UUSOCL: <socket> } else if ((sscanf(cmd, "UUSOCL: %d", &a) == 1) && ISSOCKET(a) && (_sockets[a].state == SOCK_CONNECTED)) { - TRACE("Socket %d: closed by remote host\n", a); + TRACE("Socket %d: closed by remote host\r\n", a); _sockets[a].state = SOCK_CREATED/*=CLOSED*/; } - if (_model == MODEL_LISA_C200) { + if (_dev.model == MODEL_LISA_C200) { // CDMA Specific ------------------------------------------- // +CREG: <n><SID>,<NID>,<stat> if (sscanf(cmd, "CREG: %*d,%*d,%*d,%d",&a) == 1) { - if (a == 0) _net = NET_NONE; // not registered, home network - else if (a == 1) _net = NET_HOME; // registered, home network - else if (a == 2) _net = NET_NONE; // not registered, but MT is currently searching a new operator to register to - else if (a == 3) _net = NET_DENIED; // registration denied - else if (a == 5) _net = NET_ROAMING; // registered, roaming - _act = ACT_CDMA; + if (a == 0) _net.reg = REG_NONE; // not registered, home network + else if (a == 1) _net.reg = REG_HOME; // registered, home network + else if (a == 2) _net.reg = REG_NONE; // not registered, but MT is currently searching a new operator to register to + else if (a == 3) _net.reg = REG_DENIED; // registration denied + else if (a == 5) _net.reg = REG_ROAMING; // registered, roaming + _net.act = ACT_CDMA; // +CSS: <mode>[,<format>,<oper>[,<AcT>]] } else if (sscanf(cmd, "CSS %*c,%2s,%*d",s) == 1) { - //_net = (strcmp("Z", s) == 0) ? NET_UNKNOWN : NET_HOME; - // +CMIP: xxx.xxx.xxx.xxx - } else if (sscanf(cmd, "CMIP: " IPSTR, &a,&b,&c,&d) == 4) { - _ip = IPADR(a,b,c,d); + //_net.reg = (strcmp("Z", s) == 0) ? REG_UNKNOWN : REG_HOME; } } else { // GSM/UMTS Specific ------------------------------------------- @@ -139,37 +141,23 @@ b = 255; if (sscanf(cmd, "CREG: %*d,%d,%*d,%d",&a,&b) >= 1) { // network status - if (a == 0) _net = NET_NONE; // 0: not registered, home network - else if (a == 1) _net = NET_HOME; // 1: registered, home network - else if (a == 2) _net = NET_NONE; // 2: not registered, but MT is currently searching a new operator to register to - else if (a == 3) _net = NET_DENIED; // 3: registration denied - else if (a == 4) _net = NET_UNKNOWN; // 4: unknown - else if (a == 5) _net = NET_ROAMING; // 5: registered, roaming + 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 // access technology - if (b == 0) _act = ACT_GSM; // 0: GSM - else if (b == 1) _act = ACT_GSM; // 1: GSM COMPACT - else if (b == 2) _act = ACT_UTRAN; // 2: UTRAN - else if (b == 3) _act = ACT_EDGE; // 3: GSM with EDGE availability - else if (b == 4) _act = ACT_UTRAN; // 4: UTRAN with HSDPA availability - else if (b == 5) _act = ACT_UTRAN; // 5: UTRAN with HSUPA availability - else if (b == 6) _act = ACT_UTRAN; // 6: UTRAN with HSDPA and HSUPA availability - // +COPS: <mode>[,<format>,<oper>[,<AcT>]] - } else if (sscanf(cmd, "COPS: %*d,%*d,\"%[^\"]\",%d",s,&b) >= 1) { - strcpy(_opr,s); - if (a == 0) _act = ACT_GSM; // 0: GSM, - else if (a == 2) _act = ACT_UTRAN; // 2: UTRAN - // +CPIN: <code> - } else if (sscanf(cmd, "CPIN: %7s",s) == 1) { - _sim = (strcmp("READY", s) == 0) ? SIM_READY : SIM_UNKNOWN; - // +CNUM: <code> - } else if (sscanf(cmd, "CNUM: \"My Number\",\"%31[^\"]\",%d", s, &a) == 2) { - if ((a == 129) || (a == 145)) strncpy(_num, s, sizeof(_num)); - // +UPSND=<profile_id>,<param_tag>[,<dynamic_param_val>] - } else if (sscanf(cmd, "UPSND: " PROFILE ",0,\"" IPSTR "\"", &a,&b,&c,&d) == 4) { - _ip = IPADR(a,b,c,d); + if (b == 0) _net.act = ACT_GSM; // 0: GSM + else if (b == 1) _net.act = ACT_GSM; // 1: GSM COMPACT + else if (b == 2) _net.act = ACT_UTRAN; // 2: UTRAN + else if (b == 3) _net.act = ACT_EDGE; // 3: GSM with EDGE availability + else if (b == 4) _net.act = ACT_UTRAN; // 4: UTRAN with HSDPA availability + else if (b == 5) _net.act = ACT_UTRAN; // 5: UTRAN with HSUPA availability + else if (b == 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 = 0; + if (*PROFILE == a) _ip = NOIP; } } } @@ -189,25 +177,26 @@ return WAIT; } -// ---------------------------------------------------------------- - -int MDMParser::_cbATI(int type, const char* buf, int len, Model* model) +int MDMParser::_cbString(int type, const char* buf, int len, char* str) { - if ((type == TYPE_UNKNOWN) && model) { - if (strstr(buf, "SARA-G350")) { - *model = MODEL_SARA_G350; - /*TRACE("Identified Model: SARA-G350 2G\n")*/; - } else if (strstr(buf, "LISA-U200")) { - *model = MODEL_LISA_U200; - /*TRACE("Identified Model: LISA-U200 2G/3G\n")*/; - } else if (strstr(buf, "LISA-C200")) { - *model= MODEL_LISA_C200; - /*TRACE("Identified Model: LISA-C200 CDMA\n")*/; - } + if (str && (type == TYPE_UNKNOWN)) { + if (sscanf(buf, "\r\n%s\r\n", str) == 1) + /*nothing*/; } return WAIT; } +int MDMParser::_cbInt(int type, const char* buf, int len, int* val) +{ + if (val && (type == TYPE_UNKNOWN)) { + if (sscanf(buf, "\r\n%d\r\n", val) == 1) + /*nothing*/; + } + return WAIT; +} + +// ---------------------------------------------------------------- + bool MDMParser::init(const char* pin, DevStatus* status) { for(int i = 0; i < 5; i++) { @@ -231,19 +220,19 @@ wait_ms(40); // identify the module sendFormated("ATI\r\n"); - if (OK != waitFinalResp(_cbATI, &_model)) + if (OK != waitFinalResp(_cbATI, &_dev.model)) return false; - if (_model == MODEL_UNKNOWN) + if (_dev.model == MODEL_UNKNOWN) return false; // model specific init - if (_model == MODEL_LISA_C200) { + if (_dev.model == MODEL_LISA_C200) { // disable flow control sendFormated("AT+IFC=0,0\r\n"); if (OK != waitFinalResp()) return false; // Return the pseudo ESN or MEID sendFormated("AT+GSN\r\n"); - if (OK != waitFinalResp(_cbGSN, _imei)) + if (OK != waitFinalResp(_cbString, _dev.imei)) return false; } else { // disable flow control @@ -255,7 +244,7 @@ if (OK != waitFinalResp()) return false; // enable the network identification feature - if (_model == MODEL_LISA_U200) { + if (_dev.model == MODEL_LISA_U200) { sendFormated("AT+UGPIOC=20,2\r\n"); if (OK != waitFinalResp()) return false; @@ -264,36 +253,34 @@ if (OK != waitFinalResp()) return false; } - // Enter PIN if needed - if (pin) { - sendFormated("AT+CPIN=%s\r\n", pin); - if (OK != waitFinalResp()) - return false; - } // check the sim card - for (int i = 0; i < 5; i++) { + for (int i = 0; (i < 5) && (_dev.sim != SIM_READY); i++) { sendFormated("AT+CPIN?\r\n"); - int ret = waitFinalResp(); + int ret = waitFinalResp(_cbCPIN, &_dev.sim); if ((OK != ret) && (ERROR != ret)) return false; - if (_sim != SIM_UNKNOWN) - break; - wait_ms(1000); + // Enter PIN if needed + if (_dev.sim == SIM_PIN) { + if (!pin) { + TRACE("SIM PIN not available\r\n"); + return false; + } + sendFormated("AT+CPIN=%s\r\n", pin); + if (OK != waitFinalResp(_cbCPIN, &_dev.sim)) + return false; + } else if (_dev.sim != SIM_READY) + wait_ms(1000); } - if (_sim != SIM_READY) + if (_dev.sim != SIM_READY) return false; // Returns the ICCID (Integrated Circuit Card ID) of the SIM-card. // ICCID is a serial number identifying the SIM. sendFormated("AT+CCID\r\n"); - if (OK != waitFinalResp(_cbCCID, _ccid)) + if (OK != waitFinalResp(_cbCCID, _dev.ccid)) return false; // Returns the product serial number, IMEI (International Mobile Equipment Identity) sendFormated("AT+CGSN\r\n"); - if (OK != waitFinalResp(_cbCGSN, _imei)) - return false; - // Setup SMS in text mode - sendFormated("AT+CMGF=1\r\n"); - if (OK != waitFinalResp()) + if (OK != waitFinalResp(_cbString, _dev.imei)) return false; // Configure New message indication //sendFormated("AT+CNMI=2,1,0,0,0\r\n"); @@ -301,53 +288,56 @@ // return false; } + // Setup SMS in text mode + sendFormated("AT+CMGF=1\r\n"); + if (OK != waitFinalResp()) + return false; + // setup new message indication + sendFormated("AT+CNMI=1,1\r\n"); + if (OK != waitFinalResp()) + return false; // Request IMSI (International Mobile Subscriber Identification) sendFormated("AT+CIMI\r\n"); - if (OK != waitFinalResp(_cbCIMI, _imsi)) + if (OK != waitFinalResp(_cbString, _dev.imsi)) return false; if (status) - { - status->model = _model; - status->sim = _sim; - status->ccid = _ccid; - status->imsi = _imsi; - status->imei = _imei; + memcpy(status, &_dev, sizeof(DevStatus)); + return true; +} + +int MDMParser::_cbATI(int type, const char* buf, int len, Model* model) +{ + if ((type == TYPE_UNKNOWN) && model) { + if (strstr(buf, "SARA-G350")) { + *model = MODEL_SARA_G350; + /*TRACE("Identified Model: SARA-G350 2G\\n")*/; + } else if (strstr(buf, "LISA-U200")) { + *model = MODEL_LISA_U200; + /*TRACE("Identified Model: LISA-U200 2G/3G\r\n")*/; + } else if (strstr(buf, "LISA-C200")) { + *model= MODEL_LISA_C200; + /*TRACE("Identified Model: LISA-C200 CDMA\r\n")*/; + } } - return true; + return WAIT; +} + +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; + } + } + return WAIT; } int MDMParser::_cbCCID(int type, const char* buf, int len, char* ccid) { if ((type == TYPE_PLUS) && ccid){ if (sscanf(buf, "\r\n+CCID: %[^\r]\r\n", ccid) == 1) - /*TRACE("Got CCID: %s\n", ccid)*/; - } - return WAIT; -} - -int MDMParser::_cbGSN(int type, const char* buf, int len, char* imei) -{ - if ((type == TYPE_UNKNOWN) && imei){ - if (sscanf(buf, "\r\n%[^\r]\r\n%*[^\r]\r\n", imei) == 1) - /*TRACE("Got IMEI: %s\n", imei)*/; - } - return WAIT; -} - -int MDMParser::_cbCGSN(int type, const char* buf, int len, char* imei) -{ - if ((type == TYPE_UNKNOWN) && imei){ - if (sscanf(buf, "\r\n%[^\r]\r\n", imei) == 1) - /*TRACE("Got IMEI: %s\n", imei)*/; - } - return WAIT; -} - -int MDMParser::_cbCIMI(int type, const char* buf, int len, char* imsi) -{ - if ((type == TYPE_UNKNOWN) && imsi) { - if (sscanf(buf, "\r\n%[^\r]\r\n", imsi) == 1) - /*TRACE("Got IMSI: %s\n", imsi)*/; + /*TRACE("Got CCID: %s\r\n", ccid)*/; } return WAIT; } @@ -358,39 +348,85 @@ sendFormated("AT+CREG?\r\n"); if (OK != waitFinalResp()) return false; - if ((_net != NET_ROAMING) && (_net != NET_HOME)) + if ((_net.reg != REG_ROAMING) && (_net.reg != REG_HOME)) return false; // check modem specific status messages - if (_model == MODEL_LISA_C200) { + if (_dev.model == MODEL_LISA_C200) { sendFormated("AT+CSS?\r\n"); if (OK != waitFinalResp()) return false; - if ((_net != NET_ROAMING) && (_net != NET_HOME)) + } else { + // check GPRS attach status + int state = 0; + sendFormated("AT+CGATT?\r\n"); + if (OK != waitFinalResp(_cbCGATT, &state)) return false; - } else { + if (state != 1) + return false; // check operator selection sendFormated("AT+COPS?\r\n"); - if (OK != waitFinalResp()) + if (OK != waitFinalResp(_cbCOPS, &_net)) return false; // Returns the MSISDNs related to this subscriber sendFormated("AT+CNUM\r\n"); - if (OK != waitFinalResp()) + if (OK != waitFinalResp(_cbCNUM, _net.num)) return false; } // Returns the signal strength indication sendFormated("AT+CSQ\r\n"); - if (OK != waitFinalResp()) + if (OK != waitFinalResp(_cbCSQ, &_net.rssi)) return false; if (status) { - status->num = _num; - status->opr = _opr; - status->rssi = _rssi; - status->net = _net; - status->act = _act; + memcpy(status, &_net, sizeof(NetStatus)); } return true; } +int MDMParser::_cbCGATT(int type, const char* buf, int len, int* state) +{ + if ((type == TYPE_PLUS) && state){ + if (sscanf(buf, "\r\n+CGATT: %d\r\n", state) == 1) + /*TRACE("Got CGATT: %d\r\n", state)*/; + } + return WAIT; +} + +int MDMParser::_cbCOPS(int type, const char* buf, int len, NetStatus* status) +{ + if ((type == TYPE_PLUS) && status){ + int act = 99; + // +COPS: <mode>[,<format>,<oper>[,<AcT>]] + if (sscanf(buf, "\r\n+COPS: %*d,%*d,\"%[^\"]\",%d",status->opr,&act) >= 1) { + if (act == 0) status->act = ACT_GSM; // 0: GSM, + else if (act == 2) status->act = ACT_UTRAN; // 2: UTRAN + } + } + return WAIT; +} + +int MDMParser::_cbCNUM(int type, const char* buf, int len, char* num) +{ + if ((type == TYPE_PLUS) && num){ + int a; + if ((sscanf(buf, "\r\n+CNUM: \"My Number\",\"%31[^\"]\",%d", num, &a) == 2) && + ((a == 129) || (a == 145))) { + } + } + return WAIT; +} + +int MDMParser::_cbCSQ(int type, const char* buf, int len, int* rssi) +{ + if ((type == TYPE_PLUS) && rssi){ + int a; + // +CSQ: <rssi>,<qual> + if (sscanf(buf, "\r\n+CSQ: %d,%*d",&a) == 1) { + if (a != 99) *rssi = -113 + 2*a; // 0: -113 1: -111 ... 30: -53 dBm with 2 dBm steps + //if (b != 99) int qual = b; // + } + } + return WAIT; +} bool MDMParser::powerOff(void) { sendFormated("AT+CPWROFF\r\n"); @@ -402,80 +438,106 @@ // ---------------------------------------------------------------- // internet connection -MDMParser::IP MDMParser::strToIp(const char* str) +MDMParser::IP MDMParser::join(const char* apn /*= NULL*/, const char* user /*= NULL*/, const char* password /*= NULL*/) { - IP ip = 0; - char* p = (char*)str; - for(int i = 0; i < 4; i++) { - ip |= atoi(p); - p = strchr(p, '.'); - if (p == NULL) { - break; - } - ip <<= 8; - p++; - } - return ip; -} - -bool MDMParser::join(const char* apn /*= NULL*/, const char* user /*= NULL*/, const char* password /*= NULL*/) -{ - if (_model == MODEL_LISA_C200) { + IP ip = NOIP; + if (_dev.model == MODEL_LISA_C200) { #ifdef TODO // TODO implement // enable the sendFormated("AT$QCMIPEP=1\r\n"); if (OK != waitFinalResp()) - return false; + return NOIP; //Get local IP address sendFormated("AT+CMIP?\r\n"); + // extract: +CMIP: xxx.xxx.xxx.xxx if (OK != waitFinalResp()) - return false; + return NOIP; + #endif } else { // check gprs attach status sendFormated("AT+CGATT?\r\n"); if (OK != waitFinalResp()) - return false; - // Set up the APN + return NOIP; + + // Check the profile + int a = 0; + sendFormated("AT+UPSND=" PROFILE ",8\r\n"); + if (OK != waitFinalResp(_cbUPSND, &a)) + return NOIP; + if (a == 1) { + // disconnect the profile already if it is connected + sendFormated("AT+UPSDA=" PROFILE ",4\r\n"); + if (OK != waitFinalResp()) + return NOIP;; + } + // Set up the APN if (apn) { sendFormated("AT+UPSD=" PROFILE ",1,\"%s\"\r\n", apn); if (OK != waitFinalResp()) - return false; + return NOIP; } if (user) { sendFormated("AT+UPSD=" PROFILE ",2,\"%s\"\r\n", user); if (OK != waitFinalResp()) - return false; + return NOIP; } if (password) { sendFormated("AT+UPSD=" PROFILE ",3,\"%s\"\r\n", password); if (OK != waitFinalResp()) - return false; + return NOIP; } // Set up the dynamic IP address assignment. sendFormated("AT+UPSD=" PROFILE ",7,\"0.0.0.0\"\r\n"); if (OK != waitFinalResp()) - return false; + return NOIP; // Activate the profile and make connection sendFormated("AT+UPSDA=" PROFILE ",3\r\n"); if (OK != waitFinalResp()) - return false; + return NOIP; //Get local IP address sendFormated("AT+UPSND=" PROFILE ",0\r\n"); - if (OK != waitFinalResp()) - return false; + if (OK != waitFinalResp(_cbUPSND, &ip)) + return NOIP; + } + return ip; +} + +int MDMParser::_cbUPSND(int type, const char* buf, int len, int* act) +{ + if ((type == TYPE_PLUS) && act) { + if (sscanf(buf, "\r\n+UPSND: %*d,%*d,%d", act) == 1) + /*nothing*/; } - if (!_ip) - return false; - TRACE("Got IP address: " IPSTR "\n", IPNUM(_ip)); - return true; + return WAIT; +} + +int MDMParser::_cbUPSND(int type, const char* buf, int len, IP* ip) +{ + if ((type == TYPE_PLUS) && ip) { + int a,b,c,d; + // +UPSND=<profile_id>,<param_tag>[,<dynamic_param_val>] + if (sscanf(buf, "\r\n+UPSND: " PROFILE ",0,\"" IPSTR "\"", &a,&b,&c,&d) == 4) + *ip = IPADR(a,b,c,d); + } + return WAIT; +} + +int MDMParser::_cbUDNSRN(int type, const char* buf, int len, IP* ip) +{ + if ((type == TYPE_PLUS) && ip) { + int a,b,c,d; + if (sscanf(buf, "\r\n+UDNSRN: \""IPSTR"\"", &a,&b,&c,&d) == 4) + *ip = IPADR(a,b,c,d); + } + return WAIT; } bool MDMParser::disconnect(void) { - if (_ip == 0) + if (_ip == NOIP) return true; - if (_model == MODEL_LISA_C200) { + if (_dev.model == MODEL_LISA_C200) { #ifdef TODO // TODO implement sendFormated("AT$QCMIPEP=0\r\n"); #endif @@ -484,35 +546,22 @@ } if (OK != waitFinalResp()) return false; - _ip = 0; + _ip = NOIP; return true; } -int MDMParser::_cbUDNSRN(int type, const char* buf, int len, IP* ip) -{ - if ((type == TYPE_PLUS) && ip) { - buf += 3; - int a,b,c,d; - if (sscanf(buf, "UDNSRN: \""IPSTR"\"", &a,&b,&c,&d) == 4) - *ip = IPADR(a,b,c,d); - } - return WAIT; -} - -bool MDMParser::gethostbyname(const char* host, IP* ip) +MDMParser::IP MDMParser::gethostbyname(const char* host) { - char ipstr[16]; - IP addr = strToIp(host); - *ip = 0; - snprintf(ipstr, sizeof(ipstr), IPSTR, IPNUM(addr)); - if (strcmp(ipstr, host) == 0) { - *ip = addr; - return true; + IP ip = NOIP; + int a,b,c,d; + if (sscanf(host, IPSTR, &a,&b,&c,&d) == 4) + ip = IPADR(a,b,c,d); + else { + sendFormated("AT+UDNSRN=0,\"%s\"\r\n", host); + if (OK != waitFinalResp(_cbUDNSRN, &ip)) + return false; } - sendFormated("AT+UDNSRN=0,\"%s\"\r\n", host); - if (OK != waitFinalResp(_cbUDNSRN, ip)) - return false; - return *ip != 0; + return ip; } // ---------------------------------------------------------------- @@ -552,8 +601,8 @@ bool MDMParser::socketConnect(int socket, const char * host, int port) { - IP ip; - if (!gethostbyname(host, &ip)) + IP ip = gethostbyname(host); + if (ip == NOIP) return false; // connect to socket if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CREATED)) @@ -715,24 +764,29 @@ } // ---------------------------------------------------------------- -int MDMParser::_cbCPMS(int type, const char* buf, int len, int* num) + +int MDMParser::_cbCMGL(int type, const char* buf, int len, CMGLparam* param) { - if ((type == TYPE_PLUS) && num) { - // AT+CPMS: <used1>,<total1>,<used2>,<total2>,<used3>,<total3>; - if (sscanf(buf, "\r\n+CPMS: %d,%*d", num) == 1) - /*nothing*/; + if ((type == TYPE_PLUS) && param && param->num) { + // +CMGL: <ix>,... + int ix; + if (sscanf(buf, "\r\n+CMGL: %d,", &ix) == 1) + { + *param->ix++ = ix; + param->num--; + } } return WAIT; } -int MDMParser::smsCount(void) -{ - int num = 0; - sendFormated("AT+CPMS=\"ME\"\r\n"); - if (OK != waitFinalResp(_cbCPMS,&num)) { - return 0; - } - return num; +int MDMParser::smsList(const char* stat /*= "ALL"*/, int* ix /*=NULL*/, int num /*= 0*/) { + sendFormated("AT+CMGL=\"%s\"\r\n", stat); + CMGLparam param; + param.ix = ix; + param.num = num; + if (OK != waitFinalResp(_cbCMGL, ¶m)) + return -1; + return num - param.num; } bool MDMParser::smsSend(const char* num, const char* buf) @@ -797,14 +851,15 @@ } return WAIT; } -int MDMParser::ussdCommand(const char* cmd, char* buf, int len) + +bool MDMParser::ussdCommand(const char* cmd, char* buf) { *buf = '\0'; sendFormated("AT+CUSD=1,\"%s\"\r\n",cmd); if (OK != waitFinalResp(_cbCUSD, buf)) { - return -1; + return false; } - return strlen(buf); + return true; } // ---------------------------------------------------------------- @@ -884,7 +939,7 @@ } lut[] = { { "\r\nOK\r\n", NULL, TYPE_OK }, { "\r\nERROR\r\n", NULL, TYPE_ERROR }, - { "\r\n+CME ERROR:", "\r\n", TYPE_ERROR }, + { "\r\n+CME ERROR:", "\r\n", TYPE_ERROR }, { "\r\n+CMS ERROR:", "\r\n", TYPE_ERROR }, { "\r\nRING\r\n", NULL, TYPE_RING }, { "\r\nCONNECT\r\n", NULL, TYPE_CONNECT }, @@ -902,7 +957,7 @@ if (ln == WAIT && fr) return WAIT; if ((ln != NOT_FOUND) && (unkn > 0)) - return pipe->get(buf, unkn); + return TYPE_UNKNOWN | pipe->get(buf, unkn); if (ln > 0) return lutF[i].type | pipe->get(buf, ln); } @@ -912,7 +967,7 @@ if (ln == WAIT && fr) return WAIT; if ((ln != NOT_FOUND) && (unkn > 0)) - return pipe->get(buf, unkn); + return TYPE_UNKNOWN | pipe->get(buf, unkn); if (ln > 0) return lut[i].type | pipe->get(buf, ln); }