libctrl: Move bulk of node lookup code into libosmocore

Now that the bulk of the control interface node lookup has
no reference to the BSC specific data structures, we are
moving it into libosmocore.

A control interface user now only registers an optional small
node lookup function like bsc_ctrl_node_lookup()
This commit is contained in:
Harald Welte 2014-08-21 15:10:13 +02:00
parent a67455f8d8
commit 02cc2b668a
3 changed files with 5 additions and 184 deletions

View File

@ -73,67 +73,7 @@ int sgsn_ctrl_cmds_install(void)
return rc;
}
static int sgsn_cmd_handle(struct ctrl_cmd *cmd, void *data)
{
char *request;
cmd->reply = NULL;
cmd->node = NULL;
vector vline, cmdvec, cmds_vec;
int i, ret;
ret = CTRL_CMD_ERROR;
request = talloc_strdup(tall_bsc_ctx, cmd->variable);
if (!request)
goto err;
for (i = 0; i < strlen(request); ++i) {
if (request[i] == '.')
request[i] = ' ';
}
vline = cmd_make_strvec(request);
talloc_free(request);
if (!vline) {
cmd->reply = "cmd_make_strvec failed.";
goto err;
}
/* If we're here the rest must be the command */
cmdvec = vector_init(vector_active(vline));
for (i = 0 ; i < vector_active(vline); ++i) {
vector_set(cmdvec, vector_slot(vline, i));
}
/* Get the command vector of the right node */
cmds_vec = vector_lookup(ctrl_node_vec, CTRL_NODE_ROOT);
if (!cmds_vec) {
cmd->reply = "Command not found.";
vector_free(cmdvec);
goto err;
}
ret = ctrl_cmd_exec(cmdvec, cmd, cmds_vec, data);
vector_free(cmdvec);
cmd_free_strvec(vline);
err:
if (!cmd->reply) {
LOGP(DCTRL, LOGL_ERROR, "cmd->reply has not been set.\n");
if (ret == CTRL_CMD_ERROR)
cmd->reply = "An error has occured.";
else
cmd->reply = "Command has been handled.";
}
if (ret == CTRL_CMD_ERROR)
cmd->type = CTRL_TYPE_ERROR;
return ret;
}
struct ctrl_handle *sgsn_controlif_setup(struct gsm_network *net, uint16_t port)
{
return controlif_setup(net, port, sgsn_cmd_handle);
return controlif_setup(net, port, NULL);
}

View File

@ -30,26 +30,6 @@
extern vector ctrl_node_vec;
int ctrl_parse_get_num(vector vline, int i, long *num)
{
char *token, *tmp;
if (i >= vector_active(vline))
return 0;
token = vector_slot(vline, i);
errno = 0;
if (token[0] == '\0')
return 0;
*num = strtol(token, &tmp, 10);
if (tmp[0] != '\0' || errno != 0)
return 0;
return 1;
}
/*! \brief control interface lookup function for bsc/bts gsm_data
* \param[in] data Private data passed to controlif_setup()
* \param[in] vline Vector of the line holding the command string
@ -57,8 +37,8 @@ int ctrl_parse_get_num(vector vline, int i, long *num)
* \param[out] node_data private dta of node that was determined
* \param i Current index into vline, up to which it is parsed
*/
int bsc_ctrl_node_lookup(void *data, vector vline, int *node_type,
void **node_data, int *i)
static int bsc_ctrl_node_lookup(void *data, vector vline, int *node_type,
void **node_data, int *i)
{
struct gsm_network *net = data;
struct gsm_bts *bts = NULL;
@ -117,106 +97,7 @@ err_index:
return -ERANGE;
}
int bsc_ctrl_cmd_handle(struct ctrl_cmd *cmd, void *data)
{
char *request;
int i, j, ret, node;
vector vline, cmdvec, cmds_vec;
ret = CTRL_CMD_ERROR;
cmd->reply = NULL;
node = CTRL_NODE_ROOT;
cmd->node = data;
request = talloc_strdup(cmd, cmd->variable);
if (!request)
goto err;
for (i=0;i<strlen(request);i++) {
if (request[i] == '.')
request[i] = ' ';
}
vline = cmd_make_strvec(request);
talloc_free(request);
if (!vline) {
cmd->reply = "cmd_make_strvec failed.";
goto err;
}
for (i=0;i<vector_active(vline);i++) {
int rc;
rc = bsc_ctrl_node_lookup(data, vline, &node, &cmd->node, &i);
if (rc == 1) {
/* do nothing */
} else if (rc == -ENODEV)
goto err_missing;
else if (rc == -ERANGE)
goto err_index;
else {
/* If we're here the rest must be the command */
cmdvec = vector_init(vector_active(vline)-i);
for (j=i; j<vector_active(vline); j++) {
vector_set(cmdvec, vector_slot(vline, j));
}
/* Get the command vector of the right node */
cmds_vec = vector_lookup(ctrl_node_vec, node);
if (!cmds_vec) {
cmd->reply = "Command not found.";
vector_free(cmdvec);
break;
}
ret = ctrl_cmd_exec(cmdvec, cmd, cmds_vec, data);
vector_free(cmdvec);
break;
}
if (i+1 == vector_active(vline))
cmd->reply = "Command not present.";
}
cmd_free_strvec(vline);
err:
if (!cmd->reply) {
if (ret == CTRL_CMD_ERROR) {
cmd->reply = "An error has occured.";
LOGP(DCTRL, LOGL_NOTICE,
"%s: cmd->reply has not been set (ERROR).\n",
cmd->variable);
} else if (ret == CTRL_CMD_REPLY) {
LOGP(DCTRL, LOGL_NOTICE,
"%s: cmd->reply has not been set (type = %d).\n",
cmd->variable, cmd->type);
cmd->reply = "";
} else {
cmd->reply = "Command has been handled.";
}
}
if (ret == CTRL_CMD_ERROR)
cmd->type = CTRL_TYPE_ERROR;
return ret;
err_missing:
cmd_free_strvec(vline);
cmd->type = CTRL_TYPE_ERROR;
cmd->reply = "Error while resolving object";
return ret;
err_index:
cmd_free_strvec(vline);
cmd->type = CTRL_TYPE_ERROR;
cmd->reply = "Error while parsing the index.";
return ret;
}
struct ctrl_handle *bsc_controlif_setup(struct gsm_network *net, uint16_t port)
{
return controlif_setup(net, port, bsc_ctrl_cmd_handle);
return controlif_setup(net, port, bsc_ctrl_node_lookup);
}

View File

@ -218,7 +218,7 @@ static void handle_ctrl(struct osmo_msc_data *msc, struct msgb *msg)
return;
}
ret = bsc_ctrl_cmd_handle(cmd, msc->network);
ret = ctrl_cmd_handle(msc->network->ctrl, cmd, msc->network);
if (ret != CTRL_CMD_HANDLED)
ctrl_cmd_send(&msc->msc_con->write_queue, cmd);
talloc_free(cmd);