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:
35:f28acb1be52d
Parent:
33:e04aa7c013c9
Child:
37:61373f492403
Child:
39:6e94520a3217
Child:
41:81d035fb0b6a
--- a/cellular/Cellular.cpp	Wed Dec 18 23:05:31 2013 +0000
+++ b/cellular/Cellular.cpp	Thu Dec 19 15:56:05 2013 +0000
@@ -212,23 +212,39 @@
 }
 
 bool Cellular::close() {
-    if(!socketOpened) {
-        printf("[ERROR] Socket is not open\r\n");
+    if(io == NULL) {
+        printf("[ERROR] MTSBufferedIO not set\r\n");
         return false;
     }
-    
+
+    if(!socketOpened) {
+        printf("[WARNING] Socket close() called, but socket was not open\r\n");
+        return true;
+    }
+
     if(!socketCloseable) {
         printf("[ERROR] Socket is not closeable\r\n");
         return false;
     }
     
-    //Build Escape Message => ETX
-    char buffer[2] = { 0x03, 0x00 };
-    Code code = sendBasicCommand(buffer, 1000, NONE);
-    if(code != OK) {
-        printf("[ERROR] Radio did not accept close socket command\r\n");
+    Timer tmr;
+    int timeout = 1000;
+    int written = 0;
+    tmr.start();
+    do {
+        written = io->write(ETX);
+        if(written < 0) {
+            printf("[ERROR] Failed to write to MTSBufferedIO\r\n");
+            return false;   
+        }
+        wait(0.05);
+    } while(tmr.read_ms() <= timeout && written != 1);
+
+    if(written != 1) {
+        printf("[ERROR] Timed out attempting to close socket\r\n");
         return false;
     }
+    
     socketOpened = false;
     return true;
 }
@@ -248,7 +264,7 @@
     if(timeout >= 0) {
         Timer tmr;
         tmr.start();
-        while (tmr.read_ms() <= timeout && bytesRead < max) {
+        do {
             int available = io->readable();
             if (available > 0) {
                 int size = MIN(available, max - bytesRead);
@@ -256,7 +272,7 @@
             } else {
                 wait(0.05);   
             }
-        }
+        } while (tmr.read_ms() <= timeout && bytesRead < max);
     } else {
         bytesRead = io->read(data, max);
     }
@@ -318,23 +334,77 @@
         return -1;
     }
     
+    //In order to avoid allocating another buffer, capture indices of
+    //characters to escape during write
+    int specialWritten = 0;
+    std::vector<int> vSpecial;
+    if(socketCloseable) {
+        for(int i = 0; i < length; i++) {
+            if(data[i] == ETX || data[i] == DLE) {
+                //Push back index of special characters
+                vSpecial.push_back(i);
+            }                   
+        }
+    }
+    
     int bytesWritten = 0;
-    
     if(timeout >= 0) {
         Timer tmr;
         tmr.start();
-        while (tmr.read_ms() <= timeout && bytesWritten < length) {
-            if (io->writeable()) {
-                if(io->write(*data) == 1) {
-                    data++;
-                    bytesWritten++;
+        do {
+            int capacity = io->writeable();
+            if (capacity > 0) {
+                if(specialWritten < vSpecial.size()) {
+                    //Check if current index is at a special character
+                    if(bytesWritten == vSpecial[specialWritten]) {
+                        if(capacity < 2) {
+                            //Requires at least two bytes of space
+                            wait(0.05);
+                            continue;   
+                        }
+                        //Ready to write special character    
+                        if(io->write(DLE)) {
+                            specialWritten++;
+                            if(io->write(data[bytesWritten])) {
+                                bytesWritten++;
+                            }
+                        } else {
+                            //Unable to write escape character, try again next round
+                            wait(0.05);
+                        }
+                    } else {
+                        //We want to write all the way up to the next special character    
+                        int relativeIndex = vSpecial[specialWritten] - bytesWritten;
+                        int size = MIN(capacity, relativeIndex);
+                        bytesWritten += io->write(&data[bytesWritten], size);
+                    }                    
+                } else {                
+                    int size = MIN(capacity, length - bytesWritten);
+                    bytesWritten += io->write(&data[bytesWritten], size);
                 }
             } else {
-                wait(0.05);
+                wait(0.05);   
+            }
+        } while (tmr.read_ms() <= timeout && bytesWritten < length);
+    } else {
+        for(int i = 0; i < vSpecial.size(); i++) {
+            //Write up to the special character, then write the special character
+            int size = vSpecial[i] - bytesWritten;
+            int currentWritten = io->write(&data[bytesWritten], size);
+            bytesWritten += currentWritten;
+            if(currentWritten != size) {
+                //Failed to write up to the special character.
+                return bytesWritten;
+            }
+            if(io->write(DLE) && io->write(data[bytesWritten])) {
+                bytesWritten++;
+            } else {
+                //Failed to write the special character.
+                return bytesWritten;
             }
         }
-    } else {
-        bytesWritten = io->write(data, length);
+    
+        bytesWritten = io->write(&data[bytesWritten], length - bytesWritten);
     }
     
     return bytesWritten;