/**
 * @file comms_sband_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 "comms_csw.h"
#include "comms_ipc.h"
#include "sdr_app_main.h"
#include "comms_sband_intf.h"
#include "sdr_common_intf.h"
#include "exo_io_al_sos_timer.h"

#include"comms_sband_sim.h"
#include"comms_sband_init.h"
#include"comms_sband_api_map.h"
#include"logger.h"

#include "comms_sband_xlink_ss.h"
#include "comms_sband_xlink_api.h"
#include "exo_tctm_ipc.h"

s_sdr_cfg PLACE_IN_EXT_RAM_MEM sband_cfg;
s_sdr_tmr_cfg PLACE_IN_EXT_RAM_MEM sband_tmr_cfg;
s_sdr_rssi_cfg PLACE_IN_EXT_RAM_MEM sband_rssi_cfg;
s_sdr_tm_cfg PLACE_IN_EXT_RAM_MEM sband_tm_cfg;
s_sdr_sens_cfg PLACE_IN_EXT_RAM_MEM sband_sens_cfg;
s_sdr_sband_mh_info PLACE_IN_EXT_RAM_MEM sband_mh_info;
extern s_sdr_gpass_beacon_cfg sband_gpass_cfg;
s_comms_sband_get_tm_prop_time s_band_periodic;

extern uint8_t s_comms_hk_upd_id ;
extern uint8_t is_comms_hk_upd_id_fill ;
extern uint32 PLACE_IN_EXT_RAM_MEM rx_udp_frame ;
extern uint32  PLACE_IN_EXT_RAM_MEM tx_udp_frame ;
extern s_comms_tx_cfg PLACE_IN_EXT_RAM_MEM tx_cfg_rb;
extern s_comms_rx_cfg PLACE_IN_EXT_RAM_MEM rx_cfg_rb;
extern s_comms_sys_cfg PLACE_IN_EXT_RAM_MEM sys_cfg_rb;
extern uint32_t PLACE_IN_EXT_RAM_MEM tm_store_cnt;

extern s_comms_tx_cfg PLACE_IN_EXT_RAM_MEM tx_cfg_global;
extern s_comms_rx_cfg PLACE_IN_EXT_RAM_MEM rx_cfg_global;
extern s_comms_sys_cfg PLACE_IN_EXT_RAM_MEM sys_cfg_global;

extern uint8_t PLACE_IN_EXT_RAM_MEM comms_otsu_cb_sts;
extern uint8_t PLACE_IN_EXT_RAM_MEM comms_csw_rx_buf[512] ;

/** S-Band module first ground contact status */
extern uint8_t PLACE_IN_EXT_RAM_MEM comms_sband_first_gs_contact;

/** S-Band module ground contact status after OTSU reset */
uint8_t PLACE_IN_EXT_RAM_MEM comms_sband_otsu_gs_contact = 0;

extern SERVICE_HOUSE_KEEP_STRUCT PLACE_IN_EXT_RAM_MEM sband_serv_house_keep;
extern SERVICE_DEVICE_CONF_STRUCT PLACE_IN_EXT_RAM_MEM	 sband_serv_device_conf;

/** Timer used for tm store Periodicity Timer */
extern os_timer_handle_ptr  sband_tm_periodic_read;
extern s_sband_periodic_get_tm PLACE_IN_EXT_RAM_MEM xlink_sband_tm_store;

/** Timer used for enable and periodic transmission of Beacon signal */
extern os_timer_handle_ptr sband_beacon_timer;

/** Timer used for enable and periodic transmission of Beacon signal */
extern os_timer_handle_ptr sband_beacon_enb_timer;

/** Timer used for RX on Timer */
extern os_timer_handle_ptr sband_rx_on_timer;

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

