// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/blob/master/LICENSE.md #include "SMSParser.hpp" #include #include #include #include #include #include #include #include namespace SMSParser { namespace { static constexpr auto SMSReadMsgName = "QCMGR"; static constexpr auto SingleMessageLength = 5; static constexpr auto MultipleMessageLength = 8; std::unordered_map> concatenatedMessage; std::string message; UTF8 number; } // namespace bool parse(const std::string *smsData) { bool parsed = false; if (smsData[0].find(SMSReadMsgName) == std::string::npos) { return parsed; } std::istringstream ss(smsData[0]); std::string token; std::vector tokens; while (std::getline(ss, token, ',')) { tokens.push_back(token); } /* * tokens: * [0] - +QCMGR * [1] - sender number * [2] - none * [3] - date YY/MM/DD * [4] - hour HH/MM/SS/timezone * concatenaded messages * [5] - unique concatenated message id (range: 0-65535) * [6] - current message number * [7] - total messages count */ tokens[1].erase(std::remove(tokens[1].begin(), tokens[1].end(), '\"'), tokens[1].end()); number = UCS2(tokens[1]).toUTF8(); // parse date tokens[3].erase(std::remove(tokens[3].begin(), tokens[3].end(), '\"'), tokens[3].end()); if (tokens.size() == SingleMessageLength) { LOG_DEBUG("Single message"); message = smsData[1]; parsed = true; } else if (tokens.size() == MultipleMessageLength) { std::uint32_t smsId = 0; std::uint32_t current = 0; std::uint32_t total = 0; try { smsId = std::stoi(tokens[5]); current = std::stoi(tokens[6]); total = std::stoi(tokens[7]); } catch (const std::exception &e) { LOG_ERROR("Parse SMS error %s", e.what()); parsed = false; return parsed; } concatenatedMessage[smsId][current] = smsData[1]; auto receivedConcatenatedMessages = concatenatedMessage[smsId].size(); LOG_DEBUG("Concatenated message uid: %" PRIu32 " rcv: %zu [%" PRIu32 "/%" PRIu32 "]", smsId, receivedConcatenatedMessages, current, total); if (receivedConcatenatedMessages == total) { message.clear(); for (const auto &[_, smsMessageCat] : concatenatedMessage[smsId]) { message += smsMessageCat; } concatenatedMessage.erase(smsId); parsed = true; } } return parsed; } UTF8 getNumber() { return number; } std::string getMessage() { return message; } time_t getTime() { return std::time(nullptr); } } // namespace SMSParser