diff --git a/src/mme-app/actionHandlers/attachActionHandlers.cpp b/src/mme-app/actionHandlers/attachActionHandlers.cpp
new file mode 100644
index 0000000..78b8761
--- /dev/null
+++ b/src/mme-app/actionHandlers/attachActionHandlers.cpp
@@ -0,0 +1,980 @@
+/*
+ * 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 <3gpp_24008.h>
+#include <typeinfo>
+#include "actionHandlers/actionHandlers.h"
+#include "controlBlock.h"
+#include "msgType.h"
+#include "contextManager/subsDataGroupManager.h"
+#include "contextManager/dataBlocks.h"
+#include "procedureStats.h"
+#include "log.h"
+#include "secUtils.h"
+#include "state.h"
+#include <string.h>
+#include <sstream>
+#include <smTypes.h>
+#include <cstring>
+#include <event.h>
+#include <ipcTypes.h>
+#include <tipcTypes.h>
+#include <msgBuffer.h>
+#include <interfaces/mmeIpcInterface.h>
+#include <utils/mmeCommonUtils.h>
+#include <utils/mmeContextManagerUtils.h>
+
+using namespace SM;
+using namespace mme;
+using namespace cmn::utils;
+
+extern MmeIpcInterface* mmeIpcIf_g;
+
+ActStatus ActionHandlers::validate_imsi_in_ue_context(ControlBlock& cb)
+{
+    UEContext* ueCtxt_p = static_cast<UEContext*>(cb.getPermDataBlock());
+    if (ueCtxt_p == NULL)
+    {
+         log_msg(LOG_DEBUG, "send_identity_request_to_ue: ue context is NULL \n");
+         return ActStatus::HALT;
+    }
+
+    if (ueCtxt_p->getImsi().isValid())
+    {
+        SM::Event evt(Event_e::IMSI_VALIDATION_SUCCESS, NULL);
+        cb.addEventToProcQ(evt);
+    }
+    else
+    {
+        // TODO: If known GUTI, IMSI_VALIDATION_FAILURE_KNOWN_GUTI to trigger id req to UE
+        // If unknown GUTI, IMSI_VALIDATION_FAILURE_UNKNOWN_GUTI to query old mme
+        // when s10 is supported in MME
+        SM::Event evt(Event_e::IMSI_VALIDATION_FAILURE, NULL);
+        cb.addEventToProcQ(evt);
+    }
+    return ActStatus::PROCEED;
+}
+
+ActStatus ActionHandlers::send_identity_request_to_ue(ControlBlock& cb)
+{
+	log_msg(LOG_DEBUG, "Inside send_identity_request_to_ue \n");
+
+	UEContext* ueCtxt_p = static_cast<UEContext*>(cb.getPermDataBlock());
+	if (ueCtxt_p == NULL)
+	{
+		log_msg(LOG_DEBUG, "send_identity_request_to_ue: ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	struct attachIdReq_info idReqMsg;
+	idReqMsg.msg_type = id_request;
+	idReqMsg.enb_fd = ueCtxt_p->getEnbFd();
+	idReqMsg.s1ap_enb_ue_id = ueCtxt_p->getS1apEnbUeId();
+	idReqMsg.ue_idx = ueCtxt_p->getContextID();
+	idReqMsg.ue_type = ID_IMSI;
+
+	cmn::ipc::IpcAddress destAddr;
+	destAddr.u32 = TipcServiceInstance::s1apAppInstanceNum_c;
+
+	mmeIpcIf_g->dispatchIpcMsg((char *) &idReqMsg, sizeof(idReqMsg), destAddr);
+
+    return ActStatus::PROCEED;
+}
+
+ActStatus ActionHandlers::process_identity_response(ControlBlock& cb)
+{
+	log_msg(LOG_DEBUG, "Inside process_identity_response \n");
+
+	UEContext *ueCtxt_p = static_cast<UEContext*>(cb.getPermDataBlock());
+	if (ueCtxt_p == NULL)
+	{
+		log_msg(LOG_DEBUG, "process_identity_response: ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	MsgBuffer* msgBuf = static_cast<MsgBuffer*>(cb.getMsgData());
+	if (msgBuf == NULL)
+	{
+		log_msg(LOG_DEBUG, "process_identity_response: msgBuf is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	const s1_incoming_msg_data_t* s1_msg_data = static_cast<const s1_incoming_msg_data_t*>(msgBuf->getDataPointer());
+	if (s1_msg_data == NULL)
+	{
+		log_msg(LOG_DEBUG, "process_identity_response: s1MsgData is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	const struct identityResp_Q_msg &id_resp = s1_msg_data->msg_data.identityResp_Q_msg_m;
+	if(SUCCESS != id_resp.status)
+    	{
+		log_msg(LOG_DEBUG, "process_identity_response: ID Response Failure NULL \n");
+		return ActStatus::HALT;
+	}
+
+	uint8_t imsi[BINARY_IMSI_LEN] = {0};
+    	memcpy( imsi, id_resp.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());
+
+    return ActStatus::PROCEED;
+}
+
+
+ActStatus ActionHandlers::send_air_to_hss(SM::ControlBlock& cb)
+{  
+	log_msg(LOG_DEBUG, "Inside send_air_to_hss \n");
+	
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	if (ue_ctxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "send_air_to_hss: ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	s6a_Q_msg s6a_req;
+	
+	memset(s6a_req.imsi, '\0', sizeof(s6a_req.imsi));
+	ue_ctxt->getImsi().getImsiDigits(s6a_req.imsi);
+
+	memcpy(&(s6a_req.tai), &(ue_ctxt->getTai().tai_m), sizeof(struct TAI));
+
+	s6a_req.ue_idx = ue_ctxt->getContextID();
+	s6a_req.msg_type = auth_info_request;
+
+	cmn::ipc::IpcAddress destAddr;
+	destAddr.u32 = TipcServiceInstance::s6AppInstanceNum_c;
+
+	mmeIpcIf_g->dispatchIpcMsg((char *) &s6a_req, sizeof(s6a_req), destAddr);
+
+	ProcedureStats::num_of_air_sent ++;
+	log_msg(LOG_DEBUG, "Leaving send_air_to_hss \n");
+	
+	return ActStatus::PROCEED;
+
+}
+
+ActStatus ActionHandlers::send_ulr_to_hss(SM::ControlBlock& cb)
+{  
+	log_msg(LOG_DEBUG, "Inside send_ulr_to_hss \n");
+	
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	if (ue_ctxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "send_ulr_to_hss: ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	s6a_Q_msg s6a_req;
+
+	memset(s6a_req.imsi, '\0', sizeof(s6a_req.imsi));
+	ue_ctxt->getImsi().getImsiDigits(s6a_req.imsi);
+
+	memcpy(&(s6a_req.tai), &(ue_ctxt->getTai().tai_m), sizeof(struct TAI));
+
+	s6a_req.ue_idx = ue_ctxt->getContextID();
+	s6a_req.msg_type = update_loc_request;
+
+	cmn::ipc::IpcAddress destAddr;
+	destAddr.u32 = TipcServiceInstance::s6AppInstanceNum_c;
+
+	mmeIpcIf_g->dispatchIpcMsg((char *) &s6a_req, sizeof(s6a_req), destAddr);
+
+	ProcedureStats::num_of_ulr_sent ++;
+	log_msg(LOG_DEBUG, "Leaving send_ulr_to_hss \n");
+	
+	return ActStatus::PROCEED;
+}
+
+
+ActStatus ActionHandlers::process_aia(SM::ControlBlock& cb)
+{
+	log_msg(LOG_DEBUG, "Inside handle_aia \n");
+
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	if (ue_ctxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "handle_aia: ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	MsgBuffer* msgBuf = static_cast<MsgBuffer*>(cb.getMsgData());
+
+	if (msgBuf == NULL)
+		return ActStatus::HALT;
+
+	const s6_incoming_msg_data_t* msgData_p = static_cast<const s6_incoming_msg_data_t*>(msgBuf->getDataPointer());
+
+	ue_ctxt->setAiaSecInfo(E_utran_sec_vector(msgData_p->msg_data.aia_Q_msg_m.sec));
+	
+	ProcedureStats::num_of_processed_aia ++;
+	log_msg(LOG_DEBUG, "Leaving handle_aia \n");
+	
+	return ActStatus::PROCEED;
+}
+
+ActStatus ActionHandlers::process_ula(SM::ControlBlock& cb)
+{
+	log_msg(LOG_DEBUG, "Inside handle_ula \n");
+
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	if (ue_ctxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "handle_ula: ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	SessionContext* sessionCtxt = ue_ctxt->getSessionContext();
+	if( sessionCtxt == NULL )
+    	{
+		log_msg(LOG_ERROR, "Failed to retrieve Session Context for UE IDX %d\n", cb.getCBIndex());
+        	return ActStatus::HALT;
+    	}
+	
+	MsgBuffer* msgBuf = static_cast<MsgBuffer*>(cb.getMsgData());
+
+	if (msgBuf == NULL)
+		return ActStatus::HALT;
+
+	const s6_incoming_msg_data_t* s6_msg_data = static_cast<const s6_incoming_msg_data_t*>(msgBuf->getDataPointer());
+	const struct ula_Q_msg &ula_msg = s6_msg_data->msg_data.ula_Q_msg_m;
+
+	sessionCtxt->setApnConfigProfileCtxId(ula_msg.apn_config_profile_ctx_id);
+	DigitRegister15 ueMSISDN;
+	ueMSISDN.convertFromBcdArray( reinterpret_cast<const uint8_t*>( ula_msg.MSISDN ));
+	ue_ctxt->setMsisdn(ueMSISDN);
+	ue_ctxt->setRauTauTimer(ula_msg.RAU_TAU_timer);
+	ue_ctxt->setSubscriptionStatus(ula_msg.subscription_status);
+	ue_ctxt->setNetAccessMode(ula_msg.net_access_mode);
+	ue_ctxt->setAccessRestrictionData(ula_msg.access_restriction_data);
+
+	struct AMBR ambr;
+	ambr.max_requested_bw_dl = ula_msg.max_requested_bw_dl;
+	ambr.max_requested_bw_ul = ula_msg.max_requested_bw_ul;
+	
+	ue_ctxt->setAmbr(Ambr(ambr));
+	
+	ProcedureStats::num_of_processed_ula ++;
+	log_msg(LOG_DEBUG, "Leaving handle_ula_v \n");
+	
+	return ActStatus::PROCEED;
+}
+
+ActStatus ActionHandlers::auth_req_to_ue(SM::ControlBlock& cb)
+{
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+
+	if (ue_ctxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "auth_req_to_ue: ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	authreq_info authreq;
+	authreq.msg_type = auth_request;
+	authreq.ue_idx = ue_ctxt->getContextID();
+	authreq.enb_fd = ue_ctxt->getEnbFd();
+	authreq.enb_s1ap_ue_id = ue_ctxt->getS1apEnbUeId();
+
+	ue_ctxt->setDwnLnkSeqNo(0);
+
+	E_UTRAN_sec_vector *secVect = const_cast<E_UTRAN_sec_vector*>(ue_ctxt->getAiaSecInfo().AiaSecInfo_mp);
+
+	secinfo& secInfo = const_cast<secinfo&>(ue_ctxt->getUeSecInfo().secinfo_m);
+
+	SecUtils::create_integrity_key(secVect->kasme.val, secInfo.int_key);
+
+	memcpy(&(authreq.rand), &(secVect->rand.val), NAS_RAND_SIZE);
+	memcpy(&(authreq.autn), &(secVect->autn.val), NAS_AUTN_SIZE);
+	
+	cmn::ipc::IpcAddress destAddr;
+	destAddr.u32 = TipcServiceInstance::s1apAppInstanceNum_c;
+
+	mmeIpcIf_g->dispatchIpcMsg((char *) &authreq, sizeof(authreq), destAddr);
+
+	
+	ProcedureStats::num_of_auth_req_to_ue_sent ++;
+	log_msg(LOG_DEBUG, "Leaving auth_req_to_ue_v \n");
+		
+	return ActStatus::PROCEED;
+}
+
+ActStatus ActionHandlers::auth_response_validate(SM::ControlBlock& cb)
+{
+	log_msg(LOG_DEBUG, "Inside auth_response_validate \n");
+	SM::ControlBlock* controlBlk_p = SubsDataGroupManager::Instance()->findControlBlock(cb.getCBIndex());
+
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	if (ue_ctxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "auth_response_validate: ue context or procedure ctxt is NULL \n");
+		return ActStatus::HALT;
+	}
+	
+	MsgBuffer* msgBuf = static_cast<MsgBuffer*>(cb.getMsgData());
+
+	if (msgBuf == NULL)
+		return ActStatus::HALT;
+
+	const s1_incoming_msg_data_t* s1_msg_data = static_cast<const s1_incoming_msg_data_t*>(msgBuf->getDataPointer());	
+	const struct authresp_Q_msg &auth_resp = s1_msg_data->msg_data.authresp_Q_msg_m;
+	
+	/*Check the state*/
+	if(SUCCESS != auth_resp.status) {
+		log_msg(LOG_ERROR, "eNB authentication failure for UE-%d.\n", ue_ctxt->getContextID());
+		if(auth_resp.auts.len == 0)
+		{
+			log_msg(LOG_ERROR,"No AUTS.Not Synch Failure\n");
+			SM::Event evt(Event_e::AUTH_RESP_FAILURE,NULL);
+        		controlBlk_p->addEventToProcQ(evt);
+		}
+		else
+		{
+			log_msg(LOG_INFO,"AUTS recvd.  Synch failure. send AIR\n");
+			SM::Event evt(Event_e::AUTH_RESP_SYNC_FAILURE,NULL);
+            		controlBlk_p->addEventToProcQ(evt);
+		}
+	}
+	else{
+		log_msg(LOG_INFO,"Auth response validation success. Proceeding to Sec mode Command\n");
+                SM::Event evt(Event_e::AUTH_RESP_SUCCESS,NULL);
+                controlBlk_p->addEventToProcQ(evt);
+
+	}
+	//TODO: XRES comparison
+	#if 0
+	log_msg(LOG_ERROR, "stage 3 processing memcmp - %d, %d, %d", &(ue_ctxt->getaiaSecInfo().AiaSecInfo_mp->xres.val),
+                &(auth_resp->res.val),
+                auth_resp->res.len);
+	if(memcmp(&(ue_ctxt->getaiaSecInfo().AiaSecInfo_mp->xres.val),
+		&(auth_resp->res.val),
+		auth_resp->res.len) != 0) {
+		log_msg(LOG_ERROR, "Invalid auth result received for UE %d",
+			auth_resp->ue_idx);
+		return E_FAIL;//report failure
+	}
+	#endif
+	
+	ProcedureStats::num_of_processed_auth_response ++;
+	log_msg(LOG_DEBUG, "Leaving auth_response_validate \n");
+	
+	return ActStatus::PROCEED;
+}
+
+ActStatus ActionHandlers::send_auth_reject(SM::ControlBlock& cb)
+{
+	log_msg(LOG_DEBUG, "Inside send_auth_reject \n");
+
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	if (ue_ctxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "send_auth_reject: ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+	return ActStatus::HALT;
+}
+	
+
+ActStatus ActionHandlers::sec_mode_cmd_to_ue(SM::ControlBlock& cb)
+{
+	log_msg(LOG_DEBUG, "Inside sec_mode_cmd_to_ue \n");
+
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	if (ue_ctxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "sec_mode_cmd_to_ue: ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+	sec_mode_Q_msg sec_mode_msg;
+	sec_mode_msg.msg_type  = sec_mode_command;
+	sec_mode_msg.ue_idx = ue_ctxt->getContextID();
+	sec_mode_msg.enb_fd = ue_ctxt->getEnbFd();
+	sec_mode_msg.enb_s1ap_ue_id = ue_ctxt->getS1apEnbUeId();
+	
+	memcpy(&(sec_mode_msg.ue_network), &(ue_ctxt->getUeNetCapab().ue_net_capab_m),
+		sizeof(struct UE_net_capab));
+
+	memcpy(&(sec_mode_msg.ms_net_capab), &(ue_ctxt->getMsNetCapab().ms_net_capab_m),
+                sizeof(struct MS_net_capab));
+
+	memcpy(&(sec_mode_msg.key), &(ue_ctxt->getAiaSecInfo().AiaSecInfo_mp->kasme),
+			sizeof(struct KASME));
+
+	memcpy(&(sec_mode_msg.int_key), &(ue_ctxt->getUeSecInfo().secinfo_m.int_key),
+			NAS_INT_KEY_SIZE);
+
+	sec_mode_msg.dl_seq_no = ue_ctxt->getDwnLnkSeqNo();
+	ue_ctxt->setDwnLnkSeqNo(sec_mode_msg.dl_seq_no + 1);
+
+	cmn::ipc::IpcAddress destAddr;
+	destAddr.u32 = TipcServiceInstance::s1apAppInstanceNum_c;
+
+	mmeIpcIf_g->dispatchIpcMsg((char *) &sec_mode_msg, sizeof(sec_mode_msg), destAddr);
+	
+	ProcedureStats::num_of_sec_mode_cmd_to_ue_sent ++;
+	log_msg(LOG_DEBUG, "Leaving sec_mode_cmd_to_ue \n");
+	
+	return ActStatus::PROCEED;
+}
+
+
+ActStatus ActionHandlers::process_sec_mode_resp(SM::ControlBlock& cb)
+{
+	log_msg(LOG_DEBUG, "Inside handle_sec_mode_resp \n");
+
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	if (ue_ctxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "handle_sec_mode_resp: ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	MsgBuffer* msgBuf = static_cast<MsgBuffer*>(cb.getMsgData());
+
+	if (msgBuf == NULL)
+		return ActStatus::HALT;
+
+	const s1_incoming_msg_data_t* s1_msg_data = static_cast<const s1_incoming_msg_data_t*>(msgBuf->getDataPointer());
+	const secmode_resp_Q_msg &secmode_resp = s1_msg_data->msg_data.secmode_resp_Q_msg_m;
+	if(SUCCESS == secmode_resp.status)
+	{
+		log_msg(LOG_INFO, "Sec mode complete rcv. UE - %d.\n",
+				ue_ctxt->getContextID());
+		
+	}	
+	else
+	{
+		log_msg(LOG_INFO, "Sec mode failed. UE %d", ue_ctxt->getContextID());
+	}
+
+	ProcedureStats::num_of_processed_sec_mode_resp ++;
+	log_msg(LOG_DEBUG, "Leaving handle_sec_mode_resp \n");
+	
+	return ActStatus::PROCEED;
+}
+
+ActStatus ActionHandlers::check_esm_info_req_required(SM::ControlBlock& cb)
+{
+	log_msg(LOG_DEBUG, "Inside check_esm_info_req_required \n");
+
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	if (ue_ctxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "check_esm_info_req_required: ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+	
+	MmeProcedureCtxt* procedure_p = dynamic_cast<MmeProcedureCtxt*>(cb.getTempDataBlock());
+	if (procedure_p == NULL)
+	{
+		log_msg(LOG_DEBUG, "check_esm_info_req_required: procedure context is NULL \n");
+		return ActStatus::HALT;		
+	}
+	SessionContext* sessionCtxt = SubsDataGroupManager::Instance()->getSessionContext();
+	if( sessionCtxt == NULL )
+	{
+	    log_msg(LOG_ERROR, "Failed to allocate Session Context for UE IDX %d\n", cb.getCBIndex());
+
+	    return ActStatus::HALT;
+	}
+	BearerContext* bearerCtxt_p = SubsDataGroupManager::Instance()->getBearerContext();
+	if( bearerCtxt_p == NULL )
+	{
+	    log_msg(LOG_ERROR, "Failed to allocate Bearer context for UE IDx %d\n", cb.getCBIndex());
+
+	    return ActStatus::HALT;
+	}
+
+	bearerCtxt_p->setBearerId(5);
+	sessionCtxt->setPti(procedure_p->getPti());
+	sessionCtxt->setBearerContext( bearerCtxt_p );
+	ue_ctxt->setSessionContext(sessionCtxt);
+	
+	if (procedure_p->getEsmInfoTxRequired() == false)
+	{
+		// hardcoding APN, if ESM info request is not to be sent
+		std::string apnName = "apn1";
+		struct apn_name apn = {0};
+		apn.len = apnName.length() + 1;
+		apn.val[0] = apnName.length();
+		memcpy(&(apn.val[1]), apnName.c_str(), apnName.length());
+
+		sessionCtxt->setAccessPtName(Apn_name(apn));
+        
+		SM::Event evt(Event_e::ESM_INFO_NOT_REQUIRED, NULL);
+		cb.addEventToProcQ(evt);
+	} 
+	else
+	{
+		SM::Event evt(Event_e::ESM_INFO_REQUIRED, NULL);
+		cb.addEventToProcQ(evt);
+	}
+	
+	return  ActStatus::PROCEED;
+}
+
+ActStatus ActionHandlers::send_esm_info_req_to_ue(SM::ControlBlock& cb)
+{
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+
+	if (ue_ctxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "send_esm_info_req_to_ue: ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	SessionContext *sessionCtxt = ue_ctxt->getSessionContext();
+	esm_req_Q_msg esmreq;
+	esmreq.msg_type = esm_info_request;
+	esmreq.ue_idx = ue_ctxt->getContextID();
+	esmreq.enb_fd = ue_ctxt->getEnbFd();
+	esmreq.enb_s1ap_ue_id = ue_ctxt->getS1apEnbUeId();
+	esmreq.pti = sessionCtxt->getPti();
+	esmreq.dl_seq_no = ue_ctxt->getDwnLnkSeqNo();
+	memcpy(&(esmreq.int_key), &((ue_ctxt->getUeSecInfo().secinfo_m).int_key),
+			NAS_INT_KEY_SIZE);
+	ue_ctxt->setDwnLnkSeqNo(esmreq.dl_seq_no+1);
+
+	cmn::ipc::IpcAddress destAddr;
+	destAddr.u32 = TipcServiceInstance::s1apAppInstanceNum_c;
+
+	mmeIpcIf_g->dispatchIpcMsg((char *) &esmreq, sizeof(esmreq), destAddr);
+
+	log_msg(LOG_DEBUG, "Leaving send_esm_info_req_to_ue \n");
+
+	return ActStatus::PROCEED;
+}
+
+ActStatus ActionHandlers::process_esm_info_resp(SM::ControlBlock& cb)
+{
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	if (ue_ctxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "handle_ula: ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	SessionContext* sessionCtxt = ue_ctxt->getSessionContext();
+	if( sessionCtxt == NULL )
+	{
+	    log_msg(LOG_ERROR, "Failed to allocate Session "
+                            "Context for UE IDX %d\n", cb.getCBIndex());
+	    return ActStatus::HALT;
+	}
+
+	MsgBuffer* msgBuf = static_cast<MsgBuffer*>(cb.getMsgData());
+
+	if (msgBuf == NULL)
+		return ActStatus::HALT;
+
+	const s1_incoming_msg_data_t* s1_msg_data = static_cast<const s1_incoming_msg_data_t*>(msgBuf->getDataPointer());
+	const struct esm_resp_Q_msg &esm_res =s1_msg_data->msg_data.esm_resp_Q_msg_m;
+
+    	sessionCtxt->setAccessPtName(Apn_name(esm_res.apn));
+
+	return ActStatus::PROCEED;
+}
+
+ActStatus ActionHandlers::cs_req_to_sgw(SM::ControlBlock& cb)
+{
+	log_msg(LOG_DEBUG, "Inside cs_req_to_sgw \n");
+
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	MmeProcedureCtxt *procCtxt = dynamic_cast<MmeProcedureCtxt*>(cb.getTempDataBlock());
+	if (ue_ctxt == NULL  || procCtxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "handle_ula: UE context or Procedure Context is NULL \n");
+
+		return ActStatus::HALT;
+	}
+
+   	SessionContext* sessionCtxt = ue_ctxt->getSessionContext();
+	if( sessionCtxt == NULL )
+	{
+		log_msg(LOG_ERROR, "Failed to allocate Session Context for UE IDX %d\n", cb.getCBIndex());
+
+		return ActStatus::HALT;
+	}
+
+	BearerContext* bearerCtxt_p = sessionCtxt->getBearerContext();
+	if( bearerCtxt_p == NULL )
+	{
+		log_msg(LOG_ERROR, "Failed to allocate Bearer context for UE IDx %d\n", cb.getCBIndex());
+
+		return ActStatus::HALT;
+	}
+
+	struct CS_Q_msg cs_msg;
+	cs_msg.msg_type = create_session_request;
+	cs_msg.ue_idx = ue_ctxt->getContextID();
+	
+	const DigitRegister15& ueImsi = ue_ctxt->getImsi();
+	ueImsi.convertToBcdArray( cs_msg.IMSI );
+	
+	/*uint8_t  plmn_id[3] = {0};
+	memcpy(plmn_id, ue_ctxt->gettai().tai_m.plmn_id.idx, 3);
+	if ((plmn_id[1] & 0xF0) == 0xF0)
+		plmn_id[1] = plmn_id[1] & 0x0F;
+
+	const Apn_name &apnName = sessionCtxt->getaccessPtName();
+	std::string apnStr((const char *)apnName.apnname_m.val, apnName.apnname_m.len);
+
+	stringstream formattedApn;
+	formattedApn << apnStr  <<
+					 "\x6" << "mnc" <<
+					((plmn_id[1] & 0xF0) >> 4) <<
+					(plmn_id[2] & 0x0F) <<
+					((plmn_id[2] & 0xF0) >> 4) <<
+					"\x6" << "mcc" <<
+					(plmn_id[0] & 0x0F) <<
+					((plmn_id[0] & 0xF0) >> 4) <<
+					((plmn_id[1] & 0x0F)) <<
+					"\x4" << "gprs";
+
+	uint32_t formattedApnLen = formattedApn.str().length();
+	cs_msg.apn.len = formattedApnLen + 1;
+	cs_msg.apn.val[0] = apnStr.length();
+	memcpy(&cs_msg.apn.val[1], formattedApn.str().c_str(),
+	formattedApn.str().length()); */
+
+	const Apn_name &apnName = sessionCtxt->getAccessPtName();
+	memcpy(&(cs_msg.apn), &(apnName.apnname_m), sizeof(struct apn_name));
+	memcpy(&(cs_msg.tai), &(ue_ctxt->getTai().tai_m), sizeof(struct TAI));
+	memcpy(&(cs_msg.utran_cgi), &(ue_ctxt->getUtranCgi().cgi_m), sizeof(struct CGI));
+	memcpy(&(cs_msg.pco_options[0]), procCtxt->getPcoOptions(),sizeof(cs_msg.pco_options));
+
+	const AMBR& ambr = ue_ctxt->getAmbr().ambr_m;
+
+	cs_msg.max_requested_bw_dl = ambr.max_requested_bw_dl;
+	cs_msg.max_requested_bw_ul = ambr.max_requested_bw_ul;
+
+	memset(cs_msg.MSISDN, 0, BINARY_IMSI_LEN);
+	
+	const DigitRegister15& ueMSISDN = ue_ctxt->getMsisdn();
+	ueMSISDN.convertToBcdArray(cs_msg.MSISDN);
+
+	cmn::ipc::IpcAddress destAddr;
+	destAddr.u32 = TipcServiceInstance::s11AppInstanceNum_c;
+
+	mmeIpcIf_g->dispatchIpcMsg((char *) &cs_msg, sizeof(cs_msg), destAddr);
+
+	ProcedureStats::num_of_cs_req_to_sgw_sent ++;
+	log_msg(LOG_DEBUG, "Leaving cs_req_to_sgw \n");
+
+    	return ActStatus::PROCEED;
+}
+
+ActStatus ActionHandlers::process_cs_resp(SM::ControlBlock& cb)
+{
+	log_msg(LOG_DEBUG, "Entering handle_cs_resp \n");
+
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	if (ue_ctxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "handle_cs_resp: ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	SessionContext* sessionCtxt = ue_ctxt->getSessionContext();
+	if (sessionCtxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "handle_cs_resp: session ctxt is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	MsgBuffer* msgBuf = static_cast<MsgBuffer*>(cb.getMsgData());
+
+	if (msgBuf == NULL)
+		return ActStatus::HALT;
+
+	const gtp_incoming_msg_data_t* gtp_msg_data= static_cast<const gtp_incoming_msg_data_t*>(msgBuf->getDataPointer());
+	const struct csr_Q_msg& csr_info = gtp_msg_data->msg_data.csr_Q_msg_m;
+
+	BearerContext* bearerCtxt = sessionCtxt->getBearerContext();
+	if( bearerCtxt == NULL )
+	{
+		log_msg(LOG_ERROR, "Failed to retrive Bearer context for UE IDx %d\n", cb.getCBIndex());
+
+		return ActStatus::HALT;
+	}
+
+	sessionCtxt->setS11SgwCtrlFteid(Fteid(csr_info.s11_sgw_fteid));
+	sessionCtxt->setS5S8PgwCtrlFteid(Fteid(csr_info.s5s8_pgwc_fteid));
+
+	bearerCtxt->setS1uSgwUserFteid(Fteid(csr_info.s1u_sgw_fteid));
+	bearerCtxt->setS5S8PgwUserFteid(Fteid(csr_info.s5s8_pgwu_fteid));
+
+	sessionCtxt->setPdnAddr(Paa(csr_info.pdn_addr));
+		
+	ProcedureStats::num_of_processed_cs_resp ++;
+	log_msg(LOG_DEBUG, "Leaving handle_cs_resp \n");
+	
+	return ActStatus::PROCEED;
+}
+
+ActStatus ActionHandlers::send_init_ctxt_req_to_ue(SM::ControlBlock& cb)
+{
+	log_msg(LOG_DEBUG, "Inside send_init_ctxt_req_to_ue \n");
+
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	if (ue_ctxt == NULL )
+	{
+		log_msg(LOG_DEBUG, "send_init_ctxt_req_to_ue: ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	MmeProcedureCtxt* procedure_p = dynamic_cast<MmeProcedureCtxt*>(cb.getTempDataBlock());
+	if (procedure_p == NULL)
+	{
+		log_msg(LOG_DEBUG, "send_init_ctxt_req_to_ue: procedure context is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	if (procedure_p->getAttachType() == imsiAttach_c ||
+			procedure_p->getAttachType() == unknownGutiAttach_c)
+	{
+		uint32_t mTmsi = MmeCommonUtils::allocateMtmsi();
+		if (mTmsi == 0)
+		{
+			log_msg(LOG_DEBUG, "send_init_ctxt_req_to_ue: Failed to allocate mTmsi \n");
+			return ActStatus::HALT;
+		}
+
+		ue_ctxt->setMtmsi(mTmsi);
+
+		// TODO: Should this be done here or attach_done method
+		SubsDataGroupManager::Instance()->addmTmsikey(mTmsi, ue_ctxt->getContextID());
+	}
+
+	SessionContext* sessionCtxt = ue_ctxt->getSessionContext();
+	if (sessionCtxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "send_init_ctxt_req_to_ue: session ctxt is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	unsigned int nas_count = 0;
+	E_UTRAN_sec_vector* secVect = const_cast<E_UTRAN_sec_vector*>(ue_ctxt->getAiaSecInfo().AiaSecInfo_mp);
+	secinfo& secInfo = const_cast<secinfo&>(ue_ctxt->getUeSecInfo().secinfo_m);
+
+	SecUtils::create_kenb_key(secVect->kasme.val, secInfo.kenb_key, nas_count);
+	
+	init_ctx_req_Q_msg icr_msg;
+	icr_msg.msg_type = init_ctxt_request;
+	icr_msg.ue_idx = ue_ctxt->getContextID();
+	icr_msg.enb_fd = ue_ctxt->getEnbFd();
+	icr_msg.enb_s1ap_ue_id = ue_ctxt->getS1apEnbUeId();
+
+	icr_msg.exg_max_dl_bitrate = (ue_ctxt->getAmbr().ambr_m).max_requested_bw_dl;
+	icr_msg.exg_max_ul_bitrate = (ue_ctxt->getAmbr().ambr_m).max_requested_bw_ul;
+	BearerContext* bearerCtxt = sessionCtxt->getBearerContext();
+	if( bearerCtxt == NULL )
+	{
+		log_msg(LOG_ERROR, "Failed to retrive Bearer context for UE IDx %d\n", cb.getCBIndex());
+
+		return ActStatus::HALT;
+	}
+
+	icr_msg.bearer_id = bearerCtxt->getBearerId();
+
+	icr_msg.dl_seq_no = ue_ctxt->getDwnLnkSeqNo();
+	memcpy(&(icr_msg.tai), &(ue_ctxt->getTai().tai_m), sizeof(struct TAI));
+	memcpy(&(icr_msg.gtp_teid), &(bearerCtxt->getS1uSgwUserFteid().fteid_m), sizeof(struct fteid));
+	memcpy(&(icr_msg.apn), &(sessionCtxt->getAccessPtName().apnname_m), sizeof(struct apn_name));
+	memcpy(&(icr_msg.pdn_addr), &(sessionCtxt->getPdnAddr().paa_m), sizeof(struct PAA));
+	memcpy(&(icr_msg.int_key), &((ue_ctxt->getUeSecInfo().secinfo_m).int_key),
+			NAS_INT_KEY_SIZE);
+	memcpy(&(icr_msg.sec_key), &((ue_ctxt->getUeSecInfo().secinfo_m).kenb_key),
+			KENB_SIZE);	
+	icr_msg.pti = sessionCtxt->getPti();
+        icr_msg.m_tmsi = ue_ctxt->getMtmsi();
+	ue_ctxt->setDwnLnkSeqNo(icr_msg.dl_seq_no+1);
+
+	cmn::ipc::IpcAddress destAddr;
+	destAddr.u32 = TipcServiceInstance::s1apAppInstanceNum_c;
+
+	mmeIpcIf_g->dispatchIpcMsg((char *) &icr_msg, sizeof(icr_msg), destAddr);
+	
+	ProcedureStats::num_of_init_ctxt_req_to_ue_sent ++;
+	log_msg(LOG_DEBUG, "Leaving send_init_ctxt_req_to_ue_v \n");
+		
+	return ActStatus::PROCEED;
+}
+
+ActStatus ActionHandlers::process_init_ctxt_resp(SM::ControlBlock& cb)
+{
+	log_msg(LOG_DEBUG, "Inside process_init_ctxt_resp \n");
+
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	MmeProcedureCtxt *procCtxt = dynamic_cast<MmeProcedureCtxt*>(cb.getTempDataBlock());
+
+	if (ue_ctxt == NULL || procCtxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "process_init_ctxt_resp: ue context or procedure ctxt is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	SessionContext* sessionCtxt = ue_ctxt->getSessionContext();
+	if (sessionCtxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "process_init_ctxt_resp: session ctxt is NULL \n");
+		return ActStatus::HALT;
+	}
+	
+	MsgBuffer* msgBuf = static_cast<MsgBuffer*>(cb.getMsgData());
+
+	if (msgBuf == NULL)
+		return ActStatus::HALT;
+
+	const s1_incoming_msg_data_t* s1_msg_data = static_cast<const s1_incoming_msg_data_t*>(msgBuf->getDataPointer());
+	const struct initctx_resp_Q_msg &ics_res =s1_msg_data->msg_data.initctx_resp_Q_msg_m;
+	
+	fteid S1uEnbUserFteid;
+	S1uEnbUserFteid.header.iface_type = 0;
+	S1uEnbUserFteid.header.v4 = 1;
+	S1uEnbUserFteid.header.teid_gre = ics_res.gtp_teid;
+	S1uEnbUserFteid.ip.ipv4 = *(struct in_addr*)&ics_res.transp_layer_addr;
+	
+	BearerContext* bearerCtxt = sessionCtxt->getBearerContext();
+	if (bearerCtxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "process_init_ctxt_resp: bearer ctxt is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	bearerCtxt->setS1uEnbUserFteid(Fteid(S1uEnbUserFteid));
+
+	ProcedureStats::num_of_processed_init_ctxt_resp ++;
+	log_msg(LOG_DEBUG, "Leaving process_init_ctxt_resp \n");
+	
+	return ActStatus::PROCEED;
+}
+
+ActStatus ActionHandlers::send_mb_req_to_sgw(SM::ControlBlock& cb)
+{
+	log_msg(LOG_DEBUG, "Inside send_mb_req_to_sgw \n");
+
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	if (ue_ctxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "send_mb_req_to_sgw: ue context or procedure ctxt is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	SessionContext* sessionCtxt = ue_ctxt->getSessionContext();
+	if (sessionCtxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "send_mb_req_to_sgw: session ctxt is NULL \n");
+		return ActStatus::HALT;
+	}
+	
+	struct MB_Q_msg mb_msg;
+	mb_msg.msg_type = modify_bearer_request;
+	mb_msg.ue_idx = ue_ctxt->getContextID();
+	
+	memset(mb_msg.indication, 0, S11_MB_INDICATION_FLAG_SIZE); /*TODO : future*/
+	BearerContext* bearerCtxt = sessionCtxt->getBearerContext();
+	if (bearerCtxt == NULL)
+	{
+		log_msg(LOG_DEBUG, "send_mb_req_to_sgw: bearer ctxt is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	mb_msg.bearer_id = bearerCtxt->getBearerId();
+
+	memcpy(&(mb_msg.s11_sgw_c_fteid), &(sessionCtxt->getS11SgwCtrlFteid().fteid_m),
+		sizeof(struct fteid));
+
+	memcpy(&(mb_msg.s1u_enb_fteid), &(bearerCtxt->getS1uEnbUserFteid().fteid_m),
+		sizeof(struct fteid));
+
+
+	cmn::ipc::IpcAddress destAddr;
+	destAddr.u32 = TipcServiceInstance::s11AppInstanceNum_c;
+
+	mmeIpcIf_g->dispatchIpcMsg((char *) &mb_msg, sizeof(mb_msg), destAddr);
+		
+	ProcedureStats::num_of_mb_req_to_sgw_sent ++;
+	log_msg(LOG_DEBUG, "Leaving send_mb_req_to_sgw \n");
+	
+	return ActStatus::PROCEED;
+
+}
+
+ActStatus ActionHandlers::process_attach_cmp_from_ue(SM::ControlBlock& cb)
+{	
+	log_msg(LOG_DEBUG, "Inside handle_attach_cmp_from_ue \n");
+
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	if (ue_ctxt == NULL)
+	{
+		log_msg(LOG_ERROR, "attach_done: ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	ue_ctxt->setUpLnkSeqNo(ue_ctxt->getUpLnkSeqNo()+1);
+
+	ProcedureStats::num_of_processed_attach_cmp_from_ue ++;
+	log_msg(LOG_DEBUG, "Leaving handle_attach_cmp_from_ue \n");
+	
+	return ActStatus::PROCEED;
+}
+
+ActStatus ActionHandlers::process_mb_resp(SM::ControlBlock& cb)
+{	
+	log_msg(LOG_DEBUG, "Inside handle_mb_resp \n");
+	ProcedureStats::num_of_processed_mb_resp ++;
+	return ActStatus::PROCEED;
+}
+
+ActStatus ActionHandlers::attach_done(SM::ControlBlock& cb)
+{	
+	log_msg(LOG_DEBUG, "Inside attach_done \n");
+	
+	UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
+	if (ue_ctxt == NULL)
+	{
+		log_msg(LOG_ERROR, "attach_done: ue context is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	MmContext* mmCtxt = ue_ctxt->getMmContext();
+	if (mmCtxt == NULL)
+	{
+		log_msg(LOG_ERROR, "attach_done: MMcontext is NULL \n");
+		return ActStatus::HALT;
+	}
+
+	mmCtxt->setMmState(EpsAttached);
+	
+	MmeContextManagerUtils::deallocateProcedureCtxt(cb, attach_c);
+
+	ProcedureStats::num_of_attach_done++;
+	ProcedureStats::num_of_subscribers_attached ++;
+
+	log_msg(LOG_DEBUG,"Leaving attach done\n");
+
+	return ActStatus::PROCEED;
+}
