Skip to content
This repository was archived by the owner on Jan 10, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion adb/adb.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ void put_apacket(apacket *p);
#define ADB_SUBCLASS 0x42
#define ADB_PROTOCOL 0x1

#define ADB_DBC_CLASS 0xDC
#define ADB_DBC_SUBCLASS 0x2
#define ADB_DBC_PROTOCOL 0x1

void local_init(int port);
bool local_connect(int port);
Expand All @@ -210,9 +213,9 @@ extern int SHELL_EXIT_NOTIFY_FD;
#define CHUNK_SIZE (64*1024)

#if !ADB_HOST
#define USB_DBC_ADB_PATH "/dev/dbc_raw"
#define USB_FFS_ADB_PATH "/dev/usb-ffs/adb/"
#define USB_FFS_ADB_EP(x) USB_FFS_ADB_PATH#x

#define USB_FFS_ADB_EP0 USB_FFS_ADB_EP(ep0)
#define USB_FFS_ADB_OUT USB_FFS_ADB_EP(ep1)
#define USB_FFS_ADB_IN USB_FFS_ADB_EP(ep2)
Expand Down
45 changes: 45 additions & 0 deletions adb/client/usb_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,9 @@ static int usb_bulk_read(usb_handle* h, void* data, int len) {
urb->buffer = data;
urb->buffer_length = len;

usbdevfs_ctrltransfer ufs;
unsigned short int ufsdata;

if (h->dead) {
errno = EINVAL;
return -1;
Expand All @@ -364,13 +367,55 @@ static int usb_bulk_read(usb_handle* h, void* data, int len) {
D("[ reap urb - wait ]");
h->reaper_thread = pthread_self();
int fd = h->fd;

ufsdata = 0;
ufs.bRequestType = 0x82;
ufs.bRequest = USB_REQ_GET_STATUS;
ufs.wValue = 0x0000;
ufs.wIndex = h->ep_in;
ufs.wLength = 0x0002;
ufs.data = &ufsdata;

if(TEMP_FAILURE_RETRY(ioctl(h->fd,USBDEVFS_CONTROL,&ufs))== -1)
{
D("clear_halt read failed");}
else
{
D("clear_halt read successful %d",ufsdata);
}

if(ufsdata)
{
ufs.bRequestType = 0x02;
ufs.bRequest = USB_REQ_CLEAR_FEATURE;
ufs.wValue = 0x0000;
ufs.wIndex = h->ep_out;
ufs.wLength = 0x0000;
ufs.data = NULL;

if(TEMP_FAILURE_RETRY(ioctl(h->fd,USBDEVFS_CONTROL,&ufs))== -1)
{
D("clear_halt read2 failed");
}
else
{
D("clear_halt read2 successful ");
}
errno = ETIMEDOUT;
return -1;
}

lock.unlock();

// This ioctl must not have TEMP_FAILURE_RETRY because we send SIGALRM to break out.

usbdevfs_urb* out = nullptr;
D("before reap urb");

int res = ioctl(fd, USBDEVFS_REAPURB, &out);
int saved_errno = errno;

D("after reap urb");
lock.lock();
h->reaper_thread = 0;
if (h->dead) {
Expand Down
12 changes: 8 additions & 4 deletions adb/commandline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ static int install_multiple_app(int argc, const char** argv);
static int uninstall_app(int argc, const char** argv);
static int install_app_legacy(int argc, const char** argv);
static int uninstall_app_legacy(int argc, const char** argv);
static int adb_query_command(const std::string& command);

extern int gListenAll;

Expand Down Expand Up @@ -1040,7 +1041,12 @@ static bool adb_root(const char* command) {
return false;
}

// Give adbd some time to kill itself and come back up.
// We can't use wait-for-device because devices (e.g. adb over network) might not come back.
std::this_thread::sleep_for(1s);

// Figure out whether we actually did anything.
/*
char buf[256];
char* cur = buf;
ssize_t bytes_left = sizeof(buf);
Expand All @@ -1066,10 +1072,8 @@ static bool adb_root(const char* command) {
if (cur != buf && strstr(buf, "restarting") == nullptr) {
return true;
}
*/

// Give adbd some time to kill itself and come back up.
// We can't use wait-for-device because devices (e.g. adb over network) might not come back.
std::this_thread::sleep_for(3s);
return true;
}

Expand Down Expand Up @@ -1608,7 +1612,7 @@ int adb_commandline(int argc, const char** argv) {
}
return adb_connect_command(command);
} else if (!strcmp(argv[0], "root") || !strcmp(argv[0], "unroot")) {
return adb_root(argv[0]) ? 0 : 1;
return adb_root(argv[0]) ? adb_query_command(format_host_command("reconnect")) : 1;
} else if (!strcmp(argv[0], "bugreport")) {
Bugreport bugreport;
return bugreport.DoIt(argc, argv);
Expand Down
3 changes: 2 additions & 1 deletion adb/daemon/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <getopt.h>
#include <sys/prctl.h>

#include <stdio.h>
#include <memory>

#include <android-base/logging.h>
Expand Down Expand Up @@ -177,7 +178,7 @@ int adbd_main(int server_port) {
drop_privileges(server_port);

bool is_usb = false;
if (access(USB_FFS_ADB_EP0, F_OK) == 0) {
if ( (access(USB_FFS_ADB_EP0, F_OK) == 0) || (access(USB_DBC_ADB_PATH,F_OK) == 0) ) {
// Listen on USB.
usb_init();
is_usb = true;
Expand Down
134 changes: 132 additions & 2 deletions adb/daemon/usb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ using namespace std::chrono_literals;
// on a device kernel that has been running for a while fragmenting its
// memory so we start with a larger allocation, and shrink the amount if
// necessary.
#define USB_FFS_BULK_SIZE 16384
#define USB_FFS_BULK_SIZE (64*1024)
#define USB_DBC_BULK_SIZE (64*1024)

#define cpu_to_le16(x) htole16(x)
#define cpu_to_le32(x) htole32(x)
Expand Down Expand Up @@ -459,10 +460,139 @@ static void usb_ffs_init() {
std::thread(usb_ffs_open_thread, h).detach();
}

bool init_dbc_raw(struct usb_handle* h) {
D("init_dbc_raw called\n");
h->max_rw = USB_DBC_BULK_SIZE;

h->bulk_out = adb_open(USB_DBC_ADB_PATH, O_RDWR);
if (h->bulk_out < 0) {
D("[ %s: cannot open bulk-out ep: errno=%d ]", USB_DBC_ADB_PATH, errno);
goto err;
}

h->bulk_in = h->bulk_out;
h->control = h->bulk_out;

return true;

err:
h->bulk_out = -1;
h->bulk_in = -1;
h->control = -1;
return false;
}

static void usb_dbc_open_thread(void* x) {
struct usb_handle* usb = (struct usb_handle*)x;

adb_thread_setname("usb dbc open");
D("dbc_open_thread called\n");
while (true) {
// wait until the USB device needs opening
std::unique_lock<std::mutex> lock(usb->lock);
while (!usb->open_new_connection) {
usb->notify.wait(lock);
}
usb->open_new_connection = false;
lock.unlock();

while (true) {
if (init_dbc_raw(usb)) {
break;
}
std::this_thread::sleep_for(1s);
}

D("register usb transport\n");
register_usb_transport(usb, 0, 0, 1);
}

// never gets here
abort();
}

static int usb_dbc_write(usb_handle* h, const void* data, int len) {
D("about to write (fd=%d, len=%d)", h->bulk_in, len);

const char* buf = static_cast<const char*>(data);
while (len > 0) {
int write_len = std::min(h->max_rw, len);
int n = adb_write(h->bulk_in, buf, write_len);
if (n < 0) {
D("ERROR: fd = %d, n = %d: %s", h->bulk_in, n, strerror(errno));
return -1;
}
buf += n;
len -= n;
}

D("[ done fd=%d ]", h->bulk_in);
return 0;
}

static int usb_dbc_read(usb_handle* h, void* data, int len) {
D("about to read (fd=%d, len=%d)", h->bulk_out, len);

char* buf = static_cast<char*>(data);
while (len > 0) {
int read_len = std::min(h->max_rw, len);
int n = adb_read(h->bulk_out, buf, read_len);
if (n < 0) {
D("ERROR: fd = %d, n = %d: %s", h->bulk_out, n, strerror(errno));
return -1;
}
buf += n;
len -= n;
}
D("[ done fd=%d ]", h->bulk_out);
return 0;
}

static void usb_dbc_kick(usb_handle* h) {
int err;
D("usb_dbc_kick called\n");
err = ioctl(h->bulk_in, FLUSH_DBC_EP);
if (err < 0) {
D("[ kick: source (fd=%d) clear halt failed (%d) ]", h->bulk_in, errno);
}
h->kicked = true;
}

static void usb_dbc_close(usb_handle* h) {
h->kicked = false;
D("usb_dbc_close called\n");
adb_close(h->bulk_out);
// Notify usb_adb_open_thread to open a new connection.
h->lock.lock();
h->open_new_connection = true;
h->lock.unlock();
h->notify.notify_one();
}

static void usb_dbc_init() {
D("[ usb_init - using dbc ]");

usb_handle* h = new usb_handle();

h->write = usb_dbc_write;
h->read = usb_dbc_read;
h->kick = usb_dbc_kick;
h->close = usb_dbc_close;

D("[ usb_init - starting thread ]");
std::thread(usb_dbc_open_thread, h).detach();
}


void usb_init() {
dummy_fd = adb_open("/dev/null", O_WRONLY);
CHECK_NE(dummy_fd, -1);
usb_ffs_init();

if (access(USB_DBC_ADB_PATH,F_OK) == 0)
usb_dbc_init();
else
usb_ffs_init();

}

int usb_write(usb_handle* h, const void* data, int len) {
Expand Down
8 changes: 7 additions & 1 deletion adb/transport_usb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,13 @@ void init_usb_transport(atransport* t, usb_handle* h) {

int is_adb_interface(int usb_class, int usb_subclass, int usb_protocol)
{
return (usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS && usb_protocol == ADB_PROTOCOL);

if ( (usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS && usb_protocol == ADB_PROTOCOL) ||
(usb_class == ADB_DBC_CLASS && usb_subclass == ADB_DBC_SUBCLASS && usb_protocol == ADB_DBC_PROTOCOL))
return true;
else
return false;

}

bool should_use_libusb() {
Expand Down