/**
 * @brief This function sets the tx config
 * 
 * @brief Set S-band TX configuration.
 * 
 * Sets the specified TX parameters in the S-band driver.
 *
 * @param[in] tx_cfg Pointer to TX config struct.
 * @return Result status of the set operation.
*/
e_comms_tx_cfg_sts comms_set_tx_cfg(s_comms_tx_cfg *tx_cfg)
{
    e_comms_tx_cfg_sts sts = COMMS_TX_CFG_SUCCESS;

    if (NULL != tx_cfg)
    {
#ifdef SDR_SBAND_SRS4 
        sts = SDR_SBAND_SET_TX_CFG(tx_cfg);
#endif
        os_memcpy(&tx_cfg_global, tx_cfg, sizeof(s_comms_tx_cfg));
    }
    else
    {
        sts = COMMS_TX_CFG_FAILURE;
    }

    return sts;
}

/**
 *  @brief This function gets the tx config
 * 
 * @brief Get current S-band TX configuration.
 *
 * Retrieves the active TX parameters from the S-band driver.
 * 
 * @param[out] tx_cfg Pointer to populate with current TX config. 
 * @param[out] size Size of the populated config struct.
 * @return Result status of the get operation. 
*/
e_comms_tx_cfg_sts comms_get_tx_cfg(s_comms_tx_cfg *tx_cfg, uint16_t* size)
{
    e_comms_tx_cfg_sts sts = COMMS_TX_CFG_SUCCESS;

    if (NULL != tx_cfg && NULL != size)
    {
        *size = sizeof(s_comms_tx_cfg);
#ifdef S_BAND_SIM_CB
        os_memcpy(tx_cfg, &tx_cfg_global, *size);
#else
#ifdef SDR_SBAND_SRS4
        sts = SDR_SBAND_GET_TX_CFG(tx_cfg);
#endif
        os_memcpy(&tx_cfg_rb, tx_cfg, *size);
#endif
        DEBUG_CPRINT(("sizeof s_comms_tx_cfg is %d \n", *size));
        log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,SIZEOF_S_COMMS_TX_CFG_IS__u16_,*size);
    }
    else
    {
        sts = COMMS_TX_CFG_FAILURE;
    }

    return sts;
}

/**
 * @brief This function sets the rx config
 * 
 * @brief Set S-band RX configuration.
 *
 * Sets the specified RX parameters in the S-band driver.
 * 
 * @param[in] rx_cfg Pointer to RX config struct.
 * @return Result status of the set operation.
*/ 
e_comms_rx_cfg_sts comms_set_rx_cfg(s_comms_rx_cfg *rx_cfg)
{
    e_comms_rx_cfg_sts sts = COMMS_RX_CFG_SUCCESS;

    if (NULL != rx_cfg)
    {
#ifdef SDR_SBAND_SRS4 
        sts = SDR_SBAND_SET_RX_CFG(rx_cfg);
#endif

        os_memcpy(&rx_cfg_global, rx_cfg, sizeof(s_comms_rx_cfg));

    }
    else
    {
        sts = COMMS_RX_CFG_FAILURE;
    }

    return sts;
}

/**
 * @brief This function gets the rx config
 *
 * @brief Get current S-band RX configuration.
 * 
 * Retrieves the active RX parameters from the S-band driver.
 *
 * @param[out] rx_cfg Pointer to populate with current RX config.
 * @param[out] size Size of the populated config struct. 
 * @return Result status of the get operation.
*/
e_comms_rx_cfg_sts comms_get_rx_cfg(s_comms_rx_cfg *rx_cfg, uint16_t* size)
{
    e_comms_rx_cfg_sts sts = COMMS_RX_CFG_SUCCESS;

    if (NULL != rx_cfg && NULL != size)
    {
        *size = sizeof(s_comms_rx_cfg);
#ifdef S_BAND_SIM_CB
        os_memcpy(rx_cfg, &rx_cfg_global, *size);
#else
#ifdef SDR_SBAND_SRS4 
        sts = SDR_SBAND_GET_RX_CFG(rx_cfg);
#endif
        os_memcpy(&rx_cfg_rb, rx_cfg, *size);
#endif

    }
    else
    {
        sts = COMMS_RX_CFG_FAILURE;
    }

    return sts;
}
/**
 * @brief This function sets the sys config
 * @brief Set S-band system configuration.
 *
 * Sets the specified system parameters in the S-band driver.
 *
 * @param[in] sys_cfg Pointer to system config struct. 
 * @return Result status of the set operation. 
*/
e_comms_sys_cfg_sts comms_set_sys_cfg(s_comms_sys_cfg *sys_cfg)
{
    e_comms_sys_cfg_sts sts = COMMS_SYS_CFG_SUCCESS;

    if (NULL != sys_cfg)
    {
#ifdef SDR_SBAND_SRS4 
        sts = SDR_SBAND_SET_SYS_CFG(sys_cfg);
#endif

        os_memcpy(&sys_cfg_global, sys_cfg, sizeof(s_comms_sys_cfg));

    }
    else
    {
        sts = COMMS_SYS_CFG_FAILURE;
    }

    return sts;
}

