diff options
| author | Maksym Telychko <maksym.telychko@globallogic.com> | 2019-06-08 00:23:57 +0300 | 
|---|---|---|
| committer | Maksym Telychko <maksym.telychko@globallogic.com> | 2019-06-08 00:23:57 +0300 | 
| commit | 596f8f8393bf837d73e0a62c87d52557d9191f96 (patch) | |
| tree | 0bd5ed794ed423b18aeade28b4f3ffd13d0d0e84 /src | |
| parent | 9f1b5b16547536196dde8e9296debbae924bfb2c (diff) | |
| download | libmts-io-596f8f8393bf837d73e0a62c87d52557d9191f96.tar.gz libmts-io-596f8f8393bf837d73e0a62c87d52557d9191f96.tar.bz2 libmts-io-596f8f8393bf837d73e0a62c87d52557d9191f96.zip | |
[MTS-MTQ] refactoring: telit radio implementation
leave telit specific code in telit class.
move common code to cellular radio class.
Diffstat (limited to 'src')
| -rw-r--r-- | src/MTS_IO_CellularRadio.cpp | 1299 | ||||
| -rw-r--r-- | src/MTS_IO_TelitRadio.cpp | 1170 | 
2 files changed, 1345 insertions, 1124 deletions
| diff --git a/src/MTS_IO_CellularRadio.cpp b/src/MTS_IO_CellularRadio.cpp index a29d14f..840132f 100644 --- a/src/MTS_IO_CellularRadio.cpp +++ b/src/MTS_IO_CellularRadio.cpp @@ -19,3 +19,1302 @@   */  #include "mts/MTS_IO_CellularRadio.h" + +#include <unistd.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> + +using namespace MTS::IO; + +namespace { +    typedef struct +    { +        const char    *name; +        int32_t        low; +        int32_t        high; +    } *pNameRangeMap, nameRangeMap; + +    const unsigned int NUM_GSM_BANDS = 7; +    const unsigned int NUM_WCDMA_BANDS = 6; +    const unsigned int NUM_LTE_BANDS = 42; + +    // http://niviuk.free.fr/gsm_band.php +    const nameRangeMap GSMband[] = +    { +                {"GSM 450", 259, 293}, {"GSM 480", 306, 340}, +                {"GSM 750", 438, 511}, {"GSM 850", 128, 251}, +                {"GSM 900 P", 1, 124}, {"GSM 900 E/R", 955, 1023}, +                {"GSM DCS 1800/1900", 512, 885}, + +    }; + +    // http://niviuk.free.fr/umts_band.php +    const nameRangeMap WCDMAband[] = +    { +                {"BAND I",   10592, 10838}, {"BAND II", 9662, 9938}, +                {"BAND III",  1162,  1513}, {"BAND IV", 1537, 1738}, +                {"BAND V",    4357,  4458}, {"BAND VI", 4387, 4413} +    }; + +    // http://niviuk.free.fr/lte_band.php +    const nameRangeMap EULTRAband[] = +    { +                {"EUTRAN BAND1",      0,   599}, {"EUTRAN BAND2",    600,  1199}, +                {"EUTRAN BAND3",   1200,  1949}, {"EUTRAN BAND4",   1950,  2399}, +                {"EUTRAN BAND5",   2400,  2649}, {"EUTRAN BAND6",   2650,  2749}, +                {"EUTRAN BAND7",   2750,  3449}, {"EUTRAN BAND8",   3450,  3799}, +                {"EUTRAN BAND9",   3800,  4149}, {"EUTRAN BAND10",  4150,  4749}, +                {"EUTRAN BAND11",  4750,  4999}, {"EUTRAN BAND12",  5000,  5179}, +                {"EUTRAN BAND13",  5180,  5279}, {"EUTRAN BAND14",  5280,  5379}, +                {"EUTRAN BAND17",  5730,  5849}, {"EUTRAN BAND18",  5850,  5999}, +                {"EUTRAN BAND19",  6000,  6149}, {"EUTRAN BAND20",  6150,  6449}, +                {"EUTRAN BAND21",  6450,  6525}, {"EUTRAN BAND22",  6600,  7399}, +                {"EUTRAN BAND23",  7500,  7699}, {"EUTRAN BAND24",  7700,  8039}, +                {"EUTRAN BAND25",  8040,  8689}, {"EUTRAN BAND26",  8690,  9039}, +                {"EUTRAN BAND27",  9040,  9209}, {"EUTRAN BAND28",  9210,  9659}, +                {"EUTRAN BAND29",  9660,  9769}, {"EUTRAN BAND30",  9770,  9869}, +                {"EUTRAN BAND31",  9870,  9919}, {"EUTRAN BAND32",  9920, 10359}, +                {"EUTRAN BAND33", 36000, 36199}, {"EUTRAN BAND34", 36200, 36349}, +                {"EUTRAN BAND35", 36350, 36949}, {"EUTRAN BAND36", 36950, 37549}, +                {"EUTRAN BAND37", 37550, 37749}, {"EUTRAN BAND38", 37750, 38249}, +                {"EUTRAN BAND39", 38250, 38649}, {"EUTRAN BAND40", 38650, 39649}, +                {"EUTRAN BAND41", 39650, 41589}, {"EUTRAN BAND42", 41590, 43589}, +                {"EUTRAN BAND43", 43590, 45589}, {"EUTRAN BAND44", 45590, 46589} +    }; +} + +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::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()); +            printDebug("%s| Recovering 'echo' after connection reset", m_sName.c_str()); // see CellularRadio::initialize +            setEcho(m_bEchoEnabled); +            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::getFirmware(std::string& sFirmware) { +    printTrace("%s| Get Firmware", m_sName.c_str()); +    sFirmware = VALUE_NOT_SUPPORTED; +    std::string sCmd("AT+CGMR"); +    std::string sResult = 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::getFirmwareBuild(std::string& sFirmwareBuild) { +    sFirmwareBuild = VALUE_NOT_SUPPORTED; +    return FAILURE; +} + +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 = 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 = 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 = 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::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 = 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 = 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::getModemLocation(std::string&) { +    printTrace("%s|CellularRadio getModemLocation - not supported", m_sName.c_str()); +    return FAILURE; +} + +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> - +*/ + +// Get the LAC for the LTE radio that's not in the #RFSTS response +std::string CellularRadio::queryLteLac() { +    std::string CGREGstring; +    std::string originalCGREG; +    std::string result; + +    CGREGstring = queryCGREGstring(); +    if (CGREGstring == RSP_ERROR) { +        originalCGREG = "0"; +    } else { +        originalCGREG = CGREGstring.at(CGREGstring.find(",") - 1); //Position right before first comma ("+CGREG: 0,1") +    } + +    // Temporarily set CGREG=2 to get more info +    setCGREG("2"); + +    CGREGstring = queryCGREGstring(); +    if (CGREGstring == RSP_ERROR) { +        result = VALUE_UNKNOWN; +    } else { +        size_t start = CGREGstring.find(":") + 1; //Position right after "#RFSTS:" +        std::vector<std::string> vParts = MTS::Text::split(MTS::Text::trim(CGREGstring.substr(start)), ","); +        if(vParts.size() < 3) { +            result = VALUE_UNAVAILABLE; +        } else { +            result = MTS::Text::strip(vParts[2], '"'); +        } +    } + +    setCGREG(originalCGREG); + +    return result; +} + +void CellularRadio::setCGREG(std::string value) { +    std::string sCmd("AT+CGREG=" + value); +    std::string cmdResult(sendCommand(sCmd)); +    if (cmdResult.find("OK") == std::string::npos) { +        printDebug("%s| AT#CGREG=%s returned unexpected response: [%s][%s]", m_sName.c_str(), value.c_str(), sCmd.c_str(), cmdResult.c_str()); +    } +} + +std::string CellularRadio::queryCGREGstring() { +    std::string sCmd("AT+CGREG?"); +    std::string cmdResult(sendCommand(sCmd)); +    if (cmdResult.find("+CGREG:") == std::string::npos) { +        printDebug("%s| AT#CGREG? returned unexpected response: [%s][%s]", m_sName.c_str(), sCmd.c_str(), cmdResult.c_str()); +        return RSP_ERROR; +    } +    return cmdResult; +} + +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; +    } + +    std::string sNetworkReg; +    REGISTRATION eReg; +    if (getRegistration(eReg) == SUCCESS) { +        if (convertRegistrationToString(eReg, sNetworkReg) == SUCCESS) { +            jData[KEY_NETWORK_REG] = sNetworkReg; +        } +    } +} + +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; +    std::string sResp; + +    // LE910C1-NS is an LE910, so we stop the scan after the 0. +    if (m_sName.find("LE910") != std::string::npos) { +        // use AT+CGREG instead for LE910 models +        sCmd = "AT+CGREG?"; +        sResp = "+CGREG: "; +    } +    else { +        sCmd = "AT+CREG?"; +        sResp = "+CREG: "; +    } + +    std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 5000); +    if (sResult.find(sResp) == 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&) { +    printTrace("%s| Validate MSL", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMsid(const Json::Value&) { +    printTrace("%s| Set MSID", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::getMipProfile(Json::Value&) { +    printTrace("%s| Get MIP Active Profile", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipActiveProfile(const Json::Value&) { +    printTrace("%s| Set MIP Active Profile", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipNai(const Json::Value&) { +    printTrace("%s| Set MIP NAI", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipHomeIp(const Json::Value&) { +    printTrace("%s| Set MIP Home IP", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipPrimaryHa(const Json::Value&) { +    printTrace("%s| Set MIP Primary HA", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipSecondaryHa(const Json::Value&) { +    printTrace("%s| Set MIP Secondary HA", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipMnAaaSpi(const Json::Value&) { +    printTrace("%s| Set MIP MN-AAA SPI", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipMnHaSpi(const Json::Value&) { +    printTrace("%s| Set MIP MN-HA SPI", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipRevTun(const Json::Value&) { +    printTrace("%s| Set MIP Rev Tun", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipMnAaaSs(const Json::Value&) { +    printTrace("%s| Set MIP MN-AAA SS", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipMnHaSs(const Json::Value&) { +    printTrace("%s| Set MIP MN-HA SS", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::updateDc(const Json::Value&, UpdateCb&) { +    printTrace("%s| Update Device Configuration", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::updatePrl(const Json::Value&, UpdateCb&) { +    printTrace("%s| Update Preferred Roaming List", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::updateFumo(const Json::Value&, UpdateCb&) { +    printTrace("%s| Update Firmware Update Management Object", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::resetHfa(const Json::Value&, UpdateCb&) { +    printTrace("%s| HFA Reset", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::activate(const Json::Value&, UpdateCb&) { +    printTrace("%s| Activation", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setActiveFirmware(const Json::Value&) { +    printTrace("%s| Set Active Firmware Image Number: not applicable", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::getActiveFirmware(std::string& sFwId) { +    printTrace("%s| Get Active Firmware Image Number: not applicable", m_sName.c_str()); +    sFwId = VALUE_NOT_SUPPORTED; + +    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&, 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(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-JN1") != std::string::npos) { +        sModel = "LE910-JN1"; +    } else if(sResult.find("LE866A1-JS") != std::string::npos) { +        sModel = "LE866A1-JS"; +    } else if(sResult.find("LE910-NAG") != std::string::npos) { +        sModel = "LE910-NAG"; +    } else if(sResult.find("LE910C4-NF") != std::string::npos) { +        sModel = "LE910C4-NF"; +    } else if(sResult.find("LE910-NA1") != std::string::npos) { +        sModel = "LE910-NA1"; +    } else if(sResult.find("ME910C1-NA") != std::string::npos) { +        sModel = "ME910C1-NA"; +    } else if(sResult.find("ME910C1-NV") != std::string::npos) { +        sModel = "ME910C1-NV"; +    } else if(sResult.find("ME910C1-WW") != std::string::npos) { +        sModel = "ME910C1-WW"; +    } 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("LE910C4-EU") != std::string::npos) { +        sModel = "LE910C4-EU"; +    } else if(sResult.find("LE910-EU1") != std::string::npos) { +        sModel = "LE910-EU1"; +    } else if(sResult.find("LE910C1-NS") != std::string::npos) { +    	sModel = "LE910C1-NS"; +    } else if(sResult.find("LE910C1-AP") != std::string::npos) { +    	sModel = "LE910C1-AP"; +    } 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, "2" for Verizon, and "3" for U.S. Cellular. + +    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; +                } else +                if(cId == '1') { +                    sCarrier = VALUE_CARRIER_AERIS; +                    bResult = true; +                } else +                if(cId == '2') { +                    sCarrier = VALUE_CARRIER_VERIZON; +                    bResult = true; +                } else +                if(cId == '3') { +                    sCarrier = VALUE_CARRIER_USCELLULAR; +                    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; + +} + +const char *CellularRadio::RadioBandMap::getLTEBand(const int32_t channel) +{ +    for (unsigned int ii = 0; ii < NUM_LTE_BANDS; ii++) +    { +        if (EULTRAband[ii].low <= channel && EULTRAband[ii].high >= channel) +        { +            return EULTRAband[ii].name; +        } +    } +    return VALUE_UNKNOWN.c_str(); +} + +const char *CellularRadio::RadioBandMap::getCDMABand(const int channel) +{ +    for (unsigned int ii = 0; ii < NUM_WCDMA_BANDS; ii++) +    { +        if (WCDMAband[ii].low <= channel && WCDMAband[ii].high >= channel) +        { +            return WCDMAband[ii].name; +        } +    } +    return VALUE_UNKNOWN.c_str(); +} + +const char *CellularRadio::RadioBandMap::getGSMBand(const int channel) +{ +    for (unsigned int ii = 0; ii < NUM_GSM_BANDS; ii++) +    { +        if (GSMband[ii].low <= channel && GSMband[ii].high >= channel) +        { +            return GSMband[ii].name; +        } +    } +    return VALUE_UNKNOWN.c_str(); +} + +const char *CellularRadio::RadioBandMap::getRadioBandName() +{ +    const char *band = CellularRadio::VALUE_UNKNOWN.c_str(); + +    if (m_sRadioType == VALUE_TYPE_LTE) +    { +        band = getLTEBand(m_iChannel); +    } +    else if (m_sRadioType == VALUE_TYPE_CDMA) +    { +        band = getCDMABand(m_iChannel); +    } +    else if (m_sRadioType == VALUE_TYPE_GSM) +    { +        band = getGSMBand(m_iChannel); +    } + +    return band; +} + +const char *CellularRadio::RadioBandMap::getRadioBandName(const std::string &channel, const std::string &radioType) +{ +    const char *band = VALUE_UNKNOWN.c_str(); +    int32_t chan = strtol(channel.c_str(), NULL, 10); +    if (radioType == VALUE_TYPE_LTE) +    { +        band = getLTEBand(chan); +    } +    else if (radioType == VALUE_TYPE_CDMA) +    { +        band = getCDMABand(chan); +    } +    else if (radioType == VALUE_TYPE_GSM) +    { +        band = getGSMBand(chan); +    } + +    return band; +} diff --git a/src/MTS_IO_TelitRadio.cpp b/src/MTS_IO_TelitRadio.cpp index 65d0941..6ce240e 100644 --- a/src/MTS_IO_TelitRadio.cpp +++ b/src/MTS_IO_TelitRadio.cpp @@ -20,112 +20,20 @@  #include <mts/MTS_IO_TelitRadio.h> -#include <unistd.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_Thread.h>  #include <mts/MTS_Text.h>  using namespace MTS::IO; -namespace { -    typedef struct -    { -        const char    *name; -        int32_t        low; -        int32_t        high; -    } *pNameRangeMap, nameRangeMap; - -    const unsigned int NUM_GSM_BANDS = 7; -    const unsigned int NUM_WCDMA_BANDS = 6; -    const unsigned int NUM_LTE_BANDS = 42; - -    // http://niviuk.free.fr/gsm_band.php -    const nameRangeMap GSMband[] = -    { -                {"GSM 450", 259, 293}, {"GSM 480", 306, 340}, -                {"GSM 750", 438, 511}, {"GSM 850", 128, 251}, -                {"GSM 900 P", 1, 124}, {"GSM 900 E/R", 955, 1023}, -                {"GSM DCS 1800/1900", 512, 885}, - -    }; - -    // http://niviuk.free.fr/umts_band.php -    const nameRangeMap WCDMAband[] = -    { -                {"BAND I",   10592, 10838}, {"BAND II", 9662, 9938}, -                {"BAND III",  1162,  1513}, {"BAND IV", 1537, 1738}, -                {"BAND V",    4357,  4458}, {"BAND VI", 4387, 4413} -    }; - -    // http://niviuk.free.fr/lte_band.php -    const nameRangeMap EULTRAband[] = -    { -                {"EUTRAN BAND1",      0,   599}, {"EUTRAN BAND2",    600,  1199}, -                {"EUTRAN BAND3",   1200,  1949}, {"EUTRAN BAND4",   1950,  2399}, -                {"EUTRAN BAND5",   2400,  2649}, {"EUTRAN BAND6",   2650,  2749}, -                {"EUTRAN BAND7",   2750,  3449}, {"EUTRAN BAND8",   3450,  3799}, -                {"EUTRAN BAND9",   3800,  4149}, {"EUTRAN BAND10",  4150,  4749}, -                {"EUTRAN BAND11",  4750,  4999}, {"EUTRAN BAND12",  5000,  5179}, -                {"EUTRAN BAND13",  5180,  5279}, {"EUTRAN BAND14",  5280,  5379}, -                {"EUTRAN BAND17",  5730,  5849}, {"EUTRAN BAND18",  5850,  5999}, -                {"EUTRAN BAND19",  6000,  6149}, {"EUTRAN BAND20",  6150,  6449}, -                {"EUTRAN BAND21",  6450,  6525}, {"EUTRAN BAND22",  6600,  7399}, -                {"EUTRAN BAND23",  7500,  7699}, {"EUTRAN BAND24",  7700,  8039}, -                {"EUTRAN BAND25",  8040,  8689}, {"EUTRAN BAND26",  8690,  9039}, -                {"EUTRAN BAND27",  9040,  9209}, {"EUTRAN BAND28",  9210,  9659}, -                {"EUTRAN BAND29",  9660,  9769}, {"EUTRAN BAND30",  9770,  9869}, -                {"EUTRAN BAND31",  9870,  9919}, {"EUTRAN BAND32",  9920, 10359}, -                {"EUTRAN BAND33", 36000, 36199}, {"EUTRAN BAND34", 36200, 36349}, -                {"EUTRAN BAND35", 36350, 36949}, {"EUTRAN BAND36", 36950, 37549}, -                {"EUTRAN BAND37", 37550, 37749}, {"EUTRAN BAND38", 37750, 38249}, -                {"EUTRAN BAND39", 38250, 38649}, {"EUTRAN BAND40", 38650, 39649}, -                {"EUTRAN BAND41", 39650, 41589}, {"EUTRAN BAND42", 41590, 43589}, -                {"EUTRAN BAND43", 43590, 45589}, {"EUTRAN BAND44", 45590, 46589} -    }; -} -  TelitRadio::TelitRadio(const std::string& sName, const std::string& sRadioPort) -: m_sName(sName) -, m_sRadioPort(sRadioPort) -, m_bEchoEnabled(false) -, m_bEnableEchoOnClose(false) +: CellularRadio(sName, sRadioPort)  { -    m_apIo.reset(new MTS::IO::SerialConnection( -                             MTS::IO::SerialConnection::Builder(m_sRadioPort) -                                .baudRate(115200) -                                .useLockFile() -                                .build())); -} - - -TelitRadio::~TelitRadio() { -    shutdown(); -    m_apIo.reset(); -} - -bool TelitRadio::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 TelitRadio::resetRadio(uint32_t iTimeoutMillis) { -    printInfo("%s| Rebooting radio", m_sName.c_str()); +    printInfo("%s| Rebooting radio", getName().c_str());      if(sendBasicCommand("AT#REBOOT") == SUCCESS) {          if(iTimeoutMillis > 5000) {              MTS::Thread::sleep(5000); @@ -137,203 +45,41 @@ bool TelitRadio::resetRadio(uint32_t iTimeoutMillis) {      return false;  } -bool TelitRadio::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()); -            printDebug("%s| Recovering 'echo' after connection reset", m_sName.c_str()); // see TelitRadio::initialize -            setEcho(m_bEchoEnabled); -            break; -        } - -        ::usleep(500000); //500 millis -        iCurrentTime = oTimer.getMillis(); -    } -    oTimer.stop(); -    return !m_apIo->isClosed(); -} - -void TelitRadio::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& TelitRadio::getName() const { -    return m_sName; -} - -TelitRadio::CODE TelitRadio::getModel(std::string& sModel) { -    printTrace("%s| Get Model", m_sName.c_str()); +CellularRadio::CODE TelitRadio::getModel(std::string& sModel) { +    printTrace("%s| Get Model", getName().c_str());      //Always returns SUCCESS because the model should be m_sName -    sModel = m_sName; +    sModel = getName();      std::string sCmd("ATI4"); -    std::string sResult = TelitRadio::sendCommand(m_apIo, sCmd); +    std::string sResult = sendCommand(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()); +        printWarning("%s| Unable to get model from radio.  Returning [%s]", getName().c_str(), getName().c_str());          return SUCCESS;      } else { -        sModel = TelitRadio::extractModelFromResult(sResult); +        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()); +            printWarning("%s| Unable to get model from radio.  Returning [%s]", getName().c_str(), getName().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) { +    printDebug("%s| Extracted [%s] from [%s] query", getName().c_str(), sModel.c_str(), sCmd.c_str()); +    if(sModel != getName()) {          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; -} - -TelitRadio::CODE TelitRadio::getFirmware(std::string& sFirmware) { -    printTrace("%s| Get Firmware", m_sName.c_str()); -    sFirmware = VALUE_NOT_SUPPORTED; -    std::string sCmd("AT+CGMR"); -    std::string sResult = TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::getFirmwareBuild(std::string& sFirmwareBuild) { -    sFirmwareBuild = VALUE_NOT_SUPPORTED; -    return FAILURE; -} - -TelitRadio::CODE TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::getManufacturer(std::string& sManufacturer) { -    printTrace("%s| Get Manufacturer", m_sName.c_str()); -    sManufacturer = VALUE_NOT_SUPPORTED; -    std::string sCmd("AT+GMI"); -    std::string sResult = TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::getImei(std::string& sImei) { -    printTrace("%s| Get IMEI", m_sName.c_str()); -    sImei = VALUE_NOT_SUPPORTED; -    std::string sCmd("AT+CGSN"); -    std::string sResult = TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::getMeid(std::string& sMeid) { -    printTrace("%s| Get MEID", m_sName.c_str()); -    return getImei(sMeid); -} - -TelitRadio::CODE TelitRadio::getImsi(std::string& sImsi) { -    printTrace("%s| Get IMSI", m_sName.c_str()); -    sImsi = VALUE_NOT_SUPPORTED; -    std::string sCmd("AT+CIMI"); -    std::string sResult = TelitRadio::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; +                     getName().c_str(),  sModel.c_str(), getName().c_str(), sModel.c_str());      }      return SUCCESS;  } -TelitRadio::CODE TelitRadio::getSimStatus(std::string& sSimStatus) { -    printTrace("%s| Get SIM Status", getName().c_str()); -    sSimStatus = VALUE_UNKNOWN; -    return FAILURE; -} - -TelitRadio::CODE TelitRadio::getIccid(std::string& sIccid) { -    printTrace("%s| Get ICCID", m_sName.c_str()); +CellularRadio::CODE TelitRadio::getIccid(std::string& sIccid) { +    printTrace("%s| Get ICCID", getName().c_str());      sIccid = VALUE_NOT_SUPPORTED;      std::string sCmd("AT#CCID"); -    std::string sResult = TelitRadio::sendCommand(sCmd); +    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()); +        printWarning("%s| Unable to get ICCID from radio using command [%s]", getName().c_str(), sCmd.c_str());          return FAILURE;      } @@ -342,21 +88,21 @@ TelitRadio::CODE TelitRadio::getIccid(std::string& sIccid) {          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()); +            printWarning("%s| Unable to get ICCID from radio using command [%s]", getName().c_str(), sCmd.c_str());              return FAILURE;          }      }      return SUCCESS;  } -TelitRadio::CODE TelitRadio::getService(std::string& sService) { -    printTrace("%s| Get Service", m_sName.c_str()); +CellularRadio::CODE TelitRadio::getService(std::string& sService) { +    printTrace("%s| Get Service", getName().c_str());      sService = VALUE_NOT_SUPPORTED;      std::string sCmd("AT#PSNT?"); -    std::string sResult = TelitRadio::sendCommand(sCmd); +    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()); +        printWarning("%s| Unable to get Service from radio using command [%s]", getName().c_str(), sCmd.c_str());          return FAILURE;      } @@ -376,335 +122,11 @@ TelitRadio::CODE TelitRadio::getService(std::string& sService) {              default: sService = VALUE_UNKNOWN; break;          } -        printDebug("%s| Service ID: [%d][%s]", m_sName.c_str(), iService, sService.c_str()); -    } -    return SUCCESS; -} - -TelitRadio::CODE TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::getMdn(std::string& sMdn) { -    printTrace("%s| Get MDN", m_sName.c_str()); -    sMdn = VALUE_NOT_SUPPORTED; -    std::string sCmd("AT+CNUM"); -    std::string sResult = TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::getType(std::string& sType) { -    printTrace("%s| Get Type", m_sName.c_str()); -    sType = VALUE_NOT_SUPPORTED; -    return FAILURE; -} - -TelitRadio::CODE TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::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 = TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::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; +        printDebug("%s| Service ID: [%d][%s]", getName().c_str(), iService, sService.c_str());      } -    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; -} - -TelitRadio::CODE TelitRadio::getModemLocation(std::string& sLocation) { -    printTrace("%s|TelitRadio getModemLocation - not supported", m_sName.c_str()); -    return FAILURE; -} - -TelitRadio::CODE TelitRadio::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;  } -TelitRadio::CODE TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::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) @@ -780,14 +202,14 @@ TelitRadio::CODE TelitRadio::getStaticInformation(Json::Value& jData) {      <SD> -      <ABND> -  */ -TelitRadio::CODE TelitRadio::getNetworkStatus(Json::Value& jData) { +CellularRadio::CODE TelitRadio::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()); +    printTrace("%s| Get Network Status", getName().c_str());      //Always get common network stats because this should never fail      //This way the basic stats are always returned even if AT#RFSTS fails below @@ -799,17 +221,17 @@ TelitRadio::CODE TelitRadio::getNetworkStatus(Json::Value& jData) {      // will cause the radio to stop responding until a radio power cycle      // Telit Support Portal Case #5069697      // LE910C1-NS is an LE910, so we stop the scan after the 0. -    if (m_sName.find("LE910") != std::string::npos) { +    if (getName().find("LE910") != std::string::npos) {          sCmd = "AT+CPIN?";          sResult = sendCommand(sCmd);          if (sResult.find("+CPIN:") == std::string::npos) { -            printDebug("%s| AT+CPIN? returned unexpected response: [%s][%s]", m_sName.c_str(), sCmd.c_str(), sResult.c_str()); -            printTrace("%s| Network Status:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); +            printDebug("%s| AT+CPIN? 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; //return SUCCESS because getCommonNetworkStats() succeeded at top of this function          }          if (sResult.find("SIM PIN") != std::string::npos) { -            printError("%s| The SIM is locked and must first be unlocked", m_sName.c_str()); -            printTrace("%s| Network Status:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); +            printError("%s| The SIM is locked and must first be unlocked", getName().c_str()); +            printTrace("%s| Network Status:\n%s\n", getName().c_str(), jData.toStyledString().c_str());              return SUCCESS; //return SUCCESS because getCommonNetworkStats() succeeded at top of this function          }      } @@ -818,8 +240,8 @@ TelitRadio::CODE TelitRadio::getNetworkStatus(Json::Value& jData) {      sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 200);      if (sResult.find("#RFSTS:") == std::string::npos) {          //On LTE radios without signal, this case will run because AT#RFSTS just returns "OK" -        printDebug("%s| Network Status command returned unexpected response: [%s][%s]", m_sName.c_str(), sCmd.c_str(), sResult.c_str()); -        printTrace("%s| Network Status:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); +        printDebug("%s| 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; //return SUCCESS because getCommonNetworkStats() succeeded at top of this function      } @@ -827,8 +249,8 @@ TelitRadio::CODE TelitRadio::getNetworkStatus(Json::Value& jData) {      std::vector<std::string> vParts = MTS::Text::split(MTS::Text::trim(sResult.substr(start)), ",");      if (vParts.size() < 3) { -        printDebug("%s| Network Status command reponse is an unknown format: [%s][%s]", m_sName.c_str(), sCmd.c_str(), sResult.c_str()); -        printTrace("%s| Network Status:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); +        printDebug("%s| Network Status command reponse is an unknown format: [%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; //return SUCCESS because getCommonNetworkStats() succeeded at top of this function      } else {          //Country Code and Operator Code @@ -861,7 +283,7 @@ TelitRadio::CODE TelitRadio::getNetworkStatus(Json::Value& jData) {          }        // IN003567 ME910C1 radios have some odd behavior with regards to WCDMA.  The ordering of the fields from #RFSTS are        // the same as LTE up to the 16th field (for ME901C1-WW anyway).  Drop into LTE parsing for ME910C1-WW. -    } else if((vParts.size() >= WCDMA_NETWORK_FORMAT) && (m_sName.find("ME910C1-WW") == std::string::npos)) { +    } else if((vParts.size() >= WCDMA_NETWORK_FORMAT) && (getName().find("ME910C1-WW") == std::string::npos)) {          Json::Value jDebug;          //Parse as WCDMA Network Format @@ -891,7 +313,7 @@ TelitRadio::CODE TelitRadio::getNetworkStatus(Json::Value& jData) {          jData[KEY_NETWORK] = MTS::Text::strip(vParts[16], '"');          // Get the radio band given the channel (UARFCN) -        RadioBandMap radioBandMap(vParts[1], TelitRadio::VALUE_TYPE_CDMA); +        RadioBandMap radioBandMap(vParts[1], CellularRadio::VALUE_TYPE_CDMA);          jData[KEY_ABND] = radioBandMap.getRadioBandName();          if(MTS::Text::parse(iValue, vParts[17]) && convertServiceDomainToString((SERVICEDOMAIN)iValue, sValue) == SUCCESS) { @@ -943,7 +365,7 @@ TelitRadio::CODE TelitRadio::getNetworkStatus(Json::Value& jData) {          jData[KEY_NETWORK] = MTS::Text::strip(vParts[12], '"');          // Get the radio band given the channel (EARFCN) -        RadioBandMap radioBandMap(vParts[1], TelitRadio::VALUE_TYPE_LTE); +        RadioBandMap radioBandMap(vParts[1], CellularRadio::VALUE_TYPE_LTE);          jData[KEY_ABND] = radioBandMap.getRadioBandName();          jData[KEY_LAC] = queryLteLac(); @@ -955,10 +377,11 @@ TelitRadio::CODE TelitRadio::getNetworkStatus(Json::Value& jData) {          jData[KEY_DEBUG] = jDebug;      } -    printTrace("%s| Network Status:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); +    printTrace("%s| Network Status:\n%s\n", getName().c_str(), jData.toStyledString().c_str());      return SUCCESS;  } +  // Get the LAC for the LTE radio that's not in the #RFSTS response  std::string TelitRadio::queryLteLac() {      std::string CGREGstring; @@ -977,12 +400,12 @@ std::string TelitRadio::queryLteLac() {      CGREGstring = queryCGREGstring();      if (CGREGstring == RSP_ERROR) { -        result = TelitRadio::VALUE_UNKNOWN; +        result = CellularRadio::VALUE_UNKNOWN;      } else {          size_t start = CGREGstring.find(":") + 1; //Position right after "#RFSTS:"          std::vector<std::string> vParts = MTS::Text::split(MTS::Text::trim(CGREGstring.substr(start)), ",");          if(vParts.size() < 3) { -            result = TelitRadio::VALUE_UNAVAILABLE; +            result = CellularRadio::VALUE_UNAVAILABLE;          } else {              result = MTS::Text::strip(vParts[2], '"');          } @@ -997,7 +420,7 @@ void TelitRadio::setCGREG(std::string value) {      std::string sCmd("AT+CGREG=" + value);      std::string cmdResult(sendCommand(sCmd));      if (cmdResult.find("OK") == std::string::npos) { -        printDebug("%s| AT#CGREG=%s returned unexpected response: [%s][%s]", m_sName.c_str(), value.c_str(), sCmd.c_str(), cmdResult.c_str()); +        printDebug("%s| AT#CGREG=%s returned unexpected response: [%s][%s]", getName().c_str(), value.c_str(), sCmd.c_str(), cmdResult.c_str());      }  } @@ -1005,116 +428,14 @@ std::string TelitRadio::queryCGREGstring() {      std::string sCmd("AT+CGREG?");      std::string cmdResult(sendCommand(sCmd));      if (cmdResult.find("+CGREG:") == std::string::npos) { -        printDebug("%s| AT#CGREG? returned unexpected response: [%s][%s]", m_sName.c_str(), sCmd.c_str(), cmdResult.c_str()); +        printDebug("%s| AT#CGREG? returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), cmdResult.c_str());          return RSP_ERROR;      }      return cmdResult;  } -void TelitRadio::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; -    } - -    std::string sNetworkReg; -    TelitRadio::REGISTRATION eReg; -    if (getRegistration(eReg) == SUCCESS) { -        if (convertRegistrationToString(eReg, sNetworkReg) == SUCCESS) { -            jData[TelitRadio::KEY_NETWORK_REG] = sNetworkReg; -        } -    } -} - -void TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::getRegistration(REGISTRATION& eRegistration) { -    std::string sCmd; -    std::string sResp; - -    // LE910C1-NS is an LE910, so we stop the scan after the 0. -    if (m_sName.find("LE910") != std::string::npos) { -        // use AT+CGREG instead for LE910 models -        sCmd = "AT+CGREG?"; -        sResp = "+CGREG: "; -    } -    else { -        sCmd = "AT+CREG?"; -        sResp = "+CREG: "; -    } - -    std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 5000); -    if (sResult.find(sResp) == 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; -} - -TelitRadio::CODE TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::validateMsl(const Json::Value& jArgs) { -    printTrace("%s| Validate MSL", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::setMdn(const Json::Value& jArgs) { -    printTrace("%s| Set MDN", m_sName.c_str()); +CellularRadio::CODE TelitRadio::setMdn(const Json::Value& jArgs) { +    printTrace("%s| Set MDN", getName().c_str());      if(!jArgs["mdn"].isString()) {          return INVALID_ARGS; @@ -1126,336 +447,13 @@ TelitRadio::CODE TelitRadio::setMdn(const Json::Value& jArgs) {      std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 1000);      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()); +        printWarning("%s| Unable to set MDN for radio using command [%s]", getName().c_str(), sCmd.c_str());          return FAILURE;      }      return SUCCESS;  } -TelitRadio::CODE TelitRadio::setMsid(const Json::Value& jArgs) { -    printTrace("%s| Set MSID", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::getMipProfile(Json::Value& jMipProfile) { -    printTrace("%s| Get MIP Active Profile", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::setMipActiveProfile(const Json::Value& jArgs) { -    printTrace("%s| Set MIP Active Profile", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::setMipNai(const Json::Value& jArgs) { -    printTrace("%s| Set MIP NAI", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::setMipHomeIp(const Json::Value& jArgs) { -    printTrace("%s| Set MIP Home IP", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::setMipPrimaryHa(const Json::Value& jArgs) { -    printTrace("%s| Set MIP Primary HA", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::setMipSecondaryHa(const Json::Value& jArgs) { -    printTrace("%s| Set MIP Secondary HA", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::setMipMnAaaSpi(const Json::Value& jArgs) { -    printTrace("%s| Set MIP MN-AAA SPI", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::setMipMnHaSpi(const Json::Value& jArgs) { -    printTrace("%s| Set MIP MN-HA SPI", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::setMipRevTun(const Json::Value& jArgs) { -    printTrace("%s| Set MIP Rev Tun", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::setMipMnAaaSs(const Json::Value& jArgs) { -    printTrace("%s| Set MIP MN-AAA SS", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::setMipMnHaSs(const Json::Value& jArgs) { -    printTrace("%s| Set MIP MN-HA SS", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::updateDc(const Json::Value& jArgs, UpdateCb& stepCb) { -    printTrace("%s| Update Device Configuration", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::updatePrl(const Json::Value& jArgs, UpdateCb& stepCb) { -    printTrace("%s| Update Preferred Roaming List", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::updateFumo(const Json::Value& jArgs, UpdateCb& stepCb) { -    printTrace("%s| Update Firmware Update Management Object", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::resetHfa(const Json::Value& jArgs, UpdateCb& stepCb) { -    printTrace("%s| HFA Reset", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::activate(const Json::Value& jArgs, UpdateCb& stepCb) { -    printTrace("%s| Activation", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::setActiveFirmware(const Json::Value& jArgs) { -    printTrace("%s| Set Active Firmware Image Number: not applicable", m_sName.c_str()); - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::getActiveFirmware(std::string& sFwId) { -    printTrace("%s| Get Active Firmware Image Number: not applicable", m_sName.c_str()); -    sFwId = VALUE_NOT_SUPPORTED; - -    return NOT_APPLICABLE; -} - -TelitRadio::CODE TelitRadio::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 TelitRadio::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 TelitRadio::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 TelitRadio::sendCommand(const std::string& sCmd, MTS::IO::TelitRadio::IsNeedMoreData& isNeedMoreData, int32_t timeoutMillis, const char& ESC) { -    return sendCommand(m_apIo, sCmd, isNeedMoreData, timeoutMillis, ESC); -} - -std::string TelitRadio::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; -} - -TelitRadio::CODE TelitRadio::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 TelitRadio::extractModelFromResult(const std::string& sResult) { -    std::string sModel(TelitRadio::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-JN1") != std::string::npos) { -        sModel = "LE910-JN1"; -    } else if(sResult.find("LE866A1-JS") != std::string::npos) { -        sModel = "LE866A1-JS"; -    } else if(sResult.find("LE910-NAG") != std::string::npos) { -        sModel = "LE910-NAG"; -    } else if(sResult.find("LE910C4-NF") != std::string::npos) { -        sModel = "LE910C4-NF"; -    } else if(sResult.find("LE910-NA1") != std::string::npos) { -        sModel = "LE910-NA1"; -    } else if(sResult.find("ME910C1-NA") != std::string::npos) { -        sModel = "ME910C1-NA"; -    } else if(sResult.find("ME910C1-NV") != std::string::npos) { -        sModel = "ME910C1-NV"; -    } else if(sResult.find("ME910C1-WW") != std::string::npos) { -        sModel = "ME910C1-WW"; -    } 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("LE910C4-EU") != std::string::npos) { -        sModel = "LE910C4-EU"; -    } else if(sResult.find("LE910-EU1") != std::string::npos) { -        sModel = "LE910-EU1"; -    } else if(sResult.find("LE910C1-NS") != std::string::npos) { -    	sModel = "LE910C1-NS"; -    } else if(sResult.find("LE910C1-AP") != std::string::npos) { -    	sModel = "LE910C1-AP"; -    } 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 TelitRadio::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 TelitRadio::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 TelitRadio::getCarrierFromFirmware(const std::string& sFirmware, std::string& sCarrier) {      // Telit Radios      //    H.ab.zyx => 3 Main Components @@ -1536,79 +534,3 @@ bool TelitRadio::getHardwareVersionFromFirmware(const std::string& sFirmware, st      return bResult;  } - -const char *TelitRadio::RadioBandMap::getLTEBand(const int32_t channel) -{ -    for (unsigned int ii = 0; ii < NUM_LTE_BANDS; ii++) -    { -        if (EULTRAband[ii].low <= channel && EULTRAband[ii].high >= channel) -        { -            return EULTRAband[ii].name; -        } -    } -    return VALUE_UNKNOWN.c_str(); -} - -const char *TelitRadio::RadioBandMap::getCDMABand(const int channel) -{ -    for (unsigned int ii = 0; ii < NUM_WCDMA_BANDS; ii++) -    { -        if (WCDMAband[ii].low <= channel && WCDMAband[ii].high >= channel) -        { -            return WCDMAband[ii].name; -        } -    } -    return VALUE_UNKNOWN.c_str(); -} - -const char *TelitRadio::RadioBandMap::getGSMBand(const int channel) -{ -    for (unsigned int ii = 0; ii < NUM_GSM_BANDS; ii++) -    { -        if (GSMband[ii].low <= channel && GSMband[ii].high >= channel) -        { -            return GSMband[ii].name; -        } -    } -    return VALUE_UNKNOWN.c_str(); -} - -const char *TelitRadio::RadioBandMap::getRadioBandName() -{ -    const char *band = TelitRadio::VALUE_UNKNOWN.c_str(); - -    if (m_sRadioType == TelitRadio::VALUE_TYPE_LTE) -    { -        band = getLTEBand(m_iChannel); -    } -    else if (m_sRadioType == TelitRadio::VALUE_TYPE_CDMA) -    { -        band = getCDMABand(m_iChannel); -    } -    else if (m_sRadioType == TelitRadio::VALUE_TYPE_GSM) -    { -        band = getGSMBand(m_iChannel); -    } - -    return band; -} - -const char *TelitRadio::RadioBandMap::getRadioBandName(const std::string &channel, const std::string &radioType) -{ -    const char *band = TelitRadio::VALUE_UNKNOWN.c_str(); -    int32_t chan = strtol(channel.c_str(), NULL, 10); -    if (radioType == TelitRadio::VALUE_TYPE_LTE) -    { -        band = getLTEBand(chan); -    } -    else if (radioType == TelitRadio::VALUE_TYPE_CDMA) -    { -        band = getCDMABand(chan); -    } -    else if (radioType == TelitRadio::VALUE_TYPE_GSM) -    { -        band = getGSMBand(chan); -    } - -    return band; -} | 
