android: first working device comm no root

136-add-android-support
Kyle Johannes 2023-11-18 06:03:30 -05:00
parent ca630b4569
commit 0b9491e5e3
3 changed files with 60 additions and 46 deletions

View File

@ -6,6 +6,9 @@
#ifdef ICSNEO_ENABLE_ANDROIDUSB #ifdef ICSNEO_ENABLE_ANDROIDUSB
#include "icsneo/platform/android/androidusb.h" #include "icsneo/platform/android/androidusb.h"
#include <android/log.h>
#define LOG_TAG "libicsneoc"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#endif #endif
#include "icsneo/icsneoc.h" #include "icsneo/icsneoc.h"
@ -98,6 +101,7 @@ bool icsneo_isValidNeoDevice(const neodevice_t* device) {
// return false on nullptr // return false on nullptr
if(!device) { if(!device) {
EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
LOGD("nullparameter neodevice error\n");
return false; 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) // 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); EventManager::GetInstance().add(APIEvent::Type::InvalidNeoDevice, APIEvent::Severity::Error);
LOGD("Invalid neodevice error\n");
return false; return false;
} }
bool icsneo_openDevice(const neodevice_t* device) { bool icsneo_openDevice(const neodevice_t* device) {
if(!icsneo_isValidNeoDevice(device)) if(!icsneo_isValidNeoDevice(device)) {
LOGD("Invalid neodevice error\n");
return false; return false;
}
if(!device->device->open()) if(!device->device->open()) {
LOGD("Device failed to open...\n");
return false; return false;
}
// We connected successfully, move the device to connected devices // We connected successfully, move the device to connected devices
std::vector<std::vector<std::shared_ptr<Device>>::iterator> itemsToMove; std::vector<std::vector<std::shared_ptr<Device>>::iterator> itemsToMove;

View File

@ -39,9 +39,10 @@ private:
neodevice_t& device; neodevice_t& device;
libusb_context *ctx = nullptr; libusb_context *ctx = nullptr;
libusb_device_handle *libusbDeviceHandle = nullptr; libusb_device_handle *libusbDeviceHandle = nullptr;
inline static std::unordered_map<int,libusb_device_handle*> systemFDs; //android FD, libusb handle 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 readTask() override;
void writeTask() override; void writeTask() override;
bool fdIsValid(); bool fdIsValid();

View File

@ -39,9 +39,10 @@ bool ANDROIDUSB::removeSystemFD(int sysFd) {
} }
bool ANDROIDUSB::open() { bool ANDROIDUSB::open() {
int ret = 0; openStatus = true;
if (!isOpen()) { if (!isOpen()) {
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
LOGD("Failed isOpen check in open(): %ul\n", device.handle);
return false; return false;
} }
@ -94,7 +95,8 @@ bool ANDROIDUSB::open() {
} }
bool ANDROIDUSB::isOpen() { 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() { bool ANDROIDUSB::close() {
@ -126,20 +128,24 @@ bool ANDROIDUSB::close() {
} }
void ANDROIDUSB::readTask() { void ANDROIDUSB::readTask() {
//constexpr size_t READ_BUFFER_SIZE = 2048; constexpr size_t READ_BUFFER_SIZE = 2048;
//uint8_t readbuf[READ_BUFFER_SIZE]; uint8_t readbuf[READ_BUFFER_SIZE];
EventManager::GetInstance().downgradeErrorsOnCurrentThread(); EventManager::GetInstance().downgradeErrorsOnCurrentThread();
libusb_device_handle *devh = nullptr;
auto mapItr = systemFDs.find(device.handle);
if (mapItr != systemFDs.end()) {
devh = mapItr->second;
}
while(!closing && !isDisconnected()) { while(!closing && !isDisconnected()) {
//fd_set rfds = {0}; int bytesRead = 0; // ::read(fd, readbuf, READ_BUFFER_SIZE);
//struct timeval tv = {0}; auto ret = libusb_bulk_transfer(devh, ep_in_addr, readbuf, READ_BUFFER_SIZE, &bytesRead, 50);
//FD_SET(fd, &rfds); if (ret == LIBUSB_ERROR_TIMEOUT) {
//tv.tv_usec = 50000; // 50ms continue;
//::select(fd + 1, &rfds, NULL, NULL, &tv); }
ssize_t bytesRead = 0; // ::read(fd, readbuf, READ_BUFFER_SIZE); if (ret == LIBUSB_ERROR_NO_DEVICE) {
disconnected = true;
//libusb bulk transfer? report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
//todo! }
if(bytesRead > 0) { if(bytesRead > 0) {
#if 0 // Perhaps helpful for debugging :) #if 0 // Perhaps helpful for debugging :)
std::cout << "Read data: (" << bytesRead << ')' << std::hex << std::endl; std::cout << "Read data: (" << bytesRead << ')' << std::hex << std::endl;
@ -151,7 +157,7 @@ void ANDROIDUSB::readTask() {
std::cout << std::dec << std::endl; std::cout << std::dec << std::endl;
#endif #endif
//readQueue.enqueue_bulk(readbuf, bytesRead); readQueue.enqueue_bulk(readbuf, bytesRead);
} else { } else {
if(!closing && !fdIsValid() && !isDisconnected()) { if(!closing && !fdIsValid() && !isDisconnected()) {
disconnected = true; disconnected = true;
@ -164,6 +170,11 @@ void ANDROIDUSB::readTask() {
void ANDROIDUSB::writeTask() { void ANDROIDUSB::writeTask() {
WriteOperation writeOp; WriteOperation writeOp;
EventManager::GetInstance().downgradeErrorsOnCurrentThread(); EventManager::GetInstance().downgradeErrorsOnCurrentThread();
libusb_device_handle *devh = nullptr;
auto mapItr = systemFDs.find(device.handle);
if (mapItr != systemFDs.end()) {
devh = mapItr->second;
}
while(!closing && !isDisconnected()) { while(!closing && !isDisconnected()) {
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100))) if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
continue; continue;
@ -172,31 +183,19 @@ void ANDROIDUSB::writeTask() {
ssize_t totalWritten = 0; ssize_t totalWritten = 0;
while(totalWritten < totalWriteSize) { while(totalWritten < totalWriteSize) {
const ssize_t writeSize = totalWriteSize - totalWritten; const ssize_t writeSize = totalWriteSize - totalWritten;
ssize_t actualWritten = writeSize; //::write(fd, writeOp.bytes.data() + totalWritten, writeSize); int actualWritten = 0;
auto ret = libusb_bulk_transfer(devh, ep_out_addr, writeOp.bytes.data() + totalWritten, writeSize, &actualWritten, 100);
//libusb bulk transfer? if (ret < 0) {
//todo! if (ret == LIBUSB_ERROR_NO_DEVICE) {
LOGD("Write task bulk transfer failed, device disconnected!\n");
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()) { if(!isDisconnected()) {
disconnected = true; disconnected = true;
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error); report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
} }
} else }
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error); if (ret != LIBUSB_ERROR_TIMEOUT) {
break; LOGD("Write task bulk transfer failed!\n%s", libusb_strerror(ret));
continue;
} }
} }
if(actualWritten > 0) { if(actualWritten > 0) {
@ -217,7 +216,12 @@ void ANDROIDUSB::writeTask() {
} }
bool ANDROIDUSB::fdIsValid() { 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; return false;
} }