/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef WIFICOND_NET_NETLINK_UTILS_H_
#define WIFICOND_NET_NETLINK_UTILS_H_

#include <array>
#include <functional>
#include <string>
#include <vector>

#include <linux/if_ether.h>

#include <android-base/macros.h>

#include "wificond/net/kernel-header-latest/nl80211.h"
#include "wificond/net/netlink_manager.h"
#include "wificond/net/nl80211_packet.h"

namespace android {
namespace wificond {

struct InterfaceInfo {
  InterfaceInfo() = default;
  InterfaceInfo(uint32_t if_index,
                uint32_t wiphy_index,
                const std::string& name,
                const std::array<uint8_t, ETH_ALEN>& mac_address)
      : if_index(if_index),
        wiphy_index(wiphy_index),
        name(name),
        mac_address(mac_address) {}
  // Index of this interface.
  uint32_t if_index;
  // Wiphy Index of this interface.
  uint32_t wiphy_index;
  // Name of this interface.
  std::string name;
  // MAC address of this interface.
  std::array<uint8_t, ETH_ALEN> mac_address;
};

struct BandInfo {
  BandInfo():
      is_80211n_supported(false),
      is_80211ac_supported(false),
      is_80211ax_supported(false),
      is_80211be_supported(false),
      is_160_mhz_supported(false),
      is_80p80_mhz_supported(false),
      is_320_mhz_supported(false),
      max_tx_streams(1),
      max_rx_streams(1) {};
  // Frequencies for 2.4 GHz band.
  std::vector<uint32_t> band_2g;
  // Frequencies for 5 GHz band without DFS.
  std::vector<uint32_t> band_5g;
  // Frequencies for DFS.
  std::vector<uint32_t> band_dfs;
  // Frequencies for 6 GHz band.
  std::vector<uint32_t> band_6g;
  // Frequencies for 60 GHz band.
  std::vector<uint32_t> band_60g;
  // support for 802.11n
  bool is_80211n_supported;
  // support for 802.11ac
  bool is_80211ac_supported;
  // support for 802.11ax
  bool is_80211ax_supported;
  // support for 802.11be
  bool is_80211be_supported;
  // support for 160Mhz channel width
  bool is_160_mhz_supported;
  // support for 80+80Mhz channel width
  bool is_80p80_mhz_supported;
  // support for 320Mhz channel width
  bool is_320_mhz_supported;
  // Max number of transmit spatial streams
  uint32_t max_tx_streams;
  // Max number of receive spatial streams
  uint32_t max_rx_streams;
};

struct ScanCapabilities {
  ScanCapabilities() = default;
  ScanCapabilities(uint8_t max_num_scan_ssids_,
                   uint8_t max_num_sched_scan_ssids_,
                   uint8_t max_match_sets_,
                   uint32_t max_num_scan_plans_,
                   uint32_t max_scan_plan_interval_,
                   uint32_t max_scan_plan_iterations_)
      : max_num_scan_ssids(max_num_scan_ssids_),
        max_num_sched_scan_ssids(max_num_sched_scan_ssids_),
        max_match_sets(max_match_sets_),
        max_num_scan_plans(max_num_scan_plans_),
        max_scan_plan_interval(max_scan_plan_interval_),
        max_scan_plan_iterations(max_scan_plan_iterations_) {}
  // Number of SSIDs you can scan with a single scan request.
  uint8_t max_num_scan_ssids;
  // Number of SSIDs you can scan with a single scheduled scan request.
  uint8_t max_num_sched_scan_ssids;
  // Maximum number of sets that can be used with NL80211_ATTR_SCHED_SCAN_MATCH.
  uint8_t max_match_sets;
  // Maximum number of scan plans that can be specified.
  uint32_t max_num_scan_plans;
  // Maximum interval in seconds for a particular scan plan that can be
  // specified.
  uint32_t max_scan_plan_interval;
  // Maximum number of iterations for a particular scan plan that can be
  // specified.
  uint32_t max_scan_plan_iterations;
};

struct WiphyFeatures {
  WiphyFeatures()
      : supports_random_mac_oneshot_scan(false),
        supports_random_mac_sched_scan(false),
        supports_low_span_oneshot_scan(false),
        supports_low_power_oneshot_scan(false),
        supports_high_accuracy_oneshot_scan(false),
        supports_tx_mgmt_frame_mcs(false) {}
  WiphyFeatures(uint32_t feature_flags,
                const std::vector<uint8_t>& ext_feature_flags_bytes);
  // This device/driver supports using a random MAC address during scan
  // (while not associated).
  bool supports_random_mac_oneshot_scan;
  // This device/driver supports using a random MAC address for every
  // scan iteration during scheduled scan (while not associated).
  bool supports_random_mac_sched_scan;
  // This device/driver supports performing low-span/low-latency one-shot scans.
  bool supports_low_span_oneshot_scan;
  // This device/driver supports performing low-power one-shot scans.
  bool supports_low_power_oneshot_scan;
  // This device/driver supports performing high-accuracy one-shot scans.
  bool supports_high_accuracy_oneshot_scan;
  // This device/driver supports sending a management frame at a specified MCS.
  bool supports_tx_mgmt_frame_mcs;
  // This device/driver supports sched_scan for reporting BSSs
  // with better RSSI than the current connected BSS
  bool supports_ext_sched_scan_relative_rssi;
  // There are other flags included in NL80211_ATTR_FEATURE_FLAGS.
  // We will add them once we find them useful.
};

struct StationInfo {
  StationInfo() = default;
  StationInfo(uint32_t station_tx_packets_,
              uint32_t station_tx_failed_,
              uint32_t station_tx_bitrate_,
              int8_t current_rssi_,
              uint32_t station_rx_bitrate_)
      : station_tx_packets(station_tx_packets_),
        station_tx_failed(station_tx_failed_),
        station_tx_bitrate(station_tx_bitrate_),
        current_rssi(current_rssi_),
        station_rx_bitrate(station_rx_bitrate_) {}
  // Number of successfully transmitted packets.
  int32_t station_tx_packets;
  // Number of tramsmission failures.
  int32_t station_tx_failed;
  // Transimission bit rate in 100kbit/s.
  uint32_t station_tx_bitrate;
  // Current signal strength.
  int8_t current_rssi;
  // Last Received unicast packet bit rate in 100kbit/s.
  uint32_t station_rx_bitrate;
  // There are many other counters/parameters included in station info.
  // We will add them once we find them useful.
};

class MlmeEventHandler;
class NetlinkManager;
class NL80211Packet;

// Provides NL80211 helper functions.
class NetlinkUtils {
 public:
  // Currently we only support setting the interface to STATION mode.
  // This is used for cleaning up interface after KILLING hostapd.
  enum InterfaceMode{
      STATION_MODE
  };

