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