/******************************************************************************
 ** File Name : al_service.c
 **
 ** Description:	Gives the functionalities for quering as well as manipulating the
 **					middleware database on service related data.
 **
** Copyright(c) 2011 Sunmedia Technologies - All Rights Reserved
**
** Author : kun.dai
**
** $Id$
 ******************************************************************************/
/******************************************************************************
 *	Include Files
 ******************************************************************************/
#include "al_service.h"
#include "ai_database.h"
#include "al_event.h"
#include "al_fw.h"
#include "ai_tp_list.h"
#include "app_prog_list.h"
#include "unicode.h"
/******************************************************************************
 *	Macros
 ******************************************************************************/
#define SRV_CHECKTYPE(type, typeEnum) ((typeEnum) == ((type) & (typeEnum)))
#define DIFFER(X,Y)   ((X)>(Y) ? ((X)-(Y)) : (Y)-(X))

/******************************************************************************
 *	Global Variables
 ******************************************************************************/
static al_bool g_bInitFlag = al_false;
static TpListHdl_st g_stItemList = 0;



#ifdef CONFIG_ISDB_SYSTEM
static APP_AtvDb_Type atv_database_type = ATVDB_AIR;
static al_bool atv_care_valid = al_true;
/*
 * global function
 */
void APP_Database_SwitchATVDB(APP_AtvDb_Type type)
{
    atv_database_type = type;
}

void APP_Database_SetCareIsValid(al_bool care)
{
    atv_care_valid = care;
}
#endif

#ifdef CONFIG_SUPPORT_ATV_SCAN_NTSCM_PALM_N
static APP_AtvDb_Type atv_database_type = ATVDB_AIR;
static al_bool atv_care_valid = al_true;
/*
 * global function
 */
void APP_Database_SwitchATVDB(APP_AtvDb_Type type)
{
    atv_database_type = type;
}

void APP_Database_SetCareIsValid(al_bool care)
{
    atv_care_valid = care;
}
#endif

/******************************************************************************
 *	Service Component APIs
 ******************************************************************************/
/****************************************************//**
 * @brief Initialize service component.
 *
 * The implementation may perform appropriate service initialisation when this
 * call is made, if required.
 *
 * @note
 *		1.This API must be called before any service-related function is called; <br>
 * 		2.Must be called once successfully, and still return success when called again.
 *
 * @param eDBType [in]select one or more database to initialize service component.
 *
 * @return
 * 	#AL_SUCCESS indicates success,
 * 	On failure, #AL_FAILURE is returned.
 ********************************************************/
AL_Return_t AI_Service_Init(AL_DB_EDBType_t eDBType)
{
	if (!g_bInitFlag)
	{
		g_bInitFlag = al_true;
	}

	return AL_SUCCESS;
}


/****************************************************//**
 * @brief Terminate service commponent.
 *
 * The implementation may perform appropriate service termination when this
 * call is made, if required.
 *
 * @note
 * 		1.This API must be called after any service-related function is called, <br>
 * 		2.Must be called once successfully, and still return success when called again.
 *
 * @param eDBType [in]Select one or more database to terminate service component.
 *
 * @return
 * 	#AL_SUCCESS indicates success,
 * 	On failure, #AL_FAILURE is returned.
 *
 ********************************************************/
AL_Return_t AI_Service_Term(AL_DB_EDBType_t eDBType)
{
	if (g_bInitFlag)
	{
		g_bInitFlag = al_false;
	}

	return AL_SUCCESS;
}

static al_bool AL_Cmp_Bycustermer(UINT8 *cmp_str,UINT8 *TempName,UINT32 len1,UINT32 len2,UINT32 len)
{
	/*    此比對忽略大小寫 遇到ascii之外的一律比對成功	*/
	//TempName -> enter by keyborad
	//cmp_str -> string in database
	al_bool ret = TRUE;  // True: match failed  and  False: match success
	UINT32 i=0;
	UINT16* tmp_16=NULL;
	UINT16* ProgName_16=NULL;
	{
		tmp_16 = malloc(2*DB_DVB_MAX_CHNAME_LEN);
		if (tmp_16 == NULL)
		{
			return ret;
		}
		ProgName_16 = malloc(2*DB_DVB_MAX_CHNAME_LEN);
		if (ProgName_16 == NULL)
		{
			free(tmp_16);
			return ret;
		}
		memset(tmp_16, 0, 2*DB_DVB_MAX_CHNAME_LEN);
		memset(ProgName_16, 0, 2*DB_DVB_MAX_CHNAME_LEN);

		for(i=0;i<len1;i++)
		{
			if (UNI_Utf82Utf16(TempName+i,tmp_16+i) <= 0)
			{
				printf("[%s:%d] error len!!\n",__FUNCTION__,__LINE__);
			}
		}
		for(i=0;i<len2;i++)
		{
			if (UNI_Utf82Utf16(cmp_str+i,ProgName_16+i) <= 0)
			{
				printf("[%s:%d] error len!!\n",__FUNCTION__,__LINE__);
			}
		}

		// 65=="A" 90=="Z" 97=="a" 122=="z"
		for(i=0;i<len;i++)
		{

			if(tmp_16[i] == ProgName_16[i])
			{
				ret = FALSE;
			}
			else if(tmp_16[i]>=65 && tmp_16[i]<=90)
			{
				if(ProgName_16[i]>=97 && ProgName_16[i]<=122)
				{
					if(ProgName_16[i] - tmp_16[i] == 0x20)
					{
						ret = FALSE;
					}
					else
					{
						ret =TRUE ;
						break;
					}
				}
				else
				{
					ret = TRUE;
					break;
				}
			}
			else if(tmp_16[i]>=97 && tmp_16[i]<=122)
			{
				if(ProgName_16[i]>=65 && ProgName_16[i]<=90)
				{
					if(tmp_16[i] - ProgName_16[i] == 0x20)
					{
						ret = FALSE;
					}
					else
					{
						ret =TRUE ;
						break;
					}
				}
				else
				{
					ret = TRUE;
					break;
				}
			}
			else
			{
				ret =TRUE ;
				break;
			}

		}

		free(tmp_16);
		free(ProgName_16);
	}
	return ret;
}

