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 10 13:07:02 2014 +0000
Revision:
36:c4df7bcf9b6e
Parent:
35:9275215a3a5b
Child:
37:cc3433329d66
no debug

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