1 /*
2  * Copyright (c) 2021 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 #include "softbus_adapter_ble_gatt_server.h"
16 
17 #include "securec.h"
18 #include <stdatomic.h>
19 
20 #include "c_header/ohos_bt_def.h"
21 #include "c_header/ohos_bt_gatt_server.h"
22 
23 #include "common_list.h"
24 #include "softbus_adapter_timer.h"
25 #include "softbus_def.h"
26 #include "softbus_errcode.h"
27 #include "softbus_type_def.h"
28 #include "softbus_adapter_mem.h"
29 #include "softbus_utils.h"
30 
31 #include "conn_log.h"
32 #include "softbus_adapter_ble_gatt_client.h"
33 
34 #define WAIT_HAL_REG_TIME 5 // ms
35 #define WAIT_HAL_REG_RETRY 3
36 #define SOFTBUS_MTU_SIZE 512
37 #define NEARBY_MTU_SIZE 503
38 
39 static const char SOFTBUS_APP_UUID[BT_UUID_LEN] = {
40     0x00, 0x00, 0xFE, 0x36, 0x00, 0x00, 0x10, 0x00,
41     0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
42 };
43 
44 static void FindCallbackByHandle(int32_t handle, SoftBusGattsCallback *callback);
45 static void FindCallbackByConnId(int32_t connId, SoftBusGattsCallback *callback);
46 static void FindCallbackByUdidAndSetHandle(SoftBusBtUuid *serviceUuid, SoftBusGattsCallback *callback,
47                                            int32_t srvcHandle);
48 static int32_t SetConnectionMtu(int connId, int mtu);
49 static int32_t SetConnIdAndAddr(int connId, int serverId, const SoftBusBtAddr *btAddr);
50 
51 SoftBusGattsCallback *g_gattsCallback = NULL;
52 static BtGattServerCallbacks g_bleGattsHalCallback = { 0 };
53 static _Atomic int g_halServerId = -1;
54 static _Atomic int g_halRegFlag = -1; // -1:not registered or register failed; 0:registerring; 1:registered
55 static SoftBusGattsManager g_softBusGattsManager = { 0 };
56 static _Atomic bool g_isRegisterHalCallback = false;
57 static SoftBusBleSendSignal g_serverSendSignal = {0};
58 
IsGattsManagerEmpty(void)59 static bool IsGattsManagerEmpty(void)
60 {
61     bool ret = true;
62     CONN_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_softBusGattsManager.lock) == SOFTBUS_OK, CONN_BLE, ret,
63                                    "try to lock failed");
64     ret = IsListEmpty(&g_softBusGattsManager.services);
65     (void)SoftBusMutexUnlock(&g_softBusGattsManager.lock);
66     return ret;
67 }
68 
CheckGattsStatus(void)69 int CheckGattsStatus(void)
70 {
71     if (IsGattsManagerEmpty()) {
72         CONN_LOGE(CONN_BLE, "GattsManager isListEmpty");
73         return SOFTBUS_LIST_EMPTY;
74     }
75     while (g_halRegFlag == 0) {
76         CONN_LOGE(CONN_BLE, "ble hal registerring");
77         static int tryTimes = WAIT_HAL_REG_RETRY;
78         if (tryTimes > 0) {
79             SoftBusSleepMs(WAIT_HAL_REG_TIME);
80             tryTimes--;
81         } else {
82             atomic_store_explicit(&g_halRegFlag, -1, memory_order_release);
83             break;
84         }
85     }
86     if (g_halRegFlag == -1) {
87         CONN_LOGE(CONN_BLE, "g_halRegFlag == -1");
88         return SOFTBUS_INVALID_NUM;
89     }
90     return SOFTBUS_OK;
91 }
92 
SoftBusGattsAddService(SoftBusBtUuid srvcUuid,bool isPrimary,int number)93 int SoftBusGattsAddService(SoftBusBtUuid srvcUuid, bool isPrimary, int number)
94 {
95     if ((srvcUuid.uuidLen == 0) || (srvcUuid.uuid == NULL) || (number <= 0)) {
96         return SOFTBUS_INVALID_PARAM;
97     }
98     if (CheckGattsStatus() != SOFTBUS_OK) {
99         return SOFTBUS_CONN_BLE_CHECK_STATUS_ERR;
100     }
101     BtUuid uuid = {
102         .uuid = srvcUuid.uuid,
103         .uuidLen = srvcUuid.uuidLen
104     };
105     CONN_LOGI(CONN_BLE, "halServerId=%{public}d", g_halServerId);
106     if (BleGattsAddService(g_halServerId, uuid, isPrimary, number) != SOFTBUS_OK) {
107         return SOFTBUS_CONN_BLE_UNDERLAY_SERVER_ADD_SERVICE_ERR;
108     }
109     return SOFTBUS_OK;
110 }
111 
SoftBusGattsAddCharacteristic(int srvcHandle,SoftBusBtUuid characUuid,int properties,int permissions)112 int SoftBusGattsAddCharacteristic(int srvcHandle, SoftBusBtUuid characUuid, int properties, int permissions)
113 {
114     if ((characUuid.uuidLen == 0) || (characUuid.uuid == NULL)) {
115         return SOFTBUS_INVALID_PARAM;
116     }
117     if (CheckGattsStatus() != SOFTBUS_OK) {
118         return SOFTBUS_CONN_BLE_CHECK_STATUS_ERR;
119     }
120     BtUuid uuid = {
121         .uuid = characUuid.uuid,
122         .uuidLen = characUuid.uuidLen
123     };
124     if (BleGattsAddCharacteristic(g_halServerId, srvcHandle, uuid, properties, permissions) != SOFTBUS_OK) {
125         return SOFTBUS_CONN_BLE_UNDERLAY_CHARACTERISTIC_ADD_ERR;
126     }
127     return SOFTBUS_OK;
128 }
129 
SoftBusGattsAddDescriptor(int srvcHandle,SoftBusBtUuid descUuid,int permissions)130 int SoftBusGattsAddDescriptor(int srvcHandle, SoftBusBtUuid descUuid, int permissions)
131 {
132     if ((descUuid.uuidLen == 0) || (descUuid.uuid == NULL)) {
133         return SOFTBUS_INVALID_PARAM;
134     }
135     if (CheckGattsStatus() != SOFTBUS_OK) {
136         return SOFTBUS_CONN_BLE_CHECK_STATUS_ERR;
137     }
138     BtUuid uuid = {
139         .uuid = descUuid.uuid,
140         .uuidLen = descUuid.uuidLen
141     };
142     if (BleGattsAddDescriptor(g_halServerId, srvcHandle, uuid, permissions) != SOFTBUS_OK) {
143         return SOFTBUS_CONN_BLE_UNDERLAY_DESCRIPTOR_ADD_ERR;
144     }
145     return SOFTBUS_OK;
146 }
147 
SoftBusGattsStartService(int srvcHandle)148 int SoftBusGattsStartService(int srvcHandle)
149 {
150     if (CheckGattsStatus() != SOFTBUS_OK) {
151         return SOFTBUS_CONN_BLE_CHECK_STATUS_ERR;
152     }
153     CONN_LOGI(CONN_BLE, "halServerId = %{public}d, srvcHandle = %{public}d", g_halServerId, srvcHandle);
154     if (BleGattsStartService(g_halServerId, srvcHandle) != SOFTBUS_OK) {
155         return SOFTBUS_CONN_BLE_UNDERLAY_SERVICE_START_ERR;
156     }
157     return SOFTBUS_OK;
158 }
159 
SoftBusGattsStopService(int srvcHandle)160 int SoftBusGattsStopService(int srvcHandle)
161 {
162     if (CheckGattsStatus() != SOFTBUS_OK) {
163         return SOFTBUS_CONN_BLE_CHECK_STATUS_ERR;
164     }
165     CONN_LOGI(CONN_BLE, "halServerId = %{public}d, srvcHandle = %{public}d", g_halServerId, srvcHandle);
166     if (BleGattsStopService(g_halServerId, srvcHandle) != SOFTBUS_OK) {
167         return SOFTBUS_CONN_BLE_UNDERLAY_SERVICE_STOP_ERR;
168     }
169     return SOFTBUS_OK;
170 }
171 
SoftBusGattsDeleteService(int srvcHandle)172 int SoftBusGattsDeleteService(int srvcHandle)
173 {
174     if (CheckGattsStatus() != SOFTBUS_OK) {
175         return SOFTBUS_CONN_BLE_CHECK_STATUS_ERR;
176     }
177     if (BleGattsDeleteService(g_halServerId, srvcHandle) != SOFTBUS_OK) {
178         return SOFTBUS_CONN_BLE_UNDERLAY_SERVICE_DELETE_ERR;
179     }
180     return SOFTBUS_OK;
181 }
182 
SoftBusGattsConnect(SoftBusBtAddr btAddr)183 int SoftBusGattsConnect(SoftBusBtAddr btAddr)
184 {
185     if (CheckGattsStatus() != SOFTBUS_OK) {
186         return SOFTBUS_CONN_BLE_CHECK_STATUS_ERR;
187     }
188     BdAddr addr;
189     if (memcpy_s(addr.addr, BT_ADDR_LEN, btAddr.addr, BT_ADDR_LEN) != EOK) {
190         CONN_LOGE(CONN_BLE, "memcpy fail");
191         return SOFTBUS_MEM_ERR;
192     }
193     CONN_LOGI(CONN_BLE, "BleGattsConnect start");
194     if (BleGattsConnect(g_halServerId, addr) != SOFTBUS_OK) {
195         CONN_LOGE(CONN_BLE, "BleGattsConnect return error");
196         return SOFTBUS_CONN_BLE_UNDERLAY_SERVER_CONNECT_ERR;
197     }
198     return SOFTBUS_OK;
199 }
200 
SoftBusGattsDisconnect(SoftBusBtAddr btAddr,int connId)201 int SoftBusGattsDisconnect(SoftBusBtAddr btAddr, int connId)
202 {
203     if (CheckGattsStatus() != SOFTBUS_OK) {
204         return SOFTBUS_CONN_BLE_CHECK_STATUS_ERR;
205     }
206     BdAddr addr;
207     if (memcpy_s(addr.addr, BT_ADDR_LEN, btAddr.addr, BT_ADDR_LEN) != EOK) {
208         CONN_LOGE(CONN_BLE, "memcpy fail");
209         return SOFTBUS_MEM_ERR;
210     }
211     CONN_LOGI(CONN_BLE, "BleGattsDisconnect start");
212     if (BleGattsDisconnect(g_halServerId, addr, connId) != SOFTBUS_OK) {
213         CONN_LOGE(CONN_BLE, "BleGattsDisconnect return error");
214         return SOFTBUS_CONN_BLE_UNDERLAY_SERVER_DISCONNECT_ERR;
215     }
216     return SOFTBUS_OK;
217 }
218 
SoftBusGattsSendResponse(SoftBusGattsResponse * param)219 int SoftBusGattsSendResponse(SoftBusGattsResponse *param)
220 {
221     if (param == NULL) {
222         CONN_LOGE(CONN_BLE, "invalid param");
223         return SOFTBUS_INVALID_PARAM;
224     }
225 
226     CONN_LOGI(CONN_BLE, "connId=%{public}d", param->connectId);
227     if (CheckGattsStatus() != SOFTBUS_OK) {
228         return SOFTBUS_CONN_BLE_CHECK_STATUS_ERR;
229     }
230     GattsSendRspParam response = {
231         .connectId = param->connectId,
232         .status = param->status,
233         .attrHandle = param->transId,
234         .valueLen = param->valueLen,
235         .value = param->value
236     };
237     if (BleGattsSendResponse(g_halServerId, &response) != SOFTBUS_OK) {
238         return SOFTBUS_CONN_BLE_UNDERLAY_SERVER_SEND_RESPONSE_ERR;
239     }
240     return SOFTBUS_OK;
241 }
242 
SoftBusGattsSendNotify(SoftBusGattsNotify * param)243 int SoftBusGattsSendNotify(SoftBusGattsNotify *param)
244 {
245     if (param == NULL) {
246         CONN_LOGE(CONN_BLE, "invalid param");
247         return SOFTBUS_INVALID_PARAM;
248     }
249 
250     CONN_LOGD(CONN_BLE, "enter");
251     if (CheckGattsStatus() != SOFTBUS_OK) {
252         return SOFTBUS_CONN_BLE_CHECK_STATUS_ERR;
253     }
254     GattsSendIndParam notify = {
255         .connectId = param->connectId,
256         .attrHandle = param->attrHandle,
257         .confirm = param->confirm,
258         .valueLen = param->valueLen,
259         .value = param->value
260     };
261     CONN_CHECK_AND_RETURN_RET_LOGE(
262         SoftBusMutexLock(&g_serverSendSignal.g_sendCondLock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR, CONN_BLE, "lock fail!");
263     if (!g_serverSendSignal.isWriteAvailable) {
264         SoftBusSysTime waitTime = {0};
265         SoftBusComputeWaitBleSendDataTime(BLE_WRITE_TIMEOUT_IN_MS, &waitTime);
266         int32_t ret = SoftBusCondWait(&g_serverSendSignal.g_sendCond, &g_serverSendSignal.g_sendCondLock, &waitTime);
267         if (ret != SOFTBUS_OK) {
268             CONN_LOGE(CONN_BLE, "SoftBusCondWait fail, ret=%{public}d, isWriteAvailable=%{public}d",
269                 ret, g_serverSendSignal.isWriteAvailable);
270             // fall-through: The protocol stack in the blue zone on a signal framework may not be called back.
271         }
272     }
273     g_serverSendSignal.isWriteAvailable = false;
274     (void)SoftBusMutexUnlock(&g_serverSendSignal.g_sendCondLock);
275     CONN_LOGI(CONN_BLE, "halconnId:%{public}d, attrHandle:%{public}d, confirm:%{public}d",
276         notify.connectId, notify.attrHandle, notify.confirm);
277     if (BleGattsSendIndication(g_halServerId, &notify) != SOFTBUS_OK) {
278         CONN_LOGE(CONN_BLE, "BleGattsSendIndication failed");
279         CONN_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_serverSendSignal.g_sendCondLock) == SOFTBUS_OK,
280             SOFTBUS_LOCK_ERR, CONN_BLE, "lock fail!");
281         g_serverSendSignal.isWriteAvailable = true;
282         (void)SoftBusMutexUnlock(&g_serverSendSignal.g_sendCondLock);
283         return SOFTBUS_CONN_BLE_UNDERLAY_SERVER_SEND_INDICATION_ERR;
284     }
285     return SOFTBUS_OK;
286 }
287 
BleRegisterServerCallback(int status,int serverId,BtUuid * appUuid)288 static void BleRegisterServerCallback(int status, int serverId, BtUuid *appUuid)
289 {
290     CONN_LOGI(CONN_BLE, "status=%{public}d, severId=%{public}d", status, serverId);
291     if ((appUuid == NULL) || (appUuid->uuid == NULL)) {
292         CONN_LOGE(CONN_BLE, "appUuid is null");
293         return;
294     }
295 
296     if (memcmp(appUuid->uuid, SOFTBUS_APP_UUID, appUuid->uuidLen) != 0) {
297         CONN_LOGE(CONN_BLE, "BleRegisterServerCallback unknown uuid");
298         return;
299     }
300 
301     if (status != SOFTBUS_OK) {
302         CONN_LOGE(CONN_BLE, "BleRegisterServerCallback failed, status=%{public}d", status);
303         atomic_store_explicit(&g_halRegFlag, -1, memory_order_release);
304     } else {
305         atomic_store_explicit(&g_halRegFlag, 1, memory_order_release);
306         g_halServerId = serverId;
307         CONN_LOGI(CONN_BLE, "g_halServerId:%{public}d)", g_halServerId);
308     }
309 }
310 
BleConnectServerCallback(int connId,int serverId,const BdAddr * bdAddr)311 static void BleConnectServerCallback(int connId, int serverId, const BdAddr *bdAddr)
312 {
313     if (bdAddr == NULL) {
314         CONN_LOGE(CONN_BLE, "invalid param");
315         return;
316     }
317 
318     if (SoftbusGattcCheckExistConnectionByAddr((SoftBusBtAddr *)bdAddr)) {
319         CONN_LOGW(CONN_BLE, "ble client exist connection by addr.");
320         return;
321     }
322 
323     CONN_LOGI(CONN_BLE, "ConnectServerCallback is coming, connId=%{public}d, serverId=%{public}d", connId, serverId);
324     if (serverId != g_halServerId) {
325         CONN_LOGI(CONN_BLE, "invalid serverId, halserverId=%{public}d", g_halServerId);
326         return;
327     }
328     SetConnIdAndAddr(connId, serverId, (SoftBusBtAddr *)bdAddr);
329 }
330 
RemoveConnId(int32_t connId)331 static void RemoveConnId(int32_t connId)
332 {
333     CONN_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_softBusGattsManager.lock) == SOFTBUS_OK,
334         CONN_BLE, "try to lock failed, connId=%{public}d", connId);
335     ServerConnection *it = NULL;
336     ServerConnection *next = NULL;
337     LIST_FOR_EACH_ENTRY_SAFE(it, next, &g_softBusGattsManager.connections, ServerConnection, node) {
338         if (it->connId == connId) {
339             ListDelete(&it->node);
340             SoftBusFree(it);
341             break;
342         }
343     }
344     (void)SoftBusMutexUnlock(&g_softBusGattsManager.lock);
345 }
346 
BleDisconnectServerCallback(int connId,int serverId,const BdAddr * bdAddr)347 static void BleDisconnectServerCallback(int connId, int serverId, const BdAddr *bdAddr)
348 {
349     CONN_LOGI(CONN_BLE, "DisconnectServerCallback is coming, connId=%{public}d, severId=%{public}d", connId, serverId);
350     if (serverId != g_halServerId) {
351         CONN_LOGI(CONN_BLE, "invalid serverId, halserverId=%{public}d", g_halServerId);
352         return;
353     }
354     SoftBusGattsCallback callback = { 0 };
355     FindCallbackByConnId(connId, &callback);
356     if (callback.DisconnectServerCallback != NULL) {
357         callback.DisconnectServerCallback(connId, (SoftBusBtAddr *)bdAddr);
358     }
359     RemoveConnId(connId);
360 }
361 
BleServiceAddCallback(int status,int serverId,BtUuid * uuid,int srvcHandle)362 static void BleServiceAddCallback(int status, int serverId, BtUuid *uuid, int srvcHandle)
363 {
364     if (uuid == NULL) {
365         CONN_LOGE(CONN_BLE, "invalid param");
366         return;
367     }
368 
369     (void)serverId;
370     CONN_LOGI(CONN_BLE, "srvcHandle=%{public}d", srvcHandle);
371     if (serverId != g_halServerId) {
372         return;
373     }
374     SoftBusGattsCallback callback = { 0 };
375     FindCallbackByUdidAndSetHandle((SoftBusBtUuid *)uuid, &callback, srvcHandle);
376     if (callback.ServiceAddCallback == NULL) {
377         CONN_LOGE(CONN_BLE, "find callback by uuid failed");
378         return;
379     }
380     callback.ServiceAddCallback(status, (SoftBusBtUuid *)uuid, srvcHandle);
381 }
382 
BleIncludeServiceAddCallback(int status,int serverId,int srvcHandle,int includeSrvcHandle)383 static void BleIncludeServiceAddCallback(int status, int serverId, int srvcHandle, int includeSrvcHandle)
384 {
385     (void)serverId;
386     (void)srvcHandle;
387     CONN_LOGI(CONN_BLE, "srvcHandle=%{public}d, includeSrvcHandle=%{public}d\n", srvcHandle, includeSrvcHandle);
388 }
389 
BleCharacteristicAddCallback(int status,int serverId,BtUuid * uuid,int srvcHandle,int characteristicHandle)390 static void BleCharacteristicAddCallback(int status, int serverId, BtUuid *uuid, int srvcHandle,
391     int characteristicHandle)
392 {
393     CONN_LOGI(CONN_BLE, "srvcHandle=%{public}d, charHandle=%{public}d\n", srvcHandle, characteristicHandle);
394     if (serverId != g_halServerId) {
395         CONN_LOGE(CONN_BLE, "bad server id");
396         return;
397     }
398     SoftBusGattsCallback callback = { 0 };
399     FindCallbackByHandle(srvcHandle, &callback);
400     if (callback.CharacteristicAddCallback == NULL) {
401         CONN_LOGE(CONN_BLE, "find callback by handle %{public}d failed", srvcHandle);
402         return;
403     }
404     CONN_LOGI(CONN_BLE, "characteristicHandle:%{public}d)", characteristicHandle);
405     callback.CharacteristicAddCallback(status, (SoftBusBtUuid *)uuid, srvcHandle, characteristicHandle);
406 }
407 
BleDescriptorAddCallback(int status,int serverId,BtUuid * uuid,int srvcHandle,int descriptorHandle)408 static void BleDescriptorAddCallback(int status, int serverId, BtUuid *uuid, int srvcHandle, int descriptorHandle)
409 {
410     if (uuid == NULL) {
411         CONN_LOGE(CONN_BLE, "invalid param");
412     }
413     CONN_LOGI(CONN_BLE, "srvcHandle=%{public}d, descriptorHandle=%{public}d", srvcHandle, descriptorHandle);
414     if (serverId != g_halServerId) {
415         return;
416     }
417     SoftBusGattsCallback callback = { 0 };
418     FindCallbackByHandle(srvcHandle, &callback);
419     if (callback.DescriptorAddCallback == NULL) {
420         CONN_LOGE(CONN_BLE, "find callback by handle %{public}d failed", srvcHandle);
421         return;
422     }
423     callback.DescriptorAddCallback(status, (SoftBusBtUuid *)uuid, srvcHandle, descriptorHandle);
424 }
425 
BleServiceStartCallback(int status,int serverId,int srvcHandle)426 static void BleServiceStartCallback(int status, int serverId, int srvcHandle)
427 {
428     CONN_LOGI(CONN_BLE, "ServiceStartCallback serverId=%{public}d, srvcHandle=%{public}d\n", serverId, srvcHandle);
429     if (serverId != g_halServerId) {
430         return;
431     }
432     SoftBusGattsCallback callback = { 0 };
433     FindCallbackByHandle(srvcHandle, &callback);
434     if (callback.ServiceStartCallback == NULL) {
435         CONN_LOGE(CONN_BLE, "find callback by handle %{public}d failed", srvcHandle);
436         return;
437     }
438     CONN_LOGI(CONN_BLE, "srvcHandle=%{public}d", srvcHandle);
439     callback.ServiceStartCallback(status, srvcHandle);
440 }
441 
BleServiceStopCallback(int status,int serverId,int srvcHandle)442 static void BleServiceStopCallback(int status, int serverId, int srvcHandle)
443 {
444     CONN_LOGI(CONN_BLE, "serverId=%{public}d, srvcHandle=%{public}d\n", serverId, srvcHandle);
445     if (serverId != g_halServerId) {
446         return;
447     }
448     SoftBusGattsCallback callback = { 0 };
449     FindCallbackByHandle(srvcHandle, &callback);
450     if (callback.ServiceStopCallback == NULL) {
451         CONN_LOGE(CONN_BLE, "find callback by handle %{public}d failed", srvcHandle);
452         return;
453     }
454     callback.ServiceStopCallback(status, srvcHandle);
455 }
456 
BleServiceDeleteCallback(int status,int serverId,int srvcHandle)457 static void BleServiceDeleteCallback(int status, int serverId, int srvcHandle)
458 {
459     CONN_LOGI(CONN_BLE, "ServiceDeleteCallback serverId=%{public}d,srvcHandle=%{public}d\n", serverId, srvcHandle);
460     if (serverId != g_halServerId) {
461         return;
462     }
463     SoftBusGattsCallback callback = { 0 };
464     FindCallbackByHandle(srvcHandle, &callback);
465     if (callback.ServiceDeleteCallback == NULL) {
466         CONN_LOGE(CONN_BLE, "find callback by handle %{public}d failed", srvcHandle);
467         return;
468     }
469     callback.ServiceDeleteCallback(status, srvcHandle);
470 }
471 
BleRequestReadCallback(BtReqReadCbPara readCbPara)472 static void BleRequestReadCallback(BtReqReadCbPara readCbPara)
473 {
474     CONN_LOGI(CONN_BLE, "transId=%{public}d, attrHandle=%{public}d", readCbPara.transId, readCbPara.attrHandle);
475     SoftBusGattReadRequest req = {
476         .connId = readCbPara.connId,
477         .transId = readCbPara.transId,
478         .btAddr = (SoftBusBtAddr *)readCbPara.bdAddr,
479         .attrHandle = readCbPara.attrHandle,
480         .offset = readCbPara.offset,
481         .isLong = readCbPara.isLong,
482     };
483     SoftBusGattsCallback callback = { 0 };
484     FindCallbackByConnId(readCbPara.connId, &callback);
485     if (callback.RequestReadCallback == NULL) {
486         CONN_LOGI(CONN_BLE, "find callback by handle %{public}d failed", readCbPara.connId);
487         return;
488     }
489     callback.RequestReadCallback(req);
490 }
491 
GetServerConnectionByConnIdUnsafe(int32_t connId)492 static ServerConnection *GetServerConnectionByConnIdUnsafe(int32_t connId)
493 {
494     ServerConnection *it = NULL;
495     ServerConnection *target = NULL;
496     LIST_FOR_EACH_ENTRY(it, &g_softBusGattsManager.connections, ServerConnection, node) {
497         if (it->connId == connId) {
498             target = it;
499             break;
500         }
501     }
502     return target;
503 }
504 
FindCallbackAndNotifyConnected(int32_t connId,int32_t attrHandle,SoftBusGattsCallback * callback)505 static void FindCallbackAndNotifyConnected(int32_t connId, int32_t attrHandle, SoftBusGattsCallback *callback)
506 {
507     CONN_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_softBusGattsManager.lock) == SOFTBUS_OK,
508         CONN_BLE, "try to lock failed, handle=%{public}d", attrHandle);
509     ServerService *it = NULL;
510     ServerService *target = NULL;
511     LIST_FOR_EACH_ENTRY(it, &g_softBusGattsManager.services, ServerService, node) {
512         if (it->callback.IsConcernedAttrHandle != NULL && it->callback.IsConcernedAttrHandle(it->handle, attrHandle)) {
513             target = it;
514             break;
515         }
516     }
517     if (target == NULL)  {
518         CONN_LOGW(CONN_BLE, "unconcerned handle=%{public}d", attrHandle);
519         (void)SoftBusMutexUnlock(&g_softBusGattsManager.lock);
520         return;
521     }
522 
523     ServerConnection *connection = GetServerConnectionByConnIdUnsafe(connId);
524     if (connection == NULL) {
525         CONN_LOGE(CONN_BLE, "conn is not exist, connId=%{public}d", connId);
526         (void)SoftBusMutexUnlock(&g_softBusGattsManager.lock);
527         return;
528     }
529 
530     connection->handle = target->handle; // Map connection to server
531     if (!connection->notifyConnected && connection->mtu != 0) {
532         if (target->callback.ConnectServerCallback != NULL) {
533             target->callback.ConnectServerCallback(connId, &connection->btAddr);
534         }
535         if (target->callback.MtuChangeCallback != NULL) {
536             target->callback.MtuChangeCallback(connId, connection->mtu);
537         }
538         connection->notifyConnected = true;
539     }
540     *callback = target->callback;
541     (void)SoftBusMutexUnlock(&g_softBusGattsManager.lock);
542 }
543 
BleRequestWriteCallback(BtReqWriteCbPara writeCbPara)544 static void BleRequestWriteCallback(BtReqWriteCbPara writeCbPara)
545 {
546     CONN_LOGI(CONN_BLE, "connId=%{public}d, attrHandle=%{public}d, req.needRsp=%{public}d", writeCbPara.connId,
547               writeCbPara.attrHandle, writeCbPara.needRsp);
548 
549     SoftBusGattWriteRequest req = {
550         .connId = writeCbPara.connId,
551         .transId = writeCbPara.transId,
552         .btAddr = (SoftBusBtAddr *)writeCbPara.bdAddr,
553         .attrHandle = writeCbPara.attrHandle,
554         .offset = writeCbPara.offset,
555         .length = writeCbPara.length,
556         .needRsp = writeCbPara.needRsp,
557         .isPrep = writeCbPara.isPrep,
558         .value = writeCbPara.value
559     };
560     SoftBusGattsCallback callback = { 0 };
561     FindCallbackAndNotifyConnected(writeCbPara.connId, writeCbPara.attrHandle, &callback);
562     if (callback.RequestWriteCallback != NULL) {
563         callback.RequestWriteCallback(req);
564         return;
565     }
566     // A response needs to be sent before the ACL is created.
567     CONN_LOGI(CONN_BLE, "send response handle=%{public}d", writeCbPara.connId);
568     if (writeCbPara.needRsp) {
569         SoftBusGattsResponse response = {
570             .connectId = writeCbPara.connId,
571             .transId = writeCbPara.transId,
572             .status = SOFTBUS_BT_STATUS_SUCCESS,
573             .attrHandle = writeCbPara.attrHandle,
574             .offset = writeCbPara.offset,
575             .valueLen = writeCbPara.length,
576             .value = (char *)writeCbPara.value,
577         };
578         SoftBusGattsSendResponse(&response);
579     }
580 }
581 
BleResponseConfirmationCallback(int status,int handle)582 static void BleResponseConfirmationCallback(int status, int handle)
583 {
584     CONN_LOGI(CONN_BLE, "status=%{public}d, handle=%{public}d\n", status, handle);
585 }
586 
BleIndicationSentCallback(int connId,int status)587 static void BleIndicationSentCallback(int connId, int status)
588 {
589     CONN_LOGI(CONN_BLE, "status=%{public}d, connId=%{public}d\n", status, connId);
590     CONN_CHECK_AND_RETURN_LOGE(
591         SoftBusMutexLock(&g_serverSendSignal.g_sendCondLock) == SOFTBUS_OK, CONN_BLE, "lock fail!");
592     g_serverSendSignal.isWriteAvailable = true;
593     (void)SoftBusCondBroadcast(&g_serverSendSignal.g_sendCond);
594     (void)SoftBusMutexUnlock(&g_serverSendSignal.g_sendCondLock);
595     SoftBusGattsCallback callback = { 0 };
596     FindCallbackByConnId(connId, &callback);
597     if (callback.NotifySentCallback == NULL) {
598         CONN_LOGI(CONN_BLE, "find callback by connId %{public}d failed", connId);
599         return;
600     }
601     callback.NotifySentCallback(connId, status);
602 }
603 
BleMtuChangeCallback(int connId,int mtu)604 static void BleMtuChangeCallback(int connId, int mtu)
605 {
606     CONN_LOGI(CONN_BLE, "connId=%{public}d, mtu=%{public}d", connId, mtu);
607     int32_t ret = SetConnectionMtu(connId, mtu);
608     if (ret != SOFTBUS_OK) {
609         CONN_LOGW(CONN_BLE, "SetConnectionMtu failed, err=%{public}d", ret);
610     }
611 }
612 
GattsRegisterHalCallback(void)613 static int GattsRegisterHalCallback(void)
614 {
615     g_bleGattsHalCallback.registerServerCb = BleRegisterServerCallback;
616     g_bleGattsHalCallback.connectServerCb = BleConnectServerCallback;
617     g_bleGattsHalCallback.disconnectServerCb = BleDisconnectServerCallback;
618     g_bleGattsHalCallback.serviceAddCb = BleServiceAddCallback;
619     g_bleGattsHalCallback.includeServiceAddCb = BleIncludeServiceAddCallback;
620     g_bleGattsHalCallback.characteristicAddCb = BleCharacteristicAddCallback;
621     g_bleGattsHalCallback.descriptorAddCb = BleDescriptorAddCallback;
622     g_bleGattsHalCallback.serviceStartCb = BleServiceStartCallback;
623     g_bleGattsHalCallback.serviceStopCb = BleServiceStopCallback;
624     g_bleGattsHalCallback.serviceDeleteCb = BleServiceDeleteCallback;
625     g_bleGattsHalCallback.requestReadCb = BleRequestReadCallback;
626     g_bleGattsHalCallback.requestWriteCb = BleRequestWriteCallback;
627     g_bleGattsHalCallback.responseConfirmationCb = BleResponseConfirmationCallback;
628     g_bleGattsHalCallback.indicationSentCb = BleIndicationSentCallback;
629     g_bleGattsHalCallback.mtuChangeCb = BleMtuChangeCallback;
630     return BleGattsRegisterCallbacks(&g_bleGattsHalCallback);
631 }
632 
FindCallbackByHandle(int32_t handle,SoftBusGattsCallback * callback)633 static void FindCallbackByHandle(int32_t handle, SoftBusGattsCallback *callback)
634 {
635     CONN_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_softBusGattsManager.lock) == SOFTBUS_OK,
636         CONN_BLE, "try to lock failed, handle=%{public}d", handle);
637     ServerService *it = NULL;
638     LIST_FOR_EACH_ENTRY(it, &g_softBusGattsManager.services, ServerService, node) {
639         if (it->handle == handle) {
640             *callback = it->callback;
641             break;
642         }
643     }
644     (void)SoftBusMutexUnlock(&g_softBusGattsManager.lock);
645 }
646 
SetConnectionMtu(int connId,int mtu)647 static int32_t SetConnectionMtu(int connId, int mtu)
648 {
649     CONN_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_softBusGattsManager.lock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
650         CONN_BLE, "try to lock failed, connId=%{public}d", connId);
651     ServerConnection *conn = GetServerConnectionByConnIdUnsafe(connId);
652     if (conn == NULL) {
653         CONN_LOGW(CONN_BLE, "conn is not exist, connId=%{public}d", connId);
654         (void)SoftBusMutexUnlock(&g_softBusGattsManager.lock);
655         return SOFTBUS_NOT_FIND;
656     }
657     conn->mtu = mtu;
658     (void)SoftBusMutexUnlock(&g_softBusGattsManager.lock);
659     return SOFTBUS_OK;
660 }
661 
SetConnIdAndAddr(int connId,int serverId,const SoftBusBtAddr * btAddr)662 static int32_t SetConnIdAndAddr(int connId, int serverId, const SoftBusBtAddr *btAddr)
663 {
664     CONN_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_softBusGattsManager.lock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
665         CONN_BLE, "try to lock failed, connId=%{public}d", connId);
666     ServerConnection *it = NULL;
667     ServerConnection *target =  NULL;
668     bool isExist = false;
669     LIST_FOR_EACH_ENTRY(it, &g_softBusGattsManager.connections, ServerConnection, node) {
670         if (it->connId == connId) {
671             target = it;
672             isExist = true;
673             break;
674         }
675     }
676     if (!isExist) {
677         target = (ServerConnection *)SoftBusCalloc(sizeof(ServerConnection));
678         if (target == NULL) {
679             CONN_LOGE(CONN_BLE, "calloc serverConnection failed");
680             (void)SoftBusMutexUnlock(&g_softBusGattsManager.lock);
681             return SOFTBUS_MALLOC_ERR;
682         }
683         ListInit(&target->node);
684         ListAdd(&g_softBusGattsManager.connections, &target->node);
685     }
686     target->connId = connId;
687     target->notifyConnected = false;
688     target->handle = -1;
689     (void)memcpy_s(&target->btAddr, sizeof(SoftBusBtAddr), btAddr, sizeof(SoftBusBtAddr));
690     (void)SoftBusMutexUnlock(&g_softBusGattsManager.lock);
691     return SOFTBUS_OK;
692 }
693 
FindCallbackByConnId(int32_t connId,SoftBusGattsCallback * callback)694 static void FindCallbackByConnId(int32_t connId, SoftBusGattsCallback *callback)
695 {
696     CONN_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_softBusGattsManager.lock) == SOFTBUS_OK,
697         CONN_BLE, "try to lock failed, connId=%{public}d", connId);
698     ServerConnection *conn = GetServerConnectionByConnIdUnsafe(connId);
699     if (conn == NULL) {
700         CONN_LOGI(CONN_BLE, "conn is not exist, connId=%{public}d", connId);
701         (void)SoftBusMutexUnlock(&g_softBusGattsManager.lock);
702         return;
703     }
704     int32_t handle = conn->handle;
705     (void)SoftBusMutexUnlock(&g_softBusGattsManager.lock);
706     FindCallbackByHandle(handle, callback);
707 }
708 
FindCallbackByUdidAndSetHandle(SoftBusBtUuid * serviceUuid,SoftBusGattsCallback * callback,int32_t srvcHandle)709 static void FindCallbackByUdidAndSetHandle(
710     SoftBusBtUuid *serviceUuid, SoftBusGattsCallback *callback, int32_t srvcHandle)
711 {
712     CONN_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_softBusGattsManager.lock) == SOFTBUS_OK,
713         CONN_BLE, "try to lock failed, srvcHandle=%{public}d", srvcHandle);
714     ServerService *it = NULL;
715     LIST_FOR_EACH_ENTRY(it, &g_softBusGattsManager.services, ServerService, node) {
716         if (it->serviceUuid.uuidLen == serviceUuid->uuidLen &&
717             memcmp(it->serviceUuid.uuid, serviceUuid->uuid, it->serviceUuid.uuidLen) == 0) {
718             *callback = it->callback;
719             it->handle = srvcHandle;
720             break;
721         }
722     }
723     (void)SoftBusMutexUnlock(&g_softBusGattsManager.lock);
724 }
725 
CreateAndAddGattsManager(SoftBusGattsCallback * callback,SoftBusBtUuid serviceUuid)726 static int32_t CreateAndAddGattsManager(SoftBusGattsCallback *callback, SoftBusBtUuid serviceUuid)
727 {
728     CONN_CHECK_AND_RETURN_RET_LOGE(SoftBusMutexLock(&g_softBusGattsManager.lock) == SOFTBUS_OK, SOFTBUS_LOCK_ERR,
729         CONN_BLE, "try to lock failed");
730     ServerService *it = NULL;
731     LIST_FOR_EACH_ENTRY(it, &g_softBusGattsManager.services, ServerService, node) {
732         if (it->serviceUuid.uuidLen == serviceUuid.uuidLen &&
733             memcmp(it->serviceUuid.uuid, serviceUuid.uuid, serviceUuid.uuidLen) == 0) {
734             CONN_LOGW(CONN_BLE, "SoftBusRegisterGattsCallbacks register again");
735             (void)SoftBusMutexUnlock(&g_softBusGattsManager.lock);
736             return SOFTBUS_OK;
737         }
738     }
739 
740     ServerService *service = (ServerService *)SoftBusCalloc(sizeof(ServerService));
741     if (service == NULL) {
742         CONN_LOGE(CONN_BLE, "calloc failed");
743         (void)SoftBusMutexUnlock(&g_softBusGattsManager.lock);
744         return SOFTBUS_MALLOC_ERR;
745     }
746     service->serviceUuid = serviceUuid;
747     service->callback = *callback;
748     service->handle = -1;
749 
750     ListInit(&service->node);
751     ListAdd(&g_softBusGattsManager.services, &service->node);
752     (void)SoftBusMutexUnlock(&g_softBusGattsManager.lock);
753     return SOFTBUS_OK;
754 }
755 
RemoveGattsManager(SoftBusBtUuid serviceUuid)756 static void RemoveGattsManager(SoftBusBtUuid serviceUuid)
757 {
758     CONN_CHECK_AND_RETURN_LOGE(SoftBusMutexLock(&g_softBusGattsManager.lock) == SOFTBUS_OK,
759         CONN_BLE, "try to lock failed");
760     ServerService *it = NULL;
761     ServerService *next = NULL;
762     LIST_FOR_EACH_ENTRY_SAFE(it, next, &g_softBusGattsManager.services, ServerService, node) {
763         if (it->serviceUuid.uuidLen == serviceUuid.uuidLen &&
764             memcmp(it->serviceUuid.uuid, serviceUuid.uuid, it->serviceUuid.uuidLen) == 0) {
765             ListDelete(&it->node);
766             SoftBusFree(it);
767             break;
768         }
769     }
770     (void)SoftBusMutexUnlock(&g_softBusGattsManager.lock);
771 }
772 
SoftBusRegisterGattsCallbacks(SoftBusGattsCallback * callback,SoftBusBtUuid serviceUuid)773 int SoftBusRegisterGattsCallbacks(SoftBusGattsCallback *callback, SoftBusBtUuid serviceUuid)
774 {
775     if (callback == NULL) {
776         CONN_LOGE(CONN_BLE, "SoftBusRegisterGattsCallbacks fail:nullptr");
777         return SOFTBUS_BLECONNECTION_REG_GATTS_CALLBACK_FAIL;
778     }
779 
780     int32_t ret = CreateAndAddGattsManager(callback, serviceUuid);
781     CONN_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, CONN_BLE, "create and add gattsManager failed");
782 
783     if (!atomic_load_explicit(&g_isRegisterHalCallback, memory_order_acquire)) {
784         CONN_LOGE(CONN_BLE, "GattsRegisterHalCallback");
785         ret = GattsRegisterHalCallback();
786     }
787     if (ret != SOFTBUS_OK) {
788         RemoveGattsManager(serviceUuid);
789         CONN_LOGE(CONN_BLE, "GattsRegisterCallbacks failed:%{public}d", ret);
790         return SOFTBUS_BLECONNECTION_REG_GATTS_CALLBACK_FAIL;
791     }
792     atomic_store_explicit(&g_isRegisterHalCallback, true, memory_order_release);
793     if (g_halRegFlag == -1) {
794         BtUuid uuid;
795         uuid.uuid = (char *)SOFTBUS_APP_UUID;
796         uuid.uuidLen = sizeof(SOFTBUS_APP_UUID);
797         atomic_store_explicit(&g_halRegFlag, 0, memory_order_release);
798         CONN_LOGI(CONN_BLE, "BleGattsRegister");
799         ret = BleGattsRegister(uuid);
800         if (ret != SOFTBUS_OK) {
801             atomic_store_explicit(&g_halRegFlag, -1, memory_order_release);
802             RemoveGattsManager(serviceUuid);
803             CONN_LOGE(CONN_BLE, "BleGattsRegister failed:%{public}d", ret);
804             return SOFTBUS_BLECONNECTION_REG_GATTS_CALLBACK_FAIL;
805         }
806     }
807     return SOFTBUS_OK;
808 }
809 
SoftBusUnRegisterGattsCallbacks(SoftBusBtUuid serviceUuid)810 void SoftBusUnRegisterGattsCallbacks(SoftBusBtUuid serviceUuid)
811 {
812     RemoveGattsManager(serviceUuid);
813     if (g_halRegFlag == -1 || !IsGattsManagerEmpty()) {
814         CONN_LOGI(CONN_BLE, "no need to unregist gatt server.");
815         return;
816     }
817     CONN_LOGI(CONN_BLE, "UnRegister GattsCallbacks");
818     if (BleGattsUnRegister(g_halServerId) != SOFTBUS_OK) {
819         CONN_LOGE(CONN_BLE, "BleGattsUnRegister error.");
820         return;
821     }
822     atomic_store_explicit(&g_halServerId, -1, memory_order_release);
823     atomic_store_explicit(&g_halRegFlag, -1, memory_order_release);
824 }
825 
InitSoftbusAdapterServer(void)826 int InitSoftbusAdapterServer(void)
827 {
828     ListInit(&g_softBusGattsManager.services);
829     ListInit(&g_softBusGattsManager.connections);
830     if (SoftBusMutexInit(&g_serverSendSignal.g_sendCondLock, NULL) != SOFTBUS_OK) {
831         CONN_LOGE(CONN_INIT, "mutex init failed");
832         ListDelInit(&g_softBusGattsManager.services);
833         ListDelInit(&g_softBusGattsManager.connections);
834         return SOFTBUS_NO_INIT;
835     }
836     if (SoftBusCondInit(&g_serverSendSignal.g_sendCond) != SOFTBUS_OK) {
837         ListDelInit(&g_softBusGattsManager.services);
838         ListDelInit(&g_softBusGattsManager.connections);
839         (void)SoftBusMutexDestroy(&g_serverSendSignal.g_sendCondLock);
840         return SOFTBUS_NO_INIT;
841     }
842     g_serverSendSignal.isWriteAvailable = true;
843     return SoftBusMutexInit(&g_softBusGattsManager.lock, NULL);
844 }