/*	mapp coding call handling c file	*/
/*	written by Liu Zhiguo 2003-03-04	*/
/*	Version 2.0							*/
/*	--------------------------------	*/

#include "map_includes.h"

int	assign_cugcheckinfo(struct CugChkInfo_struct *cci_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;

	asn_encode(buf,&asn_buf);
	if (cci_ptr->param_flag & 0x01)
		buf_len = add_tlv("4",CUGLOCK_LEN,cci_ptr->cug_intlock,0x00,&asn_buf);
	if (cci_ptr->param_flag & 0x02)
		buf_len = add_null("5",0x00,&asn_buf);
	return buf_len;
}

int extract_cugcheckinfo(struct CugChkInfo_struct *cci_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			len;
	u8			temp_buf[256];

	cci_ptr->param_flag = 0;
	if (buf_len == 0)
		return RER;
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	len = get_tlv("4",temp_buf,&asn_buf);
	if (len == CUGLOCK_LEN)
	{
		cci_ptr->param_flag |= 0x01;
		memcpy(cci_ptr->cug_intlock,temp_buf,CUGLOCK_LEN);
	}
	len = get_null("5",&asn_buf);
	if (len != -1)
		cci_ptr->param_flag |= 0x02;
	return ROK;
}

int assign_fwddata(struct FwdData_struct *fwd_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	u8			tag1=1;
	char			tlv1[32];

	asn_encode(buf,&asn_buf);
	if (fwd_ptr->param_flag & 0x01)		//fwd num
	{
		sprintf(tlv1,"5-%d",tag1++);
		buf_len = add_tlv(tlv1,fwd_ptr->fwd_num[0],fwd_ptr->fwd_num+1,0x80,&asn_buf);
	}
	if (fwd_ptr->param_flag & 0x02)	// fwd to sub addr
	{
		sprintf(tlv1,"4-%d",tag1++);
		buf_len = add_tlv(tlv1,fwd_ptr->fwd_subadd[0],fwd_ptr->fwd_subadd+1,0x80,&asn_buf);
	}
	if (fwd_ptr->param_flag & 0x04)	//fwd option
	{
		sprintf(tlv1,"6-%d",tag1++);
		buf_len = add_tlv(tlv1,1,&fwd_ptr->fwd_option,0x80,&asn_buf);
	}	
	return buf_len;
}

int extract_fwddata(struct FwdData_struct *fwd_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			len;
	u8			temp_buf[256];

	fwd_ptr->param_flag = 0;
	if (buf_len == 0)
		return RER;
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	len = get_tlv("5",temp_buf,&asn_buf);
	if (len != -1 && len <= ISDN_LEN)	// fwd num
	{
		fwd_ptr->param_flag |= 0x01;
		fwd_ptr->fwd_num[0] = len;
		memcpy(fwd_ptr->fwd_num+1,temp_buf,len);
	}
	len = get_tlv("4",temp_buf,&asn_buf);
	if (len != -1 && len <= ISDNSUB_LEN)	// fwd subadd
	{
		fwd_ptr->param_flag |= 0x02;
		fwd_ptr->fwd_subadd[0] = len;
		memcpy(fwd_ptr->fwd_subadd+1,temp_buf,len);
	}
	if (get_tlv("6",temp_buf,&asn_buf) == 1)	// fwd option
	{
		fwd_ptr->param_flag |= 0x04;
		fwd_ptr->fwd_option = temp_buf[0];
	}
	return ROK;
}

int assign_tcsi(struct TCsi_struct *tcsi_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	u8			ii;
	int			buf_len=0;
	u8			temp_len;
	char			tlv1[32];

	asn_encode(buf,&asn_buf);
	if (tcsi_ptr->tdpdata_list.tdpdata_len > TDPDATA_NUM)
		return RER;
	buf_len = add_null("16",0x20,&asn_buf);
	for (ii = 0;ii < tcsi_ptr->tdpdata_list.tdpdata_len;ii ++)	//o-BCSM Camel TDP Data List
	{
		sprintf(tlv1,"16.16-%d",ii+1);
		buf_len = add_null(tlv1,0x20,&asn_buf);
		sprintf(tlv1,"16.16-%d.10-1",ii+1);
		buf_len = add_int(tlv1,tcsi_ptr->tdpdata_list.tdp_data[ii].det_point,0x00,&asn_buf);
		sprintf(tlv1,"16.16-%d.2-2",ii+1);
		buf_len = add_int(tlv1,tcsi_ptr->tdpdata_list.tdp_data[ii].service_key,0x00,&asn_buf);
		sprintf(tlv1,"16.16-%d.0-3",ii+1);
		temp_len = tcsi_ptr->tdpdata_list.tdp_data[ii].scf_add[0];
		buf_len = add_tlv(tlv1,temp_len,tcsi_ptr->tdpdata_list.tdp_data[ii].scf_add+1,0x80,&asn_buf);
		sprintf(tlv1,"16.16-%d.1-4",ii+1);
		buf_len = add_int(tlv1,tcsi_ptr->tdpdata_list.tdp_data[ii].def_hand,0x80,&asn_buf);
	}
	if (tcsi_ptr->param_flag & 0x02)		//camel capability Handling
		buf_len = add_int("0-2",tcsi_ptr->camel_caphand,0x80,&asn_buf);
	return buf_len;
}

int extract_tcsi(struct TCsi_struct *tcsi_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			len;
	u8			ii,jj;
	u8			temp_buf[256];
	char			tlv1[32];

	if (buf_len == 0)
		return RER;
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	tcsi_ptr->tdpdata_list.tdpdata_len = 0;
	for (ii = 0;ii < TDPDATA_NUM;ii ++)
	{
		jj = tcsi_ptr->tdpdata_list.tdpdata_len;
		sprintf(tlv1,"16.16-%d",ii+1);
		len = get_tlv(tlv1,temp_buf,&asn_buf);
		if (len == -1)
			break;
		sprintf(tlv1,"16.16-%d.10",ii+1);	// det_point
		if (get_tlv(tlv1,temp_buf,&asn_buf) != 1)
			return RER;
		tcsi_ptr->tdpdata_list.tdp_data[jj].det_point = temp_buf[0];
		sprintf(tlv1,"16.16-%d.2",ii+1);	// service key
		len = get_int(tlv1,&asn_buf);
		if (len == -1)
			return RER;
		tcsi_ptr->tdpdata_list.tdp_data[jj].service_key = len;
		sprintf(tlv1,"16.16-%d.0",ii+1);	// scf address
		len = get_tlv(tlv1,temp_buf,&asn_buf);
		if (len == -1 || len > ISDN_LEN)
			return RER;
		tcsi_ptr->tdpdata_list.tdp_data[jj].scf_add[0] = len;
		memcpy(tcsi_ptr->tdpdata_list.tdp_data[jj].scf_add+1,temp_buf,len);
		sprintf(tlv1,"16.16-%d.1",ii+1);	// default call handling
		len = get_tlv(tlv1,temp_buf,&asn_buf);
		if (len != 1)
			return RER;
		tcsi_ptr->tdpdata_list.tdp_data[jj].def_hand = temp_buf[0];
		tcsi_ptr->tdpdata_list.tdpdata_len ++;
	}
	tcsi_ptr->param_flag |= 0x01;
	if (get_tlv("0",temp_buf,&asn_buf) == 1)
	{
		tcsi_ptr->param_flag |= 0x02;
		tcsi_ptr->camel_caphand = temp_buf[0];
	}
	return ROK;
}

