Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of MTS-Cellular by
Diff: Cellular/EasyIP.cpp
- Revision:
- 81:b0a720f7deae
- Parent:
- 78:fc9d2b983744
- Child:
- 82:f6c6e6c07db2
diff -r e66bf5723b98 -r b0a720f7deae Cellular/EasyIP.cpp --- a/Cellular/EasyIP.cpp Wed Sep 09 18:12:52 2015 +0000 +++ b/Cellular/EasyIP.cpp Wed Jul 27 23:00:39 2016 +0000 @@ -1,3 +1,20 @@ +//Debug is disabled by default +#define DEBUG_ENABLE true +#if DEBUG_ENABLE +//Enable debug +#include <cstdio> +#define DBG(x, ...) std::printf("[EasyIP : DBG]"x"\r\n", ##__VA_ARGS__); +#define WARN(x, ...) std::printf("[EasyIP : WARN]"x"\r\n", ##__VA_ARGS__); +#define ERR(x, ...) std::printf("[EasyIP : ERR]"x"\r\n", ##__VA_ARGS__); + +#else +//Disable debug +#define DBG(x, ...) +#define WARN(x, ...) +#define ERR(x, ...) + +#endif + #include "mbed.h" #include "EasyIP.h" #include "MTSText.h" @@ -30,7 +47,7 @@ if (dtr != NULL) { dtr->write(1); } - + delete dcd; delete dtr; delete resetLine; @@ -68,7 +85,7 @@ return false; } } - + //Check if socket is open if(socketOpened) { return true; @@ -78,7 +95,7 @@ if(isConnected()) { return true; } - + Timer tmr; //Check Registration: AT+CREG? == 0,1 tmr.start(); @@ -90,8 +107,8 @@ } else { break; } - } while(tmr.read() < 30); - + } while(tmr.read() < 30); + //Check RSSI: AT+CSQ tmr.reset(); do { @@ -130,8 +147,8 @@ snprintf(buf, sizeof(buf), "%d,1", type == MTSMC_LVW2 ? 3 : 1); pppResult = sendCommand("AT#SGACT?", 2000); if(pppResult.find(string(buf)) != std::string::npos) { - logDebug("Radio is already connected"); - pppConnected = true; + logDebug("Radio is already connected"); + pppConnected = true; } else { logError("PPP connection attempt failed"); pppConnected = false; @@ -144,14 +161,14 @@ void EasyIP::disconnect() { //AT#SGACT=1,0: Close PPP connection - logDebug("Closing PPP Connection"); + logDebug("Closing PPP Connection"); std::string result; Timer tmr; - + if(socketOpened) { close(true); } - + //Sends AT#SGACT=1,0 command for (int y = 0; y < 5; y++) { char buf[64]; @@ -162,7 +179,7 @@ break; } } - + /* Ensure PPP link is down, else ping commands will put radio in unknown state * (Link is not immediate in disconnection, even though OK is returned) */ @@ -179,7 +196,7 @@ wait(1); } } - + pppConnected = false; return; } @@ -190,7 +207,7 @@ //state flags for various connection components bool signal = false, regist = false, active = false; char buf[16]; - + //1) Check if APN was set if we're on an HSPA radio if (type == MTSMC_H5_IP || type == MTSMC_H5 || type == MTSMC_G3 || type == MTSMC_LAT1 || type == MTSMC_LEU1) { if(apn.size() == 0) { @@ -198,13 +215,13 @@ return false; } } - + //2) Check that we do not have a live connection up if (socketOpened) { logDebug("Socket is opened"); return true; } - + //3) Query the radio int rssi = getSignalStrength(); if (rssi == 99 || rssi == -1) { @@ -213,14 +230,14 @@ } else { signal = true; } - + Registration creg = getRegistration(); if (creg == REGISTERED) { regist = true; } else { regist = false; } - + string reply = sendCommand("AT#SGACT?", 1000); snprintf(buf, sizeof(buf), "%d,1", type == MTSMC_LVW2 ? 3 : 1); if (reply.find(string(buf)) != std::string::npos) { @@ -228,7 +245,7 @@ } else { active = false; } - + //Updates pppConnected to reflect current connection state RadioState state; bool ppp = pppConnected; @@ -244,7 +261,7 @@ state = DISCONNECTED; pppConnected = false; } - + //Compares current connection state with previous pppConnected variable state if (!ppp && state == CONNECTED) { logWarning("Internal PPP state tracking differs from radio (DISCONNECTED:CONNECTED)"); @@ -269,14 +286,14 @@ } logWarning("Internal PPP state tracking differs from radio (CONNECTED:%s)", stateStr.c_str()); } - + return pppConnected; } void EasyIP::reset() { disconnect(); - + if(sendBasicCommand("AT#REBOOT", 10000) != MTS_SUCCESS) { logError("Socket Modem did not accept RESET command"); } else { @@ -292,7 +309,7 @@ std::string sMode = ""; int typeSocket = 0; int closeType = 0; - + //1) Check that we do not have a live connection up if(socketOpened) { //Check that the address, port, and mode match @@ -314,7 +331,7 @@ logError("port out of range (0-65535)"); return false; } - + if(type == MTSMC_EV3 || type == MTSMC_LAT1 || type == MTSMC_LEU1 || type == MTSMC_LVW2) { if(!local_port) { logDebug("Local port set to 1, port 0 not supported for %s", getRadioNames(type).c_str()); @@ -332,12 +349,12 @@ logDebug("PPP connection established"); } } - + //4) Set escape sequence to not be transmitted through socket if(sendBasicCommand("AT#SKIPESC=1", 2000) != MTS_SUCCESS) { logWarning("Failed to disable escape sequence transmission on data mode suspension"); } - + if(mode == TCP) { typeSocket = 0; sMode = "TCP"; @@ -345,21 +362,21 @@ typeSocket = 1; sMode = "UDP"; } - + if(socketCloseable) { closeType = 0; } else { closeType = 255; } - - //5) Open Socket + + //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, 60000); - + if(response.find("CONNECT") != std::string::npos) { host_address = address; host_port = port; - + logInfo("Opened %s Socket [%s:%d]", sMode.c_str(), address.c_str(), port); socketOpened = true; socketMode = mode; @@ -367,14 +384,14 @@ logWarning("Unable to open %s Socket [%s:%d]", sMode.c_str(), address.c_str(), port); socketOpened = false; } - + return socketOpened; } //Closes socket connection bool EasyIP::close(bool shutdown) { - + if(io == NULL) { logError("MTSBufferedIO not set"); return false; @@ -389,18 +406,18 @@ logError("Socket is not closeable"); return false; } - + if(!sendEscapeCommand()) { logError("Failed to exit online mode"); return false; } else { socketOpened = false; } - + if (sendBasicCommand("AT#SH=1", 2000) != MTS_SUCCESS) { logDebug("Failed to close socket connection"); } - + //Clear receive buffer if (shutdown) { int counter = 0; @@ -411,7 +428,7 @@ } read(tmp, 256, 1000); } while(counter++ < 10); - + io->rxClear(); io->txClear(); } @@ -440,7 +457,7 @@ } else { bytesRead = io->read(data, max); } - + //Scan for socket closed message if(bytesRead > 0 && socketCloseable) { for(int i = 0; i < bytesRead; i++) { @@ -511,7 +528,7 @@ } else { wait(0.05); } - } while (bytesWritten < length); + } while (bytesWritten < length); } return bytesWritten; } @@ -519,7 +536,7 @@ Code EasyIP::setApn(const std::string& apn) { if (type == MTSMC_H5 || type == MTSMC_G3) { - //CGDCONT has options: IP,PPP,IPv6 + //CGDCONT has options: IP,PPP,IPv6 Code code = sendBasicCommand("AT+CGDCONT=1,IP," + apn, 1000); if (code != MTS_SUCCESS) { return code; @@ -527,7 +544,7 @@ this->apn = apn; return code; } else if (type == MTSMC_LAT1 || type == MTSMC_LEU1) { - //CGDCONT has options: IP,PPP,IPv6 + //CGDCONT has options: IP,PPP,IPv6 Code code = sendBasicCommand("AT+CGDCONT=1,\"IP\",\"" + apn + "\"", 1000); if (code != MTS_SUCCESS) { return code; @@ -546,10 +563,10 @@ std::vector<std::string> parts; int TTL=0; int Timeout=0; - + //Format parameters for sending to radio 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*2000)); //Send 1 ping if(response.empty() || response.find("ERROR") != std::string::npos) { @@ -566,11 +583,11 @@ //Parse TTL and Timeout values Timeout = std::atoi(parts[2].c_str()); TTL = std::atoi(parts[3].c_str()); - + if((Timeout < 600) && (TTL < 255)) { return true; } - } + } return false; } @@ -585,26 +602,26 @@ logError("Socket is not open."); return false; } - + if(!socketCloseable) { logError("Socket is not closeable"); return false; } - + io->rxClear(); io->txClear(); - + std::string result; unsigned int timeoutMillis = 10000; //Attempt to write command //Format for +++ command is 1 second wait, send +++, then another second wait - wait(1.2); + wait(1.2); if(io->write("+++", 3, timeoutMillis) != 3) { //Failed to write command logError("failed to send command to radio within %d milliseconds", timeoutMillis); return false; } - + Timer tmr; char tmp[256]; tmp[255] = 0; @@ -634,18 +651,19 @@ done = true; } } while (!done); - + wait(0.1); //Without a slight wait time after receiving OK, radio would - //fail to correctly receive and respond to the next AT command + //fail to correctly receive and respond to the next AT command return exitmode; } -bool EasyIP::socketCheck() { +bool EasyIP::socketCheck() +{ enum SocketStatus {SOCKETCLOSED = 0, SOCKETACTIVEDATA = 1, SOCKETSUSPEND = 2, SOCKETSUSPENDDATA = 3, SOCKETLISTEN = 4, SOCKETINCOMING = 5, ERROR = 9}; bool status = false; int socketInfo = ERROR; std::vector<std::string> params; - + //Goes from data mode to command mode if(sendEscapeCommand()) { std::string reply = sendCommand("AT#SS=1", 2000); @@ -661,7 +679,7 @@ } else { status = false; //Return value of socketOpened when checking } - + //Check socket status query if(socketInfo == SOCKETINCOMING || socketInfo == SOCKETACTIVEDATA || socketInfo == SOCKETSUSPEND || socketInfo == SOCKETSUSPENDDATA || socketInfo == SOCKETLISTEN) { //Socket opened responses status = true; @@ -671,7 +689,7 @@ logError("Could not determine socket status[%d]",socketInfo); status = false; } - + //Reconnect to active socket if able if(status) { std::string reconnect = sendCommand("AT#SO=1", 2000); @@ -683,28 +701,29 @@ return status; } -bool EasyIP::GPSenable() { +bool EasyIP::GPSenable() +{ //The HE910 returns an ERROR if you try to enable when it is already enabled. // That's why we need to check if GPS is enabled before enabling it. if(GPSenabled()) { logInfo("GPS was already enabled."); return true; } -//The LE910-NAG requires AT$GPSSLSR=2,3 to enable GPS but can use AT$GPSP=0 to disable it. - if(type == MTSMC_LAT1){ +//The LE910-NAG requires AT$GPSSLSR=2,3 to enable GPS but can use AT$GPSP=0 to disable it. + if(type == MTSMC_LAT1) { Code code = sendBasicCommand("AT$GPSSLSR=2,3", 2000); if (code == MTS_SUCCESS) { - gpsEnabled = true; + gpsEnabled = true; logInfo("GPS enabled."); return true; } else { - logError("Enable GPS failed!"); + logError("Enable GPS failed!"); return false; - } + } } else { Code code = sendBasicCommand("AT$GPSP=1", 2000); if (code == MTS_SUCCESS) { - gpsEnabled = true; + gpsEnabled = true; logInfo("GPS enabled."); return true; } else { @@ -714,7 +733,8 @@ } } -bool EasyIP::GPSdisable() { +bool EasyIP::GPSdisable() +{ // The HE910 returns an ERROR if you try to disable when it is already disabled. // That's why we need to check if GPS is disabled before disabling it. if(!GPSenabled()) { @@ -723,7 +743,7 @@ } Code code = sendBasicCommand("AT$GPSP=0", 2000); if (code == MTS_SUCCESS) { - gpsEnabled = false; + gpsEnabled = false; logInfo("GPS disabled."); return true; } else { @@ -732,7 +752,8 @@ } } -bool EasyIP::GPSenabled() { +bool EasyIP::GPSenabled() +{ std::string reply = sendCommand("AT$GPSP?", 1000); if(reply.find("1") != std::string::npos) { gpsEnabled = true; @@ -743,8 +764,9 @@ } } -Cellular::gpsData EasyIP::GPSgetPosition(){ - enum gpsFields{time, latitude, longitude, hdop, altitude, fix, cog, kmhr, knots, date, satellites, numOfFields }; +Cellular::gpsData EasyIP::GPSgetPosition() +{ + enum gpsFields {time, latitude, longitude, hdop, altitude, fix, cog, kmhr, knots, date, satellites, numOfFields }; Cellular::gpsData position; if(!gpsEnabled) { logError("GPS is disabled... can't get position."); @@ -760,14 +782,24 @@ // Remove trailing CR/LF, CR/LF, OK and CR/LF. gps.erase(gps.end()-8, gps.end()); // Split remaining data and load into corresponding structure fields. + + // Igal + DBG("GPS raw response: %s", gps); + std::vector<std::string> gpsParts = Text::split(gps, ','); // Check size. if(gpsParts.size() != numOfFields) { logError("Expected %d fields but there are %d fields in \"%s\"", numOfFields, gpsParts.size(), gps.c_str()); position.success = false; - return position; + return position; } position.latitude = gpsParts[latitude]; + // (Igal) if received empty gps message return "fail" + if ( (0 == position.latitude.compare("")) || (0 == position.latitude.compare("0"))) { + logError("GPS returned status OK but data is still invalid (e.g. Gps.latitude = %s).\r\n",position.latitude); + position.success = false; + return position; + } position.longitude = gpsParts[longitude]; position.hdop = atof(gpsParts[hdop].c_str()); position.altitude = atof(gpsParts[altitude].c_str()); @@ -777,19 +809,20 @@ position.knots = atof(gpsParts[knots].c_str()); position.satellites = atoi(gpsParts[satellites].c_str()); if((gpsParts[date].size() == 6) && (gpsParts[time].size() == 10)) { - position.timestamp = gpsParts[date].substr(4,2) + "/" + gpsParts[date].substr(2,2) + - "/" + gpsParts[date].substr(0,2) + ", " + gpsParts[time].substr(0,2) + - ":" + gpsParts[time].substr(2,2) + ":" + gpsParts[time].substr(4,6); + position.timestamp = gpsParts[date].substr(4,2) + "/" + gpsParts[date].substr(2,2) + + "/" + gpsParts[date].substr(0,2) + ", " + gpsParts[time].substr(0,2) + + ":" + gpsParts[time].substr(2,2) + ":" + gpsParts[time].substr(4,6); } - return position; + return position; } else { position.success = false; logError("NO \"OK\" returned from GPS position command \"AT$GPSACP?\"."); return position; } -} - -bool EasyIP::GPSgotFix() { +} + +bool EasyIP::GPSgotFix() +{ if(!gpsEnabled) { logError("GPS is disabled... can't get fix."); return false; @@ -797,7 +830,7 @@ Cellular::gpsData position = GPSgetPosition(); if(!position.success) { return false; - } else if(position.fix < 2){ + } else if(position.fix < 2) { logWarning("No GPS fix. GPS fix can take a few minutes. Check GPS antenna attachment and placement."); return false; } else {