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