/*	+++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding send routing info argument	*/
/*	+++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_sndroutinfoarg(struct MapSRI_Arg *sri_ptr,u8 *buf, u8 ver)
{
	ASN_BUF		asn_buf;
	u32			flag;
	int			buf_len=0;
	int			temp_len;
	u8			temp_buf[256];
	u8			tag1=1;
	char		tlv1[32];

	asn_encode(buf,&asn_buf);
	flag = sri_ptr->param_flag;
	if (flag & 0x01)	// has  MSISDN
	{
		sprintf(tlv1,"0-%d",tag1++);
		buf_len = add_tlv(tlv1,sri_ptr->msisdn[0],sri_ptr->msisdn+1,0x80,&asn_buf);//add msisdn parameter
	}
	else
	{
		mapp_log_debug("send routing information loss MSISDN");
		return RER;
	}
	if (flag & 0x02)	// has CUG check info
	{
		sprintf(tlv1,"1-%d",tag1++);
		temp_len = assign_cugcheckinfo(&sri_ptr->chk_info,temp_buf);
		buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf);
	}
	if (flag & 0x04) //has number of forwarding
	{
		sprintf(tlv1,"2-%d",tag1++);
		buf_len = add_tlv(tlv1,1,&sri_ptr->fwd_num,0x80,&asn_buf);
	}
	if (flag & 0x08 && ver >1) //interrogation type
	{
		sprintf(tlv1,"3-%d",tag1++);
		temp_buf[0] = sri_ptr->inter_type;
		buf_len = add_tlv(tlv1,1,temp_buf,0x80,&asn_buf);
	}
	if (flag & 0x10 && ver >1) //or-interrogation
	{
		sprintf(tlv1,"4-%d",tag1++);
		buf_len = add_null(tlv1,0x80,&asn_buf);
	}
	if (flag & 0x20 && ver >1) // or-capability
	{
		sprintf(tlv1,"5-%d",tag1++);
		buf_len = add_tlv(tlv1,1,&sri_ptr->or_cap,0x80,&asn_buf);
	}
	if (flag & 0x40 && ver >1)// gmsc addr
	{
		sprintf(tlv1,"6-%d",tag1++);
		buf_len = add_tlv(tlv1,sri_ptr->gmsc_add[0],sri_ptr->gmsc_add+1,0x80,&asn_buf);
	}
	if (flag & 0x80 && ver >1) // call ref num
	{
		sprintf(tlv1,"7-%d",tag1++);
		buf_len = add_tlv(tlv1,sri_ptr->callref_num[0],sri_ptr->callref_num+1,0x80,&asn_buf);
	}
	if (flag & 0x100 && ver >1) // fwd reason num
	{
		sprintf(tlv1,"8-%d",tag1++);
		temp_buf[0] = sri_ptr->fwd_reason;
		buf_len = add_tlv(tlv1,1,temp_buf,0x80,&asn_buf);
	}
	if(flag & 0x200 && ver >1 )		//bs group
	{
		sprintf(tlv1,"9-%d",tag1++);
		temp_len = assign_bscode(&sri_ptr->bs_group,temp_buf,0);
		buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf);
	}
	if (flag & 0x400)	// net info
	{
		sprintf(tlv1,"10-%d",tag1++);
		temp_len = assign_extsiginfo(&sri_ptr->net_info,temp_buf);
		buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf);
	}
	if (flag & 0x800 && ver >1) 	//camelInfo
	{
		if (sri_ptr->camel_info.param_flag & 0x01)
		{
			sprintf(tlv1,"11-%d.3",tag1);
			buf_len = add_tlv(tlv1,2,sri_ptr->camel_info.camel_phase,0x00,&asn_buf);
		}
		if (sri_ptr->camel_info.param_flag & 0x02)		//suppress-T-CSI
		{
			sprintf(tlv1,"11-%d.5",tag1);
			buf_len = add_null(tlv1,0x00,&asn_buf);
		}
		tag1 ++;
	}
	if (flag & 0x1000 && ver >1)	//suppression Of Announcement
	{
		sprintf(tlv1,"12-%d",tag1++);
		buf_len = add_null(tlv1,0x80,&asn_buf);
	}
	if (flag & 0x2000 && ver >1)	//alerting Pattern
	{
		sprintf(tlv1,"14-%d",tag1++);
		buf_len = add_tlv(tlv1,1,&sri_ptr->alt_pattern,0x80,&asn_buf);
	}
	if (flag & 0x4000 && ver >1)	//ccbs-Call
	{
		sprintf(tlv1,"15-%d",tag1++);
		buf_len = add_null(tlv1,0x80,&asn_buf);
	}
	if (flag & 0x8000 && ver >1) 	//supported CCBS phase
	{
		sprintf(tlv1,"16-%d",tag1++);
		buf_len = AddInteger(tlv1,sri_ptr->ccbs_phase,0x80,&asn_buf);
	}
	return buf_len;
}

int extract_sndroutinfoarg(struct MapSRI_Arg *sri_ptr,u32 buf_len,u8 *buf , u8 ver)
{
	ASN_BUF		asn_buf;
	int			len;
	u8			temp_buf[256];
	u32			flag=0;
	
	sri_ptr->param_flag = 0;
	if (buf_len == 0)
		return RER;
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	len = get_tlv("0",temp_buf,&asn_buf);	// get MSISDN
	if (len > 1 && len <= ISDN_LEN)
	{
		flag |= 0x01;
		sri_ptr->msisdn[0] = len;
		memcpy(sri_ptr->msisdn+1,temp_buf,len);
	}
	else
	{
		mapp_log_debug("extract_sndroutinfoarg:loss MSISDN");
		return RER;
	}
	
	len = get_tlv("1",temp_buf,&asn_buf);
	if (len > 0)	// CUG-checkInfo
	{
		flag |= 0x02;
		extract_cugcheckinfo(&sri_ptr->chk_info,len,temp_buf);
	}
	
	len = get_tlv("2",temp_buf,&asn_buf);	//number Of Forwarding
	if (len == 1)
	{
		sri_ptr->fwd_num = temp_buf[0];
		flag |= 0x04;
	}
	
	if( ver > 1 )
	{
		if (GetInteger("3",(int *)&sri_ptr->inter_type,0x80,&asn_buf) > 0)	//interrogation type
			flag |= 0x08;
		if (get_null("4",&asn_buf) > 0 )	//or-Interrogation
		{
			flag |= 0x10;
			sri_ptr->or_inter = 1;
		}
		len = get_tlv("5",temp_buf,&asn_buf);	//or-capability
		if (len == 1)
		{
			sri_ptr->or_cap = temp_buf[0];
			flag |= 0x20;
		}
		len = get_tlv("6",temp_buf,&asn_buf);	//gmsc-Address
		if (len > 1 && len <= ISDN_LEN)
		{
			flag |= 0x40;
			sri_ptr->gmsc_add[0] = len;
			memcpy(sri_ptr->gmsc_add+1,temp_buf,len);
		}
		len = get_tlv("7",temp_buf,&asn_buf);	//call Reference Number
		if (len > 0 && len <= CALLREF_NUM)
		{
			flag |= 0x80;
			sri_ptr->callref_num[0] = len;
			memcpy(sri_ptr->callref_num+1,temp_buf,len);
		}
		if (GetInteger("8",(int *)&sri_ptr->fwd_reason,0x80,&asn_buf) > 0)	//forwarding Reason
			flag |= 0x100;
		len = get_tlv("9",temp_buf,&asn_buf);	//basicServiceGroup
		if (len > 0)
		{
			flag |= 0x200;
			extract_bscode(&sri_ptr->bs_group,len,temp_buf);
		}
	}
	
	len = get_tlv("10",temp_buf,&asn_buf);	//networkSignalInfo
	if (len > 0)
	{
		flag |= 0x400;
		extract_extsiginfo(&sri_ptr->net_info,len,temp_buf);
	}
	
	if( ver > 1 )
	{
		len = get_tlv("11.3",temp_buf,&asn_buf);	//camelInfo=>supported camel phases
		if (len != -1)
		{
			memcpy(sri_ptr->camel_info.camel_phase,temp_buf,3);
			sri_ptr->camel_info.param_flag |= 0x01;
			flag |= 0x800;
		}
		if (get_null("11.5", &asn_buf) >= 0)	//camelInfo=>suppress-T-CSI
		{
			sri_ptr->camel_info.supp_tcsi = 1;
			sri_ptr->camel_info.param_flag |= 0x02;
			flag |= 0x800;
		}
		if (get_null("12", &asn_buf) >= 0)	//suppression of announcement
		{
			sri_ptr->supp_ann = 1;
			flag |= 0x1000;
		}
		if (get_tlv("14",temp_buf,&asn_buf) == 1)	//alertingPattern
		{
			sri_ptr->alt_pattern = temp_buf[0];
			flag |= 0x2000;
		}
		if (get_null("15",&asn_buf) >= 0)	//ccbs-Call
		{
			sri_ptr->ccbs_call = 1;
			flag |= 0x4000;
		}
		if (get_tlv("16",temp_buf,&asn_buf) == 1)	//supportedCCBS phase
		{
			sri_ptr->ccbs_phase = temp_buf[0];
			flag |= 0x8000;
		}
	}
	sri_ptr->param_flag = flag;
	return ROK;
}

/*	+++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding send routing info response	*/
/*	+++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_sndroutinfores(struct MapSRI_Res *sri_ptr,u8 *buf,u8 version)
{
	ASN_BUF		asn_buf;
	u32			flag;
	u32			temp_flag;
	int			len=0, jj;
	int			buf_len = 0;
	int			tag1=1,tag2=1;
	char		tlv1[32],tlv2[32];
	int			temp_len;
	u8			temp_buf[256];

	asn_encode(buf,&asn_buf);
	flag = sri_ptr->param_flag;
	if (flag & 0x01)	// has  IMSI
	{
		if (version <= 1)
		{
			sprintf(tlv1,"4-%d",tag1++);
			buf_len = add_tlv(tlv1,IMSI_LEN,sri_ptr->imsi,0x00,&asn_buf);
		}
		else
		{
			sprintf(tlv1,"9-%d",tag1++);	
			buf_len = add_tlv(tlv1,IMSI_LEN,sri_ptr->imsi,0x80,&asn_buf);
		}
	}	
	if (flag & 0x02)	// has ext routing information
	{
		if (sri_ptr->rout_info.choice_flag == 1) // route info
		{
			if (sri_ptr->rout_info.choice.rout_info.choice_flag == 1)//roam num
			{
				sprintf(tlv1,"4-%d",tag1);
				len = sri_ptr->rout_info.choice.rout_info.choice.roam_num[0];
				buf_len = add_tlv(tlv1,len,sri_ptr->rout_info.choice.rout_info.choice.roam_num+1,0x00,&asn_buf);
			}
			else if (sri_ptr->rout_info.choice.rout_info.choice_flag == 2)//fwd data
			{
				temp_len = assign_fwddata(&sri_ptr->rout_info.choice.rout_info.choice.fwd_data,temp_buf);
				sprintf(tlv1,"16-%d",tag1);//tag1,forwardingData
				buf_len = add_tlv(tlv1,temp_len,temp_buf,0x20,&asn_buf);
			}
		}
		else if (sri_ptr->rout_info.choice_flag == 2 && version >1 )	//camel Routing Info
		{
			tag2 = 1;
			if (sri_ptr->rout_info.choice.camel_info.param_flag & 0x01)	//forwardingData
			{
				temp_len = assign_fwddata(&sri_ptr->rout_info.choice.camel_info.fwd_data,temp_buf);
				sprintf(tlv1,"8-%d.16-%d",tag1,tag2++);
				buf_len = add_tlv(tlv1,temp_len,temp_buf,0x20,&asn_buf);
			}
			if (sri_ptr->rout_info.choice.camel_info.param_flag & 0x02)	//gmscCamelSubscriptionInfo
			{
				sprintf(tlv1,"8-%d.0-%d",tag1,tag2);
				if (sri_ptr->rout_info.choice.camel_info.subs_info.param_flag & 0x01)	//t-CSI
				{
					temp_len = assign_tcsi(&sri_ptr->rout_info.choice.camel_info.subs_info.t_csi,temp_buf);
					sprintf(tlv2,"%s.0-1",tlv1);
					buf_len = add_tlv(tlv2,temp_len,temp_buf,0x0a0,&asn_buf);
				}
				if (sri_ptr->rout_info.choice.camel_info.subs_info.param_flag & 0x02)	//o-CSI
				{
					temp_len = assign_ocsi(&sri_ptr->rout_info.choice.camel_info.subs_info.o_csi,temp_buf);
					sprintf(tlv2,"%s.1-2",tlv1);
					buf_len = add_tlv(tlv2,temp_len,temp_buf,0x0a0,&asn_buf);
				}
				if (sri_ptr->rout_info.choice.camel_info.subs_info.param_flag & 0x04)	//o-BcsmCamelTDP-CriteriaList
				{
					temp_len = assign_tdpcritlist(&sri_ptr->rout_info.choice.camel_info.subs_info.ob_list,temp_buf);
					sprintf(tlv2,"%s.3-3",tlv1);
					buf_len = add_tlv(tlv2,temp_len,temp_buf,0x0a0,&asn_buf);
				}
			}
		}
		tag1 ++;
	}	
	if (flag & 0x04)	//cug-checkInfo
	{
		sprintf(tlv1,"3-%d",tag1++);
		temp_len = assign_cugcheckinfo(&sri_ptr->cugchk_info,temp_buf);
		buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf);
	}	
	if( version >1 )
	{
		if (flag & 0x08)	//cugSubscription Flag
		{
			sprintf(tlv1,"6-%d",tag1++);
			buf_len = add_null(tlv1,0x00,&asn_buf);
		}
		if (flag & 0x10)		//subscriberInfo
		{
			temp_len = assign_subinfo(&sri_ptr->sub_info,temp_buf);
			sprintf(tlv1,"7-%d",tag1++);
			buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf);
		}
		if (flag & 0x20)		//ss-List
		{
			if (sri_ptr->ss_list.sslist_len > SS_LEN)
			{
				mapp_log_debug("assign_sndroutinfores: sslist_len > SS_LEN");
				return RER;
			}
			for(jj = 0;jj < sri_ptr->ss_list.sslist_len;jj ++)
			{
				sprintf(tlv1,"1-%d.4-%d",tag1,jj+1);
				buf_len = add_tlv(tlv1,1,&sri_ptr->ss_list.ss_code[jj],0x00,&asn_buf);
			}
			tag1 ++;
		}
		if (flag & 0x40)		//basicService
		{
			temp_len = assign_bscode(&sri_ptr->bs_code,temp_buf,0);
			sprintf(tlv1,"5-%d",tag1++);
			buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf);
		}
		if (flag & 0x80)		//forwarding Interrogation Required
		{
			sprintf(tlv1,"4-%d",tag1++);
			buf_len = add_null(tlv1,0x80,&asn_buf);
		}
		if (flag & 0x100)		//vmsc-Address
		{
			sprintf(tlv1,"2-%d",tag1++);
			buf_len = add_tlv(tlv1,sri_ptr->vmsc_add[0],sri_ptr->vmsc_add+1,0x80,&asn_buf);
		}
		if (flag & 0x200)		//naea-PreferredCI
		{
			sprintf(tlv1,"10-%d.0",tag1++);
			buf_len = add_tlv(tlv1,NAEA_LEN,sri_ptr->naea_ci.cic,0x80,&asn_buf);
		}
		if((flag & 0x400) == 0x400)	//ccbs-Indicators
		{
			tag2 = 1;
			temp_flag = sri_ptr->ccbs_ind.param_flag;
			if (temp_flag & 0x01)		//ccbs-Possible
			{
				sprintf(tlv1,"11-%d.0-%d",tag1,tag2++);
				buf_len = add_null(tlv1,0x80,&asn_buf);
			}
			if(temp_flag & 0x02)		//kepCCBS-CalIndicator
			{
				sprintf(tlv1,"11-%d.1-%d",tag1,tag2++);
				buf_len = add_null(tlv1,0x80,&asn_buf);
			}
			tag1++;
		}   
		if((flag & 0x800) == 0x800) //mnp indicator
		{
		    sprintf(tlv1,"13-%d",tag1++);
			temp_buf[0] = sri_ptr->mnp_indicator;
			buf_len = add_tlv(tlv1,1,temp_buf,0x80,&asn_buf);
        }
	}
	return buf_len;
}

int extract_sndroutinfores(struct MapSRI_Res *sri_ptr,u32 buf_len,u8 *buf,u8 version)
{
	ASN_BUF		asn_buf;
	u8			ii,jj;
	int			len;
	int			temp_len;
	u8			temp_buf[256];
	u8			tag1;
	char		tlv1[32];
	u32			flag=0;

	sri_ptr->param_flag = 0;
	if (buf_len == 0)
		return ROK;
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	tag1 = 1;
	if (version <= 1)
		len = get_tlv("4-1",temp_buf,&asn_buf);
	else
		len = get_tlv("9",temp_buf,&asn_buf);	//imsi
	if (len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0)
	{
		flag |= 0x01;
		memcpy(sri_ptr->imsi,temp_buf,len);
		tag1 ++;
	}
	else
		mapp_log_debug("extract_sndroutinfores: no IMSI");
	sprintf(tlv1,"4-%d",tag1);
	len = get_tlv(tlv1,temp_buf,&asn_buf);
	if (len > 0)	// roaming number
	{
		flag |= 0x02;
		sri_ptr->rout_info.choice_flag = 1;
		sri_ptr->rout_info.choice.rout_info.choice_flag = 1;
		sri_ptr->rout_info.choice.rout_info.choice.roam_num[0] = len;
		memcpy(sri_ptr->rout_info.choice.rout_info.choice.roam_num+1,temp_buf,len);
		tag1 ++;
	}
	else
	{
		len = get_tlv("16",temp_buf,&asn_buf);	//forwarding data
		if (len != -1)
		{
			flag |= 0x02;
			sri_ptr->rout_info.choice_flag = 1;
			sri_ptr->rout_info.choice.rout_info.choice_flag = 2;
			if (!extract_fwddata(&sri_ptr->rout_info.choice.rout_info.choice.fwd_data,len,temp_buf))
				return RER;
			tag1 ++;
		}
		else if( version >1 )
		{
			len = get_tlv("8",temp_buf,&asn_buf);	// camelRoutingInfo
			if (len != -1)
			{
				flag |= 0x02;
				sri_ptr->rout_info.choice_flag = 2;
				sri_ptr->rout_info.choice.camel_info.param_flag = 0;
				temp_len = get_tlv("8.16",temp_buf,&asn_buf);	// fwd data
				if (temp_len != -1)
				{
					sri_ptr->rout_info.choice.camel_info.param_flag |= 0x01;
					if (!extract_fwddata(&sri_ptr->rout_info.choice.camel_info.fwd_data,temp_len,temp_buf))
						return RER;	
				}
				temp_len = get_tlv("8.0",temp_buf,&asn_buf);	//gmscCamelSubscriptionInfo
				if (temp_len != -1)
				{
					sri_ptr->rout_info.choice.camel_info.param_flag |= 0x02;
					sri_ptr->rout_info.choice.camel_info.subs_info.param_flag = 0;
					temp_len = get_tlv("8.0.0",temp_buf,&asn_buf);	// t-CSI
					if (temp_len != -1)
					{
						sri_ptr->rout_info.choice.camel_info.subs_info.param_flag |= 0x01;
						if (!extract_tcsi(&sri_ptr->rout_info.choice.camel_info.subs_info.t_csi,temp_len,temp_buf))
							return RER;
					}
					temp_len = get_tlv("8.0.1",temp_buf,&asn_buf);	// o-CSI
					if (temp_len != -1)
					{
						sri_ptr->rout_info.choice.camel_info.subs_info.param_flag |= 0x02;
						if (!extract_ocsi(&sri_ptr->rout_info.choice.camel_info.subs_info.o_csi,temp_len,temp_buf))
							return RER;
					}
					temp_len = get_tlv("8.0.3",temp_buf,&asn_buf);	//o-BcsmCamelTDP-CrteriaList
					if (temp_len != -1)
					{
						sri_ptr->rout_info.choice.camel_info.subs_info.param_flag |= 0x04;
						if (!extract_tdpcritlist(&sri_ptr->rout_info.choice.camel_info.subs_info.ob_list,temp_len,temp_buf))
							return RER;
					}
				}
				tag1 ++;
			}
		}
	}
	len = get_tlv("3",temp_buf,&asn_buf);	//cug-CheckInfo
	if (len != -1)
	{
		if (!extract_cugcheckinfo(&sri_ptr->cugchk_info,len,temp_buf))
			return RER;
		flag |= 0x04;
		tag1 ++;
	}
	if( version > 1 )
	{
		if (get_tlv("6",temp_buf,&asn_buf) != -1)	//cug Subscription flag
		{
			flag |= 0x08;
			sri_ptr->cugsubs_flag = 1;
			tag1 ++;
		}
		len = get_tlv("7",temp_buf,&asn_buf);	//subscriber info
		if (len != -1)
		{
			flag |= 0x10;
			if (!extract_subinfo(&sri_ptr->sub_info,len,temp_buf))
				return RER;
			tag1 ++;
		}
		if (get_tlv("1",temp_buf,&asn_buf) != -1)
		{
			flag |= 0x20;
			sri_ptr->ss_list.sslist_len = 0;
			for (ii = 0;ii < SS_LEN;ii ++)
			{
				jj = sri_ptr->ss_list.sslist_len;
				sprintf(tlv1,"1.4-%d",ii+1);
				if (get_tlv(tlv1,temp_buf,&asn_buf) != 1)
					break;
				sri_ptr->ss_list.ss_code[jj] = temp_buf[0];
				sri_ptr->ss_list.sslist_len ++;
			}
			tag1 ++;
		}
		len = get_tlv("5",temp_buf,&asn_buf);	//basicService
		if (len != -1)
		{
			flag |= 0x40;
			if (!extract_bscode(&sri_ptr->bs_code,len,temp_buf))
				return RER;
			tag1 ++;
		}
		sprintf(tlv1,"4-%d",tag1);
		len = get_null(tlv1,&asn_buf);	//forwarding Interrogation Required
		if (len != -1)
		{
			flag |= 0x80;
			tag1 ++;
		}
		len = get_tlv("2",temp_buf,&asn_buf);	//vmsc-Address
		if (len != -1 && len < ISDN_LEN)
		{
			flag |= 0x100;
			sri_ptr->vmsc_add[0] = len;
			memcpy(sri_ptr->vmsc_add+1,temp_buf,len);
			tag1 ++;
		}
		if(get_tlv("10.0",temp_buf,&asn_buf) == NAEA_LEN)
		{
			flag |= 0x200;
			memcpy(sri_ptr->naea_ci.cic,temp_buf,NAEA_LEN);
			tag1 ++;
		}
		if (get_tlv("11",temp_buf,&asn_buf) != -1)	//ccbs-Indicator
		{
			flag |= 0x400;
			if (get_null("11.0",&asn_buf) > 0)		//ccbs-Possible
			{
				sri_ptr->ccbs_ind.param_flag |= 0x01;
				sri_ptr->ccbs_ind.ccbs_possible = 1;
			}
			if(get_null("11.1", &asn_buf) > 0)		//keepCCBS-CallIndicator
			{
				sri_ptr->ccbs_ind.param_flag |= 0x02;
				sri_ptr->ccbs_ind.ccbs_indicator = 1;
			}
			tag1 ++;
		}
        if (get_tlv("13",temp_buf,&asn_buf) == 1 )      //mnp indicator
		{
		    flag |= 0x800;
		    sri_ptr->mnp_indicator = temp_buf[0];
		    tag1 ++;
		}
	}
	sri_ptr->param_flag = flag;
	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding provider roaming num argument		*/
