/*
 *========================================================================
 *
 *   시스템명 : 요금징수 시스템
 *   파 일 명 : eps_main.c
 *   작 성 자 : 조보용 (baarong@neighbor21.co.kr)
 *   작 성 일 : 2018.11.15
 *   수 정 일 :
 *   설    명 :
 *
 *========================================================================
*/

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/un.h>
#include <netdb.h>
#include <signal.h>
#include <pthread.h>

#include "path_def.h"
#include "eps_head.h"
#include "sock_lib.h"
#include "eps_main.h"
#include "def_set.h"
#include "file_lb.h"
#include "dir_path.h"
#include "hi_packet_format.h"
#include "file_lb.h"
#include "file_no.h"
#include "tag_chrg.h"
#include "tag_rfnd.h"
#include "tag_iss_pay.h"

#define   EPS_BILL_PORT   "eps_bill_port"
#define epssvr "epssvr"

//void send_recv_eps();

typedef struct threaddata {
	int   sockfd;
	char  plz_id[6+1];
}THDA;

struct EPS_FUNC {
    short     kind;
    char      job [ 4+1];
    char      work[ 4+1];
    int       len;
    int       (*func)();
} eps_func[] = {
    { AZN_PERD_TAG_SALE  ,"1100","0010", sizeof(struct tag_iss_sale_rq)       , send_recv_eps /* 기간권 TAG 판매 등록 요청  */ },
    { AZN_RGSTR_TAG_CHRG ,"2100","0010", sizeof(struct tag_chrg_spec)         , send_recv_eps /* 기명권 TAG 충전 요청       */ },
    { AZN_TAG_CNCL_CHRG  ,"2200","0010", sizeof(struct tag_rfnd_spec)         , send_recv_eps /* 기명권 직전 충전 취소 요청 */ },
    {  -1                ,""    ,""    ,0                     , NULL          /* --. 종별 이상 내역 처리    */ }
};

/*
 *========================================================================
 *
 *   함 수 명 : send_recv_eps()
 *   작 성 자 : 조보용 (baarong@neighbor21.co.kr)
 *   작 성 일 : 2018.11.15
 *   수 정 일 :
 *   설    명 :
 *
 *========================================================================
*/
void send_recv_eps(int sockfd, char *plz_id, char *job, char *work, char *buff, char *kind)
{
     uchar   send_data[MAX_BUF];
     uchar   recv_data[MAX_BUF];
     int     sock, id;
     int     ret;
     char    lane_no[2];
     struct tag_iss_sale_rq RData;
     memset(lane_no, 0x00, 2);

    	 proc_log("--------------------point 10 \n");
     ret = sock_recv_data(sockfd, recv_data, MAX_BUF);
         proc_log("--------------------point 11 \n");


     id = srch_job_wrk(job,work);
     proc_log("id : %d\n", id);

     if (id < 0) exit(0);


     sock = connect_eps(id);
//sock = SOCK_SUCC;
    			proc_log("--------------------point 12 **** id = [%d] ****\n", id);
     if (sock != SOCK_FAIL)
     {
         while(1){
             switch (id) //
             {
                 case 0: /* 기간권 판매등록 */
                     make_frame1(send_data, recv_data, plz_id, lane_no, id, kind);
                     break;
                 case 1: /* 기명권 충전요청 */
                     make_frame2(send_data, recv_data, plz_id, lane_no, id, kind);
                     break;
                 case 2: /* 기명권 충전취소 */
                     make_frame3(send_data, recv_data, plz_id, lane_no, id, kind);
                     break;
                 default:
                     proc_log("지정되지 않은 전문번호가 들어왔습니다.\n");
                     break;
             }
                 			proc_log("--------------------point 13 \n");
             ret = send_eps(sock, send_data, recv_data, id);
                 			proc_log("--------------------point 14 \n");
             id = send_tcs(recv_data, send_data, plz_id, lane_no);
             if (id < 0) break;
//             sock = lb_tcp_con(epssvr, EPS_BILL_PORT);
         } /* end of while */
     } /* end of if (EPS Connect) */
}

