#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <signal.h>
#include <errno.h>
#include <net/if.h>
#include <netdb.h>
#include <syslog.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h> 
#include <pthread.h>
#include <ctype.h>
#include <execinfo.h>

#include "oled_dp.h"
#include "cJSON.h"

#include "main.h"
#include "Serial.h"
#include "uart_proto.h"



oled_config_t g_oled_config;



uint8_t qr_change = 1;

int delay_cnt = 0;

uint8_t qr_img[128][128] = {0};
uint8_t oled_img[1024] = {0};

char cfg_file_name[80] = "/etc/dropbear/accessory/hj_db/oled.config";
char ko_file_name[80] = "ssd1306-revision.ko";

pthread_t key_thread;
pthread_attr_t key_attr;

pthread_t test_dp_thread;
pthread_attr_t test_dp_attr;

pthread_t oled_dp_thread;
pthread_attr_t oled_dp_attr;

pthread_t udp_recv_thread;
pthread_attr_t udp_recv_attr;

pthread_mutex_t data_mutex;

pthread_t uart_recv_thread;
pthread_attr_t uart_recv_attr;

uint32_t run_level_1 = 3600;

uint32_t run_time = 0;  //秒

#define RUN_FLAG_WIFI_SUB_BOARD  "subboard"  // wifi单板测试
#define RUN_FLAG_AGING  "aging"  // 老化
#define RUN_FLAG_TEST  "test"  // 整机产测
#define RUN_FLAG_OK  "success"  // 测试成功

char run_flag[10] = "aging";

char run_flag_file_name[30] = "/product/run_flag";

int key_pressed = 0;

int is_mac_burn();


static void load_cfg_str_from_file(char *cfg_file_name, char *str)
{
    char *temp_str = NULL;
    char line_buf[512] = {0};

    FILE *fp = fopen(cfg_file_name, "r");
    
    if (fp == NULL)
    {
        OLED_LOG_DBG("Unable to open file: %s\n", cfg_file_name);
        OLED_LOG_DBG("Use default cfg\r\n");
        strcpy(str, "aging");
        return;
    }

    if (str == NULL)
    {
        OLED_LOG_DBG("string is null\r\n");
        return;
    }

    temp_str = str;

    while (!feof(fp))
    {
        int read_cnt = 0;

        memset(line_buf, 0, sizeof(line_buf));

        read_cnt = fread(line_buf, 1, sizeof(line_buf), fp);

        OLED_LOG_DBG("read_cnt %d \r\n", read_cnt);

        if (read_cnt > 0)
        {
            memcpy(temp_str, line_buf, read_cnt);
            temp_str += read_cnt;
        }
        else
        {
            break;
        }
    }
    
    fclose(fp);
    return;
}

static void load_ccu_from_file(char *cfg_file_name, char *str)
{
    char *temp_str = NULL;
    char line_buf[512] = {0};

    FILE *fp = fopen(cfg_file_name, "r");
    
    if (fp == NULL)
    {
        OLED_LOG_DBG("Unable to open file: %s\n", cfg_file_name);
        OLED_LOG_DBG("Use default cfg\r\n");
        strcpy(str, "*");
        return;
    }

    if (str == NULL)
    {
        OLED_LOG_DBG("string is null\r\n");
        return;
    }

    temp_str = str;

    while (!feof(fp))
    {
        int read_cnt = 0;

        memset(line_buf, 0, sizeof(line_buf));

        read_cnt = fread(line_buf, 1, sizeof(line_buf), fp);

        OLED_LOG_DBG("read_cnt %d \r\n", read_cnt);

        if (read_cnt > 0)
        {
            memcpy(temp_str, line_buf, read_cnt);
            temp_str += read_cnt;
        }
        else
        {
            break;
        }
    }

    str[5] = '\0';
    fclose(fp);
    return;
}

 void load_sn_from_file(char *cfg_file_name, char *str)
{
    char *temp_str = NULL;
    char line_buf[512] = {0};

    FILE *fp = fopen(cfg_file_name, "r");
    
    if (fp == NULL)
    {
        OLED_LOG_DBG("Unable to open file: %s\n", cfg_file_name);
        return;
    }

    if (str == NULL)
    {
        OLED_LOG_DBG("string is null\r\n");
        return;
    }

    temp_str = str;

    while (!feof(fp))
    {
        int read_cnt = 0;

        memset(line_buf, 0, sizeof(line_buf));

        read_cnt = fread(line_buf, 1, sizeof(line_buf), fp);

        OLED_LOG_DBG("read_cnt %d \r\n", read_cnt);

        if (read_cnt > 0)
        {
            memcpy(temp_str, line_buf, read_cnt);
            temp_str += read_cnt;
        }
        else
        {
            break;
        }
    }

    //str[temp_str] = '\0';
    fclose(fp);
    return;
}




