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