1 /*
2 * Copyright (c) 2021-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 "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 if (TransTdcGetInfoByFd(fd, &channel) != SOFTBUS_OK) {
74 (void)DelTrigger(module, fd, RW_TRIGGER);
75 TRANS_LOGE(TRANS_SDK, "can not match fd. release fd=%{public}d", fd);
76 return SOFTBUS_MEM_ERR;
77 }
78
79 if (events == SOFTBUS_SOCKET_IN) {
80 int32_t channelId = channel.channelId;
81 int32_t ret = TransTdcRecvData(channelId);
82 if (ret == SOFTBUS_DATA_NOT_ENOUGH) {
83 TRANS_LOGE(TRANS_SDK, "client process data fail, SOFTBUS_DATA_NOT_ENOUGH. channelId=%{public}d", channelId);
84 return SOFTBUS_OK;
85 }
86 if (ret != SOFTBUS_OK) {
87 TRANS_LOGE(TRANS_SDK, "client process data fail, channelId=%{public}d, ret=%{public}d", channelId, ret);
88 TransDelDataBufNode(channelId);
89 TransTdcCloseChannel(channelId);
90 ClientTransTdcOnSessionClosed(channelId, SHUTDOWN_REASON_RECV_DATA_ERR);
91 return ret;
92 }
93 }
94 return SOFTBUS_OK;
95 }
96
TransTdcCreateListener(int32_t fd)97 int32_t TransTdcCreateListener(int32_t fd)
98 {
99 TdcLockInit();
100 if (SoftBusMutexLock(&g_lock.lock) != SOFTBUS_OK) {
101 TRANS_LOGE(TRANS_SDK, "lock failed.");
102 return SOFTBUS_LOCK_ERR;
103 }
104 if (g_isInitedFlag == false) {
105 g_isInitedFlag = true;
106
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 TRANS_LOGI(TRANS_SDK, "create sdk listener success. fd=%{public}d", fd);
118 }
119 SoftBusMutexUnlock(&g_lock.lock);
120
121 return AddTrigger(DIRECT_CHANNEL_CLIENT, fd, READ_TRIGGER);
122 }
123
TransTdcCreateListenerWithoutAddTrigger(int32_t fd)124 int32_t TransTdcCreateListenerWithoutAddTrigger(int32_t fd)
125 {
126 TdcLockInit();
127 if (SoftBusMutexLock(&g_lock.lock) != SOFTBUS_OK) {
128 TRANS_LOGE(TRANS_SDK, "lock failed.");
129 return SOFTBUS_LOCK_ERR;
130 }
131 if (g_isInitedFlag == false) {
132 g_isInitedFlag = true;
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 TRANS_LOGI(TRANS_SDK, "create sdk listener success.fd=%{public}d", fd);
144 }
145 SoftBusMutexUnlock(&g_lock.lock);
146
147 return SOFTBUS_OK;
148 }
149
TransTdcCloseFd(int32_t fd)150 void TransTdcCloseFd(int32_t fd)
151 {
152 if (fd < 0) {
153 TRANS_LOGI(TRANS_SDK, "fd less than zero");
154 return;
155 }
156 DelTrigger(DIRECT_CHANNEL_CLIENT, fd, READ_TRIGGER);
157 if (ConnGetSocketError(fd) == SOFTBUS_CONN_BAD_FD) {
158 TRANS_LOGI(TRANS_SDK, "fd is bad fd=%{public}d", fd);
159 return;
160 }
161 ConnCloseSocket(fd);
162 }
163
TransTdcReleaseFd(int32_t fd)164 void TransTdcReleaseFd(int32_t fd)
165 {
166 if (fd < 0) {
167 TRANS_LOGI(TRANS_SDK, "fd less than zero");
168 return;
169 }
170 (void)DelTrigger(DIRECT_CHANNEL_CLIENT, fd, RW_TRIGGER);
171 if (ConnGetSocketError(fd) == SOFTBUS_CONN_BAD_FD) {
172 TRANS_LOGI(TRANS_SDK, "fd is bad fd=%{public}d", fd);
173 return;
174 }
175 ConnShutdownSocket(fd);
176 }
177
TransTdcStopRead(int32_t fd)178 int32_t TransTdcStopRead(int32_t fd)
179 {
180 if (fd < 0) {
181 TRANS_LOGI(TRANS_SDK, "fd less than zero");
182 return SOFTBUS_OK;
183 }
184 return DelTrigger(DIRECT_CHANNEL_CLIENT, fd, READ_TRIGGER);
185 }
186