blob: 5d61271410fa57e3230382f32822ff5126fb5153 [file] [log] [blame]
Roshan Pius99dab382019-02-14 07:57:10 -08001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Roshan Piusc4446792019-02-14 13:20:39 -080017#include <cstddef>
18#include <iostream>
19#include <limits>
20#include <random>
21
Roshan Pius99dab382019-02-14 07:57:10 -080022#include <android-base/logging.h>
23#include <android-base/macros.h>
24#include <private/android_filesystem_config.h>
25
Roshan Piusc4446792019-02-14 13:20:39 -080026#undef NAN
Roshan Pius99dab382019-02-14 07:57:10 -080027#include "wifi_iface_util.h"
28
Roshan Piusc4446792019-02-14 13:20:39 -080029namespace {
30// Constants to set the local bit & clear the multicast bit.
31constexpr uint8_t kMacAddressMulticastMask = 0x01;
32constexpr uint8_t kMacAddressLocallyAssignedMask = 0x02;
33} // namespace
34
Roshan Pius99dab382019-02-14 07:57:10 -080035namespace android {
36namespace hardware {
37namespace wifi {
38namespace V1_3 {
39namespace implementation {
40namespace iface_util {
41
Roshan Pius3b6705f2019-02-14 09:43:43 -080042WifiIfaceUtil::WifiIfaceUtil() : random_mac_address_(nullptr) {}
Roshan Pius99dab382019-02-14 07:57:10 -080043
44std::array<uint8_t, 6> WifiIfaceUtil::getFactoryMacAddress(
45 const std::string& iface_name) {
46 return iface_tool_.GetFactoryMacAddress(iface_name.c_str());
47}
48
49bool WifiIfaceUtil::setMacAddress(const std::string& iface_name,
50 const std::array<uint8_t, 6>& mac) {
51 if (!iface_tool_.SetUpState(iface_name.c_str(), false)) {
52 LOG(ERROR) << "SetUpState(false) failed.";
53 return false;
54 }
55 if (!iface_tool_.SetMacAddress(iface_name.c_str(), mac)) {
56 LOG(ERROR) << "SetMacAddress failed.";
57 return false;
58 }
59 if (!iface_tool_.SetUpState(iface_name.c_str(), true)) {
60 LOG(ERROR) << "SetUpState(true) failed.";
61 return false;
62 }
63 LOG(DEBUG) << "Successfully SetMacAddress.";
64 return true;
65}
66
Roshan Pius3b6705f2019-02-14 09:43:43 -080067std::array<uint8_t, 6> WifiIfaceUtil::getOrCreateRandomMacAddress() {
68 if (random_mac_address_) {
69 return *random_mac_address_.get();
70 }
71 random_mac_address_ =
72 std::make_unique<std::array<uint8_t, 6>>(createRandomMacAddress());
73 return *random_mac_address_.get();
74}
75
76std::array<uint8_t, 6> WifiIfaceUtil::createRandomMacAddress() {
Roshan Piusc4446792019-02-14 13:20:39 -080077 std::array<uint8_t, 6> address = {};
78 std::random_device rd;
79 std::default_random_engine engine(rd());
80 std::uniform_int_distribution<uint8_t> dist(
81 std::numeric_limits<uint8_t>::min(),
82 std::numeric_limits<uint8_t>::max());
83 for (size_t i = 0; i < address.size(); i++) {
84 address[i] = dist(engine);
85 }
86 // Set the local bit and clear the multicast bit.
87 address[0] |= kMacAddressLocallyAssignedMask;
88 address[0] &= ~kMacAddressMulticastMask;
89 return address;
Roshan Pius3b6705f2019-02-14 09:43:43 -080090}
Roshan Pius99dab382019-02-14 07:57:10 -080091} // namespace iface_util
92} // namespace implementation
93} // namespace V1_3
94} // namespace wifi
95} // namespace hardware
96} // namespace android