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