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 97:5e65d8f334d5, committed 2013-12-30
- Comitter:
- sgodinez
- Date:
- Mon Dec 30 19:00:56 2013 +0000
- Parent:
- 95:4fdf968b5b37
- Parent:
- 96:27bdf4aa3a31
- Child:
- 99:eba6b99bc80c
- Child:
- 101:27bb34e23304
- Commit message:
- Merged. Fixed compile error.
Changed in this revision
wifi/Wifi.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/cellular/Cellular.cpp Mon Dec 30 17:46:11 2013 +0000 +++ b/cellular/Cellular.cpp Mon Dec 30 19:00:56 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) {
--- a/io/MTSSerialFlowControl.cpp Mon Dec 30 17:46:11 2013 +0000 +++ b/io/MTSSerialFlowControl.cpp Mon Dec 30 19:00:56 2013 +0000 @@ -35,7 +35,11 @@ void MTSSerialFlowControl::handleRead() { while (serial.readable()) { - rxBuffer.write(serial.getc()); + char byte = serial.getc(); + if(rxBuffer.write(byte) != 1) { + printf("[ERROR] Serial Rx Byte Dropped [%c][%02X]\r\n", byte, byte); + notifyStopSending(); + } if (rxBuffer.size() > highThreshold) { notifyStopSending(); }
--- a/tests/test_TCP_Socket.h Mon Dec 30 17:46:11 2013 +0000 +++ b/tests/test_TCP_Socket.h Mon Dec 30 19:00:56 2013 +0000 @@ -2,6 +2,30 @@ #define _TEST_TCP_SOCKET_H_ using namespace mts; +const char PATTERN_LINE1[] = "abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()[]{}|"; +const char PATTERN[] = "abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()[]{}|\r\n" + "abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()[]{}/\r\n" + "abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()[]{}-\r\n" + "abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()[]{}\\\r\n" + "abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()[]{}|\r\n" + "abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()[]{}/\r\n" + "abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()[]{}-\r\n" + "abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()[]{}\\\r\n" + "abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()[]{}*"; + + +const char MENU[] = "1 send ascii pattern until keypress\r\n" + "2 send ascii pattern (numbered)\r\n" + "3 send pattern and close socket\r\n" + "4 send [ETX] and wait for keypress\r\n" + "5 send [DLE] and wait for keypress\r\n" + "6 send all hex values (00-FF)\r\n" + "q quit\r\n" + ">:\r\n"; + +const char WELCOME[] = "Connected to: TCP test server"; + +bool testTcpSocketIteration(); void testTcpSocket() { Code code; @@ -39,54 +63,15 @@ printf("Error during TCP socket open [%s:%d]\r\n", TEST_SERVER.c_str(), TEST_PORT); } - printf("Receiving Data (timeout = 15 seconds)\r\n"); - Timer tmr; - int bytesRead = 0; - const int size = 1024; - char data[size] = { 0 }; - tmr.start(); - do { - int status = Cellular::getInstance()->read(&data[bytesRead], size - bytesRead, 1000); - if(status != -1) { - bytesRead += status; - } else { - printf("Error reading from socket\r\n"); - data[bytesRead] = '\0'; - break; - } - printf("Total bytes read %d\r\n", bytesRead); - } while (tmr.read_ms() <= 15000 && bytesRead < size); - - printf("READ: [%d] [%s]\r\n", bytesRead, data); + //Find Welcome Message and Menu - - printf("Waiting 10 seconds\r\n"); - wait(10); - - printf("Writing to socket\r\n"); - sprintf(data, "3\r\n"); - int bytesWritten = Cellular::getInstance()->write(data, 4, 10000); - if(bytesWritten == 4) { - printf("Successfully wrote 'q'\r\n"); - } else { - printf("Failed to write 'q'\r\n"); + int count = 0; + while(testTcpSocketIteration()) { + count++; + printf("Successful Iterations: %d\r\n", count); } - bytesRead = 0; - tmr.start(); - do { - int status = Cellular::getInstance()->read(&data[bytesRead], size - bytesRead, 1000); - if(status != -1) { - bytesRead += status; - } else { - printf("Error reading from socket\r\n"); - data[bytesRead] = '\0'; - break; - } - printf("Total bytes read %d\r\n", bytesRead); - } while (tmr.read_ms() <= 15000 && bytesRead < size); - printf("READ: [%d] [%s]\r\n", bytesRead, data); - + printf("Closing socket\r\n"); Cellular::getInstance()->close(); @@ -96,4 +81,102 @@ Cellular::getInstance()->disconnect(); } +bool testTcpSocketIteration() { + + Timer tmr; + int bytesRead = 0; + const int bufferSize = 1024; + char buffer[bufferSize] = { 0 }; + std::string result; + + printf("Receiving Data\r\n"); + tmr.start(); + do { + int size = Cellular::getInstance()->read(buffer, bufferSize, 1000); + if(size != -1) { + result.append(buffer, size); + } else { + printf("Error reading from socket\r\n"); + return false; + } + printf("Total bytes read %d\r\n", result.size()); + } while (tmr.read() <= 15 && bytesRead < bufferSize); + + printf("READ: [%d] [%s]\r\n", bytesRead, result.c_str()); + + size_t pos = result.find(PATTERN_LINE1); + if(pos != std::string::npos) { + //compare buffers + int patternSize = sizeof(PATTERN) - 1; + const char* ptr = &result.data()[pos]; + bool match = true; + for(int i = 0; i < patternSize; i++) { + if(PATTERN[i] != ptr[i]) { + printf("1ST PATTERN DOESN'T MATCH AT [%d]\r\n", i); + printf("PATTERN [%02X] BUFFER [%02X]\r\n", PATTERN[i], ptr[i]); + match = false; + break; + } + } + if(match) { + printf("FOUND 1ST PATTERN\r\n"); + } + + pos = result.find(PATTERN_LINE1, pos + patternSize); + if(pos != std::string::npos) { + //compare buffers + ptr = &result.data()[pos]; + match = true; + for(int i = 0; i < patternSize; i++) { + if(PATTERN[i] != ptr[i]) { + printf("2ND PATTERN DOESN'T MATCH AT [%d]\r\n", i); + printf("PATTERN [%02X] BUFFER [%02X]\r\n", PATTERN[i], ptr[i]); + match = false; + break; + } + } + if(match) { + printf("FOUND 2ND PATTERN\r\n"); + } + } + } + + + + result.clear(); + + printf("Writing to socket: 2\r\n"); + if(Cellular::getInstance()->write("2\r\n", 3, 10000) == 3) { + printf("Successfully wrote '2'\r\n"); + } else { + printf("Failed to write '2'\r\n"); + return false; + } + printf("Expecting 'how many ? >:\r\n"); + bytesRead = Cellular::getInstance()->read(buffer, bufferSize, 10000); + if(bytesRead != -1) { + result.append(buffer, bytesRead); + printf("READ: [%d] [%s]\r\n", bytesRead, result.c_str()); + if(result.find("how many") != std::string::npos) { + printf("Successfully found 'how many'\r\n"); + printf("Writing to socket: 2\r\n"); + if(Cellular::getInstance()->write("2\r\n", 3, 10000) == 3) { + printf("Successfully wrote '2'\r\n"); + } else { + printf("Failed to write '2'\r\n"); + return false; + } + } else { + printf("Missing second option to menu item 2\r\n"); + } + } else { + printf("Error reading from socket\r\n"); + return false; + } + + + return true; +} + + #endif
--- a/wifi/Wifi.cpp Mon Dec 30 17:46:11 2013 +0000 +++ b/wifi/Wifi.cpp Mon Dec 30 19:00:56 2013 +0000 @@ -311,7 +311,7 @@ } std::string response = sendCommand("close", 10000, "CLOS"); - if(response.find("CLOS" == string::npos)) { + if(response.find("CLOS") == string::npos) { printf("[ERROR] Timed out attempting to close socket\r\n"); return false; }