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
#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
#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<std::vector<std::shared_ptr<Device>>::iterator> itemsToMove;

View File

@ -39,9 +39,10 @@ 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();

View File

@ -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;
}