Extensions: Offer an opportunity to communicate with a dead device
parent
4cd7bafca7
commit
218648ae5a
|
|
@ -174,34 +174,36 @@ bool Device::open() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!afterCommunicationOpen()) {
|
APIEvent::Type attemptErr = attemptToBeginCommunication();
|
||||||
// Very unlikely, at the time of writing this only fails if rawWrite does.
|
if(attemptErr != APIEvent::Type::NoErrorFound) {
|
||||||
// If you're looking for this error, you're probably looking for if(!serial) below.
|
// We could not communicate with the device, let's see if an extension can
|
||||||
report(APIEvent::Type::NoSerialNumber, APIEvent::Severity::Error); // Communication could not be established with the device. Perhaps it is not powered with 12 volts?
|
bool tryAgain = false;
|
||||||
com->close();
|
forEachExtension([&tryAgain](const std::shared_ptr<DeviceExtension>& ext) -> bool {
|
||||||
return false;
|
if(ext->onDeviceCommunicationDead())
|
||||||
|
tryAgain = true;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if(!tryAgain) {
|
||||||
|
report(attemptErr, APIEvent::Severity::Error);
|
||||||
|
return false; // Extensions couldn't save us
|
||||||
|
}
|
||||||
|
attemptErr = attemptToBeginCommunication();
|
||||||
|
if(attemptErr != APIEvent::Type::NoErrorFound) {
|
||||||
|
report(attemptErr, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto serial = com->getSerialNumberSync();
|
bool block = false;
|
||||||
int i = 0;
|
forEachExtension([&block](const std::shared_ptr<DeviceExtension>& ext) {
|
||||||
while(!serial) {
|
if(ext->onDeviceOpen())
|
||||||
serial = com->getSerialNumberSync();
|
return true;
|
||||||
if(i++ > 5)
|
block = true;
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(!serial) {
|
|
||||||
report(APIEvent::Type::NoSerialNumber, APIEvent::Severity::Error); // Communication could not be established with the device. Perhaps it is not powered with 12 volts?
|
|
||||||
com->close();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
});
|
||||||
|
if(block) // Extensions say no
|
||||||
std::string currentSerial = getNeoDevice().serial;
|
|
||||||
if(currentSerial != serial->deviceSerial) {
|
|
||||||
report(APIEvent::Type::IncorrectSerialNumber, APIEvent::Severity::Error);
|
|
||||||
com->close();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if(!settings->disabled) {
|
if(!settings->disabled) {
|
||||||
// Since we will not fail the open if a settings read fails,
|
// Since we will not fail the open if a settings read fails,
|
||||||
// downgrade any errors to warnings. Otherwise the error will
|
// downgrade any errors to warnings. Otherwise the error will
|
||||||
|
|
@ -258,10 +260,40 @@ bool Device::open() {
|
||||||
com->removeMessageCallback(messageReceivedCallbackID);
|
com->removeMessageCallback(messageReceivedCallbackID);
|
||||||
});
|
});
|
||||||
|
|
||||||
forEachExtension([](const std::shared_ptr<DeviceExtension>& ext) { ext->onDeviceOpen(); return true; });
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
APIEvent::Type Device::attemptToBeginCommunication() {
|
||||||
|
if(!afterCommunicationOpen()) {
|
||||||
|
// Very unlikely, at the time of writing this only fails if rawWrite does.
|
||||||
|
// If you're looking for this error, you're probably looking for if(!serial) below.
|
||||||
|
com->close();
|
||||||
|
// "Communication could not be established with the device. Perhaps it is not powered with 12 volts?"
|
||||||
|
return APIEvent::Type::NoSerialNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto serial = com->getSerialNumberSync();
|
||||||
|
int i = 0;
|
||||||
|
while(!serial) {
|
||||||
|
serial = com->getSerialNumberSync();
|
||||||
|
if(i++ > 5)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!serial) {
|
||||||
|
com->close();
|
||||||
|
// "Communication could not be established with the device. Perhaps it is not powered with 12 volts?"
|
||||||
|
return APIEvent::Type::NoSerialNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string currentSerial = getNeoDevice().serial;
|
||||||
|
if(currentSerial != serial->deviceSerial) {
|
||||||
|
com->close();
|
||||||
|
return APIEvent::Type::IncorrectSerialNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
return APIEvent::Type::NoErrorFound;
|
||||||
|
}
|
||||||
|
|
||||||
bool Device::close() {
|
bool Device::close() {
|
||||||
if(!com) {
|
if(!com) {
|
||||||
report(APIEvent::Type::Unknown, APIEvent::Severity::Error);
|
report(APIEvent::Type::Unknown, APIEvent::Severity::Error);
|
||||||
|
|
|
||||||
|
|
@ -283,6 +283,8 @@ private:
|
||||||
std::vector<Network> supportedTXNetworks;
|
std::vector<Network> supportedTXNetworks;
|
||||||
std::vector<Network> supportedRXNetworks;
|
std::vector<Network> supportedRXNetworks;
|
||||||
|
|
||||||
|
APIEvent::Type attemptToBeginCommunication();
|
||||||
|
|
||||||
// Use heartbeatSuppressed instead when reading
|
// Use heartbeatSuppressed instead when reading
|
||||||
std::atomic<int> heartbeatSuppressedByUser{0};
|
std::atomic<int> heartbeatSuppressedByUser{0};
|
||||||
bool heartbeatSuppressed() const { return heartbeatSuppressedByUser > 0 || (settings && settings->applyingSettings); }
|
bool heartbeatSuppressed() const { return heartbeatSuppressedByUser > 0 || (settings && settings->applyingSettings); }
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,12 @@ public:
|
||||||
virtual ~DeviceExtension() = default;
|
virtual ~DeviceExtension() = default;
|
||||||
virtual const char* getName() const = 0;
|
virtual const char* getName() const = 0;
|
||||||
|
|
||||||
virtual void onDeviceOpen() {}
|
// Return false to block opening
|
||||||
|
virtual bool onDeviceOpen() { return true; }
|
||||||
|
|
||||||
|
// Return true to indicate that communication should now be back
|
||||||
|
virtual bool onDeviceCommunicationDead() { return false; }
|
||||||
|
|
||||||
virtual void onGoOnline() {}
|
virtual void onGoOnline() {}
|
||||||
virtual void onGoOffline() {}
|
virtual void onGoOffline() {}
|
||||||
virtual void onDeviceClose() {}
|
virtual void onDeviceClose() {}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue