mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	Adding a new option to Chanspy(). The 'd' option allows for the spy to
press DTMF digits to switch between spying modes. Pressing 4 activates spy mode, pressing 5 activates whisper mode, and pressing 6 activates barge mode. Use of this feature overrides the normal operation of DTMF numbers. This feature is courtesy of Switchvox. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@116522 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		| @@ -64,7 +64,8 @@ static const char *desc_chan = | ||||
| "    - Dialing a series of digits followed by # builds a channel name to append\n" | ||||
| "      to 'chanprefix'. For example, executing ChanSpy(Agent) and then dialing\n" | ||||
| "      the digits '1234#' while spying will begin spying on the channel\n" | ||||
| "      'Agent/1234'.\n" | ||||
| "      'Agent/1234'. Note that this feature will be overriden if the 'd' option\n" | ||||
| "       is used\n" | ||||
| "  Note: The X option supersedes the three features above in that if a valid\n" | ||||
| "        single digit extension exists in the correct context ChanSpy will\n" | ||||
| "        exit to it. This also disables choosing a channel based on 'chanprefix'\n" | ||||
| @@ -73,6 +74,11 @@ static const char *desc_chan = | ||||
| "    b                      - Only spy on channels involved in a bridged call.\n" | ||||
| "    B                      - Instead of whispering on a single channel barge in on both\n" | ||||
| "                             channels involved in the call.\n" | ||||
| "    d                      - Override the typical numeric DTMF functionality and instead\n" | ||||
| "                             use DTMF to switch between spy modes.\n" | ||||
| "                                     4 = spy mode\n" | ||||
| "                                     5 = whisper mode\n" | ||||
| "                                     6 = barge mode\n" | ||||
| "    g(grp)                 - Only spy on channels in which one or more of the groups \n" | ||||
| "                             listed in 'grp' matches one or more groups from the\n" | ||||
| "                             SPYGROUP variable set on the channel to be spied upon.\n" | ||||
| @@ -126,6 +132,13 @@ static const char *desc_ext = | ||||
| "        exit to it.\n" | ||||
| "  Options:\n" | ||||
| "    b                      - Only spy on channels involved in a bridged call.\n" | ||||
| "    B                      - Instead of whispering on a single channel barge in on both\n" | ||||
| "                             channels involved in the call.\n" | ||||
| "    d                      - Override the typical numeric DTMF functionality and instead\n" | ||||
| "                             use DTMF to switch between spy modes.\n" | ||||
| "                                     4 = spy mode\n" | ||||
| "                                     5 = whisper mode\n" | ||||
| "                                     6 = barge mode\n" | ||||
| "    g(grp)                 - Only spy on channels in which one or more of the groups \n" | ||||
| "                             listed in 'grp' matches one or more groups from the\n" | ||||
| "                             SPYGROUP variable set on the channel to be spied upon.\n" | ||||
| @@ -162,19 +175,20 @@ static const char *desc_ext = | ||||
| ; | ||||
|  | ||||
| enum { | ||||
| 	OPTION_QUIET     = (1 << 0),    /* Quiet, no announcement */ | ||||
| 	OPTION_BRIDGED   = (1 << 1),    /* Only look at bridged calls */ | ||||
| 	OPTION_VOLUME    = (1 << 2),    /* Specify initial volume */ | ||||
| 	OPTION_GROUP     = (1 << 3),    /* Only look at channels in group */ | ||||
| 	OPTION_RECORD    = (1 << 4), | ||||
| 	OPTION_WHISPER   = (1 << 5), | ||||
| 	OPTION_PRIVATE   = (1 << 6),    /* Private Whisper mode */ | ||||
| 	OPTION_READONLY  = (1 << 7),    /* Don't mix the two channels */ | ||||
| 	OPTION_EXIT      = (1 << 8),    /* Exit to a valid single digit extension */ | ||||
| 	OPTION_ENFORCED  = (1 << 9),    /* Enforced mode */ | ||||
| 	OPTION_NOTECH    = (1 << 10),   /* Skip technology name playback */ | ||||
| 	OPTION_BARGE     = (1 << 11),   /* Barge mode (whisper to both channels) */ | ||||
| 	OPTION_NAME      = (1 << 12),   /* Say the name of the person on whom we will spy */ | ||||
| 	OPTION_QUIET             = (1 << 0),    /* Quiet, no announcement */ | ||||
| 	OPTION_BRIDGED           = (1 << 1),    /* Only look at bridged calls */ | ||||
| 	OPTION_VOLUME            = (1 << 2),    /* Specify initial volume */ | ||||
| 	OPTION_GROUP             = (1 << 3),    /* Only look at channels in group */ | ||||
| 	OPTION_RECORD            = (1 << 4), | ||||
| 	OPTION_WHISPER           = (1 << 5), | ||||
| 	OPTION_PRIVATE           = (1 << 6),    /* Private Whisper mode */ | ||||
| 	OPTION_READONLY          = (1 << 7),    /* Don't mix the two channels */ | ||||
| 	OPTION_EXIT              = (1 << 8),    /* Exit to a valid single digit extension */ | ||||
| 	OPTION_ENFORCED          = (1 << 9),    /* Enforced mode */ | ||||
| 	OPTION_NOTECH            = (1 << 10),   /* Skip technology name playback */ | ||||
| 	OPTION_BARGE             = (1 << 11),   /* Barge mode (whisper to both channels) */ | ||||
| 	OPTION_NAME              = (1 << 12),   /* Say the name of the person on whom we will spy */ | ||||
| 	OPTION_DTMF_SWITCH_MODES = (1 << 13),   /*Allow numeric DTMF to switch between chanspy modes */ | ||||
| } chanspy_opt_flags; | ||||
|  | ||||
| enum { | ||||
| @@ -200,6 +214,7 @@ AST_APP_OPTIONS(spy_opts, { | ||||
| 	AST_APP_OPTION('X', OPTION_EXIT), | ||||
| 	AST_APP_OPTION('s', OPTION_NOTECH), | ||||
| 	AST_APP_OPTION_ARG('n', OPTION_NAME, OPT_ARG_NAME), | ||||
| 	AST_APP_OPTION('d', OPTION_DTMF_SWITCH_MODES), | ||||
| }); | ||||
|  | ||||
|  | ||||
| @@ -281,8 +296,22 @@ struct chanspy_ds { | ||||
| 	ast_mutex_t lock; | ||||
| }; | ||||
|  | ||||
| static void change_spy_mode(const char digit, struct ast_flags *flags) | ||||
| { | ||||
| 	if (digit == '4') { | ||||
| 		ast_clear_flag(flags, OPTION_WHISPER); | ||||
| 		ast_clear_flag(flags, OPTION_BARGE); | ||||
| 	} else if (digit == '5') { | ||||
| 		ast_clear_flag(flags, OPTION_BARGE); | ||||
| 		ast_set_flag(flags, OPTION_WHISPER); | ||||
| 	} else if (digit == '6') { | ||||
| 		ast_clear_flag(flags, OPTION_WHISPER); | ||||
| 		ast_set_flag(flags, OPTION_BARGE); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static int channel_spy(struct ast_channel *chan, struct chanspy_ds *spyee_chanspy_ds,  | ||||
| 	int *volfactor, int fd, const struct ast_flags *flags, char *exitcontext)  | ||||
| 	int *volfactor, int fd, struct ast_flags *flags, char *exitcontext)  | ||||
| { | ||||
| 	struct chanspy_translation_helper csth; | ||||
| 	int running = 0, res, x = 0; | ||||
| @@ -327,15 +356,14 @@ static int channel_spy(struct ast_channel *chan, struct chanspy_ds *spyee_chansp | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (ast_test_flag(flags, OPTION_BARGE)) { | ||||
|   		ast_audiohook_init(&csth.whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "ChanSpy"); | ||||
| 		ast_audiohook_init(&csth.bridge_whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "Chanspy"); | ||||
|   		start_spying(spyee, spyer_name, &csth.whisper_audiohook); /* Unlocks spyee */ | ||||
| 		start_spying(ast_bridged_channel(spyee), spyer_name, &csth.bridge_whisper_audiohook); | ||||
| 	} else if (ast_test_flag(flags, OPTION_WHISPER)) { | ||||
| 		ast_audiohook_init(&csth.whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "ChanSpy"); | ||||
| 		start_spying(spyee, spyer_name, &csth.whisper_audiohook); /* Unlocks spyee */ | ||||
|   	} | ||||
| 	ast_channel_lock(chan); | ||||
| 	ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY); | ||||
| 	ast_channel_unlock(chan); | ||||
|  | ||||
|  	ast_audiohook_init(&csth.whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "ChanSpy"); | ||||
| 	ast_audiohook_init(&csth.bridge_whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "Chanspy"); | ||||
|   	start_spying(spyee, spyer_name, &csth.whisper_audiohook); /* Unlocks spyee */ | ||||
| 	start_spying(ast_bridged_channel(spyee), spyer_name, &csth.bridge_whisper_audiohook); | ||||
|  | ||||
| 	ast_channel_unlock(spyee); | ||||
| 	spyee = NULL; | ||||
| @@ -417,7 +445,11 @@ static int channel_spy(struct ast_channel *chan, struct chanspy_ds *spyee_chansp | ||||
| 				ast_debug(2, "Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n", tmp, exitcontext); | ||||
| 			} | ||||
| 		} else if (res >= '0' && res <= '9') { | ||||
| 			inp[x++] = res; | ||||
| 			if (ast_test_flag(flags, OPTION_DTMF_SWITCH_MODES)) { | ||||
| 				change_spy_mode(res, flags); | ||||
| 			} else { | ||||
| 				inp[x++] = res; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if (res == '*') { | ||||
| @@ -445,21 +477,18 @@ static int channel_spy(struct ast_channel *chan, struct chanspy_ds *spyee_chansp | ||||
| 	else | ||||
| 		ast_deactivate_generator(chan); | ||||
|  | ||||
| 	if (ast_test_flag(flags, OPTION_BARGE)) { | ||||
| 		ast_audiohook_lock(&csth.whisper_audiohook); | ||||
| 		ast_audiohook_detach(&csth.whisper_audiohook); | ||||
| 		ast_audiohook_unlock(&csth.whisper_audiohook); | ||||
| 		ast_audiohook_destroy(&csth.whisper_audiohook); | ||||
| 		ast_audiohook_lock(&csth.bridge_whisper_audiohook); | ||||
| 		ast_audiohook_detach(&csth.bridge_whisper_audiohook); | ||||
| 		ast_audiohook_unlock(&csth.bridge_whisper_audiohook); | ||||
| 		ast_audiohook_destroy(&csth.bridge_whisper_audiohook); | ||||
| 	} else if (ast_test_flag(flags, OPTION_WHISPER)) { | ||||
| 		ast_audiohook_lock(&csth.whisper_audiohook); | ||||
| 		ast_audiohook_detach(&csth.whisper_audiohook); | ||||
| 		ast_audiohook_unlock(&csth.whisper_audiohook); | ||||
| 		ast_audiohook_destroy(&csth.whisper_audiohook); | ||||
| 	} | ||||
| 	ast_channel_lock(chan); | ||||
| 	ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); | ||||
| 	ast_channel_unlock(chan); | ||||
|  | ||||
| 	ast_audiohook_lock(&csth.whisper_audiohook); | ||||
| 	ast_audiohook_detach(&csth.whisper_audiohook); | ||||
| 	ast_audiohook_unlock(&csth.whisper_audiohook); | ||||
| 	ast_audiohook_destroy(&csth.whisper_audiohook); | ||||
| 	ast_audiohook_lock(&csth.bridge_whisper_audiohook); | ||||
| 	ast_audiohook_detach(&csth.bridge_whisper_audiohook); | ||||
| 	ast_audiohook_unlock(&csth.bridge_whisper_audiohook); | ||||
| 	ast_audiohook_destroy(&csth.bridge_whisper_audiohook); | ||||
|  | ||||
| 	ast_audiohook_lock(&csth.spy_audiohook); | ||||
| 	ast_audiohook_detach(&csth.spy_audiohook); | ||||
| @@ -580,7 +609,7 @@ redo: | ||||
| 	return setup_chanspy_ds(next, chanspy_ds); | ||||
| } | ||||
|  | ||||
| static int common_exec(struct ast_channel *chan, const struct ast_flags *flags, | ||||
| static int common_exec(struct ast_channel *chan, struct ast_flags *flags, | ||||
| 	int volfactor, const int fd, const char *mygroup, const char *myenforced, | ||||
| 	const char *spec, const char *exten, const char *context, const char *mailbox, | ||||
| 	const char *name_context) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user