Device: Add disk formatting
parent
d70defbf8a
commit
1e5e714f5b
|
|
@ -292,6 +292,7 @@ set(SRC_FILES
|
||||||
disk/plasiondiskreaddriver.cpp
|
disk/plasiondiskreaddriver.cpp
|
||||||
disk/extextractordiskreaddriver.cpp
|
disk/extextractordiskreaddriver.cpp
|
||||||
disk/fat.cpp
|
disk/fat.cpp
|
||||||
|
disk/diskdetails.cpp
|
||||||
disk/vsa/vsa.cpp
|
disk/vsa/vsa.cpp
|
||||||
disk/vsa/vsa02.cpp
|
disk/vsa/vsa02.cpp
|
||||||
disk/vsa/vsa03.cpp
|
disk/vsa/vsa03.cpp
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,10 @@ static constexpr const char* LIN_SETTINGS_NOT_AVAILABLE = "LIN settings are not
|
||||||
static constexpr const char* MODE_NOT_FOUND = "The mode was not found.";
|
static constexpr const char* MODE_NOT_FOUND = "The mode was not found.";
|
||||||
static constexpr const char* GPTP_NOT_SUPPORTED = "GPTP clock synchronization is not supported on this device.";
|
static constexpr const char* GPTP_NOT_SUPPORTED = "GPTP clock synchronization is not supported on this device.";
|
||||||
static constexpr const char* SETTING_NOT_AVAILABLE = "Requested a setting that is not available on this device";
|
static constexpr const char* SETTING_NOT_AVAILABLE = "Requested a setting that is not available on this device";
|
||||||
|
static constexpr const char* DISK_FORMAT_NOT_SUPPORTED = "Disk formatting is not supported on this device.";
|
||||||
|
static constexpr const char* DISK_FORMAT_INVALID_COUNT = "Disk format config disk count is mismatched with device disk count.";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Transport Errors
|
// Transport Errors
|
||||||
static constexpr const char* FAILED_TO_READ = "A read operation failed.";
|
static constexpr const char* FAILED_TO_READ = "A read operation failed.";
|
||||||
|
|
@ -371,6 +375,10 @@ const char* APIEvent::DescriptionForType(Type type) {
|
||||||
return SEND_TO_ERROR;
|
return SEND_TO_ERROR;
|
||||||
case Type::GPTPNotSupported:
|
case Type::GPTPNotSupported:
|
||||||
return GPTP_NOT_SUPPORTED;
|
return GPTP_NOT_SUPPORTED;
|
||||||
|
case Type::DiskFormatNotSupported:
|
||||||
|
return DISK_FORMAT_NOT_SUPPORTED;
|
||||||
|
case Type::DiskFormatInvalidCount:
|
||||||
|
return DISK_FORMAT_INVALID_COUNT;
|
||||||
|
|
||||||
// FTD3XX
|
// FTD3XX
|
||||||
case Type::FTOK:
|
case Type::FTOK:
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@ void init_event(pybind11::module_& m) {
|
||||||
.value("SettingsLengthError", APIEvent::Type::SettingsLengthError)
|
.value("SettingsLengthError", APIEvent::Type::SettingsLengthError)
|
||||||
.value("SettingsChecksumError", APIEvent::Type::SettingsChecksumError)
|
.value("SettingsChecksumError", APIEvent::Type::SettingsChecksumError)
|
||||||
.value("SettingsNotAvailable", APIEvent::Type::SettingsNotAvailable)
|
.value("SettingsNotAvailable", APIEvent::Type::SettingsNotAvailable)
|
||||||
|
.value("DiskFormatNotSupported", APIEvent::Type::DiskFormatNotSupported)
|
||||||
|
.value("DiskFormatInvalidCount", APIEvent::Type::DiskFormatInvalidCount)
|
||||||
.value("SettingsReadOnly", APIEvent::Type::SettingsReadOnly)
|
.value("SettingsReadOnly", APIEvent::Type::SettingsReadOnly)
|
||||||
.value("CANSettingsNotAvailable", APIEvent::Type::CANSettingsNotAvailable)
|
.value("CANSettingsNotAvailable", APIEvent::Type::CANSettingsNotAvailable)
|
||||||
.value("CANFDSettingsNotAvailable", APIEvent::Type::CANFDSettingsNotAvailable)
|
.value("CANFDSettingsNotAvailable", APIEvent::Type::CANFDSettingsNotAvailable)
|
||||||
|
|
|
||||||
|
|
@ -324,6 +324,17 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||||
result = GPTPStatus::DecodeToMessage(packet->data, report);
|
result = GPTPStatus::DecodeToMessage(packet->data, report);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case ExtendedCommand::GetDiskDetails:
|
||||||
|
case ExtendedCommand::DiskFormatProgress: {
|
||||||
|
std::vector<uint8_t> responseBody(
|
||||||
|
packet->data.begin() + sizeof(ExtendedResponseMessage::ResponseHeader),
|
||||||
|
packet->data.end()
|
||||||
|
);
|
||||||
|
auto response = std::make_shared<ExtendedResponseMessage>(resp.command);
|
||||||
|
response->data = std::move(responseBody);
|
||||||
|
result = response;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
// No defined handler, treat this as a RawMessage
|
// No defined handler, treat this as a RawMessage
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/device/extensions/deviceextension.h"
|
#include "icsneo/device/extensions/deviceextension.h"
|
||||||
#include "icsneo/disk/fat.h"
|
#include "icsneo/disk/fat.h"
|
||||||
|
#include "icsneo/communication/message/filter/extendedresponsefilter.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable : 4996) // STL time functions
|
#pragma warning(disable : 4996) // STL time functions
|
||||||
|
|
@ -3487,3 +3488,129 @@ bool Device::enableNetworkCommunication(bool enable) {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Device::formatDisk(const DiskDetails& config, const DiskFormatProgress& handler, std::chrono::milliseconds interval) {
|
||||||
|
#pragma pack(push, 2)
|
||||||
|
struct DiskFormatProgressResponse {
|
||||||
|
uint16_t state;
|
||||||
|
uint64_t sectorsRemaining;
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
auto diskCount = getDiskCount();
|
||||||
|
|
||||||
|
if(!diskCount) {
|
||||||
|
report(APIEvent::Type::DiskFormatNotSupported, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(config.disks.size() != diskCount) {
|
||||||
|
report(APIEvent::Type::DiskFormatInvalidCount, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> payload = DiskDetails::Encode(config);
|
||||||
|
if(!com->sendCommand(ExtendedCommand::DiskFormatStart, payload)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t sectorsFormatted = 0;
|
||||||
|
uint64_t sectorsTotal = 0;
|
||||||
|
uint16_t lastState = 1;
|
||||||
|
do {
|
||||||
|
std::shared_ptr<Message> response = com->waitForMessageSync(
|
||||||
|
[this](){
|
||||||
|
return com->sendCommand(ExtendedCommand::DiskFormatProgress, {});
|
||||||
|
},
|
||||||
|
std::make_shared<ExtendedResponseFilter>(ExtendedCommand::DiskFormatProgress),
|
||||||
|
std::chrono::milliseconds(200)
|
||||||
|
);
|
||||||
|
|
||||||
|
if(!response) {
|
||||||
|
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto extResponse = std::dynamic_pointer_cast<ExtendedResponseMessage>(response);
|
||||||
|
if(!extResponse) {
|
||||||
|
// Should never happen
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(extResponse->data.size() < sizeof(DiskFormatProgressResponse)) {
|
||||||
|
report(APIEvent::Type::BufferInsufficient, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* progress = reinterpret_cast<DiskFormatProgressResponse*>(extResponse->data.data());
|
||||||
|
lastState = progress->state;
|
||||||
|
|
||||||
|
if(sectorsTotal == 0) {
|
||||||
|
sectorsTotal = progress->sectorsRemaining;
|
||||||
|
} else {
|
||||||
|
sectorsFormatted = sectorsTotal - progress->sectorsRemaining;
|
||||||
|
|
||||||
|
if(handler) {
|
||||||
|
auto directive = handler(sectorsFormatted, sectorsTotal);
|
||||||
|
|
||||||
|
if(directive == DiskFormatDirective::Stop) {
|
||||||
|
return com->sendCommand(ExtendedCommand::DiskFormatCancel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(interval);
|
||||||
|
} while(lastState);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Device::forceDiskConfigUpdate(const DiskDetails& config) {
|
||||||
|
auto diskCount = getDiskCount();
|
||||||
|
|
||||||
|
if(!diskCount) {
|
||||||
|
report(APIEvent::Type::DiskFormatNotSupported, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(config.disks.size() != diskCount) {
|
||||||
|
report(APIEvent::Type::DiskFormatInvalidCount, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return com->sendCommand(ExtendedCommand::DiskFormatUpdate, DiskDetails::Encode(config));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<DiskDetails> Device::getDiskDetails(std::chrono::milliseconds timeout) {
|
||||||
|
if(!supportsDiskFormatting()) {
|
||||||
|
report(APIEvent::Type::DiskFormatNotSupported, APIEvent::Severity::Error);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isOpen()) {
|
||||||
|
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Message> response = com->waitForMessageSync(
|
||||||
|
[this](){
|
||||||
|
return com->sendCommand(ExtendedCommand::GetDiskDetails, {});
|
||||||
|
},
|
||||||
|
std::make_shared<ExtendedResponseFilter>(ExtendedCommand::GetDiskDetails),
|
||||||
|
timeout
|
||||||
|
);
|
||||||
|
|
||||||
|
if(!response) {
|
||||||
|
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto extResponse = std::dynamic_pointer_cast<ExtendedResponseMessage>(response);
|
||||||
|
if(!extResponse) {
|
||||||
|
// Should never happen
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DiskDetails::Decode(extResponse->data, getDiskCount(), report);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
#include <icsneo/disk/diskdetails.h>
|
||||||
|
#include <icsneo/device/idevicesettings.h>
|
||||||
|
|
||||||
|
using namespace icsneo;
|
||||||
|
|
||||||
|
#pragma pack(push, 2)
|
||||||
|
|
||||||
|
struct DISK_STATUS {
|
||||||
|
uint16_t status;
|
||||||
|
uint64_t sectors;
|
||||||
|
uint32_t bytesPerSector;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DISK_DETAILS {
|
||||||
|
DISK_SETTINGS settings;
|
||||||
|
uint16_t options;
|
||||||
|
DISK_STATUS status[12];
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
static constexpr uint8_t DISK_FORMAT_FAT32 = 0x01u;
|
||||||
|
static constexpr uint8_t DISK_STATUS_PRESENT = 0x01u;
|
||||||
|
static constexpr uint8_t DISK_STATUS_INITIALIZED = 0x02u;
|
||||||
|
static constexpr uint16_t DISK_DETAILS_FULL_FORMAT = 0x01u;
|
||||||
|
|
||||||
|
std::vector<uint8_t> DiskDetails::Encode(const DiskDetails& config) {
|
||||||
|
std::vector<uint8_t> result(sizeof(DISK_DETAILS), 0);
|
||||||
|
DISK_DETAILS* details = reinterpret_cast<DISK_DETAILS*>(result.data());
|
||||||
|
details->settings.disk_layout = static_cast<uint8_t>(config.layout);
|
||||||
|
details->settings.disk_format = DISK_FORMAT_FAT32; // Always FAT32
|
||||||
|
details->options = config.fullFormat ? DISK_DETAILS_FULL_FORMAT : 0;
|
||||||
|
uint32_t& enables = details->settings.disk_enables;
|
||||||
|
enables = 0u;
|
||||||
|
for(size_t i = 0; i < config.disks.size(); i++) {
|
||||||
|
auto& disk = config.disks[i];
|
||||||
|
details->status[i].sectors = disk.sectors;
|
||||||
|
details->status[i].bytesPerSector = disk.bytesPerSector;
|
||||||
|
|
||||||
|
uint16_t& status = details->status[i].status;
|
||||||
|
status = 0u;
|
||||||
|
if(disk.initialized) {
|
||||||
|
status |= DISK_STATUS_INITIALIZED;
|
||||||
|
}
|
||||||
|
if(disk.present) {
|
||||||
|
status |= DISK_STATUS_PRESENT;
|
||||||
|
}
|
||||||
|
if(disk.formatted) {
|
||||||
|
enables |= (1u << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<DiskDetails> DiskDetails::Decode(const std::vector<uint8_t>& bytes, size_t diskCount, device_eventhandler_t report) {
|
||||||
|
if(bytes.size() < sizeof(DISK_DETAILS)) {
|
||||||
|
report(APIEvent::Type::BufferInsufficient, APIEvent::Severity::Error);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result = std::make_shared<DiskDetails>();
|
||||||
|
const DISK_DETAILS* details = reinterpret_cast<const DISK_DETAILS*>(bytes.data());
|
||||||
|
result->layout = static_cast<DiskLayout>(details->settings.disk_layout);
|
||||||
|
result->fullFormat = details->options & DISK_DETAILS_FULL_FORMAT;
|
||||||
|
|
||||||
|
result->disks.reserve(diskCount);
|
||||||
|
|
||||||
|
for(size_t i = 0; i < diskCount; i++) {
|
||||||
|
auto& disk = details->status[i];
|
||||||
|
result->disks.emplace_back();
|
||||||
|
auto& info = result->disks.back();
|
||||||
|
info.present = static_cast<bool>(disk.status & DISK_STATUS_PRESENT);
|
||||||
|
info.initialized = static_cast<bool>(disk.status & DISK_STATUS_INITIALIZED);
|
||||||
|
info.formatted = static_cast<bool>(details->settings.disk_enables & (1u << i));
|
||||||
|
info.sectors = disk.sectors;
|
||||||
|
info.bytesPerSector = disk.bytesPerSector;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
@ -113,6 +113,8 @@ public:
|
||||||
AppErrorParsingFailed = 0x2055,
|
AppErrorParsingFailed = 0x2055,
|
||||||
GPTPNotSupported = 0x2056,
|
GPTPNotSupported = 0x2056,
|
||||||
SettingNotAvaiableDevice = 0x2057,
|
SettingNotAvaiableDevice = 0x2057,
|
||||||
|
DiskFormatNotSupported = 0x2058,
|
||||||
|
DiskFormatInvalidCount = 0x2059,
|
||||||
|
|
||||||
// Transport Events
|
// Transport Events
|
||||||
FailedToRead = 0x3000,
|
FailedToRead = 0x3000,
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,12 @@ namespace icsneo {
|
||||||
|
|
||||||
class ExtendedResponseMessage : public Message {
|
class ExtendedResponseMessage : public Message {
|
||||||
public:
|
public:
|
||||||
ExtendedResponseMessage(ExtendedCommand cmd, ExtendedResponse resp)
|
ExtendedResponseMessage(ExtendedCommand cmd, ExtendedResponse resp = ExtendedResponse::OK)
|
||||||
: Message(Message::Type::ExtendedResponse), command(cmd), response(resp) {}
|
: Message(Message::Type::ExtendedResponse), command(cmd), response(resp) {}
|
||||||
|
|
||||||
const ExtendedCommand command;
|
const ExtendedCommand command;
|
||||||
const ExtendedResponse response;
|
const ExtendedResponse response;
|
||||||
|
std::vector<uint8_t> data;
|
||||||
|
|
||||||
#pragma pack(push, 2)
|
#pragma pack(push, 2)
|
||||||
struct ResponseHeader {
|
struct ResponseHeader {
|
||||||
|
|
|
||||||
|
|
@ -15,20 +15,36 @@ namespace icsneo {
|
||||||
|
|
||||||
class ExtendedResponseFilter : public MessageFilter {
|
class ExtendedResponseFilter : public MessageFilter {
|
||||||
public:
|
public:
|
||||||
ExtendedResponseFilter(icsneo::ExtendedResponse resp) : MessageFilter(Message::Type::ExtendedResponse), response(resp) {}
|
ExtendedResponseFilter(icsneo::ExtendedCommand cmd) : MessageFilter(Message::Type::ExtendedResponse), command(cmd), response(std::nullopt) {}
|
||||||
|
ExtendedResponseFilter(icsneo::ExtendedResponse resp) : MessageFilter(Message::Type::ExtendedResponse), command(std::nullopt), response(resp) {}
|
||||||
|
ExtendedResponseFilter(icsneo::ExtendedCommand cmd, icsneo::ExtendedResponse resp)
|
||||||
|
: MessageFilter(Message::Type::ExtendedResponse), command(cmd), response(resp) {}
|
||||||
|
|
||||||
bool match(const std::shared_ptr<Message>& message) const override {
|
bool match(const std::shared_ptr<Message>& message) const override {
|
||||||
if(!MessageFilter::match(message)) {
|
if(!MessageFilter::match(message)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto respMsg = std::static_pointer_cast<ExtendedResponseMessage>(message);
|
const auto respMsg = std::static_pointer_cast<ExtendedResponseMessage>(message);
|
||||||
return respMsg && matchResponse(respMsg->response);
|
return respMsg && matchResponse(respMsg->command, respMsg->response);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
icsneo::ExtendedResponse response;
|
std::optional<icsneo::ExtendedCommand> command = std::nullopt;
|
||||||
bool matchResponse(icsneo::ExtendedResponse resp) const {
|
std::optional<icsneo::ExtendedResponse> response = std::nullopt;
|
||||||
return response == resp;
|
|
||||||
|
bool matchResponse(icsneo::ExtendedCommand cmd, icsneo::ExtendedResponse resp) const {
|
||||||
|
if(command) {
|
||||||
|
if(*command != cmd) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(response) {
|
||||||
|
if(*response != resp) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include "icsneo/disk/diskreaddriver.h"
|
#include "icsneo/disk/diskreaddriver.h"
|
||||||
#include "icsneo/disk/diskwritedriver.h"
|
#include "icsneo/disk/diskwritedriver.h"
|
||||||
#include "icsneo/disk/nulldiskdriver.h"
|
#include "icsneo/disk/nulldiskdriver.h"
|
||||||
|
#include "icsneo/disk/diskdetails.h"
|
||||||
#include "icsneo/communication/communication.h"
|
#include "icsneo/communication/communication.h"
|
||||||
#include "icsneo/communication/packetizer.h"
|
#include "icsneo/communication/packetizer.h"
|
||||||
#include "icsneo/communication/encoder.h"
|
#include "icsneo/communication/encoder.h"
|
||||||
|
|
@ -637,6 +638,22 @@ public:
|
||||||
bool unsubscribeLiveData(const LiveDataHandle& handle);
|
bool unsubscribeLiveData(const LiveDataHandle& handle);
|
||||||
bool clearAllLiveData();
|
bool clearAllLiveData();
|
||||||
bool setValueLiveData(std::shared_ptr<LiveDataSetValueMessage> message);
|
bool setValueLiveData(std::shared_ptr<LiveDataSetValueMessage> message);
|
||||||
|
|
||||||
|
enum class DiskFormatDirective : uint8_t {
|
||||||
|
Continue,
|
||||||
|
Stop
|
||||||
|
};
|
||||||
|
|
||||||
|
using DiskFormatProgress = std::function<DiskFormatDirective(uint64_t sectorsFormatted, uint64_t sectorsTotal)>;
|
||||||
|
bool formatDisk(
|
||||||
|
const DiskDetails& config,
|
||||||
|
const DiskFormatProgress& handler = {},
|
||||||
|
std::chrono::milliseconds interval = std::chrono::milliseconds(500) /** Send updates at an interval of 500ms */
|
||||||
|
);
|
||||||
|
bool forceDiskConfigUpdate(const DiskDetails& config); // Forces a disk layout and enables change without formatting
|
||||||
|
std::shared_ptr<DiskDetails> getDiskDetails(std::chrono::milliseconds timeout = std::chrono::milliseconds(100));
|
||||||
|
virtual size_t getDiskCount() const { return 0; }
|
||||||
|
bool supportsDiskFormatting() const { return getDiskCount() != 0; }
|
||||||
|
|
||||||
// VSA Read functions
|
// VSA Read functions
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -924,7 +924,8 @@ public:
|
||||||
template<typename T> T getStructure() const { return *getStructurePointer<T>(); }
|
template<typename T> T getStructure() const { return *getStructurePointer<T>(); }
|
||||||
template<typename T> bool applyStructure(const T& newStructure);
|
template<typename T> bool applyStructure(const T& newStructure);
|
||||||
|
|
||||||
const size_t& getSize() const { return structSize; }
|
size_t getSize() const { return structSize; }
|
||||||
|
size_t getSerialSize() const { return settings.size(); }
|
||||||
|
|
||||||
// if settings are disabled for this device. always false unless constructed null
|
// if settings are disabled for this device. always false unless constructed null
|
||||||
bool disabled = false;
|
bool disabled = false;
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,10 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool supportsGPTP() const override { return true; }
|
bool supportsGPTP() const override { return true; }
|
||||||
|
|
||||||
|
size_t getDiskCount() const override {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,10 @@ protected:
|
||||||
bool supportsEraseMemory() const override {
|
bool supportsEraseMemory() const override {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t getDiskCount() const override {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,10 @@ protected:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t getDiskCount() const override {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,10 @@ protected:
|
||||||
bool supportsEraseMemory() const override {
|
bool supportsEraseMemory() const override {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t getDiskCount() const override {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,10 @@ protected:
|
||||||
bool supportsEraseMemory() const override {
|
bool supportsEraseMemory() const override {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t getDiskCount() const override {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,10 @@ protected:
|
||||||
std::optional<MemoryAddress> getCoreminiStartAddressSD() const override {
|
std::optional<MemoryAddress> getCoreminiStartAddressSD() const override {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t getDiskCount() const override {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,10 @@ protected:
|
||||||
std::optional<MemoryAddress> getCoreminiStartAddressSD() const override {
|
std::optional<MemoryAddress> getCoreminiStartAddressSD() const override {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t getDiskCount() const override {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,11 @@ namespace icsneo
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t getDiskCount() const override
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
#ifndef __DISKDETAILS_H__
|
||||||
|
#define __DISKDETAILS_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
#include <icsneo/api/eventmanager.h>
|
||||||
|
|
||||||
|
namespace icsneo {
|
||||||
|
|
||||||
|
enum class DiskLayout : uint8_t {
|
||||||
|
Spanned = 0,
|
||||||
|
RAID0 = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DiskInfo {
|
||||||
|
bool present; // Disk is connected
|
||||||
|
bool initialized; // Disk is initialized
|
||||||
|
bool formatted; // Disk is formatted
|
||||||
|
|
||||||
|
uint64_t sectors;
|
||||||
|
uint32_t bytesPerSector;
|
||||||
|
|
||||||
|
uint64_t size() const {
|
||||||
|
return sectors * bytesPerSector;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DiskDetails {
|
||||||
|
DiskLayout layout;
|
||||||
|
bool fullFormat;
|
||||||
|
std::vector<DiskInfo> disks;
|
||||||
|
|
||||||
|
static std::vector<uint8_t> Encode(const DiskDetails& config);
|
||||||
|
static std::shared_ptr<DiskDetails> Decode(const std::vector<uint8_t>& bytes, size_t diskCount, device_eventhandler_t report);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace icsneo
|
||||||
|
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Reference in New Issue