1 /*
2 * Copyright (C) 2023 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 #include <uv.h>
16 #include "bluetooth_log.h"
17 #include "napi_async_work.h"
18 #include "napi_bluetooth_event.h"
19 #include "napi_bluetooth_gatt_client.h"
20 #include "napi_bluetooth_gatt_client_callback.h"
21 #include "bluetooth_errorcode.h"
22
23 namespace OHOS {
24 namespace Bluetooth {
25 std::shared_mutex NapiGattClientCallback::g_gattClientCallbackInfosMutex;
26
OnCharacteristicChanged(const GattCharacteristic & characteristic)27 void NapiGattClientCallback::OnCharacteristicChanged(const GattCharacteristic &characteristic)
28 {
29 auto status = napi_acquire_threadsafe_function(onBleCharacterChangedThreadSafeFunc_);
30 if (status != napi_ok) {
31 HILOGE("napi_acquire_threadsafe_function failed, status: %{public}d", status);
32 return;
33 }
34
35 GattCharacteristic *character = new GattCharacteristic(characteristic);
36 status = napi_call_threadsafe_function(
37 onBleCharacterChangedThreadSafeFunc_, static_cast<void *>(character), napi_tsfn_blocking);
38 if (status != napi_ok) {
39 HILOGE("napi_call_threadsafe_function failed, status: %{public}d", status);
40 delete character;
41 return;
42 }
43
44 status = napi_release_threadsafe_function(onBleCharacterChangedThreadSafeFunc_, napi_tsfn_release);
45 if (status != napi_ok) {
46 HILOGE("napi_release_threadsafe_function failed, status: %{public}d", status);
47 return;
48 }
49 }
50
OnCharacteristicReadResult(const GattCharacteristic & characteristic,int ret)51 void NapiGattClientCallback::OnCharacteristicReadResult(const GattCharacteristic &characteristic, int ret)
52 {
53 HILOGI("UUID: %{public}s, ret: %{public}d", characteristic.GetUuid().ToString().c_str(), ret);
54 auto napiCharacter = std::make_shared<NapiNativeBleCharacteristic>(characteristic);
55 AsyncWorkCallFunction(asyncWorkMap_, NapiAsyncType::GATT_CLIENT_READ_CHARACTER, napiCharacter, ret);
56 }
57
OnDescriptorReadResult(const GattDescriptor & descriptor,int ret)58 void NapiGattClientCallback::OnDescriptorReadResult(const GattDescriptor &descriptor, int ret)
59 {
60 HILOGI("UUID: %{public}s, ret: %{public}d", descriptor.GetUuid().ToString().c_str(), ret);
61 auto napiDescriptor = std::make_shared<NapiNativeBleDescriptor>(descriptor);
62 AsyncWorkCallFunction(asyncWorkMap_, NapiAsyncType::GATT_CLIENT_READ_DESCRIPTOR, napiDescriptor, ret);
63 }
64
OnConnectionStateChanged(int connectionState,int ret)65 void NapiGattClientCallback::OnConnectionStateChanged(int connectionState, int ret)
66 {
67 std::unique_lock<std::shared_mutex> guard(g_gattClientCallbackInfosMutex);
68 std::map<std::string, std::shared_ptr<BluetoothCallbackInfo>>::iterator it =
69 callbackInfos_.find(STR_BT_GATT_CLIENT_CALLBACK_BLE_CONNECTIION_STATE_CHANGE);
70 if (it == callbackInfos_.end() || it->second == nullptr) {
71 HILOGI("This callback is not registered by ability.");
72 return;
73 }
74 std::shared_ptr<BluetoothCallbackInfo> callbackInfo = it->second;
75 HILOGI("connectionState:%{public}d, ret:%{public}d", connectionState, ret);
76 callbackInfo->state_ = connectionState;
77 callbackInfo->deviceId_ = client_->GetDevice()->GetDeviceAddr();
78 NapiEvent::CheckAndNotify(callbackInfo, callbackInfo->state_);
79 }
80
OnServicesDiscovered(int status)81 void NapiGattClientCallback::OnServicesDiscovered(int status)
82 {
83 HILOGI("status:%{public}d", status);
84 }
85
OnReadRemoteRssiValueResult(int rssi,int ret)86 void NapiGattClientCallback::OnReadRemoteRssiValueResult(int rssi, int ret)
87 {
88 HILOGI("rssi: %{public}d, ret: %{public}d", rssi, ret);
89 auto napiRssi = std::make_shared<NapiNativeInt>(rssi);
90 AsyncWorkCallFunction(asyncWorkMap_, NapiAsyncType::GATT_CLIENT_READ_REMOTE_RSSI_VALUE, napiRssi, ret);
91 }
92
OnCharacteristicWriteResult(const GattCharacteristic & characteristic,int ret)93 void NapiGattClientCallback::OnCharacteristicWriteResult(const GattCharacteristic &characteristic, int ret)
94 {
95 #ifdef BLUETOOTH_API_SINCE_10
96 HILOGI("UUID: %{public}s, ret: %{public}d", characteristic.GetUuid().ToString().c_str(), ret);
97 auto napiCharacter = std::make_shared<NapiNativeBleCharacteristic>(characteristic);
98 AsyncWorkCallFunction(asyncWorkMap_, NapiAsyncType::GATT_CLIENT_WRITE_CHARACTER, napiCharacter, ret);
99 #endif
100 }
101
OnDescriptorWriteResult(const GattDescriptor & descriptor,int ret)102 void NapiGattClientCallback::OnDescriptorWriteResult(const GattDescriptor &descriptor, int ret)
103 {
104 #ifdef BLUETOOTH_API_SINCE_10
105 HILOGI("UUID: %{public}s, ret: %{public}d", descriptor.GetUuid().ToString().c_str(), ret);
106 auto napiDescriptor = std::make_shared<NapiNativeBleDescriptor>(descriptor);
107 AsyncWorkCallFunction(asyncWorkMap_, NapiAsyncType::GATT_CLIENT_WRITE_DESCRIPTOR, napiDescriptor, ret);
108 #endif
109 }
110
OnSetNotifyCharacteristic(const GattCharacteristic & characteristic,int status)111 void NapiGattClientCallback::OnSetNotifyCharacteristic(const GattCharacteristic &characteristic, int status)
112 {
113 #ifdef BLUETOOTH_API_SINCE_10
114 HILOGI("UUID: %{public}s, status: %{public}d", characteristic.GetUuid().ToString().c_str(), status);
115 AsyncWorkCallFunction(asyncWorkMap_, NapiAsyncType::GATT_CLIENT_ENABLE_CHARACTER_CHANGED, nullptr, status);
116 #endif
117 }
118
OnMtuUpdate(int mtu,int ret)119 void NapiGattClientCallback::OnMtuUpdate(int mtu, int ret)
120 {
121 #ifdef BLUETOOTH_API_SINCE_10
122 HILOGI("ret: %{public}d, mtu: %{public}d", ret, mtu);
123 std::unique_lock<std::shared_mutex> guard(g_gattClientCallbackInfosMutex);
124 auto it = callbackInfos_.find(STR_BT_GATT_CLIENT_CALLBACK_BLE_MTU_CHANGE);
125 if (it == callbackInfos_.end() || it->second == nullptr) {
126 HILOGI("BLEMtuChange callback is not registered.");
127 return;
128 }
129 std::shared_ptr<BluetoothCallbackInfo> callbackInfo = it->second;
130
131 auto func = [callbackInfo, mtu]() {
132 napi_value result = nullptr;
133 napi_create_int32(callbackInfo->env_, mtu, &result);
134
135 napi_value callback = nullptr;
136 napi_value undefined = nullptr;
137 napi_value callResult = nullptr;
138 napi_get_undefined(callbackInfo->env_, &undefined);
139 napi_get_reference_value(callbackInfo->env_, callbackInfo->callback_, &callback);
140 napi_call_function(callbackInfo->env_, undefined, callback, ARGS_SIZE_ONE, &result, &callResult);
141 };
142 DoInJsMainThread(callbackInfo->env_, func);
143 #endif
144 }
145
146 } // namespace Bluetooth
147 } // namespace OHOS
148