diff options
author | Daniel Willmann <daniel@totalueberwachung.de> | 2011-08-05 12:20:58 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2012-09-11 14:53:51 +0200 |
commit | 5ff06af6f560b9e906d6c320325ae84f3602f397 (patch) | |
tree | 267fce6529bfcc4c5d1692197dd60fbdda335bfa | |
parent | d5eb431c47e681152ea35ffc7fc1e7f8f513d947 (diff) |
osmo-bsc: Put the control commands in osmo_bsc_ctrl.c
-rw-r--r-- | openbsc/include/openbsc/osmo_bsc.h | 1 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/Makefile.am | 2 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_ctrl.c | 312 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_main.c | 259 |
4 files changed, 315 insertions, 259 deletions
diff --git a/openbsc/include/openbsc/osmo_bsc.h b/openbsc/include/openbsc/osmo_bsc.h index d8465c9f7..e3a79035b 100644 --- a/openbsc/include/openbsc/osmo_bsc.h +++ b/openbsc/include/openbsc/osmo_bsc.h @@ -41,5 +41,6 @@ int bsc_scan_msc_msg(struct gsm_subscriber_connection *conn, struct msgb *msg); int bsc_handle_udt(struct gsm_network *net, struct bsc_msc_connection *conn, struct msgb *msg, unsigned int length); int bsc_handle_dt1(struct osmo_bsc_sccp_con *conn, struct msgb *msg, unsigned int len); +void bsc_ctrl_cmds_install(); #endif diff --git a/openbsc/src/osmo-bsc/Makefile.am b/openbsc/src/osmo-bsc/Makefile.am index 8f7d25b82..cea8944a8 100644 --- a/openbsc/src/osmo-bsc/Makefile.am +++ b/openbsc/src/osmo-bsc/Makefile.am @@ -7,7 +7,7 @@ bin_PROGRAMS = osmo-bsc osmo_bsc_SOURCES = osmo_bsc_main.c osmo_bsc_vty.c osmo_bsc_api.c \ osmo_bsc_grace.c osmo_bsc_msc.c osmo_bsc_sccp.c \ - osmo_bsc_filter.c osmo_bsc_bssap.c osmo_bsc_audio.c + osmo_bsc_filter.c osmo_bsc_bssap.c osmo_bsc_audio.c osmo_bsc_ctrl.c # once again since TRAU uses CC symbol :( osmo_bsc_LDADD = $(top_builddir)/src/libbsc/libbsc.a \ $(top_builddir)/src/libmsc/libmsc.a \ diff --git a/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c b/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c new file mode 100644 index 000000000..1a24a2431 --- /dev/null +++ b/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c @@ -0,0 +1,312 @@ +/* (C) 2011 by Daniel Willmann <daniel@totalueberwachung.de> + * (C) 2011 by On-Waves + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <openbsc/control_cmd.h> +#include <openbsc/debug.h> +#include <openbsc/gsm_data.h> +#include <openbsc/osmo_bsc.h> +#include <openbsc/osmo_bsc_rf.h> +#include <openbsc/osmo_msc_data.h> + +#include <osmocom/core/linuxlist.h> +#include <osmocom/core/talloc.h> + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> + +void osmo_bsc_send_trap(struct ctrl_cmd *cmd, struct bsc_msc_connection *msc_con) +{ + struct ctrl_cmd *trap; + struct ctrl_handle *ctrl; + struct osmo_msc_data *msc_data; + + msc_data = (struct osmo_msc_data *) msc_con->write_queue.bfd.data; + ctrl = msc_data->network->ctrl; + + trap = ctrl_cmd_trap(cmd); + if (!trap) { + LOGP(DCTRL, LOGL_ERROR, "Failed to create trap.\n"); + return; + } + + ctrl_cmd_send_to_all(ctrl, trap); + ctrl_cmd_send(&msc_con->write_queue, trap); + + talloc_free(trap); +} + +#define LOC_FIX_INVALID 0 +#define LOC_FIX_2D 1 +#define LOC_FIX_3D 2 + +static const struct value_string valid_names[] = { + { LOC_FIX_INVALID, "invalid" }, + { LOC_FIX_2D, "fix2d" }, + { LOC_FIX_3D, "fix3d" }, + { 0, NULL } +}; + +struct location { + struct llist_head list; + time_t tstamp; + int valid; + double lat; + double lon; + double height; +}; + +static int location_equal(struct location *a, struct location *b) +{ + return ((a->tstamp == b->tstamp) && (a->valid == b->valid) && (a->lat == b->lat) && + (a->lon == b->lon) && (a->height == b->height)); +} + +static LLIST_HEAD(locations); + +static void cleanup_locations() +{ + struct location *myloc, *tmp; + int invalpos = 0, i = 0; + + LOGP(DCTRL, LOGL_DEBUG, "Checking position list.\n"); + llist_for_each_entry_safe(myloc, tmp, &locations, list) { + i++; + if (i > 3) { + LOGP(DCTRL, LOGL_DEBUG, "Deleting old position.\n"); + llist_del(&myloc->list); + talloc_free(myloc); + } else if (myloc->valid == LOC_FIX_INVALID) { + /* Only capture the newest of subsequent invalid positions */ + invalpos++; + if (invalpos > 1) { + LOGP(DCTRL, LOGL_DEBUG, "Deleting subsequent invalid position.\n"); + invalpos--; + i--; + llist_del(&myloc->list); + talloc_free(myloc); + } + } else { + invalpos = 0; + } + } + LOGP(DCTRL, LOGL_DEBUG, "Found %i positions.\n", i); +} + +CTRL_CMD_DEFINE(net_loc, "location"); +static int get_net_loc(struct ctrl_cmd *cmd, void *data) +{ + struct location *myloc; + + if (llist_empty(&locations)) { + cmd->reply = talloc_asprintf(cmd, "0,invalid,0,0,0"); + return CTRL_CMD_REPLY; + } else { + myloc = llist_entry(locations.next, struct location, list); + } + + cmd->reply = talloc_asprintf(cmd, "%lu,%s,%f,%f,%f", myloc->tstamp, + get_value_string(valid_names, myloc->valid), myloc->lat, myloc->lon, myloc->height); + if (!cmd->reply) { + cmd->reply = "OOM"; + return CTRL_CMD_ERROR; + } + + return CTRL_CMD_REPLY; +} + +static int set_net_loc(struct ctrl_cmd *cmd, void *data) +{ + char *saveptr, *lat, *lon, *height, *tstamp, *valid, *tmp; + struct osmo_msc_data *msc; + struct location *myloc, *lastloc; + int ret; + struct gsm_network *gsmnet = (struct gsm_network *)data; + + tmp = talloc_strdup(cmd, cmd->value); + if (!tmp) + goto oom; + + myloc = talloc_zero(tall_bsc_ctx, struct location); + if (!myloc) { + talloc_free(tmp); + goto oom; + } + INIT_LLIST_HEAD(&myloc->list); + + + tstamp = strtok_r(tmp, ",", &saveptr); + valid = strtok_r(NULL, ",", &saveptr); + lat = strtok_r(NULL, ",", &saveptr); + lon = strtok_r(NULL, ",", &saveptr); + height = strtok_r(NULL, "\0", &saveptr); + + myloc->tstamp = atol(tstamp); + myloc->valid = get_string_value(valid_names, valid); + myloc->lat = atof(lat); + myloc->lon = atof(lon); + myloc->height = atof(height); + talloc_free(tmp); + + lastloc = llist_entry(locations.next, struct location, list); + + /* Add location to the end of the list */ + llist_add(&myloc->list, &locations); + + ret = get_net_loc(cmd, data); + + if (!location_equal(myloc, lastloc)) + llist_for_each_entry(msc, &gsmnet->bsc_data->mscs, entry) + osmo_bsc_send_trap(cmd, msc->msc_con); + + cleanup_locations(); + + return ret; + +oom: + cmd->reply = "OOM"; + return CTRL_CMD_ERROR; +} + +static int verify_net_loc(struct ctrl_cmd *cmd, const char *value, void *data) +{ + char *saveptr, *latstr, *lonstr, *heightstr, *tstampstr, *validstr, *tmp; + time_t tstamp; + int valid; + double lat, lon, height; + + tmp = talloc_strdup(cmd, value); + if (!tmp) + return 1; + + tstampstr = strtok_r(tmp, ",", &saveptr); + validstr = strtok_r(NULL, ",", &saveptr); + latstr = strtok_r(NULL, ",", &saveptr); + lonstr = strtok_r(NULL, ",", &saveptr); + heightstr = strtok_r(NULL, "\0", &saveptr); + + if ((tstampstr == NULL) || (validstr == NULL) || (latstr == NULL) || + (lonstr == NULL) || (heightstr == NULL)) + goto err; + + tstamp = atol(tstampstr); + valid = get_string_value(valid_names, validstr); + lat = atof(latstr); + lon = atof(lonstr); + height = atof(heightstr); + talloc_free(tmp); + + if (((tstamp == 0) && (valid != LOC_FIX_INVALID)) || (lat < -90) || (lat > 90) || + (lon < -180) || (lon > 180) || (valid < 0)) { + goto err; + } + + return 0; +err: + cmd->reply = talloc_strdup(cmd, "The format is <unixtime>,(invalid|fix2d|fix3d),<lat>,<lon>,<height>"); + return 1; +} + +CTRL_CMD_DEFINE(trx_rf_lock, "rf_locked"); +static int get_trx_rf_lock(struct ctrl_cmd *cmd, void *data) +{ + struct gsm_bts_trx *trx = cmd->node; + if (!trx) { + cmd->reply = "trx not found."; + return CTRL_CMD_ERROR; + } + + cmd->reply = talloc_asprintf(cmd, "%u", trx->mo.nm_state.administrative == NM_STATE_LOCKED ? 1 : 0); + return CTRL_CMD_REPLY; +} + +static int set_trx_rf_lock(struct ctrl_cmd *cmd, void *data) +{ + int locked = atoi(cmd->value); + struct gsm_bts_trx *trx = cmd->node; + if (!trx) { + cmd->reply = "trx not found."; + return CTRL_CMD_ERROR; + } + + gsm_trx_lock_rf(trx, locked); + + return get_trx_rf_lock(cmd, data); +} + +static int verify_trx_rf_lock(struct ctrl_cmd *cmd, const char *value, void *data) +{ + int locked = atoi(cmd->value); + + if ((locked != 0) && (locked != 1)) + return 1; + + return 0; +} + +CTRL_CMD_DEFINE(net_rf_lock, "rf_locked"); +static int get_net_rf_lock(struct ctrl_cmd *cmd, void *data) +{ + cmd->reply = "get only works for the individual trx properties."; + return CTRL_CMD_ERROR; +} + +static int set_net_rf_lock(struct ctrl_cmd *cmd, void *data) +{ + int locked = atoi(cmd->value); + struct gsm_network *net = cmd->node; + struct gsm_bts *bts; + if (!net) { + cmd->reply = "net not found."; + return CTRL_CMD_ERROR; + } + + llist_for_each_entry(bts, &net->bts_list, list) { + struct gsm_bts_trx *trx; + llist_for_each_entry(trx, &bts->trx_list, list) { + gsm_trx_lock_rf(trx, locked); + } + } + + cmd->reply = talloc_asprintf(cmd, "%u", locked); + if (!cmd->reply) { + cmd->reply = "OOM."; + return CTRL_CMD_ERROR; + } + + return CTRL_CMD_REPLY; +} + +static int verify_net_rf_lock(struct ctrl_cmd *cmd, const char *value, void *data) +{ + int locked = atoi(cmd->value); + + if ((locked != 0) && (locked != 1)) + return 1; + + return 0; +} + +void bsc_ctrl_cmds_install() +{ + ctrl_cmd_install(CTRL_NODE_NET, &cmd_net_loc); + ctrl_cmd_install(CTRL_NODE_NET, &cmd_net_rf_lock); + ctrl_cmd_install(CTRL_NODE_TRX, &cmd_trx_rf_lock); +} diff --git a/openbsc/src/osmo-bsc/osmo_bsc_main.c b/openbsc/src/osmo-bsc/osmo_bsc_main.c index 8afd6ccd1..0f70ceb36 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_main.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_main.c @@ -175,261 +175,6 @@ static void signal_handler(int signal) } } -void osmo_bsc_send_trap(struct ctrl_cmd *cmd, struct bsc_msc_connection *msc_con) -{ - struct ctrl_cmd *trap; - struct ctrl_handle *ctrl; - struct osmo_msc_data *msc_data; - - msc_data = (struct osmo_msc_data *) msc_con->write_queue.bfd.data; - ctrl = msc_data->network->ctrl; - - trap = ctrl_cmd_trap(cmd); - if (!trap) { - LOGP(DCTRL, LOGL_ERROR, "Failed to create trap.\n"); - return; - } - - ctrl_cmd_send_to_all(ctrl, trap); - ctrl_cmd_send(&msc_con->write_queue, trap); - - talloc_free(trap); -} - -struct location { - struct llist_head list; - unsigned long age; - int valid; - double lat; - double lon; - double height; -}; - -static int location_equal(struct location *a, struct location *b) -{ - return ((a->age == b->age) && (a->valid == b->valid) && (a->lat == b->lat) && - (a->lon == b->lon) && (a->height == b->height)); -} - -static LLIST_HEAD(locations); - -static void cleanup_locations() -{ - struct location *myloc, *tmp; - int invalpos = 0, i = 0; - - LOGP(DCTRL, LOGL_DEBUG, "Checking position list.\n"); - llist_for_each_entry_safe(myloc, tmp, &locations, list) { - i++; - if (i > 3) { - LOGP(DCTRL, LOGL_DEBUG, "Deleting old position.\n"); - llist_del(&myloc->list); - talloc_free(myloc); - } else if (!myloc->valid) { /* Only capture the newest of subsequent invalid positions */ - invalpos++; - if (invalpos > 1) { - LOGP(DCTRL, LOGL_DEBUG, "Deleting subsequent invalid position.\n"); - invalpos--; - i--; - llist_del(&myloc->list); - talloc_free(myloc); - } - } else { - invalpos = 0; - } - } - LOGP(DCTRL, LOGL_DEBUG, "Found %i positions.\n", i); -} - -CTRL_CMD_DEFINE(net_loc, "location"); -static int get_net_loc(struct ctrl_cmd *cmd, void *data) -{ - struct location *myloc; - - if (llist_empty(&locations)) { - cmd->reply = talloc_asprintf(cmd, "0,0,0,0,0"); - return CTRL_CMD_REPLY; - } else { - myloc = llist_entry(locations.next, struct location, list); - } - - cmd->reply = talloc_asprintf(cmd, "%lu,%i,%f,%f,%f", myloc->age, myloc->valid, myloc->lat, myloc->lon, myloc->height); - if (!cmd->reply) { - cmd->reply = "OOM"; - return CTRL_CMD_ERROR; - } - - return CTRL_CMD_REPLY; -} - -static int set_net_loc(struct ctrl_cmd *cmd, void *data) -{ - char *saveptr, *lat, *lon, *height, *age, *valid, *tmp; - struct osmo_msc_data *msc; - struct location *myloc, *lastloc; - int ret; - struct gsm_network *gsmnet = (struct gsm_network *)data; - - tmp = talloc_strdup(cmd, cmd->value); - if (!tmp) - goto oom; - - myloc = talloc_zero(tall_bsc_ctx, struct location); - if (!myloc) { - talloc_free(tmp); - goto oom; - } - INIT_LLIST_HEAD(&myloc->list); - - - age = strtok_r(tmp, ",", &saveptr); - valid = strtok_r(NULL, ",", &saveptr); - lat = strtok_r(NULL, ",", &saveptr); - lon = strtok_r(NULL, ",", &saveptr); - height = strtok_r(NULL, "\0", &saveptr); - - myloc->age = atol(age); - myloc->valid = atoi(valid); - myloc->lat = atof(lat); - myloc->lon = atof(lon); - myloc->height = atof(height); - talloc_free(tmp); - - lastloc = llist_entry(locations.next, struct location, list); - - /* Add location to the end of the list */ - llist_add(&myloc->list, &locations); - - ret = get_net_loc(cmd, data); - - if (!location_equal(myloc, lastloc)) - llist_for_each_entry(msc, &gsmnet->bsc_data->mscs, entry) - osmo_bsc_send_trap(cmd, msc->msc_con); - - cleanup_locations(); - - return ret; - -oom: - cmd->reply = "OOM"; - return CTRL_CMD_ERROR; -} - -static int verify_net_loc(struct ctrl_cmd *cmd, const char *value, void *data) -{ - char *saveptr, *latstr, *lonstr, *heightstr, *agestr, *validstr, *tmp; - unsigned long age; - int valid; - double lat, lon, height; - - tmp = talloc_strdup(cmd, value); - if (!tmp) - return 1; - - agestr = strtok_r(tmp, ",", &saveptr); - validstr = strtok_r(NULL, ",", &saveptr); - latstr = strtok_r(NULL, ",", &saveptr); - lonstr = strtok_r(NULL, ",", &saveptr); - heightstr = strtok_r(NULL, "\0", &saveptr); - - if ((agestr == NULL) || (validstr == NULL) || (latstr == NULL) || - (lonstr == NULL) || (heightstr == NULL)) - return 1; - - age = atol(agestr); - valid = atoi(validstr); - lat = atof(latstr); - lon = atof(lonstr); - height = atof(heightstr); - talloc_free(tmp); - - if (((age == 0) && (valid !=0)) || (lat < -90) || (lat > 90) || - (lon < -180) || (lon > 180) || (valid < 0) || (valid > 2)) - return 1; - - return 0; -} - -CTRL_CMD_DEFINE(trx_rf_lock, "rf_locked"); -static int get_trx_rf_lock(struct ctrl_cmd *cmd, void *data) -{ - struct gsm_bts_trx *trx = cmd->node; - if (!trx) { - cmd->reply = "trx not found."; - return CTRL_CMD_ERROR; - } - - cmd->reply = talloc_asprintf(cmd, "%u", trx->mo.nm_state.administrative == NM_STATE_LOCKED ? 1 : 0); - return CTRL_CMD_REPLY; -} - -static int set_trx_rf_lock(struct ctrl_cmd *cmd, void *data) -{ - int locked = atoi(cmd->value); - struct gsm_bts_trx *trx = cmd->node; - if (!trx) { - cmd->reply = "trx not found."; - return CTRL_CMD_ERROR; - } - - gsm_trx_lock_rf(trx, locked); - - return get_trx_rf_lock(cmd, data); -} - -static int verify_trx_rf_lock(struct ctrl_cmd *cmd, const char *value, void *data) -{ - int locked = atoi(cmd->value); - - if ((locked != 0) && (locked != 1)) - return 1; - - return 0; -} - -CTRL_CMD_DEFINE(net_rf_lock, "rf_locked"); -static int get_net_rf_lock(struct ctrl_cmd *cmd, void *data) -{ - cmd->reply = "get only works for the individual trx properties."; - return CTRL_CMD_ERROR; -} - -static int set_net_rf_lock(struct ctrl_cmd *cmd, void *data) -{ - int locked = atoi(cmd->value); - struct gsm_network *net = cmd->node; - struct gsm_bts *bts; - if (!net) { - cmd->reply = "net not found."; - return CTRL_CMD_ERROR; - } - - llist_for_each_entry(bts, &net->bts_list, list) { - struct gsm_bts_trx *trx; - llist_for_each_entry(trx, &bts->trx_list, list) { - gsm_trx_lock_rf(trx, locked); - } - } - - cmd->reply = talloc_asprintf(cmd, "%u", locked); - if (!cmd->reply) { - cmd->reply = "OOM."; - return CTRL_CMD_ERROR; - } - - return CTRL_CMD_REPLY; -} - -static int verify_net_rf_lock(struct ctrl_cmd *cmd, const char *value, void *data) -{ - int locked = atoi(cmd->value); - - if ((locked != 0) && (locked != 1)) - return 1; - - return 0; -} - int main(int argc, char **argv) { struct osmo_msc_data *msc; @@ -469,9 +214,7 @@ int main(int argc, char **argv) bsc_gsmnet->ctrl = controlif_setup(bsc_gsmnet, 4249); - ctrl_cmd_install(CTRL_NODE_NET, &cmd_net_loc); - ctrl_cmd_install(CTRL_NODE_NET, &cmd_net_rf_lock); - ctrl_cmd_install(CTRL_NODE_TRX, &cmd_trx_rf_lock); + bsc_ctrl_cmds_install(); data = bsc_gsmnet->bsc_data; if (rf_ctrl) |