From 0b9491e5e36b6fae185597cd36855c47d694463e Mon Sep 17 00:00:00 2001 From: Kyle Johannes Date: Sat, 18 Nov 2023 06:03:30 -0500 Subject: [PATCH] android: first working device comm no root --- api/icsneoc/icsneoc.cpp | 15 +++- include/icsneo/platform/android/androidusb.h | 5 +- platform/android/androidusb.cpp | 86 ++++++++++---------- 3 files changed, 60 insertions(+), 46 deletions(-) diff --git a/api/icsneoc/icsneoc.cpp b/api/icsneoc/icsneoc.cpp index b235b6b..2583eeb 100644 --- a/api/icsneoc/icsneoc.cpp +++ b/api/icsneoc/icsneoc.cpp @@ -6,6 +6,9 @@ #ifdef ICSNEO_ENABLE_ANDROIDUSB #include "icsneo/platform/android/androidusb.h" +#include +#define LOG_TAG "libicsneoc" +#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) #endif #include "icsneo/icsneoc.h" @@ -98,6 +101,7 @@ bool icsneo_isValidNeoDevice(const neodevice_t* device) { // return false on nullptr if(!device) { EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); + LOGD("nullparameter neodevice error\n"); return false; } // If this neodevice_t was returned by a previous search, it will no longer be valid (as the underlying icsneo::Device is freed) @@ -111,15 +115,20 @@ bool icsneo_isValidNeoDevice(const neodevice_t* device) { } EventManager::GetInstance().add(APIEvent::Type::InvalidNeoDevice, APIEvent::Severity::Error); + LOGD("Invalid neodevice error\n"); return false; } bool icsneo_openDevice(const neodevice_t* device) { - if(!icsneo_isValidNeoDevice(device)) + if(!icsneo_isValidNeoDevice(device)) { + LOGD("Invalid neodevice error\n"); return false; + } - if(!device->device->open()) - return false; + if(!device->device->open()) { + LOGD("Device failed to open...\n"); + return false; + } // We connected successfully, move the device to connected devices std::vector>::iterator> itemsToMove; diff --git a/include/icsneo/platform/android/androidusb.h b/include/icsneo/platform/android/androidusb.h index 906560f..e466b51 100644 --- a/include/icsneo/platform/android/androidusb.h +++ b/include/icsneo/platform/android/androidusb.h @@ -39,9 +39,10 @@ private: neodevice_t& device; libusb_context *ctx = nullptr; libusb_device_handle *libusbDeviceHandle = nullptr; - inline static std::unordered_map 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(); diff --git a/platform/android/androidusb.cpp b/platform/android/androidusb.cpp index d91b8f2..40a6334 100644 --- a/platform/android/androidusb.cpp +++ b/platform/android/androidusb.cpp @@ -39,9 +39,10 @@ bool ANDROIDUSB::removeSystemFD(int sysFd) { } bool ANDROIDUSB::open() { - int ret = 0; + openStatus = true; if (!isOpen()) { report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); + LOGD("Failed isOpen check in open(): %ul\n", device.handle); return false; } @@ -94,7 +95,8 @@ bool ANDROIDUSB::open() { } bool ANDROIDUSB::isOpen() { - return device.handle >= 0; // Negative fd indicates error or not opened yet + 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() { @@ -126,20 +128,24 @@ bool ANDROIDUSB::close() { } void ANDROIDUSB::readTask() { - //constexpr size_t READ_BUFFER_SIZE = 2048; - //uint8_t readbuf[READ_BUFFER_SIZE]; + 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()) { - //fd_set rfds = {0}; - //struct timeval tv = {0}; - //FD_SET(fd, &rfds); - //tv.tv_usec = 50000; // 50ms - //::select(fd + 1, &rfds, NULL, NULL, &tv); - ssize_t bytesRead = 0; // ::read(fd, readbuf, READ_BUFFER_SIZE); - - //libusb bulk transfer? - //todo! - + int bytesRead = 0; // ::read(fd, readbuf, READ_BUFFER_SIZE); + 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; @@ -151,7 +157,7 @@ void ANDROIDUSB::readTask() { std::cout << std::dec << std::endl; #endif - //readQueue.enqueue_bulk(readbuf, bytesRead); + readQueue.enqueue_bulk(readbuf, bytesRead); } else { if(!closing && !fdIsValid() && !isDisconnected()) { disconnected = true; @@ -164,6 +170,11 @@ void ANDROIDUSB::readTask() { 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; @@ -172,31 +183,19 @@ void ANDROIDUSB::writeTask() { ssize_t totalWritten = 0; while(totalWritten < totalWriteSize) { const ssize_t writeSize = totalWriteSize - totalWritten; - ssize_t actualWritten = writeSize; //::write(fd, writeOp.bytes.data() + totalWritten, writeSize); - - //libusb bulk transfer? - //todo! - - 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; + 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) { @@ -217,7 +216,12 @@ void ANDROIDUSB::writeTask() { } bool ANDROIDUSB::fdIsValid() { - //libusb validate FD + if (device.handle != -1) { + auto itr = systemFDs.find(device.handle); + if ((itr != systemFDs.end()) && (itr->second != nullptr)) { + return true; + } + } return false; }