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