~aleteoryx/muditaos

ref: ee5b62a14e339e058de58eab354fa626111b3b3d muditaos/module-bsp/bsp/cellular/CellularResult.hpp -rw-r--r-- 4.3 KiB
ee5b62a1 — Kuba Kleczkowski [EGD-6651] Fix communication with modem on Linux 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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#pragma once

#include <memory>
#include <module-utils/Utils.hpp>
#include <utility>

namespace bsp::cellular
{
    enum class CellularResultCode : std::uint8_t
    {
        Uninitialized,
        ReceivedAndIdle,
        ReceivedAndFull,
        ReceivedAfterFull,
        ReceivingNotStarted,
        ReceivedNoData,
        TransmittingNotStarted,
        CMUXFrameError,
    };

    constexpr size_t CellularResultStructMaxDataSize = 128;
    constexpr size_t CellularResultStructEmptySize   = 5;

    struct __attribute__((__packed__)) CellularDMAResultStruct
    {
        CellularResultCode resultCode = CellularResultCode::ReceivedNoData;
        size_t dataSize               = 0;
        std::uint8_t data[CellularResultStructMaxDataSize];

        constexpr static size_t getEmptySize()
        {
            return sizeof(CellularDMAResultStruct) - CellularResultStructMaxDataSize;
        }

        constexpr static size_t getMaxSize()
        {
            return getEmptySize() + sizeof(data);
        }

        size_t getSize() const noexcept
        {
            return getEmptySize() + dataSize;
        }
    };

    struct CellularResultStruct
    {
        CellularResultCode resultCode = CellularResultCode::Uninitialized;
        std::vector<uint8_t> data;

        [[nodiscard]] auto serialize() const -> std::unique_ptr<uint8_t[]>
        {
            auto serialized     = std::make_unique< uint8_t[]>(data.size() + sizeof(resultCode));
            serialized.get()[0] = static_cast<unsigned char>(resultCode);

            if (data.size() > 0) {
                memcpy(serialized.get() + 1, data.data(), data.size());
            }

            return serialized;
        }

        auto deserialize(const uint8_t *serialized, const size_t size) -> void
        {
            if (size > 0) {
                resultCode = static_cast<CellularResultCode>(*serialized);
                if (size > 1) {
                    data = {serialized + 1, serialized + size};
                }
            }
        }

        [[nodiscard]] auto getSerializedSize() const noexcept -> size_t
        {
            return (sizeof(resultCode) + data.size());
        }
    };

    class CellularResult
    {
        CellularResultStruct result;

      public:
        CellularResult() : result{CellularResultCode::Uninitialized, {}}
        {}

        explicit CellularResult(CellularDMAResultStruct &result)
            : result{result.resultCode, {result.data, result.data + result.dataSize}}
        {}

        explicit CellularResult(CellularResultStruct result) : result{std::move(result)}
        {}

        explicit CellularResult(const uint8_t *serialized, const size_t size)
        {
            result.deserialize(serialized, size);
        }

        auto getResultCode() const noexcept -> CellularResultCode
        {
            return result.resultCode;
        }

        auto setResultCode(CellularResultCode code) -> void
        {
            result.resultCode = code;
        }

        auto getData() const noexcept -> std::vector<uint8_t> const &
        {
            return result.data;
        }

        auto setData(const std::vector<uint8_t> &data) -> void
        {
            result.data = data;
        }

        auto getDataAsString() const -> std::string
        {
            return std::string{result.data.begin(), result.data.end()};
        }

        auto getStruct() const -> CellularResultStruct const *
        {
            return &result;
        }

        auto getSerialized() const -> std::unique_ptr<uint8_t[]>
        {
            return result.serialize();
        }

        auto getSerializedSize() const noexcept -> size_t
        {
            return result.getSerializedSize();
        }
    };
} // namespace bsp::cellular

inline const char *c_str(bsp::cellular::CellularResultCode result)
{
    switch (result) {
    case bsp::cellular::CellularResultCode::ReceivedAndIdle:
        return "ReceivedAndIdle";
    case bsp::cellular::CellularResultCode::ReceivedAndFull:
        return "ReceivedAndFull";
    case bsp::cellular::CellularResultCode::ReceivedAfterFull:
        return "ReceivedAfterFull";
    case bsp::cellular::CellularResultCode::ReceivingNotStarted:
        return "ReceivingNotStarted";
    case bsp::cellular::CellularResultCode::TransmittingNotStarted:
        return "TransmittingNotStarted";
    default:
        return "Unknown";
    }
}