116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood/* 216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Copyright (C) 2010 The Android Open Source Project 316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * 416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License"); 516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * you may not use this file except in compliance with the License. 616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * You may obtain a copy of the License at 716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * 816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * http://www.apache.org/licenses/LICENSE-2.0 916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * 1016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Unless required by applicable law or agreed to in writing, software 1116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS, 1216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * See the License for the specific language governing permissions and 1416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * limitations under the License. 1516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood */ 1616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 17b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#define LOG_TAG "MtpPacket" 18b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood 19b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#include "MtpDebug.h" 20b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#include "MtpPacket.h" 21b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#include "mtp.h" 22b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood 2316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <stdio.h> 2416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <stdlib.h> 2516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <stdio.h> 2616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 2716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <usbhost/usbhost.h> 2816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 297850ef999740f214a1990a9c090d3f3865d435aaMike Lockwoodnamespace android { 307850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood 3116864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpPacket::MtpPacket(int bufferSize) 3216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood : mBuffer(NULL), 3316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBufferSize(bufferSize), 3416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mAllocationIncrement(bufferSize), 3516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize(0) 3616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood{ 3716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer = (uint8_t *)malloc(bufferSize); 3816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!mBuffer) { 3929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("out of memory!"); 4016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood abort(); 4116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 4216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 4316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 4416864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpPacket::~MtpPacket() { 4516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mBuffer) 4616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood free(mBuffer); 4716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 4816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 4916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::reset() { 5016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(MTP_CONTAINER_HEADER_SIZE); 5116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = MTP_CONTAINER_HEADER_SIZE; 5216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood memset(mBuffer, 0, mBufferSize); 5316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 5416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 5516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::allocate(int length) { 5616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (length > mBufferSize) { 5716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int newLength = length + mAllocationIncrement; 5816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer = (uint8_t *)realloc(mBuffer, newLength); 5916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!mBuffer) { 6029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("out of memory!"); 6116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood abort(); 6216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 6316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBufferSize = newLength; 6416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 6516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 6616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 6716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::dump() { 68b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#define DUMP_BYTES_PER_ROW 16 69b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood char buffer[500]; 70b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood char* bufptr = buffer; 71b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood 7216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < mPacketSize; i++) { 73b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood sprintf(bufptr, "%02X ", mBuffer[i]); 74b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood bufptr += strlen(bufptr); 75b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood if (i % DUMP_BYTES_PER_ROW == (DUMP_BYTES_PER_ROW - 1)) { 763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("%s", buffer); 77b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood bufptr = buffer; 78b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood } 79b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood } 80b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood if (bufptr != buffer) { 81b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood // print last line 823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("%s", buffer); 8316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("\n"); 8516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 8616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 87f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwoodvoid MtpPacket::copyFrom(const MtpPacket& src) { 88f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood int length = src.mPacketSize; 89f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood allocate(length); 90f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood mPacketSize = length; 91f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood memcpy(mBuffer, src.mBuffer, length); 92f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood} 93f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood 9416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint16_t MtpPacket::getUInt16(int offset) const { 9516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset]; 9616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 9716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 9816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint32_t MtpPacket::getUInt32(int offset) const { 9916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) | 10016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ((uint32_t)mBuffer[offset + 1] << 8) | (uint32_t)mBuffer[offset]; 10116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 10216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 10316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::putUInt16(int offset, uint16_t value) { 10416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[offset++] = (uint8_t)(value & 0xFF); 10516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF); 10616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 10716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 10816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::putUInt32(int offset, uint32_t value) { 10916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[offset++] = (uint8_t)(value & 0xFF); 11016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF); 11116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF); 11216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF); 11316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 11416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 11516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint16_t MtpPacket::getContainerCode() const { 11616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return getUInt16(MTP_CONTAINER_CODE_OFFSET); 11716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 11816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 11916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::setContainerCode(uint16_t code) { 12016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt16(MTP_CONTAINER_CODE_OFFSET, code); 12116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 12216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 123f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwooduint16_t MtpPacket::getContainerType() const { 124f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood return getUInt16(MTP_CONTAINER_TYPE_OFFSET); 125f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood} 126f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood 12716864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpTransactionID MtpPacket::getTransactionID() const { 12816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return getUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET); 12916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 13016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 13116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::setTransactionID(MtpTransactionID id) { 13216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id); 13316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 13416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 13516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint32_t MtpPacket::getParameter(int index) const { 13616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (index < 1 || index > 5) { 13729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("index %d out of range in MtpPacket::getParameter", index); 13816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return 0; 13916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 14016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return getUInt32(MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t)); 14116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 14216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 14316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::setParameter(int index, uint32_t value) { 14416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (index < 1 || index > 5) { 14529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("index %d out of range in MtpPacket::setParameter", index); 14616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return; 14716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 14816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int offset = MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t); 14916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < offset + sizeof(uint32_t)) 15016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = offset + sizeof(uint32_t); 15116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(offset, value); 15216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 15316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 15416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#ifdef MTP_HOST 15542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpPacket::transfer(struct usb_request* request) { 156126ea73dd1919c8a176019c50b1ca96035aef45bMike Lockwood int result = usb_device_bulk_transfer(request->dev, 157126ea73dd1919c8a176019c50b1ca96035aef45bMike Lockwood request->endpoint, 158126ea73dd1919c8a176019c50b1ca96035aef45bMike Lockwood request->buffer, 159126ea73dd1919c8a176019c50b1ca96035aef45bMike Lockwood request->buffer_length, 160126ea73dd1919c8a176019c50b1ca96035aef45bMike Lockwood 0); 161126ea73dd1919c8a176019c50b1ca96035aef45bMike Lockwood request->actual_length = result; 162126ea73dd1919c8a176019c50b1ca96035aef45bMike Lockwood return result; 16316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 16416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#endif 1657850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood 1667850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood} // namespace android 167