• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_data_transfer.h"
19 
20 namespace vadb {
USBCmdDataTransfer(uint8_t bus_id,uint8_t dev_id,uint8_t endpoint,bool is_host_to_device,uint32_t deadline,std::vector<uint8_t> data,usbip::Device::AsyncTransferReadyCB callback)21 USBCmdDataTransfer::USBCmdDataTransfer(
22     uint8_t bus_id, uint8_t dev_id, uint8_t endpoint, bool is_host_to_device,
23     uint32_t deadline, 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_.endpoint_id = endpoint;
29   req_.is_host_to_device = is_host_to_device;
30   req_.length = data_.size();
31   req_.timeout = deadline;
32 }
33 
OnRequest(const cvd::SharedFD & fd)34 bool USBCmdDataTransfer::OnRequest(const cvd::SharedFD& fd) {
35   if (fd->Write(&req_, sizeof(req_)) != sizeof(req_)) {
36     LOG(ERROR) << "Short write: " << fd->StrError();
37     return false;
38   }
39 
40   if (req_.is_host_to_device && data_.size() > 0) {
41     if (static_cast<size_t>(fd->Write(data_.data(), data_.size())) !=
42         data_.size()) {
43       LOG(ERROR) << "Short write: " << fd->StrError();
44       return false;
45     }
46   }
47 
48   return true;
49 }
50 
OnResponse(bool is_success,const cvd::SharedFD & fd)51 bool USBCmdDataTransfer::OnResponse(bool is_success, const cvd::SharedFD& fd) {
52   if (!is_success) {
53     callback_(false, std::move(data_));
54     return true;
55   }
56 
57   if (!req_.is_host_to_device) {
58     int32_t len;
59     if (fd->Read(&len, sizeof(len)) != sizeof(len)) {
60       LOG(ERROR) << "Short read: " << fd->StrError();
61       callback_(false, std::move(data_));
62       return false;
63     }
64 
65     if (len > 0) {
66       data_.resize(len);
67       int32_t got = 0;
68       // Virtio sends data in 32k packets. We may have to do a few reads.
69       while (got < len) {
70         auto packetsize = fd->Read(&data_[got], len - got);
71         got += packetsize;
72 
73         if (fd->GetErrno() != 0) {
74           // This could, technically, also be a disconnect.
75           LOG(ERROR) << "Read failed: " << fd->StrError();
76           return false;
77         } else if (packetsize == 0) {
78           LOG(ERROR) << "Short read; remote end disconnected.";
79           return false;
80         }
81       }
82     }
83   }
84 
85   callback_(true, std::move(data_));
86   return true;
87 }
88 }  // namespace vadb
89