1 /*
2 * Copyright (C) 2021-2022 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 "wifi_p2p_group_manager.h"
16 #include <algorithm>
17 #include "wifi_config_center.h"
18 #include "wifi_logger.h"
19
20 DEFINE_WIFILOG_P2P_LABEL("WifiP2pGroupManager");
21
22 namespace OHOS {
23 namespace Wifi {
WifiP2pGroupManager()24 WifiP2pGroupManager::WifiP2pGroupManager() : groupsInfo(), currentGroup(), groupMutex(), p2pConnInfo()
25 {}
26
Initialize()27 void WifiP2pGroupManager::Initialize()
28 {
29 std::unique_lock<std::mutex> lock(groupMutex);
30 WifiSettings::GetInstance().GetWifiP2pGroupInfo(groupsInfo);
31 WifiConfigCenter::GetInstance().GetP2pInfo(p2pConnInfo);
32 }
33
StashGroups()34 void WifiP2pGroupManager::StashGroups()
35 {
36 std::unique_lock<std::mutex> lock(groupMutex);
37 RefreshGroupsFromCurrentGroup();
38 WifiSettings::GetInstance().SetWifiP2pGroupInfo(groupsInfo);
39 }
40
AddGroup(const WifiP2pGroupInfo & group)41 bool WifiP2pGroupManager::AddGroup(const WifiP2pGroupInfo &group)
42 {
43 std::unique_lock<std::mutex> lock(groupMutex);
44 for (auto it = groupsInfo.begin(); it != groupsInfo.end(); ++it) {
45 if (*it == group) {
46 return true;
47 }
48 }
49 #ifdef SUPPORT_RANDOM_MAC_ADDR
50 WIFI_LOGD("%{public}s: add a group, Name:%{private}s", __func__, group.GetGroupName().c_str());
51 AddMacAddrPairInfo(WifiMacAddrInfoType::P2P_GROUPSINFO_MACADDR_INFO, group);
52 #endif
53 groupsInfo.push_back(group);
54 return true;
55 }
56
AddOrUpdateGroup(const WifiP2pGroupInfo & group)57 bool WifiP2pGroupManager::AddOrUpdateGroup(const WifiP2pGroupInfo &group)
58 {
59 std::unique_lock<std::mutex> lock(groupMutex);
60 for (auto it = groupsInfo.begin(); it != groupsInfo.end(); ++it) {
61 if (*it == group) {
62 #ifdef SUPPORT_RANDOM_MAC_ADDR
63 WIFI_LOGD("%{public}s: remove a group, Name:%{private}s", __func__, group.GetGroupName().c_str());
64 RemoveMacAddrPairInfo(WifiMacAddrInfoType::P2P_GROUPSINFO_MACADDR_INFO, group);
65 #endif
66 groupsInfo.erase(it);
67 break;
68 }
69 }
70 #ifdef SUPPORT_RANDOM_MAC_ADDR
71 WIFI_LOGD("%{public}s: add a group, Name:%{private}s", __func__, group.GetGroupName().c_str());
72 AddMacAddrPairInfo(WifiMacAddrInfoType::P2P_GROUPSINFO_MACADDR_INFO, group);
73 #endif
74 groupsInfo.push_back(group);
75 return true;
76 }
RemoveGroup(const WifiP2pGroupInfo & group)77 bool WifiP2pGroupManager::RemoveGroup(const WifiP2pGroupInfo &group)
78 {
79 std::unique_lock<std::mutex> lock(groupMutex);
80 for (auto it = groupsInfo.begin(); it != groupsInfo.end(); ++it) {
81 if (*it == group) {
82 #ifdef SUPPORT_RANDOM_MAC_ADDR
83 WIFI_LOGD("%{public}s: remove a group, Name:%{private}s", __func__, group.GetGroupName().c_str());
84 RemoveMacAddrPairInfo(WifiMacAddrInfoType::P2P_GROUPSINFO_MACADDR_INFO, group);
85 #endif
86 groupsInfo.erase(it);
87 return true;
88 }
89 }
90 return false;
91 }
ClearAll()92 int WifiP2pGroupManager::ClearAll()
93 {
94 std::unique_lock<std::mutex> lock(groupMutex);
95 int groupSize = static_cast<int>(groupsInfo.size());
96 #ifdef SUPPORT_RANDOM_MAC_ADDR
97 WIFI_LOGD("%{public}s: clear all group, size:%{public}d", __func__, groupSize);
98 for (auto iter = groupsInfo.begin(); iter != groupsInfo.end(); ++iter) {
99 RemoveMacAddrPairInfo(WifiMacAddrInfoType::P2P_GROUPSINFO_MACADDR_INFO, *iter);
100 }
101 #endif
102 groupsInfo.clear();
103 return groupSize;
104 }
105
UpdateWpaGroup(const WifiP2pGroupInfo & group)106 void WifiP2pGroupManager::UpdateWpaGroup(const WifiP2pGroupInfo &group)
107 {
108 std::unique_lock<std::mutex> lock(groupMutex);
109 for (auto it = groupsInfo.begin(); it != groupsInfo.end(); ++it) {
110 if (it->GetGroupName() == group.GetGroupName() &&
111 it->GetOwner().GetDeviceAddress() == group.GetOwner().GetDeviceAddress()) {
112 WIFI_LOGD("UpdateWpaGroup: ssid equal, return");
113 return;
114 }
115 }
116 #ifdef SUPPORT_RANDOM_MAC_ADDR
117 WIFI_LOGD("%{public}s: update wpa group, Name:%{private}s", __func__, group.GetGroupName().c_str());
118 AddMacAddrPairInfo(WifiMacAddrInfoType::P2P_GROUPSINFO_MACADDR_INFO, group);
119 #endif
120 groupsInfo.push_back(group);
121 }
122
RemoveClientFromGroup(int networkId,const std::string & deviceAddress)123 int WifiP2pGroupManager::RemoveClientFromGroup(int networkId, const std::string &deviceAddress)
124 {
125 WifiP2pDevice device;
126 device.SetDeviceAddress(deviceAddress);
127
128 std::unique_lock<std::mutex> lock(groupMutex);
129 auto it = groupsInfo.begin();
130 for (; it != groupsInfo.end(); ++it) {
131 if (networkId == it->GetNetworkId()) {
132 if (it->IsContainsPersistentDevice(device)) {
133 it->RemovePersistentDevice(device);
134 }
135 return 0;
136 }
137 }
138 return -1;
139 }
140
GetGroups()141 const std::vector<WifiP2pGroupInfo> &WifiP2pGroupManager::GetGroups()
142 {
143 std::unique_lock<std::mutex> lock(groupMutex);
144 RefreshGroupsFromCurrentGroup();
145 return groupsInfo;
146 }
147
GetNetworkIdFromClients(const WifiP2pDevice & device)148 int WifiP2pGroupManager::GetNetworkIdFromClients(const WifiP2pDevice &device)
149 {
150 std::string deviceAddr = device.GetDeviceAddress();
151 std::transform(deviceAddr.begin(), deviceAddr.end(), deviceAddr.begin(), ::tolower);
152
153 std::unique_lock<std::mutex> lock(groupMutex);
154 for (auto it = groupsInfo.begin(); it != groupsInfo.end(); ++it) {
155 const std::vector<WifiP2pDevice> &clients = it->GetPersistentDevices();
156 for (auto client = clients.begin(); client != clients.end(); client++) {
157 std::string clientAddr = client->GetDeviceAddress();
158 std::transform(clientAddr.begin(), clientAddr.end(), clientAddr.begin(), ::tolower);
159 if (clientAddr == deviceAddr) {
160 return it->GetNetworkId();
161 }
162 }
163 }
164
165 return -1;
166 }
167
GetGroupNetworkId(const WifiP2pDevice & device)168 int WifiP2pGroupManager::GetGroupNetworkId(const WifiP2pDevice &device)
169 {
170 std::string deviceMac = device.GetDeviceAddress();
171 std::transform(deviceMac.begin(), deviceMac.end(), deviceMac.begin(), ::tolower);
172 std::string ownerMac;
173 std::unique_lock<std::mutex> lock(groupMutex);
174 for (auto it = groupsInfo.begin(); it != groupsInfo.end(); ++it) {
175 ownerMac = it->GetOwner().GetDeviceAddress();
176 std::transform(ownerMac.begin(), ownerMac.end(), ownerMac.begin(), ::tolower);
177 if (deviceMac == ownerMac) {
178 return it->GetNetworkId();
179 }
180 }
181 return -1;
182 }
GetGroupNetworkId(const WifiP2pDevice & device,const std::string & ssid)183 int WifiP2pGroupManager::GetGroupNetworkId(const WifiP2pDevice &device, const std::string &ssid)
184 {
185 std::string deviceMac = device.GetDeviceAddress();
186 std::transform(deviceMac.begin(), deviceMac.end(), deviceMac.begin(), ::tolower);
187 std::string ownerMac;
188 std::unique_lock<std::mutex> lock(groupMutex);
189 for (auto it = groupsInfo.begin(); it != groupsInfo.end(); ++it) {
190 ownerMac = it->GetOwner().GetDeviceAddress();
191 std::transform(ownerMac.begin(), ownerMac.end(), ownerMac.begin(), ::tolower);
192 if (deviceMac == ownerMac && ssid == it->GetGroupName()) {
193 return it->GetNetworkId();
194 }
195 }
196 return -1;
197 }
GetGroupOwnerAddr(int netId)198 std::string WifiP2pGroupManager::GetGroupOwnerAddr(int netId)
199 {
200 std::unique_lock<std::mutex> lock(groupMutex);
201 for (auto it = groupsInfo.begin(); it != groupsInfo.end(); ++it) {
202 if (netId == it->GetNetworkId()) {
203 return it->GetOwner().GetDeviceAddress();
204 }
205 }
206 return "";
207 }
IsInclude(int netId)208 bool WifiP2pGroupManager::IsInclude(int netId)
209 {
210 std::unique_lock<std::mutex> lock(groupMutex);
211 for (auto it = groupsInfo.begin(); it != groupsInfo.end(); ++it) {
212 if (netId == it->GetNetworkId()) {
213 return true;
214 }
215 }
216 return false;
217 }
218
RefreshGroupsFromCurrentGroup()219 void WifiP2pGroupManager::RefreshGroupsFromCurrentGroup()
220 {
221 for (auto &group : groupsInfo) {
222 if (group == currentGroup) {
223 group = currentGroup;
224 break;
225 }
226 }
227 }
228
RefreshCurrentGroupFromGroups()229 void WifiP2pGroupManager::RefreshCurrentGroupFromGroups()
230 {
231 for (auto &group : groupsInfo) {
232 if (group == currentGroup) {
233 currentGroup.SetClientDevices(group.GetClientDevices());
234 break;
235 }
236 }
237 }
238
SaveP2pInfo(const WifiP2pLinkedInfo & linkedInfo)239 void WifiP2pGroupManager::SaveP2pInfo(const WifiP2pLinkedInfo &linkedInfo)
240 {
241 std::unique_lock<std::mutex> lock(groupMutex);
242 p2pConnInfo = linkedInfo;
243 }
244
IsOldPersistentGroup(int id)245 bool WifiP2pGroupManager::IsOldPersistentGroup(int id)
246 {
247 for (auto it = groupsInfo.begin(); it != groupsInfo.end(); ++it) {
248 if (it->GetNetworkId() == id) {
249 return it->GetPersistentFlag();
250 }
251 }
252 return false;
253 }
254
GetP2pInfo() const255 const WifiP2pLinkedInfo &WifiP2pGroupManager::GetP2pInfo() const
256 {
257 return p2pConnInfo;
258 }
259
UpdateGroupsNetwork(std::map<int,WifiP2pGroupInfo> wpaGroups)260 void WifiP2pGroupManager::UpdateGroupsNetwork(std::map<int, WifiP2pGroupInfo> wpaGroups)
261 {
262 std::unique_lock<std::mutex> lock(groupMutex);
263 bool found = false;
264 auto group = groupsInfo.begin();
265 while (group != groupsInfo.end()) {
266 found = false;
267 for (auto wpaGroup = wpaGroups.begin(); wpaGroup != wpaGroups.end(); ++wpaGroup) {
268 if (group->GetGroupName() == wpaGroup->second.GetGroupName() &&
269 group->GetOwner().GetDeviceAddress() == wpaGroup->second.GetOwner().GetDeviceAddress()) {
270 group->SetNetworkId(wpaGroup->second.GetNetworkId());
271 found = true;
272 break;
273 }
274 }
275 /**
276 * If the corresponding group cannot be found, the group has been deleted by the WPA.
277 */
278 if (!found) {
279 WIFI_LOGI("The group has been deleted by the WPA.");
280 #ifdef SUPPORT_RANDOM_MAC_ADDR
281 RemoveMacAddrPairInfo(WifiMacAddrInfoType::P2P_GROUPSINFO_MACADDR_INFO, *group);
282 #endif
283 group = groupsInfo.erase(group);
284 } else {
285 group++;
286 }
287 }
288 }
289
SetCurrentGroup(WifiMacAddrInfoType type,const WifiP2pGroupInfo & group)290 void WifiP2pGroupManager::SetCurrentGroup(WifiMacAddrInfoType type, const WifiP2pGroupInfo &group)
291 {
292 std::unique_lock<std::mutex> lock(groupMutex);
293 currentGroup = group;
294 WifiConfigCenter::GetInstance().SetCurrentP2pGroupInfo(group);
295 #ifdef SUPPORT_RANDOM_MAC_ADDR
296 AddMacAddrPairInfo(type, group);
297 #endif
298 RefreshCurrentGroupFromGroups();
299 }
300
301 #ifdef SUPPORT_RANDOM_MAC_ADDR
AddMacAddrPairInfo(WifiMacAddrInfoType type,const WifiP2pGroupInfo & group)302 void WifiP2pGroupManager::AddMacAddrPairInfo(WifiMacAddrInfoType type, const WifiP2pGroupInfo &group)
303 {
304 WifiP2pDevice owner = group.GetOwner();
305 WIFI_LOGD("%{public}s add mac address, type:%{public}d, GOName:%{private}s, addr:%{private}s, addrType:%{public}d",
306 __func__, type, owner.GetDeviceName().c_str(),
307 owner.GetDeviceAddress().c_str(), owner.GetDeviceAddressType());
308 if (type == WifiMacAddrInfoType::P2P_GROUPSINFO_MACADDR_INFO) {
309 std::string goRandomMacAddr = WifiConfigCenter::GetInstance().GetRandomMacAddr(
310 WifiMacAddrInfoType::P2P_DEVICE_MACADDR_INFO, owner.GetDeviceAddress());
311 WifiConfigCenter::GetInstance().StoreWifiMacAddrPairInfo(type, owner.GetDeviceAddress(), goRandomMacAddr);
312 std::vector<WifiP2pDevice> clientVec = group.GetClientDevices();
313 std::string gcRandomMacAddr;
314 for (auto iter = clientVec.begin(); iter != clientVec.end(); ++iter) {
315 gcRandomMacAddr = WifiConfigCenter::GetInstance().GetRandomMacAddr(
316 WifiMacAddrInfoType::P2P_DEVICE_MACADDR_INFO, iter->GetDeviceAddress());
317 WifiConfigCenter::GetInstance().StoreWifiMacAddrPairInfo(type, iter->GetDeviceAddress(), gcRandomMacAddr);
318 }
319 } else if (type == WifiMacAddrInfoType::P2P_CURRENT_GROUP_MACADDR_INFO) {
320 std::string goRandomMacAddr = WifiConfigCenter::GetInstance().GetRandomMacAddr(
321 WifiMacAddrInfoType::P2P_DEVICE_MACADDR_INFO, owner.GetDeviceAddress());
322 if (!goRandomMacAddr.empty()) {
323 WifiConfigCenter::GetInstance().StoreWifiMacAddrPairInfo(type, owner.GetDeviceAddress(), goRandomMacAddr);
324 std::vector<WifiP2pDevice> clientVec = group.GetClientDevices();
325 std::string gcRandomMacAddr;
326 for (auto iter = clientVec.begin(); iter != clientVec.end(); ++iter) {
327 gcRandomMacAddr = WifiConfigCenter::GetInstance().GetRandomMacAddr(
328 WifiMacAddrInfoType::P2P_DEVICE_MACADDR_INFO, iter->GetDeviceAddress());
329 WifiConfigCenter::GetInstance().StoreWifiMacAddrPairInfo(type, iter->GetDeviceAddress(),
330 gcRandomMacAddr);
331 }
332 } else {
333 goRandomMacAddr = WifiConfigCenter::GetInstance().GetRandomMacAddr(
334 WifiMacAddrInfoType::P2P_GROUPSINFO_MACADDR_INFO, owner.GetDeviceAddress());
335 WifiConfigCenter::GetInstance().StoreWifiMacAddrPairInfo(type, owner.GetDeviceAddress(), goRandomMacAddr);
336 std::vector<WifiP2pDevice> clientVec = group.GetClientDevices();
337 std::string gcRandomMacAddr;
338 for (auto iter = clientVec.begin(); iter != clientVec.end(); ++iter) {
339 gcRandomMacAddr = WifiConfigCenter::GetInstance().GetRandomMacAddr(
340 WifiMacAddrInfoType::P2P_GROUPSINFO_MACADDR_INFO, iter->GetDeviceAddress());
341 WifiConfigCenter::GetInstance().StoreWifiMacAddrPairInfo(type, iter->GetDeviceAddress(),
342 gcRandomMacAddr);
343 }
344 }
345 } else {
346 WIFI_LOGW("%{public}s invalid type:%{public}d", __func__, type);
347 }
348 }
349
RemoveMacAddrPairInfo(WifiMacAddrInfoType type,const WifiP2pGroupInfo & group)350 void WifiP2pGroupManager::RemoveMacAddrPairInfo(WifiMacAddrInfoType type, const WifiP2pGroupInfo &group)
351 {
352 WifiP2pDevice owner = group.GetOwner();
353 WIFI_LOGD("%{public}s del mac address, type:%{public}d, GOName:%{private}s, addr:%{private}s, addrType:%{public}d",
354 __func__, type, owner.GetDeviceName().c_str(),
355 owner.GetDeviceAddress().c_str(), owner.GetDeviceAddressType());
356 WifiConfigCenter::GetInstance().RemoveMacAddrPairInfo(type,
357 owner.GetDeviceAddress(), owner.GetDeviceAddressType());
358
359 std::vector<WifiP2pDevice> clientVec = group.GetClientDevices();
360 for (auto iter = clientVec.begin(); iter != clientVec.end(); ++iter) {
361 WifiConfigCenter::GetInstance().RemoveMacAddrPairInfo(type,
362 iter->GetDeviceAddress(), iter->GetDeviceAddressType());
363 }
364 }
365 #endif
366 } // namespace Wifi
367 } // namespace OHOS
368