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:
96:27bdf4aa3a31
Parent:
92:57d4838f9861
Child:
101:27bb34e23304
--- a/cellular/Cellular.cpp	Fri Dec 27 23:55:18 2013 +0000
+++ b/cellular/Cellular.cpp	Mon Dec 30 18:55:48 2013 +0000
@@ -14,12 +14,45 @@
     return instance;
 }
 
+Cellular::Cellular(MTSBufferedIO* io)
+    : io(io)
+    , echoMode(true)
+    , pppConnected(false)
+    , mode(TCP)
+    , socketOpened(false)
+    , socketCloseable(true)
+    , local_port(0)
+    , host_port(0)
+    , dcd(NULL)
+    , dtr(NULL)
+{
+}
+
+Cellular::~Cellular()
+{
+    if (dtr != NULL) {
+        dtr->write(1);
+    }
+    
+    delete dcd;
+    delete dtr;
+}
 
 bool Cellular::init(MTSBufferedIO* io, PinName DCD, PinName DTR)
 {
     if (io == NULL) {
         return false;
     }
+    
+    if(dcd) {
+        delete dcd;
+        dcd = NULL;    
+    }
+    if(dtr) {
+        delete dtr;
+        dtr = NULL;
+    }
+    
     if (DCD != NC) {
         // the radio will raise and lower this line
         dcd = new DigitalIn(DCD); //PTA4 - KL46
@@ -32,27 +65,10 @@
         dtr->write(0);
     }
     instance->io = io;
-    return true;
+    
+    return (test() == SUCCESS);
 }
 
-Cellular::Cellular(MTSBufferedIO* io)
-    : io(io)
-    , echoMode(true)
-    , pppConnected(false)
-    , mode(TCP)
-    , socketOpened(false)
-    , socketCloseable(true)
-    , local_port(0)
-    , host_port(0)
-{
-}
-
-Cellular::~Cellular()
-{
-    if (dtr != NULL) {
-        dtr->write(1);
-    }
-}
 
 bool Cellular::connect()
 {
@@ -61,31 +77,43 @@
         return true;
     }
 
-    //Run Test first to validate a good state
+    //Check if already connected
     if(isConnected()) {
         return true;
     }
+    
+    Timer tmr;
+    
+    //Check Registration: AT+CREG? == 0,1
+    tmr.start();
+    do {
+        Registration registration = getRegistration();
+        if(registration != REGISTERED) {
+            printf("[WARNING] Not Registered [%d] ... waiting\r\n", (int)registration);
+            wait(1);
+        } else {
+            break;
+        }
+    } while(tmr.read() < 30);
 
     //Check RSSI: AT+CSQ
-    int rssi = getSignalStrength();
-    printf("[DEBUG] Signal strength: %d\r\n", rssi);
-
-    //Check Registration: AT+CREG? == 0,1
-    Registration registration = getRegistration();
-    if(registration != REGISTERED) {
-        printf("[WARNING] Not Registered [%d]\r\n", (int)registration);
-    }
+    tmr.reset();
+    do {
+        int rssi = getSignalStrength();
+        printf("[DEBUG] Signal strength: %d\r\n", rssi);
+        if(rssi == 99) {
+           printf("[WARNING] No Signal ... waiting\r\n");
+           wait(1);
+        } else {
+            break;   
+        }
+    } while(tmr.read() < 30);    
 
     //AT#CONNECTIONSTART: Make a PPP connection
     printf("[DEBUG] Making PPP Connection Attempt. APN[%s]\r\n", apn.c_str());
     std::string pppResult = sendCommand("AT#CONNECTIONSTART", 120000);
     std::vector<std::string> parts = Text::split(pppResult, "\r\n");
 
