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