[asterisk-commits] kmoore: trunk r397493 - in /trunk: ./ apps/ include/asterisk/ main/ res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Aug 22 17:33:54 CDT 2013


Author: kmoore
Date: Thu Aug 22 17:33:48 2013
New Revision: 397493

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=397493
Log:
Add SayAlphaCase and similar functionality for AGI

This adds a new dialplan application, SayAlphaCase, that performs much
the same function as SayAlpha except that it takes additional options
which allow the user to specify whether the case of each letter should
be announced for uppercase, lowercase, or all letters. Similar
functionality has been added to the SAY ALPHA AGI command via an
optional parameter.

Original Patch by: Kevin Scott Adams
Reported by: Kevin Scott Adams
Review: https://reviewboard.asterisk.org/r/2725/
(closes issue ASTERISK-20782)

Modified:
    trunk/CHANGES
    trunk/apps/app_chanspy.c
    trunk/apps/app_directory.c
    trunk/apps/app_voicemail.c
    trunk/include/asterisk/say.h
    trunk/main/channel.c
    trunk/main/pbx.c
    trunk/main/say.c
    trunk/res/res_agi.c

Modified: trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/trunk/CHANGES?view=diff&rev=397493&r1=397492&r2=397493
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Thu Aug 22 17:33:48 2013
@@ -338,6 +338,10 @@
  * The CONTROL STREAM FILE command now accepts an offsetms parameter. This
    will start the playback of the audio at the position specified. It will
    also return the final position of the file in 'endpos'.
+
+ * The SAY ALPHA command now accepts an additional parameter to control
+   whether it specifies the case of uppercase, lowercase, or all letters to
+   provide functionality similar to SayAlphaCase.
 
 CDR (Call Detail Records)
 ------------------

Modified: trunk/apps/app_chanspy.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_chanspy.c?view=diff&rev=397493&r1=397492&r2=397493
==============================================================================
--- trunk/apps/app_chanspy.c (original)
+++ trunk/apps/app_chanspy.c Thu Aug 22 17:33:48 2013
@@ -1048,7 +1048,7 @@
 								break;
 							}
 						} else {
-							res = ast_say_character_str(chan, peer_name, "", ast_channel_language(chan));
+							res = ast_say_character_str(chan, peer_name, "", ast_channel_language(chan), AST_SAY_CASE_NONE);
 						}
 					}
 					if (ptr && (num = atoi(ptr))) {

Modified: trunk/apps/app_directory.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_directory.c?view=diff&rev=397493&r1=397492&r2=397493
==============================================================================
--- trunk/apps/app_directory.c (original)
+++ trunk/apps/app_directory.c Thu Aug 22 17:33:48 2013
@@ -281,13 +281,13 @@
 		/* If Option 'e' was specified, also read the extension number with the name */
 		if (ast_test_flag(flags, OPT_SAYEXTENSION)) {
 			ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY);
-			res = ast_say_character_str(chan, ext, AST_DIGIT_ANY, ast_channel_language(chan));
+			res = ast_say_character_str(chan, ext, AST_DIGIT_ANY, ast_channel_language(chan), AST_SAY_CASE_NONE);
 		}
 	} else {
-		res = ast_say_character_str(chan, S_OR(name, ext), AST_DIGIT_ANY, ast_channel_language(chan));
+		res = ast_say_character_str(chan, S_OR(name, ext), AST_DIGIT_ANY, ast_channel_language(chan), AST_SAY_CASE_NONE);
 		if (!ast_strlen_zero(name) && ast_test_flag(flags, OPT_SAYEXTENSION)) {
 			ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY);
-			res = ast_say_character_str(chan, ext, AST_DIGIT_ANY, ast_channel_language(chan));
+			res = ast_say_character_str(chan, ext, AST_DIGIT_ANY, ast_channel_language(chan), AST_SAY_CASE_NONE);
 		}
 	}
 

