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 #ifndef WIFI_DIRECT_SCHEDULER_H 16 #define WIFI_DIRECT_SCHEDULER_H 17 18 #include <list> 19 #include <map> 20 #include <mutex> 21 #include <memory> 22 #include <string> 23 #include <thread> 24 #include "wifi_direct_types.h" 25 #include "wifi_direct_executor.h" 26 #include "command/wifi_direct_command.h" 27 #include "command/connect_command.h" 28 #include "event/wifi_direct_event_wrapper.h" 29 #include "utils/wifi_direct_anonymous.h" 30 #include "utils/wifi_direct_utils.h" 31 #include "wifi_direct_executor_factory.h" 32 33 namespace OHOS::SoftBus { 34 class WifiDirectSchedulerFactory; 35 class WifiDirectScheduler { 36 public: 37 virtual ~WifiDirectScheduler() = default; 38 39 int ConnectDevice(const WifiDirectConnectInfo &info, const WifiDirectConnectCallback &callback, 40 bool markRetried = false); 41 int ConnectDevice(const std::shared_ptr<ConnectCommand> &command, bool markRetried = false); 42 int CancelConnectDevice(const WifiDirectConnectInfo &info); 43 int DisconnectDevice(WifiDirectDisconnectInfo &info, WifiDirectDisconnectCallback &callback); 44 int ForceDisconnectDevice(WifiDirectForceDisconnectInfo &info, WifiDirectDisconnectCallback &callback); 45 46 template<typename Command> ProcessNegotiateData(const std::string & remoteDeviceId,Command & command)47 void ProcessNegotiateData(const std::string &remoteDeviceId, Command &command) 48 { 49 auto aDeviceId = WifiDirectAnonymizeDeviceId(remoteDeviceId); 50 CONN_LOGD(CONN_WIFI_DIRECT, "remoteDeviceId=%{public}s", aDeviceId.c_str()); 51 std::lock_guard executorLock(executorLock_); 52 auto it = executors_.find(remoteDeviceId); 53 if (it != executors_.end()) { 54 if (it->second->CanAcceptNegotiateData(command)) { 55 CONN_LOGI(CONN_WIFI_DIRECT, "send command to executor=%{public}s, commandId=%{public}d", 56 aDeviceId.c_str(), command.GetId()); 57 it->second->SendEvent(std::make_shared<Command>(command)); 58 return; 59 } 60 std::lock_guard commandLock(commandLock_); 61 CONN_LOGI(CONN_WIFI_DIRECT, "push command to list, commandId=%{public}u", command.GetId()); 62 commandList_.push_back(std::make_shared<Command>(command)); 63 return; 64 } 65 66 if (executors_.size() == MAX_EXECUTOR) { 67 CONN_LOGI(CONN_WIFI_DIRECT, "push command to list, commandId=%{public}u", command.GetId()); 68 std::lock_guard commandLock(commandLock_); 69 commandList_.push_back(std::make_shared<Command>(command)); 70 return; 71 } 72 73 auto processor = command.GetProcessor(); 74 if (processor == nullptr) { 75 CONN_LOGE(CONN_WIFI_DIRECT, "get processor failed"); 76 return; 77 } 78 auto executor = WifiDirectExecutorFactory::GetInstance().NewExecutor(remoteDeviceId, *this, processor, false); 79 if (executor == nullptr) { 80 return; 81 } 82 executors_.insert({ remoteDeviceId, executor }); 83 CONN_LOGI(CONN_WIFI_DIRECT, "send command to executor=%{public}s, commandId=%{public}d", 84 aDeviceId.c_str(), command.GetId()); 85 executor->SendEvent(std::make_shared<Command>(command)); 86 } 87 88 template<typename Event> ProcessEvent(const std::string & remoteDeviceId,const Event & event)89 void ProcessEvent(const std::string &remoteDeviceId, const Event &event) 90 { 91 std::lock_guard lock(executorLock_); 92 auto it = executors_.find(remoteDeviceId); 93 if (it == executors_.end()) { 94 CONN_LOGE(CONN_WIFI_DIRECT, "executor not exist, remoteDeviceId=%{public}s", 95 WifiDirectAnonymizeDeviceId(remoteDeviceId).c_str()); 96 return; 97 } 98 99 CONN_LOGI(CONN_WIFI_DIRECT, "send event to executor=%{public}s", 100 WifiDirectAnonymizeDeviceId(remoteDeviceId).c_str()); 101 auto content = std::make_shared<Event>(event); 102 it->second->SendEvent(content); 103 } 104 105 template<typename Command> QueueCommandFront(Command & command)106 void QueueCommandFront(Command &command) 107 { 108 std::lock_guard commandLock(commandLock_); 109 CONN_LOGI(CONN_WIFI_DIRECT, "push data to list front"); 110 commandList_.push_front(std::make_shared<Command>(command)); 111 } 112 113 template<typename Command> QueueCommandBack(Command & command)114 void QueueCommandBack(Command &command) 115 { 116 std::lock_guard commandLock(commandLock_); 117 CONN_LOGI(CONN_WIFI_DIRECT, "push data to list back"); 118 commandList_.push_back(std::make_shared<Command>(command)); 119 } 120 121 template<typename Command> FetchAndDispatchCommand(const std::string & remoteDeviceId)122 void FetchAndDispatchCommand(const std::string &remoteDeviceId) 123 { 124 std::lock_guard executorLock(executorLock_); 125 auto eit = executors_.find(remoteDeviceId); 126 if (eit == executors_.end()) { 127 return; 128 } 129 130 std::lock_guard commandLock(commandLock_); 131 for (auto cit = commandList_.begin(); cit != commandList_.end(); cit++) { 132 auto &command = *cit; 133 if (command->GetRemoteDeviceId() != remoteDeviceId) { 134 continue; 135 } 136 auto cmd = std::dynamic_pointer_cast<Command>(command); 137 if (cmd != nullptr) { 138 CONN_LOGI(CONN_WIFI_DIRECT, "type=%{public}d, commandId=%{public}u", 139 static_cast<int>(command->GetType()), command->GetId()); 140 eit->second->SendEvent(cmd); 141 commandList_.erase(cit); 142 return; 143 } 144 } 145 } 146 RejectNegotiateData(WifiDirectProcessor & processor)147 void RejectNegotiateData(WifiDirectProcessor &processor) 148 { 149 std::lock_guard executorLock(executorLock_); 150 processor.SetRejectNegotiateData(); 151 } 152 153 virtual bool ProcessNextCommand(WifiDirectExecutor *executor, std::shared_ptr<WifiDirectProcessor> &processor); 154 CheckExecutorRunning(const std::string & remoteDeviceId)155 bool CheckExecutorRunning(const std::string &remoteDeviceId) 156 { 157 std::lock_guard executorLock(executorLock_); 158 auto iterator = executors_.find(remoteDeviceId); 159 return iterator != executors_.end(); 160 } 161 162 protected: 163 int ScheduleActiveCommand(const std::shared_ptr<WifiDirectCommand> &command, 164 std::shared_ptr<WifiDirectExecutor> &executor); 165 static void DumpNegotiateChannel(const WifiDirectNegotiateChannel &channel); 166 167 static constexpr int MAX_EXECUTOR = 8; 168 std::recursive_mutex executorLock_; 169 std::map<std::string, std::shared_ptr<WifiDirectExecutor>> executors_; 170 std::recursive_mutex commandLock_; 171 std::list<std::shared_ptr<WifiDirectCommand>> commandList_; 172 173 private: 174 friend WifiDirectSchedulerFactory; GetInstance()175 static WifiDirectScheduler& GetInstance() 176 { 177 static WifiDirectScheduler instance; 178 return instance; 179 } 180 }; 181 } 182 #endif 183