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