~aleteoryx/muditaos

ce82949067a12b62875dfb1055abbd2af1a64484 — Pawel.Paprocki 4 years ago f3480da
[EGD-7167] Pass IMEI number to Settings

Get IMEI from cellular and display it in Settings
M module-apps/application-settings/ApplicationSettings.cpp => module-apps/application-settings/ApplicationSettings.cpp +3 -2
@@ 502,8 502,9 @@ namespace app
        });
        windowsFactory.attach(gui::window::name::technical_information, [&](Application *app, const std::string &name) {
            auto factoryData = std::make_unique<FactoryData>(*settings);
            auto model       = std::make_unique<TechnicalInformationModel>(std::move(factoryData));
            auto presenter   = std::make_unique<TechnicalWindowPresenter>(std::move(model));
            auto repository  = std::make_unique<TechnicalInformationRepository>(this);
            auto model     = std::make_unique<TechnicalInformationModel>(std::move(factoryData), std::move(repository));
            auto presenter = std::make_unique<TechnicalWindowPresenter>(this, std::move(model));
            return std::make_unique<gui::TechnicalInformationWindow>(app, std::move(presenter));
        });
        windowsFactory.attach(gui::window::name::certification, [](Application *app, const std::string &name) {

M module-apps/application-settings/CMakeLists.txt => module-apps/application-settings/CMakeLists.txt +1 -0
@@ 27,6 27,7 @@ target_sources( ${PROJECT_NAME}
        models/apps/SoundsModel.cpp
        models/system/DateAndTimeModel.cpp
        models/system/SARInfoRepository.cpp
        models/system/TechnicalInformationRepository.cpp
        models/system/FactoryData.cpp
        models/system/TechnicalInformationModel.cpp
        presenter/network/SimContactsImportWindowPresenter.cpp

M module-apps/application-settings/models/system/TechnicalInformationModel.cpp => module-apps/application-settings/models/system/TechnicalInformationModel.cpp +16 -3
@@ 9,8 9,9 @@
#include <source/version.hpp>
#include <i18n/i18n.hpp>

TechnicalInformationModel::TechnicalInformationModel(std::unique_ptr<AbstractFactoryData> &&factoryData)
    : factoryData{std::move(factoryData)}
TechnicalInformationModel::TechnicalInformationModel(std::unique_ptr<AbstractFactoryData> &&factoryData,
                                                     std::unique_ptr<AbstractTechnicalInformationRepository> repository)
    : factoryData{std::move(factoryData)}, technicalInformationRepository(std::move(repository))
{
    createData();
}


@@ 47,7 48,8 @@ void TechnicalInformationModel::createData()
    internalData.push_back(
        new gui::TechnicalInformationItem(utils::translate("app_settings_tech_info_os_version"), std::string(VERSION)));

    internalData.push_back(new gui::TechnicalInformationItem(utils::translate("app_settings_tech_info_imei"), imei));
    internalData.push_back(new gui::TechnicalInformationItem(utils::translate("app_settings_tech_info_imei"),
                                                             technicalInformationRepository->getImei()));

#if DEVELOPER_SETTINGS_OPTIONS == 1
    internalData.push_back(new gui::TechnicalInformationItem(utils::translate("app_settings_tech_info_battery"),


@@ 70,3 72,14 @@ void TechnicalInformationModel::createData()
        item->deleteByList = false;
    }
}

void TechnicalInformationModel::clearData()
{
    list->reset();
    eraseInternalData();
}

void TechnicalInformationModel::requestImei(std::function<void()> onImeiReadCallback)
{
    technicalInformationRepository->readImei(std::move(onImeiReadCallback));
}

M module-apps/application-settings/models/system/TechnicalInformationModel.hpp => module-apps/application-settings/models/system/TechnicalInformationModel.hpp +8 -3
@@ 4,24 4,29 @@
#pragma once

#include "FactoryData.hpp"
#include "TechnicalInformationRepository.hpp"

#include <InternalModel.hpp>
#include <ListItemProvider.hpp>
#include <Application.hpp>

class TechnicalInformationModel : public app::InternalModel<gui::ListItem *>, public gui::ListItemProvider
{
  private:
    static constexpr auto imei = "AA-BBBBBB-CCCCC-D";

    app::Application *application = nullptr;
    std::unique_ptr<AbstractFactoryData> factoryData;
    std::shared_ptr<AbstractTechnicalInformationRepository> technicalInformationRepository = nullptr;

  public:
    explicit TechnicalInformationModel(std::unique_ptr<AbstractFactoryData> &&factoryData);
    explicit TechnicalInformationModel(std::unique_ptr<AbstractFactoryData> &&factoryData,
                                       std::unique_ptr<AbstractTechnicalInformationRepository> repository);

    void createData();
    void clearData();

    [[nodiscard]] auto requestRecordsCount() -> unsigned int override;
    [[nodiscard]] auto getMinimalItemSpaceRequired() const -> unsigned int override;
    auto getItem(gui::Order order) -> gui::ListItem * override;
    void requestRecords(const uint32_t offset, const uint32_t limit) override;
    void requestImei(std::function<void()> onImeiReadCallback);
};

A module-apps/application-settings/models/system/TechnicalInformationRepository.cpp => module-apps/application-settings/models/system/TechnicalInformationRepository.cpp +33 -0
@@ 0,0 1,33 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "TechnicalInformationRepository.hpp"
#include <service-cellular/ServiceCellular.hpp>
#include <application-settings/ApplicationSettings.hpp>

TechnicalInformationRepository::TechnicalInformationRepository(app::Application *application)
    : app::AsyncCallbackReceiver{application}, application{application}
{}

void TechnicalInformationRepository::readImei(AbstractTechnicalInformationRepository::OnReadCallback readDoneCallback)
{

    std::function<void(const std::string &imei)> callback = [&](const std::string &imei) { imeiStr = imei; };

    auto msg  = std::make_unique<cellular::GetImeiRequest>();
    auto task = app::AsyncRequest::createFromMessage(std::move(msg), cellular::service::name);
    auto cb   = [callback, readDoneCallback](auto response) {
        auto result = dynamic_cast<cellular::GetImeiResponse *>(response);
        if (result != nullptr && result->retCode == sys::ReturnCodes::Success) {
            callback(*result->getImei());
        }
        readDoneCallback();
        return true;
    };
    task->execute(this->application, this, cb);
}

std::string TechnicalInformationRepository::getImei()
{
    return imeiStr;
}

A module-apps/application-settings/models/system/TechnicalInformationRepository.hpp => module-apps/application-settings/models/system/TechnicalInformationRepository.hpp +28 -0
@@ 0,0 1,28 @@
// 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 <apps-common/Application.hpp>
#include <service-cellular/CellularMessage.hpp>

class AbstractTechnicalInformationRepository
{
  public:
    using OnReadCallback                                       = std::function<void()>;
    virtual ~AbstractTechnicalInformationRepository() noexcept = default;
    virtual void readImei(OnReadCallback callback)             = 0;
    virtual std::string getImei()                              = 0;
};

class TechnicalInformationRepository : public AbstractTechnicalInformationRepository, public app::AsyncCallbackReceiver
{
  public:
    explicit TechnicalInformationRepository(app::Application *application);
    void readImei(OnReadCallback callback) override;
    std::string getImei() override;

  private:
    app::Application *application{};
    std::string imeiStr;
};

M module-apps/application-settings/presenter/system/TechnicalWindowPresenter.cpp => module-apps/application-settings/presenter/system/TechnicalWindowPresenter.cpp +16 -3
@@ 3,11 3,24 @@

#include "TechnicalWindowPresenter.hpp"

TechnicalWindowPresenter::TechnicalWindowPresenter(std::shared_ptr<gui::ListItemProvider> technicalInformationProvider)
    : technicalInformationProvider{std::move(technicalInformationProvider)}
{}
TechnicalWindowPresenter::TechnicalWindowPresenter(
    app::Application *application, std::shared_ptr<TechnicalInformationModel> technicalInformationProvider)
    : application(application), technicalInformationProvider{std::move(technicalInformationProvider)}
{
    onImeiReady = [&]() {
        this->technicalInformationProvider->clearData();
        this->technicalInformationProvider->createData();
        getView()->imeiReady();
        this->application->refreshWindow(gui::RefreshModes::GUI_REFRESH_FAST);
    };
}

std::shared_ptr<gui::ListItemProvider> TechnicalWindowPresenter::getTechnicalInformationProvider() const
{
    return technicalInformationProvider;
}

void TechnicalWindowPresenter::requestImei()
{
    technicalInformationProvider->requestImei(onImeiReady);
}

M module-apps/application-settings/presenter/system/TechnicalWindowPresenter.hpp => module-apps/application-settings/presenter/system/TechnicalWindowPresenter.hpp +10 -2
@@ 3,6 3,8 @@

#pragma once

#include <application-settings/models/system/TechnicalInformationModel.hpp>

#include <BasePresenter.hpp>
#include <ListItemProvider.hpp>



@@ 13,6 15,7 @@ class TechnicalWindowContract
    {
      public:
        virtual ~View() noexcept = default;
        virtual void imeiReady() noexcept = 0;
    };
    class Presenter : public app::BasePresenter<TechnicalWindowContract::View>
    {


@@ 20,16 23,21 @@ class TechnicalWindowContract
        virtual ~Presenter() noexcept = default;

        virtual std::shared_ptr<gui::ListItemProvider> getTechnicalInformationProvider() const = 0;
        virtual void requestImei()                                                             = 0;
    };
};

class TechnicalWindowPresenter : public TechnicalWindowContract::Presenter
{
  public:
    explicit TechnicalWindowPresenter(std::shared_ptr<gui::ListItemProvider> technicalInformationProvider);
    explicit TechnicalWindowPresenter(app::Application *application,
                                      std::shared_ptr<TechnicalInformationModel> technicalInformationProvider);

    std::shared_ptr<gui::ListItemProvider> getTechnicalInformationProvider() const override;
    void requestImei() override;

  private:
    std::shared_ptr<gui::ListItemProvider> technicalInformationProvider;
    app::Application *application{};
    std::shared_ptr<TechnicalInformationModel> technicalInformationProvider;
    std::function<void()> onImeiReady = nullptr;
};

M module-apps/application-settings/windows/system/TechnicalInformationWindow.cpp => module-apps/application-settings/windows/system/TechnicalInformationWindow.cpp +18 -7
@@ 15,6 15,11 @@ namespace gui
        buildInterface();
    }

    void TechnicalInformationWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    {
        presenter->requestImei();
    }

    void TechnicalInformationWindow::buildInterface()
    {
        AppWindow::buildInterface();


@@ 23,15 28,21 @@ namespace gui
        bottomBar->setActive(gui::BottomBar::Side::RIGHT, true);
        bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::translate(::style::strings::common::back));

        auto list = new ListView(this,
                                 style::window::default_left_margin,
                                 style::window::default_vertical_pos,
                                 style::listview::body_width_with_scroll,
                                 style::window::default_body_height,
                                 presenter->getTechnicalInformationProvider(),
                                 listview::ScrollBarType::Fixed);
        list = new ListView(this,
                            style::window::default_left_margin,
                            style::window::default_vertical_pos,
                            style::listview::body_width_with_scroll,
                            style::window::default_body_height,
                            presenter->getTechnicalInformationProvider(),
                            listview::ScrollBarType::Fixed);

        setFocusItem(list);
        list->rebuildList();
    }

    void TechnicalInformationWindow::imeiReady() noexcept
    {
        list->rebuildList();
    }

} // namespace gui

