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 "bus_center_client_stub.h"
17 #include "bus_center_server_proxy.h"
18 #include "client_bus_center_manager.h"
19 #include "client_trans_session_manager.h"
20 #include "comm_log.h"
21 #include "iproxy_client.h"
22 #include "ipc_skeleton.h"
23 #include "softbus_adapter_mem.h"
24 #include "softbus_adapter_thread.h"
25 #include "softbus_adapter_timer.h"
26 #include "softbus_client_context_manager.h"
27 #include "softbus_client_event_manager.h"
28 #include "softbus_client_frame_manager.h"
29 #include "softbus_client_stub_interface.h"
30 #include "softbus_errcode.h"
31 #include "softbus_server_ipc_interface_code.h"
32 #include "softbus_server_proxy.h"
33 #include "trans_client_stub.h"
34 #include "trans_server_proxy.h"
35
36 #define INVALID_CB_ID 0xFF
37 #define CYCLE_NUM_MAX 100
38
39 static int RegisterServerDeathCb(void);
40 static unsigned int g_deathCbId = INVALID_CB_ID;
41 static SvcIdentity g_svcIdentity = {0};
42
43 struct SoftBusIpcClientCmd {
44 enum SoftBusFuncId code;
45 int32_t (*func)(IpcIo *data, IpcIo *reply);
46 };
47
48 static struct SoftBusIpcClientCmd g_softBusIpcClientCmdTbl[] = {
49 { CLIENT_ON_JOIN_RESULT, ClientOnJoinLNNResult },
50 { CLIENT_ON_JOIN_METANODE_RESULT, ClientOnJoinMetaNodeResult },
51 { CLIENT_ON_LEAVE_RESULT, ClientOnLeaveLNNResult },
52 { CLIENT_ON_LEAVE_METANODE_RESULT, ClientOnLeaveMetaNodeResult },
53 { CLIENT_ON_NODE_ONLINE_STATE_CHANGED, ClientOnNodeOnlineStateChanged },
54 { CLIENT_ON_NODE_BASIC_INFO_CHANGED, ClientOnNodeBasicInfoChanged },
55 { CLIENT_ON_TIME_SYNC_RESULT, ClientOnTimeSyncResult },
56 { CLIENT_ON_PUBLISH_LNN_RESULT, ClientOnPublishLNNResult },
57 { CLIENT_ON_REFRESH_LNN_RESULT, ClientOnRefreshLNNResult },
58 { CLIENT_ON_REFRESH_DEVICE_FOUND, ClientOnRefreshDeviceFound },
59 { CLIENT_ON_CHANNEL_OPENED, ClientOnChannelOpened },
60 { CLIENT_ON_CHANNEL_OPENFAILED, ClientOnChannelOpenfailed },
61 { CLIENT_ON_CHANNEL_CLOSED, ClientOnChannelClosed },
62 { CLIENT_ON_CHANNEL_MSGRECEIVED, ClientOnChannelMsgreceived },
63 { CLIENT_SET_CHANNEL_INFO, ClientSetChannelInfo },
64 { CLIENT_ON_CHANNEL_BIND, ClientOnChannelBind },
65 };
66
ClientIpcInterfaceMsgHandle(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option)67 static int ClientIpcInterfaceMsgHandle(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option)
68 {
69 if (data == NULL) {
70 COMM_LOGE(COMM_SDK, "invalid param");
71 return SOFTBUS_ERR;
72 }
73
74 COMM_LOGI(COMM_SDK, "receive ipc transact code. code=%{public}u", code);
75 unsigned int num = sizeof(g_softBusIpcClientCmdTbl) / sizeof(struct SoftBusIpcClientCmd);
76 for (unsigned int i = 0; i < num; i++) {
77 if (code == g_softBusIpcClientCmdTbl[i].code) {
78 return g_softBusIpcClientCmdTbl[i].func(data, reply);
79 }
80 }
81 COMM_LOGE(COMM_SDK, "not support code. code=%{public}u", code);
82 return SOFTBUS_ERR;
83 }
84
InnerRegisterService(void)85 static int InnerRegisterService(void)
86 {
87 char *clientName[SOFTBUS_PKGNAME_MAX_NUM] = {0};
88 uint32_t clientNameNum = GetSoftBusClientNameList(clientName, SOFTBUS_PKGNAME_MAX_NUM);
89 if (clientNameNum == 0) {
90 COMM_LOGE(COMM_SDK, "get client name failed");
91 return SOFTBUS_ERR;
92 }
93
94 struct CommonScvId svcId = {0};
95 if (GetClientIdentity(&svcId.handle, &svcId.token, &svcId.cookie) != SOFTBUS_OK) {
96 COMM_LOGE(COMM_SDK, "get client identity failed");
97 for (uint32_t i = 0; i < clientNameNum; i++) {
98 SoftBusFree(clientName[i]);
99 }
100 return SOFTBUS_ERR;
101 }
102 for (uint32_t i = 0; i < clientNameNum; i++) {
103 while (RegisterService(clientName[i], &svcId) != SOFTBUS_OK) {
104 SoftBusSleepMs(WAIT_SERVER_READY_INTERVAL);
105 }
106 SoftBusFree(clientName[i]);
107 }
108
109 COMM_LOGD(COMM_SDK, "InnerRegisterService success");
110 return SOFTBUS_OK;
111 }
112
UnregisterServerDeathCb(void)113 static void UnregisterServerDeathCb(void)
114 {
115 RemoveDeathRecipient(g_svcIdentity, g_deathCbId);
116 g_deathCbId = INVALID_CB_ID;
117 g_svcIdentity.handle = 0;
118 g_svcIdentity.token = 0;
119 g_svcIdentity.cookie = 0;
120 }
121
DeathProcTask(void *arg)122 static void *DeathProcTask(void *arg)
123 {
124 (void)arg;
125 CLIENT_NotifyObserver(EVENT_SERVER_DEATH, NULL, 0);
126
127 ServerProxyDeInit();
128 TransServerProxyDeInit();
129 BusCenterServerProxyDeInit();
130
131 ListNode sessionServerInfoList;
132 ListInit(&sessionServerInfoList);
133 ClientCleanAllSessionWhenServerDeath(&sessionServerInfoList);
134
135 int32_t cnt = 0;
136 for (cnt = 0; cnt < CYCLE_NUM_MAX; cnt++) {
137 if (ServerProxyInit() == SOFTBUS_OK) {
138 COMM_LOGI(COMM_SDK, "proxy init wait sucess");
139 break;
140 }
141 SoftBusSleepMs(WAIT_SERVER_READY_SHORT_INTERVAL);
142 COMM_LOGI(COMM_SDK, "proxy init wait");
143 }
144
145 if (cnt == CYCLE_NUM_MAX) {
146 COMM_LOGE(COMM_SDK, "server proxy init reached the maximum count=%{public}d", cnt);
147 return NULL;
148 }
149
150 if (InnerRegisterService() != SOFTBUS_OK) {
151 COMM_LOGE(COMM_SDK, "register service failed");
152 return NULL;
153 }
154
155 TransServerProxyInit();
156 BusCenterServerProxyInit();
157 DiscRecoveryPublish();
158 DiscRecoverySubscribe();
159
160 COMM_LOGI(COMM_SDK, "\n<< !!! SERVICE (%{public}s) RECOVER !!! >>\n", SOFTBUS_SERVICE);
161 CLIENT_NotifyObserver(EVENT_SERVER_RECOVERY, NULL, 0);
162 UnregisterServerDeathCb();
163
164 if (RegisterServerDeathCb() != SOFTBUS_OK) {
165 COMM_LOGE(COMM_SDK, "reg server death cb failed");
166 return NULL;
167 }
168
169 return NULL;
170 }
171
StartDeathProcTask(void)172 static int StartDeathProcTask(void)
173 {
174 int ret;
175 SoftBusThreadAttr threadAttr;
176 SoftBusThread tid;
177 ret = SoftBusThreadAttrInit(&threadAttr);
178 if (ret != 0) {
179 COMM_LOGE(COMM_SDK, "Thread attr init failed, ret=%{public}d", ret);
180 return SOFTBUS_ERR;
181 }
182
183 threadAttr.detachState = SOFTBUS_THREAD_DETACH;
184 threadAttr.policy = SOFTBUS_SCHED_RR;
185 threadAttr.taskName = "OS_deathTsk";
186 ret = SoftBusThreadCreate(&tid, &threadAttr, DeathProcTask, NULL);
187 if (ret != 0) {
188 COMM_LOGE(COMM_SDK, "create DeathProcTask failed, ret=%{public}d", ret);
189 return SOFTBUS_ERR;
190 }
191
192 return ret;
193 }
194
DeathCallback(void)195 static void DeathCallback(void)
196 {
197 COMM_LOGW(COMM_SDK, "\n<< ATTENTION !!! >> SERVICE (%{public}s) DEAD !!!\n", SOFTBUS_SERVICE);
198
199 if (StartDeathProcTask() != SOFTBUS_OK) {
200 COMM_LOGE(COMM_SDK, "start death proc task failed");
201 }
202 COMM_LOGI(COMM_SDK, "client start check softbus server...");
203 }
204
RegisterServerDeathCb(void)205 static int RegisterServerDeathCb(void)
206 {
207 g_svcIdentity = SAMGR_GetRemoteIdentity(SOFTBUS_SERVICE, NULL);
208 g_deathCbId = INVALID_CB_ID;
209 if (AddDeathRecipient(g_svcIdentity, DeathCallback, NULL, &g_deathCbId) != EC_SUCCESS) {
210 COMM_LOGE(COMM_SDK, "reg death callback failed");
211 return SOFTBUS_ERR;
212 }
213 return SOFTBUS_OK;
214 }
215
ClientStubInit(void)216 int ClientStubInit(void)
217 {
218 if (ServerProxyInit() != SOFTBUS_OK) {
219 COMM_LOGE(COMM_SDK, "server proxy init failed.");
220 return SOFTBUS_ERR;
221 }
222
223 static IpcObjectStub objectStub = {
224 .func = ClientIpcInterfaceMsgHandle,
225 .args = NULL,
226 .isRemote = false
227 };
228 SvcIdentity clientIdentity = {
229 .handle = IPC_INVALID_HANDLE,
230 .token = SERVICE_TYPE_ANONYMOUS,
231 .cookie = (uintptr_t)&objectStub
232 };
233
234 int ret = ClientContextInit();
235 if (ret != SOFTBUS_OK) {
236 COMM_LOGE(COMM_SDK, "client context init failed.");
237 return SOFTBUS_ERR;
238 }
239 SetClientIdentity(clientIdentity.handle, clientIdentity.token, clientIdentity.cookie);
240 if (RegisterServerDeathCb() != SOFTBUS_OK) {
241 ClientContextDeinit();
242 COMM_LOGE(COMM_SDK, "reg server death cb failed");
243 return SOFTBUS_ERR;
244 }
245
246 return SOFTBUS_OK;
247 }
248
ClientRegisterService(const char *pkgName)249 int ClientRegisterService(const char *pkgName)
250 {
251 struct CommonScvId svcId = {0};
252 if (GetClientIdentity(&svcId.handle, &svcId.token, &svcId.cookie) != SOFTBUS_OK) {
253 COMM_LOGE(COMM_SDK, "get client identity failed");
254 return SOFTBUS_ERR;
255 }
256
257 while (RegisterService(pkgName, &svcId) != SOFTBUS_OK) {
258 SoftBusSleepMs(WAIT_SERVER_READY_INTERVAL);
259 }
260
261 COMM_LOGI(COMM_SDK, "ClientRegisterService success");
262 return SOFTBUS_OK;
263 }
264