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