[asterisk-commits] mjordan: branch mjordan/cdrs-of-doom r386923 - in /team/mjordan/cdrs-of-doom:...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Apr 29 21:40:08 CDT 2013


Author: mjordan
Date: Mon Apr 29 21:40:04 2013
New Revision: 386923

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386923
Log:
Merge in some prep stuff for parking

Modified:
    team/mjordan/cdrs-of-doom/apps/app_cdr.c
    team/mjordan/cdrs-of-doom/funcs/func_cdr.c
    team/mjordan/cdrs-of-doom/main/stasis.c
    team/mjordan/cdrs-of-doom/tests/test_cdr.c

Modified: team/mjordan/cdrs-of-doom/apps/app_cdr.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/cdrs-of-doom/apps/app_cdr.c?view=diff&rev=386923&r1=386922&r2=386923
==============================================================================
--- team/mjordan/cdrs-of-doom/apps/app_cdr.c (original)
+++ team/mjordan/cdrs-of-doom/apps/app_cdr.c Mon Apr 29 21:40:04 2013
@@ -50,9 +50,12 @@
 			CDRs will be created for that channel.</para>
 			<para>If a subsequent call to ResetCDR occurs, all CDRs created for
 			the channel will be enabled.</para>
+			<note><para>This application is deprecated. Please use the CDR_PROP
+			function to disable CDRs on a channel.</para></note>
 		</description>
 		<see-also>
 			<ref type="application">ResetCDR</ref>
+			<ref type="function">CDR_PROP</ref>
 		</see-also>
 	</application>
 	<application name="ResetCDR" language="en_US">
@@ -84,10 +87,13 @@
 			<para>On the other hand, if the <literal>e</literal> option is
 			specified, the effects of the NoCDR application will be lifted. CDRs
 			will be re-enabled for this channel.</para>
+			<note><para>The <literal>e</literal> option is deprecated. Please
+			use the CDR_PROP function instead.</para></note>
 		</description>
 		<see-also>
 			<ref type="application">ForkCDR</ref>
 			<ref type="application">NoCDR</ref>
+			<ref type="function">CDR_PROP</ref>
 		</see-also>
 	</application>
  ***/

Modified: team/mjordan/cdrs-of-doom/funcs/func_cdr.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/cdrs-of-doom/funcs/func_cdr.c?view=diff&rev=386923&r1=386922&r2=386923
==============================================================================
--- team/mjordan/cdrs-of-doom/funcs/func_cdr.c (original)
+++ team/mjordan/cdrs-of-doom/funcs/func_cdr.c Mon Apr 29 21:40:04 2013
@@ -158,12 +158,37 @@
 			<literal>userfield</literal>, and <literal>amaflags</literal>. You may, however, supply
 			a name not on the above list, and create your own variable, whose value can be changed
 			with this function, and this variable will be stored on the CDR.</para>
-			<para>CDRs can only be modified before the bridge between two channels is
+			<note><para>CDRs can only be modified before the bridge between two channels is
 			torn down. For example, CDRs may not be modified after the <literal>Dial</literal>
 			application has returned.</para></note>
 			<para>Example: exten => 1,1,Set(CDR(userfield)=test)</para>
 		</description>
 	</function>
