Communication: Avoid MessageFilter type punning in waitForMessageSync

v0.3.0-dev
Paul Hollinsky 2021-12-02 15:00:13 -05:00
parent 78747aa899
commit f8b5710a6c
7 changed files with 34 additions and 21 deletions

View File

@ -24,5 +24,5 @@ int LegacyDLLExport icsneoWaitForRxMessagesWithTimeOut(void* hObject, unsigned i
neodevice_t* device = (neodevice_t*)hObject; neodevice_t* device = (neodevice_t*)hObject;
if(device->device->getCurrentMessageCount() != 0) if(device->device->getCurrentMessageCount() != 0)
return true; return true;
return bool(device->device->com->waitForMessageSync(MessageFilter(), std::chrono::milliseconds(iTimeOut))); return bool(device->device->com->waitForMessageSync({}, std::chrono::milliseconds(iTimeOut)));
} }

View File

@ -112,9 +112,10 @@ void Communication::clearRedirectRead() {
} }
bool Communication::getSettingsSync(std::vector<uint8_t>& data, std::chrono::milliseconds timeout) { bool Communication::getSettingsSync(std::vector<uint8_t>& data, std::chrono::milliseconds timeout) {
static const std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(Network::NetID::ReadSettings);
std::shared_ptr<Message> msg = waitForMessageSync([this]() { std::shared_ptr<Message> msg = waitForMessageSync([this]() {
return sendCommand(Command::ReadSettings, { 0, 0, 0, 1 /* Get Global Settings */, 0, 1 /* Subversion 1 */ }); return sendCommand(Command::ReadSettings, { 0, 0, 0, 1 /* Get Global Settings */, 0, 1 /* Subversion 1 */ });
}, MessageFilter(Network::NetID::ReadSettings), timeout); }, filter, timeout);
if(!msg) if(!msg)
return false; return false;
@ -134,25 +135,35 @@ bool Communication::getSettingsSync(std::vector<uint8_t>& data, std::chrono::mil
} }
std::shared_ptr<SerialNumberMessage> Communication::getSerialNumberSync(std::chrono::milliseconds timeout) { std::shared_ptr<SerialNumberMessage> Communication::getSerialNumberSync(std::chrono::milliseconds timeout) {
static const std::shared_ptr<MessageFilter> filter = std::make_shared<Main51MessageFilter>(Command::RequestSerialNumber);
std::shared_ptr<Message> msg = waitForMessageSync([this]() { std::shared_ptr<Message> msg = waitForMessageSync([this]() {
return sendCommand(Command::RequestSerialNumber); return sendCommand(Command::RequestSerialNumber);
}, Main51MessageFilter(Command::RequestSerialNumber), timeout); }, filter, timeout);
if(!msg) // Did not receive a message if(!msg) // Did not receive a message
{
std::cout << "didn't get a message" << std::endl;
return std::shared_ptr<SerialNumberMessage>(); return std::shared_ptr<SerialNumberMessage>();
}
auto m51 = std::dynamic_pointer_cast<Main51Message>(msg); auto m51 = std::dynamic_pointer_cast<Main51Message>(msg);
if(!m51) // Could not upcast for some reason if(!m51) // Could not upcast for some reason
{
std::cout << "could not upcast" << std::endl;
return std::shared_ptr<SerialNumberMessage>(); return std::shared_ptr<SerialNumberMessage>();
}
return std::dynamic_pointer_cast<SerialNumberMessage>(m51); auto ret = std::dynamic_pointer_cast<SerialNumberMessage>(m51);
std::cout << "returning " << ret.get() << std::endl;
return ret;
} }
optional< std::vector< optional<DeviceAppVersion> > > Communication::getVersionsSync(std::chrono::milliseconds timeout) { optional< std::vector< optional<DeviceAppVersion> > > Communication::getVersionsSync(std::chrono::milliseconds timeout) {
static const std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(Message::Type::DeviceVersion);
std::vector< optional<DeviceAppVersion> > ret; std::vector< optional<DeviceAppVersion> > ret;
std::shared_ptr<Message> msg = waitForMessageSync([this]() { std::shared_ptr<Message> msg = waitForMessageSync([this]() {
return sendCommand(Command::GetMainVersion); return sendCommand(Command::GetMainVersion);
}, Main51MessageFilter(Command::GetMainVersion), timeout); }, filter, timeout);
if(!msg) // Did not receive a message if(!msg) // Did not receive a message
return nullopt; return nullopt;
@ -167,7 +178,7 @@ optional< std::vector< optional<DeviceAppVersion> > > Communication::getVersions
msg = waitForMessageSync([this]() { msg = waitForMessageSync([this]() {
return sendCommand(Command::GetSecondaryVersions); return sendCommand(Command::GetSecondaryVersions);
}, Main51MessageFilter(Command::GetSecondaryVersions), timeout); }, filter, timeout);
if(msg) { // This one is allowed to fail if(msg) { // This one is allowed to fail
ver = std::dynamic_pointer_cast<VersionMessage>(msg); ver = std::dynamic_pointer_cast<VersionMessage>(msg);
if(ver && ver->ForChip != VersionMessage::MainChip) if(ver && ver->ForChip != VersionMessage::MainChip)
@ -194,7 +205,8 @@ bool Communication::removeMessageCallback(int id) {
} }
} }
std::shared_ptr<Message> Communication::waitForMessageSync(std::function<bool(void)> onceWaitingDo, MessageFilter f, std::chrono::milliseconds timeout) { std::shared_ptr<Message> Communication::waitForMessageSync(std::function<bool(void)> onceWaitingDo,
const std::shared_ptr<MessageFilter>& f, std::chrono::milliseconds timeout) {
std::mutex m; std::mutex m;
std::condition_variable cv; std::condition_variable cv;
std::shared_ptr<Message> returnedMessage; std::shared_ptr<Message> returnedMessage;

View File

@ -345,8 +345,8 @@ bool Device::goOnline() {
updateLEDState(); updateLEDState();
MessageFilter filter(Network::NetID::Reset_Status); std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(Network::NetID::Reset_Status);
filter.includeInternalInAny = true; filter->includeInternalInAny = true;
// Wait until communication is enabled or 5 seconds, whichever comes first // Wait until communication is enabled or 5 seconds, whichever comes first
while((std::chrono::system_clock::now() - startTime) < std::chrono::seconds(5)) { while((std::chrono::system_clock::now() - startTime) < std::chrono::seconds(5)) {
@ -388,8 +388,8 @@ bool Device::goOffline() {
updateLEDState(); updateLEDState();
MessageFilter filter(Network::NetID::Reset_Status); std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(Network::NetID::Reset_Status);
filter.includeInternalInAny = true; filter->includeInternalInAny = true;
// Wait until communication is disabled or 5 seconds, whichever comes first // Wait until communication is disabled or 5 seconds, whichever comes first
while((std::chrono::system_clock::now() - startTime) < std::chrono::seconds(5)) { while((std::chrono::system_clock::now() - startTime) < std::chrono::seconds(5)) {

View File

@ -593,6 +593,7 @@ uint16_t FlexRay::Controller::CalculateCycleFilter(uint8_t baseCycle, uint8_t cy
} }
std::pair<bool, uint32_t> FlexRay::Controller::readRegister(ERAYRegister reg, std::chrono::milliseconds timeout) const { std::pair<bool, uint32_t> FlexRay::Controller::readRegister(ERAYRegister reg, std::chrono::milliseconds timeout) const {
static const std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(icsneo::Network::NetID::FlexRayControl);
if(timeout.count() <= 20) if(timeout.count() <= 20)
return {false, 0}; // Out of time! return {false, 0}; // Out of time!
@ -611,7 +612,7 @@ std::pair<bool, uint32_t> FlexRay::Controller::readRegister(ERAYRegister reg, st
return false; // Command failed to send return false; // Command failed to send
lastSent = std::chrono::steady_clock::now(); lastSent = std::chrono::steady_clock::now();
return true; return true;
}, MessageFilter(icsneo::Network::NetID::FlexRayControl), timeout); }, filter, timeout);
if(auto frmsg = std::dynamic_pointer_cast<FlexRayControlMessage>(msg)) { if(auto frmsg = std::dynamic_pointer_cast<FlexRayControlMessage>(msg)) {
if(frmsg->decoded && frmsg->controller == index && frmsg->opcode == FlexRay::Opcode::ReadCCRegs) if(frmsg->decoded && frmsg->controller == index && frmsg->opcode == FlexRay::Opcode::ReadCCRegs)
resp = frmsg; resp = frmsg;

View File

@ -230,7 +230,7 @@ bool IDeviceSettings::apply(bool temporary) {
std::shared_ptr<Main51Message> msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() { std::shared_ptr<Main51Message> msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() {
return com->sendCommand(Command::SetSettings, bytestream); return com->sendCommand(Command::SetSettings, bytestream);
}, Main51MessageFilter(Command::SetSettings), std::chrono::milliseconds(1000))); }, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000)));
if(!msg || msg->data[0] != 1) { // We did not receive a response if(!msg || msg->data[0] != 1) { // We did not receive a response
// Attempt to get the settings from the device so we're up to date if possible // Attempt to get the settings from the device so we're up to date if possible
@ -256,7 +256,7 @@ bool IDeviceSettings::apply(bool temporary) {
msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() { msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() {
return com->sendCommand(Command::SetSettings, bytestream); return com->sendCommand(Command::SetSettings, bytestream);
}, Main51MessageFilter(Command::SetSettings), std::chrono::milliseconds(1000))); }, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000)));
if(!msg || msg->data[0] != 1) { if(!msg || msg->data[0] != 1) {
// Attempt to get the settings from the device so we're up to date if possible // Attempt to get the settings from the device so we're up to date if possible
if(refresh()) { if(refresh()) {
@ -269,7 +269,7 @@ bool IDeviceSettings::apply(bool temporary) {
if(!temporary) { if(!temporary) {
msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this]() { msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this]() {
return com->sendCommand(Command::SaveSettings); return com->sendCommand(Command::SaveSettings);
}, Main51MessageFilter(Command::SaveSettings), std::chrono::milliseconds(5000))); }, std::make_shared<Main51MessageFilter>(Command::SaveSettings), std::chrono::milliseconds(5000)));
} }
applyingSettings = false; applyingSettings = false;
@ -298,7 +298,7 @@ bool IDeviceSettings::applyDefaults(bool temporary) {
std::shared_ptr<Main51Message> msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this]() { std::shared_ptr<Main51Message> msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this]() {
return com->sendCommand(Command::SetDefaultSettings); return com->sendCommand(Command::SetDefaultSettings);
}, Main51MessageFilter(Command::SetDefaultSettings), std::chrono::milliseconds(1000))); }, std::make_shared<Main51MessageFilter>(Command::SetDefaultSettings), std::chrono::milliseconds(1000)));
if(!msg || msg->data[0] != 1) { if(!msg || msg->data[0] != 1) {
// Attempt to get the settings from the device so we're up to date if possible // Attempt to get the settings from the device so we're up to date if possible
if(refresh()) { if(refresh()) {
@ -333,7 +333,7 @@ bool IDeviceSettings::applyDefaults(bool temporary) {
msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() { msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() {
return com->sendCommand(Command::SetSettings, bytestream); return com->sendCommand(Command::SetSettings, bytestream);
}, Main51MessageFilter(Command::SetSettings), std::chrono::milliseconds(1000))); }, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000)));
if(!msg || msg->data[0] != 1) { if(!msg || msg->data[0] != 1) {
// Attempt to get the settings from the device so we're up to date if possible // Attempt to get the settings from the device so we're up to date if possible
if(refresh()) { if(refresh()) {
@ -346,7 +346,7 @@ bool IDeviceSettings::applyDefaults(bool temporary) {
if(!temporary) { if(!temporary) {
msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this]() { msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this]() {
return com->sendCommand(Command::SaveSettings); return com->sendCommand(Command::SaveSettings);
}, Main51MessageFilter(Command::SaveSettings), std::chrono::milliseconds(5000))); }, std::make_shared<Main51MessageFilter>(Command::SaveSettings), std::chrono::milliseconds(5000)));
} }
applyingSettings = false; applyingSettings = false;

