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 <asyncio/AsyncIO.h>
20 #include <dirent.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <memory>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/eventfd.h>
28 #include <sys/ioctl.h>
29 #include <sys/mman.h>
30 #include <sys/poll.h>
31 #include <sys/stat.h>
32 #include <sys/types.h>
33 #include <unistd.h>
34
35 #include "PosixAsyncIO.h"
36 #include "MtpDescriptors.h"
37 #include "MtpFfsHandle.h"
38 #include "mtp.h"
39
40 namespace {
41
42 constexpr unsigned AIO_BUFS_MAX = 128;
43 constexpr unsigned AIO_BUF_LEN = 16384;
44
45 constexpr unsigned FFS_NUM_EVENTS = 5;
46
47 constexpr unsigned MAX_FILE_CHUNK_SIZE = AIO_BUFS_MAX * AIO_BUF_LEN;
48
49 constexpr uint32_t MAX_MTP_FILE_SIZE = 0xFFFFFFFF;
50 // Note: POLL_TIMEOUT_MS = 0 means return immediately i.e. no sleep.
51 // And this will cause high CPU usage.
52 constexpr int32_t POLL_TIMEOUT_MS = 500;
53
54 struct timespec ZERO_TIMEOUT = { 0, 0 };
55
56 struct mtp_device_status {
57 uint16_t wLength;
58 uint16_t wCode;
59 };
60
61 } // anonymous namespace
62
63 namespace android {
64
getPacketSize(int ffs_fd)65 int MtpFfsHandle::getPacketSize(int ffs_fd) {
66 struct usb_endpoint_descriptor desc;
67 if (ioctl(ffs_fd, FUNCTIONFS_ENDPOINT_DESC, reinterpret_cast<unsigned long>(&desc))) {
68 PLOG(ERROR) << "Could not get FFS bulk-in descriptor";
69 return MAX_PACKET_SIZE_HS;
70 } else {
71 return desc.wMaxPacketSize;
72 }
73 }
74
MtpFfsHandle(int controlFd)75 MtpFfsHandle::MtpFfsHandle(int controlFd) {
76 mControl.reset(controlFd);
77 }
78
~MtpFfsHandle()79 MtpFfsHandle::~MtpFfsHandle() {}
80
closeEndpoints()81 void MtpFfsHandle::closeEndpoints() {
82 mIntr.reset();
83 mBulkIn.reset();
84 mBulkOut.reset();
85 }
86
openEndpoints(bool ptp)87 bool MtpFfsHandle::openEndpoints(bool ptp) {
88 if (mBulkIn < 0) {
89 mBulkIn.reset(TEMP_FAILURE_RETRY(open(ptp ? FFS_PTP_EP_IN : FFS_MTP_EP_IN, O_RDWR)));
90 if (mBulkIn < 0) {
91 PLOG(ERROR) << (ptp ? FFS_PTP_EP_IN : FFS_MTP_EP_IN) << ": cannot open bulk in ep";
92 return false;
93 }
94 }
95
96 if (mBulkOut < 0) {
97 mBulkOut.reset(TEMP_FAILURE_RETRY(open(ptp ? FFS_PTP_EP_OUT : FFS_MTP_EP_OUT, O_RDWR)));
98 if (mBulkOut < 0) {
99 PLOG(ERROR) << (ptp ? FFS_PTP_EP_OUT : FFS_MTP_EP_OUT) << ": cannot open bulk out ep";
100 return false;
101 }
102 }
103
104 if (mIntr < 0) {
105 mIntr.reset(TEMP_FAILURE_RETRY(open(ptp ? FFS_PTP_EP_INTR : FFS_MTP_EP_INTR, O_RDWR)));
106 if (mIntr < 0) {
107 PLOG(ERROR) << (ptp ? FFS_PTP_EP_INTR : FFS_MTP_EP_INTR) << ": cannot open intr ep";
108 return false;
109 }
110 }
111 return true;
112 }
113
advise(int fd)114 void MtpFfsHandle::advise(int fd) {
115 for (unsigned i = 0; i < NUM_IO_BUFS; i++) {
116 if (posix_madvise(mIobuf[i].bufs.data(), MAX_FILE_CHUNK_SIZE,
117 POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED) < 0)
118 PLOG(ERROR) << "Failed to madvise";
119 }
120 if (posix_fadvise(fd, 0, 0,
121 POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE | POSIX_FADV_WILLNEED) < 0)
122 PLOG(ERROR) << "Failed to fadvise";
123 }
124
writeDescriptors(bool ptp)125 bool MtpFfsHandle::writeDescriptors(bool ptp) {
126 return ::android::writeDescriptors(mControl, ptp);
127 }
128
closeConfig()129 void MtpFfsHandle::closeConfig() {
130 mControl.reset();
131 }
132
doAsync(void * data,size_t len,bool read,bool zero_packet)133 int MtpFfsHandle::doAsync(void* data, size_t len, bool read, bool zero_packet) {
134 struct io_event ioevs[AIO_BUFS_MAX];
135 size_t total = 0;
136
137 while (total < len) {
138 size_t this_len = std::min(len - total, static_cast<size_t>(AIO_BUF_LEN * AIO_BUFS_MAX));
139 int num_bufs = this_len / AIO_BUF_LEN + (this_len % AIO_BUF_LEN == 0 ? 0 : 1);
140 for (int i = 0; i < num_bufs; i++) {
141 mIobuf[0].buf[i] = reinterpret_cast<unsigned char*>(data) + total + i * AIO_BUF_LEN;
142 }
143 int ret = iobufSubmit(&mIobuf[0], read ? mBulkOut : mBulkIn, this_len, read);
144 if (ret < 0) return -1;
145 ret = waitEvents(&mIobuf[0], ret, ioevs, nullptr);
146 if (ret < 0) return -1;
147 total += ret;
148 if (static_cast<size_t>(ret) < this_len) break;
149 }
150
151 int packet_size = getPacketSize(read ? mBulkOut : mBulkIn);
152 if (len % packet_size == 0 && zero_packet) {
153 int ret = iobufSubmit(&mIobuf[0], read ? mBulkOut : mBulkIn, 0, read);
154 if (ret < 0) return -1;
155 ret = waitEvents(&mIobuf[0], ret, ioevs, nullptr);
156 if (ret < 0) return -1;
157 }
158
159 for (unsigned i = 0; i < AIO_BUFS_MAX; i++) {
160 mIobuf[0].buf[i] = mIobuf[0].bufs.data() + i * AIO_BUF_LEN;
161 }
162 return total;
163 }
164
read(void * data,size_t len)165 int MtpFfsHandle::read(void* data, size_t len) {
166 // Zero packets are handled by receiveFile()
167 return doAsync(data, len, true, false);
168 }
169
write(const void * data,size_t len)170 int MtpFfsHandle::write(const void* data, size_t len) {
171 return doAsync(const_cast<void*>(data), len, false, true);
172 }
173
handleEvent()174 int MtpFfsHandle::handleEvent() {
175
176 std::vector<usb_functionfs_event> events(FFS_NUM_EVENTS);
177 usb_functionfs_event *event = events.data();
178 int nbytes = TEMP_FAILURE_RETRY(::read(mControl, event,
179 events.size() * sizeof(usb_functionfs_event)));
180 if (nbytes == -1) {
181 return -1;
182 }
183 int ret = 0;
184 for (size_t n = nbytes / sizeof *event; n; --n, ++event) {
185 switch (event->type) {
186 case FUNCTIONFS_BIND:
187 case FUNCTIONFS_ENABLE:
188 ret = 0;
189 errno = 0;
190 break;
191 case FUNCTIONFS_UNBIND:
192 case FUNCTIONFS_DISABLE:
193 errno = ESHUTDOWN;
194 ret = -1;
195 break;
196 case FUNCTIONFS_SETUP:
197 if (handleControlRequest(&event->u.setup) == -1)
198 ret = -1;
199 break;
200 case FUNCTIONFS_SUSPEND:
201 case FUNCTIONFS_RESUME:
202 break;
203 default:
204 LOG(ERROR) << "Mtp Event " << event->type << " (unknown)";
205 }
206 }
207 return ret;
208 }
209
handleControlRequest(const struct usb_ctrlrequest * setup)210 int MtpFfsHandle::handleControlRequest(const struct usb_ctrlrequest *setup) {
211 uint8_t type = setup->bRequestType;
212 uint8_t code = setup->bRequest;
213 uint16_t length = setup->wLength;
214 uint16_t index = setup->wIndex;
215 uint16_t value = setup->wValue;
216 std::vector<char> buf;
217 buf.resize(length);
218
219 if (!(type & USB_DIR_IN)) {
220 if (::read(mControl, buf.data(), length) != length) {
221 PLOG(ERROR) << "Mtp error ctrlreq read data";
222 }
223 }
224
225 if ((type & USB_TYPE_MASK) == USB_TYPE_CLASS && index == 0 && value == 0) {
226 switch(code) {
227 case MTP_REQ_RESET:
228 case MTP_REQ_CANCEL:
229 errno = ECANCELED;
230 return -1;
231 // break;
232 case MTP_REQ_GET_DEVICE_STATUS:
233 {
234 if (length < sizeof(struct mtp_device_status) + 4) {
235 errno = EINVAL;
236 return -1;
237 }
238 struct mtp_device_status *st = reinterpret_cast<struct mtp_device_status*>(buf.data());
239 st->wLength = htole16(sizeof(st));
240 if (mCanceled) {
241 st->wLength += 4;
242 st->wCode = MTP_RESPONSE_TRANSACTION_CANCELLED;
243 uint16_t *endpoints = reinterpret_cast<uint16_t*>(st + 1);
244 endpoints[0] = ioctl(mBulkIn, FUNCTIONFS_ENDPOINT_REVMAP);
245 endpoints[1] = ioctl(mBulkOut, FUNCTIONFS_ENDPOINT_REVMAP);
246 mCanceled = false;
247 } else {
248 st->wCode = MTP_RESPONSE_OK;
249 }
250 length = st->wLength;
251 break;
252 }
253 default:
254 LOG(ERROR) << "Unrecognized Mtp class request! " << code;
255 }
256 } else {
257 LOG(ERROR) << "Unrecognized request type " << type;
258 }
259
260 if (type & USB_DIR_IN) {
261 if (::write(mControl, buf.data(), length) != length) {
262 PLOG(ERROR) << "Mtp error ctrlreq write data";
263 }
264 }
265 return 0;
266 }
267
start(bool ptp)268 int MtpFfsHandle::start(bool ptp) {
269 if (!openEndpoints(ptp))
270 return -1;
271
272 for (unsigned i = 0; i < NUM_IO_BUFS; i++) {
273 mIobuf[i].bufs.resize(MAX_FILE_CHUNK_SIZE);
274 mIobuf[i].iocb.resize(AIO_BUFS_MAX);
275 mIobuf[i].iocbs.resize(AIO_BUFS_MAX);
276 mIobuf[i].buf.resize(AIO_BUFS_MAX);
277 for (unsigned j = 0; j < AIO_BUFS_MAX; j++) {
278 mIobuf[i].buf[j] = mIobuf[i].bufs.data() + j * AIO_BUF_LEN;
279 mIobuf[i].iocb[j] = &mIobuf[i].iocbs[j];
280 }
281 }
282
283 memset(&mCtx, 0, sizeof(mCtx));
284 if (io_setup(AIO_BUFS_MAX, &mCtx) < 0) {
285 PLOG(ERROR) << "unable to setup aio";
286 return -1;
287 }
288 mEventFd.reset(eventfd(0, EFD_NONBLOCK));
289 mPollFds[0].fd = mControl;
290 mPollFds[0].events = POLLIN;
291 mPollFds[1].fd = mEventFd;
292 mPollFds[1].events = POLLIN;
293
294 mCanceled = false;
295 return 0;
296 }
297
close()298 void MtpFfsHandle::close() {
299 io_destroy(mCtx);
300 closeEndpoints();
301 closeConfig();
302 }
303
waitEvents(struct io_buffer * buf,int min_events,struct io_event * events,int * counter)304 int MtpFfsHandle::waitEvents(struct io_buffer *buf, int min_events, struct io_event *events,
305 int *counter) {
306 int num_events = 0;
307 int ret = 0;
308 int error = 0;
309
310 while (num_events < min_events) {
311 if (poll(mPollFds, 2, POLL_TIMEOUT_MS) == -1) {
312 PLOG(ERROR) << "Mtp error during poll()";
313 return -1;
314 }
315 if (mPollFds[0].revents & POLLIN) {
316 mPollFds[0].revents = 0;
317 if (handleEvent() == -1) {
318 error = errno;
319 }
320 }
321 if (mPollFds[1].revents & POLLIN) {
322 mPollFds[1].revents = 0;
323 uint64_t ev_cnt = 0;
324
325 if (::read(mEventFd, &ev_cnt, sizeof(ev_cnt)) == -1) {
326 PLOG(ERROR) << "Mtp unable to read eventfd";
327 error = errno;
328 continue;
329 }
330
331 // It's possible that io_getevents will return more events than the eventFd reported,
332 // since events may appear in the time between the calls. In this case, the eventFd will
333 // show up as readable next iteration, but there will be fewer or no events to actually
334 // wait for. Thus we never want io_getevents to block.
335 int this_events = TEMP_FAILURE_RETRY(io_getevents(mCtx, 0, AIO_BUFS_MAX, events, &ZERO_TIMEOUT));
336 if (this_events == -1) {
337 PLOG(ERROR) << "Mtp error getting events";
338 error = errno;
339 }
340 // Add up the total amount of data and find errors on the way.
341 for (unsigned j = 0; j < static_cast<unsigned>(this_events); j++) {
342 if (events[j].res < 0) {
343 errno = -events[j].res;
344 PLOG(ERROR) << "Mtp got error event at " << j << " and " << buf->actual << " total";
345 error = errno;
346 }
347 ret += events[j].res;
348 }
349 num_events += this_events;
350 if (counter)
351 *counter += this_events;
352 }
353 if (error) {
354 errno = error;
355 ret = -1;
356 break;
357 }
358 }
359 return ret;
360 }
361
cancelTransaction()362 void MtpFfsHandle::cancelTransaction() {
363 // Device cancels by stalling both bulk endpoints.
364 if (::read(mBulkIn, nullptr, 0) != -1 || errno != EBADMSG)
365 PLOG(ERROR) << "Mtp stall failed on bulk in";
366 if (::write(mBulkOut, nullptr, 0) != -1 || errno != EBADMSG)
367 PLOG(ERROR) << "Mtp stall failed on bulk out";
368 mCanceled = true;
369 errno = ECANCELED;
370 }
371
cancelEvents(struct iocb ** iocb,struct io_event * events,unsigned start,unsigned end)372 int MtpFfsHandle::cancelEvents(struct iocb **iocb, struct io_event *events, unsigned start,
373 unsigned end) {
374 // Some manpages for io_cancel are out of date and incorrect.
375 // io_cancel will return -EINPROGRESS on success and does
376 // not place the event in the given memory. We have to use
377 // io_getevents to wait for all the events we cancelled.
378 int ret = 0;
379 unsigned num_events = 0;
380 int save_errno = errno;
381 errno = 0;
382
383 for (unsigned j = start; j < end; j++) {
384 if (io_cancel(mCtx, iocb[j], nullptr) != -1 || errno != EINPROGRESS) {
385 PLOG(ERROR) << "Mtp couldn't cancel request " << j;
386 } else {
387 num_events++;
388 }
389 }
390 if (num_events != end - start) {
391 ret = -1;
392 errno = EIO;
393 }
394 int evs = TEMP_FAILURE_RETRY(io_getevents(mCtx, num_events, AIO_BUFS_MAX, events, nullptr));
395 if (static_cast<unsigned>(evs) != num_events) {
396 PLOG(ERROR) << "Mtp couldn't cancel all requests, got " << evs;
397 ret = -1;
398 }
399
400 uint64_t ev_cnt = 0;
401 if (num_events && ::read(mEventFd, &ev_cnt, sizeof(ev_cnt)) == -1)
402 PLOG(ERROR) << "Mtp Unable to read event fd";
403
404 if (ret == 0) {
405 // Restore errno since it probably got overriden with EINPROGRESS.
406 errno = save_errno;
407 }
408 return ret;
409 }
410
iobufSubmit(struct io_buffer * buf,int fd,unsigned length,bool read)411 int MtpFfsHandle::iobufSubmit(struct io_buffer *buf, int fd, unsigned length, bool read) {
412 int ret = 0;
413 buf->actual = AIO_BUFS_MAX;
414 for (unsigned j = 0; j < AIO_BUFS_MAX; j++) {
415 unsigned rq_length = std::min(AIO_BUF_LEN, length - AIO_BUF_LEN * j);
416 io_prep(buf->iocb[j], fd, buf->buf[j], rq_length, 0, read);
417 buf->iocb[j]->aio_flags |= IOCB_FLAG_RESFD;
418 buf->iocb[j]->aio_resfd = mEventFd;
419
420 // Not enough data, so table is truncated.
421 if (rq_length < AIO_BUF_LEN || length == AIO_BUF_LEN * (j + 1)) {
422 buf->actual = j + 1;
423 break;
424 }
425 }
426
427 ret = io_submit(mCtx, buf->actual, buf->iocb.data());
428 if (ret != static_cast<int>(buf->actual)) {
429 PLOG(ERROR) << "Mtp io_submit got " << ret << " expected " << buf->actual;
430 if (ret != -1) {
431 errno = EIO;
432 }
433 ret = -1;
434 }
435 return ret;
436 }
437
receiveFile(mtp_file_range mfr,bool zero_packet)438 int MtpFfsHandle::receiveFile(mtp_file_range mfr, bool zero_packet) {
439 // When receiving files, the incoming length is given in 32 bits.
440 // A >=4G file is given as 0xFFFFFFFF
441 uint32_t file_length = mfr.length;
442 uint64_t offset = mfr.offset;
443
444 struct aiocb aio;
445 aio.aio_fildes = mfr.fd;
446 aio.aio_buf = nullptr;
447 struct aiocb *aiol[] = {&aio};
448
449 int ret = -1;
450 unsigned i = 0;
451 size_t length;
452 struct io_event ioevs[AIO_BUFS_MAX];
453 bool has_write = false;
454 bool error = false;
455 bool write_error = false;
456 int packet_size = getPacketSize(mBulkOut);
457 bool short_packet = false;
458 advise(mfr.fd);
459
460 // Break down the file into pieces that fit in buffers
461 while (file_length > 0 || has_write) {
462 // Queue an asynchronous read from USB.
463 if (file_length > 0) {
464 length = std::min(static_cast<uint32_t>(MAX_FILE_CHUNK_SIZE), file_length);
465 if (iobufSubmit(&mIobuf[i], mBulkOut, length, true) == -1)
466 error = true;
467 }
468
469 // Get the return status of the last write request.
470 if (has_write) {
471 aio_suspend(aiol, 1, nullptr);
472 int written = aio_return(&aio);
473 if (static_cast<size_t>(written) < aio.aio_nbytes) {
474 errno = written == -1 ? aio_error(&aio) : EIO;
475 PLOG(ERROR) << "Mtp error writing to disk";
476 write_error = true;
477 }
478 has_write = false;
479 }
480
481 if (error) {
482 return -1;
483 }
484
485 // Get the result of the read request, and queue a write to disk.
486 if (file_length > 0) {
487 unsigned num_events = 0;
488 ret = 0;
489 unsigned short_i = mIobuf[i].actual;
490 while (num_events < short_i) {
491 // Get all events up to the short read, if there is one.
492 // We must wait for each event since data transfer could end at any time.
493 int this_events = 0;
494 int event_ret = waitEvents(&mIobuf[i], 1, ioevs, &this_events);
495 num_events += this_events;
496
497 if (event_ret == -1) {
498 cancelEvents(mIobuf[i].iocb.data(), ioevs, num_events, mIobuf[i].actual);
499 return -1;
500 }
501 ret += event_ret;
502 for (int j = 0; j < this_events; j++) {
503 // struct io_event contains a pointer to the associated struct iocb as a __u64.
504 if (static_cast<__u64>(ioevs[j].res) <
505 reinterpret_cast<struct iocb*>(ioevs[j].obj)->aio_nbytes) {
506 // We've found a short event. Store the index since
507 // events won't necessarily arrive in the order they are queued.
508 short_i = (ioevs[j].obj - reinterpret_cast<uint64_t>(mIobuf[i].iocbs.data()))
509 / sizeof(struct iocb) + 1;
510 short_packet = true;
511 }
512 }
513 }
514 if (short_packet) {
515 if (cancelEvents(mIobuf[i].iocb.data(), ioevs, short_i, mIobuf[i].actual)) {
516 write_error = true;
517 }
518 }
519 if (file_length == MAX_MTP_FILE_SIZE) {
520 // For larger files, receive until a short packet is received.
521 if (static_cast<size_t>(ret) < length) {
522 file_length = 0;
523 }
524 } else if (ret < static_cast<int>(length)) {
525 // If file is less than 4G and we get a short packet, it's an error.
526 errno = EIO;
527 LOG(ERROR) << "Mtp got unexpected short packet";
528 return -1;
529 } else {
530 file_length -= ret;
531 }
532
533 if (write_error) {
534 cancelTransaction();
535 return -1;
536 }
537
538 // Enqueue a new write request
539 aio_prepare(&aio, mIobuf[i].bufs.data(), ret, offset);
540 aio_write(&aio);
541
542 offset += ret;
543 i = (i + 1) % NUM_IO_BUFS;
544 has_write = true;
545 }
546 }
547 if ((ret % packet_size == 0 && !short_packet) || zero_packet) {
548 // Receive an empty packet if size is a multiple of the endpoint size
549 // and we didn't already get an empty packet from the header or large file.
550 if (read(mIobuf[0].bufs.data(), packet_size) != 0) {
551 return -1;
552 }
553 }
554 return 0;
555 }
556
sendFile(mtp_file_range mfr)557 int MtpFfsHandle::sendFile(mtp_file_range mfr) {
558 uint64_t file_length = mfr.length;
559 uint32_t given_length = std::min(static_cast<uint64_t>(MAX_MTP_FILE_SIZE),
560 file_length + sizeof(mtp_data_header));
561 uint64_t offset = mfr.offset;
562 int packet_size = getPacketSize(mBulkIn);
563
564 // If file_length is larger than a size_t, truncating would produce the wrong comparison.
565 // Instead, promote the left side to 64 bits, then truncate the small result.
566 int init_read_len = std::min(
567 static_cast<uint64_t>(packet_size - sizeof(mtp_data_header)), file_length);
568
569 advise(mfr.fd);
570
571 struct aiocb aio;
572 aio.aio_fildes = mfr.fd;
573 struct aiocb *aiol[] = {&aio};
574 int ret = 0;
575 int length, num_read;
576 unsigned i = 0;
577 struct io_event ioevs[AIO_BUFS_MAX];
578 bool error = false;
579 bool has_write = false;
580
581 // Send the header data
582 mtp_data_header *header = reinterpret_cast<mtp_data_header*>(mIobuf[0].bufs.data());
583 header->length = htole32(given_length);
584 header->type = htole16(2); // data packet
585 header->command = htole16(mfr.command);
586 header->transaction_id = htole32(mfr.transaction_id);
587
588 // Some hosts don't support header/data separation even though MTP allows it
589 // Handle by filling first packet with initial file data
590 if (TEMP_FAILURE_RETRY(pread(mfr.fd, mIobuf[0].bufs.data() +
591 sizeof(mtp_data_header), init_read_len, offset))
592 != init_read_len) return -1;
593 if (doAsync(mIobuf[0].bufs.data(), sizeof(mtp_data_header) + init_read_len,
594 false, false /* zlps are handled below */) == -1)
595 return -1;
596 file_length -= init_read_len;
597 offset += init_read_len;
598 ret = init_read_len + sizeof(mtp_data_header);
599
600 // Break down the file into pieces that fit in buffers
601 while(file_length > 0 || has_write) {
602 if (file_length > 0) {
603 // Queue up a read from disk.
604 length = std::min(static_cast<uint64_t>(MAX_FILE_CHUNK_SIZE), file_length);
605 aio_prepare(&aio, mIobuf[i].bufs.data(), length, offset);
606 aio_read(&aio);
607 }
608
609 if (has_write) {
610 // Wait for usb write. Cancel unwritten portion if there's an error.
611 int num_events = 0;
612 if (waitEvents(&mIobuf[(i-1)%NUM_IO_BUFS], mIobuf[(i-1)%NUM_IO_BUFS].actual, ioevs,
613 &num_events) != ret) {
614 error = true;
615 cancelEvents(mIobuf[(i-1)%NUM_IO_BUFS].iocb.data(), ioevs, num_events,
616 mIobuf[(i-1)%NUM_IO_BUFS].actual);
617 }
618 has_write = false;
619 }
620
621 if (file_length > 0) {
622 // Wait for the previous read to finish
623 aio_suspend(aiol, 1, nullptr);
624 num_read = aio_return(&aio);
625 if (static_cast<size_t>(num_read) < aio.aio_nbytes) {
626 errno = num_read == -1 ? aio_error(&aio) : EIO;
627 PLOG(ERROR) << "Mtp error reading from disk";
628 cancelTransaction();
629 return -1;
630 }
631
632 file_length -= num_read;
633 offset += num_read;
634
635 if (error) {
636 return -1;
637 }
638
639 // Queue up a write to usb.
640 if (iobufSubmit(&mIobuf[i], mBulkIn, num_read, false) == -1) {
641 return -1;
642 }
643 has_write = true;
644 ret = num_read;
645 }
646
647 i = (i + 1) % NUM_IO_BUFS;
648 }
649
650 if (ret % packet_size == 0) {
651 // If the last packet wasn't short, send a final empty packet
652 if (write(mIobuf[0].bufs.data(), 0) != 0) {
653 return -1;
654 }
655 }
656 return 0;
657 }
658
sendEvent(mtp_event me)659 int MtpFfsHandle::sendEvent(mtp_event me) {
660 // Mimic the behavior of f_mtp by sending the event async.
661 // Events aren't critical to the connection, so we don't need to check the return value.
662 char *temp = new char[me.length];
663 memcpy(temp, me.data, me.length);
664 me.data = temp;
665 std::thread t([this, me]() { return this->doSendEvent(me); });
666 t.detach();
667 return 0;
668 }
669
doSendEvent(mtp_event me)670 void MtpFfsHandle::doSendEvent(mtp_event me) {
671 unsigned length = me.length;
672 int ret = ::write(mIntr, me.data, length);
673 if (static_cast<unsigned>(ret) != length)
674 PLOG(ERROR) << "Mtp error sending event thread!";
675 delete[] reinterpret_cast<char*>(me.data);
676 }
677
678 } // namespace android
679
680