// 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 <Utils.hpp>
#include <algorithm>
namespace at
{
namespace response
{
std::optional<std::vector<std::string>> 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<uint32_t, std::string> cregCodes;
cregCodes.insert(std::pair<uint32_t, std::string>(0, "Not registered"));
cregCodes.insert(std::pair<uint32_t, std::string>(1, "Registered, home network"));
cregCodes.insert(std::pair<uint32_t, std::string>(2, "Not registered, searching"));
cregCodes.insert(std::pair<uint32_t, std::string>(3, "Registration denied"));
cregCodes.insert(std::pair<uint32_t, std::string>(4, "Unknown"));
cregCodes.insert(std::pair<uint32_t, std::string>(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<uint32_t, uint32_t> lteFreqs;
lteFreqs.insert(std::pair<uint32_t, uint32_t>(band_1, band_1_freq));
lteFreqs.insert(std::pair<uint32_t, uint32_t>(band_2, band_2_freq));
lteFreqs.insert(std::pair<uint32_t, uint32_t>(band_3, band_3_freq));
lteFreqs.insert(std::pair<uint32_t, uint32_t>(band_4, band_4_freq));
lteFreqs.insert(std::pair<uint32_t, uint32_t>(band_5, band_5_freq));
lteFreqs.insert(std::pair<uint32_t, uint32_t>(band_7, band_7_freq));
lteFreqs.insert(std::pair<uint32_t, uint32_t>(band_8, band_8_freq));
lteFreqs.insert(std::pair<uint32_t, uint32_t>(band_12, band_12_freq));
lteFreqs.insert(std::pair<uint32_t, uint32_t>(band_13, band_13_freq));
lteFreqs.insert(std::pair<uint32_t, uint32_t>(band_18, band_18_freq));
lteFreqs.insert(std::pair<uint32_t, uint32_t>(band_20, band_20_freq));
lteFreqs.insert(std::pair<uint32_t, uint32_t>(band_25, band_25_freq));
lteFreqs.insert(std::pair<uint32_t, uint32_t>(band_26, band_26_freq));
lteFreqs.insert(std::pair<uint32_t, uint32_t>(band_28, band_28_freq));
lteFreqs.insert(std::pair<uint32_t, uint32_t>(band_38, band_38_freq));
lteFreqs.insert(std::pair<uint32_t, uint32_t>(band_40, band_40_freq));
lteFreqs.insert(std::pair<uint32_t, uint32_t>(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