
#include <math.h>
#include <sys/shm.h>
#include "umf_automation.h"
#include "umf_debug.h"
#include "gl_task.h"
#include "gl_mutex.h"
#include "gl_sema.h"
#include "app_event.h"
#include "gl_timer.h"
#include "main_app.h"
#include "sysapp_table.h"

#define UMF_AUTOMATION_DEBUG
#ifdef UMF_AUTOMATION_DEBUG
#undef	DEBF
#define	DEBF(fmt, arg...)	UMFDBG(0,fmt, ##arg)
#else
#define	DEBF(fmt, arg...)
#endif


#define RANDOM_DELAY_MAX    30
#define RANDOM_DELAY_MIN    10
#define TIME_UNIT	100
#define MAX_CMD_SIZE	100
#define MAX_LINE_SIZE	40
#define SHMEM_LEN 100

#define IR_MANUAL_REC_FILENAME	"/mnt/sda1/ManualIRRecord.txt"
#define IR_AUTO_REC_FILENAME		"/mnt/sda1/AutoIRRecord.txt"

#define DEFAULT_CODE 0x649B

static int _bRecCmdStart = 0;
static UINT32 _rtc = 0;
static UINT8 gBreakCondition = 0;
static UINT8 gTestMethod = 0;
static UINT8 gRepeatMode = 0;
static UINT32 gdMax = RANDOM_DELAY_MAX;
static UINT32 gdMin = RANDOM_DELAY_MIN;
GL_Task_t gTaskHandle;
GL_Semaphore_t pThreadSemaphore = NULL;
GL_Semaphore_t pSemaphore = NULL;


static AutoCmdPool_t* CMDPool = NULL;
static AutoMation_CallBack_t g_pfAutoMationCallback = NULL;
//static FILE *fd_auto = NULL;
static FILE *fd_manual = NULL;

AutoCmdPool_t DefaultCMDPool[] =
{
	{UI_EVENT_CH_UP, 50},
};

int nCmdCnt = sizeof(DefaultCMDPool) / sizeof(AutoCmdPool_t);

