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 11:48:04 2014 +0000
Revision:
31:a0bed6c1e05d
Parent:
30:1a647403171b
Child:
32:8f12ac182bbb
restructure the modem APIs make them more robust

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 31:a0bed6c1e05d 124 if (_dev.model == MODEL_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 31:a0bed6c1e05d 223 if (OK != waitFinalResp(_cbATI, &_dev.model))
mazgch 21:c4d64830bf02 224 return false;
mazgch 31:a0bed6c1e05d 225 if (_dev.model == MODEL_UNKNOWN)
mazgch 21:c4d64830bf02 226 return false;
mazgch 21:c4d64830bf02 227 // model specific init
mazgch 31:a0bed6c1e05d 228 if (_dev.model == MODEL_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 21:c4d64830bf02 233 // Return the pseudo ESN or MEID
mazgch 21:c4d64830bf02 234 sendFormated("AT+GSN\r\n");
mazgch 31:a0bed6c1e05d 235 if (OK != waitFinalResp(_cbString, _dev.imei))
mazgch 26:07be5faf8925 236 return false;
mazgch 26:07be5faf8925 237 } else {
mazgch 26:07be5faf8925 238 // disable flow control
mazgch 26:07be5faf8925 239 sendFormated("AT&K0\r\n");
mazgch 21:c4d64830bf02 240 if (OK != waitFinalResp())
mazgch 21:c4d64830bf02 241 return false;
mazgch 21:c4d64830bf02 242 // enable power saving
mazgch 21:c4d64830bf02 243 sendFormated("AT+UPSV=1\r\n");
mazgch 21:c4d64830bf02 244 if (OK != waitFinalResp())
mazgch 21:c4d64830bf02 245 return false;
mazgch 21:c4d64830bf02 246 // enable the network identification feature
mazgch 31:a0bed6c1e05d 247 if (_dev.model == MODEL_LISA_U200) {
mazgch 21:c4d64830bf02 248 sendFormated("AT+UGPIOC=20,2\r\n");
mazgch 21:c4d64830bf02 249 if (OK != waitFinalResp())
mazgch 21:c4d64830bf02 250 return false;
mazgch 21:c4d64830bf02 251 } else {
mazgch 21:c4d64830bf02 252 sendFormated("AT+UGPIOC=16,2\r\n");
mazgch 21:c4d64830bf02 253 if (OK != waitFinalResp())
mazgch 21:c4d64830bf02 254 return false;
mazgch 21:c4d64830bf02 255 }
mazgch 21:c4d64830bf02 256 // check the sim card
mazgch 31:a0bed6c1e05d 257 for (int i = 0; (i < 5) && (_dev.sim != SIM_READY); i++) {
mazgch 21:c4d64830bf02 258 sendFormated("AT+CPIN?\r\n");
mazgch 31:a0bed6c1e05d 259 int ret = waitFinalResp(_cbCPIN, &_dev.sim);
mazgch 21:c4d64830bf02 260 if ((OK != ret) && (ERROR != ret))
mazgch 21:c4d64830bf02 261 return false;
mazgch 31:a0bed6c1e05d 262 // Enter PIN if needed
mazgch 31:a0bed6c1e05d 263 if (_dev.sim == SIM_PIN) {
mazgch 31:a0bed6c1e05d 264 if (!pin) {
mazgch 31:a0bed6c1e05d 265 TRACE("SIM PIN not available\r\n");
mazgch 31:a0bed6c1e05d 266 return false;
mazgch 31:a0bed6c1e05d 267 }
mazgch 31:a0bed6c1e05d 268 sendFormated("AT+CPIN=%s\r\n", pin);
mazgch 31:a0bed6c1e05d 269 if (OK != waitFinalResp(_cbCPIN, &_dev.sim))
mazgch 31:a0bed6c1e05d 270 return false;
mazgch 31:a0bed6c1e05d 271 } else if (_dev.sim != SIM_READY)
mazgch 31:a0bed6c1e05d 272 wait_ms(1000);
mazgch 21:c4d64830bf02 273 }
mazgch 31:a0bed6c1e05d 274 if (_dev.sim != SIM_READY)
mazgch 21:c4d64830bf02 275 return false;
mazgch 21:c4d64830bf02 276 // Returns the ICCID (Integrated Circuit Card ID) of the SIM-card.
mazgch 21:c4d64830bf02 277 // ICCID is a serial number identifying the SIM.
mazgch 21:c4d64830bf02 278 sendFormated("AT+CCID\r\n");
mazgch 31:a0bed6c1e05d 279 if (OK != waitFinalResp(_cbCCID, _dev.ccid))
mazgch 21:c4d64830bf02 280 return false;
mazgch 21:c4d64830bf02 281 // Returns the product serial number, IMEI (International Mobile Equipment Identity)
mazgch 21:c4d64830bf02 282 sendFormated("AT+CGSN\r\n");
mazgch 31:a0bed6c1e05d 283 if (OK != waitFinalResp(_cbString, _dev.imei))
mazgch 21:c4d64830bf02 284 return false;
mazgch 21:c4d64830bf02 285 // Configure New message indication
mazgch 21:c4d64830bf02 286 //sendFormated("AT+CNMI=2,1,0,0,0\r\n");
mazgch 21:c4d64830bf02 287 //if (OK != waitFinalResp())
mazgch 21:c4d64830bf02 288 // return false;
mazgch 21:c4d64830bf02 289
mazgch 21:c4d64830bf02 290 }
mazgch 31:a0bed6c1e05d 291 // Setup SMS in text mode
mazgch 31:a0bed6c1e05d 292 sendFormated("AT+CMGF=1\r\n");
mazgch 31:a0bed6c1e05d 293 if (OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 294 return false;
mazgch 31:a0bed6c1e05d 295 // setup new message indication
mazgch 31:a0bed6c1e05d 296 sendFormated("AT+CNMI=1,1\r\n");
mazgch 31:a0bed6c1e05d 297 if (OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 298 return false;
mazgch 21:c4d64830bf02 299 // Request IMSI (International Mobile Subscriber Identification)
mazgch 21:c4d64830bf02 300 sendFormated("AT+CIMI\r\n");
mazgch 31:a0bed6c1e05d 301 if (OK != waitFinalResp(_cbString, _dev.imsi))
mazgch 21:c4d64830bf02 302 return false;
mazgch 28:4d9509e3b1cf 303 if (status)
mazgch 31:a0bed6c1e05d 304 memcpy(status, &_dev, sizeof(DevStatus));
mazgch 31:a0bed6c1e05d 305 return true;
mazgch 31:a0bed6c1e05d 306 }
mazgch 31:a0bed6c1e05d 307
mazgch 31:a0bed6c1e05d 308 int MDMParser::_cbATI(int type, const char* buf, int len, Model* model)
mazgch 31:a0bed6c1e05d 309 {
mazgch 31:a0bed6c1e05d 310 if ((type == TYPE_UNKNOWN) && model) {
mazgch 31:a0bed6c1e05d 311 if (strstr(buf, "SARA-G350")) {
mazgch 31:a0bed6c1e05d 312 *model = MODEL_SARA_G350;
mazgch 31:a0bed6c1e05d 313 /*TRACE("Identified Model: SARA-G350 2G\\n")*/;
mazgch 31:a0bed6c1e05d 314 } else if (strstr(buf, "LISA-U200")) {
mazgch 31:a0bed6c1e05d 315 *model = MODEL_LISA_U200;
mazgch 31:a0bed6c1e05d 316 /*TRACE("Identified Model: LISA-U200 2G/3G\r\n")*/;
mazgch 31:a0bed6c1e05d 317 } else if (strstr(buf, "LISA-C200")) {
mazgch 31:a0bed6c1e05d 318 *model= MODEL_LISA_C200;
mazgch 31:a0bed6c1e05d 319 /*TRACE("Identified Model: LISA-C200 CDMA\r\n")*/;
mazgch 31:a0bed6c1e05d 320 }
mazgch 28:4d9509e3b1cf 321 }
mazgch 31:a0bed6c1e05d 322 return WAIT;
mazgch 31:a0bed6c1e05d 323 }
mazgch 31:a0bed6c1e05d 324
mazgch 31:a0bed6c1e05d 325 int MDMParser::_cbCPIN(int type, const char* buf, int len, Sim* sim)
mazgch 31:a0bed6c1e05d 326 {
mazgch 31:a0bed6c1e05d 327 if ((type == TYPE_PLUS) && sim){
mazgch 31:a0bed6c1e05d 328 char s[16];
mazgch 31:a0bed6c1e05d 329 if (sscanf(buf, "\r\n+CPIN: %[^\r]\r<n", s) >= 1) {
mazgch 31:a0bed6c1e05d 330 *sim = (strcmp("READY", s) == 0) ? SIM_READY : SIM_PIN;
mazgch 31:a0bed6c1e05d 331 }
mazgch 31:a0bed6c1e05d 332 }
mazgch 31:a0bed6c1e05d 333 return WAIT;
mazgch 21:c4d64830bf02 334 }
mazgch 21:c4d64830bf02 335
mazgch 26:07be5faf8925 336 int MDMParser::_cbCCID(int type, const char* buf, int len, char* ccid)
mazgch 26:07be5faf8925 337 {
mazgch 26:07be5faf8925 338 if ((type == TYPE_PLUS) && ccid){
mazgch 26:07be5faf8925 339 if (sscanf(buf, "\r\n+CCID: %[^\r]\r\n", ccid) == 1)
mazgch 31:a0bed6c1e05d 340 /*TRACE("Got CCID: %s\r\n", ccid)*/;
mazgch 26:07be5faf8925 341 }
mazgch 26:07be5faf8925 342 return WAIT;
mazgch 26:07be5faf8925 343 }
mazgch 26:07be5faf8925 344
mazgch 28:4d9509e3b1cf 345 bool MDMParser::checkNetStatus(NetStatus* status /*= NULL*/)
mazgch 21:c4d64830bf02 346 {
mazgch 21:c4d64830bf02 347 // check registration
mazgch 21:c4d64830bf02 348 sendFormated("AT+CREG?\r\n");
mazgch 21:c4d64830bf02 349 if (OK != waitFinalResp())
mazgch 21:c4d64830bf02 350 return false;
mazgch 31:a0bed6c1e05d 351 if ((_net.reg != REG_ROAMING) && (_net.reg != REG_HOME))
mazgch 21:c4d64830bf02 352 return false;
mazgch 21:c4d64830bf02 353 // check modem specific status messages
mazgch 31:a0bed6c1e05d 354 if (_dev.model == MODEL_LISA_C200) {
mazgch 21:c4d64830bf02 355 sendFormated("AT+CSS?\r\n");
mazgch 21:c4d64830bf02 356 if (OK != waitFinalResp())
mazgch 21:c4d64830bf02 357 return false;
mazgch 31:a0bed6c1e05d 358 } else {
mazgch 31:a0bed6c1e05d 359 // check GPRS attach status
mazgch 31:a0bed6c1e05d 360 int state = 0;
mazgch 31:a0bed6c1e05d 361 sendFormated("AT+CGATT?\r\n");
mazgch 31:a0bed6c1e05d 362 if (OK != waitFinalResp(_cbCGATT, &state))
mazgch 21:c4d64830bf02 363 return false;
mazgch 31:a0bed6c1e05d 364 if (state != 1)
mazgch 31:a0bed6c1e05d 365 return false;
mazgch 21:c4d64830bf02 366 // check operator selection
mazgch 21:c4d64830bf02 367 sendFormated("AT+COPS?\r\n");
mazgch 31:a0bed6c1e05d 368 if (OK != waitFinalResp(_cbCOPS, &_net))
mazgch 21:c4d64830bf02 369 return false;
mazgch 21:c4d64830bf02 370 // Returns the MSISDNs related to this subscriber
mazgch 21:c4d64830bf02 371 sendFormated("AT+CNUM\r\n");
mazgch 31:a0bed6c1e05d 372 if (OK != waitFinalResp(_cbCNUM, _net.num))
mazgch 21:c4d64830bf02 373 return false;
mazgch 21:c4d64830bf02 374 }
mazgch 21:c4d64830bf02 375 // Returns the signal strength indication
mazgch 21:c4d64830bf02 376 sendFormated("AT+CSQ\r\n");
mazgch 31:a0bed6c1e05d 377 if (OK != waitFinalResp(_cbCSQ, &_net.rssi))
mazgch 21:c4d64830bf02 378 return false;
mazgch 28:4d9509e3b1cf 379 if (status) {
mazgch 31:a0bed6c1e05d 380 memcpy(status, &_net, sizeof(NetStatus));
mazgch 25:4045d02e44f1 381 }
mazgch 21:c4d64830bf02 382 return true;
mazgch 21:c4d64830bf02 383 }
mazgch 21:c4d64830bf02 384
mazgch 31:a0bed6c1e05d 385 int MDMParser::_cbCGATT(int type, const char* buf, int len, int* state)
mazgch 31:a0bed6c1e05d 386 {
mazgch 31:a0bed6c1e05d 387 if ((type == TYPE_PLUS) && state){
mazgch 31:a0bed6c1e05d 388 if (sscanf(buf, "\r\n+CGATT: %d\r\n", state) == 1)
mazgch 31:a0bed6c1e05d 389 /*TRACE("Got CGATT: %d\r\n", state)*/;
mazgch 31:a0bed6c1e05d 390 }
mazgch 31:a0bed6c1e05d 391 return WAIT;
mazgch 31:a0bed6c1e05d 392 }
mazgch 31:a0bed6c1e05d 393
mazgch 31:a0bed6c1e05d 394 int MDMParser::_cbCOPS(int type, const char* buf, int len, NetStatus* status)
mazgch 31:a0bed6c1e05d 395 {
mazgch 31:a0bed6c1e05d 396 if ((type == TYPE_PLUS) && status){
mazgch 31:a0bed6c1e05d 397 int act = 99;
mazgch 31:a0bed6c1e05d 398 // +COPS: <mode>[,<format>,<oper>[,<AcT>]]
mazgch 31:a0bed6c1e05d 399 if (sscanf(buf, "\r\n+COPS: %*d,%*d,\"%[^\"]\",%d",status->opr,&act) >= 1) {
mazgch 31:a0bed6c1e05d 400 if (act == 0) status->act = ACT_GSM; // 0: GSM,
mazgch 31:a0bed6c1e05d 401 else if (act == 2) status->act = ACT_UTRAN; // 2: UTRAN
mazgch 31:a0bed6c1e05d 402 }
mazgch 31:a0bed6c1e05d 403 }
mazgch 31:a0bed6c1e05d 404 return WAIT;
mazgch 31:a0bed6c1e05d 405 }
mazgch 31:a0bed6c1e05d 406
mazgch 31:a0bed6c1e05d 407 int MDMParser::_cbCNUM(int type, const char* buf, int len, char* num)
mazgch 31:a0bed6c1e05d 408 {
mazgch 31:a0bed6c1e05d 409 if ((type == TYPE_PLUS) && num){
mazgch 31:a0bed6c1e05d 410 int a;
mazgch 31:a0bed6c1e05d 411 if ((sscanf(buf, "\r\n+CNUM: \"My Number\",\"%31[^\"]\",%d", num, &a) == 2) &&
mazgch 31:a0bed6c1e05d 412 ((a == 129) || (a == 145))) {
mazgch 31:a0bed6c1e05d 413 }
mazgch 31:a0bed6c1e05d 414 }
mazgch 31:a0bed6c1e05d 415 return WAIT;
mazgch 31:a0bed6c1e05d 416 }
mazgch 31:a0bed6c1e05d 417
mazgch 31:a0bed6c1e05d 418 int MDMParser::_cbCSQ(int type, const char* buf, int len, int* rssi)
mazgch 31:a0bed6c1e05d 419 {
mazgch 31:a0bed6c1e05d 420 if ((type == TYPE_PLUS) && rssi){
mazgch 31:a0bed6c1e05d 421 int a;
mazgch 31:a0bed6c1e05d 422 // +CSQ: <rssi>,<qual>
mazgch 31:a0bed6c1e05d 423 if (sscanf(buf, "\r\n+CSQ: %d,%*d",&a) == 1) {
mazgch 31:a0bed6c1e05d 424 if (a != 99) *rssi = -113 + 2*a; // 0: -113 1: -111 ... 30: -53 dBm with 2 dBm steps
mazgch 31:a0bed6c1e05d 425 //if (b != 99) int qual = b; //
mazgch 31:a0bed6c1e05d 426 }
mazgch 31:a0bed6c1e05d 427 }
mazgch 31:a0bed6c1e05d 428 return WAIT;
mazgch 31:a0bed6c1e05d 429 }
mazgch 21:c4d64830bf02 430 bool MDMParser::powerOff(void)
mazgch 21:c4d64830bf02 431 {
mazgch 21:c4d64830bf02 432 sendFormated("AT+CPWROFF\r\n");
mazgch 21:c4d64830bf02 433 if (OK != waitFinalResp(NULL,NULL,120))
mazgch 21:c4d64830bf02 434 return false;
mazgch 21:c4d64830bf02 435 return true;
mazgch 21:c4d64830bf02 436 }
mazgch 21:c4d64830bf02 437
mazgch 21:c4d64830bf02 438 // ----------------------------------------------------------------
mazgch 21:c4d64830bf02 439 // internet connection
mazgch 21:c4d64830bf02 440
mazgch 31:a0bed6c1e05d 441 MDMParser::IP MDMParser::join(const char* apn /*= NULL*/, const char* user /*= NULL*/, const char* password /*= NULL*/)
mazgch 21:c4d64830bf02 442 {
mazgch 31:a0bed6c1e05d 443 IP ip = NOIP;
mazgch 31:a0bed6c1e05d 444 if (_dev.model == MODEL_LISA_C200) {
mazgch 21:c4d64830bf02 445 #ifdef TODO // TODO implement
mazgch 21:c4d64830bf02 446 // enable the
mazgch 21:c4d64830bf02 447 sendFormated("AT$QCMIPEP=1\r\n");
mazgch 21:c4d64830bf02 448 if (OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 449 return NOIP;
mazgch 21:c4d64830bf02 450 //Get local IP address
mazgch 21:c4d64830bf02 451 sendFormated("AT+CMIP?\r\n");
mazgch 31:a0bed6c1e05d 452 // extract: +CMIP: xxx.xxx.xxx.xxx
mazgch 21:c4d64830bf02 453 if (OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 454 return NOIP;
mazgch 31:a0bed6c1e05d 455
mazgch 21:c4d64830bf02 456 #endif
mazgch 21:c4d64830bf02 457 } else {
mazgch 21:c4d64830bf02 458 // check gprs attach status
mazgch 21:c4d64830bf02 459 sendFormated("AT+CGATT?\r\n");
mazgch 21:c4d64830bf02 460 if (OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 461 return NOIP;
mazgch 31:a0bed6c1e05d 462
mazgch 31:a0bed6c1e05d 463 // Check the profile
mazgch 31:a0bed6c1e05d 464 int a = 0;
mazgch 31:a0bed6c1e05d 465 sendFormated("AT+UPSND=" PROFILE ",8\r\n");
mazgch 31:a0bed6c1e05d 466 if (OK != waitFinalResp(_cbUPSND, &a))
mazgch 31:a0bed6c1e05d 467 return NOIP;
mazgch 31:a0bed6c1e05d 468 if (a == 1) {
mazgch 31:a0bed6c1e05d 469 // disconnect the profile already if it is connected
mazgch 31:a0bed6c1e05d 470 sendFormated("AT+UPSDA=" PROFILE ",4\r\n");
mazgch 31:a0bed6c1e05d 471 if (OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 472 return NOIP;;
mazgch 31:a0bed6c1e05d 473 }
mazgch 31:a0bed6c1e05d 474 // Set up the APN
mazgch 21:c4d64830bf02 475 if (apn) {
mazgch 21:c4d64830bf02 476 sendFormated("AT+UPSD=" PROFILE ",1,\"%s\"\r\n", apn);
mazgch 21:c4d64830bf02 477 if (OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 478 return NOIP;
mazgch 21:c4d64830bf02 479 }
mazgch 21:c4d64830bf02 480 if (user) {
mazgch 21:c4d64830bf02 481 sendFormated("AT+UPSD=" PROFILE ",2,\"%s\"\r\n", user);
mazgch 21:c4d64830bf02 482 if (OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 483 return NOIP;
mazgch 21:c4d64830bf02 484 }
mazgch 21:c4d64830bf02 485 if (password) {
mazgch 21:c4d64830bf02 486 sendFormated("AT+UPSD=" PROFILE ",3,\"%s\"\r\n", password);
mazgch 21:c4d64830bf02 487 if (OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 488 return NOIP;
mazgch 21:c4d64830bf02 489 }
mazgch 21:c4d64830bf02 490 // Set up the dynamic IP address assignment.
mazgch 21:c4d64830bf02 491 sendFormated("AT+UPSD=" PROFILE ",7,\"0.0.0.0\"\r\n");
mazgch 21:c4d64830bf02 492 if (OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 493 return NOIP;
mazgch 21:c4d64830bf02 494 // Activate the profile and make connection
mazgch 21:c4d64830bf02 495 sendFormated("AT+UPSDA=" PROFILE ",3\r\n");
mazgch 21:c4d64830bf02 496 if (OK != waitFinalResp())
mazgch 31:a0bed6c1e05d 497 return NOIP;
mazgch 21:c4d64830bf02 498 //Get local IP address
mazgch 21:c4d64830bf02 499 sendFormated("AT+UPSND=" PROFILE ",0\r\n");
mazgch 31:a0bed6c1e05d 500 if (OK != waitFinalResp(_cbUPSND, &ip))
mazgch 31:a0bed6c1e05d 501 return NOIP;
mazgch 31:a0bed6c1e05d 502 }
mazgch 31:a0bed6c1e05d 503 return ip;
mazgch 31:a0bed6c1e05d 504 }
mazgch 31:a0bed6c1e05d 505
mazgch 31:a0bed6c1e05d 506 int MDMParser::_cbUPSND(int type, const char* buf, int len, int* act)
mazgch 31:a0bed6c1e05d 507 {
mazgch 31:a0bed6c1e05d 508 if ((type == TYPE_PLUS) && act) {
mazgch 31:a0bed6c1e05d 509 if (sscanf(buf, "\r\n+UPSND: %*d,%*d,%d", act) == 1)
mazgch 31:a0bed6c1e05d 510 /*nothing*/;
mazgch 21:c4d64830bf02 511 }
mazgch 31:a0bed6c1e05d 512 return WAIT;
mazgch 31:a0bed6c1e05d 513 }
mazgch 31:a0bed6c1e05d 514
mazgch 31:a0bed6c1e05d 515 int MDMParser::_cbUPSND(int type, const char* buf, int len, IP* ip)
mazgch 31:a0bed6c1e05d 516 {
mazgch 31:a0bed6c1e05d 517 if ((type == TYPE_PLUS) && ip) {
mazgch 31:a0bed6c1e05d 518 int a,b,c,d;
mazgch 31:a0bed6c1e05d 519 // +UPSND=<profile_id>,<param_tag>[,<dynamic_param_val>]
mazgch 31:a0bed6c1e05d 520 if (sscanf(buf, "\r\n+UPSND: " PROFILE ",0,\"" IPSTR "\"", &a,&b,&c,&d) == 4)
mazgch 31:a0bed6c1e05d 521 *ip = IPADR(a,b,c,d);
mazgch 31:a0bed6c1e05d 522 }
mazgch 31:a0bed6c1e05d 523 return WAIT;
mazgch 31:a0bed6c1e05d 524 }
mazgch 31:a0bed6c1e05d 525
mazgch 31:a0bed6c1e05d 526 int MDMParser::_cbUDNSRN(int type, const char* buf, int len, IP* ip)
mazgch 31:a0bed6c1e05d 527 {
mazgch 31:a0bed6c1e05d 528 if ((type == TYPE_PLUS) && ip) {
mazgch 31:a0bed6c1e05d 529 int a,b,c,d;
mazgch 31:a0bed6c1e05d 530 if (sscanf(buf, "\r\n+UDNSRN: \""IPSTR"\"", &a,&b,&c,&d) == 4)
mazgch 31:a0bed6c1e05d 531 *ip = IPADR(a,b,c,d);
mazgch 31:a0bed6c1e05d 532 }
mazgch 31:a0bed6c1e05d 533 return WAIT;
mazgch 21:c4d64830bf02 534 }
mazgch 21:c4d64830bf02 535
mazgch 21:c4d64830bf02 536 bool MDMParser::disconnect(void)
mazgch 21:c4d64830bf02 537 {
mazgch 31:a0bed6c1e05d 538 if (_ip == NOIP)
mazgch 21:c4d64830bf02 539 return true;
mazgch 31:a0bed6c1e05d 540 if (_dev.model == MODEL_LISA_C200) {
mazgch 21:c4d64830bf02 541 #ifdef TODO // TODO implement
mazgch 21:c4d64830bf02 542 sendFormated("AT$QCMIPEP=0\r\n");
mazgch 21:c4d64830bf02 543 #endif
mazgch 21:c4d64830bf02 544 } else {
mazgch 21:c4d64830bf02 545 sendFormated("AT+UPSDA=" PROFILE ",4\r\n");
mazgch 21:c4d64830bf02 546 }
mazgch 21:c4d64830bf02 547 if (OK != waitFinalResp())
mazgch 21:c4d64830bf02 548 return false;
mazgch 31:a0bed6c1e05d 549 _ip = NOIP;
mazgch 21:c4d64830bf02 550 return true;
mazgch 21:c4d64830bf02 551 }
mazgch 21:c4d64830bf02 552
mazgch 31:a0bed6c1e05d 553 MDMParser::IP MDMParser::gethostbyname(const char* host)
mazgch 21:c4d64830bf02 554 {
mazgch 31:a0bed6c1e05d 555 IP ip = NOIP;
mazgch 31:a0bed6c1e05d 556 int a,b,c,d;
mazgch 31:a0bed6c1e05d 557 if (sscanf(host, IPSTR, &a,&b,&c,&d) == 4)
mazgch 31:a0bed6c1e05d 558 ip = IPADR(a,b,c,d);
mazgch 31:a0bed6c1e05d 559 else {
mazgch 31:a0bed6c1e05d 560 sendFormated("AT+UDNSRN=0,\"%s\"\r\n", host);
mazgch 31:a0bed6c1e05d 561 if (OK != waitFinalResp(_cbUDNSRN, &ip))
mazgch 31:a0bed6c1e05d 562 return false;
mazgch 21:c4d64830bf02 563 }
mazgch 31:a0bed6c1e05d 564 return ip;
mazgch 21:c4d64830bf02 565 }
mazgch 21:c4d64830bf02 566
mazgch 21:c4d64830bf02 567 // ----------------------------------------------------------------
mazgch 21:c4d64830bf02 568 // sockets
mazgch 21:c4d64830bf02 569
mazgch 21:c4d64830bf02 570 int MDMParser::_cbUSOCR(int type, const char* buf, int len, int* socket)
mazgch 21:c4d64830bf02 571 {
mazgch 21:c4d64830bf02 572 if ((type == TYPE_PLUS) && socket) {
mazgch 21:c4d64830bf02 573 const char* p = strstr(buf,"+USOCR: ");
mazgch 21:c4d64830bf02 574 if (p)
mazgch 21:c4d64830bf02 575 *socket = atoi(p+8);
mazgch 21:c4d64830bf02 576 }
mazgch 21:c4d64830bf02 577 return WAIT;
mazgch 21:c4d64830bf02 578 }
mazgch 21:c4d64830bf02 579
mazgch 21:c4d64830bf02 580 int MDMParser::socketSocket(IpProtocol ipproto)
mazgch 21:c4d64830bf02 581 {
mazgch 21:c4d64830bf02 582 const char* cmd;
mazgch 21:c4d64830bf02 583 if(ipproto == IPPROTO_TCP) {
mazgch 21:c4d64830bf02 584 cmd = "AT+USOCR=6\r\n";
mazgch 21:c4d64830bf02 585 } else if(ipproto == IPPROTO_UDP) {
mazgch 21:c4d64830bf02 586 cmd = "AT+USOCR=17\r\n";
mazgch 21:c4d64830bf02 587 } else { // other types not supported
mazgch 21:c4d64830bf02 588 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 589 }
mazgch 21:c4d64830bf02 590 sendFormated(cmd);
mazgch 21:c4d64830bf02 591 int socket = -1;
mazgch 26:07be5faf8925 592 if (OK != waitFinalResp(_cbUSOCR, &socket))
mazgch 21:c4d64830bf02 593 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 594 if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_FREE))
mazgch 21:c4d64830bf02 595 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 596 // successfull
mazgch 21:c4d64830bf02 597 _sockets[socket].state = SOCK_CREATED;
mazgch 21:c4d64830bf02 598 _sockets[socket].pending = 0;
mazgch 21:c4d64830bf02 599 return socket;
mazgch 21:c4d64830bf02 600 }
mazgch 21:c4d64830bf02 601
mazgch 21:c4d64830bf02 602 bool MDMParser::socketConnect(int socket, const char * host, int port)
mazgch 21:c4d64830bf02 603 {
mazgch 31:a0bed6c1e05d 604 IP ip = gethostbyname(host);
mazgch 31:a0bed6c1e05d 605 if (ip == NOIP)
mazgch 21:c4d64830bf02 606 return false;
mazgch 21:c4d64830bf02 607 // connect to socket
mazgch 21:c4d64830bf02 608 if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CREATED))
mazgch 21:c4d64830bf02 609 return false;
mazgch 21:c4d64830bf02 610 sendFormated("AT+USOCO=%d,\"" IPSTR "\",%d\r\n", socket, IPNUM(ip), port);
mazgch 21:c4d64830bf02 611 if (OK != waitFinalResp())
mazgch 21:c4d64830bf02 612 return false;
mazgch 21:c4d64830bf02 613 _sockets[socket].state = SOCK_CONNECTED;
mazgch 21:c4d64830bf02 614 return true;
mazgch 21:c4d64830bf02 615 }
mazgch 21:c4d64830bf02 616
mazgch 21:c4d64830bf02 617 bool MDMParser::socketClose(int socket)
mazgch 21:c4d64830bf02 618 {
mazgch 21:c4d64830bf02 619 if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CONNECTED))
mazgch 21:c4d64830bf02 620 return false;
mazgch 21:c4d64830bf02 621 sendFormated("AT+USOCL=%d\r\n", socket);
mazgch 21:c4d64830bf02 622 if (OK != waitFinalResp())
mazgch 21:c4d64830bf02 623 return false;
mazgch 21:c4d64830bf02 624 return true;
mazgch 21:c4d64830bf02 625 }
mazgch 21:c4d64830bf02 626
mazgch 21:c4d64830bf02 627 bool MDMParser::socketFree(int socket)
mazgch 21:c4d64830bf02 628 {
mazgch 21:c4d64830bf02 629 socketClose(socket);
mazgch 21:c4d64830bf02 630 if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CREATED))
mazgch 21:c4d64830bf02 631 return false;
mazgch 21:c4d64830bf02 632 _sockets[socket].state = SOCK_FREE;
mazgch 21:c4d64830bf02 633 return true;
mazgch 21:c4d64830bf02 634 }
mazgch 21:c4d64830bf02 635
mazgch 21:c4d64830bf02 636 int MDMParser::socketSend(int socket, const char * buf, int len)
mazgch 21:c4d64830bf02 637 {
mazgch 21:c4d64830bf02 638 if(len > 0) {
mazgch 21:c4d64830bf02 639 sendFormated("AT+USOWR=%d,%d\r\n",socket,len);
mazgch 21:c4d64830bf02 640 if (PROMPT != waitFinalResp())
mazgch 21:c4d64830bf02 641 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 642 wait_ms(50);
mazgch 21:c4d64830bf02 643 send(buf, len);
mazgch 21:c4d64830bf02 644 if (OK != waitFinalResp())
mazgch 21:c4d64830bf02 645 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 646 }
mazgch 21:c4d64830bf02 647 return len;
mazgch 21:c4d64830bf02 648 }
mazgch 21:c4d64830bf02 649
mazgch 21:c4d64830bf02 650 int MDMParser::socketSendTo(int socket, IP ip, int port, const char * buf, int len)
mazgch 21:c4d64830bf02 651 {
mazgch 21:c4d64830bf02 652 if(len > 0) {
mazgch 21:c4d64830bf02 653 sendFormated("AT+USOWR=%d,\"" IPSTR "\",%d,%d\r\n",socket,IPNUM(ip),port,len);
mazgch 21:c4d64830bf02 654 if (PROMPT != waitFinalResp())
mazgch 21:c4d64830bf02 655 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 656 wait_ms(50);
mazgch 21:c4d64830bf02 657 send(buf, len);
mazgch 21:c4d64830bf02 658 if (OK != waitFinalResp())
mazgch 21:c4d64830bf02 659 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 660 }
mazgch 21:c4d64830bf02 661 return len;
mazgch 21:c4d64830bf02 662 }
mazgch 21:c4d64830bf02 663
mazgch 21:c4d64830bf02 664 int MDMParser::socketReadable(int socket)
mazgch 21:c4d64830bf02 665 {
mazgch 21:c4d64830bf02 666 if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CONNECTED))
mazgch 21:c4d64830bf02 667 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 668 // allow to receive unsolicited commands
mazgch 21:c4d64830bf02 669 waitFinalResp(NULL, NULL, 0);
mazgch 21:c4d64830bf02 670 if (_sockets[socket].state != SOCK_CONNECTED)
mazgch 21:c4d64830bf02 671 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 672 return _sockets[socket].pending;
mazgch 21:c4d64830bf02 673 }
mazgch 21:c4d64830bf02 674
mazgch 21:c4d64830bf02 675 int MDMParser::_cbUSORD(int type, const char* buf, int len, char* out)
mazgch 21:c4d64830bf02 676 {
mazgch 21:c4d64830bf02 677 if ((type == TYPE_PLUS) && out) {
mazgch 21:c4d64830bf02 678 int sz, sk;
mazgch 21:c4d64830bf02 679 if ((sscanf(buf, "\r\n+USORD: %d,%d,", &sk, &sz) == 2) &&
mazgch 21:c4d64830bf02 680 (buf[len-sz-2] == '\"') && (buf[len-1] == '\"')) {
mazgch 21:c4d64830bf02 681 memcpy(out, &buf[len-1-sz], sz);
mazgch 21:c4d64830bf02 682 }
mazgch 21:c4d64830bf02 683 }
mazgch 21:c4d64830bf02 684 return WAIT;
mazgch 21:c4d64830bf02 685 }
mazgch 21:c4d64830bf02 686
mazgch 21:c4d64830bf02 687 int MDMParser::socketRecv(int socket, char* buf, int len)
mazgch 21:c4d64830bf02 688 {
mazgch 21:c4d64830bf02 689 int cnt = 0;
mazgch 21:c4d64830bf02 690 if (!ISSOCKET(socket))
mazgch 21:c4d64830bf02 691 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 692 memset(buf, '\0', len);
mazgch 21:c4d64830bf02 693 while (len) {
mazgch 21:c4d64830bf02 694 int blk = MAX_SIZE - 64; // still need space for headers and unsolicited commands
mazgch 21:c4d64830bf02 695 if (_sockets[socket].state != SOCK_CONNECTED)
mazgch 21:c4d64830bf02 696 return cnt ? cnt : SOCKET_ERROR;
mazgch 21:c4d64830bf02 697 if (_sockets[socket].pending < blk)
mazgch 21:c4d64830bf02 698 blk = _sockets[socket].pending;
mazgch 21:c4d64830bf02 699 if (len < blk) blk = len;
mazgch 21:c4d64830bf02 700 if (blk) {
mazgch 21:c4d64830bf02 701 sendFormated("AT+USORD=%d,%d\r\n",socket, blk);
mazgch 26:07be5faf8925 702 if (OK != waitFinalResp(_cbUSORD, buf)) {
mazgch 21:c4d64830bf02 703 return cnt ? cnt : SOCKET_ERROR;
mazgch 21:c4d64830bf02 704 }
mazgch 21:c4d64830bf02 705 len -= blk;
mazgch 21:c4d64830bf02 706 cnt += blk;
mazgch 21:c4d64830bf02 707 buf += blk;
mazgch 21:c4d64830bf02 708 _sockets[socket].pending -= blk;
mazgch 21:c4d64830bf02 709 } else {
mazgch 21:c4d64830bf02 710 // allow to receive unsolicited commands
mazgch 21:c4d64830bf02 711 waitFinalResp(NULL, NULL, 10);
mazgch 21:c4d64830bf02 712 }
mazgch 21:c4d64830bf02 713 }
mazgch 21:c4d64830bf02 714 return cnt;
mazgch 21:c4d64830bf02 715 }
mazgch 21:c4d64830bf02 716
mazgch 21:c4d64830bf02 717 int MDMParser::_cbUSORF(int type, const char* buf, int len, USORFparam* param)
mazgch 21:c4d64830bf02 718 {
mazgch 21:c4d64830bf02 719 if ((type == TYPE_PLUS) && param) {
mazgch 21:c4d64830bf02 720 int sz, sk, p, a,b,c,d;
mazgch 21:c4d64830bf02 721 if ((sscanf(buf, "\r\n+USORF: %d,\""IPSTR"\",%d,%d,",
mazgch 21:c4d64830bf02 722 &sk,&a,&b,&c,&d,&p,&sz) == 7) &&
mazgch 21:c4d64830bf02 723 (buf[len-sz-2] == '\"') && (buf[len-1] == '\"')) {
mazgch 21:c4d64830bf02 724 memcpy(param->buf, &buf[len-1-sz], sz);
mazgch 21:c4d64830bf02 725 param->ip = IPADR(a,b,c,d);
mazgch 21:c4d64830bf02 726 param->port = p;
mazgch 21:c4d64830bf02 727 }
mazgch 21:c4d64830bf02 728 }
mazgch 21:c4d64830bf02 729 return WAIT;
mazgch 21:c4d64830bf02 730 }
mazgch 21:c4d64830bf02 731
mazgch 21:c4d64830bf02 732 int MDMParser::socketRecvFrom(int socket, char* buf, int len, IP* ip)
mazgch 21:c4d64830bf02 733 {
mazgch 21:c4d64830bf02 734 int cnt = 0;
mazgch 21:c4d64830bf02 735 if (!ISSOCKET(socket))
mazgch 21:c4d64830bf02 736 return SOCKET_ERROR;
mazgch 21:c4d64830bf02 737 memset(buf, '\0', len);
mazgch 21:c4d64830bf02 738 while (len) {
mazgch 21:c4d64830bf02 739 int blk = MAX_SIZE - 64; // still need space for headers and unsolicited commands
mazgch 21:c4d64830bf02 740 if (_sockets[socket].state != SOCK_CONNECTED)
mazgch 21:c4d64830bf02 741 return cnt ? cnt : SOCKET_ERROR;
mazgch 21:c4d64830bf02 742 if (_sockets[socket].pending < blk)
mazgch 21:c4d64830bf02 743 blk = _sockets[socket].pending;
mazgch 21:c4d64830bf02 744 if (len < blk) blk = len;
mazgch 21:c4d64830bf02 745 if (blk) {
mazgch 21:c4d64830bf02 746 sendFormated("AT+USORF=%d,%d\r\n",socket, blk);
mazgch 21:c4d64830bf02 747 USORFparam param;
mazgch 21:c4d64830bf02 748 param.buf = buf;
mazgch 26:07be5faf8925 749 if (OK != waitFinalResp(_cbUSORF, &param)) {
mazgch 21:c4d64830bf02 750 return cnt ? cnt : SOCKET_ERROR;
mazgch 21:c4d64830bf02 751 }
mazgch 21:c4d64830bf02 752 *ip = param.ip;
mazgch 21:c4d64830bf02 753 //*port = param.port;
mazgch 21:c4d64830bf02 754 len -= blk;
mazgch 21:c4d64830bf02 755 cnt += blk;
mazgch 21:c4d64830bf02 756 buf += blk;
mazgch 21:c4d64830bf02 757 _sockets[socket].pending -= blk;
mazgch 21:c4d64830bf02 758 } else {
mazgch 21:c4d64830bf02 759 // allow to receive unsolicited commands
mazgch 21:c4d64830bf02 760 waitFinalResp(NULL, NULL, 10);
mazgch 21:c4d64830bf02 761 }
mazgch 21:c4d64830bf02 762 }
mazgch 21:c4d64830bf02 763 return cnt;
mazgch 21:c4d64830bf02 764 }
mazgch 21:c4d64830bf02 765
mazgch 21:c4d64830bf02 766 // ----------------------------------------------------------------
mazgch 31:a0bed6c1e05d 767
mazgch 31:a0bed6c1e05d 768 int MDMParser::_cbCMGL(int type, const char* buf, int len, CMGLparam* param)
mazgch 21:c4d64830bf02 769 {
mazgch 31:a0bed6c1e05d 770 if ((type == TYPE_PLUS) && param && param->num) {
mazgch 31:a0bed6c1e05d 771 // +CMGL: <ix>,...
mazgch 31:a0bed6c1e05d 772 int ix;
mazgch 31:a0bed6c1e05d 773 if (sscanf(buf, "\r\n+CMGL: %d,", &ix) == 1)
mazgch 31:a0bed6c1e05d 774 {
mazgch 31:a0bed6c1e05d 775 *param->ix++ = ix;
mazgch 31:a0bed6c1e05d 776 param->num--;
mazgch 31:a0bed6c1e05d 777 }
mazgch 29:53d346010624 778 }
mazgch 29:53d346010624 779 return WAIT;
mazgch 21:c4d64830bf02 780 }
mazgch 21:c4d64830bf02 781
mazgch 31:a0bed6c1e05d 782 int MDMParser::smsList(const char* stat /*= "ALL"*/, int* ix /*=NULL*/, int num /*= 0*/) {
mazgch 31:a0bed6c1e05d 783 sendFormated("AT+CMGL=\"%s\"\r\n", stat);
mazgch 31:a0bed6c1e05d 784 CMGLparam param;
mazgch 31:a0bed6c1e05d 785 param.ix = ix;
mazgch 31:a0bed6c1e05d 786 param.num = num;
mazgch 31:a0bed6c1e05d 787 if (OK != waitFinalResp(_cbCMGL, &param))
mazgch 31:a0bed6c1e05d 788 return -1;
mazgch 31:a0bed6c1e05d 789 return num - param.num;
mazgch 21:c4d64830bf02 790 }
mazgch 21:c4d64830bf02 791
mazgch 21:c4d64830bf02 792 bool MDMParser::smsSend(const char* num, const char* buf)
mazgch 21:c4d64830bf02 793 {
mazgch 21:c4d64830bf02 794 sendFormated("AT+CMGS=\"%s\"\r",num);
mazgch 21:c4d64830bf02 795 if (PROMPT != waitFinalResp()) {
mazgch 21:c4d64830bf02 796 return false;
mazgch 21:c4d64830bf02 797 }
mazgch 21:c4d64830bf02 798 send(buf, strlen(buf));
mazgch 21:c4d64830bf02 799 const char ctrlZ = 0x1A;
mazgch 21:c4d64830bf02 800 send(&ctrlZ, sizeof(ctrlZ));
mazgch 21:c4d64830bf02 801 if (OK != waitFinalResp()) {
mazgch 21:c4d64830bf02 802 return false;
mazgch 21:c4d64830bf02 803 }
mazgch 21:c4d64830bf02 804 return true;
mazgch 21:c4d64830bf02 805 }
mazgch 21:c4d64830bf02 806
mazgch 21:c4d64830bf02 807 bool MDMParser::smsDelete(int ix)
mazgch 21:c4d64830bf02 808 {
mazgch 21:c4d64830bf02 809 sendFormated("AT+CMGD=%d\r\n",ix);
mazgch 21:c4d64830bf02 810 if (OK != waitFinalResp()) {
mazgch 21:c4d64830bf02 811 return false;
mazgch 21:c4d64830bf02 812 }
mazgch 21:c4d64830bf02 813 return true;
mazgch 21:c4d64830bf02 814 }
mazgch 21:c4d64830bf02 815
mazgch 21:c4d64830bf02 816 int MDMParser::_cbCMGR(int type, const char* buf, int len, CMGRparam* param)
mazgch 21:c4d64830bf02 817 {
mazgch 21:c4d64830bf02 818 if (param) {
mazgch 21:c4d64830bf02 819 if (type == TYPE_PLUS) {
mazgch 21:c4d64830bf02 820 if (sscanf(buf, "\r\n+CMGR: \"%*[^\"]\",\"%[^\"]", param->num) == 1) {
mazgch 21:c4d64830bf02 821 }
mazgch 21:c4d64830bf02 822 } else if ((type == TYPE_UNKNOWN) && (buf[len-2] == '\r') && (buf[len-1] == '\n')) {
mazgch 21:c4d64830bf02 823 memcpy(param->buf, buf, len-2);
mazgch 21:c4d64830bf02 824 param->buf[len-2] = '\0';
mazgch 21:c4d64830bf02 825 }
mazgch 21:c4d64830bf02 826 }
mazgch 21:c4d64830bf02 827 return WAIT;
mazgch 21:c4d64830bf02 828 }
mazgch 21:c4d64830bf02 829
mazgch 21:c4d64830bf02 830 bool MDMParser::smsRead(int ix, char* num, char* buf, int len)
mazgch 21:c4d64830bf02 831 {
mazgch 21:c4d64830bf02 832 CMGRparam param;
mazgch 21:c4d64830bf02 833 param.num = num;
mazgch 21:c4d64830bf02 834 param.buf = buf;
mazgch 21:c4d64830bf02 835 sendFormated("AT+CMGR=%d\r\n",ix);
mazgch 26:07be5faf8925 836 if (OK != waitFinalResp(_cbCMGR, &param)) {
mazgch 21:c4d64830bf02 837 return false;
mazgch 21:c4d64830bf02 838 }
mazgch 21:c4d64830bf02 839 return true;
mazgch 21:c4d64830bf02 840 }
mazgch 21:c4d64830bf02 841
mazgch 21:c4d64830bf02 842 // ----------------------------------------------------------------
mazgch 21:c4d64830bf02 843
mazgch 21:c4d64830bf02 844 int MDMParser::_cbCUSD(int type, const char* buf, int len, char* resp)
mazgch 21:c4d64830bf02 845 {
mazgch 21:c4d64830bf02 846 if ((type == TYPE_PLUS) && resp) {
mazgch 21:c4d64830bf02 847 // +USD: \"%*[^\"]\",\"%[^\"]\",,\"%*[^\"]\",%d,%d,%d,%d,\"*[^\"]\",%d,%d"..);
mazgch 21:c4d64830bf02 848 if (sscanf(buf, "\r\n+CUSD: %*d,\"%[^\"]\",%*d", resp) == 1) {
mazgch 21:c4d64830bf02 849 /*nothing*/
mazgch 21:c4d64830bf02 850 }
mazgch 21:c4d64830bf02 851 }
mazgch 21:c4d64830bf02 852 return WAIT;
mazgch 21:c4d64830bf02 853 }
mazgch 31:a0bed6c1e05d 854
mazgch 31:a0bed6c1e05d 855 bool MDMParser::ussdCommand(const char* cmd, char* buf)
mazgch 21:c4d64830bf02 856 {
mazgch 21:c4d64830bf02 857 *buf = '\0';
mazgch 21:c4d64830bf02 858 sendFormated("AT+CUSD=1,\"%s\"\r\n",cmd);
mazgch 26:07be5faf8925 859 if (OK != waitFinalResp(_cbCUSD, buf)) {
mazgch 31:a0bed6c1e05d 860 return false;
mazgch 21:c4d64830bf02 861 }
mazgch 31:a0bed6c1e05d 862 return true;
mazgch 21:c4d64830bf02 863 }
mazgch 26:07be5faf8925 864
mazgch 21:c4d64830bf02 865 // ----------------------------------------------------------------
mazgch 21:c4d64830bf02 866 int MDMParser::_parseMatch(Pipe<char>* pipe, int len, const char* sta, const char* end)
mazgch 18:e5697801df29 867 {
mazgch 18:e5697801df29 868 int o = 0;
mazgch 21:c4d64830bf02 869 if (sta) {
mazgch 21:c4d64830bf02 870 while (*sta) {
mazgch 21:c4d64830bf02 871 if (++o > len) return WAIT;
mazgch 21:c4d64830bf02 872 char ch = pipe->next();
mazgch 21:c4d64830bf02 873 if (*sta++ != ch) return NOT_FOUND;
mazgch 21:c4d64830bf02 874 }
mazgch 21:c4d64830bf02 875 }
mazgch 21:c4d64830bf02 876 if (!end) return o; // no termination
mazgch 21:c4d64830bf02 877 int x = 0;
mazgch 21:c4d64830bf02 878 while (end[x]) {
mazgch 21:c4d64830bf02 879 if (++o > len) return WAIT;
mazgch 21:c4d64830bf02 880 char ch = pipe->next();
mazgch 21:c4d64830bf02 881 x = (end[x] == ch) ? x + 1 :
mazgch 21:c4d64830bf02 882 (end[0] == ch) ? 1 :
mazgch 21:c4d64830bf02 883 0;
mazgch 21:c4d64830bf02 884 }
mazgch 21:c4d64830bf02 885 return o;
mazgch 21:c4d64830bf02 886 }
mazgch 21:c4d64830bf02 887
mazgch 21:c4d64830bf02 888 int MDMParser::_parseFormated(Pipe<char>* pipe, int len, const char* fmt)
mazgch 21:c4d64830bf02 889 {
mazgch 21:c4d64830bf02 890 int o = 0;
mazgch 21:c4d64830bf02 891 int num = 0;
mazgch 21:c4d64830bf02 892 if (fmt) {
mazgch 21:c4d64830bf02 893 while (*fmt) {
mazgch 21:c4d64830bf02 894 if (++o > len) return WAIT;
mazgch 21:c4d64830bf02 895 char ch = pipe->next();
mazgch 21:c4d64830bf02 896 if (*fmt == '%') {
mazgch 21:c4d64830bf02 897 fmt++;
mazgch 21:c4d64830bf02 898 if (*fmt == 'd') { // numeric
mazgch 21:c4d64830bf02 899 fmt ++;
mazgch 21:c4d64830bf02 900 num = 0;
mazgch 21:c4d64830bf02 901 while (ch >= '0' && ch <= '9') {
mazgch 21:c4d64830bf02 902 num = num * 10 + (ch - '0');
mazgch 21:c4d64830bf02 903 if (++o > len) return WAIT;
mazgch 21:c4d64830bf02 904 ch = pipe->next();
mazgch 21:c4d64830bf02 905 }
mazgch 21:c4d64830bf02 906 }
mazgch 21:c4d64830bf02 907 else if (*fmt == 'c') { // char buffer (takes last numeric as length)
mazgch 21:c4d64830bf02 908 fmt ++;
mazgch 21:c4d64830bf02 909 while (num --) {
mazgch 21:c4d64830bf02 910 if (++o > len) return WAIT;
mazgch 21:c4d64830bf02 911 ch = pipe->next();
mazgch 21:c4d64830bf02 912 }
mazgch 21:c4d64830bf02 913 }
mazgch 21:c4d64830bf02 914 }
mazgch 21:c4d64830bf02 915 if (*fmt++ != ch) return NOT_FOUND;
mazgch 18:e5697801df29 916 }
mazgch 18:e5697801df29 917 }
mazgch 21:c4d64830bf02 918 return o;
mazgch 21:c4d64830bf02 919 }
mazgch 21:c4d64830bf02 920
mazgch 21:c4d64830bf02 921
mazgch 21:c4d64830bf02 922 int MDMParser::_getLine(Pipe<char>* pipe, char* buf, int len)
mazgch 21:c4d64830bf02 923 {
mazgch 21:c4d64830bf02 924 int unkn = 0;
mazgch 21:c4d64830bf02 925 int sz = pipe->size();
mazgch 21:c4d64830bf02 926 int fr = pipe->free();
mazgch 21:c4d64830bf02 927 if (len > sz)
mazgch 21:c4d64830bf02 928 len = sz;
mazgch 21:c4d64830bf02 929 while (len > 0)
mazgch 21:c4d64830bf02 930 {
mazgch 21:c4d64830bf02 931 static struct {
mazgch 21:c4d64830bf02 932 const char* fmt; int type;
mazgch 21:c4d64830bf02 933 } lutF[] = {
mazgch 21:c4d64830bf02 934 { "\r\n+USORD: %d,%d,\"%c\"", TYPE_PLUS },
mazgch 21:c4d64830bf02 935 { "\r\n+USORF: %d,\""IPSTR"\",%d,%d,\"%c\"", TYPE_PLUS },
mazgch 21:c4d64830bf02 936 };
mazgch 21:c4d64830bf02 937 static struct {
mazgch 21:c4d64830bf02 938 const char* sta; const char* end; int type;
mazgch 21:c4d64830bf02 939 } lut[] = {
mazgch 21:c4d64830bf02 940 { "\r\nOK\r\n", NULL, TYPE_OK },
mazgch 21:c4d64830bf02 941 { "\r\nERROR\r\n", NULL, TYPE_ERROR },
mazgch 31:a0bed6c1e05d 942 { "\r\n+CME ERROR:", "\r\n", TYPE_ERROR },
mazgch 21:c4d64830bf02 943 { "\r\n+CMS ERROR:", "\r\n", TYPE_ERROR },
mazgch 21:c4d64830bf02 944 { "\r\nRING\r\n", NULL, TYPE_RING },
mazgch 21:c4d64830bf02 945 { "\r\nCONNECT\r\n", NULL, TYPE_CONNECT },
mazgch 21:c4d64830bf02 946 { "\r\nNO CARRIER\r\n", NULL, TYPE_NOCARRIER },
mazgch 21:c4d64830bf02 947 { "\r\nNO DIALTONE\r\n", NULL, TYPE_NODIALTONE },
mazgch 21:c4d64830bf02 948 { "\r\nBUSY\r\n", NULL, TYPE_BUSY },
mazgch 21:c4d64830bf02 949 { "\r\nNO ANSWER\r\n", NULL, TYPE_NOANSWER },
mazgch 21:c4d64830bf02 950 { "\r\n+", "\r\n", TYPE_PLUS },
mazgch 21:c4d64830bf02 951 { "\r\n@", NULL, TYPE_PROMPT }, // Sockets
mazgch 21:c4d64830bf02 952 { "\r\n>", NULL, TYPE_PROMPT }, // SMS
mazgch 21:c4d64830bf02 953 };
mazgch 21:c4d64830bf02 954 for (int i = 0; i < sizeof(lutF)/sizeof(*lutF); i ++) {
mazgch 21:c4d64830bf02 955 pipe->set(unkn);
mazgch 21:c4d64830bf02 956 int ln = _parseFormated(pipe, len, lutF[i].fmt);
mazgch 21:c4d64830bf02 957 if (ln == WAIT && fr)
mazgch 21:c4d64830bf02 958 return WAIT;
mazgch 21:c4d64830bf02 959 if ((ln != NOT_FOUND) && (unkn > 0))
mazgch 31:a0bed6c1e05d 960 return TYPE_UNKNOWN | pipe->get(buf, unkn);
mazgch 21:c4d64830bf02 961 if (ln > 0)
mazgch 21:c4d64830bf02 962 return lutF[i].type | pipe->get(buf, ln);
mazgch 21:c4d64830bf02 963 }
mazgch 21:c4d64830bf02 964 for (int i = 0; i < sizeof(lut)/sizeof(*lut); i ++) {
mazgch 21:c4d64830bf02 965 pipe->set(unkn);
mazgch 21:c4d64830bf02 966 int ln = _parseMatch(pipe, len, lut[i].sta, lut[i].end);
mazgch 21:c4d64830bf02 967 if (ln == WAIT && fr)
mazgch 21:c4d64830bf02 968 return WAIT;
mazgch 21:c4d64830bf02 969 if ((ln != NOT_FOUND) && (unkn > 0))
mazgch 31:a0bed6c1e05d 970 return TYPE_UNKNOWN | pipe->get(buf, unkn);
mazgch 21:c4d64830bf02 971 if (ln > 0)
mazgch 21:c4d64830bf02 972 return lut[i].type | pipe->get(buf, ln);
mazgch 21:c4d64830bf02 973 }
mazgch 21:c4d64830bf02 974 // UNKNOWN
mazgch 21:c4d64830bf02 975 unkn ++;
mazgch 21:c4d64830bf02 976 len--;
mazgch 21:c4d64830bf02 977 }
mazgch 18:e5697801df29 978 return WAIT;
mazgch 18:e5697801df29 979 }
mazgch 18:e5697801df29 980
mazgch 18:e5697801df29 981 // ----------------------------------------------------------------
mazgch 18:e5697801df29 982 // Serial Implementation
mazgch 18:e5697801df29 983 // ----------------------------------------------------------------
mazgch 18:e5697801df29 984
mazgch 19:2b5d097ca15d 985 MDMSerial::MDMSerial(PinName tx /*= MDMTXD*/, PinName rx /*= MDMRXD*/,
mazgch 19:2b5d097ca15d 986 int baudrate /*= MDMBAUD*/,
mazgch 19:2b5d097ca15d 987 #if DEVICE_SERIAL_FC
mazgch 19:2b5d097ca15d 988 PinName rts /*= MDMRTS*/, PinName cts /*= MDMCTS*/,
mazgch 19:2b5d097ca15d 989 #endif
mazgch 18:e5697801df29 990 int rxSize /*= 256*/, int txSize /*= 128*/) :
mazgch 19:2b5d097ca15d 991 #if DEVICE_SERIAL_FC
mazgch 18:e5697801df29 992 SerialPipe(tx, rx, rts, cts, rxSize, txSize)
mazgch 19:2b5d097ca15d 993 #else
mazgch 18:e5697801df29 994 SerialPipe(tx, rx, rxSize, txSize)
mazgch 19:2b5d097ca15d 995 #endif
mazgch 18:e5697801df29 996 {
mazgch 18:e5697801df29 997 baud(baudrate);
mazgch 18:e5697801df29 998 }
mazgch 18:e5697801df29 999
mazgch 18:e5697801df29 1000 int MDMSerial::_send(const void* buf, int len)
mazgch 18:e5697801df29 1001 {
mazgch 18:e5697801df29 1002 return put((const char*)buf, len, true/*=blocking*/);
mazgch 18:e5697801df29 1003 }
mazgch 18:e5697801df29 1004
mazgch 18:e5697801df29 1005 int MDMSerial::getLine(char* buffer, int length)
mazgch 18:e5697801df29 1006 {
mazgch 18:e5697801df29 1007 return _getLine(&_pipeRx, buffer, length);
mazgch 18:e5697801df29 1008 }
mazgch 18:e5697801df29 1009
mazgch 18:e5697801df29 1010 // ----------------------------------------------------------------
mazgch 18:e5697801df29 1011 // USB Implementation
mazgch 18:e5697801df29 1012 // ----------------------------------------------------------------
mazgch 18:e5697801df29 1013
mazgch 18:e5697801df29 1014 #ifdef HAVE_MDMUSB
mazgch 18:e5697801df29 1015 // TODO properly implement with USB
mazgch 18:e5697801df29 1016 MDMUsb::MDMUsb(void) { }
mazgch 18:e5697801df29 1017 int MDMUsb::_send(const void* buf, int len) { return len; }
mazgch 18:e5697801df29 1018 int MDMUsb::getLine(char* buffer, int length) { return NOT_FOUND; }
mazgch 18:e5697801df29 1019 #endif