Drivers: Decouple from devices

This allows us to better implement alternative drivers
for devices, such as for device sharing servers or
talking to CoreMini processors within the same device.
This commit is contained in:
Paul Hollinsky
2022-03-27 14:30:31 -04:00
parent 0ff12300f3
commit 781fc2c034
66 changed files with 780 additions and 1566 deletions
+34 -29
View File
@@ -1,4 +1,5 @@
#include "icsneo/platform/ftdi.h"
#include "icsneo/device/founddevice.h"
#include <iostream>
#include <stdio.h>
#include <cstring>
@@ -9,22 +10,21 @@
using namespace icsneo;
std::vector<std::tuple<int, std::string>> FTDI::handles;
std::vector<std::string> FTDI::handles;
std::vector<neodevice_t> FTDI::FindByProduct(int product) {
void FTDI::Find(std::vector<FoundDevice>& found) {
constexpr size_t deviceSerialBufferLength = sizeof(device.serial);
std::vector<neodevice_t> found;
static FTDIContext context;
std::pair<int, std::vector<std::string>> result = context.findDevices(product);
const auto result = context.findDevices();
if(result.first < 0)
return found; // TODO Flag an error for the client application, there was an issue with FTDI
return; // TODO Flag an error for the client application, there was an issue with FTDI
for(auto& serial : result.second) {
neodevice_t d;
for(const auto& [serial, pid] : result.second) {
FoundDevice d;
strncpy(d.serial, serial.c_str(), deviceSerialBufferLength - 1);
d.serial[deviceSerialBufferLength - 1] = '\0'; // strncpy does not write a null terminator if serial is too long
std::tuple<int, std::string> devHandle = std::make_tuple(product, serial);
std::string devHandle = serial;
auto it = std::find(handles.begin(), handles.end(), devHandle);
size_t foundHandle = SIZE_MAX;
if(it != handles.end()) {
@@ -34,10 +34,14 @@ std::vector<neodevice_t> FTDI::FindByProduct(int product) {
handles.push_back(devHandle);
}
d.handle = foundHandle;
d.productId = pid;
d.makeDriver = [](const device_eventhandler_t& report, neodevice_t& device) {
return std::unique_ptr<Driver>(new FTDI(report, device));
};
found.push_back(d);
}
return found;
}
FTDI::FTDI(const device_eventhandler_t& err, neodevice_t& forDevice) : Driver(err), device(forDevice) {
@@ -56,8 +60,8 @@ bool FTDI::open() {
}
// At this point the handle has been checked to be within the bounds of the handles array
std::tuple<int, std::string>& handle = handles[device.handle];
const int openError = ftdi.openDevice(std::get<0>(handle), std::get<1>(handle).c_str());
auto& handle = handles[device.handle];
const int openError = ftdi.openDevice(0, handle.c_str());
if(openError == -5) { // Unable to claim device
report(APIEvent::Type::DeviceInUse, APIEvent::Severity::Error);
return false;
@@ -112,17 +116,13 @@ bool FTDI::close() {
return ret;
}
std::pair<int, std::vector<std::string>> FTDI::FTDIContext::findDevices(int pid) {
std::pair<int, std::vector<std::string>> ret;
std::pair<int, std::vector< std::pair<std::string, uint16_t> > > FTDI::FTDIContext::findDevices(int pid) {
std::pair<int, std::vector< std::pair<std::string, uint16_t> > > ret;
if(context == nullptr) {
ret.first = -1;
return ret;
}
if(pid == 0) {
ret.first = -2;
return ret;
}
struct ftdi_device_list* devlist = nullptr;
ret.first = ftdi_usb_find_all(context, &devlist, INTREPID_USB_VENDOR_ID, pid);
@@ -138,18 +138,23 @@ std::pair<int, std::vector<std::string>> FTDI::FTDIContext::findDevices(int pid)
return ret;
}
for (struct ftdi_device_list* curdev = devlist; curdev != NULL;) {
char serial[32];
memset(serial, 0, sizeof(serial));
int result = ftdi_usb_get_strings(context, curdev->dev, nullptr, 0, nullptr, 0, serial, 32);
size_t len = strlen(serial);
if(result >= 0 && len > 0)
ret.second.emplace_back(serial);
else if(ret.first > 0)
ret.first--; // We're discarding this device
curdev = curdev->next;
for(struct ftdi_device_list* curdev = devlist; curdev != nullptr; curdev = curdev->next) {
struct libusb_device_descriptor descriptor = {};
// Check against bDeviceClass here as it will be 0 for FTDI devices
// It will be 2 for CDC ACM devices, which we don't want to handle here
if(libusb_get_device_descriptor(curdev->dev, &descriptor) != 0 || descriptor.bDeviceClass != 0)
continue;
char serial[16] = {};
if(ftdi_usb_get_strings(context, curdev->dev, nullptr, 0, nullptr, 0, serial, sizeof(serial)) < 0)
continue;
const auto len = strnlen(serial, sizeof(serial));
if(len > 4 && len < 10)
ret.second.emplace_back(serial, descriptor.idProduct);
}
ret.first = static_cast<int>(ret.second.size());
ftdi_list_free(&devlist);
return ret;
}
@@ -157,7 +162,7 @@ std::pair<int, std::vector<std::string>> FTDI::FTDIContext::findDevices(int pid)
int FTDI::FTDIContext::openDevice(int pid, const char* serial) {
if(context == nullptr)
return 1;
if(pid == 0 || serial == nullptr)
if(serial == nullptr)
return 2;
if(serial[0] == '\0')
return 3;