module BSSGP_Emulation {
	import from NS_Types all;
	import from NS_Emulation all;
	import from BSSGP_Types all;
	import from BSSGP_Helper_Functions all;
	import from IPL4asp_Types all;

	type record BssgpStatusIndication {
		Nsei		nsei,
		BssgpBvci	bvci,
		BvcState	state
	}

	template BssgpStatusIndication t_BssgpStsInd(template Nsei nsei, template BssgpBvci bvci, template BvcState state) := {
		nsei := nsei,
		bvci := bvci,
		state := state
	}

	type enumerated BvcState {
		BVC_S_BLOCKED,
		BVC_S_UNBLOCKED
	};

	/* port from our (internal) point of view */
	type port BSSGP_SP_PT message {
		in	BssgpPdu;
		out	BssgpPdu,
			NsStatusIndication,
			BssgpStatusIndication,
			ASP_Event;
	} with { extension "internal" };

	/* port from the user point of view */
	type port BSSGP_PT message {
		in	ASP_Event,
			NsStatusIndication,
			BssgpStatusIndication,
			BssgpPdu;
		out	BssgpPdu;
	} with { extension "internal" };

	function BssgpStart() runs on BSSGP_CT {
		f_init();
		f_ScanEvents();
	}

	private function f_init() runs on BSSGP_CT {
		/* Connect the UDP socket */
		f_change_state(BVC_S_BLOCKED);
	}

	type component BSSGP_CT {
		/* UDP port towards the bottom (IUT) */
		port NS_PT BSCP;
		/* NS-User SAP towards the user */
		port BSSGP_SP_PT BSSGP_SP;

		var boolean g_sgsn_role := true;
		var BvcState g_ptp_bvc_state := BVC_S_BLOCKED;
		timer g_T1 := 15.0;
		timer g_T2 := 60.0;
	}

	modulepar {
		Nsvci mp_nsei := 96;
		Nsvci mp_bvci := 196;
		BssgpCellId mp_cellid := { ra_id := { lai := { mcc_mnc := '234F04'H, lac := 200}, rac := 0 }, cell_id := 20960 };
	};

	function f_BnsUdReq(template BssgpPdu pdu, BssgpBvci bvci := mp_bvci) return NsUnitdataRequest {
		var NsUnitdataRequest udr := {
			bvci := bvci,
			nsei := mp_nsei,
			/* for some weird reason we get "Dynamic test case error: Text encoder: Encoding an
			 * unbound integer value." when trying to send the reocrd rather than the octetstring */
			//sdu := omit,
			//bssgp := valueof(pdu)
			sdu := f_BSSGP_compact_len(enc_BssgpPdu(valueof(pdu))),
			bssgp := omit
		}
		return udr;
	}

	function f_BnsUdInd(template BssgpPdu pdu, template BssgpBvci bvci := mp_bvci) return template NsUnitdataIndication {
		var template NsUnitdataIndication udi := {
			bvci := bvci,
			nsei := mp_nsei,
			sdu := *,
			bssgp := pdu
		}
		return udi;
	}

	private function f_change_state(BvcState new_state) runs on BSSGP_CT {
		log("BSSGP State Transition: ", g_ptp_bvc_state, " -> ", new_state);
		g_ptp_bvc_state := new_state;
		BSSGP_SP.send(t_BssgpStsInd(mp_nsei, mp_bvci, g_ptp_bvc_state));
	}

	private function f_sendReset() runs on BSSGP_CT {
		var BssgpPdu pdu := valueof(t_BVC_RESET(BSSGP_CAUSE_OM_INTERVENTION, mp_bvci, mp_cellid));
		log("PDU: ", pdu);
		log("ENC: ", enc_BssgpPdu(pdu));

		/* BVC-RESET is always sent via the SIGNALLING BVCI, see Table 5.4.1 */
		BSCP.send(f_BnsUdReq(pdu, 0));
		g_T2.start;
		//f_change_state(BVC_S_WAIT_RESET);
	}

	private function f_sendUnblock() runs on BSSGP_CT {
		BSCP.send(f_BnsUdReq(t_BVC_UNBLOCK(mp_bvci), 0));
		g_T1.start;
	}

	private function f_sendBlock(BssgpCause cause) runs on BSSGP_CT {
		BSCP.send(f_BnsUdReq(t_BVC_BLOCK(mp_bvci, cause), 0));
		g_T1.start;
	}

	private function f_sendStatus(BssgpCause cause, BssgpPdu pdu) runs on BSSGP_CT {
		/* FIXME: Make sure correct Signaling or PTP BVCI is used! */
		BSCP.send(f_BnsUdReq(t_BSSGP_STATUS({ t_BSSGP_IE_Cause(cause), t_BSSGP_IE_Bvci(mp_bvci), t_BSSGP_IE_PDU(pdu)})));
	}

