blob: 94b2e377c328969f2b84c3b2ea004c053bba046d [file] [log] [blame]
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Yabin Cui19bec5b2015-09-22 15:52:57 -070017#define TRACE_TAG TRANSPORT
Dan Albertdb6fe642015-03-19 15:21:08 -070018
19#include "sysdeps.h"
Josh Gaof2a988c2018-03-07 16:51:08 -080020#include "sysdeps/memory.h"
Dan Albertdb6fe642015-03-19 15:21:08 -070021#include "transport.h"
22
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080023#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080027#include "adb.h"
28
Yabin Cui3cf1b362017-03-10 16:01:01 -080029#if ADB_HOST
30
Josh Gaoa82f2462017-12-06 15:06:14 -080031#if defined(__APPLE__)
32#define CHECK_PACKET_OVERFLOW 0
33#else
34#define CHECK_PACKET_OVERFLOW 1
35#endif
36
Josh Gao3734cf02017-05-02 15:01:09 -070037// Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes
Yabin Cui3cf1b362017-03-10 16:01:01 -080038// to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html.
39static int UsbReadMessage(usb_handle* h, amessage* msg) {
40 D("UsbReadMessage");
Josh Gao3734cf02017-05-02 15:01:09 -070041
Josh Gaoa82f2462017-12-06 15:06:14 -080042#if CHECK_PACKET_OVERFLOW
Josh Gao3734cf02017-05-02 15:01:09 -070043 size_t usb_packet_size = usb_get_max_packet_size(h);
Josh Gaoc4418182017-08-28 14:43:24 -070044 CHECK_GE(usb_packet_size, sizeof(*msg));
45 CHECK_LT(usb_packet_size, 4096ULL);
Josh Gao3734cf02017-05-02 15:01:09 -070046
47 char buffer[4096];
48 int n = usb_read(h, buffer, usb_packet_size);
49 if (n != sizeof(*msg)) {
50 D("usb_read returned unexpected length %d (expected %zu)", n, sizeof(*msg));
51 return -1;
Yabin Cui3cf1b362017-03-10 16:01:01 -080052 }
Josh Gao3734cf02017-05-02 15:01:09 -070053 memcpy(msg, buffer, sizeof(*msg));
Yabin Cui3cf1b362017-03-10 16:01:01 -080054 return n;
Josh Gaoa82f2462017-12-06 15:06:14 -080055#else
56 return usb_read(h, msg, sizeof(*msg));
57#endif
Yabin Cui3cf1b362017-03-10 16:01:01 -080058}
59
Josh Gao3734cf02017-05-02 15:01:09 -070060// Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes
Yabin Cui3cf1b362017-03-10 16:01:01 -080061// to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html.
62static int UsbReadPayload(usb_handle* h, apacket* p) {
Josh Gao3734cf02017-05-02 15:01:09 -070063 D("UsbReadPayload(%d)", p->msg.data_length);
64
Josh Gao839b9322018-02-05 18:49:10 -080065 if (p->msg.data_length > MAX_PAYLOAD) {
Josh Gaob14756a2018-02-02 14:38:04 -080066 return -1;
67 }
68
Josh Gaoa82f2462017-12-06 15:06:14 -080069#if CHECK_PACKET_OVERFLOW
Josh Gao3734cf02017-05-02 15:01:09 -070070 size_t usb_packet_size = usb_get_max_packet_size(h);
Josh Gao3734cf02017-05-02 15:01:09 -070071
72 // Round the data length up to the nearest packet size boundary.
73 // The device won't send a zero packet for packet size aligned payloads,
74 // so don't read any more packets than needed.
75 size_t len = p->msg.data_length;
76 size_t rem_size = len % usb_packet_size;
77 if (rem_size) {
78 len += usb_packet_size - rem_size;
Yabin Cui3cf1b362017-03-10 16:01:01 -080079 }
Josh Gao839b9322018-02-05 18:49:10 -080080
81 p->payload.resize(len);
82 int rc = usb_read(h, &p->payload[0], p->payload.size());
83 if (rc != static_cast<int>(p->msg.data_length)) {
84 return -1;
85 }
86
87 p->payload.resize(rc);
88 return rc;
Josh Gaoa82f2462017-12-06 15:06:14 -080089#else
Josh Gao839b9322018-02-05 18:49:10 -080090 p->payload.resize(p->msg.data_length);
91 return usb_read(h, &p->payload[0], p->payload.size());
Josh Gaoa82f2462017-12-06 15:06:14 -080092#endif
Yabin Cui3cf1b362017-03-10 16:01:01 -080093}
94
Josh Gao395b86a2018-01-28 20:32:46 -080095static int remote_read(apacket* p, usb_handle* usb) {
96 int n = UsbReadMessage(usb, &p->msg);
Yabin Cui3cf1b362017-03-10 16:01:01 -080097 if (n < 0) {
98 D("remote usb: read terminated (message)");
99 return -1;
100 }
Josh Gao395b86a2018-01-28 20:32:46 -0800101 if (static_cast<size_t>(n) != sizeof(p->msg)) {
102 D("remote usb: read received unexpected header length %d", n);
103 return -1;
Yabin Cui3cf1b362017-03-10 16:01:01 -0800104 }
105 if (p->msg.data_length) {
Josh Gao395b86a2018-01-28 20:32:46 -0800106 n = UsbReadPayload(usb, p);
Yabin Cui3cf1b362017-03-10 16:01:01 -0800107 if (n < 0) {
108 D("remote usb: terminated (data)");
109 return -1;
110 }
111 if (static_cast<uint32_t>(n) != p->msg.data_length) {
112 D("remote usb: read payload failed (need %u bytes, give %d bytes), skip it",
113 p->msg.data_length, n);
Josh Gao395b86a2018-01-28 20:32:46 -0800114 return -1;
Yabin Cui3cf1b362017-03-10 16:01:01 -0800115 }
116 }
Yabin Cui3cf1b362017-03-10 16:01:01 -0800117 return 0;
Yabin Cui3cf1b362017-03-10 16:01:01 -0800118}
119
120#else
121
122// On Android devices, we rely on the kernel to provide buffered read.
123// So we can recover automatically from EOVERFLOW.
Josh Gao395b86a2018-01-28 20:32:46 -0800124static int remote_read(apacket* p, usb_handle* usb) {
125 if (usb_read(usb, &p->msg, sizeof(amessage))) {
Josh Gao03eba902017-07-26 11:06:55 -0700126 PLOG(ERROR) << "remote usb: read terminated (message)";
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800127 return -1;
128 }
129
Josh Gao67b683a2017-05-16 15:02:45 -0700130 if (p->msg.data_length) {
Josh Gao839b9322018-02-05 18:49:10 -0800131 if (p->msg.data_length > MAX_PAYLOAD) {
Josh Gaob14756a2018-02-02 14:38:04 -0800132 PLOG(ERROR) << "remote usb: read overflow (data length = " << p->msg.data_length << ")";
133 return -1;
134 }
135
Josh Gao839b9322018-02-05 18:49:10 -0800136 p->payload.resize(p->msg.data_length);
137 if (usb_read(usb, &p->payload[0], p->payload.size())) {
Josh Gao03eba902017-07-26 11:06:55 -0700138 PLOG(ERROR) << "remote usb: terminated (data)";
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800139 return -1;
140 }
141 }
142
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800143 return 0;
144}
Yabin Cui3cf1b362017-03-10 16:01:01 -0800145#endif
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800146
Josh Gao395b86a2018-01-28 20:32:46 -0800147UsbConnection::~UsbConnection() {
148 usb_close(handle_);
149}
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800150
Josh Gao395b86a2018-01-28 20:32:46 -0800151bool UsbConnection::Read(apacket* packet) {
152 int rc = remote_read(packet, handle_);
153 return rc == 0;
154}
155
156bool UsbConnection::Write(apacket* packet) {
157 unsigned size = packet->msg.data_length;
158
159 if (usb_write(handle_, &packet->msg, sizeof(packet->msg)) != 0) {
Josh Gao03eba902017-07-26 11:06:55 -0700160 PLOG(ERROR) << "remote usb: 1 - write terminated";
Josh Gao395b86a2018-01-28 20:32:46 -0800161 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800162 }
Josh Gao395b86a2018-01-28 20:32:46 -0800163
Josh Gao839b9322018-02-05 18:49:10 -0800164 if (packet->msg.data_length != 0 && usb_write(handle_, packet->payload.data(), size) != 0) {
Josh Gao03eba902017-07-26 11:06:55 -0700165 PLOG(ERROR) << "remote usb: 2 - write terminated";
Josh Gao395b86a2018-01-28 20:32:46 -0800166 return false;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800167 }
168
Josh Gao395b86a2018-01-28 20:32:46 -0800169 return true;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800170}
171
Josh Gao395b86a2018-01-28 20:32:46 -0800172void UsbConnection::Close() {
173 usb_kick(handle_);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800174}
175
Yabin Cui3cf1b362017-03-10 16:01:01 -0800176void init_usb_transport(atransport* t, usb_handle* h) {
Yabin Cui815ad882015-09-02 17:44:28 -0700177 D("transport: usb");
Josh Gaof2a988c2018-03-07 16:51:08 -0800178 auto connection = std::make_unique<UsbConnection>(h);
Luis Hector Chavez3c7881d2018-04-25 08:56:41 -0700179 t->SetConnection(std::make_unique<BlockingConnectionAdapter>(std::move(connection)));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800180 t->type = kTransportUsb;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800181}
182
Josh Gao395b86a2018-01-28 20:32:46 -0800183int is_adb_interface(int usb_class, int usb_subclass, int usb_protocol) {
Elliott Hughes4b8538e2014-11-19 22:07:34 -0800184 return (usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS && usb_protocol == ADB_PROTOCOL);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800185}
Josh Gao210b63f2017-02-22 17:07:01 -0800186
187bool should_use_libusb() {
Josh Gao511ff8a2017-12-08 13:05:40 -0800188#if !ADB_HOST
Josh Gao210b63f2017-02-22 17:07:01 -0800189 return false;
190#else
Josh Gao1ca19aa2017-06-26 12:16:30 -0700191 static bool enable = getenv("ADB_LIBUSB") && strcmp(getenv("ADB_LIBUSB"), "1") == 0;
192 return enable;
Josh Gao210b63f2017-02-22 17:07:01 -0800193#endif
194}