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

/*==========================================================================*/
/* Head  정의                                                               */
/*==========================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include "hi_ctrl.h"
#include "snd_rcv_knd.h"
#include "hi_packet_format.h"
#include "file_no.h"
#include "dir_path.h"
#include "passraw.h"
#include "cls_lane.h"
#include "file_lb.h"
#include "func_list.h"
#include "lb_func_list.h"
#include "key_info.h"

/*==========================================================================*/
/* 전역 변수 정의                                                           */
/*==========================================================================*/
#if 1
static    struct    lane_stat_info  lane_stat_info;      /* 차로 상태정보 */
static    struct    wrk_stat_info   wrk_stat_info;     /* 근무상태정보 */
static    struct    trmn_rcv        trmn_rcv;          /* 단말수신 */
static    struct    cls_lane_spec   cls_lane_spec;     /* 폐쇄차로통행명세 */
#endif
/*================================ FUNCTION LIST =================================*/
/* lane_stat_info_chng()     각 수신 FRAME DATA에 의한 차로상태 정보의 변경 처리  */
/*================================================================================*/

/*
 *========================================================================
 *
 *   함 수 명 : wrk_stat_info_chng()
 *   작 성 자 : JBY (baarong@neighbor21)
 *   작 성 일 : 2019.05.21
 *   수 정 일 :
 *   설    명 : 근무상태정보 변경
 *
 *========================================================================
*/
int wrk_stat_info_chng()
{
    struct    write_info          wi;
    struct    hi_wrk_start        *hws;
    struct    hi_wrk_end          *hwe;
    struct    tm                  *ptime;
    long      ctime;
    int       fd, isrc;
    char      tmp[20]; memset(tmp, 0x00, sizeof(tmp));

    fd = lb_fopen(&hi_comm_ctrl.write_info, FNO_WRKSTINFO, FINOUT+FC_MANULOCK);
    if (fd == -ENOENT)
        fd = lb_fbuild(&hi_comm_ctrl.write_info, FNO_WRKSTINFO, FINOUT+FC_MANULOCK);
    if (fd < 0) return (0);

    memset(&wrk_stat_info, " ", sizeof(wrk_stat_info));
    sprintf((char *)wrk_stat_info.plz_id, "%.2s", hi_comm_ctrl.write_info.plz_id); /* 영업소    */
lane_log("WRK_STAT PLZ[%.2s]\n", wrk_stat_info.plz_id);
    sprintf((char *)wrk_stat_info.lane_no, "%02d", hi_comm_ctrl.lane_no); /* 차로번호    */

    sprintf((char *)wrk_stat_info.wrk_turn, "%02d", natoi(&hi_comm_ctrl.write_info.wrk_no[2], 2)); /* 근무순번    */

    isrc = lb_freadi(fd, &wrk_stat_info_key[0], sizeof(struct wrk_stat_info), &wrk_stat_info, FEQUAL);

    switch(hi_comm_ctrl.rcv_ctrl.cmd)
    {
        case NS_WRK_START:  /* 근무개시보고    */
            hws = (struct hi_wrk_start *)hi_comm_ctrl.rcv_ctrl.buf;
            sprintf((char *)wrk_stat_info.wrk_date, "%.4s%.2s%.2s", hws->wrk_year, hws->wrk_month, hws->wrk_day);
            wrk_stat_info.wrk_stat_div = "1";                 /* 근무개시 */
            //sprintf(tmp, "%.8s%c", hws->seq_no, '\0'); strtoul(tmp, NULL, 16);
            sprintf((char *)wrk_stat_info.strt_no, "%.8s", hws->seq_no); /* 개시연번 */
            sprintf((char *)wrk_stat_info.wrkr_no, "%.4s", hws->wrkr_no); /* 근무자번호 */

            if (hi_comm_ctrl.now_stat_info & H_MTNC)
                snprintf((char *)wrk_stat_info.wrk_div, sizeof(wrk_stat_info.wrk_div), "%d", W_MTNC); /* 보수근무중 */
            else if (hi_comm_ctrl.asc_des_div == W_ENT)
                snprintf((char *)wrk_stat_info.wrk_div, sizeof(wrk_stat_info.wrk_div), "%d", W_ENT); /* 입구근무중 */
            else
                snprintf((char *)wrk_stat_info.wrk_div, sizeof(wrk_stat_info.wrk_div), "%d", W_WOUT); /* 출구근무중 */
lane_log("입구 근무[%c]\n", wrk_stat_info.wrk_div);
            sprintf((char *)wrk_stat_info.strt_year, "%.4s", hws->wrk_start_year); /* 개시일시   */
            sprintf((char *)wrk_stat_info.strt_mon, "%.2s", hws->wrk_start_month);
            sprintf((char *)wrk_stat_info.strt_day, "%.2s", hws->wrk_start_day);
            sprintf((char *)wrk_stat_info.strt_hr, "%.2s", hws->wrk_start_hour);
            sprintf((char *)wrk_stat_info.strt_min, "%.2s", hws->wrk_start_min);
            sprintf((char *)wrk_stat_info.strt_sec, "%.2s", hws->wrk_start_sec);
            break;

        case NS_WRK_END: /* 근무종료 */
            hwe = (struct hi_wrk_end *)hi_comm_ctrl.rcv_ctrl.buf;
            if (lb_data2atoi(wrk_stat_info.wrk_div, 1) != W_MTNC)
                snprintf((char *)wrk_stat_info.wrk_div, sizeof(wrk_stat_info.wrk_div), "%d", W_WOUT); /* 출구근무중 */
lane_log("출구 근무[%c]\n", wrk_stat_info.wrk_div);
            wrk_stat_info.wrk_stat_div = "2";               /* 종료구분 */
            sprintf((char *)wrk_stat_info.end_no, "%.8s", hwe->seq_no); /* 개시연번 */
            sprintf((char *)wrk_stat_info.wrkr_no, "%.4s", hwe->wrkr_no); /* 근무자번호 */

            sprintf((char *)wrk_stat_info.end_year, "%.4s", hwe->wrk_end_year); /* 종료일시   */
            sprintf((char *)wrk_stat_info.end_mon , "%.2s", hwe->wrk_end_month);
            sprintf((char *)wrk_stat_info.end_day , "%.2s", hwe->wrk_end_day);
            sprintf((char *)wrk_stat_info.end_hr  , "%.2s", hwe->wrk_end_hour);
            sprintf((char *)wrk_stat_info.end_min , "%.2s", hwe->wrk_end_min);
            sprintf((char *)wrk_stat_info.end_sec , "%.2s", hwe->wrk_end_sec);
			
			hi_comm_ctrl.lane_stat_info.lst_rev_snd_no = hi_comm_ctrl.lane_stat_info.lst_rev_snd_no;
            break;

        default:
            lb_close(fd);
            return (0);
    }

    if (isrc > 0)
           isrc = lb_fbrewrite(fd, &wrk_stat_info_key[0], &wrk_stat_info, sizeof(struct wrk_stat_info));
    else
           isrc = lb_write(fd, &wrk_stat_info, sizeof(struct wrk_stat_info));
    lb_close(fd);

    return (0);
}

