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