/**
 * @file comms_xband_api.c
 *
 * @brief This file contains APIs for S-Band parameters configuration
 *        programming and readback
 *
 * @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 <stdio.h>
#include "exo_types.h"
#include "exo_common.h"
#include "xband_main.h"
#include "xband_xlink_ss.h"
#include "xband_xlink_api.h"
#include "xband_xlink_rfe_ctr.h"
#include "xband_ipc.h"
#include "xband_ipc.h"
#include "logger.h"
#include "exo_tctm_ipc.h"


/*##########################################################################################*/
/*************	Variable Declaration									*********************/
/*##########################################################################################*/
// ==> we place the variable declaration outside of the defgroup ServiceServer, otherwise we will see them twice in the DOXYGEN documentation !!
// // for this we create the defgroup ServiceServerVariablePub in the ServiceServer.c file where we define the variables
// // ==> The same applies to functions as soon as the description header differs in ServiceServer.h and ServiceServer.c!!

uint32 PLACE_IN_EXT_RAM_MEM NumByteForAi;
uint32 PLACE_IN_EXT_RAM_MEM NumByteForAiHigh;
uint32 PLACE_IN_EXT_RAM_MEM NumByteForAiLow;

uint32 lastProductKey[4] = {0xc9c694fb,0xdeac9b61,0x19ea8546,0x09c58891};		//!< last valid product key to save computing power

uint8 PLACE_IN_EXT_RAM_MEM need_ss;			//!< ServiceServer use \sa SS_IDLE, SS_TCP, SS_UDP, SS_CSP

uint32 PLACE_IN_EXT_RAM_MEM RcvDataServerTimeout;		//!< Timeout for ARP request
uint32 PLACE_IN_EXT_RAM_MEM RcvDataIPAdr;			//!< Destination IP-Address for RF RcvData
uint32 PLACE_IN_EXT_RAM_MEM RcvDataIPPort;			//!< Destination Port for RF RcvData
uint8  PLACE_IN_EXT_RAM_MEM RcvDataIPFormat;		//!< Received data can be send in different formats

//   (RF_RCV_SEND_FORMAT_RAW, RF_RCV_SEND_FORMAT_INFO, RF_RCV_SEND_FORMAT_DEBUG)
uint8 PLACE_IN_EXT_RAM_MEM  RcvDataServerMacAdr[6];	//!< Destination MAC Address for RF RcvData

SERVICE_COMMON_TC_STRUCT  PLACE_IN_EXT_RAM_MEM	global_serv_tc;
SERVICE_COMMON_STRUCT  	  PLACE_IN_EXT_RAM_MEM	global_serv_common;
SERVICE_IDLE_STRUCT	  PLACE_IN_EXT_RAM_MEM	global_serv_idle;
SERVICE_RESET_STRUCT	  PLACE_IN_EXT_RAM_MEM	global_serv_reset;
SERVICE_IP_ADR_STRUCT     PLACE_IN_EXT_RAM_MEM  global_serv_ip_adr;
SERVICE_VERSION_STRUCT	  PLACE_IN_EXT_RAM_MEM   global_serv_version;
SERVICE_START_RF_RCV_STRUCT PLACE_IN_EXT_RAM_MEM global_serv_start_rf_rcv;
SERVICE_RF_XMT_DATA_STRUCT  PLACE_IN_EXT_RAM_MEM global_serv_rf_xmt_data;
SERVICE_DEVICE_CONF_STRUCT  PLACE_IN_EXT_RAM_MEM global_serv_device_conf;
SERVICE_HOUSE_KEEP_STRUCT   PLACE_IN_EXT_RAM_MEM global_serv_house_keep;
SERVICE_FEATURE_SELECT_STRUCT PLACE_IN_EXT_RAM_MEM global_serv_feature_select;
SERVICE_DVBS2_CONF_STRUCT    PLACE_IN_EXT_RAM_MEM  global_serv_dvbs2_cfg;