/*
 *========================================================================
 *
 * Function : lane_stat_info_read()
 * Progrmer : JBY (baarong@neighbor21.co.kr)
 * Date     : 2018.09.03
 * Modified :
 * Remark   : 차로상태정보 읽기
 *========================================================================
*/ 
int lane_stat_info_read()
{
    struct    write_info    wi;
    int    fd,  isrc;

    fd = lb_fopen(&wi, FNO_LANESTATINFO, FINPUT+FC_MANULOCK);
    if (fd == -ENOENT)
        fd = lb_fbuild(&wi, FNO_LANESTATINFO, FINPUT+FC_MANULOCK);

    if (fd < 0)
    {
        memset(&lane_stat_info, 0, sizeof(struct lane_stat_info));
        sprintf((char *)lane_stat_info.lane_no, "%02d", hi_comm_ctrl.lane_no);
        return (fd);
    }

    sprintf((char *)hi_comm_ctrl.lane_stat_info.lane_no, "%02d", hi_comm_ctrl.lane_no);

    isrc = lb_freadi(fd,&lane_stat_info_key[0],sizeof(struct lane_stat_info), &hi_comm_ctrl.lane_stat_info,FEQUAL);
    lb_close(fd);

    if (isrc > 0)
    {
        memcpy(&lane_stat_info, &hi_comm_ctrl.lane_stat_info, sizeof(struct lane_stat_info));
        lane_stat2shm_update(&lane_stat_info);
    }
    return (isrc);
}

