• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_error_code.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     { CLIENT_CHECK_COLLAB_RELATION, ClientCheckCollabRelation },
66 };
67 
ClientIpcInterfaceMsgHandle(uint32_t code,IpcIo * data,IpcIo * reply,MessageOption option)68 static int ClientIpcInterfaceMsgHandle(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option)
69 {
70     if (data == NULL) {
71         COMM_LOGE(COMM_SDK, "invalid param");
72         return SOFTBUS_INVALID_PARAM;
73     }
74 
75     COMM_LOGI(COMM_SDK, "receive ipc transact code. code=%{public}u", code);
76     unsigned int num = sizeof(g_softBusIpcClientCmdTbl) / sizeof(struct SoftBusIpcClientCmd);
77     for (unsigned int i = 0; i < num; i++) {
78         if (code == g_softBusIpcClientCmdTbl[i].code) {
79             return g_softBusIpcClientCmdTbl[i].func(data, reply);
80         }
81     }
82     COMM_LOGE(COMM_SDK, "not support code. code=%{public}u", code);
83     return SOFTBUS_FUNC_NOT_SUPPORT;
84 }
85 
InnerRegisterService(void)86 static int InnerRegisterService(void)
87 {
88     char *clientName[SOFTBUS_PKGNAME_MAX_NUM] = {0};
89     uint32_t clientNameNum = GetSoftBusClientNameList(clientName, SOFTBUS_PKGNAME_MAX_NUM);
90     if (clientNameNum == 0) {
91         COMM_LOGE(COMM_SDK, "get client name failed");
92         return SOFTBUS_NETWORK_GET_CLIENT_NAME_FAILED;
93     }
94 
95     struct CommonScvId svcId = {0};
96     if (GetClientIdentity(&svcId.handle, &svcId.token, &svcId.cookie) != SOFTBUS_OK) {
97         COMM_LOGE(COMM_SDK, "get client identity failed");
98         for (uint32_t i = 0; i < clientNameNum; i++) {
99             SoftBusFree(clientName[i]);
100         }
101         return SOFTBUS_NETWORK_GET_CLIENT_IDENTITY_FAILED;
102     }
103     for (uint32_t i = 0; i < clientNameNum; i++) {
104         while (RegisterService(clientName[i], &svcId) != SOFTBUS_OK) {
105             SoftBusSleepMs(WAIT_SERVER_READY_INTERVAL);
106         }
107         SoftBusFree(clientName[i]);
108     }
109 
110     COMM_LOGD(COMM_SDK, "InnerRegisterService success");
111     return SOFTBUS_OK;
112 }
113 
UnregisterServerDeathCb(void)114 static void UnregisterServerDeathCb(void)
115 {
116     RemoveDeathRecipient(g_svcIdentity, g_deathCbId);
117     g_deathCbId = INVALID_CB_ID;
118     g_svcIdentity.handle = 0;
119     g_svcIdentity.token = 0;
120     g_svcIdentity.cookie = 0;
121 }
122 
DeathProcTask(void * arg)123 static void *DeathProcTask(void *arg)
124 {
125     (void)arg;
126     CLIENT_NotifyObserver(EVENT_SERVER_DEATH, NULL, 0);
127 
128     ServerProxyDeInit();
129     TransServerProxyClear();
130     BusCenterServerProxyDeInit();
131 
132     ListNode sessionServerInfoList;
133     ListInit(&sessionServerInfoList);
134     ClientCleanAllSessionWhenServerDeath(&sessionServerInfoList);
135 
136     int32_t cnt = 0;
137     for (cnt = 0; cnt < CYCLE_NUM_MAX; cnt++) {
138         if (ServerProxyInit() == SOFTBUS_OK) {
139             COMM_LOGI(COMM_SDK, "proxy init wait sucess");
140             break;
141         }
142         SoftBusSleepMs(WAIT_SERVER_READY_SHORT_INTERVAL);
143         COMM_LOGI(COMM_SDK, "proxy init wait");
144     }
145 
146     if (cnt == CYCLE_NUM_MAX) {
147         COMM_LOGE(COMM_SDK, "server proxy init reached the maximum count=%{public}d", cnt);
148         return NULL;
149     }
150 
151     if (InnerRegisterService() != SOFTBUS_OK) {
152         COMM_LOGE(COMM_SDK, "register service failed");
153         return NULL;
154     }
155 
156     TransServerProxyInit();
157     BusCenterServerProxyInit();
158     DiscRecoveryPublish();
159     DiscRecoverySubscribe();
160 
161     COMM_LOGI(COMM_SDK, "\n<< !!! SERVICE (%{public}s) RECOVER !!! >>\n", SOFTBUS_SERVICE);
162     CLIENT_NotifyObserver(EVENT_SERVER_RECOVERY, NULL, 0);
163     UnregisterServerDeathCb();
164 
165     if (RegisterServerDeathCb() != SOFTBUS_OK) {
166         COMM_LOGE(COMM_SDK, "reg server death cb failed");
167         return NULL;
168     }
169 
170     return NULL;
171 }
172 
StartDeathProcTask(void)173 static int StartDeathProcTask(void)
174 {
175     int ret;
176     SoftBusThreadAttr threadAttr;
177     SoftBusThread tid;
178     ret = SoftBusThreadAttrInit(&threadAttr);
179     if (ret != 0) {
180         COMM_LOGE(COMM_SDK, "Thread attr init failed, ret=%{public}d", ret);
181         return ret;
182     }
183 
184     threadAttr.detachState = SOFTBUS_THREAD_DETACH;
185     threadAttr.policy = SOFTBUS_SCHED_RR;
186     threadAttr.taskName = "OS_deathTsk";
187     ret = SoftBusThreadCreate(&tid, &threadAttr, DeathProcTask, NULL);
188     if (ret != 0) {
189         COMM_LOGE(COMM_SDK, "create DeathProcTask failed, ret=%{public}d", ret);
190         return ret;
191     }
192 
193     return ret;
194 }
195 
DeathCallback(void)196 static void DeathCallback(void)
197 {
198     COMM_LOGW(COMM_SDK, "\n<< ATTENTION !!! >> SERVICE (%{public}s) DEAD !!!\n", SOFTBUS_SERVICE);
199 
200     if (StartDeathProcTask() != SOFTBUS_OK) {
201         COMM_LOGE(COMM_SDK, "start death proc task failed");
202     }
203     COMM_LOGI(COMM_SDK, "client start check softbus server...");
204 }
205 
RegisterServerDeathCb(void)206 static int RegisterServerDeathCb(void)
207 {
208     g_svcIdentity = SAMGR_GetRemoteIdentity(SOFTBUS_SERVICE, NULL);
209     g_deathCbId = INVALID_CB_ID;
210     if (AddDeathRecipient(g_svcIdentity, DeathCallback, NULL, &g_deathCbId) != EC_SUCCESS) {
211         COMM_LOGE(COMM_SDK, "reg death callback failed");
212         return SOFTBUS_NETWORK_ADD_DEATH_RECIPIENT_FAILED;
213     }
214     return SOFTBUS_OK;
215 }
216 
ClientStubInit(void)217 int ClientStubInit(void)
218 {
219     if (ServerProxyInit() != SOFTBUS_OK) {
220         COMM_LOGE(COMM_SDK, "server proxy init failed.");
221         return SOFTBUS_NO_INIT;
222     }
223 
224     static IpcObjectStub objectStub = {
225         .func = ClientIpcInterfaceMsgHandle,
226         .args = NULL,
227         .isRemote = false
228     };
229     SvcIdentity clientIdentity = {
230         .handle = IPC_INVALID_HANDLE,
231         .token = SERVICE_TYPE_ANONYMOUS,
232         .cookie = (uintptr_t)&objectStub
233     };
234 
235     int ret = ClientContextInit();
236     if (ret != SOFTBUS_OK) {
237         COMM_LOGE(COMM_SDK, "client context init failed.");
238         return ret;
239     }
240     SetClientIdentity(clientIdentity.handle, clientIdentity.token, clientIdentity.cookie);
241     if (RegisterServerDeathCb() != SOFTBUS_OK) {
242         ClientContextDeinit();
243         COMM_LOGE(COMM_SDK, "reg server death cb failed");
244         return SOFTBUS_NETWORK_ADD_DEATH_RECIPIENT_FAILED;
245     }
246 
247     return SOFTBUS_OK;
248 }
249 
ClientRegisterService(const char * pkgName)250 int ClientRegisterService(const char *pkgName)
251 {
252     struct CommonScvId svcId = {0};
253     if (GetClientIdentity(&svcId.handle, &svcId.token, &svcId.cookie) != SOFTBUS_OK) {
254         COMM_LOGE(COMM_SDK, "get client identity failed");
255         return SOFTBUS_NETWORK_GET_CLIENT_IDENTITY_FAILED;
256     }
257 
258     while (RegisterService(pkgName, &svcId) != SOFTBUS_OK) {
259         SoftBusSleepMs(WAIT_SERVER_READY_INTERVAL);
260     }
261 
262     COMM_LOGI(COMM_SDK, "ClientRegisterService success");
263     return SOFTBUS_OK;
264 }
265