/****************************************************//**
 * @brief Match service by specified attribute flag.
 *
 * @note Refers to the prototype #AL_DB_RecordMatchFunc.
 *
 * @param param		[in]Service attributes filter, type: #AL_Serv_AttribFilter_t.
 * @param pRec		[in]Servie Info.
 *
 * @return
 * 	#AL_SUCCESS indicates success,
 * 	On failure, #AL_FAILURE is returned.
 ********************************************************/
al_bool AL_Serv_MatchRecByAttribute(al_void *param, al_void const*pRec)
{
	if (al_null == param || al_null == pRec)
	{
		return al_false;
	}

	AL_Serv_AttribFilter_t stFilter;
	DBServAttrib_t stAttribute;

	memset(&stFilter, 0, sizeof(AL_Serv_AttribFilter_t));
	memset(&stAttribute, 0, sizeof(DBServAttrib_t));
	memcpy(&stFilter, param, sizeof(AL_Serv_AttribFilter_t));

	if ((AL_DBTYPE_DVB_T == stFilter.eDBType)
		|| (AL_DBTYPE_DVB_C == stFilter.eDBType)
		|| (AL_DBTYPE_DVB_S == stFilter.eDBType)
		#ifdef CONFIG_ISDB_SYSTEM
		|| (AL_DBTYPE_DVB_SBTVD == stFilter.eDBType)
		#endif
	)
	{
		if (AL_DBTYPE_DVB_T == stFilter.eDBType)
		{
			if (!(((STDBServInfo_t *)pRec)->eTvRadioType & stFilter.eRecType))
			{
				return al_false;
			}
			memcpy(&stAttribute, &((STDBServInfo_t *)pRec)->stProgAttrib, sizeof(DBServAttrib_t));
			if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_PROGNAMEMATCH))
			{
				UINT8 len1 = strlen((char *)((STDBServInfo_t *)pRec)->szProgName);
				UINT8 len2 = strlen((char *)stFilter.szProgName);
				UINT8 len = len1 < len2 ? len1 : len2;
				UINT8 ret = 0;
				if (((STDBServInfo_t *)pRec)->szProgName[0] < 0x20)
				{
					if (len1 <= len2)
					{
						return al_false;
					}
					ret = strncasecmp((char *)&((STDBServInfo_t *)pRec)->szProgName[1], (char *)stFilter.szProgName, len);
				}
				else
				{
					if (len1 < len2)
					{
						return al_false;
					}
					ret = strncasecmp((char *)((STDBServInfo_t *)pRec)->szProgName, (char *)stFilter.szProgName, len);
				}
				if (ret != 0)
				{
					return al_false;
				}
			}
		}
		else if (AL_DBTYPE_DVB_C == stFilter.eDBType)
		{
			if (!(((SCDBServInfo_t *)pRec)->eTvRadioType & stFilter.eRecType))
			{
				return al_false;
			}
			memcpy(&stAttribute, &((SCDBServInfo_t *)pRec)->stProgAttrib, sizeof(DBServAttrib_t));
			if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_PROGNAMEMATCH))
			{
				UINT8 len1 = strlen((char *)((SCDBServInfo_t *)pRec)->szProgName);
				UINT8 len2 = strlen((char *)stFilter.szProgName);
				UINT8 len = len1 < len2 ? len1 : len2;
				UINT8 ret = 0;
				if (((SCDBServInfo_t *)pRec)->szProgName[0] < 0x20)
				{
					if (len1 <= len2)
					{
						return al_false;
					}
					ret = strncasecmp((char *)&((SCDBServInfo_t *)pRec)->szProgName[1], (char *)stFilter.szProgName, len);
				}
				else
				{
					if (len1 < len2)
					{
						return al_false;
					}
					ret = strncasecmp((char *)((SCDBServInfo_t *)pRec)->szProgName, (char *)stFilter.szProgName, len);
				}
				if (ret != 0)
				{
					return al_false;
				}
			}
		}
		else if (AL_DBTYPE_DVB_S == stFilter.eDBType)
		{
			if (!(((SDBServInfo_t *)pRec)->eTvRadioType & stFilter.eRecType))
			{
				return al_false;
			}
			memcpy(&stAttribute, &((SDBServInfo_t *)pRec)->stProgAttrib, sizeof(DBServAttrib_t));
			if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_PROGNAMEMATCH))
			{
				UINT8 len1 = strlen((char *)((SDBServInfo_t *)pRec)->szProgName);
				UINT8 len2 = strlen((char *)stFilter.szProgName);
				UINT8 len = len1 < len2 ? len1 : len2;
				UINT8 ret = 0;
                UINT8 TempName[DB_DVB_MAX_CHNAME_LEN];
				memset(TempName,0x0,sizeof(TempName));
				memcpy(TempName,((SDBServInfo_t *)pRec)->szProgName,len1);
#ifdef SUPPORT_FILTER_CH_BY_NAME
				if (APP_ProgList_GetChnName())
				{
					UINT8 i = 0;
					UINT8 j = 0;
					for(i=0;i<len1;i++)
					{
						if(TempName[i] == 0x86)//CHAR_EMPHASIS_ON
						{
							for(j=i;j<len1;j++)
							{
								if((TempName[j] == 0x86)//The next, may be the previous is not the correct one
									&&(j > i))
								{
									i = j;
								}
								if(TempName[j] == 0x87)//CHAR_EMPHASIS_OFF
								{
									memcpy(&TempName[i],&TempName[i+1],(len1 - i));
									memcpy(&TempName[j - 1],&TempName[j],(len1 - j));
									len1 = len1 - 2;
								}
							}
						}
					}
				}
#endif
				if (TempName[0] < 0x20)
				{
					if (len1 <= len2)
					{
						return al_false;
					}
					#if 1
					ret = AL_Cmp_Bycustermer((UINT8 *)&TempName[1],stFilter.szProgName,len1,len2,len);
					#else
					ret = strncasecmp((char *)&TempName[1], (char *)stFilter.szProgName, len);
					#endif
				}
				else
				{
					if (len1 < len2)
					{
						return al_false;
					}
					#if 1
					ret = AL_Cmp_Bycustermer(TempName,stFilter.szProgName,len1,len2,len);
					#else
					ret = strncasecmp((char *)TempName, (char *)stFilter.szProgName, len);
					#endif
				}
				if (ret != 0)
				{
					return al_false;
				}
			}
		}
		#ifdef CONFIG_ISDB_SYSTEM
		else if (AL_DBTYPE_DVB_SBTVD == stFilter.eDBType)
		{
			if (!(((SSBTVDDBServInfo_t *)pRec)->eTvRadioType & stFilter.eRecType))
			{
				return al_false;
			}
			memcpy(&stAttribute, &((SSBTVDDBServInfo_t *)pRec)->stProgAttrib, sizeof(DBServAttrib_t));
		}
		#endif

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_FAV1)
			&& (1 != stAttribute.fav1))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_FAV1)
			&& (0 != stAttribute.fav1))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_FAV2)
			&& (1 != stAttribute.fav2))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_FAV2)
			&& (0 != stAttribute.fav2))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_FAV3)
			&& (1 != stAttribute.fav3))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_FAV3)
			&& (0 != stAttribute.fav3))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_FAV4)
			&& (1 != stAttribute.fav4))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_FAV4)
			&& (0 != stAttribute.fav4))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_FAV5)
			&& (1 != stAttribute.fav5))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_FAV5)
			&& (0 != stAttribute.fav5))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_FAV6)
			&& (1 != stAttribute.fav6))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_FAV6)
			&& (0 != stAttribute.fav6))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_FAV7)
			&& (1 != stAttribute.fav7))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_FAV7)
			&& (0 != stAttribute.fav7))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_FAV8)
			&& (1 != stAttribute.fav8))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_FAV8)
			&& (0 != stAttribute.fav8))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_MOVE)
			&& (1 != stAttribute.move))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_MOVE)
			&& (0 != stAttribute.move))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_SKIP)
			&& (1 != stAttribute.skip))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_SKIP)
			&& (0 != stAttribute.skip))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_DEL)
			&& (1 != stAttribute.delete))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_DEL)
			&& (0 != stAttribute.delete))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_UNSTABLE)
			&& (1 != stAttribute.unStable))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_UNSTABLE)
			&& (0 != stAttribute.unStable))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_LOCK)
			&& (1 != stAttribute.parental_lock))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_LOCK)
			&& (0 != stAttribute.parental_lock))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_SCAMBLE)
			&& (1 != stAttribute.scramble))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_SCAMBLE)
			&& (0 != stAttribute.scramble))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_NOTRUN)
			&& (1 != stAttribute.svrnotrun))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_NOTRUN)
			&& (0 != stAttribute.svrnotrun))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_TMPSRV)
			&& (1 != stAttribute.svrtmp))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_TMPSRV)
			&& (0 != stAttribute.svrtmp))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_MPEG4TYPE)
			&& (1 == stAttribute.mpeg4type))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_MPEG4TYPE)
			&& (0 != stAttribute.mpeg4type))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_VIDEOAVC)
			&& (1 != stAttribute.videoavc))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_VIDEOAVC)
			&& (0 != stAttribute.videoavc))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_NOTVISIBLE)
			&& (1 != stAttribute.notvisible))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_NOTVISIBLE)
			&& (0 != stAttribute.notvisible))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_NOTSELETECTABLE)
			&& (1 != stAttribute.notselectable))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_NOTSELETECTABLE)
			&& (0 != stAttribute.notselectable))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_FREECA)
			&& (1 != stAttribute.freeca))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_FREECA)
			&& (0 != stAttribute.freeca))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_NAMEMODIFIED)
			&& (1 != stAttribute.nameModified))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_NAMEMODIFIED)
			&& (0 != stAttribute.nameModified))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_NITMATCH)
			&& (1 != stAttribute.NIDMatched))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_NITMATCH)
			&& (0 != stAttribute.NIDMatched))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_ONIDMATCH)
			&& (1 != stAttribute.ONIDMatched))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eDNegative, AL_SRV_DATTRIB_ONIDMATCH)
			&& (0 != stAttribute.ONIDMatched))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eDPositive, AL_SRV_DATTRIB_CIPLUSUSED)
			&& (1 != stAttribute.ciplusused))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_DATTRIB_CIPLUSUSED)
			&& (0 != stAttribute.ciplusused))
		{
			return al_false;
		}

		return al_true;
	}
	else if (AL_DBTYPE_DVB_ATV == stFilter.eDBType)
	{
#if defined(CONFIG_ISDB_SYSTEM)
	    if ((atv_database_type == ATVDB_AIR) && (0 != (((SADBServInfo_t *)pRec)->tvtype)))
        {
            return al_false;
        }

        if ((atv_database_type == ATVDB_CABLE) && (1 != (((SADBServInfo_t *)pRec)->tvtype)))
        {
            return al_false;
        }
        if ((atv_care_valid == al_true) && (1 != (((SADBServInfo_t *)pRec)->available)))
        {
            return al_false;
        }

        if (SRV_CHECKTYPE(stFilter.eAPositive, AL_SRV_AATTRIB_TVTYPE) /* air */
			&& (0 != ((SADBServInfo_t *)pRec)->tvtype))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_AATTRIB_TVTYPE)
			&& (1 != ((SADBServInfo_t *)pRec)->tvtype))
		{
			return al_false;
		}

        if (SRV_CHECKTYPE(stFilter.eAPositive, AL_SRV_AVATTRIB_VALID)
			&& (1 != ((SADBServInfo_t *)pRec)->available))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_AVATTRIB_VALID)
			&& (0 != ((SADBServInfo_t *)pRec)->available))
		{
			return al_false;
		}
