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#define LOG_TAG "MtpDataPacket" 18 19#include <stdio.h> 20#include <sys/types.h> 21#include <fcntl.h> 22 23#include <usbhost/usbhost.h> 24 25#include "MtpDataPacket.h" 26#include "MtpStringBuffer.h" 27 28#define MTP_BUFFER_SIZE 16384 29 30namespace android { 31 32MtpDataPacket::MtpDataPacket() 33 : MtpPacket(MTP_BUFFER_SIZE), // MAX_USBFS_BUFFER_SIZE 34 mOffset(MTP_CONTAINER_HEADER_SIZE) 35{ 36} 37 38MtpDataPacket::~MtpDataPacket() { 39} 40 41void MtpDataPacket::reset() { 42 MtpPacket::reset(); 43 mOffset = MTP_CONTAINER_HEADER_SIZE; 44} 45 46void MtpDataPacket::setOperationCode(MtpOperationCode code) { 47 MtpPacket::putUInt16(MTP_CONTAINER_CODE_OFFSET, code); 48} 49 50void MtpDataPacket::setTransactionID(MtpTransactionID id) { 51 MtpPacket::putUInt32(MTP_CONTAINER_TRANSACTION_ID_OFFSET, id); 52} 53 54bool MtpDataPacket::getUInt8(uint8_t& value) { 55 if (mPacketSize - mOffset < sizeof(value)) 56 return false; 57 value = mBuffer[mOffset++]; 58 return true; 59} 60 61bool MtpDataPacket::getUInt16(uint16_t& value) { 62 if (mPacketSize - mOffset < sizeof(value)) 63 return false; 64 int offset = mOffset; 65 value = (uint16_t)mBuffer[offset] | ((uint16_t)mBuffer[offset + 1] << 8); 66 mOffset += sizeof(value); 67 return true; 68} 69 70bool MtpDataPacket::getUInt32(uint32_t& value) { 71 if (mPacketSize - mOffset < sizeof(value)) 72 return false; 73 int offset = mOffset; 74 value = (uint32_t)mBuffer[offset] | ((uint32_t)mBuffer[offset + 1] << 8) | 75 ((uint32_t)mBuffer[offset + 2] << 16) | ((uint32_t)mBuffer[offset + 3] << 24); 76 mOffset += sizeof(value); 77 return true; 78} 79 80bool MtpDataPacket::getUInt64(uint64_t& value) { 81 if (mPacketSize - mOffset < sizeof(value)) 82 return false; 83 int offset = mOffset; 84 value = (uint64_t)mBuffer[offset] | ((uint64_t)mBuffer[offset + 1] << 8) | 85 ((uint64_t)mBuffer[offset + 2] << 16) | ((uint64_t)mBuffer[offset + 3] << 24) | 86 ((uint64_t)mBuffer[offset + 4] << 32) | ((uint64_t)mBuffer[offset + 5] << 40) | 87 ((uint64_t)mBuffer[offset + 6] << 48) | ((uint64_t)mBuffer[offset + 7] << 56); 88 mOffset += sizeof(value); 89 return true; 90} 91 92bool MtpDataPacket::getUInt128(uint128_t& value) { 93 return getUInt32(value[0]) && getUInt32(value[1]) && getUInt32(value[2]) && getUInt32(value[3]); 94} 95 96bool MtpDataPacket::getString(MtpStringBuffer& string) 97{ 98 return string.readFromPacket(this); 99} 100 101Int8List* MtpDataPacket::getAInt8() { 102 uint32_t count; 103 if (!getUInt32(count)) 104 return NULL; 105 Int8List* result = new Int8List; 106 for (uint32_t i = 0; i < count; i++) { 107 int8_t value; 108 if (!getInt8(value)) { 109 delete result; 110 return NULL; 111 } 112 result->push(value); 113 } 114 return result; 115} 116 117UInt8List* MtpDataPacket::getAUInt8() { 118 uint32_t count; 119 if (!getUInt32(count)) 120 return NULL; 121 UInt8List* result = new UInt8List; 122 for (uint32_t i = 0; i < count; i++) { 123 uint8_t value; 124 if (!getUInt8(value)) { 125 delete result; 126 return NULL; 127 } 128 result->push(value); 129 } 130 return result; 131} 132 133Int16List* MtpDataPacket::getAInt16() { 134 uint32_t count; 135 if (!getUInt32(count)) 136 return NULL; 137 Int16List* result = new Int16List; 138 for (uint32_t i = 0; i < count; i++) { 139 int16_t value; 140 if (!getInt16(value)) { 141 delete result; 142 return NULL; 143 } 144 result->push(value); 145 } 146 return result; 147} 148 149UInt16List* MtpDataPacket::getAUInt16() { 150 uint32_t count; 151 if (!getUInt32(count)) 152 return NULL; 153 UInt16List* result = new UInt16List; 154 for (uint32_t i = 0; i < count; i++) { 155 uint16_t value; 156 if (!getUInt16(value)) { 157 delete result; 158 return NULL; 159 } 160 result->push(value); 161 } 162 return result; 163} 164 165Int32List* MtpDataPacket::getAInt32() { 166 uint32_t count; 167 if (!getUInt32(count)) 168 return NULL; 169 Int32List* result = new Int32List; 170 for (uint32_t i = 0; i < count; i++) { 171 int32_t value; 172 if (!getInt32(value)) { 173 delete result; 174 return NULL; 175 } 176 result->push(value); 177 } 178 return result; 179} 180 181UInt32List* MtpDataPacket::getAUInt32() { 182 uint32_t count; 183 if (!getUInt32(count)) 184 return NULL; 185 UInt32List* result = new UInt32List; 186 for (uint32_t i = 0; i < count; i++) { 187 uint32_t value; 188 if (!getUInt32(value)) { 189 delete result; 190 return NULL; 191 } 192 result->push(value); 193 } 194 return result; 195} 196 197Int64List* MtpDataPacket::getAInt64() { 198 uint32_t count; 199 if (!getUInt32(count)) 200 return NULL; 201 Int64List* result = new Int64List; 202 for (uint32_t i = 0; i < count; i++) { 203 int64_t value; 204 if (!getInt64(value)) { 205 delete result; 206 return NULL; 207 } 208 result->push(value); 209 } 210 return result; 211} 212 213UInt64List* MtpDataPacket::getAUInt64() { 214 uint32_t count; 215 if (!getUInt32(count)) 216 return NULL; 217 UInt64List* result = new UInt64List; 218 for (uint32_t i = 0; i < count; i++) { 219 uint64_t value; 220 if (!getUInt64(value)) { 221 delete result; 222 return NULL; 223 } 224 result->push(value); 225 } 226 return result; 227} 228 229void MtpDataPacket::putInt8(int8_t value) { 230 allocate(mOffset + 1); 231 mBuffer[mOffset++] = (uint8_t)value; 232 if (mPacketSize < mOffset) 233 mPacketSize = mOffset; 234} 235 236void MtpDataPacket::putUInt8(uint8_t value) { 237 allocate(mOffset + 1); 238 mBuffer[mOffset++] = (uint8_t)value; 239 if (mPacketSize < mOffset) 240 mPacketSize = mOffset; 241} 242 243void MtpDataPacket::putInt16(int16_t value) { 244 allocate(mOffset + 2); 245 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 246 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 247 if (mPacketSize < mOffset) 248 mPacketSize = mOffset; 249} 250 251void MtpDataPacket::putUInt16(uint16_t value) { 252 allocate(mOffset + 2); 253 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 254 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 255 if (mPacketSize < mOffset) 256 mPacketSize = mOffset; 257} 258 259void MtpDataPacket::putInt32(int32_t value) { 260 allocate(mOffset + 4); 261 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 262 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 263 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 264 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 265 if (mPacketSize < mOffset) 266 mPacketSize = mOffset; 267} 268 269void MtpDataPacket::putUInt32(uint32_t value) { 270 allocate(mOffset + 4); 271 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 272 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 273 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 274 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 275 if (mPacketSize < mOffset) 276 mPacketSize = mOffset; 277} 278 279void MtpDataPacket::putInt64(int64_t value) { 280 allocate(mOffset + 8); 281 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 282 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 283 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 284 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 285 mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF); 286 mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF); 287 mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF); 288 mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF); 289 if (mPacketSize < mOffset) 290 mPacketSize = mOffset; 291} 292 293void MtpDataPacket::putUInt64(uint64_t value) { 294 allocate(mOffset + 8); 295 mBuffer[mOffset++] = (uint8_t)(value & 0xFF); 296 mBuffer[mOffset++] = (uint8_t)((value >> 8) & 0xFF); 297 mBuffer[mOffset++] = (uint8_t)((value >> 16) & 0xFF); 298 mBuffer[mOffset++] = (uint8_t)((value >> 24) & 0xFF); 299 mBuffer[mOffset++] = (uint8_t)((value >> 32) & 0xFF); 300 mBuffer[mOffset++] = (uint8_t)((value >> 40) & 0xFF); 301 mBuffer[mOffset++] = (uint8_t)((value >> 48) & 0xFF); 302 mBuffer[mOffset++] = (uint8_t)((value >> 56) & 0xFF); 303 if (mPacketSize < mOffset) 304 mPacketSize = mOffset; 305} 306 307void MtpDataPacket::putInt128(const int128_t& value) { 308 putInt32(value[0]); 309 putInt32(value[1]); 310 putInt32(value[2]); 311 putInt32(value[3]); 312} 313 314void MtpDataPacket::putUInt128(const uint128_t& value) { 315 putUInt32(value[0]); 316 putUInt32(value[1]); 317 putUInt32(value[2]); 318 putUInt32(value[3]); 319} 320 321void MtpDataPacket::putInt128(int64_t value) { 322 putInt64(value); 323 putInt64(value < 0 ? -1 : 0); 324} 325 326void MtpDataPacket::putUInt128(uint64_t value) { 327 putUInt64(value); 328 putUInt64(0); 329} 330 331void MtpDataPacket::putAInt8(const int8_t* values, int count) { 332 putUInt32(count); 333 for (int i = 0; i < count; i++) 334 putInt8(*values++); 335} 336 337void MtpDataPacket::putAUInt8(const uint8_t* values, int count) { 338 putUInt32(count); 339 for (int i = 0; i < count; i++) 340 putUInt8(*values++); 341} 342 343void MtpDataPacket::putAInt16(const int16_t* values, int count) { 344 putUInt32(count); 345 for (int i = 0; i < count; i++) 346 putInt16(*values++); 347} 348 349void MtpDataPacket::putAUInt16(const uint16_t* values, int count) { 350 putUInt32(count); 351 for (int i = 0; i < count; i++) 352 putUInt16(*values++); 353} 354 355void MtpDataPacket::putAUInt16(const UInt16List* values) { 356 size_t count = (values ? values->size() : 0); 357 putUInt32(count); 358 for (size_t i = 0; i < count; i++) 359 putUInt16((*values)[i]); 360} 361 362void MtpDataPacket::putAInt32(const int32_t* values, int count) { 363 putUInt32(count); 364 for (int i = 0; i < count; i++) 365 putInt32(*values++); 366} 367 368void MtpDataPacket::putAUInt32(const uint32_t* values, int count) { 369 putUInt32(count); 370 for (int i = 0; i < count; i++) 371 putUInt32(*values++); 372} 373 374void MtpDataPacket::putAUInt32(const UInt32List* list) { 375 if (!list) { 376 putEmptyArray(); 377 } else { 378 size_t size = list->size(); 379 putUInt32(size); 380 for (size_t i = 0; i < size; i++) 381 putUInt32((*list)[i]); 382 } 383} 384 385void MtpDataPacket::putAInt64(const int64_t* values, int count) { 386 putUInt32(count); 387 for (int i = 0; i < count; i++) 388 putInt64(*values++); 389} 390 391void MtpDataPacket::putAUInt64(const uint64_t* values, int count) { 392 putUInt32(count); 393 for (int i = 0; i < count; i++) 394 putUInt64(*values++); 395} 396 397void MtpDataPacket::putString(const MtpStringBuffer& string) { 398 string.writeToPacket(this); 399} 400 401void MtpDataPacket::putString(const char* s) { 402 MtpStringBuffer string(s); 403 string.writeToPacket(this); 404} 405 406void MtpDataPacket::putString(const uint16_t* string) { 407 int count = 0; 408 for (int i = 0; i <= MTP_STRING_MAX_CHARACTER_NUMBER; i++) { 409 if (string[i]) 410 count++; 411 else 412 break; 413 } 414 putUInt8(count > 0 ? count + 1 : 0); 415 for (int i = 0; i < count; i++) 416 putUInt16(string[i]); 417 // only terminate with zero if string is not empty 418 if (count > 0) 419 putUInt16(0); 420} 421 422#ifdef MTP_DEVICE 423int MtpDataPacket::read(int fd) { 424 int ret = ::read(fd, mBuffer, MTP_BUFFER_SIZE); 425 if (ret < MTP_CONTAINER_HEADER_SIZE) 426 return -1; 427 mPacketSize = ret; 428 mOffset = MTP_CONTAINER_HEADER_SIZE; 429 return ret; 430} 431 432int MtpDataPacket::write(int fd) { 433 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize); 434 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 435 int ret = ::write(fd, mBuffer, mPacketSize); 436 return (ret < 0 ? ret : 0); 437} 438 439int MtpDataPacket::writeData(int fd, void* data, uint32_t length) { 440 allocate(length + MTP_CONTAINER_HEADER_SIZE); 441 memcpy(mBuffer + MTP_CONTAINER_HEADER_SIZE, data, length); 442 length += MTP_CONTAINER_HEADER_SIZE; 443 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length); 444 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 445 int ret = ::write(fd, mBuffer, length); 446 return (ret < 0 ? ret : 0); 447} 448 449#endif // MTP_DEVICE 450 451#ifdef MTP_HOST 452int MtpDataPacket::read(struct usb_request *request) { 453 // first read the header 454 request->buffer = mBuffer; 455 request->buffer_length = mBufferSize; 456 int length = transfer(request); 457 if (length >= MTP_CONTAINER_HEADER_SIZE) { 458 // look at the length field to see if the data spans multiple packets 459 uint32_t totalLength = MtpPacket::getUInt32(MTP_CONTAINER_LENGTH_OFFSET); 460 allocate(totalLength); 461 while (totalLength > length) { 462 request->buffer = mBuffer + length; 463 request->buffer_length = totalLength - length; 464 int ret = transfer(request); 465 if (ret >= 0) 466 length += ret; 467 else { 468 length = ret; 469 break; 470 } 471 } 472 } 473 if (length >= 0) 474 mPacketSize = length; 475 return length; 476} 477 478int MtpDataPacket::readData(struct usb_request *request, void* buffer, int length) { 479 int read = 0; 480 while (read < length) { 481 request->buffer = (char *)buffer + read; 482 request->buffer_length = length - read; 483 int ret = transfer(request); 484 if (ret < 0) { 485 return ret; 486 } 487 read += ret; 488 } 489 return read; 490} 491 492// Queue a read request. Call readDataWait to wait for result 493int MtpDataPacket::readDataAsync(struct usb_request *req) { 494 if (usb_request_queue(req)) { 495 ALOGE("usb_endpoint_queue failed, errno: %d", errno); 496 return -1; 497 } 498 return 0; 499} 500 501// Wait for result of readDataAsync 502int MtpDataPacket::readDataWait(struct usb_device *device) { 503 struct usb_request *req = usb_request_wait(device); 504 return (req ? req->actual_length : -1); 505} 506 507int MtpDataPacket::readDataHeader(struct usb_request *request) { 508 request->buffer = mBuffer; 509 request->buffer_length = request->max_packet_size; 510 int length = transfer(request); 511 if (length >= 0) 512 mPacketSize = length; 513 return length; 514} 515 516int MtpDataPacket::writeDataHeader(struct usb_request *request, uint32_t length) { 517 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length); 518 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 519 request->buffer = mBuffer; 520 request->buffer_length = MTP_CONTAINER_HEADER_SIZE; 521 int ret = transfer(request); 522 return (ret < 0 ? ret : 0); 523} 524 525int MtpDataPacket::write(struct usb_request *request) { 526 MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize); 527 MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA); 528 529 // send header separately from data 530 request->buffer = mBuffer; 531 request->buffer_length = MTP_CONTAINER_HEADER_SIZE; 532 int ret = transfer(request); 533 if (ret == MTP_CONTAINER_HEADER_SIZE) { 534 request->buffer = mBuffer + MTP_CONTAINER_HEADER_SIZE; 535 request->buffer_length = mPacketSize - MTP_CONTAINER_HEADER_SIZE; 536 ret = transfer(request); 537 } 538 return (ret < 0 ? ret : 0); 539} 540 541int MtpDataPacket::write(struct usb_request *request, void* buffer, uint32_t length) { 542 request->buffer = buffer; 543 request->buffer_length = length; 544 int ret = transfer(request); 545 return (ret < 0 ? ret : 0); 546} 547 548#endif // MTP_HOST 549 550void* MtpDataPacket::getData(int& outLength) const { 551 int length = mPacketSize - MTP_CONTAINER_HEADER_SIZE; 552 if (length > 0) { 553 void* result = malloc(length); 554 if (result) { 555 memcpy(result, mBuffer + MTP_CONTAINER_HEADER_SIZE, length); 556 outLength = length; 557 return result; 558 } 559 } 560 outLength = 0; 561 return NULL; 562} 563 564} // namespace android 565