• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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