AutoCmdTable_t CMDTable[] = 
{
	{UI_EVENT_KEYPAD_MENU, "keypad_menu"},
	{UI_EVENT_KEYPAD_DOWN, "keypad_down"},
	{UI_EVENT_KEYPAD_UP, "keypad_up"},
	{UI_EVENT_KEYPAD_SOURCE, "keypad_source"},
	{UI_EVENT_KEYPAD_LEFT, "keypad_left"},
	{UI_EVENT_KEYPAD_RIGHT, "keypad_right"},
	{UI_EVENT_KEYPAD_POWER, "keypad_power"},
	{UI_EVENT_KEYPAD_EXIT, "keypad_exit"},
	{UI_EVENT_KEYPAD_EJECT, "keypad_eject"},
	{UI_EVENT_KEYPAD_PLAY, "keypad_play"},
	{UI_EVENT_KEYPAD_STOP, "keypad_stop"},
	{UI_EVENT_0, "key_0"},
	{UI_EVENT_1, "key_1"},
	{UI_EVENT_2, "key_2"},
	{UI_EVENT_3, "key_3"},
	{UI_EVENT_4, "key_4"},
	{UI_EVENT_5, "key_5"},
	{UI_EVENT_6, "key_6"},
	{UI_EVENT_7, "key_7"},
	{UI_EVENT_8, "key_8"},
	{UI_EVENT_9, "key_9"},
	{UI_EVENT_10, "key_10"},
	{UI_EVENT_POWER, "key_power"},
	{UI_EVENT_UP, "key_up"},
	{UI_EVENT_DOWN, "key_down"},
	{UI_EVENT_LEFT, "key_left"},
	{UI_EVENT_RIGHT, "key_right"},
	{UI_EVENT_ENTER, "key_enter"},
	{UI_EVENT_DISPLAY, "key_display"},
	{UI_EVENT_MUTE, "key_mute"},
	{UI_EVENT_VOL_UP, "key_vol_up"},
	{UI_EVENT_VOL_DN, "key_vol_dn"},
	{UI_EVENT_MENU, "key_menu"},
	{UI_EVENT_GOTO, "key_goto"},
	{UI_EVENT_AB, "key_ab"},
	{UI_EVENT_STOP, "key_stop"},
	{UI_EVENT_PLAY, "key_play"},
	{UI_EVENT_PAUSE, "key_pause"},
	{UI_EVENT_SLOW, "key_slow"},
	{UI_EVENT_FF, "key_ff"},
	{UI_EVENT_FR, "key_rf"},
	{UI_EVENT_NEXT, "key_next"},
	{UI_EVENT_PREV, "key_prev"},
	{UI_EVENT_RED, "key_red"},
	{UI_EVENT_GREEN, "key_green"},
	{UI_EVENT_YELLOW, "key_yellow"},
	{UI_EVENT_BLUE, "key_blue"},
	{UI_EVENT_TV_DVD, "key_tv_dvd"},
	{UI_EVENT_RETURN, "key_return"},
	{UI_EVENT_PLAY_PAUSE, "key_play_pause"},
	{UI_EVENT_FAV_UP, "key_fav_up"},
	{UI_EVENT_FAV_DN, "key_fav_dn"},
	{UI_EVENT_TTX_MIX, "key_ttx_mix"},
	{UI_EVENT_TTX_LANGUAGE, "key_ttx_language"},
	{UI_EVENT_REC_FILE, "key_rec_file"},
	{UI_EVENT_CH_UP, "key_ch_up"},
	{UI_EVENT_CH_DN, "key_ch_dn"},
	{UI_EVENT_FAV, "key_fav"},
	{UI_EVENT_AUDIO, "key_audio"},
	{UI_EVENT_TVRADIO, "key_tvradio"},
	{UI_EVENT_ATVDTV, "key_atvdtv"},
	{UI_EVENT_DVBC, "key_dvbc"},
	{UI_EVENT_DVBS, "key_dvbs"},
	{UI_EVENT_PAGE_UP, "key_page_up"},
	{UI_EVENT_PAGE_DN, "key_page_dn"},
	{UI_EVENT_RECALL, "key_recall"},
	{UI_EVENT_EXIT, "key_exit"},
	{UI_EVENT_TEXT, "key_text"},
	{UI_EVENT_EPG, "key_epg"},
	{UI_EVENT_SUBTITLE, "key_subtitle"},
	{UI_EVENT_SOURCE, "key_source"},
	{UI_EVENT_REC, "key_rec"},
	{UI_EVENT_ASPECT, "key_aspect"},
	{UI_EVENT_TIMESHIFT, "key_timeshift"},
	{UI_EVENT_PIC_MOD, "key_pic_mod"},
	{UI_EVENT_SND_MOD, "key_snd_mod"},
	{UI_EVENT_FREEZE, "key_freeze"},
	{UI_EVENT_SLEEP, "key_sleep"},
	{UI_EVENT_HOME, "key_home"},
	{UI_EVENT_ANDROID, "key_android"},
	{UI_EVENT_CECAUDIO, "key_cecaudio"},
	{UI_EVENT_DOT, "key_dot"},
	{UI_EVENT_SKYPE, "key_skype"},
	{UI_EVENT_CC, "key_cc"},
	{UI_EVENT_TTX_INDEX, "key_ttx_index"},
	{UI_EVENT_TTX_SIZE, "key_ttx_size"},
	{UI_EVENT_TTX_REVEAL, "key_ttx_reveal"},
	{UI_EVENT_TTX_HOLD, "key_ttx_hold"},
	{UI_EVENT_TTX_SUBPAGE, "key_ttx_subpage"},
	{UI_EVENT_TTX_CANCEL, "key_ttx_cancel"},
	{UI_EVENT_DEVLIST, "key_devlist"},
	{UI_EVENT_CHLIST, "key_chlist"},
	{UI_EVENT_SRC_USB, "key_src_usb"},
	{UI_EVENT_SRC_NET, "key_src_net"},
	{UI_EVENT_PIP_MENU, "key_pip_menu"},
	{UI_EVENT_FACTORY, "key_factory"},
	{UI_EVENT_INITIAL, "key_initial"},
	{UI_EVENT_FAC_HOTEL, "key_fac_hotel"},
	{UI_EVENT_MEDIA, "key_media"},
	{UI_EVENT_REC_LIST, "key_rec_list"},
	{UI_EVENT_DVD, "key_dvd"},
	{UI_EVENT_PANEL_INDEX_0, "key_panel_index_0"},
	{UI_EVENT_PANEL_INDEX_1, "key_panel_index_1"},
	{UI_EVENT_PANEL_INDEX_2, "key_panel_index_2"},
	{UI_EVENT_PANEL_INDEX_3, "key_panel_index_3"},
	{UI_EVENT_PANEL_INDEX_4, "key_panel_index_4"},
	{UI_EVENT_3D, "key_3d"},
	{UI_EVENT_AD, "key_ad"},
	{UI_EVENT_ATV, "key_atv"},
	{UI_EVENT_AV, "key_av"},
	{UI_EVENT_YPP, "key_ypp"},
	{UI_EVENT_DTV, "key_dtv"},
	{UI_EVENT_SATELLITE, "key_satellite"},
	{UI_EVENT_CABLE, "key_cable"},
	{UI_EVENT_HDMI, "key_hdmi"},
	{UI_EVENT_PIC_ASPECT, "key_pic_aspect"},
	{UI_EVENT_SOUND_MTS, "key_sound_mts"},
	{UI_EVENT_MultiPanelIndex, "key_multipanelindex"},
	{UI_EVENT_CHECK_UPGRADE, "key_check_upgrage"},
	{UI_EVENT_PCAUTOADJ, "key_pc_autoadj"},
	{UI_EVENT_AUTO_DTV, "key_auto_dtv"},
	{UI_EVENT_AUTO_ATV, "key_auto_atv"},
	{UI_EVENT_AUTO_SCART1, "key_auto_scart1"},
	{UI_EVENT_AUTO_SCART2, "key_auto_scart2"},
	{UI_EVENT_AUTO_YPBPR1, "key_auto_ypbpr1"},
	{UI_EVENT_AUTO_YPBPR2, "key_auto_ypbpr2"},
	{UI_EVENT_AUTO_YPBPR3, "key_auto_ypbpr3"},
	{UI_EVENT_AUTO_PC, "key_auto_pc"},
	{UI_EVENT_AUTO_HDMI1, "key_auto_hdmi1"},
	{UI_EVENT_AUTO_HDMI2, "key_auto_hdmi2"},
	{UI_EVENT_AUTO_HDMI3, "key_auto_hdmi3"},
	{UI_EVENT_AUTO_HDMI4, "key_auto_hdmi4"},
	{UI_EVENT_AUTO_AV1, "key_auto_av1"},
	{UI_EVENT_AUTO_AV2, "key_auto_av2"},
	{UI_EVENT_AUTO_AV3, "key_auto_av3"},
	{UI_EVENT_AUTO_SVIDEO1, "key_auto_svideo1"},
	{UI_EVENT_AUTO_SVIDEO2, "key_auto_svideo2"},
	{UI_EVENT_AUTO_DVD, "key_auto_dvd"},
#ifdef CONFIG_SUPPORT_HOTKEY_SOURCE_LOCK
	{UI_EVENT_FAC_SOURCE_LOCK, "key_fac_sourcelock"},
#endif
	{UI_EVENT_AUTO_MEDIA, "key_auto_media"},
	{UI_EVENT_AUTO_OUTPUTCI, "key_auto_outputci"},
	{UI_EVENT_AUTO_READCI, "key_auto_readci"},
	{UI_EVENT_AUTO_OUTPUTSCART, "key_auto_outputscart"},
	{UI_EVENT_AUTO_OUTPUTPCADJ, "key_auto_outputpcadj"},
	{UI_EVENT_FAC_RESET, "key_fac_reset"},
#ifdef SUPPORT_HKC_FACTORY_REMOTE
	{UI_EVENT_HKC_ENTER_BURNINGMODE, "hkc_enter_burningmode"},
	{UI_EVENT_HKC_EXIT_BURNINGMODE, "hkc_exit_burningmode"},
	{UI_EVENT_HKC_DTV, "hkc_dtv"},
	{UI_EVENT_HKC_DVBC, "hkc_dvbc"},
	{UI_EVENT_HKC_DVBS, "hkc_dvbs"},
	{UI_EVENT_HKC_CIINFO, "hkc_ciinfo"},
	{UI_EVENT_HKC_DVD, "hkc_dvd"},
	{UI_EVENT_HKC_FACTORYMENU, "hkc_factorymenu"},
	{UI_EVENT_HKC_VERSION, "hkc_version"},
	{UI_EVENT_HKC_RESET, "hkc_reset"},
	{UI_EVENT_HKC_VOLUME80, "hkc_volume80"},
	{UI_EVENT_HKC_VOLUMEUP10, "hkc_volumeup10"},
	{UI_EVENT_HKC_VOLUMEDOWN10, "hkc_volumedown10"},
	{UI_EVENT_HKC_PCAUTO, "hkc_pcauto"},
	{UI_EVENT_HKC_ADCADJUST, "hkc_adcadjust"},
	{UI_EVENT_HKC_RESET_DEFAULT_FAC, "hkc_reset_default_fac"},
	{UI_EVENT_HKC_TV, "hkc_tv"},
	{UI_EVENT_HKC_AV, "hkc_av"},
	{UI_EVENT_HKC_AV2, "hkc_av2"},
	{UI_EVENT_HKC_PC, "hkc_pc"},
	{UI_EVENT_HKC_YPBPR, "hkc_ypbpr"},
	{UI_EVENT_HKC_YPBPR2, "hkc_ypbpr2"},
	{UI_EVENT_HKC_HDMI, "hkc_hdmi"},
	{UI_EVENT_HKC_HDMI2, "hkc_hdmi2"},
	{UI_EVENT_HKC_HDMI3, "hkc_hdmi3"},
	{UI_EVENT_HKC_SCART, "hkc_scart"},
	{UI_EVENT_HKC_USB, "hkc_usb"},
#endif
#ifdef CONFIG_SUPPORT_HELP_MENU
	{UI_EVENT_HELP, "key_help"},
#endif
	{UI_EVENT_PVR_ONOFF, "key_pvr_onoff"},
	{UI_EVENT_EPG_ONOFF, "key_epg_onoff"},
};

