1 /*
2 * Copyright (C) 2017 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 #include <glog/logging.h>
17
18 #include "host/commands/virtual_usb_manager/vadb/usb_cmd_control_transfer.h"
19
20 namespace vadb {
USBCmdControlTransfer(uint8_t bus_id,uint8_t dev_id,uint8_t type,uint8_t request,uint16_t value,uint16_t index,uint32_t timeout,std::vector<uint8_t> data,usbip::Device::AsyncTransferReadyCB callback)21 USBCmdControlTransfer::USBCmdControlTransfer(
22 uint8_t bus_id, uint8_t dev_id, uint8_t type, uint8_t request,
23 uint16_t value, uint16_t index, uint32_t timeout, std::vector<uint8_t> data,
24 usbip::Device::AsyncTransferReadyCB callback)
25 : data_(std::move(data)), callback_(std::move(callback)) {
26 req_.bus_id = bus_id;
27 req_.dev_id = dev_id;
28 req_.type = type;
29 req_.cmd = request;
30 req_.value = value;
31 req_.index = index;
32 req_.length = data_.size();
33 req_.timeout = timeout;
34 }
35
OnRequest(const cvd::SharedFD & fd)36 bool USBCmdControlTransfer::OnRequest(const cvd::SharedFD& fd) {
37 if (fd->Write(&req_, sizeof(req_)) != sizeof(req_)) {
38 LOG(ERROR) << "Short write: " << fd->StrError();
39 return false;
40 }
41
42 if ((req_.type & 0x80) == 0) {
43 if (data_.size() > 0) {
44 if (static_cast<size_t>(fd->Write(data_.data(), data_.size())) !=
45 data_.size()) {
46 LOG(ERROR) << "Short write: " << fd->StrError();
47 return false;
48 }
49 }
50 }
51
52 return true;
53 }
54
OnResponse(bool is_success,const cvd::SharedFD & fd)55 bool USBCmdControlTransfer::OnResponse(bool is_success,
56 const cvd::SharedFD& fd) {
57 if (!is_success) {
58 callback_(false, std::move(data_));
59 return true;
60 }
61
62 if (req_.type & 0x80) {
63 int32_t len;
64 if (fd->Read(&len, sizeof(len)) != sizeof(len)) {
65 LOG(ERROR) << "Short read: " << fd->StrError();
66 callback_(false, std::move(data_));
67 return false;
68 }
69
70 if (len > 0) {
71 data_.resize(len);
72 if (fd->Read(data_.data(), len) != len) {
73 LOG(ERROR) << "Short read: " << fd->StrError();
74 callback_(false, std::move(data_));
75 return false;
76 }
77 }
78 }
79
80 callback_(true, std::move(data_));
81 return true;
82 }
83 } // namespace vadb
84