/**
 * @file adcs_bsk.c
 *
 * @brief This file contains basilisk telemetry extract functionalities.
 *
 * @copyright Copyright 2023 Antaris, Inc.
 */
/*********************************************************************/

#include <stdio.h>
#include <string.h>
#include "adcs_bsk.h"

/**
 * @brief This function extract the Identification Command
 */
uint16_t adcs_bsk_ext_tlm_id(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_id id_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_id);

    // Copy data to tc buffer
    memcpy(&id_param,&data[0],len);

    // Debug print
    printf("Id:- %d\n",id_param.id);

    return len;
}

/**
 * @brief This function extract the ADCS state
 */
uint16_t adcs_bsk_ext_tlm_state(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_state state = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_state);

    // Copy data to tc buffer
    memcpy(&state,&data[0],len);

    // Debug print
    printf("State:- %d\n",state.state);

    return len;
}

/**
 * @brief This function extract the TLE configuration
 */
uint16_t adcs_bsk_ext_tlm_tle(uint8_t *data)
{
    printf("TLE Configuration\n");
    // Variable decleration
    uint16_t len;
    s_adcs_tle tle_cfg = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_tle);

    // Copy data to tc buffer
    memcpy(&tle_cfg,&data[0],len);

    // Debug print
    printf("inclination:- %lf\n",tle_cfg.inclination);
    printf("eccentricity:- %lf\n",tle_cfg.eccentricity);
    printf("raan:- %lf\n",tle_cfg.raan);
    printf("arg_perigee:- %lf\n",tle_cfg.arg_perigee);
    printf("b_star:- %lf\n",tle_cfg.b_star);
    printf("mean_motion:- %lf\n",tle_cfg.mean_motion);
    printf("mean_anomaly:- %lf\n",tle_cfg.mean_anomaly);
    printf("epoch:- %lf\n",tle_cfg.epoch);

    return len;
}

/**
 * @brief This function extract the Moment of inertia matrix
 */
uint16_t adcs_bsk_ext_tlm_moi(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_moi moi_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_moi);

    // Copy data to tc buffer
    memcpy(&moi_param,&data[0],len);

    // Debug print
    printf("Mom In XX:- %lf\n",moi_param.mom_iner_xx);
    printf("Mom In YY:- %lf\n",moi_param.mom_iner_yy);
    printf("Mom In ZZ:- %lf\n",moi_param.mom_iner_zz);
    printf("Prod In xy:- %lf\n",moi_param.prod_iner_xy);
    printf("Prod In xz:- %lf\n",moi_param.prod_iner_xz);
    printf("Prod In yz:- %fl\n",moi_param.prod_iner_yz);

    return len;
}

/**
 * @brief This function extract the Power configuration
 */
uint16_t adcs_bsk_ext_tlm_power(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_pwr_cmd power_sts_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_pwr_cmd);

    // Copy data to tc buffer
    memcpy(&power_sts_param,&data[0],len);

    // Debug print
    printf("Power value:- %d\n",power_sts_param.pwr_source);

    return len;
}

/**
 * @brief This function extract the Magnetic field vector
 */
uint16_t adcs_bsk_ext_tlm_mag_vector(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_mag_vector magnetic_vector = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_mag_vector);

    // Copy data to tc buffer
    memcpy(&magnetic_vector,&data[0],len);

    // Debug print
    printf("Magnetic field X:- %d\n",magnetic_vector.mag_filed_x);
    printf("Magnetic field Y:- %d\n",magnetic_vector.mag_filed_y);
    printf("Magnetic field Z:- %d\n",magnetic_vector.mag_filed_z);

    return len;
}

/**
 * @brief This function extract the CSS vector
 */
uint16_t adcs_bsk_ext_tlm_css_sun_vector(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_sun_vector css_vector = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_sun_vector);

    // Copy data to tc buffer
    memcpy(&css_vector,&data[0],len);

    // Debug print
    printf("CSS Vector X:- %d\n",css_vector.sun_x);
    printf("CSS Vector Y:- %d\n",css_vector.sun_y);
    printf("CSS Vector Z:- %d\n",css_vector.sun_z);

    return len;
}

/**
 * @brief This function extract the FSS vector
 */
uint16_t adcs_bsk_ext_tlm_fss_sun_vector(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_sun_vector fss_vector = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_sun_vector);

    // Copy data to tc buffer
    memcpy(&fss_vector,&data[0],len);

    // Debug print
    printf("FSS Vector X:- %d\n",fss_vector.sun_x);
    printf("FSS Vector Y:- %d\n",fss_vector.sun_y);
    printf("FSS Vector Z:- %d\n",fss_vector.sun_z);

    return len;
}

/**
 * @brief This function extract the Nadir vector
 */
uint16_t adcs_bsk_ext_tlm_nadir_vector(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_nadir_vector nadir_vector = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_nadir_vector);

    // Copy data to tc buffer
    memcpy(&nadir_vector,&data[0],len);

    // Debug print
    printf("Nadir Vector X:- %d\n",nadir_vector.nadir_x);
    printf("Nadir Vector Y:- %d\n",nadir_vector.nadir_y);
    printf("Nadir Vector Z:- %d\n",nadir_vector.nadir_z);

    return len;
}

/**
 * @brief This function extract the Rate sensor rates
 */
uint16_t adcs_bsk_ext_tlm_sensor_rate(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_rate_sens rates = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_rate_sens);

    // Copy data to tc buffer
    memcpy(&rates,&data[0],len);

    // Debug print
    printf("Rate Sensor X:- %lf\n",rates.rate_x);
    printf("Rate Sensor Y:- %lf\n",rates.rate_y);
    printf("Rate Sensor Z:- %lf\n",rates.rate_z);

    return len;
}

/**
 * @brief This function extract the Star Tracker body vector for xyz axis
 */
uint16_t adcs_bsk_ext_tlm_star_body(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_star_trkr_body star_body = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_star_trkr_body);

    // Copy data to tc buffer
    memcpy(&star_body,&data[0],len);

    // Debug print
    printf("Star Tracker body X:- %d\n",star_body.star_b_x);
    printf("Star Tracker body Y:- %d\n",star_body.star_b_y);
    printf("Star Tracker body Z:- %d\n",star_body.star_b_z);

    return len;
}

/**
 * @brief This function extract the Star Tracker Orbit vector for xyz axis
 */
uint16_t adcs_bsk_ext_tlm_star_orbit(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_star_trkr_orbit star_orbit = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_star_trkr_orbit);

    // Copy data to tc buffer
    memcpy(&star_orbit,&data[0],len);

    // Debug print
    printf("Star Tracker Orbit X:- %d\n",star_orbit.star_o_x);
    printf("Star Tracker Orbit Y:- %d\n",star_orbit.star_o_y);
    printf("Star Tracker Orbit Z:- %d\n",star_orbit.star_o_z);

    return len;
}

/**
 * @brief This function extract the raw Nadir sensor measurement
 */
uint16_t adcs_bsk_ext_tlm_raw_nadir(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_nadir_sens nadir_sens = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_nadir_sens);

    // Copy data to tc buffer
    memcpy(&nadir_sens,&data[0],len);

    // Debug print
    printf("Nadir Raw X:- %d\n",nadir_sens.nadir_raw_x);
    printf("Nadir Raw Y:- %d\n",nadir_sens.nadir_raw_y);
    printf("Nadir Capture result:- %d\n",nadir_sens.nadir_busy);
    printf("Nadir Detect result:- %d\n",nadir_sens.nadir_result);

    return len;
}

/**
 * @brief This function extract the raw FSS measurement
 */
uint16_t adcs_bsk_ext_tlm_raw_fss(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_fss_sens fss_sens = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_fss_sens);

    // Copy data to tc buffer
    memcpy(&fss_sens,&data[0],len);

    // Debug print
    printf("FSS Raw X:- %d\n",fss_sens.fss_raw_x);
    printf("FSS Raw Y:- %d\n",fss_sens.fss_raw_y);
    printf("FSS Capture result:- %d\n",fss_sens.fss_busy);
    printf("FSS Detect result:- %d\n",fss_sens.fss_result);

    return len;
}

/**
 * @brief This function extract the raw Magnetometer measurement
 */