static void load_version_from_file(char *cfg_file_name, char *str,char * whole_ver)
{
    char *temp_str = NULL;
    char line_buf[512] = {0};
    int count = 0;


    if (str == NULL)
    {
        OLED_LOG_DBG("string is null\r\n");
        return;
    }
	

    FILE *fp = fopen(cfg_file_name, "r");
    
    if (fp == NULL)
    {
        OLED_LOG_DBG("Unable to open file: %s\n", cfg_file_name);
        OLED_LOG_DBG("Use default version\r\n");
	  
        strcpy(str, "*");
        return;
    }

   

    temp_str = line_buf;
    count = sizeof(line_buf);

    while (!feof(fp))
    {
        int read_cnt = 0;

        memset(line_buf, 0, sizeof(line_buf));

        read_cnt = fread(temp_str, 1, count, fp);

        OLED_LOG_DBG("read_cnt %d \r\n", read_cnt);

        if (read_cnt > 0)
        {

	     
            //memcpy(temp_str, line_buf, read_cnt);
            temp_str += read_cnt;
			count -= read_cnt;
	}
        else
        {
            break;
        }
    }


	 if((strstr(line_buf,"SW_VER") != NULL ) && (strstr(line_buf," ") != NULL) )
	 {
		 memcpy(str,strstr(line_buf,"SW_VER")+6,strstr(line_buf," ")-strstr(line_buf,"SW_VER")-6);
         memcpy(whole_ver,line_buf,strstr(line_buf," ")-line_buf);
     }
	
	 
    fclose(fp);
    return;
}

void save_cfg_str_to_file(const char *cfg_file_name, char *str)
{
    FILE *file_fd = NULL;

    file_fd = fopen(cfg_file_name, "w+");

    if (NULL == file_fd)
    {
        OLED_LOG_DBG("config %s open error\n", cfg_file_name);
        return;
    }

    fwrite(str, 1, strlen(str), file_fd);

    fflush(file_fd);
    fclose(file_fd);
}

struct thread_recdata
{
    int sockfd;
    char *info;
};

int udp_sock_test_init(void)
{
    int sock_fd;

    struct sockaddr_in server_addr;

    /* Create Socket*/
    if ((sock_fd = socket(AF_INET, SOCK_DGRAM,0)) < 0)
    {
         OLED_LOG_DBG("Failed to create socket\r\n");
        return -1;
    }

    memset(&server_addr,0,sizeof(struct sockaddr_in));
    
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERV_PORT);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)) < 0)
    {
        OLED_LOG_DBG("Failed to bind test socket on port %d\n", SERV_PORT);
        close(sock_fd);
        return -2;
    }
	
    return sock_fd;
}


