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#include "transport.h" 21 22#include <stdio.h> 23#include <stdlib.h> 24#include <string.h> 25 26#include "adb.h" 27 28#if ADB_HOST 29 30// Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes 31// to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html. 32static int UsbReadMessage(usb_handle* h, amessage* msg) { 33 D("UsbReadMessage"); 34 35 size_t usb_packet_size = usb_get_max_packet_size(h); 36 CHECK(usb_packet_size >= sizeof(*msg)); 37 CHECK(usb_packet_size < 4096); 38 39 char buffer[4096]; 40 int n = usb_read(h, buffer, usb_packet_size); 41 if (n != sizeof(*msg)) { 42 D("usb_read returned unexpected length %d (expected %zu)", n, sizeof(*msg)); 43 return -1; 44 } 45 memcpy(msg, buffer, sizeof(*msg)); 46 return n; 47} 48 49// Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes 50// to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html. 51static int UsbReadPayload(usb_handle* h, apacket* p) { 52 D("UsbReadPayload(%d)", p->msg.data_length); 53 54 size_t usb_packet_size = usb_get_max_packet_size(h); 55 CHECK(sizeof(p->data) % usb_packet_size == 0); 56 57 // Round the data length up to the nearest packet size boundary. 58 // The device won't send a zero packet for packet size aligned payloads, 59 // so don't read any more packets than needed. 60 size_t len = p->msg.data_length; 61 size_t rem_size = len % usb_packet_size; 62 if (rem_size) { 63 len += usb_packet_size - rem_size; 64 } 65 CHECK(len <= sizeof(p->data)); 66 return usb_read(h, &p->data, len); 67} 68 69static int remote_read(apacket* p, atransport* t) { 70 int n = UsbReadMessage(t->usb, &p->msg); 71 if (n < 0) { 72 D("remote usb: read terminated (message)"); 73 return -1; 74 } 75 if (static_cast<size_t>(n) != sizeof(p->msg) || !check_header(p, t)) { 76 D("remote usb: check_header failed, skip it"); 77 goto err_msg; 78 } 79 if (t->GetConnectionState() == kCsOffline) { 80 // If we read a wrong msg header declaring a large message payload, don't read its payload. 81 // Otherwise we may miss true messages from the device. 82 if (p->msg.command != A_CNXN && p->msg.command != A_AUTH) { 83 goto err_msg; 84 } 85 } 86 if (p->msg.data_length) { 87 n = UsbReadPayload(t->usb, p); 88 if (n < 0) { 89 D("remote usb: terminated (data)"); 90 return -1; 91 } 92 if (static_cast<uint32_t>(n) != p->msg.data_length) { 93 D("remote usb: read payload failed (need %u bytes, give %d bytes), skip it", 94 p->msg.data_length, n); 95 goto err_msg; 96 } 97 } 98 if (!check_data(p)) { 99 D("remote usb: check_data failed, skip it"); 100 goto err_msg; 101 } 102 return 0; 103 104err_msg: 105 p->msg.command = 0; 106 return 0; 107} 108 109#else 110 111// On Android devices, we rely on the kernel to provide buffered read. 112// So we can recover automatically from EOVERFLOW. 113static int remote_read(apacket *p, atransport *t) 114{ 115 if (usb_read(t->usb, &p->msg, sizeof(amessage))) { 116 PLOG(ERROR) << "remote usb: read terminated (message)"; 117 return -1; 118 } 119 120 if (!check_header(p, t)) { 121 LOG(ERROR) << "remote usb: check_header failed"; 122 return -1; 123 } 124 125 if (p->msg.data_length) { 126 if (usb_read(t->usb, p->data, p->msg.data_length)) { 127 PLOG(ERROR) << "remote usb: terminated (data)"; 128 return -1; 129 } 130 } 131 132 if (!check_data(p)) { 133 LOG(ERROR) << "remote usb: check_data failed"; 134 return -1; 135 } 136 137 return 0; 138} 139#endif 140 141static int remote_write(apacket *p, atransport *t) 142{ 143 unsigned size = p->msg.data_length; 144 145 if (usb_write(t->usb, &p->msg, sizeof(amessage))) { 146 PLOG(ERROR) << "remote usb: 1 - write terminated"; 147 return -1; 148 } 149 if (p->msg.data_length == 0) return 0; 150 if (usb_write(t->usb, &p->data, size)) { 151 PLOG(ERROR) << "remote usb: 2 - write terminated"; 152 return -1; 153 } 154 155 return 0; 156} 157 158static void remote_close(atransport* t) { 159 usb_close(t->usb); 160 t->usb = 0; 161} 162 163static void remote_kick(atransport* t) { 164 usb_kick(t->usb); 165} 166 167void init_usb_transport(atransport* t, usb_handle* h) { 168 D("transport: usb"); 169 t->close = remote_close; 170 t->SetKickFunction(remote_kick); 171 t->SetWriteFunction(remote_write); 172 t->read_from_remote = remote_read; 173 t->sync_token = 1; 174 t->type = kTransportUsb; 175 t->usb = h; 176} 177 178int is_adb_interface(int usb_class, int usb_subclass, int usb_protocol) 179{ 180 return (usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS && usb_protocol == ADB_PROTOCOL); 181} 182 183bool should_use_libusb() { 184#if defined(_WIN32) || !ADB_HOST 185 return false; 186#else 187 static bool enable = getenv("ADB_LIBUSB") && strcmp(getenv("ADB_LIBUSB"), "1") == 0; 188 return enable; 189#endif 190} 191