aboutsummaryrefslogblamecommitdiffstats
path: root/main/asterisk/ASTERISK-19109.patch
blob: f4399a0d4e84f400deb01fbf31a93deb1a5b5a47 (plain) (tree)
1
2
3
4
5
6
7
8


                                                                           


                                                                               
 
 


                                                                          
                                                                               
                                                                               
                                                                               



                                                                                         
















                                                                                                                           
                                                   











                                                                                                                           
                    

                         








                                                                   
                                          
 
                    









                                                                          
                    
                                    

  
                                                                                                      
  
                                                                                    

  
                                                                                                        
  
                                                                                      




                                                                                                              
                      

                                                  
         
                                                                                           
                                                                 
                                                 
                                       

         

                                                                            
                      
                 

  

                                                                        

                                         









                                                                
                                                    
                
                                                      



                                                                               





                                                                                                 
                      
                                                   
                                                              

                                             

                                                             




                                                                                                        
                       

  




                                                                                                                       



                                                    





                                                
                                          




                                                
                     


                                              

  










                                                                                                  
                                                    



                                                                                                    
                                                      




                                                                                               

                                                  





                                                                                                 
                                                    



                      

                                                                          
   
                                                                                  



                                   



                                                                                
  
                                                                                
                                     
                     







                                                                                                        
                     







                                                                                                        
                      



                                                                    
                                                                                                    


                                                                           
                                                                                


                                                                                       
                      
                 


                                                                                                           


                                       
                                   

                                         
                                     







                                       
         
 



                                                                                   
                     



                                     
                                                              


                           
                      



                                     
                                                                





















                                                                                                    
                                                                





















                                                                                                      
                                                                  


                           
                     
                                                                                                   

                                                                             




                                                                                           
                       



                                                                                              
                                                                                                                              
  

                                                                         


                    
                                               
                     


                         

                                                                                   


                                                                             
                       



                                                                    

                                       
                                       

                                         
                                         







                                       








                                                                                  
                                                                             



                                                                                
                                                                           


                                                                                    
                                                                               


                                                                                  
                                                                             


                                                                                              
                     







                                                      
                     







                                                                                                                 







                                                                                                                       









                                                                     
                     






                                            
                     








                                                        
                     







                                                                                                                       
                     








                                                              
                     






                                                                                                                                                                             


                                                                                                                       
                    





































                                                                                            

                             
















                                                                                
                   







                                                       
                   







                                                                 
                   







                                                              
                    



















                                                          
                    



















                                                           



                                                                                                                       

                                                                                                                       

                                                                                                                                            


                            
                 






                                          
                   







                                  
                   







                                               
                   

                                           
 

                                                            
 

                                                                                 



                                                                                               



                                                                        

                                                                                



                                                                                         




                                                                                

                                                                                        


                                                                            


                                                                                                                         
                                                                                   
                                                                                                                                 


                                                    
 


                                                                                                                           
                 






                                                                               
                   







                                                                                          
                   
                                                                                 

                                                                                     

                                                                                      
 

                                                                                    


                                                                                                                   
                   
                              
                                                   
                            
                                                  
                            
                                                                   
                                        
   











                                                                                         

                         
 



                                                                           

                                                     
                                                           
                                        
                                               

                                               
                                            


                                         
         


                          
diff -ru asterisk-13.0.0.orig/CHANGES asterisk-13.0.0/CHANGES
--- asterisk-13.0.0.orig/CHANGES	2014-10-31 09:25:50.097163496 -0200
+++ asterisk-13.0.0/CHANGES	2014-10-31 09:23:05.690495201 -0200
@@ -8,6 +8,10 @@
 ===
 ==============================================================================
 
+
+ * Added support for deaf participants with CLI commands, manager actions
+   and ConfBridge DTMF actions to toggle the deaf state.
+
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 12 to Asterisk 13 --------------------
 ------------------------------------------------------------------------------
diff -ru asterisk-13.0.0.orig/apps/app_confbridge.c asterisk-13.0.0/apps/app_confbridge.c
--- asterisk-13.0.0.orig/apps/app_confbridge.c	2014-10-31 09:25:50.097163496 -0200
+++ asterisk-13.0.0/apps/app_confbridge.c	2014-10-31 09:29:06.293832109 -0200
@@ -234,6 +234,30 @@
 		<description>
 		</description>
 	</manager>
+	<manager name="ConfbridgeDeafen" language="en_US">
+		<synopsis>
+			Deafen a Confbridge user.
+		</synopsis>
+		<syntax>
+			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
+			<parameter name="Conference" required="true" />
+			<parameter name="Channel" required="true" />
+		</syntax>
+		<description>
+		</description>
+	</manager>
+	<manager name="ConfbridgeUndeafen" language="en_US">
+		<synopsis>
+			Undeafen a Confbridge user.
+		</synopsis>
+		<syntax>
+			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
+			<parameter name="Conference" required="true" />
+			<parameter name="Channel" required="true" />
+		</syntax>
+		<description>
+		</description>
+	</manager>
 	<manager name="ConfbridgeKick" language="en_US">
 		<synopsis>
 			Kick a Confbridge user.
