[asterisk-commits] qwell: trunk r389746 - in /trunk: ./ channels/ include/asterisk/ main/ res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri May 24 16:21:40 CDT 2013


Author: qwell
Date: Fri May 24 16:21:25 2013
New Revision: 389746

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=389746
Log:
Split Hold event into Hold/Unhold, and move it into core.

(closes issue ASTERISK-21487)
Review: https://reviewboard.asterisk.org/r/2565/

Modified:
    trunk/   (props changed)
    trunk/CHANGES
    trunk/channels/chan_dahdi.c
    trunk/channels/chan_h323.c
    trunk/channels/chan_iax2.c
    trunk/channels/chan_mgcp.c
    trunk/channels/chan_misdn.c
    trunk/channels/chan_motif.c
    trunk/channels/chan_sip.c
    trunk/channels/chan_skinny.c
    trunk/channels/chan_unistim.c
    trunk/channels/sig_analog.c
    trunk/channels/sig_pri.c
    trunk/include/asterisk/channel.h
    trunk/include/asterisk/stasis_channels.h
    trunk/main/channel.c
    trunk/main/manager_channels.c
    trunk/main/stasis_channels.c
    trunk/res/res_sip_sdp_rtp.c

Propchange: trunk/
------------------------------------------------------------------------------
    automerge = *

Propchange: trunk/
------------------------------------------------------------------------------
    automerge-email = jparker at digium.com

Propchange: trunk/
------------------------------------------------------------------------------
    svnmerge-integrated = /trunk:1-389738

Modified: trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/trunk/CHANGES?view=diff&rev=389746&r1=389745&r2=389746
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Fri May 24 16:21:25 2013
@@ -95,6 +95,10 @@
  * The AMI 'Status' response event to the AMI Status action replaces the
    BridgedChannel and BridgedUniqueid headers with the BridgeID header to
    indicate what bridge the channel is currently in.
+
+ * The AMI 'Hold' event has been moved out of individual channel drivers, into
+   core, and is now two events: Hold and Unhold.  The status field has been
+   removed.
 
 Channel Drivers
 ------------------

Modified: trunk/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_dahdi.c?view=diff&rev=389746&r1=389745&r2=389746
==============================================================================
--- trunk/channels/chan_dahdi.c (original)
+++ trunk/channels/chan_dahdi.c Fri May 24 16:21:25 2013
@@ -6560,7 +6560,7 @@
 				p->owner = p->subs[SUB_REAL].owner;
 				if (ast_channel_state(p->owner) != AST_STATE_UP)
 					p->subs[SUB_REAL].needanswer = 1;
-				ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
+				ast_queue_unhold(p->subs[SUB_REAL].owner);
 			} else if (p->subs[SUB_THREEWAY].dfd > -1) {
 				swap_subs(p, SUB_THREEWAY, SUB_REAL);
 				unalloc_sub(p, SUB_THREEWAY);
@@ -6582,9 +6582,7 @@
 				/* This is actually part of a three way, placed on hold.  Place the third part
 				   on music on hold now */
 				if (p->subs[SUB_THREEWAY].owner) {
-					ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
-						S_OR(p->mohsuggest, NULL),
-						!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
+					ast_queue_hold(p->subs[SUB_THREEWAY].owner, p->mohsuggest);
 				}
 				p->subs[SUB_THREEWAY].inthreeway = 0;
 				/* Make it the call wait now */
@@ -6597,9 +6595,7 @@
 				/* The other party of the three way call is currently in a call-wait state.
 				   Start music on hold for them, and take the main guy out of the third call */
 				if (p->subs[SUB_CALLWAIT].owner) {
-					ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
-						S_OR(p->mohsuggest, NULL),
-						!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
+					ast_queue_hold(p->subs[SUB_CALLWAIT].owner, p->mohsuggest);
 				}
 				p->subs[SUB_CALLWAIT].inthreeway = 0;
 			}
@@ -7851,7 +7847,7 @@
 	if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
 		/* The three-way person we're about to transfer to could still be in MOH, so
 		   stop it now */
-		ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_UNHOLD);
+		ast_queue_unhold(p->subs[SUB_THREEWAY].owner);
 		if (ast_channel_state(p->subs[SUB_REAL].owner) == AST_STATE_RINGING) {
 			ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_RINGING);
 		}
@@ -7867,7 +7863,7 @@
 		ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
 		unalloc_sub(p, SUB_THREEWAY);
 	} else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
-		ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
+		ast_queue_unhold(p->subs[SUB_REAL].owner);
 		if (ast_channel_state(p->subs[SUB_THREEWAY].owner) == AST_STATE_RINGING) {
 			ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_RINGING);
 		}
@@ -8535,7 +8531,7 @@
 				/* Make sure it stops ringing */
 				dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK);
 				/* Okay -- probably call waiting*/
-				ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
+				ast_queue_unhold(p->owner);
 				p->subs[idx].needunhold = 1;
 				break;
 			case AST_STATE_RESERVED:
