1 /*
2  * Copyright (c) 2017, The Linux Foundation. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *    * Redistributions of source code must retain the above copyright
8  *      notice, this list of conditions and the following disclaimer.
9  *    * Redistributions in binary form must reproduce the above
10  *      copyright notice, this list of conditions and the following
11  *      disclaimer in the documentation and/or other materials provided
12  *      with the distribution.
13  *    * Neither the name of The Linux Foundation nor the names of its
14  *      contributors may be used to endorse or promote products derived
15  *      from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 #ifndef _HAL_H_
30 #define _HAL_H_
31 
32 /* HIDL Includes */
33 #include <android/hardware/tetheroffload/config/1.0/IOffloadConfig.h>
34 #include <android/hardware/tetheroffload/control/1.0/IOffloadControl.h>
35 #include <hidl/HidlTransportSupport.h>
36 
37 /* External Includes */
38 #include <string>
39 #include <vector>
40 
41 /* Internal Includes */
42 #include "CtUpdateAmbassador.h"
43 #include "IOffloadManager.h"
44 #include "IpaEventRelay.h"
45 #include "LocalLogBuffer.h"
46 
47 /* Avoid the namespace litering everywhere */
48 using ::android::hardware::configureRpcThreadpool;
49 using ::android::hardware::joinRpcThreadpool;
50 using ::android::hardware::Return;
51 using ::android::hardware::hidl_handle;
52 using ::android::hardware::hidl_string;
53 using ::android::hardware::hidl_vec;
54 
55 using RET = ::IOffloadManager::RET;
56 using Prefix = ::IOffloadManager::Prefix;
57 
58 using ::std::map;
59 using ::std::string;
60 using ::std::vector;
61 
62 using ::android::hardware::tetheroffload::config::V1_0::IOffloadConfig;
63 using ::android::hardware::tetheroffload::control::V1_0::IOffloadControl;
64 
65 using ::android::hardware::tetheroffload::control::V1_0::ITetheringOffloadCallback;
66 
67 
68 class HAL : public IOffloadControl, IOffloadConfig {
69 public:
70     /* Static Const Definitions */
71     static const uint32_t UDP_SUBSCRIPTIONS =
72             NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY;
73     static const uint32_t TCP_SUBSCRIPTIONS =
74             NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY;
75 
76     /* Interface to IPACM */
77     /**
78      * @TODO This will likely need to be extended into a proper FactoryPattern
79      * when version bumps are needed.
80      *
81      * This makeIPAHAL function would move to a HALFactory class.  Each HAL could
82      * then be versioned (class HAL_V1, class HAL_V2, etc) and inherit from a base class HAL.
83      * Then the version number in this function could be used to decide which one to return
84      * (if any).
85      *
86      * IPACM does not need to talk directly back to the returned HAL class.  The other methods that
87      * IPACM needs to call are covered by registering the event listeners.  If IPACM did need to
88      * talk directly back to the HAL object, without HAL registering a callback, these methods would
89      * need to be defined in the HAL base class.
90      *
91      * This would slightly break backwards compatibility so it should be discouraged; however, the
92      * base class could define a sane default implementation and not require that the child class
93      * implement this new method.  This "sane default implementation" might only be possible in the
94      * case of listening to async events; if IPACM needs to query something, then this would not
95      * be backwards compatible and should be done via registering a callback so that IPACM knows
96      * this version of HAL supports that functionality.
97      *
98      * The above statements assume that only one version of the HAL will be instantiated at a time.
99      * Yet, it seems possible that a HAL_V1 and HAL_V2 service could both be registered, extending
100      * support to both old and new client implementations.  It would be difficult to multiplex
101      * information from both versions.  Additionally, IPACM would be responsible for instantiating
102      * two HALs (makeIPAHAL(1, ...); makeIPAHAL(2, ...)) which makes signaling between HAL versions
103      * (see next paragraph) slightly more difficult but not impossible.
104      *
105      * If concurrent versions of HAL are required, there will likely need to only be one master.
106      * Whichever version of HAL receives a client first may be allowed to take over control while
107      * other versions would be required to return failures (ETRYAGAIN: another version in use) until
108      * that version of the client relinquishes control.  This should work seemlessly because we
109      * currently have an assumption that only one client will be present in system image.
110      * Logically, that client will have only a single version (or if it supports multiple, it will
111      * always attempt the newest version of HAL before falling back) and therefore no version
112      * collisions could possibly occur.
113      *
114      * Dislaimer:
115      * ==========
116      * Supporting multiple versions of an interface, in the same code base, at runtime, comes with a
117      * significant carrying cost and overhead in the form of developer headaches.  This should not
118      * be done lightly and should be extensively scoped before committing to the effort.
119      *
120      * Perhaps the notion of minor version could be introduced to bridge the gaps created above.
121      * For example, 1.x and 1.y could be ran concurrently and supported from the same IPACM code.
122      * Yet, a major version update, would not be backwards compatible.  This means that a 2.x HAL
123      * could not linked into the same IPACM code base as a 1.x HAL.
124      */
125     static HAL* makeIPAHAL(int /* version */, IOffloadManager* /* mgr */);
126 
127     /* IOffloadConfig */
128     Return<void> setHandles(
129             const hidl_handle& /* fd1 */,
130             const hidl_handle& /* fd2 */,
131             setHandles_cb /* hidl_cb */);
132 
133     /* IOffloadControl */
134     Return<void> initOffload(
135             const ::android::sp<ITetheringOffloadCallback>& /* cb */,
136             initOffload_cb /* hidl_cb */);
137     Return<void> stopOffload(
138             stopOffload_cb /* hidl_cb */);
139     Return<void> setLocalPrefixes(
140             const hidl_vec<hidl_string>& /* prefixes */,
141             setLocalPrefixes_cb /* hidl_cb */);
142     Return<void> getForwardedStats(
143             const hidl_string& /* upstream */,
144             getForwardedStats_cb /* hidl_cb */);
145     Return<void> setDataLimit(
146             const hidl_string& /* upstream */,
147             uint64_t /* limit */,
148             setDataLimit_cb /* hidl_cb */);
149     Return<void> setUpstreamParameters(
150             const hidl_string& /* iface */,
151             const hidl_string& /* v4Addr */,
152             const hidl_string& /* v4Gw */,
153             const hidl_vec<hidl_string>& /* v6Gws */,
154             setUpstreamParameters_cb /* hidl_cb */);
155     Return<void> addDownstream(
156             const hidl_string& /* iface */,
157             const hidl_string& /* prefix */,
158             addDownstream_cb /* hidl_cb */);
159     Return<void> removeDownstream(
160             const hidl_string& /* iface */,
161             const hidl_string& /* prefix */,
162             removeDownstream_cb /* hidl_cb */);
163 
164 private:
165     typedef struct BoolResult {
166         bool success;
167         string errMsg;
168     } boolResult_t;
169 
170     HAL(IOffloadManager* /* mgr */);
171     void registerAsSystemService(const char* /* name */);
172 
173     void doLogcatDump();
174 
175     static BoolResult makeInputCheckFailure(string /* customErr */);
176     static BoolResult ipaResultToBoolResult(RET /* in */);
177 
178     static vector<string> convertHidlStrToStdStr(hidl_vec<hidl_string> /* in */);
179 
180     void registerEventListeners();
181     void registerIpaCb();
182     void registerCtCb();
183     void unregisterEventListeners();
184     void unregisterIpaCb();
185     void unregisterCtCb();
186 
187     void clearHandles();
188 
189     bool isInitialized();
190 
191     IOffloadManager* mIPA;
192     hidl_handle mHandle1;
193     hidl_handle mHandle2;
194     LocalLogBuffer mLogs;
195     ::android::sp<ITetheringOffloadCallback> mCb;
196     IpaEventRelay *mCbIpa;
197     CtUpdateAmbassador *mCbCt;
198 }; /* HAL */
199 #endif /* _HAL_H_ */
200