blob: d0ec2a6d42101e638ef306a4c831bc7bf684f2d5 [file] [log] [blame]
Mike Lockwood16864ba2010-05-11 17:16:59 -04001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Mike Lockwoodb14e5882010-06-29 18:11:52 -040017#define LOG_TAG "MtpDataPacket"
18
Mike Lockwood16864ba2010-05-11 17:16:59 -040019#include <stdio.h>
20#include <sys/types.h>
21#include <fcntl.h>
22
Mike Lockwood0cf89f22010-07-26 20:40:45 -040023#include <usbhost/usbhost.h>
24
Mike Lockwood16864ba2010-05-11 17:16:59 -040025#include "MtpDataPacket.h"
26#include "MtpStringBuffer.h"
27
Mike Lockwood7850ef92010-05-14 10:10:36 -040028namespace android {
29
Mike Lockwood16864ba2010-05-11 17:16:59 -040030MtpDataPacket::MtpDataPacket()
Mike Lockwood44c19082011-12-01 18:36:06 -050031 : MtpPacket(MTP_BUFFER_SIZE), // MAX_USBFS_BUFFER_SIZE
Mike Lockwood16864ba2010-05-11 17:16:59 -040032 mOffset(MTP_CONTAINER_HEADER_SIZE)
33{
34}
35
36MtpDataPacket::~MtpDataPacket() {
37}
38
39void MtpDataPacket::reset() {
40 MtpPacket::reset();
41 mOffset = MTP_CONTAINER_HEADER_SIZE;
42}
43
44void MtpDataPacket::setOperationCode(MtpOperationCode code) {
45 MtpPacket::putUInt16(MTP_CONTAINER_CODE_OFFSET, code);
46}
47
48void MtpDataPacket::setTransactionID(MtpTransactionID id) {
49 MtpPacket::putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id);
50}
51
Mike Lockwoodab063842014-11-12 14:20:06 -080052bool MtpDataPacket::getUInt8(uint8_t& value) {
53 if (mPacketSize - mOffset < sizeof(value))
54 return false;
55 value = mBuffer[mOffset++];
56 return true;
Mike Lockwood16864ba2010-05-11 17:16:59 -040057}
58
Mike Lockwoodab063842014-11-12 14:20:06 -080059bool MtpDataPacket::getUInt16(uint16_t& value) {
60 if (mPacketSize - mOffset < sizeof(value))
61 return false;
Mike Lockwood16864ba2010-05-11 17:16:59 -040062 int offset = mOffset;
Mike Lockwoodab063842014-11-12 14:20:06 -080063 value = (uint16_t)mBuffer[offset] | ((uint16_t)mBuffer[offset + 1] << 8);
64 mOffset += sizeof(value);
65 return true;
66}
67
68bool MtpDataPacket::getUInt32(uint32_t& value) {
69 if (mPacketSize - mOffset < sizeof(value))
70 return false;
71 int offset = mOffset;
72 value = (uint32_t)mBuffer[offset] | ((uint32_t)mBuffer[offset + 1] << 8) |
Mike Lockwood16864ba2010-05-11 17:16:59 -040073 ((uint32_t)mBuffer[offset + 2] << 16) | ((uint32_t)mBuffer[offset + 3] << 24);
Mike Lockwoodab063842014-11-12 14:20:06 -080074 mOffset += sizeof(value);
75 return true;
Mike Lockwood16864ba2010-05-11 17:16:59 -040076}
77
Mike Lockwoodab063842014-11-12 14:20:06 -080078bool MtpDataPacket::getUInt64(uint64_t& value) {
79 if (mPacketSize - mOffset < sizeof(value))
80 return false;
Mike Lockwood16864ba2010-05-11 17:16:59 -040081 int offset = mOffset;
Mike Lockwoodab063842014-11-12 14:20:06 -080082 value = (uint64_t)mBuffer[offset] | ((uint64_t)mBuffer[offset + 1] << 8) |
Mike Lockwood16864ba2010-05-11 17:16:59 -040083 ((uint64_t)mBuffer[offset + 2] << 16) | ((uint64_t)mBuffer[offset + 3] << 24) |
84 ((uint64_t)mBuffer[offset + 4] << 32) | ((uint64_t)mBuffer[offset + 5] << 40) |
85 ((uint64_t)mBuffer[offset + 6] << 48) | ((uint64_t)mBuffer[offset + 7] << 56);
Mike Lockwoodab063842014-11-12 14:20:06 -080086 mOffset += sizeof(value);
87 return true;
Mike Lockwood16864ba2010-05-11 17:16:59 -040088}
89
Mike Lockwoodab063842014-11-12 14:20:06 -080090bool MtpDataPacket::getUInt128(uint128_t& value) {
91 return getUInt32(value[0]) && getUInt32(value[1]) && getUInt32(value[2]) && getUInt32(value[3]);
Mike Lockwooda6c490b2010-06-05 22:45:01 -040092}
93
Mike Lockwoodab063842014-11-12 14:20:06 -080094bool MtpDataPacket::getString(MtpStringBuffer& string)
Mike Lockwood16864ba2010-05-11 17:16:59 -040095{
Mike Lockwoodab063842014-11-12 14:20:06 -080096 return string.readFromPacket(this);
Mike Lockwood16864ba2010-05-11 17:16:59 -040097}
98
Mike Lockwood335dd2b2010-05-19 10:33:39 -040099Int8List* MtpDataPacket::getAInt8() {
Mike Lockwoodab063842014-11-12 14:20:06 -0800100 uint32_t count;
101 if (!getUInt32(count))
102 return NULL;
Mike Lockwood335dd2b2010-05-19 10:33:39 -0400103 Int8List* result = new Int8List;
Mike Lockwoodab063842014-11-12 14:20:06 -0800104 for (uint32_t i = 0; i < count; i++) {
105 int8_t value;
106 if (!getInt8(value)) {
107 delete result;
108 return NULL;
109 }
110 result->push(value);
111 }
Mike Lockwood335dd2b2010-05-19 10:33:39 -0400112 return result;
113}
114
115UInt8List* MtpDataPacket::getAUInt8() {
Mike Lockwoodab063842014-11-12 14:20:06 -0800116 uint32_t count;
117 if (!getUInt32(count))
118 return NULL;
Mike Lockwood335dd2b2010-05-19 10:33:39 -0400119 UInt8List* result = new UInt8List;
Mike Lockwoodab063842014-11-12 14:20:06 -0800120 for (uint32_t i = 0; i < count; i++) {
121 uint8_t value;
122 if (!getUInt8(value)) {
123 delete result;
124 return NULL;
125 }
126 result->push(value);
127 }
Mike Lockwood335dd2b2010-05-19 10:33:39 -0400128 return result;
129}
130
131Int16List* MtpDataPacket::getAInt16() {
Mike Lockwoodab063842014-11-12 14:20:06 -0800132 uint32_t count;
133 if (!getUInt32(count))
134 return NULL;
Mike Lockwood335dd2b2010-05-19 10:33:39 -0400135 Int16List* result = new Int16List;
Mike Lockwoodab063842014-11-12 14:20:06 -0800136 for (uint32_t i = 0; i < count; i++) {
137 int16_t value;
138 if (!getInt16(value)) {
139 delete result;
140 return NULL;
141 }
142 result->push(value);
143 }
Mike Lockwood335dd2b2010-05-19 10:33:39 -0400144 return result;
145}
146
147UInt16List* MtpDataPacket::getAUInt16() {
Mike Lockwoodab063842014-11-12 14:20:06 -0800148 uint32_t count;
149 if (!getUInt32(count))
150 return NULL;
Mike Lockwood335dd2b2010-05-19 10:33:39 -0400151 UInt16List* result = new UInt16List;
Mike Lockwoodab063842014-11-12 14:20:06 -0800152 for (uint32_t i = 0; i < count; i++) {
153 uint16_t value;
154 if (!getUInt16(value)) {
155 delete result;
156 return NULL;
157 }
158 result->push(value);
159 }
Mike Lockwood335dd2b2010-05-19 10:33:39 -0400160 return result;
161}
162
163Int32List* MtpDataPacket::getAInt32() {
Mike Lockwoodab063842014-11-12 14:20:06 -0800164 uint32_t count;
165 if (!getUInt32(count))
166 return NULL;
Mike Lockwood335dd2b2010-05-19 10:33:39 -0400167 Int32List* result = new Int32List;
Mike Lockwoodab063842014-11-12 14:20:06 -0800168 for (uint32_t i = 0; i < count; i++) {
169 int32_t value;
170 if (!getInt32(value)) {
171 delete result;
172 return NULL;
173 }
174 result->push(value);
175 }
Mike Lockwood335dd2b2010-05-19 10:33:39 -0400176 return result;
177}
178
179UInt32List* MtpDataPacket::getAUInt32() {
Mike Lockwoodab063842014-11-12 14:20:06 -0800180 uint32_t count;
181 if (!getUInt32(count))
182 return NULL;
Mike Lockwood335dd2b2010-05-19 10:33:39 -0400183 UInt32List* result = new UInt32List;
Mike Lockwoodab063842014-11-12 14:20:06 -0800184 for (uint32_t i = 0; i < count; i++) {
185 uint32_t value;
186 if (!getUInt32(value)) {
187 delete result;
188 return NULL;
189 }
190 result->push(value);
191 }
Mike Lockwood335dd2b2010-05-19 10:33:39 -0400192 return result;
193}
194
195Int64List* MtpDataPacket::getAInt64() {
Mike Lockwoodab063842014-11-12 14:20:06 -0800196 uint32_t count;
197 if (!getUInt32(count))
198 return NULL;
Mike Lockwood335dd2b2010-05-19 10:33:39 -0400199 Int64List* result = new Int64List;
Mike Lockwoodab063842014-11-12 14:20:06 -0800200 for (uint32_t i = 0; i < count; i++) {
201 int64_t value;
202 if (!getInt64(value)) {
203 delete result;
204 return NULL;
205 }
206 result->push(value);
207 }
Mike Lockwood335dd2b2010-05-19 10:33:39 -0400208 return result;
209}
210
211UInt64List* MtpDataPacket::getAUInt64() {
Mike Lockwoodab063842014-11-12 14:20:06 -0800212 uint32_t count;
213 if (!getUInt32(count))
214 return NULL;
Mike Lockwood335dd2b2010-05-19 10:33:39 -0400215 UInt64List* result = new UInt64List;
Mike Lockwoodab063842014-11-12 14:20:06 -0800216 for (uint32_t i = 0; i < count; i++) {
217 uint64_t value;
218 if (!getUInt64(value)) {
219 delete result;
220 return NULL;
221 }
222 result->push(value);
223 }
Mike Lockwood335dd2b2010-05-19 10:33:39 -0400224 return result;
225}
226
Mike Lockwood16864ba2010-05-11 17:16:59 -0400227void MtpDataPacket::putInt8(int8_t value) {
228 allocate(mOffset + 1);
229 mBuffer[mOffset++] = (uint8_t)value;
230 if (mPacketSize < mOffset)
231 mPacketSize = mOffset;
232}
233
234void MtpDataPacket::putUInt8(uint8_t value) {
235 allocate(mOffset + 1);
236 mBuffer[mOffset++] = (uint8_t)value;
237 if (mPacketSize < mOffset)
238 mPacketSize = mOffset;
239}
240
241void MtpDataPacket::putInt16(int16_t value) {
242 allocate(mOffset + 2);
243 mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
244 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
245 if (mPacketSize < mOffset)
246 mPacketSize = mOffset;
247}
248
249void MtpDataPacket::putUInt16(uint16_t value) {
250 allocate(mOffset + 2);
251 mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
252 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
253 if (mPacketSize < mOffset)
254 mPacketSize = mOffset;
255}
256
257void MtpDataPacket::putInt32(int32_t value) {
258 allocate(mOffset + 4);
259 mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
260 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
261 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
262 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
263 if (mPacketSize < mOffset)
264 mPacketSize = mOffset;
265}
266
267void MtpDataPacket::putUInt32(uint32_t value) {
268 allocate(mOffset + 4);
269 mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
270 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
271 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
272 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
273 if (mPacketSize < mOffset)
274 mPacketSize = mOffset;
275}
276
277void MtpDataPacket::putInt64(int64_t value) {
278 allocate(mOffset + 8);
279 mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
280 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
281 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
282 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
283 mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF);
284 mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF);
285 mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF);
286 mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF);
287 if (mPacketSize < mOffset)
288 mPacketSize = mOffset;
289}
290
291void MtpDataPacket::putUInt64(uint64_t value) {
292 allocate(mOffset + 8);
293 mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
294 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
295 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
296 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
297 mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF);
298 mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF);
299 mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF);
300 mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF);
301 if (mPacketSize < mOffset)
302 mPacketSize = mOffset;
303}
304
Mike Lockwooda6c490b2010-06-05 22:45:01 -0400305void MtpDataPacket::putInt128(const int128_t& value) {
306 putInt32(value[0]);
307 putInt32(value[1]);
308 putInt32(value[2]);
309 putInt32(value[3]);
310}
311
312void MtpDataPacket::putUInt128(const uint128_t& value) {
313 putUInt32(value[0]);
314 putUInt32(value[1]);
315 putUInt32(value[2]);
316 putUInt32(value[3]);
317}
318
Mike Lockwood8277cec2010-08-10 15:20:35 -0400319void MtpDataPacket::putInt128(int64_t value) {
320 putInt64(value);
Mike Lockwood59599882010-08-25 19:10:24 -0400321 putInt64(value < 0 ? -1 : 0);
Mike Lockwood8277cec2010-08-10 15:20:35 -0400322}
323
324void MtpDataPacket::putUInt128(uint64_t value) {
325 putUInt64(value);
326 putUInt64(0);
327}
328
Mike Lockwood16864ba2010-05-11 17:16:59 -0400329void MtpDataPacket::putAInt8(const int8_t* values, int count) {
330 putUInt32(count);
331 for (int i = 0; i < count; i++)
332 putInt8(*values++);
333}
334
335void MtpDataPacket::putAUInt8(const uint8_t* values, int count) {
336 putUInt32(count);
337 for (int i = 0; i < count; i++)
338 putUInt8(*values++);
339}
340
341void MtpDataPacket::putAInt16(const int16_t* values, int count) {
342 putUInt32(count);
343 for (int i = 0; i < count; i++)
344 putInt16(*values++);
345}
346
347void MtpDataPacket::putAUInt16(const uint16_t* values, int count) {
348 putUInt32(count);
349 for (int i = 0; i < count; i++)
350 putUInt16(*values++);
351}
352
Mike Lockwood782aef12010-08-10 07:37:50 -0400353void MtpDataPacket::putAUInt16(const UInt16List* values) {
354 size_t count = (values ? values->size() : 0);
355 putUInt32(count);
356 for (size_t i = 0; i < count; i++)
357 putUInt16((*values)[i]);
358}
359
Mike Lockwood16864ba2010-05-11 17:16:59 -0400360void MtpDataPacket::putAInt32(const int32_t* values, int count) {
361 putUInt32(count);
362 for (int i = 0; i < count; i++)
363 putInt32(*values++);
364}
365
366void MtpDataPacket::putAUInt32(const uint32_t* values, int count) {
367 putUInt32(count);
368 for (int i = 0; i < count; i++)
369 putUInt32(*values++);
370}
371
372void MtpDataPacket::putAUInt32(const UInt32List* list) {
373 if (!list) {
374 putEmptyArray();
375 } else {
376 size_t size = list->size();
377 putUInt32(size);
378 for (size_t i = 0; i < size; i++)
379 putUInt32((*list)[i]);
380 }
381}
382
383void MtpDataPacket::putAInt64(const int64_t* values, int count) {
384 putUInt32(count);
385 for (int i = 0; i < count; i++)
386 putInt64(*values++);
387}
388
389void MtpDataPacket::putAUInt64(const uint64_t* values, int count) {
390 putUInt32(count);
391 for (int i = 0; i < count; i++)
392 putUInt64(*values++);
393}
394
Mike Lockwood1865a5d2010-07-03 00:44:05 -0400395void MtpDataPacket::putString(const MtpStringBuffer& string) {
Mike Lockwood16864ba2010-05-11 17:16:59 -0400396 string.writeToPacket(this);
397}
398
Mike Lockwood1865a5d2010-07-03 00:44:05 -0400399void MtpDataPacket::putString(const char* s) {
Mike Lockwood16864ba2010-05-11 17:16:59 -0400400 MtpStringBuffer string(s);
401 string.writeToPacket(this);
402}
403
Mike Lockwood1865a5d2010-07-03 00:44:05 -0400404void MtpDataPacket::putString(const uint16_t* string) {
405 int count = 0;
Yin Liu014897f2012-12-04 09:19:53 +0100406 for (int i = 0; i <= MTP_STRING_MAX_CHARACTER_NUMBER; i++) {
Mike Lockwood1865a5d2010-07-03 00:44:05 -0400407 if (string[i])
408 count++;
409 else
410 break;
411 }
Mike Lockwoodde1e37a2010-08-18 12:31:09 -0400412 putUInt8(count > 0 ? count + 1 : 0);
Mike Lockwood1865a5d2010-07-03 00:44:05 -0400413 for (int i = 0; i < count; i++)
414 putUInt16(string[i]);
Mike Lockwoodde1e37a2010-08-18 12:31:09 -0400415 // only terminate with zero if string is not empty
416 if (count > 0)
417 putUInt16(0);
Mike Lockwood1865a5d2010-07-03 00:44:05 -0400418}
419
Mike Lockwood16864ba2010-05-11 17:16:59 -0400420#ifdef MTP_DEVICE
421int MtpDataPacket::read(int fd) {
Mike Lockwood44c19082011-12-01 18:36:06 -0500422 int ret = ::read(fd, mBuffer, MTP_BUFFER_SIZE);
Mike Lockwoodef441d92011-07-14 21:00:02 -0400423 if (ret < MTP_CONTAINER_HEADER_SIZE)
Mike Lockwood16864ba2010-05-11 17:16:59 -0400424 return -1;
Mike Lockwoodef441d92011-07-14 21:00:02 -0400425 mPacketSize = ret;
Mike Lockwood16864ba2010-05-11 17:16:59 -0400426 mOffset = MTP_CONTAINER_HEADER_SIZE;
Mike Lockwood16864ba2010-05-11 17:16:59 -0400427 return ret;
428}
429
430int MtpDataPacket::write(int fd) {
431 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
432 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
Mike Lockwoodef441d92011-07-14 21:00:02 -0400433 int ret = ::write(fd, mBuffer, mPacketSize);
Mike Lockwood16864ba2010-05-11 17:16:59 -0400434 return (ret < 0 ? ret : 0);
435}
Mike Lockwood64000782011-04-24 18:40:17 -0700436
437int MtpDataPacket::writeData(int fd, void* data, uint32_t length) {
Marco Nelissenebb10812014-06-23 08:15:13 -0700438 allocate(length + MTP_CONTAINER_HEADER_SIZE);
Mike Lockwoodef441d92011-07-14 21:00:02 -0400439 memcpy(mBuffer + MTP_CONTAINER_HEADER_SIZE, data, length);
440 length += MTP_CONTAINER_HEADER_SIZE;
441 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length);
Mike Lockwood64000782011-04-24 18:40:17 -0700442 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
Mike Lockwoodef441d92011-07-14 21:00:02 -0400443 int ret = ::write(fd, mBuffer, length);
Mike Lockwood64000782011-04-24 18:40:17 -0700444 return (ret < 0 ? ret : 0);
445}
446
Mike Lockwood16864ba2010-05-11 17:16:59 -0400447#endif // MTP_DEVICE
448
449#ifdef MTP_HOST
Mike Lockwood42d0b792011-01-04 14:48:57 -0500450int MtpDataPacket::read(struct usb_request *request) {
Mike Lockwood16864ba2010-05-11 17:16:59 -0400451 // first read the header
Mike Lockwood42d0b792011-01-04 14:48:57 -0500452 request->buffer = mBuffer;
453 request->buffer_length = mBufferSize;
454 int length = transfer(request);
Mike Lockwood437e9452010-07-20 12:01:36 -0400455 if (length >= MTP_CONTAINER_HEADER_SIZE) {
Mike Lockwood3e072b32010-06-10 16:34:20 -0400456 // look at the length field to see if the data spans multiple packets
457 uint32_t totalLength = MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET);
Mike Lockwood33bde8d2011-03-12 14:03:23 -0500458 allocate(totalLength);
Mike Lockwood3e072b32010-06-10 16:34:20 -0400459 while (totalLength > length) {
Mike Lockwood42d0b792011-01-04 14:48:57 -0500460 request->buffer = mBuffer + length;
Mike Lockwood33bde8d2011-03-12 14:03:23 -0500461 request->buffer_length = totalLength - length;
Mike Lockwood42d0b792011-01-04 14:48:57 -0500462 int ret = transfer(request);
Mike Lockwood3e072b32010-06-10 16:34:20 -0400463 if (ret >= 0)
464 length += ret;
465 else {
466 length = ret;
467 break;
468 }
469 }
470 }
471 if (length >= 0)
472 mPacketSize = length;
473 return length;
Mike Lockwood16864ba2010-05-11 17:16:59 -0400474}
475
Mike Lockwood42d0b792011-01-04 14:48:57 -0500476int MtpDataPacket::readData(struct usb_request *request, void* buffer, int length) {
Mike Lockwood0cf89f22010-07-26 20:40:45 -0400477 int read = 0;
478 while (read < length) {
Mike Lockwood42d0b792011-01-04 14:48:57 -0500479 request->buffer = (char *)buffer + read;
480 request->buffer_length = length - read;
481 int ret = transfer(request);
Mike Lockwood0cf89f22010-07-26 20:40:45 -0400482 if (ret < 0) {
Mike Lockwood0cf89f22010-07-26 20:40:45 -0400483 return ret;
484 }
485 read += ret;
486 }
Mike Lockwood0cf89f22010-07-26 20:40:45 -0400487 return read;
488}
489
Mike Lockwoodb9ff4442010-11-19 11:20:19 -0500490// Queue a read request. Call readDataWait to wait for result
Mike Lockwood42d0b792011-01-04 14:48:57 -0500491int MtpDataPacket::readDataAsync(struct usb_request *req) {
492 if (usb_request_queue(req)) {
Steve Block29357bc2012-01-06 19:20:56 +0000493 ALOGE("usb_endpoint_queue failed, errno: %d", errno);
Mike Lockwoodb9ff4442010-11-19 11:20:19 -0500494 return -1;
495 }
496 return 0;
497}
498
499// Wait for result of readDataAsync
Mike Lockwood42d0b792011-01-04 14:48:57 -0500500int MtpDataPacket::readDataWait(struct usb_device *device) {
501 struct usb_request *req = usb_request_wait(device);
502 return (req ? req->actual_length : -1);
Mike Lockwoodb9ff4442010-11-19 11:20:19 -0500503}
504
Mike Lockwood42d0b792011-01-04 14:48:57 -0500505int MtpDataPacket::readDataHeader(struct usb_request *request) {
506 request->buffer = mBuffer;
507 request->buffer_length = request->max_packet_size;
508 int length = transfer(request);
Mike Lockwood0cf89f22010-07-26 20:40:45 -0400509 if (length >= 0)
510 mPacketSize = length;
511 return length;
512}
513
Mike Lockwood42d0b792011-01-04 14:48:57 -0500514int MtpDataPacket::writeDataHeader(struct usb_request *request, uint32_t length) {
Mike Lockwood0cf89f22010-07-26 20:40:45 -0400515 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length);
516 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
Mike Lockwood42d0b792011-01-04 14:48:57 -0500517 request->buffer = mBuffer;
518 request->buffer_length = MTP_CONTAINER_HEADER_SIZE;
519 int ret = transfer(request);
Mike Lockwood0cf89f22010-07-26 20:40:45 -0400520 return (ret < 0 ? ret : 0);
521}
522
Mike Lockwood42d0b792011-01-04 14:48:57 -0500523int MtpDataPacket::write(struct usb_request *request) {
Mike Lockwood16864ba2010-05-11 17:16:59 -0400524 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
525 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
Mike Lockwood42d0b792011-01-04 14:48:57 -0500526 request->buffer = mBuffer;
Tomasz Mikolajewski64c948b2015-08-13 15:31:02 +0900527 request->buffer_length = mPacketSize;
Mike Lockwood42d0b792011-01-04 14:48:57 -0500528 int ret = transfer(request);
Mike Lockwood16864ba2010-05-11 17:16:59 -0400529 return (ret < 0 ? ret : 0);
530}
531
Mike Lockwood42d0b792011-01-04 14:48:57 -0500532int MtpDataPacket::write(struct usb_request *request, void* buffer, uint32_t length) {
533 request->buffer = buffer;
534 request->buffer_length = length;
535 int ret = transfer(request);
Mike Lockwood0cf89f22010-07-26 20:40:45 -0400536 return (ret < 0 ? ret : 0);
537}
538
Mike Lockwood16864ba2010-05-11 17:16:59 -0400539#endif // MTP_HOST
Mike Lockwood7850ef92010-05-14 10:10:36 -0400540
Daichi Hirono4fd9a8b2015-08-20 15:13:40 +0900541void* MtpDataPacket::getData(int* outLength) const {
Mike Lockwood3e072b32010-06-10 16:34:20 -0400542 int length = mPacketSize - MTP_CONTAINER_HEADER_SIZE;
543 if (length > 0) {
544 void* result = malloc(length);
545 if (result) {
546 memcpy(result, mBuffer + MTP_CONTAINER_HEADER_SIZE, length);
Daichi Hirono4fd9a8b2015-08-20 15:13:40 +0900547 *outLength = length;
Mike Lockwood3e072b32010-06-10 16:34:20 -0400548 return result;
549 }
550 }
Daichi Hirono4fd9a8b2015-08-20 15:13:40 +0900551 *outLength = 0;
Mike Lockwood3e072b32010-06-10 16:34:20 -0400552 return NULL;
553}
554
Mike Lockwood7850ef92010-05-14 10:10:36 -0400555} // namespace android