1 /*
2 * Copyright (c) 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 <any>
17 #include <string>
18 #include "conn_log.h"
19 #include "interface_info.h"
20 #include "protocol/wifi_direct_protocol.h"
21 #include "softbus_error_code.h"
22 #include "utils/wifi_direct_utils.h"
23
24 namespace OHOS::SoftBus {
25
26 template <>
27 InfoContainer<InterfaceInfoKey>::KeyTypeTable InfoContainer<InterfaceInfoKey>::keyTypeTable_ = {
28 { InterfaceInfoKey::DYNAMIC_MAC, Serializable::ValueType::STRING },
29 { InterfaceInfoKey::INTERFACE_NAME, Serializable::ValueType::STRING },
30 { InterfaceInfoKey::CAPABILITY, Serializable::ValueType::INT },
31 { InterfaceInfoKey::WIFI_DIRECT_ROLE, Serializable::ValueType::INT },
32 { InterfaceInfoKey::BASE_MAC, Serializable::ValueType::STRING },
33 { InterfaceInfoKey::PHYSICAL_RATE, Serializable::ValueType::INT },
34 { InterfaceInfoKey::SUPPORT_BAND, Serializable::ValueType::BYTE },
35 { InterfaceInfoKey::CHANNEL_AND_BANDWIDTH, Serializable::ValueType::BYTE_ARRAY},
36 { InterfaceInfoKey::COEXIST_CHANNEL_LIST, Serializable::ValueType::INT_ARRAY },
37 { InterfaceInfoKey::HML_LINK_COUNT, Serializable::ValueType::INT },
38 { InterfaceInfoKey::ISLAND_DEVICE_COUNT, Serializable::ValueType::INT },
39 { InterfaceInfoKey::COEXIST_VAP_COUNT, Serializable::ValueType::BOOL },
40 { InterfaceInfoKey::IPV4, Serializable::ValueType::IPV4_INFO },
41 { InterfaceInfoKey::CHANNEL_5G_LIST, Serializable::ValueType::INT_ARRAY },
42 { InterfaceInfoKey::SSID, Serializable::ValueType::STRING },
43 { InterfaceInfoKey::PORT, Serializable::ValueType::INT },
44 { InterfaceInfoKey::IS_WIDE_BAND_SUPPORT, Serializable::ValueType::BOOL },
45 { InterfaceInfoKey::CENTER_20M, Serializable::ValueType::INT },
46 { InterfaceInfoKey::CENTER_FREQUENCY1, Serializable::ValueType::INT },
47 { InterfaceInfoKey::CENTER_FREQUENCY2, Serializable::ValueType::INT },
48 { InterfaceInfoKey::BANDWIDTH, Serializable::ValueType::INT },
49 { InterfaceInfoKey::WIFI_CFG_INFO, Serializable::ValueType::STRING },
50 { InterfaceInfoKey::IS_ENABLE, Serializable::ValueType::BOOL },
51 { InterfaceInfoKey::CONNECTED_DEVICE_COUNT, Serializable::ValueType::INT },
52 { InterfaceInfoKey::PSK, Serializable::ValueType::STRING },
53 { InterfaceInfoKey::REUSE_COUNT, Serializable::ValueType::INT },
54 { InterfaceInfoKey::IS_AVAILABLE, Serializable::ValueType::BOOL },
55 { InterfaceInfoKey::COEXIST_RULE, Serializable::ValueType::BOOL },
56 { InterfaceInfoKey::LINK_MODE, Serializable::ValueType::INT },
57 { InterfaceInfoKey::LISTEN_MODULE, Serializable::ValueType::INT },
58 };
59
MarshallingString(WifiDirectProtocol & protocol,InterfaceInfoKey key,Serializable::ValueType type,const std::string & value)60 void InterfaceInfo::MarshallingString(
61 WifiDirectProtocol &protocol, InterfaceInfoKey key, Serializable::ValueType type, const std::string &value)
62 {
63 if (key == InterfaceInfoKey::DYNAMIC_MAC || key == InterfaceInfoKey::BASE_MAC) {
64 auto macString = std::any_cast<const std::string>(value);
65 auto macArray = WifiDirectUtils::MacStringToArray(macString);
66 if (!macArray.empty()) {
67 protocol.Write(static_cast<int>(key), type, macArray.data(), macArray.size());
68 }
69 } else {
70 protocol.Write(static_cast<int>(key), type, reinterpret_cast<const uint8_t*>(value.c_str()), value.length());
71 }
72 }
73
Marshalling(WifiDirectProtocol & protocol,std::vector<uint8_t> & output) const74 int InterfaceInfo::Marshalling(WifiDirectProtocol &protocol, std::vector<uint8_t> &output) const
75 {
76 ProtocolType protocolType = protocol.GetType();
77 for (const auto &[key, value] : values_) {
78 auto type = keyTypeTable_[key];
79 if (protocolType == ProtocolType::TLV &&
80 (key == InterfaceInfoKey::DYNAMIC_MAC || key == InterfaceInfoKey::BASE_MAC)) {
81 auto macString = std::any_cast<const std::string>(value);
82 auto macArray = WifiDirectUtils::MacStringToArray(macString);
83 if (!macArray.empty()) {
84 protocol.Write(static_cast<int>(key), type, macArray.data(), macArray.size());
85 }
86 continue;
87 }
88
89 switch (type) {
90 case Serializable::ValueType::BOOL: {
91 uint8_t data = std::any_cast<bool>(value);
92 protocol.Write(static_cast<int>(key), type, &data, sizeof(data));
93 break;
94 }
95 case Serializable::ValueType::INT: {
96 std::vector<uint8_t> data;
97 WifiDirectUtils::IntToBytes(std::any_cast<int>(value), sizeof(int), data);
98 protocol.Write(static_cast<int>(key), type, data.data(), data.size());
99 break;
100 }
101 case Serializable::ValueType::BYTE_ARRAY: {
102 const auto &data = std::any_cast<const std::vector<uint8_t> &>(value);
103 protocol.Write(static_cast<int>(key), type, data.data(), data.size());
104 break;
105 }
106 case Serializable::ValueType::STRING: {
107 MarshallingString(protocol, key, type, std::any_cast<const std::string>(value));
108 break;
109 }
110 case Serializable::ValueType::IPV4_INFO: {
111 const auto &ipv4Info = std::any_cast<const Ipv4Info &>(value);
112 std::vector<uint8_t> ipv4InfoOutput;
113 ipv4Info.Marshalling(ipv4InfoOutput);
114 protocol.Write(static_cast<int>(key), type, ipv4InfoOutput.data(), ipv4InfoOutput.size());
115 break;
116 }
117 default:
118 continue;
119 }
120 }
121 protocol.GetOutput(output);
122 return SOFTBUS_OK;
123 }
124
Unmarshalling(WifiDirectProtocol & protocol,const std::vector<uint8_t> & input)125 int InterfaceInfo::Unmarshalling(WifiDirectProtocol &protocol, const std::vector<uint8_t> &input)
126 {
127 int key = 0;
128 uint8_t *data = nullptr;
129 size_t size = 0;
130 enum ProtocolType protocolType = protocol.GetType();
131
132 protocol.SetInput(input);
133 while (protocol.Read(key, data, size)) {
134 auto type = keyTypeTable_[InterfaceInfoKey(key)];
135 auto keyValue = static_cast<InterfaceInfoKey>(key);
136 if (protocolType == ProtocolType::TLV &&
137 (keyValue == InterfaceInfoKey::DYNAMIC_MAC || keyValue == InterfaceInfoKey::BASE_MAC)) {
138 std::vector<uint8_t> macArray(data, data + size);
139 auto macAddressStr = WifiDirectUtils::MacArrayToString(macArray);
140 Set(InterfaceInfoKey(key), macAddressStr);
141 continue;
142 }
143
144 switch (type) {
145 case Serializable::ValueType::BOOL: {
146 Set(InterfaceInfoKey(key), *reinterpret_cast<bool *>(data));
147 break;
148 }
149 case Serializable::ValueType::INT: {
150 int intKey = (int)WifiDirectUtils::BytesToInt((uint8_t *)data, size);
151 Set(InterfaceInfoKey(key), intKey);
152 break;
153 }
154 case Serializable::ValueType::STRING: {
155 size = WifiDirectUtils::CalculateStringLength((char *)data, size);
156 Set(InterfaceInfoKey(key), std::string(reinterpret_cast<const char *>(data), size));
157 break;
158 }
159 case Serializable::ValueType::BYTE_ARRAY: {
160 Set(InterfaceInfoKey(key), std::vector<uint8_t>(data, data + size));
161 break;
162 }
163 case Serializable::ValueType::IPV4_INFO: {
164 Ipv4Info ipv4Info;
165 ipv4Info.Unmarshalling(data, size);
166 Set(InterfaceInfoKey(key), ipv4Info);
167 break;
168 }
169 default:
170 continue;
171 }
172 }
173
174 return SOFTBUS_OK;
175 }
176
SetName(const std::string & value)177 void InterfaceInfo::SetName(const std::string &value)
178 {
179 Set(InterfaceInfoKey::INTERFACE_NAME, value);
180 }
181
GetName() const182 std::string InterfaceInfo::GetName() const
183 {
184 return Get(InterfaceInfoKey::INTERFACE_NAME, std::string(""));
185 }
186
GetChannelAndBandWidth() const187 std::vector<uint8_t> InterfaceInfo::GetChannelAndBandWidth() const
188 {
189 return Get(InterfaceInfoKey::CHANNEL_AND_BANDWIDTH, std::vector<uint8_t>());
190 }
191
SetIpString(const Ipv4Info & ipv4Info)192 void InterfaceInfo::SetIpString(const Ipv4Info &ipv4Info)
193 {
194 Set(InterfaceInfoKey::IPV4, ipv4Info);
195 }
196
GetIpString() const197 Ipv4Info InterfaceInfo::GetIpString() const
198 {
199 return Get(InterfaceInfoKey::IPV4, Ipv4Info());
200 }
201
SetRole(LinkInfo::LinkMode value)202 void InterfaceInfo::SetRole(LinkInfo::LinkMode value)
203 {
204 Set(InterfaceInfoKey::WIFI_DIRECT_ROLE, static_cast<int>(value));
205 }
206
GetRole() const207 LinkInfo::LinkMode InterfaceInfo::GetRole() const
208 {
209 auto ret = Get(InterfaceInfoKey::WIFI_DIRECT_ROLE, 0);
210 return static_cast<LinkInfo::LinkMode>(ret);
211 }
212
SetSsid(const std::string & value)213 void InterfaceInfo::SetSsid(const std::string &value)
214 {
215 Set(InterfaceInfoKey::SSID, value);
216 }
217
GetSsid() const218 std::string InterfaceInfo::GetSsid() const
219 {
220 return Get(InterfaceInfoKey::SSID, std::string(""));
221 }
222
SetP2pListenPort(const int & value)223 void InterfaceInfo::SetP2pListenPort(const int &value)
224 {
225 Set(InterfaceInfoKey::PORT, value);
226 }
227
GetP2pListenPort() const228 int InterfaceInfo::GetP2pListenPort() const
229 {
230 return Get(InterfaceInfoKey::PORT, 0);
231 }
232
SetP2pListenModule(const int & value)233 void InterfaceInfo::SetP2pListenModule(const int &value)
234 {
235 Set(InterfaceInfoKey::LISTEN_MODULE, value);
236 }
237
GetP2pListenModule() const238 int InterfaceInfo::GetP2pListenModule() const
239 {
240 return Get(InterfaceInfoKey::LISTEN_MODULE, -1);
241 }
242
SetP2pGroupConfig(const std::string & groupConfig)243 void InterfaceInfo::SetP2pGroupConfig(const std::string &groupConfig)
244 {
245 Set(InterfaceInfoKey::WIFI_CFG_INFO, groupConfig);
246 auto ret = WifiDirectUtils::SplitString(groupConfig, "\n");
247 Set(InterfaceInfoKey::SSID, ret[P2P_GROUP_CONFIG_INDEX_SSID]);
248 if (!GetDynamicMac().empty()) {
249 Set(InterfaceInfoKey::DYNAMIC_MAC, ret[P2P_GROUP_CONFIG_INDEX_BSSID]);
250 }
251 Set(InterfaceInfoKey::PSK, ret[P2P_GROUP_CONFIG_INDEX_SHARE_KEY]);
252 Set(InterfaceInfoKey::CENTER_20M, std::stoi(ret[P2P_GROUP_CONFIG_INDEX_FREQ]));
253 }
254
GetP2pGroupConfig() const255 std::string InterfaceInfo::GetP2pGroupConfig() const
256 {
257 return Get(InterfaceInfoKey::WIFI_CFG_INFO, std::string(""));
258 }
259
SetDynamicMac(const std::string & value)260 void InterfaceInfo::SetDynamicMac(const std::string &value)
261 {
262 Set(InterfaceInfoKey::DYNAMIC_MAC, value);
263 }
264
GetDynamicMac() const265 std::string InterfaceInfo::GetDynamicMac() const
266 {
267 return Get(InterfaceInfoKey::DYNAMIC_MAC, std::string(""));
268 }
269
SetPsk(const std::string & value)270 void InterfaceInfo::SetPsk(const std::string &value)
271 {
272 Set(InterfaceInfoKey::PSK, value);
273 }
274
GetPsk() const275 std::string InterfaceInfo::GetPsk() const
276 {
277 return Get(InterfaceInfoKey::PSK, std::string(""));
278 }
279
SetCenter20M(int value)280 void InterfaceInfo::SetCenter20M(int value)
281 {
282 Set(InterfaceInfoKey::CENTER_20M, value);
283 }
284
GetCenter20M() const285 int InterfaceInfo::GetCenter20M() const
286 {
287 return Get(InterfaceInfoKey::CENTER_20M, 0);
288 }
289
SetBandWidth(int value)290 void InterfaceInfo::SetBandWidth(int value)
291 {
292 Set(InterfaceInfoKey::BANDWIDTH, value);
293 }
294
GetBandWidth() const295 int InterfaceInfo::GetBandWidth() const
296 {
297 return Get(InterfaceInfoKey::BANDWIDTH, 0);
298 }
299
SetIsEnable(bool value)300 void InterfaceInfo::SetIsEnable(bool value)
301 {
302 Set(InterfaceInfoKey::IS_ENABLE, value);
303 }
304
IsEnable() const305 bool InterfaceInfo::IsEnable() const
306 {
307 return Get(InterfaceInfoKey::IS_ENABLE, false);
308 }
309
SetConnectedDeviceCount(int32_t value)310 void InterfaceInfo::SetConnectedDeviceCount(int32_t value)
311 {
312 Set(InterfaceInfoKey::CONNECTED_DEVICE_COUNT, value);
313 }
314
GetConnectedDeviceCount() const315 int32_t InterfaceInfo::GetConnectedDeviceCount() const
316 {
317 return Get(InterfaceInfoKey::CONNECTED_DEVICE_COUNT, 0);
318 }
319
SetBaseMac(const std::string & value)320 void InterfaceInfo::SetBaseMac(const std::string &value)
321 {
322 Set(InterfaceInfoKey::BASE_MAC, value);
323 }
324
GetBaseMac() const325 std::string InterfaceInfo::GetBaseMac() const
326 {
327 return Get(InterfaceInfoKey::BASE_MAC, std::string(""));
328 }
329
SetCapability(int32_t value)330 void InterfaceInfo::SetCapability(int32_t value)
331 {
332 Set(InterfaceInfoKey::CAPABILITY, value);
333 }
334
GetCapability() const335 int32_t InterfaceInfo::GetCapability() const
336 {
337 return Get(InterfaceInfoKey::CAPABILITY, 0);
338 }
339
SetReuseCount(int value)340 void InterfaceInfo::SetReuseCount(int value)
341 {
342 Set(InterfaceInfoKey::REUSE_COUNT, value);
343 }
344
GetReuseCount() const345 int InterfaceInfo::GetReuseCount() const
346 {
347 return Get(InterfaceInfoKey::REUSE_COUNT, 0);
348 }
349
SetChannel5GList(const std::vector<int> & value)350 void InterfaceInfo::SetChannel5GList(const std::vector<int> &value)
351 {
352 Set(InterfaceInfoKey::CHANNEL_5G_LIST, value);
353 }
354
GetChannel5GList() const355 std::vector<int> InterfaceInfo::GetChannel5GList() const
356 {
357 std::vector<int> result;
358 return Get(InterfaceInfoKey::CHANNEL_5G_LIST, result);
359 }
360
SetIsAvailable(bool value)361 void InterfaceInfo::SetIsAvailable(bool value)
362 {
363 Set(InterfaceInfoKey::IS_AVAILABLE, value);
364 }
365
IsAvailable() const366 bool InterfaceInfo::IsAvailable() const
367 {
368 return Get(InterfaceInfoKey::IS_AVAILABLE, true);
369 }
370
RefreshIsAvailable()371 void InterfaceInfo::RefreshIsAvailable()
372 {
373 if (!IsEnable()) {
374 CONN_LOGW(CONN_WIFI_DIRECT, "isEnable=0, interface name=%{public}s", GetName().c_str());
375 SetIsAvailable(false);
376 return;
377 }
378
379 if (GetRole() == LinkInfo::LinkMode::GC) {
380 CONN_LOGW(CONN_WIFI_DIRECT, "already gc");
381 SetIsAvailable(false);
382 return;
383 }
384 SetIsAvailable(true);
385 }
386
SetPhysicalRate(int value)387 void InterfaceInfo::SetPhysicalRate(int value)
388 {
389 Set(InterfaceInfoKey::PHYSICAL_RATE, value);
390 }
391
GetPhysicalRate() const392 int InterfaceInfo::GetPhysicalRate() const
393 {
394 return Get(InterfaceInfoKey::PHYSICAL_RATE, 0);
395 }
396
IncreaseRefCount()397 void InterfaceInfo::IncreaseRefCount()
398 {
399 int count = Get(InterfaceInfoKey::REUSE_COUNT, 0);
400 count++;
401 Set(InterfaceInfoKey::REUSE_COUNT, count);
402 CONN_LOGI(CONN_WIFI_DIRECT, "reuseCount = %{public}d", count);
403 }
404
DecreaseRefCount()405 void InterfaceInfo::DecreaseRefCount()
406 {
407 int count = Get(InterfaceInfoKey::REUSE_COUNT, 0);
408 --count;
409 Set(InterfaceInfoKey::REUSE_COUNT, count);
410 CONN_LOGI(CONN_WIFI_DIRECT, "reuseCount = %{public}d", count);
411 }
412 } // namespace OHOS::SoftBus
413