support library for C027 helper functions for Buffer Pipes, Buffered Serial Port (rtos capable) and GPS parsing. It includes modem APIs for USSD, SMS and Sockets.

Dependents:   HTTPClient_Cellular_HelloWorld Cellular_HelloMQTT MbedSmartRestMain Car_Bon_car_module ... more

This library is intended to be used with u-blox products such as the C027 or a shield with u-blox cellular and GPS modules like the cellular and positioning shield from Embedded Artist.

For 2G/GSM and 3G/UMTS you need to:

  • have a SIM card and know its PIN number
  • need to know you network operators APN setting These setting should be passed to the connect or init and join functions. You can also extend the APN database in MDMAPN.h.

For CDMA products you need to make sure that you have provisioned and activated the modem with either Sprint or Verizon.

Committer:
mazgch
Date:
Thu May 15 22:20:42 2014 +0000
Revision:
74:208e3e32d263
Parent:
73:2b32e0a21df2
Child:
75:ce6e12067d0c
initial version of restructured u-blox library

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