• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 constexpr unsigned FFS_NUM_EVENTS = 5;
66 
67 static_assert(USB_FFS_MAX_WRITE > 0, "Max r/w values must be > 0!");
68 static_assert(USB_FFS_MAX_READ > 0, "Max r/w values must be > 0!");
69 
70 constexpr unsigned int MAX_MTP_FILE_SIZE = 0xFFFFFFFF;
71 
72 constexpr size_t ENDPOINT_ALLOC_RETRIES = 10;
73 
74 struct func_desc {
75     struct usb_interface_descriptor intf;
76     struct usb_endpoint_descriptor_no_audio sink;
77     struct usb_endpoint_descriptor_no_audio source;
78     struct usb_endpoint_descriptor_no_audio intr;
79 } __attribute__((packed));
80 
81 struct ss_func_desc {
82     struct usb_interface_descriptor intf;
83     struct usb_endpoint_descriptor_no_audio sink;
84     struct usb_ss_ep_comp_descriptor sink_comp;
85     struct usb_endpoint_descriptor_no_audio source;
86     struct usb_ss_ep_comp_descriptor source_comp;
87     struct usb_endpoint_descriptor_no_audio intr;
88     struct usb_ss_ep_comp_descriptor intr_comp;
89 } __attribute__((packed));
90 
91 struct desc_v1 {
92     struct usb_functionfs_descs_head_v1 {
93         __le32 magic;
94         __le32 length;
95         __le32 fs_count;
96         __le32 hs_count;
97     } __attribute__((packed)) header;
98     struct func_desc fs_descs, hs_descs;
99 } __attribute__((packed));
100 
101 struct desc_v2 {
102     struct usb_functionfs_descs_head_v2 header;
103     // The rest of the structure depends on the flags in the header.
104     __le32 fs_count;
105     __le32 hs_count;
106     __le32 ss_count;
107     __le32 os_count;
108     struct func_desc fs_descs, hs_descs;
109     struct ss_func_desc ss_descs;
110     struct usb_os_desc_header os_header;
111     struct usb_ext_compat_desc os_desc;
112 } __attribute__((packed));
113 
114 const struct usb_interface_descriptor mtp_interface_desc = {
115     .bLength = USB_DT_INTERFACE_SIZE,
116     .bDescriptorType = USB_DT_INTERFACE,
117     .bInterfaceNumber = 0,
118     .bNumEndpoints = 3,
119     .bInterfaceClass = USB_CLASS_STILL_IMAGE,
120     .bInterfaceSubClass = 1,
121     .bInterfaceProtocol = 1,
122     .iInterface = 1,
123 };
124 
125 const struct usb_interface_descriptor ptp_interface_desc = {
126     .bLength = USB_DT_INTERFACE_SIZE,
127     .bDescriptorType = USB_DT_INTERFACE,
128     .bInterfaceNumber = 0,
129     .bNumEndpoints = 3,
130     .bInterfaceClass = USB_CLASS_STILL_IMAGE,
131     .bInterfaceSubClass = 1,
132     .bInterfaceProtocol = 1,
133 };
134 
135 const struct usb_endpoint_descriptor_no_audio fs_sink = {
136     .bLength = USB_DT_ENDPOINT_SIZE,
137     .bDescriptorType = USB_DT_ENDPOINT,
138     .bEndpointAddress = 1 | USB_DIR_IN,
139     .bmAttributes = USB_ENDPOINT_XFER_BULK,
140     .wMaxPacketSize = MAX_PACKET_SIZE_FS,
141 };
142 
143 const struct usb_endpoint_descriptor_no_audio fs_source = {
144     .bLength = USB_DT_ENDPOINT_SIZE,
145     .bDescriptorType = USB_DT_ENDPOINT,
146     .bEndpointAddress = 2 | USB_DIR_OUT,
147     .bmAttributes = USB_ENDPOINT_XFER_BULK,
148     .wMaxPacketSize = MAX_PACKET_SIZE_FS,
149 };
150 
151 const struct usb_endpoint_descriptor_no_audio fs_intr = {
152     .bLength = USB_DT_ENDPOINT_SIZE,
153     .bDescriptorType = USB_DT_ENDPOINT,
154     .bEndpointAddress = 3 | USB_DIR_IN,
155     .bmAttributes = USB_ENDPOINT_XFER_INT,
156     .wMaxPacketSize = MAX_PACKET_SIZE_FS,
157     .bInterval = 6,
158 };
159 
160 const struct usb_endpoint_descriptor_no_audio hs_sink = {
161     .bLength = USB_DT_ENDPOINT_SIZE,
162     .bDescriptorType = USB_DT_ENDPOINT,
163     .bEndpointAddress = 1 | USB_DIR_IN,
164     .bmAttributes = USB_ENDPOINT_XFER_BULK,
165     .wMaxPacketSize = MAX_PACKET_SIZE_HS,
166 };
167 
168 const struct usb_endpoint_descriptor_no_audio hs_source = {
169     .bLength = USB_DT_ENDPOINT_SIZE,
170     .bDescriptorType = USB_DT_ENDPOINT,
171     .bEndpointAddress = 2 | USB_DIR_OUT,
172     .bmAttributes = USB_ENDPOINT_XFER_BULK,
173     .wMaxPacketSize = MAX_PACKET_SIZE_HS,
174 };
175 
176 const struct usb_endpoint_descriptor_no_audio hs_intr = {
177     .bLength = USB_DT_ENDPOINT_SIZE,
178     .bDescriptorType = USB_DT_ENDPOINT,
179     .bEndpointAddress = 3 | USB_DIR_IN,
180     .bmAttributes = USB_ENDPOINT_XFER_INT,
181     .wMaxPacketSize = MAX_PACKET_SIZE_HS,
182     .bInterval = 6,
183 };
184 
185 const struct usb_endpoint_descriptor_no_audio ss_sink = {
186     .bLength = USB_DT_ENDPOINT_SIZE,
187     .bDescriptorType = USB_DT_ENDPOINT,
188     .bEndpointAddress = 1 | USB_DIR_IN,
189     .bmAttributes = USB_ENDPOINT_XFER_BULK,
190     .wMaxPacketSize = MAX_PACKET_SIZE_SS,
191 };
192 
193 const struct usb_endpoint_descriptor_no_audio ss_source = {
194     .bLength = USB_DT_ENDPOINT_SIZE,
195     .bDescriptorType = USB_DT_ENDPOINT,
196     .bEndpointAddress = 2 | USB_DIR_OUT,
197     .bmAttributes = USB_ENDPOINT_XFER_BULK,
198     .wMaxPacketSize = MAX_PACKET_SIZE_SS,
199 };
200 
201 const struct usb_endpoint_descriptor_no_audio ss_intr = {
202     .bLength = USB_DT_ENDPOINT_SIZE,
203     .bDescriptorType = USB_DT_ENDPOINT,
204     .bEndpointAddress = 3 | USB_DIR_IN,
205     .bmAttributes = USB_ENDPOINT_XFER_INT,
206     .wMaxPacketSize = MAX_PACKET_SIZE_SS,
207     .bInterval = 6,
208 };
209 
210 const struct usb_ss_ep_comp_descriptor ss_sink_comp = {
211     .bLength = sizeof(ss_sink_comp),
212     .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
213     .bMaxBurst = 6,
214 };
215 
216 const struct usb_ss_ep_comp_descriptor ss_source_comp = {
217     .bLength = sizeof(ss_source_comp),
218     .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
219     .bMaxBurst = 6,
220 };
221 
222 const struct usb_ss_ep_comp_descriptor ss_intr_comp = {
223     .bLength = sizeof(ss_intr_comp),
224     .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
225 };
226 
227 const struct func_desc mtp_fs_descriptors = {
228     .intf = mtp_interface_desc,
229     .sink = fs_sink,
230     .source = fs_source,
231     .intr = fs_intr,
232 };
233 
234 const struct func_desc mtp_hs_descriptors = {
235     .intf = mtp_interface_desc,
236     .sink = hs_sink,
237     .source = hs_source,
238     .intr = hs_intr,
239 };
240 
241 const struct ss_func_desc mtp_ss_descriptors = {
242     .intf = mtp_interface_desc,
243     .sink = ss_sink,
244     .sink_comp = ss_sink_comp,
245     .source = ss_source,
246     .source_comp = ss_source_comp,
247     .intr = ss_intr,
248     .intr_comp = ss_intr_comp,
249 };
250 
251 const struct func_desc ptp_fs_descriptors = {
252     .intf = ptp_interface_desc,
253     .sink = fs_sink,
254     .source = fs_source,
255     .intr = fs_intr,
256 };
257 
258 const struct func_desc ptp_hs_descriptors = {
259     .intf = ptp_interface_desc,
260     .sink = hs_sink,
261     .source = hs_source,
262     .intr = hs_intr,
263 };
264 
265 const struct ss_func_desc ptp_ss_descriptors = {
266     .intf = ptp_interface_desc,
267     .sink = ss_sink,
268     .sink_comp = ss_sink_comp,
269     .source = ss_source,
270     .source_comp = ss_source_comp,
271     .intr = ss_intr,
272     .intr_comp = ss_intr_comp,
273 };
274 
275 #define STR_INTERFACE "MTP"
276 const struct {
277     struct usb_functionfs_strings_head header;
278     struct {
279         __le16 code;
280         const char str1[sizeof(STR_INTERFACE)];
281     } __attribute__((packed)) lang0;
282 } __attribute__((packed)) strings = {
283     .header = {
284         .magic = cpu_to_le32(FUNCTIONFS_STRINGS_MAGIC),
285         .length = cpu_to_le32(sizeof(strings)),
286         .str_count = cpu_to_le32(1),
287         .lang_count = cpu_to_le32(1),
288     },
289     .lang0 = {
290         .code = cpu_to_le16(0x0409),
291         .str1 = STR_INTERFACE,
292     },
293 };
294 
295 struct usb_os_desc_header mtp_os_desc_header = {
296     .interface = htole32(1),
297     .dwLength = htole32(sizeof(usb_os_desc_header) + sizeof(usb_ext_compat_desc)),
298     .bcdVersion = htole16(1),
299     .wIndex = htole16(4),
300     .bCount = htole16(1),
301     .Reserved = htole16(0),
302 };
303 
304 struct usb_ext_compat_desc mtp_os_desc_compat = {
305     .bFirstInterfaceNumber = 0,
306     .Reserved1 = htole32(1),
307     .CompatibleID = { 'M', 'T', 'P' },
308     .SubCompatibleID = {0},
309     .Reserved2 = {0},
310 };
311 
312 struct usb_ext_compat_desc ptp_os_desc_compat = {
313     .bFirstInterfaceNumber = 0,
314     .Reserved1 = htole32(1),
315     .CompatibleID = { 'P', 'T', 'P' },
316     .SubCompatibleID = {0},
317     .Reserved2 = {0},
318 };
319 
320 struct mtp_device_status {
321     uint16_t  wLength;
322     uint16_t  wCode;
323 };
324 
325 } // anonymous namespace
326 
327 namespace android {
328 
MtpFfsHandle()329 MtpFfsHandle::MtpFfsHandle() :
330     mMaxWrite(USB_FFS_MAX_WRITE),
331     mMaxRead(USB_FFS_MAX_READ) {}
332 
~MtpFfsHandle()333 MtpFfsHandle::~MtpFfsHandle() {}
334 
closeEndpoints()335 void MtpFfsHandle::closeEndpoints() {
336     mIntr.reset();
337     mBulkIn.reset();
338     mBulkOut.reset();
339 }
340 
initFunctionfs()341 bool MtpFfsHandle::initFunctionfs() {
342     ssize_t ret;
343     struct desc_v1 v1_descriptor;
344     struct desc_v2 v2_descriptor;
345 
346     v2_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
347     v2_descriptor.header.length = cpu_to_le32(sizeof(v2_descriptor));
348     v2_descriptor.header.flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC |
349                                  FUNCTIONFS_HAS_SS_DESC | FUNCTIONFS_HAS_MS_OS_DESC;
350     v2_descriptor.fs_count = 4;
351     v2_descriptor.hs_count = 4;
352     v2_descriptor.ss_count = 7;
353     v2_descriptor.os_count = 1;
354     v2_descriptor.fs_descs = mPtp ? ptp_fs_descriptors : mtp_fs_descriptors;
355     v2_descriptor.hs_descs = mPtp ? ptp_hs_descriptors : mtp_hs_descriptors;
356     v2_descriptor.ss_descs = mPtp ? ptp_ss_descriptors : mtp_ss_descriptors;
357     v2_descriptor.os_header = mtp_os_desc_header;
358     v2_descriptor.os_desc = mPtp ? ptp_os_desc_compat : mtp_os_desc_compat;
359 
360     if (mControl < 0) { // might have already done this before
361         mControl.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP0, O_RDWR)));
362         if (mControl < 0) {
363             PLOG(ERROR) << FFS_MTP_EP0 << ": cannot open control endpoint";
364             goto err;
365         }
366 
367         ret = TEMP_FAILURE_RETRY(::write(mControl, &v2_descriptor, sizeof(v2_descriptor)));
368         if (ret < 0) {
369             v1_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC);
370             v1_descriptor.header.length = cpu_to_le32(sizeof(v1_descriptor));
371             v1_descriptor.header.fs_count = 4;
372             v1_descriptor.header.hs_count = 4;
373             v1_descriptor.fs_descs = mPtp ? ptp_fs_descriptors : mtp_fs_descriptors;
374             v1_descriptor.hs_descs = mPtp ? ptp_hs_descriptors : mtp_hs_descriptors;
375             PLOG(ERROR) << FFS_MTP_EP0 << "Switching to V1 descriptor format";
376             ret = TEMP_FAILURE_RETRY(::write(mControl, &v1_descriptor, sizeof(v1_descriptor)));
377             if (ret < 0) {
378                 PLOG(ERROR) << FFS_MTP_EP0 << "Writing descriptors failed";
379                 goto err;
380             }
381         }
382         ret = TEMP_FAILURE_RETRY(::write(mControl, &strings, sizeof(strings)));
383         if (ret < 0) {
384             PLOG(ERROR) << FFS_MTP_EP0 << "Writing strings failed";
385             goto err;
386         }
387     }
388     if (mBulkIn > -1 || mBulkOut > -1 || mIntr > -1)
389         LOG(WARNING) << "Endpoints were not closed before configure!";
390 
391     return true;
392 
393 err:
394     closeConfig();
395     return false;
396 }
397 
closeConfig()398 void MtpFfsHandle::closeConfig() {
399     mControl.reset();
400 }
401 
controlLoop()402 void MtpFfsHandle::controlLoop() {
403     while (!handleEvent()) {}
404     LOG(DEBUG) << "Mtp server shutting down";
405 }
406 
handleEvent()407 int MtpFfsHandle::handleEvent() {
408     std::vector<usb_functionfs_event> events(FFS_NUM_EVENTS);
409     usb_functionfs_event *event = events.data();
410     int nbytes = TEMP_FAILURE_RETRY(::read(mControl, event,
411                 events.size() * sizeof(usb_functionfs_event)));
412     if (nbytes == -1) {
413         return -1;
414     }
415     int ret = 0;
416     for (size_t n = nbytes / sizeof *event; n; --n, ++event) {
417         switch (event->type) {
418         case FUNCTIONFS_BIND:
419         case FUNCTIONFS_ENABLE:
420         case FUNCTIONFS_RESUME:
421             ret = 0;
422             errno = 0;
423             break;
424         case FUNCTIONFS_SUSPEND:
425         case FUNCTIONFS_UNBIND:
426         case FUNCTIONFS_DISABLE:
427             errno = ESHUTDOWN;
428             ret = -1;
429             break;
430         case FUNCTIONFS_SETUP:
431             if (handleControlRequest(&event->u.setup) == -1)
432                 ret = -1;
433             break;
434         default:
435             LOG(DEBUG) << "Mtp Event " << event->type << " (unknown)";
436         }
437     }
438     return ret;
439 }
440 
handleControlRequest(const struct usb_ctrlrequest * setup)441 int MtpFfsHandle::handleControlRequest(const struct usb_ctrlrequest *setup) {
442     uint8_t type = setup->bRequestType;
443     uint8_t code = setup->bRequest;
444     uint16_t length = setup->wLength;
445     uint16_t index = setup->wIndex;
446     uint16_t value = setup->wValue;
447     std::vector<char> buf;
448     buf.resize(length);
449 
450     if (!(type & USB_DIR_IN)) {
451         if (::read(mControl, buf.data(), length) != length) {
452             PLOG(DEBUG) << "Mtp error ctrlreq read data";
453         }
454     }
455 
456     if ((type & USB_TYPE_MASK) == USB_TYPE_CLASS && index == 0 && value == 0) {
457         switch(code) {
458         case MTP_REQ_GET_DEVICE_STATUS:
459         {
460             if (length < sizeof(struct mtp_device_status)) {
461                 return -1;
462             }
463             struct mtp_device_status *st = reinterpret_cast<struct mtp_device_status*>(buf.data());
464             st->wLength = htole16(sizeof(st));
465             st->wCode = MTP_RESPONSE_OK;
466             length = st->wLength;
467             break;
468         }
469         default:
470             LOG(DEBUG) << "Unrecognized Mtp class request! " << code;
471         }
472     } else {
473         LOG(DEBUG) << "Unrecognized request type " << type;
474     }
475 
476     if (type & USB_DIR_IN) {
477         if (::write(mControl, buf.data(), length) != length) {
478             PLOG(DEBUG) << "Mtp error ctrlreq write data";
479         }
480     }
481     return 0;
482 }
483 
writeHandle(int fd,const void * data,int len)484 int MtpFfsHandle::writeHandle(int fd, const void* data, int len) {
485     LOG(VERBOSE) << "MTP about to write fd = " << fd << ", len=" << len;
486     int ret = 0;
487     const char* buf = static_cast<const char*>(data);
488     while (len > 0) {
489         int write_len = std::min(mMaxWrite, len);
490         int n = TEMP_FAILURE_RETRY(::write(fd, buf, write_len));
491 
492         if (n < 0) {
493             PLOG(ERROR) << "write ERROR: fd = " << fd << ", n = " << n;
494             return -1;
495         } else if (n < write_len) {
496             errno = EIO;
497             PLOG(ERROR) << "less written than expected";
498             return -1;
499         }
500         buf += n;
501         len -= n;
502         ret += n;
503     }
504     return ret;
505 }
506 
readHandle(int fd,void * data,int len)507 int MtpFfsHandle::readHandle(int fd, void* data, int len) {
508     LOG(VERBOSE) << "MTP about to read fd = " << fd << ", len=" << len;
509     int ret = 0;
510     char* buf = static_cast<char*>(data);
511     while (len > 0) {
512         int read_len = std::min(mMaxRead, len);
513         int n = TEMP_FAILURE_RETRY(::read(fd, buf, read_len));
514         if (n < 0) {
515             PLOG(ERROR) << "read ERROR: fd = " << fd << ", n = " << n;
516             return -1;
517         }
518         ret += n;
519         if (n < read_len) // done reading early
520             break;
521         buf += n;
522         len -= n;
523     }
524     return ret;
525 }
526 
spliceReadHandle(int fd,int pipe_out,int len)527 int MtpFfsHandle::spliceReadHandle(int fd, int pipe_out, int len) {
528     LOG(VERBOSE) << "MTP about to splice read fd = " << fd << ", len=" << len;
529     int ret = 0;
530     loff_t dummyoff;
531     while (len > 0) {
532         int read_len = std::min(mMaxRead, len);
533         dummyoff = 0;
534         int n = TEMP_FAILURE_RETRY(splice(fd, &dummyoff, pipe_out, nullptr, read_len, 0));
535         if (n < 0) {
536             PLOG(ERROR) << "splice read ERROR: fd = " << fd << ", n = " << n;
537             return -1;
538         }
539         ret += n;
540         if (n < read_len) // done reading early
541             break;
542         len -= n;
543     }
544     return ret;
545 }
546 
read(void * data,int len)547 int MtpFfsHandle::read(void* data, int len) {
548     return readHandle(mBulkOut, data, len);
549 }
550 
write(const void * data,int len)551 int MtpFfsHandle::write(const void* data, int len) {
552     return writeHandle(mBulkIn, data, len);
553 }
554 
start()555 int MtpFfsHandle::start() {
556     mLock.lock();
557 
558     mBulkIn.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_IN, O_RDWR)));
559     if (mBulkIn < 0) {
560         PLOG(ERROR) << FFS_MTP_EP_IN << ": cannot open bulk in ep";
561         return -1;
562     }
563 
564     mBulkOut.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_OUT, O_RDWR)));
565     if (mBulkOut < 0) {
566         PLOG(ERROR) << FFS_MTP_EP_OUT << ": cannot open bulk out ep";
567         return -1;
568     }
569 
570     mIntr.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_INTR, O_RDWR)));
571     if (mIntr < 0) {
572         PLOG(ERROR) << FFS_MTP_EP0 << ": cannot open intr ep";
573         return -1;
574     }
575 
576     mBuffer1.resize(MAX_FILE_CHUNK_SIZE);
577     mBuffer2.resize(MAX_FILE_CHUNK_SIZE);
578     posix_madvise(mBuffer1.data(), MAX_FILE_CHUNK_SIZE,
579             POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED);
580     posix_madvise(mBuffer2.data(), MAX_FILE_CHUNK_SIZE,
581             POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED);
582 
583     // Handle control requests.
584     std::thread t([this]() { this->controlLoop(); });
585     t.detach();
586 
587     // Get device specific r/w size
588     mMaxWrite = android::base::GetIntProperty("sys.usb.ffs.max_write", USB_FFS_MAX_WRITE);
589     mMaxRead = android::base::GetIntProperty("sys.usb.ffs.max_read", USB_FFS_MAX_READ);
590 
591     size_t attempts = 0;
592     while (mMaxWrite >= USB_FFS_MAX_WRITE && mMaxRead >= USB_FFS_MAX_READ &&
593             attempts < ENDPOINT_ALLOC_RETRIES) {
594         // If larger contiguous chunks of memory aren't available, attempt to try
595         // smaller allocations.
596         if (ioctl(mBulkIn, FUNCTIONFS_ENDPOINT_ALLOC, static_cast<__u32>(mMaxWrite)) ||
597             ioctl(mBulkOut, FUNCTIONFS_ENDPOINT_ALLOC, static_cast<__u32>(mMaxRead))) {
598             if (errno == ENODEV) {
599                 // Driver hasn't enabled endpoints yet.
600                 std::this_thread::sleep_for(std::chrono::milliseconds(100));
601                 attempts += 1;
602                 continue;
603             }
604             mMaxWrite /= 2;
605             mMaxRead /=2;
606         } else {
607             return 0;
608         }
609     }
610     // Try to start MtpServer anyway, with the smallest max r/w values
611     PLOG(ERROR) << "Functionfs could not allocate any memory!";
612     return 0;
613 }
614 
configure(bool usePtp)615 int MtpFfsHandle::configure(bool usePtp) {
616     // Wait till previous server invocation has closed
617     if (!mLock.try_lock_for(std::chrono::milliseconds(1000))) {
618         LOG(ERROR) << "MtpServer was unable to get configure lock";
619         return -1;
620     }
621     int ret = 0;
622 
623     // If ptp is changed, the configuration must be rewritten
624     if (mPtp != usePtp) {
625         closeEndpoints();
626         closeConfig();
627     }
628     mPtp = usePtp;
629 
630     if (!initFunctionfs()) {
631         ret = -1;
632     }
633     mLock.unlock();
634     return ret;
635 }
636 
close()637 void MtpFfsHandle::close() {
638     closeEndpoints();
639     mLock.unlock();
640 }
641 
642 /* Read from USB and write to a local file. */
receiveFile(mtp_file_range mfr,bool zero_packet)643 int MtpFfsHandle::receiveFile(mtp_file_range mfr, bool zero_packet) {
644     // When receiving files, the incoming length is given in 32 bits.
645     // A >4G file is given as 0xFFFFFFFF
646     uint32_t file_length = mfr.length;
647     uint64_t offset = mfr.offset;
648     struct usb_endpoint_descriptor mBulkOut_desc;
649     int packet_size;
650 
651     if (ioctl(mBulkOut, FUNCTIONFS_ENDPOINT_DESC, reinterpret_cast<unsigned long>(&mBulkOut_desc))) {
652         PLOG(ERROR) << "Could not get FFS bulk-out descriptor";
653         packet_size = MAX_PACKET_SIZE_HS;
654     } else {
655         packet_size = mBulkOut_desc.wMaxPacketSize;
656     }
657 
658     char *data = mBuffer1.data();
659     char *data2 = mBuffer2.data();
660 
661     struct aiocb aio;
662     aio.aio_fildes = mfr.fd;
663     aio.aio_buf = nullptr;
664     struct aiocb *aiol[] = {&aio};
665     int ret = -1;
666     size_t length;
667     bool read = false;
668     bool write = false;
669     bool short_packet = false;
670 
671     posix_fadvise(mfr.fd, 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE);
672 
673     // Break down the file into pieces that fit in buffers
674     while (file_length > 0 || write) {
675         if (file_length > 0) {
676             length = std::min(static_cast<uint32_t>(MAX_FILE_CHUNK_SIZE), file_length);
677 
678             // Read data from USB, handle errors after waiting for write thread.
679             ret = readHandle(mBulkOut, data, length);
680 
681             if (file_length != MAX_MTP_FILE_SIZE && ret < static_cast<int>(length)) {
682                 ret = -1;
683                 errno = EIO;
684             }
685             read = true;
686         }
687 
688         if (write) {
689             // get the return status of the last write request
690             aio_suspend(aiol, 1, nullptr);
691 
692             int written = aio_return(&aio);
693             if (written == -1) {
694                 errno = aio_error(&aio);
695                 return -1;
696             }
697             if (static_cast<size_t>(written) < aio.aio_nbytes) {
698                 errno = EIO;
699                 return -1;
700             }
701             write = false;
702         }
703 
704         // If there was an error reading above
705         if (ret == -1) {
706             return -1;
707         }
708 
709         if (read) {
710             if (file_length == MAX_MTP_FILE_SIZE) {
711                 // For larger files, receive until a short packet is received.
712                 if (static_cast<size_t>(ret) < length) {
713                     file_length = 0;
714                     short_packet = true;
715                 }
716             } else {
717                 // Receive an empty packet if size is a multiple of the endpoint size.
718                 file_length -= ret;
719             }
720             // Enqueue a new write request
721             aio.aio_buf = data;
722             aio.aio_sink = mfr.fd;
723             aio.aio_offset = offset;
724             aio.aio_nbytes = ret;
725             aio_write(&aio);
726 
727             offset += ret;
728             std::swap(data, data2);
729 
730             write = true;
731             read = false;
732         }
733     }
734     if ((ret % packet_size == 0 && !short_packet) || zero_packet) {
735         if (TEMP_FAILURE_RETRY(::read(mBulkOut, data, packet_size)) != 0) {
736             return -1;
737         }
738     }
739     return 0;
740 }
741 
742 /* Read from a local file and send over USB. */
sendFile(mtp_file_range mfr)743 int MtpFfsHandle::sendFile(mtp_file_range mfr) {
744     uint64_t file_length = mfr.length;
745     uint32_t given_length = std::min(static_cast<uint64_t>(MAX_MTP_FILE_SIZE),
746             file_length + sizeof(mtp_data_header));
747     uint64_t offset = mfr.offset;
748     struct usb_endpoint_descriptor mBulkIn_desc;
749     int packet_size;
750 
751     if (ioctl(mBulkIn, FUNCTIONFS_ENDPOINT_DESC, reinterpret_cast<unsigned long>(&mBulkIn_desc))) {
752         PLOG(ERROR) << "Could not get FFS bulk-in descriptor";
753         packet_size = MAX_PACKET_SIZE_HS;
754     } else {
755         packet_size = mBulkIn_desc.wMaxPacketSize;
756     }
757 
758     // If file_length is larger than a size_t, truncating would produce the wrong comparison.
759     // Instead, promote the left side to 64 bits, then truncate the small result.
760     int init_read_len = std::min(
761             static_cast<uint64_t>(packet_size - sizeof(mtp_data_header)), file_length);
762 
763     char *data = mBuffer1.data();
764     char *data2 = mBuffer2.data();
765 
766     posix_fadvise(mfr.fd, 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE);
767 
768     struct aiocb aio;
769     aio.aio_fildes = mfr.fd;
770     struct aiocb *aiol[] = {&aio};
771     int ret, length;
772     int error = 0;
773     bool read = false;
774     bool write = false;
775 
776     // Send the header data
777     mtp_data_header *header = reinterpret_cast<mtp_data_header*>(data);
778     header->length = __cpu_to_le32(given_length);
779     header->type = __cpu_to_le16(2); /* data packet */
780     header->command = __cpu_to_le16(mfr.command);
781     header->transaction_id = __cpu_to_le32(mfr.transaction_id);
782 
783     // Some hosts don't support header/data separation even though MTP allows it
784     // Handle by filling first packet with initial file data
785     if (TEMP_FAILURE_RETRY(pread(mfr.fd, reinterpret_cast<char*>(data) +
786                     sizeof(mtp_data_header), init_read_len, offset))
787             != init_read_len) return -1;
788     if (writeHandle(mBulkIn, data, sizeof(mtp_data_header) + init_read_len) == -1) return -1;
789     file_length -= init_read_len;
790     offset += init_read_len;
791     ret = init_read_len + sizeof(mtp_data_header);
792 
793     // Break down the file into pieces that fit in buffers
794     while(file_length > 0) {
795         if (read) {
796             // Wait for the previous read to finish
797             aio_suspend(aiol, 1, nullptr);
798             ret = aio_return(&aio);
799             if (ret == -1) {
800                 errno = aio_error(&aio);
801                 return -1;
802             }
803             if (static_cast<size_t>(ret) < aio.aio_nbytes) {
804                 errno = EIO;
805                 return -1;
806             }
807 
808             file_length -= ret;
809             offset += ret;
810             std::swap(data, data2);
811             read = false;
812             write = true;
813         }
814 
815         if (error == -1) {
816             return -1;
817         }
818 
819         if (file_length > 0) {
820             length = std::min(static_cast<uint64_t>(MAX_FILE_CHUNK_SIZE), file_length);
821             // Queue up another read
822             aio.aio_buf = data;
823             aio.aio_offset = offset;
824             aio.aio_nbytes = length;
825             aio_read(&aio);
826             read = true;
827         }
828 
829         if (write) {
830             if (writeHandle(mBulkIn, data2, ret) == -1) {
831                 error = -1;
832             }
833             write = false;
834         }
835     }
836 
837     if (ret % packet_size == 0) {
838         // If the last packet wasn't short, send a final empty packet
839         if (TEMP_FAILURE_RETRY(::write(mBulkIn, data, 0)) != 0) {
840             return -1;
841         }
842     }
843 
844     return 0;
845 }
846 
sendEvent(mtp_event me)847 int MtpFfsHandle::sendEvent(mtp_event me) {
848     // Mimic the behavior of f_mtp by sending the event async.
849     // Events aren't critical to the connection, so we don't need to check the return value.
850     char *temp = new char[me.length];
851     memcpy(temp, me.data, me.length);
852     me.data = temp;
853     std::thread t([this, me]() { return this->doSendEvent(me); });
854     t.detach();
855     return 0;
856 }
857 
doSendEvent(mtp_event me)858 void MtpFfsHandle::doSendEvent(mtp_event me) {
859     unsigned length = me.length;
860     int ret = ::write(mIntr, me.data, length);
861     if (static_cast<unsigned>(ret) != length)
862         PLOG(ERROR) << "Mtp error sending event thread!";
863     delete[] reinterpret_cast<char*>(me.data);
864 }
865 
866 } // namespace android
867 
get_ffs_handle()868 IMtpHandle *get_ffs_handle() {
869     return new android::MtpFfsHandle();
870 }
871 
872