diff options
Diffstat (limited to 'main.cpp')
-rw-r--r-- | main.cpp | 601 |
1 files changed, 601 insertions, 0 deletions
diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..46d2135 --- /dev/null +++ b/main.cpp @@ -0,0 +1,601 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of radio-query. + * + * radio-query is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * radio-query 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with radio-query. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <mts/MTS_Text.h> +#include <mts/MTS_Logger.h> +#include <mts/MTS_AutoPtr.h> +#include <mts/MTS_IO_CellularRadio.h> +#include <mts/MTS_IO_CellularRadioFactory.h> +#include <json/json.h> +#include <sstream> +#include <getopt.h> +#include <sys/stat.h> +#include <errno.h> +#include <string.h> +#include <stdio.h> +#include <iostream> +#include <fstream> +#include <signal.h> +#include <unistd.h> +#include "Version.h" + +const std::string DEFAULT_PORT("/dev/modem_at1"); +const std::string DEFAULT_CACHE("/var/run/radio"); +const std::string FMODEL("model"); +const std::string FIMEI("imei"); +const std::string FMEID("meid"); +const std::string FIMSI("imsi"); +const std::string FTYPE("type"); +const std::string FCODE("code"); +const std::string FRSSI("rssi"); +const std::string FFIRMWARE("firmware"); +const std::string FCARRIER("carrier"); +const std::string FMDN("mdn"); +const std::string FICCID("iccid"); + +std::string g_sCache(DEFAULT_CACHE); +std::string g_sModel; +std::string g_sType; +std::string g_sPort(DEFAULT_PORT); +Json::Value g_jData; + +MTS::AutoPtr<MTS::IO::CellularRadio> g_apRadio; + +int32_t g_iOptions = 0; + +const uint32_t OPT_INDIVIDUAL = 0x00FFFFFF; +const uint32_t OPT_SUMMARY = 0x7F000000; +const uint32_t OPT_INITIALIZE = 0x10000000; + +const uint32_t OPT_FIRMWARE = 0x00000001; +const uint32_t OPT_IMEI = 0x00000002; +const uint32_t OPT_IMSI = 0x00000004; +const uint32_t OPT_LAC = 0x00000008; +const uint32_t OPT_MODEL = 0x00000010; +const uint32_t OPT_NETREG = 0x00000020; +const uint32_t OPT_NETWORK = 0x00000040; +const uint32_t OPT_MDN = 0x00000080; +const uint32_t OPT_PHONENUMBER = OPT_MDN; +const uint32_t OPT_RSSI = 0x00000100; +const uint32_t OPT_TOWER = 0x00000200; +const uint32_t OPT_ICCID = 0x00000400; +const uint32_t OPT_SERVICE = 0x00000800; +const uint32_t OPT_TYPE = 0x00001000; +const uint32_t OPT_CARRIER = 0x00002000; +const uint32_t OPT_DATETIME = 0x00004000; + +const uint32_t OPT_SUMMARY_STATIC = 0x01000000; +const uint32_t OPT_SUMMARY_NETWORK = 0x02000000; + +void handle_sigterm(int signum); +void printHelp(const std::string& sApp); +void parseOptions(int argc, char** argv); +void initializeCache(); +void shutdown(); +template<class T> bool writeToCache(const std::string& sFile, const T& tValue); + +Json::Value getStaticData(); +Json::Value getNetworkData(); + +bool g_bIstty = false; + +int main(int argc, char** argv) { + using namespace MTS::IO; + + signal(SIGTERM, handle_sigterm); + signal(SIGINT, handle_sigterm); + + MTS::Logger::setPrintLevel(MTS::Logger::PrintLevel::OFF_LEVEL, true); + + if (isatty(fileno(stdin)) && isatty(fileno(stdout))) + g_bIstty = true; + + //Assuming cache needs to be built + bool bBuildCache = true; + + parseOptions(argc, argv); + + printTrace("istty: %d\n", g_bIstty); + + if(!(g_iOptions & OPT_INITIALIZE)) { + std::ifstream fModel; + fModel.open(g_sCache + "/" + FMODEL); + if(fModel.is_open()) { + std::string sModel; + fModel >> sModel; + fModel.close(); + if(sModel.size() > 0) { + printTrace("Pulling Model from cache: [%s]", sModel.c_str()); + g_sModel = sModel; + } + bBuildCache = false; + } + } + + MTS::IO::CellularRadioFactory factory; + g_apRadio.reset(factory.create(g_sModel, g_sPort)); + + if(g_apRadio.isNull() || !g_apRadio->initialize()) { + printf("Error creating radio interface [%s][%s]\n", g_sPort.c_str(), g_sModel.c_str()); + exit(1); + } + + if((g_iOptions & OPT_INITIALIZE) || bBuildCache) { + initializeCache(); + if(g_iOptions & OPT_INITIALIZE) { + //Initialization was the only purpose + shutdown(); + return 0; + } + } + + CellularRadio::CODE result = CellularRadio::CODE::SUCCESS; + + if(g_iOptions & OPT_SUMMARY_NETWORK) { + printf("%s", getNetworkData().toStyledString().c_str()); + } else if(g_iOptions & OPT_SUMMARY_STATIC) { + printf("%s", getStaticData().toStyledString().c_str()); + } else if(g_iOptions & OPT_RSSI) { + int32_t iValue; + result = g_apRadio->getSignalStrength(iValue); + if(result == CellularRadio::SUCCESS) { + writeToCache(FRSSI, iValue); + printf("%d", iValue); + } + } else if(g_iOptions & OPT_NETREG) { + std::string sValue; + CellularRadio::REGISTRATION eReg; + result = g_apRadio->getRegistration(eReg); + if(result == CellularRadio::SUCCESS) { + result = g_apRadio->convertRegistrationToString(eReg, sValue); + if(result == CellularRadio::SUCCESS) { + printf("%s", sValue.c_str()); + } + } + } else if(g_iOptions & OPT_LAC) { + std::string sValue; + result = g_apRadio->getLac(sValue); + if(result == CellularRadio::SUCCESS) { + printf("%s", sValue.c_str()); + } + } else if(g_iOptions & OPT_TOWER) { + std::string sValue; + result = g_apRadio->getTower(sValue); + if(result == CellularRadio::SUCCESS) { + printf("%s", sValue.c_str()); + } + } else if(g_iOptions & OPT_ICCID) { + std::string sValue; + result = g_apRadio->getIccid(sValue); + if(result == CellularRadio::SUCCESS) { + writeToCache(FICCID, sValue); + printf("%s", sValue.c_str()); + } + } else if(g_iOptions & OPT_SERVICE) { + std::string sValue; + result = g_apRadio->getService(sValue); + if(result == CellularRadio::SUCCESS) { + printf("%s", sValue.c_str()); + } + } else if(g_iOptions & OPT_NETWORK) { + std::string sValue; + result = g_apRadio->getNetwork(sValue); + if(result == CellularRadio::SUCCESS) { + printf("%s", sValue.c_str()); + } + } else if(g_iOptions & OPT_MDN) { + std::string sValue; + result = g_apRadio->getMdn(sValue); + if(result == CellularRadio::SUCCESS) { + writeToCache(FMDN, sValue); + printf("%s", sValue.c_str()); + } + } else if(g_iOptions & OPT_FIRMWARE) { + std::string sValue; + result = g_apRadio->getFirmware(sValue); + if(result == CellularRadio::SUCCESS) { + writeToCache(FFIRMWARE, sValue); + printf("%s", sValue.c_str()); + } + } else if(g_iOptions & OPT_IMEI) { + std::string sValue; + result = g_apRadio->getImei(sValue); + if(result == CellularRadio::SUCCESS) { + printf("%s", sValue.c_str()); + } + } else if(g_iOptions & OPT_IMSI) { + std::string sValue; + result = g_apRadio->getImsi(sValue); + if(result == CellularRadio::SUCCESS) { + printf("%s", sValue.c_str()); + } + } else if(g_iOptions & OPT_MODEL) { + std::string sValue; + result = g_apRadio->getModel(sValue); + if(result == CellularRadio::SUCCESS) { + printf("%s", sValue.c_str()); + } + } else if(g_iOptions & OPT_TYPE) { + std::string sValue; + std::string sType; + result = g_apRadio->getModel(sValue); + if(result == CellularRadio::SUCCESS) { + result = g_apRadio->convertModelToType(sValue, sType); + if(result == CellularRadio::SUCCESS) { + printf("%s", sType.c_str()); + } + } + } else if(g_iOptions & OPT_CARRIER) { + std::string sValue; + result = g_apRadio->getCarrier(sValue); + if(result == CellularRadio::SUCCESS) { + writeToCache(FCARRIER, sValue); + printf("%s", sValue.c_str()); + } + } else if(g_iOptions & OPT_DATETIME) { + std::string sDate, sTime, sZone; + result = g_apRadio->getTime(sDate, sTime, sZone); + if(result == CellularRadio::SUCCESS) { + printf("%s %s GMT%s", sDate.c_str(), sTime.c_str(), sZone.c_str()); + } + } + + if (g_bIstty && result == CellularRadio::CODE::SUCCESS) + printf("\n"); + + shutdown(); + return (result == CellularRadio::CODE::SUCCESS) ? 0 : 1; +} + +void handle_sigterm(int signum) { + if (signum == SIGTERM) { + shutdown(); + } +} + +void shutdown() { + printDebug("Shutting Down"); + if(!g_apRadio.isNull()) { + g_apRadio->shutdown(); + g_apRadio.reset(); + } +} + +void initializeCache() { + if(mkdir(g_sCache.c_str(), 0777) != 0) { + if(errno != EEXIST) { + printf("Error creating cache directory [%s] [%d][%s]\n", g_sCache.c_str(), errno, strerror(errno)); + exit(1); + } + } + + //Gather Static Information + const Json::Value jData = getStaticData(); + + printTrace("Static Data:\n%s\n", jData.toStyledString().c_str()); + + //Save to radio cache directory + std::ofstream ofile; + + ofile.open(g_sCache + "/" + FMODEL); + ofile << jData[MTS::IO::CellularRadio::KEY_MODEL].asString(); + ofile.close(); + + if(g_sType == MTS::IO::CellularRadio::VALUE_TYPE_CDMA) { + ofile.open(g_sCache + "/" + FIMEI); + ofile << jData[MTS::IO::CellularRadio::KEY_MEID].asString(); + ofile.close(); + ofile.open(g_sCache + "/" + FMEID); + ofile << jData[MTS::IO::CellularRadio::KEY_MEID].asString(); + ofile.close(); + } else { + ofile.open(g_sCache + "/" + FIMEI); + ofile << jData[MTS::IO::CellularRadio::KEY_IMEI].asString(); + ofile.close(); + ofile.open(g_sCache + "/" + FMEID); + ofile << jData[MTS::IO::CellularRadio::KEY_IMEI].asString(); + ofile.close(); + } + + ofile.open(g_sCache + "/" + FIMSI); + ofile << jData[MTS::IO::CellularRadio::KEY_IMSI].asString(); + ofile.close(); + + ofile.open(g_sCache + "/" + FTYPE); + ofile << jData[MTS::IO::CellularRadio::KEY_TYPE].asString(); + ofile.close(); + + ofile.open(g_sCache + "/" + FCODE); + ofile << jData[MTS::IO::CellularRadio::KEY_CODE].asString(); + ofile.close(); + + ofile.open(g_sCache + "/" + FFIRMWARE); + ofile << jData[MTS::IO::CellularRadio::KEY_FIRMWARE].asString(); + ofile.close(); + + ofile.open(g_sCache + "/" + FCARRIER); + ofile << jData[MTS::IO::CellularRadio::KEY_CARRIER].asString(); + ofile.close(); +} + +template<class T> +bool writeToCache(const std::string& sFile, const T& tValue) { + + std::ofstream ofile; + ofile.open(g_sCache + "/" + sFile); + if(!ofile.is_open()){ + return false; + } + + std::stringstream ss; + ss << tValue; + + ofile << ss.str(); + ofile.close(); + return true; +} + +Json::Value getStaticData() { + using namespace MTS::IO; + Json::Value jData; + + std::string sImei; + CellularRadio::CODE eCode = g_apRadio->getImei(sImei); + if(eCode != CellularRadio::SUCCESS) { + printWarning("Radio IMEI not found: %s", CellularRadio::getCodeAsString(eCode).c_str()); + } + + if(g_apRadio->getModel(g_sModel) == CellularRadio::SUCCESS) { + jData[CellularRadio::KEY_MODEL] = g_sModel; + } else { + printWarning("Radio model not found"); + } + + if(g_apRadio->convertModelToType(g_sModel, g_sType) == CellularRadio::SUCCESS) { + jData[CellularRadio::KEY_TYPE] = g_sType; + } else { + printWarning("Radio type not supported"); + } + + std::string sCode(CellularRadio::VALUE_UNKNOWN); + if(g_apRadio->convertModelToMtsShortCode(g_sModel, sCode) != CellularRadio::SUCCESS) { + printWarning("Radio MTS short code not supported"); + } + jData[CellularRadio::KEY_CODE] = sCode; + + if(g_sType == CellularRadio::VALUE_TYPE_CDMA) { + jData[CellularRadio::KEY_MEID] = sImei; + } else { + jData[CellularRadio::KEY_IMEI] = sImei; + + std::string sIccid; + if(g_apRadio->getIccid(sIccid) == CellularRadio::SUCCESS) { + jData[CellularRadio::KEY_ICCID] = sIccid; + } + } + + std::string sImsi(CellularRadio::VALUE_UNKNOWN); + if(g_apRadio->getImsi(sImsi) != CellularRadio::SUCCESS) { + printWarning("Radio IMSI not found"); + } + jData[CellularRadio::KEY_IMSI] = sImsi; + + std::string sMsid(CellularRadio::VALUE_UNKNOWN); + if(g_apRadio->getMsid(sMsid) != CellularRadio::SUCCESS) { + printWarning("Radio MSID not found"); + } + jData[CellularRadio::KEY_MSID] = sMsid; + + std::string sFirmware(CellularRadio::VALUE_UNKNOWN); + if(g_apRadio->getFirmware(sFirmware) != CellularRadio::SUCCESS) { + printWarning("Radio Firmware not found"); + } + jData[CellularRadio::KEY_FIRMWARE] = sFirmware; + + std::string sCarrier(CellularRadio::VALUE_UNKNOWN); + if(g_apRadio->getCarrier(sCarrier) != CellularRadio::SUCCESS) { + printWarning("Radio Carrier not found"); + } + jData[CellularRadio::KEY_CARRIER] = sCarrier; + + + std::string sHardware(CellularRadio::VALUE_UNKNOWN); + if(g_apRadio->getHardware(sHardware) != CellularRadio::SUCCESS) { + printWarning("Radio Hardware Version not found"); + } + jData[CellularRadio::KEY_HARDWARE] = sHardware; + + std::string sManufacturer(CellularRadio::VALUE_UNKNOWN); + if(g_apRadio->getManufacturer(sManufacturer) != CellularRadio::SUCCESS) { + printWarning("Radio Manufacturer not found"); + } + jData[CellularRadio::KEY_MANUFACTURER] = sManufacturer; + + std::string sMdn(CellularRadio::VALUE_UNKNOWN); + if(g_apRadio->getMdn(sMdn) == CellularRadio::SUCCESS) { + //CDMA Provisioned Flag + if(g_sType == CellularRadio::VALUE_TYPE_CDMA) { + if(sMdn.size() == 0 || sMdn.find("000000") != std::string::npos) { + jData["provisioned"] = false; + } else { + jData["provisioned"] = true; + } + } + } else { + printWarning("Radio MDN not found"); + } + jData[CellularRadio::KEY_MDN] = sMdn; + + Json::Value jMip; + if(g_apRadio->getMipProfile(jMip) == MTS::IO::CellularRadio::SUCCESS) { + jData[MTS::IO::CellularRadio::KEY_MIP] = jMip; + } + + return jData; +} + +Json::Value getNetworkData() { + Json::Value jData; + g_apRadio->getNetworkStatus(jData); + return jData; +} + +void parseOptions(int argc, char** argv) { + int c; + int iOption; + std::string sPath; + + if(argc == 1) { + printHelp(argv[0]); + exit(0); + } + + while (1) { + static struct option long_options[] = + { { "help", no_argument, 0, '?' }, + { "version", no_argument, 0, 'v' }, + { "device", required_argument, 0, 'd' }, + { "printlvl", required_argument, 0, 'p' }, + { "init", optional_argument, 0, 'i' }, + { "cachedir", required_argument, 0, 'c' }, + { "firmware", no_argument, &iOption, OPT_FIRMWARE }, + { "imei", no_argument, &iOption, OPT_IMEI }, + { "imsi", no_argument, &iOption, OPT_IMSI }, + { "lac", no_argument, &iOption, OPT_LAC }, + { "model", no_argument, &iOption, OPT_MODEL }, + { "netreg", no_argument, &iOption, OPT_NETREG }, + { "network", no_argument, &iOption, OPT_NETWORK }, + { "phonenumber", no_argument, &iOption, OPT_PHONENUMBER }, + { "mdn", no_argument, &iOption, OPT_MDN }, + { "rssi", no_argument, &iOption, OPT_RSSI }, + { "tower", no_argument, &iOption, OPT_TOWER }, + { "iccid", no_argument, &iOption, OPT_ICCID }, + { "service", no_argument, &iOption, OPT_SERVICE }, + { "type", no_argument, &iOption, OPT_TYPE }, + { "carrier", no_argument, &iOption, OPT_CARRIER }, + { "datetime", no_argument, &iOption, OPT_DATETIME }, + { "static", no_argument, &iOption, OPT_SUMMARY_STATIC }, + { "dynamic", no_argument, &iOption, OPT_SUMMARY_NETWORK }, + { 0, 0, 0, 0 } }; + + /* getopt_long stores the option index here. */ + int option_index = 0; + + c = getopt_long(argc, argv, "d:p:ic:?v", long_options, &option_index); + + /* Detect the end of the options. */ + if (c == -1) { + break; + } + + if(c == 0) { + g_iOptions |= iOption; + continue; + } + + switch (c) { + + case '?': + printHelp(argv[0]); + exit(0); + break; + + case 'v': + printf("Version: %s\n", Version::version.c_str()); + exit(0); + break; + + case 'p': + int iPrintLvl; + if(MTS::Text::parse(iPrintLvl, optarg) && iPrintLvl >= 0 && iPrintLvl <= 100) { + MTS::Logger::setPrintLevel(iPrintLvl); + } else { + printf("print level out of range [0-100]\n"); + exit(1); + } + break; + + case 'i': + if(optarg != 0) { + g_sModel = optarg; + } + g_iOptions |= OPT_INITIALIZE; + break; + + case 'c': + if(optarg != 0) { + g_sCache = optarg; + } + break; + + case 'd': + if(optarg != 0) { + g_sPort = optarg; + } + break; + + default: + printf("OPTION: [%d] ABORTING!!\n", c); + abort(); + break; + } + } + + printTrace("OPTS: %08X\n", g_iOptions); + + /* Print any remaining command line arguments (not options). */ + if (optind < argc) { + fprintf(stderr, "non-option ARGV-elements: \n"); + while (optind < argc) + fprintf(stderr, "%s ", argv[optind++]); + fprintf(stderr, "\n"); + } +} + +void printHelp(const std::string& sApp) { + printf("Usage: %s <opt1> <opt2> ...\n", sApp.c_str()); + printf("\tSimple utility to pull info from supported radios in a consistent manner\n"); + printf("\t--init (i) : initializes the utility for all future calls\n"); + printf("\t--device (d) <device> : specify modem device to query, default: /dev/modem_at1\n"); + printf("\t--printlvl (p) <level> : sets the printlvl [0-100]\n"); + printf("\t--help (?) : returns this message\n"); + printf("\t--version (v) : returns version\n"); + printf("\n"); + printf("\tQueries:\n"); + printf("\t--firmware\n"); + printf("\t--imei\n"); + printf("\t--imsi\n"); + printf("\t--lac\n"); + printf("\t--model\n"); + printf("\t--netreg\n"); + printf("\t--network\n"); + printf("\t--phonenumber\n"); + printf("\t--mdn\n"); + printf("\t--rssi\n"); + printf("\t--tower\n"); + printf("\t--iccid\n"); + printf("\t--service\n"); + printf("\t--type\n"); + printf("\t--carrier\n"); + printf("\t--datetime\n"); + printf("\n"); + printf("\tSupported Radios:\n"); + printf("\t\tHE910, GE910, DE910, CE910\n"); +} |