1 /*
2 * Copyright (c) 2021 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 "trans_tcp_direct_manager.h"
17
18 #include <securec.h>
19
20 #include "auth_interface.h"
21 #include "bus_center_info_key.h"
22 #include "bus_center_manager.h"
23 #include "softbus_adapter_mem.h"
24 #include "softbus_adapter_thread.h"
25 #include "softbus_def.h"
26 #include "softbus_errcode.h"
27 #include "softbus_log.h"
28 #include "softbus_socket.h"
29 #include "trans_tcp_direct_callback.h"
30 #include "trans_tcp_direct_message.h"
31 #include "trans_tcp_direct_p2p.h"
32 #include "trans_tcp_direct_sessionconn.h"
33 #include "trans_tcp_direct_wifi.h"
34 #include "wifi_direct_manager.h"
35
36 #define HANDSHAKE_TIMEOUT 19
37
OnSessionOpenFailProc(const SessionConn * node,int32_t errCode)38 static void OnSessionOpenFailProc(const SessionConn *node, int32_t errCode)
39 {
40 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "OnSesssionOpenFailProc: channelId=%d, side=%d, status=%d",
41 node->channelId, node->serverSide, node->status);
42 if (node->serverSide == false) {
43 if (TransTdcOnChannelOpenFailed(node->appInfo.myData.pkgName, node->appInfo.myData.pid,
44 node->channelId, errCode) != SOFTBUS_OK) {
45 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "notify channel open fail err");
46 }
47 }
48
49 int32_t fd = node->appInfo.fd;
50 if (fd >= 0) {
51 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "fd[%d] is shutdown", fd);
52 DelTrigger(node->listenMod, fd, RW_TRIGGER);
53 ConnShutdownSocket(fd);
54 }
55 }
56
NotifyTdcChannelTimeOut(ListNode * tdcChannelList)57 static void NotifyTdcChannelTimeOut(ListNode *tdcChannelList)
58 {
59 if (tdcChannelList == NULL) {
60 return;
61 }
62
63 SessionConn *item = NULL;
64 SessionConn *nextItem = NULL;
65
66 LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, tdcChannelList, SessionConn, node) {
67 OnSessionOpenFailProc(item, SOFTBUS_TRANS_HANDSHAKE_TIMEOUT);
68 TransSrvDelDataBufNode(item->channelId);
69 SoftBusFree(item);
70 }
71 }
72
TransTdcTimerProc(void)73 static void TransTdcTimerProc(void)
74 {
75 SessionConn *item = NULL;
76 SessionConn *nextItem = NULL;
77 SoftBusList *sessionList = GetSessionConnList();
78 if (sessionList == NULL) {
79 return;
80 }
81 if (GetSessionConnLock() != SOFTBUS_OK) {
82 return;
83 }
84
85 ListNode tempTdcChannelList;
86 ListInit(&tempTdcChannelList);
87
88 LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &sessionList->list, SessionConn, node) {
89 item->timeout++;
90 if (item->status < TCP_DIRECT_CHANNEL_STATUS_CONNECTED) {
91 if (item->timeout >= HANDSHAKE_TIMEOUT) {
92 ListDelete(&item->node);
93 sessionList->cnt--;
94
95 ListAdd(&tempTdcChannelList, &item->node);
96 }
97 }
98 }
99 ReleaseSessonConnLock();
100
101 NotifyTdcChannelTimeOut(&tempTdcChannelList);
102 }
103
NotifyTdcChannelStopProc(ListNode * tdcChannelList)104 static void NotifyTdcChannelStopProc(ListNode *tdcChannelList)
105 {
106 if (tdcChannelList == NULL) {
107 return;
108 }
109
110 SessionConn *item = NULL;
111 SessionConn *nextItem = NULL;
112
113 LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, tdcChannelList, SessionConn, node) {
114 OnSessionOpenFailProc(item, SOFTBUS_TRANS_NET_STATE_CHANGED);
115 TransSrvDelDataBufNode(item->channelId);
116 SoftBusFree(item);
117 }
118 }
119
120
TransTdcStopSessionProc(ListenerModule listenMod)121 NO_SANITIZE("cfi") void TransTdcStopSessionProc(ListenerModule listenMod)
122 {
123 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "TransTdcStopSessionProc");
124 SessionConn *item = NULL;
125 SessionConn *nextItem = NULL;
126
127 SoftBusList *sessionList = GetSessionConnList();
128 if (sessionList == NULL) {
129 return;
130 }
131 if (GetSessionConnLock() != SOFTBUS_OK) {
132 return;
133 }
134
135 ListNode tempTdcChannelList;
136 ListInit(&tempTdcChannelList);
137
138 LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &sessionList->list, SessionConn, node) {
139 if (listenMod != item->listenMod) {
140 continue;
141 }
142 ListDelete(&item->node);
143 sessionList->cnt--;
144
145 ListAdd(&tempTdcChannelList, &item->node);
146 }
147 ReleaseSessonConnLock();
148
149 NotifyTdcChannelStopProc(&tempTdcChannelList);
150 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "TransTdcStopSessionProc end");
151 }
152
TransTcpDirectInit(const IServerChannelCallBack * cb)153 NO_SANITIZE("cfi") int32_t TransTcpDirectInit(const IServerChannelCallBack *cb)
154 {
155 int32_t ret = P2pDirectChannelInit();
156 if (ret != SOFTBUS_OK) {
157 if (ret != SOFTBUS_FUNC_NOT_SUPPORT) {
158 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "init p2p direct channel failed");
159 return SOFTBUS_ERR;
160 }
161 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "p2p direct channel not support.");
162 }
163 if (TransSrvDataListInit() != SOFTBUS_OK) {
164 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "init srv trans tcp direct databuf list failed");
165 return SOFTBUS_ERR;
166 }
167 if (TransTdcSetCallBack(cb) != SOFTBUS_OK) {
168 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "set srv trans tcp dierct call failed");
169 return SOFTBUS_ERR;
170 }
171 if (RegisterTimeoutCallback(SOFTBUS_TCP_DIRECTCHANNEL_TIMER_FUN, TransTdcTimerProc) != SOFTBUS_OK) {
172 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "RegisterTimeoutCallback failed");
173 return SOFTBUS_ERR;
174 }
175 if (CreatSessionConnList() != SOFTBUS_OK) {
176 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "CreatSessionConnList failed");
177 return SOFTBUS_ERR;
178 }
179 return SOFTBUS_OK;
180 }
181
TransTcpDirectDeinit(void)182 NO_SANITIZE("cfi") void TransTcpDirectDeinit(void)
183 {
184 TransSrvDataListDeinit();
185 (void)RegisterTimeoutCallback(SOFTBUS_TCP_DIRECTCHANNEL_TIMER_FUN, NULL);
186 }
187
TransTdcDeathCallback(const char * pkgName,int32_t pid)188 NO_SANITIZE("cfi") void TransTdcDeathCallback(const char *pkgName, int32_t pid)
189 {
190 if (pkgName == NULL) {
191 return;
192 }
193 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "TransTdcDeathCallback: pkgName=%s", pkgName);
194 SessionConn *item = NULL;
195 SessionConn *nextItem = NULL;
196 if (GetSessionConnLock() != SOFTBUS_OK) {
197 return;
198 }
199 SoftBusList *sessionList = GetSessionConnList();
200 if (sessionList == NULL) {
201 ReleaseSessonConnLock();
202 return;
203 }
204 LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &sessionList->list, SessionConn, node) {
205 if ((strcmp(item->appInfo.myData.pkgName, pkgName) == 0) && (item->appInfo.myData.pid == pid)) {
206 ListDelete(&item->node);
207 sessionList->cnt--;
208 DelTrigger(item->listenMod, item->appInfo.fd, RW_TRIGGER);
209 SoftBusFree(item);
210 continue;
211 }
212 }
213 ReleaseSessonConnLock();
214 }
215
TransUpdAppInfo(AppInfo * appInfo,const ConnectOption * connInfo)216 static int32_t TransUpdAppInfo(AppInfo *appInfo, const ConnectOption *connInfo)
217 {
218 appInfo->peerData.port = connInfo->socketOption.port;
219 if (strcpy_s(appInfo->peerData.addr, sizeof(appInfo->peerData.addr), connInfo->socketOption.addr) != EOK) {
220 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "TransUpdAppInfo cpy fail");
221 return SOFTBUS_MEM_ERR;
222 }
223
224 appInfo->routeType = connInfo->type == CONNECT_TCP ? WIFI_STA : WIFI_P2P;
225 appInfo->protocol = connInfo->socketOption.protocol;
226
227 if (connInfo->socketOption.protocol == LNN_PROTOCOL_NIP) {
228 if (LnnGetLocalStrInfo(STRING_KEY_NODE_ADDR, appInfo->myData.addr, sizeof(appInfo->myData.addr)) !=
229 SOFTBUS_OK) {
230 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "TransUpdAppInfo get local nip fail");
231 return SOFTBUS_ERR;
232 }
233 } else {
234 if (connInfo->type == CONNECT_TCP) {
235 if (LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, appInfo->myData.addr, sizeof(appInfo->myData.addr)) !=
236 SOFTBUS_OK) {
237 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "TransUpdAppInfo get local ip fail");
238 return SOFTBUS_ERR;
239 }
240 } else if ((connInfo->type == CONNECT_P2P_REUSE) || (connInfo->type == CONNECT_P2P)) {
241 if (GetWifiDirectManager()->getLocalIpByUuid(appInfo->peerData.deviceId, appInfo->myData.addr,
242 sizeof(appInfo->myData.addr)) != SOFTBUS_OK) {
243 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "TransUpdAppInfo get p2p ip fail");
244 return SOFTBUS_TRANS_GET_P2P_INFO_FAILED;
245 }
246 }
247 }
248 return SOFTBUS_OK;
249 }
250
TransOpenDirectChannel(AppInfo * appInfo,const ConnectOption * connInfo,int32_t * channelId)251 NO_SANITIZE("cfi") int32_t TransOpenDirectChannel(AppInfo *appInfo, const ConnectOption *connInfo, int32_t *channelId)
252 {
253 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "TransOpenDirectChannel");
254 if (appInfo == NULL || connInfo == NULL || channelId == NULL) {
255 return SOFTBUS_INVALID_PARAM;
256 }
257
258 if (TransUpdAppInfo((AppInfo *)appInfo, connInfo) != SOFTBUS_OK) {
259 SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "TransOpenDirectChannel udp app fail");
260 return SOFTBUS_ERR;
261 }
262
263 int32_t ret = SOFTBUS_ERR;
264 if (connInfo->type == CONNECT_P2P) {
265 appInfo->routeType = WIFI_P2P;
266 ret = OpenP2pDirectChannel(appInfo, connInfo, channelId);
267 } else if (connInfo->type == CONNECT_P2P_REUSE) {
268 appInfo->routeType = WIFI_P2P_REUSE;
269 ret = OpenTcpDirectChannel(appInfo, connInfo, channelId);
270 } else {
271 appInfo->routeType = WIFI_STA;
272 ret = OpenTcpDirectChannel(appInfo, connInfo, channelId);
273 }
274 return ret;
275 }
276