1 /*
2 * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "softbus_conn_br_connection.h"
17
18 #include "securec.h"
19
20 #include "bus_center_decision_center.h"
21 #include "conn_log.h"
22 #include "softbus_adapter_mem.h"
23 #include "softbus_conn_br_trans.h"
24 #include "softbus_conn_common.h"
25 #include "softbus_feature_config.h"
26 #include "softbus_utils.h"
27 #include "c_header/ohos_bt_def.h"
28 #include "c_header/ohos_bt_socket.h"
29 #include "conn_event.h"
30
31 #define UUID "8ce255c0-200a-11e0-ac64-0800200c9a66"
32
33 typedef struct {
34 int32_t delta;
35 int32_t peerRc;
36 } ReferenceCount;
37
38 typedef struct {
39 int32_t socketHandle;
40 } ServerServeContext;
41
42 typedef struct {
43 uint32_t connectionId;
44 } ClientConnectContext;
45
46 typedef struct {
47 uint32_t traceId;
48 // protect variable access below
49 SoftBusMutex mutex;
50 bool available;
51 int32_t serverId;
52 } ServerState;
53
54 enum BrConnectionLooperMsgType {
55 MSG_CONNECTION_WAIT_NEGOTIATION_CLOSING_TIMEOUT = 100,
56 MSG_CONNECTION_RETRY_NOTIFY_REFERENCE,
57 MSG_CONNECTION_REPORT_CONNECT_EXCEPTION,
58 MSG_CONNECTION_OCCUPY_RELEASE,
59 MSG_CONNECTION_UPDATE_LOCAL_RC,
60 MSG_CONNECTION_UPDATE_PEER_RC,
61 };
62
63 static void BrConnectionMsgHandler(SoftBusMessage *msg);
64 static int BrCompareConnectionLooperEventFunc(const SoftBusMessage *msg, void *args);
65
66 static ConnBrEventListener g_eventListener = { 0 };
67 static SppSocketDriver *g_sppDriver = NULL;
68 static ServerState *g_serverState = NULL;
69 static SoftBusHandlerWrapper g_brConnectionAsyncHandler = {
70 .handler = {
71 .name = (char *)"BrConnectionAsyncHandler",
72 .HandleMessage = BrConnectionMsgHandler,
73 // assign when initiation
74 .looper = NULL,
75 },
76 .eventCompareFunc = BrCompareConnectionLooperEventFunc,
77 };
78
79 static int32_t g_readBufferCapacity = -1;
80 static int32_t g_mtuSize = -1;
LoopRead(uint32_t connectionId,int32_t socketHandle)81 static int32_t LoopRead(uint32_t connectionId, int32_t socketHandle)
82 {
83 LimitedBuffer *buffer = NULL;
84 int32_t status = ConnNewLimitedBuffer(&buffer, g_readBufferCapacity);
85 if (status != SOFTBUS_OK) {
86 return status;
87 }
88
89 while (true) {
90 uint8_t *data = NULL;
91 int32_t dataLen = ConnBrTransReadOneFrame(connectionId, socketHandle, buffer, &data);
92 if (dataLen < 0) {
93 status = dataLen;
94 break;
95 }
96 g_eventListener.onDataReceived(connectionId, data, dataLen);
97 }
98 ConnDeleteLimitedBuffer(&buffer);
99 return status;
100 }
101
BrConnectStatusCallback(const BdAddr * bdAddr,BtUuid uuid,int32_t status,int32_t result)102 static void BrConnectStatusCallback(const BdAddr *bdAddr, BtUuid uuid, int32_t status, int32_t result)
103 {
104 char copyMac[BT_MAC_LEN] = { 0 };
105 int32_t ret = ConvertBtMacToStr(copyMac, BT_MAC_LEN, bdAddr->addr, sizeof(bdAddr->addr));
106 CONN_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, CONN_BR,
107 "convert mac failed, result=%{public}d, status=%{public}d", result, status);
108
109 char anomizeAddress[BT_MAC_LEN] = { 0 };
110 ConvertAnonymizeMacAddress(anomizeAddress, BT_MAC_LEN, copyMac, BT_MAC_LEN);
111
112 uint64_t u64Mac = 0;
113 if (result != SOFTBUS_OK && ConvertBtMacToU64(copyMac, BT_MAC_LEN, &u64Mac) == SOFTBUS_OK) {
114 ConnPostMsgToLooper(
115 &g_brConnectionAsyncHandler, MSG_CONNECTION_REPORT_CONNECT_EXCEPTION, u64Mac, result, NULL, 0);
116 }
117
118 ConnBrConnection *connection = ConnBrGetConnectionByAddr(copyMac, CONN_SIDE_CLIENT);
119 CONN_CHECK_AND_RETURN_LOGE(connection != NULL, CONN_BR,
120 "connection not exist, mac=%{public}s, result=%{public}d, status=%{public}d",
121 anomizeAddress, result, status);
122 BrUnderlayerStatus *callbackStatus = (BrUnderlayerStatus *)SoftBusCalloc(sizeof(BrUnderlayerStatus));
123 if (callbackStatus == NULL) {
124 CONN_LOGE(CONN_BR,
125 "calloc failed, mac=%{public}s, result=%{public}d, status=%{public}d", anomizeAddress, result, status);
126 ConnBrReturnConnection(&connection);
127 return;
128 }
129 ListInit(&callbackStatus->node);
130 callbackStatus->status = status;
131 callbackStatus->result = result;
132 ListAdd(&connection->connectProcessStatus->list, &callbackStatus->node);
133 CONN_LOGD(CONN_BR, "br on connect calback, mac=%{public}s, connId=%{public}d, result=%{public}d, "
134 "status=%{public}d", anomizeAddress, connection->connectionId, result, status);
135 ConnBrReturnConnection(&connection);
136 }
137
StartBrClientConnect(ConnBrConnection * connection,const char * anomizeAddress)138 static int32_t StartBrClientConnect(ConnBrConnection *connection, const char *anomizeAddress)
139 {
140 uint8_t binaryAddr[BT_ADDR_LEN] = { 0 };
141 int32_t status = ConvertBtMacToBinary(connection->addr, BT_MAC_LEN, binaryAddr, BT_ADDR_LEN);
142 if (status != SOFTBUS_OK) {
143 CONN_LOGE(CONN_BR, "convert string mac to binary fail, connId=%{public}u, address=%{public}s, "
144 "error=%{public}d", connection->connectionId, anomizeAddress, status);
145 return SOFTBUS_CONN_BR_INVALID_ADDRESS_ERR;
146 }
147 BtSocketConnectionCallback callback = {
148 .connStateCb = BrConnectStatusCallback,
149 };
150 int32_t socketHandle = g_sppDriver->Connect(UUID, binaryAddr, &callback);
151 if (socketHandle <= INVALID_SOCKET_HANDLE) {
152 CONN_LOGE(CONN_BR, "underlayer bluetooth connect failed, connId=%{public}u, address=%{public}s",
153 connection->connectionId, anomizeAddress);
154 ConnAlarmExtra extraAlarm = {
155 .linkType = CONNECT_BR,
156 .errcode = SOFTBUS_CONN_BR_UNDERLAY_CONNECT_FAIL,
157 };
158 CONN_ALARM(CONNECTION_FAIL_ALARM, MANAGE_ALARM_TYPE, extraAlarm);
159 return SOFTBUS_CONN_BR_UNDERLAY_CONNECT_FAIL;
160 }
161 if (SoftBusMutexLock(&connection->lock) != SOFTBUS_OK) {
162 CONN_LOGE(CONN_BR, "get lock failed, connId=%{public}u, address=%{public}s", connection->connectionId,
163 anomizeAddress);
164 g_sppDriver->DisConnect(socketHandle);
165 return SOFTBUS_LOCK_ERR;
166 }
167 if (connection->state != BR_CONNECTION_STATE_CONNECTING) {
168 CONN_LOGE(CONN_BR, "unexpected state, connId=%{public}u, address=%{public}s, state=%{public}d",
169 connection->connectionId, anomizeAddress, connection->state);
170 g_sppDriver->DisConnect(socketHandle);
171 connection->state = BR_CONNECTION_STATE_CLOSED;
172 (void)SoftBusMutexUnlock(&connection->lock);
173 return SOFTBUS_CONN_BR_INTERNAL_ERR;
174 }
175 connection->socketHandle = socketHandle;
176 connection->state = BR_CONNECTION_STATE_CONNECTED;
177 (void)SoftBusMutexUnlock(&connection->lock);
178 return SOFTBUS_OK;
179 }
180
StartClientConnect(void * connectCtx)181 static void *StartClientConnect(void *connectCtx)
182 {
183 ClientConnectContext *ctx = (ClientConnectContext *)connectCtx;
184 uint32_t connectionId = ctx->connectionId;
185 SoftBusFree(ctx);
186 ConnBrConnection *connection = ConnBrGetConnectionById(connectionId);
187 if (connection == NULL) {
188 CONN_LOGE(CONN_BR, "connection not exist, connId=%{public}u", connectionId);
189 g_eventListener.onClientConnectFailed(connectionId, SOFTBUS_CONN_BR_INTERNAL_ERR);
190 return NULL;
191 }
192 char anomizeAddress[BT_MAC_LEN] = { 0 };
193 ConvertAnonymizeMacAddress(anomizeAddress, BT_MAC_LEN, connection->addr, BT_MAC_LEN);
194 CONN_LOGI(CONN_BR, "connId=%{public}u, address=%{public}s", connectionId, anomizeAddress);
195 do {
196 int ret = StartBrClientConnect(connection, anomizeAddress);
197 if (ret != SOFTBUS_OK) {
198 CONN_LOGI(CONN_BR, "connId=%{public}u, error=%{public}d", connectionId, ret);
199 g_eventListener.onClientConnectFailed(connection->connectionId, ret);
200 break;
201 }
202
203 CONN_LOGI(CONN_BR, "connect ok, id=%{public}u, address=%{public}s, socket=%{public}d",
204 connection->connectionId, anomizeAddress, connection->socketHandle);
205 g_eventListener.onClientConnected(connection->connectionId);
206 ret = LoopRead(connection->connectionId, connection->socketHandle);
207 CONN_LOGD(CONN_BR, "br client loop read exit, connId=%{public}u, address=%{public}s, socketHandle=%{public}d, "
208 "error=%{public}d", connection->connectionId, anomizeAddress, connection->socketHandle, ret);
209
210 if (SoftBusMutexLock(&connection->lock) != SOFTBUS_OK) {
211 CONN_LOGE(CONN_BR, "get lock failed, connId=%{public}u, address=%{public}s", connection->connectionId,
212 anomizeAddress);
213 g_eventListener.onConnectionException(connection->connectionId, SOFTBUS_LOCK_ERR);
214 break;
215 }
216 if (connection->socketHandle != INVALID_SOCKET_HANDLE) {
217 g_sppDriver->DisConnect(connection->socketHandle);
218 connection->socketHandle = INVALID_SOCKET_HANDLE;
219 }
220 connection->state = (ret == SOFTBUS_CONN_BR_UNDERLAY_SOCKET_CLOSED ? BR_CONNECTION_STATE_CLOSED :
221 BR_CONNECTION_STATE_EXCEPTION);
222 (void)SoftBusMutexUnlock(&connection->lock);
223 g_eventListener.onConnectionException(connection->connectionId, ret);
224 } while (false);
225 ConnBrReturnConnection(&connection);
226 return NULL;
227 }
228
CreateAndSaveConnection(int32_t socketHandle)229 static ConnBrConnection *CreateAndSaveConnection(int32_t socketHandle)
230 {
231 BluetoothRemoteDevice remote;
232 (void)memset_s(&remote, sizeof(remote), 0, sizeof(remote));
233 int32_t ret = g_sppDriver->GetRemoteDeviceInfo(socketHandle, &remote);
234 if (ret != SOFTBUS_OK) {
235 CONN_LOGE(CONN_BR, "GetRemoteDeviceInfo failed, socket=%{public}u, error=%{public}d", socketHandle, ret);
236 g_sppDriver->DisConnect(socketHandle);
237 return NULL;
238 }
239 char mac[BT_MAC_LEN] = { 0 };
240 ret = ConvertBtMacToStr(mac, BT_MAC_LEN, (uint8_t *)remote.mac, BT_ADDR_LEN);
241 if (ret != SOFTBUS_OK) {
242 CONN_LOGE(CONN_BR, "ConvertBtMacToStr failed, socket=%{public}u, error=%{public}d", socketHandle, ret);
243 g_sppDriver->DisConnect(socketHandle);
244 return NULL;
245 }
246 ConnBrConnection *connection = ConnBrCreateConnection(mac, CONN_SIDE_SERVER, socketHandle);
247 if (connection == NULL) {
248 CONN_LOGE(CONN_BR, "create connection failed, socket=%{public}u, error=%{public}d", socketHandle, ret);
249 g_sppDriver->DisConnect(socketHandle);
250 return NULL;
251 }
252 ret = ConnBrSaveConnection(connection);
253 if (ret != SOFTBUS_OK) {
254 CONN_LOGE(CONN_BR, "ConnBrSaveConnection failed, socket=%{public}u, error=%{public}d", socketHandle, ret);
255 g_sppDriver->DisConnect(socketHandle);
256 ConnBrFreeConnection(connection);
257 return NULL;
258 }
259 return connection;
260 }
261
StartServerServe(void * serveCtx)262 static void *StartServerServe(void *serveCtx)
263 {
264 ServerServeContext *ctx = (ServerServeContext *)serveCtx;
265 int32_t socketHandle = ctx->socketHandle;
266 SoftBusFree(ctx);
267 ConnBrConnection *connection = CreateAndSaveConnection(socketHandle);
268 CONN_CHECK_AND_RETURN_RET_LOGE(connection != NULL, NULL, CONN_BR, "connection is not exist");
269 do {
270 CONN_LOGI(CONN_BR, "connId=%{public}u, socket=%{public}d", connection->connectionId, socketHandle);
271 g_eventListener.onServerAccepted(connection->connectionId);
272 int32_t ret = LoopRead(connection->connectionId, socketHandle);
273 CONN_LOGD(CONN_BR, "loop read exit, connId=%{public}u, socket=%{public}d, ret=%{public}d",
274 connection->connectionId, socketHandle, ret);
275
276 if (SoftBusMutexLock(&connection->lock) != SOFTBUS_OK) {
277 CONN_LOGE(CONN_BR, "get lock failed, connId=%{public}u, socket=%{public}d", connection->connectionId,
278 socketHandle);
279 g_sppDriver->DisConnect(socketHandle);
280 g_eventListener.onConnectionException(connection->connectionId, SOFTBUS_LOCK_ERR);
281 break;
282 }
283 if (connection->socketHandle != INVALID_SOCKET_HANDLE) {
284 g_sppDriver->DisConnect(socketHandle);
285 connection->socketHandle = INVALID_SOCKET_HANDLE;
286 }
287 connection->state = (ret == SOFTBUS_CONN_BR_UNDERLAY_SOCKET_CLOSED ? BR_CONNECTION_STATE_CLOSED :
288 BR_CONNECTION_STATE_EXCEPTION);
289 (void)SoftBusMutexUnlock(&connection->lock);
290 g_eventListener.onConnectionException(connection->connectionId, ret);
291 } while (false);
292 ConnBrReturnConnection(&connection);
293 return NULL;
294 }
295
ConnBrCreateConnection(const char * addr,ConnSideType side,int32_t socketHandle)296 ConnBrConnection *ConnBrCreateConnection(const char *addr, ConnSideType side, int32_t socketHandle)
297 {
298 CONN_CHECK_AND_RETURN_RET_LOGW(addr != NULL, NULL, CONN_BR, "br creat connection: addr is NULL");
299 ConnBrConnection *connection = (ConnBrConnection *)SoftBusCalloc(sizeof(ConnBrConnection));
300 CONN_CHECK_AND_RETURN_RET_LOGE(connection != NULL, NULL, CONN_BR, "calloc br conn failed");
301 SoftBusList *list = CreateSoftBusList();
302 if (list == NULL) {
303 CONN_LOGE(CONN_BR, "create softbus list failed");
304 SoftBusFree(connection);
305 return NULL;
306 }
307 connection->connectProcessStatus = list;
308 ListInit(&connection->node);
309 // the final connectionId value is allocate on saving global
310 connection->connectionId = 0;
311 connection->side = side;
312 if (strcpy_s(connection->addr, BT_MAC_LEN, addr) != EOK) {
313 CONN_LOGE(CONN_BR, "copy address failed");
314 SoftBusFree(connection);
315 return NULL;
316 }
317 connection->mtu = (uint32_t)g_mtuSize;
318 if (SoftBusMutexInit(&connection->lock, NULL) != SOFTBUS_OK) {
319 CONN_LOGE(CONN_BR, "init lock failed");
320 SoftBusFree(connection);
321 return NULL;
322 }
323 connection->socketHandle = socketHandle;
324 connection->state = (side == CONN_SIDE_CLIENT ? BR_CONNECTION_STATE_CONNECTING : BR_CONNECTION_STATE_CONNECTED);
325 // br connection do not need exchange connection reference when establish first time, so the init value is 1
326 connection->connectionRc = 1;
327 connection->objectRc = 1;
328 connection->window = DEFAULT_WINDOW;
329 connection->sequence = 0;
330 connection->waitSequence = 0;
331 connection->ackTimeoutCount = 0;
332 connection->retryCount = 0;
333 return connection;
334 }
335
ConnBrOccupy(ConnBrConnection * connection)336 void ConnBrOccupy(ConnBrConnection *connection)
337 {
338 CONN_CHECK_AND_RETURN_LOGE(connection != NULL, CONN_BR, "conn is NULL");
339 CONN_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&connection->lock) == SOFTBUS_OK, CONN_BR,
340 "lock failed, connId=%{public}u", connection->connectionId);
341 ConnRemoveMsgFromLooper(
342 &g_brConnectionAsyncHandler, MSG_CONNECTION_OCCUPY_RELEASE, connection->connectionId, 0, NULL);
343 int32_t res = ConnPostMsgToLooper(&g_brConnectionAsyncHandler,
344 MSG_CONNECTION_OCCUPY_RELEASE, connection->connectionId, 0, NULL, WAIT_TIMEOUT_OCCUPY);
345 if (res != SOFTBUS_OK) {
346 CONN_LOGW(CONN_BR, "post msg failed, connId=%{public}u, err=%{public}d", connection->connectionId, res);
347 (void)SoftBusMutexUnlock(&connection->lock);
348 return;
349 }
350 connection->isOccupied = true;
351 (void)SoftBusMutexUnlock(&connection->lock);
352 }
353
ConnBrFreeConnection(ConnBrConnection * connection)354 void ConnBrFreeConnection(ConnBrConnection *connection)
355 {
356 CONN_CHECK_AND_RETURN_LOGW(connection != NULL, CONN_BR, "br free connection: connection is NULL");
357 if (connection->connectProcessStatus == NULL) {
358 CONN_LOGW(CONN_BR, "connectProcessStatus is NULL");
359 SoftBusFree(connection);
360 return;
361 }
362 SoftBusMutexDestroy(&connection->lock);
363 BrUnderlayerStatus *item = NULL;
364 BrUnderlayerStatus *next = NULL;
365 LIST_FOR_EACH_ENTRY_SAFE(item, next, &connection->connectProcessStatus->list, BrUnderlayerStatus, node) {
366 ListDelete(&item->node);
367 SoftBusFree(item);
368 }
369 DestroySoftBusList(connection->connectProcessStatus);
370 SoftBusFree(connection);
371 }
372
373 // connect peer as client
ConnBrConnect(ConnBrConnection * connection)374 int32_t ConnBrConnect(ConnBrConnection *connection)
375 {
376 ClientConnectContext *ctx = (ClientConnectContext *)SoftBusCalloc(sizeof(ClientConnectContext));
377 CONN_CHECK_AND_RETURN_RET_LOGE(ctx != NULL, SOFTBUS_LOCK_ERR, CONN_BR,
378 "br client connect: calloc failed, connId=%{public}u", connection->connectionId);
379 ctx->connectionId = connection->connectionId;
380 int32_t status = ConnStartActionAsync(ctx, StartClientConnect, NULL);
381 if (status != SOFTBUS_OK) {
382 CONN_LOGE(CONN_BR, "start connect thread failed, connId=%{public}u, error=%{public}d", connection->connectionId,
383 status);
384 SoftBusFree(ctx);
385 return status;
386 }
387 return SOFTBUS_OK;
388 }
389
NotifyUpdateConnectionRc(uint32_t connectionId,int32_t delta)390 static int32_t NotifyUpdateConnectionRc(uint32_t connectionId, int32_t delta)
391 {
392 ConnBrConnection *connection = ConnBrGetConnectionById(connectionId);
393 CONN_CHECK_AND_RETURN_RET_LOGE(
394 connection != NULL, SOFTBUS_INVALID_PARAM, CONN_BR, "conn not exist, id=%{public}u", connectionId);
395 if (SoftBusMutexLock(&connection->lock) != SOFTBUS_OK) {
396 CONN_LOGI(CONN_BR, "lock failed, connId=%{public}u, delta=%{public}d", connectionId, delta);
397 ConnBrReturnConnection(&connection);
398 return SOFTBUS_LOCK_ERR;
399 }
400 connection->connectionRc += delta;
401 CONN_LOGI(CONN_BR, "connId=%{public}u, side=%{public}d, delta=%{public}d, newRef=%{public}d", connectionId,
402 connection->side, delta, connection->connectionRc);
403 if (connection->connectionRc <= 0) {
404 connection->state = BR_CONNECTION_STATE_NEGOTIATION_CLOSING;
405 ConnPostMsgToLooper(&g_brConnectionAsyncHandler, MSG_CONNECTION_WAIT_NEGOTIATION_CLOSING_TIMEOUT, connectionId,
406 0, NULL, WAIT_BR_NEGOTIATION_CLOSING_TIMEOUT_MILLIS);
407 }
408 (void)SoftBusMutexUnlock(&connection->lock);
409 BrCtlMessageSerializationContext ctx = {
410 .connectionId = connectionId,
411 .flag = delta >= 0 ? CONN_HIGH : CONN_LOW,
412 .method = BR_METHOD_NOTIFY_REQUEST,
413 .referenceRequest = {
414 .delta = delta,
415 .referenceNumber = connection->connectionRc,
416 },
417 };
418 ConnEventExtra extra = {
419 .connectionId = (int32_t)connectionId,
420 .connRcDelta = delta,
421 .connRc = connection->connectionRc,
422 .peerBrMac = connection->addr,
423 .linkType = CONNECT_BR,
424 };
425 ConnBrReturnConnection(&connection);
426 uint8_t *data = NULL;
427 uint32_t dataLen = 0;
428 int64_t seq = ConnBrPackCtlMessage(ctx, &data, &dataLen);
429 if (seq < 0) {
430 CONN_LOGE(CONN_BR, "request message failed, connId=%{public}u, ret=%{public}d", connectionId, (int32_t)seq);
431 extra.errcode = (int32_t)seq;
432 extra.result = EVENT_STAGE_RESULT_FAILED;
433 CONN_EVENT(EVENT_SCENE_CONNECT, EVENT_STAGE_CONNECT_UPDATE_CONNECTION_RC, extra);
434 return (int32_t)seq;
435 }
436 extra.errcode = ConnBrPostBytes(connectionId, data, dataLen, 0, ctx.flag, MODULE_CONNECTION, seq);
437 extra.result = extra.errcode == SOFTBUS_OK ? EVENT_STAGE_RESULT_OK : EVENT_STAGE_RESULT_FAILED;
438 CONN_EVENT(EVENT_SCENE_CONNECT, EVENT_STAGE_CONNECT_UPDATE_CONNECTION_RC, extra);
439 return extra.errcode;
440 }
441
BrUpdateConnectionRc(uint32_t connectionId,int32_t delta)442 static int32_t BrUpdateConnectionRc(uint32_t connectionId, int32_t delta)
443 {
444 ConnBrConnection *connection = ConnBrGetConnectionById(connectionId);
445 CONN_CHECK_AND_RETURN_RET_LOGE(
446 connection != NULL, SOFTBUS_INVALID_PARAM, CONN_BR, "conn not exist, id=%{public}u", connectionId);
447
448 int32_t status = SoftBusMutexLock(&connection->lock);
449 if (status != SOFTBUS_OK) {
450 CONN_LOGE(CONN_BR, "lock failed, connectionId=%{public}u, error=%{public}d", connectionId, status);
451 ConnBrReturnConnection(&connection);
452 return SOFTBUS_LOCK_ERR;
453 }
454 bool isOccupied = connection->isOccupied;
455 (void)SoftBusMutexUnlock(&connection->lock);
456 ConnBrReturnConnection(&connection);
457
458 if (delta < 0 && isOccupied) {
459 CONN_LOGI(CONN_BR, "is occupied, process later, connId=%{public}u", connectionId);
460 status = ConnPostMsgToLooper(&g_brConnectionAsyncHandler, MSG_CONNECTION_UPDATE_LOCAL_RC, connectionId, delta,
461 NULL, WAIT_TIMEOUT_TRY_AGAIN);
462 if (status != SOFTBUS_OK) {
463 CONN_LOGE(CONN_BR, "post msg failed, connectionId=%{public}u, error=%{public}d", connectionId, status);
464 return status;
465 }
466 return SOFTBUS_OK;
467 }
468 return NotifyUpdateConnectionRc(connectionId, delta);
469 }
470
ConnBrUpdateConnectionRc(ConnBrConnection * connection,int32_t delta)471 int32_t ConnBrUpdateConnectionRc(ConnBrConnection *connection, int32_t delta)
472 {
473 CONN_CHECK_AND_RETURN_RET_LOGE(connection, SOFTBUS_INVALID_PARAM, CONN_BR, "conn is null");
474 return BrUpdateConnectionRc(connection->connectionId, delta);
475 }
476
ConnBrDisconnectNow(ConnBrConnection * connection)477 int32_t ConnBrDisconnectNow(ConnBrConnection *connection)
478 {
479 CONN_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&connection->lock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR, CONN_BR,
480 "br disconnect now: lock failed, connId=%{public}u", connection->connectionId);
481 int32_t status = SOFTBUS_OK;
482 if (connection->socketHandle != INVALID_SOCKET_HANDLE) {
483 status = g_sppDriver->DisConnect(connection->socketHandle);
484 connection->socketHandle = INVALID_SOCKET_HANDLE;
485 }
486 connection->state = BR_CONNECTION_STATE_CLOSED;
487 SoftBusMutexUnlock(&connection->lock);
488 return status;
489 }
490
BrPostReplyMessage(uint32_t connectionId,int32_t localRc)491 static int32_t BrPostReplyMessage(uint32_t connectionId, int32_t localRc)
492 {
493 int32_t flag = CONN_HIGH;
494 BrCtlMessageSerializationContext ctx = {
495 .connectionId = connectionId,
496 .flag = flag,
497 .method = BR_METHOD_NOTIFY_RESPONSE,
498 .referenceResponse = {
499 .referenceNumber = localRc,
500 },
501 };
502 uint8_t *data = NULL;
503 uint32_t dataLen = 0;
504 int64_t seq = ConnBrPackCtlMessage(ctx, &data, &dataLen);
505 if (seq < 0) {
506 CONN_LOGE(CONN_BR, "reply message faild, connectionId=%{public}u, ret=%{public}d", connectionId, (int32_t)seq);
507 return (int32_t)seq;
508 }
509 return ConnBrPostBytes(connectionId, data, dataLen, 0, flag, MODULE_CONNECTION, seq);
510 }
511
NotifyReferenceRequest(uint32_t connectionId,int32_t delta,int32_t peerRc)512 static int32_t NotifyReferenceRequest(uint32_t connectionId, int32_t delta, int32_t peerRc)
513 {
514 ConnBrConnection *connection = ConnBrGetConnectionById(connectionId);
515 CONN_CHECK_AND_RETURN_RET_LOGE(
516 connection != NULL, SOFTBUS_INVALID_PARAM, CONN_BR, "conn not exist, id=%{public}u", connectionId);
517 int32_t status = SoftBusMutexLock(&connection->lock);
518 if (status != SOFTBUS_OK) {
519 CONN_LOGE(CONN_BR, "lock failed, connectionId=%{public}u, error=%{public}d", connectionId, status);
520 ConnBrReturnConnection(&connection);
521 return SOFTBUS_LOCK_ERR;
522 }
523 connection->connectionRc += delta;
524 int32_t localRc = connection->connectionRc;
525 CONN_LOGI(CONN_BR, "connId=%{public}u, delta=%{public}d, peerRc=%{public}d, localRc=%{public}d", connectionId,
526 delta, peerRc, localRc);
527 if (peerRc > 0) {
528 if (localRc == 0) {
529 ConnPostMsgToLooper(&g_brConnectionAsyncHandler, MSG_CONNECTION_RETRY_NOTIFY_REFERENCE, connectionId, 0,
530 NULL, RETRY_NOTIFY_REFERENCE_DELAY_MILLIS);
531 }
532 if (connection->state == BR_CONNECTION_STATE_NEGOTIATION_CLOSING) {
533 ConnRemoveMsgFromLooper(
534 &g_brConnectionAsyncHandler, MSG_CONNECTION_WAIT_NEGOTIATION_CLOSING_TIMEOUT, connectionId, 0, NULL);
535 connection->state = BR_CONNECTION_STATE_CONNECTED;
536 g_eventListener.onConnectionResume(connectionId);
537 }
538 (void)SoftBusMutexUnlock(&connection->lock);
539 ConnBrReturnConnection(&connection);
540 return SOFTBUS_OK;
541 }
542 if (localRc <= 0) {
543 connection->state = BR_CONNECTION_STATE_CLOSING;
544 (void)SoftBusMutexUnlock(&connection->lock);
545 ConnBrDisconnectNow(connection);
546 ConnBrReturnConnection(&connection);
547 return SOFTBUS_OK;
548 }
549 (void)SoftBusMutexUnlock(&connection->lock);
550 ConnBrReturnConnection(&connection);
551 return BrPostReplyMessage(connectionId, localRc);
552 }
553
BrOnOccupyRelease(uint32_t connectionId)554 static void BrOnOccupyRelease(uint32_t connectionId)
555 {
556 ConnBrConnection *connection = ConnBrGetConnectionById(connectionId);
557 CONN_CHECK_AND_RETURN_LOGE(connection != NULL, CONN_BR, "conn not exist, id=%{public}u", connectionId);
558 int32_t status = SoftBusMutexLock(&connection->lock);
559 if (status != SOFTBUS_OK) {
560 CONN_LOGE(CONN_BR, "lock failed, connectionId=%{public}u, error=%{public}d", connectionId, status);
561 ConnBrReturnConnection(&connection);
562 return;
563 }
564 connection->isOccupied = false;
565 (void)SoftBusMutexUnlock(&connection->lock);
566 ConnBrReturnConnection(&connection);
567 }
568
BrOnReferenceRequest(uint32_t connectionId,ReferenceCount * referenceCount)569 static int32_t BrOnReferenceRequest(uint32_t connectionId, ReferenceCount *referenceCount)
570 {
571 int32_t delta = referenceCount->delta;
572 int32_t peerRc = referenceCount->peerRc;
573 ConnBrConnection *connection = ConnBrGetConnectionById(connectionId);
574 CONN_CHECK_AND_RETURN_RET_LOGE(connection != NULL,
575 SOFTBUS_INVALID_PARAM, CONN_BR, "conn not exist, id=%{public}u", connectionId);
576
577 int32_t status = SoftBusMutexLock(&connection->lock);
578 if (status != SOFTBUS_OK) {
579 CONN_LOGE(CONN_BR, "lock failed, connectionId=%{public}u, error=%{public}d", connectionId, status);
580 ConnBrReturnConnection(&connection);
581 return SOFTBUS_LOCK_ERR;
582 }
583 bool isOccupied = connection->isOccupied;
584 (void)SoftBusMutexUnlock(&connection->lock);
585 ConnBrReturnConnection(&connection);
586
587 if (delta < 0 && isOccupied) {
588 CONN_LOGI(CONN_BR, "is occupied, request process later, connectionId=%{public}u", connectionId);
589 ReferenceCount *referenceParam = (ReferenceCount *)SoftBusMalloc(sizeof(ReferenceCount));
590 if (referenceParam == NULL) {
591 CONN_LOGE(CONN_BR, "malloc buffer failed, connectionId=%{public}u", connectionId);
592 return SOFTBUS_MALLOC_ERR;
593 }
594 referenceParam->delta = delta;
595 referenceParam->peerRc = peerRc;
596
597 int32_t res = ConnPostMsgToLooper(&g_brConnectionAsyncHandler, MSG_CONNECTION_UPDATE_PEER_RC, connectionId, 0,
598 referenceParam, WAIT_TIMEOUT_TRY_AGAIN);
599 if (res != SOFTBUS_OK) {
600 CONN_LOGE(CONN_BR, "post msg failed, connectionId=%{public}u, error=%{public}d", connectionId, res);
601 SoftBusFree(referenceParam);
602 return status;
603 }
604 return SOFTBUS_OK;
605 }
606 return NotifyReferenceRequest(connectionId, delta, peerRc);
607 }
608
ConnBrOnReferenceRequest(ConnBrConnection * connection,const cJSON * json)609 int32_t ConnBrOnReferenceRequest(ConnBrConnection *connection, const cJSON *json)
610 {
611 int32_t delta = 0;
612 int32_t peerRc = 0;
613 if (!GetJsonObjectSignedNumberItem(json, KEY_DELTA, &delta) ||
614 !GetJsonObjectSignedNumberItem(json, KEY_REFERENCE_NUM, &peerRc)) {
615 CONN_LOGE(CONN_BR, "parse delta or ref failed, connectionId=%{public}u, delta=%{public}d, peerRc=%{public}d",
616 connection->connectionId, delta, peerRc);
617 return SOFTBUS_PARSE_JSON_ERR;
618 }
619 ReferenceCount referenceCount = {
620 .delta = delta,
621 .peerRc = peerRc,
622 };
623 return BrOnReferenceRequest(connection->connectionId, &referenceCount);
624 }
625
ConnBrOnReferenceResponse(ConnBrConnection * connection,const cJSON * json)626 int32_t ConnBrOnReferenceResponse(ConnBrConnection *connection, const cJSON *json)
627 {
628 CONN_CHECK_AND_RETURN_RET_LOGW(connection != NULL, SOFTBUS_INVALID_PARAM, CONN_BR, "invalid param");
629 int32_t peerRc = 0;
630 if (!GetJsonObjectSignedNumberItem(json, KEY_REFERENCE_NUM, &peerRc)) {
631 CONN_LOGE(CONN_BR, "parse delta or ref failed. connectionId=%{public}u", connection->connectionId);
632 return SOFTBUS_PARSE_JSON_ERR;
633 }
634
635 int32_t status = SoftBusMutexLock(&connection->lock);
636 if (status != SOFTBUS_OK) {
637 CONN_LOGE(CONN_BR, "get lock failed, connectionId=%{public}u, error=%{public}d", connection->connectionId,
638 status);
639 return SOFTBUS_LOCK_ERR;
640 }
641
642 CONN_LOGI(CONN_BR, "connectionId=%{public}u, peerRc=%{public}d, localRc=%{public}d, currentState=%{public}d",
643 connection->connectionId, peerRc, connection->connectionRc, connection->state);
644 if (peerRc > 0 && connection->state == BR_CONNECTION_STATE_NEGOTIATION_CLOSING) {
645 ConnRemoveMsgFromLooper(&g_brConnectionAsyncHandler, MSG_CONNECTION_WAIT_NEGOTIATION_CLOSING_TIMEOUT,
646 connection->connectionId, 0, NULL);
647 connection->state = BR_CONNECTION_STATE_CONNECTED;
648 g_eventListener.onConnectionResume(connection->connectionId);
649 }
650 (void)SoftBusMutexUnlock(&connection->lock);
651 return SOFTBUS_OK;
652 }
653
CheckBrServerStateAndOpenSppServer(ServerState * serverState)654 static int32_t CheckBrServerStateAndOpenSppServer(ServerState *serverState)
655 {
656 #define BR_ACCEPET_WAIT_TIME 1000
657 const char *name = "BrManagerInsecure";
658 int32_t status = SoftBusMutexLock(&serverState->mutex);
659 if (status != SOFTBUS_OK) {
660 CONN_LOGE(CONN_BR, "lock failed, exit listen task, traceId=%{public}u, error=%{public}d",
661 serverState->traceId, status);
662 return SOFTBUS_LOCK_ERR;
663 }
664 if (!serverState->available) {
665 CONN_LOGW(CONN_BR, "server closed, exit listen task, traceId=%{public}u", serverState->traceId);
666 SoftBusMutexUnlock(&serverState->mutex);
667 return SOFTBUS_INVALID_PARAM;
668 }
669 if (serverState->serverId != -1) {
670 g_sppDriver->CloseSppServer(serverState->serverId);
671 serverState->serverId = -1;
672 }
673 (void)SoftBusMutexUnlock(&serverState->mutex);
674 int32_t serverId = g_sppDriver->OpenSppServer(name, (int32_t)strlen(name), UUID, 0);
675 if (serverId == -1) {
676 CONN_LOGE(CONN_BR,
677 "open br server failed, retry after some times, retryDelay=%{public}d, traceId=%{public}u",
678 BR_ACCEPET_WAIT_TIME, serverState->traceId);
679 SoftBusSleepMs(BR_ACCEPET_WAIT_TIME);
680 return SOFTBUS_CONN_BR_RETRY_OPEN_SERVER;
681 }
682 CONN_LOGI(CONN_BR, "open br server ok, traceId=%{public}u, serverId=%{public}d", serverState->traceId,
683 serverId);
684 status = SoftBusMutexLock(&serverState->mutex);
685 if (status != SOFTBUS_OK) {
686 CONN_LOGE(CONN_BR, "lock failed, exit listen task, traceId=%{public}u, error=%{public}d",
687 serverState->traceId, status);
688 g_sppDriver->CloseSppServer(serverId);
689 return SOFTBUS_LOCK_ERR;
690 }
691 if (!serverState->available) {
692 CONN_LOGW(CONN_BR, "server closed during create socket period, exit listen task. traceId=%{public}u",
693 serverState->traceId);
694 g_sppDriver->CloseSppServer(serverId);
695 (void)SoftBusMutexUnlock(&serverState->mutex);
696 return SOFTBUS_INVALID_PARAM;
697 }
698 serverState->serverId = serverId;
699 (void)SoftBusMutexUnlock(&serverState->mutex);
700 return SOFTBUS_OK;
701 }
702
ListenTask(void * arg)703 static void *ListenTask(void *arg)
704 {
705 CONN_CHECK_AND_RETURN_RET_LOGW(arg != NULL, NULL, CONN_BR, "invalid param");
706 ServerState *serverState = (ServerState *)arg;
707 CONN_CHECK_AND_RETURN_RET_LOGE(serverState != NULL, NULL, CONN_BLE, "serverState is null");
708 CONN_LOGI(CONN_BR, "traceId=%{public}u", serverState->traceId);
709 int32_t status = SOFTBUS_OK;
710 while (true) {
711 status= CheckBrServerStateAndOpenSppServer(serverState);
712 if (status == SOFTBUS_CONN_BR_RETRY_OPEN_SERVER) {
713 continue;
714 }
715 if (status != SOFTBUS_OK) {
716 break;
717 }
718 CONN_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&serverState->mutex) == SOFTBUS_OK,
719 NULL, CONN_BLE, "lock failed");
720 int32_t serverId = serverState->serverId;
721 (void)SoftBusMutexUnlock(&serverState->mutex);
722 while (true) {
723 int32_t socketHandle = g_sppDriver->Accept(serverId);
724 if (socketHandle == SOFTBUS_CONN_BR_SPP_SERVER_ERR) {
725 CONN_LOGE(CONN_BR, "accept failed, traceId=%{public}u, serverId=%{public}d", serverState->traceId,
726 serverId);
727 break;
728 }
729 ServerServeContext *ctx = (ServerServeContext *)SoftBusCalloc(sizeof(ServerServeContext));
730 if (ctx == NULL) {
731 CONN_LOGE(CONN_BR, "calloc serve context failed, traceId=%{public}u, serverId=%{public}d, "
732 "socketHandle=%{public}d", serverState->traceId, serverId, socketHandle);
733 g_sppDriver->DisConnect(socketHandle);
734 continue;
735 }
736 ctx->socketHandle = socketHandle;
737 status = ConnStartActionAsync(ctx, StartServerServe, NULL);
738 if (status != SOFTBUS_OK) {
739 CONN_LOGE(CONN_BR, "start serve thread failed, traceId=%{public}u, serverId=%{public}d, "
740 "socket=%{public}d, error=%{public}d", serverState->traceId, serverId, socketHandle, status);
741 SoftBusFree(ctx);
742 g_sppDriver->DisConnect(socketHandle);
743 continue;
744 }
745 CONN_LOGI(CONN_BR, "accept incoming connection, traceId=%{public}u, serverId=%{public}d, socket=%{public}d",
746 serverState->traceId, serverId, socketHandle);
747 }
748 }
749 CONN_LOGI(CONN_BR, "br server listen exit, traceId=%{public}u", serverState->traceId);
750 (void)SoftBusMutexDestroy(&serverState->mutex);
751 SoftBusFree(serverState);
752 return NULL;
753 }
754
ConnBrStartServer(void)755 int32_t ConnBrStartServer(void)
756 {
757 static uint32_t traceIdGenerator = 0;
758
759 if (g_serverState != NULL) {
760 CONN_LOGW(CONN_BR, "server already started, skip");
761 return SOFTBUS_OK;
762 }
763 ServerState *serverState = (ServerState *)SoftBusCalloc(sizeof(ServerState));
764 CONN_CHECK_AND_RETURN_RET_LOGE(serverState != NULL, SOFTBUS_MEM_ERR, CONN_BR, "calloc server state failed");
765 serverState->traceId = traceIdGenerator++;
766 int32_t status = SoftBusMutexInit(&serverState->mutex, NULL);
767 if (status != SOFTBUS_OK) {
768 CONN_LOGE(CONN_BR, "init mutex failed, error=%{public}d", status);
769 SoftBusFree(serverState);
770 return status;
771 }
772 serverState->available = true;
773 serverState->serverId = -1;
774 status = ConnStartActionAsync(serverState, ListenTask, "BrListen_Tsk");
775 if (status != SOFTBUS_OK) {
776 CONN_LOGE(CONN_BR, "start br server failed: error=%{public}d", status);
777 (void)SoftBusMutexDestroy(&serverState->mutex);
778 SoftBusFree(serverState);
779 return status;
780 }
781 g_serverState = serverState;
782 CONN_LOGI(CONN_BR, "start ok, traceId=%{public}u", serverState->traceId);
783 return SOFTBUS_OK;
784 }
785
ConnBrStopServer(void)786 int32_t ConnBrStopServer(void)
787 {
788 if (g_serverState == NULL) {
789 CONN_LOGE(CONN_BR, "server not started yet, skip");
790 return SOFTBUS_OK;
791 }
792 int32_t status = SoftBusMutexLock(&g_serverState->mutex);
793 if (status != SOFTBUS_OK) {
794 CONN_LOGE(CONN_BR, "lock failed, error=%{public}d", status);
795 return status;
796 }
797 CONN_LOGI(CONN_BR, "traceId=%{public}u", g_serverState->traceId);
798 g_serverState->available = false;
799 if (g_serverState->serverId != -1) {
800 g_sppDriver->CloseSppServer(g_serverState->serverId);
801 g_serverState->serverId = -1;
802 }
803 (void)SoftBusMutexUnlock(&g_serverState->mutex);
804 g_serverState = NULL;
805 return SOFTBUS_OK;
806 }
807
WaitNegotiationClosingTimeoutHandler(uint32_t connectionId)808 static void WaitNegotiationClosingTimeoutHandler(uint32_t connectionId)
809 {
810 ConnBrConnection *connection = ConnBrGetConnectionById(connectionId);
811 CONN_CHECK_AND_RETURN_LOGW(connection != NULL, CONN_BR,
812 "WaitNegotiationClosingTimeoutHandler: connection not exist, id=%{public}u", connectionId);
813 int32_t status = SoftBusMutexLock(&connection->lock);
814 if (status != SOFTBUS_OK) {
815 CONN_LOGE(CONN_BR, "lock failed, connId=%{public}u, error=%{public}d", connectionId, status);
816 ConnBrReturnConnection(&connection);
817 return;
818 }
819 enum ConnBrConnectionState state = connection->state;
820 (void)SoftBusMutexUnlock(&connection->lock);
821 CONN_LOGD(CONN_BR, "connId=%{public}u, state=%{public}d", connectionId, state);
822 if (state == BR_CONNECTION_STATE_NEGOTIATION_CLOSING) {
823 ConnBrDisconnectNow(connection);
824 }
825 ConnBrReturnConnection(&connection);
826 }
827
RetryNotifyReferenceHandler(uint32_t connectionId)828 static void RetryNotifyReferenceHandler(uint32_t connectionId)
829 {
830 ConnBrConnection *connection = ConnBrGetConnectionById(connectionId);
831 CONN_CHECK_AND_RETURN_LOGW(connection != NULL, CONN_BR,
832 "RetryNotifyReferenceHandler: connection not exist, connectionId=%{public}u", connectionId);
833 ConnBrUpdateConnectionRc(connection, 0);
834 ConnBrReturnConnection(&connection);
835 }
836
ReportConnectExceptionHandler(uint64_t u64Mac,int32_t errorCode)837 static void ReportConnectExceptionHandler(uint64_t u64Mac, int32_t errorCode)
838 {
839 ConnectOption option;
840 (void)memset_s(&option, sizeof(option), 0, sizeof(option));
841 option.type = CONNECT_BR;
842 int32_t ret = ConvertU64MacToStr(u64Mac, option.brOption.brMac, BT_MAC_LEN);
843 if (ret != SOFTBUS_OK) {
844 CONN_LOGE(CONN_BR, "ConvertU64MacToStr faild, ret=%{public}d", ret);
845 return;
846 }
847 LnnDCReportConnectException(&option, errorCode);
848 }
849
BrConnectionMsgHandler(SoftBusMessage * msg)850 static void BrConnectionMsgHandler(SoftBusMessage *msg)
851 {
852 switch (msg->what) {
853 case MSG_CONNECTION_WAIT_NEGOTIATION_CLOSING_TIMEOUT:
854 WaitNegotiationClosingTimeoutHandler((uint32_t)msg->arg1);
855 break;
856 case MSG_CONNECTION_RETRY_NOTIFY_REFERENCE:
857 RetryNotifyReferenceHandler((uint32_t)msg->arg1);
858 break;
859 case MSG_CONNECTION_REPORT_CONNECT_EXCEPTION:
860 ReportConnectExceptionHandler(msg->arg1, (int32_t)msg->arg2);
861 break;
862 case MSG_CONNECTION_OCCUPY_RELEASE:
863 BrOnOccupyRelease((uint32_t)msg->arg1);
864 break;
865 case MSG_CONNECTION_UPDATE_LOCAL_RC:
866 BrUpdateConnectionRc((uint32_t)msg->arg1, (int32_t)msg->arg2);
867 break;
868 case MSG_CONNECTION_UPDATE_PEER_RC:
869 BrOnReferenceRequest((uint32_t)msg->arg1, (ReferenceCount *)msg->obj);
870 break;
871 default:
872 CONN_LOGW(CONN_BR, "receive unexpected msg, what=%{public}d", msg->what);
873 break;
874 }
875 }
876
BrCompareConnectionLooperEventFunc(const SoftBusMessage * msg,void * args)877 static int BrCompareConnectionLooperEventFunc(const SoftBusMessage *msg, void *args)
878 {
879 SoftBusMessage *ctx = (SoftBusMessage *)args;
880 if (msg->what != ctx->what) {
881 return COMPARE_FAILED;
882 }
883 switch (ctx->what) {
884 case MSG_CONNECTION_WAIT_NEGOTIATION_CLOSING_TIMEOUT:
885 case MSG_CONNECTION_UPDATE_PEER_RC:
886 case MSG_CONNECTION_OCCUPY_RELEASE:
887 case MSG_CONNECTION_UPDATE_LOCAL_RC: {
888 if (msg->arg1 == ctx->arg1) {
889 return COMPARE_SUCCESS;
890 }
891 return COMPARE_FAILED;
892 }
893 default:
894 break;
895 }
896 if (ctx->arg1 != 0 || ctx->arg2 != 0 || ctx->obj != NULL) {
897 CONN_LOGE(CONN_BR,
898 "failed to avoid fault silence, "
899 "what=%{public}d, arg1=%{public}" PRIu64 ", arg2=%{public}" PRIu64 ", objIsNull=%{public}d",
900 ctx->what, ctx->arg1, ctx->arg2, ctx->obj == NULL);
901 return COMPARE_FAILED;
902 }
903 return COMPARE_SUCCESS;
904 }
905
InitProperty()906 static int32_t InitProperty()
907 {
908 int32_t capacity = -1;
909 int32_t mtu = -1;
910 if (SoftbusGetConfig(SOFTBUS_INT_CONN_BR_MAX_DATA_LENGTH, (unsigned char *)&capacity, sizeof(capacity)) !=
911 SOFTBUS_OK) {
912 CONN_LOGE(CONN_INIT, "get br buffer capacity config fail");
913 return SOFTBUS_NO_INIT;
914 }
915 if (capacity <= 0 || capacity > MAX_BR_READ_BUFFER_CAPACITY) {
916 CONN_LOGE(CONN_INIT, "br buffer capacity is invalid, capacity=%{public}d", capacity);
917 return SOFTBUS_NO_INIT;
918 }
919 if (SoftbusGetConfig(SOFTBUS_INT_CONN_RFCOM_SEND_MAX_LEN, (unsigned char *)&mtu, sizeof(mtu)) != SOFTBUS_OK) {
920 CONN_LOGE(CONN_INIT, "get br mtu config fail");
921 return SOFTBUS_NO_INIT;
922 }
923 if (mtu <= 0 || mtu > MAX_BR_MTU_SIZE) {
924 CONN_LOGE(CONN_INIT, "br mtu is invalid, mtu=%{public}d", mtu);
925 return SOFTBUS_NO_INIT;
926 }
927 CONN_LOGD(CONN_INIT, "init br config success, read buffer capacity=%{public}d, mtu=%{public}d", capacity, mtu);
928 g_readBufferCapacity = capacity;
929 g_mtuSize = mtu;
930 return SOFTBUS_OK;
931 }
932
ConnBrConnectionMuduleInit(SoftBusLooper * looper,SppSocketDriver * sppDriver,ConnBrEventListener * listener)933 int32_t ConnBrConnectionMuduleInit(SoftBusLooper *looper, SppSocketDriver *sppDriver, ConnBrEventListener *listener)
934 {
935 CONN_CHECK_AND_RETURN_RET_LOGW(looper != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT,
936 "br connection init failed: looper is null");
937 CONN_CHECK_AND_RETURN_RET_LOGW(sppDriver != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT,
938 "br connection init failed: spp driver is null");
939 CONN_CHECK_AND_RETURN_RET_LOGW(listener != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT,
940 "br connection init failed: event listener is null");
941 CONN_CHECK_AND_RETURN_RET_LOGW(listener->onServerAccepted != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT,
942 "br connection init failed: listener OnServerAccepted is null");
943 CONN_CHECK_AND_RETURN_RET_LOGW(listener->onClientConnected != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT,
944 "br connection init failed: listener OnClientConnected is null");
945 CONN_CHECK_AND_RETURN_RET_LOGW(listener->onClientConnectFailed != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT,
946 "br connection init failed: listener OnClientFailed is null");
947 CONN_CHECK_AND_RETURN_RET_LOGW(listener->onDataReceived != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT,
948 "br connection init failed: listener OnDataReceived, is null");
949 CONN_CHECK_AND_RETURN_RET_LOGW(listener->onConnectionException != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT,
950 "br connection init failed: listener OnConnectionException is null");
951 CONN_CHECK_AND_RETURN_RET_LOGW(listener->onConnectionResume != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT,
952 "br connection init failed: listener OnConnectionResume is null");
953
954 int32_t status = InitProperty();
955 CONN_CHECK_AND_RETURN_RET_LOGE(status == SOFTBUS_OK, SOFTBUS_INVALID_PARAM, CONN_INIT,
956 "br connection init failed: init property failed");
957 g_brConnectionAsyncHandler.handler.looper = looper;
958 g_sppDriver = sppDriver;
959 g_eventListener = *listener;
960 return SOFTBUS_OK;
961 }
962