 #include "map_includes.h"





int extract_RoutingInfoForLCS_Arg(RoutingInfoForLCS_Arg *ptr,u32 buf_len,u8 *buf)

{

	ASN_BUF		asn_buf;

	int			len;

	u8			temp_buf[256];

	u32			flag=0;

	

	if (buf_len == 0)

	{

		mapp_log_debug("extract RoutingInfoForLCS_Arg param len is:0");

		return RER;

	}

	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)

		return RER;

	len = get_tlv("0",temp_buf,&asn_buf);	/*	mlc number	*/

	if (len > 1 && len <= ISDN_LEN)

	{

		flag |= 0x01;	

		ptr->mlcNumber[0] = len;

		memcpy(ptr->mlcNumber+1,temp_buf,len);

	}

	else

	{

		mapp_log_debug("extract RoutingInfoForLCS_Arg:loss MLC number");

		return RER;

	}

	

	if (get_tlv("1",temp_buf,&asn_buf) != -1)/*	 targetMs	*/

	{

		flag |= 0x02;

		len = get_tlv("1.0",temp_buf,&asn_buf);		// IMSI

		if (len == IMSI_LEN && (temp_buf[IMSI_LEN-1]&0xf0) == 0xf0)

		{

			ptr->targetMs.identityChoice = 0x01;

			memcpy(ptr->targetMs.imsi,temp_buf,IMSI_LEN);

		}

		else

		{

			len = get_tlv("1.1",temp_buf,&asn_buf);		// msisdn

			if (len > 0 && len <= ISDN_LEN)

			{

				ptr->targetMs.identityChoice = 0x02;

				ptr->targetMs.msisdn[0] = len;

				memcpy(ptr->targetMs.msisdn+1,temp_buf,len);

			}

			else

				return RER;

		}

	}

	else

	{

		mapp_log_debug("extract RoutingInfoForLCS_Arg:loss TargetMs");

		return RER;	

	}

	ptr->param_flag = flag;

	return buf_len;	

}



int assign_RoutingInfoForLCS_Res(RoutingInfoForLCS_Res *ptr,u8 *buf, u8 ver)

{

	ASN_BUF		asn_buf;

	u32			flag;

	int			buf_len=0;

	u8			len;

	

	asn_encode(buf,&asn_buf);

	flag = ptr->param_flag;



	if (flag & 0x01)	/*	targetMs	*/

	{

		if (ptr->targetMs.identityChoice == 1)	// IMSI

			buf_len = add_tlv("0.0",IMSI_LEN,ptr->targetMs.imsi,0x80,&asn_buf);

		else if (ptr->targetMs.identityChoice == 2)	// msisdn

		{

			len = ptr->targetMs.msisdn[0];

			buf_len = add_tlv("0.1",len,ptr->targetMs.msisdn+1,0x80,&asn_buf);			

		}

		else

			return 	RER;

	}

	else

		return RER;

	

	if (flag & 0x02)/*	mscNumber */

	{

		len = ptr->mscNumber[0];

		buf_len = add_tlv("1.4-1",len,ptr->mscNumber+1,0x00,&asn_buf);			

	}

	else {

		mapp_log_debug("assign RoutingInfoForLCS_Res:loss MSC NUMBER");

		return RER;	

	}

		

	return 	buf_len;

}



int extract_ProvideSubscriberLocation_Arg(ProvideSubscriberLocation_Arg *ptr,u32 buf_len,u8 *buf)

{

	ASN_BUF		asn_buf;

	int			len;

	u8			temp_buf[256];

	u32			flag=0;

	

	

	if (buf_len == 0)

	{

		mapp_log_debug("extract ProvideSubscriberLocation_Arg param len is:0");

		return RER;

	}

	if (asn_decode_v3(buf,buf_len,&decErr,&asn_buf) == -1)

		return RER;



	if((len=get_tlv("16-1.0",temp_buf,&asn_buf)) > 0)/*	locationType	*/

	{

		flag |= 0x01;

		ptr->locationType.locationEstimateType = temp_buf[0];		

	}

	else

		return RER;

	

	if((len=get_tlv("4-2",temp_buf,&asn_buf)) > 0)/*	MLC number	*/

	{

		flag |= 0x02;

		ptr->mlcNumber[0] = len;

		memcpy(ptr->mlcNumber+1,temp_buf,len);

	}

	else

		return RER;

	

	if ((len=get_tlv("2",temp_buf,&asn_buf)) != -1)	/*	imsi	*/

	{		

		if (len == IMSI_LEN)

		{

			flag |= 0x08;

			memcpy(ptr->imsi,temp_buf,len);

		}

		else

			return RER;

	}

	

	

	if ((len=get_tlv("3",temp_buf,&asn_buf)) != -1)	/*	msisdn	*/

	{

		if (len > 0 && len <= ISDN_LEN)

		{

			flag |= 0x04;

			ptr->msisdn[0] = len;

			memcpy(ptr->msisdn+1,temp_buf,len);

		}

		else

			return 	RER;		

	}

	

	ptr->param_flag = flag;

	return buf_len;	

}





int assign_ProvideSubscriberLocation_Res(ProvideSubscriberLocation_Res *ptr,u8 *buf, u8 ver)

{

	ASN_BUF		asn_buf;

	u32			flag;

	int			buf_len=0;

	

	asn_encode(buf,&asn_buf);

	flag = ptr->param_flag;

	if (flag & 0x01)/*	locationEstimate	*/

	{

		u8 locationEstimate[maxExtGeographicalInformation] = {0};

		if(ptr->locationEstimate.typeOfShape != EllipsoidPoint) /* only support EllipsoidPoint	*/

			return RER;

		locationEstimate[0] |=  ptr->locationEstimate.typeOfShape << 4;

		

		

		if(ptr->locationEstimate.degreesOfLatitude >= 0)

			locationEstimate[1] &= 0x00;

		else

			locationEstimate[1] |= 0x80;

		ptr->locationEstimate.degreesOfLatitude &= 0x7fffff;

		locationEstimate[1] |= ptr->locationEstimate.degreesOfLatitude >> 16;

		locationEstimate[2] = ptr->locationEstimate.degreesOfLatitude >> 8;

		locationEstimate[3] = ptr->locationEstimate.degreesOfLatitude & 0xff;

		

		ptr->locationEstimate.degreesOfLongitude &= 0xffffff;

		locationEstimate[4] = ptr->locationEstimate.degreesOfLongitude >> 16;

		locationEstimate[5] = ptr->locationEstimate.degreesOfLongitude >> 8;

		locationEstimate[6] = ptr->locationEstimate.degreesOfLongitude & 0xff;

		

		buf_len = add_tlv("4-1",7,locationEstimate,0x00,&asn_buf);	

	}

	else {

		return RER;

	}

				

	if (flag & 0x02)/*	cgi */

	{		

		u8	cgi[16] = {0};

		if(ptr->cgi.cgiOrLaiChoice != CgiOrSai) /* only support cgiOrSai	*/

			return RER;

		memcpy(cgi,ptr->cgi.mccMnc,3);

		cgi[3] = ptr->cgi.lac >> 8;

		cgi[4] = ptr->cgi.lac & 0xff;		

		cgi[5] = ptr->cgi.cellId >> 8;

		cgi[6] = ptr->cgi.cellId & 0xff;

		buf_len = add_tlv("6-2.0",7,cgi,0x80,&asn_buf);	

	}

	else {

		

	}

	

	return 	buf_len;

}

