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, ¬ify) != 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 }