1/*
2 * hidl interface for wpa_supplicant daemon
3 * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
4 * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
5 *
6 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
8 */
9
10#ifndef HIDL_RETURN_UTIL_H_
11#define HIDL_RETURN_UTIL_H_
12
13namespace android {
14namespace hardware {
15namespace wifi {
16namespace supplicant {
17namespace V1_1 {
18namespace implementation {
19namespace hidl_return_util {
20
21/**
22 * These utility functions are used to invoke a method on the provided
23 * HIDL interface object.
24 * These functions checks if the provided HIDL interface object is valid.
25 * a) if valid, Invokes the corresponding internal implementation function of
26 * the HIDL method. It then invokes the HIDL continuation callback with
27 * the status and any returned values.
28 * b) if invalid, invokes the HIDL continuation callback with the
29 * provided error status and default values.
30 */
31// Use for HIDL methods which return only an instance of SupplicantStatus.
32template <typename ObjT, typename WorkFuncT, typename... Args>
33Return<void> validateAndCall(
34    ObjT* obj, SupplicantStatusCode status_code_if_invalid, WorkFuncT&& work,
35    const std::function<void(const SupplicantStatus&)>& hidl_cb, Args&&... args)
36{
37	if (obj->isValid()) {
38		hidl_cb((obj->*work)(std::forward<Args>(args)...));
39	} else {
40		hidl_cb({status_code_if_invalid, ""});
41	}
42	return Void();
43}
44
45// Use for HIDL methods which return instance of SupplicantStatus and a single
46// return value.
47template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args>
48Return<void> validateAndCall(
49    ObjT* obj, SupplicantStatusCode status_code_if_invalid, WorkFuncT&& work,
50    const std::function<void(const SupplicantStatus&, ReturnT)>& hidl_cb,
51    Args&&... args)
52{
53	if (obj->isValid()) {
54		const auto& ret_pair =
55		    (obj->*work)(std::forward<Args>(args)...);
56		const SupplicantStatus& status = std::get<0>(ret_pair);
57		const auto& ret_value = std::get<1>(ret_pair);
58		hidl_cb(status, ret_value);
59	} else {
60		hidl_cb(
61		    {status_code_if_invalid, ""},
62		    typename std::remove_reference<ReturnT>::type());
63	}
64	return Void();
65}
66
67// Use for HIDL methods which return instance of SupplicantStatus and 2 return
68// values.
69template <
70    typename ObjT, typename WorkFuncT, typename ReturnT1, typename ReturnT2,
71    typename... Args>
72Return<void> validateAndCall(
73    ObjT* obj, SupplicantStatusCode status_code_if_invalid, WorkFuncT&& work,
74    const std::function<void(const SupplicantStatus&, ReturnT1, ReturnT2)>&
75	hidl_cb,
76    Args&&... args)
77{
78	if (obj->isValid()) {
79		const auto& ret_tuple =
80		    (obj->*work)(std::forward<Args>(args)...);
81		const SupplicantStatus& status = std::get<0>(ret_tuple);
82		const auto& ret_value1 = std::get<1>(ret_tuple);
83		const auto& ret_value2 = std::get<2>(ret_tuple);
84		hidl_cb(status, ret_value1, ret_value2);
85	} else {
86		hidl_cb(
87		    {status_code_if_invalid, ""},
88		    typename std::remove_reference<ReturnT1>::type(),
89		    typename std::remove_reference<ReturnT2>::type());
90	}
91	return Void();
92}
93
94}  // namespace hidl_util
95}  // namespace implementation
96}  // namespace V1_1
97}  // namespace supplicant
98}  // namespace wifi
99}  // namespace hardware
100}  // namespace android
101#endif  // HIDL_RETURN_UTIL_H_
102