/**
 * @brief This function gets the sys config
 * 
 * @brief Get S-band system configuration.
 *
 * Fetches current S-band system configuration and
 * parameters. Returns size of configuration data 
 * copied into output structure.
 * 
 * @param[in] sys_cfg  pointer to system config
 * @param[in] size  pointer to size of system messag
 * @returns status of get system config
 */

e_comms_sys_cfg_sts comms_get_sys_cfg(s_comms_sys_cfg *sys_cfg, uint16_t* size)
{
    e_comms_sys_cfg_sts sts = COMMS_SYS_CFG_SUCCESS;

    if (NULL != sys_cfg && NULL != size)
    {
        *size = sizeof(s_comms_sys_cfg);
        DEBUG_CPRINT(("\nSYS CFG Size: %d\n",*size));
        log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,SYS_CFG_SIZE__u16_,*size);
#ifdef S_BAND_SIM_CB
        os_memcpy(sys_cfg, &sys_cfg_global, *size);
#else
#ifdef SDR_SBAND_SRS4 
        sts = SDR_SBAND_GET_SYS_CFG(sys_cfg);
#endif
        os_memcpy(&sys_cfg_rb,sys_cfg, *size);
#endif

    }
    else
    {
        sts = COMMS_SYS_CFG_FAILURE;
    }

    return sts;
}

/**
 * @brief This function config the tx parameter into the comms module
 * @brief Set S-band TX configuration.
 * 
 * Configures the S-band TX with the given parameters.
 *
 * @param[in] tx_cfg TX config struct to apply.
 * @return Result status of the set operation.
 */
e_comms_tx_cfg_sts comms_tx_cfg(s_comms_tx_cfg tx_cfg)
{
    e_comms_tx_cfg_sts sts = 0;

    return sts;
}
/**
 * @brief This function config the rx parameter into the comms module
 * @brief Set S-band RX configuration.
 *
 * Configures the S-band RX with the given parameters.
 *
 * @param[in] rx_cfg RX config struct to apply. 
 * @return Result status of the set operation.
 */
e_comms_rx_cfg_sts comms_rx_cfg(s_comms_rx_cfg rx_cfg)
{
    e_comms_rx_cfg_sts sts = 0;
    return sts;
}
/**
 * @brief This function config the sys parameter into the comms module
 * @brief Set S-band system configuration.
 * 
 * Configures S-band system parameters with the given settings.
 *
 * @param[in] sys_cfg System config struct to apply.
 * @return Result status of the set operation. 
 */
e_comms_sys_cfg_sts comms_sys_cfg(s_comms_sys_cfg sys_cfg)
{
    e_comms_sys_cfg_sts sts = 0;
    return sts;
}
/**
 * @brief This function reset the comms modeule
 * @brief Reset the S-band system.
 *
 * Performs a full reset and reinitialization of the S-band hardware and software.
 *
 * @return Result status of the reset operation.
 */
e_comms_reset_sts comms_reset(void)
{
    e_comms_reset_sts sts = 0;
    return sts;
}
/**
 * @brief This function check the boot for various parameter and initialize
 *  respective boot mode
 *
  * @brief Configure S-band boot mode.
 *
 * Sets the boot configuration mode of the S-band system.
 * 
 * @param[in] mode Boot mode to configure.
 * @return Result status of the boot config operation.
 */
