+++ /dev/null
-/*
- * 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.
- */
-
-#define LOG_TAG "android.hardware.usb.gadget@1.2-service.gs101"
-
-#include "UsbGadget.h"
-#include <dirent.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <sys/inotify.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-namespace android {
-namespace hardware {
-namespace usb {
-namespace gadget {
-namespace V1_2 {
-namespace implementation {
-
-UsbGadget::UsbGadget() {
- if (access(OS_DESC_PATH, R_OK) != 0) {
- ALOGE("configfs setup not done yet");
- abort();
- }
-}
-
-void currentFunctionsAppliedCallback(bool functionsApplied, void *payload) {
- UsbGadget *gadget = (UsbGadget *)payload;
- gadget->mCurrentUsbFunctionsApplied = functionsApplied;
-}
-
-Return<void> UsbGadget::getCurrentUsbFunctions(const sp<V1_0::IUsbGadgetCallback> &callback) {
- Return<void> ret = callback->getCurrentUsbFunctionsCb(
- mCurrentUsbFunctions,
- mCurrentUsbFunctionsApplied ? Status::FUNCTIONS_APPLIED : Status::FUNCTIONS_NOT_APPLIED);
- if (!ret.isOk())
- ALOGE("Call to getCurrentUsbFunctionsCb failed %s", ret.description().c_str());
-
- return Void();
-}
-
-Return<void> UsbGadget::getUsbSpeed(const sp<V1_2::IUsbGadgetCallback> &callback) {
- std::string current_speed;
- if (ReadFileToString(SPEED_PATH, ¤t_speed)) {
- current_speed = Trim(current_speed);
- ALOGI("current USB speed is %s", current_speed.c_str());
- if (current_speed == "low-speed")
- mUsbSpeed = UsbSpeed::LOWSPEED;
- else if (current_speed == "full-speed")
- mUsbSpeed = UsbSpeed::FULLSPEED;
- else if (current_speed == "high-speed")
- mUsbSpeed = UsbSpeed::HIGHSPEED;
- else if (current_speed == "super-speed")
- mUsbSpeed = UsbSpeed::SUPERSPEED;
- else if (current_speed == "super-speed-plus")
- mUsbSpeed = UsbSpeed::SUPERSPEED_10Gb;
- else if (current_speed == "UNKNOWN")
- mUsbSpeed = UsbSpeed::UNKNOWN;
- else
- mUsbSpeed = UsbSpeed::RESERVED_SPEED;
- } else {
- ALOGE("Fail to read current speed");
- mUsbSpeed = UsbSpeed::UNKNOWN;
- }
-
- if (callback) {
- Return<void> ret = callback->getUsbSpeedCb(mUsbSpeed);
-
- if (!ret.isOk())
- ALOGE("Call to getUsbSpeedCb failed %s", ret.description().c_str());
- }
-
- return Void();
-}
-
-V1_0::Status UsbGadget::tearDownGadget() {
- if (resetGadget() != Status::SUCCESS)
- return Status::ERROR;
-
- if (monitorFfs.isMonitorRunning()) {
- monitorFfs.reset();
- } else {
- ALOGI("mMonitor not running");
- }
- return Status::SUCCESS;
-}
-
-static V1_0::Status validateAndSetVidPid(uint64_t functions) {
- V1_0::Status ret = Status::SUCCESS;
- std::string vendorFunctions = getVendorFunctions();
-
- switch (functions) {
- case static_cast<uint64_t>(GadgetFunction::MTP):
- if (!(vendorFunctions == "user" || vendorFunctions == "")) {
- ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
- ret = Status::CONFIGURATION_NOT_SUPPORTED;
- } else {
- ret = setVidPid("0x18d1", "0x4ee1");
- }
- break;
- case GadgetFunction::ADB | GadgetFunction::MTP:
- if (!(vendorFunctions == "user" || vendorFunctions == "")) {
- ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
- ret = Status::CONFIGURATION_NOT_SUPPORTED;
- } else {
- ret = setVidPid("0x18d1", "0x4ee2");
- }
- break;
- case static_cast<uint64_t>(GadgetFunction::RNDIS):
- case GadgetFunction::RNDIS | GadgetFunction::NCM:
- if (!(vendorFunctions == "user" || vendorFunctions == "")) {
- ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
- ret = Status::CONFIGURATION_NOT_SUPPORTED;
- } else {
- ret = setVidPid("0x18d1", "0x4ee3");
- }
- break;
- case GadgetFunction::ADB | GadgetFunction::RNDIS:
- case GadgetFunction::ADB | GadgetFunction::RNDIS | GadgetFunction::NCM:
- if (vendorFunctions == "dm") {
- ret = setVidPid("0x04e8", "0x6862");
- } else {
- if (!(vendorFunctions == "user" || vendorFunctions == "")) {
- ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
- ret = Status::CONFIGURATION_NOT_SUPPORTED;
- } else {
- ret = setVidPid("0x18d1", "0x4ee4");
- }
- }
- break;
- case static_cast<uint64_t>(GadgetFunction::PTP):
- if (!(vendorFunctions == "user" || vendorFunctions == "")) {
- ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
- ret = Status::CONFIGURATION_NOT_SUPPORTED;
- } else {
- ret = setVidPid("0x18d1", "0x4ee5");
- }
- break;
- case GadgetFunction::ADB | GadgetFunction::PTP:
- if (!(vendorFunctions == "user" || vendorFunctions == "")) {
- ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
- ret = Status::CONFIGURATION_NOT_SUPPORTED;
- } else {
- ret = setVidPid("0x18d1", "0x4ee6");
- }
- break;
- case static_cast<uint64_t>(GadgetFunction::ADB):
- if (vendorFunctions == "dm") {
- ret = setVidPid("0x04e8", "0x6862");
- } else if (vendorFunctions == "etr_miu") {
- ret = setVidPid("0x18d1", "0x4ee2");
- } else if (vendorFunctions == "uwb_acm"){
- ret = setVidPid("0x18d1", "0x4ee2");
- } else {
- if (!(vendorFunctions == "user" || vendorFunctions == "")) {
- ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
- ret = Status::CONFIGURATION_NOT_SUPPORTED;
- } else {
- ret = setVidPid("0x18d1", "0x4ee7");
- }
- }
- break;
- case static_cast<uint64_t>(GadgetFunction::MIDI):
- if (!(vendorFunctions == "user" || vendorFunctions == "")) {
- ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
- ret = Status::CONFIGURATION_NOT_SUPPORTED;
- } else {
- ret = setVidPid("0x18d1", "0x4ee8");
- }
- break;
- case GadgetFunction::ADB | GadgetFunction::MIDI:
- if (!(vendorFunctions == "user" || vendorFunctions == "")) {
- ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
- ret = Status::CONFIGURATION_NOT_SUPPORTED;
- } else {
- ret = setVidPid("0x18d1", "0x4ee9");
- }
- break;
- case static_cast<uint64_t>(GadgetFunction::ACCESSORY):
- if (!(vendorFunctions == "user" || vendorFunctions == ""))
- ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
- ret = setVidPid("0x18d1", "0x2d00");
- break;
- case GadgetFunction::ADB | GadgetFunction::ACCESSORY:
- if (!(vendorFunctions == "user" || vendorFunctions == ""))
- ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
- ret = setVidPid("0x18d1", "0x2d01");
- break;
- case static_cast<uint64_t>(GadgetFunction::AUDIO_SOURCE):
- if (!(vendorFunctions == "user" || vendorFunctions == ""))
- ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
- ret = setVidPid("0x18d1", "0x2d02");
- break;
- case GadgetFunction::ADB | GadgetFunction::AUDIO_SOURCE:
- if (!(vendorFunctions == "user" || vendorFunctions == ""))
- ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
- ret = setVidPid("0x18d1", "0x2d03");
- break;
- case GadgetFunction::ACCESSORY | GadgetFunction::AUDIO_SOURCE:
- if (!(vendorFunctions == "user" || vendorFunctions == ""))
- ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
- ret = setVidPid("0x18d1", "0x2d04");
- break;
- case GadgetFunction::ADB | GadgetFunction::ACCESSORY | GadgetFunction::AUDIO_SOURCE:
- if (!(vendorFunctions == "user" || vendorFunctions == ""))
- ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
- ret = setVidPid("0x18d1", "0x2d05");
- break;
- case static_cast<uint64_t>(GadgetFunction::NCM):
- if (!(vendorFunctions == "user" || vendorFunctions == ""))
- ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
- ret = setVidPid("0x18d1", "0x4eeb");
- break;
- case GadgetFunction::ADB | GadgetFunction::NCM:
- if (!(vendorFunctions == "user" || vendorFunctions == ""))
- ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
- ret = setVidPid("0x18d1", "0x4eec");
- break;
- default:
- ALOGE("Combination not supported");
- ret = Status::CONFIGURATION_NOT_SUPPORTED;
- }
- return ret;
-}
-
-Return<Status> UsbGadget::reset() {
- ALOGI("USB Gadget reset");
-
- if (!WriteStringToFile("none", PULLUP_PATH)) {
- ALOGI("Gadget cannot be pulled down");
- return Status::ERROR;
- }
-
- usleep(kDisconnectWaitUs);
-
- if (!WriteStringToFile(kGadgetName, PULLUP_PATH)) {
- ALOGI("Gadget cannot be pulled up");
- return Status::ERROR;
- }
-
- return Status::SUCCESS;
-}
-
-V1_0::Status UsbGadget::setupFunctions(uint64_t functions,
- const sp<V1_0::IUsbGadgetCallback> &callback,
- uint64_t timeout) {
- bool ffsEnabled = false;
- int i = 0;
-
- if (addGenericAndroidFunctions(&monitorFfs, functions, &ffsEnabled, &i) !=
- Status::SUCCESS)
- return Status::ERROR;
-
- std::string vendorFunctions = getVendorFunctions();
-
- if (vendorFunctions == "dm") {
- ALOGI("enable usbradio debug functions");
- if ((functions & GadgetFunction::RNDIS) != 0) {
- if (linkFunction("acm.gs6", i++))
- return Status::ERROR;
- if (linkFunction("dm.gs7", i++))
- return Status::ERROR;
- } else {
- if (linkFunction("dm.gs7", i++))
- return Status::ERROR;
- if (linkFunction("acm.gs6", i++))
- return Status::ERROR;
- }
- } else if (vendorFunctions == "etr_miu") {
- ALOGI("enable etr_miu functions");
- if (linkFunction("etr_miu.gs11", i++))
- return Status::ERROR;
- } else if (vendorFunctions == "uwb_acm") {
- ALOGI("enable uwb acm function");
- if (linkFunction("acm.uwb0", i++))
- return Status::ERROR;
- }
-
- if ((functions & GadgetFunction::ADB) != 0) {
- ffsEnabled = true;
- if (addAdb(&monitorFfs, &i) != Status::SUCCESS)
- return Status::ERROR;
- }
-
- if ((functions & GadgetFunction::NCM) != 0) {
- ALOGI("setCurrentUsbFunctions ncm");
- if (linkFunction("ncm.gs9", i++))
- return Status::ERROR;
- }
-
- // Pull up the gadget right away when there are no ffs functions.
- if (!ffsEnabled) {
- if (!WriteStringToFile(kGadgetName, PULLUP_PATH))
- return Status::ERROR;
- mCurrentUsbFunctionsApplied = true;
- if (callback)
- callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS);
- return Status::SUCCESS;
- }
-
- monitorFfs.registerFunctionsAppliedCallback(¤tFunctionsAppliedCallback, this);
- // Monitors the ffs paths to pull up the gadget when descriptors are written.
- // Also takes of the pulling up the gadget again if the userspace process
- // dies and restarts.
- monitorFfs.startMonitor();
-
- if (kDebug)
- ALOGI("Mainthread in Cv");
-
- if (callback) {
- bool pullup = monitorFfs.waitForPullUp(timeout);
- Return<void> ret = callback->setCurrentUsbFunctionsCb(
- functions, pullup ? Status::SUCCESS : Status::ERROR);
- if (!ret.isOk())
- ALOGE("setCurrentUsbFunctionsCb error %s", ret.description().c_str());
- }
-
- return Status::SUCCESS;
-}
-
-Return<void> UsbGadget::setCurrentUsbFunctions(uint64_t functions,
- const sp<V1_0::IUsbGadgetCallback> &callback,
- uint64_t timeout) {
- std::unique_lock<std::mutex> lk(mLockSetCurrentFunction);
-
- mCurrentUsbFunctions = functions;
- mCurrentUsbFunctionsApplied = false;
-
- // Unlink the gadget and stop the monitor if running.
- V1_0::Status status = tearDownGadget();
- if (status != Status::SUCCESS) {
- goto error;
- }
-
- ALOGI("Returned from tearDown gadget");
-
- // Leave the gadget pulled down to give time for the host to sense disconnect.
- usleep(kDisconnectWaitUs);
-
- if (functions == static_cast<uint64_t>(GadgetFunction::NONE)) {
- if (callback == NULL)
- return Void();
- Return<void> ret = callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS);
- if (!ret.isOk())
- ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.description().c_str());
- return Void();
- }
-
- status = validateAndSetVidPid(functions);
-
- if (status != Status::SUCCESS) {
- goto error;
- }
-
- status = setupFunctions(functions, callback, timeout);
- if (status != Status::SUCCESS) {
- goto error;
- }
-
- if (functions & GadgetFunction::NCM) {
- SetProperty("vendor.usb.dwc3_irq", "big");
- } else {
- SetProperty("vendor.usb.dwc3_irq", "medium");
- }
-
- ALOGI("Usb Gadget setcurrent functions called successfully");
- return Void();
-
-error:
- ALOGI("Usb Gadget setcurrent functions failed");
- if (callback == NULL)
- return Void();
- Return<void> ret = callback->setCurrentUsbFunctionsCb(functions, status);
- if (!ret.isOk())
- ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.description().c_str());
- return Void();
-}
-} // namespace implementation
-} // namespace V1_2
-} // namespace gadget
-} // namespace usb
-} // namespace hardware
-} // namespace android
+++ /dev/null
-/*
- * 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.
- */
-
-#pragma once
-
-#include <android-base/file.h>
-#include <android-base/properties.h>
-#include <android-base/unique_fd.h>
-#include <android-base/strings.h>
-#include <android/hardware/usb/gadget/1.2/IUsbGadget.h>
-#include <android/hardware/usb/gadget/1.2/types.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-#include <pixelusb/UsbGadgetCommon.h>
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-#include <utils/Log.h>
-#include <chrono>
-#include <condition_variable>
-#include <mutex>
-#include <string>
-#include <thread>
-
-namespace android {
-namespace hardware {
-namespace usb {
-namespace gadget {
-namespace V1_2 {
-namespace implementation {
-
-using ::android::sp;
-using ::android::base::GetProperty;
-using ::android::base::SetProperty;
-using ::android::base::unique_fd;
-using ::android::base::ReadFileToString;
-using ::android::base::Trim;
-using ::android::base::WriteStringToFile;
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::google::pixel::usb::addAdb;
-using ::android::hardware::google::pixel::usb::addEpollFd;
-using ::android::hardware::google::pixel::usb::getVendorFunctions;
-using ::android::hardware::google::pixel::usb::kDebug;
-using ::android::hardware::google::pixel::usb::kDisconnectWaitUs;
-using ::android::hardware::google::pixel::usb::linkFunction;
-using ::android::hardware::google::pixel::usb::MonitorFfs;
-using ::android::hardware::google::pixel::usb::resetGadget;
-using ::android::hardware::google::pixel::usb::setVidPid;
-using ::android::hardware::google::pixel::usb::unlinkFunctions;
-using ::android::hardware::usb::gadget::V1_0::Status;
-using ::android::hardware::usb::gadget::V1_0::IUsbGadgetCallback;
-using ::android::hardware::usb::gadget::V1_2::IUsbGadget;
-using ::android::hardware::usb::gadget::V1_2::GadgetFunction;
-using ::std::string;
-
-constexpr char kGadgetName[] = "11110000.dwc3";
-#ifndef UDC_PATH
-#define UDC_PATH "/sys/class/udc/11110000.dwc3/"
-#endif
-static MonitorFfs monitorFfs(kGadgetName);
-
-#define SPEED_PATH UDC_PATH "current_speed"
-
-struct UsbGadget : public IUsbGadget {
- UsbGadget();
-
- // Makes sure that only one request is processed at a time.
- std::mutex mLockSetCurrentFunction;
- uint64_t mCurrentUsbFunctions;
- bool mCurrentUsbFunctionsApplied;
- UsbSpeed mUsbSpeed;
-
- Return<void> setCurrentUsbFunctions(uint64_t functions,
- const sp<V1_0::IUsbGadgetCallback> &callback,
- uint64_t timeout) override;
-
- Return<void> getCurrentUsbFunctions(const sp<V1_0::IUsbGadgetCallback> &callback) override;
-
- Return<Status> reset() override;
-
- Return<void> getUsbSpeed(const sp<V1_2::IUsbGadgetCallback> &callback) override;
-
- private:
- Status tearDownGadget();
- Status setupFunctions(uint64_t functions, const sp<V1_0::IUsbGadgetCallback> &callback,
- uint64_t timeout);
-};
-
-} // namespace implementation
-} // namespace V1_2
-} // namespace gadget
-} // namespace usb
-} // namespace hardware
-} // namespace android
chmod 664 /sys/devices/platform/11110000.usb/dwc3_exynos_otg_b_sess
chmod 664 /sys/devices/platform/11110000.usb/dwc3_exynos_otg_id
chmod 664 /sys/devices/platform/11110000.usb/usb_data_enabled
-
-on property:vendor.usb.functions.ready=1
- chown system system /config/usb_gadget/
- chown system system /config/usb_gadget/g1
- chown system system /config/usb_gadget/g1/UDC
- chown system system /config/usb_gadget/g1/bDeviceClass
- chown system system /config/usb_gadget/g1/bDeviceProtocol
- chown system system /config/usb_gadget/g1/bDeviceSubClass
- chown system system /config/usb_gadget/g1/bMaxPacketSize0
- chown system system /config/usb_gadget/g1/bcdDevice
- chown system system /config/usb_gadget/g1/bcdUSB
- chown system system /config/usb_gadget/g1/configs
- chown system system /config/usb_gadget/g1/configs/b.1
- chown system system /config/usb_gadget/g1/configs/b.1/MaxPower
- chown system system /config/usb_gadget/g1/configs/b.1/bmAttributes
- chown system system /config/usb_gadget/g1/configs/b.1/strings
- chown system system /config/usb_gadget/g1/functions
- chown system system /config/usb_gadget/g1/functions/accessory.gs2
- chown system system /config/usb_gadget/g1/functions/acm.gs6
- chown system system /config/usb_gadget/g1/functions/acm.gs6/port_num
- chown system system /config/usb_gadget/g1/functions/acm.uwb0
- chown system system /config/usb_gadget/g1/functions/acm.uwb0/port_num
- chown system system /config/usb_gadget/g1/functions/audio_source.gs3
- chown system system /config/usb_gadget/g1/functions/dm.gs7
- chown system system /config/usb_gadget/g1/functions/ffs.adb
- chown system system /config/usb_gadget/g1/functions/ffs.mtp
- chown system system /config/usb_gadget/g1/functions/ffs.ptp
- chown system system /config/usb_gadget/g1/functions/midi.gs5
- chown system system /config/usb_gadget/g1/functions/midi.gs5/buflen
- chown system system /config/usb_gadget/g1/functions/midi.gs5/id
- chown system system /config/usb_gadget/g1/functions/midi.gs5/in_ports
- chown system system /config/usb_gadget/g1/functions/midi.gs5/index
- chown system system /config/usb_gadget/g1/functions/midi.gs5/out_ports
- chown system system /config/usb_gadget/g1/functions/midi.gs5/qlen
- chown system system /config/usb_gadget/g1/functions/mtp.gs0
- chown system system /config/usb_gadget/g1/functions/mtp.gs0/os_desc
- chown system system /config/usb_gadget/g1/functions/mtp.gs0/os_desc/interface.MTP
- chown system system /config/usb_gadget/g1/functions/mtp.gs0/os_desc/interface.MTP/compatible_id
- chown system system /config/usb_gadget/g1/functions/mtp.gs0/os_desc/interface.MTP/sub_compatible_id
- chown system system /config/usb_gadget/g1/functions/ncm.gs9
- chown system system /config/usb_gadget/g1/functions/ncm.gs9/dev_addr
- chown system system /config/usb_gadget/g1/functions/ncm.gs9/host_addr
- chown system system /config/usb_gadget/g1/functions/ncm.gs9/ifname
- chown system system /config/usb_gadget/g1/functions/ncm.gs9/os_desc
- chown system system /config/usb_gadget/g1/functions/ncm.gs9/os_desc/interface.ncm
- chown system system /config/usb_gadget/g1/functions/ncm.gs9/os_desc/interface.ncm/compatible_id
- chown system system /config/usb_gadget/g1/functions/ncm.gs9/os_desc/interface.ncm/sub_compatible_id
- chown system system /config/usb_gadget/g1/functions/ncm.gs9/qmult
- chown system system /config/usb_gadget/g1/functions/ptp.gs1
- chown system system /config/usb_gadget/g1/functions/ptp.gs1/os_desc
- chown system system /config/usb_gadget/g1/functions/ptp.gs1/os_desc/interface.MTP
- chown system system /config/usb_gadget/g1/functions/ptp.gs1/os_desc/interface.MTP/compatible_id
- chown system system /config/usb_gadget/g1/functions/ptp.gs1/os_desc/interface.MTP/sub_compatible_id
- chown system system /config/usb_gadget/g1/functions/rndis.gs4
- chown system system /config/usb_gadget/g1/functions/rndis.gs4/class
- chown system system /config/usb_gadget/g1/functions/rndis.gs4/dev_addr
- chown system system /config/usb_gadget/g1/functions/rndis.gs4/host_addr
- chown system system /config/usb_gadget/g1/functions/rndis.gs4/ifname
- chown system system /config/usb_gadget/g1/functions/rndis.gs4/os_desc
- chown system system /config/usb_gadget/g1/functions/rndis.gs4/os_desc/interface.rndis
- chown system system /config/usb_gadget/g1/functions/rndis.gs4/os_desc/interface.rndis/compatible_id
- chown system system /config/usb_gadget/g1/functions/rndis.gs4/os_desc/interface.rndis/sub_compatible_id
- chown system system /config/usb_gadget/g1/functions/rndis.gs4/protocol
- chown system system /config/usb_gadget/g1/functions/rndis.gs4/qmult
- chown system system /config/usb_gadget/g1/functions/rndis.gs4/subclass
- chown system system /config/usb_gadget/g1/idProduct
- chown system system /config/usb_gadget/g1/idVendor
- chown system system /config/usb_gadget/g1/max_speed
- chown system system /config/usb_gadget/g1/os_desc
- chown system system /config/usb_gadget/g1/os_desc/b.1
- chown system system /config/usb_gadget/g1/os_desc/b_vendor_code
- chown system system /config/usb_gadget/g1/os_desc/qw_sign
- chown system system /config/usb_gadget/g1/os_desc/use
- chown system system /config/usb_gadget/g1/strings
- chown system system /config/usb_gadget/g1/strings/0x409
- chown system system /config/usb_gadget/g1/strings/0x409/manufacturer
- chown system system /config/usb_gadget/g1/strings/0x409/product
- chown system system /config/usb_gadget/g1/strings/0x409/serialnumber