blob: 71dcaee716e04f5abfa132b3e3e29f1f90542127 [file] [log] [blame]
Mike Lockwood16864ba2010-05-11 17:16:59 -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 *
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#include <stdio.h>
18#include <sys/types.h>
19#include <fcntl.h>
20
21#include "MtpDataPacket.h"
22#include "MtpStringBuffer.h"
23
Mike Lockwood7850ef92010-05-14 10:10:36 -040024namespace android {
25
Mike Lockwood16864ba2010-05-11 17:16:59 -040026MtpDataPacket::MtpDataPacket()
27 : MtpPacket(512),
28 mOffset(MTP_CONTAINER_HEADER_SIZE)
29{
30}
31
32MtpDataPacket::~MtpDataPacket() {
33}
34
35void MtpDataPacket::reset() {
36 MtpPacket::reset();
37 mOffset = MTP_CONTAINER_HEADER_SIZE;
38}
39
40void MtpDataPacket::setOperationCode(MtpOperationCode code) {
41 MtpPacket::putUInt16(MTP_CONTAINER_CODE_OFFSET, code);
42}
43
44void MtpDataPacket::setTransactionID(MtpTransactionID id) {
45 MtpPacket::putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id);
46}
47
48uint16_t MtpDataPacket::getUInt16() {
49 int offset = mOffset;
50 uint16_t result = (uint16_t)mBuffer[offset] | ((uint16_t)mBuffer[offset + 1] << 8);
51 mOffset += 2;
52 return result;
53}
54
55uint32_t MtpDataPacket::getUInt32() {
56 int offset = mOffset;
57 uint32_t result = (uint32_t)mBuffer[offset] | ((uint32_t)mBuffer[offset + 1] << 8) |
58 ((uint32_t)mBuffer[offset + 2] << 16) | ((uint32_t)mBuffer[offset + 3] << 24);
59 mOffset += 4;
60 return result;
61}
62
63uint64_t MtpDataPacket::getUInt64() {
64 int offset = mOffset;
65 uint64_t result = (uint64_t)mBuffer[offset] | ((uint64_t)mBuffer[offset + 1] << 8) |
66 ((uint64_t)mBuffer[offset + 2] << 16) | ((uint64_t)mBuffer[offset + 3] << 24) |
67 ((uint64_t)mBuffer[offset + 4] << 32) | ((uint64_t)mBuffer[offset + 5] << 40) |
68 ((uint64_t)mBuffer[offset + 6] << 48) | ((uint64_t)mBuffer[offset + 7] << 56);
69 mOffset += 8;
70 return result;
71}
72
73void MtpDataPacket::getString(MtpStringBuffer& string)
74{
75 string.readFromPacket(this);
76}
77
78void MtpDataPacket::putInt8(int8_t value) {
79 allocate(mOffset + 1);
80 mBuffer[mOffset++] = (uint8_t)value;
81 if (mPacketSize < mOffset)
82 mPacketSize = mOffset;
83}
84
85void MtpDataPacket::putUInt8(uint8_t value) {
86 allocate(mOffset + 1);
87 mBuffer[mOffset++] = (uint8_t)value;
88 if (mPacketSize < mOffset)
89 mPacketSize = mOffset;
90}
91
92void MtpDataPacket::putInt16(int16_t value) {
93 allocate(mOffset + 2);
94 mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
95 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
96 if (mPacketSize < mOffset)
97 mPacketSize = mOffset;
98}
99
100void MtpDataPacket::putUInt16(uint16_t value) {
101 allocate(mOffset + 2);
102 mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
103 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
104 if (mPacketSize < mOffset)
105 mPacketSize = mOffset;
106}
107
108void MtpDataPacket::putInt32(int32_t value) {
109 allocate(mOffset + 4);
110 mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
111 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
112 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
113 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
114 if (mPacketSize < mOffset)
115 mPacketSize = mOffset;
116}
117
118void MtpDataPacket::putUInt32(uint32_t value) {
119 allocate(mOffset + 4);
120 mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
121 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
122 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
123 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
124 if (mPacketSize < mOffset)
125 mPacketSize = mOffset;
126}
127
128void MtpDataPacket::putInt64(int64_t value) {
129 allocate(mOffset + 8);
130 mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
131 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
132 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
133 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
134 mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF);
135 mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF);
136 mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF);
137 mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF);
138 if (mPacketSize < mOffset)
139 mPacketSize = mOffset;
140}
141
142void MtpDataPacket::putUInt64(uint64_t value) {
143 allocate(mOffset + 8);
144 mBuffer[mOffset++] = (uint8_t)(value & 0xFF);
145 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF);
146 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF);
147 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF);
148 mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF);
149 mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF);
150 mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF);
151 mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF);
152 if (mPacketSize < mOffset)
153 mPacketSize = mOffset;
154}
155
156void MtpDataPacket::putAInt8(const int8_t* values, int count) {
157 putUInt32(count);
158 for (int i = 0; i < count; i++)
159 putInt8(*values++);
160}
161
162void MtpDataPacket::putAUInt8(const uint8_t* values, int count) {
163 putUInt32(count);
164 for (int i = 0; i < count; i++)
165 putUInt8(*values++);
166}
167
168void MtpDataPacket::putAInt16(const int16_t* values, int count) {
169 putUInt32(count);
170 for (int i = 0; i < count; i++)
171 putInt16(*values++);
172}
173
174void MtpDataPacket::putAUInt16(const uint16_t* values, int count) {
175 putUInt32(count);
176 for (int i = 0; i < count; i++)
177 putUInt16(*values++);
178}
179
180void MtpDataPacket::putAInt32(const int32_t* values, int count) {
181 putUInt32(count);
182 for (int i = 0; i < count; i++)
183 putInt32(*values++);
184}
185
186void MtpDataPacket::putAUInt32(const uint32_t* values, int count) {
187 putUInt32(count);
188 for (int i = 0; i < count; i++)
189 putUInt32(*values++);
190}
191
192void MtpDataPacket::putAUInt32(const UInt32List* list) {
193 if (!list) {
194 putEmptyArray();
195 } else {
196 size_t size = list->size();
197 putUInt32(size);
198 for (size_t i = 0; i < size; i++)
199 putUInt32((*list)[i]);
200 }
201}
202
203void MtpDataPacket::putAInt64(const int64_t* values, int count) {
204 putUInt32(count);
205 for (int i = 0; i < count; i++)
206 putInt64(*values++);
207}
208
209void MtpDataPacket::putAUInt64(const uint64_t* values, int count) {
210 putUInt32(count);
211 for (int i = 0; i < count; i++)
212 putUInt64(*values++);
213}
214
215void MtpDataPacket::putString(const MtpStringBuffer& string)
216{
217 string.writeToPacket(this);
218}
219
220void MtpDataPacket::putString(const char* s)
221{
222 MtpStringBuffer string(s);
223 string.writeToPacket(this);
224}
225
226#ifdef MTP_DEVICE
227int MtpDataPacket::read(int fd) {
228 // first read the header
229 int ret = ::read(fd, mBuffer, MTP_CONTAINER_HEADER_SIZE);
230printf("MtpDataPacket::read 1 returned %d\n", ret);
231 if (ret != MTP_CONTAINER_HEADER_SIZE)
232 return -1;
233 // then the following data
234 int total = MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET);
235 int remaining = total - MTP_CONTAINER_HEADER_SIZE;
236printf("total: %d, remaining: %d\n", total, remaining);
237 ret = ::read(fd, &mBuffer[0] + MTP_CONTAINER_HEADER_SIZE, remaining);
238printf("MtpDataPacket::read 2 returned %d\n", ret);
239 if (ret != remaining)
240 return -1;
241
242 mPacketSize = total;
243 mOffset = MTP_CONTAINER_HEADER_SIZE;
244 return total;
245}
246
247int MtpDataPacket::readDataHeader(int fd) {
248 int ret = ::read(fd, mBuffer, MTP_CONTAINER_HEADER_SIZE);
249 if (ret > 0)
250 mPacketSize = ret;
251 else
252 mPacketSize = 0;
253 return ret;
254}
255
256int MtpDataPacket::write(int fd) {
257 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
258 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
259
260 // send header separately from data
261 int ret = ::write(fd, mBuffer, MTP_CONTAINER_HEADER_SIZE);
262 if (ret == MTP_CONTAINER_HEADER_SIZE)
263 ret = ::write(fd, mBuffer + MTP_CONTAINER_HEADER_SIZE,
264 mPacketSize - MTP_CONTAINER_HEADER_SIZE);
265 return (ret < 0 ? ret : 0);
266}
267
268int MtpDataPacket::writeDataHeader(int fd, uint32_t length) {
269 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length);
270 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
271 int ret = ::write(fd, mBuffer, MTP_CONTAINER_HEADER_SIZE);
272 return (ret < 0 ? ret : 0);
273}
274#endif // MTP_DEVICE
275
276#ifdef MTP_HOST
277int MtpDataPacket::read(struct usb_endpoint *ep) {
278 // first read the header
279 int ret = transfer(ep, mBuffer, mBufferSize);
280printf("MtpDataPacket::transfer returned %d\n", ret);
281 if (ret >= 0)
282 mPacketSize = ret;
283 return ret;
284}
285
286int MtpDataPacket::write(struct usb_endpoint *ep) {
287 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
288 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
289
290 // send header separately from data
291 int ret = transfer(ep, mBuffer, MTP_CONTAINER_HEADER_SIZE);
292 if (ret == MTP_CONTAINER_HEADER_SIZE)
293 ret = transfer(ep, mBuffer + MTP_CONTAINER_HEADER_SIZE,
294 mPacketSize - MTP_CONTAINER_HEADER_SIZE);
295 return (ret < 0 ? ret : 0);
296}
297
298#endif // MTP_HOST
Mike Lockwood7850ef92010-05-14 10:10:36 -0400299
300} // namespace android