/*
 * Copyright (c) 2019, Infosys Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>
#include <freeDiameter/freeDiameter-host.h>
#include <freeDiameter/libfdcore.h>
#include <freeDiameter/libfdproto.h>

#include "log.h"
#include "err_codes.h"
#include "message_queues.h"
#include "ipc_api.h"
#include "s6a_fd.h"
#include "s6a.h"
#include "msgType.h"
//#include "detach_stage2_info.h"
#include "hss_message.h"

#define DIAMETER_SUCCESS 2001

/** Global and externs**/
extern struct fd_dict_objects g_fd_dict_objs;
extern struct fd_dict_data g_fd_dict_data;
extern int g_Q_mme_S6a_fd;
/**global and externs end**/



/**
 * @brief callback handler for clr recvd from hss
 * Parse clr, state and do cleanup for freediameter
 * @params callback std
 * @return error/success
 */
int
clr_resp_callback(struct msg **buf, struct avp *avps, struct session *sess,
			void *data, enum disp_action *action)
{
	struct msg *resp = NULL;
	struct avp *avp_ptr = NULL;
	struct s6_incoming_msg_data_t s6_incoming_msgs;
	struct avp_hdr *avp_header = NULL;
	unsigned int sess_id_len;
	unsigned char *sess_id= NULL;

	resp = *buf;

	dump_fd_msg(resp);

	/*read session id and extract ue index*/
	CHECK_FCT_DO(fd_sess_getsid(sess, &sess_id, (size_t*)&sess_id_len),
			return S6A_FD_ERROR);
	log_msg(LOG_INFO, "\n CLR callback ----- >session id=%s \n",sess_id);
    

	/*AVP: Cancellation-Type*/
	avp_ptr = NULL;
	fd_msg_search_avp(resp, g_fd_dict_objs.cancellation_type, &avp_ptr);
	if(NULL != avp_ptr) {
		fd_msg_avp_hdr(avp_ptr, &avp_header);
		s6_incoming_msgs.msg_data.clr_Q_msg_m.c_type = avp_header->avp_value->i32;
	}
	
	fd_msg_search_avp(resp,g_fd_dict_objs.org_host, &avp_ptr);
	if(NULL != avp_ptr) {
		fd_msg_avp_hdr(avp_ptr, &avp_header);
		memcpy(s6_incoming_msgs.msg_data.clr_Q_msg_m.origin_host,avp_header->avp_value->os.data,sizeof(s6_incoming_msgs.msg_data.clr_Q_msg_m.origin_host));
		}

	fd_msg_search_avp(resp, g_fd_dict_objs.org_realm, &avp_ptr);
	if(NULL != avp_ptr) {
		fd_msg_avp_hdr(avp_ptr, &avp_header);
		memcpy(s6_incoming_msgs.msg_data.clr_Q_msg_m.origin_realm,avp_header->avp_value->os.data,sizeof(s6_incoming_msgs.msg_data.clr_Q_msg_m.origin_realm));
		}
         
	fd_msg_search_avp(resp, g_fd_dict_objs.user_name,&avp_ptr);
	if(NULL != avp_ptr) {
		fd_msg_avp_hdr(avp_ptr, &avp_header);
		memcpy(s6_incoming_msgs.msg_data.clr_Q_msg_m.imsi,avp_header->avp_value->os.data,sizeof(s6_incoming_msgs.msg_data.clr_Q_msg_m.imsi));
		}
       
       /*CLA Processing*/

       struct msg *ans, *qry;
       struct avp * a;

       if (buf == NULL)
               return EINVAL;


       /* Create answer header */
       qry = *buf;
       CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, buf, 0 ) );
       ans = *buf;

       /* Set the Origin-Host, Origin-Realm, Result-Code AVPs */
       CHECK_FCT( fd_msg_rescode_set( ans, "DIAMETER_SUCCESS", NULL, NULL, 1 ) );

       /* Send the answer */
       CHECK_FCT( fd_msg_send( buf, NULL, NULL ) );

	/*Do cleanup for freediameter*/
	fd_msg_free(*buf);

	*buf = NULL;
	
	s6_incoming_msgs.msg_type = cancel_location_request;

	s6_incoming_msgs.destInstAddr = htonl(mmeAppInstanceNum_c);
	s6_incoming_msgs.srcInstAddr = htonl(s6AppInstanceNum_c);

	/*Send to stage2 queue*/
        send_tipc_message(g_Q_mme_S6a_fd, mmeAppInstanceNum_c, (char*)&s6_incoming_msgs, S6_READ_MSG_BUF_SIZE);
	
	return SUCCESS;
}

/*Handler for CLR coming from built in perf HS*/
void
handle_perf_hss_clr(int ue_idx, struct hss_clr_msg *clr)
{
	struct s6_incoming_msg_data_t msg;
    
	msg.msg_type = cancel_location_request;
	msg.ue_idx = ue_idx;
	memcpy(&(msg.msg_data.clr_Q_msg_m.c_type), &(clr->cancellation_type), sizeof(clr->cancellation_type));
	/*Send to stage2 queue*/
	write_ipc_channel(g_Q_mme_S6a_fd, (char*)&msg, S6_READ_MSG_BUF_SIZE);
}
