module Osmocom_CTRL_Functions {

/* Definition of helper functions for the Osmocom CTRL interface.
 *
 * As opposed to many other parts of the Osmocom TTCN-3 code base, this module
 * implements blocking functions, instead of asynchronous functions.  The
 * rationale for this is simple: One normally wants to inquire a value or set
 * a value and not continue the main program until that operation is complete.
 * 
 * CTRL is a machine-type protocol on how external programs can interact with
 * an Osmocom program in a structured way.  It is intended for programmatic
 * access (by other software), as opposed to the VTY interface intended for
 * human consumption.
 *
 * (C) 2017 by Harald Welte <laforge@gnumonks.org>
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 */


	import from Osmocom_CTRL_Types all;
	import from IPA_Emulation all;

	private function f_gen_rand_id() return CtrlId {
		return int2str(float2int(rnd()*999999999.0));
	}

	/* perform a given GET Operation */
	function f_ctrl_get(IPA_CTRL_PT pt, CtrlVariable variable) return CtrlValue {
		timer T := 2.0;
		var CtrlMessage rx;
		var CtrlId id := f_gen_rand_id();
		pt.send(ts_CtrlMsgGet(id, variable));
		T.start;
		alt {
		[] pt.receive(tr_CtrlMsgGetRepl(id, variable)) -> value rx {
			}
		[] pt.receive(tr_CtrlMsgTrap) { repeat; }
		[] pt.receive(tr_CtrlMsgError) -> value rx {
			setverdict(fail, "Error in CTRL GET ", variable, ": ", rx.err.reason);
			mtc.stop;
			return "FAIL";
			}
		[] T.timeout {
			setverdict(fail, "Timeout waiting for CTRL GET REPLY ", variable);
			mtc.stop;
			return "TIMEOUT";
			}
		}
		return rx.resp.val;
	}

	/* perform a given SET Operation */
	function f_ctrl_set(IPA_CTRL_PT pt, CtrlVariable variable, CtrlValue val) {
		timer T := 2.0;
		var CtrlMessage rx;
		var CtrlId id := f_gen_rand_id();
		pt.send(ts_CtrlMsgSet(id, variable, val));
		T.start;
		alt {
		[] pt.receive(tr_CtrlMsgSetRepl(id, variable, val)) { }
		[] pt.receive(tr_CtrlMsgTrap) { repeat; }
		[] pt.receive(tr_CtrlMsgError) -> value rx {
			setverdict(fail, "Error in CTRL GET ", variable, ": ", rx.err.reason);
			mtc.stop;
			}
		[] T.timeout {
			setverdict(fail, "Timeout waiting for CTRL SET REPLY ", variable);
			mtc.stop;
			}
		}
	}

	/* Expect a matching TRAP */
	function f_ctrl_exp_trap(IPA_CTRL_PT pt, template CtrlVariable variable,
				 template CtrlValue val := ?) return CtrlValue {
		timer T := 2.0;
		var CtrlMessage rx;
		T.start;
		alt {
		[] pt.receive(tr_CtrlMsgTrap(variable, val)) -> value rx {
			}
		[] T.timeout {
			setverdict(fail, "Timeout waiting for TRAP ", variable);
			mtc.stop;
			return "TIMEOUT";
			}
		}
		return rx.trap.val;
	}

	/* Expect a matching GET result */
	function f_ctrl_get_exp(IPA_CTRL_PT pt, CtrlVariable variable, template CtrlValue exp) {
		var charstring ctrl_resp;
		ctrl_resp := f_ctrl_get(pt, variable);
		if (not match(ctrl_resp, exp)) {
			setverdict(fail, "Unexpected " & variable & ":" & ctrl_resp);
			mtc.stop;
		}
	}

	template charstring ts_ctrl_ratectr(CtrlVariable grp, integer instance, CtrlVariable name,
					    CtrlVariable kind := "abs") :=
		"rate_ctr." & kind & "." & grp & "." & int2str(instance) & "." & name;

	function f_ctrl_get_ratectr_abs(IPA_CTRL_PT pt, CtrlVariable grp, integer instance,
					CtrlVariable name) return integer {
		return str2int(f_ctrl_get(pt, valueof(ts_ctrl_ratectr(grp, instance, name))));
	}

	function f_ctrl_get_exp_ratectr_abs(IPA_CTRL_PT pt, CtrlVariable grp, integer instance,
					    CtrlVariable name, template integer exp) {
		var charstring ctrl_resp;
		var CtrlVariable variable := valueof(ts_ctrl_ratectr(grp, instance, name));
		ctrl_resp := f_ctrl_get(pt, variable);
		if (not match(str2int(ctrl_resp), exp)) {
			setverdict(fail, variable & " value " & ctrl_resp & " didn't match ", exp);
			mtc.stop;
		}
	}


}
