summaryrefslogtreecommitdiff
path: root/usb/include/pixelusb/UsbGadgetCommon.h
blob: 88b2fa5ecdcad639c989aac87187b2b279732480 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef HARDWARE_GOOGLE_PIXEL_USB_USBGADGETCOMMON_H
#define HARDWARE_GOOGLE_PIXEL_USB_USBGADGETCOMMON_H

#include <android-base/file.h>
#include <android-base/properties.h>
#include <android-base/unique_fd.h>

#include <android/hardware/usb/gadget/1.0/IUsbGadget.h>

#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/inotify.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <utils/Log.h>
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <string>
#include <thread>

namespace android {
namespace hardware {
namespace google {
namespace pixel {
namespace usb {

constexpr int kBufferSize = 512;
constexpr int kMaxFilePathLength = 256;
constexpr int kEpollEvents = 10;
constexpr bool kDebug = false;
constexpr int kDisconnectWaitUs = 100000;
constexpr int kPullUpDelay = 500000;
constexpr int kShutdownMonitor = 100;

constexpr char kBuildType[] = "ro.build.type";
constexpr char kPersistentVendorConfig[] = "persist.vendor.usb.usbradio.config";
constexpr char kVendorConfig[] = "vendor.usb.config";

#define GADGET_PATH "/config/usb_gadget/g1/"
#define PULLUP_PATH GADGET_PATH "UDC"
#define PERSISTENT_BOOT_MODE "ro.bootmode"
#define VENDOR_ID_PATH GADGET_PATH "idVendor"
#define PRODUCT_ID_PATH GADGET_PATH "idProduct"
#define DEVICE_CLASS_PATH GADGET_PATH "bDeviceClass"
#define DEVICE_SUB_CLASS_PATH GADGET_PATH "bDeviceSubClass"
#define DEVICE_PROTOCOL_PATH GADGET_PATH "bDeviceProtocol"
#define DESC_USE_PATH GADGET_PATH "os_desc/use"
#define OS_DESC_PATH GADGET_PATH "os_desc/b.1"
#define CONFIG_PATH GADGET_PATH "configs/b.1/"
#define FUNCTIONS_PATH GADGET_PATH "functions/"
#define FUNCTION_NAME "function"
#define FUNCTION_PATH CONFIG_PATH FUNCTION_NAME
#define RNDIS_PATH FUNCTIONS_PATH "gsi.rndis"

using ::android::base::GetProperty;
using ::android::base::SetProperty;
using ::android::base::unique_fd;
using ::android::base::WriteStringToFile;
using ::android::hardware::usb::gadget::V1_0::GadgetFunction;
using ::android::hardware::usb::gadget::V1_0::Status;

using ::std::lock_guard;
using ::std::move;
using ::std::mutex;
using ::std::string;
using ::std::thread;
using ::std::unique_ptr;
using ::std::vector;
using ::std::chrono::microseconds;
using ::std::chrono::steady_clock;
using ::std::literals::chrono_literals::operator""ms;

// MonitorFfs automously manages gadget pullup by monitoring
// the ep file status. Restarts the usb gadget when the ep
// owner restarts.
class MonitorFfs {
 private:
  // Monitors the endpoints Inotify events.
  unique_fd mInotifyFd;
  // Control pipe for shutting down the mMonitor thread.
  // mMonitor exits when SHUTDOWN_MONITOR is written into
  // mEventFd/
  unique_fd mEventFd;
  // Pools on mInotifyFd and mEventFd.
  unique_fd mEpollFd;
  vector<int> mWatchFd;

  // Maintains the list of Endpoints.
  vector<string> mEndpointList;
  // protects the CV.
  std::mutex mLock;
  std::condition_variable mCv;
  // protects mInotifyFd, mEpollFd.
  std::mutex mLockFd;

  // Flag to maintain the current status of gadget pullup.
  bool mCurrentUsbFunctionsApplied;

  // Thread object that executes the ep monitoring logic.
  unique_ptr<thread> mMonitor;
  // Callback to be invoked when gadget is pulled up.
  void (*mCallback)(bool functionsApplied, void *payload);
  void *mPayload;
  // Name of the USB gadget. Used for pullup.
  const char *const mGadgetName;
  // Monitor State
  bool mMonitorRunning;

 public:
  MonitorFfs(const char *const gadget);
  // Inits all the UniqueFds.
  void reset();
  // Starts monitoring endpoints and pullup the gadget when
  // the descriptors are written.
  bool startMonitor();
  // Waits for timeout_ms for gadget pull up to happen.
  // Returns immediately if the gadget is already pulled up.
  bool waitForPullUp(int timeout_ms);
  // Adds the given fd to the watch list.
  bool addInotifyFd(string fd);
  // Adds the given endpoint to the watch list.
  void addEndPoint(string ep);
  // Registers the async callback from the caller to notify the caller
  // when the gadget pull up happens.
  void registerFunctionsAppliedCallback(void (*callback)(bool functionsApplied,
                                                         void *(payload)),
                                        void *payload);
  bool isMonitorRunning();
  // Ep monitoring and the gadget pull up logic.
  static void *startMonitorFd(void *param);
};

//**************** Helper functions ************************//

// Adds the given fd to the epollfd(epfd).
int addEpollFd(const unique_fd &epfd, const unique_fd &fd);
// Removes all the usb functions link in the specified path.
int unlinkFunctions(const char *path);
// Craetes a configfs link for the function.
int linkFunction(const char *function, int index);
// Sets the USB VID and PID.
Status setVidPid(const char *vid, const char *pid);
// Extracts vendor functions from the vendor init properties.
std::string getVendorFunctions();
// Adds Adb to the usb configuration.
Status addAdb(MonitorFfs *monitorFfs, int *functionCount);
// Adds all applicable generic android usb functions other than ADB.
Status addGenericAndroidFunctions(MonitorFfs *monitorFfs, uint64_t functions,
                                  bool *ffsEnabled, int *functionCount);
// Pulls down USB gadget.
Status resetGadget();

}  // namespace usb
}  // namespace pixel
}  // namespace google
}  // namespace hardware
}  // namespace android
#endif