1 /*
2 * WPA Supplicant - Validate interfaces before calling methods
3 * Copyright (c) 2021, Google Inc. All rights reserved.
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #ifndef AIDL_RETURN_UTIL_H_
10 #define AIDL_RETURN_UTIL_H_
11
12 #include <aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.h>
13 #include <mutex>
14
15 namespace {
16 // Mutex serializes requests when this process is called by multiple clients
17 std::mutex aidl_return_mutex;
18 }
19
20 namespace aidl {
21 namespace android {
22 namespace hardware {
23 namespace wifi {
24 namespace supplicant {
25 namespace aidl_return_util {
26
27 /**
28 * These utility functions are used to invoke a method on the provided
29 * AIDL interface object.
30 * These functions check if the provided AIDL interface object is valid.
31 * a) If valid, invokes the corresponding internal implementation function of
32 * the AIDL method.
33 * b) If invalid, return without calling the internal implementation function.
34 */
35
36 // Use for AIDL methods which only return an AIDL status
37 template <typename ObjT, typename WorkFuncT, typename... Args>
validateAndCall(ObjT * obj,SupplicantStatusCode status_code_if_invalid,WorkFuncT && work,Args &&...args)38 ::ndk::ScopedAStatus validateAndCall(
39 ObjT* obj, SupplicantStatusCode status_code_if_invalid, WorkFuncT&& work,
40 Args&&... args)
41 {
42 std::lock_guard<std::mutex> guard(aidl_return_mutex);
43 if (obj->isValid()) {
44 return (obj->*work)(std::forward<Args>(args)...);
45 } else {
46 return ndk::ScopedAStatus::fromServiceSpecificError(
47 static_cast<int32_t>(status_code_if_invalid));
48 }
49 }
50
51 // Use for AIDL methods which have a return value along with the AIDL status
52 template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args>
validateAndCall(ObjT * obj,SupplicantStatusCode status_code_if_invalid,WorkFuncT && work,ReturnT * ret_val,Args &&...args)53 ::ndk::ScopedAStatus validateAndCall(
54 ObjT* obj, SupplicantStatusCode status_code_if_invalid, WorkFuncT&& work,
55 ReturnT* ret_val, Args&&... args)
56 {
57 std::lock_guard<std::mutex> guard(aidl_return_mutex);
58 if (obj->isValid()) {
59 auto call_pair = (obj->*work)(std::forward<Args>(args)...);
60 *ret_val = call_pair.first;
61 return std::forward<::ndk::ScopedAStatus>(call_pair.second);
62 } else {
63 return ndk::ScopedAStatus::fromServiceSpecificError(
64 static_cast<int32_t>(status_code_if_invalid));
65 }
66 }
67
68 } // namespace aidl_return_util
69 } // namespace supplicant
70 } // namespace wifi
71 } // namespace hardware
72 } // namespace android
73 } // namespace aidl
74 #endif // AIDL_RETURN_UTIL_H_
75