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

#include "map_includes.h"

int assign_fwdfeat(struct FwdFeat_struct *fwd_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	u32			flag1;
	int			buf_len=0;
	int			temp_len;
	char		temp_buf[256];

	asn_encode(buf,&asn_buf);
	buf_len = add_null("16",0x20,&asn_buf);
	flag1 = fwd_ptr->param_flag;
	if (flag1 & 0x01)	// bs code
	{
		if (fwd_ptr->bs_code.param_flag == 1)
		{
			temp_len = tele_bittostr(fwd_ptr->bs_code.tele_code,temp_buf,1);
			buf_len = add_tlv("16.3",temp_len,temp_buf,0x80,&asn_buf);
		}
		else if (fwd_ptr->bs_code.param_flag == 2)
		{
			temp_len = bearer_bittostr(fwd_ptr->bs_code.bearer_code,temp_buf,1);
			buf_len = add_tlv("16.2",temp_len,temp_buf,0x80,&asn_buf);
		}
	}
	else
	{
		temp_buf[0] = 0x10;
		buf_len = add_tlv("16.3",1,temp_buf,0x80,&asn_buf);
	}
	
	if (flag1 & 0x02)	//ss status
		buf_len = add_tlv("16.4",1,&fwd_ptr->ss_status,0x80,&asn_buf);
	if (flag1 & 0x04)	//fwdto_num
		buf_len = add_tlv("16.5",fwd_ptr->fwdto_num[0],fwd_ptr->fwdto_num+1,0x80,&asn_buf);
	/**
	if (flag1 & 0x08) //fwdto sub addr
	{
		sprintf(tlv5,"%s.8-%d",tlv4,tag5++);
		buf_len = add_tlv(tlv5,ISDNSUB_LEN,fwd_ptr->fwdto_subadd,0x80,&asn_buf);
	}
	**/
	if (flag1 & 0x08)	//fwd opt
		buf_len = add_tlv("16.6",1,&fwd_ptr->fwd_option,0x80,&asn_buf);
	if (flag1 & 0x10)	//norc time
		buf_len = add_tlv("16.7",1,&fwd_ptr->norc_time,0x80,&asn_buf);
	return buf_len;
}

int extract_fwdfeat(struct FwdFeat_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("16.2",temp_buf,&asn_buf);
	if (len != -1)	// bearer code
	{
		fwd_ptr->param_flag |= 0x01; // bs code
		fwd_ptr->bs_code.param_flag = 2; // bearer
		fwd_ptr->bs_code.bearer_code = bearer_strtobit(temp_buf,len);
	}
	len = get_tlv("16.3",temp_buf,&asn_buf);
	if (len != -1)	// tele code
	{
		fwd_ptr->param_flag |= 0x01; // bs code
		fwd_ptr->bs_code.param_flag = 1;// tele
		fwd_ptr->bs_code.tele_code = tele_strtobit(temp_buf,len);
	}
	if (get_tlv("16.4",temp_buf,&asn_buf) == 1)	// ss status
	{
		fwd_ptr->param_flag |= 0x02; // ss status
		fwd_ptr->ss_status = temp_buf[0];
	}
	len = get_tlv("16.5",temp_buf,&asn_buf);
	if (len != -1 && len <= ISDN_LEN)
	{
		fwd_ptr->param_flag |= 0x04; // fwd to num
		fwd_ptr->fwdto_num[0]=len;
		memcpy(fwd_ptr->fwdto_num+1,temp_buf,len);
	}
	/**
	len = get_tlv("8",temp_buf,&asn_buf);
	if (len >= 1)
	{
		fwd_ptr->param_flag |= 0x08; // fwd to sub addr
		memcpy(fwd_ptr->fwdto_subadd,temp_buf,len);
	}
	**/
	if (get_tlv("16.6",temp_buf,&asn_buf) == 1)	// forward option
	{
		fwd_ptr->param_flag |= 0x08; // fwd opt
		fwd_ptr->fwd_option = temp_buf[0];
	}
	if (get_tlv("16.7",temp_buf,&asn_buf) == 1)	// no reply condition time
	{
		fwd_ptr->param_flag |= 0x10; // norc time
		fwd_ptr->norc_time = temp_buf[0];
	}
	return ROK;
}

int assign_ssforbscode(struct SsForBsCode_struct *BSptr, u8 *buf)
{
	ASN_BUF		asn_buf;
	u32			flag;
	int			buf_len=0;
	int			temp_len;
	char		temp_buf[256];
			
	asn_encode(buf,&asn_buf);
	flag = BSptr->param_flag;
	if (flag & 0x01)
		buf_len = add_tlv("4-1",1,&BSptr->ss_code,0x00,&asn_buf);
	else
	{
		mapp_log_debug("MAPP--encode_ss_for_bs_code has not ss_code");
		return RER;
	}
	if (flag & 0x02)
	{
		if (BSptr->bs_code.param_flag == 2)	//bearer code
		{
			temp_len = bearer_bittostr(BSptr->bs_code.bearer_code,temp_buf,1);
			buf_len = add_tlv("2-2",temp_len,temp_buf,0x80,&asn_buf);
		}
		else if (BSptr->bs_code.param_flag == 1)
		{
			temp_len = tele_bittostr(BSptr->bs_code.tele_code,temp_buf,1);
			buf_len = add_tlv("3-2",temp_len,temp_buf,0x80,&asn_buf);
		}
	}
	return buf_len;				
}

int extract_ssforbscode(struct SsForBsCode_struct *BSptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			len;
	u8			temp_buf[256];
	
	BSptr->param_flag = 0;
	if (buf_len == 0)
		return RER;
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	if(get_tlv("4",temp_buf,&asn_buf) == 1)
	{
		BSptr->param_flag |= 0x01;	//ss code
		BSptr->ss_code = temp_buf[0];
	}
	else
		return RER;
	if ((len=get_tlv("2",temp_buf,&asn_buf)) != -1)
	{
		BSptr->param_flag |= 0x02;//bs code
		BSptr->bs_code.param_flag = 2;//bearer
		BSptr->bs_code.bearer_code = bearer_strtobit(temp_buf,len);
	}
	else if ((len=get_tlv("3",temp_buf,&asn_buf)) != -1)
	{
		BSptr->param_flag |= 0x02;//bs code
		BSptr->bs_code.param_flag = 1;//tele
		BSptr->bs_code.tele_code = tele_strtobit(temp_buf,len);
	}	
	return ROK;				
}	

