A library for talking to Multi-Tech's Cellular SocketModem Devices.

Dependents:   M2X_dev axeda_wrapper_dev MTS_M2x_Example1 MTS_Cellular_Connect_Example ... more

Revision:
98:dbeac735109d
Parent:
95:4fdf968b5b37
Child:
99:eba6b99bc80c
--- a/wifi/Wifi.cpp	Mon Dec 30 17:46:11 2013 +0000
+++ b/wifi/Wifi.cpp	Mon Dec 30 20:02:21 2013 +0000
@@ -19,7 +19,6 @@
     instance->io = io;
     //Set device into command mode
     if (!setCmdMode(true)) {
-        printf("[ERROR] Failed to set command mode\n\r");
         return false;
     }
 
@@ -84,11 +83,8 @@
         return false;
     }
 
-    if (!cmdOn) {
-        if(!setCmdMode(true)) {
-            printf("[ERROR] Failed to enter command mode\n\r");
-            return false;
-        }
+    if(!setCmdMode(true)) {
+        return false;
     }
 
     //Check RSSI: AT+CSQ
@@ -129,10 +125,8 @@
         close();
     }
 
-    if (!cmdOn) {
-        if(!setCmdMode(true)) {
-            printf("[ERROR] Failed to enter command mode\n\r");
-        }
+    if(!setCmdMode(true)) {
+        printf("[ERROR] Failed in disconnecting from network.  Continuing ...\r\n");
     }
 
     std::string response = sendCommand("leave", 20000);
@@ -160,6 +154,11 @@
         return true;
     }
 
+    //Check command mode.
+    if(!setCmdMode(true)) {
+        return false;
+    }
+
     //2) Query the wifi module
     wifiConnected = false;
     std::string result = sendCommand("show net", 5000, "Links");
@@ -227,11 +226,8 @@
     }
 
     //Check command mode
