[asterisk-commits] bebuild: tag certified-1.8.11-cert10 r378348 - in /certified/tags/1.8.11-cert...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jan 2 13:28:01 CST 2013


Author: bebuild
Date: Wed Jan  2 13:27:54 2013
New Revision: 378348

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=378348
Log:
Merge 378289, 378323 for 1.8.11-cert10

Removed:
    certified/tags/1.8.11-cert10/certified-asterisk-1.8.11-cert9-summary.html
    certified/tags/1.8.11-cert10/certified-asterisk-1.8.11-cert9-summary.txt
Modified:
    certified/tags/1.8.11-cert10/   (props changed)
    certified/tags/1.8.11-cert10/.version
    certified/tags/1.8.11-cert10/ChangeLog
    certified/tags/1.8.11-cert10/apps/app_confbridge.c
    certified/tags/1.8.11-cert10/apps/app_meetme.c
    certified/tags/1.8.11-cert10/channels/chan_agent.c
    certified/tags/1.8.11-cert10/channels/chan_dahdi.c
    certified/tags/1.8.11-cert10/channels/chan_iax2.c
    certified/tags/1.8.11-cert10/channels/chan_local.c
    certified/tags/1.8.11-cert10/channels/chan_sip.c
    certified/tags/1.8.11-cert10/channels/chan_skinny.c
    certified/tags/1.8.11-cert10/funcs/func_devstate.c
    certified/tags/1.8.11-cert10/include/asterisk/channel.h
    certified/tags/1.8.11-cert10/include/asterisk/devicestate.h
    certified/tags/1.8.11-cert10/include/asterisk/event_defs.h
    certified/tags/1.8.11-cert10/main/channel.c
    certified/tags/1.8.11-cert10/main/devicestate.c
    certified/tags/1.8.11-cert10/main/event.c
    certified/tags/1.8.11-cert10/main/features.c
    certified/tags/1.8.11-cert10/main/http.c
    certified/tags/1.8.11-cert10/res/res_calendar.c
    certified/tags/1.8.11-cert10/res/res_jabber.c

Propchange: certified/tags/1.8.11-cert10/
------------------------------------------------------------------------------
Binary property 'branch-1.8-merged' - no diff available.

Propchange: certified/tags/1.8.11-cert10/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Jan  2 13:27:54 2013
@@ -1,1 +1,2 @@
 /branches/1.8:357665,358162,359656,359706,359979,360086,360884,367781,367843,368604,368759,371919
+/certified/branches/1.8.11:378289,378323

Modified: certified/tags/1.8.11-cert10/.version
URL: http://svnview.digium.com/svn/asterisk/certified/tags/1.8.11-cert10/.version?view=diff&rev=378348&r1=378347&r2=378348
==============================================================================
--- certified/tags/1.8.11-cert10/.version (original)
+++ certified/tags/1.8.11-cert10/.version Wed Jan  2 13:27:54 2013
@@ -1,1 +1,1 @@
-1.8.11-cert9
+1.8.11-cert10

Modified: certified/tags/1.8.11-cert10/ChangeLog
URL: http://svnview.digium.com/svn/asterisk/certified/tags/1.8.11-cert10/ChangeLog?view=diff&rev=378348&r1=378347&r2=378348
==============================================================================
--- certified/tags/1.8.11-cert10/ChangeLog (original)
+++ certified/tags/1.8.11-cert10/ChangeLog Wed Jan  2 13:27:54 2013
@@ -1,3 +1,46 @@
+2013-01-02  Asterisk Development Team <asteriskteam at digium.com>
+
+	* Asterisk 1.8.11-cert10 Released.
+
+	* AST-2012-015: Resolve crashes due to large stack allocations when
+	  using TCP
+
+	  Asterisk had several places where messages received over various
+	  network transports may be copied in a single stack allocation. In
+	  the case of TCP, since multiple packets in a stream may be
+	  concatenated together, this can lead to large allocations that
+	  overflow the stack.
+
+	  This patch modifies those portions of Asterisk using TCP to either
+	  favor heap allocations or use an upper bound to ensure that the
+	  stack will not overflow:
+	   * For SIP, the allocation now has an upper limit
+	   * For HTTP, the allocation is now a heap allocation instead of a
+	     stack allocation
+	   * For XMPP (in res_jabber), the allocation has been eliminated
+	     since it was unnecesary.
+
+	* AST-2012-014: Prevent exhaustion of system resources through
+	  exploitation of event cache
+
+	  Asterisk maintains an internal cache for devices in the event
+	  subsystem. The device state cache holds the state of each device
+	  known to Asterisk, such that consumers of device state information
+	  can query for the last known state for a particular device, even if
+	  it is not part of an active call. The concept of a device in Asterisk
+	  can include entities that do not have a physical representation. One
+	  way that this occurred was when anonymous calls are allowed in
+	  Asterisk. A device was automatically created and stored in the cache
+	  for each anonymous call that occurred; this was possible in the SIP
+	  and IAX2 channel drivers and through channel drivers that utilized
+	  the res_jabber/res_xmpp resource modules (Gtalk, Jingle, and Motif).
+	  These devices are never removed from the system, allowing anonymous
+	  calls to potentially exhaust a system's resources.
+
+	  This patch changes the event cache subsystem and device state
+	  management to no longer cache devices that are not associated with a
+	  physical entity.
+
 2012-12-03  Asterisk Development Team <asteriskteam at digium.com>
 
 	* Created 1.8.11-cert9.