int assign_ssinfo(struct SsInfo_struct *sf_ptr,u8 *buf)
{	
	u32			flag1;
	ASN_BUF		asn_buf;
	int			buf_len=0;
	int			temp_len;
	u8			temp_buf[256];
	u8			tag2;
	char		tlv2[32];
	struct 		FwdInfo_struct	*fwd_ptr;
	struct		SsData_struct	*ss_ptr;
	struct		CBInfo_struct	*cbinf_ptr;

	asn_encode(buf,&asn_buf);
	if (sf_ptr->choice_flag == 1)	//forward info, flag = 1
	{
		fwd_ptr = (FwdInfo_struct*) &sf_ptr->choice.fwd_info;
		if (fwd_ptr->param_flag & 0x01)	// ss code
			buf_len = add_tlv("0.4",1,&fwd_ptr->ss_code,0x00,&asn_buf);
		if (fwd_ptr->param_flag & 0x02)	// forwarding feature list
		{
			temp_len = assign_fwdfeat(&fwd_ptr->fwd_feat,temp_buf);
			buf_len = add_tlv("0.16",temp_len,temp_buf,0x20,&asn_buf);
		}
		else
			return RER;
	}
	else if (sf_ptr->choice_flag == 2)	//call barring info, flag = 2
	{
		cbinf_ptr = (CBInfo_struct*)&sf_ptr->choice.cb_info;
		if (cbinf_ptr->param_flag & 0x01)	// ss code
			buf_len = add_tlv("1.4",1,&cbinf_ptr->ss_code,0x00,&asn_buf);
		if (cbinf_ptr->param_flag & 0x02)	// call barring feature list
		{
			flag1 = cbinf_ptr->cb_feat.param_flag;
			if (flag1 & 0x01)	// bs code
			{
				temp_len = assign_bscode(&cbinf_ptr->cb_feat.bs_code,temp_buf,1);
				buf_len = add_null("1.16",0x20,&asn_buf);
				buf_len = add_tlv("1.16.16",temp_len,temp_buf,0x20,&asn_buf);
				if (flag1 & 0x02)
					buf_len = add_tlv("1.16.16.4",1,&cbinf_ptr->cb_feat.ss_status,0x80,&asn_buf);
			}
			else if (flag1 & 0x02)	//ss status
			{
				buf_len = add_null("1.16",0x20,&asn_buf);
				buf_len = add_null("1.16.16",0x20,&asn_buf);
				buf_len = add_tlv("1.16.16.4",1,&cbinf_ptr->cb_feat.ss_status,0x80,&asn_buf);
			}
		}
		else
			return RER;		
	}
	else if (sf_ptr->choice_flag == 3)		//ss data, flag = 3
	{	
		ss_ptr = (SsData_struct*)&sf_ptr->choice.ss_data;
		tag2 = 1;
		if (ss_ptr->param_flag & 0x01)	//ss-code
		{
			sprintf(tlv2,"3.4-%d",tag2++);
			buf_len = add_tlv(tlv2,1,&ss_ptr->ss_code,0x00,&asn_buf);
		}
		if (ss_ptr->param_flag & 0x02)	//ss-status	
		{	
			sprintf(tlv2,"3.4-%d",tag2++);
			buf_len = add_tlv(tlv2,1,&ss_ptr->ss_status,0x80,&asn_buf);
		}		
		if (ss_ptr->param_flag & 0x04)	//ss-subscriptionOption
		{
			if (ss_ptr->subs_opt.choice_flag == 1)
			{
				sprintf(tlv2,"3.2-%d",tag2);
				temp_buf[0] = ss_ptr->subs_opt.choice.clires_opt;
				buf_len = add_tlv(tlv2,1,temp_buf,0x80,&asn_buf);
			}
			else if (ss_ptr->subs_opt.choice_flag == 2)
			{
				sprintf(tlv2,"3.1-%d",tag2);
				temp_buf[0] = ss_ptr->subs_opt.choice.over_cate;
				buf_len = add_tlv(tlv2,1,temp_buf,0x80,&asn_buf);
			}
			tag2 ++;
		}
		if (ss_ptr->param_flag & 0x08)	//basicServiceGroupList
		{
			temp_len = assign_bscode(&ss_ptr->bs_code,temp_buf,1);
			sprintf(tlv2,"3.16-%d",tag2++);
			buf_len = add_tlv(tlv2,temp_len,temp_buf,0x20,&asn_buf);
		}
		if (ss_ptr->param_flag & 0x10)	// default priority
		{
			sprintf(tlv2,"3.4-%d",tag2);
			buf_len = add_tlv(tlv2,1,&ss_ptr->default_prio,0x00,&asn_buf);
		}
	}
	else
		return RER;
	return buf_len;
}	

int extract_ssinfo(struct SsInfo_struct *sf_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF	asn_buf;
	int		len;
	u8		tag2;
	u8		tlv2[32];
	u8		temp_buf[256];
	struct	FwdInfo_struct		*fwd_ptr;
	struct	CBInfo_struct		*cbinf_ptr;
	struct	SsData_struct		*ss_ptr;
	
	sf_ptr->choice_flag = 0;
	if (buf_len == 0)
	{
		mapp_log_debug("decode SS info buf_len=0");
		return ROK;
	}	
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return 0;
	if (get_tlv("0",temp_buf,&asn_buf) > 0)	//---forwardingInfo
	{	
		sf_ptr->choice_flag = 1;
		fwd_ptr = (FwdInfo_struct*) &sf_ptr->choice.fwd_info;
		fwd_ptr->param_flag = 0;
		fwd_ptr->fwd_feat.param_flag = 0;
		if (get_tlv("0.4",temp_buf,&asn_buf) == 1)	// ss code
		{
			fwd_ptr->param_flag |= 0x01;
			fwd_ptr->ss_code = temp_buf[0];
		}
		len = get_tlv("0.16",temp_buf,&asn_buf);
		if (len != -1)	//
		{
			fwd_ptr->param_flag |= 0x02; // fwd feat
			if (!extract_fwdfeat(&fwd_ptr->fwd_feat,len,temp_buf))
				return RER;
		}
	}	
	else if (get_tlv("1",temp_buf,&asn_buf) > 1)	//callBarringInfo
	{
		sf_ptr->choice_flag = 2;
		cbinf_ptr = (CBInfo_struct*)&sf_ptr->choice.cb_info;
		cbinf_ptr->param_flag=0;
		cbinf_ptr->cb_feat.param_flag = 0;
		if (get_tlv("1.4",temp_buf,&asn_buf) == 1)	// ss code
		{
			cbinf_ptr->param_flag |= 0x01; // ss code
			cbinf_ptr->ss_code = temp_buf[0];
		}
		len = get_tlv("1.16",temp_buf,&asn_buf);	// basic code
		if (len != -1)
		{
			cbinf_ptr->param_flag |= 0x02; // call barring info
			cbinf_ptr->cb_feat.param_flag |= 0x01; // bs code
			extract_bscode(&cbinf_ptr->cb_feat.bs_code,len,temp_buf);
		}
		if (get_tlv("1.16.4",temp_buf,&asn_buf) == 1)	// ss status
		{
			cbinf_ptr->param_flag |= 0x02; // call barring info
			cbinf_ptr->cb_feat.param_flag |= 0x02; // ss status
			cbinf_ptr->cb_feat.ss_status = temp_buf[0];
		}
	}
	else if (get_tlv("3",temp_buf,&asn_buf) > 1)	//ss-Data
	{
		sf_ptr->choice_flag = 3;
		ss_ptr = (SsData_struct*) &sf_ptr->choice.ss_data;
		ss_ptr->param_flag = 0;
		if (get_tlv("3.4-1",temp_buf,&asn_buf) == 1)	// ss code
		{
			ss_ptr->param_flag |= 0x01; // ss code
			ss_ptr->ss_code = temp_buf[0];
		}
		tag2 = 2;
		sprintf(tlv2,"3.4-%d",tag2);
		if (get_tlv(tlv2,temp_buf,&asn_buf) == 1)	// ss-status
		{
			ss_ptr->param_flag |= 0x02;
			ss_ptr->ss_status = temp_buf[0];
			tag2 ++;
		}
		if (get_tlv("3.2",temp_buf,&asn_buf) == 1)	// cli restrction option
		{
			ss_ptr->param_flag |= 0x04; // subs opt
			ss_ptr->subs_opt.choice_flag = 1; // clires opt
			ss_ptr->subs_opt.choice.clires_opt = temp_buf[0];
			tag2 ++;
		}
		if (get_tlv("3.1",temp_buf,&asn_buf) == 1)	// override category
		{
			ss_ptr->param_flag |= 0x04; // subs opt
			ss_ptr->subs_opt.choice_flag = 2; // clires opt
			ss_ptr->subs_opt.choice.over_cate = temp_buf[0];
			tag2 ++;
		}
		len = get_tlv("3.16",temp_buf,&asn_buf);	// basic code
		if (len != -1)
		{
			extract_bscode(&ss_ptr->bs_code,len,temp_buf);
			ss_ptr->param_flag |= 0x08; // bs code
			tag2 ++;
		}
		sprintf(tlv2,"3.4-%d",tag2);
		if (get_tlv(tlv2,temp_buf,&asn_buf) == 1)	// default priority
		{
			ss_ptr->param_flag |= 0x10;
			ss_ptr->default_prio = temp_buf[0];
			tag2 ++;
		}
	}
	else
		return RER;	
	return ROK;	
}	

