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