summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2013-01-02 18:11:59 +0000
committerMatthew Jordan <mjordan@digium.com>2013-01-02 18:11:59 +0000
commit8fb5bdce9ab9f7f3758545753cbc787653920753 (patch)
tree65809194af8a4fa757fef26a30a2cc9c3ed02182 /channels
parent1fb06fde957fb466388c764384c2e14698e2dc15 (diff)
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 ........ Merged revisions 378321 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@378322 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_agent.c12
-rw-r--r--channels/chan_dahdi.c7
-rw-r--r--channels/chan_iax2.c32
-rw-r--r--channels/chan_local.c3
-rw-r--r--channels/chan_sip.c18
-rw-r--r--channels/chan_skinny.c16
6 files changed, 51 insertions, 37 deletions
diff --git a/channels/chan_agent.c b/channels/chan_agent.c
index 42492f4a2..a9a70d01d 100644
--- a/channels/chan_agent.c
+++ b/channels/chan_agent.c
@@ -618,7 +618,7 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
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 @@ static int agent_call(struct ast_channel *ast, const char *dest, int timeout)
} 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 @@ static int agent_hangup(struct ast_channel *ast)
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) {
@@ -2143,7 +2143,7 @@ static int login_exec(struct ast_channel *chan, const char *data)
}
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) {
@@ -2164,7 +2164,7 @@ static int login_exec(struct ast_channel *chan, const char *data)
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 {
@@ -2235,7 +2235,7 @@ static int login_exec(struct ast_channel *chan, const char *data)
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);
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index ce2d23325..84b308910 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -3478,7 +3478,7 @@ static void dahdi_pri_update_span_devstate(struct sig_pri_span *pri)
}
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. */
@@ -3494,7 +3494,7 @@ static void dahdi_pri_update_span_devstate(struct sig_pri_span *pri)
}
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) */
}
@@ -10037,7 +10037,8 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
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);
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 7a2528fc3..42588b181 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -5819,7 +5819,7 @@ static int iax2_getpeertrunk(struct sockaddr_in sin)
}
/*! \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;
@@ -5901,6 +5901,10 @@ static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capab
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) {
for (v = i->vars ; v ; v = v->next)
@@ -8182,7 +8186,7 @@ static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *
/* 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;
@@ -8736,7 +8740,7 @@ static void __expire_registry(const void *data)
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);
@@ -8791,7 +8795,7 @@ static void reg_source_db(struct iax2_peer *p)
}
}
- 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) {
@@ -8868,14 +8872,14 @@ static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, i
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 */
@@ -10441,7 +10445,8 @@ static int socket_process_helper(struct iax2_thread *thread)
(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;
@@ -11083,13 +11088,13 @@ static int socket_process_helper(struct iax2_thread *thread)
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;
@@ -11333,7 +11338,7 @@ static int socket_process_helper(struct iax2_thread *thread)
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;
@@ -11404,7 +11409,7 @@ immediatedial:
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;
@@ -12171,7 +12176,7 @@ static void __iax2_poke_noanswer(const void *data)
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]);
@@ -12345,7 +12350,8 @@ static struct ast_channel *iax2_request(const char *type, struct ast_format_cap
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) {
diff --git a/channels/chan_local.c b/channels/chan_local.c
index 14912793f..7fa6bf513 100644
--- a/channels/chan_local.c
+++ b/channels/chan_local.c
@@ -1271,6 +1271,9 @@ static struct ast_channel *local_new(struct local_pvt *p, int state, const char
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;
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index b2b3395c7..18c14eacd 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -6854,7 +6854,7 @@ static int update_call_counter(struct sip_pvt *fup, int event)
}
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;
@@ -8115,6 +8115,9 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
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];
@@ -15668,7 +15671,7 @@ static int expire_register(const void *data)
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
@@ -16459,8 +16462,9 @@ static void sip_peer_hold(struct sip_pvt *p, int hold)
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;
}
@@ -16983,7 +16987,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock
} 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) {
@@ -23439,7 +23443,7 @@ static void handle_response_peerpoke(struct sip_pvt *p, int resp, struct sip_req
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);
}
@@ -29350,7 +29354,7 @@ static int sip_poke_noanswer(const void *data)
/* 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 */
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index 2e43411ab..a11cac620 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -2145,7 +2145,7 @@ static int skinny_register(struct skinny_req *req, struct skinnysession *s)
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;
@@ -2180,7 +2180,7 @@ static int skinny_unregister(struct skinny_req *req, struct skinnysession *s)
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);
}
}
}
@@ -5947,7 +5947,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
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;
}
@@ -5987,7 +5987,7 @@ static int handle_offhook_message(struct skinny_req *req, struct skinnysession *
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;
@@ -6054,7 +6054,7 @@ static int handle_onhook_message(struct skinny_req *req, struct skinnysession *s
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);
@@ -6390,7 +6390,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
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:
@@ -6544,8 +6544,8 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
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 */