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 "nci_native_selector.h"
17 #include <dlfcn.h>
18 #include <string>
19 #include "loghelper.h"
20
21 namespace OHOS {
22 namespace NFC {
23 namespace NCI {
NciNativeSelector()24 NciNativeSelector::NciNativeSelector()
25 {
26 InitNativeInterface();
27 }
28
InitNativeInterface()29 void NciNativeSelector::InitNativeInterface()
30 {
31 nativeInterface_ = GetNciNativeInterface();
32 }
33
GetNciNativeInterface()34 std::shared_ptr<INciNativeInterface> NciNativeSelector::GetNciNativeInterface()
35 {
36 loader_ = std::make_unique<NciLibsLoader>();
37 if (!loader_->LoadLib()) {
38 return nullptr;
39 }
40 return loader_->NewInstance();
41 }
42
GetInstance()43 NciNativeSelector &NciNativeSelector::GetInstance()
44 {
45 static NciNativeSelector instance;
46 return instance;
47 }
48
GetNciCeInterface()49 std::shared_ptr<INciCeInterface> NciNativeSelector::GetNciCeInterface()
50 {
51 if (nativeInterface_) {
52 return nativeInterface_->GetNciCeInterface();
53 }
54 return nullptr;
55 }
56
GetNciNfccInterface()57 std::shared_ptr<INciNfccInterface> NciNativeSelector::GetNciNfccInterface()
58 {
59 if (nativeInterface_) {
60 return nativeInterface_->GetNciNfccInterface();
61 }
62 return nullptr;
63 }
64
GetNciTagInterface()65 std::shared_ptr<INciTagInterface> NciNativeSelector::GetNciTagInterface()
66 {
67 if (nativeInterface_) {
68 return nativeInterface_->GetNciTagInterface();
69 }
70 return nullptr;
71 }
72
NciLibsLoader(const std::string & newInterfaceSymbol,const std::string & deleteInterfaceSymbol)73 NciNativeSelector::NciLibsLoader::NciLibsLoader(const std::string &newInterfaceSymbol,
74 const std::string &deleteInterfaceSymbol): newInterfaceSymbol_(newInterfaceSymbol),
75 deleteInterfaceSymbol_(deleteInterfaceSymbol)
76 {
77 #ifdef USE_VENDOR_NCI_NATIVE
78 libPath_ = "libnci_native_vendor.z.so";
79 #else
80 libPath_ = "libnci_native_default.z.so";
81 #endif
82 }
83
~NciLibsLoader()84 NciNativeSelector::NciLibsLoader::~NciLibsLoader()
85 {
86 (void)CloseLib();
87 }
88
LoadLib()89 bool NciNativeSelector::NciLibsLoader::LoadLib()
90 {
91 if (libPath_.empty() || handle_) {
92 return false;
93 }
94 handle_ = dlopen(libPath_.c_str(), RTLD_LAZY | RTLD_LOCAL);
95 if (!handle_) {
96 ErrorLog("load %{public}s fail, %{public}s", libPath_.c_str(), dlerror());
97 return false;
98 }
99 InfoLog("load %{public}s success", libPath_.c_str());
100 return true;
101 }
102
CloseLib()103 bool NciNativeSelector::NciLibsLoader::CloseLib()
104 {
105 if (handle_) {
106 if (dlclose(handle_) != 0) {
107 handle_ = nullptr;
108 ErrorLog("close %{public}s fail, %{public}s", libPath_.c_str(), dlerror());
109 return false;
110 }
111 handle_ = nullptr;
112 }
113 InfoLog("close %{public}s success", libPath_.c_str());
114 return true;
115 }
116
NewInstance()117 std::shared_ptr<INciNativeInterface> NciNativeSelector::NciLibsLoader::NewInstance()
118 {
119 if (!handle_) {
120 ErrorLog("fail handle is null");
121 return nullptr;
122 }
123 using NewFuncType = INciNativeInterface *(*)(void);
124 using DeleteFuncType = void (*)(INciNativeInterface *);
125
126 auto newInterface = reinterpret_cast<NewFuncType>(dlsym(handle_, newInterfaceSymbol_.c_str()));
127 auto deleteInterface = reinterpret_cast<DeleteFuncType>(dlsym(handle_, deleteInterfaceSymbol_.c_str()));
128 if (!newInterface || !deleteInterface) {
129 (void)CloseLib();
130 ErrorLog("fail not found sym %{public}s", libPath_.c_str());
131 return nullptr;
132 }
133 InfoLog("new instance %{public}s success", libPath_.c_str());
134 return std::shared_ptr<INciNativeInterface>(newInterface(), deleteInterface);
135 }
136 } // namespace NCI
137 } // namespace NFC
138 } // namespace OHOS