mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 09:28:40 +02:00
Communication: MultiChannel: Properly mask out communication from non-main VNETs
This also makes it possible for Communication to create more instances of Packetizer This is necessary because Packetizer is not thread safe, so when we support more VNETs we will need to create more Packetizers.
This commit is contained in:
@@ -24,10 +24,12 @@ class Communication {
|
||||
public:
|
||||
Communication(
|
||||
device_eventhandler_t report,
|
||||
std::unique_ptr<ICommunication> com,
|
||||
std::shared_ptr<Packetizer> p,
|
||||
std::unique_ptr<Encoder> e,
|
||||
std::unique_ptr<Decoder> md) : packetizer(p), encoder(std::move(e)), decoder(std::move(md)), report(report), impl(std::move(com)) {}
|
||||
std::unique_ptr<ICommunication>&& com,
|
||||
std::function<std::unique_ptr<Packetizer>()> makeConfiguredPacketizer,
|
||||
std::unique_ptr<Encoder>&& e,
|
||||
std::unique_ptr<Decoder>&& md) : makeConfiguredPacketizer(makeConfiguredPacketizer), encoder(std::move(e)), decoder(std::move(md)), report(report), impl(std::move(com)) {
|
||||
packetizer = makeConfiguredPacketizer();
|
||||
}
|
||||
virtual ~Communication() { close(); }
|
||||
|
||||
bool open();
|
||||
@@ -59,7 +61,8 @@ public:
|
||||
MessageFilter f = MessageFilter(),
|
||||
std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
|
||||
|
||||
std::shared_ptr<Packetizer> packetizer; // Ownership is shared with the encoder
|
||||
std::function<std::unique_ptr<Packetizer>()> makeConfiguredPacketizer;
|
||||
std::unique_ptr<Packetizer> packetizer;
|
||||
std::unique_ptr<Encoder> encoder;
|
||||
std::unique_ptr<Decoder> decoder;
|
||||
device_eventhandler_t report;
|
||||
|
||||
@@ -15,14 +15,15 @@ namespace icsneo {
|
||||
|
||||
class Encoder {
|
||||
public:
|
||||
Encoder(device_eventhandler_t report, std::shared_ptr<Packetizer> p) : packetizer(p), report(report) {}
|
||||
bool encode(std::vector<uint8_t>& result, const std::shared_ptr<Message>& message);
|
||||
bool encode(std::vector<uint8_t>& result, Command cmd, bool boolean) { return encode(result, cmd, std::vector<uint8_t>({ (uint8_t)boolean })); }
|
||||
bool encode(std::vector<uint8_t>& result, Command cmd, std::vector<uint8_t> arguments = {});
|
||||
Encoder(device_eventhandler_t report) : report(report) {}
|
||||
bool encode(const Packetizer& packetizer, std::vector<uint8_t>& result, const std::shared_ptr<Message>& message);
|
||||
bool encode(const Packetizer& packetizer, std::vector<uint8_t>& result, Command cmd, bool boolean) {
|
||||
return encode(packetizer, result, cmd, std::vector<uint8_t>({ (uint8_t)boolean }));
|
||||
}
|
||||
bool encode(const Packetizer& packetizer, std::vector<uint8_t>& result, Command cmd, std::vector<uint8_t> arguments = {});
|
||||
|
||||
bool supportCANFD = false;
|
||||
private:
|
||||
std::shared_ptr<Packetizer> packetizer;
|
||||
device_eventhandler_t report;
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "icsneo/communication/icommunication.h"
|
||||
#include "icsneo/communication/command.h"
|
||||
#include "icsneo/communication/encoder.h"
|
||||
#include "icsneo/third-party/readerwriterqueue/readerwriterqueue.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
@@ -13,9 +14,9 @@ public:
|
||||
MultiChannelCommunication(
|
||||
device_eventhandler_t err,
|
||||
std::unique_ptr<ICommunication> com,
|
||||
std::shared_ptr<Packetizer> p,
|
||||
std::function<std::unique_ptr<Packetizer>()> makeConfiguredPacketizer,
|
||||
std::unique_ptr<Encoder> e,
|
||||
std::unique_ptr<Decoder> md) : Communication(err, std::move(com), p, std::move(e), std::move(md)) {}
|
||||
std::unique_ptr<Decoder> md) : Communication(err, std::move(com), makeConfiguredPacketizer, std::move(e), std::move(md)) {}
|
||||
void spawnThreads() override;
|
||||
void joinThreads() override;
|
||||
bool sendPacket(std::vector<uint8_t>& bytes) override;
|
||||
@@ -24,6 +25,8 @@ protected:
|
||||
bool preprocessPacket(std::deque<uint8_t>& usbReadFifo);
|
||||
|
||||
private:
|
||||
static constexpr const size_t NUM_SUPPORTED_VNETS = 1;
|
||||
|
||||
enum class CommandType : uint8_t {
|
||||
PlasmaReadRequest = 0x10, // Status read request to HSC
|
||||
PlasmaStatusResponse = 0x11, // Status response by HSC
|
||||
@@ -45,7 +48,6 @@ private:
|
||||
Microblaze_to_HostPC = 0x81 // Microblaze processor data to host PC
|
||||
};
|
||||
|
||||
static bool FixSlaveVNETPacketNetID(Packet& packet);
|
||||
enum class CoreMiniNetwork : uint8_t {
|
||||
HSCAN1 = (0),
|
||||
MSCAN1 = (1),
|
||||
@@ -156,8 +158,11 @@ private:
|
||||
CommandType currentCommandType;
|
||||
size_t currentReadIndex = 0;
|
||||
|
||||
std::thread mainChannelReadThread;
|
||||
void readTask();
|
||||
std::thread hidReadThread;
|
||||
std::array<std::thread, NUM_SUPPORTED_VNETS> vnetThreads;
|
||||
std::array<moodycamel::BlockingReaderWriterQueue< std::vector<uint8_t> >, NUM_SUPPORTED_VNETS> vnetQueues;
|
||||
void hidReadTask();
|
||||
void vnetReadTask(size_t vnetIndex);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ public:
|
||||
|
||||
Packetizer(device_eventhandler_t report) : report(report) {}
|
||||
|
||||
std::vector<uint8_t>& packetWrap(std::vector<uint8_t>& data, bool shortFormat);
|
||||
std::vector<uint8_t>& packetWrap(std::vector<uint8_t>& data, bool shortFormat) const;
|
||||
|
||||
bool input(const std::vector<uint8_t>& bytes);
|
||||
std::vector<std::shared_ptr<Packet>> output();
|
||||
|
||||
@@ -111,13 +111,11 @@ protected:
|
||||
report = makeEventHandler();
|
||||
auto transport = makeTransport<Transport>();
|
||||
setupTransport(*transport);
|
||||
auto packetizer = makePacketizer();
|
||||
setupPacketizer(*packetizer);
|
||||
auto encoder = makeEncoder(packetizer);
|
||||
auto encoder = makeEncoder();
|
||||
setupEncoder(*encoder);
|
||||
auto decoder = makeDecoder();
|
||||
setupDecoder(*decoder);
|
||||
com = makeCommunication(std::move(transport), packetizer, std::move(encoder), std::move(decoder));
|
||||
com = makeCommunication(std::move(transport), std::bind(&Device::makeConfiguredPacketizer, this), std::move(encoder), std::move(decoder));
|
||||
setupCommunication(*com);
|
||||
settings = makeSettings<Settings>(com);
|
||||
setupSettings(*settings);
|
||||
@@ -136,10 +134,15 @@ protected:
|
||||
std::unique_ptr<ICommunication> makeTransport() { return std::unique_ptr<ICommunication>(new Transport(report, getWritableNeoDevice())); }
|
||||
virtual void setupTransport(ICommunication&) {}
|
||||
|
||||
virtual std::shared_ptr<Packetizer> makePacketizer() { return std::make_shared<Packetizer>(report); }
|
||||
virtual std::unique_ptr<Packetizer> makePacketizer() { return std::unique_ptr<Packetizer>(new Packetizer(report)); }
|
||||
virtual void setupPacketizer(Packetizer&) {}
|
||||
std::unique_ptr<Packetizer> makeConfiguredPacketizer() {
|
||||
auto packetizer = makePacketizer();
|
||||
setupPacketizer(*packetizer);
|
||||
return packetizer;
|
||||
}
|
||||
|
||||
virtual std::unique_ptr<Encoder> makeEncoder(std::shared_ptr<Packetizer> p) { return std::unique_ptr<Encoder>(new Encoder(report, p)); }
|
||||
virtual std::unique_ptr<Encoder> makeEncoder() { return std::unique_ptr<Encoder>(new Encoder(report)); }
|
||||
virtual void setupEncoder(Encoder&) {}
|
||||
|
||||
virtual std::unique_ptr<Decoder> makeDecoder() { return std::unique_ptr<Decoder>(new Decoder(report)); }
|
||||
@@ -147,9 +150,9 @@ protected:
|
||||
|
||||
virtual std::shared_ptr<Communication> makeCommunication(
|
||||
std::unique_ptr<ICommunication> t,
|
||||
std::shared_ptr<Packetizer> p,
|
||||
std::function<std::unique_ptr<Packetizer>()> makeConfiguredPacketizer,
|
||||
std::unique_ptr<Encoder> e,
|
||||
std::unique_ptr<Decoder> d) { return std::make_shared<Communication>(report, std::move(t), p, std::move(e), std::move(d)); }
|
||||
std::unique_ptr<Decoder> d) { return std::make_shared<Communication>(report, std::move(t), makeConfiguredPacketizer, std::move(e), std::move(d)); }
|
||||
virtual void setupCommunication(Communication&) {}
|
||||
|
||||
template<typename Settings>
|
||||
|
||||
@@ -12,10 +12,18 @@ class Plasion : public Device {
|
||||
protected:
|
||||
virtual std::shared_ptr<Communication> makeCommunication(
|
||||
std::unique_ptr<ICommunication> transport,
|
||||
std::shared_ptr<Packetizer> packetizer,
|
||||
std::function<std::unique_ptr<Packetizer>()> makeConfiguredPacketizer,
|
||||
std::unique_ptr<Encoder> encoder,
|
||||
std::unique_ptr<Decoder> decoder
|
||||
) override { return std::make_shared<MultiChannelCommunication>(report, std::move(transport), packetizer, std::move(encoder), std::move(decoder)); }
|
||||
) override {
|
||||
return std::make_shared<MultiChannelCommunication>(
|
||||
report,
|
||||
std::move(transport),
|
||||
makeConfiguredPacketizer,
|
||||
std::move(encoder),
|
||||
std::move(decoder)
|
||||
);
|
||||
}
|
||||
|
||||
// TODO This is done so that Plasion can still transmit it's basic networks, awaiting slave VNET support
|
||||
virtual bool isSupportedRXNetwork(const Network&) const override { return true; }
|
||||
|
||||
Reference in New Issue
Block a user