#endif

#ifdef CONFIG_SUPPORT_ATV_SCAN_NTSCM_PALM_N
        if ((atv_database_type == ATVDB_AIR) && (0 != (((SADBServInfo_t *)pRec)->tvtype)))
        {
            return al_false;
        }

        if ((atv_database_type == ATVDB_CABLE) && (1 != (((SADBServInfo_t *)pRec)->tvtype)))
        {
            return al_false;
        }
        if ((atv_care_valid == al_true) && (1 != (((SADBServInfo_t *)pRec)->available)))
        {
            return al_false;
        }

        if (SRV_CHECKTYPE(stFilter.eAPositive, AL_SRV_AATTRIB_TVTYPE) /* air */
			&& (0 != ((SADBServInfo_t *)pRec)->tvtype))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_AATTRIB_TVTYPE)
			&& (1 != ((SADBServInfo_t *)pRec)->tvtype))
		{
			return al_false;
		}

        if (SRV_CHECKTYPE(stFilter.eAPositive, AL_SRV_AVATTRIB_VALID)
			&& (1 != ((SADBServInfo_t *)pRec)->available))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_AVATTRIB_VALID)
			&& (0 != ((SADBServInfo_t *)pRec)->available))
		{
			return al_false;
		}
#endif
		if (SRV_CHECKTYPE(stFilter.eAPositive, AL_SRV_AATTRIB_FAV1)
			&& (1 != ((SADBServInfo_t *)pRec)->fav1))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_AATTRIB_FAV1)
			&& (0 != ((SADBServInfo_t *)pRec)->fav1))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eAPositive, AL_SRV_AATTRIB_FAV2)
			&& (1 != ((SADBServInfo_t *)pRec)->fav2))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_AATTRIB_FAV2)
			&& (0 != ((SADBServInfo_t *)pRec)->fav2))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eAPositive, AL_SRV_AATTRIB_FAV3)
			&& (1 != ((SADBServInfo_t *)pRec)->fav3))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_AATTRIB_FAV3)
			&& (0 != ((SADBServInfo_t *)pRec)->fav3))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eAPositive, AL_SRV_AATTRIB_FAV4)
			&& (1 != ((SADBServInfo_t *)pRec)->fav4))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_AATTRIB_FAV4)
			&& (0 != ((SADBServInfo_t *)pRec)->fav4))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eAPositive, AL_SRV_AATTRIB_FAV5))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_AATTRIB_FAV5))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eAPositive, AL_SRV_AATTRIB_FAV6))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_AATTRIB_FAV6))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eAPositive, AL_SRV_AATTRIB_FAV7))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_AATTRIB_FAV7))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eAPositive, AL_SRV_AATTRIB_FAV8))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_AATTRIB_FAV8))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eAPositive, AL_SRV_AATTRIB_INUSE)
			&& (1 != ((SADBServInfo_t *)pRec)->inuse))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_AATTRIB_INUSE)
			&& (0 != ((SADBServInfo_t *)pRec)->inuse))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eAPositive, AL_SRV_AATTRIB_SKIP)
			&& (1 != ((SADBServInfo_t *)pRec)->skip))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_AATTRIB_SKIP)
			&& (0 != ((SADBServInfo_t *)pRec)->skip))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eAPositive, AL_SRV_AATTRIB_DEL)
			&& (1 != ((SADBServInfo_t *)pRec)->del))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_AATTRIB_DEL)
			&& (0 != ((SADBServInfo_t *)pRec)->del))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eAPositive, AL_SRV_AATTRIB_LOCK)
			&& (1 != ((SADBServInfo_t *)pRec)->lock))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_AATTRIB_LOCK)
			&& (0 != ((SADBServInfo_t *)pRec)->lock))
		{
			return al_false;
		}

		if (SRV_CHECKTYPE(stFilter.eAPositive, AL_SRV_AATTRIB_AFC)
			&& (1 != ((SADBServInfo_t *)pRec)->AFC))
		{
			return al_false;
		}
		else if (SRV_CHECKTYPE(stFilter.eANegative, AL_SRV_AATTRIB_AFC)
			&& (0 != ((SADBServInfo_t *)pRec)->AFC))
		{
			return al_false;
		}

		return al_true;
	}

	return al_false;
}

