/*
 * Copyright 2012-2019, 2022-2023 NXP
 *
 * 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.
 */
#include <string.h>
#include <sys/stat.h>

#include <atomic>
#include <bitset>
#include <map>
#include <vector>

#include <cutils/properties.h>

#include "phNxpConfig.h"
#include "phNxpLog.h"
#include "phNxpUciHal.h"
#include "phNxpUciHal_ext.h"
#include "phNxpUciHal_utils.h"
#include "phTmlUwb.h"
#include "phUwbCommon.h"
#include "sessionTrack.h"

/* Timeout value to wait for response from DEVICE_TYPE_SR1xx */
#define MAX_COMMAND_RETRY_COUNT           5
#define HAL_EXTNS_WRITE_RSP_TIMEOUT_MS    100
#define HAL_HW_RESET_NTF_TIMEOUT          10000 /* 10 sec wait */

/******************* Global variables *****************************************/
extern phNxpUciHal_Control_t nxpucihal_ctrl;

static std::vector<uint8_t> gtx_power;

/************** HAL extension functions ***************************************/
static bool phNxpUciHal_is_retry_not_required(uint8_t uci_octet0);
static void phNxpUciHal_clear_thermal_error_status();
static void phNxpUciHal_hw_reset_ntf_timeout_cb(uint32_t timerId,
                                                void *pContext);

/******************************************************************************
 * Function         phNxpUciHal_process_ext_cmd_rsp
 *
 * Description      This function process the extension command response. It
 *                  also checks the received response to expected response.
 *
 * Returns          returns UWBSTATUS_SUCCESS if response is as expected else
 *                  returns failure.
 *
 ******************************************************************************/
tHAL_UWB_STATUS phNxpUciHal_process_ext_cmd_rsp(size_t cmd_len,
                                                const uint8_t *p_cmd) {
  if (cmd_len > sizeof(nxpucihal_ctrl.p_cmd_data)) {
    NXPLOG_UCIHAL_E("Packet size is too big to send: %u.", cmd_len);
    return UWBSTATUS_FAILED;
  }
  if (cmd_len < 1) {
    return UWBSTATUS_FAILED;
  }

  /* Create local copy of cmd_data */
  memcpy(nxpucihal_ctrl.p_cmd_data, p_cmd, cmd_len);
  nxpucihal_ctrl.cmd_len = cmd_len;

  // PBF=1 or DATA packet: don't check RSP
  // upper-layer should handle the case of UWBSTATUS_COMMAND_RETRANSMIT && isRetryNotRequired
  if (phNxpUciHal_is_retry_not_required(p_cmd[0]) ||
      cmd_len < UCI_MSG_HDR_SIZE) {
    return phNxpUciHal_write_unlocked();
  }

  const uint8_t mt = (p_cmd[0] & UCI_MT_MASK) >> UCI_MT_SHIFT;
  const uint8_t gid = p_cmd[0] & UCI_GID_MASK;
  const uint8_t oid = p_cmd[1] & UCI_OID_MASK;

  if (mt == UCI_MT_CMD && gid == UCI_GID_SESSION_CONTROL && oid == UCI_MSG_SESSION_START) {
    SessionTrack_onSessionStart(cmd_len, p_cmd);
  }

  /* Vendor Specific Parsing logic */
  if (phNxpUciHal_parse(nxpucihal_ctrl.cmd_len, nxpucihal_ctrl.p_cmd_data)) {
    return UWBSTATUS_SUCCESS;
  }

  tHAL_UWB_STATUS status = UWBSTATUS_FAILED;
  int nr_retries = 0;
  int nr_timedout = 0;

  while(nr_retries < MAX_COMMAND_RETRY_COUNT) {
    nxpucihal_ctrl.cmdrsp.StartCmd(gid, oid);
    status = phNxpUciHal_write_unlocked();

    if (status != UWBSTATUS_SUCCESS) {
      NXPLOG_UCIHAL_D("phNxpUciHal_write failed for hal ext");
      nxpucihal_ctrl.cmdrsp.Cancel();
      return status;
    }

    // Wait for rsp
    status = nxpucihal_ctrl.cmdrsp.Wait(HAL_EXTNS_WRITE_RSP_TIMEOUT_MS);

    if (status == UWBSTATUS_RESPONSE_TIMEOUT) {
      nr_timedout++;
      nr_retries++;
    } else if (status == UWBSTATUS_COMMAND_RETRANSMIT) {
      // TODO: Do not retransmit CMD by here when !nxpucihal_ctrl.hal_ext_enabled,
      // Upper layer should take care of it.
      nr_retries++;
    } else {
      break;
    }
  }

  if (nr_retries >= MAX_COMMAND_RETRY_COUNT) {
    NXPLOG_UCIHAL_E("Failed to process cmd/rsp 0x%x", status);
    phNxpUciHal_send_dev_error_status_ntf();
    return UWBSTATUS_FAILED;
  }

  if (nr_timedout > 0) {
    NXPLOG_UCIHAL_E("Warning: CMD/RSP retried %d times (timeout:%d)\n",
                    nr_retries, nr_timedout);
  }

  return status;
}

/******************************************************************************
 * Function         phNxpUciHal_send_ext_cmd
 *
 * Description      This function send the extension command to UWBC. No
 *                  response is checked by this function but it waits for
 *                  the response to come.
 *
 * Returns          Returns UWBSTATUS_SUCCESS if sending cmd is successful and
 *                  response is received.
 *
 ******************************************************************************/
