// Copyright 2014 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "apmanager/device.h"

#include <base/strings/stringprintf.h>
#include <brillo/strings/string_utils.h>
#include <shill/net/attribute_list.h>
#include <shill/net/ieee80211.h>

#include "apmanager/config.h"
#include "apmanager/control_interface.h"
#include "apmanager/manager.h"

using shill::ByteString;
using std::string;

namespace apmanager {

Device::Device(Manager* manager,
               const string& device_name,
               int identifier)
    : manager_(manager),
      supports_ap_mode_(false),
      identifier_(identifier),
      adaptor_(manager->control_interface()->CreateDeviceAdaptor(this)) {
  SetDeviceName(device_name);
  SetInUse(false);
}

Device::~Device() {}

void Device::RegisterInterface(const WiFiInterface& new_interface) {
  LOG(INFO) << "RegisteringInterface " << new_interface.iface_name
            << " on device " << GetDeviceName();
  for (const auto& interface : interface_list_) {
    // Done if interface already in the list.
    if (interface.iface_index == new_interface.iface_index) {
      LOG(INFO) << "Interface " << new_interface.iface_name
                << " already registered.";
      return;
    }
  }
  interface_list_.push_back(new_interface);
  UpdatePreferredAPInterface();
}

void Device::DeregisterInterface(const WiFiInterface& interface) {
  LOG(INFO) << "DeregisteringInterface " << interface.iface_name
            << " on device " << GetDeviceName();
  for (auto it = interface_list_.begin(); it != interface_list_.end(); ++it) {
    if (it->iface_index == interface.iface_index) {
      interface_list_.erase(it);
      UpdatePreferredAPInterface();
      return;
    }
  }
}

void Device::ParseWiphyCapability(const shill::Nl80211Message& msg) {
  // Parse NL80211_ATTR_SUPPORTED_IFTYPES for AP mode interface support.
  shill::AttributeListConstRefPtr supported_iftypes;
  if (!msg.const_attributes()->ConstGetNestedAttributeList(
      NL80211_ATTR_SUPPORTED_IFTYPES, &supported_iftypes)) {
    LOG(ERROR) << "NL80211_CMD_NEW_WIPHY had no NL80211_ATTR_SUPPORTED_IFTYPES";
    return;
  }
  supported_iftypes->GetFlagAttributeValue(NL80211_IFTYPE_AP,
                                           &supports_ap_mode_);

  // Parse WiFi band capabilities.
  shill::AttributeListConstRefPtr wiphy_bands;
  if (!msg.const_attributes()->ConstGetNestedAttributeList(
      NL80211_ATTR_WIPHY_BANDS, &wiphy_bands)) {
    LOG(ERROR) << "NL80211_CMD_NEW_WIPHY had no NL80211_ATTR_WIPHY_BANDS";
    return;
  }

  shill::AttributeIdIterator band_iter(*wiphy_bands);
  for (; !band_iter.AtEnd(); band_iter.Advance()) {
    BandCapability band_cap;

    shill::AttributeListConstRefPtr wiphy_band;
    if (!wiphy_bands->ConstGetNestedAttributeList(band_iter.GetId(),
                                                  &wiphy_band)) {
      LOG(WARNING) << "WiFi band " << band_iter.GetId() << " not found";
      continue;
    }

    // ...Each band has a FREQS attribute...
    shill::AttributeListConstRefPtr frequencies;
    if (!wiphy_band->ConstGetNestedAttributeList(NL80211_BAND_ATTR_FREQS,
                                                 &frequencies)) {
      LOG(ERROR) << "BAND " << band_iter.GetId()
                 << " had no 'frequencies' attribute";
      continue;
    }

    // ...And each FREQS attribute contains an array of information about the
    // frequency...
    shill::AttributeIdIterator freq_iter(*frequencies);
    for (; !freq_iter.AtEnd(); freq_iter.Advance()) {
      shill::AttributeListConstRefPtr frequency;
      if (frequencies->ConstGetNestedAttributeList(freq_iter.GetId(),
                                                   &frequency)) {
        // ...Including the frequency, itself (the part we want).
        uint32_t frequency_value = 0;
        if (frequency->GetU32AttributeValue(NL80211_FREQUENCY_ATTR_FREQ,
                                            &frequency_value)) {
          band_cap.frequencies.push_back(frequency_value);
        }
      }
    }

    wiphy_band->GetU16AttributeValue(NL80211_BAND_ATTR_HT_CAPA,
                                     &band_cap.ht_capability_mask);
    wiphy_band->GetU16AttributeValue(NL80211_BAND_ATTR_VHT_CAPA,
                                     &band_cap.vht_capability_mask);
    band_capability_.push_back(band_cap);
  }
}

bool Device::ClaimDevice(bool full_control) {
  if (GetInUse()) {
    LOG(ERROR) << "Failed to claim device [" << GetDeviceName()
               << "]: already in used.";
    return false;
  }

  if (full_control) {
    for (const auto& interface : interface_list_) {
      manager_->ClaimInterface(interface.iface_name);
      claimed_interfaces_.insert(interface.iface_name);
    }
  } else {
    manager_->ClaimInterface(GetPreferredApInterface());
    claimed_interfaces_.insert(GetPreferredApInterface());
  }
  SetInUse(true);
  return true;
}

bool Device::ReleaseDevice() {
  if (!GetInUse()) {
    LOG(ERROR) << "Failed to release device [" << GetDeviceName()
               << "]: not currently in-used.";
    return false;
  }

  for (const auto& interface : claimed_interfaces_) {
    manager_->ReleaseInterface(interface);
  }
  claimed_interfaces_.clear();
  SetInUse(false);
  return true;
}

bool Device::InterfaceExists(const string& interface_name) {
  for (const auto& interface : interface_list_) {
    if (interface.iface_name == interface_name) {
      return true;
    }
  }
  return false;
}

bool Device::GetHTCapability(uint16_t channel, string* ht_cap) {
  // Get the band capability based on the channel.
  BandCapability band_cap;
  if (!GetBandCapability(channel, &band_cap)) {
    LOG(ERROR) << "No band capability found for channel " << channel;
    return false;
  }

  std::vector<string> ht_capability;
  // LDPC coding capability.
  if (band_cap.ht_capability_mask & shill::IEEE_80211::kHTCapMaskLdpcCoding) {
    ht_capability.push_back("LDPC");
  }

  // Supported channel width set.
  if (band_cap.ht_capability_mask &
      shill::IEEE_80211::kHTCapMaskSupWidth2040) {
    // Determine secondary channel is below or above the primary.
    bool above = false;
    if (!GetHTSecondaryChannelLocation(channel, &above)) {
      LOG(ERROR) << "Unable to determine secondary channel location for "
                 << "channel " << channel;
      return false;
    }
    if (above) {
      ht_capability.push_back("HT40+");
    } else {
      ht_capability.push_back("HT40-");
    }
  }

  // Spatial Multiplexing (SM) Power Save.
  uint16_t power_save_mask =
      (band_cap.ht_capability_mask >>
          shill::IEEE_80211::kHTCapMaskSmPsShift) & 0x3;
  if (power_save_mask == 0) {
    ht_capability.push_back("SMPS-STATIC");
  } else if (power_save_mask == 1) {
    ht_capability.push_back("SMPS-DYNAMIC");
  }

  // HT-greenfield.
  if (band_cap.ht_capability_mask & shill::IEEE_80211::kHTCapMaskGrnFld) {
    ht_capability.push_back("GF");
  }

  // Short GI for 20 MHz.
  if (band_cap.ht_capability_mask & shill::IEEE_80211::kHTCapMaskSgi20) {
    ht_capability.push_back("SHORT-GI-20");
  }

  // Short GI for 40 MHz.
  if (band_cap.ht_capability_mask & shill::IEEE_80211::kHTCapMaskSgi40) {
    ht_capability.push_back("SHORT-GI-40");
  }

  // Tx STBC.
  if (band_cap.ht_capability_mask & shill::IEEE_80211::kHTCapMaskTxStbc) {
    ht_capability.push_back("TX-STBC");
  }

  // Rx STBC.
  uint16_t rx_stbc =
      (band_cap.ht_capability_mask >>
          shill::IEEE_80211::kHTCapMaskRxStbcShift) & 0x3;
  if (rx_stbc == 1) {
    ht_capability.push_back("RX-STBC1");
  } else if (rx_stbc == 2) {
    ht_capability.push_back("RX-STBC12");
  } else if (rx_stbc == 3) {
    ht_capability.push_back("RX-STBC123");
  }

  // HT-delayed Block Ack.
  if (band_cap.ht_capability_mask & shill::IEEE_80211::kHTCapMaskDelayBA) {
    ht_capability.push_back("DELAYED-BA");
  }

  // Maximum A-MSDU length.
  if (band_cap.ht_capability_mask & shill::IEEE_80211::kHTCapMaskMaxAmsdu) {
    ht_capability.push_back("MAX-AMSDU-7935");
  }

  // DSSS/CCK Mode in 40 MHz.
  if (band_cap.ht_capability_mask & shill::IEEE_80211::kHTCapMaskDsssCck40) {
    ht_capability.push_back("DSSS_CCK-40");
  }

  // 40 MHz intolerant.
  if (band_cap.ht_capability_mask &
      shill::IEEE_80211::kHTCapMask40MHzIntolerant) {
    ht_capability.push_back("40-INTOLERANT");
  }

  *ht_cap = base::StringPrintf("[%s]",
      brillo::string_utils::Join(" ", ht_capability).c_str());
  return true;
}

bool Device::GetVHTCapability(uint16_t channel, string* vht_cap) {
  // TODO(zqiu): to be implemented.
  return false;
}

void Device::SetDeviceName(const std::string& device_name) {
  adaptor_->SetDeviceName(device_name);
}

string Device::GetDeviceName() const {
  return adaptor_->GetDeviceName();
}

void Device::SetPreferredApInterface(const std::string& interface_name) {
  adaptor_->SetPreferredApInterface(interface_name);
}

string Device::GetPreferredApInterface() const {
  return adaptor_->GetPreferredApInterface();
}

void Device::SetInUse(bool in_use) {
  return adaptor_->SetInUse(in_use);
}

bool Device::GetInUse() const {
  return adaptor_->GetInUse();
}

// static
bool Device::GetHTSecondaryChannelLocation(uint16_t channel, bool* above) {
  bool ret_val = true;

  // Determine secondary channel location base on the channel. Refer to
  // ht_cap section in hostapd.conf documentation.
  switch (channel) {
    case 7:
    case 8:
    case 9:
    case 10:
    case 11:
    case 12:
    case 13:
    case 40:
    case 48:
    case 56:
    case 64:
      *above = false;
      break;

    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 36:
    case 44:
    case 52:
    case 60:
      *above = true;
      break;

    default:
      ret_val = false;
      break;
  }

  return ret_val;
}

bool Device::GetBandCapability(uint16_t channel, BandCapability* capability) {
  uint32_t frequency;
  if (!Config::GetFrequencyFromChannel(channel, &frequency)) {
    LOG(ERROR) << "Invalid channel " << channel;
    return false;
  }

  for (const auto& band : band_capability_) {
    if (std::find(band.frequencies.begin(),
                  band.frequencies.end(),
                  frequency) != band.frequencies.end()) {
      *capability = band;
      return true;
    }
  }
  return false;
}

void Device::UpdatePreferredAPInterface() {
  // Return if device doesn't support AP interface mode.
  if (!supports_ap_mode_) {
    return;
  }

  // Use the first registered AP mode interface if there is one, otherwise use
  // the first registered managed mode interface. If none are available, then
  // no interface can be used for AP operation on this device.
  WiFiInterface preferred_interface;
  for (const auto& interface : interface_list_) {
    if (interface.iface_type == NL80211_IFTYPE_AP) {
      preferred_interface = interface;
      break;
    } else if (interface.iface_type == NL80211_IFTYPE_STATION &&
               preferred_interface.iface_name.empty()) {
      preferred_interface = interface;
    }
    // Ignore all other interface types.
  }
  // Update preferred AP interface property.
  SetPreferredApInterface(preferred_interface.iface_name);
}

}  // namespace apmanager