@@ -333,6 +357,13 @@
 	CONF_RECORD_STOP,
 };
 
+enum confbridge_feature_action {
+	CONFBRIDGE_FEATURE_MUTE,
+	CONFBRIDGE_FEATURE_UNMUTE,
+	CONFBRIDGE_FEATURE_DEAFEN,
+	CONFBRIDGE_FEATURE_UNDEAFEN
+};
+
 /*! \brief Container to hold all conference bridges in progress */
 struct ao2_container *conference_bridges;
 
@@ -404,6 +435,10 @@
 		return S_OR(custom_sounds->muted, "conf-muted");
 	case CONF_SOUND_UNMUTED:
 		return S_OR(custom_sounds->unmuted, "conf-unmuted");
+	case CONF_SOUND_DEAFENED:
+		return S_OR(custom_sounds->deafened, "conf-deafened");
+	case CONF_SOUND_UNDEAFENED:
+		return S_OR(custom_sounds->undeafened, "conf-undeafened");
 	case CONF_SOUND_ONLY_ONE:
 		return S_OR(custom_sounds->onlyone, "conf-onlyone");
 	case CONF_SOUND_THERE_ARE:
@@ -554,6 +589,16 @@
 	ast_json_unref(json_object);
 }
 
+static void send_deafen_event(struct confbridge_user *user, struct confbridge_conference *conference)
+{
+	send_conf_stasis(conference, user->chan, confbridge_deafen_type(), NULL, 1);
+}
+
+static void send_undeafen_event(struct confbridge_user *user, struct confbridge_conference *conference)
+{
+	send_conf_stasis(conference, user->chan, confbridge_undeafen_type(), NULL, 1);
+}
+
 static void set_rec_filename(struct confbridge_conference *conference, struct ast_str **filename, int is_new)
 {
 	char *rec_file = conference->b_profile.rec_file;
@@ -1734,6 +1779,11 @@
 		/* Set user level mute request. */
 		user.muted = 1;
 	}
+	/* If the caller should be joined already deafened, set the flag before we join. */
+	if (ast_test_flag(&user.u_profile, USER_OPT_STARTDEAF)) {
+		/* Set user level deaf request */
+		user.features.deaf = 1;
+	}
 
 	/* Look for a conference bridge matching the provided name */
 	if (!(conference = join_conference_bridge(args.conf_name, &user))) {
@@ -1928,6 +1978,30 @@
 	return 0;
 }
 