tHAL_UWB_STATUS phNxpUciHal_send_ext_cmd(uint16_t cmd_len, const uint8_t* p_cmd) {
  if (cmd_len >= UCI_MAX_DATA_LEN) {
    return UWBSTATUS_FAILED;
  }

  HAL_ENABLE_EXT();
  tHAL_UWB_STATUS status = phNxpUciHal_process_ext_cmd_rsp(cmd_len, p_cmd);
  HAL_DISABLE_EXT();

  return status;
}

/******************************************************************************
 * Function         phNxpUciHal_set_board_config
 *
 * Description      This function is called to set the board varaint config
 * Returns          return 0 on success and -1 on fail, On success
 *                  update the acutual state of operation in arg pointer
 *
 ******************************************************************************/
tHAL_UWB_STATUS phNxpUciHal_set_board_config(){
  tHAL_UWB_STATUS status;
  uint8_t buffer[] = {0x2E,0x00,0x00,0x02,0x01,0x01};
  /* Set the board variant configurations */
  unsigned long num = 0;
  NXPLOG_UCIHAL_D("%s: enter; ", __func__);
  uint8_t boardConfig = 0, boardVersion = 0;

  if(NxpConfig_GetNum(NAME_UWB_BOARD_VARIANT_CONFIG, &num, sizeof(num))){
    boardConfig = (uint8_t)num;
    NXPLOG_UCIHAL_D("%s: NAME_UWB_BOARD_VARIANT_CONFIG: %x", __func__,boardConfig);
  } else {
    NXPLOG_UCIHAL_D("%s: NAME_UWB_BOARD_VARIANT_CONFIG: failed %x", __func__,boardConfig);
  }
  if(NxpConfig_GetNum(NAME_UWB_BOARD_VARIANT_VERSION, &num, sizeof(num))){
    boardVersion = (uint8_t)num;
    NXPLOG_UCIHAL_D("%s: NAME_UWB_BOARD_VARIANT_VERSION: %x", __func__,boardVersion);
  } else{
    NXPLOG_UCIHAL_D("%s: NAME_UWB_BOARD_VARIANT_VERSION: failed %lx", __func__,num);
  }
  buffer[4] = boardConfig;
  buffer[5] = boardVersion;

  status = phNxpUciHal_send_ext_cmd(sizeof(buffer), buffer);

  return status;
}

/*******************************************************************************
**
** Function         phNxpUciHal_process_ext_rsp
**
** Description      Process extension function response
**
** Returns          UWBSTATUS_SUCCESS if success
**
*******************************************************************************/
tHAL_UWB_STATUS phNxpUciHal_process_ext_rsp(uint16_t rsp_len, uint8_t* p_buff){
  tHAL_UWB_STATUS status;
  int NumOfTlv, index;
  uint8_t paramId, extParamId, IdStatus;
  index = UCI_NTF_PAYLOAD_OFFSET; // index for payload start
  status = p_buff[index++];
  if(status  == UCI_STATUS_OK){
    NXPLOG_UCIHAL_D("%s: status success %d", __func__, status);
    return UWBSTATUS_SUCCESS;
  }
  NumOfTlv = p_buff[index++];
  while (index < rsp_len) {
      paramId = p_buff[index++];
      if(paramId == EXTENDED_DEVICE_CONFIG_ID) {
        extParamId = p_buff[index++];
        IdStatus = p_buff[index++];

        switch(extParamId) {
          case UCI_EXT_PARAM_DELAY_CALIBRATION_VALUE:
          case UCI_EXT_PARAM_AOA_CALIBRATION_CTRL:
          case UCI_EXT_PARAM_DPD_WAKEUP_SRC:
          case UCI_EXT_PARAM_WTX_COUNT_CONFIG:
          case UCI_EXT_PARAM_DPD_ENTRY_TIMEOUT:
          case UCI_EXT_PARAM_WIFI_COEX_FEATURE:
          case UCI_EXT_PARAM_TX_BASE_BAND_CONFIG:
          case UCI_EXT_PARAM_DDFS_TONE_CONFIG:
          case UCI_EXT_PARAM_TX_PULSE_SHAPE_CONFIG:
          case UCI_EXT_PARAM_CLK_CONFIG_CTRL:
            if(IdStatus == UCI_STATUS_FEATURE_NOT_SUPPORTED){
              NXPLOG_UCIHAL_E("%s: Vendor config param: %x %x is Not Supported", __func__, paramId, extParamId);
              status = UWBSTATUS_SUCCESS;
            } else {
              status = UWBSTATUS_FAILED;
              return status;
            }
            break;
          default:
            NXPLOG_UCIHAL_D("%s: Vendor param ID: %x", __func__, extParamId);
            break;
        }
      } else {
        IdStatus = p_buff[index++];
        switch(paramId) {
          case UCI_PARAM_ID_LOW_POWER_MODE:
            if(IdStatus == UCI_STATUS_FEATURE_NOT_SUPPORTED){
              NXPLOG_UCIHAL_E("%s: Generic config param: %x is Not Supported", __func__, paramId);
              status = UWBSTATUS_SUCCESS;
            } else {
              status = UWBSTATUS_FAILED;
              return status;
            }
            break;
          default:
            NXPLOG_UCIHAL_D("%s: Generic param ID: %x", __func__, paramId);
            break;
        }
      }
    }
 NXPLOG_UCIHAL_D("%s: exit %d", __func__, status);
 return status;
}

/*******************************************************************************
 * Function      phNxpUciHal_resetRuntimeSettings
 *
 * Description   reset per-country code settigs to default
 *
 *******************************************************************************/
static void phNxpUciHal_resetRuntimeSettings(void)
{
  phNxpUciHal_Runtime_Settings_t *rt_set = &nxpucihal_ctrl.rt_settings;
  rt_set->uwb_enable = true;
  rt_set->restricted_channel_mask = 0;
  rt_set->tx_power_offset = 0;
}

