[asterisk-commits] mjordan: branch 11 r378321 - in /branches/11: ./ apps/ apps/confbridge/ chann...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jan 2 12:10:02 CST 2013


Author: mjordan
Date: Wed Jan  2 12:09:55 2013
New Revision: 378321

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=378321
Log:
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.

(issue ASTERISK-20175)
Reported by: Russell Bryant, Leif Madsen, Joshua Colp
Tested by: kmoore
patches:
  event-cachability-3.diff uploaded by jcolp (license 5000)
........

Merged revisions 378303 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 378320 from http://svn.asterisk.org/svn/asterisk/branches/10

Modified:
    branches/11/   (props changed)
    branches/11/apps/app_confbridge.c
    branches/11/apps/app_meetme.c
    branches/11/apps/app_queue.c
    branches/11/apps/confbridge/conf_state_empty.c
    branches/11/channels/chan_agent.c
    branches/11/channels/chan_dahdi.c
    branches/11/channels/chan_iax2.c
    branches/11/channels/chan_local.c
    branches/11/channels/chan_sip.c
    branches/11/channels/chan_skinny.c
    branches/11/funcs/func_devstate.c
    branches/11/include/asterisk/channel.h
    branches/11/include/asterisk/devicestate.h
    branches/11/include/asterisk/event_defs.h
    branches/11/main/ccss.c
    branches/11/main/channel.c
    branches/11/main/channel_internal_api.c
    branches/11/main/devicestate.c
    branches/11/main/event.c
    branches/11/main/features.c
    branches/11/res/res_calendar.c
    branches/11/res/res_jabber.c

Propchange: branches/11/
------------------------------------------------------------------------------
Binary property 'branch-10-merged' - no diff available.

Modified: branches/11/apps/app_confbridge.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/apps/app_confbridge.c?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/apps/app_confbridge.c (original)
+++ branches/11/apps/app_confbridge.c Wed Jan  2 12:09:55 2013
@@ -1034,7 +1034,7 @@
 
 void conf_handle_first_join(struct conference_bridge *conference_bridge)
 {
-	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);
 }
 
 void conf_handle_second_active(struct conference_bridge *conference_bridge)

Modified: branches/11/apps/app_meetme.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/apps/app_meetme.c?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/apps/app_meetme.c (original)
+++ branches/11/apps/app_meetme.c Wed Jan  2 12:09:55 2013
@@ -2696,7 +2696,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);
 
@@ -4087,7 +4087,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);
 		}
 
  		/* This flag is meant to kill a conference with only one participant remaining.  */
@@ -5582,8 +5582,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;
 		}
 	}
@@ -6081,8 +6081,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);
 
@@ -6591,8 +6591,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: branches/11/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/apps/app_queue.c?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/apps/app_queue.c (original)
+++ branches/11/apps/app_queue.c Wed Jan  2 12:09:55 2013
@@ -1787,9 +1787,9 @@
 		if (found_member) {
 			found = 1;
 			if (avail) {
-				ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Queue:%s_avail", q->name);
+				ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
 			} else {
-				ast_devstate_changed(AST_DEVICE_INUSE, "Queue:%s_avail", q->name);
+				ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
 			}
 		}
 
@@ -2079,7 +2079,7 @@
 	 * AST_DEVICE_INUSE indicates no members are available.
 	 * AST_DEVICE_NOT_INUSE indicates a member is available.
 	 */
-	ast_devstate_changed(AST_DEVICE_INUSE, "Queue:%s_avail", q->name);
+	ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
 }
 
 static void clear_queue(struct call_queue *q)
@@ -2959,7 +2959,7 @@
 		ast_copy_string(qe->context, q->context, sizeof(qe->context));
 		q->count++;
 		if (q->count == 1) {
-			ast_devstate_changed(AST_DEVICE_RINGING, "Queue:%s", q->name);
+			ast_devstate_changed(AST_DEVICE_RINGING, AST_DEVSTATE_CACHABLE, "Queue:%s", q->name);
 		}
 
 		res = 0;
@@ -3267,7 +3267,7 @@
 			char posstr[20];
 			q->count--;
 			if (!q->count) {
-				ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Queue:%s", q->name);
+				ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s", q->name);
 			}
 
 			/* Take us out of the queue */