@@ -8690,14 +8686,10 @@
 				p->cid_suppress_expire = 0;
 				/* Start music on hold if appropriate */
 				if (!p->subs[SUB_CALLWAIT].inthreeway) {
-					ast_queue_control_data(p->subs[SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
-						S_OR(p->mohsuggest, NULL),
-						!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
+					ast_queue_hold(p->subs[SUB_CALLWAIT].owner, p->mohsuggest);
 				}
 				p->subs[SUB_CALLWAIT].needhold = 1;
-				ast_queue_control_data(p->subs[SUB_REAL].owner, AST_CONTROL_HOLD,
-					S_OR(p->mohsuggest, NULL),
-					!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
+				ast_queue_hold(p->subs[SUB_REAL].owner, p->mohsuggest);
 				p->subs[SUB_REAL].needunhold = 1;
 			} else if (!p->subs[SUB_THREEWAY].owner) {
 				if (!p->threewaycalling) {
@@ -8775,9 +8767,7 @@
 						ast_verb(3, "Started three way call on channel %d\n", p->channel);
 
 						/* Start music on hold */
-						ast_queue_control_data(p->subs[SUB_THREEWAY].owner, AST_CONTROL_HOLD,
-							S_OR(p->mohsuggest, NULL),
-							!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
+						ast_queue_hold(p->subs[SUB_THREEWAY].owner, p->mohsuggest);
 						p->subs[SUB_THREEWAY].needhold = 1;
 					}
 					ast_callid_threadstorage_auto_clean(callid, callid_created);
@@ -8814,8 +8804,9 @@
 							swap_subs(p, SUB_THREEWAY, SUB_REAL);
 							otherindex = SUB_REAL;
 						}
-						if (p->subs[otherindex].owner)
-							ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD);
+						if (p->subs[otherindex].owner) {
+							ast_queue_unhold(p->subs[otherindex].owner);
+						}
 						p->subs[otherindex].needunhold = 1;
 						p->owner = p->subs[SUB_REAL].owner;
 					} else {
@@ -8823,8 +8814,9 @@
 						swap_subs(p, SUB_THREEWAY, SUB_REAL);
 						ast_channel_softhangup_internal_flag_add(p->subs[SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
 						p->owner = p->subs[SUB_REAL].owner;
-						if (p->subs[SUB_REAL].owner)
-							ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
+						if (p->subs[SUB_REAL].owner) {
+							ast_queue_unhold(p->subs[SUB_REAL].owner);
+						}
 						p->subs[SUB_REAL].needunhold = 1;
 						dahdi_enable_ec(p);
 					}
@@ -9017,8 +9009,9 @@
 			(res != DAHDI_EVENT_HOOKCOMPLETE)) {
 			ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res);
 			p->owner = p->subs[SUB_REAL].owner;
-			if (p->owner)
-				ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
+			if (p->owner) {
+				ast_queue_unhold(p->owner);
+			}
 			p->subs[SUB_REAL].needunhold = 1;
 		}
 		switch (res) {
@@ -9062,7 +9055,7 @@
 				p->callwaitingrepeat = 0;
 				p->cidcwexpire = 0;
 				p->cid_suppress_expire = 0;
-				ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
+				ast_queue_unhold(p->owner);
 				p->subs[SUB_REAL].needunhold = 1;
 			} else
 				ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
@@ -10699,7 +10692,7 @@
 					swap_subs(p, SUB_REAL, SUB_THREEWAY);
 					unalloc_sub(p, SUB_THREEWAY);
 					p->owner = p->subs[SUB_REAL].owner;
-					ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
+					ast_queue_unhold(p->subs[SUB_REAL].owner);
 					ast_hangup(chan);
 					goto quit;
 				} else {

Modified: trunk/channels/chan_h323.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_h323.c?view=diff&rev=389746&r1=389745&r2=389746
==============================================================================
--- trunk/channels/chan_h323.c (original)
+++ trunk/channels/chan_h323.c Fri May 24 16:21:25 2013
@@ -2096,18 +2096,17 @@
 				ast_queue_control(pvt->owner, AST_CONTROL_PROGRESS);
 			switch (rtp_change) {
 			case NEED_HOLD:
-				ast_queue_control(pvt->owner, AST_CONTROL_HOLD);
+				ast_queue_hold(pvt->owner, NULL);
 				break;
 			case NEED_UNHOLD:
-				ast_queue_control(pvt->owner, AST_CONTROL_UNHOLD);
+				ast_queue_unhold(pvt->owner);
 				break;
 			default:
 				break;
 			}
 			ast_channel_unlock(pvt->owner);
 			pvt_native = ast_format_cap_destroy(pvt_native);
-		}
-		else {
+		} else {
 			if (pvt->options.progress_audio)
 				pvt->newcontrol = AST_CONTROL_PROGRESS;
 			else if (rtp_change == NEED_HOLD)
@@ -2599,10 +2598,11 @@
 	if (!pvt)
 		return;
 	if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
-		if (is_hold)
-			ast_queue_control(pvt->owner, AST_CONTROL_HOLD);
-		else
-			ast_queue_control(pvt->owner, AST_CONTROL_UNHOLD);
+		if (is_hold) {
+			ast_queue_hold(pvt->owner, NULL);
+		} else {
+			ast_queue_unhold(pvt->owner);
+		}
 		ast_channel_unlock(pvt->owner);
 	}
 	else {

Modified: trunk/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_iax2.c?view=diff&rev=389746&r1=389745&r2=389746
==============================================================================
--- trunk/channels/chan_iax2.c (original)
+++ trunk/channels/chan_iax2.c Fri May 24 16:21:25 2013
@@ -3095,6 +3095,52 @@
 }
 
 /*!
+ * \brief Queue a hold frame on the ast_channel owner
+ *
+ * This function queues a hold frame on the owner of the IAX2 pvt struct that
+ * is active for the given call number.
+ *
+ * \pre Assumes lock for callno is already held.
+ *
+ * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
+ * was valid before calling it, it may no longer be valid after calling it.
+ * This function may unlock and lock the mutex associated with this callno,
+ * meaning that another thread may grab it and destroy the call.
+ */
+static int iax2_queue_hold(int callno, const char *musicclass)
+{
+	iax2_lock_owner(callno);
+	if (iaxs[callno] && iaxs[callno]->owner) {
+		ast_queue_hold(iaxs[callno]->owner, musicclass);
+		ast_channel_unlock(iaxs[callno]->owner);
+	}
+	return 0;
+}
+
+/*!
+ * \brief Queue an unhold frame on the ast_channel owner
+ *
+ * This function queues an unhold frame on the owner of the IAX2 pvt struct that
+ * is active for the given call number.
+ *
+ * \pre Assumes lock for callno is already held.
+ *
+ * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
+ * was valid before calling it, it may no longer be valid after calling it.
+ * This function may unlock and lock the mutex associated with this callno,
+ * meaning that another thread may grab it and destroy the call.
+ */
+static int iax2_queue_unhold(int callno)
+{
+	iax2_lock_owner(callno);
+	if (iaxs[callno] && iaxs[callno]->owner) {
+		ast_queue_unhold(iaxs[callno]->owner);
+		ast_channel_unlock(iaxs[callno]->owner);
+	}
+	return 0;
+}
+
+/*!
  * \brief Queue a hangup frame on the ast_channel owner
  *
  * This function queues a hangup frame on the owner of the IAX2 pvt struct that
@@ -3112,30 +3158,6 @@
 	iax2_lock_owner(callno);
 	if (iaxs[callno] && iaxs[callno]->owner) {
 		ast_queue_hangup(iaxs[callno]->owner);
-		ast_channel_unlock(iaxs[callno]->owner);
-	}
-	return 0;
-}
-
-/*!
- * \brief Queue a control frame on the ast_channel owner
- *
- * This function queues a control frame on the owner of the IAX2 pvt struct that
- * is active for the given call number.
- *
- * \pre Assumes lock for callno is already held.
- *
- * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
- * was valid before calling it, it may no longer be valid after calling it.
- * This function may unlock and lock the mutex associated with this callno,
- * meaning that another thread may grab it and destroy the call.
- */
-static int iax2_queue_control_data(int callno, 
-	enum ast_control_frame_type control, const void *data, size_t datalen)
-{
-	iax2_lock_owner(callno);
-	if (iaxs[callno] && iaxs[callno]->owner) {
-		ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
 		ast_channel_unlock(iaxs[callno]->owner);
 	}
 	return 0;
@@ -10302,16 +10324,6 @@
 				break;
 			case IAX_COMMAND_QUELCH:
 				if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
-				        /* Generate Manager Hold event, if necessary*/
-					if (iaxs[fr->callno]->owner) {
-						ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
-							"Status: On\r\n"
-							"Channel: %s\r\n"
-							"Uniqueid: %s\r\n",
-							ast_channel_name(iaxs[fr->callno]->owner),
-							ast_channel_uniqueid(iaxs[fr->callno]->owner));
-					}
-
 					ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
 					if (ies.musiconhold) {
 						const char *moh_suggest;
@@ -10326,9 +10338,7 @@
 						 * need to check iaxs[fr->callno] after it returns.
 						 */
 						moh_suggest = iaxs[fr->callno]->mohsuggest;
-						iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
-							S_OR(moh_suggest, NULL),
-							!ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
+						iax2_queue_hold(fr->callno, moh_suggest);
 						ast_channel_unlock(iaxs[fr->callno]->owner);
 					}
 				}
