/*****************************************************************************
** File: al_channel_search.c
**
** Description: Channel search function framework implement
**
** Copyright(c) 2010 Sunmedia Technologies - All Rights Reserved
**
** Author : kun.li
**
** $Id$
*****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include "gl_task.h"
#include "gl_sema.h"
#include "gl_queue.h"

#ifdef CONFIG_ATV_SUPPORT
#include "customize.h"
#include "mid_atv_scan.h"
#endif

#include "al_area_info.h"
#include "al_aps_table_api.h"
#include "ai_debug_config.h"
#include "al_fw.h"

#ifdef CONFIG_DTV_SUPPORT
#include "mid_dtv_scan.h"
#include "ai_tp_list.h"
#include "mid_siutil_dvb.h"
#endif
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
#include "mid_sat_antenna.h"
#include "mid_playback.h"
#endif
#include "kmf_ioctl.h"
#include "drv_tuner_external.h"
#include "drv_dtv_external.h"
#include "drv_dtv_common.h"
#include "ap_extern.h"
#ifdef CONFIG_ATV_SUPPORT
#include "mid_tablescan.h"
#ifdef CONFIG_SUPPORT_TTX
#include "mid_ats.h"
#endif
#endif
#ifdef CONFIG_CC_SUPPORT
#include "al_cc.h"
#endif
/* debug and error print */
#if CS_DBG_FLAG
	#define CS_DEBUG_MESSAGE(fmt, arg...) \
	do { \
		printf("[Debug]%s: %d Line ", __FUNCTION__, __LINE__); \
		printf(fmt, ##arg); \
	} while(0)
#else
	#define CS_DEBUG_MESSAGE(fmt, arg...);
#endif

#if CS_ERROR_FLAG
	#define CS_ERROR_MESSAGE(fmt, arg...) \
	do { \
		UMFDBG(0,"[Error]%s: %d Line ", __FUNCTION__, __LINE__); \
		UMFDBG(0,fmt, ##arg); \
	} while(0)
#else
	#define CS_ERROR_MESSAGE(fmt, arg...);
#endif

#define CS_DVBS_DBG_FLAG
#ifdef CS_DVBS_DBG_FLAG
	#define CS_DVBS_DEBUG_MESSAGE(fmt, arg...) \
	do { \
		UMFDBG(0,"[DVBS]%s: %d Line ", __FUNCTION__, __LINE__); \
		UMFDBG(0,fmt, ##arg); \
	} while(0)
#else
	#define CS_DVBS_DEBUG_MESSAGE(fmt, arg...);
#endif


/* 1 MHZ */
//#define ATV_UnlockStep					(1000000)
/* 8 MHZ */
#define AnalogScanBandwidth				(8)

#define GET_DEFAULT_BANDWIDTH()			(AnalogScanBandwidth)

#define GET_SEARCH_THREAD_NAME()		("ChannelSearchAppThread")

#define CABLE_GET_NIT_DETECT			(1)
#define CABLE_GET_NIT_PARSE				(2)
#define CABLE_GET_NIT_STOP				(3)

#define BANDWIDTH_6_MHZ  		(6)
#define BANDWIDTH_7_MHZ  		(7)
#define BANDWIDTH_8_MHZ  		(8)

#define SLIP_NUMBER 	7

#if defined(CONFIG_DVB_SYSTEM_DVBS_SUPPORT)
#define DIFFER(X,Y)   ((X)>(Y) ? ((X)-(Y)) : (Y)-(X))
#endif

/* Running status type of channel search task */
typedef	enum
{
	CS_STATE_IDLE = 0,
	CS_STATE_RUNNING,
	CS_STATE_PAUSE,
	CS_STATE_ZOMBIE
} cs_search_state_t;


/* Bland Searching Step  */
typedef enum
{
	DVBS_TP_DEFAULT = 0,
	DVBS_TP_BLIND,
	DVBS_TP_BLIND_START,
	DVBS_TP_BLIND_STEP_MANUAL,
	DVBS_TP_BLIND_STEP_AUTO,
 	DVBS_TP_BLIND_END,
} cs_search_blind_state_t;

/* Internal process message of channel search task */
typedef struct
{
	al_cs_msg_type_en 	enType;
	al_uint32 			uiParams;
} cs_msg_st;

#ifdef CONFIG_ATV_SUPPORT
/* ATV channel search information */
typedef struct
{
	al_uint32	StartFreq;		/* Start Channel Frequency */
	al_uint32	CurrFreq;		/* Current Channel Frequency */
	al_uint32	EndFreq;		/* End Channel Frequency */
	al_uint32	BandWidth;		/* Bandwidth */
	al_uint32 TblLen;
	al_uint32 CurTblIdx;
	al_uint32 *pTbl;
	al_uint8  ucAreaIdx;		/*ATV area*/
	al_uint8  ucBlueScreen;		/*Blue Screen*/
	AL_ScanVideoFormat_t Video_format;
	AL_ScanAudioStd_t Audio_std;
	bool  Manual_Scan; //scan by manual
	al_uint32 Manual_Num;
} AL_Channel_Info_st;

typedef struct
{
	AL_Channel_Info_st 	stInput;
	al_int32			iDirection;
} analog_search_data_st;

#endif

#ifdef CONFIG_DTV_SUPPORT
typedef struct
{
	al_uint32 uiFrequence;
	al_uint32 uiSymRate;
	al_uint32 network_id;
	al_qam_modulation_en enModulation;
	al_bool locked;
} cs_cable_tp_info_st;

typedef struct
{
	al_uint32 uiFrequence;
	al_uint32 uiFreqEnd;
	al_uint32 uiSymRate;
	al_uint32 polarization;
	al_uint32 fe_type;
	al_uint8 modulation;
	al_uint8 ucCode_rate;
	al_uint8 ucSpec_inver;
	al_bool isTry;
} cs_sate_tp_info_st;

typedef struct _AL_T2_List {
	AL_TPSects_Info_st stT2Input;
	struct _AL_T2_List *next;
} AL_T2_List;

typedef struct
{
	al_DVBC_SearchMode_en uiDVBCSearchMode;
	al_uint8 uiNetworkIdAutoEn;
	al_uint8 uiFreqAutoEn;
	al_uint32 uiNetworkScanFreq;
} cs_cable_NetworkScan_info_st;

typedef struct {
	al_uint8			ucAreaIdx;
	MID_ScanTunerType_e	enTunerType;

	struct {
		AL_TPSects_Info_st	stInput;
		const AL_DVBT_AreaTable_t* pstAreaTable;
		al_uint32 uiSectionNum; //total section number
		al_int16 sCurSecInx; //current section index
		al_int16 sCurTpInx; // current TP index of current section
		al_uint8 ucCurBW;
		AL_T2_List *pstT2List;
		al_uint16 CurT2Inx;
		al_uint16 TotalT2count;
		al_uint32 ScanMode;
		/** Freq list derived from NIT frequency_list_descriptor */
		TpListHdl_st stFreqListHdl;
		AL_TPSects_Info_st *pstCurTerTp;
	} Terr;

	struct
	{
		TpListHdl_st stTpListHdl;
		TpListHdl_st stDefaultTpTbl;
		TpListHdl_st stNITTpTbl;
		cs_cable_tp_info_st* pstCurCableTp;
		cs_cable_NetworkScan_info_st pstNetworkScanInfo;
	} Cable;

	struct
	{
		AL_RecHandle_t hNet;
		al_polarity_en ucBlindSearchPolar;
	    al_uint32 uiCurrFreq;
		TpListHdl_st stTpListHdl;
		TpListHdl_st stDefaultTpTbl;
		TpListHdl_st stNITTpTbl;
		TpListHdl_st stBSTpTbl;
		cs_sate_tp_info_st* pstCurSateTp;
	} Satellite;

	struct
	{
		AL_TPSects_Info_st	stInput;
		const AL_DVBT_AreaTable_t* pstAreaTable;
		al_uint32 uiSectionNum; //total section number
		al_int16 sCurSecInx; //current section index
		al_int16 sCurTpInx; // current TP index of current section
		al_uint8 ucCurBW;
	} Sbtvd;

} digital_search_data_st;
#ifdef SUPPORT_ASTRA_LCN
static PMID_ScanMultSrvLCNInfoNode_t pMultiLCNInfoHead = al_null;
#endif
#endif

/* Internal process message of channel search task  */
typedef union
{
#ifdef CONFIG_ATV_SUPPORT
	analog_search_data_st 	analog;
#endif
#ifdef CONFIG_DTV_SUPPORT
	digital_search_data_st 	digital;
#endif
} cs_search_data_un;

typedef void (*cs_search_thread)(void*);
typedef AL_Return_t (*cs_search_callback)(al_uint32, void*);

/* The static datas manager structrue */
typedef struct {
	cs_search_state_t		enState;
	GL_Queue_t			pstQueue;
	GL_Semaphore_t 		pstSemaphore;
	al_uint8 				bContinue;

	al_uint32				uiCapabilities;

	al_cs_search_save_st	pfSave;
	al_cs_search_start_st	pfStart;
	al_cs_search_over_st	pfOver;
	al_cs_search_update_st	pfUpdate;

	al_cs_type_en			enType;
	cs_search_data_un		unScanData;
	al_cs_search_info_st	stSearchInfo;
	al_uint8				ucDmxIsOpen;

	al_uint8				ucLock;
	al_uint8				ucGotNITFlag;
	al_uint8				ucHasGetFreFromNIT;
} cs_info_st;

#ifdef CONFIG_DTV_SUPPORT
static dvbsi_special_spec eSpecialSpec = DVB_SPECIAL_SPEC_NONE;
static bool specialSpecIsModify = FALSE;
static al_bool NetworkScanNeedAbortScan = al_false;
static al_uint16 ServiceNetworkId = 0;
AL_DBTuneType_t geTuneType = AL_DB_MANUAL_SEARCH;
AL_DBPrivateSpec_t gePriSpec = AL_DB_DVB_PRISPEC_DBOOK;
static al_cs_search_query_operator pfQueryOperatorFunc = al_null;
#endif

GL_Task_t dummy_channel_search_TaskHandle;

static cs_info_st g_stCSInfo;
#define GET_CS_INFO()	(&g_stCSInfo)

#define CS_SEND_MSG(type, param) \
	({(msg)->enType = (type); (msg)->uiParams = (param);})

#define CS_GET_SEARCH_DIRECTION() \
	(pstInfo->unScanData.analog.iDirection)

#ifdef SUPPORT_LCN
DBLCNConfInfo_t g_LcnConf;
#endif

static al_uint32 g_CurPolar = POLAR_MAX;
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
static al_uint16 g_wLNBFreq;
static al_uint32 g_DVBSX_CurrentFeType = 0;
static DRV_Frontend_Type_t g_DVBSX_NextScanMode = 0;
static al_uint32 g_DVBSX_DelTp = FALSE;
static cs_sate_tp_info_st* g_pstCurSateTp = NULL;
static BOOLEAN g_isCBandDualLNB = FALSE;
static TpListHdl_st g_pSateLostTpInfo = TP_LIST_INVALID_HDL;
static cs_sate_tp_info_st *g_pstSatLostCurTpInfo = NULL;
static BOOLEAN g_BlindTry = FALSE;
static BOOLEAN g_NeedScanNitList = al_false;

#define MAX_PATTIMEOUT_TYR			(3)
static UINT8 g_PATTimoutTryCnt = 0;
#endif

#ifdef CONFIG_DTV_SUPPORT
/*****************************************************************************
** FUNCTION : static AL_Return_t CS_DtvSearchCallback(al_uint32 eCallbackType,
**						void* pParam)
**
** DESCRIPTION :
**				DTV search callback function registered into middleware
**
** PARAMETERS :
**				eCallbackType - Callback msg type
**				pParam - the search data of middleware
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t  CS_DtvSearchCallback(al_uint32 eCallbackType,
	void* pParam);

/*****************************************************************************
** FUNCTION : static AL_Return_t CS_DigitalAutoSearchInit(void* pdata)
**
** DESCRIPTION :
**				Init digital search area table
**
** PARAMETERS :
**				pdata - the AL_CS_Start input params
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t CS_DigitalAutoSearchInit(void* pdata);

/*****************************************************************************
** FUNCTION : static AL_Return_t CS_DigitalManualSearchInit(void* pdata)
**
** DESCRIPTION :
**				Init digital manual search
**
** PARAMETERS :
**				pdata - the AL_CS_Start input params
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t CS_DigitalManualSearchInit(void* pdata);

#ifdef CONFIG_DVB_SYSTEM_DVBT2_SUPPORT
static void _AI_CS_AddNode(AL_T2_List *pstNewT2Node)
{
	cs_info_st* pstInfo = GET_CS_INFO();
	digital_search_data_st* pstDigital = &(pstInfo->unScanData.digital);

	AL_T2_List *head = pstDigital->Terr.pstT2List;

	if (head == NULL)
	{
		pstDigital->Terr.pstT2List = pstNewT2Node;
		pstNewT2Node->next = NULL;
		return;
	}

	while(head->next != NULL)
	{
		head = head->next;
	}

	head->next = pstNewT2Node;
	pstNewT2Node->next = NULL;

}

static void _AI_CS_GetNode(al_uint16 pos, AL_T2_List **pstNewT2Node)
{
	cs_info_st* pstInfo = GET_CS_INFO();
	digital_search_data_st* pstDigital = &(pstInfo->unScanData.digital);
	al_uint16 i = 0;

	AL_T2_List *head = pstDigital->Terr.pstT2List;

	if (head == NULL)
	{
		*pstNewT2Node = NULL;
		return;
	}

	do
	{
		if (i == pos)
		{
			break;
		}
		head = head->next;
		i++;
	} while(head->next != NULL);

	*pstNewT2Node = head;

}

static void _AI_CS_FreeAllNode(AL_T2_List *head)
{
	AL_T2_List *node = NULL;

	while (head != NULL)
	{
		node = head;
		head = head->next;
		GL_MemFree(node);
	}
}
#endif

#endif

#ifdef CONFIG_ATV_SUPPORT
/*****************************************************************************
** FUNCTION : static AL_Return_t CS_AtvSearchCallback(al_uint32 eCallbackType, void* pParam)
**
** DESCRIPTION :
**				ATV callback function registered into middleware
**
** PARAMETERS :
**				pstAtvResult - the search information
**				uiChannelNumber - current channel index
** RETURN VALUES:
**				void
*****************************************************************************/
static AL_Return_t  CS_AtvSearchCallback(
	al_uint32  eCallbackType, void* pParam);
#endif
/*****************************************************************************
** FUNCTION : AL_Return_t CS_SearchEnter(void* params)
**
** DESCRIPTION :
**				Search task initialize function
**
** PARAMETERS :
**				params - the input params
** RETURN VALUES:
**				void
*****************************************************************************/
static AL_Return_t CS_SearchEnter(void* params);

/*****************************************************************************
** FUNCTION : static void CS_SearchExit(void)
**
** DESCRIPTION :
**				Search task uninitialize function
**
** PARAMETERS :
**				void
** RETURN VALUES:
**				void
*****************************************************************************/
static void CS_SearchExit(void);

/*****************************************************************************
** FUNCTION : static void CS_SearchAppThread(void* pdata)
**
** DESCRIPTION :
**				Channel search module process task
**
** PARAMETERS :
**				pdata - task data
**
** RETURN VALUES:
**				void
*****************************************************************************/
static void CS_SearchAppThread(void* pdata);

al_uint32 AL_CS_GetCurFreq(void)
{
	return g_stCSInfo.stSearchInfo.uiCurFreq;

}

al_uint16 AL_CS_GetAtvCurChannel(void)
{
	return g_stCSInfo.stSearchInfo.u.atv.usCurChaInx;
}
al_uint32 AL_CS_GetCurPolar(void)
{
	return g_CurPolar;
}

/*****************************************************************************
** FUNCTION : static AL_Return_t CS_ACIInit(void)
**
** DESCRIPTION :
**				ACI(Auto Channel Installation) initialize function
**
** PARAMETERS :
**				void
**
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t CS_ACIInit(void)
{
	return AL_SUCCESS;
}

/*****************************************************************************
** FUNCTION : static AL_Return_t CS_StopProcess(cs_msg_st* pstMsg)
**
** DESCRIPTION :
**				The stop message of search task process function
**
** PARAMETERS :
**				pstMsg - Message type
**
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t CS_StopProcess(cs_msg_st* pstMsg)
{
	//cs_info_st* pstInfo =  GET_CS_INFO();

	//pstInfo = pstInfo;

	if (AL_CS_MSG_TYPE_FINISHED != pstMsg->enType
		&& CS_MSG_TYPE_ABORT != pstMsg->enType)
	{
		return AL_FAILURE;
	}

	/* the mid_scan should be finished or idle */
	//pstInfo->enState = CS_STATE_IDLE;//move to cs thread exit set

	/* For ABORT MSG, send abort msg to mid scan,
	** and then change state to ZOMBIE
	** we should wait the mid_scan idle, but it is dumb now, break
	*/

	return AL_SUCCESS;
}

/*****************************************************************************
** FUNCTION : static AL_Return_t CS_PauseProcess(cs_msg_st* pstMsg)
**
** DESCRIPTION :
**				The pause message of search task process function
**
** PARAMETERS :
**				pstMsg - Message type
**
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t CS_PauseProcess(cs_msg_st* pstMsg)
{
	cs_info_st* pstInfo =  GET_CS_INFO();

	//pstInfo = pstInfo;

	if (CS_MSG_TYPE_PAUSE != pstMsg->enType)
	{
		return AL_FAILURE;
	}

	pstInfo->enState = CS_STATE_PAUSE;

	/*
	** send pause msg to mid scan
	** but we do not implement mid_scan pause functions,continue
	*/
	if (AL_CS_TYPE_ANALOG == pstInfo->enType
		|| AL_CS_TYPE_ANALOG_MANUAL  == pstInfo->enType
		|| AL_CS_TYPE_ANALOG_TABLE == pstInfo->enType)
	{
#ifdef CONFIG_ATV_SUPPORT
		if (AL_CS_TYPE_ANALOG_TABLE == pstInfo->enType)
		{
			MID_TableScanPause();
		}
		else
		{
			MID_AnalogTVScanPause();
		}
#endif
	}
	else if ((AL_CS_TYPE_DIGITAL == pstInfo->enType)
		|| (AL_CS_TYPE_DIGITAL_BLIND == pstInfo->enType)
		|| (AL_CS_TYPE_DIGITAL_MANUAL == pstInfo->enType))
	{
#ifdef CONFIG_DTV_SUPPORT
		MID_ScanPause();
#endif
	}
	else if (AL_CS_TYPE_ACI == pstInfo->enType)
	{

	}

	return AL_SUCCESS;
}

/*****************************************************************************
** FUNCTION : static AL_Return_t CS_ResumeProcess(cs_msg_st* pstMsg)
**
** DESCRIPTION :
**				The resume message of search task process function
**
** PARAMETERS :
**				pstMsg - Message type
**
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t CS_ResumeProcess(cs_msg_st* pstMsg)
{
	cs_info_st* pstInfo =  GET_CS_INFO();

	//pstInfo = pstInfo;

	if (CS_MSG_TYPE_RESUME != pstMsg->enType)
	{
		return AL_FAILURE;
	}

	pstInfo->enState = CS_STATE_RUNNING;

	/*
	** send resume msg to mid scan
	** but we do not implement mid_scan resume functions,continue
	*/
	if (AL_CS_TYPE_ANALOG == pstInfo->enType
		|| AL_CS_TYPE_ANALOG_MANUAL  == pstInfo->enType
		|| AL_CS_TYPE_ANALOG_TABLE == pstInfo->enType)
	{
#ifdef CONFIG_ATV_SUPPORT
		if (AL_CS_TYPE_ANALOG_TABLE == pstInfo->enType)
		{
			MID_TableScanResume();
		}
		else
		{
			MID_AnalogTVScanResume();
		}
#endif
	}
	else if ((AL_CS_TYPE_DIGITAL == pstInfo->enType)
		|| (AL_CS_TYPE_DIGITAL_BLIND == pstInfo->enType)
		|| (AL_CS_TYPE_DIGITAL_MANUAL == pstInfo->enType))
	{
#ifdef CONFIG_DTV_SUPPORT
		MID_ScanResume();
#endif
	}
	else if (AL_CS_TYPE_ACI == pstInfo->enType)
	{

	}

	return AL_SUCCESS;
}

/*****************************************************************************
** FUNCTION : static void CS_SearchAppThread(void* pdata)
**
** DESCRIPTION :
**				Channel search module process task
**
** PARAMETERS :
**				pdata - task data
**
** RETURN VALUES:
**				void
*****************************************************************************/
static void CS_SearchAppThread(void* pdata)
{
	CS_DEBUG_MESSAGE("Enter %s\n", __FUNCTION__);

	cs_info_st* pstInfo =  GET_CS_INFO();
	cs_msg_st msg;
	al_int32 timeout = GL_INFINITE_WAIT;
    
    memset(&msg, 0, sizeof(cs_msg_st));
	AL_FW_ActiveFWModule(FW_CHAN_SRCH_MODE);

	FrontendCmd_t  front;
	INT32 fEn = al_true;
	front.cmd = FRONTEND_CMD_SET_TUNER_SCAN_MODE;
	front.param = &fEn;
	ioctl(kmfdev, KMF_IOC_FRONTENDCTRL, &front);

	timeout = ((AL_CS_TYPE_DIGITAL == pstInfo->enType)
		|| (AL_CS_TYPE_DIGITAL_BLIND == pstInfo->enType)
		|| (AL_CS_TYPE_DIGITAL_MANUAL == pstInfo->enType)) ?
		300 : GL_INFINITE_WAIT;

	if (NULL != pstInfo->pfStart
		&& AL_SUCCESS != pstInfo->pfStart())
	{
		goto search_exit;
	}

	if (CS_SearchEnter(pdata))
	{
		goto search_exit;
	}

	pstInfo->bContinue = TRUE;
	pstInfo->enState = CS_STATE_RUNNING;
	if (pstInfo->pstSemaphore)
	{
		// touch for app continue running
		GL_SemaphoreGive(pstInfo->pstSemaphore);
	}

	while (pstInfo->bContinue)
	{
		if (GL_SUCCESS == GL_QueueReceive(pstInfo->pstQueue, &msg, sizeof(cs_msg_st), timeout))
		{
			switch(msg.enType)
			{
				case AL_CS_MSG_TYPE_FINISHED:
					pstInfo->bContinue = FALSE;
					CS_StopProcess(&msg);
					break;
				case CS_MSG_TYPE_ABORT:
					pstInfo->bContinue = FALSE;
					CS_StopProcess(&msg);
					break;
				case CS_MSG_TYPE_PAUSE:
					CS_PauseProcess(&msg);
					if (pstInfo->pstSemaphore)
					{
						// touch for app continue running
						GL_SemaphoreGive(pstInfo->pstSemaphore);
					}
					break;
				case CS_MSG_TYPE_RESUME:
					CS_ResumeProcess(&msg);
					if (pstInfo->pstSemaphore)
					{
						// touch for app continue running
						GL_SemaphoreGive(pstInfo->pstSemaphore);
					}
					break;
				default:
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
					if (g_BlindTry == TRUE)
					{
						break;
					}
#endif
					if ((NULL != pstInfo->pfUpdate)
						&& (0 == pstInfo->pfUpdate(msg.enType, &(pstInfo->stSearchInfo)))
						&& (AL_CS_MSG_TYPE_LOCK_CH == msg.enType))
					{
						//printf("TV Num = %4d ", pstInfo->stSearchInfo.usTVCnt);
						//printf("Radio Num = %4d ", pstInfo->stSearchInfo.u.dtv.usRadioCnt);
						//printf("Data Num = %4d\n", pstInfo->stSearchInfo.u.dtv.usDataServCnt);
					}

					break;
			}
		}
		else if (pstInfo->pstQueue == NULL)
		{
			pstInfo->bContinue = FALSE;
		}
	}

	CS_SearchExit();

search_exit:
	if (pstInfo->pstQueue)
	{
		GL_QueueDelete(pstInfo->pstQueue);
		pstInfo->pstQueue = NULL;
	}
	if (NULL != pstInfo->pfUpdate)
	{
		pstInfo->pfUpdate(AL_CS_MSG_TYPE_FINISHED, &(pstInfo->stSearchInfo));
	}

	if (pstInfo->pstSemaphore)
	{
		// touch for app continue running
		GL_SemaphoreGive(pstInfo->pstSemaphore);
	}

	if (msg.enType == AL_CS_MSG_TYPE_FINISHED)
	{
		if (pstInfo->pstSemaphore)
		{
			GL_TaskSleep(1);
			GL_SemaphoreDelete(pstInfo->pstSemaphore);
			pstInfo->pstSemaphore = al_null;
		}
	}

	fEn = al_false;
	front.cmd = FRONTEND_CMD_SET_TUNER_SCAN_MODE;
	front.param = &fEn;
	ioctl(kmfdev, KMF_IOC_FRONTENDCTRL, &front);

	AL_FW_ActiveFWModule(FW_NORMAL_VIEW_MODE);
	if (NULL != pstInfo->pfOver)
    {
        pstInfo->pfOver();
	}

	pstInfo->enState = CS_STATE_IDLE;
	CS_DEBUG_MESSAGE("Exit %s\n",__FUNCTION__);
	GL_TaskSelfDelete();
}

/*****************************************************************************
** FUNCTION : AL_Return_t CS_SearchEnter(void* params)
**
** DESCRIPTION :
**				Search task initialize function
**
** PARAMETERS :
**				params - the input params
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t CS_SearchEnter(void* params)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
#ifdef CONFIG_DTV_SUPPORT
#ifdef NIT_SCAN_SUPPORT
	digital_search_data_st* pstDigital = al_null;
	pstDigital = &pstInfo->unScanData.digital;
#endif
#endif
#ifdef CONFIG_ATV_SUPPORT
	analog_search_data_st* pstAnalog = &(pstInfo->unScanData.analog);
#endif

	CS_DEBUG_MESSAGE("Enter %s\n",__FUNCTION__);

	if (AL_CS_TYPE_ANALOG == pstInfo->enType
		|| AL_CS_TYPE_ANALOG_MANUAL == pstInfo->enType)
	{
#ifdef CONFIG_SUPPORT_TTX
		AL_TTX_Stop();//before scan, stop tt function.
#endif
#ifdef CONFIG_CC_SUPPORT
        AL_CC_Stop();//before scan, stop cc funtion.
#endif
#ifdef CONFIG_ATV_SUPPORT
		Ana_ScanInputInfo_t stAtvInitParams;

		pstInfo->stSearchInfo.usTVCnt =	(pstAnalog->stInput.EndFreq - pstAnalog->stInput.StartFreq)	/ pstAnalog->stInput.BandWidth + 1;

        /* Set tuner Init parameters */
		//stAtvInitParams.dMinFreq = AnalogScanStartFreq;
		//stAtvInitParams.dMaxFreq = AnalogScanEndFreq;

        stAtvInitParams.dMinFreq = pstAnalog->stInput.StartFreq;
		stAtvInitParams.dMaxFreq = pstAnalog->stInput.EndFreq;
		stAtvInitParams.bBlueScreen = pstAnalog->stInput.ucBlueScreen;

		stAtvInitParams.eAudioStd_Supported = pstAnalog->stInput.Audio_std;
		stAtvInitParams.eVideoFormat_Supported = pstAnalog->stInput.Video_format;

        #if 1
        CS_DEBUG_MESSAGE("\n$$$ atv scan param:");
		//printf("Min freq:%d,", stAtvInitParams.dMinFreq);
		//printf("Max freq:%d,", stAtvInitParams.dMaxFreq);
		//printf("Cur freq:%d.\n", pstAnalog->stInput.CurrFreq);
        CS_DEBUG_MESSAGE("Video Support:  PAL=%d SECAM=%d SECAM-L=%d NTSC358=%d NTSC443=%d PALM=%d PALN=%d PAL60=%d \n", \
            (stAtvInitParams.eVideoFormat_Supported &ANA_SCAN_VIDEO_FORMAT_PAL)>>2, \
            (stAtvInitParams.eVideoFormat_Supported &ANA_SCAN_VIDEO_FORMAT_SECAM)>>6, \
            (stAtvInitParams.eVideoFormat_Supported &ANA_SCAN_VIDEO_FORMAT_SECAML)>>7, \
            (stAtvInitParams.eVideoFormat_Supported &ANA_SCAN_VIDEO_FORMAT_NTSC358)>>0, \
            (stAtvInitParams.eVideoFormat_Supported &ANA_SCAN_VIDEO_FORMAT_NTSC443)>>1, \
            (stAtvInitParams.eVideoFormat_Supported &ANA_SCAN_VIDEO_FORMAT_PALM)>>3, \
            (stAtvInitParams.eVideoFormat_Supported &ANA_SCAN_VIDEO_FORMAT_PALCN)>>4, \
            (stAtvInitParams.eVideoFormat_Supported &ANA_SCAN_VIDEO_FORMAT_PAL60)>>5 \
            );
        CS_DEBUG_MESSAGE("Audio Support:  BG=%d DK= %d I=%d M=%d L=%d L1=%d \n\n", \
            (stAtvInitParams.eAudioStd_Supported &ANA_SCAN_AUDIO_STD_BG)>>1, \
            (stAtvInitParams.eAudioStd_Supported &ANA_SCAN_AUDIO_STD_DK)>>2, \
            (stAtvInitParams.eAudioStd_Supported &ANA_SCAN_AUDIO_STD_I)>>3, \
            (stAtvInitParams.eAudioStd_Supported &ANA_SCAN_AUDIO_STD_M)>>0, \
            (stAtvInitParams.eAudioStd_Supported &ANA_SCAN_AUDIO_STD_L)>>4, \
            (stAtvInitParams.eAudioStd_Supported &ANA_SCAN_AUDIO_STD_L1)>>5 \
            );
        #endif

#if defined(CONFIG_SUPPORT_TTX) && defined (CONFIG_SUPPORT_ATS)
        unsigned char *AnalogTTXLang = al_null;
        frmwrk_pfOpConext_t pfApsGetContext = al_null;
        AL_FW_GetContextCb(&pfApsGetContext);
        al_uint8 TTLanguage = 0;
        if (pfApsGetContext != al_null)
        {
            pfApsGetContext(FW_CONTEXT_TYPE_TT_LANGUAGE , FW_CONTEXT_OP_TYPE_READ,
                (al_void *)&TTLanguage, 0);
            AnalogTTXLang = &TTLanguage;
        }
        AL_TTX_Start(AL_TTX_SOURCE_TYPE_ANALOG,AnalogTTXLang);

	    stAtvInitParams.ResetATS = MID_ATS_HookAPI;
	    stAtvInitParams.GetATSData = MID_ATS_GetData;
#else
	    stAtvInitParams.ResetATS = NULL;
	    stAtvInitParams.GetATSData = NULL;
#endif

	    if (pstInfo->enType == AL_CS_TYPE_ANALOG)
	    {
	    	AL_DBCapability_t stCapability;
            memset(&stCapability, 0, sizeof(AL_DBCapability_t));
	    	AL_DB_GetCapability(AL_DBTYPE_DVB_ATV, &stCapability);

			stAtvInitParams.bMaxChannelCount = stCapability.MaxService;
			stAtvInitParams.dCurrentFreq = pstAnalog->stInput.CurrFreq;
			stAtvInitParams.eScanningDirection = ANA_SCAN_DIRECTION_POSITIVE;
			stAtvInitParams.eScanMode = ANA_SCAN_MODE_AUTO;
	    }
	    else if (pstInfo->enType == AL_CS_TYPE_ANALOG_MANUAL)
	    {
			stAtvInitParams.bMaxChannelCount = 1;
			stAtvInitParams.eScanMode = ANA_SCAN_MODE_MANUAL;
			if (pstInfo->unScanData.analog.iDirection > 0)
			{
				stAtvInitParams.dCurrentFreq = pstAnalog->stInput.CurrFreq;
				stAtvInitParams.eScanningDirection = ANA_SCAN_DIRECTION_POSITIVE;
			}
			else
			{
				stAtvInitParams.dCurrentFreq = pstAnalog->stInput.CurrFreq;
				stAtvInitParams.eScanningDirection = ANA_SCAN_DIRECTION_NEGTIVE;
			}
	    }
		AL_CNIInit();
		if (AL_SUCCESS != MID_AnalogTVScanStart(&(stAtvInitParams), CS_AtvSearchCallback))
		{
			CS_ERROR_MESSAGE("[AL_Channel_Search] MID_AnalogScanStart failed!!!!!\n\n");

			return AL_FAILURE;
		}
		else
		{
			CS_DEBUG_MESSAGE("[AL_Channel_Search] MID_AnalogScanStart Successfully!!!!!\n\n");
		}

		CS_DEBUG_MESSAGE("Exit %s\n",__FUNCTION__);

		return AL_SUCCESS;
