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