Cellular library for MTS Socket Modem Arduino Shield devices from Multi-Tech Systems

Dependents:   mtsas mtsas mtsas mtsas

Files at this revision

API Documentation at this revision

Comitter:
Leon Lindenfelser
Date:
Mon Feb 19 14:25:58 2018 -0600
Parent:
81:2e12915f892e
Commit message:
Add support for MTQ-LAT3(LE910-NA1) adn MTQ-LVW3(LE910-sv1)

Changed in this revision

Cellular/Cellular.cpp Show annotated file Show diff for this revision Revisions of this file
Cellular/Cellular.h Show annotated file Show diff for this revision Revisions of this file
Cellular/CellularFactory.cpp Show annotated file Show diff for this revision Revisions of this file
Cellular/CellularFactory.h Show annotated file Show diff for this revision Revisions of this file
Cellular/EasyIP.cpp Show annotated file Show diff for this revision Revisions of this file
Cellular/EasyIP.h Show annotated file Show diff for this revision Revisions of this file
Cellular/UIP.h Show annotated file Show diff for this revision Revisions of this file
--- a/Cellular/Cellular.cpp	Wed Nov 15 16:53:29 2017 -0600
+++ b/Cellular/Cellular.cpp	Mon Feb 19 14:25:58 2018 -0600
@@ -77,6 +77,10 @@
             return "MTSMC_LEU1";
         case MTSMC_LVW2:
             return "MTSMC_LVW2";
+        case MTQ_LAT3:
+            return "MTQ_LAT3";
+        case MTQ_LVW3:
+            return "MTQ_LVW3";            
         case MTQ_MAT1:
             return "MTQ-MAT1";
         case MTQ_MVW1:
