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:
Wed Apr 09 13:03:48 2014 +0000
Revision:
32:8f12ac182bbb
Parent:
31:a0bed6c1e05d
Child:
33:fb8fb5021b09
some improvement on cdma

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