1cc290419Sopenharmony_ci/* 2cc290419Sopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd. 3cc290419Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4cc290419Sopenharmony_ci * you may not use this file except in compliance with the License. 5cc290419Sopenharmony_ci * You may obtain a copy of the License at 6cc290419Sopenharmony_ci * 7cc290419Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8cc290419Sopenharmony_ci * 9cc290419Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10cc290419Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11cc290419Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12cc290419Sopenharmony_ci * See the License for the specific language governing permissions and 13cc290419Sopenharmony_ci * limitations under the License. 14cc290419Sopenharmony_ci */ 15cc290419Sopenharmony_ci#include "daemon_bridge.h" 16cc290419Sopenharmony_ci#include <cstdlib> 17cc290419Sopenharmony_ci#include "arpa/inet.h" 18cc290419Sopenharmony_ci#include "netinet/in.h" 19cc290419Sopenharmony_ci#include "new" 20cc290419Sopenharmony_ci#include "sys/socket.h" 21cc290419Sopenharmony_ci#include "system_depend.h" 22cc290419Sopenharmony_ci#include "unistd.h" 23cc290419Sopenharmony_ci#include "common.h" 24cc290419Sopenharmony_ci#include "session.h" 25cc290419Sopenharmony_ci#include "uv-common.h" 26cc290419Sopenharmony_ci 27cc290419Sopenharmony_cinamespace Hdc { 28cc290419Sopenharmony_ci HdcDaemonBridge::HdcDaemonBridge(const bool serverOrDaemonIn, void *ptrMainBase) 29cc290419Sopenharmony_ci : HdcTCPBase(serverOrDaemonIn, ptrMainBase) 30cc290419Sopenharmony_ci { 31cc290419Sopenharmony_ci // If the listening value for the property setting is obtained, it will be 0 randomly assigned. 32cc290419Sopenharmony_ci string strBridgePort; 33cc290419Sopenharmony_ci SystemDepend::GetDevItem("persist.hdc.port", strBridgePort); 34cc290419Sopenharmony_ci bridgeListenPort = atoi(strBridgePort.c_str()); 35cc290419Sopenharmony_ci if (bridgeListenPort <= 0) { 36cc290419Sopenharmony_ci bridgeListenPort = 0; 37cc290419Sopenharmony_ci } 38cc290419Sopenharmony_ci#ifdef HDC_DEBUG 39cc290419Sopenharmony_ci const uint16_t DEBUG_TCP_PORT = 10178; 40cc290419Sopenharmony_ci bridgeListenPort = DEBUG_TCP_PORT; 41cc290419Sopenharmony_ci#endif 42cc290419Sopenharmony_ci } 43cc290419Sopenharmony_ci 44cc290419Sopenharmony_ci HdcDaemonBridge::~HdcDaemonBridge() 45cc290419Sopenharmony_ci { 46cc290419Sopenharmony_ci } 47cc290419Sopenharmony_ci 48cc290419Sopenharmony_ci void HdcDaemonBridge::Stop() 49cc290419Sopenharmony_ci { 50cc290419Sopenharmony_ci Base::TryCloseHandle((const uv_handle_t *)&servPipe); 51cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "~HdcDaemonBridge"); 52cc290419Sopenharmony_ci } 53cc290419Sopenharmony_ci 54cc290419Sopenharmony_ci void HdcDaemonBridge::AllocBufferCallback(uv_handle_t *handle, size_t sizeSuggested, uv_buf_t *buf) 55cc290419Sopenharmony_ci { 56cc290419Sopenharmony_ci buf->base = (char *)new int[1]; 57cc290419Sopenharmony_ci buf->len = SOCKET_FD_LEN; 58cc290419Sopenharmony_ci } 59cc290419Sopenharmony_ci 60cc290419Sopenharmony_ci void HdcDaemonBridge::AcceptClient(uv_stream_t *uvpipe, ssize_t nread, const uv_buf_t *buf) 61cc290419Sopenharmony_ci { 62cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "Accept New Client"); 63cc290419Sopenharmony_ci uv_loop_t *ptrLoop = uvpipe->loop; 64cc290419Sopenharmony_ci uv_tcp_t *pServBridge = (uv_tcp_t *)uvpipe; 65cc290419Sopenharmony_ci HdcDaemonBridge *thisClass = (HdcDaemonBridge *)pServBridge->data; 66cc290419Sopenharmony_ci HdcSessionBase *ptrConnect = reinterpret_cast<HdcSessionBase *>(thisClass->clsMainBase); 67cc290419Sopenharmony_ci const uint16_t maxWaitTime = UV_DEFAULT_INTERVAL; 68cc290419Sopenharmony_ci int newPort = *(int *)buf->base; 69cc290419Sopenharmony_ci int newClientFd; 70cc290419Sopenharmony_ci int ret = 0; 71cc290419Sopenharmony_ci if (nread != SOCKET_FD_LEN) { 72cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "AcceptClient err nread %d", nread); 73cc290419Sopenharmony_ci return; 74cc290419Sopenharmony_ci } 75cc290419Sopenharmony_ci auto ctrl = ptrConnect->BuildCtrlString(SP_START_SESSION, 0, nullptr, 0); 76cc290419Sopenharmony_ci HSession hSession = ptrConnect->MallocSession(false, CONN_TCP, thisClass); 77cc290419Sopenharmony_ci if (!hSession) { 78cc290419Sopenharmony_ci goto freeBuf; 79cc290419Sopenharmony_ci } 80cc290419Sopenharmony_ci 81cc290419Sopenharmony_ci newClientFd = open("/dev/express_bridge", O_RDWR | O_NONBLOCK); 82cc290419Sopenharmony_ci if (newClientFd < 0) { 83cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "Unable to open new bridge connection err %d", errno); 84cc290419Sopenharmony_ci goto freeSession; 85cc290419Sopenharmony_ci } 86cc290419Sopenharmony_ci ret = ioctl(newClientFd, IOC_CONNECT, static_cast<unsigned long>(newPort)); 87cc290419Sopenharmony_ci if (ret < 0) { 88cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "Unable to ioctl new bridge err %d", errno); 89cc290419Sopenharmony_ci goto freeFd; 90cc290419Sopenharmony_ci } 91cc290419Sopenharmony_ci hSession->fdChildWorkTCP = (uv_os_sock_t)newClientFd; 92cc290419Sopenharmony_ci Base::StartWorkThread(ptrLoop, ptrConnect->SessionWorkThread, Base::FinishWorkThread, hSession); 93cc290419Sopenharmony_ci // wait for thread up 94cc290419Sopenharmony_ci while (hSession->childLoop.active_handles == 0) { 95cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "wait for thread up"); 96cc290419Sopenharmony_ci usleep(maxWaitTime); 97cc290419Sopenharmony_ci } 98cc290419Sopenharmony_ci Base::SendToPollFd(hSession->ctrlFd[STREAM_MAIN], ctrl.data(), ctrl.size()); 99cc290419Sopenharmony_ci goto freeBuf; 100cc290419Sopenharmony_ci 101cc290419Sopenharmony_ci freeFd: 102cc290419Sopenharmony_ci close(newClientFd); 103cc290419Sopenharmony_ci freeSession: 104cc290419Sopenharmony_ci ptrConnect->FreeSession(hSession->sessionId); 105cc290419Sopenharmony_ci freeBuf: 106cc290419Sopenharmony_ci delete[] buf->base; 107cc290419Sopenharmony_ci return; 108cc290419Sopenharmony_ci } 109cc290419Sopenharmony_ci 110cc290419Sopenharmony_ci // Set the daemon-side TCP listening 111cc290419Sopenharmony_ci int HdcDaemonBridge::SetBridgeListen() 112cc290419Sopenharmony_ci { 113cc290419Sopenharmony_ci // tcp listen 114cc290419Sopenharmony_ci HdcSessionBase *ptrConnect = (HdcSessionBase *)clsMainBase; 115cc290419Sopenharmony_ci servPipe.data = this; 116cc290419Sopenharmony_ci int bridgeFd = open("/dev/express_bridge", O_RDWR | O_NONBLOCK); 117cc290419Sopenharmony_ci if (bridgeFd <= 0) { 118cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "SetBridgeListen open failed"); 119cc290419Sopenharmony_ci return ERR_FILE_OPEN; 120cc290419Sopenharmony_ci } 121cc290419Sopenharmony_ci int ret = ioctl(bridgeFd, IOC_BIND, (unsigned long)bridgeListenPort); 122cc290419Sopenharmony_ci if (ret < 0) { 123cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "SetBridgeListen IOC_BIND failed"); 124cc290419Sopenharmony_ci close(bridgeFd); 125cc290419Sopenharmony_ci return ERR_API_FAIL; 126cc290419Sopenharmony_ci } 127cc290419Sopenharmony_ci 128cc290419Sopenharmony_ci uv_pipe_init(&ptrConnect->loopMain, &servPipe, 0); 129cc290419Sopenharmony_ci uv_pipe_open(&servPipe, (uv_file)bridgeFd); 130cc290419Sopenharmony_ci uv_read_start((uv_stream_t *)&servPipe, HdcDaemonBridge::AllocBufferCallback, HdcDaemonBridge::AcceptClient); 131cc290419Sopenharmony_ci 132cc290419Sopenharmony_ci return RET_SUCCESS; 133cc290419Sopenharmony_ci } 134cc290419Sopenharmony_ci 135cc290419Sopenharmony_ci int HdcDaemonBridge::Initial() 136cc290419Sopenharmony_ci { 137cc290419Sopenharmony_ci WRITE_LOG(LOG_DEBUG, "HdcDaemonBridge init"); 138cc290419Sopenharmony_ci if (SetBridgeListen() != RET_SUCCESS) { 139cc290419Sopenharmony_ci WRITE_LOG(LOG_FATAL, "Bridge listen failed"); 140cc290419Sopenharmony_ci return ERR_GENERIC; 141cc290419Sopenharmony_ci } 142cc290419Sopenharmony_ci#ifndef UNIT_TEST 143cc290419Sopenharmony_ci WRITE_LOG(LOG_INFO, "Bridge listen on port:[%d]", bridgeListenPort); 144cc290419Sopenharmony_ci#endif 145cc290419Sopenharmony_ci return RET_SUCCESS; 146cc290419Sopenharmony_ci } 147cc290419Sopenharmony_ci} // namespace Hdc 148