@@ -116,7 +120,10 @@
 
 Cellular::Registration Cellular::getRegistration()
 {
-    string response = sendCommand("AT+CREG?", 5000);
+    if (type == MTQ_LVW3) 
+        string response = sendCommand("AT+CEREG?", 5000);
+    else
+        string response = sendCommand("AT+CREG?", 5000);
     if (response.find("OK") == string::npos) {
         return UNKNOWN;
     }
@@ -228,7 +235,7 @@
                 }
                 
                 if(type == MTSMC_H5 || type == MTSMC_G3 || type == MTSMC_EV3 || type == MTSMC_C2 || type == MTSMC_LAT1 || type == MTSMC_LEU1 ||
-                    type == MTSMC_LVW2 || MTQ_MAT1 || MTQ_MVW1) {
+                    type == MTSMC_LVW2 || type == MTQ_LAT3 || type == MTQ_LVW3 || type == MTQ_MAT1 || type == MTQ_MVW1) {
                     if (result.find("CONNECT\r\n") != std::string::npos) {
                         done = true;
                     } 
@@ -260,9 +267,11 @@
 {
     string csmp;
     
-    if (type == MTSMC_H5_IP || type == MTSMC_H5 || type == MTSMC_G3 || type == MTSMC_LAT1 || type == MTSMC_LEU1 || MTQ_MAT1 || MTQ_MVW1) {
+    if (type == MTSMC_H5_IP || type == MTSMC_H5 || type == MTSMC_G3 || type == MTSMC_LAT1 || type == MTSMC_LEU1 || 
+        type == MTQ_LAT3 || type == MTQ_MAT1 || type == MTQ_MVW1) {
         csmp = "AT+CSMP=17,167,0,0";
-    } else if (type == MTSMC_EV3_IP || type == MTSMC_EV3 || type == MTSMC_C2_IP || type == MTSMC_C2 || type == MTSMC_LVW2) {
+    } else if (type == MTSMC_EV3_IP || type == MTSMC_EV3 || type == MTSMC_C2_IP || type == MTSMC_C2 || type == MTSMC_LVW2 ||
+        type == MTQ_LVW3 ) {
         csmp = "AT+CSMP=,4098,0,2";
     } else {
         logError("unknown radio type [%d]", type);
@@ -331,7 +340,7 @@
         }
         //Start of SMS message
         std::vector<std::string> vSmsParts = Text::split(line, ',');
-        if (type == MTSMC_H5_IP || type == MTSMC_H5 || type == MTSMC_G3 || type == MTSMC_LAT1 || type == MTSMC_LEU1 || MTQ_MAT1 || MTQ_MVW1) {
+        if (type == MTSMC_H5_IP || type == MTSMC_H5 || type == MTSMC_G3 || type == MTSMC_LAT1 || type == MTSMC_LEU1 || type == MTQ_LAT3 || type == MTQ_MAT1 || type == MTQ_MVW1) {
             /* format for H5 and H5-IP radios
              * <index>, <status>, <oa>, <alpha>, <scts>
              * scts contains a comma, so splitting on commas should give us 6 items
@@ -343,7 +352,7 @@
 
             sms.phoneNumber = vSmsParts[2];
             sms.timestamp = vSmsParts[4] + ", " + vSmsParts[5];
-        } else if (type == MTSMC_EV3_IP || type == MTSMC_EV3 || type == MTSMC_C2_IP || type == MTSMC_C2 || type == MTSMC_LVW2) {
+        } else if (type == MTSMC_EV3_IP || type == MTSMC_EV3 || type == MTSMC_C2_IP || type == MTSMC_C2 || type == MTSMC_LVW2 || type == MTQ_LVW3) {
             /* format for EV3 and EV3-IP radios
              * <index>, <status>, <oa>, <callback>, <date>
              * splitting on commas should give us 5 items
--- a/Cellular/Cellular.h	Wed Nov 15 16:53:29 2017 -0600
+++ b/Cellular/Cellular.h	Mon Feb 19 14:25:58 2018 -0600
@@ -246,7 +246,7 @@
     /// Enumeration for different cellular radio types.
     enum Radio {
         NA, MTSMC_H5, MTSMC_EV3, MTSMC_G3, MTSMC_C2, MTSMC_H5_IP, MTSMC_EV3_IP, MTSMC_C2_IP, MTSMC_LAT1, MTSMC_LVW2, MTSMC_LEU1,
-			MTQ_MAT1, MTQ_MVW1
+			MTQ_LAT3, MTQ_LVW3, MTQ_MAT1, MTQ_MVW1
     };
 
     /// An enumeration of radio registration states with a cell tower.
--- a/Cellular/CellularFactory.cpp	Wed Nov 15 16:53:29 2017 -0600
+++ b/Cellular/CellularFactory.cpp	Mon Feb 19 14:25:58 2018 -0600
@@ -1,107 +1,113 @@
-#include "mbed.h"
-#include "CellularFactory.h"
-#include "MTSLog.h"
-#include <string>
-
-using namespace mts;
-
-Cellular* CellularFactory::create(MTSBufferedIO* io) {
-    bool uip;
-    std::string model;
-    std::string reply;
-    Cellular::Radio type = Cellular::NA;
-    Cellular* cell;
-    
-    /* wait for radio to get into a good state */
-    while (true) {
-        if (sendCommand(io, "AT", 1000).find("OK") != string::npos) {
-            logTrace("radio replied");
-            break;
-        } else {
-            logTrace("waiting on radio...");
-        }
-        wait(1);
-    }
-    
-    while (true) {
-        /* AT#VVERSION is a UIP specific AT command
-         * if we get an error response, we're not using a UIP board */
-        reply = sendCommand(io, "AT#VVERSION", 2000);
-        if ((reply.find("ERROR") != string::npos) || (reply.find("error") != string::npos)) {
-            uip = false;
-            break;
-        } else if (reply.find("VVERSION:") != string::npos) {
-            uip = true;
-            break;
-        } else {
-            logTrace("Checking for UIP chip");
-        }
-        wait(1);
-    }
-    
-    /* "ATI4" gets us the model (HE910, DE910, etc) */
-    while (true) {
-        string mNumber;
-        model = sendCommand(io, "ATI4", 3000);
-        if (uip) {
-            if (model.find("HE910") != string::npos) {
-                type = Cellular::MTSMC_H5_IP;
-                mNumber = "HE910";
-            } else if (model.find("DE910") != string::npos) {
-                type = Cellular::MTSMC_EV3_IP;
-                mNumber = "DE910";
-            } else if (model.find("CE910") != string::npos) {
-                type = Cellular::MTSMC_C2_IP;
-                mNumber = "CE910";
-            }
-            if (type != Cellular::NA) {
-                cell = new UIP(type);
-                logDebug("UIP radio model: %s", mNumber.c_str());
-                break;
-            }
-        } else {
-            if (model.find("HE910") != string::npos) {
-                type = Cellular::MTSMC_H5;
-                mNumber = "HE910";
-            } else if (model.find("DE910") != string::npos) {
-                type = Cellular::MTSMC_EV3;
-                mNumber = "DE910";
-            } else if (model.find("CE910") != string::npos) {
-                type = Cellular::MTSMC_C2;
-                mNumber = "CE910";
-            } else if (model.find("GE910") != string::npos) {
-                type = Cellular::MTSMC_G3;
-                mNumber = "GE910";
-            } else if (model.find("LE910-NAG") != string::npos) {
-                type = Cellular::MTSMC_LAT1;
-                mNumber = "LE910-NAG";
-            } else if (model.find("LE910-SVG") != string::npos) {
-                type = Cellular::MTSMC_LVW2;
-                mNumber = "LE910-SVG";
-            } else if (model.find("LE910-EUG") != string::npos) {
-                type = Cellular::MTSMC_LEU1;
-                mNumber = "LE910-EUG";
-            } else if (model.find("ME910C1-NA") != string::npos) {
-                type = Cellular::MTQ_MAT1;
-                mNumber = "ME910C1-NA";
-            } else if (model.find("ME910C1-NV") != string::npos) {
-                type = Cellular::MTQ_MVW1;
-                mNumber = "ME910C1-NV";
-            }
-            if (type != Cellular::NA) {
-                cell = new EasyIP(type);
-                logDebug("EasyIP radio model: %s", mNumber.c_str());
-                break;
-            }
-        }
-        logTrace("Determining radio type");
-        wait(1);
-    }
-
-    if (! cell->init(io)) {
-        logError("cellular initialization failed");
-        return NULL;
-    }
-
-    return cell;
-}
+#include "mbed.h"
+#include "CellularFactory.h"
+#include "MTSLog.h"
+#include <string>
+
+using namespace mts;
+
+Cellular* CellularFactory::create(MTSBufferedIO* io) {
+    bool uip;
+    std::string model;
+    std::string reply;
+    Cellular::Radio type = Cellular::NA;
+    Cellular* cell;
+    
+    /* wait for radio to get into a good state */
+    while (true) {
+        if (sendCommand(io, "AT", 1000).find("OK") != string::npos) {
+            logTrace("radio replied");
+            break;
+        } else {
+            logTrace("waiting on radio...");
+        }
+        wait(1);
+    }
+    
+    while (true) {
+        /* AT#VVERSION is a UIP specific AT command
+         * if we get an error response, we're not using a UIP board */
+        reply = sendCommand(io, "AT#VVERSION", 2000);
+        if ((reply.find("ERROR") != string::npos) || (reply.find("error") != string::npos)) {
+            uip = false;
+            break;
+        } else if (reply.find("VVERSION:") != string::npos) {
+            uip = true;
+            break;
+        } else {
+            logTrace("Checking for UIP chip");
+        }
+        wait(1);
+    }
+    
+    /* "ATI4" gets us the model (HE910, DE910, etc) */
+    while (true) {
+        string mNumber;
+        model = sendCommand(io, "ATI4", 3000);
+        if (uip) {
+            if (model.find("HE910") != string::npos) {
+                type = Cellular::MTSMC_H5_IP;
+                mNumber = "HE910";
+            } else if (model.find("DE910") != string::npos) {
+                type = Cellular::MTSMC_EV3_IP;
+                mNumber = "DE910";
+            } else if (model.find("CE910") != string::npos) {
+                type = Cellular::MTSMC_C2_IP;
+                mNumber = "CE910";
+            }
+            if (type != Cellular::NA) {
+                cell = new UIP(type);
+                logDebug("UIP radio model: %s", mNumber.c_str());
+                break;
+            }
+        } else {
+            if (model.find("HE910") != string::npos) {
+                type = Cellular::MTSMC_H5;
+                mNumber = "HE910";
+            } else if (model.find("DE910") != string::npos) {
+                type = Cellular::MTSMC_EV3;
+                mNumber = "DE910";
+            } else if (model.find("CE910") != string::npos) {
+                type = Cellular::MTSMC_C2;
+                mNumber = "CE910";
+            } else if (model.find("GE910") != string::npos) {
+                type = Cellular::MTSMC_G3;
+                mNumber = "GE910";
+            } else if (model.find("LE910-NAG") != string::npos) {
+                type = Cellular::MTSMC_LAT1;
+                mNumber = "LE910-NAG";
+            } else if (model.find("LE910-SVG") != string::npos) {
+                type = Cellular::MTSMC_LVW2;
+                mNumber = "LE910-SVG";
+            } else if (model.find("LE910-EUG") != string::npos) {
+                type = Cellular::MTSMC_LEU1;
+                mNumber = "LE910-EUG";
+            } else if (model.find("LE910-NA1") != string::npos) {
+                type = Cellular::MTQ_LAT3;
+                mNumber = "LE910-NA1";
+            } else if (model.find("LE910-SV1") != string::npos) {
+                type = Cellular::MTQ_LVW3;
+                mNumber = "LE910-SV1";
+            } else if (model.find("ME910C1-NA") != string::npos) {
+                type = Cellular::MTQ_MAT1;
+                mNumber = "ME910C1-NA";
+            } else if (model.find("ME910C1-NV") != string::npos) {
+                type = Cellular::MTQ_MVW1;
+                mNumber = "ME910C1-NV";
+            }
+            if (type != Cellular::NA) {
+                cell = new EasyIP(type);
+                logDebug("EasyIP radio model: %s", mNumber.c_str());
+                break;
+            }
+        }
+        logTrace("Determining radio type");
+        wait(1);
+    }
+
+    if (! cell->init(io)) {
+        logError("cellular initialization failed");
+        return NULL;
+    }
+
+    return cell;
+}
--- a/Cellular/CellularFactory.h	Wed Nov 15 16:53:29 2017 -0600
+++ b/Cellular/CellularFactory.h	Mon Feb 19 14:25:58 2018 -0600
@@ -1,18 +1,18 @@
-#ifndef CELLULARFACTORY_H
-#define CELLULARFACTORY_H
-
-#include "UIP.h"
-#include "EasyIP.h"
-#include "MTSBufferedIO.h"
-
-namespace mts {
-
-class CellularFactory
-{
-public:
-    static Cellular* create(MTSBufferedIO* io);
-};
-
-}
-
-#endif
+#ifndef CELLULARFACTORY_H
+#define CELLULARFACTORY_H
+
+#include "UIP.h"
+#include "EasyIP.h"
+#include "MTSBufferedIO.h"
+
+namespace mts {
+
+class CellularFactory
+{
+public:
+    static Cellular* create(MTSBufferedIO* io);
+};
+
+}
+
+#endif
--- a/Cellular/EasyIP.cpp	Wed Nov 15 16:53:29 2017 -0600
+++ b/Cellular/EasyIP.cpp	Mon Feb 19 14:25:58 2018 -0600
@@ -52,7 +52,7 @@
     }
     // Shorten data sending timeout from 5s to 100ms
     // Some servers won't handle a timeout that long
-    snprintf(buf, sizeof(buf), "AT#SCFG=1,%d,300,90,600,1", type == MTSMC_LVW2 ? 3 : 1);
+    snprintf(buf, sizeof(buf), "AT#SCFG=1,%d,300,90,600,1", (type == MTSMC_LVW2 || type == MTQ_LVW3) ? 3 : 1);
     if (sendBasicCommand(string(buf), 2000) != MTS_SUCCESS) {
         logWarning("Failed to reconfigure socket timeout parameters");
     }
@@ -112,7 +112,7 @@
         logDebug("Making PPP Connection Attempt");
     }
     char buf[64];
-    snprintf(buf, sizeof(buf), "AT#SGACT=%d,1", type == MTSMC_LVW2 ? 3 : 1);
+    snprintf(buf, sizeof(buf), "AT#SGACT=%d,1", (type == MTSMC_LVW2 || type == MTQ_LVW3) ? 3 : 1);
     std::string pppResult = sendCommand(string(buf), 15000);
     std::vector<std::string> parts;
     if(pppResult.find("OK") != std::string::npos) {
@@ -127,7 +127,7 @@
         pppConnected = true;
 
     } else {
-        snprintf(buf, sizeof(buf), "%d,1", type == MTSMC_LVW2 ? 3 : 1);
+        snprintf(buf, sizeof(buf), "%d,1", (type == MTSMC_LVW2 || type == MTQ_LVW3) ? 3 : 1);
         pppResult = sendCommand("AT#SGACT?", 2000);
         if(pppResult.find(string(buf)) != std::string::npos) {
            logDebug("Radio is already connected");
@@ -155,7 +155,7 @@
     //Sends AT#SGACT=1,0 command
     for (int y = 0; y < 5; y++) {
         char buf[64];
-        snprintf(buf, sizeof(buf), "AT#SGACT=%d,0", type == MTSMC_LVW2 ? 3 : 1);
+        snprintf(buf, sizeof(buf), "AT#SGACT=%d,0", (type == MTSMC_LVW2 || type == MTQ_LVW3) ? 3 : 1);
         Code code = sendBasicCommand(string(buf), 1000);
         if (code == MTS_SUCCESS) {
             logDebug("Successfully closed PPP Connection");
@@ -169,7 +169,7 @@
     tmr.start();
     while(tmr.read() < 30) {
         char buf[16];
-        snprintf(buf, sizeof(buf), "%d,0", type == MTSMC_LVW2 ? 3 : 1);
+        snprintf(buf, sizeof(buf), "%d,0", (type == MTSMC_LVW2 || type == MTQ_LVW3) ? 3 : 1);
         result = sendCommand("AT#SGACT?", 1000);
         if(result.find(string(buf)) != std::string::npos) {
             break;
@@ -222,7 +222,7 @@
     }
     
     string reply = sendCommand("AT#SGACT?", 1000);
-    snprintf(buf, sizeof(buf), "%d,1", type == MTSMC_LVW2 ? 3 : 1);
+    snprintf(buf, sizeof(buf), "%d,1", (type == MTSMC_LVW2 || type == MTQ_LVW3) ? 3 : 1);
     if (reply.find(string(buf)) != std::string::npos) {
         active = true;
     } else {
@@ -526,7 +526,7 @@
         }
         this->apn = apn;
         return code;
-    } else if (type == MTSMC_LAT1 || type == MTSMC_LEU1) {
+    } else if (type == MTSMC_LAT1 || type == MTSMC_LEU1 || type == MTQ_LAT3) {
          //CGDCONT has options: IP,PPP,IPv6
         Code code = sendBasicCommand("AT+CGDCONT=1,\"IP\",\"" + apn + "\"", 1000);
         if (code != MTS_SUCCESS) {
@@ -541,11 +541,11 @@
         }
         this->apn = apn;
         return code;
-    } else if (type == MTQ_MVW1) {
-        logInfo("MTQ_MVW1 does not need an APN");
+    } else if (type == MTQ_MVW1 || type == MTQ_LVW3) {
+        logInfo("Radio does not need an APN");
         return MTS_SUCCESS;       
     } else {
-        logInfo("CDMA radios don't need an APN");
+        logInfo("CDMA radios do not need an APN");
         return MTS_SUCCESS;
     }
 }
--- a/Cellular/EasyIP.h	Wed Nov 15 16:53:29 2017 -0600
+++ b/Cellular/EasyIP.h	Mon Feb 19 14:25:58 2018 -0600
@@ -1,154 +1,154 @@
-#ifndef EASYIP_H
-#define EASYIP_H
-
-#include <string>
-#include <vector>
-
-#include "MTSBufferedIO.h"
-#include "Cellular.h"
-
-namespace mts
-{
-    /** This class implements the same interface used for UIP version radios on an Easy IP radio
-    * using the Hayes AT command set.
-    * (See the UIP class and documentation, "UIP.h")
-    * This class supports four main types of cellular radio interactions including:
-    * configuration and status AT-command processing, SMS processing, TCP Socket data connections,
-    * and UDP data connections. It should be noted that the radio can not process commands or
-    * SMS messages while having an open data connection at the same time. The concurrent
-    * capability may be added in a future release. This class also inherits from IPStack
-    * providing a common set of commands for communication devices that have an onboard
-    * IP Stack. It is also integrated with the standard mbed Sockets package and can therefore
-    * be used seamlessly with clients and services built on top of this interface already within
-    * the mbed library.
-    * The default baud rate for the cellular radio is 115200 bps.
-    *
-    * Example code is found under Cellular.h
-    */
-class EasyIP : public Cellular
-{
-public:
-    /** This static function is used to create or get a reference to a
-    * Cellular object. Cellular uses the singleton pattern, which means
-    * that you can only have one existing at a time. The first time you
-    * call getInstance this method creates a new uninitialized Cellular
-    * object and returns it. All future calls to this method will return
-    * a reference to the instance created during the first call. Note that
-    * you must call init on the returned instance before mnaking any other
-    * calls. If using this class's bindings to any of the Socket package
-    * classes like TCPSocketConnection, you must call this method and the
-    * init method on the returned object first, before even creating the
-    * other objects.
-    *
-    * @returns a reference to the single Cellular obect that has been created.
-    */
-    EasyIP(Radio type);
-    
-    /** Destructs a Cellular object and frees all related resources.
-    */
-    ~EasyIP();
-    
-    /** Initializes the MTS IO buffer
-    */
-    virtual bool init(MTSBufferedIO* io);
-    
-    /** PPP connect command.
-    * Connects the radio to the cellular network.
-    *
-    * @returns true if PPP connection to the network succeeded,
-    * false if the PPP connection failed.
-    */
-    virtual bool connect();
-    
-    /** PPP disconnect command.
-    * Disconnects from the PPP network, and will also close active socket
-    * connection if open. 
-    */
-    virtual void disconnect();
-    
-    /** Checks if the radio is connected to the cell network.
-    * Checks antenna signal, cell tower registration, and context activation
-    * before finally pinging (4 pings, 32 bytes each) to confirm PPP connection
-    * to network. Will return true if there is an open socket connection as well.
-    *
-    * @returns true if there is a PPP connection to the cell network, false
-    * if there is no PPP connection to the cell network.
-    */
-    virtual bool isConnected();
-    
-    /** Resets the radio/modem.
-    * Disconnects all active PPP and socket connections to do so.
-    */
-    virtual void reset();
-
-    // TCP and UDP Socket related commands
-    // For behavior of the following methods refer to IPStack.h documentation
-    
-    virtual bool open(const std::string& address, unsigned int port, Mode mode);
-    virtual bool close(bool shutdown);
-    virtual int read(char* data, int max, int timeout = -1);    
-    virtual int write(const char* data, int length, int timeout = -1);
-    
-    /** Pings specified DNS or IP address
-     * Google DNS server used as default ping address
-     * @returns true if ping received alive response else false
-     */
-    virtual bool ping(const std::string& address = "8.8.8.8"); 
-    
-    /** Sets the APN
-    * 
-    * @param apn c-string of the APN to use
-    *
-    * @returns MTS_SUCCESS if the APN was set, or is not needed, else it
-    * returns the result of the AT command sent to the radio to set the APN
-    */
-    virtual Code setApn(const std::string& apn);
-    
-    /** Enables GPS.
-    * @returns true if GPS gets or is enabled, false if GPS is not supported.
-    */
-    virtual bool GPSenable();
-
-    /** Disables GPS.
-    * @returns true if GPS gets or is disabled, false if GPS failed to disable.
-    */
-    virtual bool GPSdisable();
-
-    /** Checks if GPS is enabled.
-    * @returns true if GPS is enabled, false if GPS is disabled.
-    */
-    virtual bool GPSenabled();
-        
-    /** Get GPS position.
-    * @returns a string containing the GPS position.
-    */
-    virtual Cellular::gpsData GPSgetPosition();
-
-    /** Check for GPS fix.
-    * @returns true if there is a fix and false otherwise.
-    */
-    virtual bool GPSgotFix();
-        
-private:
-    /** Function that sends +++ to the radio to exit data mode
-    * returns true if it successfully exits from online mode, else
-    * it returns false. Used due to the fact that AT commands
-    * cannot be sent while in data mode.
-    *
-    * @returns true if the radio dropped from data mode to commande mode
-    * or is already in command mode (socket is still open in the background),
-    * and false if the radio failed to switch to command mode.
-    */
-    virtual bool sendEscapeCommand(); 
-    
-    /** Switches to command mode, queries the status of the socket connection,
-    * and then returns back to the active socket connection (if still open)
-    *
-    * @returns true if a socket is currently open, otherwise it returns false
-    */
-    virtual bool socketCheck();
-};
-
-}
-
+#ifndef EASYIP_H
+#define EASYIP_H
+
+#include <string>
+#include <vector>
+
+#include "MTSBufferedIO.h"
+#include "Cellular.h"
+
+namespace mts
+{
+    /** This class implements the same interface used for UIP version radios on an Easy IP radio
+    * using the Hayes AT command set.
+    * (See the UIP class and documentation, "UIP.h")
+    * This class supports four main types of cellular radio interactions including:
+    * configuration and status AT-command processing, SMS processing, TCP Socket data connections,
+    * and UDP data connections. It should be noted that the radio can not process commands or
+    * SMS messages while having an open data connection at the same time. The concurrent
+    * capability may be added in a future release. This class also inherits from IPStack
+    * providing a common set of commands for communication devices that have an onboard
+    * IP Stack. It is also integrated with the standard mbed Sockets package and can therefore
+    * be used seamlessly with clients and services built on top of this interface already within
+    * the mbed library.
+    * The default baud rate for the cellular radio is 115200 bps.
+    *
+    * Example code is found under Cellular.h
+    */
+class EasyIP : public Cellular
+{
+public:
+    /** This static function is used to create or get a reference to a
+    * Cellular object. Cellular uses the singleton pattern, which means
+    * that you can only have one existing at a time. The first time you
+    * call getInstance this method creates a new uninitialized Cellular
+    * object and returns it. All future calls to this method will return
+    * a reference to the instance created during the first call. Note that
+    * you must call init on the returned instance before mnaking any other
+    * calls. If using this class's bindings to any of the Socket package
+    * classes like TCPSocketConnection, you must call this method and the
+    * init method on the returned object first, before even creating the
+    * other objects.
+    *
+    * @returns a reference to the single Cellular obect that has been created.
+    */
+    EasyIP(Radio type);
+    
+    /** Destructs a Cellular object and frees all related resources.
+    */
+    ~EasyIP();
+    
+    /** Initializes the MTS IO buffer
+    */
+    virtual bool init(MTSBufferedIO* io);
+    
+    /** PPP connect command.
+    * Connects the radio to the cellular network.
+    *
+    * @returns true if PPP connection to the network succeeded,
+    * false if the PPP connection failed.
+    */
+    virtual bool connect();
+    
+    /** PPP disconnect command.
+    * Disconnects from the PPP network, and will also close active socket
+    * connection if open. 
+    */
+    virtual void disconnect();
+    
+    /** Checks if the radio is connected to the cell network.
+    * Checks antenna signal, cell tower registration, and context activation
+    * before finally pinging (4 pings, 32 bytes each) to confirm PPP connection
+    * to network. Will return true if there is an open socket connection as well.
+    *
+    * @returns true if there is a PPP connection to the cell network, false
+    * if there is no PPP connection to the cell network.
+    */
+    virtual bool isConnected();
+    
+    /** Resets the radio/modem.
+    * Disconnects all active PPP and socket connections to do so.
+    */
+    virtual void reset();
+
+    // TCP and UDP Socket related commands
+    // For behavior of the following methods refer to IPStack.h documentation
+    
+    virtual bool open(const std::string& address, unsigned int port, Mode mode);
+    virtual bool close(bool shutdown);
+    virtual int read(char* data, int max, int timeout = -1);    
+    virtual int write(const char* data, int length, int timeout = -1);
+    
+    /** Pings specified DNS or IP address
+     * Google DNS server used as default ping address
+     * @returns true if ping received alive response else false
+     */
+    virtual bool ping(const std::string& address = "8.8.8.8"); 
+    
+    /** Sets the APN
+    * 
+    * @param apn c-string of the APN to use
+    *
+    * @returns MTS_SUCCESS if the APN was set, or is not needed, else it
+    * returns the result of the AT command sent to the radio to set the APN
+    */
+    virtual Code setApn(const std::string& apn);
+    
+    /** Enables GPS.
+    * @returns true if GPS gets or is enabled, false if GPS is not supported.
+    */
+    virtual bool GPSenable();
+
+    /** Disables GPS.
+    * @returns true if GPS gets or is disabled, false if GPS failed to disable.
+    */
+    virtual bool GPSdisable();
+
+    /** Checks if GPS is enabled.
+    * @returns true if GPS is enabled, false if GPS is disabled.
+    */
+    virtual bool GPSenabled();
+        
+    /** Get GPS position.
+    * @returns a string containing the GPS position.
+    */
+    virtual Cellular::gpsData GPSgetPosition();
+
+    /** Check for GPS fix.
+    * @returns true if there is a fix and false otherwise.
+    */
+    virtual bool GPSgotFix();
+        
+private:
+    /** Function that sends +++ to the radio to exit data mode
+    * returns true if it successfully exits from online mode, else
+    * it returns false. Used due to the fact that AT commands
+    * cannot be sent while in data mode.
+    *
+    * @returns true if the radio dropped from data mode to commande mode
+    * or is already in command mode (socket is still open in the background),
+    * and false if the radio failed to switch to command mode.
+    */
+    virtual bool sendEscapeCommand(); 
+    
+    /** Switches to command mode, queries the status of the socket connection,
+    * and then returns back to the active socket connection (if still open)
+    *
+    * @returns true if a socket is currently open, otherwise it returns false
+    */
+    virtual bool socketCheck();
+};
+
+}
+
 #endif /* EASYIP_H */
\ No newline at end of file
--- a/Cellular/UIP.h	Wed Nov 15 16:53:29 2017 -0600
+++ b/Cellular/UIP.h	Mon Feb 19 14:25:58 2018 -0600
@@ -1,97 +1,97 @@
-#ifndef UIP_H
-#define UIP_H
-
-#include <string>
-#include <vector>
-
-#include "MTSBufferedIO.h"
-#include "Cellular.h"
-
-namespace mts
-{
-
-/** This is a class for communicating with a Multi-Tech Systems SocketModem iCell. The
-* SocketModem iCell is a family of carrier certified embedded cellular radio modules with
-* a common hardware footprint and AT command set for built in IP-stack functionality.
-* This class supports three main types of cellular radio interactions including:
-* configuration and status AT command processing, SMS processing, and TCP Socket
-* data connections. It should be noted that the radio can not process commands or
-* SMS messages while having an open data connection at the same time. The concurrent
-* capability may be added in a future release. This class also inherits from IPStack
-* providing a common set of commands for communication devices that have an onboard
-* IP Stack. It is also integrated with the standard mbed Sockets package and can therefore
-* be used seamlessly with clients and services built on top of this interface already within
-* the mbed library.
-*
-* All of the following examples use the Pin Names for the STMicro Nucleo F401RE board coupled with
-* the SocketModem Shield Arduino compatible board. Please chage Pin Names accordingly to
-* match your hardware configuration. It also assumes the use of RTS/CTS hardware handshaking
-* using GPIOs. To disable this you will need to change settings on the radio module and
-* and use the MTSSerial class instead of MTSSerialFlowControl. The default baud rate for the
-* cellular radio is 115200 bps.
-*
-* Example code is found under Cellular.h
-*/
-
-class UIP : public Cellular
-{
-public:
-    /** This static function is used to create or get a reference to a
-    * Cellular object. Cellular uses the singleton pattern, which means
-    * that you can only have one existing at a time. The first time you
-    * call getInstance this method creates a new uninitialized Cellular
-    * object and returns it. All future calls to this method will return
-    * a reference to the instance created during the first call. Note that
-    * you must call init on the returned instance before mnaking any other
-    * calls. If using this class's bindings to any of the Socket package
-    * classes like TCPSocketConnection, you must call this method and the
-    * init method on the returned object first, before even creating the
-    * other objects.
-    *
-    * @returns a reference to the single Cellular object that has been created.
-    */
-    UIP(Radio type);
-
-    /** Destructs a Cellular object and frees all related resources.
-    */
-    ~UIP();
-
-    virtual bool init(MTSBufferedIO* io);
-
-    // Cell connection based commands derived from CommInterface.h
-    /** Initiates a PPP connection between the radio and the cell network */
-    virtual bool connect();
-    
-    /** Disconnects the PPP connection between the radio and the cell network */
-    virtual void disconnect();
-    
-    /** Checks if the radio has a PPP connection established with the cell network 
-     * (Can reach the internet essentially)
-     */
-    virtual bool isConnected();
-    
-    /** Resets the radio, must first close active socket and PPP connections 
-     * to do so
-     */
-    virtual void reset();
-
-    // TCP and UDP Socket related commands
-    // For behavior of the following methods refer to IPStack.h documentation
-    virtual bool open(const std::string& address, unsigned int port, Mode mode);
-    virtual bool close(bool shutdown);
-    virtual int read(char* data, int max, int timeout = -1);
-    virtual int write(const char* data, int length, int timeout = -1);
-    virtual bool ping(const std::string& address = "8.8.8.8");
-    
-    /** A method for setting the APN 
-    *
-    * @param apn APN to be passed as a c-string
-    * @returns the standard AT Code enumeration
-    */
-    virtual Code setApn(const std::string& apn);
-
-};
-
-}
-
-#endif
+#ifndef UIP_H
+#define UIP_H
+
+#include <string>
+#include <vector>
+
+#include "MTSBufferedIO.h"
+#include "Cellular.h"
+
+namespace mts
+{
+
+/** This is a class for communicating with a Multi-Tech Systems SocketModem iCell. The
+* SocketModem iCell is a family of carrier certified embedded cellular radio modules with
+* a common hardware footprint and AT command set for built in IP-stack functionality.
+* This class supports three main types of cellular radio interactions including:
+* configuration and status AT command processing, SMS processing, and TCP Socket
+* data connections. It should be noted that the radio can not process commands or
+* SMS messages while having an open data connection at the same time. The concurrent
+* capability may be added in a future release. This class also inherits from IPStack
+* providing a common set of commands for communication devices that have an onboard
+* IP Stack. It is also integrated with the standard mbed Sockets package and can therefore
+* be used seamlessly with clients and services built on top of this interface already within
+* the mbed library.
+*
+* All of the following examples use the Pin Names for the STMicro Nucleo F401RE board coupled with
+* the SocketModem Shield Arduino compatible board. Please chage Pin Names accordingly to
+* match your hardware configuration. It also assumes the use of RTS/CTS hardware handshaking
+* using GPIOs. To disable this you will need to change settings on the radio module and
+* and use the MTSSerial class instead of MTSSerialFlowControl. The default baud rate for the
+* cellular radio is 115200 bps.
+*
+* Example code is found under Cellular.h
+*/
+
+class UIP : public Cellular
+{
+public:
+    /** This static function is used to create or get a reference to a
+    * Cellular object. Cellular uses the singleton pattern, which means
+    * that you can only have one existing at a time. The first time you
+    * call getInstance this method creates a new uninitialized Cellular
+    * object and returns it. All future calls to this method will return
+    * a reference to the instance created during the first call. Note that
+    * you must call init on the returned instance before mnaking any other
+    * calls. If using this class's bindings to any of the Socket package
+    * classes like TCPSocketConnection, you must call this method and the
+    * init method on the returned object first, before even creating the
+    * other objects.
+    *
+    * @returns a reference to the single Cellular object that has been created.
+    */
+    UIP(Radio type);
+
+    /** Destructs a Cellular object and frees all related resources.
+    */
+    ~UIP();
+
+    virtual bool init(MTSBufferedIO* io);
+
+    // Cell connection based commands derived from CommInterface.h
+    /** Initiates a PPP connection between the radio and the cell network */
+    virtual bool connect();
+    
+    /** Disconnects the PPP connection between the radio and the cell network */
+    virtual void disconnect();
+    
+    /** Checks if the radio has a PPP connection established with the cell network 
+     * (Can reach the internet essentially)
+     */
+    virtual bool isConnected();
+    
+    /** Resets the radio, must first close active socket and PPP connections 
+     * to do so
+     */
+    virtual void reset();
+
+    // TCP and UDP Socket related commands
+    // For behavior of the following methods refer to IPStack.h documentation
+    virtual bool open(const std::string& address, unsigned int port, Mode mode);
+    virtual bool close(bool shutdown);
+    virtual int read(char* data, int max, int timeout = -1);
+    virtual int write(const char* data, int length, int timeout = -1);
+    virtual bool ping(const std::string& address = "8.8.8.8");
+    
+    /** A method for setting the APN 
+    *
+    * @param apn APN to be passed as a c-string
+    * @returns the standard AT Code enumeration
+    */
+    virtual Code setApn(const std::string& apn);
+
+};
+
+}
+
+#endif