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:
Mon Jul 21 20:14:18 2014 +0000
Parent:
34:7d412c989964
Child:
36:948d06b3e23c
Commit message:
Cellular.cpp Fixed char-delay causing failed SMS.; EasyIP.cpp Added closed-connection checking.; TestSMS.h Added SIM-not-ready checking loop before starting SMS test.

Changed in this revision

Cellular/Cellular.cpp 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
Test/TestSMS.h Show annotated file Show diff for this revision Revisions of this file
--- a/Cellular/Cellular.cpp	Wed Jul 16 15:05:10 2014 +0000
+++ b/Cellular/Cellular.cpp	Mon Jul 21 20:14:18 2014 +0000
@@ -197,7 +197,9 @@
             return "";
         }
     }
-
+    int time_done = 0;
+    //Time in 100s of milliseconds maximum between character transmissions
+    const int MAX_INPUT_DELAY = 2;
     int timer = 0;
     size_t previous = 0;
     char tmp[256];
@@ -207,7 +209,7 @@
     do {
         wait(0.1);
         timer += 100;
-
+        
         previous = result.size();
         //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)
@@ -220,7 +222,16 @@
                 started = true;
             }
         } else {
-            done =  (result.size() == previous);
+            //Uses an timer to make sure no characters are received
+            //within a period of time after the last recevied character.
+            if(result.size() == previous) {
+                time_done++;
+                if(time_done > MAX_INPUT_DELAY) {
+                    done = true;
+                }
+            } else {
+                time_done = 0;
+            }
         }
         if(timer >= timeoutMillis) {
             if (command != "AT" && command != "at") {
@@ -257,9 +268,9 @@
         logError("CSMP failed [%s]", getRadioNames(type).c_str());
         return code;
     }
-    string cmd = "AT+CMGS=\"+";
+    string cmd = "AT+CMGS=\"";
     cmd.append(phoneNumber);
-    cmd.append("\",145");
+    cmd.append("\"");
     for (int i = 0; i < 5; i++) {
         string response1 = sendCommand(cmd, 1000);
         if (response1.find('>') != string::npos) {
@@ -295,7 +306,7 @@
         return vSms;
     }
     
-    received = sendCommand("AT+CMGL=\"ALL\"", 4000);
+    received = sendCommand("AT+CMGL=\"ALL\"", 5000);
     pos = received.find("+CMGL: ");
 
     while (pos != std::string::npos) {
@@ -304,7 +315,6 @@
         if(line.find("+CMGL: ") == std::string::npos) {
             continue;
         }
-
         //Start of SMS message
         std::vector<std::string> vSmsParts = Text::split(line, ',');
         if (type == MTSMC_H5_IP || type == MTSMC_H5) {
@@ -349,7 +359,6 @@
             //This must be the last SMS message
             bodyEnd = received.find("\r\n\r\nOK", pos);
         }
-
         //Safety check that we found the boundary of this current SMS message
         if(bodyEnd != std::string::npos) {
             sms.message = received.substr(pos, bodyEnd - pos);
--- a/Cellular/EasyIP.cpp	Wed Jul 16 15:05:10 2014 +0000
+++ b/Cellular/EasyIP.cpp	Mon Jul 21 20:14:18 2014 +0000
@@ -45,6 +45,9 @@
 
     logDebug("radio type: %s", Cellular::getRadioNames(type).c_str());
     //Turns on the HW flow control, equiv. to AT&K
+    if(sendBasicCommand("AT&K=3", 2000) != MTS_SUCCESS) {
+        logWarning("Failed to set flow control to radio");
+    }
     if(sendBasicCommand("AT+IFC=2,2", 2000) != MTS_SUCCESS) {
         logWarning("Failed to set flow control to radio");
     }
@@ -77,6 +80,7 @@
     //Check Registration: AT+CREG? == 0,1
     //(Does the AT command inside Cellular class)
     tmr.start();
+    
     do {
         Registration registration = getRegistration();
         if(registration != REGISTERED) {
@@ -108,7 +112,7 @@
     }
     //The main thing going on; Sends the AT command to start a connection
     //Assuming context is already stored in the modem
-    std::string pppResult = sendCommand("AT#SGACT=1,1", 2000);
+    std::string pppResult = sendCommand("AT#SGACT=1,1", 5000);
     std::vector<std::string> parts;
     if(pppResult.find("OK") != std::string::npos) {
         parts = Text::split(pppResult, "\r\n");
@@ -125,6 +129,7 @@
             pppConnected = false;
         } else {
             if(pppResult.find("1,1") != std::string::npos) {
+                logDebug("Radio is already connected");
                 pppConnected = true;
             } else {
                 pppConnected = false;
@@ -146,12 +151,32 @@
                     //(and thus need socket closed)
         }
     }
+    std::string result;
+    Timer tmr;
     //Sends AT#SGACT=1,0 command
-    if(sendBasicCommand("AT#SGACT=1,0", 1000) == MTS_SUCCESS) {
+    if (sendBasicCommand("AT#SGACT=1,0", 1000) == MTS_SUCCESS) {
         pppConnected = false;
         logDebug("Successfully closed PPP Connection");
     }
-    pppConnected = false; //Cell will drop connection if we go silent
+    
+    tmr.start();
+    while(tmr.read() < 30) {
+        result = sendCommand("AT#SGACT?", 1000);
+        if(result.find("1,0") != std::string::npos) {
+            pppConnected = false;
+            break;
+        } else if(result.find("ERROR") != std::string::npos) {
+            break;
+        } else {
+            wait(1);
+        }
+    }
+    
+    if(pppConnected) {
+        wait(30);
+        pppConnected = false;
+    }
+    
     return;
 }
 
@@ -252,7 +277,6 @@
             if(active) {
                 if(ping()) {
                     pppConnected = true;
-                    logWarning("Internal PPP state tracking differs from radio (DISCONNECTED:CONNECTED)");
                     stateString = "CONNECTED";
                 } else {
                     stateString = "CONNECTING";
@@ -263,14 +287,15 @@
         }
     } else if(regist != signal) {
         stateString = "CHECKING";
-        pppConnected = false;
+        return false;
     } else if(!regist && !signal) {
         stateString = "DISCONNECTED";
         pppConnected = false;
     }
-    //Log results if necessary
-    if(stateString != "CONNECTED") {
-        logWarning("Internal PPP state tracking differs from radio (CONNECTED:%s)",stateString.c_str());
+    
+    std::string pppStatus = pppConnected ? "CONNECTED" : "DISCONNECTED";
+    if(stateString != pppStatus) {
+        logDebug("Internal PPP state[%s], radio state[%s])",pppStatus.c_str() ,stateString.c_str());
     }
     return pppConnected;
 }
@@ -341,11 +366,6 @@
             logDebug("PPP connection established");
         }
     }
-    //No way to "set" port except on socket call;
-    //Going to need to warn if local_port was not set.
-    if(!local_port) {
-        logDebug("No local port was set: 0");
-    }
     
     //4) Set escape sequence to not be transmitted
     if(sendBasicCommand("AT#SKIPESC=1", 2000) != MTS_SUCCESS) {
@@ -367,7 +387,7 @@
     }
     //5) Open Socket  
     sprintf(sOpenSocketCmd, "AT#SD=1,%d,%d,%s,%d,%d,0", typeSocket, port, address.c_str(),closeType , local_port);
-    std::string response = sendCommand(sOpenSocketCmd, 5000);
+    std::string response = sendCommand(sOpenSocketCmd, 140000);
     
     if(response.find("CONNECT") != std::string::npos) {
         host_address = address;
@@ -460,9 +480,10 @@
     } else {
         bytesRead = io->read(data, max);
     }
+    
+    //Scan for socket closed message
     if(bytesRead > 0 && socketCloseable) {
-        //Scan for socket closed message
-        for(size_t i = 0; i < bytesRead; i++) {
+        for(int i = 0; i < bytesRead; i++) {
             if(data[i] == 'N') {
                 if(strstr(&data[i], "NO CARRIER")) {
                     logTrace("Found socket closed message. Checking validity");
@@ -618,7 +639,9 @@
     sprintf(buffer, "AT#PING=%s,1,32,%d", address.c_str(), (PINGDELAY*10));
     
     for(int pngs=0; pngs<PINGNUM; pngs++) {
-        std::string response = sendCommand(buffer, (PINGDELAY*1010)); //Send 1 ping
+        std::string response = sendCommand(buffer, (PINGDELAY*2000)); //Send 1 ping
+        wait(0.5); //Radio seems to get stuck if no wait is incurred between issuing ping commands
+                   //leads to unknown registration state eventually :(
         if(response.empty()) {
             continue; //Skip current loop if send command fails
         }
@@ -673,8 +696,7 @@
         return false;
     }
     if(!socketOpened) {
-        logError("Socket is not open. Can not send AT escape sequence (+++)");
-        return false;
+        logError("Socket is not open. +++ Escape sequence should fail");
     }
     
     if(!socketCloseable) {
@@ -686,10 +708,10 @@
     io->txClear();
     
     std::string result;
-    unsigned int timeoutMillis = 2000;
+    unsigned int timeoutMillis = 20000; //20s
     const int size_cmd = 3;
     //Attempt to write command
-    wait(1); //Format for +++ command is 1 second wait, send +++, then another second wait
+    wait(1.2); //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) {
--- a/Test/TestSMS.h	Wed Jul 16 15:05:10 2014 +0000
+++ b/Test/TestSMS.h	Mon Jul 21 20:14:18 2014 +0000
@@ -22,7 +22,7 @@
 TestSMS::TestSMS() : TestCollection("TestSMS") {}
 
 void TestSMS::run() {
-    const char APN[] = "";
+    const char APN[] = "b2b.tmobile.com";
     
     string number;
     string response;
@@ -56,6 +56,18 @@
         }
     }
     
+    //For determining when the SIM card is ready
+    std::string result;
+    for (int i = 0; i < 25; i++) {
+        if (i >= 25) {
+            Test::assertTrue(false);
+        }
+        if(radio->sendBasicCommand("AT+CMGD=1,4", 1000) == MTS_SUCCESS) {
+            break;
+        }
+        wait(1);
+    }
+    
     Test::assertTrue(radio->deleteAllReceivedSms() == MTS_SUCCESS);
     Test::assertTrue(radio->getReceivedSms().size() == 0);
     Test::end();
@@ -67,16 +79,17 @@
         if (response.find("ERROR") == string::npos && response.find("error") == string::npos) {
             break;
         }
-        
         wait(1);
     }
-    if (response.find("My Number") != string::npos) {
+    //Response doesn't contain "My Number", and thus will always fail
+    //Code seems to not be the same for UIP versus EasyIP
+    if (response.find("+CNUM:") != string::npos) {
         parts = Text::split(response, ",");
         number = parts[1];
         size_t fquote = number.find("\"");
         size_t bquote = number.rfind("\"");
         number = number.substr(fquote + 1, bquote - 1);
-        logInfo("my phone number: [%s]", number.c_str());
+        logInfo("My phone number: [%s]", number.c_str());
     } else {
         Test::assertTrue(false);
     }