summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJesse Gilles <jgilles@multitech.com>2015-04-20 17:14:31 -0500
committerJesse Gilles <jgilles@multitech.com>2015-04-20 17:14:31 -0500
commitd84d880627bcc1e1898a8f96b861bc25863ec86c (patch)
treee7db4eef6a8e8254eaa6ba0c7e5d56098af19d16 /src
downloadlibmts-io-d84d880627bcc1e1898a8f96b861bc25863ec86c.tar.gz
libmts-io-d84d880627bcc1e1898a8f96b861bc25863ec86c.tar.bz2
libmts-io-d84d880627bcc1e1898a8f96b861bc25863ec86c.zip
initial commit
Diffstat (limited to 'src')
-rw-r--r--src/MTS_IO_CE910Radio.cpp42
-rw-r--r--src/MTS_IO_CdmaRadio.cpp1297
-rw-r--r--src/MTS_IO_CellularRadio.cpp1522
-rw-r--r--src/MTS_IO_CellularRadioFactory.cpp145
-rw-r--r--src/MTS_IO_Connection.cpp155
-rw-r--r--src/MTS_IO_DE910Radio.cpp41
-rw-r--r--src/MTS_IO_GE910Radio.cpp41
-rw-r--r--src/MTS_IO_HE910DRadio.cpp41
-rw-r--r--src/MTS_IO_HE910EUDRadio.cpp42
-rw-r--r--src/MTS_IO_HE910Radio.cpp40
-rw-r--r--src/MTS_IO_LE910EUGRadio.cpp41
-rw-r--r--src/MTS_IO_LE910NAGRadio.cpp45
-rw-r--r--src/MTS_IO_LE910Radio.cpp39
-rw-r--r--src/MTS_IO_LE910SVGRadio.cpp45
-rw-r--r--src/MTS_IO_LockFile.cpp109
-rw-r--r--src/MTS_IO_MccMncTable.cpp1723
-rw-r--r--src/MTS_IO_SerialConnection.cpp545
17 files changed, 5913 insertions, 0 deletions
diff --git a/src/MTS_IO_CE910Radio.cpp b/src/MTS_IO_CE910Radio.cpp
new file mode 100644
index 0000000..b60c648
--- /dev/null
+++ b/src/MTS_IO_CE910Radio.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_CE910Radio.cpp
+ \brief A brief description
+ \date Nov 6, 2014
+ \author sgodinez
+
+ A more elaborate description
+*/
+
+#include <mts/MTS_IO_CE910Radio.h>
+
+using namespace MTS::IO;
+
+const std::string CE910Radio::MODEL_NAME("CE910");
+
+CE910Radio::CE910Radio(const std::string& sPort)
+: CdmaRadio(MODEL_NAME, sPort)
+{
+
+}
+
+
diff --git a/src/MTS_IO_CdmaRadio.cpp b/src/MTS_IO_CdmaRadio.cpp
new file mode 100644
index 0000000..66ce820
--- /dev/null
+++ b/src/MTS_IO_CdmaRadio.cpp
@@ -0,0 +1,1297 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_CdmaRadio.cpp
+ \brief A brief description
+ \date Nov 19, 2014
+ \author sgodinez
+
+ A more elaborate description
+*/
+
+#include <mts/MTS_IO_CdmaRadio.h>
+#include <mts/MTS_Text.h>
+#include <mts/MTS_Logger.h>
+#include <mts/MTS_Thread.h>
+
+using namespace MTS::IO;
+
+CdmaRadio::CdmaRadio(const std::string& sName, const std::string& sPort)
+: CellularRadio(sName, sPort)
+{
+
+}
+
+CdmaRadio::~CdmaRadio() {
+
+}
+
+CellularRadio::CODE CdmaRadio::getImei(std::string& sImei) {
+ printTrace("%s| Get IMEI", getName().c_str());
+ return getMeid(sImei);
+}
+
+CellularRadio::CODE CdmaRadio::getMeid(std::string& sMeid) {
+ printTrace("%s| Get MEID", getName().c_str());
+ sMeid = VALUE_NOT_SUPPORTED;
+ std::string sCmd("AT#MEIDESN?");
+ std::string sResult = CellularRadio::sendCommand(sCmd);
+ size_t pos = sResult.find(RSP_OK);
+ if (pos == std::string::npos) {
+ printWarning("%s| Unable to get MEID from radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ size_t start = sResult.find("#MEIDESN:") + sizeof("#MEIDESN:");
+ size_t stop = sResult.find(",");
+
+ if(stop != std::string::npos && stop > start) {
+ sMeid = sResult.substr(start, stop - start);
+ } else {
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::getMsid(std::string& sMsid) {
+ printTrace("%s| Get MSID", getName().c_str());
+ sMsid = VALUE_NOT_SUPPORTED;
+ std::string sCmd("AT$MSID?");
+ std::string sResult = CellularRadio::sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to get MSID from radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ size_t start = sResult.find("$MSID:") + sizeof("$MSID:");
+ sMsid = MTS::Text::trim(sResult.substr(start, end-start));
+ if(sMsid.size() == 0) {
+ printWarning("%s| MSID is empty", getName().c_str());
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::getCarrier(std::string& sCarrier) {
+ if(m_sCarrier != "") {
+ sCarrier = m_sCarrier;
+ return SUCCESS;
+ }
+
+ std::string sFirmware;
+ CODE code = getFirmware(sFirmware);
+ if(code != SUCCESS) {
+ return code;
+ }
+
+ if(!getCarrierFromFirmware(sFirmware, sCarrier)) {
+ return FAILURE;
+ }
+
+ m_sCarrier = sCarrier;
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::getNetwork(std::string& sNetwork) {
+ return getCarrier(sNetwork);
+}
+
+CellularRadio::CODE CdmaRadio::getSimStatus(std::string& sSimStatus) {
+ printTrace("%s| Get SIM Status", getName().c_str());
+ sSimStatus = VALUE_NOT_SUPPORTED;
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CdmaRadio::getIccid(std::string& sIccid) {
+ printTrace("%s| Get ICCID", getName().c_str());
+ sIccid = VALUE_NOT_SUPPORTED;
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CdmaRadio::getLac(std::string& sLac) {
+ printTrace("%s| Get LAC", getName().c_str());
+ sLac = VALUE_NOT_SUPPORTED;
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CdmaRadio::getService(std::string& sService) {
+ printTrace("%s| Get Service", getName().c_str());
+ sService = VALUE_NOT_SUPPORTED;
+ std::string sCmd("AT+SERVICE?");
+ std::string sResult = CellularRadio::sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to get Service from radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ size_t start = sResult.find("+SERVICE:");
+ if(start != std::string::npos) {
+ start += sizeof("+SERVICE:");
+ std::string sPsnt = MTS::Text::trim(sResult.substr(start, end-start));
+ int32_t iService;
+ sscanf(sPsnt.c_str(), "%d", &iService);
+
+ switch(iService) {
+ case 0: sService = "No Service"; break;
+ case 1: sService = "1xRTT"; break;
+ case 2: sService = "EVDO"; break; //Release 0
+ case 3: sService = "EVDO"; break; //Release A
+ case 4: sService = "GPRS"; break;
+ default: sService = VALUE_UNKNOWN; break;
+ }
+
+ printDebug("%s| Service ID: [%d][%s]", getName().c_str(), iService, sService.c_str());
+ }
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::getHardware(std::string& sHardware) {
+ printTrace("%s| Get Hardware", getName().c_str());
+ sHardware = VALUE_NOT_SUPPORTED;
+ std::string sCmd("AT#HWREV");
+ std::string sResult = CellularRadio::sendCommand(sCmd);
+ size_t pos = sResult.find(RSP_OK);
+ if (pos == std::string::npos) {
+ printWarning("%s| Unable to get hardware from radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ sHardware = MTS::Text::trim(sResult.substr(0, pos));
+ if(sHardware.size() == 0) {
+ printWarning("%s| Unable to get hardware from radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::getMdn(std::string& sMdn) {
+ printTrace("%s| Get MDN", getName().c_str());
+ sMdn = VALUE_NOT_SUPPORTED;
+ std::string sCmd("AT+CNUM");
+ std::string sResult = CellularRadio::sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to get MDN from radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ size_t start = sResult.find("CNUM:");
+ std::vector<std::string> vParts = MTS::Text::split(sResult.substr(start + sizeof("CNUM:"), end), ",");
+ if(vParts.size() == 3) {
+ sMdn = vParts[1];
+ if(sMdn.size() == 0) {
+ printWarning("%s| MDN is empty. Device may need to be activated", getName().c_str(), sCmd.c_str());
+ }
+ } else {
+ printWarning("%s| Unable to parse MDN from radio using command [%s][%s]", getName().c_str(), sCmd.c_str(), sResult.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::validateMsl(const Json::Value& jArgs) {
+ printTrace("%s| Validate MSL", getName().c_str());
+
+ if(!jArgs["msl"].isString()) {
+ return INVALID_ARGS;
+ }
+
+ std::string sCarrier;
+ getCarrier(sCarrier);
+
+ if(sCarrier != "Aeris" && sCarrier != "Sprint") {
+ return NOT_APPLICABLE;
+ }
+
+ std::string sMdn;
+ if(getMdn(sMdn) != SUCCESS) {
+ return FAILURE;
+ }
+
+ Json::Value jMdn(Json::objectValue);
+ jMdn["mdn"] = sMdn;
+ jMdn["msl"] = jArgs["msl"];
+
+ return setMdn(jMdn);
+}
+
+CellularRadio::CODE CdmaRadio::setMdn(const Json::Value& jArgs) {
+ printTrace("%s| Set MDN", getName().c_str());
+
+ if(!jArgs["mdn"].isString()) {
+ printError("%s| Arguments missing \"mdn\"", getName().c_str());
+ return INVALID_ARGS;
+ }
+
+ std::string sCarrier;
+ getCarrier(sCarrier);
+
+ std::string sCmd("AT$MDN=");
+ if(sCarrier == "Sprint") {
+
+ if(!jArgs["msl"].isString()) {
+ printError("%s| Arguments missing \"msl\"", getName().c_str());
+ return INVALID_ARGS;
+ }
+ sCmd += jArgs["msl"].asString() + ",";
+ } else if(sCarrier == "Aeris") {
+ //AT$MDN=<Last Six Digits of HEX MEID>,<MDN>
+ sCmd += getMeidLastSix() + ",";
+ }
+
+ //Strip spaces and hyphens
+ std::string sMdn = jArgs["mdn"].asString();
+ sMdn = MTS::Text::strip(sMdn, '-');
+ sMdn = MTS::Text::strip(sMdn, '(');
+ sMdn = MTS::Text::strip(sMdn, ')');
+ sMdn = MTS::Text::strip(sMdn, ' ');
+
+
+ sCmd += sMdn;
+
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to set MDN for radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::setMsid(const Json::Value& jArgs) {
+ printTrace("%s| Set MSID", getName().c_str());
+ if(!jArgs["msid"].isString()) {
+ printError("%s| Arguments missing \"msid\"", getName().c_str());
+ return INVALID_ARGS;
+ }
+
+ std::string sCarrier;
+ getCarrier(sCarrier);
+
+ std::string sCmd("AT$MSID=");
+ if(sCarrier == "Sprint") {
+ if(!jArgs["msl"].isString()) {
+ printError("%s| Arguments missing \"msl\"", getName().c_str());
+ return INVALID_ARGS;
+ }
+ sCmd += jArgs["msl"].asString() + ",";
+ } else if(sCarrier == "Aeris") {
+ //AT$MSID=<Last Six Digits of HEX MEID>,<MSID>
+ sCmd += getMeidLastSix() + ",";
+ }
+
+
+ sCmd += jArgs["msid"].asString();
+
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to set MSID for radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::getMipProfile(Json::Value& jMipProfile) {
+ printTrace("%s| Get MIP Active Profile", getName().c_str());
+
+ initMipProfile(jMipProfile);
+
+ std::string sCarrier;
+ getCarrier(sCarrier);
+
+ if(sCarrier == "Aeris" || sCarrier == "Sprint") {
+ std::string sCmd("AT$QCMIPGETP");
+ std::string sResult = MTS::Text::trim(sendCommand(sCmd));
+ if (sResult.find(RSP_OK) == std::string::npos) {
+ printWarning("%s| Unable to get active MIP profile for radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ std::vector<std::string> vLine = MTS::Text::split(sResult, "\r\n");
+
+ //ACTIVE MIP PROFILE
+ std::string sLine = vLine[0];
+ std::vector<std::string> vParts = MTS::Text::split(sLine, ':', 2);
+ if(vParts.size() == 2 && vParts[0] == "Profile") {
+ if(vParts[1].find("Enabled") != std::string::npos) {
+ jMipProfile[KEY_MIP_ENABLED] = true;
+ } else {
+ jMipProfile[KEY_MIP_ENABLED] = false;
+ }
+ int32_t id;
+ sscanf(vParts[1].c_str(), "%d", &id);
+ jMipProfile[KEY_MIP_ID] = id;
+
+ } else {
+ printWarning("%s| Unable to parse active MIP profile from line [%s]", getName().c_str(), sLine.c_str());
+ }
+
+
+ splitAndAssign(vLine[1], "NAI", jMipProfile, KEY_MIP_NAI);
+ splitAndAssign(vLine[2], "Home Addr", jMipProfile, KEY_MIP_HOMEADDRESS);
+ splitAndAssign(vLine[3], "Primary HA", jMipProfile, KEY_MIP_PRIMARYHA);
+ splitAndAssign(vLine[4], "Secondary HA", jMipProfile, KEY_MIP_SECONDARYHA);
+ splitAndAssign(vLine[5], "MN-AAA SPI", jMipProfile, KEY_MIP_MNAAASPI);
+ splitAndAssign(vLine[6], "MN-HA SPI", jMipProfile, KEY_MIP_MNHASPI);
+
+ //Reverse Tunneling
+ sLine = vLine[7];
+ vParts = MTS::Text::split(sLine, ':', 2);
+ if(vParts.size() == 2 && vParts[0] == "Rev Tun") {
+ if(vParts[1] == "1") {
+ jMipProfile[KEY_MIP_REVTUN] = true;
+ } else {
+ jMipProfile[KEY_MIP_REVTUN] = false;
+ }
+ } else {
+ printWarning("%s| Unable to parse Reverse Tunneling from line [%s]", getName().c_str(), sLine.c_str());
+ }
+
+ //MN-AAA SS
+ sLine = vLine[8];
+ vParts = MTS::Text::split(sLine, ':', 2);
+ if(vParts.size() == 2 && vParts[0] == "MN-AAA SS") {
+ if(vParts[1] == "Set") {
+ jMipProfile[KEY_MIP_MNAAASS] = true;
+ } else {
+ jMipProfile[KEY_MIP_MNAAASS] = false;
+ }
+ } else {
+ printWarning("%s| Unable to parse MN-AAA SS from line [%s]", getName().c_str(), sLine.c_str());
+ }
+
+ //MN-HA SS
+ sLine = vLine[9];
+ vParts = MTS::Text::split(sLine, ':', 2);
+ if(vParts.size() == 2 && vParts[0] == "MN-HA SS") {
+ if(vParts[1] == "Set") {
+ jMipProfile[KEY_MIP_MNHASS] = true;
+ } else {
+ jMipProfile[KEY_MIP_MNHASS] = false;
+ }
+ } else {
+ printWarning("%s| Unable to parse MN-HA SS from line [%s]", getName().c_str(), sLine.c_str());
+ }
+ }
+
+
+ return SUCCESS;
+}
+
+
+CellularRadio::CODE CdmaRadio::setMipActiveProfile(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP Active Profile", getName().c_str());
+
+ if(!jArgs["activeProfile"].isString()) {
+ return INVALID_ARGS;
+ }
+
+ std::string sCmd("AT$QCMIPP=");
+ sCmd += jArgs["activeProfile"].asString();
+
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to set Active profile for radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::setMipNai(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP NAI", getName().c_str());
+
+ if(!jArgs["nai"].isString()) {
+ return INVALID_ARGS;
+ }
+
+ std::string sCmd("AT$QCMIPNAI=");
+ sCmd += jArgs["nai"].asString() + ",1";
+
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to set NAI for radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::setMipHomeIp(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP Home IP", getName().c_str());
+
+ if(!jArgs["homeIp"].isString()) {
+ return INVALID_ARGS;
+ }
+
+ std::string sCmd("AT$QCMIPHA=");
+ sCmd += jArgs["homeIp"].asString() + ",1";
+
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to set Home IP profile for radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::setMipPrimaryHa(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP Primary HA", getName().c_str());
+
+ if(!jArgs["primaryHa"].isString()) {
+ return INVALID_ARGS;
+ }
+
+ std::string sCmd("AT$QCMIPPHA=");
+ sCmd += jArgs["primaryHa"].asString() + ",1";
+
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to set Primary HA for radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::setMipSecondaryHa(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP Secondary HA", getName().c_str());
+
+ if(!jArgs["secondaryHa"].isString()) {
+ return INVALID_ARGS;
+ }
+
+ std::string sCmd("AT$QCMIPSHA=");
+ sCmd += jArgs["secondaryHa"].asString() + ",1";
+
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to set Secondary HA for radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::setMipMnAaaSpi(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP MN-AAA SPI", getName().c_str());
+
+ if(!jArgs["mnAaaSpi"].isString()) {
+ return INVALID_ARGS;
+ }
+
+ std::string sCmd("AT$QCMIPMASPI=");
+ sCmd += jArgs["mnAaaSpi"].asString() + ",1";
+
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to set MN-AAA SPI for radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::setMipMnHaSpi(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP MN-HA SPI", getName().c_str());
+
+ if(!jArgs["mnHaSpi"].isString()) {
+ return INVALID_ARGS;
+ }
+
+ std::string sCmd("AT$QCMIPMHSPI=");
+ sCmd += jArgs["mnHaSpi"].asString() + ",1";
+
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to set MN-HA SPI for radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::setMipRevTun(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP Rev Tun", getName().c_str());
+
+ if(!jArgs["revTun"].isString()) {
+ return INVALID_ARGS;
+ }
+
+ std::string sCmd("AT$QCMIPRT=");
+ sCmd += jArgs["revTun"].asString() + ",1";
+
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to set Rev Tun for radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::setMipMnAaaSs(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP MN-AAA SS", getName().c_str());
+
+ if(!jArgs["mnAaaSs"].isString()) {
+ return INVALID_ARGS;
+ }
+
+ std::string sCmd("AT$QCMIPMASS=");
+ sCmd += jArgs["mnAaaSs"].asString() + ",1";
+
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to set MN-AAA SS for radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::setMipMnHaSs(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP MN-HA SS", getName().c_str());
+
+ if(!jArgs["mnHaSs"].isString()) {
+ return INVALID_ARGS;
+ }
+
+ std::string sCmd("AT$QCMIPMHSS=");
+ sCmd += jArgs["mnHaSs"].asString() + ",1";
+
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to set MN-HA SS for radio using command [%s]", getName().c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CdmaRadio::updateDc(const Json::Value& jArgs, UpdateCb& stepCb) {
+ printTrace("%s| Update Device Configuration", getName().c_str());
+
+ std::string sCarrier;
+ getCarrier(sCarrier);
+
+ if(sCarrier != "Sprint") {
+ return NOT_APPLICABLE;
+ }
+
+ CellularRadio::CODE result = FAILURE;
+ std::size_t pos = 0;
+ std::size_t end = 0;
+
+ IsNeedMoreData isNeedMoreData = [&stepCb, &result, &pos, &end, this](const std::string& iterationData, const std::string& allData)->bool {
+
+ if(iterationData.empty()) {
+ //No new data
+ return true;
+ }
+
+ end = allData.find(NL, pos);
+ printTrace("%s| Update DC Callback Started", this->getName().c_str());
+
+ while(end != std::string::npos) {
+ size_t next;
+ std::string sLine = MTS::Text::getLine(allData, pos, next);
+
+ printTrace("%s| Line: [%s]", this->getName().c_str(), sLine.c_str());
+
+ if(sLine == "#906") {
+ // DC DM session started
+ if(stepCb) {
+ stepCb(Json::Value("DC Info: DM session started"));
+ }
+ } else if(sLine == "#918") {
+ // DC Done, success
+ result = SUCCESS;
+ if(stepCb) {
+ stepCb(Json::Value("DC Done: success"));
+ }
+ return false;
+ } else if(sLine == "#924") {
+ // DC Done, no profile
+ result = SUCCESS;
+ if(stepCb) {
+ stepCb(Json::Value("DC Done: no profile"));
+ }
+ return false;
+ } else if(sLine == "#911") {
+ // DC Error: credential error
+ result = ERROR;
+ if(stepCb) {
+ stepCb(Json::Value("DC Error: credential error"));
+ }
+ return false;
+ } else if(sLine == "#912") {
+ // DC Error: unreachable server
+ result = ERROR;
+ if(stepCb) {
+ stepCb(Json::Value("DC Error: unreachable server"));
+ }
+ return false;
+ } else if(sLine == "#913") {
+ // DC Error: network error
+ result = ERROR;
+ if(stepCb) {
+ stepCb(Json::Value("DC Error: network error"));
+ }
+ return false;
+ } else if(sLine == "#915") {
+ // DC Error: update fails with other reasons
+ result = ERROR;
+ if(stepCb) {
+ stepCb(Json::Value("DC Error: update fails with other reasons"));
+ }
+ return false;
+ }else if(sLine == RSP_ERROR) {
+ result = ERROR;
+ return false;
+ }
+
+ //Set cursors for next iteration
+ if(next != std::string::npos) {
+ pos = next;
+ }
+ end = allData.find(NL, pos);
+ }
+
+ printTrace("%s| Update DC Callback Finished", this->getName().c_str());
+ return true;
+ };
+
+ sendCommand("AT+OMADM=2", isNeedMoreData, 5 * 60000);
+ return result;
+}
+
+CellularRadio::CODE CdmaRadio::updatePrl(const Json::Value& jArgs, UpdateCb& stepCb) {
+ printTrace("%s| Update Preferred Roaming List", getName().c_str());
+
+ std::string sCarrier;
+ getCarrier(sCarrier);
+
+ if(sCarrier != "Sprint") {
+ return NOT_APPLICABLE;
+ }
+
+ CellularRadio::CODE result = FAILURE;
+ std::size_t pos = 0;
+ std::size_t end = 0;
+
+ IsNeedMoreData isNeedMoreData = [&stepCb, &result, &pos, &end, this](const std::string& iterationData, const std::string& allData)->bool {
+
+ if(iterationData.empty()) {
+ //No new data
+ return true;
+ }
+
+ end = allData.find(NL, pos);
+ printTrace("%s| Update PRL Callback Started", this->getName().c_str());
+
+ while(end != std::string::npos) {
+ size_t next;
+ std::string sLine = MTS::Text::getLine(allData, pos, next);
+
+ printTrace("%s| Line: [%s]", this->getName().c_str(), sLine.c_str());
+
+ if(sLine == "#905") {
+ // PRL DM session started
+ if(stepCb) {
+ stepCb(Json::Value("PRL Info: DM session started"));
+ }
+ } else if(sLine == "#909") {
+ // PRL Done, success
+ result = SUCCESS;
+ if(stepCb) {
+ stepCb(Json::Value("PRL Done: success"));
+ }
+ return false;
+ } else if(sLine == "#910") {
+ // PRL Done, no PRL update
+ result = SUCCESS;
+ if(stepCb) {
+ stepCb(Json::Value("PRL Done: no PRL update"));
+ }
+ return false;
+ } else if(sLine == "#911") {
+ // PRL Error: credential error
+ result = ERROR;
+ if(stepCb) {
+ stepCb(Json::Value("PRL Error: credential error"));
+ }
+ return false;
+ } else if(sLine == "#912") {
+ // PRL Error: unreachable server
+ result = ERROR;
+ if(stepCb) {
+ stepCb(Json::Value("PRL Error: unreachable server"));
+ }
+ return false;
+ } else if(sLine == "#913") {
+ // PRL Error: network error
+ result = ERROR;
+ if(stepCb) {
+ stepCb(Json::Value("PRL Error: network error"));
+ }
+ return false;
+ } else if(sLine == "#915") {
+ // PRL Error: update fails with other reasons
+ result = ERROR;
+ if(stepCb) {
+ stepCb(Json::Value("PRL Error: update fails with other reasons"));
+ }
+ return false;
+ } else if(sLine == RSP_ERROR) {
+ result = ERROR;
+ return false;
+ }
+
+ //Set cursors for next iteration
+ if(next != std::string::npos) {
+ pos = next;
+ }
+ end = allData.find(NL, pos);
+ }
+
+ printTrace("%s| Update PRL Callback Finished", this->getName().c_str());
+ return true;
+ };
+
+ sendCommand("AT+PRL=2", isNeedMoreData, 5 * 60000);
+ return result;
+}
+
+CellularRadio::CODE CdmaRadio::updateFumo(const Json::Value& jArgs, UpdateCb& stepCb) {
+ printTrace("%s| Update Firmware Update Management Object", getName().c_str());
+
+ std::string sCarrier;
+ getCarrier(sCarrier);
+
+ if(sCarrier != "Sprint") {
+ return NOT_APPLICABLE;
+ }
+
+ CellularRadio::CODE result = FAILURE;
+ std::size_t pos = 0;
+ std::size_t end = 0;
+
+ IsNeedMoreData isNeedMoreData = [&stepCb, &result, &pos, &end, this](const std::string& iterationData, const std::string& allData)->bool {
+
+ if(iterationData.empty()) {
+ //No new data
+ return true;
+ }
+
+ end = allData.find(NL, pos);
+ printTrace("%s| Update FUMO Callback Started", this->getName().c_str());
+
+ while(end != std::string::npos) {
+ size_t next;
+ std::string sLine = MTS::Text::getLine(allData, pos, next);
+
+ printTrace("%s| Line: [%s]", this->getName().c_str(), sLine.c_str());
+
+ if(sLine == "#907") {
+ // FUMO DM session started
+ if(stepCb) {
+ stepCb(Json::Value("FUMO Info: DM session started"));
+ }
+ } else if(sLine == "#916") {
+ // FUMO Done, no firmware update
+ result = SUCCESS;
+ if(stepCb) {
+ stepCb(Json::Value("FUMO Done: no firmware update"));
+ }
+ return false;
+ } else if(sLine == "#911") {
+ // FUMO Error: credential error
+ result = ERROR;
+ if(stepCb) {
+ stepCb(Json::Value("FUMO Error: credential error"));
+ }
+ return false;
+ } else if(sLine == "#912") {
+ // FUMO Error: unreachable server
+ result = ERROR;
+ if(stepCb) {
+ stepCb(Json::Value("FUMO Error: unreachable server"));
+ }
+ return false;
+ } else if(sLine == "#913") {
+ // FUMO Error: network error
+ result = ERROR;
+ if(stepCb) {
+ stepCb(Json::Value("FUMO Error: network error"));
+ }
+ return false;
+ } else if(sLine == "#915") {
+ // FUMO Error: update fails with other reasons
+ result = ERROR;
+ if(stepCb) {
+ stepCb(Json::Value("FUMO Error: update fails with other reasons"));
+ }
+ return false;
+ } else if(sLine == "#919") {
+ // FUMO Firmware downloaded successfully
+ if(stepCb) {
+ stepCb(Json::Value("FUMO Info: firmware downloaded successfully"));
+ }
+ } else if(sLine == "#920:") {
+ // FUMO Firmware download progress (percent)
+ if(stepCb) {
+ stepCb(Json::Value(std::string("FUMO Info: firmware download progress ") + allData.substr(pos + 5, end + 5 - pos)));
+ }
+ } else if(sLine == "#921:") {
+ // FUMO Firmware size get from the OMA-DM server (byte)
+ if(stepCb) {
+ stepCb(Json::Value(std::string("FUMO Info: firmware size get from the OMA-DM server ") + allData.substr(pos + 5, end + 5 - pos) + " byte"));
+ }
+ } else if(sLine == "#921") { /// Info: check after check "#921:"
+ // FUMO Firmware download start
+ if(stepCb) {
+ stepCb(Json::Value("FUMO Info: firmware downloaded successfully"));
+ }
+ } else if(sLine == "#929: 200") {
+ // FUMO Done, success
+ result = SUCCESS;
+ if(stepCb) {
+ stepCb(Json::Value("FUMO Done: update success"));
+ }
+ return false;
+ } else if(sLine == "#929: 402") {
+ // FUMO Error, firmware corrupted, CRC error
+ result = ERROR;
+ if(stepCb) {
+ stepCb(Json::Value("FUMO Error: firmware corrupted, CRC error"));
+ }
+ return false;
+ } else if(sLine == "#929: 403") {
+ // FUMO Error, firmware package mismatch
+ result = ERROR;
+ if(stepCb) {
+ stepCb(Json::Value("FUMO Error: firmware package mismatch"));
+ }
+ return false;
+ } else if(sLine == "#929: 404") {
+ // FUMO Error, firmware signature failed
+ result = ERROR;
+ if(stepCb) {
+ stepCb(Json::Value("FUMO Error: firmware signature failed"));
+ }
+ return false;
+ } else if(sLine == "#929: 406") {
+ // FUMO Error, firmware update authentication failed
+ result = ERROR;
+ if(stepCb) {
+ stepCb(Json::Value("FUMO Error: firmware update authentication failed"));
+ }
+ return false;
+ } else if(sLine == "#929: 410") {
+ // FUMO Error, firmware update general error
+ result = ERROR;
+ if(stepCb) {
+ stepCb(Json::Value("FUMO Error: firmware update general error"));
+ }
+ return false;
+ } else if(sLine == "#930") {
+ // FUMO Reporting of Firmware Update result to server
+ if(stepCb) {
+ stepCb(Json::Value("FUMO Info: reporting of firmware update result to server"));
+ }
+ } else if(sLine == RSP_ERROR) {
+ result = ERROR;
+ return false;
+ }
+
+ //Set cursors for next iteration
+ if(next != std::string::npos) {
+ pos = next;
+ }
+ end = allData.find(NL, pos);
+ }
+
+ printTrace("%s| Update FUMO Callback Finished", this->getName().c_str());
+ return true;
+ };
+
+ sendCommand("AT+FUMO=2", isNeedMoreData, 30 * 60000);
+ return result;
+}
+
+CellularRadio::CODE CdmaRadio::resetHfa(const Json::Value& jArgs, UpdateCb& stepCb) {
+ printTrace("%s| HFA Reset (after device reboot HFA will occur)", getName().c_str());
+
+ std::string sCarrier;
+ getCarrier(sCarrier);
+
+ if(sCarrier != "Sprint") {
+ return NOT_APPLICABLE;
+ }
+
+ if(!jArgs["msl"].isString()) {
+ return INVALID_ARGS;
+ }
+
+ CellularRadio::CODE result = FAILURE;
+ std::size_t pos = 0;
+ std::size_t end = 0;
+
+ IsNeedMoreData isNeedMoreData = [&stepCb, &result, &pos, &end, this](const std::string& iterationData, const std::string& allData)->bool {
+ /* Expected Events:
+ * #900 - DM Client ready
+ * #904 - HFA Started
+ * #914 - HFA Done - HFA Success
+ * #905 - PRL - Session started
+ * #909 - PRL - Done - PRL success
+ * #907 - FUMO - Firmware DM session started or started again until no more updates are available
+ * #916 - FUMO - Firmware Done, No firmware update
+ */
+
+
+ if(iterationData.empty()) {
+ //No new data
+ return true;
+ }
+
+ end = allData.find(NL, pos);
+ printTrace("%s| HFA Reset Callback Started", this->getName().c_str());
+
+ while(end != std::string::npos) {
+ size_t next;
+ std::string sLine = MTS::Text::getLine(allData, pos, next);
+
+ printTrace("%s| Line: [%s]", this->getName().c_str(), sLine.c_str());
+
+ if(sLine == "#900") {
+ if(stepCb) {
+ stepCb(Json::Value("RTN Info: DM Client Ready"));
+ }
+ } else if(sLine == "#904") {
+ if(stepCb) {
+ stepCb(Json::Value("RTN Info: HFA - Session Started"));
+ }
+ } else if(sLine == "#914") {
+ if(stepCb) {
+ stepCb(Json::Value("RTN Info: HFA - Session Completed Successfully"));
+ }
+ } else if(sLine == "#905") {
+ if(stepCb) {
+ stepCb(Json::Value("RTN Info: PRL - Session Started"));
+ }
+ } else if(sLine == "#909") {
+ if(stepCb) {
+ stepCb(Json::Value("RTN Info: PRL - Session Completed Successfully"));
+ }
+ } else if(sLine == "#907") {
+ if(stepCb) {
+ stepCb(Json::Value("RTN Info: Firmware DM - Session Started"));
+ }
+ } else if(sLine == "#916") {
+ // RTN Done, success
+ result = SUCCESS;
+ if(stepCb) {
+ stepCb(Json::Value("RTN Done: Firmware DM - Session Completed Successfully"));
+ }
+ return false;
+ } else if(sLine == RSP_ERROR) {
+ result = ERROR;
+ return false;
+ } else if(sLine == RSP_OK) {
+ //The Device will reboot now, so reset the connection
+ if(stepCb) {
+ stepCb(Json::Value("RTN Info: Resetting Radio"));
+ }
+
+ //TODO: Investigate a better way of to handle
+ // recapturing the radio port after reset
+
+ //Sleep for a few seconds while resetting
+ MTS::Thread::sleep(5000);
+
+ //Try to reconnect to radio
+ if(!this->resetConnection(10000)) {
+ printError("%s| Unable to obtain radio after reset", this->getName().c_str());
+ if(stepCb) {
+ stepCb(Json::Value("RTN Error: Unable to obtain radio after reset"));
+ }
+ result = ERROR;
+ return false;
+ }
+ }
+
+ //Set cursors for next iteration
+ if(next != std::string::npos) {
+ pos = next;
+ }
+ end = allData.find(NL, pos);
+ }
+
+ printTrace("%s| HFA Reset Callback Finished", this->getName().c_str());
+ return true;
+ };
+
+ std::string sCmd("AT#SPRTN=\"");
+ sCmd += jArgs["msl"].asString() + "\"";
+ sendCommand(sCmd, isNeedMoreData, 5 * 60000);
+ return result;
+}
+
+CellularRadio::CODE CdmaRadio::activate(const Json::Value& jArgs, UpdateCb& stepCb) {
+ printTrace("%s| Activation", getName().c_str());
+
+ std::string sActivationCmd;
+ std::string sCarrier;
+ getCarrier(sCarrier);
+
+ if(sCarrier == "Aeris") {
+
+ if(!jArgs["msid"].isString()) {
+ printError("%s| Arguments missing \"msid\"", getName().c_str());
+ return INVALID_ARGS;
+ }
+
+ if(!jArgs["mdn"].isString()) {
+ printError("%s| Arguments missing \"mdn\"", getName().c_str());
+ return INVALID_ARGS;
+ }
+
+ std::string sMsid = jArgs["msid"].asString();
+ std::string sMdn = jArgs["mdn"].asString();
+ if(sMdn.size() != 10) {
+ printError("%s| MDN not valid. Expected length of 10: [%s][%d]", getName().c_str(), sMdn.c_str(), sMdn.size());
+ return INVALID_ARGS;
+ }
+
+ if(sMsid.size() != 10) {
+ printError("%s| MIN not valid. Expected length of 10: [%s][%d]", getName().c_str(), sMsid.c_str(), sMsid.size());
+ return INVALID_ARGS;
+ }
+
+ //Set MDN & MSID
+ CellularRadio::CODE code;
+ code = setMdn(jArgs);
+ if(code != SUCCESS) {
+ return code;
+ }
+
+ code = setMsid(jArgs);
+ if(code != SUCCESS) {
+ return code;
+ }
+
+ resetRadio(10000);
+
+ return SUCCESS;
+
+ } else if(sCarrier == "Verizon") {
+ sActivationCmd = "AT+CDV*22899\r";
+ } else {
+ return NOT_APPLICABLE;
+ }
+
+ CellularRadio::CODE result = FAILURE;
+ std::size_t pos = 0;
+ std::size_t end = 0;
+
+ IsNeedMoreData isNeedMoreData = [&stepCb, &result, &pos, &end, this](const std::string& iterationData, const std::string& allData)->bool {
+ //Verizon Activation
+ /* Expected Events:
+ * OK
+ * #OTASP: 0 //Start OTASP
+ * #OTASP: 1 //Start OTASP Commit
+ * #OTASP: 2 //End OTASP
+ *
+ * ERRORS:
+ * NO CARRIER //Account Plan Not Active
+ * #OTASP: 5 //Activation Failed
+ */
+
+
+ if(iterationData.empty()) {
+ //No new data
+ return true;
+ }
+
+ end = allData.find(NL, pos);
+ printTrace("%s| Activation Reset Callback Started", this->getName().c_str());
+
+ while(end != std::string::npos) {
+ size_t next;
+ std::string sLine = MTS::Text::getLine(allData, pos, next);
+
+ printTrace("%s| Line: [%s]", this->getName().c_str(), sLine.c_str());
+
+ if(sLine == RSP_OK) {
+ if(stepCb) {
+ stepCb(Json::Value("Activation Info: Over-the-Air Programming in Process"));
+ }
+ } else if(sLine == "#OTASP: 0") {
+ if(stepCb) {
+ stepCb(Json::Value("Activation Info: Saving Radio Configurations"));
+ }
+ } else if(sLine == "#OTASP: 1") {
+ if(stepCb) {
+ stepCb(Json::Value("Activation Info: Restarting Radio"));
+ }
+ } else if(sLine == "#OTASP: 2") {
+ if(stepCb) {
+ stepCb(Json::Value("Activation Info: Activation Completed Successfully"));
+ }
+ //Sleep for a few seconds while radio resets
+ MTS::Thread::sleep(5000);
+ this->resetConnection(10000);
+ result = SUCCESS;
+ return false;
+ } else if(sLine == "#OTASP: 5") {
+ if(stepCb) {
+ stepCb(Json::Value("Activation Error: Activation Failed"));
+ }
+ return false;
+ } else if(sLine == "NO CARRIER") {
+ if(stepCb) {
+ stepCb(Json::Value("Activation Error: Account Plan May Not Be Active"));
+ }
+ result = ERROR;
+ return false;
+ } else if(sLine == RSP_ERROR) {
+ result = ERROR;
+ return false;
+ }
+
+ //Set cursors for next iteration
+ if(next != std::string::npos) {
+ pos = next;
+ }
+ end = allData.find(NL, pos);
+ }
+
+ printTrace("%s| Activation Callback Finished", this->getName().c_str());
+ return true;
+ };
+
+ sendCommand(sActivationCmd, isNeedMoreData, 5 * 60000);
+ return result;
+}
+
+CellularRadio::CODE CdmaRadio::getNetworkStatus(Json::Value& jData) {
+ printTrace("%s| Get Network Status", getName().c_str());
+
+ getCommonNetworkStats(jData);
+
+ std::string sCarrier;
+ getCarrier(sCarrier);
+
+ if(sCarrier == VALUE_CARRIER_SPRINT) {
+ Json::Value& jDebug = jData["debug"];
+ std::string sCmd("AT$DEBUG?");
+ std::string sResult = MTS::Text::trim(sendCommand(sCmd));
+ if (sResult.find(RSP_OK) != std::string::npos) {
+ std::vector<std::string> vCategories = MTS::Text::split(sResult, "\r\n\r\n");
+ for(size_t i = 0 ; i < vCategories.size(); i++) {
+ std::vector<std::string> vLine = MTS::Text::split(vCategories[i], "\r\n");
+ if(vLine[0] == "1x Engineering") {
+ Json::Value& j1x = jDebug["1xrtt"];
+ splitAndAssign(vLine[1], "State", j1x, "state");
+ splitAndAssign(vLine[3], "Channel", j1x, "channel");
+ splitAndAssign(vLine[4], "Band Class", j1x, "bandClass");
+ splitAndAssign(vLine[5], "SID", j1x, "sid");
+ splitAndAssign(vLine[6], "NID", j1x, "nid");
+ splitAndAssign(vLine[7], "Base ID", j1x, "baseId");
+ splitAndAssign(vLine[8], "PN", j1x, "pn");
+ splitAndAssign(vLine[9], "P_rev", j1x, "pRev");
+ splitAndAssign(vLine[10], "Lat", j1x, "lat");
+ splitAndAssign(vLine[11], "Lon", j1x, "lon");
+ splitAndAssign(vLine[12], "Rx Pwr", j1x, "rxPwr");
+ splitAndAssign(vLine[13], "Rx Ec/Io", j1x, "rxEcIo");
+ splitAndAssign(vLine[14], "Rx FER", j1x, "rxFer");
+ splitAndAssign(vLine[15], "Tx Pwr", j1x, "txPwr");
+ splitAndAssign(vLine[16], "Active Set", j1x, "activeSet");
+ splitAndAssign(vLine[17], "Neighbor Set", j1x, "neighborSet");
+ } else if(vLine[0] == "EVDO Engineering") {
+ Json::Value& jEvdo = jDebug["evdo"];
+ splitAndAssign(vLine[1], "State", jEvdo, "state");
+ splitAndAssign(vLine[2], "Mac Index", jEvdo, "macIndex");
+ splitAndAssign(vLine[3], "Channel", jEvdo, "channel");
+ splitAndAssign(vLine[4], "Color Code", jEvdo, "colorCode");
+ splitAndAssign(vLine[5], "Sector ID", jEvdo, "sectorId");
+ splitAndAssign(vLine[6], "PN", jEvdo, "pn");
+ splitAndAssign(vLine[7], "Rx Pwr", jEvdo, "rxPwr");
+ splitAndAssign(vLine[8], "Rx PER", jEvdo, "rxPer");
+ splitAndAssign(vLine[9], "Pilot Energy", jEvdo, "pilotEnergy");
+ splitAndAssign(vLine[10], "DRC", jEvdo, "drc");
+ splitAndAssign(vLine[11], "SINR", jEvdo, "sinr");
+ splitAndAssign(vLine[12], "AN-AAA", jEvdo, "anAaa");
+ splitAndAssign(vLine[13], "IP Address", jEvdo, "ipAddress");
+ } else if(vLine[0] == "Configuration") {
+ Json::Value& jConf = jDebug["configuration"];
+ splitAndAssign(vLine[1], "Technology", jConf, "technology");
+ splitAndAssign(vLine[2], "1x Diversity", jConf, "1xDiversity");
+ splitAndAssign(vLine[3], "EVDO Diversity", jConf, "evdoDiversity");
+ splitAndAssign(vLine[4], "QLIC", jConf, "qlic");
+ splitAndAssign(vLine[5], "PRL", jConf, "prl");
+ splitAndAssign(vLine[6], "Chipset", jConf, "chipset");
+ splitAndAssign(vLine[7], "AMSS version", jConf, "amssVersion");
+ splitAndAssign(vLine[8], "Device version", jConf, "deviceVersion");
+ splitAndAssign(vLine[9], "Hardware version", jConf, "hardwareVersion");
+ splitAndAssign(vLine[10], "Browser", jConf, "browser");
+ splitAndAssign(vLine[11], "Multimedia Version", jConf, "multimediaVersion");
+ }
+ }
+
+ } else {
+ printDebug("%s| SPRINT Network Status command returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), sResult.c_str());
+ }
+ }
+
+
+ printTrace("%s| Network Status:\n%s\n", getName().c_str(), jData.toStyledString().c_str());
+
+ return SUCCESS;
+}
+
+std::string CdmaRadio::getMeidLastSix() {
+ std::string sMeid;
+ if(getMeid(sMeid) != SUCCESS || sMeid.size() != 14) {
+ return "";
+ }
+ return sMeid.substr(8);
+}
diff --git a/src/MTS_IO_CellularRadio.cpp b/src/MTS_IO_CellularRadio.cpp
new file mode 100644
index 0000000..adea939
--- /dev/null
+++ b/src/MTS_IO_CellularRadio.cpp
@@ -0,0 +1,1522 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_CellularRadio.cpp
+ \brief A brief description
+ \date Nov 5, 2014
+ \author sgodinez
+
+ A more elaborate description
+*/
+
+/*!
+ \file MTS_CELL_CellularRadio.cpp
+ \brief A brief description
+ \date Nov 4, 2014
+ \author sgodinez
+
+ A more elaborate description
+*/
+
+#include <mts/MTS_IO_CellularRadio.h>
+#include <mts/MTS_IO_MccMncTable.h>
+#include <mts/MTS_Thread.h>
+#include <mts/MTS_Timer.h>
+#include <mts/MTS_Logger.h>
+#include <mts/MTS_Text.h>
+#include <map>
+#include <cstring>
+#include <sstream>
+#include <sys/file.h>
+#include <errno.h>
+#include <unistd.h>
+
+
+using namespace MTS::IO;
+
+const char CellularRadio::ETX = 0x03; //Ends socket connection
+const char CellularRadio::DLE = 0x10; //Escapes ETX and DLE within Payload
+const char CellularRadio::CR = 0x0D;
+const char CellularRadio::NL = 0x0A;
+const char CellularRadio::CTRL_Z = 0x1A;
+
+const std::string CellularRadio::RSP_ERROR("ERROR");
+const std::string CellularRadio::RSP_OK("OK");
+
+
+const std::string CellularRadio::DEFAULT_RADIO_PORT("/dev/modem_at1");
+const std::string CellularRadio::DEFAULT_RADIO_DIR("/var/run/radio/");
+const std::string CellularRadio::VALUE_UNKNOWN("Unknown");
+const std::string CellularRadio::VALUE_UNAVAILABLE("Unavailable");
+const std::string CellularRadio::VALUE_NOT_SUPPORTED("Not Supported");
+
+const std::string CellularRadio::VALUE_NOT_REGISTERED("NOT REGISTERED");
+const std::string CellularRadio::VALUE_REGISTERED("REGISTERED");
+const std::string CellularRadio::VALUE_SEARCHING("SEARCHING");
+const std::string CellularRadio::VALUE_DENIED("DENIED");
+const std::string CellularRadio::VALUE_ROAMING("ROAMING");
+
+//Static Data
+const std::string CellularRadio::KEY_TYPE("type"); //!< GSM or CDMA
+const std::string CellularRadio::KEY_CODE("code"); //!< Product Code : H5, H6, C2, EV3, G3
+const std::string CellularRadio::KEY_MODEL("model"); //!< Model : HE910, LE910, CE910, DE910, GE910
+const std::string CellularRadio::KEY_MANUFACTURER("manufacturer"); //!< Manufacturer: Telit
+const std::string CellularRadio::KEY_HARDWARE("hardware"); //!< Radio Hardware Version
+const std::string CellularRadio::KEY_FIRMWARE("firmware"); //!< Radio Firmware Version
+
+const std::string CellularRadio::KEY_CARRIER("carrier"); //!< Cellular Service Provider (Home Network)
+const std::string CellularRadio::VALUE_CARRIER_VERIZON("Verizon");
+const std::string CellularRadio::VALUE_CARRIER_AERIS("Aeris");
+const std::string CellularRadio::VALUE_CARRIER_SPRINT("Sprint");
+const std::string CellularRadio::VALUE_CARRIER_ATT("AT&T");
+const std::string CellularRadio::VALUE_CARRIER_TMOBILE("T-Mobile");
+
+const std::string CellularRadio::KEY_IMEI("imei"); //!< International Mobile Station Equipment Identity
+const std::string CellularRadio::KEY_MEID("meid"); //!< Mobile Equipment Identifier
+const std::string CellularRadio::KEY_IMSI("imsi"); //!< International Mobile Subscriber Identity
+const std::string CellularRadio::KEY_MSID("msid"); //!< Mobil Station ID / Mobile Identification Number (MSID/MIN) (CDMA-Only)
+const std::string CellularRadio::KEY_MDN("mdn"); //!< Mobile Directory Number : Actual phone number dialed to reach radio
+const std::string CellularRadio::KEY_ICCID("iccid"); //!< Integrated Circuit Card Identifier
+const std::string CellularRadio::KEY_MSL("msl"); //!< Master Subsidy Lock
+
+//Dynamic Data
+const std::string CellularRadio::KEY_ROAMING("roaming"); //!< Indicates whether or not using Home Network
+const std::string CellularRadio::KEY_DATETIME("datetime"); //!< Date and Time from tower
+const std::string CellularRadio::KEY_SERVICE("service"); //!< Service Connection Type [GPRS, EGPRS, WCDMA, HSDPA, 1xRTT, EVDO]
+const std::string CellularRadio::KEY_NETWORK("network"); //!< Cellular Service Provider
+const std::string CellularRadio::KEY_CID("cid"); //!< Cellular ID (Tower) in HEX
+const std::string CellularRadio::KEY_LAC("lac"); //!< Location Area Code in HEX
+const std::string CellularRadio::KEY_RAC("rac"); //!< Routing Area Code in HEX
+const std::string CellularRadio::KEY_RSSI("rssi"); //!< Signal Strength
+const std::string CellularRadio::KEY_RSSIDBM("rssidBm"); //!< Signal Strength in dBm
+const std::string CellularRadio::KEY_MCC("mcc"); //!< Country Code
+const std::string CellularRadio::KEY_MNC("mnc"); //!< Operator Code
+const std::string CellularRadio::KEY_CHANNEL("channel"); //!< ARFCN or UARFCN Assigned Radio Channel
+const std::string CellularRadio::KEY_TXPWR("txpwr"); //!< Transmit Power
+const std::string CellularRadio::KEY_PSC("psc"); //!< Active Primary Synchronization Code (PSC)
+const std::string CellularRadio::KEY_ECIO("ecio"); //!< Active Ec/Io (chip energy per total wideband power in dBm)
+const std::string CellularRadio::KEY_RSCP("rscp"); //!< Active RSCP (Received Signal Code Power in dBm)
+const std::string CellularRadio::KEY_DRX("drx"); //!< Discontinuous reception cycle length (ms)
+const std::string CellularRadio::KEY_MM("mm"); //!< Mobility Management State
+const std::string CellularRadio::KEY_RR("rr"); //!< Radio Resource State
+const std::string CellularRadio::KEY_NOM("nom"); //!< Network Operator Mode
+const std::string CellularRadio::KEY_ABND("abnd"); //!< Active Band
+const std::string CellularRadio::KEY_BLER("bler"); //!< Block Error Rate (percentage)
+const std::string CellularRadio::KEY_SD("sd"); //!< Service Domain
+const std::string CellularRadio::KEY_DEBUG("debug"); //!< Debug Information
+
+const std::string CellularRadio::KEY_MIP("mipProfile"); //!< Mobile IP Information
+const std::string CellularRadio::KEY_MIP_ID("id"); //!< Mobile IP ID
+const std::string CellularRadio::KEY_MIP_ENABLED("enabled"); //!< Mobile IP Enabled/Disabled
+const std::string CellularRadio::KEY_MIP_NAI("nai"); //!< Network Access Identifier
+const std::string CellularRadio::KEY_MIP_HOMEADDRESS("homeAddress"); //!< Home Address
+const std::string CellularRadio::KEY_MIP_PRIMARYHA("primaryAddress"); //!< Primary Home Agent
+const std::string CellularRadio::KEY_MIP_SECONDARYHA("secondaryAddress"); //!< Secondary Home Agent
+const std::string CellularRadio::KEY_MIP_MNAAASPI("mnAaaSpi"); //!< Mobile Node Authentication, Authorization, and Accounting Server Security Parameter Index
+const std::string CellularRadio::KEY_MIP_MNHASPI("mnHaSpi"); //!< Mobile Node Home Agent Security Server Parameter Index
+const std::string CellularRadio::KEY_MIP_REVTUN("revTun"); //!< Reverse Tunneling Enabled
+const std::string CellularRadio::KEY_MIP_MNAAASS("mnAaaSs"); //!< Mobile Node Authentication, Authorization, and Accounting Server Shared Secret
+const std::string CellularRadio::KEY_MIP_MNHASS("mnHaSs"); //!< Mobile Node Home Agent Shared Secret
+
+const std::string CellularRadio::VALUE_TYPE_GSM("GSM");
+const std::string CellularRadio::VALUE_TYPE_LTE("LTE");
+const std::string CellularRadio::VALUE_TYPE_CDMA("CDMA");
+
+const std::string CellularRadio::VALUE_SD_NO_SERVICE("NO SERVICE");
+const std::string CellularRadio::VALUE_SD_CS_ONLY("CS ONLY");
+const std::string CellularRadio::VALUE_SD_PS_ONLY("PS ONLY");
+const std::string CellularRadio::VALUE_SD_CSPS("CS+PS");
+
+const std::string CellularRadio::VALUE_ABND_GSM_850("GSM 850");
+const std::string CellularRadio::VALUE_ABND_GSM_900("GSM 900");
+const std::string CellularRadio::VALUE_ABND_DCS_1800("DCS 1800");
+const std::string CellularRadio::VALUE_ABND_PCS_1900("PCS 1900");
+
+const std::vector<std::string> CellularRadio::DEFAULT_BAIL_STRINGS = { CellularRadio::RSP_OK, CellularRadio::RSP_ERROR };
+
+CellularRadio::CellularRadio(const std::string& sName, const std::string& sRadioPort)
+: m_sName(sName)
+, m_sRadioPort(sRadioPort)
+, m_bEchoEnabled(false)
+, m_bEnableEchoOnClose(false)
+{
+ m_apIo.reset(new MTS::IO::SerialConnection(
+ MTS::IO::SerialConnection::Builder(m_sRadioPort)
+ .baudRate(115200)
+ .useLockFile()
+ .build()));
+}
+
+
+CellularRadio::~CellularRadio() {
+ shutdown();
+ m_apIo.reset();
+}
+
+bool CellularRadio::initialize(uint32_t iTimeoutMillis) {
+ if(!m_apIo->open(iTimeoutMillis)) {
+ printError("%s| Failed to open radio port [%s]", m_sName.c_str(), m_sRadioPort.c_str());
+ return false;
+ }
+
+ bool bEnabled;
+ CODE eCode = getEcho(bEnabled);
+ if(eCode == SUCCESS && bEnabled) {
+ printDebug("%s| Disabling 'echo'", m_sName.c_str());
+ setEcho(false);
+ m_bEnableEchoOnClose = true;
+ }
+
+ return true;
+}
+
+bool CellularRadio::resetRadio(uint32_t iTimeoutMillis) {
+
+ printInfo("%s| Rebooting radio", m_sName.c_str());
+ if(sendBasicCommand("AT#REBOOT") == SUCCESS) {
+ if(iTimeoutMillis > 5000) {
+ MTS::Thread::sleep(5000);
+ iTimeoutMillis -= 5000;
+ }
+ return resetConnection(iTimeoutMillis);
+ }
+
+ return false;
+}
+
+bool CellularRadio::resetConnection(uint32_t iTimeoutMillis) {
+ //Close Current Connection
+ if(!m_apIo.isNull()) {
+ m_apIo->close();
+ }
+
+ m_apIo.reset(new MTS::IO::SerialConnection(
+ MTS::IO::SerialConnection::Builder(m_sRadioPort)
+ .baudRate(115200)
+ .useLockFile()
+ .build()));
+
+ //Try to obtain the device port over the given period of time
+ MTS::Timer oTimer;
+ oTimer.start();
+ uint64_t iCurrentTime = 0;
+ while(iCurrentTime < iTimeoutMillis) {
+
+ if(!m_apIo->open(iTimeoutMillis - iCurrentTime)) {
+ printWarning("%s| Failed to re-open radio port [%s]", m_sName.c_str(), m_sRadioPort.c_str());
+ } else {
+ printInfo("%s| Successfully re-opened radio port [%s]", m_sName.c_str(), m_sRadioPort.c_str());
+ break;
+ }
+
+ ::usleep(500000); //500 millis
+ iCurrentTime = oTimer.getMillis();
+ }
+ oTimer.stop();
+ return !m_apIo->isClosed();
+}
+
+void CellularRadio::shutdown() {
+
+ if(!m_apIo.isNull()) {
+ if(m_bEnableEchoOnClose) {
+ printDebug("%s| Enabling 'echo'", m_sName.c_str());
+ setEcho(true);
+ m_bEnableEchoOnClose = false;
+ }
+ m_apIo->close();
+ }
+}
+
+const std::string& CellularRadio::getName() const {
+ return m_sName;
+}
+
+
+CellularRadio::CODE CellularRadio::getModel(std::string& sModel) {
+ printTrace("%s| Get Model", m_sName.c_str());
+ //Always returns SUCCESS because the model should be m_sName
+ sModel = m_sName;
+ std::string sCmd("ATI4");
+ std::string sResult = CellularRadio::sendCommand(m_apIo, sCmd);
+ if (sResult.find("OK") == std::string::npos) {
+ printWarning("%s| Unable to get model from radio. Returning [%s]", m_sName.c_str(), m_sName.c_str());
+ return SUCCESS;
+ } else {
+ sModel = CellularRadio::extractModelFromResult(sResult);
+ if(sModel.size() == 0) {
+ printWarning("%s| Unable to get model from radio. Returning [%s]", m_sName.c_str(), m_sName.c_str());
+ return SUCCESS;
+ }
+ }
+
+ printDebug("%s| Extracted [%s] from [%s] query", m_sName.c_str(), sModel.c_str(), sCmd.c_str());
+ if(sModel != m_sName) {
+ printWarning("%s| Model identified [%s] does not match expected [%s]. Returning [%s]",
+ m_sName.c_str(), sModel.c_str(), m_sName.c_str(), sModel.c_str());
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CellularRadio::convertModelToMtsShortCode(const std::string& sModel, std::string& sCode) {
+ CODE eCode = FAILURE;
+
+ if(sModel.find("HE910-D") == 0) {
+ sCode = "H5";
+ eCode = SUCCESS;
+ } else if (sModel.find("HE910-EUD") == 0) {
+ sCode = "H6";
+ eCode = SUCCESS;
+ } else if (sModel.find("LE910-NAG") == 0) {
+ sCode = "LAT1";
+ eCode = SUCCESS;
+ } else if (sModel.find("LE910-SVG") == 0) {
+ sCode = "VW2";
+ eCode = SUCCESS;
+ } else if (sModel.find("LE910-EUG") == 0) {
+ sCode = "LEU1";
+ eCode = SUCCESS;
+ } else if (sModel.find("GE910") == 0) {
+ sCode = "G3";
+ eCode = SUCCESS;
+ } else if (sModel.find("CE910") == 0) {
+ sCode = "C2";
+ eCode = SUCCESS;
+ } else if (sModel.find("DE910") == 0) {
+ sCode = "EV3";
+ eCode = SUCCESS;
+ } else {
+ sCode = VALUE_NOT_SUPPORTED;
+ printError("RADIO| Could not identify MTS short code from model. [%s]", sModel.c_str());
+ eCode = ERROR;
+ }
+ return eCode;
+}
+
+CellularRadio::CODE CellularRadio::convertServiceDomainToString(SERVICEDOMAIN eSd, std::string& sSd) {
+ CODE eCode = FAILURE;
+ switch(eSd) {
+ case NO_SERVICE: sSd = VALUE_SD_NO_SERVICE; eCode = SUCCESS; break;
+ case CS_ONLY: sSd = VALUE_SD_CS_ONLY; eCode = SUCCESS; break;
+ case PS_ONLY: sSd = VALUE_SD_PS_ONLY; eCode = SUCCESS; break;
+ case CSPS: sSd = VALUE_SD_CSPS; eCode = SUCCESS; break;
+ default: sSd = VALUE_UNKNOWN; eCode = FAILURE; break;
+ }
+ return eCode;
+}
+
+CellularRadio::CODE CellularRadio::convertActiveBandToString(ACTIVEBAND eBand, std::string& sBand) {
+ CODE eCode = FAILURE;
+ switch(eBand) {
+ case GSM_850: sBand = VALUE_ABND_GSM_850; eCode = SUCCESS; break;
+ case GSM_900: sBand = VALUE_ABND_GSM_900; eCode = SUCCESS; break;
+ case DCS_1800: sBand = VALUE_ABND_DCS_1800; eCode = SUCCESS; break;
+ case PCS_1900: sBand = VALUE_ABND_PCS_1900; eCode = SUCCESS; break;
+ default: sBand = VALUE_UNKNOWN; eCode = FAILURE; break;
+ }
+ return eCode;
+}
+
+CellularRadio::CODE CellularRadio::convertModelToType(const std::string& sModel, std::string& sType) {
+ CODE eCode = FAILURE;
+ sType = VALUE_NOT_SUPPORTED;
+
+ if(sModel.find("HE910-D") == 0) {
+ sType = VALUE_TYPE_GSM;
+ eCode = SUCCESS;
+ } else if (sModel.find("HE910-EUD") == 0) {
+ sType = VALUE_TYPE_GSM;
+ eCode = SUCCESS;
+ } else if (sModel.find("LE910-NAG") == 0) {
+ sType = VALUE_TYPE_LTE;
+ eCode = SUCCESS;
+ } else if (sModel.find("LE910-SVG") == 0) {
+ sType = VALUE_TYPE_LTE;
+ eCode = SUCCESS;
+ } else if (sModel.find("LE910-EUG") == 0) {
+ sType = VALUE_TYPE_LTE;
+ eCode = SUCCESS;
+ } else if (sModel.find("GE910") == 0) {
+ sType = VALUE_TYPE_GSM;
+ eCode = SUCCESS;
+ } else if (sModel.find("CE910") == 0) {
+ sType = VALUE_TYPE_CDMA;
+ eCode = SUCCESS;
+ } else if (sModel.find("DE910") == 0) {
+ sType = VALUE_TYPE_CDMA;
+ eCode = SUCCESS;
+ } else {
+ sType = VALUE_TYPE_GSM;
+ eCode = ERROR;
+ printError("RADIO| Could not identify type from model. [%s]. Assuming [%s]", sModel.c_str(), sType.c_str());
+ }
+ return eCode;
+}
+
+CellularRadio::CODE CellularRadio::getFirmware(std::string& sFirmware) {
+ printTrace("%s| Get Firmware", m_sName.c_str());
+ sFirmware = VALUE_NOT_SUPPORTED;
+ std::string sCmd("AT+CGMR");
+ std::string sResult = CellularRadio::sendCommand(sCmd);
+ size_t pos = sResult.find(RSP_OK);
+ if (pos == std::string::npos) {
+ printWarning("%s| Unable to get firmware from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ sFirmware = MTS::Text::trim(sResult.substr(0, pos));
+ if(sFirmware.size() == 0) {
+ printWarning("%s| Unable to get firmware from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ m_sFirmware = sFirmware;
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CellularRadio::getHardware(std::string& sHardware) {
+ printTrace("%s| Get Hardware", m_sName.c_str());
+ sHardware = VALUE_NOT_SUPPORTED;
+
+ if(m_sFirmware.size() == 0) {
+ getFirmware(m_sFirmware);
+ }
+
+ if(getHardwareVersionFromFirmware(m_sFirmware, sHardware)) {
+ return SUCCESS;
+ }
+ return FAILURE;
+}
+
+CellularRadio::CODE CellularRadio::getManufacturer(std::string& sManufacturer) {
+ printTrace("%s| Get Manufacturer", m_sName.c_str());
+ sManufacturer = VALUE_NOT_SUPPORTED;
+ std::string sCmd("AT+GMI");
+ std::string sResult = CellularRadio::sendCommand(sCmd);
+ size_t pos = sResult.find(RSP_OK);
+ if (pos == std::string::npos) {
+ printWarning("%s| Unable to get manufacturer from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ sManufacturer = MTS::Text::trim(sResult.substr(0, pos));
+ if(sManufacturer.size() == 0) {
+ printWarning("%s| Unable to get manufacturer from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CellularRadio::getImei(std::string& sImei) {
+ printTrace("%s| Get IMEI", m_sName.c_str());
+ sImei = VALUE_NOT_SUPPORTED;
+ std::string sCmd("AT+CGSN");
+ std::string sResult = CellularRadio::sendCommand(sCmd);
+ size_t pos = sResult.find(RSP_OK);
+ if (pos == std::string::npos) {
+ printWarning("%s| Unable to get IMEI from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ sImei = MTS::Text::trim(sResult.substr(0, pos));
+ if(sImei.size() == 0) {
+ printWarning("%s| Unable to get IMEI from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CellularRadio::getMeid(std::string& sMeid) {
+ printTrace("%s| Get MEID", m_sName.c_str());
+ return getImei(sMeid);
+}
+
+CellularRadio::CODE CellularRadio::getImsi(std::string& sImsi) {
+ printTrace("%s| Get IMSI", m_sName.c_str());
+ sImsi = VALUE_NOT_SUPPORTED;
+ std::string sCmd("AT+CIMI");
+ std::string sResult = CellularRadio::sendCommand(sCmd);
+ size_t pos = sResult.find(RSP_OK);
+ if (pos == std::string::npos) {
+ printWarning("%s| Unable to get IMSI from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ sImsi = MTS::Text::trim(sResult.substr(0, pos));
+ if(sImsi.size() == 0) {
+ printWarning("%s| Unable to get IMSI from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CellularRadio::getSimStatus(std::string& sSimStatus) {
+ printTrace("%s| Get SIM Status", getName().c_str());
+ sSimStatus = VALUE_UNKNOWN;
+ return FAILURE;
+}
+
+CellularRadio::CODE CellularRadio::getIccid(std::string& sIccid) {
+ printTrace("%s| Get ICCID", m_sName.c_str());
+ sIccid = VALUE_NOT_SUPPORTED;
+ std::string sCmd("AT#CCID");
+ std::string sResult = CellularRadio::sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to get ICCID from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ size_t start = sResult.find("#CCID:");
+ if(start != std::string::npos) {
+ start += sizeof("#CCID:");
+ sIccid = MTS::Text::trim(sResult.substr(start, end-start));
+ if(sIccid.size() == 0) {
+ printWarning("%s| Unable to get ICCID from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+ }
+ return SUCCESS;
+}
+
+CellularRadio::CODE CellularRadio::getService(std::string& sService) {
+ printTrace("%s| Get Service", m_sName.c_str());
+ sService = VALUE_NOT_SUPPORTED;
+ std::string sCmd("AT#PSNT?");
+ std::string sResult = CellularRadio::sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to get Service from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ size_t start = sResult.find(",");
+ if(start != std::string::npos) {
+ start += 1; //comma
+ std::string sPsnt = MTS::Text::trim(sResult.substr(start, end-start));
+ int32_t iService;
+ sscanf(sPsnt.c_str(), "%d", &iService);
+
+ switch(iService) {
+ case 0: sService = "GPRS"; break;
+ case 1: sService = "EGPRS"; break;
+ case 2: sService = "WCDMA"; break;
+ case 3: sService = "HSDPA"; break;
+ default: sService = VALUE_UNKNOWN; break;
+ }
+
+ printDebug("%s| Service ID: [%d][%s]", m_sName.c_str(), iService, sService.c_str());
+ }
+ return SUCCESS;
+}
+
+CellularRadio::CODE CellularRadio::getLac(std::string& sLac) {
+ Json::Value jData;
+
+ printTrace("%s| Get LAC", m_sName.c_str());
+ sLac = VALUE_NOT_SUPPORTED;
+
+ if(getNetworkStatus(jData) == SUCCESS) {
+ if(jData.isMember(KEY_LAC)) {
+ sLac = jData[KEY_LAC].asString();
+ return SUCCESS;
+ }
+ }
+
+ return FAILURE;
+}
+
+CellularRadio::CODE CellularRadio::getMdn(std::string& sMdn) {
+ printTrace("%s| Get MDN", m_sName.c_str());
+ sMdn = VALUE_NOT_SUPPORTED;
+ std::string sCmd("AT+CNUM");
+ std::string sResult = CellularRadio::sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to get MDN from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ size_t start = sResult.find("CNUM:");
+ if(start != std::string::npos) {
+ start += sizeof("CNUM:");
+ std::vector<std::string> vParts = MTS::Text::split(sResult.substr(start, end - start), ',');
+ if(vParts.size() != 3) {
+ printWarning("%s| Unable to parse MDN from response [%s]", m_sName.c_str(), sResult.c_str());
+ return FAILURE;
+ }
+ sMdn = MTS::Text::strip(vParts[1], '"');
+ if(sMdn.size() == 0) {
+ printWarning("%s| Unable to get MDN from radio using command [%s]. MDN may not be set.", m_sName.c_str(), sCmd.c_str());
+ }
+ } else {
+ sMdn = "";
+ printWarning("%s| Unable to get MDN from radio using command [%s]. MDN may not be set.", m_sName.c_str(), sCmd.c_str());
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CellularRadio::getMsid(std::string& sMsid) {
+ printTrace("%s| Get MSID", m_sName.c_str());
+ sMsid = "";
+
+ std::string sImsi;
+ if(getImsi(sImsi) == SUCCESS) {
+ if(sImsi.size() >= 10) {
+ sMsid = sImsi.substr(sImsi.size() - 10);
+ printTrace("IMSI: [%s] MEID [%s]", sImsi.c_str(), sMsid.c_str());
+ return SUCCESS;
+ }
+ }
+ printWarning("%s| Unable to get MSID from radio", m_sName.c_str());
+ return FAILURE;
+}
+
+CellularRadio::CODE CellularRadio::getType(std::string& sType) {
+ printTrace("%s| Get Type", m_sName.c_str());
+ sType = VALUE_NOT_SUPPORTED;
+ return FAILURE;
+}
+
+CellularRadio::CODE CellularRadio::getCarrier(std::string& sCarrier) {
+ printTrace("%s| Get Carrier", m_sName.c_str());
+ if(m_sCarrier == "") {
+ Json::Value jData;
+ if(getNetworkStatus(jData) == SUCCESS) {
+ if(jData.isMember(KEY_MCC) && jData.isMember(KEY_MNC)) {
+ std::string sMcc = jData[KEY_MCC].asString();
+ std::string sMnc = jData[KEY_MNC].asString();
+ Json::Value jLookup = MccMncTable::getInstance()->lookup(sMcc, sMnc);
+ printTrace("%s| MCC-MNC Lookup: [%s][%s][%s]", m_sName.c_str(),
+ sMcc.c_str(), sMnc.c_str(), jLookup.toStyledString().c_str());
+ if(jLookup.isMember(KEY_CARRIER)) {
+ m_sCarrier = jLookup[KEY_CARRIER].asString();
+ } else {
+ printWarning("%s| MCC-MNC Lookup did not contain carrier", m_sName.c_str());
+ return FAILURE;
+ }
+ } else {
+ printWarning("%s| Network Status did no contain MCC or MNC", m_sName.c_str());
+ return FAILURE;
+ }
+ } else {
+ return FAILURE;
+ }
+ }
+
+ sCarrier = m_sCarrier;
+ return SUCCESS;
+}
+
+CellularRadio::CODE CellularRadio::getTower(std::string& sTower) {
+ Json::Value jData;
+
+ printTrace("%s| Get Tower", m_sName.c_str());
+ sTower = VALUE_NOT_SUPPORTED;
+
+ if(getNetworkStatus(jData) == SUCCESS) {
+ if(jData.isMember(KEY_CID)) {
+ sTower = jData[KEY_CID].asString();
+ return SUCCESS;
+ }
+ }
+ return FAILURE;
+}
+
+CellularRadio::CODE CellularRadio::getTime(std::string& sDate, std::string& sTime, std::string& sTimeZone) {
+ Json::Value jData;
+
+ printTrace("%s| Get Time", m_sName.c_str());
+ sDate = "";
+ sTime = "";
+ sTimeZone = "";
+
+ std::string sCmd("AT+CCLK?");
+ std::string sResult = CellularRadio::sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to get Time from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ size_t start = sResult.find("CCLK: ");
+ if(start != std::string::npos) {
+ start += sizeof("CCLK: ");
+ std::string sValue = MTS::Text::trim(sResult.substr(start, end - start));
+ sValue = MTS::Text::strip(sValue, '"');
+
+ std::vector<std::string> vParts = MTS::Text::split(sValue, ',');
+ if(vParts.size() != 2) {
+ printWarning("%s| Unable to parse Date from response [%s]", m_sName.c_str(), sResult.c_str());
+ return FAILURE;
+ }
+
+
+ std::vector<std::string> vDateParts = MTS::Text::split(vParts[0], '/');
+ if(vDateParts.size() != 3) {
+ printWarning("%s| Unable to parse Date from response [%s]", m_sName.c_str(), sResult.c_str());
+ return FAILURE;
+ }
+
+ //The Date format is YY/MM/DD -> Change to MM/DD/YY
+ sDate = vDateParts[1] + "/" + vDateParts[2] + "/" + vDateParts[0];
+
+ vParts = MTS::Text::split(vParts[1], '-');
+ if(vParts.size() != 2) {
+ printWarning("%s| Unable to parse Time from response [%s]", m_sName.c_str(), sResult.c_str());
+ return FAILURE;
+ }
+ sTime = vParts[0];
+
+ int32_t iZoneUnits; //the difference, expressed in quarters of an hour, between the local time and GMT
+ if(!MTS::Text::parse(iZoneUnits, MTS::Text::strip(vParts[1], '+'))) {
+ printWarning("%s| Unable to parse Time Zone from response [%s]", m_sName.c_str(), sResult.c_str());
+ return FAILURE;
+ }
+
+ int32_t iZone = iZoneUnits/4; //Divide by 4 to get hours difference
+ int32_t iZonePartial = (iZoneUnits % 4) * 15; //Remainder in minutes
+ std::string sPlusSign = "+";
+ if(iZonePartial < 0) {
+ //Remove negative sign from partial and clear plus sign component
+ iZonePartial *= -1;
+ sPlusSign = "";
+ }
+ std::stringstream ss;
+ ss << sPlusSign << iZone;
+ if(iZonePartial != 0) {
+ ss << ":" << iZonePartial;
+ }
+
+ sTimeZone = ss.str();
+ return SUCCESS;
+
+ } else {
+ printWarning("%s| Unable to get Time from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ }
+
+ return FAILURE;
+}
+
+CellularRadio::CODE CellularRadio::getRoaming(bool& bRoaming) {
+ Json::Value jData;
+
+ printTrace("%s| Get Roaming", m_sName.c_str());
+ bRoaming = false;
+
+ REGISTRATION eReg;
+ if(getRegistration(eReg) == SUCCESS) {
+ bRoaming = (eReg == ROAMING);
+ return SUCCESS;
+ }
+ return FAILURE;
+}
+
+CellularRadio::CODE CellularRadio::getNetwork(std::string& sNetwork) {
+ Json::Value jData;
+
+ printTrace("%s| Get Network", m_sName.c_str());
+ sNetwork = VALUE_NOT_SUPPORTED;
+
+ if(getNetworkStatus(jData) == SUCCESS) {
+ if(jData.isMember(KEY_NETWORK)) {
+ sNetwork = jData[KEY_NETWORK].asString();
+ return SUCCESS;
+ }
+ }
+ return FAILURE;
+}
+
+CellularRadio::CODE CellularRadio::getSignalStrength(int32_t& rssi) {
+ printTrace("%s| Get Signal Strength", m_sName.c_str());
+ std::string sCmd("AT+CSQ");
+ std::string sResult = sendCommand(sCmd);
+ if (sResult.find("+CSQ: ") == std::string::npos) {
+ printDebug("%s| Signal Strength command returned unexpected response: [%s]", m_sName.c_str(), sResult.c_str());
+ return FAILURE;
+ }
+
+ size_t start = sResult.find(':');
+ size_t stop = sResult.find(',', start);
+ if(start == std::string::npos || stop == std::string::npos) {
+ printDebug("%s| Signal Strength command returned malformed response: [%s]", m_sName.c_str(), sResult.c_str());
+ return FAILURE;
+ }
+ std::string signal = sResult.substr(start + 2, stop - start - 2);
+
+ sscanf(signal.c_str(), "%d", &rssi);
+ printDebug("%s| Signal Strength: [%d]", m_sName.c_str(), rssi);
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CellularRadio::convertSignalStrengthTodBm(const int32_t& iRssi, int32_t& iDbm) {
+
+ //Telit Conversion
+ if(iRssi < 0 || iRssi == 99) {
+ return FAILURE;
+ }
+
+ if(iRssi == 0) {
+ iDbm = -113;
+ } else if(iRssi == 1) {
+ iDbm = -111;
+ } else if(iRssi <= 30) {
+ //28 steps between 2 and 30
+ //54 dbm between 53 and 109
+ float stepSize = 54.0 / 28.0;
+ iDbm = -109 + (int)(stepSize * (iRssi-2));
+ } else {
+ iDbm = -51;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CellularRadio::convertdBmToSignalStrength(const int32_t& iDBm, int32_t& iRssi) {
+ //Telit Conversion
+ if(iDBm <= -113) {
+ iRssi = 0;
+ } else if(iDBm <= -111) {
+ iRssi = 1;
+ } else if(iDBm <= -53) {
+ //54 dbm between -109 and -53
+ //28 steps between 2 and 30
+ float stepSize = 28.0/54.0;
+ iRssi = ((iDBm + 109)*stepSize) + 2;
+ } else {
+ iRssi = 31;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CellularRadio::getEcho(bool& bEnabled) {
+ printTrace("%s| Echo Test", m_sName.c_str());
+ std::string sResult = sendCommand("AT");
+ if(sResult.size() == 0) {
+ return NO_RESPONSE;
+ }
+
+ if(sResult.find("AT") != std::string::npos) {
+ bEnabled = true;
+ } else {
+ bEnabled = false;
+ }
+ m_bEchoEnabled = bEnabled;
+ return SUCCESS;
+}
+
+CellularRadio::CODE CellularRadio::setEcho(bool bEnabled) {
+ CODE eCode = FAILURE;
+ if(bEnabled) {
+ eCode = sendBasicCommand("ATE1");
+ m_bEchoEnabled = (eCode == SUCCESS ) ? true : m_bEchoEnabled;
+ } else {
+ eCode = sendBasicCommand("ATE0");
+ m_bEchoEnabled = (eCode == SUCCESS ) ? false : m_bEchoEnabled;
+ }
+
+ return eCode;
+}
+
+CellularRadio::CODE CellularRadio::getStaticInformation(Json::Value& jData) {
+ printTrace("%s| Get Static Information", m_sName.c_str());
+
+ printTrace("%s| Static Information:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str());
+
+ return FAILURE;
+}
+
+/* AT#RFSTS - NETWORK STATUS
+
+ (GSM network)
+ #RFSTS:<PLMN>,<ARFCN>,<RSSI>,<LAC>,<RAC>,<TXPWR>,<MM>,<RR>,<NOM>,<CID>,<IMSI>,<NetNameAsc>,<SD>,<ABND>
+ Where:
+ <PLMN> - Country code and operator code(MCC, MNC)
+ <ARFCN> - GSM Assigned Radio Channel
+ <RSSI> - Received Signal Strength Indication
+ <LAC> - Localization Area Code
+ <RAC> - Routing Area Code
+ <TXPWR> - Tx Power
+ <MM> - Mobility Management state
+ <RR> - Radio Resource state
+ <NOM> - Network Operator Mode
+ <CID> - Cell ID
+ <IMSI> - International Mobile Subscriber Identity
+ <NetNameAsc> - Operator name
+ <SD> - Service Domain
+ 0 - No Service
+ 1 - CS only
+ 2 - PS only
+ 3 - CS+PS
+ <ABND> - Active Band
+ 1 - GSM 850
+ 2 - GSM 900
+ 3 - DCS 1800
+ 4 - PCS 1900
+
+
+ (WCDMA network)
+ #RFSTS:
+ <PLMN>,<UARFCN>,<PSC>,<Ec/Io>,<RSCP>, RSSI>,<LAC>,<RAC>,<TXPWR>,<DRX>,<MM>,<RRC>,<NOM>,<BLER>,<CID>,<IMSI>,
+ <NetNameAsc>,<SD>,<nAST>[,<nUARFCN><nPSC>,<nEc/Io>]
+ Where:
+ <PLMN> - Country code and operator code(MCC, MNC)
+ <UARFCN> - UMTS Assigned Radio Channel
+ <PSC> - Active PSC(Primary Synchronization Code)
+ <Ec/Io> - Active Ec/Io(chip energy per total wideband power in dBm)
+ <RSCP> - Active RSCP (Received Signal Code Power in dBm)
+ <RSSI> - Received Signal Strength Indication
+ <LAC> - Localization Area Code
+ <RAC> - Routing Area Code
+ <TXPWR> - Tx Power
+ <DRX> - Discontinuous reception cycle Length (cycle length in ms)
+ <MM> - Mobility Management state
+ <RR> - Radio Resource state
+ <NOM> - Network Operator Mode
+ <BLER> - Block Error Rate (e.g., 005 means 0.5 %)
+ <CID> - Cell ID
+ <IMSI> - International Mobile Station ID
+ <NetNameAsc> - Operator name
+ <SD> - Service Domain (see above)
+ <nAST> - Number of Active Set (Maximum 6)
+ <nUARFCN> UARFCN of n th active set
+ <nPSC> PSC of n th active set
+ <nEc/Io > Ec/Io of n th active Set
+
+ (LTE Network)
+ #RFSTS:
+ <PLMN> -
+ <EARFCN> -
+ <RSRP> -
+ <RSSI> -
+ <RSRQ> -
+ <TAC> -
+ [<TXPWR>] -
+ <DRX> -
+ <MM> -
+ <RRC> -
+ <CID> -
+ <IMSI> -
+ [<NetNameAsc>] -
+ <SD> -
+ <ABND> -
+*/
+CellularRadio::CODE CellularRadio::getNetworkStatus(Json::Value& jData) {
+ int32_t iValue;
+ std::string sValue;
+ const uint32_t GSM_NETWORK_FORMAT = 14;
+ const uint32_t WCDMA_NETWORK_FORMAT = 19;
+ const uint32_t LTE_NETWORK_FORMAT = 16;
+
+ printTrace("%s| Get Network Status", m_sName.c_str());
+ std::string sCmd("AT#RFSTS");
+ std::string sResult = sendCommand(sCmd);
+ if (sResult.find("#RFSTS:") == std::string::npos) {
+ printDebug("%s| Network Status command returned unexpected response: [%s][%s]", m_sName.c_str(), sCmd.c_str(), sResult.c_str());
+ return FAILURE;
+ }
+
+ size_t start = sResult.find(":") + 1; //Position right after "#RFSTS:"
+ std::vector<std::string> vParts = MTS::Text::split(MTS::Text::trim(sResult.substr(start)), ",");
+
+ if(vParts.size() >= 3) {
+ //Country Code and Operator Code
+ std::vector<std::string> vPLMN = MTS::Text::split(vParts[0], ' ');
+ if(vPLMN.size() == 2) {
+ jData[KEY_MCC] = MTS::Text::strip(vPLMN[0], '"');
+ jData[KEY_MNC] = MTS::Text::strip(vPLMN[1], '"');
+ }
+
+ jData[KEY_CHANNEL] = vParts[1];
+ } else {
+ //Unknown Format
+ return FAILURE;
+ }
+
+ if(vParts.size() == GSM_NETWORK_FORMAT ) {
+ //Parse as GSM Network Format
+ jData[KEY_RSSIDBM] = vParts[2];
+ jData[KEY_LAC] = vParts[3];
+ jData[KEY_RAC] = vParts[4];
+ jData[KEY_TXPWR] = vParts[5];
+ jData[KEY_MM] = vParts[6];
+ jData[KEY_RR] = vParts[7];
+ jData[KEY_NOM] = vParts[8];
+ jData[KEY_CID] = vParts[9];
+ jData[KEY_IMSI] = MTS::Text::strip(vParts[10], '"');
+ jData[KEY_NETWORK] = MTS::Text::strip(vParts[11], '"');
+ if(MTS::Text::parse(iValue, vParts[12]) && convertServiceDomainToString((SERVICEDOMAIN)iValue, sValue) == SUCCESS) {
+ jData[KEY_SD] = sValue;
+ }
+ if(MTS::Text::parse(iValue, vParts[13]) && convertActiveBandToString((ACTIVEBAND)iValue, sValue) == SUCCESS) {
+ jData[KEY_ABND] = sValue;
+ }
+ } else if(vParts.size() >= WCDMA_NETWORK_FORMAT) {
+ Json::Value jDebug;
+
+ //Parse as WCDMA Network Format
+
+ jDebug[KEY_PSC] = vParts[2];
+ jDebug[KEY_ECIO] = vParts[3];
+ jDebug[KEY_RSCP] = vParts[4];
+
+ jData[KEY_RSSIDBM] = vParts[5];
+ jData[KEY_LAC] = vParts[6];
+ jData[KEY_RAC] = vParts[7];
+
+ jDebug[KEY_TXPWR] = vParts[8];
+ jDebug[KEY_DRX] = vParts[9];
+ jDebug[KEY_MM] = vParts[10];
+ jDebug[KEY_RR] = vParts[11];
+ jDebug[KEY_NOM] = vParts[12];
+
+ if(vParts[13].size() != 0) {
+ jDebug[KEY_BLER] = vParts[13];
+ } else {
+ jDebug[KEY_BLER] = "000";
+ }
+
+ jData[KEY_CID] = vParts[14];
+ jData[KEY_IMSI] = MTS::Text::strip(vParts[15], '"');
+ jData[KEY_NETWORK] = MTS::Text::strip(vParts[16], '"');
+
+ if(MTS::Text::parse(iValue, vParts[17]) && convertServiceDomainToString((SERVICEDOMAIN)iValue, sValue) == SUCCESS) {
+ jDebug[KEY_SD] = sValue;
+ }
+ //Ignoring Active Set Values
+ // <nAST> - Number of Active Set (Maximum 6)
+ // <nUARFCN> - UARFCN of n th active set
+ // <nPSC> - PSC of n th active set
+ // <nEc/Io > - Ec/Io of n th active Set
+
+ jData[KEY_DEBUG] = jDebug;
+ } else if(vParts.size() >= LTE_NETWORK_FORMAT) {
+ Json::Value jDebug;
+
+ //Parse as WCDMA Network Format
+
+ jDebug["rsrp"] = vParts[2];
+ jDebug[KEY_RSSIDBM] = vParts[3];
+ jDebug["rsrq"] = vParts[4];
+
+ jData["tac"] = vParts[5];
+ jDebug[KEY_TXPWR] = vParts[6];
+ //Odd empty index at 7
+ jData[KEY_DRX] = vParts[8];
+
+ jDebug[KEY_MM] = vParts[9];
+ jDebug["rrc"] = vParts[10];
+ jDebug[KEY_CID] = vParts[11];
+ jData[KEY_IMSI] = MTS::Text::strip(vParts[12], '"');
+ jData[KEY_NETWORK] = MTS::Text::strip(vParts[13], '"');
+
+ if(MTS::Text::parse(iValue, vParts[13]) && convertServiceDomainToString((SERVICEDOMAIN)iValue, sValue) == SUCCESS) {
+ jDebug[KEY_SD] = sValue;
+ }
+ //Ignoring Active Set Values
+ // <nAST> - Number of Active Set (Maximum 6)
+ // <nUARFCN> - UARFCN of n th active set
+ // <nPSC> - PSC of n th active set
+ // <nEc/Io > - Ec/Io of n th active Set
+
+ jData[KEY_DEBUG] = jDebug;
+ }
+
+ getCommonNetworkStats(jData);
+
+ printTrace("%s| Network Status:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str());
+
+ return SUCCESS;
+}
+
+void CellularRadio::getCommonNetworkStats(Json::Value& jData) {
+
+ bool bRoaming = false;
+ if(getRoaming(bRoaming) == SUCCESS) {
+ jData[KEY_ROAMING] = bRoaming;
+ }
+
+ int32_t iRssi;
+ if(getSignalStrength(iRssi) == SUCCESS) {
+ jData[KEY_RSSI] = iRssi;
+ int32_t dBm;
+ if(!jData.isMember(KEY_RSSIDBM) && convertSignalStrengthTodBm(iRssi, dBm) == SUCCESS) {
+ //Add RSSI in dBm format
+ jData[KEY_RSSIDBM] = MTS::Text::format(dBm);
+ }
+ }
+
+ std::string sService;
+ if(getService(sService) == SUCCESS) {
+ jData[KEY_SERVICE] = sService;
+ }
+ std::string sDate, sTime, sTimeZone;
+ if(getTime(sDate, sTime, sTimeZone) == SUCCESS) {
+
+ jData[KEY_DATETIME] = sDate + " " + sTime + " GMT" + sTimeZone;
+ }
+}
+
+void CellularRadio::initMipProfile(Json::Value& jData) {
+ jData[KEY_MIP_ID] = 0;
+ jData[KEY_MIP_ENABLED] = false;
+ jData[KEY_MIP_NAI] = VALUE_UNKNOWN;
+ jData[KEY_MIP_HOMEADDRESS] = VALUE_UNKNOWN;
+ jData[KEY_MIP_PRIMARYHA] = VALUE_UNKNOWN;
+ jData[KEY_MIP_SECONDARYHA] = VALUE_UNKNOWN;
+ jData[KEY_MIP_MNAAASPI] = VALUE_UNKNOWN;
+ jData[KEY_MIP_MNHASPI] = VALUE_UNKNOWN;
+ jData[KEY_MIP_MNAAASS] = false;
+ jData[KEY_MIP_MNHASS] = false;
+}
+
+CellularRadio::CODE CellularRadio::getRegistration(REGISTRATION& eRegistration) {
+ std::string sCmd("AT+CREG?");
+ std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 5000);
+ if (sResult.find("+CREG: ") == std::string::npos) {
+ if(sResult.size() == 0) {
+ printDebug("%s| Registration command returned no response: [%s]", m_sName.c_str());
+ return NO_RESPONSE;
+ }
+ printDebug("%s| Registration command returned unexpected response: [%s]", m_sName.c_str(), sResult.c_str());
+ return FAILURE;
+ }
+
+ size_t start = sResult.find(',');
+ size_t stop = sResult.find(' ', start);
+ std::string sRegStat = sResult.substr(start + 1, stop - start - 1);
+ int32_t value;
+ sscanf(sRegStat.c_str(), "%d", &value);
+ eRegistration = (REGISTRATION)value;
+ return SUCCESS;
+}
+
+CellularRadio::CODE CellularRadio::convertRegistrationToString(REGISTRATION eRegistration, std::string& sRegistration) {
+
+ CODE eCode = FAILURE;
+ switch (eRegistration) {
+ case NOT_REGISTERED: sRegistration = VALUE_NOT_REGISTERED; eCode = SUCCESS; break;
+ case REGISTERED: sRegistration = VALUE_REGISTERED; eCode = SUCCESS; break;
+ case SEARCHING: sRegistration = VALUE_SEARCHING; eCode = SUCCESS; break;
+ case DENIED: sRegistration = VALUE_DENIED; eCode = SUCCESS; break;
+ case UNKNOWN: sRegistration = VALUE_UNKNOWN; eCode = SUCCESS; break;
+ case ROAMING: sRegistration = VALUE_ROAMING; eCode = SUCCESS; break;
+ }
+ return eCode;
+}
+
+CellularRadio::CODE CellularRadio::validateMsl(const Json::Value& jArgs) {
+ printTrace("%s| Validate MSL", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::setMdn(const Json::Value& jArgs) {
+ printTrace("%s| Set MDN", m_sName.c_str());
+
+ if(!jArgs["mdn"].isString()) {
+ return INVALID_ARGS;
+ }
+
+ std::string sCmd("AT#SNUM=1,\"");
+ sCmd += jArgs["mdn"].asString() + "\"";
+
+ std::string sResult = sendCommand(sCmd);
+ size_t end = sResult.find(RSP_OK);
+ if (end == std::string::npos) {
+ printWarning("%s| Unable to set MDN for radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+CellularRadio::CODE CellularRadio::setMsid(const Json::Value& jArgs) {
+ printTrace("%s| Set MSID", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::getMipProfile(Json::Value& jMipProfile) {
+ printTrace("%s| Get MIP Active Profile", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::setMipActiveProfile(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP Active Profile", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::setMipNai(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP NAI", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::setMipHomeIp(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP Home IP", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::setMipPrimaryHa(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP Primary HA", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::setMipSecondaryHa(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP Secondary HA", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::setMipMnAaaSpi(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP MN-AAA SPI", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::setMipMnHaSpi(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP MN-HA SPI", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::setMipRevTun(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP Rev Tun", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::setMipMnAaaSs(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP MN-AAA SS", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::setMipMnHaSs(const Json::Value& jArgs) {
+ printTrace("%s| Set MIP MN-HA SS", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::updateDc(const Json::Value& jArgs, UpdateCb& stepCb) {
+ printTrace("%s| Update Device Configuration", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::updatePrl(const Json::Value& jArgs, UpdateCb& stepCb) {
+ printTrace("%s| Update Preferred Roaming List", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::updateFumo(const Json::Value& jArgs, UpdateCb& stepCb) {
+ printTrace("%s| Update Firmware Update Management Object", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::resetHfa(const Json::Value& jArgs, UpdateCb& stepCb) {
+ printTrace("%s| HFA Reset", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::activate(const Json::Value& jArgs, UpdateCb& stepCb) {
+ printTrace("%s| Activation", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
+CellularRadio::CODE CellularRadio::sendBasicCommand(const std::string& sCmd, int32_t iTimeoutMillis, const char& ESC) {
+ std::string response = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, iTimeoutMillis, ESC);
+ if (response.size() == 0) {
+ return NO_RESPONSE;
+ } else if (response.find(RSP_OK) != std::string::npos) {
+ return SUCCESS;
+ } else if (response.find(RSP_ERROR) != std::string::npos) {
+ return ERROR;
+ } else {
+ return FAILURE;
+ }
+}
+
+std::string CellularRadio::sendCommand(const std::string& sCmd, const std::vector<std::string>& vBail, int32_t timeoutMillis, const char& ESC) {
+ return sendCommand(m_apIo, sCmd, vBail, timeoutMillis, ESC);
+}
+
+std::string CellularRadio::sendCommand(MTS::AutoPtr<MTS::IO::Connection>& apIo, const std::string& sCmd,
+ const std::vector<std::string>& vBail, int32_t timeoutMillis, const char& ESC) {
+ IsNeedMoreData isNeedMoreData = [&vBail](const std::string& iterationData, const std::string& allData)->bool {
+ for(size_t i = 0; i < vBail.size(); i++) {
+ const std::string& sBail = vBail[i];
+ if(sBail.size() > 0) {
+ if(allData.find(sBail) != std::string::npos) {
+ //Return when bail string is found
+ printTrace("RADIO| Found bail string [%s]", sBail.c_str());
+ return false;
+ }
+ }
+ }
+ return true;
+ };
+
+ return sendCommand(apIo, sCmd, isNeedMoreData, timeoutMillis, ESC);
+}
+
+std::string CellularRadio::sendCommand(const std::string& sCmd, MTS::IO::CellularRadio::IsNeedMoreData& isNeedMoreData, int32_t timeoutMillis, const char& ESC) {
+ return sendCommand(m_apIo, sCmd, isNeedMoreData, timeoutMillis, ESC);
+}
+
+std::string CellularRadio::sendCommand(MTS::AutoPtr<MTS::IO::Connection>& apIo, const std::string& sCmd,
+ IsNeedMoreData& isNeedMoreData, int32_t timeoutMillis, const char& ESC) {
+ if(MTS::Logger::getPrintLevel() >= MTS::Logger::PrintLevel::TRACE_LEVEL) {
+ printTrace("RADIO| Sending command [%s]", sCmd.c_str());
+ }
+ if(apIo.isNull()) {
+ printError("RADIO| IO is not set in sendCommand");
+ return "";
+ }
+
+ int32_t iResult;
+ if(ESC == 0x00) {
+ iResult = apIo->write(sCmd.data(), sCmd.size());
+ } else {
+ std::string sNewCmd(sCmd);
+ sNewCmd.push_back(ESC);
+ iResult = apIo->write(sNewCmd.data(), sNewCmd.size());
+ }
+
+ if(iResult == -1) {
+ printError("RADIO| Failed to send command to radio");
+ return "";
+ }
+
+ bool done = false;
+ const uint32_t capacity = 1024;
+ char buffer[capacity];
+ std::string sResult;
+ Timer timer;
+ timer.start();
+ do {
+ int32_t iterationTimeout = 100;
+ int bytesRead = apIo->read((char*)buffer, capacity, iterationTimeout);
+ if(bytesRead == -1) {
+ printError("RADIO| Failed to read from radio");
+ break;
+ }
+
+ std::string sIteration((char*)buffer, bytesRead);
+ sResult += sIteration;
+
+ if(isNeedMoreData && !isNeedMoreData(sIteration, sResult)) {
+ printTrace("RADIO| No more data needed");
+ return sResult;
+ }
+ if(timeoutMillis >= 0) {
+ done = (timer.getMillis() >= (uint64_t)timeoutMillis);
+ } else {
+ //Do not stop looping until bail string is found
+ }
+ } while(!done);
+
+ //Timed out
+ return sResult;
+}
+
+CellularRadio::CODE CellularRadio::test(MTS::AutoPtr<MTS::IO::Connection>& apIo, uint32_t timeoutSeconds) {
+ printTrace("RADIO| Basic Test");
+ uint32_t count = 0;
+ std::string sCmd("AT");
+ do {
+ std::string sResult = sendCommand(apIo, sCmd);
+ if (sResult.find(RSP_OK) == std::string::npos) {
+ printTrace("RADIO| Waiting for basic radio communication [%s] ...", sResult.c_str());
+ } else {
+ break;
+ }
+ count++;
+ } while (count < timeoutSeconds);
+
+ if(count == timeoutSeconds) {
+ printWarning("RADIO| Basic radio communication FAILED");
+ return NO_RESPONSE;
+ }
+ return SUCCESS;
+}
+
+std::string CellularRadio::extractModelFromResult(const std::string& sResult) {
+ std::string sModel(CellularRadio::VALUE_NOT_SUPPORTED);
+ if(sResult.find("HE910-D") != std::string::npos) {
+ sModel = "HE910-D";
+ } else if(sResult.find("HE910-EUD") != std::string::npos) {
+ sModel = "HE910-EUD";
+ } else if(sResult.find("LE910-NAG") != std::string::npos) {
+ sModel = "LE910-NAG";
+ } else if(sResult.find("LE910-SVG") != std::string::npos) {
+ sModel = "LE910-SVG";
+ } else if(sResult.find("LE910-EUG") != std::string::npos) {
+ sModel = "LE910-EUG";
+ } else if(sResult.find("GE910") != std::string::npos) {
+ sModel = "GE910";
+ } else if(sResult.find("DE910-DUAL") != std::string::npos) {
+ sModel = "DE910-DUAL";
+ } else if(sResult.find("CE910") != std::string::npos) {
+ sModel = "CE910";
+ }
+ return sModel;
+}
+
+std::string CellularRadio::getCodeAsString(CODE eCode) {
+ switch(eCode) {
+ case SUCCESS:
+ return "SUCCESS";
+ case ERROR:
+ return "ERROR";
+ case FAILURE:
+ return "FAILURE";
+ case NO_RESPONSE:
+ return "NO RESPONSE";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+bool CellularRadio::splitAndAssign(const std::string& sLine, const std::string& sKey, Json::Value& jParent, const std::string& sJsonKey, Json::ValueType eType) {
+
+ std::vector<std::string> vParts = MTS::Text::split(sLine, ":", 2);
+
+ if(vParts.size() == 2 && vParts[0] == sKey) {
+ if(eType == Json::ValueType::stringValue) {
+ jParent[sJsonKey] = MTS::Text::trim(vParts[1]);
+ } else if (eType == Json::ValueType::intValue || eType == Json::ValueType::uintValue) {
+ //TODO:
+ printWarning("%s| Unable to parse requested type from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str());
+ return false;
+ } else if(eType == Json::ValueType::realValue) {
+ //TODO:
+ printWarning("%s| Unable to parse requested type from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str());
+ return false;
+ } else if(eType == Json::ValueType::booleanValue) {
+ //TODO:
+ printWarning("%s| Unable to parse requested type from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str());
+ return false;
+ } else {
+ printWarning("%s| Unable to parse requested type from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str());
+ return false;
+ }
+ } else {
+ printWarning("%s| Unable to parse %s from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str());
+ return false;
+ }
+
+ return true;
+}
+
+bool CellularRadio::getCarrierFromFirmware(const std::string& sFirmware, std::string& sCarrier) {
+ // Telit Radios
+ // H.ab.zyx => 3 Main Components
+ // "H" = Hardware -> 15 = DE910 family, 18 = CE910 family, 12 = HE910 family
+ // "a" = Hardware version
+ // "b" = Software Major Version
+ // "z" = is the product type, i.e. DUAL or SC
+ // "y" = is the carrier variant
+ // "x" = is the firmware version
+ // Telit will do their best to keep the carrier variant as "0" for Sprint, "1" for Aeris, and "2" for Verizon.
+
+ const uint32_t CARRIER_INDEX = 1; //y in [zyx]
+
+ bool bResult = false;
+ std::vector<std::string> vParts = MTS::Text::split(sFirmware, '.');
+
+ if(vParts.size() == 3) {
+ //CDMA firmware version notation
+ if(vParts[0] == "15" || vParts[0] == "18") {
+ //DE910 or CE910 -> Good good
+ std::string sID = vParts[2];
+ if(sID.size() == 3) {
+ char cId = sID[CARRIER_INDEX];
+
+ //Good good
+ if(cId == '0') {
+ sCarrier = VALUE_CARRIER_SPRINT;
+ bResult = true;
+ }
+ if(cId == '1') {
+ sCarrier = VALUE_CARRIER_AERIS;
+ bResult = true;
+ }
+ if(cId == '2') {
+ sCarrier = VALUE_CARRIER_VERIZON;
+ bResult = true;
+ }
+ }
+ }
+ }
+
+ return bResult;
+}
+
+bool CellularRadio::getHardwareVersionFromFirmware(const std::string& sFirmware, std::string& sHardware) {
+ // Telit Radios
+ // H.ab.zyx => 3 Main Components
+ // "H" = Hardware -> 15 = DE910 family, 18 = CE910 family, 12 = HE910 family
+ // "a" = Hardware version
+ // "b" = Software Major Version
+ // "z" = is the product type, i.e. DUAL or SC
+ // "y" = is the carrier variant
+ // "x" = is the firmware version
+ // Telit will do their best to keep the carrier variant as "0" for Sprint, "1" for Aeris, and "2" for Verizon.
+
+ const uint32_t HARDWARE_INDEX = 0; //a in [ab]
+
+ bool bResult = false;
+ std::vector<std::string> vParts = MTS::Text::split(sFirmware, '.');
+
+ if(vParts.size() == 3) {
+ //GSM Hardware Version
+ if(!(vParts[0] == "15" || vParts[0] == "18")) {
+ //Not DE910 or CE910 -> Good good
+ std::string sVersion = vParts[1];
+ if(sVersion.size() == 2) {
+ sHardware = "1.";
+ sHardware += sVersion[HARDWARE_INDEX];
+ bResult = true;
+ }
+ }
+ }
+
+ return bResult;
+
+}
diff --git a/src/MTS_IO_CellularRadioFactory.cpp b/src/MTS_IO_CellularRadioFactory.cpp
new file mode 100644
index 0000000..3a5cb74
--- /dev/null
+++ b/src/MTS_IO_CellularRadioFactory.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_CellularRadioFactory.cpp
+ \brief A brief description
+ \date Nov 5, 2014
+ \author sgodinez
+
+ A more elaborate description
+*/
+
+#include <mts/MTS_IO_CellularRadioFactory.h>
+#include <mts/MTS_IO_HE910DRadio.h>
+#include <mts/MTS_IO_HE910EUDRadio.h>
+#include <mts/MTS_IO_LE910NAGRadio.h>
+#include <mts/MTS_IO_LE910SVGRadio.h>
+#include <mts/MTS_IO_LE910EUGRadio.h>
+#include <mts/MTS_IO_GE910Radio.h>
+#include <mts/MTS_IO_CE910Radio.h>
+#include <mts/MTS_IO_DE910Radio.h>
+#include <mts/MTS_Logger.h>
+
+using namespace MTS::IO;
+
+CellularRadioFactory::CellularRadioFactory() {
+ m_mCreationMap[HE910DRadio::MODEL_NAME] = &CellularRadioFactory::createHE910D;
+ m_mCreationMap[HE910EUDRadio::MODEL_NAME] = &CellularRadioFactory::createHE910EUD;
+ m_mCreationMap[LE910NAGRadio::MODEL_NAME] = &CellularRadioFactory::createLE910NAG;
+ m_mCreationMap[LE910SVGRadio::MODEL_NAME] = &CellularRadioFactory::createLE910SVG;
+ m_mCreationMap[LE910EUGRadio::MODEL_NAME] = &CellularRadioFactory::createLE910EUG;
+ m_mCreationMap[GE910Radio::MODEL_NAME] = &CellularRadioFactory::createGE910;
+ m_mCreationMap[DE910Radio::MODEL_NAME] = &CellularRadioFactory::createDE910;
+ m_mCreationMap[CE910Radio::MODEL_NAME] = &CellularRadioFactory::createCE910;
+}
+
+MTS::IO::CellularRadio* CellularRadioFactory::create(const std::string& sModel, const std::string& sPort) {
+
+ std::string model(sModel);
+
+ if(model.size() == 0) {
+ model = identifyRadio(sPort);
+ }
+
+ if(m_mCreationMap.count(model)) {
+ //Call this object's function via a function pointer
+ return (this->*m_mCreationMap[model])(sPort);
+ }
+
+ printWarning("[CELLULARRADIOFACTORY] Unknown radio [%s]. Attempting HE910 version.", model.c_str());
+
+ return new HE910DRadio(sPort);
+}
+
+std::string CellularRadioFactory::identifyRadio(const std::string& sPort) {
+ MTS::AutoPtr<Connection> apIo;
+
+ //Attempt to open port to radio
+ apIo.reset(new SerialConnection(SerialConnection::Builder(sPort).baudRate(115200).useLockFile().build()));
+ while(!apIo->open(30000)) {
+ printError("CellularRadioFactory| Failed to open radio port [%s]", sPort.c_str());
+ return CellularRadio::VALUE_UNKNOWN;
+ }
+
+ //Attempt basic radio communication
+ if(CellularRadio::test(apIo) != CellularRadio::SUCCESS) {
+ printError("CellularRadioFactory| Failed to communicate with radio on port [%s]", sPort.c_str());
+ apIo->close();
+ return CellularRadio::VALUE_UNKNOWN;
+ }
+
+ //Get model
+ int count = 0;
+ std::string sCmd("ATI4");
+ std::string sResult;
+ do {
+ sResult = CellularRadio::sendCommand(apIo, sCmd, CellularRadio::DEFAULT_BAIL_STRINGS, 1000, CellularRadio::CR);
+ if (sResult.find("OK") == std::string::npos) {
+ printDebug("RADIO| Attempting to get radio model [%s] ...", sResult.c_str());
+ } else {
+ break;
+ }
+ count++;
+ } while (count < 30);
+
+ if(count == 30) {
+ printDebug("RADIO| Unable to get radio model");
+ apIo->close();
+ return CellularRadio::VALUE_UNKNOWN;
+ }
+
+ std::string sModel = CellularRadio::extractModelFromResult(sResult);
+ printDebug("RADIO| Extracted [%s] from ATI4 query", sModel.c_str());
+ apIo->close();
+ return sModel;
+}
+
+CellularRadio* CellularRadioFactory::createHE910D(const std::string& sPort) {
+ return new HE910DRadio(sPort);
+}
+
+CellularRadio* CellularRadioFactory::createHE910EUD(const std::string& sPort) {
+ return new HE910EUDRadio(sPort);
+}
+
+CellularRadio* CellularRadioFactory::createLE910NAG(const std::string& sPort) {
+ return new LE910NAGRadio(sPort);
+}
+
+CellularRadio* CellularRadioFactory::createLE910SVG(const std::string& sPort) {
+ return new LE910SVGRadio(sPort);
+}
+
+CellularRadio* CellularRadioFactory::createLE910EUG(const std::string& sPort) {
+ return new LE910EUGRadio(sPort);
+}
+
+CellularRadio* CellularRadioFactory::createGE910(const std::string& sPort) {
+ return new GE910Radio(sPort);
+}
+
+CellularRadio* CellularRadioFactory::createDE910(const std::string& sPort) {
+ return new DE910Radio(sPort);
+}
+
+CellularRadio* CellularRadioFactory::createCE910(const std::string& sPort) {
+ return new CE910Radio(sPort);
+}
diff --git a/src/MTS_IO_Connection.cpp b/src/MTS_IO_Connection.cpp
new file mode 100644
index 0000000..36a91ed
--- /dev/null
+++ b/src/MTS_IO_Connection.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_Connection.cpp
+ \brief A brief description
+ \date Jan 15, 2013
+ \author sgodinez
+
+ A more elaborate description than necessary.
+*/
+
+
+#include <mts/MTS_IO_Connection.h>
+#include <mts/MTS_Buffer.h>
+#include <sys/select.h>
+
+using namespace MTS;
+using namespace MTS::IO;
+
+int32_t Connection::BLOCKING = -1;
+
+Connection::Connection(const std::string& name)
+: m_sName(name)
+, m_bClosed(true)
+, m_bCloseable(true) {
+ m_apLock.reset(new Lock());
+ m_apReadLock.reset(new Lock());
+ m_apWriteLock.reset(new Lock());
+}
+
+Connection::~Connection() {
+ m_apWriteLock.reset();
+ m_apReadLock.reset();
+ m_apLock.reset();
+}
+
+const std::string& Connection::getName() const {
+ return m_sName;
+}
+
+bool Connection::open(const int32_t& timeoutMillis) {
+ bool bOpened = true;
+ m_apLock->lock();
+ if (m_bClosed) {
+ bOpened = doOpen(timeoutMillis);
+ if (bOpened) {
+ m_bClosed = false;
+ }
+ }
+ m_apLock->unlock();
+ return bOpened;
+}
+
+void Connection::close() {
+ m_apLock->lock();
+ if (m_bCloseable) {
+ doClose();
+ m_bClosed = true;
+ }
+ m_apLock->unlock();
+}
+
+bool Connection::isClosed() const {
+ m_apLock->lock();
+ bool bResult = m_bClosed;
+ m_apLock->unlock();
+ return bResult;
+}
+
+void Connection::setCloseable(bool bCloseable) {
+ m_apLock->lock();
+ m_bCloseable = bCloseable;
+ m_apLock->unlock();
+}
+
+bool Connection::isCloseable() const {
+ m_apLock->lock();
+ bool bResult = m_bCloseable;
+ m_apLock->unlock();
+ return bResult;
+}
+
+int Connection::read(std::string& sBuffer, const uint32_t& iSize, int32_t& timeoutMillis) {
+ int result = -1;
+ if (isClosed()) {
+ return result;
+ } else {
+ char buffer[iSize];
+ m_apReadLock->lock();
+ result = doRead(buffer, iSize, timeoutMillis);
+ m_apReadLock->unlock();
+ if(result > 0) {
+ sBuffer = std::string(buffer, result);
+ }
+ }
+
+ return result;
+}
+
+int Connection::read(Buffer& oBuffer, const uint32_t& iSize, int32_t& timeoutMillis) {
+ int result = -1;
+ if (isClosed()) {
+ return result;
+ } else {
+ oBuffer.setCapacity(iSize);
+ m_apReadLock->lock();
+ result = doRead((char*)oBuffer.getBuffer(), iSize, timeoutMillis);
+ m_apReadLock->unlock();
+ }
+
+ return result;
+}
+
+int Connection::read(char* pBuffer, const uint32_t& iSize, int32_t& timeoutMillis) {
+ int result = -1;
+ if (isClosed()) {
+ return result;
+ } else {
+ m_apReadLock->lock();
+ result = doRead(pBuffer, iSize, timeoutMillis);
+ m_apReadLock->unlock();
+ }
+ return result;
+}
+
+int Connection::write(const char* pBuffer, const uint32_t& iSize, int32_t& timeoutMillis) {
+ int result = -1;
+ if (isClosed()) {
+ return result;
+ } else {
+ m_apWriteLock->lock();
+ result = doWrite(pBuffer, iSize, timeoutMillis);
+ m_apWriteLock->unlock();
+ }
+ return result;
+}
+
diff --git a/src/MTS_IO_DE910Radio.cpp b/src/MTS_IO_DE910Radio.cpp
new file mode 100644
index 0000000..766d7d1
--- /dev/null
+++ b/src/MTS_IO_DE910Radio.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_DE910Radio.cpp
+ \brief A brief description
+ \date Nov 6, 2014
+ \author sgodinez
+
+ A more elaborate description
+*/
+
+#include <mts/MTS_IO_DE910Radio.h>
+
+using namespace MTS::IO;
+
+const std::string DE910Radio::MODEL_NAME("DE910-DUAL");
+
+DE910Radio::DE910Radio(const std::string& sPort)
+: CdmaRadio(MODEL_NAME, sPort)
+{
+
+}
+
diff --git a/src/MTS_IO_GE910Radio.cpp b/src/MTS_IO_GE910Radio.cpp
new file mode 100644
index 0000000..013837b
--- /dev/null
+++ b/src/MTS_IO_GE910Radio.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_GE910Radio.cpp
+ \brief A brief description
+ \date Nov 6, 2014
+ \author sgodinez
+
+ A more elaborate description
+*/
+
+#include <mts/MTS_IO_GE910Radio.h>
+
+using namespace MTS::IO;
+
+const std::string GE910Radio::MODEL_NAME("GE910");
+
+GE910Radio::GE910Radio(const std::string& sPort)
+: CellularRadio(MODEL_NAME, sPort)
+{
+
+}
+
diff --git a/src/MTS_IO_HE910DRadio.cpp b/src/MTS_IO_HE910DRadio.cpp
new file mode 100644
index 0000000..b159a9c
--- /dev/null
+++ b/src/MTS_IO_HE910DRadio.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_HE910DRadio.cpp
+ \brief A brief description
+ \date Nov 6, 2014
+ \author sgodinez
+
+ A more elaborate description
+*/
+
+
+#include <mts/MTS_IO_HE910DRadio.h>
+
+using namespace MTS::IO;
+
+const std::string HE910DRadio::MODEL_NAME("HE910-D");
+
+HE910DRadio::HE910DRadio(const std::string& sPort)
+: HE910Radio(MODEL_NAME, sPort)
+{
+
+}
diff --git a/src/MTS_IO_HE910EUDRadio.cpp b/src/MTS_IO_HE910EUDRadio.cpp
new file mode 100644
index 0000000..4ae7e19
--- /dev/null
+++ b/src/MTS_IO_HE910EUDRadio.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_HE910EUDRadio.cpp
+ \brief A brief description
+ \date Nov 6, 2014
+ \author sgodinez
+
+ A more elaborate description
+*/
+
+#include <mts/MTS_IO_HE910EUDRadio.h>
+
+using namespace MTS::IO;
+
+const std::string HE910EUDRadio::MODEL_NAME("HE910-EUD");
+
+HE910EUDRadio::HE910EUDRadio(const std::string& sPort)
+: HE910Radio(MODEL_NAME, sPort)
+{
+
+}
+
+
diff --git a/src/MTS_IO_HE910Radio.cpp b/src/MTS_IO_HE910Radio.cpp
new file mode 100644
index 0000000..3a7851a
--- /dev/null
+++ b/src/MTS_IO_HE910Radio.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_HE910Radio.cpp
+ \brief A brief description
+ \date Nov 6, 2014
+ \author sgodinez
+
+ A more elaborate description
+*/
+
+#include <mts/MTS_IO_HE910Radio.h>
+
+using namespace MTS::IO;
+
+HE910Radio::HE910Radio(const std::string& sHE910Model, const std::string& sPort)
+: CellularRadio(sHE910Model, sPort)
+{
+
+}
+
+
diff --git a/src/MTS_IO_LE910EUGRadio.cpp b/src/MTS_IO_LE910EUGRadio.cpp
new file mode 100644
index 0000000..c3e54c3
--- /dev/null
+++ b/src/MTS_IO_LE910EUGRadio.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_LE910EUGRadio.cpp
+ \brief A brief description
+ \date Jan 19, 2015
+ \author sgodinez
+
+ A more elaborate description
+*/
+
+
+#include <mts/MTS_IO_LE910EUGRadio.h>
+
+using namespace MTS::IO;
+
+const std::string LE910EUGRadio::MODEL_NAME("LE910-EUG");
+
+LE910EUGRadio::LE910EUGRadio(const std::string& sPort)
+: LE910Radio(MODEL_NAME, sPort)
+{
+
+}
diff --git a/src/MTS_IO_LE910NAGRadio.cpp b/src/MTS_IO_LE910NAGRadio.cpp
new file mode 100644
index 0000000..c2f8bf5
--- /dev/null
+++ b/src/MTS_IO_LE910NAGRadio.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_LE910NAGRadio.cpp
+ \brief A brief description
+ \date Jan 19, 2015
+ \author sgodinez
+
+ A more elaborate description
+*/
+
+#include <mts/MTS_IO_LE910NAGRadio.h>
+
+using namespace MTS::IO;
+
+const std::string LE910NAGRadio::MODEL_NAME("LE910-NAG");
+
+LE910NAGRadio::LE910NAGRadio(const std::string& sPort)
+: LE910Radio(MODEL_NAME, sPort)
+{
+
+}
+
+CellularRadio::CODE LE910NAGRadio::getCarrier(std::string& sCarrier) {
+ sCarrier = "AT&T";
+ return SUCCESS;
+}
diff --git a/src/MTS_IO_LE910Radio.cpp b/src/MTS_IO_LE910Radio.cpp
new file mode 100644
index 0000000..cbff249
--- /dev/null
+++ b/src/MTS_IO_LE910Radio.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_LE910Radio.cpp
+ \brief A brief description
+ \date Nov 6, 2014
+ \author sgodinez
+
+ A more elaborate description
+*/
+
+#include <mts/MTS_IO_LE910Radio.h>
+
+using namespace MTS::IO;
+
+LE910Radio::LE910Radio(const std::string& sLE910Model, const std::string& sPort)
+: CellularRadio(sLE910Model, sPort)
+{
+
+}
+
diff --git a/src/MTS_IO_LE910SVGRadio.cpp b/src/MTS_IO_LE910SVGRadio.cpp
new file mode 100644
index 0000000..ee9b3f8
--- /dev/null
+++ b/src/MTS_IO_LE910SVGRadio.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_LE910SVGRadio.cpp
+ \brief A brief description
+ \date Jan 19, 2015
+ \author sgodinez
+
+ A more elaborate description
+*/
+
+#include <mts/MTS_IO_LE910SVGRadio.h>
+
+using namespace MTS::IO;
+
+const std::string LE910SVGRadio::MODEL_NAME("LE910-SVG");
+
+LE910SVGRadio::LE910SVGRadio(const std::string& sPort)
+: LE910Radio(MODEL_NAME, sPort)
+{
+
+}
+
+CellularRadio::CODE LE910SVGRadio::getCarrier(std::string& sCarrier) {
+ sCarrier = "Verizon";
+ return SUCCESS;
+}
diff --git a/src/MTS_IO_LockFile.cpp b/src/MTS_IO_LockFile.cpp
new file mode 100644
index 0000000..c013699
--- /dev/null
+++ b/src/MTS_IO_LockFile.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_LockFile.cpp
+ \brief A brief description
+ \date Oct 8, 2014
+ \author sgodinez
+
+ A more elaborate description
+*/
+
+#include <mts/MTS_IO_LockFile.h>
+#include <mts/MTS_Timer.h>
+#include <mts/MTS_Logger.h>
+#include <mts/MTS_System.h>
+#include <mts/MTS_Text.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+using namespace MTS::IO;
+
+LockFile::LockFile(const std::string& sFile)
+: m_sFile(sFile)
+, m_iLockFd(-1)
+{
+
+}
+
+LockFile::~LockFile() {
+ unlock();
+}
+
+bool LockFile::lock(uint32_t attemptMillis) {
+ if(isLocked()) {
+ return true;
+ }
+
+ MTS::Timer timer;
+
+ timer.start();
+ while(timer.getMillis() < attemptMillis) {
+ m_iLockFd =::open(m_sFile.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0644);
+ if (m_iLockFd < 0) {
+ // device already locked -> bail out
+ printWarning("LockFile| Failed to Lock [%s] [%d][%s]", m_sFile.c_str(), errno, strerror(errno));
+
+ //Check if lock file's process still exists
+ std::string sResult;
+ if(MTS::System::readFile(m_sFile, sResult) == 0 && sResult.size() > 0) {
+ struct stat sts;
+ std::string sProc = "/proc/" + MTS::Text::trim(sResult);
+ if (stat(sProc.c_str(), &sts) == -1 && errno == ENOENT) {
+ printWarning("LockFile| Current Lock's Process [%s] does not exist. Removing lock.", sResult.c_str());
+ // process doesn't exist -> remove file
+ ::unlink(m_sFile.c_str());
+ }
+ }
+
+ } else {
+ //TODO: Investigate using flock in addition to minicom-style lock : flock(m_iLockFd, LOCK_EX | LOCK_NB);
+
+ // %4d to make concurrent mgetty (if any) happy.
+ // Mgetty treats 4-bytes lock files as binary,
+ // not text, PID. Making 5+ char file. Brrr...
+ char buf[256] = {0};
+ sprintf(buf, "%4d\n", getpid());
+ write(m_iLockFd, buf, strlen(buf));
+ close(m_iLockFd);
+ return true;
+ }
+ uint32_t randomSleepTime = ((rand() % 10) + 1) * 100000; //Sleep from 100ms to 1 Second
+ ::usleep(randomSleepTime);
+ }
+ return false;
+}
+
+void LockFile::unlock() {
+ if(isLocked()) {
+ ::unlink(m_sFile.c_str());
+ //TODO: flock cleanup : flock(m_iLockFd, LOCK_UN);
+ m_iLockFd = -1;
+ }
+}
+
+bool LockFile::isLocked() {
+ return m_iLockFd >= 0;
+}
+
diff --git a/src/MTS_IO_MccMncTable.cpp b/src/MTS_IO_MccMncTable.cpp
new file mode 100644
index 0000000..8ac3f62
--- /dev/null
+++ b/src/MTS_IO_MccMncTable.cpp
@@ -0,0 +1,1723 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_MccMncTable.cpp
+ \brief Auto-Generated MCC-MNC Lookup Table
+ \date 2014-12-11
+ \author sgodinez
+
+ An Auto-Generated MCC-MNC Lookup Table
+*/
+
+#include <mts/MTS_IO_MccMncTable.h>
+#include <mts/MTS_Logger.h>
+#include <mts/MTS_Text.h>
+
+using namespace MTS::IO;
+
+MTS::AutoPtr<MTS::Lock> MccMncTable::m_apLock(new MTS::Lock());
+MccMncTable* MccMncTable::m_pInstance = NULL;
+
+MccMncTable* MccMncTable::getInstance() {
+ if(m_pInstance == NULL) {
+ m_apLock->lock();
+ if (m_pInstance == NULL) {
+ m_pInstance = new MccMncTable();
+ }
+ m_apLock->unlock();
+ }
+ return m_pInstance;
+}
+
+MccMncTable::MccMncTable() {
+ createTable();
+}
+
+Json::Value MccMncTable::lookup(const std::string& sMcc, const std::string& sMnc) {
+ uint32_t iMcc, iMnc;
+ printTrace("[MCCMNC] MCCx[%s] MNCx[%s]", sMcc.c_str(), sMnc.c_str());
+ if(!MTS::Text::parseHex(iMcc, sMcc)) { return Json::Value::null; }
+ if(!MTS::Text::parseHex(iMnc, sMnc)) { return Json::Value::null; }
+ printTrace("[MCCMNC] MCC0X[%d] MNC0X[%d]", iMcc, iMnc);
+ if (m_mTable.count(iMcc)) {
+ if(m_mTable[iMcc].count(iMnc)) {
+ std::vector<std::string> vJson = MTS::Text::split(m_mTable[iMcc][iMnc], ',');
+ Json::Value j;
+ j["iso"] = vJson[0];
+ j["country"] = vJson[1];
+ j["code"] = vJson[2];
+ j["carrier"] = vJson[3];
+ return j;
+ }
+ }
+
+ return Json::Value::null;
+}
+
+void MccMncTable::createTable() {
+ std::string sData;
+ m_mTable[649][2191] = "ge,Abkhazia,7,A-Mobile";
+ m_mTable[649][1679] = "ge,Abkhazia,7,A-Mobile";
+ m_mTable[649][1663] = "ge,Abkhazia,7,Aquafon";
+ m_mTable[1042][2191] = "af,Afghanistan,93,Afghan Telecom Corp. (AT)";
+ m_mTable[1042][2063] = "af,Afghanistan,93,Afghan Telecom Corp. (AT)";
+ m_mTable[1042][31] = "af,Afghanistan,93,Afghan Wireless/AWCC";
+ m_mTable[1042][1039] = "af,Afghanistan,93,Areeba/MTN";
+ m_mTable[1042][1295] = "af,Afghanistan,93,Etisalat";
+ m_mTable[1042][527] = "af,Afghanistan,93,Roshan";
+ m_mTable[630][31] = "al,Albania,355,AMC Mobil";
+ m_mTable[630][63] = "al,Albania,355,Eagle Mobile";
+ m_mTable[630][79] = "al,Albania,355,PLUS Communication Sh.a";
+ m_mTable[630][47] = "al,Albania,355,Vodafone";
+ m_mTable[1539][31] = "dz,Algeria,213,ATM Mobils";
+ m_mTable[1539][47] = "dz,Algeria,213,Orascom / DJEZZY";
+ m_mTable[1539][63] = "dz,Algeria,213,Oreedo/Wataniya / Nedjma";
+ m_mTable[1348][287] = "as,American Samoa,684,Blue Sky Communications";
+ m_mTable[531][63] = "ad,Andorra,376,Mobiland";
+ m_mTable[1585][79] = "ao,Angola,244,MoviCel";
+ m_mTable[1585][47] = "ao,Angola,244,Unitel";
+ m_mTable[869][2112] = "ai,Anguilla,1264,Cable and Wireless";
+ m_mTable[869][16] = "ai,Anguilla,1264,Digicell / Wireless Vent. Ltd";
+ m_mTable[836][48] = "ag,Antigua and Barbuda,1268,APUA PCS";
+ m_mTable[836][2336] = "ag,Antigua and Barbuda,1268,C & W";
+ m_mTable[836][2352] = "ag,Antigua and Barbuda,1268,DigiCel/Cing. Wireless";
+ m_mTable[1826][784] = "ar,Argentina Republic,54,Claro/ CTI/AMX";
+ m_mTable[1826][816] = "ar,Argentina Republic,54,Claro/ CTI/AMX";
+ m_mTable[1826][800] = "ar,Argentina Republic,54,Claro/ CTI/AMX";
+ m_mTable[1826][16] = "ar,Argentina Republic,54,Compania De Radiocomunicaciones Moviles SA";
+ m_mTable[1826][112] = "ar,Argentina Republic,54,Movistar/Telefonica";
+ m_mTable[1826][32] = "ar,Argentina Republic,54,Nextel";
+ m_mTable[1826][833] = "ar,Argentina Republic,54,Telecom Personal S.A.";
+ m_mTable[643][31] = "am,Armenia,374,ArmenTel/Beeline";
+ m_mTable[643][79] = "am,Armenia,374,Karabakh Telecom";
+ m_mTable[643][271] = "am,Armenia,374,Orange";
+ m_mTable[643][95] = "am,Armenia,374,Vivacell";
+ m_mTable[867][527] = "aw,Aruba,297,Digicel";
+ m_mTable[867][31] = "aw,Aruba,297,Setar GSM";
+ m_mTable[1285][335] = "au,Australia,61,AAPT Ltd.";
+ m_mTable[1285][591] = "au,Australia,61,Advanced Comm Tech Pty.";
+ m_mTable[1285][159] = "au,Australia,61,Airnet Commercial Australia Ltd..";
+ m_mTable[1285][79] = "au,Australia,61,Department of Defense";
+ m_mTable[1285][623] = "au,Australia,61,Dialogue Communications Pty Ltd";
+ m_mTable[1285][303] = "au,Australia,61,H3G Ltd.";
+ m_mTable[1285][111] = "au,Australia,61,H3G Ltd.";
+ m_mTable[1285][2191] = "au,Australia,61,Localstar Holding Pty. Ltd";
+ m_mTable[1285][415] = "au,Australia,61,Lycamobile Pty Ltd";
+ m_mTable[1285][143] = "au,Australia,61,Railcorp/Vodafone";
+ m_mTable[1285][2463] = "au,Australia,61,Railcorp/Vodafone";
+ m_mTable[1285][319] = "au,Australia,61,Railcorp/Vodafone";
+ m_mTable[1285][2319] = "au,Australia,61,Singtel Optus";
+ m_mTable[1285][47] = "au,Australia,61,Singtel Optus";
+ m_mTable[1285][31] = "au,Australia,61,Telstra Corp. Ltd.";
+ m_mTable[1285][287] = "au,Australia,61,Telstra Corp. Ltd.";
+ m_mTable[1285][1823] = "au,Australia,61,Telstra Corp. Ltd.";
+ m_mTable[1285][1839] = "au,Australia,61,Telstra Corp. Ltd.";
+ m_mTable[1285][95] = "au,Australia,61,The Ozitel Network Pty.";
+ m_mTable[1285][367] = "au,Australia,61,Victorian Rail Track Corp. (VicTrack)";
+ m_mTable[1285][63] = "au,Australia,61,Vodafone";
+ m_mTable[1285][127] = "au,Australia,61,Vodafone";
+ m_mTable[562][31] = "at,Austria,43,A1 MobilKom";
+ m_mTable[562][287] = "at,Austria,43,A1 MobilKom";
+ m_mTable[562][159] = "at,Austria,43,A1 MobilKom";
+ m_mTable[562][47] = "at,Austria,43,A1 MobilKom";
+ m_mTable[562][351] = "at,Austria,43,T-Mobile/Telering";
+ m_mTable[562][15] = "at,Austria,43,Fix Line";
+ m_mTable[562][335] = "at,Austria,43,H3G";
+ m_mTable[562][271] = "at,Austria,43,H3G";
+ m_mTable[562][111] = "at,Austria,43,A1/Orange/One Connect";
+ m_mTable[562][303] = "at,Austria,43,A1/Orange/One Connect";
+ m_mTable[562][95] = "at,Austria,43,A1/Orange/One Connect";
+ m_mTable[562][127] = "at,Austria,43,T-Mobile/Telering";
+ m_mTable[562][79] = "at,Austria,43,T-Mobile/Telering";
+ m_mTable[562][63] = "at,Austria,43,T-Mobile/Telering";
+ m_mTable[562][143] = "at,Austria,43,Telefonica";
+ m_mTable[1024][31] = "az,Azerbaijan,994,Azercell Telekom B.M.";
+ m_mTable[1024][79] = "az,Azerbaijan,994,Azerfon.";
+ m_mTable[1024][63] = "az,Azerbaijan,994,Caspian American Telecommunications LLC (CATEL)";
+ m_mTable[1024][47] = "az,Azerbaijan,994,J.V. Bakcell GSM 2000";
+ m_mTable[868][783] = "bs,Bahamas,1242,Bahamas Telco. Comp.";
+ m_mTable[868][927] = "bs,Bahamas,1242,Bahamas Telco. Comp.";
+ m_mTable[868][912] = "bs,Bahamas,1242,Bahamas Telco. Comp.";
+ m_mTable[868][63] = "bs,Bahamas,1242,Smart Communications";
+ m_mTable[1062][31] = "bh,Bahrain,973,Batelco";
+ m_mTable[1062][47] = "bh,Bahrain,973,ZAIN/Vodafone";
+ m_mTable[1062][79] = "bh,Bahrain,973,VIVA";
+ m_mTable[1136][47] = "bd,Bangladesh,880,Robi/Aktel";
+ m_mTable[1136][95] = "bd,Bangladesh,880,Citycell";
+ m_mTable[1136][111] = "bd,Bangladesh,880,Citycell";
+ m_mTable[1136][31] = "bd,Bangladesh,880,GrameenPhone";
+ m_mTable[1136][63] = "bd,Bangladesh,880,Orascom";
+ m_mTable[1136][79] = "bd,Bangladesh,880,TeleTalk";
+ m_mTable[1136][127] = "bd,Bangladesh,880,Airtel/Warid";
+ m_mTable[834][1536] = "bb,Barbados,1246,C & W BET Ltd.";
+ m_mTable[834][2064] = "bb,Barbados,1246,Cingular Wireless";
+ m_mTable[834][1872] = "bb,Barbados,1246,Digicel";
+ m_mTable[834][80] = "bb,Barbados,1246,Digicel";
+ m_mTable[834][2080] = "bb,Barbados,1246,Sunbeach";
+ m_mTable[599][63] = "by,Belarus,375,BelCel JV";
+ m_mTable[599][79] = "by,Belarus,375,BeST";
+ m_mTable[599][31] = "by,Belarus,375,Mobile Digital Communications";
+ m_mTable[599][47] = "by,Belarus,375,MTS";
+ m_mTable[518][527] = "be,Belgium,32,Base/KPN";
+ m_mTable[518][31] = "be,Belgium,32,Belgacom/Proximus";
+ m_mTable[518][111] = "be,Belgium,32,Lycamobile Belgium";
+ m_mTable[518][271] = "be,Belgium,32,Mobistar/Orange";
+ m_mTable[518][47] = "be,Belgium,32,SNCT/NMBS";
+ m_mTable[518][95] = "be,Belgium,32,Telenet BidCo NV";
+ m_mTable[1794][1663] = "bz,Belize,501,DigiCell";
+ m_mTable[1794][1679] = "bz,Belize,501,International Telco (INTELCO)";
+ m_mTable[1558][79] = "bj,Benin,229,Bell Benin/BBCOM";
+ m_mTable[1558][47] = "bj,Benin,229,Etisalat/MOOV";
+ m_mTable[1558][95] = "bj,Benin,229,GloMobile";
+ m_mTable[1558][31] = "bj,Benin,229,Libercom";
+ m_mTable[1558][63] = "bj,Benin,229,MTN/Spacetel";
+ m_mTable[848][0] = "bm,Bermuda,1441,Bermuda Digital Communications Ltd (BDC)";
+ m_mTable[848][2463] = "bm,Bermuda,1441,CellOne Ltd";
+ m_mTable[848][271] = "bm,Bermuda,1441,DigiCel / Cingular";
+ m_mTable[848][47] = "bm,Bermuda,1441,M3 Wireless Ltd";
+ m_mTable[848][31] = "bm,Bermuda,1441,Telecommunications (Bermuda & West Indies) Ltd (Digicel Bermuda)";
+ m_mTable[1026][287] = "bt,Bhutan,975,B-Mobile";
+ m_mTable[1026][383] = "bt,Bhutan,975,Bhutan Telecom Ltd (BTL)";
+ m_mTable[1026][1919] = "bt,Bhutan,975,TashiCell";
+ m_mTable[1846][47] = "bo,Bolivia,591,Entel Pcs";
+ m_mTable[1846][31] = "bo,Bolivia,591,Nuevatel";
+ m_mTable[1846][63] = "bo,Bolivia,591,TELECEL BOLIVIA";
+ m_mTable[536][2319] = "ba,Bosnia & Herzegov.,387,BH Mobile";
+ m_mTable[536][63] = "ba,Bosnia & Herzegov.,387,Eronet Mobile";
+ m_mTable[536][95] = "ba,Bosnia & Herzegov.,387,M-Tel";
+ m_mTable[1618][79] = "bw,Botswana,267,beMOBILE";
+ m_mTable[1618][31] = "bw,Botswana,267,Mascom Wireless (Pty) Ltd.";
+ m_mTable[1618][47] = "bw,Botswana,267,Orange";
+ m_mTable[1828][303] = "br,Brazil,55,Claro/Albra/America Movil";
+ m_mTable[1828][911] = "br,Brazil,55,Claro/Albra/America Movil";
+ m_mTable[1828][95] = "br,Brazil,55,Claro/Albra/America Movil";
+ m_mTable[1828][31] = "br,Brazil,55,Vivo S.A./Telemig";
+ m_mTable[1828][847] = "br,Brazil,55,CTBC Celular SA (CTBC)";
+ m_mTable[1828][831] = "br,Brazil,55,CTBC Celular SA (CTBC)";
+ m_mTable[1828][815] = "br,Brazil,55,CTBC Celular SA (CTBC)";
+ m_mTable[1828][143] = "br,Brazil,55,TIM";
+ m_mTable[1828][927] = "br,Brazil,55,Nextel (Telet)";
+ m_mTable[1828][15] = "br,Brazil,55,Nextel (Telet)";
+ m_mTable[1828][591] = "br,Brazil,55,Amazonia Celular S/A";
+ m_mTable[1828][783] = "br,Brazil,55,Oi (TNL PCS / Oi)";
+ m_mTable[1828][799] = "br,Brazil,55,Oi (TNL PCS / Oi)";
+ m_mTable[1828][367] = "br,Brazil,55,Brazil Telcom";
+ m_mTable[1828][351] = "br,Brazil,55,Sercontel Cel";
+ m_mTable[1828][127] = "br,Brazil,55,CTBC/Triangulo";
+ m_mTable[1828][415] = "br,Brazil,55,Vivo S.A./Telemig";
+ m_mTable[1828][47] = "br,Brazil,55,TIM";
+ m_mTable[1828][79] = "br,Brazil,55,TIM";
+ m_mTable[1828][63] = "br,Brazil,55,TIM";
+ m_mTable[1828][895] = "br,Brazil,55,Unicel do Brasil Telecomunicacoes Ltda";
+ m_mTable[1828][271] = "br,Brazil,55,Vivo S.A./Telemig";
+ m_mTable[1828][111] = "br,Brazil,55,Vivo S.A./Telemig";
+ m_mTable[1828][575] = "br,Brazil,55,Vivo S.A./Telemig";
+ m_mTable[1828][287] = "br,Brazil,55,Vivo S.A./Telemig";
+ m_mTable[840][1392] = "vg,British Virgin Islands,284,Caribbean Cellular";
+ m_mTable[840][1904] = "vg,British Virgin Islands,284,Digicel";
+ m_mTable[840][368] = "vg,British Virgin Islands,284,LIME";
+ m_mTable[1320][47] = "bn,Brunei,673,b-mobile";
+ m_mTable[1320][287] = "bn,Brunei,673,Datastream (DTSCom)";
+ m_mTable[1320][31] = "bn,Brunei,673,Telekom Brunei Bhd (TelBru)";
+ m_mTable[644][111] = "bg,Bulgaria,359,BTC Mobile EOOD (vivatel)";
+ m_mTable[644][63] = "bg,Bulgaria,359,BTC Mobile EOOD (vivatel)";
+ m_mTable[644][95] = "bg,Bulgaria,359,Cosmo Mobile EAD/Globul";
+ m_mTable[644][31] = "bg,Bulgaria,359,MobilTel AD";
+ m_mTable[1555][63] = "bf,Burkina Faso,226,TeleCel";
+ m_mTable[1555][31] = "bf,Burkina Faso,226,TeleMob-OnaTel";
+ m_mTable[1555][47] = "bf,Burkina Faso,226,AirTel/ZAIN/CelTel";
+ m_mTable[1044][31] = "mm,Burma,95,Myanmar Post & Teleco.";
+ m_mTable[1602][47] = "bi,Burundi,257,Africel / Safaris";
+ m_mTable[1602][143] = "bi,Burundi,257,HiTs Telecom";
+ m_mTable[1602][63] = "bi,Burundi,257,Onatel / Telecel";
+ m_mTable[1602][127] = "bi,Burundi,257,Smart Mobile / LACELL";
+ m_mTable[1602][31] = "bi,Burundi,257,Spacetel / Econet";
+ m_mTable[1602][2095] = "bi,Burundi,257,U-COM";
+ m_mTable[1110][79] = "kh,Cambodia,855,Cambodia Advance Communications Co. Ltd (CADCOMMS)";
+ m_mTable[1110][47] = "kh,Cambodia,855,Hello/Malaysia Telcom";
+ m_mTable[1110][143] = "kh,Cambodia,855,Metfone";
+ m_mTable[1110][399] = "kh,Cambodia,855,MFone/Camshin";
+ m_mTable[1110][31] = "kh,Cambodia,855,Mobitel/Cam GSM";
+ m_mTable[1110][63] = "kh,Cambodia,855,QB/Cambodia Adv. Comms.";
+ m_mTable[1110][95] = "kh,Cambodia,855,Smart Mobile";
+ m_mTable[1110][111] = "kh,Cambodia,855,Smart Mobile";
+ m_mTable[1110][159] = "kh,Cambodia,855,Sotelco Ltd (Beeline Cambodia)";
+ m_mTable[1572][31] = "cm,Cameroon,237,MTN";
+ m_mTable[1572][79] = "cm,Cameroon,237,Nextel";
+ m_mTable[1572][47] = "cm,Cameroon,237,Orange";
+ m_mTable[770][1618] = "ca,Canada,1,BC Tel Mobility";
+ m_mTable[770][1584] = "ca,Canada,1,Bell Aliant";
+ m_mTable[770][1552] = "ca,Canada,1,Bell Mobility";
+ m_mTable[770][1617] = "ca,Canada,1,Bell Mobility";
+ m_mTable[770][1648] = "ca,Canada,1,CityWest Mobility";
+ m_mTable[770][865] = "ca,Canada,1,Clearnet";
+ m_mTable[770][864] = "ca,Canada,1,Clearnet";
+ m_mTable[770][896] = "ca,Canada,1,DMTS Mobility";
+ m_mTable[770][1808] = "ca,Canada,1,Globalstar Canada";
+ m_mTable[770][1600] = "ca,Canada,1,Latitude Wireless";
+ m_mTable[770][880] = "ca,Canada,1,FIDO (Rogers AT&T/ Microcell)";
+ m_mTable[770][800] = "ca,Canada,1,mobilicity";
+ m_mTable[770][1794] = "ca,Canada,1,MT&T Mobility";
+ m_mTable[770][1621] = "ca,Canada,1,MTS Mobility";
+ m_mTable[770][1632] = "ca,Canada,1,MTS Mobility";
+ m_mTable[770][1793] = "ca,Canada,1,NB Tel Mobility";
+ m_mTable[770][1795] = "ca,Canada,1,New Tel Mobility";
+ m_mTable[770][1888] = "ca,Canada,1,Public Mobile";
+ m_mTable[770][1623] = "ca,Canada,1,Quebectel Mobility";
+ m_mTable[770][1824] = "ca,Canada,1,Rogers AT&T Wireless";
+ m_mTable[770][1664] = "ca,Canada,1,Sask Tel Mobility";
+ m_mTable[770][1620] = "ca,Canada,1,Sask Tel Mobility";
+ m_mTable[770][1622] = "ca,Canada,1,Tbay Mobility";
+ m_mTable[770][544] = "ca,Canada,1,Telus Mobility";
+ m_mTable[770][1619] = "ca,Canada,1,Telus Mobility";
+ m_mTable[770][1280] = "ca,Canada,1,Videotron";
+ m_mTable[770][1168] = "ca,Canada,1,WIND";
+ m_mTable[1573][31] = "cv,Cape Verde,238,CV Movel";
+ m_mTable[1573][47] = "cv,Cape Verde,238,T+ Telecom";
+ m_mTable[838][80] = "ky,Cayman Islands,1345,Digicel Cayman Ltd";
+ m_mTable[838][6] = "ky,Cayman Islands,1345,Digicel Ltd.";
+ m_mTable[838][320] = "ky,Cayman Islands,1345,LIME / Cable & Wirel.";
+ m_mTable[1571][31] = "cf,Central African Rep.,236,Centrafr. Telecom+";
+ m_mTable[1571][79] = "cf,Central African Rep.,236,Nationlink";
+ m_mTable[1571][63] = "cf,Central African Rep.,236,Orange/Celca";
+ m_mTable[1571][47] = "cf,Central African Rep.,236,Telecel Centraf.";
+ m_mTable[1570][79] = "td,Chad,235,Salam/Sotel";
+ m_mTable[1570][47] = "td,Chad,235,Tchad Mobile";
+ m_mTable[1570][63] = "td,Chad,235,Tigo/Milicom/Tchad Mobile";
+ m_mTable[1570][31] = "td,Chad,235,Zain/Airtel/Celtel";
+ m_mTable[1840][111] = "cl,Chile,56,Blue Two Chile SA";
+ m_mTable[1840][287] = "cl,Chile,56,Celupago SA";
+ m_mTable[1840][351] = "cl,Chile,56,Cibeles Telecom SA";
+ m_mTable[1840][63] = "cl,Chile,56,Claro";
+ m_mTable[1840][271] = "cl,Chile,56,Entel PCS";
+ m_mTable[1840][31] = "cl,Chile,56,Entel Telefonia Mov";
+ m_mTable[1840][335] = "cl,Chile,56,Netline Telefonica Movil Ltda";
+ m_mTable[1840][159] = "cl,Chile,56,Nextel SA";
+ m_mTable[1840][95] = "cl,Chile,56,Nextel SA";
+ m_mTable[1840][79] = "cl,Chile,56,Nextel SA";
+ m_mTable[1840][127] = "cl,Chile,56,TELEFONICA";
+ m_mTable[1840][47] = "cl,Chile,56,TELEFONICA";
+ m_mTable[1840][303] = "cl,Chile,56,Telestar Movil SA";
+ m_mTable[1840][15] = "cl,Chile,56,TESAM SA";
+ m_mTable[1840][319] = "cl,Chile,56,Tribe Mobile SPA";
+ m_mTable[1840][143] = "cl,Chile,56,VTR Banda Ancha SA";
+ m_mTable[1120][127] = "cn,China,86,China Mobile GSM";
+ m_mTable[1120][15] = "cn,China,86,China Mobile GSM";
+ m_mTable[1120][47] = "cn,China,86,China Mobile GSM";
+ m_mTable[1120][79] = "cn,China,86,China Space Mobile Satellite Telecommunications Co. Ltd (China Spacecom)";
+ m_mTable[1120][63] = "cn,China,86,China Telecom";
+ m_mTable[1120][95] = "cn,China,86,China Telecom";
+ m_mTable[1120][111] = "cn,China,86,China Unicom";
+ m_mTable[1120][31] = "cn,China,86,China Unicom";
+ m_mTable[1842][304] = "co,Colombia,57,Avantel SAS";
+ m_mTable[1842][258] = "co,Colombia,57,Movistar";
+ m_mTable[1842][259] = "co,Colombia,57,TIGO/Colombia Movil";
+ m_mTable[1842][1] = "co,Colombia,57,TIGO/Colombia Movil";
+ m_mTable[1842][257] = "co,Colombia,57,Comcel S.A. Occel S.A./Celcaribe";
+ m_mTable[1842][2] = "co,Colombia,57,Edatel S.A.";
+ m_mTable[1842][291] = "co,Colombia,57,Movistar";
+ m_mTable[1842][273] = "co,Colombia,57,TIGO/Colombia Movil";
+ m_mTable[1842][322] = "co,Colombia,57,UNE EPM Telecomunicaciones SA ESP";
+ m_mTable[1842][32] = "co,Colombia,57,UNE EPM Telecomunicaciones SA ESP";
+ m_mTable[1842][340] = "co,Colombia,57,Virgin Mobile Colombia SAS";
+ m_mTable[1620][31] = "km,Comoros,269,HURI - SNPT";
+ m_mTable[1584][2159] = "cd,Congo Dem. Rep.,243,Orange RDC sarl";
+ m_mTable[1584][95] = "cd,Congo Dem. Rep.,243,SuperCell";
+ m_mTable[1584][2207] = "cd,Congo Dem. Rep.,243,TIGO/Oasis";
+ m_mTable[1584][31] = "cd,Congo Dem. Rep.,243,Vodacom";
+ m_mTable[1584][2191] = "cd,Congo Dem. Rep.,243,Yozma Timeturns sprl (YTT)";
+ m_mTable[1584][47] = "cd,Congo Dem. Rep.,243,ZAIN CelTel";
+ m_mTable[1577][31] = "cg,Congo Republic,242,Airtel Congo SA";
+ m_mTable[1577][47] = "cg,Congo Republic,242,Zain/Celtel";
+ m_mTable[1577][271] = "cg,Congo Republic,242,MTN/Libertis";
+ m_mTable[1577][127] = "cg,Congo Republic,242,Warid";
+ m_mTable[1352][31] = "ck,Cook Islands,682,Telecom Cook Islands";
+ m_mTable[1810][63] = "cr,Costa Rica,506,Claro";
+ m_mTable[1810][47] = "cr,Costa Rica,506,ICE";
+ m_mTable[1810][31] = "cr,Costa Rica,506,ICE";
+ m_mTable[1810][79] = "cr,Costa Rica,506,Movistar";
+ m_mTable[1810][527] = "cr,Costa Rica,506,Virtualis";
+ m_mTable[537][31] = "hr,Croatia,385,T-Mobile/Cronet";
+ m_mTable[537][47] = "hr,Croatia,385,Tele2";
+ m_mTable[537][271] = "hr,Croatia,385,VIPnet d.o.o.";
+ m_mTable[872][31] = "cu,Cuba,53,C-COM";
+ m_mTable[866][2399] = "cw,Curacao,599,EOCG Wireless NV";
+ m_mTable[866][1695] = "cw,Curacao,599,Polycom N.V./ Digicel";
+ m_mTable[640][271] = "cy,Cyprus,357,MTN/Areeba";
+ m_mTable[640][527] = "cy,Cyprus,357,PrimeTel PLC";
+ m_mTable[640][31] = "cy,Cyprus,357,Vodafone/CyTa";
+ m_mTable[560][143] = "cz,Czech Rep.,420,Compatel s.r.o.";
+ m_mTable[560][47] = "cz,Czech Rep.,420,O2";
+ m_mTable[560][31] = "cz,Czech Rep.,420,T-Mobile / RadioMobil";
+ m_mTable[560][95] = "cz,Czech Rep.,420,Travel Telekommunikation s.r.o.";
+ m_mTable[560][79] = "cz,Czech Rep.,420,Ufone";
+ m_mTable[560][2463] = "cz,Czech Rep.,420,Vodafone";
+ m_mTable[560][63] = "cz,Czech Rep.,420,Vodafone";
+ m_mTable[568][95] = "dk,Denmark,45,ApS KBUS";
+ m_mTable[568][575] = "dk,Denmark,45,Banedanmark";
+ m_mTable[568][655] = "dk,Denmark,45,CoolTEL ApS";
+ m_mTable[568][111] = "dk,Denmark,45,Hi3G";
+ m_mTable[568][303] = "dk,Denmark,45,Lycamobile Ltd";
+ m_mTable[568][63] = "dk,Denmark,45,Mach Connectivity ApS";
+ m_mTable[568][127] = "dk,Denmark,45,";
+ m_mTable[568][79] = "dk,Denmark,45,NextGen Mobile Ltd (CardBoardFish)";
+ m_mTable[568][271] = "dk,Denmark,45,TDC Denmark";
+ m_mTable[568][31] = "dk,Denmark,45,TDC Denmark";
+ m_mTable[568][1919] = "dk,Denmark,45,Telenor/Sonofon";
+ m_mTable[568][47] = "dk,Denmark,45,Telenor/Sonofon";
+ m_mTable[568][527] = "dk,Denmark,45,Telia";
+ m_mTable[568][783] = "dk,Denmark,45,Telia";
+ m_mTable[1592][31] = "dj,Djibouti,253,Djibouti Telecom SA (Evatis)";
+ m_mTable[870][272] = "dm,Dominica,1767,C & W";
+ m_mTable[870][32] = "dm,Dominica,1767,Cingular Wireless/Digicel";
+ m_mTable[870][80] = "dm,Dominica,1767,Wireless Ventures (Dominica) Ltd (Digicel Dominica)";
+ m_mTable[880][47] = "do,Dominican Republic,1809,Claro";
+ m_mTable[880][31] = "do,Dominican Republic,1809,Orange";
+ m_mTable[880][63] = "do,Dominican Republic,1809,TRIcom";
+ m_mTable[880][79] = "do,Dominican Republic,1809,Trilogy Dominicana S. A.";
+ m_mTable[1856][47] = "ec,Ecuador,593,Alegro/Telcsa";
+ m_mTable[1856][15] = "ec,Ecuador,593,MOVISTAR/OteCel";
+ m_mTable[1856][31] = "ec,Ecuador,593,Porta/Conecel";
+ m_mTable[1538][31] = "eg,Egypt,20,EMS - Mobinil";
+ m_mTable[1538][63] = "eg,Egypt,20,ETISALAT";
+ m_mTable[1538][47] = "eg,Egypt,20,Vodafone/Mirsfone";
+ m_mTable[1798][31] = "sv,El Salvador,503,CLARO/CTE";
+ m_mTable[1798][47] = "sv,El Salvador,503,Digicel";
+ m_mTable[1798][95] = "sv,El Salvador,503,INTELFON SA de CV";
+ m_mTable[1798][79] = "sv,El Salvador,503,Telefonica";
+ m_mTable[1798][63] = "sv,El Salvador,503,Telemovil";
+ m_mTable[1575][63] = "gq,Equatorial Guinea,240,HiTs-GE";
+ m_mTable[1575][31] = "gq,Equatorial Guinea,240,ORANGE/GETESA";
+ m_mTable[1623][31] = "er,Eritrea,291,Eritel";
+ m_mTable[584][31] = "ee,Estonia,372,EMT GSM";
+ m_mTable[584][47] = "ee,Estonia,372,Radiolinja Eesti";
+ m_mTable[584][63] = "ee,Estonia,372,Tele2 Eesti AS";
+ m_mTable[584][79] = "ee,Estonia,372,Top Connect OU";
+ m_mTable[1590][31] = "et,Ethiopia,251,ETH/MTN";
+ m_mTable[1872][1] = "fk,Falkland Islands (Malvinas),500,Cable and Wireless South Atlantic Ltd (Falkland Islands";
+ m_mTable[648][63] = "fo,Faroe Islands,298,Edge Mobile Sp/F";
+ m_mTable[648][31] = "fo,Faroe Islands,298,Faroese Telecom";
+ m_mTable[648][47] = "fo,Faroe Islands,298,Kall GSM";
+ m_mTable[1346][47] = "fj,Fiji,679,DigiCell";
+ m_mTable[1346][31] = "fj,Fiji,679,Vodafone";
+ m_mTable[580][335] = "fi,Finland,358,Alands";
+ m_mTable[580][623] = "fi,Finland,358,Compatel Ltd";
+ m_mTable[580][319] = "fi,Finland,358,DNA/Finnet";
+ m_mTable[580][63] = "fi,Finland,358,DNA/Finnet";
+ m_mTable[580][303] = "fi,Finland,358,DNA/Finnet";
+ m_mTable[580][79] = "fi,Finland,358,DNA/Finnet";
+ m_mTable[580][543] = "fi,Finland,358,Elisa/Saunalahti";
+ m_mTable[580][95] = "fi,Finland,358,Elisa/Saunalahti";
+ m_mTable[580][2095] = "fi,Finland,358,ID-Mobile";
+ m_mTable[580][287] = "fi,Finland,358,Mundio Mobile (Finland) Ltd";
+ m_mTable[580][159] = "fi,Finland,358,Nokia Oyj";
+ m_mTable[580][271] = "fi,Finland,358,TDC Oy Finland";
+ m_mTable[580][2335] = "fi,Finland,358,TeliaSonera";
+ m_mTable[520][639] = "fr,France,33,AFONE SA";
+ m_mTable[520][2351] = "fr,France,33,Association Plate-forme Telecom";
+ m_mTable[520][655] = "fr,France,33,Astrium";
+ m_mTable[520][543] = "fr,France,33,Bouygues Telecom";
+ m_mTable[520][527] = "fr,France,33,Bouygues Telecom";
+ m_mTable[520][2191] = "fr,France,33,Bouygues Telecom";
+ m_mTable[520][335] = "fr,France,33,Lliad/FREE Mobile";
+ m_mTable[520][127] = "fr,France,33,GlobalStar";
+ m_mTable[520][111] = "fr,France,33,GlobalStar";
+ m_mTable[520][95] = "fr,France,33,GlobalStar";
+ m_mTable[520][671] = "fr,France,33,Orange";
+ m_mTable[520][367] = "fr,France,33,Lliad/FREE Mobile";
+ m_mTable[520][351] = "fr,France,33,Lliad/FREE Mobile";
+ m_mTable[520][607] = "fr,France,33,Lycamobile SARL";
+ m_mTable[520][63] = "fr,France,33,MobiquiThings";
+ m_mTable[520][591] = "fr,France,33,MobiquiThings";
+ m_mTable[520][799] = "fr,France,33,Mundio Mobile (France) Ltd";
+ m_mTable[520][623] = "fr,France,33,NRJ";
+ m_mTable[520][2207] = "fr,France,33,Virgin Mobile/Omer";
+ m_mTable[520][575] = "fr,France,33,Virgin Mobile/Omer";
+ m_mTable[520][47] = "fr,France,33,Orange";
+ m_mTable[520][31] = "fr,France,33,Orange";
+ m_mTable[520][2335] = "fr,France,33,Orange";
+ m_mTable[520][287] = "fr,France,33,S.F.R.";
+ m_mTable[520][271] = "fr,France,33,S.F.R.";
+ m_mTable[520][159] = "fr,France,33,S.F.R.";
+ m_mTable[520][319] = "fr,France,33,S.F.R.";
+ m_mTable[520][79] = "fr,France,33,SISTEER";
+ m_mTable[520][15] = "fr,France,33,Tel/Tel";
+ m_mTable[520][559] = "fr,France,33,Transatel SA";
+ m_mTable[832][527] = "fg,French Guiana,594,Bouygues/DigiCel";
+ m_mTable[832][31] = "fg,French Guiana,594,Orange Caribe";
+ m_mTable[832][47] = "fg,French Guiana,594,Outremer Telecom";
+ m_mTable[832][63] = "fg,French Guiana,594,TelCell GSM";
+ m_mTable[832][287] = "fg,French Guiana,594,TelCell GSM";
+ m_mTable[1351][351] = "pf,French Polynesia,689,Pacific Mobile Telecom (PMT)";
+ m_mTable[1351][527] = "pf,French Polynesia,689,Tikiphone";
+ m_mTable[1576][79] = "ga,Gabon,241,Azur/Usan S.A.";
+ m_mTable[1576][31] = "ga,Gabon,241,Libertis S.A.";
+ m_mTable[1576][47] = "ga,Gabon,241,MOOV/Telecel";
+ m_mTable[1576][63] = "ga,Gabon,241,ZAIN/Celtel Gabon S.A.";
+ m_mTable[1543][47] = "gm,Gambia,220,Africel";
+ m_mTable[1543][63] = "gm,Gambia,220,Comium";
+ m_mTable[1543][31] = "gm,Gambia,220,Gamcel";
+ m_mTable[1543][79] = "gm,Gambia,220,Q-Cell";
+ m_mTable[642][31] = "ge,Georgia,995,Geocell Ltd.";
+ m_mTable[642][63] = "ge,Georgia,995,Iberiatel Ltd.";
+ m_mTable[642][47] = "ge,Georgia,995,Magti GSM Ltd.";
+ m_mTable[642][79] = "ge,Georgia,995,MobiTel/Beeline";
+ m_mTable[642][95] = "ge,Georgia,995,Silknet";
+ m_mTable[610][383] = "de,Germany,49,E-Plus";
+ m_mTable[610][271] = "de,Germany,49,DB Netz AG";
+ //MCC(262) MNC(N/A) ISO(de) Country Code(Germany) Country(49) Carrier(Debitel)
+ m_mTable[610][63] = "de,Germany,49,E-Plus";
+ m_mTable[610][95] = "de,Germany,49,E-Plus";
+ m_mTable[610][1919] = "de,Germany,49,E-Plus";
+ m_mTable[610][303] = "de,Germany,49,E-Plus";
+ m_mTable[610][335] = "de,Germany,49,Group 3G UMTS";
+ m_mTable[610][1087] = "de,Germany,49,Lycamobile";
+ m_mTable[610][319] = "de,Germany,49,Mobilcom";
+ m_mTable[610][287] = "de,Germany,49,O2";
+ m_mTable[610][127] = "de,Germany,49,O2";
+ m_mTable[610][143] = "de,Germany,49,O2";
+ //MCC(262) MNC(N/A) ISO(de) Country Code(Germany) Country(49) Carrier(Talkline)
+ m_mTable[610][111] = "de,Germany,49,T-mobile/Telekom";
+ m_mTable[610][31] = "de,Germany,49,T-mobile/Telekom";
+ m_mTable[610][367] = "de,Germany,49,Telogic/ViStream";
+ m_mTable[610][159] = "de,Germany,49,Vodafone D2";
+ m_mTable[610][79] = "de,Germany,49,Vodafone D2";
+ m_mTable[610][47] = "de,Germany,49,Vodafone D2";
+ m_mTable[1568][79] = "gh,Ghana,233,Expresso Ghana Ltd";
+ m_mTable[1568][127] = "gh,Ghana,233,GloMobile";
+ m_mTable[1568][63] = "gh,Ghana,233,Milicom/Tigo";
+ m_mTable[1568][31] = "gh,Ghana,233,MTN";
+ m_mTable[1568][47] = "gh,Ghana,233,Vodafone";
+ m_mTable[1568][111] = "gh,Ghana,233,Airtel/ZAIN";
+ m_mTable[614][111] = "gi,Gibraltar,350,CTS Mobile";
+ m_mTable[614][159] = "gi,Gibraltar,350,eazi telecom";
+ m_mTable[614][31] = "gi,Gibraltar,350,Gibtel GSM";
+ m_mTable[514][127] = "gr,Greece,30,AMD Telecom SA";
+ m_mTable[514][47] = "gr,Greece,30,Cosmote";
+ m_mTable[514][31] = "gr,Greece,30,Cosmote";
+ m_mTable[514][79] = "gr,Greece,30,Organismos Sidirodromon Ellados (OSE)";
+ m_mTable[514][63] = "gr,Greece,30,OTE Hellenic Telecommunications Organization SA";
+ m_mTable[514][271] = "gr,Greece,30,Tim/Wind";
+ m_mTable[514][159] = "gr,Greece,30,Tim/Wind";
+ m_mTable[514][95] = "gr,Greece,30,Vodafone";
+ m_mTable[656][31] = "gl,Greenland,299,Tele Greenland";
+ m_mTable[850][272] = "gd,Grenada,1473,Cable & Wireless";
+ m_mTable[850][48] = "gd,Grenada,1473,Digicel";
+ m_mTable[850][80] = "gd,Grenada,1473,Digicel";
+ m_mTable[832][143] = "gp,Guadeloupe,590,Dauphin Telecom SU (Guadeloupe Telecom) (Guadeloupe";
+ m_mTable[832][271] = "gp,Guadeloupe,590,";
+ m_mTable[784][880] = "gu,Guam,1671,Docomo";
+ m_mTable[784][1136] = "gu,Guam,1671,Docomo";
+ m_mTable[784][320] = "gu,Guam,1671,GTA Wireless";
+ m_mTable[784][51] = "gu,Guam,1671,Guam Teleph. Auth.";
+ m_mTable[784][50] = "gu,Guam,1671,IT&E OverSeas";
+ m_mTable[785][592] = "gu,Guam,1671,Wave Runner LLC";
+ m_mTable[1796][31] = "gt,Guatemala,502,SERCOM";
+ m_mTable[1796][63] = "gt,Guatemala,502,Telefonica";
+ m_mTable[1796][47] = "gt,Guatemala,502,TIGO/COMCEL";
+ m_mTable[1553][79] = "gn,Guinea,224,Areeba - MTN";
+ m_mTable[1553][95] = "gn,Guinea,224,Celcom";
+ m_mTable[1553][63] = "gn,Guinea,224,Intercel";
+ m_mTable[1553][31] = "gn,Guinea,224,Orange/Spacetel";
+ m_mTable[1553][47] = "gn,Guinea,224,SotelGui";
+ m_mTable[1586][31] = "gw,Guinea-Bissau,245,GuineTel";
+ m_mTable[1586][63] = "gw,Guinea-Bissau,245,Orange";
+ m_mTable[1586][47] = "gw,Guinea-Bissau,245,SpaceTel";
+ m_mTable[1848][47] = "gy,Guyana,592,Cellink Plus";
+ m_mTable[1848][31] = "gy,Guyana,592,DigiCel";
+ m_mTable[882][31] = "ht,Haiti,509,Comcel";
+ m_mTable[882][47] = "ht,Haiti,509,Digicel";
+ m_mTable[882][63] = "ht,Haiti,509,National Telecom SA (NatCom)";
+ m_mTable[1800][1039] = "hn,Honduras,504,Digicel";
+ m_mTable[1800][783] = "hn,Honduras,504,HonduTel";
+ m_mTable[1800][31] = "hn,Honduras,504,SERCOM/CLARO";
+ m_mTable[1800][47] = "hn,Honduras,504,Telefonica/CELTEL";
+ m_mTable[1108][319] = "hk,Hongkong China,852,China Mobile/Peoples";
+ m_mTable[1108][303] = "hk,Hongkong China,852,China Mobile/Peoples";
+ m_mTable[1108][159] = "hk,Hongkong China,852,China Motion";
+ m_mTable[1108][127] = "hk,Hongkong China,852,China Unicom Ltd";
+ m_mTable[1108][287] = "hk,Hongkong China,852,China-HongKong Telecom Ltd (CHKTL)";
+ m_mTable[1108][31] = "hk,Hongkong China,852,Citic Telecom Ltd.";
+ m_mTable[1108][47] = "hk,Hongkong China,852,CSL Ltd.";
+ m_mTable[1108][15] = "hk,Hongkong China,852,CSL Ltd.";
+ m_mTable[1108][399] = "hk,Hongkong China,852,CSL Ltd.";
+ m_mTable[1108][271] = "hk,Hongkong China,852,CSL/New World PCS Ltd.";
+ m_mTable[1108][335] = "hk,Hongkong China,852,H3G/Hutchinson";
+ m_mTable[1108][95] = "hk,Hongkong China,852,H3G/Hutchinson";
+ m_mTable[1108][79] = "hk,Hongkong China,852,H3G/Hutchinson";
+ m_mTable[1108][63] = "hk,Hongkong China,852,H3G/Hutchinson";
+ m_mTable[1108][415] = "hk,Hongkong China,852,HKT/PCCW";
+ m_mTable[1108][527] = "hk,Hongkong China,852,HKT/PCCW";
+ m_mTable[1108][671] = "hk,Hongkong China,852,HKT/PCCW";
+ m_mTable[1108][367] = "hk,Hongkong China,852,HKT/PCCW";
+ m_mTable[1108][1151] = "hk,Hongkong China,852,shared by private TETRA systems";
+ m_mTable[1108][1039] = "hk,Hongkong China,852,shared by private TETRA systems";
+ m_mTable[1108][143] = "hk,Hongkong China,852,Trident Telecom Ventures Ltd.";
+ m_mTable[1108][383] = "hk,Hongkong China,852,Vodafone/SmarTone";
+ m_mTable[1108][351] = "hk,Hongkong China,852,Vodafone/SmarTone";
+ m_mTable[1108][111] = "hk,Hongkong China,852,Vodafone/SmarTone";
+ m_mTable[534][31] = "hu,Hungary,36,Pannon/Telenor";
+ m_mTable[534][783] = "hu,Hungary,36,T-mobile/Magyar";
+ m_mTable[534][1823] = "hu,Hungary,36,UPC Magyarorszag Kft.";
+ m_mTable[534][1807] = "hu,Hungary,36,Vodafone";
+ m_mTable[628][159] = "is,Iceland,354,Amitelo";
+ m_mTable[628][127] = "is,Iceland,354,IceCell";
+ m_mTable[628][143] = "is,Iceland,354,Landssiminn";
+ m_mTable[628][31] = "is,Iceland,354,Landssiminn";
+ m_mTable[628][287] = "is,Iceland,354,NOVA";
+ m_mTable[628][79] = "is,Iceland,354,VIKING/IMC";
+ m_mTable[628][63] = "is,Iceland,354,Vodafone/Tal hf";
+ m_mTable[628][47] = "is,Iceland,354,Vodafone/Tal hf";
+ m_mTable[628][95] = "is,Iceland,354,Vodafone/Tal hf";
+ m_mTable[1028][655] = "in,India,91,Aircel";
+ m_mTable[1028][607] = "in,India,91,Aircel";
+ m_mTable[1028][383] = "in,India,91,Aircel";
+ m_mTable[1028][1071] = "in,India,91,Aircel";
+ m_mTable[1028][831] = "in,India,91,Aircel";
+ m_mTable[1028][671] = "in,India,91,Aircel";
+ m_mTable[1028][31] = "in,India,91,Aircel Digilink India";
+ m_mTable[1028][351] = "in,India,91,Aircel Digilink India";
+ m_mTable[1028][1551] = "in,India,91,Aircel Digilink India";
+ m_mTable[1029][1343] = "in,India,91,AirTel";
+ m_mTable[1028][2159] = "in,India,91,Barakhamba Sales & Serv.";
+ m_mTable[1028][319] = "in,India,91,Barakhamba Sales & Serv.";
+ m_mTable[1028][1919] = "in,India,91,BSNL";
+ m_mTable[1028][1615] = "in,India,91,BSNL";
+ m_mTable[1028][1359] = "in,India,91,BSNL";
+ m_mTable[1028][1823] = "in,India,91,BSNL";
+ m_mTable[1028][1903] = "in,India,91,BSNL";
+ m_mTable[1028][1583] = "in,India,91,BSNL";
+ m_mTable[1028][1343] = "in,India,91,BSNL";
+ m_mTable[1028][1439] = "in,India,91,BSNL";
+ m_mTable[1028][1887] = "in,India,91,BSNL";
+ m_mTable[1028][1311] = "in,India,91,BSNL";
+ m_mTable[1028][1423] = "in,India,91,BSNL";
+ m_mTable[1028][2079] = "in,India,91,BSNL";
+ m_mTable[1028][1871] = "in,India,91,BSNL";
+ m_mTable[1028][911] = "in,India,91,BSNL";
+ m_mTable[1028][1407] = "in,India,91,BSNL";
+ m_mTable[1028][2063] = "in,India,91,BSNL";
+ m_mTable[1028][1855] = "in,India,91,BSNL";
+ m_mTable[1028][847] = "in,India,91,BSNL";
+ m_mTable[1028][1647] = "in,India,91,BSNL";
+ m_mTable[1028][1375] = "in,India,91,BSNL";
+ m_mTable[1028][1839] = "in,India,91,BSNL";
+ m_mTable[1029][271] = "in,India,91,Bharti Airtel Limited (Delhi)";
+ m_mTable[1028][1951] = "in,India,91,CellOne A&N";
+ m_mTable[1028][2095] = "in,India,91,Escorts Telecom Ltd.";
+ m_mTable[1028][2207] = "in,India,91,Escorts Telecom Ltd.";
+ m_mTable[1028][2191] = "in,India,91,Escorts Telecom Ltd.";
+ m_mTable[1028][2175] = "in,India,91,Escorts Telecom Ltd.";
+ m_mTable[1028][415] = "in,India,91,Escotel Mobile Communications";
+ m_mTable[1028][1391] = "in,India,91,Escotel Mobile Communications";
+ m_mTable[1028][303] = "in,India,91,Escotel Mobile Communications";
+ m_mTable[1029][95] = "in,India,91,Fascel Limited";
+ m_mTable[1028][95] = "in,India,91,Fascel";
+ m_mTable[1028][1807] = "in,India,91,Hexacom India";
+ m_mTable[1028][367] = "in,India,91,Hexcom India";
+ m_mTable[1028][1935] = "in,India,91,Idea Cellular Ltd.";
+ m_mTable[1028][127] = "in,India,91,Idea Cellular Ltd.";
+ m_mTable[1028][79] = "in,India,91,Idea Cellular Ltd.";
+ m_mTable[1028][591] = "in,India,91,Idea Cellular Ltd.";
+ m_mTable[1028][559] = "in,India,91,Idea Cellular Ltd.";
+ m_mTable[1028][1679] = "in,India,91,Mahanagar Telephone Nigam";
+ m_mTable[1028][1695] = "in,India,91,Mahanagar Telephone Nigam";
+ m_mTable[1028][2111] = "in,India,91,Reliable Internet Services";
+ m_mTable[1028][1295] = "in,India,91,Reliance Telecom Private";
+ m_mTable[1028][1663] = "in,India,91,Reliance Telecom Private";
+ m_mTable[1028][399] = "in,India,91,Reliance Telecom Private";
+ m_mTable[1028][2143] = "in,India,91,Reliance Telecom Private";
+ m_mTable[1028][159] = "in,India,91,Reliance Telecom Private";
+ m_mTable[1028][879] = "in,India,91,Reliance Telecom Private";
+ m_mTable[1028][1327] = "in,India,91,Reliance Telecom Private";
+ m_mTable[1028][1055] = "in,India,91,RPG Cellular";
+ m_mTable[1028][335] = "in,India,91,Spice";
+ m_mTable[1028][1103] = "in,India,91,Spice";
+ m_mTable[1028][287] = "in,India,91,Sterling Cellular Ltd.";
+ m_mTable[1028][783] = "in,India,91,Usha Martin Telecom";
+ m_mTable[1296][143] = "id,Indonesia,62,Axis/Natrindo";
+ m_mTable[1296][2207] = "id,Indonesia,62,H3G CP";
+ m_mTable[1296][31] = "id,Indonesia,62,Indosat/Satelindo/M3";
+ m_mTable[1296][543] = "id,Indonesia,62,Indosat/Satelindo/M3";
+ m_mTable[1296][15] = "id,Indonesia,62,PT Pasifik Satelit Nusantara (PSN)";
+ m_mTable[1296][639] = "id,Indonesia,62,PT Sampoerna Telekomunikasi Indonesia (STI)";
+ m_mTable[1296][655] = "id,Indonesia,62,PT Smartfren Telecom Tbk";
+ m_mTable[1296][159] = "id,Indonesia,62,PT Smartfren Telecom Tbk";
+ m_mTable[1296][287] = "id,Indonesia,62,PT. Excelcom";
+ m_mTable[1296][271] = "id,Indonesia,62,Telkomsel";
+ m_mTable[2305][319] = "n/a,International Networks,882,Antarctica";
+ m_mTable[1074][415] = "ir,Iran,98,Mobile Telecommunications Company of Esfahan JV-PJS (MTCE)";
+ m_mTable[1074][1807] = "ir,Iran,98,MTCE";
+ m_mTable[1074][863] = "ir,Iran,98,MTN/IranCell";
+ m_mTable[1074][815] = "ir,Iran,98,Taliya";
+ m_mTable[1074][287] = "ir,Iran,98,TCI / MCI";
+ m_mTable[1074][335] = "ir,Iran,98,TKC/KFZO";
+ m_mTable[1048][95] = "iq,Iraq,964,Asia Cell";
+ m_mTable[1048][2351] = "iq,Iraq,964,Itisaluna and Kalemat";
+ m_mTable[1048][1039] = "iq,Iraq,964,Korek";
+ m_mTable[1048][2095] = "iq,Iraq,964,Korek";
+ m_mTable[1048][1119] = "iq,Iraq,964,Mobitel (Iraq-Kurdistan) and Moutiny";
+ m_mTable[1048][527] = "iq,Iraq,964,ZAIN/Atheer";
+ m_mTable[1048][783] = "iq,Iraq,964,Orascom Telecom";
+ m_mTable[1048][143] = "iq,Iraq,964,Sanatel";
+ m_mTable[626][79] = "ie,Ireland,353,Access Telecom Ltd.";
+ m_mTable[626][159] = "ie,Ireland,353,Clever Communications Ltd";
+ m_mTable[626][127] = "ie,Ireland,353,eircom Ltd";
+ m_mTable[626][95] = "ie,Ireland,353,H3G";
+ m_mTable[626][287] = "ie,Ireland,353,Liffey Telecom";
+ m_mTable[626][319] = "ie,Ireland,353,Lycamobile";
+ m_mTable[626][63] = "ie,Ireland,353,Meteor Mobile Ltd.";
+ m_mTable[626][47] = "ie,Ireland,353,O2/Digifone";
+ m_mTable[626][31] = "ie,Ireland,353,Vodafone Eircell";
+ m_mTable[1061][335] = "il,Israel,972,Alon Cellular Ltd";
+ m_mTable[1061][47] = "il,Israel,972,Cellcom ltd.";
+ m_mTable[1061][143] = "il,Israel,972,Golan Telekom";
+ m_mTable[1061][351] = "il,Israel,972,Home Cellular Ltd";
+ m_mTable[1061][127] = "il,Israel,972,Hot Mobile/Mirs";
+ m_mTable[1061][1919] = "il,Israel,972,Hot Mobile/Mirs";
+ m_mTable[1061][31] = "il,Israel,972,Orange/Partner Co. Ltd.";
+ m_mTable[1061][63] = "il,Israel,972,Pelephone";
+ m_mTable[1061][367] = "il,Israel,972,Rami Levy Hashikma Marketing Communications Ltd";
+ m_mTable[546][847] = "it,Italy,39,BT Italia SpA";
+ m_mTable[546][47] = "it,Italy,39,Elsacom";
+ m_mTable[546][2463] = "it,Italy,39,Hi3G";
+ m_mTable[546][831] = "it,Italy,39,Hi3G";
+ m_mTable[546][1919] = "it,Italy,39,IPSE 2000";
+ m_mTable[546][863] = "it,Italy,39,Lycamobile Srl";
+ m_mTable[546][127] = "it,Italy,39,Noverca Italia Srl";
+ m_mTable[546][783] = "it,Italy,39,RFI Rete Ferroviaria Italiana SpA";
+ m_mTable[546][1167] = "it,Italy,39,Telecom Italia Mobile SpA";
+ m_mTable[546][1087] = "it,Italy,39,Telecom Italia Mobile SpA";
+ m_mTable[546][31] = "it,Italy,39,TIM";
+ m_mTable[546][271] = "it,Italy,39,Vodafone";
+ m_mTable[546][111] = "it,Italy,39,Vodafone";
+ m_mTable[546][2191] = "it,Italy,39,WIND (Blu) -";
+ m_mTable[546][1103] = "it,Italy,39,WIND (Blu) -";
+ m_mTable[1554][127] = "ci,Ivory Coast,225,Aircomm SA";
+ m_mTable[1554][47] = "ci,Ivory Coast,225,Atlantik Tel./Moov";
+ m_mTable[1554][79] = "ci,Ivory Coast,225,Comium";
+ m_mTable[1554][31] = "ci,Ivory Coast,225,Comstar";
+ m_mTable[1554][95] = "ci,Ivory Coast,225,MTN";
+ m_mTable[1554][63] = "ci,Ivory Coast,225,Orange";
+ m_mTable[1554][111] = "ci,Ivory Coast,225,OriCell";
+ m_mTable[824][272] = "jm,Jamaica,1876,Cable & Wireless";
+ m_mTable[824][32] = "jm,Jamaica,1876,Cable & Wireless";
+ m_mTable[824][384] = "jm,Jamaica,1876,Cable & Wireless";
+ m_mTable[824][80] = "jm,Jamaica,1876,DIGICEL/Mossel";
+ m_mTable[1088][15] = "jp,Japan,81,eMobile";
+ m_mTable[1088][1343] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][1919] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][143] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][1839] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][1359] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][1951] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][127] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][1855] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][1375] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][2191] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][1295] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][1871] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][1807] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][2207] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][1311] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][1887] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][1391] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1089][1807] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][1327] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][1903] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][1823] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][607] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][1615] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][895] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][639] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][47] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][559] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1089][1087] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][799] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][2175] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][383] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1089][2351] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][1631] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][879] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][655] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][63] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][303] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][1423] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1089][2335] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][815] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][1567] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][399] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1089][2367] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1089][1039] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][1647] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][863] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][671] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][159] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][1183] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][831] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][1551] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][415] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1089][2319] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1089][2383] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1089][1055] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][1663] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][335] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][783] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][271] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][1583] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][927] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][591] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][31] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][527] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1089][1119] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1089][2447] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1089][1071] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][1679] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][351] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][623] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][287] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][1599] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][911] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][319] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][575] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][543] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1089][1103] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1089][2463] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][847] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][1695] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][367] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][2463] = "jp,Japan,81,NTT Docomo";
+ m_mTable[1088][1935] = "jp,Japan,81,Okinawa Cellular Telephone";
+ m_mTable[1089][1615] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][1135] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][2431] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][1071] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][2319] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1089][1631] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][2351] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][2447] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][1087] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][2367] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][1167] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][111] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1089][1567] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][1103] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][2383] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][79] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1089][1583] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][1119] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][2415] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][1039] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1089][1599] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][1151] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][2399] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][1055] = "jp,Japan,81,SoftBank Mobile Corp";
+ m_mTable[1088][2111] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][2143] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][2079] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][2063] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][2159] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][2127] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1088][2095] = "jp,Japan,81,KDDI Corporation";
+ m_mTable[1046][1919] = "jo,Jordan,962,Orange/Petra";
+ m_mTable[1046][63] = "jo,Jordan,962,Umniah Mobile Co.";
+ m_mTable[1046][47] = "jo,Jordan,962,Xpress";
+ m_mTable[1046][31] = "jo,Jordan,962,ZAIN /J.M.T.S";
+ m_mTable[1025][31] = "kz,Kazakhstan,7,Beeline/KaR-Tel LLP";
+ m_mTable[1025][127] = "kz,Kazakhstan,7,Dalacom/Altel";
+ m_mTable[1025][47] = "kz,Kazakhstan,7,K-Cell";
+ m_mTable[1025][1919] = "kz,Kazakhstan,7,Tele2/NEO/MTS";
+ m_mTable[1593][95] = "ke,Kenya,254,Econet Wireless";
+ m_mTable[1593][127] = "ke,Kenya,254,Orange";
+ m_mTable[1593][47] = "ke,Kenya,254,Safaricom Ltd.";
+ m_mTable[1593][63] = "ke,Kenya,254,Zain/Celtel Ltd.";
+ m_mTable[1349][159] = "ki,Kiribati,686,Kiribati Frigate";
+ m_mTable[1127][403] = "kp,Korea N. Dem. People's Rep.,850,Sun Net";
+ m_mTable[1104][47] = "kr,Korea S Republic of,82,KT Freetel Co. Ltd.";
+ m_mTable[1104][79] = "kr,Korea S Republic of,82,KT Freetel Co. Ltd.";
+ m_mTable[1104][143] = "kr,Korea S Republic of,82,KT Freetel Co. Ltd.";
+ m_mTable[1104][111] = "kr,Korea S Republic of,82,LG Telecom";
+ m_mTable[1104][63] = "kr,Korea S Republic of,82,SK Telecom";
+ m_mTable[1104][95] = "kr,Korea S Republic of,82,SK Telecom Co. Ltd";
+ m_mTable[1049][79] = "kw,Kuwait,965,Viva";
+ m_mTable[1049][63] = "kw,Kuwait,965,Wantaniya";
+ m_mTable[1049][47] = "kw,Kuwait,965,Zain";
+ m_mTable[1079][63] = "kg,Kyrgyzstan,996,AkTel LLC";
+ m_mTable[1079][31] = "kg,Kyrgyzstan,996,Beeline/Bitel";
+ m_mTable[1079][95] = "kg,Kyrgyzstan,996,MEGACOM";
+ m_mTable[1079][159] = "kg,Kyrgyzstan,996,O!/NUR Telecom";
+ m_mTable[1111][47] = "la,Laos P.D.R.,856,ETL Mobile";
+ m_mTable[1111][31] = "la,Laos P.D.R.,856,Lao Tel";
+ m_mTable[1111][143] = "la,Laos P.D.R.,856,Tigo/Millicom";
+ m_mTable[1111][63] = "la,Laos P.D.R.,856,UNITEL/LAT";
+ m_mTable[583][95] = "lv,Latvia,371,Bite";
+ m_mTable[583][31] = "lv,Latvia,371,Latvian Mobile Phone";
+ m_mTable[583][159] = "lv,Latvia,371,SIA Camel Mobile";
+ m_mTable[583][143] = "lv,Latvia,371,SIA IZZI";
+ m_mTable[583][127] = "lv,Latvia,371,SIA Master Telecom";
+ m_mTable[583][111] = "lv,Latvia,371,SIA Rigatta";
+ m_mTable[583][47] = "lv,Latvia,371,Tele2";
+ m_mTable[583][63] = "lv,Latvia,371,TRIATEL/Telekom Baltija";
+ m_mTable[1045][815] = "lb,Lebanon,961,Cellis";
+ m_mTable[1045][863] = "lb,Lebanon,961,Cellis";
+ m_mTable[1045][831] = "lb,Lebanon,961,Cellis";
+ m_mTable[1045][847] = "lb,Lebanon,961,FTML Cellis";
+ m_mTable[1045][927] = "lb,Lebanon,961,MIC2/LibanCell";
+ m_mTable[1045][911] = "lb,Lebanon,961,MIC2/LibanCell";
+ m_mTable[1045][895] = "lb,Lebanon,961,MIC2/LibanCell";
+ m_mTable[1045][31] = "lb,Lebanon,961,MIC1 (Alfa)";
+ m_mTable[1045][63] = "lb,Lebanon,961,MIC2/LibanCell";
+ m_mTable[1045][879] = "lb,Lebanon,961,MIC2/LibanCell";
+ m_mTable[1617][47] = "ls,Lesotho,266,Econet/Ezi-cel";
+ m_mTable[1617][31] = "ls,Lesotho,266,Vodacom Lesotho";
+ m_mTable[1560][127] = "lr,Liberia,231,Celcom";
+ m_mTable[1560][63] = "lr,Liberia,231,Celcom";
+ m_mTable[1560][79] = "lr,Liberia,231,Comium BVI";
+ m_mTable[1560][47] = "lr,Liberia,231,Libercell";
+ m_mTable[1560][527] = "lr,Liberia,231,LibTelco";
+ m_mTable[1560][31] = "lr,Liberia,231,Lonestar";
+ m_mTable[1542][47] = "ly,Libya,218,Al-Madar";
+ m_mTable[1542][31] = "ly,Libya,218,Al-Madar";
+ m_mTable[1542][111] = "ly,Libya,218,Hatef";
+ m_mTable[1542][15] = "ly,Libya,218,Libyana";
+ m_mTable[1542][63] = "ly,Libya,218,Libyana";
+ m_mTable[661][111] = "li,Liechtenstein,423,CUBIC (Liechtenstein";
+ m_mTable[661][127] = "li,Liechtenstein,423,First Mobile AG";
+ m_mTable[661][95] = "li,Liechtenstein,423,Mobilkom AG";
+ m_mTable[661][47] = "li,Liechtenstein,423,Orange";
+ m_mTable[661][31] = "li,Liechtenstein,423,Swisscom FL AG";
+ m_mTable[661][1919] = "li,Liechtenstein,423,Alpmobile/Tele2";
+ m_mTable[582][47] = "lt,Lithuania,370,Bite";
+ m_mTable[582][31] = "lt,Lithuania,370,Omnitel";
+ m_mTable[582][63] = "lt,Lithuania,370,Tele2";
+ m_mTable[624][1919] = "lu,Luxembourg,352,Millicom Tango GSM";
+ m_mTable[624][31] = "lu,Luxembourg,352,P+T LUXGSM";
+ m_mTable[624][2463] = "lu,Luxembourg,352,VOXmobile S.A.";
+ m_mTable[1109][79] = "mo,Macao China,853,C.T.M. TELEMOVEL+";
+ m_mTable[1109][31] = "mo,Macao China,853,C.T.M. TELEMOVEL+";
+ m_mTable[1109][47] = "mo,Macao China,853,China Telecom";
+ m_mTable[1109][95] = "mo,Macao China,853,Hutchison Telephone (Macau) Company Ltd";
+ m_mTable[1109][63] = "mo,Macao China,853,Hutchison Telephone (Macau) Company Ltd";
+ m_mTable[1109][111] = "mo,Macao China,853,Smartone Mobile";
+ m_mTable[1109][15] = "mo,Macao China,853,Smartone Mobile";
+ m_mTable[660][1887] = "mk,Macedonia,389,MTS/Cosmofone";
+ m_mTable[660][47] = "mk,Macedonia,389,MTS/Cosmofone";
+ m_mTable[660][31] = "mk,Macedonia,389,T-Mobile/Mobimak";
+ m_mTable[660][63] = "mk,Macedonia,389,VIP Mobile";
+ m_mTable[1606][31] = "mg,Madagascar,261,MADACOM";
+ m_mTable[1606][47] = "mg,Madagascar,261,Orange/Soci";
+ m_mTable[1606][63] = "mg,Madagascar,261,Sacel";
+ m_mTable[1606][79] = "mg,Madagascar,261,Telma";
+ m_mTable[1616][31] = "mw,Malawi,265,TNM/Telekom Network Ltd.";
+ m_mTable[1616][271] = "mw,Malawi,265,Zain/Celtel ltd.";
+ m_mTable[1282][31] = "my,Malaysia,60,Art900";
+ m_mTable[1282][337] = "my,Malaysia,60,Baraka Telecom Sdn Bhd";
+ m_mTable[1282][415] = "my,Malaysia,60,CelCom";
+ m_mTable[1282][319] = "my,Malaysia,60,CelCom";
+ m_mTable[1282][367] = "my,Malaysia,60,Digi Telecommunications";
+ m_mTable[1282][271] = "my,Malaysia,60,Digi Telecommunications";
+ m_mTable[1282][527] = "my,Malaysia,60,Electcoms Wireless Sdn Bhd";
+ m_mTable[1282][383] = "my,Malaysia,60,Maxis";
+ m_mTable[1282][303] = "my,Malaysia,60,Maxis";
+ m_mTable[1282][287] = "my,Malaysia,60,MTX Utara";
+ m_mTable[1282][339] = "my,Malaysia,60,Packet One Networks (Malaysia) Sdn Bhd";
+ m_mTable[1282][341] = "my,Malaysia,60,Samata Communications Sdn Bhd";
+ m_mTable[1282][340] = "my,Malaysia,60,Talk Focus Sdn Bhd";
+ m_mTable[1282][399] = "my,Malaysia,60,U Mobile";
+ m_mTable[1282][338] = "my,Malaysia,60,YES";
+ m_mTable[1138][31] = "mv,Maldives,960,Dhiraagu/C&W";
+ m_mTable[1138][47] = "mv,Maldives,960,Wataniya/WMOBILE";
+ m_mTable[1552][31] = "ml,Mali,223,Malitel";
+ m_mTable[1552][47] = "ml,Mali,223,Orange/IKATEL";
+ m_mTable[632][543] = "mt,Malta,356,GO/Mobisle";
+ m_mTable[632][1919] = "mt,Malta,356,Melita";
+ m_mTable[632][31] = "mt,Malta,356,Vodafone";
+ m_mTable[832][303] = "mq,Martinique (French Department of),596,UTS Caraibe";
+ m_mTable[1545][47] = "mr,Mauritania,222,Chinguitel SA";
+ m_mTable[1545][31] = "mr,Mauritania,222,Mattel";
+ m_mTable[1545][271] = "mr,Mauritania,222,Mauritel";
+ m_mTable[1559][271] = "mu,Mauritius,230,Emtel Ltd";
+ m_mTable[1559][47] = "mu,Mauritius,230,Mahanagar Telephone";
+ m_mTable[1559][63] = "mu,Mauritius,230,Mahanagar Telephone";
+ m_mTable[1559][31] = "mu,Mauritius,230,Orange/Cellplus";
+ m_mTable[820][15] = "mx,Mexico,52,Axtel";
+ m_mTable[820][1295] = "mx,Mexico,52,IUSACell/UneFon";
+ m_mTable[820][80] = "mx,Mexico,52,IUSACell/UneFon";
+ m_mTable[820][64] = "mx,Mexico,52,IUSACell/UneFon";
+ m_mTable[820][79] = "mx,Mexico,52,IUSACell/UneFon";
+ m_mTable[820][63] = "mx,Mexico,52,Movistar/Pegaso";
+ m_mTable[820][48] = "mx,Mexico,52,Movistar/Pegaso";
+ m_mTable[820][16] = "mx,Mexico,52,NEXTEL";
+ m_mTable[820][31] = "mx,Mexico,52,NEXTEL";
+ m_mTable[820][144] = "mx,Mexico,52,NEXTEL";
+ m_mTable[820][128] = "mx,Mexico,52,Operadora Unefon SA de CV";
+ m_mTable[820][112] = "mx,Mexico,52,Operadora Unefon SA de CV";
+ m_mTable[820][96] = "mx,Mexico,52,SAI PCS";
+ m_mTable[820][32] = "mx,Mexico,52,TelCel/America Movil";
+ m_mTable[820][47] = "mx,Mexico,52,TelCel/America Movil";
+ m_mTable[1360][31] = "fm,Micronesia,691,FSM Telecom";
+ m_mTable[601][79] = "md,Moldova,373,Eventis Mobile";
+ m_mTable[601][95] = "md,Moldova,373,IDC/Unite";
+ m_mTable[601][63] = "md,Moldova,373,IDC/Unite";
+ m_mTable[601][2463] = "md,Moldova,373,IDC/Unite";
+ m_mTable[601][47] = "md,Moldova,373,Moldcell";
+ m_mTable[601][31] = "md,Moldova,373,Orange/Voxtel";
+ m_mTable[530][271] = "mc,Monaco,377,Monaco Telecom";
+ m_mTable[530][31] = "mc,Monaco,377,Monaco Telecom";
+ m_mTable[1064][2447] = "mn,Mongolia,976,G-Mobile Corporation Ltd";
+ m_mTable[1064][2463] = "mn,Mongolia,976,Mobicom";
+ m_mTable[1064][15] = "mn,Mongolia,976,Skytel Co. Ltd";
+ m_mTable[1064][2191] = "mn,Mongolia,976,Unitel";
+ m_mTable[663][47] = "me,Montenegro,382,Monet/T-mobile";
+ m_mTable[663][63] = "me,Montenegro,382,Mtel";
+ m_mTable[663][31] = "me,Montenegro,382,Promonte GSM";
+ m_mTable[852][2144] = "ms,Montserrat,1664,Cable & Wireless";
+ m_mTable[1540][31] = "ma,Morocco,212,IAM/Itissallat";
+ m_mTable[1540][47] = "ma,Morocco,212,INWI/WANA";
+ m_mTable[1540][15] = "ma,Morocco,212,Medi Telecom";
+ m_mTable[1603][31] = "mz,Mozambique,258,mCel";
+ m_mTable[1603][63] = "mz,Mozambique,258,Movitel";
+ m_mTable[1603][79] = "mz,Mozambique,258,Vodacom";
+ m_mTable[1609][63] = "na,Namibia,264,Leo / Orascom";
+ m_mTable[1609][31] = "na,Namibia,264,MTC";
+ m_mTable[1609][47] = "na,Namibia,264,Switch/Nam. Telec.";
+ m_mTable[1065][47] = "np,Nepal,977,Ncell";
+ m_mTable[1065][31] = "np,Nepal,977,NT Mobile / Namaste";
+ m_mTable[1065][79] = "np,Nepal,977,Smart Cell";
+ m_mTable[516][335] = "nl,Netherlands,31,6GMOBILE BV";
+ m_mTable[516][575] = "nl,Netherlands,31,Aspider Solutions";
+ m_mTable[516][95] = "nl,Netherlands,31,Elephant Talk Communications Premium Rate Services Netherlands BV";
+ m_mTable[516][383] = "nl,Netherlands,31,Intercity Mobile Communications BV";
+ m_mTable[516][271] = "nl,Netherlands,31,KPN Telecom B.V.";
+ m_mTable[516][143] = "nl,Netherlands,31,KPN Telecom B.V.";
+ m_mTable[516][1695] = "nl,Netherlands,31,KPN Telecom B.V.";
+ m_mTable[516][303] = "nl,Netherlands,31,KPN/Telfort";
+ m_mTable[516][655] = "nl,Netherlands,31,Lancelot BV";
+ m_mTable[516][159] = "nl,Netherlands,31,Lycamobile Ltd";
+ m_mTable[516][111] = "nl,Netherlands,31,Mundio/Vectone Mobile";
+ m_mTable[516][543] = "nl,Netherlands,31,NS Railinfrabeheer B.V.";
+ m_mTable[516][591] = "nl,Netherlands,31,Private Mobility Nederland BV";
+ m_mTable[516][2447] = "nl,Netherlands,31,T-Mobile B.V.";
+ m_mTable[516][367] = "nl,Netherlands,31,T-Mobile B.V.";
+ m_mTable[516][527] = "nl,Netherlands,31,T-mobile/former Orange";
+ m_mTable[516][47] = "nl,Netherlands,31,Tele2";
+ m_mTable[516][127] = "nl,Netherlands,31,Teleena Holding BV";
+ m_mTable[516][1679] = "nl,Netherlands,31,Unify Mobile";
+ m_mTable[516][399] = "nl,Netherlands,31,UPC Nederland BV";
+ m_mTable[516][79] = "nl,Netherlands,31,Vodafone Libertel";
+ m_mTable[516][63] = "nl,Netherlands,31,Voiceworks Mobile BV";
+ m_mTable[516][351] = "nl,Netherlands,31,Ziggo BV";
+ m_mTable[866][1584] = "an,Netherlands Antilles,599,Cingular Wireless";
+ m_mTable[866][1311] = "an,Netherlands Antilles,599,TELCELL GSM";
+ m_mTable[866][2335] = "an,Netherlands Antilles,599,SETEL GSM";
+ m_mTable[866][2385] = "an,Netherlands Antilles,599,UTS Wireless";
+ m_mTable[1350][31] = "nc,New Caledonia,687,OPT Mobilis";
+ m_mTable[1328][655] = "nz,New Zealand,64,2degrees";
+ m_mTable[1328][95] = "nz,New Zealand,64,NZ Telecom CDMA";
+ m_mTable[1328][47] = "nz,New Zealand,64,NZ Telecom CDMA";
+ m_mTable[1328][79] = "nz,New Zealand,64,Telstra";
+ m_mTable[1328][591] = "nz,New Zealand,64,Two Degrees Mobile Ltd";
+ m_mTable[1328][31] = "nz,New Zealand,64,Vodafone";
+ m_mTable[1328][63] = "nz,New Zealand,64,Walker Wireless Ltd.";
+ m_mTable[1808][543] = "ni,Nicaragua,505,Empresa Nicaraguense de Telecomunicaciones SA (ENITEL)";
+ m_mTable[1808][783] = "ni,Nicaragua,505,Movistar";
+ m_mTable[1808][1855] = "ni,Nicaragua,505,Claro";
+ m_mTable[1556][63] = "ne,Niger,227,Etisalat/TeleCel";
+ m_mTable[1556][79] = "ne,Niger,227,Orange/Sahelc.";
+ m_mTable[1556][31] = "ne,Niger,227,Orange/Sahelc.";
+ m_mTable[1556][47] = "ne,Niger,227,Zain/CelTel";
+ m_mTable[1569][527] = "ng,Nigeria,234,Airtel/ZAIN/Econet";
+ m_mTable[1569][1551] = "ng,Nigeria,234,ETISALAT";
+ m_mTable[1569][1295] = "ng,Nigeria,234,Glo Mobile";
+ m_mTable[1569][1039] = "ng,Nigeria,234,M-Tel/Nigeria Telecom. Ltd.";
+ m_mTable[1569][783] = "ng,Nigeria,234,MTN";
+ m_mTable[1569][2463] = "ng,Nigeria,234,Starcomms";
+ m_mTable[1569][31] = "ng,Nigeria,234,Visafone";
+ m_mTable[1569][607] = "ng,Nigeria,234,Visafone";
+ m_mTable[1365][31] = "nu,Niue,683,Niue Telecom";
+ m_mTable[578][159] = "no,Norway,47,Com4 AS";
+ m_mTable[578][543] = "no,Norway,47,Jernbaneverket (GSM-R)";
+ m_mTable[578][527] = "no,Norway,47,Jernbaneverket (GSM-R)";
+ m_mTable[578][575] = "no,Norway,47,Lycamobile Ltd";
+ m_mTable[578][47] = "no,Norway,47,Netcom";
+ m_mTable[578][559] = "no,Norway,47,Network Norway AS";
+ m_mTable[578][95] = "no,Norway,47,Network Norway AS";
+ m_mTable[578][111] = "no,Norway,47,ICE Nordisk Mobiltelefon AS";
+ m_mTable[578][143] = "no,Norway,47,TDC Mobil A/S";
+ m_mTable[578][79] = "no,Norway,47,Tele2";
+ m_mTable[578][31] = "no,Norway,47,Telenor";
+ m_mTable[578][303] = "no,Norway,47,Telenor";
+ m_mTable[578][63] = "no,Norway,47,Teletopia";
+ m_mTable[578][127] = "no,Norway,47,Ventelo AS";
+ m_mTable[1058][63] = "om,Oman,968,Nawras";
+ m_mTable[1058][47] = "om,Oman,968,Oman Mobile/GTO";
+ m_mTable[1040][143] = "pk,Pakistan,92,Instaphone";
+ m_mTable[1040][31] = "pk,Pakistan,92,Mobilink";
+ m_mTable[1040][111] = "pk,Pakistan,92,Telenor";
+ m_mTable[1040][63] = "pk,Pakistan,92,UFONE/PAKTel";
+ m_mTable[1040][127] = "pk,Pakistan,92,Warid Telecom";
+ m_mTable[1040][79] = "pk,Pakistan,92,ZONG/CMPak";
+ m_mTable[1362][2063] = "pw,Palau (Republic of),680,Palau Mobile Corp. (PMC) (Palau";
+ m_mTable[1362][31] = "pw,Palau (Republic of),680,Palau National Communications Corp. (PNCC) (Palau";
+ m_mTable[1061][95] = "ps,Palestinian Territory,970,Jawwal";
+ m_mTable[1061][111] = "ps,Palestinian Territory,970,Wataniya Mobile";
+ m_mTable[1812][31] = "pa,Panama,507,Cable & Wireless S.A.";
+ m_mTable[1812][63] = "pa,Panama,507,Claro";
+ m_mTable[1812][79] = "pa,Panama,507,Digicel";
+ m_mTable[1812][32] = "pa,Panama,507,Movistar";
+ m_mTable[1812][47] = "pa,Panama,507,Movistar";
+ m_mTable[1335][63] = "pg,Papua New Guinea,675,Digicel";
+ m_mTable[1335][47] = "pg,Papua New Guinea,675,GreenCom PNG Ltd";
+ m_mTable[1335][31] = "pg,Papua New Guinea,675,Pacific Mobile";
+ m_mTable[1860][47] = "py,Paraguay,595,Claro/Hutchison";
+ m_mTable[1860][63] = "py,Paraguay,595,Compa";
+ m_mTable[1860][31] = "py,Paraguay,595,Hola/VOX";
+ m_mTable[1860][95] = "py,Paraguay,595,TIM/Nucleo/Personal";
+ m_mTable[1860][79] = "py,Paraguay,595,Tigo/Telecel";
+ m_mTable[1814][271] = "pe,Peru,51,Claro /Amer.Mov./TIM";
+ m_mTable[1814][527] = "pe,Peru,51,Claro /Amer.Mov./TIM";
+ m_mTable[1814][31] = "pe,Peru,51,GlobalStar";
+ m_mTable[1814][47] = "pe,Peru,51,GlobalStar";
+ m_mTable[1814][111] = "pe,Peru,51,Movistar";
+ m_mTable[1814][127] = "pe,Peru,51,Nextel";
+ m_mTable[1301][15] = "ph,Philippines,63,Fix Line";
+ m_mTable[1301][47] = "ph,Philippines,63,Globe Telecom";
+ m_mTable[1301][31] = "ph,Philippines,63,Globe Telecom";
+ m_mTable[1301][2191] = "ph,Philippines,63,Next Mobile";
+ m_mTable[1301][399] = "ph,Philippines,63,RED Mobile/Cure";
+ m_mTable[1301][63] = "ph,Philippines,63,Smart";
+ m_mTable[1301][95] = "ph,Philippines,63,SUN/Digitel";
+ m_mTable[608][383] = "pl,Poland,48,Aero2 SP.";
+ m_mTable[608][399] = "pl,Poland,48,AMD Telecom.";
+ m_mTable[608][911] = "pl,Poland,48,CallFreedom Sp. z o.o.";
+ m_mTable[608][303] = "pl,Poland,48,Cyfrowy POLSAT S.A.";
+ m_mTable[608][143] = "pl,Poland,48,e-Telko";
+ m_mTable[608][159] = "pl,Poland,48,Lycamobile";
+ m_mTable[608][367] = "pl,Poland,48,Mobyland";
+ m_mTable[608][879] = "pl,Poland,48,Mundio Mobile Sp. z o.o.";
+ m_mTable[608][127] = "pl,Poland,48,Play/P4";
+ m_mTable[608][287] = "pl,Poland,48,NORDISK Polska";
+ m_mTable[608][95] = "pl,Poland,48,Orange/IDEA/Centertel";
+ m_mTable[608][63] = "pl,Poland,48,Orange/IDEA/Centertel";
+ m_mTable[608][863] = "pl,Poland,48,PKP Polskie Linie Kolejowe S.A.";
+ m_mTable[608][111] = "pl,Poland,48,Play/P4";
+ m_mTable[608][2447] = "pl,Poland,48,Play/P4";
+ m_mTable[608][31] = "pl,Poland,48,Polkomtel/Plus";
+ m_mTable[608][319] = "pl,Poland,48,Sferia";
+ m_mTable[608][335] = "pl,Poland,48,Sferia";
+ m_mTable[608][271] = "pl,Poland,48,Sferia";
+ m_mTable[608][847] = "pl,Poland,48,T-Mobile/ERA";
+ m_mTable[608][47] = "pl,Poland,48,T-Mobile/ERA";
+ m_mTable[608][351] = "pl,Poland,48,Tele2";
+ m_mTable[608][79] = "pl,Poland,48,Tele2";
+ m_mTable[616][79] = "pt,Portugal,351,CTT - Correios de Portugal SA";
+ m_mTable[616][127] = "pt,Portugal,351,Optimus";
+ m_mTable[616][63] = "pt,Portugal,351,Optimus";
+ m_mTable[616][111] = "pt,Portugal,351,TMN";
+ m_mTable[616][31] = "pt,Portugal,351,Vodafone";
+ m_mTable[816][287] = "pr,Puerto Rico,1787,Puerto Rico Telephone Company Inc. (PRTC)";
+ m_mTable[816][272] = "pr,Puerto Rico,1787,Puerto Rico Telephone Company Inc. (PRTC)";
+ m_mTable[1063][31] = "qa,Qatar,974,Qtel";
+ m_mTable[1063][47] = "qa,Qatar,974,Vodafone";
+ m_mTable[1607][15] = "re,Reunion,262,Orange";
+ m_mTable[1607][47] = "re,Reunion,262,Outremer Telecom";
+ m_mTable[1607][271] = "re,Reunion,262,SFR";
+ m_mTable[550][63] = "ro,Romania,40,Cosmote";
+ m_mTable[550][287] = "ro,Romania,40,Enigma Systems";
+ m_mTable[550][271] = "ro,Romania,40,Orange";
+ m_mTable[550][95] = "ro,Romania,40,RCS&RDS Digi Mobile";
+ m_mTable[550][47] = "ro,Romania,40,Romtelecom SA";
+ m_mTable[550][111] = "ro,Romania,40,Telemobil/Zapp";
+ m_mTable[550][31] = "ro,Romania,40,Vodafone";
+ m_mTable[550][79] = "ro,Romania,40,Telemobil/Zapp";
+ m_mTable[592][303] = "ru,Russian Federation,79,Baykal Westcom";
+ m_mTable[592][655] = "ru,Russian Federation,79,BeeLine/VimpelCom";
+ m_mTable[592][271] = "ru,Russian Federation,79,DTC/Don Telecom";
+ m_mTable[592][319] = "ru,Russian Federation,79,Kuban GSM";
+ m_mTable[592][863] = "ru,Russian Federation,79,LLC Ekaterinburg-2000";
+ m_mTable[592][47] = "ru,Russian Federation,79,Megafon";
+ m_mTable[592][31] = "ru,Russian Federation,79,MTS";
+ m_mTable[592][63] = "ru,Russian Federation,79,NCC";
+ m_mTable[592][367] = "ru,Russian Federation,79,NTC";
+ m_mTable[592][415] = "ru,Russian Federation,79,OJSC Altaysvyaz";
+ m_mTable[592][287] = "ru,Russian Federation,79,Orensot";
+ m_mTable[592][2351] = "ru,Russian Federation,79,Printelefone";
+ m_mTable[592][79] = "ru,Russian Federation,79,Sibchallenge";
+ m_mTable[592][1103] = "ru,Russian Federation,79,StavTelesot";
+ m_mTable[592][527] = "ru,Russian Federation,79,Tele2/ECC/Volgogr.";
+ m_mTable[592][2367] = "ru,Russian Federation,79,Telecom XXL";
+ m_mTable[592][927] = "ru,Russian Federation,79,UralTel";
+ m_mTable[592][383] = "ru,Russian Federation,79,UralTel";
+ m_mTable[592][2463] = "ru,Russian Federation,79,VimpelCom";
+ m_mTable[592][95] = "ru,Russian Federation,79,Yenisey Telecom";
+ m_mTable[592][351] = "ru,Russian Federation,79,ZAO SMARTS";
+ m_mTable[592][127] = "ru,Russian Federation,79,ZAO SMARTS";
+ m_mTable[1589][335] = "rw,Rwanda,250,Airtel Rwanda Ltd";
+ m_mTable[1589][271] = "rw,Rwanda,250,MTN/Rwandacell";
+ m_mTable[1589][319] = "rw,Rwanda,250,TIGO";
+ m_mTable[854][272] = "kn,Saint Kitts and Nevis,1869,Cable & Wireless";
+ m_mTable[854][1295] = "kn,Saint Kitts and Nevis,1869,Digicel";
+ m_mTable[854][1807] = "kn,Saint Kitts and Nevis,1869,UTS Cariglobe";
+ m_mTable[856][272] = "lc,Saint Lucia,1758,Cable & Wireless";
+ m_mTable[856][783] = "lc,Saint Lucia,1758,Cingular Wireless";
+ m_mTable[856][1295] = "lc,Saint Lucia,1758,Digicel (St Lucia) Limited";
+ m_mTable[1353][639] = "ws,Samoa,685,Samoatel Mobile";
+ m_mTable[1353][31] = "ws,Samoa,685,Telecom Samoa Cellular Ltd.";
+ m_mTable[658][31] = "sm,San Marino,378,Prima Telecom";
+ m_mTable[1574][31] = "st,Sao Tome & Principe,239,CSTmovel";
+ m_mTable[2305][335] = "n/a,Satellite Networks,870,AeroMobile";
+ m_mTable[2305][287] = "n/a,Satellite Networks,870,InMarSAT";
+ m_mTable[2305][303] = "n/a,Satellite Networks,870,Maritime Communications Partner AS";
+ m_mTable[2305][95] = "n/a,Satellite Networks,870,Thuraya Satellite";
+ m_mTable[1056][127] = "sa,Saudi Arabia,966,Zain";
+ m_mTable[1056][63] = "sa,Saudi Arabia,966,Etihad/Etisalat/Mobily";
+ m_mTable[1056][31] = "sa,Saudi Arabia,966,STC/Al Jawal";
+ m_mTable[1056][79] = "sa,Saudi Arabia,966,Zain";
+ m_mTable[1544][63] = "sn,Senegal,221,Expresso/Sudatel";
+ m_mTable[1544][31] = "sn,Senegal,221,Orange/Sonatel";
+ m_mTable[1544][47] = "sn,Senegal,221,Sentel GSM";
+ m_mTable[544][63] = "rs,Serbia,381,MTS/Telekom Srbija";
+ m_mTable[544][47] = "rs,Serbia,381,Telenor/Mobtel";
+ m_mTable[544][31] = "rs,Serbia,381,Telenor/Mobtel";
+ m_mTable[544][95] = "rs,Serbia,381,VIP Mobile";
+ m_mTable[1587][271] = "sc,Seychelles,248,Airtel";
+ m_mTable[1587][31] = "sc,Seychelles,248,C&W";
+ m_mTable[1587][47] = "sc,Seychelles,248,Smartcom";
+ m_mTable[1561][63] = "sl,Sierra Leone,232,Africel";
+ m_mTable[1561][31] = "sl,Sierra Leone,232,Zain/Celtel";
+ m_mTable[1561][79] = "sl,Sierra Leone,232,Comium";
+ m_mTable[1561][95] = "sl,Sierra Leone,232,Africel";
+ m_mTable[1561][47] = "sl,Sierra Leone,232,Tigo/Millicom";
+ m_mTable[1561][607] = "sl,Sierra Leone,232,Mobitel";
+ m_mTable[1317][303] = "sg,Singapore,65,GRID Communications Pte Ltd";
+ m_mTable[1317][63] = "sg,Singapore,65,MobileOne Ltd";
+ m_mTable[1317][47] = "sg,Singapore,65,Singtel";
+ m_mTable[1317][31] = "sg,Singapore,65,Singtel";
+ m_mTable[1317][127] = "sg,Singapore,65,Singtel";
+ m_mTable[1317][111] = "sg,Singapore,65,Starhub";
+ m_mTable[1317][95] = "sg,Singapore,65,Starhub";
+ m_mTable[561][111] = "sk,Slovakia,421,O2";
+ m_mTable[561][95] = "sk,Slovakia,421,Orange";
+ m_mTable[561][31] = "sk,Slovakia,421,Orange";
+ m_mTable[561][351] = "sk,Slovakia,421,Orange";
+ m_mTable[561][47] = "sk,Slovakia,421,T-Mobile";
+ m_mTable[561][79] = "sk,Slovakia,421,T-Mobile";
+ m_mTable[561][2463] = "sk,Slovakia,421,Zeleznice Slovenskej republiky (ZSR)";
+ m_mTable[659][1055] = "si,Slovenia,386,Mobitel";
+ m_mTable[659][1039] = "si,Slovenia,386,SI.Mobil";
+ m_mTable[659][271] = "si,Slovenia,386,Slovenske zeleznice d.o.o.";
+ m_mTable[659][1615] = "si,Slovenia,386,T-2 d.o.o.";
+ m_mTable[659][1807] = "si,Slovenia,386,TusMobil/VEGA";
+ m_mTable[1344][47] = "sb,Solomon Islands,677,bemobile";
+ m_mTable[1344][271] = "sb,Solomon Islands,677,BREEZE";
+ m_mTable[1344][31] = "sb,Solomon Islands,677,BREEZE";
+ m_mTable[1591][783] = "so,Somalia,252,Golis";
+ m_mTable[1591][415] = "so,Somalia,252,HorTel";
+ m_mTable[1591][271] = "so,Somalia,252,Nationlink";
+ m_mTable[1591][1551] = "so,Somalia,252,Nationlink";
+ m_mTable[1591][79] = "so,Somalia,252,Somafone";
+ m_mTable[1591][2095] = "so,Somalia,252,Telcom Mobile Somalia";
+ m_mTable[1591][31] = "so,Somalia,252,Telesom";
+ m_mTable[1621][47] = "za,South Africa,27,8.ta";
+ m_mTable[1621][543] = "za,South Africa,27,Cape Town Metropolitan";
+ m_mTable[1621][127] = "za,South Africa,27,Cell C";
+ m_mTable[1621][271] = "za,South Africa,27,MTN";
+ m_mTable[1621][303] = "za,South Africa,27,MTN";
+ m_mTable[1621][111] = "za,South Africa,27,Sentech";
+ m_mTable[1621][31] = "za,South Africa,27,Vodacom";
+ m_mTable[1621][415] = "za,South Africa,27,Wireless Business Solutions (Pty) Ltd";
+ m_mTable[1625][63] = "ss,South Sudan (Republic of),211,Gemtel Ltd (South Sudan";
+ m_mTable[1625][47] = "ss,South Sudan (Republic of),211,MTN South Sudan (South Sudan";
+ m_mTable[1625][79] = "ss,South Sudan (Republic of),211,Network of The World Ltd (NOW) (South Sudan";
+ m_mTable[1625][111] = "ss,South Sudan (Republic of),211,Zain South Sudan (South Sudan";
+ m_mTable[532][575] = "es,Spain,34,Lycamobile SL";
+ m_mTable[532][559] = "es,Spain,34,Movistar";
+ m_mTable[532][351] = "es,Spain,34,BT Espana SAU";
+ m_mTable[532][399] = "es,Spain,34,Cableuropa SAU (ONO)";
+ m_mTable[532][143] = "es,Spain,34,Euskaltel SA";
+ m_mTable[532][527] = "es,Spain,34,fonYou Wireless SL";
+ m_mTable[532][543] = "es,Spain,34,Jazz Telecom SAU";
+ m_mTable[532][623] = "es,Spain,34,Lleida";
+ m_mTable[532][607] = "es,Spain,34,Lycamobile SL";
+ m_mTable[532][127] = "es,Spain,34,Movistar";
+ m_mTable[532][95] = "es,Spain,34,Movistar";
+ m_mTable[532][287] = "es,Spain,34,Orange";
+ m_mTable[532][159] = "es,Spain,34,Orange";
+ m_mTable[532][63] = "es,Spain,34,Orange";
+ m_mTable[532][383] = "es,Spain,34,R Cable y Telec. Galicia SA";
+ m_mTable[532][415] = "es,Spain,34,Simyo/KPN";
+ m_mTable[532][367] = "es,Spain,34,Telecable de Asturias SA";
+ m_mTable[532][639] = "es,Spain,34,Truphone";
+ m_mTable[532][31] = "es,Spain,34,Vodafone";
+ m_mTable[532][111] = "es,Spain,34,Vodafone Enabler Espana SL";
+ m_mTable[532][79] = "es,Spain,34,Yoigo";
+ m_mTable[1043][95] = "lk,Sri Lanka,94,Bharti Airtel";
+ m_mTable[1043][63] = "lk,Sri Lanka,94,Etisalat/Tigo";
+ m_mTable[1043][143] = "lk,Sri Lanka,94,H3G Hutchison";
+ m_mTable[1043][31] = "lk,Sri Lanka,94,Mobitel Ltd.";
+ m_mTable[1043][47] = "lk,Sri Lanka,94,MTN/Dialog";
+ m_mTable[776][31] = "pm,St. Pierre & Miquelon,508,Ameris";
+ m_mTable[864][272] = "vc,St. Vincent & Gren.,1784,C & W";
+ m_mTable[864][271] = "vc,St. Vincent & Gren.,1784,Cingular";
+ m_mTable[864][256] = "vc,St. Vincent & Gren.,1784,Cingular";
+ m_mTable[864][80] = "vc,St. Vincent & Gren.,1784,Digicel";
+ m_mTable[864][1807] = "vc,St. Vincent & Gren.,1784,Digicel";
+ m_mTable[1588][15] = "sd,Sudan,249,Canar Telecom";
+ m_mTable[1588][47] = "sd,Sudan,249,MTN";
+ m_mTable[1588][559] = "sd,Sudan,249,MTN";
+ m_mTable[1588][351] = "sd,Sudan,249,Sudani One";
+ m_mTable[1588][127] = "sd,Sudan,249,Sudani One";
+ m_mTable[1588][95] = "sd,Sudan,249,Vivacell";
+ m_mTable[1588][143] = "sd,Sudan,249,Vivacell";
+ m_mTable[1588][111] = "sd,Sudan,249,ZAIN/Mobitel";
+ m_mTable[1588][31] = "sd,Sudan,249,ZAIN/Mobitel";
+ m_mTable[1862][63] = "sr,Suriname,597,Digicel";
+ m_mTable[1862][31] = "sr,Suriname,597,Telesur";
+ m_mTable[1862][47] = "sr,Suriname,597,Telecommunicatiebedrijf Suriname (TELESUR)";
+ m_mTable[1862][79] = "sr,Suriname,597,UNIQA";
+ m_mTable[1619][271] = "sz,Swaziland,268,Swazi MTN";
+ m_mTable[1619][31] = "sz,Swaziland,268,SwaziTelecom";
+ m_mTable[576][863] = "se,Sweden,46,42 Telecom AB";
+ m_mTable[576][367] = "se,Sweden,46,42 Telecom AB";
+ m_mTable[576][623] = "se,Sweden,46,Beepsend";
+ m_mTable[576][783] = "se,Sweden,46,NextGen Mobile Ltd (CardBoardFish)";
+ m_mTable[576][655] = "se,Sweden,46,CoolTEL Aps";
+ m_mTable[576][607] = "se,Sweden,46,Digitel Mobile Srl";
+ m_mTable[576][559] = "se,Sweden,46,Eu Tel AB";
+ m_mTable[576][639] = "se,Sweden,46,Fogg Mobile AB";
+ m_mTable[576][399] = "se,Sweden,46,Generic Mobile Systems Sweden AB";
+ m_mTable[576][383] = "se,Sweden,46,Gotalandsnatet AB";
+ m_mTable[576][47] = "se,Sweden,46,H3G Access AB";
+ m_mTable[576][79] = "se,Sweden,46,H3G Access AB";
+ m_mTable[576][879] = "se,Sweden,46,ID Mobile";
+ m_mTable[576][575] = "se,Sweden,46,Infobip Ltd.";
+ m_mTable[576][287] = "se,Sweden,46,Lindholmen Science Park AB";
+ m_mTable[576][303] = "se,Sweden,46,Lycamobile Ltd";
+ m_mTable[576][671] = "se,Sweden,46,Mercury International Carrier Services";
+ m_mTable[576][415] = "se,Sweden,46,Mundio Mobile (Sweden) Ltd";
+ m_mTable[576][271] = "se,Sweden,46,Spring Mobil AB";
+ m_mTable[576][95] = "se,Sweden,46,Svenska UMTS-N";
+ m_mTable[576][335] = "se,Sweden,46,TDC Sverige AB";
+ m_mTable[576][127] = "se,Sweden,46,Tele2 Sverige AB";
+ m_mTable[576][111] = "se,Sweden,46,Telenor (Vodafone)";
+ m_mTable[576][591] = "se,Sweden,46,Telenor (Vodafone)";
+ m_mTable[576][143] = "se,Sweden,46,Telenor (Vodafone)";
+ m_mTable[576][31] = "se,Sweden,46,Telia Mobile";
+ m_mTable[576][319] = "se,Sweden,46,Ventelo Sverige AB";
+ m_mTable[576][527] = "se,Sweden,46,Wireless Maingate AB";
+ m_mTable[576][351] = "se,Sweden,46,Wireless Maingate Nordic AB";
+ m_mTable[552][1311] = "ch,Switzerland,41,BebbiCell AG";
+ m_mTable[552][159] = "ch,Switzerland,41,Comfone AG";
+ m_mTable[552][95] = "ch,Switzerland,41,Comfone AG";
+ m_mTable[552][127] = "ch,Switzerland,41,TDC Sunrise";
+ m_mTable[552][1359] = "ch,Switzerland,41,Lycamobile AG";
+ m_mTable[552][1327] = "ch,Switzerland,41,Mundio Mobile AG";
+ m_mTable[552][63] = "ch,Switzerland,41,Orange";
+ m_mTable[552][31] = "ch,Switzerland,41,Swisscom";
+ m_mTable[552][303] = "ch,Switzerland,41,TDC Sunrise";
+ m_mTable[552][47] = "ch,Switzerland,41,TDC Sunrise";
+ m_mTable[552][143] = "ch,Switzerland,41,TDC Sunrise";
+ m_mTable[552][1343] = "ch,Switzerland,41,upc cablecom GmbH";
+ m_mTable[1047][47] = "sy,Syrian Arab Republic,963,MTN/Spacetel";
+ m_mTable[1047][159] = "sy,Syrian Arab Republic,963,Syriatel Holdings";
+ m_mTable[1047][31] = "sy,Syrian Arab Republic,963,Syriatel Holdings";
+ m_mTable[1126][1679] = "tw,Taiwan,886,ACeS Taiwan - ACeS Taiwan Telecommunications Co Ltd";
+ m_mTable[1126][95] = "tw,Taiwan,886,Asia Pacific Telecom Co. Ltd (APT)";
+ m_mTable[1126][287] = "tw,Taiwan,886,Chunghwa Telecom LDM";
+ m_mTable[1126][2351] = "tw,Taiwan,886,Chunghwa Telecom LDM";
+ m_mTable[1126][127] = "tw,Taiwan,886,Far EasTone";
+ m_mTable[1126][47] = "tw,Taiwan,886,Far EasTone";
+ m_mTable[1126][111] = "tw,Taiwan,886,Far EasTone";
+ m_mTable[1126][63] = "tw,Taiwan,886,Far EasTone";
+ m_mTable[1126][31] = "tw,Taiwan,886,Far EasTone";
+ m_mTable[1126][271] = "tw,Taiwan,886,Global Mobile Corp.";
+ m_mTable[1126][1391] = "tw,Taiwan,886,International Telecom Co. Ltd (FITEL)";
+ m_mTable[1126][2191] = "tw,Taiwan,886,KG Telecom";
+ m_mTable[1126][2431] = "tw,Taiwan,886,Taiwan Cellular";
+ m_mTable[1126][2367] = "tw,Taiwan,886,Mobitai";
+ m_mTable[1126][2463] = "tw,Taiwan,886,TransAsia";
+ m_mTable[1126][2207] = "tw,Taiwan,886,VIBO";
+ m_mTable[1126][159] = "tw,Taiwan,886,VMAX Telecom Co. Ltd";
+ m_mTable[1078][79] = "tk,Tajikistan,992,Babilon-M";
+ m_mTable[1078][95] = "tk,Tajikistan,992,Bee Line";
+ m_mTable[1078][47] = "tk,Tajikistan,992,CJSC Indigo Tajikistan";
+ m_mTable[1078][303] = "tk,Tajikistan,992,Tcell/JC Somoncom";
+ m_mTable[1078][63] = "tk,Tajikistan,992,MLT/TT mobile";
+ m_mTable[1078][31] = "tk,Tajikistan,992,Tcell/JC Somoncom";
+ m_mTable[1600][143] = "tz,Tanzania,255,Benson Informatics Ltd";
+ m_mTable[1600][111] = "tz,Tanzania,255,Dovetel (T) Ltd";
+ m_mTable[1600][159] = "tz,Tanzania,255,ExcellentCom (T) Ltd";
+ m_mTable[1600][287] = "tz,Tanzania,255,Smile Communications Tanzania Ltd";
+ m_mTable[1600][127] = "tz,Tanzania,255,Tanzania Telecommunications Company Ltd (TTCL)";
+ m_mTable[1600][47] = "tz,Tanzania,255,TIGO/MIC";
+ m_mTable[1600][31] = "tz,Tanzania,255,Tri Telecomm. Ltd.";
+ m_mTable[1600][79] = "tz,Tanzania,255,Vodacom Ltd";
+ m_mTable[1600][95] = "tz,Tanzania,255,ZAIN/Celtel";
+ m_mTable[1600][63] = "tz,Tanzania,255,Zantel/Zanzibar Telecom";
+ m_mTable[1312][527] = "th,Thailand,66,ACeS Thailand - ACeS Regional Services Co Ltd";
+ m_mTable[1312][351] = "th,Thailand,66,ACT Mobile";
+ m_mTable[1312][63] = "th,Thailand,66,Advanced Wireless Networks/AWN";
+ m_mTable[1312][31] = "th,Thailand,66,AIS/Advanced Info Service";
+ m_mTable[1312][575] = "th,Thailand,66,Digital Phone Co.";
+ m_mTable[1312][15] = "th,Thailand,66,Hutch/CAT CDMA";
+ m_mTable[1312][399] = "th,Thailand,66,Total Access (DTAC)";
+ m_mTable[1312][95] = "th,Thailand,66,Total Access (DTAC)";
+ m_mTable[1312][79] = "th,Thailand,66,True Move/Orange";
+ m_mTable[1312][2463] = "th,Thailand,66,True Move/Orange";
+ m_mTable[1300][31] = "tp,Timor-Leste,670,Telin/ Telkomcel";
+ m_mTable[1300][47] = "tp,Timor-Leste,670,Timor Telecom";
+ m_mTable[1557][47] = "tg,Togo,228,Telecel/MOOV";
+ m_mTable[1557][63] = "tg,Togo,228,Telecel/MOOV";
+ m_mTable[1557][31] = "tg,Togo,228,Togo Telecom/TogoCELL";
+ m_mTable[1337][1087] = "to,Tonga,676,Shoreline Communication";
+ m_mTable[1337][31] = "to,Tonga,676,Tonga Communications";
+ m_mTable[884][297] = "tt,Trinidad and Tobago,1868,Bmobile/TSTT";
+ m_mTable[884][304] = "tt,Trinidad and Tobago,1868,Digicel";
+ m_mTable[884][320] = "tt,Trinidad and Tobago,1868,LaqTel Ltd.";
+ m_mTable[1541][31] = "tn,Tunisia,216,Orange";
+ m_mTable[1541][63] = "tn,Tunisia,216,Oreedo/Orascom";
+ m_mTable[1541][47] = "tn,Tunisia,216,TuniCell/Tunisia Telecom";
+ m_mTable[646][79] = "tr,Turkey,90,AVEA/Aria";
+ m_mTable[646][63] = "tr,Turkey,90,AVEA/Aria";
+ m_mTable[646][31] = "tr,Turkey,90,Turkcell";
+ m_mTable[646][47] = "tr,Turkey,90,Vodafone-Telsim";
+ m_mTable[1080][31] = "tm,Turkmenistan,993,Barash Communication";
+ m_mTable[1080][47] = "tm,Turkmenistan,993,TM-Cell";
+ m_mTable[886][848] = "tc,Turks and Caicos Islands,1649,Cable & Wireless (TCI) Ltd";
+ m_mTable[886][80] = "tc,Turks and Caicos Islands,1649,Digicel TCI Ltd";
+ m_mTable[886][850] = "tc,Turks and Caicos Islands,1649,IslandCom Communications Ltd.";
+ m_mTable[1363][31] = "tv,Tuvalu,688,Tuvalu Telecommunication Corporation (TTC)";
+ m_mTable[1601][31] = "ug,Uganda,256,Celtel";
+ m_mTable[1601][1647] = "ug,Uganda,256,i-Tel Ltd";
+ m_mTable[1601][783] = "ug,Uganda,256,K2 Telecom Ltd";
+ m_mTable[1601][271] = "ug,Uganda,256,MTN Ltd.";
+ m_mTable[1601][335] = "ug,Uganda,256,Orange";
+ m_mTable[1601][831] = "ug,Uganda,256,Smile Communications Uganda Ltd";
+ m_mTable[1601][399] = "ug,Uganda,256,Suretelecom Uganda Ltd";
+ m_mTable[1601][287] = "ug,Uganda,256,Uganda Telecom Ltd.";
+ m_mTable[1601][559] = "ug,Uganda,256,Airtel/Warid";
+ m_mTable[597][111] = "ua,Ukraine,380,Astelit/LIFE";
+ m_mTable[597][95] = "ua,Ukraine,380,Golden Telecom";
+ m_mTable[597][927] = "ua,Ukraine,380,Golden Telecom";
+ m_mTable[597][79] = "ua,Ukraine,380,Intertelecom Ltd (IT)";
+ m_mTable[597][1663] = "ua,Ukraine,380,KyivStar";
+ m_mTable[597][63] = "ua,Ukraine,380,KyivStar";
+ m_mTable[597][543] = "ua,Ukraine,380,Telesystems Of Ukraine CJSC (TSU)";
+ m_mTable[597][127] = "ua,Ukraine,380,TriMob LLC";
+ m_mTable[597][1295] = "ua,Ukraine,380,UMC/MTS";
+ m_mTable[597][47] = "ua,Ukraine,380,Beeline";
+ m_mTable[597][31] = "ua,Ukraine,380,UMC/MTS";
+ m_mTable[597][1679] = "ua,Ukraine,380,Beeline";
+ m_mTable[1060][63] = "ae,United Arab Emirates,971,DU";
+ m_mTable[1073][47] = "ae,United Arab Emirates,971,Etisalat";
+ m_mTable[1060][47] = "ae,United Arab Emirates,971,Etisalat";
+ m_mTable[1072][47] = "ae,United Arab Emirates,971,Etisalat";
+ m_mTable[564][63] = "gb,United Kingdom,44,Airtel/Vodafone";
+ m_mTable[564][1903] = "gb,United Kingdom,44,BT Group";
+ m_mTable[564][1919] = "gb,United Kingdom,44,BT Group";
+ m_mTable[564][127] = "gb,United Kingdom,44,Cable and Wireless";
+ m_mTable[564][2351] = "gb,United Kingdom,44,Cable and Wireless";
+ m_mTable[564][879] = "gb,United Kingdom,44,Cable and Wireless Isle of Man";
+ m_mTable[564][399] = "gb,United Kingdom,44,Cloud9/wire9 Tel.";
+ m_mTable[565][47] = "gb,United Kingdom,44,Everyth. Ev.wh.";
+ m_mTable[564][383] = "gb,United Kingdom,44,FlexTel";
+ m_mTable[564][1375] = "gb,United Kingdom,44,Guernsey Telecoms";
+ m_mTable[564][335] = "gb,United Kingdom,44,HaySystems";
+ m_mTable[564][527] = "gb,United Kingdom,44,Hutchinson 3G";
+ m_mTable[564][2383] = "gb,United Kingdom,44,Hutchinson 3G";
+ m_mTable[564][1887] = "gb,United Kingdom,44,Inquam Telecom Ltd";
+ m_mTable[564][1295] = "gb,United Kingdom,44,Jersey Telecom";
+ m_mTable[564][863] = "gb,United Kingdom,44,JSC Ingenicum";
+ m_mTable[564][623] = "gb,United Kingdom,44,Lycamobile";
+ m_mTable[564][1423] = "gb,United Kingdom,44,Manx Telecom";
+ m_mTable[564][31] = "gb,United Kingdom,44,Mapesbury C. Ltd";
+ m_mTable[564][655] = "gb,United Kingdom,44,Marthon Telecom";
+ m_mTable[564][271] = "gb,United Kingdom,44,O2 Ltd.";
+ m_mTable[564][47] = "gb,United Kingdom,44,O2 Ltd.";
+ m_mTable[564][287] = "gb,United Kingdom,44,O2 Ltd.";
+ m_mTable[564][143] = "gb,United Kingdom,44,OnePhone";
+ m_mTable[564][367] = "gb,United Kingdom,44,Opal Telecom";
+ m_mTable[564][847] = "gb,United Kingdom,44,Everyth. Ev.wh./Orange";
+ m_mTable[564][831] = "gb,United Kingdom,44,Everyth. Ev.wh./Orange";
+ m_mTable[564][415] = "gb,United Kingdom,44,PMN/Teleware";
+ m_mTable[564][303] = "gb,United Kingdom,44,Railtrack Plc";
+ m_mTable[564][559] = "gb,United Kingdom,44,Routotelecom";
+ m_mTable[564][591] = "gb,United Kingdom,44,Stour Marine";
+ m_mTable[564][895] = "gb,United Kingdom,44,Synectiv Ltd.";
+ m_mTable[564][799] = "gb,United Kingdom,44,Everyth. Ev.wh./T-Mobile";
+ m_mTable[564][783] = "gb,United Kingdom,44,Everyth. Ev.wh./T-Mobile";
+ m_mTable[564][815] = "gb,United Kingdom,44,Everyth. Ev.wh./T-Mobile";
+ m_mTable[564][639] = "gb,United Kingdom,44,Vodafone";
+ m_mTable[564][159] = "gb,United Kingdom,44,Tismi";
+ m_mTable[564][607] = "gb,United Kingdom,44,Truphone";
+ m_mTable[564][1311] = "gb,United Kingdom,44,Jersey Telecom";
+ m_mTable[564][575] = "gb,United Kingdom,44,Vectofone Mobile Wifi";
+ m_mTable[564][351] = "gb,United Kingdom,44,Vodafone";
+ m_mTable[564][2335] = "gb,United Kingdom,44,Vodafone";
+ m_mTable[564][1935] = "gb,United Kingdom,44,Wave Telecom Ltd";
+ m_mTable[784][80] = "us,United States,1,";
+ m_mTable[784][2176] = "us,United States,1,";
+ m_mTable[784][2128] = "us,United States,1,Aeris Comm. Inc.";
+ m_mTable[784][1600] = "us,United States,1,";
+ m_mTable[784][1296] = "us,United States,1,Airtel Wireless LLC";
+ m_mTable[784][400] = "us,United States,1,Unknown";
+ m_mTable[786][144] = "us,United States,1,Allied Wireless Communications Corporation";
+ m_mTable[785][304] = "us,United States,1,";
+ m_mTable[784][1808] = "us,United States,1,Arctic Slope Telephone Association Cooperative Inc.";
+ m_mTable[784][336] = "us,United States,1,AT&T Wireless Inc.";
+ m_mTable[784][1664] = "us,United States,1,AT&T Wireless Inc.";
+ m_mTable[784][112] = "us,United States,1,AT&T Wireless Inc.";
+ m_mTable[784][1376] = "us,United States,1,AT&T Wireless Inc.";
+ m_mTable[784][1040] = "us,United States,1,AT&T Wireless Inc.";
+ m_mTable[784][896] = "us,United States,1,AT&T Wireless Inc.";
+ m_mTable[784][368] = "us,United States,1,AT&T Wireless Inc.";
+ m_mTable[784][2432] = "us,United States,1,AT&T Wireless Inc.";
+ m_mTable[785][2064] = "us,United States,1,Bluegrass Wireless LLC";
+ m_mTable[785][2048] = "us,United States,1,Bluegrass Wireless LLC";
+ m_mTable[785][1088] = "us,United States,1,Bluegrass Wireless LLC";
+ m_mTable[784][2304] = "us,United States,1,Cable & Communications Corp.";
+ m_mTable[785][1424] = "us,United States,1,California RSA No. 3 Limited Partnership";
+ m_mTable[785][1280] = "us,United States,1,Cambridge Telephone Company Inc.";
+ m_mTable[784][2096] = "us,United States,1,Caprock Cellular Ltd.";
+ m_mTable[785][630] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][1153] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][1158] = "us,United States,1,Verizon Wireless";
+ m_mTable[784][19] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][641] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][624] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][646] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][629] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][1152] = "us,United States,1,Verizon Wireless";
+ m_mTable[784][18] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][640] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][1157] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][272] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][645] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][628] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][912] = "us,United States,1,Verizon Wireless";
+ m_mTable[784][16] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][633] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][1156] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][1161] = "us,United States,1,Verizon Wireless";
+ m_mTable[784][2320] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][644] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][627] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][649] = "us,United States,1,Verizon Wireless";
+ m_mTable[784][4] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][632] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][1155] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][1160] = "us,United States,1,Verizon Wireless";
+ m_mTable[784][2192] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][643] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][626] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][648] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][631] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][1154] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][1159] = "us,United States,1,Verizon Wireless";
+ m_mTable[784][1424] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][642] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][625] = "us,United States,1,Verizon Wireless";
+ m_mTable[785][647] = "us,United States,1,Verizon Wireless";
+ m_mTable[786][624] = "us,United States,1,Cellular Network Partnership LLC";
+ m_mTable[784][864] = "us,United States,1,Cellular Network Partnership LLC";
+ m_mTable[786][640] = "us,United States,1,Cellular Network Partnership LLC";
+ m_mTable[785][400] = "us,United States,1,";
+ m_mTable[784][48] = "us,United States,1,";
+ m_mTable[785][288] = "us,United States,1,Choice Phone LLC";
+ m_mTable[784][1152] = "us,United States,1,Choice Phone LLC";
+ m_mTable[784][1584] = "us,United States,1,";
+ m_mTable[784][1056] = "us,United States,1,Cincinnati Bell Wireless LLC";
+ m_mTable[784][384] = "us,United States,1,Cingular Wireless";
+ m_mTable[784][1568] = "us,United States,1,Coleman County Telco /Trans TX";
+ m_mTable[785][64] = "us,United States,1,";
+ m_mTable[784][1551] = "us,United States,1,Consolidated Telcom";
+ m_mTable[784][111] = "us,United States,1,Consolidated Telcom";
+ m_mTable[786][896] = "us,United States,1,";
+ m_mTable[784][2352] = "us,United States,1,";
+ m_mTable[785][576] = "us,United States,1,";
+ m_mTable[784][128] = "us,United States,1,";
+ m_mTable[784][1792] = "us,United States,1,Cross Valliant Cellular Partnership";
+ m_mTable[786][48] = "us,United States,1,Cross Wireless Telephone Co.";
+ m_mTable[785][320] = "us,United States,1,Cross Wireless Telephone Co.";
+ m_mTable[785][1312] = "us,United States,1,";
+ m_mTable[786][64] = "us,United States,1,Custer Telephone Cooperative Inc.";
+ m_mTable[784][1088] = "us,United States,1,Dobson Cellular Systems";
+ m_mTable[784][2448] = "us,United States,1,E.N.M.R. Telephone Coop.";
+ m_mTable[784][1872] = "us,United States,1,East Kentucky Network LLC";
+ m_mTable[786][304] = "us,United States,1,East Kentucky Network LLC";
+ m_mTable[786][288] = "us,United States,1,East Kentucky Network LLC";
+ m_mTable[784][144] = "us,United States,1,Edge Wireless LLC";
+ m_mTable[784][1552] = "us,United States,1,Elkhart TelCo. / Epic Touch Co.";
+ m_mTable[785][528] = "us,United States,1,";
+ m_mTable[785][785] = "us,United States,1,Farmers";
+ m_mTable[785][1120] = "us,United States,1,Fisher Wireless Services Inc.";
+ m_mTable[785][880] = "us,United States,1,GCI Communication Corp.";
+ m_mTable[784][1072] = "us,United States,1,GCI Communication Corp.";
+ m_mTable[784][2336] = "us,United States,1,Get Mobile Inc.";
+ m_mTable[784][2416] = "us,United States,1,";
+ m_mTable[785][832] = "us,United States,1,Illinois Valley Cellular RSA 2 Partnership";
+ m_mTable[785][48] = "us,United States,1,";
+ m_mTable[785][1040] = "us,United States,1,Iowa RSA No. 2 Limited Partnership";
+ m_mTable[786][368] = "us,United States,1,Iowa RSA No. 2 Limited Partnership";
+ m_mTable[784][1904] = "us,United States,1,Iowa Wireless Services LLC";
+ m_mTable[784][1616] = "us,United States,1,Jasper";
+ m_mTable[784][2160] = "us,United States,1,Kaplan Telephone Company Inc.";
+ m_mTable[786][384] = "us,United States,1,Keystone Wireless LLC";
+ m_mTable[784][1680] = "us,United States,1,Keystone Wireless LLC";
+ m_mTable[785][784] = "us,United States,1,Lamar County Cellular";
+ m_mTable[784][22] = "us,United States,1,Leap Wireless International Inc.";
+ m_mTable[785][144] = "us,United States,1,";
+ m_mTable[784][64] = "us,United States,1,Matanuska Tel. Assn. Inc.";
+ m_mTable[784][1920] = "us,United States,1,Message Express Co. / Airlink PCS";
+ m_mTable[785][1632] = "us,United States,1,";
+ m_mTable[785][816] = "us,United States,1,Michigan Wireless LLC";
+ m_mTable[785][0] = "us,United States,1,";
+ m_mTable[784][1024] = "us,United States,1,Minnesota South. Wirel. Co. / Hickory";
+ m_mTable[786][544] = "us,United States,1,Missouri RSA No 5 Partnership";
+ m_mTable[786][16] = "us,United States,1,Missouri RSA No 5 Partnership";
+ m_mTable[785][2336] = "us,United States,1,Missouri RSA No 5 Partnership";
+ m_mTable[785][32] = "us,United States,1,Missouri RSA No 5 Partnership";
+ m_mTable[785][16] = "us,United States,1,Missouri RSA No 5 Partnership";
+ m_mTable[784][848] = "us,United States,1,Mohave Cellular LP";
+ m_mTable[784][1392] = "us,United States,1,MTPCS LLC";
+ m_mTable[784][656] = "us,United States,1,NEP Cellcorp Inc.";
+ m_mTable[784][847] = "us,United States,1,Nevada Wireless LLC";
+ m_mTable[785][896] = "us,United States,1,";
+ m_mTable[784][1536] = "us,United States,1,New-Cell Inc.";
+ m_mTable[785][256] = "us,United States,1,";
+ m_mTable[785][768] = "us,United States,1,Nexus Communications Inc.";
+ m_mTable[784][304] = "us,United States,1,North Carolina RSA 3 Cellular Tel. Co.";
+ m_mTable[786][560] = "us,United States,1,North Dakota Network Company";
+ m_mTable[785][1552] = "us,United States,1,North Dakota Network Company";
+ m_mTable[784][1104] = "us,United States,1,Northeast Colorado Cellular Inc.";
+ m_mTable[785][1808] = "us,United States,1,Northeast Wireless Networks LLC";
+ m_mTable[784][1648] = "us,United States,1,Northstar";
+ m_mTable[784][17] = "us,United States,1,Northstar";
+ m_mTable[785][1056] = "us,United States,1,Northwest Missouri Cellular Limited Partnership";
+ m_mTable[784][1344] = "us,United States,1,";
+ m_mTable[784][1888] = "us,United States,1,Panhandle Telephone Cooperative Inc.";
+ m_mTable[784][1408] = "us,United States,1,PCS ONE";
+ m_mTable[785][368] = "us,United States,1,PetroCom";
+ m_mTable[785][1648] = "us,United States,1,Pine Belt Cellular Inc.";
+ m_mTable[785][128] = "us,United States,1,";
+ m_mTable[784][1936] = "us,United States,1,";
+ m_mTable[784][256] = "us,United States,1,Plateau Telecommunications Inc.";
+ m_mTable[784][2368] = "us,United States,1,Poka Lambro Telco Ltd.";
+ m_mTable[785][1840] = "us,United States,1,";
+ m_mTable[785][1344] = "us,United States,1,";
+ m_mTable[784][1280] = "us,United States,1,Public Service Cellular Inc.";
+ m_mTable[785][1072] = "us,United States,1,RSA 1 Limited Partnership";
+ m_mTable[786][352] = "us,United States,1,RSA 1 Limited Partnership";
+ m_mTable[785][848] = "us,United States,1,Sagebrush Cellular Inc.";
+ m_mTable[785][2320] = "us,United States,1,";
+ m_mTable[784][1135] = "us,United States,1,SIMMETRY";
+ m_mTable[785][608] = "us,United States,1,SLO Cellular Inc / Cellular One of San Luis";
+ m_mTable[784][800] = "us,United States,1,Smith Bagley Inc.";
+ m_mTable[784][351] = "us,United States,1,Unknown";
+ m_mTable[790][17] = "us,United States,1,Southern Communications Services Inc.";
+ m_mTable[786][1328] = "us,United States,1,Sprint Spectrum";
+ m_mTable[785][2160] = "us,United States,1,Sprint Spectrum";
+ m_mTable[785][1168] = "us,United States,1,Sprint Spectrum";
+ m_mTable[784][288] = "us,United States,1,Sprint Spectrum";
+ m_mTable[790][16] = "us,United States,1,Sprint Spectrum";
+ m_mTable[786][400] = "us,United States,1,Sprint Spectrum";
+ m_mTable[785][2176] = "us,United States,1,Sprint Spectrum";
+ m_mTable[784][512] = "us,United States,1,T-Mobile";
+ m_mTable[784][592] = "us,United States,1,T-Mobile";
+ m_mTable[784][352] = "us,United States,1,T-Mobile";
+ m_mTable[784][576] = "us,United States,1,T-Mobile";
+ m_mTable[784][1632] = "us,United States,1,T-Mobile";
+ m_mTable[784][560] = "us,United States,1,T-Mobile";
+ m_mTable[784][799] = "us,United States,1,T-Mobile";
+ m_mTable[784][544] = "us,United States,1,T-Mobile";
+ m_mTable[784][624] = "us,United States,1,T-Mobile";
+ m_mTable[784][528] = "us,United States,1,T-Mobile";
+ m_mTable[784][608] = "us,United States,1,T-Mobile";
+ m_mTable[784][2048] = "us,United States,1,T-Mobile";
+ m_mTable[784][768] = "us,United States,1,T-Mobile";
+ m_mTable[784][640] = "us,United States,1,T-Mobile";
+ m_mTable[784][816] = "us,United States,1,T-Mobile";
+ m_mTable[784][784] = "us,United States,1,T-Mobile";
+ m_mTable[785][1856] = "us,United States,1,";
+ m_mTable[784][1856] = "us,United States,1,Telemetrix Inc.";
+ m_mTable[784][335] = "us,United States,1,Testing";
+ m_mTable[784][2384] = "us,United States,1,Unknown";
+ m_mTable[784][2144] = "us,United States,1,Texas RSA 15B2 Limited Partnership";
+ m_mTable[785][2096] = "us,United States,1,Thumb Cellular Limited Partnership";
+ m_mTable[785][80] = "us,United States,1,Thumb Cellular Limited Partnership";
+ m_mTable[784][1120] = "us,United States,1,TMP Corporation";
+ m_mTable[784][1168] = "us,United States,1,Triton PCS";
+ m_mTable[786][656] = "us,United States,1,Uintah Basin Electronics Telecommunications Inc.";
+ m_mTable[785][2144] = "us,United States,1,Uintah Basin Electronics Telecommunications Inc.";
+ m_mTable[784][2400] = "us,United States,1,Uintah Basin Electronics Telecommunications Inc.";
+ m_mTable[784][32] = "us,United States,1,Union Telephone Co.";
+ m_mTable[785][544] = "us,United States,1,United States Cellular Corp.";
+ m_mTable[784][1840] = "us,United States,1,United States Cellular Corp.";
+ m_mTable[785][1616] = "us,United States,1,United Wireless Communications Inc.";
+ m_mTable[784][911] = "us,United States,1,USA 3650 AT&T";
+ m_mTable[784][1312] = "us,United States,1,VeriSign";
+ m_mTable[784][3] = "us,United States,1,Unknown";
+ m_mTable[784][575] = "us,United States,1,Unknown";
+ m_mTable[784][591] = "us,United States,1,Unknown";
+ m_mTable[784][607] = "us,United States,1,Unknown";
+ m_mTable[784][1328] = "us,United States,1,West Virginia Wireless";
+ m_mTable[784][623] = "us,United States,1,Unknown";
+ m_mTable[784][832] = "us,United States,1,Westlink Communications LLC";
+ m_mTable[785][336] = "us,United States,1,";
+ m_mTable[785][112] = "us,United States,1,Wisconsin RSA #7 Limited Partnership";
+ m_mTable[784][912] = "us,United States,1,Yorkville Telephone Cooperative";
+ m_mTable[1864][63] = "uy,Uruguay,598,Ancel/Antel";
+ m_mTable[1864][31] = "uy,Uruguay,598,Ancel/Antel";
+ m_mTable[1864][271] = "uy,Uruguay,598,Claro/AM Wireless";
+ m_mTable[1864][127] = "uy,Uruguay,598,MOVISTAR";
+ m_mTable[1076][79] = "uz,Uzbekistan,998,Bee Line/Unitel";
+ m_mTable[1076][31] = "uz,Uzbekistan,998,Buztel";
+ m_mTable[1076][127] = "uz,Uzbekistan,998,MTS/Uzdunrobita";
+ m_mTable[1076][95] = "uz,Uzbekistan,998,Ucell/Coscom";
+ m_mTable[1076][47] = "uz,Uzbekistan,998,Uzmacom";
+ m_mTable[1345][95] = "vu,Vanuatu,678,DigiCel";
+ m_mTable[1345][31] = "vu,Vanuatu,678,SMILE";
+ m_mTable[1844][63] = "ve,Venezuela,58,DigiTel C.A.";
+ m_mTable[1844][47] = "ve,Venezuela,58,DigiTel C.A.";
+ m_mTable[1844][31] = "ve,Venezuela,58,DigiTel C.A.";
+ m_mTable[1844][111] = "ve,Venezuela,58,Movilnet C.A.";
+ m_mTable[1844][79] = "ve,Venezuela,58,Movistar/TelCel";
+ m_mTable[1106][127] = "vn,Viet Nam,84,Beeline";
+ m_mTable[1106][31] = "vn,Viet Nam,84,Mobifone";
+ m_mTable[1106][63] = "vn,Viet Nam,84,S-Fone/Telecom";
+ m_mTable[1106][95] = "vn,Viet Nam,84,VietnaMobile";
+ m_mTable[1106][111] = "vn,Viet Nam,84,Viettel Mobile";
+ m_mTable[1106][79] = "vn,Viet Nam,84,Viettel Mobile";
+ m_mTable[1106][143] = "vn,Viet Nam,84,Viettel Mobile";
+ m_mTable[1106][47] = "vn,Viet Nam,84,Vinaphone";
+ m_mTable[886][1295] = "vi,Virgin Islands U.S.,1340,Digicel";
+ m_mTable[1057][79] = "ye,Yemen,967,HITS/Y Unitel";
+ m_mTable[1057][47] = "ye,Yemen,967,MTN/Spacetel";
+ m_mTable[1057][31] = "ye,Yemen,967,Sabaphone";
+ m_mTable[1057][63] = "ye,Yemen,967,Yemen Mob. CDMA";
+ m_mTable[1605][63] = "zm,Zambia,260,Cell Z/MTS";
+ m_mTable[1605][47] = "zm,Zambia,260,MTN/Telecel";
+ m_mTable[1605][31] = "zm,Zambia,260,Airtel/Zain/Celtel";
+ m_mTable[1608][79] = "zw,Zimbabwe,263,Econet";
+ m_mTable[1608][31] = "zw,Zimbabwe,263,Net One";
+ m_mTable[1608][63] = "zw,Zimbabwe,263,Telecel";
+}
+
diff --git a/src/MTS_IO_SerialConnection.cpp b/src/MTS_IO_SerialConnection.cpp
new file mode 100644
index 0000000..8f0b8e3
--- /dev/null
+++ b/src/MTS_IO_SerialConnection.cpp
@@ -0,0 +1,545 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_SerialConnection.cpp
+ \brief A brief description
+ \date Jan 15, 2013
+ \author sgodinez
+
+ A more elaborate description
+*/
+
+#include <mts/MTS_IO_SerialConnection.h>
+#include <mts/MTS_Text.h>
+#include <mts/MTS_Logger.h>
+#include <unistd.h>
+
+#ifdef WIN32
+
+#else
+#include <fcntl.h> /* File control definitions */
+#include <errno.h> /* Error number definitions */
+#include <termios.h> /* POSIX terminal control definitions */
+#include <string.h> /* String function definitions */
+#endif
+
+using namespace MTS::IO;
+
+SerialConnection::Builder::Builder(const std::string& sPortName)
+: m_sPortName(sPortName)
+, m_iBaudRate(9600)
+, m_eType(RS232)
+, m_eParity(OFF)
+, m_eDataBits(B8)
+, m_eStopBits(B1)
+, m_bBuilt(false)
+{
+
+}
+
+SerialConnection::Builder& SerialConnection::Builder::type(const ETYPE& eType) {
+ m_eType = eType;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::rs232() {
+ m_eType = RS232;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::rs422() {
+ m_eType = RS422;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::rs485() {
+ m_eType = RS485;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::parity(const EPARITY& eParity) {
+ m_eParity = eParity;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::parityOff() {
+ m_eParity = OFF;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::parityOdd() {
+ m_eParity = ODD;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::parityEven() {
+ m_eParity = EVEN;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::dataBits(const EDATABITS& eDataBits) {
+ m_eDataBits = eDataBits;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::fiveDataBits() {
+ m_eDataBits = B5;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::sixDataBits() {
+ m_eDataBits = B6;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::sevenDataBits() {
+ m_eDataBits = B7;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::eightDataBits() {
+ m_eDataBits = B8;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::stopBits(const ESTOPBITS& eStopBits) {
+ m_eStopBits = eStopBits;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::oneStopBit() {
+ m_eStopBits = B1;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::twoStopBits() {
+ m_eStopBits = B2;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::baudRate(uint32_t iBaud) {
+ m_iBaudRate = iBaud;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::useLockFile(bool bEnabled) {
+ m_bLockFile = bEnabled;
+ return *this;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::build() {
+ m_bBuilt = true;
+ return *this;
+}
+
+const std::string& SerialConnection::Builder::getPortName() const {
+ return m_sPortName;
+}
+
+const uint32_t& SerialConnection::Builder::getBaudRate() const {
+ return m_iBaudRate;
+}
+
+SerialConnection::ETYPE SerialConnection::Builder::getType() const {
+ return m_eType;
+}
+
+SerialConnection::EPARITY SerialConnection::Builder::getParity() const {
+ return m_eParity;
+}
+
+SerialConnection::EDATABITS SerialConnection::Builder::getDataBits() const {
+ return m_eDataBits;
+}
+
+SerialConnection::ESTOPBITS SerialConnection::Builder::getStopBits() const {
+ return m_eStopBits;
+}
+
+bool SerialConnection::Builder::isUsingLockFile() const {
+ return m_bLockFile;
+}
+
+std::string SerialConnection::Builder::getTypeAsString() const {
+ std::string sType;
+ switch(m_eType) {
+ case RS232:
+ sType = "RS232";
+ break;
+ case RS422:
+ sType = "RS422";
+ break;
+ case RS485:
+ sType = "RS485";
+ break;
+ default:
+ break;
+ }
+ return sType;
+}
+
+SerialConnection::Builder& SerialConnection::Builder::flowControl(const SerialConnection::FLOW_CONTROL& eFlowControl) {
+ m_eFlowControl = eFlowControl;
+ return *this;
+}
+
+SerialConnection::FLOW_CONTROL SerialConnection::Builder::getFlowControl() const {
+ return m_eFlowControl;
+}
+
+bool SerialConnection::Builder::isBuilt() const {
+ return m_bBuilt;
+}
+
+SerialConnection::SerialConnection(const Builder& oBuilder)
+: Connection(oBuilder.getTypeAsString())
+, m_sPortName(oBuilder.getPortName())
+, m_iBaudRate(oBuilder.getBaudRate())
+, m_eType(oBuilder.getType())
+, m_eParity(oBuilder.getParity())
+, m_eDataBits(oBuilder.getDataBits())
+, m_eStopBits(oBuilder.getStopBits())
+, m_eFlowControl(oBuilder.getFlowControl())
+{
+ if(!oBuilder.isBuilt()) {
+ //Throw Exception?
+ }
+#ifdef WIN32
+ m_iHandle = INVALID_HANDLE_VALUE;
+#else
+ m_iHandle = -1;
+#endif
+ m_apHandleLock.reset(new Lock());
+ if(oBuilder.isUsingLockFile()) {
+ std::vector<std::string> vParts = MTS::Text::split(m_sPortName, "/");
+ m_apLockFile.reset(new LockFile("/var/lock/LCK.." + vParts[vParts.size()-1]));
+ }
+}
+
+SerialConnection::~SerialConnection() {
+ doClose();
+ m_apHandleLock.reset();
+}
+
+const std::string& SerialConnection::getPortName() const {
+ return m_sPortName;
+}
+
+uint32_t SerialConnection::getBaudRate() const {
+ return m_iBaudRate;
+}
+
+int SerialConnection::getFileDescriptor() {
+ m_apHandleLock->lock();
+ int h = m_iHandle;
+ m_apHandleLock->unlock();
+ return h;
+}
+
+bool SerialConnection::doOpen(const int32_t& timeoutMillis) {
+ m_apHandleLock->lock();
+
+ if (m_iHandle != -1) {
+ m_apHandleLock->unlock();
+ return true;
+ }
+ if(!m_apLockFile.isNull() && !m_apLockFile->lock(timeoutMillis)) {
+ printError("SERIAL| Failed to obtain file lock");
+ m_apHandleLock->unlock();
+ return false;
+ }
+
+#ifdef WIN32
+
+#else
+ m_iHandle = ::open(m_sPortName.c_str(), O_RDWR | O_NOCTTY );
+ if (m_iHandle == -1) {
+ printWarning("SERIAL| Failed to open port [%s] [%d]", m_sPortName.c_str(), errno);
+ if(!m_apLockFile.isNull()) {
+ m_apLockFile->unlock();
+ }
+ m_apHandleLock->unlock();
+ return false;
+ }
+
+ int result = tcgetattr(m_iHandle, &m_stPrevOptions);
+ if (result == -1) {
+ printWarning("SERIAL| Failed to get attributes on port [%s] [%d]", m_sPortName.c_str(), errno);
+ }
+
+ termios options = m_stPrevOptions;
+
+ //Set to Raw Mode
+ cfmakeraw(&options);
+
+ //Set the Baud Rate
+ speed_t speed = B9600;
+ switch (m_iBaudRate) {
+ case 300:
+ speed = B300;
+ break;
+ case 600:
+ speed = B600;
+ break;
+ case 1200:
+ speed = B1200;
+ break;
+ case 2400:
+ speed = B2400;
+ break;
+ case 4800:
+ speed = B4800;
+ break;
+ case 9600:
+ speed = B9600;
+ break;
+ case 19200:
+ speed = B19200;
+ break;
+ case 38400:
+ speed = B38400;
+ break;
+ case 57600:
+ speed = B57600;
+ break;
+ case 115200:
+ speed = B115200;
+ break;
+ case 230400:
+ speed = B230400;
+ break;
+ case 460800:
+ speed = B460800;
+ break;
+ case 921600:
+ speed = B921600;
+ break;
+ default:
+ printWarning("SERIAL| Baud Rate [%d] not supported. Defaulting to 9600.", m_iBaudRate);
+ m_iBaudRate = 9600;
+ speed = B9600;
+ break;
+ }
+
+ result = cfsetispeed(&options, speed);
+ if (result == -1) {
+ printWarning("SERIAL| Failed to set input speed of [%d] on port [%s] [%d]", m_iBaudRate, m_sPortName.c_str(), errno);
+ goto CLEANUP;
+ }
+ result = cfsetospeed(&options, speed);
+ if (result == -1) {
+ printWarning("SERIAL| Failed to set output speed of [%d] on port [%s] [%d]", m_iBaudRate, m_sPortName.c_str(), errno);
+ goto CLEANUP;
+ }
+
+ //Set Parity, Stop Bits, and Data Length
+ switch(m_eParity) {
+ case ODD:
+ options.c_cflag |= ( PARODD | PARENB );
+ break;
+
+ case EVEN:
+ options.c_cflag |= PARENB;
+ break;
+
+ case OFF:
+ default:
+ options.c_cflag &= ~PARENB;
+ break;
+ }
+
+ options.c_cflag &= ~CSIZE;
+ switch(m_eDataBits) {
+ case B5:
+ options.c_cflag |= CS5;
+ break;
+
+ case B6:
+ options.c_cflag |= CS6;
+ break;
+
+ case B7:
+ options.c_cflag |= CS7;
+ break;
+
+ case B8:
+ default:
+ options.c_cflag |= CS8;
+ break;
+ }
+
+ switch(m_eStopBits) {
+ case B2:
+ options.c_cflag &= CSTOPB;
+ break;
+
+ case B1:
+ default:
+ options.c_cflag &= ~CSTOPB;
+ break;
+ }
+
+ switch (m_eFlowControl) {
+ case RTS_CTS:
+ options.c_cflag &= CRTSCTS;
+ break;
+ case NONE:
+ default:
+ options.c_cflag &= ~(IXON | IXOFF | IXANY);
+ break;
+ }
+
+ //Set Control Modes
+ options.c_cc[VMIN] = 0;
+ options.c_cc[VTIME] = 2; // tenths of seconds
+
+ result = tcsetattr(m_iHandle, TCSANOW, &options);
+ if (result == -1) {
+ printWarning("SERIAL| Failed to set configurations on port [%s] [%d]", m_sPortName.c_str(), errno);
+ goto CLEANUP;
+ }
+ result = tcflush(m_iHandle, TCIOFLUSH);
+ if (result == -1) {
+ printWarning("SERIAL| Failed to flush port [%s] [%d]", m_sPortName.c_str(), errno);
+ goto CLEANUP;
+ }
+#endif
+ m_apHandleLock->unlock();
+ printInfo("SERIAL| %s connection opened on %s @ %d", getName().c_str(), m_sPortName.c_str(), m_iBaudRate);
+ return true;
+CLEANUP:
+ cleanup();
+ m_apHandleLock->unlock();
+ return false;
+}
+
+void SerialConnection::doClose() {
+ m_apHandleLock->lock();
+ cleanup();
+ m_apHandleLock->unlock();
+}
+
+int SerialConnection::doRead(char* pBuffer, const uint32_t& iSize, int32_t& timeoutMillis) {
+ int32_t result = -1;
+#ifdef WIN32
+
+#else
+
+ int h = getFileDescriptor();
+
+ if (h == -1) {
+ printError("SERIAL| bad handle on port %s", m_sPortName.c_str());
+ return result;
+ }
+
+ if(timeoutMillis < 0) {
+ result = ::read(h, pBuffer, iSize);
+ } else {
+ fd_set readfs;
+ struct timeval stTimeout;
+ stTimeout.tv_usec = ((timeoutMillis%1000) * 1000);
+ stTimeout.tv_sec = timeoutMillis/1000;
+
+ FD_ZERO(&readfs);
+ FD_SET(h, &readfs);
+ int res = select(h + 1, &readfs, NULL, NULL, &stTimeout);
+ if(res == -1) {
+ result = -1;
+ } else if (res == 0) {
+ //Timeout Occured
+ //printTrace("SERIAL| read timed out on port [%s]", m_sPortName.c_str());
+ result = 0;
+ } else {
+ if (FD_ISSET(h, &readfs)) {
+ result = ::read(h, pBuffer, iSize);
+ } else {
+ //socket closed?
+ result = -1;
+ }
+ }
+ timeoutMillis = (stTimeout.tv_usec / 1000) + (stTimeout.tv_sec * 1000);
+ }
+#endif
+ if (result < 0) {
+ printWarning("SERIAL| failed to read from %s [%d]", m_sPortName.c_str(), errno);
+ }
+ return result;
+}
+
+int SerialConnection::doWrite(const char* pBuffer, const uint32_t& iSize, int32_t& timeoutMillis) {
+ int32_t result = -1;
+#ifdef WIN32
+
+#else
+
+ int h = getFileDescriptor();
+
+ if (h == -1) {
+ printError("SERIAL| bad handle on port %s", m_sPortName.c_str());
+ return result;
+ }
+
+ if(timeoutMillis < 0) {
+ result = ::write(h, pBuffer, iSize);
+ } else {
+ //No difference between timeout and no timeout
+ result = ::write(h, pBuffer, iSize);
+ }
+
+#endif
+ if (result < 0) {
+ printWarning("SERIAL| failed to write to %s [%d]", m_sPortName.c_str(), errno);
+ }
+ return result;
+}
+
+void SerialConnection::cleanup() {
+#ifdef WIN32
+ CloseHandle(m_iHandle);
+ m_iHandle = INVALID_HANDLE_VALUE;
+#else
+ if(m_iHandle >= 0) {
+ int result = tcsetattr(m_iHandle, TCSANOW, &m_stPrevOptions);
+ if (result == -1) {
+ printWarning("SERIAL| Failed to revert configurations on port [%s] [%d]", m_sPortName.c_str(), errno);
+ }
+ ::close(m_iHandle);
+ m_iHandle = -1;
+ }
+#endif
+ if(!m_apLockFile.isNull()) {
+ m_apLockFile->unlock();
+ }
+}
+
+void SerialConnection::drain() {
+ int result = tcdrain(m_iHandle);
+ if (result == -1) {
+ printWarning("SERIAL| Failed to drain port [%s] [%d]", m_sPortName.c_str(), errno);
+ }
+}
+
+void SerialConnection::flush() {
+ int result = tcflush(m_iHandle, TCIOFLUSH);
+ if (result == -1) {
+ printWarning("SERIAL| Failed to flush port [%s] [%d]", m_sPortName.c_str(), errno);
+ }
+}