M module-apps/application-settings/windows/system/TechnicalInformationWindow.hpp => module-apps/application-settings/windows/system/TechnicalInformationWindow.hpp +3 -0
@@ 18,7 18,10 @@ namespace gui

      private:
        void buildInterface() override;
        void onBeforeShow(ShowMode mode, SwitchData *data) override;
        void imeiReady() noexcept override;

        ListView *list = nullptr;
        std::shared_ptr<TechnicalWindowContract::Presenter> presenter;
    };


M module-services/service-cellular/CMakeLists.txt => module-services/service-cellular/CMakeLists.txt +1 -0
@@ 9,6 9,7 @@ set(SOURCES
    src/NetworkTime.cpp
    src/SimContacts.cpp
    src/SMSSendHandler.cpp
    src/ImeiGetHandler.cpp

    CellularCall.cpp
    CellularServiceAPI.cpp

M module-services/service-cellular/ServiceCellular.cpp => module-services/service-cellular/ServiceCellular.cpp +3 -0
@@ 299,6 299,7 @@ void ServiceCellular::registerMessageHandlers()
    priv->connectSimCard();
    priv->connectNetworkTime();
    priv->connectSimContacts();
    priv->connectImeiGetHandler();

    connect(typeid(CellularStartOperatorsScanMessage), [&](sys::Message *request) -> sys::MessagePointer {
        auto msg = static_cast<CellularStartOperatorsScanMessage *>(request);


@@ 385,6 386,7 @@ void ServiceCellular::registerMessageHandlers()
            priv->simCard->setChannel(nullptr);
            priv->networkTime->setChannel(nullptr);
            priv->simContacts->setChannel(nullptr);
            priv->imeiGetHandler->setChannel(nullptr);

            cmux->closeChannels();
            ///> change state - simulate hot start


@@ 853,6 855,7 @@ bool ServiceCellular::handle_audio_conf_procedure()
            priv->simCard->setChannel(cmux->get(CellularMux::Channel::Commands));
            priv->networkTime->setChannel(cmux->get(CellularMux::Channel::Commands));
            priv->simContacts->setChannel(cmux->get(CellularMux::Channel::Commands));
            priv->imeiGetHandler->setChannel(cmux->get(CellularMux::Channel::Commands));
            // open channel - notifications
            DLCChannel *notificationsChannel = cmux->get(CellularMux::Channel::Notifications);
            if (notificationsChannel != nullptr) {

M module-services/service-cellular/service-cellular/CellularMessage.hpp => module-services/service-cellular/service-cellular/CellularMessage.hpp +24 -0
@@ 936,4 936,28 @@ namespace cellular
      private:
        std::shared_ptr<std::vector<SimContact>> contacts;
    };

    class GetImeiRequest : public sys::DataMessage
    {
      public:
        GetImeiRequest() : sys::DataMessage(MessageType::MessageTypeUninitialized){};
    };

    class GetImeiResponse : public sys::ResponseMessage
    {
      public:
        explicit GetImeiResponse(std::shared_ptr<std::string> imei)
            : sys::ResponseMessage(sys::ReturnCodes::Success), imei(imei)
        {}
        GetImeiResponse() : sys::ResponseMessage(sys::ReturnCodes::Failure)
        {}
        auto getImei() -> std::shared_ptr<std::string>
        {
            return imei;
        }

      private:
        std::shared_ptr<std::string> imei;
    };

} // namespace cellular

M module-services/service-cellular/service-cellular/ServiceCellular.hpp => module-services/service-cellular/service-cellular/ServiceCellular.hpp +2 -0
@@ 227,6 227,8 @@ class ServiceCellular : public sys::Service
    uint32_t ussdTimeout = 0;
    void setUSSDTimer();
    bool handleUSSDRequest(CellularUSSDMessage::RequestType requestType, const std::string &request = "");
    bool handleIMEIRequest();

    bool handleUSSDURC();
    void handleUSSDTimer();


A module-services/service-cellular/src/ImeiGetHandler.cpp => module-services/service-cellular/src/ImeiGetHandler.cpp +40 -0
@@ 0,0 1,40 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "ImeiGetHandler.hpp"
#include <ATFactory.hpp>
#include <modem/BaseChannel.hpp>

#include <log/Logger.hpp>

namespace
{
    constexpr auto IMEIResonseSize = 2;
}

namespace cellular::service
{
    void ImeiGetHandler::setChannel(at::BaseChannel *channel)
    {
        this->channel = channel;
    }

    auto ImeiGetHandler::getImei(std::string &destination) -> bool
    {

        if (channel == nullptr) {
            LOG_ERROR("No channel provided. Request ignored");
            return false;
        }
        auto result = channel->cmd(at::factory(at::AT::GET_IMEI));

        if (result.code == at::Result::Code::OK && result.response.size() == IMEIResonseSize) {
            destination = result.response[0];
            return true;
        }
        else {
            return false;
        }
    }

} // namespace cellular::service

A module-services/service-cellular/src/ImeiGetHandler.hpp => module-services/service-cellular/src/ImeiGetHandler.hpp +46 -0
@@ 0,0 1,46 @@
// 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 <service-cellular/service-cellular/CellularMessage.hpp>

#include <memory>
//#include <vector>

namespace at
{
    class Cmd;
    class BaseChannel;
} // namespace at

namespace sys
{
    class Message;
} // namespace sys

namespace cellular::service
{
    class ImeiGetHandler
    {
      public:
        /** Set cmd channel
         * \param channel channel (or nullptr to block communication)
         */
        void setChannel(at::BaseChannel *channel);
        /**
         * Reads IMEI as a string
         * @param destination reference to data destination
         * @return boor result true on success, false on fail
         */
        auto getImei(std::string &destination) -> bool;

      private:
        /**
         * Reads number of contacts stored on sim card
         * @param count number of contacts stored on sim card
         * @return boor result true on success, false on fail
         */
        at::BaseChannel *channel = nullptr;
    };
} // namespace cellular::service

M module-services/service-cellular/src/ServiceCellularPriv.cpp => module-services/service-cellular/src/ServiceCellularPriv.cpp +13 -1
@@ 26,7 26,8 @@ namespace cellular::internal
{
    ServiceCellularPriv::ServiceCellularPriv(ServiceCellular *owner)
        : owner{owner}, simCard{std::make_unique<SimCard>()}, state{std::make_unique<State>(owner)},
          networkTime{std::make_unique<NetworkTime>()}, simContacts{std::make_unique<SimContacts>()}
          networkTime{std::make_unique<NetworkTime>()}, simContacts{std::make_unique<SimContacts>()},
          imeiGetHandler{std::make_unique<service::ImeiGetHandler>()}
    {
        initSimCard();
        initSMSSendHandler();


@@ 261,4 262,15 @@ namespace cellular::internal
        });
    }

    void ServiceCellularPriv::connectImeiGetHandler()
    {
        owner->connect(typeid(cellular::GetImeiRequest), [&](sys::Message *request) -> sys::MessagePointer {
            std::string imei;
            if (imeiGetHandler->getImei(imei)) {
                return std::make_shared<cellular::GetImeiResponse>(std::make_shared<std::string>(imei));
            }
            return std::make_shared<cellular::GetImeiResponse>();
        });
    }

} // namespace cellular::internal

M module-services/service-cellular/src/ServiceCellularPriv.hpp => module-services/service-cellular/src/ServiceCellularPriv.hpp +3 -0
@@ 10,6 10,7 @@
#include "SimCard.hpp"
#include "NetworkTime.hpp"
#include "SimContacts.hpp"
#include "ImeiGetHandler.hpp"

namespace cellular::internal
{


@@ 27,6 28,7 @@ namespace cellular::internal
        std::unique_ptr<State> state;
        std::unique_ptr<NetworkTime> networkTime;
        std::unique_ptr<SimContacts> simContacts;
        std::unique_ptr<service::ImeiGetHandler> imeiGetHandler;
        State::PowerState nextPowerState = State::PowerState::Off;

      public:


@@ 35,6 37,7 @@ namespace cellular::internal
        void connectSimCard();
        void connectNetworkTime();
        void connectSimContacts();
        void connectImeiGetHandler();

        void requestNetworkTimeSettings();