/*******************************************************************************
 * Function      phNxpUciHal_applyCountryCaps
 *
 * Description   Update runtime settings with given COUNTRY_CODE_CAPS byte array
 *
 * Returns       void
 *
 *******************************************************************************/
static void phNxpUciHal_applyCountryCaps(const char country_code[2],
    const uint8_t *cc_resp, uint32_t cc_resp_len)
{
  phNxpUciHal_Runtime_Settings_t *rt_set = &nxpucihal_ctrl.rt_settings;

  uint16_t idx = 1; // first byte = number countries
  bool country_code_found = false;

  while (idx < cc_resp_len) {
    uint8_t tag = cc_resp[idx++];
    uint8_t len = cc_resp[idx++];

    if (country_code_found) {
      switch (tag) {
      case UWB_ENABLE_TAG:
        if (len == 1) {
          rt_set->uwb_enable = cc_resp[idx];
          NXPLOG_UCIHAL_D("CountryCaps uwb_enable = %u", cc_resp[idx]);
        }
        break;
      case CHANNEL_5_TAG:
        if (len == 1 && !cc_resp[idx]) {
          rt_set->restricted_channel_mask |= 1<< 5;
          NXPLOG_UCIHAL_D("CountryCaps channel 5 support = %u", cc_resp[idx]);
        }
        break;
      case CHANNEL_9_TAG:
        if (len == 1 && !cc_resp[idx]) {
          rt_set->restricted_channel_mask |= 1<< 9;
          NXPLOG_UCIHAL_D("CountryCaps channel 9 support = %u", cc_resp[idx]);
        }
        break;
      case TX_POWER_TAG:
        if (len == 2) {
          rt_set->tx_power_offset = (short)((cc_resp[idx + 0]) | (((cc_resp[idx + 1]) << RMS_TX_POWER_SHIFT) & 0xFF00));
          NXPLOG_UCIHAL_D("CountryCaps tx_power_offset = %d", rt_set->tx_power_offset);
        }
        break;
      default:
        break;
      }
    }
    if (tag == COUNTRY_CODE_TAG) {
      country_code_found = (cc_resp[idx + 0] == country_code[0]) && (cc_resp[idx + 1] == country_code[1]);
    }
    idx += len;
  }
}

/*******************************************************************************
 * Function      phNxpUciHal_is_retry_not_required
 *
 * Description   UCI command retry check
 *
 * Returns       true/false
 *
 *******************************************************************************/
static bool phNxpUciHal_is_retry_not_required(uint8_t uci_octet0) {
  bool isRetryRequired = false, isChained_cmd = false, isData_Msg = false;
  isChained_cmd = (bool)((uci_octet0 & UCI_PBF_ST_CONT) >> UCI_PBF_SHIFT);
  isData_Msg = ((uci_octet0 & UCI_MT_MASK) >> UCI_MT_SHIFT) == UCI_MT_DATA;
  isRetryRequired = isChained_cmd | isData_Msg;
  return isRetryRequired;
}

/******************************************************************************
 * Function         CountryCodeCapsGenTxPowerPacket
 *
 * Description      This function makes tx antenna power calibration command
 *                  with gtx_power[] + tx_power_offset
 *
 * Returns          true if packet has been updated
 *
 ******************************************************************************/
static bool CountryCodeCapsGenTxPowerPacket(uint8_t *packet, size_t packet_len, uint16_t *out_len)
{
  phNxpUciHal_Runtime_Settings_t *rt_set = &nxpucihal_ctrl.rt_settings;

  if (rt_set->tx_power_offset == 0)
    return false;

  if (gtx_power.empty())
    return false;

  if (gtx_power.size() > packet_len)
    return false;

  uint16_t gtx_power_len = gtx_power.size();
  memcpy(packet, gtx_power.data(), gtx_power_len);
  uint8_t index = UCI_MSG_HDR_SIZE + 2;  // channel + Tag

  // Length
  if (index > gtx_power_len) {
    NXPLOG_UCIHAL_E("Upper-layer calibration command for tx_power is invalid.");
    return false;
  }
  if (!packet[index] || (packet[index] + index) > gtx_power_len) {
    NXPLOG_UCIHAL_E("Upper-layer calibration command for tx_power is invalid.");
    return false;
  }
  index++;

  // Value[0] = Number of antennas
  uint8_t num_of_antennas = packet[index++];

  while (num_of_antennas--) {
    // each entry = { antenna-id(1) + peak_tx(2) + id_rms(2) }
    if ((index + 5) < gtx_power_len) {
      NXPLOG_UCIHAL_E("Upper-layer calibration command for tx_power is invalid.");
      return false;
    }

    index += 3; // antenna Id(1) + Peak Tx(2)

    // Adjust id_rms part
    long tx_power_long = packet[index]  | ((packet[index + 1] << RMS_TX_POWER_SHIFT) & 0xFF00);
    tx_power_long += rt_set->tx_power_offset;

    if (tx_power_long < 0)
      tx_power_long = 0;

    uint16_t tx_power_u16 = (uint16_t)tx_power_long;
    packet[index++] = tx_power_u16 & 0xff;
    packet[index++] = tx_power_u16 >> RMS_TX_POWER_SHIFT;
  }

  if (out_len)
    *out_len = gtx_power_len;

  return true;
}

/*******************************************************************************
 * Function     phNxpUciHal_handle_set_calibration
 *
 * Description  Remembers SET_VENDOR_SET_CALIBRATION_CMD packet
 *
 * Returns      void
 *
 *******************************************************************************/
