[asterisk-commits] murf: branch murf/CDRfix5 r69623 - in /team/murf/CDRfix5: channels/ funcs/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Jun 16 10:24:15 CDT 2007


Author: murf
Date: Sat Jun 16 10:24:15 2007
New Revision: 69623

URL: http://svn.digium.com/view/asterisk?view=rev&rev=69623
Log:
As per blitzrage's suggestion, I've grouped CDRstart, CDRanswer, CDRclose, and CDRabort, into CDR_CONTROL(action[|handle])

Modified:
    team/murf/CDRfix5/channels/chan_sip.c
    team/murf/CDRfix5/funcs/func_cdr.c

Modified: team/murf/CDRfix5/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/murf/CDRfix5/channels/chan_sip.c?view=diff&rev=69623&r1=69622&r2=69623
==============================================================================
--- team/murf/CDRfix5/channels/chan_sip.c (original)
+++ team/murf/CDRfix5/channels/chan_sip.c Sat Jun 16 10:24:15 2007
@@ -13859,6 +13859,7 @@
 	struct ast_channel *c = p->owner;	/* Our incoming call */
 	struct ast_channel *replacecall = p->refer->refer_call->owner;	/* The channel we're about to take over */
 	struct ast_channel *targetcall;		/* The bridge to the take-over target */
+	extern void ast_channel_log(char *title, struct ast_channel *chan);
 
 	/* Check if we're in ring state */
 	if (replacecall->_state == AST_STATE_RING)
@@ -13911,6 +13912,10 @@
 		If we are talking to internal audio stream, target call is null.
 	*/
 
+	ast_channel_log("=====SIP InvRepl --- C: Incoming:====", c);
+	ast_channel_log("=====SIP InvRepl --- replacecall: ====", replacecall);
+	ast_channel_log("=====SIP InvRepl --- targetcall:====", targetcall);
+	
 	/* Fake call progress */
 	transmit_response(p, "100 Trying", req);
 	ast_setstate(c, AST_STATE_RING);
@@ -14015,7 +14020,10 @@
 	unsigned int required_profile = 0;
 	struct ast_channel *c = NULL;		/* New channel */
 	int reinvite = 0;
-
+	extern void ast_channel_log(char *title, struct ast_channel *chan);
+
+	ast_log(LOG_NOTICE,"in handle_request_invite\n");
+	
 	/* Find out what they support */
 	if (!p->sipoptions) {
 		const char *supported = get_header(req, "Supported");
@@ -14068,6 +14076,7 @@
 		char *start, *to;
 		int error = 0;
 
+		ast_log(LOG_NOTICE,"in handle_request_invite -- a REPLACES header\n");
 		if (p->owner) {
 			ast_debug(3, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid);
 			transmit_response(p, "400 Bad request", req);	/* The best way to not not accept the transfer */
@@ -14167,6 +14176,7 @@
 
 	/* Check if this is an INVITE that sets up a new dialog or
 	   a re-invite in an existing dialog */
+	ast_log(LOG_NOTICE,"in handle_request_invite -- after REPLACES\n");
 
 	if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
 		int newcall = (p->initreq.headers ? TRUE : FALSE);
@@ -14175,6 +14185,7 @@
 		/* This also counts as a pending invite */
 		p->pendinginvite = seqno;
 		check_via(p, req);
+		ast_log(LOG_NOTICE,"in handle_request_invite -- not Ignore\n");
 
 		copy_request(&p->initreq, req);		/* Save this INVITE as the transaction basis */
 		if (sipdebug)
@@ -14205,10 +14216,12 @@
 	} else if (debug)
 		ast_verbose("Ignoring this INVITE request\n");
 
-	
+	ast_log(LOG_NOTICE,"in handle_request_invite -- after Ignore\n");
+
 	if (!p->lastinvite && !ast_test_flag(req, SIP_PKT_IGNORE) && !p->owner) {
 		/* This is a new invite */
 		/* Handle authentication if this is our first invite */
+		ast_log(LOG_NOTICE,"in handle_request_invite -- new Invite\n");
 		res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin);
 		if (res == AUTH_CHALLENGE_SENT) {
 			p->invitestate = INV_COMPLETED;		/* Needs to restart in another INVITE transaction */
@@ -14320,6 +14333,7 @@
 
 	if (replace_id) { 	/* Attended transfer or call pickup - we're the target */
 		/* Go and take over the target call */
+		ast_log(LOG_NOTICE,"in handle_request_invite -- replace_id\n");
 		if (sipdebug)
 			ast_debug(4, "Sending this call to the invite/replcaes handler %s\n", p->callid);
 		return handle_invite_replaces(p, req, debug, ast_test_flag(req, SIP_PKT_IGNORE), seqno, sin);
@@ -14327,6 +14341,9 @@
 
 
 	if (c) {	/* We have a call  -either a new call or an old one (RE-INVITE) */
+		ast_log(LOG_NOTICE,"in handle_request_invite -- c is set!\n");
+		ast_channel_log("---------INVITE------ c set:", c);
+		
 		switch(c->_state) {
 		case AST_STATE_DOWN:
 			ast_debug(2, "%s: New call is still down.... Trying... \n", c->name);
@@ -14506,6 +14523,7 @@
 			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 		}
 	}
+	ast_log(LOG_NOTICE,"in handle_request_invite -- leaving!\n");
 	return res;
 }
 
@@ -14517,6 +14535,7 @@
 					/* Chan 2: Call from Asterisk to target */
 	int res = 0;
 	struct sip_pvt *targetcall_pvt;
+	extern void ast_channel_log(char *title, struct ast_channel *chan);
 
 	/* Check if the call ID of the replaces header does exist locally */
 	if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 
@@ -14575,6 +14594,11 @@
 	}
 
 	ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);	/* Delay hangup */
