/*
 *========================================================================
 *
 *   시스템명 : 요금징수 시스템
 *   파 일 명 : lane_comm.c
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   작 성 일 : 2019.05.10
 *   수 정 일 :
 *   설    명 :
 *
 *========================================================================
*/

/*==========================================================================*/
/* Head  정의                                                               */
/*==========================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <pthread.h>
#include "hi_ctrl.h"
#include "lo_ctrl.h"
#include "snd_rcv_knd.h"
#include "file_lb.h"
#include "dir_path.h"
#include "func_list.h"

/*==========================================================================*/
/* 전역 변수 정의                                                           */
/*==========================================================================*/
extern int       rs_length;            /* SOCK recv save length  */

/*---------------------------------------------------------------------------*/
/* lane_comm_open()     OPEN된 FILE DESCRIPTOR로 부터 DATA 수신 처리         */
/* lane_comm_reopen()   차로측과 통신 단절 후, 통신 재개 처리                */
/* lane_comm_accept()   차로측과 통신 단절 후, 통신 재개 처리                */
/* lane_comm_proc()     차로측 PROTOCOL STATUS MANAGEMENT PROCEDURE          */
/* lane_comm_snd()      차로측으로 DATA 송신 처리                            */
/* lane_comm_rcv()      차로측으로 부터 DATA 수신 처리                       */
/*---------------------------------------------------------------------------*/

struct    lo_comm_ctrl    lo_comm_ctrl;                /* Control block    */

/*
 *========================================================================
 *
 *   Function : lane_comm_open()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.08.24
 *   Modified :
 *   Remark   : Accept시 Open 완료 DISC->OPEN Command 사용하지 않음
 *
 *========================================================================
*/
int lane_comm_open(char *device)
{
    memset(&lo_comm_ctrl, 0, sizeof(lo_comm_ctrl));
    lo_comm_ctrl.pkt.flg = LP_FREE;
    lo_comm_ctrl.rcv.cnt =  0;
    lo_comm_ctrl.port_fd  = -1;
    rs_length    =  0;

    strcpy(lo_comm_ctrl.device_nm, device); /* device name(inet port)*/
    lo_comm_ctrl.stat_flag  = L_OPEN;      /* L_OPEN  0x0001   open compeleted        */

    if(sock_open_port() < 0)
    {
       lo_comm_ctrl.stat_flag  = L_STOP;   /* L_STOP  0x0002   stop request           */
       return(-1);
    }
    else
    {
       hi_comm_ctrl.lane_stat_info.comm_stat = CONNECT_STAT;  /* con_stat(통신상태)  'C' CONNECT-LINE        */
	   lane_stat_info_save();
       return (0);
    }
}

/*
 *========================================================================
 *
 *   함 수 명 : lane_comm_accept()
 *   작 성 자 : 조보용 (baarong@neighbor21.co.kr)
 *   작 성 일 : 2019.05.10
 *   수 정 일 :
 *   설    명 : 차로의 접속요구를 대기한다.
 *
 *========================================================================
*/
int lane_comm_accept(char *device)
{
    memset(&lo_comm_ctrl, 0, sizeof(lo_comm_ctrl));
    lo_comm_ctrl.pkt.flg = LP_FREE;
    lo_comm_ctrl.rcv.cnt =  0;
    lo_comm_ctrl.port_fd  = -1;
    rs_length    =  0;

    strcpy(lo_comm_ctrl.device_nm, device);
    lo_comm_ctrl.stat_flag  = L_OPEN;

    hi_comm_ctrl.lane_stat_info.comm_stat = DISCONNECT_STAT;     /* DISCONNECT-LINE */
	lane_stat_info_save();

    if(sock_accept_port() < 0)
    {
       lo_comm_ctrl.stat_flag  = L_STOP;
       return(-1);
    }
    else
    {
       hi_comm_ctrl.lane_stat_info.comm_stat = CONNECT_STAT;  /* CONNECT-LINE  */
	   lane_stat_info_save();
       return (0);
    }
    return 0;
}

