MtpPacket.cpp revision f7454622eaac287d20ab43013d7015fe42b894f8
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) { 39b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGE("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) { 60b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGE("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)) { 76b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGV("%s", buffer); 77b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood bufptr = buffer; 78b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood } 79b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood } 80b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood if (bufptr != buffer) { 81b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood // print last line 82b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGV("%s", buffer); 8316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 84b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGV("\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) { 137d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood LOGE("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) { 145d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood LOGE("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 15516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodint MtpPacket::transfer(struct usb_endpoint *ep, void* buffer, int length) { 15616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (usb_endpoint_queue(ep, buffer, length)) { 157b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood LOGE("usb_endpoint_queue failed, errno: %d", errno); 15816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return -1; 15916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 16016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int ep_num; 16116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return usb_endpoint_wait(usb_endpoint_get_device(ep), &ep_num); 16216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 16316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#endif 1647850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood 1657850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood} // namespace android 166