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