uint16_t adcs_bsk_ext_tlm_raw_magmtr(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_raw_mgmtr raw_mgmtr = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_raw_mgmtr);

    // Copy data to tc buffer
    memcpy(&raw_mgmtr,&data[0],len);

    // Debug print
    printf("Raw Magnetometer X:- %d\n",raw_mgmtr.mag_raw_x);
    printf("Raw Magnetometer Y:- %d\n",raw_mgmtr.mag_raw_y);
    printf("Raw Magnetometer Z:- %d\n",raw_mgmtr.mag_raw_z);

    return len;
}

/**
 * @brief This function extract the raw GPS and Sattelite tracker structure
 */
uint16_t adcs_bsk_ext_tlm_raw_gps_status(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_gps_s gps_param  = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_gps_s);

    // Copy data to tc buffer
    memcpy(&gps_param,&data[0],len);

    // Debug print
    printf("GPS Solution Status:- %d\n",gps_param.gps_sol_sts);
    printf("GPS Number of satellite used in solution:- %d\n",\
    gps_param.gps_num_sats_tracked);
    printf("Counter for XYZ Lof from GPS:- %d\n",gps_param.gps_xyz_log_ctr);
    printf("Counter for RANGE log from GPS:- %d\n",\
    gps_param.gps_range_log_ctr);
    printf("Response Message for GPS log setup:- %d\n",gps_param.gps_response);

    return len;
}

/**
 * @brief This function extract the raw GPS time format
 */
uint16_t adcs_bsk_ext_tlm_raw_gps_time(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_gps_time gps_time  = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_gps_time);

    // Copy data to tc buffer
    memcpy(&gps_time,&data[0],len);

    // Debug print
    printf("GPS Week:- %d\n",gps_time.gps_week);
    printf("GPS Time MS:- %d\n",gps_time.gps_time_ms);

    return len;
}

/**
 * @brief This function extract the raw Position and velocity in ECEF format for X axis
 */
uint16_t adcs_bsk_ext_tlm_raw_gps_x(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_gps_x gps_x  = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_gps_x);

    // Copy data to tc buffer
    memcpy(&gps_x,&data[0],len);

    // Debug print
    printf("Position X:- %d\n",gps_x.ecef_pos_x);
    printf("Velocity X:- %d\n",gps_x.ecef_vel_x);

    return len;
}

/**
 * @brief This function extract the raw Position and velocity in ECEF format for Y axis
 */
uint16_t adcs_bsk_ext_tlm_raw_gps_y(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_gps_y gps_y  = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_gps_y);

    // Copy data to tc buffer
    memcpy(&gps_y,&data[0],len);

    // Debug print
    printf("Position Y:- %d\n",gps_y.ecef_pos_y);
    printf("Velocity Y:- %d\n",gps_y.ecef_vel_y);

    return len;
}

/**
 * @brief This function extract the raw Position and velocity in ECEF format for Z axis
 */
uint16_t adcs_bsk_ext_tlm_raw_gps_z(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_gps_z gps_z  = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_gps_z);

    // Copy data to tc buffer
    memcpy(&gps_z,&data[0],len);

    // Debug print
    printf("Position Z:- %d\n",gps_z.ecef_pos_z);
    printf("Velocity Z:- %d\n",gps_z.ecef_vel_z);

    return len;
}

/**
 * @brief This function extract the Star Tracker magnitude of identified
 */
uint16_t adcs_bsk_ext_tlm_star_magnitude(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_star_trkr_mag star_mag  = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_star_trkr_mag);

    // Copy data to tc buffer
    memcpy(&star_mag,&data[0],len);

    // Debug print
    printf("Star 1:- %d\n",star_mag.mag_star_1);
    printf("Star 2:- %d\n",star_mag.mag_star_2);
    printf("Star 3:- %d\n",star_mag.mag_star_3);

    return len;
}

/**
 * @brief This function extract the Star Tracker performance
 */
uint16_t adcs_bsk_ext_tlm_star_performance(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_star_trkr_perform star_perform  = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_star_trkr_perform);

    // Copy data to tc buffer
    memcpy(&star_perform,&data[0],len);

    // Debug print
    printf("Number Star detected:- %d\n",star_perform.num_stars_detected);
    printf("Star Image Noise:- %d\n",star_perform.star_image_noise);
    printf("Invalid Star:- %d\n",star_perform.invalid_stars);
    printf("Number of star identified:- %d\n",star_perform.num_stars_id);
    printf("Identification mode:- %d\n",star_perform.id_mode);
    printf("Image Dark value:- %d\n",star_perform.image_dark_value);

    return len;
}

/**
 * @brief This function extract the Timing information of star measurement
 */
uint16_t adcs_bsk_ext_tlm_star_timing(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_star_trkr_timing star_timing  = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_star_trkr_timing);

    // Copy data to tc buffer
    memcpy(&star_timing,&data[0],len);

    // Debug print
    printf("Capture:- %d\n",star_timing.capture);
    printf("Detection:- %d\n",star_timing.detection);
    printf("Identification:- %d\n",star_timing.id);

    return len;
}

/**
 * @brief This function extract the Raw sensor measurement
 */
uint16_t adcs_bsk_ext_tlm_raw_sensor_measure(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_raw_sensor raw_sensor  = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_raw_sensor);

    // Copy data to tc buffer
    memcpy(&raw_sensor,&data[0],len);

    // Debug print
    printf("Raw Nadir X:- %d\n",raw_sensor.nadir_raw_x);
    printf("Raw Nadir Y:- %d\n",raw_sensor.nadir_raw_y);
    printf("Raw Nadir Capture Status:- %d\n",raw_sensor.nadir_busy);
    printf("Raw Nadir Detect Status:- %d\n",raw_sensor.nadir_result);
    printf("Raw FSS X:- %d\n",raw_sensor.fss_raw_x);
    printf("Raw FSS Y:- %d\n",raw_sensor.fss_raw_y);
    printf("Raw FSS Capture Status:- %d\n",raw_sensor.fss_busy);
    printf("Raw CSS:- %d\n",raw_sensor.css_raw);
    printf("Raw Magnetometer X:- %d\n",raw_sensor.mag_raw_x);
    printf("Raw Magnetometer Y:- %d\n",raw_sensor.mag_raw_y);
    printf("Raw Magnetometer Z:- %d\n",raw_sensor.mag_raw_z);
    printf("Raw Angular Rate X:- %d\n",raw_sensor.raw_rate_x);
    printf("Raw Angular Rate Y:- %d\n",raw_sensor.raw_rate_y);
    printf("Raw Angular Rate Z:- %d\n",raw_sensor.raw_rate_z);

    return len;
}

/**
 * @brief This function extract the Raw GPS measurement
 */
uint16_t adcs_bsk_ext_tlm_raw_gps_measure(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_raw_gps raw_gps  = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_raw_gps);

    // Copy data to tc buffer
    memcpy(&raw_gps,&data[0],len);

    // Debug print
    printf("Raw GPS Solution Staus:- %d\n",raw_gps.gps_sol_sts);
    printf("Raw Number of satellite tracked:- %d\n",\
    raw_gps.gps_num_sats_tracked);
    printf("Raw Number of satellite in solution:- %d\n",\
    raw_gps.gps_num_sats_sol);
    printf("Raw gps_xyz_log_ctr:- %d\n",raw_gps.gps_xyz_log_ctr);
    printf("Raw gps_range_log_ctr:- %d\n",raw_gps.gps_range_log_ctr);
    printf("Raw gps_response:- %d\n",raw_gps.gps_response);
    printf("Raw gps_week:- %d\n",raw_gps.gps_week);
    printf("Raw gps_time_ms:- %d\n",raw_gps.gps_time_ms);
    printf("Raw ecef_pos_x:- %d\n",raw_gps.ecef_pos_x);
    printf("Raw ecef_vel_x:- %d\n",raw_gps.ecef_vel_x);
    printf("Raw ecef_pos_y:- %d\n",raw_gps.ecef_pos_y);
    printf("Raw ecef_vel_y:- %d\n",raw_gps.ecef_vel_y);
    printf("Raw ecef_pos_z:- %d\n",raw_gps.ecef_pos_z);
    printf("Raw ecef_vel_z:- %d\n",raw_gps.ecef_vel_z);
    printf("Raw std_dev_pos_x:- %lf\n",raw_gps.std_dev_pos_x);
    printf("Raw std_dev_pos_y:- %lf\n",raw_gps.std_dev_pos_y);
    printf("Raw std_dev_pos_z:- %lf\n",raw_gps.std_dev_pos_z);
    printf("Raw std_dev_vel_x:- %d\n",raw_gps.std_dev_vel_x);
    printf("Raw std_dev_vel_y:- %d\n",raw_gps.std_dev_vel_y);
    printf("Raw std_dev_vel_z:- %d\n",raw_gps.std_dev_vel_z);

    return len;
}

