~aleteoryx/muditaos

00c760233b9d355a236b44e5ca5d645f8a929530 — Pawel Olejniczak 4 years ago ed0d26d
[EGD-5783] Revert EGD-5783

Revert "EGD-5783 Exclude empty body from response message"
This reverts commit b64eb0622b6c5e59eeb2161223e793ba4164ceb9.
25 files changed, 115 insertions(+), 124 deletions(-)

M module-services/service-desktop/README.md
M module-services/service-desktop/ServiceDesktop.cpp
M module-services/service-desktop/endpoints/Context.hpp
M module-services/service-desktop/endpoints/bluetooth/README.md
M module-services/service-desktop/endpoints/calendarEvents/CalendarEventsHelper.cpp
M module-services/service-desktop/endpoints/calendarEvents/CalendarEventsHelper.hpp
M module-services/service-desktop/endpoints/calllog/CalllogHelper.cpp
M module-services/service-desktop/endpoints/calllog/CalllogHelper.hpp
M module-services/service-desktop/endpoints/contacts/ContactHelper.cpp
M module-services/service-desktop/endpoints/contacts/ContactHelper.hpp
M module-services/service-desktop/endpoints/developerMode/DeveloperModeHelper.cpp
M module-services/service-desktop/endpoints/developerMode/DeveloperModeHelper.hpp
M module-services/service-desktop/endpoints/factoryReset/FactoryReset.cpp
M module-services/service-desktop/endpoints/factoryReset/FactoryReset.hpp
M module-services/service-desktop/endpoints/messages/MessageHelper.cpp
M module-services/service-desktop/parser/HttpEnums.hpp
M module-services/service-desktop/parser/ParserUtils.hpp
M module-services/service-desktop/tests/unittest.cpp
M test/harness
M test/pytest/service-desktop/test_calendar_events.py
M test/pytest/service-desktop/test_calllog.py
M test/pytest/service-desktop/test_contacts.py
M test/pytest/service-desktop/test_messages.py
M test/pytest/service-desktop/test_templates.py
M test/pytest/service-desktop/test_threads.py
M module-services/service-desktop/README.md => module-services/service-desktop/README.md +36 -37
@@ 3,6 3,12 @@ Service Desktop

This service is handling communication between Mudita Desktop App and PurePhone.

**Note:
Service desktop is disabled by default.
To turn it on, please uncomment this line in main.cpp:**

`        ret |= sys::SystemManager::CreateService(std::make_shared<ServiceDesktop>(), sysmgr.get());
`

### Protocol description



@@ 19,8 25,11 @@ uint8_t payload[payload_length];
##### Message types
*Single printable ASCII character.*
```
endpoint = '#'
rawData = '$
enum class Type
    {
        endpoint = '#',
        rawData = '$'
    };
```
##### Payload length
*Represented by 9 printable ASCII characters.*


@@ 33,7 42,7 @@ requestPayloadJson:
     { "endpoint", endpointNumber },
     { "method", methodNumber},
     { "body", requestBodyJson },
     { "uuid", uuidNumber }
     { "uuid", uuidString }
}
```
```


@@ 42,53 51,43 @@ responsePayloadJson:
     { "endpoint", endpointNumber },
     { "status", statusCode},
     { "body", responseBodyJson },
     { "uuid", uuidNumber }
     { "uuid", uuidString }
}
```
###### Endpoint
*Each endpoint has its unique number.*

```
invalid             = 0
deviceInfo          = 1
update              = 2
filesystemUpload    = 3
backup              = 4
restore             = 5
factory             = 6
contacts            = 7
messages            = 8
calllog             = 9
calendarEvents      = 10
developerMode       = 11
bluetooth           = 12
usbSecurity         = 13
enum class Endpoint
{
    deviceInfo = 1,
    update
};
```

###### Method
*HTTP - like methods. Each has different number. Only in request message.*

```
get     = 1
post    = 2
put     = 3
del     = 4
enum class Method
{
    get = 1,
    post,
    put,
    del
};
```

###### Status
*HTTP status codes. Only in response message.*

```
OK                  = 200
Accepted            = 202
NoContent           = 204
SeeOther            = 303
BadRequest          = 400
Forbidden           = 403
NotFound            = 404
NotAcceptable       = 406
InternalServerError = 500
NotImplemented      = 501
enum class Code
{
    OK = 200,
    BadRequest = 400,
    InternalServerError = 500
};
```

###### Body


@@ 114,7 113,7 @@ get contact:
```
response:
```
#000000859{"body": [{"address": "6 Czeczota St.\n02600 Warsaw", "altName": "Bolig<0xc5><0x82>owa", "blocked": false, "favourite": true, "id": 19, "numbers": ["500639802"], "priName": "Alek"}, {"address": "6 Czeczota St.\n02600 Warsaw", "altName": "Bolig<0xc5><0x82>owa", "blocked": false, "favourite": true, "id": 22, "numbers": ["500453837"], "priName": "Gra<0xc5><0xbc>yna"}, {"address": "6 Czeczota St.\n02600 Warsaw", "altName": "Bolig<0xc5><0x82>owa", "blocked": false, "favourite": true, "id": 20, "numbers": ["500545546"], "priName": "Zofia"}, {"address": "6 Czeczota St.\n02600 Warsaw", "altName": "Bubel", "blocked": false, "favourite": true, "id": 44, "numbers": ["500087699"], "priName": "Brian"}, {"address": "6 Czeczota St.\n02600 Warsaw", "altName": "Bubel", "blocked": false, "favourite": true, "id": 43, "numbers": ["500656981"], "priName": "Cezary"}], "endpoint": 6, "status": 200, "uuid": 3}
#000000861{"body": [{"address": "6 Czeczota St.\n02600 Warsaw", "altName": "Bolig<0xc5><0x82>owa", "blocked": false, "favourite": true, "id": 19, "numbers": ["500639802"], "priName": "Alek"}, {"address": "6 Czeczota St.\n02600 Warsaw", "altName": "Bolig<0xc5><0x82>owa", "blocked": false, "favourite": true, "id": 22, "numbers": ["500453837"], "priName": "Gra<0xc5><0xbc>yna"}, {"address": "6 Czeczota St.\n02600 Warsaw", "altName": "Bolig<0xc5><0x82>owa", "blocked": false, "favourite": true, "id": 20, "numbers": ["500545546"], "priName": "Zofia"}, {"address": "6 Czeczota St.\n02600 Warsaw", "altName": "Bubel", "blocked": false, "favourite": true, "id": 44, "numbers": ["500087699"], "priName": "Brian"}, {"address": "6 Czeczota St.\n02600 Warsaw", "altName": "Bubel", "blocked": false, "favourite": true, "id": 43, "numbers": ["500656981"], "priName": "Cezary"}], "endpoint": 6, "status": 200, "uuid": "3"}
```