/****************************************************//**
 * @brief Match service by specified search field.
 *
 * @note Refers to the prototype #AL_DB_RecordMatchFunc.
 *
 * @param param		[in]Search key, type: #AL_Serv_SearchKey_t.
 * @param pRec		[in]Service detail.
 *
 * @return
 * 	#AL_SUCCESS indicates success,
 * 	On failure, #AL_FAILURE is returned.
 ********************************************************/
al_bool AL_Serv_MatchRecBySearchKey(al_void *param, al_void const*pRec)
{
	if (al_null == param || al_null == pRec)
	{
		return al_false;
	}

	AL_Serv_SearchKey_t stKey;
	al_bool bDTGSupport = al_false;
	al_uint8 u8TempCotryCode[3] = {0};
	frmwrk_pfOpConext_t pfPSIMonGetContext = al_null;

	AL_FW_GetContextCb(&pfPSIMonGetContext);

	if (pfPSIMonGetContext != al_null)
	{
		pfPSIMonGetContext(FW_CONTEXT_TYPE_COUNTRY_CODE , FW_CONTEXT_OP_TYPE_READ,
			(al_void *)u8TempCotryCode, 0);
	}

	if (strncmp((const char *)u8TempCotryCode, "GBR", 3) == 0)
	{
		bDTGSupport = al_true;
	}

	memset(&stKey, 0, sizeof(AL_Serv_SearchKey_t));
	memcpy(&stKey, param, sizeof(AL_Serv_SearchKey_t));

	if (AL_DBTYPE_DVB_T == stKey.eDBType)
	{
		if (stKey.eRecType & AL_RECTYPE_DVBSERVICE)
		{
			if (!(((STDBServInfo_t *)pRec)->eTvRadioType & stKey.eRecType))
			{
				return al_false;
			}
	        /*zhongbaoxing modified for mantis 0167629 to consider the attrib @20120204 */
			if ((0 == ((STDBServInfo_t *)pRec)->stProgAttrib.delete)
				&&(((0 == ((STDBServInfo_t *)pRec)->stProgAttrib.notvisible)
				||((stKey.eIncludeAttrib&AL_SRV_DATTRIB_NOTVISIBLE)!=0) //Gahu:C1030
				||(1 == ((STDBServInfo_t *)pRec)->stProgAttrib.bInvalidService)) //richiechang 20130604, for CI+ v1.3 HostTune no SI service (Test 2.3.1 - Step.14)
				||((stKey.eIncludeAttrib&AL_SRV_DATTRIB_DEL)!=0)))
			{
				if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_ORIGNETID)
					&& (stKey.u16OrigNetId != ((STDBServInfo_t *)pRec)->usOrigNetId))
				{
					return al_false;
				}
				if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_TSID)
					&& (stKey.u16TsId != ((STDBServInfo_t *)pRec)->usTsId
					&& !bDTGSupport))
				{
					return al_false;
				}
				if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_SRVID)
					&& (stKey.u16ServId != ((STDBServInfo_t *)pRec)->usServiceId))
				{
					return al_false;
				}
				if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_PROGNO)
					&& (stKey.u32ProgNo != ((STDBServInfo_t *)pRec)->usProgNo))
				{
					return al_false;
				}

				return al_true;
			}
			else
			{
				return al_false;
			}
		}
		else if (stKey.eRecType & AL_RECTYPE_DVBMULTIPLEX)
		{
			if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_ORIGNETID)
				&& (stKey.u16OrigNetId != ((STDBMultiplexInfo_t *)pRec)->usOrigNetId))
			{
				return al_false;
			}
			if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_TSID)
				&& (stKey.u16TsId != ((STDBMultiplexInfo_t *)pRec)->usTsId
#ifdef CONFIG_DTV_SUPPORT
				&& !AL_Event_GetEDTGSupport()
#endif
				))
			{
				return al_false;
			}
			if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_NETID)
				&& (stKey.u16NetId != ((STDBMultiplexInfo_t *)pRec)->usNetId))
			{
				return al_false;
			}
			if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_FREQ)
				&& (stKey.u32Frequency != ((STDBMultiplexInfo_t *)pRec)->uiFreqK))
			{
				return al_false;
			}
			return al_true;
		}
		else if (stKey.eRecType & AL_RECTYPE_DVBNETWORK)
		{
			if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_NETID)
				&& (stKey.u16NetId != ((STDBNetworkInfo_t *)pRec)->usNetId))
			{
				return al_false;
			}
			return al_true;
		}
	}
	else if (AL_DBTYPE_DVB_C == stKey.eDBType)
	{
		if (stKey.eRecType & AL_RECTYPE_DVBSERVICE)
		{
			if (!(((SCDBServInfo_t *)pRec)->eTvRadioType & stKey.eRecType))
			{
				return al_false;
			}

			if ((0 == ((SCDBServInfo_t *)pRec)->stProgAttrib.delete)
				&&(((0 == ((SCDBServInfo_t *)pRec)->stProgAttrib.notvisible)
				||((stKey.eIncludeAttrib&AL_SRV_DATTRIB_NOTVISIBLE)!=0) //Gahu:C1030
				||(1 == ((SCDBServInfo_t *)pRec)->stProgAttrib.bInvalidService)) //richiechang 20130604, for CI+ v1.3 HostTune no SI service (Test 2.3.1 - Step.14)
	            ||((stKey.eIncludeAttrib&AL_SRV_DATTRIB_DEL)!=0)))
			{
				if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_ORIGNETID)
					&& (stKey.u16OrigNetId != ((SCDBServInfo_t *)pRec)->usOrigNetId))
				{
					return al_false;
				}
				if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_TSID)
					&& (stKey.u16TsId != ((SCDBServInfo_t *)pRec)->usTsId
					&& !bDTGSupport))
				{
					return al_false;
				}
				if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_SRVID)
					&& (stKey.u16ServId != ((SCDBServInfo_t *)pRec)->usServiceId))
				{
					return al_false;
				}
				if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_PROGNO)
					&& (stKey.u32ProgNo != ((SCDBServInfo_t *)pRec)->usProgNo))
				{
					return al_false;
				}

				return al_true;
			}
			else
			{
				return al_false;
			}
		}
		else if (stKey.eRecType & AL_RECTYPE_DVBMULTIPLEX)
		{
			if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_ORIGNETID)
				&& (stKey.u16OrigNetId != ((SCDBMultiplexInfo_t *)pRec)->usOrigNetId))
			{
				return al_false;
			}
			if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_TSID)
				&& (stKey.u16TsId != ((SCDBMultiplexInfo_t *)pRec)->usTsId))
			{
				return al_false;
			}
			if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_NETID)
				&& (stKey.u16NetId != ((SCDBMultiplexInfo_t *)pRec)->usNetId))
			{
				return al_false;
			}
			if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_FREQ)
				&& (stKey.u32Frequency != ((SCDBMultiplexInfo_t *)pRec)->uiFreqK))
			{
				return al_false;
			}
			return al_true;
		}
	}
	else if (AL_DBTYPE_DVB_S == stKey.eDBType)
	{
		if (stKey.eRecType & AL_RECTYPE_DVBSERVICE)
		{
			if (!(((SDBServInfo_t *)pRec)->eTvRadioType & stKey.eRecType))
			{
				return al_false;
			}
	        /*zhongbaoxing modified for mantis 0167629 to consider the attrib @20120204 */
			if ((0 == ((SDBServInfo_t *)pRec)->stProgAttrib.delete)
				&&(((0 == ((SDBServInfo_t *)pRec)->stProgAttrib.notvisible)
				||((stKey.eIncludeAttrib&AL_SRV_DATTRIB_NOTVISIBLE)!=0) //Gahu:C1030
				||(1 == ((SDBServInfo_t *)pRec)->stProgAttrib.bInvalidService)) //richiechang 20130604, for CI+ v1.3 HostTune no SI service (Test 2.3.1 - Step.14)
				||((stKey.eIncludeAttrib&AL_SRV_DATTRIB_DEL)!=0)))
			{
				if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_ORIGNETID)
					&& (stKey.u16OrigNetId != ((SDBServInfo_t *)pRec)->usOrigNetId))
				{
					return al_false;
				}
				if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_TSID)
					&& (stKey.u16TsId != ((SDBServInfo_t *)pRec)->usTsId
					&& !bDTGSupport))
				{
					return al_false;
				}
				if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_SRVID)
					&& (stKey.u16ServId != ((SDBServInfo_t *)pRec)->usServiceId))
				{
					return al_false;
				}
				if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_PROGNO)
					&& (stKey.u32ProgNo != ((SDBServInfo_t *)pRec)->usProgNo))
				{
					return al_false;
				}

				return al_true;
			}
			else
			{
				return al_false;
			}
		}
		else if (stKey.eRecType & AL_RECTYPE_DVBMULTIPLEX)
		{
			if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_NETID)
				&& (stKey.u16NetId != ((SDBMultiplexInfo_t *)pRec)->usNetId))
			{
				return al_false;
			}
			if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_FREQ)
				&& (DIFFER(stKey.u32Frequency, ((SDBMultiplexInfo_t *)pRec)->usFreqM) > 3))
			{
				return al_false;
			}
			if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_SYMRATE)
				&& (stKey.u32SymbolRate != ((SDBMultiplexInfo_t *)pRec)->usSymRateK))
			{
				return al_false;
			}
			return al_true;
		}
	}
