• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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