/*	MAP Update Location c file				*/
/*	created by daniel zhang 2004-06-17		*/
/*	last modufy by xinyu yan 2006-05-15	*/
/*	------------------------------------	*/

#include "map_includes.h"
#include "map_code.h"

/* external functions */
void is41_debug(DWORD mask, const char *fmt, ...);
void is41_showbuf(DWORD mask, BYTE *buf, int len);

static int	(*is41_assign_arg[128]) ();
static int	(*is41_assign_rsp[128]) ();
static int	(*is41_extract_arg[128]) ();
static int	(*is41_extract_rsp[128]) ();
static char	is41_opr_string[128][48] = {
	"",
	"HandoffMeasurementRequest",
	"FacilitiesDirective",
	"MobileOnChannel",
	"HandoffBack",
	"FacilitiesRelease",
	"QualificationRequest",
	"QualificationDirective",
	"Blocking",
	"Unblocking",
	"ResetCircuit",
	"TrunkTest",
	"TrunkTestDisconnect",
	"RegistrationNotification",
	"RegistrationCancellation",
	"LocationRequest",
	"RoutingRequest",
	"FeatureRequest",
	"ServiceProfileRequest",
	"ServiceProfileDirective",
	"UnreliableRoamerDataDirective",
	"CallDataREquest",
	"MSInactive",
	"TransferToNumberRequest",
	"RedirectionRequest",
	"HandoffToThird",
	"FlashRequest",
	"AuthenticationDirective",
	"AuthenticationRequest",
	"BaseStationChallenge",
	"AuthenticationFailureReport",
	"CountRequest",
	"InterSystemPage",
	"UnsolicitedResponse",
	"BulkDeregistration",
	"HandoffMeasurementRequest2",
	"FacilitiesDirective2",
	"HandoffBack2",
	"HandoffToThird2",
	"AuthenticationDirectiveForward",
	"AuthenticationStatusReport",
	"InformationBackward",
	"InformationDirective",
	"InformationForward",
	"InterSystemAnswer",
	"InterSystemPage2",
	"InterSystemSetup",
	"OriginationRequest",
	"RandomVariableRequest",
	"RedirectionDirective",
	"RemoteUserInteractionDirective",
	"SMSDeliveryBackward",
	"SMSDeliveryForward",
	"SMSDeliveryPointToPoint",
	"SMSNotification",
	"SMSRequest",
	"", "", "", "", "", "", "", "", 
	"AnalyzedInformation",
	"ConnectionFailureReport",
	"ConnectResource",
	"DisconnectResource",
	"FacilitySelectedAndAvailable",
	"InstructionRequest",
	"Modify",
	"ResetTimer",
	"Search",
	"SeizeResource",
	"SRFDirective",
	"TBusy",
	"TNoAnswer",
	"", "", "", 
	"BulkDisconnection",
	"CallControlDirective",
	"OAnswer",
	"ODisconnect",
	"CallRecoveryReport",
	"TAnswer",
	"TDisconnect",
	"UnreliableCallData",
	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 
	"ShortMessageAnalyzed",
	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
};

void is41_register_encode_arg(u8 opr_code, int (*func)())
{
	is41_assign_arg[opr_code] = func;
}

void is41_register_encode_rsp(u8 opr_code, int (*func)())
{
	is41_assign_rsp[opr_code] = func;
}

void is41_register_decode_arg(u8 opr_code, int (*func)())
{
	is41_extract_arg[opr_code] = func;
}

void is41_register_decode_rsp(u8 opr_code, int (*func)())
{
	is41_extract_rsp[opr_code] = func;
}

