1 /*
2  * Copyright (C) 2020 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 
17 #ifndef HARDWARE_USB_USBGADGETCOMMON_H
18 #define HARDWARE_USB_USBGADGETCOMMON_H
19 
20 #include <android-base/file.h>
21 #include <android-base/properties.h>
22 #include <android-base/unique_fd.h>
23 
24 #include <android/hardware/usb/gadget/1.1/IUsbGadget.h>
25 
26 #include <dirent.h>
27 #include <fcntl.h>
28 #include <stdio.h>
29 #include <sys/epoll.h>
30 #include <sys/eventfd.h>
31 #include <sys/inotify.h>
32 #include <sys/mount.h>
33 #include <sys/stat.h>
34 #include <sys/types.h>
35 #include <unistd.h>
36 #include <utils/Log.h>
37 #include <chrono>
38 #include <condition_variable>
39 #include <mutex>
40 #include <string>
41 #include <thread>
42 
43 namespace android {
44 namespace hardware {
45 namespace usb {
46 namespace gadget {
47 
48 constexpr int kBufferSize = 512;
49 constexpr int kMaxFilePathLength = 256;
50 constexpr int kEpollEvents = 10;
51 constexpr bool kDebug = false;
52 constexpr int kDisconnectWaitUs = 100000;
53 constexpr int kPullUpDelay = 500000;
54 constexpr int kShutdownMonitor = 100;
55 
56 constexpr char kBuildType[] = "ro.build.type";
57 constexpr char kPersistentVendorConfig[] = "persist.vendor.usb.usbradio.config";
58 constexpr char kVendorConfig[] = "vendor.usb.config";
59 
60 #define GADGET_PATH "/config/usb_gadget/g1/"
61 #define PULLUP_PATH GADGET_PATH "UDC"
62 #define PERSISTENT_BOOT_MODE "ro.bootmode"
63 #define VENDOR_ID_PATH GADGET_PATH "idVendor"
64 #define PRODUCT_ID_PATH GADGET_PATH "idProduct"
65 #define DEVICE_CLASS_PATH GADGET_PATH "bDeviceClass"
66 #define DEVICE_SUB_CLASS_PATH GADGET_PATH "bDeviceSubClass"
67 #define DEVICE_PROTOCOL_PATH GADGET_PATH "bDeviceProtocol"
68 #define DESC_USE_PATH GADGET_PATH "os_desc/use"
69 #define OS_DESC_PATH GADGET_PATH "os_desc/b.1"
70 #define CONFIG_PATH GADGET_PATH "configs/b.1/"
71 #define FUNCTIONS_PATH GADGET_PATH "functions/"
72 #define FUNCTION_NAME "function"
73 #define FUNCTION_PATH CONFIG_PATH FUNCTION_NAME
74 #define RNDIS_PATH FUNCTIONS_PATH "gsi.rndis"
75 
76 using ::android::base::GetProperty;
77 using ::android::base::SetProperty;
78 using ::android::base::unique_fd;
79 using ::android::base::WriteStringToFile;
80 using ::android::hardware::usb::gadget::V1_0::GadgetFunction;
81 using ::android::hardware::usb::gadget::V1_0::Status;
82 
83 using ::std::lock_guard;
84 using ::std::move;
85 using ::std::mutex;
86 using ::std::string;
87 using ::std::thread;
88 using ::std::unique_ptr;
89 using ::std::vector;
90 using ::std::chrono::microseconds;
91 using ::std::chrono::steady_clock;
92 using ::std::literals::chrono_literals::operator""ms;
93 
94 // MonitorFfs automously manages gadget pullup by monitoring
95 // the ep file status. Restarts the usb gadget when the ep
96 // owner restarts.
97 class MonitorFfs {
98   private:
99     // Monitors the endpoints Inotify events.
100     unique_fd mInotifyFd;
101     // Control pipe for shutting down the mMonitor thread.
102     // mMonitor exits when SHUTDOWN_MONITOR is written into
103     // mEventFd/
104     unique_fd mEventFd;
105     // Pools on mInotifyFd and mEventFd.
106     unique_fd mEpollFd;
107     vector<int> mWatchFd;
108 
109     // Maintains the list of Endpoints.
110     vector<string> mEndpointList;
111     // protects the CV.
112     std::mutex mLock;
113     std::condition_variable mCv;
114     // protects mInotifyFd, mEpollFd.
115     std::mutex mLockFd;
116 
117     // Flag to maintain the current status of gadget pullup.
118     bool mCurrentUsbFunctionsApplied;
119 
120     // Thread object that executes the ep monitoring logic.
121     unique_ptr<thread> mMonitor;
122     // Callback to be invoked when gadget is pulled up.
123     void (*mCallback)(bool functionsApplied, void* payload);
124     void* mPayload;
125     // Name of the USB gadget. Used for pullup.
126     const char* const mGadgetName;
127     // Monitor State
128     bool mMonitorRunning;
129 
130   public:
131     MonitorFfs(const char* const gadget);
132     // Inits all the UniqueFds.
133     void reset();
134     // Starts monitoring endpoints and pullup the gadget when
135     // the descriptors are written.
136     bool startMonitor();
137     // Waits for timeout_ms for gadget pull up to happen.
138     // Returns immediately if the gadget is already pulled up.
139     bool waitForPullUp(int timeout_ms);
140     // Adds the given fd to the watch list.
141     bool addInotifyFd(string fd);
142     // Adds the given endpoint to the watch list.
143     void addEndPoint(string ep);
144     // Registers the async callback from the caller to notify the caller
145     // when the gadget pull up happens.
146     void registerFunctionsAppliedCallback(void (*callback)(bool functionsApplied, void*(payload)),
147                                           void* payload);
148     bool isMonitorRunning();
149     // Ep monitoring and the gadget pull up logic.
150     static void* startMonitorFd(void* param);
151 };
152 
153 //**************** Helper functions ************************//
154 
155 // Adds the given fd to the epollfd(epfd).
156 int addEpollFd(const unique_fd& epfd, const unique_fd& fd);
157 // Removes all the usb functions link in the specified path.
158 int unlinkFunctions(const char* path);
159 // Craetes a configfs link for the function.
160 int linkFunction(const char* function, int index);
161 // Sets the USB VID and PID.
162 Status setVidPid(const char* vid, const char* pid);
163 // Extracts vendor functions from the vendor init properties.
164 std::string getVendorFunctions();
165 // Adds Adb to the usb configuration.
166 Status addAdb(MonitorFfs* monitorFfs, int* functionCount);
167 // Adds all applicable generic android usb functions other than ADB.
168 Status addGenericAndroidFunctions(MonitorFfs* monitorFfs, uint64_t functions, bool* ffsEnabled,
169                                   int* functionCount);
170 // Pulls down USB gadget.
171 Status resetGadget();
172 
173 }  // namespace gadget
174 }  // namespace usb
175 }  // namespace hardware
176 }  // namespace android
177 #endif
178