From 3c0c6ab1e9438a8dfd493f43cd2aa301f503ae86 Mon Sep 17 00:00:00 2001 From: Pragya Gupta Date: Thu, 5 May 2016 15:09:02 +0530 Subject: [PATCH] [7570] wlbt: Changes for NAT KeepAlive offload Changes to handle NAT Keep Alive offload . Android M Framweork uses wifi HAL to start and stop offloading .These changes are added to handle these HAL commands SCSC-Bug-Id:SSB-16454 Change-Id: I65a6e9f349328755040360b51f9df45c9fac5a8f Signed-off-by: Pragya Gupta --- Android.mk | 3 +- common.h | 10 ++- wifi_hal.cpp | 4 +- wifi_offload.cpp | 226 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 239 insertions(+), 4 deletions(-) create mode 100644 wifi_offload.cpp diff --git a/Android.mk b/Android.mk index 79efc72..0a8d325 100755 --- a/Android.mk +++ b/Android.mk @@ -25,7 +25,8 @@ LOCAL_SRC_FILES := \ common.cpp \ cpp_bindings.cpp \ gscan.cpp \ - link_layer_stats.cpp + link_layer_stats.cpp \ + wifi_offload.cpp LOCAL_MODULE := libwifi-hal-slsi diff --git a/common.h b/common.h index 32e226a..61d12dc 100755 --- a/common.h +++ b/common.h @@ -55,7 +55,11 @@ typedef enum { ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200, ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF, - /* This is reserved for future usage */ + /* define all wifi offload related commands between 0x1400 and 0x14FF */ + ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1400, + ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END = 0x14FF, + + /* This is reserved for future usage */ } ANDROID_VENDOR_SUB_COMMAND; @@ -71,7 +75,9 @@ typedef enum { SLSI_NL80211_VENDOR_SUBCMD_SET_SIGNIFICANT_CHANGE, SLSI_NL80211_VENDOR_SUBCMD_RESET_SIGNIFICANT_CHANGE, SLSI_NL80211_VENDOR_SUBCMD_SET_GSCAN_OUI, - SLSI_NL80211_VENDOR_SUBCMD_SET_NODFS + SLSI_NL80211_VENDOR_SUBCMD_SET_NODFS, + SLSI_NL80211_VENDOR_SUBCMD_START_KEEP_ALIVE_OFFLOAD, + SLSI_NL80211_VENDOR_SUBCMD_STOP_KEEP_ALIVE_OFFLOAD } WIFI_SUB_COMMAND; typedef enum { diff --git a/wifi_hal.cpp b/wifi_hal.cpp index 2c2cf0b..7e0123a 100755 --- a/wifi_hal.cpp +++ b/wifi_hal.cpp @@ -121,6 +121,8 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel; fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities; fn->wifi_set_nodfs_flag = wifi_set_nodfs_flag; + fn->wifi_start_sending_offloaded_packet = wifi_start_sending_offloaded_packet; + fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet; return WIFI_SUCCESS; } @@ -421,7 +423,7 @@ static int internal_valid_message_handler(nl_msg *msg, void *arg) bool dispatched = false; pthread_mutex_lock(&info->cb_lock); - + ALOGI("Number of events %d", info->num_event_cb); for (int i = 0; i < info->num_event_cb; i++) { diff --git a/wifi_offload.cpp b/wifi_offload.cpp new file mode 100644 index 0000000..ee16b17 --- /dev/null +++ b/wifi_offload.cpp @@ -0,0 +1,226 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "nl80211_copy.h" +#include "sync.h" + +#define LOG_TAG "WifiHAL" + +#include + +#include "wifi_hal.h" +#include "common.h" +#include "cpp_bindings.h" + +#ifndef SLSI_WLAN_UNIT_TEST +using namespace android; +#endif + +typedef enum { + MKEEP_ALIVE_ATTRIBUTE_ID, + MKEEP_ALIVE_ATTRIBUTE_IP_PKT, + MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN, + MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR, + MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR, + MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC +} WIFI_MKEEP_ALIVE_ATTRIBUTE; + +typedef enum { + START_MKEEP_ALIVE, + STOP_MKEEP_ALIVE, +} GetCmdType; + +/////////////////////////////////////////////////////////////////////////////// +class MKeepAliveCommand : public WifiCommand +{ + u8 mIndex; + u8 *mIpPkt; + u16 mIpPktLen; + u8 *mSrcMacAddr; + u8 *mDstMacAddr; + u32 mPeriodMsec; + GetCmdType mType; + +public: + + // constructor for start sending + MKeepAliveCommand(wifi_interface_handle iface, u8 index, u8 *ip_packet, u16 ip_packet_len, + u8 *src_mac_addr, u8 *dst_mac_addr, u32 period_msec, GetCmdType cmdType) + : WifiCommand(iface, 0), mIndex(index), mIpPkt(ip_packet), + mIpPktLen(ip_packet_len), mSrcMacAddr(src_mac_addr), mDstMacAddr(dst_mac_addr), + mPeriodMsec(period_msec), mType(cmdType) + { } + + // constructor for stop sending + MKeepAliveCommand(wifi_interface_handle iface, u8 index, GetCmdType cmdType) + : WifiCommand(iface, 0), mIndex(index), mType(cmdType) + { } + + int createRequest(WifiRequest &request) { + int result; + + switch (mType) { + case START_MKEEP_ALIVE: + { + result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_START_KEEP_ALIVE_OFFLOAD); + if (result != WIFI_SUCCESS) { + ALOGE("Failed to create start keep alive request; result = %d", result); + return result; + } + + nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); + + result = request.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID, mIndex); + if (result < 0) { + ALOGE("Failed to put id request; result = %d", result); + return result; + } + + result = request.put_u16(MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN, mIpPktLen); + if (result < 0) { + ALOGE("Failed to put ip pkt len request; result = %d", result); + return result; + } + + result = request.put(MKEEP_ALIVE_ATTRIBUTE_IP_PKT, (u8*)mIpPkt, mIpPktLen); + if (result < 0) { + ALOGE("Failed to put ip pkt request; result = %d", result); + return result; + } + + result = request.put_addr(MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR, mSrcMacAddr); + if (result < 0) { + ALOGE("Failed to put src mac address request; result = %d", result); + return result; + } + + result = request.put_addr(MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR, mDstMacAddr); + if (result < 0) { + ALOGE("Failed to put dst mac address request; result = %d", result); + return result; + } + + result = request.put_u32(MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC, mPeriodMsec); + if (result < 0) { + ALOGE("Failed to put period request; result = %d", result); + return result; + } + + request.attr_end(data); + break; + } + + case STOP_MKEEP_ALIVE: + { + result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_STOP_KEEP_ALIVE_OFFLOAD); + if (result != WIFI_SUCCESS) { + ALOGE("Failed to create stop keep alive request; result = %d", result); + return result; + } + + nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); + + result = request.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID, mIndex); + if (result < 0) { + ALOGE("Failed to put id request; result = %d", result); + return result; + } + + request.attr_end(data); + break; + } + + default: + ALOGE("Unknown wifi keep alive command"); + result = WIFI_ERROR_UNKNOWN; + } + return result; + } + + int start() { + ALOGD("Start mkeep_alive command"); + WifiRequest request(familyId(), ifaceId()); + int result = createRequest(request); + if (result != WIFI_SUCCESS) { + ALOGE("Failed to create keep alive request; result = %d", result); + return result; + } + + result = requestResponse(request); + if (result != WIFI_SUCCESS) { + ALOGE("Failed to register keep alive response; result = %d", result); + } + return result; + } + + virtual int handleResponse(WifiEvent& reply) { + ALOGD("In MKeepAliveCommand::handleResponse"); + + if (reply.get_cmd() != NL80211_CMD_VENDOR) { + ALOGD("Ignoring reply with cmd = %d", reply.get_cmd()); + return NL_SKIP; + } + + switch (mType) { + case START_MKEEP_ALIVE: + case STOP_MKEEP_ALIVE: + break; + + default: + ALOGW("Unknown mkeep_alive command"); + } + return NL_OK; + } + + virtual int handleEvent(WifiEvent& event) { + /* NO events! */ + return NL_SKIP; + } +}; + + +/* API to send specified mkeep_alive packet periodically. */ +wifi_error wifi_start_sending_offloaded_packet(wifi_request_id index, wifi_interface_handle iface, + u8 *ip_packet, u16 ip_packet_len, u8 *src_mac_addr, u8 *dst_mac_addr, u32 period_msec) +{ + if ((index > 0 && index <= N_AVAIL_ID) && (ip_packet != NULL) && (src_mac_addr != NULL) + && (dst_mac_addr != NULL) && (period_msec > 0) + && (ip_packet_len <= MKEEP_ALIVE_IP_PKT_MAX)) { + MKeepAliveCommand *cmd = new MKeepAliveCommand(iface, index, ip_packet, ip_packet_len, + src_mac_addr, dst_mac_addr, period_msec, START_MKEEP_ALIVE); + wifi_error result = (wifi_error)cmd->start(); + delete cmd; + return result; + } else { + ALOGE("Invalid mkeep_alive parameters"); + return WIFI_ERROR_INVALID_ARGS; + } +} + +/* API to stop sending mkeep_alive packet. */ +wifi_error wifi_stop_sending_offloaded_packet(wifi_request_id index, wifi_interface_handle iface) +{ + if (index > 0 && index <= N_AVAIL_ID) { + MKeepAliveCommand *cmd = new MKeepAliveCommand(iface, index, STOP_MKEEP_ALIVE); + wifi_error result = (wifi_error)cmd->start(); + delete cmd; + return result; + } else { + ALOGE("Invalid mkeep_alive parameters"); + return WIFI_ERROR_INVALID_ARGS; + } +} -- 2.20.1