MtpPacket.cpp revision 7850ef999740f214a1990a9c090d3f3865d435aa
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 1716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <stdio.h> 1816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <stdlib.h> 1916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <stdio.h> 2016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 2116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <usbhost/usbhost.h> 2216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 2316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "MtpPacket.h" 2416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 257850ef999740f214a1990a9c090d3f3865d435aaMike Lockwoodnamespace android { 267850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood 2716864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpPacket::MtpPacket(int bufferSize) 2816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood : mBuffer(NULL), 2916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBufferSize(bufferSize), 3016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mAllocationIncrement(bufferSize), 3116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize(0) 3216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood{ 3316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer = (uint8_t *)malloc(bufferSize); 3416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!mBuffer) { 3516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood fprintf(stderr, "out of memory!\n"); 3616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood abort(); 3716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 3816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 3916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 4016864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpPacket::~MtpPacket() { 4116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mBuffer) 4216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood free(mBuffer); 4316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 4416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 4516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::reset() { 4616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(MTP_CONTAINER_HEADER_SIZE); 4716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = MTP_CONTAINER_HEADER_SIZE; 4816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood memset(mBuffer, 0, mBufferSize); 4916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 5016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 5116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::allocate(int length) { 5216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (length > mBufferSize) { 5316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int newLength = length + mAllocationIncrement; 5416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer = (uint8_t *)realloc(mBuffer, newLength); 5516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!mBuffer) { 5616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood fprintf(stderr, "out of memory!\n"); 5716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood abort(); 5816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 5916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBufferSize = newLength; 6016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 6116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 6216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 6316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::dump() { 6416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < mPacketSize; i++) { 6516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood printf("%02X ", mBuffer[i]); 6616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (i % 16 == 15) 6716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood printf("\n"); 6816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 6916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood printf("\n\n"); 7016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 7116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 7216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint16_t MtpPacket::getUInt16(int offset) const { 7316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset]; 7416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 7516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 7616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint32_t MtpPacket::getUInt32(int offset) const { 7716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) | 7816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ((uint32_t)mBuffer[offset + 1] << 8) | (uint32_t)mBuffer[offset]; 7916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 8016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 8116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::putUInt16(int offset, uint16_t value) { 8216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[offset++] = (uint8_t)(value & 0xFF); 8316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF); 8416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 8516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 8616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::putUInt32(int offset, uint32_t value) { 8716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[offset++] = (uint8_t)(value & 0xFF); 8816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF); 8916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF); 9016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF); 9116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 9216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 9316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint16_t MtpPacket::getContainerCode() const { 9416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return getUInt16(MTP_CONTAINER_CODE_OFFSET); 9516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 9616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 9716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::setContainerCode(uint16_t code) { 9816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt16(MTP_CONTAINER_CODE_OFFSET, code); 9916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 10016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 10116864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpTransactionID MtpPacket::getTransactionID() const { 10216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return getUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET); 10316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 10416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 10516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::setTransactionID(MtpTransactionID id) { 10616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id); 10716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 10816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 10916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint32_t MtpPacket::getParameter(int index) const { 11016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (index < 1 || index > 5) { 11116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood fprintf(stderr, "index %d out of range in MtpRequestPacket::getParameter\n", index); 11216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return 0; 11316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 11416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return getUInt32(MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t)); 11516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 11616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 11716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::setParameter(int index, uint32_t value) { 11816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (index < 1 || index > 5) { 11916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood fprintf(stderr, "index %d out of range in MtpResponsePacket::setParameter\n", index); 12016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return; 12116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 12216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int offset = MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t); 12316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < offset + sizeof(uint32_t)) 12416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = offset + sizeof(uint32_t); 12516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(offset, value); 12616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 12716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 12816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#ifdef MTP_HOST 12916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodint MtpPacket::transfer(struct usb_endpoint *ep, void* buffer, int length) { 13016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood printf("MtpPacket::transfer length: %d\n", length); 13116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (usb_endpoint_queue(ep, buffer, length)) { 13216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood printf("usb_endpoint_queue failed, errno: %d\n", errno); 13316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return -1; 13416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 13516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int ep_num; 13616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return usb_endpoint_wait(usb_endpoint_get_device(ep), &ep_num); 13716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 13816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#endif 1397850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood 1407850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood} // namespace android 141