/*	++++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_provroamnumarg(MapPRN_Arg *prn_ptr, u8 *buf)
{
	ASN_BUF		asn_buf;
	u32			flag;
	int			buf_len;
	int			temp_len;
	u8			temp_buf[256];
	int			tag1=1;
	char		tlv1[32];

	asn_encode(buf,&asn_buf);
	flag = prn_ptr->param_flag;
	if(flag & 0x01)	// imsi
	{
		sprintf(tlv1,"0-%d",tag1++);
		buf_len = add_tlv(tlv1,IMSI_LEN,prn_ptr->imsi,0x80,&asn_buf);
	}
	else
	{
		mapp_log_debug("Error:assign_prroamnumarg: lack imsi");
		return RER;
	}
	if (flag & 0x02) //msc number
	{
		sprintf(tlv1,"1-%d",tag1++);
		buf_len = add_tlv(tlv1,prn_ptr->msc_num[0],prn_ptr->msc_num+1,0x80,&asn_buf);
	}
	else
	{
		mapp_log_debug("assign_prroamnumarg: lack msc number");
		return RER;
	}
	if (flag & 0x04) //msisdn number
	{
		sprintf(tlv1,"2-%d",tag1++);
		buf_len = add_tlv(tlv1,prn_ptr->msisdn[0],prn_ptr->msisdn+1,0x80,&asn_buf);
	}
	if (flag & 0x08) // lmsi
	{
		sprintf(tlv1,"4-%d",tag1++);
		buf_len = add_tlv(tlv1,LMSI_LEN,prn_ptr->lmsi,0x80,&asn_buf);
	}
	if (flag & 0x10) // bearer capability
	{
		temp_len = assign_extsiginfo(&prn_ptr->bearer_cap,temp_buf);
		sprintf(tlv1,"5-%d",tag1++);
		buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf);
	}
	if (flag & 0x20) // net info
	{
		temp_len = assign_extsiginfo(&prn_ptr->net_info,temp_buf);
		sprintf(tlv1,"6-%d",tag1++);
		buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf);
	}
	if (flag & 0x40) // suppression of announcement
	{
		sprintf(tlv1,"7-%d",tag1++);
		buf_len = add_null(tlv1,0x80,&asn_buf);
	}
	if (flag & 0x80) // gmsc address
	{
		sprintf(tlv1,"8-%d",tag1++);
		buf_len = add_tlv(tlv1,prn_ptr->gmsc_add[0],prn_ptr->gmsc_add+1,0x80,&asn_buf);
	}
	if (flag & 0x100)	// call reference number
	{
		sprintf(tlv1,"9-%d",tag1++);
		buf_len = add_tlv(tlv1,prn_ptr->callref_num[0],prn_ptr->callref_num+1,0x80,&asn_buf);
	}
	if (flag & 0x200)	// or interrogation
	{
		sprintf(tlv1,"10-%d",tag1++);
		buf_len = add_null(tlv1,0x80,&asn_buf);
	}
	if (flag & 0x400)	// alert pattern
	{
		sprintf(tlv1,"12-%d",tag1++);
		buf_len = add_tlv(tlv1,1,&prn_ptr->alt_pattern,0x80,&asn_buf);
	}
	if (flag & 0x800)	// ccbs call
	{
		sprintf(tlv1,"13-%d",tag1++);
		buf_len = add_null(tlv1,0x80,&asn_buf);
	}
	if (flag & 0x1000)	// supproted camel phase in gmsc
	{
		sprintf(tlv1,"14-%d",tag1++);
		buf_len = add_tlv(tlv1,3,prn_ptr->camel_phase,0x80,&asn_buf);
	}
	return buf_len;
}

int extract_provroamnumarg(struct MapPRN_Arg *prn_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			len;
	u8			temp_buf[256];
	u32			flag=0;

	prn_ptr->param_flag = 0;
	if (buf_len == 0)
		return RER;
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	len = get_tlv("0",temp_buf,&asn_buf);
	if (len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0)
	{
		flag |= 0x01;
		memcpy(prn_ptr->imsi,temp_buf,len);
	}
	else
	{
		mapp_log_debug("extract_prroamnumarg:lack imsi");
		return RER;
	}
	len = get_tlv("1",temp_buf,&asn_buf);
	if (len > 2 && len <= ISDN_LEN)
	{
		flag |= 0x02;
		prn_ptr->msc_num[0] = len;
		memcpy(prn_ptr->msc_num+1,temp_buf,len);
	}
	else
	{
		mapp_log_debug("extract_prroamnumarg:lack msc number");
		return RER;
	}
	len = get_tlv("2",temp_buf,&asn_buf);
	if (len > 2 && len <= ISDN_LEN)
	{
		flag |= 0x04;
		prn_ptr->msisdn[0] = len;
		memcpy(prn_ptr->msisdn+1,temp_buf,len);
	}	
	len = get_tlv("4",temp_buf,&asn_buf);
	if (len == LMSI_LEN)
	{
		memcpy(prn_ptr->lmsi,temp_buf,LMSI_LEN);
		flag |= 0x08;
	}
	len = get_tlv("5",temp_buf,&asn_buf);
	if (len != -1)
	{
		if (!extract_extsiginfo(&prn_ptr->bearer_cap,len,temp_buf))
			return RER;
		flag |= 0x10;		
	}
	len = get_tlv("6",temp_buf,&asn_buf);
	if (len != -1)
	{
		if (!extract_extsiginfo(&prn_ptr->net_info,len,temp_buf))
			return RER;
		flag |= 0x20;	
	}
	if (get_null("7",&asn_buf) != -1)
	{
		flag |= 0x40;
		prn_ptr->sup_ann = 1;
	}
	len = get_tlv("8",temp_buf,&asn_buf);
	if (len > 2 && len <= ISDN_LEN)
	{
		flag |= 0x80;
		prn_ptr->gmsc_add[0] = len;
		memcpy(prn_ptr->gmsc_add+1,temp_buf,len);
	}
	len = get_tlv("9",temp_buf,&asn_buf);
	if (len > 0 && len <= CALLREF_NUM)
	{
		flag |= 0x100;
		prn_ptr->callref_num[0] = len;
		memcpy(prn_ptr->callref_num+1,temp_buf,len);
	}
	if (get_null("10",&asn_buf) != -1)
	{
		flag |= 0x200;
		prn_ptr->or_interr = 1;
	}
	if (get_tlv("12",temp_buf,&asn_buf) == 1)
	{
		flag |= 0x400;
		prn_ptr->alt_pattern = temp_buf[0];
	}
	if (get_null("13",&asn_buf) != -1)
	{
		flag |= 0x800;
		prn_ptr->ccbs_call = 1;
	}
	if (get_tlv("14",temp_buf,&asn_buf) == 3)
	{
		flag |= 0x1000;
		memcpy(prn_ptr->camel_phase,temp_buf,3);
	}
	prn_ptr->param_flag = flag;
	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding provider roaming num response		*/