void phNxpUciHal_handle_set_calibration(const uint8_t *p_data, uint16_t data_len)
{
  // Only saves the SET_CALIBRATION_CMD from upper-layer
  if (nxpucihal_ctrl.hal_ext_enabled) {
    return;
  }

  // SET_DEVICE_CALIBRATION_CMD Packet format: Channel(1) + TLV
  if (data_len < 6) {
    return;
  }
  const uint8_t channel = p_data[UCI_MSG_HDR_SIZE + 0];
  const uint8_t tag = p_data[UCI_MSG_HDR_SIZE + 1];
  if (tag != NXP_PARAM_ID_TX_POWER_PER_ANTENNA) {
    return;
  }

  phNxpUciHal_Runtime_Settings_t *rt_set = &nxpucihal_ctrl.rt_settings;

  // RMS Tx power -> Octet [4, 5] in calib data
  NXPLOG_UCIHAL_D("phNxpUciHal_handle_set_calibration channel=%u tx_power_offset=%d", channel, rt_set->tx_power_offset);

  // Backup the packet to gtx_power[]
  gtx_power = std::move(std::vector<uint8_t> {p_data, p_data + data_len});

  // Patch SET_CALIBRATION_CMD per gtx_power + tx_power_offset
  CountryCodeCapsGenTxPowerPacket(nxpucihal_ctrl.p_cmd_data, sizeof(nxpucihal_ctrl.p_cmd_data), &nxpucihal_ctrl.cmd_len);
}

/******************************************************************************
 * Function         CountryCodeCapsApplyTxPower
 *
 * Description      This function sets the TX power from COUNTRY_CODE_CAPS
 *
 * Returns          false if no tx_power_offset or no Upper-layer Calibration cmd was given
 *                  true if it was successfully applied.
 *
 ******************************************************************************/
static bool CountryCodeCapsApplyTxPower(void)
{
  if (gtx_power.empty())
    return false;

  // use whole packet as-is from upper-layer command (gtx_power[])
  std::vector<uint8_t> packet(gtx_power.size());
  uint16_t packet_size = 0;
  if (!CountryCodeCapsGenTxPowerPacket(packet.data(), packet.size(), &packet_size))
    return false;

  tHAL_UWB_STATUS status = phNxpUciHal_send_ext_cmd(packet_size, packet.data());
  if (status != UWBSTATUS_SUCCESS) {
      NXPLOG_UCIHAL_D("%s: send failed", __func__);
  }

  gtx_power.clear();

  return true;
}

static void extcal_do_xtal(void)
{
  int ret;

  // RF_CLK_ACCURACY_CALIB (otp supported)
  // parameters: cal.otp.xtal=0|1, cal.xtal=X
  uint8_t otp_xtal_flag = 0;
  uint8_t xtal_data[32];
  size_t xtal_data_len = 0;

  if (NxpConfig_GetNum("cal.otp.xtal", &otp_xtal_flag, 1) && otp_xtal_flag) {
    nxpucihal_ctrl.uwb_chip->read_otp(EXTCAL_PARAM_CLK_ACCURACY, xtal_data, sizeof(xtal_data), &xtal_data_len);
  }
  if (!xtal_data_len) {
    long retlen = 0;
    if (NxpConfig_GetByteArray("cal.xtal", xtal_data, sizeof(xtal_data), &retlen)) {
      xtal_data_len = retlen;
    }
  }

  if (xtal_data_len) {
    NXPLOG_UCIHAL_D("Apply CLK_ACCURARY (len=%zu, from-otp=%c)", xtal_data_len, otp_xtal_flag ? 'y' : 'n');

    ret = nxpucihal_ctrl.uwb_chip->apply_calibration(EXTCAL_PARAM_CLK_ACCURACY, 0, xtal_data, xtal_data_len);

    if (ret != UWBSTATUS_SUCCESS) {
      NXPLOG_UCIHAL_E("Failed to apply CLK_ACCURACY (len=%zu, from-otp=%c)",
          xtal_data_len, otp_xtal_flag ? 'y' : 'n');
    }
  }
}

