/* Process model C form file: sgsnSignallingProcedure.pr.c */
/* Portions of this file copyright 1986-2010 by OPNET Technologies, Inc. */


/*
 =========================== NOTE ==========================
 This file is automatically generated from sgsnSignallingProcedure.pr.m
 during a process model compilation.

 Do NOT manually edit this file.
 Manual edits will be lost during the next compilation.
 =========================== NOTE ==========================
*/



/* This variable carries the header into the object file */
const char sgsnSignallingProcedure_pr_c [] = "MIL_3_Tfile_Hdr_ 160A 30A op_runsim_dev 7 516D14F6 516D14F6 1 esl2-10 skathire 0 0 none none 0 0 none 0 0 0 0 0 0 0 0 2871 6                                                                                                                                                                                                                                                                                                                                                                                                   ";
#include <string.h>



/* OPNET system definitions */
#include <opnet.h>



/* Header Block */

#include "gtp.h"

#define ATTACH_RCV_IN_STRM_FROM_MS 0
#define DETACH_RCV_IN_STRM_FROM_MS 1
#define ACTIVATION_RCV_IN_STRM_FROM_MS 2
#define DEACTIVATION_RCV_IN_STRM_FROM_MS 3
#define ATTACH_XMT_OUT_STRM_TO_MS 0
#define DETACH_XMT_OUT_STRM_TO_MS 1
#define ACTIVATION_XMT_OUT_STRM_TO_MS 2
#define DEACTIVATION_XMT_OUT_STRM_TO_MS 3
#define GGSN_RCV_IN_STRM 4
#define GGSN_XMT_OUT_STRM 4

#define ATTACH_REQUEST 0x01
#define ATTACH_COMPLETE 0x03

#define MAX_SUPPORTED_MS 1000
#define MS_STATUS_DETACHED 0
#define MS_STATUS_ATTACHED 1
#define MS_STATUS_ACTIVATED 2

/* transition macros */
#define ATTACH_FROM_MS (op_intrpt_type () == \
OPC_INTRPT_STRM && op_intrpt_strm () == ATTACH_RCV_IN_STRM_FROM_MS)

#define DETACH_FROM_MS (op_intrpt_type () == \
OPC_INTRPT_STRM && op_intrpt_strm () == DETACH_RCV_IN_STRM_FROM_MS)

#define ACTIVATION_FROM_MS (op_intrpt_type () == \
OPC_INTRPT_STRM && op_intrpt_strm () == ACTIVATION_RCV_IN_STRM_FROM_MS)

#define DEACTIVATION_FROM_MS (op_intrpt_type () == \
OPC_INTRPT_STRM && op_intrpt_strm () == DEACTIVATION_RCV_IN_STRM_FROM_MS)

#define RECEIVE_FROM_GGSN (op_intrpt_type () == \
OPC_INTRPT_STRM && op_intrpt_strm () == GGSN_RCV_IN_STRM)

/* End of Header Block */

#if !defined (VOSD_NO_FIN)
#undef	BIN
#undef	BOUT
#define	BIN		FIN_LOCAL_FIELD(_op_last_line_passed) = __LINE__ - _op_block_origin;
#define	BOUT	BIN
#define	BINIT	FIN_LOCAL_FIELD(_op_last_line_passed) = 0; _op_block_origin = __LINE__;
#else
#define	BINIT
#endif /* #if !defined (VOSD_NO_FIN) */



/* State variable definitions */
typedef struct
	{
	/* Internal state tracking for FSM */
	FSM_SYS_STATE
	/* State Variables */
	int	                    		msStatus[1000]                                  ;	/* Stores the current status of the MS */
	                        		                                                	/* 0 - detached                        */
	                        		                                                	/* 1 - attached                        */
	                        		                                                	/* 2 - activated                       */
	char	                   		debugStr[1000]                                  ;
	Stathandle	             		numOfAttachReqRcvd                              ;
	Stathandle	             		numOfAttachAcceptSent                           ;
	Stathandle	             		numOfAttachCompleteRcvd                         ;
	Stathandle	             		numOfAttachRejectSent                           ;
	Stathandle	             		numOfDetachReqRcvd                              ;
	Stathandle	             		numOfDetachAcceptSent                           ;
	Stathandle	             		numOfActivatePDPContextReqRcvd                  ;
	Stathandle	             		numOfActivatePDPContextAcceptSent               ;
	Stathandle	             		numOfActivatePDPContextRejectSent               ;
	Stathandle	             		numOfDeactivatePDPContextReqRcvd                ;
	Stathandle	             		numOfDeactivatePDPContextAcceptSent             ;
	int	                    		attachRequestCounter                            ;
	int	                    		attachAcceptCounter                             ;
	int	                    		attachCompleteCounter                           ;
	int	                    		detachRequestCounter                            ;
	int	                    		detachAcceptCounter                             ;
	int	                    		activatePDPContextRequestCounter                ;
	int	                    		activatePDPContextAcceptCounter                 ;
	int	                    		attachRejectCounter                             ;
	int	                    		activatePDPContextRejectCounter                 ;
	int	                    		deactivatePDPContextRequestCounter              ;
	int	                    		deactivatePDPContextAcceptCounter               ;
	Stathandle	             		numOfCreatePDPContextResponseRcvd               ;
	Stathandle	             		numOfCreatePDPContextRequestSent                ;
	int	                    		createPDPContextRequestCounter                  ;
	int	                    		createPDPContextResponseCounter                 ;
	} sgsnSignallingProcedure_state;

