1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/devtools/adb/android_usb_device.h" 6 7#include <set> 8 9#include "base/base64.h" 10#include "base/lazy_instance.h" 11#include "base/message_loop/message_loop.h" 12#include "base/stl_util.h" 13#include "base/strings/string_util.h" 14#include "base/strings/stringprintf.h" 15#include "chrome/browser/devtools/adb/android_rsa.h" 16#include "chrome/browser/devtools/adb/android_usb_socket.h" 17#include "chrome/browser/usb/usb_device.h" 18#include "chrome/browser/usb/usb_interface.h" 19#include "chrome/browser/usb/usb_service.h" 20#include "content/public/browser/browser_thread.h" 21#include "crypto/rsa_private_key.h" 22#include "net/base/ip_endpoint.h" 23#include "net/base/net_errors.h" 24#include "net/socket/stream_socket.h" 25 26namespace { 27 28const size_t kHeaderSize = 24; 29 30const int kAdbClass = 0xff; 31const int kAdbSubclass = 0x42; 32const int kAdbProtocol = 0x1; 33 34const int kUsbTimeout = 0; 35 36const uint32 kMaxPayload = 4096; 37const uint32 kVersion = 0x01000000; 38 39static const char kHostConnectMessage[] = "host::"; 40 41using content::BrowserThread; 42 43typedef std::vector<scoped_refptr<UsbDevice> > UsbDevices; 44 45base::LazyInstance<AndroidUsbDevices>::Leaky g_devices = 46 LAZY_INSTANCE_INITIALIZER; 47 48static scoped_refptr<AndroidUsbDevice> ClaimInterface( 49 crypto::RSAPrivateKey* rsa_key, 50 scoped_refptr<UsbDeviceHandle> usb_device, 51 const UsbInterface* interface, 52 int interface_id) { 53 if (interface->GetNumAltSettings() == 0) 54 return NULL; 55 56 scoped_refptr<const UsbInterfaceDescriptor> idesc = 57 interface->GetAltSetting(0).get(); 58 59 if (idesc->GetInterfaceClass() != kAdbClass || 60 idesc->GetInterfaceSubclass() != kAdbSubclass || 61 idesc->GetInterfaceProtocol() != kAdbProtocol || 62 idesc->GetNumEndpoints() != 2) { 63 return NULL; 64 } 65 66 int inbound_address = 0; 67 int outbound_address = 0; 68 int zero_mask = 0; 69 70 for (size_t i = 0; i < idesc->GetNumEndpoints(); ++i) { 71 scoped_refptr<const UsbEndpointDescriptor> edesc = 72 idesc->GetEndpoint(i).get(); 73 if (edesc->GetTransferType() != USB_TRANSFER_BULK) 74 continue; 75 if (edesc->GetDirection() == USB_DIRECTION_INBOUND) 76 inbound_address = edesc->GetAddress(); 77 else 78 outbound_address = edesc->GetAddress(); 79 zero_mask = edesc->GetMaximumPacketSize() - 1; 80 } 81 82 if (inbound_address == 0 || outbound_address == 0) 83 return NULL; 84 85 if (!usb_device->ClaimInterface(interface_id)) 86 return NULL; 87 88 base::string16 serial; 89 if (!usb_device->GetSerial(&serial) || serial.empty()) 90 return NULL; 91 92 return new AndroidUsbDevice(rsa_key, usb_device, UTF16ToASCII(serial), 93 inbound_address, outbound_address, zero_mask); 94} 95 96static uint32 Checksum(const std::string& data) { 97 unsigned char* x = (unsigned char*)data.data(); 98 int count = data.length(); 99 uint32 sum = 0; 100 while (count-- > 0) 101 sum += *x++; 102 return sum; 103} 104 105static void DumpMessage(bool outgoing, const char* data, size_t length) { 106#if 0 107 std::string result = ""; 108 if (length == kHeaderSize) { 109 for (size_t i = 0; i < 24; ++i) { 110 result += base::StringPrintf("%02x", 111 data[i] > 0 ? data[i] : (data[i] + 0x100) & 0xFF); 112 if ((i + 1) % 4 == 0) 113 result += " "; 114 } 115 for (size_t i = 0; i < 24; ++i) { 116 if (data[i] >= 0x20 && data[i] <= 0x7E) 117 result += data[i]; 118 else 119 result += "."; 120 } 121 } else { 122 result = base::StringPrintf("%d: ", (int)length); 123 for (size_t i = 0; i < length; ++i) { 124 if (data[i] >= 0x20 && data[i] <= 0x7E) 125 result += data[i]; 126 else 127 result += "."; 128 } 129 } 130 LOG(ERROR) << (outgoing ? "[out] " : "[ in] ") << result; 131#endif // 0 132} 133 134} // namespace 135 136AdbMessage::AdbMessage(uint32 command, 137 uint32 arg0, 138 uint32 arg1, 139 const std::string& body) 140 : command(command), 141 arg0(arg0), 142 arg1(arg1), 143 body(body) { 144} 145 146AdbMessage::~AdbMessage() { 147} 148 149static void EnumerateOnFileThread(crypto::RSAPrivateKey* rsa_key, 150 AndroidUsbDevices* result) { 151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 152 153 UsbService* service = UsbService::GetInstance(); 154 AndroidUsbDevices& devices = g_devices.Get(); 155 156 UsbDevices usb_devices; 157 service->GetDevices(&usb_devices); 158 159 // GC Android devices with no actual usb device. 160 AndroidUsbDevices::iterator it = devices.begin(); 161 std::set<UsbDevice*> claimed_devices; 162 while (it != devices.end()) { 163 bool found_device = false; 164 for (UsbDevices::iterator it2 = usb_devices.begin(); 165 it2 != usb_devices.end() && !found_device; ++it2) { 166 UsbDevice* usb_device = it2->get(); 167 AndroidUsbDevice* device = it->get(); 168 if (usb_device == device->usb_device()->device()) { 169 found_device = true; 170 claimed_devices.insert(usb_device); 171 } 172 } 173 174 if (!found_device) 175 it = devices.erase(it); 176 else 177 ++it; 178 } 179 180 // Add new devices. 181 for (UsbDevices::iterator it = usb_devices.begin(); it != usb_devices.end(); 182 ++it) { 183 if (ContainsKey(claimed_devices, it->get())) 184 continue; 185 186 scoped_refptr<UsbConfigDescriptor> config = new UsbConfigDescriptor(); 187 bool success = (*it)->ListInterfaces(config.get()); 188 if (!success) 189 continue; 190 191 scoped_refptr<UsbDeviceHandle> usb_device = (*it)->Open(); 192 if (!usb_device) 193 continue; 194 195 bool claimed = false; 196 for (size_t j = 0; j < config->GetNumInterfaces(); ++j) { 197 scoped_refptr<AndroidUsbDevice> device = 198 ClaimInterface(rsa_key, usb_device, config->GetInterface(j), j); 199 if (device.get()) { 200 devices.push_back(device); 201 claimed = true; 202 } 203 } 204 if (!claimed) 205 usb_device->Close(); 206 } 207 208 *result = devices; 209} 210 211static void InitDevicesOnCallerThread( 212 AndroidUsbDevices* devices, 213 const AndroidUsbDevicesCallback& callback) { 214 for (AndroidUsbDevices::iterator it = devices->begin(); it != devices->end(); 215 ++it) { 216 (*it)->InitOnCallerThread(); 217 } 218 callback.Run(*devices); 219 delete devices; 220} 221 222// static 223void AndroidUsbDevice::Enumerate(crypto::RSAPrivateKey* rsa_key, 224 const AndroidUsbDevicesCallback& callback) { 225 AndroidUsbDevices* devices = new AndroidUsbDevices(); 226 BrowserThread::PostTaskAndReply( 227 BrowserThread::FILE, FROM_HERE, 228 base::Bind(&EnumerateOnFileThread, rsa_key, devices), 229 base::Bind(&InitDevicesOnCallerThread, devices, callback)); 230} 231 232AndroidUsbDevice::AndroidUsbDevice(crypto::RSAPrivateKey* rsa_key, 233 scoped_refptr<UsbDeviceHandle> usb_device, 234 const std::string& serial, 235 int inbound_address, 236 int outbound_address, 237 int zero_mask) 238 : message_loop_(NULL), 239 rsa_key_(rsa_key->Copy()), 240 usb_device_(usb_device), 241 serial_(serial), 242 inbound_address_(inbound_address), 243 outbound_address_(outbound_address), 244 zero_mask_(zero_mask), 245 is_connected_(false), 246 signature_sent_(false), 247 last_socket_id_(256), 248 terminated_(false) { 249} 250 251void AndroidUsbDevice::InitOnCallerThread() { 252 if (message_loop_) 253 return; 254 message_loop_ = base::MessageLoop::current(); 255 Queue(new AdbMessage(AdbMessage::kCommandCNXN, kVersion, kMaxPayload, 256 kHostConnectMessage)); 257 ReadHeader(true); 258} 259 260net::StreamSocket* AndroidUsbDevice::CreateSocket(const std::string& command) { 261 uint32 socket_id = ++last_socket_id_; 262 sockets_[socket_id] = new AndroidUsbSocket(this, socket_id, command, 263 base::Bind(&AndroidUsbDevice::SocketDeleted, this)); 264 return sockets_[socket_id]; 265} 266 267void AndroidUsbDevice::Send(uint32 command, 268 uint32 arg0, 269 uint32 arg1, 270 const std::string& body) { 271 scoped_refptr<AdbMessage> m = new AdbMessage(command, arg0, arg1, body); 272 // Delay open request if not yet connected. 273 if (!is_connected_) { 274 pending_messages_.push_back(m); 275 return; 276 } 277 Queue(m); 278} 279 280AndroidUsbDevice::~AndroidUsbDevice() { 281 Terminate(); 282} 283 284void AndroidUsbDevice::Queue(scoped_refptr<AdbMessage> message) { 285 // Queue header. 286 std::vector<uint32> header; 287 header.push_back(message->command); 288 header.push_back(message->arg0); 289 header.push_back(message->arg1); 290 bool append_zero = true; 291 if (message->body.empty()) 292 append_zero = false; 293 if (message->command == AdbMessage::kCommandAUTH && 294 message->arg0 == AdbMessage::kAuthSignature) 295 append_zero = false; 296 if (message->command == AdbMessage::kCommandWRTE) 297 append_zero = false; 298 299 size_t body_length = message->body.length() + (append_zero ? 1 : 0); 300 header.push_back(body_length); 301 header.push_back(Checksum(message->body)); 302 header.push_back(message->command ^ 0xffffffff); 303 scoped_refptr<net::IOBuffer> header_buffer = new net::IOBuffer(kHeaderSize); 304 memcpy(header_buffer.get()->data(), &header[0], kHeaderSize); 305 outgoing_queue_.push(std::make_pair(header_buffer, kHeaderSize)); 306 307 // Queue body. 308 if (!message->body.empty()) { 309 scoped_refptr<net::IOBuffer> body_buffer = new net::IOBuffer(body_length); 310 memcpy(body_buffer->data(), message->body.data(), message->body.length()); 311 if (append_zero) 312 body_buffer->data()[body_length - 1] = 0; 313 outgoing_queue_.push(std::make_pair(body_buffer, body_length)); 314 if (zero_mask_ && (body_length & zero_mask_) == 0) { 315 // Send a zero length packet. 316 outgoing_queue_.push(std::make_pair(body_buffer, 0)); 317 } 318 } 319 ProcessOutgoing(); 320} 321 322void AndroidUsbDevice::ProcessOutgoing() { 323 if (outgoing_queue_.empty() || terminated_) 324 return; 325 326 BulkMessage message = outgoing_queue_.front(); 327 outgoing_queue_.pop(); 328 DumpMessage(true, message.first->data(), message.second); 329 usb_device_->BulkTransfer(USB_DIRECTION_OUTBOUND, outbound_address_, 330 message.first, message.second, kUsbTimeout, 331 base::Bind(&AndroidUsbDevice::OutgoingMessageSent, this)); 332} 333 334void AndroidUsbDevice::OutgoingMessageSent(UsbTransferStatus status, 335 scoped_refptr<net::IOBuffer> buffer, 336 size_t result) { 337 if (status != USB_TRANSFER_COMPLETED) 338 return; 339 message_loop_->PostTask(FROM_HERE, 340 base::Bind(&AndroidUsbDevice::ProcessOutgoing, 341 this)); 342} 343 344void AndroidUsbDevice::ReadHeader(bool initial) { 345 if (terminated_) 346 return; 347 if (!initial && HasOneRef()) 348 return; // Stop polling. 349 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kHeaderSize); 350 usb_device_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_, 351 buffer, kHeaderSize, kUsbTimeout, 352 base::Bind(&AndroidUsbDevice::ParseHeader, this)); 353} 354 355void AndroidUsbDevice::ParseHeader(UsbTransferStatus status, 356 scoped_refptr<net::IOBuffer> buffer, 357 size_t result) { 358 if (status == USB_TRANSFER_TIMEOUT) { 359 message_loop_->PostTask(FROM_HERE, 360 base::Bind(&AndroidUsbDevice::ReadHeader, this, 361 false)); 362 return; 363 } 364 365 if (status != USB_TRANSFER_COMPLETED || result != kHeaderSize) { 366 TransferError(status); 367 return; 368 } 369 370 DumpMessage(false, buffer->data(), result); 371 std::vector<uint32> header(6); 372 memcpy(&header[0], buffer->data(), result); 373 scoped_refptr<AdbMessage> message = 374 new AdbMessage(header[0], header[1], header[2], ""); 375 uint32 data_length = header[3]; 376 uint32 data_check = header[4]; 377 uint32 magic = header[5]; 378 if ((message->command ^ 0xffffffff) != magic) { 379 TransferError(USB_TRANSFER_ERROR); 380 return; 381 } 382 383 if (data_length == 0) { 384 message_loop_->PostTask(FROM_HERE, 385 base::Bind(&AndroidUsbDevice::HandleIncoming, this, 386 message)); 387 return; 388 } 389 390 message_loop_->PostTask(FROM_HERE, 391 base::Bind(&AndroidUsbDevice::ReadBody, this, 392 message, data_length, data_check)); 393} 394 395void AndroidUsbDevice::ReadBody(scoped_refptr<AdbMessage> message, 396 uint32 data_length, 397 uint32 data_check) { 398 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(data_length); 399 usb_device_->BulkTransfer(USB_DIRECTION_INBOUND, inbound_address_, 400 buffer, data_length, kUsbTimeout, 401 base::Bind(&AndroidUsbDevice::ParseBody, this, message, data_length, 402 data_check)); 403} 404 405void AndroidUsbDevice::ParseBody(scoped_refptr<AdbMessage> message, 406 uint32 data_length, 407 uint32 data_check, 408 UsbTransferStatus status, 409 scoped_refptr<net::IOBuffer> buffer, 410 size_t result) { 411 if (status == USB_TRANSFER_TIMEOUT) { 412 message_loop_->PostTask(FROM_HERE, 413 base::Bind(&AndroidUsbDevice::ReadBody, this, 414 message, data_length, data_check)); 415 return; 416 } 417 418 if (status != USB_TRANSFER_COMPLETED || 419 static_cast<uint32>(result) != data_length) { 420 TransferError(status); 421 return; 422 } 423 424 DumpMessage(false, buffer->data(), data_length); 425 message->body = std::string(buffer->data(), result); 426 if (Checksum(message->body) != data_check) { 427 TransferError(USB_TRANSFER_ERROR); 428 return; 429 } 430 431 message_loop_->PostTask(FROM_HERE, 432 base::Bind(&AndroidUsbDevice::HandleIncoming, this, 433 message)); 434} 435 436void AndroidUsbDevice::HandleIncoming(scoped_refptr<AdbMessage> message) { 437 switch (message->command) { 438 case AdbMessage::kCommandAUTH: 439 { 440 DCHECK_EQ(message->arg0, static_cast<uint32>(AdbMessage::kAuthToken)); 441 if (signature_sent_) { 442 Queue(new AdbMessage(AdbMessage::kCommandAUTH, 443 AdbMessage::kAuthRSAPublicKey, 0, 444 AndroidRSAPublicKey(rsa_key_.get()))); 445 } else { 446 signature_sent_ = true; 447 std::string signature = AndroidRSASign(rsa_key_.get(), message->body); 448 if (!signature.empty()) { 449 Queue(new AdbMessage(AdbMessage::kCommandAUTH, 450 AdbMessage::kAuthSignature, 0, 451 signature)); 452 } else { 453 Queue(new AdbMessage(AdbMessage::kCommandAUTH, 454 AdbMessage::kAuthRSAPublicKey, 0, 455 AndroidRSAPublicKey(rsa_key_.get()))); 456 } 457 } 458 } 459 break; 460 case AdbMessage::kCommandCNXN: 461 { 462 is_connected_ = true; 463 PendingMessages pending; 464 pending.swap(pending_messages_); 465 for (PendingMessages::iterator it = pending.begin(); 466 it != pending.end(); ++it) { 467 Queue(*it); 468 } 469 } 470 break; 471 case AdbMessage::kCommandOKAY: 472 case AdbMessage::kCommandWRTE: 473 case AdbMessage::kCommandCLSE: 474 { 475 AndroidUsbSockets::iterator it = sockets_.find(message->arg1); 476 if (it != sockets_.end()) 477 it->second->HandleIncoming(message); 478 } 479 break; 480 default: 481 break; 482 } 483 ReadHeader(false); 484} 485 486void AndroidUsbDevice::TransferError(UsbTransferStatus status) { 487 message_loop_->PostTask(FROM_HERE, 488 base::Bind(&AndroidUsbDevice::Terminate, 489 this)); 490} 491 492void AndroidUsbDevice::Terminate() { 493 if (terminated_) 494 return; 495 496 terminated_ = true; 497 498 // Iterate over copy. 499 AndroidUsbSockets sockets(sockets_); 500 for (AndroidUsbSockets::iterator it = sockets.begin(); 501 it != sockets.end(); ++it) { 502 it->second->Terminated(); 503 } 504 505 usb_device_->ReleaseInterface(1); 506 usb_device_->Close(); 507} 508 509void AndroidUsbDevice::SocketDeleted(uint32 socket_id) { 510 sockets_.erase(socket_id); 511} 512