/*	++++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_provroamnumres(struct MapPRN_Res *prn_ptr, u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;

	asn_encode(buf, &asn_buf);
	if (prn_ptr->param_flag & 0x01)	//  roaming number
		buf_len = add_tlv("4",prn_ptr->roam_num[0],prn_ptr->roam_num+1,0x00,&asn_buf);
	else
	{
		mapp_log_debug("assign_prroamnumRES: lack roaming number");
		return RER;
	}
	return buf_len;
}

int extract_provroamnumres(struct MapPRN_Res *prn_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			len;
	u8			temp_buf[256];

	prn_ptr->param_flag = 0;
	if (buf_len == 0)
		return RER;
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	len = get_tlv("4",temp_buf,&asn_buf);
	if (len > 2)
	{
		prn_ptr->param_flag |= 0x01;
		prn_ptr->roam_num[0] = len;
		memcpy(prn_ptr->roam_num+1,temp_buf,len);
	}
	else
	{
		mapp_log_debug("extract_prroamnumres: lack roaming number");
		return RER;
	}
	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding resume call handling argument		*/
/*  ++++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_rescallhandarg(struct MapRCH_Arg *rch_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	int			temp_len;
	u8			temp_buf[256];
	u8			tag1;
	char			tlv1[32];

	asn_encode(buf,&asn_buf);
	if (rch_ptr->param_flag & 0x01)		// call reference number
		buf_len = add_tlv("0",rch_ptr->callref_num[0],rch_ptr->callref_num+1,0x80,&asn_buf);
	else
		return RER;
	if (rch_ptr->param_flag & 0x02)		// bs group
	{
		temp_len = assign_bscode(&rch_ptr->bs_group,temp_buf,0);
		buf_len = add_tlv("1",temp_len,temp_buf,0x0a0,&asn_buf);
	}
	else
		return RER;
	if (rch_ptr->param_flag & 0x04)		// forward data
	{
		temp_len = assign_fwddata(&rch_ptr->fwd_data,temp_buf);
		buf_len = add_tlv("2",temp_len,temp_buf,0x0a0,&asn_buf);
	}
	else
		return RER;
	if (rch_ptr->param_flag & 0x08)		// imsi
		buf_len = add_tlv("3",IMSI_LEN,rch_ptr->imsi,0x80,&asn_buf);
	else
		return RER;
	tag1 = 5;
	if (rch_ptr->param_flag & 0x10)		// cug check info
	{
		temp_len = assign_cugcheckinfo(&rch_ptr->cugchk_info,temp_buf);
		sprintf(tlv1,"4-%d",tag1++);
		buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf);
	}
	if (rch_ptr->param_flag & 0x20)		// o-csi
	{
		temp_len = assign_ocsi(&rch_ptr->o_csi,temp_buf);
		sprintf(tlv1,"5-%d",tag1++);
		buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf);
	}
	if (rch_ptr->param_flag & 0x40)		// ccbs possible
	{
		sprintf(tlv1,"8-%d",tag1++);
		buf_len = add_null(tlv1,0x80,&asn_buf);
	}
	return buf_len;
}

int extract_rescallhandarg(struct MapRCH_Arg *rch_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int 		len;
	u8			temp_buf[256];

	rch_ptr->param_flag = 0;
	if (buf_len == 0)
	{
		mapp_log_debug("MAPP--extract_resume call handling buf_len=0");
		return RER;
	}
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	len = get_tlv("0",temp_buf,&asn_buf);		// call reference
	if (len > 0 && len <= CALLREF_NUM)
	{
		rch_ptr->param_flag |= 0x01;
		rch_ptr->callref_num[0] = len;
		memcpy(rch_ptr->callref_num+1,temp_buf,len);
	}
	else
		return RER;
	len = get_tlv("1",temp_buf,&asn_buf);		// bs group
	if (len > 0)
	{
		if (!extract_bscode(&rch_ptr->bs_group,len,temp_buf))
			return RER;
		rch_ptr->param_flag |= 0x02;
	}
	else
		return RER;
	len = get_tlv("2",temp_buf,&asn_buf);		// forward data
	if (len > 0)
	{
		if (!extract_fwddata(&rch_ptr->fwd_data,len,temp_buf))
			return RER;
		rch_ptr->param_flag |= 0x04;
	}
	else
		return RER;
	len = get_tlv("3",temp_buf,&asn_buf);
	if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0)	//get imsi
	{
		rch_ptr->param_flag |= 0x08;
		memcpy(rch_ptr->imsi,temp_buf,IMSI_LEN);
	}
	else
		return RER;
	len = get_tlv("4",temp_buf,&asn_buf);		// cug check info
	if (len > 0)
	{
		if (!extract_cugcheckinfo(&rch_ptr->cugchk_info,len,temp_buf))
			return RER;
		rch_ptr->param_flag |= 0x10;
	}
	len = get_tlv("5",temp_buf,&asn_buf);		// o-csi
	if (len > 0)
	{
		if (!extract_ocsi(&rch_ptr->o_csi,len,temp_buf))
			return RER;
		rch_ptr->param_flag |= 0x20;
	}
	if (get_tlv("8",temp_buf,&asn_buf) != -1)	// ccbs possible
	{
		rch_ptr->param_flag |= 0x40;
		rch_ptr->ccbs_possible = 1;
	}
	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding resume call handling response		*/