Modified: certified/tags/1.8.11-cert10/apps/app_confbridge.c
URL: http://svnview.digium.com/svn/asterisk/certified/tags/1.8.11-cert10/apps/app_confbridge.c?view=diff&rev=378348&r1=378347&r2=378348
==============================================================================
--- certified/tags/1.8.11-cert10/apps/app_confbridge.c (original)
+++ certified/tags/1.8.11-cert10/apps/app_confbridge.c Wed Jan  2 13:27:54 2013
@@ -486,7 +486,7 @@
 
 	/* Set the device state for this conference */
 	if (conference_bridge->users == 1) {
-		ast_devstate_changed(AST_DEVICE_INUSE, "confbridge:%s", conference_bridge->name);
+		ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "confbridge:%s", conference_bridge->name);
 	}
 
 	/* If the caller is a marked user or is waiting for a marked user to enter pass 'em off, otherwise pass them off to do regular joining stuff */
@@ -568,7 +568,7 @@
 		}
 	} else {
 		/* Set device state to "not in use" */
-		ast_devstate_changed(AST_DEVICE_NOT_INUSE, "confbridge:%s", conference_bridge->name);
+		ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "confbridge:%s", conference_bridge->name);
 
 		ao2_unlink(conference_bridges, conference_bridge);
 	}

Modified: certified/tags/1.8.11-cert10/apps/app_meetme.c
URL: http://svnview.digium.com/svn/asterisk/certified/tags/1.8.11-cert10/apps/app_meetme.c?view=diff&rev=378348&r1=378347&r2=378348
==============================================================================
--- certified/tags/1.8.11-cert10/apps/app_meetme.c (original)
+++ certified/tags/1.8.11-cert10/apps/app_meetme.c Wed Jan  2 13:27:54 2013
@@ -2496,7 +2496,7 @@
 
 	/* This device changed state now - if this is the first user */
 	if (conf->users == 1)
-		ast_devstate_changed(AST_DEVICE_INUSE, "meetme:%s", conf->confno);
+		ast_devstate_changed(AST_DEVICE_INUSE, (conf->isdynamic ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), "meetme:%s", conf->confno);
 
 	ast_mutex_unlock(&conf->playlock);
 
@@ -3790,7 +3790,7 @@
 
 		/* Change any states */
 		if (!conf->users) {
-			ast_devstate_changed(AST_DEVICE_NOT_INUSE, "meetme:%s", conf->confno);
+			ast_devstate_changed(AST_DEVICE_NOT_INUSE, (conf->isdynamic ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), "meetme:%s", conf->confno);
 		}
 
 		/* Return the number of seconds the user was in the conf */
@@ -5175,8 +5175,8 @@
 				|| trunk_ref == exclude)
 				continue;
 			trunk_ref->state = state;
-			ast_devstate_changed(sla_state_to_devstate(state), 
-				"SLA:%s_%s", station->name, trunk->name);
+			ast_devstate_changed(sla_state_to_devstate(state), AST_DEVSTATE_CACHABLE,
+					     "SLA:%s_%s", station->name, trunk->name);
 			break;
 		}
 	}
