1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci#include <fcntl.h>
16094332d3Sopenharmony_ci#include <hdf_base.h>
17094332d3Sopenharmony_ci#include <hdf_device_desc.h>
18094332d3Sopenharmony_ci#include <hdf_device_object.h>
19094332d3Sopenharmony_ci#include <hdf_log.h>
20094332d3Sopenharmony_ci#include <sys/ioctl.h>
21094332d3Sopenharmony_ci#include <sys/stat.h>
22094332d3Sopenharmony_ci#include <osal_mem.h>
23094332d3Sopenharmony_ci#include <stub_collector.h>
24094332d3Sopenharmony_ci#include "v1_3/iwlan_interface.h"
25094332d3Sopenharmony_ci#include "wlan_impl.h"
26094332d3Sopenharmony_ci
27094332d3Sopenharmony_cistruct HdfWlanInterfaceHost {
28094332d3Sopenharmony_ci    struct IDeviceIoService ioService;
29094332d3Sopenharmony_ci    struct IWlanInterface *service;
30094332d3Sopenharmony_ci    struct HdfRemoteService **stubObject;
31094332d3Sopenharmony_ci};
32094332d3Sopenharmony_ci
33094332d3Sopenharmony_cistatic int32_t WlanInterfaceDriverDispatch(
34094332d3Sopenharmony_ci    struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
35094332d3Sopenharmony_ci{
36094332d3Sopenharmony_ci    struct HdfWlanInterfaceHost *wlaninterfaceHost = CONTAINER_OF(
37094332d3Sopenharmony_ci        client->device->service, struct HdfWlanInterfaceHost, ioService);
38094332d3Sopenharmony_ci    if (wlaninterfaceHost->service == NULL || wlaninterfaceHost->stubObject == NULL) {
39094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: invalid service obj", __func__);
40094332d3Sopenharmony_ci        return HDF_ERR_INVALID_OBJECT;
41094332d3Sopenharmony_ci    }
42094332d3Sopenharmony_ci
43094332d3Sopenharmony_ci    struct HdfRemoteService *stubObj = *wlaninterfaceHost->stubObject;
44094332d3Sopenharmony_ci    if (stubObj == NULL || stubObj->dispatcher == NULL || stubObj->dispatcher->Dispatch == NULL) {
45094332d3Sopenharmony_ci        return HDF_ERR_INVALID_OBJECT;
46094332d3Sopenharmony_ci    }
47094332d3Sopenharmony_ci
48094332d3Sopenharmony_ci    return stubObj->dispatcher->Dispatch((struct HdfRemoteService *)stubObj->target, cmdId, data, reply);
49094332d3Sopenharmony_ci}
50094332d3Sopenharmony_ci
51094332d3Sopenharmony_cistatic int HdfWlanInterfaceDriverInit(struct HdfDeviceObject *deviceObject)
52094332d3Sopenharmony_ci{
53094332d3Sopenharmony_ci    int32_t ret;
54094332d3Sopenharmony_ci    HDF_LOGI("HdfWlanInterfaceDriverInit enter.");
55094332d3Sopenharmony_ci    struct HdfWlanStubData *stubData = HdfStubDriver();
56094332d3Sopenharmony_ci    DListHeadInit(&stubData->remoteListHead);
57094332d3Sopenharmony_ci    ret = OsalMutexInit(&stubData->mutex);
58094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
59094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: Mutex init failed, error code: %{public}d", __func__, ret);
60094332d3Sopenharmony_ci        return HDF_FAILURE;
61094332d3Sopenharmony_ci    }
62094332d3Sopenharmony_ci    if (WlanInterfaceServiceInit() != HDF_SUCCESS) {
63094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: wlan interface service init failed!", __func__);
64094332d3Sopenharmony_ci        OsalMutexDestroy(&stubData->mutex);
65094332d3Sopenharmony_ci        return HDF_FAILURE;
66094332d3Sopenharmony_ci    }
67094332d3Sopenharmony_ci    return HDF_SUCCESS;
68094332d3Sopenharmony_ci}
69094332d3Sopenharmony_ci
70094332d3Sopenharmony_cistatic int HdfWlanInterfaceDriverBind(struct HdfDeviceObject *deviceObject)
71094332d3Sopenharmony_ci{
72094332d3Sopenharmony_ci    HDF_LOGI("HdfWlanInterfaceDriverBind enter.");
73094332d3Sopenharmony_ci
74094332d3Sopenharmony_ci    int32_t ret = HdfDeviceObjectSetInterfaceDesc(deviceObject, IWLANINTERFACE_INTERFACE_DESC);
75094332d3Sopenharmony_ci    if (ret != HDF_SUCCESS) {
76094332d3Sopenharmony_ci        HDF_LOGE("failed to set interface descriptor of device object");
77094332d3Sopenharmony_ci        return ret;
78094332d3Sopenharmony_ci    }
79094332d3Sopenharmony_ci
80094332d3Sopenharmony_ci    struct HdfWlanInterfaceHost *wlaninterfaceHost =
81094332d3Sopenharmony_ci        (struct HdfWlanInterfaceHost *)OsalMemAlloc(sizeof(struct HdfWlanInterfaceHost));
82094332d3Sopenharmony_ci    if (wlaninterfaceHost == NULL) {
83094332d3Sopenharmony_ci        HDF_LOGE("HdfWlanInterfaceDriverBind OsalMemAlloc HdfWlanInterfaceHost failed!");
84094332d3Sopenharmony_ci        return HDF_FAILURE;
85094332d3Sopenharmony_ci    }
86094332d3Sopenharmony_ci
87094332d3Sopenharmony_ci    struct IWlanInterface *serviceImpl = IWlanInterfaceGet(true);
88094332d3Sopenharmony_ci    struct HdfRemoteService **stubObj = StubCollectorGetOrNewObject(IWLANINTERFACE_INTERFACE_DESC, serviceImpl);
89094332d3Sopenharmony_ci    if (stubObj == NULL) {
90094332d3Sopenharmony_ci        OsalMemFree(wlaninterfaceHost);
91094332d3Sopenharmony_ci        IWlanInterfaceRelease(serviceImpl, true);
92094332d3Sopenharmony_ci        return HDF_FAILURE;
93094332d3Sopenharmony_ci    }
94094332d3Sopenharmony_ci
95094332d3Sopenharmony_ci    wlaninterfaceHost->ioService.Dispatch = WlanInterfaceDriverDispatch;
96094332d3Sopenharmony_ci    wlaninterfaceHost->ioService.Open = NULL;
97094332d3Sopenharmony_ci    wlaninterfaceHost->ioService.Release = NULL;
98094332d3Sopenharmony_ci    wlaninterfaceHost->service = serviceImpl;
99094332d3Sopenharmony_ci    wlaninterfaceHost->stubObject = stubObj;
100094332d3Sopenharmony_ci    deviceObject->service = &wlaninterfaceHost->ioService;
101094332d3Sopenharmony_ci    return HDF_SUCCESS;
102094332d3Sopenharmony_ci}
103094332d3Sopenharmony_ci
104094332d3Sopenharmony_cistatic void HdfWlanInterfaceDriverRelease(struct HdfDeviceObject *deviceObject)
105094332d3Sopenharmony_ci{
106094332d3Sopenharmony_ci    HDF_LOGI("HdfWlanInterfaceDriverRelease enter.");
107094332d3Sopenharmony_ci    struct HdfWlanRemoteNode *pos = NULL;
108094332d3Sopenharmony_ci    struct HdfWlanRemoteNode *tmp = NULL;
109094332d3Sopenharmony_ci    struct HdfWlanStubData *stubData = HdfStubDriver();
110094332d3Sopenharmony_ci    if (stubData == NULL) {
111094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: stubData is NUll!", __func__);
112094332d3Sopenharmony_ci        return;
113094332d3Sopenharmony_ci    }
114094332d3Sopenharmony_ci
115094332d3Sopenharmony_ci    DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &stubData->remoteListHead, struct HdfWlanRemoteNode, node) {
116094332d3Sopenharmony_ci        DListRemove(&(pos->node));
117094332d3Sopenharmony_ci        OsalMemFree(pos);
118094332d3Sopenharmony_ci    }
119094332d3Sopenharmony_ci    OsalMutexDestroy(&stubData->mutex);
120094332d3Sopenharmony_ci    struct HdfWlanInterfaceHost *wlaninterfaceHost = CONTAINER_OF(
121094332d3Sopenharmony_ci        deviceObject->service, struct HdfWlanInterfaceHost, ioService);
122094332d3Sopenharmony_ci    StubCollectorRemoveObject(IWLANINTERFACE_INTERFACE_DESC, wlaninterfaceHost->service);
123094332d3Sopenharmony_ci    IWlanInterfaceRelease(wlaninterfaceHost->service, true);
124094332d3Sopenharmony_ci    OsalMemFree(wlaninterfaceHost);
125094332d3Sopenharmony_ci}
126094332d3Sopenharmony_ci
127094332d3Sopenharmony_cistruct HdfDriverEntry g_wlaninterfaceDriverEntry = {
128094332d3Sopenharmony_ci    .moduleVersion = 1,
129094332d3Sopenharmony_ci    .moduleName = "wlan_service",
130094332d3Sopenharmony_ci    .Bind = HdfWlanInterfaceDriverBind,
131094332d3Sopenharmony_ci    .Init = HdfWlanInterfaceDriverInit,
132094332d3Sopenharmony_ci    .Release = HdfWlanInterfaceDriverRelease,
133094332d3Sopenharmony_ci};
134094332d3Sopenharmony_ci
135094332d3Sopenharmony_ciHDF_INIT(g_wlaninterfaceDriverEntry);