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

Dependents:   HTTPClient_Cellular_HelloWorld Cellular_HelloMQTT MbedSmartRestMain Car_Bon_car_module ... more

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

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

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

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

Committer:
mazgch
Date:
Tue May 13 16:25:56 2014 +0000
Revision:
68:33a96cf64986
Parent:
66:69072b3c5bca
Child:
69:4d6fa520dfca
allow to send large data chunks

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