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