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