From ea66852a62319901dc198ea1dc8cbfbf77217347 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Mon, 16 Oct 2017 16:18:01 +0200 Subject: ctrl: allow more nodes than those in enum ctrl_node_type Add ctrl_interface_setup_dynip2() to add a node_count parameter, which can be used to define more ctrl nodes without having to merge a patch to libosmocore. In consequence, also add ctrl_handle_alloc2(), since ctrl_interface_setup_dynip() uses ctrl_handle_alloc() to allocate the node slots, and add node_count param to static ctrl_init(). Passing zero as node_count indicates to use the default of _LAST_CTRL_NODE as before, i.e. to not define more ctrl nodes. Assert that we never allocate less than _LAST_CTRL_NODE slots. The current ctrl_interface_setup_dynip() and ctrl_handle_alloc() become simple wrappers that pass zero as node_count. Their use is still valid and they do not need to be deprecated. The API comment to ctrl_interface_setup_dynip2() explains how to define more node IDs. This patch was verified to work by osmo-hlr.git change I98ee6a06b3aa6a67adb868e0b63b0e04eb42eb50 which adds two node IDs for use by osmo-hlr only. Change-Id: I1bd62ae0d4eefde7e1517db15a2155640a1bab58 --- include/osmocom/ctrl/control_if.h | 8 ++++ src/ctrl/control_if.c | 81 ++++++++++++++++++++++++++++++++------- 2 files changed, 75 insertions(+), 14 deletions(-) diff --git a/include/osmocom/ctrl/control_if.h b/include/osmocom/ctrl/control_if.h index 6e49742d..d4443287 100644 --- a/include/osmocom/ctrl/control_if.h +++ b/include/osmocom/ctrl/control_if.h @@ -24,12 +24,20 @@ struct ctrl_handle { int ctrl_cmd_send(struct osmo_wqueue *queue, struct ctrl_cmd *cmd); int ctrl_cmd_send_trap(struct ctrl_handle *ctrl, const char *name, char *value); struct ctrl_handle *ctrl_handle_alloc(void *ctx, void *data, ctrl_cmd_lookup lookup); +struct ctrl_handle *ctrl_handle_alloc2(void *ctx, void *data, + ctrl_cmd_lookup lookup, + unsigned int node_count); struct ctrl_handle *ctrl_interface_setup(void *data, uint16_t port, ctrl_cmd_lookup lookup); struct ctrl_handle *ctrl_interface_setup_dynip(void *data, const char *bind_addr, uint16_t port, ctrl_cmd_lookup lookup); +struct ctrl_handle *ctrl_interface_setup_dynip2(void *data, + const char *bind_addr, + uint16_t port, + ctrl_cmd_lookup lookup, + unsigned int node_count); struct ctrl_connection *osmo_ctrl_conn_alloc(void *ctx, void *data); int ctrl_cmd_handle(struct ctrl_handle *ctrl, struct ctrl_cmd *cmd, void *data); struct ctrl_cmd *ctrl_cmd_exec_from_string(struct ctrl_handle *ch, const char *cmdstr); diff --git a/src/ctrl/control_if.c b/src/ctrl/control_if.c index d50ddd0d..9b8a194a 100644 --- a/src/ctrl/control_if.c +++ b/src/ctrl/control_if.c @@ -698,14 +698,20 @@ struct ctrl_handle *ctrl_interface_setup(void *data, uint16_t port, static int ctrl_initialized = 0; /* global ctrl initialization */ -static int ctrl_init(void) +static int ctrl_init(unsigned int node_count) { int ret; - if (ctrl_initialized) + if (!node_count) + node_count = _LAST_CTRL_NODE; + OSMO_ASSERT(node_count >= _LAST_CTRL_NODE); + + if (ctrl_initialized) { + OSMO_ASSERT(ctrl_initialized == node_count); return 0; + } - ctrl_node_vec = vector_init(_LAST_CTRL_NODE); + ctrl_node_vec = vector_init(node_count); if (!ctrl_node_vec) goto err; @@ -720,7 +726,7 @@ static int ctrl_init(void) if (ret) goto err_vec; - ctrl_initialized = 1; + ctrl_initialized = node_count; return 0; err_vec: @@ -730,18 +736,24 @@ err: return -1; } -/*! Allocate a CTRL interface handle - * \param[in] ctx Tallo callocation context to be used +/*! Allocate a CTRL interface handle. + * \param[in] ctx Talloc allocation context to be used * \param[in] data Pointer which will be made available to each set_..() get_..() verify_..() control command function * \param[in] lookup Lookup function pointer, can be NULL + * \param[in] node_count Number of CTRL nodes to allocate, 0 for default. * \returns ctrl_handle pointer or NULL in case of errors + * + * Please see ctrl_interface_setup_dynip2() for a detailed description of \a + * node_count semantics. */ -struct ctrl_handle *ctrl_handle_alloc(void *ctx, void *data, ctrl_cmd_lookup lookup) +struct ctrl_handle *ctrl_handle_alloc2(void *ctx, void *data, + ctrl_cmd_lookup lookup, + unsigned int node_count) { struct ctrl_handle *ctrl; - ctrl_init(); + ctrl_init(node_count); ctrl = talloc_zero(ctx, struct ctrl_handle); if (!ctrl) @@ -755,23 +767,47 @@ struct ctrl_handle *ctrl_handle_alloc(void *ctx, void *data, ctrl_cmd_lookup loo return ctrl; } -/*! Setup CTRL interface on a given address +/*! Allocate a CTRL interface handle. + * \param[in] ctx Talloc allocation context to be used + * \param[in] data Pointer which will be made available to each + set_..() get_..() verify_..() control command function + * \param[in] lookup Lookup function pointer, can be NULL + * \returns ctrl_handle pointer or NULL in case of errors + */ +struct ctrl_handle *ctrl_handle_alloc(void *ctx, void *data, ctrl_cmd_lookup lookup) +{ + return ctrl_handle_alloc2(ctx, data, lookup, 0); +} + +/*! Setup CTRL interface on a given address. * \param[in] data Pointer which will be made available to each set_..() get_..() verify_..() control command function * \param[in] bind_addr Address on which CTRL socket shall listen * \param[in] port Port on which CTRL socket shall listen * \param[in] lookup Lookup function pointer, can be NULL + * \param[in] node_count Number of CTRL nodes to allocate, 0 for default. * \returns ctrl_handle pointer or NULL in case of errors + * + * Control interface nodes are identified by a node handle; some of these are + * defined in enum ctrl_node_type, here in libosmocore. However, applications + * defining own nodes may add own control nodes without having to extend the + * enum in libosmocore. For example, in the calling application, define an enum + * like "enum more_ctrl_nodes { CTRL_NODE_FOO = _LAST_CTRL_NODE, CTRL_NODE_BAR, + * _LAST_CTRL_NODE_EXTENDED }". In order to provide space for the additional + * control nodes, pass _LAST_CTRL_NODE_EXTENDED to the \a node_count parameter. + * Passing 0 is identical to passing _LAST_CTRL_NODE, i.e. to not define own + * control nodes apart from libosmocore ones. */ -struct ctrl_handle *ctrl_interface_setup_dynip(void *data, - const char *bind_addr, - uint16_t port, - ctrl_cmd_lookup lookup) +struct ctrl_handle *ctrl_interface_setup_dynip2(void *data, + const char *bind_addr, + uint16_t port, + ctrl_cmd_lookup lookup, + unsigned int node_count) { int ret; struct ctrl_handle *ctrl; - ctrl = ctrl_handle_alloc(data, data, lookup); + ctrl = ctrl_handle_alloc2(data, data, lookup, node_count); if (!ctrl) return NULL; @@ -789,6 +825,23 @@ struct ctrl_handle *ctrl_interface_setup_dynip(void *data, return ctrl; } +/*! Setup CTRL interface on a given address. + * \param[in] data Pointer which will be made available to each + set_..() get_..() verify_..() control command function + * \param[in] bind_addr Address on which CTRL socket shall listen + * \param[in] port Port on which CTRL socket shall listen + * \param[in] lookup Lookup function pointer, can be NULL + * \returns ctrl_handle pointer or NULL in case of errors + */ +struct ctrl_handle *ctrl_interface_setup_dynip(void *data, + const char *bind_addr, + uint16_t port, + ctrl_cmd_lookup lookup) +{ + return ctrl_interface_setup_dynip2(data, bind_addr, port, lookup, 0); +} + + /*! Install a lookup helper function for control nodes * This function is used by e.g. library code to install lookup helpers * for additional nodes in the control interface. -- cgit v1.2.3