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