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
Diff: cellular/Cellular.cpp
- 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) {