summaryrefslogtreecommitdiff
path: root/msm8998/hal/inc/HAL.h
blob: c7b78178affdee7d8a0e8b9076972db74590effc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/*
 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above
 *      copyright notice, this list of conditions and the following
 *      disclaimer in the documentation and/or other materials provided
 *      with the distribution.
 *    * Neither the name of The Linux Foundation nor the names of its
 *      contributors may be used to endorse or promote products derived
 *      from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef _HAL_H_
#define _HAL_H_

/* HIDL Includes */
#include <android/hardware/tetheroffload/config/1.0/IOffloadConfig.h>
#include <android/hardware/tetheroffload/control/1.0/IOffloadControl.h>
#include <hidl/HidlTransportSupport.h>

/* External Includes */
#include <string>
#include <vector>

/* Internal Includes */
#include "CtUpdateAmbassador.h"
#include "IOffloadManager.h"
#include "IpaEventRelay.h"
#include "LocalLogBuffer.h"

/* Avoid the namespace litering everywhere */
using ::android::hardware::configureRpcThreadpool;
using ::android::hardware::joinRpcThreadpool;
using ::android::hardware::Return;
using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;

using RET = ::IOffloadManager::RET;
using Prefix = ::IOffloadManager::Prefix;

using ::std::map;
using ::std::string;
using ::std::vector;

using ::android::hardware::tetheroffload::config::V1_0::IOffloadConfig;
using ::android::hardware::tetheroffload::control::V1_0::IOffloadControl;

using ::android::hardware::tetheroffload::control::V1_0::ITetheringOffloadCallback;


class HAL : public IOffloadControl, IOffloadConfig {
public:
    /* Static Const Definitions */
    static const uint32_t UDP_SUBSCRIPTIONS =
            NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY;
    static const uint32_t TCP_SUBSCRIPTIONS =
            NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY;

    /* Interface to IPACM */
    /**
     * @TODO This will likely need to be extended into a proper FactoryPattern
     * when version bumps are needed.
     *
     * This makeIPAHAL function would move to a HALFactory class.  Each HAL could
     * then be versioned (class HAL_V1, class HAL_V2, etc) and inherit from a base class HAL.
     * Then the version number in this function could be used to decide which one to return
     * (if any).
     *
     * IPACM does not need to talk directly back to the returned HAL class.  The other methods that
     * IPACM needs to call are covered by registering the event listeners.  If IPACM did need to
     * talk directly back to the HAL object, without HAL registering a callback, these methods would
     * need to be defined in the HAL base class.
     *
     * This would slightly break backwards compatibility so it should be discouraged; however, the
     * base class could define a sane default implementation and not require that the child class
     * implement this new method.  This "sane default implementation" might only be possible in the
     * case of listening to async events; if IPACM needs to query something, then this would not
     * be backwards compatible and should be done via registering a callback so that IPACM knows
     * this version of HAL supports that functionality.
     *
     * The above statements assume that only one version of the HAL will be instantiated at a time.
     * Yet, it seems possible that a HAL_V1 and HAL_V2 service could both be registered, extending
     * support to both old and new client implementations.  It would be difficult to multiplex
     * information from both versions.  Additionally, IPACM would be responsible for instantiating
     * two HALs (makeIPAHAL(1, ...); makeIPAHAL(2, ...)) which makes signaling between HAL versions
     * (see next paragraph) slightly more difficult but not impossible.
     *
     * If concurrent versions of HAL are required, there will likely need to only be one master.
     * Whichever version of HAL receives a client first may be allowed to take over control while
     * other versions would be required to return failures (ETRYAGAIN: another version in use) until
     * that version of the client relinquishes control.  This should work seemlessly because we
     * currently have an assumption that only one client will be present in system image.
     * Logically, that client will have only a single version (or if it supports multiple, it will
     * always attempt the newest version of HAL before falling back) and therefore no version
     * collisions could possibly occur.
     *
     * Dislaimer:
     * ==========
     * Supporting multiple versions of an interface, in the same code base, at runtime, comes with a
     * significant carrying cost and overhead in the form of developer headaches.  This should not
     * be done lightly and should be extensively scoped before committing to the effort.
     *
     * Perhaps the notion of minor version could be introduced to bridge the gaps created above.
     * For example, 1.x and 1.y could be ran concurrently and supported from the same IPACM code.
     * Yet, a major version update, would not be backwards compatible.  This means that a 2.x HAL
     * could not linked into the same IPACM code base as a 1.x HAL.
     */
    static HAL* makeIPAHAL(int /* version */, IOffloadManager* /* mgr */);

    /* IOffloadConfig */
    Return<void> setHandles(
            const hidl_handle& /* fd1 */,
            const hidl_handle& /* fd2 */,
            setHandles_cb /* hidl_cb */);

    /* IOffloadControl */
    Return<void> initOffload(
            const ::android::sp<ITetheringOffloadCallback>& /* cb */,
            initOffload_cb /* hidl_cb */);
    Return<void> stopOffload(
            stopOffload_cb /* hidl_cb */);
    Return<void> setLocalPrefixes(
            const hidl_vec<hidl_string>& /* prefixes */,
            setLocalPrefixes_cb /* hidl_cb */);
    Return<void> getForwardedStats(
            const hidl_string& /* upstream */,
            getForwardedStats_cb /* hidl_cb */);
    Return<void> setDataLimit(
            const hidl_string& /* upstream */,
            uint64_t /* limit */,
            setDataLimit_cb /* hidl_cb */);
    Return<void> setUpstreamParameters(
            const hidl_string& /* iface */,
            const hidl_string& /* v4Addr */,
            const hidl_string& /* v4Gw */,
            const hidl_vec<hidl_string>& /* v6Gws */,
            setUpstreamParameters_cb /* hidl_cb */);
    Return<void> addDownstream(
            const hidl_string& /* iface */,
            const hidl_string& /* prefix */,
            addDownstream_cb /* hidl_cb */);
    Return<void> removeDownstream(
            const hidl_string& /* iface */,
            const hidl_string& /* prefix */,
            removeDownstream_cb /* hidl_cb */);

    /* Common */
    Return<void> debug(const hidl_handle& /* fd */, const hidl_vec<hidl_string>& /* options */);

private:
    typedef struct BoolResult {
        bool success;
        string errMsg;
    } boolResult_t;

    HAL(IOffloadManager* /* mgr */);
    void registerAsSystemService();
    void doLogcatDump();

    static BoolResult makeInputCheckFailure(string /* customErr */);
    static BoolResult ipaResultToBoolResult(RET /* in */);

    static vector<string> convertHidlStrToStdStr(hidl_vec<hidl_string> /* in */);

    void registerEventListeners();
    void registerIpaCb();
    void registerCtCb();
    void unregisterEventListeners();
    void unregisterIpaCb();
    void unregisterCtCb();

    void clearHandles();

    bool isInitialized();

    IOffloadManager* mIPA;
    hidl_handle mHandle1;
    hidl_handle mHandle2;
    LocalLogBuffer mLogs;
    ::android::sp<ITetheringOffloadCallback> mCb;
    IpaEventRelay *mCbIpa;
    CtUpdateAmbassador *mCbCt;
}; /* HAL */
#endif /* _HAL_H_ */