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 <map>
16 #include <memory>
17 #include <string>
18
19 #include "bluetooth_log.h"
20 #include "bluetooth_utils.h"
21 #include "napi_bluetooth_remote_device_observer.h"
22 #include "napi_bluetooth_utils.h"
23 #include "napi_bluetooth_connection.h"
24
25 namespace OHOS {
26 namespace Bluetooth {
UvQueueWorkOnPairStatusChanged(uv_work_t * work,std::pair<std::string,int> & data)27 void NapiBluetoothRemoteDeviceObserver::UvQueueWorkOnPairStatusChanged(
28 uv_work_t *work, std::pair<std::string, int> &data)
29 {
30 HILOGI("uv_work_t start");
31 if (work == nullptr) {
32 HILOGE("work is null");
33 return;
34 }
35 auto callbackData = (AfterWorkCallbackData<NapiBluetoothRemoteDeviceObserver,
36 decltype(&NapiBluetoothRemoteDeviceObserver::UvQueueWorkOnPairStatusChanged),
37 std::pair<std::string, int>> *)work->data;
38 if (callbackData == nullptr) {
39 HILOGE("callbackData is null");
40 return;
41 }
42
43 napi_value result = 0;
44 napi_value callback = 0;
45 napi_value undefined = 0;
46 napi_value callResult = 0;
47
48 napi_get_undefined(callbackData->env, &undefined);
49 HILOGI("Status is %{public}d", callbackData->data.second);
50 napi_create_object(callbackData->env, &result);
51 napi_value device = 0;
52 napi_create_string_utf8(
53 callbackData->env, callbackData->data.first.data(), callbackData->data.first.size(), &device);
54 napi_set_named_property(callbackData->env, result, "deviceId", device);
55 napi_value bondState = 0;
56 napi_create_int32(callbackData->env, callbackData->data.second, &bondState);
57 napi_set_named_property(callbackData->env, result, "state", bondState);
58 napi_get_reference_value(callbackData->env, callbackData->callback, &callback);
59 napi_call_function(callbackData->env, undefined, callback, ARGS_SIZE_ONE, &result, &callResult);
60 }
61
OnAclStateChanged(const BluetoothRemoteDevice & device,int state,unsigned int reason)62 void NapiBluetoothRemoteDeviceObserver::OnAclStateChanged(
63 const BluetoothRemoteDevice &device, int state, unsigned int reason)
64 {}
65
OnPairStatusChanged(const BluetoothRemoteDevice & device,int status)66 void NapiBluetoothRemoteDeviceObserver::OnPairStatusChanged(const BluetoothRemoteDevice &device, int status)
67 {
68 std::shared_ptr<BluetoothCallbackInfo> callbackInfo = GetCallback(REGISTER_BOND_STATE_TYPE);
69 if (callbackInfo == nullptr) {
70 HILOGI("This callback is not registered by ability.");
71 return;
72 }
73 HILOGI("addr:%{public}s, status:%{public}d", GET_ENCRYPT_ADDR(device), status);
74 uv_loop_s *loop = nullptr;
75 napi_get_uv_event_loop(callbackInfo->env_, &loop);
76 if (loop == nullptr) {
77 HILOGE("loop instance is nullptr");
78 return;
79 }
80
81 int bondStatus = 0;
82 DealPairStatus(status, bondStatus);
83
84 auto callbackData = new (std::nothrow) AfterWorkCallbackData<NapiBluetoothRemoteDeviceObserver,
85 decltype(&NapiBluetoothRemoteDeviceObserver::UvQueueWorkOnPairStatusChanged),
86 std::pair<std::string, int>>();
87 if (callbackData == nullptr) {
88 HILOGE("new callbackData failed");
89 return;
90 }
91
92 std::string deviceAddr = device.GetDeviceAddr();
93 callbackData->object = this;
94 callbackData->function = &NapiBluetoothRemoteDeviceObserver::UvQueueWorkOnPairStatusChanged;
95 callbackData->env = callbackInfo->env_;
96 callbackData->callback = callbackInfo->callback_;
97 callbackData->data = std::pair<std::string, int>(deviceAddr, bondStatus);
98
99 uv_work_t *work = new (std::nothrow) uv_work_t;
100 if (work == nullptr) {
101 HILOGE("new work failed");
102 delete callbackData;
103 callbackData = nullptr;
104 return;
105 }
106
107 work->data = static_cast<void *>(callbackData);
108
109 int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, AfterWorkCallback<decltype(callbackData)>);
110 if (ret != 0) {
111 delete callbackData;
112 callbackData = nullptr;
113 delete work;
114 work = nullptr;
115 }
116 }
117
OnRemoteUuidChanged(const BluetoothRemoteDevice & device,const std::vector<ParcelUuid> & uuids)118 void NapiBluetoothRemoteDeviceObserver ::OnRemoteUuidChanged(
119 const BluetoothRemoteDevice &device, const std::vector<ParcelUuid> &uuids)
120 {
121 HILOGD("called");
122 }
123
OnRemoteNameChanged(const BluetoothRemoteDevice & device,const std::string & deviceName)124 void NapiBluetoothRemoteDeviceObserver ::OnRemoteNameChanged(
125 const BluetoothRemoteDevice &device, const std::string &deviceName)
126 {
127 HILOGD("addr:%{public}s, deviceName:%{public}s", GET_ENCRYPT_ADDR(device), deviceName.c_str());
128 }
129
OnRemoteAliasChanged(const BluetoothRemoteDevice & device,const std::string & alias)130 void NapiBluetoothRemoteDeviceObserver ::OnRemoteAliasChanged(
131 const BluetoothRemoteDevice &device, const std::string &alias)
132 {
133 HILOGD("addr:%{public}s, alias:%{public}s", GET_ENCRYPT_ADDR(device), alias.c_str());
134 }
135
OnRemoteCodChanged(const BluetoothRemoteDevice & device,const BluetoothDeviceClass & cod)136 void NapiBluetoothRemoteDeviceObserver ::OnRemoteCodChanged(
137 const BluetoothRemoteDevice &device, const BluetoothDeviceClass &cod)
138 {
139 HILOGD("addr:%{public}s, cod:%{public}d", GET_ENCRYPT_ADDR(device), cod.GetClassOfDevice());
140 }
141
OnRemoteBatteryLevelChanged(const BluetoothRemoteDevice & device,int batteryLevel)142 void NapiBluetoothRemoteDeviceObserver ::OnRemoteBatteryLevelChanged(
143 const BluetoothRemoteDevice &device, int batteryLevel)
144 {
145 HILOGD("addr:%{public}s, batteryLevel:%{public}d", GET_ENCRYPT_ADDR(device), batteryLevel);
146 }
147
OnReadRemoteRssiEvent(const BluetoothRemoteDevice & device,int rssi,int status)148 void NapiBluetoothRemoteDeviceObserver ::OnReadRemoteRssiEvent(
149 const BluetoothRemoteDevice &device, int rssi, int status)
150 {
151 HILOGD("addr:%{public}s, rssi:%{public}d, status is %{public}d", GET_ENCRYPT_ADDR(device), rssi, status);
152 }
153
RegisterCallback(const std::string & callbackName,const std::shared_ptr<BluetoothCallbackInfo> & callback)154 void NapiBluetoothRemoteDeviceObserver::RegisterCallback(
155 const std::string &callbackName, const std::shared_ptr<BluetoothCallbackInfo> &callback)
156 {
157 std::lock_guard<std::mutex> lock(callbacksMapLock_);
158 callbacks_[callbackName] = callback;
159 }
160
DeRegisterCallback(const std::string & callbackName)161 void NapiBluetoothRemoteDeviceObserver::DeRegisterCallback(const std::string &callbackName)
162 {
163 std::lock_guard<std::mutex> lock(callbacksMapLock_);
164 callbacks_.erase(callbackName);
165 }
166
GetCallback(const std::string & callbackName)167 std::shared_ptr<BluetoothCallbackInfo> NapiBluetoothRemoteDeviceObserver::GetCallback(const std::string &callbackName)
168 {
169 std::lock_guard<std::mutex> lock(callbacksMapLock_);
170 if (callbacks_.find(callbackName) != callbacks_.end()) {
171 return callbacks_[callbackName];
172 }
173 return nullptr;
174 }
175
DealPairStatus(const int & status,int & bondStatus)176 void NapiBluetoothRemoteDeviceObserver::DealPairStatus(const int &status, int &bondStatus)
177 {
178 HILOGI("status is %{public}d", status);
179 switch (status) {
180 case PAIR_NONE:
181 bondStatus = static_cast<int>(BondState::BOND_STATE_INVALID);
182 break;
183 case PAIR_PAIRING:
184 bondStatus = static_cast<int>(BondState::BOND_STATE_BONDING);
185 break;
186 case PAIR_PAIRED:
187 bondStatus = static_cast<int>(BondState::BOND_STATE_BONDED);
188 break;
189 default:
190 break;
191 }
192 }
193 } // namespace Bluetooth
194 } // namespace OHOS