@@ -3540,7 +3540,7 @@
 			if (newstate != tmp->member->status) {
 				ast_log(LOG_WARNING, "Found a channel matching iterface %s while status was %s changed to %s\n",
 					tmp->member->interface, ast_devstate2str(tmp->member->status), ast_devstate2str(newstate));
-				ast_devstate_changed_literal(newstate, tmp->member->interface);
+				ast_devstate_changed_literal(newstate, AST_DEVSTATE_CACHABLE, tmp->member->interface);
 			}
 		}
 		if ((tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) {
@@ -6016,7 +6016,7 @@
 			}
 
 			if (!num_available_members(q)) {
-				ast_devstate_changed(AST_DEVICE_INUSE, "Queue:%s_avail", q->name);
+				ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
 			}
 
 			res = RES_OKAY;
@@ -6093,7 +6093,7 @@
 				new_member->status, new_member->paused);
 
 			if (is_member_available(new_member)) {
-				ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Queue:%s_avail", q->name);
+				ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
 			}
 
 			ao2_ref(new_member, -1);
@@ -6159,9 +6159,9 @@
 				}
 
 				if (is_member_available(mem)) {
-					ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Queue:%s_avail", q->name);
+					ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
 				} else if (!num_available_members(q)) {
-					ast_devstate_changed(AST_DEVICE_INUSE, "Queue:%s_avail", q->name);
+					ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Queue:%s_avail", q->name);
 				}
 
 				ast_queue_log(q->name, "NONE", mem->membername, (paused ? "PAUSE" : "UNPAUSE"), "%s", S_OR(reason, ""));

Modified: branches/11/apps/confbridge/conf_state_empty.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/apps/confbridge/conf_state_empty.c?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/apps/confbridge/conf_state_empty.c (original)
+++ branches/11/apps/confbridge/conf_state_empty.c Wed Jan  2 12:09:55 2013
@@ -81,6 +81,6 @@
 static void transition_to_empty(struct conference_bridge_user *cbu)
 {
 	/* Set device state to "not in use" */
-	ast_devstate_changed(AST_DEVICE_NOT_INUSE, "confbridge:%s", cbu->conference_bridge->name);
+	ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "confbridge:%s", cbu->conference_bridge->name);
 	conf_ended(cbu->conference_bridge);
 }

Modified: branches/11/channels/chan_agent.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/channels/chan_agent.c?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/channels/chan_agent.c (original)
+++ branches/11/channels/chan_agent.c Wed Jan  2 12:09:55 2013
@@ -618,7 +618,7 @@
 		if (p->chan) {
 			ast_channel_internal_bridged_channel_set(p->chan, 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 {
@@ -875,7 +875,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) {
@@ -995,7 +995,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) {
@@ -2166,7 +2166,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) {
@@ -2187,7 +2187,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 {
@@ -2258,7 +2258,7 @@
 						ast_queue_log("NONE", ast_channel_uniqueid(chan), agent, "AGENTLOGOFF", "%s|%ld", ast_channel_name(chan), 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: branches/11/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/channels/chan_dahdi.c?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/channels/chan_dahdi.c (original)
+++ branches/11/channels/chan_dahdi.c Wed Jan  2 12:09:55 2013
@@ -3438,7 +3438,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. */
@@ -3454,7 +3454,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) */
 }
@@ -10010,7 +10010,8 @@
 	if (dashptr) {
 		*dashptr = '\0';
 	}
-	ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name);
+	ast_set_flag(ast_channel_flags(tmp), 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: branches/11/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/channels/chan_iax2.c?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/channels/chan_iax2.c (original)
+++ branches/11/channels/chan_iax2.c Wed Jan  2 12:09:55 2013
@@ -5798,7 +5798,7 @@
 }
 
 /*! \brief  Create new call, interface with the PBX core */
-static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capability, const char *linkedid)
+static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capability, const char *linkedid, unsigned int cachable)
 {
 	struct ast_channel *tmp;
 	struct chan_iax2_pvt *i;
@@ -5879,6 +5879,10 @@
 		ast_channel_adsicpe_set(tmp, AST_ADSI_UNAVAILABLE);
 	i->owner = tmp;
 	i->capability = capability;
+
+	if (!cachable) {
+		ast_set_flag(ast_channel_flags(tmp), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+	}
 
 	/* Set inherited variables */
 	if (i->vars) {
@@ -8161,7 +8165,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;
@@ -8715,7 +8719,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);
 
@@ -8770,7 +8774,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) {
@@ -8847,14 +8851,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\nAddress: %s\r\nPort: %d\r\n", p->name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
 			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 */
@@ -10420,7 +10424,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;
@@ -11062,13 +11067,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;
@@ -11312,7 +11317,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;
@@ -11383,7 +11388,7 @@
 							iax2_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;
@@ -12150,7 +12155,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]);
@@ -12324,7 +12329,8 @@
 		ast_string_field_set(iaxs[callno], host, pds.peer);
 	}
 
