1 //===-- AdbClient.cpp -------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // Other libraries and framework includes 11 #include "AdbClient.h" 12 13 #include "llvm/ADT/STLExtras.h" 14 #include "llvm/ADT/SmallVector.h" 15 #include "llvm/ADT/StringRef.h" 16 #include "llvm/Support/FileUtilities.h" 17 18 #include "lldb/Host/ConnectionFileDescriptor.h" 19 #include "lldb/Host/FileSystem.h" 20 #include "lldb/Host/PosixApi.h" 21 #include "lldb/Utility/DataBuffer.h" 22 #include "lldb/Utility/DataBufferHeap.h" 23 #include "lldb/Utility/DataEncoder.h" 24 #include "lldb/Utility/DataExtractor.h" 25 #include "lldb/Utility/FileSpec.h" 26 #include "lldb/Utility/StreamString.h" 27 #include "lldb/Utility/Timeout.h" 28 29 #include <limits.h> 30 31 #include <algorithm> 32 #include <cstdlib> 33 #include <fstream> 34 #include <sstream> 35 36 // On Windows, transitive dependencies pull in <Windows.h>, which defines a 37 // macro that clashes with a method name. 38 #ifdef SendMessage 39 #undef SendMessage 40 #endif 41 42 using namespace lldb; 43 using namespace lldb_private; 44 using namespace lldb_private::platform_android; 45 using namespace std::chrono; 46 47 namespace { 48 49 const seconds kReadTimeout(20); 50 const char *kOKAY = "OKAY"; 51 const char *kFAIL = "FAIL"; 52 const char *kDATA = "DATA"; 53 const char *kDONE = "DONE"; 54 55 const char *kSEND = "SEND"; 56 const char *kRECV = "RECV"; 57 const char *kSTAT = "STAT"; 58 59 const size_t kSyncPacketLen = 8; 60 // Maximum size of a filesync DATA packet. 61 const size_t kMaxPushData = 2 * 1024; 62 // Default mode for pushed files. 63 const uint32_t kDefaultMode = 0100770; // S_IFREG | S_IRWXU | S_IRWXG 64 65 const char *kSocketNamespaceAbstract = "localabstract"; 66 const char *kSocketNamespaceFileSystem = "localfilesystem"; 67 68 Status ReadAllBytes(Connection &conn, void *buffer, size_t size) { 69 70 Status error; 71 ConnectionStatus status; 72 char *read_buffer = static_cast<char *>(buffer); 73 74 auto now = steady_clock::now(); 75 const auto deadline = now + kReadTimeout; 76 size_t total_read_bytes = 0; 77 while (total_read_bytes < size && now < deadline) { 78 auto read_bytes = 79 conn.Read(read_buffer + total_read_bytes, size - total_read_bytes, 80 duration_cast<microseconds>(deadline - now), status, &error); 81 if (error.Fail()) 82 return error; 83 total_read_bytes += read_bytes; 84 if (status != eConnectionStatusSuccess) 85 break; 86 now = steady_clock::now(); 87 } 88 if (total_read_bytes < size) 89 error = Status( 90 "Unable to read requested number of bytes. Connection status: %d.", 91 status); 92 return error; 93 } 94 95 } // namespace 96 97 Status AdbClient::CreateByDeviceID(const std::string &device_id, 98 AdbClient &adb) { 99 DeviceIDList connect_devices; 100 auto error = adb.GetDevices(connect_devices); 101 if (error.Fail()) 102 return error; 103 104 std::string android_serial; 105 if (!device_id.empty()) 106 android_serial = device_id; 107 else if (const char *env_serial = std::getenv("ANDROID_SERIAL")) 108 android_serial = env_serial; 109 110 if (android_serial.empty()) { 111 if (connect_devices.size() != 1) 112 return Status("Expected a single connected device, got instead %zu - try " 113 "setting 'ANDROID_SERIAL'", 114 connect_devices.size()); 115 adb.SetDeviceID(connect_devices.front()); 116 } else { 117 auto find_it = std::find(connect_devices.begin(), connect_devices.end(), 118 android_serial); 119 if (find_it == connect_devices.end()) 120 return Status("Device \"%s\" not found", android_serial.c_str()); 121 122 adb.SetDeviceID(*find_it); 123 } 124 return error; 125 } 126 127 AdbClient::AdbClient() {} 128 129 AdbClient::AdbClient(const std::string &device_id) : m_device_id(device_id) {} 130 131 AdbClient::~AdbClient() {} 132 133 void AdbClient::SetDeviceID(const std::string &device_id) { 134 m_device_id = device_id; 135 } 136 137 const std::string &AdbClient::GetDeviceID() const { return m_device_id; } 138 139 Status AdbClient::Connect() { 140 Status error; 141 m_conn.reset(new ConnectionFileDescriptor); 142 m_conn->Connect("connect://localhost:5037", &error); 143 144 return error; 145 } 146 147 Status AdbClient::GetDevices(DeviceIDList &device_list) { 148 device_list.clear(); 149 150 auto error = SendMessage("host:devices"); 151 if (error.Fail()) 152 return error; 153 154 error = ReadResponseStatus(); 155 if (error.Fail()) 156 return error; 157 158 std::vector<char> in_buffer; 159 error = ReadMessage(in_buffer); 160 161 llvm::StringRef response(&in_buffer[0], in_buffer.size()); 162 llvm::SmallVector<llvm::StringRef, 4> devices; 163 response.split(devices, "\n", -1, false); 164 165 for (const auto device : devices) 166 device_list.push_back(device.split('\t').first); 167 168 // Force disconnect since ADB closes connection after host:devices response 169 // is sent. 170 m_conn.reset(); 171 return error; 172 } 173 174 Status AdbClient::SetPortForwarding(const uint16_t local_port, 175 const uint16_t remote_port) { 176 char message[48]; 177 snprintf(message, sizeof(message), "forward:tcp:%d;tcp:%d", local_port, 178 remote_port); 179 180 const auto error = SendDeviceMessage(message); 181 if (error.Fail()) 182 return error; 183 184 return ReadResponseStatus(); 185 } 186 187 Status 188 AdbClient::SetPortForwarding(const uint16_t local_port, 189 llvm::StringRef remote_socket_name, 190 const UnixSocketNamespace socket_namespace) { 191 char message[PATH_MAX]; 192 const char *sock_namespace_str = 193 (socket_namespace == UnixSocketNamespaceAbstract) 194 ? kSocketNamespaceAbstract 195 : kSocketNamespaceFileSystem; 196 snprintf(message, sizeof(message), "forward:tcp:%d;%s:%s", local_port, 197 sock_namespace_str, remote_socket_name.str().c_str()); 198 199 const auto error = SendDeviceMessage(message); 200 if (error.Fail()) 201 return error; 202 203 return ReadResponseStatus(); 204 } 205 206 Status AdbClient::DeletePortForwarding(const uint16_t local_port) { 207 char message[32]; 208 snprintf(message, sizeof(message), "killforward:tcp:%d", local_port); 209 210 const auto error = SendDeviceMessage(message); 211 if (error.Fail()) 212 return error; 213 214 return ReadResponseStatus(); 215 } 216 217 Status AdbClient::SendMessage(const std::string &packet, const bool reconnect) { 218 Status error; 219 if (!m_conn || reconnect) { 220 error = Connect(); 221 if (error.Fail()) 222 return error; 223 } 224 225 char length_buffer[5]; 226 snprintf(length_buffer, sizeof(length_buffer), "%04x", 227 static_cast<int>(packet.size())); 228 229 ConnectionStatus status; 230 231 m_conn->Write(length_buffer, 4, status, &error); 232 if (error.Fail()) 233 return error; 234 235 m_conn->Write(packet.c_str(), packet.size(), status, &error); 236 return error; 237 } 238 239 Status AdbClient::SendDeviceMessage(const std::string &packet) { 240 std::ostringstream msg; 241 msg << "host-serial:" << m_device_id << ":" << packet; 242 return SendMessage(msg.str()); 243 } 244 245 Status AdbClient::ReadMessage(std::vector<char> &message) { 246 message.clear(); 247 248 char buffer[5]; 249 buffer[4] = 0; 250 251 auto error = ReadAllBytes(buffer, 4); 252 if (error.Fail()) 253 return error; 254 255 unsigned int packet_len = 0; 256 sscanf(buffer, "%x", &packet_len); 257 258 message.resize(packet_len, 0); 259 error = ReadAllBytes(&message[0], packet_len); 260 if (error.Fail()) 261 message.clear(); 262 263 return error; 264 } 265 266 Status AdbClient::ReadMessageStream(std::vector<char> &message, 267 milliseconds timeout) { 268 auto start = steady_clock::now(); 269 message.clear(); 270 271 Status error; 272 lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess; 273 char buffer[1024]; 274 while (error.Success() && status == lldb::eConnectionStatusSuccess) { 275 auto end = steady_clock::now(); 276 auto elapsed = end - start; 277 if (elapsed >= timeout) 278 return Status("Timed out"); 279 280 size_t n = m_conn->Read(buffer, sizeof(buffer), 281 duration_cast<microseconds>(timeout - elapsed), 282 status, &error); 283 if (n > 0) 284 message.insert(message.end(), &buffer[0], &buffer[n]); 285 } 286 return error; 287 } 288 289 Status AdbClient::ReadResponseStatus() { 290 char response_id[5]; 291 292 static const size_t packet_len = 4; 293 response_id[packet_len] = 0; 294 295 auto error = ReadAllBytes(response_id, packet_len); 296 if (error.Fail()) 297 return error; 298 299 if (strncmp(response_id, kOKAY, packet_len) != 0) 300 return GetResponseError(response_id); 301 302 return error; 303 } 304 305 Status AdbClient::GetResponseError(const char *response_id) { 306 if (strcmp(response_id, kFAIL) != 0) 307 return Status("Got unexpected response id from adb: \"%s\"", response_id); 308 309 std::vector<char> error_message; 310 auto error = ReadMessage(error_message); 311 if (error.Success()) 312 error.SetErrorString( 313 std::string(&error_message[0], error_message.size()).c_str()); 314 315 return error; 316 } 317 318 Status AdbClient::SwitchDeviceTransport() { 319 std::ostringstream msg; 320 msg << "host:transport:" << m_device_id; 321 322 auto error = SendMessage(msg.str()); 323 if (error.Fail()) 324 return error; 325 326 return ReadResponseStatus(); 327 } 328 329 Status AdbClient::StartSync() { 330 auto error = SwitchDeviceTransport(); 331 if (error.Fail()) 332 return Status("Failed to switch to device transport: %s", 333 error.AsCString()); 334 335 error = Sync(); 336 if (error.Fail()) 337 return Status("Sync failed: %s", error.AsCString()); 338 339 return error; 340 } 341 342 Status AdbClient::Sync() { 343 auto error = SendMessage("sync:", false); 344 if (error.Fail()) 345 return error; 346 347 return ReadResponseStatus(); 348 } 349 350 Status AdbClient::ReadAllBytes(void *buffer, size_t size) { 351 return ::ReadAllBytes(*m_conn, buffer, size); 352 } 353 354 Status AdbClient::internalShell(const char *command, milliseconds timeout, 355 std::vector<char> &output_buf) { 356 output_buf.clear(); 357 358 auto error = SwitchDeviceTransport(); 359 if (error.Fail()) 360 return Status("Failed to switch to device transport: %s", 361 error.AsCString()); 362 363 StreamString adb_command; 364 adb_command.Printf("shell:%s", command); 365 error = SendMessage(adb_command.GetString(), false); 366 if (error.Fail()) 367 return error; 368 369 error = ReadResponseStatus(); 370 if (error.Fail()) 371 return error; 372 373 error = ReadMessageStream(output_buf, timeout); 374 if (error.Fail()) 375 return error; 376 377 // ADB doesn't propagate return code of shell execution - if 378 // output starts with /system/bin/sh: most likely command failed. 379 static const char *kShellPrefix = "/system/bin/sh:"; 380 if (output_buf.size() > strlen(kShellPrefix)) { 381 if (!memcmp(&output_buf[0], kShellPrefix, strlen(kShellPrefix))) 382 return Status("Shell command %s failed: %s", command, 383 std::string(output_buf.begin(), output_buf.end()).c_str()); 384 } 385 386 return Status(); 387 } 388 389 Status AdbClient::Shell(const char *command, milliseconds timeout, 390 std::string *output) { 391 std::vector<char> output_buffer; 392 auto error = internalShell(command, timeout, output_buffer); 393 if (error.Fail()) 394 return error; 395 396 if (output) 397 output->assign(output_buffer.begin(), output_buffer.end()); 398 return error; 399 } 400 401 Status AdbClient::ShellToFile(const char *command, milliseconds timeout, 402 const FileSpec &output_file_spec) { 403 std::vector<char> output_buffer; 404 auto error = internalShell(command, timeout, output_buffer); 405 if (error.Fail()) 406 return error; 407 408 const auto output_filename = output_file_spec.GetPath(); 409 std::error_code EC; 410 llvm::raw_fd_ostream dst(output_filename, EC, llvm::sys::fs::F_None); 411 if (EC) 412 return Status("Unable to open local file %s", output_filename.c_str()); 413 414 dst.write(&output_buffer[0], output_buffer.size()); 415 dst.close(); 416 if (dst.has_error()) 417 return Status("Failed to write file %s", output_filename.c_str()); 418 return Status(); 419 } 420 421 std::unique_ptr<AdbClient::SyncService> 422 AdbClient::GetSyncService(Status &error) { 423 std::unique_ptr<SyncService> sync_service; 424 error = StartSync(); 425 if (error.Success()) 426 sync_service.reset(new SyncService(std::move(m_conn))); 427 428 return sync_service; 429 } 430 431 Status AdbClient::SyncService::internalPullFile(const FileSpec &remote_file, 432 const FileSpec &local_file) { 433 const auto local_file_path = local_file.GetPath(); 434 llvm::FileRemover local_file_remover(local_file_path); 435 436 std::error_code EC; 437 llvm::raw_fd_ostream dst(local_file_path, EC, llvm::sys::fs::F_None); 438 if (EC) 439 return Status("Unable to open local file %s", local_file_path.c_str()); 440 441 const auto remote_file_path = remote_file.GetPath(false); 442 auto error = SendSyncRequest(kRECV, remote_file_path.length(), 443 remote_file_path.c_str()); 444 if (error.Fail()) 445 return error; 446 447 std::vector<char> chunk; 448 bool eof = false; 449 while (!eof) { 450 error = PullFileChunk(chunk, eof); 451 if (error.Fail()) 452 return error; 453 if (!eof) 454 dst.write(&chunk[0], chunk.size()); 455 } 456 dst.close(); 457 if (dst.has_error()) 458 return Status("Failed to write file %s", local_file_path.c_str()); 459 460 local_file_remover.releaseFile(); 461 return error; 462 } 463 464 Status AdbClient::SyncService::internalPushFile(const FileSpec &local_file, 465 const FileSpec &remote_file) { 466 const auto local_file_path(local_file.GetPath()); 467 std::ifstream src(local_file_path.c_str(), std::ios::in | std::ios::binary); 468 if (!src.is_open()) 469 return Status("Unable to open local file %s", local_file_path.c_str()); 470 471 std::stringstream file_description; 472 file_description << remote_file.GetPath(false).c_str() << "," << kDefaultMode; 473 std::string file_description_str = file_description.str(); 474 auto error = SendSyncRequest(kSEND, file_description_str.length(), 475 file_description_str.c_str()); 476 if (error.Fail()) 477 return error; 478 479 char chunk[kMaxPushData]; 480 while (!src.eof() && !src.read(chunk, kMaxPushData).bad()) { 481 size_t chunk_size = src.gcount(); 482 error = SendSyncRequest(kDATA, chunk_size, chunk); 483 if (error.Fail()) 484 return Status("Failed to send file chunk: %s", error.AsCString()); 485 } 486 error = SendSyncRequest( 487 kDONE, llvm::sys::toTimeT(FileSystem::GetModificationTime(local_file)), 488 nullptr); 489 if (error.Fail()) 490 return error; 491 492 std::string response_id; 493 uint32_t data_len; 494 error = ReadSyncHeader(response_id, data_len); 495 if (error.Fail()) 496 return Status("Failed to read DONE response: %s", error.AsCString()); 497 if (response_id == kFAIL) { 498 std::string error_message(data_len, 0); 499 error = ReadAllBytes(&error_message[0], data_len); 500 if (error.Fail()) 501 return Status("Failed to read DONE error message: %s", error.AsCString()); 502 return Status("Failed to push file: %s", error_message.c_str()); 503 } else if (response_id != kOKAY) 504 return Status("Got unexpected DONE response: %s", response_id.c_str()); 505 506 // If there was an error reading the source file, finish the adb file 507 // transfer first so that adb isn't expecting any more data. 508 if (src.bad()) 509 return Status("Failed read on %s", local_file_path.c_str()); 510 return error; 511 } 512 513 Status AdbClient::SyncService::internalStat(const FileSpec &remote_file, 514 uint32_t &mode, uint32_t &size, 515 uint32_t &mtime) { 516 const std::string remote_file_path(remote_file.GetPath(false)); 517 auto error = SendSyncRequest(kSTAT, remote_file_path.length(), 518 remote_file_path.c_str()); 519 if (error.Fail()) 520 return Status("Failed to send request: %s", error.AsCString()); 521 522 static const size_t stat_len = strlen(kSTAT); 523 static const size_t response_len = stat_len + (sizeof(uint32_t) * 3); 524 525 std::vector<char> buffer(response_len); 526 error = ReadAllBytes(&buffer[0], buffer.size()); 527 if (error.Fail()) 528 return Status("Failed to read response: %s", error.AsCString()); 529 530 DataExtractor extractor(&buffer[0], buffer.size(), eByteOrderLittle, 531 sizeof(void *)); 532 offset_t offset = 0; 533 534 const void *command = extractor.GetData(&offset, stat_len); 535 if (!command) 536 return Status("Failed to get response command"); 537 const char *command_str = static_cast<const char *>(command); 538 if (strncmp(command_str, kSTAT, stat_len)) 539 return Status("Got invalid stat command: %s", command_str); 540 541 mode = extractor.GetU32(&offset); 542 size = extractor.GetU32(&offset); 543 mtime = extractor.GetU32(&offset); 544 return Status(); 545 } 546 547 Status AdbClient::SyncService::PullFile(const FileSpec &remote_file, 548 const FileSpec &local_file) { 549 return executeCommand([this, &remote_file, &local_file]() { 550 return internalPullFile(remote_file, local_file); 551 }); 552 } 553 554 Status AdbClient::SyncService::PushFile(const FileSpec &local_file, 555 const FileSpec &remote_file) { 556 return executeCommand([this, &local_file, &remote_file]() { 557 return internalPushFile(local_file, remote_file); 558 }); 559 } 560 561 Status AdbClient::SyncService::Stat(const FileSpec &remote_file, uint32_t &mode, 562 uint32_t &size, uint32_t &mtime) { 563 return executeCommand([this, &remote_file, &mode, &size, &mtime]() { 564 return internalStat(remote_file, mode, size, mtime); 565 }); 566 } 567 568 bool AdbClient::SyncService::IsConnected() const { 569 return m_conn && m_conn->IsConnected(); 570 } 571 572 AdbClient::SyncService::SyncService(std::unique_ptr<Connection> &&conn) 573 : m_conn(std::move(conn)) {} 574 575 Status 576 AdbClient::SyncService::executeCommand(const std::function<Status()> &cmd) { 577 if (!m_conn) 578 return Status("SyncService is disconnected"); 579 580 const auto error = cmd(); 581 if (error.Fail()) 582 m_conn.reset(); 583 584 return error; 585 } 586 587 AdbClient::SyncService::~SyncService() {} 588 589 Status AdbClient::SyncService::SendSyncRequest(const char *request_id, 590 const uint32_t data_len, 591 const void *data) { 592 const DataBufferSP data_sp(new DataBufferHeap(kSyncPacketLen, 0)); 593 DataEncoder encoder(data_sp, eByteOrderLittle, sizeof(void *)); 594 auto offset = encoder.PutData(0, request_id, strlen(request_id)); 595 encoder.PutU32(offset, data_len); 596 597 Status error; 598 ConnectionStatus status; 599 m_conn->Write(data_sp->GetBytes(), kSyncPacketLen, status, &error); 600 if (error.Fail()) 601 return error; 602 603 if (data) 604 m_conn->Write(data, data_len, status, &error); 605 return error; 606 } 607 608 Status AdbClient::SyncService::ReadSyncHeader(std::string &response_id, 609 uint32_t &data_len) { 610 char buffer[kSyncPacketLen]; 611 612 auto error = ReadAllBytes(buffer, kSyncPacketLen); 613 if (error.Success()) { 614 response_id.assign(&buffer[0], 4); 615 DataExtractor extractor(&buffer[4], 4, eByteOrderLittle, sizeof(void *)); 616 offset_t offset = 0; 617 data_len = extractor.GetU32(&offset); 618 } 619 620 return error; 621 } 622 623 Status AdbClient::SyncService::PullFileChunk(std::vector<char> &buffer, 624 bool &eof) { 625 buffer.clear(); 626 627 std::string response_id; 628 uint32_t data_len; 629 auto error = ReadSyncHeader(response_id, data_len); 630 if (error.Fail()) 631 return error; 632 633 if (response_id == kDATA) { 634 buffer.resize(data_len, 0); 635 error = ReadAllBytes(&buffer[0], data_len); 636 if (error.Fail()) 637 buffer.clear(); 638 } else if (response_id == kDONE) { 639 eof = true; 640 } else if (response_id == kFAIL) { 641 std::string error_message(data_len, 0); 642 error = ReadAllBytes(&error_message[0], data_len); 643 if (error.Fail()) 644 return Status("Failed to read pull error message: %s", error.AsCString()); 645 return Status("Failed to pull file: %s", error_message.c_str()); 646 } else 647 return Status("Pull failed with unknown response: %s", response_id.c_str()); 648 649 return Status(); 650 } 651 652 Status AdbClient::SyncService::ReadAllBytes(void *buffer, size_t size) { 653 return ::ReadAllBytes(*m_conn, buffer, size); 654 } 655