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 "MtpDataPacket" 18b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood 1916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <stdio.h> 2016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <sys/types.h> 2116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <fcntl.h> 2216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 230cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood#include <usbhost/usbhost.h> 240cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 2516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "MtpDataPacket.h" 2616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "MtpStringBuffer.h" 2716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 287850ef999740f214a1990a9c090d3f3865d435aaMike Lockwoodnamespace android { 297850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood 3016864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpDataPacket::MtpDataPacket() 3144c190826d72589f5c9e13d69e32673bd8bd7c64Mike Lockwood : MtpPacket(MTP_BUFFER_SIZE), // MAX_USBFS_BUFFER_SIZE 3216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mOffset(MTP_CONTAINER_HEADER_SIZE) 3316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood{ 3416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 3516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 3616864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpDataPacket::~MtpDataPacket() { 3716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 3816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 3916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::reset() { 4016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpPacket::reset(); 4116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mOffset = MTP_CONTAINER_HEADER_SIZE; 4216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 4316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 4416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::setOperationCode(MtpOperationCode code) { 4516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpPacket::putUInt16(MTP_CONTAINER_CODE_OFFSET, code); 4616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 4716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 4816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::setTransactionID(MtpTransactionID id) { 4916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpPacket::putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id); 5016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 5116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 52ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getUInt8(uint8_t& value) { 53ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (mPacketSize - mOffset < sizeof(value)) 54ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return false; 55ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood value = mBuffer[mOffset++]; 56ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return true; 57ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood} 58ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 59ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getUInt16(uint16_t& value) { 60ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (mPacketSize - mOffset < sizeof(value)) 61ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return false; 6216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int offset = mOffset; 63ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood value = (uint16_t)mBuffer[offset] | ((uint16_t)mBuffer[offset + 1] << 8); 64ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mOffset += sizeof(value); 65ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return true; 6616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 6716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 68ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getUInt32(uint32_t& value) { 69ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (mPacketSize - mOffset < sizeof(value)) 70ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return false; 7116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int offset = mOffset; 72ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood value = (uint32_t)mBuffer[offset] | ((uint32_t)mBuffer[offset + 1] << 8) | 7316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ((uint32_t)mBuffer[offset + 2] << 16) | ((uint32_t)mBuffer[offset + 3] << 24); 74ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mOffset += sizeof(value); 75ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return true; 7616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 7716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 78ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getUInt64(uint64_t& value) { 79ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (mPacketSize - mOffset < sizeof(value)) 80ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return false; 8116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int offset = mOffset; 82ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood value = (uint64_t)mBuffer[offset] | ((uint64_t)mBuffer[offset + 1] << 8) | 8316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ((uint64_t)mBuffer[offset + 2] << 16) | ((uint64_t)mBuffer[offset + 3] << 24) | 8416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ((uint64_t)mBuffer[offset + 4] << 32) | ((uint64_t)mBuffer[offset + 5] << 40) | 8516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ((uint64_t)mBuffer[offset + 6] << 48) | ((uint64_t)mBuffer[offset + 7] << 56); 86ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mOffset += sizeof(value); 87ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return true; 8816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 8916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 90ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getUInt128(uint128_t& value) { 91ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return getUInt32(value[0]) && getUInt32(value[1]) && getUInt32(value[2]) && getUInt32(value[3]); 92a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood} 93a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood 94ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getString(MtpStringBuffer& string) 9516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood{ 96ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return string.readFromPacket(this); 9716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 9816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 99335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodInt8List* MtpDataPacket::getAInt8() { 100ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t count; 101ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(count)) 102ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 103335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood Int8List* result = new Int8List; 104ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood for (uint32_t i = 0; i < count; i++) { 105ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood int8_t value; 106ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getInt8(value)) { 107ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood delete result; 108ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 109ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 110ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood result->push(value); 111ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 112335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood return result; 113335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood} 114335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 115335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodUInt8List* MtpDataPacket::getAUInt8() { 116ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t count; 117ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(count)) 118ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 119335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood UInt8List* result = new UInt8List; 120ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood for (uint32_t i = 0; i < count; i++) { 121ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint8_t value; 122ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt8(value)) { 123ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood delete result; 124ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 125ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 126ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood result->push(value); 127ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 128335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood return result; 129335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood} 130335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 131335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodInt16List* MtpDataPacket::getAInt16() { 132ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t count; 133ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(count)) 134ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 135335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood Int16List* result = new Int16List; 136ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood for (uint32_t i = 0; i < count; i++) { 137ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood int16_t value; 138ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getInt16(value)) { 139ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood delete result; 140ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 141ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 142ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood result->push(value); 143ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 144335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood return result; 145335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood} 146335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 147335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodUInt16List* MtpDataPacket::getAUInt16() { 148ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t count; 149ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(count)) 150ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 151335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood UInt16List* result = new UInt16List; 152ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood for (uint32_t i = 0; i < count; i++) { 153ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint16_t value; 154ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt16(value)) { 155ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood delete result; 156ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 157ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 158ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood result->push(value); 159ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 160335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood return result; 161335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood} 162335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 163335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodInt32List* MtpDataPacket::getAInt32() { 164ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t count; 165ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(count)) 166ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 167335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood Int32List* result = new Int32List; 168ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood for (uint32_t i = 0; i < count; i++) { 169ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood int32_t value; 170ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getInt32(value)) { 171ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood delete result; 172ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 173ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 174ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood result->push(value); 175ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 176335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood return result; 177335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood} 178335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 179335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodUInt32List* MtpDataPacket::getAUInt32() { 180ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t count; 181ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(count)) 182ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 183335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood UInt32List* result = new UInt32List; 184ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood for (uint32_t i = 0; i < count; i++) { 185ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t value; 186ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(value)) { 187ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood delete result; 188ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 189ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 190ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood result->push(value); 191ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 192335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood return result; 193335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood} 194335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 195335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodInt64List* MtpDataPacket::getAInt64() { 196ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t count; 197ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(count)) 198ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 199335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood Int64List* result = new Int64List; 200ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood for (uint32_t i = 0; i < count; i++) { 201ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood int64_t value; 202ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getInt64(value)) { 203ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood delete result; 204ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 205ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 206ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood result->push(value); 207ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 208335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood return result; 209335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood} 210335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 211335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodUInt64List* MtpDataPacket::getAUInt64() { 212ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t count; 213ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(count)) 214ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 215335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood UInt64List* result = new UInt64List; 216ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood for (uint32_t i = 0; i < count; i++) { 217ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint64_t value; 218ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt64(value)) { 219ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood delete result; 220ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 221ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 222ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood result->push(value); 223ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 224335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood return result; 225335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood} 226335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 22716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putInt8(int8_t value) { 22816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(mOffset + 1); 22916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)value; 23016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < mOffset) 23116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = mOffset; 23216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 23316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 23416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putUInt8(uint8_t value) { 23516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(mOffset + 1); 23616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)value; 23716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < mOffset) 23816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = mOffset; 23916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 24016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 24116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putInt16(int16_t value) { 24216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(mOffset + 2); 24316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 24416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 24516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < mOffset) 24616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = mOffset; 24716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 24816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 24916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putUInt16(uint16_t value) { 25016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(mOffset + 2); 25116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 25216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 25316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < mOffset) 25416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = mOffset; 25516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 25616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 25716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putInt32(int32_t value) { 25816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(mOffset + 4); 25916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 26016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 26116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 26216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 26316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < mOffset) 26416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = mOffset; 26516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 26616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 26716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putUInt32(uint32_t value) { 26816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(mOffset + 4); 26916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 27016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 27116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 27216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 27316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < mOffset) 27416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = mOffset; 27516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 27616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 27716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putInt64(int64_t value) { 27816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(mOffset + 8); 27916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 28016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 28116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 28216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 28316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF); 28416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF); 28516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF); 28616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF); 28716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < mOffset) 28816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = mOffset; 28916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 29016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 29116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putUInt64(uint64_t value) { 29216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(mOffset + 8); 29316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 29416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 29516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 29616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 29716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF); 29816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF); 29916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF); 30016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF); 30116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < mOffset) 30216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = mOffset; 30316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 30416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 305a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwoodvoid MtpDataPacket::putInt128(const int128_t& value) { 306a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood putInt32(value[0]); 307a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood putInt32(value[1]); 308a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood putInt32(value[2]); 309a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood putInt32(value[3]); 310a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood} 311a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood 312a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwoodvoid MtpDataPacket::putUInt128(const uint128_t& value) { 313a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood putUInt32(value[0]); 314a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood putUInt32(value[1]); 315a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood putUInt32(value[2]); 316a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood putUInt32(value[3]); 317a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood} 318a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood 3198277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwoodvoid MtpDataPacket::putInt128(int64_t value) { 3208277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood putInt64(value); 3215959988b63ace3fba2fc78b135a4f5ef25dcf860Mike Lockwood putInt64(value < 0 ? -1 : 0); 3228277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood} 3238277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 3248277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwoodvoid MtpDataPacket::putUInt128(uint64_t value) { 3258277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood putUInt64(value); 3268277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood putUInt64(0); 3278277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood} 3288277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 32916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAInt8(const int8_t* values, int count) { 33016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(count); 33116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 33216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putInt8(*values++); 33316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 33416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 33516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt8(const uint8_t* values, int count) { 33616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(count); 33716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 33816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt8(*values++); 33916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 34016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 34116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAInt16(const int16_t* values, int count) { 34216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(count); 34316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 34416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putInt16(*values++); 34516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 34616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 34716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt16(const uint16_t* values, int count) { 34816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(count); 34916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 35016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt16(*values++); 35116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 35216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 353782aef17c9921a3bf401a0432878df5031f2328bMike Lockwoodvoid MtpDataPacket::putAUInt16(const UInt16List* values) { 354782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood size_t count = (values ? values->size() : 0); 355782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood putUInt32(count); 356782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood for (size_t i = 0; i < count; i++) 357782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood putUInt16((*values)[i]); 358782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood} 359782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood 36016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAInt32(const int32_t* values, int count) { 36116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(count); 36216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 36316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putInt32(*values++); 36416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 36516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 36616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt32(const uint32_t* values, int count) { 36716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(count); 36816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 36916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(*values++); 37016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 37116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 37216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt32(const UInt32List* list) { 37316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!list) { 37416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putEmptyArray(); 37516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } else { 37616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood size_t size = list->size(); 37716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(size); 37816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (size_t i = 0; i < size; i++) 37916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32((*list)[i]); 38016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 38116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 38216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 38316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAInt64(const int64_t* values, int count) { 38416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(count); 38516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 38616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putInt64(*values++); 38716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 38816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 38916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt64(const uint64_t* values, int count) { 39016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(count); 39116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 39216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt64(*values++); 39316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 39416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 3951865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwoodvoid MtpDataPacket::putString(const MtpStringBuffer& string) { 39616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood string.writeToPacket(this); 39716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 39816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 3991865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwoodvoid MtpDataPacket::putString(const char* s) { 40016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStringBuffer string(s); 40116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood string.writeToPacket(this); 40216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 40316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 4041865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwoodvoid MtpDataPacket::putString(const uint16_t* string) { 4051865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood int count = 0; 406014897f5aece2c6212418934bd4618326979f17aYin Liu for (int i = 0; i <= MTP_STRING_MAX_CHARACTER_NUMBER; i++) { 4071865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood if (string[i]) 4081865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood count++; 4091865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood else 4101865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood break; 4111865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood } 412de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood putUInt8(count > 0 ? count + 1 : 0); 4131865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood for (int i = 0; i < count; i++) 4141865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood putUInt16(string[i]); 415de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood // only terminate with zero if string is not empty 416de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood if (count > 0) 417de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood putUInt16(0); 4181865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood} 4191865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood 42016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#ifdef MTP_DEVICE 42116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodint MtpDataPacket::read(int fd) { 42244c190826d72589f5c9e13d69e32673bd8bd7c64Mike Lockwood int ret = ::read(fd, mBuffer, MTP_BUFFER_SIZE); 423ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood if (ret < MTP_CONTAINER_HEADER_SIZE) 42416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return -1; 425ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood mPacketSize = ret; 42616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mOffset = MTP_CONTAINER_HEADER_SIZE; 42716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return ret; 42816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 42916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 43016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodint MtpDataPacket::write(int fd) { 43116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize); 43216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 433ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood int ret = ::write(fd, mBuffer, mPacketSize); 43416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return (ret < 0 ? ret : 0); 43516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 43664000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood 43764000788211f4c7e78c80a4a155390d1316e1176Mike Lockwoodint MtpDataPacket::writeData(int fd, void* data, uint32_t length) { 438ebb1081a624a773a67c49b279c775e18e693c4fcMarco Nelissen allocate(length + MTP_CONTAINER_HEADER_SIZE); 439ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood memcpy(mBuffer + MTP_CONTAINER_HEADER_SIZE, data, length); 440ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood length += MTP_CONTAINER_HEADER_SIZE; 441ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length); 44264000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 443ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood int ret = ::write(fd, mBuffer, length); 44464000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood return (ret < 0 ? ret : 0); 44564000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood} 44664000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood 44716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#endif // MTP_DEVICE 44816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 44916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#ifdef MTP_HOST 45042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::read(struct usb_request *request) { 45116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // first read the header 45242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer = mBuffer; 45342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer_length = mBufferSize; 45442d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood int length = transfer(request); 455437e945013318de54746422c8b44306e6d5319caMike Lockwood if (length >= MTP_CONTAINER_HEADER_SIZE) { 4563e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood // look at the length field to see if the data spans multiple packets 4573e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood uint32_t totalLength = MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET); 45833bde8d8c4fc71fb3cdd8356fd0df70ffb44fcd7Mike Lockwood allocate(totalLength); 459b3be006498f28f2630264135e88d266b540bcec3Daichi Hirono while (totalLength > static_cast<uint32_t>(length)) { 46042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer = mBuffer + length; 46133bde8d8c4fc71fb3cdd8356fd0df70ffb44fcd7Mike Lockwood request->buffer_length = totalLength - length; 46242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood int ret = transfer(request); 4633e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood if (ret >= 0) 4643e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood length += ret; 4653e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood else { 4663e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood length = ret; 4673e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood break; 4683e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood } 4693e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood } 4703e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood } 4713e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood if (length >= 0) 4723e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood mPacketSize = length; 4733e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood return length; 47416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 47516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 47642d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::readData(struct usb_request *request, void* buffer, int length) { 4770cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood int read = 0; 4780cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood while (read < length) { 47942d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer = (char *)buffer + read; 48042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer_length = length - read; 48142d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood int ret = transfer(request); 4820cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (ret < 0) { 4830cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood return ret; 4840cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 4850cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood read += ret; 4860cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 4870cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood return read; 4880cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood} 4890cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 490b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood// Queue a read request. Call readDataWait to wait for result 49142d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::readDataAsync(struct usb_request *req) { 49242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood if (usb_request_queue(req)) { 49329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("usb_endpoint_queue failed, errno: %d", errno); 494b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood return -1; 495b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood } 496b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood return 0; 497b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood} 498b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood 499b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood// Wait for result of readDataAsync 50042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::readDataWait(struct usb_device *device) { 50142d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood struct usb_request *req = usb_request_wait(device); 50242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood return (req ? req->actual_length : -1); 503b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood} 504b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood 50542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::readDataHeader(struct usb_request *request) { 50642d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer = mBuffer; 50742d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer_length = request->max_packet_size; 50842d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood int length = transfer(request); 5090cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (length >= 0) 5100cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mPacketSize = length; 5110cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood return length; 5120cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood} 5130cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 51442d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::writeDataHeader(struct usb_request *request, uint32_t length) { 5150cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length); 5160cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 51742d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer = mBuffer; 51842d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer_length = MTP_CONTAINER_HEADER_SIZE; 51942d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood int ret = transfer(request); 5200cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood return (ret < 0 ? ret : 0); 5210cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood} 5220cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 52342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::write(struct usb_request *request) { 52416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize); 52516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 52642d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer = mBuffer; 52764c948bf5041fdfe391553315c9d028e1ee56382Tomasz Mikolajewski request->buffer_length = mPacketSize; 52842d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood int ret = transfer(request); 52916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return (ret < 0 ? ret : 0); 53016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 53116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 53242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::write(struct usb_request *request, void* buffer, uint32_t length) { 53342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer = buffer; 53442d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer_length = length; 53542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood int ret = transfer(request); 5360cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood return (ret < 0 ? ret : 0); 5370cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood} 5380cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 53916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#endif // MTP_HOST 5407850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood 5414fd9a8b9865addfedbcd84d5c9efea0f647086a0Daichi Hironovoid* MtpDataPacket::getData(int* outLength) const { 5423e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood int length = mPacketSize - MTP_CONTAINER_HEADER_SIZE; 5433e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood if (length > 0) { 5443e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood void* result = malloc(length); 5453e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood if (result) { 5463e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood memcpy(result, mBuffer + MTP_CONTAINER_HEADER_SIZE, length); 5474fd9a8b9865addfedbcd84d5c9efea0f647086a0Daichi Hirono *outLength = length; 5483e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood return result; 5493e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood } 5503e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood } 5514fd9a8b9865addfedbcd84d5c9efea0f647086a0Daichi Hirono *outLength = 0; 5523e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood return NULL; 5533e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood} 5543e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood 5557850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood} // namespace android 556