void init_assignFunc_pointer()
{
	is41_register_encode_arg(IS41OPR_AuthenticationDirective, assign_is41AuthenticationDirective_arg);
	is41_register_encode_rsp(IS41OPR_AuthenticationDirective, assign_is41AuthenticationDirective_rsp);

	is41_register_encode_arg(IS41OPR_AuthenticationFailureReport, assign_is41AuthenticationFailureReport_arg);
	is41_register_encode_rsp(IS41OPR_AuthenticationFailureReport, assign_is41AuthenticationFailureReport_rsp);

	is41_register_encode_arg(IS41OPR_AuthenticationRequest, assign_is41AuthenticationRequest_arg);
	is41_register_encode_rsp(IS41OPR_AuthenticationRequest, assign_is41AuthenticationRequest_rsp);

	is41_register_encode_arg(IS41OPR_AuthenticationStatusReport, assign_is41AuthenticationStatusReport_arg);
	is41_register_encode_rsp(IS41OPR_AuthenticationStatusReport, assign_is41AuthenticationStatusReport_rsp);

	is41_register_encode_arg(IS41OPR_AuthenticationDirectiveForward, assign_is41AuthenticationDirectiveForward_arg);

	is41_register_encode_arg(IS41OPR_BaseStationChallenge, assign_is41BaseStationChallenge_arg);
	is41_register_encode_rsp(IS41OPR_BaseStationChallenge, assign_is41BaseStationChallenge_rsp);

	is41_register_encode_arg(IS41OPR_CountRequest, assign_is41CountRequest_arg);
	is41_register_encode_rsp(IS41OPR_CountRequest, assign_is41CountRequest_rsp);

	is41_register_encode_arg(IS41OPR_SMSDeliveryBackward, assign_Is41SmsDeliveryBackward_arg);
	is41_register_encode_rsp(IS41OPR_SMSDeliveryBackward, assign_Is41SmsDeliveryBackward_rsp);

	is41_register_encode_arg(IS41OPR_SMSDeliveryForward, assign_Is41SmsDeliveryForward_arg);
	is41_register_encode_rsp(IS41OPR_SMSDeliveryForward, assign_Is41SmsDeliveryForward_rsp);

	is41_register_encode_arg(IS41OPR_SMSDeliveryPointToPoint, assign_Is41SmsDeliveryPointToPoint_arg);
	is41_register_encode_rsp(IS41OPR_SMSDeliveryPointToPoint, assign_Is41SmsDeliveryPointToPoint_rsp);

	is41_register_encode_arg(IS41OPR_SMSNotification, assign_Is41SmsNotification_arg);
	is41_register_encode_rsp(IS41OPR_SMSNotification, assign_Is41SmsNotification_rsp);

	is41_register_encode_arg(IS41OPR_SMSRequest, assign_Is41SmsRequest_arg);
	is41_register_encode_rsp(IS41OPR_SMSRequest, assign_Is41SmsRequest_rsp);

	is41_register_encode_arg(IS41OPR_RegistrationNotification, assign_is41RegistrationNotification_arg);
	is41_register_encode_rsp(IS41OPR_RegistrationNotification, assign_is41RegistrationNotification_rsp);	
	is41_register_encode_arg(IS41OPR_RegistrationCancellation, assign_is41RegistrationCancellation_arg);
	is41_register_encode_rsp(IS41OPR_RegistrationCancellation, assign_is41RegistrationCancellation_rsp);
	is41_register_encode_arg(IS41OPR_LocationRequest, assign_is41LocationRequest_arg);
	is41_register_encode_rsp(IS41OPR_LocationRequest, assign_is41LocationRequest_rsp);
	is41_register_encode_arg(IS41OPR_RoutingRequest, assign_is41RoutingRequest_arg);
	is41_register_encode_rsp(IS41OPR_RoutingRequest, assign_is41RoutingRequest_rsp);
	is41_register_encode_arg(IS41OPR_MSInactive, assign_is41MSInactive_arg);
	is41_register_encode_rsp(IS41OPR_MSInactive, assign_is41MSInactive_rsp);

	is41_register_encode_arg(IS41OPR_FeatureRequest, assign_is41FeatureRequest_arg);
	is41_register_encode_rsp(IS41OPR_FeatureRequest, assign_is41FeatureRequest_rsp);

	is41_register_encode_arg(IS41OPR_QualificationDirective, assign_is41QualificationDirective_arg);
	is41_register_encode_rsp(IS41OPR_QualificationDirective, assign_is41QualificationDirective_rsp);

	is41_register_encode_arg(IS41OPR_TransferToNumberRequest, assign_is41TransferToNumberRequest_arg);
	is41_register_encode_rsp(IS41OPR_TransferToNumberRequest, assign_is41TransferToNumberRequest_rsp);

	is41_register_encode_arg(IS41OPR_RedirectionRequest, assign_is41RedirectionRequest_arg);
	is41_register_encode_rsp(IS41OPR_RedirectionRequest, assign_is41RedirectionRequest_rsp);
	
	is41_register_encode_arg(IS41OPR_OriginationRequest, assign_is41OriginationRequest_arg);
	is41_register_encode_rsp(IS41OPR_OriginationRequest, assign_is41OriginationRequest_rsp);
	
	is41_register_encode_arg(IS41OPR_AnalyzedInformation, assign_is41AnalyzedInformation_arg);
	is41_register_encode_rsp(IS41OPR_AnalyzedInformation, assign_is41AnalyzedInformation_rsp);
	
	is41_register_encode_arg(IS41OPR_OAnswer, assign_is41OAnswer_arg);
	
	is41_register_encode_arg(IS41OPR_ODisconnect, assign_is41ODisconnect_arg);
	is41_register_encode_rsp(IS41OPR_ODisconnect, assign_is41ODisconnect_rsp);
	
	is41_register_encode_arg(IS41OPR_TAnswer, assign_is41TAnswer_arg);
	
	is41_register_encode_arg(IS41OPR_TDisconnect, assign_is41TDisconnect_arg);
	is41_register_encode_rsp(IS41OPR_TDisconnect, assign_is41TDisconnect_rsp);
	
	is41_register_encode_arg(IS41OPR_CallControlDirective, assign_is41CallControlDirective_arg);
	is41_register_encode_rsp(IS41OPR_CallControlDirective, assign_is41CallControlDirective_rsp);
	
	is41_register_encode_arg(IS41OPR_SeizeResource, assign_is41SeizeResource_arg);
	is41_register_encode_rsp(IS41OPR_SeizeResource, assign_is41SeizeResource_rsp);
	
	is41_register_encode_arg(IS41OPR_ConnectResource, assign_is41ConnectResource_arg);
	
	is41_register_encode_arg(IS41OPR_SRFDirective, assign_is41SRFDirective_arg);
	is41_register_encode_rsp(IS41OPR_SRFDirective, assign_is41SRFDirective_rsp);
	
	is41_register_encode_arg(IS41OPR_ShortMessageAnalyzed, assign_is41ShortMessageAnalyzed_arg);
	is41_register_encode_rsp(IS41OPR_ShortMessageAnalyzed, assign_is41ShortMessageAnalyzed_rsp);
}

