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:
msinig
Date:
Thu Nov 26 09:42:01 2015 +0000
Revision:
133:57b208dd96fb
Parent:
131:965a7cbc1e58
Child:
134:2fbd5723e063
Added CellLocate API

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