  explicit NetlinkUtils(NetlinkManager* netlink_manager);
  virtual ~NetlinkUtils();

  // Get the wiphy index from kernel.
  // |*out_wiphy_index| returns the wiphy index from kernel.
  // Returns true on success.
  virtual bool GetWiphyIndex(uint32_t* out_wiphy_index);
  virtual bool GetWiphyIndex(uint32_t* out_wiphy_index,
                             const std::string& iface_name);

  // Get wifi interfaces info from kernel.
  // |wiphy_index| is the wiphy index we get using GetWiphyIndex().
  // |interface_info| returns a vector of InterfaceInfo structs with
  // information about all existing interfaces.
  // Returns true on success.
  virtual bool GetInterfaces(uint32_t wiphy_index,
                             std::vector<InterfaceInfo>* interface_info);

  // Set the mode of interface.
  // |interface_index| is the interface index.
  // |mode| is one of the values in |enum InterfaceMode|.
  // Returns true on success.
  virtual bool SetInterfaceMode(uint32_t interface_index,
                                InterfaceMode mode);

  // Get wiphy capability information from kernel.
  // Returns true on success.
  virtual bool GetWiphyInfo(uint32_t wiphy_index,
                            BandInfo* out_band_info,
                            ScanCapabilities* out_scan_capabilities,
                            WiphyFeatures* out_wiphy_features);

  // Get station info from kernel.
  // |*out_station_info]| is the struct of available station information.
  // Returns true on success.
  virtual bool GetStationInfo(uint32_t interface_index,
                              const std::array<uint8_t, ETH_ALEN>& mac_address,
                              StationInfo* out_station_info);

  // Get a bitmap for nl80211 protocol features,
  // i.e. features for the nl80211 protocol rather than device features.
  // See enum nl80211_protocol_features in nl80211.h for decoding the bitmap.
  // Returns true on success.
  virtual bool GetProtocolFeatures(uint32_t* features);

  // Get current alpha2 country code from kernel.
  // Returns true on success.
  virtual bool GetCountryCode(uint32_t wiphy_index,
                              std::string* out_country_code);

