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 if (g_stop == 1 || client == NULL || client->device == NULL ||
43 client->device->service == NULL) {
44 pthread_rwlock_unlock(&g_rwLock);
45 HDF_LOGE("%{public}s: client or client.device or service is nullptr", __func__);
46 return HDF_FAILURE;
47 }
48 struct HdfWpaInterfaceHost *wpainterfaceHost = CONTAINER_OF(
49 client->device->service, struct HdfWpaInterfaceHost, ioService);
50 if (wpainterfaceHost == NULL || wpainterfaceHost->service == NULL || wpainterfaceHost->stubObject == NULL) {
51 HDF_LOGE("%{public}s: invalid service obj", __func__);
52 pthread_rwlock_unlock(&g_rwLock);
53 return HDF_ERR_INVALID_OBJECT;
54 }
55
56 struct HdfRemoteService *stubObj = *wpainterfaceHost->stubObject;
57 if (stubObj == NULL || stubObj->dispatcher == NULL || stubObj->dispatcher->Dispatch == NULL) {
58 pthread_rwlock_unlock(&g_rwLock);
59 return HDF_ERR_INVALID_OBJECT;
60 }
61 int ret = stubObj->dispatcher->Dispatch((struct HdfRemoteService *)stubObj->target, cmdId, data, reply);
62 pthread_rwlock_unlock(&g_rwLock);
63 return ret;
64 }
65
HdfWpaInterfaceDriverInit(struct HdfDeviceObject *deviceObject)66 static int HdfWpaInterfaceDriverInit(struct HdfDeviceObject *deviceObject)
67 {
68 int32_t ret;
69 HDF_LOGI("HdfWpaInterfaceDriverInit enter.");
70 struct HdfWpaStubData *stubData = HdfWpaStubDriver();
71 DListHeadInit(&stubData->remoteListHead);
72 ret = OsalMutexInit(&stubData->mutex);
73 if (ret != HDF_SUCCESS) {
74 HDF_LOGE("%{public}s: Mutex init failed, error code: %{public}d", __func__, ret);
75 return HDF_FAILURE;
76 }
77 return HDF_SUCCESS;
78 }
79
HdfWpaInterfaceDriverBind(struct HdfDeviceObject *deviceObject)80 static int HdfWpaInterfaceDriverBind(struct HdfDeviceObject *deviceObject)
81 {
82 HDF_LOGI("HdfWpaInterfaceDriverBind enter.");
83
84 int32_t ret = HdfDeviceObjectSetInterfaceDesc(deviceObject, IWPAINTERFACE_INTERFACE_DESC);
85 if (ret != HDF_SUCCESS) {
86 HDF_LOGE("failed to set interface descriptor of device object");
87 return ret;
88 }
89
90 struct HdfWpaInterfaceHost *wpainterfaceHost =
91 (struct HdfWpaInterfaceHost *)OsalMemAlloc(sizeof(struct HdfWpaInterfaceHost));
92 if (wpainterfaceHost == NULL) {
93 HDF_LOGE("HdfWpaInterfaceDriverBind OsalMemAlloc HdfWpaInterfaceHost failed!");
94 return HDF_FAILURE;
95 }
96
97 struct IWpaInterface *serviceImpl = IWpaInterfaceGet(true);
98 struct HdfRemoteService **stubObj = StubCollectorGetOrNewObject(IWPAINTERFACE_INTERFACE_DESC, serviceImpl);
99 if (stubObj == NULL) {
100 OsalMemFree(wpainterfaceHost);
101 wpainterfaceHost = NULL;
102 IWpaInterfaceRelease(serviceImpl, true);
103 return HDF_FAILURE;
104 }
105
106 wpainterfaceHost->ioService.Dispatch = WpaInterfaceDriverDispatch;
107 wpainterfaceHost->ioService.Open = NULL;
108 wpainterfaceHost->ioService.Release = NULL;
109 wpainterfaceHost->service = serviceImpl;
110 wpainterfaceHost->stubObject = stubObj;
111 deviceObject->service = &wpainterfaceHost->ioService;
112 return HDF_SUCCESS;
113 }
114
HdfWpaInterfaceDriverRelease(struct HdfDeviceObject *deviceObject)115 static void HdfWpaInterfaceDriverRelease(struct HdfDeviceObject *deviceObject)
116 {
117 HDF_LOGI("HdfWpaInterfaceDriverRelease enter.");
118 struct HdfWpaRemoteNode *pos = NULL;
119 struct HdfWpaRemoteNode *tmp = NULL;
120 pthread_rwlock_wrlock(&g_rwLock);
121 if (deviceObject == NULL) {
122 HDF_LOGI("deviceObject is NULL.");
123 pthread_rwlock_unlock(&g_rwLock);
124 return;
125 }
126 g_stop = 1;
127 struct HdfWpaStubData *stubData = HdfWpaStubDriver();
128 if (stubData == NULL) {
129 HDF_LOGE("%{public}s: stubData is NUll!", __func__);
130 pthread_rwlock_unlock(&g_rwLock);
131 return;
132 }
133
134 DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &stubData->remoteListHead, struct HdfWpaRemoteNode, node) {
135 DListRemove(&(pos->node));
136 OsalMemFree(pos);
137 pos = NULL;
138 }
139 OsalMutexDestroy(&stubData->mutex);
140 struct HdfWpaInterfaceHost *wpainterfaceHost = CONTAINER_OF(
141 deviceObject->service, struct HdfWpaInterfaceHost, ioService);
142 StubCollectorRemoveObject(IWPAINTERFACE_INTERFACE_DESC, wpainterfaceHost->service);
143 if (wpainterfaceHost->stubObject != NULL) {
144 *(wpainterfaceHost->stubObject) = NULL;
145 }
146 wpainterfaceHost->stubObject = NULL;
147 IWpaInterfaceRelease(wpainterfaceHost->service, true);
148 OsalMemFree(wpainterfaceHost);
149 wpainterfaceHost = NULL;
150 if (deviceObject->service != NULL) {
151 deviceObject->service = NULL;
152 }
153 pthread_rwlock_unlock(&g_rwLock);
154 }
155
156 struct HdfDriverEntry g_wpainterfaceDriverEntry = {
157 .moduleVersion = 1,
158 .moduleName = "wpa_service",
159 .Bind = HdfWpaInterfaceDriverBind,
160 .Init = HdfWpaInterfaceDriverInit,
161 .Release = HdfWpaInterfaceDriverRelease,
162 };
163
164 HDF_INIT(g_wpainterfaceDriverEntry);
165