#define msStatus                		op_sv_ptr->msStatus
#define debugStr                		op_sv_ptr->debugStr
#define numOfAttachReqRcvd      		op_sv_ptr->numOfAttachReqRcvd
#define numOfAttachAcceptSent   		op_sv_ptr->numOfAttachAcceptSent
#define numOfAttachCompleteRcvd 		op_sv_ptr->numOfAttachCompleteRcvd
#define numOfAttachRejectSent   		op_sv_ptr->numOfAttachRejectSent
#define numOfDetachReqRcvd      		op_sv_ptr->numOfDetachReqRcvd
#define numOfDetachAcceptSent   		op_sv_ptr->numOfDetachAcceptSent
#define numOfActivatePDPContextReqRcvd		op_sv_ptr->numOfActivatePDPContextReqRcvd
#define numOfActivatePDPContextAcceptSent		op_sv_ptr->numOfActivatePDPContextAcceptSent
#define numOfActivatePDPContextRejectSent		op_sv_ptr->numOfActivatePDPContextRejectSent
#define numOfDeactivatePDPContextReqRcvd		op_sv_ptr->numOfDeactivatePDPContextReqRcvd
#define numOfDeactivatePDPContextAcceptSent		op_sv_ptr->numOfDeactivatePDPContextAcceptSent
#define attachRequestCounter    		op_sv_ptr->attachRequestCounter
#define attachAcceptCounter     		op_sv_ptr->attachAcceptCounter
#define attachCompleteCounter   		op_sv_ptr->attachCompleteCounter
#define detachRequestCounter    		op_sv_ptr->detachRequestCounter
#define detachAcceptCounter     		op_sv_ptr->detachAcceptCounter
#define activatePDPContextRequestCounter		op_sv_ptr->activatePDPContextRequestCounter
#define activatePDPContextAcceptCounter		op_sv_ptr->activatePDPContextAcceptCounter
#define attachRejectCounter     		op_sv_ptr->attachRejectCounter
#define activatePDPContextRejectCounter		op_sv_ptr->activatePDPContextRejectCounter
#define deactivatePDPContextRequestCounter		op_sv_ptr->deactivatePDPContextRequestCounter
#define deactivatePDPContextAcceptCounter		op_sv_ptr->deactivatePDPContextAcceptCounter
#define numOfCreatePDPContextResponseRcvd		op_sv_ptr->numOfCreatePDPContextResponseRcvd
#define numOfCreatePDPContextRequestSent		op_sv_ptr->numOfCreatePDPContextRequestSent
#define createPDPContextRequestCounter		op_sv_ptr->createPDPContextRequestCounter
#define createPDPContextResponseCounter		op_sv_ptr->createPDPContextResponseCounter

/* These macro definitions will define a local variable called	*/
/* "op_sv_ptr" in each function containing a FIN statement.	*/
/* This variable points to the state variable data structure,	*/
/* and can be used from a C debugger to display their values.	*/
#undef FIN_PREAMBLE_DEC
#undef FIN_PREAMBLE_CODE
#define FIN_PREAMBLE_DEC	sgsnSignallingProcedure_state *op_sv_ptr;
#define FIN_PREAMBLE_CODE	\
		op_sv_ptr = ((sgsnSignallingProcedure_state *)(OP_SIM_CONTEXT_PTR->_op_mod_state_ptr));


/* No Function Block */

#if !defined (VOSD_NO_FIN)
enum { _op_block_origin = __LINE__ };
#endif

/* Undefine optional tracing in FIN/FOUT/FRET */
/* The FSM has its own tracing code and the other */
/* functions should not have any tracing.		  */
#undef FIN_TRACING
#define FIN_TRACING

