1 /*
2 * Copyright (c) 2021-2025 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 "client_trans_tcp_direct_listener.h"
17
18 #include <stdbool.h>
19 #include <unistd.h>
20 #include <securec.h>
21 #include <stdatomic.h>
22
23 #include "client_trans_tcp_direct_callback.h"
24 #include "client_trans_tcp_direct_manager.h"
25 #include "client_trans_tcp_direct_message.h"
26 #include "softbus_adapter_thread.h"
27 #include "softbus_base_listener.h"
28 #include "softbus_error_code.h"
29 #include "softbus_socket.h"
30 #include "trans_log.h"
31
32 typedef struct {
33 SoftBusMutex lock;
34 _Atomic bool lockInit;
35 } SoftBusTcpListenerLock;
36
37 static SoftBusTcpListenerLock g_lock = {
38 .lockInit = false,
39 };
40 static bool g_isInitedFlag = false;
41
42
TdcLockInit(void)43 static void TdcLockInit(void)
44 {
45 if (!atomic_load_explicit(&(g_lock.lockInit), memory_order_acquire)) {
46 if (SoftBusMutexInit(&g_lock.lock, NULL) != SOFTBUS_OK) {
47 TRANS_LOGE(TRANS_INIT, "TDC lock init failed");
48 return;
49 }
50 atomic_store_explicit(&(g_lock.lockInit), true, memory_order_release);
51 }
52 }
53
TdcLockDeinit(void)54 void TdcLockDeinit(void)
55 {
56 g_lock.lockInit = false;
57 (void)SoftBusMutexDestroy(&g_lock.lock);
58 }
59
ClientTdcOnConnectEvent(ListenerModule module,int cfd,const ConnectOption * clientAddr)60 static int32_t ClientTdcOnConnectEvent(ListenerModule module, int cfd,
61 const ConnectOption *clientAddr)
62 {
63 (void)module;
64 (void)cfd;
65 (void)clientAddr;
66 return SOFTBUS_OK;
67 }
68
ClientTdcOnDataEvent(ListenerModule module,int events,int32_t fd)69 static int32_t ClientTdcOnDataEvent(ListenerModule module, int events, int32_t fd)
70 {
71 TcpDirectChannelInfo channel;
72 (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo));
73
74 int32_t ret = TransTdcGetInfoByFd(fd, &channel);
75 if (ret != SOFTBUS_OK) {
76 (void)DelTrigger(module, fd, RW_TRIGGER);
77 TRANS_LOGE(TRANS_SDK, "can not match fd. release fd=%{public}d, ret=%{public}d", fd, ret);
78 return ret;
79 }
80
81 if (events == SOFTBUS_SOCKET_IN) {
82 int32_t channelId = channel.channelId;
83 ret = TransTdcRecvData(channelId);
84 if (ret == SOFTBUS_DATA_NOT_ENOUGH) {
85 TRANS_LOGW(TRANS_SDK, "client process data fail, SOFTBUS_DATA_NOT_ENOUGH. channelId=%{public}d", channelId);
86 return SOFTBUS_OK;
87 }
88 if (ret != SOFTBUS_OK) {
89 TRANS_LOGE(TRANS_SDK, "client process data fail, channelId=%{public}d, ret=%{public}d", channelId, ret);
90 TransDelDataBufNode(channelId);
91 TransTdcCloseChannel(channelId);
92 ClientTransTdcOnSessionClosed(channelId, SHUTDOWN_REASON_RECV_DATA_ERR);
93 return ret;
94 }
95 }
96 return SOFTBUS_OK;
97 }
98
TransTdcCreateListener(int32_t fd)99 int32_t TransTdcCreateListener(int32_t fd)
100 {
101 TdcLockInit();
102 if (SoftBusMutexLock(&g_lock.lock) != SOFTBUS_OK) {
103 TRANS_LOGE(TRANS_SDK, "lock failed.");
104 return SOFTBUS_LOCK_ERR;
105 }
106 if (!g_isInitedFlag) {
107 static SoftbusBaseListener listener = {
108 .onConnectEvent = ClientTdcOnConnectEvent,
109 .onDataEvent = ClientTdcOnDataEvent,
110 };
111 int32_t ret = StartBaseClient(DIRECT_CHANNEL_CLIENT, &listener);
112 if (ret != SOFTBUS_OK) {
113 TRANS_LOGE(TRANS_SDK, "start sdk base listener failed, ret=%{public}d", ret);
114 SoftBusMutexUnlock(&g_lock.lock);
115 return ret;
116 }
117 g_isInitedFlag = true;
118 TRANS_LOGI(TRANS_SDK, "create sdk listener success. fd=%{public}d", fd);
119 }
120 SoftBusMutexUnlock(&g_lock.lock);
121
122 return AddTrigger(DIRECT_CHANNEL_CLIENT, fd, READ_TRIGGER);
123 }
124
TransTdcCreateListenerWithoutAddTrigger(int32_t fd)125 int32_t TransTdcCreateListenerWithoutAddTrigger(int32_t fd)
126 {
127 TdcLockInit();
128 if (SoftBusMutexLock(&g_lock.lock) != SOFTBUS_OK) {
129 TRANS_LOGE(TRANS_SDK, "lock failed.");
130 return SOFTBUS_LOCK_ERR;
131 }
132 if (!g_isInitedFlag) {
133 static SoftbusBaseListener listener = {
134 .onConnectEvent = ClientTdcOnConnectEvent,
135 .onDataEvent = ClientTdcOnDataEvent,
136 };
137 int32_t ret = StartBaseClient(DIRECT_CHANNEL_CLIENT, &listener);
138 if (ret != SOFTBUS_OK) {
139 TRANS_LOGE(TRANS_SDK, "start sdk base listener failed, ret=%{public}d", ret);
140 SoftBusMutexUnlock(&g_lock.lock);
141 return ret;
142 }
143 g_isInitedFlag = true;
144 TRANS_LOGI(TRANS_SDK, "create sdk listener success.fd=%{public}d", fd);
145 }
146 SoftBusMutexUnlock(&g_lock.lock);
147
148 return SOFTBUS_OK;
149 }
150
TransTdcCloseFd(int32_t fd)151 void TransTdcCloseFd(int32_t fd)
152 {
153 if (fd < 0) {
154 TRANS_LOGI(TRANS_SDK, "fd less than zero");
155 return;
156 }
157 DelTrigger(DIRECT_CHANNEL_CLIENT, fd, READ_TRIGGER);
158 if (ConnGetSocketError(fd) == SOFTBUS_CONN_BAD_FD) {
159 TRANS_LOGI(TRANS_SDK, "fd is bad fd=%{public}d", fd);
160 return;
161 }
162 ConnCloseSocket(fd);
163 }
164
TransTdcReleaseFd(int32_t fd)165 void TransTdcReleaseFd(int32_t fd)
166 {
167 if (fd < 0) {
168 TRANS_LOGI(TRANS_SDK, "fd less than zero");
169 return;
170 }
171 (void)DelTrigger(DIRECT_CHANNEL_CLIENT, fd, RW_TRIGGER);
172 if (ConnGetSocketError(fd) == SOFTBUS_CONN_BAD_FD) {
173 TRANS_LOGI(TRANS_SDK, "fd is bad fd=%{public}d", fd);
174 return;
175 }
176 ConnShutdownSocket(fd);
177 }
178
TransTdcStopRead(int32_t fd)179 int32_t TransTdcStopRead(int32_t fd)
180 {
181 if (fd < 0) {
182 TRANS_LOGI(TRANS_SDK, "fd less than zero");
183 return SOFTBUS_OK;
184 }
185 return DelTrigger(DIRECT_CHANNEL_CLIENT, fd, READ_TRIGGER);
186 }
187