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
26extern "C" {
27#endif
28#endif
29
30#ifndef EOK
31#define EOK 0
32#endif
33
34#define MAX_CALL_BACK_COUNT 10
35static struct CallbackEvent *g_callbackEventMap[MAX_CALL_BACK_COUNT] = {NULL};
36static struct Hid2dEvent *g_hid2dEventMap[MAX_CALL_BACK_COUNT] = {NULL};
37static pthread_mutex_t g_callbackMutex;
38static pthread_mutex_t g_hid2dEventMutex;
39
40int32_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
53void DeinitEventcallbackMutex(void)
54{
55    pthread_mutex_destroy(&g_callbackMutex);
56    pthread_mutex_destroy(&g_hid2dEventMutex);
57}
58
59void 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
83int32_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
130void 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
155void 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
175int32_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
224void 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
248void 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
267void 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
282int32_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