/*
 * Copyright (C) 2007 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 TRACE_TAG TRANSPORT

#include "sysdeps.h"
#include "transport.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "adb.h"

#if ADB_HOST

// Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes
// to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html.
static int UsbReadMessage(usb_handle* h, amessage* msg) {
    D("UsbReadMessage");

    size_t usb_packet_size = usb_get_max_packet_size(h);
    CHECK_GE(usb_packet_size, sizeof(*msg));
    CHECK_LT(usb_packet_size, 4096ULL);

    char buffer[4096];
    int n = usb_read(h, buffer, usb_packet_size);
    if (n != sizeof(*msg)) {
        D("usb_read returned unexpected length %d (expected %zu)", n, sizeof(*msg));
        return -1;
    }
    memcpy(msg, buffer, sizeof(*msg));
    return n;
}

// Call usb_read using a buffer having a multiple of usb_get_max_packet_size() bytes
// to avoid overflow. See http://libusb.sourceforge.net/api-1.0/packetoverflow.html.
static int UsbReadPayload(usb_handle* h, apacket* p) {
    D("UsbReadPayload(%d)", p->msg.data_length);

    size_t usb_packet_size = usb_get_max_packet_size(h);
    CHECK_EQ(0ULL, sizeof(p->data) % usb_packet_size);

    // Round the data length up to the nearest packet size boundary.
    // The device won't send a zero packet for packet size aligned payloads,
    // so don't read any more packets than needed.
    size_t len = p->msg.data_length;
    size_t rem_size = len % usb_packet_size;
    if (rem_size) {
        len += usb_packet_size - rem_size;
    }
    CHECK_LE(len, sizeof(p->data));
    return usb_read(h, &p->data, len);
}

static int remote_read(apacket* p, atransport* t) {
    int n = UsbReadMessage(t->usb, &p->msg);
    if (n < 0) {
        D("remote usb: read terminated (message)");
        return -1;
    }
    if (static_cast<size_t>(n) != sizeof(p->msg) || !check_header(p, t)) {
        D("remote usb: check_header failed, skip it");
        goto err_msg;
    }
    if (t->GetConnectionState() == kCsOffline) {
        // If we read a wrong msg header declaring a large message payload, don't read its payload.
        // Otherwise we may miss true messages from the device.
        if (p->msg.command != A_CNXN && p->msg.command != A_AUTH) {
            goto err_msg;
        }
    }
    if (p->msg.data_length) {
        n = UsbReadPayload(t->usb, p);
        if (n < 0) {
            D("remote usb: terminated (data)");
            return -1;
        }
        if (static_cast<uint32_t>(n) != p->msg.data_length) {
            D("remote usb: read payload failed (need %u bytes, give %d bytes), skip it",
              p->msg.data_length, n);
            goto err_msg;
        }
    }
    if (!check_data(p)) {
        D("remote usb: check_data failed, skip it");
        goto err_msg;
    }
    return 0;

err_msg:
    p->msg.command = 0;
    return 0;
}

#else

// On Android devices, we rely on the kernel to provide buffered read.
// So we can recover automatically from EOVERFLOW.
static int remote_read(apacket *p, atransport *t)
{
    if (usb_read(t->usb, &p->msg, sizeof(amessage))) {
        PLOG(ERROR) << "remote usb: read terminated (message)";
        return -1;
    }

    if (!check_header(p, t)) {
        LOG(ERROR) << "remote usb: check_header failed";
        return -1;
    }

    if (p->msg.data_length) {
        if (usb_read(t->usb, p->data, p->msg.data_length)) {
            PLOG(ERROR) << "remote usb: terminated (data)";
            return -1;
        }
    }

    if (!check_data(p)) {
        LOG(ERROR) << "remote usb: check_data failed";
        return -1;
    }

    return 0;
}
#endif

static int remote_write(apacket *p, atransport *t)
{
    unsigned size = p->msg.data_length;

    if (usb_write(t->usb, &p->msg, sizeof(amessage))) {
        PLOG(ERROR) << "remote usb: 1 - write terminated";
        return -1;
    }
    if (p->msg.data_length == 0) return 0;
    if (usb_write(t->usb, &p->data, size)) {
        PLOG(ERROR) << "remote usb: 2 - write terminated";
        return -1;
    }

    return 0;
}

static void remote_close(atransport* t) {
    usb_close(t->usb);
    t->usb = 0;
}

static void remote_kick(atransport* t) {
    usb_kick(t->usb);
}

void init_usb_transport(atransport* t, usb_handle* h) {
    D("transport: usb");
    t->close = remote_close;
    t->SetKickFunction(remote_kick);
    t->SetWriteFunction(remote_write);
    t->read_from_remote = remote_read;
    t->sync_token = 1;
    t->type = kTransportUsb;
    t->usb = h;
}

int is_adb_interface(int usb_class, int usb_subclass, int usb_protocol)
{
    return (usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS && usb_protocol == ADB_PROTOCOL);
}

bool should_use_libusb() {
#if defined(_WIN32) || !ADB_HOST
    return false;
#else
    static bool enable = getenv("ADB_LIBUSB") && strcmp(getenv("ADB_LIBUSB"), "1") == 0;
    return enable;
#endif
}