#endif
	}
	else if ((AL_CS_TYPE_DIGITAL == pstInfo->enType)
		|| (AL_CS_TYPE_DIGITAL_BLIND == pstInfo->enType)
#ifdef CONFIG_SUPPORT_FAST_SCANNING
		|| (AL_CS_TYPE_DIGITAL_M7_FAST == pstInfo->enType)
#endif
		|| (AL_CS_TYPE_DIGITAL_MANUAL == pstInfo->enType))
	{
#ifdef CONFIG_SUPPORT_TTX
		AL_TTX_Stop();//before scan, stop tt function.
#endif
#ifdef CONFIG_CC_SUPPORT
        AL_CC_Stop();//before scan, stop cc funtion.
#endif
#ifdef CONFIG_DTV_SUPPORT
#ifdef CONFIG_DVB_SYSTEM
		al_uint32 area_idx = pstInfo->unScanData.digital.ucAreaIdx;;
#endif
		al_uint32 uiDtvSearchCapabilities = 0;
        al_uint32 uiDtvSearchCapabilitiesExt = 0;

#ifdef CONFIG_SUPPORT_FAST_SCANNING
		if (pstInfo->uiCapabilities & AL_CS_SUPPORT_M7_FAST_SCAN)
		{
			uiDtvSearchCapabilitiesExt |= MID_SCAN_CAPS_EXT_SUPPORT_M7_FAST_SCAN;
			uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_LCN;
			uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NO_CHECK_PDSD;
			uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_14BIT_LCN;
		}
#endif

#if (defined(CONFIG_SUPPORT_MHEG5) || defined(CONFIG_CIPLUS_SUPPORT))
#ifdef CONFIG_DVB_SYSTEM
			if ((AREA_ENGLAND == area_idx) ||
				(AREA_IRELAND == area_idx))
			{
				/* support DTG */
				uiDtvSearchCapabilities |=
					MID_SCAN_CAPS_SUPPORT_NIT |
					//MID_SCAN_CAPS_SUPPORT_LCN |
					MID_SCAN_CAPS_SUPPORT_AC3 |
				#ifdef TEMPORARY_SERVICE
					MID_SCAN_CAPS_SUPPORT_TEMPORARY_SERVICE |
				#endif
					MID_SCAN_CAPS_SUPPORT_MHEG5 |
					MID_SCAN_CAPS_SUPPORT_DTG_CERTIFICATION|
					MID_SCAN_CAPS_MAIN_SYSTEM |
					MID_SCAN_CAPS_SUPPORT_ADD_SRV_IN_SDT_ONLY|
					MID_SCAN_CAPS_SUPPORT_MULTI_SERVICE_NAME;

#ifdef SUPPORT_LCN
				if (pstInfo->unScanData.digital.enTunerType != TUNER_QPSK) // not dvb-s
				{
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_LCN;
				}
#endif
			}
			else
#endif
#endif
			{
				/* do not support DTG */
		 		uiDtvSearchCapabilities |=
				#ifdef SUPPORT_LCN
					MID_SCAN_CAPS_SUPPORT_NIT |
					//MID_SCAN_CAPS_SUPPORT_LCN |
				#endif
					MID_SCAN_CAPS_SUPPORT_AC3 |
				//#ifdef SUPPORT_CONAX_CAS
					MID_SCAN_CAPS_SUPPORT_CA_SYSTEM |
				//#endif
				#ifdef TEMPORARY_SERVICE
					MID_SCAN_CAPS_SUPPORT_TEMPORARY_SERVICE |
				#endif
					MID_SCAN_CAPS_MAIN_SYSTEM |
				#if defined(CONFIG_DVB_SYSTEM) || defined(CONFIG_AUS_DVB_SYSTEM)
					MID_SCAN_CAPS_SUPPORT_ADD_SRV_IN_SDT_PAT_ONLY |
				#endif
				#ifdef CONFIG_ISDB_SYSTEM
					MID_SCAN_CAPS_SUPPORT_ADD_SRV_IN_SDT_ONLY |
				#endif
					MID_SCAN_CAPS_SUPPORT_MULTI_SERVICE_NAME;

				#ifdef CONFIG_DVB_SYSTEM
				if ((AREA_NORWAY == area_idx) ||(AREA_DENMARK == area_idx)
					|| (AREA_SWEDEN == area_idx) ||(AREA_FINLAND == area_idx))
				{
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NORDIG_CERTIFICATION;
				}
				#endif

#ifdef SUPPORT_LCN
				if (pstInfo->unScanData.digital.enTunerType != TUNER_QPSK) // not dvb-s
				{
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_LCN;
				}
#endif
			}
#if (defined(CONFIG_SUPPORT_MHEG5) || defined(CONFIG_CIPLUS_SUPPORT))
//#ifdef SUPPORT_MHEG5_ONLY_SPECIAL_AREA
#ifdef CONFIG_DVB_SYSTEM
			if((AREA_ENGLAND == area_idx)||(AREA_IRELAND == area_idx))
//#endif
			{
				uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_MHEG5 | MID_SCAN_CAPS_SUPPORT_DTG_CERTIFICATION;
			}
#endif			
#endif
			if (pstInfo->unScanData.digital.enTunerType != TUNER_QPSK) // not dvb-s
			{
				#ifdef CONFIG_DVB_SYSTEM
				if ((area_idx == AREA_FRANCE) ||
					(area_idx == AREA_POLAND) ||
					(area_idx == AREA_ITALY))
				{
					/*
					** france and poland use E-Book and Italy use Z-Book,
					** The PDSD which defined in those spec are the same value(0x00000028)
					*/
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_EBOOK_PDSD;
				}
				#endif
			#ifdef SUPPORT_LCN_VER2
				#ifdef CONFIG_DVB_SYSTEM
				if ((area_idx == AREA_SWEDEN)
					|| (area_idx == AREA_NORWAY)
					|| (area_idx == AREA_FINLAND)
					|| (area_idx == AREA_DENMARK)
					|| (area_idx == AREA_IRELAND))
				{
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_LCN_VER2;
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NORDIG_PDSD;
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_14BIT_LCN;
				}
				else if (area_idx == AREA_SINGAPORE)
				{
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_LCN_VER2;
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_14BIT_LCN;
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NO_CHECK_PDSD;
				}
				else if (area_idx == AREA_THAILAND)
				{
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_LCN_VER2;
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NO_CHECK_PDSD;
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_14BIT_LCN;
					uiDtvSearchCapabilitiesExt |= MID_SCAN_CAPSEX_SUPPORT_CHECK_LCNV2_PDSD;
				}
				#ifdef SUPPORT_GHANA_LCN
				else if( area_idx == AREA_GHANA )
				{
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_LCN_VER2;
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NO_CHECK_PDSD;
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_14BIT_LCN;
				}
				#endif
				#ifdef CONFIG_SUPPORT_MALAYSIA_CERTIFICATION
                else if( area_idx ==  AREA_MALAYSIA)
                {
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_LCN_VER2;
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NO_CHECK_PDSD;
					#ifdef SUPPORT_LCN
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_14BIT_LCN;
					#endif
                }
                #endif
                else if( area_idx == AREA_INDONESIA )
                {
                    uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_LCN_VER2;
                    uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NO_CHECK_PDSD;
                    uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_14BIT_LCN;
                }
				#endif
			#endif

			#ifdef SUPPORT_HD_SIMULCAST_LCN
				uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_HD_SIMUALCAST_LCN;
			#endif
		}

		if (pstInfo->unScanData.digital.enTunerType == TUNER_OFDM || pstInfo->unScanData.digital.enTunerType == TUNER_TDS_OFDM)
		{
			uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_DVB_T;
			if (pstInfo->uiCapabilities & MID_SCAN_CAPS_SUPPORT_DVB_T2_IMMEDIATE)
			{
				uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_DVB_T2_IMMEDIATE;
			}
			else if (pstInfo->uiCapabilities & MID_SCAN_CAPS_SUPPORT_DVB_T2_LATER)
			{
				uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_DVB_T2_LATER;
			}
		}
		else if (pstInfo->unScanData.digital.enTunerType == TUNER_QAM)
		{
			uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_DVB_C;
			uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NIT;
			#ifdef CONFIG_DVB_SYSTEM
			if (area_idx == AREA_GERMANY)
			{
				uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_LCN_VER2;
				uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NORDIG_PDSD;
			#ifdef CONFIG_SUPPORT_KDG_CERTIFICATION
				al_DVBC_Operator_en op = (pfQueryOperatorFunc != al_null) ? pfQueryOperatorFunc() : AL_DVBC_OPERATOR_AUTO;
				if (op == AL_DVBC_OPERATOR_KDG)
				{
					uiDtvSearchCapabilitiesExt |= MID_SCAN_CAPS_EXT_SUPPORT_KDG_LCN;
					uiDtvSearchCapabilities &= ~(MID_SCAN_CAPS_SUPPORT_LCN | MID_SCAN_CAPS_SUPPORT_LCN_VER2);
				}
			#endif
			}
#ifdef NIT_SCAN_SUPPORT
			if (pstDigital->Cable.pstNetworkScanInfo.uiDVBCSearchMode == AL_DVBC_SEARCHMODE_QUICK_NETWORK)
			{
				al_DVBC_Operator_en op = (pfQueryOperatorFunc != al_null) ? pfQueryOperatorFunc() : AL_DVBC_OPERATOR_AUTO;
				if (op == AL_DVBC_OPERATOR_ZIGGO || op == AL_DVBC_OPERATOR_COMHEM || op == AL_DVBC_OPERATOR_YOU_SEE)
				{
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NIT_SCAN;
				}
			}
#endif
			#endif
		}
		else if(pstInfo->unScanData.digital.enTunerType == TUNER_BST_OFDM)
		{
			uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_DVB_SBTVD;
			uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NIT;
			#ifdef SUPPORT_ONESEG_PROGRAM
			uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_ONE_SEG;
			#endif
		}
		/* DVB-S */
		else if (pstInfo->unScanData.digital.enTunerType == TUNER_QPSK)
		{
			uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_DVB_S;
			if (pstInfo->uiCapabilities & AL_CS_SUPPORT_GET_FREQ_FROM_NIT)
			{
				uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NIT;
			}
			else
			{
				uiDtvSearchCapabilities &= ~MID_SCAN_CAPS_SUPPORT_NIT;
			}
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
			if (pstInfo->enType == AL_CS_TYPE_DIGITAL_BLIND)
			{
				if (pstInfo->uiCapabilities&AL_CS_SUPPORT_BLIND_SCAN_METHOD_1)
				{
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_BLIND_SCAN_METHOD_1;
				}
				else if (pstInfo->uiCapabilities&AL_CS_SUPPORT_BLIND_SCAN_METHOD_2)
				{
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_BLIND_SCAN_METHOD_2;
				}
                else if (pstInfo->uiCapabilities&AL_CS_SUPPORT_BLIND_SCAN_METHOD_3)
				{
					uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_BLIND_SCAN_METHOD_3;
				}
			}
			else
			{
				uiDtvSearchCapabilities &= ~(MID_SCAN_CAPS_SUPPORT_BLIND_SCAN_METHOD_1|
											 MID_SCAN_CAPS_SUPPORT_BLIND_SCAN_METHOD_2|
											 MID_SCAN_CAPS_SUPPORT_BLIND_SCAN_METHOD_3);
			}

			#ifdef SUPPORT_DVBS_LCN
			uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NIT;
			#endif
			#ifdef SUPPORT_ASTRA_LCN
			uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NIT;
			uiDtvSearchCapabilitiesExt |= MID_SCAN_CAPS_EXT_SUPPORT_ASTRA_LCN;
			pMultiLCNInfoHead = NULL;
			#endif
#endif
		}
		else
		{
		}

        //zhongbaoxing added for some customer's spec: no need to check PDSD @20150510 +++
		if(pstInfo->uiCapabilities&MID_SCAN_CAPS_SUPPORT_NO_CHECK_PDSD)
		{
			uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NO_CHECK_PDSD;
		}
		//zhongbaoxing added for some customer's spec: no need to check PDSD @20150510 ---

        /* for DVB-C, dynamic check the PDSD to decide the special spec(D-Book? E-Book? Z-Book? Nordig?) */
		if (pstInfo->unScanData.digital.enTunerType == TUNER_QAM)
		{
			uiDtvSearchCapabilities &= ~(MID_SCAN_CAPS_SUPPORT_EBOOK_PDSD
				| MID_SCAN_CAPS_SUPPORT_NORDIG_PDSD
				| MID_SCAN_CAPS_SUPPORT_DTG_CERTIFICATION);

			al_DVBC_Operator_en op = (pfQueryOperatorFunc != al_null) ? pfQueryOperatorFunc() : AL_DVBC_OPERATOR_AUTO;
			if (op == AL_DVBC_OPERATOR_UNITY_MEDIA || op == AL_DVBC_OPERATOR_KBW)
			{
				uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NORDIG_PDSD;
				eSpecialSpec = DVB_SPECIAL_SPEC_NORDIG;
			}
			else if (op == AL_DVBC_OPERATOR_YOU_SEE)
			{
				uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_NORDIG_PDSD;
				uiDtvSearchCapabilitiesExt |= MID_SCAN_CAPS_EXT_SCAN_ONLY_NIT_OTHER;
				eSpecialSpec = DVB_SPECIAL_SPEC_NORDIG;
			}
			else
			{
				uiDtvSearchCapabilities |= MID_SCAN_CAPS_SUPPORT_DYNAMIC_PDSD;
				eSpecialSpec = DVB_SPECIAL_SPEC_NONE;
			}
		}
#ifdef CONFIG_DTMB_SYSTEM
		uiDtvSearchCapabilitiesExt |= MID_SCAN_CAPS_EXT_SUPPORT_DRA_AUDIO;
#endif
#ifdef CONFIG_DTV_SUPPORT
		if (MID_SUCCESS != MID_ScanStart(uiDtvSearchCapabilities, uiDtvSearchCapabilitiesExt, CS_DtvSearchCallback))
		{
			CS_ERROR_MESSAGE("[AL_Channel_Search] MID_DigitalScanStart failed!!!!!\n\n");

			return AL_FAILURE;
		}
		else
		{
			CS_DEBUG_MESSAGE("[AL_Channel_Search] MID_DigitalScanStart Successfully!!!!!\n\n");
		}

#endif

		//DMIOC_DTV_PARAM stSWParam;
		//memset(&stSWParam, 0, sizeof(DMIOC_DTV_PARAM));
		//stSWParam.DemuxUnit = MID_CmnGetDemuxUnit();
		//ioctl(dtvdev, DTV_IOCTL_INIT, &stSWParam);

		CS_DEBUG_MESSAGE("Exit %s\n",__FUNCTION__);

		return AL_SUCCESS;
#endif
	}
	else if (AL_CS_TYPE_ACI == pstInfo->enType)
	{
		return CS_ACIInit();
	}
	else if (AL_CS_TYPE_ANALOG_TABLE == pstInfo->enType)
	{
#ifdef CONFIG_ATV_SUPPORT
		Mid_TableScan_ScanInputInfo_t stAtvInitParams;
        	memset(&stAtvInitParams, 0, sizeof(Mid_TableScan_ScanInputInfo_t));

		pstInfo->stSearchInfo.usTVCnt =	pstAnalog->stInput.TblLen;

		/* Set tuner Init parameters */
		//stAtvInitParams.dMinFreq = AnalogScanStartFreq;
		//stAtvInitParams.dMaxFreq = AnalogScanEndFreq;
		//stAtvInitParams.eAudioStd_Supported = MID_TABLE_SCAN_AUDIO_STD_M;
		//stAtvInitParams.eVideoFormat_Supported = MID_TABLE_SCAN_VIDEO_FORMAT_NTSC358;
		//stAtvInitParams.bDetectVideoFormat = TRUE;
		//stAtvInitParams.eAudioStd_Supported = pstAnalog->stInput.Audio_std;
		if ((pstAnalog->stInput.Video_format & AL_ANALOG_SCAN_VIDEO_FORMAT_NTSC358))
		{
			stAtvInitParams.eVideoFormat_Supported |= MID_TABLE_SCAN_VIDEO_FORMAT_NTSC358;
		}

        if ((pstAnalog->stInput.Video_format & AL_ANALOG_SCAN_VIDEO_FORMAT_PALM))
		{
			stAtvInitParams.eVideoFormat_Supported |= MID_TABLE_SCAN_VIDEO_FORMAT_PALM;
		}

        if ((pstAnalog->stInput.Video_format & AL_ANALOG_SCAN_VIDEO_FORMAT_PALCN))
		{
			stAtvInitParams.eVideoFormat_Supported |= MID_TABLE_SCAN_VIDEO_FORMAT_PALCN;
		}

        if (pstAnalog->stInput.Video_format == AL_ANALOG_SCAN_VIDEO_FORMAT_AUTO)
		{
			stAtvInitParams.eVideoFormat_Supported |= MID_TABLE_SCAN_VIDEO_FORMAT_AUTO;
		}

		AL_CNIInit();

		if (AL_SUCCESS != MID_TableScanStart(&(stAtvInitParams), CS_AtvSearchCallback))
		{
			CS_ERROR_MESSAGE("[AL_Channel_Search] MID_TableScanStart failed!!!!!\n\n");

			return AL_FAILURE;
		}
		else
		{
			CS_DEBUG_MESSAGE("[AL_Channel_Search] MID_TableScanStart Successfully!!!!!\n\n");
		}

		CS_DEBUG_MESSAGE("Exit %s\n",__FUNCTION__);

		return AL_SUCCESS;
#endif
	}

	return AL_FAILURE;
}

/*****************************************************************************
** FUNCTION : static void CS_SearchExit(void)
**
** DESCRIPTION :
**				Search task uninitialize function
**
** PARAMETERS :
**				void
** RETURN VALUES:
**				void
*****************************************************************************/
static void CS_SearchExit(void)
{
	cs_info_st* pstInfo =  GET_CS_INFO();

	CS_DEBUG_MESSAGE("Enter %s\n",__FUNCTION__);

	if (AL_CS_TYPE_ANALOG == pstInfo->enType
		|| AL_CS_TYPE_ANALOG_MANUAL  == pstInfo->enType)
	{
#ifdef CONFIG_ATV_SUPPORT
		MID_AnalogTVScanStop();
#ifdef CONFIG_SUPPORT_TTX
        AL_TTX_Stop();
#endif
#endif
	}
	else if ((AL_CS_TYPE_DIGITAL == pstInfo->enType)
		|| (AL_CS_TYPE_DIGITAL_BLIND == pstInfo->enType)
		|| (AL_CS_TYPE_DIGITAL_MANUAL == pstInfo->enType))
	{
#ifdef CONFIG_DTV_SUPPORT
		if (specialSpecIsModify && (TUNER_QAM == pstInfo->unScanData.digital.enTunerType))
		{
			AL_PSI_Monitor_SetupConf(eSpecialSpec, 0, al_null, al_null);
			CS_DEBUG_MESSAGE("For DVB-C, dynamic adapt the special sepc!______________%d\n", eSpecialSpec);
#ifdef CONFIG_DVB_SYSTEM

			EDBLCNRule_t LcnRule;

			if (gePriSpec == AL_DB_DVB_PRISPEC_DBOOK)
			{
				LcnRule = DB_DVB_LCNRULE_GBR;
			}
			else if (gePriSpec == AL_DB_DVB_PRISPEC_ZBOOK)
			{
				LcnRule = DB_DVB_LCNRULE_ITA;
			}
			else if (gePriSpec == AL_DB_DVB_PRISPEC_NORDIG)
			{
				LcnRule = DB_DVB_LCNRULE_NORDIG;
			}
			else if (gePriSpec == AL_DB_DVB_PRISPEC_EBOOK)
			{
				LcnRule = DB_DVB_LCNRULE_PANEURO;
			}
			else
			{
				LcnRule = DB_DVB_LCNRULE_PANEURO;
			}

			LCN_SetLCNRule(LcnRule);

			specialSpecIsModify = FALSE;
#endif
		}

	#ifdef SUPPORT_NIM_RXDMA
		MID_RxdmaStop();
	#endif

		MID_ScanStop();

		if (pstInfo->ucDmxIsOpen)
		{
			DMIOC_DTV_PARAM stSWParam;
			memset(&stSWParam, 0, sizeof(DMIOC_DTV_PARAM));
			stSWParam.DemuxUnit = MID_CmnGetDemuxUnit();
			ioctl(dtvdev, DTV_IOCTL_EXIT, &stSWParam);
			pstInfo->ucDmxIsOpen = 0;
		}

		if (TUNER_QAM == pstInfo->unScanData.digital.enTunerType)
		{
			AI_TpListFree(pstInfo->unScanData.digital.Cable.stDefaultTpTbl);
			AI_TpListFree(pstInfo->unScanData.digital.Cable.stNITTpTbl);
			pstInfo->unScanData.digital.Cable.stTpListHdl = TP_LIST_INVALID_HDL;
		}
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
		if (TUNER_QPSK == pstInfo->unScanData.digital.enTunerType)
		{
			AI_TpListFree(pstInfo->unScanData.digital.Satellite.stDefaultTpTbl);
			AI_TpListFree(pstInfo->unScanData.digital.Satellite.stNITTpTbl);
			AI_TpListFree(pstInfo->unScanData.digital.Satellite.stBSTpTbl);
			AI_TpListFree(g_pSateLostTpInfo);
			g_pSateLostTpInfo = TP_LIST_INVALID_HDL;
			g_BlindTry = FALSE;
			pstInfo->unScanData.digital.Satellite.stDefaultTpTbl = TP_LIST_INVALID_HDL;
			pstInfo->unScanData.digital.Satellite.stNITTpTbl = TP_LIST_INVALID_HDL;
			pstInfo->unScanData.digital.Satellite.stBSTpTbl = TP_LIST_INVALID_HDL;
			pstInfo->unScanData.digital.Satellite.stTpListHdl = TP_LIST_INVALID_HDL;
		}
#endif
		if (TUNER_OFDM == pstInfo->unScanData.digital.enTunerType || TUNER_TDS_OFDM == pstInfo->unScanData.digital.enTunerType)
		{
            #ifdef CONFIG_DVB_SYSTEM_DVBT2_SUPPORT
			digital_search_data_st* pstDigital = &(pstInfo->unScanData.digital);
			if (pstDigital->Terr.pstT2List != NULL)
			{
				_AI_CS_FreeAllNode(pstDigital->Terr.pstT2List);

				pstDigital->Terr.pstT2List = NULL;
				pstDigital->Terr.TotalT2count = 0;
				pstDigital->Terr.CurT2Inx = 0;
				pstDigital->Terr.ScanMode = AL_SCAN_DVB_T_T2_DEFAULT_MODE;
			}
            #endif

			if (pstInfo->uiCapabilities & AL_CS_SUPPORT_NIT_FREQ_LIST_SCAN)
			{
				AI_TpListFree(pstInfo->unScanData.digital.Terr.stFreqListHdl);
			}
		}
#endif
	}
	else if (AL_CS_TYPE_ACI == pstInfo->enType)
	{
	}
	else if (AL_CS_TYPE_ANALOG_TABLE == pstInfo->enType)
	{
#ifdef CONFIG_ATV_SUPPORT
		MID_TableScanStop();
#endif
	}

	CS_DEBUG_MESSAGE("Exit %s\n",__FUNCTION__);
}

#ifdef CONFIG_ATV_SUPPORT
/*****************************************************************************
** FUNCTION : static AL_Return_t CS_AtvNextChannel(void* pdata, cs_msg_st* msg)
**
** DESCRIPTION :
**				Get information of next channel need to search
**
** PARAMETERS :
**				pdata - next channel information
**				msg - message type
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t CS_AtvNextChannel(void* pdata, cs_msg_st* msg)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
	analog_search_data_st* pstAtvScanParams = NULL;

	if (NULL == pdata)
	{
		return AL_FAILURE;
	}

    pstAtvScanParams = &(pstInfo->unScanData.analog);

    if (pstInfo->enType == AL_CS_TYPE_ANALOG_TABLE)
    {
        if (pstAtvScanParams->stInput.CurTblIdx >= pstAtvScanParams->stInput.TblLen)
        {
            CS_SEND_MSG(AL_CS_MSG_TYPE_FINISHED,0);
    		return AL_FAILURE;
        }
    	if(pstAtvScanParams->stInput.Manual_Num == FALSE)
    	{
          	pstInfo->stSearchInfo.uiCurFreq = pstAtvScanParams->stInput.pTbl[pstAtvScanParams->stInput.CurTblIdx];
    	 	pstInfo->stSearchInfo.u.atv.usCurChaInx = pstAtvScanParams->stInput.CurTblIdx;
    		pstAtvScanParams->stInput.CurTblIdx ++;

    	}
    	else
    	{
    		if(pstAtvScanParams->stInput.CurTblIdx>0)
    		{
    		    CS_SEND_MSG(AL_CS_MSG_TYPE_FINISHED,0);
                return AL_FAILURE;
            }
    		pstAtvScanParams->stInput.CurTblIdx++;
    		pstInfo->stSearchInfo.uiCurFreq = pstAtvScanParams->stInput.pTbl[pstAtvScanParams->stInput.Manual_Num];
    		pstInfo->stSearchInfo.u.atv.usCurChaInx = pstAtvScanParams->stInput.Manual_Num;
    	}
    	pstInfo->stSearchInfo.uiCurBandwidth = 6;//pstAtvScanParams->stInput.BandWidth;

        ((Mid_TableScan_Param_t *)pdata)->dFreq = pstInfo->stSearchInfo.uiCurFreq;
        //((Mid_TableScan_Param_t *)pdata)->eStd = MID_TABLE_SCAN_AUDIO_STD_M;
    }
    else
    {
    	/* joseph note:if frequency exceed the MAX frequency*/
    	if (pstAtvScanParams->stInput.EndFreq <
    		pstAtvScanParams->stInput.CurrFreq)
    	{
    		CS_SEND_MSG(AL_CS_MSG_TYPE_FINISHED,0);
    		return AL_FAILURE;
    	}

    	pstAtvScanParams->stInput.CurrFreq = MID_AnalogTVScanGetCurrentFreq();

    	pstInfo->stSearchInfo.uiCurFreq = pstAtvScanParams->stInput.CurrFreq;
    	pstInfo->stSearchInfo.uiCurBandwidth = pstAtvScanParams->stInput.BandWidth;
    	/* joseph note: put internal parmater into middleware variable */
    	((MID_ATVScanParam_t *) pdata)->dFreq = pstAtvScanParams->stInput.CurrFreq;
        /*add by xm.zeng for mantis0033044.*/
        if(pstAtvScanParams->stInput.CurrFreq < pstAtvScanParams->stInput.StartFreq)
        {
           pstAtvScanParams->stInput.CurrFreq = pstAtvScanParams->stInput.StartFreq;
        }
    	pstInfo->stSearchInfo.u.atv.usCurChaInx = (pstAtvScanParams->stInput.CurrFreq -
    			pstAtvScanParams->stInput.StartFreq) / pstAtvScanParams->stInput.BandWidth;
    }

	CS_SEND_MSG(AL_CS_MSG_TYPE_NEW_CH, 0);

	return AL_SUCCESS;
}

/*****************************************************************************
** FUNCTION : static AL_Return_t CS_AtvSaveChannel(void* pdata, cs_msg_st* msg)
**
** DESCRIPTION :
**				Save the current channel information to database
**
** PARAMETERS :
**				pdata - the information will be saved
**				msg - message type
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t CS_AtvSaveChannel(void* pdata, cs_msg_st* msg)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
	al_int32 ret = AL_SUCCESS;

	if (NULL == pdata)
	{
		return AL_FAILURE;
	}

	if (NULL != pstInfo->pfSave)
	{
		if (AL_SUCCESS != (ret = pstInfo->pfSave(NULL, NULL, pdata)))
		{
			return ret;
		}
	}

	if (pstInfo->enType != AL_CS_TYPE_ANALOG_TABLE)
	{
		pstInfo->stSearchInfo.uiCurFreq = ((Ana_ScanOutputInfo_t *)pdata)->dCurrentFreq;

	}
	else
	{
		pstInfo->stSearchInfo.uiCurFreq = ((Mid_TableScan_ScanOutputInfo_t *)pdata)->dCurrentFreq;

	}
	pstInfo->stSearchInfo.u.atv.usCurChaCnt ++;

	CS_SEND_MSG(AL_CS_MSG_TYPE_LOCK_CH, 0);

	return AL_SUCCESS;
}

/*****************************************************************************
** FUNCTION : static AL_Return_t CS_AtvSearchCallback(al_uint32 eCallbackType, void* pParam)
**
** DESCRIPTION :
**				ATV callback function registered into middleware
**
** PARAMETERS :
**				pstAtvResult - the search information
**				uiChannelNumber - current channel index
** RETURN VALUES:
**				void
*****************************************************************************/
static AL_Return_t  CS_AtvSearchCallback(al_uint32  eCallbackType, void* pParam)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
	cs_msg_st msg;
	al_int32 ret = AL_SUCCESS;

	CS_DEBUG_MESSAGE("Enter %s\n",__FUNCTION__);

	memset(&msg, 0 , sizeof(msg));

	switch (eCallbackType)
	{
		case MID_SCAN_CALLBK_TYPE_REQUEST_NEXT_CH:
			CS_DEBUG_MESSAGE("MID_SCAN_CALLBK_TYPE_REQUEST_NEXT_CH\n");
			CS_AtvNextChannel(pParam, &msg);
			break;
		case MID_SCAN_CALLBK_TYPE_LOCKED_CH:
			CS_DEBUG_MESSAGE("MID_SCAN_CALLBK_TYPE_LOCKED_CH\n");
			ret = CS_AtvSaveChannel(pParam, &msg);
			break;
		case MID_SCAN_CALLBK_TYPE_EXCEED_TRUNER:
			CS_DEBUG_MESSAGE("MID_SCAN_CALLBK_TYPE_EXCEED_TRUNER\n");
			msg.enType = AL_CS_MSG_TYPE_FINISHED;
			ret = AL_FAILURE;
			break;
		default:
			CS_DEBUG_MESSAGE("Error: scan callback type unknown!!!\n");
			break;
	}

	if (pstInfo->pstQueue
		&& (msg.enType != AL_CS_MSG_TYPE_NONE))
	{
		GL_QueueSend(pstInfo->pstQueue, (void *)&msg, sizeof(cs_msg_st));
	}

	CS_DEBUG_MESSAGE("Exit %s\n",__FUNCTION__);

	return ret;
}
#endif

#ifdef CONFIG_DTV_SUPPORT
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
al_int32 AL_CS_DTV_GetStartEndFreq(AL_RecHandle_t hNet, al_uint16 usLNBFreq, al_uint32 *puiStartFreq, al_uint32 *puiEndFreq)
{
	AL_NetworkDetail_t stNetInfo;
    al_uint16 usLNBFreqL;
    al_uint16 usLNBFreqH;

	AL_DB_QueryDetail(hNet, &stNetInfo);
	usLNBFreqL = stNetInfo.stDVBSNetwork.uiLNBFreq >> 16;
	usLNBFreqH = stNetInfo.stDVBSNetwork.uiLNBFreq & 0x0000FFFF;

#if 0
	if (usLNBFreq == 5150)
	{
		if (usLNBFreqL == usLNBFreqH)
		{
	        *puiStartFreq = 950;
	        *puiEndFreq   = 1750;
		}
		else
		{
	        *puiStartFreq = 950;
	        *puiEndFreq   = 1550;
		}
	}
	else if (usLNBFreq == 5750)
	{
		if (usLNBFreqL == usLNBFreqH)
		{
	        *puiStartFreq = 1550;
	        *puiEndFreq   = 2150;
		}
		else
		{
	        *puiStartFreq = 1550;
	        *puiEndFreq   = 2150;
		}
	}
	else if (usLNBFreq == 9750)
	{
		if (usLNBFreqL == usLNBFreqH)
		{
	        *puiStartFreq = 950;
	        *puiEndFreq   = 2150;
		}
		else
		{
	        *puiStartFreq = 950;
	        *puiEndFreq   = 2000;
		}
	}
	else if (usLNBFreq == 10250)
	{
		if (usLNBFreqL == usLNBFreqH)
		{
	        *puiStartFreq = 950;
	        *puiEndFreq   = 2150;
		}
		else
		{
	        *puiStartFreq = 950;
	        *puiEndFreq   = 2150;
	    }
	}
	else if (usLNBFreq == 10600)
	{
		if (usLNBFreqL == usLNBFreqH)
		{
	        *puiStartFreq = 950;
	        *puiEndFreq   = 2150;
	    }
		else
		{
	        *puiStartFreq = 1100;
	        *puiEndFreq   = 2150;
	    }
	}
	else if (usLNBFreq == 10750)
	{
		if (usLNBFreqL == usLNBFreqH)
		{
	        *puiStartFreq = 950;
	        *puiEndFreq   = 2000;
		}
		else
		{
	        *puiStartFreq = 950;
	        *puiEndFreq   = 2000;
		}
	}
	else if (usLNBFreq == 11250)
	{
		if (usLNBFreqL == usLNBFreqH)
		{
	        *puiStartFreq = 950;
	        *puiEndFreq   = 1500;
		}
		else
		{
	        *puiStartFreq = 950;
	        *puiEndFreq   = 2150;
	    }
	}
	else if (usLNBFreq == 11300)
	{
		if (usLNBFreqL == usLNBFreqH)
		{
	        *puiStartFreq = 950;
	        *puiEndFreq   = 1450;
		}
		else
		{
	        *puiStartFreq = 950;
	        *puiEndFreq   = 2150;
	    }
	}
    else
    {
        *puiStartFreq = 950;
        *puiEndFreq   = 2150;
    }
#else

//IF calculation add by hou.xin+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    if (usLNBFreq < LNB_C_Ku_DEVIDING_LINE)//C Band LNB
    {
        if (usLNBFreq < 4350)//950+3400=4350 this is min LNB freq value
        {
            *puiStartFreq = 950;
            *puiEndFreq   = 950;
            CS_DVBS_DEBUG_MESSAGE("\n\n[%s]###LNB freq error:%d###\n", __FUNCTION__, usLNBFreq);
            return 0;
        }

        //C band freq max range: 3400~4200
        if (usLNBFreqL != usLNBFreqH)//dual LNB
    	{
            if (usLNBFreq == usLNBFreqH)//V
            {
                *puiStartFreq = usLNBFreqH - 4200;
                *puiEndFreq   = usLNBFreqH - 3400;
            }
            else //H
            {
                *puiStartFreq = usLNBFreq - 4200;
                if (usLNBFreqH - 4200 < usLNBFreqL - 3400)//overlapping
                {
                    //if there is overlapping,we think the IF of High LNB is effective!
                    *puiEndFreq   = usLNBFreqH - 4200;
                }
                else
                {
                    *puiEndFreq   = usLNBFreq - 3400;
                }
            }
    	}
    	else//signal LNB
    	{
            *puiStartFreq = usLNBFreq - 4200;//C band freq max range: 3400~4200
            *puiEndFreq   = usLNBFreq - 3400;
        }

        if (*puiStartFreq < 950)
        {
            *puiStartFreq = 950;
        }

        if (*puiEndFreq > 2150)
        {
            *puiEndFreq = 2150;
        }
    }
    else//Ku Band LNB
    {
        //10700-2150=8550 this is min LNB freq value
        //12800-950=11850 max LNB value
        if (usLNBFreq < 8550 || usLNBFreq > 11850)
        {
            *puiStartFreq = 950;
            *puiEndFreq   = 950;
            CS_DVBS_DEBUG_MESSAGE("\n\n[%s]###LNB freq error:%d###\n", __FUNCTION__, usLNBFreq);
            return 0;
        }

        if (usLNBFreqL != usLNBFreqH)
    	{
    	    al_uint16 usFreqMid = 0;
    		usFreqMid = (usLNBFreqL + 2150 + (usLNBFreqH + 950)) / 2;
            if (usFreqMid < usLNBFreq)
            {
                usFreqMid = 950 + usLNBFreq;
            }

    		if (usLNBFreqL == usLNBFreq)
    		{
    	        *puiStartFreq = 950;
    	        *puiEndFreq   = usFreqMid - usLNBFreq;
    		}
    		else
    		{
    	        *puiStartFreq = usFreqMid - usLNBFreq;
    	        *puiEndFreq   = 2150;
    		}
    	}
    	else
    	{
            *puiStartFreq = 950;
            *puiEndFreq   = 2150;
        }

        //Ku Band freq range: 10700~12750
        if (*puiStartFreq + usLNBFreq < 10700)
        {
            *puiStartFreq = 10700 - usLNBFreq;
        }

        if (*puiEndFreq + usLNBFreq > 12800)
        {
            *puiEndFreq = 12800 - usLNBFreq;
        }

        if (*puiStartFreq < 950)
        {
            *puiStartFreq = 950;
        }

        if (*puiEndFreq > 2150)
        {
            *puiEndFreq = 2150;
        }
    }

    CS_DVBS_DEBUG_MESSAGE("###start:%d end:%d###\n", *puiStartFreq, *puiEndFreq);
//IF calculation add by hou.xin---------------------------------------------------------
#endif

    return 0;
}

