~aleteoryx/muditaos

ref: d32ce980d98396dc4652bca96ede347fa6a06f0c muditaos/module-cellular/at/cmd/src/CLCC.cpp -rw-r--r-- 4.3 KiB
d32ce980 — Tomasz Rybarski [BH-1272] Update Onboarding Finalize Screen 4 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <at/cmd/CLCC.hpp>
#include <memory>
#include <string>
#include <string_view>
#include <service-cellular/CellularCall.hpp>

namespace at
{
    namespace cmd
    {
        CLCC::CLCC(at::cmd::Modifier mod) noexcept : Cmd{"AT+CLCC", mod}
        {}

        CLCC::CLCC() noexcept : CLCC{at::cmd::Modifier::None}
        {}

        auto CLCC::toBool(const std::string &text) -> bool
        {
            int ret = -1;
            if (!utils::toNumeric(text, ret) || ret == -1) {
                throw std::runtime_error("String to bool conversion failed");
            }
            return ret == 1 ? true : false;
        }

        auto CLCC::toUInt(const std::string &text) -> std::uint8_t
        {
            auto value = std::stoul(text);
            if (value > std::numeric_limits<std::uint8_t>::max()) {
                throw std::runtime_error("Out of range value");
            }
            return static_cast<std::uint8_t>(value);
        }

        template <typename T> auto CLCC::toEnum(const std::string &text) -> std::optional<T>
        {
            static_assert(std::is_enum_v<T>);
            int ret = -1;
            if (!utils::toNumeric(text, ret) || ret == -1) {
                return std::nullopt;
            }

            return magic_enum::enum_cast<T>(ret);
        }

        template auto CLCC::toEnum<ModemCall::CallDir>(const std::string &text) -> std::optional<ModemCall::CallDir>;
        template auto CLCC::toEnum<ModemCall::CallState>(const std::string &text)
            -> std::optional<ModemCall::CallState>;
        template auto CLCC::toEnum<ModemCall::CallMode>(const std::string &text) -> std::optional<ModemCall::CallMode>;

        result::CLCC CLCC::parseCLCC(const Result &base_result)
        {
            using namespace std::literals;
            auto baseResult = Cmd::parseBase(base_result);
            result::CLCC p{baseResult};

            auto parseErrorHandler = [&p]() {
                LOG_ERROR("Parsing error - invalid parameter passed");
                p.code = result::CLCC::Code::PARSING_ERROR;
            };
            if (p && p.tokens.size() > 0) {
                for (const auto &tokens : p.tokens) {
                    auto numberOfTokens = tokens.size();
                    if (numberOfTokens != 7 && numberOfTokens != 8) {
                        LOG_ERROR("Can't parse - number of tokens %u is not valid",
                                  static_cast<unsigned int>(p.tokens.size()));
                        p.code = result::CLCC::Code::PARSING_ERROR;
                        return p;
                    }

                    try {
                        const auto callDir   = toEnum<ModemCall::CallDir>(tokens[1]);
                        const auto callState = toEnum<ModemCall::CallState>(tokens[2]);
                        const auto callMode  = toEnum<ModemCall::CallMode>(tokens[3]);
                        if (!callDir.has_value() || !callState.has_value() || !callMode.has_value()) {
                            parseErrorHandler();
                            return p;
                        }
                        p.data.push_back(result::CLCC::Data{toUInt(tokens[0]),
                                                            callDir.value(),
                                                            callState.value(),
                                                            callMode.value(),
                                                            toBool(tokens[4]),
                                                            utils::PhoneNumber(tokens[5]).getView(),
                                                            tokens[6],
                                                            (numberOfTokens == 8) ? tokens[7] : "",
                                                            numberOfTokens});
                    }
                    catch (...) {
                        parseErrorHandler();
                        return p;
                    }
                }
            }
            return p;
        }
    } // namespace cmd

    namespace result
    {
        CLCC::CLCC(const Result &result) : Result{result}
        {}

    } // namespace result
} // namespace at