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>
23 namespace Hdc {
24 static uint8_t *g_bridgeReadBuf = nullptr;
25 static constexpr char BRIDGE_FILE_PATH[20] = "/dev/express_bridge";
26
HdcBridge()27 HdcBridge::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
~HdcBridge()39 HdcBridge::~HdcBridge()
40 {
41 }
42
StartListen()43 int 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
HandleClient(int socketFd)60 int 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
ReadPipeFd(int fd,char * buf,int size)78 int HdcBridge::ReadPipeFd(int fd, char* buf, int size)
79 {
80 WRITE_LOG(LOG_INFO, "ReadPipeFd start");
81 return read(fd, buf, size);
82 }
83
ReadClient(int fd,int size)84 PersistBuffer 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
WriteClient(int fd,SerializedBuffer buf)94 int 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 = 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 ? size : cnt;
120 }
121
Stop()122 void 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
InitBridge()135 extern "C" void* InitBridge()
136 {
137 HdcBridge* instance = new HdcBridge();
138 return instance;
139 }
140
StartListen(void * ptr)141 extern "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
AcceptServerSocketFd(void * ptr,int pipeFd)150 extern "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
InitClientFd(void * ptr,int socketFd)169 extern "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
ReadClient(void * ptr,int fd,int size)178 extern "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
WriteClient(void * ptr,int fd,SerializedBuffer buf)187 extern "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
Stop(void * ptr)196 extern "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