static int shmid;
static void *shared_memory = NULL;
static char *shared_stuff = NULL;

static UINT32 GetRandomTime(void)
{
	UINT32 dDiff = gdMax - gdMin;
	return (gdMin + (rand() % dDiff));
}

static int GetKeyByStr(char *string, UINT32 *data)
{
	UINT32 i = 0;
	if (string)
	{
		for (i = 0; i < sizeof(CMDTable)/sizeof(AutoCmdTable_t); i++)
		{
			if (!strcmp(string,CMDTable[i].pString))
			{
				break;
			}
		}

		if (i >= sizeof(CMDTable)/sizeof(AutoCmdTable_t))
		{
			*data = 0;
			return -1;
		}
		else
		{
			*data = CMDTable[i].dCMD;
			return 0;
		}
	}

	return -1;
}

static UINT32 GetCusCodeByStr(char *string)
{
	UINT32 i = 0;
	UINT8 b16Flag = 0;
	UINT32 CusCode = 0;
	
	if (string == NULL)
	{
		return DEFAULT_CODE;
	}	

	if (strlen(string) > 2)
	{
		if (string[i] == '0' && string[i+1] =='x')
		{
			b16Flag = 1;
			i += 2;
		}
		else
		{
			b16Flag = 0;
		}
	}

	if (b16Flag)
	{
		CusCode = strtoul(&(string[i]), NULL, 16);
	}
	else
	{
		CusCode = strtoul(&(string[i]), NULL, 10);
	}
	DEBF("[%s:%d] CusCode =========== %d\n",__FUNCTION__,__LINE__,CusCode);
	return CusCode;
}

