Device: Find the VSA offset for Disk::Access::EntireDisk

v0.3.0-dev
Paul Hollinsky 2022-02-28 15:55:16 -05:00
parent 1fadb85206
commit c314417277
5 changed files with 98 additions and 0 deletions

View File

@ -154,6 +154,7 @@ set(SRC_FILES
disk/nulldiskdriver.cpp disk/nulldiskdriver.cpp
disk/neomemorydiskreaddriver.cpp disk/neomemorydiskreaddriver.cpp
disk/plasiondiskreaddriver.cpp disk/plasiondiskreaddriver.cpp
disk/fat.cpp
${PLATFORM_SRC} ${PLATFORM_SRC}
) )

View File

@ -4,6 +4,7 @@
#include "icsneo/communication/command.h" #include "icsneo/communication/command.h"
#include "icsneo/device/extensions/deviceextension.h" #include "icsneo/device/extensions/deviceextension.h"
#include "icsneo/platform/optional.h" #include "icsneo/platform/optional.h"
#include "icsneo/disk/fat.h"
#include <string.h> #include <string.h>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@ -532,6 +533,20 @@ optional<uint64_t> Device::getLogicalDiskSize() {
return info->getReportedSize(); return info->getReportedSize();
} }
optional<uint64_t> Device::getVSAOffsetInLogicalDisk() {
if(!isOpen()) {
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
return nullopt;
}
if (diskReadDriver->getAccess() == Disk::Access::VSA || diskReadDriver->getAccess() == Disk::Access::None)
return 0ull;
return Disk::FindVSAInFAT([this](uint64_t pos, uint8_t *into, uint64_t amount) {
return readLogicalDisk(pos, into, amount);
});
}
optional<bool> Device::getDigitalIO(IO type, size_t number /* = 1 */) { optional<bool> Device::getDigitalIO(IO type, size_t number /* = 1 */) {
if(number == 0) { // Start counting from 1 if(number == 0) { // Start counting from 1
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error); report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);

48
disk/fat.cpp 100644
View File

@ -0,0 +1,48 @@
#include "icsneo/disk/fat.h"
#include "icsneo/disk/diskdriver.h"
#include "ff.h"
#include "diskio.h"
#include <mutex>
using namespace icsneo;
// The FAT driver can only be accessed by one caller at a time, since it relies on globals
static std::mutex fatDriverMutex;
static std::function< optional<uint64_t>(uint64_t pos, uint8_t* into, uint64_t amount) > diskReadFn;
extern "C" DRESULT disk_read(BYTE, BYTE* buff, LBA_t sector, UINT count) {
static_assert(Disk::SectorSize == 512, "FatFs expects 512 byte sectors");
const uint64_t expected = count * uint64_t(Disk::SectorSize);
const auto res = diskReadFn(sector * uint64_t(Disk::SectorSize), buff, expected);
if (!res.has_value())
return RES_NOTRDY;
return res == expected ? RES_OK : RES_ERROR;
}
extern "C" DSTATUS disk_initialize(BYTE) {
return RES_OK;
}
extern "C" DSTATUS disk_status(BYTE) {
return RES_OK;
}
static uint64_t ClusterToSector(const FATFS& fs, DWORD cluster) {
return fs.database + (LBA_t)fs.csize * (cluster - 2);
}
optional<uint64_t> Disk::FindVSAInFAT(std::function< optional<uint64_t>(uint64_t pos, uint8_t* into, uint64_t amount) > diskRead) {
std::lock_guard<std::mutex> lk(fatDriverMutex);
diskReadFn = diskRead;
FATFS fs = {};
if (f_mount(&fs, "", 0) != FR_OK)
return nullopt;
FIL logData = {};
if (f_open(&logData, "0:\\LOG_DATA.VSA", FA_READ) != FR_OK)
return nullopt;
return ClusterToSector(fs, logData.obj.sclust) * uint64_t(Disk::SectorSize);
}

View File

@ -198,6 +198,18 @@ public:
*/ */
optional<uint64_t> getLogicalDiskSize(); optional<uint64_t> getLogicalDiskSize();
/**
* Get the offset to the VSA filesystem within the logical disk, represented
* in bytes.
*
* This method is synchronous and consacts the device for the latest status
* if necessary.
*
* `icsneo::nullopt` will be returned if the device does not respond in a
* timely manner, or if the disk is disconnected/improperly configured.
*/
optional<uint64_t> getVSAOffsetInLogicalDisk();
/** /**
* Retrieve the number of Ethernet (DoIP) Activation lines present * Retrieve the number of Ethernet (DoIP) Activation lines present
* on this device. * on this device.

View File

@ -0,0 +1,22 @@
#ifndef __FAT_H__
#define __FAT_H__
#ifdef __cplusplus
#include "icsneo/platform/optional.h"
#include <cstdint>
#include <functional>
namespace icsneo {
namespace Disk {
optional<uint64_t> FindVSAInFAT(std::function< optional<uint64_t>(uint64_t pos, uint8_t* into, uint64_t amount) > diskRead);
} // namespace Disk
} // namespace icsneo
#endif // __cplusplus
#endif // __FAT_H__