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_clientDevice.h"
17
18 #include "bluetooth_ble_common.h"
19 #include "bluetooth_errorcode.h"
20 #include "bluetooth_host.h"
21 #include "bluetooth_log.h"
22 #include "cj_lambda.h"
23
24 namespace OHOS {
25 namespace CJSystemapi {
26 namespace CJBluetoothBle {
27 using Bluetooth::BluetoothHost;
28 using Bluetooth::BT_ERR_INTERNAL_ERROR;
29 using Bluetooth::BT_NO_ERROR;
30 using Bluetooth::BT_TRANSPORT_BLE;
31 using Bluetooth::GATT_TRANSPORT_TYPE_LE;
32 using Bluetooth::UUID;
33
Connect()34 int32_t FfiClientDevice::Connect()
35 {
36 if (client_ == nullptr) {
37 return BT_ERR_INTERNAL_ERROR;
38 }
39 return client_->Connect(callback_, false, GATT_TRANSPORT_TYPE_LE);
40 }
41
Disconnect()42 int32_t FfiClientDevice::Disconnect()
43 {
44 if (client_ == nullptr) {
45 return BT_ERR_INTERNAL_ERROR;
46 }
47 return client_->Disconnect();
48 }
49
Close()50 int32_t FfiClientDevice::Close()
51 {
52 if (client_ == nullptr) {
53 return BT_ERR_INTERNAL_ERROR;
54 }
55 return client_->Close();
56 }
57
GetDeviceName(int32_t * errCode)58 std::string FfiClientDevice::GetDeviceName(int32_t *errCode)
59 {
60 std::string deviceName = "";
61 std::string deviceAddr = GetGattClientDeviceId();
62 *errCode = BluetoothHost::GetDefaultHost().GetRemoteDevice(deviceAddr, BT_TRANSPORT_BLE).GetDeviceName(deviceName);
63
64 HILOGI("err: %{public}d, deviceName: %{public}s", *errCode, deviceName.c_str());
65 return deviceName;
66 }
67
GetServices(CArrGattService & service)68 int32_t FfiClientDevice::GetServices(CArrGattService &service)
69 {
70 if (client_ == nullptr) {
71 return BT_ERR_INTERNAL_ERROR;
72 }
73 int ret = client_->DiscoverServices();
74 if (ret == BT_NO_ERROR) {
75 HILOGI("start get services");
76 std::vector<GattService> nativeServices = client_->GetService();
77 service = Convert2CArrGattService(nativeServices);
78 }
79 return ret;
80 }
81
GetCharacteristic(const std::shared_ptr<GattClient> & client,const UUID & serviceUuid,const UUID & characterUuid)82 static GattCharacteristic *GetCharacteristic(const std::shared_ptr<GattClient> &client, const UUID &serviceUuid,
83 const UUID &characterUuid)
84 {
85 GattCharacteristic *character = nullptr;
86 if (client) {
87 auto service = client->GetService(serviceUuid);
88 if (service.has_value()) {
89 character = service->get().GetCharacteristic(characterUuid);
90 }
91 }
92 return character;
93 }
94
GetGattcCharacteristic(const std::shared_ptr<GattClient> & client,NativeBLECharacteristic & nativeCharacteristic)95 static GattCharacteristic *GetGattcCharacteristic(const std::shared_ptr<GattClient> &client,
96 NativeBLECharacteristic &nativeCharacteristic)
97 {
98 GattCharacteristic *character = GetCharacteristic(client, UUID::FromString(nativeCharacteristic.serviceUuid),
99 UUID::FromString(nativeCharacteristic.characteristicUuid));
100 if (character) {
101 character->SetValue(nativeCharacteristic.characteristicValue.head,
102 nativeCharacteristic.characteristicValue.size);
103 }
104 return character;
105 }
106
ReadCharacteristicValue(NativeBLECharacteristic & characteristic,void (* callback)())107 int32_t FfiClientDevice::ReadCharacteristicValue(NativeBLECharacteristic &characteristic, void (*callback)())
108 {
109 GattCharacteristic *character = GetGattcCharacteristic(client_, characteristic);
110
111 if (character == nullptr) {
112 HILOGE("character is nullptr");
113 return BT_ERR_INTERNAL_ERROR;
114 }
115 int ret = BT_ERR_INTERNAL_ERROR;
116 if (client_) {
117 ret = client_->ReadCharacteristic(*character);
118 }
119 if (ret != BT_NO_ERROR) {
120 return ret;
121 }
122 auto readCharacteristicFunc = CJLambda::Create(reinterpret_cast<void (*)(RetNativeBLECharacteristic)>(callback));
123 callback_->RegisterReadCharacteristicCallback(readCharacteristicFunc);
124 return BT_NO_ERROR;
125 }
126
GetGattcDescriptor(const std::shared_ptr<GattClient> & client,const NativeBLEDescriptor & nativeDescriptor)127 static GattDescriptor *GetGattcDescriptor(const std::shared_ptr<GattClient> &client,
128 const NativeBLEDescriptor &nativeDescriptor)
129 {
130 GattDescriptor *descriptor = nullptr;
131 if (client) {
132 auto *character = GetCharacteristic(client, UUID::FromString(nativeDescriptor.serviceUuid),
133 UUID::FromString(nativeDescriptor.characteristicUuid));
134 if (character == nullptr) {
135 HILOGE("character is nullptr");
136 return nullptr;
137 }
138 descriptor = character->GetDescriptor(UUID::FromString(nativeDescriptor.descriptorUuid));
139 if (descriptor) {
140 descriptor->SetValue(nativeDescriptor.descriptorValue.head, nativeDescriptor.descriptorValue.size);
141 }
142 }
143 return descriptor;
144 }
145
ReadDescriptorValue(NativeBLEDescriptor & inputDescriptor,void (* callback)())146 int32_t FfiClientDevice::ReadDescriptorValue(NativeBLEDescriptor &inputDescriptor, void (*callback)())
147 {
148 GattDescriptor *descriptor = GetGattcDescriptor(client_, inputDescriptor);
149
150 if (descriptor == nullptr) {
151 HILOGE("descriptor is nullptr");
152 return BT_ERR_INTERNAL_ERROR;
153 }
154 int ret = BT_ERR_INTERNAL_ERROR;
155 if (client_) {
156 ret = client_->ReadDescriptor(*descriptor);
157 }
158 if (ret != BT_NO_ERROR) {
159 return ret;
160 }
161 auto readDescriptorFunc = CJLambda::Create(reinterpret_cast<void (*)(RetNativeBLEDescriptor)>(callback));
162 callback_->RegisterReadDescriptorCallback(readDescriptorFunc);
163 return BT_NO_ERROR;
164 }
165
WriteCharacteristicValue(NativeBLECharacteristic characteristic,int32_t writeType,void (* callback)())166 int32_t FfiClientDevice::WriteCharacteristicValue(NativeBLECharacteristic characteristic, int32_t writeType,
167 void (*callback)())
168 {
169 GattCharacteristic *character = GetGattcCharacteristic(client_, characteristic);
170 std::vector<uint8_t> value{};
171
172 if (character == nullptr) {
173 HILOGE("character is nullptr");
174 return BT_ERR_INTERNAL_ERROR;
175 }
176 character->SetWriteType(writeType);
177
178 int ret = BT_ERR_INTERNAL_ERROR;
179 if (client_) {
180 ret = client_->WriteCharacteristic(*character);
181 }
182 if (ret != BT_NO_ERROR) {
183 return ret;
184 }
185 auto writeCharacteristicFunc = CJLambda::Create(reinterpret_cast<void (*)(int32_t)>(callback));
186 callback_->RegisterWriteCharacteristicCallback(writeCharacteristicFunc);
187 return BT_NO_ERROR;
188 }
189
WriteDescriptorValue(NativeBLEDescriptor inputDescriptor,void (* callback)())190 int32_t FfiClientDevice::WriteDescriptorValue(NativeBLEDescriptor inputDescriptor, void (*callback)())
191 {
192 GattDescriptor *descriptor = GetGattcDescriptor(client_, inputDescriptor);
193
194 if (descriptor == nullptr) {
195 HILOGE("descriptor is nullptr");
196 return BT_ERR_INTERNAL_ERROR;
197 }
198 int ret = BT_ERR_INTERNAL_ERROR;
199 if (client_) {
200 ret = client_->WriteDescriptor(*descriptor);
201 }
202 if (ret != BT_NO_ERROR) {
203 return ret;
204 }
205 auto writeDescriptorValueFunc = CJLambda::Create(reinterpret_cast<void (*)(int32_t)>(callback));
206 callback_->RegisterWriteDescriptorCallback(writeDescriptorValueFunc);
207 return BT_NO_ERROR;
208 }
209
GetRssiValue(void (* callback)())210 int32_t FfiClientDevice::GetRssiValue(void (*callback)())
211 {
212 int ret = BT_ERR_INTERNAL_ERROR;
213 if (client_) {
214 ret = client_->ReadRemoteRssiValue();
215 }
216 if (ret != BT_NO_ERROR) {
217 return ret;
218 }
219 auto getRssiValueFunc = CJLambda::Create(reinterpret_cast<void (*)(RetDataI32)>(callback));
220 callback_->RegisterGetRemoteRssicallback(getRssiValueFunc);
221 return BT_NO_ERROR;
222 }
223
SetBLEMtuSize(int32_t mut)224 int32_t FfiClientDevice::SetBLEMtuSize(int32_t mut)
225 {
226 int ret = client_->RequestBleMtuSize(mut);
227 return ret;
228 }
229
SetCharacteristicChangeNotification(NativeBLECharacteristic characteristic,bool enable)230 int32_t FfiClientDevice::SetCharacteristicChangeNotification(NativeBLECharacteristic characteristic, bool enable)
231 {
232 GattCharacteristic *character = GetGattcCharacteristic(client_, characteristic);
233 if (character == nullptr) {
234 HILOGE("character is nullptr");
235 return BT_ERR_INTERNAL_ERROR;
236 }
237 int ret = BT_ERR_INTERNAL_ERROR;
238 if (client_) {
239 ret = client_->SetNotifyCharacteristic(*character, enable);
240 }
241 return ret;
242 }
243
SetCharacteristicChangeIndication(NativeBLECharacteristic characteristic,bool enable)244 int32_t FfiClientDevice::SetCharacteristicChangeIndication(NativeBLECharacteristic characteristic, bool enable)
245 {
246 GattCharacteristic *character = GetGattcCharacteristic(client_, characteristic);
247 if (character == nullptr) {
248 HILOGE("character is nullptr");
249 return BT_ERR_INTERNAL_ERROR;
250 }
251 int ret = BT_ERR_INTERNAL_ERROR;
252 if (client_) {
253 ret = client_->SetIndicateCharacteristic(*character, enable);
254 }
255 return ret;
256 }
257
RegisterBleGattClientDeviceObserver(int32_t callbackType,void (* callback)())258 int32_t FfiClientDevice::RegisterBleGattClientDeviceObserver(int32_t callbackType, void (*callback)())
259 {
260 if (callbackType == BLE_CHARACTERISTIC_CHANGE) {
261 auto bleCharacteristicChangeFunc =
262 CJLambda::Create(reinterpret_cast<void (*)(NativeBLECharacteristic)>(callback));
263 if (!bleCharacteristicChangeFunc) {
264 HILOGD("Register bleCharacteristicChange event failed");
265 return BT_ERR_INTERNAL_ERROR;
266 }
267 callback_->RegisterBLECharacteristicChangeFunc(bleCharacteristicChangeFunc);
268 return BT_NO_ERROR;
269 }
270
271 if (callbackType == BLE_CONNECTION_STATE_CHANGE) {
272 auto bleConnectionStateChangeFunc =
273 CJLambda::Create(reinterpret_cast<void (*)(NativeBLEConnectionChangeState)>(callback));
274 if (!bleConnectionStateChangeFunc) {
275 HILOGD("Register bleConnectionStateChange event failed");
276 return BT_ERR_INTERNAL_ERROR;
277 }
278 callback_->RegisterBLEConnectionStateChangeFunc(bleConnectionStateChangeFunc);
279 return BT_NO_ERROR;
280 }
281
282 if (callbackType == CLIENT_BLE_MTU_CHANGE) {
283 auto bleMtuChangeFunc = CJLambda::Create(reinterpret_cast<void (*)(int32_t)>(callback));
284 if (!bleMtuChangeFunc) {
285 HILOGD("Register bleMtuChange event failed");
286 return BT_ERR_INTERNAL_ERROR;
287 }
288 callback_->RegisterBLEMtuChangeFunc(bleMtuChangeFunc);
289 return BT_NO_ERROR;
290 }
291
292 return BT_NO_ERROR;
293 }
294 } // namespace CJBluetoothBle
295 } // namespace CJSystemapi
296 } // namespace OHOS