e_comms_boot_cfg_sts comms_boot_cfg(e_comms_boot_mode mode)
{
    e_comms_boot_cfg_sts sts = 0;
    return sts;
}
/**
 * @brief This function trigger the calibration of the comms module based
 * on the configured calibration parameter
 *
 * Initiates the specified calibration type on the S-band system.
 *
 * @param[in] type Calibration type to perform.
 * @return Result status of the calibration trigger.
 */
e_comms_calib_trgr_sts comms_calib_trgr(e_comms_calib_type type)
{
    e_comms_calib_trgr_sts sts = 0;
    return sts;
}
/**
 * @brief This function enables the type of tx_rx mode of the comms module
 *
 * Configures the enabled state of the S-band transceiver.
 *
 * @param[in] mode TX/RX mode to set.
 * @return Result status of the enable/disable operation. 
 */
e_comms_tx_rx_enbl_sts comms_tx_rx_enbl(e_comms_tx_rx_mode mode)
{
    e_comms_tx_rx_enbl_sts sts = 0;
    return sts;
}
/**
 * @brief This function config the tx parameter into the comms module
 *
 * Initiates a firmware upgrade on the S-band system.
 *
 * @param[in] params DFU parameters. 
 * @return Result status of the DFU trigger.
 */
e_comms_dfu_trgr_sts comms_dfu_trg(u8 *params)
{
    e_comms_dfu_trgr_sts sts = 0;
    return sts;
}
/**
 * @brief This function read the telemetry into comms module
 *
 * @brief Read S-band telemetry.
 *
 * Retrieves the specified telemetry type from the S-band driver.
 *
 * @param[in] type Telemetry type to read.
 * @return Result status of the read operation.
 */
e_comms_read_tm_sts comms_read_tm(e_comms_tm_type type)
{
    e_comms_read_tm_sts sts = 0;
    return sts;
}

/**
 * @brief Request S-band mode handler execution.  
 * 
 * Triggers the S-band mode handler to run based on current
 * driver state. Handles events like mode transitions.
 *
 * @param[in] pld Payload (unused).
 * @return Execution status.
*/
int8_t sdr_app_sdr_ctrl_sband_mh_req(void *pld)
{
    uint8_t radio_id = COMMS_SBAND_IQS;

    /**
     * 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
     **/
    sband_mh_info.sdr_fsm_st = sm_get_state(COMMS_SBAND_FSM);
    sband_mh_info.rssi0 = sdr_get_rssi0(radio_id);
    sband_mh_info.rssi1 = sdr_get_rssi1(radio_id);
    sband_mh_info.rx_err_cnt = sdr_get_rx_err_cnt(radio_id);
    sband_mh_info.tx_frm_cnt = sdr_get_tx_frm_cnt(radio_id);
    sband_mh_info.rx_freq = sdr_get_rx_freq(radio_id);
    sband_mh_info.mod = sdr_get_mod(radio_id);
    sband_mh_info.roll_off = sdr_get_roll_off(radio_id);
    sband_mh_info.symb_freq = sdr_get_symb_freq(radio_id);
    sband_mh_info.cc_enb = sdr_get_cc_enb(radio_id);
    sband_mh_info.rand_enb = sdr_get_rand_enb(radio_id);
    sband_mh_info.rs_enb = sdr_get_rs_enb(radio_id);

    sband_send_ipc_pld(SBAND_SDR_APP_MH_RSP,SDR_APP,sizeof(s_sdr_sband_mh_info),(uint8_t *)&sband_mh_info);
    return 0;
}

/**
 * @brief Handle SDR configuration request.
 * 
 * Processes an SDR configuration request message
 * and configures the S-band SDR accordingly.
 * 
 * @param[in] pld Request message payload. 
 * @return Execution status.
*/ 
int8_t sdr_app_sdr_ctrl_sband_sdr_gpass_cfg_req(void *pld)
{
    os_memcpy(&sband_gpass_cfg,(uint8_t *)pld,sizeof(s_sdr_gpass_beacon_cfg));
    sband_send_ipc(SDR_CTRL_SDR_APP_GPASS_CFG_RSP,SDR_APP);
    return 0;
}

