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

Change-Id: Ie55032217232214ac8544ca76ea34335205329e4
diff --git a/src/s6a/handlers/s6a_req_handler.c b/src/s6a/handlers/s6a_req_handler.c
new file mode 100644
index 0000000..8bc361b
--- /dev/null
+++ b/src/s6a/handlers/s6a_req_handler.c
@@ -0,0 +1,346 @@
+/*
+ * 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 <stdbool.h>
+#include <freeDiameter/freeDiameter-host.h>
+#include <freeDiameter/libfdcore.h>
+#include <freeDiameter/libfdproto.h>
+
+#include "s6a_config.h"
+#include "err_codes.h"
+#include "message_queues.h"
+#include "ipc_api.h"
+#include "sec.h"
+#include "msgType.h"
+//#include "stage1_s6a_msg.h"
+#include "s6a_fd.h"
+#include "s6a.h"
+#include "s6a_config.h"
+#include "hss_message.h"
+
+/************************************************************************
+Current file : Stage  - AIR handler of S6A
+ATTACH stages :
+@@@	Stage 1 : IAM-->[stage1 handler]-->AIR, ULR
+	Stage 2 : AIA, ULA -->[stage2 handler]--> Auth req
+	Stage 3 : Auth resp-->[stage1 handler]-->Sec mode cmd
+	Stage 4 : sec mode resp-->[stage1 handler]-->esm infor req
+	Stage 5 : esm infor resp-->[stage1 handler]-->create session
+	Stage 6 : create session resp-->[stage1 handler]-->init ctx setup
+	Stage 7 : attach complete-->[stage1 handler]-->modify bearer
+**************************************************************************/
+
+/****Globals and externs ***/
+extern int g_our_hss_fd;
+extern s6a_config  g_s6a_cfg;
+extern struct fd_dict_objects g_fd_dict_objs;
+extern struct fd_dict_data g_fd_dict_data;
+/****Global and externs end***/
+
+
+void ulr_intermediate_cb(void * data, struct msg ** msg)
+{
+	dump_fd_msg(*msg);
+}
+
+/**
+ * @brief Prepare ULR freediameter message, dump and post to HSS
+ * @param[in] aia_msg - AIA info recvd from mme-app
+ * @param[in] imsi - IMSI
+ * @return int Sucess or failure code
+ */
+static int
+send_FD_ULR(struct s6a_Q_msg *aia_msg, char imsi[])
+{
+	struct msg *fd_msg = NULL;
+	int res = SUCCESS;
+	struct s6a_sess_info s6a_sess = {.sess_id="", .sess_id_len = 0};
+	char event = 12;
+	union avp_value val;
+
+	/*Create FD header and message for update location request.*/
+	if(SUCCESS != (res = create_fd_sess_id(&s6a_sess, aia_msg->ue_idx)))
+		return res;
+
+	CHECK_FCT_DO(fd_msg_new(g_fd_dict_objs.ULR, MSGFL_ALLOC_ETEID, &fd_msg),
+			return S6A_FD_ERROR)
+
+	/*AVP: Session-Id*/
+	val.os.data = (unsigned char*)s6a_sess.sess_id;
+	val.os.len = strlen(s6a_sess.sess_id);
+	add_fd_msg(&val, g_fd_dict_objs.sess_id, &fd_msg);
+
+	/*AVP: Auth-Session-State*/
+	val.i32 = 1; /*NO_STATE_MAINTAINED*/
+	val.os.len = 0;
+	add_fd_msg(&val, g_fd_dict_objs.auth_sess_state, &fd_msg);
+
+	/*AVP: Origin-Host/Realm*/
+	CHECK_FCT_DO(fd_msg_add_origin(fd_msg, 0), return S6A_FD_ERROR);
+
+	/*AVP: Destination-Host*/
+	val.os.data = (unsigned char*)g_s6a_cfg.hss_host_name;
+	val.os.len = strlen(g_s6a_cfg.hss_host_name);
+	add_fd_msg(&val, g_fd_dict_objs.dest_host, &fd_msg);
+
+	/*AVP: Destination-Realm*/
+	val.os.data = (unsigned char*)g_s6a_cfg.realm;
+	val.os.len = strlen(g_s6a_cfg.realm);
+	add_fd_msg(&val, g_fd_dict_objs.dest_realm, &fd_msg);
+
+	/*AVP: User-Name*/
+	val.os.data = (unsigned char*)imsi;
+	val.os.len = strlen(imsi);
+	add_fd_msg(&val, g_fd_dict_objs.user_name, &fd_msg);
+
+	/*AVP: RAT-Type*/
+	val.u32 = S6A_RAT_EUTRAN;
+	val.os.len = 0;
+	add_fd_msg(&val, g_fd_dict_objs.RAT_type, &fd_msg);
+
+	/*AVP: ULR-Flags*/
+	val.u32 = ULR_FLAG_S6AS6D_IND | ULR_FLAG_INIT_ATCH_IND ;
+	add_fd_msg(&val, g_fd_dict_objs.ULR_flags, &fd_msg);
+
+	/*AVP: Visited-PLMN-Id*/
+	val.os.data = (unsigned char*)aia_msg->tai.plmn_id.idx;
+	val.os.len = 3;
+	add_fd_msg(&val, g_fd_dict_objs.visited_PLMN_id, &fd_msg);
+
+	dump_fd_msg(fd_msg);
+
+	/*Post ULR to HSS*/
+	CHECK_FCT_DO(fd_msg_send(&fd_msg, ulr_intermediate_cb, (void*)&event),
+			return S6A_FD_ERROR);
+
+	return SUCCESS;
+}
+
+
+/**
+ * @brief dump recvd aia queue msg
+ * @param[in] air_msg - IMSI
+ * @return void
+ */
+void
+dump_s6a_msg(struct s6a_Q_msg *air_msg)
+{
+	log_msg(LOG_INFO, "Received index= %d\n",air_msg->ue_idx);
+	log_msg(LOG_INFO, "Received plmn %x %x %x= %d\n",air_msg->tai.plmn_id.idx[0],
+			air_msg->tai.plmn_id.idx[1], air_msg->tai.plmn_id.idx[2]);
+}
+
+/**
+ * @brief Prepare AIR freediameter message, dump and post to HSS
+ * @param[in] aia_msg - AIA info recvd from mme-app
+ * @param[in] imsi - IMSI
+ * @return int Sucess or failure code
+ */
+static int
+send_FD_AIR(struct s6a_Q_msg *aia_msg, char imsi[])
+{
+	struct avp *avp_ptr = NULL;
+	struct msg *fd_msg = NULL;
+	int res = 0;
+	struct s6a_sess_info s6a_sess = {.sess_id="", .sess_id_len = 0};
+	union avp_value val;
+
+	log_msg(LOG_INFO, "In Send AIR:\n");
+	dump_s6a_msg(aia_msg);
+
+	/*Create FD header and message for authentication info request.*/
+	if(SUCCESS != (res = create_fd_sess_id(&s6a_sess, aia_msg->ue_idx)))
+		return res;
+
+	CHECK_FCT_DO(fd_msg_new(g_fd_dict_objs.AIR, MSGFL_ALLOC_ETEID, &fd_msg),
+			return S6A_FD_ERROR);
+
+	/*AVP: Session-Id*/
+	val.os.data = (unsigned char*)s6a_sess.sess_id;
+	val.os.len = strlen(s6a_sess.sess_id);
+	add_fd_msg(&val, g_fd_dict_objs.sess_id, &fd_msg);
+
+	/*AVP: Auth-Session-State*/
+	val.i32 = 1; /*NO_STATE_MAINTAINED*/
+	val.os.len = 0;
+	add_fd_msg(&val, g_fd_dict_objs.auth_sess_state, &fd_msg);
+
+	/*AVP: Origin-Host/Realm*/
+	CHECK_FCT_DO(fd_msg_add_origin(fd_msg, 0), return S6A_FD_ERROR)
+
+	/*AVP: Destination-Host*/
+	val.os.data = (unsigned char*)g_s6a_cfg.hss_host_name;
+	val.os.len = strlen(g_s6a_cfg.hss_host_name);
+	add_fd_msg(&val, g_fd_dict_objs.dest_host, &fd_msg);
+
+	/*AVP: Destination-Realm*/
+	val.os.data = (unsigned char*)g_s6a_cfg.realm;
+	val.os.len = strlen(g_s6a_cfg.realm);
+	add_fd_msg(&val, g_fd_dict_objs.dest_realm, &fd_msg);
+
+	/*AVP: User-Name*/
+	val.os.data = (unsigned char*)imsi;
+	val.os.len = strlen(imsi);
+	add_fd_msg(&val, g_fd_dict_objs.user_name, &fd_msg);
+
+	/*AVP: Visited-PLMN-Id*/
+	val.os.data = (unsigned char*)aia_msg->tai.plmn_id.idx;
+	val.os.len = 3;
+	add_fd_msg(&val, g_fd_dict_objs.visited_PLMN_id, &fd_msg);
+
+	/*TODO: recheck. Can it be grouped better way*/
+	/*AVP: Requested-EUTRAN-Authentication-Info*/
+	CHECK_FCT_DO(fd_msg_avp_new(
+		g_fd_dict_objs.req_EUTRAN_auth_info, 0, &avp_ptr),
+		return -1);
+	CHECK_FCT_DO(fd_msg_avp_add(fd_msg, MSG_BRW_LAST_CHILD, avp_ptr), return -1);
+
+	/*AVP: Requested-EUTRAN-Authentication-Info
+	 *----->AVP: Number-Of-Requested-Vectors(1410)*/
+	val.i32 = 1;
+	val.os.len = 0;
+	add_fd_msg(&val, g_fd_dict_objs.no_of_req_vectors,
+			(struct msg**)&avp_ptr);
+
+	/*AVP: Requested-EUTRAN-Authentication-Info
+	 * ------>AVP: Immediate-Response-Preferred*/
+	val.u32 = 0;
+	add_fd_msg(&val, g_fd_dict_objs.immediate_resp_pref,
+			(struct msg**)&avp_ptr);
+
+	dump_fd_msg(fd_msg);
+
+	/*post AIR to hss */
+	CHECK_FCT_DO(fd_msg_send(&fd_msg, NULL, NULL), return S6A_FD_ERROR);
+
+	return SUCCESS;
+}
+
+/**
+API to send AIR oto customer HSS over custome RPC
+*/
+static void
+send_rpc_AIR(struct s6a_Q_msg *air_msg, char imsi[])
+{
+	struct hss_req_msg msg;
+
+	msg.hdr = HSS_AIR_MSG;
+	msg.ue_idx = air_msg->ue_idx;
+
+	strncpy(msg.data.air.imsi, imsi, IMSI_STR_LEN);
+	memcpy(msg.data.air.plmn_id, air_msg->tai.plmn_id.idx, 3);
+
+	if (write(g_our_hss_fd, &msg, HSS_REQ_MSG_SIZE) < 0) {
+		log_msg(LOG_ERROR, "HSS AIR msg send failed.\n");
+		 		perror("writing on stream socket");
+	}
+	log_msg(LOG_INFO, "AIR msg send to hss for ue_idx %d\n",
+		air_msg->ue_idx);
+}
+
+/**
+API to send ULR oto customer HSS over custome RPC
+*/
+static void
+send_rpc_ULR(struct s6a_Q_msg *ulr_msg, char imsi[])
+{
+	struct hss_req_msg msg;
+
+	msg.hdr = HSS_ULR_MSG;
+	msg.ue_idx = ulr_msg->ue_idx;
+
+	strncpy(msg.data.air.imsi, imsi, IMSI_STR_LEN);
+	memcpy(msg.data.air.plmn_id, ulr_msg->tai.plmn_id.idx, 3);
+
+	if (write(g_our_hss_fd, &msg, HSS_REQ_MSG_SIZE) < 0) {
+		log_msg(LOG_ERROR, "HSS ULR msg send failed.\n");
+		perror("writing on stream socket");
+	}
+	log_msg(LOG_INFO, "ULR msg send to hss\n");
+}
+
+
+/**
+ * @brief convert binary imsi to string imsi
+ * Binary imsi is stored in 8 bytes, each nibble representing each imsi char.
+ * char imsi stroes each char in 1 byte.
+ * @param[in] b_imsi : Binary imsi
+ * @param[out] s_imsi : Converted string imsi
+ * @return void
+ */
+void
+imsi_bin_to_str(unsigned char *b_imsi, char *s_imsi)
+{
+	if(NULL == b_imsi || NULL == s_imsi) return;
+
+	memset(s_imsi, 0, STR_IMSI_LEN);
+
+	/* Byte 'AB' in b_imsi, is converted to two bytes 'A', 'B' in s_imsi*/
+	s_imsi[0] = '0' + ((b_imsi[0]>>4) & 0x0F);
+
+	for(int i=1; i < BINARY_IMSI_LEN; ++i) {
+		s_imsi[(i*2)-1] = '0' + (b_imsi[i] & 0x0F);
+		s_imsi[(i*2)] = '0' + ((b_imsi[i]>>4) & 0x0F);
+	}
+	s_imsi[(BINARY_IMSI_LEN*2)-1] = '\0';
+}
+
+/**
+ * @brief Post AIR and ULR messsages simultaneously to HSS.
+ * @return int Sucess or failure code
+ */
+static int
+AIR_processing(struct s6a_Q_msg * air_msg)
+{
+	log_msg(LOG_INFO, "IMSI recvd - %s\n %d \n", air_msg->imsi, air_msg->msg_type);
+
+	if(HSS_FD == g_s6a_cfg.hss_type) {
+		if(air_msg->msg_type == auth_info_request)
+			/*post to next processing*/
+			send_FD_AIR(air_msg, air_msg->imsi);
+		else if(air_msg->msg_type == update_loc_request)
+			send_FD_ULR(air_msg, air_msg->imsi);
+
+	} else {
+		log_msg(LOG_INFO, "Sending over IPC\n");
+		send_rpc_AIR(air_msg, air_msg->imsi);
+		send_rpc_ULR(air_msg, air_msg->imsi);
+	}
+
+	return SUCCESS;
+}
+
+/*
+* Thread function for stage.
+*/
+void*
+S6Req_handler(void *data)
+{
+	log_msg(LOG_INFO, "AIR Q handler ready.\n");
+
+	char *msg = ((char *) data) + ((sizeof(uint32_t)) * 2);
+	
+	AIR_processing((struct s6a_Q_msg *)msg);
+	
+	return NULL;
+}