@@ -5674,8 +5674,8 @@
 {
 	ast_atomic_fetchadd_int((int *) &event->trunk_ref->trunk->hold_stations, 1);
 	event->trunk_ref->state = SLA_TRUNK_STATE_ONHOLD_BYME;
-	ast_devstate_changed(AST_DEVICE_ONHOLD, "SLA:%s_%s", 
-		event->station->name, event->trunk_ref->trunk->name);
+	ast_devstate_changed(AST_DEVICE_ONHOLD, AST_DEVSTATE_CACHABLE, "SLA:%s_%s",
+			     event->station->name, event->trunk_ref->trunk->name);
 	sla_change_trunk_state(event->trunk_ref->trunk, SLA_TRUNK_STATE_ONHOLD, 
 		INACTIVE_TRUNK_REFS, event->trunk_ref);
 
@@ -6184,8 +6184,8 @@
 			sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP, ALL_TRUNK_REFS, NULL);
 		else {
 			trunk_ref->state = SLA_TRUNK_STATE_UP;
-			ast_devstate_changed(AST_DEVICE_INUSE, 
-				"SLA:%s_%s", station->name, trunk_ref->trunk->name);
+			ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE,
+					     "SLA:%s_%s", station->name, trunk_ref->trunk->name);
 		}
 	} else if (trunk_ref->state == SLA_TRUNK_STATE_RINGING) {
 		struct sla_ringing_trunk *ringing_trunk;

Modified: certified/tags/1.8.11-cert10/channels/chan_agent.c
URL: http://svnview.digium.com/svn/asterisk/certified/tags/1.8.11-cert10/channels/chan_agent.c?view=diff&rev=378348&r1=378347&r2=378348
==============================================================================
--- certified/tags/1.8.11-cert10/channels/chan_agent.c (original)
+++ certified/tags/1.8.11-cert10/channels/chan_agent.c Wed Jan  2 13:27:54 2013
@@ -611,7 +611,7 @@
 		if (p->chan) {
 			p->chan->_bridge = NULL;
 			p->chan = NULL;
-			ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Agent/%s", p->agent);
+			ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
 			p->acknowledged = 0;
 		}
 	} else {
@@ -866,7 +866,7 @@
 	} else {
 		/* Agent hung-up */
 		p->chan = NULL;
-		ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Agent/%s", p->agent);
+		ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
 	}
 
 	if (!res) {
@@ -989,7 +989,7 @@
 	if (!p->loginstart) {
 		p->logincallerid[0] = '\0';
 	} else {
-		ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Agent/%s", p->agent);
+		ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
 	}
 
 	if (p->abouttograb) {
@@ -2132,7 +2132,7 @@
 						}
 						ast_mutex_unlock(&p->lock);
 						AST_LIST_UNLOCK(&agents);
-						ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Agent/%s", p->agent);
+						ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
 						while (res >= 0) {
 							ast_mutex_lock(&p->lock);
 							if (p->deferlogoff && p->chan) {
@@ -2153,7 +2153,7 @@
 								if (ast_tvdiff_ms(ast_tvnow(), p->lastdisc) > 0) {
 									ast_debug(1, "Wrapup time for %s expired!\n", p->agent);
 									p->lastdisc = ast_tv(0, 0);
-									ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Agent/%s", p->agent);
+									ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
 									if (p->ackcall) {
 										check_beep(p, 0);
 									} else {
@@ -2213,7 +2213,7 @@
 						ast_queue_log("NONE", chan->uniqueid, agent, "AGENTLOGOFF", "%s|%ld", chan->name, logintime);
 						ast_verb(2, "Agent '%s' logged out\n", p->agent);
 						/* If there is no owner, go ahead and kill it now */
-						ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Agent/%s", p->agent);
+						ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
 						if (p->dead && !p->owner) {
 							ast_mutex_destroy(&p->lock);
 							ast_cond_destroy(&p->app_complete_cond);

Modified: certified/tags/1.8.11-cert10/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/certified/tags/1.8.11-cert10/channels/chan_dahdi.c?view=diff&rev=378348&r1=378347&r2=378348
==============================================================================
--- certified/tags/1.8.11-cert10/channels/chan_dahdi.c (original)
+++ certified/tags/1.8.11-cert10/channels/chan_dahdi.c Wed Jan  2 13:27:54 2013
@@ -3301,7 +3301,7 @@
 	}
 	if (pri->congestion_devstate != new_state) {
 		pri->congestion_devstate = new_state;
-		ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/congestion", pri->span);
+		ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, "DAHDI/I%d/congestion", pri->span);
 	}
 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
 	/* Update the span threshold device state and report any change. */
@@ -3317,7 +3317,7 @@
 	}
 	if (pri->threshold_devstate != new_state) {
 		pri->threshold_devstate = new_state;
-		ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/threshold", pri->span);
+		ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, "DAHDI/I%d/threshold", pri->span);
 	}
 #endif	/* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */
 }
@@ -9725,7 +9725,8 @@
 	if (dashptr) {
 		*dashptr = '\0';
 	}
-	ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name);
+	tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
+	ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_NOT_CACHABLE, device_name);
 
 	for (v = i->vars ; v ; v = v->next)
 		pbx_builtin_setvar_helper(tmp, v->name, v->value);

Modified: certified/tags/1.8.11-cert10/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/certified/tags/1.8.11-cert10/channels/chan_iax2.c?view=diff&rev=378348&r1=378347&r2=378348
==============================================================================
--- certified/tags/1.8.11-cert10/channels/chan_iax2.c (original)
+++ certified/tags/1.8.11-cert10/channels/chan_iax2.c Wed Jan  2 13:27:54 2013
@@ -5728,7 +5728,7 @@
 }
 
 /*! \brief  Create new call, interface with the PBX core */
