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