static void extcal_do_ant_delay(void)
{
  std::bitset<8> rx_antenna_mask(nxpucihal_ctrl.cal_rx_antenna_mask);
  const uint8_t n_rx_antennas = rx_antenna_mask.size();

  const uint8_t *cal_channels = NULL;
  uint8_t nr_cal_channels = 0;
  nxpucihal_ctrl.uwb_chip->get_supported_channels(&cal_channels, &nr_cal_channels);

  // RX_ANT_DELAY_CALIB
  // parameter: cal.ant<N>.ch<N>.ant_delay=X
  // N(1) + N * {AntennaID(1), Rxdelay(Q14.2)}
  if (n_rx_antennas) {
    for (int i = 0; i < nr_cal_channels; i++) {
      uint8_t ch = cal_channels[i];
      std::vector<uint8_t> entries;
      uint8_t n_entries = 0;

      for (auto i = 0; i < n_rx_antennas; i++) {
        if (!rx_antenna_mask[i])
          continue;

        const uint8_t ant_id = i + 1;

        uint16_t delay_value, version_value;
        bool value_provided = false;

        const std::string key_ant_delay = std::format("cal.ant{}.ch{}.ant_delay", ant_id, ch);
        const std::string key_force_version = key_ant_delay + std::format(".force_version", ant_id, ch);

        // 1) try cal.ant{N}.ch{N}.ant_delay.force_value.{N}
        if (NxpConfig_GetNum(key_force_version.c_str(), &version_value, 2)) {
          const std::string key_force_value = key_ant_delay + std::format(".force_value.{}", ant_id, ch, version_value);
          if (NxpConfig_GetNum(key_force_value.c_str(), &delay_value, 2)) {
            value_provided = true;
            NXPLOG_UCIHAL_D("Apply RX_ANT_DELAY_CALIB %s = %u", key_force_value.c_str(), delay_value);
          }
        }

        // 2) try cal.ant{N}.ch{N}.ant_delay
        if (!value_provided) {
          if (NxpConfig_GetNum(key_ant_delay.c_str(), &delay_value, 2)) {
            value_provided = true;
            NXPLOG_UCIHAL_D("Apply RX_ANT_DELAY_CALIB: %s = %u", key_ant_delay.c_str(), delay_value);
          }
        }

        if (!value_provided) {
          NXPLOG_UCIHAL_V("%s was not provided from configuration files.", key_ant_delay.c_str());
          continue;
        }

        entries.push_back(ant_id);
        // Little Endian
        entries.push_back(delay_value & 0xff);
        entries.push_back(delay_value >> 8);
        n_entries++;
      }

      if (!n_entries)
        continue;

      entries.insert(entries.begin(), n_entries);
      tHAL_UWB_STATUS ret = nxpucihal_ctrl.uwb_chip->apply_calibration(EXTCAL_PARAM_RX_ANT_DELAY, ch, entries.data(), entries.size());
      if (ret != UWBSTATUS_SUCCESS) {
        NXPLOG_UCIHAL_E("Failed to apply RX_ANT_DELAY for channel %u", ch);
      }
    }
  }
}

static void extcal_do_tx_power(void)
{
  std::bitset<8> tx_antenna_mask(nxpucihal_ctrl.cal_tx_antenna_mask);
  const uint8_t n_tx_antennas = tx_antenna_mask.size();

  const uint8_t *cal_channels = NULL;
  uint8_t nr_cal_channels = 0;
  nxpucihal_ctrl.uwb_chip->get_supported_channels(&cal_channels, &nr_cal_channels);

  // TX_POWER
  // parameter: cal.ant<N>.ch<N>.tx_power={...}
  if (n_tx_antennas) {
    for (int i = 0; i < nr_cal_channels; i++) {
      uint8_t ch = cal_channels[i];
      std::vector<uint8_t> entries;
      uint8_t n_entries = 0;

      for (auto i = 0; i < n_tx_antennas; i++) {
        if (!tx_antenna_mask[i])
          continue;

        char key[32];
        const uint8_t ant_id = i + 1;
        std::snprintf(key, sizeof(key), "cal.ant%u.ch%u.tx_power", ant_id, ch);

        uint8_t power_value[32];
        long retlen = 0;
        if (!NxpConfig_GetByteArray(key, power_value, sizeof(power_value), &retlen)) {
          continue;
        }

        NXPLOG_UCIHAL_D("Apply TX_POWER: %s = { %lu bytes }", key, retlen);
        entries.push_back(ant_id);
        entries.insert(entries.end(), power_value, power_value + retlen);
        n_entries++;
      }

      if (!n_entries)
        continue;

      entries.insert(entries.begin(), n_entries);
      tHAL_UWB_STATUS ret = nxpucihal_ctrl.uwb_chip->apply_calibration(EXTCAL_PARAM_TX_POWER, ch, entries.data(), entries.size());
      if (ret != UWBSTATUS_SUCCESS) {
        NXPLOG_UCIHAL_E("Failed to apply TX_POWER for channel %u", ch);
      }
    }
  }
}

static void extcal_do_tx_pulse_shape(void)
{
  // parameters: cal.tx_pulse_shape={...}
  long retlen = 0;
  uint8_t data[64];

  if (NxpConfig_GetByteArray("cal.tx_pulse_shape", data, sizeof(data), &retlen) && retlen) {
      NXPLOG_UCIHAL_D("Apply TX_PULSE_SHAPE: data = { %lu bytes }", retlen);

      tHAL_UWB_STATUS ret = nxpucihal_ctrl.uwb_chip->apply_calibration(EXTCAL_PARAM_TX_PULSE_SHAPE, 0, data, (size_t)retlen);
      if (ret != UWBSTATUS_SUCCESS) {
        NXPLOG_UCIHAL_E("Failed to apply TX_PULSE_SHAPE.");
      }
  }
}

static void extcal_do_tx_base_band(void)
{
  // TX_BASE_BAND_CONTROL, DDFS_TONE_CONFIG
  // parameters: cal.ddfs_enable=1|0, cal.dc_suppress=1|0, ddfs_tone_config={...}
  uint8_t ddfs_enable = 0, dc_suppress = 0;
  uint8_t ddfs_tone[256];
  long retlen = 0;
  tHAL_UWB_STATUS ret;

  if (NxpConfig_GetNum("cal.ddfs_enable", &ddfs_enable, 1)) {
    NXPLOG_UCIHAL_D("Apply TX_BASE_BAND_CONTROL: ddfs_enable=%u", ddfs_enable);
  }
  if (NxpConfig_GetNum("cal.dc_suppress", &dc_suppress, 1)) {
    NXPLOG_UCIHAL_D("Apply TX_BASE_BAND_CONTROL: dc_suppress=%u", dc_suppress);
  }

  // DDFS_TONE_CONFIG
  if (ddfs_enable) {
    if (!NxpConfig_GetByteArray("cal.ddfs_tone_config", ddfs_tone, sizeof(ddfs_tone), &retlen) || !retlen) {
      NXPLOG_UCIHAL_E("cal.ddfs_tone_config is not supplied while cal.ddfs_enable=1, ddfs was not enabled.");
      ddfs_enable = 0;
    } else {
      NXPLOG_UCIHAL_D("Apply DDFS_TONE_CONFIG: ddfs_tone_config = { %lu bytes }", retlen);

      ret = nxpucihal_ctrl.uwb_chip->apply_calibration(EXTCAL_PARAM_DDFS_TONE_CONFIG, 0, ddfs_tone, (size_t)retlen);
      if (ret != UWBSTATUS_SUCCESS) {
        NXPLOG_UCIHAL_E("Failed to apply DDFS_TONE_CONFIG, ddfs was not enabled.");
        ddfs_enable = 0;
      }
    }
  }

  // TX_BASE_BAND_CONTROL
  {
    uint8_t flag = 0;
    if (ddfs_enable)
      flag |= 0x01;
    if (dc_suppress)
      flag |= 0x02;
    ret = nxpucihal_ctrl.uwb_chip->apply_calibration(EXTCAL_PARAM_TX_BASE_BAND_CONTROL, 0, &flag, 1);
    if (ret) {
      NXPLOG_UCIHAL_E("Failed to apply TX_BASE_BAND_CONTROL");
    }
  }
}