-static struct ast_channel *ast_iax2_new(int callno, int state, format_t capability, const char *linkedid)
+static struct ast_channel *ast_iax2_new(int callno, int state, format_t capability, const char *linkedid, unsigned int cachable)
 {
 	struct ast_channel *tmp;
 	struct chan_iax2_pvt *i;
@@ -5796,6 +5796,10 @@
 		tmp->adsicpe = AST_ADSI_UNAVAILABLE;
 	i->owner = tmp;
 	i->capability = capability;
+
+	if (!cachable) {
+		tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
+	}
 
 	/* Set inherited variables */
 	if (i->vars) {
@@ -8085,7 +8089,7 @@
 		/* if challenge has been sent, but no challenge response if given, reject. */
 		goto return_unref;
 	}
-	ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
+	ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
 
 	/* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
 	res = 0;
@@ -8640,7 +8644,7 @@
 	if (!ast_test_flag64(peer, IAX_TEMPONLY))
 		ast_db_del("IAX/Registry", peer->name);
 	register_peer_exten(peer, 0);
-	ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
+	ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
 	if (iax2_regfunk)
 		iax2_regfunk(peer->name, 0);
 
@@ -8694,7 +8698,7 @@
 		}
 	}
 
-	ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
+	ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
 
 	p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
 	if (p->expire == -1) {
@@ -8771,14 +8775,14 @@
 					    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
 			manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
 			register_peer_exten(p, 1);
-			ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */
+			ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
 		} else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
 			ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
 					    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
 			manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
 			register_peer_exten(p, 0);
 			ast_db_del("IAX/Registry", p->name);
-			ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */
+			ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */
 		}
 		/* Update the host */
 		/* Verify that the host is really there */
@@ -10288,7 +10292,8 @@
 		    (f.frametype == AST_FRAME_IAX)) {
 			if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
 				ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
-				if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) {
+				if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL,
+						  ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED))) {
 					ast_variables_destroy(ies.vars);
 					ast_mutex_unlock(&iaxsl[fr->callno]);
 					return 1;
@@ -10921,13 +10926,13 @@
 						if (iaxs[fr->callno]->pingtime <= peer->maxms) {
 							ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
 							manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
-							ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name); /* Activate notification */
+							ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
 						}
 					} else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
 						if (iaxs[fr->callno]->pingtime > peer->maxms) {
 							ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
 							manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
-							ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
+							ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
 						}
 					}
 					peer->lastms = iaxs[fr->callno]->pingtime;
@@ -11169,7 +11174,7 @@
 											using_prefs);
 
 							ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
-							if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL)))
+							if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL, 1)))
 								iax2_destroy(fr->callno);
 							else if (ies.vars) {
 								struct ast_datastore *variablestore;
@@ -11240,7 +11245,7 @@
 							ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
 						ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
 						send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
-						if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL)))
+						if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, 1)))
 							iax2_destroy(fr->callno);
 						else if (ies.vars) {
 							struct ast_datastore *variablestore;
@@ -11992,7 +11997,7 @@
 	if (peer->lastms > -1) {
 		ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
 		manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
-		ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */
+		ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */
 	}
 	if ((callno = peer->callno) > 0) {
 		ast_mutex_lock(&iaxsl[callno]);
@@ -12160,7 +12165,7 @@
 	if (cai.found)
 		ast_string_field_set(iaxs[callno], host, pds.peer);
 
-	c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL);
+	c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL, cai.found);
 
 	ast_mutex_unlock(&iaxsl[callno]);
 

Modified: certified/tags/1.8.11-cert10/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/certified/tags/1.8.11-cert10/channels/chan_local.c?view=diff&rev=378348&r1=378347&r2=378348
==============================================================================
--- certified/tags/1.8.11-cert10/channels/chan_local.c (original)
+++ certified/tags/1.8.11-cert10/channels/chan_local.c Wed Jan  2 13:27:54 2013
@@ -1140,6 +1140,9 @@
 	tmp->tech_pvt = p;
 	tmp2->tech_pvt = p;
 
+	tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
+	tmp2->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
+
 	p->owner = tmp;
 	p->chan = tmp2;
 	p->u_owner = ast_module_user_add(p->owner);

Modified: certified/tags/1.8.11-cert10/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/certified/tags/1.8.11-cert10/channels/chan_sip.c?view=diff&rev=378348&r1=378347&r2=378348
==============================================================================
--- certified/tags/1.8.11-cert10/channels/chan_sip.c (original)
+++ certified/tags/1.8.11-cert10/channels/chan_sip.c Wed Jan  2 13:27:54 2013
@@ -6110,7 +6110,7 @@
 	}
 
 	if (p) {
-		ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", p->name);
+		ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", p->name);
 		unref_peer(p, "update_call_counter: unref_peer from call counter");
 	}
 	return 0;
