MtpPacket.cpp revision f7454622eaac287d20ab43013d7015fe42b894f8
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
17b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#define LOG_TAG "MtpPacket"
18b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood
19b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#include "MtpDebug.h"
20b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#include "MtpPacket.h"
21b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#include "mtp.h"
22b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood
2316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <stdio.h>
2416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <stdlib.h>
2516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <stdio.h>
2616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
2716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#include <usbhost/usbhost.h>
2816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
297850ef999740f214a1990a9c090d3f3865d435aaMike Lockwoodnamespace android {
307850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood
3116864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpPacket::MtpPacket(int bufferSize)
3216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    :   mBuffer(NULL),
3316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mBufferSize(bufferSize),
3416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mAllocationIncrement(bufferSize),
3516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize(0)
3616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood{
3716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer = (uint8_t *)malloc(bufferSize);
3816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (!mBuffer) {
39b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood        LOGE("out of memory!");
4016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        abort();
4116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
4216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
4316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
4416864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpPacket::~MtpPacket() {
4516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mBuffer)
4616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        free(mBuffer);
4716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
4816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
4916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::reset() {
5016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    allocate(MTP_CONTAINER_HEADER_SIZE);
5116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mPacketSize = MTP_CONTAINER_HEADER_SIZE;
5216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    memset(mBuffer, 0, mBufferSize);
5316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
5416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
5516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::allocate(int length) {
5616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (length > mBufferSize) {
5716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        int newLength = length + mAllocationIncrement;
5816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mBuffer = (uint8_t *)realloc(mBuffer, newLength);
5916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        if (!mBuffer) {
60b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood            LOGE("out of memory!");
6116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood            abort();
6216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        }
6316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mBufferSize = newLength;
6416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
6516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
6616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
6716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::dump() {
68b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#define DUMP_BYTES_PER_ROW  16
69b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood    char buffer[500];
70b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood    char* bufptr = buffer;
71b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood
7216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    for (int i = 0; i < mPacketSize; i++) {
73b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood        sprintf(bufptr, "%02X ", mBuffer[i]);
74b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood        bufptr += strlen(bufptr);
75b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood        if (i % DUMP_BYTES_PER_ROW == (DUMP_BYTES_PER_ROW - 1)) {
76b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood            LOGV("%s", buffer);
77b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood            bufptr = buffer;
78b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood        }
79b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood    }
80b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood    if (bufptr != buffer) {
81b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood        // print last line
82b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood        LOGV("%s", buffer);
8316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
84b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood    LOGV("\n");
8516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
8616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
87f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwoodvoid MtpPacket::copyFrom(const MtpPacket& src) {
88f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood    int length = src.mPacketSize;
89f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood    allocate(length);
90f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood    mPacketSize = length;
91f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood    memcpy(mBuffer, src.mBuffer, length);
92f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood}
93f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood
9416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint16_t MtpPacket::getUInt16(int offset) const {
9516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset];
9616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
9716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
9816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint32_t MtpPacket::getUInt32(int offset) const {
9916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) |
10016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood           ((uint32_t)mBuffer[offset + 1] << 8)  | (uint32_t)mBuffer[offset];
10116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
10216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
10316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::putUInt16(int offset, uint16_t value) {
10416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[offset++] = (uint8_t)(value & 0xFF);
10516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
10616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
10716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
10816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::putUInt32(int offset, uint32_t value) {
10916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[offset++] = (uint8_t)(value & 0xFF);
11016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
11116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF);
11216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF);
11316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
11416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
11516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint16_t MtpPacket::getContainerCode() const {
11616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return getUInt16(MTP_CONTAINER_CODE_OFFSET);
11716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
11816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
11916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::setContainerCode(uint16_t code) {
12016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt16(MTP_CONTAINER_CODE_OFFSET, code);
12116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
12216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
123f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwooduint16_t MtpPacket::getContainerType() const {
124f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood    return getUInt16(MTP_CONTAINER_TYPE_OFFSET);
125f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood}
126f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood
12716864bae0f51c32c456da2c43adf7a057c0c4882Mike LockwoodMtpTransactionID MtpPacket::getTransactionID() const {
12816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return getUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET);
12916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
13016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
13116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::setTransactionID(MtpTransactionID id) {
13216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id);
13316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
13416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
13516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwooduint32_t MtpPacket::getParameter(int index) const {
13616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (index < 1 || index > 5) {
137d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood        LOGE("index %d out of range in MtpPacket::getParameter", index);
13816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        return 0;
13916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
14016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return getUInt32(MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t));
14116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
14216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
14316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodvoid MtpPacket::setParameter(int index, uint32_t value) {
14416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (index < 1 || index > 5) {
145d81ce3cf2e6479915658a0829eced062e3655320Mike Lockwood        LOGE("index %d out of range in MtpPacket::setParameter", index);
14616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        return;
14716864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
14816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    int offset = MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t);
14916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (mPacketSize < offset + sizeof(uint32_t))
15016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        mPacketSize = offset + sizeof(uint32_t);
15116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    putUInt32(offset, value);
15216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
15316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood
15416864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#ifdef MTP_HOST
15516864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwoodint MtpPacket::transfer(struct usb_endpoint *ep, void* buffer, int length) {
15616864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    if (usb_endpoint_queue(ep, buffer, length)) {
157b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood        LOGE("usb_endpoint_queue failed, errno: %d", errno);
15816864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood        return -1;
15916864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    }
16016864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    int ep_num;
16116864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood    return usb_endpoint_wait(usb_endpoint_get_device(ep), &ep_num);
16216864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood}
16316864bae0f51c32c456da2c43adf7a057c0c4882Mike Lockwood#endif
1647850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood
1657850ef999740f214a1990a9c090d3f3865d435aaMike Lockwood}  // namespace android
166