+
+	ast_channel_log("=====SIP LocAttXfer --- current.chan1:====", current->chan1);
+	ast_channel_log("=====SIP LocAttXfer --- current.chan2 ====", current->chan2);
+	ast_channel_log("=====SIP LocAttXfer --- target.chan1 ====", target.chan1);
+	ast_channel_log("=====SIP LocAttXfer --- target.chan2 ====", target.chan2);
 
 	/* Perform the transfer */
 	res = attempt_transfer(current, &target);
@@ -14690,7 +14714,8 @@
 		return 0;
 	}	
 
-
+	ast_log(LOG_NOTICE,"In Handle_request_refer!\n");
+	
 	/* Check if transfer is allowed from this device */
 	if (p->allowtransfer == TRANSFER_CLOSED ) {
 		/* Transfer not allowed, decline */
@@ -14763,6 +14788,7 @@
 	/* Don't know what else to do right now. */
 	if (ast_test_flag(req, SIP_PKT_IGNORE)) 
 		return res;
+	ast_log(LOG_NOTICE,"In Handle_request_refer 2!\n");
 
 	/* If this is a blind transfer, we have the following
 	channels to work with:
@@ -14810,6 +14836,7 @@
 		return -1;
 	}
 
+	ast_log(LOG_NOTICE,"In Handle_request_refer 3!\n");
 	if (current.chan2) {
 		if (sipdebug)
 			ast_debug(4, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name);
@@ -14818,6 +14845,7 @@
 	}
 
 	ast_set_flag(&p->flags[0], SIP_GOTREFER);	
+	ast_log(LOG_NOTICE,"In Handle_request_refer 4!\n");
 
 	/* Attended transfer: Find all call legs and bridge transferee with target*/
 	if (p->refer->attendedtransfer) {
@@ -14829,6 +14857,7 @@
 		/* Fallthrough if we can't find the call leg internally */
 	}
 
+	ast_log(LOG_NOTICE,"In Handle_request_refer 5!\n");
 
 	/* Parking a call */
 	if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) {
@@ -14844,6 +14873,7 @@
 		sip_park(current.chan2, current.chan1, req, seqno);
 		return res;
 	} 
+	ast_log(LOG_NOTICE,"In Handle_request_refer 6!\n");
 
 	/* Blind transfers and remote attended xfers */
 	transmit_response(p, "202 Accepted", req);
@@ -14862,6 +14892,7 @@
 		if (p->refer->referred_by) 
 			pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by);
 	}
+	ast_log(LOG_NOTICE,"In Handle_request_refer 7!\n");
 	/* Generate a Replaces string to be used in the INVITE during attended transfer */
 	if (!ast_strlen_zero(p->refer->replaces_callid)) {
 		char tempheader[BUFSIZ];
@@ -14879,6 +14910,7 @@
 	ast_channel_unlock(current.chan1);
 	ast_channel_unlock(current.chan2);
 
+	ast_log(LOG_NOTICE,"In Handle_request_refer 7!\n");
 	/* Connect the call */
 
 	/* FAKE ringing if not attended transfer */
@@ -14903,6 +14935,7 @@
 		append_history(p, "Xfer", "Refer failed (only bridged calls).");
 		return -1;
 	}