@@ -7361,6 +7361,9 @@
 	if (i->rtp)
 		ast_jb_configure(tmp, &global_jbconf);
 
+	if (!i->relatedpeer) {
+		tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
+	}
 	/* Set channel variables for this call from configuration */
 	for (v = i->chanvars ; v ; v = v->next) {
 		char valuebuf[1024];
@@ -13945,7 +13948,7 @@
 
 	manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
 	register_peer_exten(peer, FALSE);	/* Remove regexten */
-	ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
+	ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
 
 	/* Do we need to release this peer from memory?
 		Only for realtime peers and autocreated peers
@@ -14727,8 +14730,9 @@
 	ast_atomic_fetchadd_int(&p->relatedpeer->onHold, (hold ? +1 : -1));
 
 	/* Request device state update */
-	ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", p->relatedpeer->name);
-	
+	ast_devstate_changed(AST_DEVICE_UNKNOWN, (p->owner->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE),
+			     "SIP/%s", p->relatedpeer->name);
+
 	return;
 }
 
@@ -15151,7 +15155,7 @@
 		}
 	}
 	if (!res) {
-		ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
+		ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
 	}
 	if (res < 0) {
 		switch (res) {
@@ -21272,7 +21276,7 @@
 
 		ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
 			peer->name, s, pingtime, peer->maxms);
-		ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
+		ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
 		if (sip_cfg.peer_rtupdate) {
 			ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", str_lastms, SENTINEL);
 		}
@@ -26808,7 +26812,7 @@
 	/* Don't send a devstate change if nothing changed. */
 	if (peer->lastms > -1) {
 		peer->lastms = -1;
-		ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
+		ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "SIP/%s", peer->name);
 	}
 
 	/* Try again quickly */

Modified: certified/tags/1.8.11-cert10/channels/chan_skinny.c
URL: http://svnview.digium.com/svn/asterisk/certified/tags/1.8.11-cert10/channels/chan_skinny.c?view=diff&rev=378348&r1=378347&r2=378348
==============================================================================
--- certified/tags/1.8.11-cert10/channels/chan_skinny.c (original)
+++ certified/tags/1.8.11-cert10/channels/chan_skinny.c Wed Jan  2 13:27:54 2013
@@ -1926,7 +1926,7 @@
 					register_exten(l);
 					/* initialize MWI on line and device */
 					mwi_event_cb(0, l);
-					ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name);
+					ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
 				}
 				--instance;
 			}
@@ -1964,7 +1964,7 @@
 				l->instance = 0;
 				manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name);
 				unregister_exten(l);
-				ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Skinny/%s@%s", l->name, d->name);
+				ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
 			}
 		}
 	}
@@ -5328,7 +5328,7 @@
 			ast_verb(1, "RECEIVED UNKNOWN STIMULUS:  %d(%d/%d)\n", event, instance, callreference);
 		break;
 	}
-	ast_devstate_changed(AST_DEVICE_UNKNOWN, "Skinny/%s@%s", l->name, d->name);
+	ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
 
 	return 1;
 }
@@ -5379,7 +5379,7 @@
 	transmit_ringer_mode(d, SKINNY_RING_OFF);
 	l->hookstate = SKINNY_OFFHOOK;
 
-	ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s@%s", l->name, d->name);
+	ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
 
 	if (sub && sub->onhold) {
 		return 1;
@@ -5455,7 +5455,7 @@
 		return 0;
 	}
 
-	ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name);
+	ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
 
 	if (sub->onhold) {
 		return 0;
@@ -5841,7 +5841,7 @@
 		return 0;
 	}
 
-	ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s@%s", l->name, d->name);
+	ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
 
 	switch(event) {
 	case SOFTKEY_NONE:
@@ -6056,7 +6056,7 @@
 				transmit_callstate(d, l->instance, sub->callid, l->hookstate);
 			}
 
-			ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name);
+			ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
 			if (skinnydebug)
 				ast_verb(1, "Skinny %s@%s went on hook\n", l->name, d->name);
 			if (l->transfer && sub->xferor && sub->owner->_state >= AST_STATE_RING) {
@@ -6080,7 +6080,7 @@
 				}
 			}
 			if ((l->hookstate == SKINNY_ONHOOK) && (AST_LIST_NEXT(sub, list) && !AST_LIST_NEXT(sub, list)->rtp)) {
-				ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s@%s", l->name, d->name);
+				ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s@%s", l->name, d->name);
 			}
 		}
 		break;