  // Sign up to be notified when there is MLME event.
  // Only one handler can be registered per interface index.
  // New handler will replace the registered handler if they are for the
  // same interface index.
  // NetlinkUtils is not going to take ownership of this pointer, and that it
  // is the caller's responsibility to make sure that the object exists for the
  // duration of the subscription.
  virtual void SubscribeMlmeEvent(uint32_t interface_index,
                                  MlmeEventHandler* handler);

  // Cancel the sign-up of receiving MLME event notification
  // from interface with index |interface_index|.
  virtual void UnsubscribeMlmeEvent(uint32_t interface_index);

  // Sign up to be notified when there is an regulatory domain change.
  // Only one handler can be registered per wiphy index.
  // New handler will replace the registered handler if they are for the
  // same wiphy index.
  virtual void SubscribeRegDomainChange(uint32_t wiphy_index,
                                        OnRegDomainChangedHandler handler);

  // Cancel the sign-up of receiving regulatory domain change notification
  // from wiphy with index |wiphy_index|.
  virtual void UnsubscribeRegDomainChange(uint32_t wiphy_index);

  // Sign up to be notified when there is a station event.
  // Only one handler can be registered per interface index.
  // New handler will replace the registered handler if they are for the
  // same interface index.
  virtual void SubscribeStationEvent(uint32_t interface_index,
                                     OnStationEventHandler handler);

  // Cancel the sign-up of receiving station events.
  virtual void UnsubscribeStationEvent(uint32_t interface_index);

  // Sign up to be notified when there is a channel switch event.
  // Only one handler can be registered per interface index.
  // New handler will replace the registered handler if they are for the
  // same interface index.
  virtual void SubscribeChannelSwitchEvent(uint32_t interface_index,
                                           OnChannelSwitchEventHandler handler);

  // Cancel the sign-up of receiving channel switch events.
  virtual void UnsubscribeChannelSwitchEvent(uint32_t interface_index);

  // Sign up to be notified of frame tx status events.
  virtual void SubscribeFrameTxStatusEvent(
      uint32_t interface_index, OnFrameTxStatusEventHandler handler);

  // Cancel the sign-up of receiving frame tx status events.
  virtual void UnsubscribeFrameTxStatusEvent(uint32_t interface_index);

  virtual bool SendMgmtFrame(uint32_t interface_index,
    const std::vector<uint8_t>& frame, int32_t mcs, uint64_t* out_cookie);

  // Visible for testing.
  bool supports_split_wiphy_dump_;

 private:
  bool ParseWiphyInfoFromPacket(
      const NL80211Packet& packet,
      BandInfo* out_band_info,
      ScanCapabilities* out_scan_capabilities,
      WiphyFeatures* out_wiphy_features);
  bool ParseBandInfo(const NL80211Packet* const packet,
                     BandInfo* out_band_info);
  void ParseIfTypeDataAttributes(const NL80211NestedAttr& iftype_data_attr,
                                 BandInfo* out_band_info);
  void ParseHtVhtPhyCapabilities(const NL80211NestedAttr& band,
                                 BandInfo* out_band_info);
  void ParseHtMcsSetAttribute(const NL80211NestedAttr& band,
                              BandInfo* out_band_info);
  void ParseVhtMcsSetAttribute(const NL80211NestedAttr& band,
                               BandInfo* out_band_info);
  void ParseHeMcsSetAttribute(const NL80211NestedAttr& attribute,
                              BandInfo* out_band_info);
  std::pair<uint32_t, uint32_t> ParseHtMcsSet(
      const std::vector<uint8_t>& ht_mcs_set);
  uint32_t ParseMcsMap(uint16_t mcs_map);
  void ParseVhtCapAttribute(const NL80211NestedAttr& band,
                            BandInfo* out_band_info);
  void ParseHeCapPhyAttribute(const NL80211NestedAttr& attribute,
                              BandInfo* out_band_info);
  void ParseEhtCapPhyAttribute(const NL80211NestedAttr& attribute,
                              BandInfo* out_band_info);

  bool ParseScanCapabilities(const NL80211Packet* const packet,
                             ScanCapabilities* out_scan_capabilities);

  bool MergePacketsForSplitWiphyDump(
      const std::vector<std::unique_ptr<const NL80211Packet>>& split_dump_info,
      std::vector<NL80211Packet>* packet_per_wiphy);
  void handleBandFreqAttributes(const NL80211NestedAttr& freqs_attr,
      BandInfo* out_band_info);

  NetlinkManager* netlink_manager_;

  DISALLOW_COPY_AND_ASSIGN(NetlinkUtils);
};

}  // namespace wificond
}  // namespace android

#endif  // WIFICOND_NET_NETLINK_UTILS_H_
