1 /*
2 * Copyright (c) 2024 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 "wifi_direct_executor.h"
16
17 #include <utility>
18
19 #include "wifi_direct_scheduler.h"
20 #include "data/link_manager.h"
21 #include "event/wifi_direct_event_dispatcher.h"
22 #include "conn_log.h"
23 #include "utils/wifi_direct_anonymous.h"
24 #include "utils/wifi_direct_utils.h"
25 #include "wifi_direct_scheduler_factory.h"
26 #include "command/negotiate_command.h"
27
28 namespace OHOS::SoftBus {
WifiDirectExecutor(const std::string & remoteDeviceId,WifiDirectScheduler & scheduler,std::shared_ptr<WifiDirectProcessor> & processor,bool active)29 WifiDirectExecutor::WifiDirectExecutor(const std::string &remoteDeviceId, WifiDirectScheduler &scheduler,
30 std::shared_ptr<WifiDirectProcessor> &processor, bool active)
31 : remoteDeviceId_(remoteDeviceId), scheduler_(scheduler), processor_(processor), active_(active), started_(false)
32 {
33 CONN_LOGI(CONN_WIFI_DIRECT, "remoteDeviceId=%{public}s, active=%{public}d",
34 WifiDirectAnonymizeDeviceId(remoteDeviceId_).c_str(), active_);
35 }
36
~WifiDirectExecutor()37 WifiDirectExecutor::~WifiDirectExecutor()
38 {
39 CONN_LOGI(CONN_WIFI_DIRECT, "remoteDeviceId=%{public}s", WifiDirectAnonymizeDeviceId(remoteDeviceId_).c_str());
40 }
41
Start()42 void WifiDirectExecutor::Start()
43 {
44 if (started_) {
45 CONN_LOGI(CONN_WIFI_DIRECT, "remoteDeviceId=%{public}s repeat start, ignore",
46 WifiDirectAnonymizeDeviceId(remoteDeviceId_).c_str());
47 return;
48 }
49 started_ = true;
50 std::thread thread(&WifiDirectExecutor::Run, this, processor_);
51 thread_.swap(thread);
52 thread_.detach();
53 }
54
Run(std::shared_ptr<WifiDirectProcessor> processor)55 void WifiDirectExecutor::Run(std::shared_ptr<WifiDirectProcessor> processor)
56 {
57 processor_ = std::move(processor);
58 do {
59 if (IsActive()) {
60 WifiDirectTrace::StartTrace(WifiDirectUtils::GetLocalUuid(), remoteDeviceId_);
61 } else {
62 WifiDirectTrace::StartTrace(remoteDeviceId_, WifiDirectUtils::GetLocalUuid());
63 }
64
65 processor_->BindExecutor(this);
66 try {
67 CONN_LOGI(CONN_WIFI_DIRECT, "processor run");
68 processor_->Run();
69 } catch (const ProcessorTerminate &) {
70 LinkManager::GetInstance().Dump();
71 CONN_LOGI(CONN_WIFI_DIRECT, "processor terminate");
72 ProcessUnHandleCommand();
73 }
74
75 std::lock_guard lock(processorLock_);
76 processor_ = nullptr;
77 WifiDirectTrace::StopTrace();
78 } while (scheduler_.ProcessNextCommand(this, processor_));
79
80 CONN_LOGI(CONN_WIFI_DIRECT, "executor terminate");
81 }
82
GetRemoteDeviceId()83 std::string WifiDirectExecutor::GetRemoteDeviceId()
84 {
85 return remoteDeviceId_;
86 }
87
SetRemoteDeviceId(const std::string & remoteDeviceId)88 void WifiDirectExecutor::SetRemoteDeviceId(const std::string &remoteDeviceId)
89 {
90 remoteDeviceId_ = remoteDeviceId;
91 }
92
IsActive() const93 bool WifiDirectExecutor::IsActive() const
94 {
95 return active_;
96 }
97
SetActive(bool active)98 void WifiDirectExecutor::SetActive(bool active)
99 {
100 active_ = active;
101 }
102
CanAcceptNegotiateData(WifiDirectCommand & command)103 bool WifiDirectExecutor::CanAcceptNegotiateData(WifiDirectCommand &command)
104 {
105 std::lock_guard lock(processorLock_);
106 if (processor_ == nullptr) {
107 return false;
108 }
109 return processor_->CanAcceptNegotiateData(command);
110 }
111
WaitEvent()112 WifiDirectEventDispatcher WifiDirectExecutor::WaitEvent()
113 {
114 return receiver_.Wait();
115 }
116
ProcessUnHandleCommand()117 void WifiDirectExecutor::ProcessUnHandleCommand()
118 {
119 CONN_LOGI(CONN_WIFI_DIRECT, "enter");
120 WifiDirectSchedulerFactory::GetInstance().GetScheduler().RejectNegotiateData(*processor_);
121 GetSender().ProcessUnHandle([this](std::shared_ptr<WifiDirectEventBase> &content) {
122 auto ncw =
123 std::dynamic_pointer_cast<WifiDirectEventWrapper<std::shared_ptr<NegotiateCommand>>>(content);
124 if (ncw != nullptr) {
125 processor_->HandleCommandAfterTerminate(*ncw->content_);
126 return;
127 }
128 });
129 GetSender().Clear();
130 }
131
132 }
133