void init_extractFunc_pointer()
{
	is41_register_decode_arg(IS41OPR_AuthenticationDirective, extract_is41AuthenticationDirective_arg);
	is41_register_decode_rsp(IS41OPR_AuthenticationDirective, extract_is41AuthenticationDirective_rsp);

	is41_register_decode_arg(IS41OPR_AuthenticationFailureReport, extract_is41AuthenticationFailureReport_arg);
	is41_register_decode_rsp(IS41OPR_AuthenticationFailureReport, extract_is41AuthenticationFailureReport_rsp);

	is41_register_decode_arg(IS41OPR_AuthenticationRequest, extract_is41AuthenticationRequest_arg);
	is41_register_decode_rsp(IS41OPR_AuthenticationRequest, extract_is41AuthenticationRequest_rsp);

	is41_register_decode_arg(IS41OPR_AuthenticationStatusReport, extract_is41AuthenticationStatusReport_arg);
	is41_register_decode_rsp(IS41OPR_AuthenticationStatusReport, extract_is41AuthenticationStatusReport_rsp);

	is41_register_decode_arg(IS41OPR_AuthenticationDirectiveForward, extract_is41AuthenticationDirectiveForward_arg);

	is41_register_decode_arg(IS41OPR_BaseStationChallenge, extract_is41BaseStationChallenge_arg);
	is41_register_decode_rsp(IS41OPR_BaseStationChallenge, extract_is41BaseStationChallenge_rsp);

	is41_register_decode_arg(IS41OPR_CountRequest, extract_is41CountRequest_arg);
	is41_register_decode_rsp(IS41OPR_CountRequest, extract_is41CountRequest_rsp);

	is41_register_decode_arg(IS41OPR_SMSDeliveryBackward, extract_Is41SmsDeliveryBackward_arg);
	is41_register_decode_rsp(IS41OPR_SMSDeliveryBackward, extract_Is41SmsDeliveryBackward_rsp);

	is41_register_decode_arg(IS41OPR_SMSDeliveryForward, extract_Is41SmsDeliveryForward_arg);
	is41_register_decode_rsp(IS41OPR_SMSDeliveryForward, extract_Is41SmsDeliveryForward_rsp);

	is41_register_decode_arg(IS41OPR_SMSDeliveryPointToPoint, extract_Is41SmsDeliveryPointToPoint_arg);
	is41_register_decode_rsp(IS41OPR_SMSDeliveryPointToPoint, extract_Is41SmsDeliveryPointToPoint_rsp);

	is41_register_decode_arg(IS41OPR_SMSNotification, extract_Is41SmsNotification_arg);
	is41_register_decode_rsp(IS41OPR_SMSNotification, extract_Is41SmsNotification_rsp);

	is41_register_decode_arg(IS41OPR_SMSRequest, extract_Is41SmsRequest_arg);
	is41_register_decode_rsp(IS41OPR_SMSRequest, extract_Is41SmsRequest_rsp);

	is41_register_decode_arg(IS41OPR_RegistrationNotification, extract_is41RegistrationNotification_arg);
	is41_register_decode_rsp(IS41OPR_RegistrationNotification, extract_is41RegistrationNotification_rsp);	
	is41_register_decode_arg(IS41OPR_RegistrationCancellation, extract_is41RegistrationCancellation_arg);
	is41_register_decode_rsp(IS41OPR_RegistrationCancellation, extract_is41RegistrationCancellation_rsp);	
	is41_register_decode_arg(IS41OPR_LocationRequest, extract_is41LocationRequest_arg);
	is41_register_decode_rsp(IS41OPR_LocationRequest, extract_is41LocationRequest_rsp);
	is41_register_decode_arg(IS41OPR_RoutingRequest, extract_is41RoutingRequest_arg);
	is41_register_decode_rsp(IS41OPR_RoutingRequest, extract_is41RoutingRequest_rsp);
	is41_register_decode_arg(IS41OPR_MSInactive, extract_is41MSInactive_arg);
	is41_register_decode_rsp(IS41OPR_MSInactive, extract_is41MSInactive_rsp);

	is41_register_decode_arg(IS41OPR_FeatureRequest, extract_is41FeatureRequest_arg);
	is41_register_decode_rsp(IS41OPR_FeatureRequest, extract_is41FeatureRequest_rsp);

	is41_register_decode_arg(IS41OPR_QualificationDirective, extract_is41QualificationDirective_arg);
	is41_register_decode_rsp(IS41OPR_QualificationDirective, extract_is41QualificationDirective_rsp);

	is41_register_decode_arg(IS41OPR_TransferToNumberRequest, extract_is41TransferToNumberRequest_arg);
	is41_register_decode_rsp(IS41OPR_TransferToNumberRequest, extract_is41TransferToNumberRequest_rsp);

	is41_register_decode_arg(IS41OPR_RedirectionRequest, extract_is41RedirectionRequest_arg);
	is41_register_decode_rsp(IS41OPR_RedirectionRequest, extract_is41RedirectionRequest_rsp);
	
	is41_register_decode_arg(IS41OPR_OriginationRequest, extract_is41OriginationRequest_arg);
	is41_register_decode_rsp(IS41OPR_OriginationRequest, extract_is41OriginationRequest_rsp);
	
	is41_register_decode_arg(IS41OPR_AnalyzedInformation, extract_is41AnalyzedInformation_arg);
	is41_register_decode_rsp(IS41OPR_AnalyzedInformation, extract_is41AnalyzedInformation_rsp);
	
	is41_register_decode_arg(IS41OPR_OAnswer, extract_is41OAnswer_arg);
	
	is41_register_decode_arg(IS41OPR_ODisconnect, extract_is41ODisconnect_arg);
	is41_register_decode_rsp(IS41OPR_ODisconnect, extract_is41ODisconnect_rsp);
	
	is41_register_decode_arg(IS41OPR_TAnswer, extract_is41TAnswer_arg);
	
	is41_register_decode_arg(IS41OPR_TDisconnect, extract_is41TDisconnect_arg);
	is41_register_decode_rsp(IS41OPR_TDisconnect, extract_is41TDisconnect_rsp);
	
	is41_register_decode_arg(IS41OPR_CallControlDirective, extract_is41CallControlDirective_arg);
	is41_register_decode_rsp(IS41OPR_CallControlDirective, extract_is41CallControlDirective_rsp);
	
	is41_register_decode_arg(IS41OPR_SeizeResource, extract_is41SeizeResource_arg);
	is41_register_decode_rsp(IS41OPR_SeizeResource, extract_is41SeizeResource_rsp);
	
	is41_register_decode_arg(IS41OPR_ConnectResource, extract_is41ConnectResource_arg);
	
	is41_register_decode_arg(IS41OPR_SRFDirective, extract_is41SRFDirective_arg);
	is41_register_decode_rsp(IS41OPR_SRFDirective, extract_is41SRFDirective_rsp);
	
	is41_register_decode_arg(IS41OPR_ShortMessageAnalyzed, extract_is41ShortMessageAnalyzed_arg);
	is41_register_decode_rsp(IS41OPR_ShortMessageAnalyzed, extract_is41ShortMessageAnalyzed_rsp);
}