/**
 * @brief This function extract the Star Tracker raw measurement
 */
uint16_t adcs_bsk_ext_tlm_raw_star_measure(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_raw_star_trkr raw_star_trkr  = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_raw_star_trkr);

    // Copy data to tc buffer
    memcpy(&raw_star_trkr,&data[0],len);

    // Debug print
    printf("Raw num_stars_detected:- %d\n",raw_star_trkr.num_stars_detected);
    printf("Raw star_image_noise:- %d\n",raw_star_trkr.star_image_noise);
    printf("Raw invalid_stars:- %d\n",raw_star_trkr.invalid_stars);
    printf("Raw num_stars_id:- %d\n",raw_star_trkr.num_stars_id);
    printf("Raw id_mode:- %d\n",raw_star_trkr.id_mode);
    printf("Raw image_dark_value:- %d\n",raw_star_trkr.image_dark_value);
    printf("Raw image_capture_success:- %d\n",\
    raw_star_trkr.image_capture_success);
    printf("Raw detection_success:- %d\n",raw_star_trkr.detection_success);
    printf("Raw id_success:- %d\n",raw_star_trkr.id_success);
    printf("Raw attitude_success:- %d\n",raw_star_trkr.attitude_success);
    printf("Raw processing_time_error:- %d\n",\
    raw_star_trkr.processing_time_error);
    printf("Raw tracking_module_enabled:- %d\n",\
    raw_star_trkr.tracking_module_enabled);
    printf("Raw prediction_enabled:- %d\n",raw_star_trkr.prediction_enabled);
    printf("Raw comms_error:- %d\n",raw_star_trkr.comms_error);
    printf("Raw s1_conf:- %d\n",raw_star_trkr.s1_conf);
    printf("Raw s2_conf:- %d\n",raw_star_trkr.s2_conf);
    printf("Raw s3_conf:- %d\n",raw_star_trkr.s3_conf);
    printf("Raw mag_star_1:- %d\n",raw_star_trkr.mag_star_1);
    printf("Raw mag_star_2:- %d\n",raw_star_trkr.mag_star_2);
    printf("Raw mag_star_3:- %d\n",raw_star_trkr.mag_star_3);
    printf("Raw capture:- %d\n",raw_star_trkr.capture);
    printf("Raw detection:- %d\n",raw_star_trkr.detection);
    printf("Raw id:- %d\n",raw_star_trkr.id);
    printf("Raw rate_x:- %lf\n",raw_star_trkr.rate_x);
    printf("Raw rate_y:- %lf\n",raw_star_trkr.rate_y);
    printf("Raw rate_z:- %lf\n",raw_star_trkr.rate_z);
    printf("Raw est_attitude_q1:- %lf\n",raw_star_trkr.est_attitude_q1);
    printf("Raw est_attitude_q2:- %lf\n",raw_star_trkr.est_attitude_q2);
    printf("Raw est_attitude_q3:- %lf\n",raw_star_trkr.est_attitude_q3);

    return len;
}

/**
 * @brief This function extract the Star Tracker raw data
 */
uint16_t adcs_bsk_ext_tlm_raw_star_data(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_raw_star_trkr raw_star_trkr  = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_raw_star_trkr);

    // Copy data to tc buffer
    memcpy(&raw_star_trkr,&data[0],len);

    // Debug print
    printf("Raw num_stars_detected:- %d\n",raw_star_trkr.num_stars_detected);
    printf("Raw star_image_noise:- %d\n",raw_star_trkr.star_image_noise);
    printf("Raw invalid_stars:- %d\n",raw_star_trkr.invalid_stars);
    printf("Raw num_stars_id:- %d\n",raw_star_trkr.num_stars_id);
    printf("Raw id_mode:- %d\n",raw_star_trkr.id_mode);
    printf("Raw image_dark_value:- %d\n",raw_star_trkr.image_dark_value);
    printf("Raw image_capture_success:- %d\n",\
    raw_star_trkr.image_capture_success);
    printf("Raw detection_success:- %d\n",raw_star_trkr.detection_success);
    printf("Raw id_success:- %d\n",raw_star_trkr.id_success);
    printf("Raw attitude_success:- %d\n",raw_star_trkr.attitude_success);
    printf("Raw processing_time_error:- %d\n",\
    raw_star_trkr.processing_time_error);
    printf("Raw tracking_module_enabled:- %d\n",\
    raw_star_trkr.tracking_module_enabled);
    printf("Raw prediction_enabled:- %d\n",raw_star_trkr.prediction_enabled);
    printf("Raw comms_error:- %d\n",raw_star_trkr.comms_error);
    printf("Raw s1_conf:- %d\n",raw_star_trkr.s1_conf);
    printf("Raw s2_conf:- %d\n",raw_star_trkr.s2_conf);
    printf("Raw s3_conf:- %d\n",raw_star_trkr.s3_conf);
    printf("Raw mag_star_1:- %d\n",raw_star_trkr.mag_star_1);
    printf("Raw mag_star_2:- %d\n",raw_star_trkr.mag_star_2);
    printf("Raw mag_star_3:- %d\n",raw_star_trkr.mag_star_3);
    printf("Raw capture:- %d\n",raw_star_trkr.capture);
    printf("Raw detection:- %d\n",raw_star_trkr.detection);
    printf("Raw id:- %d\n",raw_star_trkr.id);
    printf("Raw rate_x:- %lf\n",raw_star_trkr.rate_x);
    printf("Raw rate_y:- %lf\n",raw_star_trkr.rate_y);
    printf("Raw rate_z:- %lf\n",raw_star_trkr.rate_z);
    printf("Raw est_attitude_q1:- %lf\n",raw_star_trkr.est_attitude_q1);
    printf("Raw est_attitude_q2:- %lf\n",raw_star_trkr.est_attitude_q2);
    printf("Raw est_attitude_q3:- %lf\n",raw_star_trkr.est_attitude_q3);

    return len;
}

/**
 * @brief This function extract the Raw Magnetometer
 */
uint16_t adcs_bsk_ext_tlm_sec_raw_magmtr_measure(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_raw_mgmtr raw_mgmtr  = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_raw_mgmtr);

    // Copy data to tc buffer
    memcpy(&raw_mgmtr,&data[0],len);

    // Debug print
    printf("Raw magnetometer X:- %d\n",raw_mgmtr.mag_raw_x);
    printf("Raw magnetometer Y:- %d\n",raw_mgmtr.mag_raw_y);
    printf("Raw magnetometer Z:- %d\n",raw_mgmtr.mag_raw_z);

    return len;
}

/**
 * @brief This function extract the Rate sensor raw measurement
 */
uint16_t adcs_bsk_ext_tlm_raw_rates(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_raw_rate_sens raw_rate  = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_raw_rate_sens);

    // Copy data to tc buffer
    memcpy(&raw_rate,&data[0],len);

    // Debug print
    printf("X axis raw rate sensor:- %d\n",raw_rate.raw_rate_x);
    printf("Y axis raw rate sensor:- %d\n",raw_rate.raw_rate_y);
    printf("Z axis raw rate sensor:- %d\n",raw_rate.raw_rate_z);

    return len;
}

/**
 * @brief This function extract the Estimated star tracker rates
 */
uint16_t adcs_bsk_ext_tlm_star_est_rate(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_star_est_rate star_est_rate  = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_star_est_rate);

    // Copy data to tc buffer
    memcpy(&star_est_rate,&data[0],len);

    // Debug print
    printf("Estimated X Rate measurement:- %d\n",star_est_rate.x_axis_rate);
    printf("Estimated Y Rate measurement:- %d\n",star_est_rate.x_axis_rate);
    printf("Estimated Z Rate measurement:- %d\n",star_est_rate.x_axis_rate);

    return len;
}