@@ -10339,15 +10349,6 @@
 					if (!iaxs[fr->callno]) {
 						break;
 					}
-					/* Generate Manager Unhold event, if necessary */
-					if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
-						ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
-							"Status: Off\r\n"
-							"Channel: %s\r\n"
-							"Uniqueid: %s\r\n",
-							ast_channel_name(iaxs[fr->callno]->owner),
-							ast_channel_uniqueid(iaxs[fr->callno]->owner));
-					}
 
 					ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH);
 					if (!iaxs[fr->callno]->owner) {
@@ -10358,7 +10359,7 @@
 					 * We already hold the owner lock so we do not
 					 * need to check iaxs[fr->callno] after it returns.
 					 */
-					iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
+					iax2_queue_unhold(fr->callno);
 					ast_channel_unlock(iaxs[fr->callno]->owner);
 				}
 				break;

Modified: trunk/channels/chan_mgcp.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_mgcp.c?view=diff&rev=389746&r1=389745&r2=389746
==============================================================================
--- trunk/channels/chan_mgcp.c (original)
+++ trunk/channels/chan_mgcp.c Fri May 24 16:21:25 2013
@@ -3229,7 +3229,7 @@
 	enum ast_transfer_result res;
 
 	/* Ensure that the other channel goes off hold and that it is indicating properly */
-	ast_queue_control(sub->next->owner, AST_CONTROL_UNHOLD);
+	ast_queue_unhold(sub->next->owner);
 	if (ast_channel_state(sub->owner) == AST_STATE_RINGING) {
 		ast_queue_control(sub->next->owner, AST_CONTROL_RINGING);
 	}
