You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
202 lines
8.7 KiB
202 lines
8.7 KiB
4 months ago
|
/*
|
||
|
* 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_ */
|