/**
 * @brief This function extract the Sensors Current measurement
 */
uint16_t adcs_bsk_ext_tlm_sensor_current(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_sens_cur sens_current = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_sens_cur);

    // Copy data to tc buffer
    memcpy(&sens_current,&data[0],len);

    // Debug print
    printf("Nadir Current:- %lf\n",sens_current.nadir_current);
    printf("CSS Current:- %lf\n",sens_current.css_current);
    printf("FSS Current:- %lf\n",sens_current.fss_current);

    return len;
}

/**
 * @brief This function extract the Current measurement
 */
uint16_t adcs_bsk_ext_tlm_con_current_measure(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_current current_mesr = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_current);

    // Copy data to tc buffer
    memcpy(&current_mesr,&data[0],len);

    // Debug print
    printf("Current in 3.3V:- %d\n",current_mesr.current_3v3);
    printf("Current in 5V:- %d\n",current_mesr.current_5v);

    return len;
}

/**
 * @brief This function extract the Reaction wheel Current parameter
 */
uint16_t adcs_bsk_ext_tlm_rw_current(uint8_t *data)
{
    // Variable decleration
    uint16_t len = 0;
    s_adcs_rw_cur *rw_current = {0};

    // Assign payload data to the pointer
    rw_current = (s_adcs_rw_cur*)&data[1];

    printf("Reaction wheel count:- %d\n", data[0]);
    for(int i = 0; i < data[0]; i++)
    {
        // Debug print
        printf("Reaction Wheel %d Current:- %lf\n",i + 1, rw_current[i].rw_current);
    }

    return len;
}

/**
 * @brief This function extract the Temperature measurement
 */
uint16_t adcs_bsk_ext_tlm_temperature(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_temperature temp_msr = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_temperature);

    // Copy data to tc buffer
    memcpy(&temp_msr,&data[0],len);

    // Debug print
    printf("MCU Temperature:- %d\n",temp_msr.mcu_temperature);
    printf("Magnetometer Temperature:- %d\n",temp_msr.mgmtr_temperature);
    printf("Rate Sensor Temperature:- %d\n",temp_msr.rate_sensor_temperature);

    return len;
}

/**
 * @brief This function extract the Rate sensor temeprature measurement
 */
uint16_t adcs_bsk_ext_tlm_rate_sensor_temperature(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_rate_temperature rate_temp = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_rate_temperature);

    // Copy data to tc buffer
    memcpy(&rate_temp,&data[0],len);

    // Debug print
    printf("Rate Sensor X Temperature:- %d\n",rate_temp.x_rate_temp);
    printf("Rate Sensor Y Temperature:- %d\n",rate_temp.y_rate_temp);
    printf("Rate Sensor Z Temperature:- %d\n",rate_temp.z_rate_temp);

    return len;
}

/**
 * @brief This function extract the ADCS Current and Temperature
 */
uint16_t adcs_bsk_ext_tlm_power_temperature(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_cur_temp cur_temp;

    // Value assignment to variable
    len = sizeof(s_adcs_cur_temp);

    // Copy data to tc buffer
    memcpy(&cur_temp,&data[0],len);

    // Debug print
    printf("Current in 3.3V:- %d\n",cur_temp.adcs_current.current_3v3);
    printf("Current in 5V:- %d\n",cur_temp.adcs_current.current_5v);
    printf("MCU Temperature:- %d\n",cur_temp.adcs_temp.mcu_temperature);
    printf("Magnetometer Temperature:- %d\n",\
    cur_temp.adcs_temp.mgmtr_temperature);
    printf("Rate Sensor Temperature:- %d\n",\
    cur_temp.adcs_temp.rate_sensor_temperature);

    return len;
}

/**
 * @brief This function extract the Gyro configuration
 */
uint16_t adcs_bsk_ext_tlm_gyro_cfg(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_gyro_cfg gyro_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_gyro_cfg);

    // Copy data to tc buffer
    memcpy(&gyro_param,&data[0],len);

    // Debug print
    printf("gyro config:- %d\n",gyro_param.gyro_conf);
    printf("x_rate_offset:- %f\n",gyro_param.x_rate_offset);
    printf("y_rate_offset:- %f\n",gyro_param.y_rate_offset);
    printf("z_rate_offset:- %f\n",gyro_param.z_rate_offset);
    printf("rate_sensor_mult:- %d\n",gyro_param.rate_sensor_mult);

    return len;
}

/**
 * @brief This function extract the Star Tracker configuration parameters
 */
uint16_t adcs_bsk_ext_tlm_star_trkr_cgf(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_star_trkr_cfg star_trkr_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_star_trkr_cfg);

    // Copy data to tc buffer
    memcpy(&star_trkr_param,&data[0],len);

    // Debug print
    printf("angle_1:- %lf\n",star_trkr_param.angle_1);
    printf("angle_2:- %lf\n",star_trkr_param.angle_2);
    printf("angle_3:- %lf\n",star_trkr_param.angle_3);
    printf("exposure:- %d\n",star_trkr_param.exposure);
    printf("gain:- %d\n",star_trkr_param.gain);
    printf("detection_threshold:- %d\n",star_trkr_param.detection_threshold);
    printf("threshold:- %d\n",star_trkr_param.threshold);
    printf("max_star_matched:- %d\n",star_trkr_param.max_star_matched);
    printf("timeout_time:- %d\n",star_trkr_param.timeout_time);
    printf("max_star_pixel:- %d\n",star_trkr_param.max_star_pixel);
    printf("min_star_pixel:- %d\n",star_trkr_param.min_star_pixel);
    printf("error_margin:- %lf\n",star_trkr_param.error_margin);
    printf("delay_time:- %d\n",star_trkr_param.delay_time);
    printf("cent_x:- %f\n",star_trkr_param.cent_x);
    printf("cent_y:- %f\n",star_trkr_param.cent_y);
    printf("focal:- %f\n",star_trkr_param.focal);
    printf("lens_k1:- %f\n",star_trkr_param.lens_k1);
    printf("lens_k2:- %f\n",star_trkr_param.lens_k2);
    printf("lens_p1:- %f\n",star_trkr_param.lens_p1);
    printf("lens_p2:- %f\n",star_trkr_param.lens_p2);
    printf("window_width:- %d\n",star_trkr_param.window_width);
    printf("tracking_margin:- %lf\n",star_trkr_param.tracking_margin);
    printf("validation_margin:- %lf\n",star_trkr_param.validation_margin);
    printf("module_enable:- %d\n",star_trkr_param.module_enable);
    printf("location_prediction_enable:- %d\n",\
    star_trkr_param.location_prediction_enable);
    printf("search_width:- %lf\n",star_trkr_param.search_width);

    return len;
}

/**
 * @brief This function extract the Magnetometer configuration parameters
 */
uint16_t adcs_bsk_ext_tlm_mgmtr_cfg(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_mgmtr_cfg mgmtr_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_mgmtr_cfg);

    // Copy data to tc buffer
    memcpy(&mgmtr_param,&data[0],len);

    // Debug print
    printf("angle_1:- %lf\n",mgmtr_param.angle_1);
    printf("angle_2:- %lf\n",mgmtr_param.angle_2);
    printf("angle_3:- %lf\n",mgmtr_param.angle_3);
    printf("offset_1:- %lf\n",mgmtr_param.offset_1);
    printf("offset_2:- %lf\n",mgmtr_param.offset_2);
    printf("offset_3:- %lf\n",mgmtr_param.offset_3);
    printf("sens_11:- %lf\n",mgmtr_param.sens_11);
    printf("sens_12:- %lf\n",mgmtr_param.sens_12);
    printf("sens_13:- %lf\n",mgmtr_param.sens_13);
    printf("sens_21:- %lf\n",mgmtr_param.sens_21);
    printf("sens_22:- %lf\n",mgmtr_param.sens_22);
    printf("sens_23:- %lf\n",mgmtr_param.sens_23);
    printf("sens_31:- %lf\n",mgmtr_param.sens_31);
    printf("sens_32:- %lf\n",mgmtr_param.sens_32);
    printf("sens_33:- %lf\n",mgmtr_param.sens_33);

    return len;
}

/**
 * @brief This function extract the Coarse Sun Sensor configuration parameters
 */
