1cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert/*
2cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * Copyright (C) 2015 The Android Open Source Project
3cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert *
4cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * Licensed under the Apache License, Version 2.0 (the "License");
5cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * you may not use this file except in compliance with the License.
6cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * You may obtain a copy of the License at
7cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert *
8cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert *      http://www.apache.org/licenses/LICENSE-2.0
9cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert *
10cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * Unless required by applicable law or agreed to in writing, software
11cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * distributed under the License is distributed on an "AS IS" BASIS,
12cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * See the License for the specific language governing permissions and
14cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * limitations under the License.
15cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert */
16cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
173313426fad9eaaf53017cdbde889ebcec91358ecDan Albert#define TRACE_TAG TRACE_RWX
18cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
19cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert#include "adb_io.h"
20cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
21cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert#include <unistd.h>
22cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
23e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes#include <base/stringprintf.h>
24e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes
25cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert#include "adb_trace.h"
2692af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes#include "adb_utils.h"
27e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes#include "sysdeps.h"
2892af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes
2992af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughesbool SendProtocolString(int fd, const std::string& s) {
3092af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes    int length = s.size();
3192af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes    if (length > 0xffff) {
3292af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes        length = 0xffff;
3392af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes    }
3492af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes
35e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes    return WriteFdFmt(fd, "%04x", length) && WriteFdExactly(fd, s);
3692af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes}
3792af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes
3892af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughesbool SendOkay(int fd) {
3992af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes    return WriteFdExactly(fd, "OKAY", 4);
4092af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes}
4192af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes
4292af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughesbool SendFail(int fd, const std::string& reason) {
4392af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes    return WriteFdExactly(fd, "FAIL", 4) && SendProtocolString(fd, reason);
4492af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes}
45cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
46cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albertbool ReadFdExactly(int fd, void* buf, size_t len) {
47cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    char* p = reinterpret_cast<char*>(buf);
48cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
49cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    size_t len0 = len;
50cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
51cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    D("readx: fd=%d wanted=%zu\n", fd, len);
52cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    while (len > 0) {
53bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert        int r = adb_read(fd, p, len);
54cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert        if (r > 0) {
55cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert            len -= r;
56cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert            p += r;
57cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert        } else if (r == -1) {
58cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert            D("readx: fd=%d error %d: %s\n", fd, errno, strerror(errno));
59cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert            return false;
60cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert        } else {
61cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert            D("readx: fd=%d disconnected\n", fd);
62cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert            errno = 0;
63cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert            return false;
64cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert        }
65cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    }
66cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
67cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    D("readx: fd=%d wanted=%zu got=%zu\n", fd, len0, len0 - len);
68cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    if (ADB_TRACING) {
69cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert        dump_hex(reinterpret_cast<const unsigned char*>(buf), len0);
70cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    }
71cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
72cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    return true;
73cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert}
74cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
75cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albertbool WriteFdExactly(int fd, const void* buf, size_t len) {
76cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    const char* p = reinterpret_cast<const char*>(buf);
77cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    int r;
78cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
79cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    D("writex: fd=%d len=%d: ", fd, (int)len);
80cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    if (ADB_TRACING) {
81cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert        dump_hex(reinterpret_cast<const unsigned char*>(buf), len);
82cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    }
83cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
84cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    while (len > 0) {
85bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert        r = adb_write(fd, p, len);
86cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert        if (r == -1) {
87cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert            D("writex: fd=%d error %d: %s\n", fd, errno, strerror(errno));
88cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert            if (errno == EAGAIN) {
89cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert                adb_sleep_ms(1); // just yield some cpu time
90cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert                continue;
91cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert            } else if (errno == EPIPE) {
92cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert                D("writex: fd=%d disconnected\n", fd);
93cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert                errno = 0;
94cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert                return false;
9508f66bc771ac798d89451a9b68a1c6722352d683Dan Albert            } else {
9608f66bc771ac798d89451a9b68a1c6722352d683Dan Albert                return false;
97cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert            }
98cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert        } else {
99cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert            len -= r;
100cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert            p += r;
101cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert        }
102cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    }
103cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    return true;
104cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert}
105cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert
10692af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughesbool WriteFdExactly(int fd, const char* str) {
10792af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes    return WriteFdExactly(fd, str, strlen(str));
10892af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes}
10992af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes
11092af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughesbool WriteFdExactly(int fd, const std::string& str) {
11192af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes    return WriteFdExactly(fd, str.c_str(), str.size());
11292af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes}
11392af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes
114e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughesbool WriteFdFmt(int fd, const char* fmt, ...) {
115e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes    std::string str;
116e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes
117e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes    va_list ap;
118e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes    va_start(ap, fmt);
119e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes    android::base::StringAppendV(&str, fmt, ap);
120e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes    va_end(ap);
121e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes
122e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes    return WriteFdExactly(fd, str);
123cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert}
124