AdbConnection.cpp revision 3298a7d84b96ade73c6b170671711a8f2792ae59
18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright 2009, The Android Open Source Project 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * * Redistributions of source code must retain the above copyright 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * * Redistributions in binary form must reproduce the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 163298a7d84b96ade73c6b170671711a8f2792ae59Steve Block * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define LOG_TAG "wdsclient" 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "AdbConnection.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ClientUtils.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Device.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <arpa/inet.h> 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <errno.h> 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <string.h> 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <sys/socket.h> 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <sys/types.h> 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <utils/Log.h> 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid AdbConnection::close() { 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_fd != -1) { 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project shutdown(m_fd, SHUT_RDWR); 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ::close(m_fd); 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_fd = -1; 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Default adb port 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define ADB_PORT 5037 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool AdbConnection::connect() { 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Some commands (host:devices for example) close the connection so we call 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // connect after the response. 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project close(); 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_fd = socket(PF_INET, SOCK_STREAM, 0); 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_fd < 0) { 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project log_errno("Failed to create socket for connecting to adb"); 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Create the socket address struct 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project sockaddr_in adb; 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project createTcpSocket(adb, ADB_PORT); 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Connect to adb 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (::connect(m_fd, (sockaddr*) &adb, sizeof(adb)) < 0) { 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project log_errno("Failed to connect to adb"); 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Connected 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Adb protocol stuff 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define MAX_COMMAND_LENGTH 1024 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define PAYLOAD_LENGTH 4 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define PAYLOAD_FORMAT "%04X" 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool AdbConnection::sendRequest(const char* fmt, ...) const { 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_fd == -1) { 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGE("Connection is closed"); 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Build the command (service) 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char buf[MAX_COMMAND_LENGTH]; 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project va_list args; 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project va_start(args, fmt); 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int res = vsnprintf(buf, MAX_COMMAND_LENGTH, fmt, args); 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project va_end(args); 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Sending command: %04X%.*s", res, res, buf); 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Construct the payload length 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char payloadLen[PAYLOAD_LENGTH + 1]; 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project snprintf(payloadLen, sizeof(payloadLen), PAYLOAD_FORMAT, res); 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // First, send the payload length 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (send(m_fd, payloadLen, PAYLOAD_LENGTH, 0) < 0) { 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project log_errno("Failure when sending payload"); 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Send the actual command 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (send(m_fd, buf, res, 0) < 0) { 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project log_errno("Failure when sending command"); 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check for the OKAY from adb 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return checkOkayResponse(); 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void printFailureMessage(int fd) { 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Grab the payload length 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char lenStr[PAYLOAD_LENGTH + 1]; 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int payloadLen = recv(fd, lenStr, sizeof(lenStr) - 1, 0); 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(payloadLen == PAYLOAD_LENGTH, "Incorrect payload size"); 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lenStr[PAYLOAD_LENGTH] = 0; 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Parse the hex payload 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project payloadLen = strtol(lenStr, NULL, 16); 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (payloadLen < 0) 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Grab the message 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char* msg = new char[payloadLen + 1]; // include null-terminator 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int res = recv(fd, msg, payloadLen, 0); 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (res < 0) { 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project log_errno("Failure reading failure message from adb"); 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (res != payloadLen) { 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGE("Incorrect payload length %d - expected %d", res, payloadLen); 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project msg[res] = 0; 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Tell somebody about it 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGE("Received failure from adb: %s", msg); 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Cleanup 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete[] msg; 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define ADB_RESPONSE_LENGTH 4 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool AdbConnection::checkOkayResponse() const { 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ASSERT(m_fd != -1, "Connection has been closed!"); 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char buf[ADB_RESPONSE_LENGTH]; 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int res = recv(m_fd, buf, sizeof(buf), 0); 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (res < 0) { 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project log_errno("Failure reading response from adb"); 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check for a response other than OKAY/FAIL 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if ((res == ADB_RESPONSE_LENGTH) && (strncmp(buf, "OKAY", res) == 0)) { 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Command OKAY"); 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (strncmp(buf, "FAIL", ADB_RESPONSE_LENGTH) == 0) { 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Something happened, print out the reason for failure 1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project printFailureMessage(m_fd); 1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGE("Incorrect response from adb - '%.*s'", res, buf); 1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid AdbConnection::clearDevices() { 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (unsigned i = 0; i < m_devices.size(); i++) 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete m_devices.editItemAt(i); 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_devices.clear(); 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst DeviceList& AdbConnection::getDeviceList() { 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Clear the current device list 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project clearDevices(); 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_fd == -1) { 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGE("Connection is closed"); 1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_devices; 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Try to send the device list request 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!sendRequest("host:devices")) { 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGE("Failed to get device list from adb"); 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_devices; 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Get the payload length 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char lenStr[PAYLOAD_LENGTH + 1]; 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int res = recv(m_fd, lenStr, sizeof(lenStr) - 1, 0); 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (res < 0) { 1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project log_errno("Failure to read payload size of device list"); 1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_devices; 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lenStr[PAYLOAD_LENGTH] = 0; 1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Parse the hex payload 2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int payloadLen = strtol(lenStr, NULL, 16); 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (payloadLen < 0) 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_devices; 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Grab the list of devices. The format is as follows: 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // <serialno><tab><state><newline> 2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char* msg = new char[payloadLen + 1]; 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project res = recv(m_fd, msg, payloadLen, 0); 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (res < 0) { 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project log_errno("Failure reading the device list"); 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_devices; 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (res != payloadLen) { 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGE("Incorrect payload length %d - expected %d", res, payloadLen); 2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_devices; 2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project msg[res] = 0; 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char serial[32]; 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char state[32]; 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int numRead; 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char* ptr = msg; 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (sscanf(ptr, "%31s\t%31s\n%n", serial, state, &numRead) > 1) { 2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Device::DeviceType t = Device::DEVICE; 2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static const char emulator[] = "emulator-"; 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (strncmp(serial, emulator, sizeof(emulator) - 1) == 0) 2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project t = Device::EMULATOR; 2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOGV("Adding device %s (%s)", serial, state); 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_devices.add(new Device(serial, t, this)); 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Reset for the next line 2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ptr += numRead; 2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Cleanup 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete[] msg; 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_devices; 2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 238