| /* |
| * Copyright (C) 2020 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_USB_USBGADGETCOMMON_H |
| #define HARDWARE_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.2/IUsbGadget.h> |
| #include <android/hardware/usb/gadget/1.2/types.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 usb { |
| namespace gadget { |
| |
| 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"; |
| constexpr char kVendorRndisConfig[] = "vendor.usb.rndis.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" |
| #define RNDIS_PATH FUNCTIONS_PATH "rndis.gs4" |
| |
| using ::android::base::GetProperty; |
| using ::android::base::SetProperty; |
| using ::android::base::unique_fd; |
| using ::android::base::WriteStringToFile; |
| using ::android::hardware::usb::gadget::V1_0::Status; |
| using ::android::hardware::usb::gadget::V1_2::GadgetFunction; |
| |
| 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 gadget |
| } // namespace usb |
| } // namespace hardware |
| } // namespace android |
| #endif |