-	c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? ast_channel_linkedid(requestor) : NULL);
+	c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? ast_channel_linkedid(requestor) : NULL, cai.found);
+
 	ast_mutex_unlock(&iaxsl[callno]);
 
 	if (c) {

Modified: branches/11/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/channels/chan_local.c?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/channels/chan_local.c (original)
+++ branches/11/channels/chan_local.c Wed Jan  2 12:09:55 2013
@@ -1277,6 +1277,9 @@
 	ast_channel_tech_pvt_set(tmp, p);
 	ast_channel_tech_pvt_set(tmp2, p);
 
+	ast_set_flag(ast_channel_flags(tmp), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+	ast_set_flag(ast_channel_flags(tmp2), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+
 	p->owner = tmp;
 	p->chan = tmp2;
 

Modified: branches/11/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/channels/chan_sip.c?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/channels/chan_sip.c (original)
+++ branches/11/channels/chan_sip.c Wed Jan  2 12:09:55 2013
@@ -6795,7 +6795,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);
 		sip_unref_peer(p, "update_call_counter: sip_unref_peer from call counter");
 	}
 	return 0;
@@ -8056,6 +8056,9 @@
 		ast_jb_configure(tmp, &global_jbconf);
 	}
 
+	if (!i->relatedpeer) {
+		ast_set_flag(ast_channel_flags(tmp), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+	}
 	/* Set channel variables for this call from configuration */
 	for (v = i->chanvars ; v ; v = v->next) {
 		char valuebuf[1024];
@@ -15577,7 +15580,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
@@ -16362,8 +16365,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, (ast_test_flag(ast_channel_flags(p->owner), AST_FLAG_DISABLE_DEVSTATE_CACHE) ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE),
+			     "SIP/%s", p->relatedpeer->name);
+
 	return;
 }
 
@@ -16886,7 +16890,7 @@
 		} else {
 			update_peer_lastmsgssent(peer, -1, 0);
 		}
-		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) {
@@ -23259,7 +23263,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);
 		}
@@ -29161,7 +29165,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: branches/11/channels/chan_skinny.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/channels/chan_skinny.c?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/channels/chan_skinny.c (original)
+++ branches/11/channels/chan_skinny.c Wed Jan  2 12:09:55 2013
@@ -2132,7 +2132,7 @@
 				AST_LIST_TRAVERSE(&l->sublines, subline, list) {
 					ast_extension_state_add(subline->context, subline->exten, skinny_extensionstate_cb, subline->container);
 				}
-				ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s", l->name);
+				ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name);
 				--instance;
 			}
 			break;
@@ -2167,7 +2167,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", l->name);
+				ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name);
 			}
 		}
 	}
@@ -5934,7 +5934,7 @@
 			event, d->name, instance, callreference);
 		break;
 	}
-	ast_devstate_changed(AST_DEVICE_UNKNOWN, "Skinny/%s", l->name);
+	ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name);
 
 	return 1;
 }
@@ -5974,7 +5974,7 @@
 	transmit_ringer_mode(d, SKINNY_RING_OFF);
 	d->hookstate = SKINNY_OFFHOOK;
 
-	ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s", l->name);
+	ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name);
 
 	if (sub && sub->substate == SUBSTATE_HOLD) {
 		return 1;
@@ -6041,7 +6041,7 @@
 		return 0;
 	}
 	
-	ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s", l->name);
+	ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name);
 	
 	dumpsub(sub, 0);
 
@@ -6377,7 +6377,7 @@
 		return 0;
 	}
 
-	ast_devstate_changed(AST_DEVICE_INUSE, "Skinny/%s", l->name);
+	ast_devstate_changed(AST_DEVICE_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name);
 
 	switch(event) {
 	case SOFTKEY_NONE:
@@ -6531,8 +6531,8 @@
 			return 0;
 		}
 	
-		ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Skinny/%s", l->name);
-	
+		ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name);
+
 		if (sub) {
 			dumpsub(sub, 1);
 		} else { /* No sub, maybe an SLA call */

Modified: branches/11/funcs/func_devstate.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/funcs/func_devstate.c?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/funcs/func_devstate.c (original)
+++ branches/11/funcs/func_devstate.c Wed Jan  2 12:09:55 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;
 }
@@ -295,7 +295,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;
 }