/*  ++++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_rescallhandres(struct MapRCH_Res *rch_ptr,u8 *buf)
{
	return 0;
}

int extract_rescallhandres(struct MapRCH_Res *rch_ptr,u32 buf_len,u8 *buf)
{
	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding provide SIWFS number argument		*/
/*  ++++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_prvsiwfsnumarg(struct MapPSN_Arg *psn_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	int			temp_len;
	u8			temp_buf[256];
	u8			tag1;
	char			tlv1[32];

	asn_encode(buf,&asn_buf);
	if (psn_ptr->param_flag & 0x01)		// gsm bearer capability
	{
		temp_len = assign_extsiginfo(&psn_ptr->gsm_bc,temp_buf);
		buf_len = add_tlv("0",temp_len,temp_buf,0x0a0,&asn_buf);
	}
	else
		return RER;
	if (psn_ptr->param_flag & 0x02)		// ISDN bearer capability
	{
		temp_len = assign_extsiginfo(&psn_ptr->isdn_bc,temp_buf);
		buf_len = add_tlv("1",temp_len,temp_buf,0x0a0,&asn_buf);
	}
	else
		return RER;
	if (psn_ptr->param_flag & 0x04)		// call direction
		buf_len = add_tlv("2",1,&psn_ptr->call_direction,0x80,&asn_buf);
	else
		return RER;
	if (psn_ptr->param_flag & 0x08)		// b-subscriber address
		buf_len = add_tlv("3",psn_ptr->bsub_add[0],psn_ptr->bsub_add+1,0x80,&asn_buf);
	else
		return RER;
	if (psn_ptr->param_flag & 0x10)		// chosen channel
	{
		temp_len = assign_extsiginfo(&psn_ptr->chose_chan,temp_buf);
		buf_len = add_tlv("4",temp_len,temp_buf,0x0a0,&asn_buf);
	}
	else
		return RER;
	tag1 = 6;
	if (psn_ptr->param_flag & 0x20)		// low layer compatibility
	{
		temp_len = assign_extsiginfo(&psn_ptr->low_camp,temp_buf);
		sprintf(tlv1,"5-%d",tag1++);
		buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf);
	}
	if (psn_ptr->param_flag & 0x40)		// high layer compatibility
	{
		temp_len = assign_extsiginfo(&psn_ptr->high_camp,temp_buf);
		sprintf(tlv1,"6-%d",tag1++);
		buf_len = add_tlv(tlv1,temp_len,temp_buf,0x0a0,&asn_buf);
	}
	return buf_len;
}

int extract_prvsiwfsnumarg(struct MapPSN_Arg *psn_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int 		len;
	u8			temp_buf[256];

	psn_ptr->param_flag = 0;
	if (buf_len == 0)
	{
		mapp_log_debug("MAPP--extract_provide siwfs number buf_len=0");
		return RER;
	}
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	len = get_tlv("0",temp_buf,&asn_buf);	// GSM bearer capability
	if (len > 0)
	{
		if (!extract_extsiginfo(&psn_ptr->gsm_bc,len,temp_buf))
			return RER;
		psn_ptr->param_flag |= 0x01;
	}
	else
		return RER;
	len = get_tlv("1",temp_buf,&asn_buf);	// ISDN bearer capability
	if (len > 0)
	{
		if (!extract_extsiginfo(&psn_ptr->isdn_bc,len,temp_buf))
			return RER;
		psn_ptr->param_flag |= 0x02;
	}
	else
		return RER;
	if (get_tlv("2",temp_buf,&asn_buf) == 1)	// call direction
	{
		psn_ptr->param_flag |= 0x04;
		psn_ptr->call_direction = temp_buf[0];
	}
	else
		return RER;
	len = get_tlv("3",temp_buf,&asn_buf);	// b-subscriber address
	if (len > 0)
	{
		psn_ptr->param_flag |= 0x08;
		psn_ptr->bsub_add[0] = len;
		memcpy(psn_ptr->bsub_add+1,temp_buf,len);
	}
	else
		return RER;
	len = get_tlv("4",temp_buf,&asn_buf);	// chosen channel
	if (len > 0)
	{
		if (!extract_extsiginfo(&psn_ptr->chose_chan,len,temp_buf))
			return RER;
		psn_ptr->param_flag |= 0x10;
	}
	else
		return RER;
	len = get_tlv("5",temp_buf,&asn_buf);	// low layer compatibility
	if (len > 0)
	{
		if (!extract_extsiginfo(&psn_ptr->low_camp,len,temp_buf))
			return RER;
		psn_ptr->param_flag |= 0x20;
	}
	len = get_tlv("6",temp_buf,&asn_buf);	// high layer compatibility
	if (len > 0)
	{
		if (!extract_extsiginfo(&psn_ptr->high_camp,len,temp_buf))
			return RER;
		psn_ptr->param_flag |= 0x40;
	}
	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding provide SIWFS number response		*/
