diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/MTS_IO_CellularRadio.cpp | 28 | ||||
-rw-r--r-- | src/MTS_IO_EG95Radio.cpp | 43 | ||||
-rw-r--r-- | src/MTS_IO_QuectelRadio.cpp | 42 | ||||
-rw-r--r-- | src/MTS_IO_TelitRadio.cpp | 148 |
4 files changed, 183 insertions, 78 deletions
diff --git a/src/MTS_IO_CellularRadio.cpp b/src/MTS_IO_CellularRadio.cpp index 3f0c037..6df92e0 100644 --- a/src/MTS_IO_CellularRadio.cpp +++ b/src/MTS_IO_CellularRadio.cpp @@ -770,6 +770,34 @@ ICellularRadio::CODE CellularRadio::getRegistration(REGISTRATION& eRegistration) return SUCCESS; } +ICellularRadio::CODE CellularRadio::getCellularMode(CELLULAR_MODES &networks) { + networks = CELLULAR_MODE_NA; + std::string cmdResult = sendCommand("AT+COPS?"); + if (cmdResult.find(ICellularRadio::RSP_OK) == std::string::npos) { + printError("%s| AT+COPS returned unexpected response: AT+COPS? [%s]", getName().c_str(), cmdResult.c_str()); + return FAILURE; + } + + size_t cursor = 0; + const std::vector<std::string> &reply = MTS::Text::split(MTS::Text::getLine(MTS::Text::trim(cmdResult), cursor, cursor), ','); + uint8_t op; + if (reply.size() < 4 || !MTS::Text::parse(op, reply[3])) { + printError("%s| AT+COPS Error parsing reply [AT+COPS?][%s]", getName().c_str(), cmdResult.c_str()); + return FAILURE; + } + if (op == 0) { + networks = CELLULAR_MODE_2G; + } else if (op >= 2 && op <= 6) { + networks = CELLULAR_MODE_3G; + } else if (op == 7) { + networks = CELLULAR_MODE_4G; + } else { + printError("%s| AT+COPS unknown Radio Access Technology [AT+COPS?][%s]", getName().c_str(), cmdResult.c_str()); + return FAILURE; + } + return SUCCESS; +} + ICellularRadio::CODE CellularRadio::convertRegistrationToString(REGISTRATION eRegistration, std::string& sRegistration) { ICellularRadio::CODE eCode = FAILURE; diff --git a/src/MTS_IO_EG95Radio.cpp b/src/MTS_IO_EG95Radio.cpp index 5c9ed69..aff53d2 100644 --- a/src/MTS_IO_EG95Radio.cpp +++ b/src/MTS_IO_EG95Radio.cpp @@ -21,6 +21,11 @@ #include <mts/MTS_IO_EG95Radio.h> +#include <climits> + +#include <mts/MTS_Logger.h> +#include <mts/MTS_Text.h> + using namespace MTS::IO; const std::string EG95Radio::MODEL_NAME("EG95"); @@ -45,3 +50,41 @@ ICellularRadio::CODE EG95Radio::setRxDiversity(const Json::Value& jArgs) { return sendBasicCommand(sCmd); } + +ICellularRadio::CODE EG95Radio::getSupportedCellularModes(CELLULAR_MODES &networks) { + networks = static_cast<CELLULAR_MODES>(CELLULAR_MODE_2G | CELLULAR_MODE_3G | CELLULAR_MODE_4G); + return SUCCESS; +} + +ICellularRadio::CODE EG95Radio::setCellularMode(CELLULAR_MODES networks) { + std::string prefNet; + unsigned int prefOnly = 0; + for (int i = sizeof(networks)*CHAR_BIT-1; i>=0; --i){ + switch (1<<i & networks) { + case ICellularRadio::CELLULAR_MODE_2G: prefNet += "01" ; prefOnly = 1; break; + case ICellularRadio::CELLULAR_MODE_3G: prefNet += "0302"; prefOnly = 2; break; + case ICellularRadio::CELLULAR_MODE_4G: prefNet += "04" ; prefOnly = 3; break; + default: printError("Unhandled preferred network flag."); + } + } + + std::string sCmd; + if (prefNet.size() == 2) { // *g-only + sCmd = "AT+QCFG=\"nwscanmode\"," + std::to_string(prefOnly); + } else { // preferred + sCmd = "AT+QCFG=\"nwscanmode\",0"; + } + std::string cmdResult = sendCommand(sCmd); + if (cmdResult.find(ICellularRadio::RSP_OK) == std::string::npos) { + printError("%s| AT+QCFG=\"nwscanmode\" returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), cmdResult.c_str()); + return FAILURE; + } + + sCmd = "AT+QCFG=\"nwscanseq\"," + prefNet; + cmdResult = sendCommand(sCmd); + if (cmdResult.find(ICellularRadio::RSP_OK) == std::string::npos) { + printError("%s| AT+QCFG=\"nwscanseq\" returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), cmdResult.c_str()); + return FAILURE; + } + return SUCCESS; +} diff --git a/src/MTS_IO_QuectelRadio.cpp b/src/MTS_IO_QuectelRadio.cpp index f3227a5..c4bdc56 100644 --- a/src/MTS_IO_QuectelRadio.cpp +++ b/src/MTS_IO_QuectelRadio.cpp @@ -215,7 +215,6 @@ CellularRadio::CODE QuectelRadio::getNetworkStatus(Json::Value& jData) { const std::string RAT_WCDMA = "WCDMA"; const std::string RAT_LTE = "LTE"; - int32_t iValue; ACTIVEBAND abnd; SERVICEDOMAIN sd; std::string sValue; @@ -569,44 +568,3 @@ ICellularRadio::CODE QuectelRadio::convertToActiveBand(const std::string& sQuect return SUCCESS; } - -ICellularRadio::CODE QuectelRadio::getRadioNetworkMode(RADIO_NETWORK_MODE &mode) -{ - // AT+QCFG="nwscanmode" execution can take up to 300ms according to the datasheet. Setting timeout to 500ms just for sure. - std::string sCmd("AT+QCFG=\"nwscanmode\""); - std::string cmdResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 500); - - if (cmdResult.find(ICellularRadio::RSP_OK) == std::string::npos) { - printDebug("%s| AT+QCFG? returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), cmdResult.c_str()); - return FAILURE; - } - switch (stoi(MTS::Text::split(cmdResult, ',')[1])) { - case 1: mode = ICellularRadio::RADIO_NETWORK_MODE_GSM_ONLY; break; - case 5: mode = ICellularRadio::RADIO_NETWORK_MODE_UMTS_ONLY; break; - case 0: mode = ICellularRadio::RADIO_NETWORK_MODE_AUTO; break; - default: mode = ICellularRadio::RADIO_NETWORK_MODE_UNKNOWN; break; - } - return SUCCESS; -} - -ICellularRadio::CODE QuectelRadio::setRadioNetworkMode(RADIO_NETWORK_MODE mode) -{ - std::string value; - switch (mode) { - case ICellularRadio::RADIO_NETWORK_MODE_GSM_ONLY: value = "1"; break; - case ICellularRadio::RADIO_NETWORK_MODE_UMTS_ONLY: value = "5"; break; - case ICellularRadio::RADIO_NETWORK_MODE_AUTO: value = "0"; break; - default: return FAILURE; - } - std::string sCmd("AT+QCFG=\"nwscanmode\","); - sCmd += value; - - // AT+QCFG="nwscanmode" execution can take up to 300ms according to the datasheet. Setting timeout to 500ms just for sure. - std::string cmdResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 500); - - if (cmdResult.find(ICellularRadio::RSP_OK) == std::string::npos) { - printDebug("%s| AT+QCFG? returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), cmdResult.c_str()); - return FAILURE; - } - return SUCCESS; -} diff --git a/src/MTS_IO_TelitRadio.cpp b/src/MTS_IO_TelitRadio.cpp index 340c0ac..5b8e55d 100644 --- a/src/MTS_IO_TelitRadio.cpp +++ b/src/MTS_IO_TelitRadio.cpp @@ -538,42 +538,6 @@ bool TelitRadio::getHardwareVersionFromFirmware(const std::string& sFirmware, st } -ICellularRadio::CODE TelitRadio::getRadioNetworkMode(RADIO_NETWORK_MODE &mode) -{ - std::string sCmd("AT+WS46?"); - std::string cmdResult = sendCommand(sCmd); - if (cmdResult.find("+WS46:") == std::string::npos) { - printDebug("%s| AT+WS46? returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), cmdResult.c_str()); - return FAILURE; - } - switch (stoi(MTS::Text::split(cmdResult, ':')[1])) { - case 12: mode = ICellularRadio::RADIO_NETWORK_MODE_GSM_ONLY; break; - case 22: mode = ICellularRadio::RADIO_NETWORK_MODE_UMTS_ONLY; break; - case 25: mode = ICellularRadio::RADIO_NETWORK_MODE_AUTO; break; - default: mode = ICellularRadio::RADIO_NETWORK_MODE_UNKNOWN; break; - } - return SUCCESS; -} - -ICellularRadio::CODE TelitRadio::setRadioNetworkMode(RADIO_NETWORK_MODE mode) -{ - std::string value; - switch (mode) { - case ICellularRadio::RADIO_NETWORK_MODE_GSM_ONLY: value = "12"; break; - case ICellularRadio::RADIO_NETWORK_MODE_UMTS_ONLY: value = "22"; break; - case ICellularRadio::RADIO_NETWORK_MODE_AUTO: value = "25"; break; - default: return FAILURE; - } - std::string sCmd("AT+WS46="); - sCmd += value; - std::string cmdResult = sendCommand(sCmd); - if (cmdResult.find(ICellularRadio::RSP_OK) == std::string::npos) { - printDebug("%s| AT+WS46? returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), cmdResult.c_str()); - return FAILURE; - } - return SUCCESS; -} - ICellularRadio::CODE TelitRadio::getIsSimInserted(bool& bData) { printTrace("%s| Get SIM insertion status", getName().c_str()); std::string sCmd("AT#SIMDET?"); @@ -664,3 +628,115 @@ ICellularRadio::CODE TelitRadio::getSimLockAttempts(int& iAttemptsPin, int& iAtt return SUCCESS; } + +ICellularRadio::CODE TelitRadio::getSupportedCellularModes(CELLULAR_MODES &networks) { + networks = CELLULAR_MODE_NA; + std::string sCmd("AT+WS46=?"); + std::string cmdResult = sendCommand(sCmd); + if (cmdResult.find("+WS46:") == std::string::npos) { + printError("%s| AT+WS46=? returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), cmdResult.c_str()); + return FAILURE; + } + + if (cmdResult.find('(') == std::string::npos) { + printError("AT+WS46: error responce %s", cmdResult.c_str()); + return FAILURE; + } + std::string s = MTS::Text::split(cmdResult, '(')[1]; + s = MTS::Text::split(s, ')')[0]; + std::vector<std::string>v = MTS::Text::split(s, ','); + std::vector<int> m; + for(const auto &it : v) + { + if (it.find("-") != std::string::npos) { + const std::vector<std::string> &r = MTS::Text::split(it, "-"); + int begin, end; + if ( ! MTS::Text::parse(begin, r[0]) || ! MTS::Text::parse(end, r[1])) { + printError("AT+WS46: error parsing network mode range: %s-%s", r[0].c_str(), r[1].c_str()); + return FAILURE; + } + for (int i = begin; i<=end; ++i) { + m.push_back(i); + if (m.size()>1024) + break; + } + } else { + int v; + if ( ! MTS::Text::parse(v, it)) { + printError("AT+WS46: error parsing network mode: %s", it.c_str()); + return FAILURE; + } + m.push_back(v); + } + } + if (m.size()>1024) { + printError("AT+WS46: network modes count overflow, parsing error"); + return FAILURE; + } + + // Now m contains all network modes + for(const auto &it : m) { + networks = preferredNetwork(networks, it); + } + + return SUCCESS; +} + +ICellularRadio::CODE TelitRadio::setCellularMode(CELLULAR_MODES networks) { + int wds = 0; + // 3GPP TS 27.007 + // https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1515 + switch (static_cast<int>(networks)) { + case CELLULAR_MODE_2G : wds = 12; break; + case CELLULAR_MODE_3G : wds = 22; break; + case CELLULAR_MODE_2G | CELLULAR_MODE_3G | CELLULAR_MODE_4G : wds = 25; break; + case CELLULAR_MODE_4G : wds = 28; break; + case CELLULAR_MODE_2G | CELLULAR_MODE_3G : wds = 29; break; + case CELLULAR_MODE_2G | CELLULAR_MODE_4G : wds = 30; break; + case CELLULAR_MODE_3G | CELLULAR_MODE_4G : wds = 31; break; + case CELLULAR_MODE_2G | CELLULAR_MODE_3G | CELLULAR_MODE_4G | CELLULAR_MODE_5G: wds = 35; break; + case CELLULAR_MODE_5G: wds = 36; break; + case CELLULAR_MODE_4G | CELLULAR_MODE_5G: wds = 37; break; + case CELLULAR_MODE_3G | CELLULAR_MODE_4G | CELLULAR_MODE_5G: wds = 38; break; + case CELLULAR_MODE_2G | CELLULAR_MODE_4G | CELLULAR_MODE_5G: wds = 39; break; + case CELLULAR_MODE_3G | CELLULAR_MODE_5G: wds = 40; break; + case CELLULAR_MODE_2G | CELLULAR_MODE_3G | CELLULAR_MODE_5G: wds = 41; break; + case CELLULAR_MODE_2G | CELLULAR_MODE_5G: wds = 42; break; + } + std::string sCmd("AT+WS46="); + sCmd += std::to_string(wds); + std::string cmdResult = sendCommand(sCmd); + if (cmdResult.find(ICellularRadio::RSP_OK) == std::string::npos) { + printError("%s| AT+WS46= returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), cmdResult.c_str()); + return FAILURE; + } + return SUCCESS; +} + +ICellularRadio::CELLULAR_MODES TelitRadio::preferredNetwork(CELLULAR_MODES prefNetwork, int wds) +{ + int result = prefNetwork; + // 3GPP TS 27.007 + // https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1515 + switch (wds) { + case 12: result |= CELLULAR_MODE_2G; break; + case 22: result |= CELLULAR_MODE_3G; break; + case 25: result |= CELLULAR_MODE_2G | CELLULAR_MODE_3G | CELLULAR_MODE_4G; break; + case 28: result |= CELLULAR_MODE_4G; break; + case 29: result |= CELLULAR_MODE_2G | CELLULAR_MODE_3G; break; + case 30: result |= CELLULAR_MODE_2G | CELLULAR_MODE_4G; break; + case 31: result |= CELLULAR_MODE_3G | CELLULAR_MODE_4G; break; + case 35: result |= CELLULAR_MODE_2G | CELLULAR_MODE_3G | CELLULAR_MODE_4G | CELLULAR_MODE_5G; break; + case 36: result |= CELLULAR_MODE_5G; break; + case 37: result |= CELLULAR_MODE_4G | CELLULAR_MODE_5G; break; + case 38: result |= CELLULAR_MODE_3G | CELLULAR_MODE_4G | CELLULAR_MODE_5G; break; + case 39: result |= CELLULAR_MODE_2G | CELLULAR_MODE_4G | CELLULAR_MODE_5G; break; + case 40: result |= CELLULAR_MODE_3G | CELLULAR_MODE_5G; break; + case 41: result |= CELLULAR_MODE_2G | CELLULAR_MODE_3G | CELLULAR_MODE_5G; break; + case 42: result |= CELLULAR_MODE_2G | CELLULAR_MODE_5G; break; + default: + printError("AT+WS46: unhandled network mode: %d", wds); + break; + } + return static_cast<CELLULAR_MODES>(result); +} |