/*
 * 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>

MtpPacket::MtpPacket(int bufferSize)
	:	mBuffer(NULL),
		mBufferSize(bufferSize),
		mAllocationIncrement(bufferSize),
		mPacketSize(0)
{
	mBuffer = (uint8_t *)malloc(bufferSize);
	if (!mBuffer) {
		MTPE("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(size_t length) {
	if (length > mBufferSize) {
		int newLength = length + mAllocationIncrement;
		mBuffer = (uint8_t *)realloc(mBuffer, newLength);
		if (!mBuffer) {
			MTPE("out of memory!");
			abort();
		}
		mBufferSize = newLength;
	}
}

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

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

void MtpPacket::copyFrom(const MtpPacket& src) {
	int length = src.mPacketSize;
	allocate(length);
	mPacketSize = length;
	memcpy(mBuffer, src.mBuffer, length);
}

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);
}

uint16_t MtpPacket::getContainerType() const {
	return getUInt16(MTP_CONTAINER_TYPE_OFFSET);
}

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) {
		MTPE("index %d out of range in MtpPacket::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) {
		MTPE("index %d out of range in MtpPacket::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_request* request) {
	int result = usb_device_bulk_transfer(request->dev,
							request->endpoint,
							request->buffer,
							request->buffer_length,
							0);
	request->actual_length = result;
	return result;
}
#endif