update contact:


@@ 123,10 122,10 @@ update contact:
```
response:
```
#000000043{"endpoint": 6, "status": 500, "uuid": 123}/
#000000057{"body": "", "endpoint": 6, "status": 500, "uuid": "123"}/
```
```
#000000043{"endpoint": 6, "status": 204, "uuid": 123}
#000000057{"body": "", "endpoint": 6, "status": 200, "uuid": "123"}
```

add contact:


@@ 135,7 134,7 @@ add contact:
```
response:
```
#000000043{"endpoint": 6, "status": 204, "uuid": 123}
#000000057{"body": "", "endpoint": 6, "status": 200, "uuid": "123"}
```

remove contact:


@@ 144,7 143,7 @@ remove contact:
```
response:
```
#000000043{"endpoint": 6, "status": 204, "uuid": 123}
#000000057{"body": "", "endpoint": 6, "status": 200, "uuid": "123"}
```

### Service documentation

M module-services/service-desktop/ServiceDesktop.cpp => module-services/service-desktop/ServiceDesktop.cpp +1 -1
@@ 158,7 158,7 @@ sys::ReturnCodes ServiceDesktop::InitHandler()
        }

        if (updateOsMsg != nullptr && updateOsMsg->messageType == updateos::UpdateMessageType::UpdateNow) {
            LOG_DEBUG("ServiceDesktop::DataReceivedHandler file:%s uuid:%" PRIu32 "",
            LOG_DEBUG("ServiceDesktop::DataReceivedHandler file:%s uuuid:%" PRIu32 "",
                      updateOsMsg->updateStats.updateFile.c_str(),
                      updateOsMsg->updateStats.uuid);


M module-services/service-desktop/endpoints/Context.hpp => module-services/service-desktop/endpoints/Context.hpp +4 -10
@@ 83,16 83,10 @@ namespace parserFSM

        virtual auto createSimpleResponse(const std::string &entryTitle = json::entries) -> std::string
        {
            const json11::Json responseJson =
                responseContext.body.is_null()
                    ? json11::Json::object{{json::endpoint, static_cast<int>(getEndpoint())},
                                           {json::status, static_cast<int>(responseContext.status)},
                                           {json::uuid, getUuid()}}
                    : json11::Json::object{{json::endpoint, static_cast<int>(getEndpoint())},
                                           {json::status, static_cast<int>(responseContext.status)},
                                           {json::uuid, getUuid()},
                                           {json::body, responseContext.body}};

            json11::Json responseJson = json11::Json::object{{json::endpoint, static_cast<int>(getEndpoint())},
                                                             {json::status, static_cast<int>(responseContext.status)},
                                                             {json::uuid, getUuid()},
                                                             {json::body, responseContext.body}};
            return buildResponseStr(responseJson.dump().size(), responseJson.dump());
        }


M module-services/service-desktop/endpoints/bluetooth/README.md => module-services/service-desktop/endpoints/bluetooth/README.md +1 -1
@@ 52,7 52,7 @@ responsePayloadJson:
    { "endpoint", endpointNumber },
    { "status", statusCode},
    { "body", responseBodyJson },
    { "uuid", uuidNumber }
    { "uuid", uuidString }
}
```
The `Bluetooth` endpoint provides responses according to the following table: 