-    if (!cmdOn) {
-        if(!setCmdMode(true)) {
-            printf("[ERROR] Failed to enter command mode\n\r");
-            return false;
-        }
+    if(!setCmdMode(true)) {
+        return false;
     }
 
     //Set Local Port
@@ -279,6 +275,7 @@
     if (response.find("OPEN") != string::npos) {
         printf("[INFO] Opened %s Socket [%s:%d]\r\n", sMode.c_str(), address.c_str(), port);
         socketOpened = true;
+        cmdOn = false; //Need to make sure that this is true...
     } else {
         printf("[WARNING] Unable to open %s Socket [%s:%d]\r\n", sMode.c_str(),  address.c_str(), port);
         socketOpened = false;
@@ -304,15 +301,14 @@
         return true;
     }
 
-    if (!cmdOn) {
-        if(!setCmdMode(true)) {
-            printf("[ERROR] Failed to enter command mode\n\r");
-        }
+    if(!setCmdMode(true)) {
+        printf("[ERROR] Failed to close socket\r\n");
+        return false;
     }
 
     std::string response = sendCommand("close", 10000, "CLOS");
-    if(response.find("CLOS" == string::npos)) {
-        printf("[ERROR] Timed out attempting to close socket\r\n");
+    if(response.find("CLOS") == string::npos) {
+        printf("[ERROR] Failed to successfully close socket\r\n");
         return false;
     }
 
@@ -322,12 +318,112 @@
 
 int Wifi::read(char* data, int max, int timeout)
 {
-    return 0;
+    if(io == NULL) {
+        printf("[ERROR] MTSBufferedIO not set\r\n");
+        return -1;
+    }
+
+    //Check that nothing is in the rx buffer
+    if(!socketOpened && !io->readable()) {
+        printf("[ERROR] Socket is not open\r\n");
+        return -1;
+    }
+
+    //Check for data mode
+    if(!setCmdMode(false)) {
+        printf("[ERROR] Failed to read data due to mode\r\n");
+        return -1;
+    }
+
+    int bytesRead = 0;
+
+    if(timeout >= 0) {
+        bytesRead = io->read(data, max, static_cast<unsigned int>(timeout));
+    } else {
+        bytesRead = io->read(data, max);
+    }
+
+    if(bytesRead > 0 && socketCloseable) {
+        //Remove escape characters
+        int index = 0;
+        bool escapeFlag = false;
+        for(int i = 0; i < bytesRead; i++) {
+            if(data[i] == DLE || data[i] == ETX) {
+                if(escapeFlag == true) {
+                    //This character has been escaped
+                    escapeFlag = false;
+                } else if(data[bytesRead] == DLE) {
+                    //Found escape character
+                    escapeFlag = true;
+                    continue;
+                } else {
+                    //ETX sent without escape -> Socket closed
+                    printf("[INFO] Read ETX character without DLE escape. Socket closed\r\n");
+                    socketOpened = false;
+                    continue;
+                }
+            }
+
+            if(index != i) {
+                data[index] = data[i];
+            }
+            index++;
+        }
+        bytesRead = index;
+    }
+
+    //Scan for socket closed message
+    for(size_t i = 0; i < bytesRead; i++) {
+        if(data[i] == 'O') {
+            if(strstr(&data[i], "Ok_Info_SocketClosed")) {
+                printf("[INFO] Found socket closed message. Socket closed\r\n");
+                //Close socket and Cut Off End of Message
+                socketOpened = false;
+                data[i] = '\0';
+                bytesRead = i;
+                break;
+            }
+        }
+    }
+    return bytesRead;
 }
 
 int Wifi::write(const char* data, int length, int timeout)
 {
-    return 0;
+    if(io == NULL) {
+        printf("[ERROR] MTSBufferedIO not set\r\n");
+        return -1;
+    }
+
+    if(!socketOpened) {
+        printf("[ERROR] Socket is not open\r\n");
+        return -1;
+    }
+
+    //Check for data mode
+    if(!setCmdMode(false)) {
+        printf("[ERROR] Failed to write data due to mode\r\n");
+        return -1;
+    }
+
+    int bytesWritten = 0;
+    if(timeout >= 0) {
+        Timer tmr;
+        tmr.start();
+        do {
+            int available = io->writeable();
+            if (available > 0) {
+                int size = MIN(available, length - bytesWritten);
+                bytesWritten += io->write(&data[bytesWritten], size);
+            } else {
+                wait(0.05);
+            }
+        } while (tmr.read_ms() <= timeout && bytesWritten < length);
+    } else {
+        bytesWritten = io->write(&data[bytesWritten], length - bytesWritten);
+    }
+
+    return bytesWritten;
 }
 
 unsigned int Wifi::readable()
@@ -363,6 +459,11 @@
 
 Code Wifi::setNetwork(const std::string& ssid, const std::string& key, SecurityType type)
 {
+    //Check the command mode
+    if(!setCmdMode(true)) {
+        return FAILURE;
+    }
+
     Code code;
 
     //Set the appropraite SSID
@@ -392,13 +493,25 @@
 
 Code Wifi::setDNS(const std::string& dnsName)
 {
+    //Check the command mode
+    if(!setCmdMode(true)) {
+        return FAILURE;
+    }
+
     return sendBasicCommand("set dns name " + dnsName, 1000);
 }
 
 int Wifi::getSignalStrength()
 {
+    //Check the command mode
+    if(!setCmdMode(true)) {
+        printf("[ERROR] Could not get RSSI\n\r");
+        return -1;
+    }
+
     string response = sendCommand("show rssi", 2000, "dBm");
     if (response.find("RSSI") == string::npos) {
+        printf("[ERROR] Could not get RSSI\n\r");
         return -1;
     }
     int start = response.find('(');
@@ -411,6 +524,12 @@
 
 bool Wifi::ping(const std::string& address)
 {
+    //Check the command mode
+    if(!setCmdMode(true)) {
+        printf("[ERROR] Could not send ping command\n\r");
+        return false;
+    }
+
     std::string response;
     for (int i = 0; i < PINGNUM; i++) {
         response = sendCommand("ping " + address, PINGDELAY * 1000, "reply");
@@ -433,7 +552,7 @@
             cmdOn = true;
             return true;
         }
-        printf("Failed Response: %s\n\r", response.c_str());
+        printf("[ERROR] Failed to enter command mode\n\r");
         return false;
     } else {
         if (!cmdOn) {
@@ -444,6 +563,7 @@
             cmdOn = false;
             return true;
         }
+        printf("[ERROR] Failed to exit command mode\n\r");
         return false;
     }
 }
@@ -474,7 +594,7 @@
         printf("[ERROR] MTSBufferedIO not set\r\n");
         return "";
     }
-    if(socketOpened && command.compare("$$") != 0) {
+    if(socketOpened && command.compare("$$") != 0 && command.compare("exit") != 0) {
         printf("[ERROR] socket is open. Can not send AT commands\r\n");
         return "";
     }