1 /*
2  * Copyright (c) 2021 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 "driver_loader_full.h"
17 
18 #include <dlfcn.h>
19 #include <errno.h>
20 #include <stdlib.h>
21 
22 #include "securec.h"
23 
24 #include "hdf_log.h"
25 #include "hdf_object_manager.h"
26 #include "osal_mem.h"
27 
28 #define DRIVER_DESC "driverDesc"
29 #define HDF_LOG_TAG driver_loader_full
30 
31 static struct DriverLoaderFull *g_fullLoader = NULL;
32 
HdfDriverLoaderGetDriver(const char * moduleName)33 struct HdfDriver *HdfDriverLoaderGetDriver(const char *moduleName)
34 {
35     if (moduleName == NULL) {
36         return NULL;
37     }
38 
39     struct HdfDriver *driver = OsalMemAlloc(sizeof(struct HdfDriver));
40     if (driver == NULL) {
41         return NULL;
42     }
43 
44     void *handle = dlopen(moduleName, RTLD_LAZY);
45     if (handle == NULL) {
46         HDF_LOGE("get driver handle, %{public}s dlopen failed, %{public}s", moduleName, dlerror());
47         OsalMemFree(driver);
48         return NULL;
49     }
50 
51     struct HdfDriverEntry **driverEntry = (struct HdfDriverEntry **)dlsym(handle, DRIVER_DESC);
52     if (driverEntry == NULL) {
53         HDF_LOGE("get driver entry %{public}s dlsym failed", moduleName);
54         dlclose(handle);
55         OsalMemFree(driver);
56         return NULL;
57     }
58 
59     driver->entry = *driverEntry;
60     driver->priv = handle;
61 
62     return driver;
63 }
64 
HdfDriverLoaderFullReclaimDriver(struct HdfDriver * driver)65 void HdfDriverLoaderFullReclaimDriver(struct HdfDriver *driver)
66 {
67     if (driver == NULL) {
68         return;
69     }
70 
71     OsalMemFree(driver);
72 }
73 
HdfDriverLoaderFullConstruct(struct DriverLoaderFull * inst)74 void HdfDriverLoaderFullConstruct(struct DriverLoaderFull *inst)
75 {
76     struct HdfDriverLoader *pvtbl = (struct HdfDriverLoader *)inst;
77     pvtbl->super.GetDriver = HdfDriverLoaderGetDriver;
78     pvtbl->super.ReclaimDriver = HdfDriverLoaderFullReclaimDriver;
79 }
80 
HdfDriverLoaderFullCreate(void)81 struct HdfObject *HdfDriverLoaderFullCreate(void)
82 {
83     if (g_fullLoader == NULL) {
84         struct DriverLoaderFull *instance =
85             (struct DriverLoaderFull *)OsalMemCalloc(sizeof(struct DriverLoaderFull));
86         if (instance != NULL) {
87             HdfDriverLoaderFullConstruct(instance);
88             g_fullLoader = instance;
89         }
90     }
91     return (struct HdfObject *)g_fullLoader;
92 }
93 
HdfDriverLoaderFullRelease(struct HdfObject * object)94 void HdfDriverLoaderFullRelease(struct HdfObject *object)
95 {
96     struct DriverLoaderFull *instance = (struct DriverLoaderFull *)object;
97     if (instance == g_fullLoader) {
98         g_fullLoader = NULL;
99     }
100     if (instance != NULL) {
101         OsalMemFree(instance);
102     }
103 }
104 
HdfDriverLoaderGetInstance(void)105 struct IDriverLoader *HdfDriverLoaderGetInstance(void)
106 {
107     static struct IDriverLoader *instance = NULL;
108     if (instance == NULL) {
109         instance = (struct IDriverLoader *)HdfObjectManagerGetObject(HDF_OBJECT_ID_DRIVER_LOADER);
110     }
111     return instance;
112 }
113