From 242f97c0374edbded6bfb9d560060890d78617e6 Mon Sep 17 00:00:00 2001 From: Dawid Wojtas Date: Fri, 16 Sep 2022 08:06:04 +0200 Subject: [PATCH] [MOS-504] Mixed SMS messages Refactor the old part of SMS handler and parse the concatenated messages using std::unordered_map and std::map. Added unittest to the SMS parser. --- .../service-cellular/CMakeLists.txt | 1 + .../service-cellular/SMSParser.cpp | 114 ++++++ .../service-cellular/SMSParser.hpp | 15 + .../service-cellular/ServiceCellular.cpp | 127 ++----- .../service-cellular/ServiceCellular.hpp | 4 +- .../service-cellular/tests/CMakeLists.txt | 10 + .../tests/unittest_smsparsehandler.cpp | 355 ++++++++++++++++++ pure_changelog.md | 1 + 8 files changed, 529 insertions(+), 98 deletions(-) create mode 100644 module-services/service-cellular/SMSParser.cpp create mode 100644 module-services/service-cellular/SMSParser.hpp create mode 100644 module-services/service-cellular/tests/unittest_smsparsehandler.cpp diff --git a/module-services/service-cellular/CMakeLists.txt b/module-services/service-cellular/CMakeLists.txt index 068f4f68025d98b40a3e0eb6c62f658a10f4d8de..ea6738e4015ec1842083f0f745d2cf14cad26e1e 100644 --- a/module-services/service-cellular/CMakeLists.txt +++ b/module-services/service-cellular/CMakeLists.txt @@ -20,6 +20,7 @@ set(SOURCES CellularUrcHandler.cpp checkSmsCenter.cpp ServiceCellular.cpp + SMSParser.cpp SignalStrength.cpp NetworkSettings.cpp PacketData.cpp diff --git a/module-services/service-cellular/SMSParser.cpp b/module-services/service-cellular/SMSParser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d838bef3ff92cc9a78209877fcfb2737a8c567fe --- /dev/null +++ b/module-services/service-cellular/SMSParser.cpp @@ -0,0 +1,114 @@ +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/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 diff --git a/module-services/service-cellular/SMSParser.hpp b/module-services/service-cellular/SMSParser.hpp new file mode 100644 index 0000000000000000000000000000000000000000..de4d4dd0eb5b463054cdea7684f226ddba022f6d --- /dev/null +++ b/module-services/service-cellular/SMSParser.hpp @@ -0,0 +1,15 @@ +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include + +#include +#include + +namespace SMSParser +{ + bool parse(const std::string *smsData); + std::string getMessage(); + UTF8 getNumber(); + time_t getTime(); +}; // namespace SMSParser diff --git a/module-services/service-cellular/ServiceCellular.cpp b/module-services/service-cellular/ServiceCellular.cpp index 444954761307e51b382d4e195ad5f0a61fe2f44e..5c3e66cb2bdb297aa0719eb90b88ada8ddee09da 100644 --- a/module-services/service-cellular/ServiceCellular.cpp +++ b/module-services/service-cellular/ServiceCellular.cpp @@ -14,6 +14,7 @@ #include "service-cellular/MessageConstants.hpp" #include "service-cellular/connection-manager/ConnectionManagerCellularCommands.hpp" #include "SimCard.hpp" +#include "SMSParser.hpp" #include "NetworkSettings.hpp" #include "service-cellular/RequestFactory.hpp" #include "service-cellular/CellularRequestHandler.hpp" @@ -986,17 +987,13 @@ auto ServiceCellular::receiveSMS(std::string messageNumber) -> bool } }); - bool messageParsed = false; - - std::string messageRawBody; - UTF8 receivedNumber; const auto &cmd = at::factory(at::AT::QCMGR); - at::Result ret; + at::Result rawMessage; auto qcmgrRetries = 0; while (qcmgrRetries < at::AtCmdMaxRetries) { - ret = channel->cmd(cmd + messageNumber, cmd.getTimeout()); - if (!ret) { + rawMessage = channel->cmd(cmd + messageNumber, cmd.getTimeout()); + if (!rawMessage) { ++qcmgrRetries; LOG_ERROR("Could not read text message. Retry %d", qcmgrRetries); // There are cases where +QCMGR command is issued to soon after +CMTI URC, @@ -1010,104 +1007,44 @@ auto ServiceCellular::receiveSMS(std::string messageNumber) -> bool } } - if (!ret || qcmgrRetries == at::AtCmdMaxRetries) { + if (!rawMessage || qcmgrRetries == at::AtCmdMaxRetries) { LOG_ERROR("!!!! Could not read text message !!!!"); retVal = false; } else { - for (std::size_t i = 0; i < ret.response.size(); i++) { - if (ret.response[i].find("QCMGR") != std::string::npos) { - - std::istringstream ss(ret.response[i]); - std::string token; - std::vector tokens; - while (std::getline(ss, token, ',')) { - tokens.push_back(token); - } - tokens[1].erase(std::remove(tokens[1].begin(), tokens[1].end(), '\"'), tokens[1].end()); - /* - * 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 - * [6] - current message number - * [7] - total messages count - * - */ - // parse sender number - receivedNumber = UCS2(tokens[1]).toUTF8(); - - // parse date - tokens[3].erase(std::remove(tokens[3].begin(), tokens[3].end(), '\"'), tokens[3].end()); - - auto messageDate = std::time(nullptr); - - if (tokens.size() == 5) { - LOG_DEBUG("Single message"); - messageRawBody = ret.response[i + 1]; - messageParsed = true; + auto receivedMessages = rawMessage.response.size(); + for (std::size_t i = 0; i < receivedMessages; i++) { + bool messageParsed = SMSParser::parse(&rawMessage.response[i]); + if (messageParsed) { + UTF8 decodedMessage; + UTF8 smsNumber = SMSParser::getNumber(); + std::string smsMessage = SMSParser::getMessage(); + + const std::string decodedStr = utils::hexToBytes(smsMessage); + const auto mmsNotificationOpt = pdu::parse(decodedStr); + if (mmsNotificationOpt) { + std::string number = numberFromAddress(mmsNotificationOpt->fromAddress); + // NOTE: number may be empty + decodedMessage = UTF8("[MMS]"); + smsNumber = UTF8(number); } - else if (tokens.size() == 8) { - LOG_DEBUG("Concatenated message"); - uint32_t last = 0; - uint32_t current = 0; - try { - last = std::stoi(tokens[7]); - current = std::stoi(tokens[6]); - } - catch (const std::exception &e) { - LOG_ERROR("ServiceCellular::receiveSMS error %s", e.what()); - retVal = false; - break; - } - LOG_DEBUG("part %" PRIu32 "from %" PRIu32, current, last); - if (current == last) { - messageParts.push_back(ret.response[i + 1]); - - for (std::size_t j = 0; j < messageParts.size(); j++) { - messageRawBody += messageParts[j]; - } - messageParts.clear(); - messageParsed = true; - } - else { - messageParts.push_back(ret.response[i + 1]); - } + + if (decodedMessage.empty()) { + decodedMessage = UCS2(smsMessage).toUTF8(); } - if (messageParsed) { - messageParsed = false; - - UTF8 decodedMessage; - - const std::string decodedStr = utils::hexToBytes(messageRawBody); - const auto mmsNotificationOpt = pdu::parse(decodedStr); - if (mmsNotificationOpt) { - std::string number = numberFromAddress(mmsNotificationOpt->fromAddress); - // NOTE: number may be empty - decodedMessage = UTF8("[MMS]"); - receivedNumber = UTF8(number); - } - - if (decodedMessage.empty()) { - decodedMessage = UCS2(messageRawBody).toUTF8(); - } - - const auto record = createSMSRecord(decodedMessage, receivedNumber, messageDate); - - if (!dbAddSMSRecord(record)) { - LOG_ERROR("Failed to add text message to db"); - retVal = false; - break; - } + smsMessage.clear(); + + auto messageDate = SMSParser::getTime(); + const auto record = createSMSRecord(decodedMessage, smsNumber, messageDate); + + if (!dbAddSMSRecord(record)) { + LOG_ERROR("Failed to add text message to db"); + retVal = false; + break; } } } } - return retVal; } diff --git a/module-services/service-cellular/service-cellular/ServiceCellular.hpp b/module-services/service-cellular/service-cellular/ServiceCellular.hpp index 27fc5421e71832e01f18aac414dfb258e7096b88..3f9e5eee6eecd47a14c4291fda0be9e3b2d2e7a7 100644 --- a/module-services/service-cellular/service-cellular/ServiceCellular.hpp +++ b/module-services/service-cellular/service-cellular/ServiceCellular.hpp @@ -133,8 +133,6 @@ class ServiceCellular : public sys::Service /// URC GSM notification handler std::optional> identifyNotification(const std::string &data); - std::vector messageParts; - std::unique_ptr ongoingCall; std::vector tetheringCalllog; @@ -203,7 +201,7 @@ class ServiceCellular : public sys::Service [[nodiscard]] bool receiveAllMessages(); /// @} - bool transmitDtmfTone(DTMFCode digit); + bool transmitDtmfTone(DTMFCode code); /// Handle message CellularGetChannelMessage void handle_CellularGetChannelMessage(); diff --git a/module-services/service-cellular/tests/CMakeLists.txt b/module-services/service-cellular/tests/CMakeLists.txt index 0b744c193c76d3e756065f6b341487b96fabf8da..3e62ee64a5534efcc7ba9a61d056ef1b40c4ffa0 100644 --- a/module-services/service-cellular/tests/CMakeLists.txt +++ b/module-services/service-cellular/tests/CMakeLists.txt @@ -37,6 +37,16 @@ add_catch2_executable( ucs2 ) +add_catch2_executable( + NAME + cellular-smsParseHandler + SRCS + unittest_smsparsehandler.cpp + LIBS + module-cellular + ucs2 +) + add_catch2_executable( NAME cellular-datatransfer diff --git a/module-services/service-cellular/tests/unittest_smsparsehandler.cpp b/module-services/service-cellular/tests/unittest_smsparsehandler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a1f539ff8d3484451e53aac2454b61aad97288fb --- /dev/null +++ b/module-services/service-cellular/tests/unittest_smsparsehandler.cpp @@ -0,0 +1,355 @@ +// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include +#include +#include +#include + +TEST_CASE("SMSParseHandler functionality") +{ + auto prepareQCMGRFrame = + [](const UCS2 &number, std::uint16_t uid = 0, std::uint8_t current = 0, std::uint8_t total = 0) { + std::string qcmgrFrame = + R"(+QCMGR: "REC UNREAD",")" + std::string(number.str()) + R"(",,"22/09/16,14:49:11+08")"; + if (uid > 0) { + qcmgrFrame += "," + std::to_string(uid) + "," + std::to_string(current) + "," + std::to_string(total); + } + return qcmgrFrame; + }; + + SECTION("Prepare single sms frame") + { + UTF8 number("+48123456789"); + UCS2 ucs2number(number); + std::string qcmgr = + R"(+QCMGR: "REC UNREAD","002B00340038003100320033003400350036003700380039",,"22/09/16,14:49:11+08")"; + + REQUIRE(prepareQCMGRFrame(ucs2number) == qcmgr); + } + + SECTION("Prepare multiple sms frame") + { + UTF8 number("+48123456789"); + UCS2 ucs2number(number); + std::string qcmgr = + R"(+QCMGR: "REC UNREAD","002B00340038003100320033003400350036003700380039",,"22/09/16,14:49:11+08",79,2,4)"; + + REQUIRE(prepareQCMGRFrame(ucs2number, 79, 2, 4) == qcmgr); + } + + SECTION("Wrong response") + { + std::vector resp; + resp.emplace_back("Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris."); + at::Result result(at::Result::Code::OK, resp); + + bool messageParsed = SMSParser::parse(&result.response[0]); + REQUIRE_FALSE(messageParsed); + } + + SECTION("Single SMS") + { + UTF8 number("+48123456789"); + UTF8 message("Hello World 1234567890 +-*/="); + UCS2 ucs2number(number); + + std::vector resp; + resp.emplace_back(prepareQCMGRFrame(ucs2number)); + resp.emplace_back(std::string(UCS2(message).str())); + at::Result result(at::Result::Code::OK, resp); + + bool messageParsed = SMSParser::parse(&result.response[0]); + REQUIRE(messageParsed); + + UTF8 decodedNumber = UCS2(SMSParser::getNumber()).toUTF8(); + REQUIRE(decodedNumber == number); + + UTF8 decodedMessage = UCS2(SMSParser::getMessage()).toUTF8(); + REQUIRE(decodedMessage == message); + } + + SECTION("Concatenated SMS") + { + UTF8 number("+01222333444"); + UCS2 ucs2number(number); + + UTF8 message1("Lorem ipsum dolor sit amet, consectetur adipiscing elit"); + UTF8 message2(", sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + UTF8 message3("Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea " + "commodo consequat."); + UTF8 message4( + "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."); + + std::vector resp; + resp.emplace_back(prepareQCMGRFrame(ucs2number, 34, 1, 4)); + resp.emplace_back(std::string(UCS2(message1).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number, 34, 2, 4)); + resp.emplace_back(std::string(UCS2(message2).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number, 34, 3, 4)); + resp.emplace_back(std::string(UCS2(message3).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number, 34, 4, 4)); + resp.emplace_back(std::string(UCS2(message4).str())); + at::Result result(at::Result::Code::OK, resp); + + for (size_t i = 0; i < resp.size(); ++i) { + bool messageParsed = SMSParser::parse(&result.response[i]); + (void)messageParsed; + } + + UTF8 decodedNumber = UCS2(SMSParser::getNumber()).toUTF8(); + REQUIRE(decodedNumber == number); + + UTF8 decodedMessage = UCS2(SMSParser::getMessage()).toUTF8(); + UTF8 message = message1 + message2 + message3 + message4; + REQUIRE(decodedMessage == message); + } + + SECTION("Concatenated and single in the middle SMS") + { + UTF8 number1("+01222333444"); + UCS2 ucs2number1(number1); + + UTF8 message11("Excepteur sint occaecat cupidatat non proident,"); + UTF8 message12("sunt in culpa qui officia deserunt mollit anim id est laborum."); + UTF8 message13("Sed ut perspiciatis unde omnis iste natus error sit voluptatem"); + + UTF8 number2("+99000111222"); + UCS2 ucs2number2(number2); + UTF8 message21("Totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae " + "vitae dicta sunt explicabo"); + + std::vector resp; + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 34, 1, 3)); + resp.emplace_back(std::string(UCS2(message11).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 34, 2, 3)); + resp.emplace_back(std::string(UCS2(message12).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number2)); + resp.emplace_back(std::string(UCS2(message21).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 34, 3, 3)); + resp.emplace_back(std::string(UCS2(message13).str())); + at::Result result(at::Result::Code::OK, resp); + + for (size_t i = 0; i < resp.size(); ++i) { + bool messageParsed = SMSParser::parse(&result.response[i]); + if (messageParsed) { + UTF8 decodedMessage = UCS2(SMSParser::getMessage()).toUTF8(); + UTF8 decodedNumber = UCS2(SMSParser::getNumber()).toUTF8(); + if (decodedNumber == number1) { + UTF8 message = message11 + message12 + message13; + REQUIRE(decodedMessage == message); + } + else if (decodedNumber == number2) { + REQUIRE(decodedMessage == message21); + } + } + } + } + + SECTION("Mixed two concatenated SMS") + { + UTF8 number1("+2334567812"); + UCS2 ucs2number1(number1); + UTF8 message11("Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit,"); + UTF8 message12("sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt."); + UTF8 message13("Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur,"); + UTF8 message14("adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam " + "aliquam quaerat voluptatem."); + UTF8 message15("Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam,"); + UTF8 message16(" nisi ut aliquid ex ea commodi consequatur?"); + + UTF8 number2("+12998877661"); + UCS2 ucs2number2(number2); + UTF8 message21( + "Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur,"); + UTF8 message22("vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"); + UTF8 message23("At vero eos et accusamus et iusto odio dignissimos ducimus qui "); + UTF8 message24("blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias"); + UTF8 message25("excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia " + "deserunt mollitia animi"); + + std::vector resp; + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 12, 1, 6)); + resp.emplace_back(std::string(UCS2(message11).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 12, 2, 6)); + resp.emplace_back(std::string(UCS2(message12).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number2, 56, 1, 5)); + resp.emplace_back(std::string(UCS2(message21).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number2, 56, 2, 5)); + resp.emplace_back(std::string(UCS2(message22).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 12, 3, 6)); + resp.emplace_back(std::string(UCS2(message13).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number2, 56, 3, 5)); + resp.emplace_back(std::string(UCS2(message23).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number2, 56, 4, 5)); + resp.emplace_back(std::string(UCS2(message24).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number2, 56, 5, 5)); + resp.emplace_back(std::string(UCS2(message25).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 12, 4, 6)); + resp.emplace_back(std::string(UCS2(message14).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 12, 5, 6)); + resp.emplace_back(std::string(UCS2(message15).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 12, 6, 6)); + resp.emplace_back(std::string(UCS2(message16).str())); + at::Result result(at::Result::Code::OK, resp); + + for (size_t i = 0; i < resp.size(); ++i) { + bool messageParsed = SMSParser::parse(&result.response[i]); + if (messageParsed) { + UTF8 decodedMessage = UCS2(SMSParser::getMessage()).toUTF8(); + UTF8 decodedNumber = UCS2(SMSParser::getNumber()).toUTF8(); + if (decodedNumber == number1) { + UTF8 message = message11 + message12 + message13 + message14 + message15 + message16; + REQUIRE(decodedMessage == message); + } + else if (decodedNumber == number2) { + UTF8 message = message21 + message22 + message23 + message24 + message25; + REQUIRE(decodedMessage == message); + } + } + } + } + + SECTION("Mixed order of two concatenated SMS") + { + UTF8 number1("+2334567812"); + UCS2 ucs2number1(number1); + UTF8 message11("Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit,"); + UTF8 message12("sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt."); + UTF8 message13("Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur,"); + UTF8 message14("adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam " + "aliquam quaerat voluptatem."); + UTF8 message15("Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam,"); + UTF8 message16(" nisi ut aliquid ex ea commodi consequatur?"); + + UTF8 number2("+12998877661"); + UCS2 ucs2number2(number2); + UTF8 message21( + "Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur,"); + UTF8 message22("vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"); + UTF8 message23("At vero eos et accusamus et iusto odio dignissimos ducimus qui "); + UTF8 message24("blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias"); + UTF8 message25("excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia " + "deserunt mollitia animi"); + + std::vector resp; + resp.emplace_back(prepareQCMGRFrame(ucs2number2, 56, 3, 5)); + resp.emplace_back(std::string(UCS2(message23).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 12, 2, 6)); + resp.emplace_back(std::string(UCS2(message12).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 12, 6, 6)); + resp.emplace_back(std::string(UCS2(message16).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 12, 3, 6)); + resp.emplace_back(std::string(UCS2(message13).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number2, 56, 4, 5)); + resp.emplace_back(std::string(UCS2(message24).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number2, 56, 5, 5)); + resp.emplace_back(std::string(UCS2(message25).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number2, 56, 2, 5)); + resp.emplace_back(std::string(UCS2(message22).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 12, 5, 6)); + resp.emplace_back(std::string(UCS2(message15).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number2, 56, 1, 5)); + resp.emplace_back(std::string(UCS2(message21).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 12, 4, 6)); + resp.emplace_back(std::string(UCS2(message14).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 12, 1, 6)); + resp.emplace_back(std::string(UCS2(message11).str())); + + at::Result result(at::Result::Code::OK, resp); + + for (size_t i = 0; i < resp.size(); ++i) { + bool messageParsed = SMSParser::parse(&result.response[i]); + if (messageParsed) { + UTF8 decodedMessage = UCS2(SMSParser::getMessage()).toUTF8(); + UTF8 decodedNumber = UCS2(SMSParser::getNumber()).toUTF8(); + if (decodedNumber == number1) { + UTF8 message = message11 + message12 + message13 + message14 + message15 + message16; + REQUIRE(decodedMessage == message); + } + else if (decodedNumber == number2) { + UTF8 message = message21 + message22 + message23 + message24 + message25; + REQUIRE(decodedMessage == message); + } + } + } + } + + SECTION("Mixed concatenated and single SMS") + { + UTF8 number1("+2334567812"); + UCS2 ucs2number1(number1); + UTF8 message11("Id est laborum et dolorum fuga."); + UTF8 message12("Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id"); + UTF8 message13("quod maxime placeat facere possimus, omnis voluptas assumenda est."); + + UTF8 number2("+12998877661"); + UCS2 ucs2number2(number2); + UTF8 message21("Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet"); + UTF8 message22("ut et voluptates repudiandae sint et molestiae non recusandae."); + UTF8 message23("Itaque earum rerum hic tenetur a sapiente delectus,"); + UTF8 message24( + " ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."); + + UTF8 number3("+67453423143"); + UCS2 ucs2number3(number3); + UTF8 message3("Aenean magna ligula, hendrerit non tristique sed, auctor id ex."); + + UTF8 number4("+89010203040"); + UCS2 ucs2number4(number4); + UTF8 message4( + "Donec tincidunt nibh at odio iaculis accumsan. Aliquam mollis metus vitae mauris molestie scelerisque."); + + UTF8 number5("+00010020030"); + UCS2 ucs2number5(number5); + UTF8 message5("Et harum quidem rerum facilis est et expedita distinctio."); + + std::vector resp; + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 12, 1, 6)); + resp.emplace_back(std::string(UCS2(message11).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 12, 2, 6)); + resp.emplace_back(std::string(UCS2(message12).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number2, 56, 1, 5)); + resp.emplace_back(std::string(UCS2(message21).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number2, 56, 2, 5)); + resp.emplace_back(std::string(UCS2(message22).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number4)); + resp.emplace_back(std::string(UCS2(message4).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number1, 12, 3, 6)); + resp.emplace_back(std::string(UCS2(message13).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number2, 56, 3, 5)); + resp.emplace_back(std::string(UCS2(message23).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number3)); + resp.emplace_back(std::string(UCS2(message3).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number2, 56, 4, 5)); + resp.emplace_back(std::string(UCS2(message24).str())); + resp.emplace_back(prepareQCMGRFrame(ucs2number5)); + resp.emplace_back(std::string(UCS2(message5).str())); + at::Result result(at::Result::Code::OK, resp); + + for (size_t i = 0; i < resp.size(); ++i) { + bool messageParsed = SMSParser::parse(&result.response[i]); + if (messageParsed) { + UTF8 decodedMessage = UCS2(SMSParser::getMessage()).toUTF8(); + UTF8 decodedNumber = UCS2(SMSParser::getNumber()).toUTF8(); + if (decodedNumber == number1) { + UTF8 message = message11 + message12 + message13; + REQUIRE(decodedMessage == message); + } + else if (decodedNumber == number2) { + UTF8 message = message21 + message22 + message23 + message24; + REQUIRE(decodedMessage == message); + } + else if (decodedNumber == number3) { + REQUIRE(decodedMessage == message3); + } + else if (decodedNumber == number4) { + REQUIRE(decodedMessage == message4); + } + else if (decodedNumber == number5) { + REQUIRE(decodedMessage == message5); + } + } + } + } +} diff --git a/pure_changelog.md b/pure_changelog.md index 7620417fc554997e42dbf466540b9b37c10eef90..70d78c2ac531c2caf918030b3a2ef97f1f2afe7d 100644 --- a/pure_changelog.md +++ b/pure_changelog.md @@ -8,6 +8,7 @@ * Separated system volume from Bluetooth device volume for A2DP ### Fixed +* Fixed mixed SMS messages * Fixed disappearing manual alarm and vibration volume setting in German * Fixed the accessibility of user files by MTP * Fixed SIM card pop-ups not showing