@@ -341,7 +341,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: branches/11/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/branches/11/include/asterisk/channel.h?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/include/asterisk/channel.h (original)
+++ branches/11/include/asterisk/channel.h Wed Jan  2 12:09:55 2013
@@ -888,6 +888,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: branches/11/include/asterisk/devicestate.h
URL: http://svnview.digium.com/svn/asterisk/branches/11/include/asterisk/devicestate.h?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/include/asterisk/devicestate.h (original)
+++ branches/11/include/asterisk/devicestate.h Wed Jan  2 12:09:55 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: branches/11/include/asterisk/event_defs.h
URL: http://svnview.digium.com/svn/asterisk/branches/11/include/asterisk/event_defs.h?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/include/asterisk/event_defs.h (original)
+++ branches/11/include/asterisk/event_defs.h Wed Jan  2 12:09:55 2013
@@ -298,8 +298,14 @@
 	AST_EVENT_IE_PRESENCE_SUBTYPE    = 0x003b,
 	AST_EVENT_IE_PRESENCE_MESSAGE    = 0x003c,
 
+	/*!
+	 * \brief Event non-cachability flag
+	 * Used by: All events
+	 * Payload type: UINT
+	 */
+	AST_EVENT_IE_CACHABLE            = 0x003d,
 	/*! \brief Must be the last IE value +1 */
-	AST_EVENT_IE_TOTAL               = 0x003d,
+	AST_EVENT_IE_TOTAL               = 0x003e,
 };
 
 /*!

Modified: branches/11/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/main/ccss.c?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/main/ccss.c (original)
+++ branches/11/main/ccss.c Wed Jan  2 12:09:55 2013
@@ -638,7 +638,7 @@
 		"Notification of CCSS state change to '%s', device state '%s' for device '%s'\n",
 		cc_state_to_string(state), ast_devstate2str(devstate), device);
 
-	ast_devstate_changed(devstate, "ccss:%s", device);
+	ast_devstate_changed(devstate, AST_DEVSTATE_CACHABLE, "ccss:%s", device);
 }
 
 #define CC_OFFER_TIMER_DEFAULT			20		/* Seconds */

Modified: branches/11/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/main/channel.c?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/main/channel.c (original)
+++ branches/11/main/channel.c Wed Jan  2 12:09:55 2013
@@ -2434,7 +2434,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, (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE) ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), device_name);
 	}
 
 	ast_channel_nativeformats_set(chan, ast_format_cap_destroy(ast_channel_nativeformats(chan)));
@@ -7353,7 +7353,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, (ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE) ? AST_DEVSTATE_NOT_CACHABLE : AST_DEVSTATE_CACHABLE), name);
 
 	/* setstate used to conditionally report Newchannel; this is no more */
 	/*** DOCUMENTATION

Modified: branches/11/main/channel_internal_api.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/main/channel_internal_api.c?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/main/channel_internal_api.c (original)
+++ branches/11/main/channel_internal_api.c Wed Jan  2 12:09:55 2013
@@ -263,6 +263,7 @@
 	ast_data_add_bool(tree, "BRIDGE_HANGUP_RUN", ast_test_flag(ast_channel_flags(chan), AST_FLAG_BRIDGE_HANGUP_RUN));
 	ast_data_add_bool(tree, "BRIDGE_HANGUP_DONT", ast_test_flag(ast_channel_flags(chan), AST_FLAG_BRIDGE_HANGUP_DONT));
 	ast_data_add_bool(tree, "DISABLE_WORKAROUNDS", ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS));
+	ast_data_add_bool(tree, "DISABLE_DEVSTATE_CACHE", ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE));
 }
 
 int ast_channel_data_add_structure(struct ast_data *tree,

Modified: branches/11/main/devicestate.c
URL: http://svnview.digium.com/svn/asterisk/branches/11/main/devicestate.c?view=diff&rev=378321&r1=378320&r2=378321
==============================================================================
--- branches/11/main/devicestate.c (original)
+++ branches/11/main/devicestate.c Wed Jan  2 12:09:55 2013
@@ -174,6 +174,7 @@
 
 struct state_change {
 	AST_LIST_ENTRY(state_change) list;
+	enum ast_devstate_cache cachable;
 	char device[1];
 };
 
@@ -191,6 +192,7 @@
 	AST_LIST_ENTRY(devstate_change) entry;
 	uint32_t state;
 	struct ast_eid eid;
+	enum ast_devstate_cache cachable;
 	char device[1];
 };
 
@@ -424,7 +426,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;
@@ -440,18 +442,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;
 
@@ -459,10 +466,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;
 
@@ -483,14 +490,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);
@@ -502,10 +510,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;
@@ -514,7 +522,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, ...)
@@ -526,7 +534,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 */
@@ -546,7 +554,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);
 		}
 	}
@@ -590,7 +598,7 @@
 	collection->num_states++;
 }
 
-static void process_collection(const char *device, struct change_collection *collection)

[... 268 lines stripped ...]



More information about the asterisk-commits mailing list