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 "MtpDevice" 18 19 #include "MtpDebug.h" 20 #include "MtpDevice.h" 21 #include "MtpDeviceInfo.h" 22 #include "MtpObjectInfo.h" 23 #include "MtpProperty.h" 24 #include "MtpStorageInfo.h" 25 #include "MtpStringBuffer.h" 26 #include "MtpUtils.h" 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <sys/types.h> 31 #include <sys/ioctl.h> 32 #include <sys/stat.h> 33 #include <fcntl.h> 34 #include <errno.h> 35 #include <endian.h> 36 37 #include <usbhost/usbhost.h> 38 39 namespace android { 40 41 #if 0 42 static bool isMtpDevice(uint16_t vendor, uint16_t product) { 43 // Sandisk Sansa Fuze 44 if (vendor == 0x0781 && product == 0x74c2) 45 return true; 46 // Samsung YP-Z5 47 if (vendor == 0x04e8 && product == 0x503c) 48 return true; 49 return false; 50 } 51 #endif 52 53 MtpDevice* MtpDevice::open(const char* deviceName, int fd) { 54 struct usb_device *device = usb_device_new(deviceName, fd); 55 if (!device) { 56 ALOGE("usb_device_new failed for %s", deviceName); 57 return NULL; 58 } 59 60 struct usb_descriptor_header* desc; 61 struct usb_descriptor_iter iter; 62 63 usb_descriptor_iter_init(device, &iter); 64 65 while ((desc = usb_descriptor_iter_next(&iter)) != NULL) { 66 if (desc->bDescriptorType == USB_DT_INTERFACE) { 67 struct usb_interface_descriptor *interface = (struct usb_interface_descriptor *)desc; 68 69 if (interface->bInterfaceClass == USB_CLASS_STILL_IMAGE && 70 interface->bInterfaceSubClass == 1 && // Still Image Capture 71 interface->bInterfaceProtocol == 1) // Picture Transfer Protocol (PIMA 15470) 72 { 73 char* manufacturerName = usb_device_get_manufacturer_name(device); 74 char* productName = usb_device_get_product_name(device); 75 ALOGD("Found camera: \"%s\" \"%s\"\n", manufacturerName, productName); 76 free(manufacturerName); 77 free(productName); 78 } else if (interface->bInterfaceClass == 0xFF && 79 interface->bInterfaceSubClass == 0xFF && 80 interface->bInterfaceProtocol == 0) { 81 char* interfaceName = usb_device_get_string(device, interface->iInterface); 82 if (!interfaceName) { 83 continue; 84 } else if (strcmp(interfaceName, "MTP")) { 85 free(interfaceName); 86 continue; 87 } 88 free(interfaceName); 89 90 // Looks like an android style MTP device 91 char* manufacturerName = usb_device_get_manufacturer_name(device); 92 char* productName = usb_device_get_product_name(device); 93 ALOGD("Found MTP device: \"%s\" \"%s\"\n", manufacturerName, productName); 94 free(manufacturerName); 95 free(productName); 96 } 97 #if 0 98 else { 99 // look for special cased devices based on vendor/product ID 100 // we are doing this mainly for testing purposes 101 uint16_t vendor = usb_device_get_vendor_id(device); 102 uint16_t product = usb_device_get_product_id(device); 103 if (!isMtpDevice(vendor, product)) { 104 // not an MTP or PTP device 105 continue; 106 } 107 // request MTP OS string and descriptor 108 // some music players need to see this before entering MTP mode. 109 char buffer[256]; 110 memset(buffer, 0, sizeof(buffer)); 111 int ret = usb_device_control_transfer(device, 112 USB_DIR_IN|USB_RECIP_DEVICE|USB_TYPE_STANDARD, 113 USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) | 0xEE, 114 0, buffer, sizeof(buffer), 0); 115 printf("usb_device_control_transfer returned %d errno: %d\n", ret, errno); 116 if (ret > 0) { 117 printf("got MTP string %s\n", buffer); 118 ret = usb_device_control_transfer(device, 119 USB_DIR_IN|USB_RECIP_DEVICE|USB_TYPE_VENDOR, 1, 120 0, 4, buffer, sizeof(buffer), 0); 121 printf("OS descriptor got %d\n", ret); 122 } else { 123 printf("no MTP string\n"); 124 } 125 } 126 #endif 127 // if we got here, then we have a likely MTP or PTP device 128 129 // interface should be followed by three endpoints 130 struct usb_endpoint_descriptor *ep; 131 struct usb_endpoint_descriptor *ep_in_desc = NULL; 132 struct usb_endpoint_descriptor *ep_out_desc = NULL; 133 struct usb_endpoint_descriptor *ep_intr_desc = NULL; 134 for (int i = 0; i < 3; i++) { 135 ep = (struct usb_endpoint_descriptor *)usb_descriptor_iter_next(&iter); 136 if (!ep || ep->bDescriptorType != USB_DT_ENDPOINT) { 137 ALOGE("endpoints not found\n"); 138 usb_device_close(device); 139 return NULL; 140 } 141 if (ep->bmAttributes == USB_ENDPOINT_XFER_BULK) { 142 if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) 143 ep_in_desc = ep; 144 else 145 ep_out_desc = ep; 146 } else if (ep->bmAttributes == USB_ENDPOINT_XFER_INT && 147 ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) { 148 ep_intr_desc = ep; 149 } 150 } 151 if (!ep_in_desc || !ep_out_desc || !ep_intr_desc) { 152 ALOGE("endpoints not found\n"); 153 usb_device_close(device); 154 return NULL; 155 } 156 157 if (usb_device_claim_interface(device, interface->bInterfaceNumber)) { 158 ALOGE("usb_device_claim_interface failed errno: %d\n", errno); 159 usb_device_close(device); 160 return NULL; 161 } 162 163 MtpDevice* mtpDevice = new MtpDevice(device, interface->bInterfaceNumber, 164 ep_in_desc, ep_out_desc, ep_intr_desc); 165 mtpDevice->initialize(); 166 return mtpDevice; 167 } 168 } 169 170 usb_device_close(device); 171 ALOGE("device not found"); 172 return NULL; 173 } 174 175 MtpDevice::MtpDevice(struct usb_device* device, int interface, 176 const struct usb_endpoint_descriptor *ep_in, 177 const struct usb_endpoint_descriptor *ep_out, 178 const struct usb_endpoint_descriptor *ep_intr) 179 : mDevice(device), 180 mInterface(interface), 181 mRequestIn1(NULL), 182 mRequestIn2(NULL), 183 mRequestOut(NULL), 184 mRequestIntr(NULL), 185 mDeviceInfo(NULL), 186 mSessionID(0), 187 mTransactionID(0), 188 mReceivedResponse(false) 189 { 190 mRequestIn1 = usb_request_new(device, ep_in); 191 mRequestIn2 = usb_request_new(device, ep_in); 192 mRequestOut = usb_request_new(device, ep_out); 193 mRequestIntr = usb_request_new(device, ep_intr); 194 } 195 196 MtpDevice::~MtpDevice() { 197 close(); 198 for (size_t i = 0; i < mDeviceProperties.size(); i++) 199 delete mDeviceProperties[i]; 200 usb_request_free(mRequestIn1); 201 usb_request_free(mRequestIn2); 202 usb_request_free(mRequestOut); 203 usb_request_free(mRequestIntr); 204 } 205 206 void MtpDevice::initialize() { 207 openSession(); 208 mDeviceInfo = getDeviceInfo(); 209 if (mDeviceInfo) { 210 if (mDeviceInfo->mDeviceProperties) { 211 int count = mDeviceInfo->mDeviceProperties->size(); 212 for (int i = 0; i < count; i++) { 213 MtpDeviceProperty propCode = (*mDeviceInfo->mDeviceProperties)[i]; 214 MtpProperty* property = getDevicePropDesc(propCode); 215 if (property) 216 mDeviceProperties.push(property); 217 } 218 } 219 } 220 } 221 222 void MtpDevice::close() { 223 if (mDevice) { 224 usb_device_release_interface(mDevice, mInterface); 225 usb_device_close(mDevice); 226 mDevice = NULL; 227 } 228 } 229 230 void MtpDevice::print() { 231 if (mDeviceInfo) { 232 mDeviceInfo->print(); 233 234 if (mDeviceInfo->mDeviceProperties) { 235 ALOGI("***** DEVICE PROPERTIES *****\n"); 236 int count = mDeviceInfo->mDeviceProperties->size(); 237 for (int i = 0; i < count; i++) { 238 MtpDeviceProperty propCode = (*mDeviceInfo->mDeviceProperties)[i]; 239 MtpProperty* property = getDevicePropDesc(propCode); 240 if (property) { 241 property->print(); 242 delete property; 243 } 244 } 245 } 246 } 247 248 if (mDeviceInfo->mPlaybackFormats) { 249 ALOGI("***** OBJECT PROPERTIES *****\n"); 250 int count = mDeviceInfo->mPlaybackFormats->size(); 251 for (int i = 0; i < count; i++) { 252 MtpObjectFormat format = (*mDeviceInfo->mPlaybackFormats)[i]; 253 ALOGI("*** FORMAT: %s\n", MtpDebug::getFormatCodeName(format)); 254 MtpObjectPropertyList* props = getObjectPropsSupported(format); 255 if (props) { 256 for (size_t j = 0; j < props->size(); j++) { 257 MtpObjectProperty prop = (*props)[j]; 258 MtpProperty* property = getObjectPropDesc(prop, format); 259 if (property) { 260 property->print(); 261 delete property; 262 } else { 263 ALOGE("could not fetch property: %s", 264 MtpDebug::getObjectPropCodeName(prop)); 265 } 266 } 267 } 268 } 269 } 270 } 271 272 const char* MtpDevice::getDeviceName() { 273 if (mDevice) 274 return usb_device_get_name(mDevice); 275 else 276 return "???"; 277 } 278 279 bool MtpDevice::openSession() { 280 Mutex::Autolock autoLock(mMutex); 281 282 mSessionID = 0; 283 mTransactionID = 0; 284 MtpSessionID newSession = 1; 285 mRequest.reset(); 286 mRequest.setParameter(1, newSession); 287 if (!sendRequest(MTP_OPERATION_OPEN_SESSION)) 288 return false; 289 MtpResponseCode ret = readResponse(); 290 if (ret == MTP_RESPONSE_SESSION_ALREADY_OPEN) 291 newSession = mResponse.getParameter(1); 292 else if (ret != MTP_RESPONSE_OK) 293 return false; 294 295 mSessionID = newSession; 296 mTransactionID = 1; 297 return true; 298 } 299 300 bool MtpDevice::closeSession() { 301 // FIXME 302 return true; 303 } 304 305 MtpDeviceInfo* MtpDevice::getDeviceInfo() { 306 Mutex::Autolock autoLock(mMutex); 307 308 mRequest.reset(); 309 if (!sendRequest(MTP_OPERATION_GET_DEVICE_INFO)) 310 return NULL; 311 if (!readData()) 312 return NULL; 313 MtpResponseCode ret = readResponse(); 314 if (ret == MTP_RESPONSE_OK) { 315 MtpDeviceInfo* info = new MtpDeviceInfo; 316 if (info->read(mData)) 317 return info; 318 else 319 delete info; 320 } 321 return NULL; 322 } 323 324 MtpStorageIDList* MtpDevice::getStorageIDs() { 325 Mutex::Autolock autoLock(mMutex); 326 327 mRequest.reset(); 328 if (!sendRequest(MTP_OPERATION_GET_STORAGE_IDS)) 329 return NULL; 330 if (!readData()) 331 return NULL; 332 MtpResponseCode ret = readResponse(); 333 if (ret == MTP_RESPONSE_OK) { 334 return mData.getAUInt32(); 335 } 336 return NULL; 337 } 338 339 MtpStorageInfo* MtpDevice::getStorageInfo(MtpStorageID storageID) { 340 Mutex::Autolock autoLock(mMutex); 341 342 mRequest.reset(); 343 mRequest.setParameter(1, storageID); 344 if (!sendRequest(MTP_OPERATION_GET_STORAGE_INFO)) 345 return NULL; 346 if (!readData()) 347 return NULL; 348 MtpResponseCode ret = readResponse(); 349 if (ret == MTP_RESPONSE_OK) { 350 MtpStorageInfo* info = new MtpStorageInfo(storageID); 351 if (info->read(mData)) 352 return info; 353 else 354 delete info; 355 } 356 return NULL; 357 } 358 359 MtpObjectHandleList* MtpDevice::getObjectHandles(MtpStorageID storageID, 360 MtpObjectFormat format, MtpObjectHandle parent) { 361 Mutex::Autolock autoLock(mMutex); 362 363 mRequest.reset(); 364 mRequest.setParameter(1, storageID); 365 mRequest.setParameter(2, format); 366 mRequest.setParameter(3, parent); 367 if (!sendRequest(MTP_OPERATION_GET_OBJECT_HANDLES)) 368 return NULL; 369 if (!readData()) 370 return NULL; 371 MtpResponseCode ret = readResponse(); 372 if (ret == MTP_RESPONSE_OK) { 373 return mData.getAUInt32(); 374 } 375 return NULL; 376 } 377 378 MtpObjectInfo* MtpDevice::getObjectInfo(MtpObjectHandle handle) { 379 Mutex::Autolock autoLock(mMutex); 380 381 // FIXME - we might want to add some caching here 382 383 mRequest.reset(); 384 mRequest.setParameter(1, handle); 385 if (!sendRequest(MTP_OPERATION_GET_OBJECT_INFO)) 386 return NULL; 387 if (!readData()) 388 return NULL; 389 MtpResponseCode ret = readResponse(); 390 if (ret == MTP_RESPONSE_OK) { 391 MtpObjectInfo* info = new MtpObjectInfo(handle); 392 if (info->read(mData)) 393 return info; 394 else 395 delete info; 396 } 397 return NULL; 398 } 399 400 void* MtpDevice::getThumbnail(MtpObjectHandle handle, int& outLength) { 401 Mutex::Autolock autoLock(mMutex); 402 403 mRequest.reset(); 404 mRequest.setParameter(1, handle); 405 if (sendRequest(MTP_OPERATION_GET_THUMB) && readData()) { 406 MtpResponseCode ret = readResponse(); 407 if (ret == MTP_RESPONSE_OK) { 408 return mData.getData(outLength); 409 } 410 } 411 outLength = 0; 412 return NULL; 413 } 414 415 MtpObjectHandle MtpDevice::sendObjectInfo(MtpObjectInfo* info) { 416 Mutex::Autolock autoLock(mMutex); 417 418 mRequest.reset(); 419 MtpObjectHandle parent = info->mParent; 420 if (parent == 0) 421 parent = MTP_PARENT_ROOT; 422 423 mRequest.setParameter(1, info->mStorageID); 424 mRequest.setParameter(2, info->mParent); 425 426 mData.putUInt32(info->mStorageID); 427 mData.putUInt16(info->mFormat); 428 mData.putUInt16(info->mProtectionStatus); 429 mData.putUInt32(info->mCompressedSize); 430 mData.putUInt16(info->mThumbFormat); 431 mData.putUInt32(info->mThumbCompressedSize); 432 mData.putUInt32(info->mThumbPixWidth); 433 mData.putUInt32(info->mThumbPixHeight); 434 mData.putUInt32(info->mImagePixWidth); 435 mData.putUInt32(info->mImagePixHeight); 436 mData.putUInt32(info->mImagePixDepth); 437 mData.putUInt32(info->mParent); 438 mData.putUInt16(info->mAssociationType); 439 mData.putUInt32(info->mAssociationDesc); 440 mData.putUInt32(info->mSequenceNumber); 441 mData.putString(info->mName); 442 443 char created[100], modified[100]; 444 formatDateTime(info->mDateCreated, created, sizeof(created)); 445 formatDateTime(info->mDateModified, modified, sizeof(modified)); 446 447 mData.putString(created); 448 mData.putString(modified); 449 if (info->mKeywords) 450 mData.putString(info->mKeywords); 451 else 452 mData.putEmptyString(); 453 454 if (sendRequest(MTP_OPERATION_SEND_OBJECT_INFO) && sendData()) { 455 MtpResponseCode ret = readResponse(); 456 if (ret == MTP_RESPONSE_OK) { 457 info->mStorageID = mResponse.getParameter(1); 458 info->mParent = mResponse.getParameter(2); 459 info->mHandle = mResponse.getParameter(3); 460 return info->mHandle; 461 } 462 } 463 return (MtpObjectHandle)-1; 464 } 465 466 bool MtpDevice::sendObject(MtpObjectInfo* info, int srcFD) { 467 Mutex::Autolock autoLock(mMutex); 468 469 int remaining = info->mCompressedSize; 470 mRequest.reset(); 471 mRequest.setParameter(1, info->mHandle); 472 if (sendRequest(MTP_OPERATION_SEND_OBJECT)) { 473 // send data header 474 writeDataHeader(MTP_OPERATION_SEND_OBJECT, remaining); 475 476 char buffer[65536]; 477 while (remaining > 0) { 478 int count = read(srcFD, buffer, sizeof(buffer)); 479 if (count > 0) { 480 int written = mData.write(mRequestOut, buffer, count); 481 // FIXME check error 482 remaining -= count; 483 } else { 484 break; 485 } 486 } 487 } 488 MtpResponseCode ret = readResponse(); 489 return (remaining == 0 && ret == MTP_RESPONSE_OK); 490 } 491 492 bool MtpDevice::deleteObject(MtpObjectHandle handle) { 493 Mutex::Autolock autoLock(mMutex); 494 495 mRequest.reset(); 496 mRequest.setParameter(1, handle); 497 if (sendRequest(MTP_OPERATION_DELETE_OBJECT)) { 498 MtpResponseCode ret = readResponse(); 499 if (ret == MTP_RESPONSE_OK) 500 return true; 501 } 502 return false; 503 } 504 505 MtpObjectHandle MtpDevice::getParent(MtpObjectHandle handle) { 506 MtpObjectInfo* info = getObjectInfo(handle); 507 if (info) { 508 MtpObjectHandle parent = info->mParent; 509 delete info; 510 return parent; 511 } else { 512 return -1; 513 } 514 } 515 516 MtpObjectHandle MtpDevice::getStorageID(MtpObjectHandle handle) { 517 MtpObjectInfo* info = getObjectInfo(handle); 518 if (info) { 519 MtpObjectHandle storageId = info->mStorageID; 520 delete info; 521 return storageId; 522 } else { 523 return -1; 524 } 525 } 526 527 MtpObjectPropertyList* MtpDevice::getObjectPropsSupported(MtpObjectFormat format) { 528 Mutex::Autolock autoLock(mMutex); 529 530 mRequest.reset(); 531 mRequest.setParameter(1, format); 532 if (!sendRequest(MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED)) 533 return NULL; 534 if (!readData()) 535 return NULL; 536 MtpResponseCode ret = readResponse(); 537 if (ret == MTP_RESPONSE_OK) { 538 return mData.getAUInt16(); 539 } 540 return NULL; 541 542 } 543 544 MtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) { 545 Mutex::Autolock autoLock(mMutex); 546 547 mRequest.reset(); 548 mRequest.setParameter(1, code); 549 if (!sendRequest(MTP_OPERATION_GET_DEVICE_PROP_DESC)) 550 return NULL; 551 if (!readData()) 552 return NULL; 553 MtpResponseCode ret = readResponse(); 554 if (ret == MTP_RESPONSE_OK) { 555 MtpProperty* property = new MtpProperty; 556 if (property->read(mData)) 557 return property; 558 else 559 delete property; 560 } 561 return NULL; 562 } 563 564 MtpProperty* MtpDevice::getObjectPropDesc(MtpObjectProperty code, MtpObjectFormat format) { 565 Mutex::Autolock autoLock(mMutex); 566 567 mRequest.reset(); 568 mRequest.setParameter(1, code); 569 mRequest.setParameter(2, format); 570 if (!sendRequest(MTP_OPERATION_GET_OBJECT_PROP_DESC)) 571 return NULL; 572 if (!readData()) 573 return NULL; 574 MtpResponseCode ret = readResponse(); 575 if (ret == MTP_RESPONSE_OK) { 576 MtpProperty* property = new MtpProperty; 577 if (property->read(mData)) 578 return property; 579 else 580 delete property; 581 } 582 return NULL; 583 } 584 585 bool MtpDevice::readObject(MtpObjectHandle handle, 586 bool (* callback)(void* data, int offset, int length, void* clientData), 587 size_t objectSize, void* clientData) { 588 Mutex::Autolock autoLock(mMutex); 589 bool result = false; 590 591 mRequest.reset(); 592 mRequest.setParameter(1, handle); 593 if (sendRequest(MTP_OPERATION_GET_OBJECT) 594 && mData.readDataHeader(mRequestIn1)) { 595 uint32_t length = mData.getContainerLength(); 596 if (length - MTP_CONTAINER_HEADER_SIZE != objectSize) { 597 ALOGE("readObject error objectSize: %d, length: %d", 598 objectSize, length); 599 goto fail; 600 } 601 length -= MTP_CONTAINER_HEADER_SIZE; 602 uint32_t remaining = length; 603 int offset = 0; 604 605 int initialDataLength = 0; 606 void* initialData = mData.getData(initialDataLength); 607 if (initialData) { 608 if (initialDataLength > 0) { 609 if (!callback(initialData, 0, initialDataLength, clientData)) 610 goto fail; 611 remaining -= initialDataLength; 612 offset += initialDataLength; 613 } 614 free(initialData); 615 } 616 617 // USB reads greater than 16K don't work 618 char buffer1[16384], buffer2[16384]; 619 mRequestIn1->buffer = buffer1; 620 mRequestIn2->buffer = buffer2; 621 struct usb_request* req = mRequestIn1; 622 void* writeBuffer = NULL; 623 int writeLength = 0; 624 625 while (remaining > 0 || writeBuffer) { 626 if (remaining > 0) { 627 // queue up a read request 628 req->buffer_length = (remaining > sizeof(buffer1) ? sizeof(buffer1) : remaining); 629 if (mData.readDataAsync(req)) { 630 ALOGE("readDataAsync failed"); 631 goto fail; 632 } 633 } else { 634 req = NULL; 635 } 636 637 if (writeBuffer) { 638 // write previous buffer 639 if (!callback(writeBuffer, offset, writeLength, clientData)) { 640 ALOGE("write failed"); 641 // wait for pending read before failing 642 if (req) 643 mData.readDataWait(mDevice); 644 goto fail; 645 } 646 offset += writeLength; 647 writeBuffer = NULL; 648 } 649 650 // wait for read to complete 651 if (req) { 652 int read = mData.readDataWait(mDevice); 653 if (read < 0) 654 goto fail; 655 656 if (read > 0) { 657 writeBuffer = req->buffer; 658 writeLength = read; 659 remaining -= read; 660 req = (req == mRequestIn1 ? mRequestIn2 : mRequestIn1); 661 } else { 662 writeBuffer = NULL; 663 } 664 } 665 } 666 667 MtpResponseCode response = readResponse(); 668 if (response == MTP_RESPONSE_OK) 669 result = true; 670 } 671 672 fail: 673 return result; 674 } 675 676 677 // reads the object's data and writes it to the specified file path 678 bool MtpDevice::readObject(MtpObjectHandle handle, const char* destPath, int group, int perm) { 679 ALOGD("readObject: %s", destPath); 680 int fd = ::open(destPath, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); 681 if (fd < 0) { 682 ALOGE("open failed for %s", destPath); 683 return false; 684 } 685 686 fchown(fd, getuid(), group); 687 // set permissions 688 int mask = umask(0); 689 fchmod(fd, perm); 690 umask(mask); 691 692 Mutex::Autolock autoLock(mMutex); 693 bool result = false; 694 695 mRequest.reset(); 696 mRequest.setParameter(1, handle); 697 if (sendRequest(MTP_OPERATION_GET_OBJECT) 698 && mData.readDataHeader(mRequestIn1)) { 699 uint32_t length = mData.getContainerLength(); 700 if (length < MTP_CONTAINER_HEADER_SIZE) 701 goto fail; 702 length -= MTP_CONTAINER_HEADER_SIZE; 703 uint32_t remaining = length; 704 705 int initialDataLength = 0; 706 void* initialData = mData.getData(initialDataLength); 707 if (initialData) { 708 if (initialDataLength > 0) { 709 if (write(fd, initialData, initialDataLength) != initialDataLength) { 710 free(initialData); 711 goto fail; 712 } 713 remaining -= initialDataLength; 714 } 715 free(initialData); 716 } 717 718 // USB reads greater than 16K don't work 719 char buffer1[16384], buffer2[16384]; 720 mRequestIn1->buffer = buffer1; 721 mRequestIn2->buffer = buffer2; 722 struct usb_request* req = mRequestIn1; 723 void* writeBuffer = NULL; 724 int writeLength = 0; 725 726 while (remaining > 0 || writeBuffer) { 727 if (remaining > 0) { 728 // queue up a read request 729 req->buffer_length = (remaining > sizeof(buffer1) ? sizeof(buffer1) : remaining); 730 if (mData.readDataAsync(req)) { 731 ALOGE("readDataAsync failed"); 732 goto fail; 733 } 734 } else { 735 req = NULL; 736 } 737 738 if (writeBuffer) { 739 // write previous buffer 740 if (write(fd, writeBuffer, writeLength) != writeLength) { 741 ALOGE("write failed"); 742 // wait for pending read before failing 743 if (req) 744 mData.readDataWait(mDevice); 745 goto fail; 746 } 747 writeBuffer = NULL; 748 } 749 750 // wait for read to complete 751 if (req) { 752 int read = mData.readDataWait(mDevice); 753 if (read < 0) 754 goto fail; 755 756 if (read > 0) { 757 writeBuffer = req->buffer; 758 writeLength = read; 759 remaining -= read; 760 req = (req == mRequestIn1 ? mRequestIn2 : mRequestIn1); 761 } else { 762 writeBuffer = NULL; 763 } 764 } 765 } 766 767 MtpResponseCode response = readResponse(); 768 if (response == MTP_RESPONSE_OK) 769 result = true; 770 } 771 772 fail: 773 ::close(fd); 774 return result; 775 } 776 777 bool MtpDevice::sendRequest(MtpOperationCode operation) { 778 ALOGV("sendRequest: %s\n", MtpDebug::getOperationCodeName(operation)); 779 mReceivedResponse = false; 780 mRequest.setOperationCode(operation); 781 if (mTransactionID > 0) 782 mRequest.setTransactionID(mTransactionID++); 783 int ret = mRequest.write(mRequestOut); 784 mRequest.dump(); 785 return (ret > 0); 786 } 787 788 bool MtpDevice::sendData() { 789 ALOGV("sendData\n"); 790 mData.setOperationCode(mRequest.getOperationCode()); 791 mData.setTransactionID(mRequest.getTransactionID()); 792 int ret = mData.write(mRequestOut); 793 mData.dump(); 794 return (ret > 0); 795 } 796 797 bool MtpDevice::readData() { 798 mData.reset(); 799 int ret = mData.read(mRequestIn1); 800 ALOGV("readData returned %d\n", ret); 801 if (ret >= MTP_CONTAINER_HEADER_SIZE) { 802 if (mData.getContainerType() == MTP_CONTAINER_TYPE_RESPONSE) { 803 ALOGD("got response packet instead of data packet"); 804 // we got a response packet rather than data 805 // copy it to mResponse 806 mResponse.copyFrom(mData); 807 mReceivedResponse = true; 808 return false; 809 } 810 mData.dump(); 811 return true; 812 } 813 else { 814 ALOGV("readResponse failed\n"); 815 return false; 816 } 817 } 818 819 bool MtpDevice::writeDataHeader(MtpOperationCode operation, int dataLength) { 820 mData.setOperationCode(operation); 821 mData.setTransactionID(mRequest.getTransactionID()); 822 return (!mData.writeDataHeader(mRequestOut, dataLength)); 823 } 824 825 MtpResponseCode MtpDevice::readResponse() { 826 ALOGV("readResponse\n"); 827 if (mReceivedResponse) { 828 mReceivedResponse = false; 829 return mResponse.getResponseCode(); 830 } 831 int ret = mResponse.read(mRequestIn1); 832 // handle zero length packets, which might occur if the data transfer 833 // ends on a packet boundary 834 if (ret == 0) 835 ret = mResponse.read(mRequestIn1); 836 if (ret >= MTP_CONTAINER_HEADER_SIZE) { 837 mResponse.dump(); 838 return mResponse.getResponseCode(); 839 } else { 840 ALOGD("readResponse failed\n"); 841 return -1; 842 } 843 } 844 845 } // namespace android 846