static void WriteOneCmdToFile(FILE *fd, AutoCmdPool_t stCmd, UINT32 nCnt)
{
	if (fd == NULL)
	{
		DEBF("[%s:%d] open file faile\n",__FUNCTION__,__LINE__);
		return;
	}
	
	char Output_Buf[MAX_LINE_SIZE];
	UINT8 u8Len = 0;
	UINT8 u8Count = 0;

	memset(Output_Buf, 0, MAX_LINE_SIZE);

	u8Len = sizeof(CMDTable) / sizeof(AutoCmdTable_t);

	for (u8Count = 0; u8Count < u8Len; u8Count++)
	{
		if (CMDTable[u8Count].dCMD == stCmd.dCMD)
		{
			sprintf(Output_Buf, "{%d,%d,%d} %s\n",stCmd.dDelay, stCmd.dCMD, stCmd.dParam, CMDTable[u8Count].pString);
			break;
		}
	}

	if (u8Count >= u8Len)
	{
		return;
	}

	DEBF("[%s: %d] %s\n",__FUNCTION__,__LINE__,Output_Buf);
	fputs(Output_Buf, fd);
	fflush(fd);
	fsync(fileno(fd));
}

static void AUTO_MainRoutine(void* pArg)
{
	UINT32 index = 0;
	UINT32 dTableSize = nCmdCnt;//sizeof(CMDPool) / sizeof(AutoCmdPool_t);
	UINT8 dFirstLoop = TRUE;
	DEBF("[automation] Table size = %d.\n", dTableSize);
	
	while(gBreakCondition)
	{
		if(gTestMethod == SEQUENTIAL_TEST || gTestMethod == RECORDED_TEST)
		{
			if(index < dTableSize)
			{
				if (g_pfAutoMationCallback != NULL)
				{
					if(CMDPool[index].dDelay != RANDOM_TIME_DELAY)
					{
						if (dFirstLoop)
						{
							//GL_TaskSleep(GetRandomTime() *100);
							GL_SemaphoreTake(pSemaphore, GetRandomTime() *100);
							dFirstLoop = FALSE;
						}
						else
						{
							//GL_TaskSleep(CMDPool[index].dDelay);
							GL_SemaphoreTake(pSemaphore, CMDPool[index].dDelay);
						}
					}
					else
					{
						//GL_TaskSleep(GetRandomTime() *100);
						GL_SemaphoreTake(pSemaphore, GetRandomTime() *100);
					}

					if (gBreakCondition == 0)
					{
						break;
					}
					
					g_pfAutoMationCallback(CMDPool[index].dCMD, CMDPool[index].dParam,0);
					
					index++;
					if(index == dTableSize && gRepeatMode == TEST_REPEAT)
					{
						index = 0;	
					}
				}
			}
			else
			{
				DEBF("[Automation] All Commands have been executed. Task Exiting!!\n");
				gBreakCondition = 0;
				break;
			}
		}
		else if(gTestMethod == RANDOM_TEST)
		{
			index = rand() % dTableSize;
			if (g_pfAutoMationCallback != NULL)
			{
				if(CMDPool[index].dDelay != RANDOM_TIME_DELAY)
				{
					//GL_TaskSleep(CMDPool[index].dDelay);
					GL_SemaphoreTake(pSemaphore, CMDPool[index].dDelay);
				}
				else
				{
					//GL_TaskSleep(GetRandomTime() *100);
					GL_SemaphoreTake(pSemaphore, GetRandomTime() *100);
				}

				if (gBreakCondition == 0)
				{
					break;
				}
				
				g_pfAutoMationCallback(CMDPool[index].dCMD, CMDPool[index].dParam, 0);
			}
		}
	}

	printf("[%s:%d] exit autotest task!!!!!!!!!!!!!!!!!!!\n",__FUNCTION__,__LINE__);

	GL_SemaphoreGive(pThreadSemaphore);
	
	GL_TaskSelfDelete();
	return;
}

