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_udp_manager.h"
17 
18 #include <stdbool.h>
19 #include "client_trans_file.h"
20 #include "client_trans_file_listener.h"
21 #include "client_trans_socket_manager.h"
22 #include "client_trans_stream.h"
23 #include "nstackx_dfile.h"
24 #include "securec.h"
25 #include "softbus_adapter_mem.h"
26 #include "softbus_errcode.h"
27 #include "softbus_utils.h"
28 #include "trans_log.h"
29 #include "trans_pending_pkt.h"
30 #include "trans_server_proxy.h"
31 
32 static SoftBusList *g_udpChannelMgr = NULL;
33 static IClientSessionCallBack *g_sessionCb = NULL;
34 
ClientTransAddUdpChannel(UdpChannel * channel)35 static int32_t ClientTransAddUdpChannel(UdpChannel *channel)
36 {
37     if (g_udpChannelMgr == NULL) {
38         TRANS_LOGE(TRANS_INIT, "udp channel manager hasn't init.");
39         return SOFTBUS_NO_INIT;
40     }
41 
42     if (channel == NULL) {
43         TRANS_LOGW(TRANS_SDK, "invalid param.");
44         return SOFTBUS_INVALID_PARAM;
45     }
46     if (SoftBusMutexLock(&(g_udpChannelMgr->lock)) != SOFTBUS_OK) {
47         TRANS_LOGE(TRANS_SDK, "lock failed");
48         return SOFTBUS_LOCK_ERR;
49     }
50 
51     UdpChannel *channelNode = NULL;
52     LIST_FOR_EACH_ENTRY(channelNode, &(g_udpChannelMgr->list), UdpChannel, node) {
53         if (channelNode->channelId == channel->channelId) {
54             TRANS_LOGE(TRANS_SDK, "udp channel has exited.channelId=%{public}d.", channel->channelId);
55             (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
56             return SOFTBUS_TRANS_UDP_CHANNEL_ALREADY_EXIST;
57         }
58     }
59     ListInit(&(channel->node));
60     ListAdd(&(g_udpChannelMgr->list), &(channel->node));
61     TRANS_LOGI(TRANS_SDK, "add channelId=%{public}d", channel->channelId);
62     g_udpChannelMgr->cnt++;
63 
64     (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
65     return SOFTBUS_OK;
66 }
67 
TransDeleteUdpChannel(int32_t channelId)68 int32_t TransDeleteUdpChannel(int32_t channelId)
69 {
70     if (g_udpChannelMgr == NULL) {
71         TRANS_LOGE(TRANS_INIT, "udp channel manager hasn't init.");
72         return SOFTBUS_NO_INIT;
73     }
74     if (SoftBusMutexLock(&(g_udpChannelMgr->lock)) != SOFTBUS_OK) {
75         TRANS_LOGE(TRANS_SDK, "lock failed");
76         return SOFTBUS_LOCK_ERR;
77     }
78 
79     UdpChannel *channelNode = NULL;
80     LIST_FOR_EACH_ENTRY(channelNode, &(g_udpChannelMgr->list), UdpChannel, node) {
81         if (channelNode->channelId == channelId) {
82             ListDelete(&(channelNode->node));
83             TRANS_LOGI(TRANS_SDK, "delete channelId=%{public}d", channelId);
84             SoftBusFree(channelNode);
85             g_udpChannelMgr->cnt--;
86             (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
87             return SOFTBUS_OK;
88         }
89     }
90     (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
91     TRANS_LOGE(TRANS_SDK, "udp channel not found, channelId=%{public}d.", channelId);
92     return SOFTBUS_TRANS_UDP_CHANNEL_NOT_FOUND;
93 }
94 
TransGetUdpChannel(int32_t channelId,UdpChannel * channel)95 int32_t TransGetUdpChannel(int32_t channelId, UdpChannel *channel)
96 {
97     if (g_udpChannelMgr == NULL) {
98         TRANS_LOGE(TRANS_INIT, "udp channel manager hasn't init.");
99         return SOFTBUS_NO_INIT;
100     }
101     if (channel == NULL) {
102         TRANS_LOGE(TRANS_INIT, "param invalid");
103         return SOFTBUS_INVALID_PARAM;
104     }
105     if (SoftBusMutexLock(&(g_udpChannelMgr->lock)) != SOFTBUS_OK) {
106         TRANS_LOGE(TRANS_SDK, "lock failed");
107         return SOFTBUS_LOCK_ERR;
108     }
109 
110     UdpChannel *channelNode = NULL;
111     LIST_FOR_EACH_ENTRY(channelNode, &(g_udpChannelMgr->list), UdpChannel, node) {
112         if (channelNode->channelId == channelId) {
113             if (memcpy_s(channel, sizeof(UdpChannel), channelNode, sizeof(UdpChannel)) != EOK) {
114                 TRANS_LOGE(TRANS_SDK, "get udp channel memcpy_s failed.");
115                 (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
116                 return SOFTBUS_MEM_ERR;
117             }
118             (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
119             return SOFTBUS_OK;
120         }
121     }
122     (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
123     TRANS_LOGE(TRANS_SDK, "udp channel not found, channelId=%{public}d.", channelId);
124     return SOFTBUS_TRANS_UDP_CHANNEL_NOT_FOUND;
125 }
126 
TransSetUdpChannelEnable(int32_t channelId,bool isEnable)127 static int32_t TransSetUdpChannelEnable(int32_t channelId, bool isEnable)
128 {
129     if (g_udpChannelMgr == NULL) {
130         TRANS_LOGE(TRANS_SDK, "udp channel manager hasn't init.");
131         return SOFTBUS_NO_INIT;
132     }
133 
134     if (SoftBusMutexLock(&(g_udpChannelMgr->lock)) != SOFTBUS_OK) {
135         TRANS_LOGE(TRANS_SDK, "lock failed");
136         return SOFTBUS_LOCK_ERR;
137     }
138 
139     UdpChannel *channelNode = NULL;
140     LIST_FOR_EACH_ENTRY(channelNode, &(g_udpChannelMgr->list), UdpChannel, node) {
141         if (channelNode->channelId == channelId) {
142             channelNode->isEnable = isEnable;
143             (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
144             return SOFTBUS_OK;
145         }
146     }
147     (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
148     TRANS_LOGE(TRANS_SDK, "udp channel not found, channelId=%{public}d.", channelId);
149     return SOFTBUS_TRANS_UDP_CHANNEL_NOT_FOUND;
150 }
151 
OnUdpChannelOpened(int32_t channelId)152 static int32_t OnUdpChannelOpened(int32_t channelId)
153 {
154     UdpChannel channel;
155     if (memset_s(&channel, sizeof(UdpChannel), 0, sizeof(UdpChannel)) != EOK) {
156         TRANS_LOGE(TRANS_SDK, "on udp channel opened memset failed.");
157         return SOFTBUS_MEM_ERR;
158     }
159     int32_t ret = TransGetUdpChannel(channelId, &channel);
160     if (ret != SOFTBUS_OK) {
161         TRANS_LOGE(TRANS_SDK, "get udp failed. channelId=%{public}d, ret=%{public}d", channelId, ret);
162         return SOFTBUS_TRANS_UDP_GET_CHANNEL_FAILED;
163     }
164     ret = TransSetUdpChannelEnable(channelId, true);
165     if (ret != SOFTBUS_OK) {
166         TRANS_LOGE(TRANS_SDK, "set udp enable failed. channelId=%{public}d, ret=%{public}d", channelId, ret);
167         return SOFTBUS_TRANS_UDP_SET_CHANNEL_FAILED;
168     }
169     SessionType type = TYPE_BUTT;
170     switch (channel.businessType) {
171         case BUSINESS_TYPE_STREAM:
172             type = TYPE_STREAM;
173             break;
174         case BUSINESS_TYPE_FILE:
175             type = TYPE_FILE;
176             break;
177         default:
178             TRANS_LOGE(TRANS_SDK, "unsupport businessType=%{public}d.", channel.businessType);
179             return SOFTBUS_TRANS_BUSINESS_TYPE_NOT_MATCH;
180     }
181     ChannelInfo info = {0};
182     info.channelId = channel.channelId;
183     info.channelType = CHANNEL_TYPE_UDP;
184     info.isServer = channel.info.isServer;
185     info.peerPid = channel.info.peerPid;
186     info.peerUid = channel.info.peerUid;
187     info.groupId = channel.info.groupId;
188     info.peerDeviceId = channel.info.peerDeviceId;
189     info.peerSessionName = channel.info.peerSessionName;
190     info.routeType = channel.routeType;
191     info.businessType = channel.businessType;
192     if ((g_sessionCb != NULL) && (g_sessionCb->OnSessionOpened != NULL)) {
193         return g_sessionCb->OnSessionOpened(channel.info.mySessionName, &info, type);
194     }
195     return SOFTBUS_NO_INIT;
196 }
197 
ConvertChannelInfoToUdpChannel(const char * sessionName,const ChannelInfo * channel)198 static UdpChannel *ConvertChannelInfoToUdpChannel(const char *sessionName, const ChannelInfo *channel)
199 {
200     UdpChannel *newChannel = (UdpChannel *)SoftBusCalloc(sizeof(UdpChannel));
201     if (newChannel == NULL) {
202         TRANS_LOGE(TRANS_SDK, "new udp channel failed.");
203         return NULL;
204     }
205     newChannel->businessType = channel->businessType;
206     newChannel->channelId = channel->channelId;
207     newChannel->dfileId = -1;
208     newChannel->isEnable = false;
209     newChannel->info.isServer = channel->isServer;
210     newChannel->info.peerPid = channel->peerPid;
211     newChannel->info.peerUid = channel->peerUid;
212     newChannel->routeType = channel->routeType;
213     if (strcpy_s(newChannel->info.peerSessionName, SESSION_NAME_SIZE_MAX, channel->peerSessionName) != EOK ||
214         strcpy_s(newChannel->info.mySessionName, SESSION_NAME_SIZE_MAX, sessionName) != EOK ||
215         strcpy_s(newChannel->info.peerDeviceId, DEVICE_ID_SIZE_MAX, channel->peerDeviceId) != EOK ||
216         strcpy_s(newChannel->info.groupId, GROUP_ID_SIZE_MAX, channel->groupId) != EOK ||
217         strcpy_s(newChannel->info.myIp, sizeof(newChannel->info.myIp), channel->myIp) != EOK) {
218         TRANS_LOGE(TRANS_SDK, "udp channel or peer session name, device id, group id, myIp failed");
219         SoftBusFree(newChannel);
220         return NULL;
221     }
222 
223     return newChannel;
224 }
225 
TransSetdFileIdByChannelId(int32_t channelId,int32_t value)226 static int32_t TransSetdFileIdByChannelId(int32_t channelId, int32_t value)
227 {
228     if (g_udpChannelMgr == NULL) {
229         TRANS_LOGE(TRANS_SDK, "udp channel manager hasn't init.");
230         return SOFTBUS_NO_INIT;
231     }
232 
233     if (SoftBusMutexLock(&(g_udpChannelMgr->lock)) != SOFTBUS_OK) {
234         TRANS_LOGE(TRANS_SDK, "lock failed");
235         return SOFTBUS_LOCK_ERR;
236     }
237 
238     UdpChannel *channelNode = NULL;
239     LIST_FOR_EACH_ENTRY(channelNode, &(g_udpChannelMgr->list), UdpChannel, node) {
240         if (channelNode->channelId == channelId) {
241             channelNode->dfileId = value;
242             (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
243             return SOFTBUS_OK;
244         }
245     }
246     (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
247     TRANS_LOGE(TRANS_SDK, "udp channel not found, channelId=%{public}d.", channelId);
248     return SOFTBUS_TRANS_UDP_CHANNEL_NOT_FOUND;
249 }
250 
TransOnUdpChannelOpened(const char * sessionName,const ChannelInfo * channel,int32_t * udpPort)251 int32_t TransOnUdpChannelOpened(const char *sessionName, const ChannelInfo *channel, int32_t *udpPort)
252 {
253     TRANS_LOGD(TRANS_SDK, "TransOnUdpChannelOpened enter");
254     if (channel == NULL || udpPort == NULL || sessionName == NULL) {
255         TRANS_LOGW(TRANS_SDK, "invalid param.");
256         return SOFTBUS_INVALID_PARAM;
257     }
258     UdpChannel *newChannel = ConvertChannelInfoToUdpChannel(sessionName, channel);
259     if (newChannel == NULL) {
260         TRANS_LOGE(TRANS_SDK, "convert channel info to udp channel failed.");
261         return SOFTBUS_MEM_ERR;
262     }
263     if (ClientTransAddUdpChannel(newChannel) != SOFTBUS_OK) {
264         TRANS_LOGE(TRANS_SDK, "add udp channel failed.");
265         SoftBusFree(newChannel);
266         return SOFTBUS_TRANS_UDP_CLIENT_ADD_CHANNEL_FAILED;
267     }
268     TRANS_LOGI(TRANS_SDK, "add new udp channel success, channelId=%{public}d, businessType=%{public}d",
269         channel->channelId, channel->businessType);
270 
271     int32_t ret = SOFTBUS_TRANS_BUSINESS_TYPE_NOT_MATCH;
272     switch (channel->businessType) {
273         case BUSINESS_TYPE_STREAM:
274             ret = TransOnstreamChannelOpened(channel, udpPort);
275             if (ret != SOFTBUS_OK) {
276                 (void)TransDeleteUdpChannel(channel->channelId);
277                 TRANS_LOGE(TRANS_SDK, "on stream channel opened failed.");
278             }
279             break;
280         case BUSINESS_TYPE_FILE:
281             ret = TransOnFileChannelOpened(sessionName, channel, udpPort);
282             if (ret < SOFTBUS_OK) {
283                 (void)TransDeleteUdpChannel(channel->channelId);
284                 TRANS_LOGE(TRANS_SDK, "on file channel open failed.");
285                 return ret;
286             }
287             ret = TransSetdFileIdByChannelId(channel->channelId, ret);
288             if (ret != SOFTBUS_OK) {
289                 TRANS_LOGE(TRANS_SDK, "set dfileId failed, ret = %{public}d", ret);
290                 return ret;
291             }
292             ret = SOFTBUS_OK;
293             break;
294         default:
295             (void)TransDeleteUdpChannel(channel->channelId);
296             TRANS_LOGE(TRANS_SDK, "unsupport businessType=%{public}d.", channel->businessType);
297             break;
298     }
299     return ret;
300 }
301 
TransDeleteBusinnessChannel(UdpChannel * channel)302 static int32_t TransDeleteBusinnessChannel(UdpChannel *channel)
303 {
304     switch (channel->businessType) {
305         case BUSINESS_TYPE_STREAM:
306             if (TransCloseStreamChannel(channel->channelId) != SOFTBUS_OK) {
307                 TRANS_LOGE(TRANS_SDK, "trans close udp channel failed.");
308                 return SOFTBUS_TRANS_CLOSE_UDP_CHANNEL_FAILED;
309             }
310             break;
311         case BUSINESS_TYPE_FILE:
312             TransCloseFileChannel(channel->dfileId);
313             break;
314         default:
315             TRANS_LOGE(TRANS_SDK, "unsupport businessType=%{public}d.", channel->businessType);
316             return SOFTBUS_TRANS_BUSINESS_TYPE_NOT_MATCH;
317     }
318     return SOFTBUS_OK;
319 }
320 
TransOnUdpChannelOpenFailed(int32_t channelId,int32_t errCode)321 int32_t TransOnUdpChannelOpenFailed(int32_t channelId, int32_t errCode)
322 {
323     UdpChannel channel;
324     bool isFind = true;
325     if (TransGetUdpChannel(channelId, &channel) != SOFTBUS_OK) {
326         TRANS_LOGE(TRANS_SDK, "get udp channel by channelId=%{public}d failed.", channelId);
327         isFind = false;
328     }
329     if (TransDeleteUdpChannel(channelId) != SOFTBUS_OK) {
330         TRANS_LOGE(TRANS_SDK, "del channelId failed. channelId=%{public}d", channelId);
331     }
332     if ((isFind) && (channel.isEnable)) {
333         int32_t ret = TransDeleteBusinnessChannel(&channel);
334         if (ret != SOFTBUS_OK) {
335             TRANS_LOGE(TRANS_SDK, "del business channel failed. channelId=%{public}d", channelId);
336             return ret;
337         }
338     }
339     if ((g_sessionCb == NULL) || (g_sessionCb->OnSessionOpenFailed == NULL)) {
340         TRANS_LOGE(TRANS_SDK, "client trans udp manager seesion callback is null");
341         return SOFTBUS_NO_INIT;
342     }
343 
344     return g_sessionCb->OnSessionOpenFailed(channelId, CHANNEL_TYPE_UDP, errCode);
345 }
346 
TransOnUdpChannelBind(int32_t channelId,int32_t channelType)347 int32_t TransOnUdpChannelBind(int32_t channelId, int32_t channelType)
348 {
349     if ((g_sessionCb == NULL) || (g_sessionCb->OnChannelBind == NULL)) {
350         TRANS_LOGE(TRANS_SDK, "client trans udp manager OnChannelBind is null channelId=%{public}d", channelId);
351         return SOFTBUS_NO_INIT;
352     }
353 
354     int32_t ret = g_sessionCb->OnChannelBind(channelId, CHANNEL_TYPE_UDP);
355     if (ret == SOFTBUS_NOT_NEED_UPDATE) {
356         ret = SOFTBUS_OK;
357     }
358     return ret;
359 }
360 
ClosePeerUdpChannel(int32_t channelId)361 static int32_t ClosePeerUdpChannel(int32_t channelId)
362 {
363     return ServerIpcCloseChannel(NULL, channelId, CHANNEL_TYPE_UDP);
364 }
365 
RleaseUdpResources(int32_t channelId)366 static int32_t RleaseUdpResources(int32_t channelId)
367 {
368     return ServerIpcReleaseResources(channelId);
369 }
370 
NotifyCallback(UdpChannel * channel,int32_t channelId,ShutdownReason reason)371 static void NotifyCallback(UdpChannel *channel, int32_t channelId, ShutdownReason reason)
372 {
373     if (channel != NULL && (!channel->isEnable) && g_sessionCb != NULL && g_sessionCb->OnSessionOpenFailed != NULL) {
374         SessionState sessionState = SESSION_STATE_INIT;
375         if (ClientGetSessionStateByChannelId(channelId, CHANNEL_TYPE_UDP, &sessionState) == SOFTBUS_OK &&
376             (sessionState == SESSION_STATE_OPENED || sessionState == SESSION_STATE_CALLBACK_FINISHED)) {
377             if (ClosePeerUdpChannel(channelId) != SOFTBUS_OK) {
378                 TRANS_LOGW(TRANS_SDK, "trans close peer udp channel failed. channelId=%{public}d", channelId);
379             }
380         }
381         g_sessionCb->OnSessionOpenFailed(channelId, CHANNEL_TYPE_UDP, SOFTBUS_TRANS_STOP_BIND_BY_TIMEOUT);
382         return;
383     }
384     if (g_sessionCb != NULL && g_sessionCb->OnSessionClosed != NULL) {
385         g_sessionCb->OnSessionClosed(channelId, CHANNEL_TYPE_UDP, reason);
386         return;
387     }
388 }
389 
CloseUdpChannelProc(UdpChannel * channel,int32_t channelId,ShutdownReason reason)390 static int32_t CloseUdpChannelProc(UdpChannel *channel, int32_t channelId, ShutdownReason reason)
391 {
392     if (TransDeleteUdpChannel(channelId) != SOFTBUS_OK) {
393         TRANS_LOGW(TRANS_SDK, "trans del udp channel failed. channelId=%{public}d", channelId);
394     }
395 
396     switch (reason) {
397         case SHUTDOWN_REASON_PEER:
398             break;
399         case SHUTDOWN_REASON_SEND_FILE_ERR:
400         case SHUTDOWN_REASON_RECV_FILE_ERR:
401             if (RleaseUdpResources(channelId) != SOFTBUS_OK) {
402                 TRANS_LOGW(TRANS_SDK, "trans release udp resources failed. channelId=%{public}d", channelId);
403             }
404             break;
405         case SHUTDOWN_REASON_LOCAL:
406             if (ClosePeerUdpChannel(channelId) != SOFTBUS_OK) {
407                 TRANS_LOGW(TRANS_SDK, "trans close peer udp channel failed. channelId=%{public}d", channelId);
408             }
409             break;
410         default:
411             TRANS_LOGW(TRANS_SDK, "there's no reson to match. channelId=%{public}d, reason=%{public}d",
412                 channelId, (int32_t)reason);
413             break;
414     }
415 
416     if (channel != NULL) {
417         int32_t ret = TransDeleteBusinnessChannel(channel);
418         if (ret != SOFTBUS_OK) {
419             TRANS_LOGE(TRANS_SDK, "del business channel failed. channelId=%{public}d", channelId);
420             return ret;
421         }
422     }
423 
424     if (reason != SHUTDOWN_REASON_LOCAL) {
425         NotifyCallback(channel, channelId, reason);
426     }
427     return SOFTBUS_OK;
428 }
429 
CloseUdpChannel(int32_t channelId,ShutdownReason reason)430 static int32_t CloseUdpChannel(int32_t channelId, ShutdownReason reason)
431 {
432     UdpChannel channel;
433     (void)memset_s(&channel, sizeof(UdpChannel), 0, sizeof(UdpChannel));
434     TRANS_LOGI(TRANS_SDK, "close udp channelId=%{public}d, reason=%{public}d", channelId, reason);
435     if (TransGetUdpChannel(channelId, &channel) != SOFTBUS_OK) {
436         TRANS_LOGE(TRANS_SDK, "get udp channel by channelId=%{public}d failed.", channelId);
437         CloseUdpChannelProc(NULL, channelId, reason);
438         return SOFTBUS_TRANS_UDP_GET_CHANNEL_FAILED;
439     }
440     if (channel.businessType == BUSINESS_TYPE_FILE) {
441         TRANS_LOGD(TRANS_SDK, "close udp channel get file list start");
442         int32_t ret = NSTACKX_DFileSessionGetFileList(channel.dfileId);
443         if (ret != SOFTBUS_OK) {
444             TRANS_LOGE(TRANS_SDK, "close udp channel to get file list failed. channelId=%{public}d, ret=%{public}d",
445                 channelId, ret);
446         }
447     }
448     return CloseUdpChannelProc(&channel, channelId, reason);
449 }
450 
TransOnUdpChannelClosed(int32_t channelId,ShutdownReason reason)451 int32_t TransOnUdpChannelClosed(int32_t channelId, ShutdownReason reason)
452 {
453     return CloseUdpChannel(channelId, reason);
454 }
455 
TransOnUdpChannelQosEvent(int32_t channelId,int32_t eventId,int32_t tvCount,const QosTv * tvList)456 int32_t TransOnUdpChannelQosEvent(int32_t channelId, int32_t eventId, int32_t tvCount, const QosTv *tvList)
457 {
458     UdpChannel channel;
459     (void)memset_s(&channel, sizeof(UdpChannel), 0, sizeof(UdpChannel));
460     if (TransGetUdpChannel(channelId, &channel) != SOFTBUS_OK) {
461         TRANS_LOGE(TRANS_QOS, "get channel by channelId=%{public}d failed.", channelId);
462         return SOFTBUS_TRANS_UDP_GET_CHANNEL_FAILED;
463     }
464     if (g_sessionCb->OnQosEvent != NULL) {
465         g_sessionCb->OnQosEvent(channelId, CHANNEL_TYPE_UDP, eventId, tvCount, tvList);
466     }
467     return SOFTBUS_OK;
468 }
469 
ClientTransCloseUdpChannel(int32_t channelId,ShutdownReason reason)470 int32_t ClientTransCloseUdpChannel(int32_t channelId, ShutdownReason reason)
471 {
472     int32_t ret = AddPendingPacket(channelId, 0, PENDING_TYPE_UDP);
473     if (ret != SOFTBUS_OK) {
474         TRANS_LOGE(TRANS_SDK, "add pending packet failed, channelId=%{public}d.", channelId);
475         return ret;
476     }
477     ret = CloseUdpChannel(channelId, reason);
478     if (ret != SOFTBUS_OK) {
479         DelPendingPacketbyChannelId(channelId, 0, PENDING_TYPE_UDP);
480         TRANS_LOGE(TRANS_SDK, "close udp channel failed, ret=%{public}d", ret);
481         return ret;
482     }
483     ret = ProcPendingPacket(channelId, 0, PENDING_TYPE_UDP);
484     DelSessionStateClosing();
485     return ret;
486 }
487 
TransUdpChannelSendStream(int32_t channelId,const StreamData * data,const StreamData * ext,const StreamFrameInfo * param)488 int32_t TransUdpChannelSendStream(int32_t channelId, const StreamData *data, const StreamData *ext,
489     const StreamFrameInfo *param)
490 {
491     UdpChannel channel;
492     (void)memset_s(&channel, sizeof(UdpChannel), 0, sizeof(UdpChannel));
493     if (TransGetUdpChannel(channelId, &channel) != SOFTBUS_OK) {
494         TRANS_LOGE(TRANS_STREAM, "get channel by channelId=%{public}d failed.", channelId);
495         return SOFTBUS_TRANS_UDP_GET_CHANNEL_FAILED;
496     }
497     if (!channel.isEnable) {
498         TRANS_LOGE(TRANS_STREAM, "udp channel is not enable channelId=%{public}d.", channelId);
499         return SOFTBUS_TRANS_UDP_CHANNEL_DISABLE;
500     }
501     return TransSendStream(channelId, data, ext, param);
502 }
503 
TransUdpChannelSetStreamMultiLayer(int32_t channelId,const void * optValue)504 int32_t TransUdpChannelSetStreamMultiLayer(int32_t channelId, const void *optValue)
505 {
506     UdpChannel channel;
507     (void)memset_s(&channel, sizeof(UdpChannel), 0, sizeof(UdpChannel));
508     if (TransGetUdpChannel(channelId, &channel) != SOFTBUS_OK) {
509         TRANS_LOGE(TRANS_STREAM, "get channel by channelId=%{public}d failed.", channelId);
510         return SOFTBUS_TRANS_UDP_GET_CHANNEL_FAILED;
511     }
512     if (!channel.isEnable) {
513         TRANS_LOGE(TRANS_STREAM, "udp channel %{public}d is not enable.", channelId);
514         return SOFTBUS_TRANS_UDP_CHANNEL_DISABLE;
515     }
516     return TransSetStreamMultiLayer(channelId, optValue);
517 }
518 
OnUdpChannelClosed(int32_t channelId,ShutdownReason reason)519 static void OnUdpChannelClosed(int32_t channelId, ShutdownReason reason)
520 {
521     if ((g_sessionCb == NULL) || (g_sessionCb->OnSessionClosed == NULL)) {
522         return;
523     }
524     g_sessionCb->OnSessionClosed(channelId, CHANNEL_TYPE_UDP, reason);
525     if (TransDeleteUdpChannel(channelId) != SOFTBUS_OK) {
526         TRANS_LOGE(TRANS_SDK, "trans delete udp channel failed. channelId=%{public}d", channelId);
527     }
528 }
529 
OnStreamReceived(int32_t channelId,const StreamData * data,const StreamData * ext,const StreamFrameInfo * param)530 static void OnStreamReceived(int32_t channelId, const StreamData *data, const StreamData *ext,
531     const StreamFrameInfo *param)
532 {
533     if ((g_sessionCb == NULL) || (g_sessionCb->OnStreamReceived == NULL)) {
534         return;
535     }
536     g_sessionCb->OnStreamReceived(channelId, CHANNEL_TYPE_UDP, data, ext, param);
537 }
538 
OnFileGetSessionId(int32_t channelId,int32_t * sessionId)539 static int32_t OnFileGetSessionId(int32_t channelId, int32_t *sessionId)
540 {
541     if ((g_sessionCb == NULL) || (g_sessionCb->OnGetSessionId == NULL)) {
542         return SOFTBUS_INVALID_PARAM;
543     }
544     return g_sessionCb->OnGetSessionId(channelId, CHANNEL_TYPE_UDP, sessionId);
545 }
546 
OnQosEvent(int channelId,int eventId,int tvCount,const QosTv * tvList)547 static void OnQosEvent(int channelId, int eventId, int tvCount, const QosTv *tvList)
548 {
549     if ((g_sessionCb == NULL) || (g_sessionCb->OnQosEvent == NULL)) {
550         return;
551     }
552     g_sessionCb->OnQosEvent(channelId, CHANNEL_TYPE_UDP, eventId, tvCount, tvList);
553 }
554 
OnIdleTimeoutReset(int32_t sessionId)555 static int32_t OnIdleTimeoutReset(int32_t sessionId)
556 {
557     if ((g_sessionCb == NULL) || (g_sessionCb->OnIdleTimeoutReset == NULL)) {
558         return SOFTBUS_INVALID_PARAM;
559     }
560     return g_sessionCb->OnIdleTimeoutReset(sessionId);
561 }
562 
OnRawStreamEncryptOptGet(int32_t channelId,bool * isEncrypt)563 static int32_t OnRawStreamEncryptOptGet(int32_t channelId, bool *isEncrypt)
564 {
565     if (channelId < 0 || isEncrypt == NULL) {
566         TRANS_LOGE(TRANS_SDK, "invalid param");
567         return SOFTBUS_INVALID_PARAM;
568     }
569 
570     if (g_sessionCb == NULL) {
571         TRANS_LOGE(TRANS_SDK, "session callback is null");
572         return SOFTBUS_NO_INIT;
573     }
574 
575     if (g_sessionCb->OnRawStreamEncryptOptGet == NULL) {
576         TRANS_LOGE(TRANS_SDK, "OnRawStreamEncryptOptGet of session callback is null");
577         return SOFTBUS_NO_INIT;
578     }
579 
580     UdpChannel channel;
581     if (memset_s(&channel, sizeof(UdpChannel), 0, sizeof(UdpChannel)) != EOK) {
582         TRANS_LOGE(TRANS_SDK, "on udp channel opened memset failed.");
583         return SOFTBUS_MEM_ERR;
584     }
585     int32_t ret = TransGetUdpChannel(channelId, &channel);
586     if (ret != SOFTBUS_OK) {
587         TRANS_LOGE(TRANS_SDK, "get udpChannel failed. channelId=%{public}d", channelId);
588         return ret;
589     }
590 
591     if (channel.info.isServer) {
592         return g_sessionCb->OnRawStreamEncryptDefOptGet(channel.info.mySessionName, isEncrypt);
593     } else {
594         return g_sessionCb->OnRawStreamEncryptOptGet(channel.channelId, CHANNEL_TYPE_UDP, isEncrypt);
595     }
596 }
597 
598 static UdpChannelMgrCb g_udpChannelCb = {
599     .OnStreamReceived = OnStreamReceived,
600     .OnFileGetSessionId = OnFileGetSessionId,
601     .OnMessageReceived = NULL,
602     .OnUdpChannelOpened = OnUdpChannelOpened,
603     .OnUdpChannelClosed = OnUdpChannelClosed,
604     .OnQosEvent = OnQosEvent,
605     .OnIdleTimeoutReset = OnIdleTimeoutReset,
606     .OnRawStreamEncryptOptGet = OnRawStreamEncryptOptGet,
607 };
608 
ClientTransUdpMgrInit(IClientSessionCallBack * callback)609 int32_t ClientTransUdpMgrInit(IClientSessionCallBack *callback)
610 {
611     if (g_udpChannelMgr != NULL) {
612         TRANS_LOGE(TRANS_INIT, "udp channel info manager has init.");
613         return SOFTBUS_OK;
614     }
615     if (callback == NULL) {
616         TRANS_LOGE(TRANS_INIT, "udp channel info manager init failed, calback is null.");
617         return SOFTBUS_INVALID_PARAM;
618     }
619     g_sessionCb = callback;
620     RegisterStreamCb(&g_udpChannelCb);
621     TransFileInit();
622     TransFileSchemaInit();
623     if (PendingInit(PENDING_TYPE_UDP) != SOFTBUS_OK) {
624         TRANS_LOGE(TRANS_INIT, "trans udp pending init failed.");
625         return SOFTBUS_TRANS_SERVER_INIT_FAILED;
626     }
627     NSTACKX_DFileRegisterLogCallback(NstackxLogInnerImpl);
628     RegisterFileCb(&g_udpChannelCb);
629     g_udpChannelMgr = CreateSoftBusList();
630     if (g_udpChannelMgr == NULL) {
631         TRANS_LOGE(TRANS_INIT, "create udp channel manager list failed.");
632         return SOFTBUS_MALLOC_ERR;
633     }
634     TRANS_LOGI(TRANS_INIT, "trans udp channel manager init success.");
635     return SOFTBUS_OK;
636 }
637 
ClientTransUdpMgrDeinit(void)638 void ClientTransUdpMgrDeinit(void)
639 {
640     if (g_udpChannelMgr == NULL) {
641         return;
642     }
643     UnregisterStreamCb();
644     RegisterFileCb(NULL);
645     if (SoftBusMutexLock(&g_udpChannelMgr->lock) != SOFTBUS_OK) {
646         TRANS_LOGE(TRANS_INIT, "lock failed");
647         return;
648     }
649     UdpChannel *channel = NULL;
650     UdpChannel *nextChannel = NULL;
651     LIST_FOR_EACH_ENTRY_SAFE(channel, nextChannel, &g_udpChannelMgr->list, UdpChannel, node) {
652         ListDelete(&(channel->node));
653         SoftBusFree(channel);
654     }
655     (void)SoftBusMutexUnlock(&g_udpChannelMgr->lock);
656     DestroySoftBusList(g_udpChannelMgr);
657     g_udpChannelMgr = NULL;
658     TransFileDeinit();
659     TransFileSchemaDeinit();
660     PendingDeinit(PENDING_TYPE_UDP);
661     TRANS_LOGI(TRANS_INIT, "trans udp channel manager deinit success.");
662 }
663 
TransUdpChannelSendFile(int32_t channelId,const char * sFileList[],const char * dFileList[],uint32_t fileCnt)664 int32_t TransUdpChannelSendFile(int32_t channelId, const char *sFileList[], const char *dFileList[], uint32_t fileCnt)
665 {
666     UdpChannel channel;
667     if (memset_s(&channel, sizeof(UdpChannel), 0, sizeof(UdpChannel)) != EOK) {
668         TRANS_LOGE(TRANS_FILE, "memset failed.");
669         return SOFTBUS_MEM_ERR;
670     }
671     if (TransGetUdpChannel(channelId, &channel) != SOFTBUS_OK) {
672         return SOFTBUS_TRANS_UDP_GET_CHANNEL_FAILED;
673     }
674     if (!channel.isEnable || channel.dfileId < 0) {
675         TRANS_LOGE(TRANS_FILE, "udp channel is not enable.");
676         return SOFTBUS_TRANS_UDP_CHANNEL_DISABLE;
677     }
678     return TransSendFile(channel.dfileId, sFileList, dFileList, fileCnt);
679 }
680 
TransGetUdpChannelByFileId(int32_t dfileId,UdpChannel * udpChannel)681 int32_t TransGetUdpChannelByFileId(int32_t dfileId, UdpChannel *udpChannel)
682 {
683     if (g_udpChannelMgr == NULL) {
684         TRANS_LOGE(TRANS_INIT, "udp channel manager hasn't init.");
685         return SOFTBUS_NO_INIT;
686     }
687 
688     if (SoftBusMutexLock(&(g_udpChannelMgr->lock)) != SOFTBUS_OK) {
689         TRANS_LOGE(TRANS_FILE, "lock failed");
690         return SOFTBUS_LOCK_ERR;
691     }
692 
693     UdpChannel *channelNode = NULL;
694     LIST_FOR_EACH_ENTRY(channelNode, &(g_udpChannelMgr->list), UdpChannel, node) {
695         if (channelNode->dfileId == dfileId) {
696             if (memcpy_s(udpChannel, sizeof(UdpChannel), channelNode, sizeof(UdpChannel)) != EOK) {
697                 TRANS_LOGE(TRANS_FILE, "memcpy_s failed.");
698                 (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
699                 return SOFTBUS_MEM_ERR;
700             }
701             (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
702             return SOFTBUS_OK;
703         }
704     }
705     (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
706     return SOFTBUS_TRANS_UDP_CHANNEL_NOT_FOUND;
707 }
708 
TransUdpDeleteFileListener(const char * sessionName)709 void TransUdpDeleteFileListener(const char *sessionName)
710 {
711     return TransDeleteFileListener(sessionName);
712 }
713 
TransLimitChange(int32_t channelId,uint8_t tos)714 int32_t TransLimitChange(int32_t channelId, uint8_t tos)
715 {
716     if (tos != FILE_PRIORITY_BK && tos != FILE_PRIORITY_BE) {
717         TRANS_LOGE(TRANS_FILE, "invalid ip tos");
718         return SOFTBUS_INVALID_PARAM;
719     }
720     UdpChannel channel;
721     (void)memset_s(&channel, sizeof(UdpChannel), 0, sizeof(UdpChannel));
722     int32_t ret = TransGetUdpChannel(channelId, &channel);
723     if (ret != SOFTBUS_OK) {
724         return ret;
725     }
726     if (channel.info.isServer) {
727         TRANS_LOGE(TRANS_FILE, "server side no need to set ip tos");
728         return SOFTBUS_NOT_NEED_UPDATE;
729     }
730     if (channel.businessType != BUSINESS_TYPE_FILE) {
731         TRANS_LOGE(TRANS_FILE, "bussiness type not match");
732         return SOFTBUS_NOT_NEED_UPDATE;
733     }
734     uint8_t dfileTos = tos;
735     DFileOpt dfileOpt = {
736         .optType = OPT_TYPE_SOCK_PRIO,
737         .valLen = sizeof(uint8_t),
738         .value = (uint64_t)&dfileTos,
739     };
740     ret = NSTACKX_DFileSetSessionOpt(channel.dfileId, &dfileOpt);
741     if (ret != SOFTBUS_OK) {
742         TRANS_LOGE(TRANS_FILE, "NSTACKX_DFileSetOpt, channelId=%{public}d, ret=%{public}d, tos=%{public}hhu", channelId,
743             ret, tos);
744         return ret;
745     }
746     return ret;
747 }
748 
TransUdpOnCloseAckReceived(int32_t channelId)749 int32_t TransUdpOnCloseAckReceived(int32_t channelId)
750 {
751     return SetPendingPacket(channelId, 0, PENDING_TYPE_UDP);
752 }
753 
754 // trigger file event FILE_EVENT_TRANS_STATUS when link down
ClientEmitFileEvent(int32_t channelId)755 int32_t ClientEmitFileEvent(int32_t channelId)
756 {
757     UdpChannel channel;
758     (void)memset_s(&channel, sizeof(UdpChannel), 0, sizeof(UdpChannel));
759     int32_t ret = TransGetUdpChannel(channelId, &channel);
760     if (ret != SOFTBUS_OK) {
761         TRANS_LOGE(TRANS_SDK, "get udp channel by channelId=%{public}d failed.", channelId);
762         return ret;
763     }
764     if (channel.businessType == BUSINESS_TYPE_FILE) {
765         TRANS_LOGD(TRANS_SDK, "linkdown trigger file event, channelId=%{public}d", channelId);
766         ret = NSTACKX_DFileSessionGetFileList(channel.dfileId);
767         if (ret != SOFTBUS_OK) {
768             TRANS_LOGE(
769                 TRANS_SDK, "linkdown get file list failed. channelId=%{public}d, ret=%{public}d", channelId, ret);
770         }
771     }
772     return ret;
773 }
774 
TransSetUdpChanelSessionId(int32_t channelId,int32_t sessionId)775 int32_t TransSetUdpChanelSessionId(int32_t channelId, int32_t sessionId)
776 {
777     if (g_udpChannelMgr == NULL) {
778         TRANS_LOGE(TRANS_SDK, "udp channel manager hasn't init.");
779         return SOFTBUS_NO_INIT;
780     }
781 
782     if (SoftBusMutexLock(&(g_udpChannelMgr->lock)) != SOFTBUS_OK) {
783         TRANS_LOGE(TRANS_SDK, "lock failed");
784         return SOFTBUS_LOCK_ERR;
785     }
786 
787     UdpChannel *channelNode = NULL;
788     LIST_FOR_EACH_ENTRY(channelNode, &(g_udpChannelMgr->list), UdpChannel, node) {
789         if (channelNode->channelId == channelId) {
790             channelNode->sessionId = sessionId;
791             (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
792             return SOFTBUS_OK;
793         }
794     }
795     (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
796     TRANS_LOGE(TRANS_SDK, "udp channel not found, channelId=%{public}d.", channelId);
797     return SOFTBUS_TRANS_UDP_CHANNEL_NOT_FOUND;
798 }
799 
TransSetUdpChannelRenameHook(int32_t channelId,OnRenameFileCallback onRenameFile)800 int32_t TransSetUdpChannelRenameHook(int32_t channelId, OnRenameFileCallback onRenameFile)
801 {
802     if (onRenameFile == NULL) {
803         TRANS_LOGE(TRANS_SDK, "onRenameFile is null");
804         return SOFTBUS_INVALID_PARAM;
805     }
806 
807     if (g_udpChannelMgr == NULL) {
808         TRANS_LOGE(TRANS_SDK, "udp channel manager hasn't init.");
809         return SOFTBUS_NO_INIT;
810     }
811 
812     if (SoftBusMutexLock(&(g_udpChannelMgr->lock)) != SOFTBUS_OK) {
813         TRANS_LOGE(TRANS_SDK, "lock failed");
814         return SOFTBUS_LOCK_ERR;
815     }
816 
817     UdpChannel *channelNode = NULL;
818     LIST_FOR_EACH_ENTRY(channelNode, &(g_udpChannelMgr->list), UdpChannel, node) {
819         if (channelNode->channelId == channelId && channelNode->businessType == BUSINESS_TYPE_FILE) {
820             channelNode->onRenameFile = onRenameFile;
821             (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
822             return SOFTBUS_OK;
823         }
824     }
825     (void)SoftBusMutexUnlock(&(g_udpChannelMgr->lock));
826     TRANS_LOGE(TRANS_SDK, "udp channel not found, channelId=%{public}d.", channelId);
827     return SOFTBUS_TRANS_UDP_CHANNEL_NOT_FOUND;
828 }