/******************************************************************************
 * Function         phNxpUciHal_extcal_handle_coreinit
 *
 * Description      Apply additional core device settings
 *
 * Returns          void.
 *
 ******************************************************************************/
void phNxpUciHal_extcal_handle_coreinit(void)
{
  // read rx_aantenna_mask, tx_antenna_mask
  uint8_t rx_antenna_mask_n = 0x1;
  uint8_t tx_antenna_mask_n = 0x1;
  if (!NxpConfig_GetNum("cal.rx_antenna_mask", &rx_antenna_mask_n, 1)) {
      NXPLOG_UCIHAL_E("cal.rx_antenna_mask is not specified, use default 0x%x", rx_antenna_mask_n);
  }
  if (!NxpConfig_GetNum("cal.tx_antenna_mask", &tx_antenna_mask_n, 1)) {
      NXPLOG_UCIHAL_E("cal.tx_antenna_mask is not specified, use default 0x%x", tx_antenna_mask_n);
  }
  nxpucihal_ctrl.cal_rx_antenna_mask = rx_antenna_mask_n;
  nxpucihal_ctrl.cal_tx_antenna_mask = tx_antenna_mask_n;

  extcal_do_xtal();
  extcal_do_ant_delay();
}

void apply_per_country_calibrations(void)
{
  // TX-POWER can be provided by
  // 1) COUNTRY_CODE_CAPS with offset values.
  // 2) Extra calibration files with absolute tx power values
  // only one should be applied if both were provided by platform
  if (!CountryCodeCapsApplyTxPower()) {
    extcal_do_tx_power();
  }

  // These are only available from extra calibration files
  extcal_do_tx_pulse_shape();
  extcal_do_tx_base_band();

}

/******************************************************************************
 * Function         phNxpUciHal_handle_set_country_code
 *
 * Description      Apply per-country settings
 *
 * Returns          void.
 *
 ******************************************************************************/
void phNxpUciHal_handle_set_country_code(const char country_code[2])
{
  NXPLOG_UCIHAL_D("Apply country code %c%c", country_code[0], country_code[1]);

  phNxpUciHal_Runtime_Settings_t *rt_set = &nxpucihal_ctrl.rt_settings;
  phNxpUciHal_resetRuntimeSettings();

  if (!is_valid_country_code(country_code)) {
    NXPLOG_UCIHAL_D("Country code %c%c is invalid, UWB should be disabled", country_code[0], country_code[1]);
  }

  if (NxpConfig_SetCountryCode(country_code)) {
    // Load ExtraCal restrictions
    uint16_t mask= 0;
    if (NxpConfig_GetNum("cal.restricted_channels", &mask, sizeof(mask))) {
      NXPLOG_UCIHAL_D("Restriction flag, restricted channel mask=0x%x", mask);
      rt_set->restricted_channel_mask = mask;
    }

    uint8_t uwb_disable = 0;
    if (NxpConfig_GetNum("cal.uwb_disable", &uwb_disable, sizeof(uwb_disable))) {
      NXPLOG_UCIHAL_D("Restriction flag, uwb_disable=%u", uwb_disable);
      rt_set->uwb_enable = !uwb_disable;
    }

    // Apply COUNTRY_CODE_CAPS
    uint8_t cc_caps[UCI_MAX_DATA_LEN];
    long retlen = 0;
    if (NxpConfig_GetByteArray(NAME_NXP_UWB_COUNTRY_CODE_CAPS, cc_caps, sizeof(cc_caps), &retlen) && retlen) {
      NXPLOG_UCIHAL_D("COUNTRY_CODE_CAPS is provided.");
      phNxpUciHal_applyCountryCaps(country_code, cc_caps, retlen);
    }

    // Check country code validity
    if (!is_valid_country_code(country_code) && rt_set->uwb_enable) {
      NXPLOG_UCIHAL_E("UWB is not disabled by configuration files with invalid country code %c%c,"
                      " forcing it disabled", country_code[0], country_code[1]);
      rt_set->uwb_enable = false;
    }

    // Apply per-country calibration, it's handled by SessionTrack
    SessionTrack_onCountryCodeChanged();
  }

  // send country code response to upper layer
  static uint8_t rsp_data[5] = { 0x4c, 0x01, 0x00, 0x01 };
  if (rt_set->uwb_enable) {
    rsp_data[4] = UWBSTATUS_SUCCESS;
  } else {
    rsp_data[4] = UCI_STATUS_CODE_ANDROID_REGULATION_UWB_OFF;
  }
  (*nxpucihal_ctrl.p_uwb_stack_data_cback)(sizeof(rsp_data), rsp_data);
}

