Migrate MAC Addresses and BSSIDs from std::vector to std::array

Since MAC Addresses and BSSIDs are fixed size, it would be more
efficient to use a fixed length array to store them. Also, bugs
causing MAC Addresses to have the wrong size can be caught
more promptly than before.

Bug: 36974160
Fix: 36974160
Test: system/connectivity/wificond/runtests.sh
Test: manual - flash onto device and try connecting to Wifi
Change-Id: Iefab0b3bbfd286c135b10ccc4fa946faaad86ce4
diff --git a/ap_interface_impl.cpp b/ap_interface_impl.cpp
index 5700b20..f39e9c1 100644
--- a/ap_interface_impl.cpp
+++ b/ap_interface_impl.cpp
@@ -25,10 +25,10 @@
 
 using android::net::wifi::IApInterface;
 using android::wifi_system::InterfaceTool;
+using std::array;
 using std::endl;
 using std::string;
 using std::unique_ptr;
-using std::vector;
 
 using namespace std::placeholders;
 
@@ -80,8 +80,9 @@
   *ss << "------- Dump End -------" << endl;
 }
 
-void ApInterfaceImpl::OnStationEvent(StationEvent event,
-                                     const vector<uint8_t>& mac_address) {
+void ApInterfaceImpl::OnStationEvent(
+    StationEvent event,
+    const array<uint8_t, ETH_ALEN>& mac_address) {
   if (event == NEW_STATION) {
     LOG(INFO) << "New station "
               << LoggingUtils::GetMacString(mac_address)
diff --git a/ap_interface_impl.h b/ap_interface_impl.h
index 593d2da..ab3bac3 100644
--- a/ap_interface_impl.h
+++ b/ap_interface_impl.h
@@ -17,8 +17,10 @@
 #ifndef WIFICOND_AP_INTERFACE_IMPL_H_
 #define WIFICOND_AP_INTERFACE_IMPL_H_
 
+#include <array>
 #include <string>
-#include <vector>
+
+#include <linux/if_ether.h>
 
 #include <android-base/macros.h>
 #include <wifi_system/interface_tool.h>
@@ -63,7 +65,7 @@
   int number_of_associated_stations_;
 
   void OnStationEvent(StationEvent event,
-                      const std::vector<uint8_t>& mac_address);
+                      const std::array<uint8_t, ETH_ALEN>& mac_address);
 
   void OnChannelSwitchEvent(uint32_t frequency, ChannelBandwidth bandwidth);
 
diff --git a/client_interface_binder.cpp b/client_interface_binder.cpp
index 5b60844..e15b61d 100644
--- a/client_interface_binder.cpp
+++ b/client_interface_binder.cpp
@@ -16,8 +16,13 @@
 
 #include "wificond/client_interface_binder.h"
 
+#include <algorithm>
 #include <vector>
 
+#include <linux/if_ether.h>
+
+#include <android-base/logging.h>
+
 #include <binder/Status.h>
 
 #include "wificond/client_interface_impl.h"
@@ -58,7 +63,8 @@
   if (impl_ == nullptr) {
     return Status::ok();
   }
-  *out_mac_address = impl_->GetMacAddress();
+  const std::array<uint8_t, ETH_ALEN>& mac = impl_->GetMacAddress();
+  *out_mac_address = vector<uint8_t>(mac.begin(), mac.end());
   return Status::ok();
 }
 
@@ -82,7 +88,18 @@
 
 
 Status ClientInterfaceBinder::setMacAddress(const vector<uint8_t>& mac, bool* success) {
-  *success = impl_ && impl_->SetMacAddress(mac);
+  if (impl_ == nullptr) {
+    *success = false;
+    return Status::ok();
+  }
+  if (mac.size() != ETH_ALEN) {
+    LOG(ERROR) << "Invalid MAC length " << mac.size();
+    *success = false;
+    return Status::ok();
+  }
+  std::array<uint8_t, ETH_ALEN> mac_array;
+  std::copy_n(mac.begin(), ETH_ALEN, mac_array.begin());
+  *success = impl_->SetMacAddress(mac_array);
   return Status::ok();
 }
 
diff --git a/client_interface_impl.cpp b/client_interface_impl.cpp
index 2ea6871..2556e8c 100644
--- a/client_interface_impl.cpp
+++ b/client_interface_impl.cpp
@@ -18,8 +18,6 @@
 
 #include <vector>
 
-#include <linux/if_ether.h>
-
 #include <android-base/logging.h>
 
 #include "wificond/client_interface_binder.h"
@@ -61,7 +59,7 @@
       LOG(INFO) << "Connect timeout";
     }
     client_interface_->is_associated_ = false;
-    client_interface_->bssid_.clear();
+    client_interface_->bssid_.fill(0);
   }
 }
 
@@ -81,18 +79,18 @@
       LOG(INFO) << "Associate timeout";
     }
     client_interface_->is_associated_ = false;
-    client_interface_->bssid_.clear();
+    client_interface_->bssid_.fill(0);
   }
 }
 
 void MlmeEventHandlerImpl::OnDisconnect(unique_ptr<MlmeDisconnectEvent> event) {
   client_interface_->is_associated_ = false;
-  client_interface_->bssid_.clear();
+  client_interface_->bssid_.fill(0);
 }
 
 void MlmeEventHandlerImpl::OnDisassociate(unique_ptr<MlmeDisassociateEvent> event) {
   client_interface_->is_associated_ = false;
-  client_interface_->bssid_.clear();
+  client_interface_->bssid_.fill(0);
 }
 
 
@@ -100,7 +98,7 @@
     uint32_t wiphy_index,
     const std::string& interface_name,
     uint32_t interface_index,
-    const std::vector<uint8_t>& interface_mac_addr,
+    const std::array<uint8_t, ETH_ALEN>& interface_mac_addr,
     InterfaceTool* if_tool,
     NetlinkUtils* netlink_utils,
     ScanUtils* scan_utils)