@@ -3275,7 +3275,7 @@
 	if (sub->outgoing) {
 		/* Answered */
 		if (sub->owner) {
-			ast_queue_control(sub->owner, AST_CONTROL_UNHOLD);
+			ast_queue_unhold(sub->owner);
 			sub->cxmode = MGCP_CX_SENDRECV;
 			if (!sub->rtp) {
 				start_rtp(sub);
@@ -3331,7 +3331,7 @@
 				ast_log(LOG_WARNING, "On hook, but already have owner on %s@%s\n", p->name, p->parent->name);
 				ast_log(LOG_WARNING, "If we're onhook why are we here trying to handle a hd or hf?\n");
 			}
-			ast_queue_control(sub->owner, AST_CONTROL_UNHOLD);
+			ast_queue_unhold(sub->owner);
 			sub->cxmode = MGCP_CX_SENDRECV;
 			if (!sub->rtp) {
 				start_rtp(sub);
@@ -3448,8 +3448,9 @@
 					sub->cxmode = MGCP_CX_MUTE;
 					ast_verb(3, "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name);
 					transmit_modify_request(sub);
-					if (sub->owner)
-						ast_queue_control(sub->owner, AST_CONTROL_HOLD);
+					if (sub->owner) {
+						ast_queue_hold(sub->owner, NULL);
+					}
 					sub->next->cxmode = MGCP_CX_RECVONLY;
 					handle_hd_hf(sub->next, ev);
 				} else if (sub->owner && sub->next->owner) {
@@ -3460,7 +3461,7 @@
 								sub->id, sub->next->id, p->name, p->parent->name);
 						sub->cxmode = MGCP_CX_CONF;
 						sub->next->cxmode = MGCP_CX_CONF;
-						ast_queue_control(sub->next->owner, AST_CONTROL_UNHOLD);
+						ast_queue_unhold(sub->next->owner);
 						transmit_modify_request(sub);
 						transmit_modify_request(sub->next);
 					} else {
@@ -3473,8 +3474,8 @@
 						ast_verb(3, "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name);
 						transmit_modify_request(sub);
 
-						ast_queue_control(sub->owner, AST_CONTROL_HOLD);
-						ast_queue_control(sub->next->owner, AST_CONTROL_HOLD);
+						ast_queue_hold(sub->owner, NULL);
+						ast_queue_hold(sub->next->owner, NULL);
 
 						handle_hd_hf(sub->next, ev);
 					}
@@ -3489,7 +3490,7 @@
 						/* XXX - What do we do now? */
 						return -1;
 					}
-					ast_queue_control(p->sub->owner, AST_CONTROL_UNHOLD);
+					ast_queue_unhold(p->sub->owner);
 					p->sub->cxmode = MGCP_CX_SENDRECV;
 					transmit_modify_request(p->sub);
 				}

Modified: trunk/channels/chan_misdn.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_misdn.c?view=diff&rev=389746&r1=389745&r2=389746
==============================================================================
--- trunk/channels/chan_misdn.c (original)
+++ trunk/channels/chan_misdn.c Fri May 24 16:21:25 2013
@@ -10943,7 +10943,7 @@
 		ch->hold.port = 0;
 		ch->hold.channel = 0;
 
-		ast_queue_control(ch->ast, AST_CONTROL_UNHOLD);
+		ast_queue_unhold(ch->ast);
 
 		if (misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0) {
 			chan_misdn_log(4, bc->port, " --> RETRIEVE_ACK failed\n");
@@ -10973,7 +10973,7 @@
 			ch->hold.port = bc->port;
 			ch->hold.channel = bc->channel;
 
-			ast_queue_control(ch->ast, AST_CONTROL_HOLD);
+			ast_queue_hold(ch->ast, NULL);
 
 			misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE);
 		} else {

Modified: trunk/channels/chan_motif.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_motif.c?view=diff&rev=389746&r1=389745&r2=389746
==============================================================================
--- trunk/channels/chan_motif.c (original)
+++ trunk/channels/chan_motif.c Fri May 24 16:21:25 2013
@@ -2481,9 +2481,9 @@
 			ast_setstate(chan, AST_STATE_RINGING);
 		}
 	} else if (iks_find_with_attrib(pak->query, "hold", "xmlns", JINGLE_RTP_INFO_NS)) {
-		ast_queue_control(chan, AST_CONTROL_HOLD);
+		ast_queue_hold(chan, NULL);
 	} else if (iks_find_with_attrib(pak->query, "unhold", "xmlns", JINGLE_RTP_INFO_NS)) {
-		ast_queue_control(chan, AST_CONTROL_UNHOLD);
+		ast_queue_unhold(chan);
 	}
 
 	ast_channel_unlock(chan);

Modified: trunk/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_sip.c?view=diff&rev=389746&r1=389745&r2=389746
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Fri May 24 16:21:25 2013
@@ -9879,16 +9879,9 @@
 /*! \brief Change hold state for a call */
 static void change_hold_state(struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly)
 {
-	if (sip_cfg.notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD)))
+	if (sip_cfg.notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD))) {
 		sip_peer_hold(dialog, holdstate);
-	if (sip_cfg.callevents)
-		manager_event(EVENT_FLAG_CALL, "Hold",
-			      "Status: %s\r\n"
-			      "Channel: %s\r\n"
-			      "Uniqueid: %s\r\n",
-			      holdstate ? "On" : "Off",
-			      ast_channel_name(dialog->owner),
-			      ast_channel_uniqueid(dialog->owner));
+	}
 	append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", ast_str_buffer(req->data));
 	if (!holdstate) {	/* Put off remote hold */
 		ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD);	/* Clear both flags */
