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