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
LoadBusExtensionLibs()37 void BusExtensionCore::LoadBusExtensionLibs()
38 {
39 for (BusType i = BUS_TYPE_USB; i < BUS_TYPE_MAX; i = (BusType)(i + 1)) {
40 std::ostringstream libPath;
41 libPath << BUS_EXTENSION_SO_PATH << "/" << HDI_SO_PREFIX;
42 switch (i) {
43 case BUS_TYPE_USB:
44 libPath << USB_BUS_EXTENSION;
45 break;
46 default:
47 EDM_LOGE(MODULE_DEV_MGR, "invalid bus type");
48 continue;
49 }
50 libPath << HDI_SO_SUFFIX;
51 char realPath[PATH_MAX + 1] = {0};
52 if (realpath(libPath.str().c_str(), realPath) == nullptr) {
53 EDM_LOGE(MODULE_DEV_MGR, "invalid so path %{public}s", realPath);
54 continue;
55 }
56 void *handler = dlopen(realPath, RTLD_LAZY);
57 if (handler == nullptr) {
58 EDM_LOGE(MODULE_DEV_MGR, "failed to dlopen %{public}s, %{public}s", realPath, dlerror());
59 continue;
60 }
61 }
62 }
63
Init(std::shared_ptr<IDevChangeCallback> callback)64 int32_t BusExtensionCore::Init(std::shared_ptr<IDevChangeCallback> callback)
65 {
66 int ret = EDM_OK;
67 for (auto &iter : busExtensions_) {
68 if (iter.second->SetDevChangeCallback(callback) != EDM_OK) {
69 ret = EDM_NOK;
70 EDM_LOGE(MODULE_DEV_MGR, "busExtension init failed, busType is %{public}d", iter.first);
71 }
72 EDM_LOGD(MODULE_DEV_MGR, "busExtension init successfully, busType is %{public}d", iter.first);
73 }
74 return ret;
75 }
76
Register(BusType busType,std::shared_ptr<IBusExtension> busExtension)77 int32_t BusExtensionCore::Register(BusType busType, std::shared_ptr<IBusExtension> busExtension)
78 {
79 if (busExtensions_.size() == MAX_BUS_EXTENSIONS) {
80 EDM_LOGE(MODULE_DEV_MGR, "the maximum number of busextension registrations has been reached");
81 return EDM_NOK;
82 }
83 if (busExtensions_.find(busType) != busExtensions_.end()) {
84 EDM_LOGI(MODULE_DEV_MGR, "busType %{public}d has been registered", busType);
85 return EDM_OK;
86 }
87 busExtensions_.emplace(busType, busExtension);
88 EDM_LOGD(MODULE_DEV_MGR, "busType %{public}d register successfully", busType);
89 return EDM_OK;
90 }
91
GetBusExtensionByName(std::string busName)92 std::shared_ptr<IBusExtension> BusExtensionCore::GetBusExtensionByName(std::string busName)
93 {
94 static std::unordered_map<std::string, BusType> busTypeMap = {
95 {"usb", BusType::BUS_TYPE_USB}
96 };
97 auto iterMap = busTypeMap.find(LowerStr(busName));
98 if (iterMap == busTypeMap.end()) {
99 EDM_LOGE(MODULE_DEV_MGR, "invalid bus name: %{public}s", busName.c_str());
100 return nullptr;
101 }
102 BusType busType = iterMap->second;
103 auto iterExtension = busExtensions_.find(busType);
104 if (iterExtension == busExtensions_.end()) {
105 EDM_LOGE(MODULE_DEV_MGR, "%{public}s bus extension not found", busName.c_str());
106 return nullptr;
107 }
108 return busExtensions_[busType];
109 }
110 } // namespace ExternalDeviceManager
111 } // namespace OHOS