• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define LOG_TAG "android.hardware.usb.gadget.aidl-service"
18 
19 #include "UsbGadget.h"
20 #include <fcntl.h>
21 #include <stdio.h>
22 #include <sys/inotify.h>
23 #include <sys/mount.h>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27 
28 #include<android-base/properties.h>
29 
30 #include <aidl/android/frameworks/stats/IStats.h>
31 #include <pixelusb/I2cHelper.h>
32 
33 namespace aidl {
34 namespace android {
35 namespace hardware {
36 namespace usb {
37 namespace gadget {
38 #define NUM_HSI2C_PATHS 2
39 
40 using ::android::hardware::google::pixel::usb::getI2cClientPath;
41 
42 using ::android::base::GetBoolProperty;
43 using ::android::hardware::google::pixel::usb::kUvcEnabled;
44 
45 string enabledPath;
46 constexpr char* kHsi2cPaths[] = { (char *) "/sys/devices/platform/108d0000.hsi2c",
47                                   (char *) "/sys/devices/platform/10cb0000.hsi2c" };
48 constexpr char kTcpcDevName[] = "i2c-max77759tcpc";
49 constexpr char kI2cClientId[] = "0025";
50 constexpr char kAccessoryLimitCurrent[] = "usb_limit_accessory_current";
51 constexpr char kAccessoryLimitCurrentEnable[] = "usb_limit_accessory_enable";
52 
UsbGadget()53 UsbGadget::UsbGadget() : mGadgetIrqPath(""),
54     mI2cClientPath("") {
55     if (access(OS_DESC_PATH, R_OK) != 0) {
56         ALOGE("configfs setup not done yet");
57         abort();
58     }
59 }
60 
getUsbGadgetIrqPath()61 Status UsbGadget::getUsbGadgetIrqPath() {
62     std::string irqs;
63     size_t read_pos = 0;
64     size_t found_pos = 0;
65 
66     if (!ReadFileToString(kProcInterruptsPath, &irqs)) {
67         ALOGE("cannot read all interrupts");
68         return Status::ERROR;
69     }
70 
71     while (true) {
72         found_pos = irqs.find_first_of("\n", read_pos);
73         if (found_pos == std::string::npos) {
74             ALOGI("the string of all interrupts is unexpected");
75             return Status::ERROR;
76         }
77 
78         std::string single_irq = irqs.substr(read_pos, found_pos - read_pos);
79 
80         if (single_irq.find("dwc3", 0) != std::string::npos) {
81             unsigned int dwc3_irq_number;
82             size_t dwc3_pos = single_irq.find_first_of(":");
83             if (!ParseUint(single_irq.substr(0, dwc3_pos), &dwc3_irq_number)) {
84                 ALOGI("unknown IRQ strings");
85                 return Status::ERROR;
86             }
87 
88             mGadgetIrqPath = kProcIrqPath + single_irq.substr(0, dwc3_pos) + kSmpAffinityList;
89             break;
90         }
91 
92         if (found_pos == irqs.npos) {
93             ALOGI("USB gadget doesn't start");
94             return Status::ERROR;
95         }
96 
97         read_pos = found_pos + 1;
98     }
99 
100     return Status::SUCCESS;
101 }
102 
currentFunctionsAppliedCallback(bool functionsApplied,void * payload)103 void currentFunctionsAppliedCallback(bool functionsApplied, void *payload) {
104     UsbGadget *gadget = (UsbGadget *)payload;
105     gadget->mCurrentUsbFunctionsApplied = functionsApplied;
106 }
107 
getCurrentUsbFunctions(const shared_ptr<IUsbGadgetCallback> & callback,int64_t in_transactionId)108 ScopedAStatus UsbGadget::getCurrentUsbFunctions(const shared_ptr<IUsbGadgetCallback> &callback,
109         int64_t in_transactionId) {
110     ScopedAStatus ret = callback->getCurrentUsbFunctionsCb(
111         mCurrentUsbFunctions,
112         mCurrentUsbFunctionsApplied ? Status::FUNCTIONS_APPLIED : Status::FUNCTIONS_NOT_APPLIED,
113         in_transactionId);
114     if (!ret.isOk())
115         ALOGE("Call to getCurrentUsbFunctionsCb failed %s", ret.getDescription().c_str());
116 
117     return ScopedAStatus::ok();
118 }
119 
getUsbSpeed(const shared_ptr<IUsbGadgetCallback> & callback,int64_t in_transactionId)120 ScopedAStatus UsbGadget::getUsbSpeed(const shared_ptr<IUsbGadgetCallback> &callback,
121         int64_t in_transactionId) {
122     std::string current_speed;
123     if (ReadFileToString(SPEED_PATH, &current_speed)) {
124         current_speed = Trim(current_speed);
125         ALOGI("current USB speed is %s", current_speed.c_str());
126         if (current_speed == "low-speed")
127             mUsbSpeed = UsbSpeed::LOWSPEED;
128         else if (current_speed == "full-speed")
129             mUsbSpeed = UsbSpeed::FULLSPEED;
130         else if (current_speed == "high-speed")
131             mUsbSpeed = UsbSpeed::HIGHSPEED;
132         else if (current_speed == "super-speed")
133             mUsbSpeed = UsbSpeed::SUPERSPEED;
134         else if (current_speed == "super-speed-plus")
135             mUsbSpeed = UsbSpeed::SUPERSPEED_10Gb;
136         else if (current_speed == "UNKNOWN")
137             mUsbSpeed = UsbSpeed::UNKNOWN;
138         else
139             mUsbSpeed = UsbSpeed::UNKNOWN;
140     } else {
141         ALOGE("Fail to read current speed");
142         mUsbSpeed = UsbSpeed::UNKNOWN;
143     }
144 
145     if (callback) {
146         ScopedAStatus ret = callback->getUsbSpeedCb(mUsbSpeed, in_transactionId);
147 
148         if (!ret.isOk())
149             ALOGE("Call to getUsbSpeedCb failed %s", ret.getDescription().c_str());
150     }
151 
152     return ScopedAStatus::ok();
153 }
154 
tearDownGadget()155 Status UsbGadget::tearDownGadget() {
156     if (Status(resetGadget()) != Status::SUCCESS){
157         return Status::ERROR;
158     }
159 
160     if (monitorFfs.isMonitorRunning()) {
161         monitorFfs.reset();
162     } else {
163         ALOGI("mMonitor not running");
164     }
165     return Status::SUCCESS;
166 }
167 
validateAndSetVidPid(uint64_t functions)168 static Status validateAndSetVidPid(uint64_t functions) {
169     Status ret = Status::SUCCESS;
170     std::string vendorFunctions = getVendorFunctions();
171 
172     switch (functions) {
173         case GadgetFunction::MTP:
174             if (!(vendorFunctions == "user" || vendorFunctions == "")) {
175                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
176                 ret = Status::CONFIGURATION_NOT_SUPPORTED;
177             } else {
178                 ret = Status(setVidPid("0x18d1", "0x4ee1"));
179             }
180             break;
181         case GadgetFunction::ADB |
182                 GadgetFunction::MTP:
183             if (!(vendorFunctions == "user" || vendorFunctions == "")) {
184                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
185                 ret = Status::CONFIGURATION_NOT_SUPPORTED;
186             } else {
187                 ret = Status(setVidPid("0x18d1", "0x4ee2"));
188             }
189             break;
190         case GadgetFunction::RNDIS:
191         case GadgetFunction::RNDIS |
192                 GadgetFunction::NCM:
193             if (!(vendorFunctions == "user" || vendorFunctions == "")) {
194                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
195                 ret = Status::CONFIGURATION_NOT_SUPPORTED;
196             } else {
197                 ret = Status(setVidPid("0x18d1", "0x4ee3"));
198             }
199             break;
200         case GadgetFunction::ADB |
201                 GadgetFunction::RNDIS:
202         case GadgetFunction::ADB |
203                 GadgetFunction::RNDIS |
204                 GadgetFunction::NCM:
205             if (vendorFunctions == "dm") {
206                 ret = Status(setVidPid("0x04e8", "0x6862"));
207             } else {
208                 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
209                     ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
210                     ret = Status::CONFIGURATION_NOT_SUPPORTED;
211                 } else {
212                     ret = Status(setVidPid("0x18d1", "0x4ee4"));
213                 }
214             }
215             break;
216         case GadgetFunction::PTP:
217             if (!(vendorFunctions == "user" || vendorFunctions == "")) {
218                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
219                 ret = Status::CONFIGURATION_NOT_SUPPORTED;
220             } else {
221                 ret = Status(setVidPid("0x18d1", "0x4ee5"));
222             }
223             break;
224         case GadgetFunction::ADB |
225                 GadgetFunction::PTP:
226             if (!(vendorFunctions == "user" || vendorFunctions == "")) {
227                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
228                 ret = Status::CONFIGURATION_NOT_SUPPORTED;
229             } else {
230                 ret = Status(setVidPid("0x18d1", "0x4ee6"));
231             }
232             break;
233         case GadgetFunction::ADB:
234             if (vendorFunctions == "dm") {
235                 ret = Status(setVidPid("0x04e8", "0x6862"));
236             } else if (vendorFunctions == "etr_miu") {
237                 ret = Status(setVidPid("0x18d1", "0x4ee2"));
238             } else if (vendorFunctions == "uwb_acm"){
239                 ret = Status(setVidPid("0x18d1", "0x4ee2"));
240             } else {
241                 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
242                     ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
243                     ret = Status::CONFIGURATION_NOT_SUPPORTED;
244                 } else {
245                     ret = Status(setVidPid("0x18d1", "0x4ee7"));
246                 }
247             }
248             break;
249         case GadgetFunction::MIDI:
250             if (!(vendorFunctions == "user" || vendorFunctions == "")) {
251                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
252                 ret = Status::CONFIGURATION_NOT_SUPPORTED;
253             } else {
254                 ret = Status(setVidPid("0x18d1", "0x4ee8"));
255             }
256             break;
257         case GadgetFunction::ADB |
258                 GadgetFunction::MIDI:
259             if (!(vendorFunctions == "user" || vendorFunctions == "")) {
260                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
261                 ret = Status::CONFIGURATION_NOT_SUPPORTED;
262             } else {
263                 ret = Status(setVidPid("0x18d1", "0x4ee9"));
264             }
265             break;
266         case GadgetFunction::ACCESSORY:
267             if (!(vendorFunctions == "user" || vendorFunctions == ""))
268                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
269             ret = Status(setVidPid("0x18d1", "0x2d00"));
270             break;
271         case GadgetFunction::ADB |
272                  GadgetFunction::ACCESSORY:
273             if (!(vendorFunctions == "user" || vendorFunctions == ""))
274                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
275             ret = Status(setVidPid("0x18d1", "0x2d01"));
276             break;
277         case GadgetFunction::AUDIO_SOURCE:
278             if (!(vendorFunctions == "user" || vendorFunctions == ""))
279                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
280             ret = Status(setVidPid("0x18d1", "0x2d02"));
281             break;
282         case GadgetFunction::ADB |
283                 GadgetFunction::AUDIO_SOURCE:
284             if (!(vendorFunctions == "user" || vendorFunctions == ""))
285                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
286             ret = Status(setVidPid("0x18d1", "0x2d03"));
287             break;
288         case GadgetFunction::ACCESSORY |
289                 GadgetFunction::AUDIO_SOURCE:
290             if (!(vendorFunctions == "user" || vendorFunctions == ""))
291                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
292             ret = Status(setVidPid("0x18d1", "0x2d04"));
293             break;
294         case GadgetFunction::ADB |
295                 GadgetFunction::ACCESSORY |
296                 GadgetFunction::AUDIO_SOURCE:
297             if (!(vendorFunctions == "user" || vendorFunctions == ""))
298                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
299             ret = Status(setVidPid("0x18d1", "0x2d05"));
300             break;
301         case GadgetFunction::NCM:
302             if (!(vendorFunctions == "user" || vendorFunctions == ""))
303                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
304             ret = Status(setVidPid("0x18d1", "0x4eeb"));
305             break;
306         case GadgetFunction::ADB |
307                 GadgetFunction::NCM:
308             if (vendorFunctions == "dm") {
309                 ret = Status(setVidPid("0x04e8", "0x6862"));
310             } else {
311                 if (!(vendorFunctions == "user" || vendorFunctions == ""))
312                     ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
313                 ret = Status(setVidPid("0x18d1", "0x4eec"));
314             }
315             break;
316         case GadgetFunction::UVC:
317             if (!(vendorFunctions == "user" || vendorFunctions == "")) {
318                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
319                 ret = Status::CONFIGURATION_NOT_SUPPORTED;
320             } else if (!GetBoolProperty(kUvcEnabled, false)) {
321                 ALOGE("UVC function not enabled by config");
322                 ret = Status::CONFIGURATION_NOT_SUPPORTED;
323             } else {
324                 ret = Status(setVidPid("0x18d1", "0x4eed"));
325             }
326             break;
327         case GadgetFunction::ADB | GadgetFunction::UVC:
328             if (!(vendorFunctions == "user" || vendorFunctions == "")) {
329                 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
330                 ret = Status::CONFIGURATION_NOT_SUPPORTED;
331             } else if (!GetBoolProperty(kUvcEnabled, false)) {
332                 ALOGE("UVC function not enabled by config");
333                 ret = Status::CONFIGURATION_NOT_SUPPORTED;
334             } else {
335                 ret = Status(setVidPid("0x18d1", "0x4eee"));
336             }
337             break;
338         default:
339             ALOGE("Combination not supported");
340             ret = Status::CONFIGURATION_NOT_SUPPORTED;
341     }
342     return ret;
343 }
344 
reset(const shared_ptr<IUsbGadgetCallback> & callback,int64_t in_transactionId)345 ScopedAStatus UsbGadget::reset(const shared_ptr<IUsbGadgetCallback> &callback,
346         int64_t in_transactionId) {
347     ALOGI("USB Gadget reset");
348 
349     if (!WriteStringToFile("none", PULLUP_PATH)) {
350         ALOGI("Gadget cannot be pulled down");
351         if (callback)
352             callback->resetCb(Status::ERROR, in_transactionId);
353         return ScopedAStatus::fromServiceSpecificErrorWithMessage(
354                 -1, "Gadget cannot be pulled down");
355     }
356 
357     usleep(kDisconnectWaitUs);
358 
359     if (!WriteStringToFile(kGadgetName, PULLUP_PATH)) {
360         ALOGI("Gadget cannot be pulled up");
361         if (callback)
362             callback->resetCb(Status::ERROR, in_transactionId);
363         return ScopedAStatus::fromServiceSpecificErrorWithMessage(
364                 -1, "Gadget cannot be pulled up");
365     }
366     if (callback)
367         callback->resetCb(Status::SUCCESS, in_transactionId);
368 
369     return ScopedAStatus::ok();
370 }
371 
setupFunctions(long functions,const shared_ptr<IUsbGadgetCallback> & callback,uint64_t timeout,int64_t in_transactionId)372 Status UsbGadget::setupFunctions(long functions,
373         const shared_ptr<IUsbGadgetCallback> &callback, uint64_t timeout,
374         int64_t in_transactionId) {
375     bool ffsEnabled = false;
376     int i = 0;
377 
378     if (Status(addGenericAndroidFunctions(&monitorFfs, functions, &ffsEnabled, &i)) !=
379         Status::SUCCESS)
380         return Status::ERROR;
381 
382     std::string vendorFunctions = getVendorFunctions();
383 
384     if (((functions & GadgetFunction::NCM) != 0) && (vendorFunctions != "dm")) {
385         if (linkFunction("ncm.gs9", i++))
386             return Status::ERROR;
387     }
388 
389     if (vendorFunctions == "dm") {
390         ALOGI("enable usbradio debug functions");
391         if ((functions & GadgetFunction::RNDIS) != 0) {
392             if (linkFunction("acm.gs6", i++))
393                 return Status::ERROR;
394             if (linkFunction("dm.gs7", i++))
395                 return Status::ERROR;
396         } else {
397             if (linkFunction("dm.gs7", i++))
398                 return Status::ERROR;
399             if (linkFunction("acm.gs6", i++))
400                 return Status::ERROR;
401         }
402     } else if (vendorFunctions == "etr_miu") {
403         ALOGI("enable etr_miu functions");
404         if (linkFunction("etr_miu.gs11", i++))
405             return Status::ERROR;
406     } else if (vendorFunctions == "uwb_acm") {
407         ALOGI("enable uwb acm function");
408         if (linkFunction("acm.uwb0", i++))
409             return Status::ERROR;
410     }
411 
412     if ((functions & GadgetFunction::ADB) != 0) {
413         ffsEnabled = true;
414         if (Status(addAdb(&monitorFfs, &i)) != Status::SUCCESS)
415             return Status::ERROR;
416     }
417 
418     if (((functions & GadgetFunction::NCM) != 0) && (vendorFunctions == "dm")) {
419         if (linkFunction("ncm.gs9", i++))
420             return Status::ERROR;
421     }
422 
423     // Pull up the gadget right away when there are no ffs functions.
424     if (!ffsEnabled) {
425         if (!WriteStringToFile(kGadgetName, PULLUP_PATH))
426             return Status::ERROR;
427         mCurrentUsbFunctionsApplied = true;
428         if (callback)
429             callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS, in_transactionId);
430         return Status::SUCCESS;
431     }
432 
433     monitorFfs.registerFunctionsAppliedCallback(&currentFunctionsAppliedCallback, this);
434     // Monitors the ffs paths to pull up the gadget when descriptors are written.
435     // Also takes of the pulling up the gadget again if the userspace process
436     // dies and restarts.
437     monitorFfs.startMonitor();
438 
439     if (kDebug)
440         ALOGI("Mainthread in Cv");
441 
442     if (callback) {
443         bool pullup = monitorFfs.waitForPullUp(timeout);
444         ScopedAStatus ret = callback->setCurrentUsbFunctionsCb(
445             functions, pullup ? Status::SUCCESS : Status::ERROR, in_transactionId);
446         if (!ret.isOk()) {
447             ALOGE("setCurrentUsbFunctionsCb error %s", ret.getDescription().c_str());
448             return Status::ERROR;
449         }
450     }
451     return Status::SUCCESS;
452 }
453 
setCurrentUsbFunctions(long functions,const shared_ptr<IUsbGadgetCallback> & callback,int64_t timeout,int64_t in_transactionId)454 ScopedAStatus UsbGadget::setCurrentUsbFunctions(long functions,
455                                                const shared_ptr<IUsbGadgetCallback> &callback,
456                                                int64_t timeout,
457                                                int64_t in_transactionId) {
458     std::unique_lock<std::mutex> lk(mLockSetCurrentFunction);
459     std::string current_usb_power_operation_mode, current_usb_type;
460     std::string usb_limit_sink_enable;
461     std::string accessoryCurrentLimitEnablePath, accessoryCurrentLimitPath;
462 
463     mCurrentUsbFunctions = functions;
464     mCurrentUsbFunctionsApplied = false;
465 
466     if (mI2cClientPath.empty()) {
467         for (int i = 0; i < NUM_HSI2C_PATHS; i++) {
468             mI2cClientPath = getI2cClientPath(kHsi2cPaths[i], kTcpcDevName, kI2cClientId);
469             if (mI2cClientPath.empty()) {
470                 ALOGE("%s: Unable to locate i2c bus node", __func__);
471             } else {
472                 break;
473             }
474         }
475     }
476     accessoryCurrentLimitPath = mI2cClientPath + kAccessoryLimitCurrent;
477     accessoryCurrentLimitEnablePath = mI2cClientPath + kAccessoryLimitCurrentEnable;
478 
479     // Get the gadget IRQ number before tearDownGadget()
480     if (mGadgetIrqPath.empty())
481         getUsbGadgetIrqPath();
482 
483     // Unlink the gadget and stop the monitor if running.
484     Status status = tearDownGadget();
485     if (status != Status::SUCCESS) {
486         goto error;
487     }
488 
489     ALOGI("Returned from tearDown gadget");
490 
491     // Leave the gadget pulled down to give time for the host to sense disconnect.
492     usleep(kDisconnectWaitUs);
493 
494     if (functions == GadgetFunction::NONE) {
495         if (callback == NULL)
496             return ScopedAStatus::fromServiceSpecificErrorWithMessage(
497                 -1, "callback == NULL");
498         ScopedAStatus ret = callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS, in_transactionId);
499         if (!ret.isOk())
500             ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.getDescription().c_str());
501         return ScopedAStatus::fromServiceSpecificErrorWithMessage(
502                 -1, "Error while calling setCurrentUsbFunctionsCb");
503     }
504 
505     status = validateAndSetVidPid(functions);
506 
507     if (status != Status::SUCCESS) {
508         goto error;
509     }
510 
511     status = setupFunctions(functions, callback, timeout, in_transactionId);
512     if (status != Status::SUCCESS) {
513         goto error;
514     }
515 
516     if (functions & GadgetFunction::NCM) {
517         if (!mGadgetIrqPath.empty()) {
518             if (!WriteStringToFile(BIG_CORE, mGadgetIrqPath))
519                 ALOGI("Cannot move gadget IRQ to big core, path:%s", mGadgetIrqPath.c_str());
520         }
521     } else {
522         if (!mGadgetIrqPath.empty()) {
523             if (!WriteStringToFile(MEDIUM_CORE, mGadgetIrqPath))
524                 ALOGI("Cannot move gadget IRQ to medium core, path:%s", mGadgetIrqPath.c_str());
525         }
526     }
527 
528     if (ReadFileToString(CURRENT_USB_TYPE_PATH, &current_usb_type))
529         current_usb_type = Trim(current_usb_type);
530 
531     if (ReadFileToString(CURRENT_USB_POWER_OPERATION_MODE_PATH, &current_usb_power_operation_mode))
532         current_usb_power_operation_mode = Trim(current_usb_power_operation_mode);
533 
534     if (functions & GadgetFunction::ACCESSORY &&
535         current_usb_type == "Unknown SDP [CDP] DCP" &&
536         (current_usb_power_operation_mode == "default" ||
537         current_usb_power_operation_mode == "1.5A")) {
538         if (!WriteStringToFile("1300000", accessoryCurrentLimitPath)) {
539             ALOGI("Write 1.3A to limit current fail");
540         } else {
541             if (!WriteStringToFile("1", accessoryCurrentLimitEnablePath)) {
542                 ALOGI("Enable limit current fail");
543             }
544         }
545     } else {
546         if (!WriteStringToFile("0", accessoryCurrentLimitEnablePath))
547             ALOGI("unvote accessory limit current failed");
548     }
549 
550     ALOGI("Usb Gadget setcurrent functions called successfully");
551     return ScopedAStatus::ok();
552 
553 error:
554     ALOGI("Usb Gadget setcurrent functions failed");
555     if (callback == NULL)
556         return ScopedAStatus::fromServiceSpecificErrorWithMessage(
557                 -1, "Usb Gadget setcurrent functions failed");
558     ScopedAStatus ret = callback->setCurrentUsbFunctionsCb(functions, status, in_transactionId);
559     if (!ret.isOk())
560         ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.getDescription().c_str());
561     return ScopedAStatus::fromServiceSpecificErrorWithMessage(
562                 -1, "Error while calling setCurrentUsbFunctionsCb");
563 }
564 }  // namespace gadget
565 }  // namespace usb
566 }  // namespace hardware
567 }  // namespace android
568 }  // aidl
569