aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEric Wild <ewild@sysmocom.de>2019-07-09 13:48:06 +0200
committerlaforge <laforge@gnumonks.org>2019-07-21 19:27:40 +0000
commit51b610095d95c525e6882a6361eb4abfc8c6c789 (patch)
tree6cd44f7b3ac4f2747ca20c63c960e7525bd6ac40 /src
parentb4a7db0f3675fe2a13d0486cb19a3438fb03e730 (diff)
extend the ipa keepalive fsm
The new and improved fsm supports multipe use cases: 1) plain old ipa server/client operation 2) ipa client/server operation with custom send callback (i.e. to bypass the tx queue) 3) all of the above + custom timeout callback 4) fully generic operation that will pass opaque data to the callbacks The current code will always kill the fsm and deallocate it upon timeout, so the timeout callback will now return a value: 1 means the fsm will be automatically terminated, 0 means no action, which allows manually stopping/starting the fsm to reuse it. Change-Id: Ie453fdee8bfd7fc1a3f1ed67ef0331f0abb1d59b
Diffstat (limited to 'src')
-rw-r--r--src/input/ipa_keepalive.c55
1 files changed, 50 insertions, 5 deletions
diff --git a/src/input/ipa_keepalive.c b/src/input/ipa_keepalive.c
index 81b5a26..d8eec77 100644
--- a/src/input/ipa_keepalive.c
+++ b/src/input/ipa_keepalive.c
@@ -76,7 +76,9 @@ struct ipa_fsm_priv {
struct ipa_server_conn *srv_conn;
struct ipa_client_conn *client_conn;
+ void *generic;
ipa_keepalive_timeout_cb_t *timeout_cb;
+ ipa_keepalive_send_cb_t *send_fn;
};
static void ipa_ka_init(struct osmo_fsm_inst *fi, uint32_t event, void *data)
@@ -103,11 +105,23 @@ static void ipa_ka_wait_resp_onenter(struct osmo_fsm_inst *fi, uint32_t prev_sta
msg = gen_ipa_ping();
OSMO_ASSERT(msg);
- if (ifp->srv_conn)
- ipa_server_conn_send(ifp->srv_conn, msg);
+ if (ifp->send_fn && ifp->generic) {
+ ifp->send_fn(fi, ifp->generic, msg);
+ return;
+ }
+
+ if (ifp->srv_conn) {
+ if (ifp->send_fn)
+ ifp->send_fn(fi, ifp->srv_conn, msg);
+ else
+ ipa_server_conn_send(ifp->srv_conn, msg);
+ }
else {
OSMO_ASSERT(ifp->client_conn);
- ipa_client_conn_send(ifp->client_conn, msg);
+ if (ifp->send_fn)
+ ifp->send_fn(fi, ifp->client_conn, msg);
+ else
+ ipa_client_conn_send(ifp->client_conn, msg);
}
}
@@ -140,10 +154,12 @@ static int ipa_ka_fsm_timer_cb(struct osmo_fsm_inst *fi)
/* PONG not received within time */
if (ifp->srv_conn)
conn = ifp->srv_conn;
- else
+ else if (ifp->client_conn)
conn = ifp->client_conn;
+ else
+ conn = ifp->generic;
if (ifp->timeout_cb)
- ifp->timeout_cb(fi, conn);
+ return ifp->timeout_cb(fi, conn);
/* ask fsm core to terminate us */
return 1;
default:
@@ -261,6 +277,27 @@ struct osmo_fsm_inst *ipa_server_conn_alloc_keepalive_fsm(struct ipa_server_conn
return fi;
}
+/*! Create a new instance of an IPA keepalive FSM: Periodically transmit PING and expect PONG.
+ * \param[in] ctx Talloc context.
+ * \param[in] data Data to pass to write/timeout cb.
+ * \param[in] params Parameters describing the keepalive FSM time-outs.
+ * \param[in] id String used as identifier for the FSM.
+ * \returns pointer to the newly-created FSM instance; NULL in case of error. */
+struct osmo_fsm_inst *ipa_generic_conn_alloc_keepalive_fsm(void *ctx, void* data,
+ const struct ipa_keepalive_params *params,
+ const char *id)
+{
+ struct osmo_fsm_inst *fi;
+ struct ipa_fsm_priv *ifp;
+
+ fi = __ipa_conn_alloc_keepalive_fsm(ctx, params, id);
+ if (!fi)
+ return NULL;
+ ifp = fi->priv;
+ ifp->generic = data;
+ return fi;
+}
+
/*! Set a timeout call-back which is to be called once the peer doesn't respond anymore */
void ipa_keepalive_fsm_set_timeout_cb(struct osmo_fsm_inst *fi, ipa_keepalive_timeout_cb_t *cb)
{
@@ -269,6 +306,14 @@ void ipa_keepalive_fsm_set_timeout_cb(struct osmo_fsm_inst *fi, ipa_keepalive_ti
ifp->timeout_cb = cb;
}
+/*! Set a custom send callback for sending pings */
+void ipa_keepalive_fsm_set_send_cb(struct osmo_fsm_inst *fi, ipa_keepalive_send_cb_t *fn)
+{
+ struct ipa_fsm_priv *ifp = fi->priv;
+ OSMO_ASSERT(fi->fsm == &ipa_keepalive_fsm);
+ ifp->send_fn = fn;
+}
+
/*! Inform IPA Keepalive FSM that a PONG has been received. */
void ipa_keepalive_fsm_pong_received(struct osmo_fsm_inst *fi)
{