/*
 * exo_gps_linux_sim_skt.c
 *
 *  Created on: Apr 13, 2024
 *      Author: Invcuser_102
 */

#ifdef LINUX_TEMP_PORT

#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "exo_common.h"
#include "exo_gps_linux_sim_skt.h"
#include "obc_main.h"

#define MAX 80

#define SA struct sockaddr

static int connfd;
static int sockfd;
static uint8_t con_flg;
int len;
int port;
struct sockaddr_in servaddr, cli;
struct timeval timeout;

s_obc_sock_info gps_sock;

void gps_simu_server_skt_init()
{
    timeout.tv_sec = 2;
    timeout.tv_usec = 0;

    // socket create and verification
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        DEBUG_CPRINT(("\n gps simulation socket creation failed...\n"));
    }
    else
        DEBUG_CPRINT(("\n gps simulation Socket successfully created..\n"));
    bzero(&servaddr, sizeof(servaddr));
    port=atoi(gps_sock.port_num);
    DEBUG_CPRINT(("\n gps simulation socket IP addr=%s and port number%d\n",gps_sock.ip_addr,port));
    // assign IP, PORT
    servaddr.sin_family = AF_INET;
    //servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_addr.s_addr = inet_addr(gps_sock.ip_addr);
    servaddr.sin_port = htons(port);
    // Binding newly created socket to given IP and verification
    if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
        DEBUG_CPRINT(("\n gps simulation socket bind failed...\n"));
    }
    else
        DEBUG_CPRINT(("\ngps simulationSocket successfully binded..\n"));
    // Now server is ready to listen and verification

    //    setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout);
    //    setsockopt (sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof timeout);

    if ((listen(sockfd, 5)) != 0) {
        DEBUG_CPRINT(("Listen failed...\n"));
    }
    else
        DEBUG_CPRINT(("Server listening..\n"));
}

void gps_socket_con()
{
    len = sizeof(cli);

    // Accept the data packet from client and verification
    connfd = accept(sockfd, (SA*)&cli,(socklen_t *)&len);
    if (connfd < 0) {
        DEBUG_CPRINT(("server accept failed...\n"));
        con_flg=0;
    }
    else
    {
        con_flg=1;
        DEBUG_CPRINT(("server accept the client...\n"));
    }
    setsockopt (connfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout);
    setsockopt (connfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof timeout);
}

uint8_t gps_simu_data_write(uint8_t* buff, uint16_t length)
{
    int ret=0;
    if(con_flg==1)
    {
#if 0
        DEBUG_CPRINT(("gps write data=="));
        for (int i=0;i<length;i++)
        {
            DEBUG_CPRINT(("%x\t",buff[i]));
        }
        DEBUG_CPRINT(("\n"));
#endif
        if(check_socket_disconnected(connfd))
        {
            printf("Socket disconneted");
            con_flg = 0;
            ret = 1;
            close(connfd);
            //Socket disconnected
        }
        else
        {
            ret = write(connfd,buff,length);
            if(ret!=-1)
            {
                //               DEBUG_CPRINT(("gps socket write success\n"));
                ret=0;
            }
            else
            {
                DEBUG_CPRINT(("gps socket write fail\n"));
                con_flg = 0;
                ret=1;
                close(connfd);
            }
        }
    }
    else
    {
        ret=1;
    }
    return ret;
}

uint8_t gps_simu_data_read(uint8_t* buff, uint16_t length)
{
    int ret=0;
    if(con_flg==1)
    {
        ret = read(connfd,buff,length);
        if(ret==0)
        {
            con_flg = 0;
            close(connfd);
            return 0;
        }
        if(ret!=-1)
        {
            ret = 0;
        }
        else
        {
            ret=1;
        }
#if 0
        DEBUG_CPRINT(("gps read data=="));
        for (int i=0;i<length;i++)
        {
            DEBUG_CPRINT(("%x\t",buff[i]));
        }
        DEBUG_CPRINT(("\n"));
#endif
    }
    else
    {
        ret=1;
    }
    return ret;
}

void* gps_skt_simu(void* args)
{
    gps_simu_server_skt_init();
    while(1)
    {
        if(con_flg == 0)
        {
            gps_socket_con();
        }
        sleep(1);
    }
}

#endif