M module-services/service-desktop/endpoints/calendarEvents/CalendarEventsHelper.cpp => module-services/service-desktop/endpoints/calendarEvents/CalendarEventsHelper.cpp +11 -12
@@ 84,7 84,7 @@ namespace parserFSM
} // namespace parserFSM
using namespace parserFSM;

auto CalendarEventsHelper::isICalEventValid(const ICalEvent &icalEvent) const -> bool
auto CalendarEventsHelper::isICalEventValid(ICalEvent icalEvent) const -> bool
{
    if (!icalEvent.event.isValid) {
        LOG_ERROR("Ical event invalid!");


@@ 197,7 197,7 @@ auto CalendarEventsHelper::icalEventFrom(const EventsRecord &record) const -> IC
    return ICalEvent{event, alarm, rrule};
}

auto CalendarEventsHelper::eventJsonObjectFrom(const EventsRecord &record) const -> json11::Json
auto CalendarEventsHelper::eventJsonObjectFrom(EventsRecord record) const -> json11::Json
{
    auto icalEvent = icalEventFrom(record);
    if (!isICalEventValid(icalEvent)) {


@@ 326,7 326,7 @@ auto CalendarEventsHelper::eventsRecordFrom(ICalEvent &icalEvent) const -> Event
    return record;
}

auto CalendarEventsHelper::ICalEventFromJson(const json11::Json &eventObj) const -> ICalEvent
auto CalendarEventsHelper::ICalEventFromJson(json11::Json eventObj) const -> ICalEvent
{
    ICalEvent icalEvent;
    icalEvent.event.setUID(eventObj[json::calendar::event::uid].string_value());


@@ 359,7 359,7 @@ auto CalendarEventsHelper::createDBEntry(Context &context) -> sys::ReturnCodes
    const auto eventsJsonObj   = context.getBody();
    const auto eventsJsonArray = eventsJsonObj[json::calendar::events].array_items();
    bool ret                   = true;
    for (const auto &event : eventsJsonArray) {
    for (auto event : eventsJsonArray) {

        auto icalEvent = ICalEventFromJson(event);



@@ 385,9 385,9 @@ auto CalendarEventsHelper::createDBEntry(Context &context) -> sys::ReturnCodes
        auto query    = std::make_unique<db::query::events::Add>(record);
        auto listener = std::make_unique<db::EndpointListener>(
            [&](db::QueryResult *result, Context context) {
                if (auto eventResult = dynamic_cast<db::query::events::AddResult *>(result)) {
                if (auto EventResult = dynamic_cast<db::query::events::AddResult *>(result)) {

                    context.setResponseStatus(eventResult->getResult() ? http::Code::OK
                    context.setResponseStatus(EventResult->getResult() ? http::Code::OK
                                                                       : http::Code::InternalServerError);

                    MessageHandler::putToSendQueue(context.createSimpleResponse());


@@ 416,7 416,7 @@ auto CalendarEventsHelper::updateDBEntry(Context &context) -> sys::ReturnCodes
    auto eventsJsonObj = context.getBody();

    bool ret = true;
    for (const auto &event : eventsJsonObj[json::calendar::events].array_items()) {
    for (auto event : eventsJsonObj[json::calendar::events].array_items()) {

        auto icalEvent = ICalEventFromJson(event);
        if (!isICalEventValid(icalEvent) || icalEvent.event.getUID().empty()) {


@@ 429,8 429,8 @@ auto CalendarEventsHelper::updateDBEntry(Context &context) -> sys::ReturnCodes
        auto query    = std::make_unique<db::query::events::EditICS>(record);
        auto listener = std::make_unique<db::EndpointListener>(
            [](db::QueryResult *result, Context context) {
                if (auto eventResult = dynamic_cast<db::query::events::EditICSResult *>(result)) {
                    context.setResponseStatus(eventResult->getResult() ? http::Code::NoContent
                if (auto EventResult = dynamic_cast<db::query::events::EditICSResult *>(result)) {
                    context.setResponseStatus(EventResult->getResult() ? http::Code::OK
                                                                       : http::Code::InternalServerError);
                    MessageHandler::putToSendQueue(context.createSimpleResponse());
                    return true;


@@ 466,9 466,8 @@ auto CalendarEventsHelper::deleteDBEntry(Context &context) -> sys::ReturnCodes
    auto query    = std::make_unique<db::query::events::RemoveICS>(UID);
    auto listener = std::make_unique<db::EndpointListener>(
        [=](db::QueryResult *result, Context context) {
            if (auto eventResult = dynamic_cast<db::query::events::RemoveICSResult *>(result)) {
                context.setResponseStatus(eventResult->getResult() ? http::Code::NoContent
                                                                   : http::Code::InternalServerError);
            if (auto EventResult = dynamic_cast<db::query::events::RemoveICSResult *>(result)) {
                context.setResponseStatus(EventResult->getResult() ? http::Code::OK : http::Code::InternalServerError);
                MessageHandler::putToSendQueue(context.createSimpleResponse());
                return true;
            }

M module-services/service-desktop/endpoints/calendarEvents/CalendarEventsHelper.hpp => module-services/service-desktop/endpoints/calendarEvents/CalendarEventsHelper.hpp +4 -4
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 29,9 29,9 @@ namespace parserFSM
        [[nodiscard]] auto repeatFrom(RecurrenceRule &rrule) const -> Repeat;
        [[nodiscard]] auto eventsRecordFrom(ICalEvent &icalEvent) const -> EventsRecord;

        [[nodiscard]] auto eventJsonObjectFrom(const EventsRecord &record) const -> json11::Json;
        [[nodiscard]] auto ICalEventFromJson(const json11::Json &eventObj) const -> ICalEvent;
        [[nodiscard]] auto isICalEventValid(const ICalEvent &event) const -> bool;
        [[nodiscard]] auto eventJsonObjectFrom(EventsRecord record) const -> json11::Json;
        [[nodiscard]] auto ICalEventFromJson(json11::Json eventObj) const -> ICalEvent;
        [[nodiscard]] auto isICalEventValid(ICalEvent event) const -> bool;

      public:
        CalendarEventsHelper(sys::Service *_ownerServicePtr) : DBHelper(_ownerServicePtr)

M module-services/service-desktop/endpoints/calllog/CalllogHelper.cpp => module-services/service-desktop/endpoints/calllog/CalllogHelper.cpp +5 -5
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "CalllogHelper.hpp"


@@ 47,7 47,7 @@ auto CalllogHelper::requestDataFromDB(Context &context) -> sys::ReturnCodes
                    auto recordsPtr = std::make_unique<std::vector<CalllogRecord>>(contactResult->getRecords());
                    json11::Json::array calllogArray;

                    for (const auto &record : *recordsPtr) {
                    for (auto record : *recordsPtr.get()) {
                        calllogArray.emplace_back(CalllogHelper::to_json(record));
                    }



@@ 102,7 102,7 @@ auto CalllogHelper::getCalllogByContactID(Context &context) -> sys::ReturnCodes
                auto records = calllogResult->getResults();
                json11::Json::array calllogArray;

                for (const auto &record : records) {
                for (auto record : records) {
                    calllogArray.emplace_back(CalllogHelper::to_json(record));
                }



@@ 133,7 133,7 @@ auto CalllogHelper::deleteDBEntry(Context &context) -> sys::ReturnCodes
        [](db::QueryResult *result, Context context) {
            if (auto calllogResult = dynamic_cast<db::query::CalllogRemoveResult *>(result)) {

                context.setResponseStatus(calllogResult->getResults() ? http::Code::NoContent
                context.setResponseStatus(calllogResult->getResults() ? http::Code::OK
                                                                      : http::Code::InternalServerError);
                MessageHandler::putToSendQueue(context.createSimpleResponse());
                return true;


@@ 151,7 151,7 @@ auto CalllogHelper::requestCount(Context &context) -> sys::ReturnCodes
{
    return sys::ReturnCodes::Unresolved;
}
auto CalllogHelper::to_json(const CalllogRecord &record) -> json11::Json
auto CalllogHelper::to_json(CalllogRecord record) -> json11::Json
{
    std::unique_ptr<std::stringstream> ss = std::make_unique<std::stringstream>();


M module-services/service-desktop/endpoints/calllog/CalllogHelper.hpp => module-services/service-desktop/endpoints/calllog/CalllogHelper.hpp +3 -3
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 27,7 27,7 @@ namespace parserFSM
    class CalllogHelper : public DBHelper
    {
      public:
        explicit CalllogHelper(sys::Service *_ownerServicePtr) : DBHelper(_ownerServicePtr){};
        CalllogHelper(sys::Service *_ownerServicePtr) : DBHelper(_ownerServicePtr){};

        auto createDBEntry(Context &context) -> sys::ReturnCodes override;
        auto requestDataFromDB(Context &context) -> sys::ReturnCodes override;


@@ 35,7 35,7 @@ namespace parserFSM
        auto deleteDBEntry(Context &context) -> sys::ReturnCodes override;

        auto requestCount(Context &context) -> sys::ReturnCodes;
        static auto to_json(const CalllogRecord &record) -> json11::Json;
        static auto to_json(CalllogRecord record) -> json11::Json;
        auto getCalllogCount(Context &context) -> sys::ReturnCodes;
        auto getCalllogByContactID(Context &context) -> sys::ReturnCodes;
    };

M module-services/service-desktop/endpoints/contacts/ContactHelper.cpp => module-services/service-desktop/endpoints/contacts/ContactHelper.cpp +7 -7
@@ 31,11 31,11 @@

using namespace parserFSM;

auto ContactHelper::to_json(const ContactRecord &record) -> json11::Json
auto ContactHelper::to_json(ContactRecord record) -> json11::Json
{
    auto numberArray = json11::Json::array();

    for (const auto &number : record.numbers) {
    for (auto number : record.numbers) {
        numberArray.emplace_back(number.number.getEntered().c_str());
    }



@@ 49,7 49,7 @@ auto ContactHelper::to_json(const ContactRecord &record) -> json11::Json
    return recordEntry;
}

auto ContactHelper::from_json(const json11::Json &contactJSON) -> ContactRecord
auto ContactHelper::from_json(json11::Json contactJSON) -> ContactRecord
{
    auto newRecord            = ContactRecord();
    newRecord.primaryName     = UTF8(contactJSON[json::contacts::primaryName].string_value());


@@ 57,7 57,7 @@ auto ContactHelper::from_json(const json11::Json &contactJSON) -> ContactRecord
    newRecord.alternativeName = UTF8(contactJSON[json::contacts::alternativeName].string_value());
    newRecord.address         = UTF8(contactJSON[json::contacts::address].string_value());

    for (const auto &num : contactJSON[json::contacts::numbers].array_items()) {
    for (auto num : contactJSON[json::contacts::numbers].array_items()) {
        utils::PhoneNumber phoneNumber(num.string_value());
        auto contactNum = ContactRecord::Number(phoneNumber.get(), phoneNumber.toE164(), ContactNumberType ::CELL);
        newRecord.numbers.push_back(contactNum);


@@ 92,7 92,7 @@ auto ContactHelper::requestDataFromDB(Context &context) -> sys::ReturnCodes
                    context.setTotalCount(contactResult->getAllLength());
                    json11::Json::array contactsArray;

                    for (const auto &record : *recordsPtr) {
                    for (const auto &record : *recordsPtr.get()) {
                        contactsArray.emplace_back(ContactHelper::to_json(record));
                    }



@@ 216,7 216,7 @@ auto ContactHelper::updateDBEntry(Context &context) -> sys::ReturnCodes
        [](db::QueryResult *result, Context context) {
            if (auto contactResult = dynamic_cast<db::query::ContactUpdateResult *>(result)) {

                context.setResponseStatus(contactResult->getResult() ? http::Code::NoContent
                context.setResponseStatus(contactResult->getResult() ? http::Code::OK
                                                                     : http::Code::InternalServerError);
                MessageHandler::putToSendQueue(context.createSimpleResponse());



@@ 243,7 243,7 @@ auto ContactHelper::deleteDBEntry(Context &context) -> sys::ReturnCodes
        [](db::QueryResult *result, Context context) {
            if (auto contactResult = dynamic_cast<db::query::ContactRemoveResult *>(result)) {

                context.setResponseStatus(contactResult->getResult() ? http::Code::NoContent
                context.setResponseStatus(contactResult->getResult() ? http::Code::OK
                                                                     : http::Code::InternalServerError);
                MessageHandler::putToSendQueue(context.createSimpleResponse());


M module-services/service-desktop/endpoints/contacts/ContactHelper.hpp => module-services/service-desktop/endpoints/contacts/ContactHelper.hpp +2 -2
@@ 38,8 38,8 @@ namespace parserFSM

        auto requestCount(Context &context) -> sys::ReturnCodes;
        auto requestContactByID(Context &context) -> sys::ReturnCodes;
        static auto to_json(const ContactRecord &record) -> json11::Json;
        static auto from_json(const json11::Json &contactJSON) -> ContactRecord;
        static auto to_json(ContactRecord record) -> json11::Json;
        static auto from_json(json11::Json contactJSON) -> ContactRecord;
    };

    namespace json::contacts

M module-services/service-desktop/endpoints/developerMode/DeveloperModeHelper.cpp => module-services/service-desktop/endpoints/developerMode/DeveloperModeHelper.cpp +2 -2
@@ 235,7 235,7 @@ bool DeveloperModeHelper::sendKeypress(bsp::KeyCodes keyCode, gui::InputEvent::S

    gui::InputEvent event(key, state, static_cast<gui::KeyCode>(keyCode));
    LOG_INFO("Sending %s", event.str().c_str());
    auto message = std::make_shared<app::AppInputEventMessage>(event);
    auto message = std::make_shared<app::AppInputEventMessage>(std::move(event));

    return owner->bus.sendUnicast(std::move(message), service::name::evt_manager);
}


@@ 265,7 265,7 @@ bool DeveloperModeHelper::requestCellularPowerStateChange(const int cellularStat
    }
    return res;
}
auto DeveloperModeHelper::smsRecordFromJson(const json11::Json &msgJson) -> SMSRecord
auto DeveloperModeHelper::smsRecordFromJson(json11::Json msgJson) -> SMSRecord
{
    auto record = SMSRecord();


M module-services/service-desktop/endpoints/developerMode/DeveloperModeHelper.hpp => module-services/service-desktop/endpoints/developerMode/DeveloperModeHelper.hpp +1 -1
@@ 27,7 27,7 @@ namespace parserFSM
        bool sendKeypress(bsp::KeyCodes keyCode, gui::InputEvent::State state);

        void requestSimChange(const int simSelected);
        auto smsRecordFromJson(const json11::Json &msgJson) -> SMSRecord;
        auto smsRecordFromJson(json11::Json msgJson) -> SMSRecord;
        bool requestCellularPowerStateChange(const int simSelected);
        bool requestServiceStateInfo(sys::Service *serv);
        auto prepareSMS(Context &context) -> ProcessResult;

M module-services/service-desktop/endpoints/factoryReset/FactoryReset.cpp => module-services/service-desktop/endpoints/factoryReset/FactoryReset.cpp +7 -7
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "FactoryReset.hpp"


@@ 28,7 28,7 @@ namespace FactoryReset
        inline constexpr auto copy_buf = 8192 * 4;
    } // namespace

    static bool CopyFile(const std::string &sourcefile, const std::string &targetfile);
    static bool CopyFile(std::string sourcefile, std::string targetfile);

    static int recurseDepth            = 0;
    static const int max_recurse_depth = 120; /* 120 is just an arbitrary value of max number of recursive calls.


@@ 70,7 70,7 @@ namespace FactoryReset
        return true;
    }

    bool DeleteDirContent(const std::string &dir)
    bool DeleteDirContent(std::string dir)
    {
        for (auto &direntry : std::filesystem::directory_iterator(dir.c_str())) {
            if ((direntry.path().string().compare(".") != 0) && (direntry.path().string().compare("..") != 0) &&


@@ 105,7 105,7 @@ namespace FactoryReset
        return true;
    }

    bool CopyDirContent(const std::string &sourcedir, const std::string &targetdir)
    bool CopyDirContent(std::string sourcedir, std::string targetdir)
    {
        if (recurseDepth >= max_recurse_depth) {
            LOG_ERROR("FactoryReset: recurse level %d (too high), error assumed, skipping restore of dir %s",


@@ 176,7 176,7 @@ namespace FactoryReset
        return true;
    }

    static bool CopyFile(const std::string &sourcefile, const std::string &targetfile)
    static bool CopyFile(std::string sourcefile, std::string targetfile)
    {
        bool ret  = true;
        auto lamb = [](std::FILE *stream) { std::fclose(stream); };


@@ 184,10 184,10 @@ namespace FactoryReset
        std::unique_ptr<std::FILE, decltype(lamb)> sf(std::fopen(sourcefile.c_str(), "r"), lamb);
        std::unique_ptr<std::FILE, decltype(lamb)> tf(std::fopen(targetfile.c_str(), "w"), lamb);

        if ((sf != nullptr) && (tf != nullptr)) {
        if ((sf.get() != nullptr) && (tf.get() != nullptr)) {
            std::unique_ptr<unsigned char[]> buffer(new unsigned char[copy_buf]);

            if (buffer != nullptr) {
            if (buffer.get() != nullptr) {
                uint32_t loopcount = (std::filesystem::file_size(sourcefile) / copy_buf) + 1u;
                uint32_t readsize  = copy_buf;


M module-services/service-desktop/endpoints/factoryReset/FactoryReset.hpp => module-services/service-desktop/endpoints/factoryReset/FactoryReset.hpp +3 -3
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 15,6 15,6 @@ namespace sys
namespace FactoryReset
{
    bool Run(sys::Service *ownerService);
    bool DeleteDirContent(const std::string &dir);
    bool CopyDirContent(const std::string &sourcedir, const std::string &targetdir);
    bool DeleteDirContent(std::string dir);
    bool CopyDirContent(std::string sourcedir, std::string targetdir);
} // namespace FactoryReset

M module-services/service-desktop/endpoints/messages/MessageHelper.cpp => module-services/service-desktop/endpoints/messages/MessageHelper.cpp +9 -9
@@ 42,7 42,7 @@ namespace parserFSM

        auto recordEntry = json11::Json::object{{json::messages::contactID, static_cast<int>(record.contactID)},
                                                {json::messages::receivedAt, static_cast<int>(record.date)},
                                                {json::messages::createdAt, static_cast<int>(record.dateSent)},
                                                {json::messages::sentAt, static_cast<int>(record.dateSent)},
                                                {json::messages::messageID, static_cast<int>(record.ID)},
                                                {json::messages::messageBody, record.body.c_str()},
                                                {json::messages::messageType, static_cast<int>(record.type)},


@@ 167,7 167,7 @@ namespace parserFSM

    auto MessageHelper::createSMS(Context &context) -> sys::ReturnCodes
    {
        context.setResponseStatus(http::Code::NotImplemented);
        context.setResponseStatus(http::Code::InternalServerError);
        MessageHandler::putToSendQueue(context.createSimpleResponse());
        return sys::ReturnCodes::Success;
    }


@@ 184,7 184,7 @@ namespace parserFSM
            [=](db::QueryResult *result, Context context) {
                if (auto smsTemplateResult = dynamic_cast<db::query::SMSRemoveResult *>(result)) {

                    context.setResponseStatus(smsTemplateResult->getResults() ? http::Code::NoContent
                    context.setResponseStatus(smsTemplateResult->getResults() ? http::Code::OK
                                                                              : http::Code::InternalServerError);
                    MessageHandler::putToSendQueue(context.createSimpleResponse());
                    return true;


@@ 240,7 240,7 @@ namespace parserFSM
            [=](db::QueryResult *result, Context context) {
                if (auto smsTemplateResult = dynamic_cast<db::query::SMSTemplateUpdateResult *>(result)) {

                    context.setResponseStatus(smsTemplateResult->getResult() ? http::Code::NoContent
                    context.setResponseStatus(smsTemplateResult->getResult() ? http::Code::OK
                                                                             : http::Code::InternalServerError);
                    MessageHandler::putToSendQueue(context.createSimpleResponse());
                    return true;


@@ 273,7 273,7 @@ namespace parserFSM
            [=](db::QueryResult *result, Context context) {
                if (auto smsTemplateResult = dynamic_cast<db::query::SMSTemplateAddResult *>(result)) {

                    context.setResponseStatus(smsTemplateResult->getResult() ? http::Code::NoContent
                    context.setResponseStatus(smsTemplateResult->getResult() ? http::Code::OK
                                                                             : http::Code::InternalServerError);
                    MessageHandler::putToSendQueue(context.createSimpleResponse());
                    return true;


@@ 305,7 305,7 @@ namespace parserFSM
            [=](db::QueryResult *result, Context context) {
                if (auto smsTemplateResult = dynamic_cast<db::query::SMSTemplateRemoveResult *>(result)) {

                    context.setResponseStatus(smsTemplateResult->getResults() ? http::Code::NoContent
                    context.setResponseStatus(smsTemplateResult->getResults() ? http::Code::OK
                                                                              : http::Code::InternalServerError);
                    MessageHandler::putToSendQueue(context.createSimpleResponse());
                    return true;


@@ 339,7 339,7 @@ namespace parserFSM
                        auto theResults = threadsResults->getResults();
                        threadsArray.reserve(theResults.size());
                        for (auto &record : theResults) {
                            threadsArray.emplace_back(MessageHelper::toJson(record));
                            threadsArray.emplace_back(MessageHelper::toJson(std::move(record)));
                        }
                        context.setResponseBody(std::move(threadsArray));
                        context.setTotalCount(threadsResults->getTotalCount());


@@ 386,7 386,7 @@ namespace parserFSM
            [=](db::QueryResult *result, Context context) {
                if (auto threadResult = dynamic_cast<db::query::MarkAsReadResult *>(result)) {

                    context.setResponseStatus(threadResult->getResult() ? http::Code::NoContent
                    context.setResponseStatus(threadResult->getResult() ? http::Code::OK
                                                                        : http::Code::InternalServerError);
                    MessageHandler::putToSendQueue(context.createSimpleResponse());
                    return true;


@@ 406,7 406,7 @@ namespace parserFSM

    auto MessageHelper::deleteThread(Context &context) -> sys::ReturnCodes
    {
        context.setResponseStatus(http::Code::NotImplemented);
        context.setResponseStatus(http::Code::InternalServerError);
        MessageHandler::putToSendQueue(context.createSimpleResponse());
        return sys::ReturnCodes::Success;
    }

M module-services/service-desktop/parser/HttpEnums.hpp => module-services/service-desktop/parser/HttpEnums.hpp +1 -3
@@ 13,14 13,12 @@ namespace parserFSM::http
    {
        OK                  = 200,
        Accepted            = 202,
        NoContent           = 204,
        SeeOther            = 303,
        BadRequest          = 400,
        Forbidden           = 403,
        NotFound            = 404,
        NotAcceptable       = 406,
        InternalServerError = 500,
        NotImplemented      = 501
        InternalServerError = 500
    };

    /*! Enum class for the HTTP methods.

M module-services/service-desktop/parser/ParserUtils.hpp => module-services/service-desktop/parser/ParserUtils.hpp +1 -1
@@ 157,7 157,7 @@ namespace parserFSM
            inline constexpr auto messageType        = "messageType";
            inline constexpr auto phoneNumber        = "phoneNumber";
            inline constexpr auto receivedAt         = "receivedAt";
            inline constexpr auto createdAt          = "createdAt";
            inline constexpr auto sentAt             = "sentAt";
            inline constexpr auto lastUsedAt         = "lastUsedAt";
            inline constexpr auto lastUpdatedAt      = "lastUpdatedAt";
            inline constexpr auto isUnread           = "isUnread";

M module-services/service-desktop/tests/unittest.cpp => module-services/service-desktop/tests/unittest.cpp +4 -3
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <endpoints/Endpoint.hpp>


@@ 217,7 217,7 @@ TEST_CASE("DB Helpers test - json encoding (messages)")
    REQUIRE(messageJson[json::messages::messageBody] == "test message");
    REQUIRE(messageJson[json::messages::contactID] == 1);
    REQUIRE(messageJson[json::messages::receivedAt] == 12345);
    REQUIRE(messageJson[json::messages::createdAt] == 54321);
    REQUIRE(messageJson[json::messages::sentAt] == 54321);
    REQUIRE(messageJson[json::messages::threadID] == 1);
    REQUIRE(messageJson[json::messages::messageID] == 10);



@@ 246,7 246,8 @@ TEST_CASE("Context class test")
        REQUIRE(context.getMethod() == http::Method::get);
        REQUIRE(context.getUuid() == 12345);
        REQUIRE(context.getEndpoint() == EndpointType::contacts);
        REQUIRE(context.createSimpleResponse() == R"(#000000045{"endpoint": 7, "status": 204, "uuid": 12345})");
        REQUIRE(context.createSimpleResponse() ==
                R"(#000000059{"body": null, "endpoint": 7, "status": 200, "uuid": 12345})");

        context.setResponseBody(context.getBody());
        REQUIRE(context.createSimpleResponse() ==

M test/harness => test/harness +1 -1
@@ 1,1 1,1 @@
Subproject commit 4315fbc4d5bb90f469b682f63e01bf703c7e43d0
Subproject commit 5e89897197e210f9fec418b0765d6234275d4069

M test/pytest/service-desktop/test_calendar_events.py => test/pytest/service-desktop/test_calendar_events.py +2 -2
@@ 1,4 1,4 @@
# Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
# Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
import pytest
from harness.interface.defs import status


@@ 91,6 91,6 @@ def test_calendar(harness):
    for ev in range(0,event_count):
        del_body = {"UID": UIDS[ev]}
        ret = harness.endpoint_request("events", "del", del_body)
        assert ret["status"] == status["NoContent"]
        assert ret["status"] == status["OK"]



M test/pytest/service-desktop/test_calllog.py => test/pytest/service-desktop/test_calllog.py +2 -2
@@ 1,4 1,4 @@
# Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
# Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
import pytest
from harness.interface.defs import status


@@ 41,7 41,7 @@ def test_calllog(harness):
    # remove exact call log
    body = {"id": calllog[0]["id"]}
    ret = harness.endpoint_request("calllog", "del", body)
    assert ret["status"] == status["NoContent"]
    assert ret["status"] == status["OK"]

    # getting the count again
    body = {"count": True}

M test/pytest/service-desktop/test_contacts.py => test/pytest/service-desktop/test_contacts.py +3 -3
@@ 1,4 1,4 @@
# Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
# Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
import pytest
from harness.interface.defs import status


@@ 93,7 93,7 @@ def test_contacts(harness):
            "priName": "Test2",
            "id": contact_id_to_update}
    ret = harness.endpoint_request("contacts", "post", body)
    assert ret["status"] == status["NoContent"]
    assert ret["status"] == status["OK"]

    # gathering updated contact
    body = {"id": contact_id_to_update}


@@ 110,7 110,7 @@ def test_contacts(harness):
    # removing added contact
    body = {"id": contact_id_to_update}
    ret = harness.endpoint_request("contacts", "del", body)
    assert ret["status"] == status["NoContent"]
    assert ret["status"] == status["OK"]

    # verifying count
    body = {"count": True}

M test/pytest/service-desktop/test_messages.py => test/pytest/service-desktop/test_messages.py +1 -1
@@ 176,7 176,7 @@ def test_remove_message(harness):
    sms_to_remove = messages[0]
    body = {"category": "message", "messageID": sms_to_remove["messageID"]}
    ret = harness.endpoint_request("messages", "del", body)
    assert ret["status"] == status["NoContent"]
    assert ret["status"] == status["OK"]

    # get messages count again
    body = {"category": "message", "count": True}

M test/pytest/service-desktop/test_templates.py => test/pytest/service-desktop/test_templates.py +3 -3
@@ 19,7 19,7 @@ class TemplatesTester:
    def __add_template(self):
        body = {"category": "template", "templateBody": self.template_body}
        ret = self.harness.endpoint_request("messages", "post", body)
        assert ret["status"] == status["NoContent"]
        assert ret["status"] == status["OK"]
        return ret

    def __get_templates(self, limit, offset):


@@ 29,7 29,7 @@ class TemplatesTester:
    def __remove_template(self, template_id):
        body = {"category": "template", "templateID": template_id}
        ret = self.harness.endpoint_request("messages", "del", body)
        assert ret["status"] == status["NoContent"]
        assert ret["status"] == status["OK"]

    def __get_all_templates(self):
        body = {"category": "template", "count": True}


@@ 100,7 100,7 @@ class TemplatesTester:
                new_template_body = "NEW TEMPLATE BODY TEST"
                body = {"category": "template", "templateID": template["templateID"], "templateBody": new_template_body}
                ret = self.harness.endpoint_request("messages", "put", body)
                assert ret["status"] == status["NoContent"]
                assert ret["status"] == status["OK"]

                # and then remove it to clean env
                self.__remove_template(template["templateID"])

M test/pytest/service-desktop/test_threads.py => test/pytest/service-desktop/test_threads.py +1 -1
@@ 27,4 27,4 @@ def test_threads(harness):
    # set thread as read
    body = {"category": "thread", "threadID": 1, "isUnread": False}
    ret = harness.endpoint_request("messages", "put", body)
    assert ret["status"] == status["NoContent"]
    assert ret["status"] == status["OK"]