Modified: trunk/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_voicemail.c?view=diff&rev=397493&r1=397492&r2=397493
==============================================================================
--- trunk/apps/app_voicemail.c (original)
+++ trunk/apps/app_voicemail.c Thu Aug 22 17:33:48 2013
@@ -13683,7 +13683,7 @@
 		ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context);
 		res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY);
 		if (!res) {
-			res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, ast_channel_language(chan));
+			res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, ast_channel_language(chan), AST_SAY_CASE_NONE);
 		}
 	}
 

Modified: trunk/include/asterisk/say.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/say.h?view=diff&rev=397493&r1=397492&r2=397493
==============================================================================
--- trunk/include/asterisk/say.h (original)
+++ trunk/include/asterisk/say.h Thu Aug 22 17:33:48 2013
@@ -148,13 +148,23 @@
  */
 SAY_EXTERN int (* ast_say_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) SAY_INIT(ast_say_full);
 
+/*!
+ * \brief Controls how ast_say_character_str denotes the case of characters in a string
+ */
+enum ast_say_case_sensitivity {
+	AST_SAY_CASE_NONE,  /*!< Do not distinguish case on any letters */
+	AST_SAY_CASE_LOWER, /*!< Denote case only on lower case letters, upper case is assumed otherwise */
+	AST_SAY_CASE_UPPER, /*!< Denote case only on upper case letters, lower case is assumed otherwise */
+	AST_SAY_CASE_ALL,   /*!< Denote case on all letters, upper and lower */
+};
+
 /*! \brief
  * function to pronounce character and phonetic strings
  */
 int ast_say_character_str(struct ast_channel *chan, const char *num,
-	const char *ints, const char *lang);
+	const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity);
 
-SAY_EXTERN int (* ast_say_character_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd) SAY_INIT(ast_say_character_str_full);
+SAY_EXTERN int (* ast_say_character_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity, int audiofd, int ctrlfd) SAY_INIT(ast_say_character_str_full);
 
 int ast_say_phonetic_str(struct ast_channel *chan, const char *num,
 	const char *ints, const char *lang);

Modified: trunk/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/channel.c?view=diff&rev=397493&r1=397492&r2=397493
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Thu Aug 22 17:33:48 2013
@@ -7792,9 +7792,9 @@
 }
 
 int ast_say_character_str(struct ast_channel *chan, const char *str,
-	const char *ints, const char *lang)
-{
-	return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
+	const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity)
+{
+	return ast_say_character_str_full(chan, str, ints, lang, sensitivity, -1, -1);
 }
 
 int ast_say_phonetic_str(struct ast_channel *chan, const char *str,

Modified: trunk/main/pbx.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/pbx.c?view=diff&rev=397493&r1=397492&r2=397493
==============================================================================
--- trunk/main/pbx.c (original)
+++ trunk/main/pbx.c Thu Aug 22 17:33:48 2013
@@ -501,6 +501,46 @@
 			<ref type="function">CHANNEL</ref>
 		</see-also>
 	</application>
+	<application name="SayAlphaCase" language="en_US">
+		<synopsis>
+			Say Alpha.
+		</synopsis>
+		<syntax>
+			<parameter name="casetype" required="true" >
+				<enumlist>
+					<enum name="a">
+						<para>Case sensitive (all) pronunciation.
+						(Ex: SayAlphaCase(a,aBc); - lowercase a uppercase b lowercase c).</para>
+					</enum>
+					<enum name="l">
+						<para>Case sensitive (lower) pronunciation.
+						(Ex: SayAlphaCase(l,aBc); - lowercase a b lowercase c).</para>
+					</enum>
+					<enum name="n">
+						<para>Case insensitive pronunciation. Equivalent to SayAlpha.
+						(Ex: SayAlphaCase(n,aBc) - a b c).</para>
+					</enum>
+					<enum name="u">
+						<para>Case sensitive (upper) pronunciation.
+						(Ex: SayAlphaCase(u,aBc); - a uppercase b c).</para>
+					</enum>
+				</enumlist>
+			</parameter>
+			<parameter name="string" required="true" />
+		</syntax>
+		<description>
+			<para>This application will play the sounds that correspond to the letters of the
+			given <replaceable>string</replaceable>.  Optionally, a <replaceable>casetype</replaceable> may be
+			specified.  This will be used for case-insensitive or case-sensitive pronunciations.</para>
+		</description>
+		<see-also>
+			<ref type="application">SayDigits</ref>
+			<ref type="application">SayNumber</ref>
+			<ref type="application">SayPhonetic</ref>
+			<ref type="application">SayAlpha</ref>
+			<ref type="function">CHANNEL</ref>
+		</see-also>
+	</application>
 	<application name="SayDigits" language="en_US">
 		<synopsis>
 			Say Digits.
@@ -1122,6 +1162,7 @@
 static int pbx_builtin_saynumber(struct ast_channel *, const char *);
 static int pbx_builtin_saydigits(struct ast_channel *, const char *);
 static int pbx_builtin_saycharacters(struct ast_channel *, const char *);
+static int pbx_builtin_saycharacters_case(struct ast_channel *, const char *);
 static int pbx_builtin_sayphonetic(struct ast_channel *, const char *);
 static int matchcid(const char *cidpattern, const char *callerid);
 #ifdef NEED_DEBUG
@@ -1297,6 +1338,7 @@
 	{ "RaiseException", pbx_builtin_raise_exception },
 	{ "Ringing",        pbx_builtin_ringing },
 	{ "SayAlpha",       pbx_builtin_saycharacters },
+	{ "SayAlphaCase",   pbx_builtin_saycharacters_case },
 	{ "SayDigits",      pbx_builtin_saydigits },
 	{ "SayNumber",      pbx_builtin_saynumber },
 	{ "SayPhonetic",    pbx_builtin_sayphonetic },
@@ -11260,12 +11302,60 @@
 	return res;
 }
 
