[7872] wlbt : [Katmai] HAL Changes for ePNO Implementation.
[GitHub/LineageOS/android_hardware_samsung_slsi_scsc_wifibt_wifi_hal.git] / common.cpp
CommitLineData
7753f181 1
f425b4a8
PG
2#include <stdint.h>
3#include <fcntl.h>
4#include <sys/socket.h>
5#include <netlink/genl/genl.h>
6#include <netlink/genl/family.h>
7#include <netlink/genl/ctrl.h>
8#include <linux/rtnetlink.h>
9#include <netpacket/packet.h>
10#include <linux/filter.h>
11#include <linux/errqueue.h>
12
13#include <linux/pkt_sched.h>
7753f181 14#include <netlink/object-api.h>
f425b4a8
PG
15#include <netlink/netlink.h>
16#include <netlink/socket.h>
7753f181
DD
17#include <netlink/handlers.h>
18
19#include "wifi_hal.h"
20#include "common.h"
f425b4a8 21#include "cpp_bindings.h"
7753f181
DD
22
23interface_info *getIfaceInfo(wifi_interface_handle handle)
24{
25 return (interface_info *)handle;
26}
27
28wifi_handle getWifiHandle(wifi_interface_handle handle)
29{
30 return getIfaceInfo(handle)->handle;
31}
32
33hal_info *getHalInfo(wifi_handle handle)
34{
35 return (hal_info *)handle;
36}
37
38hal_info *getHalInfo(wifi_interface_handle handle)
39{
40 return getHalInfo(getWifiHandle(handle));
41}
42
43wifi_handle getWifiHandle(hal_info *info)
44{
45 return (wifi_handle)info;
46}
47
48wifi_interface_handle getIfaceHandle(interface_info *info)
49{
50 return (wifi_interface_handle)info;
51}
52
53wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_t func, void *arg)
54{
55 hal_info *info = (hal_info *)handle;
56
57 /* TODO: check for multiple handlers? */
58 pthread_mutex_lock(&info->cb_lock);
59
60 wifi_error result = WIFI_ERROR_OUT_OF_MEMORY;
61
62 if (info->num_event_cb < info->alloc_event_cb) {
63 info->event_cb[info->num_event_cb].nl_cmd = cmd;
64 info->event_cb[info->num_event_cb].vendor_id = 0;
65 info->event_cb[info->num_event_cb].vendor_subcmd = 0;
66 info->event_cb[info->num_event_cb].cb_func = func;
67 info->event_cb[info->num_event_cb].cb_arg = arg;
68 ALOGI("Successfully added event handler %p:%p for command %d at %d",
69 arg, func, cmd, info->num_event_cb);
70 info->num_event_cb++;
71 result = WIFI_SUCCESS;
72 }
73
74 pthread_mutex_unlock(&info->cb_lock);
75 return result;
76}
77
78wifi_error wifi_register_vendor_handler(wifi_handle handle,
79 uint32_t id, int subcmd, nl_recvmsg_msg_cb_t func, void *arg)
80{
81 hal_info *info = (hal_info *)handle;
82
83//ALOGD("GSCAN register handle wifi_register_vendor_handler %p", handle);
84 /* TODO: check for multiple handlers? */
85 pthread_mutex_lock(&info->cb_lock);
86 ALOGI("Added event handler %p", info);
87
88 wifi_error result = WIFI_ERROR_OUT_OF_MEMORY;
89
90 // ALOGD("register_vendor_handler: handle = %p", handle);
91 if (info->num_event_cb < info->alloc_event_cb) {
92 info->event_cb[info->num_event_cb].nl_cmd = NL80211_CMD_VENDOR;
93 info->event_cb[info->num_event_cb].vendor_id = id;
94 info->event_cb[info->num_event_cb].vendor_subcmd = subcmd;
95 info->event_cb[info->num_event_cb].cb_func = func;
96 info->event_cb[info->num_event_cb].cb_arg = arg;
97 ALOGI("Added event handler %p:%p for vendor 0x%0x and subcmd 0x%0x at %d",
98 arg, func, id, subcmd, info->num_event_cb);
99 info->num_event_cb++;
100 result = WIFI_SUCCESS;
101 }
102
103 pthread_mutex_unlock(&info->cb_lock);
104 return result;
105}
106
107void wifi_unregister_handler(wifi_handle handle, int cmd)
108{
109 hal_info *info = (hal_info *)handle;
110
111 if (cmd == NL80211_CMD_VENDOR) {
112 ALOGE("Must use wifi_unregister_vendor_handler to remove vendor handlers");
113 return;
114 }
115
116 pthread_mutex_lock(&info->cb_lock);
117
118 for (int i = 0; i < info->num_event_cb; i++) {
119 if (info->event_cb[i].nl_cmd == cmd) {
120 ALOGI("Successfully removed event handler %p:%p for cmd = 0x%0x from %d",
121 info->event_cb[i].cb_arg, info->event_cb[i].cb_func, cmd, i);
122
123 memmove(&info->event_cb[i], &info->event_cb[i+1],
124 (info->num_event_cb - i - 1) * sizeof(cb_info));
125 info->num_event_cb--;
126 break;
127 }
128 }
129
130 pthread_mutex_unlock(&info->cb_lock);
131}
132
133void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd)
134{
135 hal_info *info = (hal_info *)handle;
136
137 pthread_mutex_lock(&info->cb_lock);
138
139 for (int i = 0; i < info->num_event_cb; i++) {
140
141 if (info->event_cb[i].nl_cmd == NL80211_CMD_VENDOR
142 && info->event_cb[i].vendor_id == id
143 && info->event_cb[i].vendor_subcmd == subcmd) {
144 ALOGI("Successfully removed event handler %p:%p for vendor 0x%0x, subcmd 0x%0x from %d",
145 info->event_cb[i].cb_arg, info->event_cb[i].cb_func, id, subcmd, i);
146 memmove(&info->event_cb[i], &info->event_cb[i+1],
147 (info->num_event_cb - i - 1) * sizeof(cb_info));
148 info->num_event_cb--;
149 break;
150 }
151 }
152
153 pthread_mutex_unlock(&info->cb_lock);
154}
155
156
157wifi_error wifi_register_cmd(wifi_handle handle, int id, WifiCommand *cmd)
158{
159 hal_info *info = (hal_info *)handle;
160
161 ALOGD("registering command %d", id);
162
163 wifi_error result = WIFI_ERROR_OUT_OF_MEMORY;
164
165 if (info->num_cmd < info->alloc_cmd) {
166 info->cmd[info->num_cmd].id = id;
167 info->cmd[info->num_cmd].cmd = cmd;
168 ALOGI("Successfully added command %d: %p at %d", id, cmd, info->num_cmd);
169 info->num_cmd++;
170 result = WIFI_SUCCESS;
171 }
172
173 return result;
174}
175
176WifiCommand *wifi_unregister_cmd(wifi_handle handle, int id)
177{
178 hal_info *info = (hal_info *)handle;
179
180 ALOGD("un-registering command %d", id);
181
182 WifiCommand *cmd = NULL;
183
184 for (int i = 0; i < info->num_cmd; i++) {
185 if (info->cmd[i].id == id) {
186 cmd = info->cmd[i].cmd;
187 memmove(&info->cmd[i], &info->cmd[i+1], (info->num_cmd - i) * sizeof(cmd_info));
188 info->num_cmd--;
189 ALOGI("Successfully removed command %d: %p from %d", id, cmd, i);
190 break;
191 }
192 }
193
194 return cmd;
195}
196
197WifiCommand *wifi_get_cmd(wifi_handle handle, int id)
198{
199 hal_info *info = (hal_info *)handle;
200
201 WifiCommand *cmd = NULL;
202
203 for (int i = 0; i < info->num_cmd; i++) {
204 if (info->cmd[i].id == id) {
205 cmd = info->cmd[i].cmd;
206 break;
207 }
208 }
209
210 return cmd;
211}
212
213void wifi_unregister_cmd(wifi_handle handle, WifiCommand *cmd)
214{
215 hal_info *info = (hal_info *)handle;
216
217 for (int i = 0; i < info->num_cmd; i++) {
218 if (info->cmd[i].cmd == cmd) {
219 int id = info->cmd[i].id;
220 memmove(&info->cmd[i], &info->cmd[i+1], (info->num_cmd - i) * sizeof(cmd_info));
221 info->num_cmd--;
222 ALOGI("Successfully removed command %d: %p from %d", id, cmd, i);
223 break;
224 }
225 }
226}
f425b4a8
PG
227
228wifi_error wifi_cancel_cmd(wifi_request_id id, wifi_interface_handle iface)
229{
230 wifi_handle handle = getWifiHandle(iface);
231
232 WifiCommand *cmd = wifi_unregister_cmd(handle, id);
233 ALOGD("Cancel WifiCommand = %p", cmd);
234 if (cmd) {
235 cmd->cancel();
236 cmd->releaseRef();
237 return WIFI_SUCCESS;
238 }
239
240 return WIFI_ERROR_INVALID_ARGS;
241}