+static int action_toggle_deaf(struct confbridge_conference *conference,
+	struct confbridge_user *user, struct ast_channel *chan)
+{
+	/* Deafen or undeafen yourself */
+	user->features.deaf = !user->features.deaf;
+	ast_test_suite_event_notify("CONF_DEAF",
+		"Message: participant %s %s\r\n"
+		"Conference: %s\r\n"
+		"Channel: %s",
+		ast_channel_name(chan),
+		user->features.deaf ? "deafened" : "undeafened",
+		user->b_profile.name,
+		ast_channel_name(chan));
+	if (user->features.deaf) {
+		send_deafen_event(user, conference);
+	} else {
+		send_undeafen_event(user, conference);
+	}
+	return ast_stream_and_wait(chan, (user->features.deaf ?
+		conf_get_sound(CONF_SOUND_DEAFENED, user->b_profile.sounds) :
+		conf_get_sound(CONF_SOUND_UNDEAFENED, user->b_profile.sounds)),
+		"");
+}
+
 static int action_playback(struct ast_bridge_channel *bridge_channel, const char *playback_file)
 {
 	char *file_copy = ast_strdupa(playback_file);
@@ -2115,6 +2189,11 @@
 		case MENU_ACTION_PARTICIPANT_COUNT:
 			announce_user_count(conference, user);
 			break;
+		case MENU_ACTION_TOGGLE_DEAF:
+			res |= action_toggle_deaf(conference,
+				user,
+				bridge_channel->chan);
+			break;
 		case MENU_ACTION_PLAYBACK:
 			if (!stop_prompts) {
 				res |= action_playback(bridge_channel, menu_action->data.playback_file);
@@ -2499,38 +2578,65 @@
 }
 
 /* \internal
- * \brief Mute/unmute a single user.
+ * \brief Send feature change test event.
  */
-static void generic_mute_unmute_user(struct confbridge_conference *conference, struct confbridge_user *user, int mute)
+static void test_suite_feature_action_event_notify(
+	struct confbridge_conference *conference,
+	struct confbridge_user *user,
+	const char *state, const char *verb)
 {
-	/* Set user level mute request. */
-	user->muted = mute ? 1 : 0;
-
-	conf_update_user_mute(user);
-	ast_test_suite_event_notify("CONF_MUTE",
+	ast_test_suite_event_notify(state,
 		"Message: participant %s %s\r\n"
 		"Conference: %s\r\n"
 		"Channel: %s",
 		ast_channel_name(user->chan),
-		mute ? "muted" : "unmuted",
+		verb,
 		conference->b_profile.name,
 		ast_channel_name(user->chan));
-	if (mute) {
+}
+
+/* \internal
+ * \brief Change a feature for one conference user.
+ */
+static void generic_feature_action_helper_user(
+	struct confbridge_conference *conference, struct confbridge_user *user,
+	enum confbridge_feature_action action)
+{
+	switch (action) {
+	case CONFBRIDGE_FEATURE_DEAFEN:
+		user->features.deaf = 1;
+		test_suite_feature_action_event_notify(conference, user, "CONF_DEAF", "deafened");
+		send_deafen_event(user, conference);
+		break;
+	case CONFBRIDGE_FEATURE_UNDEAFEN:
+		user->features.deaf = 0;
+		test_suite_feature_action_event_notify(conference, user, "CONF_DEAF", "undeafened");
+		send_undeafen_event(user, conference);
+		break;
+	case CONFBRIDGE_FEATURE_MUTE:
+		user->muted = 1;
+		conf_update_user_mute(user);
+		test_suite_feature_action_event_notify(conference, user, "CONF_MUTE", "muted");
 		send_mute_event(user, conference);
-	} else {
+		break;
+	case CONFBRIDGE_FEATURE_UNMUTE:
+	default:
+		user->muted = 0;
+		conf_update_user_mute(user);
+		test_suite_feature_action_event_notify(conference, user, "CONF_MUTE", "unmuted");
 		send_unmute_event(user, conference);
+		break;
 	}
 }
 
 /* \internal
- * \brief finds a conference user by channel name and mutes/unmutes them.
- *
+ * \brief finds a conference user by channel name and changes feature bits on it.
  * \retval 0 success
  * \retval -1 conference not found
  * \retval -2 user not found
  */
-static int generic_mute_unmute_helper(int mute, const char *conference_name,
-	const char *chan_name)
+static int generic_feature_action_helper(enum confbridge_feature_action action,
+	const char *conference_name, const char *chan_name)
 {
 	RAII_VAR(struct confbridge_conference *, conference, NULL, ao2_cleanup);
 	struct confbridge_user *user;
@@ -2550,7 +2656,7 @@
 				strlen(chan_name));
 			if (match || all
 				|| (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
-				generic_mute_unmute_user(conference, user, mute);
+				generic_feature_action_helper_user(conference, user, action);
 				res = 0;
 				if (match) {
 					return res;
@@ -2563,7 +2669,7 @@
 				strlen(chan_name));
 			if (match || all
 				|| (participants && !ast_test_flag(&user->u_profile, USER_OPT_ADMIN))) {
-				generic_mute_unmute_user(conference, user, mute);
+				generic_feature_action_helper_user(conference, user, action);
 				res = 0;
 				if (match) {
 					return res;
@@ -2575,9 +2681,10 @@
 	return res;
 }
 
-static int cli_mute_unmute_helper(int mute, struct ast_cli_args *a)
+static int cli_feature_action_helper(enum confbridge_feature_action action, struct ast_cli_args *a)
 {
-	int res = generic_mute_unmute_helper(mute, a->argv[2], a->argv[3]);
+	const char *verb;
+	int res = generic_feature_action_helper(action, a->argv[2], a->argv[3]);
 
 	if (res == -1) {
 		ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
@@ -2590,7 +2697,24 @@
 		}
 		return -1;
 	}
-	ast_cli(a->fd, "%s %s from confbridge %s\n", mute ? "Muting" : "Unmuting", a->argv[3], a->argv[2]);
+
+	switch (action) {
+	case CONFBRIDGE_FEATURE_DEAFEN:
+		verb = "Deafening";
+		break;
+	case CONFBRIDGE_FEATURE_UNDEAFEN:
+		verb = "Undeafening";
+		break;
+	case CONFBRIDGE_FEATURE_MUTE:
+		verb = "Muting";
+		break;
+	case CONFBRIDGE_FEATURE_UNMUTE:
+	default:
+		verb = "Unmuting";
+		break;
+	}
+
+	ast_cli(a->fd, "%s %s from confbridge %s\n", verb, a->argv[3], a->argv[2]);
 	return 0;
 }
 
@@ -2620,7 +2744,7 @@
 		return CLI_SHOWUSAGE;
 	}
 
-	cli_mute_unmute_helper(1, a);
+	cli_feature_action_helper(CONFBRIDGE_FEATURE_MUTE, a);
 
 	return CLI_SUCCESS;
 }
@@ -2651,7 +2775,53 @@
 		return CLI_SHOWUSAGE;
 	}
 
-	cli_mute_unmute_helper(0, a);
+	cli_feature_action_helper(CONFBRIDGE_FEATURE_UNMUTE, a);
+
+	return CLI_SUCCESS;
+}
+
+static char *handle_cli_confbridge_deafen(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "confbridge deafen";
+		e->usage =
+			"Usage: confbridge deafen <conference> <channel>\n";
+		return NULL;
+	case CLI_GENERATE:
+		if (a->pos == 2) {
+			return complete_confbridge_name(a->line, a->word, a->pos, a->n);
+		}
+		return NULL;
+	}
+	if (a->argc != 4) {
+		return CLI_SHOWUSAGE;
+	}
+
+	cli_feature_action_helper(CONFBRIDGE_FEATURE_DEAFEN, a);
+
+	return CLI_SUCCESS;
+}
+
+static char *handle_cli_confbridge_undeafen(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "confbridge undeafen";
+		e->usage =
+			"Usage: confbridge undeafen <conference> <channel>\n";
+		return NULL;
+	case CLI_GENERATE:
+		if (a->pos == 2) {
+			return complete_confbridge_name(a->line, a->word, a->pos, a->n);
+		}
+		return NULL;
+	}
+	if (a->argc != 4) {
+		return CLI_SHOWUSAGE;
+	}
+
+	cli_feature_action_helper(CONFBRIDGE_FEATURE_UNDEAFEN, a);
 
 	return CLI_SUCCESS;
 }
