// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "response.hpp" #include #include namespace at { namespace response { std::optional> getTokensForATCommand(const at::Result &resp, std::string_view head) { if (resp.code == at::Result::Code::OK) { if (resp.response.size()) { for (auto el : resp.response) { if (el.compare(0, head.length(), head) == 0) { auto body = el.substr(head.length()); return utils::split(body, ","); } } } } return std::nullopt; } bool parseQPINC(const at::Result &resp, qpinc::AttemptsCounters &ret) { /// parse only first result from QPINC const std::string_view AT_QPINC_SC = "+QPINC:"; if (auto tokens = getTokensForATCommand(resp, AT_QPINC_SC); tokens) { constexpr int QPINC_TokensCount = 3; if ((*tokens).size() == QPINC_TokensCount) { utils::toNumeric((*tokens)[1], ret.PinCounter); utils::toNumeric((*tokens)[2], ret.PukCounter); return true; } } return false; } bool parseCLCK(const at::Result &resp, int &ret) { const std::string_view AT_CLCK = "+CLCK:"; if (auto tokens = getTokensForATCommand(resp, AT_CLCK); tokens) { if ((*tokens).size() != 0) { return utils::toNumeric((*tokens)[0], ret); } } return false; } bool parseCSQ(std::string response, std::string &result) { std::string toErase = "+CSQ: "; auto pos = response.find(toErase); if (pos != std::string::npos) { response.erase(pos, toErase.length()); result = response; return true; } return false; } bool parseCSQ(std::string cellularResponse, uint32_t &result) { std::string CSQstring; if (parseCSQ(cellularResponse, CSQstring)) { auto pos = CSQstring.find(','); if (pos != std::string::npos) { LOG_INFO("%s", CSQstring.c_str()); CSQstring = CSQstring.substr(0, pos); int parsedVal = 0; if (utils::toNumeric(CSQstring, parsedVal) && parsedVal >= 0) { result = parsedVal; return true; } } } return false; } namespace creg { bool isRegistered(uint32_t commandData) { // Creg command returns 1 when registered in home network, 5 when registered in roaming constexpr uint32_t registeredHome = 1; constexpr uint32_t registeredRoaming = 5; if (commandData == registeredHome || commandData == registeredRoaming) { return true; } return false; } } // namespace creg bool parseCREG(std::string &response, uint32_t &result) { auto resp = response; auto pos = resp.find(','); if (pos != std::string::npos) { auto constexpr digitLength = 1; resp = resp.substr(pos + digitLength, digitLength); int parsedVal = 0; if (utils::toNumeric(resp, parsedVal) && parsedVal >= 0) { result = parsedVal; return true; } } return false; } bool parseCREG(std::string &response, std::string &result) { std::map cregCodes; cregCodes.insert(std::pair(0, "Not registered")); cregCodes.insert(std::pair(1, "Registered, home network")); cregCodes.insert(std::pair(2, "Not registered, searching")); cregCodes.insert(std::pair(3, "Registration denied")); cregCodes.insert(std::pair(4, "Unknown")); cregCodes.insert(std::pair(5, "Registered, roaming")); uint32_t cregValue = 0; if (parseCREG(response, cregValue)) { auto cregCode = cregCodes.find(cregValue); if (cregCode != cregCodes.end()) { result = cregCode->second; return true; } } return false; } bool parseQNWINFO(std::string &response, std::string &result) { std::string toErase("+QNWINFO: "); auto pos = response.find(toErase); if (pos != std::string::npos) { response.erase(pos, toErase.length()); response.erase(std::remove(response.begin(), response.end(), '\"'), response.end()); result = response; return true; } return false; } namespace qnwinfo { uint32_t parseNetworkFrequency(std::string &response) { auto tokens = utils::split(response, ","); auto constexpr qnwinfoResponseSize = 4; auto constexpr bandTokenPos = 2; if (tokens.size() == qnwinfoResponseSize) { auto constexpr lteString = "LTE"; if (tokens[bandTokenPos].find(gsmString) != std::string::npos || tokens[bandTokenPos].find(wcdmaString) != std::string::npos) { return parseNumericBandString(tokens[bandTokenPos]); } else if (tokens[bandTokenPos].find(lteString) != std::string::npos) { return parseLteBandString(tokens[bandTokenPos]); } } return 0; } uint32_t parseNumericBandString(std::string &string) { utils::findAndReplaceAll(string, gsmString, ""); utils::findAndReplaceAll(string, wcdmaString, ""); utils::findAndReplaceAll(string, " ", ""); utils::findAndReplaceAll(string, "\"", ""); int freq = 0; utils::toNumeric(string, freq); return freq; } uint32_t parseLteBandString(std::string &string) { std::map lteFreqs; lteFreqs.insert(std::pair(band_1, band_1_freq)); lteFreqs.insert(std::pair(band_2, band_2_freq)); lteFreqs.insert(std::pair(band_3, band_3_freq)); lteFreqs.insert(std::pair(band_4, band_4_freq)); lteFreqs.insert(std::pair(band_5, band_5_freq)); lteFreqs.insert(std::pair(band_7, band_7_freq)); lteFreqs.insert(std::pair(band_8, band_8_freq)); lteFreqs.insert(std::pair(band_12, band_12_freq)); lteFreqs.insert(std::pair(band_13, band_13_freq)); lteFreqs.insert(std::pair(band_18, band_18_freq)); lteFreqs.insert(std::pair(band_20, band_20_freq)); lteFreqs.insert(std::pair(band_25, band_25_freq)); lteFreqs.insert(std::pair(band_26, band_26_freq)); lteFreqs.insert(std::pair(band_28, band_28_freq)); lteFreqs.insert(std::pair(band_38, band_38_freq)); lteFreqs.insert(std::pair(band_40, band_40_freq)); lteFreqs.insert(std::pair(band_41, band_41_freq)); auto constexpr toRemove = "LTE BAND "; auto constexpr emptyString = ""; utils::findAndReplaceAll(string, "\"", emptyString); utils::findAndReplaceAll(string, toRemove, emptyString); int band = 0; if (utils::toNumeric(string, band) && band < 0) { return 0; } auto freq = lteFreqs.find(band); if (freq != lteFreqs.end()) { return freq->second; } return 0; } } // namespace qnwinfo } // namespace response } // namespace at