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