14 changed files with 1330 additions and 734 deletions
+21
View File
@@ -18,6 +18,7 @@ set(LIBICSNEO_NPCAP_INCLUDE_DIR "" CACHE STRING "Npcap include directory; set to
option(LIBICSNEO_ENABLE_FIRMIO "Enable communication between Linux and CoreMini within the same device" OFF)
option(LIBICSNEO_ENABLE_RAW_ETHERNET "Enable devices which communicate over raw ethernet" ON)
option(LIBICSNEO_ENABLE_CDCACM "Enable devices which communicate over USB CDC ACM" ON)
option(LIBICSNEO_ENABLE_ANDROIDUSB "Enable devices which communicate over USB CDC ACM on Android" ON)
option(LIBICSNEO_ENABLE_FTDI "Enable devices which communicate over USB FTDI2XX" ON)
option(LIBICSNEO_ENABLE_TCP "Enable devices which communicate over TCP" OFF)
option(LIBICSNEO_ENABLE_FTD3XX "Enable devices which communicate over USB FTD3XX" ON)
@@ -117,6 +118,12 @@ if(WIN32)
platform/windows/vcp.cpp
)
endif()
elseif(LIBICSNEO_ENABLE_ANDROIDUSB)
list(APPEND PLATFORM_SRC
platform/android/androidusb.cpp
)
else() # Darwin or Linux
set(PLATFORM_SRC)
@@ -161,6 +168,7 @@ else() # Darwin or Linux
endif()
endif()
if(LIBICSNEO_ENABLE_FTD3XX)
if(NOT FTD3XX_ROOT) # allow system override
include(FetchContent)
@@ -360,6 +368,14 @@ if(LIBICSNEO_ENABLE_TCP)
endif()
endif()
if(LIBICSNEO_ENABLE_ANDROIDUSB)
add_library(libusb SHARED IMPORTED)
set_target_properties(libusb PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/third-party/libusb/android/libs/${ANDROID_ABI}/libusb1.0.so)
target_include_directories(icsneocpp PRIVATE third-party/libusb/libusb)
target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_ANDROIDUSB)
target_link_libraries(icsneocpp PRIVATE android log libusb)
endif()
# fatfs
add_subdirectory(third-party/fatfs)
set_property(TARGET fatfs PROPERTY POSITION_INDEPENDENT_CODE ON)
@@ -414,6 +430,11 @@ if(LIBICSNEO_BUILD_ICSNEOC)
)
target_link_libraries(icsneoc PRIVATE icsneocpp)
target_compile_features(icsneoc PRIVATE cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
if(LIBICSNEO_ENABLE_ANDROIDUSB)
target_link_libraries(icsneoc PRIVATE android log)
target_include_directories(icsneoc PRIVATE third-party/libusb/libusb)
target_compile_definitions(icsneoc PRIVATE ICSNEO_ENABLE_ANDROIDUSB)
endif()
endif()
if(LIBICSNEO_BUILD_ICSNEOC_STATIC)
+15 -3
View File
@@ -111,11 +111,15 @@ bool icsneo_isValidNeoDevice(const neodevice_t* device) {
}
bool icsneo_openDevice(const neodevice_t* device) {
if(!icsneo_isValidNeoDevice(device))
if(!icsneo_isValidNeoDevice(device)) {
//todo error
return false;
}
if(!device->device->open())
if(!device->device->open()) {
//todo error
return false;
}
// We connected successfully, move the device to connected devices
std::vector<std::vector<std::shared_ptr<Device>>::iterator> itemsToMove;
@@ -220,7 +224,6 @@ bool icsneo_getMessages(const neodevice_t* device, neomessage_t* messages, size_
return false;
*items = storage.size();
for(size_t i = 0; i < *items; i++) {
// For each message, copy into neomessage_t buffer given
messages[i] = CreateNeoMessage(storage[i]);
@@ -741,3 +744,12 @@ int icsneo_getDeviceStatus(const neodevice_t* device, void* status, size_t* size
return true;
}
#ifdef ICSNEO_ENABLE_ANDROIDUSB
bool icsneo_addSysFileDescriptor(int sysFd) {
return icsneo::ANDROIDUSB::addSystemFD(sysFd);
}
bool icsneo_removeSysFileDescriptor(int sysFd) {
return icsneo::ANDROIDUSB::removeSystemFD(sysFd);
}
#endif
+1
View File
@@ -1,5 +1,6 @@
#include "icsneo/icsneocpp.h"
#include "icsneo/device/devicefinder.h"
#include <jni.h>
using namespace icsneo;
+8
View File
@@ -15,6 +15,10 @@
#include "icsneo/platform/cdcacm.h"
#endif
#ifdef ICSNEO_ENABLE_ANDROIDUSB
#include "icsneo/platform/android/androidusb.h"
#endif
#ifdef ICSNEO_ENABLE_FTDI
#include "icsneo/platform/ftdi.h"
#endif
@@ -67,6 +71,10 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
CDCACM::Find(newDriverFoundDevices);
#endif
#ifdef ICSNEO_ENABLE_ANDROIDUSB
ANDROIDUSB::Find(newDriverFoundDevices);
#endif
#ifdef ICSNEO_ENABLE_FTDI
FTDI::Find(newDriverFoundDevices);
#endif
+1
View File
@@ -1,3 +1,4 @@
package com.example.icsneojava;
/* ----------------------------------------------------------------------------
* This file was automatically generated by SWIG (http://www.swig.org).
* Version 4.0.0
+11 -1
View File
@@ -122,6 +122,11 @@ public:
GetIfAddrsError = 0x3108,
SendToError = 0x3109,
MDIOMessageExceedsMaxLength = 0x3110,
DriverTTYPathEmpty = 0x3120,
DriverWasNotNegOne = 0x3121,
DriverTCGetAddrFail = 0x3122,
DriverTCSetAddrFail = 0x3123,
// FTD3XX
FTOK = 0x4000, // placeholder
@@ -158,10 +163,15 @@ public:
FTIncorrectDevicePath = FTOK + 31,
FTOtherError = FTOK + 32,
// Android USB
AndroidUSBLibusbInitFailed = 0x5000,
AndroidUSBFDWrapFailed = 0x5001,
NoErrorFound = 0xFFFFFFFD,
TooManyEvents = 0xFFFFFFFE,
Unknown = 0xFFFFFFFF
Unknown = 0xFFFFFFFF,
};
enum class Severity : uint8_t {
Any = 0, // Used for filtering, should not appear in data
EventInfo = 0x10,
+5
View File
@@ -837,6 +837,11 @@ extern bool icsneo_getRTC(const neodevice_t* device, uint64_t* output);
*/
extern bool icsneo_setRTC(const neodevice_t* device, uint64_t input);
#ifdef ICSNEO_ENABLE_ANDROIDUSB
extern bool icsneo_addSysFileDescriptor(int sysFd);
extern bool icsneo_removeSysFileDescriptor(int sysFd);
#endif
#ifdef __cplusplus
} // extern "C"
#endif
@@ -0,0 +1,55 @@
#ifndef __ANDROIDUSB_H_
#define __ANDROIDUSB_H_
#ifdef __cplusplus
#include "icsneo/communication/driver.h"
#include "icsneo/device/neodevice.h"
#include "icsneo/api/eventmanager.h"
#include "libusb.h"
#include <optional>
#include <chrono>
#include <sys/stat.h>
#include <stdint.h>
#include <unordered_map>
namespace icsneo {
class ANDROIDUSB : public Driver {
public:
/**
* Note: This is a driver for all devices which use Android CDC_ACM
*/
ANDROIDUSB(const device_eventhandler_t& err, neodevice_t& forDevice)
: Driver(err), device(forDevice) {
if(auto key = systemFDs.find(device.handle); key != systemFDs.end())
libusbDeviceHandle = key->second;
}
~ANDROIDUSB();
static void Find(std::vector<FoundDevice>& found);
bool open() override;
bool isOpen() override;
bool close() override;
static bool addSystemFD(int fd);
static bool removeSystemFD(int fd);
private:
neodevice_t& device;
libusb_context *ctx = nullptr;
libusb_device_handle *libusbDeviceHandle = nullptr;
inline static std::unordered_map<int,libusb_device_handle*> systemFDs; //android FD, libusb handle
static constexpr int ep_in_addr = 0x83;
static constexpr int ep_out_addr = 0x02;
bool openStatus = false;
void readTask() override;
void writeTask() override;
bool fdIsValid();
};
}
#endif // __cplusplus
#endif //LIBICSNEO_TEST_ANDROIDUSB_H
+240
View File
@@ -0,0 +1,240 @@
#include "icsneo/platform/android/androidusb.h"
#include "icsneo/device/founddevice.h"
#include <dirent.h>
#include <cstring>
#include <iostream>
#include <sstream>
#include <fstream>
#include <map>
#include <algorithm>
#include <termios.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/select.h>
#include "libusb.h"
#include <android/log.h>
#define LOG_TAG "libicsneo_test_androidusb"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
using namespace icsneo;
ANDROIDUSB::~ANDROIDUSB() {
if (isOpen())
close();
}
bool ANDROIDUSB::addSystemFD(int sysFd) {
if ((sysFd != -1) && (systemFDs[sysFd] == nullptr)) {
return true;
}
return false;
}
bool ANDROIDUSB::removeSystemFD(int sysFd) {
if (sysFd != -1) {
return systemFDs.erase(sysFd);
}
return false;
}
bool ANDROIDUSB::open() {
openStatus = true;
if (!isOpen()) {
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
LOGD("Failed isOpen check in open(): %ul\n", device.handle);
return false;
}
// Create threads
readThread = std::thread(&ANDROIDUSB::readTask, this);
writeThread = std::thread(&ANDROIDUSB::writeTask, this);
return true;
}
bool ANDROIDUSB::isOpen() {
//LOGD("isOpen handle: %i, openStatus: %s\n", device.handle, openStatus?"true":"false");
return ((device.handle >= 0) && (openStatus)); // Negative fd indicates error or not opened yet
}
bool ANDROIDUSB::close() {
if(!isOpen() && !isDisconnected()) {
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
return false;
}
closing = true;
if(readThread.joinable())
readThread.join();
if(writeThread.joinable())
writeThread.join();
closing = false;
disconnected = false;
systemFDs[device.handle] = nullptr;
openStatus = false;
device.handle = -1;
uint8_t flush;
WriteOperation flushop;
while (readQueue.try_dequeue(flush)) {}
while (writeQueue.try_dequeue(flushop)) {}
return true;
}
void ANDROIDUSB::readTask() {
constexpr size_t READ_BUFFER_SIZE = 2048;
uint8_t readbuf[READ_BUFFER_SIZE];
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
libusb_device_handle *devh = nullptr;
auto mapItr = systemFDs.find(device.handle);
if (mapItr != systemFDs.end()) {
devh = mapItr->second;
}
while(!closing && !isDisconnected()) {
int bytesRead = 0;
auto ret = libusb_bulk_transfer(devh, ep_in_addr, readbuf, READ_BUFFER_SIZE, &bytesRead, 50);
if (ret == LIBUSB_ERROR_TIMEOUT) {
continue;
}
if (ret == LIBUSB_ERROR_NO_DEVICE) {
disconnected = true;
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
}
if(bytesRead > 0) {
#if 0 // Perhaps helpful for debugging :)
std::cout << "Read data: (" << bytesRead << ')' << std::hex << std::endl;
for(int i = 0; i < bytesRead; i += 16) {
for(int j = 0; j < std::min<int>(bytesRead - i, 16); j++)
std::cout << std::setw(2) << std::setfill('0') << uint32_t(readbuf[i+j]) << ' ';
std::cout << std::endl;
}
std::cout << std::dec << std::endl;
#endif
readQueue.enqueue_bulk(readbuf, bytesRead);
} else {
if(!closing && !fdIsValid() && !isDisconnected()) {
disconnected = true;
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
}
}
}
}
void ANDROIDUSB::writeTask() {
WriteOperation writeOp;
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
libusb_device_handle *devh = nullptr;
auto mapItr = systemFDs.find(device.handle);
if (mapItr != systemFDs.end()) {
devh = mapItr->second;
}
while(!closing && !isDisconnected()) {
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
continue;
const ssize_t totalWriteSize = (ssize_t)writeOp.bytes.size();
ssize_t totalWritten = 0;
while(totalWritten < totalWriteSize) {
const ssize_t writeSize = totalWriteSize - totalWritten;
int actualWritten = 0;
auto ret = libusb_bulk_transfer(devh, ep_out_addr, writeOp.bytes.data() + totalWritten, writeSize, &actualWritten, 100);
if (ret < 0) {
if (ret == LIBUSB_ERROR_NO_DEVICE) {
LOGD("Write task bulk transfer failed, device disconnected!\n");
if(!isDisconnected()) {
disconnected = true;
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
}
}
if (ret != LIBUSB_ERROR_TIMEOUT) {
LOGD("Write task bulk transfer failed!\n%s", libusb_strerror(ret));
continue;
}
}
if(actualWritten > 0) {
#if 0 // Perhaps helpful for debugging :)
std::cout << "Wrote data: (" << actualWritten << ')' << std::hex << std::endl;
for(int i = 0; i < actualWritten; i += 16) {
for(int j = 0; j < std::min<int>(actualWritten - i, 16); j++)
std::cout << std::setw(2) << std::setfill('0') << uint32_t(writeOp.bytes[totalWritten+i+j]) << ' ';
std::cout << std::endl;
}
std::cout << std::dec << std::endl;
#endif
totalWritten += actualWritten;
}
}
}
}
bool ANDROIDUSB::fdIsValid() {
if (device.handle != -1) {
auto itr = systemFDs.find(device.handle);
if ((itr != systemFDs.end()) && (itr->second != nullptr)) {
return true;
}
}
return false;
}
void ANDROIDUSB::Find(std::vector<FoundDevice>& found) {
int ret = 0;
libusb_context *ctx = NULL;
libusb_device_handle *libusbDeviceHandle = NULL;
ret = libusb_set_option(ctx, LIBUSB_OPTION_NO_DEVICE_DISCOVERY, NULL);
if (ret != LIBUSB_SUCCESS) {
LOGD("libusb_init failed: %d\n", ret);
return;
}
ret = libusb_init(&ctx);
if (ret < 0) {
LOGD("libusb_init failed: %d\n", ret);
return;
}
//LOGD("libusb_init completed: %d\n", ret);
//LOGD("SYSTEM FDs size: %d\n", systemFDs.size());
for (auto & [fd, libUsbHandle]: systemFDs) {
ret = libusb_wrap_sys_device(ctx, (intptr_t) fd, &libusbDeviceHandle);
//LOGD("Wrapping system FD: %d, return: %s\n", fd, libusb_strerror(ret));
if (ret == 0) {
FoundDevice device = {};
struct libusb_device_descriptor desc;
unsigned char outString[255] = {};
if(libusbDeviceHandle) {
ret = libusb_get_device_descriptor(libusb_get_device(libusbDeviceHandle), &desc);
if (ret == 0) {
device.productId = desc.idProduct;
//LOGD("ProductID: %x\n", device.productId);
ret = libusb_get_string_descriptor_ascii(libusbDeviceHandle, desc.iSerialNumber,
outString, sizeof(outString));
if (ret > 0) {
std::strncpy(device.serial, reinterpret_cast<char *>(outString),
sizeof(device.serial));
} else {
LOGD("Serial number fetch failed!\n");
}
} else {
LOGD("Fetch device descriptor failed for FD: %d, %s\n", fd, libusb_strerror(ret));
}
} else {
LOGD("LIBUSB Device handle was invalid!\n");
}
device.handle = fd;
// Add a factory to make the driver
device.makeDriver = [&](const device_eventhandler_t &report, neodevice_t &device) {
return std::unique_ptr<Driver>(new ANDROIDUSB(report, device));
};
found.push_back(device); // Finally, add device to search results
libUsbHandle = libusbDeviceHandle;
}
}
}
+238
View File
@@ -0,0 +1,238 @@
#include "icsneo/platform/android/androidusb.h"
#include "icsneo/device/founddevice.h"
#include <dirent.h>
#include <cstring>
#include <iostream>
#include <sstream>
#include <fstream>
#include <map>
#include <algorithm>
#include <termios.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/select.h>
using namespace icsneo;
ANDROIDUSB::~ANDROIDUSB() {
awaitModeChangeComplete();
if(isOpen())
close();
}
bool ANDROIDUSB::open() {
if(!isOpen()) {
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
return false;
}
struct termios tty = {};
struct termios compare = {};
if(tcgetattr(fd, &tty) != 0) {
close();
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
report(APIEvent::Type::DriverTCGetAddrFail, APIEvent::Severity::Error);
return false;
}
tty.c_cflag |= (CLOCAL | CREAD); // Ignore modem controls
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; // 8-bit characters
tty.c_cflag &= ~PARENB; // No parity bit
tty.c_cflag &= ~CSTOPB; // One stop bit
tty.c_cflag &= ~CRTSCTS; // No hardware flow control
// Non-canonical mode
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
tty.c_oflag &= ~OPOST;
// Fetch bytes as they become available
// See http://man7.org/linux/man-pages/man3/termios.3.html
tty.c_cc[VMIN] = 0;
tty.c_cc[VTIME] = 1; // 100ms timeout (1 decisecond, what?)
if(tcsetattr(fd, TCSAFLUSH, &tty) != 0) { // Flushes input and output buffers as well as setting settings
close();
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
report(APIEvent::Type::DriverTCSetAddrFail, APIEvent::Severity::Error);
return false;
}
if(tcgetattr(fd, &compare) != 0 || memcmp(&tty, &compare, sizeof(struct termios)) != 0) {
close();
return false;
}
// Create threads
readThread = std::thread(&ANDROIDUSB::readTask, this);
writeThread = std::thread(&ANDROIDUSB::writeTask, this);
return true;
}
bool ANDROIDUSB::isOpen() {
return fd >= 0; // Negative fd indicates error or not opened yet
}
bool ANDROIDUSB::close() {
if(!isOpen() && !isDisconnected()) {
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
return false;
}
closing = true;
if(readThread.joinable())
readThread.join();
if(writeThread.joinable())
writeThread.join();
closing = false;
disconnected = false;
if(modeChanging) {
// We're expecting this inode to go away after we close the device
// In order to block waiting for this to happen, we first need to
// get the inode.
struct stat fileStat = {};
if(fstat(fd, &fileStat) >= 0)
disallowedInode = fileStat.st_ino;
}
int ret = ::close(fd);
fd = -1;
uint8_t flush;
WriteOperation flushop;
while (readQueue.try_dequeue(flush)) {}
while (writeQueue.try_dequeue(flushop)) {}
if(modeChanging) {
modeChanging = false;
return open(); // Reopen the reenumerated device
}
if(ret == 0) {
return true;
} else {
report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error);
return false;
}
}
void ANDROIDUSB::readTask() {
constexpr size_t READ_BUFFER_SIZE = 2048;
uint8_t readbuf[READ_BUFFER_SIZE];
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while(!closing && !isDisconnected()) {
fd_set rfds = {0};
struct timeval tv = {0};
FD_SET(fd, &rfds);
tv.tv_usec = 50000; // 50ms
::select(fd + 1, &rfds, NULL, NULL, &tv);
auto bytesRead = ::read(fd, readbuf, READ_BUFFER_SIZE);
if(bytesRead > 0) {
#if 0 // Perhaps helpful for debugging :)
std::cout << "Read data: (" << bytesRead << ')' << std::hex << std::endl;
for(int i = 0; i < bytesRead; i += 16) {
for(int j = 0; j < std::min<int>(bytesRead - i, 16); j++)
std::cout << std::setw(2) << std::setfill('0') << uint32_t(readbuf[i+j]) << ' ';
std::cout << std::endl;
}
std::cout << std::dec << std::endl;
#endif
readQueue.enqueue_bulk(readbuf, bytesRead);
} else {
if(modeChanging) {
// We were expecting a disconnect for reenumeration
modeChangeThread = std::thread([this] {
modeChangeCV.notify_all();
// Requesting thread is responsible for calling close. This allows for more flexibility
});
break;
} else if(!closing && !fdIsValid() && !isDisconnected()) {
disconnected = true;
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
}
}
}
}
void ANDROIDUSB::writeTask() {
WriteOperation writeOp;
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while(!closing && !isDisconnected()) {
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
continue;
const ssize_t totalWriteSize = (ssize_t)writeOp.bytes.size();
ssize_t totalWritten = 0;
while(totalWritten < totalWriteSize) {
const ssize_t writeSize = totalWriteSize - totalWritten;
ssize_t actualWritten = ::write(fd, writeOp.bytes.data() + totalWritten, writeSize);
if(actualWritten != writeSize) {
// If we partially wrote, it's probably EAGAIN but it won't have been set
// so don't signal an error unless it's < 0, we'll come back around and
// get a -1 to see the real error.
if(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
// We filled the TX FIFO, use select to wait for it to become available again
fd_set wfds = {0};
struct timeval tv = {0};
FD_SET(fd, &wfds);
tv.tv_usec = 50000; // 50ms
::select(fd + 1, nullptr, &wfds, nullptr, &tv);
} else if (actualWritten < 0) {
if(!fdIsValid()) {
if(!isDisconnected()) {
disconnected = true;
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
}
} else
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error);
break;
}
}
if(actualWritten > 0) {
#if 0 // Perhaps helpful for debugging :)
std::cout << "Wrote data: (" << actualWritten << ')' << std::hex << std::endl;
for(int i = 0; i < actualWritten; i += 16) {
for(int j = 0; j < std::min<int>(actualWritten - i, 16); j++)
std::cout << std::setw(2) << std::setfill('0') << uint32_t(writeOp.bytes[totalWritten+i+j]) << ' ';
std::cout << std::endl;
}
std::cout << std::dec << std::endl;
#endif
totalWritten += actualWritten;
}
}
}
}
bool ANDROIDUSB::fdIsValid() {
struct termios tty = {};
return tcgetattr(fd, &tty) == 0 ? true : false;
}
void ANDROIDUSB::Find(std::vector<FoundDevice>& found) {
for (auto& each: systemFDs) {
FoundDevice device;
device.handle = 0;
device.productId = "ttyPid";
//device.serial = {};
//device.serial[getter.getSerial().copy(device.serial, sizeof(device.serial)-1)] = '\0';
// Add a factory to make the driver
device.makeDriver = [](const device_eventhandler_t& report, neodevice_t& device) {
return std::unique_ptr<Driver>(new ANDROIDUSB(report, device));
};
found.push_back(device); // Finally, add device to search results
}
}
+4
View File
@@ -29,6 +29,7 @@ bool CDCACM::open() {
const std::string& ttyPath = HandleToTTY(device.handle);
if(ttyPath.empty()) {
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
report(APIEvent::Type::DriverTTYPathEmpty, APIEvent::Severity::Error);
return false;
}
@@ -60,6 +61,7 @@ bool CDCACM::open() {
if(!isOpen()) {
//std::cout << "Open of " << ttyPath.c_str() << " failed with " << strerror(errno) << ' ';
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
report(APIEvent::Type::DriverWasNotNegOne, APIEvent::Severity::Error);
return false;
}
@@ -69,6 +71,7 @@ bool CDCACM::open() {
if(tcgetattr(fd, &tty) != 0) {
close();
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
report(APIEvent::Type::DriverTCGetAddrFail, APIEvent::Severity::Error);
return false;
}
@@ -92,6 +95,7 @@ bool CDCACM::open() {
if(tcsetattr(fd, TCSAFLUSH, &tty) != 0) { // Flushes input and output buffers as well as setting settings
close();
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
report(APIEvent::Type::DriverTCSetAddrFail, APIEvent::Severity::Error);
return false;
}
Vendored Submodule
+1
Submodule third-party/libusb added at 4239bc3a50