• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
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 <cstdint>
18 #include <fcntl.h>
19 #include <sys/socket.h>
20 #include <netlink/genl/genl.h>
21 #include <netlink/genl/family.h>
22 #include <netlink/genl/ctrl.h>
23 #include <linux/rtnetlink.h>
24 #include <netpacket/packet.h>
25 #include <linux/filter.h>
26 #include <linux/errqueue.h>
27 
28 #include <linux/pkt_sched.h>
29 #include <netlink/object-api.h>
30 #include <netlink/netlink.h>
31 #include <netlink/socket.h>
32 #include <netlink/handlers.h>
33 
34 #include "wifi_hal.h"
35 #include "common.h"
36 #include "cpp_bindings.h"
37 #include "securec.h"
38 
39 #define MAX_CMD_SIZE 64
40 
41 /* test mode flag for halutil only */
42 bool g_halutilMode = false;
43 static std::shared_mutex g_rwMutex;
44 
ReadLockData()45 std::shared_lock<std::shared_mutex> ReadLockData()
46 {
47     return std::shared_lock<std::shared_mutex>{g_rwMutex};
48 }
49 
WriteLock()50 std::unique_lock<std::shared_mutex> WriteLock()
51 {
52     return std::unique_lock<std::shared_mutex>{g_rwMutex};
53 }
GetIfaceInfo(wifiInterfaceHandle handle)54 InterfaceInfo *GetIfaceInfo(wifiInterfaceHandle handle)
55 {
56     return (InterfaceInfo *)handle;
57 }
58 
GetWifiHandle(wifiInterfaceHandle handle)59 wifiHandle GetWifiHandle(wifiInterfaceHandle handle)
60 {
61     InterfaceInfo *info = GetIfaceInfo(handle);
62     if (info != nullptr) {
63         return GetIfaceInfo(handle)->handle;
64     }
65     return nullptr;
66 }
67 
GetHalInfo(wifiHandle handle)68 HalInfo *GetHalInfo(wifiHandle handle)
69 {
70     return (HalInfo *)handle;
71 }
72 
GetHalInfo(wifiInterfaceHandle handle)73 HalInfo *GetHalInfo(wifiInterfaceHandle handle)
74 {
75     return GetHalInfo(GetWifiHandle(handle));
76 }
77 
GetWifiHandle(HalInfo * info)78 wifiHandle GetWifiHandle(HalInfo *info)
79 {
80     return (wifiHandle)info;
81 }
82 
GetIfaceHandle(InterfaceInfo * info)83 wifiInterfaceHandle GetIfaceHandle(InterfaceInfo *info)
84 {
85     return (wifiInterfaceHandle)info;
86 }
87 
WifiRegisterHandler(wifiHandle handle,int cmd,nl_recvmsg_msg_cb_t func,void * arg)88 WifiError WifiRegisterHandler(wifiHandle handle, int cmd, nl_recvmsg_msg_cb_t func, void *arg)
89 {
90     HalInfo *info = (HalInfo *)handle;
91     pthread_mutex_lock(&info->cbLock);
92     WifiError result = HAL_OUT_OF_MEMORY;
93 
94     if (info->numEventCb < info->allocEventCb) {
95         info->eventCb[info->numEventCb].nlCmd  = cmd;
96         info->eventCb[info->numEventCb].vendorId  = 0;
97         info->eventCb[info->numEventCb].vendorSubcmd  = 0;
98         info->eventCb[info->numEventCb].cbFunc = func;
99         info->eventCb[info->numEventCb].cbArg  = arg;
100         HDF_LOGD("Successfully added event handler for command %{public}d at %{public}d", cmd, info->numEventCb);
101         info->numEventCb++;
102         result = HAL_SUCCESS;
103     }
104 
105     pthread_mutex_unlock(&info->cbLock);
106     return result;
107 }
108 
WifiRegisterVendorHandler(wifiHandle handle,uint32_t id,int subcmd,nl_recvmsg_msg_cb_t func,void * arg)109 WifiError WifiRegisterVendorHandler(wifiHandle handle,
110     uint32_t id, int subcmd, nl_recvmsg_msg_cb_t func, void *arg)
111 {
112     HalInfo *info = (HalInfo *)handle;
113     pthread_mutex_lock(&info->cbLock);
114     WifiError result = HAL_OUT_OF_MEMORY;
115     if (info->numEventCb < info->allocEventCb) {
116         int i = 0;
117         bool isUpdate = false;
118         for (i = 0; i < info->numEventCb; i++) {
119             if ((info->eventCb[i].nlCmd == NL80211_CMD_VENDOR) &&
120                 (info->eventCb[i].vendorId == id) &&
121                 (info->eventCb[i].vendorSubcmd == subcmd)) {
122                 isUpdate = true;
123                 break;
124             }
125         }
126         if (isUpdate) {
127             info->eventCb[i].cbFunc = func;
128             info->eventCb[i].cbArg = arg;
129         } else {
130             info->eventCb[info->numEventCb].nlCmd  = NL80211_CMD_VENDOR;
131             info->eventCb[info->numEventCb].vendorId  = id;
132             info->eventCb[info->numEventCb].vendorSubcmd  = subcmd;
133             info->eventCb[info->numEventCb].cbFunc = func;
134             info->eventCb[info->numEventCb].cbArg  = arg;
135             info->numEventCb++;
136         }
137         HDF_LOGI("%{public}s ""event handler for vendor 0x%{public}0x and subcmd 0x%{public}0x at %{public}d",
138             isUpdate ? "Updated" : "Added", id, subcmd, info->numEventCb);
139         result = HAL_SUCCESS;
140     }
141 
142     pthread_mutex_unlock(&info->cbLock);
143     return result;
144 }
145 
WifiUnregisterHandler(wifiHandle handle,int cmd)146 void WifiUnregisterHandler(wifiHandle handle, int cmd)
147 {
148     HalInfo *info = (HalInfo *)handle;
149 
150     if (cmd == NL80211_CMD_VENDOR) {
151         HDF_LOGE("Must use WifiUnregisterVendorHandler to remove vendor handlers");
152         return;
153     }
154 
155     pthread_mutex_lock(&info->cbLock);
156 
157     for (int i = 0; i < info->numEventCb; i++) {
158         if (info->eventCb[i].nlCmd == cmd) {
159             HDF_LOGD("Successfully removed event handler for cmd = 0x%{public}0x from %{public}d",
160                      cmd, i);
161 
162             if (memmove_s(&info->eventCb[i], (info->numEventCb - i) * sizeof(CbInfo), &info->eventCb[i + 1],
163                 (info->numEventCb - i - 1) * sizeof(CbInfo)) != EOK) {
164                 break;
165             }
166             info->numEventCb--;
167             break;
168         }
169     }
170 
171     pthread_mutex_unlock(&info->cbLock);
172 }
173 
WifiUnregisterVendorHandlerWithoutLock(wifiHandle handle,uint32_t id,int subcmd)174 void WifiUnregisterVendorHandlerWithoutLock(wifiHandle handle, uint32_t id, int subcmd)
175 {
176     HalInfo *info = (HalInfo *)handle;
177 
178     for (int i = 0; i < info->numEventCb; i++) {
179         if (info->eventCb[i].nlCmd == NL80211_CMD_VENDOR &&
180             info->eventCb[i].vendorId == id &&
181             info->eventCb[i].vendorSubcmd == subcmd) {
182             HDF_LOGI("Successfully removed event handler for vendor 0x%{public}0x,"
183                 "subcmd 0x%{public}0x from %{public}d", id, subcmd, i);
184             if (memmove_s(&info->eventCb[i], (info->numEventCb - i) * sizeof(CbInfo), &info->eventCb[i + 1],
185                 (info->numEventCb - i - 1) * sizeof(CbInfo)) != EOK) {
186                 break;
187             }
188             break;
189         }
190     }
191 }
192 
WifiUnregisterVendorHandler(wifiHandle handle,uint32_t id,int subcmd)193 void WifiUnregisterVendorHandler(wifiHandle handle, uint32_t id, int subcmd)
194 {
195     HalInfo *info = (HalInfo *)handle;
196 
197     pthread_mutex_lock(&info->cbLock);
198     WifiUnregisterVendorHandlerWithoutLock(handle, id, subcmd);
199     pthread_mutex_unlock(&info->cbLock);
200 }
201 
202 
WifiRegisterCmd(wifiHandle handle,int id,WifiCommand * cmd)203 WifiError WifiRegisterCmd(wifiHandle handle, int id, WifiCommand *cmd)
204 {
205     HalInfo *info = (HalInfo *)handle;
206 
207     HDF_LOGD("registering command %{public}d", id);
208 
209     WifiError result = HAL_OUT_OF_MEMORY;
210     if (info == nullptr) {
211         HDF_LOGE("wifi info is null");
212         return result;
213     }
214     if (info->numCmd < info->allocCmd) {
215         info->cmd[info->numCmd].id   = id;
216         info->cmd[info->numCmd].cmd  = cmd;
217         HDF_LOGD("Successfully added command %{public}d: at %{public}d", id, info->numCmd);
218         info->numCmd++;
219         result = HAL_SUCCESS;
220     } else {
221         HDF_LOGE("Failed to add command %{public}d: at %{public}d, reached MAX limit %{public}d",
222             id, info->numCmd, info->allocCmd);
223     }
224 
225     return result;
226 }
227 
WifiUnregisterCmd(wifiHandle handle,int id)228 WifiCommand *WifiUnregisterCmd(wifiHandle handle, int id)
229 {
230     HalInfo *info = (HalInfo *)handle;
231 
232     HDF_LOGD("un-registering command %{public}d", id);
233 
234     WifiCommand *cmd = nullptr;
235 
236     if (info->numCmd > MAX_CMD_SIZE) {
237         HDF_LOGE("invilid cmd size");
238         return cmd;
239     }
240     for (int i = 0; i < info->numCmd; i++) {
241         if (info->cmd[i].id == id) {
242             cmd = info->cmd[i].cmd;
243             if (memmove_s(&info->cmd[i], (info->numCmd - i) * sizeof(CmdInfo), &info->cmd[i + 1],
244                 (info->numCmd - i - 1) * sizeof(CmdInfo)) != EOK) {
245                 break;
246             }
247             info->numCmd--;
248             HDF_LOGD("Successfully removed command %{public}d: from %{public}d", id, i);
249             break;
250         }
251     }
252 
253     if (!cmd) {
254         HDF_LOGI("Failed to remove command %{public}d", id);
255     }
256 
257     return cmd;
258 }
259 
WifiUnregisterCmd(wifiHandle handle,WifiCommand * cmd)260 void WifiUnregisterCmd(wifiHandle handle, WifiCommand *cmd)
261 {
262     HalInfo *info = (HalInfo *)handle;
263 
264     for (int i = 0; i < info->numCmd; i++) {
265         if (info->cmd[i].cmd == cmd) {
266             int id = info->cmd[i].id;
267             if (memmove_s(&info->cmd[i], (info->numCmd - i) * sizeof(CmdInfo), &info->cmd[i + 1],
268                 (info->numCmd - i - 1) * sizeof(CmdInfo)) != EOK) {
269                 break;
270             }
271             info->numCmd--;
272             HDF_LOGD("Successfully removed command %{public}d: from %{public}d", id, i);
273             break;
274         }
275     }
276 }
277 
SetHautilMode(bool halutilMode)278 void SetHautilMode(bool halutilMode)
279 {
280     g_halutilMode = halutilMode;
281 }
GetGHalutilMode()282 bool GetGHalutilMode()
283 {
284     return g_halutilMode;
285 }
286