1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2021-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 <sys/stat.h> 22094332d3Sopenharmony_ci#include <osal_mem.h> 23094332d3Sopenharmony_ci#include <stub_collector.h> 24094332d3Sopenharmony_ci#include "v1_3/iwlan_interface.h" 25094332d3Sopenharmony_ci#include "wlan_impl.h" 26094332d3Sopenharmony_ci 27094332d3Sopenharmony_cistruct HdfWlanInterfaceHost { 28094332d3Sopenharmony_ci struct IDeviceIoService ioService; 29094332d3Sopenharmony_ci struct IWlanInterface *service; 30094332d3Sopenharmony_ci struct HdfRemoteService **stubObject; 31094332d3Sopenharmony_ci}; 32094332d3Sopenharmony_ci 33094332d3Sopenharmony_cistatic int32_t WlanInterfaceDriverDispatch( 34094332d3Sopenharmony_ci struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply) 35094332d3Sopenharmony_ci{ 36094332d3Sopenharmony_ci struct HdfWlanInterfaceHost *wlaninterfaceHost = CONTAINER_OF( 37094332d3Sopenharmony_ci client->device->service, struct HdfWlanInterfaceHost, ioService); 38094332d3Sopenharmony_ci if (wlaninterfaceHost->service == NULL || wlaninterfaceHost->stubObject == NULL) { 39094332d3Sopenharmony_ci HDF_LOGE("%{public}s: invalid service obj", __func__); 40094332d3Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 41094332d3Sopenharmony_ci } 42094332d3Sopenharmony_ci 43094332d3Sopenharmony_ci struct HdfRemoteService *stubObj = *wlaninterfaceHost->stubObject; 44094332d3Sopenharmony_ci if (stubObj == NULL || stubObj->dispatcher == NULL || stubObj->dispatcher->Dispatch == NULL) { 45094332d3Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 46094332d3Sopenharmony_ci } 47094332d3Sopenharmony_ci 48094332d3Sopenharmony_ci return stubObj->dispatcher->Dispatch((struct HdfRemoteService *)stubObj->target, cmdId, data, reply); 49094332d3Sopenharmony_ci} 50094332d3Sopenharmony_ci 51094332d3Sopenharmony_cistatic int HdfWlanInterfaceDriverInit(struct HdfDeviceObject *deviceObject) 52094332d3Sopenharmony_ci{ 53094332d3Sopenharmony_ci int32_t ret; 54094332d3Sopenharmony_ci HDF_LOGI("HdfWlanInterfaceDriverInit enter."); 55094332d3Sopenharmony_ci struct HdfWlanStubData *stubData = HdfStubDriver(); 56094332d3Sopenharmony_ci DListHeadInit(&stubData->remoteListHead); 57094332d3Sopenharmony_ci ret = OsalMutexInit(&stubData->mutex); 58094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 59094332d3Sopenharmony_ci HDF_LOGE("%{public}s: Mutex init failed, error code: %{public}d", __func__, ret); 60094332d3Sopenharmony_ci return HDF_FAILURE; 61094332d3Sopenharmony_ci } 62094332d3Sopenharmony_ci if (WlanInterfaceServiceInit() != HDF_SUCCESS) { 63094332d3Sopenharmony_ci HDF_LOGE("%{public}s: wlan interface service init failed!", __func__); 64094332d3Sopenharmony_ci OsalMutexDestroy(&stubData->mutex); 65094332d3Sopenharmony_ci return HDF_FAILURE; 66094332d3Sopenharmony_ci } 67094332d3Sopenharmony_ci return HDF_SUCCESS; 68094332d3Sopenharmony_ci} 69094332d3Sopenharmony_ci 70094332d3Sopenharmony_cistatic int HdfWlanInterfaceDriverBind(struct HdfDeviceObject *deviceObject) 71094332d3Sopenharmony_ci{ 72094332d3Sopenharmony_ci HDF_LOGI("HdfWlanInterfaceDriverBind enter."); 73094332d3Sopenharmony_ci 74094332d3Sopenharmony_ci int32_t ret = HdfDeviceObjectSetInterfaceDesc(deviceObject, IWLANINTERFACE_INTERFACE_DESC); 75094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 76094332d3Sopenharmony_ci HDF_LOGE("failed to set interface descriptor of device object"); 77094332d3Sopenharmony_ci return ret; 78094332d3Sopenharmony_ci } 79094332d3Sopenharmony_ci 80094332d3Sopenharmony_ci struct HdfWlanInterfaceHost *wlaninterfaceHost = 81094332d3Sopenharmony_ci (struct HdfWlanInterfaceHost *)OsalMemAlloc(sizeof(struct HdfWlanInterfaceHost)); 82094332d3Sopenharmony_ci if (wlaninterfaceHost == NULL) { 83094332d3Sopenharmony_ci HDF_LOGE("HdfWlanInterfaceDriverBind OsalMemAlloc HdfWlanInterfaceHost failed!"); 84094332d3Sopenharmony_ci return HDF_FAILURE; 85094332d3Sopenharmony_ci } 86094332d3Sopenharmony_ci 87094332d3Sopenharmony_ci struct IWlanInterface *serviceImpl = IWlanInterfaceGet(true); 88094332d3Sopenharmony_ci struct HdfRemoteService **stubObj = StubCollectorGetOrNewObject(IWLANINTERFACE_INTERFACE_DESC, serviceImpl); 89094332d3Sopenharmony_ci if (stubObj == NULL) { 90094332d3Sopenharmony_ci OsalMemFree(wlaninterfaceHost); 91094332d3Sopenharmony_ci IWlanInterfaceRelease(serviceImpl, true); 92094332d3Sopenharmony_ci return HDF_FAILURE; 93094332d3Sopenharmony_ci } 94094332d3Sopenharmony_ci 95094332d3Sopenharmony_ci wlaninterfaceHost->ioService.Dispatch = WlanInterfaceDriverDispatch; 96094332d3Sopenharmony_ci wlaninterfaceHost->ioService.Open = NULL; 97094332d3Sopenharmony_ci wlaninterfaceHost->ioService.Release = NULL; 98094332d3Sopenharmony_ci wlaninterfaceHost->service = serviceImpl; 99094332d3Sopenharmony_ci wlaninterfaceHost->stubObject = stubObj; 100094332d3Sopenharmony_ci deviceObject->service = &wlaninterfaceHost->ioService; 101094332d3Sopenharmony_ci return HDF_SUCCESS; 102094332d3Sopenharmony_ci} 103094332d3Sopenharmony_ci 104094332d3Sopenharmony_cistatic void HdfWlanInterfaceDriverRelease(struct HdfDeviceObject *deviceObject) 105094332d3Sopenharmony_ci{ 106094332d3Sopenharmony_ci HDF_LOGI("HdfWlanInterfaceDriverRelease enter."); 107094332d3Sopenharmony_ci struct HdfWlanRemoteNode *pos = NULL; 108094332d3Sopenharmony_ci struct HdfWlanRemoteNode *tmp = NULL; 109094332d3Sopenharmony_ci struct HdfWlanStubData *stubData = HdfStubDriver(); 110094332d3Sopenharmony_ci if (stubData == NULL) { 111094332d3Sopenharmony_ci HDF_LOGE("%{public}s: stubData is NUll!", __func__); 112094332d3Sopenharmony_ci return; 113094332d3Sopenharmony_ci } 114094332d3Sopenharmony_ci 115094332d3Sopenharmony_ci DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &stubData->remoteListHead, struct HdfWlanRemoteNode, node) { 116094332d3Sopenharmony_ci DListRemove(&(pos->node)); 117094332d3Sopenharmony_ci OsalMemFree(pos); 118094332d3Sopenharmony_ci } 119094332d3Sopenharmony_ci OsalMutexDestroy(&stubData->mutex); 120094332d3Sopenharmony_ci struct HdfWlanInterfaceHost *wlaninterfaceHost = CONTAINER_OF( 121094332d3Sopenharmony_ci deviceObject->service, struct HdfWlanInterfaceHost, ioService); 122094332d3Sopenharmony_ci StubCollectorRemoveObject(IWLANINTERFACE_INTERFACE_DESC, wlaninterfaceHost->service); 123094332d3Sopenharmony_ci IWlanInterfaceRelease(wlaninterfaceHost->service, true); 124094332d3Sopenharmony_ci OsalMemFree(wlaninterfaceHost); 125094332d3Sopenharmony_ci} 126094332d3Sopenharmony_ci 127094332d3Sopenharmony_cistruct HdfDriverEntry g_wlaninterfaceDriverEntry = { 128094332d3Sopenharmony_ci .moduleVersion = 1, 129094332d3Sopenharmony_ci .moduleName = "wlan_service", 130094332d3Sopenharmony_ci .Bind = HdfWlanInterfaceDriverBind, 131094332d3Sopenharmony_ci .Init = HdfWlanInterfaceDriverInit, 132094332d3Sopenharmony_ci .Release = HdfWlanInterfaceDriverRelease, 133094332d3Sopenharmony_ci}; 134094332d3Sopenharmony_ci 135094332d3Sopenharmony_ciHDF_INIT(g_wlaninterfaceDriverEntry);