[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