+static int pbx_builtin_saycharacters_case(struct ast_channel *chan, const char *data)
+{
+	int res = 0;
+	int sensitivity = 0;
+	char *parse;
+	AST_DECLARE_APP_ARGS(args,
+		AST_APP_ARG(options);
+		AST_APP_ARG(characters);
+	);
+
+	if (ast_strlen_zero(data)) {
+		ast_log(LOG_WARNING, "SayAlphaCase requires two arguments (options, characters)\n");
+		return 0;
+	}
+
+	parse = ast_strdupa(data);
+	AST_STANDARD_APP_ARGS(args, parse);
+
+	if (!args.options || strlen(args.options) != 1) {
+		ast_log(LOG_WARNING, "SayAlphaCase options are mutually exclusive and required\n");
+		return 0;
+	}
+
+	switch (args.options[0]) {
+	case 'a':
+		sensitivity = AST_SAY_CASE_ALL;
+		break;
+	case 'l':
+		sensitivity = AST_SAY_CASE_LOWER;
+		break;
+	case 'n':
+		sensitivity = AST_SAY_CASE_NONE;
+		break;
+	case 'u':
+		sensitivity = AST_SAY_CASE_UPPER;
+		break;
+	default:
+		ast_log(LOG_WARNING, "Invalid option: '%s'\n", args.options);
+		return 0;
+	}
+
+	res = ast_say_character_str(chan, args.characters, "", ast_channel_language(chan), sensitivity);
+
+	return res;
+}
+
 static int pbx_builtin_saycharacters(struct ast_channel *chan, const char *data)
 {
 	int res = 0;
 
-	if (data)
-		res = ast_say_character_str(chan, data, "", ast_channel_language(chan));
+	if (data) {
+		res = ast_say_character_str(chan, data, "", ast_channel_language(chan), AST_SAY_CASE_NONE);
+	}
+
 	return res;
 }
 

Modified: trunk/main/say.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/say.c?view=diff&rev=397493&r1=397492&r2=397493
==============================================================================
--- trunk/main/say.c (original)
+++ trunk/main/say.c Thu Aug 22 17:33:48 2013
@@ -61,13 +61,15 @@
 static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang);
 
 