int is41_u8Type_to_charType(u8 type,char *cType)
{
	if(type >= 128)
		return 0;
	else if(strlen(is41_opr_string[type]) == 0)
		return 0;
	strcpy(cType, is41_opr_string[type]);
	return 1;
}

/*int is41_u8Type_to_charType(u8 type,char *cType)
{
	switch (type)
	{
		// Authentication service operation
		case IS41OPR_AuthenticationDirective:
			sprintf(cType,"AuthenticationDirective");
			break;
		case IS41OPR_AuthenticationFailureReport:
			sprintf(cType,"AuthenticationFailureReport");
			break;
		case IS41OPR_AuthenticationRequest:
			sprintf(cType,"AuthenticationRequest");
			break;
		case IS41OPR_AuthenticationStatusReport:
			sprintf(cType,"AuthenticationStatusReport");
			break;
		case IS41OPR_AuthenticationDirectiveForward:
			sprintf(cType,"AuthenticationDirectiveForward");
			break;
		case IS41OPR_CountRequest:
			sprintf(cType,"CountRequest");
			break;
		case IS41OPR_BaseStationChallenge:
			sprintf(cType,"BaseStationChallenge");
			break;
		case IS41OPR_SMSDeliveryBackward:
			sprintf(cType,"SMSDeliveryBackward");
			break;
		case IS41OPR_SMSDeliveryForward:
			sprintf(cType,"SMSDeliveryForward");
			break;
		case IS41OPR_SMSDeliveryPointToPoint:
			sprintf(cType,"SMSDeliveryPointToPoint");
			break;
		case IS41OPR_SMSNotification:
			sprintf(cType,"IS41OPR_SMSNotification");
			break;
		case IS41OPR_SMSRequest:
			sprintf(cType,"SMSRequest");
			break;

		case IS41OPR_RegistrationNotification:
			sprintf(cType,"REGNOT");
			break;
		case IS41OPR_RegistrationCancellation:
			sprintf(cType,"REGCANC");
			break;
		case IS41OPR_LocationRequest:
			sprintf(cType,"LOCREQ");
			break;
		case IS41OPR_RoutingRequest:
			sprintf(cType,"ROUTREQ");
			break;
		case IS41OPR_MSInactive:
			sprintf(cType,"MSINACT");
			break;
		case IS41OPR_FeatureRequest:
			sprintf(cType,"FEATREQ");
			break;
		case IS41OPR_QualificationDirective:
			sprintf(cType,"QUALDIR");
			break;
		case IS41OPR_TransferToNumberRequest:
			sprintf(cType,"TRANUMREQ");
			break;
		case IS41OPR_RedirectionRequest:
			sprintf(cType,"REDREQ");
			break;
		
		default:	// unknown operation
//			sprintf(info_str,"MAPP error:the operation is unknown:%d",opr_ptr->message_type);
//			xap_send_error(info_str);
			return 0;
	}
	return 1;
}*/

