[asterisk-commits] dvossel: branch dvossel/hd_confbridge r309632 - in /team/dvossel/hd_confbridg...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Mar 4 16:17:33 CST 2011
Author: dvossel
Date: Fri Mar 4 16:17:28 2011
New Revision: 309632
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=309632
Log:
Addition of the playback and continue action
Modified:
team/dvossel/hd_confbridge/apps/app_confbridge.c
team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c
team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h
team/dvossel/hd_confbridge/configs/confbridge.conf.sample
Modified: team/dvossel/hd_confbridge/apps/app_confbridge.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/apps/app_confbridge.c?view=diff&rev=309632&r1=309631&r2=309632
==============================================================================
--- team/dvossel/hd_confbridge/apps/app_confbridge.c (original)
+++ team/dvossel/hd_confbridge/apps/app_confbridge.c Fri Mar 4 16:17:28 2011
@@ -93,6 +93,11 @@
static struct ao2_container *conference_bridges;
static int play_sound_file(struct conference_bridge *conference_bridge, const char *filename);
+static int execute_menu_entry(struct conference_bridge *conference_bridge,
+ struct conference_bridge_user *conference_bridge_user,
+ struct ast_bridge_channel *bridge_channel,
+ struct conf_menu_entry *menu_entry,
+ struct conf_menu *menu);
/*! \brief Hashing function used for conference bridges container */
static int conference_bridge_hash_cb(const void *obj, const int flags)
@@ -658,14 +663,131 @@
return res;
}
-int conf_handle_dtmf(
+static int action_toggle_mute(struct conference_bridge *conference_bridge,
+ struct conference_bridge_user *conference_bridge_user,
+ struct ast_bridge_channel *bridge_channel)
+{
+ /* Mute or unmute yourself, note we only allow manipulation if they aren't waiting for a marked user or if marked users exist */
+ if (!ast_test_flag(&conference_bridge_user->u_profile, USER_OPT_WAITMARKED) || conference_bridge->markedusers) {
+ conference_bridge_user->features.mute = (!conference_bridge_user->features.mute ? 1 : 0);
+ }
+ return ast_stream_and_wait(bridge_channel->chan, (conference_bridge_user->features.mute ? "conf-muted" : "conf-unmuted"), "");
+}
+
+static int action_playback(struct conference_bridge *conference_bridge,
+ struct conference_bridge_user *conference_bridge_user,
struct ast_bridge_channel *bridge_channel,
+ struct conf_menu *menu,
+ const char *playback_file,
+ const char *cur_dtmf)
+{
+ int i;
+ int digit;
+ char dtmf[MAXIMUM_DTMF_FEATURE_STRING];
+ struct conf_menu_entry new_menu_entry = { { 0, }, };
+
+ if (ast_streamfile(bridge_channel->chan, playback_file, bridge_channel->chan->language)) {
+ ast_log(LOG_WARNING, "Failed to playback file %s to channel\n", playback_file);
+ return -1;
+ }
+
+ /* now wait for more digits. */
+ if (!(digit = ast_waitstream(bridge_channel->chan, AST_DIGIT_ANY))) {
+ /* streaming finished and no DTMF was entered */
+ return -1;
+ } else if (digit == -1) {
+ /* error */
+ return -1;
+ }
+ ast_stopstream(bridge_channel->chan);
+
+ /* If a digit was pressed during the payback, update
+ * the dtmf string and look for a new menu entry in the
+ * menu structure */
+ ast_copy_string(dtmf, cur_dtmf, sizeof(dtmf));
+ for (i = 0; i < (MAXIMUM_DTMF_FEATURE_STRING - 1); i++) {
+ dtmf[i] = cur_dtmf[i];
+ if (!dtmf[i]) {
+ dtmf[i] = (char) digit;
+ dtmf[i + 1] = '\0';
+ i = -1;
+ break;
+ }
+ }
+ /* If i is not -1 then the new dtmf digit was _NOT_ added to the string.
+ * If this is the case, no new DTMF sequence should be looked for. */
+ if (i != -1) {
+ return 0;
+ }
+
+ if (conf_find_menu_entry_by_sequence(dtmf, menu, &new_menu_entry)) {
+ execute_menu_entry(conference_bridge,
+ conference_bridge_user,
+ bridge_channel,
+ &new_menu_entry, menu);
+ conf_menu_entry_destroy(&new_menu_entry);
+ }
+ return 0;
+}
+
+static int execute_menu_entry(struct conference_bridge *conference_bridge,
+ struct conference_bridge_user *conference_bridge_user,
+ struct ast_bridge_channel *bridge_channel,
+ struct conf_menu_entry *menu_entry,
+ struct conf_menu *menu)
+{
+ struct conf_menu_action *menu_action;
+ int res = 0;
+
+ AST_LIST_TRAVERSE(&menu_entry->actions, menu_action, action) {
+ switch (menu_action->id) {
+ case MENU_ACTION_TOGGLE_MUTE:
+ res |= action_toggle_mute(conference_bridge,
+ conference_bridge_user,
+ bridge_channel);
+ break;
+ case MENU_ACTION_PLAYBACK:
+ res |= action_playback(conference_bridge,
+ conference_bridge_user,
+ bridge_channel,
+ menu,
+ menu_action->data.playback_file,
+ menu_entry->dtmf);
+ break;
+ }
+ }
+ return res;
+}
+
+int conf_handle_dtmf(struct ast_bridge_channel *bridge_channel,
struct conference_bridge_user *conference_bridge_user,
struct conf_menu_entry *menu_entry,
struct conf_menu *menu)
{
- //todohere handle dtmf actions
- return 0;
+ struct conference_bridge *conference_bridge = conference_bridge_user->conference_bridge;
+ int res = 0;
+
+ /* See if music on hold is playing */
+ ao2_lock(conference_bridge);
+ if (conference_bridge->users == 1 && ast_test_flag(&conference_bridge_user->u_profile, USER_OPT_MUSICONHOLD)) {
+ /* Just us so MOH is probably indeed going, let's stop it */
+ ast_moh_stop(bridge_channel->chan);
+ }
+ ao2_unlock(conference_bridge);
+
+ /* execute the list of actions associated with this menu entry */
+ execute_menu_entry(conference_bridge, conference_bridge_user, bridge_channel, menu_entry, menu);
+
+ /* See if music on hold needs to be started back up again */
+ ao2_lock(conference_bridge);
+ if (conference_bridge->users == 1 && ast_test_flag(&conference_bridge_user->u_profile, USER_OPT_MUSICONHOLD)) {
+ ast_moh_start(bridge_channel->chan, conference_bridge_user->opt_args[OPTION_MUSICONHOLD_CLASS], NULL);
+ }
+ ao2_unlock(conference_bridge);
+
+ bridge_channel->state = AST_BRIDGE_CHANNEL_STATE_WAIT;
+
+ return res;
}
Modified: team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c?view=diff&rev=309632&r1=309631&r2=309632
==============================================================================
--- team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c (original)
+++ team/dvossel/hd_confbridge/apps/confbridge/conf_config_parser.c Fri Mar 4 16:17:28 2011
@@ -90,12 +90,9 @@
{
struct conf_menu *menu = obj;
struct conf_menu_entry *entry = NULL;
- struct conf_menu_action *action = NULL;
while ((entry = AST_LIST_REMOVE_HEAD(&menu->entries, entry))) {
- while ((action = AST_LIST_REMOVE_HEAD(&entry->actions, action))) {
- ast_free(action);
- }
+ conf_menu_entry_destroy(entry);
ast_free(entry);
}
}
@@ -244,7 +241,6 @@
switch (id) {
case MENU_ACTION_TOGGLE_MUTE:
- case MENU_ACTION_TOGGLE_DEAF:
break;
case MENU_ACTION_PLAYBACK:
if (!(ast_strlen_zero(databuf))) {
@@ -272,9 +268,6 @@
ast_copy_string(menu_entry->dtmf, dtmf, sizeof(menu_entry->dtmf));
if (!strcasecmp(action, "toggle_mute")) {
res |= add_action_to_menu_entry(menu_entry, MENU_ACTION_TOGGLE_MUTE, NULL);
- }
- if (!strcasecmp(action, "toggle_deaf")) {
- res |= add_action_to_menu_entry(menu_entry, MENU_ACTION_TOGGLE_DEAF, NULL);
}
if (action_len >= 8 && !strncasecmp(action, "playback", 8)) {
char *filename = ast_strdupa(action);
@@ -537,9 +530,6 @@
case MENU_ACTION_TOGGLE_MUTE:
ast_cli(a->fd, "toggle_mute");
break;
- case MENU_ACTION_TOGGLE_DEAF:
- ast_cli(a->fd, "toggle_deaf");
- break;
case MENU_ACTION_PLAYBACK:
ast_cli(a->fd, "playback(%s)", menu_action->data.playback_file);
break;
@@ -724,9 +714,33 @@
if (!(new_menu_action = ast_calloc(1, sizeof(*new_menu_action)))) {
return -1;
}
- memcpy(new_menu_action, menu_action, sizeof(new_menu_action));
+ memcpy(new_menu_action, menu_action, sizeof(*new_menu_action));
AST_LIST_INSERT_HEAD(&dst->actions, new_menu_action, action);
}
+ return 0;
+}
+
+void conf_menu_entry_destroy(struct conf_menu_entry *menu_entry)
+{
+ struct conf_menu_action *menu_action = NULL;
+ while ((menu_action = AST_LIST_REMOVE_HEAD(&menu_entry->actions, action))) {
+ ast_free(menu_action);
+ }
+}
+
+int conf_find_menu_entry_by_sequence(const char *dtmf_sequence, struct conf_menu *menu, struct conf_menu_entry *result)
+{
+ struct conf_menu_entry *menu_entry = NULL;
+ ao2_lock(menu);
+ AST_LIST_TRAVERSE(&menu->entries, menu_entry, entry) {
+ if (!strcasecmp(menu_entry->dtmf, dtmf_sequence)) {
+ copy_menu_entry(result, menu_entry);
+ ao2_unlock(menu);
+ return 1;
+ }
+ }
+ ao2_unlock(menu);
+
return 0;
}
Modified: team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h?view=diff&rev=309632&r1=309631&r2=309632
==============================================================================
--- team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h (original)
+++ team/dvossel/hd_confbridge/apps/confbridge/include/confbridge.h Fri Mar 4 16:17:28 2011
@@ -42,7 +42,6 @@
enum conf_menu_action_id {
MENU_ACTION_TOGGLE_MUTE = 1,
- MENU_ACTION_TOGGLE_DEAF,
MENU_ACTION_PLAYBACK,
};
@@ -153,6 +152,20 @@
*/
int conf_set_menu_to_user(const char *menu_name, struct conference_bridge_user *conference_bridge_user);
+/*!
+ * \brief Finds a menu_entry in a menu structure matched by DTMF sequence.
+ *
+ * \note the menu entry found must be destroyed using conf_menu_entry_destroy()
+ *
+ * \retval 1 success, entry is found and stored in result
+ * \retval 0 failure, no entry found for given DTMF sequence
+ */
+int conf_find_menu_entry_by_sequence(const char *dtmf_sequence, struct conf_menu *menu, struct conf_menu_entry *result);
+
+/*!
+ * \brief Destroys and frees all the actions stored in a menu_entry structure
+ */
+void conf_menu_entry_destroy(struct conf_menu_entry *menu_entry);
/*!
* \brief Once a DTMF sequence matches a sequence in the user's DTMF menu, this function will get
Modified: team/dvossel/hd_confbridge/configs/confbridge.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/configs/confbridge.conf.sample?view=diff&rev=309632&r1=309631&r2=309632
==============================================================================
--- team/dvossel/hd_confbridge/configs/confbridge.conf.sample (original)
+++ team/dvossel/hd_confbridge/configs/confbridge.conf.sample Fri Mar 4 16:17:28 2011
@@ -3,9 +3,9 @@
; is not currently used, but reserved
; for future use.
-; The default_user, default_bridge, and default_menu
-; sections are applied automatically to all ConfBridge
-; instances invoked without a user, bridge, or menu argument.
+; The default_user, default_bridge sections are applied
+; automatically to all ConfBridge instances invoked without
+; a user, bridge, or menu argument.
[default_user]
type=user
;admin=yes ; Sets if the user is an admin or not. Off by default.
@@ -31,10 +31,8 @@
; closest sample rate Asterisk does support to the one requested
; will be used.
-[default_menu]
+[sample_menu]
type=menu
*1=toggle_mute ; Toggle turning on and off mute. Mute will make the user silent
; to everyone else, but the user will still be able to listen in.
-*2=toggle_deaf ; Toggle turning on and off deaf. Deaf will make everyone else
- ; silent for a user, but the user will still be able to be heard.
More information about the asterisk-commits
mailing list