static void event_IRTest(int signum,siginfo_t *info,void*myact)
{
	UINT32 KeyValue = 0;
	UINT32 CusCode = 0;
	
	if (info != NULL)
	{
		DEBF("[%s:%d] sival_int ========== %d\n",__FUNCTION__,__LINE__,info->si_value.sival_int);
		switch (info->si_value.sival_int)
		{
			case IR_REC_START:
				AUTO_IF_RecStart();
				break;
			case IR_REC_STOP:
				AUTO_IF_RecStop();
				break;
			case IR_AUTOTEST_M:
				AUTO_IF_Start(RECORDED_TEST, 1);
				break;
			case IR_AUTOTEST_F:
				AUTO_IF_Start(SEQUENTIAL_TEST, 1);
				break;
			case IR_AUTOTEST_R:
				AUTO_IF_Start(RANDOM_TEST, 1);
				break;
			case IR_AUTOTEST_END:
				AUTO_IF_Stop();
				break;
			case IR_AUTOTEST_S:
				AUTO_IF_ShowCmd();
			default:
				DEBF("[%s:%d] input ========== %s, %s\n",__FUNCTION__,__LINE__,shared_stuff, &(shared_stuff[20]));
				if (0 == GetKeyByStr(&(shared_stuff[20]), &KeyValue))
				{
					CusCode = GetCusCodeByStr(shared_stuff);
					g_pfAutoMationCallback(KeyValue, CusCode,0);					
				}
				memset(shared_stuff, 0,SHMEM_LEN);
				break;
		}
	}
}

int AUTO_IF_Initialize(AutoMation_CallBack_t pfCallBack)
{
	g_pfAutoMationCallback = pfCallBack;
	/*fd_auto = fopen(IR_AUTO_REC_FILENAME, "w");

	if (fd_auto == NULL)
	{
		DEBF("[%s:%d] open %s faile\n",__FUNCTION__,__LINE__,IR_AUTO_REC_FILENAME);
	}*/

	GL_Status_t ret = GL_FAILURE;
	ret = GL_SemaphoreCreate("automationThreadSem", 1, 0, &pThreadSemaphore);
	if (ret != GL_SUCCESS)
	{
		DEBF("Error %d: %s call GL_SemaphoreCreate failed2!\n", ret, __FUNCTION__);
		
	}
	ret = GL_SemaphoreCreate("automationSem", 1, 0, &pSemaphore);
	if (ret != GL_SUCCESS)
	{
		DEBF("Error %d: %s call GL_SemaphoreCreate failed2!\n", ret, __FUNCTION__);
		
	}
	return 0;
}