int	build_is41param(struct MapOprSrv_struct *opr_ptr,u8 *buf) // build is41 service paramter
{
	ASN_BUF	asn_buf;
	u8	 	seq_flag=1;
	int		param_len = 0;
	u8		info_str[1024];
	char	charName[128];

	if (opr_ptr == NULL || buf == NULL)
		return 0;
	if (!is41_u8Type_to_charType(opr_ptr->message_type,charName))
	{
		is41_debug(IS41DB_ENCODE,"[IS41-Encode]Building param,Operation code:%d not correct",opr_ptr->message_type);
		return 0;
	}

	if (opr_ptr->message_flag == MAP_REQUEST)
	{
		is41_debug(IS41DB_ENCODE,"[IS41-Encode] MAP_REQUEST,OPRType=%s",charName);
		param_len = (*is41_assign_arg[opr_ptr->message_type]) (opr_ptr,buf);
	}
	else if (opr_ptr->message_flag == MAP_RESPONSE)
	{
		is41_debug(IS41DB_ENCODE,"[IS41-Encode] MAP_RESPONSE,OPRType=%s",charName);
		param_len = (*is41_assign_rsp[opr_ptr->message_type])(opr_ptr,buf);
	}
	else
		return 0;

	if (seq_flag == 1 && param_len > 0)
	{
		memcpy(info_str,buf,param_len%1024);
		AsnEncode(buf,256,&asn_buf);
		param_len = AddTLV(SET_NATIONAL,param_len,info_str,0xe0,&asn_buf);
		is41_debug(IS41DB_ENCODE,"[IS41-Encode] Completed,len=%d",param_len);
		is41_showbuf(IS41DB_ENCODE,buf,param_len);
	}
	else
	{
		AsnEncode(buf,256,&asn_buf);
		param_len = AddTLV(SET_NATIONAL,0,info_str,0xc0,&asn_buf);
		is41_debug(IS41DB_ENCODE,"[IS41-Encode] Completed,paramlen=0");
		is41_showbuf(IS41DB_ENCODE,buf,param_len);
	}
	return param_len;
}

