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_tcp_direct_message.h"
17
18 #include <securec.h>
19
20 #include "client_trans_tcp_direct_callback.h"
21 #include "client_trans_tcp_direct_manager.h"
22 #include "client_trans_session_manager.h"
23 #include "common_list.h"
24 #include "softbus_adapter_crypto.h"
25 #include "softbus_adapter_mem.h"
26 #include "softbus_adapter_socket.h"
27 #include "softbus_def.h"
28 #include "softbus_errcode.h"
29 #include "softbus_feature_config.h"
30 #include "softbus_socket.h"
31 #include "softbus_tcp_socket.h"
32 #include "softbus_utils.h"
33 #include "trans_log.h"
34 #include "trans_pending_pkt.h"
35
36 #define ACK_SIZE 4
37 #define DATA_EXTEND_LEN (DC_DATA_HEAD_SIZE + OVERHEAD_LEN)
38 #define MIN_BUF_LEN (1024 + DATA_EXTEND_LEN)
39
40 #define BYTE_TOS 0x60
41 #define COLLABORATE_BYTE_TOS 0x80
42 #define MESSAGE_TOS 0xC0
43
44 typedef struct {
45 ListNode node;
46 int32_t channelId;
47 int32_t fd;
48 uint32_t size;
49 char *data;
50 char *w;
51 } ClientDataBuf;
52
53 static uint32_t g_dataBufferMaxLen = 0;
54 static SoftBusList *g_tcpDataList = NULL;
55
PackTcpDataPacketHead(TcpDataPacketHead * data)56 static void PackTcpDataPacketHead(TcpDataPacketHead *data)
57 {
58 data->magicNumber = SoftBusHtoLl(data->magicNumber);
59 data->seq = (int32_t)SoftBusHtoLl((uint32_t)data->seq);
60 data->flags = SoftBusHtoLl(data->flags);
61 data->dataLen = SoftBusHtoLl(data->dataLen);
62 }
63
UnpackTcpDataPacketHead(TcpDataPacketHead * data)64 static void UnpackTcpDataPacketHead(TcpDataPacketHead *data)
65 {
66 data->magicNumber = SoftBusLtoHl(data->magicNumber);
67 data->seq = (int32_t)SoftBusLtoHl((uint32_t)data->seq);
68 data->flags = SoftBusLtoHl(data->flags);
69 data->dataLen = SoftBusLtoHl(data->dataLen);
70 }
71
TransTdcDecrypt(const char * sessionKey,const char * in,uint32_t inLen,char * out,uint32_t * outLen)72 static int32_t TransTdcDecrypt(const char *sessionKey, const char *in, uint32_t inLen, char *out, uint32_t *outLen)
73 {
74 AesGcmCipherKey cipherKey = {0};
75 cipherKey.keyLen = SESSION_KEY_LENGTH; // 256 bit encryption
76 if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKey, SESSION_KEY_LENGTH) != EOK) {
77 TRANS_LOGE(TRANS_SDK, "memcpy key error.");
78 return SOFTBUS_ERR;
79 }
80 int32_t ret = SoftBusDecryptData(&cipherKey, (unsigned char*)in, inLen, (unsigned char*)out, outLen);
81 (void)memset_s(&cipherKey, sizeof(AesGcmCipherKey), 0, sizeof(AesGcmCipherKey));
82 if (ret != SOFTBUS_OK) {
83 TRANS_LOGE(TRANS_SDK, "SoftBusDecryptData fail ret=%{public}d.", ret);
84 return SOFTBUS_DECRYPT_ERR;
85 }
86 return SOFTBUS_OK;
87 }
88
TransTdcEncryptWithSeq(const char * sessionKey,int32_t seqNum,const char * in,uint32_t inLen,char * out,uint32_t * outLen)89 static int32_t TransTdcEncryptWithSeq(const char *sessionKey, int32_t seqNum, const char *in, uint32_t inLen,
90 char *out, uint32_t *outLen)
91 {
92 AesGcmCipherKey cipherKey = {0};
93 cipherKey.keyLen = SESSION_KEY_LENGTH;
94 if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKey, SESSION_KEY_LENGTH) != EOK) {
95 TRANS_LOGE(TRANS_SDK, "memcpy key error.");
96 return SOFTBUS_ERR;
97 }
98 int ret = SoftBusEncryptDataWithSeq(&cipherKey, (unsigned char*)in, inLen, (unsigned char*)out, outLen, seqNum);
99 if (memset_s(&cipherKey, sizeof(AesGcmCipherKey), 0, sizeof(AesGcmCipherKey)) != EOK) {
100 TRANS_LOGE(TRANS_SDK, "memset cipherKey failed.");
101 return SOFTBUS_MEM_ERR;
102 }
103 if (ret != SOFTBUS_OK || *outLen != inLen + OVERHEAD_LEN) {
104 TRANS_LOGE(TRANS_SDK, "encrypt error.");
105 return SOFTBUS_ENCRYPT_ERR;
106 }
107 return SOFTBUS_OK;
108 }
109
TransTdcSetPendingPacket(int32_t channelId,const char * data,uint32_t len)110 static int32_t TransTdcSetPendingPacket(int32_t channelId, const char *data, uint32_t len)
111 {
112 if (len != ACK_SIZE) {
113 TRANS_LOGE(TRANS_SDK, "recv invalid seq.");
114 return SOFTBUS_ERR;
115 }
116
117 int32_t seq = (int32_t)SoftBusNtoHl(*(uint32_t *)data);
118 if (SetPendingPacket(channelId, seq, PENDING_TYPE_DIRECT) != SOFTBUS_OK) {
119 TRANS_LOGE(TRANS_SDK, "can not match seq=%{public}d", seq);
120 return SOFTBUS_ERR;
121 }
122 return SOFTBUS_OK;
123 }
124
TransTdcPackData(const TcpDirectChannelInfo * channel,const char * data,uint32_t len,int flags,uint32_t * outLen)125 static char *TransTdcPackData(const TcpDirectChannelInfo *channel, const char *data, uint32_t len, int flags,
126 uint32_t *outLen)
127 {
128 uint32_t dataLen = len + OVERHEAD_LEN;
129 char *buf = (char *)SoftBusMalloc(dataLen + DC_DATA_HEAD_SIZE);
130 if (buf == NULL) {
131 TRANS_LOGE(TRANS_SDK, "malloc failed.");
132 return NULL;
133 }
134
135 char *finalData = (char *)data;
136 int32_t finalSeq = channel->detail.sequence;
137 uint32_t tmpSeq;
138 if (flags == FLAG_ACK) {
139 finalSeq = *((int32_t *)data);
140 tmpSeq = SoftBusHtoNl((uint32_t)finalSeq);
141 finalData = (char *)(&tmpSeq);
142 }
143
144 TcpDataPacketHead pktHead = {
145 .magicNumber = MAGIC_NUMBER,
146 .seq = finalSeq,
147 .flags = (uint32_t)flags,
148 .dataLen = dataLen,
149 };
150 PackTcpDataPacketHead(&pktHead);
151 if (memcpy_s(buf, DC_DATA_HEAD_SIZE, &pktHead, sizeof(TcpDataPacketHead)) != EOK) {
152 SoftBusFree(buf);
153 TRANS_LOGE(TRANS_SDK, "memcpy_s error");
154 return NULL;
155 }
156 if (TransTdcEncryptWithSeq(channel->detail.sessionKey, finalSeq, finalData, len,
157 buf + DC_DATA_HEAD_SIZE, outLen) != SOFTBUS_OK) {
158 TRANS_LOGE(TRANS_SDK, "encrypt error");
159 SoftBusFree(buf);
160 return NULL;
161 }
162 return buf;
163 }
164
CheckCollaborationSessionName(const char * sessionName)165 static bool CheckCollaborationSessionName(const char *sessionName)
166 {
167 if (strstr(sessionName, "ohos.collaborationcenter") != NULL) {
168 return true;
169 }
170 return false;
171 }
172
TransTdcProcessPostData(const TcpDirectChannelInfo * channel,const char * data,uint32_t len,int32_t flags)173 static int32_t TransTdcProcessPostData(const TcpDirectChannelInfo *channel, const char *data, uint32_t len,
174 int32_t flags)
175 {
176 uint32_t outLen = 0;
177 char *buf = TransTdcPackData(channel, data, len, flags, &outLen);
178 if (buf == NULL) {
179 TRANS_LOGE(TRANS_SDK, "failed to pack bytes.");
180 return SOFTBUS_ENCRYPT_ERR;
181 }
182 if (outLen != len + OVERHEAD_LEN) {
183 TRANS_LOGE(TRANS_SDK, "pack bytes len error, outLen=%{public}d", outLen);
184 SoftBusFree(buf);
185 return SOFTBUS_ENCRYPT_ERR;
186 }
187 char sessionName[SESSION_NAME_SIZE_MAX + 1] = { 0 };
188 if (ClientGetSessionNameByChannelId(channel->channelId, channel->detail.channelType,
189 sessionName, SESSION_NAME_SIZE_MAX)) {
190 TRANS_LOGE(TRANS_SDK, "failed to get sessionName, channelId=%{public}d", channel->channelId);
191 SoftBusFree(buf);
192 return SOFTBUS_ERR;
193 }
194 uint32_t tos = (flags == FLAG_BYTES) ? BYTE_TOS : MESSAGE_TOS;
195 if (CheckCollaborationSessionName(sessionName)) {
196 tos = (flags == FLAG_BYTES) ? COLLABORATE_BYTE_TOS : MESSAGE_TOS;
197 }
198 if (SetIpTos(channel->detail.fd, tos) != SOFTBUS_OK) {
199 SoftBusFree(buf);
200 return SOFTBUS_TCP_SOCKET_ERR;
201 }
202 ssize_t ret = ConnSendSocketData(channel->detail.fd, buf, outLen + DC_DATA_HEAD_SIZE, 0);
203 if (ret != (ssize_t)outLen + DC_DATA_HEAD_SIZE) {
204 TRANS_LOGE(TRANS_SDK, "failed to send tcp data. ret=%{public}zd", ret);
205 SoftBusFree(buf);
206 return SOFTBUS_ERR;
207 }
208 SoftBusFree(buf);
209 buf = NULL;
210 return SOFTBUS_OK;
211 }
212
TransTdcSendBytes(int32_t channelId,const char * data,uint32_t len)213 int32_t TransTdcSendBytes(int32_t channelId, const char *data, uint32_t len)
214 {
215 if (data == NULL || len == 0) {
216 TRANS_LOGE(TRANS_SDK, "param invalid. channelId=%{public}d", channelId);
217 return SOFTBUS_INVALID_PARAM;
218 }
219 TcpDirectChannelInfo channel;
220 (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo));
221 if (TransTdcGetInfoByIdWithIncSeq(channelId, &channel) == NULL) {
222 TRANS_LOGE(TRANS_SDK, "TransTdcGetInfoByIdWithIncSeq failed, channelId=%{public}d.", channelId);
223 return SOFTBUS_ERR;
224 }
225
226 int ret = TransTdcProcessPostData(&channel, data, len, FLAG_BYTES);
227 (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo));
228 if (ret != SOFTBUS_OK) {
229 TRANS_LOGE(TRANS_SDK, "tdc send bytes failed, channelId=%{public}d, ret=%{public}d.", channelId, ret);
230 return ret;
231 }
232
233 return SOFTBUS_OK;
234 }
235
TransTdcSendMessage(int32_t channelId,const char * data,uint32_t len)236 int32_t TransTdcSendMessage(int32_t channelId, const char *data, uint32_t len)
237 {
238 if (data == NULL || len == 0) {
239 TRANS_LOGE(TRANS_SDK, "param invalid. channelId=%{public}d", channelId);
240 return SOFTBUS_INVALID_PARAM;
241 }
242
243 TcpDirectChannelInfo channel;
244 (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo));
245 if (TransTdcGetInfoByIdWithIncSeq(channelId, &channel) == NULL) {
246 return SOFTBUS_TRANS_TDC_CHANNEL_NOT_FOUND;
247 }
248 int32_t ret = TransTdcProcessPostData(&channel, data, len, FLAG_MESSAGE);
249 int32_t sequence = channel.detail.sequence;
250 (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo));
251 if (ret != SOFTBUS_OK) {
252 TRANS_LOGE(TRANS_SDK, "tdc send message failed, ret=%{public}d.", ret);
253 return ret;
254 }
255 return ProcPendingPacket(channelId, sequence, PENDING_TYPE_DIRECT);
256 }
257
TransTdcSendAck(const TcpDirectChannelInfo * channel,int32_t seq)258 static int32_t TransTdcSendAck(const TcpDirectChannelInfo *channel, int32_t seq)
259 {
260 if (channel == NULL) {
261 TRANS_LOGE(TRANS_SDK, "channel is null.");
262 return SOFTBUS_ERR;
263 }
264
265 return TransTdcProcessPostData(channel, (char*)(&seq), ACK_SIZE, FLAG_ACK);
266 }
267
TransGetDataBufSize(void)268 static uint32_t TransGetDataBufSize(void)
269 {
270 return MIN_BUF_LEN;
271 }
272
273 #define SLICE_HEAD_LEN 16
TransGetDataBufMaxSize(void)274 static int32_t TransGetDataBufMaxSize(void)
275 {
276 uint32_t maxLen = 0;
277 if (SoftbusGetConfig(SOFTBUS_INT_MAX_BYTES_NEW_LENGTH, (unsigned char *)&maxLen, sizeof(maxLen)) != SOFTBUS_OK) {
278 TRANS_LOGE(TRANS_SDK, "get config err");
279 return SOFTBUS_ERR;
280 }
281 g_dataBufferMaxLen = maxLen + DATA_EXTEND_LEN + SLICE_HEAD_LEN;
282 return SOFTBUS_OK;
283 }
284
TransAddDataBufNode(int32_t channelId,int32_t fd)285 int32_t TransAddDataBufNode(int32_t channelId, int32_t fd)
286 {
287 if (g_tcpDataList == NULL) {
288 TRANS_LOGE(TRANS_SDK, "g_tcpDataList is null.");
289 return SOFTBUS_ERR;
290 }
291 ClientDataBuf *node = (ClientDataBuf *)SoftBusCalloc(sizeof(ClientDataBuf));
292 if (node == NULL) {
293 TRANS_LOGE(TRANS_SDK, "calloc failed.");
294 return SOFTBUS_ERR;
295 }
296 node->channelId = channelId;
297 node->fd = fd;
298 node->size = TransGetDataBufSize();
299 node->data = (char *)SoftBusCalloc(node->size);
300 if (node->data == NULL) {
301 SoftBusFree(node);
302 TRANS_LOGE(TRANS_SDK, "calloc data failed.");
303 return SOFTBUS_ERR;
304 }
305 node->w = node->data;
306
307 if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
308 TRANS_LOGE(TRANS_SDK, "lock failed.");
309 SoftBusFree(node->data);
310 SoftBusFree(node);
311 return SOFTBUS_ERR;
312 }
313 ListAdd(&g_tcpDataList->list, &node->node);
314 TRANS_LOGI(TRANS_SDK, "add channelId=%{public}d", channelId);
315 g_tcpDataList->cnt++;
316 SoftBusMutexUnlock(&g_tcpDataList->lock);
317 return SOFTBUS_OK;
318 }
319
TransDelDataBufNode(int32_t channelId)320 int32_t TransDelDataBufNode(int32_t channelId)
321 {
322 if (g_tcpDataList == NULL) {
323 return SOFTBUS_ERR;
324 }
325
326 if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
327 TRANS_LOGE(TRANS_SDK, "lock failed.");
328 return SOFTBUS_ERR;
329 }
330 ClientDataBuf *item = NULL;
331 ClientDataBuf *next = NULL;
332 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_tcpDataList->list, ClientDataBuf, node) {
333 if (item->channelId == channelId) {
334 ListDelete(&item->node);
335 TRANS_LOGI(TRANS_SDK, "delete channelId=%{public}d", channelId);
336 SoftBusFree(item->data);
337 SoftBusFree(item);
338 g_tcpDataList->cnt--;
339 break;
340 }
341 }
342 SoftBusMutexUnlock(&g_tcpDataList->lock);
343
344 return SOFTBUS_OK;
345 }
346
TransDestroyDataBuf(void)347 static int32_t TransDestroyDataBuf(void)
348 {
349 if (g_tcpDataList == NULL) {
350 return SOFTBUS_ERR;
351 }
352
353 if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
354 TRANS_LOGE(TRANS_SDK, "lock failed.");
355 return SOFTBUS_ERR;
356 }
357 ClientDataBuf *item = NULL;
358 ClientDataBuf *next = NULL;
359 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_tcpDataList->list, ClientDataBuf, node) {
360 ListDelete(&item->node);
361 SoftBusFree(item->data);
362 SoftBusFree(item);
363 g_tcpDataList->cnt--;
364 }
365 SoftBusMutexUnlock(&g_tcpDataList->lock);
366
367 return SOFTBUS_OK;
368 }
369
TransGetDataBufNodeById(int32_t channelId)370 static ClientDataBuf *TransGetDataBufNodeById(int32_t channelId)
371 {
372 if (g_tcpDataList == NULL) {
373 return NULL;
374 }
375
376 ClientDataBuf *item = NULL;
377 LIST_FOR_EACH_ENTRY(item, &(g_tcpDataList->list), ClientDataBuf, node) {
378 if (item->channelId == channelId) {
379 return item;
380 }
381 }
382 TRANS_LOGE(TRANS_SDK, "tcp direct channel not exist. channelId=%{public}d", channelId);
383 return NULL;
384 }
385
TransTdcProcessDataByFlag(uint32_t flag,int32_t seqNum,const TcpDirectChannelInfo * channel,const char * plain,uint32_t plainLen)386 static int32_t TransTdcProcessDataByFlag(uint32_t flag, int32_t seqNum, const TcpDirectChannelInfo *channel,
387 const char *plain, uint32_t plainLen)
388 {
389 switch (flag) {
390 case FLAG_BYTES:
391 return ClientTransTdcOnDataReceived(channel->channelId, plain, plainLen, TRANS_SESSION_BYTES);
392 case FLAG_ACK:
393 TransTdcSetPendingPacket(channel->channelId, plain, plainLen);
394 return SOFTBUS_OK;
395 case FLAG_MESSAGE:
396 TransTdcSendAck(channel, seqNum);
397 return ClientTransTdcOnDataReceived(channel->channelId, plain, plainLen, TRANS_SESSION_MESSAGE);
398 default:
399 TRANS_LOGE(TRANS_SDK, "unknown flag=%{public}d.", flag);
400 return SOFTBUS_ERR;
401 }
402 }
403
TransTdcProcessData(int32_t channelId)404 static int32_t TransTdcProcessData(int32_t channelId)
405 {
406 TcpDirectChannelInfo channel;
407 if (TransTdcGetInfoById(channelId, &channel) == NULL) {
408 TRANS_LOGE(TRANS_SDK, "get key fail. channelId=%{public}d ", channelId);
409 return SOFTBUS_ERR;
410 }
411
412 if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
413 return SOFTBUS_ERR;
414 }
415 ClientDataBuf *node = TransGetDataBufNodeById(channelId);
416 if (node == NULL) {
417 TRANS_LOGE(TRANS_SDK, "node is null. channelId=%{public}d ", channelId);
418 SoftBusMutexUnlock(&g_tcpDataList->lock);
419 return SOFTBUS_ERR;
420 }
421 TcpDataPacketHead *pktHead = (TcpDataPacketHead *)(node->data);
422 int32_t seqNum = pktHead->seq;
423 uint32_t flag = pktHead->flags;
424 uint32_t dataLen = pktHead->dataLen;
425 TRANS_LOGE(TRANS_SDK, "data has all received, channelId=%{public}d, dataLen=%{public}u", channelId, dataLen);
426 char *plain = (char *)SoftBusCalloc(dataLen - OVERHEAD_LEN);
427 if (plain == NULL) {
428 TRANS_LOGE(TRANS_SDK, "malloc fail.");
429 SoftBusMutexUnlock(&g_tcpDataList->lock);
430 return SOFTBUS_MALLOC_ERR;
431 }
432
433 uint32_t plainLen;
434 int ret = TransTdcDecrypt(channel.detail.sessionKey, node->data + DC_DATA_HEAD_SIZE, dataLen, plain, &plainLen);
435 if (ret != SOFTBUS_OK) {
436 TRANS_LOGE(TRANS_SDK, "decrypt fail.");
437 SoftBusFree(plain);
438 SoftBusMutexUnlock(&g_tcpDataList->lock);
439 return SOFTBUS_DECRYPT_ERR;
440 }
441 char *end = node->data + DC_DATA_HEAD_SIZE + dataLen;
442 if (memmove_s(node->data, node->size, end, node->w - end) != EOK) {
443 TRANS_LOGE(TRANS_SDK, "memmove fail.");
444 SoftBusFree(plain);
445 SoftBusMutexUnlock(&g_tcpDataList->lock);
446 return SOFTBUS_MEM_ERR;
447 }
448 node->w = node->w - DC_DATA_HEAD_SIZE - dataLen;
449 SoftBusMutexUnlock(&g_tcpDataList->lock);
450
451 ret = TransTdcProcessDataByFlag(flag, seqNum, &channel, plain, plainLen);
452 if (ret != SOFTBUS_OK) {
453 TRANS_LOGE(TRANS_SDK, "process data fail");
454 }
455 SoftBusFree(plain);
456 return ret;
457 }
458
TransResizeDataBuffer(ClientDataBuf * oldBuf,uint32_t pkgLen)459 static int32_t TransResizeDataBuffer(ClientDataBuf *oldBuf, uint32_t pkgLen)
460 {
461 TRANS_LOGI(TRANS_SDK, "Resize Data Buffer channelId=%{public}d, pkgLen=%{public}d",
462 oldBuf->channelId, pkgLen);
463 char *newBuf = (char *)SoftBusCalloc(pkgLen);
464 if (newBuf == NULL) {
465 TRANS_LOGE(TRANS_SDK, "malloc err pkgLen=%{public}u", pkgLen);
466 return SOFTBUS_MEM_ERR;
467 }
468 uint32_t bufLen = oldBuf->w - oldBuf->data;
469 if (memcpy_s(newBuf, pkgLen, oldBuf->data, bufLen) != EOK) {
470 SoftBusFree(newBuf);
471 return SOFTBUS_MEM_ERR;
472 }
473 SoftBusFree(oldBuf->data);
474 oldBuf->data = NULL;
475 oldBuf->data = newBuf;
476 oldBuf->size = pkgLen;
477 oldBuf->w = newBuf + bufLen;
478 TRANS_LOGI(TRANS_SDK, "TransResizeDataBuffer ok");
479 return SOFTBUS_OK;
480 }
481
TransTdcProcAllData(int32_t channelId)482 static int32_t TransTdcProcAllData(int32_t channelId)
483 {
484 while (1) {
485 SoftBusMutexLock(&g_tcpDataList->lock);
486 ClientDataBuf *node = TransGetDataBufNodeById(channelId);
487 if (node == NULL) {
488 SoftBusMutexUnlock(&g_tcpDataList->lock);
489 TRANS_LOGE(TRANS_SDK, "can not find data buf node. channelId=%{public}d", channelId);
490 return SOFTBUS_ERR;
491 }
492 uint32_t bufLen = node->w - node->data;
493 if (bufLen == 0) {
494 SoftBusMutexUnlock(&g_tcpDataList->lock);
495 return SOFTBUS_OK;
496 }
497 if (bufLen < DC_DATA_HEAD_SIZE) {
498 TRANS_LOGW(TRANS_SDK,
499 " head bufLen not enough, recv biz head next time. channelId=%{public}d, bufLen=%{public}d", channelId,
500 bufLen);
501 SoftBusMutexUnlock(&g_tcpDataList->lock);
502 return SOFTBUS_DATA_NOT_ENOUGH;
503 }
504
505 TcpDataPacketHead *pktHead = (TcpDataPacketHead *)(node->data);
506 UnpackTcpDataPacketHead(pktHead);
507 if (pktHead->magicNumber != MAGIC_NUMBER) {
508 TRANS_LOGE(TRANS_SDK, "invalid data packet head. channelId=%{public}d", channelId);
509 SoftBusMutexUnlock(&g_tcpDataList->lock);
510 return SOFTBUS_ERR;
511 }
512
513 if ((pktHead->dataLen > g_dataBufferMaxLen - DC_DATA_HEAD_SIZE) || (pktHead->dataLen <= OVERHEAD_LEN)) {
514 TRANS_LOGE(TRANS_SDK, "illegal dataLen=%{public}d", pktHead->dataLen);
515 SoftBusMutexUnlock(&g_tcpDataList->lock);
516 return SOFTBUS_ERR;
517 }
518 uint32_t pkgLen = pktHead->dataLen + DC_DATA_HEAD_SIZE;
519
520 if (pkgLen > node->size && pkgLen <= g_dataBufferMaxLen) {
521 int32_t ret = TransResizeDataBuffer(node, pkgLen);
522 SoftBusMutexUnlock(&g_tcpDataList->lock);
523 return ret;
524 }
525 SoftBusMutexUnlock(&g_tcpDataList->lock);
526
527 if (bufLen < pkgLen) {
528 TRANS_LOGE(TRANS_SDK, "data bufLen not enough, recv biz data next time. bufLen=%{public}d ", bufLen);
529 return SOFTBUS_DATA_NOT_ENOUGH;
530 }
531
532 if (TransTdcProcessData(channelId) != SOFTBUS_OK) {
533 TRANS_LOGE(TRANS_SDK, "data received failed");
534 return SOFTBUS_ERR;
535 }
536 }
537 }
538
TransClientGetTdcDataBufByChannel(int32_t channelId,int32_t * fd,size_t * len)539 static int32_t TransClientGetTdcDataBufByChannel(int32_t channelId, int32_t *fd, size_t *len)
540 {
541 if (fd == NULL || len == NULL) {
542 TRANS_LOGE(TRANS_SDK, "invalid param.");
543 return SOFTBUS_ERR;
544 }
545
546 if (g_tcpDataList == NULL) {
547 TRANS_LOGE(TRANS_SDK, "tdc data list empty.");
548 return SOFTBUS_ERR;
549 }
550
551 if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
552 TRANS_LOGE(TRANS_SDK, "lock failed.");
553 return SOFTBUS_ERR;
554 }
555 ClientDataBuf *item = NULL;
556 LIST_FOR_EACH_ENTRY(item, &(g_tcpDataList->list), ClientDataBuf, node) {
557 if (item->channelId == channelId) {
558 *fd = item->fd;
559 *len = item->size - (item->w - item->data);
560 (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
561 return SOFTBUS_OK;
562 }
563 }
564 (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
565 TRANS_LOGE(TRANS_SDK, "client get tdc data buf not found. channelId=%{public}d", channelId);
566 return SOFTBUS_ERR;
567 }
568
TransClientUpdateTdcDataBufWInfo(int32_t channelId,char * recvBuf,int32_t recvLen)569 static int32_t TransClientUpdateTdcDataBufWInfo(int32_t channelId, char *recvBuf, int32_t recvLen)
570 {
571 if (recvBuf == NULL) {
572 TRANS_LOGE(TRANS_SDK, "invalid param.");
573 return SOFTBUS_ERR;
574 }
575 if (g_tcpDataList == NULL) {
576 TRANS_LOGE(TRANS_SDK, "data list empty.");
577 return SOFTBUS_ERR;
578 }
579 if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
580 TRANS_LOGE(TRANS_SDK, "lock failed.");
581 return SOFTBUS_ERR;
582 }
583
584 ClientDataBuf *item = NULL;
585 ClientDataBuf *nextItem = NULL;
586 LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &(g_tcpDataList->list), ClientDataBuf, node) {
587 if (item->channelId != channelId) {
588 continue;
589 }
590 int32_t freeLen = (int32_t)(item->size) - (item->w - item->data);
591 if (recvLen > freeLen) {
592 (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
593 TRANS_LOGE(TRANS_SDK,
594 "client tdc recvLen override freeLen. recvLen=%{public}d, freeLen=%{public}d", recvLen, freeLen);
595 return SOFTBUS_ERR;
596 }
597 if (memcpy_s(item->w, recvLen, recvBuf, recvLen) != EOK) {
598 (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
599 TRANS_LOGE(TRANS_SDK, "client tdc memcpy failed. channelId=%{public}d", channelId);
600 return SOFTBUS_ERR;
601 }
602 item->w += recvLen;
603 (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
604 TRANS_LOGI(TRANS_SDK, "client update tdc data success, channelId=%{public}d", channelId);
605 return SOFTBUS_OK;
606 }
607 (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
608 TRANS_LOGE(TRANS_SDK, "client update tdc data buf not found. channelId=%{public}d", channelId);
609 return SOFTBUS_ERR;
610 }
611
TransTdcRecvData(int32_t channelId)612 int32_t TransTdcRecvData(int32_t channelId)
613 {
614 int32_t fd = -1;
615 size_t len = 0;
616 if (TransClientGetTdcDataBufByChannel(channelId, &fd, &len) != SOFTBUS_OK) {
617 return SOFTBUS_ERR;
618 }
619 if (len == 0 || len > g_dataBufferMaxLen) {
620 TRANS_LOGE(TRANS_SDK,
621 "client tdc free databuf len invalid. channelId=%{public}d, len=%{public}zu", channelId, len);
622 return SOFTBUS_ERR;
623 }
624
625 char *recvBuf = (char*)SoftBusCalloc(len);
626 if (recvBuf == NULL) {
627 TRANS_LOGE(TRANS_SDK, "client tdc calloc failed. channelId=%{public}d, len=%{public}zu", channelId, len);
628 return SOFTBUS_ERR;
629 }
630
631 int32_t recvLen = ConnRecvSocketData(fd, recvBuf, len, 0);
632 if (recvLen < 0) {
633 SoftBusFree(recvBuf);
634 TRANS_LOGE(TRANS_SDK, "client recv data failed, channelId=%{public}d, recvLen=%{public}d.", channelId, recvLen);
635 return SOFTBUS_ERR;
636 } else if (recvLen == 0) {
637 SoftBusFree(recvBuf);
638 return SOFTBUS_DATA_NOT_ENOUGH;
639 }
640
641 if (TransClientUpdateTdcDataBufWInfo(channelId, recvBuf, recvLen) != SOFTBUS_OK) {
642 SoftBusFree(recvBuf);
643 TRANS_LOGE(TRANS_SDK, "client update data buf failed. channelId=%{public}d", channelId);
644 return SOFTBUS_ERR;
645 }
646 SoftBusFree(recvBuf);
647
648 return TransTdcProcAllData(channelId);
649 }
650
TransDataListInit(void)651 int32_t TransDataListInit(void)
652 {
653 if (g_tcpDataList != NULL) {
654 TRANS_LOGI(TRANS_SDK, "g_tcpDataList already init");
655 return SOFTBUS_OK;
656 }
657 if (TransGetDataBufMaxSize() != SOFTBUS_OK) {
658 TRANS_LOGE(TRANS_SDK, "TransGetDataBufMaxSize failed");
659 return SOFTBUS_ERR;
660 }
661 g_tcpDataList = CreateSoftBusList();
662 if (g_tcpDataList == NULL) {
663 TRANS_LOGE(TRANS_SDK, "g_tcpDataList creat list failed");
664 return SOFTBUS_ERR;
665 }
666 return SOFTBUS_OK;
667 }
668
TransDataListDeinit(void)669 void TransDataListDeinit(void)
670 {
671 if (g_tcpDataList == NULL) {
672 return;
673 }
674 (void)TransDestroyDataBuf();
675 DestroySoftBusList(g_tcpDataList);
676 g_tcpDataList = NULL;
677 }
678