module L1CTL_Test {
	import from GSM_Types all;
	import from Osmocom_Types all;
	import from LAPDm_RAW_PT all;
	import from LAPDm_Types all;

	type component dummy_CT {
		port LAPDm_PT LAPDM;
		var lapdm_CT lapdm_component;
	};

	function f_init() runs on dummy_CT {
		/* create the LAPDm component */
		lapdm_component := lapdm_CT.create;
		/* connect our own LAPDM port to the LAPDM Service Provider of the LAPDm component */
		connect(self:LAPDM, lapdm_component:LAPDM_SP);
		/* connect the LAPDm compoent's lower-side port to the system L1CTL port (which is internally
		 * connected to the Unix Domain Socket test port */
		map(lapdm_component:L1CTL, system:L1CTL);

		/* start the LAPDm parallel component calling it's local function LAPDmStart */
		lapdm_component.start(LAPDmStart());
	}

	/* master function establishing a dedicated radio channel (takes care of RACH/IMM.ASS handling) */
	function f_establish_dcch() runs on dummy_CT {
		var BCCH_tune_req tune_req := { arfcn := { false, 871 }, combined_ccch := true };
		var DCCH_establish_req est_req := { ra := 23 };

		LAPDM.send(tune_req);
		LAPDM.send(est_req);
		LAPDM.receive(DCCH_establish_res:?);
	}

	/* helper function releasing dedicated radio channel physically (no Um signaling!) */
	function f_release_dcch() runs on dummy_CT {
		var DCCH_release_req rel_req := {};
		LAPDM.send(rel_req);
	}

	template LAPDm_ph_data t_PH_DATA(template GsmSapi sapi, template boolean sacch, template LapdmFrame frame) := {
		sacch := sacch,
		sapi := sapi,
		lapdm := frame
	}
	/* template for a valid SABM frame */
	template LapdmFrame LAPDm_B_SABM(template GsmSapi sapi, octetstring payload)  := {
		ab := {
			addr := tr_LapdmAddr(sapi, false),
			ctrl := tr_LapdmCtrlSABM(true),
			len := lengthof(payload),
			m := false,
			el := 1,
			payload := payload
		}
	}

	/* template for a valid UA frame */
	template LapdmFrame tr_LAPDm_B_UA(template GsmSapi sapi, template octetstring payload)  := {
		ab := {
			addr := tr_LapdmAddr(sapi, false),
			ctrl := tr_LapdmCtrlUA(true),
			len := ?,
			m := false,
			el := 1,
			payload := payload
		}
	}

	/* template for a valid UA frame */
	template LapdmFrame LAPDm_B_UA(template GsmSapi sapi, octetstring payload)  := {
		ab := {
			addr := tr_LapdmAddr(sapi, false),
			ctrl := tr_LapdmCtrlUA(true),
			len := lengthof(payload),
			m := false,
			el := 1,
			payload := payload
		}
	}

	/* template for a valid UI frame */
	template LapdmFrame LAPDm_B_UI(template GsmSapi sapi, octetstring payload)  := {
		ab := {
			addr := tr_LapdmAddr(sapi, true),
			ctrl := tr_LapdmCtrlUI(false),
			len := lengthof(payload),
			m := false,
			el := 1,
			payload := payload
		}
	}

	template LapdmFrame t_nopayload(template GsmSapi sapi) := {
		ab := {
			addr := tr_LapdmAddr(sapi, true),
			ctrl := ?,
			len := 0,
			m := false,
			el := 1,
			payload := ''O
		}
	}

	template LapdmFrame LAPDm_B_DISC(template GsmSapi sapi) modifies t_nopayload := {
		ab := {
			ctrl := tr_LapdmCtrlDISC(true)
		}
	}

	template LapdmFrame LAPDm_B_RR(template GsmSapi sapi, template uint3_t nr) modifies t_nopayload := {
		ab := {
			ctrl := tr_LapdmCtrlRR(nr, false)
		}
	}


