• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 
16 #include "network/network_agent_template.h"
17 
18 #include "connect_count/connect_count.h"
19 #include "device/device_manager_agent.h"
20 #include "dfs_error.h"
21 #include "dfsu_exception.h"
22 #include "utils_log.h"
23 
24 namespace OHOS {
25 namespace Storage {
26 namespace DistributedFile {
27 using namespace std;
28 namespace {
29 constexpr int32_t DEVICE_OS_TYPE_OH = 10;
30 constexpr int OPEN_SESSSION_DELAY_TIME = 100;
31 constexpr int32_t NOTIFY_GET_SESSION_WAITING_TIME = 2;
32 constexpr const char* PARAM_KEY_OS_TYPE = "OS_TYPE";
33 } // namespace
34 
Start()35 void NetworkAgentTemplate::Start()
36 {
37     if (kernerlTalker_ == nullptr) {
38         LOGE("kernerlTalker_ is nullptr.");
39         return;
40     }
41     LOGI("Start Enter");
42     JoinDomain();
43     kernerlTalker_->CreatePollThread();
44     ConnectOnlineDevices();
45 }
46 
Stop()47 void NetworkAgentTemplate::Stop()
48 {
49     if (kernerlTalker_ == nullptr) {
50         LOGE("kernerlTalker_ is nullptr.");
51         return;
52     }
53     LOGI("Stop Enter");
54     StopTopHalf();
55     StopBottomHalf();
56     kernerlTalker_->WaitForPollThreadExited();
57 }
58 
ConnectDeviceByP2PAsync(const DeviceInfo info)59 void NetworkAgentTemplate::ConnectDeviceByP2PAsync(const DeviceInfo info)
60 {
61     LOGI("ConnectDeviceByP2PAsync Enter");
62     std::this_thread::sleep_for(std::chrono::milliseconds(OPEN_SESSSION_DELAY_TIME));
63     OpenSession(info, LINK_TYPE_P2P);
64 }
65 
ConnectOnlineDevices()66 void NetworkAgentTemplate::ConnectOnlineDevices()
67 {
68     string pkgName = IDaemon::SERVICE_NAME;
69     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
70 
71     auto dma = DeviceManagerAgent::GetInstance();
72     auto infos = dma->GetRemoteDevicesInfo();
73     LOGI("Have %{public}zu devices Online", infos.size());
74     for (const auto &info : infos) {
75         if (info.GetExtraData().empty()) {
76             LOGE("extraData is empty.");
77             return;
78         }
79         nlohmann::json entraDataJson = nlohmann::json::parse(info.GetExtraData(), nullptr, false);
80         if (entraDataJson.is_discarded()) {
81             LOGE("entraDataJson parse failed.");
82             return;
83         }
84         if (!Utils::IsInt32(entraDataJson, PARAM_KEY_OS_TYPE)) {
85             LOGE("error json int32_t param.");
86             return;
87         }
88         int32_t osType = entraDataJson[PARAM_KEY_OS_TYPE].get<int32_t>();
89         if (osType != DEVICE_OS_TYPE_OH) {
90             LOGE("%{private}s  the device os type = %{private}d is not openharmony.",
91                 Utils::GetAnonyString(info.GetCid()).c_str(), osType);
92             return;
93         }
94 
95         int32_t networkType;
96         int errCode = deviceManager.GetNetworkTypeByNetworkId(pkgName, info.GetCid(), networkType);
97         if (errCode) {
98             LOGE("failed to get network type by network id errCode = %{public}d", errCode);
99             continue;
100         }
101         if (!(static_cast<uint32_t>(networkType) & (1 << DistributedHardware::BIT_NETWORK_TYPE_WIFI))) {
102             LOGI("not wifi network networkType = %{public}d == %{public}d", networkType,
103                  1 << DistributedHardware::BIT_NETWORK_TYPE_WIFI);
104             continue;
105         }
106     }
107 }
108 
DisconnectAllDevices()109 void NetworkAgentTemplate::DisconnectAllDevices()
110 {
111     sessionPool_.ReleaseAllSession();
112     ConnectCount::GetInstance()->RemoveAllConnect();
113 }
114 
DisconnectDeviceByP2P(const DeviceInfo info)115 void NetworkAgentTemplate::DisconnectDeviceByP2P(const DeviceInfo info)
116 {
117     LOGI("CloseP2P, cid:%{public}s", Utils::GetAnonyString(info.GetCid()).c_str());
118     sessionPool_.ReleaseSession(info.GetCid(), false);
119 }
120 
DisconnectDeviceByP2PHmdfs(const DeviceInfo info)121 void NetworkAgentTemplate::DisconnectDeviceByP2PHmdfs(const DeviceInfo info)
122 {
123     LOGI("DeviceOffline, cid:%{public}s", Utils::GetAnonyString(info.GetCid()).c_str());
124     sessionPool_.ReleaseSession(info.GetCid(), true);
125     ConnectCount::GetInstance()->NotifyRemoteReverseObj(info.GetCid(), ON_STATUS_OFFLINE);
126     ConnectCount::GetInstance()->RemoveConnect(info.GetCid());
127 }
128 
CloseSessionForOneDevice(const string & cid)129 void NetworkAgentTemplate::CloseSessionForOneDevice(const string &cid)
130 {
131     auto cmd = make_unique<DfsuCmd<NetworkAgentTemplate, std::string>>(
132         &NetworkAgentTemplate::CloseSessionForOneDeviceInner, cid);
133     cmd->UpdateOption({.tryTimes_ = 1});
134     Recv(move(cmd));
135 }
136 
CloseSessionForOneDeviceInner(std::string cid)137 void NetworkAgentTemplate::CloseSessionForOneDeviceInner(std::string cid)
138 {
139     sessionPool_.ReleaseSession(cid, true);
140     ConnectCount::GetInstance()->NotifyRemoteReverseObj(cid, ON_STATUS_OFFLINE);
141     ConnectCount::GetInstance()->RemoveConnect(cid);
142 }
143 
AcceptSession(shared_ptr<BaseSession> session,const std::string backStage)144 void NetworkAgentTemplate::AcceptSession(shared_ptr<BaseSession> session, const std::string backStage)
145 {
146     if (session == nullptr) {
147         LOGE("session is nullptr.");
148         return;
149     }
150     auto cid = session->GetCid();
151     LOGI("AcceptSesion, cid:%{public}s", Utils::GetAnonyString(cid).c_str());
152     sessionPool_.HoldSession(session, backStage);
153 }
154 
FindSocketId(int32_t socketId)155 bool NetworkAgentTemplate::FindSocketId(int32_t socketId)
156 {
157     return sessionPool_.FindSocketId(socketId);
158 }
159 
GetSessionProcess(NotifyParam & param)160 void NetworkAgentTemplate::GetSessionProcess(NotifyParam &param)
161 {
162     auto cmd = make_unique<DfsuCmd<NetworkAgentTemplate, NotifyParam>>(
163         &NetworkAgentTemplate::GetSessionProcessInner, param);
164     cmd->UpdateOption({.tryTimes_ = 1});
165     Recv(move(cmd));
166 }
167 
GetSessionProcessInner(NotifyParam param)168 void NetworkAgentTemplate::GetSessionProcessInner(NotifyParam param)
169 {
170     string cidStr(param.remoteCid, CID_MAX_LEN);
171     int fd = param.fd;
172     LOGI("NOTIFY_GET_SESSION, old fd %{public}d, remote cid %{public}s", fd, Utils::GetAnonyString(cidStr).c_str());
173     bool ifGetSession = sessionPool_.CheckIfGetSession(fd);
174     sessionPool_.ReleaseSession(fd);
175     if (ifGetSession && ConnectCount::GetInstance()->CheckCount(cidStr)) {
176         GetSession(cidStr);
177     } else {
178         sessionPool_.SinkOffline(cidStr);
179     }
180 }
181 
GetSession(const string & cid)182 void NetworkAgentTemplate::GetSession(const string &cid)
183 {
184     std::this_thread::sleep_for(std::chrono::seconds(NOTIFY_GET_SESSION_WAITING_TIME));
185     DeviceInfo deviceInfo;
186     deviceInfo.SetCid(cid);
187     try {
188         if (OpenSession(deviceInfo, LINK_TYPE_P2P) == FileManagement::E_OK) {
189             return;
190         }
191         LOGE("reget session failed");
192         sessionPool_.SinkOffline(cid);
193         ConnectCount::GetInstance()->NotifyRemoteReverseObj(cid, ON_STATUS_OFFLINE);
194         ConnectCount::GetInstance()->RemoveConnect(cid);
195         auto deviceManager = DeviceManagerAgent::GetInstance();
196         auto deviceId = deviceManager->GetDeviceIdByNetworkId(cid);
197         if (!deviceId.empty()) {
198             deviceManager->UMountDfsDocs(cid, deviceId, true);
199         }
200     } catch (const DfsuException &e) {
201         LOGE("reget session failed, code: %{public}d", e.code());
202     }
203 }
204 } // namespace DistributedFile
205 } // namespace Storage
206 } // namespace OHOS
207