// Copyright 2012 Google Inc. All Rights Reserved.
// Author: kedong@google.com (Ke Dong)

#include "bruno/logging.h"
#include "platform.h"
#include "fancontrol.h"
#include <stdio.h>
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
#include <string.h>
#include <stdint.h>
#include <fstream>
#include <unistd.h>

namespace bruno_platform_peripheral {

#define MAX(a,b)        (((a) > (b) ? (a) : (b)))

#define FAN_CONTROL_PARAMS_FILE   "/user/sysmgr/fan_control_params.tbl"

/* same as lm96063 spinup setting in barebox. */
const unsigned int FanControl::kPwmDefaultStartup = 50;
const unsigned int FanControl::kPwmMinValue = 0;
const unsigned int FanControl::kPwmMaxValue = 100;

const unsigned int FanControl::kFanSpeedNotSpinning = 0;

/*
 * Fan will start and increase speed at temp_setpt + temp_step + 1
 * Fan will start slowing at temp_setpt - temp_step - 1
 * In between, it will not change speed.
 */

/*
 * Defaults of Fan control parameters for GFMS100 (Bruno-IS)
 * For GFMS100, Dmin and PWMsetp are used under FMS100_SOC settings.
 */
const FanControlParams FanControl::kGFMS100FanCtrlSocDefaults = {
                          temp_setpt    : 90,
                          temp_max      : 100,
                          temp_step     : 2,
                          duty_cycle_min: 25,
                          duty_cycle_max: 100,
                          pwm_step      : 1,
                          temp_overheat : 120,
                        };

const FanControlParams FanControl::kGFMS100FanCtrlHddDefaults = {
                          temp_setpt    : 56,
                          temp_max      : 60,
                          temp_step     : 2,
                          duty_cycle_min: 25,
                          duty_cycle_max: 100,
                          pwm_step      : 1,
                          temp_overheat : 120,
                        };

/*
 * Defaults of Fan control parameters for GFRG200/210 (optimus/optimus+hdd)
 * There is no direct SOC temp input, so we use the remote sensor.
 * Mapping between external temp sensor and actual cpu temp was determined
 * exterimentally.  See b/14666398 spreadsheet attachment.
 */
const FanControlParams FanControl::kGFRG200FanCtrlSocDefaults = {
                          temp_setpt    : 82,  // fan on @ 85 (cpu =~ 93)
                          temp_max      : 92,  // cpu =~ 100
                          temp_step     : 2,
                          duty_cycle_min: 30,
                          duty_cycle_max: 100,
                          pwm_step      : 1,
                          temp_overheat : 105,
                        };

const FanControlParams FanControl::kGFRG210FanCtrlSocDefaults = {
                          temp_setpt    : 86,   // fan on @ 89 (cpu =~ 93)
                          temp_max      : 94,   // cpu =~ 100
                          temp_step     : 2,
                          duty_cycle_min: 30,
                          duty_cycle_max: 100,
                          pwm_step      : 1,
                          temp_overheat : 105,
                        };

const FanControlParams FanControl::kGFRG210FanCtrlHddDefaults = {
                          temp_setpt    : 56,
                          temp_max      : 60,
                          temp_step     : 2,
                          duty_cycle_min: 30,
                          duty_cycle_max: 100,
                          pwm_step      : 1,
                          temp_overheat : 105,
                        };
/*
 * Defaults of Fan control parameters for GFRG250 (Optimus Prime)
 * There is no direct SOC temp input, so we use the remote sensor.
 * Thermal policy can be found at b/23119698
 */

const FanControlParams FanControl::kGFRG250FanCtrlSocDefaults = {
                          temp_setpt    : 76,
                          temp_max      : 88,
                          temp_step     : 3,
                          duty_cycle_min: 30,
                          duty_cycle_max: 100,
                          pwm_step      : 2,
                          temp_overheat : 105,
                        };

const FanControlParams FanControl::kGFRG250FanCtrlHddDefaults = {
                          temp_setpt    : 55,
                          temp_max      : 60,
                          temp_step     : 2,
                          duty_cycle_min: 30,
                          duty_cycle_max: 100,
                          pwm_step      : 1,
                          temp_overheat : 105,
                        };

/*
 * On Optimus Prime, AUX1 refers to the temperature sensor in the Quantenna SoC
 * which controls the 11ac wifi interface. The granularity of the temperature
 * readings are very coarse: increments of 5C.
 */
const FanControlParams FanControl::kGFRG250FanCtrlAux1Defaults = {
                          temp_setpt    : 95,
                          temp_max      : 109, /* fan speed is set to max when
                                                  temperatures reaches 110C */
                          temp_step     : 3,
                          duty_cycle_min: 30,
                          duty_cycle_max: 100,
                          pwm_step      : 2,
                          temp_overheat : 120,
                        };

/*
 * Defaults of Fan control parameters for GFSC100 (Spacecast).
 * There is no direct SOC temp input, so we use the remote sensor.
 * Mapping between external temp sensor and actual cpu temp was determined
 * exterimentally.
 */

const FanControlParams FanControl::kGFSC100FanCtrlSocDefaults = {
                          temp_setpt    : 86,   // fan on @ 89 (cpu =~ 93)
                          temp_max      : 94,   // cpu =~ 100
                          temp_step     : 2,
                          duty_cycle_min: 30,
                          duty_cycle_max: 100,
                          pwm_step      : 1,
                          temp_overheat : 105,
                        };

const FanControlParams FanControl::kGFSC100FanCtrlHddDefaults = {
                          temp_setpt    : 56,
                          temp_max      : 60,
                          temp_step     : 2,
                          duty_cycle_min: 30,
                          duty_cycle_max: 100,
                          pwm_step      : 1,
                          temp_overheat : 105,
                        };
/*
 * Defaults of Fan control parameters for GFHD100 (Bruno)
 * the original duty_cycle_min value is set to 25
 * but from the measurement, pwm = 25%, fan duty-cycle
 * (or fan speed) is 45~50%.
 * the original duty_cycle_max value is set to 100
 * but from the measurement, pwm = 40% or above, fan duty-cycle
 * (or fan speed) is 99%. pwm is set to any value greater 40
 * it will only increase fan speed by less than 1%.
 * Therefore Dmax is set to 40.
 */
const FanControlParams FanControl::kGFHD100FanCtrlSocDefaults = {
                          temp_setpt    : 90,
                          temp_max      : 100,
                          temp_step     : 2,
                          duty_cycle_min: 12,
                          duty_cycle_max: 40,
                          pwm_step      : 1,
                          temp_overheat : 120,
                        };

const FanControlParams FanControl::kGFHD200FanCtrlSocDefaults = {
                          temp_setpt    : 0,  /* No fan */
                          temp_max      : 0,
                          temp_step     : 0,
                          duty_cycle_min: 0,
                          duty_cycle_max: 0,
                          pwm_step      : 0,
                          temp_overheat : 120,
                        };

const FanControlParams FanControl::kGFHD254FanCtrlSocDefaults = {
                          temp_setpt    : 88,
                          temp_max      : 105,
                          temp_step     : 3,
                          duty_cycle_min: 25,
                          duty_cycle_max: 100,
                          pwm_step      : 2,
                          temp_overheat : 120,
                        };

const FanControlParams FanControl::kGFLT110FanCtrlSocDefaults = {
                          temp_setpt    : 0,  /* No fan */
                          temp_max      : 0,
                          temp_step     : 0,
                          duty_cycle_min: 0,
                          duty_cycle_max: 0,
                          pwm_step      : 0,
                          temp_overheat : 97,
                        };

FanControl::~FanControl() {
  Terminate();
}

bool FanControl::Init(bool *gpio_mailbox_ready) {

  /* Check if the platform instance has been initialized
   * 1) If run sysmgr,  the platform_ would be initalized in
   *    platformperipheral module.
   * 2) If run test_fan test util, the platformperipheral module won't be used.
   */

  InitParams();

  if (gpio_mailbox_ready != NULL) {
    for (int loopno = 4;
         (*gpio_mailbox_ready == false) && (loopno > 0); loopno--) {
      sleep(2);
      *gpio_mailbox_ready = CheckIfMailBoxIsReady();
      LOG(LS_VERBOSE) << "loopno=" << loopno;
    }
  }

  /* Get the current fan duty cycle */
  if (ReadFanDutyCycle(&duty_cycle_pwm_) == false) {
    LOG(LS_ERROR) << __func__ << ": failed to get fan duty cycle";
    duty_cycle_pwm_ = pfan_ctrl_params_[BRUNO_SOC].duty_cycle_min;
  }
  LOG(LS_VERBOSE) << "duty_cycle_pwm_=" << duty_cycle_pwm_;

  /* Fan pwm has been initialized in nexus init script */
  return true;
}

void FanControl::Terminate(void) {
  if (pfan_ctrl_params_) {
    delete [] pfan_ctrl_params_;
    pfan_ctrl_params_ = NULL;
  }
}

void FanControl::InitParams() {
  pfan_ctrl_params_ = new FanControlParams[BRUNO_PARAMS_TYPES_MAX];

  switch (platform_->PlatformType()) {
    case BRUNO_GFMS100:
      /* Set thermal fan policy parameters of GFMS100 */
      pfan_ctrl_params_[BRUNO_SOC] = kGFMS100FanCtrlSocDefaults;
      pfan_ctrl_params_[BRUNO_IS_HDD] = kGFMS100FanCtrlHddDefaults;
      break;
    case BRUNO_GFHD100:
      /* Set thermal fan policy parameters of GFHD100 */
      pfan_ctrl_params_[BRUNO_SOC] = kGFHD100FanCtrlSocDefaults;
      break;
    case BRUNO_GFHD200:
      pfan_ctrl_params_[BRUNO_SOC] = kGFHD200FanCtrlSocDefaults;
      break;
    case BRUNO_GFHD254:
      pfan_ctrl_params_[BRUNO_SOC] = kGFHD254FanCtrlSocDefaults;
      break;
    case BRUNO_GFRG200:
      /* Set thermal fan policy parameters of GFRG200 */
      pfan_ctrl_params_[BRUNO_SOC] = kGFRG200FanCtrlSocDefaults;
      break;
    case BRUNO_GFRG210:
      /* Set thermal fan policy parameters of GFRG210 */
      pfan_ctrl_params_[BRUNO_SOC] = kGFRG210FanCtrlSocDefaults;
      pfan_ctrl_params_[BRUNO_IS_HDD] = kGFRG210FanCtrlHddDefaults;
      break;
    case BRUNO_GFRG250:
      /* Set thermal fan policy parameters of GFRG250 */
      pfan_ctrl_params_[BRUNO_SOC] = kGFRG250FanCtrlSocDefaults;
      pfan_ctrl_params_[BRUNO_IS_HDD] = kGFRG250FanCtrlHddDefaults;
      pfan_ctrl_params_[BRUNO_AUX1] = kGFRG250FanCtrlAux1Defaults;
      break;
    case BRUNO_GFSC100:
      /* Set thermal fan policy parameters of GFSC100 */
      pfan_ctrl_params_[BRUNO_SOC] = kGFSC100FanCtrlSocDefaults;
      pfan_ctrl_params_[BRUNO_IS_HDD] = kGFSC100FanCtrlHddDefaults;
      break;
    case BRUNO_GFLT110:
      pfan_ctrl_params_[BRUNO_SOC] = kGFLT110FanCtrlSocDefaults;
      break;
    case BRUNO_UNKNOWN:
      LOG(LS_ERROR) << "Invalid platform type, ignore ... " << platform_;
      break;
  }

  /* Check if an external fan control parameter table existing */
  dbgUpdateFanControlParams();

  /* Adjust the fan control parameters for calculation. */
  for (int i = 0; i < BRUNO_PARAMS_TYPES_MAX; i++) {
    const char *suffix;
    switch(i) {
      case BRUNO_SOC:
        suffix = "_SOC";
        break;

      case BRUNO_IS_HDD:
        suffix = "_HDD";
        if (!platform_->has_hdd()) {
          LOG(LS_INFO) << "platform does not have hdd.";
          continue;
        }
        break;

      case BRUNO_AUX1:
        suffix = "_AUX1";
        if (!platform_->has_aux1()) {
          LOG(LS_INFO) << "platform does not have aux1.";
          continue;
        }
        break;

      default:
        suffix = "_UNKNOWN";
        LOG(LS_ERROR) << "Unknown type in fan param array";
        continue;
    }

    LOG(LS_INFO)
        << platform_->PlatformName()
        << suffix << std::endl
        << " Tsetpt: "    << pfan_ctrl_params_[i].temp_setpt << std::endl
        << " Tmax: "      << pfan_ctrl_params_[i].temp_max << std::endl
        << " Tstep: "     << pfan_ctrl_params_[i].temp_step << std::endl
        << " Dmin: "      << pfan_ctrl_params_[i].duty_cycle_min << std::endl
        << " Dmax: "      << pfan_ctrl_params_[i].duty_cycle_max << std::endl
        << " PWMstep: "   << pfan_ctrl_params_[i].pwm_step << std::endl
        << " Toverheat: " << pfan_ctrl_params_[i].temp_overheat << std::endl;
  }
}


bool FanControl::AdjustSpeed(
      uint16_t soc_temp, uint16_t hdd_temp, uint16_t aux1_temp,
      uint16_t fan_speed) {
  bool ret = true;
  uint16_t new_duty_cycle_pwm;

  LOG(LS_VERBOSE) << __func__ << ": soc_temp=" << soc_temp
                  << " hdd_temp=" << hdd_temp << " aux1_temp=" << aux1_temp
                  << " fan_speed=" << fan_speed;

  do {
    /* Get new SOC PWM per the current SOC and HDD temperatures */

    /* Get new duty cycle per SOC and HDD temperatures */
    ComputeDutyCycle(soc_temp, hdd_temp, aux1_temp, fan_speed,
        &new_duty_cycle_pwm);

    LOG(LS_INFO) << __func__ << ": duty_cycle_pwm = " << new_duty_cycle_pwm;
    if (new_duty_cycle_pwm != duty_cycle_pwm_) {
      /* When fan is not spinning and new_duty_cycle_pwm > duty_cycle_pwm_,
       * 1) Set to higher pwm kPwmDefaultStartup for a period of time to
       *    make sure the fan starts spinning
       * 2) then lower down to new_duty_cycle_pwm
       */
      if (fan_speed == kFanSpeedNotSpinning) {
        /* Fan is not rotating */
        if (new_duty_cycle_pwm > duty_cycle_pwm_) {
          LOG(LS_INFO) << "Set higher pwm=" << kPwmDefaultStartup;
          ret = DrivePwm(kPwmDefaultStartup);
          if (!ret) {
            LOG(LS_ERROR) << "DrivePwm failed" << kPwmDefaultStartup;
            break;
          }
          /* Sleep before lower pwm down to new_duty_cycle_pwm */
          sleep(2);
        }
      }

      ret = DrivePwm(new_duty_cycle_pwm);
      if (!ret) {
        LOG(LS_ERROR) << "DrivePwm failed";
        break;
      }
    }

  } while (false);

  return ret;
}

void FanControl::GetOverheatTemperature(uint16_t *poverheat_temp) {
  FanControlParams  *psoc = &pfan_ctrl_params_[BRUNO_SOC];
  *poverheat_temp = psoc->temp_overheat;
  return;
}

void FanControl::GetHddTemperature(uint16_t *phdd_temp) {
  *phdd_temp = 0;
  uint16_t hdd_temp;

  if (platform_->has_hdd() == true) {
    std::string buf = "hdd-temperature /dev/sda";
    /* Create vector to hold hdd temperature words */
    std::vector<std::string> tokens;

    /* Insert the HDD temperature string into a stream */
    std::string result = ExecCmd((char *)buf.c_str(), NULL);
    if ((result == "ERROR") || (result.empty() == true)) {
      /* Failed to get HDD temperature. Exit */
      LOG(LS_ERROR) << "GetHddTemperature: Can't get HDD temperature";
      return;
    }
    std::istringstream(result) >> hdd_temp;
    /* LOG(LS_INFO) << "hdd_temp: " << hdd_temp << std::endl; */
    *phdd_temp = hdd_temp;
  }
  return;
}

bool FanControl::DrivePwm(uint16_t duty_cycle) {

  LOG(LS_INFO) << "DrivePwm = " << duty_cycle;
  duty_cycle_pwm_ = duty_cycle;

  if (WriteFanDutyCycle(duty_cycle) == false) {
    LOG(LS_ERROR) << "WriteFanDutyCycle failed";
    return false;
  }

  if (duty_cycle == 0) {
    state_ = OFF;
  } else if (duty_cycle == period_+1) {
    state_ = FULL_SPEED;
  } else {
    state_ = VAR_SPEED;
  }

  return true;
}

uint16_t FanControl::__ComputeDutyCycle(
  uint16_t temp,
  uint16_t fan_speed,
  const FanControlParams &params) {

  uint16_t  compute_duty_cycle = duty_cycle_pwm_;
  if (temp > params.temp_max) {
    compute_duty_cycle = params.duty_cycle_max;
  }
  else if (temp > (params.temp_setpt + params.temp_step)) {
    if (fan_speed == kFanSpeedNotSpinning) {
      compute_duty_cycle = params.duty_cycle_min;
    }
    else if (duty_cycle_pwm_ < params.duty_cycle_max) {
      /* 1. Possibly, the fan still stops due to duty_cycle_pwm_ is not large
       *    enough. Continue increase the duty cycle.
       * 2. Or the fan is running, but it's not fast enough to cool down
       *    the unit.
       */
      compute_duty_cycle = duty_cycle_pwm_ + params.pwm_step;
      if (compute_duty_cycle > params.duty_cycle_max)
        compute_duty_cycle = params.duty_cycle_max;
    }
  }
  else if (temp < (params.temp_setpt - params.temp_step)) {
    if ((fan_speed == kFanSpeedNotSpinning) ||
        (duty_cycle_pwm_ < params.pwm_step)) {
      compute_duty_cycle = kPwmMinValue;
    }
    else {
      /* Reduce fan pwm if temp is lower than
       * the (temp_setpt - temp_step) and plus fan is still spinning
       */
      compute_duty_cycle = duty_cycle_pwm_ - params.pwm_step;
    }
  }
  return compute_duty_cycle;
}

void FanControl::ComputeDutyCycle(
  uint16_t soc_temp,
  uint16_t hdd_temp,
  uint16_t aux1_temp,
  uint16_t fan_speed,
  uint16_t *new_duty_cycle_pwm) {

  uint16_t  soc_compute_duty_cycle = 0;
  uint16_t  hdd_compute_duty_cycle = 0;
  uint16_t  aux1_compute_duty_cycle = 0;
  FanControlParams  *psoc = &pfan_ctrl_params_[BRUNO_SOC];
  FanControlParams  *phdd = get_hdd_fan_ctrl_parms();
  FanControlParams  *paux1 = get_aux1_fan_ctrl_parms();

  LOG(LS_VERBOSE) << __func__ << " - duty_cycle_pwm_ = " << duty_cycle_pwm_
               << " i/p soc_temp=" << soc_temp
               << " hdd_temp="     << hdd_temp
               << " aux1_temp="    << aux1_temp
               << " fan_speed="    << fan_speed;

  /* check SOC temps */
  if (psoc) {
    soc_compute_duty_cycle = __ComputeDutyCycle(soc_temp, fan_speed, *psoc);
  }

  /* check HDD temps */
  if (phdd) {
    hdd_compute_duty_cycle = __ComputeDutyCycle(hdd_temp, fan_speed, *phdd);
  }

  /* check HDD temps */
  if (paux1) {
    aux1_compute_duty_cycle = __ComputeDutyCycle(aux1_temp, fan_speed, *paux1);
  }

  LOG(LS_INFO) << "soc_duty_cycle_pwm = " << soc_compute_duty_cycle << " "
               << "hdd_duty_cycle_pwm = " << hdd_compute_duty_cycle << " "
               << "aux1_duty_cycle_pwm = " << aux1_compute_duty_cycle;

  *new_duty_cycle_pwm = MAX(soc_compute_duty_cycle, hdd_compute_duty_cycle);
  *new_duty_cycle_pwm = MAX(*new_duty_cycle_pwm, aux1_compute_duty_cycle);

  LOG(LS_INFO) << "new_duty_cycle_pwm = " << *new_duty_cycle_pwm;

  return;
}


std::string FanControl::ExecCmd(char* cmd, std::string *pattern) {
  char buffer[256];
  std::string result = "";
  FILE* pipe = popen(cmd, "r");

  if (!pipe) {
    LOG(LS_ERROR) << __func__ << ": ERROR";
    return "ERROR";
  }

  while(!feof(pipe)) {
    if(fgets(buffer, sizeof(buffer), pipe) != NULL) {
      /* pattern == NULL, read and return all of lines
       * pattern != NULL, return the line if found the pattern in the line
       */
      if (pattern != NULL) {
        result = buffer;
        if (result.compare(0, pattern->size(), *pattern) == 0) {
          break;      /* Found the pattern. Exit. */
        }
        result.clear();
      }
      else {
        result += buffer;
      }
    }
  }
  pclose(pipe);

  return result;
}

FanControlParams *FanControl::get_hdd_fan_ctrl_parms() {
  if (platform_->has_hdd() == true) {
    return &pfan_ctrl_params_[BRUNO_IS_HDD];
  }
  return NULL;
}

FanControlParams *FanControl::get_aux1_fan_ctrl_parms() {
  if (platform_->has_aux1() == true) {
    return &pfan_ctrl_params_[BRUNO_AUX1];
  }
  return NULL;
}


void FanControl::dbgUpdateFanControlParams(void) {
  /* Check if the external fan control parameter table existing */
  std::ifstream params_table_file (FAN_CONTROL_PARAMS_FILE);
  if (params_table_file.is_open()) {
    LOG(LS_INFO) << FAN_CONTROL_PARAMS_FILE << " existing...";
    dbgGetFanControlParamsFromParamsFile(BRUNO_SOC);
    if (platform_->has_hdd() == true) {
      dbgGetFanControlParamsFromParamsFile(BRUNO_IS_HDD);
    }
  }
}

/* A debugging function: Allow hardware engineers to tune the fan
 * control parameters
 */
bool FanControl::dbgGetFanControlParamsFromParamsFile(uint8_t fc_idx) {
  /* Create vector to hold hdd temperature words */
  std::vector<std::string> tokens;
  uint16_t max, min;

  /* TODO - Use protobuf to parse the fan control parameters. */

  /* Get the search platform keyword in the table file: GFMS100_SOC,
   * GFMS100_HDD...
   */
  std::string buf = platform_->PlatformName();
  switch (fc_idx) {
    case BRUNO_SOC:
      buf += "_SOC";
      break;
    case BRUNO_IS_HDD:
      buf += "_HDD";
      break;
    case BRUNO_AUX1:
      buf += "_AUX1";
      break;
    default:
      buf += "_UNKNOWN";
      LOG(LS_WARNING) << "Invalid fc_index: " << fc_idx << std::endl;
      break;
  }

  LOG(LS_INFO) << buf << std::endl;

  std::string result = platform_->GetLine((char *)FAN_CONTROL_PARAMS_FILE, &buf);
  if (result.empty() == true)
    return false;

  /* Insert the fan control parameters string into a stream */
  std::stringstream ss(result);
  while (ss >> buf) {
    tokens.push_back(buf);
  }

  /* LOG(LS_INFO) << "token.size = " << tokens.size() << std::endl; */

  /* Each line in the fan control table must have 7 elements */
  if (tokens.size() < 7) {
    LOG(LS_ERROR) << __func__ << "Incorrect number of params -->" << tokens.size() ;
    return false;       /* Incorrect length. Exit. */
  }

  /* Compare Tsetpt and Tmax */
  std::istringstream(tokens.at(1)) >> min;
  std::istringstream(tokens.at(2)) >> max;
  if (min > max) {
    LOG(LS_ERROR) << __func__ << "Incorrect Tsettp: " << min << " and Tmax: " << max;
    return false;   /* Invalid. Exit */
  }

  std::istringstream(tokens.at(4)) >> min;
  std::istringstream(tokens.at(5)) >> max;
  if (min > max) {
    LOG(LS_ERROR) << __func__ << "Dmin: " << min << " and Dmax: " << max;
    return false;   /* Invalid. Exit */
  }

  std::istringstream(tokens.at(1)) >> pfan_ctrl_params_[fc_idx].temp_setpt;
  std::istringstream(tokens.at(2)) >> pfan_ctrl_params_[fc_idx].temp_max;
  std::istringstream(tokens.at(3)) >> pfan_ctrl_params_[fc_idx].temp_step;
  std::istringstream(tokens.at(4)) >> pfan_ctrl_params_[fc_idx].duty_cycle_min;
  std::istringstream(tokens.at(5)) >> pfan_ctrl_params_[fc_idx].duty_cycle_max;
  std::istringstream(tokens.at(6)) >> pfan_ctrl_params_[fc_idx].pwm_step;
  return true;
}

}  // namespace bruno_platform_peripheral