/*
 *========================================================================
 *
 *   함 수 명 : lane_stat2shm_update()
 *   작 성 자 : JBY (baarong@neighbor21)
 *   작 성 일 : 2019.05.11
 *   수 정 일 :
 *   설    명 : 차로상태정보를 공유메모리로 UPDATE
 *
 *========================================================================
*/
int lane_stat2shm_update(struct lane_stat_info *lane_stat_info)
{
    static int    shmid = -1;
    static struct sm_lane_info *sm_lane_info;

    if (shmid < 0)
    {
        shmid = shmget(KM_SMON, sizeof(struct sm_lane_info), IPC_CREAT|0644);
        if (shmid < 0) return (0);
        sm_lane_info = (struct sm_lane_info *)shmat(shmid, (void *)0, 0644);
        if (sm_lane_info == (struct sm_lane_info *)-1)
        {
            shmid = -1;
            return (0);
        }
    }
    memcpy(&sm_lane_info->lane_stat_info[hi_comm_ctrl.lane_no-1], lane_stat_info, sizeof(struct lane_stat_info));
    sm_lane_info->utim[hi_comm_ctrl.lane_no-1] = hi_comm_ctrl.time;
    sm_lane_info->xtimm_lane_info = hi_comm_ctrl.time;
    return (0);
}

/*
 *========================================================================
 *
 *   함 수 명 : lane_stat_info_restore()
 *   작 성 자 : JBY (baarong@neighbor21)
 *   작 성 일 : 2019.05.11
 *   수 정 일 :
 *   설    명 : 차로상태 정보 이상시 최종 처리된 단말수신-F에서 차로상태정보
 *              RECORD 복구 처리
 *               < 복구 내용 >
 *              1. 최종수신 전송연번
 *              2. 최종수신 DATA 종별
 *              3. 최종근무일자
 *               < 전송연번 복구 >
 *              1. 단말수신-F로 부터
 *              2. 폐쇄차로통행명세-F로 부터
 *
 *========================================================================
*/
void lane_stat_info_restore()
{
    char   d_path[128];
    struct write_info wi;
    struct hi_packet_format *hpf;
    struct tm *tm;
    int    retc, chck;
    time_t c_clock;
    int    i, knd;
    char   tmp[10]; memset(tmp, 0x00, sizeof(tmp));

    c_clock = time(0);
    c_clock = c_clock + (48 * 60 * 60);

    for (i=0, chck=0; i<10; i++)    /* 최근 10일간만 CHECK    */
    {
        c_clock -= (24*60*60);
        tm = localtime(&c_clock);
        sprintf(d_path, "%s/%04d%02d%02d", DIR_TCS, YEAR(tm->tm_year), MONTH(tm->tm_mon), DAY(tm->tm_mday));

        if (access(d_path, 0) < 0) continue;

        sprintf((char *)wi.year, "%04d", YEAR(tm->tm_year));
        sprintf((char *)wi.mon, "%02d", MONTH(tm->tm_mon));
        sprintf((char *)wi.day, "%02d", DAY(tm->tm_mday));
        retc = record_read(&wi, chck);
        if (retc & 0x01 && hi_comm_ctrl.lane_stat_info.lst_rev_snd_no == 0)
        {
            /* 단말수신 RECORD READ OK */
            hpf = (struct hi_packet_format *)trmn_rcv.data;
            memset(tmp, 0x00, sizeof(tmp));
            sprintf(tmp, "%.8s%c", hpf->seq_no, '\0');
            hi_comm_ctrl.lane_stat_info.lst_rev_snd_no = strtoul(tmp, NULL, 16);

            memset(tmp, 0x00, sizeof(tmp));
            sprintf(tmp, "%.2s%c", hpf->kind, '\0');
            hi_comm_ctrl.lane_stat_info.last_rcv_knd = strtoul(tmp, NULL, 16);
#ifdef _VERIFY_
            lane_log("===== 단말수신 종별[%02x]\n", hi_comm_ctrl.lane_stat_info.last_rcv_knd);
#endif
        }
        if ((retc & 0x02) && (hi_comm_ctrl.lane_stat_info.lst_rev_snd_no == 0 ||
            cmp_seq_no(cls_lane_spec.sno, hi_comm_ctrl.lane_stat_info.lst_rev_snd_no) > 0))
        {
            /* 폐쇄차로통행명세 RECORD READ OK */
            hi_comm_ctrl.lane_stat_info.lst_rev_snd_no = cls_lane_spec.sno;
        }

        if (hi_comm_ctrl.lane_stat_info.lst_rev_snd_no != 0)    /* 최종수신연번 복구 완 */
            chck |= (0x02 | 0x04);

        if (!(retc & 0x01))
            break;

        /* 단말수신에 의한 최종근무자 및 일자 복구 */
        hpf = (struct hi_packet_format *)trmn_rcv.data;
        memset(tmp, 0x00, sizeof(tmp));
        sprintf(tmp, "%.2s%c", hpf->kind, '\0');
        knd = strtoul(tmp, NULL, 16);
#ifdef _VERIFY_
        lane_log("===== 복구 종별[%02x]\n", knd);
#endif
        switch (knd)
        {
            case NS_WRK_END: /* 근무종료     */
                hi_comm_ctrl.lane_stat_info.wrk_stat = WS_NONE;           /* 비근무중     */
                e_memcpy(hi_comm_ctrl.lane_stat_info.be_wrk_year, wi.year);     /* 이전근무일자    */
                e_memcpy(hi_comm_ctrl.lane_stat_info.be_wrk_mon, wi.mon);
                e_memcpy(hi_comm_ctrl.lane_stat_info.be_wrk_day, wi.day);
                e_memcpy(hi_comm_ctrl.lane_stat_info.be_wrk_no, wi.wrk_no);
                break;
            default:
                hi_comm_ctrl.lane_stat_info.wrk_stat = WS_NORMAL;           /* 일반근무중    */
                e_memcpy(hi_comm_ctrl.lane_stat_info.wrk_year, wi.year);         /* 현근무일자    */
                e_memcpy(hi_comm_ctrl.lane_stat_info.wrk_mon, wi.mon);
                e_memcpy(hi_comm_ctrl.lane_stat_info.wrk_day, wi.day);
                e_memcpy(hi_comm_ctrl.lane_stat_info.wrk_no, wi.wrk_no);
                break;
        }
        break;
    }
}

