/* * 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 . * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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; std::string g_sRxDiversity; std::string g_sActiveFirmware; std::string g_sConfigFile; Json::Value g_jData; std::string g_sSimPin; std::string g_sCellularMode; std::string g_sDeltaFwPath; MTS::AutoPtr g_apRadio; int32_t g_iOptions = 0; const uint32_t OPT_INDIVIDUAL = 0x01FFFFFF; const uint32_t OPT_SUMMARY = 0x7E000000; const uint32_t OPT_INITIALIZE = 0x80000000; 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; const uint32_t OPT_SETRXDIVERSITY = 0x01000000; const uint32_t OPT_SETACTIVEFIRMWARE = 0x02000000; const uint32_t OPT_CONFIG_FILE = 0x04000000; const uint32_t OPT_SET_CELLULAR_MODE = 0x08000000; const uint32_t OPT_UNLOCK_SIM_CARD = 0x20000000; const uint32_t OPT_RESET_RADIO = 0x40000000; int32_t g_iAuxOptions = 0; const uint32_t AOPT_DFU_UPLOAD = 0x00000001; 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::ICellularRadio::CODE code); std::string loadImeiFromDeviceInfo(); MTS::IO::ICellularRadio::CELLULAR_MODES cellularModeFlags(const std::string networks); static int iOption = 0; static struct option long_options[] = { { "help", no_argument, 0, '?' }, { "version", no_argument, 0, 'v' }, { "printlvl", required_argument, 0, 'p' }, { "device", required_argument, 0, 'd' }, { "config-file", required_argument, 0, 'c' }, { "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-active-firmware" , required_argument, 0, 'f' }, { "set-rx-diversity", required_argument, 0, 'r' }, { "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' }, { "unlock-sim-card", required_argument, 0, OPT_UNLOCK_SIM_CARD }, { "reset-radio", no_argument, &iOption, OPT_RESET_RADIO }, { "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 }, { "set-cellular-mode", required_argument, 0, 'w' }, { "delta-fwu-upload", required_argument, 0, 'x' }, { 0, 0, 0, 0 } }; Json::Value getStaticData(); Json::Value getNetworkData(); MTS::IO::ICellularRadio::CODE handleDeltaFwUpload(const std::string& sPath); MTS::IO::ICellularRadio::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; } ICellularRadio::CODE result = ICellularRadio::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::ICellularRadio::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::ICellularRadio::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::objectValue); if(g_iOptions & OPT_CONFIG_FILE) { jArgs["config-file"] = g_sConfigFile; } 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)); } else if(g_iOptions & OPT_SETRXDIVERSITY) { Json::Value jArgs(Json::objectValue); jArgs["enabled"] = g_sRxDiversity; result = g_apRadio->setRxDiversity(jArgs); printf("%s\n", code2str(result)); } else if(g_iOptions & OPT_SETACTIVEFIRMWARE) { Json::Value jArgs(Json::objectValue); jArgs["fwid"] = g_sActiveFirmware; result = g_apRadio->setActiveFirmware(jArgs); printf("%s\n", code2str(result)); } else if(g_iOptions & OPT_UNLOCK_SIM_CARD) { Json::Value jArgs(Json::objectValue); jArgs["pin"] = g_sSimPin; result = g_apRadio->unlockSimCard(jArgs); printf("%s\n", code2str(result)); } else if(g_iOptions & OPT_RESET_RADIO) { bool ret = g_apRadio->resetRadio(); result = (ret) ? ICellularRadio::CODE::SUCCESS : ICellularRadio::CODE::FAILURE; printf("%s\n", code2str(result)); } else if(g_iOptions & OPT_SET_CELLULAR_MODE) { ICellularRadio::CELLULAR_MODES networks = cellularModeFlags(g_sCellularMode); if (networks != ICellularRadio::CELLULAR_MODE_NA) { result = g_apRadio->setCellularMode(networks); printf("%s\n", code2str(result)); } else { printf("Invalid argument: %s\n", g_sCellularMode.c_str()); } } else if (g_iAuxOptions & AOPT_DFU_UPLOAD) { result = handleDeltaFwUpload(g_sDeltaFwPath); } shutdown(); return (result == ICellularRadio::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) { if(argc == 1) { printHelp(argv[0]); exit(0); } while (true) { int c = getopt_long(argc, argv, "t:d:p:r:?v", long_options, nullptr); /* 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 'r': if(optarg != 0) { g_sRxDiversity = optarg; } g_iOptions |= OPT_SETRXDIVERSITY; break; case 'f': if(optarg != 0) { g_sActiveFirmware = optarg; } g_iOptions |= OPT_SETACTIVEFIRMWARE; 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 'c': if(optarg != 0) { g_sConfigFile = optarg; } g_iOptions |= OPT_CONFIG_FILE; 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; case OPT_UNLOCK_SIM_CARD: if(optarg != 0) { g_sSimPin = optarg; } g_iOptions |= OPT_UNLOCK_SIM_CARD; break; case 'w': if (optarg) g_sCellularMode = optarg; g_iOptions |= OPT_SET_CELLULAR_MODE; break; case 'x': if (optarg) g_sDeltaFwPath = optarg; g_iAuxOptions |= AOPT_DFU_UPLOAD; 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] [] ...\n", sApp.c_str()); printf("\tSimple utility to send either general AT command or predefined specific command to radio module\n"); printf("\t [ -t -d ] : send AT command. Timeout and device are optional\n"); printf("\t--device (d) : modem device to use, default: /dev/modem_at1\n"); printf("\t--init-dc : initiate device configuration update\n"); printf("\t--init-fumo [ --config-file ] : initiate module/modem firmware update\n"); printf("\t--init-prl : initiate PRL update\n"); printf("\t--init-activation [ --msid --mdn ]\n"); printf("\t : initiate account activation. Some carriers require MDN and MSID\n"); printf("\n"); printf("\t--set-mdn [ --msl ] : set MDN value. Some carriers require MSL\n"); printf("\t--set-msid [ --msl ] : set MSID value. Some carriers require MSL\n"); printf("\t--set-msl : validate and save Master Subsidy Lock (MSL) in cache\n"); printf("\t--set-mip-active-profile : set active MIP profile\n"); printf("\t--set-mip-nai : set MIP Network Access Identifier\n"); printf("\t--set-mip-home-ip : set MIP Home Address\n"); printf("\t--set-mip-primary-ha : set MIP Primary Home Agent\n"); printf("\t--set-mip-secondary-ha : set MIP Secondary Home Agent\n"); printf("\t--set-mip-mn-aaa-spi : set MIP MN AAA SPI\n"); printf("\t--set-mip-mn-ha-spi : set MIP MN HA SPI\n"); printf("\t--set-mip-rev-tun : set MIP Reverse Tunneling\n"); printf("\t--set-mip-mn-aaa-ss : set MIP MN AAA SS\n"); printf("\t--set-mip-mn-ha-ss : set MIP MN HA SS\n"); printf("\t--set-rx-diversity : set RX Diversity\n"); printf("\t--set-cellular-mode : set preferred networks eg. 2g,3g,4g\n"); // Applicable for LTE910-NA1 dual FW images only // printf("\t--set-active-firmware : switch to a specific firmware image\n"); printf("\t--factory-default [ --msl ] : reset to factory defaults\n"); printf("\t--unlock-sim-card : unlock the SIM card using the PIN code provided\n"); printf("\t--reset-radio : reset the radio module using AT commands\n"); printf("\t--delta-fwu-upload : upload a delta radio FWU file to the radio\n"); printf("\n"); printf("\t--printlvl (p) : 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\tLE910, HE910, GE910, DE910, CE910, ME910, EG95\n"); } const char *code2str(MTS::IO::ICellularRadio::CODE code) { switch (code) { case MTS::IO::ICellularRadio::CODE::SUCCESS: return "Success"; case MTS::IO::ICellularRadio::CODE::ERROR: return "Error"; case MTS::IO::ICellularRadio::CODE::FAILURE: return "Failure"; case MTS::IO::ICellularRadio::CODE::NO_RESPONSE: return "No Response"; case MTS::IO::ICellularRadio::CODE::NOT_APPLICABLE: return "Not Applicable"; case MTS::IO::ICellularRadio::CODE::INVALID_ARGS: return "Invalid Arguments"; } return "Unknown"; } MTS::IO::ICellularRadio::CELLULAR_MODES cellularModeFlags(const std::string networks) { using namespace MTS::IO; int result = ICellularRadio::CELLULAR_MODE_NA; const std::vector &items = MTS::Text::split(networks, ","); for (const auto &it: items) { if (it == "2g") { result |= ICellularRadio::CELLULAR_MODE_2G; } else if (it == "3g") { result |= ICellularRadio::CELLULAR_MODE_3G; } else if (it == "4g") { result |= ICellularRadio::CELLULAR_MODE_4G; } else if (it == "5g") { result |= ICellularRadio::CELLULAR_MODE_5G; } else { result = ICellularRadio::CELLULAR_MODE_NA; break; } } return static_cast(result); } MTS::IO::ICellularRadio::CODE handleDeltaFwUpload(const std::string& sPath) { int fd = open(sPath.c_str(), O_RDONLY); if (fd < 0) { printf("Failed to open file [%s]: %d\n", sPath.c_str(), errno); return MTS::IO::ICellularRadio::CODE::ERROR; } auto rc = g_apRadio->uploadDeltaFirmwareFile(fd, cb); close(fd); return rc; }