static al_uint32 CS_DTV_GetTpFrequency(al_uint16 usLNBFreq, al_uint32 dIfFreq)
{
	al_uint32 dRealFreq;

    if (usLNBFreq > LNB_C_Ku_DEVIDING_LINE)
    {
        dRealFreq = (usLNBFreq << 16) | (usLNBFreq + dIfFreq);
    }
    else
    {
		if (g_isCBandDualLNB)
		{
			if (dIfFreq < LNB3_5150_HIGH_IF_FREQ)
			{
				dRealFreq = (LNB3_5150 << 16) | (LNB3_5150 - dIfFreq);
			}
			else
			{
				dRealFreq = (LNB3_5750 << 16) | (LNB3_5750 - dIfFreq);
			}
		}
		else
		{
			dRealFreq = (usLNBFreq << 16) | (usLNBFreq - dIfFreq);
		}
    }

    return dRealFreq;
}

al_uint32 AL_CS_GetCurSymbolRate(void)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
	digital_search_data_st* pstDigital = &(pstInfo->unScanData.digital);
	al_uint32 symbol_rate = 0;

	if (pstDigital)
	{
		switch (pstDigital->enTunerType)
		{
			case TUNER_QPSK:
				if (pstDigital->Satellite.pstCurSateTp)
				{
					symbol_rate = pstDigital->Satellite.pstCurSateTp->uiSymRate;
				}
				break;
			case TUNER_QAM:
				if (pstDigital->Cable.pstCurCableTp)
				{
					symbol_rate = pstDigital->Cable.pstCurCableTp->uiSymRate;
				}
				break;
			default:
				break;
		}
	}

	return symbol_rate;
}

al_uint32 AL_CS_DVBSX_InitScanFEType(al_uint32 fe_type)
{
    g_DVBSX_CurrentFeType = fe_type;

    if (fe_type == AL_CS_DVBSX_S_TO_S2 || fe_type == AL_CS_DVBSX_ONLY_S)
    {
        g_DVBSX_NextScanMode = FRONTEND_TYPE_QPSK;
    }
    else if (fe_type == AL_CS_DVBSX_S2_TO_S || fe_type == AL_CS_DVBSX_ONLY_S2)
    {
        g_DVBSX_NextScanMode = FRONTEND_TYPE_DVBS2;
    }
    else
    {
        g_DVBSX_NextScanMode = 0;
        CS_DVBS_DEBUG_MESSAGE("[ERROR]please configure scan mode!!!\n\n");
    }

    g_DVBSX_DelTp = FALSE;//reset delete flag
    g_NeedScanNitList = al_false;
	g_pstCurSateTp = NULL;

    return g_DVBSX_NextScanMode;
}

static AL_Return_t CS_DTV_SwitchScanFEType(void)
{
    AL_Return_t Ret = AL_FAILURE;

    if (g_DVBSX_CurrentFeType == AL_CS_DVBSX_S_TO_S2)
    {
        if (g_DVBSX_NextScanMode == FRONTEND_TYPE_QPSK)//pre scan mode
        {
            g_DVBSX_NextScanMode = FRONTEND_TYPE_DVBS2;//next scan mode
            Ret = AL_SUCCESS;
        }
        else//current scan mode is already dvb-s2 mode
        {
            Ret = AL_FAILURE;
        }
    }
    else if (g_DVBSX_CurrentFeType == AL_CS_DVBSX_S2_TO_S)
    {
        if (g_DVBSX_NextScanMode == FRONTEND_TYPE_DVBS2)//pre scan mode
        {
            g_DVBSX_NextScanMode = FRONTEND_TYPE_QPSK;//next scan mode
            Ret = AL_SUCCESS;
        }
        else//current scan mode is already dvb-s2 mode
        {
            Ret = AL_FAILURE;
        }
    }
    else//only scan s or s2
    {
        Ret = AL_FAILURE;
    }

    return Ret;
}

/*****************************************************************************
** FUNCTION : static AL_Return_t CS_DtvGetNextBlindInfo(void* pdata, cs_msg_st* msg)
**
** DESCRIPTION :
**				Get information of next net need to search
**
** PARAMETERS :
**				pdata - next net information
**				msg - message type
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t CS_DtvGetNextBlindInfo(void* pdata, cs_msg_st* msg)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
	digital_search_data_st* pstDigital = &(pstInfo->unScanData.digital);
	MID_ScanParam_t *pParam = ((MID_ScanParam_t *) pdata);
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
	AL_NetworkDetail_t stNetInfo;
	Ant_TRANSPONDER_st CurTp;
	Ant_UsalsSetting_SatLocation_st SatLocal;
	al_uint32 uiTuningStep = 10;
	al_uint32 uiTuningBand = 64;
    al_uint32 uiFreqStart;
    al_uint32 uiFreqEnd;
    al_uint16 usLNBFreqL;
    al_uint16 usLNBFreqH;
    al_uint8 ucNextBand = TRUE;
    al_uint8 bConnectFE = TRUE;
#endif
	al_uint32 uiFrequence = 0;
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
     memset(&stNetInfo, 0, sizeof(AL_NetworkDetail_t));
     memset(&CurTp, 0, sizeof(Ant_TRANSPONDER_st));
     memset(&SatLocal, 0, sizeof(Ant_UsalsSetting_SatLocation_st));
#endif
	if ((AL_CS_TYPE_DIGITAL_BLIND != pstInfo->enType) ||
		(NULL == pdata))
	{
		return AL_FAILURE;
	}

	pParam->enType = pstDigital->enTunerType;

	if (pstDigital->enTunerType == TUNER_OFDM || pstDigital->enTunerType == TUNER_TDS_OFDM)
	{
	}
	else if (pstDigital->enTunerType == TUNER_QAM)
	{
	}
	else if (pstDigital->enTunerType == TUNER_QPSK)
	{
    #ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
		AL_DB_QueryDetail(pstDigital->Satellite.hNet, &stNetInfo);
		usLNBFreqL = stNetInfo.stDVBSNetwork.uiLNBFreq >> 16;
		usLNBFreqH = stNetInfo.stDVBSNetwork.uiLNBFreq & 0x0000FFFF;

        if (pstInfo->uiCapabilities&AL_CS_SUPPORT_STEP_BLIND_SCAN)
        {
            MID_SatCtrl_FrontendCtrl(FRONTEND_CMD_GET_BLINDSEARCH_TUNER_STEP_SIZE, &uiTuningStep);
    		MID_SatCtrl_FrontendCtrl(FRONTEND_CMD_GET_BLINDSEARCH_TUNER_BAND, &uiTuningBand);
        }

		if (g_CurPolar == POLAR_MAX)
		{
            pstDigital->Satellite.pstCurSateTp = al_null;//get scan param
			AI_TpListGetNode(pstDigital->Satellite.stTpListHdl, (void**)&(pstDigital->Satellite.pstCurSateTp));
			if (pstDigital->Satellite.ucBlindSearchPolar == BOTH_H_V)
			{
				pParam->u.qpsk.polarization = HORIZONTAL;
			}
			else
			{
				pParam->u.qpsk.polarization = pstDigital->Satellite.ucBlindSearchPolar;
			}

            if ((usLNBFreqL != usLNBFreqH) && (usLNBFreqL < LNB_C_Ku_DEVIDING_LINE || usLNBFreqH < LNB_C_Ku_DEVIDING_LINE))
            {
                if (pParam->u.qpsk.polarization == VERTICAL)
                {
                    g_wLNBFreq = usLNBFreqH;
                }
                else
                {
                    g_wLNBFreq = usLNBFreqL;
                }
            }
            else
            {
			    g_wLNBFreq = usLNBFreqL;
			}
		}
		else
		{
			if (pstInfo->uiCapabilities&AL_CS_SUPPORT_STEP_BLIND_SCAN)
			{
				AL_CS_DTV_GetStartEndFreq(pstDigital->Satellite.hNet, g_wLNBFreq, &uiFreqStart, &uiFreqEnd);
				uiFrequence = MID_SatCtrl_GetIfFrequency(pstDigital->Satellite.pstCurSateTp->uiFrequence);
				if (uiFrequence < uiFreqEnd-uiTuningStep)
				{
					ucNextBand = FALSE;
				}
			}
			if (ucNextBand == TRUE)
			{
				if ((pstDigital->Satellite.ucBlindSearchPolar == BOTH_H_V) &&
					(pParam->u.qpsk.polarization == HORIZONTAL))
				{
					pParam->u.qpsk.polarization = VERTICAL;
				}
				else
				{
					if ((usLNBFreqL == usLNBFreqH) || (g_wLNBFreq == usLNBFreqH))
					{
						g_CurPolar = POLAR_MAX;
						return AL_FAILURE;
					}
					else
					{
						g_wLNBFreq = usLNBFreqH;
						if (pstDigital->Satellite.ucBlindSearchPolar == BOTH_H_V)
						{
							pParam->u.qpsk.polarization = HORIZONTAL;
						}
						else
						{
							pParam->u.qpsk.polarization = pstDigital->Satellite.ucBlindSearchPolar;
						}
					}
				}
			}
		}
		AL_CS_DTV_GetStartEndFreq(pstDigital->Satellite.hNet, g_wLNBFreq, &uiFreqStart, &uiFreqEnd);
		if (pstInfo->uiCapabilities&AL_CS_SUPPORT_STEP_BLIND_SCAN)
		{
			if (ucNextBand == TRUE)
			{
				pParam->u.qpsk.frequency = uiFreqStart;
			}
			else
			{
				pParam->u.qpsk.frequency = pstDigital->Satellite.uiCurrFreq + uiTuningStep;
			}
			if (uiTuningStep < uiTuningBand)
			{
				pParam->u.qpsk.freq_end = pParam->u.qpsk.frequency + uiTuningBand;
			}
			else
			{
				pParam->u.qpsk.freq_end = pParam->u.qpsk.frequency + uiTuningStep;
			}
		}
		else
		{
			pParam->u.qpsk.frequency = uiFreqStart;
			pParam->u.qpsk.freq_end = uiFreqEnd;
		}

#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
        pParam->u.qpsk.fe_type = g_DVBSX_NextScanMode;
#endif
		CS_DVBS_DEBUG_MESSAGE("\n\n");
        CS_DVBS_DEBUG_MESSAGE("==========fe_type: %s\n", \
            (pParam->u.qpsk.fe_type == FRONTEND_TYPE_DVBS2)? "dvb-s2" : "dvb-s");
		CS_DVBS_DEBUG_MESSAGE("==========start:   %d\n", pParam->u.qpsk.frequency);
		CS_DVBS_DEBUG_MESSAGE("==========freq_end:%d\n", pParam->u.qpsk.freq_end);
		CS_DVBS_DEBUG_MESSAGE("==========polarization:%d(%s)\n\n", pParam->u.qpsk.polarization,\
			(pParam->u.qpsk.polarization == HORIZONTAL)? "H" : "V");

        if ((usLNBFreqL != usLNBFreqH) && (usLNBFreqL < LNB_C_Ku_DEVIDING_LINE || usLNBFreqH < LNB_C_Ku_DEVIDING_LINE))
        {
            MID_SatCtrl_CBand_DualLNBSetType(g_wLNBFreq);
            if ((g_wLNBFreq == LNB3_5150 && pParam->u.qpsk.polarization != HORIZONTAL) || \
                (g_wLNBFreq == LNB3_5750 && pParam->u.qpsk.polarization != VERTICAL))
            {
                CS_ERROR_MESSAGE("\n\n[%s]C band polar setting error!!\n\n", __FUNCTION__);
            }
        }

		pstDigital->Satellite.uiCurrFreq = pParam->u.qpsk.frequency;
		g_CurPolar = pParam->u.qpsk.polarization;
		pstDigital->Satellite.pstCurSateTp->uiFrequence = CS_DTV_GetTpFrequency(g_wLNBFreq, pParam->u.qpsk.frequency);
		uiFrequence = pstDigital->Satellite.pstCurSateTp->uiFrequence;
        //uiFrequence = CS_DTV_GetTpFrequency(g_wLNBFreq, pParam->u.qpsk.frequency);
		CurTp.usFreq = uiFrequence;
		CurTp.usSymRate = pParam->u.qpsk.symrate;
		CurTp.u8Polar = pParam->u.qpsk.polarization;
        if (pParam->u.qpsk.fe_type == FRONTEND_TYPE_DVBS2)
        {
            CurTp.u8TpType = EDVB_DELIVER_TYPE_S2;
        }
        else
        {
            CurTp.u8TpType = EDVB_DELIVER_TYPE_S;
        }
		MID_SatCtrl_SetCurrentSatelliteInfo(SATINFO_ALL, 0, &(stNetInfo.stDVBSNetwork));
		SatLocal.u32SatLongitudeDirection = stNetInfo.stDVBSNetwork.ucEastWest;
		SatLocal.u32SatLongitude = stNetInfo.stDVBSNetwork.iLongitude;
		MID_SatCtrl_SetUsalsLocation(MOTORSEL_SAT, NULL, &SatLocal);
		MID_SatCtrl_LNBCtrlSetFreq(stNetInfo.stDVBSNetwork.uiLNBFreq);
		MID_SatCtrl_SetCurrentTpInfo(TPINFO_FREQ, CurTp.usFreq, NULL);
		CurTp.usFreq = MID_SatCtrl_GetIfFrequency(CurTp.usFreq);
        if ((pstInfo->uiCapabilities & AL_CS_SUPPORT_BLIND_SCAN_METHOD_2)
            || (pstInfo->uiCapabilities & AL_CS_SUPPORT_BLIND_SCAN_METHOD_3)
            )
        {
            bConnectFE = FALSE;
        }
        else
        {
            bConnectFE = TRUE;
        }

        if ((usLNBFreqL != usLNBFreqH) && (usLNBFreqL > LNB_C_Ku_DEVIDING_LINE && usLNBFreqH > LNB_C_Ku_DEVIDING_LINE))
        {
            if(g_wLNBFreq == usLNBFreqL && g_CurPolar == VERTICAL)
            {
                pParam->u.qpsk.Diseqc_Bank = FRONTEND_DISEQC_BANK_A_LB_VP;
            }
            else if(g_wLNBFreq == usLNBFreqH && g_CurPolar == VERTICAL)
            {
                pParam->u.qpsk.Diseqc_Bank = FRONTEND_DISEQC_BANK_A_HB_VP;
            }
            else if(g_wLNBFreq == usLNBFreqL && g_CurPolar == HORIZONTAL)
            {
                pParam->u.qpsk.Diseqc_Bank = FRONTEND_DISEQC_BANK_A_LB_HP;
            }
            else if(g_wLNBFreq == usLNBFreqH && g_CurPolar == HORIZONTAL)
            {
                pParam->u.qpsk.Diseqc_Bank = FRONTEND_DISEQC_BANK_A_HB_HP;
            }
            else
            {
                pParam->u.qpsk.Diseqc_Bank = FRONTEND_DISEQC_BANK_A_LB_VP;
            }
        }

        MID_Playback_DVBSTune(CurTp, FALSE, bConnectFE);
	#endif

	}
	else if (pstDigital->enTunerType == TUNER_BST_OFDM)
	{
	}
	else
	{
	}

	if (pstDigital->enTunerType == TUNER_QPSK)
	{
		pstInfo->stSearchInfo.uiCurFreq = (uiFrequence&0xffff);
	}
	else
	{
		pstInfo->stSearchInfo.uiCurFreq = uiFrequence;
	}

	pstInfo->stSearchInfo.u.dtv.ucCurBand ++;
	pstInfo->stSearchInfo.u.dtv.uiProgress = 0;
	CS_SEND_MSG(AL_CS_MSG_TYPE_NEW_BAND, 0);

	return AL_SUCCESS;
}

#if 0 // removed since this function is never callbacked since SVN 61341
static AL_Return_t CS_DtvBuildBlindScanTbl(al_uint32 freq_KHz, al_uint32 symbol, al_uint32 fe_type)
{
	cs_info_st* pstInfo =  GET_CS_INFO();

	digital_search_data_st* pstDigital = &(pstInfo->unScanData.digital);

	CS_DEBUG_MESSAGE("Enter %s\n",__FUNCTION__);

	if (pstDigital->enTunerType == TUNER_QAM)
	{
	}
	else if (pstDigital->enTunerType == TUNER_QPSK)
	{
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
		cs_sate_tp_info_st stSateTpInfo;
		if (pstDigital->Satellite.stBSTpTbl == TP_LIST_INVALID_HDL)
		{
			if (AL_SUCCESS != AI_TpListInit(&(pstDigital->Satellite.stBSTpTbl)))
			{
				CS_ERROR_MESSAGE("%s Fail\n",__FUNCTION__);
				return AL_FAILURE;
			}
			pstInfo->stSearchInfo.u.dtv.usTotalTpNum = 0;
		}

		memset(&stSateTpInfo, 0, sizeof(stSateTpInfo));
		stSateTpInfo.uiFrequence    = freq_KHz/1000;
		stSateTpInfo.uiSymRate      = symbol/1000;
		stSateTpInfo.polarization   = g_CurPolar;
        stSateTpInfo.fe_type        = fe_type;
		stSateTpInfo.uiFrequence = MID_SatCtrl_GetTpFrequency(g_wLNBFreq, stSateTpInfo.uiFrequence);

		if (AL_SUCCESS != AI_TpListAddNode(pstDigital->Satellite.stBSTpTbl,
					&stSateTpInfo, sizeof(cs_sate_tp_info_st)))
		{
			CS_ERROR_MESSAGE("%s Fail\n",__FUNCTION__);
			return AL_FAILURE;
		}
		pstInfo->stSearchInfo.u.dtv.usTotalTpNum++;
#endif
	}

	CS_DEBUG_MESSAGE("Exit %s\n",__FUNCTION__);
	return AL_SUCCESS;
}
#endif

static AL_Return_t CS_DtvSendUpdateUIMsg(al_uint32 u32Progress, al_uint32* UserSearchState, al_uint32 reserve)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
	cs_msg_st stmsg;
	cs_msg_st* msg = &stmsg;

	CS_DEBUG_MESSAGE("Enter %s \n",__FUNCTION__);

	memset(&stmsg, 0, sizeof(stmsg));

	*UserSearchState = pstInfo->enState;

	if (u32Progress == 0)
	{
		return AL_FAILURE;
	}

	pstInfo->stSearchInfo.u.dtv.uiProgress = u32Progress;
	CS_SEND_MSG(AL_CS_MSG_TYPE_NEW_BAND, 0);

	if (pstInfo->pstQueue && (stmsg.enType != AL_CS_MSG_TYPE_NONE))
	{
		GL_QueueSend(pstInfo->pstQueue, (void *)&stmsg, sizeof(cs_msg_st));
	}

	CS_DEBUG_MESSAGE("Exit %s\n",__FUNCTION__);
	return AL_SUCCESS;
}

#endif

#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
static AL_Return_t CS_DtvCheckTypeForNit(AL_Return_t ret)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
	digital_search_data_st* pstDigital = &pstInfo->unScanData.digital;

	if (pstInfo->uiCapabilities & AL_CS_SUPPORT_GET_FREQ_FROM_NIT)
	{
		if (g_DVBSX_NextScanMode == FRONTEND_TYPE_QPSK)
		{
			while ((ret == AL_SUCCESS)
				&& (pstDigital->Satellite.pstCurSateTp->fe_type ==	FRONTEND_TYPE_DVBS2)
				&& (pstDigital->Satellite.stTpListHdl == pstDigital->Satellite.stNITTpTbl))
			{
				ret = AI_TpListGetNode(pstDigital->Satellite.stTpListHdl,
					(void**)&(pstDigital->Satellite.pstCurSateTp));
			}
		}
		else if (g_DVBSX_NextScanMode == FRONTEND_TYPE_DVBS2)
		{
			while ((ret == AL_SUCCESS)
				&& (pstDigital->Satellite.pstCurSateTp->fe_type ==	FRONTEND_TYPE_QPSK)
				&& (pstDigital->Satellite.stTpListHdl == pstDigital->Satellite.stNITTpTbl))
			{
				ret = AI_TpListGetNode(pstDigital->Satellite.stTpListHdl,
					(void**)&(pstDigital->Satellite.pstCurSateTp));
			}
		}
	}

	return ret;
}
#endif
extern UINT8 _ScanDecodeGetPATTimeoutStatus(void);
/*****************************************************************************
** FUNCTION : static AL_Return_t CS_DtvGetNextTp(void)
**
** DESCRIPTION :
**				Get the next TP information
**
** PARAMETERS :
**				pstTp - the TP information buffer
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t CS_DtvGetNextTp(void)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
	digital_search_data_st* pstDigital = &pstInfo->unScanData.digital;
#if defined(CONFIG_DVB_SYSTEM_DVBS_SUPPORT) || defined(CONFIG_DVB_SYSTEM_DVBC_SUPPORT)
	AL_Return_t ret = AL_FAILURE;
#endif

	if ((AL_CS_TYPE_DIGITAL_BLIND != pstInfo->enType) &&
		(AL_CS_TYPE_DIGITAL_MANUAL != pstInfo->enType) &&
		(AL_CS_TYPE_DIGITAL != pstInfo->enType))
	{
		return AL_FAILURE;
	}

	if (TUNER_QAM == pstDigital->enTunerType)
	{
#ifdef CONFIG_DVB_SYSTEM_DVBC_SUPPORT
		if(NetworkScanNeedAbortScan == al_true)
		{
			return AL_FAILURE;
		}

		if ((pstInfo->ucLock == al_true) && (pstInfo->ucHasGetFreFromNIT != al_true)
			&& ((pstDigital->Cable.pstNetworkScanInfo.uiDVBCSearchMode == AL_DVBC_SEARCHMODE_FULL)
			|| (pstDigital->Cable.pstNetworkScanInfo.uiDVBCSearchMode == AL_DVBC_SEARCHMODE_FULL_NETWORK)))
		{
			al_uint8 iCount = 0;
			do
			{
				ret = AI_TpListGetNode(pstDigital->Cable.stTpListHdl,
					(void**)&(pstDigital->Cable.pstCurCableTp));
				iCount ++;
				if (ret == AL_SUCCESS)
				{
					printf("[%s:%d] iCount = %d, freq: %d\n",__FUNCTION__,__LINE__,iCount,pstDigital->Cable.pstCurCableTp->uiFrequence);
				}
			}while((AL_SUCCESS == ret) && (iCount < SLIP_NUMBER));
		}
		else
		{
			/* for quick search mode, we need to check the scan history of previous freq */
			cs_cable_tp_info_st *pstPrevious = pstDigital->Cable.pstCurCableTp;
			
			ret = AI_TpListGetNode(pstDigital->Cable.stTpListHdl,
				(void**)&(pstDigital->Cable.pstCurCableTp));

			if (ret == AL_SUCCESS && pstPrevious != NULL 
				&& pstDigital->Cable.pstNetworkScanInfo.uiDVBCSearchMode == AL_DVBC_SEARCHMODE_QUICK)
			{
				#define TUNER_LOCK_DIFF_RANGE (500)
				if (pstPrevious->locked 
					&& pstDigital->Cable.pstCurCableTp->uiFrequence -pstPrevious->uiFrequence <= TUNER_LOCK_DIFF_RANGE)
				{
					/* skip this freq if previous freq has been locked  */
					pstInfo->stSearchInfo.u.dtv.usCurTpCnt ++;
					
					ret = AI_TpListGetNode(pstDigital->Cable.stTpListHdl, (void**)&(pstDigital->Cable.pstCurCableTp));

					return ret;
				}	
				
			}
			
		}
		return ret;