@@ -2806,6 +2976,8 @@
 	AST_CLI_DEFINE(handle_cli_confbridge_kick, "Kick participants out of conference bridges."),
 	AST_CLI_DEFINE(handle_cli_confbridge_mute, "Mute participants."),
 	AST_CLI_DEFINE(handle_cli_confbridge_unmute, "Unmute participants."),
+	AST_CLI_DEFINE(handle_cli_confbridge_deafen, "Deafen a participant."),
+	AST_CLI_DEFINE(handle_cli_confbridge_undeafen, "Undeafen a participant."),
 	AST_CLI_DEFINE(handle_cli_confbridge_lock, "Lock a conference."),
 	AST_CLI_DEFINE(handle_cli_confbridge_unlock, "Unlock a conference."),
 	AST_CLI_DEFINE(handle_cli_confbridge_start_record, "Start recording a conference"),
@@ -2958,10 +3130,11 @@
 	return 0;
 }
 
-static int action_mute_unmute_helper(struct mansession *s, const struct message *m, int mute)
+static int action_feature_action_helper(struct mansession *s, const struct message *m, enum confbridge_feature_action action)
 {
 	const char *conference_name = astman_get_header(m, "Conference");
 	const char *channel_name = astman_get_header(m, "Channel");
+	char *verb;
 	int res = 0;
 
 	if (ast_strlen_zero(conference_name)) {
@@ -2977,7 +3150,7 @@
 		return 0;
 	}
 
-	res = generic_mute_unmute_helper(mute, conference_name, channel_name);
+	res = generic_feature_action_helper(action, conference_name, channel_name);
 
 	if (res == -1) {
 		astman_send_error(s, m, "No Conference by that name found.");
@@ -2987,17 +3160,41 @@
 		return 0;
 	}
 
-	astman_send_ack(s, m, mute ? "User muted" : "User unmuted");
+	switch (action) {
+	case CONFBRIDGE_FEATURE_DEAFEN:
+		verb = "User deafened";
+		break;
+	case CONFBRIDGE_FEATURE_UNDEAFEN:
+		verb = "User undeafened";
+		break;
+	case CONFBRIDGE_FEATURE_MUTE:
+		verb = "User muted";
+		break;
+	case CONFBRIDGE_FEATURE_UNMUTE:
+	default:
+		verb = "User unmuted";
+		break;
+	}
+
+	astman_send_ack(s, m, verb);
 	return 0;
 }
 
 static int action_confbridgeunmute(struct mansession *s, const struct message *m)
 {
-	return action_mute_unmute_helper(s, m, 0);
+	return action_feature_action_helper(s, m, CONFBRIDGE_FEATURE_UNMUTE);
 }
 static int action_confbridgemute(struct mansession *s, const struct message *m)
 {
-	return action_mute_unmute_helper(s, m, 1);
+	return action_feature_action_helper(s, m, CONFBRIDGE_FEATURE_MUTE);
+}
+static int action_confbridgeundeafen(struct mansession *s, const struct message *m)
+{
+	return action_feature_action_helper(s, m, CONFBRIDGE_FEATURE_UNDEAFEN);
+}
+static int action_confbridgedeafen(struct mansession *s, const struct message *m)
+{
+	return action_feature_action_helper(s, m, CONFBRIDGE_FEATURE_DEAFEN);
 }
 
 static int action_lock_unlock_helper(struct mansession *s, const struct message *m, int lock)
@@ -3350,6 +3547,8 @@
 	ast_manager_unregister("ConfbridgeListRooms");
 	ast_manager_unregister("ConfbridgeMute");
 	ast_manager_unregister("ConfbridgeUnmute");
+	ast_manager_unregister("ConfbridgeDeafen");
+	ast_manager_unregister("ConfbridgeUndeafen");
 	ast_manager_unregister("ConfbridgeKick");
 	ast_manager_unregister("ConfbridgeUnlock");
 	ast_manager_unregister("ConfbridgeLock");
@@ -3419,6 +3618,8 @@
 	res |= ast_manager_register_xml("ConfbridgeListRooms", EVENT_FLAG_REPORTING, action_confbridgelistrooms);
 	res |= ast_manager_register_xml("ConfbridgeMute", EVENT_FLAG_CALL, action_confbridgemute);
 	res |= ast_manager_register_xml("ConfbridgeUnmute", EVENT_FLAG_CALL, action_confbridgeunmute);
