/*
*   X10 IP播报和出厂设置检测程序
*   2019.7.30 lpc
*
*   Intercom device Funtions: Dial && PlayIP
*   Speaker device Funtions: PlayIP && FactoryREST
*/

#include <sys/poll.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>

#define Boolean int
#define TRUE    1
#define FALSE   0
#define MAX_PIPE_BUFSIZE    256

static int playip_lock = FALSE;
static int press_down = FALSE;

static enum devType
{
    INTERCOM = 0,
    SPEAKER
};

static int devType;

Boolean get_ip(char * pv)
{
        FILE * fp;
        char cmdbuf[128], value[32];
        sprintf(cmdbuf,"/sbin/ifconfig eth0 | grep inet | cut -d\":\" -f2 | cut -d\" \" -f1");
        fp = popen(cmdbuf, "r");
        if (fp == NULL) {
                // printf("Fail to open pipe\n");
                return FALSE;
        }

        memset(value,0,sizeof(value));

        if (!feof(fp) && fgets(value,MAX_PIPE_BUFSIZE,fp) != NULL)
            ;
            // printf("value:%s\n", value);
        else {
            printf("ip wrong\n");
            return FALSE;
        }

        pclose(fp);

        if(strlen(value) < 10)
            return FALSE;

        strcpy(pv,value);
        return TRUE;
}

int PlayIP()
{
    //add by ssc 2019-12-26
    char language[32];
    FILE *fp = popen("sysconf /etc/speaker.conf get system language","r");
    if(!fp)
        perror("popen wrong");
    bzero(language,sizeof(language));
    fread(language,1,sizeof(language),fp);
    pclose(fp);
    language[strlen(language)] = '\0';

    playip_lock = TRUE;
    char ipaddr[16],cmd_line[240];
    if(!get_ip(ipaddr)) {
        if (strcmp(language, "en") == 0){
            system("mpg123 -r 48000 /home/new-speaker/target/share/sounds/en/get_ip_failed.mp3");
        }else{
            system("mpg123 -r 48000 /home/new-speaker/target/share/sounds/cn/get_ip_failed.mp3");
        }
        return 0;
    }

    if (strcmp(language, "en") == 0){
        strcpy(cmd_line,"cd /home/new-speaker/target/share/sounds/en/;mpg123 -r 48000 ");
    }else{
        strcpy(cmd_line,"cd /home/new-speaker/target/share/sounds/cn/;mpg123 -r 48000 ");
    }

    int i;
    for (i=0;i<strlen(ipaddr);i++){
        switch(ipaddr[i])
        {
            case '0':
                strcat(cmd_line,"digit-0.mp3 ");
                break;
            case '1':
                strcat(cmd_line,"digit-1.mp3 ");
                break;
            case '2':
                strcat(cmd_line,"digit-2.mp3 ");
                break;
            case '3':
                strcat(cmd_line,"digit-3.mp3 ");
                break;
            case '4':
                strcat(cmd_line,"digit-4.mp3 ");
                break;
            case '5':
                strcat(cmd_line,"digit-5.mp3 ");
                break;
            case '6':
                strcat(cmd_line,"digit-6.mp3 ");
                break;
            case '7':
                strcat(cmd_line,"digit-7.mp3 ");
                break;
            case '8':
                strcat(cmd_line,"digit-8.mp3 ");
                break;
            case '9':
                strcat(cmd_line,"digit-9.mp3 ");
                break;
            case '.':
                strcat(cmd_line,"dian.mp3 ");
                break;
        }
    }
    // printf("cmd-line:%s\n", cmd_line);
    system(cmd_line);
    playip_lock = FALSE;

    return 0;
}

static int checkSIPActive()
{
    char enable[8];
    FILE *fp1;
    bzero(enable,sizeof(enable));
    fp1 = popen("sysconf /etc/speaker.conf get system enabled", "r");
    fread(enable,1,sizeof(enable),fp1);
    pclose(fp1);
    if(!strcmp(enable,"yes")) return TRUE;
    else
        return FALSE;
}

void *thread_playIP(void *p)
{
    if(!playip_lock){
        system("/etc/scripts/change_output_vol.sh reduce;/etc/scripts/pa_mute.sh 0");
        PlayIP();
        system("/etc/scripts/pa_mute.sh 1;/etc/scripts/change_output_vol.sh recover");
    }
    pthread_exit(NULL);
}

