• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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