/*	Service_Validate_Key					*************************************************/
/**
 * @ingroup	ServiceServerFunctionPub
 * @brief	checks if service_server is not blocked and received key is valid. For next service
 * 			server processing commands, the received features are stored temporary!
 *
 * @param	[in] RcvData (Pointer to the received service_data)
 *
 * @return	-1 if key is invalid, -2 if processing blocked, 0 if succeed/valid
 * @note		Its recommended to call this function before next service processing
 * 			functions are called! (because of features)
 *********************************************************************************************/
int8 Service_Validate_Key(uint8 *RcvData)
{
    uint8 i = 0,status=0;
    uint32 rcvd_key[4];
    os_memcpy(rcvd_key,RcvData,16);

    for(i=0;i<4;i++)
    {
        if(rcvd_key[i] == lastProductKey[i])
        {
            DEBUG_CPRINT(("\n\r key matched rcvd_key[%d]: %x",i,rcvd_key[i]));
            log_id_with_two_arg(LOG_INFO_L1,LOG_COMMS,KEY_MATCHED_RCVD_KEY__u8__u32_,i,rcvd_key[i]);
            status =1;
        }
        else
        {
            DEBUG_CPRINT(("\n\r key mis-matched rcvd_key[%d]: %x",i,rcvd_key[i]));
            log_id_with_two_arg(LOG_INFO_L1,LOG_COMMS,KEY_MIS_MATCHED_RCVD_KEY__u8__u32_,i,rcvd_key[i]);
            status = -1;
            break;
        }
    }
    return status;

}

/*	Service_Idle					*********************************************************/
/**
 * @ingroup	ServiceServerFunctionPub
 * @brief	processes a received SERVICE_IDLE command
 *
 * @param	[in] RcvData (Pointer to TcpRcvData after service_event)
 * @param	[in]  uint32 DataRead (number of received bytes in TCP Buffer)
 *
 * @return	number of bytes which processed
 * @note		none
 *********************************************************************************************/
uint32 Service_Idle(uint8 *RcvData, uint32 DataRead)
{
    return 0;

}

/*	Service_Reset					*********************************************************/
/**
 * @ingroup	ServiceServerFunctionPub
 * @brief	processes a received SERVICE_RESET command
 *
 * @param	[in] RcvData (Pointer to TcpRcvData after service_event)
 * @param	[in]  uint32 DataRead (number of received bytes in TCP Buffer)
 *
 * @return	number of bytes which processed
 * @note		none
 *********************************************************************************************/
uint32 Service_Reset(uint8 *RcvData, uint32 DataRead)
{
	return 0;
}

/*	Service_XmtData					*********************************************************/
/**
 * @ingroup	ServiceServerFunctionPub
 * @brief	processes a received SERVICE_RF_XMT_DATA command
 *
 * @param	[in] RcvData (Pointer to TcpRcvData -> service_event)
 * @param	[in]  uint32 DataRead (number of received bytes in TCP Buffer)
 *
 * @return	number of bytes which processed, 0- No Data processed or -1 if Error
 *
 * @note		count down NumByteForAi for test with reduced throughput -> TCP-Break
 *			==> no AiRcv and AiXmt Processing; no ADC-DMA is running -> for 10ms interval
 *			==> CountDown * 8Bit * 100(10ms Tick) = Mbits/s
 *
 *			-> max. 350000 => 280MBits/s
 *			350000 -> @1.000ms timer_tick -> ~168MBits/s @ 61% CPU-Load
 *			350000 -> @0.500us timer_tick -> ~256MBits/s @ 95% CPU-Load
 *			350000 -> @0.333us timer_tick -> ~280MBits/s @ 99% CPU-Load
 *
 *			-> min. < 5500 could be a problem for the other side because long TCP-Break (>1s)
 *			500    -> @1.000ms timer_tick -> 400kBits/s @ 2.0% CPU-Load (smaller basic load)
 *			500    -> @0.500ms timer_tick -> 400kBits/s @ 3.3% CPU-Load
 *			500    -> @0.333ms timer_tick -> 400kBits/s @ 4.7% CPU-Load (more throughput possible)
 *
 *********************************************************************************************/