View File

@ -60,7 +60,7 @@ public:
int addMessageCallback(const MessageCallback& cb); int addMessageCallback(const MessageCallback& cb);
bool removeMessageCallback(int id); bool removeMessageCallback(int id);
std::shared_ptr<Message> waitForMessageSync( std::shared_ptr<Message> waitForMessageSync(
MessageFilter f = MessageFilter(), const std::shared_ptr<MessageFilter>& f = {},
std::chrono::milliseconds timeout = std::chrono::milliseconds(50)) { std::chrono::milliseconds timeout = std::chrono::milliseconds(50)) {
return waitForMessageSync([](){ return true; }, f, timeout); return waitForMessageSync([](){ return true; }, f, timeout);
} }
@ -68,7 +68,7 @@ public:
// Return false to bail early, in case your initial command failed. // Return false to bail early, in case your initial command failed.
std::shared_ptr<Message> waitForMessageSync( std::shared_ptr<Message> waitForMessageSync(
std::function<bool(void)> onceWaitingDo, std::function<bool(void)> onceWaitingDo,
MessageFilter f = MessageFilter(), const std::shared_ptr<MessageFilter>& f = {},
std::chrono::milliseconds timeout = std::chrono::milliseconds(50)); std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
std::function<std::unique_ptr<Packetizer>()> makeConfiguredPacketizer; std::function<std::unique_ptr<Packetizer>()> makeConfiguredPacketizer;

View File

@ -19,7 +19,7 @@ public:
// We still guarantee it's a Main51Message if it matches because of the dynamic_pointer_cast below // We still guarantee it's a Main51Message if it matches because of the dynamic_pointer_cast below
Main51MessageFilter(Command command) : command(command) { includeInternalInAny = true; } Main51MessageFilter(Command command) : command(command) { includeInternalInAny = true; }
bool match(const std::shared_ptr<Message>& message) const { bool match(const std::shared_ptr<Message>& message) const override {
if(!MessageFilter::match(message)) { if(!MessageFilter::match(message)) {
//std::cout << "message filter did not match base for " << message->network << std::endl; //std::cout << "message filter did not match base for " << message->network << std::endl;
return false; return false;