	function f_test_sabm_results_in_ua(uint8_t sapi, boolean use_sacch, octetstring payload) runs on dummy_CT return boolean {
		var LAPDm_ph_data phd;
		var boolean result := false;
		timer T := 5.0;

		f_establish_dcch();
		LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_SABM(sapi, payload)));
		log("====> expecting ", t_PH_DATA(sapi, use_sacch, LAPDm_B_UA(sapi, payload)));
		T.start
		alt {
			[] LAPDM.receive(t_PH_DATA(?, use_sacch, LAPDm_B_UA(sapi, payload))) { result := true; }
			[] LAPDM.receive(t_PH_DATA(?, use_sacch, ?)) -> value phd { log("Other msg on DCH: ", phd); repeat; }
			[] LAPDM.receive(t_PH_DATA(?, ?, ?)) -> value phd { log("Other PH-DATA: ", phd); repeat; }
			[] T.timeout { }
		}
		LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_RR(sapi, 0)));
		f_release_dcch();
		return result;
	}

	testcase TC_sabm_ua_dcch_sapi0() runs on dummy_CT {
		f_init();
		if (not f_test_sabm_results_in_ua(0, false, 'FEFE'O)) {
			setverdict(fail);
		}
		setverdict(pass);
	}

	testcase TC_sabm_ua_dcch_sapi0_nopayload() runs on dummy_CT {
		f_init();
		if (f_test_sabm_results_in_ua(0, false, ''O)) {
			setverdict(fail, "Initial SABM/UA must contain L3 payload but BTS accepts without");
		}
		setverdict(pass);
	}

	testcase TC_sabm_ua_dcch_sapi3() runs on dummy_CT {
		f_init();
		if (f_test_sabm_results_in_ua(3, false, 'FEFE'O)) {
			setverdict(fail, "Initial SABM/UA must be on SAPI0, but BTS accepts SAPI=3");
		}
		setverdict(pass);
	}

	testcase TC_sabm_ua_dcch_sapi4() runs on dummy_CT {
		f_init();
		if (f_test_sabm_results_in_ua(4, false, 'FEFE'O)) {
			setverdict(fail, "Initial SABM/UA must be on SAPI0, but BTS accepts SAPI=4");
		}
		setverdict(pass);
	}

	testcase TC_sabm_contention() runs on dummy_CT {
		var LAPDm_ph_data phd;
		const octetstring payload := '0102030405'O;
		const GsmSapi sapi := 0;
		const boolean use_sacch := false;
		timer T := 5.0;

		f_init();

		f_establish_dcch();
		/* first frame is our real SABM */
		LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_SABM(sapi, payload)));
		/* second frame is a SABM with different payload, which BTS has to ignore according to 8.4.1.4 */
		LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_SABM(sapi, 'ABCDEF'O)));
		log("====> expecting ", t_PH_DATA(sapi, use_sacch, LAPDm_B_UA(sapi, payload)));
		T.start
		alt {
			[] LAPDM.receive(t_PH_DATA(?, use_sacch, LAPDm_B_UA(sapi, payload))) { setverdict(pass); repeat; }
			[] LAPDM.receive(t_PH_DATA(?, use_sacch, tr_LAPDm_B_UA(sapi, ?))) {
				setverdict(fail, "Second SABM was responded to during contention resolution");
			}
			[] LAPDM.receive { repeat };
			[] T.timeout { }
		}
		f_release_dcch();
	}

	/* we test that a re-transmitted SABM with identical payload will result in the retransmission of a
	  * SABM. This is required during the contention resolution procedure as specified in 8.4.1.4 */
	testcase TC_sabm_retransmit() runs on dummy_CT {
		const octetstring payload := '00FEFEDEADBEEF'O;
		f_init();
		if (not f_test_sabm_results_in_ua(0, false, payload)) {
			setverdict(fail, "UA not received for first SABM");
		}
		if (not f_test_sabm_results_in_ua(0, false, payload)) {
			setverdict(fail, "UA not received for second SABM");
		}
		setverdict(pass);
	}

	testcase TC_foo() runs on dummy_CT {
		var LapdmFrame lf;
/*
		var LapdmFrame lf := valueof(LAPDm_B_UA(0, ''O));
		log("ENC UA: ", enc_LapdmFrame(lf));
		lf := valueof(LAPDm_B_UI(0, ''O));
		log("ENC UI B: ", enc_LapdmFrame(lf));
		log("ENC UI B: ", enc_LapdmFrameB(lf.b));

		log("DEC UI AF: ", dec_LapdmAddressField('03'O));
*/

		lf := valueof(LAPDm_B_RR(0, 0));
		log("ENC RR: ", enc_LapdmFrame(lf));

		lf := valueof(LAPDm_B_UA(0, ''O));
		log("ENC UA: ", enc_LapdmFrame(lf));

		lf := valueof(LAPDm_B_UI(0, ''O));
		log("ENC UI: ", enc_LapdmFrame(lf));

		log("DEC UI CU: ", dec_LapdmCtrlU('03'O));
		log("DEC UI CT: ", dec_LapdmCtrl('03'O));

		log("DEC UA: ", dec_LapdmFrameAB('017301'O));
		log("DEC UI: ", dec_LapdmFrameAB('030301'O));
		log("DEC I: ", dec_LapdmFrameAB('030001'O));
		log("DEC S: ", dec_LapdmFrameAB('030101'O));
		log("DEC: ", dec_LapdmFrameAB('030301'O));
		log("DEC: ", dec_LapdmFrameAB('0303012B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O));
	}

	control {
		execute(TC_foo());
		execute(TC_sabm_ua_dcch_sapi0());
/*
		execute(TC_sabm_ua_dcch_sapi0_nopayload());
		execute(TC_sabm_ua_dcch_sapi3());
		execute(TC_sabm_ua_dcch_sapi4());
		execute(TC_sabm_contention());
		execute(TC_sabm_retransmit());
*/
	}
}
