summaryrefslogtreecommitdiff
path: root/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main.cpp')
-rw-r--r--main.cpp597
1 files changed, 597 insertions, 0 deletions
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..56c9c61
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,597 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of radio-cmd.
+ *
+ * radio-cmd 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-cmd 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-cmd. 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 <stdlib.h>
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include <signal.h>
+#include "Version.h"
+
+const std::string DEFAULT_PORT("/dev/modem_at1");
+const int32_t DEFAULT_TIMEOUT = 100;
+const std::string DEFAULT_COMMAND("AT");
+const std::string DEFAULT_CACHE("/var/run/radio");
+const std::string FMODEL("model");
+const std::string FMSL("msl");
+
+std::string g_sTimeout;
+std::string g_sDevice(DEFAULT_PORT);
+std::string g_sAtCommand(DEFAULT_COMMAND);
+std::string g_sCache(DEFAULT_CACHE);
+std::string g_sModel;
+
+std::string g_sMDN;
+std::string g_sMSID;
+std::string g_sMSL;
+std::string g_sMIPActiveProfile;
+std::string g_sMIPNai;
+std::string g_sMIPHomeAddr;
+std::string g_sMIPPrimaryHa;
+std::string g_sMIPSecondaryHa;
+std::string g_sMIPMnAaaSpi;
+std::string g_sMIPMnHaSpi;
+std::string g_sMIPRevTun;
+std::string g_sMIPMnAaaSs;
+std::string g_sMIPMnHaSs;
+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_TIMEOUT = 0x00000001;
+const uint32_t OPT_DEVICE = 0x00000002;
+const uint32_t OPT_COMMAND = 0x00000004;
+const uint32_t OPT_MSL = 0x00000008;
+const uint32_t OPT_SETMDN = 0x00000010;
+const uint32_t OPT_SETMSID = 0x00000020;
+const uint32_t OPT_SETMSL = 0x00000040;
+const uint32_t OPT_SETMIPACTIVEPROFILE = 0x00000080;
+const uint32_t OPT_SETMIPNAI = 0x00000100;
+const uint32_t OPT_SETMIPHOMEADDR = 0x00000200;
+const uint32_t OPT_SETMIPPRIMARYHA = 0x00000400;
+const uint32_t OPT_SETMIPSECONDARYHA = 0x00000800;
+const uint32_t OPT_SETMIPMNAAASPI = 0x00001000;
+const uint32_t OPT_SETMIPMNHASPI = 0x00002000;
+const uint32_t OPT_SETMIPREVTUN = 0x00004000;
+const uint32_t OPT_SETMIPMNAAASS = 0x00008000;
+const uint32_t OPT_SETMIPMNHASS = 0x00010000;
+const uint32_t OPT_INIT_DC = 0x00020000;
+const uint32_t OPT_INIT_FUMO = 0x00040000;
+const uint32_t OPT_INIT_PRL = 0x00080000;
+const uint32_t OPT_INIT_RTN = 0x00100000;
+const uint32_t OPT_INIT_ACTIVATION = 0x00200000;
+const uint32_t OPT_MDN = 0x00400000;
+const uint32_t OPT_MSID = 0x00800000;
+
+void handle_sigterm(int signum);
+void printHelp(const std::string& sApp);
+void parseOptions(int argc, char** argv);
+void initializeCache();
+void shutdown();
+const char *code2str(MTS::IO::CellularRadio::CODE code);
+std::string loadImeiFromDeviceInfo();
+
+Json::Value getStaticData();
+Json::Value getNetworkData();
+
+MTS::IO::CellularRadio::UpdateCb cb = [](const Json::Value& s)->void {
+ if(s.isString()) {
+ printf("%s\n", s.asCString());
+ }
+};
+
+int main(int argc, char** argv) {
+ using namespace MTS::IO;
+
+ //Disable stdout buffering so this process can pipe out data as needed
+ // * otherwise entire stdout is buffered until process is closed using popen
+ setbuf(stdout, NULL);
+
+ signal(SIGTERM, handle_sigterm);
+ signal(SIGINT, handle_sigterm);
+
+ MTS::Logger::setPrintLevel(MTS::Logger::PrintLevel::OFF_LEVEL, true);
+
+ parseOptions(argc, argv);
+
+ if(!(g_iOptions & OPT_INITIALIZE)) {
+ // get model from cache
+ std::ifstream fModel((g_sCache + "/" + FMODEL).c_str());
+ if(fModel.is_open()) {
+ std::string sModel;
+ fModel >> sModel;
+ if(sModel.size() > 0) {
+ printTrace("Pulling Model from cache: [%s]", sModel.c_str());
+ g_sModel = sModel;
+ }
+ }
+ // get msl from cache
+ std::ifstream fMSL((g_sCache + "/" + FMSL).c_str());
+ if(fMSL.is_open()) {
+ std::string sMSL;
+ fMSL >> sMSL;
+ if(sMSL.size() > 0) {
+ printTrace("Pulling Msl from cache: [%s]", sMSL.c_str());
+ g_sMSL = sMSL;
+ g_iOptions |= OPT_MSL;
+ }
+ }
+ }
+
+ MTS::IO::CellularRadioFactory factory;
+ g_apRadio.reset(factory.create(g_sModel, g_sDevice));
+
+ if(g_apRadio.isNull() || !g_apRadio->initialize()) {
+ printf("Error creating radio interface [%s][%s]\n", g_sDevice.c_str(), g_sModel.c_str());
+ return EXIT_FAILURE;
+ }
+
+ CellularRadio::CODE result = CellularRadio::CODE::SUCCESS;
+
+ if(g_iOptions & OPT_COMMAND) {
+ int32_t timeoutMillis = DEFAULT_TIMEOUT;
+ if(g_iOptions & OPT_TIMEOUT) {
+ timeoutMillis = atoi(g_sTimeout.c_str());
+ if(!timeoutMillis) {
+ printError("Timeout: invalid, use default timeout\n");
+ timeoutMillis = DEFAULT_TIMEOUT;
+ }
+ }
+ printDebug("AT Command: %s\n", g_sAtCommand.c_str());
+ std::string sResult = g_apRadio->sendCommand(g_sAtCommand, MTS::IO::CellularRadio::DEFAULT_BAIL_STRINGS, timeoutMillis);
+ printDebug("RESULT: %s\n", sResult.c_str());
+ // skip first line
+ std::size_t pos = sResult.find('\n');
+ if(pos == std::string::npos) {
+ pos = 0;
+ } else {
+ ++pos;
+ }
+ printf("%s", sResult.substr(pos).c_str());
+ } else if(g_iOptions & OPT_SETMDN) {
+ Json::Value jArgs(Json::objectValue);
+ printDebug("SET MDN: %s\n", g_sMDN.c_str());
+ jArgs["mdn"] = g_sMDN;
+ if(g_iOptions & OPT_MSL) {
+ printDebug("MSL: %s\n", g_sMSL.c_str());
+ jArgs["msl"] = g_sMSL;
+ }
+ result = g_apRadio->setMdn(jArgs);
+ printf("%s\n", code2str(result));
+ } else if(g_iOptions & OPT_SETMSID) {
+ Json::Value jArgs(Json::objectValue);
+ printDebug("SET MSID: %s\n", g_sMSID.c_str());
+ jArgs["msid"] = g_sMSID;
+ if(g_iOptions & OPT_MSL) {
+ printDebug("MSL: %s\n", g_sMSL.c_str());
+ jArgs["msl"] = g_sMSL;
+ }
+ result = g_apRadio->setMsid(jArgs);
+ printf("%s\n", code2str(result));
+ } else if(g_iOptions & OPT_SETMIPACTIVEPROFILE) {
+ Json::Value jArgs(Json::objectValue);
+ printDebug("SET MIP ACTIVE PROFILE: %s\n", g_sMIPActiveProfile.c_str());
+ jArgs["activeProfile"] = g_sMIPActiveProfile;
+ result = g_apRadio->setMipActiveProfile(jArgs);
+ printf("%s\n", code2str(result));
+ } else if(g_iOptions & OPT_SETMIPNAI) {
+ Json::Value jArgs(Json::objectValue);
+ printDebug("SET MIP NAI: %s\n", g_sMIPNai.c_str());
+ jArgs["nai"] = g_sMIPNai;
+ result = g_apRadio->setMipNai(jArgs);
+ printf("%s\n", code2str(result));
+ } else if(g_iOptions & OPT_SETMIPHOMEADDR) {
+ Json::Value jArgs(Json::objectValue);
+ printDebug("SET MIP HOME ADDR: %s\n", g_sMIPHomeAddr.c_str());
+ jArgs["homeIp"] = g_sMIPHomeAddr;
+ result = g_apRadio->setMipHomeIp(jArgs);
+ printf("%s\n", code2str(result));
+ } else if(g_iOptions & OPT_SETMIPPRIMARYHA) {
+ Json::Value jArgs(Json::objectValue);
+ printDebug("SET MIP PRIMARY HA: %s\n", g_sMIPPrimaryHa.c_str());
+ jArgs["primaryHa"] = g_sMIPPrimaryHa;
+ result = g_apRadio->setMipPrimaryHa(jArgs);
+ printf("%s\n", code2str(result));
+ } else if(g_iOptions & OPT_SETMIPSECONDARYHA) {
+ Json::Value jArgs(Json::objectValue);
+ printDebug("SET MIP SECONDARY HA: %s\n", g_sMIPSecondaryHa.c_str());
+ jArgs["secondaryHa"] = g_sMIPSecondaryHa;
+ result = g_apRadio->setMipSecondaryHa(jArgs);
+ printf("%s\n", code2str(result));
+ } else if(g_iOptions & OPT_SETMIPMNAAASPI) {
+ Json::Value jArgs(Json::objectValue);
+ printDebug("SET MIP MN-AAA SPI: %s\n", g_sMIPMnAaaSpi.c_str());
+ jArgs["mnAaaSpi"] = g_sMIPMnAaaSpi;
+ result = g_apRadio->setMipMnAaaSpi(jArgs);
+ printf("%s\n", code2str(result));
+ } else if(g_iOptions & OPT_SETMIPMNHASPI) {
+ Json::Value jArgs(Json::objectValue);
+ printDebug("SET MIP MN-HA SPI: %s\n", g_sMIPMnHaSpi.c_str());
+ jArgs["mnHaSpi"] = g_sMIPMnHaSpi;
+ result = g_apRadio->setMipMnHaSpi(jArgs);
+ printf("%s\n", code2str(result));
+ } else if(g_iOptions & OPT_SETMIPREVTUN) {
+ Json::Value jArgs(Json::objectValue);
+ printDebug("SET MIP REV TUN: %s\n", g_sMIPRevTun.c_str());
+ jArgs["revTun"] = g_sMIPRevTun;
+ result = g_apRadio->setMipRevTun(jArgs);
+ printf("%s\n", code2str(result));
+ } else if(g_iOptions & OPT_SETMIPMNAAASS) {
+ Json::Value jArgs(Json::objectValue);
+ printDebug("SET MIP MN-AAA SS: %s\n", g_sMIPMnAaaSs.c_str());
+ jArgs["mnAaaSs"] = g_sMIPMnAaaSs;
+ result = g_apRadio->setMipMnAaaSs(jArgs);
+ printf("%s\n", code2str(result));
+ } else if(g_iOptions & OPT_SETMIPMNHASS) {
+ Json::Value jArgs(Json::objectValue);
+ printDebug("SET MIP MN-HA SS: %s\n", g_sMIPMnHaSs.c_str());
+ jArgs["mnHaSs"] = g_sMIPMnHaSs;
+ result = g_apRadio->setMipMnHaSs(jArgs);
+ printf("%s\n", code2str(result));
+ } else if(g_iOptions & OPT_SETMSL) {
+ Json::Value jArgs(Json::objectValue);
+ jArgs["msl"] = g_sMSL;
+ result = g_apRadio->validateMsl(jArgs);
+ if(result == MTS::IO::CellularRadio::CODE::SUCCESS) {
+ std::ofstream fMSL((g_sCache + "/" + FMSL).c_str(), std::ios_base::trunc | std::ios_base::out);
+ if(fMSL.is_open()) {
+ std::string sMSL;
+ fMSL << g_sMSL;
+ }
+ }
+ printf("%s\n", code2str(result));
+ } else if(g_iOptions & OPT_INIT_DC) {
+ Json::Value jArgs(Json::nullValue);
+ result = g_apRadio->updateDc(jArgs, cb);
+ printf("%s\n", code2str(result));
+ } else if(g_iOptions & OPT_INIT_PRL) {
+ Json::Value jArgs(Json::nullValue);
+ result = g_apRadio->updatePrl(jArgs, cb);
+ printf("%s\n", code2str(result));
+ } else if(g_iOptions & OPT_INIT_FUMO) {
+ Json::Value jArgs(Json::nullValue);
+ result = g_apRadio->updateFumo(jArgs, cb);
+ printf("%s\n", code2str(result));
+ } else if(g_iOptions & OPT_INIT_RTN) {
+ Json::Value jArgs(Json::objectValue);
+ if(g_iOptions & OPT_MSL) {
+ printDebug("MSL: %s\n", g_sMSL.c_str());
+ jArgs["msl"] = g_sMSL;
+ }
+ result = g_apRadio->resetHfa(jArgs, cb);
+ printf("%s\n", code2str(result));
+ } else if(g_iOptions & OPT_INIT_ACTIVATION) {
+ Json::Value jArgs(Json::objectValue);
+ if(g_iOptions & OPT_MSID) {
+ printDebug("MSID: %s", g_sMSID.c_str());
+ jArgs["msid"] = g_sMSID;
+ }
+ if(g_iOptions & OPT_MDN) {
+ printDebug("MDN: %s", g_sMDN.c_str());
+ jArgs["mdn"] = g_sMDN;
+ }
+ result = g_apRadio->activate(jArgs, cb);
+ printf("%s\n", code2str(result));
+ }
+
+ 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();
+ }
+}
+
+void parseOptions(int argc, char** argv) {
+ int c;
+ int iOption = 0;
+
+ if(argc == 1) {
+ printHelp(argv[0]);
+ exit(0);
+ }
+
+ while (1) {
+ static struct option long_options[] =
+ { { "help", no_argument, 0, '?' },
+ { "version", no_argument, 0, 'v' },
+ { "printlvl", required_argument, 0, 'p' },
+ { "device", required_argument, 0, 'd' },
+ { "set-mdn", required_argument, 0, 'n' },
+ { "set-msl", required_argument, 0, 'm' },
+ { "set-msid", required_argument, 0, 's' },
+ { "msl", required_argument, 0, 'l' },
+ { "mdn", required_argument, 0, 'k' },
+ { "msid", required_argument, 0, 'j' },
+ { "set-mip-active-profile", required_argument, 0, '0' },
+ { "set-mip-nai", required_argument, 0, '1' },
+ { "set-mip-home-ip", required_argument, 0, '2' },
+ { "set-mip-primary-ha", required_argument, 0, '3' },
+ { "set-mip-secondary-ha", required_argument, 0, '4' },
+ { "set-mip-mn-aaa-spi", required_argument, 0, '5' },
+ { "set-mip-mn-ha-spi", required_argument, 0, '6' },
+ { "set-mip-rev-tun", required_argument, 0, '7' },
+ { "set-mip-mn-aaa-ss", required_argument, 0, '8' },
+ { "set-mip-mn-ha-ss", required_argument, 0, '9' },
+ { "init-dc", no_argument, &iOption, OPT_INIT_DC },
+ { "init-fumo", no_argument, &iOption, OPT_INIT_FUMO },
+ { "init-prl", no_argument, &iOption, OPT_INIT_PRL },
+ { "init-activation", no_argument, &iOption, OPT_INIT_ACTIVATION },
+ { "factory-default", no_argument, &iOption, OPT_INIT_RTN },
+ { 0, 0, 0, 0 } };
+
+ /* getopt_long stores the option index here. */
+ int option_index = 0;
+
+ c = getopt_long(argc, argv, "t:d:p:?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 't':
+ if(optarg != 0) {
+ g_sTimeout = optarg;
+ }
+ g_iOptions |= OPT_TIMEOUT;
+ break;
+
+ case 'd':
+ if(optarg != 0) {
+ g_sDevice = optarg;
+ }
+ g_iOptions |= OPT_DEVICE;
+ break;
+
+ case 'n':
+ if(optarg != 0) {
+ g_sMDN = optarg;
+ }
+ g_iOptions |= OPT_SETMDN;
+ break;
+
+ case 's':
+ if(optarg != 0) {
+ g_sMSID = optarg;
+ }
+ g_iOptions |= OPT_SETMSID;
+ break;
+
+ case 'm':
+ if(optarg != 0) {
+ g_sMSL = optarg;
+ }
+ g_iOptions |= OPT_SETMSL;
+ break;
+
+ case 'l':
+ if(optarg != 0) {
+ g_sMSL = optarg;
+ }
+ g_iOptions |= OPT_MSL;
+ break;
+
+ case 'k':
+ if(optarg != 0) {
+ g_sMDN = optarg;
+ }
+ g_iOptions |= OPT_MDN;
+ break;
+ case 'j':
+ if(optarg != 0) {
+ g_sMSID = optarg;
+ }
+ g_iOptions |= OPT_MSID;
+ break;
+ case '0':
+ if(optarg != 0) {
+ g_sMIPActiveProfile = optarg;
+ }
+ g_iOptions |= OPT_SETMIPACTIVEPROFILE;
+ break;
+
+ case '1':
+ if(optarg != 0) {
+ g_sMIPNai = optarg;
+ }
+ g_iOptions |= OPT_SETMIPNAI;
+ break;
+
+ case '2':
+ if(optarg != 0) {
+ g_sMIPHomeAddr = optarg;
+ }
+ g_iOptions |= OPT_SETMIPHOMEADDR;
+ break;
+
+ case '3':
+ if(optarg != 0) {
+ g_sMIPPrimaryHa = optarg;
+ }
+ g_iOptions |= OPT_SETMIPPRIMARYHA;
+ break;
+
+ case '4':
+ if(optarg != 0) {
+ g_sMIPSecondaryHa = optarg;
+ }
+ g_iOptions |= OPT_SETMIPSECONDARYHA;
+ break;
+
+ case '5':
+ if(optarg != 0) {
+ g_sMIPMnAaaSpi = optarg;
+ }
+ g_iOptions |= OPT_SETMIPMNAAASPI;
+ break;
+
+ case '6':
+ if(optarg != 0) {
+ g_sMIPMnHaSpi = optarg;
+ }
+ g_iOptions |= OPT_SETMIPMNHASPI;
+ break;
+
+ case '7':
+ if(optarg != 0) {
+ g_sMIPRevTun = optarg;
+ }
+ g_iOptions |= OPT_SETMIPREVTUN;
+ break;
+
+ case '8':
+ if(optarg != 0) {
+ g_sMIPMnAaaSs = optarg;
+ }
+ g_iOptions |= OPT_SETMIPMNAAASS;
+ break;
+
+ case '9':
+ if(optarg != 0) {
+ g_sMIPMnHaSs = optarg;
+ }
+ g_iOptions |= OPT_SETMIPMNHASS;
+ break;
+
+ default:
+ printf("OPTION: [%d] ABORTING!!\n", c);
+ abort();
+ break;
+ }
+ }
+
+ if((g_iOptions & (OPT_TIMEOUT | OPT_DEVICE)) || !g_iOptions) {
+ /* Assume that any remaining command line arguments is AT Command */
+ if(optind < argc) {
+ g_sAtCommand = argv[optind];
+ g_iOptions |= OPT_COMMAND;
+ }
+ }
+
+ printDebug("OPTS: %08X\n", g_iOptions);
+
+}
+
+void printHelp(const std::string& sApp) {
+ printf("Usage: %s [OPTION] [<AT_COMMAND>] ...\n", sApp.c_str());
+ printf("\tSimple utility to send either general AT command or predefined specific command to radio module\n");
+ printf("\t<AT_COMMAND> [ -t <TIMEOUT> -d <DEVICE> ] : send AT command. Timeout and device are optional\n");
+ printf("\t--device (d) <device> : modem device to use, default: /dev/modem_at1\n");
+ printf("\t--init-dc : initiate device configuration update\n");
+ printf("\t--init-fumo : initiate module/modem firmware update\n");
+ printf("\t--init-prl : initiate PRL update\n");
+ printf("\t--init-activation [ --msid <MSID> --mdn <MDN>]\n");
+ printf("\t : initiate account activation. Some carriers require MDN and MSID\n");
+ printf("\n");
+ printf("\t--set-mdn <MDN> [ --msl <MSL> ] : set MDN value. Some carriers require MSL\n");
+ printf("\t--set-msid <MSID> [ --msl <MSL> ] : set MSID value. Some carriers require MSL\n");
+ printf("\t--set-msl <MSL> : validate and save Master Subsidy Lock (MSL) in cache\n");
+ printf("\t--set-mip-active-profile <VAL> : set active MIP profile\n");
+ printf("\t--set-mip-nai <VAL> : set MIP Network Access Identifier\n");
+ printf("\t--set-mip-home-ip <VAL> : set MIP Home Address\n");
+ printf("\t--set-mip-primary-ha <VAL> : set MIP Primary Home Agent\n");
+ printf("\t--set-mip-secondary-ha <VAL> : set MIP Secondary Home Agent\n");
+ printf("\t--set-mip-mn-aaa-spi <VAL> : set MIP MN AAA SPI\n");
+ printf("\t--set-mip-mn-ha-spi <VAL> : set MIP MN HA SPI\n");
+ printf("\t--set-mip-rev-tun <VAL> : set MIP Reverse Tunneling\n");
+ printf("\t--set-mip-mn-aaa-ss <VAL> : set MIP MN AAA SS\n");
+ printf("\t--set-mip-mn-ha-ss <VAL> : set MIP MN HA SS\n");
+ printf("\t--factory-default [ --msl <MSL> ] : reset to factory defaults\n");
+ printf("\n");
+ printf("\t--printlvl (p) <level> : sets the printlvl [0-100]\n");
+ printf("\t--version (v) : returns version\n");
+ printf("\t--help (?) : returns this message\n");
+ printf("\n");
+ printf("\tSupported Radios:\n");
+ printf("\t\tHE910, GE910, DE910, CE910\n");
+}
+
+const char *code2str(MTS::IO::CellularRadio::CODE code) {
+ switch (code) {
+ case MTS::IO::CellularRadio::CODE::SUCCESS:
+ return "Success";
+ case MTS::IO::CellularRadio::CODE::ERROR:
+ return "Error";
+ case MTS::IO::CellularRadio::CODE::FAILURE:
+ return "Failure";
+ case MTS::IO::CellularRadio::CODE::NO_RESPONSE:
+ return "No Response";
+ case MTS::IO::CellularRadio::CODE::NOT_APPLICABLE:
+ return "Not Applicable";
+ case MTS::IO::CellularRadio::CODE::INVALID_ARGS:
+ return "Invalid Arguments";
+ }
+ return "Unknown";
+}