uint16_t adcs_bsk_ext_tlm_css_cfg(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_css_cfg css_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_css_cfg);

    // Copy data to tc buffer
    memcpy(&css_param,&data[0],len);

    // Debug print
    printf("Css config:- %d\n",css_param.css_conf);
    printf("css_scale:- %lf\n",css_param.css_scale);
    printf("css_min:- %d\n",css_param.css_min);

    return len;
}

/**
 * @brief This function extract the Fine Sun Sensor configuration parameters
 */
uint16_t adcs_bsk_ext_tlm_fss_cfg(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_fss_cfg fss_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_fss_cfg);

    // Copy data to tc buffer
    memcpy(&fss_param,&data[0],len);

    // Debug print
    printf("fss config:- %d\n",fss_param.fss_conf);
    printf("fss_scale:- %lf\n",fss_param.fss_scale);
    printf("fss_min:- %d\n",fss_param.fss_min);

    return len;
}

/**
 * @brief This function extract the Nadir configuration parameters
 */
uint16_t adcs_bsk_ext_tlm_nadir_cfg(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_nadir_cfg nadir_cfg_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_nadir_cfg);

    // Copy data to tc buffer
    memcpy(&nadir_cfg_param,&data[0],len);

    // Debug print
    printf("max_deviation_pct:- %d\n",nadir_cfg_param.max_deviation_pct);
    printf("max_bad_edges:- %d\n",nadir_cfg_param.max_bad_edges);
    printf("max_radius:- %d\n",nadir_cfg_param.max_radius);
    printf("min_radius:- %d\n",nadir_cfg_param.min_radius);

    return len;
}

/**
 * @brief This function extract the Redundant  Magnetometer configuration parameters
 */
uint16_t adcs_bsk_ext_tlm_red_mgmtr_cfg(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_mgmtr_cfg red_mgmtr_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_mgmtr_cfg);

    // Copy data to tc buffer
    memcpy(&red_mgmtr_param,&data[0],len);

    // Debug print
    printf("angle_1:- %lf\n",red_mgmtr_param.angle_1);
    printf("angle_2:- %lf\n",red_mgmtr_param.angle_2);
    printf("angle_3:- %lf\n",red_mgmtr_param.angle_3);
    printf("offset_1:- %lf\n",red_mgmtr_param.offset_1);
    printf("offset_2:- %lf\n",red_mgmtr_param.offset_2);
    printf("offset_3:- %lf\n",red_mgmtr_param.offset_3);
    printf("sens_11:- %lf\n",red_mgmtr_param.sens_11);
    printf("sens_12:- %lf\n",red_mgmtr_param.sens_12);
    printf("sens_13:- %lf\n",red_mgmtr_param.sens_13);
    printf("sens_21:- %lf\n",red_mgmtr_param.sens_21);
    printf("sens_22:- %lf\n",red_mgmtr_param.sens_22);
    printf("sens_23:- %lf\n",red_mgmtr_param.sens_23);
    printf("sens_31:- %lf\n",red_mgmtr_param.sens_31);
    printf("sens_32:- %lf\n",red_mgmtr_param.sens_32);
    printf("sens_33:- %lf\n",red_mgmtr_param.sens_33);

    return len;
}

/**
 * @brief This function extract the Magnetorquer configuration parameters
 */
uint16_t adcs_bsk_ext_tlm_mgntrqr_cfg(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_mgntrqr_cfg mgntrqr_config_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_mgntrqr_cfg);

    // Copy data to tc buffer
    memcpy(&mgntrqr_config_param,&data[0],len);

    // Debug print
    printf("Magnetoquer Axis:- %d\n",mgntrqr_config_param.mgntrqr_axis);

    return len;
}

/**
 * @brief This function extract the Reaction Wheel configuration parameters
 */
uint16_t adcs_bsk_ext_tlm_rw_cfg(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_rw_cfg rw_cfg_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_rw_cfg);

    // Copy data to tc buffer
    memcpy(&rw_cfg_param,&data[0],len);

    // Debug print
    printf("RW 1 Axis:- %d\n",rw_cfg_param.rw_conf);

    return len;
}

/**
 * @brief This function extract the Detumble control configuration parameters
 */
uint16_t adcs_bsk_ext_tlm_detumble_param(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_detumble_ctrl detumble_ctrl_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_detumble_ctrl);

    // Copy data to tc buffer
    memcpy(&detumble_ctrl_param,&data[0],len);

    // Debug print
    printf("spin_gain:- %f\n",detumble_ctrl_param.spin_gain);
    printf("damping_gain:- %f\n",detumble_ctrl_param.damping_gain);
    printf("rw_ref_spin_rate:- %lf\n",detumble_ctrl_param.rw_ref_spin_rate);
    printf("f_bdot_gain:- %f\n",detumble_ctrl_param.f_bdot_gain);

    return len;
}

/**
 * @brief This function extract the Y axis reaction wheel control configuration parameters
 */
uint16_t adcs_bsk_ext_tlm_y_rw_ctrl(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_y_rw_ctrl y_rw_ctrl_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_y_rw_ctrl);

    // Copy data to tc buffer
    memcpy(&y_rw_ctrl_param,&data[0],len);

    // Debug print
    printf("Y ctrl_gain:- %f\n",y_rw_ctrl_param.ctrl_gain);
    printf("Y nutation_damp_gain:- %f\n",y_rw_ctrl_param.nutation_damp_gain);
    printf("Y prop_gain:- %lf\n",y_rw_ctrl_param.prop_gain);
    printf("Y derv_gain:- %f\n",y_rw_ctrl_param.derv_gain);
    printf("Y ref_rw_mom:- %f\n",y_rw_ctrl_param.ref_rw_mom);

    return len;
}

/**
 * @brief This function extract the Reaction wheel control configuration parameters
 */
uint16_t adcs_bsk_ext_tlm_rw_ctrl(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_rw_ctrl rw_ctrl_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_rw_ctrl);

    // Copy data to tc buffer
    memcpy(&rw_ctrl_param,&data[0],len);

    // Debug print
    printf("spin_gain:- %f\n",rw_ctrl_param.rw_prop_gain);
    printf("nutation_damp_gain:- %f\n",rw_ctrl_param.rw_derv_gain);
    printf("prop_gain:- %lf\n",rw_ctrl_param.y_rw_bias);
    printf("sun_point_facet:- %d\n",rw_ctrl_param.sun_point_facet);
    printf("rw_error_handling:- %d\n",rw_ctrl_param.rw_error_handling);

    return len;
}

/**
 * @brief This function extract the Tracking control gain parameters
 */
uint16_t adcs_bsk_ext_tlm_trck_ctrl_gain(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_trck_ctrl_gain trck_ctrl_gain = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_trck_ctrl_gain);

    // Copy data to tc buffer
    memcpy(&trck_ctrl_gain,&data[0],len);

    // Debug print
    printf("prop_gain:- %f\n",trck_ctrl_gain.prop_gain);
    printf("derv_gain:- %f\n",trck_ctrl_gain.derv_gain);
    printf("integ_gain:- %f\n",trck_ctrl_gain.integ_gain);
    printf("target_Track_Facet:- %d\n",trck_ctrl_gain.target_Track_Facet);

    return len;
}

/**
 * @brief This function extract the Attitude Angle gain parameters
 */
uint16_t adcs_bsk_ext_tlm_attitude(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_attitude_angl attitude_angle = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_attitude_angl);

    // Copy data to tc buffer
    memcpy(&attitude_angle,&data[0],len);

    // Debug print
    printf("roll:- %lf\n",attitude_angle.roll);
    printf("pitch:- %lf\n",attitude_angle.pitch);
    printf("yaw:- %lf\n",attitude_angle.yaw);

    return len;
}

/**
 * @brief This function extract the Target Tarcking parameters
 */
uint16_t adcs_bsk_ext_tlm_target_track(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_trck_target trck_target_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_trck_target);

    // Copy data to tc buffer
    memcpy(&trck_target_param,&data[0],len);

    // Debug print
    printf("lat_ref:- %lf\n",trck_target_param.lat_ref);
    printf("long_ref:- %lf\n",trck_target_param.long_ref);
    printf("alt_ref:- %lf\n",trck_target_param.alt_ref);

    return len;
}

/**
 * @brief This function extract the Interial reference
 */
