1 /*
2 * Copyright (c) 2024-2025 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 "ble_send_manager.h"
17
18 #include <chrono>
19 #include <condition_variable>
20 #include <thread>
21 #include <unistd.h>
22 #include <atomic>
23
24 #include <sstream>
25 #include <sys/prctl.h>
26 #include "securec.h"
27
28 #include "c_header/ohos_bt_gatt.h"
29 #include "connect/mc_connect_manager.h"
30 #include "iservice_registry.h"
31
32 #include "system_ability_definition.h"
33 #include "uuid.h"
34 #include "mechbody_controller_service.h"
35
36 using namespace OHOS::Bluetooth;
37
38 namespace OHOS {
39 namespace MechBodyController {
40 namespace {
41 const std::string TAG = "BleSendManager";
42 const std::string TARGET_DEVICE_NAME = "TARGET_DEVICE_NAME";
43 constexpr long SCAN_REPORT_DELAY_MILLIS = 3 * 1000;
44 constexpr size_t NOTIFY_DATA_MAX_SIZE = 1024 * 1024;
45 constexpr int32_t MECH_SAID = 8550;
46 constexpr int32_t BUF_MIN_LEN = 8;
47 constexpr int32_t BUF_MAX_LEN = 251;
48 constexpr int32_t WAIT_TIME = 60;
49 constexpr int32_t ERROR_NO_LISTENERS = -10001;
50 constexpr int32_t ERROR_INVALID_PARAMETER = -10002;
51 constexpr int32_t MECHBODY_GATT_INVALID_PARAM = -10003;
52 constexpr int32_t ERROR_SIZE_TOO_LARGE = -10004;
53 constexpr int32_t MECHBODY_GATT_CONNECT_FAILED = -10005;
54 constexpr int32_t WAIT_TIME_TEN = 10;
55 std::atomic<bool> g_isUnloadScheduled = false;
56 std::unique_ptr<std::thread> delayThread;
57
58 UUID SERVICE_UUID = UUID::FromString("15f1e600-a277-43fc-a484-dd39ef8a9100"); // GATT Service uuid
59 UUID MECHBODY_CHARACTERISTIC_WRITE_UUID = UUID::FromString("15f1e602-a277-43fc-a484-dd39ef8a9100"); // write uuid
60 UUID MECHBODY_CHARACTERISTIC_NOTIFY_UUID = UUID::FromString("15f1e603-a277-43fc-a484-dd39ef8a9100"); // notify uuid
61 BleSendManager& bleSendManager = BleSendManager::GetInstance();
62 }
63
GetInstance()64 BleSendManager& BleSendManager::GetInstance()
65 {
66 static auto instance = new BleSendManager();
67 return *instance;
68 }
69
BleSendManager()70 BleSendManager::BleSendManager()
71 {}
~BleSendManager()72 BleSendManager::~BleSendManager()
73 {}
74
BleGattClientCallback()75 BleGattClientCallback::BleGattClientCallback()
76 {}
~BleGattClientCallback()77 BleGattClientCallback::~BleGattClientCallback()
78 {}
79
UnloadSystemAbility()80 void UnloadSystemAbility()
81 {
82 HILOGI("start");
83 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
84 if (sam == nullptr) {
85 HILOGE("GetSystemAbilityManager return null.");
86 return;
87 }
88 int32_t ret = sam->UnloadSystemAbility(MECH_SAID);
89 if (ret != ERR_OK) {
90 HILOGE("UnLoadSystemAbility mechbody sa failed.");
91 return;
92 }
93 HILOGI("end");
94 }
95
DelayedUnloadSystemAbility(std::chrono::seconds delay)96 void DelayedUnloadSystemAbility(std::chrono::seconds delay)
97 {
98 HILOGI("start");
99 if (g_isUnloadScheduled) {
100 HILOGI("already Unload Scheduled. isUnloadScheduled = %{public}d", g_isUnloadScheduled.load());
101 return;
102 }
103 if (delayThread != nullptr) {
104 HILOGI("Thread is empty.");
105 return;
106 }
107 delayThread = std::make_unique<std::thread>([delay]() {
108 std::this_thread::sleep_for(delay);
109 if (g_isUnloadScheduled) {
110 HILOGI(" will Unload SystemAbility, isUnloadScheduled = %{public}d",
111 g_isUnloadScheduled.load());
112 UnloadSystemAbility();
113 }
114 });
115 g_isUnloadScheduled = true;
116 HILOGI("end");
117 }
118
CancelDelayedUnload()119 void CancelDelayedUnload()
120 {
121 HILOGI("start");
122 if (!g_isUnloadScheduled) {
123 HILOGI("No Unload Scheduled.");
124 return;
125 }
126 g_isUnloadScheduled = false;
127 HILOGI("isUnloadScheduled = %{public}d", g_isUnloadScheduled.load());
128 if (delayThread && delayThread->joinable()) {
129 HILOGI("delayThread is join. isUnloadScheduled = %{public}d", g_isUnloadScheduled.load());
130 delayThread->detach();
131 }
132 HILOGI("end. isUnloadScheduled = %{public}d", g_isUnloadScheduled.load());
133 }
134
OnConnectionStateChanged(int connectionState,int ret)135 void BleGattClientCallback::OnConnectionStateChanged(int connectionState, int ret)
136 {
137 HILOGI("MECHBODY_EXEC_CONNECT BleGattClientCallback start. connectionState= %{public}d, ret= %{public}d",
138 connectionState, ret);
139 MechInfo mechInfo;
140 MechConnectManager::GetInstance().GetMechInfo(mac, mechInfo);
141 bleSendManager.OnConnectionStateChanged(connectionState, ret, mechInfo);
142 HILOGI("MECHBODY_EXEC_CONNECT BleGattClientCallback end");
143 }
144
OnServicesDiscovered(int status)145 void BleGattClientCallback::OnServicesDiscovered(int status)
146 {
147 HILOGI("called. status= %{public}d", status);
148 if (status != OHOS::Bluetooth::GattStatus::GATT_SUCCESS) {
149 HILOGE("OnServicesDiscovered state is not sucess");
150 return;
151 }
152 if (bleSendManager.gattClient_ == nullptr) {
153 HILOGE("gattClient_ is null");
154 return;
155 }
156 auto mService = bleSendManager.gattClient_->GetService(SERVICE_UUID);
157 if (!mService.has_value()) {
158 HILOGE("Failed to get service.");
159 return;
160 }
161 HILOGI("GetService success");
162 auto notifyCharacteristic = mService->get().GetCharacteristic(MECHBODY_CHARACTERISTIC_NOTIFY_UUID);
163 if (!notifyCharacteristic) {
164 HILOGE("Failed to get notify characteristic.");
165 return;
166 }
167 auto writeCharacteristic = mService->get().GetCharacteristic(MECHBODY_CHARACTERISTIC_WRITE_UUID);
168 if (!writeCharacteristic) {
169 HILOGE("Failed to get write characteristic.");
170 return;
171 }
172 int permissions = notifyCharacteristic->GetPermissions();
173 int properties = notifyCharacteristic->GetProperties();
174 uint16_t handle = notifyCharacteristic->GetHandle();
175 GattCharacteristic characteristic = GattCharacteristic(MECHBODY_CHARACTERISTIC_NOTIFY_UUID, handle, permissions,
176 properties);
177 bleSendManager.gattClient_->SetNotifyCharacteristic(characteristic, true);
178 int wPermissions = writeCharacteristic->GetPermissions();
179 int wProperties = writeCharacteristic->GetProperties();
180 uint16_t wHandle = writeCharacteristic->GetHandle();
181 bleSendManager.handle_ = wHandle;
182 bleSendManager.permissions_ = wPermissions;
183 bleSendManager.properties_ = wProperties;
184 HILOGI("end");
185 }
186
OnSetNotifyCharacteristic(const GattCharacteristic & characteristic,int status)187 void BleGattClientCallback::OnSetNotifyCharacteristic(const GattCharacteristic &characteristic, int status)
188 {
189 MechInfo mechInfo;
190 if (MechConnectManager::GetInstance().GetMechInfo(mac, mechInfo) != ERR_OK) {
191 HILOGI("MECHBODY_EXEC_CONNECT Can not found mech info for mac: %{public}s", GetAnonymStr(mac).c_str());
192 return;
193 }
194 HILOGI("called. status= %{public}d", status);
195 std::lock_guard<std::mutex> lock(bleSendManager.isGattReadyMtx_);
196 bleSendManager.isGattReady_ = (status == 1);
197 HILOGI("end. IsGattReady= %{public}d", bleSendManager.isGattReady_);
198
199 BleSendManager::GetInstance().OnGattReady(mechInfo);
200 }
201
OnCharacteristicChanged(const GattCharacteristic & characteristic)202 void BleGattClientCallback::OnCharacteristicChanged(const GattCharacteristic &characteristic)
203 {
204 HILOGD("called.");
205 size_t size = 0;
206 uint8_t *valueData = characteristic.GetValue(&size).get();
207 HILOGD("size = %{public}zu", size);
208
209 // notifydata
210 BleSendManager::GetInstance().OnReceive(valueData, size);
211 }
212
OnCharacteristicWriteResult(const GattCharacteristic & characteristic,int ret)213 void BleGattClientCallback::OnCharacteristicWriteResult(const GattCharacteristic &characteristic, int ret)
214 {
215 HILOGD("called, ret = %{public}d\n", ret);
216 if (ret == OHOS::Bluetooth::GattStatus::GATT_SUCCESS) {
217 HILOGI("write success");
218 size_t size = 0;
219 const std::unique_ptr<uint8_t[]> &value = characteristic.GetValue(&size);
220 HILOGI("write sucess, size = %{public}zu", size);
221 if (value == nullptr || size == 0) {
222 HILOGI("value is empty or null");
223 return;
224 }
225 } else if (ret == OHOS::Bluetooth::GattStatus::GATT_FAILURE) {
226 HILOGI("write failed");
227 } else if (ret == OHOS::Bluetooth::GattStatus::WRITE_NOT_PERMITTED) {
228 HILOGI("write not permission");
229 }
230 }
231
getMac() const232 const std::string &BleGattClientCallback::getMac() const
233 {
234 return mac;
235 }
236
setMac(const std::string & mac)237 void BleGattClientCallback::setMac(const std::string &mac)
238 {
239 BleGattClientCallback::mac = mac;
240 }
241
Init()242 void BleSendManager::Init()
243 {
244 HILOGI("Init start");
245 {
246 std::lock_guard<std::mutex> lock(observerRegisterMutex_);
247 if (observer_ == nullptr) {
248 observer_ = std::make_shared<HidObserver>();
249 Bluetooth::HidHost::GetProfile()->RegisterObserver(observer_);
250 HILOGI("MECHBODY_EXEC_CONNECT hid RegisterObserver registed");
251 }
252 if (hostObserver_ == nullptr) {
253 hostObserver_ = std::make_shared<HostObserver>();
254 Bluetooth::BluetoothHost::GetDefaultHost().RegisterRemoteDeviceObserver(hostObserver_);
255 HILOGI("MECHBODY_EXEC_CONNECT host RegisterObserver registed");
256 }
257 }
258 auto runner = AppExecFwk::EventRunner::Create("BleSenderManager");
259 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
260 }
261
UnInit()262 void BleSendManager::UnInit()
263 {
264 HILOGI("UnInit start");
265 if (gattClient_ != nullptr) {
266 if (gattClient_->Close() != 0) {
267 HILOGE("Close gattclient error");
268 }
269 gattClient_.reset();
270 gattClient_ = nullptr;
271 }
272 }
273
OnConnectionStateChanged(int connectionState,int ret,MechInfo & mechInfo)274 void BleSendManager::OnConnectionStateChanged(int connectionState, int ret, MechInfo &mechInfo)
275 {
276 HILOGI("MECHBODY_EXEC_CONNECT start. connectionState= %{public}d, ret= %{public}d",
277 connectionState, ret);
278 if (connectionState != (int)BTConnectState::CONNECTED && connectionState != (int)BTConnectState::DISCONNECTED) {
279 HILOGE("MECHBODY_EXEC_CONNECT ignore, connectionState = %{public}d, connecting or disconnecting",
280 connectionState);
281 return;
282 }
283 if (connectionState == (int)BTConnectState::CONNECTED) {
284 HILOGI("MECHBODY_EXEC_CONNECT connectionState is CONNECTED");
285 CancelDelayedUnload();
286 CHECK_POINTER_RETURN(gattClient_, "gattClient_");
287 gattClient_->DiscoverServices();
288 HILOGI("MECHBODY_EXEC_CONNECT called to discover service");
289 gattClient_->RequestConnectionPriority(MECH_GATT_PRIORITY_HIGH);
290 return;
291 } else if (connectionState == (int)BTConnectState::DISCONNECTED) {
292 HILOGI("MECHBODY_EXEC_CONNECT connectionState is DISCONNECTED");
293 {
294 std::unique_lock<std::mutex> lock(gattDisconnMutex_);
295 MechConnectManager::GetInstance().SetMechanicGattState(mechInfo.mac, false);
296 gattDisconnCv_.notify_all();
297 }
298 HILOGI("MECHBODY_EXEC_CONNECT Tracking uninit start.");
299 McCameraTrackingController::GetInstance().UnInit();
300 HILOGI("MECHBODY_EXEC_CONNECT Tracking uninit finish.");
301 MechbodyDisConnect(mechInfo);
302 }
303 HILOGI("MECHBODY_EXEC_CONNECT end");
304 }
305
OnPairStateChanged(int pairState,int cause,MechInfo & mechInfo)306 void BleSendManager::OnPairStateChanged(int pairState, int cause, MechInfo &mechInfo)
307 {
308 HILOGI("MECHBODY_EXEC_CONNECT device Pair Status change. mech info: %{public}s; "
309 "status: %{public}d; cause: %{public}d;", mechInfo.ToString().c_str(), pairState, cause);
310 if (pairState == Bluetooth::PAIR_PAIRED) {
311 HILOGI("MECHBODY_EXEC_CONNECT Set Device Alias start.");
312 Bluetooth::BluetoothRemoteDevice remoteDevice =
313 Bluetooth::BluetoothRemoteDevice(mechInfo.mac, Bluetooth::BT_TRANSPORT_BLE);
314 std::string showName = mechInfo.mechName + "-mechanic";
315 int32_t res = remoteDevice.SetDeviceAlias(showName);
316 HILOGI("MECHBODY_EXEC_CONNECT SetDeviceAlias end. result: %{public}d", res);
317
318 std::unique_lock<std::mutex> lock(pairMutex_);
319 MechConnectManager::GetInstance().SetMechanicPairState(mechInfo.mac, true);
320 pairCv_.notify_all();
321 }
322 }
323
OnHidStateChanged(int hidState,int cause,MechInfo & mechInfo)324 void BleSendManager::OnHidStateChanged(int hidState, int cause, MechInfo &mechInfo)
325 {
326 HILOGI("MECHBODY_EXEC_CONNECT device HID connect state change. "
327 "mech info: %{public}s; state: %{public}d", mechInfo.ToString().c_str(), hidState);
328 if (hidState == static_cast<int>(Bluetooth::BTConnectState::DISCONNECTED)) {
329 std::unique_lock<std::mutex> lock(hidDisconnMutex_);
330 MechConnectManager::GetInstance().SetMechanicHidState(mechInfo.mac, false);
331 hidDisconnCv_.notify_all();
332
333 MechbodyDisConnect(mechInfo);
334 } else if (hidState == static_cast<int>(Bluetooth::BTConnectState::CONNECTED)) {
335 std::unique_lock<std::mutex> lock(hidMutex_);
336 MechConnectManager::GetInstance().SetMechanicHidState(mechInfo.mac, true);
337 hidCv_.notify_all();
338 }
339 }
340
OnReceive(uint8_t * data,size_t size)341 int32_t BleSendManager::OnReceive(uint8_t *data, size_t size)
342 {
343 HILOGD("OnReceive in. size = %{public}zu", size);
344 if (data == nullptr) {
345 HILOGE("data is null");
346 return ERROR_INVALID_PARAMETER;
347 }
348
349 if (size == 0) {
350 HILOGE("size is zero");
351 return ERROR_INVALID_PARAMETER;
352 }
353
354 if (size > NOTIFY_DATA_MAX_SIZE) {
355 HILOGE("size exceeds maximum allowed size: %{public}zu > %{public}zu", size, NOTIFY_DATA_MAX_SIZE);
356 return ERROR_SIZE_TOO_LARGE;
357 }
358
359 std::lock_guard<std::mutex> lock(bleReceviceMutex_);
360 if (bleReceviceListeners_.empty()) {
361 HILOGE("bleReceviceListeners_ is null");
362 return ERROR_NO_LISTENERS;
363 }
364 for (std::shared_ptr<BleReceviceListener> listener : bleReceviceListeners_) {
365 if (listener == nullptr) {
366 HILOGE("bleReceviceListeners_ is null");
367 return ERROR_NO_LISTENERS;
368 }
369 listener->OnReceive(data, size);
370 }
371 return ERR_OK;
372 }
373
RegisterTransportSendAdapter(const std::shared_ptr<BleReceviceListener> listener)374 int32_t BleSendManager::RegisterTransportSendAdapter(const std::shared_ptr<BleReceviceListener> listener)
375 {
376 // LCOV_EXCL_START
377 if (listener == nullptr) {
378 HILOGE("listener is null.");
379 return ERROR_NO_LISTENERS;
380 }
381 std::lock_guard<std::mutex> lock(bleReceviceMutex_);
382 auto it = std::find(bleReceviceListeners_.begin(), bleReceviceListeners_.end(), listener);
383 if (it != bleReceviceListeners_.end()) {
384 HILOGE("bleReceviceListeners_ repeat register");
385 return ERR_OK;
386 }
387
388 bleReceviceListeners_.push_back(listener);
389 return ERR_OK;
390 // LCOV_EXCL_STOP
391 }
392
UnRegisterTransportSendAdapter(const std::shared_ptr<BleReceviceListener> listener)393 int32_t BleSendManager::UnRegisterTransportSendAdapter(const std::shared_ptr<BleReceviceListener> listener)
394 {
395 // LCOV_EXCL_START
396 std::lock_guard<std::mutex> lock(bleReceviceMutex_);
397 if (bleReceviceListeners_.empty()) {
398 HILOGE("bleReceviceListeners_ is null");
399 return ERROR_NO_LISTENERS;
400 }
401 auto it = std::find(bleReceviceListeners_.begin(), bleReceviceListeners_.end(), listener);
402 if (it == bleReceviceListeners_.end()) {
403 HILOGE("bleReceviceListeners_ not found");
404 return ERROR_NO_LISTENERS;
405 }
406 bleReceviceListeners_.erase(it);
407 return ERR_OK;
408 // LCOV_EXCL_STOP
409 }
410
CheckGattcIsReady()411 bool BleSendManager::CheckGattcIsReady()
412 {
413 // LCOV_EXCL_START
414 HILOGI("in. IsGattReady=%{public}s", isGattReady_ ? "true":"false");
415 return isGattReady_;
416 // LCOV_EXCL_STOP
417 }
418
OnGattReady(MechInfo & mechInfo)419 void BleSendManager::OnGattReady(MechInfo &mechInfo)
420 {
421 HILOGI("MECHBODY_EXEC_CONNECT called");
422 MechConnectManager::GetInstance().NotifyMechConnect(mechInfo);
423 {
424 std::unique_lock<std::mutex> lock(gattMutex_);
425 MechConnectManager::GetInstance().SetMechanicGattState(mechInfo.mac, true);
426 gattCv_.notify_all();
427 }
428 HILOGI("MECHBODY_EXEC_CONNECT Tracking init start.");
429 McCameraTrackingController::GetInstance().Init();
430 HILOGI("MECHBODY_EXEC_CONNECT Tracking init finish.");
431 }
432
InitScanPara()433 void BleSendManager::InitScanPara()
434 {
435 // LCOV_EXCL_START
436 scanParam_.settings.SetScanMode(BleScanMode::OHOS_BLE_SCAN_MODE_LOW_POWER);
437 scanParam_.settings.SetReportDelay(SCAN_REPORT_DELAY_MILLIS);
438
439 Bluetooth::BleScanFilter scanFilter;
440
441 scanParam_.filters.clear();
442 scanParam_.filters.push_back(scanFilter);
443
444 std::shared_ptr<BleCentralManagerCallbackImpl> bleCentralManagerCallback =
445 std::make_shared<BleCentralManagerCallbackImpl>();
446 bleCentralManager_ = std::make_shared<Bluetooth::BleCentralManager>(bleCentralManagerCallback);
447 // LCOV_EXCL_STOP
448 }
449
OnScanCallback(const Bluetooth::BleScanResult & result)450 void BleSendManager::OnScanCallback(const Bluetooth::BleScanResult &result)
451 {
452 HILOGI("OnScanCallback in");
453 std::vector<uint8_t> advPayload = result.GetPayload();
454 std::string address = result.GetPeripheralDevice().GetDeviceAddr();
455 std::string deviceName = result.GetPeripheralDevice().GetDeviceName();
456 if (deviceName == TARGET_DEVICE_NAME) {
457 address_ = address;
458 this->StopScan();
459 int32_t ret = MechbodyGattcConnect(address, deviceName);
460 if (ret != ERR_OK) {
461 HILOGE("MechbodyGattcConnect failed, status= %{public}d", ret);
462 }
463 }
464 }
465
StartScan()466 void BleSendManager::StartScan()
467 {
468 // LCOV_EXCL_START
469 HILOGI("startScan start");
470 if (bleCentralManager_ == nullptr) {
471 HILOGE("RemoteLogBleScanner StartScan bleCentralManager_ is empty");
472 return;
473 }
474 this->StopScan();
475 int32_t status = bleCentralManager_->StartScan(scanParam_.settings, scanParam_.filters);
476 if (status == Bluetooth::BtErrCode::BT_NO_ERROR) {
477 HILOGI("BleCentralManager startScan success");
478 } else {
479 HILOGE("BleCentralManager StartScan failed code = %{public}d.", status);
480 }
481 HILOGI("startScan end");
482 // LCOV_EXCL_STOP
483 }
484
StopScan()485 void BleSendManager::StopScan()
486 {
487 // LCOV_EXCL_START
488 if (bleCentralManager_ == nullptr) {
489 HILOGE("StopScan bleCentralManager_ is empty");
490 return;
491 }
492 int ret = bleCentralManager_->StopScan();
493 HILOGI("StopScan ret: %{public}d", ret);
494 // LCOV_EXCL_STOP
495 }
496
MechbodyConnect(std::string mac,std::string deviceName)497 int32_t BleSendManager::MechbodyConnect(std::string mac, std::string deviceName)
498 {
499 HILOGI("MECHBODY_EXEC_CONNECT satrt");
500 auto connFunc = [this, mac, deviceName]() {
501 if (MechConnectManager::GetInstance().IsConnect()) {
502 HILOGW("MECHBODY_EXEC_CONNECT mechInfos has connected.");
503 return;
504 }
505 MechInfo mechInfo;
506 mechInfo.mac = mac;
507 mechInfo.mechName = deviceName;
508 if (MechConnectManager::GetInstance().GetMechInfo(mechInfo.mac, mechInfo) != ERR_OK) {
509 if (MechConnectManager::GetInstance().AddMechInfo(mechInfo) != ERR_OK) {
510 HILOGE("MECHBODY_EXEC_CONNECT save machInfo for mac: %{public}s", mechInfo.ToString().c_str());
511 return;
512 }
513 }
514 HILOGI("MECHBODY_EXEC_CONNECT async connect start, mech info for: %{public}s", mechInfo.ToString().c_str());
515 if (mechInfo.gattCoonectState) {
516 HILOGE("MECHBODY_EXEC_CONNECT mech has connected: %{public}s", GetAnonymStr(mechInfo.mac).c_str());
517 return;
518 }
519 int32_t gattRet = ERR_OK;
520 do {
521 gattRet = MechbodyGattcConnect(mechInfo.mac, mechInfo.mechName);
522 if (gattRet != ERR_OK) {
523 HILOGE("MECHBODY_EXEC_CONNECT gatt connect failed mechInfo: %{public}s", mechInfo.ToString().c_str());
524 break;
525 }
526 int32_t ret = MechbodyPair(mechInfo.mac, mechInfo.mechName);
527 if (ret != ERR_OK) {
528 HILOGE("MECHBODY_EXEC_CONNECT make pair failed mechInfo: %{public}s", mechInfo.ToString().c_str());
529 }
530 ret = MechbodyHidConnect(mechInfo.mac, mechInfo.mechName);
531 if (ret != ERR_OK) {
532 HILOGE("MECHBODY_EXEC_CONNECT hid connect failed mechInfo: %{public}s", mechInfo.ToString().c_str());
533 }
534 } while (false);
535
536 if (gattRet != ERR_OK) {
537 HILOGI("MECHBODY_EXEC_CONNECT async connect rollback, mechInfo: %{public}s", mechInfo.ToString().c_str());
538 MechbodyDisConnectSync(mechInfo);
539 }
540 HILOGI("MECHBODY_EXEC_CONNECT async connect end, mech info for: %{public}s", mechInfo.ToString().c_str());
541 };
542
543 if (eventHandler_ != nullptr) {
544 eventHandler_->PostTask(connFunc);
545 }
546 HILOGI("MECHBODY_EXEC_CONNECT end");
547 return ERR_OK;
548 }
549
MechbodyGattcConnect(std::string mac,std::string deviceName)550 int32_t BleSendManager::MechbodyGattcConnect(std::string mac, std::string deviceName)
551 {
552 HILOGI("MECHBODY_EXEC_CONNECT connect begin, mac: %{public}s", GetAnonymStr(mac).c_str());
553 address_ = mac;
554 deviceName_ = deviceName;
555 BluetoothRemoteDevice device(mac, 1);
556 gattClient_ = std::make_shared<OHOS::Bluetooth::GattClient>(device);
557 bleGattClientCallBack_ = std::make_shared<BleGattClientCallback>();
558 bleGattClientCallBack_->setMac(mac);
559 gattClient_->Init();
560 int result = gattClient_->Connect(bleGattClientCallBack_, false, BT_TRANSPORT_BLE);
561 if (result != 0) {
562 HILOGE("MECHBODY_EXEC_CONNECT Failed to connect, result: %{public}d", result);
563 return MECHBODY_GATT_CONNECT_FAILED;
564 }
565
566 std::unique_lock<std::mutex> lock(gattMutex_);
567 if (!gattCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_TEN),
568 [this, mac]() mutable {
569 bool gattState = false;
570 MechConnectManager::GetInstance().GetMechanicGattState(mac, gattState);
571 return gattState;
572 })) {
573 HILOGE("MECHBODY_EXEC_CONNECT wait for gatt connect timeout");
574 return MECHBODY_GATT_CONNECT_FAILED;
575 }
576 HILOGI("MECHBODY_EXEC_CONNECT connect end mac: %{public}s", GetAnonymStr(mac).c_str());
577 return ERR_OK;
578 }
579
MechbodyPair(std::string & mac,std::string & deviceName)580 int32_t BleSendManager::MechbodyPair(std::string &mac, std::string &deviceName)
581 {
582 HILOGI("MECHBODY_EXEC_CONNECT start, mac: %{public}s, device name: %{public}s;",
583 GetAnonymStr(mac).c_str(), GetAnonymStr(deviceName).c_str());
584 Bluetooth::BluetoothRemoteDevice device =
585 Bluetooth::BluetoothRemoteDevice(mac, Bluetooth::BT_TRANSPORT_BLE);
586 int32_t res = device.StartCrediblePair();
587 HILOGI("MECHBODY_EXEC_CONNECT end. CrediblePair result: %{public}d", res);
588
589 std::unique_lock<std::mutex> lock(pairMutex_);
590 if (!pairCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_TEN),
591 [this, mac]()mutable {
592 bool pairState = false;
593 MechConnectManager::GetInstance().GetMechanicPairState(mac, pairState);
594 return pairState;
595 })) {
596 HILOGE("MECHBODY_EXEC_CONNECT wait for pair timeout");
597 return MECHBODY_GATT_CONNECT_FAILED;
598 }
599 HILOGI("MECHBODY_EXEC_CONNECT end, mac: %{public}s, device name: %{public}s;",
600 GetAnonymStr(mac).c_str(), GetAnonymStr(deviceName).c_str());
601 return ERR_OK;
602 }
603
MechbodyHidConnect(std::string & mac,std::string & deviceName)604 int32_t BleSendManager::MechbodyHidConnect(std::string &mac, std::string &deviceName)
605 {
606 HILOGI("MECHBODY_EXEC_CONNECT start, mac: %{public}s, device name: %{public}s;",
607 GetAnonymStr(mac).c_str(), GetAnonymStr(deviceName).c_str());
608 Bluetooth::BluetoothRemoteDevice remoteDevice = Bluetooth::BluetoothRemoteDevice(mac);
609 int32_t res = Bluetooth::HidHost::GetProfile()->Connect(remoteDevice);
610 std::unique_lock<std::mutex> lock(hidMutex_);
611 if (!pairCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_TEN),
612 [this, mac]()mutable {
613 bool hidState = false;
614 MechConnectManager::GetInstance().GetMechanicHidState(mac, hidState);
615 return hidState;
616 })) {
617 HILOGE("MECHBODY_EXEC_CONNECT wait for hid timeout");
618 return MECHBODY_GATT_CONNECT_FAILED;
619 }
620 HILOGI("MECHBODY_EXEC_CONNECT end, mac: %{public}s, device name: %{public}s;",
621 GetAnonymStr(mac).c_str(), GetAnonymStr(deviceName).c_str());
622 return res;
623 }
624
MechbodyDisConnect(MechInfo & mechInfo)625 int32_t BleSendManager::MechbodyDisConnect(MechInfo &mechInfo)
626 {
627 HILOGI("MECHBODY_EXEC_DISCONNECT start, mech info for: %{public}s", mechInfo.ToString().c_str());
628 auto connFunc = [this, mechInfo]() mutable {
629 if (MechConnectManager::GetInstance().GetMechanicGattState(
630 mechInfo.mac, mechInfo.gattCoonectState) != ERR_OK) {
631 HILOGE("MECHBODY_EXEC_DISCONNECT Can not find mech info for amc: %{public}s",
632 GetAnonymStr(mechInfo.mac).c_str());
633 return;
634 }
635 HILOGI("MECHBODY_EXEC_DISCONNECT async disconnect start, mech info for: %{public}s",
636 mechInfo.ToString().c_str());
637 if (!mechInfo.gattCoonectState) {
638 OnGattDisconnect(mechInfo);
639 HILOGE("MECHBODY_EXEC_DISCONNECT Device has already disconnected for mechInfo: %{public}s",
640 mechInfo.ToString().c_str());
641 return;
642 }
643 MechbodyDisConnectSync(mechInfo);
644 HILOGI("MECHBODY_EXEC_DISCONNECT async disconnect end, mech info for: %{public}s", mechInfo.ToString().c_str());
645 };
646
647 if (eventHandler_ != nullptr) {
648 eventHandler_->PostTask(connFunc);
649 }
650 HILOGI("MECHBODY_EXEC_DISCONNECT end, mech info for: %{public}s", mechInfo.ToString().c_str());
651 return ERR_OK;
652 }
653
MechbodyDisConnectSync(MechInfo & mechInfo)654 int32_t BleSendManager::MechbodyDisConnectSync(MechInfo &mechInfo)
655 {
656 HILOGI("MECHBODY_EXEC_DISCONNECT start, mech info for: %{public}s", mechInfo.ToString().c_str());
657 int32_t ret = ERR_OK;
658 ret = MechbodyHidDisconnect(mechInfo);
659 if (ret != ERR_OK) {
660 HILOGE("MECHBODY_EXEC_DISCONNECT hid disconnect failed for mechInfo: %{public}s",
661 mechInfo.ToString().c_str());
662 }
663 ret = MechbodyGattcDisconnect(mechInfo);
664 if (ret != ERR_OK) {
665 HILOGE("MECHBODY_EXEC_DISCONNECT gatt disconnect failed for mechInfo: %{public}s",
666 mechInfo.ToString().c_str());
667 }
668 HILOGI("MECHBODY_EXEC_DISCONNECT end, mech info for: %{public}s", mechInfo.ToString().c_str());
669 return ret;
670 }
671
OnGattDisconnect(MechInfo & mechInfo)672 void BleSendManager::OnGattDisconnect(MechInfo &mechInfo)
673 {
674 MechConnectManager::GetInstance().NotifyMechDisconnect(mechInfo);
675 DelayedUnloadSystemAbility(std::chrono::seconds(WAIT_TIME));
676
677 HILOGI("destruct bleGattClientCallBack_ start");
678 if (gattClient_ != nullptr) {
679 if (gattClient_->Close() != 0) {
680 HILOGE("Close gattclient error");
681 }
682 gattClient_.reset();
683 gattClient_ = nullptr;
684 }
685
686 if (bleGattClientCallBack_ != nullptr) {
687 bleGattClientCallBack_.reset();
688 bleGattClientCallBack_ = nullptr;
689 }
690 HILOGI("end and destruct bleGattClientCallBack_ end");
691 }
692
MechbodyGattcDisconnect(MechInfo mechInfo)693 int32_t BleSendManager::MechbodyGattcDisconnect(MechInfo mechInfo)
694 {
695 HILOGI("MECHBODY_EXEC_DISCONNECT begin");
696 if (gattClient_ == nullptr) {
697 HILOGE("gattClient_ is nullptr");
698 return MECHBODY_GATT_INVALID_PARAM;
699 }
700 int status = gattClient_->Disconnect();
701 HILOGI("MECHBODY_EXEC_DISCONNECT BleGattcDisconnect info, status: %{public}d", status);
702 if (status != OHOS_BT_STATUS_SUCCESS) {
703 HILOGE("MECHBODY_EXEC_DISCONNECT BleGattcDisconnect error, status: %{public}d", status);
704 return MECHBODY_GATT_INVALID_PARAM;
705 }
706 HILOGI("MECHBODY_EXEC_DISCONNECT OnGattDisconnect will enter.");
707
708 std::unique_lock<std::mutex> lock(gattDisconnMutex_);
709 if (!gattDisconnCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_TEN),
710 [this, mechInfo]() mutable {
711 bool gattState = true;
712 MechConnectManager::GetInstance().GetMechanicGattState(mechInfo.mac, gattState);
713 return !gattState;
714 })) {
715 HILOGE("MECHBODY_EXEC_DISCONNECT wait for gatt connect timeout");
716 return MECHBODY_GATT_CONNECT_FAILED;
717 }
718 OnGattDisconnect(mechInfo);
719 HILOGI("MECHBODY_EXEC_DISCONNECT disconnect end mechInfo: %{public}s", mechInfo.ToString().c_str());
720 return status;
721 }
722
MechbodyHidDisconnect(MechInfo & mechInfo)723 int32_t BleSendManager::MechbodyHidDisconnect(MechInfo &mechInfo)
724 {
725 HILOGI("MECHBODY_EXEC_DISCONNECT start");
726 Bluetooth::BluetoothRemoteDevice remoteDevice =
727 Bluetooth::BluetoothRemoteDevice(mechInfo.mac, Bluetooth::BT_TRANSPORT_BLE);
728 int32_t res = Bluetooth::HidHost::GetProfile()->Disconnect(remoteDevice);
729 HILOGI("MECHBODY_EXEC_DISCONNECT end. hid Disconnect result: %{public}d;", res);
730
731 std::unique_lock<std::mutex> lock(hidDisconnMutex_);
732 if (!hidDisconnCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_TEN),
733 [this, mechInfo]() mutable {
734 bool hidState = true;
735 MechConnectManager::GetInstance().GetMechanicHidState(mechInfo.mac, hidState);
736 return !hidState;
737 })) {
738 HILOGE("MECHBODY_EXEC_DISCONNECT wait for hid disconnect timeout");
739 return ERR_OK;
740 }
741 HILOGI("MECHBODY_EXEC_DISCONNECT disconnect end mechInfo: %{public}s", mechInfo.ToString().c_str());
742 HILOGI("MECHBODY_EXEC_CONNECT RemovePair start.");
743 res = Bluetooth::BluetoothHost::GetDefaultHost().RemovePair(remoteDevice);
744 HILOGI("MECHBODY_EXEC_CONNECT RemovePair end, result: %{public}d", res);
745 return ERR_OK;
746 }
747
MechbodyGattcWriteCharacteristic(uint8_t * data,uint32_t dataLen)748 int32_t BleSendManager::MechbodyGattcWriteCharacteristic(uint8_t *data, uint32_t dataLen)
749 {
750 HILOGD("WriteCharacteristic start");
751 int32_t result = -1;
752 if (data == nullptr || dataLen <= BUF_MIN_LEN) {
753 HILOGE("data is nullptr or len is not enough");
754 return MECHBODY_GATT_INVALID_PARAM;
755 }
756 if (gattClient_ == nullptr) {
757 HILOGE("gattClient_ is nullptr");
758 return MECHBODY_GATT_INVALID_PARAM;
759 }
760 GattCharacteristic wrCharacteristic = GattCharacteristic(MECHBODY_CHARACTERISTIC_WRITE_UUID,
761 handle_, permissions_, properties_);
762 wrCharacteristic.SetValue(data, dataLen);
763 wrCharacteristic.SetWriteType(GattCharacteristic::WriteType::DEFAULT);
764 HILOGD("Mech writeC");
765 result = gattClient_->WriteCharacteristic(wrCharacteristic);
766 HILOGI("Mech writeC, result = %{public}d handle: %{public}d dataLen: %{public}d \n", \
767 result, handle_, dataLen);
768 return result;
769 }
770
SendData(uint8_t * data,uint32_t dataLen)771 int32_t BleSendManager::SendData(uint8_t *data, uint32_t dataLen)
772 {
773 HILOGD("ble send start.");
774 if (data == NULL) {
775 HILOGE("ble client send data failed, invalia param, data is null");
776 return MECHBODY_GATT_INVALID_PARAM;
777 }
778 if (!(dataLen >= BUF_MIN_LEN && dataLen <= BUF_MAX_LEN)) {
779 HILOGE("ble client send data failed, data length is out of range, data len: %{public}d", dataLen);
780 return MECHBODY_GATT_INVALID_PARAM;
781 }
782 int32_t result = MechbodyGattcWriteCharacteristic(data, dataLen);
783 HILOGD("write SendData dataLen= %{public}d, result = %{public}d", dataLen, result);
784 return result;
785 }
786
OnScanCallback(const Bluetooth::BleScanResult & result)787 void BleCentralManagerCallbackImpl::OnScanCallback(const Bluetooth::BleScanResult &result)
788 {
789 HILOGI("ble impl OnScanCallback start");
790 BleSendManager& bleSendManager = BleSendManager::GetInstance();
791 bleSendManager.OnScanCallback(result);
792 HILOGI("ble impl OnScanCallback end");
793 }
794
OnAclStateChanged(const OHOS::Bluetooth::BluetoothRemoteDevice & device,int state,unsigned int reason)795 void HostObserver::OnAclStateChanged(const OHOS::Bluetooth::BluetoothRemoteDevice &device,
796 int state, unsigned int reason)
797 {}
798
OnPairStatusChanged(const OHOS::Bluetooth::BluetoothRemoteDevice & device,int status,int cause)799 void HostObserver::OnPairStatusChanged(const OHOS::Bluetooth::BluetoothRemoteDevice &device, int status, int cause)
800 {
801 std::string address = device.GetDeviceAddr();
802 HILOGI("MECHBODY_EXEC_DISCONNECT address: %{public}s;", GetAnonymStr(address).c_str());
803 MechInfo mechInfo;
804 if (MechConnectManager::GetInstance().GetMechInfo(address, mechInfo) != ERR_OK) {
805 HILOGI("MECHBODY_EXEC_DISCONNECT The equipment is not covered by this service. "
806 "mac: %{public}s; state: %{public}d", GetAnonymStr(address).c_str(), status);
807 return;
808 }
809 BleSendManager::GetInstance().OnPairStateChanged(status, cause, mechInfo);
810 }
811
OnRemoteUuidChanged(const OHOS::Bluetooth::BluetoothRemoteDevice & device,const std::vector<Bluetooth::ParcelUuid> & uuids)812 void HostObserver::OnRemoteUuidChanged(const OHOS::Bluetooth::BluetoothRemoteDevice &device,
813 const std::vector<Bluetooth::ParcelUuid> &uuids)
814 {}
815
OnRemoteNameChanged(const OHOS::Bluetooth::BluetoothRemoteDevice & device,const std::string & deviceName)816 void HostObserver::OnRemoteNameChanged(const OHOS::Bluetooth::BluetoothRemoteDevice &device,
817 const std::string &deviceName)
818 {}
819
OnRemoteAliasChanged(const OHOS::Bluetooth::BluetoothRemoteDevice & device,const std::string & alias)820 void HostObserver::OnRemoteAliasChanged(const OHOS::Bluetooth::BluetoothRemoteDevice &device, const std::string &alias)
821 {}
822
OnRemoteCodChanged(const OHOS::Bluetooth::BluetoothRemoteDevice & device,const OHOS::Bluetooth::BluetoothDeviceClass & cod)823 void HostObserver::OnRemoteCodChanged(const OHOS::Bluetooth::BluetoothRemoteDevice &device,
824 const OHOS::Bluetooth::BluetoothDeviceClass &cod)
825 {}
826
OnRemoteBatteryLevelChanged(const OHOS::Bluetooth::BluetoothRemoteDevice & device,int batteryLevel)827 void HostObserver::OnRemoteBatteryLevelChanged(const OHOS::Bluetooth::BluetoothRemoteDevice &device, int batteryLevel)
828 {}
829
OnReadRemoteRssiEvent(const OHOS::Bluetooth::BluetoothRemoteDevice & device,int rssi,int status)830 void HostObserver::OnReadRemoteRssiEvent(const OHOS::Bluetooth::BluetoothRemoteDevice &device, int rssi, int status)
831 {}
832
OnRemoteBatteryChanged(const OHOS::Bluetooth::BluetoothRemoteDevice & device,const OHOS::Bluetooth::DeviceBatteryInfo & batteryInfo)833 void HostObserver::OnRemoteBatteryChanged(const OHOS::Bluetooth::BluetoothRemoteDevice &device,
834 const OHOS::Bluetooth::DeviceBatteryInfo &batteryInfo)
835 {}
836
OnRemoteDeviceCommonInfoReport(const OHOS::Bluetooth::BluetoothRemoteDevice & device,const std::vector<uint8_t> & value)837 void HostObserver::OnRemoteDeviceCommonInfoReport(const OHOS::Bluetooth::BluetoothRemoteDevice &device,
838 const std::vector<uint8_t> &value)
839 {}
840
OnConnectionStateChanged(const OHOS::Bluetooth::BluetoothRemoteDevice & device,int state,int cause)841 void HidObserver::OnConnectionStateChanged(const OHOS::Bluetooth::BluetoothRemoteDevice &device, int state, int cause)
842 {
843 std::string address = device.GetDeviceAddr();
844 HILOGI("MECHBODY_EXEC_DISCONNECT address: %{public}s;", GetAnonymStr(address).c_str());
845 MechInfo mechInfo;
846 if (MechConnectManager::GetInstance().GetMechInfo(address, mechInfo) != ERR_OK) {
847 HILOGI("MECHBODY_EXEC_DISCONNECT The equipment is not covered by this service. "
848 "mac: %{public}s; state: %{public}d", GetAnonymStr(address).c_str(), state);
849 return;
850 }
851 BleSendManager::GetInstance().OnHidStateChanged(state, cause, mechInfo);
852 }
853
854 } // namespace MechBodyController
855 } // namespace OHOS