/*  ++++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_prvsiwfsnumres(struct MapPSN_Res *psn_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;

	asn_encode(buf,&asn_buf);
	if (psn_ptr->param_flag & 0x01)
		buf_len = add_tlv("0",psn_ptr->siwfs_num[0],psn_ptr->siwfs_num+1,0x80,&asn_buf);
	else
		return RER;
	return buf_len;
}

int extract_prvsiwfsnumres(struct MapPSN_Res *psn_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int 		len;
	u8			temp_buf[256];

	psn_ptr->param_flag = 0;
	if (buf_len == 0)
	{
		mapp_log_debug("MAPP--extract_provide siwfs number buf_len=0");
		return RER;
	}
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	len = get_tlv("0",temp_buf,&asn_buf);
	if (len > 0 && len <= ISDN_LEN)
	{
		psn_ptr->param_flag |= 0x01;
		psn_ptr->siwfs_num[0] = len;
		memcpy(psn_ptr->siwfs_num+1,temp_buf,len);
	}
	else
		return RER;
	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding SIWFS signalling modify argument	*/
/*  ++++++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_siwfssigmodarg(struct MapSSM_Arg *ssm_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	int			temp_len;
	u8			temp_buf[256];

	asn_encode(buf,&asn_buf);
	if (ssm_ptr->param_flag & 0x01)		// channel type
	{
		temp_len = assign_extsiginfo(&ssm_ptr->chan_type,temp_buf);
		buf_len = add_tlv("0",temp_len,temp_buf,0x0a0,&asn_buf);
	}
	if (ssm_ptr->param_flag & 0x02)		// chosen channel
	{
		temp_len = assign_extsiginfo(&ssm_ptr->chose_chan,temp_buf);
		buf_len = add_tlv("1",temp_len,temp_buf,0x0a0,&asn_buf);
	}
	return buf_len;
}

int extract_siwfssigmodarg(struct MapSSM_Arg *ssm_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int 		len;
	u8			temp_buf[256];

	ssm_ptr->param_flag = 0;
	if (buf_len == 0)
	{
		mapp_log_debug("MAPP--extract_siwfs signalling modify buf_len=0");
		return ROK;
	}
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	len = get_tlv("0",temp_buf,&asn_buf);	// channel type
	if (len > 0)
	{
		if (!extract_extsiginfo(&ssm_ptr->chan_type,len,temp_buf))
			return RER;
		ssm_ptr->param_flag |= 0x01;
	}
	len = get_tlv("1",temp_buf,&asn_buf);	// chosen channel
	if (len > 0)
	{
		if (!extract_extsiginfo(&ssm_ptr->chose_chan,len,temp_buf))
			return RER;
		ssm_ptr->param_flag |= 0x02;
	}
	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding SIWFS signalling modify response	*/
