summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfred E. Heggestad <alfred.heggestad@gmail.com>2016-11-27 18:07:42 +0100
committerAlfred E. Heggestad <alfred.heggestad@gmail.com>2016-11-27 18:07:42 +0100
commit1203abd362a212b6cb6a02ff54f466d3a23dbf83 (patch)
tree6d3db4240e76a90def031b1bc2c312b09643697d
parente1e5337644671c7df1703a0916242868bcccd1fc (diff)
cmd: check for duplicated entries
- registering duplicate short commands is no longer possible - disable a couple of short commands, use long command instead (short commands should only be used for very frequently used things) - menu: properly register/unregister digit handlers for active calls thanks to Juha Heinanen for reporting an issue with the 'a' key
-rw-r--r--include/baresip.h2
-rw-r--r--modules/debug_cmd/debug_cmd.c6
-rw-r--r--modules/menu/menu.c45
-rw-r--r--modules/vidloop/vidloop.c4
-rw-r--r--src/cmd.c15
-rw-r--r--test/cmd.c3
6 files changed, 58 insertions, 17 deletions
diff --git a/include/baresip.h b/include/baresip.h
index 4acc0cd..1b0343a 100644
--- a/include/baresip.h
+++ b/include/baresip.h
@@ -692,6 +692,8 @@ int cmd_process_long(struct commands *commands, const char *str, size_t len,
int cmd_print(struct re_printf *pf, const struct commands *commands);
const struct cmd *cmd_find_long(const struct commands *commands,
const char *name);
+struct cmds *cmds_find(const struct commands *commands,
+ const struct cmd *cmdv);
/*
diff --git a/modules/debug_cmd/debug_cmd.c b/modules/debug_cmd/debug_cmd.c
index 4b29bb1..28b1d71 100644
--- a/modules/debug_cmd/debug_cmd.c
+++ b/modules/debug_cmd/debug_cmd.c
@@ -85,13 +85,13 @@ static int cmd_play_file(struct re_printf *pf, void *arg)
static const struct cmd debugcmdv[] = {
{"main", 0, 0, "Main loop debug", re_debug },
-{"config", 'g', 0, "Print configuration", cmd_config_print },
+{"config", 'g', 0, "Print configuration", cmd_config_print },
{"sipstat", 'i', 0, "SIP debug", ua_print_sip_status },
-{"modules", 'm', 0, "Module debug", mod_debug },
+{"modules", 0, 0, "Module debug", mod_debug },
{"netstat", 'n', 0, "Network debug", cmd_net_debug },
{"sysinfo", 's', 0, "System info", print_system_info },
{"timers", 0, 0, "Timer debug", tmr_status },
-{"uastat", 'u', 0, "UA debug", cmd_ua_debug },
+{"uastat", 'u', 0, "UA debug", cmd_ua_debug },
{"memstat", 'y', 0, "Memory status", mem_status },
{"play", 0, CMD_PRM, "Play audio file", cmd_play_file },
};
diff --git a/modules/menu/menu.c b/modules/menu/menu.c
index 9036f56..b82e81d 100644
--- a/modules/menu/menu.c
+++ b/modules/menu/menu.c
@@ -44,7 +44,7 @@ static struct {
} menu;
-static void menu_set_incall(bool incall);
+static int menu_set_incall(bool incall);
static void update_callstatus(void);
static void alert_stop(void);
@@ -421,6 +421,9 @@ static const struct cmd cmdv[] = {
{NULL, 'T', 0, "Toggle UAs", cmd_ua_next },
{NULL, 'R', CMD_PRM, "Create User-Agent", create_ua },
+};
+
+static const struct cmd dialcmdv[] = {
/* Numeric keypad inputs: */
{NULL, '#', CMD_PRM, NULL, dial_handler },
{NULL, '*', CMD_PRM, NULL, dial_handler },
@@ -683,18 +686,18 @@ static int set_current_call(struct re_printf *pf, void *arg)
static const struct cmd callcmdv[] = {
{"", 'I', 0, "Send re-INVITE", call_reinvite },
{"resume", 'X', 0, "Call resume", cmd_call_resume },
-{"", 'a', 0, "Audio stream", call_audio_debug },
-{"", 'e', 0, "Cycle audio encoder", call_audioenc_cycle },
+{"audio_debug",'A', 0, "Audio stream", call_audio_debug },
+{"audio_cycle",'e', 0, "Cycle audio encoder", call_audioenc_cycle },
{"mute", 'm', 0, "Call mute/un-mute", call_mute },
-{"transfer", 'r', CMD_IPRM, "Transfer call", call_xfer },
+{"transfer", 't', CMD_IPRM, "Transfer call", call_xfer },
{"hold", 'x', 0, "Call hold", cmd_call_hold },
{"", 'H', 0, "Hold previous call", hold_prev_call },
{"", 'L', 0, "Resume previous call",hold_prev_call },
-{"", 'A', CMD_IPRM, "Switch audio device", switch_audio_dev },
+{"audev", 0, CMD_IPRM, "Switch audio device", switch_audio_dev },
#ifdef USE_VIDEO
-{"", 'E', 0, "Cycle video encoder", call_videoenc_cycle },
-{"", 'v', 0, "Video stream", call_video_debug },
+{"video_cycle", 'E', 0, "Cycle video encoder", call_videoenc_cycle },
+{"video_debug", 'V', 0, "Video stream", call_video_debug },
#endif
/* Numeric keypad for DTMF events: */
@@ -717,17 +720,33 @@ static const struct cmd callcmdv[] = {
};
-static void menu_set_incall(bool incall)
+static int menu_set_incall(bool incall)
{
struct commands *commands = baresip_commands();
+ int err = 0;
/* Dynamic menus */
if (incall) {
- (void)cmd_register(commands, callcmdv, ARRAY_SIZE(callcmdv));
+ cmd_unregister(commands, dialcmdv);
+
+ if (!cmds_find(commands, callcmdv)) {
+ err = cmd_register(commands,
+ callcmdv, ARRAY_SIZE(callcmdv));
+ }
}
else {
cmd_unregister(commands, callcmdv);
+
+ if (!cmds_find(commands, dialcmdv)) {
+ err = cmd_register(baresip_commands(), dialcmdv,
+ ARRAY_SIZE(dialcmdv));
+ }
}
+ if (err) {
+ warning("menu: set_incall: cmd_register failed (%m)\n", err);
+ }
+
+ return err;
}
@@ -994,6 +1013,11 @@ static int module_init(void)
statmode = STATMODE_CALL;
err = cmd_register(baresip_commands(), cmdv, ARRAY_SIZE(cmdv));
+ err |= cmd_register(baresip_commands(), dialcmdv,
+ ARRAY_SIZE(dialcmdv));
+ if (err)
+ return err;
+
err |= uag_event_register(ua_event_handler, NULL);
err |= message_init(message_handler, NULL);
@@ -1010,8 +1034,9 @@ static int module_close(void)
message_close();
uag_event_unregister(ua_event_handler);
cmd_unregister(baresip_commands(), cmdv);
+ cmd_unregister(baresip_commands(), dialcmdv);
+ cmd_unregister(baresip_commands(), callcmdv);
- menu_set_incall(false);
tmr_cancel(&tmr_alert);
tmr_cancel(&tmr_stat);
dialbuf = mem_deref(dialbuf);
diff --git a/modules/vidloop/vidloop.c b/modules/vidloop/vidloop.c
index 3a5d38c..6a90318 100644
--- a/modules/vidloop/vidloop.c
+++ b/modules/vidloop/vidloop.c
@@ -477,8 +477,8 @@ static int vidloop_stop(struct re_printf *pf, void *arg)
static const struct cmd cmdv[] = {
- {"vidloop", 'v', 0, "Start video-loop", vidloop_start },
- {"vidloop_stop", 'V', 0, "Stop video-loop", vidloop_stop },
+ {"vidloop", 0, 0, "Start video-loop", vidloop_start },
+ {"vidloop_stop", 0, 0, "Stop video-loop", vidloop_stop },
};
diff --git a/src/cmd.c b/src/cmd.c
index 4c9d4ca..f0ad6e9 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -73,8 +73,8 @@ static int ctx_alloc(struct cmd_ctx **ctxp, const struct cmd *cmd)
}
-static struct cmds *cmds_find(const struct commands *commands,
- const struct cmd *cmdv)
+struct cmds *cmds_find(const struct commands *commands,
+ const struct cmd *cmdv)
{
struct le *le;
@@ -396,6 +396,17 @@ int cmd_register(struct commands *commands,
for (i=0; i<cmdc; i++) {
const struct cmd *cmd = &cmdv[i];
+ if (cmd->key) {
+ const struct cmd *x = cmd_find_by_key(commands,
+ cmd->key);
+ if (x) {
+ warning("short command '%c' already"
+ " registered as \"%s\"\n",
+ x->key, x->desc);
+ return EALREADY;
+ }
+ }
+
if (cmd->key == LONG_PREFIX) {
warning("cmd: cannot register command with"
" short key '%c'\n", cmd->key);
diff --git a/test/cmd.c b/test/cmd.c
index 06f35b6..ae3838b 100644
--- a/test/cmd.c
+++ b/test/cmd.c
@@ -63,6 +63,9 @@ int test_cmd(void)
err = cmd_register(&commands, cmdv, ARRAY_SIZE(cmdv));
ASSERT_EQ(0, err);
+ /* it is not possible to register same block twice */
+ ASSERT_EQ(EALREADY, cmd_register(&commands, cmdv, ARRAY_SIZE(cmdv)));
+
/* issue a different command */
err = cmd_process(&commands, &ctx, 'h', &pf_null, &test);
ASSERT_EQ(0, err);