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