devel/adb: new port

This commit is contained in:
c0dev0id
2026-07-08 11:08:05 +02:00
parent a91ecb0f1d
commit 8813f7e720
28 changed files with 786 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
/*
* OpenBSD stub implementations of the old-style adb USB API (usb_handle*).
*
* These are never called because should_use_libusb() always returns true on
* OpenBSD, but the linker requires them to resolve symbols referenced from
* adb/client/transport_usb.cpp.
*
* Licensed under the Apache License, Version 2.0.
*/
#include <stddef.h>
#include "client/usb.h"
struct usb_handle {};
void usb_init() {}
void usb_cleanup() {}
int usb_write(usb_handle*, const void*, int) { return -1; }
int usb_read(usb_handle*, void*, int) { return -1; }
int usb_close(usb_handle*) { return -1; }
void usb_reset(usb_handle*) {}
void usb_kick(usb_handle*) {}
size_t usb_get_max_packet_size(usb_handle*) { return 512; }

View File

@@ -0,0 +1,20 @@
/* OpenBSD stub for linux/capability.h */
#pragma once
#include <stdint.h>
typedef uint32_t __u32;
#define _LINUX_CAPABILITY_VERSION_3 0x20080522
#define _LINUX_CAPABILITY_U32S_3 2
#define VFS_CAP_REVISION_1 0x01000000
#define VFS_CAP_REVISION_2 0x02000000
#define VFS_CAP_REVISION_3 0x03000000
#define VFS_CAP_REVISION_MASK 0xff000000
#define VFS_CAP_FLAGS_EFFECTIVE 0x000001
struct vfs_cap_data {
__u32 magic_etc;
struct { __u32 permitted, inheritable; } data[2];
};
struct vfs_ns_cap_data {
__u32 magic_etc;
struct { __u32 permitted, inheritable; } data[2];
__u32 rootid;
};

View File

@@ -0,0 +1,8 @@
/* OpenBSD compat: add mempcpy (GNU extension) via #include_next wrapper */
#pragma once
#include_next <string.h>
#ifndef mempcpy
static inline void *mempcpy(void *dst, const void *src, size_t n) {
return (char *)memcpy(dst, src, n) + n;
}
#endif

View File

@@ -0,0 +1,3 @@
/* OpenBSD stub: major/minor/makedev are in sys/types.h */
#pragma once
#include <sys/types.h>

View File

@@ -0,0 +1,170 @@
/*
* USB transport for fastboot using libusb-1.0.
* Used on OpenBSD (and other platforms without Linux usbfs).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include <libusb-1.0/libusb.h>
#include <stdio.h>
#include <string.h>
#include <memory>
#include <android-base/macros.h>
#include "usb.h"
static libusb_context* g_ctx = nullptr;
class LibUsbTransport : public UsbTransport {
public:
LibUsbTransport(libusb_device_handle* h, uint8_t ep_in, uint8_t ep_out,
int ifc_num, uint32_t ms_timeout)
: handle_(h), ep_in_(ep_in), ep_out_(ep_out),
ifc_num_(ifc_num), ms_timeout_(ms_timeout) {}
~LibUsbTransport() override { Close(); }
ssize_t Read(void* data, size_t len) override {
int transferred = 0;
int r = libusb_bulk_transfer(handle_, ep_in_,
reinterpret_cast<unsigned char*>(data),
static_cast<int>(len), &transferred,
ms_timeout_);
if (r == 0 || r == LIBUSB_ERROR_TIMEOUT)
return transferred;
return -1;
}
ssize_t Write(const void* data, size_t len) override {
int transferred = 0;
int r = libusb_bulk_transfer(handle_, ep_out_,
const_cast<unsigned char*>(
reinterpret_cast<const unsigned char*>(data)),
static_cast<int>(len), &transferred,
ms_timeout_);
if (r == 0)
return transferred;
return -1;
}
int Close() override {
if (handle_) {
libusb_release_interface(handle_, ifc_num_);
libusb_close(handle_);
handle_ = nullptr;
}
return 0;
}
int Reset() override {
if (handle_)
return libusb_reset_device(handle_) ? -1 : 0;
return -1;
}
private:
libusb_device_handle* handle_;
uint8_t ep_in_, ep_out_;
int ifc_num_;
uint32_t ms_timeout_;
DISALLOW_COPY_AND_ASSIGN(LibUsbTransport);
};
std::unique_ptr<UsbTransport> usb_open(ifc_match_func callback,
uint32_t timeout_ms) {
if (!g_ctx) {
if (libusb_init(&g_ctx) != 0)
return nullptr;
}
libusb_device** devs;
ssize_t cnt = libusb_get_device_list(g_ctx, &devs);
if (cnt < 0)
return nullptr;
std::unique_ptr<UsbTransport> result;
for (ssize_t i = 0; i < cnt && !result; i++) {
libusb_device* dev = devs[i];
struct libusb_device_descriptor desc;
if (libusb_get_device_descriptor(dev, &desc) != 0)
continue;
struct libusb_config_descriptor* config;
if (libusb_get_active_config_descriptor(dev, &config) != 0)
continue;
for (int j = 0; j < (int)config->bNumInterfaces && !result; j++) {
const struct libusb_interface* ifc = &config->interface[j];
for (int k = 0; k < ifc->num_altsetting && !result; k++) {
const struct libusb_interface_descriptor* id = &ifc->altsetting[k];
usb_ifc_info info = {};
info.dev_vendor = desc.idVendor;
info.dev_product = desc.idProduct;
info.dev_class = desc.bDeviceClass;
info.dev_subclass = desc.bDeviceSubClass;
info.dev_protocol = desc.bDeviceProtocol;
info.ifc_class = id->bInterfaceClass;
info.ifc_subclass = id->bInterfaceSubClass;
info.ifc_protocol = id->bInterfaceProtocol;
uint8_t ep_in = 0, ep_out = 0;
for (int e = 0; e < (int)id->bNumEndpoints; e++) {
const struct libusb_endpoint_descriptor* ep = &id->endpoint[e];
if ((ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) !=
LIBUSB_TRANSFER_TYPE_BULK)
continue;
if (ep->bEndpointAddress & LIBUSB_ENDPOINT_IN) {
ep_in = ep->bEndpointAddress;
info.has_bulk_in = 1;
} else {
ep_out = ep->bEndpointAddress;
info.has_bulk_out = 1;
}
}
libusb_device_handle* h;
if (libusb_open(dev, &h) != 0)
continue;
info.writable = 1;
if (desc.iSerialNumber) {
libusb_get_string_descriptor_ascii(
h, desc.iSerialNumber,
reinterpret_cast<unsigned char*>(info.serial_number),
sizeof(info.serial_number));
}
if (id->iInterface) {
libusb_get_string_descriptor_ascii(
h, id->iInterface,
reinterpret_cast<unsigned char*>(info.interface),
sizeof(info.interface));
}
snprintf(info.device_path, sizeof(info.device_path),
"usb:%d:%d", libusb_get_bus_number(dev),
libusb_get_device_address(dev));
if (callback(&info) == 0 && ep_in && ep_out) {
if (libusb_claim_interface(h, id->bInterfaceNumber) == 0) {
result = std::make_unique<LibUsbTransport>(
h, ep_in, ep_out, id->bInterfaceNumber,
timeout_ms);
} else {
libusb_close(h);
}
} else {
libusb_close(h);
}
}
}
libusb_free_config_descriptor(config);
}
libusb_free_device_list(devs, 1);
return result;
}