summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaksym Telychko <maksym.telychko@globallogic.com>2019-07-25 17:57:07 +0300
committerMaksym Telychko <maksym.telychko@globallogic.com>2019-07-25 17:57:07 +0300
commit59bd86588878af7e3f541902e8f2ed3d125dde81 (patch)
tree1cdb08cc727773f89e8e0fefe9c1977a1d89212b
parentc884d6cbebf99bb18edeba95fcb1a4191f538f01 (diff)
downloadlibmts-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.h12
-rw-r--r--include/mts/MTS_IO_QuectelRadio.h4
-rw-r--r--include/mts/MTS_IO_TelitRadio.h5
-rw-r--r--src/MTS_IO_QuectelRadio.cpp12
-rw-r--r--src/MTS_IO_TelitRadio.cpp130
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);
+}