mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 01:18:36 +02:00
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:
+34
-29
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user