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