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