+	ast_log(LOG_NOTICE,"In Handle_request_refer 8!\n");
 	ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);	/* Delay hangup */
 
 	/* For blind transfers, move the call to the new extensions. For attended transfers on multiple
@@ -14932,6 +14965,7 @@
 		ast_clear_flag(&p->flags[0], SIP_GOTREFER);	
 		res = -1;
 	}
+	ast_log(LOG_NOTICE,"In Handle_request_refer 9!\n");
 	return res;
 }
 

Modified: team/murf/CDRfix5/funcs/func_cdr.c
URL: http://svn.digium.com/view/asterisk/team/murf/CDRfix5/funcs/func_cdr.c?view=diff&rev=69623&r1=69622&r2=69623
==============================================================================
--- team/murf/CDRfix5/funcs/func_cdr.c (original)
+++ team/murf/CDRfix5/funcs/func_cdr.c Sat Jun 16 10:24:15 2007
@@ -215,191 +215,147 @@
 "     2 = BILLING\n"
 "     3 = DOCUMENTATION\n"
 "If a third argument is supplied, it must be a handle that is returned\n"
-"by CDRstart(). In this case, any field can be set in the CDR associated\n"
+"by CDR_CONTROL(start). In this case, any field can be set in the CDR associated\n"
 "with 'handle', except the start, answer and end times, which are set via the\n"
-"CDRstart(), CDRanswer() and CDRclose() functions, respectively. \n"
+"CDR_CONTROL() function, with actions 'start', 'answer', and 'close', respectively.\n"
+"duration and billsec are set via the close action.\n"
 };
 
-static int function_cdr_create(struct ast_channel *chan, const char *cmd,
+
+static int function_cdr_control(struct ast_channel *chan, const char *cmd,
 								   char *parse, char *buf, size_t len)
 {
-	struct ast_cdr *cdr = 0;
-	char *handle;
-
-	/* no args, no options so far */
-	
-	cdr = calloc(sizeof(struct ast_cdr),1);
-
-	if (!cdr) {
-		ast_log(LOG_ERROR,"CDRcreate could not allocate CDR memory!\n");
-	} else {
-		ast_cdr_init(cdr, chan);
-		
-		ast_cdr_start(cdr);
-	}
-	
-	asprintf(&handle, "%lu", (unsigned long)cdr);
-	
-	ast_copy_string(buf, handle, len);
-	free(handle);
-	
-	return 0;
-}
-
-static struct ast_custom_function cdr_create_function = {
-	.name = "CDRstart",
-	.synopsis = "Create and Start a non-attached CDR",
-	.syntax = "CDRstart()",
-	.desc =
-	"This function will create a CDR. This CDR will be initialized from the current channel,\n"
-	"and its start time will be set to the current time.\n" 
-	"It will return a 'handle' (a string of numbers) that can be used by the CDRanswer(),\n"
-	"the CDRclose() funcs to prepare and post a CDR. The CDR() function, given this handle,\n"
-	"can be used to modify any of the variables associated with this CDR.\n",
-	.read = function_cdr_create
-};
-
-static int function_cdr_answer(struct ast_channel *chan, const char *cmd,
-								   char *parse, char *buf, size_t len)
-{
 	struct ast_cdr *cdr;
 	
 	AST_DECLARE_APP_ARGS(args,
+			     AST_APP_ARG(action);
 			     AST_APP_ARG(handle);
 	);
 
 	buf[0] = '\0';
 
 	if (ast_strlen_zero(parse)) {
-		ast_log(LOG_WARNING, "CDRanswer requires an argument, CDRanswer(<handle>)\n");
+		ast_log(LOG_ERROR, "CDR_CONTROL requires an action argument, CDR_CONTROL(action[|<handle>])\n");
 		return -1;
 	}
 
 	AST_STANDARD_APP_ARGS(args, parse);
 
 	if (args.argc < 1) {
-		ast_log(LOG_WARNING, "CDRanswer requires an argument, CDRanswer(<handle>)\n");
+		ast_log(LOG_ERROR, "CDR_CONTROL requires an action argument, CDR_CONTROL(action[|<handle>])\n");
 		return -1;
 	}
-
-	cdr = (struct ast_cdr*)strtoul(args.handle, NULL, 10);
-	ast_cdr_answer(cdr);
-	
-	ast_copy_string(buf, args.handle, len);
-	
+	if (strcasecmp(args.action,"start") == 0) {
+		char *handle;
+		
+		if (args.argc > 1)
+			ast_log(LOG_WARNING, "CDR_CONTROL's start action does not need further arguments. Ignoring '%s'.\n", args.handle);
+
+		cdr = calloc(sizeof(struct ast_cdr),1);
+
+		if (!cdr) {
+			ast_log(LOG_ERROR,"CDRcreate could not allocate CDR memory!\n");
+		} else {
+			ast_cdr_init(cdr, chan);
+			
+			ast_cdr_start(cdr);
+		}
+	
+		asprintf(&handle, "%lu", (unsigned long)cdr);
+	
+		ast_copy_string(buf, handle, len);
+		free(handle);
+	} else if (strcasecmp(args.action,"answer") == 0) {
+		if (args.argc < 2) {
+			ast_log(LOG_ERROR, "CDR_CONTROL's '%s' action requires a 'handle'!\n", args.action);
+			buf[0] = 0;
+			return -1;
+		}
+		cdr = (struct ast_cdr*)strtoul(args.handle, NULL, 10);
+		if (!cdr)
+			return -1;
+		ast_cdr_answer(cdr);
+		ast_copy_string(buf, args.handle, len);
+	} else if (strcasecmp(args.action,"close") == 0) {
+		if (args.argc < 2) {
+			ast_log(LOG_ERROR, "CDR_CONTROL's '%s' action requires a 'handle'!\n", args.action);
+			buf[0] = 0;
+			return -1;
+		}
+		cdr = (struct ast_cdr*)strtoul(args.handle, NULL, 10);
+		if (!cdr)
+			return -1;
+		ast_cdr_end(cdr);
+		ast_cdr_detach(cdr);
+		buf[0] = 0;
+	} else if (strcasecmp(args.action,"abort") == 0) {
+		if (args.argc < 2) {
+			ast_log(LOG_ERROR, "CDR_CONTROL's '%s' action requires a 'handle'!\n", args.action);
+			buf[0] = 0;
+			return -1;
+		}
+		cdr = (struct ast_cdr*)strtoul(args.handle, NULL, 10);
+		if (!cdr)
+			return -1;
+		ast_cdr_free(cdr);
+		buf[0] = 0;
+	} else {
+		ast_log(LOG_ERROR, "CDR_CONTROL does not grok the '%s' action! Command ignored!\n", args.action);
+		ast_copy_string(buf, "BAD.ACTION", len);
+		return -1;
+	}
 	return 0;
 }
 