uint16_t adcs_bsk_ext_tlm_inertial_ref(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_inrt_ref inrt_ref = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_inrt_ref);

    // Copy data to tc buffer
    memcpy(&inrt_ref,&data[0],len);

    // Debug print
    printf("iner_ref_x:- %d\n",inrt_ref.iner_ref_x);
    printf("iner_ref_y:- %d\n",inrt_ref.iner_ref_y);
    printf("iner_ref_z:- %d\n",inrt_ref.iner_ref_z);

    return len;
}

/**
 * @brief This function extract the Estimation parameters
 */
uint16_t adcs_bsk_ext_tlm_est_param(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_est_param est_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_est_param);

    // Copy data to tc buffer
    memcpy(&est_param,&data[0],len);

    // Debug print
    printf("mag_rate_noise:- %f\n",est_param.mag_rate_noise);
    printf("ekf_sys_noise:- %f\n",est_param.ekf_sys_noise);
    printf("css_noise:- %f\n",est_param.css_noise);
    printf("sun_noise:- %f\n",est_param.sun_noise);
    printf("nadir_noise:- %f\n",est_param.nadir_noise);
    printf("mag_noise:- %f\n",est_param.mag_noise);
    printf("star_noise:- %f\n",est_param.star_noise);
    printf("use_sun_est:- %d\n",est_param.use_sun_est);
    printf("use_nadir_est:- %d\n",est_param.use_nadir_est);
    printf("use_css_est:- %d\n",est_param.use_css_est);
    printf("use_star_est:- %d\n",est_param.use_star_est);
    printf("nadir_terminator_check:- %d\n",est_param.nadir_terminator_check);
    printf("mag_mode:- %d\n",est_param.mag_mode);

    return len;
}

/**
 * @brief This function extract the ECI position of the sattlite
 */
uint16_t adcs_bsk_ext_tlm_eci_postition(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_eci_position eci_position = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_eci_position);

    // Copy data to tc buffer
    memcpy(&eci_position,&data[0],len);

    // Debug print
    printf("Position X:- %d\n",eci_position.position_x);
    printf("Position Y:- %d\n",eci_position.position_y);
    printf("Position Z:- %d\n",eci_position.position_z);

    return len;
}

/**
 * @brief This function extract the ECI velocity of the Sattelite
 */
uint16_t adcs_bsk_ext_tlm_sat_velocity(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_eci_velocity eci_velocity = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_eci_velocity);

    // Copy data to tc buffer
    memcpy(&eci_velocity,&data[0],len);

    // Debug print
    printf("Velocity X:- %d\n",eci_velocity.velocity_x);
    printf("Velocity Y:- %d\n",eci_velocity.velocity_y);
    printf("Velocity Z:- %d\n",eci_velocity.velocity_z);

    return len;
}

/**
 * @brief This function extract the Position LLH
 */
uint16_t adcs_bsk_ext_tlm_llh_psition(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_trck_target trck_target_param = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_trck_target);

    // Copy data to tc buffer
    memcpy(&trck_target_param,&data[0],len);

    // Debug print
    printf("lat_ref:- %lf\n",trck_target_param.lat_ref);
    printf("long_ref:- %lf\n",trck_target_param.long_ref);
    printf("alt_ref:- %lf\n",trck_target_param.alt_ref);

    return len;
}

/**
 * @brief This function extract the Estimated angular rates
 */
uint16_t adcs_bsk_ext_tlm_est_rate(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_est_rate est_rate = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_est_rate);

    // Copy data to tc buffer
    memcpy(&est_rate,&data[0],len);

    // Debug print
    printf("Est X Angular Rate:- %d\n",est_rate.est_x_angular_rate);
    printf("Est Y Angular Rate:- %d\n",est_rate.est_y_angular_rate);
    printf("Est Z Angular Rate:- %d\n",est_rate.est_z_angular_rate);

    return len;
}

/**
 * @brief This function extract the Estimated quaternion
 */
uint16_t adcs_bsk_ext_tlm_est_qutrn(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_est_qutrn est_qutrn = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_est_qutrn);

    // Copy data to tc buffer
    memcpy(&est_qutrn,&data[0],len);

    // Debug print
    printf("Est Quaternion 1:- %d\n",est_qutrn.est_qutrn_1);
    printf("Est Quaternion 2:- %d\n",est_qutrn.est_qutrn_2);
    printf("Est Quaternion 3:- %d\n",est_qutrn.est_qutrn_3);

    return len;
}

/**
 * @brief This function extract the ECEF position of the sattlite
 */
uint16_t adcs_bsk_ext_tlm_ecef_position(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_eci_position ecef_position = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_eci_position);

    // Copy data to tc buffer
    memcpy(&ecef_position,&data[0],len);

    // Debug print
    printf("Position X:- %d\n",ecef_position.position_x);
    printf("Position Y:- %d\n",ecef_position.position_y);
    printf("Position Z:- %d\n",ecef_position.position_z);

    return len;
}

/**
 * @brief This function extract the Magnetic filed vector measurement
 */
uint16_t adcs_bsk_ext_tlm_mod_mag_vector(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_mag_vector mag_vec = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_mag_vector);

    // Copy data to tc buffer
    memcpy(&mag_vec,&data[0],len);

    // Debug print
    printf("Magnetic Vector X:- %d\n",mag_vec.mag_filed_x);
    printf("Magnetic Vector Y:- %d\n",mag_vec.mag_filed_y);
    printf("Magnetic Vector Z:- %d\n",mag_vec.mag_filed_z);

    return len;
}

/**
 * @brief This function extract the Sun Vector measurement
 */
uint16_t adcs_bsk_ext_tlm_mod_sun_vector(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_sun_vector sun_vec = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_sun_vector);

    // Copy data to tc buffer
    memcpy(&sun_vec,&data[0],len);

    // Debug print
    printf("Sun Vector X:- %d\n",sun_vec.sun_x);
    printf("Sun Vector Y:- %d\n",sun_vec.sun_y);
    printf("Sun Vector Z:- %d\n",sun_vec.sun_z);

    return len;
}

/**
 * @brief This function extract the Estimation gyro measurement
 */
uint16_t adcs_bsk_ext_tlm_est_gyro_measure(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_est_gyro est_gyro = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_est_gyro);

    // Copy data to tc buffer
    memcpy(&est_gyro,&data[0],len);

    // Debug print
    printf("Estimated X-gyro Bias:- %d\n",est_gyro.est_gyro_x);
    printf("Estimated Y-gyro Bias:- %d\n",est_gyro.est_gyro_y);
    printf("Estimated Z-gyro Bias:- %d\n",est_gyro.est_gyro_z);

    return len;
}

/**
 * @brief This function extract the Estimation innovation vector
 */
uint16_t adcs_bsk_ext_tlm_est_innovation(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_est_innovn est_innovn = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_est_innovn);

    // Copy data to tc buffer
    memcpy(&est_innovn,&data[0],len);

    // Debug print
    printf("Innovation Vector X:- %d\n",est_innovn.innovn_vec_x);
    printf("Innovation Vector Y:- %d\n",est_innovn.innovn_vec_y);
    printf("Innovation Vector Z:- %d\n",est_innovn.innovn_vec_z);

    return len;
}

/**
 * @brief This function extract the Quaternion error vector
 */
uint16_t adcs_bsk_ext_tlm_qutrn_error(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_qutr_error qutr_error = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_qutr_error);

    // Copy data to tc buffer
    memcpy(&qutr_error,&data[0],len);

    // Debug print
    printf("Quaternion Error -Q1:- %d\n",qutr_error.qutr_error_q1);
    printf("Quaternion Error -Q2:- %d\n",qutr_error.qutr_error_q2);
    printf("Quaternion Error -Q3:- %d\n",qutr_error.qutr_error_q3);

    return len;
}

/**
 * @brief This function extract the Quaternion covariance
 */
uint16_t adcs_bsk_ext_tlm_qutrn_covr(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_qutr_covr qutr_covr = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_qutr_covr);

    // Copy data to tc buffer
    memcpy(&qutr_covr,&data[0],len);

    // Debug print
    printf("Quaternion Covariance - Q1:- %d\n",qutr_covr.qutr_covr_q1);
    printf("Quaternion Covariance - Q2:- %d\n",qutr_covr.qutr_covr_q2);
    printf("Quaternion Covariance - Q3:- %d\n",qutr_covr.qutr_covr_q3);

    return len;
}

