• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2017-2018, 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 #define KERNEL_PAGE 4096
68 
69 class HAL : public IOffloadControl, IOffloadConfig {
70 public:
71     /* Static Const Definitions */
72     static const uint32_t UDP_SUBSCRIPTIONS =
73             NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY;
74     static const uint32_t TCP_SUBSCRIPTIONS =
75             NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY;
76 
77     /* Interface to IPACM */
78     /**
79      * @TODO This will likely need to be extended into a proper FactoryPattern
80      * when version bumps are needed.
81      *
82      * This makeIPAHAL function would move to a HALFactory class.  Each HAL could
83      * then be versioned (class HAL_V1, class HAL_V2, etc) and inherit from a base class HAL.
84      * Then the version number in this function could be used to decide which one to return
85      * (if any).
86      *
87      * IPACM does not need to talk directly back to the returned HAL class.  The other methods that
88      * IPACM needs to call are covered by registering the event listeners.  If IPACM did need to
89      * talk directly back to the HAL object, without HAL registering a callback, these methods would
90      * need to be defined in the HAL base class.
91      *
92      * This would slightly break backwards compatibility so it should be discouraged; however, the
93      * base class could define a sane default implementation and not require that the child class
94      * implement this new method.  This "sane default implementation" might only be possible in the
95      * case of listening to async events; if IPACM needs to query something, then this would not
96      * be backwards compatible and should be done via registering a callback so that IPACM knows
97      * this version of HAL supports that functionality.
98      *
99      * The above statements assume that only one version of the HAL will be instantiated at a time.
100      * Yet, it seems possible that a HAL_V1 and HAL_V2 service could both be registered, extending
101      * support to both old and new client implementations.  It would be difficult to multiplex
102      * information from both versions.  Additionally, IPACM would be responsible for instantiating
103      * two HALs (makeIPAHAL(1, ...); makeIPAHAL(2, ...)) which makes signaling between HAL versions
104      * (see next paragraph) slightly more difficult but not impossible.
105      *
106      * If concurrent versions of HAL are required, there will likely need to only be one master.
107      * Whichever version of HAL receives a client first may be allowed to take over control while
108      * other versions would be required to return failures (ETRYAGAIN: another version in use) until
109      * that version of the client relinquishes control.  This should work seemlessly because we
110      * currently have an assumption that only one client will be present in system image.
111      * Logically, that client will have only a single version (or if it supports multiple, it will
112      * always attempt the newest version of HAL before falling back) and therefore no version
113      * collisions could possibly occur.
114      *
115      * Dislaimer:
116      * ==========
117      * Supporting multiple versions of an interface, in the same code base, at runtime, comes with a
118      * significant carrying cost and overhead in the form of developer headaches.  This should not
119      * be done lightly and should be extensively scoped before committing to the effort.
120      *
121      * Perhaps the notion of minor version could be introduced to bridge the gaps created above.
122      * For example, 1.x and 1.y could be ran concurrently and supported from the same IPACM code.
123      * Yet, a major version update, would not be backwards compatible.  This means that a 2.x HAL
124      * could not linked into the same IPACM code base as a 1.x HAL.
125      */
126     static Return<::android::sp<HAL>> makeIPAHAL(int /* version */, IOffloadManager* /* mgr */);
127 
128     /* IOffloadConfig */
129     Return<void> setHandles(
130             const hidl_handle& /* fd1 */,
131             const hidl_handle& /* fd2 */,
132             setHandles_cb /* hidl_cb */);
133 
134     /* IOffloadControl */
135     Return<void> initOffload(
136             const ::android::sp<ITetheringOffloadCallback>& /* cb */,
137             initOffload_cb /* hidl_cb */);
138     Return<void> stopOffload(
139             stopOffload_cb /* hidl_cb */);
140     Return<void> setLocalPrefixes(
141             const hidl_vec<hidl_string>& /* prefixes */,
142             setLocalPrefixes_cb /* hidl_cb */);
143     Return<void> getForwardedStats(
144             const hidl_string& /* upstream */,
145             getForwardedStats_cb /* hidl_cb */);
146     Return<void> setDataLimit(
147             const hidl_string& /* upstream */,
148             uint64_t /* limit */,
149             setDataLimit_cb /* hidl_cb */);
150     Return<void> setUpstreamParameters(
151             const hidl_string& /* iface */,
152             const hidl_string& /* v4Addr */,
153             const hidl_string& /* v4Gw */,
154             const hidl_vec<hidl_string>& /* v6Gws */,
155             setUpstreamParameters_cb /* hidl_cb */);
156     Return<void> addDownstream(
157             const hidl_string& /* iface */,
158             const hidl_string& /* prefix */,
159             addDownstream_cb /* hidl_cb */);
160     Return<void> removeDownstream(
161             const hidl_string& /* iface */,
162             const hidl_string& /* prefix */,
163             removeDownstream_cb /* hidl_cb */);
164 
165 private:
166     typedef struct BoolResult {
167         bool success;
168         string errMsg;
169     } boolResult_t;
170 
171     HAL(IOffloadManager* /* mgr */);
172     void registerAsSystemService(const char* /* name */);
173 
174     void doLogcatDump();
175 
176     static BoolResult makeInputCheckFailure(string /* customErr */);
177     static BoolResult ipaResultToBoolResult(RET /* in */);
178 
179     static vector<string> convertHidlStrToStdStr(hidl_vec<hidl_string> /* in */);
180 
181     void registerEventListeners();
182     void registerIpaCb();
183     void registerCtCb();
184     void unregisterEventListeners();
185     void unregisterIpaCb();
186     void unregisterCtCb();
187 
188     void clearHandles();
189 
190     bool isInitialized();
191 
192     IOffloadManager* mIPA;
193     hidl_handle mHandle1;
194     hidl_handle mHandle2;
195     LocalLogBuffer mLogs;
196     ::android::sp<ITetheringOffloadCallback> mCb;
197     IpaEventRelay *mCbIpa;
198     CtUpdateAmbassador *mCbCt;
199 }; /* HAL */
200 #endif /* _HAL_H_ */
201