Added HTTP API to C027_Support library.

Fork of C027_Support by u-blox

Committer:
fdilenarda
Date:
Thu Dec 10 08:35:49 2015 +0000
Revision:
134:307c15ce18e8
Parent:
133:57b208dd96fb
Child:
136:95ae93a46ae5
added HTTP API

Who changed what in which revision?

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