/**
 * @brief This function extract the Angular rate covariance
 */
uint16_t adcs_bsk_ext_tlm_ang_rate_covr(uint8_t *data)
{
    // Variable decleration
    uint16_t len;
    s_adcs_angl_rate_covr rate_covr = {0};

    // Value assignment to variable
    len = sizeof(s_adcs_angl_rate_covr);

    // Copy data to tc buffer
    memcpy(&rate_covr,&data[0],len);

    // Debug print
    printf("X Angular Rate Covariance:- %d\n",rate_covr.covr_ang_rate_x);
    printf("Y Angular Rate Covariance:- %d\n",rate_covr.covr_ang_rate_y);
    printf("Z Angular Rate Covariance:- %d\n",rate_covr.covr_ang_rate_z);

    return len;
}

/**
 * @brief This function extract the Control mode configuration
 */
void adcs_bsk_ext_tlm_ctrl_mode(uint8_t *data)
{
    // Variable decleration
    s_adcs_ctrl_mode cntrl_mode = {0};
    u_control_mode_param control_param;

    // Copy data to tc buffer
    cntrl_mode.ctrl_mode = data[0];

    printf("Crtl Mode :- %d\n",cntrl_mode.ctrl_mode);

    // Select control mode
    switch(cntrl_mode.ctrl_mode)
    {
        case ADCS_CTRL_MODE_THREE_AXIS:             // 3axis stabilization
        {
            // Copy data to local variable
            memcpy(&control_param.attitude_ctrl, &data[1],
                    sizeof(s_adcs_attitude_angl));
            printf("Roll %lf Pitch %lf Yaw %lf\n",\
                    control_param.attitude_ctrl.roll,\
                    control_param.attitude_ctrl.pitch,\
                    control_param.attitude_ctrl.yaw);
        }
        break;
        case ADCS_CTRL_MODE_TARGET_TRACKING:        // Target tracking
        {
            printf("Target Tracking\n");

            // Copy data to local variable
            memcpy(&control_param.target_track_ctrl, &data[1],
                    sizeof(s_adcs_trck_target));
            printf("Longtitude %f Latitude %f Altitude %f\n",\
                    control_param.target_track_ctrl.long_ref,\
                    control_param.target_track_ctrl.lat_ref,\
                    control_param.target_track_ctrl.alt_ref);
        }
        break;
        case ADCS_CTRL_MODE_SUN_POINTING:           // Sun pointing
        {
            printf("Sun Tracking\n");
        }
        break;
        case ADCS_CTRL_MODE_NADIR_POINTING:         // Nadir pointing
        {
            // Copy data to local variable
            memcpy(&control_param.nadir_point_mode, &data[1], 4);
            printf("Nadir Pointing Mode:- %d\n",\
            control_param.nadir_point_mode);
        }
        break;
        case ADCS_CTRL_MODE_NONE:                   // No control mode
        {
            printf("Control mode none\n");
        }
        break;
        case ADCS_CTRL_MODE_DETUMBLING:             // Detumbling control mode
        {
            printf("Control mode detumbling\n");
        }
        break;
        case ADCS_CTRL_MODE_Y_SPIN_STABILIZATION:   // Y Spin Stabilization
        {
            printf("Control mode Y Spin\n");
        }
        break;
        case ADCS_CTRL_MODE_Z_SPIN_STABILIZATION:   // Z Spin Stabilization
        {
            printf("Control mode Z Spin\n");
        }
        break;
        case ADCS_CTRL_MODE_CUSTOM:                 // Custom control mode
        {
            printf("Control Custom mode\n");
        }
        break;
        default:
        {
            printf("CTRL Default Case\n");
            //data = 1;
        }
        break;
    }
}

/**
 * @brief This function extract the Reaction wheel speed command
 */
void adcs_bsk_ext_tlm_rw_speed_cmd(uint8_t *data)
{
    // Variable decleration
    s_adcs_rw_speed *rw_speed = {0};

    // Assign payload data to the pointer
    rw_speed = (s_adcs_rw_speed*)&data[1];

    printf("Reaction wheel count:- %d\n", data[0]);
    for(int i = 0; i < data[0]; i++)
    {
        // Debug print
        printf("Commanded Wheel %d Speed:- %d\n",i + 1, rw_speed[i].rw_speed);
    }
}

/**
 * @brief This function extract the Reaction wheel speed measurement
 */
void adcs_bsk_ext_tlm_rw_speed_measure(uint8_t *data)
{
    // Variable decleration
    s_adcs_rw_speed *rw_speed = {0};

    // Assign payload data to the pointer
    rw_speed = (s_adcs_rw_speed*)&data[1];

    printf("Reaction wheel count:- %d\n", data[0]);
    for(int i = 0; i < data[0]; i++)
    {
        // Debug print
        printf("Measured Wheel %d Speed:- %d\n",i + 1, rw_speed[i].rw_speed);
    }
}

/**
 * @brief This function extract the telemetry data based on telemetry id.
 */
