MtpDataPacket.cpp revision ebb1081a624a773a67c49b279c775e18e693c4fc
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#define MTP_BUFFER_SIZE 16384
29
30namespace android {
31
32MtpDataPacket::MtpDataPacket()
33    :   MtpPacket(MTP_BUFFER_SIZE),   // MAX_USBFS_BUFFER_SIZE
34        mOffset(MTP_CONTAINER_HEADER_SIZE)
35{
36}
37
38MtpDataPacket::~MtpDataPacket() {
39}
40
41void MtpDataPacket::reset() {
42    MtpPacket::reset();
43    mOffset = MTP_CONTAINER_HEADER_SIZE;
44}
45
46void MtpDataPacket::setOperationCode(MtpOperationCode code) {
47    MtpPacket::putUInt16(MTP_CONTAINER_CODE_OFFSET, code);
48}
49
50void MtpDataPacket::setTransactionID(MtpTransactionID id) {
51    MtpPacket::putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id);
52}
53
54uint16_t MtpDataPacket::getUInt16() {
55    int offset = mOffset;
56    uint16_t result = (uint16_t)mBuffer[offset] | ((uint16_t)mBuffer[offset + 1] << 8);
57    mOffset += 2;
58    return result;
59}
60
61uint32_t MtpDataPacket::getUInt32() {
62    int offset = mOffset;
63    uint32_t result = (uint32_t)mBuffer[offset] | ((uint32_t)mBuffer[offset + 1] << 8) |
64           ((uint32_t)mBuffer[offset + 2] << 16)  | ((uint32_t)mBuffer[offset + 3] << 24);
65    mOffset += 4;
66    return result;
67}
68
69uint64_t MtpDataPacket::getUInt64() {
70    int offset = mOffset;
71    uint64_t result = (uint64_t)mBuffer[offset] | ((uint64_t)mBuffer[offset + 1] << 8) |
72           ((uint64_t)mBuffer[offset + 2] << 16) | ((uint64_t)mBuffer[offset + 3] << 24) |
73           ((uint64_t)mBuffer[offset + 4] << 32) | ((uint64_t)mBuffer[offset + 5] << 40) |
74           ((uint64_t)mBuffer[offset + 6] << 48)  | ((uint64_t)mBuffer[offset + 7] << 56);
75    mOffset += 8;
76    return result;
77}
78
79void MtpDataPacket::getUInt128(uint128_t& value) {
80    value[0] = getUInt32();
81    value[1] = getUInt32();
82    value[2] = getUInt32();
83    value[3] = getUInt32();
84}
85
86void MtpDataPacket::getString(MtpStringBuffer& string)
87{
88    string.readFromPacket(this);
89}
90
91Int8List* MtpDataPacket::getAInt8() {
92    Int8List* result = new Int8List;
93    int count = getUInt32();
94    for (int i = 0; i < count; i++)
95        result->push(getInt8());
96    return result;
97}
98
99UInt8List* MtpDataPacket::getAUInt8() {
100    UInt8List* result = new UInt8List;
101    int count = getUInt32();
102    for (int i = 0; i < count; i++)
103        result->push(getUInt8());
104    return result;
105}
106
107Int16List* MtpDataPacket::getAInt16() {
108    Int16List* result = new Int16List;
109    int count = getUInt32();
110    for (int i = 0; i < count; i++)
111        result->push(getInt16());
112    return result;
113}
114
115UInt16List* MtpDataPacket::getAUInt16() {
116    UInt16List* result = new UInt16List;
117    int count = getUInt32();
118    for (int i = 0; i < count; i++)
119        result->push(getUInt16());
120    return result;
121}
122
123Int32List* MtpDataPacket::getAInt32() {
124    Int32List* result = new Int32List;
125    int count = getUInt32();
126    for (int i = 0; i < count; i++)
127        result->push(getInt32());
128    return result;
129}
130
131UInt32List* MtpDataPacket::getAUInt32() {
132    UInt32List* result = new UInt32List;
133    int count = getUInt32();
134    for (int i = 0; i < count; i++)
135        result->push(getUInt32());
136    return result;
137}
138
139Int64List* MtpDataPacket::getAInt64() {
140    Int64List* result = new Int64List;
141    int count = getUInt32();
142    for (int i = 0; i < count; i++)
143        result->push(getInt64());
144    return result;
145}
146
147UInt64List* MtpDataPacket::getAUInt64() {
148    UInt64List* result = new UInt64List;
149    int count = getUInt32();
150    for (int i = 0; i < count; i++)
151        result->push(getUInt64());
152    return result;
153}
154
155void MtpDataPacket::putInt8(int8_t value) {
156    allocate(mOffset + 1);
157    mBuffer[mOffset++] = (uint8_t)value;
158    if (mPacketSize < mOffset)
159        mPacketSize = mOffset;
160}
161
162void MtpDataPacket::putUInt8(uint8_t value) {
163    allocate(mOffset + 1);
164    mBuffer[mOffset++] = (uint8_t)value;
165    if (mPacketSize < mOffset)
166        mPacketSize = mOffset;
167}
168
169void MtpDataPacket::putInt16(int16_t value) {
170    allocate(mOffset + 2);
171    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
172    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
173    if (mPacketSize < mOffset)
174        mPacketSize = mOffset;
175}
176
177void MtpDataPacket::putUInt16(uint16_t value) {
178    allocate(mOffset + 2);
179    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
180    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
181    if (mPacketSize < mOffset)
182        mPacketSize = mOffset;
183}
184
185void MtpDataPacket::putInt32(int32_t value) {
186    allocate(mOffset + 4);
187    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
188    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
189    mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
190    mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
191    if (mPacketSize < mOffset)
192        mPacketSize = mOffset;
193}
194
195void MtpDataPacket::putUInt32(uint32_t value) {
196    allocate(mOffset + 4);
197    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
198    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
199    mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
200    mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
201    if (mPacketSize < mOffset)
202        mPacketSize = mOffset;
203}
204
205void MtpDataPacket::putInt64(int64_t value) {
206    allocate(mOffset + 8);
207    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
208    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
209    mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
210    mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
211    mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF);
212    mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF);
213    mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF);
214    mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF);
215    if (mPacketSize < mOffset)
216        mPacketSize = mOffset;
217}
218
219void MtpDataPacket::putUInt64(uint64_t value) {
220    allocate(mOffset + 8);
221    mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
222    mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
223    mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
224    mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
225    mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF);
226    mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF);
227    mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF);
228    mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF);
229    if (mPacketSize < mOffset)
230        mPacketSize = mOffset;
231}
232
233void MtpDataPacket::putInt128(const int128_t& value) {
234    putInt32(value[0]);
235    putInt32(value[1]);
236    putInt32(value[2]);
237    putInt32(value[3]);
238}
239
240void MtpDataPacket::putUInt128(const uint128_t& value) {
241    putUInt32(value[0]);
242    putUInt32(value[1]);
243    putUInt32(value[2]);
244    putUInt32(value[3]);
245}
246
247void MtpDataPacket::putInt128(int64_t value) {
248    putInt64(value);
249    putInt64(value < 0 ? -1 : 0);
250}
251
252void MtpDataPacket::putUInt128(uint64_t value) {
253    putUInt64(value);
254    putUInt64(0);
255}
256
257void MtpDataPacket::putAInt8(const int8_t* values, int count) {
258    putUInt32(count);
259    for (int i = 0; i < count; i++)
260        putInt8(*values++);
261}
262
263void MtpDataPacket::putAUInt8(const uint8_t* values, int count) {
264    putUInt32(count);
265    for (int i = 0; i < count; i++)
266        putUInt8(*values++);
267}
268
269void MtpDataPacket::putAInt16(const int16_t* values, int count) {
270    putUInt32(count);
271    for (int i = 0; i < count; i++)
272        putInt16(*values++);
273}
274
275void MtpDataPacket::putAUInt16(const uint16_t* values, int count) {
276    putUInt32(count);
277    for (int i = 0; i < count; i++)
278        putUInt16(*values++);
279}
280
281void MtpDataPacket::putAUInt16(const UInt16List* values) {
282    size_t count = (values ? values->size() : 0);
283    putUInt32(count);
284    for (size_t i = 0; i < count; i++)
285        putUInt16((*values)[i]);
286}
287
288void MtpDataPacket::putAInt32(const int32_t* values, int count) {
289    putUInt32(count);
290    for (int i = 0; i < count; i++)
291        putInt32(*values++);
292}
293
294void MtpDataPacket::putAUInt32(const uint32_t* values, int count) {
295    putUInt32(count);
296    for (int i = 0; i < count; i++)
297        putUInt32(*values++);
298}
299
300void MtpDataPacket::putAUInt32(const UInt32List* list) {
301    if (!list) {
302        putEmptyArray();
303    } else {
304        size_t size = list->size();
305        putUInt32(size);
306        for (size_t i = 0; i < size; i++)
307            putUInt32((*list)[i]);
308    }
309}
310
311void MtpDataPacket::putAInt64(const int64_t* values, int count) {
312    putUInt32(count);
313    for (int i = 0; i < count; i++)
314        putInt64(*values++);
315}
316
317void MtpDataPacket::putAUInt64(const uint64_t* values, int count) {
318    putUInt32(count);
319    for (int i = 0; i < count; i++)
320        putUInt64(*values++);
321}
322
323void MtpDataPacket::putString(const MtpStringBuffer& string) {
324    string.writeToPacket(this);
325}
326
327void MtpDataPacket::putString(const char* s) {
328    MtpStringBuffer string(s);
329    string.writeToPacket(this);
330}
331
332void MtpDataPacket::putString(const uint16_t* string) {
333    int count = 0;
334    for (int i = 0; i <= MTP_STRING_MAX_CHARACTER_NUMBER; i++) {
335        if (string[i])
336            count++;
337        else
338            break;
339    }
340    putUInt8(count > 0 ? count + 1 : 0);
341    for (int i = 0; i < count; i++)
342        putUInt16(string[i]);
343    // only terminate with zero if string is not empty
344    if (count > 0)
345        putUInt16(0);
346}
347
348#ifdef MTP_DEVICE
349int MtpDataPacket::read(int fd) {
350    int ret = ::read(fd, mBuffer, MTP_BUFFER_SIZE);
351    if (ret < MTP_CONTAINER_HEADER_SIZE)
352        return -1;
353    mPacketSize = ret;
354    mOffset = MTP_CONTAINER_HEADER_SIZE;
355    return ret;
356}
357
358int MtpDataPacket::write(int fd) {
359    MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
360    MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
361    int ret = ::write(fd, mBuffer, mPacketSize);
362    return (ret < 0 ? ret : 0);
363}
364
365int MtpDataPacket::writeData(int fd, void* data, uint32_t length) {
366    allocate(length + MTP_CONTAINER_HEADER_SIZE);
367    memcpy(mBuffer + MTP_CONTAINER_HEADER_SIZE, data, length);
368    length += MTP_CONTAINER_HEADER_SIZE;
369    MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length);
370    MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
371    int ret = ::write(fd, mBuffer, length);
372    return (ret < 0 ? ret : 0);
373}
374
375#endif // MTP_DEVICE
376
377#ifdef MTP_HOST
378int MtpDataPacket::read(struct usb_request *request) {
379    // first read the header
380    request->buffer = mBuffer;
381    request->buffer_length = mBufferSize;
382    int length = transfer(request);
383    if (length >= MTP_CONTAINER_HEADER_SIZE) {
384        // look at the length field to see if the data spans multiple packets
385        uint32_t totalLength = MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET);
386        allocate(totalLength);
387        while (totalLength > length) {
388            request->buffer = mBuffer + length;
389            request->buffer_length = totalLength - length;
390            int ret = transfer(request);
391            if (ret >= 0)
392                length += ret;
393            else {
394                length = ret;
395                break;
396            }
397        }
398    }
399    if (length >= 0)
400        mPacketSize = length;
401    return length;
402}
403
404int MtpDataPacket::readData(struct usb_request *request, void* buffer, int length) {
405    int read = 0;
406    while (read < length) {
407        request->buffer = (char *)buffer + read;
408        request->buffer_length = length - read;
409        int ret = transfer(request);
410        if (ret < 0) {
411            return ret;
412        }
413        read += ret;
414    }
415    return read;
416}
417
418// Queue a read request.  Call readDataWait to wait for result
419int MtpDataPacket::readDataAsync(struct usb_request *req) {
420    if (usb_request_queue(req)) {
421        ALOGE("usb_endpoint_queue failed, errno: %d", errno);
422        return -1;
423    }
424    return 0;
425}
426
427// Wait for result of readDataAsync
428int MtpDataPacket::readDataWait(struct usb_device *device) {
429    struct usb_request *req = usb_request_wait(device);
430    return (req ? req->actual_length : -1);
431}
432
433int MtpDataPacket::readDataHeader(struct usb_request *request) {
434    request->buffer = mBuffer;
435    request->buffer_length = request->max_packet_size;
436    int length = transfer(request);
437    if (length >= 0)
438        mPacketSize = length;
439    return length;
440}
441
442int MtpDataPacket::writeDataHeader(struct usb_request *request, uint32_t length) {
443    MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length);
444    MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
445    request->buffer = mBuffer;
446    request->buffer_length = MTP_CONTAINER_HEADER_SIZE;
447    int ret = transfer(request);
448    return (ret < 0 ? ret : 0);
449}
450
451int MtpDataPacket::write(struct usb_request *request) {
452    MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
453    MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
454
455    // send header separately from data
456    request->buffer = mBuffer;
457    request->buffer_length = MTP_CONTAINER_HEADER_SIZE;
458    int ret = transfer(request);
459    if (ret == MTP_CONTAINER_HEADER_SIZE) {
460        request->buffer = mBuffer + MTP_CONTAINER_HEADER_SIZE;
461        request->buffer_length = mPacketSize - MTP_CONTAINER_HEADER_SIZE;
462        ret = transfer(request);
463    }
464    return (ret < 0 ? ret : 0);
465}
466
467int MtpDataPacket::write(struct usb_request *request, void* buffer, uint32_t length) {
468    request->buffer = buffer;
469    request->buffer_length = length;
470    int ret = transfer(request);
471    return (ret < 0 ? ret : 0);
472}
473
474#endif // MTP_HOST
475
476void* MtpDataPacket::getData(int& outLength) const {
477    int length = mPacketSize - MTP_CONTAINER_HEADER_SIZE;
478    if (length > 0) {
479        void* result = malloc(length);
480        if (result) {
481            memcpy(result, mBuffer + MTP_CONTAINER_HEADER_SIZE, length);
482            outLength = length;
483            return result;
484        }
485    }
486    outLength = 0;
487    return NULL;
488}
489
490}  // namespace android
491