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 "connect_command.h"
16 
17 #include <cstring>
18 
19 #include "conn_log.h"
20 
21 #include "channel/auth_negotiate_channel.h"
22 #include "channel/dummy_negotiate_channel.h"
23 #include "channel/proxy_negotiate_channel.h"
24 #include "data/link_manager.h"
25 #include "event/wifi_direct_event_dispatcher.h"
26 #include "processor_selector_factory.h"
27 #include "utils/wifi_direct_anonymous.h"
28 #include "utils/wifi_direct_utils.h"
29 #include "utils/wifi_direct_dfx.h"
30 #include "wifi_direct_scheduler_factory.h"
31 
32 namespace OHOS::SoftBus {
ConnectCommand(const WifiDirectConnectInfo & info,const WifiDirectConnectCallback & callback)33 ConnectCommand::ConnectCommand(const WifiDirectConnectInfo &info, const WifiDirectConnectCallback &callback)
34     : callback_(callback)
35 {
36     info_.info_ = info;
37     if (strlen(info.remoteNetworkId) != 0) {
38         remoteDeviceId_ = WifiDirectUtils::NetworkIdToUuid(info_.info_.remoteNetworkId);
39         return;
40     }
41     CONN_LOGE(CONN_WIFI_DIRECT, "remoteNetworkId empty!!");
42 }
43 
GetRemoteDeviceId() const44 std::string ConnectCommand::GetRemoteDeviceId() const
45 {
46     if (!remoteDeviceId_.empty()) {
47         return remoteDeviceId_;
48     }
49     remoteDeviceId_ = WifiDirectUtils::NetworkIdToUuid(info_.info_.remoteNetworkId);
50     return remoteDeviceId_;
51 }
52 
GetProcessor()53 std::shared_ptr<WifiDirectProcessor> ConnectCommand::GetProcessor()
54 {
55     CONN_LOGI(CONN_WIFI_DIRECT, "enter");
56     auto selector = ProcessorSelectorFactory::GetInstance().NewSelector();
57     if (selector == nullptr) {
58         CONN_LOGE(CONN_WIFI_DIRECT, "selector is null");
59         return nullptr;
60     }
61     return (*selector)(info_.info_);
62 }
63 
GetConnectInfo()64 ConnectInfo &ConnectCommand::GetConnectInfo()
65 {
66     return info_;
67 }
68 
GetConnectCallback() const69 WifiDirectConnectCallback ConnectCommand::GetConnectCallback() const
70 {
71     return callback_;
72 }
73 
SetSuccessCallback(const SuccessCallback & callback)74 void ConnectCommand::SetSuccessCallback(const SuccessCallback &callback)
75 {
76     successCallback_ = callback;
77 }
78 
SetFailureCallback(const FailureCallback & callback)79 void ConnectCommand::SetFailureCallback(const FailureCallback &callback)
80 {
81     failureCallback_ = callback;
82 }
83 
OnSuccess(const WifiDirectLink & link) const84 void ConnectCommand::OnSuccess(const WifiDirectLink &link) const
85 {
86     CONN_LOGI(CONN_WIFI_DIRECT,
87         "requestId=%{public}u, linkId=%{public}d, localIp=%{public}s, remoteIp=%{public}s, remotePort=%{public}d, "
88         "linkType=%{public}d, isReuse=%{public}d, bw=%{public}d, channelId=%{public}d, remoteDeviceId=%{public}s",
89         info_.info_.requestId, link.linkId, WifiDirectAnonymizeIp(link.localIp).c_str(),
90         WifiDirectAnonymizeIp(link.remoteIp).c_str(), link.remotePort, link.linkType, link.isReuse, link.bandWidth,
91         link.channelId, WifiDirectAnonymizeDeviceId(remoteDeviceId_).c_str());
92     if (successCallback_ != nullptr) {
93         successCallback_(link);
94         return;
95     }
96     WifiDirectDfx::GetInstance().DfxRecord(true, SOFTBUS_OK, info_);
97     if (callback_.onConnectSuccess != nullptr) {
98         callback_.onConnectSuccess(info_.info_.requestId, &link);
99     }
100 }
101 
OnFailure(int32_t reason) const102 void ConnectCommand::OnFailure(int32_t reason) const
103 {
104     CONN_LOGI(CONN_WIFI_DIRECT, "requestId=%{public}u, reason=%{public}d, remoteDeviceId=%{public}s",
105         info_.info_.requestId, reason, WifiDirectAnonymizeDeviceId(remoteDeviceId_).c_str());
106     if (reason == SOFTBUS_CONN_NEED_RENEGOTIATE && !HasRetried()) {
107         CONN_LOGI(CONN_WIFI_DIRECT, "retry");
108         WifiDirectSchedulerFactory::GetInstance().GetScheduler().ConnectDevice(info_.info_, callback_, true);
109         return;
110     }
111     if (failureCallback_ != nullptr) {
112         failureCallback_(reason);
113         return;
114     }
115     WifiDirectDfx::GetInstance().DfxRecord(false, reason, info_);
116     if (callback_.onConnectFailure != nullptr) {
117         callback_.onConnectFailure(info_.info_.requestId, reason);
118     }
119 }
120 
PreferNegotiateChannel()121 void ConnectCommand::PreferNegotiateChannel()
122 {
123     auto innerLink = LinkManager::GetInstance().GetReuseLink(info_.info_.connectType, remoteDeviceId_);
124     if (remoteDeviceId_.length() != (UUID_BUF_LEN - 1) && innerLink == nullptr) {
125         innerLink = LinkManager::GetInstance().GetReuseLink(remoteDeviceId_);
126     }
127     if (innerLink == nullptr || innerLink->GetNegotiateChannel() == nullptr) {
128         if (info_.info_.negoChannel.type == NEGO_CHANNEL_AUTH) {
129             CONN_LOGI(CONN_WIFI_DIRECT, "prefer input auth channel");
130             info_.channel_ = std::make_shared<AuthNegotiateChannel>(info_.info_.negoChannel.handle.authHandle);
131         } else if (info_.info_.negoChannel.type == NEGO_CHANNEL_COC) {
132             CONN_LOGI(CONN_WIFI_DIRECT, "prefer input proxy channel");
133             info_.channel_ = std::make_shared<CoCProxyNegotiateChannel>(info_.info_.negoChannel.handle.channelId);
134         } else {
135             CONN_LOGI(CONN_WIFI_DIRECT, "prefer input null channel");
136             info_.channel_ = std::make_shared<DummyNegotiateChannel>();
137         }
138         return;
139     }
140 
141     CONN_LOGI(CONN_WIFI_DIRECT, "prefer inner channel");
142     info_.channel_ = innerLink->GetNegotiateChannel();
143 }
144 
IsSameCommand(const WifiDirectConnectInfo & info) const145 bool ConnectCommand::IsSameCommand(const WifiDirectConnectInfo &info) const
146 {
147     return (info.requestId == info_.info_.requestId) && (info.pid == info_.info_.pid);
148 }
149 } // namespace OHOS::SoftBus
150