• 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 #pragma once
17 
18 #include <map>
19 #include <memory>
20 #include <string>
21 #include <libusb/libusb.h>
22 
23 #include "common/libs/fs/shared_fd.h"
24 #include "common/libs/threads/cuttlefish_thread.h"
25 #include "guest/commands/usbforward/transport_request.h"
26 
27 namespace usb_forward {
28 
29 // USBServer exposes access to USB devices over pipe (virtio channel etc).
30 // Usage:
31 //
32 //     cvd::SharedFD pipe = cvd::SharedFD::Open(pipe_path, O_RDWR);
33 //     USBServer server(pipe);
34 //     CHECK(server.Init());
35 //     server.Serve();
36 class USBServer final {
37  public:
38   USBServer(const cvd::SharedFD& fd);
39   ~USBServer() = default;
40 
41   // Serve incoming USB requests.
42   void Serve();
43 
44  private:
45   // HandleDeviceEvent opens and closes Android Gadget device, whenever it
46   // appears / disappears.
47   static int HandleDeviceEvent(libusb_context*, libusb_device*,
48                                 libusb_hotplug_event event, void* self_raw);
49 
50   // Handle CmdDeviceList request.
51   void HandleDeviceList(uint32_t tag);
52 
53   // Handle CmdAttach request.
54   void HandleAttach(uint32_t tag);
55 
56   // Handle CmdControlTransfer request.
57   void HandleControlTransfer(uint32_t tag);
58 
59   // Handle CmdDataTransfer request.
60   void HandleDataTransfer(uint32_t tag);
61 
62   // Handle CmdHeartbeat request.
63   void HandleHeartbeat(uint32_t tag);
64 
65   // OnAsyncDataTransferComplete handles end of asynchronous data transfer cycle
66   // and sends response back to caller.
67   void OnTransferComplete(uint32_t tag, bool is_data_in, bool is_success,
68                           const uint8_t* buffer, int32_t actual_length);
69 
70   // Initialize, Configure and start libusb.
71   void InitLibUSB();
72 
73   // Stop, Deconfigure and Clean up libusb.
74   void ExitLibUSB();
75 
76   // Extract device info, if device is available.
77   bool GetDeviceInfo(DeviceInfo* info, std::vector<InterfaceInfo>* ifaces);
78 
79   // Handle asynchronous libusb events.
80   static void* ProcessLibUSBRequests(void* self_ptr);
81 
82   std::shared_ptr<libusb_device_handle> handle_;
83   libusb_hotplug_callback_handle hotplug_handle_;
84 
85   std::unique_ptr<cvd::ScopedThread> libusb_thread_;
86   cvd::Mutex write_mutex_;
87   cvd::SharedFD fd_;
88   cvd::SharedFD device_event_fd_;
89   cvd::SharedFD thread_event_fd_;
90 
91   cvd::Mutex requests_mutex_;
92   std::map<uint32_t, std::unique_ptr<TransportRequest>> requests_in_flight_;
93 
94   USBServer(const USBServer& other) = delete;
95   USBServer& operator=(const USBServer& other) = delete;
96 };
97 
98 }  // namespace usb_forward
99