+	res |= ast_manager_register_xml("ConfbridgeDeafen", EVENT_FLAG_CALL, action_confbridgedeafen);
+	res |= ast_manager_register_xml("ConfbridgeUndeafen", EVENT_FLAG_CALL, action_confbridgeundeafen);
 	res |= ast_manager_register_xml("ConfbridgeKick", EVENT_FLAG_CALL, action_confbridgekick);
 	res |= ast_manager_register_xml("ConfbridgeUnlock", EVENT_FLAG_CALL, action_confbridgeunlock);
 	res |= ast_manager_register_xml("ConfbridgeLock", EVENT_FLAG_CALL, action_confbridgelock);
Binary files asterisk-13.0.0.orig/apps/app_confbridge.o and asterisk-13.0.0/apps/app_confbridge.o differ
Binary files asterisk-13.0.0.orig/apps/app_confbridge.so and asterisk-13.0.0/apps/app_confbridge.so differ
Binary files asterisk-13.0.0.orig/apps/app_meetme.o and asterisk-13.0.0/apps/app_meetme.o differ
Binary files asterisk-13.0.0.orig/apps/app_meetme.so and asterisk-13.0.0/apps/app_meetme.so differ
diff -ru asterisk-13.0.0.orig/apps/confbridge/conf_config_parser.c asterisk-13.0.0/apps/confbridge/conf_config_parser.c
--- asterisk-13.0.0.orig/apps/confbridge/conf_config_parser.c	2014-10-31 09:25:50.097163496 -0200
+++ asterisk-13.0.0/apps/confbridge/conf_config_parser.c	2014-10-31 09:23:05.690495201 -0200
@@ -869,6 +869,10 @@
 		ast_string_field_set(sounds, muted, sound_file);
 	} else if (!strcasecmp(sound_name, "sound_unmuted")) {
 		ast_string_field_set(sounds, unmuted, sound_file);
+	} else if (!strcasecmp(sound_name, "sound_deafened")) {
+		ast_string_field_set(sounds, deafened, sound_file);
+	} else if (!strcasecmp(sound_name, "sound_undeafened")) {
+		ast_string_field_set(sounds, undeafened, sound_file);
 	} else if (!strcasecmp(sound_name, "sound_there_are")) {
 		ast_string_field_set(sounds, thereare, sound_file);
 	} else if (!strcasecmp(sound_name, "sound_other_in_party")) {
@@ -1068,6 +1072,7 @@
 	switch (id) {
 	case MENU_ACTION_NOOP:
 	case MENU_ACTION_TOGGLE_MUTE:
+	case MENU_ACTION_TOGGLE_DEAF:
 	case MENU_ACTION_INCREASE_LISTENING:
 	case MENU_ACTION_DECREASE_LISTENING:
 	case MENU_ACTION_INCREASE_TALKING:
@@ -1358,6 +1363,9 @@
 	ast_cli(a->fd,"Start Muted:             %s\n",
 		u_profile.flags & USER_OPT_STARTMUTED?
 		"true" : "false");
+	ast_cli(a->fd,"Start Deaf:              %s\n",
+		u_profile.flags & USER_OPT_STARTDEAF?
+		"true" : "false");
 	ast_cli(a->fd,"MOH When Empty:          %s\n",
 		u_profile.flags & USER_OPT_MUSICONHOLD ?
 		"enabled" : "disabled");
@@ -1562,6 +1570,8 @@
 	ast_cli(a->fd,"sound_kicked:         %s\n", conf_get_sound(CONF_SOUND_KICKED, b_profile.sounds));
 	ast_cli(a->fd,"sound_muted:          %s\n", conf_get_sound(CONF_SOUND_MUTED, b_profile.sounds));
 	ast_cli(a->fd,"sound_unmuted:        %s\n", conf_get_sound(CONF_SOUND_UNMUTED, b_profile.sounds));
+	ast_cli(a->fd,"sound_deafened:       %s\n", conf_get_sound(CONF_SOUND_DEAFENED, b_profile.sounds));
+	ast_cli(a->fd,"sound_undeafened:     %s\n", conf_get_sound(CONF_SOUND_UNDEAFENED, b_profile.sounds));
 	ast_cli(a->fd,"sound_there_are:      %s\n", conf_get_sound(CONF_SOUND_THERE_ARE, b_profile.sounds));
 	ast_cli(a->fd,"sound_other_in_party: %s\n", conf_get_sound(CONF_SOUND_OTHER_IN_PARTY, b_profile.sounds));
 	ast_cli(a->fd,"sound_place_into_conference: %s\n", conf_get_sound(CONF_SOUND_PLACE_IN_CONF, b_profile.sounds));
@@ -1690,6 +1700,9 @@
 			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_NOOP:
 				ast_cli(a->fd, "no_op");
 				break;
@@ -2063,6 +2076,7 @@
 	aco_option_register(&cfg_info, "admin", ACO_EXACT, user_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct user_profile, flags), USER_OPT_ADMIN);
 	aco_option_register(&cfg_info, "marked", ACO_EXACT, user_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct user_profile, flags), USER_OPT_MARKEDUSER);
 	aco_option_register(&cfg_info, "startmuted", ACO_EXACT, user_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct user_profile, flags), USER_OPT_STARTMUTED);
