/************************************************************
**
**     Object name : 
**
**     Public      : 
**
**     Private     : 
**
**     Description
**     -- -- -- -- -- -- -- --
**     RASP-MXを用いたUSBメモリへの音声収録システム
**     
**
**     History
**     -- -- -- -- -- -- -- --
**     2015.08.13 K.Takagi MX用に移植
**     2015.06.26 K.Takagi 新規作成
**
**
**     Copyright (c) 2015
**     System In Frontier Inc.
**
*/


/*=========================================================*/
/*               Special Macro Definition                  */
/*=========================================================*/

#undef  DEBUG

#define ENABLE_REC_SOUND
#define ENABLE_DISK_MOUNT


/*=========================================================*/
/*                   Include Files                         */
/*=========================================================*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>

#include "RecSystem.h"
#include "rasp-netapi-arg.h"

/*=========================================================*/
/*                   Macro Definition                      */
/*=========================================================*/

#undef DEBUG_PRINT
#ifdef DEBUG

#define DEBUG_PRINT printf

#else

#define DEBUG_PRINT(...)  

#endif


/*=========================================================*/
/*                 Structure Declaration                   */
/*=========================================================*/


/*=========================================================*/
/*                    Private Valiable                     */
/*=========================================================*/

/*=========================================================*/
/*                    Public Valiable                      */
/*=========================================================*/


#include "LoadRecInfo.c"

#ifdef ENABLE_DISK_MOUNT
#include "DeviceMount.c"
#endif

#ifdef ENABLE_REC_SOUND
#include "RecSound.c"
#endif


#include "MxGpio.c"

/************************************************************
**
**  Public  : 
**
**  History : 
**            2015.08.13 K.Takagi SWの処理を実装
**            2015.08.07 K.Takagi SWの処理を仮実装
**            2015.06.26 K.Takagi 新規作成
**
**  Description
**  -----------
**  収録システムのメイン
**
*/

