• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 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 "ohos_bt_gatt_server.h"
17 
18 #include <iostream>
19 #include <string.h>
20 #include <vector>
21 #include <map>
22 
23 #include "ohos_bt_adapter_utils.h"
24 #include "bluetooth_gatt_server.h"
25 #include "bluetooth_log.h"
26 #include "bluetooth_utils.h"
27 
28 #include "securec.h"
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 using namespace std;
35 
36 namespace OHOS {
37 namespace Bluetooth {
38 static BtGattServerCallbacks *g_GattsCallback;
39 
40 struct ConnectedDevice {
41     int serverId;
42     BdAddr remoteAddr;
43 };
44 static int g_connId = 0;
45 
46 static std::map<int, struct ConnectedDevice> g_MapConnectedDevice;
47 
48 #define MAXIMUM_NUMBER_APPLICATION 64
49 #define MAXIMUM_NUMBER_GATTSERVICE 64
50 struct GattServiceWapper {
51     GattService *gattService;
52     int index;
53     int maxNum;
54     int handleOffset;
55     bool isAdding;
56 };
57 
58 struct GattServerWapper {
59     GattServer *gattServer;
60     struct GattServiceWapper gattServices[MAXIMUM_NUMBER_GATTSERVICE];
61 };
62 
63 GattServerWapper g_gattServers[MAXIMUM_NUMBER_APPLICATION];
64 
65 #define GATTSERVER(x) g_gattServers[x].gattServer
66 #define GATTSERVICES(x, y) g_gattServers[x].gattServices[y]
67 #define GATTSERVICE(x, y) GATTSERVICES(x, y).gattService
68 
69 static GattCharacteristic *FindCharacteristic(int serverId, int attrHandle, bool isOffset, int *srvcHandle);
70 
71 class GattServerCallbackWapper : public GattServerCallback {
72 public:
GattServerCallbackWapper(BtGattServerCallbacks * callback,int serverId)73     GattServerCallbackWapper(BtGattServerCallbacks *callback, int serverId)
74     {
75         appCallback_ = callback;
76         serverId_ = serverId;
77     }
78 
OnConnectionStateUpdate(const BluetoothRemoteDevice & device,int state)79     void OnConnectionStateUpdate(const BluetoothRemoteDevice &device, int state)
80     {
81         struct ConnectedDevice dev;
82         dev.serverId = serverId_;
83         GetAddrFromString(device.GetDeviceAddr(), dev.remoteAddr.addr);
84         HILOGI("device: %{public}s, connect state: %{public}d", GET_ENCRYPT_ADDR(device), state);
85 
86         if (state == static_cast<int>(BTConnectState::CONNECTED)) {
87             if (g_GattsCallback == nullptr || g_GattsCallback->connectServerCb == nullptr) {
88                 HILOGW("call back is null.");
89                 return;
90             }
91             std::map<int, struct ConnectedDevice>::iterator iter;
92             iter = FindDeviceRecord(dev);
93             if (iter != g_MapConnectedDevice.end()) {
94                 HILOGW("device already in maps! connId: %{public}d", iter->first);
95                 g_GattsCallback->connectServerCb(iter->first, serverId_, &dev.remoteAddr);
96             } else {
97                 g_MapConnectedDevice.insert(std::pair<int, struct ConnectedDevice>(g_connId, dev));
98                 HILOGI("device connected. connId: %{public}d", g_connId);
99                 g_GattsCallback->connectServerCb(g_connId, serverId_, &dev.remoteAddr);
100                 g_connId++;
101             }
102         }
103 
104         if (state == static_cast<int>(BTConnectState::DISCONNECTED)) {
105             if (g_GattsCallback == nullptr || g_GattsCallback->disconnectServerCb == nullptr) {
106                 HILOGW("call back is null.");
107                 return;
108             }
109             std::map<int, struct ConnectedDevice>::iterator iter;
110             iter = FindDeviceRecord(dev);
111             if (iter != g_MapConnectedDevice.end()) {
112                 HILOGI("device disconnected. connId: %{public}d", iter->first);
113                 g_GattsCallback->disconnectServerCb(iter->first, serverId_, &dev.remoteAddr);
114                 g_MapConnectedDevice.erase(iter);
115             }
116         }
117     }
118 
OnServiceAdded(GattService * Service,int ret)119     NO_SANITIZE("cfi") void OnServiceAdded(GattService *Service, int ret)
120     {
121         int i;
122         int err = OHOS_BT_STATUS_SUCCESS;
123         for (i = 0; i < MAXIMUM_NUMBER_GATTSERVICE; i++) {
124             if (GATTSERVICE(serverId_, i) != nullptr) {
125                 HILOGI("isAdding: %{public}d, srvcUuid: %{public}s, ind: %{public}s",
126                     GATTSERVICES(serverId_, i).isAdding,
127                     GATTSERVICE(serverId_, i)->GetUuid().ToString().c_str(),
128                     Service->GetUuid().ToString().c_str());
129             } else {
130                 HILOGE("services is empty!");
131             }
132             if (GATTSERVICE(serverId_, i) != nullptr &&
133                 GATTSERVICES(serverId_, i).isAdding &&
134                 GATTSERVICE(serverId_, i)->GetUuid().CompareTo(Service->GetUuid()) == 0) {
135                 GATTSERVICES(serverId_, i).isAdding = false;
136                 GATTSERVICES(serverId_, i).handleOffset = Service->GetHandle() - i;
137                 HILOGI("serverId: %{public}d, service handle is: %{public}d, offset: %{public}d",
138                     serverId_, GATTSERVICE(serverId_, i)->GetHandle(), GATTSERVICES(serverId_, i).handleOffset);
139                 break;
140             }
141         }
142 
143         if (i == MAXIMUM_NUMBER_GATTSERVICE) {
144             HILOGE("add service failed, invalid srvcHandle: %{public}u", Service->GetHandle());
145             err = OHOS_BT_STATUS_FAIL;
146         }
147 
148         vector<GattCharacteristic> &characteristics = Service->GetCharacteristics();
149         for (auto item = characteristics.begin(); item != characteristics.end(); item++) {
150             HILOGI("charHandle: %{public}d, uuid: %{public}s",
151                 item->GetHandle(), item->GetUuid().ToString().c_str());
152             vector<GattDescriptor> &descriptors = item->GetDescriptors();
153             for (auto des = descriptors.begin(); des != descriptors.end(); des++) {
154                 HILOGI("desHandle: %{public}d, uuid: %{public}s", des->GetHandle(), des->GetUuid().ToString().c_str());
155             }
156         }
157 
158         if (g_GattsCallback != nullptr && g_GattsCallback->serviceStartCb != nullptr) {
159             g_GattsCallback->serviceStartCb(err, serverId_, i);
160         } else {
161             HILOGW("call back is null.");
162         }
163     }
164 
OnCharacteristicReadRequest(const BluetoothRemoteDevice & device,GattCharacteristic & characteristic,int requestId)165     void OnCharacteristicReadRequest(
166         const BluetoothRemoteDevice &device, GattCharacteristic &characteristic, int requestId)
167     {
168         struct ConnectedDevice dev;
169         dev.serverId = serverId_;
170         GetAddrFromString(device.GetDeviceAddr(), dev.remoteAddr.addr);
171 
172         std::map<int, struct ConnectedDevice>::iterator iter;
173         iter = FindDeviceRecord(dev);
174 
175         int srvcHandle = 0;
176         FindCharacteristic(serverId_, characteristic.GetHandle(), true, &srvcHandle);
177 
178         BtReqReadCbPara readInfo;
179         readInfo.connId = iter->first;
180         readInfo.transId = requestId;
181         readInfo.bdAddr = &dev.remoteAddr;
182         readInfo.attrHandle = characteristic.GetHandle() - GATTSERVICES(serverId_, srvcHandle).handleOffset;
183         readInfo.offset = 0;
184         readInfo.isLong = false;
185         HILOGI("connId: %{public}d, requestId: %{public}d, attrHandle: %{public}d",
186             iter->first, requestId, readInfo.attrHandle);
187         if (g_GattsCallback != nullptr && g_GattsCallback->requestReadCb != nullptr) {
188             g_GattsCallback->requestReadCb(readInfo);
189         } else {
190             HILOGW("call back is null.");
191         }
192     }
193 
OnCharacteristicWriteRequest(const BluetoothRemoteDevice & device,GattCharacteristic & characteristic,int requestId)194     void OnCharacteristicWriteRequest(
195         const BluetoothRemoteDevice &device, GattCharacteristic &characteristic, int requestId)
196     {
197         struct ConnectedDevice dev;
198         dev.serverId = serverId_;
199         GetAddrFromString(device.GetDeviceAddr(), dev.remoteAddr.addr);
200 
201         std::map<int, struct ConnectedDevice>::iterator iter;
202         iter = FindDeviceRecord(dev);
203 
204         int srvcHandle = 0;
205         FindCharacteristic(serverId_, characteristic.GetHandle(), true, &srvcHandle);
206 
207         BtReqWriteCbPara writeInfo;
208         size_t length = 0;
209         writeInfo.connId = iter->first;
210         writeInfo.transId = requestId;
211         writeInfo.bdAddr = &dev.remoteAddr;
212         writeInfo.attrHandle = characteristic.GetHandle() - GATTSERVICES(serverId_, srvcHandle).handleOffset;
213         writeInfo.offset = 0;
214         writeInfo.value = characteristic.GetValue(&length).get();
215         writeInfo.length = length;
216         writeInfo.needRsp = (characteristic.GetWriteType() == GattCharacteristic::WriteType::DEFAULT);
217         writeInfo.isPrep = false;
218         HILOGI("connId: %{public}d, requestId: %{public}d, attrHandle: %{public}d, valueLen: %{public}d",
219             iter->first, requestId, writeInfo.attrHandle, writeInfo.length);
220         if (g_GattsCallback != nullptr && g_GattsCallback->requestWriteCb != nullptr) {
221             g_GattsCallback->requestWriteCb(writeInfo);
222         } else {
223             HILOGW("call back is null.");
224         }
225     }
226 
OnDescriptorReadRequest(const BluetoothRemoteDevice & device,GattDescriptor & descriptor,int requestId)227     void OnDescriptorReadRequest(const BluetoothRemoteDevice &device, GattDescriptor &descriptor, int requestId)
228     {
229         struct ConnectedDevice dev;
230         dev.serverId = serverId_;
231         GetAddrFromString(device.GetDeviceAddr(), dev.remoteAddr.addr);
232 
233         std::map<int, struct ConnectedDevice>::iterator iter;
234         iter = FindDeviceRecord(dev);
235 
236         const GattCharacteristic *characteristic = descriptor.GetCharacteristic();
237         int srvcHandle = 0;
238         FindCharacteristic(serverId_, characteristic->GetHandle(), true, &srvcHandle);
239 
240         BtReqReadCbPara readInfo;
241         readInfo.connId = iter->first;
242         readInfo.transId = requestId;
243         readInfo.bdAddr = &dev.remoteAddr;
244         readInfo.attrHandle = descriptor.GetHandle() - GATTSERVICES(serverId_, srvcHandle).handleOffset;
245         readInfo.offset = 0;
246         readInfo.isLong = false;
247         if (g_GattsCallback != nullptr && g_GattsCallback->requestReadCb != nullptr) {
248             g_GattsCallback->requestReadCb(readInfo);
249         } else {
250             HILOGW("call back is null.");
251         }
252     }
253 
OnDescriptorWriteRequest(const BluetoothRemoteDevice & device,GattDescriptor & descriptor,int requestId)254     void OnDescriptorWriteRequest(
255         const BluetoothRemoteDevice &device, GattDescriptor &descriptor, int requestId)
256     {
257         struct ConnectedDevice dev;
258         dev.serverId = serverId_;
259         GetAddrFromString(device.GetDeviceAddr(), dev.remoteAddr.addr);
260 
261         std::map<int, struct ConnectedDevice>::iterator iter;
262         iter = FindDeviceRecord(dev);
263 
264         const GattCharacteristic *characteristic = descriptor.GetCharacteristic();
265         int srvcHandle = 0;
266         FindCharacteristic(serverId_, characteristic->GetHandle(), true, &srvcHandle);
267 
268         BtReqWriteCbPara writeInfo;
269         size_t length = 0;
270         writeInfo.connId = iter->first;
271         writeInfo.transId = requestId;
272         writeInfo.bdAddr = &dev.remoteAddr;
273         writeInfo.attrHandle = descriptor.GetHandle() - GATTSERVICES(serverId_, srvcHandle).handleOffset;
274         writeInfo.offset = 0;
275         writeInfo.value = descriptor.GetValue(&length).get();
276         writeInfo.length = length;
277         writeInfo.needRsp = true;
278         writeInfo.isPrep = false;
279         if (g_GattsCallback != nullptr && g_GattsCallback->requestWriteCb != nullptr) {
280             g_GattsCallback->requestWriteCb(writeInfo);
281         } else {
282             HILOGW("call back is null.");
283         }
284     }
285 
OnMtuUpdate(const BluetoothRemoteDevice & device,int mtu)286     void OnMtuUpdate(const BluetoothRemoteDevice &device, int mtu)
287     {
288         HILOGI("mtu: %{public}d", mtu);
289         struct ConnectedDevice dev;
290         dev.serverId = serverId_;
291         GetAddrFromString(device.GetDeviceAddr(), dev.remoteAddr.addr);
292 
293         std::map<int, struct ConnectedDevice>::iterator iter;
294         iter = FindDeviceRecord(dev);
295         if (g_GattsCallback != nullptr && g_GattsCallback->mtuChangeCb != nullptr) {
296             g_GattsCallback->mtuChangeCb(iter->first, mtu);
297         } else {
298             HILOGW("call back is null.");
299         }
300     }
301 
OnNotificationCharacteristicChanged(const BluetoothRemoteDevice & device,int result)302     void OnNotificationCharacteristicChanged(const BluetoothRemoteDevice &device, int result)
303     {
304         HILOGI("result: %{public}d", result);
305         struct ConnectedDevice dev;
306         dev.serverId = serverId_;
307         GetAddrFromString(device.GetDeviceAddr(), dev.remoteAddr.addr);
308 
309         std::map<int, struct ConnectedDevice>::iterator iter;
310         iter = FindDeviceRecord(dev);
311         if (g_GattsCallback != nullptr && g_GattsCallback->indicationSentCb != nullptr) {
312             g_GattsCallback->indicationSentCb(iter->first, result);
313         } else {
314             HILOGW("call back is null.");
315         }
316     }
317 
OnConnectionParameterChanged(const BluetoothRemoteDevice & device,int interval,int latency,int timeout,int status)318     void OnConnectionParameterChanged(
319         const BluetoothRemoteDevice &device, int interval, int latency, int timeout, int status)
320     {
321         HILOGI("enter");
322     }
323 
324 private:
FindDeviceRecord(struct ConnectedDevice & device)325     std::map<int, struct ConnectedDevice>::iterator FindDeviceRecord(struct ConnectedDevice &device)
326     {
327         std::map<int, struct ConnectedDevice>::iterator iter;
328         for (iter = g_MapConnectedDevice.begin(); iter != g_MapConnectedDevice.end(); iter++) {
329             struct ConnectedDevice value = iter->second;
330             if (value.serverId == device.serverId &&
331                 memcmp(value.remoteAddr.addr, device.remoteAddr.addr, sizeof(value.remoteAddr.addr)) == 0) {
332                 return iter;
333             }
334         }
335         return iter;
336     }
337 
338     BtGattServerCallbacks *appCallback_;
339     int serverId_;
340 };
341 
FindCharacteristic(int serverId,int attrHandle,bool isOffset,int * srvcHandle)342 static GattCharacteristic *FindCharacteristic(int serverId, int attrHandle, bool isOffset, int *srvcHandle)
343 {
344     if (srvcHandle == nullptr) {
345         return nullptr;
346     }
347     for (int i = 0; i < MAXIMUM_NUMBER_GATTSERVICE; i++) {
348         GattService *gattService = GATTSERVICE(serverId, i);
349         if (gattService == nullptr) {
350             continue;
351         }
352 
353         std::vector<GattCharacteristic> &gattCharacteristics = gattService->GetCharacteristics();
354 
355         for (auto &character : gattCharacteristics) {
356             if (character.GetHandle() == attrHandle) {
357                 *srvcHandle = i;
358                 return &character;
359             }
360         }
361     }
362     return nullptr;
363 }
364 
365 /**
366  * @brief Registers a GATT server with a specified application UUID.
367  *
368  * The <b>RegisterServerCallback</b> is invoked to return the GATT server ID.
369  *
370  * @param appUuid Indicates the UUID of the application for which the GATT server is to be registered.
371  * The UUID is defined by the application.
372  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the GATT server is registered;
373  * returns an error code defined in {@link BtStatus} otherwise.
374  * @since 6
375  */
BleGattsRegister(BtUuid appUuid)376 NO_SANITIZE("cfi") int BleGattsRegister(BtUuid appUuid)
377 {
378     HILOGI("enter");
379     if (g_GattsCallback == nullptr) {
380         HILOGE("callback is null, call BleGattsRegisterCallbacks first");
381         return OHOS_BT_STATUS_FAIL;
382     }
383     for (int i = 0; i < MAXIMUM_NUMBER_APPLICATION; i++) {
384         if (GATTSERVER(i) == nullptr) {
385             GattServerCallbackWapper *callbackWapper = new GattServerCallbackWapper(g_GattsCallback, i);
386             GATTSERVER(i) = new GattServer(*callbackWapper);
387             HILOGI("register gattServer: %{public}d", i);
388             if (g_GattsCallback->registerServerCb != nullptr) {
389                 g_GattsCallback->registerServerCb(0, i, &appUuid);
390             }
391             return OHOS_BT_STATUS_SUCCESS;
392         }
393     }
394 
395     if (g_GattsCallback->registerServerCb != nullptr) {
396         g_GattsCallback->registerServerCb(1, 0, &appUuid);
397     }
398     return OHOS_BT_STATUS_FAIL;
399 }
400 
401 /**
402  * @brief Unregisters a GATT server with a specified ID.
403  *
404  * @param serverId Indicates the ID of the GATT server.
405  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the GATT server is unregistered;
406  * returns an error code defined in {@link BtStatus} otherwise.
407  * @since 6
408  */
BleGattsUnRegister(int serverId)409 int BleGattsUnRegister(int serverId)
410 {
411     HILOGI("serverId: %{public}d", serverId);
412     if (serverId >= 0 && serverId < MAXIMUM_NUMBER_APPLICATION) {
413         if (GATTSERVER(serverId) != nullptr) {
414             delete GATTSERVER(serverId);
415             GATTSERVER(serverId) = nullptr;
416             return OHOS_BT_STATUS_SUCCESS;
417         }
418     }
419 
420     return OHOS_BT_STATUS_FAIL;
421 }
422 
423 /**
424  * @brief Disconnects the GATT server from the client.
425  *
426  * @param serverId Indicates the ID of the GATT server.
427  * @param bdAddr Indicates the address of the client.
428  * @param connId Indicates the connection ID, which is returned during the server registration.
429  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the GATT server is disconnected from the client;
430  * returns an error code defined in {@link BtStatus} otherwise.
431  * @since 6
432  */
BleGattsDisconnect(int serverId,BdAddr bdAddr,int connId)433 int BleGattsDisconnect(int serverId, BdAddr bdAddr, int connId)
434 {
435     HILOGI("serverId: %{public}d, connId: %{public}d", serverId, connId);
436     if (serverId >= MAXIMUM_NUMBER_APPLICATION || serverId < 0) {
437         return OHOS_BT_STATUS_PARM_INVALID;
438     }
439 
440     if (GATTSERVER(serverId) == nullptr) {
441         return OHOS_BT_STATUS_UNHANDLED;
442     }
443 
444     string strAddress;
445     GetAddrFromByte(bdAddr.addr, strAddress);
446     BluetoothRemoteDevice device(strAddress, BT_TRANSPORT_BLE);
447 
448     GATTSERVER(serverId)->CancelConnection(device);
449     return OHOS_BT_STATUS_SUCCESS;
450 }
451 
452 /**
453  * @brief Adds a service.
454  *
455  * This function adds the service, its characteristics, and descriptors separately in sequence.\n
456  * A service is a collection of data and related behavior that enable a specific capability or feature.\n
457  * It consists of a service declaration and one or more included services and characteristics.
458  *
459  * @param serverId Indicates the ID of the GATT server.
460  * @param srvcUuid Indicates the UUID of the service.
461  * @param isPrimary Specifies whether the service is primary or secondary.
462  * Value <b>true</b> indicates that the service is primary, and <b>false</b> indicates that the service is secondary.
463  * @param number Indicates the number of attribute handles.
464  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the service is added;
465  * returns an error code defined in {@link BtStatus} otherwise.
466  * @since 6
467  */
BleGattsAddService(int serverId,BtUuid srvcUuid,bool isPrimary,int number)468 NO_SANITIZE("cfi") int BleGattsAddService(int serverId, BtUuid srvcUuid, bool isPrimary, int number)
469 {
470     HILOGI("enter");
471     string strUuid(srvcUuid.uuid);
472     if (!regex_match(strUuid, uuidRegex)) {
473         HILOGE("match the UUID faild.");
474         return OHOS_BT_STATUS_PARM_INVALID;
475     }
476     UUID uuid(UUID::FromString(strUuid));
477 
478     for (int i = 0; i < MAXIMUM_NUMBER_GATTSERVICE; i++) {
479         if (GATTSERVICE(serverId, i) == nullptr) {
480             HILOGI("add srvcHandle: %{public}d", i);
481             GATTSERVICE(serverId, i) = new GattService(
482                 uuid, i, number, isPrimary ? GattServiceType::PRIMARY : GattServiceType::SECONDARY);
483             GATTSERVICES(serverId, i).maxNum = number;
484             GATTSERVICES(serverId, i).index = i + 1;
485             GATTSERVICES(serverId, i).isAdding = false;
486             if (g_GattsCallback != nullptr && g_GattsCallback->serviceAddCb != nullptr) {
487                 g_GattsCallback->serviceAddCb(0, serverId, &srvcUuid, i);
488             } else {
489                 HILOGW("call back is null");
490             }
491             return OHOS_BT_STATUS_SUCCESS;
492         }
493     }
494     return OHOS_BT_STATUS_FAIL;
495 }
496 
497 /**
498  * @brief Adds an included service to a specified service.
499  *
500  * An included service is referenced to define another service on the GATT server.
501  *
502  * @param serverId Indicates the ID of the GATT server.
503  * @param srvcHandle Indicates the handle ID of the service.
504  * @param includedHandle Indicates the attribute handle ID of the included service.
505  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the included service is added to the service;
506  * returns an error code defined in {@link BtStatus} otherwise.
507  * @since 6
508  */
BleGattsAddIncludedService(int serverId,int srvcHandle,int includedHandle)509 int BleGattsAddIncludedService(int serverId, int srvcHandle, int includedHandle)
510 {
511     return OHOS_BT_STATUS_UNSUPPORTED;
512 }
513 
ConvertPermissions(int permission)514 static int ConvertPermissions(int permission)
515 {
516     int newPermission = 0;
517 
518     if ((permission & OHOS_GATT_PERMISSION_READ) == OHOS_GATT_PERMISSION_READ) {
519         newPermission = static_cast<int>(GattPermission::READABLE);
520     }
521 
522     if ((permission & OHOS_GATT_PERMISSION_WRITE) == OHOS_GATT_PERMISSION_WRITE) {
523         newPermission += static_cast<int>(GattPermission::WRITABLE);
524     }
525 
526     return newPermission;
527 }
528 
529 /**
530  * @brief Adds a characteristic to a specified service.
531  *
532  * A characteristic consists of data, the data access method, data format, and how the data manifests itself.
533  *
534  * @param serverId Indicates the ID of the GATT server.
535  * @param srvcHandle Indicates the handle ID of the service.
536  * @param characUuid Indicates the UUID of the characteristic to add.
537  * @param properties Indicates the access methods supported by the characteristic,
538  * as enumerated in {@link GattCharacteristicProperty}.
539  * @param permissions Indicates the access permissions supported by the characteristic,
540  * as enumerated in {@link GattAttributePermission}.
541  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the characteristic is added to the service;
542  * returns an error code defined in {@link BtStatus} otherwise.
543  * @since 6
544  */
BleGattsAddCharacteristic(int serverId,int srvcHandle,BtUuid characUuid,int properties,int permissions)545 NO_SANITIZE("cfi") int BleGattsAddCharacteristic(int serverId, int srvcHandle, BtUuid characUuid,
546                               int properties, int permissions)
547 {
548     HILOGI("properties: %{public}d, permissions:%{public}d", properties, permissions);
549     string strUuid(characUuid.uuid);
550     if (!regex_match(strUuid, uuidRegex)) {
551         HILOGE("match the UUID faild.");
552         return OHOS_BT_STATUS_PARM_INVALID;
553     }
554     UUID uuid(UUID::FromString(strUuid));
555 
556     int chHandle = GATTSERVICES(serverId, srvcHandle).index;
557     GATTSERVICES(serverId, srvcHandle).index += 2;
558     GattCharacteristic characteristic(uuid, chHandle, ConvertPermissions(permissions), properties);
559 
560     unsigned char stubValue[1] = {0x31};
561     characteristic.SetValue(stubValue, sizeof(stubValue));
562     GATTSERVICE(serverId, srvcHandle)->AddCharacteristic(characteristic);
563 
564     HILOGI("serverId: %{public}d, srvcHandle: %{public}d, charHandle: %{public}d", serverId, srvcHandle, chHandle);
565     if (g_GattsCallback != nullptr && g_GattsCallback->characteristicAddCb != nullptr) {
566         g_GattsCallback->characteristicAddCb(0, serverId, &characUuid, srvcHandle, chHandle);
567     } else {
568         HILOGW("callback is null.");
569     }
570     return OHOS_BT_STATUS_SUCCESS;
571 }
572 
573 /**
574  * @brief Adds a descriptor to a specified characteristic.
575  *
576  * A descriptor contains the description, configuration, and format of a characteristic.
577  *
578  * @param serverId Indicates the ID of the GATT server.
579  * @param srvcHandle Indicates the handle ID of the service to which the characteristic belongs.
580  * @param descUuid Indicates the UUID of the descriptor to add.
581  * @param permissions Indicates the access permissions supported by the descriptor,
582  * as enumerated in {@link GattAttributePermission}.
583  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the descriptor is added to the characteristic;
584  * returns an error code defined in {@link BtStatus} otherwise.
585  * @since 6
586  */
BleGattsAddDescriptor(int serverId,int srvcHandle,BtUuid descUuid,int permissions)587 NO_SANITIZE("cfi") int BleGattsAddDescriptor(int serverId, int srvcHandle, BtUuid descUuid, int permissions)
588 {
589     string strUuid(descUuid.uuid);
590     HILOGI("descUuid: %{public}s", strUuid.c_str());
591     if (!regex_match(strUuid, uuidRegex)) {
592         HILOGE("match the UUID faild.");
593         return OHOS_BT_STATUS_PARM_INVALID;
594     }
595     UUID uuid(UUID::FromString(strUuid));
596     GattCharacteristic &characteristic = GATTSERVICE(serverId, srvcHandle)->GetCharacteristics().back();
597     int desHandle = GATTSERVICES(serverId, srvcHandle).index++;
598     GattDescriptor descriptor(uuid, desHandle, ConvertPermissions(permissions));
599 
600     unsigned char stubValue[2] = {0x01, 0x00};
601     descriptor.SetValue(stubValue, sizeof(stubValue));
602 
603     characteristic.AddDescriptor(descriptor);
604     HILOGI("serverId: %{public}d, srvcHandle: %{public}d, desHandle: %{public}d", serverId, srvcHandle, desHandle);
605     if (g_GattsCallback != nullptr && g_GattsCallback->descriptorAddCb != nullptr) {
606         g_GattsCallback->descriptorAddCb(0, serverId, &descUuid, srvcHandle, desHandle);
607     } else {
608         HILOGW("callback is null.");
609     }
610 
611     return OHOS_BT_STATUS_SUCCESS;
612 }
613 
614 /**
615  * @brief Starts a service.
616  *
617  * @param serverId Indicates the ID of the GATT server.
618  * @param srvcHandle Indicates the handle ID of the service.
619  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the service is started;
620  * returns an error code defined in {@link BtStatus} otherwise.
621  * @since 6
622  */
BleGattsStartService(int serverId,int srvcHandle)623 int BleGattsStartService(int serverId, int srvcHandle)
624 {
625     HILOGI("serverId: %{public}d, srvcHandle: %{public}d, uuid: %{public}s",
626         serverId, srvcHandle, GATTSERVICE(serverId, srvcHandle)->GetUuid().ToString().c_str());
627     GATTSERVICES(serverId, srvcHandle).isAdding = true;
628     GATTSERVER(serverId)->AddService(*GATTSERVICE(serverId, srvcHandle));
629     return OHOS_BT_STATUS_SUCCESS;
630 }
631 
632 /**
633  * @brief Stops a service.
634  *
635  * @param serverId Indicates the ID of the GATT server.
636  * @param srvcHandle Indicates the handle ID of the service.
637  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the service is stopped;
638  * returns an error code defined in {@link BtStatus} otherwise.
639  * @since 6
640  */
BleGattsStopService(int serverId,int srvcHandle)641 int BleGattsStopService(int serverId, int srvcHandle)
642 {
643     HILOGI("serverId: %{public}d, srvcHandle: %{public}d", serverId, srvcHandle);
644     GATTSERVICES(serverId, srvcHandle).isAdding = false;
645     GATTSERVER(serverId)->RemoveGattService(*GATTSERVICE(serverId, srvcHandle));
646     if (g_GattsCallback != nullptr && g_GattsCallback->serviceStopCb != nullptr) {
647         g_GattsCallback->serviceStopCb(OHOS_BT_STATUS_SUCCESS, serverId, srvcHandle);
648     } else {
649         HILOGW("callback is null.");
650     }
651     return OHOS_BT_STATUS_SUCCESS;
652 }
653 
654 /**
655  * @brief Deletes a service.
656  *
657  * @param serverId Indicates the ID of the GATT server.
658  * @param srvcHandle Indicates the handle ID of the service.
659  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the service is deleted;
660  * returns an error code defined in {@link BtStatus} otherwise.
661  * @since 6
662  */
BleGattsDeleteService(int serverId,int srvcHandle)663 NO_SANITIZE("cfi") int BleGattsDeleteService(int serverId, int srvcHandle)
664 {
665     HILOGI("serverId: %{public}d, srvcHandle: %{public}d", serverId, srvcHandle);
666     GATTSERVER(serverId)->RemoveGattService(*GATTSERVICE(serverId, srvcHandle));
667     delete GATTSERVICE(serverId, srvcHandle);
668     GATTSERVICE(serverId, srvcHandle) = nullptr;
669     if (g_GattsCallback != nullptr && g_GattsCallback->serviceDeleteCb != nullptr) {
670         g_GattsCallback->serviceDeleteCb(OHOS_BT_STATUS_SUCCESS, serverId, srvcHandle);
671     } else {
672         HILOGW("callback is null.");
673     }
674     return OHOS_BT_STATUS_SUCCESS;
675 }
676 
677 /**
678  * @brief Clears all services.
679  *
680  * @param serverId Indicates the ID of the GATT server.
681  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the services are cleared;
682  * returns an error code defined in {@link BtStatus} otherwise.
683  * @since 6
684  */
BleGattsClearServices(int serverId)685 int BleGattsClearServices(int serverId) {
686     HILOGI("serverId: %{public}d", serverId);
687     return OHOS_BT_STATUS_SUCCESS;
688 }
689 
690 /**
691  * @brief Sends a response to the client from which a read or write request has been received.
692  *
693  * @param serverId Indicates the ID of the GATT server.
694  * @param param Indicates the pointer to the response parameters. For details, see {@link GattsSendRspParam}.
695  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the response is sent;
696  * returns an error code defined in {@link BtStatus} otherwise.
697  * @since 6
698  */
BleGattsSendResponse(int serverId,GattsSendRspParam * param)699 int BleGattsSendResponse(int serverId, GattsSendRspParam *param)
700 {
701     if (param == nullptr) {
702         HILOGE("param is null, serverId: %{public}d", serverId);
703         return OHOS_BT_STATUS_FAIL;
704     }
705     HILOGI("serverId:%{public}d, attrHandle:%{public}d, valueLen:%{public}d",
706         serverId, param->attrHandle, param->valueLen);
707     std::map<int, struct ConnectedDevice>::iterator iter;
708     iter = g_MapConnectedDevice.find(param->connectId);
709 
710     struct ConnectedDevice value = iter->second;
711 
712     string strAddress;
713     GetAddrFromByte(value.remoteAddr.addr, strAddress);
714 
715     BluetoothRemoteDevice device(strAddress, 1);
716 
717     int ret = GATTSERVER(serverId)->SendResponse(device, param->attrHandle,
718         param->status, 0, (unsigned char *)param->value, param->valueLen);
719 
720     if (g_GattsCallback != nullptr && g_GattsCallback->responseConfirmationCb != nullptr) {
721         g_GattsCallback->responseConfirmationCb(ret, param->attrHandle);
722     } else {
723         HILOGW("callback is null.");
724     }
725     return OHOS_BT_STATUS_SUCCESS;
726 }
727 
728 /**
729  * @brief Sends an indication or notification to the client.
730  *
731  * The <b>confirm</b> field in <b>param</b> determines whether to send an indication or a notification.
732  *
733  * @param serverId Indicates the ID of the GATT server.
734  * @param param Indicates the pointer to the sending parameters. For details, see {@link GattsSendIndParam}.
735  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the indication or notification is sent;
736  * returns an error code defined in {@link BtStatus} otherwise.
737  * @since 6
738  */
BleGattsSendIndication(int serverId,GattsSendIndParam * param)739 int BleGattsSendIndication(int serverId, GattsSendIndParam *param)
740 {
741     if (param == nullptr) {
742         HILOGE("param is null, serverId: %{public}d", serverId);
743         return OHOS_BT_STATUS_FAIL;
744     }
745     HILOGI("serverId: %{public}d, attrHandle:%{public}d, confirm:%{public}d, valueLen:%{public}d",
746         serverId, param->attrHandle, param->confirm, param->valueLen);
747     std::map<int, struct ConnectedDevice>::iterator iter;
748     iter = g_MapConnectedDevice.find(param->connectId);
749 
750     struct ConnectedDevice value = iter->second;
751 
752     string strAddress;
753     GetAddrFromByte(value.remoteAddr.addr, strAddress);
754     HILOGI("device: %{public}s", GetEncryptAddr(strAddress).c_str());
755     BluetoothRemoteDevice device(strAddress, 1);
756 
757     int srvcHandle = 0;
758     GattCharacteristic *appCharacteristic = FindCharacteristic(serverId, param->attrHandle, false, &srvcHandle);
759     if (appCharacteristic == nullptr) {
760         HILOGE("not find characteristic");
761         return OHOS_BT_STATUS_FAIL;
762     }
763 
764     HILOGI("srvcHandle:%{public}d", srvcHandle);
765     GattCharacteristic characteristic(appCharacteristic->GetUuid(),
766         appCharacteristic->GetHandle() + GATTSERVICES(serverId, srvcHandle).handleOffset,
767         appCharacteristic->GetPermissions(),
768         appCharacteristic->GetProperties());
769 
770     characteristic.SetValue((unsigned char*)param->value, param->valueLen);
771 
772     GATTSERVER(serverId)->NotifyCharacteristicChanged(device, characteristic,
773         (param->confirm == 1) ? true : false);
774     return OHOS_BT_STATUS_SUCCESS;
775 }
776 
777 /**
778  * @brief Sets the encryption type for the GATT connection.
779  *
780  * @param bdAddr Indicates the address of the client.
781  * @param secAct Indicates the encryption type, as enumerated in {@link BleSecAct}.
782  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the encryption type is set;
783  * returns an error code defined in {@link BtStatus} otherwise.
784  * @since 6
785  */
BleGattsSetEncryption(BdAddr bdAddr,BleSecAct secAct)786 int BleGattsSetEncryption(BdAddr bdAddr, BleSecAct secAct) {
787     return OHOS_BT_STATUS_UNSUPPORTED;
788 }
789 
790 /**
791  * @brief Registers GATT server callbacks.
792  *
793  * @param func Indicates the pointer to the callbacks to register, as enumerated in {@link BtGattServerCallbacks}.
794  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the callbacks are registered;
795  * returns an error code defined in {@link BtStatus} otherwise.
796  * @since 6
797  */
BleGattsRegisterCallbacks(BtGattServerCallbacks * func)798 int BleGattsRegisterCallbacks(BtGattServerCallbacks *func)
799 {
800     HILOGI("enter");
801     if (func == nullptr) {
802         HILOGE("func is null.");
803         return OHOS_BT_STATUS_PARM_INVALID;
804     }
805 
806     g_GattsCallback = func;
807     return OHOS_BT_STATUS_SUCCESS;
808 }
809 
810 /**
811  * @brief Adds a service, its characteristics, and descriptors and starts the service.
812  *
813  * This function is available for system applications only.
814  *
815  * @param srvcHandle Indicates the pointer to the handle ID of the service,
816  * which is returned by whoever implements this function.
817  * @param srvcInfo Indicates the pointer to the service information.
818  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the operation is successful;
819  * returns an error code defined in {@link BtStatus} otherwise.
820  * @since 6
821  */
BleGattsStartServiceEx(int * srvcHandle,BleGattService * srvcInfo)822 int BleGattsStartServiceEx(int *srvcHandle, BleGattService *srvcInfo) {
823     return OHOS_BT_STATUS_UNSUPPORTED;
824 }
825 
826 /**
827  * @brief Stops a service.
828  *
829  * This function is available for system applications only.
830  *
831  * @param srvcHandle Indicates the handle ID of the service.
832  * @return Returns {@link OHOS_BT_STATUS_SUCCESS} if the operation is successful;
833  * returns an error code defined in {@link BtStatus} otherwise.
834  * @since 6
835  */
BleGattsStopServiceEx(int srvcHandle)836 int BleGattsStopServiceEx(int srvcHandle) {
837     return OHOS_BT_STATUS_UNSUPPORTED;
838 }
839 }  // namespace Bluetooth
840 }  // namespace OHOS
841 
842 #ifdef __cplusplus
843 }
844 #endif
845 /** @} */
846