/**
 * @brief Handle SDR configuration request.
 * 
 * Processes an SDR configuration request message
 * and configures the S-band SDR accordingly.
 * 
 * @param[in] pld Request message payload. 
 * @return Execution status.
*/
int8_t sdr_app_sdr_ctrl_sband_sdr_cfg_req(void *pld)
{
    os_memcpy(&sband_cfg,(uint8_t *)pld,sizeof(s_sdr_cfg));
    sband_send_ipc(SDR_CTRL_SDR_APP_SDR_CFG_RSP,SDR_APP);
    return 0;
}

/**
 * @brief Handle mode configuration request.
 *
 * Processes a mode configuration request message
 * and configures the S-band mode accordingly.
 *
 * @param[in] pld Request message payload.
 * @return Execution status. 
*/
int8_t sdr_app_sdr_ctrl_sband_mode_cfg_req(void *pld)
{
    uint8_t sband_sts = 0;
    os_memcpy(&sband_sts,(uint8_t *)pld,sizeof(uint8_t));
    sband_send_ipc(SDR_CTRL_SDR_APP_MODE_CFG_RSP,SDR_APP);
    return 0;
}

/**
 * @brief Handle timer configuration request.
 *
 * Processes a timer configuration request message  
 * and configures the S-band timers accordingly.
 * 
 * @param[in] pld Request message payload.
 * @return Execution status.
*/
int8_t sdr_app_sdr_ctrl_sband_tmr_cfg_req(void *pld)
{
    os_memcpy(&sband_tmr_cfg,(uint8_t *)pld,sizeof(s_sdr_tmr_cfg));
    /**TODO: Timer restart based on activity */
    if(os_timer_is_active(sband_beacon_timer) == TIM_RUN)
    {
     	os_timer_start(sband_beacon_timer, sband_tmr_cfg.beacon_prd_tmr);
    }

    if(os_timer_is_active(sband_beacon_enb_timer) == TIM_RUN)
    {
     	os_timer_start(sband_beacon_enb_timer, sband_tmr_cfg.beacon_enb_tmr);
    }

    if(os_timer_is_active(sband_rx_on_timer) == TIM_RUN)
    {
     	os_timer_start(sband_rx_on_timer, sband_tmr_cfg.sdr_rx_on_tmr);
    }

    if(os_timer_is_active(sband_tx_tm_on) == TIM_RUN)
    {
     	os_timer_start(sband_tx_tm_on, sband_tmr_cfg.sdr_tm_tx_tmr);
    }

    if(os_timer_is_active(sband_tm_periodic_read) == TIM_RUN)
    {
    	if((sband_tmr_cfg.sdr_tm_read_tmr >= sband_rssi_cfg.rssi_prd_tmr)&&(sband_rssi_cfg.rssi_prd_tmr !=0))
    	{
    		tm_store_cnt = sband_tmr_cfg.sdr_tm_read_tmr/sband_rssi_cfg.rssi_prd_tmr;
    		os_timer_start(sband_tm_periodic_read, sband_rssi_cfg.rssi_prd_tmr);
    	}
    	else
    	{
    		tm_store_cnt = 1;
    		os_timer_start(sband_tm_periodic_read, sband_tmr_cfg.sdr_tm_read_tmr);
    	}
    }

    sband_send_ipc(SDR_CTRL_SDR_APP_TMR_CFG_RSP,SDR_APP);
    return 0;
}

/**
 * @brief Handle RSSI configuration request.
 *
 * Processes an RSSI configuration request message
 * and configures S-band RSSI reporting accordingly.
 *
 * @param[in] pld Request message payload.
 * @return Execution status.
*/
int8_t sdr_app_sdr_ctrl_sband_rssi_cfg_req(void *pld)
{
    os_memcpy(&sband_rssi_cfg,(uint8_t *)pld,sizeof(s_sdr_rssi_cfg));
    DEBUG_CPRINT(("\nIPC RSSI_PRD_TMR:%d\n",sband_rssi_cfg.rssi_prd_tmr));
    sband_send_ipc(SDR_CTRL_SDR_APP_RSSI_CFG_RSP,SDR_APP);
    return 0;
}

