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
;
68 ALOGI("Successfully added event handler %p:%p for command %d at %d",
69 arg
, func
, cmd
, info
->num_event_cb
);
71 result
= WIFI_SUCCESS
;
74 pthread_mutex_unlock(&info
->cb_lock
);
78 wifi_error
wifi_register_vendor_handler(wifi_handle handle
,
79 uint32_t id
, int subcmd
, nl_recvmsg_msg_cb_t func
, void *arg
)
81 hal_info
*info
= (hal_info
*)handle
;
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
);
88 wifi_error result
= WIFI_ERROR_OUT_OF_MEMORY
;
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
);
100 result
= WIFI_SUCCESS
;
103 pthread_mutex_unlock(&info
->cb_lock
);
107 void wifi_unregister_handler(wifi_handle handle
, int cmd
)
109 hal_info
*info
= (hal_info
*)handle
;
111 if (cmd
== NL80211_CMD_VENDOR
) {
112 ALOGE("Must use wifi_unregister_vendor_handler to remove vendor handlers");
116 pthread_mutex_lock(&info
->cb_lock
);
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
);
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
--;
130 pthread_mutex_unlock(&info
->cb_lock
);
133 void wifi_unregister_vendor_handler(wifi_handle handle
, uint32_t id
, int subcmd
)
135 hal_info
*info
= (hal_info
*)handle
;
137 pthread_mutex_lock(&info
->cb_lock
);
139 for (int i
= 0; i
< info
->num_event_cb
; i
++) {
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
--;
153 pthread_mutex_unlock(&info
->cb_lock
);
157 wifi_error
wifi_register_cmd(wifi_handle handle
, int id
, WifiCommand
*cmd
)
159 hal_info
*info
= (hal_info
*)handle
;
161 ALOGD("registering command %d", id
);
163 wifi_error result
= WIFI_ERROR_OUT_OF_MEMORY
;
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
);
170 result
= WIFI_SUCCESS
;
176 WifiCommand
*wifi_unregister_cmd(wifi_handle handle
, int id
)
178 hal_info
*info
= (hal_info
*)handle
;
180 ALOGD("un-registering command %d", id
);
182 WifiCommand
*cmd
= NULL
;
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
));
189 ALOGI("Successfully removed command %d: %p from %d", id
, cmd
, i
);
197 WifiCommand
*wifi_get_cmd(wifi_handle handle
, int id
)
199 hal_info
*info
= (hal_info
*)handle
;
201 WifiCommand
*cmd
= NULL
;
203 for (int i
= 0; i
< info
->num_cmd
; i
++) {
204 if (info
->cmd
[i
].id
== id
) {
205 cmd
= info
->cmd
[i
].cmd
;
213 void wifi_unregister_cmd(wifi_handle handle
, WifiCommand
*cmd
)
215 hal_info
*info
= (hal_info
*)handle
;
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
));
222 ALOGI("Successfully removed command %d: %p from %d", id
, cmd
, i
);
228 wifi_error
wifi_cancel_cmd(wifi_request_id id
, wifi_interface_handle iface
)
230 wifi_handle handle
= getWifiHandle(iface
);
232 WifiCommand
*cmd
= wifi_unregister_cmd(handle
, id
);
233 ALOGD("Cancel WifiCommand = %p", cmd
);
240 return WIFI_ERROR_INVALID_ARGS
;