// Copyright 2021 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 "shill/wifi/wifi_cqm.h"

#include <fcntl.h>
#include <string>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>

#include "shill/logging.h"
#include "shill/metrics.h"
#include "shill/net/netlink_message.h"
#include "shill/net/nl80211_message.h"
#include "shill/scope_logger.h"
#include "shill/wifi/wifi_service.h"

namespace shill {

namespace Logging {
static auto kModuleLogScope = ScopeLogger::kWiFi;
static std::string ObjectID(const WiFiCQM* w) {
  return "(wifi_cqm)";
}
}  // namespace Logging

namespace {
constexpr int16_t kTriggerFwDumpThresholdDbm = -80;
// Have a large enough time interval to rate limit the number of
// triggered FW dumps from shill.
constexpr auto kFwDumpCoolDownPeriod = base::TimeDelta::FromSeconds(360);
constexpr char kFwDumpIntelSysFs[] =
    "/sys/kernel/debug/ieee80211/phy0/iwlwifi/iwlmvm/fw_dbg_collect";

bool WriteToFwDumpSysPath(const base::FilePath& path) {
  base::ScopedFD fd(HANDLE_EINTR(open(path.value().c_str(), O_WRONLY)));
  if (!fd.is_valid()) {
    LOG(ERROR) << "Failed to open sysfs file"
               << ", " << path.value();
    return false;
  }

  if (!base::WriteFileDescriptor(fd.get(), "1")) {
    LOG(ERROR) << "failed to write to sys fs FW dump file";
    return false;
  }

  return true;
}

// Currently it supports Intel and this will support other chipsets once
// they are enabled.
void SetUpFwDumpPath(base::FilePath* path) {
  if (base::PathExists(base::FilePath(kFwDumpIntelSysFs))) {
    *path = base::FilePath(kFwDumpIntelSysFs);
    return;
  }

  // Path existence check for new chipsets goes here.
}

}  // namespace

// CQM thresholds for RSSI notification and Packet loss is configurable
// in kernel; Currently default kernel CQM thresholds are used.
// TODO(b/197597374) : Feature to configure CQM thresholds.
WiFiCQM::WiFiCQM(Metrics* metrics, WiFi* wifi)
    : wifi_(wifi), metrics_(metrics) {
  CHECK(wifi_) << "Passed wifi object was found null.";
  CHECK(metrics_) << "Passed metrics object was found null.";
  SetUpFwDumpPath(&fw_dump_path_);
  if (fw_dump_path_.empty()) {
    SLOG(this, 3) << "Firmware dump not supported.";
  }
}

WiFiCQM::~WiFiCQM() = default;

void WiFiCQM::TriggerFwDump() {
  if (fw_dump_path_.empty()) {
    SLOG(this, 3) << "FW dump is not supported, cannot trigger FW dump.";
    return;
  }

  auto current = base::Time::NowFromSystemTime();

  if (current < (previous_fw_dump_time_ + kFwDumpCoolDownPeriod) &&
      fw_dump_count_) {
    auto time_left = previous_fw_dump_time_ + kFwDumpCoolDownPeriod - current;
    SLOG(this, 3) << "In FW dump cool down period, no FW dump triggered, "
                  << "Time left (in sec): " << time_left.InSecondsF() << " "
                  << "Cool down period (in sec): "
                  << kFwDumpCoolDownPeriod.InSecondsF();
    return;
  }

  fw_dump_count_++;

  SLOG(this, 3) << "Triggering FW dump.";
  if (WriteToFwDumpSysPath(fw_dump_path_)) {
    SLOG(this, 3) << "FW dump trigger succeeded.";
  }

  previous_fw_dump_time_ = current;
}

void WiFiCQM::OnCQMNotify(const Nl80211Message& nl80211_message) {
  if (nl80211_message.command() != NotifyCqmMessage::kCommand) {
    LOG(ERROR) << __func__
               << ": unexpected command: " << nl80211_message.command_string();
    return;
  }

  AttributeListConstRefPtr cqm_attrs;
  if (!nl80211_message.const_attributes()->ConstGetNestedAttributeList(
          NL80211_ATTR_CQM, &cqm_attrs)) {
    LOG(ERROR) << "Could not find NL80211_ATTR_CQM tag.";
    return;
  }

  // Return after RSSI message is processed. The CQM in kernel is designed to
  // publish one notification type in a given CQM message.
  uint32_t trigger_state;
  if (cqm_attrs->GetU32AttributeValue(NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
                                      &trigger_state)) {
    SLOG(this, 3) << "CQM NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT event found.";
    return;
  }

  // NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT can be used to determine transition
  // to RSSI high or RSSI low conditions. When feature to configure kernel CQM
  // thresholds from Shill is completed, we can use transition to RSSI high and
  // RSSI low conditions to process Beacon/Packet losses.
  // TODO(b/197597374) : Feature to configure CQM thresholds.
  if (wifi_ &&
      wifi_->GetSignalLevelForActiveService() < kTriggerFwDumpThresholdDbm) {
    SLOG(this, 3) << "CQM notification for signal strength less than "
                  << kTriggerFwDumpThresholdDbm << " dBm, Ignore.";
    return;
  }

  uint32_t packet_loss;
  if (cqm_attrs->GetU32AttributeValue(NL80211_ATTR_CQM_PKT_LOSS_EVENT,
                                      &packet_loss)) {
    SLOG(this, 3) << "CQM Packet loss event received, total packet losses: "
                  << packet_loss;
    metrics_->SendEnumToUMA(Metrics::kMetricWiFiCQMNotification,
                            Metrics::kWiFiCQMPacketLoss, Metrics::kWiFiCQMMax);
    TriggerFwDump();
    return;
  }

  bool beacon_flag;
  if (cqm_attrs->GetFlagAttributeValue(NL80211_ATTR_CQM_BEACON_LOSS_EVENT,
                                       &beacon_flag)) {
    SLOG(this, 3) << "CQM notification for Beacon loss observed.";
    metrics_->SendEnumToUMA(Metrics::kMetricWiFiCQMNotification,
                            Metrics::kWiFiCQMBeaconLoss, Metrics::kWiFiCQMMax);
    TriggerFwDump();
    return;
  }
}

}  // namespace shill
