1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "MtpPacket" 18 19#include "MtpDebug.h" 20#include "MtpPacket.h" 21#include "mtp.h" 22 23#include <stdio.h> 24#include <stdlib.h> 25#include <stdio.h> 26 27#include <usbhost/usbhost.h> 28 29namespace android { 30 31MtpPacket::MtpPacket(int bufferSize) 32 : mBuffer(NULL), 33 mBufferSize(bufferSize), 34 mAllocationIncrement(bufferSize), 35 mPacketSize(0) 36{ 37 mBuffer = (uint8_t *)malloc(bufferSize); 38 if (!mBuffer) { 39 ALOGE("out of memory!"); 40 abort(); 41 } 42} 43 44MtpPacket::~MtpPacket() { 45 if (mBuffer) 46 free(mBuffer); 47} 48 49void MtpPacket::reset() { 50 allocate(MTP_CONTAINER_HEADER_SIZE); 51 mPacketSize = MTP_CONTAINER_HEADER_SIZE; 52 memset(mBuffer, 0, mBufferSize); 53} 54 55void MtpPacket::allocate(size_t length) { 56 if (length > mBufferSize) { 57 int newLength = length + mAllocationIncrement; 58 mBuffer = (uint8_t *)realloc(mBuffer, newLength); 59 if (!mBuffer) { 60 ALOGE("out of memory!"); 61 abort(); 62 } 63 mBufferSize = newLength; 64 } 65} 66 67void MtpPacket::dump() { 68#define DUMP_BYTES_PER_ROW 16 69 char buffer[500]; 70 char* bufptr = buffer; 71 72 for (int i = 0; i < mPacketSize; i++) { 73 sprintf(bufptr, "%02X ", mBuffer[i]); 74 bufptr += strlen(bufptr); 75 if (i % DUMP_BYTES_PER_ROW == (DUMP_BYTES_PER_ROW - 1)) { 76 ALOGV("%s", buffer); 77 bufptr = buffer; 78 } 79 } 80 if (bufptr != buffer) { 81 // print last line 82 ALOGV("%s", buffer); 83 } 84 ALOGV("\n"); 85} 86 87void MtpPacket::copyFrom(const MtpPacket& src) { 88 int length = src.mPacketSize; 89 allocate(length); 90 mPacketSize = length; 91 memcpy(mBuffer, src.mBuffer, length); 92} 93 94uint16_t MtpPacket::getUInt16(int offset) const { 95 return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset]; 96} 97 98uint32_t MtpPacket::getUInt32(int offset) const { 99 return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) | 100 ((uint32_t)mBuffer[offset + 1] << 8) | (uint32_t)mBuffer[offset]; 101} 102 103void MtpPacket::putUInt16(int offset, uint16_t value) { 104 mBuffer[offset++] = (uint8_t)(value & 0xFF); 105 mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF); 106} 107 108void MtpPacket::putUInt32(int offset, uint32_t value) { 109 mBuffer[offset++] = (uint8_t)(value & 0xFF); 110 mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF); 111 mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF); 112 mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF); 113} 114 115uint16_t MtpPacket::getContainerCode() const { 116 return getUInt16(MTP_CONTAINER_CODE_OFFSET); 117} 118 119void MtpPacket::setContainerCode(uint16_t code) { 120 putUInt16(MTP_CONTAINER_CODE_OFFSET, code); 121} 122 123uint16_t MtpPacket::getContainerType() const { 124 return getUInt16(MTP_CONTAINER_TYPE_OFFSET); 125} 126 127MtpTransactionID MtpPacket::getTransactionID() const { 128 return getUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET); 129} 130 131void MtpPacket::setTransactionID(MtpTransactionID id) { 132 putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id); 133} 134 135uint32_t MtpPacket::getParameter(int index) const { 136 if (index < 1 || index > 5) { 137 ALOGE("index %d out of range in MtpPacket::getParameter", index); 138 return 0; 139 } 140 return getUInt32(MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t)); 141} 142 143void MtpPacket::setParameter(int index, uint32_t value) { 144 if (index < 1 || index > 5) { 145 ALOGE("index %d out of range in MtpPacket::setParameter", index); 146 return; 147 } 148 int offset = MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t); 149 if (mPacketSize < offset + sizeof(uint32_t)) 150 mPacketSize = offset + sizeof(uint32_t); 151 putUInt32(offset, value); 152} 153 154#ifdef MTP_HOST 155int MtpPacket::transfer(struct usb_request* request) { 156 int result = usb_device_bulk_transfer(request->dev, 157 request->endpoint, 158 request->buffer, 159 request->buffer_length, 160 0); 161 request->actual_length = result; 162 return result; 163} 164#endif 165 166} // namespace android 167