@@ -10795,16 +10788,14 @@
 
 	if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && (!ast_sockaddr_isnull(sa) || !ast_sockaddr_isnull(vsa) || !ast_sockaddr_isnull(tsa) || !ast_sockaddr_isnull(isa)) && (!sendonly || sendonly == -1)) {
 		if (!ast_test_flag(&p->flags[2], SIP_PAGE3_DISCARD_REMOTE_HOLD_RETRIEVAL)) {
-			ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
+			ast_queue_unhold(p->owner);
 		}
 		/* Activate a re-invite */
 		ast_queue_frame(p->owner, &ast_null_frame);
 		change_hold_state(p, req, FALSE, sendonly);
 	} else if ((sockaddr_is_null_or_any(sa) && sockaddr_is_null_or_any(vsa) && sockaddr_is_null_or_any(tsa) && sockaddr_is_null_or_any(isa)) || (sendonly && sendonly != -1)) {
 		if (!ast_test_flag(&p->flags[2], SIP_PAGE3_DISCARD_REMOTE_HOLD_RETRIEVAL)) {
-			ast_queue_control_data(p->owner, AST_CONTROL_HOLD,
-				       S_OR(p->mohsuggest, NULL),
-				       !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
+			ast_queue_hold(p->owner, p->mohsuggest);
 		}
 		if (sendonly)
 			ast_rtp_instance_stop(p->rtp);
@@ -25440,7 +25431,7 @@
 				   *without* an SDP, which is supposed to mean "Go back to your state"
 				   and since they put os on remote hold, we go back to off hold */
 				if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
-					ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
+					ast_queue_unhold(p->owner);
 					/* Activate a re-invite */
 					ast_queue_frame(p->owner, &ast_null_frame);
 					change_hold_state(p, req, FALSE, 0);
@@ -26703,7 +26694,7 @@
 				bridged_to = ast_bridged_channel(c);
 				if (bridged_to) {
 					/* Don't actually hangup here... */
-					ast_queue_control(c, AST_CONTROL_UNHOLD);
+					ast_queue_unhold(c);
 					ast_channel_unlock(c);  /* async_goto can do a masquerade, no locks can be held during a masq */
 					ast_async_goto(bridged_to, p->context, p->refer->refer_to, 1);
 					ast_channel_lock(c);

Modified: trunk/channels/chan_skinny.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_skinny.c?view=diff&rev=389746&r1=389745&r2=389746
==============================================================================
--- trunk/channels/chan_skinny.c (original)
+++ trunk/channels/chan_skinny.c Fri May 24 16:21:25 2013
@@ -5263,7 +5263,7 @@
 			ast_channel_name(xferor->owner), ast_bridged_channel(xferor->owner) ? ast_channel_name(ast_bridged_channel(xferor->owner)) : "");
 
 		if (ast_bridged_channel(xferor->owner)) {
-			ast_queue_control(xferee->owner, AST_CONTROL_UNHOLD);
+			ast_queue_unhold(xferee->owner);
 			if (ast_channel_state(xferor->owner) == AST_STATE_RING) {
 				/* play ringing inband */
 				if ((ts = ast_get_indication_tone(ast_channel_zone(xferor->owner), "ring"))) {
@@ -5279,7 +5279,7 @@
 				return -1;
 			}
 		} else if (ast_bridged_channel(xferee->owner)) {
-			ast_queue_control(xferee->owner, AST_CONTROL_UNHOLD);
+			ast_queue_unhold(xferee->owner);
 			if (ast_channel_state(xferor->owner) == AST_STATE_RING) {
 				/* play ringing inband */
 				if ((ts = ast_get_indication_tone(ast_channel_zone(xferor->owner), "ring"))) {
@@ -5690,9 +5690,7 @@
 
 			sub->substate = SUBSTATE_HOLD;
 
-			ast_queue_control_data(sub->owner, AST_CONTROL_HOLD,
-				S_OR(l->mohsuggest, NULL),
-				!ast_strlen_zero(l->mohsuggest) ? strlen(l->mohsuggest) + 1 : 0);
+			ast_queue_hold(sub->owner, l->mohsuggest);
 
 			return;
 		default:
@@ -5874,7 +5872,7 @@
 			transmit_callstate(d, l->instance, sub->callid, SKINNY_OFFHOOK);
 		}
 		if (sub->substate == SUBSTATE_HOLD) {
-			ast_queue_control(sub->owner, AST_CONTROL_UNHOLD);
+			ast_queue_unhold(sub->owner);
 			transmit_connect(d, sub);
 		}
 		transmit_ringer_mode(d, SKINNY_RING_OFF);
@@ -5952,9 +5950,7 @@
 			ast_log(LOG_WARNING, "Cannot set substate to SUBSTATE_HOLD from %s (on call-%d)\n", substate2str(sub->substate), sub->callid);
 			return;
 		}
-		ast_queue_control_data(sub->owner, AST_CONTROL_HOLD,
-			S_OR(l->mohsuggest, NULL),
-			!ast_strlen_zero(l->mohsuggest) ? strlen(l->mohsuggest) + 1 : 0);
+		ast_queue_hold(sub->owner, l->mohsuggest);
 
 		transmit_activatecallplane(d, l);
 		transmit_closereceivechannel(d, sub);

Modified: trunk/channels/chan_unistim.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_unistim.c?view=diff&rev=389746&r1=389745&r2=389746
==============================================================================
--- trunk/channels/chan_unistim.c (original)
+++ trunk/channels/chan_unistim.c Fri May 24 16:21:25 2013
@@ -2453,7 +2453,7 @@
 	send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON);
 	send_stop_timer(pte);
 	if (sub->owner) {
-		ast_queue_control_data(sub->owner, AST_CONTROL_HOLD, NULL, 0);
+		ast_queue_hold(sub->owner, NULL);
 		send_end_call(pte);
 	}
 	return;
@@ -2474,7 +2474,7 @@
 	send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);
 	send_start_timer(pte);
 	if (sub->owner) {
-		ast_queue_control_data(sub->owner, AST_CONTROL_UNHOLD, NULL, 0);
+		ast_queue_unhold(sub->owner);
 		if (sub->rtp) {
 			send_start_rtp(sub);
 		}
@@ -2961,8 +2961,7 @@
 	if (sub->moh) {
 		ast_log(LOG_WARNING, "Transfer with peer already listening music on hold\n");
 	} else {
-		ast_queue_control_data(sub->owner, AST_CONTROL_HOLD,
-			sub->parent->musicclass, strlen(sub->parent->musicclass) + 1);
+		ast_queue_hold(sub->owner, sub->parent->musicclass);
 		sub->moh = 1;
 		sub->subtype = SUB_THREEWAY;
 	}
@@ -2988,7 +2987,7 @@
 		}
 		if (sub->owner) {
 			swap_subs(sub, sub_trans);
-			ast_queue_control(sub_trans->owner, AST_CONTROL_UNHOLD);
+			ast_queue_unhold(sub_trans->owner);
 			sub_trans->moh = 0;
 			sub_trans->subtype = SUB_REAL;
 			sub->subtype = SUB_THREEWAY;
@@ -3498,7 +3497,7 @@
 		if (sub && sub->owner) {
 			sub_stop_silence(pte, sub);
 			send_tone(pte, 0, 0);
-			ast_queue_control(sub->owner, AST_CONTROL_UNHOLD);
+			ast_queue_unhold(sub->owner);
 			sub->moh = 0;
 			sub->subtype = SUB_REAL;
 			pte->state = STATE_CALL;
@@ -4789,7 +4788,7 @@
 		if (unistimdebug) {
 			ast_verb(0, "Threeway call disconnected, switching to real call\n");
 		}
-		ast_queue_control(sub_trans->owner, AST_CONTROL_UNHOLD);
+		ast_queue_unhold(sub_trans->owner);
 		sub_trans->moh = 0;
 		sub_trans->subtype = SUB_REAL;
 		swap_subs(sub_trans, sub);

Modified: trunk/channels/sig_analog.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/sig_analog.c?view=diff&rev=389746&r1=389745&r2=389746
==============================================================================
--- trunk/channels/sig_analog.c (original)
+++ trunk/channels/sig_analog.c Fri May 24 16:21:25 2013
@@ -1354,7 +1354,7 @@
 				if (ast_channel_state(p->owner) != AST_STATE_UP) {
 					ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_ANSWER);
 				}
-				ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD);
+				ast_queue_unhold(p->subs[ANALOG_SUB_REAL].owner);
 				/* Unlock the call-waiting call that we swapped to real-call. */
 				ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner);
 			} else if (p->subs[ANALOG_SUB_THREEWAY].allocd) {
@@ -1382,9 +1382,7 @@
 				/* This is actually part of a three way, placed on hold.  Place the third part
 				   on music on hold now */
 				if (p->subs[ANALOG_SUB_THREEWAY].owner) {
-					ast_queue_control_data(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CONTROL_HOLD,
-						S_OR(p->mohsuggest, NULL),
-						!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
+					ast_queue_hold(p->subs[ANALOG_SUB_THREEWAY].owner, p->mohsuggest);
 				}
 				analog_set_inthreeway(p, ANALOG_SUB_THREEWAY, 0);
 				/* Make it the call wait now */
@@ -1406,9 +1404,7 @@
 				   Start music on hold for them, and take the main guy out of the third call */
 				analog_set_inthreeway(p, ANALOG_SUB_CALLWAIT, 0);
 				if (p->subs[ANALOG_SUB_CALLWAIT].owner) {
-					ast_queue_control_data(p->subs[ANALOG_SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
-						S_OR(p->mohsuggest, NULL),
-						!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
+					ast_queue_hold(p->subs[ANALOG_SUB_CALLWAIT].owner, p->mohsuggest);
 				}
 			}
 			if (p->subs[ANALOG_SUB_CALLWAIT].owner) {
@@ -2323,7 +2319,7 @@
 					analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_THREEWAY);
 					analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
 					analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
-					ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD);
+					ast_queue_unhold(p->subs[ANALOG_SUB_REAL].owner);
 					ast_hangup(chan);
 					goto quit;
 				} else {
@@ -3024,7 +3020,7 @@
 				/* Make sure it stops ringing */
 				analog_off_hook(p);
 				/* Okay -- probably call waiting */
-				ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
+				ast_queue_unhold(p->owner);
 				break;
 			case AST_STATE_RESERVED:
 				/* Start up dialtone */
@@ -3183,14 +3179,10 @@
 
 				/* Start music on hold if appropriate */
 				if (!p->subs[ANALOG_SUB_CALLWAIT].inthreeway) {
-					ast_queue_control_data(p->subs[ANALOG_SUB_CALLWAIT].owner, AST_CONTROL_HOLD,
-						S_OR(p->mohsuggest, NULL),
-						!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
-				}
-				ast_queue_control_data(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_HOLD,
-					S_OR(p->mohsuggest, NULL),
-					!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
-				ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD);
+					ast_queue_hold(p->subs[ANALOG_SUB_CALLWAIT].owner, p->mohsuggest);
+				}
+				ast_queue_hold(p->subs[ANALOG_SUB_REAL].owner, p->mohsuggest);
+				ast_queue_unhold(p->subs[ANALOG_SUB_REAL].owner);
 
 				/* Unlock the call-waiting call that we swapped to real-call. */
 				ast_channel_unlock(p->subs[ANALOG_SUB_REAL].owner);
@@ -3282,9 +3274,7 @@
 						ast_verb(3, "Started three way call on channel %d\n", p->channel);
 
 						/* Start music on hold */
-						ast_queue_control_data(p->subs[ANALOG_SUB_THREEWAY].owner, AST_CONTROL_HOLD,
-							S_OR(p->mohsuggest, NULL),
-							!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
+						ast_queue_hold(p->subs[ANALOG_SUB_THREEWAY].owner, p->mohsuggest);
 					}
 					ast_callid_threadstorage_auto_clean(callid, callid_created);
 				}
@@ -3334,7 +3324,7 @@
 							analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
 							orig_3way_sub = ANALOG_SUB_REAL;
 						}
