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:
Vanger
Date:
Wed Jul 16 14:26:10 2014 +0000
Parent:
32:7d5581159bed
Child:
34:7d412c989964
Commit message:
Updating and formatting documentation for EasyIP.h and EasyIP.cpp.; Comment tweak for UIP.h

Changed in this revision

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/EasyIP.cpp	Tue Jul 15 20:37:08 2014 +0000
+++ b/Cellular/EasyIP.cpp	Wed Jul 16 14:26:10 2014 +0000
@@ -6,121 +6,10 @@
 
 using namespace mts;
 
-bool EasyIP::sendEscapeCommand()
-{
-    //string Cellular::sendCommand(const std::string& command, unsigned int timeoutMillis, char esc)
-    if(io == NULL) {
-        logError("MTSBufferedIO not set");
-        return false;
-    }
-    if(!socketOpened) {
-        logError("Socket is not open. Can not send AT escape sequence (+++)");
-        return false;
-    }
-    
-    if(!socketCloseable) {
-        logError("Socket is not closeable");
-        return false;
-    }
-    
-    io->rxClear();
-    io->txClear();
-    
-    std::string result;
-    unsigned int timeoutMillis = 2000;
-    const int size_cmd = 3;
-    //Attempt to write command
-    wait(1); //Format for +++ command is 1 second wait, send +++, then another second wait
-             //1s wait after command is implemented as a polling function for 2 seconds
-             //Option: Could change wait periods to be longer/shorter (0-255)*50ms
-    if(io->write("+++", size_cmd, timeoutMillis) != size_cmd) {
-        //Failed to write command
-        logError("failed to send command to radio within %d milliseconds", timeoutMillis);
-        return false;
-    }
-    
-    int timer = 0;
-    char tmp[256];
-    tmp[255] = 0;
-    bool done = false;
-    io->read(tmp,255,0);
-    bool exitmode = false;
-    
-    do {
-        wait(0.1);
-        timer += 100;
-        //Make a non-blocking read call by passing timeout of zero
-            int size = io->read(tmp,255,0);    //1 less than allocated (timeout is instant)
-            if(size > 0) {
-                result.append(tmp, size);
-            }
-        if(result.find("OK") != std::string::npos) {
-            exitmode = true;
-            done = true;
-        } else if(result.find("NO CARRIER") != std::string::npos) {
-            exitmode = true;
-            done = true;
-        } else if(result.find("ERROR") != std::string::npos) {
-            exitmode = false;
-            done = true;
-        }
-        if(timer >= timeoutMillis) {
-            logDebug("Escape sequence [+++] timed out after %d milliseconds", timeoutMillis);
-            exitmode = true;
-            done = true;
-        }
-    } while (!done);
-    
-    return exitmode;
-}
 
