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