-static int say_character_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
+static int say_character_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity, int audiofd, int ctrlfd)
 {
 	const char *fn;
 	char fnbuf[10], asciibuf[20] = "letters/ascii";
 	char ltr;
 	int num = 0;
 	int res = 0;
+	int upper = 0;
+	int lower = 0;
 
 	while (str[num] && !res) {
 		fn = NULL;
@@ -121,9 +123,35 @@
 			break;
 		default:
 			ltr = str[num];
-			if ('A' <= ltr && ltr <= 'Z') ltr += 'a' - 'A';		/* file names are all lower-case */
-			strcpy(fnbuf, "letters/X");
-			fnbuf[8] = ltr;
+			if ('A' <= ltr && ltr <= 'Z') {
+				ltr += 'a' - 'A';		/* file names are all lower-case */
+				switch (sensitivity) {
+				case AST_SAY_CASE_UPPER:
+				case AST_SAY_CASE_ALL:
+					upper = !upper;
+				case AST_SAY_CASE_LOWER:
+				case AST_SAY_CASE_NONE:
+					break;
+				}
+			} else if ('a' <= ltr && ltr <= 'z') {
+				switch (sensitivity) {
+				case AST_SAY_CASE_LOWER:
+				case AST_SAY_CASE_ALL:
+					lower = !lower;
+				case AST_SAY_CASE_UPPER:
+				case AST_SAY_CASE_NONE:
+					break;
+				}
+			}
+
+			if (upper) {
+				strcpy(fnbuf, "uppercase");
+			} else if (lower) {
+				strcpy(fnbuf, "lowercase");
+			} else {
+				strcpy(fnbuf, "letters/X");
+				fnbuf[8] = ltr;
+			}
 			fn = fnbuf;
 		}
 		if ((fn && ast_fileexists(fn, NULL, lang) > 0) ||
@@ -136,6 +164,9 @@
 					res = ast_waitstream(chan, ints);
 			}
 			ast_stopstream(chan);
+		}
+		if (upper || lower) {
+			continue;
 		}
 		num++;
 	}

Modified: trunk/res/res_agi.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_agi.c?view=diff&rev=397493&r1=397492&r2=397493
==============================================================================
--- trunk/res/res_agi.c (original)
+++ trunk/res/res_agi.c Thu Aug 22 17:33:48 2013
@@ -2313,11 +2313,37 @@
 static int handle_sayalpha(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
 {
 	int res;
-
-	if (argc != 4)
-		return RESULT_SHOWUSAGE;
-
-	res = ast_say_character_str_full(chan, argv[2], argv[3], ast_channel_language(chan), agi->audio, agi->ctrl);
+	int sensitivity = AST_SAY_CASE_NONE;
+
+	if (argc < 4 || argc > 5) {
+		return RESULT_SHOWUSAGE;
+	}
+
+	if (argc > 4) {
+		switch (argv[4][0]) {
+		case 'a':
+		case 'A':
+			sensitivity = AST_SAY_CASE_ALL;
+			break;
+		case 'l':
+		case 'L':
+			sensitivity = AST_SAY_CASE_LOWER;
+			break;
+		case 'n':
+		case 'N':
+			sensitivity = AST_SAY_CASE_NONE;
+			break;
+		case 'u':
+		case 'U':
+			sensitivity = AST_SAY_CASE_UPPER;
+			break;
+		case '\0':
+			break;
+		default:
+			return RESULT_SHOWUSAGE;
+		}
+	}
+	res = ast_say_character_str_full(chan, argv[2], argv[3], ast_channel_language(chan), sensitivity, agi->audio, agi->ctrl);
 	if (res == 1) /* New command */
 		return RESULT_SUCCESS;
 	ast_agi_send(agi->fd, chan, "200 result=%d\n", res);




More information about the asterisk-commits mailing list