-static struct ast_custom_function cdr_answer_function = {
-	.name = "CDRanswer",
-	.synopsis = "Sets the Answer time in the CDR associated with the supplied handle to the current time",
-	.syntax = "CDRanswer(handle)",
+static struct ast_custom_function cdr_control_function = {
+	.name = "CDR_CONTROL",
+	.synopsis = "A single function for generating your own CDR's from the dialplan",
+	.syntax = "CDR_CONTROL(action[|handle])",
 	.desc =
-	"This function will Set the start time to the current time in the CDR associated with the argument 'handle'.\n"
-	" This func will return the handle.\n",
-	.read = function_cdr_answer
+"This function is used to create, set times, post, or destroy your own custom CDR's\n"
+"from the dialplan. These CDR's are not stored on the channel as traditional CDR's are.\n"
+"You can open as many CDR's as you wish simultaneously. You have complete control of the\n"
+"contents of the CDR's, via the CDR() function, supplying the 'handle' in the optional third arg.\n"
+"The 'action' argument can be one of:\n"
+"    start     (allocate a CDR, and pass back a 'handle' to it)\n"
+"    answer    (set the answer time to the current time in the CDR associated with the 'handle')\n"
+"    close     (set the end time for the CDR, and post and detach it)\n"
+"    abort     (oops, don't need this CDR after all, free and destroy it without posting)\n"
+"If you specify any action other than 'start', you must also supply a handle.\n"
+"The start action returns a new handle. The answer action returns the same handle it was given.\n"
+"The close and abort actions return an empty string.\n"
+"Every 'start' action should be matched at some point with a 'close' or 'abort' action\n"
+"to avoid memory leaks.\n"
+"\n"
+"This function can be very useful for:\n"
+" 1. Generating CDR's for recording time spent in an application or AGI script.\n"
+" 2. Generating CDR's to record unanswered calls, or calls terminated before they are answered.\n"
+"\n"
+"Example: (in AEL)\n"
+"context test\n"
+"{\n"
+"        5 => {\n"
+"                Set(mycdr=${CDR_CONTROL(start)});\n"
+"                NoOp(CDR_CONTROL(answer) says: ${CDR_CONTROL(answer|${mycdr})} );\n"
+"                Set(CDR(lastapp||${mycdr})=Record+BackGround);\n"
+"                Set(CDR(lastdata||${mycdr})=whoknows);\n"
+"                Record(recording:wav);\n"
+"                Background(recording);\n"
+"                NoOp(CDR_CONTROL(close) says: ${CDR_CONTROL(close|${mycdr})} );\n"
+"        }\n"
+"}\n",
+	
+	.read = function_cdr_control
 };
 
 
-static int function_cdr_close(struct ast_channel *chan, const char *cmd,
-								   char *parse, char *buf, size_t len)
-{
-	struct ast_cdr *cdr;
-	
-	AST_DECLARE_APP_ARGS(args,
-			     AST_APP_ARG(handle);
-	);
-
-	buf[0] = '\0';
-
-	if (ast_strlen_zero(parse)) {
-		ast_log(LOG_WARNING, "CDRclose requires an argument, CDRclose(<handle>)\n");
-		return -1;
-	}
-
-	AST_STANDARD_APP_ARGS(args, parse);
-
-	if (args.argc < 1) {
-		ast_log(LOG_WARNING, "CDRclose requires an argument, CDRclose(<handle>)\n");
-		return -1;
-	}
-
-	cdr = (struct ast_cdr*)strtoul(args.handle, NULL, 10);
-
-	ast_cdr_end(cdr);
-	ast_cdr_detach(cdr);
-	
-	ast_copy_string(buf, args.handle, len);
-	
-	return 0;
-}
-
-static struct ast_custom_function cdr_close_function = {
-	.name = "CDRclose",
-	.synopsis = "Sets the Answer time in the CDR associated with the supplied handle to the current time",
-	.syntax = "CDRclose(handle)",
-	.desc =
-	"This function will Set the start time to the current time in the CDR associated with the argument 'handle'.\n"
-	" This func will return the handle.\n",
-	.read = function_cdr_close
-};
-
-static int function_cdr_abort(struct ast_channel *chan, const char *cmd,
-								   char *parse, char *buf, size_t len)
-{
-	struct ast_cdr *cdr;
-	
-	AST_DECLARE_APP_ARGS(args,
-			     AST_APP_ARG(handle);
-	);
-
-	buf[0] = '\0';
-
-	if (ast_strlen_zero(parse)) {
-		ast_log(LOG_WARNING, "CDRabort requires an argument, CDRabort(<handle>)\n");
-		return -1;
-	}
-
-	AST_STANDARD_APP_ARGS(args, parse);
-
-	if (args.argc < 1) {
-		ast_log(LOG_WARNING, "CDRabort requires an argument, CDRabort(<handle>)\n");
-		return -1;
-	}
-
-	cdr = (struct ast_cdr*)strtoul(args.handle, NULL, 10);
-	
-	if (!cdr)
-		return 0;
-
-	ast_cdr_free(cdr);
-
-	buf[0] = 0;
-	
-	return 0;
-}
-
-static struct ast_custom_function cdr_abort_function = {
-	.name = "CDRabort",
-	.synopsis = "Sets the Answer time in the CDR associated with the supplied handle to the current time",
-	.syntax = "CDRabort(handle)",
-	.desc =
-	"This function will Set the start time to the current time in the CDR associated with the argument 'handle'.\n"
-	" This func will return the handle.\n",
-	.read = function_cdr_abort
-};
-
-
 
 static int unload_module(void)
 {
 	int res = 0;
 	
 	res = ast_custom_function_unregister(&cdr_function);
-	res |= ast_custom_function_unregister(&cdr_create_function);
-	res |= ast_custom_function_unregister(&cdr_answer_function);
-	res |= ast_custom_function_unregister(&cdr_close_function);
-	res |= ast_custom_function_unregister(&cdr_abort_function);
+	res |= ast_custom_function_unregister(&cdr_control_function);
 	return res;
 }
 
@@ -408,10 +364,7 @@
 	int res = 0;
 	
 	res = ast_custom_function_register(&cdr_function);
-	res |= ast_custom_function_register(&cdr_create_function);
-	res |= ast_custom_function_register(&cdr_answer_function);
-	res |= ast_custom_function_register(&cdr_close_function);
-	res |= ast_custom_function_register(&cdr_abort_function);
+	res |= ast_custom_function_register(&cdr_control_function);
 	return res;
 }
 




More information about the asterisk-commits mailing list