support library for C027 helper functions for Buffer Pipes, Buffered Serial Port (rtos capable) and GPS parsing. It includes modem APIs for USSD, SMS and Sockets.

Dependents:   HTTPClient_Cellular_HelloWorld Cellular_HelloMQTT MbedSmartRestMain Car_Bon_car_module ... more

This library is intended to be used with u-blox products such as the C027 or a shield with u-blox cellular and GPS modules like the cellular and positioning shield from Embedded Artist.

For 2G/GSM and 3G/UMTS you need to:

  • have a SIM card and know its PIN number
  • need to know you network operators APN setting These setting should be passed to the connect or init and join functions. You can also extend the APN database in MDMAPN.h.

For CDMA products you need to make sure that you have provisioned and activated the modem with either Sprint or Verizon.

Committer:
mazgch
Date:
Thu Jun 05 15:16:57 2014 +0000
Revision:
84:a05edb010176
Parent:
82:055dcfcf9dcc
Child:
85:dd8f4f0d0ca9
added simple APN lookup table

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mazgch 18:e5697801df29 1 #include "mbed.h"
mazgch 18:e5697801df29 2 #include "MDM.h"
mazgch 74:208e3e32d263 3 #include "Relax.h"
mazgch 74:208e3e32d263 4 #ifdef TARGET_UBLOX_C027
mazgch 74:208e3e32d263 5 #include "C027_api.h"
mazgch 74:208e3e32d263 6 #endif
mazgch 18:e5697801df29 7
mazgch 84:a05edb010176 8 /* ----------------------------------------------------------------
mazgch 84:a05edb010176 9 APN stands for Access Point Name, a setting on your modem or phone
mazgch 84:a05edb010176 10 that identifies an external network your phone can access for data
mazgch 84:a05edb010176 11 (e.g., 3G or 4G Internet service on your phone).
mazgch 84:a05edb010176 12
mazgch 84:a05edb010176 13 The APN settings can be forced when calling the join function.
mazgch 84:a05edb010176 14 Below is a list of known APNs that us used if no apn config
mazgch 84:a05edb010176 15 is forced. This list could be extended by other settings.
mazgch 84:a05edb010176 16
mazgch 84:a05edb010176 17 For further reading:
mazgch 84:a05edb010176 18 wiki apn: http://en.wikipedia.org/wiki/Access_Point_Name
mazgch 84:a05edb010176 19 wiki mcc/mnc: http://en.wikipedia.org/wiki/Mobile_country_code
mazgch 84:a05edb010176 20 google: https://www.google.de/search?q=APN+list
mazgch 84:a05edb010176 21 ---------------------------------------------------------------- */
mazgch 84:a05edb010176 22 //! helper
mazgch 84:a05edb010176 23 #define _APN(a,u,p) a "\0" u "\0" p "\0"
mazgch 84:a05edb010176 24 //! default APN settings used by many networks
mazgch 84:a05edb010176 25 static const char* apndef = _APN("internet",,);
mazgch 84:a05edb010176 26 //! this is a list of special APNs for different network operators
mazgch 84:a05edb010176 27 static const struct { const char* mccmnc; const char* cfg; } apnlut[] = {
mazgch 84:a05edb010176 28 // Germany
mazgch 84:a05edb010176 29 { /*T-Mobile*/ "26201", _APN("internet.t-mobile","t-mobile","tm") },
mazgch 84:a05edb010176 30 // Switzerland
mazgch 84:a05edb010176 31 { /*Swisscom*/ "22801", _APN("gprs.swisscom.ch",,) },
mazgch 84:a05edb010176 32 // USA
mazgch 84:a05edb010176 33 { /*T-Mobile*/ "310026|310260|310490",
mazgch 84:a05edb010176 34 _APN("epc.tmobile.com",,)
mazgch 84:a05edb010176 35 _APN("fast.tmobile.com",,) /*LTE*/ },
mazgch 84:a05edb010176 36 { /*AT&T*/ "310030|310150|310170|310260|310410|310560|310680",
mazgch 84:a05edb010176 37 _APN("phone",,)
mazgch 84:a05edb010176 38 _APN("wap.cingular","WAP@CINGULARGPRS.COM","CINGULAR1")
mazgch 84:a05edb010176 39 _APN("isp.cingular","ISP@CINGULARGPRS.COM","CINGULAR1") },
mazgch 84:a05edb010176 40 // ...
mazgch 84:a05edb010176 41 };
mazgch 84:a05edb010176 42 // ----------------------------------------------------------------
mazgch 84:a05edb010176 43
mazgch 74:208e3e32d263 44 #define PROFILE "0" //!< this is the psd profile used
mazgch 74:208e3e32d263 45 #define MAX_SIZE 128 //!< max expected messages
mazgch 74:208e3e32d263 46 //! test if it is a socket
mazgch 21:c4d64830bf02 47 #define ISSOCKET(s) (((s) >= 0) && ((s) < (sizeof(_sockets)/sizeof(*_sockets))))
mazgch 75:ce6e12067d0c 48 //! check for timeout
mazgch 75:ce6e12067d0c 49 #define TIMEOUT(t, ms) ((ms != TIMEOUT_BLOCKING) && (ms < t.read_ms()))
mazgch 80:34985b4d821e 50 //! registration ok check helper
mazgch 79:291df065e345 51 #define REG_OK(r) ((r == REG_HOME) || (r == REG_ROAMING))
mazgch 80:34985b4d821e 52 //! registration done check helper (no need to poll further)
mazgch 79:291df065e345 53 #define REG_DONE(r) ((r == REG_HOME) || (r == REG_ROAMING) || (r == REG_DENIED))
mazgch 79:291df065e345 54
mazgch 74:208e3e32d263 55 #ifdef MDM_DEBUG
mazgch 74:208e3e32d263 56 void dumpAtCmd(const char* buf, int len)
mazgch 21:c4d64830bf02 57 {
mazgch 75:ce6e12067d0c 58 ::printf(" %3d \"", len);
mazgch 21:c4d64830bf02 59 while (len --) {
mazgch 21:c4d64830bf02 60 char ch = *buf++;
mazgch 75:ce6e12067d0c 61 if ((ch > 0x1F) && (ch != 0x7F)) { // is printable
mazgch 75:ce6e12067d0c 62 if (ch == '%') ::printf("%%");
mazgch 75:ce6e12067d0c 63 else if (ch == '"') ::printf("\\\"");
mazgch 75:ce6e12067d0c 64 else if (ch == '\\') ::printf("\\\\");
mazgch 75:ce6e12067d0c 65 else putchar(ch);
mazgch 75:ce6e12067d0c 66 } else {
mazgch 75:ce6e12067d0c 67 if (ch == '\a') ::printf("\\a"); // BEL (0x07)
mazgch 75:ce6e12067d0c 68 else if (ch == '\b') ::printf("\\b"); // Backspace (0x08)
mazgch 75:ce6e12067d0c 69 else if (ch == '\t') ::printf("\\t"); // Horizontal Tab (0x09)
mazgch 75:ce6e12067d0c 70 else if (ch == '\n') ::printf("\\n"); // Linefeed (0x0A)
mazgch 75:ce6e12067d0c 71 else if (ch == '\v') ::printf("\\v"); // Vertical Tab (0x0B)
mazgch 75:ce6e12067d0c 72 else if (ch == '\f') ::printf("\\f"); // Formfeed (0x0C)
mazgch 75:ce6e12067d0c 73 else if (ch == '\r') ::printf("\\r"); // Carriage Return (0x0D)
mazgch 76:f7c3dd568dae 74 else ::printf("\\x%02x", (unsigned char)ch);
mazgch 75:ce6e12067d0c 75 }
mazgch 21:c4d64830bf02 76 }
mazgch 75:ce6e12067d0c 77 ::printf("\"\r\n");
mazgch 21:c4d64830bf02 78 }
mazgch 74:208e3e32d263 79
mazgch 75:ce6e12067d0c 80 #define ERROR(fmt) (_debugLevel < 0) ? : ::printf(RED(fmt))
mazgch 75:ce6e12067d0c 81 #define INFO(fmt) (_debugLevel < 1) ? : ::printf(GRE(fmt))
mazgch 75:ce6e12067d0c 82 #define TRACE(...) (_debugLevel < 2) ? : ::printf(__VA_ARGS__)
mazgch 74:208e3e32d263 83
mazgch 31:a0bed6c1e05d 84 #if 1 // colored terminal output using ANSI escape sequences
mazgch 75:ce6e12067d0c 85 #define COL(c,t) "\033[" c t "\033[" "39m"
mazgch 31:a0bed6c1e05d 86 #else
mazgch 31:a0bed6c1e05d 87 #define COL(c,t) t
mazgch 31:a0bed6c1e05d 88 #endif
mazgch 31:a0bed6c1e05d 89 #define BLA(t) COL("30m",t)
mazgch 31:a0bed6c1e05d 90 #define RED(t) COL("31m",t)
mazgch 31:a0bed6c1e05d 91 #define GRE(t) COL("32m",t)
mazgch 31:a0bed6c1e05d 92 #define YEL(t) COL("33m",t)
mazgch 31:a0bed6c1e05d 93 #define BLU(t) COL("34m",t)
mazgch 31:a0bed6c1e05d 94 #define MAG(t) COL("35m",t)
mazgch 31:a0bed6c1e05d 95 #define CYA(t) COL("36m",t)
mazgch 31:a0bed6c1e05d 96 #define WHY(t) COL("37m",t)
mazgch 74:208e3e32d263 97
mazgch 74:208e3e32d263 98 #else
mazgch 74:208e3e32d263 99
mazgch 75:ce6e12067d0c 100 #define ERROR(...) (void)0 // no tracing
mazgch 74:208e3e32d263 101 #define INFO(...) (void)0 // no tracing
mazgch 74:208e3e32d263 102 #define TRACE(...) (void)0 // no tracing
mazgch 74:208e3e32d263 103
mazgch 31:a0bed6c1e05d 104 #endif
mazgch 21:c4d64830bf02 105
mazgch 44:9d12223b78ff 106 MDMParser* MDMParser::inst;
mazgch 44:9d12223b78ff 107
mazgch 21:c4d64830bf02 108 MDMParser::MDMParser(void)
mazgch 21:c4d64830bf02 109 {
mazgch 44:9d12223b78ff 110 inst = this;
mazgch 31:a0bed6c1e05d 111 memset(&_dev, 0, sizeof(_dev));
mazgch 31:a0bed6c1e05d 112 memset(&_net, 0, sizeof(_net));
mazgch 54:7ba8e4c218e2 113 _net.lac = 0xFFFF;
mazgch 54:7ba8e4c218e2 114 _net.ci = 0xFFFFFFFF;
mazgch 35:9275215a3a5b 115 _ip = NOIP;
mazgch 76:f7c3dd568dae 116 _init = false;
mazgch 31:a0bed6c1e05d 117 memset(_sockets, 0, sizeof(_sockets));
mazgch 74:208e3e32d263 118 #ifdef MDM_DEBUG
mazgch 76:f7c3dd568dae 119 _debugLevel = 1;
mazgch 74:208e3e32d263 120 _debugTime.start();
mazgch 74:208e3e32d263 121 #endif
mazgch 74:208e3e32d263 122 }
mazgch 74:208e3e32d263 123
mazgch 18:e5697801df29 124 int MDMParser::send(const char* buf, int len)
mazgch 18:e5697801df29 125 {
mazgch 74:208e3e32d263 126 #ifdef MDM_DEBUG
mazgch 74:208e3e32d263 127 if (_debugLevel >= 3) {
mazgch 75:ce6e12067d0c 128 ::printf("%10.3f AT send ", _debugTime.read_ms()*0.001);
mazgch 74:208e3e32d263 129 dumpAtCmd(buf,len);
mazgch 74:208e3e32d263 130 }
mazgch 21:c4d64830bf02 131 #endif
mazgch 18:e5697801df29 132 return _send(buf, len);
mazgch 18:e5697801df29 133 }
mazgch 18:e5697801df29 134
mazgch 21:c4d64830bf02 135 int MDMParser::sendFormated(const char* format, ...) {
mazgch 21:c4d64830bf02 136 char buf[MAX_SIZE];
mazgch 21:c4d64830bf02 137 va_list args;
mazgch 21:c4d64830bf02 138 va_start(args, format);
mazgch 21:c4d64830bf02 139 int len = vsnprintf(buf,sizeof(buf), format, args);
mazgch 21:c4d64830bf02 140 va_end(args);
mazgch 21:c4d64830bf02 141 return send(buf, len);
mazgch 21:c4d64830bf02 142 }
mazgch 21:c4d64830bf02 143
mazgch 26:07be5faf8925 144 int MDMParser::waitFinalResp(_CALLBACKPTR cb /* = NULL*/,
mazgch 26:07be5faf8925 145 void* param /* = NULL*/,
mazgch 26:07be5faf8925 146 int timeout_ms /*= 5000*/)
mazgch 26:07be5faf8925 147 {
mazgch 69:4d6fa520dfca 148 char buf[MAX_SIZE + 64 /* add some more space for framing */];
mazgch 21:c4d64830bf02 149 Timer timer;
mazgch 21:c4d64830bf02 150 timer.start();
mazgch 21:c4d64830bf02 151 do {
mazgch 21:c4d64830bf02 152 int ret = getLine(buf, sizeof(buf));
mazgch 74:208e3e32d263 153 #ifdef MDM_DEBUG
mazgch 74:208e3e32d263 154 if ((_debugLevel >= 3) && (ret != WAIT) && (ret != NOT_FOUND))
mazgch 21:c4d64830bf02 155 {
mazgch 31:a0bed6c1e05d 156 int len = LENGTH(ret);
mazgch 31:a0bed6c1e05d 157 int type = TYPE(ret);
mazgch 31:a0bed6c1e05d 158 const char* s = (type == TYPE_UNKNOWN)? YEL("UNK") :
mazgch 35:9275215a3a5b 159 (type == TYPE_TEXT) ? MAG("TXT") :
mazgch 53:cb0d94b9de3a 160 (type == TYPE_OK ) ? GRE("OK ") :
mazgch 31:a0bed6c1e05d 161 (type == TYPE_ERROR) ? RED("ERR") :
mazgch 31:a0bed6c1e05d 162 (type == TYPE_PLUS) ? CYA(" + ") :
mazgch 31:a0bed6c1e05d 163 (type == TYPE_PROMPT) ? BLU(" > ") :
mazgch 31:a0bed6c1e05d 164 "..." ;
mazgch 75:ce6e12067d0c 165 ::printf("%10.3f AT read %s", _debugTime.read_ms()*0.001, s);
mazgch 74:208e3e32d263 166 dumpAtCmd(buf, len);
mazgch 21:c4d64830bf02 167 }
mazgch 21:c4d64830bf02 168 #endif
mazgch 21:c4d64830bf02 169 if ((ret != WAIT) && (ret != NOT_FOUND))
mazgch 18:e5697801df29 170 {
mazgch 21:c4d64830bf02 171 int type = TYPE(ret);
mazgch 21:c4d64830bf02 172 // handle unsolicited commands here
mazgch 21:c4d64830bf02 173 if (type == TYPE_PLUS) {
mazgch 21:c4d64830bf02 174 const char* cmd = buf+3;
mazgch 54:7ba8e4c218e2 175 int a, b, c, d, r;
mazgch 23:05a1aeeb5fd9 176 char s[32];
mazgch 21:c4d64830bf02 177
mazgch 31:a0bed6c1e05d 178 // SMS Command ---------------------------------
mazgch 31:a0bed6c1e05d 179 // +CNMI: <mem>,<index>
mazgch 31:a0bed6c1e05d 180 if (sscanf(cmd, "CMTI: \"%*[^\"]\",%d", &a) == 1) {
mazgch 31:a0bed6c1e05d 181 TRACE("New SMS at index %d\r\n", a);
mazgch 21:c4d64830bf02 182 // Socket Specific Command ---------------------------------
mazgch 21:c4d64830bf02 183 // +UUSORD: <socket>,<length>
mazgch 21:c4d64830bf02 184 } else if ((sscanf(cmd, "UUSORD: %d,%d", &a, &b) == 2) &&
mazgch 63:42cb563a25bc 185 ISSOCKET(a) /*&& (_sockets[a].state == SOCK_CONNECTED)*/) {
mazgch 31:a0bed6c1e05d 186 TRACE("Socket %d: %d bytes pending\r\n", a, b);
mazgch 21:c4d64830bf02 187 _sockets[a].pending = b;
mazgch 69:4d6fa520dfca 188 // +UUSORF: <socket>,<length>
mazgch 69:4d6fa520dfca 189 } else if ((sscanf(cmd, "UUSORF: %d,%d", &a, &b) == 2) &&
mazgch 69:4d6fa520dfca 190 ISSOCKET(a) /*&& (_sockets[a].state == SOCK_CONNECTED)*/) {
mazgch 69:4d6fa520dfca 191 TRACE("Socket %d: %d bytes pending\r\n", a, b);
mazgch 69:4d6fa520dfca 192 _sockets[a].pending = b;
mazgch 21:c4d64830bf02 193 // +UUSOCL: <socket>
mazgch 21:c4d64830bf02 194 } else if ((sscanf(cmd, "UUSOCL: %d", &a) == 1) &&
mazgch 21:c4d64830bf02 195 ISSOCKET(a) && (_sockets[a].state == SOCK_CONNECTED)) {
mazgch 31:a0bed6c1e05d 196 TRACE("Socket %d: closed by remote host\r\n", a);
mazgch 21:c4d64830bf02 197 _sockets[a].state = SOCK_CREATED/*=CLOSED*/;
mazgch 21:c4d64830bf02 198 }
mazgch 32:8f12ac182bbb 199 if (_dev.dev == DEV_LISA_C200) {
mazgch 21:c4d64830bf02 200 // CDMA Specific -------------------------------------------
mazgch 21:c4d64830bf02 201 // +CREG: <n><SID>,<NID>,<stat>
mazgch 54:7ba8e4c218e2 202 if (sscanf(cmd, "CREG: %*d,%d,%d,%d",&a,&b,&c) == 3) {
mazgch 54:7ba8e4c218e2 203 // _net.sid = a;
mazgch 54:7ba8e4c218e2 204 // _net.nid = b;
mazgch 79:291df065e345 205 if (c == 0) _net.csd = REG_NONE; // not registered, home network
mazgch 79:291df065e345 206 else if (c == 1) _net.csd = REG_HOME; // registered, home network
mazgch 79:291df065e345 207 else if (c == 2) _net.csd = REG_NONE; // not registered, but MT is currently searching a new operator to register to
mazgch 79:291df065e345 208 else if (c == 3) _net.csd = REG_DENIED; // registration denied
mazgch 79:291df065e345 209 else if (c == 5) _net.csd = REG_ROAMING; // registered, roaming
mazgch 79:291df065e345 210 _net.psd = _net.csd; // fake PSD registration (CDMA is always registered)
mazgch 31:a0bed6c1e05d 211 _net.act = ACT_CDMA;
mazgch 84:a05edb010176 212 // +CSS: <mode>[,<format>,<oper>[,<AcT>]]
mazgch 21:c4d64830bf02 213 } else if (sscanf(cmd, "CSS %*c,%2s,%*d",s) == 1) {
mazgch 31:a0bed6c1e05d 214 //_net.reg = (strcmp("Z", s) == 0) ? REG_UNKNOWN : REG_HOME;
mazgch 21:c4d64830bf02 215 }
mazgch 21:c4d64830bf02 216 } else {
mazgch 21:c4d64830bf02 217 // GSM/UMTS Specific -------------------------------------------
mazgch 79:291df065e345 218 // +UUPSDD: <profile_id>
mazgch 79:291df065e345 219 if (sscanf(cmd, "UUPSDD: %d",&a) == 1) {
mazgch 79:291df065e345 220 if (*PROFILE == a) _ip = NOIP;
mazgch 79:291df065e345 221 } else {
mazgch 79:291df065e345 222 // +CREG|CGREG: <n>,<stat>[,<lac>,<ci>[,AcT[,<rac>]]] // reply to AT+CREG|AT+CGREG
mazgch 79:291df065e345 223 // +CREG|CGREG: <stat>[,<lac>,<ci>[,AcT[,<rac>]]] // URC
mazgch 79:291df065e345 224 b = 0xFFFF; c = 0xFFFFFFFF; d = -1;
mazgch 79:291df065e345 225 r = sscanf(cmd, "%s %*d,%d,\"%X\",\"%X\",%d",s,&a,&b,&c,&d);
mazgch 79:291df065e345 226 if (r <= 1)
mazgch 79:291df065e345 227 r = sscanf(cmd, "%s %d,\"%X\",\"%X\",%d",s,&a,&b,&c,&d);
mazgch 79:291df065e345 228 if (r >= 2) {
mazgch 79:291df065e345 229 Reg *reg = !strcmp(s, "CREG:") ? &_net.csd :
mazgch 79:291df065e345 230 !strcmp(s, "CGREG:") ? &_net.psd : NULL;
mazgch 79:291df065e345 231 if (reg) {
mazgch 79:291df065e345 232 // network status
mazgch 79:291df065e345 233 if (a == 0) *reg = REG_NONE; // 0: not registered, home network
mazgch 79:291df065e345 234 else if (a == 1) *reg = REG_HOME; // 1: registered, home network
mazgch 79:291df065e345 235 else if (a == 2) *reg = REG_NONE; // 2: not registered, but MT is currently searching a new operator to register to
mazgch 79:291df065e345 236 else if (a == 3) *reg = REG_DENIED; // 3: registration denied
mazgch 79:291df065e345 237 else if (a == 4) *reg = REG_UNKNOWN; // 4: unknown
mazgch 79:291df065e345 238 else if (a == 5) *reg = REG_ROAMING; // 5: registered, roaming
mazgch 79:291df065e345 239 if ((r >= 3) && (b != 0xFFFF)) _net.lac = b; // location area code
mazgch 79:291df065e345 240 if ((r >= 4) && (c != 0xFFFFFFFF)) _net.ci = c; // cell ID
mazgch 79:291df065e345 241 // access technology
mazgch 79:291df065e345 242 if (r >= 5) {
mazgch 79:291df065e345 243 if (d == 0) _net.act = ACT_GSM; // 0: GSM
mazgch 79:291df065e345 244 else if (d == 1) _net.act = ACT_GSM; // 1: GSM COMPACT
mazgch 79:291df065e345 245 else if (d == 2) _net.act = ACT_UTRAN; // 2: UTRAN
mazgch 79:291df065e345 246 else if (d == 3) _net.act = ACT_EDGE; // 3: GSM with EDGE availability
mazgch 79:291df065e345 247 else if (d == 4) _net.act = ACT_UTRAN; // 4: UTRAN with HSDPA availability
mazgch 79:291df065e345 248 else if (d == 5) _net.act = ACT_UTRAN; // 5: UTRAN with HSUPA availability
mazgch 79:291df065e345 249 else if (d == 6) _net.act = ACT_UTRAN; // 6: UTRAN with HSDPA and HSUPA availability
mazgch 79:291df065e345 250 }
mazgch 79:291df065e345 251 }
mazgch 54:7ba8e4c218e2 252 }
mazgch 21:c4d64830bf02 253 }
mazgch 21:c4d64830bf02 254 }
mazgch 21:c4d64830bf02 255 }
mazgch 21:c4d64830bf02 256 if (cb) {
mazgch 21:c4d64830bf02 257 int len = LENGTH(ret);
mazgch 21:c4d64830bf02 258 int ret = cb(type, buf, len, param);
mazgch 21:c4d64830bf02 259 if (WAIT != ret)
mazgch 21:c4d64830bf02 260 return ret;
mazgch 21:c4d64830bf02 261 }
mazgch 75:ce6e12067d0c 262 if (type == TYPE_OK) return RESP_OK;
mazgch 75:ce6e12067d0c 263 if (type == TYPE_ERROR) return RESP_ERROR;
mazgch 75:ce6e12067d0c 264 if (type == TYPE_PROMPT) return RESP_PROMPT;
mazgch 21:c4d64830bf02 265 }
mazgch 21:c4d64830bf02 266 // relax a bit
mazgch 74:208e3e32d263 267 RELAX_MS(10);
mazgch 21:c4d64830bf02 268 }
mazgch 75:ce6e12067d0c 269 while (!TIMEOUT(timer, timeout_ms));
mazgch 21:c4d64830bf02 270 return WAIT;
mazgch 21:c4d64830bf02 271 }
mazgch 21:c4d64830bf02 272
mazgch 31:a0bed6c1e05d 273 int MDMParser::_cbString(int type, const char* buf, int len, char* str)
mazgch 21:c4d64830bf02 274 {
mazgch 37:cc3433329d66 275 if (str && (type == TYPE_UNKNOWN)) {
mazgch 31:a0bed6c1e05d 276 if (sscanf(buf, "\r\n%s\r\n", str) == 1)
mazgch 31:a0bed6c1e05d 277 /*nothing*/;
mazgch 21:c4d64830bf02 278 }
mazgch 21:c4d64830bf02 279 return WAIT;
mazgch 21:c4d64830bf02 280 }
mazgch 21:c4d64830bf02 281
mazgch 31:a0bed6c1e05d 282 int MDMParser::_cbInt(int type, const char* buf, int len, int* val)
mazgch 31:a0bed6c1e05d 283 {
mazgch 37:cc3433329d66 284 if (val && (type == TYPE_UNKNOWN)) {
mazgch 31:a0bed6c1e05d 285 if (sscanf(buf, "\r\n%d\r\n", val) == 1)
mazgch 31:a0bed6c1e05d 286 /*nothing*/;
mazgch 31:a0bed6c1e05d 287 }
mazgch 31:a0bed6c1e05d 288 return WAIT;
mazgch 31:a0bed6c1e05d 289 }
mazgch 31:a0bed6c1e05d 290
mazgch 31:a0bed6c1e05d 291 // ----------------------------------------------------------------
mazgch 31:a0bed6c1e05d 292
mazgch 57:869bd35f44cc 293 bool MDMParser::connect(
mazgch 57:869bd35f44cc 294 const char* simpin,
mazgch 80:34985b4d821e 295 const char* apn, const char* username,
mazgch 80:34985b4d821e 296 const char* password, Auth auth,
mazgch 74:208e3e32d263 297 PinName pn)
mazgch 57:869bd35f44cc 298 {
mazgch 75:ce6e12067d0c 299 bool ok = init(simpin, NULL, pn);
mazgch 74:208e3e32d263 300 #ifdef MDM_DEBUG
mazgch 75:ce6e12067d0c 301 if (_debugLevel >= 1) dumpDevStatus(&_dev);
mazgch 74:208e3e32d263 302 #endif
mazgch 75:ce6e12067d0c 303 if (!ok)
mazgch 57:869bd35f44cc 304 return false;
mazgch 75:ce6e12067d0c 305 ok = registerNet();
mazgch 74:208e3e32d263 306 #ifdef MDM_DEBUG
mazgch 75:ce6e12067d0c 307 if (_debugLevel >= 1) dumpNetStatus(&_net);
mazgch 74:208e3e32d263 308 #endif
mazgch 75:ce6e12067d0c 309 if (!ok)
mazgch 57:869bd35f44cc 310 return false;
mazgch 80:34985b4d821e 311 IP ip = join(apn,username,password,auth);
mazgch 74:208e3e32d263 312 #ifdef MDM_DEBUG
mazgch 74:208e3e32d263 313 if (_debugLevel >= 1) dumpIp(ip);
mazgch 74:208e3e32d263 314 #endif
mazgch 57:869bd35f44cc 315 if (ip == NOIP)
mazgch 57:869bd35f44cc 316 return false;
mazgch 57:869bd35f44cc 317 return true;
mazgch 57:869bd35f44cc 318 }
mazgch 57:869bd35f44cc 319
mazgch 74:208e3e32d263 320 bool MDMParser::init(const char* simpin, DevStatus* status, PinName pn)
mazgch 21:c4d64830bf02 321 {
mazgch 74:208e3e32d263 322 int i = 10;
mazgch 76:f7c3dd568dae 323 memset(&_dev, 0, sizeof(_dev));
mazgch 74:208e3e32d263 324 if (pn != NC) {
mazgch 74:208e3e32d263 325 INFO("Modem::wakeup\r\n");
mazgch 74:208e3e32d263 326 DigitalOut pin(pn, 1);
mazgch 74:208e3e32d263 327 while (i--) {
mazgch 79:291df065e345 328 // SARA-U2/LISA-U2 50..80us
mazgch 79:291df065e345 329 pin = 0; wait_us(50);
mazgch 79:291df065e345 330 pin = 1; wait_ms(10);
mazgch 79:291df065e345 331
mazgch 79:291df065e345 332 // SARA-G35 >5ms, LISA-C2 > 150ms
mazgch 79:291df065e345 333 pin = 0; wait_ms(150);
mazgch 79:291df065e345 334 pin = 1; wait_ms(100);
mazgch 79:291df065e345 335
mazgch 79:291df065e345 336 // purge any messages
mazgch 79:291df065e345 337 while (WAIT != waitFinalResp(NULL,NULL,0))
mazgch 79:291df065e345 338 /* nothing */;
mazgch 74:208e3e32d263 339 // check interface and disable local echo
mazgch 74:208e3e32d263 340 sendFormated("AT\r\n");
mazgch 74:208e3e32d263 341 if(RESP_OK == waitFinalResp(NULL,NULL,500))
mazgch 74:208e3e32d263 342 break;
mazgch 74:208e3e32d263 343 }
mazgch 75:ce6e12067d0c 344 if (i < 0) {
mazgch 75:ce6e12067d0c 345 ERROR("No Reply from Modem");
mazgch 74:208e3e32d263 346 return false;
mazgch 75:ce6e12067d0c 347 }
mazgch 21:c4d64830bf02 348 }
mazgch 76:f7c3dd568dae 349 _init = true;
mazgch 75:ce6e12067d0c 350
mazgch 74:208e3e32d263 351 INFO("Modem::init\r\n");
mazgch 21:c4d64830bf02 352 // echo off
mazgch 21:c4d64830bf02 353 sendFormated("AT E0\r\n");
mazgch 52:8071747a7cb3 354 if(RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 355 return false;
mazgch 21:c4d64830bf02 356 // enable verbose error messages
mazgch 21:c4d64830bf02 357 sendFormated("AT+CMEE=2\r\n");
mazgch 52:8071747a7cb3 358 if(RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 359 return false;
mazgch 21:c4d64830bf02 360 // set baud rate
mazgch 21:c4d64830bf02 361 sendFormated("AT+IPR=115200\r\n");
mazgch 52:8071747a7cb3 362 if (RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 363 return false;
mazgch 74:208e3e32d263 364 RELAX_MS(40);
mazgch 21:c4d64830bf02 365 // identify the module
mazgch 21:c4d64830bf02 366 sendFormated("ATI\r\n");
mazgch 52:8071747a7cb3 367 if (RESP_OK != waitFinalResp(_cbATI, &_dev.dev))
mazgch 21:c4d64830bf02 368 return false;
mazgch 32:8f12ac182bbb 369 if (_dev.dev == DEV_UNKNOWN)
mazgch 21:c4d64830bf02 370 return false;
mazgch 32:8f12ac182bbb 371 // device specific init
mazgch 32:8f12ac182bbb 372 if (_dev.dev == DEV_LISA_C200) {
mazgch 32:8f12ac182bbb 373 // get the manufacturer
mazgch 32:8f12ac182bbb 374 sendFormated("AT+GMI\r\n");
mazgch 52:8071747a7cb3 375 if (RESP_OK != waitFinalResp(_cbString, _dev.manu))
mazgch 32:8f12ac182bbb 376 return false;
mazgch 32:8f12ac182bbb 377 // get the model identification
mazgch 32:8f12ac182bbb 378 sendFormated("AT+GMM\r\n");
mazgch 52:8071747a7cb3 379 if (RESP_OK != waitFinalResp(_cbString, _dev.model))
mazgch 32:8f12ac182bbb 380 return false;
mazgch 32:8f12ac182bbb 381 // get the sw version
mazgch 32:8f12ac182bbb 382 sendFormated("AT+GMR\r\n");
mazgch 52:8071747a7cb3 383 if (RESP_OK != waitFinalResp(_cbString, _dev.ver))
mazgch 32:8f12ac182bbb 384 return false;
mazgch 21:c4d64830bf02 385 // Return the pseudo ESN or MEID
mazgch 21:c4d64830bf02 386 sendFormated("AT+GSN\r\n");
mazgch 52:8071747a7cb3 387 if (RESP_OK != waitFinalResp(_cbString, _dev.meid))
mazgch 26:07be5faf8925 388 return false;
mazgch 50:d76aece8038f 389 #if 0
mazgch 50:d76aece8038f 390 // enable power saving
mazgch 50:d76aece8038f 391 if (_dev.lpm != LPM_DISABLED) {
mazgch 50:d76aece8038f 392 // enable power saving (requires flow control, cts at least)
mazgch 50:d76aece8038f 393 sendFormated("AT+UPSV=1,1280\r\n");
mazgch 52:8071747a7cb3 394 if (RESP_OK != waitFinalResp())
mazgch 50:d76aece8038f 395 return false;
mazgch 50:d76aece8038f 396 _dev.lpm = LPM_ACTIVE;
mazgch 50:d76aece8038f 397 }
mazgch 50:d76aece8038f 398 #endif
mazgch 26:07be5faf8925 399 } else {
mazgch 32:8f12ac182bbb 400 if (_dev.dev == DEV_LISA_U200) {
mazgch 35:9275215a3a5b 401 // enable the network identification feature
mazgch 21:c4d64830bf02 402 sendFormated("AT+UGPIOC=20,2\r\n");
mazgch 52:8071747a7cb3 403 if (RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 404 return false;
mazgch 21:c4d64830bf02 405 } else {
mazgch 35:9275215a3a5b 406 // enable the network identification feature
mazgch 21:c4d64830bf02 407 sendFormated("AT+UGPIOC=16,2\r\n");
mazgch 52:8071747a7cb3 408 if (RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 409 return false;
mazgch 21:c4d64830bf02 410 }
mazgch 21:c4d64830bf02 411 // check the sim card
mazgch 31:a0bed6c1e05d 412 for (int i = 0; (i < 5) && (_dev.sim != SIM_READY); i++) {
mazgch 21:c4d64830bf02 413 sendFormated("AT+CPIN?\r\n");
mazgch 31:a0bed6c1e05d 414 int ret = waitFinalResp(_cbCPIN, &_dev.sim);
mazgch 62:a02f026bdd7c 415 // having an error here is ok (sim may still be initializing)
mazgch 52:8071747a7cb3 416 if ((RESP_OK != ret) && (RESP_ERROR != ret))
mazgch 21:c4d64830bf02 417 return false;
mazgch 31:a0bed6c1e05d 418 // Enter PIN if needed
mazgch 77:55788e619858 419 if (_dev.sim == SIM_PIN) {
mazgch 57:869bd35f44cc 420 if (!simpin) {
mazgch 75:ce6e12067d0c 421 ERROR("SIM PIN not available\r\n");
mazgch 31:a0bed6c1e05d 422 return false;
mazgch 31:a0bed6c1e05d 423 }
mazgch 57:869bd35f44cc 424 sendFormated("AT+CPIN=%s\r\n", simpin);
mazgch 52:8071747a7cb3 425 if (RESP_OK != waitFinalResp(_cbCPIN, &_dev.sim))
mazgch 31:a0bed6c1e05d 426 return false;
mazgch 62:a02f026bdd7c 427 } else if (_dev.sim != SIM_READY) {
mazgch 74:208e3e32d263 428 RELAX_MS(1000);
mazgch 62:a02f026bdd7c 429 }
mazgch 21:c4d64830bf02 430 }
mazgch 77:55788e619858 431 if (_dev.sim != SIM_READY) {
mazgch 77:55788e619858 432 if (_dev.sim == SIM_MISSING)
mazgch 77:55788e619858 433 ERROR("SIM not inserted\r\n");
mazgch 21:c4d64830bf02 434 return false;
mazgch 77:55788e619858 435 }
mazgch 32:8f12ac182bbb 436 // get the manufacturer
mazgch 32:8f12ac182bbb 437 sendFormated("AT+CGMI\r\n");
mazgch 52:8071747a7cb3 438 if (RESP_OK != waitFinalResp(_cbString, _dev.manu))
mazgch 32:8f12ac182bbb 439 return false;
mazgch 32:8f12ac182bbb 440 // get the model identification
mazgch 32:8f12ac182bbb 441 sendFormated("AT+CGMM\r\n");
mazgch 52:8071747a7cb3 442 if (RESP_OK != waitFinalResp(_cbString, _dev.model))
mazgch 32:8f12ac182bbb 443 return false;
mazgch 32:8f12ac182bbb 444 // get the
mazgch 32:8f12ac182bbb 445 sendFormated("AT+CGMR\r\n");
mazgch 52:8071747a7cb3 446 if (RESP_OK != waitFinalResp(_cbString, _dev.ver))
mazgch 32:8f12ac182bbb 447 return false;
mazgch 21:c4d64830bf02 448 // Returns the ICCID (Integrated Circuit Card ID) of the SIM-card.
mazgch 21:c4d64830bf02 449 // ICCID is a serial number identifying the SIM.
mazgch 21:c4d64830bf02 450 sendFormated("AT+CCID\r\n");
mazgch 52:8071747a7cb3 451 if (RESP_OK != waitFinalResp(_cbCCID, _dev.ccid))
mazgch 21:c4d64830bf02 452 return false;
mazgch 21:c4d64830bf02 453 // Returns the product serial number, IMEI (International Mobile Equipment Identity)
mazgch 21:c4d64830bf02 454 sendFormated("AT+CGSN\r\n");
mazgch 52:8071747a7cb3 455 if (RESP_OK != waitFinalResp(_cbString, _dev.imei))
mazgch 21:c4d64830bf02 456 return false;
mazgch 50:d76aece8038f 457 // enable power saving
mazgch 50:d76aece8038f 458 if (_dev.lpm != LPM_DISABLED) {
mazgch 50:d76aece8038f 459 // enable power saving (requires flow control, cts at least)
mazgch 50:d76aece8038f 460 sendFormated("AT+UPSV=1\r\n");
mazgch 52:8071747a7cb3 461 if (RESP_OK != waitFinalResp())
mazgch 50:d76aece8038f 462 return false;
mazgch 50:d76aece8038f 463 _dev.lpm = LPM_ACTIVE;
mazgch 50:d76aece8038f 464 }
mazgch 79:291df065e345 465 // enable the psd registration unsolicited result code
mazgch 79:291df065e345 466 sendFormated("AT+CGREG=2\r\n");
mazgch 79:291df065e345 467 if (RESP_OK != waitFinalResp())
mazgch 79:291df065e345 468 return false;
mazgch 84:a05edb010176 469 // set operator selection
mazgch 84:a05edb010176 470 sendFormated("AT+COPS=0,0\r\n");
mazgch 84:a05edb010176 471 if (RESP_OK != waitFinalResp(NULL,NULL,180*1000))
mazgch 84:a05edb010176 472 return false;
mazgch 21:c4d64830bf02 473 }
mazgch 79:291df065e345 474 // enable the network registration unsolicited result code
mazgch 79:291df065e345 475 sendFormated("AT+CREG=%d\r\n", (_dev.dev == DEV_LISA_C200) ? 1 : 2);
mazgch 79:291df065e345 476 if (RESP_OK != waitFinalResp())
mazgch 79:291df065e345 477 return false;
mazgch 31:a0bed6c1e05d 478 // Setup SMS in text mode
mazgch 31:a0bed6c1e05d 479 sendFormated("AT+CMGF=1\r\n");
mazgch 52:8071747a7cb3 480 if (RESP_OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 481 return false;
mazgch 31:a0bed6c1e05d 482 // setup new message indication
mazgch 75:ce6e12067d0c 483 sendFormated("AT+CNMI=2,1\r\n");
mazgch 52:8071747a7cb3 484 if (RESP_OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 485 return false;
mazgch 21:c4d64830bf02 486 // Request IMSI (International Mobile Subscriber Identification)
mazgch 21:c4d64830bf02 487 sendFormated("AT+CIMI\r\n");
mazgch 52:8071747a7cb3 488 if (RESP_OK != waitFinalResp(_cbString, _dev.imsi))
mazgch 21:c4d64830bf02 489 return false;
mazgch 28:4d9509e3b1cf 490 if (status)
mazgch 31:a0bed6c1e05d 491 memcpy(status, &_dev, sizeof(DevStatus));
mazgch 31:a0bed6c1e05d 492 return true;
mazgch 31:a0bed6c1e05d 493 }
mazgch 31:a0bed6c1e05d 494
mazgch 74:208e3e32d263 495 bool MDMParser::powerOff(void)
mazgch 74:208e3e32d263 496 {
mazgch 76:f7c3dd568dae 497 if (_init) {
mazgch 76:f7c3dd568dae 498 INFO("Modem::powerOff\r\n");
mazgch 76:f7c3dd568dae 499 sendFormated("AT+CPWROFF\r\n");
mazgch 76:f7c3dd568dae 500 if (RESP_OK != waitFinalResp(NULL,NULL,120*1000))
mazgch 76:f7c3dd568dae 501 return false;
mazgch 76:f7c3dd568dae 502 _init = false;
mazgch 76:f7c3dd568dae 503 }
mazgch 74:208e3e32d263 504 return true;
mazgch 74:208e3e32d263 505 }
mazgch 74:208e3e32d263 506
mazgch 32:8f12ac182bbb 507 int MDMParser::_cbATI(int type, const char* buf, int len, Dev* dev)
mazgch 31:a0bed6c1e05d 508 {
mazgch 37:cc3433329d66 509 if ((type == TYPE_UNKNOWN) && dev) {
mazgch 31:a0bed6c1e05d 510 if (strstr(buf, "SARA-G350")) {
mazgch 32:8f12ac182bbb 511 *dev = DEV_SARA_G350;
mazgch 32:8f12ac182bbb 512 /*TRACE("Identified Device: SARA-G350 2G\\n")*/;
mazgch 31:a0bed6c1e05d 513 } else if (strstr(buf, "LISA-U200")) {
mazgch 32:8f12ac182bbb 514 *dev = DEV_LISA_U200;
mazgch 32:8f12ac182bbb 515 /*TRACE("Identified Device: LISA-U200 2G/3G\r\n")*/;
mazgch 31:a0bed6c1e05d 516 } else if (strstr(buf, "LISA-C200")) {
mazgch 32:8f12ac182bbb 517 *dev= DEV_LISA_C200;
mazgch 32:8f12ac182bbb 518 /*TRACE("Identified Device: LISA-C200 CDMA\r\n")*/;
mazgch 31:a0bed6c1e05d 519 }
mazgch 28:4d9509e3b1cf 520 }
mazgch 31:a0bed6c1e05d 521 return WAIT;
mazgch 31:a0bed6c1e05d 522 }
mazgch 31:a0bed6c1e05d 523
mazgch 31:a0bed6c1e05d 524 int MDMParser::_cbCPIN(int type, const char* buf, int len, Sim* sim)
mazgch 31:a0bed6c1e05d 525 {
mazgch 75:ce6e12067d0c 526 if (sim) {
mazgch 75:ce6e12067d0c 527 if (type == TYPE_PLUS){
mazgch 75:ce6e12067d0c 528 char s[16];
mazgch 75:ce6e12067d0c 529 if (sscanf(buf, "\r\n+CPIN: %[^\r]\r\n", s) >= 1)
mazgch 75:ce6e12067d0c 530 *sim = (0 == strcmp("READY", s)) ? SIM_READY : SIM_PIN;
mazgch 75:ce6e12067d0c 531 } else if (type == TYPE_ERROR) {
mazgch 75:ce6e12067d0c 532 if (strstr(buf, "+CME ERROR: SIM not inserted"))
mazgch 75:ce6e12067d0c 533 *sim = SIM_MISSING;
mazgch 31:a0bed6c1e05d 534 }
mazgch 31:a0bed6c1e05d 535 }
mazgch 31:a0bed6c1e05d 536 return WAIT;
mazgch 21:c4d64830bf02 537 }
mazgch 21:c4d64830bf02 538
mazgch 26:07be5faf8925 539 int MDMParser::_cbCCID(int type, const char* buf, int len, char* ccid)
mazgch 26:07be5faf8925 540 {
mazgch 26:07be5faf8925 541 if ((type == TYPE_PLUS) && ccid){
mazgch 26:07be5faf8925 542 if (sscanf(buf, "\r\n+CCID: %[^\r]\r\n", ccid) == 1)
mazgch 31:a0bed6c1e05d 543 /*TRACE("Got CCID: %s\r\n", ccid)*/;
mazgch 26:07be5faf8925 544 }
mazgch 26:07be5faf8925 545 return WAIT;
mazgch 26:07be5faf8925 546 }
mazgch 26:07be5faf8925 547
mazgch 75:ce6e12067d0c 548 bool MDMParser::registerNet(NetStatus* status /*= NULL*/, int timeout_ms /*= 180000*/)
mazgch 75:ce6e12067d0c 549 {
mazgch 75:ce6e12067d0c 550 Timer timer;
mazgch 75:ce6e12067d0c 551 timer.start();
mazgch 75:ce6e12067d0c 552 INFO("Modem::register\r\n");
mazgch 75:ce6e12067d0c 553 while (!checkNetStatus(status) && !TIMEOUT(timer, timeout_ms))
mazgch 75:ce6e12067d0c 554 RELAX_MS(1000);
mazgch 79:291df065e345 555 if (_net.csd == REG_DENIED) ERROR("CSD Registration Denied\r\n");
mazgch 79:291df065e345 556 if (_net.psd == REG_DENIED) ERROR("PSD Registration Denied\r\n");
mazgch 79:291df065e345 557 return REG_OK(_net.csd) || REG_OK(_net.psd);
mazgch 75:ce6e12067d0c 558 }
mazgch 75:ce6e12067d0c 559
mazgch 28:4d9509e3b1cf 560 bool MDMParser::checkNetStatus(NetStatus* status /*= NULL*/)
mazgch 21:c4d64830bf02 561 {
mazgch 75:ce6e12067d0c 562 memset(&_net, 0, sizeof(_net));
mazgch 75:ce6e12067d0c 563 _net.lac = 0xFFFF;
mazgch 75:ce6e12067d0c 564 _net.ci = 0xFFFFFFFF;
mazgch 21:c4d64830bf02 565 // check registration
mazgch 21:c4d64830bf02 566 sendFormated("AT+CREG?\r\n");
mazgch 52:8071747a7cb3 567 if (RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 568 return false;
mazgch 79:291df065e345 569 if (_dev.dev != DEV_LISA_C200) {
mazgch 79:291df065e345 570 // check PSD registration
mazgch 79:291df065e345 571 sendFormated("AT+CGREG?\r\n");
mazgch 79:291df065e345 572 if (RESP_OK != waitFinalResp())
mazgch 79:291df065e345 573 return false;
mazgch 79:291df065e345 574 }
mazgch 79:291df065e345 575 if (REG_OK(_net.csd) || REG_OK(_net.psd))
mazgch 75:ce6e12067d0c 576 {
mazgch 75:ce6e12067d0c 577 // check modem specific status messages
mazgch 75:ce6e12067d0c 578 if (_dev.dev == DEV_LISA_C200) {
mazgch 75:ce6e12067d0c 579 sendFormated("AT+CSS?\r\n");
mazgch 75:ce6e12067d0c 580 if (RESP_OK != waitFinalResp())
mazgch 75:ce6e12067d0c 581 return false;
mazgch 81:3966a5c17037 582 while (1) {
mazgch 81:3966a5c17037 583 // get the Telephone number
mazgch 81:3966a5c17037 584 sendFormated("AT$MDN?\r\n");
mazgch 81:3966a5c17037 585 if (RESP_OK != waitFinalResp(_cbString, _net.num))
mazgch 81:3966a5c17037 586 return false;
mazgch 81:3966a5c17037 587 // check if we have a Mobile Directory Number
mazgch 81:3966a5c17037 588 if (*_net.num && (memcmp(_net.num, "000000", 6) != 0))
mazgch 81:3966a5c17037 589 break;
mazgch 81:3966a5c17037 590
mazgch 81:3966a5c17037 591 INFO("Device not yet activated\r\n");
mazgch 81:3966a5c17037 592 INFO("Make sure you have a valid contract with the network operator for this device.\r\n");
mazgch 81:3966a5c17037 593 // Check if the the version contains a V for Verizon
mazgch 81:3966a5c17037 594 // Verizon: E0.V.xx.00.xxR,
mazgch 81:3966a5c17037 595 // Sprint E0.S.xx.00.xxR
mazgch 81:3966a5c17037 596 if (_dev.ver[3] == 'V') {
mazgch 81:3966a5c17037 597 int i;
mazgch 81:3966a5c17037 598 INFO("Start device over-the-air activation (this can take a few minutes)\r\n");
mazgch 81:3966a5c17037 599 sendFormated("AT+CDV=*22899\r\n");
mazgch 81:3966a5c17037 600 i = 1;
mazgch 82:055dcfcf9dcc 601 if ((RESP_OK != waitFinalResp(_cbUACTIND, &i, 120*1000)) || (i == 1)) {
mazgch 81:3966a5c17037 602 ERROR("Device over-the-air activation failed\r\n");
mazgch 81:3966a5c17037 603 return false;
mazgch 81:3966a5c17037 604 }
mazgch 81:3966a5c17037 605 INFO("Device over-the-air activation successful\r\n");
mazgch 81:3966a5c17037 606
mazgch 81:3966a5c17037 607 INFO("Start PRL over-the-air update (this can take a few minutes)\r\n");
mazgch 81:3966a5c17037 608 sendFormated("AT+CDV=*22891\r\n");
mazgch 81:3966a5c17037 609 i = 1;
mazgch 82:055dcfcf9dcc 610 if ((RESP_OK != waitFinalResp(_cbUACTIND, &i, 120*1000)) || (i == 1)) {
mazgch 81:3966a5c17037 611 ERROR("PRL over-the-air update failed\r\n");
mazgch 81:3966a5c17037 612 return false;
mazgch 81:3966a5c17037 613 }
mazgch 81:3966a5c17037 614 INFO("PRL over-the-air update successful\r\n");
mazgch 81:3966a5c17037 615
mazgch 81:3966a5c17037 616 } else {
mazgch 81:3966a5c17037 617 // Sprint or Aeris
mazgch 81:3966a5c17037 618 INFO("Wait for OMA-DM over-the-air activation (this can take a few minutes)\r\n");
mazgch 81:3966a5c17037 619 RELAX_MS(120*1000);
mazgch 81:3966a5c17037 620 }
mazgch 81:3966a5c17037 621 }
mazgch 75:ce6e12067d0c 622 // get the the Network access identifier string
mazgch 75:ce6e12067d0c 623 char nai[64];
mazgch 75:ce6e12067d0c 624 sendFormated("AT$QCMIPNAI?\r\n");
mazgch 75:ce6e12067d0c 625 if (RESP_OK != waitFinalResp(_cbString, nai))
mazgch 75:ce6e12067d0c 626 return false;
mazgch 75:ce6e12067d0c 627 } else {
mazgch 75:ce6e12067d0c 628 sendFormated("AT+COPS?\r\n");
mazgch 75:ce6e12067d0c 629 if (RESP_OK != waitFinalResp(_cbCOPS, &_net))
mazgch 75:ce6e12067d0c 630 return false;
mazgch 75:ce6e12067d0c 631 // Returns the MSISDNs related to this subscriber
mazgch 75:ce6e12067d0c 632 sendFormated("AT+CNUM\r\n");
mazgch 75:ce6e12067d0c 633 if (RESP_OK != waitFinalResp(_cbCNUM, _net.num))
mazgch 75:ce6e12067d0c 634 return false;
mazgch 75:ce6e12067d0c 635 }
mazgch 75:ce6e12067d0c 636 // Returns the signal strength indication
mazgch 75:ce6e12067d0c 637 sendFormated("AT+CSQ\r\n");
mazgch 75:ce6e12067d0c 638 if (RESP_OK != waitFinalResp(_cbCSQ, &_net))
mazgch 32:8f12ac182bbb 639 return false;
mazgch 75:ce6e12067d0c 640 }
mazgch 28:4d9509e3b1cf 641 if (status) {
mazgch 31:a0bed6c1e05d 642 memcpy(status, &_net, sizeof(NetStatus));
mazgch 25:4045d02e44f1 643 }
mazgch 79:291df065e345 644 return REG_DONE(_net.csd) && REG_DONE(_net.psd);
mazgch 31:a0bed6c1e05d 645 }
mazgch 31:a0bed6c1e05d 646
mazgch 31:a0bed6c1e05d 647 int MDMParser::_cbCOPS(int type, const char* buf, int len, NetStatus* status)
mazgch 31:a0bed6c1e05d 648 {
mazgch 31:a0bed6c1e05d 649 if ((type == TYPE_PLUS) && status){
mazgch 31:a0bed6c1e05d 650 int act = 99;
mazgch 31:a0bed6c1e05d 651 // +COPS: <mode>[,<format>,<oper>[,<AcT>]]
mazgch 31:a0bed6c1e05d 652 if (sscanf(buf, "\r\n+COPS: %*d,%*d,\"%[^\"]\",%d",status->opr,&act) >= 1) {
mazgch 31:a0bed6c1e05d 653 if (act == 0) status->act = ACT_GSM; // 0: GSM,
mazgch 31:a0bed6c1e05d 654 else if (act == 2) status->act = ACT_UTRAN; // 2: UTRAN
mazgch 31:a0bed6c1e05d 655 }
mazgch 31:a0bed6c1e05d 656 }
mazgch 31:a0bed6c1e05d 657 return WAIT;
mazgch 31:a0bed6c1e05d 658 }
mazgch 31:a0bed6c1e05d 659
mazgch 31:a0bed6c1e05d 660 int MDMParser::_cbCNUM(int type, const char* buf, int len, char* num)
mazgch 31:a0bed6c1e05d 661 {
mazgch 31:a0bed6c1e05d 662 if ((type == TYPE_PLUS) && num){
mazgch 31:a0bed6c1e05d 663 int a;
mazgch 31:a0bed6c1e05d 664 if ((sscanf(buf, "\r\n+CNUM: \"My Number\",\"%31[^\"]\",%d", num, &a) == 2) &&
mazgch 31:a0bed6c1e05d 665 ((a == 129) || (a == 145))) {
mazgch 31:a0bed6c1e05d 666 }
mazgch 31:a0bed6c1e05d 667 }
mazgch 31:a0bed6c1e05d 668 return WAIT;
mazgch 31:a0bed6c1e05d 669 }
mazgch 31:a0bed6c1e05d 670
mazgch 54:7ba8e4c218e2 671 int MDMParser::_cbCSQ(int type, const char* buf, int len, NetStatus* status)
mazgch 31:a0bed6c1e05d 672 {
mazgch 54:7ba8e4c218e2 673 if ((type == TYPE_PLUS) && status){
mazgch 54:7ba8e4c218e2 674 int a,b;
mazgch 54:7ba8e4c218e2 675 char _ber[] = { 49, 43, 37, 25, 19, 13, 7, 0 }; // see 3GPP TS 45.008 [20] subclause 8.2.4
mazgch 31:a0bed6c1e05d 676 // +CSQ: <rssi>,<qual>
mazgch 54:7ba8e4c218e2 677 if (sscanf(buf, "\r\n+CSQ: %d,%d",&a,&b) == 2) {
mazgch 54:7ba8e4c218e2 678 if (a != 99) status->rssi = -113 + 2*a; // 0: -113 1: -111 ... 30: -53 dBm with 2 dBm steps
mazgch 54:7ba8e4c218e2 679 if ((b != 99) && (b < sizeof(_ber))) status->ber = _ber[b]; //
mazgch 31:a0bed6c1e05d 680 }
mazgch 31:a0bed6c1e05d 681 }
mazgch 31:a0bed6c1e05d 682 return WAIT;
mazgch 31:a0bed6c1e05d 683 }
mazgch 21:c4d64830bf02 684
mazgch 81:3966a5c17037 685 int MDMParser::_cbUACTIND(int type, const char* buf, int len, int* i)
mazgch 81:3966a5c17037 686 {
mazgch 81:3966a5c17037 687 if ((type == TYPE_PLUS) && i){
mazgch 82:055dcfcf9dcc 688 int a;
mazgch 82:055dcfcf9dcc 689 if (sscanf(buf, "\r\n+UACTIND: %d", &a) == 1) {
mazgch 82:055dcfcf9dcc 690 *i = a;
mazgch 81:3966a5c17037 691 }
mazgch 81:3966a5c17037 692 }
mazgch 81:3966a5c17037 693 return WAIT;
mazgch 81:3966a5c17037 694 }
mazgch 81:3966a5c17037 695
mazgch 21:c4d64830bf02 696 // ----------------------------------------------------------------
mazgch 21:c4d64830bf02 697 // internet connection
mazgch 21:c4d64830bf02 698
mazgch 79:291df065e345 699 MDMParser::IP MDMParser::join(const char* apn /*= NULL*/, const char* username /*= NULL*/,
mazgch 79:291df065e345 700 const char* password /*= NULL*/, Auth auth /*= AUTH_DETECT*/)
mazgch 21:c4d64830bf02 701 {
mazgch 78:caf0014375cb 702 INFO("Modem::join\r\n");
mazgch 32:8f12ac182bbb 703 _ip = NOIP;
mazgch 32:8f12ac182bbb 704 if (_dev.dev == DEV_LISA_C200) {
mazgch 76:f7c3dd568dae 705 // make a dumy dns lookup (which will fail, so ignore the result)
mazgch 76:f7c3dd568dae 706 sendFormated("AT+UDNSRN=0,\"u-blox.com\"\r\n");
mazgch 76:f7c3dd568dae 707 waitFinalResp();
mazgch 76:f7c3dd568dae 708 // This fake lookup will enable the IP connection and we
mazgch 76:f7c3dd568dae 709 // should have an IP after this, so we check it
mazgch 76:f7c3dd568dae 710
mazgch 21:c4d64830bf02 711 //Get local IP address
mazgch 21:c4d64830bf02 712 sendFormated("AT+CMIP?\r\n");
mazgch 52:8071747a7cb3 713 if (RESP_OK != waitFinalResp(_cbCMIP, &_ip))
mazgch 31:a0bed6c1e05d 714 return NOIP;
mazgch 21:c4d64830bf02 715 } else {
mazgch 21:c4d64830bf02 716 // check gprs attach status
mazgch 72:d1e943ad6558 717 sendFormated("AT+CGATT=1\r\n");
mazgch 74:208e3e32d263 718 if (RESP_OK != waitFinalResp(NULL,NULL,3*60*1000))
mazgch 31:a0bed6c1e05d 719 return NOIP;
mazgch 31:a0bed6c1e05d 720
mazgch 31:a0bed6c1e05d 721 // Check the profile
mazgch 31:a0bed6c1e05d 722 int a = 0;
mazgch 79:291df065e345 723 bool force = true;
mazgch 31:a0bed6c1e05d 724 sendFormated("AT+UPSND=" PROFILE ",8\r\n");
mazgch 52:8071747a7cb3 725 if (RESP_OK != waitFinalResp(_cbUPSND, &a))
mazgch 31:a0bed6c1e05d 726 return NOIP;
mazgch 79:291df065e345 727 if (a == 1 && force) {
mazgch 31:a0bed6c1e05d 728 // disconnect the profile already if it is connected
mazgch 31:a0bed6c1e05d 729 sendFormated("AT+UPSDA=" PROFILE ",4\r\n");
mazgch 58:e38a2e942fbb 730 if (RESP_OK != waitFinalResp(NULL,NULL,40*1000))
mazgch 84:a05edb010176 731 return NOIP;
mazgch 79:291df065e345 732 a = 0;
mazgch 31:a0bed6c1e05d 733 }
mazgch 79:291df065e345 734 if (a == 0) {
mazgch 84:a05edb010176 735 bool ok = false;
mazgch 84:a05edb010176 736 // try to lookup the apn settings from our local database by mccmnc
mazgch 84:a05edb010176 737 const char* config = NULL;
mazgch 84:a05edb010176 738 if (!apn && !username && !password) {
mazgch 84:a05edb010176 739 char mccmnc[8] = "";
mazgch 84:a05edb010176 740 config = apndef;
mazgch 84:a05edb010176 741 sendFormated("AT+UDOPN=0\r\n");
mazgch 84:a05edb010176 742 if ((RESP_OK == waitFinalResp(_cbUDOPN, mccmnc)) && *mccmnc) {
mazgch 84:a05edb010176 743 // many carriers use internet without username and password, os use this as default
mazgch 84:a05edb010176 744 // now try to lookup the setting for our table
mazgch 84:a05edb010176 745 for (int i = 0; i < sizeof(apnlut)/sizeof(*apnlut); i ++) {
mazgch 84:a05edb010176 746 if (strstr(apnlut[i].mccmnc, mccmnc)) {
mazgch 84:a05edb010176 747 config = apnlut[i].cfg;
mazgch 84:a05edb010176 748 break;
mazgch 84:a05edb010176 749 }
mazgch 84:a05edb010176 750 }
mazgch 84:a05edb010176 751 }
mazgch 79:291df065e345 752 }
mazgch 84:a05edb010176 753
mazgch 79:291df065e345 754 // Set up the dynamic IP address assignment.
mazgch 79:291df065e345 755 sendFormated("AT+UPSD=" PROFILE ",7,\"0.0.0.0\"\r\n");
mazgch 52:8071747a7cb3 756 if (RESP_OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 757 return NOIP;
mazgch 84:a05edb010176 758
mazgch 84:a05edb010176 759 do {
mazgch 84:a05edb010176 760 if (config) {
mazgch 84:a05edb010176 761 apn = *config ? config : "";
mazgch 84:a05edb010176 762 config += strlen(config)+1;
mazgch 84:a05edb010176 763 username = *config ? config : "";
mazgch 84:a05edb010176 764 config += strlen(config)+1;
mazgch 84:a05edb010176 765 password = *config ? config : "";
mazgch 84:a05edb010176 766 config += strlen(config)+1;
mazgch 84:a05edb010176 767 if (!*config) config = NULL;
mazgch 84:a05edb010176 768 TRACE("Testing APN Settings(\"%s\",\"%s\",\"%s\")\r\n", apn, username, password);
mazgch 79:291df065e345 769 }
mazgch 84:a05edb010176 770 // Set up the APN
mazgch 84:a05edb010176 771 sendFormated("AT+UPSD=" PROFILE ",1,\"%s\"\r\n", apn?apn:"");
mazgch 84:a05edb010176 772 if (RESP_OK != waitFinalResp())
mazgch 84:a05edb010176 773 return NOIP;
mazgch 84:a05edb010176 774 sendFormated("AT+UPSD=" PROFILE ",2,\"%s\"\r\n", username?username:"");
mazgch 84:a05edb010176 775 if (RESP_OK != waitFinalResp())
mazgch 84:a05edb010176 776 return NOIP;
mazgch 84:a05edb010176 777 sendFormated("AT+UPSD=" PROFILE ",3,\"%s\"\r\n", password?password:"");
mazgch 84:a05edb010176 778 if (RESP_OK != waitFinalResp())
mazgch 84:a05edb010176 779 return NOIP;
mazgch 84:a05edb010176 780 // try different Authentication Protocols
mazgch 84:a05edb010176 781 // 0 = none
mazgch 84:a05edb010176 782 // 1 = PAP (Password Authentication Protocol)
mazgch 84:a05edb010176 783 // 2 = CHAP (Challenge Handshake Authentication Protocol)
mazgch 84:a05edb010176 784 for (int i = AUTH_NONE; i <= AUTH_CHAP && !ok; i ++) {
mazgch 84:a05edb010176 785 if ((auth == AUTH_DETECT) || (auth == i)) {
mazgch 84:a05edb010176 786 // Set up the Authentication Protocol
mazgch 84:a05edb010176 787 sendFormated("AT+UPSD=" PROFILE ",6,%d\r\n", i);
mazgch 84:a05edb010176 788 if (RESP_OK != waitFinalResp())
mazgch 84:a05edb010176 789 return NOIP;
mazgch 84:a05edb010176 790 // Activate the profile and make connection
mazgch 84:a05edb010176 791 sendFormated("AT+UPSDA=" PROFILE ",3\r\n");
mazgch 84:a05edb010176 792 if (RESP_OK == waitFinalResp(NULL,NULL,150*1000))
mazgch 84:a05edb010176 793 ok = true;
mazgch 84:a05edb010176 794 }
mazgch 84:a05edb010176 795 }
mazgch 84:a05edb010176 796 } while (config); // maybe use next setting ?
mazgch 84:a05edb010176 797 if (!ok) {
mazgch 79:291df065e345 798 ERROR("Your modem APN/password/username may be wrong\r\n");
mazgch 31:a0bed6c1e05d 799 return NOIP;
mazgch 79:291df065e345 800 }
mazgch 74:208e3e32d263 801 }
mazgch 21:c4d64830bf02 802 //Get local IP address
mazgch 21:c4d64830bf02 803 sendFormated("AT+UPSND=" PROFILE ",0\r\n");
mazgch 52:8071747a7cb3 804 if (RESP_OK != waitFinalResp(_cbUPSND, &_ip))
mazgch 31:a0bed6c1e05d 805 return NOIP;
mazgch 31:a0bed6c1e05d 806 }
mazgch 32:8f12ac182bbb 807 return _ip;
mazgch 31:a0bed6c1e05d 808 }
mazgch 31:a0bed6c1e05d 809
mazgch 84:a05edb010176 810 int MDMParser::_cbUDOPN(int type, const char* buf, int len, char* mccmnc)
mazgch 84:a05edb010176 811 {
mazgch 84:a05edb010176 812 if ((type == TYPE_PLUS) && mccmnc) {
mazgch 84:a05edb010176 813 if (sscanf(buf, "\r\n+UDOPN: 0,\"%[^\"]\"", mccmnc) == 1)
mazgch 84:a05edb010176 814 ;
mazgch 84:a05edb010176 815 }
mazgch 84:a05edb010176 816 return WAIT;
mazgch 84:a05edb010176 817 }
mazgch 84:a05edb010176 818
mazgch 32:8f12ac182bbb 819 int MDMParser::_cbCMIP(int type, const char* buf, int len, IP* ip)
mazgch 32:8f12ac182bbb 820 {
mazgch 32:8f12ac182bbb 821 if ((type == TYPE_PLUS) && ip) {
mazgch 32:8f12ac182bbb 822 int a,b,c,d;
mazgch 32:8f12ac182bbb 823 if (sscanf(buf, "\r\n+CMIP: " IPSTR, &a,&b,&c,&d) == 4)
mazgch 32:8f12ac182bbb 824 *ip = IPADR(a,b,c,d);
mazgch 32:8f12ac182bbb 825 }
mazgch 32:8f12ac182bbb 826 return WAIT;
mazgch 32:8f12ac182bbb 827 }
mazgch 32:8f12ac182bbb 828
mazgch 31:a0bed6c1e05d 829 int MDMParser::_cbUPSND(int type, const char* buf, int len, int* act)
mazgch 31:a0bed6c1e05d 830 {
mazgch 31:a0bed6c1e05d 831 if ((type == TYPE_PLUS) && act) {
mazgch 31:a0bed6c1e05d 832 if (sscanf(buf, "\r\n+UPSND: %*d,%*d,%d", act) == 1)
mazgch 31:a0bed6c1e05d 833 /*nothing*/;
mazgch 21:c4d64830bf02 834 }
mazgch 31:a0bed6c1e05d 835 return WAIT;
mazgch 31:a0bed6c1e05d 836 }
mazgch 31:a0bed6c1e05d 837
mazgch 31:a0bed6c1e05d 838 int MDMParser::_cbUPSND(int type, const char* buf, int len, IP* ip)
mazgch 31:a0bed6c1e05d 839 {
mazgch 31:a0bed6c1e05d 840 if ((type == TYPE_PLUS) && ip) {
mazgch 31:a0bed6c1e05d 841 int a,b,c,d;
mazgch 31:a0bed6c1e05d 842 // +UPSND=<profile_id>,<param_tag>[,<dynamic_param_val>]
mazgch 31:a0bed6c1e05d 843 if (sscanf(buf, "\r\n+UPSND: " PROFILE ",0,\"" IPSTR "\"", &a,&b,&c,&d) == 4)
mazgch 31:a0bed6c1e05d 844 *ip = IPADR(a,b,c,d);
mazgch 31:a0bed6c1e05d 845 }
mazgch 31:a0bed6c1e05d 846 return WAIT;
mazgch 31:a0bed6c1e05d 847 }
mazgch 31:a0bed6c1e05d 848
mazgch 31:a0bed6c1e05d 849 int MDMParser::_cbUDNSRN(int type, const char* buf, int len, IP* ip)
mazgch 31:a0bed6c1e05d 850 {
mazgch 31:a0bed6c1e05d 851 if ((type == TYPE_PLUS) && ip) {
mazgch 31:a0bed6c1e05d 852 int a,b,c,d;
mazgch 31:a0bed6c1e05d 853 if (sscanf(buf, "\r\n+UDNSRN: \""IPSTR"\"", &a,&b,&c,&d) == 4)
mazgch 31:a0bed6c1e05d 854 *ip = IPADR(a,b,c,d);
mazgch 31:a0bed6c1e05d 855 }
mazgch 31:a0bed6c1e05d 856 return WAIT;
mazgch 21:c4d64830bf02 857 }
mazgch 21:c4d64830bf02 858
mazgch 21:c4d64830bf02 859 bool MDMParser::disconnect(void)
mazgch 21:c4d64830bf02 860 {
mazgch 31:a0bed6c1e05d 861 if (_ip == NOIP)
mazgch 21:c4d64830bf02 862 return true;
mazgch 74:208e3e32d263 863 INFO("Modem::disconnect\r\n");
mazgch 32:8f12ac182bbb 864 if (_dev.dev == DEV_LISA_C200) {
mazgch 76:f7c3dd568dae 865 // There something to do here
mazgch 21:c4d64830bf02 866 } else {
mazgch 21:c4d64830bf02 867 sendFormated("AT+UPSDA=" PROFILE ",4\r\n");
mazgch 52:8071747a7cb3 868 if (RESP_OK != waitFinalResp())
mazgch 32:8f12ac182bbb 869 return false;
mazgch 21:c4d64830bf02 870 }
mazgch 31:a0bed6c1e05d 871 _ip = NOIP;
mazgch 21:c4d64830bf02 872 return true;
mazgch 21:c4d64830bf02 873 }
mazgch 21:c4d64830bf02 874
mazgch 31:a0bed6c1e05d 875 MDMParser::IP MDMParser::gethostbyname(const char* host)
mazgch 21:c4d64830bf02 876 {
mazgch 31:a0bed6c1e05d 877 IP ip = NOIP;
mazgch 31:a0bed6c1e05d 878 int a,b,c,d;
mazgch 31:a0bed6c1e05d 879 if (sscanf(host, IPSTR, &a,&b,&c,&d) == 4)
mazgch 31:a0bed6c1e05d 880 ip = IPADR(a,b,c,d);
mazgch 31:a0bed6c1e05d 881 else {
mazgch 31:a0bed6c1e05d 882 sendFormated("AT+UDNSRN=0,\"%s\"\r\n", host);
mazgch 52:8071747a7cb3 883 if (RESP_OK != waitFinalResp(_cbUDNSRN, &ip))
mazgch 31:a0bed6c1e05d 884 return false;
mazgch 21:c4d64830bf02 885 }
mazgch 31:a0bed6c1e05d 886 return ip;
mazgch 21:c4d64830bf02 887 }
mazgch 21:c4d64830bf02 888
mazgch 21:c4d64830bf02 889 // ----------------------------------------------------------------
mazgch 21:c4d64830bf02 890 // sockets
mazgch 21:c4d64830bf02 891
mazgch 21:c4d64830bf02 892 int MDMParser::_cbUSOCR(int type, const char* buf, int len, int* socket)
mazgch 21:c4d64830bf02 893 {
mazgch 21:c4d64830bf02 894 if ((type == TYPE_PLUS) && socket) {
mazgch 21:c4d64830bf02 895 const char* p = strstr(buf,"+USOCR: ");
mazgch 21:c4d64830bf02 896 if (p)
mazgch 21:c4d64830bf02 897 *socket = atoi(p+8);
mazgch 21:c4d64830bf02 898 }
mazgch 21:c4d64830bf02 899 return WAIT;
mazgch 21:c4d64830bf02 900 }
mazgch 21:c4d64830bf02 901
mazgch 63:42cb563a25bc 902 int MDMParser::socketSocket(IpProtocol ipproto, int port)
mazgch 21:c4d64830bf02 903 {
mazgch 47:9a89e5195721 904 TRACE("socketSocket(%d)\r\n", ipproto);
mazgch 21:c4d64830bf02 905 if(ipproto == IPPROTO_TCP) {
mazgch 63:42cb563a25bc 906 sendFormated("AT+USOCR=6\r\n");
mazgch 63:42cb563a25bc 907 } else if ((ipproto == IPPROTO_UDP) && (port == -1)){
mazgch 63:42cb563a25bc 908 sendFormated("AT+USOCR=17\r\n");
mazgch 63:42cb563a25bc 909 } else if (ipproto == IPPROTO_UDP){
mazgch 63:42cb563a25bc 910 sendFormated("AT+USOCR=17,%d\r\n", port);
mazgch 21:c4d64830bf02 911 } else { // other types not supported
mazgch 21:c4d64830bf02 912 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 913 }
mazgch 21:c4d64830bf02 914 int socket = -1;
mazgch 52:8071747a7cb3 915 if (RESP_OK != waitFinalResp(_cbUSOCR, &socket))
mazgch 21:c4d64830bf02 916 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 917 if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_FREE))
mazgch 21:c4d64830bf02 918 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 919 // successfull
mazgch 21:c4d64830bf02 920 _sockets[socket].state = SOCK_CREATED;
mazgch 21:c4d64830bf02 921 _sockets[socket].pending = 0;
mazgch 66:69072b3c5bca 922 _sockets[socket].timeout_ms = TIMEOUT_BLOCKING;
mazgch 21:c4d64830bf02 923 return socket;
mazgch 21:c4d64830bf02 924 }
mazgch 21:c4d64830bf02 925
mazgch 21:c4d64830bf02 926 bool MDMParser::socketConnect(int socket, const char * host, int port)
mazgch 21:c4d64830bf02 927 {
mazgch 47:9a89e5195721 928 TRACE("socketConnect(%d,%s,%d)\r\n", socket, host,port);
mazgch 31:a0bed6c1e05d 929 IP ip = gethostbyname(host);
mazgch 31:a0bed6c1e05d 930 if (ip == NOIP)
mazgch 21:c4d64830bf02 931 return false;
mazgch 21:c4d64830bf02 932 // connect to socket
mazgch 21:c4d64830bf02 933 if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CREATED))
mazgch 21:c4d64830bf02 934 return false;
mazgch 21:c4d64830bf02 935 sendFormated("AT+USOCO=%d,\"" IPSTR "\",%d\r\n", socket, IPNUM(ip), port);
mazgch 52:8071747a7cb3 936 if (RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 937 return false;
mazgch 21:c4d64830bf02 938 _sockets[socket].state = SOCK_CONNECTED;
mazgch 21:c4d64830bf02 939 return true;
mazgch 21:c4d64830bf02 940 }
mazgch 21:c4d64830bf02 941
mazgch 44:9d12223b78ff 942 bool MDMParser::socketIsConnected(int socket)
mazgch 44:9d12223b78ff 943 {
mazgch 47:9a89e5195721 944 TRACE("socketIsConnected(%d)\r\n", socket);
mazgch 47:9a89e5195721 945 if (!ISSOCKET(socket))
mazgch 47:9a89e5195721 946 return false;
mazgch 47:9a89e5195721 947 return _sockets[socket].state == SOCK_CONNECTED;
mazgch 44:9d12223b78ff 948 }
mazgch 44:9d12223b78ff 949
mazgch 66:69072b3c5bca 950 bool MDMParser::socketSetBlocking(int socket, int timeout_ms)
mazgch 44:9d12223b78ff 951 {
mazgch 47:9a89e5195721 952 TRACE("socketSetBlocking(%d,%d)\r\n", socket, timeout_ms);
mazgch 44:9d12223b78ff 953 if (!ISSOCKET(socket))
mazgch 44:9d12223b78ff 954 return false;
mazgch 44:9d12223b78ff 955 _sockets[socket].timeout_ms = timeout_ms;
mazgch 44:9d12223b78ff 956 return true;
mazgch 44:9d12223b78ff 957 }
mazgch 44:9d12223b78ff 958
mazgch 21:c4d64830bf02 959 bool MDMParser::socketClose(int socket)
mazgch 21:c4d64830bf02 960 {
mazgch 47:9a89e5195721 961 TRACE("socketClose(%d)\r\n", socket);
mazgch 21:c4d64830bf02 962 if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CONNECTED))
mazgch 21:c4d64830bf02 963 return false;
mazgch 21:c4d64830bf02 964 sendFormated("AT+USOCL=%d\r\n", socket);
mazgch 52:8071747a7cb3 965 if (RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 966 return false;
mazgch 44:9d12223b78ff 967 _sockets[socket].state = SOCK_CREATED;
mazgch 21:c4d64830bf02 968 return true;
mazgch 21:c4d64830bf02 969 }
mazgch 21:c4d64830bf02 970
mazgch 21:c4d64830bf02 971 bool MDMParser::socketFree(int socket)
mazgch 21:c4d64830bf02 972 {
mazgch 47:9a89e5195721 973 TRACE("socketFree(%d)\r\n", socket);
mazgch 21:c4d64830bf02 974 socketClose(socket);
mazgch 21:c4d64830bf02 975 if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CREATED))
mazgch 21:c4d64830bf02 976 return false;
mazgch 21:c4d64830bf02 977 _sockets[socket].state = SOCK_FREE;
mazgch 21:c4d64830bf02 978 return true;
mazgch 21:c4d64830bf02 979 }
mazgch 21:c4d64830bf02 980
mazgch 69:4d6fa520dfca 981 #define USO_MAX_WRITE 1024 //!< maximum number of bytes to write to socket
mazgch 69:4d6fa520dfca 982
mazgch 21:c4d64830bf02 983 int MDMParser::socketSend(int socket, const char * buf, int len)
mazgch 21:c4d64830bf02 984 {
mazgch 47:9a89e5195721 985 TRACE("socketSend(%d,,%d)\r\n", socket,len);
mazgch 68:33a96cf64986 986 int cnt = len;
mazgch 68:33a96cf64986 987 while (cnt > 0) {
mazgch 69:4d6fa520dfca 988 int blk = USO_MAX_WRITE;
mazgch 68:33a96cf64986 989 if (cnt < blk)
mazgch 68:33a96cf64986 990 blk = cnt;
mazgch 68:33a96cf64986 991 sendFormated("AT+USOWR=%d,%d\r\n",socket,blk);
mazgch 52:8071747a7cb3 992 if (RESP_PROMPT != waitFinalResp())
mazgch 21:c4d64830bf02 993 return SOCKET_ERROR;
mazgch 74:208e3e32d263 994 RELAX_MS(50);
mazgch 68:33a96cf64986 995 send(buf, blk);
mazgch 52:8071747a7cb3 996 if (RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 997 return SOCKET_ERROR;
mazgch 68:33a96cf64986 998 buf += blk;
mazgch 68:33a96cf64986 999 cnt -= blk;
mazgch 21:c4d64830bf02 1000 }
mazgch 68:33a96cf64986 1001 return (len - cnt);
mazgch 21:c4d64830bf02 1002 }
mazgch 21:c4d64830bf02 1003
mazgch 21:c4d64830bf02 1004 int MDMParser::socketSendTo(int socket, IP ip, int port, const char * buf, int len)
mazgch 21:c4d64830bf02 1005 {
mazgch 65:dd94f920a762 1006 TRACE("socketSendTo(%d," IPSTR ",%d,,%d)\r\n", socket, IPNUM(ip),port,len);
mazgch 68:33a96cf64986 1007 int cnt = len;
mazgch 68:33a96cf64986 1008 while (cnt > 0) {
mazgch 69:4d6fa520dfca 1009 int blk = USO_MAX_WRITE;
mazgch 68:33a96cf64986 1010 if (cnt < blk)
mazgch 68:33a96cf64986 1011 blk = cnt;
mazgch 68:33a96cf64986 1012 sendFormated("AT+USOST=%d,\"" IPSTR "\",%d,%d\r\n",socket,IPNUM(ip),port,blk);
mazgch 52:8071747a7cb3 1013 if (RESP_PROMPT != waitFinalResp())
mazgch 21:c4d64830bf02 1014 return SOCKET_ERROR;
mazgch 74:208e3e32d263 1015 RELAX_MS(50);
mazgch 68:33a96cf64986 1016 send(buf, blk);
mazgch 63:42cb563a25bc 1017 if (RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 1018 return SOCKET_ERROR;
mazgch 68:33a96cf64986 1019 buf += blk;
mazgch 68:33a96cf64986 1020 cnt -= blk;
mazgch 21:c4d64830bf02 1021 }
mazgch 68:33a96cf64986 1022 return (len - cnt);
mazgch 21:c4d64830bf02 1023 }
mazgch 21:c4d64830bf02 1024
mazgch 21:c4d64830bf02 1025 int MDMParser::socketReadable(int socket)
mazgch 21:c4d64830bf02 1026 {
mazgch 47:9a89e5195721 1027 TRACE("socketReadable(%d)\r\n", socket);
mazgch 21:c4d64830bf02 1028 if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CONNECTED))
mazgch 21:c4d64830bf02 1029 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 1030 // allow to receive unsolicited commands
mazgch 21:c4d64830bf02 1031 waitFinalResp(NULL, NULL, 0);
mazgch 21:c4d64830bf02 1032 if (_sockets[socket].state != SOCK_CONNECTED)
mazgch 21:c4d64830bf02 1033 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 1034 return _sockets[socket].pending;
mazgch 21:c4d64830bf02 1035 }
mazgch 21:c4d64830bf02 1036
mazgch 21:c4d64830bf02 1037 int MDMParser::_cbUSORD(int type, const char* buf, int len, char* out)
mazgch 21:c4d64830bf02 1038 {
mazgch 21:c4d64830bf02 1039 if ((type == TYPE_PLUS) && out) {
mazgch 21:c4d64830bf02 1040 int sz, sk;
mazgch 21:c4d64830bf02 1041 if ((sscanf(buf, "\r\n+USORD: %d,%d,", &sk, &sz) == 2) &&
mazgch 21:c4d64830bf02 1042 (buf[len-sz-2] == '\"') && (buf[len-1] == '\"')) {
mazgch 21:c4d64830bf02 1043 memcpy(out, &buf[len-1-sz], sz);
mazgch 21:c4d64830bf02 1044 }
mazgch 21:c4d64830bf02 1045 }
mazgch 21:c4d64830bf02 1046 return WAIT;
mazgch 21:c4d64830bf02 1047 }
mazgch 21:c4d64830bf02 1048
mazgch 21:c4d64830bf02 1049 int MDMParser::socketRecv(int socket, char* buf, int len)
mazgch 21:c4d64830bf02 1050 {
mazgch 21:c4d64830bf02 1051 int cnt = 0;
mazgch 47:9a89e5195721 1052 TRACE("socketRecv(%d,,%d)\r\n", socket, len);
mazgch 21:c4d64830bf02 1053 if (!ISSOCKET(socket))
mazgch 21:c4d64830bf02 1054 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 1055 memset(buf, '\0', len);
mazgch 44:9d12223b78ff 1056 Timer timer;
mazgch 44:9d12223b78ff 1057 timer.start();
mazgch 21:c4d64830bf02 1058 while (len) {
mazgch 69:4d6fa520dfca 1059 int blk = MAX_SIZE; // still need space for headers and unsolicited commands
mazgch 21:c4d64830bf02 1060 if (_sockets[socket].pending < blk)
mazgch 21:c4d64830bf02 1061 blk = _sockets[socket].pending;
mazgch 21:c4d64830bf02 1062 if (len < blk) blk = len;
mazgch 21:c4d64830bf02 1063 if (blk) {
mazgch 44:9d12223b78ff 1064 sendFormated("AT+USORD=%d,%d\r\n",socket, blk);
mazgch 52:8071747a7cb3 1065 if (RESP_OK != waitFinalResp(_cbUSORD, buf)) {
mazgch 44:9d12223b78ff 1066 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 1067 }
mazgch 21:c4d64830bf02 1068 len -= blk;
mazgch 21:c4d64830bf02 1069 cnt += blk;
mazgch 21:c4d64830bf02 1070 buf += blk;
mazgch 21:c4d64830bf02 1071 _sockets[socket].pending -= blk;
mazgch 75:ce6e12067d0c 1072 } else if ((_sockets[socket].state == SOCK_CONNECTED) &&
mazgch 75:ce6e12067d0c 1073 !TIMEOUT(timer, _sockets[socket].timeout_ms)) {
mazgch 21:c4d64830bf02 1074 // allow to receive unsolicited commands
mazgch 21:c4d64830bf02 1075 waitFinalResp(NULL, NULL, 10);
mazgch 44:9d12223b78ff 1076 } else {
mazgch 44:9d12223b78ff 1077 len = 0; // no more data and socket closed or timed-out
mazgch 21:c4d64830bf02 1078 }
mazgch 21:c4d64830bf02 1079 }
mazgch 21:c4d64830bf02 1080 return cnt;
mazgch 21:c4d64830bf02 1081 }
mazgch 21:c4d64830bf02 1082
mazgch 21:c4d64830bf02 1083 int MDMParser::_cbUSORF(int type, const char* buf, int len, USORFparam* param)
mazgch 21:c4d64830bf02 1084 {
mazgch 21:c4d64830bf02 1085 if ((type == TYPE_PLUS) && param) {
mazgch 21:c4d64830bf02 1086 int sz, sk, p, a,b,c,d;
mazgch 21:c4d64830bf02 1087 if ((sscanf(buf, "\r\n+USORF: %d,\""IPSTR"\",%d,%d,",
mazgch 21:c4d64830bf02 1088 &sk,&a,&b,&c,&d,&p,&sz) == 7) &&
mazgch 21:c4d64830bf02 1089 (buf[len-sz-2] == '\"') && (buf[len-1] == '\"')) {
mazgch 21:c4d64830bf02 1090 memcpy(param->buf, &buf[len-1-sz], sz);
mazgch 21:c4d64830bf02 1091 param->ip = IPADR(a,b,c,d);
mazgch 21:c4d64830bf02 1092 param->port = p;
mazgch 21:c4d64830bf02 1093 }
mazgch 21:c4d64830bf02 1094 }
mazgch 21:c4d64830bf02 1095 return WAIT;
mazgch 21:c4d64830bf02 1096 }
mazgch 21:c4d64830bf02 1097
mazgch 63:42cb563a25bc 1098 int MDMParser::socketRecvFrom(int socket, IP* ip, int* port, char* buf, int len)
mazgch 21:c4d64830bf02 1099 {
mazgch 21:c4d64830bf02 1100 int cnt = 0;
mazgch 63:42cb563a25bc 1101 TRACE("socketRecvFrom(%d,,%d)\r\n", socket, len);
mazgch 21:c4d64830bf02 1102 if (!ISSOCKET(socket))
mazgch 21:c4d64830bf02 1103 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 1104 memset(buf, '\0', len);
mazgch 44:9d12223b78ff 1105 Timer timer;
mazgch 44:9d12223b78ff 1106 timer.start();
mazgch 21:c4d64830bf02 1107 while (len) {
mazgch 69:4d6fa520dfca 1108 int blk = MAX_SIZE; // still need space for headers and unsolicited commands
mazgch 21:c4d64830bf02 1109 if (_sockets[socket].pending < blk)
mazgch 21:c4d64830bf02 1110 blk = _sockets[socket].pending;
mazgch 21:c4d64830bf02 1111 if (len < blk) blk = len;
mazgch 21:c4d64830bf02 1112 if (blk) {
mazgch 21:c4d64830bf02 1113 sendFormated("AT+USORF=%d,%d\r\n",socket, blk);
mazgch 21:c4d64830bf02 1114 USORFparam param;
mazgch 21:c4d64830bf02 1115 param.buf = buf;
mazgch 52:8071747a7cb3 1116 if (RESP_OK != waitFinalResp(_cbUSORF, &param)) {
mazgch 44:9d12223b78ff 1117 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 1118 }
mazgch 21:c4d64830bf02 1119 *ip = param.ip;
mazgch 63:42cb563a25bc 1120 *port = param.port;
mazgch 21:c4d64830bf02 1121 len -= blk;
mazgch 21:c4d64830bf02 1122 cnt += blk;
mazgch 21:c4d64830bf02 1123 buf += blk;
mazgch 21:c4d64830bf02 1124 _sockets[socket].pending -= blk;
mazgch 75:ce6e12067d0c 1125 } else if (!TIMEOUT(timer, _sockets[socket].timeout_ms)) {
mazgch 21:c4d64830bf02 1126 // allow to receive unsolicited commands
mazgch 21:c4d64830bf02 1127 waitFinalResp(NULL, NULL, 10);
mazgch 75:ce6e12067d0c 1128 } else
mazgch 44:9d12223b78ff 1129 len = 0; // no more data and socket closed or timed-out
mazgch 21:c4d64830bf02 1130 }
mazgch 44:9d12223b78ff 1131 timer.stop();
mazgch 44:9d12223b78ff 1132 timer.reset();
mazgch 21:c4d64830bf02 1133 return cnt;
mazgch 21:c4d64830bf02 1134 }
mazgch 21:c4d64830bf02 1135
mazgch 21:c4d64830bf02 1136 // ----------------------------------------------------------------
mazgch 31:a0bed6c1e05d 1137
mazgch 31:a0bed6c1e05d 1138 int MDMParser::_cbCMGL(int type, const char* buf, int len, CMGLparam* param)
mazgch 21:c4d64830bf02 1139 {
mazgch 31:a0bed6c1e05d 1140 if ((type == TYPE_PLUS) && param && param->num) {
mazgch 31:a0bed6c1e05d 1141 // +CMGL: <ix>,...
mazgch 31:a0bed6c1e05d 1142 int ix;
mazgch 31:a0bed6c1e05d 1143 if (sscanf(buf, "\r\n+CMGL: %d,", &ix) == 1)
mazgch 31:a0bed6c1e05d 1144 {
mazgch 31:a0bed6c1e05d 1145 *param->ix++ = ix;
mazgch 31:a0bed6c1e05d 1146 param->num--;
mazgch 31:a0bed6c1e05d 1147 }
mazgch 29:53d346010624 1148 }
mazgch 29:53d346010624 1149 return WAIT;
mazgch 21:c4d64830bf02 1150 }
mazgch 21:c4d64830bf02 1151
mazgch 31:a0bed6c1e05d 1152 int MDMParser::smsList(const char* stat /*= "ALL"*/, int* ix /*=NULL*/, int num /*= 0*/) {
mazgch 31:a0bed6c1e05d 1153 sendFormated("AT+CMGL=\"%s\"\r\n", stat);
mazgch 31:a0bed6c1e05d 1154 CMGLparam param;
mazgch 31:a0bed6c1e05d 1155 param.ix = ix;
mazgch 31:a0bed6c1e05d 1156 param.num = num;
mazgch 52:8071747a7cb3 1157 if (RESP_OK != waitFinalResp(_cbCMGL, &param))
mazgch 31:a0bed6c1e05d 1158 return -1;
mazgch 31:a0bed6c1e05d 1159 return num - param.num;
mazgch 21:c4d64830bf02 1160 }
mazgch 21:c4d64830bf02 1161
mazgch 21:c4d64830bf02 1162 bool MDMParser::smsSend(const char* num, const char* buf)
mazgch 21:c4d64830bf02 1163 {
mazgch 80:34985b4d821e 1164 sendFormated("AT+CMGS=\"%s\"\r\n",num);
mazgch 58:e38a2e942fbb 1165 if (RESP_PROMPT != waitFinalResp(NULL,NULL,150*1000)) {
mazgch 21:c4d64830bf02 1166 return false;
mazgch 21:c4d64830bf02 1167 }
mazgch 21:c4d64830bf02 1168 send(buf, strlen(buf));
mazgch 21:c4d64830bf02 1169 const char ctrlZ = 0x1A;
mazgch 21:c4d64830bf02 1170 send(&ctrlZ, sizeof(ctrlZ));
mazgch 52:8071747a7cb3 1171 if (RESP_OK != waitFinalResp()) {
mazgch 21:c4d64830bf02 1172 return false;
mazgch 21:c4d64830bf02 1173 }
mazgch 21:c4d64830bf02 1174 return true;
mazgch 21:c4d64830bf02 1175 }
mazgch 21:c4d64830bf02 1176
mazgch 21:c4d64830bf02 1177 bool MDMParser::smsDelete(int ix)
mazgch 21:c4d64830bf02 1178 {
mazgch 21:c4d64830bf02 1179 sendFormated("AT+CMGD=%d\r\n",ix);
mazgch 52:8071747a7cb3 1180 if (RESP_OK != waitFinalResp()) {
mazgch 21:c4d64830bf02 1181 return false;
mazgch 21:c4d64830bf02 1182 }
mazgch 21:c4d64830bf02 1183 return true;
mazgch 21:c4d64830bf02 1184 }
mazgch 21:c4d64830bf02 1185
mazgch 21:c4d64830bf02 1186 int MDMParser::_cbCMGR(int type, const char* buf, int len, CMGRparam* param)
mazgch 21:c4d64830bf02 1187 {
mazgch 21:c4d64830bf02 1188 if (param) {
mazgch 21:c4d64830bf02 1189 if (type == TYPE_PLUS) {
mazgch 21:c4d64830bf02 1190 if (sscanf(buf, "\r\n+CMGR: \"%*[^\"]\",\"%[^\"]", param->num) == 1) {
mazgch 21:c4d64830bf02 1191 }
mazgch 37:cc3433329d66 1192 } else if ((type == TYPE_UNKNOWN) && (buf[len-2] == '\r') && (buf[len-1] == '\n')) {
mazgch 21:c4d64830bf02 1193 memcpy(param->buf, buf, len-2);
mazgch 21:c4d64830bf02 1194 param->buf[len-2] = '\0';
mazgch 21:c4d64830bf02 1195 }
mazgch 21:c4d64830bf02 1196 }
mazgch 21:c4d64830bf02 1197 return WAIT;
mazgch 21:c4d64830bf02 1198 }
mazgch 21:c4d64830bf02 1199
mazgch 21:c4d64830bf02 1200 bool MDMParser::smsRead(int ix, char* num, char* buf, int len)
mazgch 21:c4d64830bf02 1201 {
mazgch 21:c4d64830bf02 1202 CMGRparam param;
mazgch 21:c4d64830bf02 1203 param.num = num;
mazgch 21:c4d64830bf02 1204 param.buf = buf;
mazgch 21:c4d64830bf02 1205 sendFormated("AT+CMGR=%d\r\n",ix);
mazgch 52:8071747a7cb3 1206 if (RESP_OK != waitFinalResp(_cbCMGR, &param)) {
mazgch 21:c4d64830bf02 1207 return false;
mazgch 21:c4d64830bf02 1208 }
mazgch 21:c4d64830bf02 1209 return true;
mazgch 21:c4d64830bf02 1210 }
mazgch 54:7ba8e4c218e2 1211
mazgch 54:7ba8e4c218e2 1212 // ----------------------------------------------------------------
mazgch 70:0a87d256cd24 1213
mazgch 70:0a87d256cd24 1214 int MDMParser::_cbCUSD(int type, const char* buf, int len, char* resp)
mazgch 70:0a87d256cd24 1215 {
mazgch 70:0a87d256cd24 1216 if ((type == TYPE_PLUS) && resp) {
mazgch 70:0a87d256cd24 1217 // +USD: \"%*[^\"]\",\"%[^\"]\",,\"%*[^\"]\",%d,%d,%d,%d,\"*[^\"]\",%d,%d"..);
mazgch 70:0a87d256cd24 1218 if (sscanf(buf, "\r\n+CUSD: %*d,\"%[^\"]\",%*d", resp) == 1) {
mazgch 70:0a87d256cd24 1219 /*nothing*/
mazgch 70:0a87d256cd24 1220 }
mazgch 70:0a87d256cd24 1221 }
mazgch 70:0a87d256cd24 1222 return WAIT;
mazgch 70:0a87d256cd24 1223 }
mazgch 70:0a87d256cd24 1224
mazgch 70:0a87d256cd24 1225 bool MDMParser::ussdCommand(const char* cmd, char* buf)
mazgch 70:0a87d256cd24 1226 {
mazgch 80:34985b4d821e 1227 if (_dev.dev == DEV_LISA_C200)
mazgch 80:34985b4d821e 1228 return false;
mazgch 70:0a87d256cd24 1229 *buf = '\0';
mazgch 70:0a87d256cd24 1230 sendFormated("AT+CUSD=1,\"%s\"\r\n",cmd);
mazgch 70:0a87d256cd24 1231 if (RESP_OK != waitFinalResp(_cbCUSD, buf)) {
mazgch 70:0a87d256cd24 1232 return false;
mazgch 70:0a87d256cd24 1233 }
mazgch 70:0a87d256cd24 1234 return true;
mazgch 70:0a87d256cd24 1235 }
mazgch 80:34985b4d821e 1236
mazgch 80:34985b4d821e 1237 // ----------------------------------------------------------------
mazgch 70:0a87d256cd24 1238
mazgch 80:34985b4d821e 1239 bool MDMParser::delFile(const char* filename)
mazgch 80:34985b4d821e 1240 {
mazgch 80:34985b4d821e 1241 sendFormated("AT+UDELFILE=\"%s\"\r\n", filename);
mazgch 80:34985b4d821e 1242 if (RESP_OK != waitFinalResp())
mazgch 80:34985b4d821e 1243 return false;
mazgch 80:34985b4d821e 1244 return true;
mazgch 80:34985b4d821e 1245 }
mazgch 80:34985b4d821e 1246
mazgch 80:34985b4d821e 1247 int MDMParser::writeFile(const char* filename, const char* buf, int len)
mazgch 80:34985b4d821e 1248 {
mazgch 80:34985b4d821e 1249 sendFormated("AT+UDWNFILE=\"%s\",%d\r\n", filename, len);
mazgch 80:34985b4d821e 1250 if (RESP_PROMPT != waitFinalResp())
mazgch 80:34985b4d821e 1251 return 0;
mazgch 80:34985b4d821e 1252 send(buf, len);
mazgch 80:34985b4d821e 1253 if (RESP_OK != waitFinalResp())
mazgch 80:34985b4d821e 1254 return 0;
mazgch 80:34985b4d821e 1255 return len;
mazgch 80:34985b4d821e 1256 }
mazgch 80:34985b4d821e 1257
mazgch 80:34985b4d821e 1258 int MDMParser::readFile(const char* filename, char* buf, int len)
mazgch 80:34985b4d821e 1259 {
mazgch 80:34985b4d821e 1260 sendFormated("AT+URDFILE=\"%s\"\r\n", filename, len);
mazgch 80:34985b4d821e 1261 URDFILEparam param;
mazgch 80:34985b4d821e 1262 param.filename = filename;
mazgch 80:34985b4d821e 1263 param.buf = buf;
mazgch 80:34985b4d821e 1264 param.sz = len;
mazgch 80:34985b4d821e 1265 param.len = 0;
mazgch 80:34985b4d821e 1266 if (RESP_OK != waitFinalResp(_cbURDFILE, &param))
mazgch 80:34985b4d821e 1267 return -1;
mazgch 80:34985b4d821e 1268 return param.len;
mazgch 80:34985b4d821e 1269 }
mazgch 80:34985b4d821e 1270
mazgch 80:34985b4d821e 1271 int MDMParser::_cbURDFILE(int type, const char* buf, int len, URDFILEparam* param)
mazgch 80:34985b4d821e 1272 {
mazgch 80:34985b4d821e 1273 if ((type == TYPE_PLUS) && param && param->filename && param->buf) {
mazgch 80:34985b4d821e 1274 char filename[48];
mazgch 80:34985b4d821e 1275 int sz;
mazgch 80:34985b4d821e 1276 if ((sscanf(buf, "\r\n+URDFILE: \"%[^\"]\",%d,", filename, &sz) == 2) &&
mazgch 80:34985b4d821e 1277 (0 == strcmp(param->filename, filename)) &&
mazgch 80:34985b4d821e 1278 (buf[len-sz-2] == '\"') && (buf[len-1] == '\"')) {
mazgch 80:34985b4d821e 1279 param->len = (sz < param->sz) ? sz : param->sz;
mazgch 80:34985b4d821e 1280 memcpy(param->buf, &buf[len-1-sz], param->len);
mazgch 80:34985b4d821e 1281 }
mazgch 80:34985b4d821e 1282 }
mazgch 80:34985b4d821e 1283 return WAIT;
mazgch 80:34985b4d821e 1284 }
mazgch 80:34985b4d821e 1285
mazgch 70:0a87d256cd24 1286 // ----------------------------------------------------------------
mazgch 74:208e3e32d263 1287 bool MDMParser::setDebug(int level)
mazgch 74:208e3e32d263 1288 {
mazgch 74:208e3e32d263 1289 #ifdef MDM_DEBUG
mazgch 74:208e3e32d263 1290 if ((_debugLevel >= 0) && (level >= 0)) {
mazgch 74:208e3e32d263 1291 _debugLevel = level;
mazgch 74:208e3e32d263 1292 return true;
mazgch 74:208e3e32d263 1293 }
mazgch 74:208e3e32d263 1294 #endif
mazgch 74:208e3e32d263 1295 return false;
mazgch 74:208e3e32d263 1296 }
mazgch 74:208e3e32d263 1297
mazgch 73:2b32e0a21df2 1298 void MDMParser::dumpDevStatus(MDMParser::DevStatus* status,
mazgch 73:2b32e0a21df2 1299 _DPRINT dprint, void* param)
mazgch 54:7ba8e4c218e2 1300 {
mazgch 75:ce6e12067d0c 1301 dprint(param, "Modem::devStatus\r\n");
mazgch 54:7ba8e4c218e2 1302 const char* txtDev[] = { "Unknown", "SARA-G350", "LISA-U200", "LISA-C200" };
mazgch 54:7ba8e4c218e2 1303 if (status->dev < sizeof(txtDev)/sizeof(*txtDev) && (status->dev != MDMParser::DEV_UNKNOWN))
mazgch 73:2b32e0a21df2 1304 dprint(param, " Device: %s\r\n", txtDev[status->dev]);
mazgch 54:7ba8e4c218e2 1305 const char* txtLpm[] = { "Disabled", "Enabled", "Active" };
mazgch 54:7ba8e4c218e2 1306 if (status->lpm < sizeof(txtLpm)/sizeof(*txtLpm))
mazgch 73:2b32e0a21df2 1307 dprint(param, " Power Save: %s\r\n", txtLpm[status->lpm]);
mazgch 75:ce6e12067d0c 1308 const char* txtSim[] = { "Unknown", "Missing", "Pin", "Ready" };
mazgch 54:7ba8e4c218e2 1309 if (status->sim < sizeof(txtSim)/sizeof(*txtSim) && (status->sim != MDMParser::SIM_UNKNOWN))
mazgch 73:2b32e0a21df2 1310 dprint(param, " SIM: %s\r\n", txtSim[status->sim]);
mazgch 54:7ba8e4c218e2 1311 if (*status->ccid)
mazgch 73:2b32e0a21df2 1312 dprint(param, " CCID: %s\r\n", status->ccid);
mazgch 54:7ba8e4c218e2 1313 if (*status->imei)
mazgch 73:2b32e0a21df2 1314 dprint(param, " IMEI: %s\r\n", status->imei);
mazgch 54:7ba8e4c218e2 1315 if (*status->imsi)
mazgch 73:2b32e0a21df2 1316 dprint(param, " IMSI: %s\r\n", status->imsi);
mazgch 54:7ba8e4c218e2 1317 if (*status->meid)
mazgch 73:2b32e0a21df2 1318 dprint(param, " MEID: %s\r\n", status->meid); // LISA-C
mazgch 54:7ba8e4c218e2 1319 if (*status->manu)
mazgch 73:2b32e0a21df2 1320 dprint(param, " Manufacturer: %s\r\n", status->manu);
mazgch 54:7ba8e4c218e2 1321 if (*status->model)
mazgch 73:2b32e0a21df2 1322 dprint(param, " Model: %s\r\n", status->model);
mazgch 54:7ba8e4c218e2 1323 if (*status->ver)
mazgch 73:2b32e0a21df2 1324 dprint(param, " Version: %s\r\n", status->ver);
mazgch 54:7ba8e4c218e2 1325 }
mazgch 54:7ba8e4c218e2 1326
mazgch 73:2b32e0a21df2 1327 void MDMParser::dumpNetStatus(MDMParser::NetStatus *status,
mazgch 73:2b32e0a21df2 1328 _DPRINT dprint, void* param)
mazgch 54:7ba8e4c218e2 1329 {
mazgch 75:ce6e12067d0c 1330 dprint(param, "Modem::netStatus\r\n");
mazgch 54:7ba8e4c218e2 1331 const char* txtReg[] = { "Unknown", "Denied", "None", "Home", "Roaming" };
mazgch 79:291df065e345 1332 if (status->csd < sizeof(txtReg)/sizeof(*txtReg) && (status->csd != MDMParser::REG_UNKNOWN))
mazgch 79:291df065e345 1333 dprint(param, " CSD Registration: %s\r\n", txtReg[status->csd]);
mazgch 79:291df065e345 1334 if (status->psd < sizeof(txtReg)/sizeof(*txtReg) && (status->psd != MDMParser::REG_UNKNOWN))
mazgch 79:291df065e345 1335 dprint(param, " PSD Registration: %s\r\n", txtReg[status->psd]);
mazgch 54:7ba8e4c218e2 1336 const char* txtAct[] = { "Unknown", "GSM", "Edge", "3G", "CDMA" };
mazgch 54:7ba8e4c218e2 1337 if (status->act < sizeof(txtAct)/sizeof(*txtAct) && (status->act != MDMParser::ACT_UNKNOWN))
mazgch 73:2b32e0a21df2 1338 dprint(param, " Access Technology: %s\r\n", txtAct[status->act]);
mazgch 54:7ba8e4c218e2 1339 if (status->rssi)
mazgch 73:2b32e0a21df2 1340 dprint(param, " Signal Strength: %d dBm\r\n", status->rssi);
mazgch 54:7ba8e4c218e2 1341 if (status->ber)
mazgch 73:2b32e0a21df2 1342 dprint(param, " Bit Error Rate: %d\r\n", status->ber);
mazgch 54:7ba8e4c218e2 1343 if (*status->opr)
mazgch 73:2b32e0a21df2 1344 dprint(param, " Operator: %s\r\n", status->opr);
mazgch 54:7ba8e4c218e2 1345 if (status->lac != 0xFFFF)
mazgch 73:2b32e0a21df2 1346 dprint(param, " Location Area Code: %04X\r\n", status->lac);
mazgch 54:7ba8e4c218e2 1347 if (status->ci != 0xFFFFFFFF)
mazgch 73:2b32e0a21df2 1348 dprint(param, " Cell ID: %08X\r\n", status->ci);
mazgch 54:7ba8e4c218e2 1349 if (*status->num)
mazgch 73:2b32e0a21df2 1350 dprint(param, " Phone Number: %s\r\n", status->num);
mazgch 54:7ba8e4c218e2 1351 }
mazgch 54:7ba8e4c218e2 1352
mazgch 73:2b32e0a21df2 1353 void MDMParser::dumpIp(MDMParser::IP ip,
mazgch 73:2b32e0a21df2 1354 _DPRINT dprint, void* param)
mazgch 54:7ba8e4c218e2 1355 {
mazgch 57:869bd35f44cc 1356 if (ip != NOIP)
mazgch 75:ce6e12067d0c 1357 dprint(param, "Modem:IP " IPSTR "\r\n", IPNUM(ip));
mazgch 54:7ba8e4c218e2 1358 }
mazgch 70:0a87d256cd24 1359
mazgch 21:c4d64830bf02 1360 // ----------------------------------------------------------------
mazgch 21:c4d64830bf02 1361 int MDMParser::_parseMatch(Pipe<char>* pipe, int len, const char* sta, const char* end)
mazgch 18:e5697801df29 1362 {
mazgch 18:e5697801df29 1363 int o = 0;
mazgch 21:c4d64830bf02 1364 if (sta) {
mazgch 21:c4d64830bf02 1365 while (*sta) {
mazgch 21:c4d64830bf02 1366 if (++o > len) return WAIT;
mazgch 21:c4d64830bf02 1367 char ch = pipe->next();
mazgch 21:c4d64830bf02 1368 if (*sta++ != ch) return NOT_FOUND;
mazgch 21:c4d64830bf02 1369 }
mazgch 21:c4d64830bf02 1370 }
mazgch 21:c4d64830bf02 1371 if (!end) return o; // no termination
mazgch 35:9275215a3a5b 1372 // at least any char
mazgch 35:9275215a3a5b 1373 if (++o > len) return WAIT;
mazgch 35:9275215a3a5b 1374 pipe->next();
mazgch 35:9275215a3a5b 1375 // check the end
mazgch 21:c4d64830bf02 1376 int x = 0;
mazgch 21:c4d64830bf02 1377 while (end[x]) {
mazgch 21:c4d64830bf02 1378 if (++o > len) return WAIT;
mazgch 21:c4d64830bf02 1379 char ch = pipe->next();
mazgch 21:c4d64830bf02 1380 x = (end[x] == ch) ? x + 1 :
mazgch 21:c4d64830bf02 1381 (end[0] == ch) ? 1 :
mazgch 21:c4d64830bf02 1382 0;
mazgch 21:c4d64830bf02 1383 }
mazgch 21:c4d64830bf02 1384 return o;
mazgch 21:c4d64830bf02 1385 }
mazgch 21:c4d64830bf02 1386
mazgch 21:c4d64830bf02 1387 int MDMParser::_parseFormated(Pipe<char>* pipe, int len, const char* fmt)
mazgch 21:c4d64830bf02 1388 {
mazgch 21:c4d64830bf02 1389 int o = 0;
mazgch 21:c4d64830bf02 1390 int num = 0;
mazgch 21:c4d64830bf02 1391 if (fmt) {
mazgch 21:c4d64830bf02 1392 while (*fmt) {
mazgch 21:c4d64830bf02 1393 if (++o > len) return WAIT;
mazgch 21:c4d64830bf02 1394 char ch = pipe->next();
mazgch 21:c4d64830bf02 1395 if (*fmt == '%') {
mazgch 21:c4d64830bf02 1396 fmt++;
mazgch 21:c4d64830bf02 1397 if (*fmt == 'd') { // numeric
mazgch 21:c4d64830bf02 1398 fmt ++;
mazgch 21:c4d64830bf02 1399 num = 0;
mazgch 21:c4d64830bf02 1400 while (ch >= '0' && ch <= '9') {
mazgch 21:c4d64830bf02 1401 num = num * 10 + (ch - '0');
mazgch 21:c4d64830bf02 1402 if (++o > len) return WAIT;
mazgch 21:c4d64830bf02 1403 ch = pipe->next();
mazgch 21:c4d64830bf02 1404 }
mazgch 21:c4d64830bf02 1405 }
mazgch 21:c4d64830bf02 1406 else if (*fmt == 'c') { // char buffer (takes last numeric as length)
mazgch 21:c4d64830bf02 1407 fmt ++;
mazgch 21:c4d64830bf02 1408 while (num --) {
mazgch 21:c4d64830bf02 1409 if (++o > len) return WAIT;
mazgch 21:c4d64830bf02 1410 ch = pipe->next();
mazgch 21:c4d64830bf02 1411 }
mazgch 21:c4d64830bf02 1412 }
mazgch 80:34985b4d821e 1413 else if (*fmt == 's') {
mazgch 80:34985b4d821e 1414 fmt ++;
mazgch 80:34985b4d821e 1415 if (ch != '\"') return NOT_FOUND;
mazgch 80:34985b4d821e 1416 do {
mazgch 80:34985b4d821e 1417 if (++o > len) return WAIT;
mazgch 80:34985b4d821e 1418 ch = pipe->next();
mazgch 80:34985b4d821e 1419 } while (ch != '\"');
mazgch 80:34985b4d821e 1420 if (++o > len) return WAIT;
mazgch 80:34985b4d821e 1421 ch = pipe->next();
mazgch 80:34985b4d821e 1422 }
mazgch 21:c4d64830bf02 1423 }
mazgch 21:c4d64830bf02 1424 if (*fmt++ != ch) return NOT_FOUND;
mazgch 18:e5697801df29 1425 }
mazgch 18:e5697801df29 1426 }
mazgch 21:c4d64830bf02 1427 return o;
mazgch 21:c4d64830bf02 1428 }
mazgch 21:c4d64830bf02 1429
mazgch 21:c4d64830bf02 1430 int MDMParser::_getLine(Pipe<char>* pipe, char* buf, int len)
mazgch 21:c4d64830bf02 1431 {
mazgch 21:c4d64830bf02 1432 int unkn = 0;
mazgch 21:c4d64830bf02 1433 int sz = pipe->size();
mazgch 21:c4d64830bf02 1434 int fr = pipe->free();
mazgch 21:c4d64830bf02 1435 if (len > sz)
mazgch 21:c4d64830bf02 1436 len = sz;
mazgch 21:c4d64830bf02 1437 while (len > 0)
mazgch 21:c4d64830bf02 1438 {
mazgch 21:c4d64830bf02 1439 static struct {
mazgch 21:c4d64830bf02 1440 const char* fmt; int type;
mazgch 21:c4d64830bf02 1441 } lutF[] = {
mazgch 21:c4d64830bf02 1442 { "\r\n+USORD: %d,%d,\"%c\"", TYPE_PLUS },
mazgch 21:c4d64830bf02 1443 { "\r\n+USORF: %d,\""IPSTR"\",%d,%d,\"%c\"", TYPE_PLUS },
mazgch 80:34985b4d821e 1444 { "\r\n+URDFILE: %s,%d,\"%c\"", TYPE_PLUS },
mazgch 21:c4d64830bf02 1445 };
mazgch 21:c4d64830bf02 1446 static struct {
mazgch 21:c4d64830bf02 1447 const char* sta; const char* end; int type;
mazgch 21:c4d64830bf02 1448 } lut[] = {
mazgch 21:c4d64830bf02 1449 { "\r\nOK\r\n", NULL, TYPE_OK },
mazgch 21:c4d64830bf02 1450 { "\r\nERROR\r\n", NULL, TYPE_ERROR },
mazgch 31:a0bed6c1e05d 1451 { "\r\n+CME ERROR:", "\r\n", TYPE_ERROR },
mazgch 21:c4d64830bf02 1452 { "\r\n+CMS ERROR:", "\r\n", TYPE_ERROR },
mazgch 21:c4d64830bf02 1453 { "\r\nRING\r\n", NULL, TYPE_RING },
mazgch 21:c4d64830bf02 1454 { "\r\nCONNECT\r\n", NULL, TYPE_CONNECT },
mazgch 21:c4d64830bf02 1455 { "\r\nNO CARRIER\r\n", NULL, TYPE_NOCARRIER },
mazgch 21:c4d64830bf02 1456 { "\r\nNO DIALTONE\r\n", NULL, TYPE_NODIALTONE },
mazgch 21:c4d64830bf02 1457 { "\r\nBUSY\r\n", NULL, TYPE_BUSY },
mazgch 21:c4d64830bf02 1458 { "\r\nNO ANSWER\r\n", NULL, TYPE_NOANSWER },
mazgch 21:c4d64830bf02 1459 { "\r\n+", "\r\n", TYPE_PLUS },
mazgch 21:c4d64830bf02 1460 { "\r\n@", NULL, TYPE_PROMPT }, // Sockets
mazgch 21:c4d64830bf02 1461 { "\r\n>", NULL, TYPE_PROMPT }, // SMS
mazgch 80:34985b4d821e 1462 { "\n>", NULL, TYPE_PROMPT }, // File
mazgch 21:c4d64830bf02 1463 };
mazgch 21:c4d64830bf02 1464 for (int i = 0; i < sizeof(lutF)/sizeof(*lutF); i ++) {
mazgch 21:c4d64830bf02 1465 pipe->set(unkn);
mazgch 21:c4d64830bf02 1466 int ln = _parseFormated(pipe, len, lutF[i].fmt);
mazgch 21:c4d64830bf02 1467 if (ln == WAIT && fr)
mazgch 21:c4d64830bf02 1468 return WAIT;
mazgch 21:c4d64830bf02 1469 if ((ln != NOT_FOUND) && (unkn > 0))
mazgch 31:a0bed6c1e05d 1470 return TYPE_UNKNOWN | pipe->get(buf, unkn);
mazgch 21:c4d64830bf02 1471 if (ln > 0)
mazgch 21:c4d64830bf02 1472 return lutF[i].type | pipe->get(buf, ln);
mazgch 21:c4d64830bf02 1473 }
mazgch 21:c4d64830bf02 1474 for (int i = 0; i < sizeof(lut)/sizeof(*lut); i ++) {
mazgch 21:c4d64830bf02 1475 pipe->set(unkn);
mazgch 21:c4d64830bf02 1476 int ln = _parseMatch(pipe, len, lut[i].sta, lut[i].end);
mazgch 21:c4d64830bf02 1477 if (ln == WAIT && fr)
mazgch 21:c4d64830bf02 1478 return WAIT;
mazgch 21:c4d64830bf02 1479 if ((ln != NOT_FOUND) && (unkn > 0))
mazgch 31:a0bed6c1e05d 1480 return TYPE_UNKNOWN | pipe->get(buf, unkn);
mazgch 21:c4d64830bf02 1481 if (ln > 0)
mazgch 21:c4d64830bf02 1482 return lut[i].type | pipe->get(buf, ln);
mazgch 21:c4d64830bf02 1483 }
mazgch 21:c4d64830bf02 1484 // UNKNOWN
mazgch 21:c4d64830bf02 1485 unkn ++;
mazgch 21:c4d64830bf02 1486 len--;
mazgch 21:c4d64830bf02 1487 }
mazgch 18:e5697801df29 1488 return WAIT;
mazgch 18:e5697801df29 1489 }
mazgch 18:e5697801df29 1490
mazgch 18:e5697801df29 1491 // ----------------------------------------------------------------
mazgch 18:e5697801df29 1492 // Serial Implementation
mazgch 18:e5697801df29 1493 // ----------------------------------------------------------------
mazgch 18:e5697801df29 1494
mazgch 76:f7c3dd568dae 1495 /*! Helper Dev Null Device
mazgch 76:f7c3dd568dae 1496 Small helper class used to shut off stderr/stdout. Sometimes stdin/stdout
mazgch 76:f7c3dd568dae 1497 is shared with the serial port of the modem. Having printfs inbetween the
mazgch 76:f7c3dd568dae 1498 AT commands you cause a failure of the modem.
mazgch 76:f7c3dd568dae 1499 */
mazgch 76:f7c3dd568dae 1500 class DevNull : public Stream {
mazgch 76:f7c3dd568dae 1501 public:
mazgch 76:f7c3dd568dae 1502 DevNull() : Stream(_name+1) { } //!< Constructor
mazgch 76:f7c3dd568dae 1503 void claim(const char* mode, FILE* file)
mazgch 76:f7c3dd568dae 1504 { freopen(_name, mode, file); } //!< claim a stream
mazgch 76:f7c3dd568dae 1505 protected:
mazgch 76:f7c3dd568dae 1506 virtual int _getc() { return EOF; } //!< Nothing
mazgch 76:f7c3dd568dae 1507 virtual int _putc(int c) { return c; } //!< Discard
mazgch 76:f7c3dd568dae 1508 static const char* _name; //!< File name
mazgch 76:f7c3dd568dae 1509 };
mazgch 76:f7c3dd568dae 1510 const char* DevNull::_name = "/null"; //!< the null device name
mazgch 76:f7c3dd568dae 1511 static DevNull null; //!< the null device
mazgch 76:f7c3dd568dae 1512
mazgch 19:2b5d097ca15d 1513 MDMSerial::MDMSerial(PinName tx /*= MDMTXD*/, PinName rx /*= MDMRXD*/,
mazgch 19:2b5d097ca15d 1514 int baudrate /*= MDMBAUD*/,
mazgch 43:a89a7a505991 1515 #if DEVICE_SERIAL_FC
mazgch 19:2b5d097ca15d 1516 PinName rts /*= MDMRTS*/, PinName cts /*= MDMCTS*/,
mazgch 43:a89a7a505991 1517 #endif
mazgch 18:e5697801df29 1518 int rxSize /*= 256*/, int txSize /*= 128*/) :
mazgch 35:9275215a3a5b 1519 SerialPipe(tx, rx, rxSize, txSize)
mazgch 18:e5697801df29 1520 {
mazgch 76:f7c3dd568dae 1521 if (rx == USBRX)
mazgch 76:f7c3dd568dae 1522 null.claim("r", stdin);
mazgch 76:f7c3dd568dae 1523 if (tx == USBTX) {
mazgch 76:f7c3dd568dae 1524 null.claim("w", stdout);
mazgch 76:f7c3dd568dae 1525 null.claim("w", stderr);
mazgch 74:208e3e32d263 1526 #ifdef MDM_DEBUG
mazgch 76:f7c3dd568dae 1527 _debugLevel = -1;
mazgch 76:f7c3dd568dae 1528 #endif
mazgch 76:f7c3dd568dae 1529 }
mazgch 74:208e3e32d263 1530 #ifdef TARGET_UBLOX_C027
mazgch 74:208e3e32d263 1531 _onboard = (tx == MDMTXD) && (rx == MDMRXD);
mazgch 74:208e3e32d263 1532 if (_onboard)
mazgch 74:208e3e32d263 1533 c027_mdm_powerOn(false);
mazgch 74:208e3e32d263 1534 #endif
mazgch 18:e5697801df29 1535 baud(baudrate);
mazgch 35:9275215a3a5b 1536 #if DEVICE_SERIAL_FC
mazgch 35:9275215a3a5b 1537 if ((rts != NC) || (cts != NC))
mazgch 35:9275215a3a5b 1538 {
mazgch 35:9275215a3a5b 1539 Flow flow = (cts == NC) ? RTS :
mazgch 35:9275215a3a5b 1540 (rts == NC) ? CTS : RTSCTS ;
mazgch 35:9275215a3a5b 1541 set_flow_control(flow, rts, cts);
mazgch 35:9275215a3a5b 1542 if (cts != NC) _dev.lpm = LPM_ENABLED;
mazgch 35:9275215a3a5b 1543 }
mazgch 35:9275215a3a5b 1544 #endif
mazgch 18:e5697801df29 1545 }
mazgch 18:e5697801df29 1546
mazgch 76:f7c3dd568dae 1547 MDMSerial::~MDMSerial(void)
mazgch 76:f7c3dd568dae 1548 {
mazgch 76:f7c3dd568dae 1549 powerOff();
mazgch 76:f7c3dd568dae 1550 #ifdef TARGET_UBLOX_C027
mazgch 76:f7c3dd568dae 1551 if (_onboard)
mazgch 76:f7c3dd568dae 1552 c027_mdm_powerOff();
mazgch 76:f7c3dd568dae 1553 #endif
mazgch 76:f7c3dd568dae 1554 }
mazgch 76:f7c3dd568dae 1555
mazgch 18:e5697801df29 1556 int MDMSerial::_send(const void* buf, int len)
mazgch 18:e5697801df29 1557 {
mazgch 35:9275215a3a5b 1558 return put((const char*)buf, len, true/*=blocking*/);
mazgch 18:e5697801df29 1559 }
mazgch 18:e5697801df29 1560
mazgch 18:e5697801df29 1561 int MDMSerial::getLine(char* buffer, int length)
mazgch 18:e5697801df29 1562 {
mazgch 18:e5697801df29 1563 return _getLine(&_pipeRx, buffer, length);
mazgch 18:e5697801df29 1564 }
mazgch 18:e5697801df29 1565
mazgch 18:e5697801df29 1566 // ----------------------------------------------------------------
mazgch 18:e5697801df29 1567 // USB Implementation
mazgch 18:e5697801df29 1568 // ----------------------------------------------------------------
mazgch 18:e5697801df29 1569
mazgch 18:e5697801df29 1570 #ifdef HAVE_MDMUSB
mazgch 76:f7c3dd568dae 1571 MDMUsb::MDMUsb(void)
mazgch 74:208e3e32d263 1572 {
mazgch 74:208e3e32d263 1573 #ifdef MDM_DEBUG
mazgch 74:208e3e32d263 1574 _debugLevel = 1;
mazgch 74:208e3e32d263 1575 #endif
mazgch 74:208e3e32d263 1576 #ifdef TARGET_UBLOX_C027
mazgch 74:208e3e32d263 1577 _onboard = true;
mazgch 74:208e3e32d263 1578 c027_mdm_powerOn(true);
mazgch 74:208e3e32d263 1579 #endif
mazgch 74:208e3e32d263 1580 }
mazgch 76:f7c3dd568dae 1581
mazgch 76:f7c3dd568dae 1582 MDMUsb::~MDMUsb(void)
mazgch 76:f7c3dd568dae 1583 {
mazgch 76:f7c3dd568dae 1584 powerOff();
mazgch 76:f7c3dd568dae 1585 #ifdef TARGET_UBLOX_C027
mazgch 76:f7c3dd568dae 1586 if (_onboard)
mazgch 76:f7c3dd568dae 1587 c027_mdm_powerOff();
mazgch 76:f7c3dd568dae 1588 #endif
mazgch 76:f7c3dd568dae 1589 }
mazgch 76:f7c3dd568dae 1590
mazgch 76:f7c3dd568dae 1591 int MDMUsb::_send(const void* buf, int len) { return 0; }
mazgch 76:f7c3dd568dae 1592
mazgch 18:e5697801df29 1593 int MDMUsb::getLine(char* buffer, int length) { return NOT_FOUND; }
mazgch 76:f7c3dd568dae 1594
mazgch 35:9275215a3a5b 1595 #endif