1 /*
2 * Copyright (c) 2021-2023 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 "network/network_agent_template.h"
17
18 #include "device/device_manager_agent.h"
19 #include "dfsu_exception.h"
20 #include "utils_log.h"
21
22 namespace OHOS {
23 namespace Storage {
24 namespace DistributedFile {
25 using namespace std;
26 namespace {
27 constexpr int MAX_RETRY_COUNT = 7;
28 constexpr int OPEN_SESSSION_DELAY_TIME = 100;
29 } // namespace
30
Start()31 void NetworkAgentTemplate::Start()
32 {
33 JoinDomain();
34 kernerlTalker_->CreatePollThread();
35 ConnectOnlineDevices();
36 }
37
Stop()38 void NetworkAgentTemplate::Stop()
39 {
40 StopTopHalf();
41 StopBottomHalf();
42 kernerlTalker_->WaitForPollThreadExited();
43 }
44
ConnectDeviceAsync(const DeviceInfo info)45 void NetworkAgentTemplate::ConnectDeviceAsync(const DeviceInfo info)
46 {
47 std::this_thread::sleep_for(std::chrono::milliseconds(
48 OPEN_SESSSION_DELAY_TIME)); // Temporary workaround for time sequence issues(offline-onSessionOpened)
49 OpenSession(info, LINK_TYPE_AP);
50 }
51
ConnectDeviceByP2PAsync(const DeviceInfo info)52 void NetworkAgentTemplate::ConnectDeviceByP2PAsync(const DeviceInfo info)
53 {
54 std::this_thread::sleep_for(std::chrono::milliseconds(OPEN_SESSSION_DELAY_TIME));
55 OpenSession(info, LINK_TYPE_P2P);
56 }
57
ConnectOnlineDevices()58 void NetworkAgentTemplate::ConnectOnlineDevices()
59 {
60 string pkgName = IDaemon::SERVICE_NAME;
61 auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
62
63 auto dma = DeviceManagerAgent::GetInstance();
64 auto infos = dma->GetRemoteDevicesInfo();
65 LOGI("Have %{public}zu devices Online", infos.size());
66 for (const auto &info : infos) {
67 int32_t networkType;
68 int errCode = deviceManager.GetNetworkTypeByNetworkId(pkgName, info.GetCid(), networkType);
69 if (errCode) {
70 LOGE("failed to get network type by network id errCode = %{public}d", errCode);
71 continue;
72 }
73 if (!(networkType & (1 << DistributedHardware::BIT_NETWORK_TYPE_WIFI))) {
74 LOGI("not wifi network networkType = %{public}d == %{public}d", networkType,
75 1 << DistributedHardware::BIT_NETWORK_TYPE_WIFI);
76 continue;
77 }
78
79 auto cmd = make_unique<DfsuCmd<NetworkAgentTemplate, const DeviceInfo>>(
80 &NetworkAgentTemplate::ConnectDeviceAsync, info);
81 cmd->UpdateOption({.tryTimes_ = MAX_RETRY_COUNT});
82 Recv(move(cmd));
83 }
84 }
85
DisconnectAllDevices()86 void NetworkAgentTemplate::DisconnectAllDevices()
87 {
88 sessionPool_.ReleaseAllSession();
89 }
90
DisconnectDevice(const DeviceInfo info)91 void NetworkAgentTemplate::DisconnectDevice(const DeviceInfo info)
92 {
93 LOGI("DeviceOffline, cid:%{public}s", info.GetCid().c_str());
94 sessionPool_.ReleaseSession(info.GetCid(), LINK_TYPE_AP);
95 }
96
DisconnectDeviceByP2P(const DeviceInfo info)97 void NetworkAgentTemplate::DisconnectDeviceByP2P(const DeviceInfo info)
98 {
99 LOGI("DeviceOffline, cid:%{public}s", info.GetCid().c_str());
100 sessionPool_.ReleaseSession(info.GetCid(), LINK_TYPE_P2P);
101 }
102
OccupySession(int sessionId,uint8_t linkType)103 void NetworkAgentTemplate::OccupySession(int sessionId, uint8_t linkType)
104 {
105 sessionPool_.OccupySession(sessionId, linkType);
106 }
107
FindSession(int sessionId)108 bool NetworkAgentTemplate::FindSession(int sessionId)
109 {
110 return sessionPool_.FindSession(sessionId);
111 }
112
CloseSessionForOneDevice(const string & cid)113 void NetworkAgentTemplate::CloseSessionForOneDevice(const string &cid)
114 {
115 (void)cid;
116 LOGI("session closed!");
117 }
118
AcceptSession(shared_ptr<BaseSession> session)119 void NetworkAgentTemplate::AcceptSession(shared_ptr<BaseSession> session)
120 {
121 auto cmd = make_unique<DfsuCmd<NetworkAgentTemplate, shared_ptr<BaseSession>>>(
122 &NetworkAgentTemplate::AcceptSessionInner, session);
123 cmd->UpdateOption({.tryTimes_ = 1});
124 Recv(move(cmd));
125 }
126
AcceptSessionInner(shared_ptr<BaseSession> session)127 void NetworkAgentTemplate::AcceptSessionInner(shared_ptr<BaseSession> session)
128 {
129 auto cid = session->GetCid();
130 LOGI("AcceptSesion, cid:%{public}s", cid.c_str());
131 sessionPool_.HoldSession(session);
132 }
133
GetSessionProcess(NotifyParam & param)134 void NetworkAgentTemplate::GetSessionProcess(NotifyParam ¶m)
135 {
136 auto cmd = make_unique<DfsuCmd<NetworkAgentTemplate, NotifyParam>>(
137 &NetworkAgentTemplate::GetSessionProcessInner, param);
138 cmd->UpdateOption({.tryTimes_ = 1});
139 Recv(move(cmd));
140 }
141
GetSessionProcessInner(NotifyParam param)142 void NetworkAgentTemplate::GetSessionProcessInner(NotifyParam param)
143 {
144 string cidStr(param.remoteCid, CID_MAX_LEN);
145 int fd = param.fd;
146 LOGI("NOTIFY_GET_SESSION, old fd %{public}d, remote cid %{public}s", fd, cidStr.c_str());
147 uint8_t linkType = sessionPool_.ReleaseSession(fd);
148 GetSession(cidStr, linkType);
149 }
150
GetSession(const string & cid,uint8_t linkType)151 void NetworkAgentTemplate::GetSession(const string &cid, uint8_t linkType)
152 {
153 DeviceInfo deviceInfo;
154 deviceInfo.SetCid(cid);
155 try {
156 OpenSession(deviceInfo, linkType);
157 } catch (const DfsuException &e) {
158 LOGE("reget session failed, code: %{public}d", e.code());
159 }
160 }
161 } // namespace DistributedFile
162 } // namespace Storage
163 } // namespace OHOS
164