~aleteoryx/muditaos

6851c04e12413ca981a634f51cbee2222c6b4812 — Maciej Janicki 4 years ago dfa1d51
[EGD-5976] Add tethering cellular disabling

This commit adds disabling of URC messages during
tethering mode. It also adds call and sms logging after
tethering is disabled.
M module-cellular/at/Commands.hpp => module-cellular/at/Commands.hpp +16 -8
@@ 31,7 31,7 @@ namespace at
        URC_DELAY_ON,               /// Enable delay the output of URC indication until ring indicator pulse ends
        URC_UART1,                  /// Route URCs to UART1
        AT_PIN_READY_LOGIC,         /// Configure AP_Ready pin logic ( enable, logic level 1, 200ms )
        URC_NOTIF_SIGNAL,           /// Turn on signal strength change URC
        CSQ_URC_ON,                 /// Turn on signal strength change URC
        CRC_ON,                     /// Change incoming call notification from "RING" to "+CRING:type"
        CALLER_NUMBER_PRESENTATION, /// Turn on caller's number presentation
        SMS_TEXT_FORMAT,            /// Set Message format to Text


@@ 54,13 54,14 @@ namespace at
        CNUM, /// doc: the command can get the subscribers own number(s) from the (U)SI
        CIMI, /// Its getting IMSI from selected SIM card
        QCMGR,
        ATH,  /// hangup
        ATA,  /// (doc): timeout should be possibly set up to 90s
        ATD,  /// setup call
        IPR,  /// set baudrate
        CMUX, /// setup cmux params
        CFUN, /// set phone functionality
        CMGS, /// sms
        ATH,       /// hangup
        QHUP_BUSY, /// hangup all calls with busy reason
        ATA,       /// (doc): timeout should be possibly set up to 90s
        ATD,       /// setup call
        IPR,       /// set baudrate
        CMUX,      /// setup cmux params
        CFUN,      /// set phone functionality
        CMGS,      /// sms
        QCMGS,
        CREG,       /// network registration status
        QNWINFO,    /// network informations (band etc)


@@ 126,6 127,13 @@ namespace at
        QMBNCFG,  /// Quectel command for MBN files management
        QCFG_IMS, /// Set/Get IP Multimedia Services, get state of VoLTE
        QEEC,     /// Echo cancellation parameters
        RING_URC_OFF,
        RING_URC_ON,
        CSQ_URC_OFF,
        SMS_URC_OFF,
        SMS_URC_ON,
        ACT_URC_OFF,
        ACT_URC_ON,
    };

    enum class commadsSet

M module-cellular/at/src/ATFactory.cpp => module-cellular/at/src/ATFactory.cpp +12 -2
@@ 24,7 24,8 @@ namespace at
        {AT::URC_DELAY_ON, {"AT+QCFG=\"urc/delay\",1"}},
        {AT::URC_UART1, {"AT+QURCCFG=\"urcport\",\"uart1\""}},
        {AT::AT_PIN_READY_LOGIC, {"AT+QCFG=\"apready\",1,1,200"}},
        {AT::URC_NOTIF_SIGNAL, {"AT+QINDCFG=\"csq\",1"}},
        {AT::CSQ_URC_ON, {"AT+QINDCFG=\"csq\",1"}},
        {AT::CSQ_URC_OFF, {"AT+QINDCFG=\"csq\",0"}},
        {AT::CRC_ON, {"AT+CRC=1"}},
        {AT::CALLER_NUMBER_PRESENTATION, {"AT+CLIP=1", default_long_timeout}},
        {AT::SMS_TEXT_FORMAT, {"AT+CMGF=1"}},


@@ 41,6 42,7 @@ namespace at
        {AT::CIMI, {"AT+CIMI"}},
        {AT::QCMGR, {"AT+QCMGR=", 180s}},
        {AT::ATH, {"ATH", 100s}},
        {AT::QHUP_BUSY, {"AT+QHUP=17", 100s}},
        {AT::ATA, {"ATA", 100s}},
        {AT::ATD, {"ATD", 6s}},
        {AT::IPR, {"AT+IPR="}},


