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
2844c190826d72589f5c9e13d69e32673bd8bd7c64Mike Lockwood#define MTP_BUFFER_SIZE 16384
2944c190826d72589f5c9e13d69e32673bd8bd7c64Mike Lockwood
307850ef999740f214a1990a9c090d3f3865d435aaMike Lockwoodnamespace android {
317850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood
3216864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpDataPacket::MtpDataPacket()
3344c190826d72589f5c9e13d69e32673bd8bd7c64Mike Lockwood    :   MtpPacket(MTP_BUFFER_SIZE),   // MAX_USBFS_BUFFER_SIZE
3416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mOffset(MTP_CONTAINER_HEADER_SIZE)
3516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood{
3616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
3716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
3816864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpDataPacket::~MtpDataPacket() {
3916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
4016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
4116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::reset() {
4216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    MtpPacket::reset();
4316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mOffset = MTP_CONTAINER_HEADER_SIZE;
4416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
4516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
4616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::setOperationCode(MtpOperationCode code) {
4716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    MtpPacket::putUInt16(MTP_CONTAINER_CODE_OFFSET, code);
4816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
4916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
5016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::setTransactionID(MtpTransactionID id) {
5116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    MtpPacket::putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id);
5216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
5316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
5416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint16_t MtpDataPacket::getUInt16() {
5516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    int offset = mOffset;
5616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    uint16_t result = (uint16_t)mBuffer[offset] | ((uint16_t)mBuffer[offset + 1] << 8);
5716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mOffset += 2;
5816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return result;
5916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
6016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
6116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint32_t MtpDataPacket::getUInt32() {
6216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    int offset = mOffset;
6316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    uint32_t result = (uint32_t)mBuffer[offset] | ((uint32_t)mBuffer[offset + 1] << 8) |
6416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood           ((uint32_t)mBuffer[offset + 2] << 16)  | ((uint32_t)mBuffer[offset + 3] << 24);
6516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mOffset += 4;
6616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return result;
6716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
6816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
6916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint64_t MtpDataPacket::getUInt64() {
7016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    int offset = mOffset;
7116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    uint64_t result = (uint64_t)mBuffer[offset] | ((uint64_t)mBuffer[offset + 1] << 8) |
7216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood           ((uint64_t)mBuffer[offset + 2] << 16) | ((uint64_t)mBuffer[offset + 3] << 24) |
7316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood           ((uint64_t)mBuffer[offset + 4] << 32) | ((uint64_t)mBuffer[offset + 5] << 40) |
7416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood           ((uint64_t)mBuffer[offset + 6] << 48)  | ((uint64_t)mBuffer[offset + 7] << 56);
7516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mOffset += 8;
7616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return result;
7716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
7816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
79a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwoodvoid MtpDataPacket::getUInt128(uint128_t& value) {
80a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    value[0] = getUInt32();
81a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    value[1] = getUInt32();
82a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    value[2] = getUInt32();
83a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    value[3] = getUInt32();
84a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood}
85a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
8616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::getString(MtpStringBuffer& string)
8716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood{
8816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    string.readFromPacket(this);
8916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
9016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
91335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodInt8List* MtpDataPacket::getAInt8() {
92335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    Int8List* result = new Int8List;
93335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    int count = getUInt32();
94335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    for (int i = 0; i < count; i++)
95335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood        result->push(getInt8());
96335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    return result;
97335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood}
98335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
99335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodUInt8List* MtpDataPacket::getAUInt8() {
100335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    UInt8List* result = new UInt8List;
101335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    int count = getUInt32();
102335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    for (int i = 0; i < count; i++)
103335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood        result->push(getUInt8());
104335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    return result;
105335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood}
106335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
107335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodInt16List* MtpDataPacket::getAInt16() {
108335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    Int16List* result = new Int16List;
109335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    int count = getUInt32();
110335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    for (int i = 0; i < count; i++)
111335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood        result->push(getInt16());
112335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    return result;
113335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood}
114335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
115335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodUInt16List* MtpDataPacket::getAUInt16() {
116335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    UInt16List* result = new UInt16List;
117335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    int count = getUInt32();
118335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    for (int i = 0; i < count; i++)
119335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood        result->push(getUInt16());
120335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    return result;
121335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood}
122335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
123335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodInt32List* MtpDataPacket::getAInt32() {
124335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    Int32List* result = new Int32List;
125335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    int count = getUInt32();
126335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    for (int i = 0; i < count; i++)
127335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood        result->push(getInt32());
128335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    return result;
129335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood}
130335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
131335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodUInt32List* MtpDataPacket::getAUInt32() {
132335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    UInt32List* result = new UInt32List;
133335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    int count = getUInt32();
134335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    for (int i = 0; i < count; i++)
135335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood        result->push(getUInt32());
136335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    return result;
137335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood}
138335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
139335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodInt64List* MtpDataPacket::getAInt64() {
140335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    Int64List* result = new Int64List;
141335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    int count = getUInt32();
142335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    for (int i = 0; i < count; i++)
143335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood        result->push(getInt64());
144335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    return result;
145335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood}
146335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
147335dd2be955607f2632eabc25045857f2cc8b674Mike LockwoodUInt64List* MtpDataPacket::getAUInt64() {
148335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    UInt64List* result = new UInt64List;
149335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    int count = getUInt32();
150335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    for (int i = 0; i < count; i++)
151335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood        result->push(getUInt64());
152335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood    return result;
153335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood}
154335dd2be955607f2632eabc25045857f2cc8b674Mike Lockwood
15516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putInt8(int8_t value) {
15616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(mOffset + 1);
15716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)value;
15816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < mOffset)
15916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = mOffset;
16016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
16116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
16216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putUInt8(uint8_t value) {
16316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(mOffset + 1);
16416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)value;
16516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < mOffset)
16616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = mOffset;
16716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
16816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
16916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putInt16(int16_t value) {
17016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(mOffset + 2);
17116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
17216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
17316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < mOffset)
17416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = mOffset;
17516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
17616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
17716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putUInt16(uint16_t value) {
17816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(mOffset + 2);
17916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
18016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
18116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < mOffset)
18216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = mOffset;
18316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
18416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
18516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putInt32(int32_t value) {
18616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(mOffset + 4);
18716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
18816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
18916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
19016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
19116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < mOffset)
19216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = mOffset;
19316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
19416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
19516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putUInt32(uint32_t value) {
19616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(mOffset + 4);
19716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
19816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
19916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
20016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
20116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < mOffset)
20216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = mOffset;
20316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
20416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
20516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putInt64(int64_t value) {
20616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(mOffset + 8);
20716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
20816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
20916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
21016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
21116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF);
21216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF);
21316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF);
21416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF);
21516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < mOffset)
21616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = mOffset;
21716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
21816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
21916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putUInt64(uint64_t value) {
22016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(mOffset + 8);
22116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
22216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
22316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
22416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
22516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF);
22616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF);
22716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF);
22816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF);
22916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < mOffset)
23016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = mOffset;
23116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
23216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
233a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwoodvoid MtpDataPacket::putInt128(const int128_t& value) {
234a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    putInt32(value[0]);
235a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    putInt32(value[1]);
236a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    putInt32(value[2]);
237a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    putInt32(value[3]);
238a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood}
239a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
240a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwoodvoid MtpDataPacket::putUInt128(const uint128_t& value) {
241a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    putUInt32(value[0]);
242a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    putUInt32(value[1]);
243a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    putUInt32(value[2]);
244a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood    putUInt32(value[3]);
245a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood}
246a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood
2478277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwoodvoid MtpDataPacket::putInt128(int64_t value) {
2488277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood    putInt64(value);
2495959988b63ace3fba2fc78b135a4f5ef25dcf860Mike Lockwood    putInt64(value < 0 ? -1 : 0);
2508277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood}
2518277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood
2528277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwoodvoid MtpDataPacket::putUInt128(uint64_t value) {
2538277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood    putUInt64(value);
2548277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood    putUInt64(0);
2558277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood}
2568277cec96ffa55082962591bca1c55abbeec8c26Mike Lockwood
25716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAInt8(const int8_t* values, int count) {
25816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(count);
25916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < count; i++)
26016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putInt8(*values++);
26116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
26216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
26316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt8(const uint8_t* values, int count) {
26416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(count);
26516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < count; i++)
26616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putUInt8(*values++);
26716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
26816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
26916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAInt16(const int16_t* values, int count) {
27016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(count);
27116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < count; i++)
27216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putInt16(*values++);
27316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
27416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
27516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt16(const uint16_t* values, int count) {
27616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(count);
27716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < count; i++)
27816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putUInt16(*values++);
27916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
28016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
281782aef17c9921a3bf401a0432878df5031f2328bMike Lockwoodvoid MtpDataPacket::putAUInt16(const UInt16List* values) {
282782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood    size_t count = (values ? values->size() : 0);
283782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood    putUInt32(count);
284782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood    for (size_t i = 0; i < count; i++)
285782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood        putUInt16((*values)[i]);
286782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood}
287782aef17c9921a3bf401a0432878df5031f2328bMike Lockwood
28816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAInt32(const int32_t* values, int count) {
28916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(count);
29016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < count; i++)
29116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putInt32(*values++);
29216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
29316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
29416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt32(const uint32_t* values, int count) {
29516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(count);
29616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < count; i++)
29716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putUInt32(*values++);
29816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
29916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
30016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt32(const UInt32List* list) {
30116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (!list) {
30216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putEmptyArray();
30316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    } else {
30416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        size_t size = list->size();
30516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putUInt32(size);
30616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        for (size_t i = 0; i < size; i++)
30716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            putUInt32((*list)[i]);
30816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
30916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
31016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
31116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAInt64(const int64_t* values, int count) {
31216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(count);
31316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < count; i++)
31416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putInt64(*values++);
31516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
31616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
31716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpDataPacket::putAUInt64(const uint64_t* values, int count) {
31816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(count);
31916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < count; i++)
32016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        putUInt64(*values++);
32116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
32216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
3231865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwoodvoid MtpDataPacket::putString(const MtpStringBuffer& string) {
32416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    string.writeToPacket(this);
32516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
32616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
3271865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwoodvoid MtpDataPacket::putString(const char* s) {
32816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    MtpStringBuffer string(s);
32916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    string.writeToPacket(this);
33016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
33116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
3321865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwoodvoid MtpDataPacket::putString(const uint16_t* string) {
3331865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood    int count = 0;
3341865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood    for (int i = 0; i < 256; i++) {
3351865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood        if (string[i])
3361865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood            count++;
3371865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood        else
3381865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood            break;
3391865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood    }
340de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood    putUInt8(count > 0 ? count + 1 : 0);
3411865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood    for (int i = 0; i < count; i++)
3421865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood        putUInt16(string[i]);
343de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood    // only terminate with zero if string is not empty
344de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood    if (count > 0)
345de1e37aad04640ef76f3c017b65adca087c7be0fMike Lockwood        putUInt16(0);
3461865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood}
3471865a5ddcfe7b0e8dc211419aea1094b1491a5fdMike Lockwood
34816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#ifdef MTP_DEVICE
34916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodint MtpDataPacket::read(int fd) {
35044c190826d72589f5c9e13d69e32673bd8bd7c64Mike Lockwood    int ret = ::read(fd, mBuffer, MTP_BUFFER_SIZE);
351ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood    if (ret < MTP_CONTAINER_HEADER_SIZE)
35216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        return -1;
353ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood    mPacketSize = ret;
35416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mOffset = MTP_CONTAINER_HEADER_SIZE;
35516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return ret;
35616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
35716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
35816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodint MtpDataPacket::write(int fd) {
35916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
36016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
361ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood    int ret = ::write(fd, mBuffer, mPacketSize);
36216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return (ret < 0 ? ret : 0);
36316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
36464000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood
36564000788211f4c7e78c80a4a155390d1316e1176Mike Lockwoodint MtpDataPacket::writeData(int fd, void* data, uint32_t length) {
366ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood    allocate(length);
367ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood    memcpy(mBuffer + MTP_CONTAINER_HEADER_SIZE, data, length);
368ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood    length += MTP_CONTAINER_HEADER_SIZE;
369ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood    MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length);
37064000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood    MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
371ef441d965504dbf31c5db690e5b34fcdcecd92ffMike Lockwood    int ret = ::write(fd, mBuffer, length);
37264000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood    return (ret < 0 ? ret : 0);
37364000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood}
37464000788211f4c7e78c80a4a155390d1316e1176Mike Lockwood
37516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#endif // MTP_DEVICE
37616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
37716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#ifdef MTP_HOST
37842d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::read(struct usb_request *request) {
37916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    // first read the header
38042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    request->buffer = mBuffer;
38142d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    request->buffer_length = mBufferSize;
38242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    int length = transfer(request);
383437e945013318de54746422c8b44306e6d5319caMike Lockwood    if (length >= MTP_CONTAINER_HEADER_SIZE) {
3843e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        // look at the length field to see if the data spans multiple packets
3853e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        uint32_t totalLength = MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET);
38633bde8d8c4fc71fb3cdd8356fd0df70ffb44fcd7Mike Lockwood        allocate(totalLength);
3873e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        while (totalLength > length) {
38842d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood            request->buffer = mBuffer + length;
38933bde8d8c4fc71fb3cdd8356fd0df70ffb44fcd7Mike Lockwood            request->buffer_length = totalLength - length;
39042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood            int ret = transfer(request);
3913e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood            if (ret >= 0)
3923e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood                length += ret;
3933e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood            else {
3943e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood                length = ret;
3953e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood                break;
3963e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood            }
3973e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        }
3983e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    }
3993e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    if (length >= 0)
4003e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        mPacketSize = length;
4013e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    return length;
40216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
40316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
40442d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::readData(struct usb_request *request, void* buffer, int length) {
4050cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    int read = 0;
4060cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    while (read < length) {
40742d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        request->buffer = (char *)buffer + read;
40842d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        request->buffer_length = length - read;
40942d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        int ret = transfer(request);
4100cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood        if (ret < 0) {
4110cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood            return ret;
4120cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood        }
4130cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood        read += ret;
4140cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    }
4150cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    return read;
4160cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood}
4170cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood
418b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood// Queue a read request.  Call readDataWait to wait for result
41942d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::readDataAsync(struct usb_request *req) {
42042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    if (usb_request_queue(req)) {
42129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("usb_endpoint_queue failed, errno: %d", errno);
422b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood        return -1;
423b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood    }
424b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood    return 0;
425b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood}
426b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood
427b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood// Wait for result of readDataAsync
42842d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::readDataWait(struct usb_device *device) {
42942d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    struct usb_request *req = usb_request_wait(device);
43042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    return (req ? req->actual_length : -1);
431b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood}
432b9ff444a7eaf7ffd43970c0477110c6808bd4a7cMike Lockwood
43342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::readDataHeader(struct usb_request *request) {
43442d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    request->buffer = mBuffer;
43542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    request->buffer_length = request->max_packet_size;
43642d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    int length = transfer(request);
4370cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    if (length >= 0)
4380cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood        mPacketSize = length;
4390cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    return length;
4400cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood}
4410cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood
44242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::writeDataHeader(struct usb_request *request, uint32_t length) {
4430cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length);
4440cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
44542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    request->buffer = mBuffer;
44642d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    request->buffer_length = MTP_CONTAINER_HEADER_SIZE;
44742d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    int ret = transfer(request);
4480cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    return (ret < 0 ? ret : 0);
4490cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood}
4500cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood
45142d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::write(struct usb_request *request) {
45216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
45316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
45416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
45516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    // send header separately from data
45642d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    request->buffer = mBuffer;
45742d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    request->buffer_length = MTP_CONTAINER_HEADER_SIZE;
45842d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    int ret = transfer(request);
45942d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    if (ret == MTP_CONTAINER_HEADER_SIZE) {
46042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        request->buffer = mBuffer + MTP_CONTAINER_HEADER_SIZE;
46142d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        request->buffer_length = mPacketSize - MTP_CONTAINER_HEADER_SIZE;
46242d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood        ret = transfer(request);
46342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    }
46416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return (ret < 0 ? ret : 0);
46516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
46616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
46742d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodint MtpDataPacket::write(struct usb_request *request, void* buffer, uint32_t length) {
46842d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    request->buffer = buffer;
46942d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    request->buffer_length = length;
47042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood    int ret = transfer(request);
4710cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood    return (ret < 0 ? ret : 0);
4720cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood}
4730cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood
47416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#endif // MTP_HOST
4757850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood
4763e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwoodvoid* MtpDataPacket::getData(int& outLength) const {
4773e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    int length = mPacketSize - MTP_CONTAINER_HEADER_SIZE;
4783e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    if (length > 0) {
4793e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        void* result = malloc(length);
4803e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        if (result) {
4813e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood            memcpy(result, mBuffer + MTP_CONTAINER_HEADER_SIZE, length);
4823e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood            outLength = length;
4833e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood            return result;
4843e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood        }
4853e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    }
4863e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    outLength = 0;
4873e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood    return NULL;
4883e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood}
4893e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood
4907850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood}  // namespace android
491