/**
 * @brief Handle telemetry configuration request. 
 *
 * Processes a TM configuration request message
 * and configures S-band telemetry accordingly.
 *
 * @param[in] pld Request message payload. 
 * @return Execution status.
*/
int8_t sdr_app_sdr_ctrl_sband_tm_cfg_req(void *pld)
{
    os_memcpy(&sband_tm_cfg,(uint8_t *)pld,sizeof(s_sdr_tm_cfg));
    sband_send_ipc(SDR_CTRL_SDR_APP_TM_CFG_RSP,SDR_APP);
    return 0;
}

/**
 * @brief Handle sensitivity configuration request.
 *
 * Processes a sensitivity configuration request message
 * and configures S-band sensitivity accordingly.
 * 
 * @param[in] pld Request message payload.
 * @return Execution status.
*/
int8_t sdr_app_sdr_ctrl_sband_sens_cfg_req(void *pld)
{
    os_memcpy(&sband_sens_cfg,(uint8_t *)pld,sizeof(s_sdr_sens_cfg));
    sband_send_ipc(SDR_CTRL_SDR_APP_SENS_CFG_RSP,SDR_APP);
    return 0;
}

/**
 * @brief Handle S-band TC/TM message.
 *
 * Processes an incoming S-band TC/TM packet based on 
 * message type and dispatches to appropriate handler.
 *
 * @param[in] radio_id S-band radio ID (unused).
 * @param[in] msg_id TC or TM message ID. 
 * @param[in] pld_ptr Pointer to message payload.
 * @param[in] pld_len Payload length in bytes.
 * @return Execution status.
*/
int8_t comms_tctm_hdlr(uint8_t radio_id, uint16_t msg_id, void *pld_ptr,uint16_t pld_len)
{
#if 0
    switch(radio_id)
    {
#ifdef SDR_SBAND_SRS4
        case COMMS_S_BAND:
            {
                comms_srs4_tctm_hdlr(msg_id,pld_len,pld_ptr);
            }
            break;
#endif
        case COMMS_SBAND_IQS:
            {
                comms_xlink_s_tctm_hdlr(msg_id,pld_len,pld_ptr);
            }
            break;
    }
#endif
    comms_xlink_s_tctm_hdlr(msg_id,pld_len,pld_ptr);

    return 0;
}
/**
 * @brief Handle initial S-band sync packet.
 * 
 * Processes the initial sync packet received from the ground 
 * during S-band acquisition. Performs synchronization actions:
 * - Extracts time, product key, frequencies
 * - Applies configurations 
 * - Sends ack to ground  
 *
 * @param[in] tc_tm_data Pointer to sync packet data.
*/
void comms_sband_initial_sync_hdlr(uint8_t *tc_tm_data)
{
    uint16_t rx_size = 0;
    sys_time_date_s set_time;
    sys_time_date_s get_time;
    uint8_t status = 0;
    uint8 sync_msg[50];
    os_memcpy(sync_msg,&tc_tm_data[TC_PLD_IDX],sizeof("Hello Janus1"));
    DEBUG_CPRINT(("\nFirst sync message received: %s\n",sync_msg));
    log_string(LOG_INFO_L1,LOG_COMMS,"First sync message received: ");
    log_string(LOG_INFO_L1,LOG_COMMS,(char*)sync_msg);
    rx_size = sizeof("Hello Antaris");
    os_memcpy(&comms_csw_rx_buf[TM_PLD_IDX],"Hello Antaris",rx_size);

    os_memcpy(&set_time,&tc_tm_data[TC_PLD_IDX]+sizeof("Hello Janus1"),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_L1,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_L1,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);
#ifdef COMMS_TIME_DEBUG
    get_crnt_time_date(&get_time);

    DEBUG_CPRINT(("COMMS INITAL SYNC SEN sos time %d :%d :%d \n",get_time.hour,get_time.minute,get_time.seconds));
    log_id_with_three_arg(LOG_INFO_L1,LOG_COMMS,COMMS_INITAL_SYNC_SEN_SOS_TIME__u8__u8__u8_,get_time.hour,get_time.minute,get_time.seconds);
    DEBUG_CPRINT(("COMMS INITAL SYNC SEN sos date %d :%d :%d \n",get_time.date,get_time.month,get_time.year));
    log_id_with_three_arg(LOG_INFO_L1,LOG_COMMS,COMMS_INITAL_SYNC_SEN_SOS_DATE__u8__u8__u16_,get_time.date,get_time.month,get_time.year);
#endif

    os_memcpy(&comms_csw_rx_buf[TM_PLD_IDX]+rx_size,&get_time,sizeof(sys_time_date_s));
    rx_size +=sizeof(sys_time_date_s);

    comms_tc_tm_get_rsp_hdlr(TM_COMMS_INITIAL_SYNC, status,tc_tm_data, rx_size);

    if(comms_otsu_cb_sts)
    {
        /** OTSU Call back - Success*/
        comms_sband_otsu_gs_contact = 1;
        sband_nvm_upd_otsu_ground_contact();
#ifndef LINUX_TEMP_PORT
        send_otsu_gssync_sts(1);
#endif
        comms_otsu_cb_sts = 0;
    }
    else
    {
        if(!comms_sband_first_gs_contact)
        {
            comms_sband_first_gs_contact = 1;
            sband_nvm_upd_first_ground_contact();
            //sband_send_ipc(SBAND_OBC_GROUND_SYNC_IND,OBC_MAIN);
        }
    }
    sband_gs_contact_status_upd_itc(SBAND_TC_TM_ST_REQ,DEFAULT_COMMS_RADIO_ID);//HBTODO

}