int assign_ussdarg(struct UssdArg_struct *ussd_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	u8			tag1;
	u8			tlv1[32];

	asn_encode(buf,&asn_buf);
	if (ussd_ptr->param_flag & 0x01)	// ussd scheme
		buf_len = add_tlv("4-1",1,&ussd_ptr->ussd_scheme,0x00,&asn_buf);
	else
		return RER;
	if (ussd_ptr->param_flag & 0x02)	// ussd string
	{
		if (ussd_ptr->ussd_string.string_len > USSD_LEN)
			return RER;
		buf_len = add_tlv("4-2",ussd_ptr->ussd_string.string_len,ussd_ptr->ussd_string.ussd_data,0x00,&asn_buf);
	}
	else
		return RER;
	tag1 = 3;
	if (ussd_ptr->param_flag & 0x04)	// alert pattern
	{
		sprintf(tlv1,"4-%d",tag1++);
		buf_len = add_tlv(tlv1,1,&ussd_ptr->alt_pattern,0x00,&asn_buf);
	}
	if (ussd_ptr->param_flag & 0x08)	// msisdn
	{
		sprintf(tlv1,"0-%d",tag1++);
		buf_len = add_tlv(tlv1,ussd_ptr->msisdn[0],ussd_ptr->msisdn+1,0x80,&asn_buf);
	}
	return buf_len;
}

int extract_ussdarg(struct UssdArg_struct *ussd_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int 		len;
	u8			temp_buf[256];

	ussd_ptr->param_flag = 0;
	if (buf_len == 0)
		return RER;
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	if (get_tlv("4-1",temp_buf,&asn_buf) == 1)	// ussd scheme
	{
		ussd_ptr->param_flag |= 0x01;
		ussd_ptr->ussd_scheme = temp_buf[0];
	}
	else
		return RER;
	len = get_tlv("4-2",temp_buf,&asn_buf);		// ussd data
	if (len > 0 && len <= USSD_LEN)
	{
		ussd_ptr->param_flag |= 0x02;
		ussd_ptr->ussd_string.string_len = len;
		memcpy(ussd_ptr->ussd_string.ussd_data,temp_buf,len);
	}
	else
		return RER;
	if (get_tlv("4-3",temp_buf,&asn_buf) == 1)	// alert pattern
	{
		ussd_ptr->param_flag |= 0x04;
		ussd_ptr->alt_pattern = temp_buf[0];
	}
	len = get_tlv("0",temp_buf,&asn_buf);		// msisdn
	if (len > 0 && len <= ISDN_LEN)
	{
		ussd_ptr->param_flag |= 0x08;
		ussd_ptr->msisdn[0] = len;
		memcpy(ussd_ptr->msisdn+1,temp_buf,len);
	}
	return ROK;
}

int assign_ussdres(struct UssdRes_struct *ussd_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;

	asn_encode(buf,&asn_buf);
	if (ussd_ptr->param_flag & 0x01)	// ussd scheme
		buf_len = add_tlv("4-1",1,&ussd_ptr->ussd_scheme,0x00,&asn_buf);
	else
		return RER;
	if (ussd_ptr->param_flag & 0x02)	// ussd string
	{
		if (ussd_ptr->ussd_string.string_len > USSD_LEN)
			return RER;
		buf_len = add_tlv("4-2",ussd_ptr->ussd_string.string_len,ussd_ptr->ussd_string.ussd_data,0x00,&asn_buf);
	}
	else
		return RER;
	return buf_len;
}

int extract_ussdres(struct UssdRes_struct *ussd_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int 		len;
	u8			temp_buf[256];

	ussd_ptr->param_flag = 0;
	if (buf_len == 0)
		return RER;
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	if (get_tlv("4-1",temp_buf,&asn_buf) == 1)	// ussd scheme
	{
		ussd_ptr->param_flag |= 0x01;
		ussd_ptr->ussd_scheme = temp_buf[0];
	}
	else
		return RER;
	len = get_tlv("4-2",temp_buf,&asn_buf);		// ussd data
	if (len > 0 && len <= USSD_LEN)
	{
		ussd_ptr->param_flag |= 0x02;
		ussd_ptr->ussd_string.string_len = len;
		memcpy(ussd_ptr->ussd_string.ussd_data,temp_buf,len);
	}
	else
		return RER;
	return ROK;
}

