1487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang/*
2487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * Copyright (C) 2016 The Android Open Source Project
3487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang *
4487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * Licensed under the Apache License, Version 2.0 (the "License");
5487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * you may not use this file except in compliance with the License.
6487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * You may obtain a copy of the License at
7487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang *
8487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang *      http://www.apache.org/licenses/LICENSE-2.0
9487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang *
10487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * Unless required by applicable law or agreed to in writing, software
11487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * distributed under the License is distributed on an "AS IS" BASIS,
12487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or         implied.
13487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * See the License for the specific language governing permissions and
14487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang * limitations under the License.
15487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang */
16487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
17487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <utils/Log.h>
18487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <fcntl.h>
19487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <sys/stat.h>
20487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <cutils/properties.h>
21487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <dirent.h>
22487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <errno.h>
23487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <linux/usb/ch9.h>
24487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <stdio.h>
25487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <stdlib.h>
26487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <string.h>
27487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <sys/ioctl.h>
28487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <sys/types.h>
29487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <sys/endian.h>
30487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <unistd.h>
31487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
32487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <android-base/logging.h>
33487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include <android-base/unique_fd.h>
34487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang#include "IMtpHandle.h"
35487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
36487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangconstexpr char mtp_dev_path[] = "/dev/mtp_usb";
37487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
38487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangclass MtpDevHandle : public IMtpHandle {
39487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangprivate:
40487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    android::base::unique_fd mFd;
41487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
42487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangpublic:
43487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    MtpDevHandle();
44487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    ~MtpDevHandle();
45487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    int read(void *data, int len);
46487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    int write(const void *data, int len);
47487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
485410756e75fb7567540f13d3813f42f4ac3838a0Jerry Zhang    int receiveFile(mtp_file_range mfr, bool);
49487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    int sendFile(mtp_file_range mfr);
50487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    int sendEvent(mtp_event me);
51487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
52487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    int start();
53487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    void close();
54487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
55487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    int configure(bool ptp);
56487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang};
57487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
58487be61fb0a38873aec1d12da92437fba5e728f2Jerry ZhangMtpDevHandle::MtpDevHandle()
59487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    : mFd(-1) {};
60487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
61487be61fb0a38873aec1d12da92437fba5e728f2Jerry ZhangMtpDevHandle::~MtpDevHandle() {}
62487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
63487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint MtpDevHandle::read(void *data, int len) {
64487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    return ::read(mFd, data, len);
65487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang}
66487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
67487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint MtpDevHandle::write(const void *data, int len) {
68487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    return ::write(mFd, data, len);
69487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang}
70487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
715410756e75fb7567540f13d3813f42f4ac3838a0Jerry Zhangint MtpDevHandle::receiveFile(mtp_file_range mfr, bool) {
72487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    return ioctl(mFd, MTP_RECEIVE_FILE, reinterpret_cast<unsigned long>(&mfr));
73487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang}
74487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
75487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint MtpDevHandle::sendFile(mtp_file_range mfr) {
76487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    return ioctl(mFd, MTP_SEND_FILE_WITH_HEADER, reinterpret_cast<unsigned long>(&mfr));
77487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang}
78487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
79487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint MtpDevHandle::sendEvent(mtp_event me) {
80487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    return ioctl(mFd, MTP_SEND_EVENT, reinterpret_cast<unsigned long>(&me));
81487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang}
82487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
83487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint MtpDevHandle::start() {
84487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    mFd = android::base::unique_fd(TEMP_FAILURE_RETRY(open(mtp_dev_path, O_RDWR)));
85487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    if (mFd == -1) return -1;
86487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    return 0;
87487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang}
88487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
89487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangvoid MtpDevHandle::close() {
90487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    mFd.reset();
91487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang}
92487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
93487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhangint MtpDevHandle::configure(bool) {
94487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    // Nothing to do, driver can configure itself
95487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    return 0;
96487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang}
97487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang
98487be61fb0a38873aec1d12da92437fba5e728f2Jerry ZhangIMtpHandle *get_mtp_handle() {
99487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang    return new MtpDevHandle();
100487be61fb0a38873aec1d12da92437fba5e728f2Jerry Zhang}
101