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