/* ++++++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding register SS argument	*/
/* ++++++++++++++++++++++++++++++++++++++	*/
int assign_regssarg(struct MapRSS_Arg *rss_ptr, u8 *buf)
{
	ASN_BUF		asn_buf;
	u32			flag;
	int			buf_len=0;
	u8			tag1;
	u8			tlv1[32];
	int			temp_len;
	u8			temp_buf[256];

	asn_encode(buf,&asn_buf);
	flag = rss_ptr->param_flag;
	if(flag & 0x01) // ss-code
		buf_len = add_tlv("4-1",1,&rss_ptr->ss_code,0x00,&asn_buf);
	else
	{
		mapp_log_debug("register SS request lack ss code");
		return RER;
	}
	tag1 = 2;
	if(flag & 0x02) // basic service code
	{
		if (rss_ptr->bs_code.param_flag & 0x01)
		{
			sprintf(tlv1,"3-%d",tag1++);
			temp_len = tele_bittostr(rss_ptr->bs_code.tele_code,temp_buf,1);
			buf_len = add_tlv(tlv1,temp_len,temp_buf,0x80,&asn_buf);
		}
		else if (rss_ptr->bs_code.param_flag & 0x02)
		{
			sprintf(tlv1,"2-%d",tag1++);
			temp_len = bearer_bittostr(rss_ptr->bs_code.bearer_code,temp_buf,1);
			buf_len = add_tlv(tlv1,temp_len,temp_buf,0x80,&asn_buf);
		}
	}
	if (flag & 0x04)	// fwdToNum
	{
		sprintf(tlv1,"4-%d",tag1++);
		temp_len = rss_ptr->fwdto_num[0];
		if(temp_len>ISDN_LEN) temp_len = ISDN_LEN;
		buf_len = add_tlv(tlv1,temp_len,rss_ptr->fwdto_num+1,0x80,&asn_buf);
	}
	/**
	if((flag & 0x08) != 0x08) // no fwdToSubAdr
		mapp_log_debug("register SS request lack fwdToSubAdr");
	else
	{
		sprintf(tlv1,"6-%d",tag1++);
		len = rss_ptr->fwdto_subadd[0];
		buf_len = add_tlv(tlv1,len,rss_ptr->fwdto_subadd+1,0x80,&asn_buf);
	}
**/
	if (flag & 0x08) // nrc time
	{
		sprintf(tlv1,"5-%d",tag1++);
		buf_len = add_tlv(tlv1,1,&rss_ptr->norc_time,0x80,&asn_buf);
	}
	if(flag & 0x10) // default prio
	{
		sprintf(tlv1,"7-%d",tag1++);
		buf_len = add_tlv(tlv1,1,&rss_ptr->default_prio,0x80,&asn_buf);
	}
	return buf_len;
}

int extract_regssarg(struct MapRSS_Arg *rss_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			len;
	u32			flag=0;
	u8			temp_buf[256];
	u8			tag1;
	u8			tlv1[32];
	
	rss_ptr->param_flag = 0;	
	if (buf_len == 0)
		return RER;
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	if (get_tlv("4-1",temp_buf,&asn_buf) == 1)
	{
		rss_ptr->ss_code = temp_buf[0];
		flag |= 0x01;
	}
	else
	{
		mapp_log_debug("extract_regssarg:lack ss_code");
		return RER;
	}
	tag1 = 2;
	if ((len=get_tlv("2",temp_buf,&asn_buf)) != -1)
	{
		flag |= 0x02;
		rss_ptr->bs_code.param_flag = 2;
		rss_ptr->bs_code.bearer_code = bearer_strtobit(temp_buf,len);
		tag1 ++;
	}
	if ((len=get_tlv("3",temp_buf,&asn_buf)) != -1)
	{
		flag |= 0x02;
		rss_ptr->bs_code.param_flag = 1;
		rss_ptr->bs_code.tele_code =tele_strtobit(temp_buf,len);
		tag1 ++;
	}
	sprintf(tlv1,"4-%d",tag1);
	len = get_tlv(tlv1,temp_buf,&asn_buf);
	if (len >= 1)
	{
		flag |= 0x04;
		if(len>ISDN_LEN) len = ISDN_LEN;
		rss_ptr->fwdto_num[0] = len;
		memcpy(rss_ptr->fwdto_num+1,temp_buf,len);
	}
	/**
	sprintf(tlv1,"6-%d",tag1);
	len=get_tlv(tlv1,temp_buf,&asn_buf);	
	if (len>=1)
	{
		tag1++;
		mapp_log_debug("extract_regssarg: get fwdToSubAddr");
		rss_ptr->fwdto_subadd[0]=len;
		memcpy(rss_ptr->fwdto_subadd+1,temp_buf,len);
		flag |= 0x08;
	}
	**/
	if (get_tlv("5",temp_buf,&asn_buf) == 1)
	{
		rss_ptr->norc_time = temp_buf[0];
		flag |= 0x08;
	}
	if (get_tlv("7",temp_buf,&asn_buf) == 1)
	{
		rss_ptr->default_prio = temp_buf[0];
		flag |= 0x10;
	}
	rss_ptr->param_flag = flag;
	return ROK;
}

/* ++++++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding register SS response	*/
/* ++++++++++++++++++++++++++++++++++++++	*/
int assign_regssres(struct MapRSS_Res *rss_ptr,u8 *buf)
{
	if (rss_ptr->param_flag & 0x01)
		return assign_ssinfo(&rss_ptr->ss_info,buf);
	else
		return 0;
}

int extract_regssres(struct MapRSS_Res *rss_ptr,u32 buf_len,u8 *buf)
{
	int return_value;
	
	rss_ptr->param_flag = 0;
	if (buf_len == 0)
		return ROK;
	return_value = extract_ssinfo(&rss_ptr->ss_info,buf_len,buf);
	if (return_value == ROK)
	{
		rss_ptr->param_flag |= 0x01;
		return ROK;
	}
	return RER;
}

/* +++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding erase SS argument	*/
/* +++++++++++++++++++++++++++++++++++	*/
int assign_erassarg(struct MapESS_Arg *ess_ptr, u8 *buf)
{
	if (ess_ptr->param_flag & 0x01)
		return assign_ssforbscode(&ess_ptr->ss_forbs,buf);
	else
		return RER;
}

int extract_erassarg(struct MapESS_Arg *ess_ptr,u32 buf_len,u8 *buf)
{
	int return_value;

	ess_ptr->param_flag = 0;
	if (buf_len == 0)
		return RER;
	return_value = extract_ssforbscode(&ess_ptr->ss_forbs,buf_len,buf);
	if (return_value == ROK)
	{
		ess_ptr->param_flag |= 0x01;
		return ROK;
	}	
	return RER;	
}

/* +++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding erase SS response	*/
/* +++++++++++++++++++++++++++++++++++	*/
int assign_erassres(MapESS_Res *essr_ptr, u8 *buf)
{
	if (essr_ptr->param_flag & 0x01)
		return assign_ssinfo(&essr_ptr->ss_info,buf);
	else
		return 0;	
}

int extract_erassres(struct MapESS_Res *essr_ptr,u32 buf_len,u8 *buf)
{
	int return_value;
	
	essr_ptr->param_flag = 0;
	if (buf_len == 0)
		return ROK;
	return_value = extract_ssinfo(&essr_ptr->ss_info,buf_len,buf);
	if (return_value == ROK)
	{
		essr_ptr->param_flag |= 0x01;
		return ROK;
	}	
	return RER;
}

/* ++++++++++++++++++++++++++++++++++++		*/
/* encoding/decoding active SS argument		*/
/* ++++++++++++++++++++++++++++++++++++		*/
int assign_actssarg(MapASS_Arg *ass_ptr, u8 *buf)
{
	if (ass_ptr->param_flag & 0x01)
		return assign_ssforbscode(&ass_ptr->ss_forbs,buf);
	else
		return RER;	
}

