MME2 changes - Propped commits from openmme/paging branch. Added scripts
for code gen

Change-Id: Ie55032217232214ac8544ca76ea34335205329e4
diff --git a/src/s6a/handlers/aia_handler.c b/src/s6a/handlers/aia_handler.c
new file mode 100644
index 0000000..bb096dd
--- /dev/null
+++ b/src/s6a/handlers/aia_handler.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2003-2018, Great Software Laboratory Pvt. Ltd.
+ * Copyright (c) 2017 Intel Corporation
+ * 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 "stage1_s6a_msg.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 Parse authentication information avp recvd in AIA. This contains
+ * important security information for the UE
+ * @param [in] avp_data - AVP value received
+ * @param [out] aia - Security info is filled in to aia msg Q
+ * @return int - error code
+ */
+static int
+get_aia_sec_vector(struct avp *avp_data, struct aia_Q_msg *aia)
+{
+	struct avp *sub_avp = NULL;
+	struct avp_hdr *element = NULL;
+
+	CHECK_FCT_DO(fd_msg_avp_hdr(avp_data, &element),
+			return S6A_FD_ERROR);
+
+	/*Authentication-Info*/
+	if ((NULL == element) ||
+			(element->avp_code != g_fd_dict_data.auth_info.avp_code))
+		return S6A_FD_ERROR;
+
+	/*Find first sub child of Authentication-Info*/
+	CHECK_FCT_DO(fd_msg_browse(avp_data, MSG_BRW_FIRST_CHILD, &sub_avp,
+			NULL),
+			return S6A_FD_ERROR);
+
+	/*Lookup for sub element "E-UTRAN-Vector" in loop*/
+	while (NULL != sub_avp) {
+
+		fd_msg_avp_hdr(sub_avp, &element);
+
+		if ((NULL != element) && (element->avp_code ==
+			g_fd_dict_data.E_UTRAN_vector.avp_code))
+			/*Found the entry*/
+			break;
+
+		/*Iterate sub entries*/
+		CHECK_FCT_DO(fd_msg_browse(sub_avp, MSG_BRW_NEXT, &sub_avp,
+			NULL),
+			return S6A_FD_ERROR);
+	}
+
+	/*Element "E-UTRAN-Vector" not found, then return*/
+	if (NULL == sub_avp) return S6A_FD_ERROR;
+
+	CHECK_FCT_DO(fd_msg_browse(sub_avp, MSG_BRW_FIRST_CHILD,
+			&sub_avp, NULL),
+			return S6A_FD_ERROR);
+
+	/*Iterate all sub elements of E-UTRAN-Vector and filter sec vector params*/
+	for (;
+		NULL != sub_avp; /*Till null*/
+//		CHECK_FCT_DO(fd_msg_browse(sub_avp, MSG_BRW_NEXT, &sub_avp, NULL),
+//			return S6A_FD_ERROR) /*Iterate elements*/
+		) {
+
+		fd_msg_avp_hdr(sub_avp, &element);
+
+		/*AVP: RAND(1447) l=28 f=VM- vnd=TGPP*/
+		if (element->avp_code == g_fd_dict_data.RAND.avp_code) {
+
+			//if (element->avp_value->os.len > sizeof(aia->sec.rand.val))
+			if (element->avp_value->os.len > AIA_RAND_SIZE)
+				return S6A_FD_ERROR;
+
+			aia->sec.rand.len = element->avp_value->os.len;
+			memcpy(aia->sec.rand.val, element->avp_value->os.data,
+				aia->sec.rand.len);
+		}
+
+		/*AVP: XRES(1448) l=20 f=VM- vnd=TGPP*/
+		if (element->avp_code == g_fd_dict_data.XRES.avp_code) {
+
+			if (element->avp_value->os.len > AIA_RES_SIZE)
+				return S6A_FD_ERROR;
+
+			aia->sec.xres.len = element->avp_value->os.len;
+			memcpy(aia->sec.xres.val, element->avp_value->os.data,
+				aia->sec.xres.len);
+		}
+
+		/*AVP: AUTN(1449) l=28 f=VM- vnd=TGPP*/
+		if (element->avp_code == g_fd_dict_data.AUTN.avp_code) {
+
+			if (element->avp_value->os.len > AIA_AUTN_SIZE)
+				return S6A_FD_ERROR;
+
+			aia->sec.autn.len = element->avp_value->os.len;
+			memcpy(aia->sec.autn.val, element->avp_value->os.data,
+				aia->sec.autn.len);
+		}
+
+		/*AVP: KASME(1450) l=44 f=VM- vnd=TGPP*/
+		if (element->avp_code == g_fd_dict_data.KASME.avp_code) {
+
+			if (element->avp_value->os.len > AIA_KASME_SIZE)
+				return S6A_FD_ERROR;
+
+			aia->sec.kasme.len = element->avp_value->os.len;
+			memcpy(aia->sec.kasme.val, element->avp_value->os.data,
+				aia->sec.kasme.len);
+		}
+
+		CHECK_FCT_DO(fd_msg_browse(sub_avp, MSG_BRW_NEXT, &sub_avp, NULL),
+			return S6A_FD_ERROR) /*Iterate elements*/
+
+	}
+
+	return SUCCESS;
+}
+
+static
+void send_to_stage2(struct s6_incoming_msg_data_t *incoming_msg_p)
+{
+	TRACE_ENTRY("\n****************WRITE TO g_Q_mme_S6a_fd");
+
+	incoming_msg_p->destInstAddr = htonl(mmeAppInstanceNum_c);
+	incoming_msg_p->srcInstAddr = htonl(s6AppInstanceNum_c);
+
+	/*Send to stage2 queue*/
+	send_tipc_message(g_Q_mme_S6a_fd, mmeAppInstanceNum_c, (char*)incoming_msg_p, S6_READ_MSG_BUF_SIZE);
+}
+
+int aia_resp_callback(struct msg **buf, struct avp *_avp,
+		struct session *session, void *data,
+		enum disp_action * action)
+{
+	TRACE_ENTRY("\n****************ANJANA ******  Callback ----- >AIA recvd\n");
+	int res = SUCCESS, sess_id_len;
+	struct msg *resp = *buf;
+	struct avp *avp_ptr = NULL;
+	unsigned char *sess_id= NULL;
+	struct s6_incoming_msg_data_t s6_incoming_msgs;
+	struct avp_hdr *avp_hdr = NULL;
+
+	log_msg(LOG_INFO, "\nCallback ----- >AIA recvd\n");
+
+	dump_fd_msg(resp);
+	//TODO - workaround for dump call. Remove this.
+	{
+		char * buf = NULL;
+		size_t len = 0;
+		printf("*********AIA CALLBACK******%s\n", fd_msg_dump_treeview(&buf, &len, NULL, resp,
+					fd_g_config->cnf_dict, 0, 1));
+		free(buf);
+	}
+
+	CHECK_FCT_DO(fd_sess_getsid(session, &sess_id, (size_t*)&sess_id_len),
+		return S6A_FD_ERROR);
+
+	log_msg(LOG_INFO, "\nCallback ----- >session id=%s \n",sess_id);
+    
+	s6_incoming_msgs.msg_type = auth_info_answer;
+	/*Retrieve UE index embedded in to session ID string at AIR time*/
+	s6_incoming_msgs.ue_idx = get_ue_idx_from_fd_resp(sess_id, sess_id_len);
+
+	/*AVP: Result-Code(268)*/
+	fd_msg_search_avp(resp, g_fd_dict_objs.res_code, &avp_ptr);
+
+	if (NULL != avp_ptr) {
+		fd_msg_avp_hdr(avp_ptr, &avp_hdr);
+		res = avp_hdr->avp_value->u32;
+
+		if (DIAMETER_SUCCESS != res) {
+			log_msg(LOG_ERROR, "Diameter error with HSS\n");
+		}
+		//Vikram: chk res = SUCCESS;
+
+	} else {
+		struct fd_result fd_res;
+
+		avp_ptr = NULL;
+		fd_msg_search_avp(resp, g_fd_dict_objs.exp_res,
+			&avp_ptr);
+
+		if (NULL == avp_ptr) {
+			res = S6A_FD_ERROR;
+		} else if (parse_fd_result(avp_ptr, &fd_res) != 0) {
+			res = S6A_FD_ERROR;
+		} else res = fd_res.result_code;
+	}
+
+	if (DIAMETER_SUCCESS == res) {
+		/*AVP: Authentication-Info*/
+		fd_msg_search_avp(resp, g_fd_dict_objs.auth_info,
+			&avp_ptr);
+
+		if (NULL != avp_ptr) {
+			if (get_aia_sec_vector(avp_ptr, &s6_incoming_msgs.msg_data.aia_Q_msg_m) != SUCCESS)
+				res = S6A_FD_ERROR;
+		} else {
+			res = S6A_FD_ERROR;
+		}
+	}
+
+	/*Handled fd msg, do cleanup*/
+	fd_msg_free(*buf);
+
+	*buf = NULL;
+
+	if (DIAMETER_SUCCESS != res) s6_incoming_msgs.msg_data.aia_Q_msg_m.res = S6A_AIA_FAILED;
+
+	send_to_stage2(&s6_incoming_msgs);
+
+	return SUCCESS;
+}
+
+void
+handle_perf_hss_aia(int ue_idx, struct hss_aia_msg *aia)
+{
+    struct s6_incoming_msg_data_t msg;
+
+	msg.ue_idx = ue_idx;
+	msg.msg_type = auth_info_answer;
+	msg.msg_data.aia_Q_msg_m.res= 0;
+	memcpy(&(msg.msg_data.aia_Q_msg_m.sec.rand), &(aia->rand), sizeof(RAND));
+	memcpy(&(msg.msg_data.aia_Q_msg_m.sec.xres), &(aia->xres), sizeof(XRES));
+	memcpy(&(msg.msg_data.aia_Q_msg_m.sec.autn), &(aia->autn), sizeof(AUTN));
+	memcpy(&(msg.msg_data.aia_Q_msg_m.sec.kasme), &(aia->kasme), sizeof(KASME));
+
+	send_to_stage2(&msg);/*handle diameter error*/
+}