• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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