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 19d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono#include "MtpDataPacket.h" 20d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono 21d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono#include <algorithm> 22bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang#include <errno.h> 23d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono#include <fcntl.h> 2416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <stdio.h> 2516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <sys/types.h> 260cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood#include <usbhost/usbhost.h> 2716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "MtpStringBuffer.h" 28487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include "IMtpHandle.h" 2916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 307850ef999740f214a1990a9c090d3f3865d435aaMike Lockwoodnamespace android { 317850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood 32d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirononamespace { 33d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono// Reads the exact |count| bytes from |fd| to |buf|. 34d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono// Returns |count| if it succeed to read the bytes. Otherwise returns -1. If it reaches EOF, the 35d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono// function regards it as an error. 36d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hironossize_t readExactBytes(int fd, void* buf, size_t count) { 37d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono if (count > SSIZE_MAX) { 38d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono return -1; 39d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono } 40d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono size_t read_count = 0; 41d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono while (read_count < count) { 42d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono int result = read(fd, static_cast<int8_t*>(buf) + read_count, count - read_count); 43d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono // Assume that EOF is error. 44d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono if (result <= 0) { 45d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono return -1; 46d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono } 47d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono read_count += result; 48d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono } 49d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono return read_count == count ? count : -1; 50d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono} 51d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono} // namespace 52d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono 5316864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpDataPacket::MtpDataPacket() 5444c190826d72589f5c9e13d69e32673bd8bd7c64Mike Lockwood : MtpPacket(MTP_BUFFER_SIZE), // MAX_USBFS_BUFFER_SIZE 5516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mOffset(MTP_CONTAINER_HEADER_SIZE) 5616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood{ 5716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 5816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 5916864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpDataPacket::~MtpDataPacket() { 6016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 6116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 6216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::reset() { 6316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpPacket::reset(); 6416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mOffset = MTP_CONTAINER_HEADER_SIZE; 6516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 6616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 6716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::setOperationCode(MtpOperationCode code) { 6816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpPacket::putUInt16(MTP_CONTAINER_CODE_OFFSET, code); 6916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 7016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 7116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::setTransactionID(MtpTransactionID id) { 7216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpPacket::putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id); 7316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 7416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 75ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getUInt8(uint8_t& value) { 76ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (mPacketSize - mOffset < sizeof(value)) 77ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return false; 78ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood value = mBuffer[mOffset++]; 79ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return true; 80ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood} 81ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood 82ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getUInt16(uint16_t& value) { 83ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (mPacketSize - mOffset < sizeof(value)) 84ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return false; 8516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int offset = mOffset; 86ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood value = (uint16_t)mBuffer[offset] | ((uint16_t)mBuffer[offset + 1] << 8); 87ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mOffset += sizeof(value); 88ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return true; 8916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 9016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 91ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getUInt32(uint32_t& value) { 92ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (mPacketSize - mOffset < sizeof(value)) 93ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return false; 9416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int offset = mOffset; 95ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood value = (uint32_t)mBuffer[offset] | ((uint32_t)mBuffer[offset + 1] << 8) | 9616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ((uint32_t)mBuffer[offset + 2] << 16) | ((uint32_t)mBuffer[offset + 3] << 24); 97ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mOffset += sizeof(value); 98ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return true; 9916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 10016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 101ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getUInt64(uint64_t& value) { 102ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (mPacketSize - mOffset < sizeof(value)) 103ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return false; 10416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood int offset = mOffset; 105ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood value = (uint64_t)mBuffer[offset] | ((uint64_t)mBuffer[offset + 1] << 8) | 10616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ((uint64_t)mBuffer[offset + 2] << 16) | ((uint64_t)mBuffer[offset + 3] << 24) | 10716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ((uint64_t)mBuffer[offset + 4] << 32) | ((uint64_t)mBuffer[offset + 5] << 40) | 10816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood ((uint64_t)mBuffer[offset + 6] << 48) | ((uint64_t)mBuffer[offset + 7] << 56); 109ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood mOffset += sizeof(value); 110ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return true; 11116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 11216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 113ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getUInt128(uint128_t& value) { 114ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return getUInt32(value[0]) && getUInt32(value[1]) && getUInt32(value[2]) && getUInt32(value[3]); 115a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood} 116a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood 117ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwoodbool MtpDataPacket::getString(MtpStringBuffer& string) 11816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood{ 119ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return string.readFromPacket(this); 12016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 12116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 122335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodInt8List* MtpDataPacket::getAInt8() { 123ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t count; 124ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(count)) 125ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 126335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood Int8List* result = new Int8List; 127ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood for (uint32_t i = 0; i < count; i++) { 128ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood int8_t value; 129ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getInt8(value)) { 130ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood delete result; 131ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 132ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 133bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang result->push_back(value); 134ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 135335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood return result; 136335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood} 137335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 138335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodUInt8List* MtpDataPacket::getAUInt8() { 139ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t count; 140ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(count)) 141ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 142335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood UInt8List* result = new UInt8List; 143ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood for (uint32_t i = 0; i < count; i++) { 144ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint8_t value; 145ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt8(value)) { 146ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood delete result; 147ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 148ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 149bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang result->push_back(value); 150ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 151335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood return result; 152335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood} 153335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 154335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodInt16List* MtpDataPacket::getAInt16() { 155ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t count; 156ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(count)) 157ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 158335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood Int16List* result = new Int16List; 159ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood for (uint32_t i = 0; i < count; i++) { 160ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood int16_t value; 161ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getInt16(value)) { 162ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood delete result; 163ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 164ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 165bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang result->push_back(value); 166ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 167335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood return result; 168335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood} 169335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 170335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodUInt16List* MtpDataPacket::getAUInt16() { 171ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t count; 172ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(count)) 173ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 174335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood UInt16List* result = new UInt16List; 175ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood for (uint32_t i = 0; i < count; i++) { 176ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint16_t value; 177ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt16(value)) { 178ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood delete result; 179ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 180ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 181bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang result->push_back(value); 182ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 183335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood return result; 184335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood} 185335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 186335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodInt32List* MtpDataPacket::getAInt32() { 187ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t count; 188ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(count)) 189ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 190335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood Int32List* result = new Int32List; 191ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood for (uint32_t i = 0; i < count; i++) { 192ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood int32_t value; 193ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getInt32(value)) { 194ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood delete result; 195ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 196ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 197bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang result->push_back(value); 198ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 199335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood return result; 200335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood} 201335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 202335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodUInt32List* MtpDataPacket::getAUInt32() { 203ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t count; 204ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(count)) 205ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 206335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood UInt32List* result = new UInt32List; 207ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood for (uint32_t i = 0; i < count; i++) { 208ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t value; 209ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(value)) { 210ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood delete result; 211ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 212ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 213bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang result->push_back(value); 214ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 215335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood return result; 216335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood} 217335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 218335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodInt64List* MtpDataPacket::getAInt64() { 219ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t count; 220ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(count)) 221ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 222335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood Int64List* result = new Int64List; 223ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood for (uint32_t i = 0; i < count; i++) { 224ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood int64_t value; 225ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getInt64(value)) { 226ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood delete result; 227ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 228ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 229bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang result->push_back(value); 230ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 231335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood return result; 232335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood} 233335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 234335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodUInt64List* MtpDataPacket::getAUInt64() { 235ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint32_t count; 236ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt32(count)) 237ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 238335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood UInt64List* result = new UInt64List; 239ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood for (uint32_t i = 0; i < count; i++) { 240ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood uint64_t value; 241ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood if (!getUInt64(value)) { 242ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood delete result; 243ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood return NULL; 244ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 245bc1d4b41f4df1b6dd04801ea5a526d23f5321340Jerry Zhang result->push_back(value); 246ab063847e6e893740749029a04cce1f6b7345ed5Mike Lockwood } 247335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood return result; 248335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood} 249335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood 25016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putInt8(int8_t value) { 25116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(mOffset + 1); 25216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)value; 25316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < mOffset) 25416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = mOffset; 25516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 25616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 25716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putUInt8(uint8_t value) { 25816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(mOffset + 1); 25916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)value; 26016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < mOffset) 26116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = mOffset; 26216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 26316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 26416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putInt16(int16_t value) { 26516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(mOffset + 2); 26616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 26716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 26816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < mOffset) 26916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = mOffset; 27016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 27116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 27216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putUInt16(uint16_t value) { 27316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(mOffset + 2); 27416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 27516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 27616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < mOffset) 27716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = mOffset; 27816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 27916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 28016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putInt32(int32_t value) { 28116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(mOffset + 4); 28216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 28316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 28416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 28516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 28616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < mOffset) 28716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = mOffset; 28816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 28916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 29016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putUInt32(uint32_t value) { 29116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(mOffset + 4); 29216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 29316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 29416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 29516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 29616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < mOffset) 29716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = mOffset; 29816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 29916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 30016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putInt64(int64_t value) { 30116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(mOffset + 8); 30216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 30316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 30416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 30516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 30616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF); 30716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF); 30816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF); 30916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF); 31016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < mOffset) 31116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = mOffset; 31216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 31316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 31416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putUInt64(uint64_t value) { 31516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood allocate(mOffset + 8); 31616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 31716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 31816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 31916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 32016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF); 32116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF); 32216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF); 32316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF); 32416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (mPacketSize < mOffset) 32516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mPacketSize = mOffset; 32616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 32716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 328a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwoodvoid MtpDataPacket::putInt128(const int128_t& value) { 329a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood putInt32(value[0]); 330a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood putInt32(value[1]); 331a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood putInt32(value[2]); 332a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood putInt32(value[3]); 333a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood} 334a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood 335a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwoodvoid MtpDataPacket::putUInt128(const uint128_t& value) { 336a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood putUInt32(value[0]); 337a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood putUInt32(value[1]); 338a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood putUInt32(value[2]); 339a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood putUInt32(value[3]); 340a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood} 341a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood 3428277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwoodvoid MtpDataPacket::putInt128(int64_t value) { 3438277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood putInt64(value); 3445959988b63ace3fba2fc78b135a4f5ef25dcf860Mike Lockwood putInt64(value < 0 ? -1 : 0); 3458277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood} 3468277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 3478277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwoodvoid MtpDataPacket::putUInt128(uint64_t value) { 3488277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood putUInt64(value); 3498277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood putUInt64(0); 3508277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood} 3518277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood 35216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAInt8(const int8_t* values, int count) { 35316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(count); 35416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 35516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putInt8(*values++); 35616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 35716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 35816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt8(const uint8_t* values, int count) { 35916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(count); 36016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 36116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt8(*values++); 36216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 36316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 36416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAInt16(const int16_t* values, int count) { 36516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(count); 36616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 36716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putInt16(*values++); 36816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 36916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 37016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt16(const uint16_t* values, int count) { 37116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(count); 37216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 37316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt16(*values++); 37416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 37516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 376782aef17c9921a3bf401a0432878df5031f2328bMike Lockwoodvoid MtpDataPacket::putAUInt16(const UInt16List* values) { 377782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood size_t count = (values ? values->size() : 0); 378782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood putUInt32(count); 379782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood for (size_t i = 0; i < count; i++) 380782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood putUInt16((*values)[i]); 381782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood} 382782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood 38316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAInt32(const int32_t* values, int count) { 38416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(count); 38516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 38616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putInt32(*values++); 38716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 38816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 38916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt32(const uint32_t* values, int count) { 39016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(count); 39116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 39216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(*values++); 39316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 39416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 39516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt32(const UInt32List* list) { 39616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood if (!list) { 39716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putEmptyArray(); 39816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } else { 39916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood size_t size = list->size(); 40016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(size); 40116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (size_t i = 0; i < size; i++) 40216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32((*list)[i]); 40316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood } 40416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 40516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 40616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAInt64(const int64_t* values, int count) { 40716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(count); 40816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 40916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putInt64(*values++); 41016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 41116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 41216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt64(const uint64_t* values, int count) { 41316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt32(count); 41416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood for (int i = 0; i < count; i++) 41516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood putUInt64(*values++); 41616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 41716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 4181865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwoodvoid MtpDataPacket::putString(const MtpStringBuffer& string) { 41916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood string.writeToPacket(this); 42016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 42116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 4221865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwoodvoid MtpDataPacket::putString(const char* s) { 42316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpStringBuffer string(s); 42416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood string.writeToPacket(this); 42516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 42616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 4271865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwoodvoid MtpDataPacket::putString(const uint16_t* string) { 4281865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood int count = 0; 429014897f5aece2c6212418934bd4618326979f17aYin Liu for (int i = 0; i <= MTP_STRING_MAX_CHARACTER_NUMBER; i++) { 4301865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood if (string[i]) 4311865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood count++; 4321865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood else 4331865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood break; 4341865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood } 435de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood putUInt8(count > 0 ? count + 1 : 0); 4361865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood for (int i = 0; i < count; i++) 4371865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood putUInt16(string[i]); 438de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood // only terminate with zero if string is not empty 439de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood if (count > 0) 440de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood putUInt16(0); 4411865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood} 4421865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood 443487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#ifdef MTP_DEVICE 444487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint MtpDataPacket::read(IMtpHandle *h) { 445487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang int ret = h->read(mBuffer, MTP_BUFFER_SIZE); 446ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood if (ret < MTP_CONTAINER_HEADER_SIZE) 44716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return -1; 448ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood mPacketSize = ret; 44916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood mOffset = MTP_CONTAINER_HEADER_SIZE; 45016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return ret; 45116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 45216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 453487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint MtpDataPacket::write(IMtpHandle *h) { 45416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize); 45516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 456487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang int ret = h->write(mBuffer, mPacketSize); 45716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood return (ret < 0 ? ret : 0); 45816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 45964000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood 460487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint MtpDataPacket::writeData(IMtpHandle *h, void* data, uint32_t length) { 461ebb1081a624a773a67c49b279c775e18e693c4fcMarco Nelissen allocate(length + MTP_CONTAINER_HEADER_SIZE); 462ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood memcpy(mBuffer + MTP_CONTAINER_HEADER_SIZE, data, length); 463ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood length += MTP_CONTAINER_HEADER_SIZE; 464ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length); 46564000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 466487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang int ret = h->write(mBuffer, length); 46764000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood return (ret < 0 ? ret : 0); 46864000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood} 46964000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood 47016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#endif // MTP_DEVICE 47116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 47216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#ifdef MTP_HOST 47342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::read(struct usb_request *request) { 47416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood // first read the header 47542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer = mBuffer; 47642d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer_length = mBufferSize; 47742d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood int length = transfer(request); 478437e945013318de54746422c8b44306e6d5319caMike Lockwood if (length >= MTP_CONTAINER_HEADER_SIZE) { 4793e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood // look at the length field to see if the data spans multiple packets 4803e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood uint32_t totalLength = MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET); 48133bde8d8c4fc71fb3cdd8356fd0df70ffb44fcd7Mike Lockwood allocate(totalLength); 482b3be006498f28f2630264135e88d266b540bcec3Daichi Hirono while (totalLength > static_cast<uint32_t>(length)) { 48342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer = mBuffer + length; 48433bde8d8c4fc71fb3cdd8356fd0df70ffb44fcd7Mike Lockwood request->buffer_length = totalLength - length; 48542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood int ret = transfer(request); 4863e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood if (ret >= 0) 4873e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood length += ret; 4883e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood else { 4893e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood length = ret; 4903e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood break; 4913e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood } 4923e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood } 4933e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood } 4943e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood if (length >= 0) 4953e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood mPacketSize = length; 4963e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood return length; 49716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 49816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 49942d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::readData(struct usb_request *request, void* buffer, int length) { 5000cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood int read = 0; 5010cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood while (read < length) { 50242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer = (char *)buffer + read; 50342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer_length = length - read; 50442d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood int ret = transfer(request); 5050cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (ret < 0) { 5060cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood return ret; 5070cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 5080cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood read += ret; 5090cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 5100cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood return read; 5110cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood} 5120cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 513b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood// Queue a read request. Call readDataWait to wait for result 51442d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::readDataAsync(struct usb_request *req) { 51542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood if (usb_request_queue(req)) { 51629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("usb_endpoint_queue failed, errno: %d", errno); 517b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood return -1; 518b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood } 519b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood return 0; 520b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood} 521b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood 522b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood// Wait for result of readDataAsync 52342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::readDataWait(struct usb_device *device) { 524cb8d8af1ad71ca7b800d298376dec7e6b1c1c766Philip P. Moltmann struct usb_request *req = usb_request_wait(device, -1); 52542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood return (req ? req->actual_length : -1); 526b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood} 527b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood 52842d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::readDataHeader(struct usb_request *request) { 52942d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer = mBuffer; 53042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood request->buffer_length = request->max_packet_size; 53142d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood int length = transfer(request); 5320cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (length >= 0) 5330cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood mPacketSize = length; 5340cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood return length; 5350cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood} 5360cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 537d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hironoint MtpDataPacket::write(struct usb_request *request, UrbPacketDivisionMode divisionMode) { 538d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono if (mPacketSize < MTP_CONTAINER_HEADER_SIZE || mPacketSize > MTP_BUFFER_SIZE) { 539d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono ALOGE("Illegal packet size."); 540d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono return -1; 541d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono } 5420cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 54316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize); 54416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 545d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono 546d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono size_t processedBytes = 0; 547d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono while (processedBytes < mPacketSize) { 548d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono const size_t write_size = 549d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono processedBytes == 0 && divisionMode == FIRST_PACKET_ONLY_HEADER ? 550d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono MTP_CONTAINER_HEADER_SIZE : mPacketSize - processedBytes; 551d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono request->buffer = mBuffer + processedBytes; 552d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono request->buffer_length = write_size; 553d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono const int result = transfer(request); 554d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono if (result < 0) { 555d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono ALOGE("Failed to write bytes to the device."); 556d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono return -1; 557d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono } 558d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono processedBytes += result; 559d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono } 560d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono 561d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono return processedBytes == mPacketSize ? processedBytes : -1; 56216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood} 56316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood 564d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hironoint MtpDataPacket::write(struct usb_request *request, 565d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono UrbPacketDivisionMode divisionMode, 566d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono int fd, 567d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono size_t payloadSize) { 568d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono // Obtain the greatest multiple of minimum packet size that is not greater than 569d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono // MTP_BUFFER_SIZE. 570d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono if (request->max_packet_size <= 0) { 571d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono ALOGE("Cannot determine bulk transfer size due to illegal max packet size %d.", 572d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono request->max_packet_size); 573d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono return -1; 574d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono } 575d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono const size_t maxBulkTransferSize = 576d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono MTP_BUFFER_SIZE - (MTP_BUFFER_SIZE % request->max_packet_size); 577d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono const size_t containerLength = payloadSize + MTP_CONTAINER_HEADER_SIZE; 578d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono size_t processedBytes = 0; 579d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono bool readError = false; 580d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono 581d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono // Bind the packet with given request. 582d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono request->buffer = mBuffer; 583d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono allocate(maxBulkTransferSize); 584d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono 585d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono while (processedBytes < containerLength) { 586d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono size_t bulkTransferSize = 0; 587d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono 588d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono // prepare header. 589d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono const bool headerSent = processedBytes != 0; 590d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono if (!headerSent) { 591d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, containerLength); 592d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 593d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono bulkTransferSize += MTP_CONTAINER_HEADER_SIZE; 594d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono } 595d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono 596d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono // Prepare payload. 597d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono if (headerSent || divisionMode == FIRST_PACKET_HAS_PAYLOAD) { 598d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono const size_t processedPayloadBytes = 599d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono headerSent ? processedBytes - MTP_CONTAINER_HEADER_SIZE : 0; 600d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono const size_t maxRead = payloadSize - processedPayloadBytes; 601d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono const size_t maxWrite = maxBulkTransferSize - bulkTransferSize; 602d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono const size_t bulkTransferPayloadSize = std::min(maxRead, maxWrite); 603d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono // prepare payload. 604d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono if (!readError) { 605d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono const ssize_t result = readExactBytes( 606d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono fd, 607d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono mBuffer + bulkTransferSize, 608d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono bulkTransferPayloadSize); 609d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono if (result < 0) { 610d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono ALOGE("Found an error while reading data from FD. Send 0 data instead."); 611d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono readError = true; 612d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono } 613d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono } 614d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono if (readError) { 615d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono memset(mBuffer + bulkTransferSize, 0, bulkTransferPayloadSize); 616d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono } 617d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono bulkTransferSize += bulkTransferPayloadSize; 618d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono } 619d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono 620d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono // Bulk transfer. 621d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono mPacketSize = bulkTransferSize; 622d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono request->buffer_length = bulkTransferSize; 623d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono const int result = transfer(request); 624d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono if (result != static_cast<ssize_t>(bulkTransferSize)) { 625d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono // Cannot recover writing error. 626d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono ALOGE("Found an error while write data to MtpDevice."); 627d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono return -1; 628d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono } 629d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono 630d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono // Update variables. 631d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono processedBytes += bulkTransferSize; 632d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono } 633d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono 634d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono return readError ? -1 : processedBytes; 6350cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood} 6360cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 63716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#endif // MTP_HOST 6387850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood 6394fd9a8b9865addfedbcd84d5c9efea0f647086a0Daichi Hironovoid* MtpDataPacket::getData(int* outLength) const { 6403e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood int length = mPacketSize - MTP_CONTAINER_HEADER_SIZE; 6413e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood if (length > 0) { 6423e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood void* result = malloc(length); 6433e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood if (result) { 6443e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood memcpy(result, mBuffer + MTP_CONTAINER_HEADER_SIZE, length); 6454fd9a8b9865addfedbcd84d5c9efea0f647086a0Daichi Hirono *outLength = length; 6463e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood return result; 6473e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood } 6483e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood } 6494fd9a8b9865addfedbcd84d5c9efea0f647086a0Daichi Hirono *outLength = 0; 6503e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood return NULL; 6513e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood} 6523e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood 6537850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood} // namespace android 654