Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fdfe74f9 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "DO NOT MERGE : Add simple control request handling" into oc-mr1-dev

parents aa488ac2 dfb8b169
Loading
Loading
Loading
Loading
+93 −0
Original line number Diff line number Diff line
@@ -62,6 +62,8 @@ constexpr int MAX_FILE_CHUNK_SIZE = 3145728;
constexpr int USB_FFS_MAX_WRITE = MTP_BUFFER_SIZE;
constexpr int USB_FFS_MAX_READ = MTP_BUFFER_SIZE;

constexpr unsigned FFS_NUM_EVENTS = 5;

static_assert(USB_FFS_MAX_WRITE > 0, "Max r/w values must be > 0!");
static_assert(USB_FFS_MAX_READ > 0, "Max r/w values must be > 0!");

@@ -315,6 +317,11 @@ struct usb_ext_compat_desc ptp_os_desc_compat = {
    .Reserved2 = {0},
};

struct mtp_device_status {
    uint16_t  wLength;
    uint16_t  wCode;
};

} // anonymous namespace

namespace android {
@@ -392,6 +399,88 @@ void MtpFfsHandle::closeConfig() {
    mControl.reset();
}

void MtpFfsHandle::controlLoop() {
    while (!handleEvent()) {}
    LOG(DEBUG) << "Mtp server shutting down";
}

int MtpFfsHandle::handleEvent() {
    std::vector<usb_functionfs_event> events(FFS_NUM_EVENTS);
    usb_functionfs_event *event = events.data();
    int nbytes = TEMP_FAILURE_RETRY(::read(mControl, event,
                events.size() * sizeof(usb_functionfs_event)));
    if (nbytes == -1) {
        return -1;
    }
    int ret = 0;
    for (size_t n = nbytes / sizeof *event; n; --n, ++event) {
        switch (event->type) {
        case FUNCTIONFS_BIND:
        case FUNCTIONFS_ENABLE:
        case FUNCTIONFS_RESUME:
            ret = 0;
            errno = 0;
            break;
        case FUNCTIONFS_SUSPEND:
        case FUNCTIONFS_UNBIND:
        case FUNCTIONFS_DISABLE:
            errno = ESHUTDOWN;
            ret = -1;
            break;
        case FUNCTIONFS_SETUP:
            if (handleControlRequest(&event->u.setup) == -1)
                ret = -1;
            break;
        default:
            LOG(DEBUG) << "Mtp Event " << event->type << " (unknown)";
        }
    }
    return ret;
}

int MtpFfsHandle::handleControlRequest(const struct usb_ctrlrequest *setup) {
    uint8_t type = setup->bRequestType;
    uint8_t code = setup->bRequest;
    uint16_t length = setup->wLength;
    uint16_t index = setup->wIndex;
    uint16_t value = setup->wValue;
    std::vector<char> buf;
    buf.resize(length);

    if (!(type & USB_DIR_IN)) {
        if (::read(mControl, buf.data(), length) != length) {
            PLOG(DEBUG) << "Mtp error ctrlreq read data";
        }
    }

    if ((type & USB_TYPE_MASK) == USB_TYPE_CLASS && index == 0 && value == 0) {
        switch(code) {
        case MTP_REQ_GET_DEVICE_STATUS:
        {
            if (length < sizeof(struct mtp_device_status)) {
                return -1;
            }
            struct mtp_device_status *st = reinterpret_cast<struct mtp_device_status*>(buf.data());
            st->wLength = htole16(sizeof(st));
            st->wCode = MTP_RESPONSE_OK;
            length = st->wLength;
            break;
        }
        default:
            LOG(DEBUG) << "Unrecognized Mtp class request! " << code;
        }
    } else {
        LOG(DEBUG) << "Unrecognized request type " << type;
    }

    if (type & USB_DIR_IN) {
        if (::write(mControl, buf.data(), length) != length) {
            PLOG(DEBUG) << "Mtp error ctrlreq write data";
        }
    }
    return 0;
}

int MtpFfsHandle::writeHandle(int fd, const void* data, int len) {
    LOG(VERBOSE) << "MTP about to write fd = " << fd << ", len=" << len;
    int ret = 0;
@@ -491,6 +580,10 @@ int MtpFfsHandle::start() {
    posix_madvise(mBuffer2.data(), MAX_FILE_CHUNK_SIZE,
            POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED);

    // Handle control requests.
    std::thread t([this]() { this->controlLoop(); });
    t.detach();

    // Get device specific r/w size
    mMaxWrite = android::base::GetIntProperty("sys.usb.ffs.max_write", USB_FFS_MAX_WRITE);
    mMaxRead = android::base::GetIntProperty("sys.usb.ffs.max_read", USB_FFS_MAX_READ);
+4 −0
Original line number Diff line number Diff line
@@ -35,6 +35,10 @@ private:
    void closeEndpoints();
    void doSendEvent(mtp_event me);

    void controlLoop();
    int handleEvent();
    int handleControlRequest(const struct usb_ctrlrequest *setup);

    bool mPtp;

    std::timed_mutex mLock;
+6 −0
Original line number Diff line number Diff line
@@ -494,4 +494,10 @@
#define MTP_ASSOCIATION_TYPE_UNDEFINED              0x0000
#define MTP_ASSOCIATION_TYPE_GENERIC_FOLDER         0x0001

// MTP class reqeusts
#define MTP_REQ_CANCEL              0x64
#define MTP_REQ_GET_EXT_EVENT_DATA  0x65
#define MTP_REQ_RESET               0x66
#define MTP_REQ_GET_DEVICE_STATUS   0x67

#endif // _MTP_H