1 /*
2 * Copyright (c) 2024 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 "bluetooth_ble_gattServer.h"
17
18 #include "bluetooth_ble_common.h"
19 #include "bluetooth_errorcode.h"
20 #include "bluetooth_gatt_service.h"
21 #include "bluetooth_log.h"
22 #include "cj_lambda.h"
23
24 namespace OHOS {
25 namespace CJSystemapi {
26 namespace CJBluetoothBle {
27 using Bluetooth::BT_ERR_INTERNAL_ERROR;
28 using Bluetooth::BT_ERR_INVALID_PARAM;
29 using Bluetooth::BT_NO_ERROR;
30 using Bluetooth::BTTransport;
31 using Bluetooth::GattServiceType;
32 using Bluetooth::UUID;
33
CheckGattsAddService(NativeGattService service,std::unique_ptr<GattService> & outService)34 static int CheckGattsAddService(NativeGattService service, std::unique_ptr<GattService> &outService)
35 {
36 GattServiceType type = service.isPrimary ? GattServiceType::PRIMARY : GattServiceType::SECONDARY;
37 outService = std::make_unique<GattService>(UUID::FromString(service.serviceUuid), type);
38
39 CArrBLECharacteristic characteristics = service.characteristics;
40 for (int64_t i = 0; i < characteristics.size; i++) {
41 NativeBLECharacteristic nativeCharacter = characteristics.head[i];
42
43 NativeGattPermission permissions = {
44 .readable = true,
45 .writeable = true,
46 };
47 int charPermissions = ConvertGattPermissions(permissions);
48 int charProperties = ConvertGattProperties(nativeCharacter.properties);
49 GattCharacteristic character(UUID::FromString(nativeCharacter.characteristicUuid), charPermissions,
50 charProperties);
51 character.SetValue(nativeCharacter.characteristicValue.head, nativeCharacter.characteristicValue.size);
52
53 CArrBLEDescriptor descriptors = nativeCharacter.descriptors;
54 for (int64_t j = 0; j < descriptors.size; j++) {
55 NativeBLEDescriptor nativeDescriptor = descriptors.head[j];
56 GattDescriptor descriptor(UUID::FromString(nativeDescriptor.descriptorUuid), 0);
57 descriptor.SetValue(nativeDescriptor.descriptorValue.head, nativeDescriptor.descriptorValue.size);
58 character.AddDescriptor(descriptor);
59 }
60 outService->AddCharacteristic(character);
61 }
62 return BT_NO_ERROR;
63 }
64
AddService(NativeGattService service)65 int32_t FfiGattServer::AddService(NativeGattService service)
66 {
67 std::unique_ptr<GattService> gattService{nullptr};
68 auto status = CheckGattsAddService(service, gattService);
69 if (status != BT_NO_ERROR) {
70 return status;
71 }
72 if (server_ == nullptr) {
73 return BT_ERR_INTERNAL_ERROR;
74 }
75 int ret = server_->AddService(*gattService);
76 return ret;
77 }
78
RemoveService(std::string serviceUuid)79 int32_t FfiGattServer::RemoveService(std::string serviceUuid)
80 {
81 UUID realServiceUuid = UUID::FromString(serviceUuid);
82 int ret = BT_ERR_INTERNAL_ERROR;
83 if (server_ == nullptr) {
84 return ret;
85 }
86 auto primaryService = server_->GetService(realServiceUuid, true);
87 if (primaryService.has_value()) {
88 ret = server_->RemoveGattService(*primaryService);
89 if (ret != BT_NO_ERROR) {
90 return ret;
91 }
92 }
93 auto secondService = server_->GetService(realServiceUuid, false);
94 if (secondService.has_value()) {
95 ret = server_->RemoveGattService(*secondService);
96 if (ret != BT_NO_ERROR) {
97 return ret;
98 }
99 }
100 return ret;
101 }
102
Close()103 int32_t FfiGattServer::Close()
104 {
105 if (server_ == nullptr) {
106 return BT_ERR_INTERNAL_ERROR;
107 }
108 return server_->Close();
109 }
110
GetGattCharacteristic(const std::shared_ptr<GattServer> & server,const UUID & serviceUuid,const UUID & characterUuid)111 static GattCharacteristic *GetGattCharacteristic(const std::shared_ptr<GattServer> &server, const UUID &serviceUuid,
112 const UUID &characterUuid)
113 {
114 auto service = server->GetService(serviceUuid, true);
115 if (!service.has_value()) {
116 service = server->GetService(serviceUuid, false);
117 }
118 if (!service.has_value()) {
119 HILOGE("not found service uuid: %{public}s", serviceUuid.ToString().c_str());
120 return nullptr;
121 }
122 GattCharacteristic *character = service.value().get().GetCharacteristic(characterUuid);
123 return character;
124 }
125
NotifyCharacteristicChanged(std::string deviceId,NativeNotifyCharacteristic characteristic)126 int32_t FfiGattServer::NotifyCharacteristicChanged(std::string deviceId, NativeNotifyCharacteristic characteristic)
127 {
128 if (server_ == nullptr) {
129 return BT_ERR_INTERNAL_ERROR;
130 }
131 auto character = GetGattCharacteristic(server_, UUID::FromString(characteristic.serviceUuid),
132 UUID::FromString(characteristic.characteristicUuid));
133 if (character == nullptr) {
134 return BT_ERR_INVALID_PARAM;
135 }
136 character->SetValue(characteristic.characteristicValue.head, characteristic.characteristicValue.size);
137 BluetoothRemoteDevice remoteDevice(deviceId, BTTransport::ADAPTER_BLE);
138 int ret = server_->NotifyCharacteristicChanged(remoteDevice, *character, characteristic.confirm);
139 return ret;
140 }
141
SendResponse(NativeServerResponse serverResponse)142 int32_t FfiGattServer::SendResponse(NativeServerResponse serverResponse)
143 {
144 BluetoothRemoteDevice remoteDevice(serverResponse.deviceId, BTTransport::ADAPTER_BLE);
145 if (server_ == nullptr) {
146 return BT_ERR_INTERNAL_ERROR;
147 }
148 return server_->SendResponse(remoteDevice, serverResponse.transId, serverResponse.status, serverResponse.offset,
149 serverResponse.value.head, static_cast<int>(serverResponse.value.size));
150 ;
151 }
152
CreateCharacteristicReadFunc(void (* callback)())153 int32_t FfiGattServer::CreateCharacteristicReadFunc(void (*callback)())
154 {
155 auto characteristicReadFunc =
156 CJLambda::Create(reinterpret_cast<void (*)(NativeCharacteristicReadRequest)>(callback));
157 if (!characteristicReadFunc) {
158 HILOGD("Register characteristicRead event failed");
159 return BT_ERR_INTERNAL_ERROR;
160 }
161 callback_->RegisterCharacteristicReadFunc(characteristicReadFunc);
162 return BT_NO_ERROR;
163 }
164
CreateCharacteristicWriteFunc(void (* callback)())165 int32_t FfiGattServer::CreateCharacteristicWriteFunc(void (*callback)())
166 {
167 auto characteristicWriteFunc =
168 CJLambda::Create(reinterpret_cast<void (*)(NativeCharacteristicWriteRequest)>(callback));
169 if (!characteristicWriteFunc) {
170 HILOGD("Register characteristicWrite event failed");
171 return BT_ERR_INTERNAL_ERROR;
172 }
173 callback_->RegisterCharacteristicWriteFunc(characteristicWriteFunc);
174 return BT_NO_ERROR;
175 }
176
CreateDescriptorReadFunc(void (* callback)())177 int32_t FfiGattServer::CreateDescriptorReadFunc(void (*callback)())
178 {
179 auto descriptorReadFunc = CJLambda::Create(reinterpret_cast<void (*)(NativeDescriptorReadRequest)>(callback));
180 if (!descriptorReadFunc) {
181 HILOGD("Register descriptorRead event failed");
182 return BT_ERR_INTERNAL_ERROR;
183 }
184 callback_->RegisterDescriptorReadFunc(descriptorReadFunc);
185 return BT_NO_ERROR;
186 }
187
CreateRegisterDescriptorWriteFunc(void (* callback)())188 int32_t FfiGattServer::CreateRegisterDescriptorWriteFunc(void (*callback)())
189 {
190 auto descriptorWriteFunc = CJLambda::Create(reinterpret_cast<void (*)(NativeDescriptorWriteRequest)>(callback));
191 if (!descriptorWriteFunc) {
192 HILOGD("Register descriptorWrite event failed");
193 return BT_ERR_INTERNAL_ERROR;
194 }
195 callback_->RegisterDescriptorWriteFunc(descriptorWriteFunc);
196 return BT_NO_ERROR;
197 }
198
CreateConnectionStateChangeFunc(void (* callback)())199 int32_t FfiGattServer::CreateConnectionStateChangeFunc(void (*callback)())
200 {
201 auto connectionStateChangeFunc =
202 CJLambda::Create(reinterpret_cast<void (*)(NativeBLEConnectionChangeState)>(callback));
203 if (!connectionStateChangeFunc) {
204 HILOGD("Register connectionStateChange event failed");
205 return BT_ERR_INTERNAL_ERROR;
206 }
207 callback_->RegisterConnectionStateChangeFunc(connectionStateChangeFunc);
208 return BT_NO_ERROR;
209 }
210
CreateBLEMtuChangeFunc(void (* callback)())211 int32_t FfiGattServer::CreateBLEMtuChangeFunc(void (*callback)())
212 {
213 auto bleMtuChangeFunc = CJLambda::Create(reinterpret_cast<void (*)(int32_t)>(callback));
214 if (!bleMtuChangeFunc) {
215 HILOGD("Register bleMtuChange event failed");
216 return BT_ERR_INTERNAL_ERROR;
217 }
218 callback_->RegisterBLEMtuChangeFunc(bleMtuChangeFunc);
219 return BT_NO_ERROR;
220 }
221
RegisterBleGattServerObserver(int32_t callbackType,void (* callback)())222 int32_t FfiGattServer::RegisterBleGattServerObserver(int32_t callbackType, void (*callback)())
223 {
224 if (callbackType == CHARACTERISTIC_READ) {
225 return CreateCharacteristicReadFunc(callback);
226 }
227
228 if (callbackType == CHARACTERISTIC_WRITE) {
229 return CreateCharacteristicWriteFunc(callback);
230 }
231
232 if (callbackType == DESCRIPTOR_READ) {
233 return CreateDescriptorReadFunc(callback);
234 }
235
236 if (callbackType == DESCRIPTOR_WRITE) {
237 return CreateRegisterDescriptorWriteFunc(callback);
238 }
239
240 if (callbackType == CONNECTION_STATE_CHANGE) {
241 return CreateConnectionStateChangeFunc(callback);
242 }
243
244 if (callbackType == SERVER_BLE_MTU_CHANGE) {
245 return CreateBLEMtuChangeFunc(callback);
246 }
247
248 return BT_NO_ERROR;
249 }
250
251 std::vector<std::string> FfiGattServer::deviceList_;
252 std::mutex FfiGattServer::deviceListMutex_;
253 } // namespace CJBluetoothBle
254 } // namespace CJSystemapi
255 } // namespace OHOS