diff options
| author | John Klug <john.klug@multitech.com> | 2023-01-11 11:26:50 -0600 | 
|---|---|---|
| committer | John Klug <john.klug@multitech.com> | 2023-01-11 11:26:50 -0600 | 
| commit | e661044a43345f7cac947c3bb6178a2c045028f6 (patch) | |
| tree | 904f32734e0e2dff8ecccbf83264b8bf8a8cecc1 /src/MTS_IO_CellularRadio.cpp | |
| parent | 81c924e1b30efabd5e5a7c712998b989917b2a8e (diff) | |
| parent | 430506fb7757d6736988d75c8ea53c85f6c97da9 (diff) | |
| download | libmts-io-e661044a43345f7cac947c3bb6178a2c045028f6.tar.gz libmts-io-e661044a43345f7cac947c3bb6178a2c045028f6.tar.bz2 libmts-io-e661044a43345f7cac947c3bb6178a2c045028f6.zip | |
Verizon IMSI detection merge1.0.33
Diffstat (limited to 'src/MTS_IO_CellularRadio.cpp')
| -rw-r--r-- | src/MTS_IO_CellularRadio.cpp | 175 | 
1 files changed, 175 insertions, 0 deletions
| diff --git a/src/MTS_IO_CellularRadio.cpp b/src/MTS_IO_CellularRadio.cpp index afdfc1e..069d5fa 100644 --- a/src/MTS_IO_CellularRadio.cpp +++ b/src/MTS_IO_CellularRadio.cpp @@ -1755,3 +1755,178 @@ ICellularRadio::CODE CellularRadio::getSelectedBandsRaw(std::string& sRawBands)      printTrace("%s| Acquiring selected bands: not applicable", m_sName.c_str());      return NOT_APPLICABLE;  } + +ICellularRadio::CODE CellularRadio::getPdpContexts(Json::Value& jData) { +    printTrace("%s| Fetching the list of PDP contexts from the radio", getName().c_str()); +    CODE rc; + +    const std::string sCommand = "AT+CGDCONT?"; +    const int dTimeout = 1000; +    std::string sResult; + +    rc = sendBasicQuery(sCommand, "", sResult, dTimeout); +    if (rc != SUCCESS) { +        return rc; +    } + +    std::vector<std::string> vContexts = MTS::Text::split(sResult, "+CGDCONT: "); +    std::vector<std::string> vContextParams; + +    for (size_t i = 0; i < vContexts.size(); i++) { +        vContexts[i] = MTS::Text::trim(vContexts[i]); + +        if (vContexts[i].empty()) { +            continue; +        } + +        vContextParams = MTS::Text::split(vContexts[i], ",", 4); + +        if (vContextParams.size() < 3) { +            return FAILURE; +        } + +        std::string sContextId = vContextParams[0]; +        std::string sIpMode = MTS::Text::trim(vContextParams[1], '"'); // Remove double quotes from the start and end of the value +        std::string sApn = MTS::Text::trim(vContextParams[2], '"');    // Remove double quotes from the start and end of the value + +        jData[sContextId][ICellularRadio::KEY_PDP_CONTEXT_IPMODE] = sIpMode; +        jData[sContextId][ICellularRadio::KEY_PDP_CONTEXT_APN] = sApn; +    } + +    return SUCCESS; +} + +ICellularRadio::CODE CellularRadio::setPdpContext(const std::string& sId, const Json::Value& jConfig) { +    printTrace("%s| Setting context to the radio", getName().c_str()); +    CODE rc; + +    if (sId.empty()) { +        printError("%s| PDP Context ID is not specified", getName().c_str()); +        return FAILURE; +    } + +    std::string sCommand = "AT+CGDCONT=" + sId; +    const int dTimeout = 1000; + +    Json::Value jAllContexts; + +    rc = getPdpContexts(jAllContexts); +    if (rc != SUCCESS) { +        printError("%s| Failed to retrieve the current PDP context configuration: [%d]", getName().c_str(), rc); +        return rc; +    } + +    // Remove the context if no parameters defined +    if (!jConfig.isMember(ICellularRadio::KEY_PDP_CONTEXT_IPMODE) && !jConfig.isMember(ICellularRadio::KEY_PDP_CONTEXT_APN)) { +        if (jAllContexts.isMember(sId)) { +            rc = sendBasicCommand(sCommand, dTimeout); +            return rc; +        } else { +            printError("%s| PDP Context [%s] does not exist", getName().c_str(), sId.c_str()); +            return FAILURE; +        } +    } + +    std::string sIpMode; + +    if (jConfig.isMember(ICellularRadio::KEY_PDP_CONTEXT_IPMODE)) { +        if (jConfig[ICellularRadio::KEY_PDP_CONTEXT_IPMODE] == "IP" || jConfig[ICellularRadio::KEY_PDP_CONTEXT_IPMODE] == "PPP" || +            jConfig[ICellularRadio::KEY_PDP_CONTEXT_IPMODE] == "IPV6" || jConfig[ICellularRadio::KEY_PDP_CONTEXT_IPMODE] == "IPV4V6") { +                sIpMode = jConfig[ICellularRadio::KEY_PDP_CONTEXT_IPMODE].asString(); +        } else { +            printError("%s| Invalid IP Mode defined: [%s]", getName().c_str(), jConfig[ICellularRadio::KEY_PDP_CONTEXT_IPMODE].asString().c_str()); +            return FAILURE; +        } +    } else if (jAllContexts.isMember(sId)) { +        printInfo("%s| Re-using IP Mode [%s] for PDP context [%s]", getName().c_str(), jAllContexts[sId][ICellularRadio::KEY_PDP_CONTEXT_IPMODE].asString().c_str(), sId.c_str()); +        sIpMode = jAllContexts[sId][ICellularRadio::KEY_PDP_CONTEXT_IPMODE].asString(); +    } else { +        printError("%s| Failed to edit PDP context [%s] - no such context defined", getName().c_str(), sId.c_str()); +        return FAILURE; +    } + +    sCommand += ",\""; +    sCommand += sIpMode; +    sCommand += "\""; + +    std::string sApn; + +    if (jConfig.isMember(ICellularRadio::KEY_PDP_CONTEXT_APN)) { +        sApn = jConfig[ICellularRadio::KEY_PDP_CONTEXT_APN].asString(); +    } else if (jAllContexts.isMember(sId)) { +        printInfo("%s| Re-using APN [%s] for PDP context [%s]", getName().c_str(), jAllContexts[sId][ICellularRadio::KEY_PDP_CONTEXT_APN].asString().c_str(), sId.c_str()); +        sApn = jAllContexts[sId][ICellularRadio::KEY_PDP_CONTEXT_APN].asString(); +    } else { +        printError("%s| Failed to edit PDP context [%s] - no such context defined", getName().c_str(), sId.c_str()); +        return FAILURE; +    } + +    sCommand += ",\""; +    sCommand += sApn; +    sCommand += "\""; + +    rc = sendBasicCommand(sCommand, dTimeout); + +    return rc; +} + +ICellularRadio::CODE CellularRadio::getDiagnostics(std::string& sReport) { +    // Clear the original content before using the string as a buffer. +    sReport.clear(); + +    // Determine whether the SIM card is locked to select the appropriate +    // list of commands for this radio. +    std::string sSimLockStatus; +    CODE iSimLockRet = getSimLockStatus(sSimLockStatus); + +    // Re-use the SIM status detection logic from TelitRadio::getNetworkStatus. +    // The SIM should be inserted and NOT locked. +    bool bIsSimReady = (iSimLockRet == CODE::SUCCESS +                        && sSimLockStatus != "SIM PIN" +                        && sSimLockStatus != "SIM PUK"); + +    // Determine the list of diagnostic commands required for this radio. +    const auto& vCommands = getDiagCommands(bIsSimReady); + +    // For all commands - set the maximum timeout to 2 seconds. +    const int iMaxTimeout = 2000; + +    // Allow the radio to ignore up to 2 consecutive queries before giving up. +    int iMaxNoResponseCount = 2; +    int iNoResponseCount = 0; + +    // Execute each of the commands, add their output to the report. +    for (const auto& sCmd : vCommands) { +        // First line - the command to execute. +        sReport.append(sCmd); +        sReport.push_back(ICellularRadio::CR); +        sReport.push_back(ICellularRadio::NL); + +        // Execute the command. +        std::string sResult = sendCommand(sCmd, ICellularRadio::DEFAULT_BAIL_STRINGS, iMaxTimeout); + +        // Count the number of commands ignored by the radio. +        // Normally, the radio should not ignore any of the commands, +        // but radios have their own bugs. +        if (sResult.empty()) { +            printWarning("%s| Failed to execute the [%s] command - no response from the radio in [%d] ms", getName().c_str(), sCmd.c_str(), iMaxTimeout); +            sResult = "<NO RESPONSE FROM THE RADIO>\r\n"; +            ++iNoResponseCount; +        } else { +            iNoResponseCount = 0; +        } + +        // If the radio ignored too many commands - probably it is stuck and will not +        // return to operation on its own. There is no point in waiting any longer. +        if (iNoResponseCount >= iMaxNoResponseCount) { +            printError("%s| Failed to execute the diagnostic commands - the radio has stopped responding", getName().c_str()); +            return CODE::NO_RESPONSE; +        } + +        // Append the command output to the report. +        sReport.append(sResult); +    } + +    // All commands returned a non-empty output. +    return CODE::SUCCESS; +} | 
