1060ff233Sopenharmony_ci/*
2060ff233Sopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3060ff233Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4060ff233Sopenharmony_ci * you may not use this file except in compliance with the License.
5060ff233Sopenharmony_ci * You may obtain a copy of the License at
6060ff233Sopenharmony_ci *
7060ff233Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8060ff233Sopenharmony_ci *
9060ff233Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10060ff233Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11060ff233Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12060ff233Sopenharmony_ci * See the License for the specific language governing permissions and
13060ff233Sopenharmony_ci * limitations under the License.
14060ff233Sopenharmony_ci */
15060ff233Sopenharmony_ci
16060ff233Sopenharmony_ci#include "bus_center_client_stub.h"
17060ff233Sopenharmony_ci#include "bus_center_server_proxy.h"
18060ff233Sopenharmony_ci#include "client_bus_center_manager.h"
19060ff233Sopenharmony_ci#include "client_trans_session_manager.h"
20060ff233Sopenharmony_ci#include "comm_log.h"
21060ff233Sopenharmony_ci#include "iproxy_client.h"
22060ff233Sopenharmony_ci#include "ipc_skeleton.h"
23060ff233Sopenharmony_ci#include "softbus_adapter_mem.h"
24060ff233Sopenharmony_ci#include "softbus_adapter_thread.h"
25060ff233Sopenharmony_ci#include "softbus_adapter_timer.h"
26060ff233Sopenharmony_ci#include "softbus_client_context_manager.h"
27060ff233Sopenharmony_ci#include "softbus_client_event_manager.h"
28060ff233Sopenharmony_ci#include "softbus_client_frame_manager.h"
29060ff233Sopenharmony_ci#include "softbus_client_stub_interface.h"
30060ff233Sopenharmony_ci#include "softbus_errcode.h"
31060ff233Sopenharmony_ci#include "softbus_server_ipc_interface_code.h"
32060ff233Sopenharmony_ci#include "softbus_server_proxy.h"
33060ff233Sopenharmony_ci#include "trans_client_stub.h"
34060ff233Sopenharmony_ci#include "trans_server_proxy.h"
35060ff233Sopenharmony_ci
36060ff233Sopenharmony_ci#define INVALID_CB_ID 0xFF
37060ff233Sopenharmony_ci#define CYCLE_NUM_MAX 100
38060ff233Sopenharmony_ci
39060ff233Sopenharmony_cistatic int RegisterServerDeathCb(void);
40060ff233Sopenharmony_cistatic unsigned int g_deathCbId = INVALID_CB_ID;
41060ff233Sopenharmony_cistatic SvcIdentity g_svcIdentity = {0};
42060ff233Sopenharmony_ci
43060ff233Sopenharmony_cistruct SoftBusIpcClientCmd {
44060ff233Sopenharmony_ci    enum SoftBusFuncId code;
45060ff233Sopenharmony_ci    int32_t (*func)(IpcIo *data, IpcIo *reply);
46060ff233Sopenharmony_ci};
47060ff233Sopenharmony_ci
48060ff233Sopenharmony_cistatic struct SoftBusIpcClientCmd g_softBusIpcClientCmdTbl[] = {
49060ff233Sopenharmony_ci    { CLIENT_ON_JOIN_RESULT, ClientOnJoinLNNResult },
50060ff233Sopenharmony_ci    { CLIENT_ON_JOIN_METANODE_RESULT, ClientOnJoinMetaNodeResult },
51060ff233Sopenharmony_ci    { CLIENT_ON_LEAVE_RESULT, ClientOnLeaveLNNResult },
52060ff233Sopenharmony_ci    { CLIENT_ON_LEAVE_METANODE_RESULT, ClientOnLeaveMetaNodeResult },
53060ff233Sopenharmony_ci    { CLIENT_ON_NODE_ONLINE_STATE_CHANGED, ClientOnNodeOnlineStateChanged },
54060ff233Sopenharmony_ci    { CLIENT_ON_NODE_BASIC_INFO_CHANGED, ClientOnNodeBasicInfoChanged },
55060ff233Sopenharmony_ci    { CLIENT_ON_TIME_SYNC_RESULT, ClientOnTimeSyncResult },
56060ff233Sopenharmony_ci    { CLIENT_ON_PUBLISH_LNN_RESULT, ClientOnPublishLNNResult },
57060ff233Sopenharmony_ci    { CLIENT_ON_REFRESH_LNN_RESULT, ClientOnRefreshLNNResult },
58060ff233Sopenharmony_ci    { CLIENT_ON_REFRESH_DEVICE_FOUND, ClientOnRefreshDeviceFound },
59060ff233Sopenharmony_ci    { CLIENT_ON_CHANNEL_OPENED, ClientOnChannelOpened },
60060ff233Sopenharmony_ci    { CLIENT_ON_CHANNEL_OPENFAILED, ClientOnChannelOpenfailed },
61060ff233Sopenharmony_ci    { CLIENT_ON_CHANNEL_CLOSED, ClientOnChannelClosed },
62060ff233Sopenharmony_ci    { CLIENT_ON_CHANNEL_MSGRECEIVED, ClientOnChannelMsgreceived },
63060ff233Sopenharmony_ci    { CLIENT_SET_CHANNEL_INFO, ClientSetChannelInfo },
64060ff233Sopenharmony_ci    { CLIENT_ON_CHANNEL_BIND, ClientOnChannelBind },
65060ff233Sopenharmony_ci};
66060ff233Sopenharmony_ci
67060ff233Sopenharmony_cistatic int ClientIpcInterfaceMsgHandle(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option)
68060ff233Sopenharmony_ci{
69060ff233Sopenharmony_ci    if (data == NULL) {
70060ff233Sopenharmony_ci        COMM_LOGE(COMM_SDK, "invalid param");
71060ff233Sopenharmony_ci        return SOFTBUS_ERR;
72060ff233Sopenharmony_ci    }
73060ff233Sopenharmony_ci
74060ff233Sopenharmony_ci    COMM_LOGI(COMM_SDK, "receive ipc transact code. code=%{public}u", code);
75060ff233Sopenharmony_ci    unsigned int num = sizeof(g_softBusIpcClientCmdTbl) / sizeof(struct SoftBusIpcClientCmd);
76060ff233Sopenharmony_ci    for (unsigned int i = 0; i < num; i++) {
77060ff233Sopenharmony_ci        if (code == g_softBusIpcClientCmdTbl[i].code) {
78060ff233Sopenharmony_ci            return g_softBusIpcClientCmdTbl[i].func(data, reply);
79060ff233Sopenharmony_ci        }
80060ff233Sopenharmony_ci    }
81060ff233Sopenharmony_ci    COMM_LOGE(COMM_SDK, "not support code. code=%{public}u", code);
82060ff233Sopenharmony_ci    return SOFTBUS_ERR;
83060ff233Sopenharmony_ci}
84060ff233Sopenharmony_ci
85060ff233Sopenharmony_cistatic int InnerRegisterService(void)
86060ff233Sopenharmony_ci{
87060ff233Sopenharmony_ci    char *clientName[SOFTBUS_PKGNAME_MAX_NUM] = {0};
88060ff233Sopenharmony_ci    uint32_t clientNameNum = GetSoftBusClientNameList(clientName, SOFTBUS_PKGNAME_MAX_NUM);
89060ff233Sopenharmony_ci    if (clientNameNum == 0) {
90060ff233Sopenharmony_ci        COMM_LOGE(COMM_SDK, "get client name failed");
91060ff233Sopenharmony_ci        return SOFTBUS_ERR;
92060ff233Sopenharmony_ci    }
93060ff233Sopenharmony_ci
94060ff233Sopenharmony_ci    struct CommonScvId svcId = {0};
95060ff233Sopenharmony_ci    if (GetClientIdentity(&svcId.handle, &svcId.token, &svcId.cookie) != SOFTBUS_OK) {
96060ff233Sopenharmony_ci        COMM_LOGE(COMM_SDK, "get client identity failed");
97060ff233Sopenharmony_ci        for (uint32_t i = 0; i < clientNameNum; i++) {
98060ff233Sopenharmony_ci            SoftBusFree(clientName[i]);
99060ff233Sopenharmony_ci        }
100060ff233Sopenharmony_ci        return SOFTBUS_ERR;
101060ff233Sopenharmony_ci    }
102060ff233Sopenharmony_ci    for (uint32_t i = 0; i < clientNameNum; i++) {
103060ff233Sopenharmony_ci        while (RegisterService(clientName[i], &svcId) != SOFTBUS_OK) {
104060ff233Sopenharmony_ci            SoftBusSleepMs(WAIT_SERVER_READY_INTERVAL);
105060ff233Sopenharmony_ci        }
106060ff233Sopenharmony_ci        SoftBusFree(clientName[i]);
107060ff233Sopenharmony_ci    }
108060ff233Sopenharmony_ci
109060ff233Sopenharmony_ci    COMM_LOGD(COMM_SDK, "InnerRegisterService success");
110060ff233Sopenharmony_ci    return SOFTBUS_OK;
111060ff233Sopenharmony_ci}
112060ff233Sopenharmony_ci
113060ff233Sopenharmony_cistatic void UnregisterServerDeathCb(void)
114060ff233Sopenharmony_ci{
115060ff233Sopenharmony_ci    RemoveDeathRecipient(g_svcIdentity, g_deathCbId);
116060ff233Sopenharmony_ci    g_deathCbId = INVALID_CB_ID;
117060ff233Sopenharmony_ci    g_svcIdentity.handle = 0;
118060ff233Sopenharmony_ci    g_svcIdentity.token = 0;
119060ff233Sopenharmony_ci    g_svcIdentity.cookie = 0;
120060ff233Sopenharmony_ci}
121060ff233Sopenharmony_ci
122060ff233Sopenharmony_cistatic void *DeathProcTask(void *arg)
123060ff233Sopenharmony_ci{
124060ff233Sopenharmony_ci    (void)arg;
125060ff233Sopenharmony_ci    CLIENT_NotifyObserver(EVENT_SERVER_DEATH, NULL, 0);
126060ff233Sopenharmony_ci
127060ff233Sopenharmony_ci    ServerProxyDeInit();
128060ff233Sopenharmony_ci    TransServerProxyDeInit();
129060ff233Sopenharmony_ci    BusCenterServerProxyDeInit();
130060ff233Sopenharmony_ci
131060ff233Sopenharmony_ci    ListNode sessionServerInfoList;
132060ff233Sopenharmony_ci    ListInit(&sessionServerInfoList);
133060ff233Sopenharmony_ci    ClientCleanAllSessionWhenServerDeath(&sessionServerInfoList);
134060ff233Sopenharmony_ci
135060ff233Sopenharmony_ci    int32_t cnt = 0;
136060ff233Sopenharmony_ci    for (cnt = 0; cnt < CYCLE_NUM_MAX; cnt++) {
137060ff233Sopenharmony_ci        if (ServerProxyInit() == SOFTBUS_OK) {
138060ff233Sopenharmony_ci            COMM_LOGI(COMM_SDK, "proxy init wait sucess");
139060ff233Sopenharmony_ci            break;
140060ff233Sopenharmony_ci        }
141060ff233Sopenharmony_ci        SoftBusSleepMs(WAIT_SERVER_READY_SHORT_INTERVAL);
142060ff233Sopenharmony_ci        COMM_LOGI(COMM_SDK, "proxy init wait");
143060ff233Sopenharmony_ci    }
144060ff233Sopenharmony_ci
145060ff233Sopenharmony_ci    if (cnt == CYCLE_NUM_MAX) {
146060ff233Sopenharmony_ci        COMM_LOGE(COMM_SDK, "server proxy init reached the maximum count=%{public}d", cnt);
147060ff233Sopenharmony_ci        return NULL;
148060ff233Sopenharmony_ci    }
149060ff233Sopenharmony_ci
150060ff233Sopenharmony_ci    if (InnerRegisterService() != SOFTBUS_OK) {
151060ff233Sopenharmony_ci        COMM_LOGE(COMM_SDK, "register service failed");
152060ff233Sopenharmony_ci        return NULL;
153060ff233Sopenharmony_ci    }
154060ff233Sopenharmony_ci
155060ff233Sopenharmony_ci    TransServerProxyInit();
156060ff233Sopenharmony_ci    BusCenterServerProxyInit();
157060ff233Sopenharmony_ci    DiscRecoveryPublish();
158060ff233Sopenharmony_ci    DiscRecoverySubscribe();
159060ff233Sopenharmony_ci
160060ff233Sopenharmony_ci    COMM_LOGI(COMM_SDK, "\n<< !!! SERVICE (%{public}s) RECOVER !!! >>\n", SOFTBUS_SERVICE);
161060ff233Sopenharmony_ci    CLIENT_NotifyObserver(EVENT_SERVER_RECOVERY, NULL, 0);
162060ff233Sopenharmony_ci    UnregisterServerDeathCb();
163060ff233Sopenharmony_ci
164060ff233Sopenharmony_ci    if (RegisterServerDeathCb() != SOFTBUS_OK) {
165060ff233Sopenharmony_ci        COMM_LOGE(COMM_SDK, "reg server death cb failed");
166060ff233Sopenharmony_ci        return NULL;
167060ff233Sopenharmony_ci    }
168060ff233Sopenharmony_ci
169060ff233Sopenharmony_ci    return NULL;
170060ff233Sopenharmony_ci}
171060ff233Sopenharmony_ci
172060ff233Sopenharmony_cistatic int StartDeathProcTask(void)
173060ff233Sopenharmony_ci{
174060ff233Sopenharmony_ci    int ret;
175060ff233Sopenharmony_ci    SoftBusThreadAttr threadAttr;
176060ff233Sopenharmony_ci    SoftBusThread tid;
177060ff233Sopenharmony_ci    ret = SoftBusThreadAttrInit(&threadAttr);
178060ff233Sopenharmony_ci    if (ret != 0) {
179060ff233Sopenharmony_ci        COMM_LOGE(COMM_SDK, "Thread attr init failed, ret=%{public}d", ret);
180060ff233Sopenharmony_ci        return SOFTBUS_ERR;
181060ff233Sopenharmony_ci    }
182060ff233Sopenharmony_ci
183060ff233Sopenharmony_ci    threadAttr.detachState = SOFTBUS_THREAD_DETACH;
184060ff233Sopenharmony_ci    threadAttr.policy = SOFTBUS_SCHED_RR;
185060ff233Sopenharmony_ci    threadAttr.taskName = "OS_deathTsk";
186060ff233Sopenharmony_ci    ret = SoftBusThreadCreate(&tid, &threadAttr, DeathProcTask, NULL);
187060ff233Sopenharmony_ci    if (ret != 0) {
188060ff233Sopenharmony_ci        COMM_LOGE(COMM_SDK, "create DeathProcTask failed, ret=%{public}d", ret);
189060ff233Sopenharmony_ci        return SOFTBUS_ERR;
190060ff233Sopenharmony_ci    }
191060ff233Sopenharmony_ci
192060ff233Sopenharmony_ci    return ret;
193060ff233Sopenharmony_ci}
194060ff233Sopenharmony_ci
195060ff233Sopenharmony_cistatic void DeathCallback(void)
196060ff233Sopenharmony_ci{
197060ff233Sopenharmony_ci    COMM_LOGW(COMM_SDK, "\n<< ATTENTION !!! >> SERVICE (%{public}s) DEAD !!!\n", SOFTBUS_SERVICE);
198060ff233Sopenharmony_ci
199060ff233Sopenharmony_ci    if (StartDeathProcTask() != SOFTBUS_OK) {
200060ff233Sopenharmony_ci        COMM_LOGE(COMM_SDK, "start death proc task failed");
201060ff233Sopenharmony_ci    }
202060ff233Sopenharmony_ci    COMM_LOGI(COMM_SDK, "client start check softbus server...");
203060ff233Sopenharmony_ci}
204060ff233Sopenharmony_ci
205060ff233Sopenharmony_cistatic int RegisterServerDeathCb(void)
206060ff233Sopenharmony_ci{
207060ff233Sopenharmony_ci    g_svcIdentity = SAMGR_GetRemoteIdentity(SOFTBUS_SERVICE, NULL);
208060ff233Sopenharmony_ci    g_deathCbId = INVALID_CB_ID;
209060ff233Sopenharmony_ci    if (AddDeathRecipient(g_svcIdentity, DeathCallback, NULL, &g_deathCbId) != EC_SUCCESS) {
210060ff233Sopenharmony_ci        COMM_LOGE(COMM_SDK, "reg death callback failed");
211060ff233Sopenharmony_ci        return SOFTBUS_ERR;
212060ff233Sopenharmony_ci    }
213060ff233Sopenharmony_ci    return SOFTBUS_OK;
214060ff233Sopenharmony_ci}
215060ff233Sopenharmony_ci
216060ff233Sopenharmony_ciint ClientStubInit(void)
217060ff233Sopenharmony_ci{
218060ff233Sopenharmony_ci    if (ServerProxyInit() != SOFTBUS_OK) {
219060ff233Sopenharmony_ci        COMM_LOGE(COMM_SDK, "server proxy init failed.");
220060ff233Sopenharmony_ci        return SOFTBUS_ERR;
221060ff233Sopenharmony_ci    }
222060ff233Sopenharmony_ci
223060ff233Sopenharmony_ci    static IpcObjectStub objectStub = {
224060ff233Sopenharmony_ci        .func = ClientIpcInterfaceMsgHandle,
225060ff233Sopenharmony_ci        .args = NULL,
226060ff233Sopenharmony_ci        .isRemote = false
227060ff233Sopenharmony_ci    };
228060ff233Sopenharmony_ci    SvcIdentity clientIdentity = {
229060ff233Sopenharmony_ci        .handle = IPC_INVALID_HANDLE,
230060ff233Sopenharmony_ci        .token = SERVICE_TYPE_ANONYMOUS,
231060ff233Sopenharmony_ci        .cookie = (uintptr_t)&objectStub
232060ff233Sopenharmony_ci    };
233060ff233Sopenharmony_ci
234060ff233Sopenharmony_ci    int ret = ClientContextInit();
235060ff233Sopenharmony_ci    if (ret != SOFTBUS_OK) {
236060ff233Sopenharmony_ci        COMM_LOGE(COMM_SDK, "client context init failed.");
237060ff233Sopenharmony_ci        return SOFTBUS_ERR;
238060ff233Sopenharmony_ci    }
239060ff233Sopenharmony_ci    SetClientIdentity(clientIdentity.handle, clientIdentity.token, clientIdentity.cookie);
240060ff233Sopenharmony_ci    if (RegisterServerDeathCb() != SOFTBUS_OK) {
241060ff233Sopenharmony_ci        ClientContextDeinit();
242060ff233Sopenharmony_ci        COMM_LOGE(COMM_SDK, "reg server death cb failed");
243060ff233Sopenharmony_ci        return SOFTBUS_ERR;
244060ff233Sopenharmony_ci    }
245060ff233Sopenharmony_ci
246060ff233Sopenharmony_ci    return SOFTBUS_OK;
247060ff233Sopenharmony_ci}
248060ff233Sopenharmony_ci
249060ff233Sopenharmony_ciint ClientRegisterService(const char *pkgName)
250060ff233Sopenharmony_ci{
251060ff233Sopenharmony_ci    struct CommonScvId svcId = {0};
252060ff233Sopenharmony_ci    if (GetClientIdentity(&svcId.handle, &svcId.token, &svcId.cookie) != SOFTBUS_OK) {
253060ff233Sopenharmony_ci        COMM_LOGE(COMM_SDK, "get client identity failed");
254060ff233Sopenharmony_ci        return SOFTBUS_ERR;
255060ff233Sopenharmony_ci    }
256060ff233Sopenharmony_ci
257060ff233Sopenharmony_ci    while (RegisterService(pkgName, &svcId) != SOFTBUS_OK) {
258060ff233Sopenharmony_ci        SoftBusSleepMs(WAIT_SERVER_READY_INTERVAL);
259060ff233Sopenharmony_ci    }
260060ff233Sopenharmony_ci
261060ff233Sopenharmony_ci    COMM_LOGI(COMM_SDK, "ClientRegisterService success");
262060ff233Sopenharmony_ci    return SOFTBUS_OK;
263060ff233Sopenharmony_ci}
264