<p>Harald Welte has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/13196">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Add IPA keep-alive FSM implementation<br><br>The IPA keep-alive FSM code takes care of periodically transmitting<br>and IPA CCM PING and expecting an IPA CCM PONG in return.<br><br>Change-Id: I2763da49a74de85046ac07d53592c89973314ca6<br>---<br>M include/osmocom/abis/ipa.h<br>M src/Makefile.am<br>A src/input/ipa_keepalive.c<br>3 files changed, 319 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmo-abis refs/changes/96/13196/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/abis/ipa.h b/include/osmocom/abis/ipa.h</span><br><span>index a738156..4f6081f 100644</span><br><span>--- a/include/osmocom/abis/ipa.h</span><br><span>+++ b/include/osmocom/abis/ipa.h</span><br><span>@@ -5,6 +5,7 @@</span><br><span> #include <osmocom/core/linuxlist.h></span><br><span> #include <osmocom/core/timer.h></span><br><span> #include <osmocom/core/select.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/fsm.h></span><br><span> #include <osmocom/gsm/ipa.h></span><br><span> </span><br><span> struct e1inp_line;</span><br><span>@@ -99,4 +100,39 @@</span><br><span> </span><br><span> void ipa_msg_push_header(struct msgb *msg, uint8_t proto);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/***********************************************************************</span><br><span style="color: hsl(120, 100%, 40%);">+ * IPA Keep-Alive FSM</span><br><span style="color: hsl(120, 100%, 40%);">+ ***********************************************************************/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! parameters describing the keep-alive FSM (timeouts). */</span><br><span style="color: hsl(120, 100%, 40%);">+struct ipa_keepalive_params {</span><br><span style="color: hsl(120, 100%, 40%);">+     /*! interval in which to send IPA CCM PING requests to the peer. */</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int interval;</span><br><span style="color: hsl(120, 100%, 40%);">+        /*! time to wait for an IPA CCM PONG in response to a IPA CCM PING before giving up. */</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int wait_for_resp;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+typedef void ipa_keepalive_timeout_cb_t(struct osmo_fsm_inst *fi, void *conn);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_fsm_inst *ipa_client_conn_alloc_keepalive_fsm(struct ipa_client_conn *client,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                          const struct ipa_keepalive_params *params,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                    const char *id);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_fsm_inst *ipa_server_conn_alloc_keepalive_fsm(struct ipa_server_conn *server,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                         const struct ipa_keepalive_params *params,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                    const char *id);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_fsm_inst *ipa_keepalive_alloc_server(struct ipa_server_conn *server,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                 const struct ipa_keepalive_params *params,</span><br><span style="color: hsl(120, 100%, 40%);">+                                            const char *id);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void ipa_keepalive_fsm_set_timeout_cb(struct osmo_fsm_inst *fi, ipa_keepalive_timeout_cb_t *cb);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void ipa_keepalive_fsm_start(struct osmo_fsm_inst *fi);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void ipa_keepalive_fsm_stop(struct osmo_fsm_inst *fi);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void ipa_keepalive_fsm_pong_received(struct osmo_fsm_inst *fi);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #endif</span><br><span>diff --git a/src/Makefile.am b/src/Makefile.am</span><br><span>index 9566617..2d2424d 100644</span><br><span>--- a/src/Makefile.am</span><br><span>+++ b/src/Makefile.am</span><br><span>@@ -21,6 +21,7 @@</span><br><span>                        trau_frame.c \</span><br><span>                       input/dahdi.c \</span><br><span>                      input/ipa.c \</span><br><span style="color: hsl(120, 100%, 40%);">+                         input/ipa_keepalive.c \</span><br><span>                      input/ipaccess.c \</span><br><span>                   input/lapd.c \</span><br><span>                       input/lapd_pcap.c \</span><br><span>diff --git a/src/input/ipa_keepalive.c b/src/input/ipa_keepalive.c</span><br><span>new file mode 100644</span><br><span>index 0000000..3158cb4</span><br><span>--- /dev/null</span><br><span>+++ b/src/input/ipa_keepalive.c</span><br><span>@@ -0,0 +1,282 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* IPA keep-alive FSM; Periodically transmit IPA_PING and expect IPA_PONG in return.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2019 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * SPDX-License-Identifier: GPL-2.0+</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License along</span><br><span style="color: hsl(120, 100%, 40%);">+ * with this program; if not, write to the Free Software Foundation, Inc.,</span><br><span style="color: hsl(120, 100%, 40%);">+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/fsm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/timer.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/msgb.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/protocol/ipaccess.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/abis/ipa.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define S(x)        (1 << (x))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* generate a msgb containing an IPA CCM PING message */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *gen_ipa_ping(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct msgb *msg = msgb_alloc_headroom(64, 32, "IPA PING");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!msg)</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        msgb_put_u8(msg, IPAC_MSGT_PING);</span><br><span style="color: hsl(120, 100%, 40%);">+     ipa_msg_push_header(msg, IPAC_PROTO_IPACCESS);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return msg;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum osmo_ipa_keepalive_state {</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_IPA_KA_S_INIT,</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_IPA_KA_S_IDLE,             /* waiting for next interval */</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_IPA_KA_S_WAIT_RESP,        /* waiting for response to keepalive */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum osmo_ipa_keepalive_event {</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_IPA_KA_E_START,</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_IPA_KA_E_STOP,</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_IPA_KA_E_PONG,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct value_string ipa_keepalive_event_names[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_VALUE_STRING(OSMO_IPA_KA_E_START),</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_VALUE_STRING(OSMO_IPA_KA_E_STOP),</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_VALUE_STRING(OSMO_IPA_KA_E_PONG),</span><br><span style="color: hsl(120, 100%, 40%);">+        { 0, NULL }</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct ipa_fsm_priv {</span><br><span style="color: hsl(120, 100%, 40%);">+      struct ipa_keepalive_params params;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ipa_server_conn *srv_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct ipa_client_conn *client_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+  ipa_keepalive_timeout_cb_t *timeout_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void ipa_ka_init(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ipa_fsm_priv *ifp = fi->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     switch (event) {</span><br><span style="color: hsl(120, 100%, 40%);">+      case OSMO_IPA_KA_E_START:</span><br><span style="color: hsl(120, 100%, 40%);">+             osmo_fsm_inst_state_chg(fi, OSMO_IPA_KA_S_WAIT_RESP, ifp->params.interval, 2);</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              OSMO_ASSERT(0);</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void ipa_ka_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      /* no permitted events aside from E_START, which is handled in allstate_events */</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void ipa_ka_wait_resp_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct ipa_fsm_priv *ifp = fi->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Send an IPA PING to the peer */</span><br><span style="color: hsl(120, 100%, 40%);">+    msg = gen_ipa_ping();</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (ifp->srv_conn)</span><br><span style="color: hsl(120, 100%, 40%);">+         ipa_server_conn_send(ifp->srv_conn, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  else {</span><br><span style="color: hsl(120, 100%, 40%);">+                OSMO_ASSERT(ifp->client_conn);</span><br><span style="color: hsl(120, 100%, 40%);">+             ipa_client_conn_send(ifp->client_conn, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void ipa_ka_wait_resp(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ipa_fsm_priv *ifp = fi->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     switch (event) {</span><br><span style="color: hsl(120, 100%, 40%);">+      case OSMO_IPA_KA_E_PONG:</span><br><span style="color: hsl(120, 100%, 40%);">+              osmo_fsm_inst_state_chg(fi, OSMO_IPA_KA_S_IDLE, ifp->params.wait_for_resp, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              OSMO_ASSERT(0);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int ipa_ka_fsm_timer_cb(struct osmo_fsm_inst *fi)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct ipa_fsm_priv *ifp = fi->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+       void *conn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (fi->T) {</span><br><span style="color: hsl(120, 100%, 40%);">+   case 1:</span><br><span style="color: hsl(120, 100%, 40%);">+               /* send another PING */</span><br><span style="color: hsl(120, 100%, 40%);">+               osmo_fsm_inst_state_chg(fi, OSMO_IPA_KA_S_WAIT_RESP, ifp->params.interval, 2);</span><br><span style="color: hsl(120, 100%, 40%);">+             return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     case 2:</span><br><span style="color: hsl(120, 100%, 40%);">+               /* PONG not received within time */</span><br><span style="color: hsl(120, 100%, 40%);">+           if (ifp->srv_conn)</span><br><span style="color: hsl(120, 100%, 40%);">+                 conn = ifp->srv_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+              else</span><br><span style="color: hsl(120, 100%, 40%);">+                  conn = ifp->client_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+           if (ifp->timeout_cb)</span><br><span style="color: hsl(120, 100%, 40%);">+                       ifp->timeout_cb(fi, conn);</span><br><span style="color: hsl(120, 100%, 40%);">+         /* ask fsm core to terminate us */</span><br><span style="color: hsl(120, 100%, 40%);">+            return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+     default:</span><br><span style="color: hsl(120, 100%, 40%);">+              OSMO_ASSERT(0);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void ipa_ka_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (event) {</span><br><span style="color: hsl(120, 100%, 40%);">+      case OSMO_IPA_KA_E_STOP:</span><br><span style="color: hsl(120, 100%, 40%);">+              osmo_fsm_inst_state_chg(fi, OSMO_IPA_KA_S_INIT, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              OSMO_ASSERT(0);</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct osmo_fsm_state ipa_keepalive_states[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ [OSMO_IPA_KA_S_INIT] = {</span><br><span style="color: hsl(120, 100%, 40%);">+              .name = "INIT",</span><br><span style="color: hsl(120, 100%, 40%);">+             .in_event_mask = S(OSMO_IPA_KA_E_START),</span><br><span style="color: hsl(120, 100%, 40%);">+              .out_state_mask = S(OSMO_IPA_KA_S_WAIT_RESP),</span><br><span style="color: hsl(120, 100%, 40%);">+         .action = ipa_ka_init,</span><br><span style="color: hsl(120, 100%, 40%);">+        },</span><br><span style="color: hsl(120, 100%, 40%);">+    [OSMO_IPA_KA_S_IDLE] = {</span><br><span style="color: hsl(120, 100%, 40%);">+              .name = "IDLE",</span><br><span style="color: hsl(120, 100%, 40%);">+             .out_state_mask = S(OSMO_IPA_KA_S_WAIT_RESP) | S(OSMO_IPA_KA_S_INIT),</span><br><span style="color: hsl(120, 100%, 40%);">+         .action = ipa_ka_idle,</span><br><span style="color: hsl(120, 100%, 40%);">+        },</span><br><span style="color: hsl(120, 100%, 40%);">+    [OSMO_IPA_KA_S_WAIT_RESP] = {</span><br><span style="color: hsl(120, 100%, 40%);">+         .name = "WAIT_RESP",</span><br><span style="color: hsl(120, 100%, 40%);">+                .in_event_mask = S(OSMO_IPA_KA_E_PONG),</span><br><span style="color: hsl(120, 100%, 40%);">+               .out_state_mask = S(OSMO_IPA_KA_S_IDLE) | S(OSMO_IPA_KA_S_INIT),</span><br><span style="color: hsl(120, 100%, 40%);">+              .action = ipa_ka_wait_resp,</span><br><span style="color: hsl(120, 100%, 40%);">+           .onenter = ipa_ka_wait_resp_onenter,</span><br><span style="color: hsl(120, 100%, 40%);">+  },</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct osmo_fsm ipa_keepalive_fsm = {</span><br><span style="color: hsl(120, 100%, 40%);">+        .name = "IPA-KEEPALIVE",</span><br><span style="color: hsl(120, 100%, 40%);">+    .states = ipa_keepalive_states,</span><br><span style="color: hsl(120, 100%, 40%);">+       .num_states = ARRAY_SIZE(ipa_keepalive_states),</span><br><span style="color: hsl(120, 100%, 40%);">+       .log_subsys = DLINP,</span><br><span style="color: hsl(120, 100%, 40%);">+  .allstate_action = ipa_ka_allstate_action,</span><br><span style="color: hsl(120, 100%, 40%);">+    .event_names = ipa_keepalive_event_names,</span><br><span style="color: hsl(120, 100%, 40%);">+     .timer_cb = ipa_ka_fsm_timer_cb,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static __attribute__((constructor)) void on_dso_load(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fsm_register(&ipa_keepalive_fsm);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Create a new instance of an IPA keepalive FSM: Periodically transmit PING and expect PONG.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] client The client connection for which to crate the FSM. Used as talloc context.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] params Parameters describing the keepalive FSM time-outs.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] id String used as identifier for the FSM.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns pointer to the newly-created FSM instance; NULL in case of error. */</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_fsm_inst *ipa_client_conn_alloc_keepalive_fsm(struct ipa_client_conn *client,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                    const struct ipa_keepalive_params *params,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                    const char *id)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct osmo_fsm_inst *fi;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct ipa_fsm_priv *ifp;</span><br><span style="color: hsl(120, 100%, 40%);">+     void *ctx = client;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ fi = osmo_fsm_inst_alloc(&ipa_keepalive_fsm, ctx, NULL, LOGL_DEBUG, id);</span><br><span style="color: hsl(120, 100%, 40%);">+  ifp = talloc_zero(fi, struct ipa_fsm_priv);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!ifp) {</span><br><span style="color: hsl(120, 100%, 40%);">+           osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+            return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     memcpy(&ifp->params, params, sizeof(ifp->params));</span><br><span style="color: hsl(120, 100%, 40%);">+  ifp->client_conn = client;</span><br><span style="color: hsl(120, 100%, 40%);">+ fi->priv = ifp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return fi;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Create a new instance of an IPA keepalive FSM: Periodically transmit PING and expect PONG.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] server The server connection for which to crate the FSM. Used as talloc context.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] params Parameters describing the keepalive FSM time-outs.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] id String used as identifier for the FSM.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns pointer to the newly-created FSM instance; NULL in case of error. */</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_fsm_inst *ipa_server_conn_alloc_keepalive_fsm(struct ipa_server_conn *server,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                      const struct ipa_keepalive_params *params,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                    const char *id)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct osmo_fsm_inst *fi;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct ipa_fsm_priv *ifp;</span><br><span style="color: hsl(120, 100%, 40%);">+     void *ctx = server;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ fi = osmo_fsm_inst_alloc(&ipa_keepalive_fsm, ctx, NULL, LOGL_NOTICE, id);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!fi)</span><br><span style="color: hsl(120, 100%, 40%);">+              return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        ifp = talloc_zero(fi, struct ipa_fsm_priv);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!ifp) {</span><br><span style="color: hsl(120, 100%, 40%);">+           osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+            return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     memcpy(&ifp->params, params, sizeof(ifp->params));</span><br><span style="color: hsl(120, 100%, 40%);">+  ifp->srv_conn = server;</span><br><span style="color: hsl(120, 100%, 40%);">+    fi->priv = ifp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return fi;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Set a timeout call-back which is to be called once the peer doesn't respond anymore */</span><br><span style="color: hsl(120, 100%, 40%);">+void ipa_keepalive_fsm_set_timeout_cb(struct osmo_fsm_inst *fi, ipa_keepalive_timeout_cb_t *cb)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct ipa_fsm_priv *ifp = fi->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(fi->fsm == &ipa_keepalive_fsm);</span><br><span style="color: hsl(120, 100%, 40%);">+    ifp->timeout_cb = cb;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Start the ping/pong procedure of the IPA Keepalive FSM. */</span><br><span style="color: hsl(120, 100%, 40%);">+void ipa_keepalive_fsm_pong_received(struct osmo_fsm_inst *fi)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(fi->fsm == &ipa_keepalive_fsm);</span><br><span style="color: hsl(120, 100%, 40%);">+    osmo_fsm_inst_dispatch(fi, OSMO_IPA_KA_E_PONG, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Stop the ping/pong procedure of the IPA Keepalive FSM. */</span><br><span style="color: hsl(120, 100%, 40%);">+void ipa_keepalive_fsm_start(struct osmo_fsm_inst *fi)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_ASSERT(fi->fsm == &ipa_keepalive_fsm);</span><br><span style="color: hsl(120, 100%, 40%);">+    osmo_fsm_inst_dispatch(fi, OSMO_IPA_KA_E_START, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Inform IPA Keepalive FSM that a PONG has been received. */</span><br><span style="color: hsl(120, 100%, 40%);">+void ipa_keepalive_fsm_stop(struct osmo_fsm_inst *fi)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(fi->fsm == &ipa_keepalive_fsm);</span><br><span style="color: hsl(120, 100%, 40%);">+    osmo_fsm_inst_dispatch(fi, OSMO_IPA_KA_E_STOP, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/13196">change 13196</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/13196"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmo-abis </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I2763da49a74de85046ac07d53592c89973314ca6 </div>
<div style="display:none"> Gerrit-Change-Number: 13196 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Harald Welte <laforge@gnumonks.org> </div>