void *udp_test_handle(void *rec_data)
{
	struct sockaddr_in client_addr;
	socklen_t client_len = sizeof(client_addr);
	char rcv_buff[100];
	int rcv_num = -1;
	int send_len = 0;
	struct thread_recdata *thread_test_info;
	thread_test_info = (struct thread_recdata *)rec_data;
	
	memset(&client_addr, 0, sizeof(client_addr));

	while(1)
	{
		rcv_num= recvfrom(thread_test_info->sockfd, rcv_buff, sizeof(rcv_buff), 0, (struct sockaddr*)&client_addr, &client_len);

		if (rcv_num>0)
	       {
	             rcv_buff[rcv_num] = '\0';
	             OLED_LOG_DBG("%s %u says: %s\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port),rcv_buff);

			if(!strncmp(rcv_buff,"failed",6))
			{
				rcv_buff[6]= '_';
				rcv_buff[7]= 'a';
				rcv_buff[8]= 'c';
				rcv_buff[9]= 'k';

				send_len = 10;
			}
			else if(!strncmp(rcv_buff,"success",7))
			{
				rcv_buff[7]= '_';
				rcv_buff[8]= 'a';
				rcv_buff[9]= 'c';
				rcv_buff[10]= 'k';

				send_len = 11;

				//save_cfg_str_to_file(run_flag_file_name, run_flag);
                save_cfg_str_to_file(run_flag_file_name, "success");
			}
			else
			{
				send_len = sizeof(rcv_buff);
			}

		      sendto(thread_test_info->sockfd,rcv_buff,send_len,0,(struct sockaddr*)&client_addr,sizeof(client_addr)) ;  

		      if(!strncmp(rcv_buff,"success",7)) //如果整机测试成功
		      {
		    	     strcpy(run_flag ,"success\n"); 
                     

			        OLED_LOG_DBG("test_ok,will reset after 10s\r\n");
		      }
		    }
	       else
	       {
		      OLED_LOG_DBG("recv error\n");
	       }
    	}
}

int oled_dp_run_state(void)
{
	char str[32] = {0};

   // if (g_oled_config.ccu_show_qr)
    {
       // int delay_cnt = 0;
       delay_cnt = 0;
        qr_change = 1;

        while (delay_cnt ++ < 5)   //5s
        {
            if (qr_change == 1)
            {
                clear_screen(); 
                
                pthread_mutex_lock(&data_mutex);
                {
                    qr_change = 0;

                    if(!strncmp(run_flag,RUN_FLAG_AGING,5))
                    {
                        show_chn_set(45, 1, 14, 12); //老
                        show_chn_set(57, 1, 15, 12); //化
                        show_chn_set(69, 1, 16, 12); //中
                    }
                    else if(!strncmp(run_flag,RUN_FLAG_WIFI_SUB_BOARD,8))
                    {
                        show_chn_set(30, 1, 20, 12); //单
                        show_chn_set(42, 1, 21, 12); //板
                        show_chn_set(54, 1, 18, 12); //产
                        show_chn_set(66, 1, 19, 12); //测
                        show_chn_set(78, 1, 16, 12); //中
                    }
                    else if(!strncmp(run_flag,RUN_FLAG_TEST,4))
                    {
                        show_chn_set(30, 1, 17, 12); //整
                        show_chn_set(42, 1, 13, 12); //机
                        show_chn_set(54, 1, 18, 12); //产
                        show_chn_set(66, 1, 19, 12); //测
                        show_chn_set(78, 1, 16, 12); //中
                    }
			
                    sprintf(str, "%02d%c%02d", run_time/3600 , ':' , (run_time%3600)/60);
					
                	show_str_set(str, 45, 5, show_8x16_mode);
                }
                pthread_mutex_unlock(&data_mutex);
            }

            for (int c = 0; c < 10; c ++)   //  1s
            {
                usleep(100000);   // 100ms
            }

            run_time ++;

		
        }
    }

    return 0;
}

int oled_dp_info(void)
{
    char str[32] = {0};
    char ip[32] = "0.0.0.0";

    #if 1
    {
        int sd;
        struct sockaddr_in sin;
        struct ifreq ifr;

        sd = socket(AF_INET, SOCK_DGRAM, 0);

        if (-1 == sd)
        {
            OLED_LOG_DBG("socket error: %s\n", strerror(errno));
        }
        else
        {
            strncpy(ifr.ifr_name, g_oled_config.ccu_lan, IFNAMSIZ);
            
            ifr.ifr_name[IFNAMSIZ - 1] = 0;

            if (ioctl(sd, SIOCGIFADDR, &ifr) < 0)
            {
                OLED_LOG_DBG("ioctl error: %s\n", strerror(errno));
                snprintf(ip, IP_SIZE, "0.0.0.0");
            }
            else
            {
                memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
                snprintf(ip, IP_SIZE, "%s", inet_ntoa(sin.sin_addr));
            }

            close(sd);
        }
    }
    #endif

    time_t now;
    struct tm *timenow;

    {
        time(&now);
        timenow = localtime(&now);
    }
    
  //  int i = 0;
    delay_cnt = 0;

    int hour = timenow->tm_hour;
    int min = timenow->tm_min;

    qr_change = 1;

    while (delay_cnt ++ < 5)  //5s
    {
        if (qr_change == 1)
        {
            pthread_mutex_lock(&data_mutex);
            
            {
                qr_change = 0;

                clear_screen();

                sprintf(str, "%s", ip);
                show_str_set(str, 0, 0, show_6x8_mode);  //IP显示

                #if defined (AR9331)
                {
                    show_str_set("3", 120, 0, show_6x8_mode); 
                }
                #elif defined (AR9533)
                {
                    show_chn_set(104, 0, 12, 12);
                    show_chn_set(116, 0, 13, 12);
                }
                #endif

				/* 日期显示 */
                sprintf(str, "%d-%d-%d", timenow->tm_year + 1900, timenow->tm_mon + 1, timenow->tm_mday);
                show_str_set(str, 35, 2, show_6x8_mode);

				/* 时间显示 */
                sprintf(str, "%02d%c%02d", timenow->tm_hour, timenow->tm_sec % 2 == 1 ? ':' : ' ', timenow->tm_min);
                show_str_set(str, 45, 3, show_8x16_mode);

				/* CCUID显示 */

		   memset(g_oled_config.ccu_id,0,sizeof(g_oled_config.ccu_id));
		   load_ccu_from_file(CCUID_CFG_FILE,g_oled_config.ccu_id);
				
                sprintf(str, "%s(%s)", g_oled_config.ccu_id, g_oled_config.ccu_version);
                show_str_set(str, 0, 7, show_6x8_mode);

				/* 主机状态显示 */
                if (g_oled_config.ccu_status == 0)     //正常
                {
                   // show_chn_set(104, 6, 4, 12);
                   // show_chn_set(116, 6, 5, 12);

		     show_chn_set(104, 6, 18, 12); //产
		     show_chn_set(116, 6, 19, 12); //测
                }
                else if (g_oled_config.ccu_status == 1) //
                {
                    show_chn_set(104, 6, 8, 12);
                    show_chn_set(116, 6, 9, 12);
                }
                else if (g_oled_config.ccu_status == 2) 
                {
                    show_chn_set(104, 6, 10, 12);
                    show_chn_set(116, 6, 11, 12);
                }
                else
                {
                    sprintf(str, "E%02d", g_oled_config.ccu_status);
                    show_str_set(str, 92, 7, show_6x8_mode);
                }
            }

            pthread_mutex_unlock(&data_mutex);
        }

        {
            time(&now);
            timenow = localtime(&now);
        }

        if (hour != timenow->tm_hour || min != timenow->tm_min)
        {
            hour = timenow->tm_hour;
            min = timenow->tm_min;

            sprintf(str, "%02d%c%02d", timenow->tm_hour, timenow->tm_sec % 2 == 1 ? ':' : ' ', timenow->tm_min);
            show_str_set(str, 45, 3, show_8x16_mode);
        }
        else
        {
            char str_ch[8] = {0};
            sprintf(str_ch, "%c", timenow->tm_sec % 2 == 1 ? ':' : ' ');
            show_str_set(str_ch, 45 + 8 * 2, 3, show_8x16_mode);
        }
        
        //每次显示延时10s
        for (int c = 0; c < 10; c ++)
        {
            usleep(100000);
        }

        run_time ++;
    }

    return 0;
}

void *oled_dp(void *parameter)
{
    int ops_start_gw_flag = 0;
    int ops_reset_firmware__flag = 0;
   // wakeup_screen();
    clear_screen();

    while (1)
    {
        int ret = is_mac_burn();
        if(ret == 1)
		{
			if (!strncmp(run_flag,RUN_FLAG_WIFI_SUB_BOARD,8)) //wifi单板测试
            {
                oled_dp_run_state();
                oled_dp_info();

                //另外的线程处理串口数据
            }
            else if (!strncmp(run_flag,RUN_FLAG_AGING,5)) //老化
            {
                oled_dp_run_state();
                oled_dp_info();

                if(run_time >= 14400)  // 单位秒，4个小时
                {
                    OLED_LOG_DBG("aging_ok,wait for test\r\n");
                    
                    strcpy(run_flag ,RUN_FLAG_TEST);

                    save_cfg_str_to_file(run_flag_file_name, run_flag);
                    OLED_LOG_DBG("test string to file ok\n");

                    run_time = 0;
                }
            }
			else if(!strncmp(run_flag,RUN_FLAG_TEST,4)) //整机产测
			{
				if(ops_start_gw_flag == 0)
				{
					ops_start_gw_flag = 1;
						
					//进入整机之前获取ccuid
					system("export LD_LIBRARY_PATH=/home/hj/smarthome/lib");

	                system("/sbin/hj_auth_ccuid.sh &");

					system("/product/SmartGateway.AR9533 -f TEST -h 2 &");   //  入墙主机参数是-h  1，桌面主机是-h 2

					OLED_LOG_DBG("running---SmartGateway.ar9531\r\n");

				}

				oled_dp_run_state();
				oled_dp_info();
			}
			else if(!strncmp(run_flag,RUN_FLAG_OK,7))
			{
				oled_dp_info();
			
				if(ops_reset_firmware__flag == 0)
				{
					ops_reset_firmware__flag = 1;

					save_cfg_str_to_file(run_flag_file_name, run_flag);

					OLED_LOG_DBG("exe---firstboot -y && reboot\r\n");

					system("firstboot -y && reboot -f");//恢复出厂设置
				}
			}
		}
		else if(ret == 0)
		{
			
			 clear_screen();
			 //show_str_set("mac no burn", 25, 3, show_8x16_mode); 
             show_str_set("MAC ", 25, 3, show_8x16_mode); 
	         show_chn_set(54, 3, 22, 16); //未
			 show_chn_set(74, 3, 23, 16); //烧
			 show_chn_set(94, 3, 24, 16); //录
			 sleep(10);
			 oled_dp_info();
			
		}
        else 
        {
             clear_screen();
			 show_str_set("checking mac...", 25, 3, show_8x16_mode); 
			 sleep(10);
			 oled_dp_info();
        }
	       
    }
}

void *uart_recv_deamon(void *parameter)
{


    fd_set rd;
    int nFlag;
    struct timeval tval = {2,0};

    int count = 0;
    unsigned char data_buf[512];
    teSerial_Status ret = E_SERIAL_ERROR;
    eSerial_start();

    while (1)
    {
        //判断是否在单板产测状态
        if(!strncmp(run_flag,RUN_FLAG_WIFI_SUB_BOARD,8))
        {     
            FD_ZERO(&rd);
            FD_SET(serial_fd,&rd);

            nFlag = select(serial_fd + 1, &rd, NULL, NULL, &tval);

            if(0 > nFlag)
            {
                OLED_LOG_DBG("uartRecv():select error !\n");
                OLED_LOG_DBG("uartRecv errno = %d", errno);
                usleep( 100000 );
            }
            else if(0 == nFlag)
            {
                //OLED_LOG_DBG( "----------------uartRecv():select time out !------------------\n"); 
        
                usleep( 100000 );
            }
            else
            {
                
                if(FD_ISSET(serial_fd, &rd))
                {
                    ret = eSerial_Read(&data_buf[count]);

                    if(ret == E_SERIAL_OK)
                    {
                        if(get_uart_frame((uint8_t *)data_buf,1))
                        {
                            uart_frame_handle();
                        }
                    }
                    else if(ret == E_SERIAL_FD_ERROR)
                    {
                        eSerial_start();
                    }
                }
            }
            
        }
        else
        {
             eSerial_stop();
             if(!strncmp(run_flag,RUN_FLAG_AGING,5))  //老化状态提供cpu使用率
             {
                    int i = 0;
                    while(1)
                    {
                        //usleep(1);
                        i++;
                        i = i%40000;
                        if(i > 0 && i< 10)
                        {
                            usleep(1);
                        }
                        if(strncmp(run_flag,RUN_FLAG_AGING,5) != 0) 
                        {
                            break;
                        }

                    }
             }
        }
    }
}

int key_file_fd = -1;

void key_init(int gpio_num)
{
    char str[120] = {0};
    int re = 0;

    memset(str, 0, sizeof(str));
    snprintf(str, sizeof(str), "/sys/class/gpio/gpio%d", gpio_num);

    if ((access(str, F_OK)) == -1)
    {
        snprintf(str, sizeof(str), "echo %d > /sys/class/gpio/export", gpio_num);
        re = system(str);

        if (re != 0)
        {
            return;
        }
    }

    snprintf(str, sizeof(str), "echo in > /sys/class/gpio/gpio%d/direction", gpio_num);
    re = system(str);

    if (re != 0)
    {
        return;
    }
}

void key_file_init(int gpio_num)
{
    char file_str[80] = {0};

    snprintf(file_str, sizeof(file_str), "/sys/class/gpio/gpio%d/value", gpio_num);

    key_file_fd = open(file_str, O_RDONLY);
    
    if (key_file_fd == -1)
    {
        OLED_LOG_DBG("Unable to open file: %s\n", file_str);
        return;
    }

    return;
}

int key_read(void)
{
    int ret = -1;
    char line_buf[80] = {0};

    if (key_file_fd < 0)
    {
        return ret;
    }

    memset(line_buf, 0, sizeof(line_buf));

    if (lseek(key_file_fd, 0, SEEK_SET) < 0)
    {
        return ret;
    }

    if (read(key_file_fd, line_buf, sizeof(line_buf)) < 0)
    {
        return ret;
    }

    if (strlen(line_buf) > 0)
    {
        ret = atoi(line_buf);
    }

    return ret;
}

int key_file_read(int gpio_num)
{
    int ret = -1;
    char file_str[80] = {0};
    char line_buf[80] = {0};
    FILE *fp = NULL;

    snprintf(file_str, sizeof(file_str), "/sys/class/gpio/gpio%d/value", gpio_num);

    fp = fopen(file_str, "r");
    
    if (fp == NULL)
    {
        OLED_LOG_DBG("Unable to open file: %s\n", file_str);
        return ret;
    }

    memset(line_buf, 0, sizeof(line_buf));
    fgets(line_buf, sizeof(line_buf), fp);

    if (strlen(line_buf) > 0)
    {
        ret = atoi(line_buf);
    }
    
    fclose(fp);
    return ret;
}

uint8_t get_mac(char *mac_name, char *mac_str, int len)
{
    #if 0
    int fd;
    int interface;
    struct ifreq buf[16];
    struct ifconf ifc;

    char mac[32] = {0};

    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
    {
        int i = 0;

        ifc.ifc_len = sizeof(buf);
        ifc.ifc_buf = (caddr_t)buf;

        if (!ioctl(fd, SIOCGIFCONF, (char *)&ifc))
        {
            interface = ifc.ifc_len / sizeof(struct ifreq);

            while (i < interface)
            {
           
                if (strncmp(mac_name, buf[i].ifr_name, strlen(buf[i].ifr_name)) == 0)
                {
                    if (!(ioctl(fd, SIOCGIFHWADDR, (char *)&buf[i])))
                    {
                        sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X",
                            (unsigned char)buf[i].ifr_hwaddr.sa_data[0],
                            (unsigned char)buf[i].ifr_hwaddr.sa_data[1],
                            (unsigned char)buf[i].ifr_hwaddr.sa_data[2],
                            (unsigned char)buf[i].ifr_hwaddr.sa_data[3],
                            (unsigned char)buf[i].ifr_hwaddr.sa_data[4],
                            (unsigned char)buf[i].ifr_hwaddr.sa_data[5]);
                    }
                    snprintf(mac_str, len, "%s", mac);
			close(fd);
                    return 1;
                }
                i ++;
            }
        }

	close(fd);
    }

    return 0;
    #endif

    char *temp_str = NULL;
    char line_buf[512] = {0};
    FILE *fp = NULL;

    if(mac_name == NULL || mac_str == NULL){
        OLED_LOG_DBG(" ARG ERROR \n");
        return 0;
    }

    if(strcmp(ETH1_MAC_NAME,mac_name) == 0){
            fp = fopen(ETH1_ADDRESS_FILE_PATH, "r");
    }
    else if(strcmp(ETH0_MAC_NAME,mac_name) == 0){
            fp = fopen(ETH0_ADDRESS_FILE_PATH, "r");
    }
    
    if (fp == NULL)
    {
        OLED_LOG_DBG("Unable to open file: %s\n", cfg_file_name);
        strcpy(mac_str, "*");
        return 0;
    }

    temp_str = mac_str;

    while (!feof(fp))
    {
        int read_cnt = 0;

        memset(line_buf, 0, sizeof(line_buf));

        read_cnt = fread(line_buf, 1, sizeof(line_buf), fp);

        OLED_LOG_DBG("read_cnt %d \r\n", read_cnt);

        if (read_cnt > 0)
        {
            memcpy(temp_str, line_buf, read_cnt);
            temp_str += read_cnt;
        }
        else
        {
            break;
        }
    }

    fclose(fp);

    //转换为大写
    int i = 0;
    for(i=0;i<strlen(mac_str);i++)
		mac_str[i]=toupper(mac_str[i]);

    return 1;
}

 int is_mac_burn()
 {
	char eth1_mac[32] = "";

	 if (get_mac(ETH1_MAC_NAME, eth1_mac, sizeof(eth1_mac)) == 0)
    {
        OLED_LOG_DBG("eth1 error\n");
        return -1;
    }

	OLED_LOG_DBG("eth1:%s\n",eth1_mac);

    //开头的几位对，且不等于默认mac
	if(strncmp(eth1_mac,"28:D9:8A:",9) == 0 && strncmp(eth1_mac,"28:D9:8A:0B:FF:FF",17) != 0)
	{
		return 1;
	}

	return 0;

 }

