/**
 * @file comms_uhf_intf.c
 *
 * @brief This file has the S-Band driver FSM implemenation and the relevant functions
 *
 * @copyright Copyright 2023 Antaris, Inc.
 *
 * 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 "sm_api.h"
#include "exo_common.h"
#include "comms_uhf_intf.h"
#include "comms_uhf_ipc.h"
#include "sdr_app_main.h"
#include "sdr_common_intf.h"
#include "exo_io_al_sos_timer.h"
#include <stdio.h>
#include"comms_uhf_main.h"
#include"comms_uhf_sim.h"
#include"comms_uhf_init.h"
#include"comms_uhf_api_map.h"
#include "comms_csw.h"
#include "exo_tctm_ipc.h"
#include "logger.h"

s_sdr_cfg PLACE_IN_EXT_RAM_MEM uhf_cfg;
s_sdr_tmr_cfg PLACE_IN_EXT_RAM_MEM uhf_tmr_cfg;
s_sdr_rssi_cfg PLACE_IN_EXT_RAM_MEM uhf_rssi_cfg;
s_sdr_tm_cfg PLACE_IN_EXT_RAM_MEM uhf_tm_cfg;
s_sdr_uhf_mh_info PLACE_IN_EXT_RAM_MEM sdr_uhf_mh;
extern s_sdr_gpass_beacon_cfg uhf_gpass_cfg;


extern uint8_t PLACE_IN_EXT_RAM_MEM comms_uhf_csw_rx_buf[512];
extern uint8_t PLACE_IN_EXT_RAM_MEM comms_uhf_otsu_cb_sts;
extern uint8_t PLACE_IN_EXT_RAM_MEM mms_uhf_first_gs_contact;
extern uint8_t PLACE_IN_EXT_RAM_MEM comms_uhf_first_gs_contact;

/** Timer used for tm store Periodicity Timer */
extern os_timer_handle_ptr uhf_tm_periodic_read;

/** Timer used for periodic transmission of Beacon signal */
extern os_timer_handle_ptr uhf_beacon_timer;

/** Timer used for enable transmission of Beacon signal */
extern os_timer_handle_ptr uhf_beacon_enb_timer;

/** Timer used for transmit ON duration */
extern os_timer_handle_ptr uhf_tx_tm_on;

/**
* @brief This function reset the comms modeule
*
* Performs a complete reset of the UHF communication hardware
* and software state machines. 
*/
e_comms_uhf_reset_sts comms_uhf_reset(void)
{
	e_comms_uhf_reset_sts sts = 0;
    return sts;
}
/**
* @brief This function check the boot for various parameter and initialize
*  respective boot mode
*
* Configures UHF communication parameters and settings.
* Called during system boot.
*/
e_comms_uhf_boot_cfg_sts comms_uhf_boot_cfg(e_comms_uhf_boot_mode mode)
{
	e_comms_uhf_boot_cfg_sts sts = 0;
    return sts;
}
/**
* @brief This function trigger the calibration of the comms module based
* on the configured calibration parameter
*
* Triggers the UHF calibration sequence. Calibration adjusts
* parameters for optimal communication performance.
*/
e_comms_uhf_calib_trgr_sts comms_uhf_calib_trgr(e_comms_uhf_calib_type type)
{
	e_comms_uhf_calib_trgr_sts sts = 0;
    return sts;
}
/**
* @brief This function enables the type of tx_rx mode of the comms module
*
* Enables UHF transmission and reception functions.
*/
e_comms_uhf_tx_rx_enbl_sts comms_uhf_tx_rx_enbl(e_comms_uhf_tx_rx_mode mode)
{
	e_comms_uhf_tx_rx_enbl_sts sts = 0;
    return sts;
}
/**
* @brief This function config the tx parameter into the comms module
*
*/
e_comms_uhf_dfu_trgr_sts comms_uhf_dfu_trg(uint8_t *params)
{
	e_comms_uhf_dfu_trgr_sts sts = 0;
    return sts;
}
/**
* @brief This function read the telemetry into comms module
*
* Reads status and telemetry data from the UHF system.
*/
e_comms_uhf_read_tm_sts comms_uhf_read_tm(e_comms_uhf_tm_type type)
{
	e_comms_uhf_read_tm_sts sts = 0;
    return sts;
}