-bool EasyIP::socketCheck() {
-    bool status = false;
-    std::string socketInfo = "9"; //9 is unrecognized
-    std::vector<std::string> params;
-    
-    if(sendEscapeCommand()) {
-        socketOpened = false;
-        if(sendBasicCommand("AT", 1000) == MTS_SUCCESS) {
-            socketInfo = sendCommand("AT#SS=1", 2000);
-            if(socketInfo.find("OK") != std::string::npos) {
-                //Found valid response
-                params = Text::split(socketInfo, "\r\n");
-                params = Text::split(params[1], ",");
-                socketInfo = params[1];
-                //Check comparison of params[1] to response codes
-            } else {
-                logError("Could not determine socket status[%s]",socketInfo.c_str());
-                socketInfo == "9"; //9 is unrecognized
-            }
-        }
-    } else {
-        status = false; //Return value of socketOpened when checking
-    }
-    //Check socket status query
-    if(socketInfo == "2" || socketInfo == "3" || socketInfo == "1" || socketInfo == "4") {
-        status = true; //2 and 3 are suspended connections
-    } else if(socketInfo == "0" || socketInfo == "5") {
-        status = false; //0 is closed socket, probably won't occur
-    } else {
-        logError("Could not determine socket status");
-        status = false; //anything else is unknown status
-    }
-    
-    if(status) {
-        std::string reconnect = sendCommand("AT#SO=1", 2000);
-        if(reconnect.find("CONNECT") != std::string::npos || reconnect.find("OK") != std::string::npos) {
-        } else {
-            logError("Failed to resume socket connection");
-        }
-    }
-    return status;
-}
 
 EasyIP::EasyIP(Radio type)
 {
-    //Not sure how the construction process is done, 
-    //but assuming it works for both EasyIP and UIP the same way.
     this->type = type;
     io = NULL;
     dcd = NULL;
@@ -138,8 +27,6 @@
 
 EasyIP::~EasyIP()
 {
-    //Same reasoning for the destructor as the constructor,
-    //assuming it works for UIP, it will work for EasyIP
     if (dtr != NULL) {
         dtr->write(1);
     }
@@ -166,7 +53,7 @@
 
 bool EasyIP::connect()
 {
-    //Check if APN is not set, if so, connect will not work.
+    //Check if APN is not set, if it is not, connect will not work.
     if (type == MTSMC_H5_IP || type == MTSMC_H5 || type == MTSMC_G3) {
         if(apn.size() == 0) {
             logDebug("APN is not set");
@@ -327,7 +214,7 @@
         }
     }
     
-    //Check active mode (SGACT = 1,1)
+    //Check active context (SGACT = 1,1)
     reply = sendCommand("AT#SGACT?", 500);
     if(reply.empty() || (reply.find("ERROR") != std::string::npos)) {
         active = false;
@@ -388,6 +275,18 @@
     return pppConnected;
 }
 
+//Resets the radio
+void EasyIP::reset()
+{
+    disconnect();
+    if(sendBasicCommand("AT#REBOOT", 10000) != MTS_SUCCESS) {
+        logError("Socket Modem did not accept RESET command\n\r");
+    } else {
+        logWarning("Socket Modem is resetting, allow 30 seconds for it to come back\n\r");
+        return;
+    }
+}
+
 //Binds the socket to a specific port if able
 bool EasyIP::bind(unsigned int port)
 {
@@ -678,7 +577,7 @@
          //Set IP,PPP,IPv6
         Code code = sendBasicCommand("AT+CGDCONT=1,PPP," + apn, 1000);
         if (code != MTS_SUCCESS) {
-            return code;
+            return code; //This will return whatever is not MTS_SUCCESS
         }
         this->apn = apn;
         return code; //This will return MTS_SUCCESS
@@ -688,17 +587,6 @@
     }
 }
 
-void EasyIP::reset()
-{
-    disconnect();
-    if(sendBasicCommand("AT#REBOOT", 10000) != MTS_SUCCESS) {
-        logError("Socket Modem did not accept RESET command\n\r");
-    } else {
-        logWarning("Socket Modem is resetting, allow 30 seconds for it to come back\n\r");
-        return;
-    }
-}
-
 std::string EasyIP::getDeviceIP()
 {
     return local_address;
@@ -776,3 +664,117 @@
 
     return MTS_SUCCESS;
 }
+
+bool EasyIP::sendEscapeCommand()
+{
+    //string Cellular::sendCommand(const std::string& command, unsigned int timeoutMillis, char esc)
+    if(io == NULL) {
+        logError("MTSBufferedIO not set");
+        return false;
+    }
+    if(!socketOpened) {
+        logError("Socket is not open. Can not send AT escape sequence (+++)");
+        return false;
+    }
+    
+    if(!socketCloseable) {
+        logError("Socket is not closeable");
+        return false;
+    }
+    
+    io->rxClear();
+    io->txClear();
+    
+    std::string result;
+    unsigned int timeoutMillis = 2000;
+    const int size_cmd = 3;
+    //Attempt to write command
+    wait(1); //Format for +++ command is 1 second wait, send +++, then another second wait
+             //1s wait after command is implemented as a polling function for 2 seconds
+             //Option: Could change wait periods to be longer/shorter (0-255)*50ms
+    if(io->write("+++", size_cmd, timeoutMillis) != size_cmd) {
+        //Failed to write command
+        logError("failed to send command to radio within %d milliseconds", timeoutMillis);
+        return false;
+    }
+    
+    int timer = 0;
+    char tmp[256];
+    tmp[255] = 0;
+    bool done = false;
+    io->read(tmp,255,0);
+    bool exitmode = false;
+    
+    do {
+        wait(0.1);
+        timer += 100;
+        //Make a non-blocking read call by passing timeout of zero
+            int size = io->read(tmp,255,0);    //1 less than allocated (timeout is instant)
+            if(size > 0) {
+                result.append(tmp, size);
+            }
+        if(result.find("OK") != std::string::npos) {
+            exitmode = true;
+            done = true;
+        } else if(result.find("NO CARRIER") != std::string::npos) {
+            exitmode = true;
+            done = true;
+        } else if(result.find("ERROR") != std::string::npos) {
+            exitmode = false;
+            done = true;
+        }
+        if(timer >= timeoutMillis) {
+            logDebug("Escape sequence [+++] timed out after %d milliseconds", timeoutMillis);
+            exitmode = true;
+            done = true;
+        }
+    } while (!done);
+    
+    return exitmode;
+}
+
+bool EasyIP::socketCheck() {
+    bool status = false;
+    std::string socketInfo = "9"; //9 is unrecognized
+    std::vector<std::string> params;
+    
+    //Goes from data mode to command mode
+    if(sendEscapeCommand()) {
+        socketOpened = false;
+        if(sendBasicCommand("AT", 1000) == MTS_SUCCESS) {
+            socketInfo = sendCommand("AT#SS=1", 2000);
+            if(socketInfo.find("OK") != std::string::npos) {
+                //Found valid response
+                params = Text::split(socketInfo, "\r\n");
+                params = Text::split(params[1], ",");
+                socketInfo = params[1];
+                //Check comparison of params[1] to response codes
+            } else {
+                logError("Could not determine socket status[%s]",socketInfo.c_str());
+                socketInfo == "9"; //9 is unrecognized
+            }
+        }
+    } else {
+        status = false; //Return value of socketOpened when checking
+    }
+    
+    //Check socket status query
+    if(socketInfo == "2" || socketInfo == "3" || socketInfo == "1" || socketInfo == "4") {
+        status = true; //2 and 3 are suspended connections
+    } else if(socketInfo == "0" || socketInfo == "5") {
+        status = false; //0 is closed socket, probably won't occur
+    } else {
+        logError("Could not determine socket status");
+        status = false; //anything else is unknown status
+    }
+    
+    //Reconnects to active socket if able
+    if(status) {
+        std::string reconnect = sendCommand("AT#SO=1", 2000);
+        if(reconnect.find("CONNECT") != std::string::npos || reconnect.find("OK") != std::string::npos) {
+        } else {
+            logError("Failed to resume socket connection");
+        }
+    }
+    return status;
+}
--- a/Cellular/EasyIP.h	Tue Jul 15 20:37:08 2014 +0000
+++ b/Cellular/EasyIP.h	Wed Jul 16 14:26:10 2014 +0000
@@ -9,33 +9,24 @@
 
 namespace mts
 {
-/** This is a class for communicating without a Multi-Tech Systems SocketModem iCell. Instead, 
-* it uses the hayes command set to implement the same commands and functions as the UIP class.
-* (See the UIP class and documentation, "UIP.h")
-* 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.
-* The default baud rate for the cellular radio is 115200 bps.
-*/
-class EasyIP : public Cellular     //Inherits from Cellular.
+    /** This is a class for communicating without a Multi-Tech Systems SocketModem iCell. Instead, 
+    * it uses the hayes command set to directly implement the same UIP interface to the radio.
+    * (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.
+    */
+class EasyIP : public Cellular
 {
-private:
-    /*Function that sends +++ to radio to exit data mode
-      returns true if successful exit from online mode, else false
-    */
-    virtual bool sendEscapeCommand(); 
-    /*Switches to command mode, queries socket connection status,
-      then returns true if there is an active socket connection, 
-      else it returns false.*/
-    virtual bool socketCheck();
 public:
-/** This static function is used to create or get a reference to a
+    /** 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
@@ -53,13 +44,38 @@
     /** Destructs a Cellular object and frees all related resources.
     */
     ~EasyIP();
-
+    /** Initializes the MTS IO buffer
+     * INCOMPLETE
+    */
     virtual bool init(MTSBufferedIO* io);
-
-    // Wifi connection based commands derived from CommInterface.h
+    
+    /** 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
@@ -72,12 +88,19 @@
     virtual int write(const char* data, int length, int timeout = -1);
     virtual unsigned int readable();
     virtual unsigned int writeable();
-    virtual bool ping(const std::string& address = "8.8.8.8"); //Google DNS server
+    virtual bool ping(const std::string& address = "8.8.8.8"); //Google DNS server used as default ping address
     virtual std::string getDeviceIP();
-    virtual bool setDeviceIP(std::string address = "DHCP");//Runs DHCP to configure the IP
+    virtual bool setDeviceIP(std::string address = "DHCP");
     
-    //Sets the APN, also sets mode to IP, might need to change
+    /** 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);
+    
     /** A method for configuring command ehco capability on the radio. This command
     * sets whether sent characters are echoed back from the radio, in which case you
     * will receive back every command you send.
@@ -88,18 +111,44 @@
     virtual Code echo(bool state);
 
     /** This method can be used to trade socket functionality for performance.
-    * In order to enable a socket connection to be closed by the client side programtically,
-    * this class must process all read and write data on the socket to guard the special
-    * escape character used to close an open socket connection. It is recommened that you
-    * use the default of true unless the overhead of these operations is too significant.
+    * Can disable checking socket closed messages from the data socket, and thus the socket
+    * will only be visibly closed to the local side if the radio is explicitly checked, or
+    * the socket is closed by the local side through the use of physical pin manipulation.
+    *
+    * Uses the Hayes escape sequence (1 second pause, "+++", 1 second pause) to exit the socket
+    * connection to check if a received "NO CARRIER" string is from the radio indicating the socket
+    * has been closed, or is merely part of the data stream. Should not occur very often, however, if 
+    * data carrying the string "NO CARRIER" is going to be transmitted frequently, then the socket should
+    * be set closeable and physical-socket-closing-means be used instead to reduce the large amount of
+    * overhead switching from checking the validity of the "NO CARRIER" message being and indication of
+    * the socket connection being closed.
     *
     * @param enabled set to true if you want the socket closeable, otherwise false. The default
     * is true.
     * @returns the standard AT Code enumeration.
     */
-    virtual Code setSocketCloseable(bool enabled = true);  //ETX closes socket (ETX and DLE in payload are escaped with DLE)
+    virtual Code setSocketCloseable(bool enabled = true);
+    
+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
+#endif /* SMC_H */
--- a/Cellular/UIP.h	Tue Jul 15 20:37:08 2014 +0000
+++ b/Cellular/UIP.h	Wed Jul 16 14:26:10 2014 +0000
@@ -46,7 +46,7 @@
     * 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.
+    * @returns a reference to the single Cellular object that has been created.
     */
     UIP(Radio type);