@@ -211,21 +209,16 @@
   return true;
 }
 
-const vector<uint8_t>& ClientInterfaceImpl::GetMacAddress() {
+const std::array<uint8_t, ETH_ALEN>& ClientInterfaceImpl::GetMacAddress() {
   return interface_mac_addr_;
 }
 
-bool ClientInterfaceImpl::SetMacAddress(const ::std::vector<uint8_t>& mac) {
-  if (mac.size() != ETH_ALEN) {
-    LOG(ERROR) << "Invalid MAC length " << mac.size();
-    return false;
-  }
+bool ClientInterfaceImpl::SetMacAddress(const std::array<uint8_t, ETH_ALEN>& mac) {
   if (!if_tool_->SetWifiUpState(false)) {
     LOG(ERROR) << "SetWifiUpState(false) failed.";
     return false;
   }
-  if (!if_tool_->SetMacAddress(interface_name_.c_str(),
-      {{mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]}})) {
+  if (!if_tool_->SetMacAddress(interface_name_.c_str(), mac)) {
     LOG(ERROR) << "SetMacAddress(" << interface_name_ << ", "
                << LoggingUtils::GetMacString(mac) << ") failed.";
     return false;
diff --git a/client_interface_impl.h b/client_interface_impl.h
index 63077ec..d2145a6 100644
--- a/client_interface_impl.h
+++ b/client_interface_impl.h
@@ -17,8 +17,11 @@
 #ifndef WIFICOND_CLIENT_INTERFACE_IMPL_H_
 #define WIFICOND_CLIENT_INTERFACE_IMPL_H_
 
+#include <array>
 #include <string>
 
+#include <linux/if_ether.h>
+
 #include <android-base/macros.h>
 #include <utils/StrongPointer.h>
 #include <wifi_system/interface_tool.h>
@@ -62,7 +65,7 @@
       uint32_t wiphy_index,
       const std::string& interface_name,
       uint32_t interface_index,
-      const std::vector<uint8_t>& interface_mac_addr,
+      const std::array<uint8_t, ETH_ALEN>& interface_mac_addr,
       android::wifi_system::InterfaceTool* if_tool,
       NetlinkUtils* netlink_utils,
       ScanUtils* scan_utils);
@@ -73,10 +76,10 @@
 
   bool GetPacketCounters(std::vector<int32_t>* out_packet_counters);
   bool SignalPoll(std::vector<int32_t>* out_signal_poll_results);
-  const std::vector<uint8_t>& GetMacAddress();
+  const std::array<uint8_t, ETH_ALEN>& GetMacAddress();
   const std::string& GetInterfaceName() const { return interface_name_; }
   const android::sp<ScannerImpl> GetScanner() { return scanner_; };
-  bool SetMacAddress(const ::std::vector<uint8_t>& mac);
+  bool SetMacAddress(const std::array<uint8_t, ETH_ALEN>& mac);
   virtual bool IsAssociated() const;
   void Dump(std::stringstream* ss) const;
 
@@ -86,7 +89,7 @@
   const uint32_t wiphy_index_;
   const std::string interface_name_;
   const uint32_t interface_index_;
-  const std::vector<uint8_t> interface_mac_addr_;
+  const std::array<uint8_t, ETH_ALEN> interface_mac_addr_;
   android::wifi_system::InterfaceTool* const if_tool_;
   NetlinkUtils* const netlink_utils_;
   ScanUtils* const scan_utils_;
@@ -97,7 +100,7 @@
 
   // Cached information for this connection.
   bool is_associated_;
-  std::vector<uint8_t> bssid_;
+  std::array<uint8_t, ETH_ALEN> bssid_;
   uint32_t associate_freq_;
 
   // Capability information for this wiphy/interface.
diff --git a/logging_utils.cpp b/logging_utils.cpp
index f717a50..189f0dd 100644
--- a/logging_utils.cpp
+++ b/logging_utils.cpp
@@ -16,19 +16,19 @@
 
 #include "wificond/logging_utils.h"
 
+#include <array>
 #include <iomanip>
-#include <vector>
 
 #include <android-base/macros.h>
 
+using std::array;
 using std::string;
 using std::stringstream;
-using std::vector;
 
 namespace android {
 namespace wificond {
 
-string LoggingUtils::GetMacString(const vector<uint8_t>& mac_address) {
+string LoggingUtils::GetMacString(const array<uint8_t, ETH_ALEN>& mac_address) {
   stringstream ss;
   for (const uint8_t& b : mac_address) {
     ss << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(b);
diff --git a/logging_utils.h b/logging_utils.h
index 1176d8a..86592b3 100644
--- a/logging_utils.h
+++ b/logging_utils.h
@@ -17,9 +17,11 @@
 #ifndef WIFICOND_LOGGING_UTILS_H_
 #define WIFICOND_LOGGING_UTILS_H_
 
-#include <vector>
+#include <array>
 #include <sstream>
 
+#include <linux/if_ether.h>
+
 #include <android-base/macros.h>
 
 #include "wificond/net/netlink_manager.h"
@@ -30,7 +32,7 @@
 class LoggingUtils {
  public:
   LoggingUtils() = default;
-  static std::string GetMacString(const std::vector<uint8_t>& mac_address);
+  static std::string GetMacString(const std::array<uint8_t, ETH_ALEN>& mac_address);
   static std::string GetBandwidthString(ChannelBandwidth bandwidth);
 
  private:
diff --git a/net/mlme_event.cpp b/net/mlme_event.cpp
index 2a87a1d..1e58d38 100644
--- a/net/mlme_event.cpp
+++ b/net/mlme_event.cpp
@@ -23,6 +23,7 @@
 #include "wificond/net/kernel-header-latest/nl80211.h"
 #include "wificond/net/nl80211_packet.h"
 
+using std::array;
 using std::unique_ptr;
 using std::vector;
 
@@ -33,7 +34,7 @@
 
 bool GetCommonFields(const NL80211Packet* packet,
                      uint32_t* if_index,
-                     vector<uint8_t>* bssid) {
+                     array<uint8_t, ETH_ALEN>* bssid) {
   if (!packet->GetAttributeValue(NL80211_ATTR_IFINDEX, if_index)) {
      LOG(ERROR) << "Failed to get NL80211_ATTR_IFINDEX";
      return false;
diff --git a/net/mlme_event.h b/net/mlme_event.h
index cc332fc..79d25e3 100644
--- a/net/mlme_event.h
+++ b/net/mlme_event.h
@@ -17,8 +17,10 @@
 #ifndef WIFICOND_NET_MLME_EVENT_H_
 #define WIFICOND_NET_MLME_EVENT_H_
 
+#include <array>
 #include <memory>
-#include <vector>
+
+#include <linux/if_ether.h>
 
 #include <android-base/macros.h>
 
@@ -32,7 +34,7 @@
   static std::unique_ptr<MlmeConnectEvent> InitFromPacket(
       const NL80211Packet* packet);
   // Returns the BSSID of the associated AP.
-  const std::vector<uint8_t>& GetBSSID() const { return bssid_; }
+  const std::array<uint8_t, ETH_ALEN>& GetBSSID() const { return bssid_; }
   // Get the status code of this connect event.
   // 0 = success, non-zero = failure.
   // Status codes definition: IEEE 802.11-2012, 8.4.1.9, Table 8-37
@@ -44,7 +46,7 @@
   MlmeConnectEvent() = default;
 
   uint32_t interface_index_;
-  std::vector<uint8_t> bssid_;
+  std::array<uint8_t, ETH_ALEN> bssid_;
   uint16_t status_code_;
   bool is_timeout_;
 
@@ -56,7 +58,7 @@
   static std::unique_ptr<MlmeAssociateEvent> InitFromPacket(
       const NL80211Packet* packet);
   // Returns the BSSID of the associated AP.
-  const std::vector<uint8_t>& GetBSSID() const { return bssid_; }
+  const std::array<uint8_t, ETH_ALEN>& GetBSSID() const { return bssid_; }
   // Get the status code of this associate event.
   // 0 = success, non-zero = failure.
   // Status codes definition: IEEE 802.11-2012, 8.4.1.9, Table 8-37
@@ -68,7 +70,7 @@
   MlmeAssociateEvent() = default;
 
   uint32_t interface_index_;
-  std::vector<uint8_t> bssid_;
+  std::array<uint8_t, ETH_ALEN> bssid_;
   uint16_t status_code_;
   bool is_timeout_;
 
@@ -80,14 +82,14 @@
   static std::unique_ptr<MlmeRoamEvent> InitFromPacket(
       const NL80211Packet* packet);
   // Returns the BSSID of the associated AP.
-  const std::vector<uint8_t>& GetBSSID() const { return bssid_; }
+  const std::array<uint8_t, ETH_ALEN>& GetBSSID() const { return bssid_; }
   uint32_t GetInterfaceIndex() const { return interface_index_; }
 
  private:
   MlmeRoamEvent() = default;
 
   uint32_t interface_index_;
-  std::vector<uint8_t> bssid_;
+  std::array<uint8_t, ETH_ALEN> bssid_;
 
   DISALLOW_COPY_AND_ASSIGN(MlmeRoamEvent);
 };
@@ -102,7 +104,7 @@
   MlmeDisconnectEvent() = default;
 
   uint32_t interface_index_;
-  std::vector<uint8_t> bssid_;
+  std::array<uint8_t, ETH_ALEN> bssid_;
 
   DISALLOW_COPY_AND_ASSIGN(MlmeDisconnectEvent);
 };
@@ -116,7 +118,7 @@
   MlmeDisassociateEvent() = default;
 
   uint32_t interface_index_;
-  std::vector<uint8_t> bssid_;
+  std::array<uint8_t, ETH_ALEN> bssid_;
 
   DISALLOW_COPY_AND_ASSIGN(MlmeDisassociateEvent);
 };
diff --git a/net/netlink_manager.cpp b/net/netlink_manager.cpp
index e7e10ae..83a6a7d 100644
--- a/net/netlink_manager.cpp
+++ b/net/netlink_manager.cpp
@@ -33,6 +33,7 @@
 #include "net/nl80211_packet.h"
 
 using android::base::unique_fd;
+using std::array;
 using std::placeholders::_1;
 using std::string;
 using std::unique_ptr;
@@ -534,7 +535,7 @@
     }
     const auto handler = on_station_event_handler_.find(if_index);
     if (handler != on_station_event_handler_.end()) {
-      vector<uint8_t> mac_address;
+      array<uint8_t, ETH_ALEN> mac_address;
       if (!packet->GetAttributeValue(NL80211_ATTR_MAC, &mac_address)) {
         LOG(WARNING) << "Failed to get mac address from station event";
         return;
diff --git a/net/netlink_manager.h b/net/netlink_manager.h
index f8817f4..71b20a1 100644
--- a/net/netlink_manager.h
+++ b/net/netlink_manager.h
@@ -17,10 +17,13 @@
 #ifndef WIFICOND_NET_NETLINK_MANAGER_H_
 #define WIFICOND_NET_NETLINK_MANAGER_H_
 
+#include <array>
 #include <functional>
 #include <map>
 #include <memory>
 
+#include <linux/if_ether.h>
+
 #include <android-base/macros.h>
 #include <android-base/unique_fd.h>
 
@@ -113,7 +116,7 @@
 // |mac_address| is the station mac address associated with this event.
 typedef std::function<void(
     StationEvent event,
-    const std::vector<uint8_t>& mac_address)> OnStationEventHandler;
+    const std::array<uint8_t, ETH_ALEN>& mac_address)> OnStationEventHandler;
 
 class NetlinkManager {
  public:
diff --git a/net/netlink_utils.cpp b/net/netlink_utils.cpp
index adaa37e..48d7d3c 100644
--- a/net/netlink_utils.cpp
+++ b/net/netlink_utils.cpp
@@ -16,6 +16,8 @@
 
 #include "wificond/net/netlink_utils.h"
 
+#include <array>
+#include <algorithm>
 #include <bitset>
 #include <map>
 #include <string>
@@ -29,6 +31,7 @@
 #include "wificond/net/mlme_event_handler.h"
 #include "wificond/net/nl80211_packet.h"
 
+using std::array;
 using std::make_pair;
 using std::make_unique;
 using std::map;
@@ -198,7 +201,7 @@
       continue;
     }
 
-    vector<uint8_t> if_mac_addr;
+    array<uint8_t, ETH_ALEN> if_mac_addr;
     if (!packet->GetAttributeValue(NL80211_ATTR_MAC, &if_mac_addr)) {
       LOG(WARNING) << "Failed to get interface mac address";
       continue;
@@ -457,7 +460,7 @@
 }
 
 bool NetlinkUtils::GetStationInfo(uint32_t interface_index,
-                                  const vector<uint8_t>& mac_address,
+                                  const array<uint8_t, ETH_ALEN>& mac_address,
                                   StationInfo* out_station_info) {
   NL80211Packet get_station(
       netlink_manager_->GetFamilyId(),
@@ -466,8 +469,8 @@
       getpid());
   get_station.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_IFINDEX,
                                                  interface_index));
-  get_station.AddAttribute(NL80211Attr<vector<uint8_t>>(NL80211_ATTR_MAC,
-                                                        mac_address));
+  get_station.AddAttribute(NL80211Attr<array<uint8_t, ETH_ALEN>>(
+      NL80211_ATTR_MAC, mac_address));
 
   unique_ptr<const NL80211Packet> response;
   if (!netlink_manager_->SendMessageAndGetSingleResponse(get_station,
diff --git a/net/netlink_utils.h b/net/netlink_utils.h
index fd73fac..2f627ad 100644
--- a/net/netlink_utils.h
+++ b/net/netlink_utils.h
@@ -17,9 +17,12 @@
 #ifndef WIFICOND_NET_NETLINK_UTILS_H_
 #define WIFICOND_NET_NETLINK_UTILS_H_
 
+#include <array>
 #include <string>
 #include <vector>
 
+#include <linux/if_ether.h>
+
 #include <android-base/macros.h>
 
 #include "wificond/net/kernel-header-latest/nl80211.h"
@@ -30,18 +33,18 @@
 
 struct InterfaceInfo {
   InterfaceInfo() = default;
-  InterfaceInfo(uint32_t index_,
-                const std::string name_,
-                const std::vector<uint8_t> mac_address_)
-      : index(index_),
-        name(name_),
-        mac_address(mac_address_) {}
+  InterfaceInfo(uint32_t index,
+                const std::string& name,
+                const std::array<uint8_t, ETH_ALEN>& mac_address)
+      : index(index),
+        name(name),
+        mac_address(mac_address) {}
   // Index of this interface.
   uint32_t index;
   // Name of this interface.
   std::string name;
   // MAC address of this interface.
-  std::vector<uint8_t> mac_address;
+  std::array<uint8_t, ETH_ALEN> mac_address;
 };
 
 struct BandInfo {
@@ -184,7 +187,7 @@
   // |*out_station_info]| is the struct of available station information.
   // Returns true on success.
   virtual bool GetStationInfo(uint32_t interface_index,
-                              const std::vector<uint8_t>& mac_address,
+                              const std::array<uint8_t, ETH_ALEN>& mac_address,
                               StationInfo* out_station_info);
 
   // Get a bitmap for nl80211 protocol features,
diff --git a/net/nl80211_attribute.h b/net/nl80211_attribute.h
index 04fc890..1493c56 100644
--- a/net/nl80211_attribute.h
+++ b/net/nl80211_attribute.h
@@ -113,6 +113,23 @@
   std::vector<uint8_t> GetValue() const;
 }; // class NL80211Attr for raw data
 
+template <size_t N>
+class NL80211Attr<std::array<uint8_t, N>> : public BaseNL80211Attr {
+ public:
+  NL80211Attr(int id, const std::array<uint8_t, N>& raw_buffer)
+      : BaseNL80211Attr(
+          id, std::vector<uint8_t>(raw_buffer.begin(), raw_buffer.end())) {}
+  explicit NL80211Attr(const std::vector<uint8_t>& data) {
+    data_ = data;
+  }
+  ~NL80211Attr() override = default;
+  std::array<uint8_t, N> GetValue() const {
+    std::array<uint8_t, N> arr;
+    std::copy_n(data_.data() + NLA_HDRLEN, N, arr.begin());
+    return arr;
+  }
+}; // class NL80211Attr for fixed size array
+
 template <>
 class NL80211Attr<std::string> : public BaseNL80211Attr {
  public:
diff --git a/scanning/offload/offload_scan_utils.cpp b/scanning/offload/offload_scan_utils.cpp
index 1446f76..d476507 100644
--- a/scanning/offload/offload_scan_utils.cpp
+++ b/scanning/offload/offload_scan_utils.cpp
@@ -43,7 +43,7 @@
     single_scan_result.ssid.assign(scan_result[i].networkInfo.ssid.begin(),
                                    scan_result[i].networkInfo.ssid.end());
     for (size_t j = 0; j < scan_result[i].bssid.elementCount(); j++) {
-      single_scan_result.bssid.push_back(scan_result[i].bssid[j]);
+      single_scan_result.bssid.at(j) = scan_result[i].bssid[j];
     }
     single_scan_result.frequency = scan_result[i].frequency;
     single_scan_result.signal_mbm = scan_result[i].rssi;
diff --git a/scanning/scan_result.cpp b/scanning/scan_result.cpp
index 7df4daa..fa85981 100644
--- a/scanning/scan_result.cpp
+++ b/scanning/scan_result.cpp
@@ -16,6 +16,8 @@
 
 #include "wificond/scanning/scan_result.h"
 
+#include <algorithm>
+
 #include <android-base/logging.h>
 
 #include "wificond/logging_utils.h"
@@ -32,7 +34,7 @@
 namespace wificond {
 
 NativeScanResult::NativeScanResult(std::vector<uint8_t>& ssid_,
-                                   std::vector<uint8_t>& bssid_,
+                                   std::array<uint8_t, ETH_ALEN>& bssid_,
                                    std::vector<uint8_t>& info_element_,
                                    uint32_t frequency_,
                                    int32_t signal_mbm_,
@@ -53,7 +55,8 @@
 
 status_t NativeScanResult::writeToParcel(::android::Parcel* parcel) const {
   RETURN_IF_FAILED(parcel->writeByteVector(ssid));
-  RETURN_IF_FAILED(parcel->writeByteVector(bssid));
+  RETURN_IF_FAILED(parcel->writeByteVector(
+      std::vector<uint8_t>(bssid.begin(), bssid.end())));
   RETURN_IF_FAILED(parcel->writeByteVector(info_element));
   RETURN_IF_FAILED(parcel->writeUint32(frequency));
   RETURN_IF_FAILED(parcel->writeInt32(signal_mbm));
@@ -74,7 +77,16 @@
 
 status_t NativeScanResult::readFromParcel(const ::android::Parcel* parcel) {
   RETURN_IF_FAILED(parcel->readByteVector(&ssid));
-  RETURN_IF_FAILED(parcel->readByteVector(&bssid));
+  {
+    std::vector<uint8_t> bssid_vec;
+    RETURN_IF_FAILED(parcel->readByteVector(&bssid_vec));
+    if (bssid_vec.size() != ETH_ALEN) {
+      LOG(ERROR) << "bssid length expected " << ETH_ALEN << " bytes, but got "
+                 << bssid_vec.size() << " bytes";
+      return ::android::BAD_VALUE;
+    }
+    std::copy_n(bssid_vec.begin(), ETH_ALEN, bssid.begin());
+  }
   RETURN_IF_FAILED(parcel->readByteVector(&info_element));
   RETURN_IF_FAILED(parcel->readUint32(&frequency));
   RETURN_IF_FAILED(parcel->readInt32(&signal_mbm));
diff --git a/scanning/scan_result.h b/scanning/scan_result.h
index 4e7df47..bd9dc98 100644
--- a/scanning/scan_result.h
+++ b/scanning/scan_result.h
@@ -17,8 +17,11 @@
 #ifndef WIFICOND_SCANNING_SCAN_RESULT_H_
 #define WIFICOND_SCANNING_SCAN_RESULT_H_
 
+#include <array>
 #include <vector>
 
+#include <linux/if_ether.h>
+
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
 
@@ -35,7 +38,7 @@
  public:
   NativeScanResult() = default;
   NativeScanResult(std::vector<uint8_t>& ssid,
-                   std::vector<uint8_t>& bssid,
+                   std::array<uint8_t, ETH_ALEN>& bssid,
                    std::vector<uint8_t>& info_element,
                    uint32_t frequency,
                    int32_t signal_mbm,
@@ -51,7 +54,7 @@
   // SSID of the BSS.
   std::vector<uint8_t> ssid;
   // BSSID of the BSS.
-  std::vector<uint8_t> bssid;
+  std::array<uint8_t, ETH_ALEN> bssid;
   // Binary array containing the raw information elements from the probe
   // response/beacon.
   std::vector<uint8_t> info_element;
diff --git a/scanning/scan_utils.cpp b/scanning/scan_utils.cpp
index 708e0b4..7b38871 100644
--- a/scanning/scan_utils.cpp
+++ b/scanning/scan_utils.cpp
@@ -17,9 +17,11 @@
 #include "android/net/wifi/IWifiScannerImpl.h"
 #include "wificond/scanning/scan_utils.h"
 
+#include <array>
 #include <vector>
 
 #include <linux/netlink.h>
+#include <linux/if_ether.h>
 
 #include <android-base/logging.h>
 
@@ -31,6 +33,7 @@
 using android::net::wifi::IWifiScannerImpl;
 using com::android::server::wifi::wificond::NativeScanResult;
 using com::android::server::wifi::wificond::RadioChainInfo;
+using std::array;
 using std::unique_ptr;
 using std::vector;
 
@@ -134,7 +137,7 @@
   }
   NL80211NestedAttr bss(0);
   if (packet->GetAttribute(NL80211_ATTR_BSS, &bss)) {
-    vector<uint8_t> bssid;
+    array<uint8_t, ETH_ALEN> bssid;
     if (!bss.GetAttributeValue(NL80211_BSS_BSSID, &bssid)) {
       LOG(ERROR) << "Failed to get BSSID from scan result packet";
       return false;
diff --git a/tests/ap_interface_impl_unittest.cpp b/tests/ap_interface_impl_unittest.cpp
index dfd1510..0f1bf28 100644
--- a/tests/ap_interface_impl_unittest.cpp
+++ b/tests/ap_interface_impl_unittest.cpp
@@ -14,9 +14,12 @@
  * limitations under the License.
  */
 
+#include <array>
 #include <memory>
 #include <vector>
 
+#include <linux/if_ether.h>
+
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <wifi_system_test/mock_interface_tool.h>
@@ -28,6 +31,7 @@
 #include "wificond/ap_interface_impl.h"
 
 using android::wifi_system::MockInterfaceTool;
+using std::array;
 using std::placeholders::_1;
 using std::placeholders::_2;
 using std::unique_ptr;
@@ -45,7 +49,7 @@
 
 const char kTestInterfaceName[] = "testwifi0";
 const uint32_t kTestInterfaceIndex = 42;
-const uint8_t kFakeMacAddress[] = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
+const array<uint8_t, ETH_ALEN> kFakeMacAddress = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
 
 void CaptureStationEventHandler(
     OnStationEventHandler* out_handler,
@@ -95,8 +99,7 @@
         netlink_utils_.get(),
         if_tool_.get()));
 
-  vector<uint8_t> fake_mac_address(kFakeMacAddress,
-                                   kFakeMacAddress + sizeof(kFakeMacAddress));
+  array<uint8_t, ETH_ALEN> fake_mac_address = kFakeMacAddress;
   EXPECT_EQ(0, ap_interface_->GetNumberOfAssociatedStations());
   handler(NEW_STATION, fake_mac_address);
   EXPECT_EQ(1, ap_interface_->GetNumberOfAssociatedStations());
@@ -120,8 +123,7 @@
   EXPECT_TRUE(binder->registerCallback(callback, &out_success).isOk());
   EXPECT_TRUE(out_success);
 
-  vector<uint8_t> fake_mac_address(kFakeMacAddress,
-                                   kFakeMacAddress + sizeof(kFakeMacAddress));
+  array<uint8_t, ETH_ALEN> fake_mac_address = kFakeMacAddress;
   EXPECT_CALL(*callback, onNumAssociatedStationsChanged(1));
   handler(NEW_STATION, fake_mac_address);
   EXPECT_CALL(*callback, onNumAssociatedStationsChanged(2));
diff --git a/tests/client_interface_impl_unittest.cpp b/tests/client_interface_impl_unittest.cpp
index da61ce6..08033c3 100644
--- a/tests/client_interface_impl_unittest.cpp
+++ b/tests/client_interface_impl_unittest.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <array>
 #include <memory>
 #include <vector>
 
@@ -40,7 +41,6 @@
 const uint32_t kTestWiphyIndex = 2;
 const char kTestInterfaceName[] = "testwifi0";
 const uint32_t kTestInterfaceIndex = 42;
-const size_t kMacAddrLenBytes = ETH_ALEN;
 
 class ClientInterfaceImplTest : public ::testing::Test {
  protected:
@@ -54,7 +54,7 @@
         kTestWiphyIndex,
         kTestInterfaceName,
         kTestInterfaceIndex,
-        vector<uint8_t>{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+        std::array<uint8_t, ETH_ALEN>{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
         if_tool_.get(),
         netlink_utils_.get(),
         scan_utils_.get()});
@@ -78,24 +78,17 @@
 
 }  // namespace
 
-TEST_F(ClientInterfaceImplTest, SetMacAddressFailsOnInvalidInput) {
-  EXPECT_FALSE(client_interface_->SetMacAddress(
-      std::vector<uint8_t>(kMacAddrLenBytes - 1)));
-  EXPECT_FALSE(client_interface_->SetMacAddress(
-      std::vector<uint8_t>(kMacAddrLenBytes + 1)));
-}
-
 TEST_F(ClientInterfaceImplTest, SetMacAddressFailsOnInterfaceDownFailure) {
   EXPECT_CALL(*if_tool_, SetWifiUpState(false)).WillOnce(Return(false));
   EXPECT_FALSE(
-      client_interface_->SetMacAddress(std::vector<uint8_t>(kMacAddrLenBytes)));
+      client_interface_->SetMacAddress(std::array<uint8_t, ETH_ALEN>()));
 }
 
 TEST_F(ClientInterfaceImplTest, SetMacAddressFailsOnAddressChangeFailure) {
   EXPECT_CALL(*if_tool_, SetWifiUpState(false)).WillOnce(Return(true));
   EXPECT_CALL(*if_tool_, SetMacAddress(_, _)).WillOnce(Return(false));
   EXPECT_FALSE(
-      client_interface_->SetMacAddress(std::vector<uint8_t>(kMacAddrLenBytes)));
+      client_interface_->SetMacAddress(std::array<uint8_t, ETH_ALEN>()));
 }
 
 TEST_F(ClientInterfaceImplTest, SetMacAddressFailsOnInterfaceUpFailure) {
@@ -103,7 +96,7 @@
   EXPECT_CALL(*if_tool_, SetMacAddress(_, _)).WillOnce(Return(true));
   EXPECT_CALL(*if_tool_, SetWifiUpState(true)).WillOnce(Return(false));
   EXPECT_FALSE(
-      client_interface_->SetMacAddress(std::vector<uint8_t>(kMacAddrLenBytes)));
+      client_interface_->SetMacAddress(std::array<uint8_t, ETH_ALEN>()));
 }
 
 TEST_F(ClientInterfaceImplTest, SetMacAddressReturnsTrueOnSuccess) {
@@ -111,17 +104,17 @@
   EXPECT_CALL(*if_tool_, SetMacAddress(_, _)).WillOnce(Return(true));
   EXPECT_CALL(*if_tool_, SetWifiUpState(true)).WillOnce(Return(true));
   EXPECT_TRUE(
-      client_interface_->SetMacAddress(std::vector<uint8_t>(kMacAddrLenBytes)));
+      client_interface_->SetMacAddress(std::array<uint8_t, ETH_ALEN>()));
 }
 
 TEST_F(ClientInterfaceImplTest, SetMacAddressPassesCorrectAddressToIfTool) {
   EXPECT_CALL(*if_tool_, SetWifiUpState(false)).WillOnce(Return(true));
   EXPECT_CALL(*if_tool_, SetMacAddress(_,
-      std::array<uint8_t, kMacAddrLenBytes>{{1, 2, 3, 4, 5, 6}}))
+      std::array<uint8_t, ETH_ALEN>{{1, 2, 3, 4, 5, 6}}))
     .WillOnce(Return(true));
   EXPECT_CALL(*if_tool_, SetWifiUpState(true)).WillOnce(Return(true));
   EXPECT_TRUE(client_interface_->SetMacAddress(
-      std::vector<uint8_t>{1, 2, 3, 4, 5, 6}));
+      std::array<uint8_t, ETH_ALEN>{{1, 2, 3, 4, 5, 6}}));
 }
 
 }  // namespace wificond
diff --git a/tests/mock_client_interface_impl.cpp b/tests/mock_client_interface_impl.cpp
index d2f1915..8476cff 100644
--- a/tests/mock_client_interface_impl.cpp
+++ b/tests/mock_client_interface_impl.cpp
@@ -18,6 +18,8 @@
 
 #include <vector>
 
+#include <linux/if_ether.h>
+
 #include <wifi_system/interface_tool.h>
 
 #include "wificond/net/netlink_utils.h"
@@ -27,7 +29,7 @@
 namespace wificond {
 
 const char kTestInterfaceName[] = "testwifi0";
-const uint8_t kTestInterfaceMacAddress[] = {0x10, 0x20, 0xfe, 0xae, 0x2d, 0xc2};
+const std::array<uint8_t, ETH_ALEN> kTestInterfaceMacAddress = {0x10, 0x20, 0xfe, 0xae, 0x2d, 0xc2};
 const uint32_t kTestInterfaceIndex = 42;
 const uint32_t kTestWiphyIndex = 2;
 
@@ -39,9 +41,7 @@
         kTestWiphyIndex,
         kTestInterfaceName,
         kTestInterfaceIndex,
-        std::vector<uint8_t>(
-            kTestInterfaceMacAddress,
-            kTestInterfaceMacAddress + arraysize(kTestInterfaceMacAddress)),
+        std::array<uint8_t, ETH_ALEN>(kTestInterfaceMacAddress),
         interface_tool,
         netlink_utils,
         scan_utils) {}
diff --git a/tests/netlink_utils_unittest.cpp b/tests/netlink_utils_unittest.cpp
index 4e7fd56..f650ff4 100644
--- a/tests/netlink_utils_unittest.cpp
+++ b/tests/netlink_utils_unittest.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <array>
 #include <memory>
 #include <string>
 #include <vector>
@@ -65,8 +66,8 @@
 const char kFakeCountryCode[] = "US";
 const uint32_t kFakeInterfaceIndex = 34;
 const uint32_t kFakeInterfaceIndex1 = 36;
-const uint8_t kFakeInterfaceMacAddress[] = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
-const uint8_t kFakeInterfaceMacAddress1[] = {0x05, 0x04, 0xef, 0x27, 0x12, 0xff};
+const std::array<uint8_t, ETH_ALEN> kFakeInterfaceMacAddress = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
+const std::array<uint8_t, ETH_ALEN> kFakeInterfaceMacAddress1 = {0x05, 0x04, 0xef, 0x27, 0x12, 0xff};
 const uint8_t kFakeExtFeaturesForLowSpanScan[] = {0x0, 0x0, 0x40};
 const uint8_t kFakeExtFeaturesForLowPowerScan[] = {0x0, 0x0, 0x80};
 const uint8_t kFakeExtFeaturesForHighAccuracy[] = {0x0, 0x0, 0x0, 0x1};
@@ -367,11 +368,8 @@
   NL80211Attr<uint32_t> if_index_attr(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex);
   new_interface.AddAttribute(if_index_attr);
   // Insert mac address attribute.
-  std::vector<uint8_t> if_mac_addr;
-  if_mac_addr.assign(
-      kFakeInterfaceMacAddress,
-      kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress));
-  NL80211Attr<vector<uint8_t>> if_mac_attr(NL80211_ATTR_MAC, if_mac_addr);
+  std::array<uint8_t, ETH_ALEN> if_mac_addr = kFakeInterfaceMacAddress;
+  NL80211Attr<std::array<uint8_t, ETH_ALEN>> if_mac_attr(NL80211_ATTR_MAC, if_mac_addr);
   new_interface.AddAttribute(if_mac_attr);
 
   // Mock a valid response from kernel.
@@ -409,12 +407,9 @@
       NL80211_ATTR_IFNAME, string(kFakeInterfaceName)));
   expected_interface.AddAttribute(NL80211Attr<uint32_t>(
       NL80211_ATTR_IFINDEX, kFakeInterfaceIndex));
-  std::vector<uint8_t> if_mac_addr;
-  if_mac_addr.assign(
-      kFakeInterfaceMacAddress,
-      kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress));
+  std::array<uint8_t, ETH_ALEN> if_mac_addr = kFakeInterfaceMacAddress;
   expected_interface.AddAttribute(
-      NL80211Attr<vector<uint8_t>>(NL80211_ATTR_MAC, if_mac_addr));
+      NL80211Attr<std::array<uint8_t, ETH_ALEN>>(NL80211_ATTR_MAC, if_mac_addr));
 
   // Kernel can send us the pseduo interface packet first
   vector<NL80211Packet> response = {psuedo_interface, expected_interface};
@@ -443,11 +438,9 @@
   new_interface.AddAttribute(
       NL80211Attr<uint32_t>(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex));
   // Insert mac address attribute.
-  std::vector<uint8_t> if_mac_addr(
-      kFakeInterfaceMacAddress,
-      kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress));
+  std::array<uint8_t, ETH_ALEN> if_mac_addr = kFakeInterfaceMacAddress;
   new_interface.AddAttribute(
-      NL80211Attr<vector<uint8_t>>(NL80211_ATTR_MAC, if_mac_addr));
+      NL80211Attr<std::array<uint8_t, ETH_ALEN>>(NL80211_ATTR_MAC, if_mac_addr));
 
   // Create a new interface packet for p2p0.
   NL80211Packet new_interface_p2p0(
@@ -463,11 +456,9 @@
   new_interface_p2p0.AddAttribute(
       NL80211Attr<uint32_t>(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex1));
   // Insert mac address attribute.
-  std::vector<uint8_t> if_mac_addr_p2p(
-      kFakeInterfaceMacAddress1,
-      kFakeInterfaceMacAddress1 + sizeof(kFakeInterfaceMacAddress1));
+  std::array<uint8_t, ETH_ALEN> if_mac_addr_p2p = kFakeInterfaceMacAddress1;
   new_interface_p2p0.AddAttribute(
-      NL80211Attr<vector<uint8_t>>(NL80211_ATTR_MAC, if_mac_addr_p2p));
+      NL80211Attr<std::array<uint8_t, ETH_ALEN>>(NL80211_ATTR_MAC, if_mac_addr_p2p));
 
   // Mock response from kernel, including 2 interfaces.
   vector<NL80211Packet> response = {new_interface_p2p0, new_interface};
