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 Apr 17 20:41:30 2014 +0000
Revision:
44:9d12223b78ff
Parent:
43:a89a7a505991
Child:
45:ebc2fd8dcf21
adding mbed style (tcp)socket api

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