aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2019-11-25 03:59:44 +0100
committerNeels Hofmeyr <neels@hofmeyr.de>2020-04-30 19:21:18 +0200
commit939f508f00ee56d6e347a4377d4007e7ffe51782 (patch)
tree1351514e9f666500da8b2dc5d962ff6cec42fd14
parentc79bcdedc92a5ae7dad67b5f10452d549ccfb39e (diff)
gsup client: add up_down_cb(), add osmo_gsup_client_create3()
For the GSUP clients in upcoming D-GSM enabled osmo-hlr, it will be necessary to trigger an event as soon as a GSUP client connection becomes ready for communication. Add the osmo_gsup_client->up_down_cb. Add osmo_gsup_client_create3() to pass the up_down_cb in the arguments. Also add a cb data argument to populate the already existing osmo_gsup_client->data item directly from osmo_gsup_client_create3(). We need the callbacks and data pointer in the osmo_gsup_client_create() function right before startup, because this function immediately starts up the connection. Who knows whether callbacks might trigger right away. Because there are so many arguments, and to prevent the need for ever new versions of this function, pass the arguments as an extendable struct. Change-Id: I6f181e42b678465bc9945f192559dc57d2083c6d
-rw-r--r--include/osmocom/gsupclient/gsup_client.h25
-rw-r--r--src/gsupclient/gsup_client.c69
2 files changed, 74 insertions, 20 deletions
diff --git a/include/osmocom/gsupclient/gsup_client.h b/include/osmocom/gsupclient/gsup_client.h
index b417ade..ea66ca1 100644
--- a/include/osmocom/gsupclient/gsup_client.h
+++ b/include/osmocom/gsupclient/gsup_client.h
@@ -38,6 +38,8 @@ struct osmo_gsup_client;
/* Expects message in msg->l2h */
typedef int (*osmo_gsup_client_read_cb_t)(struct osmo_gsup_client *gsupc, struct msgb *msg);
+typedef bool (*osmo_gsup_client_up_down_cb_t)(struct osmo_gsup_client *gsupc, bool up);
+
struct osmo_gsup_client {
const char *unit_name; /* same as ipa_dev->unit_name, for backwards compat */
@@ -53,7 +55,30 @@ struct osmo_gsup_client {
int got_ipa_pong;
struct ipaccess_unit *ipa_dev; /* identification information sent to IPA server */
+
+ osmo_gsup_client_up_down_cb_t up_down_cb;
+};
+
+struct osmo_gsup_client_config {
+ /*! IP access unit which contains client identification information; must be allocated in talloc_ctx as well to
+ * ensure it lives throughout the lifetime of the connection. */
+ struct ipaccess_unit *ipa_dev;
+ /*! GSUP server IP address to connect to. */
+ const char *ip_addr;
+ /*! GSUP server TCP port to connect to. */
+ unsigned int tcp_port;
+ /*! OPA client configuration, or NULL. */
+ struct osmo_oap_client_config *oapc_config;
+ /*! callback for reading from the GSUP connection. */
+ osmo_gsup_client_read_cb_t read_cb;
+ /*! Invoked when the GSUP link is ready for communication, and when the link drops. */
+ osmo_gsup_client_up_down_cb_t up_down_cb;
+ /*! User data stored in the returned gsupc->data, as context for the callbacks. */
+ void *data;
+ /*! Marker for future extension, always pass this as false. */
+ bool more;
};
+struct osmo_gsup_client *osmo_gsup_client_create3(void *talloc_ctx, struct osmo_gsup_client_config *config);
struct osmo_gsup_client *osmo_gsup_client_create2(void *talloc_ctx,
struct ipaccess_unit *ipa_dev,
diff --git a/src/gsupclient/gsup_client.c b/src/gsupclient/gsup_client.c
index 52985c9..4f76efc 100644
--- a/src/gsupclient/gsup_client.c
+++ b/src/gsupclient/gsup_client.c
@@ -97,6 +97,12 @@ static void connect_timer_cb(void *gsupc_)
if (gsupc->is_connected)
return;
+ if (gsupc->up_down_cb) {
+ /* When the up_down_cb() returns false, the user asks us not to retry connecting. */
+ if (!gsupc->up_down_cb(gsupc, false))
+ return;
+ }
+
gsup_client_connect(gsupc);
}
@@ -139,9 +145,18 @@ static void gsup_client_updown_cb(struct ipa_client_conn *link, int up)
gsup_client_oap_register(gsupc);
osmo_timer_del(&gsupc->connect_timer);
+
+ if (gsupc->up_down_cb)
+ gsupc->up_down_cb(gsupc, true);
} else {
osmo_timer_del(&gsupc->ping_timer);
+ if (gsupc->up_down_cb) {
+ /* When the up_down_cb() returns false, the user asks us not to retry connecting. */
+ if (!gsupc->up_down_cb(gsupc, false))
+ return;
+ }
+
osmo_timer_schedule(&gsupc->connect_timer,
OSMO_GSUP_CLIENT_RECONNECT_INTERVAL, 0);
}
@@ -263,31 +278,28 @@ static void start_test_procedure(struct osmo_gsup_client *gsupc)
* Use the provided ipaccess unit as the client-side identifier; ipa_dev should
* be allocated in talloc_ctx talloc_ctx as well.
* \param[in] talloc_ctx talloc context.
- * \param[in] ipa_dev IP access unit which contains client identification information; must be allocated
- * in talloc_ctx as well to ensure it lives throughout the lifetime of the connection.
- * \param[in] ip_addr GSUP server IP address.
- * \param[in] tcp_port GSUP server TCP port.
- * \param[in] read_cb callback for reading from the GSUP connection.
- * \param[in] oapc_config OPA client configuration.
- * \returns a GSUP client connection or NULL on failure.
+ * \param[in] config Parameters for setting up the GSUP client.
+ * \return a GSUP client connection, or NULL on failure.
*/
-struct osmo_gsup_client *osmo_gsup_client_create2(void *talloc_ctx,
- struct ipaccess_unit *ipa_dev,
- const char *ip_addr,
- unsigned int tcp_port,
- osmo_gsup_client_read_cb_t read_cb,
- struct osmo_oap_client_config *oapc_config)
+struct osmo_gsup_client *osmo_gsup_client_create3(void *talloc_ctx, struct osmo_gsup_client_config *config)
{
struct osmo_gsup_client *gsupc;
int rc;
+ OSMO_ASSERT(config->ipa_dev->unit_name);
+
gsupc = talloc_zero(talloc_ctx, struct osmo_gsup_client);
OSMO_ASSERT(gsupc);
- gsupc->unit_name = (const char *)ipa_dev->unit_name; /* API backwards compat */
- gsupc->ipa_dev = ipa_dev;
+ *gsupc = (struct osmo_gsup_client){
+ .unit_name = (const char *)config->ipa_dev->unit_name, /* API backwards compat */
+ .ipa_dev = config->ipa_dev,
+ .read_cb = config->read_cb,
+ .up_down_cb = config->up_down_cb,
+ .data = config->data,
+ };
/* a NULL oapc_config will mark oap_state disabled. */
- rc = osmo_oap_client_init(oapc_config, &gsupc->oap_state);
+ rc = osmo_oap_client_init(config->oapc_config, &gsupc->oap_state);
if (rc != 0)
goto failed;
@@ -295,7 +307,7 @@ struct osmo_gsup_client *osmo_gsup_client_create2(void *talloc_ctx,
/* no e1inp */ NULL,
0,
/* no specific local IP:port */ NULL, 0,
- ip_addr, tcp_port,
+ config->ip_addr, config->tcp_port,
gsup_client_updown_cb,
gsup_client_read_cb,
/* default write_cb */ NULL,
@@ -309,9 +321,6 @@ struct osmo_gsup_client *osmo_gsup_client_create2(void *talloc_ctx,
if (rc < 0)
goto failed;
-
- gsupc->read_cb = read_cb;
-
return gsupc;
failed:
@@ -319,6 +328,26 @@ failed:
return NULL;
}
+/*! Like osmo_gsup_client_create3() but without the up_down_cb and data arguments, and with the oapc_config argument in
+ * a different position.
+ */
+struct osmo_gsup_client *osmo_gsup_client_create2(void *talloc_ctx,
+ struct ipaccess_unit *ipa_dev,
+ const char *ip_addr,
+ unsigned int tcp_port,
+ osmo_gsup_client_read_cb_t read_cb,
+ struct osmo_oap_client_config *oapc_config)
+{
+ struct osmo_gsup_client_config cfg = {
+ .ipa_dev = ipa_dev,
+ .ip_addr = ip_addr,
+ .tcp_port = tcp_port,
+ .oapc_config = oapc_config,
+ .read_cb = read_cb,
+ };
+ return osmo_gsup_client_create3(talloc_ctx, &cfg);
+}
+
/**
* Like osmo_gsup_client_create2() except it expects a unit name instead
* of a full-blown ipacess_unit as the client-side identifier.