-						ast_queue_control(p->subs[orig_3way_sub].owner, AST_CONTROL_UNHOLD);
+						ast_queue_unhold(p->subs[orig_3way_sub].owner);
 						analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
 					} else {
 						ast_verb(3, "Dumping incomplete call on %s\n", ast_channel_name(p->subs[ANALOG_SUB_THREEWAY].owner));
@@ -3342,7 +3332,7 @@
 						orig_3way_sub = ANALOG_SUB_REAL;
 						ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
 						analog_set_new_owner(p, p->subs[ANALOG_SUB_REAL].owner);
-						ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_UNHOLD);
+						ast_queue_unhold(p->subs[ANALOG_SUB_REAL].owner);
 						analog_set_echocanceller(p, 1);
 					}
 				}
@@ -3585,7 +3575,7 @@
 					analog_event2str(res), ast_channel_name(ast), ast_channel_name(p->owner));
 			}
 			if (p->owner) {
-				ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
+				ast_queue_unhold(p->owner);
 			}
 		}
 		switch (res) {
@@ -3624,7 +3614,7 @@
 					ast_setstate(p->owner, AST_STATE_UP);
 				}
 				analog_stop_callwait(p);
-				ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
+				ast_queue_unhold(p->owner);
 			} else {
 				ast_log(LOG_WARNING, "Absorbed %s, but nobody is left!?!?\n",
 					analog_event2str(res));

Modified: trunk/channels/sig_pri.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/sig_pri.c?view=diff&rev=389746&r1=389745&r2=389746
==============================================================================
--- trunk/channels/sig_pri.c (original)
+++ trunk/channels/sig_pri.c Fri May 24 16:21:25 2013
@@ -1241,6 +1241,50 @@
 	sig_pri_lock_owner(pri, chanpos);
 	if (pri->pvts[chanpos]->owner) {
 		ast_queue_frame(pri->pvts[chanpos]->owner, frame);
+		ast_channel_unlock(pri->pvts[chanpos]->owner);
+	}
+}
+
+/*!
+ * \internal
+ * \brief Queue a hold frame onto the owner channel.
+ * \since 12
+ *
+ * \param pri PRI span control structure.
+ * \param chanpos Channel position in the span.
+ *
+ * \note Assumes the pri->lock is already obtained.
+ * \note Assumes the sig_pri_lock_private(pri->pvts[chanpos]) is already obtained.
+ *
+ * \return Nothing
+ */
+static void sig_pri_queue_hold(struct sig_pri_span *pri, int chanpos)
+{
+	sig_pri_lock_owner(pri, chanpos);
+	if (pri->pvts[chanpos]->owner) {
+		ast_queue_hold(pri->pvts[chanpos]->owner, NULL);
+		ast_channel_unlock(pri->pvts[chanpos]->owner);
+	}
+}
+
+/*!
+ * \internal
+ * \brief Queue an unhold frame onto the owner channel.
+ * \since 12
+ *
+ * \param pri PRI span control structure.
+ * \param chanpos Channel position in the span.
+ *
+ * \note Assumes the pri->lock is already obtained.
+ * \note Assumes the sig_pri_lock_private(pri->pvts[chanpos]) is already obtained.
+ *
+ * \return Nothing
+ */
+static void sig_pri_queue_unhold(struct sig_pri_span *pri, int chanpos)
+{
+	sig_pri_lock_owner(pri, chanpos);
+	if (pri->pvts[chanpos]->owner) {
+		ast_queue_unhold(pri->pvts[chanpos]->owner);
 		ast_channel_unlock(pri->pvts[chanpos]->owner);
 	}
 }
