1 /* 2 * Copyright (c) 2023 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_ble_connection.h" 17 18 #include <securec.h> 19 20 #include "conn_event.h" 21 #include "conn_log.h" 22 #include "bus_center_manager.h" 23 #include "softbus_adapter_mem.h" 24 #include "softbus_conn_ble_manager.h" 25 #include "softbus_conn_ble_trans.h" 26 #include "softbus_conn_common.h" 27 #include "softbus_datahead_transform.h" 28 #include "softbus_json_utils.h" 29 #include "ble_protocol_interface_factory.h" 30 #include "softbus_utils.h" 31 32 // basic info json key definition 33 #define BASIC_INFO_KEY_DEVID "devid" 34 #define BASIC_INFO_KEY_ROLE "type" 35 #define BASIC_INFO_KEY_DEVTYPE "devtype" 36 #define BASIC_INFO_KEY_FEATURE "FEATURE_SUPPORT" 37 38 enum ConnectionLoopMsgType { 39 MSG_CONNECTION_RETRY_SERVER_STATE_CONSISTENT = 100, 40 MSG_CONNECTION_EXCHANGE_BASIC_INFO_TIMEOUT, 41 MSG_CONNECTION_WAIT_NEGOTIATION_CLOSING_TIMEOUT, 42 MSG_CONNECTION_IDLE_DISCONNECT_TIMEOUT, 43 MSG_CONNECTION_OCCUPY_RELEASE, 44 MSG_CONNECTION_UPDATE_REFRENCE, 45 }; 46 47 enum BleServerState { 48 BLE_SERVER_STATE_STARTING, 49 BLE_SERVER_STATE_STARTED, 50 BLE_SERVER_STATE_STOPPING, 51 BLE_SERVER_STATE_STOPPED, 52 }; 53 54 // As bluetooth may be change quickly and ble server start and stop is async, 55 // we should coordinate and keep this finally state consistent 56 typedef struct { 57 SoftBusMutex lock; 58 enum BleServerState expect; 59 enum BleServerState actual; 60 int32_t status[BLE_PROTOCOL_MAX]; 61 } BleServerCoordination; 62 63 typedef struct { 64 int32_t delta; 65 int32_t peerRc; 66 uint16_t challengeCode; 67 bool isActiveUpdateLocalRc; 68 } BleReferenceContext; 69 70 typedef struct { 71 int32_t delta; 72 int32_t localRc; 73 int32_t challengeCode; 74 uint32_t connId; 75 int32_t underlayerHandle; 76 } RcPackCtlMsgPara; 77 78 typedef struct { 79 char devId[DEVID_BUFF_LEN]; 80 int32_t deviceType; 81 int32_t feature; 82 int32_t type; 83 } BaseInfo; 84 85 static void BleConnectionMsgHandler(SoftBusMessage *msg); 86 static int BleCompareConnectionLooperEventFunc(const SoftBusMessage *msg, void *args); 87 88 static ConnBleConnectionEventListener g_connectionListener; 89 static SoftBusHandlerWrapper g_bleConnectionAsyncHandler = { 90 .handler = { 91 .name = (char *)"BleConnectionAsyncHandler", 92 .HandleMessage = BleConnectionMsgHandler, 93 // assign when initiation 94 .looper = NULL, 95 }, 96 .eventCompareFunc = BleCompareConnectionLooperEventFunc, 97 }; 98 static BleServerCoordination g_serverCoordination = { 99 .actual = BLE_SERVER_STATE_STOPPED, 100 .expect = BLE_SERVER_STATE_STOPPED, 101 }; 102 // compatible with old devices, old device not support remote disconnect 103 static const ConnBleFeatureBitSet g_featureBitSet = (1 << BLE_FEATURE_SUPPORT_REMOTE_DISCONNECT); 104 ConnBleCreateConnection(const char * addr,BleProtocolType protocol,ConnSideType side,int32_t underlayerHandle,bool fastestConnectEnable)105 ConnBleConnection *ConnBleCreateConnection( 106 const char *addr, BleProtocolType protocol, ConnSideType side, int32_t underlayerHandle, bool fastestConnectEnable) 107 { 108 CONN_CHECK_AND_RETURN_RET_LOGW(addr != NULL, NULL, CONN_BLE, "invalid parameter: ble addr is NULL"); 109 110 ConnBleConnection *connection = (ConnBleConnection *)SoftBusCalloc(sizeof(ConnBleConnection)); 111 CONN_CHECK_AND_RETURN_RET_LOGW(connection != NULL, NULL, CONN_BLE, "calloc ble connection failed"); 112 ListInit(&connection->node); 113 // the final connectionId value is allocate on saving global 114 connection->connectionId = 0; 115 connection->protocol = protocol; 116 connection->side = side; 117 connection->fastestConnectEnable = fastestConnectEnable; 118 if (strcpy_s(connection->addr, BT_MAC_LEN, addr) != EOK) { 119 CONN_LOGE(CONN_BLE, "copy address failed"); 120 SoftBusFree(connection); 121 return NULL; 122 } 123 connection->sequence = 0; 124 connection->buffer.seq = 0; 125 connection->buffer.total = 0; 126 ListInit(&connection->buffer.packets); 127 128 if (SoftBusMutexInit(&connection->lock, NULL) != SOFTBUS_OK) { 129 CONN_LOGE(CONN_BLE, "init lock failed"); 130 SoftBusFree(connection); 131 return NULL; 132 } 133 connection->state = 134 (side == CONN_SIDE_CLIENT ? BLE_CONNECTION_STATE_CONNECTING : BLE_CONNECTION_STATE_EXCHANGING_BASIC_INFO); 135 connection->underlayerHandle = underlayerHandle; 136 // udid field will be assigned after basic info exchanged 137 // the final MTU value will be signed on mtu exchange stage 138 connection->mtu = 0; 139 // ble connection need exchange connection reference even if establish first time, so the init value is 0 140 connection->connectionRc = 0; 141 connection->objectRc = 1; 142 connection->retrySearchServiceCnt = 0; 143 connection->underlayerFastConnectFailedScanFailure = false; 144 connection->isOccupied = false; 145 SoftBusList *list = CreateSoftBusList(); 146 if (list == NULL) { 147 CONN_LOGE(CONN_BLE, "create softbus list failed"); 148 SoftBusMutexDestroy(&connection->lock); 149 SoftBusFree(connection); 150 return NULL; 151 } 152 connection->connectStatus = list; 153 return connection; 154 } 155 ConnBleFreeConnection(ConnBleConnection * connection)156 void ConnBleFreeConnection(ConnBleConnection *connection) 157 { 158 SoftBusMutexDestroy(&connection->lock); 159 ConnBlePacket *it = NULL; 160 ConnBlePacket *next = NULL; 161 LIST_FOR_EACH_ENTRY_SAFE(it, next, &connection->buffer.packets, ConnBlePacket, node) { 162 ListDelete(&it->node); 163 SoftBusFree(it->data); 164 SoftBusFree(it); 165 } 166 167 BleUnderlayerStatus *item = NULL; 168 BleUnderlayerStatus *nextItem = NULL; 169 LIST_FOR_EACH_ENTRY_SAFE(item, nextItem, &connection->connectStatus->list, BleUnderlayerStatus, node) { 170 ListDelete(&item->node); 171 SoftBusFree(item); 172 } 173 DestroySoftBusList(connection->connectStatus); 174 SoftBusFree(connection); 175 } 176 ConnBleStartServer(void)177 int32_t ConnBleStartServer(void) 178 { 179 CONN_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_serverCoordination.lock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR, 180 CONN_BLE, "ble start server failed, try to lock failed"); 181 g_serverCoordination.expect = BLE_SERVER_STATE_STARTED; 182 enum BleServerState actual = g_serverCoordination.actual; 183 (void)SoftBusMutexUnlock(&g_serverCoordination.lock); 184 if (actual == BLE_SERVER_STATE_STARTING || actual == BLE_SERVER_STATE_STARTED) { 185 return SOFTBUS_OK; 186 } 187 const BleUnifyInterface *interface; 188 for (int i = BLE_GATT; i < BLE_PROTOCOL_MAX; i++) { 189 interface = ConnBleGetUnifyInterface(i); 190 if (interface == NULL) { 191 continue; 192 } 193 g_serverCoordination.status[i] = interface->bleServerStartService(); 194 } 195 for (int i = BLE_GATT; i < BLE_PROTOCOL_MAX; i++) { 196 if (g_serverCoordination.status[i] != SOFTBUS_OK) { 197 ConnPostMsgToLooper(&g_bleConnectionAsyncHandler, MSG_CONNECTION_RETRY_SERVER_STATE_CONSISTENT, 0, 0, NULL, 198 RETRY_SERVER_STATE_CONSISTENT_MILLIS); 199 return SOFTBUS_OK; 200 } 201 } 202 CONN_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_serverCoordination.lock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR, 203 CONN_BLE, "ble start server failed, try to lock failed"); 204 g_serverCoordination.actual = BLE_SERVER_STATE_STARTING; 205 (void)SoftBusMutexUnlock(&g_serverCoordination.lock); 206 return SOFTBUS_OK; 207 } 208 ConnBleStopServer(void)209 int32_t ConnBleStopServer(void) 210 { 211 CONN_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_serverCoordination.lock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR, 212 CONN_BLE, "ble stop server failed, try to lock failed"); 213 g_serverCoordination.expect = BLE_SERVER_STATE_STOPPED; 214 enum BleServerState actual = g_serverCoordination.actual; 215 (void)SoftBusMutexUnlock(&g_serverCoordination.lock); 216 if (actual == BLE_SERVER_STATE_STOPPING || actual == BLE_SERVER_STATE_STOPPED) { 217 return SOFTBUS_OK; 218 } 219 const BleUnifyInterface *interface; 220 for (int i = BLE_GATT; i < BLE_PROTOCOL_MAX; i++) { 221 interface = ConnBleGetUnifyInterface(i); 222 if (interface == NULL) { 223 continue; 224 } 225 g_serverCoordination.status[i] = interface->bleServerStopService(); 226 } 227 for (int i = BLE_GATT; i < BLE_PROTOCOL_MAX; i++) { 228 if (g_serverCoordination.status[i] != SOFTBUS_OK) { 229 ConnPostMsgToLooper(&g_bleConnectionAsyncHandler, MSG_CONNECTION_RETRY_SERVER_STATE_CONSISTENT, 0, 0, NULL, 230 RETRY_SERVER_STATE_CONSISTENT_MILLIS); 231 return SOFTBUS_OK; 232 } 233 } 234 CONN_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_serverCoordination.lock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR, 235 CONN_BLE, "ble close server failed, try to lock failed"); 236 g_serverCoordination.actual = BLE_SERVER_STATE_STOPPING; 237 (void)SoftBusMutexUnlock(&g_serverCoordination.lock); 238 return SOFTBUS_OK; 239 } 240 ConnBleConnect(ConnBleConnection * connection)241 int32_t ConnBleConnect(ConnBleConnection *connection) 242 { 243 CONN_CHECK_AND_RETURN_RET_LOGW(connection != NULL, SOFTBUS_INVALID_PARAM, CONN_BLE, 244 "ble connection connect failed, invalid param, connection is null"); 245 const BleUnifyInterface *interface = ConnBleGetUnifyInterface(connection->protocol); 246 CONN_CHECK_AND_RETURN_RET_LOGW(interface != NULL, SOFTBUS_CONN_BLE_INTERNAL_ERR, CONN_BLE, 247 "ble connection connect failed, protocol not support"); 248 return interface->bleClientConnect(connection); 249 } 250 ShouldGrace(enum ConnBleDisconnectReason reason)251 static bool ShouldGrace(enum ConnBleDisconnectReason reason) 252 { 253 switch (reason) { 254 case BLE_DISCONNECT_REASON_CONNECT_TIMEOUT: 255 case BLE_DISCONNECT_REASON_INTERNAL_ERROR: 256 case BLE_DISCONNECT_REASON_POST_BYTES_FAILED: 257 case BLE_DISCONNECT_REASON_RESET: 258 return false; 259 default: 260 return true; 261 } 262 } 263 ShoudRefreshGatt(enum ConnBleDisconnectReason reason)264 static bool ShoudRefreshGatt(enum ConnBleDisconnectReason reason) 265 { 266 switch (reason) { 267 case BLE_DISCONNECT_REASON_CONNECT_TIMEOUT: 268 return true; 269 default: 270 return false; 271 } 272 } 273 ConnBleDisconnectNow(ConnBleConnection * connection,enum ConnBleDisconnectReason reason)274 int32_t ConnBleDisconnectNow(ConnBleConnection *connection, enum ConnBleDisconnectReason reason) 275 { 276 CONN_CHECK_AND_RETURN_RET_LOGW(connection != NULL, SOFTBUS_INVALID_PARAM, CONN_BLE, 277 "ble connection disconnect failed, invalid param, connection is null"); 278 const BleUnifyInterface *interface = ConnBleGetUnifyInterface(connection->protocol); 279 CONN_CHECK_AND_RETURN_RET_LOGW(interface != NULL, SOFTBUS_CONN_BLE_INTERNAL_ERR, CONN_BLE, 280 "ble connection disconnect failed, protocol not support"); 281 CONN_LOGI(CONN_BLE, 282 "receive ble disconnect now, connId=%{public}u, side=%{public}d, reason=%{public}d", 283 connection->connectionId, connection->side, reason); 284 ConnRemoveMsgFromLooper( 285 &g_bleConnectionAsyncHandler, MSG_CONNECTION_IDLE_DISCONNECT_TIMEOUT, connection->connectionId, 0, NULL); 286 if (connection->side == CONN_SIDE_CLIENT) { 287 bool grace = ShouldGrace(reason); 288 bool refreshGatt = ShoudRefreshGatt(reason); 289 return interface->bleClientDisconnect(connection, grace, refreshGatt); 290 } 291 return interface->bleServerDisconnect(connection); 292 } 293 OnDisconnectedDataFinished(uint32_t connectionId,int32_t error)294 static void OnDisconnectedDataFinished(uint32_t connectionId, int32_t error) 295 { 296 if (error != SOFTBUS_OK) { 297 return; 298 } 299 int32_t status = ConnPostMsgToLooper(&g_bleConnectionAsyncHandler, MSG_CONNECTION_WAIT_NEGOTIATION_CLOSING_TIMEOUT, 300 connectionId, 0, NULL, WAIT_NEGOTIATION_CLOSING_TIMEOUT_MILLIS); 301 if (status != SOFTBUS_OK) { 302 CONN_LOGE(CONN_BLE, "post closing timeout event failed, err=%{public}d", status); 303 } 304 } 305 ConnPackCtlMsgRcSendDeltaData(RcPackCtlMsgPara * rcMsgPara)306 static int32_t ConnPackCtlMsgRcSendDeltaData(RcPackCtlMsgPara *rcMsgPara) 307 { 308 int32_t flag = CONN_LOW; 309 if (rcMsgPara->delta >= 0) { 310 flag = CONN_HIGH; 311 } 312 BleCtlMessageSerializationContext ctx = { 313 .connectionId = rcMsgPara->connId, 314 .flag = flag, 315 .method = CTRL_MSG_METHOD_NOTIFY_REQUEST, 316 .referenceRequest = { 317 .referenceNumber = rcMsgPara->localRc, 318 .delta = rcMsgPara->delta, 319 }, 320 .challengeCode = rcMsgPara->challengeCode, 321 }; 322 uint8_t *data = NULL; 323 uint32_t dataLen = 0; 324 int64_t seq = ConnBlePackCtlMessage(ctx, &data, &dataLen); 325 if (seq < 0) { 326 CONN_LOGE(CONN_BLE, "ble pack notify request message failed, " 327 "connId=%{public}u, underlayerHandle=%{public}d, error=%{public}d", 328 rcMsgPara->connId, rcMsgPara->underlayerHandle, (int32_t)seq); 329 return (int32_t)seq; 330 } 331 return rcMsgPara->localRc <= 0 ? 332 ConnBlePostBytesInner(rcMsgPara->connId, data, dataLen, 0, flag, MODULE_CONNECTION, seq, 333 OnDisconnectedDataFinished) : 334 ConnBlePostBytesInner(rcMsgPara->connId, data, dataLen, 0, flag, MODULE_CONNECTION, seq, NULL); 335 } 336 NeedProccessOccupy(ConnBleConnection * connection,int32_t delta,uint16_t challengeCode,bool isActiveUpdateLocalRc,int32_t peerRc)337 static bool NeedProccessOccupy(ConnBleConnection *connection, int32_t delta, uint16_t challengeCode, 338 bool isActiveUpdateLocalRc, int32_t peerRc) 339 { 340 int32_t status = SoftBusMutexLock(&connection->lock); 341 CONN_CHECK_AND_RETURN_RET_LOGE(status == SOFTBUS_OK, false, CONN_BLE, "lock err"); 342 bool isOccupied = connection->isOccupied; 343 (void)SoftBusMutexUnlock(&connection->lock); 344 if (delta > 0 || !isOccupied) { 345 return false; 346 } 347 348 CONN_LOGI(CONN_BLE, "is occupied, process later, connId=%{public}u", connection->connectionId); 349 BleReferenceContext *referenceContext = (BleReferenceContext *)SoftBusMalloc(sizeof(BleReferenceContext)); 350 CONN_CHECK_AND_RETURN_RET_LOGE(referenceContext != NULL, false, CONN_BLE, 351 "malloc buffer failed, connectionId=%{public}u", connection->connectionId); 352 referenceContext->delta = delta; 353 referenceContext->challengeCode = challengeCode; 354 referenceContext->isActiveUpdateLocalRc = isActiveUpdateLocalRc; 355 referenceContext->peerRc = peerRc; 356 status = ConnPostMsgToLooper(&g_bleConnectionAsyncHandler, MSG_CONNECTION_UPDATE_REFRENCE, 357 connection->connectionId, 0, referenceContext, WAIT_TIMEOUT_TRY_AGAIN); 358 if (status != SOFTBUS_OK) { 359 SoftBusFree(referenceContext); 360 CONN_LOGE(CONN_BLE, "post msg failed, connectionId=%{public}u, error=%{public}d", 361 connection->connectionId, status); 362 return false; 363 } 364 return true; 365 } 366 ConnBleUpdateConnectionRc(ConnBleConnection * connection,uint16_t challengeCode,int32_t delta)367 int32_t ConnBleUpdateConnectionRc(ConnBleConnection *connection, uint16_t challengeCode, int32_t delta) 368 { 369 CONN_CHECK_AND_RETURN_RET_LOGE(connection != NULL, SOFTBUS_INVALID_PARAM, CONN_BLE, "connection is null"); 370 if (NeedProccessOccupy(connection, delta, challengeCode, true, 0)) { 371 return SOFTBUS_OK; 372 } 373 int32_t status = SoftBusMutexLock(&connection->lock); 374 CONN_CHECK_AND_RETURN_RET_LOGW(status == SOFTBUS_OK, SOFTBUS_LOCK_ERR, CONN_BLE, 375 "Lock faild, err=%{public}d", status); 376 int32_t underlayerHandle = connection->underlayerHandle; 377 ConnBleFeatureBitSet featureBitSet = connection->featureBitSet; 378 connection->connectionRc += delta; 379 int32_t localRc = connection->connectionRc; 380 if (localRc <= 0) { 381 connection->state = BLE_CONNECTION_STATE_NEGOTIATION_CLOSING; 382 } else if (connection->state == BLE_CONNECTION_STATE_NEGOTIATION_CLOSING) { 383 ConnRemoveMsgFromLooper(&g_bleConnectionAsyncHandler, MSG_CONNECTION_WAIT_NEGOTIATION_CLOSING_TIMEOUT, 384 connection->connectionId, 0, NULL); 385 connection->state = BLE_CONNECTION_STATE_CONNECTED; 386 } 387 (void)SoftBusMutexUnlock(&connection->lock); 388 ConnEventExtra extra = { 389 .connRcDelta = delta, 390 .connRc = localRc, 391 .linkType = CONNECT_BLE, 392 .peerBleMac = connection->addr, 393 .connectionId = (int32_t)connection->connectionId, 394 .result = EVENT_STAGE_RESULT_OK 395 }; 396 CONN_EVENT(EVENT_SCENE_CONNECT, EVENT_STAGE_CONNECT_UPDATE_CONNECTION_RC, extra); 397 CONN_LOGI(CONN_BLE, "ble notify refrence, connId=%{public}u, handle=%{public}d, side=%{public}d, " 398 "delta=%{public}d, challenge=%{public}u, localRc=%{public}d", 399 connection->connectionId, underlayerHandle, connection->side, delta, challengeCode, localRc); 400 401 if (localRc <= 0) { 402 if ((featureBitSet & (1 << BLE_FEATURE_SUPPORT_REMOTE_DISCONNECT)) == 0) { 403 CONN_LOGW(CONN_BLE, "reference count <= 0 and peer not support negotiation disconnect by notify msg, " 404 "disconnect directly after 200 ms, connId=%{public}u, handle=%{public}d, featureBitSet=%{public}u", 405 connection->connectionId, underlayerHandle, featureBitSet); 406 ConnPostMsgToLooper(&g_bleConnectionAsyncHandler, MSG_CONNECTION_WAIT_NEGOTIATION_CLOSING_TIMEOUT, 407 connection->connectionId, 0, NULL, CLOSING_TIMEOUT_MILLIS); 408 return SOFTBUS_OK; 409 } 410 } 411 412 RcPackCtlMsgPara rcMsgPara = { 413 .delta = delta, 414 .localRc = localRc, 415 .challengeCode = challengeCode, 416 .connId = connection->connectionId, 417 .underlayerHandle = underlayerHandle, 418 }; 419 return ConnPackCtlMsgRcSendDeltaData(&rcMsgPara); 420 } 421 BleOnReferenceRequest(ConnBleConnection * connection,BleReferenceContext * referenceCount)422 static int32_t BleOnReferenceRequest(ConnBleConnection *connection, BleReferenceContext *referenceCount) 423 { 424 int32_t delta = referenceCount->delta; 425 int32_t peerRc = referenceCount->peerRc; 426 uint16_t challengeCode = referenceCount->challengeCode; 427 if (NeedProccessOccupy(connection, delta, challengeCode, false, peerRc)) { 428 return SOFTBUS_OK; 429 } 430 int32_t status = SoftBusMutexLock(&connection->lock); 431 if (status != SOFTBUS_OK) { 432 CONN_LOGE(CONN_BLE, "try to lock failed, connId=%{public}u, err=%{public}d", connection->connectionId, status); 433 return SOFTBUS_LOCK_ERR; 434 } 435 connection->connectionRc += delta; 436 int32_t localRc = connection->connectionRc; 437 CONN_LOGI(CONN_BLE, "ble received reference request, connId=%{public}u, delta=%{public}d, peerRef=%{public}d, " 438 "localRc=%{public}d, challenge=%{public}u", connection->connectionId, delta, peerRc, localRc, challengeCode); 439 if (peerRc > 0) { 440 if (connection->state == BLE_CONNECTION_STATE_NEGOTIATION_CLOSING) { 441 ConnRemoveMsgFromLooper(&g_bleConnectionAsyncHandler, MSG_CONNECTION_WAIT_NEGOTIATION_CLOSING_TIMEOUT, 442 connection->connectionId, 0, NULL); 443 connection->state = BLE_CONNECTION_STATE_EXCHANGED_BASIC_INFO; 444 g_connectionListener.onConnectionResume(connection->connectionId); 445 } 446 (void)SoftBusMutexUnlock(&connection->lock); 447 NotifyReusedConnected(connection->connectionId, challengeCode); 448 return SOFTBUS_OK; 449 } 450 if (localRc <= 0) { 451 connection->state = BLE_CONNECTION_STATE_CLOSING; 452 (void)SoftBusMutexUnlock(&connection->lock); 453 ConnBleDisconnectNow(connection, BLE_DISCONNECT_REASON_NEGOTIATION_NO_REFERENCE); 454 return SOFTBUS_OK; 455 } 456 (void)SoftBusMutexUnlock(&connection->lock); 457 458 RcPackCtlMsgPara rcMsgPara = { 459 .delta = 0, 460 .localRc = localRc, 461 .challengeCode = challengeCode, 462 .connId = connection->connectionId, 463 .underlayerHandle = connection->underlayerHandle, 464 }; 465 return ConnPackCtlMsgRcSendDeltaData(&rcMsgPara); 466 } 467 ConnBleOnReferenceRequest(ConnBleConnection * connection,const cJSON * json)468 int32_t ConnBleOnReferenceRequest(ConnBleConnection *connection, const cJSON *json) 469 { 470 CONN_CHECK_AND_RETURN_RET_LOGW(connection != NULL, SOFTBUS_INVALID_PARAM, CONN_BLE, "invalid param"); 471 int32_t delta = 0; 472 int32_t peerRc = 0; 473 uint16_t challengeCode = 0; 474 if (!GetJsonObjectSignedNumberItem(json, CTRL_MSG_KEY_DELTA, &delta) || 475 !GetJsonObjectSignedNumberItem(json, CTRL_MSG_KEY_REF_NUM, &peerRc)) { 476 CONN_LOGE(CONN_BLE, 477 "parse delta or reference number fields failed, connId=%{public}u, delta=%{public}d, peerRc=%{public}d", 478 connection->connectionId, delta, peerRc); 479 return SOFTBUS_PARSE_JSON_ERR; 480 } 481 if (!GetJsonObjectNumber16Item(json, CTRL_MSG_KEY_CHALLENGE, &challengeCode)) { 482 CONN_LOGW(CONN_BLE, "old version NOT have KEY_CHALLENGE field. connId=%{public}u", connection->connectionId); 483 } 484 485 BleReferenceContext referenceCount = { 486 .delta = delta, 487 .peerRc = peerRc, 488 .challengeCode = challengeCode, 489 }; 490 return BleOnReferenceRequest(connection, &referenceCount); 491 } 492 ConnBleUpdateConnectionPriority(ConnBleConnection * connection,ConnectBlePriority priority)493 int32_t ConnBleUpdateConnectionPriority(ConnBleConnection *connection, ConnectBlePriority priority) 494 { 495 CONN_CHECK_AND_RETURN_RET_LOGW(connection != NULL, SOFTBUS_INVALID_PARAM, CONN_BLE, 496 "ble connection update connection priority failed, invalid param, connection is null"); 497 if (connection->side == CONN_SIDE_SERVER) { 498 return SOFTBUS_FUNC_NOT_SUPPORT; 499 } 500 const BleUnifyInterface *interface = ConnBleGetUnifyInterface(connection->protocol); 501 CONN_CHECK_AND_RETURN_RET_LOGW(interface != NULL, SOFTBUS_CONN_BLE_INTERNAL_ERR, CONN_BLE, 502 "ble connection update connection priority failed, protocol not support"); 503 return interface->bleClientUpdatePriority(connection, priority); 504 } 505 ConnBleSend(ConnBleConnection * connection,const uint8_t * data,uint32_t dataLen,int32_t module)506 int32_t ConnBleSend(ConnBleConnection *connection, const uint8_t *data, uint32_t dataLen, int32_t module) 507 { 508 CONN_CHECK_AND_RETURN_RET_LOGW(connection != NULL, SOFTBUS_INVALID_PARAM, CONN_BLE, 509 "ble connection send data failed, invalid param, connection is null"); 510 CONN_CHECK_AND_RETURN_RET_LOGW(data != NULL, SOFTBUS_INVALID_PARAM, CONN_BLE, 511 "ble connection send data failed, invalid param, data is null"); 512 CONN_CHECK_AND_RETURN_RET_LOGW(dataLen != 0, SOFTBUS_INVALID_PARAM, CONN_BLE, 513 "ble connection send data failed, invalid param, data len is 0"); 514 const BleUnifyInterface *interface = ConnBleGetUnifyInterface(connection->protocol); 515 CONN_CHECK_AND_RETURN_RET_LOGW(interface != NULL, SOFTBUS_CONN_BLE_INTERNAL_ERR, CONN_BLE, 516 "ble connection send data failed, protocol not support"); 517 return connection->side == CONN_SIDE_SERVER ? 518 interface->bleServerSend(connection, data, dataLen, module) : 519 interface->bleClientSend(connection, data, dataLen, module); 520 } 521 ConnBleRefreshIdleTimeout(ConnBleConnection * connection)522 void ConnBleRefreshIdleTimeout(ConnBleConnection *connection) 523 { 524 ConnRemoveMsgFromLooper( 525 &g_bleConnectionAsyncHandler, MSG_CONNECTION_IDLE_DISCONNECT_TIMEOUT, connection->connectionId, 0, NULL); 526 ConnPostMsgToLooper(&g_bleConnectionAsyncHandler, MSG_CONNECTION_IDLE_DISCONNECT_TIMEOUT, connection->connectionId, 527 0, NULL, CONNECTION_IDLE_DISCONNECT_TIMEOUT_MILLIS); 528 } 529 ConnBleInnerComplementDeviceId(ConnBleConnection * connection)530 void ConnBleInnerComplementDeviceId(ConnBleConnection *connection) 531 { 532 if (strlen(connection->udid) != 0) { 533 CONN_LOGD(CONN_BLE, "udid already exist"); 534 return; 535 } 536 if (strlen(connection->networkId) == 0) { 537 CONN_LOGW(CONN_BLE, 538 "network id not exchange yet, connId=%{public}u, protocol=%{public}d", 539 connection->connectionId, connection->protocol); 540 return; 541 } 542 int32_t status = LnnGetRemoteStrInfo(connection->networkId, STRING_KEY_DEV_UDID, connection->udid, UDID_BUF_LEN); 543 CONN_LOGD(CONN_BLE, 544 "complementation ble connection device id, connId=%{public}u, protocol=%{public}d, status=%{public}d", 545 connection->connectionId, connection->protocol, status); 546 } 547 ConnBlePackCtrlMsgHeader(ConnPktHead * header,uint32_t dataLen)548 static void ConnBlePackCtrlMsgHeader(ConnPktHead *header, uint32_t dataLen) 549 { 550 static int64_t ctlMsgSeqGenerator = 0; 551 int64_t seq = ctlMsgSeqGenerator++; 552 553 header->magic = MAGIC_NUMBER; 554 header->module = MODULE_CONNECTION; 555 header->seq = seq; 556 header->flag = CONN_HIGH; 557 header->len = dataLen; 558 PackConnPktHead(header); 559 } 560 561 // CoC connection exchange 'networdId' as old udid field may disclosure of user privacy and be traced; 562 // GATT connection keep exchange 'udid' as keeping compatibility SendBasicInfo(ConnBleConnection * connection)563 static int32_t SendBasicInfo(ConnBleConnection *connection) 564 { 565 int32_t status = SOFTBUS_CONN_BLE_INTERNAL_ERR; 566 char devId[DEVID_BUFF_LEN] = { 0 }; 567 BleProtocolType protocol = connection->protocol; 568 ConnBleFeatureBitSet featureBitSet = connection->featureBitSet; 569 bool isSupportNetWorkIdExchange = (featureBitSet & 570 (1 << BLE_FEATURE_SUPPORT_SUPPORT_NETWORKID_BASICINFO_EXCAHNGE)) != 0; 571 if (protocol == BLE_COC || isSupportNetWorkIdExchange) { 572 status = LnnGetLocalStrInfo(STRING_KEY_NETWORKID, devId, DEVID_BUFF_LEN); 573 } else if (protocol == BLE_GATT) { 574 status = LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, devId, DEVID_BUFF_LEN); 575 } 576 if (status != SOFTBUS_OK) { 577 CONN_LOGE(CONN_BLE, "get devid from net ledger failed, connId=%{public}u, protocol=%{public}d, err=%{public}d", 578 connection->connectionId, connection->protocol, status); 579 return status; 580 } 581 582 int32_t deviceType = 0; 583 status = LnnGetLocalNumInfo(NUM_KEY_DEV_TYPE_ID, &deviceType); 584 if (status != SOFTBUS_OK) { 585 CONN_LOGE(CONN_BLE, 586 "get device type from net ledger failed, connId=%{public}u, err=%{public}d", 587 connection->connectionId, status); 588 return status; 589 } 590 591 cJSON *json = cJSON_CreateObject(); 592 if (json == NULL) { 593 CONN_LOGE(CONN_BLE, "create json object failed, connId=%{public}u", connection->connectionId); 594 return SOFTBUS_CREATE_JSON_ERR; 595 } 596 char *payload = NULL; 597 featureBitSet |= g_featureBitSet; 598 do { 599 if (!AddStringToJsonObject(json, BASIC_INFO_KEY_DEVID, devId) || 600 !AddNumberToJsonObject(json, BASIC_INFO_KEY_ROLE, connection->side) || 601 !AddNumberToJsonObject(json, BASIC_INFO_KEY_DEVTYPE, deviceType) || 602 !AddNumberToJsonObject(json, BASIC_INFO_KEY_FEATURE, featureBitSet)) { 603 CONN_LOGE(CONN_BLE, "add json info failed, connId=%{public}u", connection->connectionId); 604 status = SOFTBUS_CREATE_JSON_ERR; 605 break; 606 } 607 payload = cJSON_PrintUnformatted(json); 608 uint32_t payloadLen = strlen(payload); 609 uint32_t dataLen = NET_CTRL_MSG_TYPE_HEADER_SIZE + payloadLen + 1; 610 uint32_t bufLen = dataLen + (connection->protocol == BLE_COC ? sizeof(ConnPktHead) : 0); 611 uint8_t *buf = (uint8_t *)SoftBusCalloc(bufLen); 612 if (buf == NULL) { 613 CONN_LOGE(CONN_BLE, 614 "malloc buf failed, connId=%{public}u, bufLen=%{public}u", connection->connectionId, bufLen); 615 status = SOFTBUS_MALLOC_ERR; 616 break; 617 } 618 619 int32_t offset = 0; 620 if (connection->protocol == BLE_COC) { 621 ConnPktHead *header = (ConnPktHead *)buf; 622 ConnBlePackCtrlMsgHeader(header, dataLen); 623 offset += sizeof(ConnPktHead); 624 } 625 int32_t *netCtrlMsgHeader = (int32_t *)(buf + offset); 626 netCtrlMsgHeader[0] = NET_CTRL_MSG_TYPE_BASIC_INFO; 627 offset += NET_CTRL_MSG_TYPE_HEADER_SIZE; 628 if (memcpy_s(buf + offset, bufLen - offset, payload, payloadLen) != EOK) { 629 CONN_LOGE(CONN_BLE, 630 "memcpy_s buf failed, connId=%{public}u, bufLen=%{public}u, paylaodLen=%{public}u", 631 connection->connectionId, bufLen, payloadLen); 632 status = SOFTBUS_MEM_ERR; 633 SoftBusFree(buf); 634 break; 635 } 636 status = ConnBlePostBytesInner(connection->connectionId, buf, bufLen, 0, CONN_HIGH, MODULE_BLE_NET, 0, NULL); 637 CONN_LOGI(CONN_BLE, "ble send basic info, connId=%{public}u, side=%{public}s, status=%{public}d", 638 connection->connectionId, connection->side == CONN_SIDE_CLIENT ? "client" : "server", status); 639 if (status != SOFTBUS_OK) { 640 break; 641 } 642 } while (false); 643 cJSON_Delete(json); 644 if (payload != NULL) { 645 cJSON_free(payload); 646 } 647 ConnEventExtra extra = { 648 .connectionId = (int32_t)connection->connectionId, 649 .connRole = connection->side, 650 .linkType = CONNECT_BLE, 651 .peerBleMac = connection->addr, 652 .errcode = status, 653 .result = status == SOFTBUS_OK ? EVENT_STAGE_RESULT_OK : EVENT_STAGE_RESULT_FAILED 654 }; 655 CONN_EVENT(EVENT_SCENE_CONNECT, EVENT_STAGE_CONNECT_SEND_BASIC_INFO, extra); 656 return status; 657 } 658 ParsePeerBasicInfoInner(ConnBleConnection * connection,const uint8_t * data,uint32_t dataLen,BaseInfo * baseInfo)659 static int32_t ParsePeerBasicInfoInner(ConnBleConnection *connection, const uint8_t *data, 660 uint32_t dataLen, BaseInfo *baseInfo) 661 { 662 if (dataLen <= NET_CTRL_MSG_TYPE_HEADER_SIZE) { 663 CONN_LOGI(CONN_BLE, 664 "date len exceed, connId=%{public}u, dataLen=%{public}d", connection->connectionId, dataLen); 665 return SOFTBUS_INVALID_PARAM; 666 } 667 int offset = 0; 668 if (connection->protocol == BLE_COC) { 669 offset += sizeof(ConnPktHead); 670 } 671 int32_t *netCtrlMsgHeader = (int32_t *)(data + offset); 672 if (netCtrlMsgHeader[0] != NET_CTRL_MSG_TYPE_BASIC_INFO) { 673 CONN_LOGI(CONN_BLE, 674 "not basic info type, connId=%{public}u, type=%{public}d", connection->connectionId, netCtrlMsgHeader[0]); 675 return SOFTBUS_CONN_BLE_INTERNAL_ERR; 676 } 677 offset += NET_CTRL_MSG_TYPE_HEADER_SIZE; 678 cJSON *json = cJSON_ParseWithLength((char *)(data + offset), dataLen - offset); 679 if (json == NULL) { 680 CONN_LOGI(CONN_BLE, "parse json failed, connId=%{public}u", connection->connectionId); 681 return SOFTBUS_PARSE_JSON_ERR; 682 } 683 // mandatory fields 684 if (!GetJsonObjectStringItem(json, BASIC_INFO_KEY_DEVID, baseInfo->devId, DEVID_BUFF_LEN) || 685 !GetJsonObjectNumberItem(json, BASIC_INFO_KEY_ROLE, &(baseInfo->type))) { 686 cJSON_Delete(json); 687 CONN_LOGE(CONN_BLE, "basic info field not exist, connId=%{public}u", connection->connectionId); 688 return SOFTBUS_CONN_BLE_INTERNAL_ERR; 689 } 690 // optional field 691 if (!GetJsonObjectNumberItem(json, BASIC_INFO_KEY_DEVTYPE, &(baseInfo->deviceType))) { 692 CONN_LOGE(CONN_BLE, "ble parse basic info warning, 'devType' is not exist, connId=%{public}u", 693 connection->connectionId); 694 // fall through 695 } 696 if (!GetJsonObjectNumberItem(json, BASIC_INFO_KEY_FEATURE, &(baseInfo->feature))) { 697 CONN_LOGE(CONN_BLE, "ble parse basic info warning, 'FEATURE_SUPPORT' is not exist, connId=%{public}u", 698 connection->connectionId); 699 // fall through 700 } 701 cJSON_Delete(json); 702 return SOFTBUS_OK; 703 } 704 ParseBasicInfo(ConnBleConnection * connection,const uint8_t * data,uint32_t dataLen)705 static int32_t ParseBasicInfo(ConnBleConnection *connection, const uint8_t *data, uint32_t dataLen) 706 { 707 BaseInfo baseInfo = {0}; 708 int32_t ret = ParsePeerBasicInfoInner(connection, data, dataLen, &baseInfo); 709 CONN_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, CONN_BLE, "ble parse data failed, error=%{public}d", ret); 710 bool isSupportNetWorkIdExchange = ((uint32_t)(baseInfo.feature) & 711 (1 << BLE_FEATURE_SUPPORT_SUPPORT_NETWORKID_BASICINFO_EXCAHNGE)) != 0; 712 ret = SoftBusMutexLock(&connection->lock); 713 CONN_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, SOFTBUS_LOCK_ERR, CONN_BLE, 714 "try to lock failed, connId=%{public}u, err=%{public}d", connection->connectionId, ret); 715 716 if (connection->protocol == BLE_COC || isSupportNetWorkIdExchange) { 717 if (memcpy_s(connection->networkId, NETWORK_ID_BUF_LEN, baseInfo.devId, DEVID_BUFF_LEN) != EOK) { 718 (void)SoftBusMutexUnlock(&connection->lock); 719 CONN_LOGE(CONN_BLE, "memcpy_s network id failed, connId=%{public}u", connection->connectionId); 720 return SOFTBUS_MEM_ERR; 721 } 722 ConnBleInnerComplementDeviceId(connection); 723 } else if (connection->protocol == BLE_GATT) { 724 if (memcpy_s(connection->udid, UDID_BUF_LEN, baseInfo.devId, DEVID_BUFF_LEN) != EOK) { 725 (void)SoftBusMutexUnlock(&connection->lock); 726 CONN_LOGE(CONN_BLE, "memcpy_s udid failed, connId=%{public}u", connection->connectionId); 727 return SOFTBUS_MEM_ERR; 728 } 729 } 730 connection->featureBitSet = (ConnBleFeatureBitSet)(baseInfo.feature); 731 connection->state = BLE_CONNECTION_STATE_EXCHANGED_BASIC_INFO; 732 (void)SoftBusMutexUnlock(&connection->lock); 733 734 // revert current side role is peer side role 735 int32_t expectedPeerType = connection->side == CONN_SIDE_CLIENT ? 2 : 1; 736 if (expectedPeerType != baseInfo.type) { 737 CONN_LOGW(CONN_BLE, "parse basic info, the role of connection is mismatch, " 738 "expectedPeerType=%{public}d, actualPeerType=%{public}d", expectedPeerType, baseInfo.type); 739 } 740 ConnEventExtra extra = { 741 .connectionId = (int32_t)connection->connectionId, 742 .connRole = connection->side, 743 .supportFeature = baseInfo.feature, 744 .linkType = CONNECT_BLE, 745 .peerBleMac = connection->addr, 746 .result = EVENT_STAGE_RESULT_OK 747 }; 748 char devType[DEVICE_TYPE_MAX_SIZE + 1] = {0}; 749 if (snprintf_s(devType, DEVICE_TYPE_MAX_SIZE + 1, DEVICE_TYPE_MAX_SIZE, "%03X", baseInfo.deviceType) >= 0) { 750 extra.peerDeviceType = devType; 751 } 752 CONN_EVENT(EVENT_SCENE_CONNECT, EVENT_STAGE_CONNECT_PARSE_BASIC_INFO, extra); 753 CONN_LOGI(CONN_BLE, "ble parse basic info, connId=%{public}u, side=%{public}s, deviceType=%{public}d, " 754 "supportFeature=%{public}u", connection->connectionId, 755 connection->side == CONN_SIDE_CLIENT ? "client" : "server", baseInfo.deviceType, baseInfo.feature); 756 return SOFTBUS_OK; 757 } 758 BleOnClientConnected(uint32_t connectionId)759 void BleOnClientConnected(uint32_t connectionId) 760 { 761 ConnBleConnection *connection = ConnBleGetConnectionById(connectionId); 762 CONN_CHECK_AND_RETURN_LOGW(connection != NULL, CONN_BLE, "connection not exist, connId=%{public}u", connectionId); 763 int32_t status = SOFTBUS_OK; 764 do { 765 status = SoftBusMutexLock(&connection->lock); 766 if (status != SOFTBUS_OK) { 767 CONN_LOGE(CONN_BLE, "try to lock failed, connId=%{public}u, err=%{public}d", connectionId, status); 768 break; 769 } 770 connection->state = BLE_CONNECTION_STATE_EXCHANGING_BASIC_INFO; 771 (void)SoftBusMutexUnlock(&connection->lock); 772 status = ConnPostMsgToLooper(&g_bleConnectionAsyncHandler, MSG_CONNECTION_EXCHANGE_BASIC_INFO_TIMEOUT, 773 connectionId, 0, NULL, BASIC_INFO_EXCHANGE_TIMEOUT); 774 if (status != SOFTBUS_OK) { 775 CONN_LOGE(CONN_BLE, 776 "post basic info exchange timeout event failed, connId=%{public}u, err=%{public}d", 777 connectionId, status); 778 break; 779 } 780 status = SendBasicInfo(connection); 781 if (status != SOFTBUS_OK) { 782 CONN_LOGE(CONN_BLE, 783 "send basic info message failed, connId=%{public}u, err=%{public}d", connectionId, status); 784 break; 785 } 786 } while (false); 787 if (status != SOFTBUS_OK) { 788 g_connectionListener.onConnectFailed(connection->connectionId, status); 789 } 790 ConnBleReturnConnection(&connection); 791 } 792 BleOnClientFailed(uint32_t connectionId,int32_t error)793 void BleOnClientFailed(uint32_t connectionId, int32_t error) 794 { 795 ConnBleConnection *connection = ConnBleGetConnectionById(connectionId); 796 CONN_CHECK_AND_RETURN_LOGW(connection != NULL, CONN_BLE, "connection not exist, connId=%{public}u", connectionId); 797 if (connection->protocol == BLE_GATT) { 798 g_connectionListener.onConnectFailed(connectionId, error); 799 ConnBleReturnConnection(&connection); 800 return; 801 } 802 803 int32_t status = SoftBusMutexLock(&connection->connectStatus->lock); 804 if (status != SOFTBUS_OK) { 805 CONN_LOGE(CONN_BLE, "lock failed, connId=%{public}u", connectionId); 806 ConnBleReturnConnection(&connection); 807 return; 808 } 809 BleUnderlayerStatus *it = NULL; 810 LIST_FOR_EACH_ENTRY(it, &connection->connectStatus->list, BleUnderlayerStatus, node) { 811 // to find the last error 812 if (it->result != 0) { 813 error = it->result; 814 } 815 } 816 (void)SoftBusMutexUnlock(&connection->connectStatus->lock); 817 ConnBleReturnConnection(&connection); 818 g_connectionListener.onConnectFailed(connectionId, error); 819 } 820 HandleBasicInfo(ConnBleConnection * connection,uint8_t * data,uint32_t dataLen,const BleUnifyInterface * interface)821 static void HandleBasicInfo(ConnBleConnection *connection, uint8_t *data, uint32_t dataLen, 822 const BleUnifyInterface *interface) 823 { 824 int32_t ret = ParseBasicInfo(connection, data, dataLen); 825 SoftBusFree(data); 826 if (ret != SOFTBUS_OK) { 827 CONN_LOGE(CONN_BLE, "parse basic info failed, connId=%{public}u, side=%{public}d, handle=%{public}d, " 828 "err=%{public}d", connection->connectionId, connection->side, connection->underlayerHandle, ret); 829 if (connection->side == CONN_SIDE_CLIENT) { 830 g_connectionListener.onConnectFailed(connection->connectionId, ret); 831 } else { 832 interface->bleServerDisconnect(connection); 833 } 834 return; 835 } 836 ConnRemoveMsgFromLooper( 837 &g_bleConnectionAsyncHandler, MSG_CONNECTION_EXCHANGE_BASIC_INFO_TIMEOUT, connection->connectionId, 0, NULL); 838 if (connection->side == CONN_SIDE_SERVER) { 839 ret = SendBasicInfo(connection); 840 if (ret != SOFTBUS_OK) { 841 CONN_LOGE(CONN_BLE, "send server side basic info failed, connId=%{public}u, handle=%{public}d, " 842 "err=%{public}d", connection->connectionId, connection->underlayerHandle, ret); 843 interface->bleServerDisconnect(connection); 844 return; 845 } 846 ret = interface->bleServerConnect(connection); 847 CONN_LOGI(CONN_BLE, "server side finish exchange basic info, connId=%{public}u, handle=%{public}d, " 848 "serverConnectStatus=%{public}d", connection->connectionId, connection->underlayerHandle, ret); 849 ConnBleRefreshIdleTimeout(connection); 850 g_connectionListener.onServerAccepted(connection->connectionId); 851 } else { 852 CONN_LOGI(CONN_BLE, "client side finish exchange basic info, connId=%{public}u, handle=%{public}d", 853 connection->connectionId, connection->underlayerHandle); 854 ConnBleRefreshIdleTimeout(connection); 855 g_connectionListener.onConnected(connection->connectionId); 856 } 857 } 858 859 // Memory Management Conventions: MUST free data if dispatch process is intercepted, 860 // otherwise it is responsibity of uplayer to free data BleOnDataReceived(uint32_t connectionId,bool isConnCharacteristic,uint8_t * data,uint32_t dataLen)861 void BleOnDataReceived(uint32_t connectionId, bool isConnCharacteristic, uint8_t *data, uint32_t dataLen) 862 { 863 ConnBleConnection *connection = ConnBleGetConnectionById(connectionId); 864 if (connection == NULL) { 865 CONN_LOGE(CONN_BLE, "connection not exist, connId=%{public}u", connectionId); 866 SoftBusFree(data); 867 return; 868 } 869 const BleUnifyInterface *interface = ConnBleGetUnifyInterface(connection->protocol); 870 if (interface == NULL) { 871 CONN_LOGE(CONN_BLE, "protocol not support, connId=%{public}u", connectionId); 872 SoftBusFree(data); 873 return; 874 } 875 int32_t status = SOFTBUS_OK; 876 do { 877 if (isConnCharacteristic) { 878 ConnBleRefreshIdleTimeout(connection); 879 g_connectionListener.onDataReceived(connectionId, isConnCharacteristic, data, dataLen); 880 break; 881 } 882 883 status = SoftBusMutexLock(&connection->lock); 884 if (status != SOFTBUS_OK) { 885 SoftBusFree(data); 886 // NOT notify client 'onConnectFailed' or server disconnect as it can not get state safely here, 887 // connection will fail after basic info change timeout, all resouces will cleanup in timeout handle method 888 CONN_LOGE(CONN_BLE, "try to lock failed, connId=%{public}u, err=%{public}d", connectionId, status); 889 break; 890 } 891 enum ConnBleConnectionState state = connection->state; 892 (void)SoftBusMutexUnlock(&connection->lock); 893 if (state != BLE_CONNECTION_STATE_EXCHANGING_BASIC_INFO) { 894 ConnBleRefreshIdleTimeout(connection); 895 isConnCharacteristic = (connection->protocol == BLE_COC) ? true : isConnCharacteristic; 896 g_connectionListener.onDataReceived(connectionId, isConnCharacteristic, data, dataLen); 897 break; 898 } 899 900 HandleBasicInfo(connection, data, dataLen, interface); 901 } while (false); 902 ConnBleReturnConnection(&connection); 903 } 904 BleOnConnectionClosed(uint32_t connectionId,int32_t status)905 void BleOnConnectionClosed(uint32_t connectionId, int32_t status) 906 { 907 ConnRemoveMsgFromLooper( 908 &g_bleConnectionAsyncHandler, MSG_CONNECTION_IDLE_DISCONNECT_TIMEOUT, connectionId, 0, NULL); 909 g_connectionListener.onConnectionClosed(connectionId, status); 910 } 911 BleOnServerStarted(BleProtocolType protocol,int32_t status)912 void BleOnServerStarted(BleProtocolType protocol, int32_t status) 913 { 914 CONN_LOGD(CONN_BLE, "receive ble server started event, status=%{public}d", status); 915 916 CONN_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_serverCoordination.lock) == SOFTBUS_OK, CONN_BLE, 917 "on server start event handle failed, try to lock failed"); 918 g_serverCoordination.status[protocol] = status; 919 g_serverCoordination.actual = 920 ((g_serverCoordination.status[BLE_GATT] == SOFTBUS_OK) && (g_serverCoordination.status[BLE_COC] == SOFTBUS_OK ? 921 BLE_SERVER_STATE_STARTED : BLE_SERVER_STATE_STOPPED)); 922 if (g_serverCoordination.expect != g_serverCoordination.actual) { 923 ConnPostMsgToLooper(&g_bleConnectionAsyncHandler, MSG_CONNECTION_RETRY_SERVER_STATE_CONSISTENT, 0, 0, NULL, 924 RETRY_SERVER_STATE_CONSISTENT_MILLIS); 925 } 926 (void)SoftBusMutexUnlock(&g_serverCoordination.lock); 927 } 928 BleOnServerClosed(BleProtocolType protocol,int32_t status)929 void BleOnServerClosed(BleProtocolType protocol, int32_t status) 930 { 931 CONN_LOGD(CONN_BLE, "receive ble server closed event, status=%{public}d", status); 932 933 CONN_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_serverCoordination.lock) == SOFTBUS_OK, CONN_BLE, 934 "on server close event handle failed, try to lock failed"); 935 g_serverCoordination.status[protocol] = status; 936 g_serverCoordination.actual = 937 (g_serverCoordination.status[BLE_GATT] == SOFTBUS_OK && g_serverCoordination.status[BLE_COC] == SOFTBUS_OK ? 938 BLE_SERVER_STATE_STOPPED : BLE_SERVER_STATE_STARTED); 939 if (g_serverCoordination.expect != g_serverCoordination.actual) { 940 ConnPostMsgToLooper(&g_bleConnectionAsyncHandler, MSG_CONNECTION_RETRY_SERVER_STATE_CONSISTENT, 0, 0, NULL, 941 RETRY_SERVER_STATE_CONSISTENT_MILLIS); 942 } 943 (void)SoftBusMutexUnlock(&g_serverCoordination.lock); 944 } 945 BleOnServerAccepted(uint32_t connectionId)946 void BleOnServerAccepted(uint32_t connectionId) 947 { 948 ConnBleConnection *connection = ConnBleGetConnectionById(connectionId); 949 CONN_CHECK_AND_RETURN_LOGW(connection != NULL, CONN_BLE, "connection not exist, connId=%{public}u", connectionId); 950 const BleUnifyInterface *interface = ConnBleGetUnifyInterface(connection->protocol); 951 CONN_CHECK_AND_RETURN_LOGW(interface != NULL, CONN_BLE, 952 "ble server accepted failed, interface not support, connId=%{public}u", connectionId); 953 int32_t status = SOFTBUS_OK; 954 do { 955 status = SoftBusMutexLock(&connection->lock); 956 if (status != SOFTBUS_OK) { 957 CONN_LOGE(CONN_BLE, "try to lock failed, connId=%{public}u, err=%{public}d", connectionId, status); 958 break; 959 } 960 connection->state = BLE_CONNECTION_STATE_EXCHANGING_BASIC_INFO; 961 (void)SoftBusMutexUnlock(&connection->lock); 962 status = ConnPostMsgToLooper(&g_bleConnectionAsyncHandler, MSG_CONNECTION_EXCHANGE_BASIC_INFO_TIMEOUT, 963 connectionId, 0, NULL, BASIC_INFO_EXCHANGE_TIMEOUT); 964 if (status != SOFTBUS_OK) { 965 CONN_LOGE(CONN_BLE, 966 "post basic info exchange timeout event failed, connId=%{public}u, err=%{public}d", 967 connectionId, status); 968 break; 969 } 970 } while (false); 971 if (status != SOFTBUS_OK) { 972 interface->bleServerDisconnect(connection); 973 } 974 ConnBleReturnConnection(&connection); 975 } 976 DoRetryAction(enum BleServerState expect)977 static int32_t DoRetryAction(enum BleServerState expect) 978 { 979 int32_t statusGatt = SOFTBUS_OK; 980 int32_t statusCoc = SOFTBUS_OK; 981 if (g_serverCoordination.status[BLE_GATT] != SOFTBUS_OK) { 982 const BleUnifyInterface *interface = ConnBleGetUnifyInterface(BLE_GATT); 983 if (interface != NULL) { 984 statusGatt = (expect == BLE_SERVER_STATE_STARTED) ? interface->bleServerStartService() : 985 interface->bleServerStopService(); 986 } 987 } 988 989 if (g_serverCoordination.status[BLE_COC] != SOFTBUS_OK) { 990 const BleUnifyInterface *interface = ConnBleGetUnifyInterface(BLE_COC); 991 if (interface != NULL) { 992 statusCoc = (expect == BLE_SERVER_STATE_STARTED) ? interface->bleServerStartService() : 993 interface->bleServerStopService(); 994 } 995 } 996 997 return (statusGatt != SOFTBUS_OK || statusCoc != SOFTBUS_OK) ? SOFTBUS_CONN_BLE_CHECK_STATUS_ERR : SOFTBUS_OK; 998 } 999 ConnBleOccupy(ConnBleConnection * connection)1000 void ConnBleOccupy(ConnBleConnection *connection) 1001 { 1002 CONN_CHECK_AND_RETURN_LOGE(connection != NULL, CONN_BLE, "conn is NULL"); 1003 ConnRemoveMsgFromLooper( 1004 &g_bleConnectionAsyncHandler, MSG_CONNECTION_OCCUPY_RELEASE, connection->connectionId, 0, NULL); 1005 int32_t ret = ConnPostMsgToLooper(&g_bleConnectionAsyncHandler, 1006 MSG_CONNECTION_OCCUPY_RELEASE, connection->connectionId, 0, NULL, WAIT_TIMEOUT_OCCUPY); 1007 CONN_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, CONN_BLE, "post msg failed, connId=%{public}u, err=%{public}d", 1008 connection->connectionId, ret); 1009 CONN_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&connection->lock) == SOFTBUS_OK, CONN_BLE, 1010 "lock failed, connId=%{public}u", connection->connectionId); 1011 connection->isOccupied = true; 1012 (void)SoftBusMutexUnlock(&connection->lock); 1013 } 1014 RetryServerStatConsistentHandler(void)1015 static void RetryServerStatConsistentHandler(void) 1016 { 1017 CONN_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_serverCoordination.lock) == SOFTBUS_OK, CONN_BLE, 1018 "retry server state consistent msg handle, try to lock failed"); 1019 enum BleServerState expect = g_serverCoordination.expect; 1020 enum BleServerState actual = g_serverCoordination.actual; 1021 (void)SoftBusMutexUnlock(&g_serverCoordination.lock); 1022 if (expect == actual) { 1023 // consistent reached 1024 return; 1025 } 1026 if (actual == BLE_SERVER_STATE_STARTING || actual == BLE_SERVER_STATE_STOPPING) { 1027 // action on the fly, try later 1028 ConnPostMsgToLooper(&g_bleConnectionAsyncHandler, MSG_CONNECTION_RETRY_SERVER_STATE_CONSISTENT, 0, 0, NULL, 1029 RETRY_SERVER_STATE_CONSISTENT_MILLIS); 1030 return; 1031 } 1032 int32_t status = DoRetryAction(expect); 1033 if (status != SOFTBUS_OK) { 1034 ConnPostMsgToLooper(&g_bleConnectionAsyncHandler, MSG_CONNECTION_RETRY_SERVER_STATE_CONSISTENT, 0, 0, NULL, 1035 RETRY_SERVER_STATE_CONSISTENT_MILLIS); 1036 return; 1037 } 1038 CONN_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_serverCoordination.lock) == SOFTBUS_OK, CONN_BLE, 1039 "retry server state consistent msg handle, try to lock failed"); 1040 g_serverCoordination.actual = 1041 (expect == BLE_SERVER_STATE_STARTED ? BLE_SERVER_STATE_STARTING : BLE_SERVER_STATE_STOPPING); 1042 (void)SoftBusMutexUnlock(&g_serverCoordination.lock); 1043 } 1044 BasicInfoExchangeTimeoutHandler(uint32_t connectionId)1045 static void BasicInfoExchangeTimeoutHandler(uint32_t connectionId) 1046 { 1047 ConnBleConnection *connection = ConnBleGetConnectionById(connectionId); 1048 CONN_CHECK_AND_RETURN_LOGW(connection != NULL, CONN_BLE, 1049 "ble basic info exchange timeout handle failed, connection not exist, connId=%{public}u", connectionId); 1050 const BleUnifyInterface *interface = ConnBleGetUnifyInterface(connection->protocol); 1051 CONN_CHECK_AND_RETURN_LOGW(interface != NULL, CONN_BLE, 1052 "ble basic info exchange timeout handle failed, protocol not support, connId=%{public}u", connectionId); 1053 CONN_LOGW(CONN_BLE, "ble basic info exchange timeout, connId=%{public}u, side=%{public}s", connectionId, 1054 connection->side == CONN_SIDE_CLIENT ? "client" : "server"); 1055 if (connection->side == CONN_SIDE_CLIENT) { 1056 g_connectionListener.onConnectFailed(connectionId, SOFTBUS_CONN_BLE_EXCHANGE_BASIC_INFO_TIMEOUT_ERR); 1057 } else { 1058 interface->bleServerDisconnect(connection); 1059 } 1060 ConnBleReturnConnection(&connection); 1061 } 1062 WaitNegotiationClosingTimeoutHandler(uint32_t connectionId)1063 static void WaitNegotiationClosingTimeoutHandler(uint32_t connectionId) 1064 { 1065 ConnBleConnection *connection = ConnBleGetConnectionById(connectionId); 1066 CONN_CHECK_AND_RETURN_LOGW(connection != NULL, CONN_BLE, 1067 "ble wait negotiation closing timeout handler failed: connection not exist, connId=%{public}u", connectionId); 1068 int32_t status = SoftBusMutexLock(&connection->lock); 1069 if (status != SOFTBUS_OK) { 1070 CONN_LOGE(CONN_BLE, "try to lock failed, connId=%{public}u", connectionId); 1071 ConnBleReturnConnection(&connection); 1072 return; 1073 } 1074 enum ConnBleConnectionState state = connection->state; 1075 (void)SoftBusMutexUnlock(&connection->lock); 1076 CONN_LOGW(CONN_BLE, 1077 "ble wait negotiation closing timeout, connId=%{public}u, state=%{public}d", connectionId, state); 1078 if (state == BLE_CONNECTION_STATE_NEGOTIATION_CLOSING) { 1079 ConnBleDisconnectNow(connection, BLE_DISCONNECT_REASON_NEGOTIATION_WAIT_TIMEOUT); 1080 } 1081 ConnBleReturnConnection(&connection); 1082 } 1083 ConnectionIdleDisconnectTimeoutHandler(uint32_t connectionId)1084 static void ConnectionIdleDisconnectTimeoutHandler(uint32_t connectionId) 1085 { 1086 ConnBleConnection *connection = ConnBleGetConnectionById(connectionId); 1087 CONN_CHECK_AND_RETURN_LOGW(connection != NULL, CONN_BLE, 1088 "connection idle disconnect timeout handler failed: connection not exist, connId=%{public}u", connectionId); 1089 CONN_LOGW(CONN_BLE, 1090 "connection idle disconnect timeout handler, connection idle exceed forgot call " 1091 "disconnect? disconnect now, timeoutMillis=%{public}ums, connId=%{public}u", 1092 CONNECTION_IDLE_DISCONNECT_TIMEOUT_MILLIS, connectionId); 1093 ConnBleDisconnectNow(connection, BLE_DISCONNECT_REASON_IDLE_WAIT_TIMEOUT); 1094 ConnBleReturnConnection(&connection); 1095 } 1096 BleOnOccupyRelease(uint32_t connectionId)1097 static void BleOnOccupyRelease(uint32_t connectionId) 1098 { 1099 ConnBleConnection *connection = ConnBleGetConnectionById(connectionId); 1100 CONN_CHECK_AND_RETURN_LOGE(connection != NULL, CONN_BLE, "conn not exist, id=%{public}u", connectionId); 1101 int32_t status = SoftBusMutexLock(&connection->lock); 1102 if (status != SOFTBUS_OK) { 1103 CONN_LOGE(CONN_BLE, "lock failed, connectionId=%{public}u, error=%{public}d", connectionId, status); 1104 ConnBleReturnConnection(&connection); 1105 return; 1106 } 1107 connection->isOccupied = false; 1108 (void)SoftBusMutexUnlock(&connection->lock); 1109 ConnBleReturnConnection(&connection); 1110 } 1111 BleRetryUpdateConnectionRc(uint32_t connectionId,BleReferenceContext * referenceContext)1112 static void BleRetryUpdateConnectionRc(uint32_t connectionId, BleReferenceContext *referenceContext) 1113 { 1114 CONN_CHECK_AND_RETURN_LOGE(referenceContext != NULL, CONN_BLE, "referenceContext is null"); 1115 ConnBleConnection *connection = ConnBleGetConnectionById(connectionId); 1116 CONN_CHECK_AND_RETURN_LOGE(connection != NULL, CONN_BLE, "conn not exist, id=%{public}u", connectionId); 1117 if (referenceContext->isActiveUpdateLocalRc) { 1118 ConnBleUpdateConnectionRc(connection, referenceContext->challengeCode, referenceContext->delta); 1119 } else { 1120 BleOnReferenceRequest(connection, referenceContext); 1121 } 1122 ConnBleReturnConnection(&connection); 1123 } 1124 BleConnectionMsgHandler(SoftBusMessage * msg)1125 static void BleConnectionMsgHandler(SoftBusMessage *msg) 1126 { 1127 CONN_LOGI(CONN_BLE, "ble connection looper receive msg, msg=%{public}d", msg->what); 1128 switch (msg->what) { 1129 case MSG_CONNECTION_RETRY_SERVER_STATE_CONSISTENT: 1130 RetryServerStatConsistentHandler(); 1131 break; 1132 case MSG_CONNECTION_EXCHANGE_BASIC_INFO_TIMEOUT: 1133 BasicInfoExchangeTimeoutHandler((uint32_t)msg->arg1); 1134 break; 1135 case MSG_CONNECTION_WAIT_NEGOTIATION_CLOSING_TIMEOUT: 1136 WaitNegotiationClosingTimeoutHandler((uint32_t)msg->arg1); 1137 break; 1138 case MSG_CONNECTION_IDLE_DISCONNECT_TIMEOUT: 1139 ConnectionIdleDisconnectTimeoutHandler((uint32_t)msg->arg1); 1140 break; 1141 case MSG_CONNECTION_OCCUPY_RELEASE: 1142 BleOnOccupyRelease((uint32_t)msg->arg1); 1143 break; 1144 case MSG_CONNECTION_UPDATE_REFRENCE: 1145 BleRetryUpdateConnectionRc((uint32_t)msg->arg1, (BleReferenceContext *)msg->obj); 1146 break; 1147 default: 1148 CONN_LOGW(CONN_BLE, 1149 "ATTENTION, ble conn looper receive unexpected msg, just ignore, FIX it quickly. what=%{public}d", 1150 msg->what); 1151 break; 1152 } 1153 } 1154 BleCompareConnectionLooperEventFunc(const SoftBusMessage * msg,void * args)1155 static int BleCompareConnectionLooperEventFunc(const SoftBusMessage *msg, void *args) 1156 { 1157 SoftBusMessage *ctx = (SoftBusMessage *)args; 1158 if (msg->what != ctx->what) { 1159 return COMPARE_FAILED; 1160 } 1161 switch (ctx->what) { 1162 case MSG_CONNECTION_EXCHANGE_BASIC_INFO_TIMEOUT: 1163 case MSG_CONNECTION_WAIT_NEGOTIATION_CLOSING_TIMEOUT: 1164 case MSG_CONNECTION_IDLE_DISCONNECT_TIMEOUT: 1165 case MSG_CONNECTION_UPDATE_REFRENCE: 1166 case MSG_CONNECTION_OCCUPY_RELEASE: { 1167 if (msg->arg1 == ctx->arg1) { 1168 return COMPARE_SUCCESS; 1169 } 1170 return COMPARE_FAILED; 1171 } 1172 default: 1173 break; 1174 } 1175 if (ctx->arg1 != 0 || ctx->arg2 != 0 || ctx->obj != NULL) { 1176 CONN_LOGE(CONN_BLE, "there is compare context value not use, forgot implement? " 1177 "compare failed to avoid fault silence, what=%{public}d, arg1=%{public}" PRIu64 1178 ", arg2=%{public}" PRIu64 ", objIsNull=%{public}d", 1179 ctx->what, ctx->arg1, ctx->arg2, ctx->obj == NULL); 1180 return COMPARE_FAILED; 1181 } 1182 return COMPARE_SUCCESS; 1183 } 1184 CheckBleInitConnectionPara(SoftBusLooper * looper,ConnBleConnectionEventListener * listener)1185 static int32_t CheckBleInitConnectionPara(SoftBusLooper *looper, ConnBleConnectionEventListener *listener) 1186 { 1187 CONN_CHECK_AND_RETURN_RET_LOGW(looper != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT, 1188 "init ble connection failed: invalid param, looper is null"); 1189 CONN_CHECK_AND_RETURN_RET_LOGW(listener != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT, 1190 "init ble connection failed: invalid param, listener is null"); 1191 CONN_CHECK_AND_RETURN_RET_LOGW(listener->onServerAccepted != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT, 1192 "init ble connection failed: invalid param, listener onServerAccepted is null"); 1193 CONN_CHECK_AND_RETURN_RET_LOGW(listener->onConnected != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT, 1194 "init ble connection failed: invalid param, listener onConnected is null"); 1195 CONN_CHECK_AND_RETURN_RET_LOGW(listener->onConnectFailed != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT, 1196 "init ble connection failed: invalid param, listener onConnectFailed is null"); 1197 CONN_CHECK_AND_RETURN_RET_LOGW(listener->onDataReceived != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT, 1198 "init ble connection failed: invalid param, listener onDataReceived is null"); 1199 CONN_CHECK_AND_RETURN_RET_LOGW(listener->onConnectionClosed != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT, 1200 "init ble connection failed: invalid param, listener onConnectionClosed is null"); 1201 CONN_CHECK_AND_RETURN_RET_LOGW(listener->onConnectionResume != NULL, SOFTBUS_INVALID_PARAM, CONN_INIT, 1202 "init ble connection failed: invalid param, listener onConnectionResume is null"); 1203 return SOFTBUS_OK; 1204 } 1205 ConnBleInitConnectionMudule(SoftBusLooper * looper,ConnBleConnectionEventListener * listener)1206 int32_t ConnBleInitConnectionMudule(SoftBusLooper *looper, ConnBleConnectionEventListener *listener) 1207 { 1208 int32_t ret = CheckBleInitConnectionPara(looper, listener); 1209 CONN_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, CONN_INIT, "ConnServerPartInit init failed."); 1210 ConnBleClientEventListener clientEventListener = { 1211 .onClientConnected = BleOnClientConnected, 1212 .onClientFailed = BleOnClientFailed, 1213 .onClientDataReceived = BleOnDataReceived, 1214 .onClientConnectionClosed = BleOnConnectionClosed, 1215 }; 1216 ConnBleServerEventListener serverEventListener = { 1217 .onServerStarted = BleOnServerStarted, 1218 .onServerClosed = BleOnServerClosed, 1219 .onServerAccepted = BleOnServerAccepted, 1220 .onServerDataReceived = BleOnDataReceived, 1221 .onServerConnectionClosed = BleOnConnectionClosed, 1222 }; 1223 ret = SOFTBUS_CONN_BLE_INTERNAL_ERR; 1224 const BleUnifyInterface *interface; 1225 for (int i = BLE_GATT; i < BLE_PROTOCOL_MAX; i++) { 1226 interface = ConnBleGetUnifyInterface(i); 1227 if (interface == NULL) { 1228 continue; 1229 } 1230 ret = interface->bleClientInitModule(looper, &clientEventListener); 1231 CONN_CHECK_AND_RETURN_RET_LOGW(ret == SOFTBUS_OK, ret, CONN_INIT, 1232 "init ble connection failed: init ble client failed, i=%{public}d, err=%{public}d", i, ret); 1233 ret = interface->bleServerInitModule(looper, &serverEventListener); 1234 CONN_CHECK_AND_RETURN_RET_LOGW(ret == SOFTBUS_OK, ret, CONN_INIT, 1235 "init ble connection failed: init ble server failed, i=%{public}d, err=%{public}d", i, ret); 1236 } 1237 ret = SoftBusMutexInit(&g_serverCoordination.lock, NULL); 1238 CONN_CHECK_AND_RETURN_RET_LOGW(ret == SOFTBUS_OK, ret, CONN_INIT, 1239 "init ble connection failed: init server coordination lock failed, err=%{public}d", ret); 1240 g_bleConnectionAsyncHandler.handler.looper = looper; 1241 g_connectionListener = *listener; 1242 return SOFTBUS_OK; 1243 } 1244