/**
 * @brief Request UHF mode handler transition
 * 
 * This function requests a transition to a new state in the UHF
 * mode handler state machine. It allows other modules to trigger
 * a controlled transition between UHF mode handler states.
 *
 * @param pld Pointer to payload data for the state transition
 *
 * @return Status code indicating success or failure of request  
*/
int8_t sdr_app_sdr_ctrl_uhf_mh_req(void *pld)
{
    uint8_t radio_id = COMMS_UHF;

    /**
     * 1.	COMMS FSM state (4 bits)
     * 2.	RSSI (4 bits) 
     * 3.	RX error count (4 bytes)
     * 4.	Number of frame TX count (4 bytes)
     * 5.	RX frequency (4 bytes)
     * 6.	RX Modulation, symbol rate, roll-off and other configurations (2 bytes)
     *
     * For RSSI Encoding
     * 1.	Good range - Maximum RX input level to (Reference sensitivity – 3bBm) – [-40 to -102 dBm]
     * 2.	Acceptable range - (Reference sensitivity – 3bBm) to Reference sensitivity – [-102 to -105 dBm]
     * 3.	Noise floor – Below Reference sensitivity value – [less than -105 dBm]
     * this can be encoded for RX0 and RX1 in the 4 bits
     **/
    sdr_uhf_mh.sdr_fsm_st = sm_get_state(COMMS_UHF_FSM);
    sdr_uhf_mh.rssi0 = sdr_get_rssi0(radio_id);
    sdr_uhf_mh.rssi1 = sdr_get_rssi1(radio_id);
    sdr_uhf_mh.rx_err_cnt = sdr_get_rx_err_cnt(radio_id);
    sdr_uhf_mh.tx_frm_cnt = sdr_get_tx_frm_cnt(radio_id);
    sdr_uhf_mh.rx_freq = sdr_get_rx_freq(radio_id);
    sdr_uhf_mh.mod = sdr_get_mod(radio_id);
    sdr_uhf_mh.roll_off = sdr_get_roll_off(radio_id);
    sdr_uhf_mh.symb_freq = sdr_get_symb_freq(radio_id);
    sdr_uhf_mh.cc_enb = sdr_get_cc_enb(radio_id);
    sdr_uhf_mh.rand_enb = sdr_get_rand_enb(radio_id);
    sdr_uhf_mh.crc_enb = sdr_get_crc_enb(radio_id);
    sdr_uhf_mh.dc_filter_enb = sdr_get_dc_filter_enb(radio_id);
    sdr_uhf_mh.manchester_coding_en = sdr_get_manchester_enb(radio_id);

    uhf_send_ipc_pld(UHF_SDR_APP_MH_RSP,SDR_APP,sizeof(s_sdr_uhf_mh_info),(uint8_t *)&sdr_uhf_mh);
    return 0;
}
/**
 * @brief Request to configure UHF SDR  
 * 
 * @param pld Pointer to configuration data
 */
int8_t sdr_app_sdr_ctrl_uhf_sdr_cfg_req(void *pld)
{
    os_memcpy(&uhf_cfg,(uint8_t *)pld,sizeof(s_sdr_cfg));
    uhf_send_ipc(SDR_CTRL_SDR_APP_SDR_CFG_RSP,SDR_APP);
    return 0;
}
/**
 * @brief Request to configure UHF SDR
 *
 * @param pld Pointer to configuration data
 */

int8_t sdr_app_sdr_ctrl_uhf_sdr_gpass_cfg_req(void *pld)
{
    os_memcpy(&uhf_gpass_cfg,(uint8_t *)pld,sizeof(s_sdr_gpass_beacon_cfg));
    uhf_send_ipc(SDR_CTRL_SDR_APP_GPASS_CFG_RSP,SDR_APP);
    return 0;
}


/**
 * @brief Request to configure UHF SDR  
 * 
 * @param pld Pointer to configuration data
 */
int8_t sdr_app_sdr_ctrl_uhf_mode_cfg_req(void *pld)
{
    uint8_t uhf_sts = 0;
    os_memcpy(&uhf_sts,(uint8_t *)pld,sizeof(uint8_t));
    uhf_send_ipc(SDR_CTRL_SDR_APP_MODE_CFG_RSP,SDR_APP);
    return 0;
}
/**
 * @brief Request to configure UHF timers
 *
 * @param pld Pointer to timer configuration data
 */
int8_t sdr_app_sdr_ctrl_uhf_tmr_cfg_req(void *pld)
{
    os_memcpy(&uhf_tmr_cfg,(uint8_t *)pld,sizeof(s_sdr_tmr_cfg));

    /**Timer restart based on activity */
    if(os_timer_is_active(uhf_beacon_timer) == TIM_RUN)
    {
     	os_timer_start(uhf_beacon_timer, uhf_tmr_cfg.beacon_prd_tmr);
    }
    if(os_timer_is_active(uhf_beacon_enb_timer) == TIM_RUN)
    {
    	os_timer_start(uhf_beacon_enb_timer, uhf_tmr_cfg.beacon_enb_tmr);
    }
    if(os_timer_is_active(uhf_tm_periodic_read) == TIM_RUN)
    {
    	os_timer_start(uhf_tm_periodic_read, uhf_tmr_cfg.sdr_tm_read_tmr);
    }
    if(os_timer_is_active(uhf_tx_tm_on) == TIM_RUN)
    {
    	os_timer_start(uhf_tx_tm_on, uhf_tmr_cfg.sdr_tm_tx_tmr);
    }

    uhf_send_ipc(SDR_CTRL_SDR_APP_TMR_CFG_RSP,SDR_APP);
    return 0;
}
/**
 * @brief Request to configure UHF RSSI
 *
 * @param pld Pointer to RSSI configuration data
 */