int extract_actssarg(struct MapASS_Arg *ass_ptr,u32 buf_len,u8 *buf)
{
	int return_value;
			
	ass_ptr->param_flag = 0;
	if (buf_len == 0)
		return RER;
	return_value = extract_ssforbscode(&ass_ptr->ss_forbs,buf_len,buf);
	if(return_value == ROK)
	{
		ass_ptr->param_flag |= 0x01;
		return ROK;
	}	
	return RER;	
}

/* ++++++++++++++++++++++++++++++++++++		*/
/* encoding/decoding active SS response		*/
/* ++++++++++++++++++++++++++++++++++++		*/
int assign_actssres(MapASS_Res *assr_ptr,u8 *buf)
{
	if (assr_ptr->param_flag & 0x01)
		return assign_ssinfo(&assr_ptr->ss_info,buf);
	else
		return 0;	
}

int extract_actssres(struct MapASS_Res *assr_ptr,u32 buf_len,u8 *buf)
{
	int return_value;
	
	assr_ptr->param_flag = 0;
	if (buf_len == 0)
		return ROK;
	return_value = extract_ssinfo(&assr_ptr->ss_info,buf_len,buf);
	if(return_value == ROK)
	{
		assr_ptr->param_flag |= 0x01;
		return ROK;
	}	
	return RER;
}

/* ++++++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding deactive SS argument	*/
/* ++++++++++++++++++++++++++++++++++++++	*/
int assign_deactssarg(MapDASS_Arg *dss_ptr,u8 *buf)
{
	if (dss_ptr->param_flag & 0x01)
		return assign_ssforbscode(&dss_ptr->ss_forbs,buf);
	else
		return RER;
}

int extract_deactssarg(struct MapDASS_Arg *dss_ptr,u32 buf_len,u8 *buf)
{
	int return_value;

	dss_ptr->param_flag = 0;
	if (buf_len == 0)
		return RER;
	return_value = extract_ssforbscode(&dss_ptr->ss_forbs,buf_len,buf);
	if(return_value == ROK)
	{
		dss_ptr->param_flag |= 0x01;
		return ROK;
	}
	return RER;	
}

/* ++++++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding deactive SS response	*/
/* ++++++++++++++++++++++++++++++++++++++	*/
int assign_deactssres(MapDASS_Res *dssr_ptr,u8 *buf)
{
	if (dssr_ptr->param_flag & 0x01)
		return assign_ssinfo(&dssr_ptr->ss_info,buf);
	else
		return 0;	
}

int extract_deactssres(struct MapDASS_Res *dssr_ptr,u32 buf_len,u8 *buf)
{
	int return_value;
	
	dssr_ptr->param_flag = 0;
	if (buf_len == 0)
		return ROK;
	return_value = extract_ssinfo(&dssr_ptr->ss_info,buf_len,buf);
	if(return_value == ROK)
	{
		dssr_ptr->param_flag |= 0x01;
		return ROK;
	}
	return RER;
}

/* ++++++++++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding interrogate SS argument	*/
/* ++++++++++++++++++++++++++++++++++++++++++	*/
int assign_intrssarg(MapINTSS_Arg *intrss_ptr, u8 *buf)
{
	if (intrss_ptr->param_flag & 0x01)
		return assign_ssforbscode(&intrss_ptr->ss_forbs,buf);
	else
		return RER;	
}

int extract_intrssarg(struct MapINTSS_Arg *intr_ptr,u32 buf_len,u8 *buf)
{
	int return_value;

	intr_ptr->param_flag = 0;
	if (buf_len == 0)
		return RER;
	return_value = extract_ssforbscode(&intr_ptr->ss_forbs,buf_len,buf);
	if(return_value == ROK)
	{
		intr_ptr->param_flag |= 0x01;
		return ROK;
	}
	return RER;
}

/* ++++++++++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding interrogate SS response	*/
/* ++++++++++++++++++++++++++++++++++++++++++	*/
int assign_intrssres(MapINTSS_Res *intrss_ptr, u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	u32			temp_flag;
	int			temp_len;
	u8			tag1;
	u8			tlv1[32];
	u8			temp_buf[256];
	struct		GenSerInfo_struct	*gen_ptr;

	asn_encode(buf, &asn_buf);
	if ((intrss_ptr->param_flag & 0x01) != 0x01)	// no result
	{
		mapp_log_debug("assign_intrssres: lack ss status");
		return RER;
	}	
	temp_flag = intrss_ptr->result.choice_flag;
	if (temp_flag == 1)		//ss status
		buf_len = add_tlv("0",1,&intrss_ptr->result.choice.ss_status,0x80,&asn_buf);
	else if (temp_flag == 2) 	//basic service group list
	{
		temp_len = assign_bscode(&intrss_ptr->result.choice.bs_code,temp_buf,1);
		buf_len = add_tlv("2",temp_len,temp_buf,0x0a0,&asn_buf);
	}
	else if (temp_flag == 3)	// fwd feature list
	{
		temp_len = assign_fwdfeat(&intrss_ptr->result.choice.fwd_feat,temp_buf);
		buf_len = add_tlv("3",temp_len,temp_buf,0x0a0,&asn_buf);
	}
	else if (temp_flag == 4)	// genser_info
	{
		gen_ptr = (GenSerInfo_struct *) &intrss_ptr->result.choice.genser_info;
		if (gen_ptr->param_flag & 0x01)	// ss status
			buf_len = add_tlv("4.4",1,&gen_ptr->ss_status,0x00,&asn_buf);
		tag1 = 2;
		if (gen_ptr->param_flag & 0x02)	// clires opt
		{
			temp_buf[0] = gen_ptr->clires_opt;
			sprintf(tlv1,"4.10-%d",tag1++);
			buf_len = add_tlv(tlv1,1,temp_buf,0x00,&asn_buf);
		}
		if (gen_ptr->param_flag & 0x04)	// max entitled priority
		{
			sprintf(tlv1,"4.0-%d",tag1++);
			buf_len = add_tlv(tlv1,1,&gen_ptr->maxent_prio,0x00,&asn_buf);
		}
		if (gen_ptr->param_flag & 0x08)	// default priority
		{
			sprintf(tlv1,"4.1-%d",tag1++);
			buf_len = add_tlv(tlv1,1,&gen_ptr->default_prio,0x00,&asn_buf);
		}
		// empty the ccbs feature list
	}
	else
		return RER;
	return buf_len;
}