int main(int argc, char **argv)
{
    int ret_stat;
    int fd_rasp;
    int fd_sw;
    
    RASP_USB_REC_INFO_t usb_rec_info;
    REC_SOUND_INFO_t sound_info;
    
    
    char info_file_name[DIR_NAME_LENGTH + FILE_NAME_LENGTH + 10];
    FILE *fp;
    struct timeval rec_time;
    struct tm *rec_tm;
    
    int mount_flag;
    
    
    /* 各種情報を初期化 */
    fd_rasp = -1;
    fd_sw   = -1;
    
    memset(&usb_rec_info, 0, sizeof(RASP_USB_REC_INFO_t));
    memset(&sound_info,  0, sizeof(REC_SOUND_INFO_t));
    
    sem_init(&sound_info.sem_id, 0, 0);
    
    /* 音声用のデバイスファイルを開く */
    //fd_rasp = InitSoundDevice(NULL);
    fd_rasp = InitSoundDevice("/dev/kt"); // MX
    if(fd_rasp < 0)
    {
        printf("RASP Device Init Error.\n");
        return -1;
    }
    else
    {
        printf("RASP Device Init OK.\n");
    }
    
    /* SW用のデバイスを開く */
    fd_sw = OpenSW();
    if(fd_sw < 0)
    {
        close(fd_rasp);
        return -1;
    }
    
    /* システムの情報をファイルから読み出す
    **
    ** mount.conf はデフォルト設定
    ** usb-rec.conf 側のユーザ設定で上書き可
    */
    LoadSystemInfo("/root/mount.conf", &usb_rec_info);
    ret_stat = LoadSystemInfo("/root/usb-rec.conf", &usb_rec_info);
    if(ret_stat < 0)
    {
        printf("Load System Info File Error.\n");
        goto ErrorEnd;
    }
    else
    {
        printf("Load System Info File OK.\n");
    }

    /* システム情報表示 */
    ShowSystemInfo(&usb_rec_info);

    /* 各種情報をコピー */
    sound_info.fd              = fd_rasp;
    sound_info.sound_file_size = usb_rec_info.sound_file_size;
    sprintf(sound_info.sound_file_name, "%s/%s",  usb_rec_info.mount_point, usb_rec_info.sound_file_name);
    sprintf(info_file_name, "%s/%s",  usb_rec_info.mount_point, usb_rec_info.save_info_file);
    
    /* 
    ** 引数が指定されなければデーモンとして起動
    ** なにか指定された場合はフロントエンドで起動（デバック用）
    */
    if(argc == 1)
    {
        ret_stat = daemon(0,0);
    }
    
    
    while(1)
    {
    
        /* SWの状態を監視 */
        while(1)
        {
            int sw;
            
            /* SWがON(1)になったら抜ける */
            sw = CheckSW(fd_sw, 1);
            if(sw)
            {
                break;
            }
            
            sleep(1);
        }
        
        
        mount_flag = 0x0;
#ifdef ENABLE_DISK_MOUNT
        /* ユーザ指定のデバイスのマウントを試す */
        ret_stat = DeviceMount(usb_rec_info.mount_device, usb_rec_info.mount_point, usb_rec_info.mount_fs);
        if(ret_stat == 0)
        {
            printf("Mount OK : %s\n", usb_rec_info.mount_device);
            mount_flag = 0x1;
        }
        
        /* /dev/sdaでのmountを試す */
        if(!mount_flag)
        {
            ret_stat = DeviceMount("/dev/sda", usb_rec_info.mount_point, usb_rec_info.mount_fs);
            if(ret_stat == 0)
            {
                printf("Mount OK : /dev/sda\n");
                mount_flag = 0x1;
            }
        }
        
        /* /dev/sda1でのmountを試す */
        if(!mount_flag)
        {
            ret_stat = DeviceMount("/dev/sda1", usb_rec_info.mount_point, usb_rec_info.mount_fs);
            if(ret_stat == 0)
            {
                printf("Mount OK : /dev/sda1\n");
                mount_flag = 0x1;
            }
        }
        
        if(!mount_flag)
        {
            printf("Muont Error\n");
            perror(NULL);
            goto ErrorEnd;
        }
#endif
        
        /* ここがメイン処理 */
        {
            /* 開始時刻記録 */
            fp = fopen(info_file_name, "wt");
            if(fp == NULL)
            {
                printf("File Open Error.\n");
                goto ErrorEnd;
            }
            
            ret_stat = gettimeofday(&rec_time, NULL);
            if(ret_stat == 0)
            {
                fprintf(fp, "Start\n");
                fprintf(fp, "%ld[sec] %ld[usec]\n", rec_time.tv_sec, rec_time.tv_usec);
                rec_tm = localtime(&(rec_time.tv_sec));
                fprintf(fp, "%d/%d/%d %d:%d:%d\n", 
                        rec_tm->tm_year+1900, rec_tm->tm_mon+1, rec_tm->tm_mday,
                        rec_tm->tm_hour, rec_tm->tm_min, rec_tm->tm_sec);
            }
            sync();
            
#ifdef ENABLE_REC_SOUND
            /* 音声収録用のスレッドを起動 */
            ret_stat = RecSouncMainStart(&sound_info);
            if(ret_stat < 0)
            {
                printf("RecSoundMainStart Error.\n");
            }
            else
            {
                printf("RecSoundMainStart OK.\n");
            }
#endif

            /* SWの状態を監視 */
            while(1)
            {
                int sw;
                
                /* SWがOFF(0)になったら抜ける */
                sw = CheckSW(fd_sw, 0);
                if(sw)
                {
                    break;
                }
                
                sleep(1);
            }

#ifdef ENABLE_REC_SOUND
            /* 他のスレッドに終了を通知 */
            ret_stat = RecSouncMainStop(&sound_info);
            if(ret_stat < 0)
            {
                printf("RecSoundMainStop Error.\n");
            }
            else
            {
                printf("RecSoundMainStop OK.\n");
            }
#endif
            
            /* 終了時刻記録 */
            ret_stat = gettimeofday(&rec_time, NULL);
            if(ret_stat == 0)
            {
                fprintf(fp, "End\n");
                fprintf(fp, "%ld[sec] %ld[usec]\n", rec_time.tv_sec, rec_time.tv_usec);
                rec_tm = localtime(&(rec_time.tv_sec));
                fprintf(fp, "%d/%d/%d %d:%d:%d\n", 
                        rec_tm->tm_year+1900, rec_tm->tm_mon+1, rec_tm->tm_mday,
                        rec_tm->tm_hour, rec_tm->tm_min, rec_tm->tm_sec);
            }
            fclose(fp);
            
            sync();
            sync();
        }
#ifdef ENABLE_DISK_MOUNT
        /* ディスクをマウントしていた場合は外す */
        DeviceUnmount(usb_rec_info.mount_point);
        mount_flag = 0;
#endif

    } /* while(1) */
    
ErrorEnd:
    /* 赤LEDを点灯させる */
    

#ifdef ENABLE_DISK_MOUNT
    /* ディスクをマウントしていた場合は外す */
    if(mount_flag != 0x0)
    {
        DeviceUnmount(usb_rec_info.mount_point);
    }
    mount_flag = 0;
#endif
    
    CloseSW(fd_sw);
    close(fd_rasp);
    
    return 0;
}

/* デバックモードを解除 */
#undef DEBUG


/* EOF */
