1 /*
2 * Copyright (c) 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 #include <fcntl.h>
16 #include <hdf_base.h>
17 #include <hdf_device_desc.h>
18 #include <hdf_device_object.h>
19 #include <hdf_log.h>
20 #include <sys/ioctl.h>
21 #include <sys/stat.h>
22 #include <osal_mem.h>
23 #include <stub_collector.h>
24 #include "v1_0/iwpa_interface.h"
25 #include "wpa_impl.h"
26
27 struct HdfWpaInterfaceHost {
28 struct IDeviceIoService ioService;
29 struct IWpaInterface *service;
30 struct HdfRemoteService **stubObject;
31 };
32
WpaInterfaceDriverDispatch(struct HdfDeviceIoClient * client,int cmdId,struct HdfSBuf * data,struct HdfSBuf * reply)33 static int32_t WpaInterfaceDriverDispatch(
34 struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
35 {
36 HDF_LOGI("WpaInterfaceDriverDispatch enter.");
37 struct HdfWpaInterfaceHost *wpainterfaceHost = CONTAINER_OF(
38 client->device->service, struct HdfWpaInterfaceHost, ioService);
39 if (wpainterfaceHost->service == NULL || wpainterfaceHost->stubObject == NULL) {
40 HDF_LOGE("%{public}s: invalid service obj", __func__);
41 return HDF_ERR_INVALID_OBJECT;
42 }
43
44 struct HdfRemoteService *stubObj = *wpainterfaceHost->stubObject;
45 if (stubObj == NULL || stubObj->dispatcher == NULL || stubObj->dispatcher->Dispatch == NULL) {
46 return HDF_ERR_INVALID_OBJECT;
47 }
48
49 return stubObj->dispatcher->Dispatch((struct HdfRemoteService *)stubObj->target, cmdId, data, reply);
50 }
51
HdfWpaInterfaceDriverInit(struct HdfDeviceObject * deviceObject)52 static int HdfWpaInterfaceDriverInit(struct HdfDeviceObject *deviceObject)
53 {
54 int32_t ret;
55 HDF_LOGI("HdfWpaInterfaceDriverInit enter.");
56 struct HdfWpaStubData *stubData = HdfWpaStubDriver();
57 DListHeadInit(&stubData->remoteListHead);
58 ret = OsalMutexInit(&stubData->mutex);
59 if (ret != HDF_SUCCESS) {
60 HDF_LOGE("%{public}s: Mutex init failed, error code: %{public}d", __func__, ret);
61 return HDF_FAILURE;
62 }
63 return HDF_SUCCESS;
64 }
65
HdfWpaInterfaceDriverBind(struct HdfDeviceObject * deviceObject)66 static int HdfWpaInterfaceDriverBind(struct HdfDeviceObject *deviceObject)
67 {
68 HDF_LOGI("HdfWpaInterfaceDriverBind enter.");
69
70 int32_t ret = HdfDeviceObjectSetInterfaceDesc(deviceObject, IWPAINTERFACE_INTERFACE_DESC);
71 if (ret != HDF_SUCCESS) {
72 HDF_LOGE("failed to set interface descriptor of device object");
73 return ret;
74 }
75
76 struct HdfWpaInterfaceHost *wpainterfaceHost =
77 (struct HdfWpaInterfaceHost *)OsalMemAlloc(sizeof(struct HdfWpaInterfaceHost));
78 if (wpainterfaceHost == NULL) {
79 HDF_LOGE("HdfWpaInterfaceDriverBind OsalMemAlloc HdfWpaInterfaceHost failed!");
80 return HDF_FAILURE;
81 }
82
83 struct IWpaInterface *serviceImpl = IWpaInterfaceGet(true);
84 struct HdfRemoteService **stubObj = StubCollectorGetOrNewObject(IWPAINTERFACE_INTERFACE_DESC, serviceImpl);
85 if (stubObj == NULL) {
86 OsalMemFree(wpainterfaceHost);
87 IWpaInterfaceRelease(serviceImpl, true);
88 return HDF_FAILURE;
89 }
90
91 wpainterfaceHost->ioService.Dispatch = WpaInterfaceDriverDispatch;
92 wpainterfaceHost->ioService.Open = NULL;
93 wpainterfaceHost->ioService.Release = NULL;
94 wpainterfaceHost->service = serviceImpl;
95 wpainterfaceHost->stubObject = stubObj;
96 deviceObject->service = &wpainterfaceHost->ioService;
97 return HDF_SUCCESS;
98 }
99
HdfWpaInterfaceDriverRelease(struct HdfDeviceObject * deviceObject)100 static void HdfWpaInterfaceDriverRelease(struct HdfDeviceObject *deviceObject)
101 {
102 HDF_LOGI("HdfWpaInterfaceDriverRelease enter.");
103 struct HdfWpaRemoteNode *pos = NULL;
104 struct HdfWpaRemoteNode *tmp = NULL;
105 struct HdfWpaStubData *stubData = HdfWpaStubDriver();
106 if (stubData == NULL) {
107 HDF_LOGE("%{public}s: stubData is NUll!", __func__);
108 return;
109 }
110
111 DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &stubData->remoteListHead, struct HdfWpaRemoteNode, node) {
112 DListRemove(&(pos->node));
113 OsalMemFree(pos);
114 }
115 OsalMutexDestroy(&stubData->mutex);
116 struct HdfWpaInterfaceHost *wpainterfaceHost = CONTAINER_OF(
117 deviceObject->service, struct HdfWpaInterfaceHost, ioService);
118 StubCollectorRemoveObject(IWPAINTERFACE_INTERFACE_DESC, wpainterfaceHost->service);
119 IWpaInterfaceRelease(wpainterfaceHost->service, true);
120 OsalMemFree(wpainterfaceHost);
121 }
122
123 struct HdfDriverEntry g_wpainterfaceDriverEntry = {
124 .moduleVersion = 1,
125 .moduleName = "wpa_service",
126 .Bind = HdfWpaInterfaceDriverBind,
127 .Init = HdfWpaInterfaceDriverInit,
128 .Release = HdfWpaInterfaceDriverRelease,
129 };
130
131 HDF_INIT(g_wpainterfaceDriverEntry);
132