@@ -5177,42 +5221,6 @@
 		(orig_state == next_state) ? "$" : sig_pri_moh_state_str(next_state));
 }
 
-#if defined(HAVE_PRI_CALL_HOLD)
-/*!
- * \internal
- * \brief Post an AMI hold event.
- * \since 10.0
- *
- * \param chan Channel to post event to
- * \param is_held TRUE if the call was placed on hold.
- *
- * \return Nothing
- */
-static void sig_pri_ami_hold_event(struct ast_channel *chan, int is_held)
-{
-	/*** DOCUMENTATION
-		<managerEventInstance>
-			<synopsis>Raised when a PRI channel is put on Hold.</synopsis>
-			<syntax>
-				<parameter name="Status">
-					<enumlist>
-						<enum name="On"/>
-						<enum name="Off"/>
-					</enumlist>
-				</parameter>
-			</syntax>
-		</managerEventInstance>
-	***/
-	ast_manager_event(chan, EVENT_FLAG_CALL, "Hold",
-		"Status: %s\r\n"
-		"Channel: %s\r\n"
-		"Uniqueid: %s\r\n",
-		is_held ? "On" : "Off",
-		ast_channel_name(chan),
-		ast_channel_uniqueid(chan));
-}
-#endif	/* defined(HAVE_PRI_CALL_HOLD) */
-
 /*!
  * \internal
  * \brief Set callid threadstorage for the pri_dchannel thread when a new call is created
@@ -5327,13 +5335,11 @@
 		goto done_with_owner;
 	}
 	sig_pri_handle_subcmds(pri, chanpos_old, ev->e, ev->hold.subcmds, ev->hold.call);
-	pri_queue_control(pri, chanpos_old, AST_CONTROL_HOLD);
+	sig_pri_queue_hold(pri, chanpos_old);
 	chanpos_new = pri_fixup_principle(pri, chanpos_new, ev->hold.call);
 	if (chanpos_new < 0) {
 		/* Should never happen. */