#ifdef CONFIG_ISDB_SYSTEM
	if (AL_DBTYPE_DVB_SBTVD == stKey.eDBType)
	{
		if (stKey.eRecType & AL_RECTYPE_DVBSERVICE)
		{
			if (!(((SSBTVDDBServInfo_t *)pRec)->eTvRadioType & stKey.eRecType))
			{
				return al_false;
			}
	        /*zhongbaoxing modified for mantis 0167629 to consider the attrib @20120204 */
			if ((0 == ((SSBTVDDBServInfo_t *)pRec)->stProgAttrib.delete)
				&&((0 == ((STDBServInfo_t *)pRec)->stProgAttrib.notvisible)
				||((stKey.eIncludeAttrib&AL_SRV_DATTRIB_NOTVISIBLE)!=0) //Gahu:C1030
				||(1 == ((STDBServInfo_t *)pRec)->stProgAttrib.bInvalidService) //richiechang 20130604, for CI+ v1.3 HostTune no SI service (Test 2.3.1 - Step.14)
	          	       ||((stKey.eIncludeAttrib&AL_SRV_DATTRIB_DEL)!=0)))
			{
				if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_ORIGNETID)
					&& (stKey.u16OrigNetId != ((SSBTVDDBServInfo_t *)pRec)->usOrigNetId))
				{
					return al_false;
				}
				if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_TSID)
					&& (stKey.u16TsId != ((SSBTVDDBServInfo_t *)pRec)->usTsId
					&& !bDTGSupport))
				{
					return al_false;
				}
				if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_SRVID)
					&& (stKey.u16ServId != ((SSBTVDDBServInfo_t *)pRec)->usServiceId))
				{
					return al_false;
				}
				if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_PROGNO)
					&& (stKey.u32ProgNo != ((SSBTVDDBServInfo_t *)pRec)->usProgNo))
				{
					return al_false;
				}

				return al_true;
			}
			else
			{
				return al_false;
			}
		}
		else if (stKey.eRecType & AL_RECTYPE_DVBMULTIPLEX)
		{
			if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_TSID)
				&& (stKey.u16TsId != ((SSBTVDDBMultiplexInfo_t *)pRec)->usTsId
#ifdef CONFIG_DTV_SUPPORT
				&& !AL_Event_GetEDTGSupport()
#endif
				))
			{
				return al_false;
			}
			if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_NETID)
				&& (stKey.u16NetId != ((SSBTVDDBMultiplexInfo_t *)pRec)->usNetId))
			{
				return al_false;
			}
			if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_FREQ)
				&& (stKey.u32Frequency != ((SSBTVDDBMultiplexInfo_t *)pRec)->uiFreqK))
			{
				return al_false;
			}
			return al_true;
		}
		else if (stKey.eRecType & AL_RECTYPE_DVBNETWORK)
		{
			if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_NETID)
				&& (stKey.u16NetId != ((SSBTVDDBNetworkInfo_t *)pRec)->usNetId))
			{
				return al_false;
			}
			return al_true;
		}
	}