/**
 * @brief Generate S-band crosslink health telemetry.
 *
 * Collects and packages S-band health telemetry items
 * for crosslink transmission:
 * - Statistics, temperatures, statuses
 * - Encodes into CCSDS packet
 *
 * Called periodically by telemetry collection task. 
 */
void sband_xlinks_health_report_tm(void)
{
    s_sband_periodic_tm *tm = (s_sband_periodic_tm*)&xlink_sband_tm_store.sband_tm_store[s_comms_hk_upd_id];

    HOUSE_KEEP_STRUCT *hk = &sband_serv_house_keep.HouseKeep;


    tm->cmn_tm.temp_xcvr                   = hk->Temp.AD9361; //xlink_sys_param.temp_xcvr;

    tm->cmn_tm.temp_mcu                    = hk->Temp.EthPhy; //xlink_sys_param.temp_mcu;
    
      tm->cmn_tm.temp_fpga                   = hk->Temp.Zynq; //xlink_sys_param.temp_fpga;
   
      tm->cmn_tm.volt_vint                   = hk->Volt[0]; //xlink_sys_param.volt_vint;

    tm->cmn_tm.volt_vaux                   = hk->Volt[1]; //xlink_sys_param.volt_vaux;

    tm->cmn_tm.volt_vbram                  = hk->Volt[2]; //xlink_sys_param.volt_vbram;

    tm->cmn_tm.volt_vpint                  = hk->Volt[3]; //xlink_sys_param.volt_vpint;

    tm->cmn_tm.volt_vpaux                  = hk->Volt[4]; //xlink_sys_param.volt_vpaux;

    tm->cmn_tm.volt_vpdro                  = hk->Volt[5]; //xlink_sys_param.volt_vpdro;

    tm->rx_tm[RX_CH_0].rx_cfg_frames 	    = rx_udp_frame;

    tm->rx_tm[RX_CH_0].rx_cfg_detected      = rx_udp_frame;

    tm->rx_tm[RX_CH_0].rx_cfg_rssi		    = comms_xlink_s_get_rssi(RX_CH_0);

    tm->rx_tm[RX_CH_0].rx_avg_rssi			= comms_xlink_s_get_rssi(RX_CH_0);

    tm->rx_tm[RX_CH_0].rx_cfg_freqerr	    = hk->RcvInfCh[RX_CH_0].DopplerFreq;

    tm->rx_tm[RX_CH_0].rx_cfg_carrier_lock  = hk->RcvInfCh[RX_CH_0].Sync;

    tm->rx_tm[RX_CH_0].rx_frame_lock	    = hk->RcvInfCh[RX_CH_0].Sync;

    tm->rx_tm[RX_CH_0].rx_sir_min	    	= hk->RcvInfCh[RX_CH_0].SirMin;

    tm->rx_tm[RX_CH_0].rx_sir_max	    	= hk->RcvInfCh[RX_CH_0].SirMax;

    tm->rx_tm[RX_CH_0].rx_bch_block_cnt     = hk->RcvInfCh[RX_CH_0].BchBlockCount;

    tm->rx_tm[RX_CH_0].rx_bch_err_cnt       = hk->RcvInfCh[RX_CH_0].BchErrCount;

    tm->rx_tm[RX_CH_1].rx_cfg_frames 	    = rx_udp_frame;

    tm->rx_tm[RX_CH_1].rx_cfg_detected      = rx_udp_frame;

    tm->rx_tm[RX_CH_1].rx_cfg_rssi	    = comms_xlink_s_get_rssi(RX_CH_1);

    tm->rx_tm[RX_CH_0].rx_avg_rssi			= comms_xlink_s_get_rssi(RX_CH_0);

    tm->rx_tm[RX_CH_1].rx_cfg_freqerr	    = hk->RcvInfCh[RX_CH_1].DopplerFreq;

    tm->rx_tm[RX_CH_1].rx_cfg_carrier_lock  = hk->RcvInfCh[RX_CH_1].Sync;
   
    tm->rx_tm[RX_CH_1].rx_frame_lock	    = hk->RcvInfCh[RX_CH_1].Sync;

    tm->rx_tm[RX_CH_1].rx_sir_min	    = hk->RcvInfCh[RX_CH_1].SirMin;

    tm->rx_tm[RX_CH_1].rx_sir_max	    = hk->RcvInfCh[RX_CH_1].SirMax;

    tm->rx_tm[RX_CH_1].rx_bch_block_cnt     = hk->RcvInfCh[RX_CH_1].BchBlockCount;

    tm->rx_tm[RX_CH_1].rx_bch_err_cnt       = hk->RcvInfCh[RX_CH_1].BchErrCount;

    tm->tx_tm.tx_cfg_frames 	    = tx_udp_frame;
     
    tm->tx_tm.tx_cfg_pwr_rfl	    = sband_serv_device_conf.XmtCtr3.AttTxGain_0/10;
    s_comms_hk_upd_id++;

    DEBUG_CPRINT(("The hk comms upd id is %d\n", s_comms_hk_upd_id));
    
    log_id_with_one_arg(LOG_INFO_L2,LOG_COMMS,HK_COMMS_ID_IS_u8_,s_comms_hk_upd_id);

    if(s_comms_hk_upd_id == MAX_SBAND_PERIODIC_TM)
    {
        s_comms_hk_upd_id = 0;
        is_comms_hk_upd_id_fill = 1;
    }
    /** Enqueue the information to Buffering FW */
    s_sband_periodic_tm *sband_data = os_malloc(sizeof(s_sband_periodic_tm));
    if(sband_data)
    {
        s_band_periodic.time_stamp=get_crnt_time_date_in_epoch();
        os_memcpy(sband_data, tm, sizeof(s_sband_periodic_tm));
        tc_sband_buff_fw_enqueue_req((uint8*)sband_data, SBAND_PERIODIC_TM_QUEUE_ID);
    }
    else
    {
        //malloc failed
    }

    os_timer_start(sband_tm_periodic_read, sband_tmr_cfg.sdr_tm_read_tmr);
}

/**
 * @brief Get current S-band state.
 *
 * Returns the state enum value corresponding 
 * to the current S-band driver state.
 *
 * @return Current S-band state enum value.
*/
uint8 sband_get_state(void)
{
	return sat_dev_sts[HW_S_BAND].hw_sts;
}