@@ 110,7 112,15 @@ namespace at
        {AT::QNVFR, {"AT+QNVFR=", default_long_timeout}},
        {AT::QNVFW, {"AT+QNVFW=", default_long_timeout}},
        {AT::QMBNCFG, {"AT+QMBNCFG=", default_long_timeout}},
        {AT::QCFG_IMS, {"AT+QCFG=\"ims\""}}};
        {AT::QCFG_IMS, {"AT+QCFG=\"ims\""}},
        {AT::RING_URC_ON, {"AT+QINDCFG=\"ring\",1"}},
        {AT::RING_URC_OFF, {"AT+QINDCFG=\"ring\",0"}},
        {AT::ACT_URC_OFF, {"AT+QINDCFG=\"act\",0"}},
        {AT::ACT_URC_ON, {"AT+QINDCFG=\"act\",1"}},
        {AT::SMS_URC_ON, {"AT+QINDCFG=\"smsincoming\",1"}},
        {AT::SMS_URC_OFF, {"AT+QINDCFG=\"smsincoming\",0"}},

    };

    auto factory(AT at) -> const Cmd &
    {

M module-cellular/at/src/Commands.cpp => module-cellular/at/src/Commands.cpp +2 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <Commands.hpp>


@@ 19,7 19,7 @@ namespace at
            ret.push_back(AT::URC_DELAY_ON);
            ret.push_back(AT::URC_UART1);
            ret.push_back(AT::AT_PIN_READY_LOGIC);
            ret.push_back(AT::URC_NOTIF_SIGNAL);
            ret.push_back(AT::CSQ_URC_ON);
            break;
        case commadsSet::simInit:
            ret.push_back(AT::CALLER_NUMBER_PRESENTATION);

M module-db/CMakeLists.txt => module-db/CMakeLists.txt +1 -0
@@ 98,6 98,7 @@ set(SOURCES
        queries/calllog/QueryCalllogGetByContactID.cpp
        queries/notifications/QueryNotificationsGet.cpp
        queries/notifications/QueryNotificationsIncrement.cpp
        queries/notifications/QueryNotificationsMultipleIncrement.cpp
        queries/notifications/QueryNotificationsClear.cpp
        queries/notifications/QueryNotificationsGetAll.cpp
        queries/phonebook/QueryContactGet.cpp

M module-db/Interface/CalllogRecord.cpp => module-db/Interface/CalllogRecord.cpp +5 -1
@@ 25,6 25,10 @@ CalllogRecord::CalllogRecord(const CalllogTableRow &tableRow)
      phoneNumber(utils::PhoneNumber(tableRow.number, tableRow.e164number).getView()), isRead(tableRow.isRead)
{}

CalllogRecord::CalllogRecord(const CallType type, const utils::PhoneNumber::View &number)
    : presentation(PresentationType::PR_UNKNOWN), date(std::time(nullptr)), type(type), phoneNumber(number)
{}

uint32_t CalllogRecord::getContactId() const
{
    return contactId;


@@ 54,7 58,7 @@ CalllogRecordInterface::CalllogRecordInterface(CalllogDB *calllogDb, ContactsDB 

bool CalllogRecordInterface::Add(const CalllogRecord &rec)
{
    auto localRec      = rec;
    auto localRec = rec;
    if (!rec.phoneNumber.getFormatted().empty()) {
        ContactRecordInterface contactInterface(contactsDB);
        auto contactMatch =

M module-db/Interface/CalllogRecord.hpp => module-db/Interface/CalllogRecord.hpp +2 -1
@@ 29,7 29,8 @@ struct CalllogRecord : public Record
    friend std::ostream &operator<<(std::ostream &out, const CalllogRecord &point);
    [[nodiscard]] std::string str() const;

    CalllogRecord()  = default;
    CalllogRecord() = default;
    CalllogRecord(const CallType type, const utils::PhoneNumber::View &number);
    CalllogRecord(const CalllogTableRow &tableRow);

    uint32_t getContactId() const;

M module-db/Interface/NotificationsRecord.cpp => module-db/Interface/NotificationsRecord.cpp +54 -17
@@ 4,6 4,7 @@
#include "NotificationsRecord.hpp"
#include "module-db/queries/notifications/QueryNotificationsGet.hpp"
#include "module-db/queries/notifications/QueryNotificationsIncrement.hpp"
#include "module-db/queries/notifications/QueryNotificationsMultipleIncrement.hpp"
#include "module-db/queries/notifications/QueryNotificationsClear.hpp"
#include "module-db/queries/notifications/QueryNotificationsGetAll.hpp"
#include "Databases/NotificationsDB.hpp"


@@ 147,6 148,9 @@ std::unique_ptr<db::QueryResult> NotificationsRecordInterface::runQuery(std::sha
    if (const auto local_query = dynamic_cast<const db::query::notifications::Increment *>(query.get())) {
        return runQueryImpl(local_query);
    }
    if (const auto local_query = dynamic_cast<const db::query::notifications::MultipleIncrement *>(query.get())) {
        return runQueryImpl(local_query);
    }
    if (const auto local_query = dynamic_cast<const db::query::notifications::Clear *>(query.get())) {
        return runQueryImpl(local_query);
    }


@@ 166,25 170,26 @@ std::unique_ptr<db::query::notifications::GetResult> NotificationsRecordInterfac
std::unique_ptr<db::query::notifications::IncrementResult> NotificationsRecordInterface::runQueryImpl(
    const db::query::notifications::Increment *query)
{
    auto ret = false;
    if (auto record = GetByKey(query->getKey()); record.isValid()) {
        auto &currentContactRecord = record.contactRecord;
        if (auto numberMatch = contactsDb->MatchByNumber(query->getNumber()); numberMatch.has_value()) {
            if (record.value == 0) {
                currentContactRecord = std::move(numberMatch.value().contact);
            }
            else if (currentContactRecord.has_value() &&
                     numberMatch.value().contactId != currentContactRecord.value().ID) {
                currentContactRecord.reset();
            }
        }
        else {
            currentContactRecord.reset();
    auto ret = processIncrement(query->getKey(), query->getNumber(), 1);

    return std::make_unique<db::query::notifications::IncrementResult>(ret);
}

std::unique_ptr<db::query::notifications::MultipleIncrementResult> NotificationsRecordInterface::runQueryImpl(
    const db::query::notifications::MultipleIncrement *query)
{
    auto ret            = false;
    const auto &numbers = query->getNumbers();
    std::optional<utils::PhoneNumber::View> number;

    if (!numbers.empty()) {
        if (all_of(numbers.begin(), numbers.end(), [&](const auto &number) { return number == numbers.at(0); })) {
            number = std::make_optional(numbers.at(0));
        }
        record.value++;
        ret = Update(record);

        ret = processIncrement(query->getKey(), std::move(number), numbers.size());
    }
    return std::make_unique<db::query::notifications::IncrementResult>(ret);
    return std::make_unique<db::query::notifications::MultipleIncrementResult>(ret);
}

std::unique_ptr<db::query::notifications::ClearResult> NotificationsRecordInterface::runQueryImpl(


@@ 206,3 211,35 @@ std::unique_ptr<db::query::notifications::GetAllResult> NotificationsRecordInter
    auto records               = GetLimitOffset(0, numberOfNotifications);
    return std::make_unique<db::query::notifications::GetAllResult>(std::move(records));
}

bool NotificationsRecordInterface::processIncrement(NotificationsRecord::Key key,
                                                    std::optional<utils::PhoneNumber::View> &&number,
                                                    size_t size)
{
    auto ret = false;

    if (auto record = GetByKey(key); record.isValid() && number.has_value()) {
        auto &currentContactRecord = record.contactRecord;
        if (size == 1) {
            if (auto numberMatch = contactsDb->MatchByNumber(number.value()); numberMatch.has_value()) {
                if (record.value == 0) {
                    currentContactRecord = std::move(numberMatch.value().contact);
                }
                else if (currentContactRecord.has_value() &&
                         numberMatch.value().contactId != currentContactRecord.value().ID) {
                    currentContactRecord.reset();
                }
            }
            else {
                currentContactRecord.reset();
            }
        }
        else if (size > 1) {
            currentContactRecord.reset();
        }
        record.value += size;
        ret = Update(record);
    }

    return ret;
}

M module-db/Interface/NotificationsRecord.hpp => module-db/Interface/NotificationsRecord.hpp +9 -2
@@ 21,6 21,8 @@ namespace db::query::notifications
    class Get;
    class GetResult;
    class Increment;
    class MultipleIncrement;
    class MultipleIncrementResult;
    class IncrementResult;
    class Clear;
    class ClearResult;


@@ 44,7 46,7 @@ struct NotificationsRecord : public Record

    friend std::ostream &operator<<(std::ostream &out, const NotificationsRecord &point);

    NotificationsRecord()  = default;
    NotificationsRecord() = default;
    explicit NotificationsRecord(const NotificationsTableRow &tableRow,
                                 std::optional<ContactRecord> record = std::nullopt);



@@ 78,13 80,18 @@ class NotificationsRecordInterface : public RecordInterface<NotificationsRecord,
    std::unique_ptr<db::QueryResult> runQuery(std::shared_ptr<db::Query> query) override;

  private:
    NotificationsDB *notificationsDb = nullptr;
    NotificationsDB *notificationsDb   = nullptr;
    ContactRecordInterface *contactsDb = nullptr;

    std::optional<ContactRecord> getContactRecord(uint32_t id) const;
    std::unique_ptr<db::query::notifications::GetResult> runQueryImpl(const db::query::notifications::Get *query);
    std::unique_ptr<db::query::notifications::IncrementResult> runQueryImpl(
        const db::query::notifications::Increment *query);
    std::unique_ptr<db::query::notifications::MultipleIncrementResult> runQueryImpl(
        const db::query::notifications::MultipleIncrement *query);
    std::unique_ptr<db::query::notifications::ClearResult> runQueryImpl(const db::query::notifications::Clear *query);
    std::unique_ptr<db::query::notifications::GetAllResult> runQueryImpl(const db::query::notifications::GetAll *query);
    [[nodiscard]] bool processIncrement(NotificationsRecord::Key key,
                                        std::optional<utils::PhoneNumber::View> &&number,
                                        size_t size);
};

A module-db/queries/notifications/QueryNotificationsMultipleIncrement.cpp => module-db/queries/notifications/QueryNotificationsMultipleIncrement.cpp +39 -0
@@ 0,0 1,39 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "QueryNotificationsMultipleIncrement.hpp"

namespace db::query::notifications
{
    MultipleIncrement::MultipleIncrement(NotificationsRecord::Key key,
                                         const std::vector<utils::PhoneNumber::View> &numbers)
        : Query(Query::Type::Update), key(key), numbers(numbers)
    {}

    auto MultipleIncrement::getKey() const noexcept -> NotificationsRecord::Key
    {
        return key;
    }
    auto MultipleIncrement::getNumbers() const noexcept -> const std::vector<utils::PhoneNumber::View> &
    {
        return numbers;
    }

    auto MultipleIncrement::debugInfo() const -> std::string
    {
        return "MultipleIncrement";
    }

    MultipleIncrementResult::MultipleIncrementResult(bool ret) : ret(ret)
    {}

    auto MultipleIncrementResult::getResult() const noexcept -> bool
    {
        return ret;
    }

    auto MultipleIncrementResult::debugInfo() const -> std::string
    {
        return "MultipleIncrementResult";
    }
} // namespace db::query::notifications

A module-db/queries/notifications/QueryNotificationsMultipleIncrement.hpp => module-db/queries/notifications/QueryNotificationsMultipleIncrement.hpp +38 -0
@@ 0,0 1,38 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <Interface/NotificationsRecord.hpp>
#include <Common/Query.hpp>
#include <string>
#include <PhoneNumber.hpp>

namespace db::query::notifications
{
    class MultipleIncrement : public Query
    {
        const NotificationsRecord::Key key;
        const std::vector<utils::PhoneNumber::View> numbers;

      public:
        MultipleIncrement(NotificationsRecord::Key key, const std::vector<utils::PhoneNumber::View> &numbers);

        [[nodiscard]] auto getKey() const noexcept -> NotificationsRecord::Key;
        [[nodiscard]] auto getNumbers() const noexcept -> const std::vector<utils::PhoneNumber::View> &;

        [[nodiscard]] auto debugInfo() const -> std::string override;
    };

    class MultipleIncrementResult : public QueryResult
    {
        bool ret;

      public:
        explicit MultipleIncrementResult(bool ret);
        [[nodiscard]] auto getResult() const noexcept -> bool;

        [[nodiscard]] auto debugInfo() const -> std::string override;
    };

} // namespace db::query::notifications

M module-services/service-cellular/CellularCall.cpp => module-services/service-cellular/CellularCall.cpp +1 -5
@@ 30,11 30,7 @@ namespace CellularCall
        }

        clear();
        CalllogRecord callRec;
        callRec.type        = type;
        callRec.date         = std::time(nullptr);
        callRec.presentation = PresentationType::PR_UNKNOWN;
        callRec.phoneNumber  = number;
        CalllogRecord callRec{type, number};
        call                = startCallAction ? startCallAction(callRec) : CalllogRecord();
        if (!call.isValid()) {
            LOG_ERROR("startCallAction failed");

M module-services/service-cellular/ServiceCellular.cpp => module-services/service-cellular/ServiceCellular.cpp +113 -5
@@ 58,6 58,7 @@
#include <at/UrcFactory.hpp>
#include <queries/messages/sms/QuerySMSSearchByType.hpp>
#include <queries/notifications/QueryNotificationsIncrement.hpp>
#include <queries/notifications/QueryNotificationsMultipleIncrement.hpp>
#include <projdefs.h>
#include <service-antenna/AntennaMessage.hpp>
#include <service-antenna/AntennaServiceAPI.hpp>


@@ 280,9 281,23 @@ void ServiceCellular::registerMessageHandlers()
    phoneModeObserver->connect(this);
    phoneModeObserver->subscribe(
        [this](sys::phone_modes::PhoneMode mode) { connectionManager->onPhoneModeChange(mode); });
    phoneModeObserver->subscribe([](sys::phone_modes::Tethering tethering) {
    phoneModeObserver->subscribe([&](sys::phone_modes::Tethering tethering) {
        using bsp::cellular::USB::setPassthrough;
        using bsp::cellular::USB::PassthroughState;
        if (tethering == sys::phone_modes::Tethering::On) {
            if (!tetheringTurnOffURC()) {
                LOG_ERROR("Failed to disable URC on tethering enable");
            }
        }
        else {
            if (!tetheringTurnOnURC()) {
                LOG_ERROR("Failed to enable URC on tethering disable");
            }
            if (!receiveAllMessages()) {
                LOG_ERROR("Failed to receive all sms after tethering disabling");
            }
            logTetheringCalls();
        }
        setPassthrough(tethering == sys::phone_modes::Tethering::On ? PassthroughState::ENABLED
                                                                    : PassthroughState::DISABLED);
    });


@@ 1413,6 1428,7 @@ bool ServiceCellular::handle_modem_on()
    channel->cmd("AT+CCLK?");
    // inform host ap ready
    cmux->informModemHostWakeup();
    tetheringTurnOnURC();
    priv->state->set(State::ST::URCReady);
    LOG_DEBUG("AP ready");
    return true;


@@ 2048,6 2064,7 @@ auto ServiceCellular::handleCellularIncominCallMessage(sys::Message *msg) -> std

auto ServiceCellular::handleCellularCallerIdMessage(sys::Message *msg) -> std::shared_ptr<sys::ResponseMessage>
{

    auto message = static_cast<CellularCallerIdMessage *>(msg);
    ongoingCall.setNumber(message->number);
    return sys::MessageNone{};


@@ 2319,13 2336,19 @@ auto ServiceCellular::handleCellularRingNotification(sys::Message *msg) -> std::

auto ServiceCellular::handleCellularCallerIdNotification(sys::Message *msg) -> std::shared_ptr<sys::ResponseMessage>
{
    auto message = static_cast<CellularCallerIdNotification *>(msg);
    if (isIncommingCallAllowed()) {
        auto message = static_cast<CellularCallerIdNotification *>(msg);
        bus.sendMulticast(std::make_shared<CellularCallerIdMessage>(message->getNubmer()),
                          sys::BusChannel::ServiceCellularNotifications);
        return std::make_shared<CellularResponseMessage>(true);
    }
    return std::make_shared<CellularResponseMessage>(this->hangUpCall());
    else {
        if (phoneModeObserver->isTetheringOn()) {
            tetheringCalllog.push_back(CalllogRecord{CallType::CT_MISSED, message->getNubmer()});
            return std::make_shared<CellularResponseMessage>(hangUpCallBusy());
        }
    }
    return std::make_shared<CellularResponseMessage>(hangUpCall());
}

auto ServiceCellular::handleCellularSetConnectionFrequencyMessage(sys::Message *msg)


@@ 2343,13 2366,13 @@ auto ServiceCellular::handleCellularSetConnectionFrequencyMessage(sys::Message *

auto ServiceCellular::isIncommingCallAllowed() -> bool
{
    return phoneModeObserver->isInMode(sys::phone_modes::PhoneMode::Connected);
    return phoneModeObserver->isInMode(sys::phone_modes::PhoneMode::Connected) && !phoneModeObserver->isTetheringOn();
}

auto ServiceCellular::hangUpCall() -> bool
{
    auto channel = cmux->get(CellularMux::Channel::Commands);
    if (channel) {
    if (channel != nullptr) {
        if (channel->cmd(at::factory(at::AT::ATH))) {
            return true;
        }


@@ 2357,3 2380,88 @@ auto ServiceCellular::hangUpCall() -> bool
    LOG_ERROR("Failed to hang up call");
    return false;
}

auto ServiceCellular::hangUpCallBusy() -> bool
{
    auto channel = cmux->get(CellularMux::Channel::Commands);
    if (channel != nullptr) {
        if (channel->cmd(at::factory(at::AT::QHUP_BUSY))) {
            return true;
        }
    }
    LOG_ERROR("Failed to hang up call");
    return false;
}

auto ServiceCellular::tetheringTurnOffURC() -> bool
{
    auto channel = cmux->get(CellularMux::Channel::Commands);
    if (channel != nullptr) {
        if (!channel->cmd(at::factory(at::AT::CSQ_URC_OFF))) {
            LOG_ERROR("Failed to stop CSQ URC");
            return false;
        }
        if (!channel->cmd(at::factory(at::AT::ACT_URC_OFF))) {
            LOG_ERROR("Failed to stop ACT URC");
            return false;
        }
        if (!channel->cmd(at::factory(at::AT::SMS_URC_OFF))) {
            LOG_ERROR("Failed to stop SMS URC");
            return false;
        }
        if (!channel->cmd(at::factory(at::AT::RING_URC_OFF))) {
            LOG_ERROR("Failed to stop RING URC");
            return false;
        }
    }
    return true;
}

auto ServiceCellular::tetheringTurnOnURC() -> bool
{
    auto channel = cmux->get(CellularMux::Channel::Commands);
    if (channel != nullptr) {
        if (!channel->cmd(at::factory(at::AT::CSQ_URC_ON))) {
            LOG_ERROR("Failed to stop CSQ URC");
            return false;
        }
        if (!channel->cmd(at::factory(at::AT::ACT_URC_ON))) {
            LOG_ERROR("Failed to stop ACT URC");
            return false;
        }
        if (!channel->cmd(at::factory(at::AT::SMS_URC_ON))) {
            LOG_ERROR("Failed to stop SMS URC");
            return false;
        }

        if (!channel->cmd(at::factory(at::AT::RING_URC_ON))) {
            LOG_ERROR("Failed to stop RING URC");
            return false;
        }
    }
    return true;
}

auto ServiceCellular::logTetheringCalls() -> void
{
    if (!tetheringCalllog.empty()) {
        for (auto callRecord : tetheringCalllog) {
            auto call = DBServiceAPI::CalllogAdd(this, callRecord);
            if (call.ID == DB_ID_NONE) {
                LOG_ERROR("CalllogAdd failed");
            }
        }

        std::vector<utils::PhoneNumber::View> numbers;
        for (auto calllogRecord : tetheringCalllog) {
            numbers.push_back(calllogRecord.phoneNumber);
        }

        DBServiceAPI::GetQuery(
            this,
            db::Interface::Name::Notifications,
            std::make_unique<db::query::notifications::MultipleIncrement>(NotificationsRecord::Key::Calls, numbers));

        tetheringCalllog.clear();
    }
}

M module-services/service-cellular/service-cellular/ServiceCellular.hpp => module-services/service-cellular/service-cellular/ServiceCellular.hpp +6 -0
@@ 138,6 138,7 @@ class ServiceCellular : public sys::Service
    std::vector<std::string> messageParts;

    CellularCall::CellularCall ongoingCall;
    std::vector<CalllogRecord> tetheringCalllog;

    ussd::State ussdState = ussd::State::none;



@@ 316,6 317,11 @@ class ServiceCellular : public sys::Service
    auto isIncommingCallAllowed() -> bool;

    auto hangUpCall() -> bool;
    auto hangUpCallBusy() -> bool;

    auto tetheringTurnOffURC() -> bool;
    auto tetheringTurnOnURC() -> bool;
    auto logTetheringCalls() -> void;

  private:
    std::unique_ptr<cellular::internal::ServiceCellularPriv> priv;