int32 Service_XmtData(uint8 *RcvData, uint32 DataRead)
{
	return 0;
}


/*	Service_DevConf				*************************************************************/
/**
 * @ingroup	ServiceServerFunctionPub
 * @brief	processes a received SERVICE_DEVICE_CONF command
 *
 * @param	[in] RcvData (Pointer to TcpRcvData after service_event)
 * @param	[in] uint32 DataRead (number of received bytes in TCP Buffer)
 *
 * @return	number of bytes which processed
 * @note		Call Service_Validate_Key function before, to ensure features are filled
 *********************************************************************************************/
uint32 Service_DevConf(uint8 *RcvData, uint32 DataRead)
{
	return 0;
}


/*	Service_GetFeatureSel		*************************************************************/
/**
 * @ingroup	ServiceServerFunctionPub
 * @brief	processes a received SERVICE_FEATURE_SELECT command
 *
 * @param	[in] RcvData (Pointer to TcpRcvData after service_event)
 * @param	[in] uint32 DataRead (number of received bytes in TCP Buffer)
 *
 * @return	number of bytes which processed
 * @note		Call Service_Validate_Key function before, to ensure features are filled
 *********************************************************************************************/
uint32 Service_GetFeatureSel(uint8 *RcvData, uint32 DataRead)
{
	return 0;
}

/*	Service_GetHouseKeep		*************************************************************/
/**
 * @ingroup	ServiceServerFunctionPub
 * @brief	processes a received SERVICE_HOUSE_KEEP command
 *
 * @param	[in] RcvData (Pointer to TcpRcvData after service_event)
 * @param	[in] uint32 DataRead (number of received bytes in TCP Buffer)
 *
 * @return	number of bytes which processed
 * @note		none
 *********************************************************************************************/
uint32 Service_GetHouseKeep(uint8 *RcvData, uint32 DataRead)
{
	return 0;
}

/*	Service_StartRfRcv			*************************************************************/
/**
 * @ingroup	ServiceServerFunctionPub
 * @brief	processes a received SERVICE_START_RF_RCV command
 *
 * @param	[in] RcvData (Pointer to TcpRcvData after service_event)
 * @param	[in] uint32 DataRead (number of received bytes in TCP Buffer)
 *
 * @return	number of bytes which processed
 * @note		none
 *********************************************************************************************/
uint32 Service_StartRfRcv(uint8 *RcvData, uint32 DataRead)
{
	return 0;
}


/*	Service_Version				*************************************************************/
/**
 * @ingroup	ServiceServerFunctionPub
 * @brief	processes a received SERVICE_VERSION command
 *
 * @param	[in] RcvData (Pointer to TcpRcvData after service_event)
 * @param	[in] uint32 DataRead (number of received bytes in TCP Buffer)
 *
 * @return	number of bytes which processed
 * @note		none
 *********************************************************************************************/
uint32 Service_Version(uint8 *RcvData, uint32 DataRead)
{
	return 0;
}

/*	Service_IpAdr				*************************************************************/
/**
 * @ingroup	ServiceServerFunctionPub
 * @brief	processes a received SERVICE_IP_ADR or SERVICE_IP_ADR_SAVE command
 *
 * @param	[in] RcvData (Pointer to TcpRcvData after service_event)
 * @param	[in] uint32 DataRead (number of received bytes in TCP Buffer)
 *
 * @return	number of bytes which processed
 * @note		none
 *********************************************************************************************/
uint32 Service_IpAdr(uint8 *RcvData, uint32 DataRead)
{
	return 0;
}

/**
 * @brief This function is used for processing the telecommand and
 *       send request to X-Band module via PS IPCC interface
 */
