MtpDataPacket.cpp revision 335dd2be955607f2632eabc25045857f2cc8b674
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#include <stdio.h> 18#include <sys/types.h> 19#include <fcntl.h> 20 21#include "MtpDataPacket.h" 22#include "MtpStringBuffer.h" 23 24namespace android { 25 26MtpDataPacket::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 78Int8List* MtpDataPacket::getAInt8() { 79 Int8List* result = new Int8List; 80 int count = getUInt32(); 81 for (int i = 0; i < count; i++) 82 result->push(getInt8()); 83 return result; 84} 85 86UInt8List* MtpDataPacket::getAUInt8() { 87 UInt8List* result = new UInt8List; 88 int count = getUInt32(); 89 for (int i = 0; i < count; i++) 90 result->push(getUInt8()); 91 return result; 92} 93 94Int16List* MtpDataPacket::getAInt16() { 95 Int16List* result = new Int16List; 96 int count = getUInt32(); 97 for (int i = 0; i < count; i++) 98 result->push(getInt16()); 99 return result; 100} 101 102UInt16List* MtpDataPacket::getAUInt16() { 103 UInt16List* result = new UInt16List; 104 int count = getUInt32(); 105 for (int i = 0; i < count; i++) 106 result->push(getUInt16()); 107 return result; 108} 109 110Int32List* MtpDataPacket::getAInt32() { 111 Int32List* result = new Int32List; 112 int count = getUInt32(); 113 for (int i = 0; i < count; i++) 114 result->push(getInt32()); 115 return result; 116} 117 118UInt32List* MtpDataPacket::getAUInt32() { 119 UInt32List* result = new UInt32List; 120 int count = getUInt32(); 121 for (int i = 0; i < count; i++) 122 result->push(getUInt32()); 123 return result; 124} 125 126Int64List* MtpDataPacket::getAInt64() { 127 Int64List* result = new Int64List; 128 int count = getUInt32(); 129 for (int i = 0; i < count; i++) 130 result->push(getInt64()); 131 return result; 132} 133 134UInt64List* MtpDataPacket::getAUInt64() { 135 UInt64List* result = new UInt64List; 136 int count = getUInt32(); 137 for (int i = 0; i < count; i++) 138 result->push(getUInt64()); 139 return result; 140} 141 142void MtpDataPacket::putInt8(int8_t value) { 143 allocate(mOffset + 1); 144 mBuffer[mOffset++] = (uint8_t)value; 145 if (mPacketSize < mOffset) 146 mPacketSize = mOffset; 147} 148 149void MtpDataPacket::putUInt8(uint8_t value) { 150 allocate(mOffset + 1); 151 mBuffer[mOffset++] = (uint8_t)value; 152 if (mPacketSize < mOffset) 153 mPacketSize = mOffset; 154} 155 156void MtpDataPacket::putInt16(int16_t value) { 157 allocate(mOffset + 2); 158 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 159 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 160 if (mPacketSize < mOffset) 161 mPacketSize = mOffset; 162} 163 164void MtpDataPacket::putUInt16(uint16_t value) { 165 allocate(mOffset + 2); 166 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 167 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 168 if (mPacketSize < mOffset) 169 mPacketSize = mOffset; 170} 171 172void MtpDataPacket::putInt32(int32_t value) { 173 allocate(mOffset + 4); 174 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 175 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 176 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 177 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 178 if (mPacketSize < mOffset) 179 mPacketSize = mOffset; 180} 181 182void MtpDataPacket::putUInt32(uint32_t value) { 183 allocate(mOffset + 4); 184 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 185 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 186 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 187 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 188 if (mPacketSize < mOffset) 189 mPacketSize = mOffset; 190} 191 192void MtpDataPacket::putInt64(int64_t value) { 193 allocate(mOffset + 8); 194 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 195 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 196 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 197 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 198 mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF); 199 mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF); 200 mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF); 201 mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF); 202 if (mPacketSize < mOffset) 203 mPacketSize = mOffset; 204} 205 206void MtpDataPacket::putUInt64(uint64_t value) { 207 allocate(mOffset + 8); 208 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 209 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 210 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 211 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 212 mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF); 213 mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF); 214 mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF); 215 mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF); 216 if (mPacketSize < mOffset) 217 mPacketSize = mOffset; 218} 219 220void MtpDataPacket::putAInt8(const int8_t* values, int count) { 221 putUInt32(count); 222 for (int i = 0; i < count; i++) 223 putInt8(*values++); 224} 225 226void MtpDataPacket::putAUInt8(const uint8_t* values, int count) { 227 putUInt32(count); 228 for (int i = 0; i < count; i++) 229 putUInt8(*values++); 230} 231 232void MtpDataPacket::putAInt16(const int16_t* values, int count) { 233 putUInt32(count); 234 for (int i = 0; i < count; i++) 235 putInt16(*values++); 236} 237 238void MtpDataPacket::putAUInt16(const uint16_t* values, int count) { 239 putUInt32(count); 240 for (int i = 0; i < count; i++) 241 putUInt16(*values++); 242} 243 244void MtpDataPacket::putAInt32(const int32_t* values, int count) { 245 putUInt32(count); 246 for (int i = 0; i < count; i++) 247 putInt32(*values++); 248} 249 250void MtpDataPacket::putAUInt32(const uint32_t* values, int count) { 251 putUInt32(count); 252 for (int i = 0; i < count; i++) 253 putUInt32(*values++); 254} 255 256void MtpDataPacket::putAUInt32(const UInt32List* list) { 257 if (!list) { 258 putEmptyArray(); 259 } else { 260 size_t size = list->size(); 261 putUInt32(size); 262 for (size_t i = 0; i < size; i++) 263 putUInt32((*list)[i]); 264 } 265} 266 267void MtpDataPacket::putAInt64(const int64_t* values, int count) { 268 putUInt32(count); 269 for (int i = 0; i < count; i++) 270 putInt64(*values++); 271} 272 273void MtpDataPacket::putAUInt64(const uint64_t* values, int count) { 274 putUInt32(count); 275 for (int i = 0; i < count; i++) 276 putUInt64(*values++); 277} 278 279void MtpDataPacket::putString(const MtpStringBuffer& string) 280{ 281 string.writeToPacket(this); 282} 283 284void MtpDataPacket::putString(const char* s) 285{ 286 MtpStringBuffer string(s); 287 string.writeToPacket(this); 288} 289 290#ifdef MTP_DEVICE 291int MtpDataPacket::read(int fd) { 292 // first read the header 293 int ret = ::read(fd, mBuffer, MTP_CONTAINER_HEADER_SIZE); 294printf("MtpDataPacket::read 1 returned %d\n", ret); 295 if (ret != MTP_CONTAINER_HEADER_SIZE) 296 return -1; 297 // then the following data 298 int total = MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET); 299 int remaining = total - MTP_CONTAINER_HEADER_SIZE; 300printf("total: %d, remaining: %d\n", total, remaining); 301 ret = ::read(fd, &mBuffer[0] + MTP_CONTAINER_HEADER_SIZE, remaining); 302printf("MtpDataPacket::read 2 returned %d\n", ret); 303 if (ret != remaining) 304 return -1; 305 306 mPacketSize = total; 307 mOffset = MTP_CONTAINER_HEADER_SIZE; 308 return total; 309} 310 311int MtpDataPacket::readDataHeader(int fd) { 312 int ret = ::read(fd, mBuffer, MTP_CONTAINER_HEADER_SIZE); 313 if (ret > 0) 314 mPacketSize = ret; 315 else 316 mPacketSize = 0; 317 return ret; 318} 319 320int MtpDataPacket::write(int fd) { 321 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize); 322 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 323 324 // send header separately from data 325 int ret = ::write(fd, mBuffer, MTP_CONTAINER_HEADER_SIZE); 326 if (ret == MTP_CONTAINER_HEADER_SIZE) 327 ret = ::write(fd, mBuffer + MTP_CONTAINER_HEADER_SIZE, 328 mPacketSize - MTP_CONTAINER_HEADER_SIZE); 329 return (ret < 0 ? ret : 0); 330} 331 332int MtpDataPacket::writeDataHeader(int fd, uint32_t length) { 333 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length); 334 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 335 int ret = ::write(fd, mBuffer, MTP_CONTAINER_HEADER_SIZE); 336 return (ret < 0 ? ret : 0); 337} 338#endif // MTP_DEVICE 339 340#ifdef MTP_HOST 341int MtpDataPacket::read(struct usb_endpoint *ep) { 342 // first read the header 343 int ret = transfer(ep, mBuffer, mBufferSize); 344printf("MtpDataPacket::transfer returned %d\n", ret); 345 if (ret >= 0) 346 mPacketSize = ret; 347 return ret; 348} 349 350int MtpDataPacket::write(struct usb_endpoint *ep) { 351 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize); 352 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 353 354 // send header separately from data 355 int ret = transfer(ep, mBuffer, MTP_CONTAINER_HEADER_SIZE); 356 if (ret == MTP_CONTAINER_HEADER_SIZE) 357 ret = transfer(ep, mBuffer + MTP_CONTAINER_HEADER_SIZE, 358 mPacketSize - MTP_CONTAINER_HEADER_SIZE); 359 return (ret < 0 ? ret : 0); 360} 361 362#endif // MTP_HOST 363 364} // namespace android 365