/*  ++++++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_siwfssigmodres(struct MapSSM_Res *ssm_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	int			temp_len;
	u8			temp_buf[256];

	asn_encode(buf,&asn_buf);
	if (ssm_ptr->param_flag & 0x01)		// chosen channel
	{
		temp_len = assign_extsiginfo(&ssm_ptr->chose_chan,temp_buf);
		buf_len = add_tlv("0",temp_len,temp_buf,0x0a0,&asn_buf);
	}
	return buf_len;
}

int extract_siwfssigmodres(struct MapSSM_Res *ssm_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int 		len;
	u8			temp_buf[256];

	ssm_ptr->param_flag = 0;
	if (buf_len == 0)
	{
		mapp_log_debug("MAPP--extract_siwfs signalling modify buf_len=0");
		return ROK;
	}
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	len = get_tlv("0",temp_buf,&asn_buf);	// chosen channel
	if (len > 0)
	{
		if (!extract_extsiginfo(&ssm_ptr->chose_chan,len,temp_buf))
			return RER;
		ssm_ptr->param_flag |= 0x01;
	}
	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding set reporting state argument	*/
/*  ++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_setrepstatearg(struct MapSRS_Arg *srs_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	u8			temp_buf[256];

	asn_encode(buf,&asn_buf);
	if (srs_ptr->param_flag & 0x01)		// imsi
		buf_len = add_tlv("0",IMSI_LEN,srs_ptr->imsi,0x80,&asn_buf);
	if (srs_ptr->param_flag & 0x02)		// lmsi
		buf_len = add_tlv("1",LMSI_LEN,srs_ptr->lmsi,0x80,&asn_buf);
	if (srs_ptr->param_flag & 0x04)		// ccbs monitoring
	{
		temp_buf[0] = srs_ptr->ccbs_monitor;
		buf_len = add_tlv("2",1,temp_buf,0x80,&asn_buf);
	}
	return buf_len;
}

int extract_setrepstatearg(struct MapSRS_Arg *srs_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int 		len;
	u8			temp_buf[256];

	srs_ptr->param_flag = 0;
	if (buf_len == 0)
	{
		mapp_log_debug("MAPP--extract_set reporting state buf_len=0");
		return ROK;
	}
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	len = get_tlv("0",temp_buf,&asn_buf);
	if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0)	//get imsi
	{
		srs_ptr->param_flag |= 0x01;
		memcpy(srs_ptr->imsi,temp_buf,IMSI_LEN);
	}
	if (get_tlv("1",temp_buf,&asn_buf) == LMSI_LEN)	// get lmsi
	{
		srs_ptr->param_flag |= 0x02;
		memcpy(srs_ptr->lmsi,temp_buf,LMSI_LEN);
	}
	if (get_tlv("2",temp_buf,&asn_buf) == 1)	// get ccbs monitor
	{
		srs_ptr->param_flag |= 0x04;
		srs_ptr->ccbs_monitor = temp_buf[0];
	}
	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding set reporting state response	*/
/*  ++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_setrepstateres(struct MapSRS_Res *srs_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	u8			temp_buf[256];

	asn_encode(buf,&asn_buf);
	if (srs_ptr->param_flag & 0x01)		// ccbs subscriber status
	{
		temp_buf[0] = srs_ptr->ccbs_stat;
		buf_len = add_tlv("0",1,temp_buf,0x80,&asn_buf);
	}
	return buf_len;
}

int extract_setrepstateres(struct MapSRS_Res *srs_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	u8			temp_buf[256];

	srs_ptr->param_flag = 0;
	if (buf_len == 0)
	{
		mapp_log_debug("MAPP--extract_set reporting state buf_len=0");
		return ROK;
	}
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	if (get_tlv("0",temp_buf,&asn_buf) == 1)	// get ccbs subscriber status
	{
		srs_ptr->param_flag |= 0x01;
		srs_ptr->ccbs_stat = temp_buf[0];
	}
	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding status report argument	*/
/*  ++++++++++++++++++++++++++++++++++++++++	*/
int assign_statreparg(struct MapSR_Arg *sr_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	u8			temp_buf[256];

	asn_encode(buf,&asn_buf);
	if (sr_ptr->param_flag & 0x01)		// imsi
		buf_len = add_tlv("0",IMSI_LEN,sr_ptr->imsi,0x80,&asn_buf);
	else
		return RER;
	if (sr_ptr->param_flag & 0x02)		// event report data
	{
		if (sr_ptr->event_data.param_flag & 0x01)	// ccbs subscriber status
		{
			temp_buf[0] = sr_ptr->event_data.ccbs_stat;
			buf_len = add_tlv("1.0",1,temp_buf,0x80,&asn_buf);
		}
	}
	if (sr_ptr->param_flag & 0x04)		// call report data
	{
		if (sr_ptr->call_data.param_flag & 0x01)	// monitor mode
		{
			temp_buf[0] = sr_ptr->call_data.monitor_mode;
			buf_len = add_tlv("2.0",1,temp_buf,0x80,&asn_buf);
		}
		if (sr_ptr->call_data.param_flag & 0x02)	// call outcome
		{
			temp_buf[0] = sr_ptr->call_data.call_outcome;
			buf_len = add_tlv("2.1",1,temp_buf,0x80,&asn_buf);
		}
	}
	return buf_len;
}

int extract_statreparg(struct MapSR_Arg *sr_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int 		len;
	u8			temp_buf[256];

	sr_ptr->param_flag = 0;
	if (buf_len == 0)
	{
		mapp_log_debug("MAPP--extract_status report buf_len=0");
		return RER;
	}
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	len = get_tlv("0",temp_buf,&asn_buf);
	if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0)	//get imsi
	{
		sr_ptr->param_flag |= 0x01;
		memcpy(sr_ptr->imsi,temp_buf,IMSI_LEN);
	}
	else
		return RER;
	if (get_tlv("1.0",temp_buf,&asn_buf) != -1)		// ccbs subscriber status
	{
		sr_ptr->param_flag |= 0x02;
		sr_ptr->event_data.param_flag |= 0x01;
		sr_ptr->event_data.ccbs_stat = temp_buf[0];
	}
	if (get_tlv("2.0",temp_buf,&asn_buf) != -1)		// monitor mode
	{
		sr_ptr->param_flag |= 0x04;
		sr_ptr->call_data.param_flag |= 0x01;
		sr_ptr->call_data.monitor_mode = temp_buf[0];
	}
	if (get_tlv("2.1",temp_buf,&asn_buf) != -1)		// call outcome
	{
		sr_ptr->param_flag |= 0x04;
		sr_ptr->call_data.param_flag |= 0x02;
		sr_ptr->call_data.call_outcome = temp_buf[0];
	}
	return ROK;	
}

/*	++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding status report response	*/
/*  ++++++++++++++++++++++++++++++++++++++++	*/
int assign_statrepres(struct MapSR_Res *sr_ptr,u8 *buf)
{
	return 0;
}