#endif
	}

	if (TUNER_QPSK == pstDigital->enTunerType)
	{
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
		if ((g_DVBSX_DelTp != FALSE) && (((g_DVBSX_NextScanMode == FRONTEND_TYPE_QPSK) && (g_DVBSX_CurrentFeType == AL_CS_DVBSX_S_TO_S2))
			|| ((g_DVBSX_NextScanMode == FRONTEND_TYPE_DVBS2) && (g_DVBSX_CurrentFeType == AL_CS_DVBSX_S2_TO_S))))
		{
			if ((pstInfo->uiCapabilities & AL_CS_SUPPORT_SELECT_TP_SCAN_MODE)
				|| ((pstInfo->uiCapabilities & AL_CS_SUPPORT_GET_FREQ_FROM_NIT) && (pstDigital->Satellite.stTpListHdl == pstDigital->Satellite.stDefaultTpTbl)))
			{
				AI_TpListDeleteOneNode(pstDigital->Satellite.stTpListHdl,(void**)&(g_pstCurSateTp));

            	pstDigital->Satellite.pstCurSateTp = g_pstCurSateTp;
				pstInfo->stSearchInfo.u.dtv.usTotalTpNum--;
			}
		}
        g_DVBSX_DelTp = FALSE;

		if (_ScanDecodeGetPATTimeoutStatus() && g_PATTimoutTryCnt <= MAX_PATTIMEOUT_TYR
			&& pstDigital->Satellite.pstCurSateTp != NULL)
		{
			CS_DEBUG_MESSAGE("\n\n[%s %d]Try uiFrequence = 0x%x, uiSymRate = %d, polarization = %d, fe_type = %d\n\n", __FUNCTION__, __LINE__,
				pstDigital->Satellite.pstCurSateTp->uiFrequence, pstDigital->Satellite.pstCurSateTp->uiSymRate,
				pstDigital->Satellite.pstCurSateTp->polarization, pstDigital->Satellite.pstCurSateTp->fe_type);
            pstInfo->stSearchInfo.u.dtv.usCurTpCnt--;
			g_PATTimoutTryCnt++;
			return AL_SUCCESS;
		}
		g_PATTimoutTryCnt = 0;
		ret = AI_TpListGetNode(pstDigital->Satellite.stTpListHdl,
			(void**)&(pstDigital->Satellite.pstCurSateTp));
        g_pstCurSateTp = pstDigital->Satellite.pstCurSateTp;

		ret = CS_DtvCheckTypeForNit(ret);

		if ((ret != AL_SUCCESS) &&
			(pstInfo->uiCapabilities & AL_CS_SUPPORT_BLIND_SCAN_METHOD_2) &&
			(pstDigital->Satellite.stBSTpTbl != pstDigital->Satellite.stTpListHdl) &&
			(pstDigital->Satellite.stBSTpTbl != TP_LIST_INVALID_HDL))
		{
			pstDigital->Satellite.pstCurSateTp = al_null;
			pstDigital->Satellite.stTpListHdl = pstDigital->Satellite.stBSTpTbl;
			ret = AI_TpListGetNode(pstDigital->Satellite.stTpListHdl,
				(void**)&(pstDigital->Satellite.pstCurSateTp));
		}

        if ((ret != AL_SUCCESS) \
            &&((pstInfo->uiCapabilities & AL_CS_SUPPORT_SELECT_TP_SCAN_MODE)))
        {
            if (CS_DTV_SwitchScanFEType() == AL_SUCCESS)
            {
                pstDigital->Satellite.pstCurSateTp = al_null;
                pstDigital->Satellite.stTpListHdl = pstDigital->Satellite.stDefaultTpTbl;
    			ret = AI_TpListGetNode(pstDigital->Satellite.stTpListHdl,
    				(void**)&(pstDigital->Satellite.pstCurSateTp));
            }
        }

		/*
		* AL_CS_DVBSX_S_TO_S2, step 1 search default tp list -S for all tp list; step 2 search NIT tp list -S for S tp list , skip S2 tp list;
		* 	step 3 search default tp list -S2 for all tp list; step 4 search NIT tp list -S2 for S2 tp list, skip S tp list.
		*/
		if ((ret != AL_SUCCESS) && (pstInfo->uiCapabilities & AL_CS_SUPPORT_GET_FREQ_FROM_NIT))
		{
			/* current tp list is default tp list */
			if (pstDigital->Satellite.stTpListHdl == pstDigital->Satellite.stDefaultTpTbl)
			{
				/* S/S2 default change to NIT */
				if (pstDigital->Satellite.stNITTpTbl != TP_LIST_INVALID_HDL)
				{
					pstDigital->Satellite.pstCurSateTp = al_null;
					pstDigital->Satellite.stTpListHdl = pstDigital->Satellite.stNITTpTbl;
					ret = AI_TpListGetNode(pstDigital->Satellite.stTpListHdl,
						(void**)&(pstDigital->Satellite.pstCurSateTp));
					ret = CS_DtvCheckTypeForNit(ret);
					/* current is S, but NIT tp list all  tp is S2
					** or current is S2, but NIT tp list all tp is S
					*/
					if (ret != AL_SUCCESS)
					{
						/* S change to S2 or S2 change to S */
						if (CS_DTV_SwitchScanFEType() == AL_SUCCESS)
			            {
			                pstDigital->Satellite.pstCurSateTp = al_null;
			                pstDigital->Satellite.stTpListHdl = pstDigital->Satellite.stDefaultTpTbl;
			    			ret = AI_TpListGetNode(pstDigital->Satellite.stTpListHdl,
			    				(void**)&(pstDigital->Satellite.pstCurSateTp));
							/* AL_CS_DVBSX_S_TO_S2, S defaut tp list is deleted all
							** or AL_CS_DVBSX_S2_TO_S, S2 defaut tp list is deleted all
							*/
							if (ret != AL_SUCCESS)
							{
								pstDigital->Satellite.pstCurSateTp = al_null;
								pstDigital->Satellite.stTpListHdl = pstDigital->Satellite.stNITTpTbl;
								ret = AI_TpListGetNode(pstDigital->Satellite.stTpListHdl,
									(void**)&(pstDigital->Satellite.pstCurSateTp));
								ret = CS_DtvCheckTypeForNit(ret);
								/* AL_CS_DVBSX_S_TO_S2, S is not search nit tp list but S2 searched nit tp list
								** or AL_CS_DVBSX_S2_TO_S, S2 is not search nit tp list but S searched nit tp list
								*/
								if ((ret != AL_SUCCESS) && g_NeedScanNitList)
								{
									if (g_DVBSX_CurrentFeType == AL_CS_DVBSX_S_TO_S2)
									{
										g_DVBSX_NextScanMode = FRONTEND_TYPE_QPSK;
										g_DVBSX_CurrentFeType = AL_CS_DVBSX_S2_TO_S;
									}
									else
									{
										g_DVBSX_NextScanMode = FRONTEND_TYPE_DVBS2;
										g_DVBSX_CurrentFeType = AL_CS_DVBSX_S_TO_S2;
									}
									g_NeedScanNitList = al_false;
									pstDigital->Satellite.pstCurSateTp = al_null;
									pstDigital->Satellite.stTpListHdl = pstDigital->Satellite.stNITTpTbl;
									ret = AI_TpListGetNode(pstDigital->Satellite.stTpListHdl,
										(void**)&(pstDigital->Satellite.pstCurSateTp));
									ret = CS_DtvCheckTypeForNit(ret);
								}
							}
			            }
						/* AL_CS_DVBSX_S_TO_S2, S is not search nit tp list but S2 searched nit tp list
						** or AL_CS_DVBSX_S2_TO_S, S2 is not search nit tp list but S searched nit tp list
						*/
						else if (g_NeedScanNitList)
						{
							if (g_DVBSX_CurrentFeType == AL_CS_DVBSX_S_TO_S2)
							{
								g_DVBSX_NextScanMode = FRONTEND_TYPE_QPSK;
								g_DVBSX_CurrentFeType = AL_CS_DVBSX_S2_TO_S;
							}
							else
							{
								g_DVBSX_NextScanMode = FRONTEND_TYPE_DVBS2;
								g_DVBSX_CurrentFeType = AL_CS_DVBSX_S_TO_S2;
							}
							g_NeedScanNitList = al_false;
							pstDigital->Satellite.pstCurSateTp = al_null;
							pstDigital->Satellite.stTpListHdl = pstDigital->Satellite.stNITTpTbl;
							ret = AI_TpListGetNode(pstDigital->Satellite.stTpListHdl,
								(void**)&(pstDigital->Satellite.pstCurSateTp));
							ret = CS_DtvCheckTypeForNit(ret);
						}
					}
				}
				else
				{
					/* S change to S2 or S2 change to S */
					if (CS_DTV_SwitchScanFEType() == AL_SUCCESS)
		            {
		            	g_NeedScanNitList = al_true;
		                pstDigital->Satellite.pstCurSateTp = al_null;
		                pstDigital->Satellite.stTpListHdl = pstDigital->Satellite.stDefaultTpTbl;
		    			ret = AI_TpListGetNode(pstDigital->Satellite.stTpListHdl,
		    				(void**)&(pstDigital->Satellite.pstCurSateTp));
		            }
				}
			}
			/* current tp list is Nit tp list */
			else if (pstDigital->Satellite.stTpListHdl == pstDigital->Satellite.stNITTpTbl)
			{
				/* S change to S2 or S2 change to S */
				if (CS_DTV_SwitchScanFEType() == AL_SUCCESS)
				{
					pstDigital->Satellite.pstCurSateTp = al_null;
					pstDigital->Satellite.stTpListHdl = pstDigital->Satellite.stDefaultTpTbl;
					ret = AI_TpListGetNode(pstDigital->Satellite.stTpListHdl,
						(void**)&(pstDigital->Satellite.pstCurSateTp));
					/* AL_CS_DVBSX_S_TO_S2, S defaut tp list is deleted all
					** or AL_CS_DVBSX_S2_TO_S, S2 defaut tp list is deleted all
					*/
					if (ret != AL_SUCCESS)
					{
						pstDigital->Satellite.pstCurSateTp = al_null;
						pstDigital->Satellite.stTpListHdl = pstDigital->Satellite.stNITTpTbl;
						ret = AI_TpListGetNode(pstDigital->Satellite.stTpListHdl,
							(void**)&(pstDigital->Satellite.pstCurSateTp));
						ret = CS_DtvCheckTypeForNit(ret);
						/* AL_CS_DVBSX_S_TO_S2, S is not search nit tp list but S2 searched nit tp list
						** or AL_CS_DVBSX_S2_TO_S, S2 is not search nit tp list but S searched nit tp list
						*/
						if ((ret != AL_SUCCESS) && g_NeedScanNitList)
						{
							if (g_DVBSX_CurrentFeType == AL_CS_DVBSX_S_TO_S2)
							{
								g_DVBSX_NextScanMode = FRONTEND_TYPE_QPSK;
								g_DVBSX_CurrentFeType = AL_CS_DVBSX_S2_TO_S;
							}
							else
							{
								g_DVBSX_NextScanMode = FRONTEND_TYPE_DVBS2;
								g_DVBSX_CurrentFeType = AL_CS_DVBSX_S_TO_S2;
							}
							g_NeedScanNitList = al_false;
							pstDigital->Satellite.pstCurSateTp = al_null;
							pstDigital->Satellite.stTpListHdl = pstDigital->Satellite.stNITTpTbl;
							ret = AI_TpListGetNode(pstDigital->Satellite.stTpListHdl,
								(void**)&(pstDigital->Satellite.pstCurSateTp));
							ret = CS_DtvCheckTypeForNit(ret);
						}
					}
				}
				/* AL_CS_DVBSX_S_TO_S2, S is not search nit tp list but S2 searched nit tp list
				** or AL_CS_DVBSX_S2_TO_S, S2 is not search nit tp list but S searched nit tp list
				*/
				else if (g_NeedScanNitList && (pstDigital->Satellite.stNITTpTbl != TP_LIST_INVALID_HDL))
				{
					if (g_DVBSX_CurrentFeType == AL_CS_DVBSX_S_TO_S2)
					{
						g_DVBSX_NextScanMode = FRONTEND_TYPE_QPSK;
						g_DVBSX_CurrentFeType = AL_CS_DVBSX_S2_TO_S;
					}
					else
					{
						g_DVBSX_NextScanMode = FRONTEND_TYPE_DVBS2;
						g_DVBSX_CurrentFeType = AL_CS_DVBSX_S_TO_S2;
					}
					g_NeedScanNitList = al_false;
					pstDigital->Satellite.pstCurSateTp = al_null;
					pstDigital->Satellite.stTpListHdl = pstDigital->Satellite.stNITTpTbl;
					ret = AI_TpListGetNode(pstDigital->Satellite.stTpListHdl,
						(void**)&(pstDigital->Satellite.pstCurSateTp));
					ret = CS_DtvCheckTypeForNit(ret);
				}
			}
		}

		g_pstCurSateTp = pstDigital->Satellite.pstCurSateTp;
		return ret;
#endif
	}

	if (TUNER_OFDM == pstDigital->enTunerType || TUNER_TDS_OFDM == pstDigital->enTunerType)
	{
#ifdef CONFIG_DVB_SYSTEM_DVBT_SUPPORT
		const AL_TPSects_Info_st* pstTbl = NULL;
		AL_TPSects_Info_st* pstTp = &(pstDigital->Terr.stInput);
		al_int32 tp_num = 0;
        static BOOLEAN bResetBw = TRUE;

		if (AL_CS_TYPE_DIGITAL_MANUAL == pstInfo->enType)
		{
			al_uint8 bMaxBw = 0;

			pstTbl = &(pstDigital->Terr.stInput);
			tp_num = pstInfo->stSearchInfo.u.dtv.usTotalTpNum;

            if (pstDigital->Terr.sCurTpInx >= tp_num && !(pstDigital->Terr.ScanMode & AL_SCAN_SEPARATE_DVBT2))
			{
                bResetBw = TRUE;
                #ifdef CONFIG_DVB_SYSTEM_DVBT2_SUPPORT
				if (pstDigital->Terr.ScanMode & AL_SCAN_SEPARATE_DVBT)
				{
					pstDigital->Terr.ScanMode = AL_SCAN_SEPARATE_DVBT2;
                    pstDigital->Terr.ucCurBW = 0;
				}
                else if (pstDigital->Terr.ScanMode & AL_SCAN_TOGETHER_DVBT)
				{
                    pstDigital->Terr.ScanMode = AL_SCAN_TOGETHER_DVBT2;
                    pstDigital->Terr.ucCurBW = 0;
				}
                else
                #endif
				{
					return AL_FAILURE;
				}
			}

            if (pstTbl != NULL)
            {
                AL_CS_DtvMaxBW(pstTbl->stBandWidth, &bMaxBw);
                if (pstDigital->Terr.ucCurBW >= bMaxBw || bResetBw == TRUE)
                {
                    bResetBw = FALSE;
                    pstDigital->Terr.ucCurBW = 0;
                }
            }

            if (!(pstDigital->Terr.ScanMode & AL_SCAN_SEPARATE_DVBT2)
                && !(pstDigital->Terr.ScanMode & AL_SCAN_TOGETHER_DVBT2)
                && !(pstDigital->Terr.ScanMode & AL_SCAN_ONLY_DVBT2))//T2 no need switch BW
			{
                if (pstDigital->Terr.ucCurBW == 0)
                {
                    AL_CS_DtvMinBW(pstTbl->stBandWidth, &(pstDigital->Terr.ucCurBW));
    				if (!(pstTbl->stBandWidth.eBandWidth.BandWidthSWEn))
    				{
                        bResetBw = TRUE;
                        pstDigital->Terr.sCurTpInx ++;
                    }
                }
                else //if (pstDigital->Terr.ucCurBW != 0)
                {
                    AL_CS_DtvMaxBW(pstTbl->stBandWidth, &bMaxBw);
                    if (pstTbl->stBandWidth.eBandWidth.BandWidthSWEn)
                    {
                        if (pstDigital->Terr.ucCurBW < bMaxBw)
                        {
                            if (AL_SUCCESS == AL_CS_DtvNextBW(pstTbl->stBandWidth, &(pstDigital->Terr.ucCurBW), 1))
                            {
                                if (pstDigital->Terr.ucCurBW >= bMaxBw)
                                {
                                    bResetBw = TRUE;
                                    pstDigital->Terr.sCurTpInx ++;
                                }
                            }
                            else
                            {
                                bResetBw = TRUE;
                                pstDigital->Terr.sCurTpInx ++;
                            }
                        }
                    }
                    else
                    {
                        bResetBw = TRUE;
                        pstDigital->Terr.sCurTpInx ++;
                    }
                }
			}

#ifdef CONFIG_DVB_SYSTEM_DVBT2_SUPPORT
			if (pstDigital->Terr.ScanMode & AL_SCAN_SEPARATE_DVBT2)
			{
				if (pstDigital->Terr.CurT2Inx >= pstDigital->Terr.TotalT2count)
				{
                    pstInfo->stSearchInfo.u.dtv.uiProgress = 100;
					return AL_FAILURE;
				}
				AL_T2_List *pstListNode;
				_AI_CS_GetNode(pstDigital->Terr.CurT2Inx, &pstListNode);
                if (pstListNode == NULL)
                {
                    return AL_FAILURE;
                }
				pstTbl = &pstListNode->stT2Input;

				memset(pstTp, 0, sizeof(AL_TPSects_Info_st));
				pstTp->stBandWidth = pstTbl->stBandWidth;
				pstTp->StartFreq = pstTbl->StartFreq;
				pstTp->StartTpNum = pstTbl->StartTpNum;
				pstTp->UHF_VHF = pstTbl->UHF_VHF;

                if (pstDigital->Terr.ucCurBW == 0)
                {
                    AL_CS_DtvMinBW(pstTbl->stBandWidth, &(pstDigital->Terr.ucCurBW));
    				if (!(pstTbl->stBandWidth.eBandWidth.BandWidthSWEn))
    				{
                        bResetBw = TRUE;
                        ++pstDigital->Terr.CurT2Inx;
                    }
                }
                else //if (pstDigital->Terr.ucCurBW != 0)
                {
                    AL_CS_DtvMaxBW(pstTbl->stBandWidth, &bMaxBw);
                    if (pstTbl->stBandWidth.eBandWidth.BandWidthSWEn)
                    {
                        if (pstDigital->Terr.ucCurBW < bMaxBw)
                        {
                            if (AL_SUCCESS == AL_CS_DtvNextBW(pstTbl->stBandWidth, &(pstDigital->Terr.ucCurBW), 1))
                            {
                                if (pstDigital->Terr.ucCurBW >= bMaxBw)
                                {
                                    bResetBw = TRUE;
                                    ++pstDigital->Terr.CurT2Inx;
                                }
                            }
                            else
                            {
                                bResetBw = TRUE;
                                ++pstDigital->Terr.CurT2Inx;
                            }
                        }
                    }
                    else
                    {
                        bResetBw = TRUE;
                        ++pstDigital->Terr.CurT2Inx;
                    }
                }
			}
			else if (pstDigital->Terr.ScanMode == AL_SCAN_ONLY_DVBT2)
			{
				AL_CS_DtvMinBW(pstTbl->stBandWidth, &(pstDigital->Terr.ucCurBW));
				if (!(pstTbl->stBandWidth.eBandWidth.BandWidthSWEn))
				{
                    bResetBw = TRUE;
                    pstDigital->Terr.sCurTpInx ++;
                }
			}
#endif
            return AL_SUCCESS;
		}
		else if (AL_CS_TYPE_DIGITAL == pstInfo->enType)
		{
			if (!(pstInfo->uiCapabilities & AL_CS_SUPPORT_NIT_FREQ_LIST_SCAN))
			{
				al_uint8 bMaxBw = 0;

                if ((pstDigital->Terr.ScanMode & AL_SCAN_SEPARATE_DVBT)
                    ||(pstDigital->Terr.ScanMode & AL_SCAN_TOGETHER_DVBT)
                    ||(pstDigital->Terr.ScanMode & AL_SCAN_ONLY_DVBT)
                    ||(pstDigital->Terr.ScanMode & AL_SCAN_ONLY_DVBT2))
                {
                    pstTbl = &(pstDigital->Terr.pstAreaTable->pTPRegion_Area[pstDigital->Terr.sCurSecInx]);

                    pstTbl = &(pstDigital->Terr.pstAreaTable->pTPRegion_Area[pstDigital->Terr.sCurSecInx]);
                    if(pstTbl == NULL)
                    {
                        return AL_FAILURE;
                    }

                    tp_num = pstTbl->SectTPCount;
                    if (pstDigital->Terr.sCurTpInx >= tp_num)
                    {
                        bResetBw = TRUE;
                        ++pstDigital->Terr.sCurSecInx;
                        pstDigital->Terr.sCurTpInx = 0;

                        if ((al_uint32) (pstDigital->Terr.sCurSecInx) > pstDigital->Terr.uiSectionNum)
                        {
#ifdef CONFIG_DVB_SYSTEM_DVBT2_SUPPORT
                            if (pstDigital->Terr.ScanMode & AL_SCAN_SEPARATE_DVBT)
                            {
                                pstDigital->Terr.sCurSecInx = 0;
                                pstDigital->Terr.ScanMode = AL_SCAN_SEPARATE_DVBT2;
                            }
                            else
#endif
                            {
                                bResetBw = TRUE;
                                return AL_FAILURE;
                            }
                        }
                    }

                    AL_CS_DtvMaxBW(pstTbl->stBandWidth, &bMaxBw);
                    if (pstDigital->Terr.ucCurBW >= bMaxBw || bResetBw == TRUE)
                    {
                        bResetBw = FALSE;
                        pstDigital->Terr.ucCurBW = 0;
                    }
                }

                if ((pstDigital->Terr.ScanMode & AL_SCAN_SEPARATE_DVBT)
                    ||(pstDigital->Terr.ScanMode & AL_SCAN_TOGETHER_DVBT)
                    ||(pstDigital->Terr.ScanMode & AL_SCAN_ONLY_DVBT)
                    ||(pstDigital->Terr.ScanMode & AL_SCAN_ONLY_DVBT2))
                {
					pstTbl = &(pstDigital->Terr.pstAreaTable->pTPRegion_Area[pstDigital->Terr.sCurSecInx]);

					memset(pstTp, 0, sizeof(AL_TPSects_Info_st));

					pstTp->stBandWidth = pstTbl->stBandWidth;
					pstTp->StartFreq = pstTbl->StartFreq + pstTbl->stBandWidth.eBandWidth.BaseBandWidth * pstDigital->Terr.sCurTpInx * 1000;
					pstTp->StartTpNum = pstTbl->StartTpNum + pstDigital->Terr.sCurTpInx;
					pstTp->UHF_VHF = pstTbl->UHF_VHF;

                    if (pstDigital->Terr.ucCurBW == 0)
                    {
                        AL_CS_DtvMinBW(pstTbl->stBandWidth, &(pstDigital->Terr.ucCurBW));
        				if (!(pstTbl->stBandWidth.eBandWidth.BandWidthSWEn))
        				{
                            bResetBw = TRUE;
                            pstDigital->Terr.sCurTpInx ++;
                        }
                    }
                    else //if (pstDigital->Terr.ucCurBW != 0)
                    {
                        AL_CS_DtvMaxBW(pstTbl->stBandWidth, &bMaxBw);
                        if (pstTbl->stBandWidth.eBandWidth.BandWidthSWEn)
                        {
                            if (pstDigital->Terr.ucCurBW < bMaxBw)
                            {
                                if (AL_SUCCESS == AL_CS_DtvNextBW(pstTbl->stBandWidth, &(pstDigital->Terr.ucCurBW), 1))
                                {
                                    if (pstDigital->Terr.ucCurBW >= bMaxBw)
                                    {
                                        bResetBw = TRUE;
                                        pstDigital->Terr.sCurTpInx ++;
                                    }
                                }
                                else
                                {
                                    bResetBw = TRUE;
                                    pstDigital->Terr.sCurTpInx ++;
                                }
                            }
                        }
                        else
                        {
                            bResetBw = TRUE;
                            pstDigital->Terr.sCurTpInx ++;
                        }
                    }
				}

#ifdef CONFIG_DVB_SYSTEM_DVBT2_SUPPORT
				if (pstDigital->Terr.ScanMode & AL_SCAN_SEPARATE_DVBT2)
				{
					AL_T2_List *pstListNode;

					if (pstDigital->Terr.CurT2Inx >= pstDigital->Terr.TotalT2count)
					{
                        bResetBw = TRUE;
                        pstInfo->stSearchInfo.u.dtv.uiProgress = 100;
						return AL_FAILURE;
					}

					_AI_CS_GetNode(pstDigital->Terr.CurT2Inx, &pstListNode);
                    if (pstListNode == NULL)
                    {
                        bResetBw = TRUE;
                        return AL_FAILURE;
                    }

					pstTbl = &pstListNode->stT2Input;

                    if (pstTbl != NULL)
                    {
                        AL_CS_DtvMaxBW(pstTbl->stBandWidth, &bMaxBw);
                        if (pstDigital->Terr.ucCurBW >= bMaxBw || bResetBw == TRUE)
                        {
                            bResetBw = FALSE;
                            pstDigital->Terr.ucCurBW = 0;
                        }
                    }

					memset(pstTp, 0, sizeof(AL_TPSects_Info_st));
					pstTp->stBandWidth = pstTbl->stBandWidth;
					pstTp->StartFreq = pstTbl->StartFreq;
					pstTp->StartTpNum = pstTbl->StartTpNum;
					pstTp->UHF_VHF = pstTbl->UHF_VHF;

                    if (pstDigital->Terr.ucCurBW == 0)
                    {
                        AL_CS_DtvMinBW(pstTbl->stBandWidth, &(pstDigital->Terr.ucCurBW));
        				if (!(pstTbl->stBandWidth.eBandWidth.BandWidthSWEn))
        				{
                            bResetBw = TRUE;
                            ++pstDigital->Terr.CurT2Inx;
                        }
                        AL_CS_DtvMaxBW(pstTbl->stBandWidth, &bMaxBw);
                    }
                    else //if (pstDigital->Terr.ucCurBW != 0)
                    {
                        AL_CS_DtvMaxBW(pstTbl->stBandWidth, &bMaxBw);
                        if (pstTbl->stBandWidth.eBandWidth.BandWidthSWEn)
                        {
                            if (pstDigital->Terr.ucCurBW < bMaxBw)
                            {
                                if (AL_SUCCESS == AL_CS_DtvNextBW(pstTbl->stBandWidth, &(pstDigital->Terr.ucCurBW), 1))
                                {
                                    if (pstDigital->Terr.ucCurBW >= bMaxBw)
                                    {
                                        bResetBw = TRUE;
                                        ++pstDigital->Terr.CurT2Inx;
                                    }
                                }
                                else
                                {
                                    bResetBw = TRUE;
                                    ++pstDigital->Terr.CurT2Inx;
                                }
                            }
                        }
                        else
                        {
                            bResetBw = TRUE;
                            ++pstDigital->Terr.CurT2Inx;
                        }
                    }
				}
#endif
                return AL_SUCCESS;
			}
			else
			{
				/* use NIT frequency_list_descriptor */
				if (pstDigital->Terr.ScanMode != AL_SCAN_SEPARATE_DVBT2)
				{
					return AI_TpListGetNode(pstDigital->Terr.stFreqListHdl, (void**)&(pstDigital->Terr.pstCurTerTp));
				}
			}
		}
#endif
	}
	else if (TUNER_BST_OFDM == pstDigital->enTunerType)
	{
#ifdef CONFIG_ISDB_SYSTEM
		const AL_TPSects_Info_st* pstTbl = NULL;
		AL_TPSects_Info_st* pstTp = &(pstDigital->Sbtvd.stInput);
		al_int32 tp_num;
		if (AL_CS_TYPE_DIGITAL_MANUAL == pstInfo->enType)
		{
			al_uint8 bMaxBw = 0;

			pstTbl = &(pstDigital->Sbtvd.stInput);

			if (pstDigital->Sbtvd.ucCurBW != 0)
			{
				AL_CS_DtvMaxBW(pstTbl->stBandWidth, &bMaxBw);

				if ((pstDigital->Sbtvd.ucCurBW < bMaxBw) &&
					(AL_SUCCESS == AL_CS_DtvNextBW(pstTbl->stBandWidth, &(pstDigital->Sbtvd.ucCurBW), 1)))
				{
					return AL_SUCCESS;
				}
			}

			tp_num = pstInfo->stSearchInfo.u.dtv.usTotalTpNum;
			if (pstDigital->Sbtvd.sCurTpInx >= tp_num)
			{
				return AL_FAILURE;
			}
			AL_CS_DtvMinBW(pstTbl->stBandWidth, &(pstDigital->Sbtvd.ucCurBW));
			pstDigital->Sbtvd.sCurTpInx ++;
		}
		else if (AL_CS_TYPE_DIGITAL == pstInfo->enType)
		{
			al_uint8 bMaxBw = 0;

			if (pstDigital->Sbtvd.ucCurBW != 0)
			{
				pstTbl = &(pstDigital->Sbtvd.pstAreaTable->pTPRegion_Area[pstDigital->Sbtvd.sCurSecInx]);

				tp_num = pstTbl->SectTPCount;
				AL_CS_DtvMaxBW(pstTbl->stBandWidth, &bMaxBw);

				if ((pstDigital->Sbtvd.ucCurBW < bMaxBw) &&
					(AL_SUCCESS == AL_CS_DtvNextBW(pstTbl->stBandWidth, &(pstDigital->Sbtvd.ucCurBW), 1)))
				{
					return AL_SUCCESS;
				}

				pstDigital->Sbtvd.sCurTpInx ++;

				if (pstDigital->Sbtvd.sCurTpInx >= tp_num)
				{
					if ((al_uint32)(pstDigital->Sbtvd.sCurSecInx + 1) > pstDigital->Sbtvd.uiSectionNum)
					{
						return AL_FAILURE;
					}

					++ pstDigital->Sbtvd.sCurSecInx;
					pstDigital->Sbtvd.sCurTpInx = 0;
				}
			}
			else
			{
			}
			pstTbl = &(pstDigital->Sbtvd.pstAreaTable->pTPRegion_Area[pstDigital->Sbtvd.sCurSecInx]);

			memset(pstTp, 0, sizeof(AL_TPSects_Info_st));

			pstTp->stBandWidth = pstTbl->stBandWidth;
			pstTp->StartFreq = pstTbl->StartFreq + pstTbl->stBandWidth.eBandWidth.BaseBandWidth * pstDigital->Sbtvd.sCurTpInx * 1000;
			pstTp->StartTpNum = pstTbl->StartTpNum + pstDigital->Sbtvd.sCurTpInx;
			pstTp->UHF_VHF = pstTbl->UHF_VHF;
			AL_CS_DtvMinBW(pstTbl->stBandWidth, &(pstDigital->Sbtvd.ucCurBW));
		}
#endif
	}
	else
	{

	}

	return AL_SUCCESS;
}
/*****************************************************************************
** FUNCTION : static AL_Return_t CS_DtvNextChannel(void* pdata, cs_msg_st* msg)
**
** DESCRIPTION :
**				Get information of next TP need to search
**
** PARAMETERS :
**				pdata - next TP information
**				msg - message type
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t CS_DtvNextChannel(void* pdata, cs_msg_st* msg)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
	digital_search_data_st* pstDigital = &(pstInfo->unScanData.digital);
	al_uint32 uiFrequence = 0;

	if (NULL == pdata)
	{
		return AL_FAILURE;
	}

	if (AL_SUCCESS != CS_DtvGetNextTp())
	{
		CS_SEND_MSG(AL_CS_MSG_TYPE_FINISHED, 0);
#ifdef CONFIG_DVB_SYSTEM_DVBT2_SUPPORT
		if ((pstDigital->enTunerType == TUNER_OFDM) && (pstDigital->Terr.TotalT2count != 0))
		{
			/* Free all T2 node */
			_AI_CS_FreeAllNode(pstDigital->Terr.pstT2List);

			pstDigital->Terr.pstT2List = NULL;
			pstDigital->Terr.TotalT2count = 0;
			pstDigital->Terr.CurT2Inx = 0;
			pstDigital->Terr.ScanMode = AL_SCAN_DVB_T_T2_DEFAULT_MODE;
		}
#endif
		return AL_FAILURE;
	}

	((MID_ScanParam_t *)pdata)->enType = pstDigital->enTunerType;

	if (pstDigital->enTunerType == TUNER_OFDM || pstDigital->enTunerType == TUNER_TDS_OFDM)
	{
		CS_DEBUG_MESSAGE("\nCONNECT TO TUNER-T\n");

		if (!(pstInfo->uiCapabilities & AL_CS_SUPPORT_NIT_FREQ_LIST_SCAN))
		{
#if defined CONFIG_DVB_SYSTEM
			if (((MID_ScanParam_t *) pdata)->u.ofdm.frequency != pstDigital->Terr.stInput.StartFreq)
			{
				#if 0//mark
				if (!(pstDigital->Terr.ScanMode & AL_SCAN_DVB_T_T2_SEPARATE_MODE))
				{
					pstInfo->stSearchInfo.u.dtv.usCurTpCnt ++;
				}
                #else
                if (!(pstDigital->Terr.ScanMode & AL_SCAN_SEPARATE_DVBT2)
                    && !(pstDigital->Terr.ScanMode & AL_SCAN_TOGETHER_DVBT2))
                {
                    pstInfo->stSearchInfo.u.dtv.usCurTpCnt ++;
                }
                #endif
			}
#elif (defined CONFIG_DTMB_SYSTEM)
			if (((MID_ScanParam_t *) pdata)->u.tdsofdm.frequency != pstDigital->Terr.stInput.StartFreq)
			{
				#if 0//mark
				if (!(pstDigital->Terr.ScanMode & AL_SCAN_DVB_T_T2_SEPARATE_MODE))
				{
					pstInfo->stSearchInfo.u.dtv.usCurTpCnt ++;
				}
                #else
                if (!(pstDigital->Terr.ScanMode & AL_SCAN_SEPARATE_DVBT2)
                    && !(pstDigital->Terr.ScanMode & AL_SCAN_TOGETHER_DVBT2))
                {
                    pstInfo->stSearchInfo.u.dtv.usCurTpCnt ++;
                }
                #endif
			}
#endif


#if (defined CONFIG_DVB_SYSTEM)
			((MID_ScanParam_t *) pdata)->u.ofdm.frequency = pstDigital->Terr.stInput.StartFreq;
			((MID_ScanParam_t *) pdata)->u.ofdm.bandwidth = pstDigital->Terr.ucCurBW;
#elif (defined CONFIG_DTMB_SYSTEM)
            ((MID_ScanParam_t *) pdata)->u.tdsofdm.frequency = pstDigital->Terr.stInput.StartFreq;
			((MID_ScanParam_t *) pdata)->u.tdsofdm.bandwidth = pstDigital->Terr.ucCurBW;
#endif
			pstInfo->stSearchInfo.uiCurBandwidth = pstDigital->Terr.ucCurBW;
			uiFrequence = pstDigital->Terr.stInput.StartFreq;

#ifdef CONFIG_DVB_SYSTEM_DVBT2_SUPPORT
            switch (pstDigital->Terr.ScanMode)
            {
                case AL_SCAN_ONLY_DVBT:
                case (AL_SCAN_ONLY_DVBT | AL_SCAN_DVB_T_T2_SEPARATE_MODE):
                case (AL_SCAN_ONLY_DVBT | AL_SCAN_DVB_T_T2_TOGETHER_MODE):
                    ((MID_ScanParam_t *) pdata)->u.ofdm.ScanMode = MID_SCAN_STATE_ONLY_DVBT;
                    break;
                case AL_SCAN_ONLY_DVBT2:
                case (AL_SCAN_ONLY_DVBT2 | AL_SCAN_DVB_T_T2_SEPARATE_MODE):
                case (AL_SCAN_ONLY_DVBT2 | AL_SCAN_DVB_T_T2_TOGETHER_MODE):
                    ((MID_ScanParam_t *) pdata)->u.ofdm.ScanMode = MID_SCAN_STATE_ONLY_DVBT2;
                    break;

                case AL_SCAN_DVB_T_T2_TOGETHER_MODE:
                case AL_SCAN_TOGETHER_DVBT|AL_SCAN_DVB_T_T2_TOGETHER_MODE:
                case AL_SCAN_TOGETHER_DVBT:
                    ((MID_ScanParam_t *) pdata)->u.ofdm.ScanMode = MID_SCAN_STATE_TOGETHER_DVBT;
                    break;
                case AL_SCAN_TOGETHER_DVBT2|AL_SCAN_DVB_T_T2_TOGETHER_MODE:
                case AL_SCAN_TOGETHER_DVBT2:
                    ((MID_ScanParam_t *) pdata)->u.ofdm.ScanMode = MID_SCAN_STATE_TOGETHER_DVBT2;
                    break;

                case AL_SCAN_DVB_T_T2_SEPARATE_MODE:
                case AL_SCAN_SEPARATE_DVBT|AL_SCAN_DVB_T_T2_SEPARATE_MODE:
                case AL_SCAN_SEPARATE_DVBT:
                    ((MID_ScanParam_t *) pdata)->u.ofdm.ScanMode = MID_SCAN_STATE_SEPARATE_DVBT;
                    break;
                case AL_SCAN_SEPARATE_DVBT2|AL_SCAN_DVB_T_T2_SEPARATE_MODE:
                case AL_SCAN_SEPARATE_DVBT2:
                    ((MID_ScanParam_t *) pdata)->u.ofdm.ScanMode = MID_SCAN_STATE_SEPARATE_DVBT2;
                    break;

                default:
                    ((MID_ScanParam_t *) pdata)->u.ofdm.ScanMode = MID_SCAN_STATE_ONLY_DVBT;
                    CS_ERROR_MESSAGE("=====scan mode error!=====\n");
                    break;
            }

            if (pstDigital->Terr.ScanMode & (AL_SCAN_SEPARATE_DVBT|AL_SCAN_SEPARATE_DVBT2))
            {
                if (pstDigital->Terr.ScanMode & AL_SCAN_SEPARATE_DVBT2)
                {
                    pstInfo->stSearchInfo.u.dtv.usCurTpCnt = pstDigital->Terr.stInput.StartTpNum;

                     pstInfo->stSearchInfo.u.dtv.uiProgress = \
                        (50+((pstDigital->Terr.CurT2Inx*1.0)/ pstDigital->Terr.TotalT2count)*50);
                }
                else
                {
                    pstInfo->stSearchInfo.u.dtv.uiProgress = \
                        (((pstInfo->stSearchInfo.u.dtv.usCurTpCnt*1.0)/ (pstInfo->stSearchInfo.u.dtv.usTotalTpNum + pstInfo->stSearchInfo.u.dtv.usTotalTpNum)) *100);
                }
            }
#else
            #ifdef CONFIG_DVB_SYSTEM
            ((MID_ScanParam_t *) pdata)->u.ofdm.ScanMode = MID_SCAN_STATE_ONLY_DVBT;
            #endif
#endif
		}
		else
		{
			al_uint8 bBandWidth = 0;
			AL_TPSects_Info_st *pstTerTp = pstDigital->Terr.pstCurTerTp;
#if defined CONFIG_DVB_SYSTEM
			((MID_ScanParam_t *) pdata)->u.ofdm.frequency = pstTerTp->StartFreq;
#elif defined CONFIG_DTMB_SYSTEM
            ((MID_ScanParam_t *) pdata)->u.tdsofdm.frequency = pstTerTp->StartFreq;
#endif
			AL_CS_DtvMaxBW(pstTerTp->stBandWidth, &bBandWidth);

#if defined CONFIG_DVB_SYSTEM
			((MID_ScanParam_t *) pdata)->u.ofdm.bandwidth = bBandWidth;
#elif defined CONFIG_DTMB_SYSTEM
            ((MID_ScanParam_t *) pdata)->u.tdsofdm.bandwidth = pstTerTp->StartFreq;
#endif
			pstDigital->Terr.ucCurBW = bBandWidth;
			pstInfo->stSearchInfo.uiCurBandwidth = bBandWidth;
			pstDigital->Terr.stInput.StartFreq = pstTerTp->StartFreq;
			uiFrequence = pstTerTp->StartFreq;
			pstInfo->stSearchInfo.u.dtv.usCurTpCnt ++;
		}
	}
	else if (pstDigital->enTunerType == TUNER_QAM)
	{
		CS_DEBUG_MESSAGE("\nCONNECT TO TUNER-C\n");
		cs_cable_tp_info_st* pstCblTp = pstDigital->Cable.pstCurCableTp;
		((MID_ScanParam_t *) pdata)->u.qam.frequency = pstCblTp->uiFrequence;
		((MID_ScanParam_t *) pdata)->u.qam.symbrate = pstCblTp->uiSymRate;
		((MID_ScanParam_t *) pdata)->u.qam.modulation = pstCblTp->enModulation;
		((MID_ScanParam_t *) pdata)->u.qam.network_id = pstCblTp->network_id;


		pstInfo->stSearchInfo.u.dtv.usCurTpCnt ++;

		uiFrequence = pstCblTp->uiFrequence;
	}
	else if (pstDigital->enTunerType == TUNER_QPSK)
	{
	#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
		CS_DEBUG_MESSAGE("CONNECT TO TUNER-S\n");
		cs_sate_tp_info_st* pstSateTp = pstDigital->Satellite.pstCurSateTp;
		Ant_TRANSPONDER_st CurTp;
		Ant_UsalsSetting_SatLocation_st SatLocal;
		AL_NetworkDetail_t stNetInfo;
		Ant_TRANSPONDER_st CurrTpInfo;
		UINT32 u32LNBFrequency = (pstSateTp->uiFrequence >> 16);

		AL_DB_QueryDetail(pstDigital->Satellite.hNet, &stNetInfo);

		// Freq Get from NIT is IF freq already.
		if (pstSateTp->uiFrequence <= 2150)
		{
			MID_SatCtrl_GetCurrentTpInfo(&CurrTpInfo);
			uiFrequence = MID_SatCtrl_GetTpFrequency(CurrTpInfo.usFreq>>16, pstSateTp->uiFrequence);
		}
		else
		{
		    CS_DEBUG_MESSAGE("pstSateTp->uiFrequence = 0x%x\n", pstSateTp->uiFrequence);
			if (0 == u32LNBFrequency)
			{
				u32LNBFrequency = MID_SatCtrl_GetLnbFreqFromDualLNB(pstSateTp->uiFrequence, MID_SatCtrl_LNBCtrlGetFreq());
				pstSateTp->uiFrequence |= (u32LNBFrequency << 16);
			}
		    CS_DEBUG_MESSAGE("pstSateTp->uiFrequence = 0x%x\n", pstSateTp->uiFrequence);
			pstSateTp->uiFrequence = MID_SatCtrl_GetIfFrequency(pstSateTp->uiFrequence);
			uiFrequence = MID_SatCtrl_GetTpFrequency(u32LNBFrequency,pstSateTp->uiFrequence);
		}

		((MID_ScanParam_t *) pdata)->u.qpsk.frequency = pstSateTp->uiFrequence;
		((MID_ScanParam_t *) pdata)->u.qpsk.symrate = pstSateTp->uiSymRate;
		((MID_ScanParam_t *) pdata)->u.qpsk.polarization = pstSateTp->polarization;
        if (pstInfo->uiCapabilities & AL_CS_SUPPORT_BLIND_SCAN_METHOD_2
            || pstInfo->uiCapabilities & AL_CS_SUPPORT_BLIND_SCAN_METHOD_3
            || (pstDigital->Satellite.stNITTpTbl != TP_LIST_INVALID_HDL
            && pstDigital->Satellite.stTpListHdl == pstDigital->Satellite.stNITTpTbl))
        {
            CS_DEBUG_MESSAGE("pstSateTp->fe_type = %d\n", pstSateTp->fe_type);
            if (pstSateTp->fe_type == FRONTEND_TYPE_DVBS2)
            {
                ((MID_ScanParam_t *) pdata)->u.qpsk.fe_type = FRONTEND_TYPE_DVBS2;
            }
            else
            {
                ((MID_ScanParam_t *) pdata)->u.qpsk.fe_type = FRONTEND_TYPE_QPSK;
            }
        }
        else
        {
            ((MID_ScanParam_t *) pdata)->u.qpsk.fe_type = g_DVBSX_NextScanMode;
        }
		g_CurPolar = pstSateTp->polarization;
		g_wLNBFreq = (uiFrequence & 0xFFFF0000)>>16;
		printf("\n**** %d g_wLNBFreq:0x%x ---- g_wLNBFreq:%d *****\n\n",__LINE__,g_wLNBFreq,(UINT32)g_wLNBFreq);
		MID_SatCtrl_CBand_DualLNBSetType(g_wLNBFreq);

		pstInfo->stSearchInfo.u.dtv.usCurTpCnt ++;
		CurTp.usFreq = uiFrequence;
		CurTp.usSymRate = pstSateTp->uiSymRate;
		CurTp.u8Polar = pstSateTp->polarization;
        if (pstInfo->uiCapabilities & AL_CS_SUPPORT_BLIND_SCAN_METHOD_2
            || pstInfo->uiCapabilities & AL_CS_SUPPORT_BLIND_SCAN_METHOD_3
            || (pstDigital->Satellite.stNITTpTbl != TP_LIST_INVALID_HDL
            && pstDigital->Satellite.stTpListHdl == pstDigital->Satellite.stNITTpTbl))//Current scan NIT TP List
        {
            if (pstSateTp->fe_type == FRONTEND_TYPE_DVBS2)
            {
                CurTp.u8TpType = EDVB_DELIVER_TYPE_S2;
            }
            else
            {
                CurTp.u8TpType = EDVB_DELIVER_TYPE_S;
            }
        }
		MID_SatCtrl_SetCurrentSatelliteInfo(SATINFO_ALL, 0, &(stNetInfo.stDVBSNetwork));
		SatLocal.u32SatLongitudeDirection = stNetInfo.stDVBSNetwork.ucEastWest;
		SatLocal.u32SatLongitude = stNetInfo.stDVBSNetwork.iLongitude;
		MID_SatCtrl_SetCurrentTpInfo(TPINFO_ALL,0,&CurTp);
		MID_SatCtrl_SetUsalsLocation(MOTORSEL_SAT, NULL, &SatLocal);
		MID_SatCtrl_LNBCtrlSetFreq(stNetInfo.stDVBSNetwork.uiLNBFreq);
	#endif
	}
	else if (pstDigital->enTunerType == TUNER_BST_OFDM)
	{
		CS_DEBUG_MESSAGE("\nCONNECT TO SBTVD\n");
		if (((MID_ScanParam_t *) pdata)->u.bstofdm.frequency != pstDigital->Sbtvd.stInput.StartFreq)
		{
			pstInfo->stSearchInfo.u.dtv.usCurTpCnt ++;
		}

		((MID_ScanParam_t *) pdata)->u.bstofdm.frequency = pstDigital->Sbtvd.stInput.StartFreq;
		((MID_ScanParam_t *) pdata)->u.bstofdm.bandwidth = pstDigital->Sbtvd.ucCurBW;

		pstInfo->stSearchInfo.uiCurBandwidth = pstDigital->Sbtvd.ucCurBW;

		uiFrequence = pstDigital->Sbtvd.stInput.StartFreq;
	}
	else
	{

	}

	if (pstDigital->enTunerType == TUNER_QPSK)
	{
		pstInfo->stSearchInfo.uiCurFreq = (uiFrequence&0xffff);
	}
	else
	{
		pstInfo->stSearchInfo.uiCurFreq = uiFrequence;
	}

	CS_SEND_MSG(AL_CS_MSG_TYPE_NEW_CH, 0);

	return AL_SUCCESS;
}