/*
 *========================================================================
 *
 *   함 수 명 : func()
 *   작 성 자 : 조보용 (baarong@neighbor21.co.kr)
 *   작 성 일 : 2018.11.15
 *   수 정 일 :
 *   설    명 : 스레드 생성후 실행되는 로직
 *
 *========================================================================
*/
int threafunc(void *param)
{
	THDA *thdata = (THDA *)param;
    struct tag_iss_sale_rq *rq;
	int sockfd, ii;
    int ret;
    char buff[10];
	char lane_no[2+1], job[4+1], work[4+1], plz_id[6+1];
	char kinds;
    memset(lane_no, 0x0, 3);
    memset(job,     0x0, 5);
    memset(work,    0x0, 5);
    memset(plz_id,  0x0, 6);
			proc_log("--------------------point 5 \n");
//    sockfd = *((int *)param);
	sockfd = thdata->sockfd;
	memcpy(plz_id, thdata->plz_id, sizeof(plz_id)-1);

			proc_log("--------------------point 6 [%.6s][%d]\n", plz_id, sockfd);
    ret = sock_recv_data_nolog(sockfd, buff, 1);
			proc_log("--------------------point 7 sockfd = [%d], ret = [%d], \n", sockfd, ret);
	kinds = buff[0];
    if(!ret)
    {
        pthread_exit(0);
    }
			proc_log("--------------------point 8 [%02x]\n", buff[0]);

    for (ii=0; eps_func[ii].kind != -1; ii++)
    {
        if (eps_func[ii].kind == buff[0]) /* 종별코드(1) */
        break;   
    }
    			proc_log("--------------------point 9 [%02x]\n", buff[0]);
    if(eps_func[ii].kind == -1)
    {
        proc_log("종별코드 ERROR 0x%02x 차로 %.2s", buff[0], buff+1);
        pthread_exit(0);
    }
    else
    {
        strncpy(job ,eps_func[ii].job , 4);
        strncpy(work,eps_func[ii].work, 4);
        proc_log("%s\t%s\t%s", plz_id, job, work);
    
        (*eps_func[ii].func)(sockfd, plz_id, job, work, buff, kinds);
    }
    close(sockfd);
}



/*
 *========================================================================
 *
 *   함 수 명 : main()
 *   작 성 자 : 조보용 (baarong@neighbor21.co.kr)
 *   작 성 일 : 2018.11.15
 *   수 정 일 :
 *   설    명 :
 *
 *========================================================================
*/
int main(int argc, char **argv)
{
    int ii, fid, sock, sockfd;
    char  logdir[128+1];
    char  sock_name[128+1];
    char  plz_id[6+1];
    int options;
    extern  char  *optarg;
	pthread_t tid;
	int Ret;
	THDA tdata;
    memset(plz_id,  0x0, 4);


    while((options = getopt(argc, argv, "p:hs")) != EOF)
    {
        switch (options)
        {
            case 'p': /* 영업소번호 */
                sprintf(plz_id, "%s", optarg);
                break;
            default:
                break;
        }
    }

    sigignore(SIGPIPE);
    sigignore(SIGCHLD);

    sprintf(logdir, "%s/lnk_epssvr", LOG_DIR);
    mkdir(logdir, 0755);
    chdir(logdir);

    sprintf(sock_name, "lnk_epssvr%s", plz_id);

    sock = unix_sock_listen(sock_name);
    if(sock == SOCK_FAIL)
    exit(0);
			proc_log("--------------------point 1 [%d]\n", sock);

    while(1)
    {
        sockfd = unix_sock_accept(sock);
			proc_log("--------------------point 2 sock[%d]\n", sock);
			proc_log("--------------------point 2 sockfd[%d]\n", sockfd);

		memset(&tdata, 0x0, sizeof(struct threaddata));

			proc_log("--------------------point 2-1 [%d]\n", sockfd);
		tdata.sockfd = sockfd;
			proc_log("--------------------point 2-2 [%d]\n", sockfd);
		sprintf(tdata.plz_id, "%.6s", plz_id);

			proc_log("--------------------point 3 [%d]\n", tdata.sockfd);
		Ret = pthread_create(&tid, NULL, threafunc, (void *)&tdata);
		if(Ret < 0)
		{
			proc_log("스레드 생성 에러 \n");
			exit(0);
		}
			proc_log("--------------------point 4 \n");
		if(!Ret) pthread_detach(tid);
    }
}