diff --git a/tests/scan_result_unittest.cpp b/tests/scan_result_unittest.cpp
index 01dcfd7..facda6f 100644
--- a/tests/scan_result_unittest.cpp
+++ b/tests/scan_result_unittest.cpp
@@ -14,14 +14,18 @@
  * limitations under the License.
  */
 
+#include <array>
 #include <vector>
 
+#include <linux/if_ether.h>
+
 #include <gtest/gtest.h>
 
 #include "wificond/scanning/scan_result.h"
 
 using ::com::android::server::wifi::wificond::NativeScanResult;
 using ::com::android::server::wifi::wificond::RadioChainInfo;
+using std::array;
 using std::vector;
 
 namespace android {
@@ -32,7 +36,7 @@
 
 const uint8_t kFakeSsid[] =
     {'G', 'o', 'o', 'g', 'l', 'e', 'G', 'u', 'e', 's', 't'};
-const uint8_t kFakeBssid[] = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
+const array<uint8_t, ETH_ALEN> kFakeBssid = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
 const uint8_t kFakeIE[] = {0x05, 0x11, 0x32, 0x11};
 constexpr uint32_t kFakeFrequency = 5240;
 constexpr int32_t kFakeSignalMbm= -32;
@@ -49,7 +53,7 @@
 
 TEST_F(ScanResultTest, ParcelableTest) {
   std::vector<uint8_t> ssid(kFakeSsid, kFakeSsid + sizeof(kFakeSsid));
-  std::vector<uint8_t> bssid(kFakeBssid, kFakeBssid + sizeof(kFakeBssid));
+  array<uint8_t, ETH_ALEN> bssid = kFakeBssid;
   std::vector<uint8_t> ie(kFakeIE, kFakeIE + sizeof(kFakeIE));
   std::vector<RadioChainInfo> radio_chain_infos;
   radio_chain_infos.emplace_back(
diff --git a/tests/server_unittest.cpp b/tests/server_unittest.cpp
index adfe50e..774bd12 100644
--- a/tests/server_unittest.cpp
+++ b/tests/server_unittest.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <array>
 #include <memory>
 
 #include <gmock/gmock.h>
@@ -53,9 +54,9 @@
 const uint32_t kFakeInterfaceIndex = 34;
 const uint32_t kFakeInterfaceIndex1 = 36;
 const uint32_t kFakeInterfaceIndexP2p = 36;
-const uint8_t kFakeInterfaceMacAddress[] = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
-const uint8_t kFakeInterfaceMacAddress1[] = {0x05, 0x04, 0xef, 0x27, 0x12, 0xff};
-const uint8_t kFakeInterfaceMacAddressP2p[] = {0x15, 0x24, 0xef, 0x27, 0x12, 0xff};
+const std::array<uint8_t, ETH_ALEN> kFakeInterfaceMacAddress = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
+const std::array<uint8_t, ETH_ALEN> kFakeInterfaceMacAddress1 = {0x05, 0x04, 0xef, 0x27, 0x12, 0xff};
+const std::array<uint8_t, ETH_ALEN> kFakeInterfaceMacAddressP2p = {0x15, 0x24, 0xef, 0x27, 0x12, 0xff};
 
 // This is a helper function to mock the behavior of
 // NetlinkUtils::GetInterfaces().
@@ -98,23 +99,17 @@
       InterfaceInfo(
           kFakeInterfaceIndex,
           std::string(kFakeInterfaceName),
-          vector<uint8_t>(
-              kFakeInterfaceMacAddress,
-              kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress))),
+          std::array<uint8_t, ETH_ALEN>(kFakeInterfaceMacAddress)),
       // AP Interface
       InterfaceInfo(
           kFakeInterfaceIndex1,
           std::string(kFakeInterfaceName1),
-          vector<uint8_t>(
-              kFakeInterfaceMacAddress1,
-              kFakeInterfaceMacAddress1 + sizeof(kFakeInterfaceMacAddress1))),
+          std::array<uint8_t, ETH_ALEN>(kFakeInterfaceMacAddress1)),
       // p2p interface
       InterfaceInfo(
           kFakeInterfaceIndexP2p,
           std::string(kFakeInterfaceNameP2p),
-           vector<uint8_t>(
-               kFakeInterfaceMacAddressP2p,
-               kFakeInterfaceMacAddressP2p + sizeof(kFakeInterfaceMacAddressP2p)))
+          std::array<uint8_t, ETH_ALEN>(kFakeInterfaceMacAddressP2p))
   };
 
   Server server_{unique_ptr<InterfaceTool>(if_tool_),