blob: 9d6f875c698d7040224abbcea2e52e595e3599b6 [file] [log] [blame]
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -04001/*
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 *
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -05008 * http://www.apache.org/licenses/LICENSE-2.0
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -04009 *
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.
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040015 */
16
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -050017#define LOG_TAG "MtpPacket"
18
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040019#include "MtpDebug.h"
20#include "MtpPacket.h"
21#include "mtp.h"
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <stdio.h>
26
27#include <usbhost/usbhost.h>
28
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040029MtpPacket::MtpPacket(int bufferSize)
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -050030 : mBuffer(NULL),
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040031 mBufferSize(bufferSize),
32 mAllocationIncrement(bufferSize),
33 mPacketSize(0)
34{
35 mBuffer = (uint8_t *)malloc(bufferSize);
36 if (!mBuffer) {
37 MTPE("out of memory!");
38 abort();
39 }
40}
41
42MtpPacket::~MtpPacket() {
43 if (mBuffer)
44 free(mBuffer);
45}
46
47void MtpPacket::reset() {
48 allocate(MTP_CONTAINER_HEADER_SIZE);
49 mPacketSize = MTP_CONTAINER_HEADER_SIZE;
50 memset(mBuffer, 0, mBufferSize);
51}
52
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -050053void MtpPacket::allocate(size_t length) {
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040054 if (length > mBufferSize) {
55 int newLength = length + mAllocationIncrement;
56 mBuffer = (uint8_t *)realloc(mBuffer, newLength);
57 if (!mBuffer) {
58 MTPE("out of memory!");
59 abort();
60 }
61 mBufferSize = newLength;
62 }
63}
64
65void MtpPacket::dump() {
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -050066#define DUMP_BYTES_PER_ROW 16
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040067 char buffer[500];
68 char* bufptr = buffer;
69
70 for (size_t i = 0; i < mPacketSize; i++) {
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -050071 bufptr += snprintf(bufptr, sizeof(buffer) - (bufptr - buffer), "%02X ",
72 mBuffer[i]);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040073 if (i % DUMP_BYTES_PER_ROW == (DUMP_BYTES_PER_ROW - 1)) {
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -050074 ALOGV("%s", buffer);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040075 bufptr = buffer;
76 }
77 }
78 if (bufptr != buffer) {
79 // print last line
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -050080 ALOGV("%s", buffer);
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040081 }
bigbiff bigbiffaf32bb92018-12-18 18:39:53 -050082 ALOGV("\n");
bigbiff bigbiffc7eee6f2014-09-02 18:59:01 -040083}
84
85void MtpPacket::copyFrom(const MtpPacket& src) {
86 int length = src.mPacketSize;
87 allocate(length);
88 mPacketSize = length;
89 memcpy(mBuffer, src.mBuffer, length);
90}
91
92uint16_t MtpPacket::getUInt16(int offset) const {
93 return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset];
94}
95
96uint32_t MtpPacket::getUInt32(int offset) const {
97 return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) |
98 ((uint32_t)mBuffer[offset + 1] << 8) | (uint32_t)mBuffer[offset];
99}
100
101void MtpPacket::putUInt16(int offset, uint16_t value) {
102 mBuffer[offset++] = (uint8_t)(value & 0xFF);
103 mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
104}
105
106void MtpPacket::putUInt32(int offset, uint32_t value) {
107 mBuffer[offset++] = (uint8_t)(value & 0xFF);
108 mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
109 mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF);
110 mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF);
111}
112
113uint16_t MtpPacket::getContainerCode() const {
114 return getUInt16(MTP_CONTAINER_CODE_OFFSET);
115}
116
117void MtpPacket::setContainerCode(uint16_t code) {
118 putUInt16(MTP_CONTAINER_CODE_OFFSET, code);
119}
120
121uint16_t MtpPacket::getContainerType() const {
122 return getUInt16(MTP_CONTAINER_TYPE_OFFSET);
123}
124
125MtpTransactionID MtpPacket::getTransactionID() const {
126 return getUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET);
127}
128
129void MtpPacket::setTransactionID(MtpTransactionID id) {
130 putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id);
131}
132
133uint32_t MtpPacket::getParameter(int index) const {
134 if (index < 1 || index > 5) {
135 MTPE("index %d out of range in MtpPacket::getParameter", index);
136 return 0;
137 }
138 return getUInt32(MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t));
139}
140
141void MtpPacket::setParameter(int index, uint32_t value) {
142 if (index < 1 || index > 5) {
143 MTPE("index %d out of range in MtpPacket::setParameter", index);
144 return;
145 }
146 int offset = MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t);
147 if (mPacketSize < offset + sizeof(uint32_t))
148 mPacketSize = offset + sizeof(uint32_t);
149 putUInt32(offset, value);
150}
151
152#ifdef MTP_HOST
153int MtpPacket::transfer(struct usb_request* request) {
154 int result = usb_device_bulk_transfer(request->dev,
155 request->endpoint,
156 request->buffer,
157 request->buffer_length,
158 0);
159 request->actual_length = result;
160 return result;
161}
162#endif