diff --git a/api/icsneocpp/event.cpp b/api/icsneocpp/event.cpp index 71aed02..af0d910 100644 --- a/api/icsneocpp/event.cpp +++ b/api/icsneocpp/event.cpp @@ -72,6 +72,7 @@ static constexpr const char* MESSAGE_MAX_LENGTH_EXCEEDED = "The message was too static constexpr const char* VALUE_NOT_YET_PRESENT = "The value is not yet present."; static constexpr const char* TIMEOUT = "The timeout was reached."; static constexpr const char* WIVI_NOT_SUPPORTED = "Wireless neoVI functions are not supported on this device."; +static constexpr const char* RESTRICTED_ENTRY_FLAG = "Attempted to set a restricted flag in a Root Directory entry."; // Device Errors static constexpr const char* POLLING_MESSAGE_OVERFLOW = "Too many messages have been recieved for the polling message buffer, some have been lost!"; @@ -218,6 +219,8 @@ const char* APIEvent::DescriptionForType(Type type) { return TIMEOUT; case Type::WiVINotSupported: return WIVI_NOT_SUPPORTED; + case Type::RestrictedEntryFlag: + return RESTRICTED_ENTRY_FLAG; // Device Errors case Type::PollingMessageOverflow: diff --git a/device/device.cpp b/device/device.cpp index e1f22ab..9807fd4 100644 --- a/device/device.cpp +++ b/device/device.cpp @@ -1709,7 +1709,7 @@ std::optional Device::sendEthPhyMsg(const EthPhyMessage& message, return std::make_optional(*retMsg); } -std::optional Device::SetCollectionUploaded(uint32_t collectionEntryByteAddress) +std::optional Device::SetRootDirectoryEntryFlags(uint8_t mask, uint8_t values, uint32_t collectionEntryByteAddress) { if(!supportsWiVI()) { @@ -1717,15 +1717,31 @@ std::optional Device::SetCollectionUploaded(uint32_t collectionEntryByteAd return std::nullopt; } + if (mask & RootDirectoryEntryFlags::IsPrePost) + { + report(APIEvent::Type::RestrictedEntryFlag, APIEvent::Severity::EventWarning); + mask &= ~RootDirectoryEntryFlags::IsPrePost; + values &= ~RootDirectoryEntryFlags::IsPrePost; + } + + if (mask & RootDirectoryEntryFlags::PrePostTriggered) + { + report(APIEvent::Type::RestrictedEntryFlag, APIEvent::Severity::EventWarning); + mask &= ~RootDirectoryEntryFlags::PrePostTriggered; + values &= ~RootDirectoryEntryFlags::PrePostTriggered; + } + auto timeout = std::chrono::milliseconds(2500); std::vector args( {(uint8_t)(collectionEntryByteAddress & 0xFF), (uint8_t)((collectionEntryByteAddress >> 8) & 0xFF), (uint8_t)((collectionEntryByteAddress >> 16) & 0xFF), - (uint8_t)((collectionEntryByteAddress >> 24) & 0xFF)}); + (uint8_t)((collectionEntryByteAddress >> 24) & 0xFF), + values, + mask}); std::shared_ptr response = com->waitForMessageSync( - [this, args](){ return com->sendCommand(ExtendedCommand::SetUploadedFlag, args); }, + [this, args](){ return com->sendCommand(ExtendedCommand::SetRootFSEntryFlags, args); }, std::make_shared(Message::Type::ExtendedResponse), timeout); if(!response) { @@ -1737,7 +1753,7 @@ std::optional Device::SetCollectionUploaded(uint32_t collectionEntryByteAd { // TODO fix this error report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error); - return std::make_optional(false); + return false; } bool success = retMsg->response == ExtendedResponse::OK; if(!success) @@ -1745,8 +1761,8 @@ std::optional Device::SetCollectionUploaded(uint32_t collectionEntryByteAd // TODO fix this error report(APIEvent::Type::Unknown, APIEvent::Severity::EventWarning); } - // Valid device with a properly formed respose, return success - return std::make_optional(success); + // Valid device with a properly formed response, return success + return success; } std::optional> Device::getRTC() diff --git a/include/icsneo/api/event.h b/include/icsneo/api/event.h index f06f082..f8b9526 100644 --- a/include/icsneo/api/event.h +++ b/include/icsneo/api/event.h @@ -49,6 +49,7 @@ public: ValueNotYetPresent = 0x1013, Timeout = 0x1014, WiVINotSupported = 0x1015, + RestrictedEntryFlag = 0x1016, // Device Events PollingMessageOverflow = 0x2000, diff --git a/include/icsneo/communication/command.h b/include/icsneo/communication/command.h index 141bb14..c13700d 100644 --- a/include/icsneo/communication/command.h +++ b/include/icsneo/communication/command.h @@ -52,7 +52,7 @@ enum class ExtendedCommand : uint16_t { GetSupportedFeatures = 0x0018, GetComponentVersions = 0x001A, Reboot = 0x001C, - SetUploadedFlag = 0x0027, + SetRootFSEntryFlags = 0x0027, GenericBinaryInfo = 0x0030, LiveData = 0x0035, }; diff --git a/include/icsneo/device/device.h b/include/icsneo/device/device.h index 2d80ee2..554bb76 100644 --- a/include/icsneo/device/device.h +++ b/include/icsneo/device/device.h @@ -424,6 +424,16 @@ public: IsEncrypted = 16, }; + enum RootDirectoryEntryFlags : uint8_t { + IsPrePost = 1, + PrePostTriggered = (1 << 1), + UploadPriority = (1 << 2) | (1 << 3), + CellularEnabled = (1 << 4), + WiFiEnabled = (1 << 5), + Uploaded = (1 << 6), + Unused = (1 << 7) + }; + typedef std::function< void(uint64_t value) > ScriptStatusCallback; /** @@ -579,8 +589,20 @@ public: std::optional sendEthPhyMsg(const EthPhyMessage& message, std::chrono::milliseconds timeout = std::chrono::milliseconds(50)); - std::optional SetCollectionUploaded(uint32_t collectionEntryByteAddress); - + + /** + * Set the flags of the root directory entry specified at given address + * + * Will not allow changes of IsPrePost and PrePostTriggered flags and will produce a warning + * if there is an attempt to do so + * + * @param mask Flags to set, with each bit representing a different entry flag @RootDirectoryEntryFlags + * @param values The values in which to set each flag, each bit corresponding to the flag in the same position + * @param collectionEntryByteAddress The position of the root directory entry in which to set these flags + * @return Success or failure + */ + std::optional SetRootDirectoryEntryFlags(uint8_t mask, uint8_t values, uint32_t collectionEntryByteAddress); + std::shared_ptr com; std::unique_ptr settings;