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