summaryrefslogtreecommitdiffstats
path: root/bcmdhd/wifi_hal
diff options
context:
space:
mode:
authorEcco Park <eccopark@broadcom.com>2015-06-18 17:02:35 -0700
committerVinit Deshpande <vinitd@google.com>2015-06-24 16:07:02 -0700
commit8f1ec7e8e43ec37e94806764b2873c93368cf137 (patch)
tree7610a295e0f62b5e5cb277b7a5df991b9f86dd19 /bcmdhd/wifi_hal
parentc604b53461cfea0a1e6f6f5ad84b0a35be69b8e0 (diff)
downloadhardware_broadcom_wlan-8f1ec7e8e43ec37e94806764b2873c93368cf137.zip
hardware_broadcom_wlan-8f1ec7e8e43ec37e94806764b2873c93368cf137.tar.gz
hardware_broadcom_wlan-8f1ec7e8e43ec37e94806764b2873c93368cf137.tar.bz2
Add wifi offload feature: mkeep_alive
b/21405946 Change-Id: I8e9a2f2b2f76d1d689fcd645b9332b290d710ae6 Signed-off-by: JerryLee <jerrylee@broadcom.com>
Diffstat (limited to 'bcmdhd/wifi_hal')
-rw-r--r--bcmdhd/wifi_hal/Android.mk3
-rw-r--r--bcmdhd/wifi_hal/common.h4
-rw-r--r--bcmdhd/wifi_hal/wifi_hal.cpp2
-rw-r--r--bcmdhd/wifi_hal/wifi_offload.cpp229
4 files changed, 237 insertions, 1 deletions
diff --git a/bcmdhd/wifi_hal/Android.mk b/bcmdhd/wifi_hal/Android.mk
index bb8514a..ea19efd 100644
--- a/bcmdhd/wifi_hal/Android.mk
+++ b/bcmdhd/wifi_hal/Android.mk
@@ -32,7 +32,8 @@ LOCAL_SRC_FILES := \
cpp_bindings.cpp \
gscan.cpp \
link_layer_stats.cpp \
- wifi_logger.cpp
+ wifi_logger.cpp \
+ wifi_offload.cpp
LOCAL_MODULE := libwifi-hal-bcm
diff --git a/bcmdhd/wifi_hal/common.h b/bcmdhd/wifi_hal/common.h
index 5df02fe..8c09c16 100644
--- a/bcmdhd/wifi_hal/common.h
+++ b/bcmdhd/wifi_hal/common.h
@@ -59,6 +59,10 @@ typedef enum {
ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400,
ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END = 0x14FF,
+ /* define all wifi offload related commands between 0x1600 and 0x16FF */
+ ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600,
+ ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END = 0x16FF,
+
/* This is reserved for future usage */
} ANDROID_VENDOR_SUB_COMMAND;
diff --git a/bcmdhd/wifi_hal/wifi_hal.cpp b/bcmdhd/wifi_hal/wifi_hal.cpp
index 51cf7d6..1d02b7b 100644
--- a/bcmdhd/wifi_hal/wifi_hal.cpp
+++ b/bcmdhd/wifi_hal/wifi_hal.cpp
@@ -157,6 +157,8 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn)
fn->wifi_enable_lazy_roam = wifi_enable_lazy_roam;
fn->wifi_start_rssi_monitoring = wifi_start_rssi_monitoring;
fn->wifi_stop_rssi_monitoring = wifi_stop_rssi_monitoring;
+ 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;
}
diff --git a/bcmdhd/wifi_hal/wifi_offload.cpp b/bcmdhd/wifi_hal/wifi_offload.cpp
new file mode 100644
index 0000000..936ca40
--- /dev/null
+++ b/bcmdhd/wifi_hal/wifi_offload.cpp
@@ -0,0 +1,229 @@
+#include <stdint.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <linux/rtnetlink.h>
+#include <netpacket/packet.h>
+#include <linux/filter.h>
+#include <linux/errqueue.h>
+
+#include <linux/pkt_sched.h>
+#include <netlink/object-api.h>
+#include <netlink/netlink.h>
+#include <netlink/socket.h>
+#include <netlink-types.h>
+
+#include "nl80211_copy.h"
+#include "sync.h"
+
+#define LOG_TAG "WifiHAL"
+
+#include <utils/Log.h>
+
+#include "wifi_hal.h"
+#include "common.h"
+#include "cpp_bindings.h"
+
+using namespace android;
+
+typedef enum {
+ WIFI_OFFLOAD_START_MKEEP_ALIVE = ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START,
+ WIFI_OFFLOAD_STOP_MKEEP_ALIVE,
+} WIFI_OFFLOAD_SUB_COMMAND;
+
+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, WIFI_OFFLOAD_START_MKEEP_ALIVE);
+ 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, WIFI_OFFLOAD_STOP_MKEEP_ALIVE);
+ 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;
+ }
+}