Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: GPS_6Axis_DataLogger_SD_UDP
Fork of C027_Support by
Revision 120:e86bb9bd34c9, committed 2015-03-24
- Comitter:
- rlinnmoran
- Date:
- Tue Mar 24 21:36:34 2015 +0000
- Parent:
- 114:e347ed0fab5e
- Commit message:
- test
Changed in this revision
--- a/MDM.cpp Thu Nov 06 09:06:37 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1679 +0,0 @@
-#include "mbed.h"
-#include "MDM.h"
-#ifdef TARGET_UBLOX_C027
- #include "C027_api.h"
-#endif
-#include "MDMAPN.h"
-
-#define PROFILE "0" //!< this is the psd profile used
-#define MAX_SIZE 128 //!< max expected messages
-// num sockets
-#define NUMSOCKETS (sizeof(_sockets)/sizeof(*_sockets))
-//! test if it is a socket is ok to use
-#define ISSOCKET(s) (((s) >= 0) && ((s) < NUMSOCKETS) && (_sockets[s].handle != SOCKET_ERROR))
-//! check for timeout
-#define TIMEOUT(t, ms) ((ms != TIMEOUT_BLOCKING) && (ms < t.read_ms()))
-//! registration ok check helper
-#define REG_OK(r) ((r == REG_HOME) || (r == REG_ROAMING))
-//! registration done check helper (no need to poll further)
-#define REG_DONE(r) ((r == REG_HOME) || (r == REG_ROAMING) || (r == REG_DENIED))
-//! helper to make sure that lock unlock pair is always balaced
-#define LOCK() { lock()
-//! helper to make sure that lock unlock pair is always balaced
-#define UNLOCK() } unlock()
-
-#ifdef MDM_DEBUG
- #if 1 // colored terminal output using ANSI escape sequences
- #define COL(c) "\033[" c
- #else
- #define COL(c)
- #endif
- #define DEF COL("39m")
- #define BLA COL("30m")
- #define RED COL("31m")
- #define GRE COL("32m")
- #define YEL COL("33m")
- #define BLU COL("34m")
- #define MAG COL("35m")
- #define CYA COL("36m")
- #define WHY COL("37m")
-
-void dumpAtCmd(const char* buf, int len)
-{
- ::printf(" %3d \"", len);
- while (len --) {
- char ch = *buf++;
- if ((ch > 0x1F) && (ch != 0x7F)) { // is printable
- if (ch == '%') ::printf("%%");
- else if (ch == '"') ::printf("\\\"");
- else if (ch == '\\') ::printf("\\\\");
- else putchar(ch);
- } else {
- if (ch == '\a') ::printf("\\a"); // BEL (0x07)
- else if (ch == '\b') ::printf("\\b"); // Backspace (0x08)
- else if (ch == '\t') ::printf("\\t"); // Horizontal Tab (0x09)
- else if (ch == '\n') ::printf("\\n"); // Linefeed (0x0A)
- else if (ch == '\v') ::printf("\\v"); // Vertical Tab (0x0B)
- else if (ch == '\f') ::printf("\\f"); // Formfeed (0x0C)
- else if (ch == '\r') ::printf("\\r"); // Carriage Return (0x0D)
- else ::printf("\\x%02x", (unsigned char)ch);
- }
- }
- ::printf("\"\r\n");
-}
-
- #define ERROR(...) (_debugLevel < 0) ? : ::printf(RED), ::printf(__VA_ARGS__), ::printf(DEF)
- #define TEST(...) ::printf(CYA), ::printf(__VA_ARGS__), ::printf(DEF)
- #define INFO(...) (_debugLevel < 1) ? : ::printf(GRE), ::printf(__VA_ARGS__), ::printf(DEF)
- #define TRACE(...) (_debugLevel < 2) ? : ::printf(__VA_ARGS__)
-
-#else
-
- #define ERROR(...) (void)0 // no tracing
- #define TEST(...) (void)0 // no tracing
- #define INFO(...) (void)0 // no tracing
- #define TRACE(...) (void)0 // no tracing
-
-#endif
-
-MDMParser* MDMParser::inst;
-
-MDMParser::MDMParser(void)
-{
- inst = this;
- memset(&_dev, 0, sizeof(_dev));
- memset(&_net, 0, sizeof(_net));
- _net.lac = 0xFFFF;
- _net.ci = 0xFFFFFFFF;
- _ip = NOIP;
- _init = false;
- memset(_sockets, 0, sizeof(_sockets));
- for (int socket = 0; socket < NUMSOCKETS; socket ++)
- _sockets[socket].handle = SOCKET_ERROR;
-#ifdef MDM_DEBUG
- _debugLevel = 1;
- _debugTime.start();
-#endif
-}
-
-int MDMParser::send(const char* buf, int len)
-{
-#ifdef MDM_DEBUG
- if (_debugLevel >= 3) {
- ::printf("%10.3f AT send ", _debugTime.read_ms()*0.001);
- dumpAtCmd(buf,len);
- }
-#endif
- return _send(buf, len);
-}
-
-int MDMParser::sendFormated(const char* format, ...) {
- char buf[MAX_SIZE];
- va_list args;
- va_start(args, format);
- int len = vsnprintf(buf,sizeof(buf), format, args);
- va_end(args);
- return send(buf, len);
-}
-
-int MDMParser::waitFinalResp(_CALLBACKPTR cb /* = NULL*/,
- void* param /* = NULL*/,
- int timeout_ms /*= 5000*/)
-{
- char buf[MAX_SIZE + 64 /* add some more space for framing */];
- Timer timer;
- timer.start();
- do {
- int ret = getLine(buf, sizeof(buf));
-#ifdef MDM_DEBUG
- if ((_debugLevel >= 3) && (ret != WAIT) && (ret != NOT_FOUND))
- {
- int len = LENGTH(ret);
- int type = TYPE(ret);
- const char* s = (type == TYPE_UNKNOWN)? YEL "UNK" DEF :
- (type == TYPE_TEXT) ? MAG "TXT" DEF :
- (type == TYPE_OK ) ? GRE "OK " DEF :
- (type == TYPE_ERROR) ? RED "ERR" DEF :
- (type == TYPE_PLUS) ? CYA " + " DEF :
- (type == TYPE_PROMPT) ? BLU " > " DEF :
- "..." ;
- ::printf("%10.3f AT read %s", _debugTime.read_ms()*0.001, s);
- dumpAtCmd(buf, len);
- }
-#endif
- if ((ret != WAIT) && (ret != NOT_FOUND))
- {
- int type = TYPE(ret);
- // handle unsolicited commands here
- if (type == TYPE_PLUS) {
- const char* cmd = buf+3;
- int a, b, c, d, r;
- char s[32];
-
- // SMS Command ---------------------------------
- // +CNMI: <mem>,<index>
- if (sscanf(cmd, "CMTI: \"%*[^\"]\",%d", &a) == 1) {
- TRACE("New SMS at index %d\r\n", a);
- // Socket Specific Command ---------------------------------
- // +UUSORD: <socket>,<length>
- } else if ((sscanf(cmd, "UUSORD: %d,%d", &a, &b) == 2)) {
- int socket = _findSocket(a);
- TRACE("Socket %d: handle %d has %d bytes pending\r\n", socket, a, b);
- if (socket != SOCKET_ERROR)
- _sockets[socket].pending = b;
- // +UUSORF: <socket>,<length>
- } else if ((sscanf(cmd, "UUSORF: %d,%d", &a, &b) == 2)) {
- int socket = _findSocket(a);
- TRACE("Socket %d: handle %d has %d bytes pending\r\n", socket, a, b);
- if (socket != SOCKET_ERROR)
- _sockets[socket].pending = b;
- // +UUSOCL: <socket>
- } else if ((sscanf(cmd, "UUSOCL: %d", &a) == 1)) {
- int socket = _findSocket(a);
- TRACE("Socket %d: handle %d closed by remote host\r\n", socket, a);
- if ((socket != SOCKET_ERROR) && _sockets[socket].connected)
- _sockets[socket].connected = false;
- }
- if (_dev.dev == DEV_LISA_C200) {
- // CDMA Specific -------------------------------------------
- // +CREG: <n><SID>,<NID>,<stat>
- if (sscanf(cmd, "CREG: %*d,%d,%d,%d",&a,&b,&c) == 3) {
- // _net.sid = a;
- // _net.nid = b;
- if (c == 0) _net.csd = REG_NONE; // not registered, home network
- else if (c == 1) _net.csd = REG_HOME; // registered, home network
- else if (c == 2) _net.csd = REG_NONE; // not registered, but MT is currently searching a new operator to register to
- else if (c == 3) _net.csd = REG_DENIED; // registration denied
- else if (c == 5) _net.csd = REG_ROAMING; // registered, roaming
- _net.psd = _net.csd; // fake PSD registration (CDMA is always registered)
- _net.act = ACT_CDMA;
- // +CSS: <mode>[,<format>,<oper>[,<AcT>]]
- } else if (sscanf(cmd, "CSS %*c,%2s,%*d",s) == 1) {
- //_net.reg = (strcmp("Z", s) == 0) ? REG_UNKNOWN : REG_HOME;
- }
- } else {
- // GSM/UMTS Specific -------------------------------------------
- // +UUPSDD: <profile_id>
- if (sscanf(cmd, "UUPSDD: %d",&a) == 1) {
- if (*PROFILE == a) _ip = NOIP;
- } else {
- // +CREG|CGREG: <n>,<stat>[,<lac>,<ci>[,AcT[,<rac>]]] // reply to AT+CREG|AT+CGREG
- // +CREG|CGREG: <stat>[,<lac>,<ci>[,AcT[,<rac>]]] // URC
- b = 0xFFFF; c = 0xFFFFFFFF; d = -1;
- r = sscanf(cmd, "%s %*d,%d,\"%X\",\"%X\",%d",s,&a,&b,&c,&d);
- if (r <= 1)
- r = sscanf(cmd, "%s %d,\"%X\",\"%X\",%d",s,&a,&b,&c,&d);
- if (r >= 2) {
- Reg *reg = !strcmp(s, "CREG:") ? &_net.csd :
- !strcmp(s, "CGREG:") ? &_net.psd : NULL;
- if (reg) {
- // network status
- if (a == 0) *reg = REG_NONE; // 0: not registered, home network
- else if (a == 1) *reg = REG_HOME; // 1: registered, home network
- else if (a == 2) *reg = REG_NONE; // 2: not registered, but MT is currently searching a new operator to register to
- else if (a == 3) *reg = REG_DENIED; // 3: registration denied
- else if (a == 4) *reg = REG_UNKNOWN; // 4: unknown
- else if (a == 5) *reg = REG_ROAMING; // 5: registered, roaming
- if ((r >= 3) && (b != 0xFFFF)) _net.lac = b; // location area code
- if ((r >= 4) && (c != 0xFFFFFFFF)) _net.ci = c; // cell ID
- // access technology
- if (r >= 5) {
- if (d == 0) _net.act = ACT_GSM; // 0: GSM
- else if (d == 1) _net.act = ACT_GSM; // 1: GSM COMPACT
- else if (d == 2) _net.act = ACT_UTRAN; // 2: UTRAN
- else if (d == 3) _net.act = ACT_EDGE; // 3: GSM with EDGE availability
- else if (d == 4) _net.act = ACT_UTRAN; // 4: UTRAN with HSDPA availability
- else if (d == 5) _net.act = ACT_UTRAN; // 5: UTRAN with HSUPA availability
- else if (d == 6) _net.act = ACT_UTRAN; // 6: UTRAN with HSDPA and HSUPA availability
- }
- }
- }
- }
- }
- }
- if (cb) {
- int len = LENGTH(ret);
- int ret = cb(type, buf, len, param);
- if (WAIT != ret)
- return ret;
- }
- if (type == TYPE_OK)
- return RESP_OK;
- if (type == TYPE_ERROR)
- return RESP_ERROR;
- if (type == TYPE_PROMPT)
- return RESP_PROMPT;
- }
- // relax a bit
- wait_ms(10);
- }
- while (!TIMEOUT(timer, timeout_ms));
- return WAIT;
-}
-
-int MDMParser::_cbString(int type, const char* buf, int len, char* str)
-{
- if (str && (type == TYPE_UNKNOWN)) {
- if (sscanf(buf, "\r\n%s\r\n", str) == 1)
- /*nothing*/;
- }
- return WAIT;
-}
-
-int MDMParser::_cbInt(int type, const char* buf, int len, int* val)
-{
- if (val && (type == TYPE_UNKNOWN)) {
- if (sscanf(buf, "\r\n%d\r\n", val) == 1)
- /*nothing*/;
- }
- return WAIT;
-}
-
-// ----------------------------------------------------------------
-
-bool MDMParser::connect(
- const char* simpin,
- const char* apn, const char* username,
- const char* password, Auth auth,
- PinName pn)
-{
- bool ok = init(simpin, NULL, pn);
-#ifdef MDM_DEBUG
- if (_debugLevel >= 1) dumpDevStatus(&_dev);
-#endif
- if (!ok)
- return false;
- ok = registerNet();
-#ifdef MDM_DEBUG
- if (_debugLevel >= 1) dumpNetStatus(&_net);
-#endif
- if (!ok)
- return false;
- IP ip = join(apn,username,password,auth);
-#ifdef MDM_DEBUG
- if (_debugLevel >= 1) dumpIp(ip);
-#endif
- if (ip == NOIP)
- return false;
- return true;
-}
-
-bool MDMParser::init(const char* simpin, DevStatus* status, PinName pn)
-{
- int i = 10;
- LOCK();
- memset(&_dev, 0, sizeof(_dev));
- if (pn != NC) {
- INFO("Modem::wakeup\r\n");
- DigitalOut pin(pn, 1);
- while (i--) {
- // SARA-U2/LISA-U2 50..80us
- pin = 0; ::wait_us(50);
- pin = 1; ::wait_ms(10);
-
- // SARA-G35 >5ms, LISA-C2 > 150ms, LEON-G2 >5ms
- pin = 0; ::wait_ms(150);
- pin = 1; ::wait_ms(100);
-
- // purge any messages
- purge();
-
- // check interface
- sendFormated("AT\r\n");
- int r = waitFinalResp(NULL,NULL,1000);
- if(RESP_OK == r) break;
- }
- if (i < 0) {
- ERROR("No Reply from Modem\r\n");
- goto failure;
- }
- }
- _init = true;
-
- INFO("Modem::init\r\n");
- // echo off
- sendFormated("AT E0\r\n");
- if(RESP_OK != waitFinalResp())
- goto failure;
- // enable verbose error messages
- sendFormated("AT+CMEE=2\r\n");
- if(RESP_OK != waitFinalResp())
- goto failure;
- // set baud rate
- sendFormated("AT+IPR=115200\r\n");
- if (RESP_OK != waitFinalResp())
- goto failure;
- // wait some time until baudrate is applied
- wait_ms(200); // SARA-G > 40ms
- // identify the module
- sendFormated("ATI\r\n");
- if (RESP_OK != waitFinalResp(_cbATI, &_dev.dev))
- goto failure;
- if (_dev.dev == DEV_UNKNOWN)
- goto failure;
- // device specific init
- if (_dev.dev == DEV_LISA_C200) {
- // get the manufacturer
- sendFormated("AT+GMI\r\n");
- if (RESP_OK != waitFinalResp(_cbString, _dev.manu))
- goto failure;
- // get the model identification
- sendFormated("AT+GMM\r\n");
- if (RESP_OK != waitFinalResp(_cbString, _dev.model))
- goto failure;
- // get the sw version
- sendFormated("AT+GMR\r\n");
- if (RESP_OK != waitFinalResp(_cbString, _dev.ver))
- goto failure;
- // get the pseudo ESN or MEID
- sendFormated("AT+GSN\r\n");
- if (RESP_OK != waitFinalResp(_cbString, _dev.meid))
- goto failure;
-#if 0
- // enable power saving
- if (_dev.lpm != LPM_DISABLED) {
- // enable power saving (requires flow control, cts at least)
- sendFormated("AT+UPSV=1,1280\r\n");
- if (RESP_OK != waitFinalResp())
- goto failure;
- _dev.lpm = LPM_ACTIVE;
- }
-#endif
- } else {
- if ((_dev.dev == DEV_LISA_U200) || (_dev.dev == DEV_LEON_G200)) {
- // enable the network identification feature
- sendFormated("AT+UGPIOC=20,2\r\n");
- if (RESP_OK != waitFinalResp())
- goto failure;
- } else if ((_dev.dev == DEV_SARA_U260) || (_dev.dev == DEV_SARA_U270) ||
- (_dev.dev == DEV_SARA_G350)) {
- // enable the network identification feature
- sendFormated("AT+UGPIOC=16,2\r\n");
- if (RESP_OK != waitFinalResp())
- goto failure;
- }
- // check the sim card
- for (int i = 0; (i < 5) && (_dev.sim != SIM_READY); i++) {
- sendFormated("AT+CPIN?\r\n");
- int ret = waitFinalResp(_cbCPIN, &_dev.sim);
- // having an error here is ok (sim may still be initializing)
- if ((RESP_OK != ret) && (RESP_ERROR != ret))
- goto failure;
- // Enter PIN if needed
- if (_dev.sim == SIM_PIN) {
- if (!simpin) {
- ERROR("SIM PIN not available\r\n");
- goto failure;
- }
- sendFormated("AT+CPIN=%s\r\n", simpin);
- if (RESP_OK != waitFinalResp(_cbCPIN, &_dev.sim))
- goto failure;
- } else if (_dev.sim != SIM_READY) {
- wait_ms(1000);
- }
- }
- if (_dev.sim != SIM_READY) {
- if (_dev.sim == SIM_MISSING)
- ERROR("SIM not inserted\r\n");
- goto failure;
- }
- // get the manufacturer
- sendFormated("AT+CGMI\r\n");
- if (RESP_OK != waitFinalResp(_cbString, _dev.manu))
- goto failure;
- // get the model identification
- sendFormated("AT+CGMM\r\n");
- if (RESP_OK != waitFinalResp(_cbString, _dev.model))
- goto failure;
- // get the
- sendFormated("AT+CGMR\r\n");
- if (RESP_OK != waitFinalResp(_cbString, _dev.ver))
- goto failure;
- // Returns the ICCID (Integrated Circuit Card ID) of the SIM-card.
- // ICCID is a serial number identifying the SIM.
- sendFormated("AT+CCID\r\n");
- if (RESP_OK != waitFinalResp(_cbCCID, _dev.ccid))
- goto failure;
- // Returns the product serial number, IMEI (International Mobile Equipment Identity)
- sendFormated("AT+CGSN\r\n");
- if (RESP_OK != waitFinalResp(_cbString, _dev.imei))
- goto failure;
- // enable power saving
- if (_dev.lpm != LPM_DISABLED) {
- // enable power saving (requires flow control, cts at least)
- sendFormated("AT+UPSV=1\r\n");
- if (RESP_OK != waitFinalResp())
- goto failure;
- _dev.lpm = LPM_ACTIVE;
- }
- // enable the psd registration unsolicited result code
- sendFormated("AT+CGREG=2\r\n");
- if (RESP_OK != waitFinalResp())
- goto failure;
- }
- // enable the network registration unsolicited result code
- sendFormated("AT+CREG=%d\r\n", (_dev.dev == DEV_LISA_C200) ? 1 : 2);
- if (RESP_OK != waitFinalResp())
- goto failure;
- // Setup SMS in text mode
- sendFormated("AT+CMGF=1\r\n");
- if (RESP_OK != waitFinalResp())
- goto failure;
- // setup new message indication
- sendFormated("AT+CNMI=2,1\r\n");
- if (RESP_OK != waitFinalResp())
- goto failure;
- // Request IMSI (International Mobile Subscriber Identification)
- sendFormated("AT+CIMI\r\n");
- if (RESP_OK != waitFinalResp(_cbString, _dev.imsi))
- goto failure;
- if (status)
- memcpy(status, &_dev, sizeof(DevStatus));
- UNLOCK();
- return true;
-failure:
- unlock();
- return false;
-}
-
-bool MDMParser::powerOff(void)
-{
- bool ok = false;
- if (_init) {
- LOCK();
- INFO("Modem::powerOff\r\n");
- sendFormated("AT+CPWROFF\r\n");
- if (RESP_OK == waitFinalResp(NULL,NULL,120*1000)) {
- _init = false;
- ok = true;
- }
- UNLOCK();
- }
- return ok;
-}
-
-int MDMParser::_cbATI(int type, const char* buf, int len, Dev* dev)
-{
- if ((type == TYPE_UNKNOWN) && dev) {
- if (strstr(buf, "SARA-G350")) *dev = DEV_SARA_G350;
- else if (strstr(buf, "LISA-U200")) *dev = DEV_LISA_U200;
- else if (strstr(buf, "LISA-C200")) *dev = DEV_LISA_C200;
- else if (strstr(buf, "SARA-U260")) *dev = DEV_SARA_U260;
- else if (strstr(buf, "SARA-U270")) *dev = DEV_SARA_U270;
- else if (strstr(buf, "LEON-G200")) *dev = DEV_LEON_G200;
- }
- return WAIT;
-}
-
-int MDMParser::_cbCPIN(int type, const char* buf, int len, Sim* sim)
-{
- if (sim) {
- if (type == TYPE_PLUS){
- char s[16];
- if (sscanf(buf, "\r\n+CPIN: %[^\r]\r\n", s) >= 1)
- *sim = (0 == strcmp("READY", s)) ? SIM_READY : SIM_PIN;
- } else if (type == TYPE_ERROR) {
- if (strstr(buf, "+CME ERROR: SIM not inserted"))
- *sim = SIM_MISSING;
- }
- }
- return WAIT;
-}
-
-int MDMParser::_cbCCID(int type, const char* buf, int len, char* ccid)
-{
- if ((type == TYPE_PLUS) && ccid){
- if (sscanf(buf, "\r\n+CCID: %[^\r]\r\n", ccid) == 1)
- /*TRACE("Got CCID: %s\r\n", ccid)*/;
- }
- return WAIT;
-}
-
-bool MDMParser::registerNet(NetStatus* status /*= NULL*/, int timeout_ms /*= 180000*/)
-{
- Timer timer;
- timer.start();
- INFO("Modem::register\r\n");
- while (!checkNetStatus(status) && !TIMEOUT(timer, timeout_ms))
- wait_ms(1000);
- if (_net.csd == REG_DENIED) ERROR("CSD Registration Denied\r\n");
- if (_net.psd == REG_DENIED) ERROR("PSD Registration Denied\r\n");
- return REG_OK(_net.csd) || REG_OK(_net.psd);
-}
-
-bool MDMParser::checkNetStatus(NetStatus* status /*= NULL*/)
-{
- bool ok = false;
- LOCK();
- memset(&_net, 0, sizeof(_net));
- _net.lac = 0xFFFF;
- _net.ci = 0xFFFFFFFF;
- // check registration
- sendFormated("AT+CREG?\r\n");
- waitFinalResp(); // don't fail as service could be not subscribed
- if (_dev.dev != DEV_LISA_C200) {
- // check PSD registration
- sendFormated("AT+CGREG?\r\n");
- waitFinalResp(); // don't fail as service could be not subscribed
- }
- if (REG_OK(_net.csd) || REG_OK(_net.psd))
- {
- // check modem specific status messages
- if (_dev.dev == DEV_LISA_C200) {
- sendFormated("AT+CSS?\r\n");
- if (RESP_OK != waitFinalResp())
- goto failure;
- while (1) {
- // get the Telephone number
- sendFormated("AT$MDN?\r\n");
- if (RESP_OK != waitFinalResp(_cbString, _net.num))
- goto failure;
- // check if we have a Mobile Directory Number
- if (*_net.num && (memcmp(_net.num, "000000", 6) != 0))
- break;
-
- INFO("Device not yet activated\r\n");
- INFO("Make sure you have a valid contract with the network operator for this device.\r\n");
- // Check if the the version contains a V for Verizon
- // Verizon: E0.V.xx.00.xxR,
- // Sprint E0.S.xx.00.xxR
- if (_dev.ver[3] == 'V') {
- int i;
- INFO("Start device over-the-air activation (this can take a few minutes)\r\n");
- sendFormated("AT+CDV=*22899\r\n");
- i = 1;
- if ((RESP_OK != waitFinalResp(_cbUACTIND, &i, 120*1000)) || (i == 1)) {
- ERROR("Device over-the-air activation failed\r\n");
- goto failure;
- }
- INFO("Device over-the-air activation successful\r\n");
-
- INFO("Start PRL over-the-air update (this can take a few minutes)\r\n");
- sendFormated("AT+CDV=*22891\r\n");
- i = 1;
- if ((RESP_OK != waitFinalResp(_cbUACTIND, &i, 120*1000)) || (i == 1)) {
- ERROR("PRL over-the-air update failed\r\n");
- goto failure;
- }
- INFO("PRL over-the-air update successful\r\n");
-
- } else {
- // Sprint or Aeris
- INFO("Wait for OMA-DM over-the-air activation (this can take a few minutes)\r\n");
- wait_ms(120*1000);
- }
- }
- // get the the Network access identifier string
- char nai[64];
- sendFormated("AT$QCMIPNAI?\r\n");
- if (RESP_OK != waitFinalResp(_cbString, nai))
- goto failure;
- } else {
- sendFormated("AT+COPS?\r\n");
- if (RESP_OK != waitFinalResp(_cbCOPS, &_net))
- goto failure;
- // get the MSISDNs related to this subscriber
- sendFormated("AT+CNUM\r\n");
- if (RESP_OK != waitFinalResp(_cbCNUM, _net.num))
- goto failure;
- }
- // get the signal strength indication
- sendFormated("AT+CSQ\r\n");
- if (RESP_OK != waitFinalResp(_cbCSQ, &_net))
- goto failure;
- }
- if (status) {
- memcpy(status, &_net, sizeof(NetStatus));
- }
- ok = REG_DONE(_net.csd) && REG_DONE(_net.psd);
- UNLOCK();
- return ok;
-failure:
- unlock();
- return false;
-}
-
-int MDMParser::_cbCOPS(int type, const char* buf, int len, NetStatus* status)
-{
- if ((type == TYPE_PLUS) && status){
- int act = 99;
- // +COPS: <mode>[,<format>,<oper>[,<AcT>]]
- if (sscanf(buf, "\r\n+COPS: %*d,%*d,\"%[^\"]\",%d",status->opr,&act) >= 1) {
- if (act == 0) status->act = ACT_GSM; // 0: GSM,
- else if (act == 2) status->act = ACT_UTRAN; // 2: UTRAN
- }
- }
- return WAIT;
-}
-
-int MDMParser::_cbCNUM(int type, const char* buf, int len, char* num)
-{
- if ((type == TYPE_PLUS) && num){
- int a;
- if ((sscanf(buf, "\r\n+CNUM: \"My Number\",\"%31[^\"]\",%d", num, &a) == 2) &&
- ((a == 129) || (a == 145))) {
- }
- }
- return WAIT;
-}
-
-int MDMParser::_cbCSQ(int type, const char* buf, int len, NetStatus* status)
-{
- if ((type == TYPE_PLUS) && status){
- int a,b;
- char _ber[] = { 49, 43, 37, 25, 19, 13, 7, 0 }; // see 3GPP TS 45.008 [20] subclause 8.2.4
- // +CSQ: <rssi>,<qual>
- if (sscanf(buf, "\r\n+CSQ: %d,%d",&a,&b) == 2) {
- if (a != 99) status->rssi = -113 + 2*a; // 0: -113 1: -111 ... 30: -53 dBm with 2 dBm steps
- if ((b != 99) && (b < sizeof(_ber))) status->ber = _ber[b]; //
- }
- }
- return WAIT;
-}
-
-int MDMParser::_cbUACTIND(int type, const char* buf, int len, int* i)
-{
- if ((type == TYPE_PLUS) && i){
- int a;
- if (sscanf(buf, "\r\n+UACTIND: %d", &a) == 1) {
- *i = a;
- }
- }
- return WAIT;
-}
-
-// ----------------------------------------------------------------
-// internet connection
-
-MDMParser::IP MDMParser::join(const char* apn /*= NULL*/, const char* username /*= NULL*/,
- const char* password /*= NULL*/, Auth auth /*= AUTH_DETECT*/)
-{
- LOCK();
- INFO("Modem::join\r\n");
- _ip = NOIP;
- if (_dev.dev == DEV_LISA_C200) {
- // make a dumy dns lookup (which will fail, so ignore the result)
- sendFormated("AT+UDNSRN=0,\"u-blox.com\"\r\n");
- waitFinalResp();
- // This fake lookup will enable the IP connection and we
- // should have an IP after this, so we check it
-
- //Get local IP address
- sendFormated("AT+CMIP?\r\n");
- if (RESP_OK != waitFinalResp(_cbCMIP, &_ip))
- goto failure;
- } else {
- // check gprs attach status
- sendFormated("AT+CGATT=1\r\n");
- if (RESP_OK != waitFinalResp(NULL,NULL,3*60*1000))
- goto failure;
-
- // Check the profile
- int a = 0;
- bool force = true;
- sendFormated("AT+UPSND=" PROFILE ",8\r\n");
- if (RESP_OK != waitFinalResp(_cbUPSND, &a))
- goto failure;
- if (a == 1 && force) {
- // disconnect the profile already if it is connected
- sendFormated("AT+UPSDA=" PROFILE ",4\r\n");
- if (RESP_OK != waitFinalResp(NULL,NULL,40*1000))
- goto failure;
- a = 0;
- }
- if (a == 0) {
- bool ok = false;
- // try to lookup the apn settings from our local database by mccmnc
- const char* config = NULL;
- if (!apn && !username && !password)
- config = apnconfig(_dev.imsi);
-
- // Set up the dynamic IP address assignment.
- sendFormated("AT+UPSD=" PROFILE ",7,\"0.0.0.0\"\r\n");
- if (RESP_OK != waitFinalResp())
- goto failure;
-
- do {
- if (config) {
- apn = _APN_GET(config);
- username = _APN_GET(config);
- password = _APN_GET(config);
- TRACE("Testing APN Settings(\"%s\",\"%s\",\"%s\")\r\n", apn, username, password);
- }
- // Set up the APN
- if (apn && *apn) {
- sendFormated("AT+UPSD=" PROFILE ",1,\"%s\"\r\n", apn);
- if (RESP_OK != waitFinalResp())
- goto failure;
- }
- if (username && *username) {
- sendFormated("AT+UPSD=" PROFILE ",2,\"%s\"\r\n", username);
- if (RESP_OK != waitFinalResp())
- goto failure;
- }
- if (password && *password) {
- sendFormated("AT+UPSD=" PROFILE ",3,\"%s\"\r\n", password);
- if (RESP_OK != waitFinalResp())
- goto failure;
- }
- // try different Authentication Protocols
- // 0 = none
- // 1 = PAP (Password Authentication Protocol)
- // 2 = CHAP (Challenge Handshake Authentication Protocol)
- for (int i = AUTH_NONE; i <= AUTH_CHAP && !ok; i ++) {
- if ((auth == AUTH_DETECT) || (auth == i)) {
- // Set up the Authentication Protocol
- sendFormated("AT+UPSD=" PROFILE ",6,%d\r\n", i);
- if (RESP_OK != waitFinalResp())
- goto failure;
- // Activate the profile and make connection
- sendFormated("AT+UPSDA=" PROFILE ",3\r\n");
- if (RESP_OK == waitFinalResp(NULL,NULL,150*1000))
- ok = true;
- }
- }
- } while (!ok && config && *config); // maybe use next setting ?
- if (!ok) {
- ERROR("Your modem APN/password/username may be wrong\r\n");
- goto failure;
- }
- }
- //Get local IP address
- sendFormated("AT+UPSND=" PROFILE ",0\r\n");
- if (RESP_OK != waitFinalResp(_cbUPSND, &_ip))
- goto failure;
- }
- UNLOCK();
- return _ip;
-failure:
- unlock();
- return NOIP;
-}
-
-int MDMParser::_cbUDOPN(int type, const char* buf, int len, char* mccmnc)
-{
- if ((type == TYPE_PLUS) && mccmnc) {
- if (sscanf(buf, "\r\n+UDOPN: 0,\"%[^\"]\"", mccmnc) == 1)
- ;
- }
- return WAIT;
-}
-
-int MDMParser::_cbCMIP(int type, const char* buf, int len, IP* ip)
-{
- if ((type == TYPE_UNKNOWN) && ip) {
- int a,b,c,d;
- if (sscanf(buf, "\r\n" IPSTR, &a,&b,&c,&d) == 4)
- *ip = IPADR(a,b,c,d);
- }
- return WAIT;
-}
-
-int MDMParser::_cbUPSND(int type, const char* buf, int len, int* act)
-{
- if ((type == TYPE_PLUS) && act) {
- if (sscanf(buf, "\r\n+UPSND: %*d,%*d,%d", act) == 1)
- /*nothing*/;
- }
- return WAIT;
-}
-
-int MDMParser::_cbUPSND(int type, const char* buf, int len, IP* ip)
-{
- if ((type == TYPE_PLUS) && ip) {
- int a,b,c,d;
- // +UPSND=<profile_id>,<param_tag>[,<dynamic_param_val>]
- if (sscanf(buf, "\r\n+UPSND: " PROFILE ",0,\"" IPSTR "\"", &a,&b,&c,&d) == 4)
- *ip = IPADR(a,b,c,d);
- }
- return WAIT;
-}
-
-int MDMParser::_cbUDNSRN(int type, const char* buf, int len, IP* ip)
-{
- if ((type == TYPE_PLUS) && ip) {
- int a,b,c,d;
- if (sscanf(buf, "\r\n+UDNSRN: \"" IPSTR "\"", &a,&b,&c,&d) == 4)
- *ip = IPADR(a,b,c,d);
- }
- return WAIT;
-}
-
-bool MDMParser::disconnect(void)
-{
- bool ok = false;
- LOCK();
- INFO("Modem::disconnect\r\n");
- if (_ip != NOIP) {
- if (_dev.dev == DEV_LISA_C200) {
- // There something to do here
- _ip = NOIP;
- ok = true;
- } else {
- sendFormated("AT+UPSDA=" PROFILE ",4\r\n");
- if (RESP_OK != waitFinalResp()) {
- _ip = NOIP;
- ok = true;
- }
- }
- }
- UNLOCK();
- return ok;
-}
-
-MDMParser::IP MDMParser::gethostbyname(const char* host)
-{
- IP ip = NOIP;
- int a,b,c,d;
- if (sscanf(host, IPSTR, &a,&b,&c,&d) == 4)
- ip = IPADR(a,b,c,d);
- else {
- LOCK();
- sendFormated("AT+UDNSRN=0,\"%s\"\r\n", host);
- if (RESP_OK != waitFinalResp(_cbUDNSRN, &ip))
- ip = NOIP;
- UNLOCK();
- }
- return ip;
-}
-
-// ----------------------------------------------------------------
-// sockets
-
-int MDMParser::_cbUSOCR(int type, const char* buf, int len, int* handle)
-{
- if ((type == TYPE_PLUS) && handle) {
- // +USOCR: socket
- if (sscanf(buf, "\r\n+USOCR: %d", handle) == 1)
- /*nothing*/;
- }
- return WAIT;
-}
-
-int MDMParser::socketSocket(IpProtocol ipproto, int port)
-{
- int socket;
- LOCK();
- // find an free socket
- socket = _findSocket();
- TRACE("socketSocket(%d)\r\n", ipproto);
- if (socket != SOCKET_ERROR) {
- if (ipproto == IPPROTO_UDP) {
- // sending port can only be set on 2G/3G modules
- if ((port != -1) && (_dev.dev != DEV_LISA_C200)) {
- sendFormated("AT+USOCR=17,%d\r\n", port);
- } else {
- sendFormated("AT+USOCR=17\r\n");
- }
- } else /*(ipproto == IPPROTO_TCP)*/ {
- sendFormated("AT+USOCR=6\r\n");
- }
- int handle = SOCKET_ERROR;
- if ((RESP_OK == waitFinalResp(_cbUSOCR, &handle)) &&
- (handle != SOCKET_ERROR)) {
- TRACE("Socket %d: handle %d was created\r\n", socket, handle);
- _sockets[socket].handle = handle;
- _sockets[socket].timeout_ms = TIMEOUT_BLOCKING;
- _sockets[socket].connected = false;
- _sockets[socket].pending = 0;
- }
- else
- socket = SOCKET_ERROR;
- }
- UNLOCK();
- return socket;
-}
-
-bool MDMParser::socketConnect(int socket, const char * host, int port)
-{
- IP ip = gethostbyname(host);
- if (ip == NOIP)
- return false;
- // connect to socket
- bool ok = false;
- LOCK();
- if (ISSOCKET(socket) && (!_sockets[socket].connected)) {
- TRACE("socketConnect(%d,%s,%d)\r\n", socket,host,port);
- sendFormated("AT+USOCO=%d,\"" IPSTR "\",%d\r\n", _sockets[socket].handle, IPNUM(ip), port);
- if (RESP_OK == waitFinalResp())
- ok = _sockets[socket].connected = true;
- }
- UNLOCK();
- return ok;
-}
-
-bool MDMParser::socketIsConnected(int socket)
-{
- bool ok = false;
- LOCK();
- ok = ISSOCKET(socket) && _sockets[socket].connected;
- TRACE("socketIsConnected(%d) %s\r\n", socket, ok?"yes":"no");
- UNLOCK();
- return ok;
-}
-
-bool MDMParser::socketSetBlocking(int socket, int timeout_ms)
-{
- bool ok = false;
- LOCK();
- TRACE("socketSetBlocking(%d,%d)\r\n", socket,timeout_ms);
- if (ISSOCKET(socket)) {
- _sockets[socket].timeout_ms = timeout_ms;
- ok = true;
- }
- UNLOCK();
- return ok;
-}
-
-bool MDMParser::socketClose(int socket)
-{
- bool ok = false;
- LOCK();
- if (ISSOCKET(socket) && _sockets[socket].connected) {
- TRACE("socketClose(%d)\r\n", socket);
- sendFormated("AT+USOCL=%d\r\n", _sockets[socket].handle);
- if (RESP_OK == waitFinalResp()) {
- _sockets[socket].connected = false;
- ok = true;
- }
- }
- UNLOCK();
- return ok;
-}
-
-bool MDMParser::socketFree(int socket)
-{
- // make sure it is closed
- socketClose(socket);
- bool ok = true;
- LOCK();
- if (ISSOCKET(socket)) {
- TRACE("socketFree(%d)\r\n", socket);
- _sockets[socket].handle = SOCKET_ERROR;
- _sockets[socket].timeout_ms = TIMEOUT_BLOCKING;
- _sockets[socket].connected = false;
- _sockets[socket].pending = 0;
- ok = true;
- }
- UNLOCK();
- return ok;
-}
-
-#define USO_MAX_WRITE 1024 //!< maximum number of bytes to write to socket
-
-int MDMParser::socketSend(int socket, const char * buf, int len)
-{
- TRACE("socketSend(%d,,%d)\r\n", socket,len);
- int cnt = len;
- while (cnt > 0) {
- int blk = USO_MAX_WRITE;
- if (cnt < blk)
- blk = cnt;
- bool ok = false;
- LOCK();
- if (ISSOCKET(socket)) {
- sendFormated("AT+USOWR=%d,%d\r\n",_sockets[socket].handle,blk);
- if (RESP_PROMPT == waitFinalResp()) {
- wait_ms(50);
- send(buf, blk);
- if (RESP_OK == waitFinalResp())
- ok = true;
- }
- }
- UNLOCK();
- if (!ok)
- return SOCKET_ERROR;
- buf += blk;
- cnt -= blk;
- }
- return (len - cnt);
-}
-
-int MDMParser::socketSendTo(int socket, IP ip, int port, const char * buf, int len)
-{
- TRACE("socketSendTo(%d," IPSTR ",%d,,%d)\r\n", socket,IPNUM(ip),port,len);
- int cnt = len;
- while (cnt > 0) {
- int blk = USO_MAX_WRITE;
- if (cnt < blk)
- blk = cnt;
- bool ok = false;
- LOCK();
- if (ISSOCKET(socket)) {
- sendFormated("AT+USOST=%d,\"" IPSTR "\",%d,%d\r\n",_sockets[socket].handle,IPNUM(ip),port,blk);
- if (RESP_PROMPT == waitFinalResp()) {
- wait_ms(50);
- send(buf, blk);
- if (RESP_OK == waitFinalResp())
- ok = true;
- }
- }
- UNLOCK();
- if (!ok)
- return SOCKET_ERROR;
- buf += blk;
- cnt -= blk;
- }
- return (len - cnt);
-}
-
-int MDMParser::socketReadable(int socket)
-{
- int pending = SOCKET_ERROR;
- LOCK();
- if (ISSOCKET(socket) && _sockets[socket].connected) {
- TRACE("socketReadable(%d)\r\n", socket);
- // allow to receive unsolicited commands
- waitFinalResp(NULL, NULL, 0);
- if (_sockets[socket].connected)
- pending = _sockets[socket].pending;
- }
- UNLOCK();
- return pending;
-}
-
-int MDMParser::_cbUSORD(int type, const char* buf, int len, char* out)
-{
- if ((type == TYPE_PLUS) && out) {
- int sz, sk;
- if ((sscanf(buf, "\r\n+USORD: %d,%d,", &sk, &sz) == 2) &&
- (buf[len-sz-2] == '\"') && (buf[len-1] == '\"')) {
- memcpy(out, &buf[len-1-sz], sz);
- }
- }
- return WAIT;
-}
-
-int MDMParser::socketRecv(int socket, char* buf, int len)
-{
- int cnt = 0;
- TRACE("socketRecv(%d,,%d)\r\n", socket, len);
-#ifdef MDM_DEBUG
- memset(buf, '\0', len);
-#endif
- Timer timer;
- timer.start();
- while (len) {
- int blk = MAX_SIZE; // still need space for headers and unsolicited commands
- if (len < blk) blk = len;
- bool ok = false;
- LOCK();
- if (ISSOCKET(socket)) {
- if (_sockets[socket].connected) {
- if (_sockets[socket].pending < blk)
- blk = _sockets[socket].pending;
- if (blk > 0) {
- sendFormated("AT+USORD=%d,%d\r\n",_sockets[socket].handle, blk);
- if (RESP_OK == waitFinalResp(_cbUSORD, buf)) {
- _sockets[socket].pending -= blk;
- len -= blk;
- cnt += blk;
- buf += blk;
- ok = true;
- }
- } else if (!TIMEOUT(timer, _sockets[socket].timeout_ms)) {
- ok = (WAIT == waitFinalResp(NULL,NULL,0)); // wait for URCs
- } else {
- len = 0;
- ok = true;
- }
- } else {
- len = 0;
- ok = true;
- }
- }
- UNLOCK();
- if (!ok) {
- TRACE("socketRecv: ERROR\r\n");
- return SOCKET_ERROR;
- }
- }
- TRACE("socketRecv: %d \"%*s\"\r\n", cnt, cnt, buf-cnt);
- return cnt;
-}
-
-int MDMParser::_cbUSORF(int type, const char* buf, int len, USORFparam* param)
-{
- if ((type == TYPE_PLUS) && param) {
- int sz, sk, p, a,b,c,d;
- int r = sscanf(buf, "\r\n+USORF: %d,\"" IPSTR "\",%d,%d,",
- &sk,&a,&b,&c,&d,&p,&sz);
- if ((r == 7) && (buf[len-sz-2] == '\"') && (buf[len-1] == '\"')) {
- memcpy(param->buf, &buf[len-1-sz], sz);
- param->ip = IPADR(a,b,c,d);
- param->port = p;
- }
- }
- return WAIT;
-}
-
-int MDMParser::socketRecvFrom(int socket, IP* ip, int* port, char* buf, int len)
-{
- int cnt = 0;
- TRACE("socketRecvFrom(%d,,%d)\r\n", socket, len);
-#ifdef MDM_DEBUG
- memset(buf, '\0', len);
-#endif
- Timer timer;
- timer.start();
- while (len) {
- int blk = MAX_SIZE; // still need space for headers and unsolicited commands
- if (len < blk) blk = len;
- bool ok = false;
- LOCK();
- if (ISSOCKET(socket)) {
- if (_sockets[socket].pending < blk)
- blk = _sockets[socket].pending;
- if (blk > 0) {
- sendFormated("AT+USORF=%d,%d\r\n",_sockets[socket].handle, blk);
- USORFparam param;
- param.buf = buf;
- if (RESP_OK == waitFinalResp(_cbUSORF, ¶m)) {
- _sockets[socket].pending -= blk;
- *ip = param.ip;
- *port = param.port;
- len -= blk;
- cnt += blk;
- buf += blk;
- len = 0; // done
- ok = true;
- }
- } else if (!TIMEOUT(timer, _sockets[socket].timeout_ms)) {
- ok = (WAIT == waitFinalResp(NULL,NULL,0)); // wait for URCs
- } else {
- len = 0; // no more data and socket closed or timed-out
- ok = true;
- }
- }
- UNLOCK();
- if (!ok) {
- TRACE("socketRecv: ERROR\r\n");
- return SOCKET_ERROR;
- }
- }
- timer.stop();
- timer.reset();
- TRACE("socketRecv: %d \"%*s\"\r\n", cnt, cnt, buf-cnt);
- return cnt;
-}
-
-int MDMParser::_findSocket(int handle) {
- for (int socket = 0; socket < NUMSOCKETS; socket ++) {
- if (_sockets[socket].handle == handle)
- return socket;
- }
- return SOCKET_ERROR;
-}
-
-// ----------------------------------------------------------------
-
-int MDMParser::_cbCMGL(int type, const char* buf, int len, CMGLparam* param)
-{
- if ((type == TYPE_PLUS) && param && param->num) {
- // +CMGL: <ix>,...
- int ix;
- if (sscanf(buf, "\r\n+CMGL: %d,", &ix) == 1)
- {
- *param->ix++ = ix;
- param->num--;
- }
- }
- return WAIT;
-}
-
-int MDMParser::smsList(const char* stat /*= "ALL"*/, int* ix /*=NULL*/, int num /*= 0*/) {
- int ret = -1;
- LOCK();
- sendFormated("AT+CMGL=\"%s\"\r\n", stat);
- CMGLparam param;
- param.ix = ix;
- param.num = num;
- if (RESP_OK == waitFinalResp(_cbCMGL, ¶m))
- ret = num - param.num;
- UNLOCK();
- return ret;
-}
-
-bool MDMParser::smsSend(const char* num, const char* buf)
-{
- bool ok = false;
- LOCK();
- sendFormated("AT+CMGS=\"%s\"\r\n",num);
- if (RESP_PROMPT == waitFinalResp(NULL,NULL,150*1000)) {
- send(buf, strlen(buf));
- const char ctrlZ = 0x1A;
- send(&ctrlZ, sizeof(ctrlZ));
- ok = (RESP_OK == waitFinalResp());
- }
- UNLOCK();
- return ok;
-}
-
-bool MDMParser::smsDelete(int ix)
-{
- bool ok = false;
- LOCK();
- sendFormated("AT+CMGD=%d\r\n",ix);
- ok = (RESP_OK == waitFinalResp());
- UNLOCK();
- return ok;
-}
-
-int MDMParser::_cbCMGR(int type, const char* buf, int len, CMGRparam* param)
-{
- if (param) {
- if (type == TYPE_PLUS) {
- if (sscanf(buf, "\r\n+CMGR: \"%*[^\"]\",\"%[^\"]", param->num) == 1) {
- }
- } else if ((type == TYPE_UNKNOWN) && (buf[len-2] == '\r') && (buf[len-1] == '\n')) {
- memcpy(param->buf, buf, len-2);
- param->buf[len-2] = '\0';
- }
- }
- return WAIT;
-}
-
-bool MDMParser::smsRead(int ix, char* num, char* buf, int len)
-{
- bool ok = false;
- LOCK();
- CMGRparam param;
- param.num = num;
- param.buf = buf;
- sendFormated("AT+CMGR=%d\r\n",ix);
- ok = (RESP_OK == waitFinalResp(_cbCMGR, ¶m));
- UNLOCK();
- return ok;
-}
-
-// ----------------------------------------------------------------
-
-int MDMParser::_cbCUSD(int type, const char* buf, int len, char* resp)
-{
- if ((type == TYPE_PLUS) && resp) {
- // +USD: \"%*[^\"]\",\"%[^\"]\",,\"%*[^\"]\",%d,%d,%d,%d,\"*[^\"]\",%d,%d"..);
- if (sscanf(buf, "\r\n+CUSD: %*d,\"%[^\"]\",%*d", resp) == 1) {
- /*nothing*/
- }
- }
- return WAIT;
-}
-
-bool MDMParser::ussdCommand(const char* cmd, char* buf)
-{
- bool ok = false;
- LOCK();
- *buf = '\0';
- if (_dev.dev != DEV_LISA_C200) {
- sendFormated("AT+CUSD=1,\"%s\"\r\n",cmd);
- ok = (RESP_OK == waitFinalResp(_cbCUSD, buf));
- }
- UNLOCK();
- return ok;
-}
-
-// ----------------------------------------------------------------
-
-bool MDMParser::delFile(const char* filename)
-{
- bool ok = false;
- LOCK();
- sendFormated("AT+UDELFILE=\"%s\"\r\n", filename);
- ok = (RESP_OK == waitFinalResp());
- UNLOCK();
- return ok;
-}
-
-int MDMParser::writeFile(const char* filename, const char* buf, int len)
-{
- bool ok = false;
- LOCK();
- sendFormated("AT+UDWNFILE=\"%s\",%d\r\n", filename, len);
- if (RESP_PROMPT == waitFinalResp()) {
- send(buf, len);
- ok = (RESP_OK == waitFinalResp());
- }
- UNLOCK();
- return ok ? len : -1;
-}
-
-int MDMParser::readFile(const char* filename, char* buf, int len)
-{
- URDFILEparam param;
- param.filename = filename;
- param.buf = buf;
- param.sz = len;
- param.len = 0;
- LOCK();
- sendFormated("AT+URDFILE=\"%s\"\r\n", filename, len);
- if (RESP_OK != waitFinalResp(_cbURDFILE, ¶m))
- param.len = -1;
- UNLOCK();
- return param.len;
-}
-
-int MDMParser::_cbURDFILE(int type, const char* buf, int len, URDFILEparam* param)
-{
- if ((type == TYPE_PLUS) && param && param->filename && param->buf) {
- char filename[48];
- int sz;
- if ((sscanf(buf, "\r\n+URDFILE: \"%[^\"]\",%d,", filename, &sz) == 2) &&
- (0 == strcmp(param->filename, filename)) &&
- (buf[len-sz-2] == '\"') && (buf[len-1] == '\"')) {
- param->len = (sz < param->sz) ? sz : param->sz;
- memcpy(param->buf, &buf[len-1-sz], param->len);
- }
- }
- return WAIT;
-}
-
-// ----------------------------------------------------------------
-bool MDMParser::setDebug(int level)
-{
-#ifdef MDM_DEBUG
- if ((_debugLevel >= 0) && (level >= 0)) {
- _debugLevel = level;
- return true;
- }
-#endif
- return false;
-}
-
-void MDMParser::dumpDevStatus(MDMParser::DevStatus* status,
- _DPRINT dprint, void* param)
-{
- dprint(param, "Modem::devStatus\r\n");
- const char* txtDev[] = { "Unknown", "SARA-G350", "LISA-U200", "LISA-C200", "SARA-U260", "SARA-U270", "LEON-G200" };
- if (status->dev < sizeof(txtDev)/sizeof(*txtDev) && (status->dev != DEV_UNKNOWN))
- dprint(param, " Device: %s\r\n", txtDev[status->dev]);
- const char* txtLpm[] = { "Disabled", "Enabled", "Active" };
- if (status->lpm < sizeof(txtLpm)/sizeof(*txtLpm))
- dprint(param, " Power Save: %s\r\n", txtLpm[status->lpm]);
- const char* txtSim[] = { "Unknown", "Missing", "Pin", "Ready" };
- if (status->sim < sizeof(txtSim)/sizeof(*txtSim) && (status->sim != SIM_UNKNOWN))
- dprint(param, " SIM: %s\r\n", txtSim[status->sim]);
- if (*status->ccid)
- dprint(param, " CCID: %s\r\n", status->ccid);
- if (*status->imei)
- dprint(param, " IMEI: %s\r\n", status->imei);
- if (*status->imsi)
- dprint(param, " IMSI: %s\r\n", status->imsi);
- if (*status->meid)
- dprint(param, " MEID: %s\r\n", status->meid); // LISA-C
- if (*status->manu)
- dprint(param, " Manufacturer: %s\r\n", status->manu);
- if (*status->model)
- dprint(param, " Model: %s\r\n", status->model);
- if (*status->ver)
- dprint(param, " Version: %s\r\n", status->ver);
-}
-
-void MDMParser::dumpNetStatus(MDMParser::NetStatus *status,
- _DPRINT dprint, void* param)
-{
- dprint(param, "Modem::netStatus\r\n");
- const char* txtReg[] = { "Unknown", "Denied", "None", "Home", "Roaming" };
- if (status->csd < sizeof(txtReg)/sizeof(*txtReg) && (status->csd != REG_UNKNOWN))
- dprint(param, " CSD Registration: %s\r\n", txtReg[status->csd]);
- if (status->psd < sizeof(txtReg)/sizeof(*txtReg) && (status->psd != REG_UNKNOWN))
- dprint(param, " PSD Registration: %s\r\n", txtReg[status->psd]);
- const char* txtAct[] = { "Unknown", "GSM", "Edge", "3G", "CDMA" };
- if (status->act < sizeof(txtAct)/sizeof(*txtAct) && (status->act != ACT_UNKNOWN))
- dprint(param, " Access Technology: %s\r\n", txtAct[status->act]);
- if (status->rssi)
- dprint(param, " Signal Strength: %d dBm\r\n", status->rssi);
- if (status->ber)
- dprint(param, " Bit Error Rate: %d\r\n", status->ber);
- if (*status->opr)
- dprint(param, " Operator: %s\r\n", status->opr);
- if (status->lac != 0xFFFF)
- dprint(param, " Location Area Code: %04X\r\n", status->lac);
- if (status->ci != 0xFFFFFFFF)
- dprint(param, " Cell ID: %08X\r\n", status->ci);
- if (*status->num)
- dprint(param, " Phone Number: %s\r\n", status->num);
-}
-
-void MDMParser::dumpIp(MDMParser::IP ip,
- _DPRINT dprint, void* param)
-{
- if (ip != NOIP)
- dprint(param, "Modem:IP " IPSTR "\r\n", IPNUM(ip));
-}
-
-// ----------------------------------------------------------------
-int MDMParser::_parseMatch(Pipe<char>* pipe, int len, const char* sta, const char* end)
-{
- int o = 0;
- if (sta) {
- while (*sta) {
- if (++o > len) return WAIT;
- char ch = pipe->next();
- if (*sta++ != ch) return NOT_FOUND;
- }
- }
- if (!end) return o; // no termination
- // at least any char
- if (++o > len) return WAIT;
- pipe->next();
- // check the end
- int x = 0;
- while (end[x]) {
- if (++o > len) return WAIT;
- char ch = pipe->next();
- x = (end[x] == ch) ? x + 1 :
- (end[0] == ch) ? 1 :
- 0;
- }
- return o;
-}
-
-int MDMParser::_parseFormated(Pipe<char>* pipe, int len, const char* fmt)
-{
- int o = 0;
- int num = 0;
- if (fmt) {
- while (*fmt) {
- if (++o > len) return WAIT;
- char ch = pipe->next();
- if (*fmt == '%') {
- fmt++;
- if (*fmt == 'd') { // numeric
- fmt ++;
- num = 0;
- while (ch >= '0' && ch <= '9') {
- num = num * 10 + (ch - '0');
- if (++o > len) return WAIT;
- ch = pipe->next();
- }
- }
- else if (*fmt == 'c') { // char buffer (takes last numeric as length)
- fmt ++;
- while (num --) {
- if (++o > len) return WAIT;
- ch = pipe->next();
- }
- }
- else if (*fmt == 's') {
- fmt ++;
- if (ch != '\"') return NOT_FOUND;
- do {
- if (++o > len) return WAIT;
- ch = pipe->next();
- } while (ch != '\"');
- if (++o > len) return WAIT;
- ch = pipe->next();
- }
- }
- if (*fmt++ != ch) return NOT_FOUND;
- }
- }
- return o;
-}
-
-int MDMParser::_getLine(Pipe<char>* pipe, char* buf, int len)
-{
- int unkn = 0;
- int sz = pipe->size();
- int fr = pipe->free();
- if (len > sz)
- len = sz;
- while (len > 0)
- {
- static struct {
- const char* fmt; int type;
- } lutF[] = {
- { "\r\n+USORD: %d,%d,\"%c\"", TYPE_PLUS },
- { "\r\n+USORF: %d,\"" IPSTR "\",%d,%d,\"%c\"", TYPE_PLUS },
- { "\r\n+URDFILE: %s,%d,\"%c\"", TYPE_PLUS },
- };
- static struct {
- const char* sta; const char* end; int type;
- } lut[] = {
- { "\r\nOK\r\n", NULL, TYPE_OK },
- { "\r\nERROR\r\n", NULL, TYPE_ERROR },
- { "\r\n+CME ERROR:", "\r\n", TYPE_ERROR },
- { "\r\n+CMS ERROR:", "\r\n", TYPE_ERROR },
- { "\r\nRING\r\n", NULL, TYPE_RING },
- { "\r\nCONNECT\r\n", NULL, TYPE_CONNECT },
- { "\r\nNO CARRIER\r\n", NULL, TYPE_NOCARRIER },
- { "\r\nNO DIALTONE\r\n", NULL, TYPE_NODIALTONE },
- { "\r\nBUSY\r\n", NULL, TYPE_BUSY },
- { "\r\nNO ANSWER\r\n", NULL, TYPE_NOANSWER },
- { "\r\n+", "\r\n", TYPE_PLUS },
- { "\r\n@", NULL, TYPE_PROMPT }, // Sockets
- { "\r\n>", NULL, TYPE_PROMPT }, // SMS
- { "\n>", NULL, TYPE_PROMPT }, // File
- };
- for (int i = 0; i < sizeof(lutF)/sizeof(*lutF); i ++) {
- pipe->set(unkn);
- int ln = _parseFormated(pipe, len, lutF[i].fmt);
- if (ln == WAIT && fr)
- return WAIT;
- if ((ln != NOT_FOUND) && (unkn > 0))
- return TYPE_UNKNOWN | pipe->get(buf, unkn);
- if (ln > 0)
- return lutF[i].type | pipe->get(buf, ln);
- }
- for (int i = 0; i < sizeof(lut)/sizeof(*lut); i ++) {
- pipe->set(unkn);
- int ln = _parseMatch(pipe, len, lut[i].sta, lut[i].end);
- if (ln == WAIT && fr)
- return WAIT;
- if ((ln != NOT_FOUND) && (unkn > 0))
- return TYPE_UNKNOWN | pipe->get(buf, unkn);
- if (ln > 0)
- return lut[i].type | pipe->get(buf, ln);
- }
- // UNKNOWN
- unkn ++;
- len--;
- }
- return WAIT;
-}
-
-// ----------------------------------------------------------------
-// Serial Implementation
-// ----------------------------------------------------------------
-
-/*! Helper Dev Null Device
- Small helper class used to shut off stderr/stdout. Sometimes stdin/stdout
- is shared with the serial port of the modem. Having printfs inbetween the
- AT commands you cause a failure of the modem.
-*/
-class DevNull : public Stream {
-public:
- DevNull() : Stream(_name+1) { } //!< Constructor
- void claim(const char* mode, FILE* file)
- { freopen(_name, mode, file); } //!< claim a stream
-protected:
- virtual int _getc() { return EOF; } //!< Nothing
- virtual int _putc(int c) { return c; } //!< Discard
- static const char* _name; //!< File name
-};
-const char* DevNull::_name = "/null"; //!< the null device name
-static DevNull null; //!< the null device
-
-MDMSerial::MDMSerial(PinName tx /*= MDMTXD*/, PinName rx /*= MDMRXD*/,
- int baudrate /*= MDMBAUD*/,
-#if DEVICE_SERIAL_FC
- PinName rts /*= MDMRTS*/, PinName cts /*= MDMCTS*/,
-#endif
- int rxSize /*= 256*/, int txSize /*= 128*/) :
- SerialPipe(tx, rx, rxSize, txSize)
-{
- if (rx == USBRX)
- null.claim("r", stdin);
- if (tx == USBTX) {
- null.claim("w", stdout);
- null.claim("w", stderr);
-#ifdef MDM_DEBUG
- _debugLevel = -1;
-#endif
- }
-#ifdef TARGET_UBLOX_C027
- _onboard = (tx == MDMTXD) && (rx == MDMRXD);
- if (_onboard)
- c027_mdm_powerOn(false);
-#endif
- baud(baudrate);
-#if DEVICE_SERIAL_FC
- if ((rts != NC) || (cts != NC))
- {
- Flow flow = (cts == NC) ? RTS :
- (rts == NC) ? CTS : RTSCTS ;
- set_flow_control(flow, rts, cts);
- if (cts != NC) _dev.lpm = LPM_ENABLED;
- }
-#endif
-}
-
-MDMSerial::~MDMSerial(void)
-{
- powerOff();
-#ifdef TARGET_UBLOX_C027
- if (_onboard)
- c027_mdm_powerOff();
-#endif
-}
-
-int MDMSerial::_send(const void* buf, int len)
-{
- return put((const char*)buf, len, true/*=blocking*/);
-}
-
-int MDMSerial::getLine(char* buffer, int length)
-{
- return _getLine(&_pipeRx, buffer, length);
-}
-
-// ----------------------------------------------------------------
-// USB Implementation
-// ----------------------------------------------------------------
-
-#ifdef HAVE_MDMUSB
-MDMUsb::MDMUsb(void)
-{
-#ifdef MDM_DEBUG
- _debugLevel = 1;
-#endif
-#ifdef TARGET_UBLOX_C027
- _onboard = true;
- c027_mdm_powerOn(true);
-#endif
-}
-
-MDMUsb::~MDMUsb(void)
-{
- powerOff();
-#ifdef TARGET_UBLOX_C027
- if (_onboard)
- c027_mdm_powerOff();
-#endif
-}
-
-int MDMUsb::_send(const void* buf, int len) { return 0; }
-
-int MDMUsb::getLine(char* buffer, int length) { return NOT_FOUND; }
-
-#endif
--- a/MDM.h Thu Nov 06 09:06:37 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,660 +0,0 @@
-#pragma once
-
-#include "mbed.h"
-#include <stdarg.h>
-
-#include "Pipe.h"
-#include "SerialPipe.h"
-
-#ifdef TARGET_UBLOX_C027
- #define MDM_IF(onboard,shield) onboard
-#else
- #define MDM_IF(onboard,shield) shield
-#endif
-
-//! include debug capabilty on more powerful targets with a dedicated debug port
-#if defined(TARGET_LPC1768) || defined(TARGET_LPC4088) || defined(TARGET_K64F)
- #define MDM_DEBUG
-#endif
-
-/** basic modem parser class
-*/
-class MDMParser
-{
-public:
- //! Constructor
- MDMParser(void);
- //! get static instance
- static MDMParser* getInstance() { return inst; };
-
- // ----------------------------------------------------------------
- // Types
- // ----------------------------------------------------------------
- //! MT Device Types
- typedef enum { DEV_UNKNOWN, DEV_SARA_G350, DEV_LISA_U200, DEV_LISA_C200,
- DEV_SARA_U260, DEV_SARA_U270, DEV_LEON_G200 } Dev;
- //! SIM Status
- typedef enum { SIM_UNKNOWN, SIM_MISSING, SIM_PIN, SIM_READY } Sim;
- //! SIM Status
- typedef enum { LPM_DISABLED, LPM_ENABLED, LPM_ACTIVE } Lpm;
- //! Device status
- typedef struct {
- Dev dev; //!< Device Type
- Lpm lpm; //!< Power Saving
- Sim sim; //!< SIM Card Status
- char ccid[20+1]; //!< Integrated Circuit Card ID
- char imsi[15+1]; //!< International Mobile Station Identity
- char imei[15+1]; //!< International Mobile Equipment Identity
- char meid[18+1]; //!< Mobile Equipment IDentifier
- char manu[16]; //!< Manufacturer (u-blox)
- char model[16]; //!< Model Name (LISA-U200, LISA-C200 or SARA-G350)
- char ver[16]; //!< Software Version
- } DevStatus;
- //! Registration Status
- typedef enum { REG_UNKNOWN, REG_DENIED, REG_NONE, REG_HOME, REG_ROAMING } Reg;
- //! Access Technology
- typedef enum { ACT_UNKNOWN, ACT_GSM, ACT_EDGE, ACT_UTRAN, ACT_CDMA } AcT;
- //! Network Status
- typedef struct {
- Reg csd; //!< CSD Registration Status (Circuit Switched Data)
- Reg psd; //!< PSD Registration status (Packet Switched Data)
- AcT act; //!< Access Technology
- int rssi; //!< Received Signal Strength Indication (in dBm, range -113..-53)
- int ber; //!< Bit Error Rate (BER), see 3GPP TS 45.008 [20] subclause 8.2.4
- char opr[16+1]; //!< Operator Name
- char num[32]; //!< Mobile Directory Number
- unsigned short lac; //!< location area code in hexadecimal format (2 bytes in hex)
- unsigned int ci; //!< Cell ID in hexadecimal format (2 to 4 bytes in hex)
- } NetStatus;
- //! An IP v4 address
- typedef uint32_t IP;
- #define NOIP ((MDMParser::IP)0) //!< No IP address
- // ip number formating and conversion
- #define IPSTR "%d.%d.%d.%d"
- #define IPNUM(ip) ((ip)>>24)&0xff, \
- ((ip)>>16)&0xff, \
- ((ip)>> 8)&0xff, \
- ((ip)>> 0)&0xff
- #define IPADR(a,b,c,d) ((((IP)(a))<<24) | \
- (((IP)(b))<<16) | \
- (((IP)(c))<< 8) | \
- (((IP)(d))<< 0))
-
-
- // ----------------------------------------------------------------
- // Device
- // ----------------------------------------------------------------
-
- typedef enum { AUTH_NONE, AUTH_PAP, AUTH_CHAP, AUTH_DETECT } Auth;
-
- /** Combined Init, checkNetStatus, join suitable for simple applications
- \param simpin a optional pin of the SIM card
- \param apn the of the network provider e.g. "internet" or "apn.provider.com"
- \param username is the user name text string for the authentication phase
- \param password is the password text string for the authentication phase
- \param auth is the authentication mode (CHAP,PAP,NONE or DETECT)
- \return true if successful, false otherwise
- */
- bool connect(const char* simpin = NULL,
- const char* apn = NULL, const char* username = NULL,
- const char* password = NULL, Auth auth = AUTH_DETECT,
- PinName pn MDM_IF( = MDMPWRON, = D4));
-
- /** register (Attach) the MT to the GPRS service.
- \param simpin a optional pin of the SIM card
- \param status an optional struture to with device information
- \return true if successful, false otherwise
- */
- bool init(const char* simpin = NULL, DevStatus* status = NULL,
- PinName pn MDM_IF( = MDMPWRON, = D4));
-
- /** register to the network
- \param status an optional structure to with network information
- \param timeout_ms -1 blocking, else non blocking timeout in ms
- \return true if successful and connected to network, false otherwise
- */
- bool registerNet(NetStatus* status = NULL, int timeout_ms = 180000);
-
- /** check if the network is available
- \param status an optional structure to with network information
- \return true if successful and connected to network, false otherwise
- */
- bool checkNetStatus(NetStatus* status = NULL);
-
- /** Power off the MT, This function has to be called prior to
- switching off the supply.
- \return true if successfully, false otherwise
- */
- bool powerOff(void);
-
- // ----------------------------------------------------------------
- // Data Connection (GPRS)
- // ----------------------------------------------------------------
-
- /** register (Attach) the MT to the GPRS service.
- \param apn the of the network provider e.g. "internet" or "apn.provider.com"
- \param username is the user name text string for the authentication phase
- \param password is the password text string for the authentication phase
- \param auth is the authentication mode (CHAP,PAP,NONE or DETECT)
- \return the ip that is assigned
- */
- MDMParser::IP join(const char* apn = NULL, const char* username = NULL,
- const char* password = NULL, Auth auth = AUTH_DETECT);
-
- /** deregister (detach) the MT from the GPRS service.
- \return true if successful, false otherwise
- */
- bool disconnect(void);
-
- /** Translates a domain name to an IP address
- \param host the domain name to translate e.g. "u-blox.com"
- \return the IP if successful, 0 otherwise
- */
- MDMParser::IP gethostbyname(const char* host);
-
- // ----------------------------------------------------------------
- // Sockets
- // ----------------------------------------------------------------
-
- //! Type of IP protocol
- typedef enum { IPPROTO_TCP, IPPROTO_UDP } IpProtocol;
-
- //! Socket error return codes
- #define SOCKET_ERROR -1
-
- /** Create a socket for a ip protocol (and optionaly bind)
- \param ipproto the protocol (UDP or TCP)
- \param port in case of UDP, this optional port where it is bind
- \return the socket handle if successful or SOCKET_ERROR on failure
- */
- int socketSocket(IpProtocol ipproto, int port = -1);
-
- /** make a socket connection
- \param socket the socket handle
- \param host the domain name to connect e.g. "u-blox.com"
- \param port the port to connect
- \return true if successfully, false otherwise
- */
- bool socketConnect(int socket, const char* host, int port);
-
- /** make a socket connection
- \param socket the socket handle
- \return true if connected, false otherwise
- */
- bool socketIsConnected(int socket);
-
- /** Get the number of bytes pending for reading for this socket
- \param socket the socket handle
- \param timeout_ms -1 blocking, else non blocking timeout in ms
- \return 0 if successful or SOCKET_ERROR on failure
- */
- bool socketSetBlocking(int socket, int timeout_ms);
-
- /** Write socket data
- \param socket the socket handle
- \param buf the buffer to write
- \param len the size of the buffer to write
- \return the size written or SOCKET_ERROR on failure
- */
- int socketSend(int socket, const char * buf, int len);
-
- /** Write socket data to a IP
- \param socket the socket handle
- \param ip the ip to send to
- \param port the port to send to
- \param buf the buffer to write
- \param len the size of the buffer to write
- \return the size written or SOCKET_ERROR on failure
- */
- int socketSendTo(int socket, IP ip, int port, const char * buf, int len);
-
- /** Get the number of bytes pending for reading for this socket
- \param socket the socket handle
- \return the number of bytes pending or SOCKET_ERROR on failure
- */
- int socketReadable(int socket);
-
- /** Read this socket
- \param socket the socket handle
- \param buf the buffer to read into
- \param len the size of the buffer to read into
- \return the number of bytes read or SOCKET_ERROR on failure
- */
- int socketRecv(int socket, char* buf, int len);
-
- /** Read from this socket
- \param socket the socket handle
- \param ip the ip of host where the data originates from
- \param port the port where the data originates from
- \param buf the buffer to read into
- \param len the size of the buffer to read into
- \return the number of bytes read or SOCKET_ERROR on failure
- */
- int socketRecvFrom(int socket, IP* ip, int* port, char* buf, int len);
-
- /** Close a connectied socket (that was connected with #socketConnect)
- \param socket the socket handle
- \return true if successfully, false otherwise
- */
- bool socketClose(int socket);
-
- /** Free the socket (that was allocated before by #socketSocket)
- \param socket the socket handle
- \return true if successfully, false otherwise
- */
- bool socketFree(int socket);
-
- // ----------------------------------------------------------------
- // SMS Short Message Service
- // ----------------------------------------------------------------
-
- /** count the number of sms in the device and optionally return a
- list with indexes from the storage locations in the device.
- \param stat what type of messages you can use use
- "REC UNREAD", "REC READ", "STO UNSENT", "STO SENT", "ALL"
- \param ix list where to save the storage positions
- \param num number of elements in the list
- \return the number of messages, this can be bigger than num, -1 on failure
- */
- int smsList(const char* stat = "ALL", int* ix = NULL, int num = 0);
-
- /** Read a Message from a storage position
- \param ix the storage position to read
- \param num the originator address (~16 chars)
- \param buf a buffer where to save the sm
- \param len the length of the sm
- \return true if successful, false otherwise
- */
- bool smsRead(int ix, char* num, char* buf, int len);
-
- /** Send a message to a recipient
- \param ix the storage position to delete
- \return true if successful, false otherwise
- */
- bool smsDelete(int ix);
-
- /** Send a message to a recipient
- \param num the phone number of the recipient
- \param buf the content of the message to sent
- \return true if successful, false otherwise
- */
- bool smsSend(const char* num, const char* buf);
-
- // ----------------------------------------------------------------
- // USSD Unstructured Supplementary Service Data
- // ----------------------------------------------------------------
-
- /** Read a Message from a storage position
- \param cmd the ussd command to send e.g "*#06#"
- \param buf a buffer where to save the reply
- \return true if successful, false otherwise
- */
- bool ussdCommand(const char* cmd, char* buf);
-
- // ----------------------------------------------------------------
- // FILE
- // ----------------------------------------------------------------
-
- /** Delete a file in the local file system
- \param filename the name of the file
- \return true if successful, false otherwise
- */
- bool delFile(const char* filename);
-
- /** Write some data to a file in the local file system
- \param filename the name of the file
- \param buf the data to write
- \param len the size of the data to write
- \return the number of bytes written
- */
- int writeFile(const char* filename, const char* buf, int len);
-
- /** REad a file from the local file system
- \param filename the name of the file
- \param buf a buffer to hold the data
- \param len the size to read
- \return the number of bytes read
- */
- int readFile(const char* filename, char* buf, int len);
-
- // ----------------------------------------------------------------
- // DEBUG/DUMP status to standard out (printf)
- // ----------------------------------------------------------------
-
- /*! Set the debug level
- \param level 0 = OFF, 1 = INFO(default), 2 = TRACE, 3 = ATCMD
- \return true if successful, false not possible
- */
- bool setDebug(int level);
-
- //! helper type for DPRINT
- typedef int (*_DPRINT)(void* param, char const * format, ...);
-
- //! helper to declate templates and void versions
-#define _DUMP_TEMPLATE(func, type, arg) \
- template<class T> \
- inline void func(type arg, \
- int (*dprint)( T* param, char const * format, ...), \
- T* param) { func(arg, (_DPRINT)dprint, (void*)param); } \
- static void func(type arg, \
- _DPRINT dprint = (_DPRINT)fprintf, \
- void* param = (void*)stdout);
-
- /** dump the device status to stdout using printf
- \param status the status to convert to textual form,
- unavailable fields are ommited (not printed)
- \param dprint a function pointer
- \param param the irst argument passed to dprint
- */
- _DUMP_TEMPLATE(dumpDevStatus, MDMParser::DevStatus*, status)
-
- /** dump the network status to stdout using printf
- \param status the status to convert to textual form,
- unavailable fields are ommited (not printed)
- \param dprint a function pointer
- \param param the irst argument passed to dprint
- */
- _DUMP_TEMPLATE(dumpNetStatus, MDMParser::NetStatus*, status)
-
- /** dump the ip address to stdout using printf
- \param ip the ip to convert to textual form,
- unavailable fields are ommited (not printed)
- \param dprint a function pointer
- \param param the irst argument passed to dprint
- */
- _DUMP_TEMPLATE(dumpIp, MDMParser::IP, ip)
-
- // ----------------------------------------------------------------
- // Parseing
- // ----------------------------------------------------------------
-
- enum {
- // waitFinalResp Responses
- NOT_FOUND = 0,
- WAIT = -1, // TIMEOUT
- RESP_OK = -2,
- RESP_ERROR = -3,
- RESP_PROMPT = -4,
-
- // getLine Responses
- #define LENGTH(x) (x & 0x00FFFF) //!< extract/mask the length
- #define TYPE(x) (x & 0xFF0000) //!< extract/mask the type
-
- TYPE_UNKNOWN = 0x000000,
- TYPE_OK = 0x110000,
- TYPE_ERROR = 0x120000,
- TYPE_RING = 0x210000,
- TYPE_CONNECT = 0x220000,
- TYPE_NOCARRIER = 0x230000,
- TYPE_NODIALTONE = 0x240000,
- TYPE_BUSY = 0x250000,
- TYPE_NOANSWER = 0x260000,
- TYPE_PROMPT = 0x300000,
- TYPE_PLUS = 0x400000,
- TYPE_TEXT = 0x500000,
-
- // special timout constant
- TIMEOUT_BLOCKING = -1
- };
-
- /** Get a line from the physical interface. This function need
- to be implemented in a inherited class. Usually just calls
- #_getLine on the rx buffer pipe.
-
- \param buf the buffer to store it
- \param buf size of the buffer
- \return type and length if something was found,
- WAIT if not enough data is available
- NOT_FOUND if nothing was found
- */
- virtual int getLine(char* buf, int len) = 0;
-
- /* clear the pending input data
- */
- virtual void purge(void) = 0;
-
- /** Write data to the device
- \param buf the buffer to write
- \param buf size of the buffer to write
- \return bytes written
- */
- virtual int send(const char* buf, int len);
-
- /** Write formated date to the physical interface (printf style)
- \param fmt the format string
- \param .. variable arguments to be formated
- \return bytes written
- */
- int sendFormated(const char* format, ...);
-
- /** callback function for #waitFinalResp with void* as argument
- \param type the #getLine response
- \param buf the parsed line
- \param len the size of the parsed line
- \param param the optional argument passed to #waitFinalResp
- \return WAIT if processing should continue,
- any other value aborts #waitFinalResp and this retunr value retuned
- */
- typedef int (*_CALLBACKPTR)(int type, const char* buf, int len, void* param);
-
- /** Wait for a final respons
- \param cb the optional callback function
- \param param the optional callback function parameter
- \param timeout_ms the timeout to wait (See Estimated command
- response time of AT manual)
- */
- int waitFinalResp(_CALLBACKPTR cb = NULL,
- void* param = NULL,
- int timeout_ms = 10000);
-
- /** template version of #waitFinalResp when using callbacks,
- This template will allow the compiler to do type cheking but
- internally symply casts the arguments and call the (void*)
- version of #waitFinalResp.
- \sa waitFinalResp
- */
- template<class T>
- inline int waitFinalResp(int (*cb)(int type, const char* buf, int len, T* param),
- T* param,
- int timeout_ms = 10000)
- {
- return waitFinalResp((_CALLBACKPTR)cb, (void*)param, timeout_ms);
- }
-
-protected:
- /** Write bytes to the physical interface. This function should be
- implemented in a inherited class.
- \param buf the buffer to write
- \param buf size of the buffer to write
- \return bytes written
- */
- virtual int _send(const void* buf, int len) = 0;
-
- /** Helper: Parse a line from the receiving buffered pipe
- \param pipe the receiving buffer pipe
- \param buf the parsed line
- \param len the size of the parsed line
- \return type and length if something was found,
- WAIT if not enough data is available
- NOT_FOUND if nothing was found
- */
- static int _getLine(Pipe<char>* pipe, char* buffer, int length);
-
- /** Helper: Parse a match from the pipe
- \param pipe the buffered pipe
- \param number of bytes to parse at maximum,
- \param sta the starting string, NULL if none
- \param end the terminating string, NULL if none
- \return size of parsed match
- */
- static int _parseMatch(Pipe<char>* pipe, int len, const char* sta, const char* end);
-
- /** Helper: Parse a match from the pipe
- \param pipe the buffered pipe
- \param number of bytes to parse at maximum,
- \param fmt the formating string (%d any number, %c any char of last %d len)
- \return size of parsed match
- */
- static int _parseFormated(Pipe<char>* pipe, int len, const char* fmt);
-
-protected:
- // for rtos over riding by useing Rtos<MDMxx>
- /** override in a rtos system, you us the wait function of a Thread
- \param ms the number of milliseconds to wait
- */
- virtual void wait_ms(int ms) { if (ms) ::wait_ms(ms); }
- //! override the lock in a rtos system
- virtual void lock(void) { }
- //! override the unlock in a rtos system
- virtual void unlock(void) { }
-protected:
- // parsing callbacks for different AT commands and their parameter arguments
- static int _cbString(int type, const char* buf, int len, char* str);
- static int _cbInt(int type, const char* buf, int len, int* val);
- // device
- static int _cbATI(int type, const char* buf, int len, Dev* dev);
- static int _cbCPIN(int type, const char* buf, int len, Sim* sim);
- static int _cbCCID(int type, const char* buf, int len, char* ccid);
- // network
- static int _cbCSQ(int type, const char* buf, int len, NetStatus* status);
- static int _cbCOPS(int type, const char* buf, int len, NetStatus* status);
- static int _cbCNUM(int type, const char* buf, int len, char* num);
- static int _cbUACTIND(int type, const char* buf, int len, int* i);
- static int _cbUDOPN(int type, const char* buf, int len, char* mccmnc);
- // sockets
- static int _cbCMIP(int type, const char* buf, int len, IP* ip);
- static int _cbUPSND(int type, const char* buf, int len, int* act);
- static int _cbUPSND(int type, const char* buf, int len, IP* ip);
- static int _cbUDNSRN(int type, const char* buf, int len, IP* ip);
- static int _cbUSOCR(int type, const char* buf, int len, int* handle);
- static int _cbUSORD(int type, const char* buf, int len, char* out);
- typedef struct { char* buf; IP ip; int port; } USORFparam;
- static int _cbUSORF(int type, const char* buf, int len, USORFparam* param);
- typedef struct { char* buf; char* num; } CMGRparam;
- static int _cbCUSD(int type, const char* buf, int len, char* buf);
- // sms
- typedef struct { int* ix; int num; } CMGLparam;
- static int _cbCMGL(int type, const char* buf, int len, CMGLparam* param);
- static int _cbCMGR(int type, const char* buf, int len, CMGRparam* param);
- // file
- typedef struct { const char* filename; char* buf; int sz; int len; } URDFILEparam;
- static int _cbURDFILE(int type, const char* buf, int len, URDFILEparam* param);
- // variables
- DevStatus _dev; //!< collected device information
- NetStatus _net; //!< collected network information
- IP _ip; //!< assigned ip address
- // management struture for sockets
- typedef struct { int handle; int timeout_ms; volatile bool connected; volatile int pending; } SockCtrl;
- // LISA-C has 6 TCP and 6 UDP sockets
- // LISA-U and SARA-G have 7 sockets
- SockCtrl _sockets[12];
- int _findSocket(int handle = SOCKET_ERROR/* = CREATE*/);
- static MDMParser* inst;
- bool _init;
-#ifdef TARGET_UBLOX_C027
- bool _onboard;
-#endif
-#ifdef MDM_DEBUG
- int _debugLevel;
- Timer _debugTime;
-#endif
-};
-
-// -----------------------------------------------------------------------
-
-/** modem class which uses a serial port
- as physical interface.
-*/
-class MDMSerial : public SerialPipe, public MDMParser
-{
-public:
- /** Constructor
-
- \param tx is the serial ports transmit pin (modem to CPU)
- \param rx is the serial ports receive pin (CPU to modem)
- \param baudrate the baudrate of the modem use 115200
- \param rts is the serial ports ready to send pin (CPU to modem)
- this pin is optional
- \param cts is the serial ports clear to send pin (modem to CPU)
- this pin is optional, but required for power saving to be enabled
- \param rxSize the size of the serial rx buffer
- \param txSize the size of the serial tx buffer
- */
- MDMSerial(PinName tx MDM_IF( = MDMTXD, = D1 ),
- PinName rx MDM_IF( = MDMRXD, = D0 ),
- int baudrate MDM_IF( = MDMBAUD, = 115200 ),
- #if DEVICE_SERIAL_FC
- PinName rts MDM_IF( = MDMRTS, = NC /* D2 resistor R62 on shield not mounted */ ),
- PinName cts MDM_IF( = MDMCTS, = NC /* D3 resistor R63 on shield not mounted */ ),
- #endif
- int rxSize = 256 ,
- int txSize = 128 );
- //! Destructor
- virtual ~MDMSerial(void);
-
- /** Get a line from the physical interface.
- \param buf the buffer to store it
- \param buf size of the buffer
- \return type and length if something was found,
- WAIT if not enough data is available
- NOT_FOUND if nothing was found
- */
- virtual int getLine(char* buffer, int length);
-
- /* clear the pending input data */
- virtual void purge(void)
- {
- while (readable())
- getc();
- }
-protected:
- /** Write bytes to the physical interface.
- \param buf the buffer to write
- \param buf size of the buffer to write
- \return bytes written
- */
- virtual int _send(const void* buf, int len);
-};
-
-// -----------------------------------------------------------------------
-
-//#define HAVE_MDMUSB
-#ifdef HAVE_MDMUSB
-class MDMUsb : /*public UsbSerial,*/ public MDMParser
-{
-public:
- //! Constructor
- MDMUsb(void);
- //! Destructor
- virtual ~MDMUsb(void);
- virtual int getLine(char* buffer, int length);
- virtual void purge(void) { }
-protected:
- virtual int _send(const void* buf, int len);
-};
-#endif
-
-// -----------------------------------------------------------------------
-
-#ifdef RTOS_H
-/** Use this template to override the lock and wait functions of the
- modem driver in a Rtos system. For example declare it the modem
- object as MDMRtos<MDMSerial> instead of MDMSerial.
-*/
-template <class T>
-class MDMRtos : public T
-{
-protected:
- //! we assume that the modem runs in a thread so we yield when waiting
- virtual void wait_ms(int ms) {
- if (ms) Thread::wait(ms);
- else Thread::yield();
- }
- //! lock a mutex when accessing the modem
- virtual void lock(void) { _mtx.lock(); }
- //! unlock the modem when done accessing it
- virtual void unlock(void) { _mtx.unlock(); }
- // the mutex resource
- Mutex _mtx;
-};
-#endif
\ No newline at end of file
--- a/MDMAPN.h Thu Nov 06 09:06:37 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-#pragma once
-
-/* ----------------------------------------------------------------
- APN stands for Access Point Name, a setting on your modem or phone
- that identifies an external network your phone can access for data
- (e.g. 3G or 4G Internet service on your phone).
-
- The APN settings can be forced when calling the join function.
- Below is a list of known APNs that us used if no apn config
- is forced. This list could be extended by other settings.
-
- For further reading:
- wiki apn: http://en.wikipedia.org/wiki/Access_Point_Name
- wiki mcc/mnc: http://en.wikipedia.org/wiki/Mobile_country_code
- google: https://www.google.de/search?q=APN+list
----------------------------------------------------------------- */
-
-//! helper to generate the APN string
-#define _APN(apn,username,password) apn "\0" username "\0" password "\0"
-
-//! helper to extract a field from the config string
-#define _APN_GET(cfg) \
- *cfg ? cfg : ""; \
- cfg += strlen(cfg) + 1
-
-//! APN lookup struct
-typedef struct {
- const char* mccmnc; //!< mobile country code (MCC) and mobile network code MNC
- const char* cfg; //!< APN configuartion string, use _APN macro to generate
-} APN_t;
-
-//! default APN settings used by many networks
-static const char* apndef = _APN(,,)
- _APN("internet",,);
-
-/*! this is a list of special APNs for different network operators
- There is no need to enter the default apn internet in the table;
- apndef will be used if no entry matches.
-
- The APN without username/password have to be listed first.
-*/
-static const APN_t apnlut[] = {
-// MCC Country
-// { /* Operator */ "MCC-MNC[,MNC]" _APN(APN,USERNAME,PASSWORD) },
-// MCC must be 3 digits
-// MNC must be either 2 or 3 digits
-// MCC must be separated by '-' from MNC, multiple MNC can be separated by ','
-
-// 232 Austria - AUT
- { /* T-Mobile */ "232-03", _APN("m2m.business",,) },
-
-// 460 China - CN
- { /* CN Mobile */"460-00", _APN("cmnet",,)
- _APN("cmwap",,) },
- { /* Unicom */ "460-01", _APN("3gnet",,)
- _APN("uninet","uninet","uninet") },
-
-// 262 Germany - DE
- { /* T-Mobile */ "262-01", _APN("internet.t-mobile","t-mobile","tm") },
- { /* T-Mobile */ "262-02,06",
- _APN("m2m.business",,) },
-
-// 222 Italy - IT
- { /* TIM */ "222-01", _APN("ibox.tim.it",,) },
- { /* Vodafone */ "222-10", _APN("web.omnitel.it",,) },
- { /* Wind */ "222-88", _APN("internet.wind.biz",,) },
-
-// 440 Japan - JP
- { /* Softbank */ "440-04,06,20,40,41,42,43,44,45,46,47,48,90,91,92,93,94,95"
- ",96,97,98"
- _APN("open.softbank.ne.jp","opensoftbank","ebMNuX1FIHg9d3DA")
- _APN("smile.world","dna1trop","so2t3k3m2a") },
- { /* NTTDoCoMo */"440-09,10,11,12,13,14,15,16,17,18,19,21,22,23,24,25,26,27,"
- "28,29,30,31,32,33,34,35,36,37,38,39,58,59,60,61,62,63,"
- "64,65,66,67,68,69,87,99",
- _APN("bmobilewap",,) /*BMobile*/
- _APN("mpr2.bizho.net","Mopera U",) /* DoCoMo */
- _APN("bmobile.ne.jp","bmobile@wifi2","bmobile") /*BMobile*/ },
-
-// 204 Netherlands - NL
- { /* Vodafone */ "204-04", _APN("public4.m2minternet.com",,) },
-
-// 293 Slovenia - SI
- { /* Si.mobil */ "293-40", _APN("internet.simobil.si",,) },
- { /* Tusmobil */ "293-70", _APN("internet.tusmobil.si",,) },
-
-// 240 Sweden SE
- { /* Telia */ "240-01", _APN("online.telia.se",,) },
- { /* Telenor */ "240-06,08",
- _APN("services.telenor.se",,) },
- { /* Tele2 */ "240-07", _APN("mobileinternet.tele2.se",,) },
-
-// 228 Switzerland - CH
- { /* Swisscom */ "228-01", _APN("gprs.swisscom.ch",,) },
- { /* Orange */ "228-03", _APN("internet",,) /* contract */
- _APN("click",,) /* pre-pay */ },
-
-// 234 United Kingdom - GB
- { /* O2 */ "234-02,10,11",
- _APN("mobile.o2.co.uk","faster","web") /* contract */
- _APN("mobile.o2.co.uk","bypass","web") /* pre-pay */
- _APN("payandgo.o2.co.uk","payandgo","payandgo") },
- { /* Vodafone */ "234-15", _APN("internet","web","web") /* contract */
- _APN("pp.vodafone.co.uk","wap","wap") /* pre-pay */ },
- { /* Three */ "234-20", _APN("three.co.uk",,) },
-
-// 310 United States of America - US
- { /* T-Mobile */ "310-026,260,490",
- _APN("epc.tmobile.com",,)
- _APN("fast.tmobile.com",,) /* LTE */ },
- { /* AT&T */ "310-030,150,170,260,410,560,680",
- _APN("phone",,)
- _APN("wap.cingular","WAP@CINGULARGPRS.COM","CINGULAR1")
- _APN("isp.cingular","ISP@CINGULARGPRS.COM","CINGULAR1") },
-};
-
-inline const char* apnconfig(const char* imsi)
-{
- const char* config = NULL;
- if (imsi && *imsi) {
- // many carriers use internet without username and password, os use this as default
- // now try to lookup the setting for our table
- for (int i = 0; i < sizeof(apnlut)/sizeof(*apnlut) && !config; i ++) {
- const char* p = apnlut[i].mccmnc;
- // check the MCC
- if ((0 == memcmp(imsi, p, 3))) {
- p += 3;
- // check all the MNC, MNC length can be 2 or 3 digits
- while (((p[0] == '-') || (p[0] == ',')) &&
- (p[1] >= '0') && (p[1] <= '9') &&
- (p[2] >= '0') && (p[2] <= '9') && !config) {
- int l = ((p[3] >= '0') && (p[3] <= '9')) ? 3 : 2;
- if (0 == memcmp(imsi+3,p+1,l))
- config = apnlut[i].cfg;
- p += 1 + l;
- }
- }
- }
- }
- // use default if not found
- if (!config)
- config = apndef;
- return config;
-}
\ No newline at end of file
--- a/Socket/Endpoint.h Thu Nov 06 09:06:37 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/* Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#ifndef ENDPOINT_H
-#define ENDPOINT_H
-
-#include "MDM.h"
-
-class UDPSocket;
-
-class Endpoint {
- friend class UDPSocket;
-public:
- Endpoint(void) {
- _ip[0] = '\0';
- _port = 0;
- _mdm = NULL;
- }
-
- void reset_address(void) {
- _ip[0] = '\0';
- _port = 0;
- }
-
- int set_address(const char* host, const int port) {
- _ip[0] = '\0';
- _port = 0;
- if (_mdm == NULL)
- _mdm = MDMParser::getInstance();
- if (_mdm == NULL)
- return -1;
- // resove the host name (eventually does a dns lookup)
- MDMParser::IP ip = _mdm->gethostbyname(host);
- if (ip == NOIP)
- return -1;
- sprintf(_ip, IPSTR, IPNUM(ip));
- _port = port;
- return 0;
- }
-
- char* get_address(void) { return _ip; }
-
- int get_port(void) { return _port; }
-
-protected:
- MDMParser* _mdm;
- char _ip[17];
- int _port;
-};
-
-#endif
--- a/Socket/Socket.h Thu Nov 06 09:06:37 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-#ifndef SOCKET_H_
-#define SOCKET_H_
-
-#include "MDM.h"
-
-/** Socket file descriptor and select wrapper
- */
-class Socket {
-public:
- Socket() {
- _socket = -1;
- _timeout_ms = MDMParser::TIMEOUT_BLOCKING;
- _mdm = NULL;
- }
-
- void set_blocking(bool blocking, unsigned int timeout = 1500) {
- _timeout_ms = blocking ? MDMParser::TIMEOUT_BLOCKING : (int)timeout;
- if (_socket >= 0) {
- _mdm->socketSetBlocking(_socket, _timeout_ms);
- }
- }
-
- int close() {
- bool ret = false;
- if (_socket >= 0)
- {
- ret = _mdm->socketClose(_socket);
- _mdm->socketFree(_socket);
- _socket = -1;
- _timeout_ms = MDMParser::TIMEOUT_BLOCKING;
- }
- return ret ? 0 : -1;
- }
-
- ~Socket() { close(); }
-
-protected:
- int _socket;
- int _timeout_ms;
- MDMParser* _mdm;
-};
-
-
-#endif /* SOCKET_H_ */
--- a/Socket/TCPSocketConnection.h Thu Nov 06 09:06:37 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-#ifndef TCPSOCKET_H
-#define TCPSOCKET_H
-
-#include "Socket.h"
-
-/** TCP socket connection
- */
-class TCPSocketConnection: public Socket
-{
- friend class TCPSocketServer;
-
-public:
- /** TCP socket connection
- */
- TCPSocketConnection() {}
-
- /** Connects this TCP socket to the server
- \param host The host to connect to. It can either be an IP Address or a hostname that will be resolved with DNS.
- \param port The host's port to connect to.
- \return 0 on success, -1 on failure.
- */
- int connect(const char* host, const int port)
- {
- if (_mdm == NULL)
- _mdm = MDMParser::getInstance();
- if (_mdm == NULL)
- return -1;
-
- if (_socket < 0) {
- _socket = _mdm->socketSocket(MDMParser::IPPROTO_TCP);
- if (_socket < 0) {
- return -1;
- }
- }
-
- _mdm->socketSetBlocking(_socket, _timeout_ms);
- if (!_mdm->socketConnect(_socket, host, port)) {
- return -1;
- }
- return 0;
- }
- /** Check if the socket is connected
- \return true if connected, false otherwise.
- */
- bool is_connected(void) { return _mdm->socketIsConnected(_socket); }
-
- /** Send data to the remote host.
- \param data The buffer to send to the host.
- \param length The length of the buffer to send.
- \return the number of written bytes on success (>=0) or -1 on failure
- */
- int send(char* data, int length) { return _mdm->socketSend(_socket, data, length); }
-
- /** Send all the data to the remote host.
- \param data The buffer to send to the host.
- \param length The length of the buffer to send.
- \return the number of written bytes on success (>=0) or -1 on failure
- */
- int send_all(char* data, int length) { return send(data,length); }
-
- /** Receive data from the remote host.
- \param data The buffer in which to store the data received from the host.
- \param length The maximum length of the buffer.
- \return the number of received bytes on success (>=0) or -1 on failure
- */
- int receive(char* data, int length) { return _mdm->socketRecv(_socket, data, length); }
-
- /** Receive all the data from the remote host.
- \param data The buffer in which to store the data received from the host.
- \param length The maximum length of the buffer.
- \return the number of received bytes on success (>=0) or -1 on failure
- */
- int receive_all(char* data, int length) { return receive(data,length); }
-
-};
-
-#endif
--- a/Socket/UDPSocket.h Thu Nov 06 09:06:37 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/* Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef UDPSOCKET_H
-#define UDPSOCKET_H
-
-#include "Socket/Socket.h"
-#include "Socket/Endpoint.h"
-
-/**
-UDP Socket
-*/
-class UDPSocket : public Socket {
-
-public:
- int init(void)
- {
- if (_mdm == NULL)
- _mdm = MDMParser::getInstance();
- if (_mdm == NULL)
- return -1;
- return 0;
- }
-
- int bind(int port) {
- if (_socket < 0) {
- _socket = _mdm->socketSocket(MDMParser::IPPROTO_UDP, port);
- if (_socket < 0) {
- return -1;
- }
- }
- _mdm->socketSetBlocking(_socket, _timeout_ms);
- return 0;
- }
-
- int join_multicast_group(const char* address) { return -1; }
-
- int set_broadcasting(bool broadcast=true) { return -1; }
-
- int sendTo(Endpoint &remote, char *packet, int length)
- {
- char* str = remote.get_address();
- int port = remote.get_port();
- MDMParser::IP ip = _mdm->gethostbyname(str);
- if (ip == NOIP)
- return -1;
- return _mdm->socketSendTo(_socket, ip, port, packet, length);
- }
-
- int receiveFrom(Endpoint &remote, char *buffer, int length)
- {
- MDMParser::IP ip;
- int port;
- int ret = _mdm->socketRecvFrom(_socket, &ip, &port, buffer, length);
- if (ret >= 0) {
- char str[17];
- sprintf(str, IPSTR, IPNUM(ip));
- remote.set_address(str, port);
- }
- return ret;
- }
-};
-
-#endif