/*****************************************************************************
** FUNCTION : static AL_Return_t CS_DtvSaveService(void* pdata, cs_msg_st* msg)
**
** DESCRIPTION :
**				Save the current service information to database
**
** PARAMETERS :
**				pdata - the information will be saved
**				msg - message type
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t CS_DtvSaveService(void* pdata, al_uint32  eCallbackType, cs_msg_st* msg)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
	digital_search_data_st* pstDigital = &(pstInfo->unScanData.digital);
	AL_Return_t ret = AL_SUCCESS;
	void* pstScanInfo = NULL;
	AL_CableTP_Info_st stCableInfo;
	AL_SateTP_Info_st stSateInfo;
	//AL_DB_EDBType_t eDBType = AL_DBTYPE_MAX;

	CS_DEBUG_MESSAGE("Enter %s\n",__FUNCTION__);

	if (NULL == pdata)
	{
		CS_DEBUG_MESSAGE("Invalid data!\n");
		return AL_FAILURE;
	}

    #if 0  /*remove to app_scan_save.c. for diffrent customer's spec.*/
	/* discard those services which use PcrPid == 0x1FFF */
	if (al_false == AL_Event_GetEDTGSupport() && ((MID_ScanDVBServiceInfo_t*)(pdata))->usPcrPid == 0x1FFF)
	{
		CS_DEBUG_MESSAGE("Pcrpid is 0x1FFF no need to save to database \n");
		ret = AL_FAILURE;
		return ret;
	}
    #endif

	if (NULL != pstInfo->pfSave)
	{
		if (pstDigital->enTunerType == TUNER_OFDM || pstDigital->enTunerType == TUNER_TDS_OFDM)
		{
			pstScanInfo = &(pstDigital->Terr.stInput);
			//eDBType = AL_DBTYPE_DVB_T;
		}
		else if (pstDigital->enTunerType == TUNER_QAM)
		{
			ServiceNetworkId = ((MID_ScanDVBServiceInfo_t*)pdata)->usNetId;
			if (((pstDigital->Cable.pstNetworkScanInfo.uiDVBCSearchMode == AL_DVBC_SEARCHMODE_QUICK_NETWORK)
				|| (pstDigital->Cable.pstNetworkScanInfo.uiDVBCSearchMode == AL_DVBC_SEARCHMODE_FULL_NETWORK))
				&& (pstDigital->Cable.pstNetworkScanInfo.uiNetworkIdAutoEn == al_false)
				&& ((((MID_ScanDVBServiceInfo_t*)pdata)->usNetId != pstDigital->Cable.pstCurCableTp->network_id)
				&& (pstDigital->Cable.pstCurCableTp->network_id != 65535) && (pstDigital->Cable.pstCurCableTp->network_id != 0)))
			{
				/* network id does not match */
				CS_DEBUG_MESSAGE("NetworkId don't match, No Save,  uiDVBCSearchMode: %d, uiNetworkIdAutoEn: %d, usNetId: %d,%d\n",
				pstDigital->Cable.pstNetworkScanInfo.uiDVBCSearchMode, pstDigital->Cable.pstNetworkScanInfo.uiNetworkIdAutoEn, ((MID_ScanDVBServiceInfo_t*)pdata)->usNetId, pstDigital->Cable.pstCurCableTp->network_id);
				if (pstDigital->Cable.pstNetworkScanInfo.uiFreqAutoEn == al_false)
				{
					NetworkScanNeedAbortScan = al_true;
				}
				return AL_FAILURE;
			}
			memset(&stCableInfo, 0, sizeof(stCableInfo));
			stCableInfo.uiFrequency = pstDigital->Cable.pstCurCableTp->uiFrequence;
			stCableInfo.uiSymbRate = pstDigital->Cable.pstCurCableTp->uiSymRate;
			stCableInfo.usModulation = pstDigital->Cable.pstCurCableTp->enModulation;
			pstScanInfo = &stCableInfo;
			//eDBType = AL_DBTYPE_DVB_C;
		}
		else if (pstDigital->enTunerType == TUNER_QPSK)
		{
			memset(&stSateInfo, 0, sizeof(stSateInfo));
			stSateInfo.uiPolarization = pstDigital->Satellite.pstCurSateTp->polarization;
			stSateInfo.uiFrequency = pstDigital->Satellite.pstCurSateTp->uiFrequence;
			stSateInfo.uiSymbRate = pstDigital->Satellite.pstCurSateTp->uiSymRate;
            stSateInfo.uiFEType = pstDigital->Satellite.pstCurSateTp->fe_type;
			stSateInfo.hNet = pstDigital->Satellite.hNet;
			stSateInfo.modulation = pstDigital->Satellite.pstCurSateTp->modulation;
			stSateInfo.ucCode_rate = pstDigital->Satellite.pstCurSateTp->ucCode_rate;
			stSateInfo.ucSpec_inver = pstDigital->Satellite.pstCurSateTp->ucSpec_inver;
			pstScanInfo = &stSateInfo;
			//eDBType = AL_DBTYPE_DVB_S;
		}
		else if (pstDigital->enTunerType == TUNER_BST_OFDM)
		{
		#ifdef CONFIG_ISDB_SYSTEM
			//eDBType = AL_DBTYPE_DVB_SBTVD;
		#endif
			pstScanInfo = &(pstDigital->Sbtvd.stInput);
		}
		else
		{

		}
		/* check if it's necessary to save scramble serivce */
		if (pstInfo->uiCapabilities & AL_CS_FILTER_SCRAMBLE_SERVICE)
		{
			if (((MID_ScanDVBServiceInfo_t*)pdata)->ucServiceFlag & SERVICE_SCRAMBLED)
			{
				return AL_FAILURE;
			}
		}

		if (AL_SUCCESS != (ret = pstInfo->pfSave(pstScanInfo, (void*)&(pstInfo->stSearchInfo), pdata)))
		{
			CS_DEBUG_MESSAGE("Save finish unsuccessfully!\n");
			return ret;
		}

	}

#ifdef NIT_SCAN_SUPPORT
	if (MID_ScanGetNitScanFlag() == TRUE)
	{
		al_uint16 TotalChannel = 0;

		TotalChannel = pstInfo->stSearchInfo.usTVCnt + pstInfo->stSearchInfo.u.dtv.usDataServCnt + pstInfo->stSearchInfo.u.dtv.usRadioCnt;
		if (TotalChannel%10 == 0)
		{
			CS_SEND_MSG(AL_CS_MSG_TYPE_LOCK_CH, 0) ;
		}
	}
	else
#endif
#ifdef CONFIG_SUPPORT_FAST_SCANNING
	if (pstInfo->uiCapabilities & AL_CS_SUPPORT_M7_FAST_SCAN)
	{
#if 0
		al_uint16 TotalChannel = 0;

		TotalChannel = pstInfo->stSearchInfo.usTVCnt + pstInfo->stSearchInfo.u.dtv.usDataServCnt + pstInfo->stSearchInfo.u.dtv.usRadioCnt;
		if (TotalChannel % 100 == 0)
		{
			CS_SEND_MSG(AL_CS_MSG_TYPE_LOCK_CH, 0) ;
		}
#endif
	}
	else
#endif

	{
		CS_SEND_MSG(AL_CS_MSG_TYPE_LOCK_CH, 0) ;
	}

	CS_DEBUG_MESSAGE("Exit %s\n",__FUNCTION__);

	return ret;
}

static AL_Return_t CS_GetFreqTblFromNIT(MID_ScanParam_t* pstScanInfo)
{
	cs_info_st* pstInfo = GET_CS_INFO();
	digital_search_data_st* pstDigital = &pstInfo->unScanData.digital;

	CS_DEBUG_MESSAGE("Enter %s\n",__FUNCTION__);

	if (pstInfo->unScanData.digital.enTunerType == TUNER_QAM)
	{
		cs_cable_tp_info_st* pstCableTpInfo = NULL;
		cs_cable_tp_info_st stCableTp;

		if (((pstDigital->Cable.pstNetworkScanInfo.uiDVBCSearchMode == AL_DVBC_SEARCHMODE_QUICK_NETWORK)
			|| (pstDigital->Cable.pstNetworkScanInfo.uiDVBCSearchMode == AL_DVBC_SEARCHMODE_FULL_NETWORK))
			&& (pstDigital->Cable.pstNetworkScanInfo.uiNetworkIdAutoEn == al_false)
			&& (((ServiceNetworkId != pstDigital->Cable.pstCurCableTp->network_id))
			&& (pstDigital->Cable.pstCurCableTp->network_id != 65535) && (pstDigital->Cable.pstCurCableTp->network_id != 0)))
		{
			return AL_FAILURE;
		}
		if (CABLE_GET_NIT_DETECT == pstInfo->ucGotNITFlag)
		{
			if (AL_SUCCESS != AI_TpListInit(&pstDigital->Cable.stNITTpTbl))
			{
				CS_DEBUG_MESSAGE("prepare NIT TP list unsuccessfully!\n");
				return AL_FAILURE;
			}

			pstInfo->ucGotNITFlag = CABLE_GET_NIT_PARSE;
		}
		pstInfo->ucHasGetFreFromNIT = al_true;
		CS_DEBUG_MESSAGE("Get new TP %d from NIT\n",pstScanInfo->u.qam.frequency);

		do {
			/* check current frequence has been searched or not in default TP table */
			AI_TpListGetNode(pstDigital->Cable.stTpListHdl, (void**)&pstCableTpInfo);
			for ( ; pstCableTpInfo != pstDigital->Cable.pstCurCableTp; )
			{
				if (pstCableTpInfo->uiFrequence == pstScanInfo->u.qam.frequency)
				{
					CS_DEBUG_MESSAGE("this frequence has been scaned\n");
					return AL_SUCCESS;
				}

				AI_TpListGetNode(pstDigital->Cable.stTpListHdl, (void**)&pstCableTpInfo);
			}

			if (pstCableTpInfo->uiFrequence == pstScanInfo->u.qam.frequency)
			{
				return AL_SUCCESS;
			}
		} while(0);

		do {
			/* check current frequence has been added in NIT Tp list or not */
			pstCableTpInfo = NULL;
			AI_TpListGetNode(pstDigital->Cable.stNITTpTbl, (void**)&pstCableTpInfo);
			for ( ; NULL != pstCableTpInfo; )
			{
				if (pstCableTpInfo->uiFrequence == pstScanInfo->u.qam.frequency)
				{
					CS_DEBUG_MESSAGE("this frequence has been added\n");
					return AL_SUCCESS;
				}

				AI_TpListGetNode(pstDigital->Cable.stNITTpTbl, (void**)&pstCableTpInfo);
			}
		} while(0);

		if ((pstScanInfo->u.qam.frequency <=  pstInfo->stSearchInfo.uiCurFreq + 2000) && (pstScanInfo->u.qam.frequency >=  pstInfo->stSearchInfo.uiCurFreq - 2000))
		{
			CS_DEBUG_MESSAGE("this frequence same as current freq, frequency: %d, uiCurFreq: %d\n", pstScanInfo->u.qam.frequency, pstInfo->stSearchInfo.uiCurFreq);
			return AL_SUCCESS;
		}

		memset(&stCableTp, 0, sizeof(stCableTp));
		stCableTp.uiFrequence = pstScanInfo->u.qam.frequency;
		stCableTp.uiSymRate = pstScanInfo->u.qam.symbrate;
        if (pstScanInfo->u.qam.modulation >= AL_QAM_MAX)
        {
            stCableTp.enModulation = AL_QAM_MAX;
        }
        else
        {
		    stCableTp.enModulation = pstScanInfo->u.qam.modulation;
        }
		stCableTp.network_id = pstDigital->Cable.pstCurCableTp->network_id;
		AI_TpListAddNode(pstDigital->Cable.stNITTpTbl, &stCableTp, sizeof(stCableTp));

		CS_DEBUG_MESSAGE("Exit %s\n",__FUNCTION__);
	}
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
	else if (pstInfo->unScanData.digital.enTunerType == TUNER_QPSK)
	{
		cs_sate_tp_info_st* pstSateTpInfo = NULL;
		cs_sate_tp_info_st stSateTp;

		if (((pstScanInfo->u.qpsk.frequency < 1060000) ||
			 (pstScanInfo->u.qpsk.frequency > 1280000)) &&
			((pstScanInfo->u.qpsk.frequency < 95000) ||
			 (pstScanInfo->u.qpsk.frequency > 215000)))
		{
			CS_DEBUG_MESSAGE("No Freq is parsed out!\n");
			return AL_FAILURE;
		}

		if ((CABLE_GET_NIT_DETECT == pstInfo->ucGotNITFlag) &&
			(pstDigital->Satellite.stNITTpTbl == TP_LIST_INVALID_HDL))
		{
			if (AL_SUCCESS != AI_TpListInit(&pstDigital->Satellite.stNITTpTbl))
			{
				CS_DEBUG_MESSAGE("prepare NIT TP list unsuccessfully!\n");
				return AL_FAILURE;
			}

			pstInfo->ucGotNITFlag = CABLE_GET_NIT_PARSE;
		}

		CS_DEBUG_MESSAGE("Get new TP (%d,%d,%d) fe_type = %d from NIT\n", pstScanInfo->u.qpsk.frequency,
			pstScanInfo->u.qpsk.symrate, pstScanInfo->u.qpsk.polarization, pstScanInfo->u.qpsk.fe_type);
		pstScanInfo->u.qpsk.frequency = pstScanInfo->u.qpsk.frequency/100;
		pstScanInfo->u.qpsk.symrate = pstScanInfo->u.qpsk.symrate/10;
        if ((pstScanInfo->u.qpsk.polarization == 0) || (pstScanInfo->u.qpsk.polarization == 2))
    	{
    		pstScanInfo->u.qpsk.polarization = 1; //H
    	}
    	else if ((pstScanInfo->u.qpsk.polarization == 1) || (pstScanInfo->u.qpsk.polarization == 3))
    	{
    		pstScanInfo->u.qpsk.polarization = 0; //V
    	}

		pstSateTpInfo = NULL;
		do {
			/* check current frequence has been searched or not in default TP table */
			AI_TpListGetNode(pstDigital->Satellite.stTpListHdl, (void**)&pstSateTpInfo);
			for ( ; (pstSateTpInfo != NULL) && (pstSateTpInfo != pstDigital->Satellite.pstCurSateTp); )
			{
				if ((DIFFER((pstSateTpInfo->uiFrequence&0xffff), pstScanInfo->u.qpsk.frequency) <= 3) &&
					(pstSateTpInfo->uiSymRate == pstScanInfo->u.qpsk.symrate) &&
					(pstSateTpInfo->polarization == pstScanInfo->u.qpsk.polarization))
				{
					CS_DEBUG_MESSAGE("this frequence has been scaned\n");
					return AL_SUCCESS;
				}

				AI_TpListGetNode(pstDigital->Satellite.stTpListHdl, (void**)&pstSateTpInfo);
			}
		} while(0);

		if ((pstSateTpInfo != NULL) && (DIFFER((pstSateTpInfo->uiFrequence&0xffff), pstScanInfo->u.qpsk.frequency) <= 3)
				&& (pstSateTpInfo->polarization == pstScanInfo->u.qpsk.polarization)
				&& (pstSateTpInfo->uiSymRate == pstScanInfo->u.qpsk.symrate))
		{
			CS_DEBUG_MESSAGE("this frequence same as current freq\n");
			return AL_SUCCESS;
		}

		pstSateTpInfo = pstDigital->Satellite.pstCurSateTp;
		do {
			/* check current frequence  in default TP table */
			AI_TpListGetNode(pstDigital->Satellite.stTpListHdl, (void**)&pstSateTpInfo);
			for ( ; pstSateTpInfo != NULL; )
			{
				if ((DIFFER((pstSateTpInfo->uiFrequence&0xffff), pstScanInfo->u.qpsk.frequency) <= 3) &&
					(pstSateTpInfo->uiSymRate == pstScanInfo->u.qpsk.symrate) &&
					(pstSateTpInfo->polarization == pstScanInfo->u.qpsk.polarization))
				{
					CS_DEBUG_MESSAGE("Delete this TP from default table.\n");
					AI_TpListDeleteOneNode(pstDigital->Satellite.stTpListHdl,(void**)&pstSateTpInfo);
					if ((g_DVBSX_CurrentFeType == AL_CS_DVBSX_S_TO_S2 && g_DVBSX_NextScanMode == FRONTEND_TYPE_QPSK)
						|| (g_DVBSX_CurrentFeType == AL_CS_DVBSX_S2_TO_S && g_DVBSX_NextScanMode == FRONTEND_TYPE_DVBS2))
					{
						pstInfo->stSearchInfo.u.dtv.usTotalTpNum -= 2;
					}
					else
					{
						pstInfo->stSearchInfo.u.dtv.usTotalTpNum--;
					}
					break;
				}
				AI_TpListGetNode(pstDigital->Satellite.stTpListHdl, (void**)&pstSateTpInfo);
			}
		} while(0);

#if 1
		do {
			/* check current frequence has been added in NIT Tp list or not */
			pstSateTpInfo = NULL;
			AI_TpListGetNode(pstDigital->Satellite.stNITTpTbl, (void**)&pstSateTpInfo);
			for ( ; NULL != pstSateTpInfo; )
			{
				if (((pstSateTpInfo->uiFrequence&0xffff) == pstScanInfo->u.qpsk.frequency) &&
					(pstSateTpInfo->uiSymRate == pstScanInfo->u.qpsk.symrate) &&
					(pstSateTpInfo->polarization == pstScanInfo->u.qpsk.polarization))
				{
					CS_DEBUG_MESSAGE("this frequence has been added\n");
					return AL_SUCCESS;
				}

				AI_TpListGetNode(pstDigital->Satellite.stNITTpTbl, (void**)&pstSateTpInfo);
			}
		} while(0);
#endif

		memset(&stSateTp, 0, sizeof(stSateTp));
		stSateTp.uiFrequence = pstScanInfo->u.qpsk.frequency;
		if (stSateTp.uiFrequence > 2150)
		{
			stSateTp.uiFrequence |= (MID_SatCtrl_GetLnbFreqFromDualLNB(stSateTp.uiFrequence, MID_SatCtrl_LNBCtrlGetFreq()) << 16);
		}
		stSateTp.uiSymRate = pstScanInfo->u.qpsk.symrate;
		stSateTp.polarization = pstScanInfo->u.qpsk.polarization;
		stSateTp.fe_type = (0 == pstScanInfo->u.qpsk.fe_type ? FRONTEND_TYPE_QPSK : FRONTEND_TYPE_DVBS2);

		AI_TpListAddNode(pstDigital->Satellite.stNITTpTbl, &stSateTp, sizeof(stSateTp));

		CS_DEBUG_MESSAGE("Exit %s\n", __FUNCTION__);
	}
#endif
	return AL_SUCCESS;
}

static void CS_ResetScanTbl(void)
{
	cs_info_st* pstInfo = GET_CS_INFO();
	digital_search_data_st* pstDigital = &pstInfo->unScanData.digital;
	al_uint32 uiCounter = 0;
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
	al_uint32 uiTpFromNITCounter = 0;
#endif

	if (pstDigital->enTunerType == TUNER_QAM)
	{
		cs_cable_tp_info_st* pstCableTpInfo = NULL;
		pstDigital->Cable.stTpListHdl = pstDigital->Cable.stNITTpTbl;
		pstDigital->Cable.pstCurCableTp = NULL;

		for (;;++ uiCounter)
		{
			AI_TpListGetNode(pstDigital->Cable.stTpListHdl, (void**)&pstCableTpInfo);
			if (NULL == pstCableTpInfo)
			{
				break;
			}
		}

		/* so as to let progress of UI more smoother */
		pstInfo->stSearchInfo.u.dtv.usTotalTpNum = uiCounter + pstInfo->stSearchInfo.u.dtv.usCurTpCnt;
		pstInfo->ucGotNITFlag = CABLE_GET_NIT_STOP;
	}
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
	else if (pstDigital->enTunerType == TUNER_QPSK)
	{
		cs_sate_tp_info_st* pstSateTpInfo = NULL;
		#if 0
		pstDigital->Satellite.stTpListHdl = pstDigital->Satellite.stNITTpTbl;
		pstDigital->Satellite.pstCurSateTp = NULL;
		#endif

		pstSateTpInfo = pstDigital->Satellite.pstCurSateTp;
		for (;;++ uiCounter)
		{
			AI_TpListGetNode(pstDigital->Satellite.stTpListHdl, (void**)&pstSateTpInfo);
			if (NULL == pstSateTpInfo)
			{
				break;
			}
		}

		pstSateTpInfo = NULL;
		for (;;++ uiTpFromNITCounter)
		{
			AI_TpListGetNode(pstDigital->Satellite.stNITTpTbl, (void**)&pstSateTpInfo);
			if (NULL == pstSateTpInfo)
			{
				break;
			}
		}
        #if 0
        if (!(pstInfo->uiCapabilities & AL_CS_SUPPORT_BLIND_SCAN_METHOD_2 || pstInfo->uiCapabilities & AL_CS_SUPPORT_BLIND_SCAN_METHOD_3)
            &&(pstInfo->unScanData.digital.Satellite.pstCurSateTp->fe_type == AL_CS_DVBSX_S2_TO_S
                || pstInfo->unScanData.digital.Satellite.pstCurSateTp->fe_type == AL_CS_DVBSX_S_TO_S2))
		{
			if ((g_DVBSX_CurrentFeType == AL_CS_DVBSX_S_TO_S2 && g_DVBSX_NextScanMode == FRONTEND_TYPE_QPSK)
				|| (g_DVBSX_CurrentFeType == AL_CS_DVBSX_S2_TO_S && g_DVBSX_NextScanMode == FRONTEND_TYPE_DVBS2))
			{
				uiCounter += pstInfo->stSearchInfo.u.dtv.usTotalTpNum / 2;
			}
        }
        #endif
		pstInfo->stSearchInfo.u.dtv.usTotalTpNum += uiTpFromNITCounter;
		pstInfo->ucGotNITFlag = CABLE_GET_NIT_STOP;

	#if !(defined(SUPPORT_DVBS_LCN) || defined(SUPPORT_ASTRA_LCN))
		MID_ScanCleanNitCap();
	#endif
	}
#endif
}

//zhongbaoxing added @20130307 for UPC sepc ---
#endif

#if defined(SUPPORT_TRD) && defined (CONFIG_SUPPORT_DTG_CERTIFICATION)
/* to check Target Region Name w/ DTG specified rule */
static void CS_scanCheckStringForDTG(al_uint8 *pucString, al_uint32 dwlen)
{
	al_uint32 len = 0;

	if (AL_Event_GetEDTGSupport() == al_true)
	{
		if (dwlen>0)
		{
			len = MID_CmnDecompressString(pucString, dwlen);
			if (len >= MAX_TRDNAME_LEN)
			{
				CS_ERROR_MESSAGE("\n\nBIG ERROR!! target region name is not correct!!!maybe mem overlap \n\n");
			}
			if (len > dwlen)
			{
				dwlen = len;
			}
			MID_CmnTransStrWithSpeciChar(pucString, dwlen);
			MID_CmnTransStrWithoutControlChar(pucString, dwlen);
		}

		if (dwlen > 0)
		{
			MID_CmnTransStrWith00(pucString,  dwlen);
		}

		if (dwlen > 0)
		{
			MID_CmnTransStrWithoutSpeciChar(pucString,  dwlen);
		}

		if (dwlen > 0)
		{
			MID_CmnTransStrWithoutNewline(pucString,  dwlen);
		}
	}
}
#endif

#ifdef CONFIG_DTV_SUPPORT
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
#define SAT_LOST_TP_MAX_TRY_COUNT		(10)
UINT32 g_satLostTpTryCount = 0;
//extern UINT32 g_u32BSCapabilities;

static AL_Return_t CS_DtvBlindSearchAddLostTp(void* pParam, al_uint16 usLNBFreq, al_bool tryTP)
{
	// Add lost TP info
	CS_DEBUG_MESSAGE("\n%s %d============================\n", __FUNCTION__, __LINE__);
	al_uint32 uiFrequence;
	cs_sate_tp_info_st stSatTpInfo;
	cs_info_st* pstInfo =  GET_CS_INFO();
	if (TP_LIST_INVALID_HDL == g_pSateLostTpInfo)
	{
		AI_TpListInit(&g_pSateLostTpInfo);
	}

	uiFrequence = ((MID_ScanParam_t *) pParam)->u.qpsk.frequency;
	stSatTpInfo.uiFrequence = CS_DTV_GetTpFrequency(usLNBFreq, uiFrequence);
	stSatTpInfo.uiSymRate = ((MID_ScanParam_t *) pParam)->u.qpsk.symrate;
	stSatTpInfo.fe_type = ((MID_ScanParam_t *) pParam)->u.qpsk.fe_type;
	stSatTpInfo.polarization = ((MID_ScanParam_t *) pParam)->u.qpsk.polarization;
    stSatTpInfo.isTry = tryTP;
	if (AL_SUCCESS != AI_TpListAddNode(g_pSateLostTpInfo, &stSatTpInfo, sizeof(cs_sate_tp_info_st)))
	{
		CS_ERROR_MESSAGE("%s Fail\n",__FUNCTION__);
	}
	else
	{
		pstInfo->stSearchInfo.u.dtv.usTotalTpNum++;
	}
	printf("[%s:%d] g_pSateLostTpInfo 0x%x++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n",__FUNCTION__,__LINE__,g_pSateLostTpInfo);

	cs_sate_tp_info_st *pstSatTpInfo = NULL;
	TpListHdl_st pSateLostTpInfo = g_pSateLostTpInfo;
	while (AI_TpListGetNode(pSateLostTpInfo, (void **)&pstSatTpInfo) == AL_SUCCESS)
	{
	}
	g_pstSatLostCurTpInfo = NULL;
	return AL_SUCCESS;
}

