1 /*
2 * Copyright (C) 2024 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 "dbinder_softbus_client.h"
17
18 #include <dlfcn.h>
19 #include "check_instance_exit.h"
20 #include "ipc_debug.h"
21 #include "log_tags.h"
22
23 namespace OHOS {
24
25 using namespace OHOS::HiviewDFX;
26 static constexpr HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_IPC_DBINDER_SOFTBUS_CLIENT, "DBinderSoftbusClient"};
27
28 #ifdef __aarch64__
29 static constexpr const char *SOFTBUS_PATH_NAME = "/system/lib64/platformsdk/libsoftbus_client.z.so";
30 #else
31 static constexpr const char *SOFTBUS_PATH_NAME = "/system/lib/platformsdk/libsoftbus_client.z.so";
32 #endif
33
GetInstance()34 DBinderSoftbusClient& DBinderSoftbusClient::GetInstance()
35 {
36 static DBinderSoftbusClient instance;
37 return instance;
38 }
39
DBinderSoftbusClient()40 DBinderSoftbusClient::DBinderSoftbusClient()
41 {
42 }
43
~DBinderSoftbusClient()44 DBinderSoftbusClient::~DBinderSoftbusClient()
45 {
46 exitFlag_ = true;
47 ZLOGI(LOG_LABEL, "destroy");
48 }
49
OpenSoftbusClientSo()50 bool DBinderSoftbusClient::OpenSoftbusClientSo()
51 {
52 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, false);
53 std::lock_guard<std::mutex> lockGuard(loadSoMutex_);
54
55 if (isLoaded_ && (soHandle_ != nullptr)) {
56 return true;
57 }
58
59 soHandle_ = dlopen(SOFTBUS_PATH_NAME, RTLD_NOW | RTLD_NODELETE);
60 if (soHandle_ == nullptr) {
61 ZLOGE(LOG_LABEL, "dlopen %{public}s failed, err msg:%{public}s", SOFTBUS_PATH_NAME, dlerror());
62 return false;
63 }
64
65 isLoaded_ = true;
66 ZLOGI(LOG_LABEL, "dlopen %{public}s SOFTBUS_CLIENT_SUCCESS", SOFTBUS_PATH_NAME);
67
68 return true;
69 }
70
DBinderGrantPermission(int32_t uid,int32_t pid,const std::string & socketName)71 int32_t DBinderSoftbusClient::DBinderGrantPermission(int32_t uid, int32_t pid, const std::string &socketName)
72 {
73 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, SOFTBUS_CLIENT_INSTANCE_EXIT);
74 if (grantPermissionFunc_ != nullptr) {
75 return grantPermissionFunc_(uid, pid, socketName.c_str());
76 }
77
78 if (!OpenSoftbusClientSo()) {
79 return SOFTBUS_CLIENT_DLOPEN_FAILED;
80 }
81
82 grantPermissionFunc_ = (DBinderGrantPermissionFunc)dlsym(soHandle_, "DBinderGrantPermission");
83 if (grantPermissionFunc_ == nullptr) {
84 ZLOGE(LOG_LABEL, "dlsym DBinderGrantPermission fail, err msg:%{public}s", dlerror());
85 return SOFTBUS_CLIENT_DLSYM_FAILED;
86 }
87
88 return grantPermissionFunc_(uid, pid, socketName.c_str());
89 }
90
DBinderRemovePermission(const std::string & socketName)91 int32_t DBinderSoftbusClient::DBinderRemovePermission(const std::string &socketName)
92 {
93 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, SOFTBUS_CLIENT_INSTANCE_EXIT);
94 if (removePermissionFunc_ != nullptr) {
95 return removePermissionFunc_(socketName.c_str());
96 }
97
98 if (!OpenSoftbusClientSo()) {
99 return SOFTBUS_CLIENT_DLOPEN_FAILED;
100 }
101
102 removePermissionFunc_ = (DBinderRemovePermissionFunc)dlsym(soHandle_, "DBinderRemovePermission");
103 if (removePermissionFunc_ == nullptr) {
104 ZLOGE(LOG_LABEL, "dlsym DBinderRemovePermission fail, err msg:%{public}s", dlerror());
105 return SOFTBUS_CLIENT_DLSYM_FAILED;
106 }
107
108 return removePermissionFunc_(socketName.c_str());
109 }
110
GetLocalNodeDeviceId(const std::string & pkgName,std::string & devId)111 int32_t DBinderSoftbusClient::GetLocalNodeDeviceId(const std::string &pkgName, std::string &devId)
112 {
113 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, SOFTBUS_CLIENT_INSTANCE_EXIT);
114 NodeBasicInfo nodeBasicInfo;
115 if (getLocalNodeDeviceInfoFunc_ != nullptr) {
116 if (getLocalNodeDeviceInfoFunc_(pkgName.c_str(), &nodeBasicInfo) != 0) {
117 ZLOGE(LOG_LABEL, "Get local node device info failed");
118 return SOFTBUS_CLIENT_GET_DEVICE_INFO_FAILED;
119 }
120 devId = nodeBasicInfo.networkId;
121 return SOFTBUS_CLIENT_SUCCESS;
122 }
123
124 if (!OpenSoftbusClientSo()) {
125 return SOFTBUS_CLIENT_DLOPEN_FAILED;
126 }
127
128 getLocalNodeDeviceInfoFunc_ = (GetLocalNodeDeviceInfoFunc)dlsym(soHandle_, "GetLocalNodeDeviceInfo");
129 if (getLocalNodeDeviceInfoFunc_ == nullptr) {
130 ZLOGE(LOG_LABEL, "dlsym GetLocalNodeDeviceInfo fail, err msg:%{public}s", dlerror());
131 return SOFTBUS_CLIENT_DLSYM_FAILED;
132 }
133
134 if (getLocalNodeDeviceInfoFunc_(pkgName.c_str(), &nodeBasicInfo) != 0) {
135 ZLOGE(LOG_LABEL, "Get local node device info failed");
136 return SOFTBUS_CLIENT_GET_DEVICE_INFO_FAILED;
137 }
138 devId = nodeBasicInfo.networkId;
139 return SOFTBUS_CLIENT_SUCCESS;
140 }
141
Socket(SocketInfo info)142 int32_t DBinderSoftbusClient::Socket(SocketInfo info)
143 {
144 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, SOFTBUS_CLIENT_INSTANCE_EXIT);
145 if (socketFunc_ != nullptr) {
146 return socketFunc_(info);
147 }
148
149 if (!OpenSoftbusClientSo()) {
150 return SOFTBUS_CLIENT_DLOPEN_FAILED;
151 }
152
153 socketFunc_ = (SocketFunc)dlsym(soHandle_, "Socket");
154 if (socketFunc_ == nullptr) {
155 ZLOGE(LOG_LABEL, "dlsym Socket fail, err msg:%{public}s", dlerror());
156 return SOFTBUS_CLIENT_DLSYM_FAILED;
157 }
158
159 return socketFunc_(info);
160 }
161
Listen(int32_t socket,const QosTV qos[],uint32_t qosCount,const ISocketListener * listener)162 int32_t DBinderSoftbusClient::Listen(
163 int32_t socket, const QosTV qos[], uint32_t qosCount, const ISocketListener *listener)
164 {
165 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, SOFTBUS_CLIENT_INSTANCE_EXIT);
166 if (listenFunc_ != nullptr) {
167 return listenFunc_(socket, qos, qosCount, listener);
168 }
169
170 if (!OpenSoftbusClientSo()) {
171 return SOFTBUS_CLIENT_DLOPEN_FAILED;
172 }
173
174 listenFunc_ = (ListenFunc)dlsym(soHandle_, "Listen");
175 if (listenFunc_ == nullptr) {
176 ZLOGE(LOG_LABEL, "dlsym Listen fail, err msg:%{public}s", dlerror());
177 return SOFTBUS_CLIENT_DLSYM_FAILED;
178 }
179
180 return listenFunc_(socket, qos, qosCount, listener);
181 }
182
Bind(int32_t socket,const QosTV qos[],uint32_t qosCount,const ISocketListener * listener)183 int32_t DBinderSoftbusClient::Bind(
184 int32_t socket, const QosTV qos[], uint32_t qosCount, const ISocketListener *listener)
185 {
186 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, SOFTBUS_CLIENT_INSTANCE_EXIT);
187 if (bindFunc_ != nullptr) {
188 return bindFunc_(socket, qos, qosCount, listener);
189 }
190
191 if (!OpenSoftbusClientSo()) {
192 return SOFTBUS_CLIENT_DLOPEN_FAILED;
193 }
194
195 bindFunc_ = (BindFunc)dlsym(soHandle_, "Bind");
196 if (bindFunc_ == nullptr) {
197 ZLOGE(LOG_LABEL, "dlsym Bind fail, err msg:%{public}s", dlerror());
198 return SOFTBUS_CLIENT_DLSYM_FAILED;
199 }
200
201 return bindFunc_(socket, qos, qosCount, listener);
202 }
203
SendBytes(int32_t socket,const void * data,uint32_t len)204 int32_t DBinderSoftbusClient::SendBytes(int32_t socket, const void *data, uint32_t len)
205 {
206 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, SOFTBUS_CLIENT_INSTANCE_EXIT);
207 if (sendBytesFunc_ != nullptr) {
208 return sendBytesFunc_(socket, data, len);
209 }
210
211 if (!OpenSoftbusClientSo()) {
212 return SOFTBUS_CLIENT_DLOPEN_FAILED;
213 }
214
215 sendBytesFunc_ = (SendBytesFunc)dlsym(soHandle_, "SendBytes");
216 if (sendBytesFunc_ == nullptr) {
217 ZLOGE(LOG_LABEL, "dlsym SendBytes fail, err msg:%{public}s", dlerror());
218 return SOFTBUS_CLIENT_DLSYM_FAILED;
219 }
220 return sendBytesFunc_(socket, data, len);
221 }
222
SendMessage(int32_t socket,const void * data,uint32_t len)223 int32_t DBinderSoftbusClient::SendMessage(int32_t socket, const void *data, uint32_t len)
224 {
225 CHECK_INSTANCE_EXIT_WITH_RETVAL(exitFlag_, SOFTBUS_CLIENT_INSTANCE_EXIT);
226 if (sendMessageFunc_ != nullptr) {
227 return sendMessageFunc_(socket, data, len);
228 }
229
230 if (!OpenSoftbusClientSo()) {
231 return SOFTBUS_CLIENT_DLOPEN_FAILED;
232 }
233
234 sendMessageFunc_ = (SendMessageFunc)dlsym(soHandle_, "SendMessage");
235 if (sendMessageFunc_ == nullptr) {
236 ZLOGE(LOG_LABEL, "dlsym SendMessage fail, err msg:%{public}s", dlerror());
237 return SOFTBUS_CLIENT_DLSYM_FAILED;
238 }
239 return sendMessageFunc_(socket, data, len);
240 }
241
Shutdown(int32_t socket)242 void DBinderSoftbusClient::Shutdown(int32_t socket)
243 {
244 CHECK_INSTANCE_EXIT(exitFlag_);
245 if (shutdownFunc_ != nullptr) {
246 shutdownFunc_(socket);
247 return;
248 }
249
250 if (!OpenSoftbusClientSo()) {
251 return;
252 }
253
254 shutdownFunc_ = (ShutdownFunc)dlsym(soHandle_, "Shutdown");
255 if (shutdownFunc_ == nullptr) {
256 ZLOGE(LOG_LABEL, "dlsym Shutdown fail, err msg:%{public}s", dlerror());
257 return;
258 }
259
260 shutdownFunc_(socket);
261 }
262 } // namespace OHOS
263