1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <string.h>
17 #include <stdlib.h>
18 #include <osal_mem.h>
19 #include <pthread.h>
20 #include "wifi_common_cmd.h"
21 #include "hdf_log.h"
22 #include "securec.h"
23 
24 #ifdef __cplusplus
25 #if __cplusplus
26 extern "C" {
27 #endif
28 #endif
29 
30 #ifndef EOK
31 #define EOK 0
32 #endif
33 
34 #define MAX_CALL_BACK_COUNT 10
35 static struct CallbackEvent *g_callbackEventMap[MAX_CALL_BACK_COUNT] = {NULL};
36 static struct Hid2dEvent *g_hid2dEventMap[MAX_CALL_BACK_COUNT] = {NULL};
37 static pthread_mutex_t g_callbackMutex;
38 static pthread_mutex_t g_hid2dEventMutex;
39 
InitEventcallbackMutex(void)40 int32_t InitEventcallbackMutex(void)
41 {
42     if (pthread_mutex_init(&g_callbackMutex, NULL) != RET_CODE_SUCCESS) {
43         HDF_LOGE("%s: init g_callbackMutex failed.", __FUNCTION__);
44         return RET_CODE_FAILURE;
45     }
46     if (pthread_mutex_init(&g_hid2dEventMutex, NULL) != RET_CODE_SUCCESS) {
47         HDF_LOGE("%s: init g_hid2dEventMutex failed.", __FUNCTION__);
48         return RET_CODE_FAILURE;
49     }
50     return RET_CODE_SUCCESS;
51 }
52 
DeinitEventcallbackMutex(void)53 void DeinitEventcallbackMutex(void)
54 {
55     pthread_mutex_destroy(&g_callbackMutex);
56     pthread_mutex_destroy(&g_hid2dEventMutex);
57 }
58 
WifiEventReport(const char * ifName,uint32_t event,void * data)59 void WifiEventReport(const char *ifName, uint32_t event, void *data)
60 {
61     HDF_LOGD("hal enter %{public}s", __FUNCTION__);
62     uint32_t i;
63     OnReceiveFunc callbackEventMap[MAX_CALL_BACK_COUNT] = {NULL};
64 
65     pthread_mutex_lock(&g_callbackMutex);
66     for (i = 0; i < MAX_CALL_BACK_COUNT; i++) {
67         if (g_callbackEventMap[i] != NULL && (strcmp(g_callbackEventMap[i]->ifName, ifName) == 0) &&
68             (((1 << event) & g_callbackEventMap[i]->eventType) != 0)) {
69             HDF_LOGD("send event=%{public}u, ifName=%{public}s, i=%{public}d", event, ifName, i);
70             callbackEventMap[i] = g_callbackEventMap[i]->onRecFunc;
71         }
72     }
73     pthread_mutex_unlock(&g_callbackMutex);
74     for (i = 0; i < MAX_CALL_BACK_COUNT; i++) {
75         if (callbackEventMap[i] != NULL) {
76             HDF_LOGD("callbackEventMap i:%{public}d vent=%{public}u, ifName=%{public}s", i,  event, ifName);
77             callbackEventMap[i](event, data, ifName);
78         }
79     }
80     HDF_LOGD("hal exit %{public}s", __FUNCTION__);
81 }
82 
WifiRegisterEventCallback(OnReceiveFunc onRecFunc,uint32_t eventType,const char * ifName)83 int32_t WifiRegisterEventCallback(OnReceiveFunc onRecFunc, uint32_t eventType, const char *ifName)
84 {
85     uint32_t i;
86     struct CallbackEvent *callbackEvent = NULL;
87     HDF_LOGI("hal enter %{public}s", __FUNCTION__);
88     if (onRecFunc == NULL || ifName == NULL) {
89         HDF_LOGE("%s: input parameter invalid, line: %d", __FUNCTION__, __LINE__);
90         return RET_CODE_INVALID_PARAM;
91     }
92     pthread_mutex_lock(&g_callbackMutex);
93     for (i = 0; i < MAX_CALL_BACK_COUNT; i++) {
94         if (g_callbackEventMap[i] != NULL && g_callbackEventMap[i]->eventType == eventType &&
95             (strcmp(g_callbackEventMap[i]->ifName, ifName) == 0) && g_callbackEventMap[i]->onRecFunc == onRecFunc) {
96             HDF_LOGI("i:%{public}d ifName:%{public}s the onRecFunc has been registered!", i, ifName);
97             pthread_mutex_unlock(&g_callbackMutex);
98             return RET_CODE_SUCCESS;
99         }
100     }
101     pthread_mutex_unlock(&g_callbackMutex);
102     callbackEvent = (struct CallbackEvent *)malloc(sizeof(struct CallbackEvent));
103     if (callbackEvent == NULL) {
104         HDF_LOGE("%{public}s fail: malloc fail!", __FUNCTION__);
105         return RET_CODE_FAILURE;
106     }
107     callbackEvent->eventType = eventType;
108     if (strcpy_s(callbackEvent->ifName, IFNAMSIZ, ifName) != RET_CODE_SUCCESS) {
109         free(callbackEvent);
110         HDF_LOGE("%{public}s: ifName strcpy_s fail", __FUNCTION__);
111         return RET_CODE_FAILURE;
112     }
113     callbackEvent->onRecFunc = onRecFunc;
114     pthread_mutex_lock(&g_callbackMutex);
115     for (i = 0; i < MAX_CALL_BACK_COUNT; i++) {
116         if (g_callbackEventMap[i] == NULL) {
117             g_callbackEventMap[i] = callbackEvent;
118             HDF_LOGI("g_callbackEventMap successful, i:%{public}u, ifName:%{public}s, eventType:%{public}u", i, ifName,
119                 eventType);
120             pthread_mutex_unlock(&g_callbackMutex);
121             return RET_CODE_SUCCESS;
122         }
123     }
124     pthread_mutex_unlock(&g_callbackMutex);
125     free(callbackEvent);
126     HDF_LOGI("hal exit %{public}s fail register onRecFunc num more than %{public}d", __FUNCTION__, MAX_CALL_BACK_COUNT);
127     return RET_CODE_FAILURE;
128 }
129 
WifiUnregisterEventCallback(OnReceiveFunc onRecFunc,uint32_t eventType,const char * ifName)130 void WifiUnregisterEventCallback(OnReceiveFunc onRecFunc, uint32_t eventType, const char *ifName)
131 {
132     uint32_t i;
133     HDF_LOGI("hal enter %{public}s", __FUNCTION__);
134     if (onRecFunc == NULL || ifName == NULL) {
135         HDF_LOGE("%s: input parameter invalid, line: %d", __FUNCTION__, __LINE__);
136         return;
137     }
138     pthread_mutex_lock(&g_callbackMutex);
139     for (i = 0; i < MAX_CALL_BACK_COUNT; i++) {
140         if (g_callbackEventMap[i] != NULL && g_callbackEventMap[i]->eventType == eventType &&
141             (strcmp(g_callbackEventMap[i]->ifName, ifName) == 0) && g_callbackEventMap[i]->onRecFunc == onRecFunc) {
142             g_callbackEventMap[i]->onRecFunc = NULL;
143             free(g_callbackEventMap[i]);
144             g_callbackEventMap[i] = NULL;
145             HDF_LOGI("%{public}s: g_callbackEventMap null, i:%{public}u, ifName:%{public}s, eventType:%{public}u",
146                 __FUNCTION__, i, ifName, eventType);
147             pthread_mutex_unlock(&g_callbackMutex);
148             return;
149         }
150     }
151     pthread_mutex_unlock(&g_callbackMutex);
152     HDF_LOGI("hal exit %{public}s", __FUNCTION__);
153 }
154 
Hid2dEventReport(const char * ifName,const uint8_t * msg,uint32_t msgLen)155 void Hid2dEventReport(const char *ifName, const uint8_t *msg, uint32_t msgLen)
156 {
157     uint32_t i;
158     Hid2dCallback hid2dEventMap[MAX_CALL_BACK_COUNT] = {NULL};
159 
160     pthread_mutex_lock(&g_hid2dEventMutex);
161     for (i = 0; i < MAX_CALL_BACK_COUNT; i++) {
162         if (g_hid2dEventMap[i] != NULL && (strcmp(g_hid2dEventMap[i]->ifName, ifName) == 0)) {
163             HDF_LOGI("%{public}s: Hid2dEventReport ifName = %s", __FUNCTION__, ifName);
164             hid2dEventMap[i] = g_hid2dEventMap[i]->func;
165         }
166     }
167     pthread_mutex_unlock(&g_hid2dEventMutex);
168     for (i = 0; i < MAX_CALL_BACK_COUNT; i++) {
169         if (hid2dEventMap[i] != NULL) {
170             hid2dEventMap[i](msg, msgLen);
171         }
172     }
173 }
174 
WifiRegisterHid2dCallback(Hid2dCallback func,const char * ifName)175 int32_t WifiRegisterHid2dCallback(Hid2dCallback func, const char *ifName)
176 {
177     struct Hid2dEvent *event = NULL;
178     uint32_t i;
179     HDF_LOGI("hal enter %{public}s", __FUNCTION__);
180     if (func == NULL || ifName == NULL) {
181         HDF_LOGE("%s: input parameter invalid, line: %d", __FUNCTION__, __LINE__);
182         return RET_CODE_INVALID_PARAM;
183     }
184     pthread_mutex_lock(&g_hid2dEventMutex);
185     for (i = 0; i < MAX_CALL_BACK_COUNT; i++) {
186         if (g_hid2dEventMap[i] != NULL && (strcmp(g_hid2dEventMap[i]->ifName, ifName) == 0) &&
187             g_hid2dEventMap[i]->func == func) {
188             HDF_LOGI("%{public}s: i:%{public}d ifName:%{public}s, the callback function has been registered!",
189                 __FUNCTION__, i, ifName);
190             pthread_mutex_unlock(&g_hid2dEventMutex);
191             return RET_CODE_SUCCESS;
192         }
193     }
194     pthread_mutex_unlock(&g_hid2dEventMutex);
195     event = (struct Hid2dEvent *)OsalMemCalloc(sizeof(struct Hid2dEvent));
196     if (event == NULL) {
197         HDF_LOGE("%s fail: OsalMemCalloc fail!", __FUNCTION__);
198         return RET_CODE_FAILURE;
199     }
200     do {
201         if (strcpy_s(event->ifName, IFNAMSIZ + 1, ifName) != RET_CODE_SUCCESS) {
202             HDF_LOGE("%s: ifName strcpy_s fail", __FUNCTION__);
203             break;
204         }
205         event->func = func;
206         pthread_mutex_lock(&g_hid2dEventMutex);
207         for (i = 0; i < MAX_CALL_BACK_COUNT; i++) {
208             if (g_hid2dEventMap[i] == NULL) {
209                 g_hid2dEventMap[i] = event;
210                 HDF_LOGI("%{public}s, g_hid2dEventMap i:%{public}d event!", __FUNCTION__, i);
211                 OsalMemFree(event);
212                 pthread_mutex_unlock(&g_hid2dEventMutex);
213                 return RET_CODE_SUCCESS;
214             }
215         }
216         pthread_mutex_unlock(&g_hid2dEventMutex);
217     } while (0);
218 
219     OsalMemFree(event);
220     HDF_LOGI("hal exit %{public}s fail: register onRecFunc num more than %d!", __FUNCTION__, MAX_CALL_BACK_COUNT);
221     return RET_CODE_FAILURE;
222 }
223 
WifiUnregisterHid2dCallback(Hid2dCallback func,const char * ifName)224 void WifiUnregisterHid2dCallback(Hid2dCallback func, const char *ifName)
225 {
226     uint32_t i;
227     HDF_LOGI("hal enter %{public}s", __FUNCTION__);
228     if (func == NULL || ifName == NULL) {
229         HDF_LOGE("%s: input parameter invalid, line: %d", __FUNCTION__, __LINE__);
230         return;
231     }
232     pthread_mutex_lock(&g_hid2dEventMutex);
233     for (i = 0; i < MAX_CALL_BACK_COUNT; i++) {
234         if (g_hid2dEventMap[i] != NULL && (strcmp(g_hid2dEventMap[i]->ifName, ifName) == 0) &&
235             g_hid2dEventMap[i]->func == func) {
236             g_hid2dEventMap[i]->func = NULL;
237             OsalMemFree(g_hid2dEventMap[i]);
238             g_hid2dEventMap[i] = NULL;
239             pthread_mutex_unlock(&g_hid2dEventMutex);
240             HDF_LOGI("%{public}s, g_hid2dEventMap i:%{public}d null!", __FUNCTION__, i);
241             return;
242         }
243     }
244     pthread_mutex_unlock(&g_hid2dEventMutex);
245     HDF_LOGI("hal exit %{public}s", __FUNCTION__);
246 }
247 
FreeScanResult(WifiScanResult * res)248 void FreeScanResult(WifiScanResult *res)
249 {
250     if (res == NULL) {
251         return;
252     }
253     if (res->bssid != NULL) {
254         OsalMemFree(res->bssid);
255         res->bssid = NULL;
256     }
257     if (res->ie != NULL) {
258         OsalMemFree(res->ie);
259         res->ie = NULL;
260     }
261     if (res->beaconIe != NULL) {
262         OsalMemFree(res->beaconIe);
263         res->beaconIe = NULL;
264     }
265 }
266 
FreeScanResults(WifiScanResults * res)267 void FreeScanResults(WifiScanResults *res)
268 {
269     HDF_LOGI("hal enter %{public}s", __FUNCTION__);
270     uint32_t i;
271     if (res == NULL) {
272         return;
273     }
274     for (i = 0; i < res->num; i++) {
275         FreeScanResult(&res->scanResult[i]);
276     }
277     OsalMemFree(res->scanResult);
278     res->scanResult = NULL;
279     HDF_LOGI("hal exit %{public}s", __FUNCTION__);
280 }
281 
InitScanResults(WifiScanResults * scanResults)282 int32_t InitScanResults(WifiScanResults *scanResults)
283 {
284     HDF_LOGI("hal enter %{public}s", __FUNCTION__);
285     if (scanResults == NULL) {
286         HDF_LOGE("%s: scanResults is NULL", __FUNCTION__);
287         return RET_CODE_FAILURE;
288     }
289     scanResults->scanResultCapacity = INIT_SCAN_RES_NUM;
290     scanResults->num = 0;
291     scanResults->scanResult = (WifiScanResult *)OsalMemCalloc(sizeof(WifiScanResult) * scanResults->scanResultCapacity);
292     if (scanResults->scanResult == NULL) {
293         HDF_LOGE("%s: scanResults->scanResult is NULL", __FUNCTION__);
294         return RET_CODE_NOMEM;
295     }
296     HDF_LOGI("hal exit %{public}s", __FUNCTION__);
297     return RET_CODE_SUCCESS;
298 }
299 #ifdef __cplusplus
300 #if __cplusplus
301 }
302 #endif
303 #endif
304