diff options
author | Maksym Telychko <maksym.telychko@globallogic.com> | 2019-07-25 17:57:07 +0300 |
---|---|---|
committer | Maksym Telychko <maksym.telychko@globallogic.com> | 2019-07-25 17:57:07 +0300 |
commit | 59bd86588878af7e3f541902e8f2ed3d125dde81 (patch) | |
tree | 1cdb08cc727773f89e8e0fefe9c1977a1d89212b | |
parent | c884d6cbebf99bb18edeba95fcb1a4191f538f01 (diff) | |
download | libmts-io-59bd86588878af7e3f541902e8f2ed3d125dde81.tar.gz libmts-io-59bd86588878af7e3f541902e8f2ed3d125dde81.tar.bz2 libmts-io-59bd86588878af7e3f541902e8f2ed3d125dde81.zip |
MTX-2891 mpower: 2-3-4g switch implementation for Telit
-rw-r--r-- | include/mts/MTS_IO_ICellularRadio.h | 12 | ||||
-rw-r--r-- | include/mts/MTS_IO_QuectelRadio.h | 4 | ||||
-rw-r--r-- | include/mts/MTS_IO_TelitRadio.h | 5 | ||||
-rw-r--r-- | src/MTS_IO_QuectelRadio.cpp | 12 | ||||
-rw-r--r-- | src/MTS_IO_TelitRadio.cpp | 130 |
5 files changed, 163 insertions, 0 deletions
diff --git a/include/mts/MTS_IO_ICellularRadio.h b/include/mts/MTS_IO_ICellularRadio.h index e2bf652..29f710a 100644 --- a/include/mts/MTS_IO_ICellularRadio.h +++ b/include/mts/MTS_IO_ICellularRadio.h @@ -68,6 +68,14 @@ namespace MTS { RADIO_NETWORK_MODE_LTE_ONLY }; + enum PREFERRED_NETWORKS : uint8_t { + PREFERRED_NETWORK_NA = 0, // NOT AVAILABLE + PREFERRED_NETWORK_2G = 1 << 0, // GSM + PREFERRED_NETWORK_3G = 1 << 1, // WCDMA + PREFERRED_NETWORK_4G = 1 << 2, // LTE + PREFERRED_NETWORK_5G = 1 << 3 // 5G + }; + static CODE convertModelToType(const std::string& sModel, std::string& sType); static CODE convertModelToMtsShortCode(const std::string& sModel, std::string& sCode, ICellularRadio *radioObj = NULL); static CODE convertServiceDomainToString(SERVICEDOMAIN eSd, std::string& sSd); @@ -220,6 +228,10 @@ namespace MTS { virtual CODE getImsi(std::string& sImsi) = 0; virtual CODE getSimStatus(std::string& sSimStatus) = 0; + virtual CODE getAvailablePreferredNetworks(PREFERRED_NETWORKS &networks) = 0; + virtual CODE getPreferredNetworks(PREFERRED_NETWORKS &networks) = 0; + virtual CODE setPreferredNetworks(PREFERRED_NETWORKS networks) = 0; + /** * @brief getSimStatusSummary - get summary on the SIM card status * (if there is a SIM card inserted, is it locked, etc). diff --git a/include/mts/MTS_IO_QuectelRadio.h b/include/mts/MTS_IO_QuectelRadio.h index 3b1ba5a..8b8b92a 100644 --- a/include/mts/MTS_IO_QuectelRadio.h +++ b/include/mts/MTS_IO_QuectelRadio.h @@ -44,6 +44,10 @@ namespace MTS { CODE getRadioNetworkMode(RADIO_NETWORK_MODE &mode) override; CODE setRadioNetworkMode(RADIO_NETWORK_MODE mode) override; + CODE getAvailablePreferredNetworks(PREFERRED_NETWORKS &networks) override; + CODE getPreferredNetworks(PREFERRED_NETWORKS &networks) override; + CODE setPreferredNetworks(PREFERRED_NETWORKS networks) override; + protected: QuectelRadio(const std::string& sName, const std::string& sRadioPort); diff --git a/include/mts/MTS_IO_TelitRadio.h b/include/mts/MTS_IO_TelitRadio.h index 6382696..7b04125 100644 --- a/include/mts/MTS_IO_TelitRadio.h +++ b/include/mts/MTS_IO_TelitRadio.h @@ -42,6 +42,10 @@ namespace MTS { CODE getRadioNetworkMode(RADIO_NETWORK_MODE &mode) override; CODE setRadioNetworkMode(RADIO_NETWORK_MODE mode) override; + CODE getAvailablePreferredNetworks(PREFERRED_NETWORKS &networks) override; + CODE getPreferredNetworks(PREFERRED_NETWORKS &networks) override; + CODE setPreferredNetworks(PREFERRED_NETWORKS networks) override; + protected: TelitRadio(const std::string& sName, const std::string& sRadioPort); @@ -53,6 +57,7 @@ namespace MTS { private: virtual CODE getSimLockAttempts(int& iAttemptsPin, int& iAttemptsPuk, const std::string& sLockStatus); + static ICellularRadio::PREFERRED_NETWORKS preferredNetwork(PREFERRED_NETWORKS prefNetwork, int wds); }; } diff --git a/src/MTS_IO_QuectelRadio.cpp b/src/MTS_IO_QuectelRadio.cpp index f3227a5..c603d08 100644 --- a/src/MTS_IO_QuectelRadio.cpp +++ b/src/MTS_IO_QuectelRadio.cpp @@ -610,3 +610,15 @@ ICellularRadio::CODE QuectelRadio::setRadioNetworkMode(RADIO_NETWORK_MODE mode) } return SUCCESS; } + +ICellularRadio::CODE QuectelRadio::getAvailablePreferredNetworks(PREFERRED_NETWORKS &networks) { + return SUCCESS; +} + +ICellularRadio::CODE QuectelRadio::getPreferredNetworks(PREFERRED_NETWORKS &networks) { + return SUCCESS; +} + +ICellularRadio::CODE QuectelRadio::setPreferredNetworks(PREFERRED_NETWORKS networks) { + return SUCCESS; +} diff --git a/src/MTS_IO_TelitRadio.cpp b/src/MTS_IO_TelitRadio.cpp index 340c0ac..2750b98 100644 --- a/src/MTS_IO_TelitRadio.cpp +++ b/src/MTS_IO_TelitRadio.cpp @@ -546,6 +546,7 @@ ICellularRadio::CODE TelitRadio::getRadioNetworkMode(RADIO_NETWORK_MODE &mode) printDebug("%s| AT+WS46? returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), cmdResult.c_str()); return FAILURE; } + // TODO: replace with MTS::Text::parse 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; @@ -664,3 +665,132 @@ ICellularRadio::CODE TelitRadio::getSimLockAttempts(int& iAttemptsPin, int& iAtt return SUCCESS; } + +ICellularRadio::CODE TelitRadio::getAvailablePreferredNetworks(PREFERRED_NETWORKS &networks) { + networks = PREFERRED_NETWORK_NA; + 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; + } + + if (cmdResult.find('(') == std::string::npos) { + printDebug("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])) { + printDebug("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)) { + printDebug("AT+WS46: error parsing network mode: %s", it.c_str()); + return FAILURE; + } + m.push_back(v); + } + } + if (m.size()>1024) { + printDebug("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::getPreferredNetworks(PREFERRED_NETWORKS &networks) { + networks = PREFERRED_NETWORK_NA; + 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; + } + int wds; + size_t cursor; + if (MTS::Text::parse(wds, MTS::Text::trim(MTS::Text::getLine(MTS::Text::split(cmdResult, ':')[1], 0, cursor)))) { + networks = preferredNetwork(networks, wds); + return SUCCESS; + } + return FAILURE; +} + +ICellularRadio::CODE TelitRadio::setPreferredNetworks(PREFERRED_NETWORKS networks) { + int wds = 0; + // 3GPP TS 27.007 + // https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1515 + switch (static_cast<int>(networks)) { + case PREFERRED_NETWORK_2G : wds = 12; break; + case PREFERRED_NETWORK_3G : wds = 22; break; + case PREFERRED_NETWORK_2G | PREFERRED_NETWORK_3G | PREFERRED_NETWORK_4G : wds = 25; break; + case PREFERRED_NETWORK_4G : wds = 28; break; + case PREFERRED_NETWORK_2G | PREFERRED_NETWORK_3G : wds = 29; break; + case PREFERRED_NETWORK_2G | PREFERRED_NETWORK_4G : wds = 30; break; + case PREFERRED_NETWORK_3G | PREFERRED_NETWORK_4G : wds = 31; break; + case PREFERRED_NETWORK_2G | PREFERRED_NETWORK_3G | PREFERRED_NETWORK_4G | PREFERRED_NETWORK_5G: wds = 35; break; + case PREFERRED_NETWORK_5G: wds = 36; break; + case PREFERRED_NETWORK_4G | PREFERRED_NETWORK_5G: wds = 37; break; + case PREFERRED_NETWORK_3G | PREFERRED_NETWORK_4G | PREFERRED_NETWORK_5G: wds = 38; break; + case PREFERRED_NETWORK_2G | PREFERRED_NETWORK_4G | PREFERRED_NETWORK_5G: wds = 39; break; + case PREFERRED_NETWORK_3G | PREFERRED_NETWORK_5G: wds = 40; break; + case PREFERRED_NETWORK_2G | PREFERRED_NETWORK_3G | PREFERRED_NETWORK_5G: wds = 41; break; + case PREFERRED_NETWORK_2G | PREFERRED_NETWORK_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) { + printDebug("%s| AT+WS46= returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), cmdResult.c_str()); + return FAILURE; + } + return SUCCESS; +} + +ICellularRadio::PREFERRED_NETWORKS TelitRadio::preferredNetwork(PREFERRED_NETWORKS 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 |= PREFERRED_NETWORK_2G; break; + case 22: result |= PREFERRED_NETWORK_3G; break; + case 25: result |= PREFERRED_NETWORK_2G | PREFERRED_NETWORK_3G | PREFERRED_NETWORK_4G; break; + case 28: result |= PREFERRED_NETWORK_4G; break; + case 29: result |= PREFERRED_NETWORK_2G | PREFERRED_NETWORK_3G; break; + case 30: result |= PREFERRED_NETWORK_2G | PREFERRED_NETWORK_4G; break; + case 31: result |= PREFERRED_NETWORK_3G | PREFERRED_NETWORK_4G; break; + case 35: result |= PREFERRED_NETWORK_2G | PREFERRED_NETWORK_3G | PREFERRED_NETWORK_4G | PREFERRED_NETWORK_5G; break; + case 36: result |= PREFERRED_NETWORK_5G; break; + case 37: result |= PREFERRED_NETWORK_4G | PREFERRED_NETWORK_5G; break; + case 38: result |= PREFERRED_NETWORK_3G | PREFERRED_NETWORK_4G | PREFERRED_NETWORK_5G; break; + case 39: result |= PREFERRED_NETWORK_2G | PREFERRED_NETWORK_4G | PREFERRED_NETWORK_5G; break; + case 40: result |= PREFERRED_NETWORK_3G | PREFERRED_NETWORK_5G; break; + case 41: result |= PREFERRED_NETWORK_2G | PREFERRED_NETWORK_3G | PREFERRED_NETWORK_5G; break; + case 42: result |= PREFERRED_NETWORK_2G | PREFERRED_NETWORK_5G; break; + default: + printDebug("AT+WS46: unhandled network mode: %d", wds); + break; + } + return static_cast<PREFERRED_NETWORKS>(result); +} |