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(8); 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 Error ReadAllBytes(Connection &conn, void *buffer, size_t size) { 69 70 Error 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 = Error( 90 "Unable to read requested number of bytes. Connection status: %d.", 91 status); 92 return error; 93 } 94 95 } // namespace 96 97 Error 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 Error("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 Error("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 Error AdbClient::Connect() { 140 Error error; 141 m_conn.reset(new ConnectionFileDescriptor); 142 m_conn->Connect("connect://localhost:5037", &error); 143 144 return error; 145 } 146 147 Error 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 169 // response is sent. 170 m_conn.reset(); 171 return error; 172 } 173 174 Error 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 Error AdbClient::SetPortForwarding(const uint16_t local_port, 188 llvm::StringRef remote_socket_name, 189 const UnixSocketNamespace socket_namespace) { 190 char message[PATH_MAX]; 191 const char *sock_namespace_str = 192 (socket_namespace == UnixSocketNamespaceAbstract) 193 ? kSocketNamespaceAbstract 194 : kSocketNamespaceFileSystem; 195 snprintf(message, sizeof(message), "forward:tcp:%d;%s:%s", local_port, 196 sock_namespace_str, remote_socket_name.str().c_str()); 197 198 const auto error = SendDeviceMessage(message); 199 if (error.Fail()) 200 return error; 201 202 return ReadResponseStatus(); 203 } 204 205 Error AdbClient::DeletePortForwarding(const uint16_t local_port) { 206 char message[32]; 207 snprintf(message, sizeof(message), "killforward:tcp:%d", local_port); 208 209 const auto error = SendDeviceMessage(message); 210 if (error.Fail()) 211 return error; 212 213 return ReadResponseStatus(); 214 } 215 216 Error AdbClient::SendMessage(const std::string &packet, const bool reconnect) { 217 Error error; 218 if (!m_conn || reconnect) { 219 error = Connect(); 220 if (error.Fail()) 221 return error; 222 } 223 224 char length_buffer[5]; 225 snprintf(length_buffer, sizeof(length_buffer), "%04x", 226 static_cast<int>(packet.size())); 227 228 ConnectionStatus status; 229 230 m_conn->Write(length_buffer, 4, status, &error); 231 if (error.Fail()) 232 return error; 233 234 m_conn->Write(packet.c_str(), packet.size(), status, &error); 235 return error; 236 } 237 238 Error AdbClient::SendDeviceMessage(const std::string &packet) { 239 std::ostringstream msg; 240 msg << "host-serial:" << m_device_id << ":" << packet; 241 return SendMessage(msg.str()); 242 } 243 244 Error AdbClient::ReadMessage(std::vector<char> &message) { 245 message.clear(); 246 247 char buffer[5]; 248 buffer[4] = 0; 249 250 auto error = ReadAllBytes(buffer, 4); 251 if (error.Fail()) 252 return error; 253 254 unsigned int packet_len = 0; 255 sscanf(buffer, "%x", &packet_len); 256 257 message.resize(packet_len, 0); 258 error = ReadAllBytes(&message[0], packet_len); 259 if (error.Fail()) 260 message.clear(); 261 262 return error; 263 } 264 265 Error AdbClient::ReadMessageStream(std::vector<char> &message, 266 milliseconds timeout) { 267 auto start = steady_clock::now(); 268 message.clear(); 269 270 Error error; 271 lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess; 272 char buffer[1024]; 273 while (error.Success() && status == lldb::eConnectionStatusSuccess) { 274 auto end = steady_clock::now(); 275 auto elapsed = end - start; 276 if (elapsed >= timeout) 277 return Error("Timed out"); 278 279 size_t n = m_conn->Read(buffer, sizeof(buffer), 280 duration_cast<microseconds>(timeout - elapsed), 281 status, &error); 282 if (n > 0) 283 message.insert(message.end(), &buffer[0], &buffer[n]); 284 } 285 return error; 286 } 287 288 Error AdbClient::ReadResponseStatus() { 289 char response_id[5]; 290 291 static const size_t packet_len = 4; 292 response_id[packet_len] = 0; 293 294 auto error = ReadAllBytes(response_id, packet_len); 295 if (error.Fail()) 296 return error; 297 298 if (strncmp(response_id, kOKAY, packet_len) != 0) 299 return GetResponseError(response_id); 300 301 return error; 302 } 303 304 Error AdbClient::GetResponseError(const char *response_id) { 305 if (strcmp(response_id, kFAIL) != 0) 306 return Error("Got unexpected response id from adb: \"%s\"", response_id); 307 308 std::vector<char> error_message; 309 auto error = ReadMessage(error_message); 310 if (error.Success()) 311 error.SetErrorString( 312 std::string(&error_message[0], error_message.size()).c_str()); 313 314 return error; 315 } 316 317 Error AdbClient::SwitchDeviceTransport() { 318 std::ostringstream msg; 319 msg << "host:transport:" << m_device_id; 320 321 auto error = SendMessage(msg.str()); 322 if (error.Fail()) 323 return error; 324 325 return ReadResponseStatus(); 326 } 327 328 Error AdbClient::StartSync() { 329 auto error = SwitchDeviceTransport(); 330 if (error.Fail()) 331 return Error("Failed to switch to device transport: %s", error.AsCString()); 332 333 error = Sync(); 334 if (error.Fail()) 335 return Error("Sync failed: %s", error.AsCString()); 336 337 return error; 338 } 339 340 Error AdbClient::Sync() { 341 auto error = SendMessage("sync:", false); 342 if (error.Fail()) 343 return error; 344 345 return ReadResponseStatus(); 346 } 347 348 Error AdbClient::ReadAllBytes(void *buffer, size_t size) { 349 return ::ReadAllBytes(*m_conn, buffer, size); 350 } 351 352 Error AdbClient::internalShell(const char *command, milliseconds timeout, 353 std::vector<char> &output_buf) { 354 output_buf.clear(); 355 356 auto error = SwitchDeviceTransport(); 357 if (error.Fail()) 358 return Error("Failed to switch to device transport: %s", error.AsCString()); 359 360 StreamString adb_command; 361 adb_command.Printf("shell:%s", command); 362 error = SendMessage(adb_command.GetString(), false); 363 if (error.Fail()) 364 return error; 365 366 error = ReadResponseStatus(); 367 if (error.Fail()) 368 return error; 369 370 error = ReadMessageStream(output_buf, timeout); 371 if (error.Fail()) 372 return error; 373 374 // ADB doesn't propagate return code of shell execution - if 375 // output starts with /system/bin/sh: most likely command failed. 376 static const char *kShellPrefix = "/system/bin/sh:"; 377 if (output_buf.size() > strlen(kShellPrefix)) { 378 if (!memcmp(&output_buf[0], kShellPrefix, strlen(kShellPrefix))) 379 return Error("Shell command %s failed: %s", command, 380 std::string(output_buf.begin(), output_buf.end()).c_str()); 381 } 382 383 return Error(); 384 } 385 386 Error AdbClient::Shell(const char *command, milliseconds timeout, 387 std::string *output) { 388 std::vector<char> output_buffer; 389 auto error = internalShell(command, timeout, output_buffer); 390 if (error.Fail()) 391 return error; 392 393 if (output) 394 output->assign(output_buffer.begin(), output_buffer.end()); 395 return error; 396 } 397 398 Error AdbClient::ShellToFile(const char *command, milliseconds timeout, 399 const FileSpec &output_file_spec) { 400 std::vector<char> output_buffer; 401 auto error = internalShell(command, timeout, output_buffer); 402 if (error.Fail()) 403 return error; 404 405 const auto output_filename = output_file_spec.GetPath(); 406 std::error_code EC; 407 llvm::raw_fd_ostream dst(output_filename, EC, llvm::sys::fs::F_None); 408 if (EC) 409 return Error("Unable to open local file %s", output_filename.c_str()); 410 411 dst.write(&output_buffer[0], output_buffer.size()); 412 dst.close(); 413 if (dst.has_error()) 414 return Error("Failed to write file %s", output_filename.c_str()); 415 return Error(); 416 } 417 418 std::unique_ptr<AdbClient::SyncService> 419 AdbClient::GetSyncService(Error &error) { 420 std::unique_ptr<SyncService> sync_service; 421 error = StartSync(); 422 if (error.Success()) 423 sync_service.reset(new SyncService(std::move(m_conn))); 424 425 return sync_service; 426 } 427 428 Error AdbClient::SyncService::internalPullFile(const FileSpec &remote_file, 429 const FileSpec &local_file) { 430 const auto local_file_path = local_file.GetPath(); 431 llvm::FileRemover local_file_remover(local_file_path); 432 433 std::error_code EC; 434 llvm::raw_fd_ostream dst(local_file_path, EC, llvm::sys::fs::F_None); 435 if (EC) 436 return Error("Unable to open local file %s", local_file_path.c_str()); 437 438 const auto remote_file_path = remote_file.GetPath(false); 439 auto error = SendSyncRequest(kRECV, remote_file_path.length(), 440 remote_file_path.c_str()); 441 if (error.Fail()) 442 return error; 443 444 std::vector<char> chunk; 445 bool eof = false; 446 while (!eof) { 447 error = PullFileChunk(chunk, eof); 448 if (error.Fail()) 449 return error; 450 if (!eof) 451 dst.write(&chunk[0], chunk.size()); 452 } 453 dst.close(); 454 if (dst.has_error()) 455 return Error("Failed to write file %s", local_file_path.c_str()); 456 457 local_file_remover.releaseFile(); 458 return error; 459 } 460 461 Error AdbClient::SyncService::internalPushFile(const FileSpec &local_file, 462 const FileSpec &remote_file) { 463 const auto local_file_path(local_file.GetPath()); 464 std::ifstream src(local_file_path.c_str(), std::ios::in | std::ios::binary); 465 if (!src.is_open()) 466 return Error("Unable to open local file %s", local_file_path.c_str()); 467 468 std::stringstream file_description; 469 file_description << remote_file.GetPath(false).c_str() << "," << kDefaultMode; 470 std::string file_description_str = file_description.str(); 471 auto error = SendSyncRequest(kSEND, file_description_str.length(), 472 file_description_str.c_str()); 473 if (error.Fail()) 474 return error; 475 476 char chunk[kMaxPushData]; 477 while (!src.eof() && !src.read(chunk, kMaxPushData).bad()) { 478 size_t chunk_size = src.gcount(); 479 error = SendSyncRequest(kDATA, chunk_size, chunk); 480 if (error.Fail()) 481 return Error("Failed to send file chunk: %s", error.AsCString()); 482 } 483 error = SendSyncRequest( 484 kDONE, llvm::sys::toTimeT(FileSystem::GetModificationTime(local_file)), 485 nullptr); 486 if (error.Fail()) 487 return error; 488 489 std::string response_id; 490 uint32_t data_len; 491 error = ReadSyncHeader(response_id, data_len); 492 if (error.Fail()) 493 return Error("Failed to read DONE response: %s", error.AsCString()); 494 if (response_id == kFAIL) { 495 std::string error_message(data_len, 0); 496 error = ReadAllBytes(&error_message[0], data_len); 497 if (error.Fail()) 498 return Error("Failed to read DONE error message: %s", error.AsCString()); 499 return Error("Failed to push file: %s", error_message.c_str()); 500 } else if (response_id != kOKAY) 501 return Error("Got unexpected DONE response: %s", response_id.c_str()); 502 503 // If there was an error reading the source file, finish the adb file 504 // transfer first so that adb isn't expecting any more data. 505 if (src.bad()) 506 return Error("Failed read on %s", local_file_path.c_str()); 507 return error; 508 } 509 510 Error AdbClient::SyncService::internalStat(const FileSpec &remote_file, 511 uint32_t &mode, uint32_t &size, 512 uint32_t &mtime) { 513 const std::string remote_file_path(remote_file.GetPath(false)); 514 auto error = SendSyncRequest(kSTAT, remote_file_path.length(), 515 remote_file_path.c_str()); 516 if (error.Fail()) 517 return Error("Failed to send request: %s", error.AsCString()); 518 519 static const size_t stat_len = strlen(kSTAT); 520 static const size_t response_len = stat_len + (sizeof(uint32_t) * 3); 521 522 std::vector<char> buffer(response_len); 523 error = ReadAllBytes(&buffer[0], buffer.size()); 524 if (error.Fail()) 525 return Error("Failed to read response: %s", error.AsCString()); 526 527 DataExtractor extractor(&buffer[0], buffer.size(), eByteOrderLittle, 528 sizeof(void *)); 529 offset_t offset = 0; 530 531 const void *command = extractor.GetData(&offset, stat_len); 532 if (!command) 533 return Error("Failed to get response command"); 534 const char *command_str = static_cast<const char *>(command); 535 if (strncmp(command_str, kSTAT, stat_len)) 536 return Error("Got invalid stat command: %s", command_str); 537 538 mode = extractor.GetU32(&offset); 539 size = extractor.GetU32(&offset); 540 mtime = extractor.GetU32(&offset); 541 return Error(); 542 } 543 544 Error AdbClient::SyncService::PullFile(const FileSpec &remote_file, 545 const FileSpec &local_file) { 546 return executeCommand([this, &remote_file, &local_file]() { 547 return internalPullFile(remote_file, local_file); 548 }); 549 } 550 551 Error AdbClient::SyncService::PushFile(const FileSpec &local_file, 552 const FileSpec &remote_file) { 553 return executeCommand([this, &local_file, &remote_file]() { 554 return internalPushFile(local_file, remote_file); 555 }); 556 } 557 558 Error AdbClient::SyncService::Stat(const FileSpec &remote_file, uint32_t &mode, 559 uint32_t &size, uint32_t &mtime) { 560 return executeCommand([this, &remote_file, &mode, &size, &mtime]() { 561 return internalStat(remote_file, mode, size, mtime); 562 }); 563 } 564 565 bool AdbClient::SyncService::IsConnected() const { 566 return m_conn && m_conn->IsConnected(); 567 } 568 569 AdbClient::SyncService::SyncService(std::unique_ptr<Connection> &&conn) 570 : m_conn(std::move(conn)) {} 571 572 Error AdbClient::SyncService::executeCommand( 573 const std::function<Error()> &cmd) { 574 if (!m_conn) 575 return Error("SyncService is disconnected"); 576 577 const auto error = cmd(); 578 if (error.Fail()) 579 m_conn.reset(); 580 581 return error; 582 } 583 584 AdbClient::SyncService::~SyncService() {} 585 586 Error AdbClient::SyncService::SendSyncRequest(const char *request_id, 587 const uint32_t data_len, 588 const void *data) { 589 const DataBufferSP data_sp(new DataBufferHeap(kSyncPacketLen, 0)); 590 DataEncoder encoder(data_sp, eByteOrderLittle, sizeof(void *)); 591 auto offset = encoder.PutData(0, request_id, strlen(request_id)); 592 encoder.PutU32(offset, data_len); 593 594 Error error; 595 ConnectionStatus status; 596 m_conn->Write(data_sp->GetBytes(), kSyncPacketLen, status, &error); 597 if (error.Fail()) 598 return error; 599 600 if (data) 601 m_conn->Write(data, data_len, status, &error); 602 return error; 603 } 604 605 Error AdbClient::SyncService::ReadSyncHeader(std::string &response_id, 606 uint32_t &data_len) { 607 char buffer[kSyncPacketLen]; 608 609 auto error = ReadAllBytes(buffer, kSyncPacketLen); 610 if (error.Success()) { 611 response_id.assign(&buffer[0], 4); 612 DataExtractor extractor(&buffer[4], 4, eByteOrderLittle, sizeof(void *)); 613 offset_t offset = 0; 614 data_len = extractor.GetU32(&offset); 615 } 616 617 return error; 618 } 619 620 Error AdbClient::SyncService::PullFileChunk(std::vector<char> &buffer, 621 bool &eof) { 622 buffer.clear(); 623 624 std::string response_id; 625 uint32_t data_len; 626 auto error = ReadSyncHeader(response_id, data_len); 627 if (error.Fail()) 628 return error; 629 630 if (response_id == kDATA) { 631 buffer.resize(data_len, 0); 632 error = ReadAllBytes(&buffer[0], data_len); 633 if (error.Fail()) 634 buffer.clear(); 635 } else if (response_id == kDONE) { 636 eof = true; 637 } else if (response_id == kFAIL) { 638 std::string error_message(data_len, 0); 639 error = ReadAllBytes(&error_message[0], data_len); 640 if (error.Fail()) 641 return Error("Failed to read pull error message: %s", error.AsCString()); 642 return Error("Failed to pull file: %s", error_message.c_str()); 643 } else 644 return Error("Pull failed with unknown response: %s", response_id.c_str()); 645 646 return Error(); 647 } 648 649 Error AdbClient::SyncService::ReadAllBytes(void *buffer, size_t size) { 650 return ::ReadAllBytes(*m_conn, buffer, size); 651 } 652