~aleteoryx/muditaos

ref: ea27e6871615172000db8664a9d11d1b6103c562 muditaos/module-bsp/bsp/cellular/CellularResult.hpp -rw-r--r-- 4.3 KiB
ea27e687 — Maciej Janicki [EGD-5748] Remake Cellular flow 5 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::unique_ptr<uint8_t>(new 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";
    }
}