1 /*
2 * Copyright (C) 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
16 #include "wifi_hid2d_service_utils.h"
17 #include <regex>
18 #include <shared_mutex>
19 #include "dhcp_define.h"
20 #include "wifi_logger.h"
21 #include "wifi_common_util.h"
22
23 namespace OHOS {
24 namespace Wifi {
25 DEFINE_WIFILOG_P2P_LABEL("Hid2dIpPool");
26 std::list<std::string> IpPool::ipList;
27 std::map<std::string, std::string> IpPool::mapGcMacToAllocIp;
28 const std::string PATTERN_IP = "^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
29 std::shared_mutex g_ipPoolMutex;
30 static std::mutex g_sharedLinkMutex;
31 std::map<int, int> SharedLinkManager::sharedLinkCountMap;
32 int SharedLinkManager::firstGroupUid = -1;
33 #define DEFAULT_UID 0
34
InitIpPool(const std::string & serverIp)35 bool IpPool::InitIpPool(const std::string& serverIp)
36 {
37 WIFI_LOGI("Init ip pool");
38
39 std::unique_lock<std::shared_mutex> guard(g_ipPoolMutex);
40 if (!ipList.empty()) {
41 return true;
42 }
43
44 std::string hostIp = serverIp.empty() ? DHCP::IP_V4_DEFAULT : serverIp;
45 if (!IsValidIp(hostIp)) {
46 return false;
47 }
48
49 std::string serverIpHead = hostIp.substr(0, hostIp.find_last_of("\\."));
50 ipList.clear();
51 mapGcMacToAllocIp.clear();
52 for (int i = HID2D_IPPOOL_START; i <= HID2D_IPPOOL_END; ++i) {
53 ipList.emplace_back(serverIpHead + "." + std::to_string(i));
54 }
55 return true;
56 }
57
GetIp(const std::string & gcMac)58 std::string IpPool::GetIp(const std::string& gcMac)
59 {
60 WIFI_LOGI("Get ip, gcMac: %{public}s", MacAnonymize(gcMac).c_str());
61
62 std::unique_lock<std::shared_mutex> guard(g_ipPoolMutex);
63 std::string ip = "";
64 if (ipList.empty()) {
65 WIFI_LOGE("Alloc ip failed!");
66 return ip;
67 }
68 ip = ipList.front();
69 ipList.pop_front();
70 mapGcMacToAllocIp[gcMac] = ip;
71 return ip;
72 }
73
ReleaseIp(const std::string & gcMac)74 void IpPool::ReleaseIp(const std::string& gcMac)
75 {
76 WIFI_LOGI("Release ip, gcMac: %{public}s", MacAnonymize(gcMac).c_str());
77
78 std::unique_lock<std::shared_mutex> guard(g_ipPoolMutex);
79 auto iter = mapGcMacToAllocIp.find(gcMac);
80 if (iter == mapGcMacToAllocIp.end()) {
81 return;
82 }
83
84 if (std::find(ipList.begin(), ipList.end(), iter->second) != ipList.end()) {
85 return;
86 }
87 if (IsValidIp(iter->second)) {
88 ipList.emplace_back(iter->second);
89 mapGcMacToAllocIp.erase(iter);
90 }
91 }
92
ReleaseIpPool()93 void IpPool::ReleaseIpPool()
94 {
95 WIFI_LOGI("Release ip pool");
96
97 std::unique_lock<std::shared_mutex> guard(g_ipPoolMutex);
98 mapGcMacToAllocIp.clear();
99 ipList.clear();
100 }
101
IsValidIp(const std::string & ip)102 bool IpPool::IsValidIp(const std::string& ip)
103 {
104 if (ip.empty()) {
105 return false;
106 }
107 return std::regex_match(ip, std::regex(PATTERN_IP));
108 }
109
SetGroupUid(int callingUid)110 void SharedLinkManager::SetGroupUid(int callingUid)
111 {
112 std::unique_lock<std::mutex> lock(g_sharedLinkMutex);
113 WIFI_LOGI("Set Group UID: %{public}d -> %{public}d", firstGroupUid, callingUid);
114 if (firstGroupUid != -1) {
115 return;
116 }
117 firstGroupUid = callingUid;
118 }
119
GetGroupUid(int & callingUid)120 void SharedLinkManager::GetGroupUid(int &callingUid)
121 {
122 std::unique_lock<std::mutex> lock(g_sharedLinkMutex);
123 WIFI_LOGI("Get Group UID: %{public}d", firstGroupUid);
124 callingUid = firstGroupUid;
125 }
126
IncreaseSharedLink()127 void SharedLinkManager::IncreaseSharedLink()
128 {
129 std::unique_lock<std::mutex> lock(g_sharedLinkMutex);
130 WIFI_LOGI("IncreaseSharedLink, current GO UID: %{public}d", firstGroupUid);
131 if (!sharedLinkCountMap.empty()) {
132 WIFI_LOGE("IncreaseSharedLink, Current count is not zeros");
133 sharedLinkCountMap.clear();
134 }
135 if (firstGroupUid == -1) {
136 firstGroupUid = DEFAULT_UID;
137 }
138 sharedLinkCountMap[firstGroupUid]++;
139 }
140
IncreaseSharedLink(int callingUid)141 void SharedLinkManager::IncreaseSharedLink(int callingUid)
142 {
143 std::unique_lock<std::mutex> lock(g_sharedLinkMutex);
144 sharedLinkCountMap[callingUid]++;
145 WIFI_LOGI("CallingUid %{public}d increase shared link to %{public}d", callingUid,
146 sharedLinkCountMap[callingUid]);
147 }
148
DecreaseSharedLink(int callingUid)149 void SharedLinkManager::DecreaseSharedLink(int callingUid)
150 {
151 std::unique_lock<std::mutex> lock(g_sharedLinkMutex);
152 if (sharedLinkCountMap.find(callingUid) == sharedLinkCountMap.end()) {
153 WIFI_LOGE("CallingUid %{public}d decrease error for not found!", callingUid);
154 return;
155 }
156 if (sharedLinkCountMap[callingUid] == 0) {
157 WIFI_LOGE("CallingUid %{public}d decrease error for sharedLinkCount == 0!", callingUid);
158 return;
159 }
160 sharedLinkCountMap[callingUid]--;
161 WIFI_LOGI("CallingUid %{public}d decrease shared link to %{public}d", callingUid,
162 sharedLinkCountMap[callingUid]);
163 }
164
ClearSharedLinkCount()165 void SharedLinkManager::ClearSharedLinkCount()
166 {
167 WIFI_LOGI("ClearSharedLinkCount");
168 std::unique_lock<std::mutex> lock(g_sharedLinkMutex);
169 firstGroupUid = -1;
170 sharedLinkCountMap.clear();
171 }
172
GetSharedLinkCount()173 int SharedLinkManager::GetSharedLinkCount()
174 {
175 std::unique_lock<std::mutex> lock(g_sharedLinkMutex);
176 int sharedLinkCount = 0;
177 for (auto iter : sharedLinkCountMap) {
178 sharedLinkCount += iter.second;
179 }
180 WIFI_LOGI("Get sharedLinkCount: %{public}d", sharedLinkCount);
181 return sharedLinkCount;
182 }
183 } // namespace Wifi
184 } // namespace OHOS