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
45namespace {
46
47constexpr char FFS_MTP_EP_IN[] = "/dev/usb-ffs/mtp/ep1";
48constexpr char FFS_MTP_EP_OUT[] = "/dev/usb-ffs/mtp/ep2";
49constexpr char FFS_MTP_EP_INTR[] = "/dev/usb-ffs/mtp/ep3";
50
51constexpr int MAX_PACKET_SIZE_FS = 64;
52constexpr int MAX_PACKET_SIZE_HS = 512;
53constexpr int MAX_PACKET_SIZE_SS = 1024;
54
55// Must be divisible by all max packet size values
56constexpr 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
62constexpr int USB_FFS_MAX_WRITE = MTP_BUFFER_SIZE;
63constexpr int USB_FFS_MAX_READ = MTP_BUFFER_SIZE;
64
65static_assert(USB_FFS_MAX_WRITE > 0, "Max r/w values must be > 0!");
66static_assert(USB_FFS_MAX_READ > 0, "Max r/w values must be > 0!");
67
68constexpr unsigned int MAX_MTP_FILE_SIZE = 0xFFFFFFFF;
69
70constexpr size_t ENDPOINT_ALLOC_RETRIES = 10;
71
72struct 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
79struct 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
89struct 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
99struct 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
109const 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
120const 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
130const 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
138const 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
146const 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
155const 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
163const 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
171const 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
180const 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
188const 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
196const 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
205const 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
211const 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
217const struct usb_ss_ep_comp_descriptor ss_intr_comp = {
218    .bLength = sizeof(ss_intr_comp),
219    .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
220};
221
222const 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
229const 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
236const 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
246const 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
253const 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
260const 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"
271const 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
292namespace android {
293
294MtpFfsHandle::MtpFfsHandle() :
295    mMaxWrite(USB_FFS_MAX_WRITE),
296    mMaxRead(USB_FFS_MAX_READ) {}
297
298MtpFfsHandle::~MtpFfsHandle() {}
299
300void MtpFfsHandle::closeEndpoints() {
301    mIntr.reset();
302    mBulkIn.reset();
303    mBulkOut.reset();
304}
305
306bool 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
355err:
356    closeConfig();
357    return false;
358}
359
360void MtpFfsHandle::closeConfig() {
361    mControl.reset();
362}
363
364int 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
387int 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
407int 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
427int MtpFfsHandle::read(void* data, int len) {
428    return readHandle(mBulkOut, data, len);
429}
430
431int MtpFfsHandle::write(const void* data, int len) {
432    return writeHandle(mBulkIn, data, len);
433}
434
435int 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
491int 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
513void MtpFfsHandle::close() {
514    closeEndpoints();
515    mLock.unlock();
516}
517
518/* Read from USB and write to a local file. */
519int 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. */
617int 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
721int 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
729IMtpHandle *get_ffs_handle() {
730    return new android::MtpFfsHandle();
731}
732
733