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