summaryrefslogtreecommitdiff
path: root/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main.cpp')
-rw-r--r--main.cpp601
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");
+}