// TODO: support fragmented packets
/*************************************************************************************
 * Function         phNxpUciHal_handle_set_app_config
 *
 * Description      Handle SESSION_SET_APP_CONFIG_CMD packet,
 *                  remove unsupported parameters
 *
 * Returns          true  : SESSION_SET_APP_CONFIG_CMD/RSP was handled by this function
 *                  false : This packet should go to chip
 *
 *************************************************************************************/
bool phNxpUciHal_handle_set_app_config(uint16_t *data_len, uint8_t *p_data)
{
  const phNxpUciHal_Runtime_Settings_t *rt_set = &nxpucihal_ctrl.rt_settings;
  // Android vendor specific app configs not supported by FW
  const uint8_t tags_to_del[] = {
    UCI_PARAM_ID_TX_ADAPTIVE_PAYLOAD_POWER,
    UCI_PARAM_ID_AOA_AZIMUTH_MEASUREMENTS,
    UCI_PARAM_ID_AOA_ELEVATION_MEASUREMENTS,
    UCI_PARAM_ID_RANGE_MEASUREMENTS
  };

  // check basic validity
  uint16_t payload_len = (p_data[UCI_CMD_LENGTH_PARAM_BYTE1] & 0xFF) |
                         ((p_data[UCI_CMD_LENGTH_PARAM_BYTE2] & 0xFF) << 8);
  if (payload_len != (*data_len - UCI_MSG_HDR_SIZE)) {
    NXPLOG_UCIHAL_E("SESSION_SET_APP_CONFIG_CMD: payload length mismatch");
    return false;
  }
  if (!p_data[UCI_CMD_NUM_CONFIG_PARAM_BYTE]) {
    return false;
  }

  uint32_t session_handle = le_bytes_to_cpu<uint32_t>(&p_data[UCI_MSG_SESSION_SET_APP_CONFIG_HANDLE_OFFSET]);
  uint8_t ch = 0;

  // Create local copy of cmd_data for data manipulation
  uint8_t uciCmd[UCI_MAX_DATA_LEN];
  uint16_t packet_len = *data_len;
  if (sizeof(uciCmd) < packet_len) {
    NXPLOG_UCIHAL_E("SESSION_SET_APP_CONFIG_CMD packet size %u is too big to handle, skip patching.", packet_len);
    return false;
  }
  // 9 = Header 4 + SessionID 4 + NumOfConfigs 1
  uint8_t i = 9, j = 9;
  uint8_t nr_deleted = 0, bytes_deleted = 0;
  memcpy(uciCmd, p_data, i);

  while (i < packet_len) {
    if ( (i + 2) >= packet_len) {
      NXPLOG_UCIHAL_E("SESSION_SET_APP_CONFIG_CMD parse error at %u", i);
      return false;
    }

    // All parameters should have 1 byte tag
    uint8_t tlv_tag = p_data[i + 0];
    uint8_t tlv_len = p_data[i + 1];
    uint8_t param_len = 2 + tlv_len;
    if ((i + param_len) > packet_len) {
      NXPLOG_UCIHAL_E("SESSION_SET_APP_CONFIG_CMD parse error at %u", i);
    }

    // check restricted channel
    if (tlv_tag == UCI_PARAM_ID_CHANNEL_NUMBER && tlv_len == 1) {
      ch = p_data[i + 2];

      if (((ch == CHANNEL_NUM_5) && (rt_set->restricted_channel_mask & (1 << 5))) ||
          ((ch == CHANNEL_NUM_9) && (rt_set->restricted_channel_mask & (1 << 9)))) {
        phNxpUciHal_print_packet(NXP_TML_UCI_CMD_AP_2_UWBS, p_data, packet_len);
        NXPLOG_UCIHAL_D("Country code blocked channel %u", ch);

        // send setAppConfig response with UCI_STATUS_CODE_ANDROID_REGULATION_UWB_OFF response
        static uint8_t rsp_data[] = { 0x41, 0x03, 0x04, 0x04,
          UCI_STATUS_FAILED, 0x01, tlv_tag, UCI_STATUS_CODE_ANDROID_REGULATION_UWB_OFF
        };
        (*nxpucihal_ctrl.p_uwb_stack_data_cback)(sizeof(rsp_data), rsp_data);
        return true;
      }
    }

    // remove unsupported parameters
    if (std::find(std::begin(tags_to_del), std::end(tags_to_del), tlv_tag) == std::end(tags_to_del)) {
      memcpy(&uciCmd[j], &p_data[i], param_len);
      j += param_len;
    } else {
      NXPLOG_UCIHAL_D("Removed param payload with Tag ID:0x%02x", tlv_tag);
      nr_deleted++;
      bytes_deleted += param_len;
    }
    i += param_len;
  }
  if (nr_deleted) {
    phNxpUciHal_print_packet(NXP_TML_UCI_CMD_AP_2_UWBS, p_data, packet_len);

    // uci number of config params update
    if (uciCmd[UCI_CMD_NUM_CONFIG_PARAM_BYTE] < nr_deleted) {
      NXPLOG_UCIHAL_E("SESSION_SET_APP_CONFIG_CMD cannot parse packet: wrong nr_parameters");
      return false;
    }
    uciCmd[UCI_CMD_NUM_CONFIG_PARAM_BYTE] -= nr_deleted;

    // uci command length update
    if (packet_len < (UCI_MSG_HDR_SIZE + bytes_deleted)) {
      NXPLOG_UCIHAL_E("SESSION_SET_APP_CONFIG_CMD cannot parse packet: underflow");
      return false;
    }
    packet_len -= bytes_deleted;
    payload_len = packet_len - UCI_MSG_HDR_SIZE;
    uciCmd[UCI_CMD_LENGTH_PARAM_BYTE2] = (payload_len & 0xFF00) >> 8;
    uciCmd[UCI_CMD_LENGTH_PARAM_BYTE1] = (payload_len & 0xFF);

    // Swap
    memcpy(p_data, uciCmd, packet_len);
    *data_len = packet_len;
  }

  SessionTrack_onAppConfig(session_handle, ch);

  return false;
}

