add ipa ping/pong keepalive for OML/RSL links between bts and bsc

Patch-by: ewild, osmith
Related: OS#4070
Change-Id: I30e3bd601e55355aaf738ee2f2c44c1ec2c46c6a
Depends: (libosmo-abis) Ie453fdee8bfd7fc1a3f1ed67ef0331f0abb1d59b
diff --git a/src/e1_input_vty.c b/src/e1_input_vty.c
index a1943e6..8d89d04 100644
--- a/src/e1_input_vty.c
+++ b/src/e1_input_vty.c
@@ -38,6 +38,7 @@
 #include <osmocom/vty/telnet_interface.h>
 
 #include <osmocom/abis/e1_input.h>
+#include <osmocom/abis/ipa.h>
 
 /* CONFIG */
 
@@ -169,6 +170,47 @@
 	return set_keepalive_params(vty, atoi(argv[0]), 0, 0, 0);
 }
 
+#define IPA_KEEPALIVE_HELP "Enable IPA PING/PONG keep-alive\n"
+static int set_ipa_keepalive_params(struct vty *vty, int e1_nr, int interval, int wait_for_resp)
+{
+	struct e1inp_line *line = e1inp_line_find(e1_nr);
+
+	if (!line) {
+		vty_out(vty, "%% Line %d doesn't exist%s", e1_nr, VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	if (strcmp(line->driver->name, "ipa") != 0) {
+		vty_out(vty, "%% Line %d doesn't use the ipa driver%s", e1_nr, VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	TALLOC_FREE(line->ipa_kap);
+	if (interval) {
+		line->ipa_kap = talloc_zero(line, struct ipa_keepalive_params);
+		line->ipa_kap->wait_for_resp = wait_for_resp;
+		line->ipa_kap->interval = interval;
+	}
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_e1line_ipa_keepalive, cfg_e1_line_ipa_keepalive_cmd,
+	"e1_line <0-255> ipa-keepalive <1-300> <1-300>",
+	E1_LINE_HELP IPA_KEEPALIVE_HELP
+	"Idle interval in seconds before probes are sent\n"
+	"Time to wait for PONG response\n")
+{
+	return set_ipa_keepalive_params(vty, atoi(argv[0]), atoi(argv[1]), atoi(argv[2]));
+}
+
+DEFUN(cfg_e1line_no_ipa_keepalive, cfg_e1_line_no_ipa_keepalive_cmd,
+	"no e1_line <0-255> ipa-keepalive",
+	NO_STR E1_LINE_HELP IPA_KEEPALIVE_HELP)
+{
+	return set_ipa_keepalive_params(vty, atoi(argv[0]), 0, 0);
+}
+
 DEFUN(cfg_e1line_name, cfg_e1_line_name_cmd,
 	"e1_line <0-255> name .LINE",
 	E1_LINE_HELP "Set name for this line\n" "Human readable name\n")
@@ -242,7 +284,10 @@
 				line->keepalive_num_probes,
 				line->keepalive_probe_interval,
 				VTY_NEWLINE);
-
+		if (line->ipa_kap)
+			vty_out(vty, " e1_line %u ipa-keepalive %d %d%s", line->num,
+				line->ipa_kap->interval, line->ipa_kap->wait_for_resp,
+				VTY_NEWLINE);
 	}
 
 	const char *ipa_bind = e1inp_ipa_get_bind_addr();
@@ -398,6 +443,8 @@
 	install_element(L_E1INP_NODE, &cfg_e1_line_keepalive_cmd);
 	install_element(L_E1INP_NODE, &cfg_e1_line_keepalive_params_cmd);
 	install_element(L_E1INP_NODE, &cfg_e1_line_no_keepalive_cmd);
+	install_element(L_E1INP_NODE, &cfg_e1_line_ipa_keepalive_cmd);
+	install_element(L_E1INP_NODE, &cfg_e1_line_no_ipa_keepalive_cmd);
 
 	install_element(L_E1INP_NODE, &cfg_ipa_bind_cmd);