int extract_intrssres(struct MapINTSS_Res *intrss_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			len;
	u8			temp_buf[256];
	int 		choice_flag=0;
	
	intrss_ptr->param_flag = 0;
	intrss_ptr->result.choice_flag = 0;
	if (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)
	{
		intrss_ptr->result.choice.ss_status = temp_buf[0];
		choice_flag = 1;
	}
	if ((len=get_tlv("2",temp_buf,&asn_buf)) != -1)	// basic service 
	{
		if (!extract_bscode(&intrss_ptr->result.choice.bs_code,len,temp_buf))
			return RER;
		choice_flag = 2;
	}
	len = get_tlv("3",temp_buf,&asn_buf);	//forwardingFeatureList
	if (len > 0)//forwardingFeatureList
	{
		choice_flag = 3;
		if (!extract_fwdfeat(&intrss_ptr->result.choice.fwd_feat,len,temp_buf))
			return RER;
	}
	if (get_tlv("4",temp_buf,&asn_buf)>0)	// generic service info
	{
		choice_flag = 4;
		intrss_ptr->result.choice.genser_info.param_flag = 0;
		if (get_tlv("4.4",temp_buf,&asn_buf) == 1)	// ss status
		{
			intrss_ptr->result.choice.genser_info.ss_status = temp_buf[0];
			intrss_ptr->result.choice.genser_info.param_flag |= 0x01; // ss status
		}
		if (get_tlv("4.10",temp_buf,&asn_buf) == 1)	// cli restriction option
		{
			intrss_ptr->result.choice.genser_info.clires_opt = temp_buf[0];
			intrss_ptr->result.choice.genser_info.param_flag |= 0x02; // cilres opt
		}
		if (get_tlv("4.0",temp_buf,&asn_buf) == 1)	// max entitled priority
		{
			intrss_ptr->result.choice.genser_info.maxent_prio = temp_buf[0];
			intrss_ptr->result.choice.genser_info.param_flag |= 0x04;
		}
		if (get_tlv("4.1",temp_buf,&asn_buf) == 1)	// default priority
		{
			intrss_ptr->result.choice.genser_info.default_prio = temp_buf[0];
			intrss_ptr->result.choice.genser_info.param_flag |= 0x08;
		}
	}	
	if (choice_flag > 0)
	{
		intrss_ptr->result.choice_flag = choice_flag;
		intrss_ptr->param_flag = 0x01;
	}	
	return ROK;
}

/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding process unstructured SS request argument	*/
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_prcunssreqarg(struct MapPUSSR_Arg *psr_ptr,u8 *buf)
{
	if (psr_ptr->param_flag & 0x01)
		return assign_ussdarg(&psr_ptr->ussd_arg,buf);
	else
		return RER;
}

int extract_prcunssreqarg(struct MapPUSSR_Arg *psr_ptr,u32 buf_len,u8 *buf)
{
	if (extract_ussdarg(&psr_ptr->ussd_arg,buf_len,buf))
	{
		psr_ptr->param_flag = 0x01;
		return ROK;
	}
	else
		return RER;
}

/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding process unstructured SS request response	*/
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_prcunssreqres(struct MapPUSSR_Res *psr_ptr,u8 *buf)
{
	if (psr_ptr->param_flag & 0x01)
		return assign_ussdres(&psr_ptr->ussd_res,buf);
	else
		return RER;
}

int extract_prcunssreqres(struct MapPUSSR_Res *psr_ptr,u32 buf_len,u8 *buf)
{
	if (extract_ussdres(&psr_ptr->ussd_res,buf_len,buf))
	{
		psr_ptr->param_flag = 0x01;
		return ROK;
	}
	else
		return RER;
}

/* ++++++++++++++++++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding unstructured ss request argument	*/
/* ++++++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_unssreqarg(struct MapUSSR_Arg *usr_ptr,u8 *buf)
{
	if (usr_ptr->param_flag & 0x01)
		return assign_ussdarg(&usr_ptr->ussd_arg,buf);
	else
		return RER;
}

int extract_unssreqarg(struct MapUSSR_Arg *usr_ptr,u32 buf_len,u8 *buf)
{
	if (extract_ussdarg(&usr_ptr->ussd_arg,buf_len,buf))
	{
		usr_ptr->param_flag = 0x01;
		return ROK;
	}
	else
		return RER;
}

/* ++++++++++++++++++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding unstructured SS request response	*/
/* ++++++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_unssreqres(struct MapUSSR_Res *usr_ptr,u8 *buf)
{
	if (usr_ptr->param_flag & 0x01)
		return assign_ussdres(&usr_ptr->ussd_res,buf);
	else
		return 0;
}

int extract_unssreqres(struct MapUSSR_Res *usr_ptr,u32 buf_len,u8 *buf)
{
	if (buf_len == 0)
		return ROK;
	if (extract_ussdres(&usr_ptr->ussd_res,buf_len,buf))
	{
		usr_ptr->param_flag = 0x01;
		return ROK;
	}
	else
		return RER;
}

/* ++++++++++++++++++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding unstructured ss notify argument	*/
/* ++++++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_unssnotarg(struct MapUSSN_Arg *usn_ptr,u8 *buf)
{
	if (usn_ptr->param_flag & 0x01)
		return assign_ussdarg(&usn_ptr->ussd_arg,buf);
	else
		return RER;
}

int extract_unssnotarg(struct MapUSSN_Arg *usn_ptr,u32 buf_len,u8 *buf)
{
	if (extract_ussdarg(&usn_ptr->ussd_arg,buf_len,buf))
	{
		usn_ptr->param_flag = 0x01;
		return ROK;
	}
	else
		return RER;
}

/* ++++++++++++++++++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding unstructured ss notify response	*/
/* ++++++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_unssnotres(struct MapUSSN_Res *usn_ptr,u8 *buf)
{
	return 0;
}

int extract_unssnotres(struct MapUSSN_Res *usn_ptr,u32 buf_len,u8 *buf)
{
	return ROK;
}

/* +++++++++++++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding register Password argument		*/
/* +++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_regpswdarg(struct MapRPSS_Arg *rpw_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	
	asn_encode(buf,&asn_buf);
	if (rpw_ptr->param_flag & 0x01)
	{
		buf_len = add_tlv("4",1,&rpw_ptr->ss_code,0x00,&asn_buf);
		return buf_len;
	}
	else
		return RER;
}

int extract_regpswdarg(struct MapRPSS_Arg *rpw_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	u8			temp_buf[256];
	
	rpw_ptr->param_flag = 0;
	if (buf_len == 0)
		return RER;
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return 0;
	if (get_tlv("4",temp_buf,&asn_buf) == 1)
	{
		rpw_ptr->ss_code = temp_buf[0];
		rpw_ptr->param_flag |= 0x01;
		return ROK;
	}
	return RER;
}

/* +++++++++++++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding register Password response		*/
/* +++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_regpswdres(struct MapRPSS_Res *rpwr_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	
	asn_encode(buf,&asn_buf);
	if (rpwr_ptr->param_flag & 0x01)
	{
		buf_len = add_tlv("18",PASSWD_LEN,rpwr_ptr->passwd,0x00,&asn_buf);
		return buf_len;
	}
	else
		return RER;
}

int extract_regpswdres(struct MapRPSS_Res *rpwr_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	u8			temp_buf[256];
	
	rpwr_ptr->param_flag = 0;
	if (buf_len == 0)
		return RER;
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return 0;
	if (get_tlv("18",temp_buf,&asn_buf) == PASSWD_LEN)
	{
		memcpy(rpwr_ptr->passwd,temp_buf,PASSWD_LEN);
		rpwr_ptr->param_flag |= 0x01;
		return ROK;
	}
	return RER;
}

/* +++++++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding get Password argument	*/
/* +++++++++++++++++++++++++++++++++++++++	*/
int assign_getpswdarg(struct MapGPSS_Arg *gpw_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	char		temp_buf[32];
	
	asn_encode(buf,&asn_buf);
	if (gpw_ptr->param_flag & 0x01)	// has not
	{
		temp_buf[0] = gpw_ptr->gui_info;
		buf_len = add_tlv("10",1,temp_buf,0x00,&asn_buf);
		return buf_len;
	}
	else
		return RER;
}

