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
MtpFfsHandle()294 MtpFfsHandle::MtpFfsHandle() :
295 mMaxWrite(USB_FFS_MAX_WRITE),
296 mMaxRead(USB_FFS_MAX_READ) {}
297
~MtpFfsHandle()298 MtpFfsHandle::~MtpFfsHandle() {}
299
closeEndpoints()300 void MtpFfsHandle::closeEndpoints() {
301 mIntr.reset();
302 mBulkIn.reset();
303 mBulkOut.reset();
304 }
305
initFunctionfs()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
closeConfig()360 void MtpFfsHandle::closeConfig() {
361 mControl.reset();
362 }
363
writeHandle(int fd,const void * data,int len)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
readHandle(int fd,void * data,int len)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
spliceReadHandle(int fd,int pipe_out,int len)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
read(void * data,int len)427 int MtpFfsHandle::read(void* data, int len) {
428 return readHandle(mBulkOut, data, len);
429 }
430
write(const void * data,int len)431 int MtpFfsHandle::write(const void* data, int len) {
432 return writeHandle(mBulkIn, data, len);
433 }
434
start()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
configure(bool usePtp)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
close()513 void MtpFfsHandle::close() {
514 closeEndpoints();
515 mLock.unlock();
516 }
517
518 /* Read from USB and write to a local file. */
receiveFile(mtp_file_range mfr,bool zero_packet)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. */
sendFile(mtp_file_range mfr)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
sendEvent(mtp_event me)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
get_ffs_handle()729 IMtpHandle *get_ffs_handle() {
730 return new android::MtpFfsHandle();
731 }
732
733