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