Modified: certified/tags/1.8.11-cert10/funcs/func_devstate.c
URL: http://svnview.digium.com/svn/asterisk/certified/tags/1.8.11-cert10/funcs/func_devstate.c?view=diff&rev=378348&r1=378347&r2=378348
==============================================================================
--- certified/tags/1.8.11-cert10/funcs/func_devstate.c (original)
+++ certified/tags/1.8.11-cert10/funcs/func_devstate.c Wed Jan  2 13:27:54 2013
@@ -132,7 +132,7 @@
 
 	ast_db_put(astdb_family, data, value);
 
-	ast_devstate_changed(state_val, "Custom:%s", data);
+	ast_devstate_changed(state_val, AST_DEVSTATE_CACHABLE, "Custom:%s", data);
 
 	return 0;
 }
@@ -294,7 +294,7 @@
 
 	ast_db_put(astdb_family, dev, state);
 
-	ast_devstate_changed(state_val, "Custom:%s", dev);
+	ast_devstate_changed(state_val, AST_DEVSTATE_CACHABLE, "Custom:%s", dev);
 
 	return CLI_SUCCESS;
 }
@@ -340,7 +340,7 @@
 		if (dev_name <= (const char *) 1)
 			continue;
 		ast_devstate_changed(ast_devstate_val(db_entry->data),
-			"Custom:%s\n", dev_name);
+			AST_DEVSTATE_CACHABLE, "Custom:%s\n", dev_name);
 	}
 	ast_db_freetree(db_tree);
 	db_tree = NULL;

Modified: certified/tags/1.8.11-cert10/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/certified/tags/1.8.11-cert10/include/asterisk/channel.h?view=diff&rev=378348&r1=378347&r2=378348
==============================================================================
--- certified/tags/1.8.11-cert10/include/asterisk/channel.h (original)
+++ certified/tags/1.8.11-cert10/include/asterisk/channel.h Wed Jan  2 13:27:54 2013
@@ -936,6 +936,12 @@
 	 *  some non-traditional dialplans (like AGI) to continue to function.
 	 */
 	AST_FLAG_DISABLE_WORKAROUNDS = (1 << 20),
+	/*! Disable device state event caching.  This allows allows channel
+	 * drivers to selectively prevent device state events from being cached
+	 * by certain channels such as anonymous calls which have no persistent
+	 * represenatation that can be tracked.
+	 */
+	AST_FLAG_DISABLE_DEVSTATE_CACHE = (1 << 21),
 };
 
 /*! \brief ast_bridge_config flags */

Modified: certified/tags/1.8.11-cert10/include/asterisk/devicestate.h
URL: http://svnview.digium.com/svn/asterisk/certified/tags/1.8.11-cert10/include/asterisk/devicestate.h?view=diff&rev=378348&r1=378347&r2=378348
==============================================================================
--- certified/tags/1.8.11-cert10/include/asterisk/devicestate.h (original)
+++ certified/tags/1.8.11-cert10/include/asterisk/devicestate.h Wed Jan  2 13:27:54 2013
@@ -61,6 +61,14 @@
 	AST_DEVICE_TOTAL,        /*/ Total num of device states, used for testing */
 };
 
+/*! \brief Device State Cachability
+ *  \note This is used to define the cachability of a device state when set.
+ */
+enum ast_devstate_cache {
+	AST_DEVSTATE_NOT_CACHABLE,  /*!< This device state is not cachable */
+	AST_DEVSTATE_CACHABLE,      /*!< This device state is cachable */
+};
+
 /*! \brief Devicestate provider call back */
 typedef enum ast_device_state (*ast_devstate_prov_cb_type)(const char *data);
 
@@ -129,6 +137,7 @@
  * \brief Tells Asterisk the State for Device is changed
  *
  * \param state the new state of the device
+ * \param cachable whether this device state is cachable
  * \param fmt device name like a dial string with format parameters
  *
  * The new state of the device will be sent off to any subscribers
@@ -138,13 +147,14 @@
  * \retval 0 on success
  * \retval -1 on failure
  */
-int ast_devstate_changed(enum ast_device_state state, const char *fmt, ...)
-	__attribute__((format(printf, 2, 3)));
+int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt, ...)
+	__attribute__((format(printf, 3, 4)));
 
 /*!
  * \brief Tells Asterisk the State for Device is changed
  *
  * \param state the new state of the device
+ * \param cachable whether this device state is cachable
  * \param device device name like a dial string with format parameters
  *
  * The new state of the device will be sent off to any subscribers
@@ -154,7 +164,7 @@
  * \retval 0 on success
  * \retval -1 on failure
  */