/*
 *========================================================================
 *
 *   함 수 명 : lane_stat_info_save()
 *   작 성 자 : JBY (baarong@neighbor21)
 *   작 성 일 : 2019.05.11
 *   수 정 일 :
 *   설    명 : 차로상태정보(lane_stat_info) FILE WRITE
 *
 *========================================================================
*/
int lane_stat_info_save()
{
    struct    write_info    wi;
    int    fd,   isrc;

    sprintf((char *)lane_stat_info.lane_no, "%02d", hi_comm_ctrl.lane_no);

    if (memcmp(&lane_stat_info, &hi_comm_ctrl.lane_stat_info, sizeof(struct lane_stat_info)) == 0){
        /*---------------
        lane_stat2shm_update(&lane_stat_info);
        lane_stat2shared();
        return (0);
        ---------------*/
    }
    lane_log(" [SV2LC] (lane_stat.c) 차로번호 (%d) 메모리 변경함 !!\n", hi_comm_ctrl.lane_no);

    fd = lb_fopen(&wi, FNO_LANESTATINFO, FINOUT+FC_MANULOCK);
    if (fd == -ENOENT)
        fd = lb_fbuild(&wi, FNO_LANESTATINFO, FINOUT+FC_MANULOCK);
    if (fd < 0) return (fd);

    isrc = lb_fbrewrite(fd, &lane_stat_info_key[0], &hi_comm_ctrl.lane_stat_info, sizeof(struct lane_stat_info));

    if (isrc < 0){
        isrc = lb_writel(fd, &hi_comm_ctrl.lane_stat_info, sizeof(struct lane_stat_info));
        if(isrc > 0) memcpy(&lane_stat_info, &hi_comm_ctrl.lane_stat_info, sizeof(struct lane_stat_info));
    }else memcpy(&lane_stat_info, &hi_comm_ctrl.lane_stat_info, sizeof(struct lane_stat_info));

    lb_close(fd);

    //lane_stat2shm_update(&lane_stat_info);
    //lane_stat2shared();
    return (isrc);
}