static AL_Return_t CS_DtvGetBSLostTpConnect(void* pParam, cs_sate_tp_info_st* pstParam)
{
	CS_DEBUG_MESSAGE("CONNECT TO TUNER-S\n");
	cs_info_st* pstInfo =  GET_CS_INFO();
	digital_search_data_st* pstDigital = &(pstInfo->unScanData.digital);
	cs_sate_tp_info_st* pstSateTp = pstParam;
	Ant_TRANSPONDER_st CurTp;
	Ant_UsalsSetting_SatLocation_st SatLocal;
	AL_NetworkDetail_t stNetInfo;
	Ant_TRANSPONDER_st CurrTpInfo;
	al_uint32 uiFrequence = 0;
	UINT32 u32LNBFrequency = (pstSateTp->uiFrequence >> 16);

	AL_DB_QueryDetail(pstDigital->Satellite.hNet, &stNetInfo);

	// Freq Get from NIT is IF freq already.
	if (pstSateTp->uiFrequence <= 2150)
	{
		MID_SatCtrl_GetCurrentTpInfo(&CurrTpInfo);
		uiFrequence = MID_SatCtrl_GetTpFrequency(CurrTpInfo.usFreq>>16, pstSateTp->uiFrequence);
	}
	else
	{
		CS_DEBUG_MESSAGE("pstSateTp->uiFrequence = 0x%x\n", pstSateTp->uiFrequence);
		if (0 == u32LNBFrequency)
		{
			u32LNBFrequency = MID_SatCtrl_GetLnbFreqFromDualLNB(pstSateTp->uiFrequence, MID_SatCtrl_LNBCtrlGetFreq());
			pstSateTp->uiFrequence |= (u32LNBFrequency << 16);
		}
		CS_DEBUG_MESSAGE("pstSateTp->uiFrequence = 0x%x\n", pstSateTp->uiFrequence);
		pstSateTp->uiFrequence = MID_SatCtrl_GetIfFrequency(pstSateTp->uiFrequence);
		uiFrequence = MID_SatCtrl_GetTpFrequency(u32LNBFrequency,pstSateTp->uiFrequence);
	}

	((MID_ScanParam_t *) pParam)->u.qpsk.frequency = pstSateTp->uiFrequence;
	((MID_ScanParam_t *) pParam)->u.qpsk.symrate = pstSateTp->uiSymRate;
	((MID_ScanParam_t *) pParam)->u.qpsk.polarization = pstSateTp->polarization;
	if (pstInfo->uiCapabilities & AL_CS_SUPPORT_BLIND_SCAN_METHOD_3)
	{
		if (pstSateTp->fe_type == FRONTEND_TYPE_DVBS2)
		{
			((MID_ScanParam_t *) pParam)->u.qpsk.fe_type = FRONTEND_TYPE_DVBS2;
		}
		else
		{
			((MID_ScanParam_t *) pParam)->u.qpsk.fe_type = FRONTEND_TYPE_QPSK;
		}
	}

	g_CurPolar = pstSateTp->polarization;
	g_wLNBFreq = (uiFrequence & 0xFFFF0000)>>16;
	MID_SatCtrl_CBand_DualLNBSetType(g_wLNBFreq);

	pstInfo->stSearchInfo.u.dtv.usCurTpCnt ++;
	CurTp.usFreq = uiFrequence;
	CurTp.usSymRate = pstSateTp->uiSymRate;
	CurTp.u8Polar = pstSateTp->polarization;
	if (pstInfo->uiCapabilities & AL_CS_SUPPORT_BLIND_SCAN_METHOD_2
		|| pstInfo->uiCapabilities & AL_CS_SUPPORT_BLIND_SCAN_METHOD_3)
	{
		if (pstSateTp->fe_type == FRONTEND_TYPE_DVBS2)
		{
			CurTp.u8TpType = EDVB_DELIVER_TYPE_S2;
		}
		else
		{
			CurTp.u8TpType = EDVB_DELIVER_TYPE_S;
		}
	}
	MID_SatCtrl_SetCurrentSatelliteInfo(SATINFO_ALL, 0, &(stNetInfo.stDVBSNetwork));
	SatLocal.u32SatLongitudeDirection = stNetInfo.stDVBSNetwork.ucEastWest;
	SatLocal.u32SatLongitude = stNetInfo.stDVBSNetwork.iLongitude;
	MID_SatCtrl_SetCurrentTpInfo(TPINFO_ALL,0,&CurTp);
	MID_SatCtrl_SetUsalsLocation(MOTORSEL_SAT, NULL, &SatLocal);
	MID_SatCtrl_LNBCtrlSetFreq(stNetInfo.stDVBSNetwork.uiLNBFreq);

	return AL_SUCCESS;
}

static AL_Return_t CS_DtvGetBSNextLostTp(void* pParam)
{
	CS_DEBUG_MESSAGE("%s %d\n", __FUNCTION__, __LINE__);
	AL_Return_t ret = AL_FAILURE;
	cs_info_st* pstInfo =  GET_CS_INFO();

	//printf("[%s:%d] g_pSateLostTpInfo 0x%x++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n",__FUNCTION__,__LINE__,g_pSateLostTpInfo);
	if (g_pSateLostTpInfo == TP_LIST_INVALID_HDL)
	{
		//printf("[%s:%d] +++++++++++++++++++++++++++++\n",__FUNCTION__,__LINE__);
		return AL_FAILURE;
	}

	pstInfo->stSearchInfo.u.dtv.usCurTpCnt++;
	g_satLostTpTryCount = 0;
	TpListHdl_st pSateLostTpInfo = g_pSateLostTpInfo;
	ret = AI_TpListGetNode(pSateLostTpInfo, (void **)&g_pstSatLostCurTpInfo);
	//printf("[%s:%d] g_pSateLostTpInfo 0x%x++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n",__FUNCTION__,__LINE__,g_pSateLostTpInfo);
	if (AL_SUCCESS == ret)
	{
		CS_DtvGetBSLostTpConnect(pParam, g_pstSatLostCurTpInfo);
	}
	else
	{
		AI_TpListFree(g_pSateLostTpInfo);
		g_pSateLostTpInfo = TP_LIST_INVALID_HDL;
	}

	return ret;
}

#define abs(A)  ((A) < (0) ? (-(A)):(A))
static AL_Return_t CS_DtvBSLostTpTry(void* pParam)
{
	CS_DEBUG_MESSAGE("\n============g_satLostTpTryCount=%d================\n", g_satLostTpTryCount);
	AL_Return_t ret = AL_FAILURE;
	double try_table[] = {0.25, -0.25, 0.5, -0.5, 1, -1, -3, -5, -9, 9};
	cs_sate_tp_info_st tpInfo = *g_pstSatLostCurTpInfo;

	if (!g_pstSatLostCurTpInfo->isTry)
	{
		return AL_FAILURE;
	}

	if (g_satLostTpTryCount < sizeof(try_table)/sizeof(try_table[0]))
	{
		printf("[%s:%d] g_satLostTpTryCount ===================== %d\n",__FUNCTION__,__LINE__,g_satLostTpTryCount);
		ret = AL_SUCCESS;
		if (abs(try_table[g_satLostTpTryCount]) < 1)
		{
			tpInfo.uiFrequence += try_table[g_satLostTpTryCount] * ((double)tpInfo.uiSymRate/1000);
		}
		else
		{
			tpInfo.uiFrequence += try_table[g_satLostTpTryCount];
		}
		CS_DtvGetBSLostTpConnect(pParam, &tpInfo);
	}

	g_satLostTpTryCount++;
	return ret;
}
#endif
/*****************************************************************************
** FUNCTION : static AL_Return_t CS_DtvSearchCallback(al_uint32 eCallbackType,
**						void* pParam)
**
** DESCRIPTION :
**				DTV search callback function registered into middleware
**
** PARAMETERS :
**				eCallbackType - Callback msg type
**				pParam - the search data of middleware
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t CS_DtvSearchCallback(al_uint32  eCallbackType,
	void* pParam)
{
	cs_info_st* pstInfo = GET_CS_INFO();
	MID_ScanParam_t* pstScanParam = (MID_ScanParam_t*)pParam;
	AL_Return_t ret = AL_SUCCESS;
	cs_msg_st msg;
	MID_ScanSpecialSpec *DTVSpecialSpec;
#if defined(CONFIG_DVB_SYSTEM_DVBS_SUPPORT) || defined(CONFIG_DVB_SYSTEM_DVBT2_SUPPORT)
    INT32 spectral_inversion = 0;
#endif
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
    INT32 cnt = 0;
    MID_ScanParam_t TP_Param;
    al_uint16 usLNBFreq = 0;
    AL_NetworkDetail_t stNetInfo;
    al_uint16 usLNBFreqL;
    al_uint16 usLNBFreqH;
    DRV_Frontend_Sat_Ch_List_t *pslt_ch_info = pParam;
#endif
#if defined(CONFIG_DVB_SYSTEM_DVBS_SUPPORT) || defined(CONFIG_DVB_SYSTEM_DVBT2_SUPPORT) || defined (CONFIG_DVB_SYSTEM_DVBC_SUPPORT)
    digital_search_data_st* pstDigital = &(pstInfo->unScanData.digital);
#endif

#ifdef SUPPORT_TRD
	MID_ScanDVBTpInfo_t *pstTpInfo = al_null;
	dvbpsi_target_region_name_dr_t *pstTrdName = al_null;
	al_uint32 k;
#endif

	if (al_null == pParam)
	{
		return AL_FAILURE;
	}

	memset(&msg, 0, sizeof(msg));

	CS_DEBUG_MESSAGE("Enter %s eCallbackType = %d\n", __FUNCTION__, eCallbackType);

	switch (eCallbackType)
	{
		case MID_SCAN_CALLBK_TYPE_REQUEST_NEXT_TP:
			if (CABLE_GET_NIT_PARSE == pstInfo->ucGotNITFlag)
			{
				CS_ResetScanTbl();
			}
			if (pstInfo->ucDmxIsOpen)
			{
				DMIOC_DTV_PARAM stSWParam;
				memset(&stSWParam, 0, sizeof(DMIOC_DTV_PARAM));
				stSWParam.DemuxUnit = MID_CmnGetDemuxUnit();
				ioctl(dtvdev, DTV_IOCTL_EXIT, &stSWParam);
				pstInfo->ucDmxIsOpen = 0;
			}
			ret = CS_DtvNextChannel(pParam, &msg);
			pstInfo->ucLock = al_false;
			break;
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
		case MID_SCAN_CALLBK_TYPE_REQUEST_NEXT_BS_LOST_TP:
			g_BlindTry = TRUE;
			ret = CS_DtvGetBSNextLostTp(pParam);
			if (ret != AL_SUCCESS)
            {
            	g_BlindTry = FALSE;
				msg.enType = AL_CS_MSG_TYPE_FINISHED;
				msg.uiParams = 0;
            }
			break;
		case MID_SCAN_CALLBK_TYPE_BS_LOST_TP_TRY:
			g_BlindTry = TRUE;
			ret = CS_DtvBSLostTpTry(pParam);
			break;
		case MID_SCAN_CALLBK_TYPE_BLIND_NO_SERVICE:
			//Add lost TP
			CS_DtvBlindSearchAddLostTp(pParam, g_wLNBFreq, al_true);
			break;
        case MID_SCAN_CALLBK_TYPE_BLIND_CANDIDATE_TABLE:
            AL_DB_QueryDetail(pstDigital->Satellite.hNet, &stNetInfo);
            usLNBFreqL = stNetInfo.stDVBSNetwork.uiLNBFreq >> 16;
            usLNBFreqH = stNetInfo.stDVBSNetwork.uiLNBFreq & 0x0000FFFF;
			CS_DEBUG_MESSAGE("pslt_ch_info->nCh=%d\n", pslt_ch_info->nCh);
            for (cnt = 0; cnt < pslt_ch_info->nCh; cnt++)
            {
                if(FRONTEND_DISEQC_BANK_A_LB_VP == pslt_ch_info->para[cnt].DiseqcBank)
                {
                    TP_Param.u.qpsk.polarization = VERTICAL;
                    usLNBFreq = usLNBFreqL;
                }
                else if(FRONTEND_DISEQC_BANK_A_HB_VP == pslt_ch_info->para[cnt].DiseqcBank)
                {
                    TP_Param.u.qpsk.polarization = VERTICAL;
                    usLNBFreq = usLNBFreqH;
                }
                else if(FRONTEND_DISEQC_BANK_A_LB_HP == pslt_ch_info->para[cnt].DiseqcBank)
                {
                    TP_Param.u.qpsk.polarization = HORIZONTAL;
                    usLNBFreq = usLNBFreqL;
                }
                else if(FRONTEND_DISEQC_BANK_A_HB_HP == pslt_ch_info->para[cnt].DiseqcBank)
                {
                    TP_Param.u.qpsk.polarization = HORIZONTAL;
                    usLNBFreq = usLNBFreqH;
                }
                TP_Param.u.qpsk.frequency = pslt_ch_info->para[cnt].freqKHz / 1000;
                TP_Param.u.qpsk.symrate = pslt_ch_info->para[cnt].baudrate / 1000;
                TP_Param.u.qpsk.fe_type = pslt_ch_info->para[cnt].standard;

                CS_DtvBlindSearchAddLostTp(&TP_Param, usLNBFreq,al_false);
            }
            break;
#endif
		case MID_SCAN_CALLBK_TYPE_LOCKED_TP:
			if (AL_SUCCESS == pstScanParam->u32ScanFlag)
			{
				pstInfo->ucLock = al_true;
#if defined (CONFIG_DVB_SYSTEM_DVBC_SUPPORT)
				if (pstDigital->enTunerType == TUNER_QAM 
					&&  pstDigital->Cable.pstNetworkScanInfo.uiDVBCSearchMode == AL_DVBC_SEARCHMODE_QUICK)
				{
					cs_cable_tp_info_st* pstCblTp = pstDigital->Cable.pstCurCableTp;
					pstCblTp->locked = al_true;
				}
#endif			
				if (! pstInfo->ucDmxIsOpen)
				{
					DMIOC_DTV_PARAM stSWParam;
					UINT8 TS_Mode = 0;
					UINT8 TS_Input = 0;
					FrontendCmd_t  front;

					memset(&front, 0, sizeof(FrontendCmd_t));
					memset(&stSWParam, 0, sizeof(DMIOC_DTV_PARAM));
					front.cmd = FRONTEND_CMD_GET_TS_MODE;
					front.param = (void *)&TS_Mode;
					ioctl(kmfdev, KMF_IOC_FRONTENDCTRL , &front);
					stSWParam.bSerial = TS_Mode;

					front.cmd = FRONTEND_CMD_GET_TS_INPUT;
					front.param = (void *)&TS_Input;
					ioctl(kmfdev, KMF_IOC_FRONTENDCTRL , &front);
					stSWParam.bExternal_TS = TS_Input;

					stSWParam.DemuxUnit = MID_CmnGetDemuxUnit();
					ioctl(dtvdev, DTV_IOCTL_INIT, &stSWParam);
					pstInfo->ucDmxIsOpen = 1;
				}
			}
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
			if (pstInfo->unScanData.digital.enTunerType == TUNER_QPSK)
		 	{
				cs_sate_tp_info_st* pstSateTp = pstDigital->Satellite.pstCurSateTp;
				Ant_TRANSPONDER_st CurrTpInfo;
				DRV_Frontend_Modulation_Info_t modulation_info;

				if (AL_CS_TYPE_DIGITAL_BLIND == pstInfo->enType)	//blind searching
				{
					if (((MID_ScanParam_t *) pParam)->u.qpsk.frequency > 0 && ((MID_ScanParam_t *) pParam)->u.qpsk.symrate > 0)
					{
						al_uint32 uiFrequence;
						uiFrequence = ((MID_ScanParam_t *) pParam)->u.qpsk.frequency;
						pstSateTp->uiFrequence = CS_DTV_GetTpFrequency(g_wLNBFreq, uiFrequence);
						pstSateTp->uiSymRate = ((MID_ScanParam_t *) pParam)->u.qpsk.symrate;
						if (g_isCBandDualLNB)
						{
							if (uiFrequence < LNB3_5150_HIGH_IF_FREQ)
							{
								pstSateTp->polarization = HORIZONTAL;
							}
							else
							{
								pstSateTp->polarization = VERTICAL;
							}
						}
						else
						{
							pstSateTp->polarization = ((MID_ScanParam_t *) pParam)->u.qpsk.polarization;
						}
                        pstSateTp->fe_type = ((MID_ScanParam_t *) pParam)->u.qpsk.fe_type;
					}
				}
				else
				{
					MID_SatCtrl_GetCurrentTpInfo(&CurrTpInfo);
					pstSateTp->uiFrequence = MID_SatCtrl_GetTpFrequency(CurrTpInfo.usFreq>>16, pstSateTp->uiFrequence);
				}
				MID_SatCtrl_FrontendCtrl(FRONTEND_CMD_GET_MODULATION_INFO, (void *)&modulation_info);
				pstSateTp->modulation = modulation_info.DVB_S2.emodulation;
				pstSateTp->ucCode_rate = modulation_info.DVB_S2.efec_inner;
				MID_SatCtrl_FrontendCtrl(FRONTEND_CMD_GET_SPECTRUM_INVERSION, (void *)&spectral_inversion);
				pstSateTp->ucSpec_inver = spectral_inversion;
				CS_DEBUG_MESSAGE("===modulation = %d, ucCode_rate = %d, spectral_inversion = %d\n", pstSateTp->modulation, pstSateTp->ucCode_rate, spectral_inversion);
		 	}
#endif
#ifdef CONFIG_DVB_SYSTEM_DVBT2_SUPPORT
            if (pstInfo->unScanData.digital.enTunerType == TUNER_OFDM)
            {
                FrontendCmd_t  front;
                front.cmd = FRONTEND_CMD_GET_SPECTRUM_INVERSION;
                front.param = &spectral_inversion;
                ioctl(kmfdev, KMF_IOC_FRONTENDCTRL , &front);
                pstDigital->Terr.stInput.ucSpec_inver = spectral_inversion;
            }
            #if 0//mark
			if (pstInfo->unScanData.digital.enTunerType == TUNER_OFDM \
				&& (pstInfo->uiCapabilities & MID_SCAN_CAPS_SUPPORT_DVB_T2_LATER))
			{
				if (pstInfo->unScanData.digital.Terr.ScanMode & AL_SCAN_SEPARATE_DVBT
					&& pstScanParam->u32ScanFlag == AL_SUCCESS)//please make sure DRV_SUCCESS == AL_SUCCESS
				{
					pstInfo->stSearchInfo.u.dtv.usCurTpCnt ++;//scan dvb-t and found channel
				}
				else if (pstInfo->unScanData.digital.Terr.ScanMode & AL_SCAN_SEPARATE_DVBT2)
				{
					pstInfo->stSearchInfo.u.dtv.usCurTpCnt ++;//scan dvb-t2
				}
			}
            #endif
#endif
			break;

        case MID_SCAN_CALLBK_TYPE_T2_ONE_TP_SCAN_FINISH:
#ifdef CONFIG_DVB_SYSTEM_DVBT2_SUPPORT
            if (pstInfo->uiCapabilities & MID_SCAN_CAPS_SUPPORT_DVB_T2_IMMEDIATE
                && pstInfo->unScanData.digital.enTunerType == TUNER_OFDM)
            {
                if (pstDigital->Terr.ScanMode & AL_SCAN_TOGETHER_DVBT2)
                {
                    pstDigital->Terr.ScanMode = AL_SCAN_TOGETHER_DVBT;
                }
            }
#endif
            break;

		case MID_SCAN_CALLBK_TYPE_T2_INFO:
#ifdef CONFIG_DVB_SYSTEM_DVBT2_SUPPORT
            if (pstInfo->uiCapabilities & MID_SCAN_CAPS_SUPPORT_DVB_T2_LATER
                && pstInfo->unScanData.digital.enTunerType == TUNER_OFDM)
			{
                if (pstDigital->Terr.ScanMode & AL_SCAN_SEPARATE_DVBT)
                {
                    if (pstDigital->Terr.stInput.stBandWidth.eBandWidth.BandWidthSWEn)
                    {
                        al_uint8 bMaxBw = 0;
                        AL_CS_DtvMaxBW(pstDigital->Terr.stInput.stBandWidth, &bMaxBw);
                        if (pstDigital->Terr.ucCurBW < bMaxBw)
                        {
                            break;
                        }
                    }

    				AL_T2_List *pstNewT2Node;
    				pstNewT2Node = (AL_T2_List*)GL_MemAlloc(sizeof(AL_T2_List));
    				if (pstNewT2Node == NULL)
    				{
    					CS_ERROR_MESSAGE("Memery for new T2 node is not enough\n");
    					break;
    				}
    				memcpy(&(pstNewT2Node->stT2Input), &(pstDigital->Terr.stInput), sizeof(AL_TPSects_Info_st));
                    pstNewT2Node->stT2Input.StartTpNum = pstInfo->stSearchInfo.u.dtv.usCurTpCnt;

    				_AI_CS_AddNode(pstNewT2Node);

                    pstDigital->Terr.ucCurBW = 0;
    				pstDigital->Terr.TotalT2count++;//count next scan dvb-t2 channel
                }
			}

            if (pstInfo->uiCapabilities & MID_SCAN_CAPS_SUPPORT_DVB_T2_IMMEDIATE
                && pstInfo->unScanData.digital.enTunerType == TUNER_OFDM)
            {
                if (pstDigital->Terr.ScanMode & AL_SCAN_TOGETHER_DVBT
                    && (AL_CS_TYPE_DIGITAL == pstInfo->enType))
                {
                    pstDigital->Terr.ScanMode = AL_SCAN_TOGETHER_DVBT2;
                }
            }
#endif
			break;

		case MID_SCAN_CALLBK_TYPE_UNDEFINED_SERVICE_INFO:
		case MID_SCAN_CALLBK_TYPE_SERVICE_INFO:
			ret = CS_DtvSaveService(pParam, eCallbackType, &msg);
#ifdef CONFIG_DVB_SYSTEM_DVBT2_SUPPORT
            if (pstInfo->uiCapabilities & MID_SCAN_CAPS_SUPPORT_DVB_T2_LATER
                && pstInfo->unScanData.digital.enTunerType == TUNER_OFDM
                && AL_CS_TYPE_DIGITAL_MANUAL == pstInfo->enType)
			{
                if (pstDigital->Terr.stInput.stBandWidth.eBandWidth.BandWidthSWEn)
                {
                    pstDigital->Terr.sCurTpInx ++;
                    pstDigital->Terr.CurT2Inx ++;
                }
                if (pstDigital->Terr.ScanMode & AL_SCAN_SEPARATE_DVBT)
                {
                    pstInfo->stSearchInfo.u.dtv.uiProgress = 100;
                }
			}
#endif

#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
            if ((pstInfo->unScanData.digital.enTunerType == TUNER_QPSK) \
                && (AL_CS_TYPE_DIGITAL == pstInfo->enType) \
                && ((pstInfo->uiCapabilities & AL_CS_SUPPORT_SELECT_TP_SCAN_MODE) \
                || (pstInfo->uiCapabilities & AL_CS_SUPPORT_GET_FREQ_FROM_NIT)))
            {
                g_DVBSX_DelTp = TRUE;
            }
#endif
			break;

		case MID_SCAN_CALLBK_TYPE_SPECIAL_SPEC:
			if (al_null != pParam)
			{
				DTVSpecialSpec = (MID_ScanSpecialSpec *) pParam;

				if (eSpecialSpec != DTVSpecialSpec->eSpecialSpec && pstInfo->unScanData.digital.enTunerType == TUNER_QAM)
				{
					DTVSpecialSpec->changeCapabilitie = TRUE;
					eSpecialSpec = DTVSpecialSpec->eSpecialSpec;
					specialSpecIsModify = TRUE;
					if (eSpecialSpec == DVB_SPECIAL_SPEC_DTG)
					{
						gePriSpec = AL_DB_DVB_PRISPEC_DBOOK;
					}
					else if (eSpecialSpec == DVB_SPECIAL_SPEC_ZBOOK)
					{
						gePriSpec = AL_DB_DVB_PRISPEC_ZBOOK;
					}
					else if (eSpecialSpec == DVB_SPECIAL_SPEC_NORDIG)
					{
						gePriSpec = AL_DB_DVB_PRISPEC_NORDIG;
					}
					else if (eSpecialSpec == DVB_SPECIAL_SPEC_EBOOK)
					{
						gePriSpec = AL_DB_DVB_PRISPEC_EBOOK;
					}
				}
			}
			break;
		case MID_SCAN_CALLBK_TYPE_TP_INFO:
			if (al_null == pParam)
			{
				break;
			}
		#ifdef SUPPORT_TRD
			pstTpInfo = (MID_ScanDVBTpInfo_t *) pParam;
			pstTrdName = pstTpInfo->pst_trd_name_info;
			if (al_null != pstTrdName)
			{
				while(pstTrdName)
				{
					CS_DEBUG_MESSAGE("strlen=%d: \n", strlen((char *)pstTrdName->ucName));
					for (k = 0; k < strlen((char *)pstTrdName->ucName); k ++)
					{
						CS_DEBUG_MESSAGE("%02x \n", pstTrdName->ucName[k] & 0xff);
					}
					CS_DEBUG_MESSAGE(" => \n");
#ifdef CONFIG_SUPPORT_DTG_CERTIFICATION
					CS_scanCheckStringForDTG(pstTrdName->ucName, strlen((char *)pstTrdName->ucName));
#endif
					CS_DEBUG_MESSAGE("strlen=%d: \n", strlen((char *)pstTrdName->ucName));
					for (k = 0; k < strlen((char *)pstTrdName->ucName); k ++)
					{
						CS_DEBUG_MESSAGE("%02x \n", pstTrdName->ucName[k] & 0xff);
					}

					for (k = 0; k < strlen((char *)pstTrdName->ucName); k ++)
					{
						CS_DEBUG_MESSAGE("%c\n", pstTrdName->ucName[k] & 0xff);
					}
					CS_DEBUG_MESSAGE(" depth=%d 0x%x 0x%x 0x%x \n",
						pstTrdName->u8RegionDepth,
						pstTrdName->RegionLevel[1],
						pstTrdName->RegionLevel[2],
						pstTrdName->RegionLevel[3]);
					// not store pstTrdName->next, for it not needed for dictionary, and then duplicate checking function work correct.
					#ifdef CONFIG_DVB_SYSTEM
					LCN_AddTRNDToDictionary(pstTrdName, sizeof(*pstTrdName) - sizeof(dvbpsi_target_region_name_dr_t *));
					pstTrdName = pstTrdName->next;
					#endif
				}
			}
#endif
			break;
		case MID_SCAN_CALLBK_TYPE_CARRIER_INFO:
			if (CABLE_GET_NIT_STOP == pstInfo->ucGotNITFlag)
			{
				break;
			}
			CS_GetFreqTblFromNIT(pstScanParam);
			break;
#ifdef SUPPORT_ASTRA_LCN
		case MID_SCAN_CALLBK_TYPE_ASTRA_LCN_INFO:
			{
				PMID_ScanMultSrvLCNInfoNode_t pInfo = (PMID_ScanMultSrvLCNInfoNode_t)pParam;
				pInfo->pNext = pMultiLCNInfoHead;
				pMultiLCNInfoHead = pInfo;
			}
			break;
#endif
		case MID_SCAN_CALLBK_TYPE_REQUEST_NEXT_BLIND_INFO:
			if (pstInfo->ucDmxIsOpen)
			{
				DMIOC_DTV_PARAM stSWParam;
				memset(&stSWParam, 0, sizeof(DMIOC_DTV_PARAM));
				stSWParam.DemuxUnit = MID_CmnGetDemuxUnit();
				ioctl(dtvdev, DTV_IOCTL_EXIT, &stSWParam);
				pstInfo->ucDmxIsOpen = 0;
			}
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
			ret = CS_DtvGetNextBlindInfo(pParam, &msg);
			if ((ret != AL_SUCCESS) &&
				(pstInfo->uiCapabilities&AL_CS_SUPPORT_BLIND_SCAN_METHOD_1))
			{
                if (CS_DTV_SwitchScanFEType() == AL_SUCCESS)
                {
                    ret = CS_DtvGetNextBlindInfo(pParam, &msg);
                }
                if (ret != AL_SUCCESS)
                {
    				msg.enType = AL_CS_MSG_TYPE_FINISHED;
    				msg.uiParams = 0;
                }
			}
            if ((ret != AL_SUCCESS) &&
				(pstInfo->uiCapabilities&AL_CS_SUPPORT_BLIND_SCAN_METHOD_3))
            {
				if (g_pSateLostTpInfo == TP_LIST_INVALID_HDL)
				{
					//msg.enType = AL_CS_MSG_TYPE_FINISHED;
					//msg.uiParams = 0;
				}
            }
#else
            msg.enType = AL_CS_MSG_TYPE_FINISHED;
            msg.uiParams = 0;
#endif
			break;
		case MID_SCAN_CALLBK_TYPE_LOCK_NEW_TP:
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
			if (pstInfo->unScanData.digital.enTunerType == TUNER_QPSK)
		 	{
				cs_sate_tp_info_st* pstSateTp = pstDigital->Satellite.pstCurSateTp;

				if (AL_CS_TYPE_DIGITAL_BLIND == pstInfo->enType)	//blind searching
				{
					if (((MID_ScanParam_t *) pParam)->u.qpsk.frequency > 0)
					{
						al_uint32 uiFrequence;
						uiFrequence = ((MID_ScanParam_t *) pParam)->u.qpsk.frequency;
						pstSateTp->uiFrequence = CS_DTV_GetTpFrequency(g_wLNBFreq, uiFrequence);
						if (0 == pstSateTp->uiFrequence)
						{
							break;
						}
						pstSateTp->uiSymRate = ((MID_ScanParam_t *) pParam)->u.qpsk.symrate;
                        pstSateTp->fe_type = ((MID_ScanParam_t *) pParam)->u.qpsk.fe_type;
						if (g_isCBandDualLNB)
						{
							if (uiFrequence < LNB3_5150_HIGH_IF_FREQ)
							{
								pstSateTp->polarization = HORIZONTAL;
							}
							else
							{
								pstSateTp->polarization = VERTICAL;
							}
						}
						else
						{
							pstSateTp->polarization = ((MID_ScanParam_t *) pParam)->u.qpsk.polarization;
						}
						pstInfo->stSearchInfo.uiCurFreq = (pstSateTp->uiFrequence&0xffff);
					}
					pstInfo->stSearchInfo.u.dtv.usCurTpCnt ++;
				}
		 	}

            if ((pstInfo->unScanData.digital.enTunerType == TUNER_QPSK)
                && (pstInfo->uiCapabilities&AL_CS_SUPPORT_BLIND_SCAN_METHOD_3)
                && (AL_CS_TYPE_DIGITAL_BLIND == pstInfo->enType))
		 	{
                msg.enType = AL_CS_MSG_TYPE_LOCK_CH;
                msg.uiParams = 0;

            }
            else
#endif
            {
            	msg.enType = AL_CS_MSG_TYPE_NEW_CH;
            	msg.uiParams = 0;
            }
			break;

        case MID_SCAN_CALLBK_TYPE_PROGRESS:
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
            if (pstInfo->unScanData.digital.enTunerType == TUNER_QPSK)
		 	{
				if (AL_CS_TYPE_DIGITAL_BLIND == pstInfo->enType)	//blind searching
				{
                    cs_sate_tp_info_st* pstSateTp = pstDigital->Satellite.pstCurSateTp;
                    if (((MID_ScanParam_t *) pParam)->u.qpsk.frequency > 0)
					{
						al_uint32 uiFrequence;
						uiFrequence = ((MID_ScanParam_t *) pParam)->u.qpsk.frequency;
						pstSateTp->uiFrequence = CS_DTV_GetTpFrequency(g_wLNBFreq, uiFrequence);
						pstSateTp->uiSymRate = ((MID_ScanParam_t *) pParam)->u.qpsk.symrate;
                        pstSateTp->fe_type = ((MID_ScanParam_t *) pParam)->u.qpsk.fe_type;
						pstSateTp->polarization = ((MID_ScanParam_t *) pParam)->u.qpsk.polarization;
						pstInfo->stSearchInfo.uiCurFreq = (pstSateTp->uiFrequence&0xffff);
					}
                    msg.enType = AL_CS_MSG_TYPE_NEW_CH;
                    msg.uiParams = 0;
				}
		 	}
#endif
            break;

#ifdef NIT_SCAN_SUPPORT
		case MID_SCAN_CALLBk_TYPE_NIT_SCAN_SERVICE_INFO:
			ret = CS_DtvSaveService(pParam, eCallbackType, &msg);
			break;

		case MID_SCAN_CALLBK_TYPE_FINISH:
			if (pstInfo->pstQueue)
			{
				msg.enType = AL_CS_MSG_TYPE_LOCK_CH;
				msg.uiParams = 0;
				GL_QueueSend(pstInfo->pstQueue, (void *)&msg, sizeof(cs_msg_st));
			}
			msg.enType = AL_CS_MSG_TYPE_FINISHED;
			msg.uiParams = 0;
			break;
#endif
		default:
			CS_DEBUG_MESSAGE("Error: scan callback type unknown, Type %d!!!\n",eCallbackType);
			break;
	}

	if (pstInfo->pstQueue && (msg.enType != AL_CS_MSG_TYPE_NONE))
	{
		GL_QueueSend(pstInfo->pstQueue, (void *)&msg, sizeof(cs_msg_st));
	}

	CS_DEBUG_MESSAGE("Exit %s\n",__FUNCTION__);

	return ret;
}

/*****************************************************************************
** FUNCTION : static AL_Return_t CS_DigitalAutoSearchInit(void* pdata)
**
** DESCRIPTION :
**				Init digital search area table
**
** PARAMETERS :
**				pdata - the AL_CS_Start input params
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t CS_DigitalAutoSearchInit(void* pdata)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
	digital_search_data_st* pstDigital = al_null;
	al_cs_input_params_st* pstInput = al_null;
	const AL_TPSects_Info_st* pstTbl = al_null;
	al_uint32 i,j;
	al_int32 m,n;

    if (!pdata || !pstInfo)
    {
	    return AL_FAILURE;
	}
    
	pstDigital = &pstInfo->unScanData.digital;

	if (TUNER_QAM == pstDigital->enTunerType)
	{
		const AL_DVBC_AreaTable_t* pstCableTbl;
		cs_cable_tp_info_st stCableTpInfo;

		pstCableTbl = ((al_cs_input_params_st *)pdata)->u.dtv.pstScanTable;
		if (((al_null == pstCableTbl) && ((((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiDVBCSearchMode == AL_DVBC_SEARCHMODE_QUICK)
			|| (((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiDVBCSearchMode == AL_DVBC_SEARCHMODE_QUICK_NETWORK)))
			|| (((((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiDVBCSearchMode == AL_DVBC_SEARCHMODE_FULL)
			|| (((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiDVBCSearchMode == AL_DVBC_SEARCHMODE_FULL_NETWORK))
			&& (((al_cs_input_params_st*)pdata)->uiEndFreq <= (((al_cs_input_params_st*)pdata)->uiStartFreq + ((((al_cs_input_params_st*)pdata)->stBandwidth.bByte)*100)))))
		{
			return AL_FAILURE;
		}
		if (AL_SUCCESS != AI_TpListInit(&(pstDigital->Cable.stDefaultTpTbl)))
		{
			return AL_FAILURE;
		}

		if(((((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiDVBCSearchMode == AL_DVBC_SEARCHMODE_QUICK_NETWORK))
			&& (((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiFreqAutoEn == al_false))
		{
			memset(&stCableTpInfo, 0, sizeof(stCableTpInfo));
			stCableTpInfo.uiFrequence = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiNetworkScanFreq;
			stCableTpInfo.uiSymRate = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiSymRate;
            if (((al_cs_input_params_st*)pdata)->u.dtv.qam_info.enModulation >= AL_QAM_MAX)
            {
                stCableTpInfo.enModulation = AL_QAM_MAX;
            }
            else
            {
			    stCableTpInfo.enModulation = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.enModulation;
            }
			stCableTpInfo.network_id = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.network_id;
			if (AL_SUCCESS !=
					AI_TpListAddNode(pstDigital->Cable.stDefaultTpTbl,
						&stCableTpInfo, sizeof(cs_cable_tp_info_st)))
			{
				AI_TpListFree(pstDigital->Cable.stDefaultTpTbl);
				return AL_FAILURE;
			}
			#if 0//def CONFIG_DVB_SYSTEM
			//zhongbaoxing added @20130307 for UPC sepc +++
			if(pstInfo->unScanData.digital.ucAreaIdx == AREA_NETHERLANDS)
			{
				if((((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiDVBCSearchMode == AL_DVBC_SEARCHMODE_QUICK_NETWORK)
					&& (((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiFreqAutoEn == al_false))
				{
					Mid_ScanSetUserNetworkId(g_UserNetworkID);
				}
			}
			else
			{
				Mid_ScanSetUserNetworkId(0);
			}
			//zhongbaoxing added @20130307 for UPC sepc ---
			#endif
			pstInfo->stSearchInfo.u.dtv.usTotalTpNum = 1;
		}
		else if ((((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiDVBCSearchMode == AL_DVBC_SEARCHMODE_FULL)
			|| (((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiDVBCSearchMode == AL_DVBC_SEARCHMODE_FULL_NETWORK))
		{
			al_uint32 u32TpNum = 0;
    			u32TpNum = ((((al_cs_input_params_st*)pdata)->uiEndFreq) - (((al_cs_input_params_st*)pdata)->uiStartFreq)) / ((((al_cs_input_params_st*)pdata)->stBandwidth.bByte)*100)+1;
			for (i = 0; i < u32TpNum; ++ i)
			{
				memset(&stCableTpInfo, 0, sizeof(stCableTpInfo));
				stCableTpInfo.uiFrequence = (((al_cs_input_params_st*)pdata)->uiStartFreq) + i*((((al_cs_input_params_st*)pdata)->stBandwidth.bByte)*100);
				stCableTpInfo.uiSymRate = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiSymRate;
                if (((al_cs_input_params_st*)pdata)->u.dtv.qam_info.enModulation >= AL_QAM_MAX)
                {
                    stCableTpInfo.enModulation = AL_QAM_MAX;
                }
                else
                {
				    stCableTpInfo.enModulation = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.enModulation;
                }
				stCableTpInfo.network_id = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.network_id;
				if (AL_SUCCESS !=
						AI_TpListAddNode(pstDigital->Cable.stDefaultTpTbl,
							&stCableTpInfo, sizeof(cs_cable_tp_info_st)))
				{
					AI_TpListFree(pstDigital->Cable.stDefaultTpTbl);
					return AL_FAILURE;
				}
			}
			pstInfo->stSearchInfo.u.dtv.usTotalTpNum = u32TpNum;
		}
		else
		{
		    if (!pstCableTbl)
            {
                return AL_FAILURE;
            }
            
			for (i = 0; i < pstCableTbl->uiTpNum; ++ i)
			{
				memset(&stCableTpInfo, 0, sizeof(stCableTpInfo));
				stCableTpInfo.uiFrequence = pstCableTbl->pstTpTbl[i];
				stCableTpInfo.uiSymRate = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiSymRate;
                if (((al_cs_input_params_st*)pdata)->u.dtv.qam_info.enModulation >= AL_QAM_MAX)
                {
                    stCableTpInfo.enModulation = AL_QAM_MAX;
                }
                else
                {
				    stCableTpInfo.enModulation = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.enModulation;
                }
				stCableTpInfo.network_id = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.network_id;
				stCableTpInfo.locked = al_false;
				if (AL_SUCCESS !=
						AI_TpListAddNode(pstDigital->Cable.stDefaultTpTbl,
							&stCableTpInfo, sizeof(cs_cable_tp_info_st)))
				{
					AI_TpListFree(pstDigital->Cable.stDefaultTpTbl);
					return AL_FAILURE;
				}
			}
			pstInfo->stSearchInfo.u.dtv.usTotalTpNum = pstCableTbl->uiTpNum;
		}
		pstDigital->Cable.stTpListHdl = pstDigital->Cable.stDefaultTpTbl;
		pstDigital->Cable.pstCurCableTp = al_null;
		pstDigital->Cable.pstNetworkScanInfo.uiDVBCSearchMode = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiDVBCSearchMode;
		pstDigital->Cable.pstNetworkScanInfo.uiNetworkIdAutoEn = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiNetworkIdAutoEn;
		pstDigital->Cable.pstNetworkScanInfo.uiFreqAutoEn = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiFreqAutoEn;
		pstDigital->Cable.pstNetworkScanInfo.uiNetworkScanFreq = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiNetworkScanFreq;
	}
	else if (TUNER_QPSK == pstDigital->enTunerType)
	{
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
		const AL_DVBS_AreaTable_t* pstSateTbl;
		cs_sate_tp_info_st stSateTpInfo;
        al_uint32 fe_type = 0;

		fe_type = ((al_cs_input_params_st *)pdata)->u.dtv.qpsk_info.uiFeType;
		AL_CS_DVBSX_InitScanFEType(fe_type);

		pstSateTbl = ((al_cs_input_params_st *)pdata)->u.dtv.pstScanTable;
		if (al_null == pstSateTbl)
		{
			return AL_FAILURE;
		}

		pstInfo->unScanData.digital.Satellite.stDefaultTpTbl = TP_LIST_INVALID_HDL;
		pstInfo->unScanData.digital.Satellite.stNITTpTbl = TP_LIST_INVALID_HDL;
		pstInfo->unScanData.digital.Satellite.stBSTpTbl = TP_LIST_INVALID_HDL;
		pstInfo->unScanData.digital.Satellite.stTpListHdl = TP_LIST_INVALID_HDL;

		if (AL_SUCCESS != AI_TpListInit(&(pstDigital->Satellite.stDefaultTpTbl)))
		{
			return AL_FAILURE;
		}

		for (i = 0; i < pstSateTbl->uiTpNum; ++ i)
		{
			memset(&stSateTpInfo, 0, sizeof(stSateTpInfo));
			stSateTpInfo.uiFrequence = ((pstSateTbl->pstTpTbl)+i)->usFreq;
			stSateTpInfo.uiSymRate   = ((pstSateTbl->pstTpTbl)+i)->usSymRate;
			stSateTpInfo.polarization  = ((pstSateTbl->pstTpTbl)+i)->u8Polar;
			stSateTpInfo.fe_type = ((pstSateTbl->pstTpTbl)+i)->ucTp_dvb_type;

			if (AL_SUCCESS != AI_TpListAddNode(pstDigital->Satellite.stDefaultTpTbl,
						&stSateTpInfo, sizeof(cs_sate_tp_info_st)))
			{
				AI_TpListFree(pstDigital->Satellite.stDefaultTpTbl);
				return AL_FAILURE;
			}
		}

		pstDigital->Satellite.stTpListHdl = pstDigital->Satellite.stDefaultTpTbl;
		pstDigital->Satellite.pstCurSateTp = al_null;
        
        if (((al_cs_input_params_st*)pdata)->u.dtv.qpsk_info.u8Polarization >= POLAR_MAX)
        {
            pstDigital->Satellite.ucBlindSearchPolar = POLAR_MAX;
        }
        else
        {
		    pstDigital->Satellite.ucBlindSearchPolar = ((al_cs_input_params_st*)pdata)->u.dtv.qpsk_info.u8Polarization;
        }
		pstDigital->Satellite.hNet = ((al_cs_input_params_st *)pdata)->u.dtv.qpsk_info.hNet;
		pstInfo->stSearchInfo.u.dtv.usTotalTpNum = pstSateTbl->uiTpNum;

        if (fe_type == AL_CS_DVBSX_S_TO_S2 || fe_type == AL_CS_DVBSX_S2_TO_S)
        {
            pstInfo->stSearchInfo.u.dtv.usTotalTpNum += pstInfo->stSearchInfo.u.dtv.usTotalTpNum;
        }
#endif

	}
	else if (TUNER_OFDM == pstDigital->enTunerType || TUNER_TDS_OFDM == pstDigital->enTunerType)
	{
		pstInput = (al_cs_input_params_st *)pdata;

        pstDigital->Terr.TotalT2count = 0;
        pstDigital->Terr.CurT2Inx = 0;
        pstDigital->Terr.ScanMode = AL_SCAN_ONLY_DVBT;
#ifdef CONFIG_DVB_SYSTEM_DVBT2_SUPPORT
        if (pstInput->u.dtv.dvbt2mode & AL_SCAN_ONLY_DVBT)
        {
            pstDigital->Terr.ScanMode = AL_SCAN_ONLY_DVBT;
        }
        else if (pstInput->u.dtv.dvbt2mode & AL_SCAN_ONLY_DVBT2)
        {
            pstDigital->Terr.ScanMode = AL_SCAN_ONLY_DVBT2;
        }
        else if (pstInput->u.dtv.dvbt2mode & AL_SCAN_DVB_T_T2_TOGETHER_MODE)
        {
            pstDigital->Terr.ScanMode = (AL_SCAN_DVB_T_T2_TOGETHER_MODE | AL_SCAN_TOGETHER_DVBT);
        }
        else if (pstInput->u.dtv.dvbt2mode & AL_SCAN_DVB_T_T2_SEPARATE_MODE)
        {
            pstDigital->Terr.ScanMode = (AL_SCAN_DVB_T_T2_SEPARATE_MODE | AL_SCAN_SEPARATE_DVBT);
        }
        else
        {
            pstDigital->Terr.ScanMode = AL_SCAN_DVB_T_T2_DEFAULT_MODE;
        }
#endif
		if (!(pstInput->uiCapabilities & AL_CS_SUPPORT_NIT_FREQ_LIST_SCAN))
		{
			pstDigital->Terr.pstAreaTable = pstInput->u.dtv.pstScanTable;
			if (al_null == pdata || al_null == pstDigital->Terr.pstAreaTable ||
				(al_null == (pstTbl = pstDigital->Terr.pstAreaTable->pTPRegion_Area)))
			{
				return AL_FAILURE;
			}

			pstInfo->stSearchInfo.u.dtv.usTotalTpNum = 0;

			pstDigital->Terr.uiSectionNum = pstDigital->Terr.pstAreaTable->SectNum - 1;
			pstDigital->Terr.sCurSecInx = 0;
			pstDigital->Terr.sCurTpInx = 0;
			pstDigital->Terr.ucCurBW = 0;

			for(m = pstDigital->Terr.uiSectionNum; m >= 0; m --)
			{
				for(n = pstTbl[m].SectTPCount - 1; n >= 0; n --)
				{
					memset(&pstDigital->Terr.stInput, 0, sizeof(AL_TPSects_Info_st));
					pstDigital->Terr.stInput.stBandWidth = pstTbl[m].stBandWidth;
					pstDigital->Terr.stInput.StartFreq =
						pstTbl[m].StartFreq + pstTbl[m].stBandWidth.eBandWidth.BaseBandWidth * n * 1000;
					pstDigital->Terr.stInput.StartTpNum = pstTbl[m].StartTpNum + n;
					pstDigital->Terr.stInput.UHF_VHF = pstTbl[m].UHF_VHF;

					pstInfo->stSearchInfo.u.dtv.usTotalTpNum ++;
				}
			}
		}
		else
		{
			/* retrieve freq from frequency_list_descriptor */
			al_uint32 *freq = al_null;
			AL_TPSects_Info_st TerInfo;
			al_uint16 node_num = 0;
			al_uint16 k;
			al_uint16 match = 0;
			al_uint32 temp = 0;

			AI_TpListInit(&pstDigital->Terr.stFreqListHdl);

			pstDigital->Terr.pstAreaTable = pstInput->u.dtv.pstScanTable;
			pstTbl = pstDigital->Terr.pstAreaTable->pTPRegion_Area;

			pstDigital->Terr.uiSectionNum = pstDigital->Terr.pstAreaTable->SectNum - 1;
			pstDigital->Terr.sCurSecInx = 0;
			pstDigital->Terr.sCurTpInx = 0;
			pstDigital->Terr.ucCurBW = 0;
			pstDigital->Terr.pstCurTerTp = al_null;

			while (AI_TpListGetNode((TpListHdl_st)pstInput->u.dtv.ofdm_info.FreqlistHdl, (void **)&freq) == AL_SUCCESS)
			{
				node_num++;
			}

			al_uint32 *pFreqAarry = (al_uint32 *)GL_MemAlloc(node_num * sizeof(al_uint32));

			if (pFreqAarry == al_null)
			{
				CS_ERROR_MESSAGE("Memory is not enough\n");
				return AL_MEMORY_ALLOC_FAILED;
			}

			for (i = 0; i < node_num; i++)
			{
				AI_TpListGetNode((TpListHdl_st)pstInput->u.dtv.ofdm_info.FreqlistHdl, (void **)&freq);
				/* wuliang: change the freq scale for channel search since freq in frequency_list_descriptor looks like:
					52200000, 55400000, so change scale to 522000, 554000 for scan scale.
				*/
				pFreqAarry[i] = *freq/100;
			}

			/* Remove duplicate node (with same fre q) to tail and set 0xFFFF*/
			for (i = 0; i < (al_uint32)(node_num - match) && pFreqAarry[i] != 0xFFFF; i++)
			{
				for (j = i+1; j < (al_uint32)(node_num - match); j++)
				{
					if (pFreqAarry[i] == pFreqAarry[j])
					{
						for (k = j; k < (node_num - 1 - match); k++)
						{
							pFreqAarry[k] = pFreqAarry[k+1];
						}
						pFreqAarry[node_num -1 - match] = 0xFFFF;
						match ++;
					}
				}
			}

			/* bubble sorting */
			for (i = 0; i < (al_uint32)(node_num - match); i++)
			{
				for (j = i+1; j < (al_uint32)(node_num - match); j++)
				{
					if (pFreqAarry[i] > pFreqAarry[j])
					{
						temp = pFreqAarry[i];
						pFreqAarry[i] = pFreqAarry[j];
						pFreqAarry[j] = temp;
					}
				}
			}

			for (i = 0; i < (al_uint32)(node_num - match); i++)
			{
				CS_DEBUG_MESSAGE("Freq list[%d] = %d\n", i, pFreqAarry[i]);
			}

			pstInfo->stSearchInfo.u.dtv.usTotalTpNum = 0;
			for (k = 0; k < (node_num - match); k++)
			{
				i = 0;
				bool found = false;
				TerInfo.StartFreq = pFreqAarry[k];
				/* the Freq list has been sorted, for effiency, do not reset i, j as we can search from the previous place */
				for (; i <= pstDigital->Terr.uiSectionNum; i ++)
				{
					j = 0;
					for (; j <= (al_uint32)pstTbl[i].SectTPCount - 1; j ++)
					{
						if (TerInfo.StartFreq == pstTbl[i].StartFreq + pstTbl[i].stBandWidth.eBandWidth.BaseBandWidth * j * 1000)
						{
							/* retrieve bandwidth and UHF_VHF of this freq */
							TerInfo.stBandWidth = pstTbl[i].stBandWidth;
							TerInfo.UHF_VHF = pstTbl[i].UHF_VHF;
							found = true;
							break;
						}
					}

					if (found)
						break;
				}

				if (found)
				{
					AI_TpListAddNode(pstDigital->Terr.stFreqListHdl, (void *)&TerInfo, sizeof(AL_TPSects_Info_st));
					pstInfo->stSearchInfo.u.dtv.usTotalTpNum++;
				}
			}

			GL_MemFree(pFreqAarry);

		}
	}
	else if (TUNER_BST_OFDM == pstDigital->enTunerType)
	{
		pstInput = (al_cs_input_params_st *)pdata;
		pstDigital->Sbtvd.pstAreaTable = pstInput->u.dtv.pstScanTable;
		if (al_null == pstDigital->Sbtvd.pstAreaTable ||
			(al_null == (pstTbl = pstDigital->Sbtvd.pstAreaTable->pTPRegion_Area)))
		{
			return AL_FAILURE;
		}

		pstInfo->stSearchInfo.u.dtv.usTotalTpNum = 0;

		pstDigital->Sbtvd.uiSectionNum = pstDigital->Sbtvd.pstAreaTable->SectNum - 1;
		pstDigital->Sbtvd.sCurSecInx = 0;
		pstDigital->Sbtvd.sCurTpInx = 0;
		pstDigital->Sbtvd.ucCurBW = 0;

		for(m = pstDigital->Sbtvd.uiSectionNum; m >= 0; m --)
		{
			for(n = pstTbl[m].SectTPCount - 1; n >= 0; n --)
			{
				memset(&pstDigital->Sbtvd.stInput, 0, sizeof(AL_TPSects_Info_st));
				pstDigital->Sbtvd.stInput.stBandWidth = pstTbl[m].stBandWidth;
				pstDigital->Sbtvd.stInput.StartFreq =
					pstTbl[m].StartFreq + pstTbl[m].stBandWidth.eBandWidth.BaseBandWidth * n * 1000;
				pstDigital->Sbtvd.stInput.StartTpNum = pstTbl[m].StartTpNum + n;
				pstDigital->Sbtvd.stInput.UHF_VHF = pstTbl[m].UHF_VHF;

				pstInfo->stSearchInfo.u.dtv.usTotalTpNum ++;
			}
		}
	}
	else
	{

	}

