#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