#endif
	else if (AL_DBTYPE_DVB_ATV == stKey.eDBType)
	{
		if (stKey.eRecType & AL_RECTYPE_ATVSERVICE)
		{
			if (0 == ((SADBServInfo_t *)pRec)->del)
			{
				if (SRV_CHECKTYPE(stKey.eSearchField, AL_SRV_SEARCHFIELD_FREQ)
					&& (stKey.u32Frequency != ((SADBServInfo_t *)pRec)->u32Freq))
				{
					return al_false;
				}
				return al_true;
			}
			else
			{
				return al_false;
			}
		}
	}

	return al_false;
}

//For Riks, to store User Service Info.
typedef struct
{
	AL_DB_EDBType_t eDBType;
	UINT16 usONID;
	UINT16 usTSID;
	UINT16 usServID;
	UINT16 usUserProgNo;
	UINT8 ucServName[DB_DVB_MAX_CHNAME_LEN];
} AI_Serv_UserLoc_t;

#if defined (SUPPORT_GHANA_LCN) || defined (CONFIG_SUPPORT_MALAYSIA_CERTIFICATION)
static al_bool g_bBackupUserServsLCN = al_false;

AL_Return_t AL_Serv_BackupUserServsLCN( al_uint8 country )
{
	if( country == AREA_GHANA || country == AREA_MALAYSIA)
		g_bBackupUserServsLCN = al_true;
	else
		g_bBackupUserServsLCN = al_false;

	return AL_SUCCESS;
}
#endif

