[asterisk-commits] file: trunk r186382 - in /trunk: channels/ include/asterisk/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Apr 3 11:47:33 CDT 2009


Author: file
Date: Fri Apr  3 11:47:27 2009
New Revision: 186382

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=186382
Log:
Add better support for relaying success or failure of the ast_transfer() API call.

This API call now waits for a special frame from the underlying channel driver to
indicate success or failure. This allows the return value to truly convey whether
the transfer worked or not. In the case of the Transfer() dialplan application this
means the value of the TRANSFERSTATUS dialplan variable is actually true.

(closes issue #12713)
Reported by: davidw
Tested by: file

Modified:
    trunk/channels/chan_iax2.c
    trunk/channels/chan_sip.c
    trunk/include/asterisk/frame.h
    trunk/main/channel.c

Modified: trunk/channels/chan_iax2.c
URL: http://svn.digium.com/svn-view/asterisk/trunk/channels/chan_iax2.c?view=diff&rev=186382&r1=186381&r2=186382
==============================================================================
--- trunk/channels/chan_iax2.c (original)
+++ trunk/channels/chan_iax2.c Fri Apr  3 11:47:27 2009
@@ -4413,6 +4413,7 @@
 	unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
 	struct iax_ie_data ied = { "", };
 	char tmp[256], *context;
+	enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
 	ast_copy_string(tmp, dest, sizeof(tmp));
 	context = strchr(tmp, '@');
 	if (context) {
@@ -4423,6 +4424,7 @@
 	if (context)
 		iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
 	ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
+	ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message));
 	return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
 }
 	

Modified: trunk/channels/chan_sip.c
URL: http://svn.digium.com/svn-view/asterisk/trunk/channels/chan_sip.c?view=diff&rev=186382&r1=186381&r2=186382
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Fri Apr  3 11:47:27 2009
@@ -17045,6 +17045,8 @@
   */
 static void handle_response_refer(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno)
 {
+	enum ast_control_transfer message = AST_TRANSFER_FAILED;
+
 	/* If no refer structure exists, then do nothing */
 	if (!p->refer)
 		return;
@@ -17064,12 +17066,18 @@
 		if (ast_strlen_zero(p->authname)) {
 			ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n",
 				ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
+			if (p->owner) {
+				ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
+			}
 			pvt_set_needdestroy(p, "unable to authenticate REFER");
 		}
 		if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_REFER, 0)) {
 			ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From"));
 			p->refer->status = REFER_NOAUTH;
-			pvt_set_needdestroy(p, "failed to authenticat REFER");
+			if (p->owner) {
+				ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
+			}
+			pvt_set_needdestroy(p, "failed to authenticate REFER");
 		}
 		break;
 	case 481: /* Call leg does not exist */
@@ -17090,11 +17098,17 @@
 		ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to);
 		pvt_set_needdestroy(p, "received 500/501 response");
 		p->refer->status = REFER_FAILED;
+		if (p->owner) {
+			ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
+		}
 		break;
 	case 603:   /* Transfer declined */
 		ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to);
 		p->refer->status = REFER_FAILED;
 		pvt_set_needdestroy(p, "received 603 response");
+		if (p->owner) {
+			ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
+		}
 		break;
 	}
 }
@@ -18129,7 +18143,11 @@
 		if (!success) {
 			ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n");
 		}
-		
+
+		if (p->owner) {
+			enum ast_control_transfer message = success ? AST_TRANSFER_SUCCESS : AST_TRANSFER_FAILED;
+			ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
+		}
 		/* Confirm that we received this packet */
 		transmit_response(p, "200 OK", req);
 	} else if (p->mwi && !strcmp(event, "message-summary")) {
@@ -24311,6 +24329,11 @@
 
 	sip_scheddestroy(p, SIP_TRANS_TIMEOUT);	/* Make sure we stop send this reply. */
 	sip_alreadygone(p);
+
+	if (p->owner) {
+		enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
+		ast_queue_control_data(p->owner, AST_CONTROL_TRANSFER, &message, sizeof(message));
+	}
 	/* hangup here */
 	return 0;
 }

Modified: trunk/include/asterisk/frame.h
URL: http://svn.digium.com/svn-view/asterisk/trunk/include/asterisk/frame.h?view=diff&rev=186382&r1=186381&r2=186382
==============================================================================
--- trunk/include/asterisk/frame.h (original)
+++ trunk/include/asterisk/frame.h Fri Apr  3 11:47:27 2009
@@ -319,6 +319,7 @@
 	AST_CONTROL_VIDUPDATE = 18,	/*!< Indicate video frame update */
 	AST_CONTROL_T38 = 19,		/*!< T38 state change request/notification */
 	AST_CONTROL_SRCUPDATE = 20,     /*!< Indicate source of media has changed */
+	AST_CONTROL_TRANSFER = 21,      /*!< Indicate status of a transfer request */
 };
 
 enum ast_control_t38 {
@@ -327,6 +328,11 @@
 	AST_T38_NEGOTIATED,		/*!< T38 negotiated (fax mode) */
 	AST_T38_TERMINATED,		/*!< T38 terminated (back to voice) */
 	AST_T38_REFUSED			/*!< T38 refused for some reason (usually rejected by remote end) */
+};
+
+enum ast_control_transfer {
+	AST_TRANSFER_SUCCESS = 0, /*!< Transfer request on the channel worked */
+	AST_TRANSFER_FAILED,      /*!< Transfer request on the channel failed */
 };
 
 #define AST_SMOOTHER_FLAG_G729		(1 << 0)

Modified: trunk/main/channel.c
URL: http://svn.digium.com/svn-view/asterisk/trunk/main/channel.c?view=diff&rev=186382&r1=186381&r2=186382
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Fri Apr  3 11:47:27 2009
@@ -2994,6 +2994,7 @@
 	case AST_CONTROL_ANSWER:
 	case AST_CONTROL_HANGUP:
 	case AST_CONTROL_T38:
+	case AST_CONTROL_TRANSFER:
 		return 0;
 
 	case AST_CONTROL_CONGESTION:
@@ -3080,6 +3081,7 @@
 	case AST_CONTROL_HOLD:
 	case AST_CONTROL_UNHOLD:
 	case AST_CONTROL_T38:
+	case AST_CONTROL_TRANSFER:
 		/* Nothing left to do for these. */
 		res = 0;
 		break;
@@ -3759,6 +3761,37 @@
 			res = 0;
 	}
 	ast_channel_unlock(chan);
+
+	if (res < 0) {
+		return res;
+	}
+
+	for (;;) {
+		struct ast_frame *fr;
+
+		res = ast_waitfor(chan, -1);
+
+		if (res < 0 || !(fr = ast_read(chan))) {
+			res = -1;
+			break;
+		}
+
+		if (fr->frametype == AST_FRAME_CONTROL && fr->subclass == AST_CONTROL_TRANSFER) {
+			enum ast_control_transfer *message = fr->data.ptr;
+
+			if (*message == AST_TRANSFER_SUCCESS) {
+				res = 1;
+			} else {
+				res = -1;
+			}
+
+			ast_frfree(fr);
+			break;
+		}
+
+		ast_frfree(fr);
+	}
+
 	return res;
 }
 




More information about the asterisk-commits mailing list