1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 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 <pthread.h> 22094332d3Sopenharmony_ci#include <sys/stat.h> 23094332d3Sopenharmony_ci#include <osal_mem.h> 24094332d3Sopenharmony_ci#include <stub_collector.h> 25094332d3Sopenharmony_ci#include "v1_1/iwpa_interface.h" 26094332d3Sopenharmony_ci#include "wpa_impl.h" 27094332d3Sopenharmony_ci 28094332d3Sopenharmony_cistruct HdfWpaInterfaceHost { 29094332d3Sopenharmony_ci struct IDeviceIoService ioService; 30094332d3Sopenharmony_ci struct IWpaInterface *service; 31094332d3Sopenharmony_ci struct HdfRemoteService **stubObject; 32094332d3Sopenharmony_ci}; 33094332d3Sopenharmony_ci 34094332d3Sopenharmony_cistatic pthread_rwlock_t g_rwLock = PTHREAD_RWLOCK_INITIALIZER; 35094332d3Sopenharmony_cistatic int g_stop = 0; 36094332d3Sopenharmony_ci 37094332d3Sopenharmony_cistatic int32_t WpaInterfaceDriverDispatch( 38094332d3Sopenharmony_ci struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply) 39094332d3Sopenharmony_ci{ 40094332d3Sopenharmony_ci HDF_LOGI("WpaInterfaceDriverDispatch enter."); 41094332d3Sopenharmony_ci pthread_rwlock_rdlock(&g_rwLock); 42094332d3Sopenharmony_ci if (g_stop == 1 || client == NULL || client->device == NULL || 43094332d3Sopenharmony_ci client->device->service == NULL) { 44094332d3Sopenharmony_ci pthread_rwlock_unlock(&g_rwLock); 45094332d3Sopenharmony_ci HDF_LOGE("%{public}s: client or client.device or service is nullptr", __func__); 46094332d3Sopenharmony_ci return HDF_FAILURE; 47094332d3Sopenharmony_ci } 48094332d3Sopenharmony_ci struct HdfWpaInterfaceHost *wpainterfaceHost = CONTAINER_OF( 49094332d3Sopenharmony_ci client->device->service, struct HdfWpaInterfaceHost, ioService); 50094332d3Sopenharmony_ci if (wpainterfaceHost == NULL || wpainterfaceHost->service == NULL || wpainterfaceHost->stubObject == NULL) { 51094332d3Sopenharmony_ci HDF_LOGE("%{public}s: invalid service obj", __func__); 52094332d3Sopenharmony_ci pthread_rwlock_unlock(&g_rwLock); 53094332d3Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 54094332d3Sopenharmony_ci } 55094332d3Sopenharmony_ci 56094332d3Sopenharmony_ci struct HdfRemoteService *stubObj = *wpainterfaceHost->stubObject; 57094332d3Sopenharmony_ci if (stubObj == NULL || stubObj->dispatcher == NULL || stubObj->dispatcher->Dispatch == NULL) { 58094332d3Sopenharmony_ci pthread_rwlock_unlock(&g_rwLock); 59094332d3Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 60094332d3Sopenharmony_ci } 61094332d3Sopenharmony_ci int ret = stubObj->dispatcher->Dispatch((struct HdfRemoteService *)stubObj->target, cmdId, data, reply); 62094332d3Sopenharmony_ci pthread_rwlock_unlock(&g_rwLock); 63094332d3Sopenharmony_ci return ret; 64094332d3Sopenharmony_ci} 65094332d3Sopenharmony_ci 66094332d3Sopenharmony_cistatic int HdfWpaInterfaceDriverInit(struct HdfDeviceObject *deviceObject) 67094332d3Sopenharmony_ci{ 68094332d3Sopenharmony_ci int32_t ret; 69094332d3Sopenharmony_ci HDF_LOGI("HdfWpaInterfaceDriverInit enter."); 70094332d3Sopenharmony_ci struct HdfWpaStubData *stubData = HdfWpaStubDriver(); 71094332d3Sopenharmony_ci DListHeadInit(&stubData->remoteListHead); 72094332d3Sopenharmony_ci ret = OsalMutexInit(&stubData->mutex); 73094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 74094332d3Sopenharmony_ci HDF_LOGE("%{public}s: Mutex init failed, error code: %{public}d", __func__, ret); 75094332d3Sopenharmony_ci return HDF_FAILURE; 76094332d3Sopenharmony_ci } 77094332d3Sopenharmony_ci return HDF_SUCCESS; 78094332d3Sopenharmony_ci} 79094332d3Sopenharmony_ci 80094332d3Sopenharmony_cistatic int HdfWpaInterfaceDriverBind(struct HdfDeviceObject *deviceObject) 81094332d3Sopenharmony_ci{ 82094332d3Sopenharmony_ci HDF_LOGI("HdfWpaInterfaceDriverBind enter."); 83094332d3Sopenharmony_ci 84094332d3Sopenharmony_ci int32_t ret = HdfDeviceObjectSetInterfaceDesc(deviceObject, IWPAINTERFACE_INTERFACE_DESC); 85094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 86094332d3Sopenharmony_ci HDF_LOGE("failed to set interface descriptor of device object"); 87094332d3Sopenharmony_ci return ret; 88094332d3Sopenharmony_ci } 89094332d3Sopenharmony_ci 90094332d3Sopenharmony_ci struct HdfWpaInterfaceHost *wpainterfaceHost = 91094332d3Sopenharmony_ci (struct HdfWpaInterfaceHost *)OsalMemAlloc(sizeof(struct HdfWpaInterfaceHost)); 92094332d3Sopenharmony_ci if (wpainterfaceHost == NULL) { 93094332d3Sopenharmony_ci HDF_LOGE("HdfWpaInterfaceDriverBind OsalMemAlloc HdfWpaInterfaceHost failed!"); 94094332d3Sopenharmony_ci return HDF_FAILURE; 95094332d3Sopenharmony_ci } 96094332d3Sopenharmony_ci 97094332d3Sopenharmony_ci struct IWpaInterface *serviceImpl = IWpaInterfaceGet(true); 98094332d3Sopenharmony_ci struct HdfRemoteService **stubObj = StubCollectorGetOrNewObject(IWPAINTERFACE_INTERFACE_DESC, serviceImpl); 99094332d3Sopenharmony_ci if (stubObj == NULL) { 100094332d3Sopenharmony_ci OsalMemFree(wpainterfaceHost); 101094332d3Sopenharmony_ci wpainterfaceHost = NULL; 102094332d3Sopenharmony_ci IWpaInterfaceRelease(serviceImpl, true); 103094332d3Sopenharmony_ci return HDF_FAILURE; 104094332d3Sopenharmony_ci } 105094332d3Sopenharmony_ci 106094332d3Sopenharmony_ci wpainterfaceHost->ioService.Dispatch = WpaInterfaceDriverDispatch; 107094332d3Sopenharmony_ci wpainterfaceHost->ioService.Open = NULL; 108094332d3Sopenharmony_ci wpainterfaceHost->ioService.Release = NULL; 109094332d3Sopenharmony_ci wpainterfaceHost->service = serviceImpl; 110094332d3Sopenharmony_ci wpainterfaceHost->stubObject = stubObj; 111094332d3Sopenharmony_ci deviceObject->service = &wpainterfaceHost->ioService; 112094332d3Sopenharmony_ci return HDF_SUCCESS; 113094332d3Sopenharmony_ci} 114094332d3Sopenharmony_ci 115094332d3Sopenharmony_cistatic void HdfWpaInterfaceDriverRelease(struct HdfDeviceObject *deviceObject) 116094332d3Sopenharmony_ci{ 117094332d3Sopenharmony_ci HDF_LOGI("HdfWpaInterfaceDriverRelease enter."); 118094332d3Sopenharmony_ci struct HdfWpaRemoteNode *pos = NULL; 119094332d3Sopenharmony_ci struct HdfWpaRemoteNode *tmp = NULL; 120094332d3Sopenharmony_ci pthread_rwlock_wrlock(&g_rwLock); 121094332d3Sopenharmony_ci if (deviceObject == NULL) { 122094332d3Sopenharmony_ci HDF_LOGI("deviceObject is NULL."); 123094332d3Sopenharmony_ci pthread_rwlock_unlock(&g_rwLock); 124094332d3Sopenharmony_ci return; 125094332d3Sopenharmony_ci } 126094332d3Sopenharmony_ci g_stop = 1; 127094332d3Sopenharmony_ci struct HdfWpaStubData *stubData = HdfWpaStubDriver(); 128094332d3Sopenharmony_ci if (stubData == NULL) { 129094332d3Sopenharmony_ci HDF_LOGE("%{public}s: stubData is NUll!", __func__); 130094332d3Sopenharmony_ci pthread_rwlock_unlock(&g_rwLock); 131094332d3Sopenharmony_ci return; 132094332d3Sopenharmony_ci } 133094332d3Sopenharmony_ci 134094332d3Sopenharmony_ci DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &stubData->remoteListHead, struct HdfWpaRemoteNode, node) { 135094332d3Sopenharmony_ci DListRemove(&(pos->node)); 136094332d3Sopenharmony_ci OsalMemFree(pos); 137094332d3Sopenharmony_ci pos = NULL; 138094332d3Sopenharmony_ci } 139094332d3Sopenharmony_ci OsalMutexDestroy(&stubData->mutex); 140094332d3Sopenharmony_ci struct HdfWpaInterfaceHost *wpainterfaceHost = CONTAINER_OF( 141094332d3Sopenharmony_ci deviceObject->service, struct HdfWpaInterfaceHost, ioService); 142094332d3Sopenharmony_ci StubCollectorRemoveObject(IWPAINTERFACE_INTERFACE_DESC, wpainterfaceHost->service); 143094332d3Sopenharmony_ci if (wpainterfaceHost->stubObject != NULL) { 144094332d3Sopenharmony_ci *(wpainterfaceHost->stubObject) = NULL; 145094332d3Sopenharmony_ci } 146094332d3Sopenharmony_ci wpainterfaceHost->stubObject = NULL; 147094332d3Sopenharmony_ci IWpaInterfaceRelease(wpainterfaceHost->service, true); 148094332d3Sopenharmony_ci OsalMemFree(wpainterfaceHost); 149094332d3Sopenharmony_ci wpainterfaceHost = NULL; 150094332d3Sopenharmony_ci if (deviceObject->service != NULL) { 151094332d3Sopenharmony_ci deviceObject->service = NULL; 152094332d3Sopenharmony_ci } 153094332d3Sopenharmony_ci pthread_rwlock_unlock(&g_rwLock); 154094332d3Sopenharmony_ci} 155094332d3Sopenharmony_ci 156094332d3Sopenharmony_cistruct HdfDriverEntry g_wpainterfaceDriverEntry = { 157094332d3Sopenharmony_ci .moduleVersion = 1, 158094332d3Sopenharmony_ci .moduleName = "wpa_service", 159094332d3Sopenharmony_ci .Bind = HdfWpaInterfaceDriverBind, 160094332d3Sopenharmony_ci .Init = HdfWpaInterfaceDriverInit, 161094332d3Sopenharmony_ci .Release = HdfWpaInterfaceDriverRelease, 162094332d3Sopenharmony_ci}; 163094332d3Sopenharmony_ci 164094332d3Sopenharmony_ciHDF_INIT(g_wpainterfaceDriverEntry); 165