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:
Tue Jan 12 08:37:29 2016 +0000
Revision:
134:2fbd5723e063
Parent:
133:57b208dd96fb
Child:
135:cbccf4052d45
added features for connection manager

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