diff options
-rw-r--r-- | openbsc/include/openbsc/osmo_bsc_rf.h | 25 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_ctrl.c | 7 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_rf.c | 81 |
3 files changed, 113 insertions, 0 deletions
diff --git a/openbsc/include/openbsc/osmo_bsc_rf.h b/openbsc/include/openbsc/osmo_bsc_rf.h index 6db28cd64..d3e2caba4 100644 --- a/openbsc/include/openbsc/osmo_bsc_rf.h +++ b/openbsc/include/openbsc/osmo_bsc_rf.h @@ -1,9 +1,28 @@ #ifndef OSMO_BSC_RF #define OSMO_BSC_RF +#include <openbsc/gsm_data.h> #include <osmocom/core/write_queue.h> #include <osmocom/core/timer.h> +enum osmo_bsc_rf_opstate { + OSMO_BSC_RF_OPSTATE_INOPERATIONAL, + OSMO_BSC_RF_OPSTATE_OPERATIONAL, +}; + +enum osmo_bsc_rf_adminstate { + OSMO_BSC_RF_ADMINSTATE_UNLOCKED, + OSMO_BSC_RF_ADMINSTATE_LOCKED, +}; + +enum osmo_bsc_rf_policy { + OSMO_BSC_RF_POLICY_OFF, + OSMO_BSC_RF_POLICY_ON, + OSMO_BSC_RF_POLICY_GRACE, + OSMO_BSC_RF_POLICY_UNKNOWN, +}; + + struct gsm_network; struct osmo_bsc_rf { @@ -30,6 +49,12 @@ struct osmo_bsc_rf_conn { struct osmo_bsc_rf *rf; }; +const char *osmo_bsc_rf_get_opstate_name(enum osmo_bsc_rf_opstate opstate); +const char *osmo_bsc_rf_get_adminstate_name(enum osmo_bsc_rf_adminstate adminstate); +const char *osmo_bsc_rf_get_policy_name(enum osmo_bsc_rf_policy policy); +enum osmo_bsc_rf_opstate osmo_bsc_rf_get_opstate_by_bts(struct gsm_bts *bts); +enum osmo_bsc_rf_adminstate osmo_bsc_rf_get_adminstate_by_bts(struct gsm_bts *bts); +enum osmo_bsc_rf_policy osmo_bsc_rf_get_policy_by_bts(struct gsm_bts *bts); struct osmo_bsc_rf *osmo_bsc_rf_create(const char *path, struct gsm_network *net); #endif diff --git a/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c b/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c index 58a281818..1508aa941 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c @@ -53,6 +53,7 @@ static int get_bts_loc(struct ctrl_cmd *cmd, void *data); static void generate_location_state_trap(struct gsm_bts *bts, struct bsc_msc_connection *msc_con) { struct ctrl_cmd *cmd; + const char *oper, *admin, *policy; cmd = ctrl_cmd_create(msc_con, CTRL_TYPE_TRAP); @@ -63,6 +64,12 @@ static void generate_location_state_trap(struct gsm_bts *bts, struct bsc_msc_con cmd->node = bts; get_bts_loc(cmd, NULL); + oper = osmo_bsc_rf_get_opstate_name(osmo_bsc_rf_get_opstate_by_bts(bts)); + admin = osmo_bsc_rf_get_adminstate_name(osmo_bsc_rf_get_adminstate_by_bts(bts)); + policy = osmo_bsc_rf_get_policy_name(osmo_bsc_rf_get_policy_by_bts(bts)); + + cmd->reply = talloc_asprintf_append(cmd->reply, ",%s,%s,%s", oper, admin, policy); + osmo_bsc_send_trap(cmd, msc_con); } diff --git a/openbsc/src/osmo-bsc/osmo_bsc_rf.c b/openbsc/src/osmo-bsc/osmo_bsc_rf.c index dc61a045d..b774a5db8 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_rf.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_rf.c @@ -28,6 +28,7 @@ #include <openbsc/ipaccess.h> #include <osmocom/core/talloc.h> +#include <osmocom/core/utils.h> #include <osmocom/gsm/protocol/gsm_12_21.h> #include <sys/socket.h> @@ -42,6 +43,86 @@ #define RF_CMD_D_OFF 'd' #define RF_CMD_ON_G 'g' +static const struct value_string opstate_names[] = { + { OSMO_BSC_RF_OPSTATE_INOPERATIONAL, "inoperational" }, + { OSMO_BSC_RF_OPSTATE_OPERATIONAL, "operational" }, + { 0, NULL } +}; + +static const struct value_string adminstate_names[] = { + { OSMO_BSC_RF_ADMINSTATE_UNLOCKED, "unlocked" }, + { OSMO_BSC_RF_ADMINSTATE_LOCKED, "locked" }, + { 0, NULL } +}; + +static const struct value_string policy_names[] = { + { OSMO_BSC_RF_POLICY_OFF, "off" }, + { OSMO_BSC_RF_POLICY_ON, "on" }, + { OSMO_BSC_RF_POLICY_GRACE, "grace" }, + { OSMO_BSC_RF_POLICY_UNKNOWN, "unknown" }, + { 0, NULL } +}; + +const char *osmo_bsc_rf_get_opstate_name(enum osmo_bsc_rf_opstate opstate) +{ + return get_value_string(opstate_names, opstate); +} + +const char *osmo_bsc_rf_get_adminstate_name(enum osmo_bsc_rf_adminstate adminstate) +{ + return get_value_string(adminstate_names, adminstate); +} + +const char *osmo_bsc_rf_get_policy_name(enum osmo_bsc_rf_policy policy) +{ + return get_value_string(policy_names, policy); +} + +enum osmo_bsc_rf_opstate osmo_bsc_rf_get_opstate_by_bts(struct gsm_bts *bts) +{ + struct gsm_bts_trx *trx; + + llist_for_each_entry(trx, &bts->trx_list, list) { + if (trx->mo.nm_state.operational == NM_OPSTATE_ENABLED) + return OSMO_BSC_RF_OPSTATE_OPERATIONAL; + } + + /* No trx were active, so this bts is disabled */ + return OSMO_BSC_RF_OPSTATE_INOPERATIONAL; +} + +enum osmo_bsc_rf_adminstate osmo_bsc_rf_get_adminstate_by_bts(struct gsm_bts *bts) +{ + struct gsm_bts_trx *trx; + + llist_for_each_entry(trx, &bts->trx_list, list) { + if (trx->mo.nm_state.administrative == NM_STATE_UNLOCKED) + return OSMO_BSC_RF_ADMINSTATE_UNLOCKED; + } + + /* All trx administrative states were locked */ + return OSMO_BSC_RF_ADMINSTATE_LOCKED; +} + +enum osmo_bsc_rf_policy osmo_bsc_rf_get_policy_by_bts(struct gsm_bts *bts) +{ + struct osmo_msc_data *msc_data = bts->network->msc_data; + + if (!msc_data || !msc_data->rf_ctrl) + return OSMO_BSC_RF_POLICY_UNKNOWN; + + switch (msc_data->rf_ctrl->policy) { + case S_RF_ON: + return OSMO_BSC_RF_POLICY_ON; + case S_RF_OFF: + return OSMO_BSC_RF_POLICY_OFF; + case S_RF_GRACE: + return OSMO_BSC_RF_POLICY_GRACE; + default: + return OSMO_BSC_RF_POLICY_UNKNOWN; + } +} + static int lock_each_trx(struct gsm_network *net, int lock) { struct gsm_bts *bts; |