al_bool AI_Serv_MatchUserByAttributes(al_void *param, al_void const*pRec)
{
	if (al_null == param || al_null == pRec)
	{
		return al_false;
	}

#if defined (SUPPORT_GHANA_LCN) || defined (CONFIG_SUPPORT_MALAYSIA_CERTIFICATION)
	if( AL_DBTYPE_DVB_T == *(AL_DB_EDBType_t *)param && g_bBackupUserServsLCN )
	{
		if( ((STDBServInfo_t *)pRec)->usProgNo == 0xFFFF )
			return al_false;
		if( ((STDBServInfo_t *)pRec)->stProgAttrib.delete == 1 )
			return al_false;
		if( ((STDBServInfo_t *)pRec)->stProgAttrib.notvisible == 1 )
			return al_false;
		if( ((STDBServInfo_t *)pRec)->stProgAttrib.notselectable == 1 )
			return al_false;
		return al_true;
	}
#endif

	if (AL_DBTYPE_DVB_T == *(AL_DB_EDBType_t *)param)
	{
		if (((STDBServInfo_t *)pRec)->usUserProgNo == 0xFFFF)
		{
			return al_false;
		}
		if (((STDBServInfo_t *)pRec)->stProgAttrib.fav8 == 0)
		{
			return al_false;
		}
		if (((STDBServInfo_t *)pRec)->stProgAttrib.delete == 1)
		{
			return al_false;
		}
		if (((STDBServInfo_t *)pRec)->stProgAttrib.notvisible == 1)
		{
			return al_false;
		}
		if (((STDBServInfo_t *)pRec)->stProgAttrib.notselectable == 1)
		{
			return al_false;
		}
	}

	return al_true;
}
al_bool AI_Serv_MatchUserByLocation(al_void *param, al_void const*pRec)
{
	if (al_null == param || al_null == pRec)
	{
		return al_false;
	}

	AI_Serv_UserLoc_t *pstUserLoc = (AI_Serv_UserLoc_t *)param;

	if (AL_DBTYPE_DVB_T == pstUserLoc->eDBType)
	{
		if (((STDBServInfo_t *)pRec)->usOrigNetId != pstUserLoc->usONID)
		{
			return al_false;
		}
		if (((STDBServInfo_t *)pRec)->usServiceId != pstUserLoc->usServID)
		{
			return al_false;
		}
	#ifdef SUPPORT_GHANA_LCN
		if( g_bBackupUserServsLCN )
		{
			if( ((STDBServInfo_t *)pRec)->usTsId != pstUserLoc->usTSID )
				return al_false;
			return al_true;
		}
	#endif
		//If the user service still exists, then skip it
		if (((STDBServInfo_t *)pRec)->usUserProgNo != 0xFFFF
			&& ((STDBServInfo_t *)pRec)->stProgAttrib.fav8 == 1)
		{
			return al_false;
		}
	}

	return al_true;
}

