1 /*
2 * Copyright (c) 2021-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 "softbus_server_proxy_frame.h"
17
18 #include <chrono>
19 #include <cstdlib>
20 #include <ctime>
21 #include <mutex>
22 #include <thread>
23 #include "client_bus_center_manager.h"
24 #include "client_trans_session_manager.h"
25 #include "client_trans_socket_manager.h"
26 #include "bus_center_server_proxy.h"
27 #include "comm_log.h"
28 #include "ipc_skeleton.h"
29 #include "iremote_broker.h"
30 #include "iremote_object.h"
31 #include "iremote_proxy.h"
32 #include "softbus_adapter_mem.h"
33 #include "softbus_adapter_timer.h"
34 #include "softbus_client_death_recipient.h"
35 #include "softbus_client_frame_manager.h"
36 #include "softbus_client_stub_interface.h"
37 #include "softbus_def.h"
38 #include "softbus_errcode.h"
39 #include "softbus_server_ipc_interface_code.h"
40 #include "softbus_server_proxy_standard.h"
41 #include "trans_server_proxy.h"
42
43 namespace {
44 OHOS::sptr<OHOS::IRemoteObject> g_serverProxy = nullptr;
45 OHOS::sptr<OHOS::IRemoteObject> g_oldServerProxy = nullptr;
46 OHOS::sptr<OHOS::IRemoteObject::DeathRecipient> g_clientDeath = nullptr;
47 std::mutex g_mutex;
48 constexpr uint32_t WAIT_SERVER_INTERVAL = 50;
49 constexpr uint32_t SOFTBUS_MAX_RETRY_TIMES = 25;
50 uint32_t g_getSystemAbilityId = 2;
51 uint32_t g_printRequestFailedCount = 0;
52 constexpr int32_t RANDOM_RANGE_MAX = 501; // range of random numbers is (0, 500ms)
53 constexpr uint32_t PRINT_INTERVAL = 200;
54 constexpr int32_t CYCLE_NUMBER_MAX = 100;
55 const std::u16string SAMANAGER_INTERFACE_TOKEN = u"ohos.samgr.accessToken";
56 }
57
InnerRegisterService(ListNode * sessionServerInfoList)58 static int InnerRegisterService(ListNode *sessionServerInfoList)
59 {
60 srand(time(nullptr));
61 int32_t randomNum = rand();
62 int32_t scaledNum = randomNum % RANDOM_RANGE_MAX;
63
64 // Prevent high-concurrency conflicts
65 std::this_thread::sleep_for(std::chrono::milliseconds(scaledNum));
66 if (g_serverProxy == nullptr) {
67 COMM_LOGE(COMM_SDK, "g_serverProxy is nullptr!");
68 return SOFTBUS_INVALID_PARAM;
69 }
70 OHOS::sptr<OHOS::SoftBusServerProxyFrame> serverProxyFrame =
71 new (std::nothrow) OHOS::SoftBusServerProxyFrame(g_serverProxy);
72 if (serverProxyFrame == nullptr) {
73 COMM_LOGE(COMM_SDK, "serverProxyFrame is nullptr!");
74 return SOFTBUS_INVALID_PARAM;
75 }
76 char *clientName[SOFTBUS_PKGNAME_MAX_NUM] = {0};
77 uint32_t clientNameNum = GetSoftBusClientNameList(clientName, SOFTBUS_PKGNAME_MAX_NUM);
78 if (clientNameNum == 0) {
79 COMM_LOGE(COMM_SDK, "get client name failed");
80 return SOFTBUS_TRANS_GET_CLIENT_NAME_FAILED;
81 }
82 for (uint32_t i = 0; i < clientNameNum; i++) {
83 while (serverProxyFrame->SoftbusRegisterService(clientName[i], nullptr) != SOFTBUS_OK) {
84 SoftBusSleepMs(WAIT_SERVER_READY_INTERVAL);
85 }
86 SoftBusFree(clientName[i]);
87 }
88 int32_t ret = ReCreateSessionServerToServer(sessionServerInfoList);
89 if (ret != SOFTBUS_OK) {
90 COMM_LOGE(COMM_SDK, "ReCreateSessionServerToServer failed!\n");
91 return ret;
92 }
93 COMM_LOGD(COMM_SDK, "softbus server register service success!\n");
94 return SOFTBUS_OK;
95 }
96
GetSystemAbility()97 static OHOS::sptr<OHOS::IRemoteObject> GetSystemAbility()
98 {
99 OHOS::MessageParcel data;
100 if (!data.WriteInterfaceToken(SAMANAGER_INTERFACE_TOKEN)) {
101 COMM_LOGE(COMM_EVENT, "write interface token failed!");
102 return nullptr;
103 }
104
105 data.WriteInt32(SOFTBUS_SERVER_SA_ID_INNER);
106 OHOS::MessageParcel reply;
107 OHOS::MessageOption option;
108 OHOS::sptr<OHOS::IRemoteObject> samgr = OHOS::IPCSkeleton::GetContextObject();
109 if (samgr == nullptr) {
110 COMM_LOGE(COMM_EVENT, "Get samgr failed!");
111 return nullptr;
112 }
113 int32_t err = samgr->SendRequest(g_getSystemAbilityId, data, reply, option);
114 if (err != 0) {
115 if ((++g_printRequestFailedCount) % PRINT_INTERVAL == 0) {
116 COMM_LOGD(COMM_EVENT, "Get GetSystemAbility failed!");
117 }
118 return nullptr;
119 }
120 return reply.ReadRemoteObject();
121 }
122
ServerProxyInit(void)123 static int32_t ServerProxyInit(void)
124 {
125 std::lock_guard<std::mutex> lock(g_mutex);
126 if (g_serverProxy == nullptr) {
127 g_serverProxy = GetSystemAbility();
128 if (g_serverProxy == nullptr) {
129 return SOFTBUS_IPC_ERR;
130 }
131
132 if (g_serverProxy == g_oldServerProxy) {
133 g_serverProxy = nullptr;
134 COMM_LOGE(COMM_SDK, "g_serverProxy not update\n");
135 return SOFTBUS_IPC_ERR;
136 }
137
138 g_clientDeath =
139 OHOS::sptr<OHOS::IRemoteObject::DeathRecipient>(new (std::nothrow) OHOS::SoftBusClientDeathRecipient());
140 if (g_clientDeath == nullptr) {
141 COMM_LOGE(COMM_SDK, "DeathRecipient object is nullptr\n");
142 return SOFTBUS_TRANS_DEATH_RECIPIENT_INVAILD;
143 }
144 if (!g_serverProxy->AddDeathRecipient(g_clientDeath)) {
145 COMM_LOGE(COMM_SDK, "AddDeathRecipient failed\n");
146 return SOFTBUS_TRANS_ADD_DEATH_RECIPIENT_FAILED;
147 }
148 }
149 return SOFTBUS_OK;
150 }
151
152 static RestartEventCallback g_restartAuthParaCallback = nullptr;
153
RestartAuthParaNotify(void)154 static void RestartAuthParaNotify(void)
155 {
156 if (g_restartAuthParaCallback == nullptr) {
157 COMM_LOGI(COMM_SDK, "Restart AuthPara notify is not used!\n");
158 return;
159 }
160 if (g_restartAuthParaCallback() != SOFTBUS_OK) {
161 RestartAuthParaCallbackUnregister();
162 COMM_LOGE(COMM_SDK, "Restart AuthPara notify failed!\n");\
163 return;
164 }
165 COMM_LOGI(COMM_SDK, "Restart AuthPara notify success!\n");
166 }
167
ClientDeathProcTask(void)168 void ClientDeathProcTask(void)
169 {
170 {
171 std::lock_guard<std::mutex> lock(g_mutex);
172 g_oldServerProxy = g_serverProxy;
173 if (g_serverProxy != nullptr && g_clientDeath != nullptr) {
174 g_serverProxy->RemoveDeathRecipient(g_clientDeath);
175 }
176 g_serverProxy.clear();
177 }
178 TransServerProxyDeInit();
179 BusCenterServerProxyDeInit();
180
181 ListNode sessionServerInfoList;
182 ListInit(&sessionServerInfoList);
183 ClientCleanAllSessionWhenServerDeath(&sessionServerInfoList);
184
185 int32_t cnt = 0;
186 for (cnt = 0; cnt < CYCLE_NUMBER_MAX; cnt++) {
187 if (ServerProxyInit() == SOFTBUS_OK) {
188 break;
189 }
190 SoftBusSleepMs(WAIT_SERVER_INTERVAL);
191 }
192 if (cnt == CYCLE_NUMBER_MAX) {
193 COMM_LOGE(COMM_SDK, "server proxy init reached the maximum count=%{public}d", cnt);
194 return;
195 }
196 TransServerProxyInit();
197 BusCenterServerProxyInit();
198 InnerRegisterService(&sessionServerInfoList);
199 RestartAuthParaNotify();
200 DiscRecoveryPublish();
201 DiscRecoverySubscribe();
202 DiscRecoveryPolicy();
203 RestartRegDataLevelChange();
204 }
205
RestartAuthParaCallbackUnregister(void)206 void RestartAuthParaCallbackUnregister(void)
207 {
208 g_restartAuthParaCallback = nullptr;
209 }
210
RestartAuthParaCallbackRegister(RestartEventCallback callback)211 int32_t RestartAuthParaCallbackRegister(RestartEventCallback callback)
212 {
213 if (callback == nullptr) {
214 COMM_LOGE(COMM_SDK, "Restart OpenAuthSessionWithPara callback register param is invalid!\n");
215 return SOFTBUS_ERR;
216 }
217 g_restartAuthParaCallback = callback;
218 COMM_LOGI(COMM_SDK, "Restart event callback register success!\n");
219 return SOFTBUS_OK;
220 }
221
ClientStubInit(void)222 int32_t ClientStubInit(void)
223 {
224 if (ServerProxyInit() != SOFTBUS_OK) {
225 COMM_LOGE(COMM_SDK, "ServerProxyInit failed\n");
226 return SOFTBUS_NO_INIT;
227 }
228 return SOFTBUS_OK;
229 }
230
ClientRegisterService(const char * pkgName)231 int ClientRegisterService(const char *pkgName)
232 {
233 if (g_serverProxy == nullptr) {
234 COMM_LOGE(COMM_SDK, "g_serverProxy is nullptr!");
235 return SOFTBUS_INVALID_PARAM;
236 }
237 OHOS::sptr<OHOS::SoftBusServerProxyFrame> serverProxyFrame =
238 new (std::nothrow) OHOS::SoftBusServerProxyFrame(g_serverProxy);
239 if (serverProxyFrame == nullptr) {
240 COMM_LOGE(COMM_SDK, "serverProxyFrame is nullptr!");
241 return SOFTBUS_INVALID_PARAM;
242 }
243 uint32_t sleepCnt = 0;
244 while (serverProxyFrame->SoftbusRegisterService(pkgName, nullptr) != SOFTBUS_OK) {
245 SoftBusSleepMs(WAIT_SERVER_READY_INTERVAL);
246 sleepCnt++;
247 if (sleepCnt >= SOFTBUS_MAX_RETRY_TIMES) {
248 return SOFTBUS_SERVER_NOT_INIT;
249 }
250 }
251
252 COMM_LOGD(COMM_SDK, "softbus server register service success! pkgName=%{public}s\n", pkgName);
253 return SOFTBUS_OK;
254 }
255