Home | History | Annotate | Download | only in mtp
      1 /*
      2  * Copyright (C) 2016 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 #include <android-base/logging.h>
     18 #include <android-base/properties.h>
     19 #include <dirent.h>
     20 #include <errno.h>
     21 #include <fcntl.h>
     22 #include <linux/usb/ch9.h>
     23 #include <linux/usb/functionfs.h>
     24 #include <mutex>
     25 #include <stdio.h>
     26 #include <stdlib.h>
     27 #include <string.h>
     28 #include <sys/endian.h>
     29 #include <sys/ioctl.h>
     30 #include <sys/mman.h>
     31 #include <sys/stat.h>
     32 #include <sys/types.h>
     33 #include <unistd.h>
     34 #include <vector>
     35 
     36 #include "AsyncIO.h"
     37 #include "MtpFfsHandle.h"
     38 #include "mtp.h"
     39 
     40 #define cpu_to_le16(x)  htole16(x)
     41 #define cpu_to_le32(x)  htole32(x)
     42 
     43 #define FUNCTIONFS_ENDPOINT_ALLOC       _IOR('g', 231, __u32)
     44 
     45 namespace {
     46 
     47 constexpr char FFS_MTP_EP_IN[] = "/dev/usb-ffs/mtp/ep1";
     48 constexpr char FFS_MTP_EP_OUT[] = "/dev/usb-ffs/mtp/ep2";
     49 constexpr char FFS_MTP_EP_INTR[] = "/dev/usb-ffs/mtp/ep3";
     50 
     51 constexpr int MAX_PACKET_SIZE_FS = 64;
     52 constexpr int MAX_PACKET_SIZE_HS = 512;
     53 constexpr int MAX_PACKET_SIZE_SS = 1024;
     54 
     55 // Must be divisible by all max packet size values
     56 constexpr int MAX_FILE_CHUNK_SIZE = 3145728;
     57 
     58 // Safe values since some devices cannot handle large DMAs
     59 // To get good performance, override these with
     60 // higher values per device using the properties
     61 // sys.usb.ffs.max_read and sys.usb.ffs.max_write
     62 constexpr int USB_FFS_MAX_WRITE = MTP_BUFFER_SIZE;
     63 constexpr int USB_FFS_MAX_READ = MTP_BUFFER_SIZE;
     64 
     65 static_assert(USB_FFS_MAX_WRITE > 0, "Max r/w values must be > 0!");
     66 static_assert(USB_FFS_MAX_READ > 0, "Max r/w values must be > 0!");
     67 
     68 constexpr unsigned int MAX_MTP_FILE_SIZE = 0xFFFFFFFF;
     69 
     70 constexpr size_t ENDPOINT_ALLOC_RETRIES = 10;
     71 
     72 struct func_desc {
     73     struct usb_interface_descriptor intf;
     74     struct usb_endpoint_descriptor_no_audio sink;
     75     struct usb_endpoint_descriptor_no_audio source;
     76     struct usb_endpoint_descriptor_no_audio intr;
     77 } __attribute__((packed));
     78 
     79 struct ss_func_desc {
     80     struct usb_interface_descriptor intf;
     81     struct usb_endpoint_descriptor_no_audio sink;
     82     struct usb_ss_ep_comp_descriptor sink_comp;
     83     struct usb_endpoint_descriptor_no_audio source;
     84     struct usb_ss_ep_comp_descriptor source_comp;
     85     struct usb_endpoint_descriptor_no_audio intr;
     86     struct usb_ss_ep_comp_descriptor intr_comp;
     87 } __attribute__((packed));
     88 
     89 struct desc_v1 {
     90     struct usb_functionfs_descs_head_v1 {
     91         __le32 magic;
     92         __le32 length;
     93         __le32 fs_count;
     94         __le32 hs_count;
     95     } __attribute__((packed)) header;
     96     struct func_desc fs_descs, hs_descs;
     97 } __attribute__((packed));
     98 
     99 struct desc_v2 {
    100     struct usb_functionfs_descs_head_v2 header;
    101     // The rest of the structure depends on the flags in the header.
    102     __le32 fs_count;
    103     __le32 hs_count;
    104     __le32 ss_count;
    105     struct func_desc fs_descs, hs_descs;
    106     struct ss_func_desc ss_descs;
    107 } __attribute__((packed));
    108 
    109 const struct usb_interface_descriptor mtp_interface_desc = {
    110     .bLength = USB_DT_INTERFACE_SIZE,
    111     .bDescriptorType = USB_DT_INTERFACE,
    112     .bInterfaceNumber = 0,
    113     .bNumEndpoints = 3,
    114     .bInterfaceClass = USB_CLASS_STILL_IMAGE,
    115     .bInterfaceSubClass = 1,
    116     .bInterfaceProtocol = 1,
    117     .iInterface = 1,
    118 };
    119 
    120 const struct usb_interface_descriptor ptp_interface_desc = {
    121     .bLength = USB_DT_INTERFACE_SIZE,
    122     .bDescriptorType = USB_DT_INTERFACE,
    123     .bInterfaceNumber = 0,
    124     .bNumEndpoints = 3,
    125     .bInterfaceClass = USB_CLASS_STILL_IMAGE,
    126     .bInterfaceSubClass = 1,
    127     .bInterfaceProtocol = 1,
    128 };
    129 
    130 const struct usb_endpoint_descriptor_no_audio fs_sink = {
    131     .bLength = USB_DT_ENDPOINT_SIZE,
    132     .bDescriptorType = USB_DT_ENDPOINT,
    133     .bEndpointAddress = 1 | USB_DIR_IN,
    134     .bmAttributes = USB_ENDPOINT_XFER_BULK,
    135     .wMaxPacketSize = MAX_PACKET_SIZE_FS,
    136 };
    137 
    138 const struct usb_endpoint_descriptor_no_audio fs_source = {
    139     .bLength = USB_DT_ENDPOINT_SIZE,
    140     .bDescriptorType = USB_DT_ENDPOINT,
    141     .bEndpointAddress = 2 | USB_DIR_OUT,
    142     .bmAttributes = USB_ENDPOINT_XFER_BULK,
    143     .wMaxPacketSize = MAX_PACKET_SIZE_FS,
    144 };
    145 
    146 const struct usb_endpoint_descriptor_no_audio fs_intr = {
    147     .bLength = USB_DT_ENDPOINT_SIZE,
    148     .bDescriptorType = USB_DT_ENDPOINT,
    149     .bEndpointAddress = 3 | USB_DIR_IN,
    150     .bmAttributes = USB_ENDPOINT_XFER_INT,
    151     .wMaxPacketSize = MAX_PACKET_SIZE_FS,
    152     .bInterval = 6,
    153 };
    154 
    155 const struct usb_endpoint_descriptor_no_audio hs_sink = {
    156     .bLength = USB_DT_ENDPOINT_SIZE,
    157     .bDescriptorType = USB_DT_ENDPOINT,
    158     .bEndpointAddress = 1 | USB_DIR_IN,
    159     .bmAttributes = USB_ENDPOINT_XFER_BULK,
    160     .wMaxPacketSize = MAX_PACKET_SIZE_HS,
    161 };
    162 
    163 const struct usb_endpoint_descriptor_no_audio hs_source = {
    164     .bLength = USB_DT_ENDPOINT_SIZE,
    165     .bDescriptorType = USB_DT_ENDPOINT,
    166     .bEndpointAddress = 2 | USB_DIR_OUT,
    167     .bmAttributes = USB_ENDPOINT_XFER_BULK,
    168     .wMaxPacketSize = MAX_PACKET_SIZE_HS,
    169 };
    170 
    171 const struct usb_endpoint_descriptor_no_audio hs_intr = {
    172     .bLength = USB_DT_ENDPOINT_SIZE,
    173     .bDescriptorType = USB_DT_ENDPOINT,
    174     .bEndpointAddress = 3 | USB_DIR_IN,
    175     .bmAttributes = USB_ENDPOINT_XFER_INT,
    176     .wMaxPacketSize = MAX_PACKET_SIZE_HS,
    177     .bInterval = 6,
    178 };
    179 
    180 const struct usb_endpoint_descriptor_no_audio ss_sink = {
    181     .bLength = USB_DT_ENDPOINT_SIZE,
    182     .bDescriptorType = USB_DT_ENDPOINT,
    183     .bEndpointAddress = 1 | USB_DIR_IN,
    184     .bmAttributes = USB_ENDPOINT_XFER_BULK,
    185     .wMaxPacketSize = MAX_PACKET_SIZE_SS,
    186 };
    187 
    188 const struct usb_endpoint_descriptor_no_audio ss_source = {
    189     .bLength = USB_DT_ENDPOINT_SIZE,
    190     .bDescriptorType = USB_DT_ENDPOINT,
    191     .bEndpointAddress = 2 | USB_DIR_OUT,
    192     .bmAttributes = USB_ENDPOINT_XFER_BULK,
    193     .wMaxPacketSize = MAX_PACKET_SIZE_SS,
    194 };
    195 
    196 const struct usb_endpoint_descriptor_no_audio ss_intr = {
    197     .bLength = USB_DT_ENDPOINT_SIZE,
    198     .bDescriptorType = USB_DT_ENDPOINT,
    199     .bEndpointAddress = 3 | USB_DIR_IN,
    200     .bmAttributes = USB_ENDPOINT_XFER_INT,
    201     .wMaxPacketSize = MAX_PACKET_SIZE_SS,
    202     .bInterval = 6,
    203 };
    204 
    205 const struct usb_ss_ep_comp_descriptor ss_sink_comp = {
    206     .bLength = sizeof(ss_sink_comp),
    207     .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
    208     .bMaxBurst = 6,
    209 };
    210 
    211 const struct usb_ss_ep_comp_descriptor ss_source_comp = {
    212     .bLength = sizeof(ss_source_comp),
    213     .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
    214     .bMaxBurst = 6,
    215 };
    216 
    217 const struct usb_ss_ep_comp_descriptor ss_intr_comp = {
    218     .bLength = sizeof(ss_intr_comp),
    219     .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
    220 };
    221 
    222 const struct func_desc mtp_fs_descriptors = {
    223     .intf = mtp_interface_desc,
    224     .sink = fs_sink,
    225     .source = fs_source,
    226     .intr = fs_intr,
    227 };
    228 
    229 const struct func_desc mtp_hs_descriptors = {
    230     .intf = mtp_interface_desc,
    231     .sink = hs_sink,
    232     .source = hs_source,
    233     .intr = hs_intr,
    234 };
    235 
    236 const struct ss_func_desc mtp_ss_descriptors = {
    237     .intf = mtp_interface_desc,
    238     .sink = ss_sink,
    239     .sink_comp = ss_sink_comp,
    240     .source = ss_source,
    241     .source_comp = ss_source_comp,
    242     .intr = ss_intr,
    243     .intr_comp = ss_intr_comp,
    244 };
    245 
    246 const struct func_desc ptp_fs_descriptors = {
    247     .intf = ptp_interface_desc,
    248     .sink = fs_sink,
    249     .source = fs_source,
    250     .intr = fs_intr,
    251 };
    252 
    253 const struct func_desc ptp_hs_descriptors = {
    254     .intf = ptp_interface_desc,
    255     .sink = hs_sink,
    256     .source = hs_source,
    257     .intr = hs_intr,
    258 };
    259 
    260 const struct ss_func_desc ptp_ss_descriptors = {
    261     .intf = ptp_interface_desc,
    262     .sink = ss_sink,
    263     .sink_comp = ss_sink_comp,
    264     .source = ss_source,
    265     .source_comp = ss_source_comp,
    266     .intr = ss_intr,
    267     .intr_comp = ss_intr_comp,
    268 };
    269 
    270 #define STR_INTERFACE "MTP"
    271 const struct {
    272     struct usb_functionfs_strings_head header;
    273     struct {
    274         __le16 code;
    275         const char str1[sizeof(STR_INTERFACE)];
    276     } __attribute__((packed)) lang0;
    277 } __attribute__((packed)) strings = {
    278     .header = {
    279         .magic = cpu_to_le32(FUNCTIONFS_STRINGS_MAGIC),
    280         .length = cpu_to_le32(sizeof(strings)),
    281         .str_count = cpu_to_le32(1),
    282         .lang_count = cpu_to_le32(1),
    283     },
    284     .lang0 = {
    285         .code = cpu_to_le16(0x0409),
    286         .str1 = STR_INTERFACE,
    287     },
    288 };
    289 
    290 } // anonymous namespace
    291 
    292 namespace android {
    293 
    294 MtpFfsHandle::MtpFfsHandle() :
    295     mMaxWrite(USB_FFS_MAX_WRITE),
    296     mMaxRead(USB_FFS_MAX_READ) {}
    297 
    298 MtpFfsHandle::~MtpFfsHandle() {}
    299 
    300 void MtpFfsHandle::closeEndpoints() {
    301     mIntr.reset();
    302     mBulkIn.reset();
    303     mBulkOut.reset();
    304 }
    305 
    306 bool MtpFfsHandle::initFunctionfs() {
    307     ssize_t ret;
    308     struct desc_v1 v1_descriptor;
    309     struct desc_v2 v2_descriptor;
    310 
    311     v2_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
    312     v2_descriptor.header.length = cpu_to_le32(sizeof(v2_descriptor));
    313     v2_descriptor.header.flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC |
    314                                  FUNCTIONFS_HAS_SS_DESC;
    315     v2_descriptor.fs_count = 4;
    316     v2_descriptor.hs_count = 4;
    317     v2_descriptor.ss_count = 7;
    318     v2_descriptor.fs_descs = mPtp ? ptp_fs_descriptors : mtp_fs_descriptors;
    319     v2_descriptor.hs_descs = mPtp ? ptp_hs_descriptors : mtp_hs_descriptors;
    320     v2_descriptor.ss_descs = mPtp ? ptp_ss_descriptors : mtp_ss_descriptors;
    321 
    322     if (mControl < 0) { // might have already done this before
    323         mControl.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP0, O_RDWR)));
    324         if (mControl < 0) {
    325             PLOG(ERROR) << FFS_MTP_EP0 << ": cannot open control endpoint";
    326             goto err;
    327         }
    328 
    329         ret = TEMP_FAILURE_RETRY(::write(mControl, &v2_descriptor, sizeof(v2_descriptor)));
    330         if (ret < 0) {
    331             v1_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC);
    332             v1_descriptor.header.length = cpu_to_le32(sizeof(v1_descriptor));
    333             v1_descriptor.header.fs_count = 4;
    334             v1_descriptor.header.hs_count = 4;
    335             v1_descriptor.fs_descs = mPtp ? ptp_fs_descriptors : mtp_fs_descriptors;
    336             v1_descriptor.hs_descs = mPtp ? ptp_hs_descriptors : mtp_hs_descriptors;
    337             PLOG(ERROR) << FFS_MTP_EP0 << "Switching to V1 descriptor format";
    338             ret = TEMP_FAILURE_RETRY(::write(mControl, &v1_descriptor, sizeof(v1_descriptor)));
    339             if (ret < 0) {
    340                 PLOG(ERROR) << FFS_MTP_EP0 << "Writing descriptors failed";
    341                 goto err;
    342             }
    343         }
    344         ret = TEMP_FAILURE_RETRY(::write(mControl, &strings, sizeof(strings)));
    345         if (ret < 0) {
    346             PLOG(ERROR) << FFS_MTP_EP0 << "Writing strings failed";
    347             goto err;
    348         }
    349     }
    350     if (mBulkIn > -1 || mBulkOut > -1 || mIntr > -1)
    351         LOG(WARNING) << "Endpoints were not closed before configure!";
    352 
    353     return true;
    354 
    355 err:
    356     closeConfig();
    357     return false;
    358 }
    359 
    360 void MtpFfsHandle::closeConfig() {
    361     mControl.reset();
    362 }
    363 
    364 int MtpFfsHandle::writeHandle(int fd, const void* data, int len) {
    365     LOG(VERBOSE) << "MTP about to write fd = " << fd << ", len=" << len;
    366     int ret = 0;
    367     const char* buf = static_cast<const char*>(data);
    368     while (len > 0) {
    369         int write_len = std::min(mMaxWrite, len);
    370         int n = TEMP_FAILURE_RETRY(::write(fd, buf, write_len));
    371 
    372         if (n < 0) {
    373             PLOG(ERROR) << "write ERROR: fd = " << fd << ", n = " << n;
    374             return -1;
    375         } else if (n < write_len) {
    376             errno = EIO;
    377             PLOG(ERROR) << "less written than expected";
    378             return -1;
    379         }
    380         buf += n;
    381         len -= n;
    382         ret += n;
    383     }
    384     return ret;
    385 }
    386 
    387 int MtpFfsHandle::readHandle(int fd, void* data, int len) {
    388     LOG(VERBOSE) << "MTP about to read fd = " << fd << ", len=" << len;
    389     int ret = 0;
    390     char* buf = static_cast<char*>(data);
    391     while (len > 0) {
    392         int read_len = std::min(mMaxRead, len);
    393         int n = TEMP_FAILURE_RETRY(::read(fd, buf, read_len));
    394         if (n < 0) {
    395             PLOG(ERROR) << "read ERROR: fd = " << fd << ", n = " << n;
    396             return -1;
    397         }
    398         ret += n;
    399         if (n < read_len) // done reading early
    400             break;
    401         buf += n;
    402         len -= n;
    403     }
    404     return ret;
    405 }
    406 
    407 int MtpFfsHandle::spliceReadHandle(int fd, int pipe_out, int len) {
    408     LOG(VERBOSE) << "MTP about to splice read fd = " << fd << ", len=" << len;
    409     int ret = 0;
    410     loff_t dummyoff;
    411     while (len > 0) {
    412         int read_len = std::min(mMaxRead, len);
    413         dummyoff = 0;
    414         int n = TEMP_FAILURE_RETRY(splice(fd, &dummyoff, pipe_out, nullptr, read_len, 0));
    415         if (n < 0) {
    416             PLOG(ERROR) << "splice read ERROR: fd = " << fd << ", n = " << n;
    417             return -1;
    418         }
    419         ret += n;
    420         if (n < read_len) // done reading early
    421             break;
    422         len -= n;
    423     }
    424     return ret;
    425 }
    426 
    427 int MtpFfsHandle::read(void* data, int len) {
    428     return readHandle(mBulkOut, data, len);
    429 }
    430 
    431 int MtpFfsHandle::write(const void* data, int len) {
    432     return writeHandle(mBulkIn, data, len);
    433 }
    434 
    435 int MtpFfsHandle::start() {
    436     mLock.lock();
    437 
    438     mBulkIn.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_IN, O_RDWR)));
    439     if (mBulkIn < 0) {
    440         PLOG(ERROR) << FFS_MTP_EP_IN << ": cannot open bulk in ep";
    441         return -1;
    442     }
    443 
    444     mBulkOut.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_OUT, O_RDWR)));
    445     if (mBulkOut < 0) {
    446         PLOG(ERROR) << FFS_MTP_EP_OUT << ": cannot open bulk out ep";
    447         return -1;
    448     }
    449 
    450     mIntr.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_INTR, O_RDWR)));
    451     if (mIntr < 0) {
    452         PLOG(ERROR) << FFS_MTP_EP0 << ": cannot open intr ep";
    453         return -1;
    454     }
    455 
    456     mBuffer1.resize(MAX_FILE_CHUNK_SIZE);
    457     mBuffer2.resize(MAX_FILE_CHUNK_SIZE);
    458     posix_madvise(mBuffer1.data(), MAX_FILE_CHUNK_SIZE,
    459             POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED);
    460     posix_madvise(mBuffer2.data(), MAX_FILE_CHUNK_SIZE,
    461             POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED);
    462 
    463     // Get device specific r/w size
    464     mMaxWrite = android::base::GetIntProperty("sys.usb.ffs.max_write", USB_FFS_MAX_WRITE);
    465     mMaxRead = android::base::GetIntProperty("sys.usb.ffs.max_read", USB_FFS_MAX_READ);
    466 
    467     size_t attempts = 0;
    468     while (mMaxWrite >= USB_FFS_MAX_WRITE && mMaxRead >= USB_FFS_MAX_READ &&
    469             attempts < ENDPOINT_ALLOC_RETRIES) {
    470         // If larger contiguous chunks of memory aren't available, attempt to try
    471         // smaller allocations.
    472         if (ioctl(mBulkIn, FUNCTIONFS_ENDPOINT_ALLOC, static_cast<__u32>(mMaxWrite)) ||
    473             ioctl(mBulkOut, FUNCTIONFS_ENDPOINT_ALLOC, static_cast<__u32>(mMaxRead))) {
    474             if (errno == ENODEV) {
    475                 // Driver hasn't enabled endpoints yet.
    476                 std::this_thread::sleep_for(std::chrono::milliseconds(100));
    477                 attempts += 1;
    478                 continue;
    479             }
    480             mMaxWrite /= 2;
    481             mMaxRead /=2;
    482         } else {
    483             return 0;
    484         }
    485     }
    486     // Try to start MtpServer anyway, with the smallest max r/w values
    487     PLOG(ERROR) << "Functionfs could not allocate any memory!";
    488     return 0;
    489 }
    490 
    491 int MtpFfsHandle::configure(bool usePtp) {
    492     // Wait till previous server invocation has closed
    493     if (!mLock.try_lock_for(std::chrono::milliseconds(1000))) {
    494         LOG(ERROR) << "MtpServer was unable to get configure lock";
    495         return -1;
    496     }
    497     int ret = 0;
    498 
    499     // If ptp is changed, the configuration must be rewritten
    500     if (mPtp != usePtp) {
    501         closeEndpoints();
    502         closeConfig();
    503     }
    504     mPtp = usePtp;
    505 
    506     if (!initFunctionfs()) {
    507         ret = -1;
    508     }
    509     mLock.unlock();
    510     return ret;
    511 }
    512 
    513 void MtpFfsHandle::close() {
    514     closeEndpoints();
    515     mLock.unlock();
    516 }
    517 
    518 /* Read from USB and write to a local file. */
    519 int MtpFfsHandle::receiveFile(mtp_file_range mfr, bool zero_packet) {
    520     // When receiving files, the incoming length is given in 32 bits.
    521     // A >4G file is given as 0xFFFFFFFF
    522     uint32_t file_length = mfr.length;
    523     uint64_t offset = mfr.offset;
    524     struct usb_endpoint_descriptor mBulkOut_desc;
    525     int packet_size;
    526 
    527     if (ioctl(mBulkOut, FUNCTIONFS_ENDPOINT_DESC, reinterpret_cast<unsigned long>(&mBulkOut_desc))) {
    528         PLOG(ERROR) << "Could not get FFS bulk-out descriptor";
    529         packet_size = MAX_PACKET_SIZE_HS;
    530     } else {
    531         packet_size = mBulkOut_desc.wMaxPacketSize;
    532     }
    533 
    534     char *data = mBuffer1.data();
    535     char *data2 = mBuffer2.data();
    536 
    537     struct aiocb aio;
    538     aio.aio_fildes = mfr.fd;
    539     aio.aio_buf = nullptr;
    540     struct aiocb *aiol[] = {&aio};
    541     int ret = -1;
    542     size_t length;
    543     bool read = false;
    544     bool write = false;
    545 
    546     posix_fadvise(mfr.fd, 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE);
    547 
    548     // Break down the file into pieces that fit in buffers
    549     while (file_length > 0 || write) {
    550         if (file_length > 0) {
    551             length = std::min(static_cast<uint32_t>(MAX_FILE_CHUNK_SIZE), file_length);
    552 
    553             // Read data from USB, handle errors after waiting for write thread.
    554             ret = readHandle(mBulkOut, data, length);
    555 
    556             if (file_length != MAX_MTP_FILE_SIZE && ret < static_cast<int>(length)) {
    557                 ret = -1;
    558                 errno = EIO;
    559             }
    560             read = true;
    561         }
    562 
    563         if (write) {
    564             // get the return status of the last write request
    565             aio_suspend(aiol, 1, nullptr);
    566 
    567             int written = aio_return(&aio);
    568             if (written == -1) {
    569                 errno = aio_error(&aio);
    570                 return -1;
    571             }
    572             if (static_cast<size_t>(written) < aio.aio_nbytes) {
    573                 errno = EIO;
    574                 return -1;
    575             }
    576             write = false;
    577         }
    578 
    579         // If there was an error reading above
    580         if (ret == -1) {
    581             return -1;
    582         }
    583 
    584         if (read) {
    585             if (file_length == MAX_MTP_FILE_SIZE) {
    586                 // For larger files, receive until a short packet is received.
    587                 if (static_cast<size_t>(ret) < length) {
    588                     file_length = 0;
    589                 }
    590             } else {
    591                 // Receive an empty packet if size is a multiple of the endpoint size.
    592                 file_length -= ret;
    593             }
    594             // Enqueue a new write request
    595             aio.aio_buf = data;
    596             aio.aio_sink = mfr.fd;
    597             aio.aio_offset = offset;
    598             aio.aio_nbytes = ret;
    599             aio_write(&aio);
    600 
    601             offset += ret;
    602             std::swap(data, data2);
    603 
    604             write = true;
    605             read = false;
    606         }
    607     }
    608     if (ret % packet_size == 0 || zero_packet) {
    609         if (TEMP_FAILURE_RETRY(::read(mBulkOut, data, packet_size)) != 0) {
    610             return -1;
    611         }
    612     }
    613     return 0;
    614 }
    615 
    616 /* Read from a local file and send over USB. */
    617 int MtpFfsHandle::sendFile(mtp_file_range mfr) {
    618     uint64_t file_length = mfr.length;
    619     uint32_t given_length = std::min(static_cast<uint64_t>(MAX_MTP_FILE_SIZE),
    620             file_length + sizeof(mtp_data_header));
    621     uint64_t offset = mfr.offset;
    622     struct usb_endpoint_descriptor mBulkIn_desc;
    623     int packet_size;
    624 
    625     if (ioctl(mBulkIn, FUNCTIONFS_ENDPOINT_DESC, reinterpret_cast<unsigned long>(&mBulkIn_desc))) {
    626         PLOG(ERROR) << "Could not get FFS bulk-in descriptor";
    627         packet_size = MAX_PACKET_SIZE_HS;
    628     } else {
    629         packet_size = mBulkIn_desc.wMaxPacketSize;
    630     }
    631 
    632     // If file_length is larger than a size_t, truncating would produce the wrong comparison.
    633     // Instead, promote the left side to 64 bits, then truncate the small result.
    634     int init_read_len = std::min(
    635             static_cast<uint64_t>(packet_size - sizeof(mtp_data_header)), file_length);
    636 
    637     char *data = mBuffer1.data();
    638     char *data2 = mBuffer2.data();
    639 
    640     posix_fadvise(mfr.fd, 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE);
    641 
    642     struct aiocb aio;
    643     aio.aio_fildes = mfr.fd;
    644     struct aiocb *aiol[] = {&aio};
    645     int ret, length;
    646     int error = 0;
    647     bool read = false;
    648     bool write = false;
    649 
    650     // Send the header data
    651     mtp_data_header *header = reinterpret_cast<mtp_data_header*>(data);
    652     header->length = __cpu_to_le32(given_length);
    653     header->type = __cpu_to_le16(2); /* data packet */
    654     header->command = __cpu_to_le16(mfr.command);
    655     header->transaction_id = __cpu_to_le32(mfr.transaction_id);
    656 
    657     // Some hosts don't support header/data separation even though MTP allows it
    658     // Handle by filling first packet with initial file data
    659     if (TEMP_FAILURE_RETRY(pread(mfr.fd, reinterpret_cast<char*>(data) +
    660                     sizeof(mtp_data_header), init_read_len, offset))
    661             != init_read_len) return -1;
    662     if (writeHandle(mBulkIn, data, sizeof(mtp_data_header) + init_read_len) == -1) return -1;
    663     file_length -= init_read_len;
    664     offset += init_read_len;
    665     ret = init_read_len + sizeof(mtp_data_header);
    666 
    667     // Break down the file into pieces that fit in buffers
    668     while(file_length > 0) {
    669         if (read) {
    670             // Wait for the previous read to finish
    671             aio_suspend(aiol, 1, nullptr);
    672             ret = aio_return(&aio);
    673             if (ret == -1) {
    674                 errno = aio_error(&aio);
    675                 return -1;
    676             }
    677             if (static_cast<size_t>(ret) < aio.aio_nbytes) {
    678                 errno = EIO;
    679                 return -1;
    680             }
    681 
    682             file_length -= ret;
    683             offset += ret;
    684             std::swap(data, data2);
    685             read = false;
    686             write = true;
    687         }
    688 
    689         if (error == -1) {
    690             return -1;
    691         }
    692 
    693         if (file_length > 0) {
    694             length = std::min(static_cast<uint64_t>(MAX_FILE_CHUNK_SIZE), file_length);
    695             // Queue up another read
    696             aio.aio_buf = data;
    697             aio.aio_offset = offset;
    698             aio.aio_nbytes = length;
    699             aio_read(&aio);
    700             read = true;
    701         }
    702 
    703         if (write) {
    704             if (writeHandle(mBulkIn, data2, ret) == -1) {
    705                 error = -1;
    706             }
    707             write = false;
    708         }
    709     }
    710 
    711     if (ret % packet_size == 0) {
    712         // If the last packet wasn't short, send a final empty packet
    713         if (TEMP_FAILURE_RETRY(::write(mBulkIn, data, 0)) != 0) {
    714             return -1;
    715         }
    716     }
    717 
    718     return 0;
    719 }
    720 
    721 int MtpFfsHandle::sendEvent(mtp_event me) {
    722     unsigned length = me.length;
    723     int ret = writeHandle(mIntr, me.data, length);
    724     return static_cast<unsigned>(ret) == length ? 0 : -1;
    725 }
    726 
    727 } // namespace android
    728 
    729 IMtpHandle *get_ffs_handle() {
    730     return new android::MtpFfsHandle();
    731 }
    732 
    733