+	aco_option_register(&cfg_info, "startdeaf", ACO_EXACT, user_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct user_profile, flags), USER_OPT_STARTDEAF);
 	aco_option_register(&cfg_info, "music_on_hold_when_empty", ACO_EXACT, user_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct user_profile, flags), USER_OPT_MUSICONHOLD);
 	aco_option_register(&cfg_info, "quiet", ACO_EXACT, user_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct user_profile, flags), USER_OPT_QUIET);
 	aco_option_register_custom(&cfg_info, "announce_user_count_all", ACO_EXACT, user_types, "no", announce_user_count_all_handler, 0);
diff -ru asterisk-13.0.0.orig/apps/confbridge/confbridge_manager.c asterisk-13.0.0/apps/confbridge/confbridge_manager.c
--- asterisk-13.0.0.orig/apps/confbridge/confbridge_manager.c	2014-10-31 09:25:50.097163496 -0200
+++ asterisk-13.0.0/apps/confbridge/confbridge_manager.c	2014-10-31 09:23:05.690495201 -0200
@@ -189,6 +189,38 @@
 			</see-also>
 		</managerEventInstance>
 	</managerEvent>
+	<managerEvent language="en_US" name="ConfbridgeDeafen">
+		<managerEventInstance class="EVENT_FLAG_CALL">
+			<synopsis>Raised when a Confbridge participant deafens.</synopsis>
+			<syntax>
+				<parameter name="Conference">
+					<para>The name of the Confbridge conference.</para>
+				</parameter>
+				<bridge_snapshot/>
+				<channel_snapshot/>
+			</syntax>
+			<see-also>
+				<ref type="managerEvent">ConfbridgeUndeafen</ref>
+				<ref type="application">ConfBridge</ref>
+			</see-also>
+		</managerEventInstance>
+	</managerEvent>
+	<managerEvent language="en_US" name="ConfbridgeUndeafen">
+		<managerEventInstance class="EVENT_FLAG_CALL">
+			<synopsis>Raised when a confbridge participant undeafens.</synopsis>
+			<syntax>
+				<parameter name="Conference">
+					<para>The name of the Confbridge conference.</para>
+				</parameter>
+				<bridge_snapshot/>
+				<channel_snapshot/>
+			</syntax>
+			<see-also>
+				<ref type="managerEvent">ConfbridgeMute</ref>
+				<ref type="application">ConfBridge</ref>
+			</see-also>
+		</managerEventInstance>
+	</managerEvent>
 	<managerEvent language="en_US" name="ConfbridgeTalking">
 		<managerEventInstance class="EVENT_FLAG_CALL">
 			<synopsis>Raised when a confbridge participant unmutes.</synopsis>
@@ -338,6 +370,18 @@
 	ast_free(extra_text);
 }
 
