/**
 * @file mfcc_csp_intf.c
 *
 * @brief #TODO
 *
 * #TODO
 *
 */
/*********************************************************************/
#include "csp/interfaces/csp_if.h"
#include "csp/arch/csp_time.h"
#include"errno.h"
#include <csp/csp.h>
#include <mfcc_tc_tm_sample.h>
#include <mfcc_csp_intf.h>
#include "csp/interfaces/csp_if_slgnd_tcp.h"

extern s_sock_info tctm_soc_inf;
volatile uint8_t csp_setup_done =0;

/** UHF module SRC/DST addresses*/
#define UHF_UART_TX_ADDRESS 15

/** UHF module port numbers */
#define UHF_CSP_TX_DATA_PORT 25
#define UHF_CSP_RX_DATA_PORT 35

#ifndef CAN_BYPASS
/** SRS-4 module port numbers */
#define SRS4_CSP_TX_DATA_PORT 40
#define SRS4_CSP_RX_DATA_PORT 20
#else

#define SRS4_CSP_TX_DATA_PORT 41
#define SRS4_CSP_RX_DATA_PORT 21

#endif

void CSP_Setup(void)
{
    int status = 0;
    status=status;
    if(csp_setup_done != 1)
    {
#if 0
        printf("\n\rInitialising CSP\n");
#endif
        csp_conf_t *csp_conf1 = malloc(sizeof(csp_conf_t));
        /* Add interface(s) */
        csp_iface_t * default_iface = NULL;
        csp_conf_get_defaults(csp_conf1);

#ifdef CAN_BYPASS
#ifdef SBAND_SIM
        csp_conf1->address = 12;
#elif UHF_SIM 
        csp_conf1->address = 15;
#elif UHF_GS_SIM
        csp_conf1->address = 15;
#elif BACKDOOR_SOCK_SIM 
        csp_conf1->address = 12;
#elif IQS_S_SIM
        csp_conf1->address = 12;
#endif
#endif
        printf("GS CSP Node Address:%d",csp_conf1->address);
        /* Init CSP */
        csp_conf1->buffer_data_size = 1450*8;
        csp_init(csp_conf1);

        /* Start router */
        int res = csp_route_start_task(100, 10);
        res=res;
#if 0
        if (res != CSP_ERR_NONE) {
            printf("csp_route_start_task() %d", res);
        }
#endif

        char radio_host[50];
        strcpy(radio_host,tctm_soc_inf.ip_addr);
        strcat(radio_host,":");
        strcat(radio_host,tctm_soc_inf.port_num);

#ifndef GS_OBC_TCP
        printf("\n[UDP] host_addr : %s\n", radio_host);
        status = csp_slgnd_init_udp(radio_host, NULL, &default_iface);
#else
        printf("\n[TCP] host_addr : %s\n", radio_host);
        status = csp_slgnd_init_tcp(radio_host,tctm_soc_inf.ip_addr, NULL, &default_iface);
#endif
        csp_rtable_set(csp_conf1->address, 0, default_iface, CSP_NO_VIA_ADDRESS);

        csp_route_set(CSP_DEFAULT_ROUTE,default_iface , CSP_NO_VIA_ADDRESS);

#if 0
        printf("Connection table\r\n");
        csp_conn_print_table();

        printf("Interfaces\r\n");
        csp_iflist_print();

        printf("Route table\r\n");
        csp_rtable_print();
#endif
        free(csp_conf1);
        csp_conf1 = NULL;
        csp_setup_done = 1;
    }
}

int32_t csp_send_tm(uint8_t* tm_data, uint16_t len)
{
    csp_conn_t *conn;
    csp_packet_t *packet;
    size_t sent = 0, datasize, remain=0;
#if 0 
    int i=0, j = 0,received=0;
    i=i;
    j=j;
    received=received;
#endif
    remain=remain;
#ifdef UHF_GS_SIM
    conn = csp_connect(CSP_PRIO_NORM, SRS4_SPACE_ADDRESS, UHF_CSP_TX_DATA_PORT , SRS4_DEFAULT_TIMEOUT, CSP_O_NONE);
#else
    conn = csp_connect(CSP_PRIO_NORM, SRS4_SPACE_ADDRESS, SRS4_CSP_TX_DATA_PORT , SRS4_DEFAULT_TIMEOUT, CSP_O_NONE);
#endif
    if (!conn)
    {
        printf("\nERROR Connection refused \n");
        return -ECONNREFUSED;
    }

    remain = (len + SRS4_CAN_MTU - 1) / SRS4_CAN_MTU;

    while (sent < len) {
        if (len - sent > SRS4_CAN_MTU)
            datasize = SRS4_CAN_MTU;
        else
            datasize = len - sent;
        packet = csp_buffer_get(datasize);
        if (!packet) {
            csp_close(conn);
            printf("\nERROR no memory \n");
            return -ENOMEM;
        }

        memcpy(packet->data, &tm_data[sent], datasize);
        packet->length = datasize;

#if 0
        printf("data size is %d\n", datasize);

        for(i = sent; i<=datasize; i++)
        {
            printf("tm_data[%d] : %d \r\n",i,tm_data[i]);
        }
        printf(" value of packet->length is %d\r\n", packet->length);
        printf(" value of packet->id is %x\r\n", packet->id);

        for(j = 0; j<=packet->length; j++)
        {
            printf("packet[%d] = %x \r\n",j,packet[j]);
        }/*
            packet[0] = 0;
            packet[1] = 0xc80101;
            packet[2] = 0;
            packet[3] = 0;
            packet[4] = 0;
            packet[5] = 0;
            packet[6] = 0;*/
#endif

        if (!csp_send(conn, packet, SRS4_DEFAULT_TIMEOUT)) {
            csp_buffer_free(packet);
            csp_close(conn);
            return -EIO;
        }
        sent += datasize;
    }

    csp_buffer_free(packet);

    csp_close(conn);

    return 0;
}

int32_t csp_recv_tc(void)
{
    csp_conn_t *conn;
    csp_packet_t *packet;
//    size_t sent = 0, received = 0, datasize, remain;
 //   int i, j = 0;

    csp_socket_t *sock;

    sock = csp_socket(CSP_SO_NONE);

    /* Create socket with no specific socket options, e.g. accepts CRC32, HMAC, etc. if enabled during compilation */

    /* Bind socket to all ports, e.g. all incoming connections will be handled here */
    csp_bind(sock, CSP_ANY);

    /* Create a backlog of 10 connections, i.e. up to 10 new connections can be queued */
    csp_listen(sock, 10);

    //uint8_t tm_data[10] = {0};

    /** dummy transmission to establish sync on the CSP */
    // csp_send_tm(tm_data,10);


    while (1)
    {
        if ((conn = csp_accept(sock, 1)) == NULL) {
            /* timeout */
            usleep(100);
            //osDelay(1);
            //return;
        }

        while ((packet = csp_read(conn, 1)) != NULL)
        {
            switch (csp_conn_dport(conn))
            {
                case SRS4_CSP_RX_DATA_PORT :
                case UHF_CSP_RX_DATA_PORT :

                    mfcc_tm_parser(packet->data,packet->length);

                    csp_buffer_free(packet);

                    break;

                default:
                    /* Call the default CSP service handler, handle pings, buffer use, etc. */
                    csp_service_handler(conn,packet);
                    break;
            }
        }

        /* Close current connection */
        csp_close(conn);

        //	printf("\r\nCSP Connection is closed");
    }
    return 0;
}
