CQ出版 Interface 2014年10月号のC027(MAX7-Q)GPSテスト記事のプログラム。 CQ publishing Interface 2014.10 issue, C027 GPS(MAX-7Q) test program.
Dependencies: C027 C027_Support mbed
Revision 3:002503ab7199, committed 2014-07-28
- Comitter:
- ntaka206
- Date:
- Mon Jul 28 15:51:53 2014 +0000
- Parent:
- 2:bc413454a83e
- Commit message:
- C027_SupportTest_xively_location????????C027_Support?????????????; http://mbed.org/users/ntaka206/code/C027_Support/;
Changed in this revision
diff -r bc413454a83e -r 002503ab7199 C027_Support.lib --- a/C027_Support.lib Mon Jul 28 15:45:16 2014 +0000 +++ b/C027_Support.lib Mon Jul 28 15:51:53 2014 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/teams/ublox/code/C027_Support/#4d6fa520dfca +http://mbed.org/users/ntaka206/code/C027_Support/#839c6c8b7a16
diff -r bc413454a83e -r 002503ab7199 C027_Support/GPS.cpp --- a/C027_Support/GPS.cpp Mon Jul 28 15:45:16 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,354 +0,0 @@ -#include "mbed.h" -#include <ctype.h> -#include "GPS.h" - -int GPSParser::_getMessage(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) - { - // NMEA protocol - pipe->set(unkn); - int nmea = _parseNmea(pipe,len); - if ((nmea != NOT_FOUND) && (unkn > 0)) - return UNKNOWN | pipe->get(buf,unkn); - if (nmea == WAIT && fr) - return WAIT; - if (nmea > 0) - return NMEA | pipe->get(buf,nmea); - // UBX protocol - - pipe->set(unkn); - int ubx = _parseUbx(pipe,len); - if ((ubx != NOT_FOUND) && (unkn > 0)) - return UNKNOWN | pipe->get(buf,unkn); - if (ubx == WAIT && fr) - return WAIT; - if (ubx > 0) - return UBX | pipe->get(buf,ubx); - - // UNKNOWN - unkn ++; - len--; - } - if (unkn > 0) - return UNKNOWN | pipe->get(buf,unkn); - return WAIT; -} - -int GPSParser::_parseNmea(Pipe<char>* pipe, int len) -{ - int o = 0; - int c = 0; - char ch; - if (++o > len) return WAIT; - if ('$' != pipe->next()) return NOT_FOUND; - // this needs to be extended by crc checking - for (;;) - { - if (++o > len) return WAIT; - ch = pipe->next(); - if ('*' == ch) break; // crc delimiter - if (!isprint(ch)) return NOT_FOUND; - c ^= ch; - } - if (++o > len) return WAIT; - ch = toHex[(c >> 4) & 0xF]; // high nibble - if (ch != pipe->next()) return NOT_FOUND; - if (++o > len) return WAIT; - ch = toHex[(c >> 0) & 0xF]; // low nibble - if (ch != pipe->next()) return NOT_FOUND; - if (++o > len) return WAIT; - if ('\r' != pipe->next()) return NOT_FOUND; - if (++o > len) return WAIT; - if ('\n' != pipe->next()) return NOT_FOUND; - return o; -} - -int GPSParser::_parseUbx(Pipe<char>* pipe, int l) -{ - int o = 0; - if (++o > l) return WAIT; - if ('\xB5' != pipe->next()) return NOT_FOUND; - if (++o > l) return WAIT; - if ('\x62' != pipe->next()) return NOT_FOUND; - o += 4; - if (o > l) return WAIT; - int i,j,ca,cb; - i = pipe->next(); ca = i; cb = ca; // cls - i = pipe->next(); ca += i; cb += ca; // id - i = pipe->next(); ca += i; cb += ca; // len_lsb - j = pipe->next(); ca += j; cb += ca; // len_msb - j = i + (j << 8); - while (j--) - { - if (++o > l) return WAIT; - i = pipe->next(); - ca += i; - cb += ca; - } - ca &= 0xFF; cb &= 0xFF; - if (++o > l) return WAIT; - if (ca != pipe->next()) return NOT_FOUND; - if (++o > l) return WAIT; - if (cb != pipe->next()) return NOT_FOUND; - return o; -} - -int GPSParser::send(const char* buf, int len) -{ - return _send(buf, len); -} - -void GPSParser::powerOff(void) -{ - // set the gps into backup mode using the command RMX-LPREQ - struct { unsigned long dur; unsigned long flags; } msg = {0/*endless*/,0/*backup*/}; - sendUbx(0x02, 0x41, &msg, sizeof(msg)); -} - -int GPSParser::sendNmea(const char* buf, int len) -{ - char head[1] = { '$' }; - char tail[5] = { '*', 0x00/*crc_high*/, 0x00/*crc_low*/, '\r', '\n' }; - int i; - int crc = 0; - for (i = 0; i < len; i ++) - crc ^= *buf++; - i = _send(head, sizeof(head)); - i += _send(buf, len); - tail[1] = toHex[(crc > 4) & 0xF0]; - tail[2] = toHex[(crc > 0) & 0x0F]; - i += _send(tail, sizeof(tail)); - return i; -} - -int GPSParser::sendUbx(unsigned char cls, unsigned char id, const void* buf /*= NULL*/, int len /*= 0*/) -{ - char head[6] = { 0xB5, 0x62, cls, id, len >> 0, len >> 8 }; - char crc[2]; - int i; - int ca = 0; - int cb = 0; - for (i = 2; i < 6; i ++) - { - ca += head[i]; - cb += ca; - } - for (i = 0; i < len; i ++) - { - ca += ((char*)buf)[i]; - cb += ca; - } - i = _send(head, sizeof(head)); - i += _send(buf, len); - crc[0] = ca & 0xFF; - crc[1] = cb & 0xFF; - i += _send(crc, sizeof(crc)); - return i; -} - -const char* GPSParser::findNmeaItemPos(int ix, const char* start, const char* end) -{ - // find the start - for (; (start < end) && (ix > 0); start ++) - { - if (*start == ',') - ix --; - } - // found and check bounds - if ((ix == 0) && (start < end) && - (*start != ',') && (*start != '*') && (*start != '\r') && (*start != '\n')) - return start; - else - return NULL; -} - -bool GPSParser::getNmeaItem(int ix, char* buf, int len, double& val) -{ - char* end = &buf[len]; - const char* pos = findNmeaItemPos(ix, buf, end); - // find the start - if (!pos) - return false; - val = strtod(pos, &end); - // restore the last character - return (end > pos); -} - -bool GPSParser::getNmeaItem(int ix, char* buf, int len, int& val, int base /*=10*/) -{ - char* end = &buf[len]; - const char* pos = findNmeaItemPos(ix, buf, end); - // find the start - if (!pos) - return false; - val = (int)strtol(pos, &end, base); - return (end > pos); -} - -bool GPSParser::getNmeaItem(int ix, char* buf, int len, char& val) -{ - const char* end = &buf[len]; - const char* pos = findNmeaItemPos(ix, buf, end); - // find the start - if (!pos) - return false; - // skip leading spaces - while ((pos < end) && isspace(*pos)) - pos++; - // check bound - if ((pos < end) && - (*pos != ',') && (*pos != '*') && (*pos != '\r') && (*pos != '\n')) - { - val = *pos; - return true; - } - return false; -} - -bool GPSParser::getNmeaAngle(int ix, char* buf, int len, double& val) -{ - char ch; - if (getNmeaItem(ix,buf,len,val) && getNmeaItem(ix+1,buf,len,ch) && - ((ch == 'S') || (ch == 'N') || (ch == 'E') || (ch == 'W'))) - { - val *= 0.01; - int i = (int)val; - val = (val - i) / 0.6 + i; - if (ch == 'S' || ch == 'W') - val = -val; - return true; - } - return false; -} - -const char GPSParser::toHex[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; - -// ---------------------------------------------------------------- -// Serial Implementation -// ---------------------------------------------------------------- - -GPSSerial::GPSSerial(PinName tx /*= GPSTXD*/, PinName rx /*= GPSRXD*/, int baudrate /*= GPSBAUD*/, - int rxSize /*= 256*/, int txSize /*= 128*/) : - SerialPipe(tx, rx, rxSize, txSize) -{ - baud(baudrate); -} - -int GPSSerial::getMessage(char* buf, int len) -{ - return _getMessage(&_pipeRx, buf, len); -} - -int GPSSerial::_send(const void* buf, int len) -{ - return put((const char*)buf, len, true/*=blocking*/); -} - -// ---------------------------------------------------------------- -// I2C Implementation -// ---------------------------------------------------------------- - -GPSI2C::GPSI2C(PinName sda /*= GPSSDA*/, PinName scl /*= GPSSCL*/, - unsigned char i2cAdr /*=GPSADR*/, int rxSize /*= 256*/) : - I2C(sda,scl), - _pipe(rxSize), - _i2cAdr(i2cAdr) -{ - frequency(100000); - found = false; -} - -bool GPSI2C::detect(void) -{ - if (!found) - { - int w = I2C::write(_i2cAdr,®STREAM,sizeof(REGSTREAM)); - if (w == 0) - found = true; - } - return found; -} - -int GPSI2C::getMessage(char* buf, int len) -{ - // fill the pipe - int sz = _pipe.free(); - if (sz) - sz = _get(buf, sz); - if (sz) - _pipe.put(buf, sz); - // now parse it - return _getMessage(&_pipe, buf, len); -} - -int GPSI2C::send(const char* buf, int len) -{ - int sent = 0; - if (len) - { - if (!I2C::write(_i2cAdr,®STREAM,sizeof(REGSTREAM),true)) - sent = send(buf, len); - found = (len == sent); - stop(); - } - return sent; -} - -int GPSI2C::sendNmea(const char* buf, int len) -{ - int sent = 0; - if (!I2C::write(_i2cAdr,®STREAM,sizeof(REGSTREAM),true)) - sent = GPSParser::sendNmea(buf, len); - found = (len == sent); - stop(); - return sent; -} - -int GPSI2C::sendUbx(unsigned char cls, unsigned char id, const void* buf, int len) -{ - int sent = 0; - if (!I2C::write(_i2cAdr,®STREAM,sizeof(REGSTREAM),true)) - sent = GPSParser::sendUbx(cls, id, buf, len); - found = (len == sent); - I2C::stop(); - return sent; -} - -int GPSI2C::_get(char* buf, int len) -{ - int read = 0; - unsigned char sz[2] = {0,0}; - if (!I2C::write(_i2cAdr,®LEN,sizeof(REGLEN),true) && - !I2C::read(_i2cAdr,(char*)sz,sizeof(sz))) - { - int size = 256 * (int)sz[0] + sz[1]; - if (size > len) - size = len; - if (size > 0) - { - if (!I2C::write(_i2cAdr,®STREAM,sizeof(REGSTREAM),true) && - !I2C::read(_i2cAdr,buf,size)) { - read = size; - } - else - found = false; - } - } - else - found = false; - return read; -} - -int GPSI2C::_send(const void* buf, int len) -{ - return !I2C::write(_i2cAdr,(const char*)buf,len,true) ? len : 0; -} - -const char GPSI2C::REGLEN = 0xFD; -const char GPSI2C::REGSTREAM = 0xFF;
diff -r bc413454a83e -r 002503ab7199 C027_Support/GPS.h --- a/C027_Support/GPS.h Mon Jul 28 15:45:16 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,284 +0,0 @@ -#pragma once - -#include "mbed.h" -#include "Pipe.h" -#include "SerialPipe.h" - -#ifdef TARGET_UBLOX_C027 - // if we detect the C027 platform we will assign the - // default pinname and baudrate in the constructor - // this helper macro will be used. - #define _C027DEFAULT(name) = name -#else - #define _C027DEFAULT(name) -#endif - -/** basic gps parser class -*/ -class GPSParser -{ -public: - enum { - // getLine Responses - WAIT = -1, //!< wait for more incoming data (the start of a message was found, or no data available) - NOT_FOUND = 0, //!< a parser concluded the the current offset of the pipe doe not contain a valid message - - #define LENGTH(x) (x & 0x00FFFF) //!< extract/mask the length - #define PROTOCOL(x) (x & 0xFF0000) //!< extract/mask the type - - UNKNOWN = 0x000000, //!< message type is unknown - UBX = 0x100000, //!< message if of protocol NMEA - NMEA = 0x200000 //!< message if of protocol UBX - }; - - /** Get a line from the physical interface. This fucntion - needs to be implemented in the inherited class. - \param buf the buffer to store it - \param len 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 getMessage(char* buf, int len) = 0; - - /** send a buffer - \param buf the buffer to write - \param len size of the buffer to write - \return bytes written - */ - virtual int send(const char* buf, int len); - - /** send a NMEA message, this function just takes the - payload and calculates and adds checksum. ($ and *XX\r\n will be added) - \param buf the message payload to write - \param len size of the message payload to write - \return total bytes written - */ - virtual int sendNmea(const char* buf, int len); - - /** send a UBX message, this function just takes the - payload and calculates and adds checksum. - \param cls the UBX class id - \param id the UBX message id - \param buf the message payload to write - \param len size of the message payload to write - \return total bytes written - */ - virtual int sendUbx(unsigned char cls, unsigned char id, - const void* buf = NULL, int len = 0); - - /** Power off the gps, it can be again woken up by an - edge on the serial port on the external interrupt pin. - */ - void powerOff(void); - - /** get the first character of a NMEA field - \param ix the index of the field to find - \param start the start of the buffer - \param end the end of the buffer - \return the pointer to the first character of the field. - */ - static const char* findNmeaItemPos(int ix, const char* start, const char* end); - - /** extract a double value from a buffer containing a NMEA message - \param ix the index of the field to extract - \param buf the NMEA message - \param len the size of the NMEA message - \param val the extracted value - \return true if successful, false otherwise - */ - static bool getNmeaItem(int ix, char* buf, int len, double& val); - - /** extract a interger value from a buffer containing a NMEA message - \param ix the index of the field to extract - \param buf the NMEA message - \param len the size of the NMEA message - \param val the extracted value - \param base the numeric base to be used (e.g. 8, 10 or 16) - \return true if successful, false otherwise - */ - static bool getNmeaItem(int ix, char* buf, int len, int& val, int base/*=10*/); - - /** extract a char value from a buffer containing a NMEA message - \param ix the index of the field to extract - \param buf the NMEA message - \param len the size of the NMEA message - \param val the extracted value - \return true if successful, false otherwise - */ - static bool getNmeaItem(int ix, char* buf, int len, char& val); - - /** extract a latitude/longitude value from a buffer containing a NMEA message - \param ix the index of the field to extract (will extract ix and ix + 1) - \param buf the NMEA message - \param len the size of the NMEA message - \param val the extracted latitude or longitude - \return true if successful, false otherwise - */ - static bool getNmeaAngle(int ix, char* buf, int len, double& val); - -protected: - /** Get a line from the physical interface. - \param pipe the receiveing pipe to parse messages - \param buf the buffer to store it - \param len 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 - */ - static int _getMessage(Pipe<char>* pipe, char* buf, int len); - - /** Check if the current offset of the pipe contains a NMEA message. - \param pipe the receiveing pipe to parse messages - \param len numer of bytes to parse at maximum - \return length if something was found (including the NMEA frame) - WAIT if not enough data is available - NOT_FOUND if nothing was found - */ - static int _parseNmea(Pipe<char>* pipe, int len); - - /** Check if the current offset of the pipe contains a UBX message. - \param pipe the receiveing pipe to parse messages - \param len numer of bytes to parse at maximum - \return length if something was found (including the UBX frame) - WAIT if not enough data is available - NOT_FOUND if nothing was found - */ - static int _parseUbx(Pipe<char>* pipe, int len); - - /** Write bytes to the physical interface. This function - needs to be implemented by the inherited class. - \param buf the buffer to write - \param len size of the buffer to write - \return bytes written - */ - virtual int _send(const void* buf, int len) = 0; - - static const char toHex[16]; //!< num to hex conversion -}; - -/** gps class which uses a serial port - as physical interface. -*/ -class GPSSerial : public SerialPipe, public GPSParser -{ -public: - /** Constructor - \param tx is the serial ports transmit pin (gps to CPU) - \param rx is the serial ports receive pin (CPU to gps) - \param baudrate the baudrate of the gps use 9600 - \param rxSize the size of the serial rx buffer - \param txSize the size of the serial tx buffer - */ - GPSSerial(PinName tx _C027DEFAULT( GPSTXD ), - PinName rx _C027DEFAULT( GPSRXD ), - int baudrate _C027DEFAULT( GPSBAUD ), - int rxSize = 256 , - int txSize = 128 ); - - /** Get a line from the physical interface. - \param buf the buffer to store it - \param len 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 getMessage(char* buf, int len); - -protected: - /** Write bytes to the physical interface. - \param buf the buffer to write - \param len size of the buffer to write - \return bytes written - */ - virtual int _send(const void* buf, int len); -}; - -/** gps class which uses a i2c as physical interface. -*/ -class GPSI2C : public I2C, public GPSParser -{ -public: - /** Constructor - \param sda is the I2C SDA pin (between CPU and GPS) - \param scl is the I2C SCL pin (CPU to GPS) - \param adr the I2C address of the GPS set to (66<<1) - \param rxSize the size of the serial rx buffer - */ - GPSI2C(PinName sda _C027DEFAULT( GPSSDA ), - PinName scl _C027DEFAULT( GPSSCL ), - unsigned char i2cAdr _C027DEFAULT( GPSADR ), - int rxSize = 256 ); - - /** helper function to probe the i2c device - \return true if successfully detected the gps. - */ - bool detect(void); - - /** Get a line from the physical interface. - \param buf the buffer to store it - \param len 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 getMessage(char* buf, int len); - - /** send a buffer - \param buf the buffer to write - \param len size of the buffer to write - \return bytes written - */ - virtual int send(const char* buf, int len); - - /** send a NMEA message, this function just takes the - payload and calculates and adds checksum. ($ and *XX\r\n will be added) - \param buf the message payload to write - \param len size of the message payload to write - \return total bytes written - */ - virtual int sendNmea(const char* buf, int len); - - /** send a UBX message, this function just takes the - payload and calculates and adds checksum. - \param cls the UBX class id - \param id the UBX message id - \param buf the message payload to write - \param len size of the message payload to write - \return total bytes written - */ - virtual int sendUbx(unsigned char cls, unsigned char id, - const void* buf = NULL, int len = 0); - -protected: - /** check if the port is writeable (like SerialPipe) - \return true if writeable - */ - bool writeable(void) { return true; } - - /** Write a character (like SerialPipe) - \param c the character to write - \return true if succesffully written - */ - bool putc(int c) { char ch = c; return send(&ch, 1); } - - /** Write bytes to the physical interface. - \param buf the buffer to write - \param len size of the buffer to write - \return bytes written - */ - virtual int _send(const void* buf, int len); - - /** read bytes from the physical interface. - \param buf the buffer to read into - \param len size of the read buffer - \return bytes read - */ - int _get(char* buf, int len); - - Pipe<char> _pipe; //!< the rx pipe - bool found; //!< flag if device is detected. - unsigned char _i2cAdr; //!< the i2c address - static const char REGLEN; //!< the length i2c register address - static const char REGSTREAM;//!< the stream i2c register address -};
diff -r bc413454a83e -r 002503ab7199 C027_Support/MDM.cpp --- a/C027_Support/MDM.cpp Mon Jul 28 15:45:16 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1260 +0,0 @@ -#include "mbed.h" -#include <ctype.h> -#include <string.h> -#include "MDM.h" - -#define TRACE (1/*1=off,0=trace*/)?:printf -#define DEBUG // enable this for AT command debugging -#define PROFILE "0" // this is the psd profile used -// some helper -#define ISSOCKET(s) (((s) >= 0) && ((s) < (sizeof(_sockets)/sizeof(*_sockets)))) -#define WAIT_MS(ms) wait_ms(ms) // you may choose to use Thread::wait(ms) - -#define MAX_SIZE 128 // max expected messages - -#ifdef DEBUG -void dump(const char* buf, int len) -{ - while (len --) { - char ch = *buf++; - if (ch == '\r') printf("\\r"); - else if (ch == '\n') printf("\\n"); - else if (ch >= 0x20) printf("%c", ch); - else printf("\\x%02x", ch); - } -} - -Timer dbgTime; - - #if 1 // colored terminal output using ANSI escape sequences - #define COL(c,t) "\33[" c t "\33[" "39m" - #else - #define COL(c,t) t - #endif - #define BLA(t) COL("30m",t) - #define RED(t) COL("31m",t) - #define GRE(t) COL("32m",t) - #define YEL(t) COL("33m",t) - #define BLU(t) COL("34m",t) - #define MAG(t) COL("35m",t) - #define CYA(t) COL("36m",t) - #define WHY(t) COL("37m",t) -#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; - memset(_sockets, 0, sizeof(_sockets)); -#ifdef DEBUG - dbgTime.start(); -#endif -} - -int MDMParser::send(const char* buf, int len) -{ -#ifdef DEBUG - printf("%10.3f ", dbgTime.read_ms()*0.001); - printf("AT send %4d \"", len); - dump(buf,len); - printf("\"\r\n"); -#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 DEBUG - if ((ret != WAIT) && (ret != NOT_FOUND)) - { - int len = LENGTH(ret); - int type = TYPE(ret); - const char* s = (type == TYPE_UNKNOWN)? YEL("UNK") : - (type == TYPE_TEXT) ? MAG("TXT") : - (type == TYPE_OK ) ? GRE("OK ") : - (type == TYPE_ERROR) ? RED("ERR") : - (type == TYPE_PLUS) ? CYA(" + ") : - (type == TYPE_PROMPT) ? BLU(" > ") : - "..." ; - printf("%10.3f ", dbgTime.read_ms()*0.001); - printf("AT read %s %3d \"", s, len); - dump(buf, len); - printf("\"\r\n"); - } -#endif - if ((ret != WAIT) && (ret != NOT_FOUND)) - { - int type = TYPE(ret); - if (type == TYPE_OK) return RESP_OK; - if (type == TYPE_ERROR) return RESP_ERROR; - if (type == TYPE_PROMPT) return RESP_PROMPT; - // 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) && - ISSOCKET(a) /*&& (_sockets[a].state == SOCK_CONNECTED)*/) { - TRACE("Socket %d: %d bytes pending\r\n", a, b); - _sockets[a].pending = b; - // +UUSORF: <socket>,<length> - } else if ((sscanf(cmd, "UUSORF: %d,%d", &a, &b) == 2) && - ISSOCKET(a) /*&& (_sockets[a].state == SOCK_CONNECTED)*/) { - TRACE("Socket %d: %d bytes pending\r\n", a, b); - _sockets[a].pending = b; - // +UUSOCL: <socket> - } else if ((sscanf(cmd, "UUSOCL: %d", &a) == 1) && - ISSOCKET(a) && (_sockets[a].state == SOCK_CONNECTED)) { - TRACE("Socket %d: closed by remote host\r\n", a); - _sockets[a].state = SOCK_CREATED/*=CLOSED*/; - } - 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.reg = REG_NONE; // not registered, home network - else if (c == 1) _net.reg = REG_HOME; // registered, home network - else if (c == 2) _net.reg = REG_NONE; // not registered, but MT is currently searching a new operator to register to - else if (c == 3) _net.reg = REG_DENIED; // registration denied - else if (c == 5) _net.reg = REG_ROAMING; // registered, roaming - _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 ------------------------------------------- - // +CREG: <n>, <stat>[,<lac>,<ci>[,AcT]] - b = 255; - r = sscanf(cmd, "CREG: %*d,%d,\"%X\",\"%X\",%d",&a,&b,&c,&d); - if (r >= 1) { - // network status - if (a == 0) _net.reg = REG_NONE; // 0: not registered, home network - else if (a == 1) _net.reg = REG_HOME; // 1: registered, home network - else if (a == 2) _net.reg = REG_NONE; // 2: not registered, but MT is currently searching a new operator to register to - else if (a == 3) _net.reg = REG_DENIED; // 3: registration denied - else if (a == 4) _net.reg = REG_UNKNOWN; // 4: unknown - else if (a == 5) _net.reg = REG_ROAMING; // 5: registered, roaming - if ((r >= 2) && (b != 0xFFFF)) _net.lac = b; // location area code - if ((r >= 3) && (c != 0xFFFFFFFF)) _net.ci = c; // cell ID - // access technology - if (r >= 4) { - 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 - } - - // +UUPSDD: <profile_id> - } else if (sscanf(cmd, "UUPSDD: %d",&a) == 1) { - if (*PROFILE == a) _ip = NOIP; - } - } - } - if (cb) { - int len = LENGTH(ret); - int ret = cb(type, buf, len, param); - if (WAIT != ret) - return ret; - } - } - // relax a bit - WAIT_MS(10); - } - while ((timeout_ms == TIMEOUT_BLOCKING) || - (timer.read_ms() < timeout_ms)); - timer.stop(); - timer.reset(); - 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, - bool dump) -{ - DevStatus devStatus = {}; - WAIT_MS(2000); - bool mdmOk = init(simpin, &devStatus); - if (dump) dumpDevStatus(&devStatus); - if (!mdmOk) - return false; - // wait until we are connected - int i = 60; - NetStatus netStatus = {}; - while (!checkNetStatus(&netStatus)) - { - if ((netStatus.reg == REG_DENIED) || (i == 0)) - break;; - i --; - WAIT_MS(1000); - } - if (dump) dumpNetStatus(&netStatus); - if ((netStatus.reg == REG_DENIED) || (i == 0)) - return false; - IP ip = join(apn,username,password); - if (dump) dumpIp(ip); - if (ip == NOIP) - return false; - return true; -} - -bool MDMParser::init(const char* simpin, DevStatus* status) -{ - int i = 5; - // we should wait some time before - while (i--) { - // check interface and disable local echo - sendFormated("AT\r\n"); - if(RESP_OK == waitFinalResp(NULL,NULL,1000)) - break; - } - if (i < 0) - return false; - // echo off - sendFormated("AT E0\r\n"); - if(RESP_OK != waitFinalResp()) - return false; - // enable verbose error messages - sendFormated("AT+CMEE=2\r\n"); - if(RESP_OK != waitFinalResp()) - return false; - // set baud rate - sendFormated("AT+IPR=115200\r\n"); - if (RESP_OK != waitFinalResp()) - return false; - WAIT_MS(40); - // identify the module - sendFormated("ATI\r\n"); - if (RESP_OK != waitFinalResp(_cbATI, &_dev.dev)) - return false; - if (_dev.dev == DEV_UNKNOWN) - return false; - // device specific init - if (_dev.dev == DEV_LISA_C200) { - // get the manufacturer - sendFormated("AT+GMI\r\n"); - if (RESP_OK != waitFinalResp(_cbString, _dev.manu)) - return false; - // get the model identification - sendFormated("AT+GMM\r\n"); - if (RESP_OK != waitFinalResp(_cbString, _dev.model)) - return false; - // get the sw version - sendFormated("AT+GMR\r\n"); - if (RESP_OK != waitFinalResp(_cbString, _dev.ver)) - return false; - // Return the pseudo ESN or MEID - sendFormated("AT+GSN\r\n"); - if (RESP_OK != waitFinalResp(_cbString, _dev.meid)) - return false; -#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()) - return false; - _dev.lpm = LPM_ACTIVE; - } -#endif - } else { - if (_dev.dev == DEV_LISA_U200) { - // enable the network identification feature - sendFormated("AT+UGPIOC=20,2\r\n"); - if (RESP_OK != waitFinalResp()) - return false; - } else { - // enable the network identification feature - sendFormated("AT+UGPIOC=16,2\r\n"); - if (RESP_OK != waitFinalResp()) - return false; - } - // 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)) - return false; - // Enter PIN if needed - if (_dev.sim == SIM_PIN) { - if (!simpin) { - TRACE("SIM PIN not available\r\n"); - return false; - } - sendFormated("AT+CPIN=%s\r\n", simpin); - if (RESP_OK != waitFinalResp(_cbCPIN, &_dev.sim)) - return false; - } else if (_dev.sim != SIM_READY) { - WAIT_MS(1000); - } - } - if (_dev.sim != SIM_READY) - return false; - // get the manufacturer - sendFormated("AT+CGMI\r\n"); - if (RESP_OK != waitFinalResp(_cbString, _dev.manu)) - return false; - // get the model identification - sendFormated("AT+CGMM\r\n"); - if (RESP_OK != waitFinalResp(_cbString, _dev.model)) - return false; - // get the - sendFormated("AT+CGMR\r\n"); - if (RESP_OK != waitFinalResp(_cbString, _dev.ver)) - return false; - // 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)) - return false; - // Returns the product serial number, IMEI (International Mobile Equipment Identity) - sendFormated("AT+CGSN\r\n"); - if (RESP_OK != waitFinalResp(_cbString, _dev.imei)) - return false; -#if 0 - // Configure New message indication - sendFormated("AT+CNMI=2,1,0,0,0\r\n"); - if (RESP_OK != waitFinalResp()) - return false; -#endif - // 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()) - return false; - _dev.lpm = LPM_ACTIVE; - } - } - // Setup SMS in text mode - sendFormated("AT+CMGF=1\r\n"); - if (RESP_OK != waitFinalResp()) - return false; - // setup new message indication - sendFormated("AT+CNMI=1,1\r\n"); - if (RESP_OK != waitFinalResp()) - return false; - // Request IMSI (International Mobile Subscriber Identification) - sendFormated("AT+CIMI\r\n"); - if (RESP_OK != waitFinalResp(_cbString, _dev.imsi)) - return false; - if (status) - memcpy(status, &_dev, sizeof(DevStatus)); - return true; -} - -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; - /*TRACE("Identified Device: SARA-G350 2G\\n")*/; - } else if (strstr(buf, "LISA-U200")) { - *dev = DEV_LISA_U200; - /*TRACE("Identified Device: LISA-U200 2G/3G\r\n")*/; - } else if (strstr(buf, "LISA-C200")) { - *dev= DEV_LISA_C200; - /*TRACE("Identified Device: LISA-C200 CDMA\r\n")*/; - } - } - return WAIT; -} - -int MDMParser::_cbCPIN(int type, const char* buf, int len, Sim* sim) -{ - if ((type == TYPE_PLUS) && sim){ - char s[16]; - if (sscanf(buf, "\r\n+CPIN: %[^\r]\r<n", s) >= 1) { - *sim = (strcmp("READY", s) == 0) ? SIM_READY : SIM_PIN; - } - } - 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::checkNetStatus(NetStatus* status /*= NULL*/) -{ - // enable the network registration unsolicited result code -// sendFormated("AT+CREG=%d\r\n", (_dev.dev == DEV_LISA_C200) ? 1 : 2); - sendFormated("AT+CGREG=%d\r\n", 2); - if (RESP_OK != waitFinalResp()) - return false; - // check registration -// sendFormated("AT+CREG?\r\n"); - sendFormated("AT+CGREG?\r\n"); - if (RESP_OK != waitFinalResp()) - return false; - if ((_net.reg != REG_ROAMING) && (_net.reg != REG_HOME)) - return false; - // check modem specific status messages - if (_dev.dev == DEV_LISA_C200) { - sendFormated("AT+CSS?\r\n"); - if (RESP_OK != waitFinalResp()) - return false; - // get the Telephone number - sendFormated("AT$MDN?\r\n"); - if (RESP_OK != waitFinalResp(_cbString, _net.num)) - return false; - // check if we have a Mobile Directory Number - if (memcmp(_net.num, "0000", 4) == 0) - return false; - // get the the Network access identifier string - char nai[64]; - sendFormated("AT$QCMIPNAI?\r\n"); - if (RESP_OK != waitFinalResp(_cbString, nai)) - return false; - } else { - // check GPRS attach status - int state = 0; - sendFormated("AT+CGATT?\r\n"); - if (RESP_OK != waitFinalResp(_cbCGATT, &state, 3*60*1000)) - return false; - if (state != 1) - return false; - // check operator selection - sendFormated("AT+COPS?\r\n"); - if (RESP_OK != waitFinalResp(_cbCOPS, &_net, 3*60*1000)) - return false; - // Returns the MSISDNs related to this subscriber - sendFormated("AT+CNUM\r\n"); - if (RESP_OK != waitFinalResp(_cbCNUM, _net.num)) - return false; - } - // Returns the signal strength indication - sendFormated("AT+CSQ\r\n"); - if (RESP_OK != waitFinalResp(_cbCSQ, &_net)) - return false; - if (status) { - memcpy(status, &_net, sizeof(NetStatus)); - } - return true; -} - -int MDMParser::_cbCGATT(int type, const char* buf, int len, int* state) -{ - if ((type == TYPE_PLUS) && state){ - if (sscanf(buf, "\r\n+CGATT: %d\r\n", state) == 1) - /*TRACE("Got CGATT: %d\r\n", state)*/; - } - return WAIT; -} - -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; -} -bool MDMParser::powerOff(void) -{ - sendFormated("AT+CPWROFF\r\n"); - if (RESP_OK != waitFinalResp(NULL,NULL,120)) - return false; - return true; -} - -// ---------------------------------------------------------------- -// internet connection - -MDMParser::IP MDMParser::join(const char* apn /*= NULL*/, const char* username /*= NULL*/, const char* password /*= NULL*/) -{ - _ip = NOIP; - if (_dev.dev == DEV_LISA_C200) { - // TODO: is there something to do here? -#if 0 - //Get local IP address - sendFormated("AT+CMIP?\r\n"); - if (RESP_OK != waitFinalResp(_cbCMIP, &_ip)) - return NOIP; -#else - return 0x01010101; // a fake IP -#endif - } else { - // check gprs attach status - sendFormated("AT+CGATT?\r\n"); - if (RESP_OK != waitFinalResp()) - return NOIP; - - // Check the profile - int a = 0; - sendFormated("AT+UPSND=" PROFILE ",8\r\n"); - if (RESP_OK != waitFinalResp(_cbUPSND, &a)) - return NOIP; - if (a == 1) { - // disconnect the profile already if it is connected - sendFormated("AT+UPSDA=" PROFILE ",4\r\n"); - if (RESP_OK != waitFinalResp(NULL,NULL,40*1000)) - return NOIP;; - } - // Set up the APN - if (apn) { - sendFormated("AT+UPSD=" PROFILE ",1,\"%s\"\r\n", apn); - if (RESP_OK != waitFinalResp()) - return NOIP; - } - if (username) { - sendFormated("AT+UPSD=" PROFILE ",2,\"%s\"\r\n", username); - if (RESP_OK != waitFinalResp()) - return NOIP; - } - if (password) { - sendFormated("AT+UPSD=" PROFILE ",3,\"%s\"\r\n", password); - if (RESP_OK != waitFinalResp()) - return NOIP; - } - // Set up the dynamic IP address assignment. - sendFormated("AT+UPSD=" PROFILE ",7,\"0.0.0.0\"\r\n"); - if (RESP_OK != waitFinalResp()) - return NOIP; - // Activate the profile and make connection - sendFormated("AT+UPSDA=" PROFILE ",3\r\n"); - if (RESP_OK != waitFinalResp(NULL,NULL,150*1000)) - return NOIP; - //Get local IP address - sendFormated("AT+UPSND=" PROFILE ",0\r\n"); - if (RESP_OK != waitFinalResp(_cbUPSND, &_ip)) - return NOIP; - } - return _ip; -} - -int MDMParser::_cbCMIP(int type, const char* buf, int len, IP* ip) -{ - if ((type == TYPE_PLUS) && ip) { - int a,b,c,d; - if (sscanf(buf, "\r\n+CMIP: " 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) -{ - if (_ip == NOIP) - return true; - if (_dev.dev == DEV_LISA_C200) { - // TODO: is there something to do here? - } else { - sendFormated("AT+UPSDA=" PROFILE ",4\r\n"); - if (RESP_OK != waitFinalResp()) - return false; - } - _ip = NOIP; - return true; -} - -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 { - sendFormated("AT+UDNSRN=0,\"%s\"\r\n", host); - if (RESP_OK != waitFinalResp(_cbUDNSRN, &ip)) - return false; - } - return ip; -} - -// ---------------------------------------------------------------- -// sockets - -int MDMParser::_cbUSOCR(int type, const char* buf, int len, int* socket) -{ - if ((type == TYPE_PLUS) && socket) { - const char* p = strstr(buf,"+USOCR: "); - if (p) - *socket = atoi(p+8); - } - return WAIT; -} - -int MDMParser::socketSocket(IpProtocol ipproto, int port) -{ - TRACE("socketSocket(%d)\r\n", ipproto); - if(ipproto == IPPROTO_TCP) { - sendFormated("AT+USOCR=6\r\n"); - } else if ((ipproto == IPPROTO_UDP) && (port == -1)){ - sendFormated("AT+USOCR=17\r\n"); - } else if (ipproto == IPPROTO_UDP){ - sendFormated("AT+USOCR=17,%d\r\n", port); - } else { // other types not supported - return SOCKET_ERROR; - } - int socket = -1; - if (RESP_OK != waitFinalResp(_cbUSOCR, &socket)) - return SOCKET_ERROR; - if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_FREE)) - return SOCKET_ERROR; - // successfull - _sockets[socket].state = SOCK_CREATED; - _sockets[socket].pending = 0; - _sockets[socket].timeout_ms = TIMEOUT_BLOCKING; - return socket; -} - -bool MDMParser::socketConnect(int socket, const char * host, int port) -{ - TRACE("socketConnect(%d,%s,%d)\r\n", socket, host,port); - IP ip = gethostbyname(host); - if (ip == NOIP) - return false; - // connect to socket - if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CREATED)) - return false; - sendFormated("AT+USOCO=%d,\"" IPSTR "\",%d\r\n", socket, IPNUM(ip), port); - if (RESP_OK != waitFinalResp()) - return false; - _sockets[socket].state = SOCK_CONNECTED; - return true; -} - -bool MDMParser::socketIsConnected(int socket) -{ - TRACE("socketIsConnected(%d)\r\n", socket); - if (!ISSOCKET(socket)) - return false; - TRACE(" ... %d\r\n", _sockets[socket].state); - return _sockets[socket].state == SOCK_CONNECTED; -} - -bool MDMParser::socketSetBlocking(int socket, int timeout_ms) -{ - TRACE("socketSetBlocking(%d,%d)\r\n", socket, timeout_ms); - if (!ISSOCKET(socket)) - return false; - _sockets[socket].timeout_ms = timeout_ms; - return true; -} - -bool MDMParser::socketClose(int socket) -{ - TRACE("socketClose(%d)\r\n", socket); - if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CONNECTED)) - return false; - sendFormated("AT+USOCL=%d\r\n", socket); - if (RESP_OK != waitFinalResp()) - return false; - _sockets[socket].state = SOCK_CREATED; - return true; -} - -bool MDMParser::socketFree(int socket) -{ - TRACE("socketFree(%d)\r\n", socket); - socketClose(socket); - if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CREATED)) - return false; - _sockets[socket].state = SOCK_FREE; - return true; -} - -#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; - sendFormated("AT+USOWR=%d,%d\r\n",socket,blk); - if (RESP_PROMPT != waitFinalResp()) - return SOCKET_ERROR; - WAIT_MS(50); - send(buf, blk); - if (RESP_OK != waitFinalResp()) - 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; - sendFormated("AT+USOST=%d,\"" IPSTR "\",%d,%d\r\n",socket,IPNUM(ip),port,blk); - if (RESP_PROMPT != waitFinalResp()) - return SOCKET_ERROR; - WAIT_MS(50); - send(buf, blk); - if (RESP_OK != waitFinalResp()) - return SOCKET_ERROR; - buf += blk; - cnt -= blk; - } - return (len - cnt); -} - -int MDMParser::socketReadable(int socket) -{ - TRACE("socketReadable(%d)\r\n", socket); - if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CONNECTED)) - return SOCKET_ERROR; - // allow to receive unsolicited commands - waitFinalResp(NULL, NULL, 0); - if (_sockets[socket].state != SOCK_CONNECTED) - return SOCKET_ERROR; - return _sockets[socket].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); - if (!ISSOCKET(socket)) - return SOCKET_ERROR; - memset(buf, '\0', len); - Timer timer; - timer.start(); - while (len) { - int blk = MAX_SIZE; // still need space for headers and unsolicited commands - if (_sockets[socket].pending < blk) - blk = _sockets[socket].pending; - if (len < blk) blk = len; - if (blk) { - sendFormated("AT+USORD=%d,%d\r\n",socket, blk); - if (RESP_OK != waitFinalResp(_cbUSORD, buf)) { - return SOCKET_ERROR; - } - len -= blk; - cnt += blk; - buf += blk; - _sockets[socket].pending -= blk; - } else if ((_sockets[socket].state == SOCK_CONNECTED) && ( - (_sockets[socket].timeout_ms == TIMEOUT_BLOCKING) || - (timer.read_ms() < _sockets[socket].timeout_ms))){ - // allow to receive unsolicited commands - waitFinalResp(NULL, NULL, 10); - } else { - len = 0; // no more data and socket closed or timed-out - } - } - - timer.stop(); - timer.reset(); - 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; - if ((sscanf(buf, "\r\n+USORF: %d,\""IPSTR"\",%d,%d,", - &sk,&a,&b,&c,&d,&p,&sz) == 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); - if (!ISSOCKET(socket)) - return SOCKET_ERROR; - memset(buf, '\0', len); - Timer timer; - timer.start(); - while (len) { - int blk = MAX_SIZE; // still need space for headers and unsolicited commands - if (_sockets[socket].pending < blk) - blk = _sockets[socket].pending; - if (len < blk) blk = len; - if (blk) { - sendFormated("AT+USORF=%d,%d\r\n",socket, blk); - USORFparam param; - param.buf = buf; - if (RESP_OK != waitFinalResp(_cbUSORF, ¶m)) { - return SOCKET_ERROR; - } - *ip = param.ip; - *port = param.port; - len -= blk; - cnt += blk; - buf += blk; - _sockets[socket].pending -= blk; - } else if ((_sockets[socket].timeout_ms == TIMEOUT_BLOCKING) || - (timer.read_ms() < _sockets[socket].timeout_ms)) { - // allow to receive unsolicited commands - waitFinalResp(NULL, NULL, 10); - } else { - len = 0; // no more data and socket closed or timed-out - } - } - timer.stop(); - timer.reset(); - return cnt; -} - -// ---------------------------------------------------------------- - -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*/) { - sendFormated("AT+CMGL=\"%s\"\r\n", stat); - CMGLparam param; - param.ix = ix; - param.num = num; - if (RESP_OK != waitFinalResp(_cbCMGL, ¶m)) - return -1; - return num - param.num; -} - -bool MDMParser::smsSend(const char* num, const char* buf) -{ - sendFormated("AT+CMGS=\"%s\"\r",num); - if (RESP_PROMPT != waitFinalResp(NULL,NULL,150*1000)) { - return false; - } - send(buf, strlen(buf)); - const char ctrlZ = 0x1A; - send(&ctrlZ, sizeof(ctrlZ)); - if (RESP_OK != waitFinalResp()) { - return false; - } - return true; -} - -bool MDMParser::smsDelete(int ix) -{ - sendFormated("AT+CMGD=%d\r\n",ix); - if (RESP_OK != waitFinalResp()) { - return false; - } - return true; -} - -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) -{ - CMGRparam param; - param.num = num; - param.buf = buf; - sendFormated("AT+CMGR=%d\r\n",ix); - if (RESP_OK != waitFinalResp(_cbCMGR, ¶m)) { - return false; - } - return true; -} - -// ---------------------------------------------------------------- - -void MDMParser::dumpDevStatus(MDMParser::DevStatus* status) -{ - printf("Modem Device Status:\r\n"); - const char* txtDev[] = { "Unknown", "SARA-G350", "LISA-U200", "LISA-C200" }; - if (status->dev < sizeof(txtDev)/sizeof(*txtDev) && (status->dev != MDMParser::DEV_UNKNOWN)) - printf(" Device: %s\r\n", txtDev[status->dev]); - const char* txtLpm[] = { "Disabled", "Enabled", "Active" }; - if (status->lpm < sizeof(txtLpm)/sizeof(*txtLpm)) - printf(" Power Save: %s\r\n", txtLpm[status->lpm]); - const char* txtSim[] = { "Unknown", "Pin", "Ready" }; - if (status->sim < sizeof(txtSim)/sizeof(*txtSim) && (status->sim != MDMParser::SIM_UNKNOWN)) - printf(" SIM: %s\r\n", txtSim[status->sim]); - if (*status->ccid) - printf(" CCID: %s\r\n", status->ccid); - if (*status->imei) - printf(" IMEI: %s\r\n", status->imei); - if (*status->imsi) - printf(" IMSI: %s\r\n", status->imsi); - if (*status->meid) - printf(" MEID: %s\r\n", status->meid); // LISA-C - if (*status->manu) - printf(" Manufacturer: %s\r\n", status->manu); - if (*status->model) - printf(" Model: %s\r\n", status->model); - if (*status->ver) - printf(" Version: %s\r\n", status->ver); -} - -void MDMParser::dumpNetStatus(MDMParser::NetStatus *status) -{ - printf("Modem Network Status:\r\n"); - const char* txtReg[] = { "Unknown", "Denied", "None", "Home", "Roaming" }; - if (status->reg < sizeof(txtReg)/sizeof(*txtReg) && (status->reg != MDMParser::REG_UNKNOWN)) - printf(" Registration: %s\r\n", txtReg[status->reg]); - const char* txtAct[] = { "Unknown", "GSM", "Edge", "3G", "CDMA" }; - if (status->act < sizeof(txtAct)/sizeof(*txtAct) && (status->act != MDMParser::ACT_UNKNOWN)) - printf(" Access Technology: %s\r\n", txtAct[status->act]); - if (status->rssi) - printf(" Signal Strength: %d dBm\r\n", status->rssi); - if (status->ber) - printf(" Bit Error Rate: %d\r\n", status->ber); - if (*status->opr) - printf(" Operator: %s\r\n", status->opr); - if (status->lac != 0xFFFF) - printf(" Location Area Code: %04X\r\n", status->lac); - if (status->ci != 0xFFFFFFFF) - printf(" Cell ID: %08X\r\n", status->ci); - if (*status->num) - printf(" Phone Number: %s\r\n", status->num); -} - -void MDMParser::dumpIp(MDMParser::IP ip) -{ - if (ip != NOIP) - printf("Modem IP Address: " IPSTR "\r\n", IPNUM(ip)); -} - -// ---------------------------------------------------------------- - -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) -{ - *buf = '\0'; - sendFormated("AT+CUSD=1,\"%s\"\r\n",cmd); - if (RESP_OK != waitFinalResp(_cbCUSD, buf)) { - return false; - } - return true; -} - -// ---------------------------------------------------------------- -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(); - } - } - } - 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 }, - }; - 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 - }; - 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 -// ---------------------------------------------------------------- - -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) -{ - 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 -} - -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 -// TODO properly implement with USB -MDMUsb::MDMUsb(void) { } -int MDMUsb::_send(const void* buf, int len) { return len; } -int MDMUsb::getLine(char* buffer, int length) { return NOT_FOUND; } -#endif
diff -r bc413454a83e -r 002503ab7199 C027_Support/MDM.h --- a/C027_Support/MDM.h Mon Jul 28 15:45:16 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,530 +0,0 @@ -#pragma once - -#include "mbed.h" -#include <stdarg.h> - -#include "Pipe.h" -#include "SerialPipe.h" - -#ifdef TARGET_UBLOX_C027 - // if we detect the C027 platform we will assign the - // default pinname and baudrate in the constructor - // this helper macro will be used. - #define _C027DEFAULT(name) = name -#else - #define _C027DEFAULT(name) -#endif - -/** basic modem parser class -*/ -class MDMParser -{ -public: - //! Constructor - MDMParser(); - //! 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; - //! SIM Status - typedef enum { SIM_UNKNOWN, SIM_PIN, SIM_READY } Sim; - //! SIM Status - typedef enum { LPM_DISABLED, LPM_ENABLED, LPM_ACTIVE, LPM_SLEEP } 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 reg; //!< Registration Status - 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 - // ---------------------------------------------------------------- - - /** 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 dump set to true if you like to dump the status if successful - \return true if successful, false otherwise - */ - bool connect(const char* simpin, - const char* apn, const char* username, const char* password, - bool dump); - - /** 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); - - /** 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 dump set to true if you like to dump the status if successful - \return the ip that is assigned - */ - MDMParser::IP join(const char* apn = NULL, const char* username = NULL, const char* password = NULL); - - /** 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); - - // ---------------------------------------------------------------- - // DUMP status to standard out (printf) - // ---------------------------------------------------------------- - - /** dump the device status to stdout using printf - \param status the status to convert to textual form, - unavailable fields are ommited (not printed) - */ - static void 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) - */ - static void 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) - */ - static void 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; - - /** 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> - 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: - // 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 _cbCGATT(int type, const char* buf, int len, int* state); - // 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* socket); - 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); - // variables - DevStatus _dev; //!< collected device information - NetStatus _net; //!< collected network information - IP _ip; //!< assigned ip address - // management struture for sockets - typedef enum { SOCK_FREE, SOCK_CREATED, SOCK_CONNECTED } SockState; - typedef struct { SockState state; int pending; int timeout_ms; } SockCtrl; - // LISA-C has 6 TCP and 6 UDP sockets starting at index 18 - // LISA-U and SARA-G have 7 sockets starting at index 1 - SockCtrl _sockets[32]; - static MDMParser* inst; -}; - -// ----------------------------------------------------------------------- - -/** 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 _C027DEFAULT(MDMTXD), - PinName rx _C027DEFAULT(MDMRXD), - int baudrate _C027DEFAULT(MDMBAUD), - #if DEVICE_SERIAL_FC - PinName rts _C027DEFAULT(MDMRTS), - PinName cts _C027DEFAULT(MDMCTS), - #endif - int rxSize = 256 , - int txSize = 128 ); - /** 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); -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: - MDMUsb(void); - virtual int getLine(char* buffer, int length); -protected: - virtual int _send(const void* buf, int len); -}; -#endif - -
diff -r bc413454a83e -r 002503ab7199 C027_Support/Pipe.h --- a/C027_Support/Pipe.h Mon Jul 28 15:45:16 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,240 +0,0 @@ -#pragma once - -/** pipe, this class implements a buffered pipe that can be savely - written and read between two context. E.g. Written from a task - and read from a interrupt. -*/ -template <class T> -class Pipe -{ -public: - /* Constructor - \param n size of the pipe/buffer - \param b optional buffer that should be used. - if NULL the constructor will allocate a buffer of size n. - */ - Pipe(int n, T* b = NULL) - { - _a = b ? NULL : new T[n]; - _r = 0; - _w = 0; - _b = b ? b : _a; - _s = n; - } - /** Destructor - frees a allocated buffer. - */ - ~Pipe(void) - { - if (_a) - delete [] _a; - } - - /* This function can be used during debugging to hexdump the - content of a buffer to the stdout. - */ - void dump(void) - { - int o = _r; - printf("pipe: %d/%d ", size(), _s); - while (o != _w) { - T t = _b[o]; - printf("%0*X", sizeof(T)*2, t); - o = _inc(o); - } - printf("\n"); - } - - // writing thread/context API - //------------------------------------------------------------- - - /** Check if buffer is writeable (=not full) - \return true if writeable - */ - bool writeable(void) - { - return free() > 0; - } - - /** Return the number of free elements in the buffer - \return the number of free elements - */ - int free(void) - { - int s = _r - _w; - if (s <= 0) - s += _s; - return s - 1; - } - - /* Add a single element to the buffer. (blocking) - \param c the element to add. - \return c - */ - T putc(T c) - { - int i = _w; - int j = i; - i = _inc(i); - while (i == _r) // = !writeable() - /*wait for space*/; - _b[j] = c; - _w = i; - return c; - } - - /* Add a buffer of elements to the buffer. - \param p the elements to add - \param n the number elements to add from p - \param t set to true if blocking, false otherwise - \return number elements added - */ - int put(const T* p, int n, bool t = false) - { - int c = n; - while (c) - { - int f; - for (;;) // wait for space - { - f = free(); - if (f) break; // data avail - if (!t) return n - c; // no more space and not blocking - } - // check free space - if (c < f) f = c; - int w = _w; - int m = _s - w; - // check wrap - if (f > m) f = m; - memcpy(&_b[w], p, f); - _w = _inc(w, f); - c -= f; - p += f; - } - return n - c; - } - - // reading thread/context API - // -------------------------------------------------------- - - /** Check if there are any emelemnt available (readble / not empty) - \return true if readable/not empty - */ - bool readable(void) - { - return (_r != _w); - } - - /** Get the number of values available in the buffer - return the number of element available - */ - int size(void) - { - int s = _w - _r; - if (s < 0) - s += _s; - return s; - } - - /** get a single value from buffered pipe (this function will block if no values available) - \return the element extracted - */ - T getc(void) - { - int r = _r; - while (r == _w) // = !readable() - /*wait for data*/; - T t = _b[r]; - _r = _inc(r); - return t; - } - - /*! get elements from the buffered pipe - \param p the elements extracted - \param n the maximum number elements to extract - \param t set to true if blocking, false otherwise - \return number elements extracted - */ - int get(T* p, int n, bool t = false) - { - int c = n; - while (c) - { - int f; - for (;;) // wait for data - { - f = size(); - if (f) break; // free space - if (!t) return n - c; // no space and not blocking - } - // check available data - if (c < f) f = c; - int r = _r; - int m = _s - r; - // check wrap - if (f > m) f = m; - memcpy(p, &_b[r], f); - _r = _inc(r, f); - c -= f; - p += f; - } - return n - c; - } - - // the following functions are useful if you like to inspect - // or parse the buffer in the reading thread/context - // -------------------------------------------------------- - - /** set the parsing index and return the number of available - elments starting this position. - \param ix the index to set. - \return the number of elements starting at this position - */ - int set(int ix) - { - int sz = size(); - ix = (ix > sz) ? sz : ix; - _o = _inc(_r, ix); - return sz - ix; - } - - /** get the next element from parsing position and increment parsing index - \return the extracted element. - */ - T next(void) - { - int o = _o; - T t = _b[o]; - _o = _inc(o); - return t; - } - - /** commit the index, mrk the current parsing index as consumed data. - */ - void done(void) - { - _r = _o; - } - -private: - /** increment the index - \param i index to increment - \param n the step to increment - \return the incremented index. - */ - inline int _inc(int i, int n = 1) - { - i += n; - if (i >= _s) - i -= _s; - return i; - } - - T* _b; //!< buffer - T* _a; //!< allocated buffer - int _s; //!< size of buffer (s - 1) elements can be stored - volatile int _w; //!< write index - volatile int _r; //!< read index - int _o; //!< offest index used by parsing functions -};
diff -r bc413454a83e -r 002503ab7199 C027_Support/SerialPipe.cpp --- a/C027_Support/SerialPipe.cpp Mon Jul 28 15:45:16 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +0,0 @@ -#pragma once - -#include "SerialPipe.h" - -SerialPipe::SerialPipe(PinName tx, PinName rx, int rxSize, int txSize) - : _SerialPipeBase(tx,rx), _pipeRx(rxSize), _pipeTx(txSize) -{ - attach(this, &SerialPipe::rxIrqBuf, RxIrq); -#if defined(TARGET_UBLOX_C027) || defined(TARGET_LPC1768) - // the lpc1768 supports interrupt driven tx - attach(this, &SerialPipe::txIrqBuf, TxIrq); -#endif -} - -SerialPipe::~SerialPipe(void) -{ - attach(NULL, RxIrq); -#if defined(TARGET_UBLOX_C027) || defined(TARGET_LPC1768) - attach(NULL, TxIrq); -#endif -} - -// tx channel -int SerialPipe::writeable(void) -{ - return _pipeTx.free(); -} - -int SerialPipe::putc(int c) -{ - c = _pipeTx.putc(c); - txStart(); - return c; -} - -int SerialPipe::put(const void* buffer, int length, bool blocking) -{ - int count = length; - const char* ptr = (const char*)buffer; - if (count) - { - do - { - int written = _pipeTx.put(ptr, count, false); - ptr += written; - count -= written; - txStart(); - } - while (count && blocking); - } - return (length - count); -} - -void SerialPipe::txIrqBuf(void) -{ - while (_SerialPipeBase::writeable() && _pipeTx.readable()) - { - char c = _pipeTx.getc(); - _SerialPipeBase::_base_putc(c); - } -} - -void SerialPipe::txStart(void) -{ -#if defined(TARGET_UBLOX_C027) || defined(TARGET_LPC1768) - __disable_irq(); - txIrqBuf(); - __enable_irq(); -#else - while (_pipeTx.readable()) - { - char c = _pipeTx.getc(); - while (!_SerialPipeBase::writeable()) - /*wait*/; - _SerialPipeBase::_base_putc(c); - } -#endif -} - -// rx channel -int SerialPipe::readable(void) -{ - return _pipeRx.readable(); -} - -int SerialPipe::getc(void) -{ - if (!_pipeRx.readable()) - return EOF; - return _pipeRx.getc(); -} - -int SerialPipe::get(void* buffer, int length, bool blocking) -{ - return _pipeRx.get((char*)buffer,length,blocking); -} - -void SerialPipe::rxIrqBuf(void) -{ - while (_SerialPipeBase::readable()) - { - char c = _SerialPipeBase::_base_getc(); - if (_pipeRx.writeable()) - _pipeRx.putc(c); - else - /* overflow */; - } -} -
diff -r bc413454a83e -r 002503ab7199 C027_Support/SerialPipe.h --- a/C027_Support/SerialPipe.h Mon Jul 28 15:45:16 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -#pragma once - -#include "mbed.h" -#include "Pipe.h" - -#define _SerialPipeBase SerialBase //!< base class used by this class - -/** Buffered serial interface (rtos capable/interrupt driven) -*/ -class SerialPipe : public _SerialPipeBase -{ -public: - /** Constructor - \param tx the trasmitting pin - \param rx the receiving pin - \param rxSize the size of the receiving buffer - \param txSize the size of the transmitting buffer - */ - SerialPipe(PinName tx, PinName rx, int rxSize = 128, int txSize = 128); - - /** Destructor - */ - ~SerialPipe(void); - - // tx channel - //---------------------------------------------------- - - /** check if writable - return the number of free bytes - */ - int writeable(void); - - /** send a character (blocking) - \param c the character to send - \return c - */ - int putc(int c); - - /** send a buffer - \param buffer the buffer to send - \param length the size of the buffer to send - \param blocking, if true this function will block - until all bytes placed in the buffer. - \return the number of bytes written - */ - int put(const void* buffer, int length, bool blocking); - - // rx channel - //---------------------------------------------------- - - /** check if readable - \return the size available in the buffer. - */ - int readable(void); - - /** receive one character from the serial port (blocking) - \param the character received - */ - int getc(void); - - /** read a buffer from the serial port - \param pointer to the buffer to read. - \param length number of bytes to read - \param blocking true if all bytes shall be read. false if only the available bytes. - \return the number of bytes read. - */ - int get(void* buffer, int length, bool blocking); - -protected: - //! receive interrupt routine - void rxIrqBuf(void); - //! transmit interrupt woutine - void txIrqBuf(void); - //! start transmission helper - void txStart(void); - Pipe<char> _pipeRx; //!< receive pipe - Pipe<char> _pipeTx; //!< transmit pipe -};
diff -r bc413454a83e -r 002503ab7199 C027_Support/Socket/Endpoint.h --- a/C027_Support/Socket/Endpoint.h Mon Jul 28 15:45:16 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
diff -r bc413454a83e -r 002503ab7199 C027_Support/Socket/Socket.h --- a/C027_Support/Socket/Socket.h Mon Jul 28 15:45:16 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_ */
diff -r bc413454a83e -r 002503ab7199 C027_Support/Socket/TCPSocketConnection.h --- a/C027_Support/Socket/TCPSocketConnection.h Mon Jul 28 15:45:16 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
diff -r bc413454a83e -r 002503ab7199 C027_Support/Socket/UDPSocket.h --- a/C027_Support/Socket/UDPSocket.h Mon Jul 28 15:45:16 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
diff -r bc413454a83e -r 002503ab7199 main.cpp --- a/main.cpp Mon Jul 28 15:45:16 2014 +0000 +++ b/main.cpp Mon Jul 28 15:51:53 2014 +0000 @@ -1,3 +1,7 @@ +/* + * CQ出版 Interface 2014年10月号のC027(MAX-7Q)GPSテスト記事で使用したプログラム + * Naoya Takamura + */ #include "mbed.h" #include "GPS.h"
diff -r bc413454a83e -r 002503ab7199 mbed.bld --- a/mbed.bld Mon Jul 28 15:45:16 2014 +0000 +++ b/mbed.bld Mon Jul 28 15:51:53 2014 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/8a40adfe8776 \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/6213f644d804 \ No newline at end of file