u8 extract_is41param(struct MapOprSrv_struct *opr_ptr,u8 opr_code,u8 opr_flag,u32 pre_param_len,u8 *pre_param)
{
	ASN_BUF		asn_buf;
//	u8			info_str[1024];
	u8			param[1024];
	int			param_len;
	char		charName[128];

	asn_decode(pre_param,1,&asn_buf);
	param_len = get_tlv(SET_NATIONAL,param,&asn_buf);

	if (param_len == -1)	// not has sequence id
	{
		param_len = pre_param_len;
		memcpy(param,pre_param,param_len);
	}

	if (!is41_u8Type_to_charType(opr_code,charName))
	{
		is41_debug(IS41DB_ENCODE,"[IS41-Encode]Extracting param,Operation code:%d not correct",opr_code);
		return 0;
	}

	if (opr_flag == MAP_INDICATE)
	{
		is41_debug(IS41DB_DECODE,"[IS41-Decode]USER->IS41P,IS41_INDICATE,OPRType=%s",charName);
		is41_showbuf(IS41DB_DECODE,param,param_len);
		if (*is41_extract_arg[opr_code] != NULL)
		{
			return (*is41_extract_arg[opr_code])(opr_ptr,param_len,param);
		}
		else
		{
			is41_debug(IS41DB_ERR,"[IS41-Decode]No decode function for IS41_INDICATE opr_code=%d",opr_code);
			return 0;
		}
	}
	else if (opr_flag == MAP_CONFIRM)
	{
		is41_debug(IS41DB_DECODE,"[IS41-Decode]USER->IS41P,MAP_CONFIRM,OPRType=%s",charName);
		is41_showbuf(IS41DB_DECODE,param,param_len);
		if (*is41_extract_rsp[opr_code] != NULL)
			return (*is41_extract_rsp[opr_code])(opr_ptr,param_len,param);
		else
		{
			is41_debug(IS41DB_ERR,"[IS41-Decode]No decode function for IS41_CONFIRM opr_code=%d",opr_code);
			return 0;
		}
	}

	return 1;
}