+static void confbridge_deafen_cb(void *data, struct stasis_subscription *sub,
+	struct stasis_message *message)
+{
+	confbridge_publish_manager_event(message, "ConfbridgeDeafen", NULL);
+}
+
+static void confbridge_undeafen_cb(void *data, struct stasis_subscription *sub,
+	struct stasis_message *message)
+{
+	confbridge_publish_manager_event(message, "ConfbridgeUndeafen", NULL);
+}
+
 static void confbridge_talking_cb(void *data, struct stasis_subscription *sub,
 	struct stasis_message *message)
 {
@@ -366,6 +410,8 @@
 STASIS_MESSAGE_TYPE_DEFN(confbridge_stop_record_type);
 STASIS_MESSAGE_TYPE_DEFN(confbridge_mute_type);
 STASIS_MESSAGE_TYPE_DEFN(confbridge_unmute_type);
+STASIS_MESSAGE_TYPE_DEFN(confbridge_deafen_type);
+STASIS_MESSAGE_TYPE_DEFN(confbridge_undeafen_type);
 STASIS_MESSAGE_TYPE_DEFN(confbridge_talking_type);
 
 void manager_confbridge_shutdown(void) {
@@ -377,6 +423,8 @@
 	STASIS_MESSAGE_TYPE_CLEANUP(confbridge_stop_record_type);
 	STASIS_MESSAGE_TYPE_CLEANUP(confbridge_mute_type);
 	STASIS_MESSAGE_TYPE_CLEANUP(confbridge_unmute_type);
+	STASIS_MESSAGE_TYPE_CLEANUP(confbridge_deafen_type);
+	STASIS_MESSAGE_TYPE_CLEANUP(confbridge_undeafen_type);
 	STASIS_MESSAGE_TYPE_CLEANUP(confbridge_talking_type);
 
 	if (bridge_state_router) {
@@ -400,6 +448,8 @@
 	STASIS_MESSAGE_TYPE_INIT(confbridge_stop_record_type);
 	STASIS_MESSAGE_TYPE_INIT(confbridge_mute_type);
 	STASIS_MESSAGE_TYPE_INIT(confbridge_unmute_type);
+	STASIS_MESSAGE_TYPE_INIT(confbridge_deafen_type);
+	STASIS_MESSAGE_TYPE_INIT(confbridge_undeafen_type);
 	STASIS_MESSAGE_TYPE_INIT(confbridge_talking_type);
 
 	bridge_state_router = stasis_message_router_create(
@@ -466,6 +516,20 @@
 		return -1;
 	}
 	if (stasis_message_router_add(bridge_state_router,
+			confbridge_deafen_type(),
+			confbridge_deafen_cb,
+			NULL)) {
+		manager_confbridge_shutdown();
+		return -1;
+	}
+	if (stasis_message_router_add(bridge_state_router,
+			confbridge_undeafen_type(),
+			confbridge_undeafen_cb,
+			NULL)) {
+		manager_confbridge_shutdown();
+		return -1;
+	}
+	if (stasis_message_router_add(bridge_state_router,
 			confbridge_talking_type(),
 			confbridge_talking_cb,
 			NULL)) {
@@ -536,6 +600,20 @@
 			NULL)) {
 		manager_confbridge_shutdown();
 		return -1;
+	}
+	if (stasis_message_router_add(channel_state_router,
+			confbridge_deafen_type(),
+			confbridge_deafen_cb,
+			NULL)) {
+		manager_confbridge_shutdown();
+		return -1;
+	}
+	if (stasis_message_router_add(channel_state_router,
+			confbridge_undeafen_type(),
+			confbridge_undeafen_cb,
+			NULL)) {
+		manager_confbridge_shutdown();
+		return -1;
 	}
 	if (stasis_message_router_add(channel_state_router,
 			confbridge_talking_type(),
diff -ru asterisk-13.0.0.orig/apps/confbridge/include/confbridge.h asterisk-13.0.0/apps/confbridge/include/confbridge.h
--- asterisk-13.0.0.orig/apps/confbridge/include/confbridge.h	2014-10-31 09:25:50.097163496 -0200
+++ asterisk-13.0.0/apps/confbridge/include/confbridge.h	2014-10-31 09:23:05.690495201 -0200
@@ -60,6 +60,7 @@
 	USER_OPT_ANNOUNCEUSERCOUNTALL = (1 << 14), /*!< Sets if the number of users should be announced to everyone. */
 	USER_OPT_JITTERBUFFER =  (1 << 15), /*!< Places a jitterbuffer on the user. */
 	USER_OPT_ANNOUNCE_JOIN_LEAVE_REVIEW = (1 << 16), /*!< modifies ANNOUNCE_JOIN_LEAVE - user reviews the recording before continuing */
+	USER_OPT_STARTDEAF =     (1 << 17), /*!< Set if the caller should be initially set deaf */
 };
 
 enum bridge_profile_flags {
@@ -72,6 +73,7 @@
 
 enum conf_menu_action_id {
 	MENU_ACTION_TOGGLE_MUTE = 1,
+	MENU_ACTION_TOGGLE_DEAF,
 	MENU_ACTION_PLAYBACK,
 	MENU_ACTION_PLAYBACK_AND_CONTINUE,
 	MENU_ACTION_INCREASE_LISTENING,
@@ -146,6 +148,8 @@
 	CONF_SOUND_KICKED,
 	CONF_SOUND_MUTED,
 	CONF_SOUND_UNMUTED,
+	CONF_SOUND_DEAFENED,
+	CONF_SOUND_UNDEAFENED,
 	CONF_SOUND_ONLY_ONE,
 	CONF_SOUND_THERE_ARE,
 	CONF_SOUND_OTHER_IN_PARTY,
@@ -173,6 +177,8 @@
 		AST_STRING_FIELD(kicked);
 		AST_STRING_FIELD(muted);
 		AST_STRING_FIELD(unmuted);
+		AST_STRING_FIELD(deafened);
+		AST_STRING_FIELD(undeafened);
 		AST_STRING_FIELD(onlyone);
 		AST_STRING_FIELD(thereare);
 		AST_STRING_FIELD(otherinparty);
@@ -365,6 +371,8 @@
 	struct conf_menu_entry *menu_entry,
 	struct conf_menu *menu);
 
+struct stasis_message_type *confbridge_deafen_type(void);
+struct stasis_message_type *confbridge_undeafen_type(void);
 
 /*! \brief Looks to see if sound file is stored in bridge profile sounds, if not
  *  default sound is provided.*/
diff -ru asterisk-13.0.0.orig/bridges/bridge_softmix.c asterisk-13.0.0/bridges/bridge_softmix.c
--- asterisk-13.0.0.orig/bridges/bridge_softmix.c	2014-10-31 09:25:50.097163496 -0200
+++ asterisk-13.0.0/bridges/bridge_softmix.c	2014-10-31 09:23:05.690495201 -0200
@@ -942,15 +942,21 @@
 
 			ast_mutex_lock(&sc->lock);
 
-			/* Make SLINEAR write frame from local buffer */
-			ao2_t_replace(sc->write_frame.subclass.format, cur_slin,
-				"Replace softmix channel slin format");
-			sc->write_frame.datalen = softmix_datalen;
-			sc->write_frame.samples = softmix_samples;
-			memcpy(sc->final_buf, buf, softmix_datalen);
+			if (bridge_channel->features && bridge_channel->features->deaf) {
+				/* For deaf channels post a null frame */
+				sc->write_frame.frametype = AST_FRAME_NULL;
+			} else {
+				/* Make SLINEAR write frame from local buffer */
+				sc->write_frame.frametype = AST_FRAME_VOICE;
+				ao2_t_replace(sc->write_frame.subclass.format, cur_slin,
+					"Replace softmix channel slin format");
+				sc->write_frame.datalen = softmix_datalen;
+				sc->write_frame.samples = softmix_samples;
+				memcpy(sc->final_buf, buf, softmix_datalen);
 
-			/* process the softmix channel's new write audio */
-			softmix_process_write_audio(&trans_helper, ast_channel_rawwriteformat(bridge_channel->chan), sc);
+				/* process the softmix channel's new write audio */
+				softmix_process_write_audio(&trans_helper, ast_channel_rawwriteformat(bridge_channel->chan), sc);
+			}
 
 			ast_mutex_unlock(&sc->lock);
 
diff -ru asterisk-13.0.0.orig/configs/samples/confbridge.conf.sample asterisk-13.0.0/configs/samples/confbridge.conf.sample
--- asterisk-13.0.0.orig/configs/samples/confbridge.conf.sample	2014-10-31 09:25:50.100496828 -0200
+++ asterisk-13.0.0/configs/samples/confbridge.conf.sample	2014-10-31 09:23:05.693828534 -0200
@@ -20,6 +20,7 @@
 ;admin=yes     ; Sets if the user is an admin or not. Off by default.
 ;marked=yes    ; Sets if this is a marked user or not. Off by default.
 ;startmuted=yes; Sets if all users should start out muted. Off by default
+;startdeaf=yes ; Sets if all users should start out deaf. Off by default.
 ;music_on_hold_when_empty=yes  ; Sets whether MOH should be played when only
                                ; one person is in the conference or when the
                                ; the user is waiting on a marked user to enter
@@ -222,6 +223,8 @@
 ;sound_kicked ; The sound played to a user who has been kicked from the conference.
 ;sound_muted  ; The sound played when the mute option it toggled on.
 ;sound_unmuted  ; The sound played when the mute option it toggled off.
+;sound_deafened  ; The sound played when the deaf option is toggled on.
+;sound_undeafened  ; The sound played when the deaf option is toggled off.
 ;sound_only_person ; The sound played when the user is the only person in the conference.
 ;sound_only_one ; The sound played to a user when there is only one other
                 ; person is in the conference.
@@ -283,6 +286,8 @@
                                        ; using the '&' character as a delimiter.
 ; 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.
+; toggle_deaf      ; Toggle turning on and off deaf.  Deaf will make the user to hear
+                   ; only silence, but the user will still be able to talk.
 
 ; no_op ; This action does nothing (No Operation). Its only real purpose exists for
         ; being able to reserve a sequence in the config as a menu exit sequence.
diff -ru asterisk-13.0.0.orig/include/asterisk/bridge_features.h asterisk-13.0.0/include/asterisk/bridge_features.h
--- asterisk-13.0.0.orig/include/asterisk/bridge_features.h	2014-10-31 09:25:50.100496828 -0200
+++ asterisk-13.0.0/include/asterisk/bridge_features.h	2014-10-31 09:23:05.693828534 -0200
@@ -273,6 +273,8 @@
 	unsigned int usable:1;
 	/*! TRUE if the channel/bridge is muted. */
 	unsigned int mute:1;
+	/*! TRUE if the channel/bridge is deaf. */
+	unsigned int deaf:1;
 	/*! TRUE if DTMF should be passed into the bridge tech.  */
 	unsigned int dtmf_passthrough:1;
 };
diff -ru asterisk-13.0.0.orig/main/bridge_channel.c asterisk-13.0.0/main/bridge_channel.c
--- asterisk-13.0.0.orig/main/bridge_channel.c	2014-10-31 09:25:50.100496828 -0200
+++ asterisk-13.0.0/main/bridge_channel.c	2014-10-31 09:35:50.917169437 -0200
@@ -43,6 +43,7 @@
 #include "asterisk/app.h"
 #include "asterisk/pbx.h"
 #include "asterisk/channel.h"
+#include "asterisk/format_cache.h"
 #include "asterisk/timing.h"
 #include "asterisk/bridge.h"
 #include "asterisk/bridge_channel.h"
@@ -910,7 +911,21 @@
 		return 0;
 	}
 
-	dup = ast_frdup(fr);
+	if (fr->frametype == AST_FRAME_VOICE &&
+	    (bridge_channel->features && bridge_channel->features->deaf)) {
+		short buf[fr->samples];
+		struct ast_frame sframe = {
+			.frametype = AST_FRAME_VOICE,
+			.subclass.format = ast_format_slin,
+			.data.ptr = buf,
+			.samples = fr->samples,
+			.datalen = sizeof(buf),
+		};
+		memset(buf, 0, sizeof(buf));
+		dup = ast_frdup(&sframe);
+	} else {
+		dup = ast_frdup(fr);
+	}
 	if (!dup) {
 		return -1;
 	}