Check serial number on device open, get correctly for PCAP devices

This commit is contained in:
Paul Hollinsky
2018-09-25 17:53:58 -04:00
parent 72773d9afa
commit 69773d6537
7 changed files with 97 additions and 29 deletions
+13 -12
View File
@@ -68,19 +68,20 @@ bool Communication::getSettingsSync(std::vector<uint8_t>& data, std::chrono::mil
return true;
}
bool Communication::getSerialNumberSync(std::string& serial, std::chrono::milliseconds timeout) {
std::shared_ptr<SerialNumberMessage> Communication::getSerialNumberSync(std::chrono::milliseconds timeout) {
sendCommand(Command::RequestSerialNumber);
std::shared_ptr<Message> msg = waitForMessageSync(MessageFilter(Network::NetID::RED_OLDFORMAT), timeout);
if(!msg)
return false;
std::cout << "Got " << msg->data.size() << " bytes" << std::endl;
for(size_t i = 0; i < msg->data.size(); i++) {
std::cout << std::hex << (int)msg->data[i] << ' ' << std::dec;
if(i % 16 == 15)
std::cout << std::endl;
std::shared_ptr<Message> msg = waitForMessageSync(std::make_shared<Main51MessageFilter>(Command::RequestSerialNumber), timeout);
if(!msg) {
std::cout << "Didn't get a message in time" << std::endl;
return std::shared_ptr<SerialNumberMessage>();
}
return true;
auto m51 = std::dynamic_pointer_cast<Main51Message>(msg);
if(!m51) {
std::cout << "msg could not be cast to main51 " << msg->network << std::endl;
return std::shared_ptr<SerialNumberMessage>();
}
return std::dynamic_pointer_cast<SerialNumberMessage>(m51);
}
int Communication::addMessageCallback(const MessageCallback& cb) {
@@ -97,7 +98,7 @@ bool Communication::removeMessageCallback(int id) {
}
}
std::shared_ptr<Message> Communication::waitForMessageSync(MessageFilter f, std::chrono::milliseconds timeout) {
std::shared_ptr<Message> Communication::waitForMessageSync(std::shared_ptr<MessageFilter> f, std::chrono::milliseconds timeout) {
std::mutex m;
std::condition_variable cv;
std::shared_ptr<Message> returnedMessage;
+5 -5
View File
@@ -33,13 +33,14 @@ public:
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 = {});
bool getSettingsSync(std::vector<uint8_t>& data, std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
bool getSerialNumberSync(std::string& serial, std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
std::shared_ptr<SerialNumberMessage> getSerialNumberSync(std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
int addMessageCallback(const MessageCallback& cb);
bool removeMessageCallback(int id);
std::shared_ptr<Message> waitForMessageSync(MessageFilter f = MessageFilter(), std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
void setAlign16Bit(bool enable) { align16bit = enable; }
std::shared_ptr<Message> waitForMessageSync(MessageFilter f = MessageFilter(), std::chrono::milliseconds timeout = std::chrono::milliseconds(50)) {
return waitForMessageSync(std::make_shared<MessageFilter>(f), timeout);
}
std::shared_ptr<Message> waitForMessageSync(std::shared_ptr<MessageFilter> f, std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
std::shared_ptr<Packetizer> packetizer;
std::shared_ptr<MessageDecoder> decoder;
@@ -52,7 +53,6 @@ protected:
private:
bool isOpen = false;
bool align16bit = true; // Not needed for Gigalog, Galaxy, etc and newer
std::thread readTaskThread;
void readTask();
+37 -1
View File
@@ -1,5 +1,6 @@
#include "communication/include/messagedecoder.h"
#include "communication/include/communication.h"
#include "communication/message/include/serialnumbermessage.h"
#include "communication/include/command.h"
#include "device/include/device.h"
#include <iostream>
@@ -33,7 +34,42 @@ std::shared_ptr<Message> MessageDecoder::decodePacket(const std::shared_ptr<Pack
return msg;
}
default:
// TODO Implement others
switch(packet->network.getNetID()) {
case Network::NetID::Main51: {
switch((Command)packet->data[0]) {
case Command::RequestSerialNumber: {
auto msg = std::make_shared<SerialNumberMessage>();
msg->network = packet->network;
uint64_t serial = GetUInt64FromLEBytes(packet->data.data() + 1);
// The device sends 64-bits of serial number, but we never use more than 32-bits.
msg->deviceSerial = Device::SerialNumToString((uint32_t)serial);
msg->hasMacAddress = packet->data.size() >= 15;
if(msg->hasMacAddress)
memcpy(msg->macAddress, packet->data.data() + 9, sizeof(msg->macAddress));
msg->hasPCBSerial = packet->data.size() >= 31;
if(msg->hasPCBSerial)
memcpy(msg->pcbSerial, packet->data.data() + 15, sizeof(msg->pcbSerial));
return msg;
}
}
break;
}
case Network::NetID::RED_OLDFORMAT: {
/* So-called "old format" messages are a "new style, long format" wrapper around the old short messages.
* They consist of a 16-bit LE length first, then the 8-bit length and netid combo byte, then the payload
* with no checksum. The upper-nibble length of the combo byte should be ignored completely, using the
* length from the first two bytes in it's place. Ideally, we never actually send the oldformat messages
* out to the rest of the application as they can recursively get decoded to another message type here.
* Feed the result back into the decoder in case we do something special with the resultant netid.
*/
uint16_t length = packet->data[0] | (packet->data[1] << 8);
packet->network = Network(packet->data[2] & 0xF);
packet->data.erase(packet->data.begin(), packet->data.begin() + 3);
if(packet->data.size() != length)
packet->data.resize(length);
return decodePacket(packet);
}
}
break;
}
+3 -3
View File
@@ -54,7 +54,7 @@ bool Packetizer::input(const std::vector<uint8_t>& inputBytes) {
headerSize = 6;
} else {
state = ReadState::GetData;
checksum = true;
checksum = true; // Even if checksum is not explicitly disallowed, we enable it here, as this goes into length calculation
headerSize = 2;
packetLength += 2; // The packet length given in short packets does not include header
}
@@ -99,10 +99,10 @@ bool Packetizer::input(const std::vector<uint8_t>& inputBytes) {
while(currentIndex < packetLength)
packet.data[i++] = bytes[currentIndex++];
if(!checksum || bytes[currentIndex] == Communication::ICSChecksum(packet.data)) {
if(disableChecksum || !checksum || bytes[currentIndex] == ICSChecksum(packet.data)) {
// Got a good packet
gotGoodPackets = true;
processedPackets.push_back(std::make_shared<Communication::Packet>(packet));
processedPackets.push_back(std::make_shared<Packet>(packet));
for (auto a = 0; a < packetLength; a++)
bytes.pop_front();
} else {