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

Change-Id: Ie55032217232214ac8544ca76ea34335205329e4
diff --git a/src/mme-app/actionHandlers/defaultMmeProcedureActionHandlers.cpp b/src/mme-app/actionHandlers/defaultMmeProcedureActionHandlers.cpp
new file mode 100644
index 0000000..269b7fc
--- /dev/null
+++ b/src/mme-app/actionHandlers/defaultMmeProcedureActionHandlers.cpp
@@ -0,0 +1,382 @@
+/*
+ * Copyright 2019-present Infosys Limited
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/******************************************************************************
+ *
+ * This file has both generated and manual code.
+ *
+ * File template used for code generation:
+ * <TOP-DIR/scripts/SMCodeGen/templates/stateMachineTmpls/actionHandlers.cpp.tt>
+ *
+ ******************************************************************************/
+
+#include <actionHandlers/actionHandlers.h>
+#include <contextManager/dataBlocks.h>
+#include <contextManager/subsDataGroupManager.h>
+#include <controlBlock.h>
+#include <event.h>
+#include <mmeStates/attachStart.h>
+#include <mmeStates/detachStart.h>
+#include <mmeStates/niDetachStart.h>
+#include <mmeStates/pagingStart.h>
+#include <mmeStates/s1ReleaseStart.h>
+#include <mmeStates/serviceRequestStart.h>
+#include "mmeStates/tauStart.h"
+#include <msgBuffer.h>
+#include <msgType.h>
+#include <log.h>
+#include <procedureStats.h>
+#include <s1ap_structs.h>
+#include <state.h>
+#include <string.h>
+#include <sstream>
+#include <smTypes.h>
+#include <typeinfo>
+#include <utils/mmeProcedureTypes.h>
+#include <utils/mmeCommonUtils.h>
+#include <utils/mmeContextManagerUtils.h>
+
+using namespace mme;
+using namespace SM;
+
+/***************************************
+* Action handler : default_attach_req_handler
+***************************************/
+ActStatus ActionHandlers::default_attach_req_handler(ControlBlock& cb)
+{
+	log_msg(LOG_ERROR, "default_attach_req_handler \n");
+
+	UEContext* ueCtxt_p = NULL;
+	MmContext* mmctxt = NULL;
+
+	ueCtxt_p = static_cast <UEContext *>(cb.getPermDataBlock());
+	if (ueCtxt_p != NULL)
+		mmctxt = ueCtxt_p->getMmContext();
+
+	MsgBuffer* msgBuf = static_cast<MsgBuffer*>(cb.getMsgData());
+	if (msgBuf == NULL)
+	{
+		log_msg(LOG_ERROR, "Failed to retrieve message buffer \n");
+		return ActStatus::HALT;
+	}
+
+	const s1_incoming_msg_data_t* msgData_p =
+			static_cast<const s1_incoming_msg_data_t*>(msgBuf->getDataPointer());
+	if (msgData_p == NULL)
+	{
+		log_msg(LOG_ERROR, "Failed to retrieve data buffer \n");
+		return ActStatus::HALT;
+	}
+
+	const struct ue_attach_info &ue_info = (msgData_p->msg_data.ue_attach_info_m);
+
+	AttachType attachType = MmeCommonUtils::getAttachType(ueCtxt_p, ue_info);
+	if (attachType == maxAttachType_c)
+	{
+		log_msg(LOG_ERROR, "Failed to identify attach type \n");
+		return ActStatus::HALT;
+	}
+
+	if (ueCtxt_p == NULL)
+	{
+		ueCtxt_p = SubsDataGroupManager::Instance()->getUEContext();
+		if (ueCtxt_p == NULL)
+		{
+			log_msg(LOG_ERROR, "Failed to allocate UE context \n");
+
+			return ActStatus::HALT;
+		}
+
+		mmctxt = SubsDataGroupManager::Instance()->getMmContext();
+		if( mmctxt == NULL )
+		{
+			log_msg(LOG_ERROR, "Failed to allocate MM Context \n");
+
+			SubsDataGroupManager::Instance()->deleteUEContext( ueCtxt_p );
+			return ActStatus::HALT;
+		}
+
+		ueCtxt_p->setContextID(cb.getCBIndex());
+		ueCtxt_p->setMmContext( mmctxt );
+
+		cb.setPermDataBlock(ueCtxt_p);
+		cb.setFastAccessBlock(ueCtxt_p, 1);
+	}
+
+	MmeProcedureCtxt* prcdCtxt_p = SubsDataGroupManager::Instance()->getMmeProcedureCtxt();
+	if( prcdCtxt_p == NULL )
+	{
+		log_msg(LOG_ERROR, "Failed to allocate Procedure Context \n");
+
+		return ActStatus::HALT;
+	}
+
+	prcdCtxt_p->setCtxtType( ProcedureType::attach_c );
+	prcdCtxt_p->setNextState(AttachStart::Instance());
+
+	cb.setCurrentTempDataBlock(prcdCtxt_p);
+
+	// Copy attach request message data into UE Context
+
+	ueCtxt_p->setS1apEnbUeId(ue_info.s1ap_enb_ue_id);
+	ueCtxt_p->setEnbFd(ue_info.enb_fd);
+	ueCtxt_p->setTai(Tai(ue_info.tai));
+	ueCtxt_p->setUtranCgi(Cgi(ue_info.utran_cgi));
+	ueCtxt_p->setUeNetCapab(Ue_net_capab(ue_info.ue_net_capab));
+	ueCtxt_p->setMsNetCapab(Ms_net_capab(ue_info.ms_net_capab));
+	prcdCtxt_p->setPti(ue_info.pti);
+	prcdCtxt_p->setPcoOptions(ue_info.pco_options);
+	prcdCtxt_p->setEsmInfoTxRequired(ue_info.esm_info_tx_required);
+	prcdCtxt_p->setAttachType(attachType);
+
+	switch(attachType)
+	{
+		case imsiAttach_c:
+		{
+			uint8_t imsi[BINARY_IMSI_LEN] = {0};
+		    	memcpy( imsi, ue_info.IMSI, BINARY_IMSI_LEN );
+
+			// Only upper nibble of first octect in imsi need to be considered
+			// Changing the lower nibble to 0x0f for handling
+			uint8_t first = imsi[0] >> 4;
+			imsi[0] = (uint8_t)(( first << 4 ) | 0x0f );
+
+			DigitRegister15 IMSIInfo;
+			IMSIInfo.convertFromBcdArray(imsi);
+			ueCtxt_p->setImsi(IMSIInfo);
+
+			SubsDataGroupManager::Instance()->addimsikey(ueCtxt_p->getImsi(), ueCtxt_p->getContextID());
+
+			SM::Event evt(Event_e::VALIDATE_IMSI, NULL);
+			cb.addEventToProcQ(evt);
+
+			break;
+		}
+		case knownGutiAttach_c:
+		{
+			// copy seq num?
+
+			SM::Event evt(Event_e::VALIDATE_IMSI, NULL);
+			cb.addEventToProcQ(evt);
+
+			break;
+		}
+		case unknownGutiAttach_c:
+		{
+			SM::Event evt(Event_e::VALIDATE_IMSI, NULL);
+			cb.addEventToProcQ(evt);
+
+			break;
+		}
+		default:
+		{
+			log_msg(LOG_ERROR, "Unhandled attach type %s", attachType);
+		}
+	}
+
+	return ActStatus::PROCEED;
+}
+
+/***************************************
+* Action handler : default_detach_req_handler
+***************************************/
+ActStatus ActionHandlers::default_detach_req_handler(ControlBlock& cb)
+{
+	MmeDetachProcedureCtxt* prcdCtxt_p = SubsDataGroupManager::Instance()->getMmeDetachProcedureCtxt();
+	if( prcdCtxt_p == NULL )
+	{
+		log_msg(LOG_ERROR, "Failed to allocate procedure context for detach cbIndex %d\n", cb.getCBIndex());
+
+		return ActStatus::HALT;
+	}
+
+	prcdCtxt_p->setCtxtType( ProcedureType::detach_c );
+	prcdCtxt_p->setDetachType( DetachType::ueInitDetach_c );
+	prcdCtxt_p->setNextState(DetachStart::Instance());
+	cb.setCurrentTempDataBlock(prcdCtxt_p);
+
+	SM::Event evt(Event_e::DETACH_REQ_FROM_UE, NULL);
+	cb.addEventToProcQ(evt);
+
+	return ActStatus::PROCEED;
+}
+
+/***************************************
+* Action handler : default_ddn_handler
+***************************************/
+ActStatus ActionHandlers::default_ddn_handler(ControlBlock& cb)
+{
+	MmeSvcReqProcedureCtxt* svcReqProc_p = SubsDataGroupManager::Instance()->getMmeSvcReqProcedureCtxt();
+	if (svcReqProc_p == NULL)
+	{
+		log_msg(LOG_ERROR, "Failed to allocate procedure context"
+				" for DDN handling cbIndex %d\n", cb.getCBIndex());
+
+		return ActStatus::HALT;
+	}
+	
+	MsgBuffer* msgBuf = static_cast<MsgBuffer*>(cb.getMsgData());
+
+	if (msgBuf == NULL)
+	{
+	    log_msg(LOG_DEBUG,"process_ddn: msgBuf is NULL \n");
+	    return ActStatus::HALT;
+   	}
+
+   	const gtp_incoming_msg_data_t* gtp_msg_data= static_cast<const gtp_incoming_msg_data_t*>(msgBuf->getDataPointer());
+   	const struct ddn_Q_msg& ddn_info = gtp_msg_data->msg_data.ddn_Q_msg_m;
+
+	svcReqProc_p->setCtxtType(ProcedureType::serviceRequest_c);
+	svcReqProc_p->setNextState(PagingStart::Instance());
+	svcReqProc_p->setPagingTrigger(ddnInit_c);
+	svcReqProc_p->setDdnSeqNo(ddn_info.seq_no);
+	svcReqProc_p->setArp(Arp(ddn_info.arp));
+	svcReqProc_p->setEpsBearerId(ddn_info.eps_bearer_id);
+
+	cb.setCurrentTempDataBlock(svcReqProc_p);
+    
+	SM::Event evt(Event_e::DDN_FROM_SGW, NULL);
+	cb.addEventToProcQ(evt);
+	return ActStatus::PROCEED;
+}
+
+/***************************************
+* Action handler : default_service_req_handler
+***************************************/
+ActStatus ActionHandlers::default_service_req_handler(ControlBlock& cb)
+{
+	MmeSvcReqProcedureCtxt* svcReqProc_p = SubsDataGroupManager::Instance()->getMmeSvcReqProcedureCtxt();
+	if (svcReqProc_p == NULL)
+	{
+		log_msg(LOG_ERROR, "Failed to allocate procedure context"
+				" for service request cbIndex %d\n", cb.getCBIndex());
+
+		return ActStatus::HALT;
+	}
+
+	svcReqProc_p->setCtxtType(ProcedureType::serviceRequest_c);
+	svcReqProc_p->setNextState(ServiceRequestStart::Instance());
+	cb.setCurrentTempDataBlock(svcReqProc_p);
+
+	SM::Event evt(Event_e::SERVICE_REQUEST_FROM_UE, NULL);
+	cb.addEventToProcQ(evt);
+
+    return ActStatus::PROCEED;
+}
+
+/***************************************
+* Action handler : default_cancel_loc_req_handler
+***************************************/
+ActStatus ActionHandlers::default_cancel_loc_req_handler(ControlBlock& cb)
+{
+	UEContext *ueCtxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	if (ueCtxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	MmContext* mmCtxt = ueCtxt->getMmContext();
+	if (mmCtxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "mm context is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	if (mmCtxt->getMmState() == EpsDetached)
+	{
+		log_msg(LOG_INFO, "Subscriber is already detached. "
+				"Cleaning up the contexts. UE IDx %d\n", cb.getCBIndex());
+		
+		MmeContextManagerUtils::deleteUEContext(cb.getCBIndex());
+
+		return ActStatus::PROCEED;
+	}
+
+	MmeDetachProcedureCtxt* prcdCtxt_p = SubsDataGroupManager::Instance()->getMmeDetachProcedureCtxt();
+	if(prcdCtxt_p == NULL)
+	{
+		log_msg(LOG_ERROR, "Failed to allocate Procedure Ctxt\n");
+		return ActStatus::HALT;
+	}
+	prcdCtxt_p->setCtxtType( ProcedureType::detach_c );
+	prcdCtxt_p->setDetachType(DetachType::hssInitDetach_c);
+	prcdCtxt_p->setNextState(NiDetachStart::Instance());
+	prcdCtxt_p->setCancellationType(SUBSCRIPTION_WITHDRAWAL);
+	cb.setCurrentTempDataBlock(prcdCtxt_p);
+
+	SM::Event evt(Event_e::CLR_FROM_HSS, NULL);
+	cb.addEventToProcQ(evt);
+
+    return ActStatus::PROCEED;
+}
+
+/***************************************
+* Action handler : default_s1_release_req_handler
+***************************************/
+ActStatus ActionHandlers::default_s1_release_req_handler(ControlBlock& cb)
+{
+	MmeProcedureCtxt* prcdCtxt_p = SubsDataGroupManager::Instance()->getMmeProcedureCtxt();
+	if( prcdCtxt_p == NULL )
+	{
+		log_msg(LOG_ERROR, "Failed to allocate procedure Ctxt \n");
+		return ActStatus::HALT;
+	}
+
+	prcdCtxt_p->setCtxtType( ProcedureType::s1Release_c );
+	prcdCtxt_p->setNextState(S1ReleaseStart::Instance());
+	cb.setCurrentTempDataBlock(prcdCtxt_p);
+
+	ProcedureStats::num_of_s1_rel_req_received ++;
+
+	SM::Event evt(Event_e::S1_REL_REQ_FROM_UE, NULL);
+	cb.addEventToProcQ(evt);
+
+	return ActStatus::PROCEED;
+}
+
+/***************************************
+* Action handler : default_tau_req_handler
+***************************************/
+ActStatus ActionHandlers::default_tau_req_handler(ControlBlock& cb)
+{
+	MmeTauProcedureCtxt* tauReqProc_p = SubsDataGroupManager::Instance()->getMmeTauProcedureCtxt();
+	if (tauReqProc_p == NULL)
+	{
+		log_msg(LOG_ERROR, "Failed to allocate procedure context"
+				" for tau request cbIndex %d\n", cb.getCBIndex());
+
+		return ActStatus::HALT;
+	}
+	
+	MsgBuffer* msgBuf = static_cast<MsgBuffer*>(cb.getMsgData());
+	if (msgBuf == NULL)
+	{	
+            log_msg(LOG_DEBUG,"process_tau_req: msgBuf is NULL \n");
+            return ActStatus::HALT;
+	}
+	
+	const s1_incoming_msg_data_t* msgData_p =
+			static_cast<const s1_incoming_msg_data_t*>(msgBuf->getDataPointer());
+	if (msgData_p == NULL)
+	{
+		log_msg(LOG_ERROR, "Failed to retrieve data buffer \n");
+		return ActStatus::HALT;
+	}
+
+	const struct tauReq_Q_msg &tauReq = (msgData_p->msg_data.tauReq_Q_msg_m);	
+	
+	tauReqProc_p->setCtxtType(ProcedureType::tau_c);
+	tauReqProc_p->setNextState(TauStart::Instance());	
+	tauReqProc_p->setS1apEnbUeId(msgData_p->s1ap_enb_ue_id);
+	tauReqProc_p->setEnbFd(tauReq.enb_fd);
+	cb.setCurrentTempDataBlock(tauReqProc_p);	
+
+	SM::Event evt(Event_e::TAU_REQUEST_FROM_UE, NULL);
+	cb.addEventToProcQ(evt);
+	return ActStatus::PROCEED;
+}
+