bool phNxpUciHal_handle_get_caps_info(size_t data_len, const uint8_t *p_data)
{
  if (data_len < UCI_MSG_CORE_GET_CAPS_INFO_NR_OFFSET)
    return false;

  uint8_t status = p_data[UCI_RESPONSE_STATUS_OFFSET];
  uint8_t nr = p_data[UCI_MSG_CORE_GET_CAPS_INFO_NR_OFFSET];
  if (status != UWBSTATUS_SUCCESS || nr < 1)
    return false;

  auto tlvs = decodeTlvBytes({0xe0, 0xe1, 0xe2, 0xe3}, &p_data[UCI_MSG_CORE_GET_CAPS_INFO_TLV_OFFSET], data_len - UCI_MSG_CORE_GET_CAPS_INFO_TLV_OFFSET);
  if (tlvs.size() != nr) {
    NXPLOG_UCIHAL_E("Failed to parse DevCaps %zu != %u", tlvs.size(), nr);
  }

  // Remove all NXP vendor specific parameters
  for (auto it = tlvs.begin(); it != tlvs.end();) {
    if (it->first > 0xff)
      it = tlvs.erase(it);
    else
      it++;
  }

  // Override AOA_SUPPORT_TAG_ID
  auto it = tlvs.find(AOA_SUPPORT_TAG_ID);
  if (it != tlvs.end()) {
    if (nxpucihal_ctrl.numberOfAntennaPairs == 1) {
      it->second = std::vector<uint8_t>{0x01};
    } else if (nxpucihal_ctrl.numberOfAntennaPairs > 1) {
      it->second = std::vector<uint8_t>{0x05};
    } else {
      it->second = std::vector<uint8_t>{0x00};
    }
  }

  // Byteorder of CCC_SUPPORTED_PROTOCOL_VERSIONS_ID
  it = tlvs.find(CCC_SUPPORTED_PROTOCOL_VERSIONS_ID);
  if (it != tlvs.end() && it->second.size() == 2) {
    std::swap(it->second[0], it->second[1]);
  }

  // Append UWB_VENDOR_CAPABILITY from configuration files
  {
    std::array<uint8_t, NXP_MAX_CONFIG_STRING_LEN> buffer;
    long retlen = 0;
    if (NxpConfig_GetByteArray(NAME_UWB_VENDOR_CAPABILITY, buffer.data(),
                               buffer.size(), &retlen) && retlen) {
      auto vendorTlvs = decodeTlvBytes({}, buffer.data(), retlen);
      for (auto const& [key, val] : vendorTlvs) {
        tlvs[key] = val;
      }
    }
  }

  // Apply restrictions
  const phNxpUciHal_Runtime_Settings_t *rt_set = &nxpucihal_ctrl.rt_settings;

  uint8_t fira_channels = 0xff;
  if (rt_set->restricted_channel_mask & (1 << 5))
    fira_channels &= CHANNEL_5_MASK;
  if (rt_set->restricted_channel_mask & (1 << 9))
    fira_channels &= CHANNEL_9_MASK;

  uint8_t ccc_channels = 0;
  if (!(rt_set->restricted_channel_mask & (1 << 5)))
    ccc_channels |= 0x01;
  if (!(rt_set->restricted_channel_mask & (1 << 9)))
    ccc_channels |= 0x02;

  tlvs[UWB_CHANNELS] = std::vector{fira_channels};
  tlvs[CCC_UWB_CHANNELS] = std::vector{ccc_channels};

  // Convert it back to raw packet bytes
  uint8_t packet[256];

  // header
  memcpy(packet, p_data, UCI_MSG_HDR_SIZE);
  // status
  packet[UCI_RESPONSE_STATUS_OFFSET] = UWBSTATUS_SUCCESS;
  // nr
  packet[UCI_MSG_CORE_GET_CAPS_INFO_NR_OFFSET] = tlvs.size();

  // tlvs
  auto tlv_bytes = encodeTlvBytes(tlvs);
  if ((tlv_bytes.size() + UCI_MSG_CORE_GET_CAPS_INFO_TLV_OFFSET) > sizeof(packet)) {
    NXPLOG_UCIHAL_E("DevCaps overflow!");
    return false;
  } else {
    uint8_t packet_len = UCI_MSG_CORE_GET_CAPS_INFO_TLV_OFFSET + tlv_bytes.size();
    packet[UCI_PAYLOAD_LENGTH_OFFSET] = packet_len - UCI_MSG_HDR_SIZE;
    memcpy(&packet[UCI_MSG_CORE_GET_CAPS_INFO_TLV_OFFSET], tlv_bytes.data(), tlv_bytes.size());

    phNxpUciHal_print_packet(NXP_TML_UCI_RSP_NTF_UWBS_2_AP, packet, packet_len);

    // send GET CAPS INFO response to the Upper Layer
    (*nxpucihal_ctrl.p_uwb_stack_data_cback)(packet_len, packet);
    // skip the incoming packet as we have send the modified response
    // already
    return true;
  }
}
