diff options
author | Jesse Gilles <jgilles@multitech.com> | 2015-04-20 17:14:31 -0500 |
---|---|---|
committer | Jesse Gilles <jgilles@multitech.com> | 2015-04-20 17:14:31 -0500 |
commit | d84d880627bcc1e1898a8f96b861bc25863ec86c (patch) | |
tree | e7db4eef6a8e8254eaa6ba0c7e5d56098af19d16 /src | |
download | libmts-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.cpp | 42 | ||||
-rw-r--r-- | src/MTS_IO_CdmaRadio.cpp | 1297 | ||||
-rw-r--r-- | src/MTS_IO_CellularRadio.cpp | 1522 | ||||
-rw-r--r-- | src/MTS_IO_CellularRadioFactory.cpp | 145 | ||||
-rw-r--r-- | src/MTS_IO_Connection.cpp | 155 | ||||
-rw-r--r-- | src/MTS_IO_DE910Radio.cpp | 41 | ||||
-rw-r--r-- | src/MTS_IO_GE910Radio.cpp | 41 | ||||
-rw-r--r-- | src/MTS_IO_HE910DRadio.cpp | 41 | ||||
-rw-r--r-- | src/MTS_IO_HE910EUDRadio.cpp | 42 | ||||
-rw-r--r-- | src/MTS_IO_HE910Radio.cpp | 40 | ||||
-rw-r--r-- | src/MTS_IO_LE910EUGRadio.cpp | 41 | ||||
-rw-r--r-- | src/MTS_IO_LE910NAGRadio.cpp | 45 | ||||
-rw-r--r-- | src/MTS_IO_LE910Radio.cpp | 39 | ||||
-rw-r--r-- | src/MTS_IO_LE910SVGRadio.cpp | 45 | ||||
-rw-r--r-- | src/MTS_IO_LockFile.cpp | 109 | ||||
-rw-r--r-- | src/MTS_IO_MccMncTable.cpp | 1723 | ||||
-rw-r--r-- | src/MTS_IO_SerialConnection.cpp | 545 |
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); + } +} |