/*
 * OutputTask.h
 *
 *  Created on: 2020年2月25日
 *      Author: 7564
 */

#ifndef OUTPUTTASK_H_
#define OUTPUTTASK_H_


#include    <sys/time.h>
#include    <sys/timeb.h>
#include    <sys/types.h>
#include    <sys/stat.h>
#include    <sys/types.h>
#include    <sys/ioctl.h>
#include    <sys/socket.h>
#include    <sys/ipc.h>
#include    <sys/shm.h>
#include    <sys/shm.h>
#include    <sys/mman.h>
#include    <linux/wireless.h>
#include    <linux/can.h>
#include    <linux/can/raw.h>
#include    <arpa/inet.h>
#include    <netinet/in.h>

#include    <unistd.h>
#include    <stdarg.h>
#include    <stdio.h>
#include    <stdlib.h>
#include    <unistd.h>
#include    <fcntl.h>
#include    <termios.h>
#include    <errno.h>
#include    <errno.h>
#include    <string.h>
#include    <time.h>
#include    <ctype.h>
#include    <ifaddrs.h>
#include    <stdbool.h>

#define ShmTestKey  2001

#define ARRAY_SIZE(A)       (sizeof(A) / sizeof(A[0]))
#define PASS                1
#define FAIL                -1
#define YES                 1
#define NO                  0
#define PRESS               1
#define RELEASE             0
#define MAX_PSU_QUANTITY        62

int Uart1Fd = -1;
char *priPortName = "/dev/ttyS1";

bool libInitialize = false;
struct timeval _cmdSubPriority_time;

unsigned char Button1 = RELEASE;
unsigned char Button2 = RELEASE;
bool leftBtnPush = false;
bool rightBtnPush = false;

unsigned char _psuCount = 0;
unsigned char isGetCount = NO;

float VOLTAGE;
float CURRENT;

struct PsuModuleInfo {
    unsigned int    PSU_POWER_INFO;
    float           PSU_VOLTAGE_INFO;
    unsigned short  PSU_CURRENT_INFO;
};

struct UnSafeData {
    unsigned char           PSU_COUNT;
    struct PsuModuleInfo    PsuModule[MAX_PSU_QUANTITY];
    unsigned int            PSU_POWER;
    float                   PSU_VOLTAGE;
    unsigned short          PSU_CURRENT;
};

struct UnSafeData           *UnSafeDataInfo;

typedef struct GPIO_IN {
    unsigned char AC_Connector;
    unsigned char AC_MainBreaker;
    unsigned char SPD;
    unsigned char Door_Open;
    unsigned char GFD[2];
    unsigned char AC_Drop;
    unsigned char Emergency_IO;

    unsigned char Emergency_Btn;
    unsigned char Button[2];
    unsigned char Key[4];
} Gpio_in;

Gpio_in gpio_in;

enum CHARGING_MODE {
    CHARGING_MODE_STOP =            0x00,
    CHARGING_MODE_START =           0x01,
    CHARGING_MODE_TERMINATING =     0x10,
};

unsigned char _charging_mode = CHARGING_MODE_STOP;

int tranceive(int fd, unsigned char *cmd, unsigned char cmd_len, unsigned char *rx)
{
    int len;
    tcflush(fd, TCIOFLUSH);
    if (write(fd, cmd, cmd_len) >= cmd_len) {
        usleep(50000);
        len = read(fd, rx, 512);
    } else {
#ifdef SystemLogMessage
        DEBUG_ERROR("Serial command %s response fail.\n", cmd);
#endif
    }

    return len;
}

unsigned char Query_Gpio_Input(unsigned char fd, unsigned char targetAddr, Gpio_in *Ret_Buf)
{
    unsigned char result = FAIL;
    unsigned char tx[7] = {0xaa, 0x00, targetAddr, 0x0a, 0x00, 0x00, 0x00};
    unsigned char rx[512];
    unsigned char chksum = 0x00;
    unsigned char len = tranceive(fd, tx, sizeof(tx), rx);

    if (len > 0) {
        for (int idx = 0; idx < (rx[4] | rx[5] << 8); idx++) {
            chksum ^= rx[6 + idx];
        }

        if ((chksum == rx[6 + (rx[4] | rx[5] << 8)]) &&
                (rx[2] == tx[1]) &&
                (rx[1] == tx[2]) &&
                (rx[3] == tx[3])) {
            Ret_Buf->Button[0]          = (rx[7] >> 1) & 0x01;
            Ret_Buf->Button[1]          = (rx[7] >> 2) & 0x01;

            result = PASS;
        }
    }

    return result;
}

void GetInputGpioStatus()
{
    if (Query_Gpio_Input(Uart1Fd, 0x04, &gpio_in) == PASS) {
        Button1 = gpio_in.Button[0];
        Button2 = gpio_in.Button[1];
    }
}

#endif /* OUTPUTTASK_H_ */