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