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

Files at this revision

API Documentation at this revision

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

C027_Support.lib Show annotated file Show diff for this revision Revisions of this file
C027_Support/GPS.cpp Show diff for this revision Revisions of this file
C027_Support/GPS.h Show diff for this revision Revisions of this file
C027_Support/MDM.cpp Show diff for this revision Revisions of this file
C027_Support/MDM.h Show diff for this revision Revisions of this file
C027_Support/Pipe.h Show diff for this revision Revisions of this file
C027_Support/SerialPipe.cpp Show diff for this revision Revisions of this file
C027_Support/SerialPipe.h Show diff for this revision Revisions of this file
C027_Support/Socket/Endpoint.h Show diff for this revision Revisions of this file
C027_Support/Socket/Socket.h Show diff for this revision Revisions of this file
C027_Support/Socket/TCPSocketConnection.h Show diff for this revision Revisions of this file
C027_Support/Socket/UDPSocket.h Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
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,&REGSTREAM,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,&REGSTREAM,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,&REGSTREAM,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,&REGSTREAM,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,&REGLEN,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,&REGSTREAM,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, &param)) {
-                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, &param))
-        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, &param)) {
-        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