/* libs/utils/adb_networking.c ** ** Copyright 2006, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #define ADB_PORT 5037 #define _GNU_SOURCE /* for asprintf */ #include #include #include #include #include #include #include #include #include #include #define ADB_RESPONSE_SIZE 4 /** * Unfortunately, java.net.Socket wants to create it's filedescriptor early * So, this function takes an fd that must be an unconnected * PF_LOCAL SOCK_STREAM */ int adb_networking_connect_fd(int fd, struct sockaddr_in *p_address) { struct sockaddr_in local_addr; socklen_t alen; char *cmd; char buf[ADB_RESPONSE_SIZE + 1]; ssize_t count_read; int ret; int err; /* for impl of inet_ntoa below*/ union { uint8_t b[4]; uint32_t l; } a; /* First, connect to adb */ memset(&local_addr, 0, sizeof(local_addr)); local_addr.sin_family = AF_INET; local_addr.sin_port = htons(ADB_PORT); local_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); do { err = connect(fd, (struct sockaddr *) &local_addr, sizeof(local_addr)); } while (err < 0 && errno == EINTR); if (err < 0) { return -1; } a.l = p_address->sin_addr.s_addr; // compose the command asprintf(&cmd, "tcp:%u:%u.%u.%u.%u", (unsigned int)ntohs(p_address->sin_port), a.b[0],a.b[1],a.b[2],a.b[3]); // buf is now the ascii hex length of cmd snprintf(buf, sizeof(buf), "%04X", strlen(cmd)); // write the 4-byte length do { err = write(fd, buf, 4); } while (err < 0 && errno == EINTR); // write the command do { err = write(fd, cmd, strlen(cmd)); } while (err < 0 && errno == EINTR); // read the result do { count_read = read(fd, buf, sizeof(buf) - 1); } while (count_read < 0 && errno != EINTR); if (count_read == ADB_RESPONSE_SIZE && 0 == strncmp(buf, "OKAY", ADB_RESPONSE_SIZE)) { ret = 0; } else { /* what errno here? s_addr), sizeof(p_out_addr->s_addr)); } while (count_read < 0 && errno != EINTR); if (count_read != 4) { goto error; } free(cmd); close(fd); return 0; error: free(cmd); close(fd); memset(p_out_addr, 0, sizeof(struct in_addr)); return -1; }