#ifdef CONFIG_SUPPORT_FAST_SCANNING
	pstInput = (al_cs_input_params_st *)pdata;
	if(pstInput->uiCapabilities & AL_CS_SUPPORT_M7_FAST_SCAN)
	{
		MID_ScanSetFastScanPid(pstInput->u.dtv.uiM7FstPid);
		MID_ScanSetFastScanUpdateMode(pstInput->u.dtv.bM7CheckVersion);
	}
#endif

	return AL_SUCCESS;
}

/*****************************************************************************
** FUNCTION : static AL_Return_t CS_DigitalBlindSearchInit(void* pdata)
**
** DESCRIPTION :
**				Init digital search area table
**
** PARAMETERS :
**				pdata - the AL_CS_Start input params
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t CS_DigitalBlindSearchInit(void* pdata)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
	digital_search_data_st* pstDigital = al_null;
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
	AL_NetworkDetail_t stNetInfo;
    al_uint16 usLNBFreqL;
    al_uint16 usLNBFreqH;
#endif

    if (!pdata || !pstInfo)
    {
	    return AL_FAILURE;
	}
    
	pstDigital = &pstInfo->unScanData.digital;

	if (TUNER_QAM == pstDigital->enTunerType)
	{
	}
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
	else if (TUNER_QPSK == pstDigital->enTunerType)
	{
		const AL_DVBS_AreaTable_t* pstSateTbl;
		cs_sate_tp_info_st stSateTpInfo;
        al_uint32 fe_type = 0;

		pstSateTbl = ((al_cs_input_params_st *)pdata)->u.dtv.pstScanTable;

		if (al_null == pstSateTbl)
		{
			CS_ERROR_MESSAGE(" %s , %d , Satellite table is NULL\n", __FUNCTION__, __LINE__);
			return AL_FAILURE;
		}

		pstInfo->unScanData.digital.Satellite.stDefaultTpTbl = TP_LIST_INVALID_HDL;
		pstInfo->unScanData.digital.Satellite.stNITTpTbl = TP_LIST_INVALID_HDL;
		pstInfo->unScanData.digital.Satellite.stBSTpTbl = TP_LIST_INVALID_HDL;
		pstInfo->unScanData.digital.Satellite.stTpListHdl = TP_LIST_INVALID_HDL;

		if (AL_SUCCESS != AI_TpListInit(&(pstDigital->Satellite.stDefaultTpTbl)))
		{
			CS_ERROR_MESSAGE(" %s , %d , Init Default TP table fail\n", __FUNCTION__, __LINE__);
			return AL_FAILURE;
		}

		memset(&stSateTpInfo, 0, sizeof(stSateTpInfo));
		stSateTpInfo.uiFrequence = ((al_cs_input_params_st*)pdata)->uiStartFreq;
		stSateTpInfo.uiFreqEnd = ((al_cs_input_params_st*)pdata)->uiEndFreq;
		stSateTpInfo.uiSymRate = ((al_cs_input_params_st*)pdata)->u.dtv.qpsk_info.uiSymRate;
		stSateTpInfo.polarization = ((al_cs_input_params_st*)pdata)->u.dtv.qpsk_info.u8Polarization;

		if (AL_SUCCESS != AI_TpListAddNode(pstDigital->Satellite.stDefaultTpTbl,
					&stSateTpInfo, sizeof(cs_sate_tp_info_st)))
		{
			AI_TpListFree(pstDigital->Satellite.stDefaultTpTbl);
			CS_ERROR_MESSAGE(" %s , %d , add TP list fail\n", __FUNCTION__, __LINE__);
			return AL_FAILURE;
		}

		pstDigital->Satellite.stTpListHdl = pstDigital->Satellite.stDefaultTpTbl;
		pstDigital->Satellite.pstCurSateTp = al_null;
        if (((al_cs_input_params_st*)pdata)->u.dtv.qpsk_info.u8Polarization >= POLAR_MAX)
        {
            pstDigital->Satellite.ucBlindSearchPolar = POLAR_MAX;
        }
        else
        {
		    pstDigital->Satellite.ucBlindSearchPolar = ((al_cs_input_params_st*)pdata)->u.dtv.qpsk_info.u8Polarization;
        }
		pstDigital->Satellite.hNet = ((al_cs_input_params_st *)pdata)->u.dtv.qpsk_info.hNet;
		pstInfo->stSearchInfo.u.dtv.usTotalTpNum = 0;//pstSateTbl->uiTpNum;
		pstInfo->stSearchInfo.u.dtv.uiProgress = 0;

		AL_DB_QueryDetail(pstDigital->Satellite.hNet, &stNetInfo);
		usLNBFreqL = stNetInfo.stDVBSNetwork.uiLNBFreq >> 16;
		usLNBFreqH = stNetInfo.stDVBSNetwork.uiLNBFreq & 0x0000FFFF;
		g_isCBandDualLNB = FALSE;
		if (usLNBFreqL != usLNBFreqH && usLNBFreqH < LNB_C_Ku_DEVIDING_LINE && usLNBFreqL < LNB_C_Ku_DEVIDING_LINE)
		{
			g_isCBandDualLNB = TRUE;
		}
		if (pstDigital->Satellite.ucBlindSearchPolar == BOTH_H_V)
		{
			pstInfo->stSearchInfo.u.dtv.ucTotalBand = 2;
		}
		else
		{
			pstInfo->stSearchInfo.u.dtv.ucTotalBand = 1;
		}

		if (usLNBFreqL != usLNBFreqH)
		{
			pstInfo->stSearchInfo.u.dtv.ucTotalBand = pstInfo->stSearchInfo.u.dtv.ucTotalBand << 1;
		}

        fe_type = ((al_cs_input_params_st *)pdata)->u.dtv.qpsk_info.uiFeType;

        if ((!((pstInfo->uiCapabilities & AL_CS_SUPPORT_BLIND_SCAN_METHOD_2)||(pstInfo->uiCapabilities & AL_CS_SUPPORT_BLIND_SCAN_METHOD_3)))
            && (fe_type == AL_CS_DVBSX_S_TO_S2 || fe_type == AL_CS_DVBSX_S2_TO_S))
        {
            pstInfo->stSearchInfo.u.dtv.ucTotalBand = pstInfo->stSearchInfo.u.dtv.ucTotalBand << 1;
        }
        AL_CS_DVBSX_InitScanFEType(fe_type);

		if (pstInfo->uiCapabilities & AL_CS_SUPPORT_BLIND_SCAN_METHOD_2)
		{
			//MID_ScanBlindScanChannelInfoCallback(CS_DtvBuildBlindScanTbl); // removed since this function is never callbacked since SVN 61341
			MID_ScanBlindScanUpdateUICallback(CS_DtvSendUpdateUIMsg);
		}
        if (pstInfo->uiCapabilities & AL_CS_SUPPORT_BLIND_SCAN_METHOD_3)
		{
			MID_ScanBlindScanUpdateUICallback(CS_DtvSendUpdateUIMsg);
		}
		g_CurPolar = POLAR_MAX;
	}
#endif
	else if (TUNER_OFDM == pstDigital->enTunerType)
	{
	}
	else if (TUNER_BST_OFDM == pstDigital->enTunerType)
	{
	}
	else
	{

	}

	return AL_SUCCESS;
}

/*****************************************************************************
** FUNCTION : static AL_Return_t CS_DigitalManualSearchInit(void* pdata)
**
** DESCRIPTION :
**				Init digital manual search
**
** PARAMETERS :
**				pdata - the AL_CS_Start input params
** RETURN VALUES:
**				AL_SUCCESS
**				AL_FAILURE
*****************************************************************************/
static AL_Return_t CS_DigitalManualSearchInit(void* pdata)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
	digital_search_data_st* pstDigital = al_null;

	if (!pdata || !pstInfo)
    {
	    return AL_FAILURE;
	}
    
    pstDigital = &pstInfo->unScanData.digital;

	if (TUNER_QAM == pstDigital->enTunerType)
	{
		cs_cable_tp_info_st stCableTpInfo;
		memset(&stCableTpInfo, 0, sizeof(stCableTpInfo));

		if (((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiNetworkIdAutoEn == FALSE)
		{
			stCableTpInfo.network_id = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.network_id;
		}
		pstDigital->Cable.pstNetworkScanInfo.uiDVBCSearchMode = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiDVBCSearchMode;
		pstDigital->Cable.pstNetworkScanInfo.uiNetworkIdAutoEn = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiNetworkIdAutoEn;
		//pstDigital->Cable.pstNetworkScanInfo.uiFreqAutoEn = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiFreqAutoEn;
		//pstDigital->Cable.pstNetworkScanInfo.uiNetworkScanFreq = ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiNetworkScanFreq;

		if (AL_SUCCESS != AI_TpListInit(&(pstDigital->Cable.stDefaultTpTbl)))
		{
			return AL_FAILURE;
		}

		stCableTpInfo.uiFrequence = ((al_cs_input_params_st*)pdata)->uiStartFreq;
		stCableTpInfo.uiSymRate =
			((al_cs_input_params_st*)pdata)->u.dtv.qam_info.uiSymRate;
        if (((al_cs_input_params_st*)pdata)->u.dtv.qam_info.enModulation >= AL_QAM_MAX)
        {
            stCableTpInfo.enModulation = AL_QAM_MAX;
        }
        else
        {
		    stCableTpInfo.enModulation =
			    ((al_cs_input_params_st*)pdata)->u.dtv.qam_info.enModulation;
        }
		if (AL_SUCCESS !=
			AI_TpListAddNode(pstDigital->Cable.stDefaultTpTbl,
				&stCableTpInfo, sizeof(cs_cable_tp_info_st)))
		{
			AI_TpListFree(pstDigital->Cable.stDefaultTpTbl);
			return AL_FAILURE;
		}

		pstDigital->Cable.stTpListHdl = pstDigital->Cable.stDefaultTpTbl;
		pstDigital->Cable.pstCurCableTp = al_null;
		pstInfo->stSearchInfo.u.dtv.usTotalTpNum = 1;

	}
#ifdef CONFIG_DVB_SYSTEM_DVBS_SUPPORT
	else if (TUNER_QPSK == pstDigital->enTunerType)
	{
        al_uint32 fe_type = 0;
		cs_sate_tp_info_st stSateTpInfo;
		memset(&stSateTpInfo, 0, sizeof(stSateTpInfo));

		if (AL_SUCCESS != AI_TpListInit(&(pstDigital->Satellite.stDefaultTpTbl)))
		{
			return AL_FAILURE;
		}

		stSateTpInfo.uiFrequence = ((al_cs_input_params_st*)pdata)->uiStartFreq;
		stSateTpInfo.uiSymRate = ((al_cs_input_params_st*)pdata)->u.dtv.qpsk_info.uiSymRate;
		stSateTpInfo.polarization = ((al_cs_input_params_st*)pdata)->u.dtv.qpsk_info.u8Polarization;

		if (AL_SUCCESS != AI_TpListAddNode(pstDigital->Satellite.stDefaultTpTbl,
				&stSateTpInfo, sizeof(cs_sate_tp_info_st)))
		{
			AI_TpListFree(pstDigital->Satellite.stDefaultTpTbl);
			return AL_FAILURE;
		}
		pstDigital->Satellite.hNet = ((al_cs_input_params_st *)pdata)->u.dtv.qpsk_info.hNet;
		pstDigital->Satellite.stTpListHdl = pstDigital->Satellite.stDefaultTpTbl;
		pstDigital->Satellite.pstCurSateTp = al_null;

        fe_type = ((al_cs_input_params_st *)pdata)->u.dtv.qpsk_info.uiFeType;

        AL_CS_DVBSX_InitScanFEType(fe_type);
	}
#endif
	else if (TUNER_OFDM == pstDigital->enTunerType || TUNER_TDS_OFDM == pstDigital->enTunerType )
	{
		pstDigital->Terr.pstAreaTable = ((al_cs_input_params_st*)pdata)->u.dtv.pstScanTable;
		if (al_null == pstDigital->Terr.pstAreaTable)
		{
			CS_DEBUG_MESSAGE("ERROR! %s, %d\n",__FUNCTION__,__LINE__);
			return AL_FAILURE;
		}

		pstDigital->Terr.stInput.StartFreq =
			pstInfo->stSearchInfo.uiCurFreq =
				((al_cs_input_params_st*)pdata)->uiStartFreq;
		pstDigital->Terr.stInput.stBandWidth = ((al_cs_input_params_st*)pdata)->stBandwidth;
		pstInfo->stSearchInfo.uiCurBandwidth = pstDigital->Terr.stInput.stBandWidth.eBandWidth.BaseBandWidth;

		pstInfo->stSearchInfo.u.dtv.usTotalTpNum = 1;

		pstDigital->Terr.ucCurBW = 0;
		pstDigital->Terr.sCurTpInx = 0;
		pstDigital->Terr.sCurSecInx = 0;
		pstDigital->Terr.uiSectionNum = 0;

        pstDigital->Terr.TotalT2count = 0;
        pstDigital->Terr.CurT2Inx = 0;
        pstDigital->Terr.ScanMode = AL_SCAN_ONLY_DVBT;
#ifdef CONFIG_DVB_SYSTEM_DVBT2_SUPPORT
        if (((al_cs_input_params_st*)pdata)->u.dtv.dvbt2mode & AL_SCAN_ONLY_DVBT)
        {
            pstDigital->Terr.ScanMode = AL_SCAN_ONLY_DVBT;
        }
        else if (((al_cs_input_params_st*)pdata)->u.dtv.dvbt2mode & AL_SCAN_ONLY_DVBT2)
        {
            pstDigital->Terr.ScanMode = AL_SCAN_ONLY_DVBT2;
        }
        else if (((al_cs_input_params_st*)pdata)->u.dtv.dvbt2mode & AL_SCAN_DVB_T_T2_TOGETHER_MODE)
        {
            pstDigital->Terr.ScanMode = (AL_SCAN_DVB_T_T2_TOGETHER_MODE | AL_SCAN_TOGETHER_DVBT);
        }
        else if (((al_cs_input_params_st*)pdata)->u.dtv.dvbt2mode & AL_SCAN_DVB_T_T2_SEPARATE_MODE)
        {
            pstDigital->Terr.ScanMode = (AL_SCAN_DVB_T_T2_SEPARATE_MODE | AL_SCAN_SEPARATE_DVBT);
        }
        else
        {
            pstDigital->Terr.ScanMode = AL_SCAN_ONLY_DVBT;
        }
#endif
	}
	else if (TUNER_BST_OFDM == pstDigital->enTunerType)
	{
		pstDigital->Sbtvd.pstAreaTable =
			((al_cs_input_params_st*)pdata)->u.dtv.pstScanTable;
		if (al_null == pstDigital->Sbtvd.pstAreaTable)
		{
			CS_DEBUG_MESSAGE("ERROR! %s, %d\n",__FUNCTION__,__LINE__);
			return AL_FAILURE;
		}

		pstDigital->Sbtvd.stInput.StartFreq =
			pstInfo->stSearchInfo.uiCurFreq =
				((al_cs_input_params_st*)pdata)->uiStartFreq;
		pstDigital->Sbtvd.stInput.stBandWidth = ((al_cs_input_params_st*)pdata)->stBandwidth;
		pstInfo->stSearchInfo.uiCurBandwidth = pstDigital->Sbtvd.stInput.stBandWidth.eBandWidth.BaseBandWidth;

		pstInfo->stSearchInfo.u.dtv.usTotalTpNum = 1;

		pstDigital->Sbtvd.ucCurBW = 0;
		pstDigital->Sbtvd.sCurTpInx = 0;
		pstDigital->Sbtvd.sCurSecInx = 0;
		pstDigital->Sbtvd.uiSectionNum = 0;
	}
	else
	{

	}

	return AL_SUCCESS;
}
#endif

#ifdef SUPPORT_LCN
/* auto dispose LCN Conflict and judge whether need user to dispose the remain conficts */
DBLCNConfInfo_t* AL_LCN_GetLCNConfChannel(al_void)
{
	return &g_LcnConf;
}

#ifdef SUPPORT_ASTRA_LCN
static al_void CS_DtvCacheChnListName(al_void)
{
	PMID_ScanMultSrvLCNInfoNode_t pTmp = pMultiLCNInfoHead;
	PMID_ScanMultSrvLCNInfo_t pMultiSrvLCNInfo = al_null;
	PMID_ScanMultSrvLCNInfo_t pTmpChnList = al_null;
	UINT8 uiIdx = 0;
	UINT32 uiIter = 0;
	DBSingChnLCN_t stLCN;
	DBDVBLocator_t stLocator;
	//jun.luo@2018.11.27: we use fake channel list id here, refer to mantis 0048711
	UINT32 uiIterEx = 1;
	UINT32 uiWrapChnListID = 0;

	while (pTmp != al_null)
	{
		pMultiSrvLCNInfo = pTmp->pstMultiSrvLCNInfo;
		pTmpChnList = pMultiSrvLCNInfo;
		while (pTmpChnList != al_null)
		{
			uiWrapChnListID = uiIterEx++;
			if (DB_SUCCESS == LCN_MultiChnList_SetIdName(uiWrapChnListID/*pTmpChnList->channel_list_id*/, pTmpChnList->channel_list_name,
				strlen((const char *)pTmpChnList->channel_list_name), &uiIdx))
			{
				uiIter = 0;
				while (uiIter < pTmpChnList->uiSrvCnt)
				{
					stLCN.usChnListID = uiWrapChnListID/*pTmpChnList->channel_list_id*/;
					stLCN.usLCN = pTmpChnList->pLCNList[uiIter].usLCN | DB_DVB_LCN_INDICATOR;
					stLCN.bVisibleFlag = pTmpChnList->pLCNList[uiIter].bVisible;
					stLCN.ucServType = pTmpChnList->pLCNList[uiIter].ucServType;

					stLocator.usONID = pTmpChnList->pLCNList[uiIter].usONID;
					stLocator.usTSID = pTmpChnList->pLCNList[uiIter].usTSID;
					stLocator.usSrvID = pTmpChnList->pLCNList[uiIter].usSrvID;
					LCN_MultiChnList_SetLCNExt(&stLocator, &stLCN, uiIdx);
#if 0
					printf("222 Locator(0x%04x, 0x%04x, 0x%04x)----LCN:%d, validFlag:%d, listID:%d, SlotIdx:%d, ServType:%d\n",
						stLocator.usONID, stLocator.usTSID, stLocator.usSrvID,
						GET_LCN(stLCN.usLCN), stLCN.bVisibleFlag, stLCN.usChnListID, uiIdx, stLCN.ucServType);
#endif
					uiIter++;
				}
			}
			pTmpChnList = pTmpChnList->pNextChnList;
		}
		pTmp = pTmp->pNext;
	}
}

static al_void CS_DtvFreeASTRAMultiChnInfo(al_void)
{
	PMID_ScanMultSrvLCNInfoNode_t pTmp = pMultiLCNInfoHead;
	PMID_ScanMultSrvLCNInfo_t pMultiSrvLCNInfo = al_null;
	PMID_ScanMultSrvLCNInfo_t pTmpSrvList = al_null;

	while(pTmp != al_null)
	{
		pMultiLCNInfoHead = pMultiLCNInfoHead->pNext;

		pMultiSrvLCNInfo = pTmp->pstMultiSrvLCNInfo;
		pTmpSrvList = pMultiSrvLCNInfo;
		while (pTmpSrvList != al_null)
		{
			pMultiSrvLCNInfo = pMultiSrvLCNInfo->pNextChnList;
			free(pTmpSrvList->pLCNList);
			free(pTmpSrvList);
			pTmpSrvList = pMultiSrvLCNInfo;
		}

		free(pTmp);
		pTmp = pMultiLCNInfoHead;
	}

	pMultiLCNInfoHead = al_null;
}
#endif

/* auto dispose LCN Conflict and judge whether need user to dispose the remain conficts */
bool AL_LCN_ProcessAndJudgeWhetherPopToUser(AL_DB_EDBType_t eNetType, al_uint8 u8Country, al_bool bForceAutoProc)
{
#ifdef CONFIG_DVB_SYSTEM
#ifdef SUPPORT_TRD
	PDBTRNDDictionary_t pTRDDictionary;
#endif
#endif
#ifdef SUPPORT_DVBS_LCN
	if (eNetType == AL_DBTYPE_DVB_S)
	{
#ifdef SUPPORT_ASTRA_LCN
		CS_DtvCacheChnListName();
		CS_DtvFreeASTRAMultiChnInfo();

		if (LCN_MultiChnList_GetValidCnt() >= 2)
		{
			return al_true;
		}
	    else
#endif
	    {
			LCN_PreJudgeLCN();
			LCN_QueryLCNConflict(&g_LcnConf);
			LCN_PostJudgeLCN();
	        LCN_AutoAssignConflictLCN();
	        LCN_FreeLCNConflict();
			LCN_FreeTRNDDictionary();
	    }
	}
	else
#endif
	if (bForceAutoProc == al_false && eNetType == AL_DBTYPE_DVB_T)
	{
	#ifdef SUPPORT_GHANA_LCN
		if( u8Country==AREA_GHANA && LCN_MultiChnList_GetValidCnt()>=2 )
		{
			return al_true;
		}
	#endif

#ifdef SUPPORT_THAILAND_EVORA
		if(u8Country == AREA_THAILAND && LCN_MultiChnList_GetValidCnt() >= 2)
		{
			return al_true;
		}
#endif
#ifdef CONFIG_SUPPORT_MALAYSIA_CERTIFICATION
        if(u8Country ==  AREA_MALAYSIA && LCN_MultiChnList_GetValidCnt() >= 2)
        {
            return al_true;
        }
#endif
		LCN_PreJudgeLCN();
		LCN_QueryLCNConflict(&g_LcnConf);

		if (g_LcnConf.ConfCount > 0)
		{
#ifdef CONFIG_DVB_SYSTEM
			if (u8Country == AREA_ITALY)
			{
#ifdef SUPPORT_LCN_CONFLICT_MENU
				return al_true;
#else
				LCN_AutoAssignConflictLCN();
#endif
			}
#ifdef SUPPORT_TRD
			else if (u8Country == AREA_ENGLAND)
			{
				if (DB_SUCCESS == LCN_GetTRNDDictionary(&pTRDDictionary))
				{
					return al_true;
				}
				else
				{
					LCN_AutoAssignConflictLCN();
				}
			}
#endif
			else
#endif
			{
				LCN_AutoAssignConflictLCN();
			}
		}

		LCN_PostJudgeLCN();
	}
    //zhongbaoxing added for mantis 0172272 @20120310 +++
    else
    {
		LCN_PreJudgeLCN();
		LCN_QueryLCNConflict(&g_LcnConf);
		LCN_PostJudgeLCN();
        LCN_AutoAssignConflictLCN();
        LCN_FreeLCNConflict();
		LCN_FreeTRNDDictionary();
    }
    //zhongbaoxing added for mantis 0172272 @20120310 ---

	return al_false;
}
#endif

/**
* @brief Start the channel search function.
*
* @param input_params[input] the start params of channel search function.
*
* @param search_start[input] Initilize callback function called.
*
* @param search_over[input] Uninitilize callback function.
*
* @param search_update[input] Update callback function used to update UI display.
*
* @param search_save[input] save program into database function.
*
* @return AL_SUCCESS start channel search is successful, AL_FAILURE otherwise.
*/
AL_Return_t AL_CS_Start(al_cs_input_params_st* input_params,
	al_cs_search_start_st search_start,
	al_cs_search_over_st search_over,
	al_cs_search_update_st search_update,
	al_cs_search_save_st search_save)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
#ifdef CONFIG_ATV_SUPPORT
	AL_Channel_Info_st* pstAnalogInput = NULL;
#endif

	CS_DEBUG_MESSAGE("Enter %s\n",__FUNCTION__);

	if (pstInfo->enState != CS_STATE_IDLE)
	{
		CS_DEBUG_MESSAGE("The CS has initial\n");
		return AL_FAILURE;
	}

	if (NULL == input_params
		|| (input_params->enCsType >= AL_CS_TYPE_MAX
		|| input_params->enCsType <= AL_CS_TYPE_MIN))
	{
		CS_DEBUG_MESSAGE("CS invalid params\n");
		return AL_FAILURE;
	}

	memset(pstInfo, 0, sizeof(cs_info_st));
	pstInfo->enType			= input_params->enCsType;
	pstInfo->pfStart 		= search_start;
	pstInfo->pfOver 		= search_over;
	pstInfo->pfUpdate		= search_update;
	pstInfo->pfSave 		= search_save;
	pstInfo->uiCapabilities = input_params->uiCapabilities;

	if (AL_CS_TYPE_ANALOG == input_params->enCsType
		|| AL_CS_TYPE_ANALOG_MANUAL == input_params->enCsType
		|| AL_CS_TYPE_ANALOG_TABLE == input_params->enCsType)
	{
#ifdef CONFIG_ATV_SUPPORT
        #if 0
        DRV_RfFrontend_Status_t tStatus;
		FrontendCmd_t  front;
		front.cmd = FRONTEND_CMD_QUERY_SETTINGS;
		front.param = &tStatus;
		ioctl(kmfdev, KMF_IOC_FRONTENDCTRL , &front);
        #endif
		pstAnalogInput = &pstInfo->unScanData.analog.stInput;
		if (AL_CS_TYPE_ANALOG_TABLE == input_params->enCsType)
		{
			pstAnalogInput->StartFreq = input_params->uiStartFreq;
			pstAnalogInput->EndFreq =  input_params->uiEndFreq;
		}
		else
		{
			pstAnalogInput->StartFreq = (0 == input_params->uiStartFreq) ?
					ATV_SCAN_RANGE_MIN : input_params->uiStartFreq;

			pstAnalogInput->EndFreq = (0 == input_params->uiEndFreq) ?
					ATV_SCAN_RANGE_MAX : input_params->uiEndFreq;

	        pstAnalogInput->CurrFreq = (ATV_SCAN_RANGE_MIN > input_params->uiCurrentFreq) ?
					ATV_SCAN_RANGE_MIN : input_params->uiCurrentFreq;
		}
		if (AL_CS_TYPE_ANALOG_TABLE == input_params->enCsType)
		{
			pstAnalogInput->BandWidth = 6;
		}
		else
		{
			pstAnalogInput->BandWidth = (0 == input_params->stBandwidth.eBandWidth.BaseBandWidth) ?
				GET_DEFAULT_BANDWIDTH() : input_params->stBandwidth.eBandWidth.BaseBandWidth;
		}
		pstAnalogInput->BandWidth *= 1000000;

		pstInfo->unScanData.analog.iDirection = (input_params->u.atv.uiDirection) ? -1 : 1;

		pstAnalogInput->TblLen = input_params->u.atv.uiScanCnt;
		pstAnalogInput->CurTblIdx = 0;
		pstAnalogInput->Manual_Num = input_params->u.atv.Manual_Num;
		pstAnalogInput->pTbl = input_params->u.atv.puiScanTable;
		pstAnalogInput->ucAreaIdx = input_params->u.atv.ucAreaIdx;
		pstAnalogInput->ucBlueScreen = input_params->u.atv.ucBlueScreen;
		pstAnalogInput->Video_format = input_params->u.atv.VideoFormat;
		pstAnalogInput->Audio_std= input_params->u.atv.AudioStd;
#endif
	}
	else if (AL_CS_TYPE_DIGITAL == input_params->enCsType
		|| AL_CS_TYPE_DIGITAL_MANUAL == input_params->enCsType)
	{
#ifdef CONFIG_DTV_SUPPORT
		pstInfo->unScanData.digital.ucAreaIdx = input_params->u.dtv.ucAreaIdx;
		if (AL_CS_TUNER_OFDM == input_params->u.dtv.enTunerType || AL_CS_TUNER_TDS_OFDM == input_params->u.dtv.enTunerType)
		{
#if defined CONFIG_DVB_SYSTEM
			pstInfo->unScanData.digital.enTunerType = TUNER_OFDM;
#elif defined CONFIG_DTMB_SYSTEM
            pstInfo->unScanData.digital.enTunerType = TUNER_TDS_OFDM;
#endif
			if ((input_params->u.dtv.dvbt2mode & AL_SCAN_DVB_T_T2_TOGETHER_MODE)
				||((input_params->u.dtv.dvbt2mode & AL_SCAN_ONLY_DVBT)||(input_params->u.dtv.dvbt2mode & AL_SCAN_ONLY_DVBT2)))
			{
				pstInfo->uiCapabilities |= MID_SCAN_CAPS_SUPPORT_DVB_T2_IMMEDIATE;
				pstInfo->uiCapabilities &= ~ MID_SCAN_CAPS_SUPPORT_DVB_T2_LATER;
			}
			else if (input_params->u.dtv.dvbt2mode & AL_SCAN_DVB_T_T2_SEPARATE_MODE)
			{
				pstInfo->uiCapabilities |= MID_SCAN_CAPS_SUPPORT_DVB_T2_LATER;
				pstInfo->uiCapabilities &= ~ MID_SCAN_CAPS_SUPPORT_DVB_T2_IMMEDIATE;
			}
			else
			{
				pstInfo->uiCapabilities &= ~ MID_SCAN_CAPS_SUPPORT_DVB_T2_IMMEDIATE;
				pstInfo->uiCapabilities &= ~ MID_SCAN_CAPS_SUPPORT_DVB_T2_LATER;
			}
		}
		else if (AL_CS_TUNER_QPSK == input_params->u.dtv.enTunerType)
		{
			pstInfo->unScanData.digital.enTunerType = TUNER_QPSK;
			if (input_params->uiCapabilities & AL_CS_SUPPORT_GET_FREQ_FROM_NIT)
			{
				pstInfo->uiCapabilities |= AL_CS_SUPPORT_GET_FREQ_FROM_NIT;
			}
			else
			{
				pstInfo->uiCapabilities &= ~AL_CS_SUPPORT_GET_FREQ_FROM_NIT;
			}
		}
		else if (AL_CS_TUNER_QAM == input_params->u.dtv.enTunerType)
		{
			pstInfo->unScanData.digital.enTunerType = TUNER_QAM;
			NetworkScanNeedAbortScan = al_false;
			ServiceNetworkId = 0;
		}
		else if (AL_CS_TUNER_BST_OFDM == input_params->u.dtv.enTunerType)
		{
			pstInfo->unScanData.digital.enTunerType = TUNER_BST_OFDM;
		}

		pstInfo->ucGotNITFlag = CABLE_GET_NIT_STOP;
		if (pstInfo->uiCapabilities & AL_CS_SUPPORT_GET_FREQ_FROM_NIT)
		{
			pstInfo->ucGotNITFlag = CABLE_GET_NIT_DETECT;
		}

		if (AL_CS_TYPE_DIGITAL == input_params->enCsType)
		{
			geTuneType = AL_DB_AUTO_SEARCH;

			if (AL_SUCCESS != CS_DigitalAutoSearchInit(input_params))
			{
				return AL_FAILURE;
			}
		}
		else
		{
			geTuneType = AL_DB_MANUAL_SEARCH;
			if (AL_SUCCESS != CS_DigitalManualSearchInit(input_params))
			{
				return AL_FAILURE;
			}
		}

		if (AL_SUCCESS != AL_DB_RegisterDupliRecStrategy(NULL, &geTuneType, &gePriSpec))
		{
			return AL_FAILURE;
		}
#endif
	}
	else if (AL_CS_TYPE_DIGITAL_BLIND == input_params->enCsType)
	{
#ifdef CONFIG_DTV_SUPPORT
		pstInfo->unScanData.digital.ucAreaIdx = input_params->u.dtv.ucAreaIdx;
		if (AL_CS_TUNER_OFDM == input_params->u.dtv.enTunerType)
		{
		}
		else if (AL_CS_TUNER_QPSK == input_params->u.dtv.enTunerType)
		{
			pstInfo->unScanData.digital.enTunerType = TUNER_QPSK;
			if (input_params->uiCapabilities & AL_CS_SUPPORT_GET_FREQ_FROM_NIT)
			{
				pstInfo->uiCapabilities |= AL_CS_SUPPORT_GET_FREQ_FROM_NIT;
			}
			else
			{
				pstInfo->uiCapabilities &= ~AL_CS_SUPPORT_GET_FREQ_FROM_NIT;
			}
			if (input_params->uiCapabilities & AL_CS_SUPPORT_STEP_BLIND_SCAN)
			{
				pstInfo->uiCapabilities |= AL_CS_SUPPORT_STEP_BLIND_SCAN;
			}
			else
			{
				pstInfo->uiCapabilities &= ~AL_CS_SUPPORT_STEP_BLIND_SCAN;
			}
		}
		else if (AL_CS_TUNER_QAM == input_params->u.dtv.enTunerType)
		{
		}
		else if (AL_CS_TUNER_BST_OFDM == input_params->u.dtv.enTunerType)
		{
		}

		pstInfo->ucGotNITFlag = CABLE_GET_NIT_STOP;
		if (pstInfo->uiCapabilities & AL_CS_SUPPORT_GET_FREQ_FROM_NIT)
		{
			pstInfo->ucGotNITFlag = CABLE_GET_NIT_DETECT;
		}

		geTuneType = AL_DB_AUTO_SEARCH;

		if (AL_SUCCESS != CS_DigitalBlindSearchInit(input_params))
		{
			return AL_FAILURE;
		}

		if (AL_SUCCESS != AL_DB_RegisterDupliRecStrategy(NULL, &geTuneType, &gePriSpec))
		{
			return AL_FAILURE;
		}
#endif
	}
	else if (AL_CS_TYPE_ACI == input_params->enCsType)
	{

	}

	if (GL_SUCCESS !=
		GL_QueueCreate("SearchAppThreadQueue", sizeof(cs_msg_st), 20, 1, &pstInfo->pstQueue))
	{
		CS_DEBUG_MESSAGE("CS create queue fail\n");
		return AL_FAILURE;
	}

	if (GL_SUCCESS != GL_SemaphoreCreate("ScanAppSemaphore", 1, 0, &pstInfo->pstSemaphore))
	{
		CS_DEBUG_MESSAGE("CS create Semaphore fail\n");
		return AL_FAILURE;
	}
	if (GL_SUCCESS == GL_TaskCreate(GET_SEARCH_THREAD_NAME(), CS_SearchAppThread,
			NULL, 5, 4096, FALSE, &dummy_channel_search_TaskHandle))
	{
		if (GL_SUCCESS == GL_TaskActivate(dummy_channel_search_TaskHandle))
		{
			if (pstInfo->pstSemaphore)
			{
				// waiting for scan thread start running
				GL_SemaphoreTake(pstInfo->pstSemaphore, GL_INFINITE_WAIT);
			}
			CS_DEBUG_MESSAGE("Exit %s\n",__FUNCTION__);
			return AL_SUCCESS;
		}
	}

	GL_QueueDelete(pstInfo->pstQueue);
	pstInfo->pstQueue = NULL;

	return AL_FAILURE;
}

