1 /*
2  * Copyright (c) 2021 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 "softbus_conn_br_trans.h"
17 
18 #include "securec.h"
19 
20 #include "conn_event.h"
21 #include "conn_log.h"
22 #include "softbus_adapter_mem.h"
23 #include "softbus_conn_br_pending_packet.h"
24 #include "softbus_conn_br_send_queue.h"
25 #include "softbus_conn_common.h"
26 #include "softbus_conn_flow_control.h"
27 #include "softbus_conn_manager.h"
28 #include "softbus_datahead_transform.h"
29 #include "softbus_def.h"
30 #include "softbus_errcode.h"
31 #include "softbus_json_utils.h"
32 
33 static SppSocketDriver *g_sppDriver = NULL;
34 static ConnBrTransEventListener g_transEventListener = { 0 };
35 static struct ConnSlideWindowController *g_flowController = NULL;
36 static void *SendHandlerLoop(void *arg);
37 static StartBrSendLPInfo g_startBrSendLPInfo = { 0 };
38 
BrRecvDataParse(uint32_t connectionId,LimitedBuffer * buffer,int32_t * outLen)39 static uint8_t *BrRecvDataParse(uint32_t connectionId, LimitedBuffer *buffer, int32_t *outLen)
40 {
41     uint32_t pktHeadLen = sizeof(ConnPktHead);
42     if (buffer->length < pktHeadLen) {
43         // not enough for ConnPktHead
44         return NULL;
45     }
46     ConnPktHead *head = (ConnPktHead *)(buffer->buffer);
47     UnpackConnPktHead(head);
48     if ((uint32_t)(head->magic) != MAGIC_NUMBER) {
49         buffer->length = 0;
50         CONN_LOGE(CONN_BR, "recv unknown data: conn id=%{public}u, magic 0x%{public}x", connectionId, head->magic);
51         return NULL;
52     }
53     if (buffer->capacity - pktHeadLen < head->len) {
54         buffer->length = 0;
55         CONN_LOGE(CONN_BR, "recv data too big: connId=%{public}u, module=%{public}d, seq=%{public}" PRId64 ", "
56             "datalen=%{public}d", connectionId, head->module, head->seq, head->len);
57         return NULL;
58     }
59     uint32_t packLen = head->len + sizeof(ConnPktHead);
60     if (buffer->length < packLen) {
61         CONN_LOGD(CONN_BR, "recv incomplete packet, connId=%{public}u", connectionId);
62         return NULL;
63     }
64     uint8_t *dataCopy = (uint8_t *)SoftBusCalloc(packLen);
65     if (dataCopy == NULL) {
66         CONN_LOGE(CONN_BR, "parse data failed: calloc failed, retry next time, connId=%{public}u, packLen=%{public}u",
67             connectionId, packLen);
68         return NULL;
69     }
70     if (memcpy_s(dataCopy, packLen, buffer->buffer, packLen) != EOK) {
71         CONN_LOGE(CONN_BR, "parse data failed: memcpy_s failed, retry next time, connId=%{public}u, "
72             "packLen=%{public}u, bufferLen=%{public}u", connectionId, packLen, buffer->length);
73         SoftBusFree(dataCopy);
74         return NULL;
75     }
76     if (buffer->length > packLen &&
77         memmove_s(buffer->buffer, buffer->length, buffer->buffer + packLen, buffer->length - packLen) != EOK) {
78         CONN_LOGE(CONN_BR, "parse data failed: memmove_s failed, retry next time. connId=%{public}u, ", connectionId);
79         SoftBusFree(dataCopy);
80         return NULL;
81     }
82     CONN_LOGI(CONN_BR, "br receive data, connId=%{public}u, cachedLength=%{public}u, "
83         "Len=%{public}u, Flg=%{public}d, Module=%{public}d, Seq=%{public}" PRId64 "",
84         connectionId, buffer->length, packLen, head->flag, head->module, head->seq);
85     buffer->length -= packLen;
86     *outLen = (int32_t)packLen;
87     return dataCopy;
88 }
89 
ConnBrTransReadOneFrame(uint32_t connectionId,int32_t socketHandle,LimitedBuffer * buffer,uint8_t ** outData)90 int32_t ConnBrTransReadOneFrame(uint32_t connectionId, int32_t socketHandle, LimitedBuffer *buffer, uint8_t **outData)
91 {
92     while (true) {
93         int32_t dataLen = 0;
94         uint8_t *data = BrRecvDataParse(connectionId, buffer, &dataLen);
95         if (data != NULL) {
96             *outData = data;
97             return dataLen;
98         }
99         int32_t recvLen = g_sppDriver->Read(
100             socketHandle, buffer->buffer + buffer->length, (int32_t)(buffer->capacity - buffer->length));
101         if (recvLen == BR_READ_SOCKET_CLOSED) {
102             CONN_LOGW(CONN_BR,
103                 "br connection read return, connection closed. connId=%{public}u, socketHandle=%{public}d",
104                 connectionId, socketHandle);
105             ConnAuditExtra extra = {
106                 .auditType = AUDIT_EVENT_MSG_ERROR,
107                 .connectionId = connectionId,
108                 .errcode = SOFTBUS_CONN_BR_UNDERLAY_SOCKET_CLOSED,
109             };
110             CONN_AUDIT(STATS_SCENE_CONN_BT_RECV_FAILED, extra);
111             return SOFTBUS_CONN_BR_UNDERLAY_SOCKET_CLOSED;
112         }
113         if (recvLen < 0) {
114             CONN_LOGE(CONN_BR,
115                 "br connection read return, connectionId=%{public}u, socketHandle=%{public}d, error=%{public}d",
116                 connectionId, socketHandle, recvLen);
117             ConnAuditExtra extra = {
118                 .auditType = AUDIT_EVENT_MSG_ERROR,
119                 .connectionId = connectionId,
120                 .errcode = SOFTBUS_CONN_BR_UNDERLAY_READ_FAIL,
121             };
122             CONN_AUDIT(STATS_SCENE_CONN_BT_RECV_FAILED, extra);
123             return SOFTBUS_CONN_BR_UNDERLAY_READ_FAIL;
124         }
125         buffer->length += (uint32_t)recvLen;
126     }
127 }
128 
BrTransSend(uint32_t connectionId,int32_t socketHandle,uint32_t mtu,const uint8_t * data,uint32_t dataLen)129 int32_t BrTransSend(uint32_t connectionId, int32_t socketHandle, uint32_t mtu, const uint8_t *data, uint32_t dataLen)
130 {
131     uint32_t waitWriteLen = dataLen;
132     while (waitWriteLen > 0) {
133         uint32_t expect = waitWriteLen > mtu ? mtu : waitWriteLen;
134         int32_t amount = g_flowController->apply(g_flowController, (int32_t)expect);
135         int32_t writeLen = g_sppDriver->Write(socketHandle, data, amount);
136         if (writeLen < 0) {
137             CONN_LOGE(CONN_BR,
138                 "br send data failed: underlayer bluetooth write failed, connId=%{public}u, "
139                 "socketHandle=%{public}d, mtu=%{public}d, totalLen=%{public}d, waitWriteLen=%{public}d, "
140                 "alreadyWriteLen=%{public}d, error=%{public}d",
141                 connectionId, socketHandle, mtu, dataLen, waitWriteLen, dataLen - waitWriteLen, writeLen);
142             return SOFTBUS_CONN_BR_UNDERLAY_WRITE_FAIL;
143         }
144         data += writeLen;
145         waitWriteLen -= (uint32_t)writeLen;
146     }
147     return SOFTBUS_OK;
148 }
149 
SerializeByJson(BrCtlMessageSerializationContext ctx,char ** outData,uint32_t * outDataLen)150 static int32_t SerializeByJson(BrCtlMessageSerializationContext ctx, char **outData, uint32_t *outDataLen)
151 {
152     cJSON *json = cJSON_CreateObject();
153     if (json == NULL) {
154         return SOFTBUS_CREATE_JSON_ERR;
155     }
156     if (ctx.method == BR_METHOD_NOTIFY_REQUEST) {
157         if (!AddNumberToJsonObject(json, KEY_METHOD, BR_METHOD_NOTIFY_REQUEST) ||
158             !AddNumberToJsonObject(json, KEY_DELTA, ctx.referenceRequest.delta) ||
159             !AddNumberToJsonObject(json, KEY_REFERENCE_NUM, ctx.referenceRequest.referenceNumber)) {
160             cJSON_Delete(json);
161             return SOFTBUS_CREATE_JSON_ERR;
162         }
163     } else if (ctx.method == BR_METHOD_NOTIFY_RESPONSE) {
164         if (!AddNumberToJsonObject(json, KEY_METHOD, BR_METHOD_NOTIFY_RESPONSE) ||
165             !AddNumberToJsonObject(json, KEY_REFERENCE_NUM, ctx.referenceResponse.referenceNumber)) {
166             cJSON_Delete(json);
167             return SOFTBUS_CREATE_JSON_ERR;
168         }
169     } else if (ctx.method == BR_METHOD_NOTIFY_ACK) {
170         if (!AddNumberToJsonObject(json, KEY_METHOD, BR_METHOD_NOTIFY_ACK) ||
171             !AddNumberToJsonObject(json, KEY_WINDOWS, ctx.ackRequestResponse.window) ||
172             !AddNumber64ToJsonObject(json, KEY_ACK_SEQ_NUM, ctx.ackRequestResponse.seq)) {
173             cJSON_Delete(json);
174             return SOFTBUS_CREATE_JSON_ERR;
175         }
176     } else if (ctx.method == BR_METHOD_ACK_RESPONSE) {
177         if (!AddNumberToJsonObject(json, KEY_METHOD, BR_METHOD_ACK_RESPONSE) ||
178             !AddNumberToJsonObject(json, KEY_WINDOWS, ctx.ackRequestResponse.window) ||
179             !AddNumber64ToJsonObject(json, KEY_ACK_SEQ_NUM, ctx.ackRequestResponse.seq)) {
180             cJSON_Delete(json);
181             return SOFTBUS_CREATE_JSON_ERR;
182         }
183     } else {
184         cJSON_Delete(json);
185         return SOFTBUS_CONN_BR_INTERNAL_ERR;
186     }
187     char *data = cJSON_PrintUnformatted(json);
188     cJSON_Delete(json);
189     if (data == NULL) {
190         return SOFTBUS_CREATE_JSON_ERR;
191     }
192     *outData = data;
193     *outDataLen = strlen(data) + 1;
194     return SOFTBUS_OK;
195 }
196 
ConnBrPackCtlMessage(BrCtlMessageSerializationContext ctx,uint8_t ** outData,uint32_t * outDataLen)197 int64_t ConnBrPackCtlMessage(BrCtlMessageSerializationContext ctx, uint8_t **outData, uint32_t *outDataLen)
198 {
199     static int64_t ctlMsgSeqGenerator = 0;
200     int64_t seq = ctlMsgSeqGenerator++;
201 
202     char *data = NULL;
203     uint32_t dataLen = 0;
204     int32_t ret = SerializeByJson(ctx, &data, &dataLen);
205     if (ret != SOFTBUS_OK) {
206         CONN_LOGE(CONN_BR,
207             "br pack ctl message failed: serialize json bytes failed, connId=%{public}u, method=%{public}d",
208             ctx.connectionId, ctx.method);
209         return ret;
210     }
211 
212     uint32_t headSize = sizeof(ConnPktHead);
213     uint32_t bufLen = dataLen + headSize;
214     uint8_t *buf = (uint8_t *)SoftBusCalloc(bufLen);
215     if (buf == NULL) {
216         cJSON_free(data);
217         return SOFTBUS_MALLOC_ERR;
218     }
219     ConnPktHead head = { 0 };
220     head.magic = MAGIC_NUMBER;
221     head.module = MODULE_CONNECTION;
222     head.seq = seq;
223     head.flag = ctx.flag;
224     head.len = dataLen;
225     PackConnPktHead(&head);
226     if (memcpy_s(buf, bufLen, &head, headSize) != EOK) {
227         CONN_LOGE(CONN_BR,
228             "br pack ctl message failed: memcpy connection header failed, connId=%{public}u, method=%{public}d",
229             ctx.connectionId, ctx.method);
230         cJSON_free(data);
231         SoftBusFree(buf);
232         return SOFTBUS_MEM_ERR;
233     }
234     if (memcpy_s(buf + headSize, bufLen - headSize, data, dataLen) != EOK) {
235         CONN_LOGE(CONN_BR,
236             "br pack ctl message failed: memcpy ctl message bytes failed, connId=%{public}u, method=%{public}d",
237             ctx.connectionId, ctx.method);
238         cJSON_free(data);
239         SoftBusFree(buf);
240         return SOFTBUS_MEM_ERR;
241     }
242     cJSON_free(data);
243     *outData = buf;
244     *outDataLen = bufLen;
245     return seq;
246 }
247 
FreeSendNode(SendBrQueueNode * node)248 static void FreeSendNode(SendBrQueueNode *node)
249 {
250     if (node->data != NULL) {
251         SoftBusFree(node->data);
252     }
253     SoftBusFree(node);
254 }
255 
ConnBrPostBytes(uint32_t connectionId,uint8_t * data,uint32_t len,int32_t pid,int32_t flag,int32_t module,int64_t seq)256 int32_t ConnBrPostBytes(
257     uint32_t connectionId, uint8_t *data, uint32_t len, int32_t pid, int32_t flag, int32_t module, int64_t seq)
258 {
259     CONN_CHECK_AND_RETURN_RET_LOGW(data != NULL, SOFTBUS_INVALID_PARAM, CONN_BR,
260         "br post bytes failed: invalid param, data is null, connectionId=%{public}u, pid=%{public}d, "
261         "Len=%{public}u, Flg=%{public}d, Module=%{public}d, Seq=%{public}" PRId64 "",
262         connectionId, pid, len, flag, module, seq);
263 
264     if (len == 0 || len > MAX_DATA_LEN) {
265         CONN_LOGW(CONN_BR,
266             "br post bytes failed, invalid param, data len is 0, connectionId=%{public}u, pid=%{public}d, "
267             "Len=%{public}u, Flg=%{public}d, Module=%{public}d, Seq=%{public}" PRId64 "",
268             connectionId, pid, len, flag, module, seq);
269         SoftBusFree(data);
270         return SOFTBUS_INVALID_PARAM;
271     }
272 
273     ConnBrConnection *connection = ConnBrGetConnectionById(connectionId);
274     if (connection == NULL) {
275         CONN_LOGE(CONN_BR,
276             "br post bytes failed: connection is not exist, connectionId=%{public}u, pid=%{public}d, "
277             "Len=%{public}u, Flg=%{public}d, Module=%{public}d, Seq=%{public}" PRId64 "",
278             connectionId, pid, len, flag, module, seq);
279         SoftBusFree(data);
280         return SOFTBUS_CONN_BR_CONNECTION_NOT_EXIST_ERR;
281     }
282     int32_t status = SoftBusMutexLock(&connection->lock);
283     if (status != SOFTBUS_OK) {
284         CONN_LOGE(CONN_BR,
285             "br post bytes failed: try to lock failed, connectionId=%{public}u, pid=%{public}d, "
286             "Len=%{public}u, Flg=%{public}d, Module=%{public}d, Seq=%{public}" PRId64 ", error=%{public}d",
287             connectionId, pid, len, flag, module, seq, status);
288         ConnBrReturnConnection(&connection);
289         SoftBusFree(data);
290         return SOFTBUS_LOCK_ERR;
291     }
292     enum ConnBrConnectionState state = connection->state;
293     (void)SoftBusMutexUnlock(&connection->lock);
294     ConnBrReturnConnection(&connection);
295     if (state != BR_CONNECTION_STATE_CONNECTED && module != MODULE_CONNECTION) {
296         CONN_LOGE(CONN_BR,
297             "br post bytes failed: connection is not ready, state=%{public}d, connId=%{public}u, pid=%{public}d, "
298             "Len=%{public}u, Flg=%{public}d, Module=%{public}d, Seq=%{public}" PRId64 "",
299             state, connectionId, pid, len, flag, module, seq);
300         SoftBusFree(data);
301         return SOFTBUS_CONN_BR_CONNECTION_NOT_READY_ERR;
302     }
303 
304     SendBrQueueNode *node = (SendBrQueueNode *)SoftBusCalloc(sizeof(SendBrQueueNode));
305     if (node == NULL) {
306         CONN_LOGE(CONN_BR,
307             "br post bytes failed: calloc queue node failed, connectionId=%{public}u, pid=%{public}d, "
308             "Len=%{public}u, Flg=%{public}d, Module=%{public}d, Seq=%{public}" PRId64 "",
309             connectionId, pid, len, flag, module, seq);
310         SoftBusFree(data);
311         return SOFTBUS_MEM_ERR;
312     }
313     node->connectionId = connectionId;
314     node->data = data;
315     node->len = len;
316     node->pid = pid;
317     node->flag = flag;
318     node->module = module;
319     node->seq = seq;
320     node->isInner = (pid == 0);
321     status = ConnBrEnqueueNonBlock((const void *)node);
322     if (status != SOFTBUS_OK) {
323         CONN_LOGE(CONN_BR,
324             "br post bytes failed: enqueue failed, error=%{public}d, connId=%{public}u, pid=%{public}d, "
325             "Len=%{public}u, Flg=%{public}d, Module=%{public}d, Seq=%{public}" PRId64 "",
326             status, connectionId, pid, len, flag, module, seq);
327         FreeSendNode(node);
328         return status;
329     }
330     CONN_LOGI(CONN_BR,
331         "br post bytes: receive post byte request, connId=%{public}u, pid=%{public}d, "
332         "Len=%{public}u, Flg=%{public}d, Module=%{public}d, Seq=%{public}" PRId64 "",
333         connectionId, pid, len, flag, module, seq);
334     CONN_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_startBrSendLPInfo.lock) == SOFTBUS_OK,
335         SOFTBUS_LOCK_ERR, CONN_BR, "lock fail!");
336     g_startBrSendLPInfo.messagePosted = true;
337     if (!g_startBrSendLPInfo.sendTaskRunning) {
338         status = ConnStartActionAsync(NULL, SendHandlerLoop, "BrSend_Tsk");
339         if (status != SOFTBUS_OK) {
340             CONN_LOGE(CONN_BR, "start br send task failed errno=%{public}d", status);
341             SoftBusMutexUnlock(&g_startBrSendLPInfo.lock);
342             return status;
343         }
344         g_startBrSendLPInfo.sendTaskRunning = true;
345         SoftBusMutexUnlock(&g_startBrSendLPInfo.lock);
346         CONN_LOGD(CONN_BR, "start br send task succ");
347         return SOFTBUS_OK;
348     }
349     SoftBusMutexUnlock(&g_startBrSendLPInfo.lock);
350     return SOFTBUS_OK;
351 }
352 
353 // call this method MUST wrapper connection lock
SendAckUnsafe(const ConnBrConnection * connection)354 static int32_t SendAckUnsafe(const ConnBrConnection *connection)
355 {
356     int32_t flag = CONN_HIGH;
357     BrCtlMessageSerializationContext ctx = {
358         .connectionId = connection->connectionId,
359         .flag = flag,
360         .method = BR_METHOD_NOTIFY_ACK,
361         .ackRequestResponse = {
362             .window = connection->window,
363             .seq = connection->sequence,
364         },
365     };
366     uint8_t *data = NULL;
367     uint32_t dataLen = 0;
368     int64_t ctrlMsgSeq = ConnBrPackCtlMessage(ctx, &data, &dataLen);
369     if (ctrlMsgSeq < 0) {
370         CONN_LOGW(CONN_BR,
371             "br send ack failed: pack message failed, connId=%{public}u, window=%{public}d, seq=%{public}" PRId64
372             ", error=%{public}d",
373             connection->connectionId, connection->window, connection->sequence, (int32_t)ctrlMsgSeq);
374         return (int32_t)ctrlMsgSeq;
375     }
376     int32_t status = ConnBrCreateBrPendingPacket(connection->connectionId, connection->sequence);
377     if (status != SOFTBUS_OK) {
378         CONN_LOGW(CONN_BR,
379             "br send ack failed: create pending failed, connId=%{public}u, window=%{public}d, seq=%{public}" PRId64
380             ", error=%{public}d", connection->connectionId, connection->window, connection->sequence, status);
381         SoftBusFree(data);
382         return status;
383     }
384     status = BrTransSend(connection->connectionId, connection->socketHandle, connection->mtu, data, dataLen);
385     if (status != SOFTBUS_OK) {
386         ConnBrDelBrPendingPacket(connection->connectionId, connection->sequence);
387     }
388     CONN_LOGI(CONN_BR,
389         "br send ack, connectionId=%{public}u, Len=%{public}u, Flg=%{public}d, Module=%{public}d, Seq=%{public}" PRId64
390         ", error=%{public}d", connection->connectionId, dataLen, flag, MODULE_CONNECTION, ctrlMsgSeq, status);
391     SoftBusFree(data);
392     return status;
393 }
394 
WaitAck(ConnBrConnection * connection)395 static void WaitAck(ConnBrConnection *connection)
396 {
397     CONN_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&connection->lock) == SOFTBUS_OK, CONN_BR,
398         "wait ack failed: try to lock failed, connectionId=%{public}u", connection->connectionId);
399     int64_t waitSequence = connection->waitSequence;
400     SoftBusMutexUnlock(&connection->lock);
401 
402     void *ignore = NULL;
403     int32_t ret = ConnBrGetBrPendingPacket(connection->connectionId, waitSequence, WAIT_ACK_TIMEOUT_MILLS, &ignore);
404     SoftBusFree(ignore);
405 
406     CONN_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&connection->lock) == SOFTBUS_OK, CONN_BR,
407         "wait ack failed: try to lock failed after pending, connectionId=%{public}u", connection->connectionId);
408     switch (ret) {
409         case SOFTBUS_ALREADY_TRIGGERED:
410             connection->ackTimeoutCount = 0;
411             connection->window = connection->window < MAX_WINDOW ? connection->window + 1 : MAX_WINDOW;
412             break;
413         case SOFTBUS_OK:
414             connection->ackTimeoutCount = 0;
415             break;
416         case SOFTBUS_TIMOUT:
417             connection->ackTimeoutCount += 1;
418             if (connection->window > MIN_WINDOW && connection->ackTimeoutCount % TIMEOUT_TIMES == 0) {
419                 connection->window = connection->window - 1;
420             }
421             if (connection->window < DEFAULT_WINDOW && connection->ackTimeoutCount > ACK_FAILED_TIMES) {
422                 connection->window = DEFAULT_WINDOW;
423             }
424             break;
425         default:
426             connection->ackTimeoutCount = 0;
427             break;
428     }
429     connection->waitSequence = 0;
430     SoftBusMutexUnlock(&connection->lock);
431 }
432 
SendHandlerLoop(void * arg)433 void *SendHandlerLoop(void *arg)
434 {
435     (void)arg;
436     CONN_LOGI(CONN_BR, "br send data: send loop start");
437     SendBrQueueNode *sendNode = NULL;
438     while (true) {
439         int32_t status = ConnBrDequeueBlock((void **)(&sendNode));
440         if (status == SOFTBUS_TIMOUT && sendNode == NULL) {
441             CONN_LOGD(CONN_BR, "br dequeue time out err=%{public}d", status);
442             CONN_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_startBrSendLPInfo.lock) == SOFTBUS_OK,
443                 NULL, CONN_BR, "lock fail!");
444             if (g_startBrSendLPInfo.messagePosted) {
445                 CONN_LOGE(CONN_BR, "message posted not quit");
446                 g_startBrSendLPInfo.messagePosted = false;
447                 SoftBusMutexUnlock(&g_startBrSendLPInfo.lock);
448                 continue;
449             }
450             g_startBrSendLPInfo.sendTaskRunning = false;
451             SoftBusMutexUnlock(&g_startBrSendLPInfo.lock);
452             CONN_LOGE(CONN_BR, "quit send loop");
453             break;
454         }
455         int32_t ret = SoftBusMutexLock(&g_startBrSendLPInfo.lock);
456         if (ret != SOFTBUS_OK) {
457             CONN_LOGE(CONN_BR, "lock fail!");
458             FreeSendNode(sendNode);
459             sendNode = NULL;
460             return NULL;
461         }
462         g_startBrSendLPInfo.messagePosted = false;
463         SoftBusMutexUnlock(&g_startBrSendLPInfo.lock);
464         if (status != SOFTBUS_OK || sendNode == NULL) {
465             CONN_LOGE(CONN_BR, "br dequeue send node failed, error=%{public}d", status);
466             continue;
467         }
468         ConnBrConnection *connection = ConnBrGetConnectionById(sendNode->connectionId);
469         if (connection == NULL) {
470             CONN_LOGE(CONN_BR, "br send data failed: connection is not exist, connectionId=%{public}u",
471                 sendNode->connectionId);
472             g_transEventListener.onPostByteFinshed(sendNode->connectionId, sendNode->len, sendNode->pid, sendNode->flag,
473                 sendNode->module, sendNode->seq, SOFTBUS_CONN_BR_CONNECTION_NOT_EXIST_ERR);
474             FreeSendNode(sendNode);
475             sendNode = NULL;
476             continue;
477         }
478 
479         if (SoftBusMutexLock(&connection->lock) != SOFTBUS_OK) {
480             CONN_LOGE(
481                 CONN_BR, "br send data failed: try to lock failed, connectionId=%{public}u", sendNode->connectionId);
482             g_transEventListener.onPostByteFinshed(sendNode->connectionId, sendNode->len, sendNode->pid, sendNode->flag,
483                 sendNode->module, sendNode->seq, SOFTBUS_LOCK_ERR);
484             ConnBrReturnConnection(&connection);
485             FreeSendNode(sendNode);
486             sendNode = NULL;
487             continue;
488         }
489 
490         int32_t socketHandle = connection->socketHandle;
491         if (socketHandle == INVALID_SOCKET_HANDLE) {
492             CONN_LOGE(CONN_BR, "br send data failed: invalid socket, connectionId=%{public}u", sendNode->connectionId);
493             (void)SoftBusMutexUnlock(&connection->lock);
494             ConnBrReturnConnection(&connection);
495             g_transEventListener.onPostByteFinshed(sendNode->connectionId, sendNode->len, sendNode->pid, sendNode->flag,
496                 sendNode->module, sendNode->seq, SOFTBUS_CONN_BR_CONNECTION_INVALID_SOCKET);
497             FreeSendNode(sendNode);
498             sendNode = NULL;
499             continue;
500         }
501 
502         connection->sequence += 1;
503         if (connection->sequence % connection->window == 0) {
504             if (SendAckUnsafe(connection) == SOFTBUS_OK) {
505                 connection->waitSequence = connection->sequence;
506             }
507         }
508         int32_t window = connection->window;
509         int64_t sequence = connection->sequence;
510         int64_t waitSequence = connection->waitSequence;
511         (void)SoftBusMutexUnlock(&connection->lock);
512 
513         if (window > 1 && sequence % window == window - 1 && waitSequence != 0) {
514             WaitAck(connection);
515         }
516         status = BrTransSend(connection->connectionId, socketHandle, connection->mtu, sendNode->data, sendNode->len);
517         ConnBrReturnConnection(&connection);
518         CONN_LOGD(CONN_BR, "br send data, connId=%{public}u, status=%{public}d, socketHandle=%{public}d",
519             sendNode->connectionId, status, socketHandle);
520         g_transEventListener.onPostByteFinshed(sendNode->connectionId, sendNode->len, sendNode->pid, sendNode->flag,
521             sendNode->module, sendNode->seq, status);
522         FreeSendNode(sendNode);
523         sendNode = NULL;
524     }
525     return NULL;
526 }
527 
ConnBrTransConfigPostLimit(const LimitConfiguration * configuration)528 int32_t ConnBrTransConfigPostLimit(const LimitConfiguration *configuration)
529 {
530     CONN_CHECK_AND_RETURN_RET_LOGW(
531         configuration != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT, "invalid param, configuration is null");
532     CONN_CHECK_AND_RETURN_RET_LOGW(configuration->type == CONNECT_BR, SOFTBUS_INVALID_PARAM, CONN_INIT,
533         "invalid param, not br type, type=%{public}d", configuration->type);
534     int32_t ret = SOFTBUS_OK;
535     if (!configuration->active) {
536         ret = g_flowController->disable(g_flowController);
537     } else {
538         ret = g_flowController->enable(g_flowController, configuration->windowInMillis, configuration->quotaInBytes);
539     }
540     CONN_LOGI(CONN_BR, "config br postlimit, active=%{public}d, windows=%{public}d millis, quota=%{public}d bytes, "
541         "result=%{public}d", configuration->active, configuration->windowInMillis, configuration->quotaInBytes, ret);
542     return ret;
543 }
544 
ConnBrTransMuduleInit(SppSocketDriver * sppDriver,ConnBrTransEventListener * listener)545 int32_t ConnBrTransMuduleInit(SppSocketDriver *sppDriver, ConnBrTransEventListener *listener)
546 {
547     CONN_CHECK_AND_RETURN_RET_LOGW(sppDriver != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT,
548         "init br trans module failed: invalid param, sppDriver is null");
549     CONN_CHECK_AND_RETURN_RET_LOGW(sppDriver->Read != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT,
550         "init br trans module failed: invalid param, sppDriver->Read is null");
551     CONN_CHECK_AND_RETURN_RET_LOGW(sppDriver->Write != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT,
552         "init br trans module failed: invalid param, sppDriver->Write is null");
553     CONN_CHECK_AND_RETURN_RET_LOGW(listener != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT,
554         "init br trans module failed: invalid param, listener is null");
555     CONN_CHECK_AND_RETURN_RET_LOGW(listener->onPostByteFinshed != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT,
556         "init br trans module failed: invalid param, listener->onPostByteFinshed is null");
557 
558     int32_t status = ConnBrInnerQueueInit();
559     CONN_CHECK_AND_RETURN_RET_LOGW(status == SOFTBUS_OK, status, CONN_INIT,
560         "init br trans module failed: init br send queue failed, error=%{public}d", status);
561 
562     struct ConnSlideWindowController *controller = ConnSlideWindowControllerNew();
563     if (controller == NULL) {
564         CONN_LOGW(CONN_INIT, "init br trans module failed: init flow controller failed");
565         ConnBrInnerQueueDeinit();
566         return SOFTBUS_CONN_BR_INTERNAL_ERR;
567     }
568 
569     g_sppDriver = sppDriver;
570     g_transEventListener = *listener;
571     g_flowController = controller;
572     status = SoftBusMutexInit(&g_startBrSendLPInfo.lock, NULL);
573     if (status != SOFTBUS_OK) {
574         CONN_LOGW(CONN_INIT, "init br trans module failed: init send lp lock failed, err=%{public}d", status);
575         ConnBrInnerQueueDeinit();
576         ConnSlideWindowControllerDelete(controller);
577         return status;
578     }
579     return SOFTBUS_OK;
580 }
581