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