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