#pragma once #include #include #include 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 data; [[nodiscard]] auto serialize() const -> std::unique_ptr { auto serialized = std::make_unique< uint8_t[]>(data.size() + sizeof(resultCode)); serialized.get()[0] = static_cast(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(*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 const & { return result.data; } auto setData(const std::vector &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 { 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"; } }