#ifdef CONFIG_ATV_SUPPORT
/**
* @brief Set the search direction mainly used in ATV.
*
* @param direction[input] zero for positive, or other for negative.
*
* @return AL_SUCCESS set search direction is successful, AL_FAILURE otherwise.
*/
AL_Return_t AL_CS_SetSearchDirection(al_int32 direction)
{
	cs_info_st* pstInfo =  GET_CS_INFO();

	CS_DEBUG_MESSAGE("Enter %s\n",__FUNCTION__);

	if (CS_STATE_IDLE == pstInfo->enState
		|| AL_CS_TYPE_ANALOG_MANUAL != pstInfo->enType)
	{
		return AL_SUCCESS;
	}

	pstInfo->unScanData.analog.iDirection =
		(direction) ? -1 : 1;

	if (pstInfo->unScanData.analog.iDirection > 0)
 	{
		MID_AnalogTVScanSetDirection(ANA_SCAN_DIRECTION_POSITIVE);
 	}
 	else
 	{
		MID_AnalogTVScanSetDirection(ANA_SCAN_DIRECTION_NEGTIVE);
 	}

	CS_DEBUG_MESSAGE("Exit %s\n",__FUNCTION__);

	return AL_SUCCESS;
}
#endif

/**
* @brief Send message to stop the channel search flow.
*
* @return AL_SUCCESS stop channel search is successful, AL_FAILURE otherwise.
*/
AL_Return_t AL_CS_Stop(void)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
	cs_msg_st msg;

	CS_DEBUG_MESSAGE("Enter %s\n",__FUNCTION__);

	if ((NULL == pstInfo->pstQueue) ||
		(NULL == pstInfo->pstSemaphore))
	{
		return AL_SUCCESS;
	}

	msg.enType = CS_MSG_TYPE_ABORT;
	msg.uiParams = 0;

	GL_QueueSendUrgent(pstInfo->pstQueue,
		(void *)&msg, sizeof(cs_msg_st));

	if (pstInfo->pstSemaphore)
	{
		// waiting for scan thread stop
		GL_SemaphoreTake(pstInfo->pstSemaphore, GL_INFINITE_WAIT);
		GL_SemaphoreDelete(pstInfo->pstSemaphore);
		pstInfo->pstSemaphore = al_null;
	}

	CS_DEBUG_MESSAGE("Exit %s\n",__FUNCTION__);

	return AL_SUCCESS;
}

/**
* @brief Send message to pause the search flow.
*
* @return AL_SUCCESS channel search pause is success, AL_FAILURE otherwise.
*/
AL_Return_t AL_CS_Pause(void)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
	cs_msg_st msg;

	CS_DEBUG_MESSAGE("Enter %s\n",__FUNCTION__);

	if ((CS_STATE_IDLE == pstInfo->enState) ||
		(NULL == pstInfo->pstQueue) ||
		(NULL == pstInfo->pstSemaphore))
	{
		return AL_SUCCESS;
	}

	msg.enType = CS_MSG_TYPE_PAUSE;
	msg.uiParams = 0;

	GL_QueueSendUrgent(pstInfo->pstQueue,
		(void *)&msg, sizeof(cs_msg_st));

	if (pstInfo->pstSemaphore)
	{
		GL_SemaphoreTake(pstInfo->pstSemaphore, GL_INFINITE_WAIT);
	}

	CS_DEBUG_MESSAGE("Exit %s\n",__FUNCTION__);

	return AL_SUCCESS;
}

/**
* @brief Send message to resume the search flow.
*
* @return AL_SUCCESS channel search resume is success, AL_FAILURE otherwise.
*/
AL_Return_t AL_CS_Resume(void)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
	cs_msg_st msg;

	if ((CS_STATE_IDLE == pstInfo->enState) ||
		(NULL == pstInfo->pstQueue) ||
		(NULL == pstInfo->pstSemaphore))
	{
		return AL_SUCCESS;
	}

	msg.enType = CS_MSG_TYPE_RESUME;
	msg.uiParams = 0;

	GL_QueueSendUrgent(pstInfo->pstQueue,
		(void *)&msg, sizeof(cs_msg_st));

	if (pstInfo->pstSemaphore)
	{
		GL_SemaphoreTake(pstInfo->pstSemaphore, GL_INFINITE_WAIT);
	}

	CS_DEBUG_MESSAGE("Exit %s\n",__FUNCTION__);

	return AL_SUCCESS;
}

/**
* @brief Is the channel search module stop or not.
*
* @return al_true channel search is stoped, al_false channel search is not stoped.
*/
al_bool AL_CS_IsStop(void)
{
	cs_info_st* pstInfo =  GET_CS_INFO();

	return (pstInfo->bContinue == FALSE);
}

al_bool AL_CS_IsStopFinish(void)
{
	cs_info_st* pstInfo =  GET_CS_INFO();

	return (pstInfo->enState == CS_STATE_IDLE);
}

al_uint16 AL_CS_AtvCurIdx(void)
{
    cs_info_st* pstInfo =  GET_CS_INFO();

    return pstInfo->stSearchInfo.u.atv.usCurChaInx;
}
#ifdef CONFIG_SUPPORT_ATV_SCAN_NTSCM_PALM_N
al_bool AL_CS_UpdateParam(al_cs_input_params_st* input_params,al_uint32 i)
{
	cs_info_st* pstInfo =  GET_CS_INFO();
	AL_Channel_Info_st* pstAnalogInput = NULL;

	pstAnalogInput = &pstInfo->unScanData.analog.stInput;
	pstAnalogInput->TblLen = input_params->u.atv.uiScanCnt;
	pstAnalogInput->pTbl = input_params->u.atv.puiScanTable;
	pstInfo->stSearchInfo.usTVCnt = pstAnalogInput->TblLen;
	pstInfo->stSearchInfo.u.atv.usCurChaInx = i;
	pstAnalogInput->CurTblIdx = i+1;
	return AL_SUCCESS;
}
#endif
#ifdef CONFIG_DTV_SUPPORT
/*****************************************************************************
** FUNCTION : AL_CS_DtvMinBW
**
** DESCRIPTION : Get BW of special area
**
**
** PARAMETERS :
**              stBW - BW struct
**				pbBW - BW
**
** RETURN VALUES:
**				AL_FAILURE - operation failure
**				AL_SUCCESS - operation success
*****************************************************************************/
AL_Return_t AL_CS_DtvMinBW(AL_BandWidth_Info_st stBW, al_uint8 *pbBW)
{
	if (NULL == pbBW)
	{
		return AL_FAILURE;
	}

	if (stBW.eBandWidth.BandWidthSWEn)
	{
		if (stBW.eBandWidth.BandWidth6MEn)
		{
			*pbBW = BANDWIDTH_6_MHZ;
		}
		else if (stBW.eBandWidth.BandWidth7MEn)
		{
			*pbBW = BANDWIDTH_7_MHZ;
		}
		else if (stBW.eBandWidth.BandWidth8MEn)
		{
			*pbBW = BANDWIDTH_8_MHZ;
		}
	}
	else
	{
		*pbBW = stBW.eBandWidth.BaseBandWidth;
	}

	return AL_SUCCESS;
}

/*****************************************************************************
** FUNCTION : AL_CS_DtvMaxBW
**
** DESCRIPTION : Get BW of special area
**
**
** PARAMETERS :
**              stBW - BW struct
**				pbBW - BW
**
** RETURN VALUES:
**				AL_FAILURE - operation failure
**				AL_SUCCESS - operation success
*****************************************************************************/
AL_Return_t AL_CS_DtvMaxBW(AL_BandWidth_Info_st stBW, al_uint8 *pbBW)
{
	if (NULL == pbBW)
	{
		return AL_FAILURE;
	}

	if (stBW.eBandWidth.BandWidthSWEn)
	{
		if (stBW.eBandWidth.BandWidth8MEn)
		{
			*pbBW = BANDWIDTH_8_MHZ;
		}
		else if (stBW.eBandWidth.BandWidth7MEn)
		{
			*pbBW = BANDWIDTH_7_MHZ;
		}
		else if (stBW.eBandWidth.BandWidth6MEn)
		{
			*pbBW = BANDWIDTH_6_MHZ;
		}
	}
	else
	{
		*pbBW = stBW.eBandWidth.BaseBandWidth;
	}

	return AL_SUCCESS;
}

/*****************************************************************************
** FUNCTION : AL_CS_DtvNextBW
**
** DESCRIPTION : Get BW of special area
**
**
** PARAMETERS :
**              stBW - BW struct
**				pbBW - BW
**              bDirect - search direct
**
** RETURN VALUES:
**				AL_FAILURE - operation failure
**				AL_SUCCESS - operation success
*****************************************************************************/
AL_Return_t AL_CS_DtvNextBW(AL_BandWidth_Info_st stBW, al_uint8 *pbBW, INT8 bDirect)
{
	if (NULL == pbBW)
	{
		return AL_FAILURE;
	}

	if (stBW.eBandWidth.BandWidthSWEn)
	{
        if (bDirect == 1)
        {
            if ((stBW.eBandWidth.BandWidth6MEn) && (*pbBW == BANDWIDTH_6_MHZ))
            {
                if (stBW.eBandWidth.BandWidth7MEn)
                {
                    *pbBW = BANDWIDTH_7_MHZ;
                    return AL_SUCCESS;
                }
                else if (stBW.eBandWidth.BandWidth8MEn)
                {
                    *pbBW = BANDWIDTH_8_MHZ;
                    return AL_SUCCESS;
                }
            }
            else if ((stBW.eBandWidth.BandWidth7MEn) && (*pbBW == BANDWIDTH_7_MHZ))
            {
                if (stBW.eBandWidth.BandWidth8MEn)
                {
                    *pbBW = BANDWIDTH_8_MHZ;
                    return AL_SUCCESS;
                }
            }
            else if ((stBW.eBandWidth.BandWidth8MEn) && (*pbBW == BANDWIDTH_8_MHZ))
            {
                return AL_FAILURE;
            }
        }
		else if (bDirect == -1)
		{
			if ((stBW.eBandWidth.BandWidth8MEn) && (*pbBW == BANDWIDTH_8_MHZ))
			{
				if (stBW.eBandWidth.BandWidth7MEn)
				{
					*pbBW = BANDWIDTH_7_MHZ;
					return AL_SUCCESS;
				}
				else if (stBW.eBandWidth.BandWidth6MEn)
				{
					*pbBW = BANDWIDTH_6_MHZ;
					return AL_SUCCESS;
				}
			}
			else if ((stBW.eBandWidth.BandWidth7MEn) && (*pbBW == BANDWIDTH_7_MHZ))
			{
				if (stBW.eBandWidth.BandWidth6MEn)
				{
					*pbBW = BANDWIDTH_6_MHZ;
					return AL_SUCCESS;
				}
			}
			else if ((stBW.eBandWidth.BandWidth6MEn) && (*pbBW == BANDWIDTH_6_MHZ))
			{
				return AL_FAILURE;
			}
		}
	}

	return AL_FAILURE;
}

/*****************************************************************************
** FUNCTION : AL_CS_DtvSetSpecialSpec
**
** DESCRIPTION : set special spec
**
**
** PARAMETERS :
**              ePriSpec - DVB private special spec
**
** RETURN VALUES:
**				AL_FAILURE - operation failure
**				AL_SUCCESS - operation success
*****************************************************************************/
AL_Return_t AL_CS_DtvSetSpecialSpec(AL_DBPrivateSpec_t ePriSpec)
{
	gePriSpec = ePriSpec;
	return AL_SUCCESS;
}

AL_DBPrivateSpec_t AL_CS_DtvGetSpecialSpec(void)
{
	return gePriSpec;
}

al_void AL_CS_SetOperatorQueryFunc(al_cs_search_query_operator search_query_op)
{
	pfQueryOperatorFunc = search_query_op;
}
#endif
/*****************************************************************************
** $Rev$
**
*****************************************************************************/

