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