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