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)  := {
		b := {
			addr := tr_LapdmAddr(sapi, false),
			ctrl := t_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)  := {
		b := {
			addr := tr_LapdmAddr(sapi, false),
			ctrl := t_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)  := {
		b := {
			addr := tr_LapdmAddr(sapi, false),
			ctrl := t_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)  := {
		b := {
			addr := tr_LapdmAddr(sapi, true),
			ctrl := t_LapdmCtrlUI(false),
			len := lengthof(payload),
			m := false,
			el := 1,
			payload := payload
		}
	}

	template LapdmFrame t_nopayload(template GsmSapi sapi) := {
		b := {
			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 := {
		b := {
			ctrl := t_LapdmCtrlDISC(true)
		}
	}

	template LapdmFrame LAPDm_B_RR(template GsmSapi sapi, template uint3_t nr) modifies t_nopayload := {
		b := {
			ctrl := t_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_LapdmFrameB('017301'O));
		log("DEC UI: ", dec_LapdmFrameA('030301'O));
		log("DEC I: ", dec_LapdmFrameA('030001'O));
		log("DEC S: ", dec_LapdmFrameA('030101'O));
		log("DEC: ", dec_LapdmFrameB('030301'O));
		log("DEC: ", dec_LapdmFrameB('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());
*/
	}
}