void *key_process(void *parameter)
{
    
    key_init(12);
    key_file_init(12);    
   

    while (1)
    {

        usleep(10000);

        if (key_read() == 0)
        {
            if (key_pressed == 0)
            {
                OLED_LOG_DBG("Key pressed\r\n");
            }

            key_pressed += 10;
        }
        else
        {
            if (key_pressed > 0)
            {


                OLED_LOG_DBG("Key released\r\n");
			delay_cnt  = 10;
				
                key_pressed = 0;
            }
        }
    }
}


#if 1

int main(int argc, char **argv)
{
    void *status;
    int rc;

    strcpy(g_oled_config.ccu_udp_path, argv[0]);
    strcat(g_oled_config.ccu_udp_path, "_addr");

    openlog("OLED", LOG_PID, LOG_USER);
     
    memset((uint8_t *)oled_img, 0xff, 1024);
    memset((char *)&g_oled_config, 0, sizeof(oled_config_t));

   load_cfg_str_from_file(run_flag_file_name, run_flag);
   load_version_from_file(VERSION_CFG_FILE, g_oled_config.ccu_version,g_oled_config.version_str);
   load_ccu_from_file(CCUID_CFG_FILE,g_oled_config.ccu_id);
   strcpy(g_oled_config.ccu_lan, "eth1");
   g_oled_config.ccu_show_qr = true;
   

    #if 1 // process input args
    {
        int opt;
        char *opt_str = "f:k:";
        
        while ((opt = getopt(argc, argv, opt_str)) !=  -1)
        {
            if (opt == 'f')
            {
                strncpy(cfg_file_name, optarg, sizeof(cfg_file_name));
            }
            else if (opt == 'k')
            {
                strncpy(cfg_file_name, optarg, sizeof(cfg_file_name));
            }
        }

        if ((strlen(cfg_file_name) == 0) || (strlen(ko_file_name) == 0))
        {
            OLED_LOG_DBG("Usage : %s [-f cfg_file_name] [-k ko_file_nmae]\r\n", argv[0]);
            return 0;
        }
    }
    #endif

   

   

    #if 1 // mutex init
    {
        pthread_mutex_init(&data_mutex, NULL);
    }
    #endif

    

   
    #if 1 // init oled thread
    {
        pthread_attr_init(&oled_dp_attr);

        size_t s = 1500;
        pthread_attr_setstacksize(&oled_dp_attr, s);

        pthread_attr_setdetachstate(&oled_dp_attr, PTHREAD_CREATE_JOINABLE);

        rc = pthread_create(&oled_dp_thread, &oled_dp_attr, oled_dp, NULL);

        if (rc)
        {
            OLED_LOG_DBG("Error : unable to create thread oled_dp\r\n");
            return 0;
        }
    }
    #endif

    #if 1 // init test thread
    {	
    	 struct thread_recdata thread_test;
        int test_sockfd;
        char *buf = NULL;

        while (buf == NULL)
        {
            buf = malloc(1500);
        }

        memset(buf, 0, 1500);

        /* 创建UDP*/
        test_sockfd = udp_sock_test_init();

        if (test_sockfd <= 0)
        {
            OLED_LOG_DBG("socket init error!\r\n");
            return 0;
        }

        thread_test.sockfd = test_sockfd;
        thread_test.info = buf;
    
        pthread_attr_init(&test_dp_attr);

        size_t s = 1500;
        pthread_attr_setstacksize(&test_dp_attr, s);

        pthread_attr_setdetachstate(&test_dp_attr, PTHREAD_CREATE_JOINABLE);

        rc = pthread_create(&test_dp_thread, &test_dp_attr, udp_test_handle, (void *)&thread_test);

        if (rc)
        {
            OLED_LOG_DBG("Error : unable to create thread test_dp\r\n");
            return 0;
        }
    }
    #endif


	#if 1
    {
        pthread_attr_init(&key_attr);

        size_t s = 1500;
        pthread_attr_setstacksize(&key_attr, s);

        pthread_attr_setdetachstate(&key_attr, PTHREAD_CREATE_JOINABLE);

        rc = pthread_create(&key_thread, &key_attr, key_process, NULL);

        if (rc)
        {
            OLED_LOG_DBG("Error : unable to create thread key_process\r\n");
            return 0;
        }
    }
    #endif

     #if 1 // init uart thread
    {
        pthread_attr_init(&uart_recv_attr);

        size_t s = 1500;
        pthread_attr_setstacksize(&uart_recv_attr, s);

        pthread_attr_setdetachstate(&uart_recv_attr, PTHREAD_CREATE_JOINABLE);

        rc = pthread_create(&uart_recv_thread, &uart_recv_attr, uart_recv_deamon, NULL);

        if (rc)
        {
            OLED_LOG_DBG("Error : unable to create thread oled_dp\r\n");
            return 0;
        }
    }
    #endif

    pthread_attr_destroy(&test_dp_attr);
    pthread_attr_destroy(&oled_dp_attr);
    pthread_attr_destroy(&key_attr);
    pthread_attr_destroy(&uart_recv_attr);
	

#if 1
    {
        rc = pthread_join(test_dp_thread, &status);
        
        if (rc)
        {
            OLED_LOG_DBG("Error : unable to join udp_recv\r\n");
            return 0;
        }
    }
#endif

    {
        rc = pthread_join(oled_dp_thread, &status);

        if (rc)
        {
            OLED_LOG_DBG("Error : unable to join oled_dp\r\n");
            return 0;
        }
    }

    {
        rc = pthread_join(key_thread, &status);

        if (rc)
        {
            OLED_LOG_DBG("Error : unable to join key_thread\r\n");
            return 0;
        }
    }

    {
        rc = pthread_join(uart_recv_thread, &status);

        if (rc)
        {
            OLED_LOG_DBG("Error : unable to join key_thread\r\n");
            return 0;
        }
    }

    pthread_exit(NULL);
    return 0;
}

#endif