	altstep as_allstate() runs on BSSGP_CT {
		var NsUnitdataIndication udi;
		var NsStatusIndication nsi;
		var ASP_Event evt;

		/* Respond to BLOCK for wrong NSVCI */
		[] BSCP.receive(f_BnsUdInd(t_BVC_BLOCK(?, ?), 0)) -> value udi {
			log("Rx BVC-BLOCK for unknown BVCI");
			f_sendStatus(BSSGP_CAUSE_BVCI_UNKNOWN, udi.bssgp);
		}

		/* Respond to RESET with correct BVCI/CellID */
		[] BSCP.receive(f_BnsUdInd(t_BVC_RESET(?, mp_bvci, mp_cellid), 0)) -> value udi {
			log("Rx BVC-RESET for Our BVCI=", mp_bvci);
			BSCP.send(f_BnsUdReq(t_BVC_RESET_ACK(mp_bvci, mp_cellid), 0));
			f_change_state(BVC_S_UNBLOCKED);
		}

		/* Respond to RESET for signalling BVCI 0 */
		[] BSCP.receive(f_BnsUdInd(t_BVC_RESET(?, 0, mp_cellid), 0)) -> value udi {
			log("Rx BVC-RESET for Signaling BVCI=0");
			BSCP.send(f_BnsUdReq(t_BVC_RESET_ACK(0, mp_cellid), 0));
		}

		/* Respond to RESET with wrong NSEI/NSVCI */
		[] BSCP.receive(f_BnsUdInd(t_BVC_RESET(?, ?, ?), 0)) -> value udi {
			log("Rx BVC-RESET for unknown BVCI");
			f_sendStatus(BSSGP_CAUSE_BVCI_UNKNOWN, udi.bssgp);
		}

		/* default case of handling unknown PDUs */
		[] BSCP.receive(f_BnsUdInd(?, ?)) -> value udi {
			log("Rx Unexpected BSSGP PDU ", udi.bssgp," in state ", g_ptp_bvc_state);
			f_sendStatus(BSSGP_CAUSE_PDU_NOT_COMPATIBLE_WITH_PROTOCOL_STATE, udi.bssgp);
		}
		/* Forwarding of ASP_Event and NsStatusIndication to user */
		[] BSCP.receive(ASP_Event:?) -> value evt { BSSGP_SP.send(evt); }
		[] BSCP.receive(NsStatusIndication:?) -> value nsi { 
			/* if we just became NS-unblocked, send a BCC-RESET */
			if (nsi.old_state != NSE_S_ALIVE_UNBLOCKED and nsi.new_state == NSE_S_ALIVE_UNBLOCKED) {
				if (g_sgsn_role == false) {
					f_sendReset();
				}
				/* Idea: We coudl send BVC-UNBLOCK here like some SGSN do */
			}
			BSSGP_SP.send(nsi);
		}
	}

	private function f_ScanEvents() runs on BSSGP_CT {
		var NsUnitdataIndication udi;
		var BssgpPdu bs_pdu;
		var default d;


		log("matching against ", t_BVC_RESET(?, mp_bvci, mp_cellid));

		d := activate(as_allstate());

		while (true) {
		if (g_ptp_bvc_state == BVC_S_BLOCKED) {
			alt {
				[] g_T1.timeout {
					f_sendUnblock();
				}
				[] BSCP.receive(f_BnsUdInd(t_BVC_UNBLOCK_ACK(mp_bvci))) {
					g_T1.stop;
					f_change_state(BVC_S_UNBLOCKED);
				}
			}
		} else if (g_ptp_bvc_state == BVC_S_UNBLOCKED) {
			alt {
				/* bogus unblock, just respond with ACK */
				[] BSCP.receive(f_BnsUdInd(t_BVC_UNBLOCK(mp_bvci), 0)) -> value udi {
					BSCP.send(f_BnsUdReq(t_BVC_UNBLOCK_ACK(mp_bvci), 0));
				}
				/* Respond to BLOCK with BLOCK-ACK + change state */
				[] BSCP.receive(f_BnsUdInd(t_BVC_BLOCK(mp_bvci, ?), 0)) -> value udi {
					BSCP.send(f_BnsUdReq(t_BVC_BLOCK_ACK(mp_bvci), 0));
					g_T1.stop;
					f_change_state(BVC_S_BLOCKED);
				}
				[] g_T1.timeout {
					f_sendBlock(BSSGP_CAUSE_OM_INTERVENTION);
				}
				[] BSCP.receive(f_BnsUdInd(t_BVC_BLOCK_ACK(mp_bvci), 0)) -> value udi {
					g_T1.stop;
					f_change_state(BVC_S_BLOCKED);
				}
				[] BSCP.receive(f_BnsUdInd(t_BVC_RESET_ACK(mp_bvci, mp_cellid), 0)) -> value udi {
					g_T2.stop;
					f_change_state(BVC_S_UNBLOCKED);
				}

				/* simply acknowledge all Flow Control Messages */
				[g_sgsn_role] BSCP.receive(f_BnsUdInd(t_BVC_FC_BVC)) {
					BSCP.send(f_BnsUdReq(t_BVC_FC_BVC_ACK));
				}
				[g_sgsn_role] BSCP.receive(f_BnsUdInd(t_BVC_FC_MS)) {
					BSCP.send(f_BnsUdReq(t_BVC_FC_MS_ACK));
				}

				/* BSSGP-UNITDATA PDUs from network to NS-UNITDATA.ind to user */
				[] BSCP.receive(f_BnsUdInd(tr_BSSGP_type(DL_UNITDATA))) -> value udi {
					BSSGP_SP.send(udi.bssgp);
				}
				[] BSCP.receive(f_BnsUdInd(tr_BSSGP_type(UL_UNITDATA))) -> value udi {
					BSSGP_SP.send(udi.bssgp);
				}
				/* pass virtually any PDU from user to NS-UNITDATA PDU on network */
				[] BSSGP_SP.receive(BssgpPdu:?) -> value bs_pdu {
					BSCP.send(f_BnsUdReq(bs_pdu));
				}

			}
		}

		} /* while */
		//deactivate(d);
	}
}
