#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>
#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);
int mncc_hold(struct osmocom_ms *ms);
int mncc_retrieve(struct osmocom_ms *ms, int number);
+int mncc_dtmf(struct osmocom_ms *ms, char *dtmf);
extern struct llist_head ms_list;
extern struct llist_head active_connections;
1
};
+struct cmd_node support_node = {
+ SUPPORT_NODE,
+ "%s(support)#",
+ 1
+};
+
static void print_vty(void *priv, const char *fmt, ...)
{
char buffer[1000];
}
}
+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)
+{
+ if (vty_reading)
+ return;
+ vty_out(vty, "You must restart for change to take effect!%s",
+ VTY_NEWLINE);
+}
+
static struct osmocom_ms *get_ms(const char *name, struct vty *vty)
{
struct osmocom_ms *ms;
ms = get_ms(argv[0], vty);
if (!ms)
return CMD_WARNING;
- gsm_support_dump(&ms->support, print_vty, vty);
+ gsm_support_dump(ms, print_vty, vty);
} else {
llist_for_each_entry(ms, &ms_list, entity) {
- gsm_support_dump(&ms->support, print_vty, vty);
+ gsm_support_dump(ms, print_vty, vty);
vty_out(vty, "%s", VTY_NEWLINE);
}
}
static void gsm_states_dump(struct osmocom_ms *ms, struct vty *vty)
{
+ struct gsm_settings *set = &ms->settings;
struct gsm_trans *trans;
vty_out(vty, "Current state of MS '%s'%s", ms->name, VTY_NEWLINE);
- if (ms->settings.plmn_mode == PLMN_MODE_AUTO)
+ if (set->plmn_mode == PLMN_MODE_AUTO)
vty_out(vty, " automatic network selection: %s%s",
plmn_a_state_names[ms->plmn.state], VTY_NEWLINE);
else
vty_out(vty, " manual network selection: %s%s",
plmn_m_state_names[ms->plmn.state], VTY_NEWLINE);
- vty_out(vty, " cell selection: %s%s",
- cs_state_names[ms->cellsel.state], VTY_NEWLINE);
+ vty_out(vty, " cell selection: %s",
+ cs_state_names[ms->cellsel.state]);
+ if (ms->rrlayer.state == GSM48_RR_ST_IDLE && ms->cellsel.selected)
+ vty_out(vty, " (ARFCN %d)", ms->cellsel.sel_arfcn);
+ vty_out(vty, "%s", VTY_NEWLINE);
vty_out(vty, " radio ressource layer: %s%s",
gsm48_rr_state_names[ms->rrlayer.state], VTY_NEWLINE);
vty_out(vty, " mobility management layer: %s",
"Hold current active call\n")
{
struct osmocom_ms *ms;
- int i;
+ struct gsm_settings *set;
+ struct gsm_settings_abbrev *abbrev;
+ char *number;
ms = get_ms(argv[0], vty);
if (!ms)
return CMD_WARNING;
+ set = &ms->settings;
- switch (argv[1][0]) {
- case 'a':
+ if (set->ch_cap == GSM_CAP_SDCCH) {
+ vty_out(vty, "Basic call is not supported for SDCCH only "
+ "mobile%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ 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;
return CMD_SUCCESS;
}
+DEFUN(call_dtmf, call_dtmf_cmd, "call MS_NAME dtmf DIGITS",
+ "Make a call\nName of MS (see \"show ms\")\n"
+ "One or more DTMF digits to transmit")
+{
+ struct osmocom_ms *ms;
+ struct gsm_settings *set;
+
+ ms = get_ms(argv[0], vty);
+ if (!ms)
+ return CMD_WARNING;
+ set = &ms->settings;
+
+ if (!set->cc_dtmf) {
+ vty_out(vty, "DTMF not supported, please enable!%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ mncc_dtmf(ms, (char *)argv[1]);
+
+ return CMD_SUCCESS;
+}
+
DEFUN(network_show, network_show_cmd, "network show MS_NAME",
"Network ...\nShow results of network search (again)\n"
"Name of MS (see \"show ms\")")
{
struct osmocom_ms *ms;
+ struct gsm_settings *set;
struct gsm322_plmn *plmn;
struct gsm322_plmn_list *temp;
ms = get_ms(argv[0], vty);
if (!ms)
return CMD_WARNING;
+ set = &ms->settings;
plmn = &ms->plmn;
- if (ms->settings.plmn_mode != PLMN_MODE_AUTO
+ if (set->plmn_mode != PLMN_MODE_AUTO
&& plmn->state != GSM322_M3_NOT_ON_PLMN) {
vty_out(vty, "Start network search first!%s", VTY_NEWLINE);
return CMD_WARNING;
return CMD_SUCCESS;
}
+#define SUP_WRITE(item, cmd) \
+ if (sup->item) \
+ vty_out(vty, " %s%s%s", (set->item) ? "" : "no ", cmd, \
+ VTY_NEWLINE);
+
static void config_write_ms_single(struct vty *vty, struct osmocom_ms *ms)
{
- struct gsm_support *sup = &ms->support;
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) {
vty_out(vty, " %scall-waiting%s", (set->cw) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " %sclip%s", (set->clip) ? "" : "no ", VTY_NEWLINE);
vty_out(vty, " %sclir%s", (set->clir) ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, " test-sim%s", VTY_NEWLINE);
- vty_out(vty, " imsi %s%s", set->test_imsi, VTY_NEWLINE);
- switch (set->test_ki_type) {
- case GSM_SIM_KEY_XOR:
- vty_out(vty, " ki xor %s%s", hexdump(set->test_ki, 12),
- VTY_NEWLINE);
- break;
- case GSM_SIM_KEY_COMP128:
- vty_out(vty, " ki comp128 %s%s", hexdump(set->test_ki, 16),
- VTY_NEWLINE);
- break;
- }
- vty_out(vty, " %sbarred-access%s", (set->test_barr) ? "" : "no ",
- VTY_NEWLINE);
- if (set->test_rplmn_valid)
- vty_out(vty, " rplmn %s %s%s",
- gsm_print_mcc(set->test_rplmn_mcc),
- gsm_print_mnc(set->test_rplmn_mnc),
- VTY_NEWLINE);
- else
- vty_out(vty, " no rplmn%s", VTY_NEWLINE);
- vty_out(vty, " hplmn-search %s%s", (set->test_always) ? "everywhere"
- : "foreign-country", VTY_NEWLINE);
- vty_out(vty, " exit%s", VTY_NEWLINE);
- vty_out(vty, " min-rxlev %d%s", set->min_rxlev_db, VTY_NEWLINE);
if (set->alter_tx_power)
if (set->alter_tx_power_value)
vty_out(vty, " tx-power %d%s",
vty_out(vty, " no location-updating%s", VTY_NEWLINE);
else
vty_out(vty, " location-updating%s", VTY_NEWLINE);
- if (sup->full_v1 || sup->full_v2 || sup->full_v3) {
+ if (set->full_v1 || set->full_v2 || set->full_v3) {
/* mandatory anyway */
vty_out(vty, " codec full-speed%s%s",
(!set->half_prefer) ? " prefer" : "",
VTY_NEWLINE);
}
- if (sup->half_v1 || sup->half_v3) {
+ if (set->half_v1 || set->half_v3) {
if (set->half)
vty_out(vty, " codec half-speed%s%s",
(set->half_prefer) ? " prefer" : "",
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");
+ SUP_WRITE(a5_2, "a5/2");
+ SUP_WRITE(a5_3, "a5/3");
+ SUP_WRITE(a5_4, "a5/4");
+ SUP_WRITE(a5_5, "a5/5");
+ SUP_WRITE(a5_6, "a5/6");
+ SUP_WRITE(a5_7, "a5/7");
+ SUP_WRITE(p_gsm, "p-gsm");
+ SUP_WRITE(e_gsm, "e-gsm");
+ SUP_WRITE(r_gsm, "r-gsm");
+ SUP_WRITE(dcs, "dcs");
+ vty_out(vty, " class-900 %d%s", set->class_900, VTY_NEWLINE);
+ vty_out(vty, " class-dcs %d%s", set->class_dcs, VTY_NEWLINE);
+ switch (set->ch_cap) {
+ case GSM_CAP_SDCCH:
+ vty_out(vty, " channel-capability sdcch%s", VTY_NEWLINE);
+ break;
+ case GSM_CAP_SDCCH_TCHF:
+ vty_out(vty, " channel-capability sdcch+tchf%s", VTY_NEWLINE);
+ break;
+ case GSM_CAP_SDCCH_TCHF_TCHH:
+ vty_out(vty, " channel-capability sdcch+tchf+tchh%s",
+ VTY_NEWLINE);
+ break;
+ }
+ SUP_WRITE(full_v1, "full-speech-v1");
+ SUP_WRITE(full_v2, "full-speech-v2");
+ SUP_WRITE(full_v3, "full-speech-v3");
+ SUP_WRITE(half_v1, "half-speech-v1");
+ SUP_WRITE(half_v3, "half-speech-v3");
+ vty_out(vty, " min-rxlev %d%s", set->min_rxlev_db, VTY_NEWLINE);
+ vty_out(vty, " dsc-max %d%s", set->dsc_max, VTY_NEWLINE);
+ vty_out(vty, " exit%s", VTY_NEWLINE);
+ vty_out(vty, " test-sim%s", VTY_NEWLINE);
+ vty_out(vty, " imsi %s%s", set->test_imsi, VTY_NEWLINE);
+ switch (set->test_ki_type) {
+ case GSM_SIM_KEY_XOR:
+ vty_out(vty, " ki xor %s%s", hexdump(set->test_ki, 12),
+ VTY_NEWLINE);
+ break;
+ case GSM_SIM_KEY_COMP128:
+ vty_out(vty, " ki comp128 %s%s", hexdump(set->test_ki, 16),
+ VTY_NEWLINE);
+ break;
+ }
+ vty_out(vty, " %sbarred-access%s", (set->test_barr) ? "" : "no ",
+ VTY_NEWLINE);
+ if (set->test_rplmn_valid)
+ vty_out(vty, " rplmn %s %s%s",
+ gsm_print_mcc(set->test_rplmn_mcc),
+ gsm_print_mnc(set->test_rplmn_mnc),
+ VTY_NEWLINE);
+ else
+ vty_out(vty, " no rplmn%s", VTY_NEWLINE);
+ vty_out(vty, " hplmn-search %s%s", (set->test_always) ? "everywhere"
+ : "foreign-country", VTY_NEWLINE);
+ vty_out(vty, " exit%s", VTY_NEWLINE);
vty_out(vty, "exit%s", VTY_NEWLINE);
vty_out(vty, "!%s", VTY_NEWLINE);
}
"Use SIM from reader\nTest SIM inserted")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
switch (argv[0][0]) {
case 'n':
- ms->settings.sim_type = GSM_SIM_TYPE_NONE;
+ set->sim_type = GSM_SIM_TYPE_NONE;
break;
case 'r':
- ms->settings.sim_type = GSM_SIM_TYPE_READER;
+ set->sim_type = GSM_SIM_TYPE_READER;
break;
case 't':
- ms->settings.sim_type = GSM_SIM_TYPE_TEST;
+ set->sim_type = GSM_SIM_TYPE_TEST;
break;
default:
vty_out(vty, "unknown SIM type%s", VTY_NEWLINE);
return CMD_WARNING;
}
+ vty_restart(vty);
return CMD_SUCCESS;
}
"Manual network selection")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
struct msgb *nmsg;
if (!ms->plmn.state) {
if (argv[0][0] == 'a')
- ms->settings.plmn_mode = PLMN_MODE_AUTO;
+ set->plmn_mode = PLMN_MODE_AUTO;
else
- ms->settings.plmn_mode = PLMN_MODE_MANUAL;
+ set->plmn_mode = PLMN_MODE_MANUAL;
return CMD_SUCCESS;
}
"Software version digit")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
char *error, *sv = "0";
if (argc >= 2)
return CMD_WARNING;
}
- strcpy(ms->settings.imei, argv[0]);
- strcpy(ms->settings.imeisv, argv[0]);
- strcpy(ms->settings.imeisv + 15, sv);
+ strcpy(set->imei, argv[0]);
+ strcpy(set->imeisv, argv[0]);
+ strcpy(set->imeisv + 15, sv);
return CMD_SUCCESS;
}
"Use fixed IMEI on every power on")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.imei_random = 0;
+ set->imei_random = 0;
+ vty_restart(vty);
return CMD_SUCCESS;
}
"Number of trailing digits to randomize")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.imei_random = atoi(argv[0]);
+ set->imei_random = atoi(argv[0]);
+ vty_restart(vty);
return CMD_SUCCESS;
}
"Use special IMSI for emergency calls\n15 digits IMSI")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
char *error;
error = gsm_check_imsi(argv[0]);
vty_out(vty, "%s%s", error, VTY_NEWLINE);
return CMD_WARNING;
}
- strcpy(ms->settings.emergency_imsi, argv[0]);
+ strcpy(set->emergency_imsi, argv[0]);
return CMD_SUCCESS;
}
NO_STR "Use IMSI of SIM or IMEI for emergency calls")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.emergency_imsi[0] = '\0';
+ set->emergency_imsi[0] = '\0';
return CMD_SUCCESS;
}
NO_STR "Disallow waiting calls")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.cw = 0;
+ set->cw = 0;
return CMD_SUCCESS;
}
"Allow waiting calls")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.cw = 1;
+ set->cw = 1;
return CMD_SUCCESS;
}
"Force caller ID presentation")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.clip = 1;
- ms->settings.clir = 0;
+ set->clip = 1;
+ set->clir = 0;
return CMD_SUCCESS;
}
"Force caller ID restriction")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.clip = 0;
- ms->settings.clir = 1;
+ set->clip = 0;
+ set->clir = 1;
return CMD_SUCCESS;
}
NO_STR "Disable forcing of caller ID presentation")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.clip = 0;
+ set->clip = 0;
return CMD_SUCCESS;
}
NO_STR "Disable forcing of caller ID restriction")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.clir = 0;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_min_rxlev, cfg_ms_min_rxlev_cmd, "min-rxlev <-110--47>",
- "Set the minimum receive level to select a cell\n"
- "Minimum receive level from -110 dBm to -47 dBm")
-{
- struct osmocom_ms *ms = vty->index;
-
- ms->settings.min_rxlev_db = atoi(argv[0]);
+ set->clir = 0;
return CMD_SUCCESS;
}
"Always full power\nFixed GSM power value if supported")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
switch (argv[0][0]) {
case 'a':
- ms->settings.alter_tx_power = 0;
+ set->alter_tx_power = 0;
break;
case 'f':
- ms->settings.alter_tx_power = 1;
- ms->settings.alter_tx_power_value = 0;
+ set->alter_tx_power = 1;
+ set->alter_tx_power_value = 0;
break;
}
"Fixed GSM power value if supported")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.alter_tx_power = 1;
- ms->settings.alter_tx_power_value = atoi(argv[0]);
+ set->alter_tx_power = 1;
+ set->alter_tx_power_value = atoi(argv[0]);
return CMD_SUCCESS;
}
"Delay in half bits (distance in 553.85 meter steps)")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.alter_delay = atoi(argv[0]);
+ set->alter_delay = atoi(argv[0]);
gsm48_rr_alter_delay(ms);
return CMD_SUCCESS;
NO_STR "Do not simulate a lower or higher distance from the BTS")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.alter_delay = 0;
+ set->alter_delay = 0;
gsm48_rr_alter_delay(ms);
return CMD_SUCCESS;
"Stick to the given cell\nARFCN of the cell to stick to")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.stick = 1;
- ms->settings.stick_arfcn = atoi(argv[0]);
+ set->stick = 1;
+ set->stick_arfcn = atoi(argv[0]);
return CMD_SUCCESS;
}
NO_STR "Do not stick to any cell")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.stick = 0;
+ set->stick = 0;
return CMD_SUCCESS;
}
"Allow location updating")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.no_lupd = 0;
+ set->no_lupd = 0;
return CMD_SUCCESS;
}
NO_STR "Do not allow location updating")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.no_lupd = 1;
+ set->no_lupd = 1;
return CMD_SUCCESS;
}
"Enable codec\nFull speed speech codec")
{
struct osmocom_ms *ms = vty->index;
- struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
- if (!sup->full_v1 && !sup->full_v2 && !sup->full_v3) {
+ if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
return CMD_WARNING;
}
"Enable codec\nFull speed speech codec\nPrefer this codec")
{
struct osmocom_ms *ms = vty->index;
- struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
- if (!sup->full_v1 && !sup->full_v2 && !sup->full_v3) {
+ if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
return CMD_WARNING;
}
- ms->settings.half_prefer = 0;
+ set->half_prefer = 0;
return CMD_SUCCESS;
}
"Enable codec\nHalf speed speech codec")
{
struct osmocom_ms *ms = vty->index;
- struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
- if (!sup->half_v1 && !sup->half_v3) {
+ if (!set->half_v1 && !set->half_v3) {
vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
return CMD_WARNING;
}
- ms->settings.half = 1;
+ set->half = 1;
return CMD_SUCCESS;
}
"Enable codec\nHalf speed speech codec\nPrefer this codec")
{
struct osmocom_ms *ms = vty->index;
- struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
- if (!sup->half_v1 && !sup->half_v3) {
+ if (!set->half_v1 && !set->half_v3) {
vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
return CMD_WARNING;
}
- ms->settings.half = 1;
- ms->settings.half_prefer = 1;
+ set->half = 1;
+ set->half_prefer = 1;
return CMD_SUCCESS;
}
NO_STR "Disable codec\nHalf speed speech codec")
{
struct osmocom_ms *ms = vty->index;
- struct gsm_support *sup = &ms->support;
+ struct gsm_settings *set = &ms->settings;
- if (!sup->half_v1 && !sup->half_v3) {
+ if (!set->half_v1 && !set->half_v3) {
vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
return CMD_WARNING;
}
- ms->settings.half = 0;
- ms->settings.half_prefer = 0;
+ set->half = 0;
+ set->half_prefer = 0;
return CMD_SUCCESS;
}
-/* per testsim config */
-DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim",
- "Configure test SIM emulation")
+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")
{
- vty->node = TESTSIM_NODE;
+ 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;
}
return CMD_SUCCESS;
}
+/* per support config */
+DEFUN(cfg_ms_support, cfg_ms_support_cmd, "support",
+ "Define supported features")
+{
+ vty->node = SUPPORT_NODE;
+
+ return CMD_SUCCESS;
+}
+
+#define SUP_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
+DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
+{ \
+ struct osmocom_ms *ms = vty->index; \
+ struct gsm_settings *set = &ms->settings; \
+ struct gsm_support *sup = &ms->support; \
+ if (!sup->item) { \
+ vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
+ if (vty_reading) \
+ return CMD_SUCCESS; \
+ return CMD_WARNING; \
+ } \
+ if (restart) \
+ vty_restart(vty); \
+ set->item = 1; \
+ return CMD_SUCCESS; \
+}
+
+#define SUP_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
+DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
+{ \
+ struct osmocom_ms *ms = vty->index; \
+ struct gsm_settings *set = &ms->settings; \
+ struct gsm_support *sup = &ms->support; \
+ if (!sup->item) { \
+ vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
+ if (vty_reading) \
+ return CMD_SUCCESS; \
+ return CMD_WARNING; \
+ } \
+ if (restart) \
+ vty_restart(vty); \
+ set->item = 0; \
+ return CMD_SUCCESS; \
+}
+
+#define SET_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
+DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
+{ \
+ struct osmocom_ms *ms = vty->index; \
+ struct gsm_settings *set = &ms->settings; \
+ if (restart) \
+ vty_restart(vty); \
+ set->item = 1; \
+ return CMD_SUCCESS; \
+}
+
+#define SET_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
+DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
+{ \
+ struct osmocom_ms *ms = vty->index; \
+ struct gsm_settings *set = &ms->settings; \
+ if (restart) \
+ vty_restart(vty); \
+ set->item = 0; \
+ return CMD_SUCCESS; \
+}
+
+SET_EN(cfg_ms_sup_dtmf, cfg_ms_sup_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
+SET_DI(cfg_ms_sup_no_dtmf, cfg_ms_sup_no_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
+SUP_EN(cfg_ms_sup_sms, cfg_ms_sup_sms_cmd, sms_ptp, "sms", "SMS", 0);
+SUP_DI(cfg_ms_sup_no_sms, cfg_ms_sup_no_sms_cmd, sms_ptp, "sms", "SMS", 0);
+SUP_EN(cfg_ms_sup_a5_1, cfg_ms_sup_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
+SUP_DI(cfg_ms_sup_no_a5_1, cfg_ms_sup_no_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
+SUP_EN(cfg_ms_sup_a5_2, cfg_ms_sup_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
+SUP_DI(cfg_ms_sup_no_a5_2, cfg_ms_sup_no_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
+SUP_EN(cfg_ms_sup_a5_3, cfg_ms_sup_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
+SUP_DI(cfg_ms_sup_no_a5_3, cfg_ms_sup_no_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
+SUP_EN(cfg_ms_sup_a5_4, cfg_ms_sup_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
+SUP_DI(cfg_ms_sup_no_a5_4, cfg_ms_sup_no_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
+SUP_EN(cfg_ms_sup_a5_5, cfg_ms_sup_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
+SUP_DI(cfg_ms_sup_no_a5_5, cfg_ms_sup_no_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
+SUP_EN(cfg_ms_sup_a5_6, cfg_ms_sup_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
+SUP_DI(cfg_ms_sup_no_a5_6, cfg_ms_sup_no_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
+SUP_EN(cfg_ms_sup_a5_7, cfg_ms_sup_a5_7_cmd, a5_7, "a5/7", "A5/7", 0);
+SUP_DI(cfg_ms_sup_no_a5_7, cfg_ms_sup_no_a5_7_cmd, a5_7, "a5/7", "A5/7", 1);
+SUP_EN(cfg_ms_sup_p_gsm, cfg_ms_sup_p_gsm_cmd, p_gsm, "p-gsm", "P-GSM (900)",
+ 1);
+SUP_DI(cfg_ms_sup_no_p_gsm, cfg_ms_sup_no_p_gsm_cmd, p_gsm, "p-gsm",
+ "P-GSM (900)", 1);
+SUP_EN(cfg_ms_sup_e_gsm, cfg_ms_sup_e_gsm_cmd, e_gsm, "e-gsm", "E-GSM (850)",
+ 1);
+SUP_DI(cfg_ms_sup_no_e_gsm, cfg_ms_sup_no_e_gsm_cmd, e_gsm, "e-gsm",
+ "E-GSM (850)", 1);
+SUP_EN(cfg_ms_sup_r_gsm, cfg_ms_sup_r_gsm_cmd, r_gsm, "r-gsm", "R-GSM (850)",
+ 1);
+SUP_DI(cfg_ms_sup_no_r_gsm, cfg_ms_sup_no_r_gsm_cmd, r_gsm, "r-gsm",
+ "R-GSM (850)", 1);
+SUP_EN(cfg_ms_sup_dcs, cfg_ms_sup_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
+SUP_DI(cfg_ms_sup_no_dcs, cfg_ms_sup_no_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
+
+DEFUN(cfg_ms_sup_class_900, cfg_ms_sup_class_900_cmd, "class-900 (1|2|3|4|5)",
+ "Select power class for GSM 850/900\n"
+ "20 Watts\n"
+ "8 Watts\n"
+ "5 Watts\n"
+ "2 Watts\n"
+ "0.8 Watts")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+ struct gsm_support *sup = &ms->support;
+
+ set->class_900 = atoi(argv[0]);
+
+ if (set->class_900 < sup->class_900 && !vty_reading)
+ vty_out(vty, "You selected an higher class than supported "
+ " by hardware!%s", VTY_NEWLINE);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_sup_class_dcs, cfg_ms_sup_class_dcs_cmd, "class-dcs (1|2|3)",
+ "Select power class for DCS 1800\n"
+ "1 Watt\n"
+ "0.25 Watts\n"
+ "4 Watts")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+ struct gsm_support *sup = &ms->support;
+
+ set->class_dcs = atoi(argv[0]);
+
+ if (((set->class_dcs + 1) & 3) < ((sup->class_dcs + 1) & 3)
+ && !vty_reading)
+ vty_out(vty, "You selected an higher class than supported "
+ " by hardware!%s", VTY_NEWLINE);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_sup_ch_cap, cfg_ms_sup_ch_cap_cmd, "channel-capability "
+ "(sdcch|sdcch+tchf|sdcch+tchf+tchh)",
+ "Select channel capability\nSDCCH only\nSDCCH + TCH/F\nSDCCH + TCH/H")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+ struct gsm_support *sup = &ms->support;
+ uint8_t ch_cap;
+
+ if (!strcmp(argv[0], "sdcch+tchf+tchh"))
+ ch_cap = GSM_CAP_SDCCH_TCHF_TCHH;
+ else if (!strcmp(argv[0], "sdcch+tchf"))
+ ch_cap = GSM_CAP_SDCCH_TCHF;
+ else
+ ch_cap = GSM_CAP_SDCCH;
+
+ if (ch_cap > sup->ch_cap && !vty_reading) {
+ vty_out(vty, "You selected an higher capability than supported "
+ " by hardware!%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (ch_cap != set->ch_cap
+ && (ch_cap == GSM_CAP_SDCCH || set->ch_cap == GSM_CAP_SDCCH))
+ vty_restart(vty);
+
+ set->ch_cap = ch_cap;
+
+ return CMD_SUCCESS;
+}
+
+SUP_EN(cfg_ms_sup_full_v1, cfg_ms_sup_full_v1_cmd, full_v1, "full-speech-v1",
+ "Full rate speech V1", 0);
+SUP_DI(cfg_ms_sup_no_full_v1, cfg_ms_sup_no_full_v1_cmd, full_v1,
+ "full-speech-v1", "Full rate speech V1", 0);
+SUP_EN(cfg_ms_sup_full_v2, cfg_ms_sup_full_v2_cmd, full_v2, "full-speech-v2",
+ "Full rate speech V2 (EFR)", 0);
+SUP_DI(cfg_ms_sup_no_full_v2, cfg_ms_sup_no_full_v2_cmd, full_v2,
+ "full-speech-v2", "Full rate speech V2 (EFR)", 0);
+SUP_EN(cfg_ms_sup_full_v3, cfg_ms_sup_full_v3_cmd, full_v3, "full-speech-v3",
+ "Full rate speech V3 (AMR)", 0);
+SUP_DI(cfg_ms_sup_no_full_v3, cfg_ms_sup_no_full_v3_cmd, full_v3,
+ "full-speech-v3", "Full rate speech V3 (AMR)", 0);
+SUP_EN(cfg_ms_sup_half_v1, cfg_ms_sup_half_v1_cmd, half_v1, "half-speech-v1",
+ "Half rate speech V1 (AMR)", 0);
+SUP_DI(cfg_ms_sup_no_half_v1, cfg_ms_sup_no_half_v1_cmd, half_v1,
+ "half-speech-v1", "Half rate speech V1", 0);
+SUP_EN(cfg_ms_sup_half_v3, cfg_ms_sup_half_v3_cmd, half_v3, "half-speech-v3",
+ "Half rate speech V3 (AMR)", 0);
+SUP_DI(cfg_ms_sup_no_half_v3, cfg_ms_sup_no_half_v3_cmd, half_v3,
+ "half-speech-v3", "Half rate speech V3", 0);
+
+DEFUN(cfg_ms_sup_min_rxlev, cfg_ms_sup_min_rxlev_cmd, "min-rxlev <-110--47>",
+ "Set the minimum receive level to select a cell\n"
+ "Minimum receive level from -110 dBm to -47 dBm")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+
+ set->min_rxlev_db = atoi(argv[0]);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_sup_dsc_max, cfg_ms_sup_dsc_max_cmd, "dsc-max <90-500>",
+ "Set the maximum DSC value. Standard is 90. Increase to make mobile "
+ "more reliable against bad RX signal. This increase the propability "
+ "of missing a paging requests\n"
+ "DSC initial and maximum value (standard is 90)")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+
+ set->dsc_max = atoi(argv[0]);
+
+ return CMD_SUCCESS;
+}
+
+/* per testsim config */
+DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim",
+ "Configure test SIM emulation")
+{
+ vty->node = TESTSIM_NODE;
+
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_test_imsi, cfg_test_imsi_cmd, "imsi IMSI",
"Set IMSI on test card\n15 digits IMSI")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
char *error = gsm_check_imsi(argv[0]);
if (error) {
return CMD_WARNING;
}
- strcpy(ms->settings.test_imsi, argv[0]);
+ strcpy(set->test_imsi, argv[0]);
+ vty_restart(vty);
return CMD_SUCCESS;
}
"Allow access to barred cells")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.test_barr = 1;
+ set->test_barr = 1;
return CMD_SUCCESS;
}
NO_STR "Deny access to barred cells")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.test_barr = 0;
+ set->test_barr = 0;
return CMD_SUCCESS;
}
NO_STR "Unset Registered PLMN")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
- ms->settings.test_rplmn_valid = 0;
+ set->test_rplmn_valid = 0;
+ vty_restart(vty);
return CMD_SUCCESS;
}
"Set Registered PLMN\nMobile Country Code\nMobile Network Code")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
uint16_t mcc = gsm_input_mcc((char *)argv[0]),
mnc = gsm_input_mnc((char *)argv[1]);
vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
return CMD_WARNING;
}
- ms->settings.test_rplmn_valid = 1;
- ms->settings.test_rplmn_mcc = mcc;
- ms->settings.test_rplmn_mnc = mnc;
+ set->test_rplmn_valid = 1;
+ set->test_rplmn_mcc = mcc;
+ set->test_rplmn_mnc = mnc;
+ vty_restart(vty);
return CMD_SUCCESS;
}
"Search for HPLMN when in a different country")
{
struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
switch (argv[0][0]) {
case 'e':
- ms->settings.test_always = 1;
+ set->test_always = 1;
break;
case 'f':
- ms->settings.test_always = 0;
+ set->test_always = 0;
break;
}
+ vty_restart(vty);
return CMD_SUCCESS;
}
vty->index = NULL;
break;
case TESTSIM_NODE:
+ case SUPPORT_NODE:
vty->node = MS_NODE;
break;
default:
vty->index = NULL;
break;
case TESTSIM_NODE:
+ case SUPPORT_NODE:
vty->node = MS_NODE;
break;
default:
case VTY_NODE:
case MS_NODE:
case TESTSIM_NODE:
+ case SUPPORT_NODE:
vty_config_unlock(vty);
vty->node = ENABLE_NODE;
vty->index = NULL;
return CMD_SUCCESS;
}
+#define SUP_NODE(item) \
+ install_element(SUPPORT_NODE, &cfg_ms_sup_item_cmd);
+
int ms_vty_init(void)
{
install_element_ve(&show_ms_cmd);
install_element(ENABLE_NODE, &network_select_cmd);
install_element(ENABLE_NODE, &call_cmd);
install_element(ENABLE_NODE, &call_retr_cmd);
+ install_element(ENABLE_NODE, &call_dtmf_cmd);
install_element(CONFIG_NODE, &cfg_gps_device_cmd);
install_element(CONFIG_NODE, &cfg_gps_baud_cmd);
install_element(MS_NODE, &cfg_ms_clir_cmd);
install_element(MS_NODE, &cfg_ms_no_clip_cmd);
install_element(MS_NODE, &cfg_ms_no_clir_cmd);
- install_element(MS_NODE, &cfg_ms_testsim_cmd);
- install_element(MS_NODE, &cfg_ms_min_rxlev_cmd);
install_element(MS_NODE, &cfg_ms_tx_power_cmd);
install_element(MS_NODE, &cfg_ms_tx_power_val_cmd);
install_element(MS_NODE, &cfg_ms_sim_delay_cmd);
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);
+ install_default(SUPPORT_NODE);
+ install_element(SUPPORT_NODE, &ournode_exit_cmd);
+ install_element(SUPPORT_NODE, &ournode_end_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_dtmf_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_dtmf_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_sms_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_sms_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_a5_1_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_1_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_a5_2_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_2_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_a5_3_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_3_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_a5_4_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_4_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_a5_5_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_5_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_a5_6_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_6_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_a5_7_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_7_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_p_gsm_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_p_gsm_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_e_gsm_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_e_gsm_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_r_gsm_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_r_gsm_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_dcs_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_dcs_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_class_900_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_class_dcs_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_ch_cap_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_full_v1_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v1_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_full_v2_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v2_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_full_v3_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v3_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_half_v1_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v1_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_half_v3_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v3_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_min_rxlev_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_dsc_max_cmd);
install_node(&testsim_node, config_write_dummy);
install_default(TESTSIM_NODE);
install_element(TESTSIM_NODE, &ournode_exit_cmd);