#undef FOUTRET_TRACING
#define FOUTRET_TRACING

#if defined (__cplusplus)
extern "C" {
#endif
	void sgsnSignallingProcedure (OP_SIM_CONTEXT_ARG_OPT);
	VosT_Obtype _op_sgsnSignallingProcedure_init (int * init_block_ptr);
	void _op_sgsnSignallingProcedure_diag (OP_SIM_CONTEXT_ARG_OPT);
	void _op_sgsnSignallingProcedure_terminate (OP_SIM_CONTEXT_ARG_OPT);
	VosT_Address _op_sgsnSignallingProcedure_alloc (VosT_Obtype, int);
	void _op_sgsnSignallingProcedure_svar (void *, const char *, void **);


#if defined (__cplusplus)
} /* end of 'extern "C"' */
#endif




/* Process model interrupt handling procedure */


void
sgsnSignallingProcedure (OP_SIM_CONTEXT_ARG_OPT)
	{
#if !defined (VOSD_NO_FIN)
	int _op_block_origin = 0;
#endif
	FIN_MT (sgsnSignallingProcedure ());

		{
		/* Temporary Variables */
		Packet *pkptr;
		/* End of Temporary Variables */


		FSM_ENTER ("sgsnSignallingProcedure")

		FSM_BLOCK_SWITCH
			{
			/*---------------------------------------------------------*/
			/** state (init) enter executives **/
			FSM_STATE_ENTER_FORCED_NOLABEL (0, "init", "sgsnSignallingProcedure [init enter execs]")
				FSM_PROFILE_SECTION_IN ("sgsnSignallingProcedure [init enter execs]", state0_enter_exec)
				{
				// initialize the msStatus state variable
				int i;
				
				for (i=0; i < MAX_SUPPORTED_MS; i++)
					{
					    msStatus[i] = MS_STATUS_DETACHED;
					}
				
				numOfAttachReqRcvd = op_stat_reg ("Num of Attach Request Received",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				numOfAttachAcceptSent = op_stat_reg ("Num of Attach Accept Sent",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				numOfAttachCompleteRcvd = op_stat_reg ("Num of Attach Complete Received",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				numOfAttachRejectSent = op_stat_reg ("Num of Attach Reject Sent",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				
				numOfDetachReqRcvd = op_stat_reg ("Num of Detach Request Received",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				numOfDetachAcceptSent = op_stat_reg ("Num of Detach Accept Sent",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				
				numOfActivatePDPContextReqRcvd = op_stat_reg ("Num of Activate PDP Context Request Received",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				numOfActivatePDPContextAcceptSent = op_stat_reg ("Num of Activate PDP Context Accept Sent",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				numOfActivatePDPContextRejectSent = op_stat_reg ("Num of Activate PDP Context Reject Sent",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				
				numOfDeactivatePDPContextReqRcvd = op_stat_reg ("Num of Deactivate PDP Context Request Received",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				numOfDeactivatePDPContextAcceptSent = op_stat_reg ("Num of DeactivatePDP Context Accept Sent",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				
				numOfCreatePDPContextRequestSent = op_stat_reg ("Num of Create PDP Context Response Received",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				
				numOfCreatePDPContextResponseRcvd = op_stat_reg ("Num of Create PDP Context Response Received",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				
				// initialize the statistics counter
				attachRequestCounter = 0;
				attachAcceptCounter = 0;
				attachCompleteCounter = 0;
				attachRejectCounter = 0;
				detachRequestCounter = 0;
				detachAcceptCounter = 0;
				activatePDPContextRequestCounter = 0;
				activatePDPContextAcceptCounter = 0;
				activatePDPContextRejectCounter = 0;
				deactivatePDPContextRequestCounter = 0;
				deactivatePDPContextAcceptCounter = 0;
				createPDPContextRequestCounter = 0;
				createPDPContextResponseCounter = 0;
				}
				FSM_PROFILE_SECTION_OUT (state0_enter_exec)

			/** state (init) exit executives **/
			FSM_STATE_EXIT_FORCED (0, "init", "sgsnSignallingProcedure [init exit execs]")


			/** state (init) transition processing **/
			FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "init", "scheduler", "tr_17", "sgsnSignallingProcedure [init -> scheduler : default / ]")
				/*---------------------------------------------------------*/



			/** state (scheduler) enter executives **/
			FSM_STATE_ENTER_UNFORCED (1, "scheduler", state1_enter_exec, "sgsnSignallingProcedure [scheduler enter execs]")

			/** blocking after enter executives of unforced state. **/
			FSM_EXIT (3,"sgsnSignallingProcedure")


			/** state (scheduler) exit executives **/
			FSM_STATE_EXIT_UNFORCED (1, "scheduler", "sgsnSignallingProcedure [scheduler exit execs]")


			/** state (scheduler) transition processing **/
			FSM_PROFILE_SECTION_IN ("sgsnSignallingProcedure [scheduler trans conditions]", state1_trans_conds)
			FSM_INIT_COND (ATTACH_FROM_MS)
			FSM_TEST_COND (ACTIVATION_FROM_MS)
			FSM_TEST_COND (DEACTIVATION_FROM_MS)
			FSM_TEST_COND (DETACH_FROM_MS)
			FSM_TEST_COND (RECEIVE_FROM_GGSN)
			FSM_DFLT_COND
			FSM_TEST_LOGIC ("scheduler")
			FSM_PROFILE_SECTION_OUT (state1_trans_conds)

			FSM_TRANSIT_SWITCH
				{
				FSM_CASE_TRANSIT (0, 2, state2_enter_exec, ;, "ATTACH_FROM_MS", "", "scheduler", "attachMsgRcvFromMS", "tr_0", "sgsnSignallingProcedure [scheduler -> attachMsgRcvFromMS : ATTACH_FROM_MS / ]")
				FSM_CASE_TRANSIT (1, 3, state3_enter_exec, ;, "ACTIVATION_FROM_MS", "", "scheduler", "activationMsgRcvFromMS", "tr_4", "sgsnSignallingProcedure [scheduler -> activationMsgRcvFromMS : ACTIVATION_FROM_MS / ]")
				FSM_CASE_TRANSIT (2, 4, state4_enter_exec, ;, "DEACTIVATION_FROM_MS", "", "scheduler", "deactivationMsgRcvFromMS", "tr_6", "sgsnSignallingProcedure [scheduler -> deactivationMsgRcvFromMS : DEACTIVATION_FROM_MS / ]")
				FSM_CASE_TRANSIT (3, 5, state5_enter_exec, ;, "DETACH_FROM_MS", "", "scheduler", "detachMsgRcvFromMS", "tr_8", "sgsnSignallingProcedure [scheduler -> detachMsgRcvFromMS : DETACH_FROM_MS / ]")
				FSM_CASE_TRANSIT (4, 6, state6_enter_exec, ;, "RECEIVE_FROM_GGSN", "", "scheduler", "ggsnMsgRcvd", "tr_25", "sgsnSignallingProcedure [scheduler -> ggsnMsgRcvd : RECEIVE_FROM_GGSN / ]")
				FSM_CASE_TRANSIT (5, 1, state1_enter_exec, ;, "default", "", "scheduler", "scheduler", "tr_21", "sgsnSignallingProcedure [scheduler -> scheduler : default / ]")
				}
				/*---------------------------------------------------------*/



			/** state (attachMsgRcvFromMS) enter executives **/
			FSM_STATE_ENTER_FORCED (2, "attachMsgRcvFromMS", state2_enter_exec, "sgsnSignallingProcedure [attachMsgRcvFromMS enter execs]")
				FSM_PROFILE_SECTION_IN ("sgsnSignallingProcedure [attachMsgRcvFromMS enter execs]", state2_enter_exec)
				{
				int messageType;
				double attachReqSentTime;
				int imsi;
				Packet * attachAcceptPkPtr;
				int ptmsi;
				pkptr = op_pk_get(ATTACH_RCV_IN_STRM_FROM_MS);
				// retrieve the message type of message sent by SGSN
				op_pk_nfd_get (pkptr, "messageType", &messageType);
				
				switch (messageType) {
				    case ATTACH_REQUEST:
				        // increment the number of attach request received
						attachRequestCounter++;
					    op_stat_write(numOfAttachReqRcvd, attachRequestCounter);
					
					    // retrieve the attach request sent time
					    op_pk_nfd_get (pkptr, "attachReqSentTime", &attachReqSentTime);
				        	
					    // retrieve the imsi from attach request
					    op_pk_nfd_get(pkptr, "imsi", &imsi);
					
				        // reply MS with AttachAccept
					    attachAcceptPkPtr = op_pk_create_fmt ("attachAccept");
					    // set allocated ptmsi
					    // which is same as the imsi of the MS
					    op_pk_nfd_set(attachAcceptPkPtr, "allocatedPTMSI", 
							imsi);
					    // set attach request set time
					    op_pk_nfd_set(attachAcceptPkPtr, "attachReqSentTime", 
							attachReqSentTime);
						
					    op_pk_send(attachAcceptPkPtr, ATTACH_XMT_OUT_STRM_TO_MS);
						
						// increment number of attach accept sent
						attachAcceptCounter++;
						op_stat_write(numOfAttachAcceptSent, attachAcceptCounter);
						
					    break;
				     case ATTACH_COMPLETE:
				        // retrieve the ptmsi of the ms
						op_pk_nfd_get(pkptr, "ptmsi", &ptmsi);
					    // change the status of the ms to attached
						msStatus[ptmsi] = MS_STATUS_ATTACHED;
				
						// increment the number of attach complete received
						attachCompleteCounter++;
					    op_stat_write(numOfAttachCompleteRcvd, attachCompleteCounter);
					    
						break;
					 default:
					    break;
					}
				op_pk_destroy(pkptr);
				}
				FSM_PROFILE_SECTION_OUT (state2_enter_exec)

			/** state (attachMsgRcvFromMS) exit executives **/
			FSM_STATE_EXIT_FORCED (2, "attachMsgRcvFromMS", "sgsnSignallingProcedure [attachMsgRcvFromMS exit execs]")


			/** state (attachMsgRcvFromMS) transition processing **/
			FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "attachMsgRcvFromMS", "scheduler", "tr_1", "sgsnSignallingProcedure [attachMsgRcvFromMS -> scheduler : default / ]")
				/*---------------------------------------------------------*/



			/** state (activationMsgRcvFromMS) enter executives **/
			FSM_STATE_ENTER_FORCED (3, "activationMsgRcvFromMS", state3_enter_exec, "sgsnSignallingProcedure [activationMsgRcvFromMS enter execs]")
				FSM_PROFILE_SECTION_IN ("sgsnSignallingProcedure [activationMsgRcvFromMS enter execs]", state3_enter_exec)
				{
				double activationReqSentTime;
				Packet * activatePDPContextAcceptPkPtr;
				Packet * createPDPContextRequestPkPtr;
				GTPEndUserAddress gtpEndUserAddress;
				int ptmsi;
				
				pkptr = op_pk_get(ACTIVATION_RCV_IN_STRM_FROM_MS);
				
				// increment the number of activate PDP context request received
				activatePDPContextRequestCounter++;
				op_stat_write(numOfActivatePDPContextReqRcvd, activatePDPContextRequestCounter);
				
				// retrieve the activation request sent time
				op_pk_nfd_get (pkptr, "activationReqSentTime", &activationReqSentTime);
				// retrieve the ptmsi of the ms
				op_pk_nfd_get(pkptr, "ptmsi", &ptmsi);
				// reply MS with activate PDP context accept
				activatePDPContextAcceptPkPtr = op_pk_create_fmt ("activatePDPContextAccept");
				// set activtion request set time
				op_pk_nfd_set(activatePDPContextAcceptPkPtr, "activationReqSentTime", 
				    activationReqSentTime);
				op_pk_send(activatePDPContextAcceptPkPtr, ACTIVATION_XMT_OUT_STRM_TO_MS);
				// change the status of the MS to activated
				msStatus[ptmsi] = MS_STATUS_ACTIVATED;
				
				// increment the number of activate PDP context accept sent
				activatePDPContextAcceptCounter++;
				op_stat_write(numOfActivatePDPContextAcceptSent, activatePDPContextAcceptCounter);
				
				// send CreatePDPContextRequest to GGSN
				createPDPContextRequestPkPtr = op_pk_create_fmt ("CreatePDPContextRequest");
				// set end user address
				gtpEndUserAddress.type = 128;
				gtpEndUserAddress.length = 6;
				gtpEndUserAddress.pdpOrganization = 17;
				gtpEndUserAddress.pdpType = 33;
				op_pk_nfd_set(createPDPContextRequestPkPtr, "endUserAddress", 
				    gtpEndUserAddress);
				op_pk_send(createPDPContextRequestPkPtr, GGSN_XMT_OUT_STRM);
				
				op_pk_destroy(pkptr);
				}
				FSM_PROFILE_SECTION_OUT (state3_enter_exec)

			/** state (activationMsgRcvFromMS) exit executives **/
			FSM_STATE_EXIT_FORCED (3, "activationMsgRcvFromMS", "sgsnSignallingProcedure [activationMsgRcvFromMS exit execs]")


			/** state (activationMsgRcvFromMS) transition processing **/
			FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "activationMsgRcvFromMS", "scheduler", "tr_5", "sgsnSignallingProcedure [activationMsgRcvFromMS -> scheduler : default / ]")
				/*---------------------------------------------------------*/



			/** state (deactivationMsgRcvFromMS) enter executives **/
			FSM_STATE_ENTER_FORCED (4, "deactivationMsgRcvFromMS", state4_enter_exec, "sgsnSignallingProcedure [deactivationMsgRcvFromMS enter execs]")
				FSM_PROFILE_SECTION_IN ("sgsnSignallingProcedure [deactivationMsgRcvFromMS enter execs]", state4_enter_exec)
				{
				double deactivationReqSentTime;
				Packet * deactivatePDPContextAcceptPkPtr;
				int ptmsi;
				
				pkptr = op_pk_get(DEACTIVATION_RCV_IN_STRM_FROM_MS);
				
				// increment the number of deactivate PDP context request received
				deactivatePDPContextRequestCounter++;
				op_stat_write(numOfDeactivatePDPContextReqRcvd, deactivatePDPContextRequestCounter);
				
				// retrieve the deactivation request sent time
				op_pk_nfd_get (pkptr, "deactivationReqSentTime", &deactivationReqSentTime);
				// retrieve the ptmsi of the ms
				op_pk_nfd_get(pkptr, "ptmsi", &ptmsi);
				// reply MS with deactivate PDP context accept
				deactivatePDPContextAcceptPkPtr = op_pk_create_fmt ("deactivatePDPContextAccept");
				// set deactivtion request set time
				op_pk_nfd_set(deactivatePDPContextAcceptPkPtr, "deactivationReqSentTime", 
				    deactivationReqSentTime);
				op_pk_send(deactivatePDPContextAcceptPkPtr, DEACTIVATION_XMT_OUT_STRM_TO_MS);
				// change the status of the MS to activated
				msStatus[ptmsi] = MS_STATUS_ATTACHED;
				
				// increment the number of deactivate PDP context accept sent
				deactivatePDPContextAcceptCounter++;
				op_stat_write(numOfDeactivatePDPContextAcceptSent, deactivatePDPContextAcceptCounter);
				
				op_pk_destroy(pkptr);
				}
				FSM_PROFILE_SECTION_OUT (state4_enter_exec)

			/** state (deactivationMsgRcvFromMS) exit executives **/
			FSM_STATE_EXIT_FORCED (4, "deactivationMsgRcvFromMS", "sgsnSignallingProcedure [deactivationMsgRcvFromMS exit execs]")


			/** state (deactivationMsgRcvFromMS) transition processing **/
			FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "deactivationMsgRcvFromMS", "scheduler", "tr_19", "sgsnSignallingProcedure [deactivationMsgRcvFromMS -> scheduler : default / ]")
				/*---------------------------------------------------------*/



			/** state (detachMsgRcvFromMS) enter executives **/
			FSM_STATE_ENTER_FORCED (5, "detachMsgRcvFromMS", state5_enter_exec, "sgsnSignallingProcedure [detachMsgRcvFromMS enter execs]")
				FSM_PROFILE_SECTION_IN ("sgsnSignallingProcedure [detachMsgRcvFromMS enter execs]", state5_enter_exec)
				{
				double detachReqSentTime;
				Packet * detachAcceptPkPtr;
				int ptmsi;
				
				pkptr = op_pk_get(DETACH_RCV_IN_STRM_FROM_MS);
				
				// increment the number of detach request received
				detachRequestCounter++;
				op_stat_write(numOfDetachReqRcvd, detachRequestCounter);
				
				// retrieve the detach request sent time
				op_pk_nfd_get (pkptr, "detachReqSentTime", &detachReqSentTime);
				// retrieve the ptmsi of the ms
				op_pk_nfd_get(pkptr, "ptmsi", &ptmsi);
				// reply MS with detach accept
				detachAcceptPkPtr = op_pk_create_fmt ("detachAccept");
				// set detach request set time
				op_pk_nfd_set(detachAcceptPkPtr, "detachReqSentTime", 
				    detachReqSentTime);
				sprintf (debugStr, "Detach Accept sent time %f", op_sim_time());
				//op_prg_odb_print_major ("Debug message for MS-SGSN", debugStr, OPC_NIL);
				
				op_pk_send(detachAcceptPkPtr, DETACH_XMT_OUT_STRM_TO_MS);
				// change the status of the MS to detached
				msStatus[ptmsi] = MS_STATUS_DETACHED;
				
				// increment the number of detach accept sent
				detachAcceptCounter++;
				op_stat_write(numOfDetachAcceptSent, detachAcceptCounter);
				
				op_pk_destroy(pkptr);
				}
				FSM_PROFILE_SECTION_OUT (state5_enter_exec)

			/** state (detachMsgRcvFromMS) exit executives **/
			FSM_STATE_EXIT_FORCED (5, "detachMsgRcvFromMS", "sgsnSignallingProcedure [detachMsgRcvFromMS exit execs]")


			/** state (detachMsgRcvFromMS) transition processing **/
			FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "detachMsgRcvFromMS", "scheduler", "tr_7", "sgsnSignallingProcedure [detachMsgRcvFromMS -> scheduler : default / ]")
				/*---------------------------------------------------------*/



			/** state (ggsnMsgRcvd) enter executives **/
			FSM_STATE_ENTER_FORCED (6, "ggsnMsgRcvd", state6_enter_exec, "sgsnSignallingProcedure [ggsnMsgRcvd enter execs]")
				FSM_PROFILE_SECTION_IN ("sgsnSignallingProcedure [ggsnMsgRcvd enter execs]", state6_enter_exec)
				{
				Packet * createPDPContextResponsePkPtr;
				
				pkptr = op_pk_get(GGSN_RCV_IN_STRM);
				
				// increment the number of Create PDP Context Response received
				createPDPContextResponseCounter++;
				op_stat_write(numOfCreatePDPContextResponseRcvd, createPDPContextResponseCounter);
				op_pk_destroy(pkptr);
				}
				FSM_PROFILE_SECTION_OUT (state6_enter_exec)

			/** state (ggsnMsgRcvd) exit executives **/
			FSM_STATE_EXIT_FORCED (6, "ggsnMsgRcvd", "sgsnSignallingProcedure [ggsnMsgRcvd exit execs]")


			/** state (ggsnMsgRcvd) transition processing **/
			FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "ggsnMsgRcvd", "scheduler", "tr_26", "sgsnSignallingProcedure [ggsnMsgRcvd -> scheduler : default / ]")
				/*---------------------------------------------------------*/



			}


		FSM_EXIT (0,"sgsnSignallingProcedure")
		}
	}




void
_op_sgsnSignallingProcedure_diag (OP_SIM_CONTEXT_ARG_OPT)
	{
	/* No Diagnostic Block */
	}




void
_op_sgsnSignallingProcedure_terminate (OP_SIM_CONTEXT_ARG_OPT)
	{

	FIN_MT (_op_sgsnSignallingProcedure_terminate ())


	/* No Termination Block */

	Vos_Poolmem_Dealloc (op_sv_ptr);

	FOUT
	}


/* Undefine shortcuts to state variables to avoid */
/* syntax error in direct access to fields of */
/* local variable prs_ptr in _op_sgsnSignallingProcedure_svar function. */
#undef msStatus
#undef debugStr
#undef numOfAttachReqRcvd
#undef numOfAttachAcceptSent
#undef numOfAttachCompleteRcvd
#undef numOfAttachRejectSent
#undef numOfDetachReqRcvd
#undef numOfDetachAcceptSent
#undef numOfActivatePDPContextReqRcvd
#undef numOfActivatePDPContextAcceptSent
#undef numOfActivatePDPContextRejectSent
#undef numOfDeactivatePDPContextReqRcvd
#undef numOfDeactivatePDPContextAcceptSent
#undef attachRequestCounter
#undef attachAcceptCounter
#undef attachCompleteCounter
#undef detachRequestCounter
#undef detachAcceptCounter
#undef activatePDPContextRequestCounter
#undef activatePDPContextAcceptCounter
#undef attachRejectCounter
#undef activatePDPContextRejectCounter
#undef deactivatePDPContextRequestCounter
#undef deactivatePDPContextAcceptCounter
#undef numOfCreatePDPContextResponseRcvd
#undef numOfCreatePDPContextRequestSent
#undef createPDPContextRequestCounter
#undef createPDPContextResponseCounter

#undef FIN_PREAMBLE_DEC
#undef FIN_PREAMBLE_CODE

#define FIN_PREAMBLE_DEC
#define FIN_PREAMBLE_CODE

VosT_Obtype
_op_sgsnSignallingProcedure_init (int * init_block_ptr)
	{
	VosT_Obtype obtype = OPC_NIL;
	FIN_MT (_op_sgsnSignallingProcedure_init (init_block_ptr))

	obtype = Vos_Define_Object_Prstate ("proc state vars (sgsnSignallingProcedure)",
		sizeof (sgsnSignallingProcedure_state));
	*init_block_ptr = 0;

	FRET (obtype)
	}

VosT_Address
_op_sgsnSignallingProcedure_alloc (VosT_Obtype obtype, int init_block)
	{
#if !defined (VOSD_NO_FIN)
	int _op_block_origin = 0;
#endif
	sgsnSignallingProcedure_state * ptr;
	FIN_MT (_op_sgsnSignallingProcedure_alloc (obtype))

	ptr = (sgsnSignallingProcedure_state *)Vos_Alloc_Object (obtype);
	if (ptr != OPC_NIL)
		{
		ptr->_op_current_block = init_block;
#if defined (OPD_ALLOW_ODB)
		ptr->_op_current_state = "sgsnSignallingProcedure [init enter execs]";
#endif
		}
	FRET ((VosT_Address)ptr)
	}



void
_op_sgsnSignallingProcedure_svar (void * gen_ptr, const char * var_name, void ** var_p_ptr)
	{
	sgsnSignallingProcedure_state		*prs_ptr;

	FIN_MT (_op_sgsnSignallingProcedure_svar (gen_ptr, var_name, var_p_ptr))

	if (var_name == OPC_NIL)
		{
		*var_p_ptr = (void *)OPC_NIL;
		FOUT
		}
	prs_ptr = (sgsnSignallingProcedure_state *)gen_ptr;

	if (strcmp ("msStatus" , var_name) == 0)
		{
		*var_p_ptr = (void *) (prs_ptr->msStatus);
		FOUT
		}
	if (strcmp ("debugStr" , var_name) == 0)
		{
		*var_p_ptr = (void *) (prs_ptr->debugStr);
		FOUT
		}
	if (strcmp ("numOfAttachReqRcvd" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->numOfAttachReqRcvd);
		FOUT
		}
	if (strcmp ("numOfAttachAcceptSent" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->numOfAttachAcceptSent);
		FOUT
		}
	if (strcmp ("numOfAttachCompleteRcvd" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->numOfAttachCompleteRcvd);
		FOUT
		}
	if (strcmp ("numOfAttachRejectSent" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->numOfAttachRejectSent);
		FOUT
		}
	if (strcmp ("numOfDetachReqRcvd" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->numOfDetachReqRcvd);
		FOUT
		}
	if (strcmp ("numOfDetachAcceptSent" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->numOfDetachAcceptSent);
		FOUT
		}
	if (strcmp ("numOfActivatePDPContextReqRcvd" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->numOfActivatePDPContextReqRcvd);
		FOUT
		}
	if (strcmp ("numOfActivatePDPContextAcceptSent" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->numOfActivatePDPContextAcceptSent);
		FOUT
		}
	if (strcmp ("numOfActivatePDPContextRejectSent" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->numOfActivatePDPContextRejectSent);
		FOUT
		}
	if (strcmp ("numOfDeactivatePDPContextReqRcvd" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->numOfDeactivatePDPContextReqRcvd);
		FOUT
		}
	if (strcmp ("numOfDeactivatePDPContextAcceptSent" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->numOfDeactivatePDPContextAcceptSent);
		FOUT
		}
	if (strcmp ("attachRequestCounter" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->attachRequestCounter);
		FOUT
		}
	if (strcmp ("attachAcceptCounter" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->attachAcceptCounter);
		FOUT
		}
	if (strcmp ("attachCompleteCounter" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->attachCompleteCounter);
		FOUT
		}
	if (strcmp ("detachRequestCounter" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->detachRequestCounter);
		FOUT
		}
	if (strcmp ("detachAcceptCounter" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->detachAcceptCounter);
		FOUT
		}
	if (strcmp ("activatePDPContextRequestCounter" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->activatePDPContextRequestCounter);
		FOUT
		}
	if (strcmp ("activatePDPContextAcceptCounter" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->activatePDPContextAcceptCounter);
		FOUT
		}
	if (strcmp ("attachRejectCounter" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->attachRejectCounter);
		FOUT
		}
	if (strcmp ("activatePDPContextRejectCounter" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->activatePDPContextRejectCounter);
		FOUT
		}
	if (strcmp ("deactivatePDPContextRequestCounter" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->deactivatePDPContextRequestCounter);
		FOUT
		}
	if (strcmp ("deactivatePDPContextAcceptCounter" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->deactivatePDPContextAcceptCounter);
		FOUT
		}
	if (strcmp ("numOfCreatePDPContextResponseRcvd" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->numOfCreatePDPContextResponseRcvd);
		FOUT
		}
	if (strcmp ("numOfCreatePDPContextRequestSent" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->numOfCreatePDPContextRequestSent);
		FOUT
		}
	if (strcmp ("createPDPContextRequestCounter" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->createPDPContextRequestCounter);
		FOUT
		}
	if (strcmp ("createPDPContextResponseCounter" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->createPDPContextResponseCounter);
		FOUT
		}
	*var_p_ptr = (void *)OPC_NIL;

	FOUT
	}

