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>
13 #include <linux/pkt_sched.h>
14 #include <netlink/object-api.h>
15 #include <netlink/netlink.h>
16 #include <netlink/socket.h>
17 #include <netlink/handlers.h>
21 #include "cpp_bindings.h"
23 interface_info
*getIfaceInfo(wifi_interface_handle handle
)
25 return (interface_info
*)handle
;
28 wifi_handle
getWifiHandle(wifi_interface_handle handle
)
30 return getIfaceInfo(handle
)->handle
;
33 hal_info
*getHalInfo(wifi_handle handle
)
35 return (hal_info
*)handle
;
38 hal_info
*getHalInfo(wifi_interface_handle handle
)
40 return getHalInfo(getWifiHandle(handle
));
43 wifi_handle
getWifiHandle(hal_info
*info
)
45 return (wifi_handle
)info
;
48 wifi_interface_handle
getIfaceHandle(interface_info
*info
)
50 return (wifi_interface_handle
)info
;
53 wifi_error
wifi_register_handler(wifi_handle handle
, int cmd
, nl_recvmsg_msg_cb_t func
, void *arg
)
55 hal_info
*info
= (hal_info
*)handle
;
57 /* TODO: check for multiple handlers? */
58 pthread_mutex_lock(&info
->cb_lock
);
60 wifi_error result
= WIFI_ERROR_OUT_OF_MEMORY
;
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
;
69 ALOGI("Successfully added event handler %p:%p for command %d at %d",
70 arg, func, cmd, info->num_event_cb);*/
72 result
= WIFI_SUCCESS
;
75 pthread_mutex_unlock(&info
->cb_lock
);
79 wifi_error
wifi_register_vendor_handler(wifi_handle handle
,
80 uint32_t id
, int subcmd
, nl_recvmsg_msg_cb_t func
, void *arg
)
82 hal_info
*info
= (hal_info
*)handle
;
84 //ALOGD("GSCAN register handle wifi_register_vendor_handler %p", handle);
85 /* TODO: check for multiple handlers? */
86 pthread_mutex_lock(&info
->cb_lock
);
87 //ALOGI("Added event handler %p", info);
89 wifi_error result
= WIFI_ERROR_OUT_OF_MEMORY
;
91 // ALOGD("register_vendor_handler: handle = %p", handle);
92 if (info
->num_event_cb
< info
->alloc_event_cb
) {
93 info
->event_cb
[info
->num_event_cb
].nl_cmd
= NL80211_CMD_VENDOR
;
94 info
->event_cb
[info
->num_event_cb
].vendor_id
= id
;
95 info
->event_cb
[info
->num_event_cb
].vendor_subcmd
= subcmd
;
96 info
->event_cb
[info
->num_event_cb
].cb_func
= func
;
97 info
->event_cb
[info
->num_event_cb
].cb_arg
= arg
;
99 ALOGI("Added event handler %p:%p for vendor 0x%0x and subcmd 0x%0x at %d",
100 arg, func, id, subcmd, info->num_event_cb);*/
101 info
->num_event_cb
++;
102 result
= WIFI_SUCCESS
;
105 pthread_mutex_unlock(&info
->cb_lock
);
109 void wifi_unregister_handler(wifi_handle handle
, int cmd
)
111 hal_info
*info
= (hal_info
*)handle
;
113 if (cmd
== NL80211_CMD_VENDOR
) {
114 ALOGE("Must use wifi_unregister_vendor_handler to remove vendor handlers");
118 pthread_mutex_lock(&info
->cb_lock
);
120 for (int i
= 0; i
< info
->num_event_cb
; i
++) {
121 if (info
->event_cb
[i
].nl_cmd
== cmd
) {
123 ALOGI("Successfully removed event handler %p:%p for cmd = 0x%0x from %d",
124 info->event_cb[i].cb_arg, info->event_cb[i].cb_func, cmd, i);*/
126 memmove(&info
->event_cb
[i
], &info
->event_cb
[i
+1],
127 (info
->num_event_cb
- i
- 1) * sizeof(cb_info
));
128 info
->num_event_cb
--;
133 pthread_mutex_unlock(&info
->cb_lock
);
136 void wifi_unregister_vendor_handler(wifi_handle handle
, uint32_t id
, int subcmd
)
138 hal_info
*info
= (hal_info
*)handle
;
140 pthread_mutex_lock(&info
->cb_lock
);
142 for (int i
= 0; i
< info
->num_event_cb
; i
++) {
144 if (info
->event_cb
[i
].nl_cmd
== NL80211_CMD_VENDOR
145 && info
->event_cb
[i
].vendor_id
== id
146 && info
->event_cb
[i
].vendor_subcmd
== subcmd
) {
148 ALOGI("Successfully removed event handler %p:%p for vendor 0x%0x, subcmd 0x%0x from %d",
149 info->event_cb[i].cb_arg, info->event_cb[i].cb_func, id, subcmd, i);*/
150 memmove(&info
->event_cb
[i
], &info
->event_cb
[i
+1],
151 (info
->num_event_cb
- i
- 1) * sizeof(cb_info
));
152 info
->num_event_cb
--;
157 pthread_mutex_unlock(&info
->cb_lock
);
161 wifi_error
wifi_register_cmd(wifi_handle handle
, int id
, WifiCommand
*cmd
)
163 hal_info
*info
= (hal_info
*)handle
;
165 //ALOGD("registering command %d", id);
167 wifi_error result
= WIFI_ERROR_OUT_OF_MEMORY
;
169 if (info
->num_cmd
< info
->alloc_cmd
) {
170 info
->cmd
[info
->num_cmd
].id
= id
;
171 info
->cmd
[info
->num_cmd
].cmd
= cmd
;
172 //ALOGI("Successfully added command %d: %p at %d", id, cmd, info->num_cmd);
174 result
= WIFI_SUCCESS
;
180 WifiCommand
*wifi_unregister_cmd(wifi_handle handle
, int id
)
182 hal_info
*info
= (hal_info
*)handle
;
184 //ALOGD("un-registering command %d", id);
186 WifiCommand
*cmd
= NULL
;
188 for (int i
= 0; i
< info
->num_cmd
; i
++) {
189 if (info
->cmd
[i
].id
== id
) {
190 cmd
= info
->cmd
[i
].cmd
;
191 memmove(&info
->cmd
[i
], &info
->cmd
[i
+1], (info
->num_cmd
- i
) * sizeof(cmd_info
));
193 //ALOGI("Successfully removed command %d: %p from %d", id, cmd, i);
201 WifiCommand
*wifi_get_cmd(wifi_handle handle
, int id
)
203 hal_info
*info
= (hal_info
*)handle
;
205 WifiCommand
*cmd
= NULL
;
207 for (int i
= 0; i
< info
->num_cmd
; i
++) {
208 if (info
->cmd
[i
].id
== id
) {
209 cmd
= info
->cmd
[i
].cmd
;
217 void wifi_unregister_cmd(wifi_handle handle
, WifiCommand
*cmd
)
219 hal_info
*info
= (hal_info
*)handle
;
221 for (int i
= 0; i
< info
->num_cmd
; i
++) {
222 if (info
->cmd
[i
].cmd
== cmd
) {
223 memmove(&info
->cmd
[i
], &info
->cmd
[i
+1], (info
->num_cmd
- i
) * sizeof(cmd_info
));
225 //ALOGI("Successfully removed command %d: %p from %d", id, cmd, i);
231 wifi_error
wifi_cancel_cmd(wifi_request_id id
, wifi_interface_handle iface
)
233 wifi_handle handle
= getWifiHandle(iface
);
235 WifiCommand
*cmd
= wifi_unregister_cmd(handle
, id
);
236 //ALOGD("Cancel WifiCommand = %p", cmd);
243 return WIFI_ERROR_INVALID_ARGS
;