/*
 *========================================================================
 *
 *   Function : lane_comm_reopen()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.08.24
 *   Modified :
 *   Remark   : 하위차로의 통신을 단절 후, 통신 재개처리
 *
 *========================================================================
*/
int lane_comm_reopen(FILE *packet_f)
{
    struct    tm    *tm;
    time_t     t;
	FILE *pack_f = NULL;
    char date[8+1];
	pack_f = packet_f;
lane_log("lane_comm_reopen 1");
    lo_comm_ctrl.stat_flag  = L_STOP;
lane_log("lane_comm_reopen 2");
    sock_close_port();
lane_log("lane_comm_reopen 3");
    t = time(0);
    tm = localtime(&t);
lane_log("lane_comm_reopen 4");
    sprintf(date, "%04d%02d%02d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
lane_log("lane_comm_reopen 5");
    log_open(date, pack_f);
lane_log("Re Open 1\n");
    packet_open(date, pack_f);
lane_log("Re Open 2\n");
    e_memcpy(hi_comm_ctrl.device_nm, hi_comm_ctrl.bas_tbl.lane_info[hi_comm_ctrl.lane_no-1].port);
lane_log("Re Open 3[%s]\n", hi_comm_ctrl.device_nm);
    hi_comm_ctrl.device_nm[sizeof(hi_comm_ctrl.bas_tbl.lane_info[hi_comm_ctrl.lane_no-1].port)] = '\0';
lane_log("Re Open 4[%s]\n", hi_comm_ctrl.device_nm);
    return(lane_comm_accept((char *)hi_comm_ctrl.device_nm));
}

/*
 *========================================================================
 *
 *   함 수 명 : lane_comm_close()
 *   작 성 자 : 조보용 (baarong@neighbor21.co.kr)
 *   작 성 일 : 2019.05.10
 *   수 정 일 :
 *   설    명 : 통신 종료
 *
 *========================================================================
*/
void lane_comm_close()
{
   lo_comm_ctrl.stat_flag  = L_STOP;
   sock_close_port();
}

/*
 *========================================================================
 *
 *   Function : lane_comm_proc()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.08.24
 *   Modified :
 *   Remark   : 하위차로에서 수신된 데이타 처리 및 하위차로로 송신
 *
 *========================================================================
*/
int lane_comm_proc(int rdflg, char *p)
{
    int    retcode;

    if (rdflg > 0)
    {
        retcode = sock_recv_data();
        if(retcode == -1)
        {
            lo_comm_ctrl.stat_flag = L_ERR;
            return (-1);
        }
    }

    while(1)
    {
        retcode = azn_recv_data();

        if(retcode > 0)
        {

            lane_comm_rcv();
            if (hi_comm_ctrl.rcv_ctrl.len > 0)
            {
//lane_log("차로데이터 수신[%d]\n", hi_comm_ctrl.rcv_ctrl.len);
               retcode = recv_process(p);
//lane_log("recv_process rslt[%d]\n", retcode);
               hi_comm_ctrl.rcv_ctrl.len = 0;

               if (retcode != 0)
               {
                  lo_comm_ctrl.stat_flag = L_ERR;
                  return(-1);
               }
            }
//lane_log("lane_comm_snd start[%d]\n", retcode);
            lane_comm_snd();
//lane_log("lane_comm_snd end[%d]\n", retcode);
        }
        else if(retcode < 0)
        {
            lo_comm_ctrl.stat_flag = L_ERR;
            return(-1);
        }
        else  break;
    } /*/End of while*/
    return (0);
}

/*
 *========================================================================
 *
 *   Function : lane_comm_rcv()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.08.24
 *   Modified :
 *   Remark   : 차로제어기로 부터 수신한 데이타 변환처리
 *
 *========================================================================
*/
void lane_comm_rcv()
{
    lo_comm_ctrl.rcv.cnt = 0;
    ns_packet_l2h(lo_comm_ctrl.rcv.buf, lo_comm_ctrl.rcv.len);
}

/*
 *========================================================================
 *
 *   Function : lane_comm_snd()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.08.24
 *   Modified :
 *   Remark   : 차로제어기에 데이타 송신
 *              차로제어기에 전송할 데이타 변환처리
 *
 *========================================================================
*/
int lane_comm_snd()
{
    if (hi_comm_ctrl.snd.len > 0 )
    {
lane_log("lane_comm_snd 1[%d]\n", hi_comm_ctrl.snd.len);
        if ( ns_packet_h2l(hi_comm_ctrl.snd.buf, hi_comm_ctrl.snd.len) > 0)
            hi_comm_ctrl.snd.len = 0;
lane_log("lane_comm_snd 2\n");
    }

    if(lo_comm_ctrl.pkt.flg == LP_FREE) return(0);

    memcpy(lo_comm_ctrl.snd.buf, lo_comm_ctrl.pkt.buf, lo_comm_ctrl.pkt.len);

    lo_comm_ctrl.snd.len = lo_comm_ctrl.pkt.len;

    if (sock_send_data() == 0)
    {
        lo_comm_ctrl.pkt.flg  = LP_FREE;
        lo_comm_ctrl.snd.len  = 0;
    }
    else
    {
        return (-1);
    }
    
    return 0;
}