-int ast_devstate_changed_literal(enum ast_device_state state, const char *device);
+int ast_devstate_changed_literal(enum ast_device_state state, enum ast_devstate_cache cachable, const char *device);
 
 /*!
  * \brief Tells Asterisk the State for Device is changed.

Modified: certified/tags/1.8.11-cert10/include/asterisk/event_defs.h
URL: http://svnview.digium.com/svn/asterisk/certified/tags/1.8.11-cert10/include/asterisk/event_defs.h?view=diff&rev=378348&r1=378347&r2=378348
==============================================================================
--- certified/tags/1.8.11-cert10/include/asterisk/event_defs.h (original)
+++ certified/tags/1.8.11-cert10/include/asterisk/event_defs.h Wed Jan  2 13:27:54 2013
@@ -290,8 +290,14 @@
 	AST_EVENT_IE_PRESENCE_STATE      = 0x0036,
 	AST_EVENT_IE_PRESENCE_SUBTYPE    = 0x0037,
 	AST_EVENT_IE_PRESENCE_MESSAGE    = 0x0038,
+	/*!
+	 * \brief Event non-cachability flag
+	 * Used by: All events
+	 * Payload type: UINT
+	 */
+	AST_EVENT_IE_CACHABLE            = 0x0039,
 	/*! \brief Must be the last IE value +1 */
-	AST_EVENT_IE_TOTAL               = 0x0039,
+	AST_EVENT_IE_TOTAL               = 0x003a,
 };
 
 /*!

Modified: certified/tags/1.8.11-cert10/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/certified/tags/1.8.11-cert10/main/channel.c?view=diff&rev=378348&r1=378347&r2=378348
==============================================================================
--- certified/tags/1.8.11-cert10/main/channel.c (original)
+++ certified/tags/1.8.11-cert10/main/channel.c Wed Jan  2 13:27:54 2013
@@ -285,6 +285,7 @@
 	ast_data_add_bool(tree, "BRIDGE_HANGUP_RUN", ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_RUN));
 	ast_data_add_bool(tree, "BRIDGE_HANGUP_DONT", ast_test_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT));
 	ast_data_add_bool(tree, "DISABLE_WORKAROUNDS", ast_test_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS));
+	ast_data_add_bool(tree, "DISABLE_DEVSTATE_CACHE", ast_test_flag(chan, AST_FLAG_DISABLE_DEVSTATE_CACHE));
 }
 
 #if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
@@ -2474,7 +2475,7 @@
 		 * instance is dead, we don't know the state of all other possible
 		 * instances.
 		 */
-		ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name);
+		ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, (chan->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), device_name);
 	}
 }
 
@@ -6912,7 +6913,7 @@
 	/* We have to pass AST_DEVICE_UNKNOWN here because it is entirely possible that the channel driver
 	 * for this channel is using the callback method for device state. If we pass in an actual state here
 	 * we override what they are saying the state is and things go amuck. */
-	ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name);
+	ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, (chan->flags & AST_FLAG_DISABLE_DEVSTATE_CACHE ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), name);
 
 	/* setstate used to conditionally report Newchannel; this is no more */
 	ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate",

Modified: certified/tags/1.8.11-cert10/main/devicestate.c
URL: http://svnview.digium.com/svn/asterisk/certified/tags/1.8.11-cert10/main/devicestate.c?view=diff&rev=378348&r1=378347&r2=378348
==============================================================================
--- certified/tags/1.8.11-cert10/main/devicestate.c (original)
+++ certified/tags/1.8.11-cert10/main/devicestate.c Wed Jan  2 13:27:54 2013
@@ -170,6 +170,7 @@
 
 struct state_change {
 	AST_LIST_ENTRY(state_change) list;
+	enum ast_devstate_cache cachable;
 	char device[1];
 };
 
@@ -187,6 +188,7 @@
 	AST_LIST_ENTRY(devstate_change) entry;
 	uint32_t state;
 	struct ast_eid eid;
+	enum ast_devstate_cache cachable;
 	char device[1];
 };
 
@@ -422,7 +424,7 @@
 	return res;
 }
 
-static void devstate_event(const char *device, enum ast_device_state state)
+static void devstate_event(const char *device, enum ast_device_state state, int cachable)
 {
 	struct ast_event *event;
 	enum ast_event_type event_type;
@@ -438,18 +440,23 @@
 	ast_debug(3, "device '%s' state '%d'\n", device, state);
 
 	if (!(event = ast_event_new(event_type,
-			AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device,
-			AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, state,
-			AST_EVENT_IE_END))) {
+				    AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, device,
+				    AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, state,
+				    AST_EVENT_IE_CACHABLE, AST_EVENT_IE_PLTYPE_UINT, cachable,
+				    AST_EVENT_IE_END))) {
 		return;
 	}
 