+	<function name="CDR_PROP" language="en_US">
+		<synopsis>
+			Set a property on a channel's CDR.
+		</synopsis>
+		<syntax>
+			<parameter name="name" required="true">
+				<para>The property to set on the CDR.</para>
+				<enumlist>
+					<enum name="party_a">
+						<para>Set this channel as the preferred Party A when
+						channels are associated together.</para>
+						<para>Write-Only</para>
+					</enum>
+					<enum name="disable">
+						<para>Disable CDRs for this channel.</para>
+						<para>Write-Only</para>
+					</enum>
+				</enumlist>
+			</parameter>
+		</syntax>
+		<description>
+			<para>This function sets a property on a channel's CDR. Properties
+			alter the behavior of how the CDR operates for that channel.</para>
+		</description>
+	</function>
  ***/
 
 enum cdr_option_flags {
@@ -181,7 +206,6 @@
 		    char *buf, size_t len)
 {
 	char format_buf[128];
-	char *ret = NULL;
 	struct ast_flags flags = { 0 };
 	RAII_VAR(char *, tempbuf, ast_malloc(128), ast_free);
 	char *info;
@@ -210,17 +234,26 @@
 	}
 
 	if (ast_test_flag(&flags, OPT_FLOAT) && (!strcasecmp("billsec", args.variable) || !strcasecmp("duration", args.variable))) {
-		sprintf(format_buf, "%lf", temp_buf);
-		strcpy(temp_buf, format_buf);
+		long ms;
+		double dtime;
+		sscanf(tempbuf, "%ld", &ms);
+		dtime = (double)(ms / 1000.0);
+		snprintf(tempbuf, sizeof(*tempbuf), "%lf", dtime);
 	} else if (!ast_test_flag(&flags, OPT_UNPARSED)) {
-		if (!strcasecmp("start") || !strcasecmp("end") || (!strcasecmp("answer"))) {
-
-		} else if (!strcasecmp("disposition")) {
+		if (!strcasecmp("start", args.variable)
+				|| !strcasecmp("end", args.variable)
+				|| !strcasecmp("answer", args.variable)) {
+			struct timeval fmt_time;
+			struct ast_tm tm;
+			sscanf(tempbuf, "%ld.%ld", &fmt_time.tv_sec, &fmt_time.tv_usec);
+			ast_localtime(&fmt_time, &tm, NULL);
+			ast_strftime(tempbuf, sizeof(*tempbuf), "%Y-%m-%d %T", &tm);
+		} else if (!strcasecmp("disposition", args.variable)) {
 			int disposition;
 			sscanf(tempbuf, "%8d", &disposition);
 			snprintf(format_buf, sizeof(format_buf), "%s", ast_cdr_disp2str(disposition));
 			strcpy(tempbuf, format_buf);
-		} else if (!strcasecmp("amaflags")) {
+		} else if (!strcasecmp("amaflags", args.variable)) {
 			int amaflags;
 			sscanf(tempbuf, "%8d", &amaflags);
 			snprintf(format_buf, sizeof(format_buf), "%s", ast_channel_amaflags2string(amaflags));
@@ -228,8 +261,8 @@
 		}
 	}
 
-	ast_copy_string(buf, temp_buf, len);
-	return ret ? 0 : -1;
+	ast_copy_string(buf, tempbuf, len);
+	return 0;
 }
 
 static int cdr_write(struct ast_channel *chan, const char *cmd, char *parse,
@@ -255,7 +288,6 @@
 		ast_channel_accountcode_set(chan, value);
 		ast_channel_unlock(chan);
 	} else if (!strcasecmp(args.variable, "peeraccount")) {
-		/* XXX TODO: Deprecate peeraccount. It won't do anything */
 		ast_log(AST_LOG_WARNING, "The 'peeraccount' setting is not supported. Please set the 'accountcode' on the appropriate channel using the CHANNEL function.\n");
 	} else if (!strcasecmp(args.variable, "userfield")) {
 		ast_cdr_setuserfield(ast_channel_name(chan), value);
@@ -279,20 +311,58 @@
 	return 0;
 }
 
+static int cdr_prop_write(struct ast_channel *chan, const char *cmd, char *parse,
+		     const char *value)
+{
+	enum ast_cdr_options option;
+
+	if (!strcasecmp("party_a", cmd)) {
+		option = AST_CDR_FLAG_PARTY_A;
+	} else if (!strcasecmp("disable", cmd)) {
+		option = AST_CDR_FLAG_DISABLE_ALL;
+	} else {
+		ast_log(AST_LOG_WARNING, "Unknown option %s used with CDR_PROP\n", cmd);
+		return 0;
+	}
+
+	if (ast_true(value)) {
+		ast_cdr_set_property(ast_channel_name(chan), option);
+	} else {
+		ast_cdr_clear_property(ast_channel_name(chan), option);
+	}
+	return 0;
+}
+
 static struct ast_custom_function cdr_function = {
 	.name = "CDR",
 	.read = cdr_read,
 	.write = cdr_write,
 };
 
+static struct ast_custom_function cdr_prop_function = {
+	.name = "CDR_PROP",
+	.read = NULL,
+	.write = cdr_prop_write,
+};
+
 static int unload_module(void)
 {
-	return ast_custom_function_unregister(&cdr_function);
+	int res = 0;
+
+	res |= ast_custom_function_unregister(&cdr_function);
+	res |= ast_custom_function_unregister(&cdr_prop_function);
+
+	return res;
 }
 
 static int load_module(void)
 {
-	return ast_custom_function_register(&cdr_function);
+	int res = 0;
+
+	res |= ast_custom_function_register(&cdr_function);
+	res |= ast_custom_function_register(&cdr_prop_function);
+
+	return res;
 }
 
 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Call Detail Record (CDR) dialplan function");

Modified: team/mjordan/cdrs-of-doom/main/stasis.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/cdrs-of-doom/main/stasis.c?view=diff&rev=386923&r1=386922&r2=386923
==============================================================================
--- team/mjordan/cdrs-of-doom/main/stasis.c (original)
+++ team/mjordan/cdrs-of-doom/main/stasis.c Mon Apr 29 21:40:04 2013
@@ -363,7 +363,6 @@
 				ast_log(LOG_DEBUG, "Dropping dispatch\n");
 				break;
 			}
