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