Begin adding an encoder for messages
parent
d7372bbd5a
commit
5bf50ddc00
|
|
@ -46,7 +46,7 @@ bool Communication::close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Communication::sendPacket(std::vector<uint8_t>& bytes) {
|
bool Communication::sendPacket(std::vector<uint8_t>& bytes) {
|
||||||
return impl->write(packetizer->packetWrap(bytes));
|
return rawWrite(packetizer->packetWrap(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Communication::sendCommand(Command cmd, std::vector<uint8_t> arguments) {
|
bool Communication::sendCommand(Command cmd, std::vector<uint8_t> arguments) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
#include "communication/include/encoder.h"
|
||||||
|
|
||||||
|
using namespace icsneo;
|
||||||
|
|
||||||
|
std::shared_ptr<Message> Encoder::encode(const std::shared_ptr<Message>& message) {
|
||||||
|
switch(message->network.getType()) {
|
||||||
|
// case Network::Type::CAN: {
|
||||||
|
// if(message->data.size() < 24)
|
||||||
|
// break; // We would read garbage when interpereting the data
|
||||||
|
|
||||||
|
// HardwareCANPacket* data = (HardwareCANPacket*)message->data.data();
|
||||||
|
// auto msg = std::make_shared<CANMessage>();
|
||||||
|
// msg->network = message->network;
|
||||||
|
// msg->arbid = data->header.SID;
|
||||||
|
// msg->data.reserve(data->dlc.DLC);
|
||||||
|
|
||||||
|
// // Timestamp calculation
|
||||||
|
// msg->timestamp = data->timestamp.TS * 25; // Timestamps are in 25ns increments since 1/1/2007 GMT 00:00:00.0000
|
||||||
|
|
||||||
|
// for(auto i = 0; i < data->dlc.DLC; i++)
|
||||||
|
// msg->data.push_back(data->data[i]);
|
||||||
|
// return msg;
|
||||||
|
// }
|
||||||
|
default:
|
||||||
|
switch(message->network.getNetID()) {
|
||||||
|
case Network::NetID::Main51:
|
||||||
|
if(message->data.size() > 0xF) {
|
||||||
|
message->network = Network::NetID::RED_OLDFORMAT;
|
||||||
|
message->data.insert(message->data.begin(), 0x10 | (uint8_t)Network::NetID::Main51);
|
||||||
|
return encode(message);
|
||||||
|
}
|
||||||
|
message->data.insert(message->data.begin(), (message->data.size() << 4) | (uint8_t)Network::NetID::Main51);
|
||||||
|
data.in
|
||||||
|
break;
|
||||||
|
case Network::NetID::RED_OLDFORMAT: {
|
||||||
|
// See the decoder for an explanation
|
||||||
|
uint16_t length = message->data[0] | (message->data[1] << 8);
|
||||||
|
message->network = Network(message->data[2] & 0xF);
|
||||||
|
message->data.erase(message->data.begin(), message->data.begin() + 3);
|
||||||
|
if(message->data.size() != length)
|
||||||
|
message->data.resize(length);
|
||||||
|
return decodePacket(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto msg = std::make_shared<Message>();
|
||||||
|
msg->network = message->network;
|
||||||
|
msg->data = message->data;
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> Encoder::encode(Command cmd, std::vector<uint8_t> arguments = {}) {
|
||||||
|
auto msg = std::make_shared<Message>();
|
||||||
|
msg->network = Network::NetID::Main51;
|
||||||
|
msg->data.resize(arguments.size() + 1);
|
||||||
|
msg->data.push_back((uint8_t)cmd);
|
||||||
|
msg->data.insert(msg->data.end(), std::make_move_iterator(arguments.begin()), std::make_move_iterator(arguments.end()));
|
||||||
|
return encode(msg);
|
||||||
|
}
|
||||||
|
|
@ -28,7 +28,7 @@ public:
|
||||||
virtual void spawnThreads();
|
virtual void spawnThreads();
|
||||||
virtual void joinThreads();
|
virtual void joinThreads();
|
||||||
bool rawWrite(const std::vector<uint8_t>& bytes) { return impl->write(bytes); }
|
bool rawWrite(const std::vector<uint8_t>& bytes) { return impl->write(bytes); }
|
||||||
bool sendPacket(std::vector<uint8_t>& bytes);
|
virtual bool sendPacket(std::vector<uint8_t>& bytes);
|
||||||
|
|
||||||
virtual bool sendCommand(Command cmd, bool boolean) { return sendCommand(cmd, std::vector<uint8_t>({ (uint8_t)boolean })); }
|
virtual bool sendCommand(Command cmd, bool boolean) { return sendCommand(cmd, std::vector<uint8_t>({ (uint8_t)boolean })); }
|
||||||
virtual bool sendCommand(Command cmd, std::vector<uint8_t> arguments = {});
|
virtual bool sendCommand(Command cmd, std::vector<uint8_t> arguments = {});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
#ifndef __ENCODER_H_
|
||||||
|
#define __ENCODER_H_
|
||||||
|
|
||||||
|
#include "communication/message/include/message.h"
|
||||||
|
#include "communication/message/include/canmessage.h"
|
||||||
|
#include "communication/include/packet.h"
|
||||||
|
#include "communication/include/network.h"
|
||||||
|
#include <queue>
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
|
namespace icsneo {
|
||||||
|
|
||||||
|
class Encoder {
|
||||||
|
public:
|
||||||
|
std::vector<uint8_t> encode(const std::shared_ptr<Message>& message);
|
||||||
|
std::vector<uint8_t> encode(Command cmd, bool boolean) { return encode(cmd, std::vector<uint8_t>({ (uint8_t)boolean })); }
|
||||||
|
std::vector<uint8_t> encode(Command cmd, std::vector<uint8_t> arguments = {});
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef uint16_t icscm_bitfield;
|
||||||
|
struct HardwareCANPacket {
|
||||||
|
struct {
|
||||||
|
icscm_bitfield IDE : 1;
|
||||||
|
icscm_bitfield SRR : 1;
|
||||||
|
icscm_bitfield SID : 11;
|
||||||
|
icscm_bitfield EDL : 1;
|
||||||
|
icscm_bitfield BRS : 1;
|
||||||
|
icscm_bitfield ESI : 1;
|
||||||
|
} header;
|
||||||
|
struct {
|
||||||
|
icscm_bitfield EID : 12;
|
||||||
|
icscm_bitfield TXMSG : 1;
|
||||||
|
icscm_bitfield TXAborted : 1;
|
||||||
|
icscm_bitfield TXLostArb : 1;
|
||||||
|
icscm_bitfield TXError : 1;
|
||||||
|
} eid;
|
||||||
|
struct {
|
||||||
|
icscm_bitfield DLC : 4;
|
||||||
|
icscm_bitfield RB0 : 1;
|
||||||
|
icscm_bitfield IVRIF : 1;
|
||||||
|
icscm_bitfield HVEnable : 1;// must be cleared before passing into CAN driver
|
||||||
|
icscm_bitfield ExtendedNetworkIndexBit : 1;//DO NOT CLOBBER THIS
|
||||||
|
icscm_bitfield RB1 : 1;
|
||||||
|
icscm_bitfield RTR : 1;
|
||||||
|
icscm_bitfield EID : 6;
|
||||||
|
} dlc;
|
||||||
|
unsigned char data[8];
|
||||||
|
struct {
|
||||||
|
uint64_t TS : 60;
|
||||||
|
uint64_t : 3;
|
||||||
|
uint64_t IsExtended : 1;
|
||||||
|
} timestamp;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -10,9 +10,9 @@ namespace icsneo {
|
||||||
class MultiChannelCommunication : public Communication {
|
class MultiChannelCommunication : public Communication {
|
||||||
public:
|
public:
|
||||||
MultiChannelCommunication(std::shared_ptr<ICommunication> com, std::shared_ptr<Packetizer> p, std::shared_ptr<Decoder> md) : Communication(com, p, md) {}
|
MultiChannelCommunication(std::shared_ptr<ICommunication> com, std::shared_ptr<Packetizer> p, std::shared_ptr<Decoder> md) : Communication(com, p, md) {}
|
||||||
void spawnThreads();
|
void spawnThreads() override;
|
||||||
void joinThreads();
|
void joinThreads() override;
|
||||||
bool sendCommand(Command cmd, std::vector<uint8_t> arguments);
|
bool sendPacket(std::vector<uint8_t>& bytes) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool preprocessPacket(std::deque<uint8_t>& usbReadFifo);
|
bool preprocessPacket(std::deque<uint8_t>& usbReadFifo);
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ namespace icsneo {
|
||||||
class Packetizer {
|
class Packetizer {
|
||||||
public:
|
public:
|
||||||
static uint8_t ICSChecksum(const std::vector<uint8_t>& data);
|
static uint8_t ICSChecksum(const std::vector<uint8_t>& data);
|
||||||
std::vector<uint8_t>& packetWrap(std::vector<uint8_t>& data);
|
std::vector<uint8_t>& packetWrap(std::vector<uint8_t>& data, bool checksum = true);
|
||||||
|
|
||||||
bool input(const std::vector<uint8_t>& bytes);
|
bool input(const std::vector<uint8_t>& bytes);
|
||||||
std::vector<std::shared_ptr<Packet>> output();
|
std::vector<std::shared_ptr<Packet>> output();
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,7 @@ void MultiChannelCommunication::joinThreads() {
|
||||||
mainChannelReadThread.join();
|
mainChannelReadThread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MultiChannelCommunication::sendCommand(Command cmd, std::vector<uint8_t> arguments) {
|
bool MultiChannelCommunication::sendPacket(std::vector<uint8_t>& bytes) {
|
||||||
std::vector<uint8_t> bytes;
|
|
||||||
bytes.push_back((uint8_t)cmd);
|
|
||||||
for(auto& b : arguments)
|
|
||||||
bytes.push_back(b);
|
|
||||||
bytes.insert(bytes.begin(), 0xB | ((uint8_t)bytes.size() << 4));
|
|
||||||
bytes = packetizer->packetWrap(bytes);
|
|
||||||
bytes.insert(bytes.begin(), {(uint8_t)CommandType::HostPC_to_Vnet1, (uint8_t)bytes.size(), (uint8_t)(bytes.size() >> 8)});
|
bytes.insert(bytes.begin(), {(uint8_t)CommandType::HostPC_to_Vnet1, (uint8_t)bytes.size(), (uint8_t)(bytes.size() >> 8)});
|
||||||
return rawWrite(bytes);
|
return rawWrite(bytes);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ uint8_t Packetizer::ICSChecksum(const std::vector<uint8_t>& data) {
|
||||||
return (uint8_t)checksum;
|
return (uint8_t)checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t>& Packetizer::packetWrap(std::vector<uint8_t>& data) {
|
std::vector<uint8_t>& Packetizer::packetWrap(std::vector<uint8_t>& data, bool checksum) {
|
||||||
if(!disableChecksum)
|
if(!disableChecksum && checksum)
|
||||||
data.push_back(ICSChecksum(data));
|
data.push_back(ICSChecksum(data));
|
||||||
data.insert(data.begin(), 0xAA);
|
data.insert(data.begin(), 0xAA);
|
||||||
if(align16bit && data.size() % 2 == 1)
|
if(align16bit && data.size() % 2 == 1)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue