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