MtpPacket.cpp revision 7850ef999740f214a1990a9c090d3f3865d435aa
116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood/*
216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Copyright (C) 2010 The Android Open Source Project
316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood *
416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License");
516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * you may not use this file except in compliance with the License.
616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * You may obtain a copy of the License at
716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood *
816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood *      http://www.apache.org/licenses/LICENSE-2.0
916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood *
1016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * Unless required by applicable law or agreed to in writing, software
1116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS,
1216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * See the License for the specific language governing permissions and
1416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood * limitations under the License.
1516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood */
1616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
1716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <stdio.h>
1816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <stdlib.h>
1916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <stdio.h>
2016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
2116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <usbhost/usbhost.h>
2216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
2316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include "MtpPacket.h"
2416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
257850ef999740f214a1990a9c090d3f3865d435aaMike Lockwoodnamespace android {
267850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood
2716864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpPacket::MtpPacket(int bufferSize)
2816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    :   mBuffer(NULL),
2916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mBufferSize(bufferSize),
3016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mAllocationIncrement(bufferSize),
3116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize(0)
3216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood{
3316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer = (uint8_t *)malloc(bufferSize);
3416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (!mBuffer) {
3516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        fprintf(stderr, "out of memory!\n");
3616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        abort();
3716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
3816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
3916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
4016864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpPacket::~MtpPacket() {
4116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mBuffer)
4216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        free(mBuffer);
4316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
4416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
4516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::reset() {
4616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(MTP_CONTAINER_HEADER_SIZE);
4716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mPacketSize = MTP_CONTAINER_HEADER_SIZE;
4816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    memset(mBuffer, 0, mBufferSize);
4916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
5016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
5116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::allocate(int length) {
5216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (length > mBufferSize) {
5316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        int newLength = length + mAllocationIncrement;
5416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mBuffer = (uint8_t *)realloc(mBuffer, newLength);
5516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        if (!mBuffer) {
5616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            fprintf(stderr, "out of memory!\n");
5716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            abort();
5816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        }
5916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mBufferSize = newLength;
6016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
6116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
6216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
6316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::dump() {
6416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < mPacketSize; i++) {
6516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        printf("%02X ", mBuffer[i]);
6616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        if (i % 16 == 15)
6716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            printf("\n");
6816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
6916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    printf("\n\n");
7016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
7116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
7216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint16_t MtpPacket::getUInt16(int offset) const {
7316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset];
7416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
7516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
7616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint32_t MtpPacket::getUInt32(int offset) const {
7716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) |
7816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood           ((uint32_t)mBuffer[offset + 1] << 8)  | (uint32_t)mBuffer[offset];
7916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
8016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
8116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::putUInt16(int offset, uint16_t value) {
8216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[offset++] = (uint8_t)(value & 0xFF);
8316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
8416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
8516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
8616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::putUInt32(int offset, uint32_t value) {
8716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[offset++] = (uint8_t)(value & 0xFF);
8816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
8916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF);
9016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF);
9116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
9216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
9316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint16_t MtpPacket::getContainerCode() const {
9416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return getUInt16(MTP_CONTAINER_CODE_OFFSET);
9516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
9616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
9716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::setContainerCode(uint16_t code) {
9816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt16(MTP_CONTAINER_CODE_OFFSET, code);
9916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
10016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
10116864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpTransactionID MtpPacket::getTransactionID() const {
10216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return getUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET);
10316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
10416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
10516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::setTransactionID(MtpTransactionID id) {
10616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id);
10716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
10816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
10916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint32_t MtpPacket::getParameter(int index) const {
11016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (index < 1 || index > 5) {
11116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        fprintf(stderr, "index %d out of range in MtpRequestPacket::getParameter\n", index);
11216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        return 0;
11316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
11416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return getUInt32(MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t));
11516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
11616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
11716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::setParameter(int index, uint32_t value) {
11816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (index < 1 || index > 5) {
11916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        fprintf(stderr, "index %d out of range in MtpResponsePacket::setParameter\n", index);
12016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        return;
12116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
12216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    int offset = MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t);
12316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < offset + sizeof(uint32_t))
12416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = offset + sizeof(uint32_t);
12516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(offset, value);
12616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
12716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
12816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#ifdef MTP_HOST
12916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodint MtpPacket::transfer(struct usb_endpoint *ep, void* buffer, int length) {
13016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    printf("MtpPacket::transfer length: %d\n", length);
13116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (usb_endpoint_queue(ep, buffer, length)) {
13216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        printf("usb_endpoint_queue failed, errno: %d\n", errno);
13316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        return -1;
13416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
13516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    int ep_num;
13616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return usb_endpoint_wait(usb_endpoint_get_device(ep), &ep_num);
13716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
13816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#endif
1397850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood
1407850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood}  // namespace android
141