• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
19 #include "softbus_adapter_timer.h"
20 #include "softbus_def.h"
21 #include "softbus_errcode.h"
22 #include "softbus_log.h"
23 #include "softbus_type_def.h"
24 
25 #include "c_header/ohos_bt_def.h"
26 #include "c_header/ohos_bt_gatt_server.h"
27 
28 #define WAIT_HAL_REG_TIME 5 // ms
29 #define WAIT_HAL_REG_RETRY 3
30 
31 static const char SOFTBUS_APP_UUID[BT_UUID_LEN] = {
32     0x00, 0x00, 0xFE, 0x36, 0x00, 0x00, 0x10, 0x00,
33     0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
34 };
35 
36 SoftBusGattsCallback *g_gattsCallback = NULL;
37 static BtGattServerCallbacks g_bleGattsHalCallback = {0};
38 static volatile int g_halServerId = -1;
39 static volatile int g_halRegFlag = -1; // -1:not registered or register failed; 0:registerring; 1:registered
40 
CheckGattsStatus(void)41 NO_SANITIZE("cfi") int CheckGattsStatus(void)
42 {
43     if (g_gattsCallback == NULL) {
44         return SOFTBUS_ERR;
45     }
46     while (g_halRegFlag == 0) {
47         CLOGE("ble hal registerring");
48         static int tryTimes = WAIT_HAL_REG_RETRY;
49         if (tryTimes > 0) {
50             SoftBusSleepMs(WAIT_HAL_REG_TIME);
51             tryTimes--;
52         } else {
53             g_halRegFlag = -1;
54             break;
55         }
56     }
57     if (g_halRegFlag == -1) {
58         return SOFTBUS_ERR;
59     }
60     return SOFTBUS_OK;
61 }
62 
SoftBusGattsAddService(SoftBusBtUuid srvcUuid,bool isPrimary,int number)63 NO_SANITIZE("cfi") int SoftBusGattsAddService(SoftBusBtUuid srvcUuid, bool isPrimary, int number)
64 {
65     if ((srvcUuid.uuidLen == 0) || (srvcUuid.uuid == NULL) || (number <= 0)) {
66         return SOFTBUS_ERR;
67     }
68     if (CheckGattsStatus() != SOFTBUS_OK) {
69         return SOFTBUS_ERR;
70     }
71     BtUuid uuid = {
72         .uuid = srvcUuid.uuid,
73         .uuidLen = srvcUuid.uuidLen
74     };
75     if (BleGattsAddService(g_halServerId, uuid, isPrimary, number) != SOFTBUS_OK) {
76         return SOFTBUS_ERR;
77     }
78     return SOFTBUS_OK;
79 }
80 
SoftBusGattsAddCharacteristic(int srvcHandle,SoftBusBtUuid characUuid,int properties,int permissions)81 NO_SANITIZE("cfi") int SoftBusGattsAddCharacteristic(int srvcHandle, SoftBusBtUuid characUuid, int properties,
82     int permissions)
83 {
84     if ((characUuid.uuidLen == 0) || (characUuid.uuid == NULL)) {
85         return SOFTBUS_ERR;
86     }
87     if (CheckGattsStatus() != SOFTBUS_OK) {
88         return SOFTBUS_ERR;
89     }
90     BtUuid uuid = {
91         .uuid = characUuid.uuid,
92         .uuidLen = characUuid.uuidLen
93     };
94     if (BleGattsAddCharacteristic(g_halServerId, srvcHandle, uuid, properties, permissions) != SOFTBUS_OK) {
95         return SOFTBUS_ERR;
96     }
97     return SOFTBUS_OK;
98 }
99 
SoftBusGattsAddDescriptor(int srvcHandle,SoftBusBtUuid descUuid,int permissions)100 NO_SANITIZE("cfi") int SoftBusGattsAddDescriptor(int srvcHandle, SoftBusBtUuid descUuid, int permissions)
101 {
102     if ((descUuid.uuidLen == 0) || (descUuid.uuid == NULL)) {
103         return SOFTBUS_ERR;
104     }
105     if (CheckGattsStatus() != SOFTBUS_OK) {
106         return SOFTBUS_ERR;
107     }
108     BtUuid uuid = {
109         .uuid = descUuid.uuid,
110         .uuidLen = descUuid.uuidLen
111     };
112     if (BleGattsAddDescriptor(g_halServerId, srvcHandle, uuid, permissions) != SOFTBUS_OK) {
113         return SOFTBUS_ERR;
114     }
115     return SOFTBUS_OK;
116 }
117 
SoftBusGattsStartService(int srvcHandle)118 NO_SANITIZE("cfi") int SoftBusGattsStartService(int srvcHandle)
119 {
120     if (CheckGattsStatus() != SOFTBUS_OK) {
121         return SOFTBUS_ERR;
122     }
123     CLOGI("BLEINFOPRTINT:BleGattsStartService(%d, %d)", g_halServerId, srvcHandle);
124     if (BleGattsStartService(g_halServerId, srvcHandle) != SOFTBUS_OK) {
125         return SOFTBUS_ERR;
126     }
127     return SOFTBUS_OK;
128 }
129 
SoftBusGattsStopService(int srvcHandle)130 NO_SANITIZE("cfi") int SoftBusGattsStopService(int srvcHandle)
131 {
132     if (CheckGattsStatus() != SOFTBUS_OK) {
133         return SOFTBUS_ERR;
134     }
135     CLOGI("BLEINFOPRTINT:SoftBusGattsStopService(%d, %d)", g_halServerId, srvcHandle);
136     if (BleGattsStopService(g_halServerId, srvcHandle) != SOFTBUS_OK) {
137         return SOFTBUS_ERR;
138     }
139     return SOFTBUS_OK;
140 }
141 
SoftBusGattsDeleteService(int srvcHandle)142 NO_SANITIZE("cfi") int SoftBusGattsDeleteService(int srvcHandle)
143 {
144     if (CheckGattsStatus() != SOFTBUS_OK) {
145         return SOFTBUS_ERR;
146     }
147     if (BleGattsDeleteService(g_halServerId, srvcHandle) != SOFTBUS_OK) {
148         return SOFTBUS_ERR;
149     }
150     return SOFTBUS_OK;
151 }
152 
SoftBusGattsConnect(int connId)153 int SoftBusGattsConnect(int connId)
154 {
155     CLOGD("SoftBusGattsConnect stub is called, return success");
156     return SOFTBUS_OK;
157 }
158 
SoftBusGattsDisconnect(SoftBusBtAddr btAddr,int connId)159 NO_SANITIZE("cfi") int SoftBusGattsDisconnect(SoftBusBtAddr btAddr, int connId)
160 {
161     if (CheckGattsStatus() != SOFTBUS_OK) {
162         return SOFTBUS_ERR;
163     }
164     BdAddr addr;
165     if (memcpy_s(addr.addr, BT_ADDR_LEN, btAddr.addr, BT_ADDR_LEN) != EOK) {
166         CLOGE("SoftBusGattsDisconnect memcpy fail");
167         return SOFTBUS_ERR;
168     }
169     if (BleGattsDisconnect(g_halServerId, addr, connId) != SOFTBUS_OK) {
170         return SOFTBUS_ERR;
171     }
172     return SOFTBUS_OK;
173 }
174 
SoftBusGattsSendResponse(SoftBusGattsResponse * param)175 NO_SANITIZE("cfi") int SoftBusGattsSendResponse(SoftBusGattsResponse *param)
176 {
177     if (CheckGattsStatus() != SOFTBUS_OK) {
178         return SOFTBUS_ERR;
179     }
180     GattsSendRspParam response = {
181         .connectId = param->connectId,
182         .status = param->status,
183         .attrHandle = param->transId,
184         .valueLen = param->valueLen,
185         .value = param->value
186     };
187     if (BleGattsSendResponse(g_halServerId, &response) != SOFTBUS_OK) {
188         return SOFTBUS_ERR;
189     }
190     return SOFTBUS_OK;
191 }
192 
SoftBusGattsSendNotify(SoftBusGattsNotify * param)193 NO_SANITIZE("cfi") int SoftBusGattsSendNotify(SoftBusGattsNotify *param)
194 {
195     CLOGI("SoftBusGattsSendNotify enter");
196     if (CheckGattsStatus() != SOFTBUS_OK) {
197         return SOFTBUS_ERR;
198     }
199     GattsSendIndParam notify = {
200         .connectId = param->connectId,
201         .attrHandle = param->attrHandle,
202         .confirm = param->confirm,
203         .valueLen = param->valueLen,
204         .value = param->value
205     };
206     CLOGI("SoftBusGattsSendNotify call BleGattsSendIndication halconnId:%d attrHandle:%d confirm:%d",
207         notify.connectId, notify.attrHandle, notify.confirm);
208     if (BleGattsSendIndication(g_halServerId, &notify) != SOFTBUS_OK) {
209         CLOGE("SoftBusGattsSendNotify failed");
210         return SOFTBUS_ERR;
211     }
212     return SOFTBUS_OK;
213 }
214 
BleRegisterServerCallback(int status,int serverId,BtUuid * appUuid)215 NO_SANITIZE("cfi") static void BleRegisterServerCallback(int status, int serverId, BtUuid *appUuid)
216 {
217     CLOGI("BleRegisterServerCallback status=%d severId=%d", status, serverId);
218     if ((appUuid == NULL) || (appUuid->uuid == NULL)) {
219         CLOGE("BleRegisterServerCallback appUuid is null");
220         return;
221     }
222 
223     if (memcmp(appUuid->uuid, SOFTBUS_APP_UUID, appUuid->uuidLen) != 0) {
224         CLOGE("BleRegisterServerCallback unknown uuid");
225         return;
226     }
227 
228     if (status != SOFTBUS_OK) {
229         CLOGE("BleRegisterServerCallback failed, status=%d", status);
230         g_halRegFlag = -1;
231     } else {
232         g_halRegFlag = 1;
233         g_halServerId = serverId;
234         CLOGI("BLEINFOPRTINT:BleRegisterServerCallback g_halServerId:%d)", g_halServerId);
235     }
236 }
237 
BleConnectServerCallback(int connId,int serverId,const BdAddr * bdAddr)238 NO_SANITIZE("cfi") static void BleConnectServerCallback(int connId, int serverId, const BdAddr *bdAddr)
239 {
240     CLOGI("ConnectServerCallback is coming, connId=%d serverId=%d\n", connId, serverId);
241     if (serverId != g_halServerId) {
242         return;
243     }
244     g_gattsCallback->ConnectServerCallback(connId, (const SoftBusBtAddr*)bdAddr);
245 }
246 
BleDisconnectServerCallback(int connId,int serverId,const BdAddr * bdAddr)247 NO_SANITIZE("cfi") static void BleDisconnectServerCallback(int connId, int serverId, const BdAddr *bdAddr)
248 {
249     CLOGI("DisconnectServerCallback is coming, connId=%d severId=%d", connId, serverId);
250     if (serverId != g_halServerId) {
251         return;
252     }
253     g_gattsCallback->DisconnectServerCallback(connId, (const SoftBusBtAddr*)bdAddr);
254 }
255 
BleServiceAddCallback(int status,int serverId,BtUuid * uuid,int srvcHandle)256 NO_SANITIZE("cfi") static void BleServiceAddCallback(int status, int serverId, BtUuid *uuid, int srvcHandle)
257 {
258     (void)serverId;
259     CLOGI("ServiceAddCallback srvcHandle=%d\n", srvcHandle);
260     if (serverId != g_halServerId) {
261         return;
262     }
263     CLOGI("BLEINFOPRTINT:BleServiceAddCallback srvcHandle:%d)", srvcHandle);
264     g_gattsCallback->ServiceAddCallback(status, (SoftBusBtUuid *)uuid, srvcHandle);
265 }
266 
BleIncludeServiceAddCallback(int status,int serverId,int srvcHandle,int includeSrvcHandle)267 NO_SANITIZE("cfi") static void BleIncludeServiceAddCallback(int status, int serverId, int srvcHandle,
268     int includeSrvcHandle)
269 {
270     (void)serverId;
271     (void)srvcHandle;
272     CLOGI("IncludeServiceAddCallback srvcHandle=%d,includeSrvcHandle=%d\n", srvcHandle, includeSrvcHandle);
273 }
274 
BleCharacteristicAddCallback(int status,int serverId,BtUuid * uuid,int srvcHandle,int characteristicHandle)275 NO_SANITIZE("cfi") static void BleCharacteristicAddCallback(int status, int serverId, BtUuid *uuid, int srvcHandle,
276     int characteristicHandle)
277 {
278     CLOGI("CharacteristicAddCallback srvcHandle=%d,charHandle=%d\n", srvcHandle, characteristicHandle);
279     if (serverId != g_halServerId) {
280         CLOGE("bad server id");
281         return;
282     }
283     CLOGI("BLEINFOPRTINT:BleCharacteristicAddCallback characteristicHandle:%d)", characteristicHandle);
284     g_gattsCallback->CharacteristicAddCallback(status, (SoftBusBtUuid *)uuid, srvcHandle, characteristicHandle);
285 }
286 
BleDescriptorAddCallback(int status,int serverId,BtUuid * uuid,int srvcHandle,int descriptorHandle)287 NO_SANITIZE("cfi") static void BleDescriptorAddCallback(int status, int serverId, BtUuid *uuid,
288     int srvcHandle, int descriptorHandle)
289 {
290     CLOGI("DescriptorAddCallback srvcHandle=%d,descriptorHandle=%d", srvcHandle, descriptorHandle);
291     if (serverId != g_halServerId) {
292         return;
293     }
294     CLOGI("BLEINFOPRTINT:BleDescriptorAddCallback descriptorHandle:%d)", descriptorHandle);
295     g_gattsCallback->DescriptorAddCallback(status, (SoftBusBtUuid *)uuid, srvcHandle, descriptorHandle);
296 }
297 
BleServiceStartCallback(int status,int serverId,int srvcHandle)298 NO_SANITIZE("cfi") static void BleServiceStartCallback(int status, int serverId, int srvcHandle)
299 {
300     CLOGI("ServiceStartCallback serverId=%d,srvcHandle=%d\n", serverId, srvcHandle);
301     if (serverId != g_halServerId) {
302         return;
303     }
304     CLOGI("BLEINFOPRTINT:BleServiceStartCallback srvcHandle:%d)", srvcHandle);
305     g_gattsCallback->ServiceStartCallback(status, srvcHandle);
306 }
307 
BleServiceStopCallback(int status,int serverId,int srvcHandle)308 NO_SANITIZE("cfi") static void BleServiceStopCallback(int status, int serverId, int srvcHandle)
309 {
310     CLOGI("ServiceStopCallback serverId=%d,srvcHandle=%d\n", serverId, srvcHandle);
311     if (serverId != g_halServerId) {
312         return;
313     }
314     g_gattsCallback->ServiceStopCallback(status, srvcHandle);
315 }
316 
BleServiceDeleteCallback(int status,int serverId,int srvcHandle)317 NO_SANITIZE("cfi") static void BleServiceDeleteCallback(int status, int serverId, int srvcHandle)
318 {
319     CLOGI("ServiceDeleteCallback serverId=%d,srvcHandle=%d\n", serverId, srvcHandle);
320     if (serverId != g_halServerId) {
321         return;
322     }
323     g_gattsCallback->ServiceDeleteCallback(status, srvcHandle);
324 }
325 
BleRequestReadCallback(BtReqReadCbPara readCbPara)326 NO_SANITIZE("cfi") static void BleRequestReadCallback(BtReqReadCbPara readCbPara)
327 {
328     CLOGI("RequestReadCallback transId=%d, attrHandle=%d\n", readCbPara.transId, readCbPara.attrHandle);
329     SoftBusGattReadRequest req = {
330         .connId = readCbPara.connId,
331         .transId = readCbPara.transId,
332         .btAddr = (SoftBusBtAddr *)readCbPara.bdAddr,
333         .attrHandle = readCbPara.attrHandle,
334         .offset = readCbPara.offset,
335         .isLong = readCbPara.isLong
336     };
337     g_gattsCallback->RequestReadCallback(req);
338 }
339 
BleRequestWriteCallback(BtReqWriteCbPara writeCbPara)340 NO_SANITIZE("cfi") static void BleRequestWriteCallback(BtReqWriteCbPara writeCbPara)
341 {
342     CLOGI("RequestWriteCallback transId=%d, attrHandle=%d\n", writeCbPara.transId, writeCbPara.attrHandle);
343     SoftBusGattWriteRequest req = {
344         .connId = writeCbPara.connId,
345         .transId = writeCbPara.transId,
346         .btAddr = (SoftBusBtAddr *)writeCbPara.bdAddr,
347         .attrHandle = writeCbPara.attrHandle,
348         .offset = writeCbPara.offset,
349         .length = writeCbPara.length,
350         .needRsp = writeCbPara.needRsp,
351         .isPrep = writeCbPara.isPrep,
352         .value = writeCbPara.value
353     };
354     g_gattsCallback->RequestWriteCallback(req);
355 }
356 
BleResponseConfirmationCallback(int status,int handle)357 NO_SANITIZE("cfi") static void BleResponseConfirmationCallback(int status, int handle)
358 {
359     CLOGI("ResponseConfirmationCallback status=%d, handle=%d\n", status, handle);
360     g_gattsCallback->ResponseConfirmationCallback(status, handle);
361 }
362 
BleIndicationSentCallback(int connId,int status)363 NO_SANITIZE("cfi") static void BleIndicationSentCallback(int connId, int status)
364 {
365     CLOGI("IndicationSentCallback status=%d, connId=%d\n", status, connId);
366     g_gattsCallback->NotifySentCallback(connId, status);
367 }
368 
BleMtuChangeCallback(int connId,int mtu)369 NO_SANITIZE("cfi") static void BleMtuChangeCallback(int connId, int mtu)
370 {
371     CLOGI("MtuChangeCallback connId=%d, mtu=%d\n", connId, mtu);
372     g_gattsCallback->MtuChangeCallback(connId, mtu);
373 }
374 
GattsRegisterHalCallback(void)375 static int GattsRegisterHalCallback(void)
376 {
377     g_bleGattsHalCallback.registerServerCb = BleRegisterServerCallback;
378     g_bleGattsHalCallback.connectServerCb = BleConnectServerCallback;
379     g_bleGattsHalCallback.disconnectServerCb = BleDisconnectServerCallback;
380     g_bleGattsHalCallback.serviceAddCb = BleServiceAddCallback;
381     g_bleGattsHalCallback.includeServiceAddCb = BleIncludeServiceAddCallback;
382     g_bleGattsHalCallback.characteristicAddCb = BleCharacteristicAddCallback;
383     g_bleGattsHalCallback.descriptorAddCb = BleDescriptorAddCallback;
384     g_bleGattsHalCallback.serviceStartCb = BleServiceStartCallback;
385     g_bleGattsHalCallback.serviceStopCb = BleServiceStopCallback;
386     g_bleGattsHalCallback.serviceDeleteCb = BleServiceDeleteCallback;
387     g_bleGattsHalCallback.requestReadCb = BleRequestReadCallback;
388     g_bleGattsHalCallback.requestWriteCb = BleRequestWriteCallback;
389     g_bleGattsHalCallback.responseConfirmationCb = BleResponseConfirmationCallback;
390     g_bleGattsHalCallback.indicationSentCb = BleIndicationSentCallback;
391     g_bleGattsHalCallback.mtuChangeCb = BleMtuChangeCallback;
392     return BleGattsRegisterCallbacks(&g_bleGattsHalCallback);
393 }
394 
SoftBusRegisterGattsCallbacks(SoftBusGattsCallback * callback)395 NO_SANITIZE("cfi") int SoftBusRegisterGattsCallbacks(SoftBusGattsCallback *callback)
396 {
397     if (callback == NULL) {
398         CLOGE("SoftBusRegisterGattsCallbacks fail:nullptr");
399         return SOFTBUS_BLECONNECTION_REG_GATTS_CALLBACK_FAIL;
400     }
401     if (g_gattsCallback != NULL) {
402         CLOGW("SoftBusRegisterGattsCallbacks register again");
403     } else {
404         g_gattsCallback = callback;
405     }
406     int ret = GattsRegisterHalCallback();
407     if (ret != SOFTBUS_OK) {
408         CLOGE("SoftBusRegisterGattsCallbacks GattsRegisterCallbacks failed:%d", ret);
409         return SOFTBUS_BLECONNECTION_REG_GATTS_CALLBACK_FAIL;
410     }
411     if (g_halRegFlag == -1) {
412         BtUuid uuid;
413         uuid.uuid = (char *)SOFTBUS_APP_UUID;
414         uuid.uuidLen = sizeof(SOFTBUS_APP_UUID);
415         g_halRegFlag = 0;
416         ret = BleGattsRegister(uuid);
417         if (ret != SOFTBUS_OK) {
418             g_halRegFlag = -1;
419             CLOGE("BleGattsRegister failed%d", ret);
420             return SOFTBUS_BLECONNECTION_REG_GATTS_CALLBACK_FAIL;
421         }
422     }
423     return SOFTBUS_OK;
424 }
425 
SoftBusUnRegisterGattsCallbacks(void)426 NO_SANITIZE("cfi") void SoftBusUnRegisterGattsCallbacks(void)
427 {
428     if (g_gattsCallback == NULL) {
429         CLOGI("no need to unregist gatts callback.");
430         return;
431     }
432     if (g_halRegFlag == -1) {
433         CLOGI("no need to unregist gatt server.");
434         return;
435     }
436     if (BleGattsUnRegister(g_halServerId) != SOFTBUS_OK) {
437         CLOGE("BleGattsUnRegister error.");
438         return;
439     }
440     g_halServerId = -1;
441     g_halRegFlag = -1;
442 }
443