int AUTO_IF_SetRandomMaxnMin(UINT32 dMax, UINT32 dMin)
{
	gdMax = dMax;
	gdMin = dMin;
	return 0;
}

int AUTO_IF_Start(UINT32 dTestMethod, UINT8 bRepeat)
{
	if (gBreakCondition == 1)
	{
		DEBF("ir autotest has running!\n");
        return -1;
	}
	
	gTestMethod = dTestMethod;
	gRepeatMode = bRepeat;

	if (gTestMethod == SEQUENTIAL_TEST)
	{
		AUTO_IF_SetTable(NULL, 0);
	}
	else if (dTestMethod != RECORDED_TEST)
	{
		CMDPool = DefaultCMDPool;
	}

	if(CMDPool == NULL)
	{
		DEBF("No IRC command!\n");
		return -1;
	}

	gBreakCondition = 1;

	while (GL_SemaphoreTake(pSemaphore, GL_NO_WAIT) == GL_SUCCESS) ;
	
	//create task
	GL_Status_t dReturnValue = GL_TaskCreate("Automation", AUTO_MainRoutine, (void *)NULL, AUTOMATION_TASK_PRIORITY, AUTOMATION_STACK_SIZE, true, &(gTaskHandle));
	if(dReturnValue != GL_SUCCESS)
	{
		DEBF("[Automation] Task Create Failed!!\n");
	}
	
	return 0;
}

int AUTO_IF_SetTable(AutoCmdPool_t* stTable, UINT32 dTableSize)
{
	if(gBreakCondition != 0)
	{
		return -1;
	}

	if (stTable != NULL && dTableSize > 0)
	{
		CMDPool = stTable;
		nCmdCnt = dTableSize;
	}
	else
	{
		char Output_Buf[MAX_LINE_SIZE];
		char Temp_Buf1[6];
		char Temp_Buf2[6];
		char Temp_Buf3[6];
		FILE *fd = NULL;
		UINT8 u8StrLen = 0;
		UINT8 u8Count1 = 0;
		UINT8 u8Count2 = 0;
		UINT8 u8Count3 = 0;
		UINT8 u8Count4 = 0;
		UINT8 u8StartFlag = FALSE;
		AutoCmdPool_t stCmd;
		
		nCmdCnt = 0;

		fd = fopen(IR_MANUAL_REC_FILENAME, "r+");

		if (fd == NULL)
		{
			printf("[%s:%d] open file faile!!!!!!!!!!!!!!\n",__FUNCTION__,__LINE__);
			return -1;
		}

		if(CMDPool == NULL)
		{
			CMDPool = GL_MemAlloc(sizeof(AutoCmdPool_t) * MAX_CMD_SIZE);
		}
		memset(CMDPool, 0, (sizeof(AutoCmdPool_t) * MAX_CMD_SIZE));
		nCmdCnt = 0;

		while (1)
		{
			memset(&stCmd, 0, sizeof(AutoCmdPool_t));
			memset(Temp_Buf1, 0, 6);
			memset(Temp_Buf2, 0, 6);
			memset(Temp_Buf3, 0, 6);
			
			if (fgets(Output_Buf, MAX_LINE_SIZE, fd) == NULL)
			{
				if (ferror(fd))
				{
					DEBF("%s() %d File error.\n", __FUNCTION__, __LINE__);
					clearerr(fd);
					break;
				}
				else
				{
					fclose(fd);
					return -1;
				}
			}
			
			u8StrLen = strlen(Output_Buf);

			for (u8Count1 = 0; u8Count1 < u8StrLen; u8Count1++)
			{
				if (Output_Buf[u8Count1] == '{')
				{
					u8StartFlag = 1;
					u8Count2 = 0;
					continue;
				}
				else if (Output_Buf[u8Count1] == '}')
				{
					break;
				}
				else if ((Output_Buf[u8Count1] == ',' || Output_Buf[u8Count1] == ' ') && (u8StartFlag == 1))
				{
					u8StartFlag = 2;
					u8Count3 = 0;
					continue;
				}
				else if ((Output_Buf[u8Count1] == ',' || Output_Buf[u8Count1] == ' ') && (u8StartFlag == 2))
				{
					u8StartFlag = 3;
					u8Count4 = 0;
					continue;
				}

				if (u8StartFlag == 1)
				{
					Temp_Buf1[u8Count2++] = Output_Buf[u8Count1];
				}
				else if (u8StartFlag == 2)
				{
					Temp_Buf2[u8Count3++] = Output_Buf[u8Count1];
				}
				else if (u8StartFlag == 3)
				{
					Temp_Buf3[u8Count4++] = Output_Buf[u8Count1];
				}
			}

			Temp_Buf1[u8Count2] = '\0';
			Temp_Buf2[u8Count3] = '\0';
			Temp_Buf3[u8Count4] = '\0';
			stCmd.dCMD = atoi(Temp_Buf2);
			stCmd.dParam = atoi(Temp_Buf3);
			stCmd.dDelay = atoi(Temp_Buf1);
			DEBF("[%s:%d] dCMD: %d, dParam: %d, dDelay: %d\n",__FUNCTION__,__LINE__,stCmd.dCMD,stCmd.dParam,stCmd.dDelay);
			if ((CMDPool != NULL) && (nCmdCnt < MAX_CMD_SIZE))
			{
				CMDPool[nCmdCnt].dCMD = stCmd.dCMD;
				CMDPool[nCmdCnt].dParam = stCmd.dParam;
				CMDPool[nCmdCnt].dDelay = stCmd.dDelay;
				nCmdCnt ++;
			}
		}
		
		fclose(fd);
		fd = NULL;
	}
	
	return 0;
}

