[APR-2053]wlbt: NAN R2 integration fxes
[GitHub/MotorolaMobilityLLC/hardware-samsung_slsi-scsc_wifibt-wifi_hal.git] / wifi_offload.cpp
CommitLineData
3c0c6ab1
PG
1#include <stdint.h>
2#include <fcntl.h>
3#include <sys/socket.h>
4#include <netlink/genl/genl.h>
5#include <netlink/genl/family.h>
6#include <netlink/genl/ctrl.h>
7#include <linux/rtnetlink.h>
8#include <netpacket/packet.h>
9#include <linux/filter.h>
10#include <linux/errqueue.h>
11
12#include <linux/pkt_sched.h>
13#include <netlink/object-api.h>
14#include <netlink/netlink.h>
15#include <netlink/socket.h>
f84a01f1 16#include <netlink/types.h>
3c0c6ab1
PG
17
18#include "nl80211_copy.h"
19#include "sync.h"
20
d3a587e8 21#define LOG_TAG "WifiHAL[offload]"
3c0c6ab1
PG
22
23#include <utils/Log.h>
24
25#include "wifi_hal.h"
26#include "common.h"
27#include "cpp_bindings.h"
28
3c0c6ab1
PG
29typedef enum {
30 MKEEP_ALIVE_ATTRIBUTE_ID,
31 MKEEP_ALIVE_ATTRIBUTE_IP_PKT,
32 MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN,
33 MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR,
34 MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR,
35 MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC
36} WIFI_MKEEP_ALIVE_ATTRIBUTE;
37
38typedef enum {
39 START_MKEEP_ALIVE,
40 STOP_MKEEP_ALIVE,
41} GetCmdType;
42
43///////////////////////////////////////////////////////////////////////////////
44class MKeepAliveCommand : public WifiCommand
45{
46 u8 mIndex;
47 u8 *mIpPkt;
48 u16 mIpPktLen;
49 u8 *mSrcMacAddr;
50 u8 *mDstMacAddr;
51 u32 mPeriodMsec;
52 GetCmdType mType;
53
54public:
55
56 // constructor for start sending
57 MKeepAliveCommand(wifi_interface_handle iface, u8 index, u8 *ip_packet, u16 ip_packet_len,
58 u8 *src_mac_addr, u8 *dst_mac_addr, u32 period_msec, GetCmdType cmdType)
59 : WifiCommand(iface, 0), mIndex(index), mIpPkt(ip_packet),
60 mIpPktLen(ip_packet_len), mSrcMacAddr(src_mac_addr), mDstMacAddr(dst_mac_addr),
61 mPeriodMsec(period_msec), mType(cmdType)
62 { }
63
64 // constructor for stop sending
65 MKeepAliveCommand(wifi_interface_handle iface, u8 index, GetCmdType cmdType)
66 : WifiCommand(iface, 0), mIndex(index), mType(cmdType)
0fe9bfaf
PG
67 {
68 mIpPkt = NULL;
69 mIpPktLen = 0;
70 mSrcMacAddr = NULL;
71 mDstMacAddr = NULL;
72 mPeriodMsec = 0;
73 }
3c0c6ab1
PG
74
75 int createRequest(WifiRequest &request) {
76 int result;
77
78 switch (mType) {
79 case START_MKEEP_ALIVE:
80 {
81 result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_START_KEEP_ALIVE_OFFLOAD);
82 if (result != WIFI_SUCCESS) {
83 ALOGE("Failed to create start keep alive request; result = %d", result);
84 return result;
85 }
86
87 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
88
89 result = request.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID, mIndex);
90 if (result < 0) {
91 ALOGE("Failed to put id request; result = %d", result);
92 return result;
93 }
94
95 result = request.put_u16(MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN, mIpPktLen);
96 if (result < 0) {
97 ALOGE("Failed to put ip pkt len request; result = %d", result);
98 return result;
99 }
100
101 result = request.put(MKEEP_ALIVE_ATTRIBUTE_IP_PKT, (u8*)mIpPkt, mIpPktLen);
102 if (result < 0) {
103 ALOGE("Failed to put ip pkt request; result = %d", result);
104 return result;
105 }
106
107 result = request.put_addr(MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR, mSrcMacAddr);
108 if (result < 0) {
109 ALOGE("Failed to put src mac address request; result = %d", result);
110 return result;
111 }
112
113 result = request.put_addr(MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR, mDstMacAddr);
114 if (result < 0) {
115 ALOGE("Failed to put dst mac address request; result = %d", result);
116 return result;
117 }
118
119 result = request.put_u32(MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC, mPeriodMsec);
120 if (result < 0) {
121 ALOGE("Failed to put period request; result = %d", result);
122 return result;
123 }
124
125 request.attr_end(data);
126 break;
127 }
128
129 case STOP_MKEEP_ALIVE:
130 {
131 result = request.create(GOOGLE_OUI, SLSI_NL80211_VENDOR_SUBCMD_STOP_KEEP_ALIVE_OFFLOAD);
132 if (result != WIFI_SUCCESS) {
133 ALOGE("Failed to create stop keep alive request; result = %d", result);
134 return result;
135 }
136
137 nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
138
139 result = request.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID, mIndex);
140 if (result < 0) {
141 ALOGE("Failed to put id request; result = %d", result);
142 return result;
143 }
144
145 request.attr_end(data);
146 break;
147 }
148
149 default:
150 ALOGE("Unknown wifi keep alive command");
151 result = WIFI_ERROR_UNKNOWN;
152 }
153 return result;
154 }
155
156 int start() {
157 ALOGD("Start mkeep_alive command");
158 WifiRequest request(familyId(), ifaceId());
159 int result = createRequest(request);
160 if (result != WIFI_SUCCESS) {
161 ALOGE("Failed to create keep alive request; result = %d", result);
162 return result;
163 }
164
165 result = requestResponse(request);
166 if (result != WIFI_SUCCESS) {
167 ALOGE("Failed to register keep alive response; result = %d", result);
168 }
169 return result;
170 }
171
172 virtual int handleResponse(WifiEvent& reply) {
3c0c6ab1
PG
173
174 if (reply.get_cmd() != NL80211_CMD_VENDOR) {
175 ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
176 return NL_SKIP;
177 }
178
179 switch (mType) {
180 case START_MKEEP_ALIVE:
181 case STOP_MKEEP_ALIVE:
182 break;
183
184 default:
185 ALOGW("Unknown mkeep_alive command");
186 }
187 return NL_OK;
188 }
189
190 virtual int handleEvent(WifiEvent& event) {
191 /* NO events! */
192 return NL_SKIP;
193 }
194};
195
263043fb 196
3c0c6ab1
PG
197/* API to send specified mkeep_alive packet periodically. */
198wifi_error wifi_start_sending_offloaded_packet(wifi_request_id index, wifi_interface_handle iface,
f0567d5c
MG
199 u16 ether_type, u8 *ip_packet, u16 ip_packet_len, u8 *src_mac_addr, u8 *dst_mac_addr,
200 u32 period_msec)
3c0c6ab1 201{
263043fb
MG
202 if ((index > 0 && index <= N_AVAIL_ID) && (ip_packet != NULL) && (src_mac_addr != NULL)
203 && (dst_mac_addr != NULL) && (period_msec > 0)
204 && (ip_packet_len <= MKEEP_ALIVE_IP_PKT_MAX)) {
205 MKeepAliveCommand *cmd = new MKeepAliveCommand(iface, index, ip_packet, ip_packet_len,
206 src_mac_addr, dst_mac_addr, period_msec, START_MKEEP_ALIVE);
207 wifi_error result = (wifi_error)cmd->start();
208 delete cmd;
209 return result;
210 } else {
211 ALOGE("Invalid mkeep_alive parameters");
212 return WIFI_ERROR_INVALID_ARGS;
213 }
3c0c6ab1
PG
214}
215
216/* API to stop sending mkeep_alive packet. */
217wifi_error wifi_stop_sending_offloaded_packet(wifi_request_id index, wifi_interface_handle iface)
218{
263043fb
MG
219 if (index > 0 && index <= N_AVAIL_ID) {
220 MKeepAliveCommand *cmd = new MKeepAliveCommand(iface, index, STOP_MKEEP_ALIVE);
221 wifi_error result = (wifi_error)cmd->start();
222 delete cmd;
223 return result;
224 } else {
225 ALOGE("Invalid mkeep_alive parameters");
226 return WIFI_ERROR_INVALID_ARGS;
227 }
3c0c6ab1 228}