-		pri_queue_control(pri, chanpos_old, AST_CONTROL_UNHOLD);
-	} else {
-		sig_pri_ami_hold_event(owner, 1);
+		sig_pri_queue_unhold(pri, chanpos_old);
 	}
 
 done_with_owner:;
@@ -5521,12 +5527,7 @@
 	sig_pri_lock_private(pri->pvts[chanpos]);
 	callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
 	sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve.subcmds, ev->retrieve.call);
-	sig_pri_lock_owner(pri, chanpos);
-	pri_queue_control(pri, chanpos, AST_CONTROL_UNHOLD);
-	if (pri->pvts[chanpos]->owner) {
-		sig_pri_ami_hold_event(pri->pvts[chanpos]->owner, 0);
-		ast_channel_unlock(pri->pvts[chanpos]->owner);
-	}
+	sig_pri_queue_unhold(pri, chanpos);
 	pri_retrieve_ack(pri->pri, ev->retrieve.call,
 		PVT_TO_CHANNEL(pri->pvts[chanpos]));
 	sig_pri_moh_fsm_event(pri->pvts[chanpos]->owner, pri->pvts[chanpos],
@@ -7428,12 +7429,12 @@
 				switch (e->notify.info) {
 				case PRI_NOTIFY_REMOTE_HOLD:
 					if (!pri->discardremoteholdretrieval) {
-						pri_queue_control(pri, chanpos, AST_CONTROL_HOLD);
+						sig_pri_queue_hold(pri, chanpos);
 					}
 					break;
 				case PRI_NOTIFY_REMOTE_RETRIEVAL:
 					if (!pri->discardremoteholdretrieval) {
-						pri_queue_control(pri, chanpos, AST_CONTROL_UNHOLD);
+						sig_pri_queue_unhold(pri, chanpos);
 					}
 					break;
 				}

Modified: trunk/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/channel.h?view=diff&rev=389746&r1=389745&r2=389746
==============================================================================
--- trunk/include/asterisk/channel.h (original)
+++ trunk/include/asterisk/channel.h Fri May 24 16:21:25 2013
@@ -1201,6 +1201,31 @@
  * \since 1.6.1
  */
 int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause);
+
+/*!
+ * \brief Queue a hold frame
+ *
+ * \param chan channel to queue frame onto
+ * \param musicclass The suggested musicclass for the other end to use
+ *
+ * \note The channel does not need to be locked before calling this function.
+ *
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_queue_hold(struct ast_channel *chan, const char *musicclass);
+
+/*!
+ * \brief Queue an unhold frame
+ *
+ * \param chan channel to queue frame onto
+ *
+ * \note The channel does not need to be locked before calling this function.
+ *
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_queue_unhold(struct ast_channel *chan);
 
 /*!
  * \brief Queue a control frame without payload

Modified: trunk/include/asterisk/stasis_channels.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/stasis_channels.h?view=diff&rev=389746&r1=389745&r2=389746
==============================================================================
--- trunk/include/asterisk/stasis_channels.h (original)
+++ trunk/include/asterisk/stasis_channels.h Fri May 24 16:21:25 2013
@@ -341,6 +341,22 @@
 
 /*!
  * \since 12
+ * \brief Message type for when a channel is placed on hold.
+ *
+ * \retval A stasis message type
+ */
+struct stasis_message_type *ast_channel_hold_type(void);
+
+/*!
+ * \since 12
+ * \brief Message type for when a channel is removed from hold.
+ *
+ * \retval A stasis message type
+ */
+struct stasis_message_type *ast_channel_unhold_type(void);
+
+/*!
+ * \since 12
  * \brief Message type for when a channel starts spying on another channel
  *
  * \retval A stasis message type

Modified: trunk/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/channel.c?view=diff&rev=389746&r1=389745&r2=389746
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Fri May 24 16:21:25 2013
@@ -1353,9 +1353,11 @@
 	struct stasis_message_type *type, struct ast_json *blob)
 {
 	RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
-	if (blob) {
-		message = ast_channel_blob_create(chan, type, blob);
-	}
+	if (!blob) {
+		blob = ast_json_null();
+	}
+
+	message = ast_channel_blob_create(chan, type, blob);
 	if (message) {
 		stasis_publish(ast_channel_topic(chan), message);
 	}
@@ -1402,6 +1404,39 @@
 
 	res = ast_queue_frame(chan, &f);
 	ast_channel_unlock(chan);
+	return res;
+}
+
+int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
+{
+	RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
+	RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
+	struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HOLD };
+	int res;
+
+	if (!ast_strlen_zero(musicclass)) {
+		f.data.ptr = (void *) musicclass;
+		f.datalen = strlen(musicclass) + 1;
+
+		blob = ast_json_pack("{s: s}",
+				     "musicclass", musicclass);
+	}
+
+	publish_channel_blob(chan, ast_channel_hold_type(), blob);
+
+	res = ast_queue_frame(chan, &f);
+	return res;
+}
+

[... 185 lines stripped ...]



More information about the asterisk-commits mailing list