int extract_statrepres(struct MapSR_Res *sr_ptr,u32 buf_len,u8 *buf)
{
	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding remote user free argument		*/
/*  ++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_rmtuserfreearg(struct MapRUF_Arg *ruf_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	int			temp_len;
	u8			temp_buf[256];
	u8			tag1;
	char			tlv1[32];

	asn_encode(buf,&asn_buf);
	if (ruf_ptr->param_flag & 0x01)		// imsi
		buf_len = add_tlv("0",IMSI_LEN,ruf_ptr->imsi,0x80,&asn_buf);
	else
		return RER;
	if (ruf_ptr->param_flag & 0x02)		// call info
	{
		temp_len = assign_extsiginfo(&ruf_ptr->call_info,temp_buf);
		buf_len = add_tlv("1",temp_len,temp_buf,0x0a0,&asn_buf);
	}
	else
		return RER;
	if (ruf_ptr->param_flag & 0x04)		// ccbs feature
	{
		temp_len = assign_ccbsfeat(&ruf_ptr->ccbs_feat,temp_buf);
		buf_len = add_tlv("2",temp_len,temp_buf,0x0a0,&asn_buf);
	}
	else
		return RER;
	if (ruf_ptr->param_flag & 0x08)		// translate number
		buf_len = add_tlv("3",ruf_ptr->trans_num[0],ruf_ptr->trans_num+1,0x80,&asn_buf);
	tag1 = 5;
	if (ruf_ptr->param_flag & 0x10)		// replace number
	{
		sprintf(tlv1,"4-%d",tag1++);
		buf_len = add_null(tlv1,0x80,&asn_buf);
	}
	if (ruf_ptr->param_flag & 0x20)		// alert pattern
	{
		sprintf(tlv1,"5-%d",tag1++);
		buf_len = add_tlv(tlv1,1,&ruf_ptr->alt_pattern,0x80,&asn_buf);
	}
	return buf_len;
}

int extract_rmtuserfreearg(struct MapRUF_Arg *ruf_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int 		len;
	u8			temp_buf[256];

	ruf_ptr->param_flag = 0;
	if (buf_len == 0)
	{
		mapp_log_debug("MAPP--extract_remote user free buf_len=0");
		return RER;
	}
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	len = get_tlv("0",temp_buf,&asn_buf);
	if (len==IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0)	//get imsi
	{
		ruf_ptr->param_flag |= 0x01;
		memcpy(ruf_ptr->imsi,temp_buf,IMSI_LEN);
	}
	else
		return RER;
	len = get_tlv("1",temp_buf,&asn_buf);	// get call info
	if (len > 0)
	{
		if (!extract_extsiginfo(&ruf_ptr->call_info,len,temp_buf))
			return RER;
		ruf_ptr->param_flag |= 0x02;
	}
	else
		return RER;
	len = get_tlv("2",temp_buf,&asn_buf);	// get ccbs feature
	if (len > 0)
	{
		if (!extract_ccbsfeat(&ruf_ptr->ccbs_feat,len,temp_buf))
			return RER;
		ruf_ptr->param_flag |= 0x04;
	}
	else
		return RER;
	len = get_tlv("3",temp_buf,&asn_buf);	// get tranlate number
	if (len > 0 && len <= ISDN_LEN)
	{
		ruf_ptr->param_flag |= 0x08;
		ruf_ptr->trans_num[0] = len;
		memcpy(ruf_ptr->trans_num+1,temp_buf,len);
	}
	else
		return RER;
	if (get_tlv("4",temp_buf,&asn_buf) != -1)	// get replace number
	{
		ruf_ptr->param_flag |= 0x10;
		ruf_ptr->replace_num = 1;
	}
	if (get_tlv("5",temp_buf,&asn_buf) == 1)	// get alert pattern
	{
		ruf_ptr->param_flag |= 0x20;
		ruf_ptr->alt_pattern = temp_buf[0];
	}
	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding remote user free response		*/
/*  ++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_rmtuserfreeres(struct MapRUF_Res *ruf_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	u8			temp_buf[256];

	asn_encode(buf,&asn_buf);
	if (ruf_ptr->param_flag & 0x01)		// ruf outcome
	{
		temp_buf[0] = ruf_ptr->ruf_outcome;
		buf_len = add_tlv("0",1,temp_buf,0x80,&asn_buf);
	}
	else
		return RER;
	return buf_len;
}

int extract_rmtuserfreeres(struct MapRUF_Res *ruf_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	u8			temp_buf[256];

	ruf_ptr->param_flag = 0;
	if (buf_len == 0)
	{
		mapp_log_debug("MAPP--extract_remote user free buf_len=0");
		return RER;
	}
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	if (get_tlv("0",temp_buf,&asn_buf) == 1)
	{
		ruf_ptr->param_flag |= 0x01;
		ruf_ptr->ruf_outcome = temp_buf[0];
	}
	else
		return RER;
	return ROK;
}


//umts	add by gxchen	start
/*	++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding ist-Alert argument		*/
/*  ++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_istalertarg(struct MapISTAlert_Arg *ista_ptr, u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len = 0;
	
	asn_encode(buf, &asn_buf);
	if(ista_ptr->param_flag & 0x01)		// imsi
		buf_len = add_tlv("0", IMSI_LEN, ista_ptr->imsi, 0x80, &asn_buf);
	else
	{
		mapp_log_debug("assign istalertarg lack IMSI");
		return RER;
	}

	return buf_len;
}
int extract_istalertarg(struct MapISTAlert_Arg *ista_ptr, u32 buf_len, u8 *buf)
{
	ASN_BUF		asn_buf;
	int			len=0;
	u8			temp_buf[256];

	ista_ptr->param_flag = 0;
	if(buf_len == 0)
	{
		mapp_log_debug("MAPP--extract istalertarg buf_len=0");
		return RER;
	}
	if(asn_decode_v3(buf, buf_len, &decErr, &asn_buf) == -1)
		return RER;
	len = get_tlv("0", temp_buf, &asn_buf);
	if(len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0)	//get imsi
	{
		ista_ptr->param_flag |= 0x01;
		memcpy(ista_ptr->imsi, temp_buf, len);
	}
	else
	{
		mapp_log_debug("extract istalertarg lack IMSI");
		return RER;
	}

	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding ist-Alert response		*/
/*  ++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_istalertres(struct MapISTAlert_Res *ista_ptr, u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len = 0;
	
	asn_encode(buf, &asn_buf);
	if(ista_ptr->param_flag & 0x01)	
		buf_len = add_tlv("0", 1, &ista_ptr->ist_alert_timer, 0x80, &asn_buf);
	if(ista_ptr->param_flag & 0x02)	
		buf_len = add_tlv("1", 1, &ista_ptr->ist_info_withdraw, 0x80, &asn_buf);
	if(ista_ptr->param_flag & 0x04)
		buf_len = add_tlv("2", 1, (u8*)&ista_ptr->callterm_ind, 0x80, &asn_buf);

	return buf_len;
}
int extract_istalertres(struct MapISTAlert_Res *ista_ptr, u32 buf_len, u8 *buf)
{
	ASN_BUF		asn_buf;
	//int			len=0;
	u8			temp_buf[256];

	ista_ptr->param_flag = 0;
	if(buf_len == 0)
	{
		mapp_log_debug("MAPP--extract istalertres buf_len=0");
		return RER;
	}
	if(asn_decode_v3(buf, buf_len, &decErr, &asn_buf) == -1)
		return RER;
	if(1 == get_tlv("0", temp_buf, &asn_buf))
	{
		ista_ptr->param_flag |= 0x01;
		ista_ptr->ist_alert_timer = temp_buf[0];
	}
	if(1 == get_tlv("1", temp_buf, &asn_buf))
	{
		ista_ptr->param_flag |= 0x02;
		ista_ptr->ist_info_withdraw = temp_buf[0];
	}
	if(1 == get_tlv("2", temp_buf, &asn_buf))
	{
		ista_ptr->param_flag |= 0x04;
		ista_ptr->callterm_ind = temp_buf[0];
	}

	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding ist-Commad argument		*/
/*  ++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_istcmdarg(struct MapISTCmd_Arg *istc_ptr, u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len = 0;
	
	asn_encode(buf, &asn_buf);
	if(istc_ptr->param_flag & 0x01)		// imsi
		buf_len = add_tlv("0", IMSI_LEN, istc_ptr->imsi, 0x80, &asn_buf);
	else
	{
		mapp_log_debug("assign istcmdarg lack IMSI");
		return RER;
	}

	return buf_len;
}
int extract_istcmdarg(struct MapISTCmd_Arg *istc_ptr, u32 buf_len, u8 *buf)
{
	ASN_BUF		asn_buf;
	int			len=0;
	u8			temp_buf[256];

	istc_ptr->param_flag = 0;
	if(buf_len == 0)
	{
		mapp_log_debug("MAPP--extract istcmdarg buf_len=0");
		return RER;
	}
	if(asn_decode_v3(buf, buf_len, &decErr, &asn_buf) == -1)
		return RER;
	len = get_tlv("0", temp_buf, &asn_buf);
	if(len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0)	//get imsi
	{
		istc_ptr->param_flag |= 0x01;
		memcpy(istc_ptr->imsi, temp_buf, len);
	}
	else
	{
		mapp_log_debug("extract istcmdarg lack IMSI");
		return RER;
	}

	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding ist-Commad response		*/
/*  ++++++++++++++++++++++++++++++++++++++++++++	*/
/*int assign_istcmdres(struct MapISTCmd_Res *istc_ptr,u8 *buf)
{
}
int extract_istcmdres(struct MapISTCmd_Res *istc_ptr,u32 buf_len,u8 *buf)
{
}
*/
//add by gxchen	end