int AUTO_IF_Stop(void)
{
	if (gBreakCondition)
	{
		printf("[%s:%d] stop autotest start!!!!!!!!!!!!!!!!!!!\n",__FUNCTION__,__LINE__);
		while (GL_SemaphoreTake(pThreadSemaphore, GL_NO_WAIT) == GL_SUCCESS) ;
		
		gBreakCondition = 0;
		
		GL_SemaphoreGive(pSemaphore);
		GL_SemaphoreTake(pThreadSemaphore, GL_INFINITE_WAIT);
		
		printf("[%s:%d] stop autotest end!!!!!!!!!!!!!!!!!!!\n",__FUNCTION__,__LINE__);
	}
	return 0;
}

int AUTO_IF_Finalize(void)
{
	if(gTestMethod == RECORDED_TEST)
	{
		if(CMDPool)
		{
			GL_MemFree(CMDPool);
			CMDPool = NULL;
		}
	}
	
	gTestMethod = 0;

	/*if (fd_auto != NULL)
	{
		fclose(fd_auto);
		fd_auto = NULL;
	}*/

	if(pThreadSemaphore)
	{
		GL_SemaphoreDelete(pThreadSemaphore);
		pThreadSemaphore = NULL;
	}

	if(pSemaphore)
	{
		GL_SemaphoreDelete(pSemaphore);
		pSemaphore = NULL;
	}
	
	return 0;
}

void AUTO_IF_RecStart(void)
{
	if(_bRecCmdStart == 1)
	{
		// we already started!!!
		return;
	}
	
	fd_manual = fopen(IR_MANUAL_REC_FILENAME, "w");

	if (fd_manual == NULL)
	{
		DEBF("[%s:%d] open %s faile\n",__FUNCTION__,__LINE__,IR_MANUAL_REC_FILENAME);
	}

	DEBF("%s!!!\n", __FUNCTION__);
	_bRecCmdStart = 1;

	if(CMDPool == NULL)
	{
		CMDPool = GL_MemAlloc(sizeof(AutoCmdPool_t) * MAX_CMD_SIZE);
	}
	memset(CMDPool, 0, (sizeof(AutoCmdPool_t) * MAX_CMD_SIZE));
	nCmdCnt = 0;
	_rtc = 0;
}

void AUTO_IF_RecStop(void)
{	
	if(_bRecCmdStart == 0)
	{
		// we already stopped!!!
		return;
	}

	UINT32 rtc = 0;
	sw_timespec timespec;

	memset(&timespec, 0, sizeof(sw_timespec));
	GL_GetCurrTime(&timespec);
	rtc = (GL_UINT32)((timespec.sec * 1000) + timespec.usec);

	if(nCmdCnt > 0)
	{
		/* modify the first record delay time */
		if (_rtc != 0)
		{
			CMDPool[0].dDelay = rtc - _rtc;
		}
		
		/* add for manual ir record ir to ManualIRRecord.txt */
		if ((_rtc != 0) && (nCmdCnt > 0) && (fd_manual != NULL))
		{
			WriteOneCmdToFile(fd_manual, CMDPool[nCmdCnt-1], nCmdCnt-1);
		}
		
		/* modify the first record delay time */
		if ((_rtc != 0) && (nCmdCnt > 0) && (fd_manual != NULL))
		{
			int uCount = 0;

			fseek(fd_manual, 0, SEEK_SET);

			for (uCount = 0; uCount < nCmdCnt; uCount++)
			{
				WriteOneCmdToFile(fd_manual, CMDPool[uCount], uCount);
			}
		}
	}
	
	_bRecCmdStart = 0;
	
	if(fd_manual != NULL)
	{		
		fclose(fd_manual);
		
		fd_manual = NULL;
	}
}

