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 * 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; } } }