/*
 *========================================================================
 *
 *   Function : lane_stat_info_chng()
 *   Progrmer : JBY (baarong@neighbor21.co.kr)
 *   Date     : 2018.09.03
 *   Modified :
 *   Remark   : 차로상태정보 변경
 *
 *========================================================================
*/
int lane_stat_info_chng()
{
    struct    hi_rq_seq_no                    *hrsn;
    struct    hi_cmd_reply                    *hcr;
    struct    hi_lane_stat                    *hls;
    struct    hi_rpr_data                     *hrd;
    struct    hi_wrk_start                    *hws;
    struct    hi_wrk_end                      *hwe;
    int       i, rvs_no;
    char tmp[10]; memset(tmp, 0x00, sizeof(tmp));

    if (hi_comm_ctrl.now_stat_info & H_ACC_RESND)
        return (0);             /* 재전송 중인 자료   */

    switch (hi_comm_ctrl.rcv_ctrl.cmd)        /* 수신 DATA의 종별 ? */
    {
        case NS_RQ_SEQ_NO:   /* 전송연번요구 */
//lane_log("전송연번요구 1\n");
            hrsn = (struct hi_rq_seq_no *)hi_comm_ctrl.rcv_ctrl.buf;
//lane_log("전송연번요구 2\n");
            hi_comm_ctrl.lane_stat_info.comm_stat = CONNECT_STAT;           /* 회선상태 */
//lane_log("전송연번요구 3\n");
            sprintf(hi_comm_ctrl.lane_stat_info.lane_typ, "0%c", hrsn->io_div); /* 차로 TYPE */
//lane_log("전송연번요구 4\n");
            break;
        case NS_CMD_REPLY:   /* 지령 응답 */
//lane_log("지령응답 0\n");
            hcr = (struct hi_cmd_reply *)hi_comm_ctrl.rcv_ctrl.buf;
//lane_log("지령응답 1\n");
            switch (hcr->reply_typ - '0')
            {
                case 0x01: /* 테이블지령응답 */
                    for (i=0; i < TB_LAST; i++)
                    {
                        if(i == 3) continue; //휴일정보 사라짐
//lane_log("테이블 지령 응답[%d][%d]\n", i, TB_LAST);
                        rvs_no = lb_data2atoi((char const *)hi_comm_ctrl.bas_tbl.rvs_tbl_info[i].rvs_no, 2);
//lane_log("개정번호[%d][%d]\n", rvs_no, hi_comm_ctrl.lane_stat_info.tbl_stat[i][0]);
                        if (rvs_no == hi_comm_ctrl.lane_stat_info.tbl_stat[i][0])
                        {
                            hi_comm_ctrl.lane_stat_info.tbl_stat[i][1] = 0x00; /*처리완료*/
                        }
                        else
                        {
                            hi_comm_ctrl.lane_stat_info.tbl_stat[i][1] = 0x02; /*송신대기*/
                        }
                    }
                    break;

                case 0x02: /* 보증전송연번 응답 */
                    hi_comm_ctrl.lane_stat_info.warr_snd_no = hi_comm_ctrl.warr_snd_no;
                    break;

                case 0x03:
                    break;

                default :
                    lane_log(" [LC2SV] (lane_stat.c) MF_TUPDA (테이블 지령 응답) 코드 이상 [%x]\n",hcr->reply_typ);
                    break;
            }
            break;

        case NS_LANE_STAT:   /* 차로상태 정보 */
            hls = (struct hi_lane_stat *)hi_comm_ctrl.rcv_ctrl.buf;

            /* 기기 상태 정보 [추후 변경]   */
            if(hi_comm_ctrl.rcv_ctrl.cmd == NS_LANE_STAT)
            {
                /* 수신 DATA의 종별 ? */
                if(hls->mchi_stat[0] & MC_KEY) hi_comm_ctrl.lane_stat_info.mchi_stat0 = 1;
                else hi_comm_ctrl.lane_stat_info.mchi_stat0 = 0;

                if(hls->mchi_stat[0] & MC_COVER) hi_comm_ctrl.lane_stat_info.mchi_stat1 = 1;
                else hi_comm_ctrl.lane_stat_info.mchi_stat1 = 0;

                if(hls->mchi_stat[0] & MC_STACKER) hi_comm_ctrl.lane_stat_info.mchi_stat2 = 1;
                else hi_comm_ctrl.lane_stat_info.mchi_stat2 = 0;

                if(hls->mchi_stat[0] & MC_HOPPER) hi_comm_ctrl.lane_stat_info.mchi_stat3 = 1;
                else hi_comm_ctrl.lane_stat_info.mchi_stat3 = 0;

                if(hls->mchi_stat[0] & MC_SIGLIGHT) hi_comm_ctrl.lane_stat_info.mchi_stat5 = 1;
                else hi_comm_ctrl.lane_stat_info.mchi_stat5 = 0;
            }
            else
            {
                hi_comm_ctrl.lane_stat_info.mchi_stat0 = 0;
                hi_comm_ctrl.lane_stat_info.mchi_stat1 = 0;
                hi_comm_ctrl.lane_stat_info.mchi_stat2 = 0;
                hi_comm_ctrl.lane_stat_info.mchi_stat3 = 0;
                hi_comm_ctrl.lane_stat_info.mchi_stat4 = 0;
                if(hls->mchi_stat[0] & 0x40) hi_comm_ctrl.lane_stat_info.mchi_stat5 = 1;
                else hi_comm_ctrl.lane_stat_info.mchi_stat5 = 0;
            }

            for (i=0; i < TB_LAST; i++)
            {
//                if(hi_comm_ctrl.asc_des_div == L_ENT && hi_comm_ctrl.plz_typ == 0 && i >= 2) break;

                /*************************************************/
                /* 수신 TABLE 상태 : 0  미등록                   */
                /*                   1  등록중                   */
                /*                   2  등록완료                 */
                /* (주) TABLE 상태는 항상 0로 수신됨.            */
                /*************************************************/
                hi_comm_ctrl.lane_stat_info.tbl_stat[i][2] = hls->tbl_stat[i].stat - '0';

//                if(hi_comm_ctrl.rcv_ctrl.cmd == NS_LANE_STAT && i == 6) continue;  /* TAG B/L 관리연번으로 관리 */
//                if(hi_comm_ctrl.rcv_ctrl.cmd == NS_LANE_STAT && i == 7) continue;  /* TAG P/L 관리연번으로 관리 */
//                if(hi_comm_ctrl.rcv_ctrl.cmd == NS_LANE_STAT && i == 8) continue;  /* 발행사정보 기초사항으로 관리 */

                rvs_no = lb_data2atoi((char const *)hi_comm_ctrl.bas_tbl.rvs_tbl_info[i].rvs_no, 2);
lane_log("개정[%d] [%d]\n", rvs_no, hi_comm_ctrl.lane_stat_info.tbl_stat[i][0]);
                if ( rvs_no != lb_data2atoi((char const *)hls->tbl_stat[i].rvs_no, 2) || lb_data2atoi((char const *)hls->tbl_stat[i].rvs_no, 2) != 0)
                {
                    hi_comm_ctrl.lane_stat_info.tbl_stat[i][1] = 0x01; /* 지령미처리 */
                    lane_log(" [SV2LC] 개정번호%d s[%d] c[%d]\n",  i, hi_comm_ctrl.lane_stat_info.tbl_stat[i][0], lb_data2atoi((char const *)hls->tbl_stat[i].rvs_no, 2));
                }
                else
                {
                    hi_comm_ctrl.lane_stat_info.tbl_stat[i][1] = 0x00; /* 송신 OK    */
                }
                hi_comm_ctrl.lane_stat_info.tbl_stat[i][0] = lb_data2atoi((char const *)hls->tbl_stat[i].rvs_no, 2);
            }

            /* 차로 F/W DATA     */
            //e_memcpy(hi_comm_ctrl.lane_stat_info.ctrl_div, hls->lane_ctrler_div);
            //sprintf(tmp, "%.8s%c", hls->fw_ver, '\0');
            //hi_comm_ctrl.lane_stat_info.lane_fw_ver = strtoul(tmp, NULL, 16);

            sprintf(tmp, "%.8s%c", hls->bl_seq_no, '\0');
            hi_comm_ctrl.lane_stat_info.bl_lst_hnd_no = strtoul(tmp, NULL, 16);
            sprintf(tmp, "%.8s%c", hls->bef_seq_no, '\0');
            hi_comm_ctrl.lane_stat_info.bef_lst_hnd_no = strtoul(tmp, NULL, 16);
            sprintf(tmp, "%.8s%c", hls->imm_carno_seq_no, '\0');
            hi_comm_ctrl.lane_stat_info.imm_lst_hnd_no = strtoul(tmp, NULL, 16);
            sprintf(tmp, "%.8s%c", hls->rfid_seq_no, '\0');
            hi_comm_ctrl.lane_stat_info.rfid_lst_hnd_no = strtoul(tmp, NULL, 16);
            sprintf(tmp, "%.8s%c", hls->red_carno_seq_no, '\0');
            hi_comm_ctrl.lane_stat_info.red_lst_hnd_no = strtoul(tmp, NULL, 16);

            break;

        case NS_RPR_DATA:  /* 보수 DATA */
            hrd = (struct hi_rpr_data *)hi_comm_ctrl.rcv_ctrl.buf;
            e_memcpy(hi_comm_ctrl.lane_stat_info.rpr_info_knd, hrd->mchi_kind); /* 기종    */
            hi_comm_ctrl.lane_stat_info.occ_rest_div = hrd->occ_rest - '0';       /* 발생/복구 구분 */
            e_memcpy(hi_comm_ctrl.lane_stat_info.err_code, hrd->err_code);     /* 이상코드 */
            chg_date_tm(&hi_comm_ctrl.lane_stat_info.occ_year, &hrd->year);       /* 발생일시 */
            hi_comm_ctrl.lane_stat_info.last_err_knd = NS_RPR_DATA;      /* 최종특이사항종별 */
#if 0  /*  보수 정보 추후 변경 */
            if (hrd->mchi_kind == 5 && hrd->err_code == 0)
                hi_comm_ctrl.lane_stat_info.mchi_stat3 =  0;                /* HOPPER NEAR EMPTY 복구 */
#endif
            break;

        case NS_WRK_START:  /* 근무개시보고 */
//lane_log("근무개시 Stat 1\n");
            hws = (struct hi_wrk_start *)hi_comm_ctrl.rcv_ctrl.buf;
//lane_log("근무개시 Stat 2\n");
            if(memcmp(hws->wrkr_no, "6", 1) == 0)
            {
                hi_comm_ctrl.write_info.wrk_knd = WS_RPR;
                hi_comm_ctrl.lane_stat_info.wrk_stat = WS_RPR;
            }else{
                hi_comm_ctrl.write_info.wrk_knd = WS_NORMAL;
                hi_comm_ctrl.lane_stat_info.wrk_stat = WS_NORMAL;
            }
//lane_log("근무개시 Stat 3\n");
            //hi_comm_ctrl.lane_stat_info.wrk_stat = hws->wrk_div-'0';                        /* 근무상태 */
            sprintf((char *)hi_comm_ctrl.lane_stat_info.wrk_year, "%.4s", hws->wrk_year);   /* 근무일자 */
			sprintf((char *)hi_comm_ctrl.lane_stat_info.wrk_mon , "%.2s", hws->wrk_month);  /* 근무일자 */
			sprintf((char *)hi_comm_ctrl.lane_stat_info.wrk_day , "%.2s", hws->wrk_day);    /* 근무일자 */
//lane_log("근무개시 Stat 4\n");
            e_memcpy(hi_comm_ctrl.lane_stat_info.wrk_no, hws->wrk_no);                      /* 근무번호 */
//lane_log("근무개시 Stat 5\n");
            e_memcpy(hi_comm_ctrl.lane_stat_info.wrkr_no, hws->wrkr_no);                    /* 근무자 번호 */
//lane_log("근무개시 Stat 6\n");
            chg_date_tm(&hi_comm_ctrl.lane_stat_info.wrk_strt_year, &hws->wrk_start_year);  /* 근무개시일시 */
//lane_log("근무개시 Stat 7\n");
            sprintf(hi_comm_ctrl.lane_stat_info.lane_typ, "0%c", hws->io_div); /* 차로 TYPE */
//lane_log("근무개시 Stat 8\n");
            memset(hi_comm_ctrl.lane_stat_info.wrk_end_year, 0x00, sizeof(hi_comm_ctrl.lane_stat_info.wrk_end_year)); /* 근무종료일시 */
            memset(hi_comm_ctrl.lane_stat_info.wrk_end_mon,  0x00, sizeof(hi_comm_ctrl.lane_stat_info.wrk_end_mon ));
            memset(hi_comm_ctrl.lane_stat_info.wrk_end_day,  0x00, sizeof(hi_comm_ctrl.lane_stat_info.wrk_end_day ));
            memset(hi_comm_ctrl.lane_stat_info.wrk_end_hr ,  0x00, sizeof(hi_comm_ctrl.lane_stat_info.wrk_end_hr  ));
            memset(hi_comm_ctrl.lane_stat_info.wrk_end_min,  0x00, sizeof(hi_comm_ctrl.lane_stat_info.wrk_end_min ));
            memset(hi_comm_ctrl.lane_stat_info.wrk_end_sec,  0x00, sizeof(hi_comm_ctrl.lane_stat_info.wrk_end_sec ));
            break;

        case NS_WRK_END: /* 근무종료    */
            hwe = (struct hi_wrk_end *)hi_comm_ctrl.rcv_ctrl.buf;
            chg_date(&hi_comm_ctrl.lane_stat_info.be_wrk_year, &hwe->wrk_date);           /* 이전근무일자 */
            e_memcpy(hi_comm_ctrl.lane_stat_info.be_wrk_no, hwe->wrk_no);                 /* 이전근무번호    */
            chg_date_tm(&hi_comm_ctrl.lane_stat_info.wrk_end_year, &hwe->wrk_end_year);   /* 근무종료일시 */
            memset(hi_comm_ctrl.lane_stat_info.wrk_year, 0, 4);                             /* 현근무일자 */
            memset(hi_comm_ctrl.lane_stat_info.wrk_mon, 0, 2);
            memset(hi_comm_ctrl.lane_stat_info.wrk_day, 0, 2);
            memset(hi_comm_ctrl.lane_stat_info.wrk_no, 0, 4);                               /* 현근무번호 */
            break;

        default:
            break;
    }
lane_log("lane_stat_cng End\n");
    return (0);
}

