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