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