ProtoPlexer

Documentation
Login
#ifndef PLEXER_H
#define PLEXER_H
#include "protoplexer.h"
#include "plexer_msg.h"
#include "plexer_chunk.h"

namespace protoplexer
{
	uint16_t CANID_2_from(uint32_t CAN_ID);
	uint16_t CANID_2_dest(uint32_t CAN_ID);
	uint_fast8_t CANID_2_priority(uint32_t CAN_ID);
	uint_fast8_t CANID_2_startbit(uint32_t CAN_ID);

    class plexer_interface {
    public:
        virtual ~plexer_interface() = default;
        virtual plexer_result send_msg (const plexer_msg* msg) = 0;
        virtual uint16_t own_address() const = 0;
    };

    class plexer_base : public plexer_interface {
    public:
        explicit plexer_base(uint16_t own_address, uint_fast16_t max_chunk_length )
            : _own_address(own_address&0x0FFF), _max_chunk_length(max_chunk_length) {}
        virtual ~plexer_base() = default;

        plexer_result send_msg (plexer_msg * msg, bool own);
        plexer_result send_msg(uint16_t MSG_ID, uint16_t from, uint16_t to, const uint8_t* data = nullptr, uint16_t length = 0, uint8_t priority = priority_minimal);
        plexer_result send_msg (const plexer_msg * msg) override;

        uint16_t own_address() const override { return _own_address; }

        plexer_result add_chunk(const plexer_chunk* chunk);

        static const char* result2string(plexer_result value) noexcept;

        virtual void rx_event(std::shared_ptr<plexer_msg>) {}
        virtual plexer_hw_result send_chunk(plexer_chunk * chunk) {
          (void) chunk;
          return plexer_hw_result::error_non_recoverable;
        }

        uint_fast16_t max_chunk_length() const { return _max_chunk_length; }

        bool monitoring() const { return _monitoring; }
        void setMonitoring(bool monitoring) { _monitoring = monitoring; }

    private:
        virtual void handle_inbox(std::shared_ptr<plexer_msg> msg) = 0;
        virtual void handle_outbox(plexer_chunk&& chunk) = 0;
        virtual void revert_outbox() = 0;

        const uint16_t _own_address;
        std::map<uint32_t, std::shared_ptr<plexer_msg>> rx_buffers;
        uint_fast16_t _max_chunk_length;
        bool _monitoring = false;
    };

    class plexer_queued : public plexer_base
    {
    public:
        using plexer_base::plexer_base;

        plexer_result poll_rx();
        plexer_result poll_tx();
        plexer_result poll_new();

        virtual void rx_notification (uint16_t message_ID) {
          (void) message_ID;
        }
        virtual std::shared_ptr<plexer_chunk> receive_chunk() {return nullptr;}

        uint_fast16_t max_send_attempts() const { return _max_send_attempts; }
        void setMax_send_attempts(uint_fast16_t max_send_attempts) { _max_send_attempts = max_send_attempts; }

    private:
        void handle_inbox(std::shared_ptr<plexer_msg> msg) final override;
        void handle_outbox(plexer_chunk&& chunk) final override;
        void revert_outbox() final override;

        std::queue<std::shared_ptr<plexer_msg>> inbox_queue;
        std::deque<plexer_chunk> outbox_queue;
        uint_fast16_t done_send_attempts = 0;
        uint_fast16_t _max_send_attempts = 100;
    };

    class plexer_blocking : public plexer_base
    {
    public:
        using plexer_base::plexer_base;

    private:
        void handle_inbox(std::shared_ptr<plexer_msg> msg) final override { return rx_event(std::move(msg)); }
        void handle_outbox(plexer_chunk&& chunk) final override { send_chunk(&chunk); }
        void revert_outbox() final override {}
    };
}

#endif // PLEXER_H