1/* 2 * Copyright (C) 2024 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 "bridge.h" 17#include "log.h" 18#include "sys_para.h" 19#include "base.h" 20 21#include <unistd.h> 22#include <fcntl.h> 23namespace Hdc { 24static uint8_t *g_bridgeReadBuf = nullptr; 25static constexpr char BRIDGE_FILE_PATH[20] = "/dev/express_bridge"; 26 27HdcBridge::HdcBridge() 28{ 29 string strBridgePort; 30 GetDevItem("persist.hdc.port", strBridgePort); 31 WRITE_LOG(LOG_INFO, "strBridgePort:%s", strBridgePort.c_str()); 32 bridgeListenPort = atoi(strBridgePort.c_str()); 33 if (bridgeListenPort <= 0) { 34 bridgeListenPort = 0; 35 } 36 WRITE_LOG(LOG_INFO, "bridgeListenPort:%d", bridgeListenPort); 37} 38 39HdcBridge::~HdcBridge() 40{ 41} 42 43int HdcBridge::StartListen() 44{ 45 bridgeFd = open(BRIDGE_FILE_PATH, O_RDWR); 46 WRITE_LOG(LOG_INFO, "StartListen bridgeFd:%d", bridgeFd); 47 if (bridgeFd <= 0) { 48 WRITE_LOG(LOG_FATAL, "SetBridgeListen open failed"); 49 return -1; 50 } 51 int ret = ioctl(bridgeFd, IOC_BIND, static_cast<unsigned long>(bridgeListenPort)); 52 WRITE_LOG(LOG_INFO, "StartListen ioctl ret:%d", ret); 53 if (ret < 0) { 54 WRITE_LOG(LOG_FATAL, "SetBridgeListen IOC_BIND failed"); 55 return -1; 56 } 57 return bridgeFd; 58} 59 60int HdcBridge::HandleClient(int socketFd) 61{ 62 int newClientFd = open(BRIDGE_FILE_PATH, O_RDWR); 63 WRITE_LOG(LOG_INFO, "HandleClient newClientFd:%d", newClientFd); 64 if (newClientFd < 0) { 65 WRITE_LOG(LOG_FATAL, "Unable to open new bridge connection err %d", errno); 66 return -1; 67 } 68 errno = 0; 69 int ret = ioctl(newClientFd, IOC_CONNECT, static_cast<unsigned long>(socketFd)); 70 if (ret < 0) { 71 WRITE_LOG(LOG_FATAL, "Unable to ioctl new bridge err %d", errno); 72 close(newClientFd); 73 return -1; 74 } 75 return newClientFd; 76} 77 78int HdcBridge::ReadPipeFd(int fd, char* buf, int size) 79{ 80 WRITE_LOG(LOG_INFO, "ReadPipeFd start"); 81 return read(fd, buf, size); 82} 83 84PersistBuffer HdcBridge::ReadClient(int fd, int size) 85{ 86 if (g_bridgeReadBuf == nullptr) { 87 WRITE_LOG(LOG_DEBUG, "remalloc g_bridgeReadBuf"); 88 g_bridgeReadBuf = new uint8_t[MAX_SIZE_IOBUF]; 89 } 90 int readSize = read(fd, g_bridgeReadBuf, size); 91 return PersistBuffer{reinterpret_cast<char *>(g_bridgeReadBuf), static_cast<uint64_t>(readSize)}; 92} 93 94int HdcBridge::WriteClient(int fd, SerializedBuffer buf) 95{ 96 uint8_t* ptr = reinterpret_cast<uint8_t *>(buf.ptr); 97 size_t size = static_cast<size_t>(buf.size); 98 int cnt = static_cast<int>(size); 99 constexpr int intrmax = 1000; 100 int intrcnt = 0; 101 while (cnt > 0) { 102 int rc = write(fd, ptr, cnt); 103 if (rc < 0) { 104 int err = errno; 105 if (err != EINTR && err != EAGAIN) { 106 WRITE_LOG(LOG_FATAL, "WriteClient fd:%d send rc:%d err:%d", fd, rc, err); 107 cnt = -1; 108 break; 109 } 110 if (++intrcnt > intrmax) { 111 WRITE_LOG(LOG_WARN, "WriteClient fd:%d send interrupt err:%d", fd, err); 112 intrcnt = 0; 113 } 114 continue; 115 } 116 ptr += rc; 117 cnt -= rc; 118 } 119 return cnt == 0 ? static_cast<int>(size) : cnt; 120} 121 122void HdcBridge::Stop() 123{ 124 if (bridgeFd > 0) { 125 close(bridgeFd); 126 bridgeFd = -1; 127 } 128 129 if (g_bridgeReadBuf != nullptr) { 130 delete[] g_bridgeReadBuf; 131 g_bridgeReadBuf = nullptr; 132 } 133} 134 135extern "C" void* InitBridge() 136{ 137 HdcBridge* instance = new HdcBridge(); 138 return instance; 139} 140 141extern "C" int StartListen(void* ptr) 142{ 143 HdcBridge* bridge = (HdcBridge*)ptr; 144 if (bridge == nullptr) { 145 return -1; 146 } 147 return bridge->StartListen(); 148} 149 150extern "C" int AcceptServerSocketFd(void* ptr, int pipeFd) 151{ 152 WRITE_LOG(LOG_INFO, "AcceptServerSocketFd start, pipeFd:%d", pipeFd); 153 HdcBridge* bridge = (HdcBridge*)ptr; 154 if (bridge == nullptr) { 155 return -1; 156 } 157 char socketFdBuf[4] = { 0 }; 158 int ret = bridge->ReadPipeFd(pipeFd, socketFdBuf, 4); 159 WRITE_LOG(LOG_INFO, "AcceptServerSocketFd get socketfd buf size:%d", ret); 160 if (ret < 0) { 161 WRITE_LOG(LOG_INFO, "AcceptServerSocketFd get socket fd fail"); 162 return -1; 163 } 164 int socketFd = *reinterpret_cast<int*>(socketFdBuf); 165 WRITE_LOG(LOG_INFO, "AcceptServerSocketFd get socketfd:%d", socketFd); 166 return socketFd; 167} 168 169extern "C" int InitClientFd(void* ptr, int socketFd) 170{ 171 HdcBridge* bridge = (HdcBridge*)ptr; 172 if (bridge == nullptr) { 173 return -1; 174 } 175 return bridge->HandleClient(socketFd); 176} 177 178extern "C" PersistBuffer ReadClient(void* ptr, int fd, int size) 179{ 180 HdcBridge* bridge = (HdcBridge*)ptr; 181 if (bridge == nullptr) { 182 return PersistBuffer{reinterpret_cast<char *>(0), static_cast<uint64_t>(0)}; 183 } 184 return bridge->ReadClient(fd, size); 185} 186 187extern "C" int WriteClient(void* ptr, int fd, SerializedBuffer buf) 188{ 189 HdcBridge* bridge = (HdcBridge*)ptr; 190 if (bridge == nullptr) { 191 return -1; 192 } 193 return bridge->WriteClient(fd, buf); 194} 195 196extern "C" int Stop(void* ptr) 197{ 198 HdcBridge* bridge = (HdcBridge*)ptr; 199 if (bridge == nullptr) { 200 return -1; 201 } 202 bridge->Stop(); 203 return 0; 204} 205} 206 207