* add C027_Support fork

Fork of C027_Support by u-blox

Committer:
mazgch
Date:
Thu May 15 22:20:42 2014 +0000
Revision:
74:208e3e32d263
Parent:
73:2b32e0a21df2
Child:
75:ce6e12067d0c
initial version of restructured u-blox library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mazgch 18:e5697801df29 1 #include "mbed.h"
mazgch 18:e5697801df29 2 #include <ctype.h>
mazgch 31:a0bed6c1e05d 3 #include <string.h>
mazgch 18:e5697801df29 4 #include "MDM.h"
mazgch 74:208e3e32d263 5 #include "Relax.h"
mazgch 74:208e3e32d263 6 #ifdef TARGET_UBLOX_C027
mazgch 74:208e3e32d263 7 #include "C027_api.h"
mazgch 74:208e3e32d263 8 #endif
mazgch 18:e5697801df29 9
mazgch 74:208e3e32d263 10 #define PROFILE "0" //!< this is the psd profile used
mazgch 74:208e3e32d263 11 #define MAX_SIZE 128 //!< max expected messages
mazgch 74:208e3e32d263 12 //! test if it is a socket
mazgch 21:c4d64830bf02 13 #define ISSOCKET(s) (((s) >= 0) && ((s) < (sizeof(_sockets)/sizeof(*_sockets))))
mazgch 21:c4d64830bf02 14
mazgch 69:4d6fa520dfca 15
mazgch 74:208e3e32d263 16 #ifdef MDM_DEBUG
mazgch 74:208e3e32d263 17 void dumpAtCmd(const char* buf, int len)
mazgch 21:c4d64830bf02 18 {
mazgch 74:208e3e32d263 19 printf(" %3d \"", len);
mazgch 21:c4d64830bf02 20 while (len --) {
mazgch 21:c4d64830bf02 21 char ch = *buf++;
mazgch 74:208e3e32d263 22 if (ch == '\r') puts("\\r");
mazgch 74:208e3e32d263 23 else if (ch == '\n') puts("\\n");
mazgch 74:208e3e32d263 24 else if (ch >= 0x20) putchar(ch);
mazgch 21:c4d64830bf02 25 else printf("\\x%02x", ch);
mazgch 21:c4d64830bf02 26 }
mazgch 74:208e3e32d263 27 puts("\"\r\n");
mazgch 21:c4d64830bf02 28 }
mazgch 74:208e3e32d263 29
mazgch 74:208e3e32d263 30 #define INFO (_debugLevel >= 1) ? : printf
mazgch 74:208e3e32d263 31 #define TRACE (_debugLevel >= 2) ? : printf
mazgch 74:208e3e32d263 32
mazgch 31:a0bed6c1e05d 33 #if 1 // colored terminal output using ANSI escape sequences
mazgch 31:a0bed6c1e05d 34 #define COL(c,t) "\33[" c t "\33[" "39m"
mazgch 31:a0bed6c1e05d 35 #else
mazgch 31:a0bed6c1e05d 36 #define COL(c,t) t
mazgch 31:a0bed6c1e05d 37 #endif
mazgch 31:a0bed6c1e05d 38 #define BLA(t) COL("30m",t)
mazgch 31:a0bed6c1e05d 39 #define RED(t) COL("31m",t)
mazgch 31:a0bed6c1e05d 40 #define GRE(t) COL("32m",t)
mazgch 31:a0bed6c1e05d 41 #define YEL(t) COL("33m",t)
mazgch 31:a0bed6c1e05d 42 #define BLU(t) COL("34m",t)
mazgch 31:a0bed6c1e05d 43 #define MAG(t) COL("35m",t)
mazgch 31:a0bed6c1e05d 44 #define CYA(t) COL("36m",t)
mazgch 31:a0bed6c1e05d 45 #define WHY(t) COL("37m",t)
mazgch 74:208e3e32d263 46
mazgch 74:208e3e32d263 47 #else
mazgch 74:208e3e32d263 48
mazgch 74:208e3e32d263 49 #define INFO(...) (void)0 // no tracing
mazgch 74:208e3e32d263 50 #define TRACE(...) (void)0 // no tracing
mazgch 74:208e3e32d263 51
mazgch 31:a0bed6c1e05d 52 #endif
mazgch 21:c4d64830bf02 53
mazgch 44:9d12223b78ff 54 MDMParser* MDMParser::inst;
mazgch 44:9d12223b78ff 55
mazgch 21:c4d64830bf02 56 MDMParser::MDMParser(void)
mazgch 21:c4d64830bf02 57 {
mazgch 44:9d12223b78ff 58 inst = this;
mazgch 31:a0bed6c1e05d 59 memset(&_dev, 0, sizeof(_dev));
mazgch 31:a0bed6c1e05d 60 memset(&_net, 0, sizeof(_net));
mazgch 54:7ba8e4c218e2 61 _net.lac = 0xFFFF;
mazgch 54:7ba8e4c218e2 62 _net.ci = 0xFFFFFFFF;
mazgch 35:9275215a3a5b 63 _ip = NOIP;
mazgch 31:a0bed6c1e05d 64 memset(_sockets, 0, sizeof(_sockets));
mazgch 74:208e3e32d263 65 #ifdef MDM_DEBUG
mazgch 74:208e3e32d263 66 _debugTime.start();
mazgch 74:208e3e32d263 67 #endif
mazgch 74:208e3e32d263 68 }
mazgch 74:208e3e32d263 69
mazgch 74:208e3e32d263 70 MDMParser::~MDMParser(void)
mazgch 74:208e3e32d263 71 {
mazgch 74:208e3e32d263 72 powerOff();
mazgch 74:208e3e32d263 73 #ifdef TARGET_UBLOX_C027
mazgch 74:208e3e32d263 74 if (_onboard)
mazgch 74:208e3e32d263 75 c027_mdm_powerOff();
mazgch 58:e38a2e942fbb 76 #endif
mazgch 21:c4d64830bf02 77 }
mazgch 18:e5697801df29 78
mazgch 18:e5697801df29 79 int MDMParser::send(const char* buf, int len)
mazgch 18:e5697801df29 80 {
mazgch 74:208e3e32d263 81 #ifdef MDM_DEBUG
mazgch 74:208e3e32d263 82 if (_debugLevel >= 3) {
mazgch 74:208e3e32d263 83 printf("%10.3f AT send ", _debugTime.read_ms()*0.001);
mazgch 74:208e3e32d263 84 dumpAtCmd(buf,len);
mazgch 74:208e3e32d263 85 }
mazgch 21:c4d64830bf02 86 #endif
mazgch 18:e5697801df29 87 return _send(buf, len);
mazgch 18:e5697801df29 88 }
mazgch 18:e5697801df29 89
mazgch 21:c4d64830bf02 90 int MDMParser::sendFormated(const char* format, ...) {
mazgch 21:c4d64830bf02 91 char buf[MAX_SIZE];
mazgch 21:c4d64830bf02 92 va_list args;
mazgch 21:c4d64830bf02 93 va_start(args, format);
mazgch 21:c4d64830bf02 94 int len = vsnprintf(buf,sizeof(buf), format, args);
mazgch 21:c4d64830bf02 95 va_end(args);
mazgch 21:c4d64830bf02 96 return send(buf, len);
mazgch 21:c4d64830bf02 97 }
mazgch 21:c4d64830bf02 98
mazgch 26:07be5faf8925 99 int MDMParser::waitFinalResp(_CALLBACKPTR cb /* = NULL*/,
mazgch 26:07be5faf8925 100 void* param /* = NULL*/,
mazgch 26:07be5faf8925 101 int timeout_ms /*= 5000*/)
mazgch 26:07be5faf8925 102 {
mazgch 69:4d6fa520dfca 103 char buf[MAX_SIZE + 64 /* add some more space for framing */];
mazgch 21:c4d64830bf02 104 Timer timer;
mazgch 21:c4d64830bf02 105 timer.start();
mazgch 21:c4d64830bf02 106 do {
mazgch 21:c4d64830bf02 107 int ret = getLine(buf, sizeof(buf));
mazgch 74:208e3e32d263 108 #ifdef MDM_DEBUG
mazgch 74:208e3e32d263 109 if ((_debugLevel >= 3) && (ret != WAIT) && (ret != NOT_FOUND))
mazgch 21:c4d64830bf02 110 {
mazgch 31:a0bed6c1e05d 111 int len = LENGTH(ret);
mazgch 31:a0bed6c1e05d 112 int type = TYPE(ret);
mazgch 31:a0bed6c1e05d 113 const char* s = (type == TYPE_UNKNOWN)? YEL("UNK") :
mazgch 35:9275215a3a5b 114 (type == TYPE_TEXT) ? MAG("TXT") :
mazgch 53:cb0d94b9de3a 115 (type == TYPE_OK ) ? GRE("OK ") :
mazgch 31:a0bed6c1e05d 116 (type == TYPE_ERROR) ? RED("ERR") :
mazgch 31:a0bed6c1e05d 117 (type == TYPE_PLUS) ? CYA(" + ") :
mazgch 31:a0bed6c1e05d 118 (type == TYPE_PROMPT) ? BLU(" > ") :
mazgch 31:a0bed6c1e05d 119 "..." ;
mazgch 74:208e3e32d263 120 printf("%10.3f AT read %s", _debugTime.read_ms()*0.001, s);
mazgch 74:208e3e32d263 121 dumpAtCmd(buf, len);
mazgch 21:c4d64830bf02 122 }
mazgch 21:c4d64830bf02 123 #endif
mazgch 21:c4d64830bf02 124 if ((ret != WAIT) && (ret != NOT_FOUND))
mazgch 18:e5697801df29 125 {
mazgch 21:c4d64830bf02 126 int type = TYPE(ret);
mazgch 52:8071747a7cb3 127 if (type == TYPE_OK) return RESP_OK;
mazgch 52:8071747a7cb3 128 if (type == TYPE_ERROR) return RESP_ERROR;
mazgch 52:8071747a7cb3 129 if (type == TYPE_PROMPT) return RESP_PROMPT;
mazgch 21:c4d64830bf02 130 // handle unsolicited commands here
mazgch 21:c4d64830bf02 131 if (type == TYPE_PLUS) {
mazgch 21:c4d64830bf02 132 const char* cmd = buf+3;
mazgch 54:7ba8e4c218e2 133 int a, b, c, d, r;
mazgch 23:05a1aeeb5fd9 134 char s[32];
mazgch 21:c4d64830bf02 135
mazgch 31:a0bed6c1e05d 136 // SMS Command ---------------------------------
mazgch 31:a0bed6c1e05d 137 // +CNMI: <mem>,<index>
mazgch 31:a0bed6c1e05d 138 if (sscanf(cmd, "CMTI: \"%*[^\"]\",%d", &a) == 1) {
mazgch 31:a0bed6c1e05d 139 TRACE("New SMS at index %d\r\n", a);
mazgch 21:c4d64830bf02 140 // Socket Specific Command ---------------------------------
mazgch 21:c4d64830bf02 141 // +UUSORD: <socket>,<length>
mazgch 21:c4d64830bf02 142 } else if ((sscanf(cmd, "UUSORD: %d,%d", &a, &b) == 2) &&
mazgch 63:42cb563a25bc 143 ISSOCKET(a) /*&& (_sockets[a].state == SOCK_CONNECTED)*/) {
mazgch 31:a0bed6c1e05d 144 TRACE("Socket %d: %d bytes pending\r\n", a, b);
mazgch 21:c4d64830bf02 145 _sockets[a].pending = b;
mazgch 69:4d6fa520dfca 146 // +UUSORF: <socket>,<length>
mazgch 69:4d6fa520dfca 147 } else if ((sscanf(cmd, "UUSORF: %d,%d", &a, &b) == 2) &&
mazgch 69:4d6fa520dfca 148 ISSOCKET(a) /*&& (_sockets[a].state == SOCK_CONNECTED)*/) {
mazgch 69:4d6fa520dfca 149 TRACE("Socket %d: %d bytes pending\r\n", a, b);
mazgch 69:4d6fa520dfca 150 _sockets[a].pending = b;
mazgch 21:c4d64830bf02 151 // +UUSOCL: <socket>
mazgch 21:c4d64830bf02 152 } else if ((sscanf(cmd, "UUSOCL: %d", &a) == 1) &&
mazgch 21:c4d64830bf02 153 ISSOCKET(a) && (_sockets[a].state == SOCK_CONNECTED)) {
mazgch 31:a0bed6c1e05d 154 TRACE("Socket %d: closed by remote host\r\n", a);
mazgch 21:c4d64830bf02 155 _sockets[a].state = SOCK_CREATED/*=CLOSED*/;
mazgch 21:c4d64830bf02 156 }
mazgch 32:8f12ac182bbb 157 if (_dev.dev == DEV_LISA_C200) {
mazgch 21:c4d64830bf02 158 // CDMA Specific -------------------------------------------
mazgch 21:c4d64830bf02 159 // +CREG: <n><SID>,<NID>,<stat>
mazgch 54:7ba8e4c218e2 160 if (sscanf(cmd, "CREG: %*d,%d,%d,%d",&a,&b,&c) == 3) {
mazgch 54:7ba8e4c218e2 161 // _net.sid = a;
mazgch 54:7ba8e4c218e2 162 // _net.nid = b;
mazgch 54:7ba8e4c218e2 163 if (c == 0) _net.reg = REG_NONE; // not registered, home network
mazgch 54:7ba8e4c218e2 164 else if (c == 1) _net.reg = REG_HOME; // registered, home network
mazgch 54:7ba8e4c218e2 165 else if (c == 2) _net.reg = REG_NONE; // not registered, but MT is currently searching a new operator to register to
mazgch 54:7ba8e4c218e2 166 else if (c == 3) _net.reg = REG_DENIED; // registration denied
mazgch 54:7ba8e4c218e2 167 else if (c == 5) _net.reg = REG_ROAMING; // registered, roaming
mazgch 31:a0bed6c1e05d 168 _net.act = ACT_CDMA;
mazgch 21:c4d64830bf02 169 // +CSS: <mode>[,<format>,<oper>[,<AcT>]]
mazgch 21:c4d64830bf02 170 } else if (sscanf(cmd, "CSS %*c,%2s,%*d",s) == 1) {
mazgch 31:a0bed6c1e05d 171 //_net.reg = (strcmp("Z", s) == 0) ? REG_UNKNOWN : REG_HOME;
mazgch 21:c4d64830bf02 172 }
mazgch 21:c4d64830bf02 173 } else {
mazgch 21:c4d64830bf02 174 // GSM/UMTS Specific -------------------------------------------
mazgch 21:c4d64830bf02 175 // +CREG: <n>, <stat>[,<lac>,<ci>[,AcT]]
mazgch 21:c4d64830bf02 176 b = 255;
mazgch 54:7ba8e4c218e2 177 r = sscanf(cmd, "CREG: %*d,%d,\"%X\",\"%X\",%d",&a,&b,&c,&d);
mazgch 54:7ba8e4c218e2 178 if (r >= 1) {
mazgch 21:c4d64830bf02 179 // network status
mazgch 31:a0bed6c1e05d 180 if (a == 0) _net.reg = REG_NONE; // 0: not registered, home network
mazgch 31:a0bed6c1e05d 181 else if (a == 1) _net.reg = REG_HOME; // 1: registered, home network
mazgch 31:a0bed6c1e05d 182 else if (a == 2) _net.reg = REG_NONE; // 2: not registered, but MT is currently searching a new operator to register to
mazgch 31:a0bed6c1e05d 183 else if (a == 3) _net.reg = REG_DENIED; // 3: registration denied
mazgch 31:a0bed6c1e05d 184 else if (a == 4) _net.reg = REG_UNKNOWN; // 4: unknown
mazgch 31:a0bed6c1e05d 185 else if (a == 5) _net.reg = REG_ROAMING; // 5: registered, roaming
mazgch 54:7ba8e4c218e2 186 if ((r >= 2) && (b != 0xFFFF)) _net.lac = b; // location area code
mazgch 54:7ba8e4c218e2 187 if ((r >= 3) && (c != 0xFFFFFFFF)) _net.ci = c; // cell ID
mazgch 21:c4d64830bf02 188 // access technology
mazgch 54:7ba8e4c218e2 189 if (r >= 4) {
mazgch 54:7ba8e4c218e2 190 if (d == 0) _net.act = ACT_GSM; // 0: GSM
mazgch 54:7ba8e4c218e2 191 else if (d == 1) _net.act = ACT_GSM; // 1: GSM COMPACT
mazgch 54:7ba8e4c218e2 192 else if (d == 2) _net.act = ACT_UTRAN; // 2: UTRAN
mazgch 54:7ba8e4c218e2 193 else if (d == 3) _net.act = ACT_EDGE; // 3: GSM with EDGE availability
mazgch 54:7ba8e4c218e2 194 else if (d == 4) _net.act = ACT_UTRAN; // 4: UTRAN with HSDPA availability
mazgch 54:7ba8e4c218e2 195 else if (d == 5) _net.act = ACT_UTRAN; // 5: UTRAN with HSUPA availability
mazgch 54:7ba8e4c218e2 196 else if (d == 6) _net.act = ACT_UTRAN; // 6: UTRAN with HSDPA and HSUPA availability
mazgch 54:7ba8e4c218e2 197 }
mazgch 54:7ba8e4c218e2 198
mazgch 21:c4d64830bf02 199 // +UUPSDD: <profile_id>
mazgch 21:c4d64830bf02 200 } else if (sscanf(cmd, "UUPSDD: %d",&a) == 1) {
mazgch 31:a0bed6c1e05d 201 if (*PROFILE == a) _ip = NOIP;
mazgch 21:c4d64830bf02 202 }
mazgch 21:c4d64830bf02 203 }
mazgch 21:c4d64830bf02 204 }
mazgch 21:c4d64830bf02 205 if (cb) {
mazgch 21:c4d64830bf02 206 int len = LENGTH(ret);
mazgch 21:c4d64830bf02 207 int ret = cb(type, buf, len, param);
mazgch 21:c4d64830bf02 208 if (WAIT != ret)
mazgch 21:c4d64830bf02 209 return ret;
mazgch 21:c4d64830bf02 210 }
mazgch 21:c4d64830bf02 211 }
mazgch 21:c4d64830bf02 212 // relax a bit
mazgch 74:208e3e32d263 213 RELAX_MS(10);
mazgch 21:c4d64830bf02 214 }
mazgch 66:69072b3c5bca 215 while ((timeout_ms == TIMEOUT_BLOCKING) ||
mazgch 66:69072b3c5bca 216 (timer.read_ms() < timeout_ms));
mazgch 21:c4d64830bf02 217 timer.stop();
mazgch 21:c4d64830bf02 218 timer.reset();
mazgch 21:c4d64830bf02 219 return WAIT;
mazgch 21:c4d64830bf02 220 }
mazgch 21:c4d64830bf02 221
mazgch 31:a0bed6c1e05d 222 int MDMParser::_cbString(int type, const char* buf, int len, char* str)
mazgch 21:c4d64830bf02 223 {
mazgch 37:cc3433329d66 224 if (str && (type == TYPE_UNKNOWN)) {
mazgch 31:a0bed6c1e05d 225 if (sscanf(buf, "\r\n%s\r\n", str) == 1)
mazgch 31:a0bed6c1e05d 226 /*nothing*/;
mazgch 21:c4d64830bf02 227 }
mazgch 21:c4d64830bf02 228 return WAIT;
mazgch 21:c4d64830bf02 229 }
mazgch 21:c4d64830bf02 230
mazgch 31:a0bed6c1e05d 231 int MDMParser::_cbInt(int type, const char* buf, int len, int* val)
mazgch 31:a0bed6c1e05d 232 {
mazgch 37:cc3433329d66 233 if (val && (type == TYPE_UNKNOWN)) {
mazgch 31:a0bed6c1e05d 234 if (sscanf(buf, "\r\n%d\r\n", val) == 1)
mazgch 31:a0bed6c1e05d 235 /*nothing*/;
mazgch 31:a0bed6c1e05d 236 }
mazgch 31:a0bed6c1e05d 237 return WAIT;
mazgch 31:a0bed6c1e05d 238 }
mazgch 31:a0bed6c1e05d 239
mazgch 31:a0bed6c1e05d 240 // ----------------------------------------------------------------
mazgch 31:a0bed6c1e05d 241
mazgch 57:869bd35f44cc 242 bool MDMParser::connect(
mazgch 57:869bd35f44cc 243 const char* simpin,
mazgch 57:869bd35f44cc 244 const char* apn, const char* username, const char* password,
mazgch 74:208e3e32d263 245 PinName pn)
mazgch 57:869bd35f44cc 246 {
mazgch 57:869bd35f44cc 247 DevStatus devStatus = {};
mazgch 74:208e3e32d263 248 bool mdmOk = init(simpin, &devStatus, pn);
mazgch 74:208e3e32d263 249 #ifdef MDM_DEBUG
mazgch 74:208e3e32d263 250 if (_debugLevel >= 1) dumpDevStatus(&devStatus);
mazgch 74:208e3e32d263 251 #endif
mazgch 57:869bd35f44cc 252 if (!mdmOk)
mazgch 57:869bd35f44cc 253 return false;
mazgch 57:869bd35f44cc 254 // wait until we are connected
mazgch 74:208e3e32d263 255 int i = 180;
mazgch 57:869bd35f44cc 256 NetStatus netStatus = {};
mazgch 74:208e3e32d263 257 INFO("Modem::register\r\n");
mazgch 57:869bd35f44cc 258 while (!checkNetStatus(&netStatus))
mazgch 57:869bd35f44cc 259 {
mazgch 57:869bd35f44cc 260 if ((netStatus.reg == REG_DENIED) || (i == 0))
mazgch 57:869bd35f44cc 261 break;;
mazgch 57:869bd35f44cc 262 i --;
mazgch 74:208e3e32d263 263 RELAX_MS(1000);
mazgch 57:869bd35f44cc 264 }
mazgch 74:208e3e32d263 265 #ifdef MDM_DEBUG
mazgch 74:208e3e32d263 266 if (_debugLevel >= 1) dumpNetStatus(&netStatus);
mazgch 74:208e3e32d263 267 #endif
mazgch 57:869bd35f44cc 268 if ((netStatus.reg == REG_DENIED) || (i == 0))
mazgch 57:869bd35f44cc 269 return false;
mazgch 57:869bd35f44cc 270 IP ip = join(apn,username,password);
mazgch 74:208e3e32d263 271 #ifdef MDM_DEBUG
mazgch 74:208e3e32d263 272 if (_debugLevel >= 1) dumpIp(ip);
mazgch 74:208e3e32d263 273 #endif
mazgch 57:869bd35f44cc 274 if (ip == NOIP)
mazgch 57:869bd35f44cc 275 return false;
mazgch 57:869bd35f44cc 276 return true;
mazgch 57:869bd35f44cc 277 }
mazgch 57:869bd35f44cc 278
mazgch 74:208e3e32d263 279 bool MDMParser::init(const char* simpin, DevStatus* status, PinName pn)
mazgch 21:c4d64830bf02 280 {
mazgch 74:208e3e32d263 281 int i = 10;
mazgch 74:208e3e32d263 282 if (pn != NC) {
mazgch 74:208e3e32d263 283 INFO("Modem::wakeup\r\n");
mazgch 74:208e3e32d263 284 DigitalOut pin(pn, 1);
mazgch 74:208e3e32d263 285 while (i--) {
mazgch 74:208e3e32d263 286 pin = 0;
mazgch 74:208e3e32d263 287 RELAX_MS(5); // SARA-G/U
mazgch 74:208e3e32d263 288 pin = 1;
mazgch 74:208e3e32d263 289 RELAX_MS(100);
mazgch 74:208e3e32d263 290 // check interface and disable local echo
mazgch 74:208e3e32d263 291 sendFormated("AT\r\n");
mazgch 74:208e3e32d263 292 if(RESP_OK == waitFinalResp(NULL,NULL,500))
mazgch 74:208e3e32d263 293 break;
mazgch 74:208e3e32d263 294 }
mazgch 74:208e3e32d263 295 if (i < 0)
mazgch 74:208e3e32d263 296 return false;
mazgch 21:c4d64830bf02 297 }
mazgch 74:208e3e32d263 298 INFO("Modem::init\r\n");
mazgch 21:c4d64830bf02 299 // echo off
mazgch 21:c4d64830bf02 300 sendFormated("AT E0\r\n");
mazgch 52:8071747a7cb3 301 if(RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 302 return false;
mazgch 21:c4d64830bf02 303 // enable verbose error messages
mazgch 21:c4d64830bf02 304 sendFormated("AT+CMEE=2\r\n");
mazgch 52:8071747a7cb3 305 if(RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 306 return false;
mazgch 21:c4d64830bf02 307 // set baud rate
mazgch 21:c4d64830bf02 308 sendFormated("AT+IPR=115200\r\n");
mazgch 52:8071747a7cb3 309 if (RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 310 return false;
mazgch 74:208e3e32d263 311 RELAX_MS(40);
mazgch 21:c4d64830bf02 312 // identify the module
mazgch 21:c4d64830bf02 313 sendFormated("ATI\r\n");
mazgch 52:8071747a7cb3 314 if (RESP_OK != waitFinalResp(_cbATI, &_dev.dev))
mazgch 21:c4d64830bf02 315 return false;
mazgch 32:8f12ac182bbb 316 if (_dev.dev == DEV_UNKNOWN)
mazgch 21:c4d64830bf02 317 return false;
mazgch 32:8f12ac182bbb 318 // device specific init
mazgch 32:8f12ac182bbb 319 if (_dev.dev == DEV_LISA_C200) {
mazgch 32:8f12ac182bbb 320 // get the manufacturer
mazgch 32:8f12ac182bbb 321 sendFormated("AT+GMI\r\n");
mazgch 52:8071747a7cb3 322 if (RESP_OK != waitFinalResp(_cbString, _dev.manu))
mazgch 32:8f12ac182bbb 323 return false;
mazgch 32:8f12ac182bbb 324 // get the model identification
mazgch 32:8f12ac182bbb 325 sendFormated("AT+GMM\r\n");
mazgch 52:8071747a7cb3 326 if (RESP_OK != waitFinalResp(_cbString, _dev.model))
mazgch 32:8f12ac182bbb 327 return false;
mazgch 32:8f12ac182bbb 328 // get the sw version
mazgch 32:8f12ac182bbb 329 sendFormated("AT+GMR\r\n");
mazgch 52:8071747a7cb3 330 if (RESP_OK != waitFinalResp(_cbString, _dev.ver))
mazgch 32:8f12ac182bbb 331 return false;
mazgch 21:c4d64830bf02 332 // Return the pseudo ESN or MEID
mazgch 21:c4d64830bf02 333 sendFormated("AT+GSN\r\n");
mazgch 52:8071747a7cb3 334 if (RESP_OK != waitFinalResp(_cbString, _dev.meid))
mazgch 26:07be5faf8925 335 return false;
mazgch 50:d76aece8038f 336 #if 0
mazgch 50:d76aece8038f 337 // enable power saving
mazgch 50:d76aece8038f 338 if (_dev.lpm != LPM_DISABLED) {
mazgch 50:d76aece8038f 339 // enable power saving (requires flow control, cts at least)
mazgch 50:d76aece8038f 340 sendFormated("AT+UPSV=1,1280\r\n");
mazgch 52:8071747a7cb3 341 if (RESP_OK != waitFinalResp())
mazgch 50:d76aece8038f 342 return false;
mazgch 50:d76aece8038f 343 _dev.lpm = LPM_ACTIVE;
mazgch 50:d76aece8038f 344 }
mazgch 50:d76aece8038f 345 #endif
mazgch 26:07be5faf8925 346 } else {
mazgch 32:8f12ac182bbb 347 if (_dev.dev == DEV_LISA_U200) {
mazgch 35:9275215a3a5b 348 // enable the network identification feature
mazgch 21:c4d64830bf02 349 sendFormated("AT+UGPIOC=20,2\r\n");
mazgch 52:8071747a7cb3 350 if (RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 351 return false;
mazgch 21:c4d64830bf02 352 } else {
mazgch 35:9275215a3a5b 353 // enable the network identification feature
mazgch 21:c4d64830bf02 354 sendFormated("AT+UGPIOC=16,2\r\n");
mazgch 52:8071747a7cb3 355 if (RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 356 return false;
mazgch 21:c4d64830bf02 357 }
mazgch 21:c4d64830bf02 358 // check the sim card
mazgch 31:a0bed6c1e05d 359 for (int i = 0; (i < 5) && (_dev.sim != SIM_READY); i++) {
mazgch 21:c4d64830bf02 360 sendFormated("AT+CPIN?\r\n");
mazgch 31:a0bed6c1e05d 361 int ret = waitFinalResp(_cbCPIN, &_dev.sim);
mazgch 62:a02f026bdd7c 362 // having an error here is ok (sim may still be initializing)
mazgch 52:8071747a7cb3 363 if ((RESP_OK != ret) && (RESP_ERROR != ret))
mazgch 21:c4d64830bf02 364 return false;
mazgch 31:a0bed6c1e05d 365 // Enter PIN if needed
mazgch 31:a0bed6c1e05d 366 if (_dev.sim == SIM_PIN) {
mazgch 57:869bd35f44cc 367 if (!simpin) {
mazgch 74:208e3e32d263 368 INFO("SIM PIN not available\r\n");
mazgch 31:a0bed6c1e05d 369 return false;
mazgch 31:a0bed6c1e05d 370 }
mazgch 57:869bd35f44cc 371 sendFormated("AT+CPIN=%s\r\n", simpin);
mazgch 52:8071747a7cb3 372 if (RESP_OK != waitFinalResp(_cbCPIN, &_dev.sim))
mazgch 31:a0bed6c1e05d 373 return false;
mazgch 62:a02f026bdd7c 374 } else if (_dev.sim != SIM_READY) {
mazgch 74:208e3e32d263 375 RELAX_MS(1000);
mazgch 62:a02f026bdd7c 376 }
mazgch 21:c4d64830bf02 377 }
mazgch 31:a0bed6c1e05d 378 if (_dev.sim != SIM_READY)
mazgch 21:c4d64830bf02 379 return false;
mazgch 32:8f12ac182bbb 380 // get the manufacturer
mazgch 32:8f12ac182bbb 381 sendFormated("AT+CGMI\r\n");
mazgch 52:8071747a7cb3 382 if (RESP_OK != waitFinalResp(_cbString, _dev.manu))
mazgch 32:8f12ac182bbb 383 return false;
mazgch 32:8f12ac182bbb 384 // get the model identification
mazgch 32:8f12ac182bbb 385 sendFormated("AT+CGMM\r\n");
mazgch 52:8071747a7cb3 386 if (RESP_OK != waitFinalResp(_cbString, _dev.model))
mazgch 32:8f12ac182bbb 387 return false;
mazgch 32:8f12ac182bbb 388 // get the
mazgch 32:8f12ac182bbb 389 sendFormated("AT+CGMR\r\n");
mazgch 52:8071747a7cb3 390 if (RESP_OK != waitFinalResp(_cbString, _dev.ver))
mazgch 32:8f12ac182bbb 391 return false;
mazgch 21:c4d64830bf02 392 // Returns the ICCID (Integrated Circuit Card ID) of the SIM-card.
mazgch 21:c4d64830bf02 393 // ICCID is a serial number identifying the SIM.
mazgch 21:c4d64830bf02 394 sendFormated("AT+CCID\r\n");
mazgch 52:8071747a7cb3 395 if (RESP_OK != waitFinalResp(_cbCCID, _dev.ccid))
mazgch 21:c4d64830bf02 396 return false;
mazgch 21:c4d64830bf02 397 // Returns the product serial number, IMEI (International Mobile Equipment Identity)
mazgch 21:c4d64830bf02 398 sendFormated("AT+CGSN\r\n");
mazgch 52:8071747a7cb3 399 if (RESP_OK != waitFinalResp(_cbString, _dev.imei))
mazgch 21:c4d64830bf02 400 return false;
mazgch 50:d76aece8038f 401 #if 0
mazgch 21:c4d64830bf02 402 // Configure New message indication
mazgch 50:d76aece8038f 403 sendFormated("AT+CNMI=2,1,0,0,0\r\n");
mazgch 52:8071747a7cb3 404 if (RESP_OK != waitFinalResp())
mazgch 50:d76aece8038f 405 return false;
mazgch 50:d76aece8038f 406 #endif
mazgch 50:d76aece8038f 407 // enable power saving
mazgch 50:d76aece8038f 408 if (_dev.lpm != LPM_DISABLED) {
mazgch 50:d76aece8038f 409 // enable power saving (requires flow control, cts at least)
mazgch 50:d76aece8038f 410 sendFormated("AT+UPSV=1\r\n");
mazgch 52:8071747a7cb3 411 if (RESP_OK != waitFinalResp())
mazgch 50:d76aece8038f 412 return false;
mazgch 50:d76aece8038f 413 _dev.lpm = LPM_ACTIVE;
mazgch 50:d76aece8038f 414 }
mazgch 21:c4d64830bf02 415 }
mazgch 31:a0bed6c1e05d 416 // Setup SMS in text mode
mazgch 31:a0bed6c1e05d 417 sendFormated("AT+CMGF=1\r\n");
mazgch 52:8071747a7cb3 418 if (RESP_OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 419 return false;
mazgch 31:a0bed6c1e05d 420 // setup new message indication
mazgch 31:a0bed6c1e05d 421 sendFormated("AT+CNMI=1,1\r\n");
mazgch 52:8071747a7cb3 422 if (RESP_OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 423 return false;
mazgch 21:c4d64830bf02 424 // Request IMSI (International Mobile Subscriber Identification)
mazgch 21:c4d64830bf02 425 sendFormated("AT+CIMI\r\n");
mazgch 52:8071747a7cb3 426 if (RESP_OK != waitFinalResp(_cbString, _dev.imsi))
mazgch 21:c4d64830bf02 427 return false;
mazgch 71:041de9a6d93c 428 // enable the network registration unsolicited result code
mazgch 71:041de9a6d93c 429 sendFormated("AT+CREG=%d\r\n", (_dev.dev == DEV_LISA_C200) ? 1 : 2);
mazgch 71:041de9a6d93c 430 if (RESP_OK != waitFinalResp())
mazgch 71:041de9a6d93c 431 return false;
mazgch 28:4d9509e3b1cf 432 if (status)
mazgch 31:a0bed6c1e05d 433 memcpy(status, &_dev, sizeof(DevStatus));
mazgch 31:a0bed6c1e05d 434 return true;
mazgch 31:a0bed6c1e05d 435 }
mazgch 31:a0bed6c1e05d 436
mazgch 74:208e3e32d263 437 bool MDMParser::powerOff(void)
mazgch 74:208e3e32d263 438 {
mazgch 74:208e3e32d263 439 INFO("Modem::powerOff\r\n");
mazgch 74:208e3e32d263 440 sendFormated("AT+CPWROFF\r\n");
mazgch 74:208e3e32d263 441 if (RESP_OK != waitFinalResp(NULL,NULL,120*1000))
mazgch 74:208e3e32d263 442 return false;
mazgch 74:208e3e32d263 443 return true;
mazgch 74:208e3e32d263 444 }
mazgch 74:208e3e32d263 445
mazgch 32:8f12ac182bbb 446 int MDMParser::_cbATI(int type, const char* buf, int len, Dev* dev)
mazgch 31:a0bed6c1e05d 447 {
mazgch 37:cc3433329d66 448 if ((type == TYPE_UNKNOWN) && dev) {
mazgch 31:a0bed6c1e05d 449 if (strstr(buf, "SARA-G350")) {
mazgch 32:8f12ac182bbb 450 *dev = DEV_SARA_G350;
mazgch 32:8f12ac182bbb 451 /*TRACE("Identified Device: SARA-G350 2G\\n")*/;
mazgch 31:a0bed6c1e05d 452 } else if (strstr(buf, "LISA-U200")) {
mazgch 32:8f12ac182bbb 453 *dev = DEV_LISA_U200;
mazgch 32:8f12ac182bbb 454 /*TRACE("Identified Device: LISA-U200 2G/3G\r\n")*/;
mazgch 31:a0bed6c1e05d 455 } else if (strstr(buf, "LISA-C200")) {
mazgch 32:8f12ac182bbb 456 *dev= DEV_LISA_C200;
mazgch 32:8f12ac182bbb 457 /*TRACE("Identified Device: LISA-C200 CDMA\r\n")*/;
mazgch 31:a0bed6c1e05d 458 }
mazgch 28:4d9509e3b1cf 459 }
mazgch 31:a0bed6c1e05d 460 return WAIT;
mazgch 31:a0bed6c1e05d 461 }
mazgch 31:a0bed6c1e05d 462
mazgch 31:a0bed6c1e05d 463 int MDMParser::_cbCPIN(int type, const char* buf, int len, Sim* sim)
mazgch 31:a0bed6c1e05d 464 {
mazgch 31:a0bed6c1e05d 465 if ((type == TYPE_PLUS) && sim){
mazgch 31:a0bed6c1e05d 466 char s[16];
mazgch 31:a0bed6c1e05d 467 if (sscanf(buf, "\r\n+CPIN: %[^\r]\r<n", s) >= 1) {
mazgch 31:a0bed6c1e05d 468 *sim = (strcmp("READY", s) == 0) ? SIM_READY : SIM_PIN;
mazgch 31:a0bed6c1e05d 469 }
mazgch 31:a0bed6c1e05d 470 }
mazgch 31:a0bed6c1e05d 471 return WAIT;
mazgch 21:c4d64830bf02 472 }
mazgch 21:c4d64830bf02 473
mazgch 26:07be5faf8925 474 int MDMParser::_cbCCID(int type, const char* buf, int len, char* ccid)
mazgch 26:07be5faf8925 475 {
mazgch 26:07be5faf8925 476 if ((type == TYPE_PLUS) && ccid){
mazgch 26:07be5faf8925 477 if (sscanf(buf, "\r\n+CCID: %[^\r]\r\n", ccid) == 1)
mazgch 31:a0bed6c1e05d 478 /*TRACE("Got CCID: %s\r\n", ccid)*/;
mazgch 26:07be5faf8925 479 }
mazgch 26:07be5faf8925 480 return WAIT;
mazgch 26:07be5faf8925 481 }
mazgch 26:07be5faf8925 482
mazgch 28:4d9509e3b1cf 483 bool MDMParser::checkNetStatus(NetStatus* status /*= NULL*/)
mazgch 21:c4d64830bf02 484 {
mazgch 21:c4d64830bf02 485 // check registration
mazgch 21:c4d64830bf02 486 sendFormated("AT+CREG?\r\n");
mazgch 52:8071747a7cb3 487 if (RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 488 return false;
mazgch 31:a0bed6c1e05d 489 if ((_net.reg != REG_ROAMING) && (_net.reg != REG_HOME))
mazgch 21:c4d64830bf02 490 return false;
mazgch 21:c4d64830bf02 491 // check modem specific status messages
mazgch 32:8f12ac182bbb 492 if (_dev.dev == DEV_LISA_C200) {
mazgch 21:c4d64830bf02 493 sendFormated("AT+CSS?\r\n");
mazgch 52:8071747a7cb3 494 if (RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 495 return false;
mazgch 32:8f12ac182bbb 496 // get the Telephone number
mazgch 32:8f12ac182bbb 497 sendFormated("AT$MDN?\r\n");
mazgch 52:8071747a7cb3 498 if (RESP_OK != waitFinalResp(_cbString, _net.num))
mazgch 32:8f12ac182bbb 499 return false;
mazgch 32:8f12ac182bbb 500 // check if we have a Mobile Directory Number
mazgch 33:fb8fb5021b09 501 if (memcmp(_net.num, "0000", 4) == 0)
mazgch 32:8f12ac182bbb 502 return false;
mazgch 32:8f12ac182bbb 503 // get the the Network access identifier string
mazgch 32:8f12ac182bbb 504 char nai[64];
mazgch 32:8f12ac182bbb 505 sendFormated("AT$QCMIPNAI?\r\n");
mazgch 52:8071747a7cb3 506 if (RESP_OK != waitFinalResp(_cbString, nai))
mazgch 32:8f12ac182bbb 507 return false;
mazgch 31:a0bed6c1e05d 508 } else {
mazgch 31:a0bed6c1e05d 509 // check GPRS attach status
mazgch 31:a0bed6c1e05d 510 sendFormated("AT+CGATT?\r\n");
mazgch 72:d1e943ad6558 511 if (RESP_OK != waitFinalResp(_cbCGATT, &_net.gprs))
mazgch 31:a0bed6c1e05d 512 return false;
mazgch 21:c4d64830bf02 513 // check operator selection
mazgch 21:c4d64830bf02 514 sendFormated("AT+COPS?\r\n");
mazgch 72:d1e943ad6558 515 if (RESP_OK != waitFinalResp(_cbCOPS, &_net))
mazgch 21:c4d64830bf02 516 return false;
mazgch 21:c4d64830bf02 517 // Returns the MSISDNs related to this subscriber
mazgch 21:c4d64830bf02 518 sendFormated("AT+CNUM\r\n");
mazgch 52:8071747a7cb3 519 if (RESP_OK != waitFinalResp(_cbCNUM, _net.num))
mazgch 21:c4d64830bf02 520 return false;
mazgch 21:c4d64830bf02 521 }
mazgch 21:c4d64830bf02 522 // Returns the signal strength indication
mazgch 21:c4d64830bf02 523 sendFormated("AT+CSQ\r\n");
mazgch 54:7ba8e4c218e2 524 if (RESP_OK != waitFinalResp(_cbCSQ, &_net))
mazgch 21:c4d64830bf02 525 return false;
mazgch 28:4d9509e3b1cf 526 if (status) {
mazgch 31:a0bed6c1e05d 527 memcpy(status, &_net, sizeof(NetStatus));
mazgch 25:4045d02e44f1 528 }
mazgch 21:c4d64830bf02 529 return true;
mazgch 21:c4d64830bf02 530 }
mazgch 21:c4d64830bf02 531
mazgch 72:d1e943ad6558 532 int MDMParser::_cbCGATT(int type, const char* buf, int len, Gprs* gprs)
mazgch 31:a0bed6c1e05d 533 {
mazgch 72:d1e943ad6558 534 if ((type == TYPE_PLUS) && gprs){
mazgch 72:d1e943ad6558 535 int i;
mazgch 72:d1e943ad6558 536 if (sscanf(buf, "\r\n+CGATT: %d\r\n", &i) == 1) {
mazgch 72:d1e943ad6558 537 if (i == 0) *gprs = GPRS_DETACHED;
mazgch 72:d1e943ad6558 538 else if (i == 1) *gprs = GPRS_ATTACHED;
mazgch 72:d1e943ad6558 539 }
mazgch 31:a0bed6c1e05d 540 }
mazgch 31:a0bed6c1e05d 541 return WAIT;
mazgch 31:a0bed6c1e05d 542 }
mazgch 31:a0bed6c1e05d 543
mazgch 31:a0bed6c1e05d 544 int MDMParser::_cbCOPS(int type, const char* buf, int len, NetStatus* status)
mazgch 31:a0bed6c1e05d 545 {
mazgch 31:a0bed6c1e05d 546 if ((type == TYPE_PLUS) && status){
mazgch 31:a0bed6c1e05d 547 int act = 99;
mazgch 31:a0bed6c1e05d 548 // +COPS: <mode>[,<format>,<oper>[,<AcT>]]
mazgch 31:a0bed6c1e05d 549 if (sscanf(buf, "\r\n+COPS: %*d,%*d,\"%[^\"]\",%d",status->opr,&act) >= 1) {
mazgch 31:a0bed6c1e05d 550 if (act == 0) status->act = ACT_GSM; // 0: GSM,
mazgch 31:a0bed6c1e05d 551 else if (act == 2) status->act = ACT_UTRAN; // 2: UTRAN
mazgch 31:a0bed6c1e05d 552 }
mazgch 31:a0bed6c1e05d 553 }
mazgch 31:a0bed6c1e05d 554 return WAIT;
mazgch 31:a0bed6c1e05d 555 }
mazgch 31:a0bed6c1e05d 556
mazgch 31:a0bed6c1e05d 557 int MDMParser::_cbCNUM(int type, const char* buf, int len, char* num)
mazgch 31:a0bed6c1e05d 558 {
mazgch 31:a0bed6c1e05d 559 if ((type == TYPE_PLUS) && num){
mazgch 31:a0bed6c1e05d 560 int a;
mazgch 31:a0bed6c1e05d 561 if ((sscanf(buf, "\r\n+CNUM: \"My Number\",\"%31[^\"]\",%d", num, &a) == 2) &&
mazgch 31:a0bed6c1e05d 562 ((a == 129) || (a == 145))) {
mazgch 31:a0bed6c1e05d 563 }
mazgch 31:a0bed6c1e05d 564 }
mazgch 31:a0bed6c1e05d 565 return WAIT;
mazgch 31:a0bed6c1e05d 566 }
mazgch 31:a0bed6c1e05d 567
mazgch 54:7ba8e4c218e2 568 int MDMParser::_cbCSQ(int type, const char* buf, int len, NetStatus* status)
mazgch 31:a0bed6c1e05d 569 {
mazgch 54:7ba8e4c218e2 570 if ((type == TYPE_PLUS) && status){
mazgch 54:7ba8e4c218e2 571 int a,b;
mazgch 54:7ba8e4c218e2 572 char _ber[] = { 49, 43, 37, 25, 19, 13, 7, 0 }; // see 3GPP TS 45.008 [20] subclause 8.2.4
mazgch 31:a0bed6c1e05d 573 // +CSQ: <rssi>,<qual>
mazgch 54:7ba8e4c218e2 574 if (sscanf(buf, "\r\n+CSQ: %d,%d",&a,&b) == 2) {
mazgch 54:7ba8e4c218e2 575 if (a != 99) status->rssi = -113 + 2*a; // 0: -113 1: -111 ... 30: -53 dBm with 2 dBm steps
mazgch 54:7ba8e4c218e2 576 if ((b != 99) && (b < sizeof(_ber))) status->ber = _ber[b]; //
mazgch 31:a0bed6c1e05d 577 }
mazgch 31:a0bed6c1e05d 578 }
mazgch 31:a0bed6c1e05d 579 return WAIT;
mazgch 31:a0bed6c1e05d 580 }
mazgch 21:c4d64830bf02 581
mazgch 21:c4d64830bf02 582 // ----------------------------------------------------------------
mazgch 21:c4d64830bf02 583 // internet connection
mazgch 21:c4d64830bf02 584
mazgch 57:869bd35f44cc 585 MDMParser::IP MDMParser::join(const char* apn /*= NULL*/, const char* username /*= NULL*/, const char* password /*= NULL*/)
mazgch 21:c4d64830bf02 586 {
mazgch 74:208e3e32d263 587 TRACE("Modem::join\r\n");
mazgch 32:8f12ac182bbb 588 _ip = NOIP;
mazgch 32:8f12ac182bbb 589 if (_dev.dev == DEV_LISA_C200) {
mazgch 32:8f12ac182bbb 590 // TODO: is there something to do here?
mazgch 59:382695f1ce85 591 #if 0
mazgch 21:c4d64830bf02 592 //Get local IP address
mazgch 21:c4d64830bf02 593 sendFormated("AT+CMIP?\r\n");
mazgch 52:8071747a7cb3 594 if (RESP_OK != waitFinalResp(_cbCMIP, &_ip))
mazgch 31:a0bed6c1e05d 595 return NOIP;
mazgch 59:382695f1ce85 596 #else
mazgch 59:382695f1ce85 597 return 0x01010101; // a fake IP
mazgch 59:382695f1ce85 598 #endif
mazgch 21:c4d64830bf02 599 } else {
mazgch 21:c4d64830bf02 600 // check gprs attach status
mazgch 72:d1e943ad6558 601 sendFormated("AT+CGATT=1\r\n");
mazgch 74:208e3e32d263 602 if (RESP_OK != waitFinalResp(NULL,NULL,3*60*1000))
mazgch 31:a0bed6c1e05d 603 return NOIP;
mazgch 31:a0bed6c1e05d 604
mazgch 31:a0bed6c1e05d 605 // Check the profile
mazgch 31:a0bed6c1e05d 606 int a = 0;
mazgch 31:a0bed6c1e05d 607 sendFormated("AT+UPSND=" PROFILE ",8\r\n");
mazgch 52:8071747a7cb3 608 if (RESP_OK != waitFinalResp(_cbUPSND, &a))
mazgch 31:a0bed6c1e05d 609 return NOIP;
mazgch 31:a0bed6c1e05d 610 if (a == 1) {
mazgch 31:a0bed6c1e05d 611 // disconnect the profile already if it is connected
mazgch 31:a0bed6c1e05d 612 sendFormated("AT+UPSDA=" PROFILE ",4\r\n");
mazgch 58:e38a2e942fbb 613 if (RESP_OK != waitFinalResp(NULL,NULL,40*1000))
mazgch 31:a0bed6c1e05d 614 return NOIP;;
mazgch 31:a0bed6c1e05d 615 }
mazgch 31:a0bed6c1e05d 616 // Set up the APN
mazgch 21:c4d64830bf02 617 if (apn) {
mazgch 21:c4d64830bf02 618 sendFormated("AT+UPSD=" PROFILE ",1,\"%s\"\r\n", apn);
mazgch 52:8071747a7cb3 619 if (RESP_OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 620 return NOIP;
mazgch 21:c4d64830bf02 621 }
mazgch 57:869bd35f44cc 622 if (username) {
mazgch 57:869bd35f44cc 623 sendFormated("AT+UPSD=" PROFILE ",2,\"%s\"\r\n", username);
mazgch 52:8071747a7cb3 624 if (RESP_OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 625 return NOIP;
mazgch 21:c4d64830bf02 626 }
mazgch 21:c4d64830bf02 627 if (password) {
mazgch 21:c4d64830bf02 628 sendFormated("AT+UPSD=" PROFILE ",3,\"%s\"\r\n", password);
mazgch 52:8071747a7cb3 629 if (RESP_OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 630 return NOIP;
mazgch 21:c4d64830bf02 631 }
mazgch 21:c4d64830bf02 632 // Set up the dynamic IP address assignment.
mazgch 21:c4d64830bf02 633 sendFormated("AT+UPSD=" PROFILE ",7,\"0.0.0.0\"\r\n");
mazgch 52:8071747a7cb3 634 if (RESP_OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 635 return NOIP;
mazgch 21:c4d64830bf02 636 // Activate the profile and make connection
mazgch 21:c4d64830bf02 637 sendFormated("AT+UPSDA=" PROFILE ",3\r\n");
mazgch 74:208e3e32d263 638 if (RESP_OK != waitFinalResp(NULL,NULL,150*1000)) {
mazgch 74:208e3e32d263 639 INFO("Your modem APN/password/username may be wrong\r\n");
mazgch 31:a0bed6c1e05d 640 return NOIP;
mazgch 74:208e3e32d263 641 }
mazgch 21:c4d64830bf02 642 //Get local IP address
mazgch 21:c4d64830bf02 643 sendFormated("AT+UPSND=" PROFILE ",0\r\n");
mazgch 52:8071747a7cb3 644 if (RESP_OK != waitFinalResp(_cbUPSND, &_ip))
mazgch 31:a0bed6c1e05d 645 return NOIP;
mazgch 31:a0bed6c1e05d 646 }
mazgch 32:8f12ac182bbb 647 return _ip;
mazgch 31:a0bed6c1e05d 648 }
mazgch 31:a0bed6c1e05d 649
mazgch 32:8f12ac182bbb 650 int MDMParser::_cbCMIP(int type, const char* buf, int len, IP* ip)
mazgch 32:8f12ac182bbb 651 {
mazgch 32:8f12ac182bbb 652 if ((type == TYPE_PLUS) && ip) {
mazgch 32:8f12ac182bbb 653 int a,b,c,d;
mazgch 32:8f12ac182bbb 654 if (sscanf(buf, "\r\n+CMIP: " IPSTR, &a,&b,&c,&d) == 4)
mazgch 32:8f12ac182bbb 655 *ip = IPADR(a,b,c,d);
mazgch 32:8f12ac182bbb 656 }
mazgch 32:8f12ac182bbb 657 return WAIT;
mazgch 32:8f12ac182bbb 658 }
mazgch 32:8f12ac182bbb 659
mazgch 31:a0bed6c1e05d 660 int MDMParser::_cbUPSND(int type, const char* buf, int len, int* act)
mazgch 31:a0bed6c1e05d 661 {
mazgch 31:a0bed6c1e05d 662 if ((type == TYPE_PLUS) && act) {
mazgch 31:a0bed6c1e05d 663 if (sscanf(buf, "\r\n+UPSND: %*d,%*d,%d", act) == 1)
mazgch 31:a0bed6c1e05d 664 /*nothing*/;
mazgch 21:c4d64830bf02 665 }
mazgch 31:a0bed6c1e05d 666 return WAIT;
mazgch 31:a0bed6c1e05d 667 }
mazgch 31:a0bed6c1e05d 668
mazgch 31:a0bed6c1e05d 669 int MDMParser::_cbUPSND(int type, const char* buf, int len, IP* ip)
mazgch 31:a0bed6c1e05d 670 {
mazgch 31:a0bed6c1e05d 671 if ((type == TYPE_PLUS) && ip) {
mazgch 31:a0bed6c1e05d 672 int a,b,c,d;
mazgch 31:a0bed6c1e05d 673 // +UPSND=<profile_id>,<param_tag>[,<dynamic_param_val>]
mazgch 31:a0bed6c1e05d 674 if (sscanf(buf, "\r\n+UPSND: " PROFILE ",0,\"" IPSTR "\"", &a,&b,&c,&d) == 4)
mazgch 31:a0bed6c1e05d 675 *ip = IPADR(a,b,c,d);
mazgch 31:a0bed6c1e05d 676 }
mazgch 31:a0bed6c1e05d 677 return WAIT;
mazgch 31:a0bed6c1e05d 678 }
mazgch 31:a0bed6c1e05d 679
mazgch 31:a0bed6c1e05d 680 int MDMParser::_cbUDNSRN(int type, const char* buf, int len, IP* ip)
mazgch 31:a0bed6c1e05d 681 {
mazgch 31:a0bed6c1e05d 682 if ((type == TYPE_PLUS) && ip) {
mazgch 31:a0bed6c1e05d 683 int a,b,c,d;
mazgch 31:a0bed6c1e05d 684 if (sscanf(buf, "\r\n+UDNSRN: \""IPSTR"\"", &a,&b,&c,&d) == 4)
mazgch 31:a0bed6c1e05d 685 *ip = IPADR(a,b,c,d);
mazgch 31:a0bed6c1e05d 686 }
mazgch 31:a0bed6c1e05d 687 return WAIT;
mazgch 21:c4d64830bf02 688 }
mazgch 21:c4d64830bf02 689
mazgch 21:c4d64830bf02 690 bool MDMParser::disconnect(void)
mazgch 21:c4d64830bf02 691 {
mazgch 31:a0bed6c1e05d 692 if (_ip == NOIP)
mazgch 21:c4d64830bf02 693 return true;
mazgch 74:208e3e32d263 694 INFO("Modem::disconnect\r\n");
mazgch 32:8f12ac182bbb 695 if (_dev.dev == DEV_LISA_C200) {
mazgch 32:8f12ac182bbb 696 // TODO: is there something to do here?
mazgch 21:c4d64830bf02 697 } else {
mazgch 21:c4d64830bf02 698 sendFormated("AT+UPSDA=" PROFILE ",4\r\n");
mazgch 52:8071747a7cb3 699 if (RESP_OK != waitFinalResp())
mazgch 32:8f12ac182bbb 700 return false;
mazgch 21:c4d64830bf02 701 }
mazgch 31:a0bed6c1e05d 702 _ip = NOIP;
mazgch 21:c4d64830bf02 703 return true;
mazgch 21:c4d64830bf02 704 }
mazgch 21:c4d64830bf02 705
mazgch 31:a0bed6c1e05d 706 MDMParser::IP MDMParser::gethostbyname(const char* host)
mazgch 21:c4d64830bf02 707 {
mazgch 31:a0bed6c1e05d 708 IP ip = NOIP;
mazgch 31:a0bed6c1e05d 709 int a,b,c,d;
mazgch 31:a0bed6c1e05d 710 if (sscanf(host, IPSTR, &a,&b,&c,&d) == 4)
mazgch 31:a0bed6c1e05d 711 ip = IPADR(a,b,c,d);
mazgch 31:a0bed6c1e05d 712 else {
mazgch 31:a0bed6c1e05d 713 sendFormated("AT+UDNSRN=0,\"%s\"\r\n", host);
mazgch 52:8071747a7cb3 714 if (RESP_OK != waitFinalResp(_cbUDNSRN, &ip))
mazgch 31:a0bed6c1e05d 715 return false;
mazgch 21:c4d64830bf02 716 }
mazgch 31:a0bed6c1e05d 717 return ip;
mazgch 21:c4d64830bf02 718 }
mazgch 21:c4d64830bf02 719
mazgch 21:c4d64830bf02 720 // ----------------------------------------------------------------
mazgch 21:c4d64830bf02 721 // sockets
mazgch 21:c4d64830bf02 722
mazgch 21:c4d64830bf02 723 int MDMParser::_cbUSOCR(int type, const char* buf, int len, int* socket)
mazgch 21:c4d64830bf02 724 {
mazgch 21:c4d64830bf02 725 if ((type == TYPE_PLUS) && socket) {
mazgch 21:c4d64830bf02 726 const char* p = strstr(buf,"+USOCR: ");
mazgch 21:c4d64830bf02 727 if (p)
mazgch 21:c4d64830bf02 728 *socket = atoi(p+8);
mazgch 21:c4d64830bf02 729 }
mazgch 21:c4d64830bf02 730 return WAIT;
mazgch 21:c4d64830bf02 731 }
mazgch 21:c4d64830bf02 732
mazgch 63:42cb563a25bc 733 int MDMParser::socketSocket(IpProtocol ipproto, int port)
mazgch 21:c4d64830bf02 734 {
mazgch 47:9a89e5195721 735 TRACE("socketSocket(%d)\r\n", ipproto);
mazgch 21:c4d64830bf02 736 if(ipproto == IPPROTO_TCP) {
mazgch 63:42cb563a25bc 737 sendFormated("AT+USOCR=6\r\n");
mazgch 63:42cb563a25bc 738 } else if ((ipproto == IPPROTO_UDP) && (port == -1)){
mazgch 63:42cb563a25bc 739 sendFormated("AT+USOCR=17\r\n");
mazgch 63:42cb563a25bc 740 } else if (ipproto == IPPROTO_UDP){
mazgch 63:42cb563a25bc 741 sendFormated("AT+USOCR=17,%d\r\n", port);
mazgch 21:c4d64830bf02 742 } else { // other types not supported
mazgch 21:c4d64830bf02 743 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 744 }
mazgch 21:c4d64830bf02 745 int socket = -1;
mazgch 52:8071747a7cb3 746 if (RESP_OK != waitFinalResp(_cbUSOCR, &socket))
mazgch 21:c4d64830bf02 747 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 748 if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_FREE))
mazgch 21:c4d64830bf02 749 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 750 // successfull
mazgch 21:c4d64830bf02 751 _sockets[socket].state = SOCK_CREATED;
mazgch 21:c4d64830bf02 752 _sockets[socket].pending = 0;
mazgch 66:69072b3c5bca 753 _sockets[socket].timeout_ms = TIMEOUT_BLOCKING;
mazgch 21:c4d64830bf02 754 return socket;
mazgch 21:c4d64830bf02 755 }
mazgch 21:c4d64830bf02 756
mazgch 21:c4d64830bf02 757 bool MDMParser::socketConnect(int socket, const char * host, int port)
mazgch 21:c4d64830bf02 758 {
mazgch 47:9a89e5195721 759 TRACE("socketConnect(%d,%s,%d)\r\n", socket, host,port);
mazgch 31:a0bed6c1e05d 760 IP ip = gethostbyname(host);
mazgch 31:a0bed6c1e05d 761 if (ip == NOIP)
mazgch 21:c4d64830bf02 762 return false;
mazgch 21:c4d64830bf02 763 // connect to socket
mazgch 21:c4d64830bf02 764 if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CREATED))
mazgch 21:c4d64830bf02 765 return false;
mazgch 21:c4d64830bf02 766 sendFormated("AT+USOCO=%d,\"" IPSTR "\",%d\r\n", socket, IPNUM(ip), port);
mazgch 52:8071747a7cb3 767 if (RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 768 return false;
mazgch 21:c4d64830bf02 769 _sockets[socket].state = SOCK_CONNECTED;
mazgch 21:c4d64830bf02 770 return true;
mazgch 21:c4d64830bf02 771 }
mazgch 21:c4d64830bf02 772
mazgch 44:9d12223b78ff 773 bool MDMParser::socketIsConnected(int socket)
mazgch 44:9d12223b78ff 774 {
mazgch 47:9a89e5195721 775 TRACE("socketIsConnected(%d)\r\n", socket);
mazgch 47:9a89e5195721 776 if (!ISSOCKET(socket))
mazgch 47:9a89e5195721 777 return false;
mazgch 47:9a89e5195721 778 return _sockets[socket].state == SOCK_CONNECTED;
mazgch 44:9d12223b78ff 779 }
mazgch 44:9d12223b78ff 780
mazgch 66:69072b3c5bca 781 bool MDMParser::socketSetBlocking(int socket, int timeout_ms)
mazgch 44:9d12223b78ff 782 {
mazgch 47:9a89e5195721 783 TRACE("socketSetBlocking(%d,%d)\r\n", socket, timeout_ms);
mazgch 44:9d12223b78ff 784 if (!ISSOCKET(socket))
mazgch 44:9d12223b78ff 785 return false;
mazgch 44:9d12223b78ff 786 _sockets[socket].timeout_ms = timeout_ms;
mazgch 44:9d12223b78ff 787 return true;
mazgch 44:9d12223b78ff 788 }
mazgch 44:9d12223b78ff 789
mazgch 21:c4d64830bf02 790 bool MDMParser::socketClose(int socket)
mazgch 21:c4d64830bf02 791 {
mazgch 47:9a89e5195721 792 TRACE("socketClose(%d)\r\n", socket);
mazgch 21:c4d64830bf02 793 if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CONNECTED))
mazgch 21:c4d64830bf02 794 return false;
mazgch 21:c4d64830bf02 795 sendFormated("AT+USOCL=%d\r\n", socket);
mazgch 52:8071747a7cb3 796 if (RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 797 return false;
mazgch 44:9d12223b78ff 798 _sockets[socket].state = SOCK_CREATED;
mazgch 21:c4d64830bf02 799 return true;
mazgch 21:c4d64830bf02 800 }
mazgch 21:c4d64830bf02 801
mazgch 21:c4d64830bf02 802 bool MDMParser::socketFree(int socket)
mazgch 21:c4d64830bf02 803 {
mazgch 47:9a89e5195721 804 TRACE("socketFree(%d)\r\n", socket);
mazgch 21:c4d64830bf02 805 socketClose(socket);
mazgch 21:c4d64830bf02 806 if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CREATED))
mazgch 21:c4d64830bf02 807 return false;
mazgch 21:c4d64830bf02 808 _sockets[socket].state = SOCK_FREE;
mazgch 21:c4d64830bf02 809 return true;
mazgch 21:c4d64830bf02 810 }
mazgch 21:c4d64830bf02 811
mazgch 69:4d6fa520dfca 812 #define USO_MAX_WRITE 1024 //!< maximum number of bytes to write to socket
mazgch 69:4d6fa520dfca 813
mazgch 21:c4d64830bf02 814 int MDMParser::socketSend(int socket, const char * buf, int len)
mazgch 21:c4d64830bf02 815 {
mazgch 47:9a89e5195721 816 TRACE("socketSend(%d,,%d)\r\n", socket,len);
mazgch 68:33a96cf64986 817 int cnt = len;
mazgch 68:33a96cf64986 818 while (cnt > 0) {
mazgch 69:4d6fa520dfca 819 int blk = USO_MAX_WRITE;
mazgch 68:33a96cf64986 820 if (cnt < blk)
mazgch 68:33a96cf64986 821 blk = cnt;
mazgch 68:33a96cf64986 822 sendFormated("AT+USOWR=%d,%d\r\n",socket,blk);
mazgch 52:8071747a7cb3 823 if (RESP_PROMPT != waitFinalResp())
mazgch 21:c4d64830bf02 824 return SOCKET_ERROR;
mazgch 74:208e3e32d263 825 RELAX_MS(50);
mazgch 68:33a96cf64986 826 send(buf, blk);
mazgch 52:8071747a7cb3 827 if (RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 828 return SOCKET_ERROR;
mazgch 68:33a96cf64986 829 buf += blk;
mazgch 68:33a96cf64986 830 cnt -= blk;
mazgch 21:c4d64830bf02 831 }
mazgch 68:33a96cf64986 832 return (len - cnt);
mazgch 21:c4d64830bf02 833 }
mazgch 21:c4d64830bf02 834
mazgch 21:c4d64830bf02 835 int MDMParser::socketSendTo(int socket, IP ip, int port, const char * buf, int len)
mazgch 21:c4d64830bf02 836 {
mazgch 65:dd94f920a762 837 TRACE("socketSendTo(%d," IPSTR ",%d,,%d)\r\n", socket, IPNUM(ip),port,len);
mazgch 68:33a96cf64986 838 int cnt = len;
mazgch 68:33a96cf64986 839 while (cnt > 0) {
mazgch 69:4d6fa520dfca 840 int blk = USO_MAX_WRITE;
mazgch 68:33a96cf64986 841 if (cnt < blk)
mazgch 68:33a96cf64986 842 blk = cnt;
mazgch 68:33a96cf64986 843 sendFormated("AT+USOST=%d,\"" IPSTR "\",%d,%d\r\n",socket,IPNUM(ip),port,blk);
mazgch 52:8071747a7cb3 844 if (RESP_PROMPT != waitFinalResp())
mazgch 21:c4d64830bf02 845 return SOCKET_ERROR;
mazgch 74:208e3e32d263 846 RELAX_MS(50);
mazgch 68:33a96cf64986 847 send(buf, blk);
mazgch 63:42cb563a25bc 848 if (RESP_OK != waitFinalResp())
mazgch 21:c4d64830bf02 849 return SOCKET_ERROR;
mazgch 68:33a96cf64986 850 buf += blk;
mazgch 68:33a96cf64986 851 cnt -= blk;
mazgch 21:c4d64830bf02 852 }
mazgch 68:33a96cf64986 853 return (len - cnt);
mazgch 21:c4d64830bf02 854 }
mazgch 21:c4d64830bf02 855
mazgch 21:c4d64830bf02 856 int MDMParser::socketReadable(int socket)
mazgch 21:c4d64830bf02 857 {
mazgch 47:9a89e5195721 858 TRACE("socketReadable(%d)\r\n", socket);
mazgch 21:c4d64830bf02 859 if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CONNECTED))
mazgch 21:c4d64830bf02 860 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 861 // allow to receive unsolicited commands
mazgch 21:c4d64830bf02 862 waitFinalResp(NULL, NULL, 0);
mazgch 21:c4d64830bf02 863 if (_sockets[socket].state != SOCK_CONNECTED)
mazgch 21:c4d64830bf02 864 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 865 return _sockets[socket].pending;
mazgch 21:c4d64830bf02 866 }
mazgch 21:c4d64830bf02 867
mazgch 21:c4d64830bf02 868 int MDMParser::_cbUSORD(int type, const char* buf, int len, char* out)
mazgch 21:c4d64830bf02 869 {
mazgch 21:c4d64830bf02 870 if ((type == TYPE_PLUS) && out) {
mazgch 21:c4d64830bf02 871 int sz, sk;
mazgch 21:c4d64830bf02 872 if ((sscanf(buf, "\r\n+USORD: %d,%d,", &sk, &sz) == 2) &&
mazgch 21:c4d64830bf02 873 (buf[len-sz-2] == '\"') && (buf[len-1] == '\"')) {
mazgch 21:c4d64830bf02 874 memcpy(out, &buf[len-1-sz], sz);
mazgch 21:c4d64830bf02 875 }
mazgch 21:c4d64830bf02 876 }
mazgch 21:c4d64830bf02 877 return WAIT;
mazgch 21:c4d64830bf02 878 }
mazgch 21:c4d64830bf02 879
mazgch 21:c4d64830bf02 880 int MDMParser::socketRecv(int socket, char* buf, int len)
mazgch 21:c4d64830bf02 881 {
mazgch 21:c4d64830bf02 882 int cnt = 0;
mazgch 47:9a89e5195721 883 TRACE("socketRecv(%d,,%d)\r\n", socket, len);
mazgch 21:c4d64830bf02 884 if (!ISSOCKET(socket))
mazgch 21:c4d64830bf02 885 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 886 memset(buf, '\0', len);
mazgch 44:9d12223b78ff 887 Timer timer;
mazgch 44:9d12223b78ff 888 timer.start();
mazgch 21:c4d64830bf02 889 while (len) {
mazgch 69:4d6fa520dfca 890 int blk = MAX_SIZE; // still need space for headers and unsolicited commands
mazgch 21:c4d64830bf02 891 if (_sockets[socket].pending < blk)
mazgch 21:c4d64830bf02 892 blk = _sockets[socket].pending;
mazgch 21:c4d64830bf02 893 if (len < blk) blk = len;
mazgch 21:c4d64830bf02 894 if (blk) {
mazgch 44:9d12223b78ff 895 sendFormated("AT+USORD=%d,%d\r\n",socket, blk);
mazgch 52:8071747a7cb3 896 if (RESP_OK != waitFinalResp(_cbUSORD, buf)) {
mazgch 44:9d12223b78ff 897 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 898 }
mazgch 21:c4d64830bf02 899 len -= blk;
mazgch 21:c4d64830bf02 900 cnt += blk;
mazgch 21:c4d64830bf02 901 buf += blk;
mazgch 21:c4d64830bf02 902 _sockets[socket].pending -= blk;
mazgch 44:9d12223b78ff 903 } else if ((_sockets[socket].state == SOCK_CONNECTED) && (
mazgch 66:69072b3c5bca 904 (_sockets[socket].timeout_ms == TIMEOUT_BLOCKING) ||
mazgch 44:9d12223b78ff 905 (timer.read_ms() < _sockets[socket].timeout_ms))){
mazgch 21:c4d64830bf02 906 // allow to receive unsolicited commands
mazgch 21:c4d64830bf02 907 waitFinalResp(NULL, NULL, 10);
mazgch 44:9d12223b78ff 908 } else {
mazgch 44:9d12223b78ff 909 len = 0; // no more data and socket closed or timed-out
mazgch 21:c4d64830bf02 910 }
mazgch 21:c4d64830bf02 911 }
mazgch 58:e38a2e942fbb 912
mazgch 44:9d12223b78ff 913 timer.stop();
mazgch 44:9d12223b78ff 914 timer.reset();
mazgch 21:c4d64830bf02 915 return cnt;
mazgch 21:c4d64830bf02 916 }
mazgch 21:c4d64830bf02 917
mazgch 21:c4d64830bf02 918 int MDMParser::_cbUSORF(int type, const char* buf, int len, USORFparam* param)
mazgch 21:c4d64830bf02 919 {
mazgch 21:c4d64830bf02 920 if ((type == TYPE_PLUS) && param) {
mazgch 21:c4d64830bf02 921 int sz, sk, p, a,b,c,d;
mazgch 21:c4d64830bf02 922 if ((sscanf(buf, "\r\n+USORF: %d,\""IPSTR"\",%d,%d,",
mazgch 21:c4d64830bf02 923 &sk,&a,&b,&c,&d,&p,&sz) == 7) &&
mazgch 21:c4d64830bf02 924 (buf[len-sz-2] == '\"') && (buf[len-1] == '\"')) {
mazgch 21:c4d64830bf02 925 memcpy(param->buf, &buf[len-1-sz], sz);
mazgch 21:c4d64830bf02 926 param->ip = IPADR(a,b,c,d);
mazgch 21:c4d64830bf02 927 param->port = p;
mazgch 21:c4d64830bf02 928 }
mazgch 21:c4d64830bf02 929 }
mazgch 21:c4d64830bf02 930 return WAIT;
mazgch 21:c4d64830bf02 931 }
mazgch 21:c4d64830bf02 932
mazgch 63:42cb563a25bc 933 int MDMParser::socketRecvFrom(int socket, IP* ip, int* port, char* buf, int len)
mazgch 21:c4d64830bf02 934 {
mazgch 21:c4d64830bf02 935 int cnt = 0;
mazgch 63:42cb563a25bc 936 TRACE("socketRecvFrom(%d,,%d)\r\n", socket, len);
mazgch 21:c4d64830bf02 937 if (!ISSOCKET(socket))
mazgch 21:c4d64830bf02 938 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 939 memset(buf, '\0', len);
mazgch 44:9d12223b78ff 940 Timer timer;
mazgch 44:9d12223b78ff 941 timer.start();
mazgch 21:c4d64830bf02 942 while (len) {
mazgch 69:4d6fa520dfca 943 int blk = MAX_SIZE; // still need space for headers and unsolicited commands
mazgch 21:c4d64830bf02 944 if (_sockets[socket].pending < blk)
mazgch 21:c4d64830bf02 945 blk = _sockets[socket].pending;
mazgch 21:c4d64830bf02 946 if (len < blk) blk = len;
mazgch 21:c4d64830bf02 947 if (blk) {
mazgch 21:c4d64830bf02 948 sendFormated("AT+USORF=%d,%d\r\n",socket, blk);
mazgch 21:c4d64830bf02 949 USORFparam param;
mazgch 21:c4d64830bf02 950 param.buf = buf;
mazgch 52:8071747a7cb3 951 if (RESP_OK != waitFinalResp(_cbUSORF, &param)) {
mazgch 44:9d12223b78ff 952 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 953 }
mazgch 21:c4d64830bf02 954 *ip = param.ip;
mazgch 63:42cb563a25bc 955 *port = param.port;
mazgch 21:c4d64830bf02 956 len -= blk;
mazgch 21:c4d64830bf02 957 cnt += blk;
mazgch 21:c4d64830bf02 958 buf += blk;
mazgch 21:c4d64830bf02 959 _sockets[socket].pending -= blk;
mazgch 66:69072b3c5bca 960 } else if ((_sockets[socket].timeout_ms == TIMEOUT_BLOCKING) ||
mazgch 63:42cb563a25bc 961 (timer.read_ms() < _sockets[socket].timeout_ms)) {
mazgch 21:c4d64830bf02 962 // allow to receive unsolicited commands
mazgch 21:c4d64830bf02 963 waitFinalResp(NULL, NULL, 10);
mazgch 44:9d12223b78ff 964 } else {
mazgch 44:9d12223b78ff 965 len = 0; // no more data and socket closed or timed-out
mazgch 21:c4d64830bf02 966 }
mazgch 21:c4d64830bf02 967 }
mazgch 44:9d12223b78ff 968 timer.stop();
mazgch 44:9d12223b78ff 969 timer.reset();
mazgch 21:c4d64830bf02 970 return cnt;
mazgch 21:c4d64830bf02 971 }
mazgch 21:c4d64830bf02 972
mazgch 21:c4d64830bf02 973 // ----------------------------------------------------------------
mazgch 31:a0bed6c1e05d 974
mazgch 31:a0bed6c1e05d 975 int MDMParser::_cbCMGL(int type, const char* buf, int len, CMGLparam* param)
mazgch 21:c4d64830bf02 976 {
mazgch 31:a0bed6c1e05d 977 if ((type == TYPE_PLUS) && param && param->num) {
mazgch 31:a0bed6c1e05d 978 // +CMGL: <ix>,...
mazgch 31:a0bed6c1e05d 979 int ix;
mazgch 31:a0bed6c1e05d 980 if (sscanf(buf, "\r\n+CMGL: %d,", &ix) == 1)
mazgch 31:a0bed6c1e05d 981 {
mazgch 31:a0bed6c1e05d 982 *param->ix++ = ix;
mazgch 31:a0bed6c1e05d 983 param->num--;
mazgch 31:a0bed6c1e05d 984 }
mazgch 29:53d346010624 985 }
mazgch 29:53d346010624 986 return WAIT;
mazgch 21:c4d64830bf02 987 }
mazgch 21:c4d64830bf02 988
mazgch 31:a0bed6c1e05d 989 int MDMParser::smsList(const char* stat /*= "ALL"*/, int* ix /*=NULL*/, int num /*= 0*/) {
mazgch 31:a0bed6c1e05d 990 sendFormated("AT+CMGL=\"%s\"\r\n", stat);
mazgch 31:a0bed6c1e05d 991 CMGLparam param;
mazgch 31:a0bed6c1e05d 992 param.ix = ix;
mazgch 31:a0bed6c1e05d 993 param.num = num;
mazgch 52:8071747a7cb3 994 if (RESP_OK != waitFinalResp(_cbCMGL, &param))
mazgch 31:a0bed6c1e05d 995 return -1;
mazgch 31:a0bed6c1e05d 996 return num - param.num;
mazgch 21:c4d64830bf02 997 }
mazgch 21:c4d64830bf02 998
mazgch 21:c4d64830bf02 999 bool MDMParser::smsSend(const char* num, const char* buf)
mazgch 21:c4d64830bf02 1000 {
mazgch 21:c4d64830bf02 1001 sendFormated("AT+CMGS=\"%s\"\r",num);
mazgch 58:e38a2e942fbb 1002 if (RESP_PROMPT != waitFinalResp(NULL,NULL,150*1000)) {
mazgch 21:c4d64830bf02 1003 return false;
mazgch 21:c4d64830bf02 1004 }
mazgch 21:c4d64830bf02 1005 send(buf, strlen(buf));
mazgch 21:c4d64830bf02 1006 const char ctrlZ = 0x1A;
mazgch 21:c4d64830bf02 1007 send(&ctrlZ, sizeof(ctrlZ));
mazgch 52:8071747a7cb3 1008 if (RESP_OK != waitFinalResp()) {
mazgch 21:c4d64830bf02 1009 return false;
mazgch 21:c4d64830bf02 1010 }
mazgch 21:c4d64830bf02 1011 return true;
mazgch 21:c4d64830bf02 1012 }
mazgch 21:c4d64830bf02 1013
mazgch 21:c4d64830bf02 1014 bool MDMParser::smsDelete(int ix)
mazgch 21:c4d64830bf02 1015 {
mazgch 21:c4d64830bf02 1016 sendFormated("AT+CMGD=%d\r\n",ix);
mazgch 52:8071747a7cb3 1017 if (RESP_OK != waitFinalResp()) {
mazgch 21:c4d64830bf02 1018 return false;
mazgch 21:c4d64830bf02 1019 }
mazgch 21:c4d64830bf02 1020 return true;
mazgch 21:c4d64830bf02 1021 }
mazgch 21:c4d64830bf02 1022
mazgch 21:c4d64830bf02 1023 int MDMParser::_cbCMGR(int type, const char* buf, int len, CMGRparam* param)
mazgch 21:c4d64830bf02 1024 {
mazgch 21:c4d64830bf02 1025 if (param) {
mazgch 21:c4d64830bf02 1026 if (type == TYPE_PLUS) {
mazgch 21:c4d64830bf02 1027 if (sscanf(buf, "\r\n+CMGR: \"%*[^\"]\",\"%[^\"]", param->num) == 1) {
mazgch 21:c4d64830bf02 1028 }
mazgch 37:cc3433329d66 1029 } else if ((type == TYPE_UNKNOWN) && (buf[len-2] == '\r') && (buf[len-1] == '\n')) {
mazgch 21:c4d64830bf02 1030 memcpy(param->buf, buf, len-2);
mazgch 21:c4d64830bf02 1031 param->buf[len-2] = '\0';
mazgch 21:c4d64830bf02 1032 }
mazgch 21:c4d64830bf02 1033 }
mazgch 21:c4d64830bf02 1034 return WAIT;
mazgch 21:c4d64830bf02 1035 }
mazgch 21:c4d64830bf02 1036
mazgch 21:c4d64830bf02 1037 bool MDMParser::smsRead(int ix, char* num, char* buf, int len)
mazgch 21:c4d64830bf02 1038 {
mazgch 21:c4d64830bf02 1039 CMGRparam param;
mazgch 21:c4d64830bf02 1040 param.num = num;
mazgch 21:c4d64830bf02 1041 param.buf = buf;
mazgch 21:c4d64830bf02 1042 sendFormated("AT+CMGR=%d\r\n",ix);
mazgch 52:8071747a7cb3 1043 if (RESP_OK != waitFinalResp(_cbCMGR, &param)) {
mazgch 21:c4d64830bf02 1044 return false;
mazgch 21:c4d64830bf02 1045 }
mazgch 21:c4d64830bf02 1046 return true;
mazgch 21:c4d64830bf02 1047 }
mazgch 54:7ba8e4c218e2 1048
mazgch 54:7ba8e4c218e2 1049 // ----------------------------------------------------------------
mazgch 70:0a87d256cd24 1050
mazgch 70:0a87d256cd24 1051 int MDMParser::_cbCUSD(int type, const char* buf, int len, char* resp)
mazgch 70:0a87d256cd24 1052 {
mazgch 70:0a87d256cd24 1053 if ((type == TYPE_PLUS) && resp) {
mazgch 70:0a87d256cd24 1054 // +USD: \"%*[^\"]\",\"%[^\"]\",,\"%*[^\"]\",%d,%d,%d,%d,\"*[^\"]\",%d,%d"..);
mazgch 70:0a87d256cd24 1055 if (sscanf(buf, "\r\n+CUSD: %*d,\"%[^\"]\",%*d", resp) == 1) {
mazgch 70:0a87d256cd24 1056 /*nothing*/
mazgch 70:0a87d256cd24 1057 }
mazgch 70:0a87d256cd24 1058 }
mazgch 70:0a87d256cd24 1059 return WAIT;
mazgch 70:0a87d256cd24 1060 }
mazgch 70:0a87d256cd24 1061
mazgch 70:0a87d256cd24 1062 bool MDMParser::ussdCommand(const char* cmd, char* buf)
mazgch 70:0a87d256cd24 1063 {
mazgch 70:0a87d256cd24 1064 *buf = '\0';
mazgch 70:0a87d256cd24 1065 sendFormated("AT+CUSD=1,\"%s\"\r\n",cmd);
mazgch 70:0a87d256cd24 1066 if (RESP_OK != waitFinalResp(_cbCUSD, buf)) {
mazgch 70:0a87d256cd24 1067 return false;
mazgch 70:0a87d256cd24 1068 }
mazgch 70:0a87d256cd24 1069 return true;
mazgch 70:0a87d256cd24 1070 }
mazgch 70:0a87d256cd24 1071
mazgch 70:0a87d256cd24 1072 // ----------------------------------------------------------------
mazgch 74:208e3e32d263 1073 bool MDMParser::setDebug(int level)
mazgch 74:208e3e32d263 1074 {
mazgch 74:208e3e32d263 1075 #ifdef MDM_DEBUG
mazgch 74:208e3e32d263 1076 if ((_debugLevel >= 0) && (level >= 0)) {
mazgch 74:208e3e32d263 1077 _debugLevel = level;
mazgch 74:208e3e32d263 1078 return true;
mazgch 74:208e3e32d263 1079 }
mazgch 74:208e3e32d263 1080 #endif
mazgch 74:208e3e32d263 1081 return false;
mazgch 74:208e3e32d263 1082 }
mazgch 74:208e3e32d263 1083
mazgch 73:2b32e0a21df2 1084 void MDMParser::dumpDevStatus(MDMParser::DevStatus* status,
mazgch 73:2b32e0a21df2 1085 _DPRINT dprint, void* param)
mazgch 54:7ba8e4c218e2 1086 {
mazgch 73:2b32e0a21df2 1087 dprint(param, "Modem Device Status:\r\n");
mazgch 54:7ba8e4c218e2 1088 const char* txtDev[] = { "Unknown", "SARA-G350", "LISA-U200", "LISA-C200" };
mazgch 54:7ba8e4c218e2 1089 if (status->dev < sizeof(txtDev)/sizeof(*txtDev) && (status->dev != MDMParser::DEV_UNKNOWN))
mazgch 73:2b32e0a21df2 1090 dprint(param, " Device: %s\r\n", txtDev[status->dev]);
mazgch 54:7ba8e4c218e2 1091 const char* txtLpm[] = { "Disabled", "Enabled", "Active" };
mazgch 54:7ba8e4c218e2 1092 if (status->lpm < sizeof(txtLpm)/sizeof(*txtLpm))
mazgch 73:2b32e0a21df2 1093 dprint(param, " Power Save: %s\r\n", txtLpm[status->lpm]);
mazgch 54:7ba8e4c218e2 1094 const char* txtSim[] = { "Unknown", "Pin", "Ready" };
mazgch 54:7ba8e4c218e2 1095 if (status->sim < sizeof(txtSim)/sizeof(*txtSim) && (status->sim != MDMParser::SIM_UNKNOWN))
mazgch 73:2b32e0a21df2 1096 dprint(param, " SIM: %s\r\n", txtSim[status->sim]);
mazgch 54:7ba8e4c218e2 1097 if (*status->ccid)
mazgch 73:2b32e0a21df2 1098 dprint(param, " CCID: %s\r\n", status->ccid);
mazgch 54:7ba8e4c218e2 1099 if (*status->imei)
mazgch 73:2b32e0a21df2 1100 dprint(param, " IMEI: %s\r\n", status->imei);
mazgch 54:7ba8e4c218e2 1101 if (*status->imsi)
mazgch 73:2b32e0a21df2 1102 dprint(param, " IMSI: %s\r\n", status->imsi);
mazgch 54:7ba8e4c218e2 1103 if (*status->meid)
mazgch 73:2b32e0a21df2 1104 dprint(param, " MEID: %s\r\n", status->meid); // LISA-C
mazgch 54:7ba8e4c218e2 1105 if (*status->manu)
mazgch 73:2b32e0a21df2 1106 dprint(param, " Manufacturer: %s\r\n", status->manu);
mazgch 54:7ba8e4c218e2 1107 if (*status->model)
mazgch 73:2b32e0a21df2 1108 dprint(param, " Model: %s\r\n", status->model);
mazgch 54:7ba8e4c218e2 1109 if (*status->ver)
mazgch 73:2b32e0a21df2 1110 dprint(param, " Version: %s\r\n", status->ver);
mazgch 54:7ba8e4c218e2 1111 }
mazgch 54:7ba8e4c218e2 1112
mazgch 73:2b32e0a21df2 1113 void MDMParser::dumpNetStatus(MDMParser::NetStatus *status,
mazgch 73:2b32e0a21df2 1114 _DPRINT dprint, void* param)
mazgch 54:7ba8e4c218e2 1115 {
mazgch 73:2b32e0a21df2 1116 dprint(param, "Modem Network Status:\r\n");
mazgch 54:7ba8e4c218e2 1117 const char* txtReg[] = { "Unknown", "Denied", "None", "Home", "Roaming" };
mazgch 54:7ba8e4c218e2 1118 if (status->reg < sizeof(txtReg)/sizeof(*txtReg) && (status->reg != MDMParser::REG_UNKNOWN))
mazgch 73:2b32e0a21df2 1119 dprint(param, " Registration: %s\r\n", txtReg[status->reg]);
mazgch 72:d1e943ad6558 1120 const char* txtGprs[] = { "Unknown", "Detached", "Attached" };
mazgch 72:d1e943ad6558 1121 if (status->gprs < sizeof(txtGprs)/sizeof(*txtGprs) && (status->gprs != MDMParser::GPRS_UNKNOWN))
mazgch 73:2b32e0a21df2 1122 dprint(param, " Gprs: %s\r\n", txtGprs[status->gprs]);
mazgch 54:7ba8e4c218e2 1123 const char* txtAct[] = { "Unknown", "GSM", "Edge", "3G", "CDMA" };
mazgch 54:7ba8e4c218e2 1124 if (status->act < sizeof(txtAct)/sizeof(*txtAct) && (status->act != MDMParser::ACT_UNKNOWN))
mazgch 73:2b32e0a21df2 1125 dprint(param, " Access Technology: %s\r\n", txtAct[status->act]);
mazgch 54:7ba8e4c218e2 1126 if (status->rssi)
mazgch 73:2b32e0a21df2 1127 dprint(param, " Signal Strength: %d dBm\r\n", status->rssi);
mazgch 54:7ba8e4c218e2 1128 if (status->ber)
mazgch 73:2b32e0a21df2 1129 dprint(param, " Bit Error Rate: %d\r\n", status->ber);
mazgch 54:7ba8e4c218e2 1130 if (*status->opr)
mazgch 73:2b32e0a21df2 1131 dprint(param, " Operator: %s\r\n", status->opr);
mazgch 54:7ba8e4c218e2 1132 if (status->lac != 0xFFFF)
mazgch 73:2b32e0a21df2 1133 dprint(param, " Location Area Code: %04X\r\n", status->lac);
mazgch 54:7ba8e4c218e2 1134 if (status->ci != 0xFFFFFFFF)
mazgch 73:2b32e0a21df2 1135 dprint(param, " Cell ID: %08X\r\n", status->ci);
mazgch 54:7ba8e4c218e2 1136 if (*status->num)
mazgch 73:2b32e0a21df2 1137 dprint(param, " Phone Number: %s\r\n", status->num);
mazgch 54:7ba8e4c218e2 1138 }
mazgch 54:7ba8e4c218e2 1139
mazgch 73:2b32e0a21df2 1140 void MDMParser::dumpIp(MDMParser::IP ip,
mazgch 73:2b32e0a21df2 1141 _DPRINT dprint, void* param)
mazgch 54:7ba8e4c218e2 1142 {
mazgch 57:869bd35f44cc 1143 if (ip != NOIP)
mazgch 73:2b32e0a21df2 1144 dprint(param, "Modem IP Address: " IPSTR "\r\n", IPNUM(ip));
mazgch 54:7ba8e4c218e2 1145 }
mazgch 70:0a87d256cd24 1146
mazgch 21:c4d64830bf02 1147 // ----------------------------------------------------------------
mazgch 21:c4d64830bf02 1148 int MDMParser::_parseMatch(Pipe<char>* pipe, int len, const char* sta, const char* end)
mazgch 18:e5697801df29 1149 {
mazgch 18:e5697801df29 1150 int o = 0;
mazgch 21:c4d64830bf02 1151 if (sta) {
mazgch 21:c4d64830bf02 1152 while (*sta) {
mazgch 21:c4d64830bf02 1153 if (++o > len) return WAIT;
mazgch 21:c4d64830bf02 1154 char ch = pipe->next();
mazgch 21:c4d64830bf02 1155 if (*sta++ != ch) return NOT_FOUND;
mazgch 21:c4d64830bf02 1156 }
mazgch 21:c4d64830bf02 1157 }
mazgch 21:c4d64830bf02 1158 if (!end) return o; // no termination
mazgch 35:9275215a3a5b 1159 // at least any char
mazgch 35:9275215a3a5b 1160 if (++o > len) return WAIT;
mazgch 35:9275215a3a5b 1161 pipe->next();
mazgch 35:9275215a3a5b 1162 // check the end
mazgch 21:c4d64830bf02 1163 int x = 0;
mazgch 21:c4d64830bf02 1164 while (end[x]) {
mazgch 21:c4d64830bf02 1165 if (++o > len) return WAIT;
mazgch 21:c4d64830bf02 1166 char ch = pipe->next();
mazgch 21:c4d64830bf02 1167 x = (end[x] == ch) ? x + 1 :
mazgch 21:c4d64830bf02 1168 (end[0] == ch) ? 1 :
mazgch 21:c4d64830bf02 1169 0;
mazgch 21:c4d64830bf02 1170 }
mazgch 21:c4d64830bf02 1171 return o;
mazgch 21:c4d64830bf02 1172 }
mazgch 21:c4d64830bf02 1173
mazgch 21:c4d64830bf02 1174 int MDMParser::_parseFormated(Pipe<char>* pipe, int len, const char* fmt)
mazgch 21:c4d64830bf02 1175 {
mazgch 21:c4d64830bf02 1176 int o = 0;
mazgch 21:c4d64830bf02 1177 int num = 0;
mazgch 21:c4d64830bf02 1178 if (fmt) {
mazgch 21:c4d64830bf02 1179 while (*fmt) {
mazgch 21:c4d64830bf02 1180 if (++o > len) return WAIT;
mazgch 21:c4d64830bf02 1181 char ch = pipe->next();
mazgch 21:c4d64830bf02 1182 if (*fmt == '%') {
mazgch 21:c4d64830bf02 1183 fmt++;
mazgch 21:c4d64830bf02 1184 if (*fmt == 'd') { // numeric
mazgch 21:c4d64830bf02 1185 fmt ++;
mazgch 21:c4d64830bf02 1186 num = 0;
mazgch 21:c4d64830bf02 1187 while (ch >= '0' && ch <= '9') {
mazgch 21:c4d64830bf02 1188 num = num * 10 + (ch - '0');
mazgch 21:c4d64830bf02 1189 if (++o > len) return WAIT;
mazgch 21:c4d64830bf02 1190 ch = pipe->next();
mazgch 21:c4d64830bf02 1191 }
mazgch 21:c4d64830bf02 1192 }
mazgch 21:c4d64830bf02 1193 else if (*fmt == 'c') { // char buffer (takes last numeric as length)
mazgch 21:c4d64830bf02 1194 fmt ++;
mazgch 21:c4d64830bf02 1195 while (num --) {
mazgch 21:c4d64830bf02 1196 if (++o > len) return WAIT;
mazgch 21:c4d64830bf02 1197 ch = pipe->next();
mazgch 21:c4d64830bf02 1198 }
mazgch 21:c4d64830bf02 1199 }
mazgch 21:c4d64830bf02 1200 }
mazgch 21:c4d64830bf02 1201 if (*fmt++ != ch) return NOT_FOUND;
mazgch 18:e5697801df29 1202 }
mazgch 18:e5697801df29 1203 }
mazgch 21:c4d64830bf02 1204 return o;
mazgch 21:c4d64830bf02 1205 }
mazgch 21:c4d64830bf02 1206
mazgch 21:c4d64830bf02 1207 int MDMParser::_getLine(Pipe<char>* pipe, char* buf, int len)
mazgch 21:c4d64830bf02 1208 {
mazgch 21:c4d64830bf02 1209 int unkn = 0;
mazgch 21:c4d64830bf02 1210 int sz = pipe->size();
mazgch 21:c4d64830bf02 1211 int fr = pipe->free();
mazgch 21:c4d64830bf02 1212 if (len > sz)
mazgch 21:c4d64830bf02 1213 len = sz;
mazgch 21:c4d64830bf02 1214 while (len > 0)
mazgch 21:c4d64830bf02 1215 {
mazgch 21:c4d64830bf02 1216 static struct {
mazgch 21:c4d64830bf02 1217 const char* fmt; int type;
mazgch 21:c4d64830bf02 1218 } lutF[] = {
mazgch 21:c4d64830bf02 1219 { "\r\n+USORD: %d,%d,\"%c\"", TYPE_PLUS },
mazgch 21:c4d64830bf02 1220 { "\r\n+USORF: %d,\""IPSTR"\",%d,%d,\"%c\"", TYPE_PLUS },
mazgch 21:c4d64830bf02 1221 };
mazgch 21:c4d64830bf02 1222 static struct {
mazgch 21:c4d64830bf02 1223 const char* sta; const char* end; int type;
mazgch 21:c4d64830bf02 1224 } lut[] = {
mazgch 21:c4d64830bf02 1225 { "\r\nOK\r\n", NULL, TYPE_OK },
mazgch 21:c4d64830bf02 1226 { "\r\nERROR\r\n", NULL, TYPE_ERROR },
mazgch 31:a0bed6c1e05d 1227 { "\r\n+CME ERROR:", "\r\n", TYPE_ERROR },
mazgch 21:c4d64830bf02 1228 { "\r\n+CMS ERROR:", "\r\n", TYPE_ERROR },
mazgch 21:c4d64830bf02 1229 { "\r\nRING\r\n", NULL, TYPE_RING },
mazgch 21:c4d64830bf02 1230 { "\r\nCONNECT\r\n", NULL, TYPE_CONNECT },
mazgch 21:c4d64830bf02 1231 { "\r\nNO CARRIER\r\n", NULL, TYPE_NOCARRIER },
mazgch 21:c4d64830bf02 1232 { "\r\nNO DIALTONE\r\n", NULL, TYPE_NODIALTONE },
mazgch 21:c4d64830bf02 1233 { "\r\nBUSY\r\n", NULL, TYPE_BUSY },
mazgch 21:c4d64830bf02 1234 { "\r\nNO ANSWER\r\n", NULL, TYPE_NOANSWER },
mazgch 21:c4d64830bf02 1235 { "\r\n+", "\r\n", TYPE_PLUS },
mazgch 21:c4d64830bf02 1236 { "\r\n@", NULL, TYPE_PROMPT }, // Sockets
mazgch 21:c4d64830bf02 1237 { "\r\n>", NULL, TYPE_PROMPT }, // SMS
mazgch 21:c4d64830bf02 1238 };
mazgch 21:c4d64830bf02 1239 for (int i = 0; i < sizeof(lutF)/sizeof(*lutF); i ++) {
mazgch 21:c4d64830bf02 1240 pipe->set(unkn);
mazgch 21:c4d64830bf02 1241 int ln = _parseFormated(pipe, len, lutF[i].fmt);
mazgch 21:c4d64830bf02 1242 if (ln == WAIT && fr)
mazgch 21:c4d64830bf02 1243 return WAIT;
mazgch 21:c4d64830bf02 1244 if ((ln != NOT_FOUND) && (unkn > 0))
mazgch 31:a0bed6c1e05d 1245 return TYPE_UNKNOWN | pipe->get(buf, unkn);
mazgch 21:c4d64830bf02 1246 if (ln > 0)
mazgch 21:c4d64830bf02 1247 return lutF[i].type | pipe->get(buf, ln);
mazgch 21:c4d64830bf02 1248 }
mazgch 21:c4d64830bf02 1249 for (int i = 0; i < sizeof(lut)/sizeof(*lut); i ++) {
mazgch 21:c4d64830bf02 1250 pipe->set(unkn);
mazgch 21:c4d64830bf02 1251 int ln = _parseMatch(pipe, len, lut[i].sta, lut[i].end);
mazgch 21:c4d64830bf02 1252 if (ln == WAIT && fr)
mazgch 21:c4d64830bf02 1253 return WAIT;
mazgch 21:c4d64830bf02 1254 if ((ln != NOT_FOUND) && (unkn > 0))
mazgch 31:a0bed6c1e05d 1255 return TYPE_UNKNOWN | pipe->get(buf, unkn);
mazgch 21:c4d64830bf02 1256 if (ln > 0)
mazgch 21:c4d64830bf02 1257 return lut[i].type | pipe->get(buf, ln);
mazgch 21:c4d64830bf02 1258 }
mazgch 21:c4d64830bf02 1259 // UNKNOWN
mazgch 21:c4d64830bf02 1260 unkn ++;
mazgch 21:c4d64830bf02 1261 len--;
mazgch 21:c4d64830bf02 1262 }
mazgch 18:e5697801df29 1263 return WAIT;
mazgch 18:e5697801df29 1264 }
mazgch 18:e5697801df29 1265
mazgch 18:e5697801df29 1266 // ----------------------------------------------------------------
mazgch 18:e5697801df29 1267 // Serial Implementation
mazgch 18:e5697801df29 1268 // ----------------------------------------------------------------
mazgch 18:e5697801df29 1269
mazgch 19:2b5d097ca15d 1270 MDMSerial::MDMSerial(PinName tx /*= MDMTXD*/, PinName rx /*= MDMRXD*/,
mazgch 19:2b5d097ca15d 1271 int baudrate /*= MDMBAUD*/,
mazgch 43:a89a7a505991 1272 #if DEVICE_SERIAL_FC
mazgch 19:2b5d097ca15d 1273 PinName rts /*= MDMRTS*/, PinName cts /*= MDMCTS*/,
mazgch 43:a89a7a505991 1274 #endif
mazgch 18:e5697801df29 1275 int rxSize /*= 256*/, int txSize /*= 128*/) :
mazgch 35:9275215a3a5b 1276 SerialPipe(tx, rx, rxSize, txSize)
mazgch 18:e5697801df29 1277 {
mazgch 74:208e3e32d263 1278 #ifdef MDM_DEBUG
mazgch 74:208e3e32d263 1279 _debugLevel = (tx == USBTX) ? -1 : 1;
mazgch 74:208e3e32d263 1280 #endif
mazgch 74:208e3e32d263 1281 #ifdef TARGET_UBLOX_C027
mazgch 74:208e3e32d263 1282 _onboard = (tx == MDMTXD) && (rx == MDMRXD);
mazgch 74:208e3e32d263 1283 if (_onboard)
mazgch 74:208e3e32d263 1284 c027_mdm_powerOn(false);
mazgch 74:208e3e32d263 1285 #endif
mazgch 18:e5697801df29 1286 baud(baudrate);
mazgch 35:9275215a3a5b 1287 #if DEVICE_SERIAL_FC
mazgch 35:9275215a3a5b 1288 if ((rts != NC) || (cts != NC))
mazgch 35:9275215a3a5b 1289 {
mazgch 35:9275215a3a5b 1290 Flow flow = (cts == NC) ? RTS :
mazgch 35:9275215a3a5b 1291 (rts == NC) ? CTS : RTSCTS ;
mazgch 35:9275215a3a5b 1292 set_flow_control(flow, rts, cts);
mazgch 35:9275215a3a5b 1293 if (cts != NC) _dev.lpm = LPM_ENABLED;
mazgch 35:9275215a3a5b 1294 }
mazgch 35:9275215a3a5b 1295 #endif
mazgch 18:e5697801df29 1296 }
mazgch 18:e5697801df29 1297
mazgch 18:e5697801df29 1298 int MDMSerial::_send(const void* buf, int len)
mazgch 18:e5697801df29 1299 {
mazgch 35:9275215a3a5b 1300 return put((const char*)buf, len, true/*=blocking*/);
mazgch 18:e5697801df29 1301 }
mazgch 18:e5697801df29 1302
mazgch 18:e5697801df29 1303 int MDMSerial::getLine(char* buffer, int length)
mazgch 18:e5697801df29 1304 {
mazgch 18:e5697801df29 1305 return _getLine(&_pipeRx, buffer, length);
mazgch 18:e5697801df29 1306 }
mazgch 18:e5697801df29 1307
mazgch 18:e5697801df29 1308 // ----------------------------------------------------------------
mazgch 18:e5697801df29 1309 // USB Implementation
mazgch 18:e5697801df29 1310 // ----------------------------------------------------------------
mazgch 18:e5697801df29 1311
mazgch 18:e5697801df29 1312 #ifdef HAVE_MDMUSB
mazgch 74:208e3e32d263 1313 MDMUsb(void)
mazgch 74:208e3e32d263 1314 {
mazgch 74:208e3e32d263 1315 #ifdef MDM_DEBUG
mazgch 74:208e3e32d263 1316 _debugLevel = 1;
mazgch 74:208e3e32d263 1317 #endif
mazgch 74:208e3e32d263 1318 #ifdef TARGET_UBLOX_C027
mazgch 74:208e3e32d263 1319 _onboard = true;
mazgch 74:208e3e32d263 1320 c027_mdm_powerOn(true);
mazgch 74:208e3e32d263 1321 #endif
mazgch 74:208e3e32d263 1322 }
mazgch 18:e5697801df29 1323 int MDMUsb::_send(const void* buf, int len) { return len; }
mazgch 18:e5697801df29 1324 int MDMUsb::getLine(char* buffer, int length) { return NOT_FOUND; }
mazgch 35:9275215a3a5b 1325 #endif