• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "trans_tcp_direct_manager.h"
17 
18 #include <securec.h>
19 
20 #include "bus_center_manager.h"
21 #include "softbus_adapter_mem.h"
22 #include "softbus_def.h"
23 #include "softbus_error_code.h"
24 #include "legacy/softbus_hisysevt_transreporter.h"
25 #include "softbus_socket.h"
26 #include "trans_channel_common.h"
27 #include "trans_event.h"
28 #include "trans_log.h"
29 #include "trans_tcp_direct_callback.h"
30 #include "trans_tcp_direct_listener.h"
31 #include "trans_tcp_direct_message.h"
32 #include "trans_tcp_direct_p2p.h"
33 #include "trans_tcp_direct_sessionconn.h"
34 #include "trans_tcp_direct_wifi.h"
35 #include "wifi_direct_manager.h"
36 
37 #define HANDSHAKE_TIMEOUT 19
38 
OnSessionOpenFailProc(const SessionConn * node,int32_t errCode)39 static void OnSessionOpenFailProc(const SessionConn *node, int32_t errCode)
40 {
41     TRANS_LOGW(TRANS_CTRL, "OnSesssionOpenFailProc: channelId=%{public}d, side=%{public}d, status=%{public}d",
42         node->channelId, node->serverSide, node->status);
43     int64_t timeStart = node->appInfo.timeStart;
44     int64_t timeDiff = GetSoftbusRecordTimeMillis() - timeStart;
45     char localUdid[UDID_BUF_LEN] = { 0 };
46     (void)LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, localUdid, sizeof(localUdid));
47     TransEventExtra extra = {
48         .calleePkg = NULL,
49         .callerPkg = node->appInfo.myData.pkgName,
50         .channelId = node->channelId,
51         .peerChannelId = node->appInfo.peerData.channelId,
52         .peerNetworkId = node->appInfo.peerNetWorkId,
53         .socketName = node->appInfo.myData.sessionName,
54         .linkType = node->appInfo.connectType,
55         .costTime = (int32_t)timeDiff,
56         .errcode = errCode,
57         .osType = (node->appInfo.osType < 0) ? UNKNOW_OS_TYPE : node->appInfo.osType,
58         .localUdid = localUdid,
59         .peerUdid = node->appInfo.peerUdid,
60         .peerDevVer = node->appInfo.peerVersion,
61         .result = EVENT_STAGE_RESULT_FAILED
62     };
63     extra.deviceState = TransGetDeviceState(node->appInfo.peerNetWorkId);
64     if (!node->serverSide) {
65         TRANS_EVENT(EVENT_SCENE_OPEN_CHANNEL, EVENT_STAGE_OPEN_CHANNEL_END, extra);
66     } else {
67         TRANS_EVENT(EVENT_SCENE_OPEN_CHANNEL_SERVER, EVENT_STAGE_OPEN_CHANNEL_END, extra);
68     }
69     if (node->serverSide == false) {
70         if (TransTdcOnChannelOpenFailed(node->appInfo.myData.pkgName, node->appInfo.myData.pid,
71             node->channelId, errCode) != SOFTBUS_OK) {
72             TRANS_LOGW(TRANS_CTRL, "notify channel open fail err");
73         }
74     }
75 }
76 
NotifyTdcChannelTimeOut(ListNode * tdcChannelList)77 static void NotifyTdcChannelTimeOut(ListNode *tdcChannelList)
78 {
79     if (tdcChannelList == NULL) {
80         TRANS_LOGE(TRANS_CTRL, "param invalid");
81         return;
82     }
83 
84     SessionConn *item = NULL;
85     SessionConn *nextItem = NULL;
86     LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, tdcChannelList, SessionConn, node) {
87         OnSessionOpenFailProc(item, SOFTBUS_TRANS_HANDSHAKE_TIMEOUT);
88         TransSrvDelDataBufNode(item->channelId);
89         SoftBusFree(item);
90     }
91 }
92 
TransTdcTimerProc(void)93 static void TransTdcTimerProc(void)
94 {
95     SessionConn *item = NULL;
96     SessionConn *nextItem = NULL;
97     SoftBusList *sessionList = GetSessionConnList();
98     if (sessionList == NULL) {
99         TRANS_LOGE(TRANS_CTRL, "get session conn list failed");
100         return;
101     }
102     if (GetSessionConnLock() != SOFTBUS_OK) {
103         TRANS_LOGE(TRANS_CTRL, "get session conn lock failed");
104         return;
105     }
106 
107     ListNode tempTdcChannelList;
108     ListInit(&tempTdcChannelList);
109 
110     LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &sessionList->list, SessionConn, node) {
111         item->timeout++;
112         if (item->status < TCP_DIRECT_CHANNEL_STATUS_CONNECTED) {
113             if (item->timeout >= HANDSHAKE_TIMEOUT) {
114                 int32_t fd = item->appInfo.fd;
115                 item->appInfo.fd = -1;
116                 ListDelete(&item->node);
117                 sessionList->cnt--;
118                 if (fd >= 0) {
119                     TRANS_LOGW(TRANS_CTRL, "session is shutdown. fd=%{public}d", fd);
120                     DelTrigger(item->listenMod, fd, RW_TRIGGER);
121                     TransTdcSocketReleaseFd(item->listenMod, fd);
122                 }
123 
124                 ListAdd(&tempTdcChannelList, &item->node);
125             }
126         }
127     }
128     ReleaseSessionConnLock();
129 
130     NotifyTdcChannelTimeOut(&tempTdcChannelList);
131 }
132 
NotifyTdcChannelStopProc(ListNode * tdcChannelList)133 static void NotifyTdcChannelStopProc(ListNode *tdcChannelList)
134 {
135     if (tdcChannelList == NULL) {
136         TRANS_LOGE(TRANS_INIT, "param invalid");
137         return;
138     }
139 
140     SessionConn *item = NULL;
141     SessionConn *nextItem = NULL;
142 
143     LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, tdcChannelList, SessionConn, node) {
144         OnSessionOpenFailProc(item, SOFTBUS_TRANS_NET_STATE_CHANGED);
145         TransSrvDelDataBufNode(item->channelId);
146         SoftBusFree(item);
147     }
148 }
149 
150 
TransTdcStopSessionProc(ListenerModule listenMod)151 void TransTdcStopSessionProc(ListenerModule listenMod)
152 {
153     TRANS_LOGD(TRANS_CTRL, "enter.");
154 
155     SessionConn *item = NULL;
156     SessionConn *nextItem = NULL;
157 
158     SoftBusList *sessionList = GetSessionConnList();
159     if (sessionList == NULL) {
160         TRANS_LOGE(TRANS_INIT, "get session conn list failed");
161         return;
162     }
163     if (GetSessionConnLock() != SOFTBUS_OK) {
164         TRANS_LOGE(TRANS_INIT, "get session conn lock failed");
165         return;
166     }
167 
168     ListNode tempTdcChannelList;
169     ListInit(&tempTdcChannelList);
170     LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &sessionList->list, SessionConn, node) {
171         if (listenMod != item->listenMod) {
172             continue;
173         }
174         int32_t fd = item->appInfo.fd;
175         item->appInfo.fd = -1;
176         ListDelete(&item->node);
177         sessionList->cnt--;
178         if (fd >= 0) {
179             TRANS_LOGW(TRANS_CTRL, "session is shutdown. fd=%{public}d", fd);
180             DelTrigger(item->listenMod, fd, RW_TRIGGER);
181             TransTdcSocketReleaseFd(item->listenMod, fd);
182         }
183         ListAdd(&tempTdcChannelList, &item->node);
184     }
185     ReleaseSessionConnLock();
186     NotifyTdcChannelStopProc(&tempTdcChannelList);
187     TRANS_LOGD(TRANS_CTRL, "ok");
188 }
189 
TransTcpDirectInit(const IServerChannelCallBack * cb)190 int32_t TransTcpDirectInit(const IServerChannelCallBack *cb)
191 {
192     TRANS_CHECK_AND_RETURN_RET_LOGE(cb != NULL, SOFTBUS_INVALID_PARAM, TRANS_CTRL, "param invalid");
193     int32_t ret = P2pDirectChannelInit();
194     if (ret != SOFTBUS_OK) {
195         if (ret != SOFTBUS_FUNC_NOT_SUPPORT) {
196             TRANS_LOGE(TRANS_INIT, "init p2p direct channel failed");
197             return ret;
198         }
199         TRANS_LOGW(TRANS_INIT, "p2p direct channel not support.");
200     }
201 
202     ret = TransSrvDataListInit();
203     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret,
204         TRANS_INIT, "init srv trans tcp direct databuf list failed");
205 
206     ret = TransTdcSetCallBack(cb);
207     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_INIT, "set srv trans tcp dierct call failed");
208 
209     ret = RegisterTimeoutCallback(SOFTBUS_TCP_DIRECTCHANNEL_TIMER_FUN, TransTdcTimerProc);
210     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_INIT, "RegisterTimeoutCallback failed");
211 
212     ret = CreatSessionConnList();
213     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_INIT, "CreatSessionConnList failed");
214 
215     ret = CreateTcpChannelInfoList();
216     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_INIT, "CreateTcpChannelInfoList failed");
217 
218     return SOFTBUS_OK;
219 }
220 
TransTcpDirectDeinit(void)221 void TransTcpDirectDeinit(void)
222 {
223     if (UnRegisterTimeoutCallback(SOFTBUS_TCP_DIRECTCHANNEL_TIMER_FUN) != SOFTBUS_OK) {
224         TRANS_LOGE(TRANS_CTRL, "unregister tcp directchannel timer callback failed");
225     }
226     TransSrvDataListDeinit();
227 }
228 
TransTdcDeathCallback(const char * pkgName,int32_t pid)229 void TransTdcDeathCallback(const char *pkgName, int32_t pid)
230 {
231     if (pkgName == NULL) {
232         TRANS_LOGE(TRANS_CTRL, "param invalid");
233         return;
234     }
235 
236     SessionConn *item = NULL;
237     SessionConn *nextItem = NULL;
238     if (GetSessionConnLock() != SOFTBUS_OK) {
239         TRANS_LOGE(TRANS_CTRL, "get session conn lock failed");
240         return;
241     }
242     SoftBusList *sessionList = GetSessionConnList();
243     if (sessionList == NULL) {
244         TRANS_LOGE(TRANS_CTRL, "get session conn list failed");
245         ReleaseSessionConnLock();
246         return;
247     }
248     LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &sessionList->list, SessionConn, node) {
249         if ((strcmp(item->appInfo.myData.pkgName, pkgName) == 0) && (item->appInfo.myData.pid == pid)) {
250             ListDelete(&item->node);
251             char *anonymizePkgName = NULL;
252             Anonymize(pkgName, &anonymizePkgName);
253             TRANS_LOGI(TRANS_CTRL, "delete pkgName=%{public}s, pid=%{public}d", anonymizePkgName, pid);
254             AnonymizeFree(anonymizePkgName);
255             sessionList->cnt--;
256             DelTrigger(item->listenMod, item->appInfo.fd, RW_TRIGGER);
257             TransTdcSocketReleaseFd(item->listenMod, item->appInfo.fd);
258             SoftBusFree(item);
259             continue;
260         }
261     }
262     ReleaseSessionConnLock();
263 }
264 
TransUpdateAppInfo(AppInfo * appInfo,const ConnectOption * connInfo)265 static int32_t TransUpdateAppInfo(AppInfo *appInfo, const ConnectOption *connInfo)
266 {
267     appInfo->peerData.port = connInfo->socketOption.port;
268     if (strcpy_s(appInfo->peerData.addr, sizeof(appInfo->peerData.addr), connInfo->socketOption.addr) != EOK) {
269         TRANS_LOGE(TRANS_CTRL, "strcpy_s remote ip fail.");
270         return SOFTBUS_STRCPY_ERR;
271     }
272     appInfo->routeType = connInfo->type == CONNECT_TCP ? WIFI_STA : WIFI_P2P;
273     appInfo->protocol = connInfo->socketOption.protocol;
274     if (connInfo->socketOption.protocol == LNN_PROTOCOL_NIP) {
275         if (LnnGetLocalStrInfo(STRING_KEY_NODE_ADDR, appInfo->myData.addr, sizeof(appInfo->myData.addr)) !=
276             SOFTBUS_OK) {
277             TRANS_LOGE(TRANS_CTRL, "Lnn: get local ip fail.");
278             return SOFTBUS_TRANS_GET_LOCAL_IP_FAILED;
279         }
280     } else {
281         if (connInfo->type == CONNECT_TCP) {
282             int32_t ifNameIdx = (connInfo->socketOption.moduleId == DIRECT_CHANNEL_SERVER_USB) ? USB_IF : WLAN_IF;
283             if (LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_IP, appInfo->myData.addr,
284                 sizeof(appInfo->myData.addr), ifNameIdx) != SOFTBUS_OK) {
285                 TRANS_LOGE(TRANS_CTRL, "Lnn: get local ip fail.");
286                 return SOFTBUS_TRANS_GET_LOCAL_IP_FAILED;
287             }
288         }
289     }
290     return SOFTBUS_OK;
291 }
292 
TransOpenDirectChannel(AppInfo * appInfo,const ConnectOption * connInfo,int32_t * channelId)293 int32_t TransOpenDirectChannel(AppInfo *appInfo, const ConnectOption *connInfo, int32_t *channelId)
294 {
295     TRANS_LOGD(TRANS_CTRL, "enter.");
296     if (appInfo == NULL || connInfo == NULL || channelId == NULL) {
297         return SOFTBUS_INVALID_PARAM;
298     }
299     int32_t ret = TransUpdateAppInfo(appInfo, connInfo);
300     if (ret != SOFTBUS_OK) {
301         TRANS_LOGE(TRANS_CTRL, "udp app fail");
302         return ret;
303     }
304     if (connInfo->type == CONNECT_P2P || connInfo->type == CONNECT_HML) {
305         appInfo->routeType = WIFI_P2P;
306         ret = OpenP2pDirectChannel(appInfo, connInfo, channelId);
307     } else if (connInfo->type == CONNECT_P2P_REUSE) {
308         appInfo->routeType = WIFI_P2P_REUSE;
309         ret = OpenTcpDirectChannel(appInfo, connInfo, channelId);
310     } else {
311         appInfo->routeType = (connInfo->socketOption.moduleId == DIRECT_CHANNEL_SERVER_USB) ? WIFI_USB : WIFI_STA;
312         ret = OpenTcpDirectChannel(appInfo, connInfo, channelId);
313     }
314 
315     ConnectType connType = connInfo->type;
316     if (connType == CONNECT_P2P_REUSE) {
317         connType = (IsHmlIpAddr(appInfo->myData.addr)) ? CONNECT_HML : CONNECT_P2P;
318     }
319     TransEventExtra extra = {
320         .peerNetworkId = NULL,
321         .calleePkg = NULL,
322         .callerPkg = NULL,
323         .linkType = connType,
324         .channelType = CHANNEL_TYPE_TCP_DIRECT,
325         .channelId = *channelId,
326         .errcode = ret,
327         .socketName = appInfo->myData.sessionName,
328         .result = (ret == SOFTBUS_OK) ? EVENT_STAGE_RESULT_OK : EVENT_STAGE_RESULT_FAILED
329     };
330     SessionConn conn;
331     if (GetSessionConnById(*channelId, &conn) == SOFTBUS_OK) {
332         extra.authId = conn.authHandle.authId;
333         extra.socketFd = conn.appInfo.fd;
334         extra.requestId = (int32_t)conn.requestId;
335     };
336     (void)memset_s(conn.appInfo.sessionKey, sizeof(conn.appInfo.sessionKey), 0, sizeof(conn.appInfo.sessionKey));
337     TRANS_EVENT(EVENT_SCENE_OPEN_CHANNEL, EVENT_STAGE_START_CONNECT, extra);
338     return ret;
339 }
340