diff options
-rw-r--r-- | src/host/layer23/include/osmocom/bb/mobile/settings.h | 11 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/app_mobile.c | 1 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/settings.c | 17 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/vty_interface.c | 156 |
4 files changed, 161 insertions, 24 deletions
diff --git a/src/host/layer23/include/osmocom/bb/mobile/settings.h b/src/host/layer23/include/osmocom/bb/mobile/settings.h index 24379514..88649e36 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/settings.h +++ b/src/host/layer23/include/osmocom/bb/mobile/settings.h @@ -67,9 +67,20 @@ struct gsm_settings { /* radio */ uint16_t dsc_max; + + /* dialing */ + struct llist_head abbrev; +}; + +struct gsm_settings_abbrev { + struct llist_head list; + char abbrev[4]; + char number[32]; + char name[32]; }; int gsm_settings_init(struct osmocom_ms *ms); +int gsm_settings_exit(struct osmocom_ms *ms); char *gsm_check_imei(const char *imei, const char *sv); int gsm_random_imei(struct gsm_settings *set); diff --git a/src/host/layer23/src/mobile/app_mobile.c b/src/host/layer23/src/mobile/app_mobile.c index 8d3ea8a9..650b450a 100644 --- a/src/host/layer23/src/mobile/app_mobile.c +++ b/src/host/layer23/src/mobile/app_mobile.c @@ -149,6 +149,7 @@ int mobile_exit(struct osmocom_ms *ms) gsm_subscr_exit(ms); gsm48_cc_exit(ms); gsm_sim_exit(ms); + gsm_settings_exit(ms); printf("Power off!\n"); diff --git a/src/host/layer23/src/mobile/settings.c b/src/host/layer23/src/mobile/settings.c index 37e0dd84..1f08cc2d 100644 --- a/src/host/layer23/src/mobile/settings.c +++ b/src/host/layer23/src/mobile/settings.c @@ -68,6 +68,23 @@ int gsm_settings_init(struct osmocom_ms *ms) if (sup->half_v1 || sup->half_v3) set->half = 1; + INIT_LLIST_HEAD(&set->abbrev); + + return 0; +} + +int gsm_settings_exit(struct osmocom_ms *ms) +{ + struct gsm_settings *set = &ms->settings; + struct gsm_settings_abbrev *abbrev; + + while (!llist_empty(&set->abbrev)) { + abbrev = llist_entry(set->abbrev.next, + struct gsm_settings_abbrev, list); + llist_del(&abbrev->list); + talloc_free(abbrev); + } + return 0; } diff --git a/src/host/layer23/src/mobile/vty_interface.c b/src/host/layer23/src/mobile/vty_interface.c index e35a09f3..35cab315 100644 --- a/src/host/layer23/src/mobile/vty_interface.c +++ b/src/host/layer23/src/mobile/vty_interface.c @@ -27,6 +27,7 @@ #include <osmocore/utils.h> #include <osmocore/gsm48.h> +#include <osmocore/talloc.h> #include <osmocom/bb/common/osmocom_data.h> #include <osmocom/bb/common/networks.h> @@ -36,6 +37,8 @@ #include <osmocom/bb/mobile/gps.h> #include <osmocom/vty/telnet_interface.h> +void *l23_ctx; + int mncc_call(struct osmocom_ms *ms, char *number); int mncc_hangup(struct osmocom_ms *ms); int mncc_answer(struct osmocom_ms *ms); @@ -83,6 +86,31 @@ static void print_vty(void *priv, const char *fmt, ...) } } +int vty_check_number(struct vty *vty, const char *number) +{ + int i; + + for (i = 0; i < strlen(number); i++) { + /* allow international notation with + */ + if (i == 0 && number[i] == '+') + continue; + if (!(number[i] >= '0' && number[i] <= '9') + && number[i] != '*' + && number[i] != '#' + && !(number[i] >= 'a' && number[i] <= 'c')) { + vty_out(vty, "Invalid digit '%c' of number!%s", + number[i], VTY_NEWLINE); + return -EINVAL; + } + } + if (number[0] == '\0' || (number[0] == '+' && number[1] == '\0')) { + vty_out(vty, "Given number has no digits!%s", VTY_NEWLINE); + return -EINVAL; + } + + return 0; +} + int vty_reading = 0; static void vty_restart(struct vty *vty) @@ -633,7 +661,8 @@ DEFUN(call, call_cmd, "call MS_NAME (NUMBER|emergency|answer|hangup|hold)", { struct osmocom_ms *ms; struct gsm_settings *set; - int i; + struct gsm_settings_abbrev *abbrev; + char *number; ms = get_ms(argv[0], vty); if (!ms) @@ -646,33 +675,27 @@ DEFUN(call, call_cmd, "call MS_NAME (NUMBER|emergency|answer|hangup|hold)", return CMD_WARNING; } - if (!strcmp(argv[1], "emergency")) - mncc_call(ms, (char *)argv[1]); - else switch (argv[1][0]) { - case 'a': + number = (char *)argv[1]; + if (!strcmp(number, "emergency")) + mncc_call(ms, number); + else if (!strcmp(number, "answer")) mncc_answer(ms); - break; - case 'h': - if (argv[1][1] == 'a') - mncc_hangup(ms); - else - mncc_hold(ms); - break; - default: - for (i = 0; i < strlen(argv[1]); i++) { - /* allow international notation with + */ - if (i == 0 && argv[1][i] == '+') - continue; - if (!(argv[1][i] >= '0' && argv[1][i] <= '9') - && argv[1][i] != '*' - && argv[1][i] != '#' - && !(argv[1][i] >= 'a' && argv[1][i] <= 'c')) { - vty_out(vty, "Invalid digit '%c'%s", argv[1][i], + else if (!strcmp(number, "hangup")) + mncc_hangup(ms); + else if (!strcmp(number, "hold")) + mncc_hold(ms); + else { + llist_for_each_entry(abbrev, &set->abbrev, list) { + if (!strcmp(number, abbrev->abbrev)) { + number = abbrev->number; + vty_out(vty, "Dialing number '%s'%s", number, VTY_NEWLINE); - return CMD_WARNING; + break; } } - mncc_call(ms, (char *)argv[1]); + if (vty_check_number(vty, number)) + return CMD_WARNING; + mncc_call(ms, number); } return CMD_SUCCESS; @@ -828,6 +851,7 @@ static void config_write_ms_single(struct vty *vty, struct osmocom_ms *ms) { struct gsm_settings *set = &ms->settings; struct gsm_support *sup = &ms->support; + struct gsm_settings_abbrev *abbrev; vty_out(vty, "ms %s%s", ms->name, VTY_NEWLINE); switch(set->sim_type) { @@ -894,6 +918,14 @@ static void config_write_ms_single(struct vty *vty, struct osmocom_ms *ms) else vty_out(vty, " no codec half-speed%s", VTY_NEWLINE); } + if (llist_empty(&set->abbrev)) + vty_out(vty, " no abbrev%s", VTY_NEWLINE); + else { + llist_for_each_entry(abbrev, &set->abbrev, list) + vty_out(vty, " abbrev %s %s%s%s%s", abbrev->abbrev, + abbrev->number, (abbrev->name[0]) ? " " : "", + abbrev->name, VTY_NEWLINE); + } vty_out(vty, " support%s", VTY_NEWLINE); SUP_WRITE(sms_ptp, "sms"); SUP_WRITE(a5_1, "a5/1"); @@ -1358,6 +1390,80 @@ DEFUN(cfg_no_codec_half, cfg_ms_no_codec_half_cmd, "no codec half-speed", return CMD_SUCCESS; } +DEFUN(cfg_abbrev, cfg_ms_abbrev_cmd, "abbrev ABBREVIATION NUMBER [name]", + "Store given abbreviation number\n1-3 digits abbreviation\n" + "Number to store for the abbreviation " + "(Use digits '0123456789*#abc', and '+' to dial international)\n" + "Name of the abbreviation") +{ + struct osmocom_ms *ms = vty->index; + struct gsm_settings *set = &ms->settings; + struct gsm_settings_abbrev *abbrev; + int i; + + llist_for_each_entry(abbrev, &set->abbrev, list) { + if (!strcmp(argv[0], abbrev->abbrev)) { + vty_out(vty, "Given abbreviation '%s' already stored, " + "delete first!%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + } + + if (strlen(argv[0]) >= sizeof(abbrev->abbrev)) { + vty_out(vty, "Given abbreviation too long%s", VTY_NEWLINE); + return CMD_WARNING; + } + + for (i = 0; i < strlen(argv[0]); i++) { + if (argv[0][i] < '0' || argv[0][i] > '9') { + vty_out(vty, "Given abbreviation must have digits " + "0..9 only!%s", VTY_NEWLINE); + return CMD_WARNING; + } + } + + if (vty_check_number(vty, argv[1])) + return CMD_WARNING; + + abbrev = talloc_zero(l23_ctx, struct gsm_settings_abbrev); + if (!abbrev) { + vty_out(vty, "No Memory!%s", VTY_NEWLINE); + return CMD_WARNING; + } + llist_add_tail(&abbrev->list, &set->abbrev); + strncpy(abbrev->abbrev, argv[0], sizeof(abbrev->abbrev) - 1); + strncpy(abbrev->number, argv[1], sizeof(abbrev->number) - 1); + if (argc >= 3) + strncpy(abbrev->name, argv[2], sizeof(abbrev->name) - 1); + + return CMD_SUCCESS; +} + +DEFUN(cfg_no_abbrev, cfg_ms_no_abbrev_cmd, "no abbrev [abbreviation]", + NO_STR "Remove given abbreviation number or all numbers\n" + "Abbreviation number to remove") +{ + struct osmocom_ms *ms = vty->index; + struct gsm_settings *set = &ms->settings; + struct gsm_settings_abbrev *abbrev, *abbrev2; + uint8_t deleted = 0; + + llist_for_each_entry_safe(abbrev, abbrev2, &set->abbrev, list) { + if (argc < 1 || !strcmp(argv[0], abbrev->abbrev)) { + llist_del(&abbrev->list); + deleted = 1; + } + } + + if (argc >= 1 && !deleted) { + vty_out(vty, "Given abbreviation '%s' not found!%s", + argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + + return CMD_SUCCESS; +} + static int config_write_dummy(struct vty *vty) { return CMD_SUCCESS; @@ -1853,6 +1959,8 @@ int ms_vty_init(void) install_element(MS_NODE, &cfg_ms_codec_half_cmd); install_element(MS_NODE, &cfg_ms_codec_half_pref_cmd); install_element(MS_NODE, &cfg_ms_no_codec_half_cmd); + install_element(MS_NODE, &cfg_ms_abbrev_cmd); + install_element(MS_NODE, &cfg_ms_no_abbrev_cmd); install_element(MS_NODE, &cfg_ms_testsim_cmd); install_element(MS_NODE, &cfg_ms_support_cmd); install_node(&support_node, config_write_dummy); |