/*
 *========================================================================
 *
 *   함 수 명 : record_read()
 *   작 성 자 : JBY (baarong@neighbor21)
 *   작 성 일 : 2019.05.12
 *   수 정 일 :
 *   설    명 : 차로의 최종일의 최종 DATA RECORD READ.
 *              1. 최종근무자의 단말수신-F의 최종 RECORD를 READ
 *              2. 폐쇄차로 통행명세-F의 최종 RECORD
 *
 *========================================================================
*/
int record_read(struct write_info *wi, int flag)
{
    char    d_path[128], c_path[128];
    struct    trmn_rcv     f_trmn_rcv, tmp_trmn_rcv;
    struct    stat     statb;
    int    fd,      isrc;
    int    retc;
    int    i, j=0, k, l;
    int    jsfd,    jsrc;


    sprintf(d_path, "%s/%.4s%.2s%.2s", DIR_TCS, wi->year, wi->mon, wi->day);

    retc = 0;

    if (!(flag & 0x01))
    {
        /* 단말수신-F의 최종 RECORD */
        for (i=MAX_WRKCNT; i>0; i--)
        {
            sprintf(c_path,"%s/TERMRECV%.2s%02d%02d",d_path, hi_comm_ctrl.bas_tbl.plz_id, hi_comm_ctrl.lane_no, i);
            retc = stat(c_path, &statb);
            if (retc != 0 || statb.st_size == 0) continue;

            /* 일자의 최종근무 OK */
            sprintf(c_path, "%02d%02d", hi_comm_ctrl.lane_no, i);
            memcpy(wi->wrk_no, c_path, 4);

            memset(&tmp_trmn_rcv, 0x00, sizeof(tmp_trmn_rcv));
            fd = lb_fopen(wi, FNO_TERMRECV, FINPUT+FC_MANULOCK);

            if (fd < 0) continue;

            while (1)
            {
                j++;
                lseek(fd,-j * sizeof(struct trmn_rcv), SEEK_END);

                retc = read(fd,&f_trmn_rcv, sizeof(struct trmn_rcv));

                if(retc < sizeof(struct trmn_rcv)) break;

                if(j == 1 && f_trmn_rcv.flag == F_END)
                {
                    memcpy(&tmp_trmn_rcv, &f_trmn_rcv, sizeof(struct trmn_rcv));
                    continue;
                }

                if(f_trmn_rcv.flag == F_CON)
                {
                    memcpy(&tmp_trmn_rcv, &f_trmn_rcv, sizeof(struct trmn_rcv));
                }
                else if(f_trmn_rcv.flag == F_END)
                {
                    break;
                }
            }
            lb_close(fd);

            memcpy(&trmn_rcv, &tmp_trmn_rcv, sizeof(struct trmn_rcv));

            retc = 0;
            retc |= 0x01;
            break;
        }
    }
    if (!(flag & 0x02))
    {
        /* 폐쇄차로 통행 명세 */
        memset(&cls_lane_spec, 0, sizeof(struct cls_lane_spec));

        fd = lb_fopen(wi, FNO_CLSPASSSPEC, FINPUT+FC_MANULOCK);

        if (fd >= 0)
        {
            k = 0;

            while(1)
            {
                k++;
                lseek(fd, -k * sizeof(struct cls_lane_spec), SEEK_END);
                isrc = read(fd, &cls_lane_spec, sizeof(struct cls_lane_spec));
                if(isrc < sizeof(struct cls_lane_spec)) break;
                if (isrc == 0 && cls_lane_spec.lane_no == hi_comm_ctrl.lane_no) break;
            }
            retc |= 0x02;
            lb_close(fd);
        }

    }
    lb_close(fd);
    return (retc);
}