uint32 xband_proc_tc(uint32 serv_event)
{
    os_memcpy(global_serv_tc.product_key,lastProductKey,sizeof(lastProductKey));
    global_serv_tc.service_event = serv_event;

    xband_send_ipc_pld(XBAND_OBC_IPCC_SEND_REQ,OBC_IPCC_SEND,sizeof(SERVICE_COMMON_TC_STRUCT),(uint8_t*)&global_serv_tc);
    return 0;
}

uint8_t PLACE_IN_EXT_RAM_MEM xband_tm_buff[1024];
/**
 * @brief This function is used for processing the telecommand and
 *       send request to X-Band module via PS IPCC interface
 */
uint32 xband_proc_tc_pld(uint32 serv_event, uint8 *pld)
{
    switch(serv_event & 0x0F)
    {
        case SERVICE_DEVICE_CONF:
            {
                os_memcpy(global_serv_device_conf.product_key,lastProductKey,sizeof(lastProductKey));
                global_serv_device_conf.service_event = serv_event;
                os_memcpy(((uint8 *)(&global_serv_device_conf.HwPins)),pld,((sizeof(SERVICE_DEVICE_CONF_STRUCT))-(sizeof(uint32 )* 5)));
                 //xband_tm_buff[0] =  MAX_SER_DEVICE_PRODUCT_KEY_CNT;
                 //xband_tm_buff[1] =  MAX_SER_DEVICE_RCVCTRCH_CNT; 
                //os_memcpy(&xband_tm_buff[2],&global_serv_device_conf,sizeof(SERVICE_DEVICE_CONF));


                xband_send_ipc_pld(XBAND_OBC_IPCC_SEND_REQ,OBC_IPCC_SEND,sizeof(SERVICE_DEVICE_CONF_STRUCT),(uint8_t*)&global_serv_device_conf);
            }
            break;

        case SERVICE_VERSION:
            {
                os_memcpy(global_serv_version.product_key,lastProductKey,sizeof(lastProductKey));
                global_serv_version.service_event = serv_event;
                os_memcpy(((uint8 *)(&global_serv_version.prog_version)),pld,((sizeof(SERVICE_VERSION_STRUCT))-(sizeof(uint32) * 5)));
                 //xband_tm_buff[0] =  MAX_SER_VER_PRODUCT_KEY_CNT ;
                  //os_memcpy(&xband_tm_buff[1],&global_serv_version,sizeof(SERVICE_VERSION));

                xband_send_ipc_pld(XBAND_OBC_IPCC_SEND_REQ,OBC_IPCC_SEND,sizeof(SERVICE_VERSION_STRUCT),(uint8_t*)&global_serv_version);
            }
            break;

        case SERVICE_IP_ADR:
        case SERVICE_IP_ADR_SAVE:
            {
                os_memcpy(global_serv_ip_adr.product_key,lastProductKey,sizeof(lastProductKey));
                global_serv_ip_adr.service_event = serv_event;
                os_memcpy(((uint8 *)(&global_serv_ip_adr.ip_address)),pld,(sizeof(uint32)));

                //xband_tm_buff[0] =  MAX_SER_IP_PRODUCT_KEY_CNT;
                //os_memcpy(&xband_tm_buff[1],&global_serv_ip_adr,sizeof(SERVICE_IP_ADR_STRUCT));

                xband_send_ipc_pld(XBAND_OBC_IPCC_SEND_REQ,OBC_IPCC_SEND,sizeof(SERVICE_IP_ADR_STRUCT),(uint8_t*)&global_serv_ip_adr);
            }
            break;

#if 0
            /** SET option is not available in current documentation */
        case SERVICE_FLAGS_CONF:
            {
                os_memcpy(global_serv_.product_key,lastProductKey,sizeof(lastProductKey));
                global_serv_tc.service_event = serv_event;
                os_memcpy(&global_serv_ip_adr.ip_address,pld,(sizeof(uint32)));

                xband_send_ipc_pld(XBAND_OBC_IPCC_SEND_REQ,OBC_IPCC_SEND,sizeof(SERVICE_VERSION_STRUCT),&global_serv_ip_adr);
            }
            break;
#endif
        case SERVICE_DVBS2_CONF:
            {
                os_memcpy(global_serv_dvbs2_cfg.product_key,lastProductKey,sizeof(lastProductKey));
                global_serv_dvbs2_cfg.service_event = serv_event;

                os_memcpy(((uint8 *)(&global_serv_dvbs2_cfg.service_event)) + sizeof(uint32),pld,((sizeof(SERVICE_DVBS2_CONF_STRUCT))-(sizeof(uint32 )* 5)));

                //xband_tm_buff[0] =  MAX_SER_DVB_PRODUCT_KEY_CNT;
                //os_memcpy(&xband_tm_buff[1],&global_serv_dvbs2_cfg,sizeof(SERVICE_DVBS2_CONF));

                xband_send_ipc_pld(XBAND_OBC_IPCC_SEND_REQ,OBC_IPCC_SEND,sizeof(SERVICE_DVBS2_CONF_STRUCT),(uint8_t*)&global_serv_dvbs2_cfg);
            }
            break;

        case SERVICE_START_RF_RCV:
            {
                os_memcpy(global_serv_start_rf_rcv.product_key,lastProductKey,sizeof(lastProductKey));
                global_serv_start_rf_rcv.service_event = serv_event;
                os_memcpy(((uint8 *)&global_serv_start_rf_rcv.ip_address),pld,((sizeof(SERVICE_START_RF_RCV_STRUCT))-(sizeof(uint32 )* 5)));
                //xband_tm_buff[0] =  MAX_SER_START_PRODUCT_KEY_CNT;
                //os_memcpy(&xband_tm_buff[1],&global_serv_start_rf_rcv,sizeof(SERVICE_START_RF_RCV));

                xband_send_ipc_pld(XBAND_OBC_IPCC_SEND_REQ,OBC_IPCC_SEND,sizeof(SERVICE_START_RF_RCV_STRUCT),(uint8_t*)&global_serv_start_rf_rcv);
            }
            break;

        case SERVICE_RF_XMT_DATA:
            {
                os_memcpy(global_serv_rf_xmt_data.product_key,lastProductKey,sizeof(lastProductKey));
                global_serv_rf_xmt_data.service_event = serv_event;
                os_memcpy((uint8 *)(&global_serv_rf_xmt_data.service_event) + (sizeof(uint32)) ,pld,((sizeof(SERVICE_RF_XMT_DATA_STRUCT))-(sizeof(uint32 )* 5)));
                // xband_tm_buff[0] =  MAX_SER_RF_XMT_PRODUCT_KEY_CNT;
                 //xband_tm_buff[1] =  (uint8_t)MAX_SER_RF_PAYLOAD_CNT & 0xff;
                 //xband_tm_buff[2] =  (uint8_t)MAX_SER_RF_PAYLOAD_CNT >> 8;

                //os_memcpy(&xband_tm_buff[3],&global_serv_rf_xmt_data,sizeof(SERVICE_RF_XMT_DATA));

                xband_send_ipc_pld(XBAND_OBC_IPCC_SEND_REQ,OBC_IPCC_SEND,sizeof(SERVICE_RF_XMT_DATA_STRUCT),(uint8_t*)&global_serv_rf_xmt_data);
            }
            break;
    }
    return 0;

}


