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:
Thu May 15 06:16:10 2014 +0000
Revision:
71:041de9a6d93c
Parent:
70:0a87d256cd24
Child:
72:d1e943ad6558
move at command

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