void whoami()
{
    char tmp[32];
    FILE *fp = popen("sysconf /etc/speaker.conf get system model","r");
    if(!fp)
        perror("popen wrong");
    bzero(tmp,sizeof(tmp));
    fread(tmp,1,sizeof(tmp),fp);
    pclose(fp);
    tmp[strlen(tmp)] = '\0';

    if(!strncasecmp(tmp, "SH30", 4) || !strncasecmp(tmp, "SW15", 4) || !strncasecmp(tmp, "SC15", 4))
        devType = SPEAKER;
    else if (!strncasecmp(tmp, "IA03", 4) || !strncasecmp(tmp, "IV03", 4))
        devType = INTERCOM;
    else
        devType = SPEAKER;
}

void emergencyCall()
{
    char tmp[32],exten[15],buf[128];
    FILE *fp1;
    bzero(tmp,sizeof(tmp));
    fp1 = popen("sysconf /etc/speaker.conf get intercom repress_cancel", "r");
    fread(tmp,1,sizeof(tmp),fp1);
    pclose(fp1);

    if (!strcmp(tmp,"no")){
        bzero(exten,sizeof(exten));
        fp1 = popen("sysconf /etc/speaker.conf get intercom onekey_num", "r");
        fread(exten,1,sizeof(exten),fp1);
        pclose(fp1);
        if(strlen(exten)){
            sprintf(buf,"linphonecsh dial %s",exten);
            system(buf);
        }
    } else {
        bzero(tmp,sizeof(tmp));
        fp1 = popen("sysconf /userdata/tmp_state.conf get intercom onekey_state", "r");
        fread(tmp,1,sizeof(tmp),fp1);
        pclose(fp1);

        if(strlen(tmp)) {
            if(!strncasecmp(tmp,"idle",4)) // Dial action
            {
                bzero(exten,sizeof(exten));
                fp1 = popen("sysconf /etc/speaker.conf get intercom onekey_num", "r");
                fread(exten,1,sizeof(exten),fp1);
                pclose(fp1);
                if(strlen(exten)){
                    sprintf(buf,"linphonecsh dial %s &",exten);
                    system(buf);
                }
            } else if (!strncasecmp(tmp,"inUse",5)) { // Cancel or Hangup
                system("linphonecsh generic terminate");
                system("sysconf /userdata/tmp_state.conf set intercom onekey_state idle");

            }
        }
    }
}

int main(int argc, char *argv[]){
    struct pollfd fdset;
    int key1_fd, ret, len, count, i;
    char buf[128];
    time_t lastime, newtime;
    FILE *fp1;
    pthread_t  thread;

    // Short delay
    sleep(5);

    /* KEY1 */
    key1_fd = open("/sys/class/gpio/gpio140/value", O_RDONLY);
    read(key1_fd, buf, sizeof(buf));
    lseek(key1_fd, 0, SEEK_SET);

    whoami();

    while(1)
    {
        memset(&fdset, 0x00, sizeof(struct pollfd));
        fdset.fd = key1_fd;
        fdset.events = POLLPRI;


        ret = poll(&fdset, 1, 3000);
        if(ret < 0){
            printf("npoll() faild! \n");
            return -1;
        }
        if(ret == 0)
            continue;

        /*KEY1*/
        if( fdset.revents & POLLPRI )
        {
            count = 0;
            for(i=0;i<50;i++){ // 50ms
                bzero(buf,sizeof(buf));
                read(fdset.fd, buf, sizeof(buf));
                lseek(fdset.fd, 0, SEEK_SET);
                if(buf[0]-'0' == 0)
                    count++;
                usleep(1000);
            }
            // printf("zero counts: %d\n", count);
            if (count >= 30) {
                press_down = TRUE;
                time(&newtime);
                printf("KEY DOWN\n");
            } else {
                time(&lastime);
                len = lastime - newtime;
                printf("KEY UP, Time:%d\n", len);

                if(press_down){
                    press_down = FALSE;
                    if(devType == SPEAKER){
                        if ( len >= 2 && len <= 9) // Play IP
                            pthread_create(&thread, NULL, thread_playIP, NULL);
                        else if ( len >= 1000)
                            pthread_create(&thread, NULL, thread_playIP, NULL);
                        else if ( len >= 10){
                            system("/etc/scripts/play_rebooting.sh;rm -f /oem/.userdata && /sbin/reboot");
                        }
                    } else {
                        if (len >= 5)
                            pthread_create(&thread, NULL, thread_playIP, NULL);
                        else // Make a phone call.
                            if(checkSIPActive())
                                emergencyCall();
                    }
                }
            }
        }
    }
}