-
 			if (ast_taskprocessor_push(sub->mailbox, dispatch_exec, dispatch) == 0) {
 				/* Ownership transferred to mailbox.
 				 * Don't increment ref, b/c the task processor

Modified: team/mjordan/cdrs-of-doom/tests/test_cdr.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/cdrs-of-doom/tests/test_cdr.c?view=diff&rev=386923&r1=386922&r2=386923
==============================================================================
--- team/mjordan/cdrs-of-doom/tests/test_cdr.c (original)
+++ team/mjordan/cdrs-of-doom/tests/test_cdr.c Mon Apr 29 21:40:04 2013
@@ -1871,21 +1871,18 @@
 	bridge = ast_bridge_basic_new();
 	ast_test_validate(test, bridge != NULL);
 
-	ast_bridge_impart(bridge, chan_charlie, NULL, NULL, 0);
+	ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_charlie, NULL, NULL, 0));
 	while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
-	ast_bridge_impart(bridge, chan_david, NULL, NULL, 0);
+	ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_david, NULL, NULL, 0));
 	while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
-	ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0);
+	ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0));
 	while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
-	ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0);
+	ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0));
 	while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
-	ast_bridge_depart(chan_alice);
-	while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
-	ast_bridge_depart(chan_bob);
-	while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
-	ast_bridge_depart(chan_charlie);
-	while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
-	ast_bridge_depart(chan_david);
+	ast_test_validate(test, 0 == ast_bridge_depart(chan_alice));
+	ast_test_validate(test, 0 == ast_bridge_depart(chan_bob));
+	ast_test_validate(test, 0 == ast_bridge_depart(chan_charlie));
+	ast_test_validate(test, 0 == ast_bridge_depart(chan_david));
 
 	HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
 	HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
@@ -1896,6 +1893,85 @@
 
 	return result;
 }
+
+AST_TEST_DEFINE(test_cdr_park)
+{
+	RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
+	RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
+	RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
+			ao2_cleanup);
+	struct timespec to_sleep = {1, 0};
+
+	struct ast_party_caller bob_caller = BOB_CALLERID;
+	struct ast_party_caller alice_caller = ALICE_CALLERID;
+	struct ast_cdr bob_expected = {
+		.clid = "\"Bob\" <200>",
+		.src = "200",
+		.dst = "200",
+		.dcontext = "default",
+		.channel = CHANNEL_TECH_NAME "/Bob",
+		.lastapp = "Park",
+		.lastdata = "701",
+		.billsec = 1,
+		.amaflags = AST_AMA_DOCUMENTATION,
+		.disposition = AST_CDR_ANSWERED,
+		.accountcode = "200",
+	};
+	struct ast_cdr alice_expected = {
+		.clid = "\"Alice\" <100>",
+		.src = "100",
+		.dst = "100",
+		.dcontext = "default",
+		.channel = CHANNEL_TECH_NAME "/Alice",
+		.lastapp = "Park",
+		.lastdata = "700",
+		.billsec = 1,
+		.amaflags = AST_AMA_DOCUMENTATION,
+		.disposition = AST_CDR_ANSWERED,
+		.accountcode = "100",
+	};
+	enum ast_test_result_state result = AST_TEST_NOT_RUN;
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = __func__;
+		info->category = TEST_CATEGORY;
+		info->summary = "Test cdrs for a single party entering Park";
+		info->description =
+			"Test the properties of a CDR for calls that are\n"
+			"answered, enters Park, and leaves it.\n";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+	SWAP_CONFIG(config, debug_cdr_config);
+	CREATE_ALICE_CHANNEL(chan_alice, &alice_caller, &alice_expected);
+	CREATE_BOB_CHANNEL(chan_bob, &bob_caller, &bob_expected);
+
+	EMULATE_APP_DATA(chan_alice, 1, "Park", "700");
+	ast_setstate(chan_alice, AST_STATE_UP);
+	EMULATE_APP_DATA(chan_bob, 1, "Park", "701");
+	ast_setstate(chan_bob, AST_STATE_UP);
+
+	bridge = ast_bridge_basic_new();
+	ast_test_validate(test, bridge != NULL);
+
+	ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0);
+	ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0);
+	while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
+	ast_bridge_depart(chan_alice);
+	ast_bridge_depart(chan_bob);
+
+	/* And then it hangs up */
+	HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
+	HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
+
+	result = verify_mock_cdr_record(test, &alice_expected, 2);
+
+	return result;
+}
+
 
 AST_TEST_DEFINE(test_cdr_fields)
 {
@@ -2341,6 +2417,8 @@
 	AST_TEST_UNREGISTER(test_cdr_dial_answer_twoparty_bridge_b);
 	AST_TEST_UNREGISTER(test_cdr_dial_answer_multiparty);
 
+	AST_TEST_UNREGISTER(test_cdr_park);
+
 	AST_TEST_UNREGISTER(test_cdr_fields);
 	AST_TEST_UNREGISTER(test_cdr_no_reset_cdr);
 	AST_TEST_UNREGISTER(test_cdr_fork_cdr);
@@ -2378,6 +2456,8 @@
 	AST_TEST_REGISTER(test_cdr_dial_answer_twoparty_bridge_b);
 	AST_TEST_REGISTER(test_cdr_dial_answer_multiparty);
 
+	AST_TEST_REGISTER(test_cdr_park);
+
 	AST_TEST_REGISTER(test_cdr_fields);
 	AST_TEST_REGISTER(test_cdr_no_reset_cdr);
 	AST_TEST_REGISTER(test_cdr_fork_cdr);




More information about the asterisk-commits mailing list