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