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