int extract_getpswdarg(struct MapGPSS_Arg *gpw_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	u8			temp_buf[256];
	
	gpw_ptr->param_flag = 0;
	if (buf_len == 0)
		return RER;
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	if (get_tlv("10",temp_buf,&asn_buf) > 0)
	{
		gpw_ptr->gui_info = temp_buf[0];
		gpw_ptr->param_flag |= 0x01;
		return ROK;
	}
	return RER;
}

/* +++++++++++++++++++++++++++++++++++++++	*/
/* encoding/decoding get Password response	*/
/* +++++++++++++++++++++++++++++++++++++++	*/
int assign_getpswdres(struct MapGPSS_Res *rpwr_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	
	asn_encode(buf,&asn_buf);
	if (rpwr_ptr->param_flag & 0x01)
	{
		buf_len = add_tlv("18",PASSWD_LEN,rpwr_ptr->passwd,0x00,&asn_buf);
		return buf_len;
	}
	else
		return RER;
}

int extract_getpswdres(struct MapGPSS_Res *rpwr_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	u8			temp_buf[256];
	
	rpwr_ptr->param_flag = 0;
	if (buf_len == 0)
		return RER;
	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)
		return RER;
	if (get_tlv("18",temp_buf,&asn_buf) == PASSWD_LEN)
	{
		memcpy(rpwr_ptr->passwd,temp_buf,PASSWD_LEN);
		rpwr_ptr->param_flag |= 0x01;
		return ROK;
	}
	return RER;
}

/*	+++++++++++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding SS invocation notification argument	*/
/*  +++++++++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_ssinvnotarg(struct MapSSIN_Arg *sin_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	u8			ii;
	u8			tlv1[32];

	asn_encode(buf,&asn_buf);
	if (sin_ptr->param_flag & 0x01)		// imsi
		buf_len = add_tlv("0",IMSI_LEN,sin_ptr->imsi,0x80,&asn_buf);
	else
		return RER;
	if (sin_ptr->param_flag & 0x02)		// msisdn
		buf_len = add_tlv("1",sin_ptr->msisdn[0],sin_ptr->msisdn+1,0x80,&asn_buf);
	else
		return RER;
	if (sin_ptr->param_flag & 0x04)		// ss event
		buf_len = add_tlv("2",1,&sin_ptr->ss_event,0x80,&asn_buf);
	else
		return RER;
	if (sin_ptr->param_flag & 0x08)		// ss event specification
	{
		if (sin_ptr->event.event_len > EVENT_LEN)
			return RER;
		for (ii = 0;ii < sin_ptr->event.event_len;ii ++)
		{
			sprintf(tlv1,"3.4-%d",ii+1);
			buf_len = add_tlv(tlv1,sin_ptr->event.event_spe[ii][0],sin_ptr->event.event_spe[ii]+1,0x00,&asn_buf);
		}
	}
	return buf_len;
}

int extract_ssinvnotarg(struct MapSSIN_Arg *sin_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int 		len;
	u8			temp_buf[256];
	u8			ii;
	u8			tlv1[32];

	sin_ptr->param_flag = 0;
	if (buf_len == 0)
	{
		mapp_log_debug("MAPP--extract_ss invocation notification 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
	{
		sin_ptr->param_flag |= 0x01;
		memcpy(sin_ptr->imsi,temp_buf,IMSI_LEN);
	}
	else
		return RER;
	len = get_tlv("1",temp_buf,&asn_buf);	// get msisdn
	if (len > 0 && len <= ISDN_LEN)
	{
		sin_ptr->param_flag |= 0x02;
		sin_ptr->msisdn[0] = len;
		memcpy(sin_ptr->msisdn+1,temp_buf,len);
	}
	else
		return RER;
	if (get_tlv("2",temp_buf,&asn_buf) == 1)	// ss event
	{
		sin_ptr->param_flag |= 0x04;
		sin_ptr->ss_event = temp_buf[0];
	}
	else
		return RER;
	if (get_tlv("3",temp_buf,&asn_buf) != -1)	// ss event specification
	{
		for (ii = 0;ii < EVENT_LEN;ii ++)
		{
			sprintf(tlv1,"3.4-%d",ii+1);
			len = get_tlv(tlv1,temp_buf,&asn_buf);
			if (len > 0 && len <= ISDN_LEN)
			{
				sin_ptr->param_flag |= 0x08;
				sin_ptr->event.event_spe[ii][0] = len;
				memcpy(sin_ptr->event.event_spe[ii]+1,temp_buf,len);
			}
			else
			{
				sin_ptr->event.event_len = ii;
				break;
			}
		}
	}
	return ROK;
}

/*	+++++++++++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding SS invocation notification response	*/
/*  +++++++++++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_ssinvnotres(struct MapSSIN_Res *sin_ptr,u8 *buf)
{
	return 0;
}

int extract_ssinvnotres(struct MapSSIN_Res *sin_ptr,u32 buf_len,u8 *buf)
{
	return ROK;
}

/*	+++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding register CC entity argument	*/
/*  +++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_regccentarg(struct MapRCCE_Arg *rce_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	int			temp_len;
	u8			temp_buf[256],temp_data[256];

	asn_encode(buf,&asn_buf);
	if (rce_ptr->param_flag & 0x01)		// ss code
		buf_len = add_tlv("0",1,&rce_ptr->ss_code,0x80,&asn_buf);
	else
		return RER;
	if (rce_ptr->param_flag & 0x02)		// CCBS data
	{
		if (rce_ptr->ccbs_data.param_flag & 0x01)	// ccbs feature
		{
			temp_len = assign_ccbsfeat(&rce_ptr->ccbs_data.ccbs_feat,temp_buf);
			buf_len = add_tlv("1.0",temp_len,temp_buf,0x0a0,&asn_buf);
		}
		else
			return RER;
		if (rce_ptr->ccbs_data.param_flag & 0x02)	// translated B-number
		{
			temp_len = rce_ptr->ccbs_data.trans_num[0];
			buf_len = add_tlv("1.1",temp_len,rce_ptr->ccbs_data.trans_num+1,0x80,&asn_buf);
		}
		else
			return RER;
		if (rce_ptr->ccbs_data.param_flag & 0x04)	// service indicator
		{
			temp_data[0] = rce_ptr->ccbs_data.ser_ind;
			temp_len = bytestrtobitstr(temp_buf,temp_data,2);
			buf_len = add_tlv("1.2",temp_len,temp_buf,0x80,&asn_buf);
		}
		if (rce_ptr->ccbs_data.param_flag & 0x08)	// call info
		{
			temp_len = assign_extsiginfo(&rce_ptr->ccbs_data.call_info,temp_buf);
			buf_len = add_tlv("1.3",temp_len,temp_buf,0x80,&asn_buf);
		}
		else
			return RER;
		if (rce_ptr->ccbs_data.param_flag & 0x10)	// network signal info
		{
			temp_len = assign_extsiginfo(&rce_ptr->ccbs_data.net_info,temp_buf);
			buf_len = add_tlv("1.4",temp_len,temp_buf,0x0a0,&asn_buf);
		}
		else
			return RER;
	}
	return buf_len;
}

int extract_regccentarg(struct MapRCCE_Arg *rce_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int 		len;
	int			temp_len;
	u8			temp_buf[256],temp_data[256];

	rce_ptr->param_flag = 0;
	if (buf_len == 0)
	{
		mapp_log_debug("MAPP--extract_register CC entity 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)	// ss code
	{
		rce_ptr->param_flag |= 0x01;
		rce_ptr->ss_code = temp_buf[0];
	}
	else
		return RER;
	if (get_tlv("1",temp_buf,&asn_buf) != -1)	// ccbs data
	{
		rce_ptr->param_flag |= 0x02;
		len = get_tlv("1.0",temp_buf,&asn_buf);
		if (len != -1)
		{
			if (!extract_ccbsfeat(&rce_ptr->ccbs_data.ccbs_feat,len,temp_buf))
				return RER;
			rce_ptr->ccbs_data.param_flag |= 0x01;
		}
		else
			return RER;
		len = get_tlv("1.1",temp_buf,&asn_buf);	// translate B-number
		if (len > 0 && len <= ISDN_LEN)
		{
			rce_ptr->ccbs_data.param_flag |= 0x02;
			rce_ptr->ccbs_data.trans_num[0] = len;
			memcpy(rce_ptr->ccbs_data.trans_num+1,temp_buf,len);
		}
		else
			return RER;
		len = get_tlv("1.2",temp_buf,&asn_buf);	// service indicator
		if (len != -1)
		{
			rce_ptr->ccbs_data.param_flag |= 0x04;
			temp_len = bitstrtobytestr(temp_data,temp_buf,len);
			rce_ptr->ccbs_data.ser_ind = bcdtou32(temp_data,temp_len);
		}
		len = get_tlv("1.3",temp_buf,&asn_buf);
		if (len != -1)
		{
			if (extract_extsiginfo(&rce_ptr->ccbs_data.call_info,len,temp_buf) != RER)
				rce_ptr->ccbs_data.param_flag |= 0x08;
		}
		else
			return RER;
		len = get_tlv("1.4",temp_buf,&asn_buf);
		if (len != -1)
		{
			if (extract_extsiginfo(&rce_ptr->ccbs_data.net_info,len,temp_buf) != RER)
				rce_ptr->ccbs_data.param_flag |= 0x10;
		}
		else
			return RER;
	}
	return ROK;
}

/*	+++++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding register CC entity response	*/
/*  +++++++++++++++++++++++++++++++++++++++++++++	*/
int assign_regccentres(struct MapRCCE_Res *rce_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;
	int			temp_len;
	u8			temp_buf[256];

	asn_encode(buf,&asn_buf);
	if (rce_ptr->param_flag & 0x01)	// ccbs feature
	{
		temp_len = assign_ccbsfeat(&rce_ptr->ccbs_feat,temp_buf);
		buf_len = add_tlv("0",temp_len,temp_buf,0x0a0,&asn_buf);
	}
	return buf_len;
}

