• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 "trans_assemble_tlv.h"
21 #include "client_trans_tcp_direct_callback.h"
22 #include "client_trans_tcp_direct_manager.h"
23 #include "client_trans_session_manager.h"
24 #include "client_trans_socket_manager.h"
25 #include "common_list.h"
26 #include "softbus_adapter_crypto.h"
27 #include "softbus_adapter_mem.h"
28 #include "softbus_adapter_socket.h"
29 #include "softbus_def.h"
30 #include "softbus_error_code.h"
31 #include "softbus_feature_config.h"
32 #include "softbus_socket.h"
33 #include "softbus_tcp_socket.h"
34 #include "softbus_utils.h"
35 #include "trans_log.h"
36 #include "trans_pending_pkt.h"
37 #include "trans_tcp_process_data.h"
38 #include "softbus_mintp_socket.h"
39 
40 #define ACK_SIZE 4
41 
42 #define BYTE_TOS 0x60
43 #define COLLABORATE_BYTE_TOS 0x80
44 #define MESSAGE_TOS 0xC0
45 #define MAGICNUM_SIZE sizeof(uint32_t)
46 #define TLVCOUNT_SIZE sizeof(uint8_t)
47 
48 static SoftBusList *g_tcpDataList = NULL;
49 
TransTdcSetPendingPacket(int32_t channelId,const char * data,uint32_t len,uint32_t dataSeq)50 static int32_t TransTdcSetPendingPacket(int32_t channelId, const char *data, uint32_t len, uint32_t dataSeq)
51 {
52     if (len != ACK_SIZE) {
53         TRANS_LOGE(TRANS_SDK, "recv invalid seq.");
54         return SOFTBUS_INVALID_PARAM;
55     }
56     if (dataSeq != 0) { // A non-zero value indicates asynchronous. PendingPacket does not need to be set.
57         int32_t socketId = INVALID_SESSION_ID;
58         SessionListenerAdapter sessionCallback;
59         bool isServer = false;
60         (void)memset_s(&sessionCallback, sizeof(SessionListenerAdapter), 0, sizeof(SessionListenerAdapter));
61         int32_t ret = ClientGetSessionIdByChannelId(channelId, CHANNEL_TYPE_TCP_DIRECT, &socketId, false);
62         if (ret != SOFTBUS_OK) {
63             TRANS_LOGE(TRANS_SDK, "get socketId failed, channelId=%{public}d", channelId);
64             return ret;
65         }
66         ret = ClientGetSessionCallbackAdapterById(socketId, &sessionCallback, &isServer);
67         if (ret != SOFTBUS_OK) {
68             TRANS_LOGE(TRANS_SDK, "get session callback failed, channelId=%{public}d", channelId);
69             return ret;
70         }
71         ret = DeleteDataSeqInfoList(dataSeq, channelId);
72         if (ret != SOFTBUS_OK) {
73             TRANS_LOGE(TRANS_SDK, "tcp delete dataSeqInfoList failed, channelId=%{public}d", channelId);
74             return ret;
75         }
76         if (sessionCallback.socketClient.OnBytesSent == NULL) {
77             TRANS_LOGE(TRANS_SDK, "OnBytesSent is null, channelId=%{public}d", channelId);
78             return SOFTBUS_INVALID_PARAM;
79         }
80         sessionCallback.socketClient.OnBytesSent(socketId, dataSeq, SOFTBUS_OK);
81         return SOFTBUS_OK;
82     }
83     int32_t seq = (int32_t)SoftBusNtoHl(*(uint32_t *)data);
84     int32_t ret = SetPendingPacket(channelId, seq, PENDING_TYPE_DIRECT);
85     if (ret != SOFTBUS_OK) {
86         TRANS_LOGE(TRANS_SDK, "can not match seq=%{public}d", seq);
87         return ret;
88     }
89     return SOFTBUS_OK;
90 }
91 
TransTdcPackData(const TcpDirectChannelInfo * channel,const char * data,uint32_t len,int32_t flags,DataLenInfo * lenInfo)92 static char *TransTdcPackData(const TcpDirectChannelInfo *channel, const char *data, uint32_t len, int32_t flags,
93     DataLenInfo *lenInfo)
94 {
95     bool needAck = false;
96     bool supportTlv = false;
97     int32_t ret = GetSupportTlvAndNeedAckById(channel->channelId, CHANNEL_TYPE_TCP_DIRECT, &supportTlv, &needAck);
98     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, NULL, TRANS_SDK, "get need ack failed by channelId");
99     TransTdcPackDataInfo dataInfo = {
100         .needAck = needAck,
101         .supportTlv = supportTlv,
102         .seq = channel->detail.sequence,
103         .len = len,
104     };
105     return TransTdcPackAllData(&dataInfo, channel->detail.sessionKey, data, flags, lenInfo);
106 }
107 
CheckCollaborationSessionName(const char * sessionName)108 static bool CheckCollaborationSessionName(const char *sessionName)
109 {
110     if (strstr(sessionName, "ohos.collaborationcenter") != NULL) {
111         return true;
112     }
113     return false;
114 }
115 
TransTcpSetTos(TcpDirectChannelInfo * channel,int32_t flags)116 static int32_t TransTcpSetTos(TcpDirectChannelInfo *channel, int32_t flags)
117 {
118     if (channel == NULL) {
119         return SOFTBUS_INVALID_PARAM;
120     }
121     char sessionName[SESSION_NAME_SIZE_MAX + 1] = { 0 };
122     if (ClientGetSessionNameByChannelId(
123         channel->channelId, channel->detail.channelType, sessionName, SESSION_NAME_SIZE_MAX) != SOFTBUS_OK) {
124         TRANS_LOGE(TRANS_SDK, "failed to get sessionName, channelId=%{public}d", channel->channelId);
125         return SOFTBUS_TRANS_SESSION_NAME_NO_EXIST;
126     }
127     uint32_t tos = (flags == FLAG_BYTES) ? BYTE_TOS : MESSAGE_TOS;
128     if (CheckCollaborationSessionName(sessionName)) {
129         tos = (flags == FLAG_BYTES) ? COLLABORATE_BYTE_TOS : MESSAGE_TOS;
130     }
131     if (channel->detail.fdProtocol == LNN_PROTOCOL_MINTP) {
132         if (SetMintpSocketTos(channel->detail.fd, tos) != SOFTBUS_OK) {
133             return SOFTBUS_SOCKET_ERR;
134         }
135     } else if (channel->detail.fdProtocol != LNN_PROTOCOL_HTP) {
136         if (SetIpTos(channel->detail.fd, tos) != SOFTBUS_OK) {
137             return SOFTBUS_TCP_SOCKET_ERR;
138         }
139     }
140 
141     return SOFTBUS_OK;
142 }
143 
TransTdcProcessPostData(TcpDirectChannelInfo * channel,const char * data,uint32_t len,int32_t flags)144 static int32_t TransTdcProcessPostData(TcpDirectChannelInfo *channel, const char *data, uint32_t len, int32_t flags)
145 {
146     bool supportTlv = false;
147     int32_t ret = GetSupportTlvAndNeedAckById(channel->channelId, channel->detail.channelType, &supportTlv, NULL);
148     if (ret != SOFTBUS_OK) {
149         TRANS_LOGE(TRANS_SDK, "failed to get supprotTlv. channelId=%{public}d", channel->channelId);
150         return ret;
151     }
152     DataLenInfo lenInfo = { 0 };
153     char *buf = TransTdcPackData(channel, data, len, flags, &lenInfo);
154     TRANS_CHECK_AND_RETURN_RET_LOGE(buf != NULL, SOFTBUS_ENCRYPT_ERR, TRANS_SDK, "failed to pack bytes.");
155     ret = TransTcpSetTos(channel, flags);
156     if (ret != SOFTBUS_OK) {
157         TRANS_LOGE(TRANS_SDK, "failed to set tos. channelId=%{public}d", channel->channelId);
158         SoftBusFree(buf);
159         return ret;
160     }
161     if (SoftBusMutexLock(&(channel->detail.fdLock)) != SOFTBUS_OK) {
162         TRANS_LOGE(TRANS_SDK, "failed to lock fd. channelId=%{public}d", channel->channelId);
163         SoftBusFree(buf);
164         return SOFTBUS_LOCK_ERR;
165     }
166     ret = TransTdcSendData(&lenInfo, supportTlv, channel->detail.fd, len, buf);
167     if (ret != SOFTBUS_OK) {
168         TRANS_LOGE(TRANS_SDK, "failed to send data. channelId=%{public}d", channel->channelId);
169         SoftBusFree(buf);
170         (void)SoftBusMutexUnlock(&(channel->detail.fdLock));
171         return ret;
172     }
173     (void)SoftBusMutexUnlock(&(channel->detail.fdLock));
174     SoftBusFree(buf);
175     buf = NULL;
176     return SOFTBUS_OK;
177 }
178 
TransTdcSendBytes(int32_t channelId,const char * data,uint32_t len,bool needAck)179 int32_t TransTdcSendBytes(int32_t channelId, const char *data, uint32_t len, bool needAck)
180 {
181     if (data == NULL || len == 0) {
182         TRANS_LOGE(TRANS_SDK, "param invalid. channelId=%{public}d", channelId);
183         return SOFTBUS_INVALID_PARAM;
184     }
185     TcpDirectChannelInfo channel;
186     (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo));
187     if (TransTdcGetInfoIncFdRefById(channelId, &channel, true) == NULL) {
188         TRANS_LOGE(TRANS_SDK, "get info by id failed, channelId=%{public}d.", channelId);
189         return SOFTBUS_TRANS_TDC_GET_INFO_FAILED;
190     }
191     if (needAck) {
192         int32_t sequence = channel.detail.sequence;
193         int32_t ret = AddPendingPacket(channelId, sequence, PENDING_TYPE_DIRECT);
194         if (ret != SOFTBUS_OK) {
195             TRANS_LOGE(TRANS_SDK, "add pending packet failed, channelId=%{public}d.", channelId);
196             TransUpdateFdState(channel.channelId);
197             return ret;
198         }
199         if (channel.detail.needRelease) {
200             TRANS_LOGE(TRANS_SDK, "trans tdc channel need release, cancel sendBytes, channelId=%{public}d.", channelId);
201             TransUpdateFdState(channel.channelId);
202             return SOFTBUS_TRANS_TDC_CHANNEL_CLOSED_BY_ANOTHER_THREAD;
203         }
204         ret = TransTdcProcessPostData(&channel, data, len, FLAG_BYTES);
205         TransUpdateFdState(channel.channelId);
206         (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo));
207         if (ret != SOFTBUS_OK) {
208             DelPendingPacketbyChannelId(channelId, sequence, PENDING_TYPE_DIRECT);
209             TRANS_LOGE(TRANS_SDK, "tdc send bytes failed, channelId=%{public}d, ret=%{public}d.", channelId, ret);
210             return ret;
211         }
212         return ProcPendingPacket(channelId, sequence, PENDING_TYPE_DIRECT);
213     }
214     if (channel.detail.needRelease) {
215         TRANS_LOGE(TRANS_SDK, "trans tdc channel need release, cancel sendBytes, channelId=%{public}d.", channelId);
216         TransUpdateFdState(channel.channelId);
217         return SOFTBUS_TRANS_TDC_CHANNEL_CLOSED_BY_ANOTHER_THREAD;
218     }
219     int32_t ret = TransTdcProcessPostData(&channel, data, len, FLAG_BYTES);
220     TransUpdateFdState(channel.channelId);
221     (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo));
222     if (ret != SOFTBUS_OK) {
223         TRANS_LOGE(TRANS_SDK, "tdc send bytes failed, channelId=%{public}d, ret=%{public}d.", channelId, ret);
224         return ret;
225     }
226 
227     return SOFTBUS_OK;
228 }
229 
TransSetTosSendData(TcpDirectChannelInfo * channel,char * buf,int32_t newPkgHeadSize,int32_t flags,uint32_t outLen)230 static int32_t TransSetTosSendData(TcpDirectChannelInfo *channel, char *buf, int32_t newPkgHeadSize,
231     int32_t flags, uint32_t outLen)
232 {
233     if (channel == NULL) {
234         return SOFTBUS_INVALID_PARAM;
235     }
236     int32_t ret = TransTcpSetTos(channel, flags);
237     if (ret != SOFTBUS_OK) {
238         TRANS_LOGE(TRANS_SDK, "failed to set tos. channelId=%{public}d", channel->channelId);
239         SoftBusFree(buf);
240         return ret;
241     }
242     if (SoftBusMutexLock(&(channel->detail.fdLock)) != SOFTBUS_OK) {
243         TRANS_LOGE(TRANS_SDK, "failed to lock fd. channelId=%{public}d", channel->channelId);
244         SoftBusFree(buf);
245         return SOFTBUS_LOCK_ERR;
246     }
247     ssize_t res = ConnSendSocketData(channel->detail.fd, buf, outLen + newPkgHeadSize, 0);
248     if (res != (ssize_t)outLen + newPkgHeadSize) {
249         TRANS_LOGE(TRANS_SDK, "failed to send tcp data. res=%{public}zd", res);
250         (void)SoftBusMutexUnlock(&(channel->detail.fdLock));
251         SoftBusFree(buf);
252         return SOFTBUS_TRANS_SEND_LEN_BEYOND_LIMIT;
253     }
254     (void)SoftBusMutexUnlock(&(channel->detail.fdLock));
255     SoftBusFree(buf);
256     return SOFTBUS_OK;
257 }
258 
BuildTdcSendDataInfo(EncrptyInfo * enInfo,char * finalData,uint32_t inLen,char * out,uint32_t * outLen)259 static void BuildTdcSendDataInfo(EncrptyInfo *enInfo, char *finalData, uint32_t inLen, char *out, uint32_t *outLen)
260 {
261     enInfo->in = finalData;
262     enInfo->inLen = inLen;
263     enInfo->out = out;
264     enInfo->outLen = outLen;
265 }
266 
TransTdcNeedAckProcessPostData(TcpDirectChannelInfo * channel,const char * data,uint32_t len,int32_t flags,uint32_t dataSeq)267 static int32_t TransTdcNeedAckProcessPostData(TcpDirectChannelInfo *channel, const char *data, uint32_t len,
268     int32_t flags, uint32_t dataSeq)
269 {
270     uint32_t outLen = 0;
271     int32_t newPkgHeadSize = 0;
272     uint32_t dataLen = len + OVERHEAD_LEN;
273     char *finalData = (char *)data;
274     int32_t finalSeq = channel->detail.sequence;
275     uint32_t tmpSeq;
276     EncrptyInfo enInfo = { 0 };
277     if (flags == FLAG_ACK) {
278         finalSeq = *((int32_t *)data);
279         tmpSeq = SoftBusHtoNl((uint32_t)finalSeq);
280         finalData = (char *)(&tmpSeq);
281     }
282     DataHead pktHead = { 0 };
283     int32_t tlvBufferSize = 0;
284     int32_t ret = BuildDataHead(&pktHead, finalSeq, flags, dataLen, &tlvBufferSize);
285     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "build tlv dataHead error");
286     ret = BuildNeedAckTlvData(&pktHead, true, dataSeq, &tlvBufferSize); // asynchronous sendbytes must support reply ack
287     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "build tlv needAck error");
288     char *buf = TransTdcPackTlvData(&pktHead, tlvBufferSize, dataLen);
289     if (buf == NULL) {
290         ReleaseDataHeadResource(&pktHead);
291         TRANS_LOGE(TRANS_SDK, "pack data fail");
292         return SOFTBUS_TRANS_PACK_TLV_DATA_FAILED;
293     }
294     ReleaseDataHeadResource(&pktHead);
295     newPkgHeadSize = MAGICNUM_SIZE + TLVCOUNT_SIZE + tlvBufferSize;
296     BuildTdcSendDataInfo(&enInfo, finalData, len, buf + newPkgHeadSize, &outLen);
297     ret = TransTdcEncryptWithSeq(channel->detail.sessionKey, finalSeq, &enInfo);
298     (void)memset_s(channel->detail.sessionKey, SESSION_KEY_LENGTH, 0, SESSION_KEY_LENGTH);
299     if (ret != SOFTBUS_OK) {
300         TRANS_LOGE(TRANS_SDK, "encrypt error");
301         SoftBusFree(buf);
302         return ret;
303     }
304     if (outLen != len + OVERHEAD_LEN) {
305         TRANS_LOGE(TRANS_SDK, "pack bytes len error, outLen=%{public}d", outLen);
306         SoftBusFree(buf);
307         return SOFTBUS_ENCRYPT_ERR;
308     }
309     ret = TransSetTosSendData(channel, buf, newPkgHeadSize, flags, outLen);
310     if (ret != SOFTBUS_OK) {
311         TRANS_LOGE(TRANS_SDK, "set tos send data error, channelId=%{public}d", channel->channelId);
312         return ret;
313     }
314     return SOFTBUS_OK;
315 }
316 
TransTdcAsyncSendBytes(int32_t channelId,const char * data,uint32_t len,uint32_t dataSeq)317 int32_t TransTdcAsyncSendBytes(int32_t channelId, const char *data, uint32_t len, uint32_t dataSeq)
318 {
319     if (data == NULL || len == 0) {
320         TRANS_LOGE(TRANS_SDK, "param invalid. channelId=%{public}d", channelId);
321         return SOFTBUS_INVALID_PARAM;
322     }
323 
324     TcpDirectChannelInfo channel;
325     (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo));
326     if (TransTdcGetInfoIncFdRefById(channelId, &channel, true) == NULL) {
327         return SOFTBUS_TRANS_TDC_CHANNEL_NOT_FOUND;
328     }
329     if (channel.detail.needRelease) {
330         TRANS_LOGE(TRANS_SDK, "trans tdc channel need release, cancel sendBytes, channelId=%{public}d.", channelId);
331         return SOFTBUS_TRANS_TDC_CHANNEL_CLOSED_BY_ANOTHER_THREAD;
332     }
333     TransUpdateFdState(channel.channelId);
334     int32_t ret = TransTdcNeedAckProcessPostData(&channel, data, len, FLAG_BYTES, dataSeq);
335     if (ret != SOFTBUS_OK) {
336         TRANS_LOGE(TRANS_SDK, "tdc async send bytes failed, channelId=%{public}d, ret=%{public}d.", channelId, ret);
337         return ret;
338     }
339 
340     int32_t socketId = 0;
341     ret = ClientGetSessionIdByChannelId(channelId, channel.detail.channelType, &socketId, false);
342     if (ret != SOFTBUS_OK) {
343         TRANS_LOGE(TRANS_SDK, "tdc get sessionId failed, channelId=%{public}d, ret=%{public}d.", channelId, ret);
344         return ret;
345     }
346     ret = DataSeqInfoListAddItem(dataSeq, channelId, socketId, channel.detail.channelType);
347     if (ret != SOFTBUS_OK) {
348         TRANS_LOGE(TRANS_SDK, "tdc add seqInfoList failed, channelId=%{public}d, ret=%{public}d.", channelId, ret);
349         return ret;
350     }
351     return SOFTBUS_OK;
352 }
353 
TransTdcSendMessage(int32_t channelId,const char * data,uint32_t len)354 int32_t TransTdcSendMessage(int32_t channelId, const char *data, uint32_t len)
355 {
356     if (data == NULL || len == 0) {
357         TRANS_LOGE(TRANS_SDK, "param invalid. channelId=%{public}d", channelId);
358         return SOFTBUS_INVALID_PARAM;
359     }
360 
361     TcpDirectChannelInfo channel;
362     (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo));
363     if (TransTdcGetInfoIncFdRefById(channelId, &channel, true) == NULL) {
364         return SOFTBUS_TRANS_TDC_CHANNEL_NOT_FOUND;
365     }
366     int32_t sequence = channel.detail.sequence;
367     int32_t ret = AddPendingPacket(channelId, sequence, PENDING_TYPE_DIRECT);
368     if (ret != SOFTBUS_OK) {
369         TRANS_LOGE(TRANS_SDK, "add pending packet failed, channelId=%{public}d.", channelId);
370         return ret;
371     }
372     if (channel.detail.needRelease) {
373         TRANS_LOGE(TRANS_SDK, "trans tdc channel need release, cancel sendMessage, channelId=%{public}d.", channelId);
374         return SOFTBUS_TRANS_TDC_CHANNEL_CLOSED_BY_ANOTHER_THREAD;
375     }
376     ret = TransTdcProcessPostData(&channel, data, len, FLAG_MESSAGE);
377     TransUpdateFdState(channel.channelId);
378     (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo));
379     if (ret != SOFTBUS_OK) {
380         DelPendingPacketbyChannelId(channelId, sequence, PENDING_TYPE_DIRECT);
381         TRANS_LOGE(TRANS_SDK, "tdc send message failed, ret=%{public}d.", ret);
382         return ret;
383     }
384     return ProcPendingPacket(channelId, sequence, PENDING_TYPE_DIRECT);
385 }
386 
TransTdcSendAck(int32_t channelId,int32_t seq)387 static int32_t TransTdcSendAck(int32_t channelId, int32_t seq)
388 {
389     TcpDirectChannelInfo channel;
390     (void)memset_s(&channel, sizeof(TcpDirectChannelInfo), 0, sizeof(TcpDirectChannelInfo));
391     if (TransTdcGetInfoIncFdRefById(channelId, &channel, false) == NULL) {
392         TRANS_LOGE(TRANS_SDK, "get info by id failed, channelId=%{public}d.", channelId);
393         return SOFTBUS_TRANS_TDC_GET_INFO_FAILED;
394     }
395     if (channel.detail.needRelease) {
396         TRANS_LOGE(TRANS_SDK, "trans tdc channel need release, cancel sendMessage, channelId=%{public}d.", channelId);
397         return SOFTBUS_TRANS_TDC_CHANNEL_CLOSED_BY_ANOTHER_THREAD;
398     }
399     int32_t ret = TransTdcProcessPostData(&channel, (char *)(&seq), ACK_SIZE, FLAG_ACK);
400     TransUpdateFdState(channel.channelId);
401     return ret;
402 }
403 
TransTdcNeedSendAck(TcpDirectChannelInfo * channel,int32_t seq,uint32_t dataSeq,bool needAck)404 static int32_t TransTdcNeedSendAck(TcpDirectChannelInfo *channel, int32_t seq, uint32_t dataSeq, bool needAck)
405 {
406     if (channel == NULL) {
407         TRANS_LOGE(TRANS_SDK, "channel is null.");
408         return SOFTBUS_INVALID_PARAM;
409     }
410     if (needAck) {
411         TRANS_LOGI(TRANS_SDK, "tdc need send ack to client");
412         return TransTdcNeedAckProcessPostData(channel, (char *)(&seq), ACK_SIZE, FLAG_ACK, dataSeq);
413     }
414     return SOFTBUS_OK;
415 }
416 
TransAddDataBufNode(int32_t channelId,int32_t fd)417 int32_t TransAddDataBufNode(int32_t channelId, int32_t fd)
418 {
419     if (g_tcpDataList == NULL) {
420         TRANS_LOGE(TRANS_SDK, "g_tcpDataList is null.");
421         return SOFTBUS_NO_INIT;
422     }
423     DataBuf *node = (DataBuf *)SoftBusCalloc(sizeof(DataBuf));
424     if (node == NULL) {
425         TRANS_LOGE(TRANS_SDK, "malloc failed.");
426         return SOFTBUS_MALLOC_ERR;
427     }
428     node->channelId = channelId;
429     node->fd = fd;
430     node->size = TransGetDataBufSize();
431     node->data = (char *)SoftBusCalloc(node->size);
432     if (node->data == NULL) {
433         SoftBusFree(node);
434         TRANS_LOGE(TRANS_SDK, "malloc data failed.");
435         return SOFTBUS_MALLOC_ERR;
436     }
437     node->w = node->data;
438 
439     if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
440         TRANS_LOGE(TRANS_SDK, "lock failed.");
441         SoftBusFree(node->data);
442         SoftBusFree(node);
443         return SOFTBUS_LOCK_ERR;
444     }
445     ListAdd(&g_tcpDataList->list, &node->node);
446     TRANS_LOGI(TRANS_SDK, "add channelId=%{public}d", channelId);
447     g_tcpDataList->cnt++;
448     (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
449     return SOFTBUS_OK;
450 }
451 
TransDelDataBufNode(int32_t channelId)452 int32_t TransDelDataBufNode(int32_t channelId)
453 {
454     if (g_tcpDataList == NULL) {
455         return SOFTBUS_NO_INIT;
456     }
457 
458     if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
459         TRANS_LOGE(TRANS_SDK, "lock failed.");
460         return SOFTBUS_LOCK_ERR;
461     }
462     DataBuf *item = NULL;
463     DataBuf *next = NULL;
464     LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_tcpDataList->list, DataBuf, node) {
465         if (item->channelId == channelId) {
466             ListDelete(&item->node);
467             TRANS_LOGI(TRANS_SDK, "delete channelId=%{public}d", channelId);
468             SoftBusFree(item->data);
469             SoftBusFree(item);
470             g_tcpDataList->cnt--;
471             break;
472         }
473     }
474     (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
475 
476     return SOFTBUS_OK;
477 }
478 
TransDestroyDataBuf(void)479 static int32_t TransDestroyDataBuf(void)
480 {
481     if (g_tcpDataList == NULL) {
482         return SOFTBUS_NO_INIT;
483     }
484 
485     if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
486         TRANS_LOGE(TRANS_SDK, "lock failed.");
487         return SOFTBUS_LOCK_ERR;
488     }
489     DataBuf *item = NULL;
490     DataBuf *next = NULL;
491     LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_tcpDataList->list, DataBuf, node) {
492         ListDelete(&item->node);
493         SoftBusFree(item->data);
494         SoftBusFree(item);
495         g_tcpDataList->cnt--;
496     }
497     (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
498 
499     return SOFTBUS_OK;
500 }
501 
TransGetDataBufNodeById(int32_t channelId)502 static DataBuf *TransGetDataBufNodeById(int32_t channelId)
503 {
504     if (g_tcpDataList ==  NULL) {
505         return NULL;
506     }
507 
508     DataBuf *item = NULL;
509     LIST_FOR_EACH_ENTRY(item, &(g_tcpDataList->list), DataBuf, node) {
510         if (item->channelId == channelId) {
511             return item;
512         }
513     }
514     TRANS_LOGE(TRANS_SDK, "tcp direct channel not exist. channelId=%{public}d", channelId);
515     return NULL;
516 }
517 
TransTdcProcessDataByFlag(uint32_t flag,int32_t seqNum,TcpDirectChannelInfo * channel,const char * plain,uint32_t plainLen)518 static int32_t TransTdcProcessDataByFlag(
519     uint32_t flag, int32_t seqNum, TcpDirectChannelInfo *channel, const char *plain, uint32_t plainLen)
520 {
521     switch (flag) {
522         case FLAG_BYTES:
523             return ClientTransTdcOnDataReceived(channel->channelId, plain, plainLen, TRANS_SESSION_BYTES);
524         case FLAG_ACK:
525             TransTdcSetPendingPacket(channel->channelId, plain, plainLen, 0); // the old message process dataSeq is 0.
526             return SOFTBUS_OK;
527         case FLAG_MESSAGE:
528             TransTdcSendAck(channel->channelId, seqNum);
529             return ClientTransTdcOnDataReceived(channel->channelId, plain, plainLen, TRANS_SESSION_MESSAGE);
530         default:
531             TRANS_LOGE(TRANS_SDK, "unknown flag=%{public}d.", flag);
532             return SOFTBUS_INVALID_PARAM;
533     }
534 }
535 
TransTdcProcessBytesDataByFlag(TcpDataTlvPacketHead * pktHead,TcpDirectChannelInfo * channel,char * plain,uint32_t plainLen)536 static int32_t TransTdcProcessBytesDataByFlag(
537     TcpDataTlvPacketHead *pktHead, TcpDirectChannelInfo *channel, char *plain, uint32_t plainLen)
538 {
539     uint32_t flag = pktHead->flags;
540     int32_t seqNum = pktHead->seq;
541     uint32_t dataSeq = pktHead->dataSeq;
542     bool needAck = pktHead->needAck;
543     switch (flag) {
544         case FLAG_BYTES:
545             TransTdcNeedSendAck(channel, seqNum, dataSeq, needAck); // this is new sync process and async process
546             return ClientTransTdcOnDataReceived(channel->channelId, plain, plainLen, TRANS_SESSION_BYTES);
547         case FLAG_ACK:
548             TransTdcSetPendingPacket(channel->channelId, plain, plainLen, dataSeq); // the async or new sync process
549             return SOFTBUS_OK;
550         case FLAG_MESSAGE:
551             TransTdcSendAck(channel->channelId, seqNum);
552             return ClientTransTdcOnDataReceived(channel->channelId, plain, plainLen, TRANS_SESSION_MESSAGE);
553         default:
554             TRANS_LOGE(TRANS_SDK, "unknown flag=%{public}u.", flag);
555             return SOFTBUS_INVALID_PARAM;
556     }
557 }
558 
TransTdcProcessTlvData(int32_t channelId,TcpDataTlvPacketHead * pktHead,int32_t pkgHeadSize)559 static int32_t TransTdcProcessTlvData(int32_t channelId, TcpDataTlvPacketHead *pktHead, int32_t pkgHeadSize)
560 {
561     TcpDirectChannelInfo channel;
562     if (TransTdcGetInfoById(channelId, &channel) != SOFTBUS_OK) {
563         TRANS_LOGE(TRANS_SDK, "get channelInfo failed. channelId=%{public}d", channelId);
564         return SOFTBUS_TRANS_TDC_CHANNEL_NOT_FOUND;
565     }
566     if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
567         return SOFTBUS_LOCK_ERR;
568     }
569     uint32_t plainLen = 1;
570     DataBuf *node = TransGetDataBufNodeById(channelId);
571     if (node == NULL) {
572         TRANS_LOGE(TRANS_SDK, "node is null. channelId=%{public}d", channelId);
573         (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
574         return SOFTBUS_TRANS_NODE_NOT_FOUND;
575     }
576     uint32_t dataLen = pktHead->dataLen;
577     TRANS_LOGI(TRANS_SDK, "data received, channelId=%{public}d, dataLen=%{public}u, size=%{public}d, seq=%{public}d",
578         channelId, dataLen, node->size, pktHead->seq);
579     char *plain = (char *)SoftBusCalloc(dataLen - OVERHEAD_LEN);
580     if (plain == NULL) {
581         TRANS_LOGE(TRANS_SDK, "malloc fail, channelId=%{public}d, dataLen=%{public}u", channelId, dataLen);
582         (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
583         return SOFTBUS_MALLOC_ERR;
584     }
585     int32_t ret = TransTdcDecrypt(channel.detail.sessionKey, node->data + pkgHeadSize, dataLen, plain, &plainLen);
586     if (ret != SOFTBUS_OK) {
587         TRANS_LOGE(TRANS_SDK, "decrypt fail, channelId=%{public}d, dataLen=%{public}u", channel.channelId, dataLen);
588         SoftBusFree(plain);
589         (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
590         return SOFTBUS_DECRYPT_ERR;
591     }
592     ret = MoveNode(channel.channelId, node, dataLen, pkgHeadSize);
593     if (ret != SOFTBUS_OK) {
594         SoftBusFree(plain);
595         (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
596         return ret;
597     }
598     (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
599     ret = TransTdcProcessBytesDataByFlag(pktHead, &channel, plain, plainLen);
600     if (ret != SOFTBUS_OK) {
601         TRANS_LOGE(TRANS_SDK, "process data fail, channelId=%{public}d, dataLen=%{public}u",
602             channel.channelId, dataLen);
603     }
604     SoftBusFree(plain);
605     return ret;
606 }
607 
TransTdcProcessData(int32_t channelId)608 static int32_t TransTdcProcessData(int32_t channelId)
609 {
610     TcpDirectChannelInfo channel;
611     int32_t ret = TransTdcGetInfoById(channelId, &channel);
612     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, SOFTBUS_TRANS_TDC_CHANNEL_NOT_FOUND, TRANS_SDK,
613         "get key fail. channelId=%{public}d ", channelId);
614     ret = SoftBusMutexLock(&g_tcpDataList->lock);
615     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, SOFTBUS_LOCK_ERR, TRANS_SDK, "lock failed ");
616     uint32_t plainLen = 1;
617     DataBuf *node = TransGetDataBufNodeById(channelId);
618     if (node == NULL) {
619         TRANS_LOGE(TRANS_SDK, "node is null. channelId=%{public}d ", channelId);
620         (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
621         return SOFTBUS_TRANS_NODE_NOT_FOUND;
622     }
623     TcpDataPacketHead *pktHead = (TcpDataPacketHead *)(node->data);
624     int32_t seqNum = pktHead->seq;
625     uint32_t flag = pktHead->flags;
626     uint32_t dataLen = pktHead->dataLen;
627     TRANS_LOGI(TRANS_SDK, "data received, channelId=%{public}d, len=%{public}u, size=%{public}d, seq=%{public}d"
628         ", flags=%{public}d", channelId, dataLen, node->size, seqNum, flag);
629     char *plain = (char *)SoftBusCalloc(dataLen - OVERHEAD_LEN);
630     if (plain == NULL) {
631         TRANS_LOGE(TRANS_SDK, "malloc fail, channelId=%{public}d, dataLen=%{public}u", channelId, dataLen);
632         (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
633         return SOFTBUS_MALLOC_ERR;
634     }
635     ret = TransTdcUnPackData(channelId, channel.detail.sessionKey, plain, &plainLen, node);
636     if (ret != SOFTBUS_OK) {
637         TRANS_LOGE(TRANS_SDK, "unpack fail, channelId=%{public}d, dataLen=%{public}u", channelId, dataLen);
638         SoftBusFree(plain);
639         (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
640         return SOFTBUS_DECRYPT_ERR;
641     }
642     (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
643     ret = TransTdcProcessDataByFlag(flag, seqNum, &channel, plain, plainLen);
644     if (ret != SOFTBUS_OK) {
645         TRANS_LOGE(TRANS_SDK, "process data fail, channelId=%{public}d, dataLen=%{public}u", channelId, dataLen);
646     }
647     SoftBusFree(plain);
648     return ret;
649 }
650 
TransTdcProcAllTlvData(int32_t channelId)651 static int32_t TransTdcProcAllTlvData(int32_t channelId)
652 {
653     TRANS_CHECK_AND_RETURN_RET_LOGE(g_tcpDataList != NULL, SOFTBUS_NO_INIT, TRANS_CTRL, "g_tcpSrvDataList is NULL");
654     while (1) {
655         SoftBusMutexLock(&g_tcpDataList->lock);
656         TcpDataTlvPacketHead pktHead = { 0 };
657         uint32_t newPktHeadSize = 0;
658         DataBuf *node = TransGetDataBufNodeById(channelId);
659         if (node == NULL) {
660             (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
661             TRANS_LOGE(TRANS_SDK, "can not find data buf node. channelId=%{public}d", channelId);
662             return SOFTBUS_TRANS_NODE_NOT_FOUND;
663         }
664         bool flag = false;
665         int32_t ret = TransTdcUnPackAllTlvData(channelId, &pktHead, &newPktHeadSize, node, &flag);
666         if (ret != SOFTBUS_OK || flag == true) {
667             (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
668             return ret;
669         }
670         (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
671         ret = TransTdcProcessTlvData(channelId, &pktHead, newPktHeadSize);
672         TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "data received failed");
673     }
674 }
675 
TransTdcProcAllData(int32_t channelId)676 static int32_t TransTdcProcAllData(int32_t channelId)
677 {
678     TRANS_CHECK_AND_RETURN_RET_LOGE(g_tcpDataList != NULL, SOFTBUS_NO_INIT, TRANS_CTRL, "g_tcpSrvDataList is NULL");
679     while (1) {
680         SoftBusMutexLock(&g_tcpDataList->lock);
681         DataBuf *node = TransGetDataBufNodeById(channelId);
682         if (node == NULL) {
683             (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
684             TRANS_LOGE(TRANS_SDK, "can not find data buf node. channelId=%{public}d", channelId);
685             return SOFTBUS_TRANS_NODE_NOT_FOUND;
686         }
687         bool flag = false;
688         int32_t ret = TransTdcUnPackAllData(channelId, node, &flag);
689         if (ret != SOFTBUS_OK || flag == true) {
690             (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
691             return ret;
692         }
693         (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
694         ret = TransTdcProcessData(channelId);
695         TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "data received failed");
696     }
697 }
698 
TransClientGetTdcDataBufByChannel(int32_t channelId,int32_t * fd,size_t * len)699 static int32_t TransClientGetTdcDataBufByChannel(int32_t channelId, int32_t *fd, size_t *len)
700 {
701     if (fd == NULL || len == NULL) {
702         TRANS_LOGE(TRANS_SDK, "invalid param.");
703         return SOFTBUS_INVALID_PARAM;
704     }
705 
706     if (g_tcpDataList == NULL) {
707         TRANS_LOGE(TRANS_SDK, "tdc data list empty.");
708         return SOFTBUS_NO_INIT;
709     }
710 
711     if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
712         TRANS_LOGE(TRANS_SDK, "lock failed.");
713         return SOFTBUS_LOCK_ERR;
714     }
715     DataBuf *item = NULL;
716     LIST_FOR_EACH_ENTRY(item, &(g_tcpDataList->list), DataBuf, node) {
717         if (item->channelId == channelId) {
718             *fd = item->fd;
719             *len = item->size - (item->w - item->data);
720             (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
721             return SOFTBUS_OK;
722         }
723     }
724     (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
725     TRANS_LOGE(TRANS_SDK, "client get tdc data buf not found. channelId=%{public}d", channelId);
726     return SOFTBUS_TRANS_TDC_CHANNEL_NOT_FOUND;
727 }
728 
TransClientUpdateTdcDataBufWInfo(int32_t channelId,char * recvBuf,int32_t recvLen)729 static int32_t TransClientUpdateTdcDataBufWInfo(int32_t channelId, char *recvBuf, int32_t recvLen)
730 {
731     if (recvBuf == NULL) {
732         TRANS_LOGE(TRANS_SDK, "invalid param.");
733         return SOFTBUS_INVALID_PARAM;
734     }
735     if (g_tcpDataList == NULL) {
736         TRANS_LOGE(TRANS_SDK, "data list empty.");
737         return SOFTBUS_NO_INIT;
738     }
739     if (SoftBusMutexLock(&g_tcpDataList->lock) != SOFTBUS_OK) {
740         TRANS_LOGE(TRANS_SDK, "lock failed.");
741         return SOFTBUS_LOCK_ERR;
742     }
743 
744     DataBuf *item = NULL;
745     DataBuf *nextItem = NULL;
746     LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &(g_tcpDataList->list), DataBuf, node) {
747         if (item->channelId != channelId) {
748             continue;
749         }
750         int32_t freeLen = (int32_t)(item->size) - (item->w - item->data);
751         if (recvLen > freeLen) {
752             (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
753             TRANS_LOGE(TRANS_SDK,
754                 "client tdc recvLen override freeLen. recvLen=%{public}d, freeLen=%{public}d", recvLen, freeLen);
755             return SOFTBUS_TRANS_INVALID_DATA_LENGTH;
756         }
757         if (memcpy_s(item->w, recvLen, recvBuf, recvLen) != EOK) {
758             (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
759             TRANS_LOGE(TRANS_SDK, "client tdc memcpy failed. channelId=%{public}d", channelId);
760             return SOFTBUS_MEM_ERR;
761         }
762         item->w += recvLen;
763         (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
764         TRANS_LOGD(TRANS_SDK, "client update tdc data success, channelId=%{public}d", channelId);
765         return SOFTBUS_OK;
766     }
767     (void)SoftBusMutexUnlock(&g_tcpDataList->lock);
768     TRANS_LOGE(TRANS_SDK, "client update tdc data buf not found. channelId=%{public}d", channelId);
769     return SOFTBUS_TRANS_TDC_CHANNEL_NOT_FOUND;
770 }
771 
TransTdcRecvData(int32_t channelId)772 int32_t TransTdcRecvData(int32_t channelId)
773 {
774     int32_t recvLen = 1;
775     int32_t fd = -1;
776     size_t len = 0;
777     int32_t ret = TransClientGetTdcDataBufByChannel(channelId, &fd, &len);
778     if (ret != SOFTBUS_OK) {
779         TRANS_LOGE(TRANS_SDK, "get Tdc data buf by channelId=%{public}d failed, ret=%{public}d", channelId, ret);
780         return ret;
781     }
782     char *recvBuf = (char*)SoftBusCalloc(len);
783     if (recvBuf == NULL) {
784         TRANS_LOGE(TRANS_SDK, "client tdc malloc failed. channelId=%{public}d, len=%{public}zu", channelId, len);
785         return SOFTBUS_MALLOC_ERR;
786     }
787     ret = TransTdcRecvFirstData(channelId, recvBuf, &recvLen, fd, len);
788     if (ret != SOFTBUS_OK) {
789         SoftBusFree(recvBuf);
790         return ret;
791     }
792     ret = TransClientUpdateTdcDataBufWInfo(channelId, recvBuf, recvLen);
793     if (ret != SOFTBUS_OK) {
794         SoftBusFree(recvBuf);
795         TRANS_LOGE(TRANS_SDK, "client update data buf failed. channelId=%{public}d, ret=%{public}d", channelId, ret);
796         return ret;
797     }
798     SoftBusFree(recvBuf);
799     bool supportTlv = false;
800     ret = GetSupportTlvAndNeedAckById(channelId, CHANNEL_TYPE_TCP_DIRECT, &supportTlv, NULL);
801     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "fail to get support tlv");
802     if (supportTlv) {
803         return TransTdcProcAllTlvData(channelId);
804     }
805     return TransTdcProcAllData(channelId);
806 }
807 
TransDataListInit(void)808 int32_t TransDataListInit(void)
809 {
810     if (g_tcpDataList != NULL) {
811         TRANS_LOGI(TRANS_SDK, "g_tcpDataList already init");
812         return SOFTBUS_OK;
813     }
814     int32_t ret = TransGetTdcDataBufMaxSize();
815     TRANS_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, TRANS_SDK, "TransGetTdcDataBufMaxSize failed");
816 
817     g_tcpDataList = CreateSoftBusList();
818     if (g_tcpDataList == NULL) {
819         TRANS_LOGE(TRANS_SDK, "g_tcpDataList creat list failed");
820         return SOFTBUS_NO_INIT;
821     }
822     return SOFTBUS_OK;
823 }
824 
TransDataListDeinit(void)825 void TransDataListDeinit(void)
826 {
827     if (g_tcpDataList == NULL) {
828         return;
829     }
830     (void)TransDestroyDataBuf();
831     DestroySoftBusList(g_tcpDataList);
832     g_tcpDataList = NULL;
833 }
834