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