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
This commit is contained in:
Neels Hofmeyr 2017-10-16 16:18:01 +02:00 committed by Neels Hofmeyr
parent 1fa8dfbaf4
commit ea66852a62
2 changed files with 76 additions and 15 deletions

View File

@ -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);

View File

@ -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)
return 0;
if (!node_count)
node_count = _LAST_CTRL_NODE;
OSMO_ASSERT(node_count >= _LAST_CTRL_NODE);
ctrl_node_vec = vector_init(_LAST_CTRL_NODE);
if (ctrl_initialized) {
OSMO_ASSERT(ctrl_initialized == node_count);
return 0;
}
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.