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 }