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