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