1 /*
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 
17 #define TRACE_TAG TRANSPORT
18 
19 #include "sysdeps.h"
20 
21 #include "client/usb.h"
22 
23 #include <memory>
24 
25 #include "sysdeps.h"
26 #include "transport.h"
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 
32 #include "adb.h"
33 
34 #if defined(__APPLE__)
35 #define CHECK_PACKET_OVERFLOW 0
36 #else
37 #define CHECK_PACKET_OVERFLOW 1
38 #endif
39 
40 // Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes
41 // to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html.
UsbReadMessage(usb_handle * h,amessage * msg)42 static int UsbReadMessage(usb_handle* h, amessage* msg) {
43     D("UsbReadMessage");
44 
45 #if CHECK_PACKET_OVERFLOW
46     size_t usb_packet_size = usb_get_max_packet_size(h);
47     CHECK_GE(usb_packet_size, sizeof(*msg));
48     CHECK_LT(usb_packet_size, 4096ULL);
49 
50     char buffer[4096];
51     int n = usb_read(h, buffer, usb_packet_size);
52     if (n != sizeof(*msg)) {
53         D("usb_read returned unexpected length %d (expected %zu)", n, sizeof(*msg));
54         return -1;
55     }
56     memcpy(msg, buffer, sizeof(*msg));
57     return n;
58 #else
59     return usb_read(h, msg, sizeof(*msg));
60 #endif
61 }
62 
63 // Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes
64 // to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html.
UsbReadPayload(usb_handle * h,apacket * p)65 static int UsbReadPayload(usb_handle* h, apacket* p) {
66     D("UsbReadPayload(%d)", p->msg.data_length);
67 
68     if (p->msg.data_length > MAX_PAYLOAD) {
69         return -1;
70     }
71 
72 #if CHECK_PACKET_OVERFLOW
73     size_t usb_packet_size = usb_get_max_packet_size(h);
74 
75     // Round the data length up to the nearest packet size boundary.
76     // The device won't send a zero packet for packet size aligned payloads,
77     // so don't read any more packets than needed.
78     size_t len = p->msg.data_length;
79     size_t rem_size = len % usb_packet_size;
80     if (rem_size) {
81         len += usb_packet_size - rem_size;
82     }
83 
84     p->payload.resize(len);
85     int rc = usb_read(h, &p->payload[0], p->payload.size());
86     if (rc != static_cast<int>(p->msg.data_length)) {
87         return -1;
88     }
89 
90     p->payload.resize(rc);
91     return rc;
92 #else
93     p->payload.resize(p->msg.data_length);
94     return usb_read(h, &p->payload[0], p->payload.size());
95 #endif
96 }
97 
remote_read(apacket * p,usb_handle * usb)98 static int remote_read(apacket* p, usb_handle* usb) {
99     int n = UsbReadMessage(usb, &p->msg);
100     if (n < 0) {
101         D("remote usb: read terminated (message)");
102         return -1;
103     }
104     if (static_cast<size_t>(n) != sizeof(p->msg)) {
105         D("remote usb: read received unexpected header length %d", n);
106         return -1;
107     }
108     if (p->msg.data_length) {
109         n = UsbReadPayload(usb, p);
110         if (n < 0) {
111             D("remote usb: terminated (data)");
112             return -1;
113         }
114         if (static_cast<uint32_t>(n) != p->msg.data_length) {
115             D("remote usb: read payload failed (need %u bytes, give %d bytes), skip it",
116               p->msg.data_length, n);
117             return -1;
118         }
119     }
120     return 0;
121 }
122 
~UsbConnection()123 UsbConnection::~UsbConnection() {
124     usb_close(handle_);
125 }
126 
Read(apacket * packet)127 bool UsbConnection::Read(apacket* packet) {
128     int rc = remote_read(packet, handle_);
129     return rc == 0;
130 }
131 
Write(apacket * packet)132 bool UsbConnection::Write(apacket* packet) {
133     int size = packet->msg.data_length;
134 
135     if (usb_write(handle_, &packet->msg, sizeof(packet->msg)) != sizeof(packet->msg)) {
136         PLOG(ERROR) << "remote usb: 1 - write terminated";
137         return false;
138     }
139 
140     if (packet->msg.data_length != 0 && usb_write(handle_, packet->payload.data(), size) != size) {
141         PLOG(ERROR) << "remote usb: 2 - write terminated";
142         return false;
143     }
144 
145     return true;
146 }
147 
DoTlsHandshake(RSA * key,std::string * auth_key)148 bool UsbConnection::DoTlsHandshake(RSA* key, std::string* auth_key) {
149     // TODO: support TLS for usb connections
150     LOG(FATAL) << "Not supported yet.";
151     return false;
152 }
153 
Reset()154 void UsbConnection::Reset() {
155     usb_reset(handle_);
156     usb_kick(handle_);
157 }
158 
Close()159 void UsbConnection::Close() {
160     usb_kick(handle_);
161 }
162 
init_usb_transport(atransport * t,usb_handle * h)163 void init_usb_transport(atransport* t, usb_handle* h) {
164     D("transport: usb");
165     auto connection = std::make_unique<UsbConnection>(h);
166     t->SetConnection(std::make_unique<BlockingConnectionAdapter>(std::move(connection)));
167     t->type = kTransportUsb;
168     t->SetUsbHandle(h);
169 }
170 
is_adb_interface(int usb_class,int usb_subclass,int usb_protocol)171 bool is_adb_interface(int usb_class, int usb_subclass, int usb_protocol) {
172     // ADB over gadget mode and DbC use the same ADB protocol.
173     if (usb_protocol == ADB_PROTOCOL && ((usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS) ||
174             (usb_class == ADB_DBC_CLASS && usb_subclass == ADB_DBC_SUBCLASS)))
175         return true;
176     else
177         return false;
178 }
179 
should_use_libusb()180 bool should_use_libusb() {
181     bool enable = true;
182 #if defined(_WIN32)
183     enable = false;
184 #endif
185     char* env = getenv("ADB_LIBUSB");
186     if (env) {
187         enable = (strcmp(env, "1") == 0);
188     }
189     return enable;
190 }
191