int AUTO_IF_RecCmd(UINT32 dCmd, UINT32 dParam)
{
	//static UINT32 s_PreRtc = 0;
	//static AutoCmdPool_t s_stCmd;
	UINT32 rtc = 0;
	sw_timespec timespec;

	memset(&timespec, 0, sizeof(sw_timespec));
	GL_GetCurrTime(&timespec);
	rtc = (GL_UINT32)((timespec.sec * 1000) + timespec.usec);

	if(dCmd > UI_EVENT_NULL)
	{
		return 0;
	}
	
	/* add for auto ir record all ir to AutoIRRecord.txt */
	/*if (fd_auto != NULL)
	{
		if (s_PreRtc != 0)
		{
			WriteOneCmdToFile(fd_auto, s_stCmd, nCmdCnt-1);
		}

		if (s_PreRtc != 0)
		{
			s_stCmd.dDelay = rtc - s_PreRtc;
		}
		else
		{
			s_stCmd.dDelay = 0;
		}
		s_stCmd.dCMD = dCmd;
		s_stCmd.dParam = dParam;
		s_PreRtc = rtc;
	}*/

	if(_bRecCmdStart == 0)
	{
		return 0;
	}

	if(nCmdCnt >= MAX_CMD_SIZE)
	{
		DEBF("%s record command full, Max is %d\n", __FUNCTION__, MAX_CMD_SIZE);
		return 0;
	}

	if (CMDPool == NULL)
	{
		return 0;
	}

	/* add for manual ir record ir to ManualIRRecord.txt */
	if ((_rtc != 0) && (nCmdCnt > 0) && (fd_manual != NULL))
	{
		WriteOneCmdToFile(fd_manual, CMDPool[nCmdCnt-1], nCmdCnt-1);
	}
	
	rtc = 0;
	memset(&timespec, 0, sizeof(sw_timespec));
	GL_GetCurrTime(&timespec);
	rtc = (GL_UINT32)((timespec.sec * 1000) + timespec.usec);

	if(_rtc == 0)
	{
		CMDPool[nCmdCnt].dDelay = 0;
	}
	else
	{
		CMDPool[nCmdCnt].dDelay = rtc - _rtc;
	}
	
	CMDPool[nCmdCnt].dCMD = dCmd;
	CMDPool[nCmdCnt].dParam = dParam;
	DEBF("%s(nCmdCnt = %d, cmd = %d,dParam = %d, delay = %d)\n", __FUNCTION__, nCmdCnt, CMDPool[nCmdCnt].dCMD, CMDPool[nCmdCnt].dParam, CMDPool[nCmdCnt].dDelay);
	nCmdCnt++;
		
	_rtc = rtc;

	return 1;
}


void AUTO_IF_ShowCmd(void)
{
	if(CMDPool == NULL)
	{
		DEBF("No IRC command!\n");
		return;
	}
	
	DEBF("%s(%d)\n", __FUNCTION__, nCmdCnt);
	int i;
	for(i = 0; i < nCmdCnt; i++)
	{
		DEBF("[%02d]: CMD = %d, Param = %d, delay = %d\n", i, CMDPool[i].dCMD, CMDPool[i].dParam, CMDPool[i].dDelay);
	}
}

int AUTO_IF_Regist_SignalEvent(void)
{
	struct sigaction sigact;

	sigemptyset( &sigact.sa_mask );
	sigact.sa_handler = (void*)event_IRTest;
	sigact.sa_flags = SA_SIGINFO;
	if( sigaction(SIG_IRTEST, &sigact, NULL) < 0 )
	{
		fprintf( stderr,"Error: sigaction failed! (%s)\n", strerror(errno) );
		return 1;
	}

	/* create shared memory */
	if (shared_stuff == NULL)
	{
		if((shmid = shmget(1234,SHMEM_LEN,0666 | IPC_CREAT)) < 0)
		{
			DEBF("Error: shmget failed!\n");
			return 1;
		}

		shared_memory = shmat(shmid, NULL, 0);
		if (shared_memory == (void *)-1)
		{
			DEBF("Error: shmat failed!\n");
			return 1;
		}
		DEBF("Memory atttached at %p\n",shared_memory);
		shared_stuff = (char *)shared_memory;
	}
	
	return 0;
}