void unfied_tlm_data_extract(uint8_t *data,uint16_t pld_len,uint8_t id)
{
    if(id >= API_RESP_ID)
    {
        switch(id)
        {
            case API_RESP_ID:                // Get Identification
            {
                adcs_bsk_ext_tlm_id(data);
            }
            break;
            case API_RESP_STATE:             // Get ADCS state
            {
                adcs_bsk_ext_tlm_state(data);
            }
            break;
            case API_RESP_TLE:               // Get TLE
            {
                adcs_bsk_ext_tlm_tle(data);
            }
            break;
            case API_RESP_MOI:               // Get moment of inetria
            {
                adcs_bsk_ext_tlm_moi(data);
            }
            break;
            case API_RESP_PWR:               // Get power configuration
            {
                adcs_bsk_ext_tlm_power(data);
            }
            break;
            case API_RESP_MAG_FIELD_VEC:     // Get magnetic field vector
            {
                adcs_bsk_ext_tlm_mag_vector(data);
            }
            break;
            case API_RESP_CSS_VEC:           // Get CSS vector
            {
                adcs_bsk_ext_tlm_css_sun_vector(data);
            }
            break;
            case API_RESP_FSS_VEC:           // Get FSS vector
            {
                adcs_bsk_ext_tlm_fss_sun_vector(data);
            }
            break;
            case API_RESP_NADIR_VEC:         // Get nadir vector
            {
                adcs_bsk_ext_tlm_nadir_vector(data);
            }
            break;
            case API_RESP_SENSOR_RATE:       // Get sensor rate
            {
                adcs_bsk_ext_tlm_sensor_rate(data);
            }
            break;
            case API_RESP_STAR_TRKR_BVEC:    // Get star tracker body vector
            {
                adcs_bsk_ext_tlm_star_body(data);
            }
            break;
            case API_RESP_STAR_TRKR_OVEC:    // Get star trackere orbit vector
            {
                adcs_bsk_ext_tlm_star_orbit(data);
            }
            break;
            case API_RESP_RAW_NADIR_SEN:     // Get raw nadir sensor meaurement
            {
                adcs_bsk_ext_tlm_raw_nadir(data);
            }
            break;
            case API_RESP_RAW_FSS_SEN:  // Get raw fine sun sensor measurement
            {
                adcs_bsk_ext_tlm_raw_fss(data);
            }
            break;
            case API_RESP_RAW_MAGMTR:   // Get raw magnetometer measurement
            {
                adcs_bsk_ext_tlm_raw_magmtr(data);
            }
            break;
            case API_RESP_RAW_GPS_STS:       // Get raw GPS staus
            {
                adcs_bsk_ext_tlm_raw_gps_status(data);
            }
            break;
            case API_RESP_RAW_GPS_TIME:      // Get raw GPS time
            {
                adcs_bsk_ext_tlm_raw_gps_time(data);
            }
            break;
            case API_RESP_RAW_GPS_X:         // Get raw GPS X axis
            {
                adcs_bsk_ext_tlm_raw_gps_x(data);
            }
            break;
            case API_RESP_RAW_GPS_Y:         // Get raw GPS Y axis
            {
                adcs_bsk_ext_tlm_raw_gps_y(data);
            }
            break;
            case API_RESP_RAW_GPS_Z:         // Get raw GPS Z axis
            {
                adcs_bsk_ext_tlm_raw_gps_z(data);
            }
            break;
            case API_RESP_STAR_MAG:          // Get star magnitude
            {
                adcs_bsk_ext_tlm_star_magnitude(data);
            }
            break;
            case API_RESP_STAR_PERFORM:      // Get star performance
            {
                adcs_bsk_ext_tlm_star_performance(data);
            }
            break;
            case API_RESP_STAR_TIMING:       // Get star timing
            {
                adcs_bsk_ext_tlm_star_timing(data);
            }
            break;
            case API_RESP_RAW_SENS:          // Get raw sensor measurement
            {
                adcs_bsk_ext_tlm_raw_sensor_measure(data);
            }
            break;
            case API_RESP_RAW_GPS:           // Get raw GPS measurement
            {
                adcs_bsk_ext_tlm_raw_gps_measure(data);
            }
            break;
            case API_RESP_RAW_STAR_TRAC:    // Get raw star tracker measurement
            {
                adcs_bsk_ext_tlm_raw_star_measure(data);
            }
            break;
            case API_RESP_STAR_RDATA:        // Get raw star tracker data
            {
                adcs_bsk_ext_tlm_raw_star_data(data);
            }
            break;
            case API_RESP_RAW_SEC_MAGMTR:    // Get raw secondary magnetometer
            {
                adcs_bsk_ext_tlm_sec_raw_magmtr_measure(data);
            }
            break;
            case API_RESP_RAW_SENS_RATE:     // Get raw sensor rates
            {
                adcs_bsk_ext_tlm_raw_rates(data);
            }
            break;
            case API_RESP_STAR_EST_RATE:    // Get star tracker estimation rate
            {
                adcs_bsk_ext_tlm_star_est_rate(data);
            }
            break;
            case API_RESP_SENS_CUR:          // Get sensor current
            {
                adcs_bsk_ext_tlm_sensor_current(data);
            }
            break;
            case API_RESP_CON_CUR:  // Get adcs consumed current measurement
            {
                adcs_bsk_ext_tlm_con_current_measure(data);
            }
            break;
            case API_RESP_RW_CUR:            // Get reaction wheel current
            {
                adcs_bsk_ext_tlm_rw_current(data);
            }
            break;
            case API_RESP_TEMP:              // Get adcs temperature
            {
                adcs_bsk_ext_tlm_temperature(data);
            }
            break;
            case API_RESP_SENS_RATE_TEMP:    // Get rate sensor temperature
            {
                adcs_bsk_ext_tlm_rate_sensor_temperature(data);
            }
            break;
            case API_RESP_POW_TEMP:    // Get power and temperature measurement
            {
                adcs_bsk_ext_tlm_power_temperature(data);
            }
            break;
            case API_RESP_GYRO_CFG:          // Get gyro configuration
            {
                adcs_bsk_ext_tlm_gyro_cfg(data);
            }
            break;
            case API_RESP_STAR_TRAC_CFG:     // Get star tracker configuration
            {
                adcs_bsk_ext_tlm_star_trkr_cgf(data);
            }
            break;
            case API_RESP_MAGMTR_CFG:        // Get magnetometer configuration
            {
                adcs_bsk_ext_tlm_mgmtr_cfg(data);
            }
            break;
            case API_RESP_CSS_CFG:           // Get CSS configuration
            {
                adcs_bsk_ext_tlm_css_cfg(data);
            }
            break;
            case API_RESP_FSS_CFG:           // Get FSS configuration
            {
                adcs_bsk_ext_tlm_fss_cfg(data);
            }
            break;
            case API_RESP_NADIR_CFG:         // Get Nadir configuration
            {
                adcs_bsk_ext_tlm_nadir_cfg(data);
            }
            break;
            case API_RESP_RED_MAGMTR_CFG:    // Get Redudant magnetometer
            {
                adcs_bsk_ext_tlm_red_mgmtr_cfg(data);
            }
            break;
            case API_RESP_MGNTRQR_CFG:       // Get magnetorquer configuration
            {
                adcs_bsk_ext_tlm_mgntrqr_cfg(data);
            }
            break;
            case API_RESP_RW_CFG:           // Get reaction wheel configuration
            {
                adcs_bsk_ext_tlm_rw_cfg(data);
            }
            break;
            case API_RESP_DETUMBLE_CTRL:     // Get detumble parameters
            {
                adcs_bsk_ext_tlm_detumble_param(data);
            }
            break;
            case API_RESP_Y_RW_CTRL:         // Get Y reaction wheel control
            {
                adcs_bsk_ext_tlm_y_rw_ctrl(data);
            }
            break;
            case API_RESP_RW_CTRL:           // Get reaction wheel control
            {
                adcs_bsk_ext_tlm_rw_ctrl(data);
            }
            break;
            case API_RESP_TRCK_CTRL_GAIN:    // Get tracking control gain
            {
                adcs_bsk_ext_tlm_trck_ctrl_gain(data);
            }
            break;
            case API_RESP_ATTITUDE_ANGL:     // Get attitude angle
            {
                adcs_bsk_ext_tlm_attitude(data);
            }
            break;
            case API_RESP_TRCK_TARGET:       // Get target tracking parameters
            {
                adcs_bsk_ext_tlm_target_track(data);
            }
            break;
            case API_RESP_INRTL_REF:         // Get inertial reference
            {
                adcs_bsk_ext_tlm_inertial_ref(data);
            }
            break;
            case API_RESP_EST_PARAM:         // Get estimation paremeters
            {
                adcs_bsk_ext_tlm_est_param(data);
            }
            break;
            case API_RESP_POS_ECI:           // Get sattelite position ECI
            {
                adcs_bsk_ext_tlm_eci_postition(data);
            }
            break;
            case API_RESP_VEL:               // Get sattelite velocity
            {
                adcs_bsk_ext_tlm_sat_velocity(data);
            }
            break;
            case API_RESP_POS_LLH:           // Get sattelte position LLH
            {
                adcs_bsk_ext_tlm_llh_psition(data);
            }
            break;
            case API_RESP_EST_RATE:          // Get estimation rates
            {
                adcs_bsk_ext_tlm_est_rate(data);
            }
            break;
            case API_RESP_EST_QUTRN:         // Get estimated quaternion
            {
                adcs_bsk_ext_tlm_est_qutrn(data);
            }
            break;
            case API_RESP_ECEF_POS:          // Get ECEF sattelite position
            {
                adcs_bsk_ext_tlm_ecef_position(data);
            }
            break;
            case API_RESP_MODL_MAG:     // Get moduled magnetic field vector
            {
                adcs_bsk_ext_tlm_mod_mag_vector(data);
            }
            break;
            case API_RESP_MODL_SUN:          // Get moduled sun vector
            {
                adcs_bsk_ext_tlm_mod_sun_vector(data);
            }
            break;
            case API_RESP_EST_GYRO:          // Get estimated gyro measurement
            {
                adcs_bsk_ext_tlm_est_gyro_measure(data);
            }
            break;
            case API_RESP_EST_INNOVN:        // Get estimation innovation
            {
                adcs_bsk_ext_tlm_est_innovation(data);
            }
            break;
            case API_RESP_QUTR_ERROR:        // Get quaternion error vector
            {
                adcs_bsk_ext_tlm_qutrn_error(data);
            }
            break;
            case API_RESP_QUTR_COVR:         // Get quaternion covariance
            {
                adcs_bsk_ext_tlm_qutrn_covr(data);
            }
            break;
            case API_RESP_ANGL_COVR:         // Get angular rate covariance
            {
                adcs_bsk_ext_tlm_ang_rate_covr(data);
            }
            break;
            case API_RESP_CTRL_MODE:
            {
                adcs_bsk_ext_tlm_ctrl_mode(data);
            }
            break;
            case API_RESP_RW_SPEED:
            {
                adcs_bsk_ext_tlm_rw_speed_cmd(data);
            }
            break;
            case API_RESP_RW_SPEED_MEASURE:
            {
                adcs_bsk_ext_tlm_rw_speed_measure(data);
            }
            break;
            default:
            {
                printf("ADCS: Decoding Function not available for this TM Id:- %u\n",id);
            }
            break;
        }
    }
}
