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 <dlfcn.h>
17 #include <sstream>
18 
19 #include "edm_errors.h"
20 #include "hilog_wrapper.h"
21 #include "string_ex.h"
22 #include "bus_extension_core.h"
23 
24 #ifdef __aarch64__
25 static constexpr const char *BUS_EXTENSION_SO_PATH = "/system/lib64";
26 #else
27 static constexpr const char *BUS_EXTENSION_SO_PATH = "/system/lib";
28 #endif
29 static constexpr const char *HDI_SO_SUFFIX = ".z.so";
30 static constexpr const char *HDI_SO_PREFIX = "lib";
31 static constexpr const char *USB_BUS_EXTENSION = "driver_extension_usb_bus";
32 
33 namespace OHOS {
34 namespace ExternalDeviceManager {
35 IMPLEMENT_SINGLE_INSTANCE(BusExtensionCore);
36 
37 std::unordered_map<std::string, BusType> BusExtensionCore::busTypeMap_ = {
38     {"usb", BusType::BUS_TYPE_USB}
39 };
40 
LoadBusExtensionLibs()41 void BusExtensionCore::LoadBusExtensionLibs()
42 {
43     for (BusType i = BUS_TYPE_USB; i < BUS_TYPE_MAX; i = (BusType)(i + 1)) {
44         std::ostringstream libPath;
45         libPath << BUS_EXTENSION_SO_PATH << "/" << HDI_SO_PREFIX;
46         switch (i) {
47             case BUS_TYPE_USB:
48                 libPath << USB_BUS_EXTENSION;
49                 break;
50             default:
51                 EDM_LOGE(MODULE_DEV_MGR, "invalid bus type");
52                 continue;
53         }
54         libPath << HDI_SO_SUFFIX;
55         char realPath[PATH_MAX + 1] = {0};
56         if (realpath(libPath.str().c_str(), realPath) == nullptr) {
57             EDM_LOGE(MODULE_DEV_MGR, "invalid so path %{public}s", realPath);
58             continue;
59         }
60         void *handler = dlopen(realPath, RTLD_LAZY);
61         if (handler == nullptr) {
62             EDM_LOGE(MODULE_DEV_MGR, "failed to dlopen  %{public}s, %{public}s", realPath, dlerror());
63             continue;
64         }
65     }
66 }
67 
Init(std::shared_ptr<IDevChangeCallback> callback)68 int32_t BusExtensionCore::Init(std::shared_ptr<IDevChangeCallback> callback)
69 {
70     int ret = EDM_OK;
71     for (auto &iter : busExtensions_) {
72         if (iter.second->SetDevChangeCallback(callback) != EDM_OK) {
73             ret = EDM_NOK;
74             EDM_LOGE(MODULE_DEV_MGR, "busExtension init failed, busType is %{public}d", iter.first);
75         }
76         EDM_LOGD(MODULE_DEV_MGR, "busExtension init successfully, busType is %{public}d", iter.first);
77     }
78     return ret;
79 }
80 
Register(BusType busType,std::shared_ptr<IBusExtension> busExtension)81 int32_t BusExtensionCore::Register(BusType busType, std::shared_ptr<IBusExtension> busExtension)
82 {
83     if (busExtensions_.size() == MAX_BUS_EXTENSIONS) {
84         EDM_LOGE(MODULE_DEV_MGR, "the maximum number of busextension registrations has been reached");
85         return EDM_NOK;
86     }
87     if (busExtensions_.find(busType) != busExtensions_.end()) {
88         EDM_LOGI(MODULE_DEV_MGR, "busType %{public}d has been registered", busType);
89         return EDM_OK;
90     }
91     busExtensions_.emplace(busType, busExtension);
92     EDM_LOGD(MODULE_DEV_MGR, "busType %{public}d register successfully", busType);
93     return EDM_OK;
94 }
95 
GetBusTypeByName(const std::string & busName)96 BusType BusExtensionCore::GetBusTypeByName(const std::string &busName)
97 {
98     auto iterMap = busTypeMap_.find(LowerStr(busName));
99     if (iterMap == busTypeMap_.end()) {
100         EDM_LOGE(MODULE_DEV_MGR, "invalid bus name: %{public}s", busName.c_str());
101         return BusType::BUS_TYPE_INVALID;
102     }
103     return iterMap->second;
104 }
105 
GetBusExtensionByName(std::string busName)106 std::shared_ptr<IBusExtension> BusExtensionCore::GetBusExtensionByName(std::string busName)
107 {
108     BusType busType = GetBusTypeByName(busName);
109     if (busType <= BusType::BUS_TYPE_INVALID || busType >= BusType::BUS_TYPE_MAX) {
110         return nullptr;
111     }
112     auto iterExtension = busExtensions_.find(busType);
113     if (iterExtension == busExtensions_.end()) {
114         EDM_LOGE(MODULE_DEV_MGR, "%{public}s bus extension not found", busName.c_str());
115         return nullptr;
116     }
117     return busExtensions_[busType];
118 }
119 } // namespace ExternalDeviceManager
120 } // namespace OHOS