/**
 * @brief This function is used for processing the control information received
 *        from X-Band module via IPCC interface
 */
uint32 xband_proc_rcv_data(uint8 *RcvData)
{
    int8 icd_rsp_status = (int8)(*RcvData);
    uint8 status = 0;
    uint16 tm_size = 0;
    CPRINT_VARIABLE_UNUSED(icd_rsp_status);
    CPRINT_VARIABLE_UNUSED(status);
    CPRINT_VARIABLE_UNUSED(tm_size);

    DEBUG_CPRINT(("\nReceived X-Band ICD response : %d \n",icd_rsp_status));
    log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,RECEIVED_X_BAND_ICD_RESPONSE__s8_,icd_rsp_status);


    SERVICE_COMMON_STRUCT *rcv_data = NULL;

    rcv_data = (SERVICE_COMMON_STRUCT*)(RcvData + sizeof(int8));

    status = Service_Validate_Key((uint8*)rcv_data);

    if(status)
    {
        DEBUG_CPRINT(("\n\r Received Service event: %x",rcv_data->service_event));
        log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,RECEIVED_SERVICE_EVENT__u32_,rcv_data->service_event);

        if(SERVICE_ACK == (0xC0000000 & rcv_data->service_event))
        {
            status = XBAND_TM_SUCCESS;
        }
        else if(SERVICE_NAK == (0xC0000000 & rcv_data->service_event))
        {
            status = XBAND_TM_FAILURE;
        }
        else if(SERVICE_BUSY == (0xC0000000 & rcv_data->service_event))
        {
            status = XBAND_TM_BUSY;
        }

        DEBUG_CPRINT(("\r\n X-Band response status: %d",status));
        log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,X_BAND_RESPONSE_STATUS__s8_,status);

        switch(rcv_data->service_event & 0x3FFFFFFF)
        {
            case (SERVICE_SET | SERVICE_IDLE):
                {
                    xband_tc_tm_set_rsp_hdlr(TM_XBAND_SET_IDLE_CFG,status);
                }
                break;
            case (SERVICE_SET | SERVICE_DEVICE_CONF):
                {
                    xband_tc_tm_set_rsp_hdlr(TM_XBAND_SET_DEVICE_CONF,status);
                }
                break;
            case (SERVICE_SET | SERVICE_VERSION):
                {
                    xband_tc_tm_set_rsp_hdlr(TM_XBAND_SET_VERSION,status);
                }
                break;
            case (SERVICE_SET | SERVICE_IP_ADR):
                {
                    xband_tc_tm_set_rsp_hdlr(TM_XBAND_SET_IP_ADR,status);
                }
                break;
            case (SERVICE_SET | SERVICE_IP_ADR_SAVE):
                {
                    xband_tc_tm_set_rsp_hdlr(TM_XBAND_SET_IP_ADR_SAVE,status);
                }
                break;
            case (SERVICE_SET | SERVICE_FLAGS_CONF):
                {
                    xband_tc_tm_set_rsp_hdlr(TM_XBAND_SET_FLAGS_CONF,status);
                }
                break;
            case (SERVICE_SET | SERVICE_DVBS2_CONF):
                {
                    xband_tc_tm_set_rsp_hdlr(TM_XBAND_SET_DVBS2_CONF,status);
                }
                break;
            case (SERVICE_SET | SERVICE_START_RF_RCV):
                {
                    xband_tc_tm_set_rsp_hdlr(TM_XBAND_SET_START_RF_RCV,status);
                }
                break;
            case (SERVICE_SET | SERVICE_RF_XMT_DATA):
                {
                    xband_tc_tm_set_rsp_hdlr(TM_XBAND_SET_RF_XMT_DATA,status);
                }
                break;
            case (SERVICE_SET | SERVICE_RESET):
                {
                    xband_tc_tm_set_rsp_hdlr(TM_XBAND_SET_RESET,status);
                }
                break;
            case (SERVICE_GET | SERVICE_HOUSE_KEEP):
                {
                    tm_size = sizeof(SERVICE_HOUSE_KEEP_STRUCT);
                    os_memcpy(&global_serv_house_keep,rcv_data,tm_size);

                    tm_size = tm_size - 6*sizeof(uint32);
                    
                    xband_tm_buff[0] =  MAX_HSEKEEP_VOLT_CNT;
                    xband_tm_buff[1] =  MAX_HSEKEEP_RCV_INTF_CNT;
                    xband_tm_buff[2] =  MAX_HSEKEEP_XMT_INTF_CNT;
                    os_memcpy(&xband_tm_buff[3],&global_serv_house_keep.HouseKeep,tm_size);
                    
                    //xband_tc_tm_get_rsp_hdlr(TM_XBAND_GET_HOUSE_KEEP,status,tm_size,(uint8_t*)&global_serv_house_keep.HouseKeep);
                    xband_tc_tm_get_rsp_hdlr(TM_XBAND_GET_HOUSE_KEEP,status,tm_size+3,(uint8_t*)&xband_tm_buff[0]);
                }
                break;
            case (SERVICE_GET | SERVICE_XPA_INF):
                {
                    //tm_size = sizeof(SERVICE_XPA_INF);
                    //os_memcpy(global_ser,rcv_data,tm_size);

                    xband_tc_tm_set_rsp_hdlr(TM_XBAND_GET_XPA_INF,status);
                }
                break;
            case (SERVICE_GET | SERVICE_FEATURE_SELECT):
                {
                    tm_size = sizeof(SERVICE_FEATURE_SELECT_STRUCT);
                    os_memcpy(&global_serv_feature_select,rcv_data,tm_size);

                    tm_size = tm_size - 5*sizeof(uint32);

                    xband_tc_tm_get_rsp_hdlr(TM_XBAND_GET_FEATURE_SELECT,status,tm_size,(uint8_t*)&global_serv_feature_select.feature_select);
                }
                break;
            case (SERVICE_GET | SERVICE_IP_ADR):
                {
                    tm_size = sizeof(SERVICE_IP_ADR_STRUCT);
                    os_memcpy(&global_serv_ip_adr,rcv_data,tm_size);
                    tm_size = 4;

                    xband_tc_tm_get_rsp_hdlr(TM_XBAND_GET_IP_ADR,status,tm_size,(uint8_t*)&global_serv_ip_adr.ip_address);
                }
                break;
            case (SERVICE_GET | SERVICE_DEVICE_CONF):
                {
                    tm_size = sizeof(SERVICE_DEVICE_CONF_STRUCT);
                    os_memcpy(&global_serv_device_conf,rcv_data,tm_size);

                    tm_size = tm_size - 5*sizeof(uint32);

                    xband_tc_tm_get_rsp_hdlr(TM_XBAND_GET_DEVICE_CONF,status,tm_size,(uint8_t*)&global_serv_device_conf.HwPins);
                }
                break;
            case (SERVICE_GET | SERVICE_VERSION):
                {
                    tm_size = sizeof(SERVICE_VERSION_STRUCT);
                    os_memcpy(&global_serv_version,rcv_data,tm_size);

                    tm_size = tm_size - 5*sizeof(uint32);
                    xband_tm_buff[0] =  MAX_SER_FILENAME_CNT;
                    os_memcpy(&xband_tm_buff[1],&global_serv_version.prog_version,tm_size);

                    //xband_tc_tm_get_rsp_hdlr(TM_XBAND_GET_VERSION,status,tm_size,(uint8_t*)&global_serv_version.prog_version);
                    xband_tc_tm_get_rsp_hdlr(TM_XBAND_GET_VERSION,status,tm_size+1,(uint8_t*)&xband_tm_buff[0]);
                }
                break;
            case (SERVICE_GET | SERVICE_FLAGS_CONF):
                {
                    //tm_size = sizeof(SERVICE_FLAGS_CONF);
                    //os_memcpy(global_serv_flags_conf,rcv_data,tm_size);

                   // xband_tc_tm_get_rsp_hdlr(TM_XBAND_GET_FLAGS_CONF,status);
                }
                break;

        }

    }
    return 0;

}


