Cellular library for MTS Socket Modem Arduino Shield devices from Multi-Tech Systems
Dependents: mtsas mtsas mtsas mtsas
Revision 35:257eb41405e1, committed 2014-07-21
- 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
--- 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); }