// 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 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 platformInstance_ would be initalized in
   *    platformperipheral module.
   * 2) If run test_fan test util, the platformperipheral module won't be used.
   */
  if (platformInstance_ == NULL) {
    /* The global platform instance is not initialized. Let's handle it. */
    LOG(LS_VERBOSE) << "Init platformInstance_ in fancontrol";
    platformInstance_ = new Platform ("Unknown Platform", BRUNO_UNKNOWN,
                                      false, false);
    platformInstance_->Init();
    allocatedPlatformInstanceLocal_ = true;
  }

  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;
  }
  if ((allocatedPlatformInstanceLocal_ == true) && (platformInstance_)) {
    delete platformInstance_;
    platformInstance_ = NULL;
  }
}

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

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

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

  FanControlParams *pfan_ctrl;
  uint8_t idx;
  /* Adjust the fan control parameters for calculation. */
  for (idx = 0, pfan_ctrl = pfan_ctrl_params_; idx <= max; idx++, pfan_ctrl++) {
    LOG(LS_INFO) << platformInstance_->PlatformName()
                 << ((idx == BRUNO_SOC)? "_SOC" : "_HDD") << std::endl
                 << " Tsetpt: "    << pfan_ctrl->temp_setpt << std::endl
                 << " Tmax: "      << pfan_ctrl->temp_max << std::endl
                 << " Tstep: "     << pfan_ctrl->temp_step << std::endl
                 << " Dmin: "      << pfan_ctrl->duty_cycle_min << std::endl
                 << " Dmax: "      << pfan_ctrl->duty_cycle_max << std::endl
                 << " PWMstep: "   << pfan_ctrl->pwm_step << std::endl
                 << " Toverheat: " << pfan_ctrl->temp_overheat << std::endl;
  }
}


bool FanControl::AdjustSpeed(
      uint16_t soc_temp, uint16_t hdd_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 << " 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, 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 (platformInstance_->PlatformHasHdd() == 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;
}


void FanControl::ComputeDutyCycle(
  uint16_t soc_temp,
  uint16_t hdd_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;
  FanControlParams  *psoc = &pfan_ctrl_params_[BRUNO_SOC];
  FanControlParams  *phdd = get_hdd_fan_ctrl_parms();

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

  /* check SOC temps */
  if (psoc) {
    soc_compute_duty_cycle = duty_cycle_pwm_;
    if (soc_temp > psoc->temp_max) {
      soc_compute_duty_cycle = psoc->duty_cycle_max;
    }
    else if (soc_temp > (psoc->temp_setpt + psoc->temp_step)) {
      if (fan_speed == kFanSpeedNotSpinning) {
        soc_compute_duty_cycle = psoc->duty_cycle_min;
      }
      else if (duty_cycle_pwm_ < psoc->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.
         */
        soc_compute_duty_cycle = duty_cycle_pwm_ + psoc->pwm_step;
        if (soc_compute_duty_cycle > psoc->duty_cycle_max)
          soc_compute_duty_cycle = psoc->duty_cycle_max;
      }
    }
    else if (soc_temp < (psoc->temp_setpt - psoc->temp_step)) {
      if ((fan_speed == kFanSpeedNotSpinning) ||
          (duty_cycle_pwm_ < psoc->pwm_step)) {
        soc_compute_duty_cycle = kPwmMinValue;
      }
      else {
        /* Reduce fan pwm if soc_temp is lower than
         * the (temp_setpt - temp_step) and plus fan is still spinning
         */
        soc_compute_duty_cycle = duty_cycle_pwm_ - psoc->pwm_step;
      }
    }
  }

  /* check HDD temps */
  if (phdd) {
    hdd_compute_duty_cycle = duty_cycle_pwm_;
    if (if_hdd_temp_over_temp_max(hdd_temp, phdd) == true) {
      hdd_compute_duty_cycle = phdd->duty_cycle_max;
    }
    else if (if_hdd_temp_over_temp_setpt(hdd_temp, phdd) == true) {
      if (fan_speed == kFanSpeedNotSpinning) {
        hdd_compute_duty_cycle = phdd->duty_cycle_min;
      }
      else if (duty_cycle_pwm_ < phdd->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.
         */
        hdd_compute_duty_cycle = duty_cycle_pwm_ + phdd->pwm_step;
        if (hdd_compute_duty_cycle > phdd->duty_cycle_max)
          hdd_compute_duty_cycle = phdd->duty_cycle_max;
      }
    }
    else if (if_hdd_temp_lower_than_temp_setpt(hdd_temp, phdd) == true) {
      if ((fan_speed == kFanSpeedNotSpinning) ||
          (duty_cycle_pwm_ < phdd->pwm_step)) {
        hdd_compute_duty_cycle = kPwmMinValue;
      }
      else {
        /* Reduce fan pwm if both soc_temp and hdd_temp are lower than
         * their (temp_setpt - temp_step) and plus fan is still spinning
         */
        hdd_compute_duty_cycle = duty_cycle_pwm_ - phdd->pwm_step;
      }
    }
  }

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

  *new_duty_cycle_pwm = MAX(soc_compute_duty_cycle, hdd_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() {
  FanControlParams  *ptr = NULL;
  if (platformInstance_->PlatformHasHdd() == true) {
    ptr = &pfan_ctrl_params_[BRUNO_IS_HDD];
  }
  return ptr;
}


bool FanControl::if_hdd_temp_over_temp_max(const uint16_t hdd_temp, const FanControlParams *phdd) const {
  bool  ret = false;  /* if no hdd params, default is false */
  if ((phdd != NULL) && (hdd_temp > phdd->temp_max)) {
    ret = true;
  }
  return ret;
}


bool FanControl::if_hdd_temp_over_temp_setpt(const uint16_t hdd_temp, const FanControlParams *phdd) const {
  bool  ret = false;  /* if no hdd params, default is false */
  if ((phdd != NULL) && (hdd_temp > (phdd->temp_setpt + phdd->temp_step))) {
    ret = true;
  }
  return ret;
}


bool FanControl::if_hdd_temp_lower_than_temp_setpt(const uint16_t hdd_temp, const FanControlParams *phdd) const {
  bool  ret = true;   /* if no hdd params, default is true */
  if (phdd != NULL) {
    if (hdd_temp < (phdd->temp_setpt - phdd->temp_step)) {
      ret = true;
    }
    else {
      ret = false;
    }
  }
  return ret;
}


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 (platformInstance_->PlatformHasHdd() == 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 = platformInstance_->PlatformName();
  switch (fc_idx) {
    case BRUNO_SOC:
      buf += "_SOC";
      break;
    case BRUNO_IS_HDD:
      buf += "_HDD";
      break;
    default:
      buf += "_UNKNOWN";
      LOG(LS_WARNING) << "Invalid fc_index: " << fc_idx << std::endl;
      break;
  }

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

  std::string result = platformInstance_->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