int8_t sdr_app_sdr_ctrl_uhf_rssi_cfg_req(void *pld)
{
    os_memcpy(&uhf_rssi_cfg,(uint8_t *)pld,sizeof(s_sdr_rssi_cfg));
    uhf_send_ipc(SDR_CTRL_SDR_APP_RSSI_CFG_RSP,SDR_APP);
    return 0;
}
/**
 * @brief Request to configure UHF telemetry
 *
 * @param pld Pointer to telemetry configuration data 
 */ 
int8_t sdr_app_sdr_ctrl_uhf_tm_cfg_req(void *pld)
{
    os_memcpy(&uhf_tm_cfg,(uint8_t *)pld,sizeof(s_sdr_tm_cfg));
    uhf_send_ipc(SDR_CTRL_SDR_APP_RSSI_CFG_RSP,SDR_APP);
    return 0;
}
/**
 * @brief Handle initial UHF sync
 *
 * Performs initial sync actions for UHF communication.
 */
void uhf_initial_sync_hdlr(void)
{
    uint8_t rx_size = 13;
    uint8_t *tc_tm_data = NULL;
    uint8_t status = 0;

    sys_time_date_s set_time;
    sys_time_date_s get_time;
    status = 0;
    uint8 sync_msg[50];
    os_memcpy(sync_msg,&tc_tm_data[TC_PLD_IDX],sizeof("Hello Janus 1"));
    DEBUG_CPRINT(("\nFirst sync message received: %s\n",sync_msg));
    log_string(LOG_INFO_L1,LOG_COMMS,"FIRST_SYNC_MSG_RECEIVED__s8_");
    log_string(LOG_INFO_L1,LOG_COMMS,(char *)sync_msg);
    rx_size = sizeof("Hello Antaris");
    os_memcpy(&comms_uhf_csw_rx_buf[TM_PLD_IDX],"Hello Antaris",rx_size);

    os_memcpy(&set_time,&tc_tm_data[TC_PLD_IDX]+sizeof("Hello Janus 1"),sizeof(sys_time_date_s));
    DEBUG_CPRINT(("COMMS INITAL SYNC RCV sos time %d :%d :%d \n",set_time.hour,set_time.minute,set_time.seconds));
    log_id_with_three_arg(LOG_INFO_L2,LOG_COMMS,COMMS_INITAL_SYNC_RCV_SOS_TIME__u8__u8__u8_,set_time.hour,set_time.minute,set_time.seconds);
    DEBUG_CPRINT(("COMMS INITAL SYNC RCV sos date %d :%d :%d \n",set_time.date,set_time.month,set_time.year));
    log_id_with_three_arg(LOG_INFO_L2,LOG_COMMS,COMMS_INITAL_SYNC_RCV_SOS_DATE__u8__u8__u16_,set_time.date,set_time.month,set_time.year);
    set_crnt_time_date_withnvm(&set_time);

    get_crnt_time_date(&get_time);

    os_memcpy(&comms_uhf_csw_rx_buf[TM_PLD_IDX]+rx_size,&get_time,sizeof(sys_time_date_s));
    rx_size +=sizeof(sys_time_date_s);
    comms_uhf_tc_tm_get_rsp_hdlr(TM_COMMS_UHF_INITIAL_SYNC, status,tc_tm_data, rx_size);

    if(comms_uhf_otsu_cb_sts)
    {
        /** OTSU Call back - Success*/
        uhf_nvm_upd_otsu_ground_contact();
#ifndef LINUX_TEMP_PORT
        send_otsu_gssync_sts(1);
#endif
        comms_uhf_otsu_cb_sts = 0;
    }
    else
    {
        if(!comms_uhf_first_gs_contact)
        {
            comms_uhf_first_gs_contact = 1;
            uhf_nvm_upd_first_ground_contact();
            //uhf_send_ipc(UHF_OBC_GROUND_SYNC_IND,OBC_MAIN);
        }
    }

    uhf_gs_contact_status_upd_itc(UHF_TC_TM_ST_REQ,DEFAULT_COMMS_RADIO_ID); //HBTODO

}
/**
 * @brief Get current UHF state
 * 
 * @return UHF state machine current state
 */
uint8_t uhf_get_state(void)
{
	return sat_dev_sts[HW_UHF].hw_sts;
}

