blob: fde05b3a9f20794cad8a4b2c3735a5950a3cf911 [file] [log] [blame]
Harald Welte8542cef2017-07-19 20:06:26 +02001module Osmocom_VTY_Functions {
2 import from TELNETasp_PortType all;
Stefan Sperlingcff13562018-11-13 15:24:06 +01003 import from Osmocom_Types all;
Harald Welte8542cef2017-07-19 20:06:26 +02004
Harald Welte553f6552018-01-24 18:50:53 +01005 modulepar {
6 charstring mp_prompt_prefix := "OpenBSC";
7 }
Harald Welte8542cef2017-07-19 20:06:26 +02008
Harald Welte553f6552018-01-24 18:50:53 +01009 const charstring VTY_VIEW_SUFFIX := "> ";
10 const charstring VTY_ENABLE_SUFFIX := "# ";
11 const charstring VTY_CFG_SUFFIX := "(*)";
12
13 template charstring t_vty_unknown := pattern "*% Unknown command.";
Harald Welte8542cef2017-07-19 20:06:26 +020014
15 /* configure prompts in TELNETasp module */
Harald Weltea2663252018-09-10 10:21:44 +020016 function f_vty_set_prompts(TELNETasp_PT pt, charstring prompt_prefix := mp_prompt_prefix) {
Harald Welte553f6552018-01-24 18:50:53 +010017 var ASP_TelnetDynamicConfig vty_prompt[3] := {
18 {
19 prompt := {
20 id := 1,
Harald Weltea2663252018-09-10 10:21:44 +020021 prompt := prompt_prefix & VTY_VIEW_SUFFIX,
Harald Welte553f6552018-01-24 18:50:53 +010022 has_wildcards := false
23 }
24 }, {
25 prompt := {
26 id := 2,
Harald Weltea2663252018-09-10 10:21:44 +020027 prompt := prompt_prefix & VTY_ENABLE_SUFFIX,
Harald Welte553f6552018-01-24 18:50:53 +010028 has_wildcards := false
29 }
30 }, {
31 prompt := {
32 id := 3,
Harald Weltea2663252018-09-10 10:21:44 +020033 prompt := prompt_prefix & VTY_CFG_SUFFIX,
Harald Welte553f6552018-01-24 18:50:53 +010034 has_wildcards := true
35 }
36 }
37 };
38
Harald Welte8542cef2017-07-19 20:06:26 +020039 /* set some configuration that isn't possible to express
40 * in the config file due to syntactic restrictions (Who invents config
41 * files that don't permit regular expressions? */
42 for (var integer i := 0; i < sizeof(vty_prompt); i:= i + 1) {
Harald Welte553f6552018-01-24 18:50:53 +010043 pt.send(vty_prompt[i]);
Harald Welte8542cef2017-07-19 20:06:26 +020044 }
45 }
46
47 /* wait for any of the permitted prompts; buffer + return all intermediate output */
48 function f_vty_wait_for_prompt(TELNETasp_PT pt) return charstring {
Harald Welte8542cef2017-07-19 20:06:26 +020049 var charstring rx, buf := "";
Stefan Sperling23b45972018-07-27 17:20:38 +020050 var integer fd;
Harald Welte8542cef2017-07-19 20:06:26 +020051 timer T := 2.0;
52
53 T.start;
54 alt {
Harald Weltea2663252018-09-10 10:21:44 +020055 [] pt.receive(pattern "\w+" & VTY_VIEW_SUFFIX) { };
56 [] pt.receive(pattern "\w+\# ") { };
Vadim Yanitskiyea247d52018-10-28 22:47:24 +070057 [] pt.receive(pattern "\w+\(*\)\# ") { };
Harald Welte553f6552018-01-24 18:50:53 +010058 [] pt.receive(t_vty_unknown) {
59 testcase.stop(fail, "VTY: Unknown Command");
60 };
Harald Welte8542cef2017-07-19 20:06:26 +020061 [] pt.receive(charstring:?) -> value rx { buf := buf & rx; repeat };
Stefan Sperling23b45972018-07-27 17:20:38 +020062 [] pt.receive(integer:?) -> value fd {
63 if (fd == -1) {
64 setverdict(fail, "VTY Telnet Connection Failure");
65 mtc.stop;
66 } else {
67 repeat; /* telnet connection succeeded */
68 }
69 }
Harald Welte553f6552018-01-24 18:50:53 +010070 [] T.timeout {
71 setverdict(fail, "VTY Timeout for prompt");
Daniel Willmanne4ff5372018-07-05 17:35:03 +020072 mtc.stop;
Harald Welte553f6552018-01-24 18:50:53 +010073 };
Harald Welte8542cef2017-07-19 20:06:26 +020074 }
75 T.stop;
76 return buf;
77 }
78
79 /* send a VTY command and obtain response until prompt is received */
80 function f_vty_transceive_ret(TELNETasp_PT pt, charstring tx) return charstring {
81 pt.send(tx);
82 return f_vty_wait_for_prompt(pt);
83 }
84
85 /* send a VTY command and obtain response until prompt is received */
86 function f_vty_transceive(TELNETasp_PT pt, charstring tx) {
Harald Welte930d0a72018-03-22 22:08:40 +010087 var charstring unused := f_vty_transceive_ret(pt, tx);
Harald Welte8542cef2017-07-19 20:06:26 +020088 }
89
90 type integer BtsNr (0..255);
91 type integer BtsTrxNr (0..255);
92 type integer BtsTimeslotNr (0..7);
Philipp Maierd0e64b02019-03-13 14:15:23 +010093 type integer MscNr (0..255);
Harald Welte8542cef2017-07-19 20:06:26 +020094
95 type charstring BtsGprsMode ("none", "gprs", "egrps");
96
97 /* enter the'confiugration' mode of the VTY */
98 function f_vty_enter_config(TELNETasp_PT pt) {
99 f_vty_transceive(pt, "configure terminal")
100 }
101
102 function f_vty_enter_cfg_network(TELNETasp_PT pt) {
103 f_vty_enter_config(pt);
104 f_vty_transceive(pt, "network")
105 }
106
107 function f_vty_enter_cfg_bts(TELNETasp_PT pt, BtsNr bts := 0) {
108 f_vty_enter_cfg_network(pt);
109 f_vty_transceive(pt, "bts " & int2str(bts));
110 }
111
112 function f_vty_enter_cfg_trx(TELNETasp_PT pt, BtsNr bts := 0, BtsTrxNr trx := 0) {
113 f_vty_enter_cfg_bts(pt, bts);
114 f_vty_transceive(pt, "trx " & int2str(trx));
115 }
116
117 function f_vty_enter_cfg_ts(TELNETasp_PT pt, BtsNr bts := 0, BtsTrxNr trx := 0, BtsTimeslotNr ts) {
118 f_vty_enter_cfg_trx(pt, bts, trx);
119 f_vty_transceive(pt, "timeslot " & int2str(ts));
120 }
121
Philipp Maierd0e64b02019-03-13 14:15:23 +0100122 function f_vty_enter_cfg_msc(TELNETasp_PT pt, MscNr msc := 0) {
123 f_vty_enter_config(pt);
124 f_vty_transceive(pt, "msc " & int2str(msc));
125 }
126
Harald Weltef640a012018-04-14 17:49:21 +0200127type record of charstring rof_charstring;
128function f_vty_config2(TELNETasp_PT pt, rof_charstring config_nodes, charstring cmd)
Harald Welte872ce172018-02-16 22:10:33 +0100129{
130 /* enter config mode; enter node */
131 f_vty_enter_config(pt);
Harald Weltef640a012018-04-14 17:49:21 +0200132 for (var integer i := 0; i < sizeof(config_nodes); i := i+1) {
133 f_vty_transceive(pt, config_nodes[i]);
134 }
Harald Welte872ce172018-02-16 22:10:33 +0100135 /* execute command */
136 f_vty_transceive(pt, cmd);
137 /* leave config mode */
138 f_vty_transceive(pt, "end");
139}
140
141
Harald Weltef640a012018-04-14 17:49:21 +0200142function f_vty_config(TELNETasp_PT pt, charstring config_node, charstring cmd)
143{
144 f_vty_config2(pt, {config_node}, cmd);
145}
146
Alexander Couzens98aa59e2018-06-12 13:45:59 +0200147function f_vty_transceive_match(TELNETasp_PT pt, charstring cmd, template charstring exp_ret) {
148 var charstring ret := f_vty_transceive_ret(pt, cmd);
149 if (not match(ret, exp_ret)) {
150 setverdict(fail, "Non-matching VTY response: ", ret);
Daniel Willmanne4ff5372018-07-05 17:35:03 +0200151 mtc.stop;
Alexander Couzens98aa59e2018-06-12 13:45:59 +0200152 }
153}
154
Alexander Couzens1e6d9902018-06-12 13:48:26 +0200155function f_vty_transceive_not_match(TELNETasp_PT pt, charstring cmd, template charstring exp_ret) {
156 var charstring ret := f_vty_transceive_ret(pt, cmd);
157 if (match(ret, exp_ret)) {
158 setverdict(fail, "Unexpected matching VTY response: ", ret);
Daniel Willmanne4ff5372018-07-05 17:35:03 +0200159 mtc.stop;
Alexander Couzens1e6d9902018-06-12 13:48:26 +0200160 }
161}
162
Stefan Sperlingcff13562018-11-13 15:24:06 +0100163function f_vty_transceive_match_regex(TELNETasp_PT pt, charstring cmd, charstring regex, integer groupno) return charstring
164{
165 var charstring resp := f_vty_transceive_ret(pt, cmd);
166 return regexp(resp, regex, groupno);
167}
168
169function f_vty_transceive_match_regexp_retry(TELNETasp_PT pt, charstring cmd, charstring regex,
170 integer groupno, integer num_attempts, float retry_delay) return charstring
171{
172 while (num_attempts > 0) {
173 var charstring ret := f_vty_transceive_match_regex(pt, cmd, regex, groupno);
174 if (ret != "") {
175 return ret;
176 }
177 f_sleep(retry_delay);
178 num_attempts := num_attempts - 1;
179 }
180
181 setverdict(fail, "No matching VTY response for regular expression '", regex,
182 "' after ", num_attempts, " attempts." );
183 mtc.stop;
184}
Harald Weltef640a012018-04-14 17:49:21 +0200185
Harald Welte8542cef2017-07-19 20:06:26 +0200186}