-    //printf("[DEBUG] PPP CONNECT RESULT [%s]\r\n", pppResult.c_str());
-//    for(uint32_t i = 0; i < parts.size(); i++) {
-//        printf("[%d] [%s]\r\n", i, parts[i].c_str());
-//    }
-
     if(pppResult.find("Ok_Info_GprsActivation") != std::string::npos) {
         if(parts.size() >= 2) {
             local_address = parts[1];
@@ -160,16 +188,15 @@
 {
     char buffer[256] = {0};
     Code portCode, addressCode;
-    printf("[DEBUG] Attempting to Open Socket\r\n");
 
     //1) Check that we do not have a live connection up
     if(socketOpened) {
         //Check that the address, port, and mode match
         if(host_address != address || host_port != port || this->mode != mode) {
             if(this->mode == TCP) {
-                printf("[ERROR] TCP socket already opened (%s:%d)\r\n", host_address.c_str(), host_port);
+                printf("[ERROR] TCP socket already opened [%s:%d]\r\n", host_address.c_str(), host_port);
             } else {
-                printf("[ERROR] UDP socket already opened (%s:%d)\r\n", host_address.c_str(), host_port);
+                printf("[ERROR] UDP socket already opened [%s:%d]\r\n", host_address.c_str(), host_port);
             }
             return false;
         }
@@ -184,7 +211,6 @@
         return false;
     }
 
-
     //3) Check PPP connection
     if(!isConnected()) {
         printf("[ERROR] PPP not established.  Attempting to connect\r\n");
@@ -195,7 +221,7 @@
             printf("[DEBUG] PPP connection established\r\n");
         }
     }
-
+    
     //Set Local Port
     if(local_port != 0) {
         //Attempt to set local port
@@ -241,8 +267,6 @@
         printf("[ERROR] Host address could not be set\r\n");
     }
 
-
-
     // Try and Connect
     std::string sMode;
     std::string sOpenSocketCmd;
@@ -253,6 +277,7 @@
         sOpenSocketCmd = "AT#OUDP";
         sMode = "UDP";
     }
+    
     string response = sendCommand(sOpenSocketCmd, 30000);
     if (response.find("Ok_Info_WaitingForData") != string::npos) {
         printf("[INFO] Opened %s Socket [%s:%d]\r\n", sMode.c_str(), address.c_str(), port);
@@ -466,11 +491,11 @@
 unsigned int Cellular::readable()
 {
     if(io == NULL) {
-        printf("[ERROR] MTSBufferedIO not set\r\n");
+        printf("[WARNING] MTSBufferedIO not set\r\n");
         return 0;
     }
-    if(!socketOpened) {
-        printf("[ERROR] Socket is not open\r\n");
+    if(!socketOpened && !io->readable()) {
+        printf("[WARNING] Socket is not open\r\n");
         return 0;
     }
     return io->readable();
@@ -479,11 +504,11 @@
 unsigned int Cellular::writeable()
 {
     if(io == NULL) {
-        printf("[ERROR] MTSBufferedIO not set\r\n");
+        printf("[WARNING] MTSBufferedIO not set\r\n");
         return 0;
     }
     if(!socketOpened) {
-        printf("[ERROR] Socket is not open\r\n");
+        printf("[WARNING] Socket is not open\r\n");
         return 0;
     }
 
@@ -503,16 +528,26 @@
 
 Code Cellular::test()
 {
-    Code code = sendBasicCommand("AT", 1000);
+    bool basicRadioComms = false;
+    Code code;
+    Timer tmr;
+    tmr.start();
+    do {
+        printf("[DEBUG] Attempting basic radio communication\r\n");
+        code = sendBasicCommand("AT", 1000);
+        if(code == SUCCESS) {
+            basicRadioComms = true;
+            break;   
+        } else {
+            wait(1);   
+        }
+    } while(tmr.read() < 15);
 
-    if(code != SUCCESS) {
-        printf("[Error] Failed basic AT command");
-        return code;
+    if(!basicRadioComms) {
+        printf("[ERROR] Unable to communicate with the radio\r\n");
+        return FAILURE;
     }
-
-    //AT#VSTATE != "CHECKING"
-
-    //AT#GPRSMODE ==
+    
     return SUCCESS;
 }
 
@@ -545,7 +580,7 @@
 
 Cellular::Registration Cellular::getRegistration()
 {
-    string response = sendCommand("AT+CREG?", 1000);
+    string response = sendCommand("AT+CREG?", 5000);
     if (response.find("OK") == string::npos) {
         return UNKNOWN;
     }
@@ -571,25 +606,6 @@
     return UNKNOWN;
 }
 
-Code Cellular::sendBasicCommand(const std::string& command, unsigned int timeoutMillis, char esc)
-{
-    if(socketOpened) {
-        printf("[ERROR] socket is open. Can not send AT commands\r\n");
-        return ERROR;
-    }
-
-    string response = sendCommand(command, timeoutMillis, esc);
-    if (response.size() == 0) {
-        return NO_RESPONSE;
-    } else if (response.find("OK") != string::npos) {
-        return SUCCESS;
-    } else if (response.find("ERROR") != string::npos) {
-        return ERROR;
-    } else {
-        return FAILURE;
-    }
-}
-
 Code Cellular::setApn(const std::string& apn)
 {
     Code code = sendBasicCommand("AT#APNSERV=\"" + apn + "\"", 1000);
@@ -744,6 +760,24 @@
     return sendBasicCommand("AT+CMGD=1,4", 1000);
 }
 
+Code Cellular::sendBasicCommand(const std::string& command, unsigned int timeoutMillis, char esc)
+{
+    if(socketOpened) {
+        printf("[ERROR] socket is open. Can not send AT commands\r\n");
+        return ERROR;
+    }
+
+    string response = sendCommand(command, timeoutMillis, esc);
+    if (response.size() == 0) {
+        return NO_RESPONSE;
+    } else if (response.find("OK") != string::npos) {
+        return SUCCESS;
+    } else if (response.find("ERROR") != string::npos) {
+        return ERROR;
+    } else {
+        return FAILURE;
+    }
+}
 
 string Cellular::sendCommand(const std::string& command, unsigned int timeoutMillis, char esc)
 {