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