int extract_regccentres(struct MapRCCE_Res *rce_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	int 		len;
	u8			temp_buf[256];

	rce_ptr->param_flag = 0;
	if (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 != -1)
	{
		if (!extract_ccbsfeat(&rce_ptr->ccbs_feat,len,temp_buf))
			return RER;
		rce_ptr->param_flag |= 0x01;
	}
	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding erase CC entity argument	*/
/*  ++++++++++++++++++++++++++++++++++++++++++	*/
int assign_eraseccentarg(struct MapECCE_Arg *ece_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;

	asn_encode(buf,&asn_buf);
	if (ece_ptr->param_flag & 0x01)		// ss code
		buf_len = add_tlv("0",1,&ece_ptr->ss_code,0x80,&asn_buf);
	else
		return RER;
	if (ece_ptr->param_flag & 0x02)		// ccbs index
		buf_len = add_tlv("1",1,&ece_ptr->ccbs_index,0x80,&asn_buf);
	return buf_len;
}

int extract_eraseccentarg(struct MapECCE_Arg *ece_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	u8			temp_buf[256];

	ece_ptr->param_flag = 0;
	if (buf_len == 0)
	{
		mapp_log_debug("MAPP--extract_erase CC entity 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)	// ss code
	{
		ece_ptr->param_flag |= 0x01;
		ece_ptr->ss_code = temp_buf[0];
	}
	else
		return RER;
	if (get_tlv("1",temp_buf,&asn_buf) == 1)	// ccbs index
	{
		ece_ptr->param_flag |= 0x02;
		ece_ptr->ccbs_index = temp_buf[0];
	}
	return ROK;
}

/*	++++++++++++++++++++++++++++++++++++++++++	*/
/*	encoding/decoding erase CC entity response	*/
/*  ++++++++++++++++++++++++++++++++++++++++++	*/
int assign_eraseccentres(struct MapECCE_Res *ece_ptr,u8 *buf)
{
	ASN_BUF		asn_buf;
	int			buf_len=0;

	asn_encode(buf,&asn_buf);
	if (ece_ptr->param_flag & 0x01)		// ss code
		buf_len = add_tlv("0",1,&ece_ptr->ss_code,0x80,&asn_buf);
	else
		return RER;
	if (ece_ptr->param_flag & 0x02)		// ss status
		buf_len = add_tlv("1",1,&ece_ptr->ss_status,0x80,&asn_buf);
	return buf_len;
}

int extract_eraseccentres(struct MapECCE_Res *ece_ptr,u32 buf_len,u8 *buf)
{
	ASN_BUF		asn_buf;
	u8			temp_buf[256];

	ece_ptr->param_flag = 0;
	if (buf_len == 0)
	{
		mapp_log_debug("MAPP--extract_erase CC entity 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)	// ss code
	{
		ece_ptr->param_flag |= 0x01;
		ece_ptr->ss_code = temp_buf[0];
	}
	else
		return RER;
	if (get_tlv("1",temp_buf,&asn_buf) == 1)	// ss status
	{
		ece_ptr->param_flag |= 0x02;
		ece_ptr->ss_status = temp_buf[0];
	}
	return ROK;
}
