/*
 * Copyright (C) 2010 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 LOG_TAG "MtpPacket"

#include "MtpDebug.h"
#include "MtpPacket.h"
#include "mtp.h"

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

#include <usbhost/usbhost.h>

namespace android {

MtpPacket::MtpPacket(int bufferSize)
    :   mBuffer(NULL),
        mBufferSize(bufferSize),
        mAllocationIncrement(bufferSize),
        mPacketSize(0)
{
    mBuffer = (uint8_t *)malloc(bufferSize);
    if (!mBuffer) {
        LOGE("out of memory!");
        abort();
    }
}

MtpPacket::~MtpPacket() {
    if (mBuffer)
        free(mBuffer);
}

void MtpPacket::reset() {
    allocate(MTP_CONTAINER_HEADER_SIZE);
    mPacketSize = MTP_CONTAINER_HEADER_SIZE;
    memset(mBuffer, 0, mBufferSize);
}

void MtpPacket::allocate(int length) {
    if (length > mBufferSize) {
        int newLength = length + mAllocationIncrement;
        mBuffer = (uint8_t *)realloc(mBuffer, newLength);
        if (!mBuffer) {
            LOGE("out of memory!");
            abort();
        }
        mBufferSize = newLength;
    }
}

void MtpPacket::dump() {
#define DUMP_BYTES_PER_ROW  16
    char buffer[500];
    char* bufptr = buffer;

    for (int i = 0; i < mPacketSize; i++) {
        sprintf(bufptr, "%02X ", mBuffer[i]);
        bufptr += strlen(bufptr);
        if (i % DUMP_BYTES_PER_ROW == (DUMP_BYTES_PER_ROW - 1)) {
            LOGV("%s", buffer);
            bufptr = buffer;
        }
    }
    if (bufptr != buffer) {
        // print last line
        LOGV("%s", buffer);
    }
    LOGV("\n");
}

uint16_t MtpPacket::getUInt16(int offset) const {
    return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset];
}

uint32_t MtpPacket::getUInt32(int offset) const {
    return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) |
           ((uint32_t)mBuffer[offset + 1] << 8)  | (uint32_t)mBuffer[offset];
}

void MtpPacket::putUInt16(int offset, uint16_t value) {
    mBuffer[offset++] = (uint8_t)(value & 0xFF);
    mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
}

void MtpPacket::putUInt32(int offset, uint32_t value) {
    mBuffer[offset++] = (uint8_t)(value & 0xFF);
    mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
    mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF);
    mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF);
}

uint16_t MtpPacket::getContainerCode() const {
    return getUInt16(MTP_CONTAINER_CODE_OFFSET);
}

void MtpPacket::setContainerCode(uint16_t code) {
    putUInt16(MTP_CONTAINER_CODE_OFFSET, code);
}

MtpTransactionID MtpPacket::getTransactionID() const {
    return getUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET);
}

void MtpPacket::setTransactionID(MtpTransactionID id) {
    putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id);
}

uint32_t MtpPacket::getParameter(int index) const {
    if (index < 1 || index > 5) {
        LOGE("index %d out of range in MtpRequestPacket::getParameter", index);
        return 0;
    }
    return getUInt32(MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t));
}

void MtpPacket::setParameter(int index, uint32_t value) {
    if (index < 1 || index > 5) {
        LOGE("index %d out of range in MtpResponsePacket::setParameter", index);
        return;
    }
    int offset = MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t);
    if (mPacketSize < offset + sizeof(uint32_t))
        mPacketSize = offset + sizeof(uint32_t);
    putUInt32(offset, value);
}

#ifdef MTP_HOST
int MtpPacket::transfer(struct usb_endpoint *ep, void* buffer, int length) {
    if (usb_endpoint_queue(ep, buffer, length)) {
        LOGE("usb_endpoint_queue failed, errno: %d", errno);
        return -1;
    }
    int ep_num;
    return usb_endpoint_wait(usb_endpoint_get_device(ep), &ep_num);
}
#endif

}  // namespace android