//For Riks, need to store User Service list
AL_Return_t AL_Serv_StoreUserServs(AL_DB_EDBType_t eDBType)
{
	AL_RecHandle_t hServ = AL_DB_INVALIDHDL;
	AL_ServiceDetail_t stServInfo;
	AI_Serv_UserLoc_t stUserLoc;

	if (g_stItemList != 0)
	{
		AI_TpListFree(g_stItemList);
	}

	if (AL_DBTYPE_DVB_T == eDBType)
	{
		if (AL_SUCCESS != AI_TpListInit(&g_stItemList))
		{
			return AL_FAILURE;
		}

		while (AL_SUCCESS == AL_DB_GetMatchedRecord((AL_DB_RecordMatchFunc)AI_Serv_MatchUserByAttributes,
			(al_void *)&eDBType, eDBType, AL_RECTYPE_DVBSERVICE, AL_DB_REQ_GETNEXT, &hServ))
		{
			memset(&stServInfo, 0, sizeof(stServInfo));
			if (AL_SUCCESS == AL_DB_QueryDetail(hServ, (al_void *)&stServInfo))
			{
				memset(&stUserLoc, 0, sizeof(stUserLoc));
				stUserLoc.eDBType = eDBType;
				stUserLoc.usONID = stServInfo.stDVBTServ.usOrigNetId;
				stUserLoc.usTSID = stServInfo.stDVBTServ.usTsId;
				stUserLoc.usServID = stServInfo.stDVBTServ.usServiceId;
			#ifdef SUPPORT_GHANA_LCN
				if( g_bBackupUserServsLCN )
					stUserLoc.usUserProgNo = stServInfo.stDVBTServ.usProgNo;
				else
			#endif
				stUserLoc.usUserProgNo = stServInfo.stDVBTServ.usUserProgNo;
				memcpy(stUserLoc.ucServName, stServInfo.stDVBTServ.szProgName, DB_DVB_MAX_CHNAME_LEN);
				if (AL_SUCCESS != AI_TpListAddNode(g_stItemList, (void *)&stUserLoc, sizeof(stUserLoc)))
				{
					break;
				}
			}

		}
	}

	return AL_SUCCESS;
}
//For Riks, need to retrieve User Service list
al_bool _AI_Serv_CompareProgName(UINT8 *u8LocName, UINT8 *u8ProgName)
{
	UINT8 i;

	for (i = 0; i < DB_DVB_MAX_CHNAME_LEN; i++)
	{
		if (u8LocName[i] != u8ProgName[i])
		{
			return al_false;
		}
	}

	return al_true;
}

AL_Return_t AL_Serv_RetrieveUserServs(AL_DB_EDBType_t eDBType)
{
	AL_RecHandle_t hServ = AL_DB_INVALIDHDL;
	AL_ServiceDetail_t stServInfo;
	AI_Serv_UserLoc_t *pstUserLoc = al_null;

	if (g_stItemList == 0)
	{
	#ifdef SUPPORT_GHANA_LCN
		g_bBackupUserServsLCN = al_false;
	#endif
		return AL_FAILURE;
	}

	if (AL_DBTYPE_DVB_T == eDBType)
	{
		while (AL_SUCCESS == AI_TpListGetNode(g_stItemList, (void * *)&pstUserLoc)
			&& pstUserLoc != al_null)
		{
			if (AL_SUCCESS == AL_DB_GetMatchedRecord((AL_DB_RecordMatchFunc)AI_Serv_MatchUserByLocation,
				(al_void *)pstUserLoc, eDBType, AL_RECTYPE_DVBSERVICE, AL_DB_REQ_GETFIRST, &hServ))
			{
				memset(&stServInfo, 0, sizeof(stServInfo));
				if (AL_SUCCESS == AL_DB_QueryDetail(hServ, (al_void *)&stServInfo))
				{
				#ifdef SUPPORT_GHANA_LCN
					if( g_bBackupUserServsLCN )
					{
						stServInfo.stDVBTServ.usProgNo = pstUserLoc->usUserProgNo;
						AL_DB_UpdateDetailFieldByName( hServ, (al_uint8 *)"usProgNo", (al_void *)&stServInfo.stDVBTServ.usProgNo );
						continue;
					}
				#endif

					stServInfo.stDVBTServ.stProgAttrib.fav8 = 1;
					stServInfo.stDVBTServ.usUserProgNo = pstUserLoc->usUserProgNo;
					if (!_AI_Serv_CompareProgName(pstUserLoc->ucServName,
						stServInfo.stDVBTServ.szProgName))
					{
						memcpy(stServInfo.stDVBTServ.szProgName, pstUserLoc->ucServName, DB_DVB_MAX_CHNAME_LEN);
						AL_DB_UpdateDetailFieldByName(hServ,
							(al_uint8 *)"szProgName", (al_void *)stServInfo.stDVBTServ.szProgName);
						stServInfo.stDVBTServ.stProgAttrib.nameModified = 1;
					}
					AL_DB_UpdateDetailFieldByName(hServ,
						(al_uint8 *)"usUserProgNo", (al_void *) &stServInfo.stDVBTServ.usUserProgNo);
					AL_DB_UpdateDetailFieldByName(hServ,
						(al_uint8 *)"stProgAttrib", (al_void *) &stServInfo.stDVBTServ.stProgAttrib);
				}
			}
		}

		if (AL_SUCCESS != AI_TpListFree(g_stItemList))
		{
		#ifdef SUPPORT_GHANA_LCN
			g_bBackupUserServsLCN = al_false;
		#endif
			return AL_FAILURE;
		}

		g_stItemList = 0;
	}

#ifdef SUPPORT_GHANA_LCN
	g_bBackupUserServsLCN = al_false;
#endif
	return AL_SUCCESS;
}

