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 "lldb/Core/DataBuffer.h" 12 #include "lldb/Core/DataBufferHeap.h" 13 #include "lldb/Core/DataEncoder.h" 14 #include "lldb/Core/DataExtractor.h" 15 #include "llvm/ADT/SmallVector.h" 16 #include "llvm/ADT/StringRef.h" 17 #include "llvm/ADT/STLExtras.h" 18 #include "llvm/Support/FileUtilities.h" 19 20 // Project includes 21 #include "AdbClient.h" 22 23 #include <limits.h> 24 25 #include <algorithm> 26 #include <fstream> 27 #include <sstream> 28 29 using namespace lldb; 30 using namespace lldb_private; 31 using namespace lldb_private::platform_android; 32 33 namespace { 34 35 const uint32_t kReadTimeout = 1000000; // 1 second 36 const char * kOKAY = "OKAY"; 37 const char * kFAIL = "FAIL"; 38 const size_t kSyncPacketLen = 8; 39 40 } // namespace 41 42 Error 43 AdbClient::CreateByDeviceID(const std::string &device_id, AdbClient &adb) 44 { 45 DeviceIDList connect_devices; 46 auto error = adb.GetDevices(connect_devices); 47 if (error.Fail()) 48 return error; 49 50 if (device_id.empty()) 51 { 52 if (connect_devices.size() != 1) 53 return Error("Expected a single connected device, got instead %" PRIu64, 54 static_cast<uint64_t>(connect_devices.size())); 55 56 adb.SetDeviceID(connect_devices.front()); 57 } 58 else 59 { 60 auto find_it = std::find(connect_devices.begin(), connect_devices.end(), device_id); 61 if (find_it == connect_devices.end()) 62 return Error("Device \"%s\" not found", device_id.c_str()); 63 64 adb.SetDeviceID(*find_it); 65 } 66 return error; 67 } 68 69 AdbClient::AdbClient (const std::string &device_id) 70 : m_device_id (device_id) 71 { 72 } 73 74 void 75 AdbClient::SetDeviceID (const std::string &device_id) 76 { 77 m_device_id = device_id; 78 } 79 80 const std::string& 81 AdbClient::GetDeviceID() const 82 { 83 return m_device_id; 84 } 85 86 Error 87 AdbClient::Connect () 88 { 89 Error error; 90 m_conn.Connect ("connect://localhost:5037", &error); 91 92 return error; 93 } 94 95 Error 96 AdbClient::GetDevices (DeviceIDList &device_list) 97 { 98 device_list.clear (); 99 100 auto error = SendMessage ("host:devices"); 101 if (error.Fail ()) 102 return error; 103 104 error = ReadResponseStatus (); 105 if (error.Fail ()) 106 return error; 107 108 std::vector<char> in_buffer; 109 error = ReadMessage (in_buffer); 110 111 llvm::StringRef response (&in_buffer[0], in_buffer.size ()); 112 llvm::SmallVector<llvm::StringRef, 4> devices; 113 response.split (devices, "\n", -1, false); 114 115 for (const auto device: devices) 116 device_list.push_back (device.split ('\t').first); 117 118 return error; 119 } 120 121 Error 122 AdbClient::SetPortForwarding (const uint16_t port) 123 { 124 char message[48]; 125 snprintf (message, sizeof (message), "forward:tcp:%d;tcp:%d", port, port); 126 127 const auto error = SendDeviceMessage (message); 128 if (error.Fail ()) 129 return error; 130 131 return ReadResponseStatus (); 132 } 133 134 Error 135 AdbClient::DeletePortForwarding (const uint16_t port) 136 { 137 char message[32]; 138 snprintf (message, sizeof (message), "killforward:tcp:%d", port); 139 140 const auto error = SendDeviceMessage (message); 141 if (error.Fail ()) 142 return error; 143 144 return ReadResponseStatus (); 145 } 146 147 Error 148 AdbClient::SendMessage (const std::string &packet, const bool reconnect) 149 { 150 Error error; 151 if (reconnect) 152 { 153 error = Connect (); 154 if (error.Fail ()) 155 return error; 156 } 157 158 char length_buffer[5]; 159 snprintf (length_buffer, sizeof (length_buffer), "%04x", static_cast<int>(packet.size ())); 160 161 ConnectionStatus status; 162 163 m_conn.Write (length_buffer, 4, status, &error); 164 if (error.Fail ()) 165 return error; 166 167 m_conn.Write (packet.c_str (), packet.size (), status, &error); 168 return error; 169 } 170 171 Error 172 AdbClient::SendDeviceMessage (const std::string &packet) 173 { 174 std::ostringstream msg; 175 msg << "host-serial:" << m_device_id << ":" << packet; 176 return SendMessage (msg.str ()); 177 } 178 179 Error 180 AdbClient::ReadMessage (std::vector<char> &message) 181 { 182 message.clear (); 183 184 char buffer[5]; 185 buffer[4] = 0; 186 187 auto error = ReadAllBytes (buffer, 4); 188 if (error.Fail ()) 189 return error; 190 191 unsigned int packet_len = 0; 192 sscanf (buffer, "%x", &packet_len); 193 194 message.resize (packet_len, 0); 195 error = ReadAllBytes (&message[0], packet_len); 196 if (error.Fail ()) 197 message.clear (); 198 199 return error; 200 } 201 202 Error 203 AdbClient::ReadResponseStatus() 204 { 205 char response_id[5]; 206 207 static const size_t packet_len = 4; 208 response_id[packet_len] = 0; 209 210 auto error = ReadAllBytes (response_id, packet_len); 211 if (error.Fail ()) 212 return error; 213 214 if (strncmp (response_id, kOKAY, packet_len) != 0) 215 return GetResponseError (response_id); 216 217 return error; 218 } 219 220 Error 221 AdbClient::GetResponseError (const char *response_id) 222 { 223 if (strcmp (response_id, kFAIL) != 0) 224 return Error ("Got unexpected response id from adb: \"%s\"", response_id); 225 226 std::vector<char> error_message; 227 auto error = ReadMessage (error_message); 228 if (error.Success ()) 229 error.SetErrorString (std::string (&error_message[0], error_message.size ()).c_str ()); 230 231 return error; 232 } 233 234 Error 235 AdbClient::SwitchDeviceTransport () 236 { 237 std::ostringstream msg; 238 msg << "host:transport:" << m_device_id; 239 240 auto error = SendMessage (msg.str ()); 241 if (error.Fail ()) 242 return error; 243 244 return ReadResponseStatus (); 245 } 246 247 Error 248 AdbClient::PullFile (const char *remote_file, const char *local_file) 249 { 250 auto error = SwitchDeviceTransport (); 251 if (error.Fail ()) 252 return Error ("Failed to switch to device transport: %s", error.AsCString ()); 253 254 error = Sync (); 255 if (error.Fail ()) 256 return Error ("Sync failed: %s", error.AsCString ()); 257 258 llvm::FileRemover local_file_remover (local_file); 259 260 std::ofstream dst (local_file, std::ios::out | std::ios::binary); 261 if (!dst.is_open ()) 262 return Error ("Unable to open local file %s", local_file); 263 264 error = SendSyncRequest ("RECV", strlen(remote_file), remote_file); 265 if (error.Fail ()) 266 return error; 267 268 std::vector<char> chunk; 269 bool eof = false; 270 while (!eof) 271 { 272 error = PullFileChunk (chunk, eof); 273 if (error.Fail ()) 274 return Error ("Failed to read file chunk: %s", error.AsCString ()); 275 if (!eof) 276 dst.write (&chunk[0], chunk.size ()); 277 } 278 279 local_file_remover.releaseFile (); 280 return error; 281 } 282 283 Error 284 AdbClient::Sync () 285 { 286 auto error = SendMessage ("sync:", false); 287 if (error.Fail ()) 288 return error; 289 290 return ReadResponseStatus (); 291 } 292 293 Error 294 AdbClient::PullFileChunk (std::vector<char> &buffer, bool &eof) 295 { 296 buffer.clear (); 297 298 std::string response_id; 299 uint32_t data_len; 300 auto error = ReadSyncHeader (response_id, data_len); 301 if (error.Fail ()) 302 return error; 303 304 if (response_id == "DATA") 305 { 306 buffer.resize (data_len, 0); 307 error = ReadAllBytes (&buffer[0], data_len); 308 if (error.Fail ()) 309 buffer.clear (); 310 } 311 else if (response_id == "DONE") 312 eof = true; 313 else 314 error = GetResponseError (response_id.c_str ()); 315 316 return error; 317 } 318 319 Error 320 AdbClient::SendSyncRequest (const char *request_id, const uint32_t data_len, const void *data) 321 { 322 const DataBufferSP data_sp (new DataBufferHeap (kSyncPacketLen, 0)); 323 DataEncoder encoder (data_sp, eByteOrderLittle, sizeof (void*)); 324 auto offset = encoder.PutData (0, request_id, strlen(request_id)); 325 encoder.PutU32 (offset, data_len); 326 327 Error error; 328 ConnectionStatus status; 329 m_conn.Write (data_sp->GetBytes (), kSyncPacketLen, status, &error); 330 if (error.Fail ()) 331 return error; 332 333 m_conn.Write (data, data_len, status, &error); 334 return error; 335 } 336 337 Error 338 AdbClient::ReadSyncHeader (std::string &response_id, uint32_t &data_len) 339 { 340 char buffer[kSyncPacketLen]; 341 342 auto error = ReadAllBytes (buffer, kSyncPacketLen); 343 if (error.Success ()) 344 { 345 response_id.assign (&buffer[0], 4); 346 DataExtractor extractor (&buffer[4], 4, eByteOrderLittle, sizeof (void*)); 347 offset_t offset = 0; 348 data_len = extractor.GetU32 (&offset); 349 } 350 351 return error; 352 } 353 354 Error 355 AdbClient::ReadAllBytes (void *buffer, size_t size) 356 { 357 Error error; 358 ConnectionStatus status; 359 char *read_buffer = static_cast<char*>(buffer); 360 361 size_t tota_read_bytes = 0; 362 while (tota_read_bytes < size) 363 { 364 auto read_bytes = m_conn.Read (read_buffer + tota_read_bytes, size - tota_read_bytes, kReadTimeout, status, &error); 365 if (error.Fail ()) 366 return error; 367 tota_read_bytes += read_bytes; 368 } 369 return error; 370 } 371