-	ast_event_queue_and_cache(event);
+	if (cachable) {
+		ast_event_queue_and_cache(event);
+	} else {
+		ast_event_queue(event);
+	}
 }
 
 /*! Called by the state change thread to find out what the state is, and then
  *  to queue up the state change event */
-static void do_state_change(const char *device)
+static void do_state_change(const char *device, int cachable)
 {
 	enum ast_device_state state;
 
@@ -457,10 +464,10 @@
 
 	ast_debug(3, "Changing state for %s - state %d (%s)\n", device, state, ast_devstate2str(state));
 
-	devstate_event(device, state);
-}
-
-int ast_devstate_changed_literal(enum ast_device_state state, const char *device)
+	devstate_event(device, state, cachable);
+}
+
+int ast_devstate_changed_literal(enum ast_device_state state, enum ast_devstate_cache cachable, const char *device)
 {
 	struct state_change *change;
 
@@ -481,14 +488,15 @@
 	 */
 
 	if (state != AST_DEVICE_UNKNOWN) {
-		devstate_event(device, state);
+		devstate_event(device, state, cachable);
 	} else if (change_thread == AST_PTHREADT_NULL || !(change = ast_calloc(1, sizeof(*change) + strlen(device)))) {
 		/* we could not allocate a change struct, or */
 		/* there is no background thread, so process the change now */
-		do_state_change(device);
+		do_state_change(device, cachable);
 	} else {
 		/* queue the change */
 		strcpy(change->device, device);
+		change->cachable = cachable;
 		AST_LIST_LOCK(&state_changes);
 		AST_LIST_INSERT_TAIL(&state_changes, change, list);
 		ast_cond_signal(&change_pending);
@@ -500,10 +508,10 @@
 
 int ast_device_state_changed_literal(const char *dev)
 {
-	return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, dev);
-}
-
-int ast_devstate_changed(enum ast_device_state state, const char *fmt, ...) 
+	return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, dev);
+}
+
+int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt, ...)
 {
 	char buf[AST_MAX_EXTENSION];
 	va_list ap;
@@ -512,7 +520,7 @@
 	vsnprintf(buf, sizeof(buf), fmt, ap);
 	va_end(ap);
 
-	return ast_devstate_changed_literal(state, buf);
+	return ast_devstate_changed_literal(state, cachable, buf);
 }
 
 int ast_device_state_changed(const char *fmt, ...) 
@@ -524,7 +532,7 @@
 	vsnprintf(buf, sizeof(buf), fmt, ap);
 	va_end(ap);
 
-	return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, buf);
+	return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, buf);
 }
 
 /*! \brief Go through the dev state change queue and update changes in the dev state thread */
@@ -544,7 +552,7 @@
 		/* Process each state change */
 		while ((current = next)) {
 			next = AST_LIST_NEXT(current, list);
-			do_state_change(current->device);
+			do_state_change(current->device, current->cachable);
 			ast_free(current);
 		}
 	}
@@ -588,7 +596,7 @@
 	collection->num_states++;
 }
 
-static void process_collection(const char *device, struct change_collection *collection)
+static void process_collection(const char *device, enum ast_devstate_cache cachable, struct change_collection *collection)
 {
 	int i;
 	struct ast_devstate_aggregate agg;
@@ -639,7 +647,11 @@
 		return;
 	}
 
-	ast_event_queue_and_cache(event);
+	if (cachable) {
+		ast_event_queue_and_cache(event);
+	} else {
+		ast_event_queue(event);
+	}
 }
 
 static void handle_devstate_change(struct devstate_change *sc)
@@ -665,7 +677,7 @@
 	/* Populate the collection of device states from the cache */
 	ast_event_dump_cache(tmp_sub);
 
-	process_collection(sc->device, &collection);
+	process_collection(sc->device, sc->cachable, &collection);
 
 	ast_event_sub_destroy(tmp_sub);
 }
@@ -694,10 +706,12 @@
 	const char *device;
 	const struct ast_eid *eid;
 	uint32_t state;
+	enum ast_devstate_cache cachable = AST_DEVSTATE_CACHABLE;
 
 	device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE);
 	eid = ast_event_get_ie_raw(event, AST_EVENT_IE_EID);
 	state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
+	cachable = ast_event_get_ie_uint(event, AST_EVENT_IE_CACHABLE);
 
 	if (ast_strlen_zero(device) || !eid) {
 		ast_log(LOG_ERROR, "Invalid device state change event received\n");
@@ -710,6 +724,7 @@
 	strcpy(sc->device, device);
 	sc->eid = *eid;
 	sc->state = state;
+	sc->cachable = cachable;
 
 	ast_mutex_lock(&devstate_collector.lock);

[... 305 lines stripped ...]



More information about the asterisk-commits mailing list