• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <stdlib.h>
18 #include <linux/pkt_sched.h>
19 #include <netlink/object-api.h>
20 #include <netlink-types.h>
21 
22 #include "wifi_hal.h"
23 #include "common.h"
24 #include <netlink-types.h>
25 
getIfaceInfo(wifi_interface_handle handle)26 interface_info *getIfaceInfo(wifi_interface_handle handle)
27 {
28     return (interface_info *)handle;
29 }
30 
getWifiHandle(wifi_interface_handle handle)31 wifi_handle getWifiHandle(wifi_interface_handle handle)
32 {
33     return getIfaceInfo(handle)->handle;
34 }
35 
getHalInfo(wifi_handle handle)36 hal_info *getHalInfo(wifi_handle handle)
37 {
38     return (hal_info *)handle;
39 }
40 
getHalInfo(wifi_interface_handle handle)41 hal_info *getHalInfo(wifi_interface_handle handle)
42 {
43     return getHalInfo(getWifiHandle(handle));
44 }
45 
getWifiHandle(hal_info * info)46 wifi_handle getWifiHandle(hal_info *info)
47 {
48     return (wifi_handle)info;
49 }
50 
getIfaceHandle(interface_info * info)51 wifi_interface_handle getIfaceHandle(interface_info *info)
52 {
53     return (wifi_interface_handle)info;
54 }
55 
wifi_register_handler(wifi_handle handle,int cmd,nl_recvmsg_msg_cb_t func,void * arg)56 wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_t func, void *arg)
57 {
58     hal_info *info = (hal_info *)handle;
59 
60     /* TODO: check for multiple handlers? */
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         info->num_event_cb++;
69         ALOGI("Successfully added event handler %p for command %d", func, cmd);
70         return WIFI_SUCCESS;
71     } else {
72         return WIFI_ERROR_OUT_OF_MEMORY;
73     }
74 }
75 
wifi_register_vendor_handler(wifi_handle handle,uint32_t id,int subcmd,nl_recvmsg_msg_cb_t func,void * arg)76 wifi_error wifi_register_vendor_handler(wifi_handle handle,
77         uint32_t id, int subcmd, nl_recvmsg_msg_cb_t func, void *arg)
78 {
79     hal_info *info = (hal_info *)handle;
80 
81     for (int i = 0; i < info->num_event_cb; i++) {
82         if(info->event_cb[info->num_event_cb].vendor_id  == id &&
83            info->event_cb[info->num_event_cb].vendor_subcmd == subcmd)
84         {
85             info->event_cb[info->num_event_cb].cb_func = func;
86             info->event_cb[info->num_event_cb].cb_arg  = arg;
87             ALOGI("Updated event handler %p for vendor 0x%0x, subcmd 0x%0x"
88                 " and arg %p", func, id, subcmd, arg);
89             return WIFI_SUCCESS;
90         }
91     }
92 
93     if (info->num_event_cb < info->alloc_event_cb) {
94         info->event_cb[info->num_event_cb].nl_cmd  = NL80211_CMD_VENDOR;
95         info->event_cb[info->num_event_cb].vendor_id  = id;
96         info->event_cb[info->num_event_cb].vendor_subcmd  = subcmd;
97         info->event_cb[info->num_event_cb].cb_func = func;
98         info->event_cb[info->num_event_cb].cb_arg  = arg;
99         info->num_event_cb++;
100         ALOGI("Added event handler %p for vendor 0x%0x, subcmd 0x%0x and arg"
101             " %p", func, id, subcmd, arg);
102         return WIFI_SUCCESS;
103     } else {
104         return WIFI_ERROR_OUT_OF_MEMORY;
105     }
106 }
107 
wifi_unregister_handler(wifi_handle handle,int cmd)108 void wifi_unregister_handler(wifi_handle handle, int cmd)
109 {
110     hal_info *info = (hal_info *)handle;
111 
112     if (cmd == NL80211_CMD_VENDOR) {
113         ALOGE("Must use wifi_unregister_vendor_handler to remove vendor handlers");
114     }
115 
116     for (int i = 0; i < info->num_event_cb; i++) {
117         if (info->event_cb[i].nl_cmd == cmd) {
118             memmove(&info->event_cb[i], &info->event_cb[i+1],
119                 (info->num_event_cb - i) * sizeof(cb_info));
120             info->num_event_cb--;
121             ALOGI("Successfully removed event handler for command %d", cmd);
122             return;
123         }
124     }
125 }
126 
wifi_unregister_vendor_handler(wifi_handle handle,uint32_t id,int subcmd)127 void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd)
128 {
129     hal_info *info = (hal_info *)handle;
130 
131     for (int i = 0; i < info->num_event_cb; i++) {
132 
133         if (info->event_cb[i].nl_cmd == NL80211_CMD_VENDOR
134                 && info->event_cb[i].vendor_id == id
135                 && info->event_cb[i].vendor_subcmd == subcmd) {
136 
137             memmove(&info->event_cb[i], &info->event_cb[i+1],
138                 (info->num_event_cb - i) * sizeof(cb_info));
139             info->num_event_cb--;
140             ALOGI("Successfully removed event handler for vendor 0x%0x", id);
141             return;
142         }
143     }
144 }
145 
146 
wifi_register_cmd(wifi_handle handle,int id,WifiCommand * cmd)147 wifi_error wifi_register_cmd(wifi_handle handle, int id, WifiCommand *cmd)
148 {
149     hal_info *info = (hal_info *)handle;
150 
151     ALOGD("registering command %d", id);
152 
153     if (info->num_cmd < info->alloc_cmd) {
154         info->cmd[info->num_cmd].id   = id;
155         info->cmd[info->num_cmd].cmd  = cmd;
156         info->num_cmd++;
157         ALOGI("Successfully added command %d: %p", id, cmd);
158         return WIFI_SUCCESS;
159     } else {
160         return WIFI_ERROR_OUT_OF_MEMORY;
161     }
162 }
163 
wifi_unregister_cmd(wifi_handle handle,int id)164 WifiCommand *wifi_unregister_cmd(wifi_handle handle, int id)
165 {
166     hal_info *info = (hal_info *)handle;
167 
168     ALOGD("un-registering command %d", id);
169 
170     for (int i = 0; i < info->num_cmd; i++) {
171         if (info->cmd[i].id == id) {
172             WifiCommand *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", id, cmd);
176             return cmd;
177         }
178     }
179 
180     return NULL;
181 }
182 
wifi_unregister_cmd(wifi_handle handle,WifiCommand * cmd)183 void wifi_unregister_cmd(wifi_handle handle, WifiCommand *cmd)
184 {
185     hal_info *info = (hal_info *)handle;
186 
187     for (int i = 0; i < info->num_cmd; i++) {
188         if (info->cmd[i].cmd == cmd) {
189             int id = info->cmd[i].id;
190             memmove(&info->cmd[i], &info->cmd[i+1], (info->num_cmd - i) * sizeof(cmd_info));
191             info->num_cmd--;
192             ALOGI("Successfully removed command %d: %p", id, cmd);
193             return;
194         }
195     }
196 }
197 
198 #ifdef __cplusplus
199 extern "C"
200 {
201 #endif /* __cplusplus */
202 
hexdump(char * bytes,u16 len)203 void hexdump(char *bytes, u16 len)
204 {
205     int i=0;
206     ALOGI("******HexDump len:%d*********", len);
207     for (i = 0; ((i + 7) < len); i+=8) {
208         ALOGI("%02x %02x %02x %02x   %02x %02x %02x %02x",
209               bytes[i], bytes[i+1],
210               bytes[i+2], bytes[i+3],
211               bytes[i+4], bytes[i+5],
212               bytes[i+6], bytes[i+7]);
213     }
214     if ((len - i) >= 4) {
215         ALOGI("%02x %02x %02x %02x",
216               bytes[i], bytes[i+1],
217               bytes[i+2], bytes[i+3]);
218         i+=4;
219     }
220     for (;i < len;i++) {
221         ALOGI("%02x", bytes[i]);
222     }
223     ALOGI("******HexDump End***********");
224 }
225 
226 #ifdef __cplusplus
227 }
228 #endif /* __cplusplus */
229