1 /*
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
17 #define LOG_TAG "MtpDataPacket"
18
19 #include <stdio.h>
20 #include <sys/types.h>
21 #include <fcntl.h>
22
23 #include <usbhost/usbhost.h>
24
25 #include "MtpDataPacket.h"
26 #include "MtpStringBuffer.h"
27
28 namespace android {
29
MtpDataPacket()30 MtpDataPacket::MtpDataPacket()
31 : MtpPacket(MTP_BUFFER_SIZE), // MAX_USBFS_BUFFER_SIZE
32 mOffset(MTP_CONTAINER_HEADER_SIZE)
33 {
34 }
35
~MtpDataPacket()36 MtpDataPacket::~MtpDataPacket() {
37 }
38
reset()39 void MtpDataPacket::reset() {
40 MtpPacket::reset();
41 mOffset = MTP_CONTAINER_HEADER_SIZE;
42 }
43
setOperationCode(MtpOperationCode code)44 void MtpDataPacket::setOperationCode(MtpOperationCode code) {
45 MtpPacket::putUInt16(MTP_CONTAINER_CODE_OFFSET, code);
46 }
47
setTransactionID(MtpTransactionID id)48 void MtpDataPacket::setTransactionID(MtpTransactionID id) {
49 MtpPacket::putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id);
50 }
51
getUInt8(uint8_t & value)52 bool MtpDataPacket::getUInt8(uint8_t& value) {
53 if (mPacketSize - mOffset < sizeof(value))
54 return false;
55 value = mBuffer[mOffset++];
56 return true;
57 }
58
getUInt16(uint16_t & value)59 bool MtpDataPacket::getUInt16(uint16_t& value) {
60 if (mPacketSize - mOffset < sizeof(value))
61 return false;
62 int offset = mOffset;
63 value = (uint16_t)mBuffer[offset] | ((uint16_t)mBuffer[offset + 1] << 8);
64 mOffset += sizeof(value);
65 return true;
66 }
67
getUInt32(uint32_t & value)68 bool 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) |
73 ((uint32_t)mBuffer[offset + 2] << 16) | ((uint32_t)mBuffer[offset + 3] << 24);
74 mOffset += sizeof(value);
75 return true;
76 }
77
getUInt64(uint64_t & value)78 bool MtpDataPacket::getUInt64(uint64_t& value) {
79 if (mPacketSize - mOffset < sizeof(value))
80 return false;
81 int offset = mOffset;
82 value = (uint64_t)mBuffer[offset] | ((uint64_t)mBuffer[offset + 1] << 8) |
83 ((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);
86 mOffset += sizeof(value);
87 return true;
88 }
89
getUInt128(uint128_t & value)90 bool MtpDataPacket::getUInt128(uint128_t& value) {
91 return getUInt32(value[0]) && getUInt32(value[1]) && getUInt32(value[2]) && getUInt32(value[3]);
92 }
93
getString(MtpStringBuffer & string)94 bool MtpDataPacket::getString(MtpStringBuffer& string)
95 {
96 return string.readFromPacket(this);
97 }
98
getAInt8()99 Int8List* MtpDataPacket::getAInt8() {
100 uint32_t count;
101 if (!getUInt32(count))
102 return NULL;
103 Int8List* result = new Int8List;
104 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 }
112 return result;
113 }
114
getAUInt8()115 UInt8List* MtpDataPacket::getAUInt8() {
116 uint32_t count;
117 if (!getUInt32(count))
118 return NULL;
119 UInt8List* result = new UInt8List;
120 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 }
128 return result;
129 }
130
getAInt16()131 Int16List* MtpDataPacket::getAInt16() {
132 uint32_t count;
133 if (!getUInt32(count))
134 return NULL;
135 Int16List* result = new Int16List;
136 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 }
144 return result;
145 }
146
getAUInt16()147 UInt16List* MtpDataPacket::getAUInt16() {
148 uint32_t count;
149 if (!getUInt32(count))
150 return NULL;
151 UInt16List* result = new UInt16List;
152 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 }
160 return result;
161 }
162
getAInt32()163 Int32List* MtpDataPacket::getAInt32() {
164 uint32_t count;
165 if (!getUInt32(count))
166 return NULL;
167 Int32List* result = new Int32List;
168 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 }
176 return result;
177 }
178
getAUInt32()179 UInt32List* MtpDataPacket::getAUInt32() {
180 uint32_t count;
181 if (!getUInt32(count))
182 return NULL;
183 UInt32List* result = new UInt32List;
184 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 }
192 return result;
193 }
194
getAInt64()195 Int64List* MtpDataPacket::getAInt64() {
196 uint32_t count;
197 if (!getUInt32(count))
198 return NULL;
199 Int64List* result = new Int64List;
200 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 }
208 return result;
209 }
210
getAUInt64()211 UInt64List* MtpDataPacket::getAUInt64() {
212 uint32_t count;
213 if (!getUInt32(count))
214 return NULL;
215 UInt64List* result = new UInt64List;
216 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 }
224 return result;
225 }
226
putInt8(int8_t value)227 void MtpDataPacket::putInt8(int8_t value) {
228 allocate(mOffset + 1);
229 mBuffer[mOffset++] = (uint8_t)value;
230 if (mPacketSize < mOffset)
231 mPacketSize = mOffset;
232 }
233
putUInt8(uint8_t value)234 void MtpDataPacket::putUInt8(uint8_t value) {
235 allocate(mOffset + 1);
236 mBuffer[mOffset++] = (uint8_t)value;
237 if (mPacketSize < mOffset)
238 mPacketSize = mOffset;
239 }
240
putInt16(int16_t value)241 void 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
putUInt16(uint16_t value)249 void 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
putInt32(int32_t value)257 void 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
putUInt32(uint32_t value)267 void 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
putInt64(int64_t value)277 void 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
putUInt64(uint64_t value)291 void 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
putInt128(const int128_t & value)305 void MtpDataPacket::putInt128(const int128_t& value) {
306 putInt32(value[0]);
307 putInt32(value[1]);
308 putInt32(value[2]);
309 putInt32(value[3]);
310 }
311
putUInt128(const uint128_t & value)312 void MtpDataPacket::putUInt128(const uint128_t& value) {
313 putUInt32(value[0]);
314 putUInt32(value[1]);
315 putUInt32(value[2]);
316 putUInt32(value[3]);
317 }
318
putInt128(int64_t value)319 void MtpDataPacket::putInt128(int64_t value) {
320 putInt64(value);
321 putInt64(value < 0 ? -1 : 0);
322 }
323
putUInt128(uint64_t value)324 void MtpDataPacket::putUInt128(uint64_t value) {
325 putUInt64(value);
326 putUInt64(0);
327 }
328
putAInt8(const int8_t * values,int count)329 void MtpDataPacket::putAInt8(const int8_t* values, int count) {
330 putUInt32(count);
331 for (int i = 0; i < count; i++)
332 putInt8(*values++);
333 }
334
putAUInt8(const uint8_t * values,int count)335 void MtpDataPacket::putAUInt8(const uint8_t* values, int count) {
336 putUInt32(count);
337 for (int i = 0; i < count; i++)
338 putUInt8(*values++);
339 }
340
putAInt16(const int16_t * values,int count)341 void MtpDataPacket::putAInt16(const int16_t* values, int count) {
342 putUInt32(count);
343 for (int i = 0; i < count; i++)
344 putInt16(*values++);
345 }
346
putAUInt16(const uint16_t * values,int count)347 void MtpDataPacket::putAUInt16(const uint16_t* values, int count) {
348 putUInt32(count);
349 for (int i = 0; i < count; i++)
350 putUInt16(*values++);
351 }
352
putAUInt16(const UInt16List * values)353 void 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
putAInt32(const int32_t * values,int count)360 void MtpDataPacket::putAInt32(const int32_t* values, int count) {
361 putUInt32(count);
362 for (int i = 0; i < count; i++)
363 putInt32(*values++);
364 }
365
putAUInt32(const uint32_t * values,int count)366 void MtpDataPacket::putAUInt32(const uint32_t* values, int count) {
367 putUInt32(count);
368 for (int i = 0; i < count; i++)
369 putUInt32(*values++);
370 }
371
putAUInt32(const UInt32List * list)372 void 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
putAInt64(const int64_t * values,int count)383 void MtpDataPacket::putAInt64(const int64_t* values, int count) {
384 putUInt32(count);
385 for (int i = 0; i < count; i++)
386 putInt64(*values++);
387 }
388
putAUInt64(const uint64_t * values,int count)389 void MtpDataPacket::putAUInt64(const uint64_t* values, int count) {
390 putUInt32(count);
391 for (int i = 0; i < count; i++)
392 putUInt64(*values++);
393 }
394
putString(const MtpStringBuffer & string)395 void MtpDataPacket::putString(const MtpStringBuffer& string) {
396 string.writeToPacket(this);
397 }
398
putString(const char * s)399 void MtpDataPacket::putString(const char* s) {
400 MtpStringBuffer string(s);
401 string.writeToPacket(this);
402 }
403
putString(const uint16_t * string)404 void MtpDataPacket::putString(const uint16_t* string) {
405 int count = 0;
406 for (int i = 0; i <= MTP_STRING_MAX_CHARACTER_NUMBER; i++) {
407 if (string[i])
408 count++;
409 else
410 break;
411 }
412 putUInt8(count > 0 ? count + 1 : 0);
413 for (int i = 0; i < count; i++)
414 putUInt16(string[i]);
415 // only terminate with zero if string is not empty
416 if (count > 0)
417 putUInt16(0);
418 }
419
420 #ifdef MTP_DEVICE
read(int fd)421 int MtpDataPacket::read(int fd) {
422 int ret = ::read(fd, mBuffer, MTP_BUFFER_SIZE);
423 if (ret < MTP_CONTAINER_HEADER_SIZE)
424 return -1;
425 mPacketSize = ret;
426 mOffset = MTP_CONTAINER_HEADER_SIZE;
427 return ret;
428 }
429
write(int fd)430 int MtpDataPacket::write(int fd) {
431 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
432 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
433 int ret = ::write(fd, mBuffer, mPacketSize);
434 return (ret < 0 ? ret : 0);
435 }
436
writeData(int fd,void * data,uint32_t length)437 int MtpDataPacket::writeData(int fd, void* data, uint32_t length) {
438 allocate(length + MTP_CONTAINER_HEADER_SIZE);
439 memcpy(mBuffer + MTP_CONTAINER_HEADER_SIZE, data, length);
440 length += MTP_CONTAINER_HEADER_SIZE;
441 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length);
442 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
443 int ret = ::write(fd, mBuffer, length);
444 return (ret < 0 ? ret : 0);
445 }
446
447 #endif // MTP_DEVICE
448
449 #ifdef MTP_HOST
read(struct usb_request * request)450 int MtpDataPacket::read(struct usb_request *request) {
451 // first read the header
452 request->buffer = mBuffer;
453 request->buffer_length = mBufferSize;
454 int length = transfer(request);
455 if (length >= MTP_CONTAINER_HEADER_SIZE) {
456 // look at the length field to see if the data spans multiple packets
457 uint32_t totalLength = MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET);
458 allocate(totalLength);
459 while (totalLength > static_cast<uint32_t>(length)) {
460 request->buffer = mBuffer + length;
461 request->buffer_length = totalLength - length;
462 int ret = transfer(request);
463 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;
474 }
475
readData(struct usb_request * request,void * buffer,int length)476 int MtpDataPacket::readData(struct usb_request *request, void* buffer, int length) {
477 int read = 0;
478 while (read < length) {
479 request->buffer = (char *)buffer + read;
480 request->buffer_length = length - read;
481 int ret = transfer(request);
482 if (ret < 0) {
483 return ret;
484 }
485 read += ret;
486 }
487 return read;
488 }
489
490 // Queue a read request. Call readDataWait to wait for result
readDataAsync(struct usb_request * req)491 int MtpDataPacket::readDataAsync(struct usb_request *req) {
492 if (usb_request_queue(req)) {
493 ALOGE("usb_endpoint_queue failed, errno: %d", errno);
494 return -1;
495 }
496 return 0;
497 }
498
499 // Wait for result of readDataAsync
readDataWait(struct usb_device * device)500 int MtpDataPacket::readDataWait(struct usb_device *device) {
501 struct usb_request *req = usb_request_wait(device);
502 return (req ? req->actual_length : -1);
503 }
504
readDataHeader(struct usb_request * request)505 int MtpDataPacket::readDataHeader(struct usb_request *request) {
506 request->buffer = mBuffer;
507 request->buffer_length = request->max_packet_size;
508 int length = transfer(request);
509 if (length >= 0)
510 mPacketSize = length;
511 return length;
512 }
513
writeDataHeader(struct usb_request * request,uint32_t length)514 int MtpDataPacket::writeDataHeader(struct usb_request *request, uint32_t length) {
515 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length);
516 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
517 request->buffer = mBuffer;
518 request->buffer_length = MTP_CONTAINER_HEADER_SIZE;
519 int ret = transfer(request);
520 return (ret < 0 ? ret : 0);
521 }
522
write(struct usb_request * request)523 int MtpDataPacket::write(struct usb_request *request) {
524 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
525 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
526 request->buffer = mBuffer;
527 request->buffer_length = mPacketSize;
528 int ret = transfer(request);
529 return (ret < 0 ? ret : 0);
530 }
531
write(struct usb_request * request,void * buffer,uint32_t length)532 int 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);
536 return (ret < 0 ? ret : 0);
537 }
538
539 #endif // MTP_HOST
540
getData(int * outLength) const541 void* MtpDataPacket::getData(int* outLength) const {
542 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);
547 *outLength = length;
548 return result;
549 }
550 }
551 *outLength = 0;
552 return NULL;
553 }
554
555 } // namespace android
556