This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Neels Hofmeyr gerrit-no-reply at lists.osmocom.orgHello Max, Jenkins Builder, I'd like you to reexamine a change. Please visit https://gerrit.osmocom.org/4311 to look at the new patch set (#3). ctrl: completely replace all CTRL commands The previous commands are not conforming to how the CTRL interface is intended to work: SET enable-ps <IMSI> SET disable-ps <IMSI> SET status-ps <IMSI> 'status-ps' is a write-only command even though it returns the status. 'enable-ps' / 'disable-ps' indicate the value instead of a variable name of an entity. The entity <IMSI> takes the place of the variable value. See also https://lists.osmocom.org/pipermail/openbsc/2017-September/011236.html Instead, replace with SET subscriber.by-imsi-123456.ps-enabled {0,1} GET subscriber.by-imsi-123456.ps-enabled and also provide further CTRL functions while at it: {SET,GET} subscriber.by-{imsi,msisdn,id}-123456.{cs,ps}-enabled {0,1} GET subscriber.by-{imsi,msisdn,id}-123456.{info,info-aud,info-all} Provide CTRL tests in the form of transcripts. This is the first time an application uses CTRL_NODE ids that are defined outside of libosmocore, see 'Depends' below. Implementation choice: the first idea was to have a '.' between the 'by-xxx' and the value, like: subscriber.by-xxx.123456.function but the difficulty with subscribers is that they are not in RAM, and I can't just point node_data at a struct instance that is always there (like, say, a global bts[0] struct in osmo-bsc). Instead, I want to store the selector and later decide whether to read from the DB or whatever. With a '.' separating things, the only way in a ctrl function to obtain both 'by-xxx' and '123456' for picking a subscriber record would be to parse the entire variable path string elements, including 'subscriber' and 'function', which would then also clumsily fix at which node level we hook these commands; there could have been separate CTRL_NODE_SUBSCR_BY_{IMSI,MSISDN,ID} parent nodes, but we cannot introspect the current parent node dynamically within a ctrl function handler (plus I'm not sure whether it's possible and a good idea to have the same command under multiple parent nodes). Rather than that, I store the 'by-foo-123' token in the node_data pointer to have both bits of information pointed at by a single pointer; I use the incoming command parsing to get this token pre-separated from surrounding node names, and no need to re-allocate it, since the vector of tokens lives until after command execution is complete. Each leaf command obtains this token from cmd->node (aka node_data), and feeds this token to a common static function to parse selector and value from it and to retrieve a subscriber record as needed. (BTW, I have mentioned on the mailing list that this way might be necessary to avoid numeric-only CTRL node names, but we don't need to, and that is not at all related to this choice of structure.) Depends: libosmocore I1bd62ae0d4eefde7e1517db15a2155640a1bab58 libosmocore Ic9dba0e4a1eb5a7dc3cee2f181b9024ed4fc7005 Change-Id: I98ee6a06b3aa6a67adb868e0b63b0e04eb42eb50 --- M src/ctrl.c M src/ctrl.h M src/hlr.c M tests/test_subscriber.ctrl M tests/test_subscriber.sql M tests/test_subscriber.vty A tests/test_subscriber_errors.ctrl 7 files changed, 871 insertions(+), 78 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-hlr refs/changes/11/4311/3 diff --git a/src/ctrl.c b/src/ctrl.c index 3bd4d8f..6140a25 100644 --- a/src/ctrl.c +++ b/src/ctrl.c @@ -21,87 +21,382 @@ */ #include <stdbool.h> +#include <errno.h> +#include <inttypes.h> +#include <string.h> -#include <osmocom/ctrl/control_cmd.h> -#include <osmocom/ctrl/control_if.h> +#include <osmocom/gsm/gsm23003.h> #include <osmocom/ctrl/ports.h> -#include "gsup_server.h" -#include "logging.h" -#include "db.h" #include "hlr.h" -#include "luop.h" #include "ctrl.h" +#include "db.h" -static int handle_cmd_ps(struct hlr *ctx, struct ctrl_cmd *cmd, bool enable) +#define SEL_BY "by-" +#define SEL_BY_IMSI SEL_BY "imsi-" +#define SEL_BY_MSISDN SEL_BY "msisdn-" +#define SEL_BY_ID SEL_BY "id-" + +#define hexdump_buf(buf) osmo_hexdump_nospc((void*)buf, sizeof(buf)) + +static bool startswith(const char *str, const char *start) +{ + return strncmp(str, start, strlen(start)) == 0; +} + +static int _get_subscriber(struct db_context *dbc, + const char *by_selector, + struct hlr_subscriber *subscr) +{ + const char *val; + if (startswith(by_selector, SEL_BY_IMSI)) { + val = by_selector + strlen(SEL_BY_IMSI); + if (!osmo_imsi_str_valid(val)) + return -EINVAL; + return db_subscr_get_by_imsi(dbc, val, subscr); + } + if (startswith(by_selector, SEL_BY_MSISDN)) { + val = by_selector + strlen(SEL_BY_MSISDN); + if (!osmo_msisdn_str_valid(val)) + return -EINVAL; + return db_subscr_get_by_msisdn(dbc, val, subscr); + } + if (startswith(by_selector, SEL_BY_ID)) { + int64_t id; + char *endptr; + val = by_selector + strlen(SEL_BY_ID); + if (*val == '+') + return -EINVAL; + errno = 0; + id = strtoll(val, &endptr, 10); + if (errno || *endptr) + return -EINVAL; + return db_subscr_get_by_id(dbc, id, subscr); + } + return -ENOTSUP; +} + +static bool get_subscriber(struct db_context *dbc, + const char *by_selector, + struct hlr_subscriber *subscr, + struct ctrl_cmd *cmd) +{ + int rc = _get_subscriber(dbc, by_selector, subscr); + switch (rc) { + case 0: + return true; + case -ENOTSUP: + cmd->reply = "Not a known subscriber 'by-xxx-' selector."; + return false; + case -EINVAL: + cmd->reply = "Invalid value part of 'by-xxx-value' selector."; + return false; + case -ENOENT: + cmd->reply = "No such subscriber."; + return false; + default: + cmd->reply = NULL; + return false; + } +} + +/* Optimization: if a subscriber operation is requested by-imsi, just return + * the IMSI right back. */ +static const char *get_subscriber_imsi(struct db_context *dbc, + const char *by_selector, + struct ctrl_cmd *cmd) +{ + static struct hlr_subscriber subscr; + + if (startswith(by_selector, SEL_BY_IMSI)) + return by_selector + strlen(SEL_BY_IMSI); + if (!get_subscriber(dbc, by_selector, &subscr, cmd)) + return NULL; + return subscr.imsi; +} + +/* printf fmt and arg to completely omit a string if it is empty. */ +#define FMT_S "%s%s%s%s" +#define ARG_S(name, val) \ + (val) && *(val) ? "\n" : "", \ + (val) && *(val) ? name : "", \ + (val) && *(val) ? "\t" : "", \ + (val) && *(val) ? (val) : "" \ + +/* printf fmt and arg to completely omit bool of given value. */ +#define FMT_BOOL "%s" +#define ARG_BOOL_OMIT_TRUE(name, val) \ + val ? "" : "\n" name "\t0" +#define ARG_BOOL_OMIT_FALSE(name, val) \ + val ? "\n" name "\t1" : "" +#define ARG_BOOL(name, val) \ + val ? "\n" name "\t1" : "\n" name "\t0" + +static void print_subscr_info(struct ctrl_cmd *cmd, + struct hlr_subscriber *subscr) +{ + ctrl_cmd_reply_printf(cmd, + "\nid\t%"PRIu64 + FMT_S + FMT_S + FMT_BOOL + FMT_BOOL + FMT_S + FMT_S + FMT_S +#if 0 +/* not used yet */ + FMT_BOOL + FMT_BOOL + "\nperiodic_lu_timer\t%u" + "\nperiodic_rau_tau_timer\t%u" + "\nlmsi\t%08x" +#endif + , + subscr->id, + ARG_S("imsi", subscr->imsi), + ARG_S("msisdn", subscr->msisdn), + ARG_BOOL_OMIT_TRUE("nam_cs", subscr->nam_cs), + ARG_BOOL_OMIT_TRUE("nam_ps", subscr->nam_ps), + ARG_S("vlr_number", subscr->vlr_number), + ARG_S("sgsn_number", subscr->sgsn_number), + ARG_S("sgsn_address", subscr->sgsn_address) +#if 0 + , + ARG_BOOL_OMIT_FALSE("ms_purged_cs", subscr->ms_purged_cs), + ARG_BOOL_OMIT_FALSE("ms_purged_ps", subscr->ms_purged_ps), + subscr->periodic_lu_timer, + subscr->periodic_rau_tau_timer, + subscr->lmsi +#endif + ); +} + +static void print_subscr_info_aud2g(struct ctrl_cmd *cmd, struct osmo_sub_auth_data *aud) +{ + if (aud->algo == OSMO_AUTH_ALG_NONE) + return; + ctrl_cmd_reply_printf(cmd, + "\naud2g.algo\t%s" + "\naud2g.ki\t%s" + , + osmo_auth_alg_name(aud->algo), + hexdump_buf(aud->u.gsm.ki)); +} + +static void print_subscr_info_aud3g(struct ctrl_cmd *cmd, struct osmo_sub_auth_data *aud) +{ + if (aud->algo == OSMO_AUTH_ALG_NONE) + return; + ctrl_cmd_reply_printf(cmd, + "\naud3g.algo\t%s" + "\naud3g.k\t%s" + , + osmo_auth_alg_name(aud->algo), + hexdump_buf(aud->u.umts.k)); + /* hexdump uses a static string buffer, hence only one hexdump per + * printf(). */ + ctrl_cmd_reply_printf(cmd, + "\naud3g.%s\t%s" + "\naud3g.ind_bitlen\t%u" + "\naud3g.sqn\t%"PRIu64 + , + aud->u.umts.opc_is_op? "op" : "opc", + hexdump_buf(aud->u.umts.opc), + aud->u.umts.ind_bitlen, + aud->u.umts.sqn); +} + +CTRL_CMD_DEFINE_RO(subscr_info, "info"); +static int get_subscr_info(struct ctrl_cmd *cmd, void *data) { struct hlr_subscriber subscr; + struct hlr *hlr = data; + const char *by_selector = cmd->node; - if (db_subscr_get_by_imsi(ctx->dbc, cmd->value, &subscr) < 0) { - cmd->reply = "Subscriber Unknown in HLR"; + if (!get_subscriber(hlr->dbc, by_selector, &subscr, cmd)) + return CTRL_CMD_ERROR; + + print_subscr_info(cmd, &subscr); + + return CTRL_CMD_REPLY; +} + +CTRL_CMD_DEFINE_RO(subscr_info_aud, "info-aud"); +static int get_subscr_info_aud(struct ctrl_cmd *cmd, void *data) +{ + const char *imsi; + struct osmo_sub_auth_data aud2g; + struct osmo_sub_auth_data aud3g; + struct hlr *hlr = data; + const char *by_selector = cmd->node; + int rc; + + imsi = get_subscriber_imsi(hlr->dbc, by_selector, cmd); + if (!imsi) + return CTRL_CMD_ERROR; + + rc = db_get_auth_data(hlr->dbc, imsi, &aud2g, &aud3g, NULL); + + if (rc == -ENOENT) { + aud2g.algo = OSMO_AUTH_ALG_NONE; + aud3g.algo = OSMO_AUTH_ALG_NONE; + } else if (rc) { + cmd->reply = "Error retrieving authentication data."; return CTRL_CMD_ERROR; } - if (hlr_subscr_nam(ctx, &subscr, enable, true) < 0) { - cmd->reply = "Error updating DB"; + print_subscr_info_aud2g(cmd, &aud2g); + print_subscr_info_aud3g(cmd, &aud3g); + + return CTRL_CMD_REPLY; +} + +CTRL_CMD_DEFINE_RO(subscr_info_all, "info-all"); +static int get_subscr_info_all(struct ctrl_cmd *cmd, void *data) +{ + struct hlr_subscriber subscr; + struct osmo_sub_auth_data aud2g; + struct osmo_sub_auth_data aud3g; + struct hlr *hlr = data; + const char *by_selector = cmd->node; + int rc; + + if (!get_subscriber(hlr->dbc, by_selector, &subscr, cmd)) + return CTRL_CMD_ERROR; + + rc = db_get_auth_data(hlr->dbc, subscr.imsi, &aud2g, &aud3g, NULL); + + if (rc == -ENOENT) { + aud2g.algo = OSMO_AUTH_ALG_NONE; + aud3g.algo = OSMO_AUTH_ALG_NONE; + } else if (rc) { + cmd->reply = "Error retrieving authentication data."; return CTRL_CMD_ERROR; } + print_subscr_info(cmd, &subscr); + print_subscr_info_aud2g(cmd, &aud2g); + print_subscr_info_aud3g(cmd, &aud3g); + + return CTRL_CMD_REPLY; +} + +static int verify_subscr_cs_ps_enabled(struct ctrl_cmd *cmd, const char *value, void *data) +{ + if (!value || !*value + || (strcmp(value, "0") && strcmp(value, "1"))) + return 1; + return 0; +} + +static int get_subscr_cs_ps_enabled(struct ctrl_cmd *cmd, void *data, + bool is_ps) +{ + struct hlr_subscriber subscr; + struct hlr *hlr = data; + const char *by_selector = cmd->node; + + if (!get_subscriber(hlr->dbc, by_selector, &subscr, cmd)) + return CTRL_CMD_ERROR; + + cmd->reply = (is_ps ? subscr.nam_ps : subscr.nam_cs) + ? "1" : "0"; + return CTRL_CMD_REPLY; +} + +static int set_subscr_cs_ps_enabled(struct ctrl_cmd *cmd, void *data, + bool is_ps) +{ + const char *imsi; + struct hlr *hlr = data; + const char *by_selector = cmd->node; + + imsi = get_subscriber_imsi(hlr->dbc, by_selector, cmd); + if (!imsi) + return CTRL_CMD_ERROR; + if (db_subscr_nam(hlr->dbc, imsi, strcmp(cmd->value, "1") == 0, is_ps)) + return CTRL_CMD_ERROR; cmd->reply = "OK"; return CTRL_CMD_REPLY; } -CTRL_CMD_DEFINE_WO_NOVRF(enable_ps, "enable-ps"); -static int set_enable_ps(struct ctrl_cmd *cmd, void *data) +CTRL_CMD_DEFINE(subscr_ps_enabled, "ps-enabled"); +static int verify_subscr_ps_enabled(struct ctrl_cmd *cmd, const char *value, void *data) { - return handle_cmd_ps(data, cmd, true); + return verify_subscr_cs_ps_enabled(cmd, value, data); +} +static int get_subscr_ps_enabled(struct ctrl_cmd *cmd, void *data) +{ + return get_subscr_cs_ps_enabled(cmd, data, true); +} +static int set_subscr_ps_enabled(struct ctrl_cmd *cmd, void *data) +{ + return set_subscr_cs_ps_enabled(cmd, data, true); } -CTRL_CMD_DEFINE_WO_NOVRF(disable_ps, "disable-ps"); -static int set_disable_ps(struct ctrl_cmd *cmd, void *data) +CTRL_CMD_DEFINE(subscr_cs_enabled, "cs-enabled"); +static int verify_subscr_cs_enabled(struct ctrl_cmd *cmd, const char *value, void *data) { - return handle_cmd_ps(data, cmd, false); + return verify_subscr_cs_ps_enabled(cmd, value, data); } - -CTRL_CMD_DEFINE_WO_NOVRF(status_ps, "status-ps"); -static int set_status_ps(struct ctrl_cmd *cmd, void *data) +static int get_subscr_cs_enabled(struct ctrl_cmd *cmd, void *data) { - struct hlr *ctx = data; - struct lu_operation *luop = lu_op_alloc(ctx->gs); - if (!luop) { - cmd->reply = "Internal HLR error"; - return CTRL_CMD_ERROR; - } - - if (!lu_op_fill_subscr(luop, ctx->dbc, cmd->value)) { - cmd->reply = "Subscriber Unknown in HLR"; - return CTRL_CMD_ERROR; - } - - cmd->reply = luop->subscr.nam_ps ? "1" : "0"; - - return CTRL_CMD_REPLY; + return get_subscr_cs_ps_enabled(cmd, data, false); +} +static int set_subscr_cs_enabled(struct ctrl_cmd *cmd, void *data) +{ + return set_subscr_cs_ps_enabled(cmd, data, false); } int hlr_ctrl_cmds_install() { int rc = 0; - rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_enable_ps); - rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_disable_ps); - rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_status_ps); + rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_info); + rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_info_aud); + rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_info_all); + rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_ps_enabled); + rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_cs_enabled); return rc; } -struct ctrl_handle *hlr_controlif_setup(struct hlr *ctx, - struct osmo_gsup_server *gs) +static int hlr_ctrl_node_lookup(void *data, vector vline, int *node_type, + void **node_data, int *i) +{ + const char *token = vector_slot(vline, *i); + + switch (*node_type) { + case CTRL_NODE_ROOT: + if (strcmp(token, "subscriber") != 0) + return 0; + *node_data = NULL; + *node_type = CTRL_NODE_SUBSCR; + break; + case CTRL_NODE_SUBSCR: + if (!startswith(token, "by-")) + return 0; + *node_data = (void*)token; + *node_type = CTRL_NODE_SUBSCR_BY; + break; + default: + return 0; + } + + return 1; +} + +struct ctrl_handle *hlr_controlif_setup(struct hlr *hlr) { int rc; - struct ctrl_handle *hdl = ctrl_interface_setup_dynip(ctx, - ctx->ctrl_bind_addr, - OSMO_CTRL_PORT_HLR, - NULL); + struct ctrl_handle *hdl; + + hdl = ctrl_interface_setup_dynip2(hlr, + hlr->ctrl_bind_addr, + OSMO_CTRL_PORT_HLR, + hlr_ctrl_node_lookup, + _LAST_CTRL_NODE_HLR); if (!hdl) return NULL; diff --git a/src/ctrl.h b/src/ctrl.h index 663de30..3f9ba3f 100644 --- a/src/ctrl.h +++ b/src/ctrl.h @@ -24,8 +24,11 @@ #include <osmocom/ctrl/control_if.h> -#include "gsup_server.h" +enum hlr_ctrl_node { + CTRL_NODE_SUBSCR = _LAST_CTRL_NODE, + CTRL_NODE_SUBSCR_BY, + _LAST_CTRL_NODE_HLR +}; int hlr_ctrl_cmds_install(); -struct ctrl_handle *hlr_controlif_setup(struct hlr *ctx, - struct osmo_gsup_server *gs); +struct ctrl_handle *hlr_controlif_setup(struct hlr *hlr); diff --git a/src/hlr.c b/src/hlr.c index b32f709..6310526 100644 --- a/src/hlr.c +++ b/src/hlr.c @@ -474,7 +474,7 @@ } g_hlr->ctrl_bind_addr = ctrl_vty_get_bind_addr(); - g_hlr->ctrl = hlr_controlif_setup(g_hlr, g_hlr->gs); + g_hlr->ctrl = hlr_controlif_setup(g_hlr); osmo_init_ignore_signals(); signal(SIGINT, &signal_hdlr); diff --git a/tests/test_subscriber.ctrl b/tests/test_subscriber.ctrl index 3284ae5..30dae00 100644 --- a/tests/test_subscriber.ctrl +++ b/tests/test_subscriber.ctrl @@ -1,27 +1,414 @@ -GET 1 invalid -ERROR 1 Command not found -SET 2 invalid nonsense -ERROR 2 Command not found +GET 1 subscriber.by-imsi-901990000000001.info +GET_REPLY 1 subscriber.by-imsi-901990000000001.info +id 1 +imsi 901990000000001 +msisdn 1 -SET 3 enable-ps 901990000000001 -SET_REPLY 3 enable-ps OK -SET 4 status-ps 901990000000001 -SET_REPLY 4 status-ps 1 -SET 5 enable-ps 901990000000001 -SET_REPLY 5 enable-ps OK -SET 6 status-ps 901990000000001 -SET_REPLY 6 status-ps 1 +GET 2 subscriber.by-imsi-901990000000001.info-aud +GET_REPLY 2 subscriber.by-imsi-901990000000001.info-aud +aud2g.algo COMP128v1 +aud2g.ki 000102030405060708090a0b0c0d0e0f -SET 7 disable-ps 901990000000001 -SET_REPLY 7 disable-ps OK -SET 8 status-ps 901990000000001 -SET_REPLY 8 status-ps 0 -SET 9 disable-ps 901990000000001 -SET_REPLY 9 disable-ps OK -SET 10 status-ps 901990000000001 -SET_REPLY 10 status-ps 0 +GET 3 subscriber.by-imsi-901990000000001.info-all +GET_REPLY 3 subscriber.by-imsi-901990000000001.info-all +id 1 +imsi 901990000000001 +msisdn 1 +aud2g.algo COMP128v1 +aud2g.ki 000102030405060708090a0b0c0d0e0f -SET 11 enable-ps 901990000000001 -SET_REPLY 11 enable-ps OK -SET 12 status-ps 901990000000001 -SET_REPLY 12 status-ps 1 +GET 4 subscriber.by-imsi-901990000000002.info +GET_REPLY 4 subscriber.by-imsi-901990000000002.info +id 2 +imsi 901990000000002 + +GET 5 subscriber.by-imsi-901990000000002.info-aud +GET_REPLY 5 subscriber.by-imsi-901990000000002.info-aud +aud3g.algo MILENAGE +aud3g.k 000102030405060708090a0b0c0d0e0f +aud3g.opc 101112131415161718191a1b1c1d1e1f +aud3g.ind_bitlen 5 +aud3g.sqn 0 + +GET 6 subscriber.by-imsi-901990000000002.info-all +GET_REPLY 6 subscriber.by-imsi-901990000000002.info-all +id 2 +imsi 901990000000002 +aud3g.algo MILENAGE +aud3g.k 000102030405060708090a0b0c0d0e0f +aud3g.opc 101112131415161718191a1b1c1d1e1f +aud3g.ind_bitlen 5 +aud3g.sqn 0 + +GET 7 subscriber.by-imsi-901990000000003.info +GET_REPLY 7 subscriber.by-imsi-901990000000003.info +id 3 +imsi 901990000000003 +msisdn 103 + +GET 8 subscriber.by-imsi-901990000000003.info-aud +GET_REPLY 8 subscriber.by-imsi-901990000000003.info-aud +aud2g.algo COMP128v1 +aud2g.ki 000102030405060708090a0b0c0d0e0f +aud3g.algo MILENAGE +aud3g.k 000102030405060708090a0b0c0d0e0f +aud3g.opc 101112131415161718191a1b1c1d1e1f +aud3g.ind_bitlen 5 +aud3g.sqn 0 + +GET 9 subscriber.by-imsi-901990000000003.info-all +GET_REPLY 9 subscriber.by-imsi-901990000000003.info-all +id 3 +imsi 901990000000003 +msisdn 103 +aud2g.algo COMP128v1 +aud2g.ki 000102030405060708090a0b0c0d0e0f +aud3g.algo MILENAGE +aud3g.k 000102030405060708090a0b0c0d0e0f +aud3g.opc 101112131415161718191a1b1c1d1e1f +aud3g.ind_bitlen 5 +aud3g.sqn 0 + +GET 10 subscriber.by-imsi-901990000000003.ps-enabled +GET_REPLY 10 subscriber.by-imsi-901990000000003.ps-enabled 1 + +SET 11 subscriber.by-imsi-901990000000003.ps-enabled 0 +SET_REPLY 11 subscriber.by-imsi-901990000000003.ps-enabled OK +GET 12 subscriber.by-imsi-901990000000003.ps-enabled +GET_REPLY 12 subscriber.by-imsi-901990000000003.ps-enabled 0 + +GET 13 subscriber.by-imsi-901990000000003.info +GET_REPLY 13 subscriber.by-imsi-901990000000003.info +id 3 +imsi 901990000000003 +msisdn 103 +nam_ps 0 + +SET 14 subscriber.by-imsi-901990000000003.ps-enabled 0 +SET_REPLY 14 subscriber.by-imsi-901990000000003.ps-enabled OK +GET 15 subscriber.by-imsi-901990000000003.ps-enabled +GET_REPLY 15 subscriber.by-imsi-901990000000003.ps-enabled 0 + +SET 16 subscriber.by-imsi-901990000000003.ps-enabled 1 +SET_REPLY 16 subscriber.by-imsi-901990000000003.ps-enabled OK +GET 17 subscriber.by-imsi-901990000000003.ps-enabled +GET_REPLY 17 subscriber.by-imsi-901990000000003.ps-enabled 1 + +GET 18 subscriber.by-imsi-901990000000003.info +GET_REPLY 18 subscriber.by-imsi-901990000000003.info +id 3 +imsi 901990000000003 +msisdn 103 + +SET 19 subscriber.by-imsi-901990000000003.ps-enabled 1 +SET_REPLY 19 subscriber.by-imsi-901990000000003.ps-enabled OK +GET 20 subscriber.by-imsi-901990000000003.ps-enabled +GET_REPLY 20 subscriber.by-imsi-901990000000003.ps-enabled 1 + +GET 21 subscriber.by-imsi-901990000000003.cs-enabled +GET_REPLY 21 subscriber.by-imsi-901990000000003.cs-enabled 1 + +SET 22 subscriber.by-imsi-901990000000003.cs-enabled 0 +SET_REPLY 22 subscriber.by-imsi-901990000000003.cs-enabled OK +GET 23 subscriber.by-imsi-901990000000003.cs-enabled +GET_REPLY 23 subscriber.by-imsi-901990000000003.cs-enabled 0 + +GET 24 subscriber.by-imsi-901990000000003.info +GET_REPLY 24 subscriber.by-imsi-901990000000003.info +id 3 +imsi 901990000000003 +msisdn 103 +nam_cs 0 + +SET 25 subscriber.by-imsi-901990000000003.cs-enabled 0 +SET_REPLY 25 subscriber.by-imsi-901990000000003.cs-enabled OK +GET 26 subscriber.by-imsi-901990000000003.cs-enabled +GET_REPLY 26 subscriber.by-imsi-901990000000003.cs-enabled 0 + +SET 27 subscriber.by-imsi-901990000000003.cs-enabled 1 +SET_REPLY 27 subscriber.by-imsi-901990000000003.cs-enabled OK +GET 28 subscriber.by-imsi-901990000000003.cs-enabled +GET_REPLY 28 subscriber.by-imsi-901990000000003.cs-enabled 1 + +GET 29 subscriber.by-imsi-901990000000003.info +GET_REPLY 29 subscriber.by-imsi-901990000000003.info +id 3 +imsi 901990000000003 +msisdn 103 + +SET 30 subscriber.by-imsi-901990000000003.cs-enabled 1 +SET_REPLY 30 subscriber.by-imsi-901990000000003.cs-enabled OK +GET 31 subscriber.by-imsi-901990000000003.cs-enabled +GET_REPLY 31 subscriber.by-imsi-901990000000003.cs-enabled 1 + +SET 32 subscriber.by-imsi-901990000000003.ps-enabled 0 +SET_REPLY 32 subscriber.by-imsi-901990000000003.ps-enabled OK +SET 33 subscriber.by-imsi-901990000000003.cs-enabled 0 +SET_REPLY 33 subscriber.by-imsi-901990000000003.cs-enabled OK +GET 34 subscriber.by-imsi-901990000000003.info +GET_REPLY 34 subscriber.by-imsi-901990000000003.info +id 3 +imsi 901990000000003 +msisdn 103 +nam_cs 0 +nam_ps 0 + +SET 35 subscriber.by-imsi-901990000000003.ps-enabled 1 +SET_REPLY 35 subscriber.by-imsi-901990000000003.ps-enabled OK +SET 36 subscriber.by-imsi-901990000000003.cs-enabled 1 +SET_REPLY 36 subscriber.by-imsi-901990000000003.cs-enabled OK +GET 37 subscriber.by-imsi-901990000000003.info +GET_REPLY 37 subscriber.by-imsi-901990000000003.info +id 3 +imsi 901990000000003 +msisdn 103 + + + +GET 38 subscriber.by-msisdn-103.info +GET_REPLY 38 subscriber.by-msisdn-103.info +id 3 +imsi 901990000000003 +msisdn 103 + +GET 39 subscriber.by-msisdn-103.info-aud +GET_REPLY 39 subscriber.by-msisdn-103.info-aud +aud2g.algo COMP128v1 +aud2g.ki 000102030405060708090a0b0c0d0e0f +aud3g.algo MILENAGE +aud3g.k 000102030405060708090a0b0c0d0e0f +aud3g.opc 101112131415161718191a1b1c1d1e1f +aud3g.ind_bitlen 5 +aud3g.sqn 0 + +GET 40 subscriber.by-msisdn-103.info-all +GET_REPLY 40 subscriber.by-msisdn-103.info-all +id 3 +imsi 901990000000003 +msisdn 103 +aud2g.algo COMP128v1 +aud2g.ki 000102030405060708090a0b0c0d0e0f +aud3g.algo MILENAGE +aud3g.k 000102030405060708090a0b0c0d0e0f +aud3g.opc 101112131415161718191a1b1c1d1e1f +aud3g.ind_bitlen 5 +aud3g.sqn 0 + +GET 41 subscriber.by-msisdn-103.ps-enabled +GET_REPLY 41 subscriber.by-msisdn-103.ps-enabled 1 + +SET 42 subscriber.by-msisdn-103.ps-enabled 0 +SET_REPLY 42 subscriber.by-msisdn-103.ps-enabled OK +GET 43 subscriber.by-msisdn-103.ps-enabled +GET_REPLY 43 subscriber.by-msisdn-103.ps-enabled 0 + +GET 44 subscriber.by-msisdn-103.info +GET_REPLY 44 subscriber.by-msisdn-103.info +id 3 +imsi 901990000000003 +msisdn 103 +nam_ps 0 + +SET 45 subscriber.by-msisdn-103.ps-enabled 0 +SET_REPLY 45 subscriber.by-msisdn-103.ps-enabled OK +GET 46 subscriber.by-msisdn-103.ps-enabled +GET_REPLY 46 subscriber.by-msisdn-103.ps-enabled 0 + +SET 47 subscriber.by-msisdn-103.ps-enabled 1 +SET_REPLY 47 subscriber.by-msisdn-103.ps-enabled OK +GET 48 subscriber.by-msisdn-103.ps-enabled +GET_REPLY 48 subscriber.by-msisdn-103.ps-enabled 1 + +GET 49 subscriber.by-msisdn-103.info +GET_REPLY 49 subscriber.by-msisdn-103.info +id 3 +imsi 901990000000003 +msisdn 103 + +SET 50 subscriber.by-msisdn-103.ps-enabled 1 +SET_REPLY 50 subscriber.by-msisdn-103.ps-enabled OK +GET 51 subscriber.by-msisdn-103.ps-enabled +GET_REPLY 51 subscriber.by-msisdn-103.ps-enabled 1 + +GET 52 subscriber.by-msisdn-103.cs-enabled +GET_REPLY 52 subscriber.by-msisdn-103.cs-enabled 1 + +SET 53 subscriber.by-msisdn-103.cs-enabled 0 +SET_REPLY 53 subscriber.by-msisdn-103.cs-enabled OK +GET 54 subscriber.by-msisdn-103.cs-enabled +GET_REPLY 54 subscriber.by-msisdn-103.cs-enabled 0 + +GET 55 subscriber.by-msisdn-103.info +GET_REPLY 55 subscriber.by-msisdn-103.info +id 3 +imsi 901990000000003 +msisdn 103 +nam_cs 0 + +SET 56 subscriber.by-msisdn-103.cs-enabled 0 +SET_REPLY 56 subscriber.by-msisdn-103.cs-enabled OK +GET 57 subscriber.by-msisdn-103.cs-enabled +GET_REPLY 57 subscriber.by-msisdn-103.cs-enabled 0 + +SET 58 subscriber.by-msisdn-103.cs-enabled 1 +SET_REPLY 58 subscriber.by-msisdn-103.cs-enabled OK +GET 59 subscriber.by-msisdn-103.cs-enabled +GET_REPLY 59 subscriber.by-msisdn-103.cs-enabled 1 + +GET 60 subscriber.by-msisdn-103.info +GET_REPLY 60 subscriber.by-msisdn-103.info +id 3 +imsi 901990000000003 +msisdn 103 + +SET 61 subscriber.by-msisdn-103.cs-enabled 1 +SET_REPLY 61 subscriber.by-msisdn-103.cs-enabled OK +GET 62 subscriber.by-msisdn-103.cs-enabled +GET_REPLY 62 subscriber.by-msisdn-103.cs-enabled 1 + +SET 63 subscriber.by-msisdn-103.ps-enabled 0 +SET_REPLY 63 subscriber.by-msisdn-103.ps-enabled OK +SET 64 subscriber.by-msisdn-103.cs-enabled 0 +SET_REPLY 64 subscriber.by-msisdn-103.cs-enabled OK +GET 65 subscriber.by-msisdn-103.info +GET_REPLY 65 subscriber.by-msisdn-103.info +id 3 +imsi 901990000000003 +msisdn 103 +nam_cs 0 +nam_ps 0 + +SET 66 subscriber.by-msisdn-103.ps-enabled 1 +SET_REPLY 66 subscriber.by-msisdn-103.ps-enabled OK +SET 67 subscriber.by-msisdn-103.cs-enabled 1 +SET_REPLY 67 subscriber.by-msisdn-103.cs-enabled OK +GET 68 subscriber.by-msisdn-103.info +GET_REPLY 68 subscriber.by-msisdn-103.info +id 3 +imsi 901990000000003 +msisdn 103 + + + +GET 69 subscriber.by-id-3.info +GET_REPLY 69 subscriber.by-id-3.info +id 3 +imsi 901990000000003 +msisdn 103 + +GET 70 subscriber.by-id-3.info-aud +GET_REPLY 70 subscriber.by-id-3.info-aud +aud2g.algo COMP128v1 +aud2g.ki 000102030405060708090a0b0c0d0e0f +aud3g.algo MILENAGE +aud3g.k 000102030405060708090a0b0c0d0e0f +aud3g.opc 101112131415161718191a1b1c1d1e1f +aud3g.ind_bitlen 5 +aud3g.sqn 0 + +GET 71 subscriber.by-id-3.info-all +GET_REPLY 71 subscriber.by-id-3.info-all +id 3 +imsi 901990000000003 +msisdn 103 +aud2g.algo COMP128v1 +aud2g.ki 000102030405060708090a0b0c0d0e0f +aud3g.algo MILENAGE +aud3g.k 000102030405060708090a0b0c0d0e0f +aud3g.opc 101112131415161718191a1b1c1d1e1f +aud3g.ind_bitlen 5 +aud3g.sqn 0 + +GET 72 subscriber.by-id-3.ps-enabled +GET_REPLY 72 subscriber.by-id-3.ps-enabled 1 + +SET 73 subscriber.by-id-3.ps-enabled 0 +SET_REPLY 73 subscriber.by-id-3.ps-enabled OK +GET 74 subscriber.by-id-3.ps-enabled +GET_REPLY 74 subscriber.by-id-3.ps-enabled 0 + +GET 75 subscriber.by-id-3.info +GET_REPLY 75 subscriber.by-id-3.info +id 3 +imsi 901990000000003 +msisdn 103 +nam_ps 0 + +SET 76 subscriber.by-id-3.ps-enabled 0 +SET_REPLY 76 subscriber.by-id-3.ps-enabled OK +GET 77 subscriber.by-id-3.ps-enabled +GET_REPLY 77 subscriber.by-id-3.ps-enabled 0 + +SET 78 subscriber.by-id-3.ps-enabled 1 +SET_REPLY 78 subscriber.by-id-3.ps-enabled OK +GET 79 subscriber.by-id-3.ps-enabled +GET_REPLY 79 subscriber.by-id-3.ps-enabled 1 + +GET 80 subscriber.by-id-3.info +GET_REPLY 80 subscriber.by-id-3.info +id 3 +imsi 901990000000003 +msisdn 103 + +SET 81 subscriber.by-id-3.ps-enabled 1 +SET_REPLY 81 subscriber.by-id-3.ps-enabled OK +GET 82 subscriber.by-id-3.ps-enabled +GET_REPLY 82 subscriber.by-id-3.ps-enabled 1 + +GET 83 subscriber.by-id-3.cs-enabled +GET_REPLY 83 subscriber.by-id-3.cs-enabled 1 + +SET 84 subscriber.by-id-3.cs-enabled 0 +SET_REPLY 84 subscriber.by-id-3.cs-enabled OK +GET 85 subscriber.by-id-3.cs-enabled +GET_REPLY 85 subscriber.by-id-3.cs-enabled 0 + +GET 86 subscriber.by-id-3.info +GET_REPLY 86 subscriber.by-id-3.info +id 3 +imsi 901990000000003 +msisdn 103 +nam_cs 0 + +SET 87 subscriber.by-id-3.cs-enabled 0 +SET_REPLY 87 subscriber.by-id-3.cs-enabled OK +GET 88 subscriber.by-id-3.cs-enabled +GET_REPLY 88 subscriber.by-id-3.cs-enabled 0 + +SET 89 subscriber.by-id-3.cs-enabled 1 +SET_REPLY 89 subscriber.by-id-3.cs-enabled OK +GET 90 subscriber.by-id-3.cs-enabled +GET_REPLY 90 subscriber.by-id-3.cs-enabled 1 + +GET 91 subscriber.by-id-3.info +GET_REPLY 91 subscriber.by-id-3.info +id 3 +imsi 901990000000003 +msisdn 103 + +SET 92 subscriber.by-id-3.cs-enabled 1 +SET_REPLY 92 subscriber.by-id-3.cs-enabled OK +GET 93 subscriber.by-id-3.cs-enabled +GET_REPLY 93 subscriber.by-id-3.cs-enabled 1 + +SET 94 subscriber.by-id-3.ps-enabled 0 +SET_REPLY 94 subscriber.by-id-3.ps-enabled OK +SET 95 subscriber.by-id-3.cs-enabled 0 +SET_REPLY 95 subscriber.by-id-3.cs-enabled OK +GET 96 subscriber.by-id-3.info +GET_REPLY 96 subscriber.by-id-3.info +id 3 +imsi 901990000000003 +msisdn 103 +nam_cs 0 +nam_ps 0 + +SET 97 subscriber.by-id-3.ps-enabled 1 +SET_REPLY 97 subscriber.by-id-3.ps-enabled OK +SET 98 subscriber.by-id-3.cs-enabled 1 +SET_REPLY 98 subscriber.by-id-3.cs-enabled OK +GET 99 subscriber.by-id-3.info +GET_REPLY 99 subscriber.by-id-3.info +id 3 +imsi 901990000000003 +msisdn 103 diff --git a/tests/test_subscriber.sql b/tests/test_subscriber.sql index 0767d48..decd7d2 100644 --- a/tests/test_subscriber.sql +++ b/tests/test_subscriber.sql @@ -1,6 +1,6 @@ -- 2G only subscriber -INSERT INTO subscriber (id, imsi) VALUES (1, '901990000000001'); +INSERT INTO subscriber (id, imsi, msisdn) VALUES (1, '901990000000001', '1'); INSERT INTO auc_2g (subscriber_id, algo_id_2g, ki) VALUES (1, 1, '000102030405060708090a0b0c0d0e0f'); -- 3G only subscriber @@ -8,6 +8,6 @@ INSERT INTO auc_3g (subscriber_id, algo_id_3g, k, opc, sqn) VALUES (2, 5, '000102030405060708090a0b0c0d0e0f', '101112131415161718191a1b1c1d1e1f', 0); -- 2G + 3G subscriber -INSERT INTO subscriber (id, imsi) VALUES (3, '901990000000003'); +INSERT INTO subscriber (id, imsi, msisdn) VALUES (3, '901990000000003', '103'); INSERT INTO auc_2g (subscriber_id, algo_id_2g, ki) VALUES (3, 1, '000102030405060708090a0b0c0d0e0f'); INSERT INTO auc_3g (subscriber_id, algo_id_3g, k, opc, sqn) VALUES (3, 5, '000102030405060708090a0b0c0d0e0f', '101112131415161718191a1b1c1d1e1f', 0); diff --git a/tests/test_subscriber.vty b/tests/test_subscriber.vty index 2e0bdce..2da455f 100644 --- a/tests/test_subscriber.vty +++ b/tests/test_subscriber.vty @@ -305,6 +305,7 @@ OPC=cededeffacedacefacedbadfadedbeef IND-bitlen=23 +OsmoHLR# subscriber imsi 123456789023000 update aud3g milenage k Deaf0ff1ceD0d0DabbedD1ced1ceF00d op C01ffedC1cadaeAc1d1f1edAcac1aB0a OsmoHLR# subscriber imsi 123456789023000 update aud3g milenage k Deaf0ff1ceD0d0DabbedD1ced1ceF00d op CoiffedCicadaeAcidifiedAcaciaBoa % Invalid value for OP: 'CoiffedCicadaeAcidifiedAcaciaBoa' OsmoHLR# subscriber imsi 123456789023000 show @@ -313,8 +314,8 @@ MSISDN: 423 3G auth: MILENAGE K=deaf0ff1ced0d0dabbedd1ced1cef00d - OPC=cededeffacedacefacedbadfadedbeef - IND-bitlen=23 + OP=c01ffedc1cadaeac1d1f1edacac1ab0a + IND-bitlen=5 OsmoHLR# subscriber id 1 update aud2g comp128v2 ki CededEffacedAceFacedBadFadedBeef OsmoHLR# subscriber id 1 show @@ -325,8 +326,8 @@ KI=cededeffacedacefacedbadfadedbeef 3G auth: MILENAGE K=deaf0ff1ced0d0dabbedd1ced1cef00d - OPC=cededeffacedacefacedbadfadedbeef - IND-bitlen=23 + OP=c01ffedc1cadaeac1d1f1edacac1ab0a + IND-bitlen=5 OsmoHLR# subscriber imsi 123456789023000 delete % Deleted subscriber for IMSI '123456789023000' diff --git a/tests/test_subscriber_errors.ctrl b/tests/test_subscriber_errors.ctrl new file mode 100644 index 0000000..2f64fdb --- /dev/null +++ b/tests/test_subscriber_errors.ctrl @@ -0,0 +1,107 @@ +GET 1 invalid +ERROR 1 Command not found +SET 2 invalid nonsense +ERROR 2 Command not found + +GET 3 subscriber.by-imsi-nonsense.info +ERROR 3 Invalid value part of 'by-xxx-value' selector. +GET 4 subscriber.by-msisdn-nonsense.info +ERROR 4 Invalid value part of 'by-xxx-value' selector. +GET 5 subscriber.by-id-nonsense.info +ERROR 5 Invalid value part of 'by-xxx-value' selector. + +GET 6 subscriber +ERROR 6 Command not present. +GET 7 subscriber. +ERROR 7 Command not present. +GET 8 subscriber.by-nonsense +ERROR 8 Command not present. +GET 9 subscriber.by-nonsense- +ERROR 9 Command not present. +GET 10 subscriber.by-nonsense-123456 +ERROR 10 Command not present. +GET 11 subscriber.by-nonsense-123456. +ERROR 11 Command not present. +GET 12 subscriber.by-imsi- +ERROR 12 Command not present. +GET 13 subscriber.by-imsi-. +ERROR 13 Command not present. +GET 14 subscriber.by-imsi-901990000000003 +ERROR 14 Command not present. +GET 15 subscriber.by-imsi-901990000000003. +ERROR 15 Command not present. + +GET 16 subscriber.by-nonsense-123456.info +ERROR 16 Not a known subscriber 'by-xxx-' selector. +GET 17 subscriber.by-123456.info +ERROR 17 Not a known subscriber 'by-xxx-' selector. + +GET 18 subscriber.by-imsi-.info +ERROR 18 Invalid value part of 'by-xxx-value' selector. +GET 19 subscriber.by-imsi--.info +ERROR 19 Invalid value part of 'by-xxx-value' selector. + +GET 20 subscriber.by-imsi-12345678901234567.info +ERROR 20 Invalid value part of 'by-xxx-value' selector. +GET 21 subscriber.by-imsi-12345.info +ERROR 21 Invalid value part of 'by-xxx-value' selector. +GET 22 subscriber.by-imsi-1234567890123456.info +ERROR 22 Invalid value part of 'by-xxx-value' selector. + +GET 23 subscriber.by-id-99999999999999999999999999.info +ERROR 23 Invalid value part of 'by-xxx-value' selector. +GET 24 subscriber.by-id-9223372036854775807.info +ERROR 24 No such subscriber. +GET 25 subscriber.by-id-9223372036854775808.info +ERROR 25 Invalid value part of 'by-xxx-value' selector. +GET 26 subscriber.by-id--1.info +ERROR 26 No such subscriber. +GET 27 subscriber.by-id--9223372036854775808.info +ERROR 27 No such subscriber. +GET 28 subscriber.by-id--9223372036854775809.info +ERROR 28 Invalid value part of 'by-xxx-value' selector. + +GET 29 subscriber.by-id-1+1.info +ERROR 29 Invalid value part of 'by-xxx-value' selector. +GET 30 subscriber.by-id--.info +ERROR 30 Invalid value part of 'by-xxx-value' selector. +GET 31 subscriber.by-id-+1.info +ERROR 31 Invalid value part of 'by-xxx-value' selector. +GET 32 subscriber.by-id-+-1.info +ERROR 32 Invalid value part of 'by-xxx-value' selector. +GET 33 subscriber.by-id--+1.info +ERROR 33 Invalid value part of 'by-xxx-value' selector. +GET 34 subscriber.by-id-++1.info +ERROR 34 Invalid value part of 'by-xxx-value' selector. +GET 35 subscriber.by-id---1.info +ERROR 35 Invalid value part of 'by-xxx-value' selector. + +GET 36 subscriber.by-id- 1.info +ERROR 36 Command not present. +GET 37 subscriber.by-id-+ 1.info +ERROR 37 Command not present. +GET 38 subscriber.by-id-- 1.info +ERROR 38 Command not present. + + +SET 39 subscriber.by-imsi-901990000000001.info foo +ERROR 39 Read Only attribute +SET 40 subscriber.by-imsi-901990000000001.info-aud foo +ERROR 40 Read Only attribute +SET 41 subscriber.by-imsi-901990000000001.info-all foo +ERROR 41 Read Only attribute + +SET 42 subscriber.by-imsi-901990000000001.ps-enabled nonsense +ERROR 42 Value failed verification. +SET 43 subscriber.by-imsi-901990000000001.cs-enabled nonsense +ERROR 43 Value failed verification. + +SET 44 subscriber.by-imsi-901990000000001.ps-enabled +ERROR err Command parser error. +SET 45 subscriber.by-imsi-901990000000001.cs-enabled +ERROR err Command parser error. + +GET 46 subscriber.by-imsi-1234567890123456.ps-enabled +ERROR 46 Invalid value part of 'by-xxx-value' selector. +GET 47 subscriber.by-imsi-1234567890123456.cs-enabled +ERROR 47 Invalid value part of 'by-xxx-value' selector. -- To view, visit https://gerrit.osmocom.org/4311 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newpatchset Gerrit-Change-Id: I98ee6a06b3aa6a67adb868e0b63b0e04eb42eb50 Gerrit-PatchSet: 3 Gerrit-Project: osmo-hlr Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: Max <msuraev at sysmocom.de> Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr at sysmocom.de>