]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merge changes for 11.2.0-rc2
authorAsterisk Autobuilder <asteriskteam@digium.com>
Wed, 9 Jan 2013 20:43:00 +0000 (20:43 +0000)
committerAsterisk Autobuilder <asteriskteam@digium.com>
Wed, 9 Jan 2013 20:43:00 +0000 (20:43 +0000)
* 378687, 378690, 378036 for ASTERISK-20801
* 378287, 378409 for ASTERISK-20658
* 378582 for ASTERISK-20681
* 378321, 378411 for ASTERISK-20175

git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/11.2.0-rc2@378785 65c4cc65-6c06-0410-ace0-fbb531ad65f3

35 files changed:
.version
CHANGES
ChangeLog
UPGRADE.txt
apps/app_confbridge.c
apps/app_meetme.c
apps/app_queue.c
apps/confbridge/conf_state_empty.c
asterisk-11.2.0-rc1-summary.html [deleted file]
asterisk-11.2.0-rc1-summary.txt [deleted file]
channels/chan_agent.c
channels/chan_dahdi.c
channels/chan_iax2.c
channels/chan_local.c
channels/chan_sip.c
channels/chan_skinny.c
channels/sip/include/sip.h
configs/queues.conf.sample
funcs/func_devstate.c
include/asterisk/channel.h
include/asterisk/devicestate.h
include/asterisk/event_defs.h
main/ccss.c
main/channel.c
main/channel_internal_api.c
main/devicestate.c
main/event.c
main/features.c
main/http.c
res/pjproject/aconfigure
res/pjproject/aconfigure.ac
res/pjproject/build/common.mak
res/res_calendar.c
res/res_jabber.c
res/res_xmpp.c

index 94ba9ae2bd6236c18196c4014ebc033247372dd2..b7ce1a2353df22cee41898b49d3935bc87ca1187 100644 (file)
--- a/.version
+++ b/.version
@@ -1 +1 @@
-11.2.0-rc1
+11.2.0-rc2
diff --git a/CHANGES b/CHANGES
index b28e3bf6c30938697323fdb268432cfcc7eab103..e317f47dbf9eb12f06f1f7adcdafa31170bedf40 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -901,8 +901,6 @@ Queue changes
  * Added member option ignorebusy this when set and ringinuse is not
    will allow per member control of multiple calls as ringinuse does for
    the Queue.
- * Added global option check_state_unknown to enforce checking of device state
-   when the device state is unknown app_queue will see unknown as available.
 
 Applications
 ------------
index 8c03a7aa252b9e1e38154b759a9d8c8966497e22..42366ce19f0dbac909a450229e08f55cee9c707d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,78 @@
+2013-01-09  Asterisk Development Team <asteriskteam@digium.com>
+
+       * Asterisk 11.2.0-rc2 Released.
+
+       * Fix pjproject compilation in certain circumstances.
+
+         On a fresh checkout of Asterisk 11, running make before ./configure
+         could cause the pjproject subdirectory to get in an odd state that
+         would prevent compilation. This patch by Tilghman prevents that from
+         occurring.
+
+         (closes issue ASTERISK-20681)
+         Patch-by: Tilghman Lesher
+
+       * AST-2012-014: 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, the allocation has been eliminated since it was
+           unnecessary.
+
+         This patch contains the fix for both res_jabber and res_xmpp.
+
+       * AST-2012-015: 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 call 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.
+
+       * Revert bad ringinuse=no patch.
+
+         With the option ringinuse=no set, the patch committed previous for
+         ASTERISK-16115 causes non-SIP queue members to never be called
+         because the device state is checked after a channel is created to
+         determine if the member is busy. These queue members always get the
+         "Member %s is busy, cannot dial" message.
+
+         Most channel drivers other than chan_sip use the default device
+         state handling. The default device state is considered in use or
+         unknown if the channel exists or not, respectively.
+
+       * Fix multiple calls to a queue member that is only in queue.
+
+         When ringinuse=no queue members can receive more than one call if
+         these calls happen at nearly the same time. This patch fixes it so a
+         queu member does not receive more than one call from a queue. note
+         that this fix does not prevent multiple calls to a member if hte
+         member is in more than one queue (see ASTERISK-16115).
+
 2012-12-10  Asterisk Development Team <asteriskteam@digium.com>
 
        * Asterisk 11.2.0-rc1 Released.
index 4f9691344d11d965742a7b90d86e418e614d1147..ae1ba2feeb71eae3f3a47d8ee87688a95f6b7cda 100644 (file)
@@ -26,6 +26,9 @@ From 11.1 to 11.2:
   part of a character set in the dialplan extensions.  The code now
   consistently ignores these characters when matching dialplan extensions.
 
+* Removed the queues.conf check_state_unknown option.  It is no longer
+  necessary.
+
 From 11.0 to 11.1:
 
 Queues:
index b0f61e9902e12149e276e20be954395605d812e5..12ae7872cd9a6ea4eb750968016cc49d8e259734 100644 (file)
@@ -953,7 +953,7 @@ int conf_add_post_join_action(struct conference_bridge_user *cbu, int (*func)(st
 
 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)
index 5b300d1111cf72c8fc4c44def9e6e7f15547259d..05ef9f4b25e03169a3fae31cf929679fb9dd6bb7 100644 (file)
@@ -2696,7 +2696,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
 
        /* 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 @@ bailoutandtrynormal:
 
                /* 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 @@ static void sla_change_trunk_state(const struct sla_trunk *trunk, enum sla_trunk
                                || 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 @@ static void sla_handle_hold_event(struct sla_event *event)
 {
        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 @@ static int sla_station_exec(struct ast_channel *chan, const char *data)
                        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;
index 62b54b6eed539ee67dc4ded91f0b3b85630c9b7f..9f262a7a611379295080c947755c2ac85b13075c 100644 (file)
@@ -1042,9 +1042,6 @@ static int negative_penalty_invalid = 0;
 /*! \brief queues.conf [general] option */
 static int log_membername_as_agent = 0;
 
-/*! \brief queues.conf [general] option */
-static int check_state_unknown = 0;
-
 /*! \brief name of the ringinuse field in the realtime database */
 static char *realtime_ringinuse_field;
 
@@ -1160,6 +1157,7 @@ struct member {
        struct call_queue *lastqueue;        /*!< Last queue we received a call */
        unsigned int dead:1;                 /*!< Used to detect members deleted in realtime */
        unsigned int delme:1;                /*!< Flag to delete entry on reload */
+       unsigned int call_pending:1;         /*!< TRUE if the Q is attempting to place a call to the member. */
        char rt_uniqueid[80];                /*!< Unique id of realtime member entry */
        unsigned int ringinuse:1;            /*!< Flag to ring queue members even if their status is 'inuse' */
 };
@@ -1787,9 +1785,9 @@ static int handle_statechange(void *datap)
                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 +2077,7 @@ static void init_queue(struct call_queue *q)
         * 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 +2957,7 @@ static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *
                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 +3265,7 @@ static void leave_queue(struct queue_ent *qe)
                        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 */
@@ -3488,6 +3486,112 @@ static char *vars2manager(struct ast_channel *chan, char *vars, size_t len)
        return vars;
 }
 
+/*!
+ * \internal
+ * \brief Check if the member status is available.
+ *
+ * \param status Member status to check if available.
+ *
+ * \retval non-zero if the member status is available.
+ */
+static int member_status_available(int status)
+{
+       return status == AST_DEVICE_NOT_INUSE || status == AST_DEVICE_UNKNOWN;
+}
+
+/*!
+ * \internal
+ * \brief Clear the member call pending flag.
+ *
+ * \param mem Queue member.
+ *
+ * \return Nothing
+ */
+static void member_call_pending_clear(struct member *mem)
+{
+       ao2_lock(mem);
+       mem->call_pending = 0;
+       ao2_unlock(mem);
+}
+
+/*!
+ * \internal
+ * \brief Set the member call pending flag.
+ *
+ * \param mem Queue member.
+ *
+ * \retval non-zero if call pending flag was already set.
+ */
+static int member_call_pending_set(struct member *mem)
+{
+       int old_pending;
+
+       ao2_lock(mem);
+       old_pending = mem->call_pending;
+       mem->call_pending = 1;
+       ao2_unlock(mem);
+
+       return old_pending;
+}
+
+/*!
+ * \internal
+ * \brief Determine if can ring a queue entry.
+ *
+ * \param qe Queue entry to check.
+ * \param call Member call attempt.
+ *
+ * \retval non-zero if an entry can be called.
+ */
+static int can_ring_entry(struct queue_ent *qe, struct callattempt *call)
+{
+       if (call->member->paused) {
+               ast_debug(1, "%s paused, can't receive call\n", call->interface);
+               return 0;
+       }
+
+       if (!call->member->ringinuse && !member_status_available(call->member->status)) {
+               ast_debug(1, "%s not available, can't receive call\n", call->interface);
+               return 0;
+       }
+
+       if ((call->lastqueue && call->lastqueue->wrapuptime && (time(NULL) - call->lastcall < call->lastqueue->wrapuptime))
+               || (!call->lastqueue && qe->parent->wrapuptime && (time(NULL) - call->lastcall < qe->parent->wrapuptime))) {
+               ast_debug(1, "Wrapuptime not yet expired on queue %s for %s\n",
+                       (call->lastqueue ? call->lastqueue->name : qe->parent->name),
+                       call->interface);
+               return 0;
+       }
+
+       if (use_weight && compare_weight(qe->parent, call->member)) {
+               ast_debug(1, "Priority queue delaying call to %s:%s\n",
+                       qe->parent->name, call->interface);
+               return 0;
+       }
+
+       if (!call->member->ringinuse) {
+               if (member_call_pending_set(call->member)) {
+                       ast_debug(1, "%s has another call pending, can't receive call\n",
+                               call->interface);
+                       return 0;
+               }
+
+               /*
+                * The queue member is available.  Get current status to be sure
+                * because the device state and extension state callbacks may
+                * not have updated the status yet.
+                */
+               if (!member_status_available(get_queue_member_status(call->member))) {
+                       ast_debug(1, "%s actually not available, can't receive call\n",
+                               call->interface);
+                       member_call_pending_clear(call->member);
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
 /*! 
  * \brief Part 2 of ring_one
  *
@@ -3509,60 +3613,17 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies
        char tech[256];
        char *location;
        const char *macrocontext, *macroexten;
-       enum ast_device_state newstate;
 
        /* on entry here, we know that tmp->chan == NULL */
-       if (tmp->member->paused) {
-               ast_debug(1, "%s paused, can't receive call\n", tmp->interface);
-               if (ast_channel_cdr(qe->chan)) {
-                       ast_cdr_busy(ast_channel_cdr(qe->chan));
-               }
-               tmp->stillgoing = 0;
-               (*busies)++;
-               return 0;
-       }
-
-       if ((tmp->lastqueue && tmp->lastqueue->wrapuptime && (time(NULL) - tmp->lastcall < tmp->lastqueue->wrapuptime)) ||
-               (!tmp->lastqueue && qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime))) {
-               ast_debug(1, "Wrapuptime not yet expired on queue %s for %s\n",
-                               (tmp->lastqueue ? tmp->lastqueue->name : qe->parent->name), tmp->interface);
-               if (ast_channel_cdr(qe->chan)) {
-                       ast_cdr_busy(ast_channel_cdr(qe->chan));
-               }
-               tmp->stillgoing = 0;
-               (*busies)++;
-               return 0;
-       }
-
-       if (!tmp->member->ringinuse) {
-               if (check_state_unknown && (tmp->member->status == AST_DEVICE_UNKNOWN)) {
-                       newstate = ast_device_state(tmp->member->interface);
-                       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);
-                       }
-               }
-               if ((tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) {
-                       ast_debug(1, "%s in use, can't receive call\n", tmp->interface);
-                       if (ast_channel_cdr(qe->chan)) {
-                               ast_cdr_busy(ast_channel_cdr(qe->chan));
-                       }
-                       tmp->stillgoing = 0;
-                       (*busies)++;
-                       return 0;
-               }
-       }
-
-       if (use_weight && compare_weight(qe->parent,tmp->member)) {
-               ast_debug(1, "Priority queue delaying call to %s:%s\n", qe->parent->name, tmp->interface);
+       if (!can_ring_entry(qe, tmp)) {
                if (ast_channel_cdr(qe->chan)) {
                        ast_cdr_busy(ast_channel_cdr(qe->chan));
                }
                tmp->stillgoing = 0;
-               (*busies)++;
+               ++*busies;
                return 0;
        }
+       ast_assert(tmp->member->ringinuse || tmp->member->call_pending);
 
        ast_copy_string(tech, tmp->interface, sizeof(tech));
        if ((location = strchr(tech, '/'))) {
@@ -3574,18 +3635,18 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies
        /* Request the peer */
        tmp->chan = ast_request(tech, ast_channel_nativeformats(qe->chan), qe->chan, location, &status);
        if (!tmp->chan) {                       /* If we can't, just go on to the next call */
-               if (ast_channel_cdr(qe->chan)) {
-                       ast_cdr_busy(ast_channel_cdr(qe->chan));
-               }
-               tmp->stillgoing = 0;
-
                ao2_lock(qe->parent);
-               update_status(qe->parent, tmp->member, get_queue_member_status(tmp->member));
                qe->parent->rrpos++;
                qe->linpos++;
                ao2_unlock(qe->parent);
 
-               (*busies)++;
+               member_call_pending_clear(tmp->member);
+
+               if (ast_channel_cdr(qe->chan)) {
+                       ast_cdr_busy(ast_channel_cdr(qe->chan));
+               }
+               tmp->stillgoing = 0;
+               ++*busies;
                return 0;
        }
 
@@ -3656,25 +3717,17 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies
        ast_channel_unlock(tmp->chan);
        ast_channel_unlock(qe->chan);
 
-       ao2_lock(tmp->member);
-       update_status(qe->parent, tmp->member, get_queue_member_status(tmp->member));
-       if (!qe->parent->ringinuse && (tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) {
-               ast_verb(1, "Member %s is busy, cannot dial", tmp->member->interface);
-               res = -1;
-       }
-       else {
-               /* Place the call, but don't wait on the answer */
-               res = ast_call(tmp->chan, location, 0);
-       }
-       ao2_unlock(tmp->member);
-       if (res) {
+       /* Place the call, but don't wait on the answer */
+       if ((res = ast_call(tmp->chan, location, 0))) {
                /* Again, keep going even if there's an error */
                ast_verb(3, "Couldn't call %s\n", tmp->interface);
                do_hang(tmp);
-               (*busies)++;
-               update_status(qe->parent, tmp->member, get_queue_member_status(tmp->member));
+               member_call_pending_clear(tmp->member);
+               ++*busies;
                return 0;
-       } else if (qe->parent->eventwhencalled) {
+       }
+
+       if (qe->parent->eventwhencalled) {
                char vars[2048];
 
                ast_channel_lock_both(tmp->chan, qe->chan);
@@ -3730,7 +3783,7 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies
                ast_verb(3, "Called %s\n", tmp->interface);
        }
 
-       update_status(qe->parent, tmp->member, get_queue_member_status(tmp->member));
+       member_call_pending_clear(tmp->member);
        return 1;
 }
 
@@ -6026,7 +6079,7 @@ static int remove_from_queue(const char *queuename, const char *interface)
                        }
 
                        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;
@@ -6103,7 +6156,7 @@ static int add_to_queue(const char *queuename, const char *interface, const char
                                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);
@@ -6169,9 +6222,9 @@ static int set_member_paused(const char *queuename, const char *interface, const
                                }
 
                                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, ""));
@@ -7724,10 +7777,6 @@ static void queue_set_global_params(struct ast_config *cfg)
        if ((general_val = ast_variable_retrieve(cfg, "general", "log_membername_as_agent"))) {
                log_membername_as_agent = ast_true(general_val);
        }
-       check_state_unknown = 0;
-       if ((general_val = ast_variable_retrieve(cfg, "general", "check_state_unknown"))) {
-               check_state_unknown = ast_true(general_val);
-       }
 }
 
 /*! \brief reload information pertaining to a single member
@@ -8505,7 +8554,7 @@ static int manager_queues_summary(struct mansession *s, const struct message *m)
                        while ((mem = ao2_iterator_next(&mem_iter))) {
                                if ((mem->status != AST_DEVICE_UNAVAILABLE) && (mem->status != AST_DEVICE_INVALID)) {
                                        ++qmemcount;
-                                       if (((mem->status == AST_DEVICE_NOT_INUSE) || (mem->status == AST_DEVICE_UNKNOWN)) && !(mem->paused)) {
+                                       if (member_status_available(mem->status) && !mem->paused) {
                                                ++qmemavail;
                                        }
                                }
index 22997ad2c6cf08d7243e7020481bf29ae32da3b6..afc736d4a2156143c5035ad6b564b0634d71f621 100644 (file)
@@ -81,6 +81,6 @@ static void join_marked(struct conference_bridge_user *cbu)
 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);
 }
diff --git a/asterisk-11.2.0-rc1-summary.html b/asterisk-11.2.0-rc1-summary.html
deleted file mode 100644 (file)
index 4b7e9d9..0000000
+++ /dev/null
@@ -1,403 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /><title>Release Summary - asterisk-11.2.0-rc1</title></head>
-<body>
-<h1 align="center"><a name="top">Release Summary</a></h1>
-<h3 align="center">asterisk-11.2.0-rc1</h3>
-<h3 align="center">Date: 2012-12-09</h3>
-<h3 align="center">&lt;asteriskteam@digium.com&gt;</h3>
-<hr/>
-<h2 align="center">Table of Contents</h2>
-<ol>
-   <li><a href="#summary">Summary</a></li>
-   <li><a href="#contributors">Contributors</a></li>
-   <li><a href="#issues">Closed Issues</a></li>
-   <li><a href="#commits">Other Changes</a></li>
-   <li><a href="#diffstat">Diffstat</a></li>
-</ol>
-<hr/>
-<a name="summary"><h2 align="center">Summary</h2></a>
-<center><a href="#top">[Back to Top]</a></center><br/><p>This release includes only bug fixes.  The changes included were made only to address problems that have been identified in this release series.  Users should be able to safely upgrade to this version if this release series is already in use.  Users considering upgrading from a previous release series are strongly encouraged to review the UPGRADE.txt document as well as the CHANGES document for information about upgrading to this release series.</p>
-<p>The data in this summary reflects changes that have been made since the previous release, asterisk-11.1.0.</p>
-<hr/>
-<a name="contributors"><h2 align="center">Contributors</h2></a>
-<center><a href="#top">[Back to Top]</a></center><br/><p>This table lists the people who have submitted code, those that have tested patches, as well as those that reported issues on the issue tracker that were resolved in this release.  For coders, the number is how many of their patches (of any size) were committed into this release.  For testers, the number is the number of times their name was listed as assisting with testing a patch.  Finally, for reporters, the number is the number of issues that they reported that were closed by commits that went into this release.</p>
-<table width="100%" border="0">
-<tr>
-<td width="33%"><h3>Coders</h3></td>
-<td width="33%"><h3>Testers</h3></td>
-<td width="33%"><h3>Reporters</h3></td>
-</tr>
-<tr valign="top">
-<td>
-22 rmudgett<br/>
-4 jcolp<br/>
-4 jrose<br/>
-4 mjordan<br/>
-4 mmichelson<br/>
-3 dlee<br/>
-2 elguero<br/>
-2 russell<br/>
-2 tilghman<br/>
-1 alecdavis<br/>
-1 Andre Luis<br/>
-1 beagles<br/>
-1 file<br/>
-1 James Le Cuirot<br/>
-1 Jeremiah Gowdy<br/>
-1 jkroon<br/>
-1 kmoore<br/>
-1 pkiefer<br/>
-1 Rusty Newton<br/>
-1 seanbright<br/>
-1 wdoekes<br/>
-</td>
-<td>
-3 rmudgett<br/>
-1 alecdavis<br/>
-1 elguero<br/>
-1 Jared Smith<br/>
-1 mjordan<br/>
-1 Rusty Newton<br/>
-1 Steven T. Wheeler<br/>
-</td>
-<td>
-4 mjordan<br/>
-1 alecdavis<br/>
-1 andrel<br/>
-1 chewi<br/>
-1 coopvr<br/>
-1 deti<br/>
-1 dlee<br/>
-1 eabad<br/>
-1 elguero<br/>
-1 ibc<br/>
-1 jgowdy<br/>
-1 jkroon<br/>
-1 joshoa<br/>
-1 jrose<br/>
-1 jsmith<br/>
-1 mcargile<br/>
-1 p_lindheimer<br/>
-1 rmudgett<br/>
-1 sruffell<br/>
-1 supertle<br/>
-1 swheeler<br/>
-1 tomo1657<br/>
-1 tootai<br/>
-1 vldmr<br/>
-1 wimpy<br/>
-</td>
-</tr>
-</table>
-<hr/>
-<a name="issues"><h2 align="center">Closed Issues</h2></a>
-<center><a href="#top">[Back to Top]</a></center><br/><p>This is a list of all issues from the issue tracker that were closed by changes that went into this release.</p>
-<h3>Category: Applications/app_confbridge</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20655">ASTERISK-20655</a>: Cannot reset pin with CONFBRIDGE(user,pin)<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377228">377228</a><br/>
-Reporter: wimpy<br/>
-Coders: rmudgett<br/>
-<br/>
-<h3>Category: Applications/app_meetme</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20486">ASTERISK-20486</a>: MeetMe Unable to write frame to channel after SIP channel hangs up.<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376310">376310</a><br/>
-Reporter: mcargile<br/>
-Coders: jrose<br/>
-<br/>
-<h3>Category: Applications/app_queue</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-19918">ASTERISK-19918</a>: MoH (Music on Hold) is stopped after call in a queue is terminated<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376217">376217</a><br/>
-Reporter: eabad<br/>
-Coders: beagles<br/>
-<br/>
-<h3>Category: Applications/app_voicemail</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20280">ASTERISK-20280</a>: In app_voicemail we attempt to play the sound "vm-urgent-removed", which should be "vm-marked-nonurgent"<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376264">376264</a><br/>
-Reporter: tomo1657<br/>
-Testers: Rusty Newton<br/>
-Coders: Rusty Newton<br/>
-<br/>
-<h3>Category: Channels/General</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20414">ASTERISK-20414</a>: Timeout antipattern using ast_waitfor_nandfds<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376014">376014</a><br/>
-Reporter: dlee<br/>
-Coders: mmichelson<br/>
-<br/>
-<h3>Category: Channels/chan_bridge</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20492">ASTERISK-20492</a>: Stuck DTMF when using ChannelRedirect to split a two channel bridge<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=375966">375966</a><br/>
-Reporter: jgowdy<br/>
-Testers: rmudgett<br/>
-Coders: Jeremiah Gowdy, rmudgett<br/>
-<br/>
-<h3>Category: Channels/chan_dahdi/SS7</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20204">ASTERISK-20204</a>: Asterisk not rejecting call setup on CIC that is down<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376060">376060</a><br/>
-Reporter: supertle<br/>
-Coders: rmudgett<br/>
-<br/>
-<h3>Category: Channels/chan_local</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20769">ASTERISK-20769</a>: Memory leak of local_pvt in chan_local.<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376870">376870</a><br/>
-Reporter: rmudgett<br/>
-Testers: rmudgett<br/>
-Coders: rmudgett<br/>
-<br/>
-<h3>Category: Channels/chan_motif</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20671">ASTERISK-20671</a>: Add Who Hung Up support to the Motif channel driver<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377462">377462</a><br/>
-Reporter: mjordan<br/>
-Coders: jcolp<br/>
-<br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20751">ASTERISK-20751</a>: chan_motif leaves UDP ports open<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377021">377021</a><br/>
-Reporter: joshoa<br/>
-Coders: jcolp<br/>
-<br/>
-<h3>Category: Channels/chan_sip/General</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20226">ASTERISK-20226</a>: Segfault in chan_sip while performing connected line update<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376917">376917</a><br/>
-Reporter: jsmith<br/>
-Testers: Jared Smith<br/>
-Coders: mmichelson<br/>
-<br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20486">ASTERISK-20486</a>: MeetMe Unable to write frame to channel after SIP channel hangs up.<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376310">376310</a><br/>
-Reporter: mcargile<br/>
-Coders: jrose<br/>
-<br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20570">ASTERISK-20570</a>: Asterisk, when acting as the UAS in Session Timer negotiation, fails to add required header in 200 response ("Require: timer")<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376550">376550</a><br/>
-Reporter: mjordan<br/>
-Coders: mmichelson<br/>
-<br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20643">ASTERISK-20643</a>: SIP ICE support - remove hardcoded limitation on SDP size, make ICE support disabled by default in SIP, maybe provide a better warning message<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376130">376130</a><br/>
-Reporter: coopvr<br/>
-Coders: jcolp<br/>
-<br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20724">ASTERISK-20724</a>: Fix natdetected flag being set when VIA doesn't include port in address<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376836">376836</a><br/>
-Reporter: elguero<br/>
-Coders: elguero<br/>
-<br/>
-<h3>Category: Channels/chan_sip/SRTP</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20499">ASTERISK-20499</a>: Crash in libsrtp srtp_unprotect_rtcp when SIP channel is bridged with non-optimizing Local channel<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377262">377262</a><br/>
-Reporter: tootai<br/>
-Coders: jrose<br/>
-<br/>
-<h3>Category: Channels/chan_sip/TCP-TLS</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20763">ASTERISK-20763</a>: Memory Leak in chan_sip with TLS enabled clients<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377259">377259</a><br/>
-Reporter: deti<br/>
-Coders: jcolp<br/>
-<br/>
-<h3>Category: Channels/chan_sip/WebSocket</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20745">ASTERISK-20745</a>: In MESSAGE received over WebSocket, the body last char is cut<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376822">376822</a><br/>
-Reporter: ibc<br/>
-Coders: pkiefer<br/>
-<br/>
-<h3>Category: Codecs/codec_dahdi</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-19921">ASTERISK-19921</a>: codec_dahdi: Wrong number of encoder/decoder channels.<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377383">377383</a><br/>
-Reporter: sruffell<br/>
-Coders: kmoore<br/>
-<br/>
-<h3>Category: Contrib/General</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20756">ASTERISK-20756</a>: Asterisk sippeers.sql columns place error cause peer to be without codecs when setting disallow=all under MySQL<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377433">377433</a><br/>
-Reporter: andrel<br/>
-Coders: Andre Luis<br/>
-<br/>
-<h3>Category: Core/Channels</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20492">ASTERISK-20492</a>: Stuck DTMF when using ChannelRedirect to split a two channel bridge<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=375966">375966</a><br/>
-Reporter: jgowdy<br/>
-Testers: rmudgett<br/>
-Coders: Jeremiah Gowdy, rmudgett<br/>
-<br/>
-<h3>Category: Core/ManagerInterface</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20677">ASTERISK-20677</a>: Action Challenge not working with allowmultiplelogin=no<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376727">376727</a><br/>
-Reporter: vldmr<br/>
-Coders: jrose<br/>
-<br/>
-<h3>Category: Core/PBX</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-19205">ASTERISK-19205</a>: Most Unique pattern matching broken when trailing "-" is part of extension<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376690">376690</a><br/>
-Reporter: p_lindheimer<br/>
-Testers: rmudgett<br/>
-Coders: rmudgett<br/>
-<br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20639">ASTERISK-20639</a>: Dynamic hints are not properly initialized when the extension contains an underscore.<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376144">376144</a><br/>
-Reporter: swheeler<br/>
-Testers: Steven T. Wheeler, elguero<br/>
-Coders: elguero<br/>
-<br/>
-<h3>Category: General</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-19463">ASTERISK-19463</a>: Asterisk deadlocks during startup with mutex errors<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376441">376441</a><br/>
-Reporter: mjordan<br/>
-Testers: mjordan<br/>
-Coders: mjordan<br/>
-<br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20226">ASTERISK-20226</a>: Segfault in chan_sip while performing connected line update<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376917">376917</a><br/>
-Reporter: jsmith<br/>
-Testers: Jared Smith<br/>
-Coders: mmichelson<br/>
-<br/>
-<h3>Category: PBX/General</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20628">ASTERISK-20628</a>: [patch] - main/pbx.c - ShowDialPlan generates with error if no Exten: was presented and there are no exten => lines present<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376168">376168</a><br/>
-Reporter: jkroon<br/>
-Coders: jkroon<br/>
-<br/>
-<h3>Category: PBX/pbx_spool</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20593">ASTERISK-20593</a>: [patch] Future-dated call files are ignored when astspooldir is relative<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376234">376234</a><br/>
-Reporter: chewi<br/>
-Coders: James Le Cuirot<br/>
-<br/>
-<h3>Category: Resources/res_monitor</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20641">ASTERISK-20641</a>: Erroneous error messages from Monitor when using options 'i' and 'o'<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376391">376391</a><br/>
-Reporter: jrose<br/>
-Coders: jrose<br/>
-<br/>
-<h3>Category: Tests/testsuite</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-19463">ASTERISK-19463</a>: Asterisk deadlocks during startup with mutex errors<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376441">376441</a><br/>
-Reporter: mjordan<br/>
-Testers: mjordan<br/>
-Coders: mjordan<br/>
-<br/>
-<h3>Category: Utilities/General</h3><br/>
-<a href="https://issues.asterisk.org/jira/browse/ASTERISK-20505">ASTERISK-20505</a>: Migrate hashtest/hashtest2 to be unit tests<br/>
-Revision: <a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376339">376339</a><br/>
-Reporter: mjordan<br/>
-Coders: dlee<br/>
-<br/>
-<hr/>
-<a name="commits"><h2 align="center">Commits Not Associated with an Issue</h2></a>
-<center><a href="#top">[Back to Top]</a></center><br/><p>This is a list of all changes that went into this release that did not directly close an issue from the issue tracker.  The commits may have been marked as being related to an issue.  If that is the case, the issue numbers are listed here, as well.</p>
-<table width="100%" border="1">
-<tr><td><b>Revision</b></td><td><b>Author</b></td><td><b>Summary</b></td><td><b>Issues Referenced</b></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376048">376048</a></td><td>rmudgett</td><td>Add MALLOC_DEBUG enhancements.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376089">376089</a></td><td>mmichelson</td><td>Fix a "set but not used" warning on newer gccs.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376343">376343</a></td><td>dlee</td><td>Fixed extconf.c breakage introduced in r376306.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376415">376415</a></td><td>mjordan</td><td>Add a test event that reports changes in ConfBridge state</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376471">376471</a></td><td>wdoekes</td><td>Fix most leftover non-opaque ast_str uses.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376561">376561</a></td><td>dlee</td><td>Added missing newlines to websocket ast_logs.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376588">376588</a></td><td>mjordan</td><td>Re-initialize logmsgs mutex upon logger initialization to prevent lock errors</td>
-<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-19463">ASTERISK-19463</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376629">376629</a></td><td>rmudgett</td><td>Made AST_LIST_REMOVE() simpler and use better names.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376659">376659</a></td><td>rmudgett</td><td>Remove unnecessary channel module references.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376760">376760</a></td><td>rmudgett</td><td>Enhance MALLOC_DEBUG CLI commands.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376790">376790</a></td><td>rmudgett</td><td>Add MALLOC_DEBUG atexit unreleased malloc memory summary.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376866">376866</a></td><td>rmudgett</td><td>Fix compile error.</td>
-<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-20724">ASTERISK-20724</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376921">376921</a></td><td>seanbright</td><td>Minor spelling fix to the VOLUME documentation.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376952">376952</a></td><td>rmudgett</td><td>chan_misdn: Fix sending RELEASE_COMPLETE in response to SETUP.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=376983">376983</a></td><td>file</td><td>Tweak extension used for incoming calls received on Motif.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377039">377039</a></td><td>rmudgett</td><td>Fix CCSS CLI commands and logger level not unregistered.</td>
-<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-20649">ASTERISK-20649</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377071">377071</a></td><td>rmudgett</td><td>Cleanup CDR resources on exit.</td>
-<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-20649">ASTERISK-20649</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377075">377075</a></td><td>rmudgett</td><td>Cleanup CLI resources on exit and CLI command registration errors.</td>
-<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-20649">ASTERISK-20649</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377106">377106</a></td><td>rmudgett</td><td>Cleanup config cache on exit.</td>
-<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-20649">ASTERISK-20649</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377137">377137</a></td><td>rmudgett</td><td>Cleanup core main on exit.</td>
-<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-20649">ASTERISK-20649</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377167">377167</a></td><td>rmudgett</td><td>Cleanup ast_run_atexits() atexits list.</td>
-<td><a href="https://issues.asterisk.org/jira/browse/ASTERISK-20649">ASTERISK-20649</a></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377195">377195</a></td><td>russell</td><td>Add libuuid to install_prereq for Fedora.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377213">377213</a></td><td>rmudgett</td><td>confbridge: Update online XML documentation.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377244">377244</a></td><td>rmudgett</td><td>Fix registering core show codecs/codec CLI commands twice.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377319">377319</a></td><td>mjordan</td><td>Fix memory leak in 'manager show event' when command entered incorrectly</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377340">377340</a></td><td>russell</td><td>Add CLI tab completion to 'acl show'.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377355">377355</a></td><td>rmudgett</td><td>confbridge: Fix some resource leaks on conference teardown.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377401">377401</a></td><td>rmudgett</td><td>MALLOC_DEBUG: Only wait if we want atexit allocation dumps.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377505">377505</a></td><td>tilghman</td><td>Remove some dead code and additionally handle a case that wasn't handled.</td>
-<td></td></tr><tr><td><a href="http://svn.digium.com/view/asterisk/branches/11?view=revision&revision=377511">377511</a></td><td>tilghman</td><td>Improve documentation by making all of the colors used readable,</td>
-<td></td></tr></table>
-<hr/>
-<a name="diffstat"><h2 align="center">Diffstat Results</h2></a>
-<center><a href="#top">[Back to Top]</a></center><br/><p>This is a summary of the changes to the source code that went into this release that was generated using the diffstat utility.</p>
-<pre>
-UPGRADE.txt                          |    6
-addons/cdr_mysql.c                   |   11
-addons/res_config_mysql.c            |    3
-apps/app_celgenuserevent.c           |    9
-apps/app_confbridge.c                |  148 ++--
-apps/app_dial.c                      |   14
-apps/app_jack.c                      |    4
-apps/app_meetme.c                    |   15
-apps/app_queue.c                     |   26
-apps/app_record.c                    |   27
-apps/app_voicemail.c                 |    2
-apps/app_waitforring.c               |   25
-apps/confbridge/conf_config_parser.c |  126 ++-
-apps/confbridge/conf_state.c         |    5
-channels/chan_agent.c                |   14
-channels/chan_dahdi.c                |   42 -
-channels/chan_iax2.c                 |   14
-channels/chan_local.c                |   21
-channels/chan_motif.c                |   27
-channels/chan_sip.c                  |  208 +++--
-channels/misdn/isdn_lib.c            |   17
-channels/sig_analog.c                |   22
-channels/sig_pri.c                   |   12
-channels/sig_ss7.c                   |   51 -
-channels/sip/include/sip.h           |    1
-codecs/codec_dahdi.c                 |    2
-configs/motif.conf.sample            |    5
-configs/sip.conf.sample              |    5
-contrib/realtime/mysql/sippeers.sql  |    2
-contrib/scripts/install_prereq       |    2
-funcs/func_volume.c                  |    2
-include/asterisk/_private.h          |    1
-include/asterisk/astmm.h             |    3
-include/asterisk/channel.h           |    8
-include/asterisk/features.h          |   12
-include/asterisk/hashtab.h           |    3
-include/asterisk/linkedlists.h       |   58 -
-include/asterisk/lock.h              |   16
-include/asterisk/time.h              |   14
-include/asterisk/utils.h             |   29
-main/asterisk.c                      |  352 ++++++----
-main/astmm.c                         | 1223 ++++++++++++++++++++++++++++++-----
-main/ccss.c                          |    2
-main/cdr.c                           |   46 -
-main/channel.c                       |  150 +++-
-main/channel_internal_api.c          |   21
-main/cli.c                           |   41 +
-main/config.c                        |   14
-main/features.c                      |   27
-main/format.c                        |    6
-main/indications.c                   |    2
-main/lock.c                          |    2
-main/logger.c                        |   11
-main/manager.c                       |    7
-main/named_acl.c                     |   25
-main/pbx.c                           |  532 +++++++++++----
-main/rtp_engine.c                    |   16
-main/security_events.c               |    2
-main/stdtime/localtime.c             |   14
-main/utils.c                         |   69 +
-main/xmldoc.c                        |    8
-pbx/pbx_dundi.c                      |   31
-pbx/pbx_spool.c                      |    2
-res/res_fax.c                        |  128 ++-
-res/res_http_websocket.c             |   12
-res/res_monitor.c                    |   32
-res/res_rtp_asterisk.c               |    2
-res/res_srtp.c                       |    4
-tests/test_astobj2_thrash.c          |  353 ++++++++++
-tests/test_hashtab_thrash.c          |  321 +++++++++
-utils/Makefile                       |    7
-utils/extconf.c                      |    1
-utils/hashtest.c                     |  410 -----------
-utils/hashtest2.c                    |  418 -----------
-utils/utils.xml                      |    8
-75 files changed, 3469 insertions(+), 1842 deletions(-)
-</pre><br/>
-<hr/>
-</body>
-</html>
diff --git a/asterisk-11.2.0-rc1-summary.txt b/asterisk-11.2.0-rc1-summary.txt
deleted file mode 100644 (file)
index f51f5dd..0000000
+++ /dev/null
@@ -1,526 +0,0 @@
-                                Release Summary
-
-                              asterisk-11.2.0-rc1
-
-                                Date: 2012-12-09
-
-                           <asteriskteam@digium.com>
-
-     ----------------------------------------------------------------------
-
-                               Table of Contents
-
-    1. Summary
-    2. Contributors
-    3. Closed Issues
-    4. Other Changes
-    5. Diffstat
-
-     ----------------------------------------------------------------------
-
-                                    Summary
-
-                                 [Back to Top]
-
-   This release includes only bug fixes. The changes included were made only
-   to address problems that have been identified in this release series.
-   Users should be able to safely upgrade to this version if this release
-   series is already in use. Users considering upgrading from a previous
-   release series are strongly encouraged to review the UPGRADE.txt document
-   as well as the CHANGES document for information about upgrading to this
-   release series.
-
-   The data in this summary reflects changes that have been made since the
-   previous release, asterisk-11.1.0.
-
-     ----------------------------------------------------------------------
-
-                                  Contributors
-
-                                 [Back to Top]
-
-   This table lists the people who have submitted code, those that have
-   tested patches, as well as those that reported issues on the issue tracker
-   that were resolved in this release. For coders, the number is how many of
-   their patches (of any size) were committed into this release. For testers,
-   the number is the number of times their name was listed as assisting with
-   testing a patch. Finally, for reporters, the number is the number of
-   issues that they reported that were closed by commits that went into this
-   release.
-
-     Coders                   Testers                  Reporters              
-   22 rmudgett              3 rmudgett               4 mjordan                
-   4 jcolp                  1 alecdavis              1 alecdavis              
-   4 jrose                  1 elguero                1 andrel                 
-   4 mjordan                1 Jared Smith            1 chewi                  
-   4 mmichelson             1 mjordan                1 coopvr                 
-   3 dlee                   1 Rusty Newton           1 deti                   
-   2 elguero                1 Steven T. Wheeler      1 dlee                   
-   2 russell                                         1 eabad                  
-   2 tilghman                                        1 elguero                
-   1 alecdavis                                       1 ibc                    
-   1 Andre Luis                                      1 jgowdy                 
-   1 beagles                                         1 jkroon                 
-   1 file                                            1 joshoa                 
-   1 James Le Cuirot                                 1 jrose                  
-   1 Jeremiah Gowdy                                  1 jsmith                 
-   1 jkroon                                          1 mcargile               
-   1 kmoore                                          1 p_lindheimer           
-   1 pkiefer                                         1 rmudgett               
-   1 Rusty Newton                                    1 sruffell               
-   1 seanbright                                      1 supertle               
-   1 wdoekes                                         1 swheeler               
-                                                     1 tomo1657               
-                                                     1 tootai                 
-                                                     1 vldmr                  
-                                                     1 wimpy                  
-
-     ----------------------------------------------------------------------
-
-                                 Closed Issues
-
-                                 [Back to Top]
-
-   This is a list of all issues from the issue tracker that were closed by
-   changes that went into this release.
-
-  Category: Applications/app_confbridge
-
-   ASTERISK-20655: Cannot reset pin with CONFBRIDGE(user,pin)
-   Revision: 377228
-   Reporter: wimpy
-   Coders: rmudgett
-
-  Category: Applications/app_meetme
-
-   ASTERISK-20486: MeetMe Unable to write frame to channel after SIP channel
-   hangs up.
-   Revision: 376310
-   Reporter: mcargile
-   Coders: jrose
-
-  Category: Applications/app_queue
-
-   ASTERISK-19918: MoH (Music on Hold) is stopped after call in a queue is
-   terminated
-   Revision: 376217
-   Reporter: eabad
-   Coders: beagles
-
-  Category: Applications/app_voicemail
-
-   ASTERISK-20280: In app_voicemail we attempt to play the sound
-   "vm-urgent-removed", which should be "vm-marked-nonurgent"
-   Revision: 376264
-   Reporter: tomo1657
-   Testers: Rusty Newton
-   Coders: Rusty Newton
-
-  Category: Channels/General
-
-   ASTERISK-20414: Timeout antipattern using ast_waitfor_nandfds
-   Revision: 376014
-   Reporter: dlee
-   Coders: mmichelson
-
-  Category: Channels/chan_bridge
-
-   ASTERISK-20492: Stuck DTMF when using ChannelRedirect to split a two
-   channel bridge
-   Revision: 375966
-   Reporter: jgowdy
-   Testers: rmudgett
-   Coders: Jeremiah Gowdy, rmudgett
-
-  Category: Channels/chan_dahdi/SS7
-
-   ASTERISK-20204: Asterisk not rejecting call setup on CIC that is down
-   Revision: 376060
-   Reporter: supertle
-   Coders: rmudgett
-
-  Category: Channels/chan_local
-
-   ASTERISK-20769: Memory leak of local_pvt in chan_local.
-   Revision: 376870
-   Reporter: rmudgett
-   Testers: rmudgett
-   Coders: rmudgett
-
-  Category: Channels/chan_motif
-
-   ASTERISK-20671: Add Who Hung Up support to the Motif channel driver
-   Revision: 377462
-   Reporter: mjordan
-   Coders: jcolp
-
-   ASTERISK-20751: chan_motif leaves UDP ports open
-   Revision: 377021
-   Reporter: joshoa
-   Coders: jcolp
-
-  Category: Channels/chan_sip/General
-
-   ASTERISK-20226: Segfault in chan_sip while performing connected line
-   update
-   Revision: 376917
-   Reporter: jsmith
-   Testers: Jared Smith
-   Coders: mmichelson
-
-   ASTERISK-20486: MeetMe Unable to write frame to channel after SIP channel
-   hangs up.
-   Revision: 376310
-   Reporter: mcargile
-   Coders: jrose
-
-   ASTERISK-20570: Asterisk, when acting as the UAS in Session Timer
-   negotiation, fails to add required header in 200 response ("Require:
-   timer")
-   Revision: 376550
-   Reporter: mjordan
-   Coders: mmichelson
-
-   ASTERISK-20643: SIP ICE support - remove hardcoded limitation on SDP size,
-   make ICE support disabled by default in SIP, maybe provide a better
-   warning message
-   Revision: 376130
-   Reporter: coopvr
-   Coders: jcolp
-
-   ASTERISK-20724: Fix natdetected flag being set when VIA doesn't include
-   port in address
-   Revision: 376836
-   Reporter: elguero
-   Coders: elguero
-
-  Category: Channels/chan_sip/SRTP
-
-   ASTERISK-20499: Crash in libsrtp srtp_unprotect_rtcp when SIP channel is
-   bridged with non-optimizing Local channel
-   Revision: 377262
-   Reporter: tootai
-   Coders: jrose
-
-  Category: Channels/chan_sip/TCP-TLS
-
-   ASTERISK-20763: Memory Leak in chan_sip with TLS enabled clients
-   Revision: 377259
-   Reporter: deti
-   Coders: jcolp
-
-  Category: Channels/chan_sip/WebSocket
-
-   ASTERISK-20745: In MESSAGE received over WebSocket, the body last char is
-   cut
-   Revision: 376822
-   Reporter: ibc
-   Coders: pkiefer
-
-  Category: Codecs/codec_dahdi
-
-   ASTERISK-19921: codec_dahdi: Wrong number of encoder/decoder channels.
-   Revision: 377383
-   Reporter: sruffell
-   Coders: kmoore
-
-  Category: Contrib/General
-
-   ASTERISK-20756: Asterisk sippeers.sql columns place error cause peer to be
-   without codecs when setting disallow=all under MySQL
-   Revision: 377433
-   Reporter: andrel
-   Coders: Andre Luis
-
-  Category: Core/Channels
-
-   ASTERISK-20492: Stuck DTMF when using ChannelRedirect to split a two
-   channel bridge
-   Revision: 375966
-   Reporter: jgowdy
-   Testers: rmudgett
-   Coders: Jeremiah Gowdy, rmudgett
-
-  Category: Core/ManagerInterface
-
-   ASTERISK-20677: Action Challenge not working with allowmultiplelogin=no
-   Revision: 376727
-   Reporter: vldmr
-   Coders: jrose
-
-  Category: Core/PBX
-
-   ASTERISK-19205: Most Unique pattern matching broken when trailing "-" is
-   part of extension
-   Revision: 376690
-   Reporter: p_lindheimer
-   Testers: rmudgett
-   Coders: rmudgett
-
-   ASTERISK-20639: Dynamic hints are not properly initialized when the
-   extension contains an underscore.
-   Revision: 376144
-   Reporter: swheeler
-   Testers: Steven T. Wheeler, elguero
-   Coders: elguero
-
-  Category: General
-
-   ASTERISK-19463: Asterisk deadlocks during startup with mutex errors
-   Revision: 376441
-   Reporter: mjordan
-   Testers: mjordan
-   Coders: mjordan
-
-   ASTERISK-20226: Segfault in chan_sip while performing connected line
-   update
-   Revision: 376917
-   Reporter: jsmith
-   Testers: Jared Smith
-   Coders: mmichelson
-
-  Category: PBX/General
-
-   ASTERISK-20628: [patch] - main/pbx.c - ShowDialPlan generates with error
-   if no Exten: was presented and there are no exten => lines present
-   Revision: 376168
-   Reporter: jkroon
-   Coders: jkroon
-
-  Category: PBX/pbx_spool
-
-   ASTERISK-20593: [patch] Future-dated call files are ignored when
-   astspooldir is relative
-   Revision: 376234
-   Reporter: chewi
-   Coders: James Le Cuirot
-
-  Category: Resources/res_monitor
-
-   ASTERISK-20641: Erroneous error messages from Monitor when using options
-   'i' and 'o'
-   Revision: 376391
-   Reporter: jrose
-   Coders: jrose
-
-  Category: Tests/testsuite
-
-   ASTERISK-19463: Asterisk deadlocks during startup with mutex errors
-   Revision: 376441
-   Reporter: mjordan
-   Testers: mjordan
-   Coders: mjordan
-
-  Category: Utilities/General
-
-   ASTERISK-20505: Migrate hashtest/hashtest2 to be unit tests
-   Revision: 376339
-   Reporter: mjordan
-   Coders: dlee
-
-     ----------------------------------------------------------------------
-
-                      Commits Not Associated with an Issue
-
-                                 [Back to Top]
-
-   This is a list of all changes that went into this release that did not
-   directly close an issue from the issue tracker. The commits may have been
-   marked as being related to an issue. If that is the case, the issue
-   numbers are listed here, as well.
-
-   +------------------------------------------------------------------------+
-   | Revision | Author     | Summary                    | Issues Referenced |
-   |----------+------------+----------------------------+-------------------|
-   | 376048   | rmudgett   | Add MALLOC_DEBUG           |                   |
-   |          |            | enhancements.              |                   |
-   |----------+------------+----------------------------+-------------------|
-   | 376089   | mmichelson | Fix a "set but not used"   |                   |
-   |          |            | warning on newer gccs.     |                   |
-   |----------+------------+----------------------------+-------------------|
-   | 376343   | dlee       | Fixed extconf.c breakage   |                   |
-   |          |            | introduced in r376306.     |                   |
-   |----------+------------+----------------------------+-------------------|
-   |          |            | Add a test event that      |                   |
-   | 376415   | mjordan    | reports changes in         |                   |
-   |          |            | ConfBridge state           |                   |
-   |----------+------------+----------------------------+-------------------|
-   | 376471   | wdoekes    | Fix most leftover          |                   |
-   |          |            | non-opaque ast_str uses.   |                   |
-   |----------+------------+----------------------------+-------------------|
-   | 376561   | dlee       | Added missing newlines to  |                   |
-   |          |            | websocket ast_logs.        |                   |
-   |----------+------------+----------------------------+-------------------|
-   |          |            | Re-initialize logmsgs      |                   |
-   | 376588   | mjordan    | mutex upon logger          | ASTERISK-19463    |
-   |          |            | initialization to prevent  |                   |
-   |          |            | lock errors                |                   |
-   |----------+------------+----------------------------+-------------------|
-   |          |            | Made AST_LIST_REMOVE()     |                   |
-   | 376629   | rmudgett   | simpler and use better     |                   |
-   |          |            | names.                     |                   |
-   |----------+------------+----------------------------+-------------------|
-   | 376659   | rmudgett   | Remove unnecessary channel |                   |
-   |          |            | module references.         |                   |
-   |----------+------------+----------------------------+-------------------|
-   | 376760   | rmudgett   | Enhance MALLOC_DEBUG CLI   |                   |
-   |          |            | commands.                  |                   |
-   |----------+------------+----------------------------+-------------------|
-   |          |            | Add MALLOC_DEBUG atexit    |                   |
-   | 376790   | rmudgett   | unreleased malloc memory   |                   |
-   |          |            | summary.                   |                   |
-   |----------+------------+----------------------------+-------------------|
-   | 376866   | rmudgett   | Fix compile error.         | ASTERISK-20724    |
-   |----------+------------+----------------------------+-------------------|
-   | 376921   | seanbright | Minor spelling fix to the  |                   |
-   |          |            | VOLUME documentation.      |                   |
-   |----------+------------+----------------------------+-------------------|
-   |          |            | chan_misdn: Fix sending    |                   |
-   | 376952   | rmudgett   | RELEASE_COMPLETE in        |                   |
-   |          |            | response to SETUP.         |                   |
-   |----------+------------+----------------------------+-------------------|
-   |          |            | Tweak extension used for   |                   |
-   | 376983   | file       | incoming calls received on |                   |
-   |          |            | Motif.                     |                   |
-   |----------+------------+----------------------------+-------------------|
-   |          |            | Fix CCSS CLI commands and  |                   |
-   | 377039   | rmudgett   | logger level not           | ASTERISK-20649    |
-   |          |            | unregistered.              |                   |
-   |----------+------------+----------------------------+-------------------|
-   | 377071   | rmudgett   | Cleanup CDR resources on   | ASTERISK-20649    |
-   |          |            | exit.                      |                   |
-   |----------+------------+----------------------------+-------------------|
-   |          |            | Cleanup CLI resources on   |                   |
-   | 377075   | rmudgett   | exit and CLI command       | ASTERISK-20649    |
-   |          |            | registration errors.       |                   |
-   |----------+------------+----------------------------+-------------------|
-   | 377106   | rmudgett   | Cleanup config cache on    | ASTERISK-20649    |
-   |          |            | exit.                      |                   |
-   |----------+------------+----------------------------+-------------------|
-   | 377137   | rmudgett   | Cleanup core main on exit. | ASTERISK-20649    |
-   |----------+------------+----------------------------+-------------------|
-   | 377167   | rmudgett   | Cleanup ast_run_atexits()  | ASTERISK-20649    |
-   |          |            | atexits list.              |                   |
-   |----------+------------+----------------------------+-------------------|
-   | 377195   | russell    | Add libuuid to             |                   |
-   |          |            | install_prereq for Fedora. |                   |
-   |----------+------------+----------------------------+-------------------|
-   | 377213   | rmudgett   | confbridge: Update online  |                   |
-   |          |            | XML documentation.         |                   |
-   |----------+------------+----------------------------+-------------------|
-   |          |            | Fix registering core show  |                   |
-   | 377244   | rmudgett   | codecs/codec CLI commands  |                   |
-   |          |            | twice.                     |                   |
-   |----------+------------+----------------------------+-------------------|
-   |          |            | Fix memory leak in         |                   |
-   | 377319   | mjordan    | 'manager show event' when  |                   |
-   |          |            | command entered            |                   |
-   |          |            | incorrectly                |                   |
-   |----------+------------+----------------------------+-------------------|
-   | 377340   | russell    | Add CLI tab completion to  |                   |
-   |          |            | 'acl show'.                |                   |
-   |----------+------------+----------------------------+-------------------|
-   |          |            | confbridge: Fix some       |                   |
-   | 377355   | rmudgett   | resource leaks on          |                   |
-   |          |            | conference teardown.       |                   |
-   |----------+------------+----------------------------+-------------------|
-   |          |            | MALLOC_DEBUG: Only wait if |                   |
-   | 377401   | rmudgett   | we want atexit allocation  |                   |
-   |          |            | dumps.                     |                   |
-   |----------+------------+----------------------------+-------------------|
-   |          |            | Remove some dead code and  |                   |
-   | 377505   | tilghman   | additionally handle a case |                   |
-   |          |            | that wasn't handled.       |                   |
-   |----------+------------+----------------------------+-------------------|
-   |          |            | Improve documentation by   |                   |
-   | 377511   | tilghman   | making all of the colors   |                   |
-   |          |            | used readable,             |                   |
-   +------------------------------------------------------------------------+
-
-     ----------------------------------------------------------------------
-
-                                Diffstat Results
-
-                                 [Back to Top]
-
-   This is a summary of the changes to the source code that went into this
-   release that was generated using the diffstat utility.
-
- UPGRADE.txt                          |    6
- addons/cdr_mysql.c                   |   11
- addons/res_config_mysql.c            |    3
- apps/app_celgenuserevent.c           |    9
- apps/app_confbridge.c                |  148 ++--
- apps/app_dial.c                      |   14
- apps/app_jack.c                      |    4
- apps/app_meetme.c                    |   15
- apps/app_queue.c                     |   26
- apps/app_record.c                    |   27
- apps/app_voicemail.c                 |    2
- apps/app_waitforring.c               |   25
- apps/confbridge/conf_config_parser.c |  126 ++-
- apps/confbridge/conf_state.c         |    5
- channels/chan_agent.c                |   14
- channels/chan_dahdi.c                |   42 -
- channels/chan_iax2.c                 |   14
- channels/chan_local.c                |   21
- channels/chan_motif.c                |   27
- channels/chan_sip.c                  |  208 +++--
- channels/misdn/isdn_lib.c            |   17
- channels/sig_analog.c                |   22
- channels/sig_pri.c                   |   12
- channels/sig_ss7.c                   |   51 -
- channels/sip/include/sip.h           |    1
- codecs/codec_dahdi.c                 |    2
- configs/motif.conf.sample            |    5
- configs/sip.conf.sample              |    5
- contrib/realtime/mysql/sippeers.sql  |    2
- contrib/scripts/install_prereq       |    2
- funcs/func_volume.c                  |    2
- include/asterisk/_private.h          |    1
- include/asterisk/astmm.h             |    3
- include/asterisk/channel.h           |    8
- include/asterisk/features.h          |   12
- include/asterisk/hashtab.h           |    3
- include/asterisk/linkedlists.h       |   58 -
- include/asterisk/lock.h              |   16
- include/asterisk/time.h              |   14
- include/asterisk/utils.h             |   29
- main/asterisk.c                      |  352 ++++++----
- main/astmm.c                         | 1223 ++++++++++++++++++++++++++++++-----
- main/ccss.c                          |    2
- main/cdr.c                           |   46 -
- main/channel.c                       |  150 +++-
- main/channel_internal_api.c          |   21
- main/cli.c                           |   41 +
- main/config.c                        |   14
- main/features.c                      |   27
- main/format.c                        |    6
- main/indications.c                   |    2
- main/lock.c                          |    2
- main/logger.c                        |   11
- main/manager.c                       |    7
- main/named_acl.c                     |   25
- main/pbx.c                           |  532 +++++++++++----
- main/rtp_engine.c                    |   16
- main/security_events.c               |    2
- main/stdtime/localtime.c             |   14
- main/utils.c                         |   69 +
- main/xmldoc.c                        |    8
- pbx/pbx_dundi.c                      |   31
- pbx/pbx_spool.c                      |    2
- res/res_fax.c                        |  128 ++-
- res/res_http_websocket.c             |   12
- res/res_monitor.c                    |   32
- res/res_rtp_asterisk.c               |    2
- res/res_srtp.c                       |    4
- tests/test_astobj2_thrash.c          |  353 ++++++++++
- tests/test_hashtab_thrash.c          |  321 +++++++++
- utils/Makefile                       |    7
- utils/extconf.c                      |    1
- utils/hashtest.c                     |  410 -----------
- utils/hashtest2.c                    |  418 -----------
- utils/utils.xml                      |    8
- 75 files changed, 3469 insertions(+), 1842 deletions(-)
-
-     ----------------------------------------------------------------------
index 81cf8d56783aeef55dd8b9925b5dc3cdab537a40..fbd3ec0603422a89dc1a28a08182a5a1f801c18e 100644 (file)
@@ -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) {
@@ -2166,7 +2166,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) {
@@ -2187,7 +2187,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 {
@@ -2258,7 +2258,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);
index 390f8b2a22f80a8cf92f8a754740d24be0b51b1e..c60379795e425f264605acee5ea211ff54245158 100644 (file)
@@ -3438,7 +3438,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. */
@@ -3454,7 +3454,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) */
 }
@@ -10010,7 +10010,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);
index 80041336f46d97f68e3f07294f1f5760cfaf4be3..38274de7d657dd17b6c15e19bd6bc08a9ec60e89 100644 (file)
@@ -5798,7 +5798,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;
@@ -5880,6 +5880,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)
@@ -8161,7 +8165,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;
@@ -8715,7 +8719,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);
 
@@ -8770,7 +8774,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) {
@@ -8847,14 +8851,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 */
@@ -10420,7 +10424,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;
@@ -11062,13 +11067,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;
@@ -11312,7 +11317,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;
@@ -11383,7 +11388,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;
@@ -12150,7 +12155,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]);
@@ -12324,7 +12329,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) {
index da86e14733dcc13ddbf8fe3ed977d8b878a11112..ec19cd71b9270832b0d93cf8858db61d5cc70838 100644 (file)
@@ -1266,6 +1266,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;
        p->u_owner = ast_module_user_add(p->owner);
index 37b4c7ba17b7198b3c5535bcaec0df989acd4556..5207c51e274a5327ddb0732aebbc0fe596633562 100644 (file)
@@ -2667,19 +2667,20 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str
                        int authenticated, time_t start, struct sip_threadinfo *me)
 {
        int res, content_length, after_poll = 1, need_poll = 1;
+       size_t datalen = ast_str_strlen(req->data);
        char buf[1024] = "";
        int timeout = -1;
-
-       /* Read in headers one line at a time */
-       while (ast_str_strlen(req->data) < 4 || strncmp(REQ_OFFSET_TO_STR(req, data->used - 4), "\r\n\r\n", 4)) {
-               if (!tcptls_session->client && !authenticated) {
-                       if ((timeout = sip_check_authtimeout(start)) < 0) {
-                               ast_debug(2, "SIP SSL server failed to determine authentication timeout\n");
+       /* Read in headers one line at a time */
+       while (datalen < 4 || strncmp(REQ_OFFSET_TO_STR(req, data->used - 4), "\r\n\r\n", 4)) {
+               if (!tcptls_session->client && !authenticated) {
+                       if ((timeout = sip_check_authtimeout(start)) < 0) {
+                               ast_debug(2, "SIP TLS server failed to determine authentication timeout\n");
                                return -1;
                        }
 
                        if (timeout == 0) {
-                               ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
+                               ast_debug(2, "SIP TLS server timed out\n");
                                return -1;
                        }
                } else {
@@ -2694,11 +2695,11 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str
                        after_poll = 1;
                        res = ast_wait_for_input(tcptls_session->fd, timeout);
                        if (res < 0) {
-                               ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res);
+                               ast_debug(2, "SIP TLS server :: ast_wait_for_input returned %d\n", res);
                                return -1;
                        } else if (res == 0) {
                                /* timeout */
-                               ast_debug(2, "SIP TCP server timed out\n");
+                               ast_debug(2, "SIP TLS server timed out\n");
                                return -1;
                        }
                }
@@ -2719,6 +2720,13 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str
                        return -1;
                }
                ast_str_append(&req->data, 0, "%s", buf);
+
+               datalen = ast_str_strlen(req->data);
+               if (datalen > SIP_MAX_PACKET_SIZE) {
+                       ast_log(LOG_WARNING, "Rejecting TLS packet from '%s' because way too large: %zu\n",
+                               ast_sockaddr_stringify(&tcptls_session->remote_address), datalen);
+                       return -1;
+               }
        }
        copy_request(reqcpy, req);
        parse_request(reqcpy);
@@ -2732,7 +2740,7 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str
                                }
 
                                if (timeout == 0) {
-                                       ast_debug(2, "SIP SSL server timed out\n");
+                                       ast_debug(2, "SIP TLS server timed out\n");
                                        return -1;
                                }
                        } else {
@@ -2744,11 +2752,11 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str
                                after_poll = 1;
                                res = ast_wait_for_input(tcptls_session->fd, timeout);
                                if (res < 0) {
-                                       ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res);
+                                       ast_debug(2, "SIP TLS server :: ast_wait_for_input returned %d\n", res);
                                        return -1;
                                } else if (res == 0) {
                                        /* timeout */
-                                       ast_debug(2, "SIP TCP server timed out\n");
+                                       ast_debug(2, "SIP TLS server timed out\n");
                                        return -1;
                                }
                        }
@@ -2771,6 +2779,13 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str
                        }
                        content_length -= strlen(buf);
                        ast_str_append(&req->data, 0, "%s", buf);
+               
+                       datalen = ast_str_strlen(req->data);
+                       if (datalen > SIP_MAX_PACKET_SIZE) {
+                               ast_log(LOG_WARNING, "Rejecting TLS packet from '%s' because way too large: %zu\n",
+                                       ast_sockaddr_stringify(&tcptls_session->remote_address), datalen);
+                               return -1;
+                       }
                }
        }
        /*! \todo XXX If there's no Content-Length or if the content-length and what
@@ -2944,6 +2959,8 @@ static int sip_tcp_read(struct sip_request *req, struct ast_tcptls_session_insta
        enum message_integrity message_integrity = MESSAGE_FRAGMENT;
 
        while (message_integrity == MESSAGE_FRAGMENT) {
+               size_t datalen;
+
                if (ast_str_strlen(tcptls_session->overflow_buf) == 0) {
                        char readbuf[4097];
                        int timeout;
@@ -2983,6 +3000,13 @@ static int sip_tcp_read(struct sip_request *req, struct ast_tcptls_session_insta
                        ast_str_append(&req->data, 0, "%s", ast_str_buffer(tcptls_session->overflow_buf));
                        ast_str_reset(tcptls_session->overflow_buf);
                }
+               
+               datalen = ast_str_strlen(req->data);
+               if (datalen > SIP_MAX_PACKET_SIZE) {
+                       ast_log(LOG_WARNING, "Rejecting TCP packet from '%s' because way too large: %zu\n",
+                               ast_sockaddr_stringify(&tcptls_session->remote_address), datalen);
+                       return -1;
+               }
 
                message_integrity = check_message_integrity(&req->data, &tcptls_session->overflow_buf);
        }
@@ -3054,7 +3078,7 @@ static void *_sip_tcp_helper_thread(struct ast_tcptls_session_instance *tcptls_s
        }
 
        me->threadid = pthread_self();
-       ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP");
+       ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "TLS" : "TCP");
 
        /* set up pollfd to watch for reads on both the socket and the alert_pipe */
        fds[0].fd = tcptls_session->fd;
@@ -3088,7 +3112,7 @@ static void *_sip_tcp_helper_thread(struct ast_tcptls_session_instance *tcptls_s
                        }
 
                        if (timeout == 0) {
-                               ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
+                               ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "TLS": "TCP");
                                goto cleanup;
                        }
                } else {
@@ -3098,11 +3122,11 @@ static void *_sip_tcp_helper_thread(struct ast_tcptls_session_instance *tcptls_s
                if (ast_str_strlen(tcptls_session->overflow_buf) == 0) {
                        res = ast_poll(fds, 2, timeout); /* polls for both socket and alert_pipe */
                        if (res < 0) {
-                               ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res);
+                               ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "TLS": "TCP", res);
                                goto cleanup;
                        } else if (res == 0) {
                                /* timeout */
-                               ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
+                               ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "TLS": "TCP");
                                goto cleanup;
                        }
                }
@@ -3184,7 +3208,7 @@ static void *_sip_tcp_helper_thread(struct ast_tcptls_session_instance *tcptls_s
                }
        }
 
-       ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP");
+       ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "TLS" : "TCP");
 
 cleanup:
        if (tcptls_session && !tcptls_session->client && !authenticated) {
@@ -6771,7 +6795,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;
@@ -8032,6 +8056,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];
@@ -15540,7 +15567,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
@@ -16325,8 +16352,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;
 }
 
@@ -16849,7 +16877,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) {
@@ -23219,7 +23247,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);
                }
@@ -29113,7 +29141,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 */
index 2997ac834ec69d2313788582f450e2b76e8c7f6e..0332235b821f6776939d1a89c878a2bde2085484 100644 (file)
@@ -2133,7 +2133,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;
@@ -2168,7 +2168,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);
                        }
                }
        }
@@ -5935,7 +5935,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;
 }
@@ -5975,7 +5975,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;
@@ -6042,7 +6042,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);
 
@@ -6378,7 +6378,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:
@@ -6532,8 +6532,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 */
index 7f907c6e5ed805741d3693dd3199417bcda48221..17841096ca22c5ca8dcec36246c4e4a96285b8ac 100644 (file)
 
 #define SIP_MAX_HEADERS           64     /*!< Max amount of SIP headers to read */
 #define SIP_MAX_LINES             256    /*!< Max amount of lines in SIP attachment (like SDP) */
+#define SIP_MAX_PACKET_SIZE       20480  /*!< Max SIP packet size */
 #define SIP_MIN_PACKET            4096   /*!< Initialize size of memory to allocate for packets */
 #define MAX_HISTORY_ENTRIES              50     /*!< Max entires in the history list for a sip_pvt */
 
index c9e5e21a470816c654ca45dacee3d58a15983375..f7c05181c0fdcbaf60fd78f5ea6b0bea0cac5c10 100644 (file)
@@ -71,13 +71,6 @@ monitor-type = MixMonitor
 ;
 ;log_membername_as_agent = no
 ;
-; app_queue allows calls to members in a "Unknown" state to be treated as available
-; setting check_state_unknown = yes will cause app_queue to query the channel driver
-; to better determine the state this only applies to queues with ringinuse set
-; appropriately.
-;
-;check_state_unknown = no
-;
 ;[markq]
 ;
 ; A sample call queue
index e1f34387a116f8d87d2217a5d67edc271a3175dc..6472610c8a70a0b2bfdd5451af2ada658f052d9e 100644 (file)
@@ -132,7 +132,7 @@ static int devstate_write(struct ast_channel *chan, const char *cmd, char *data,
 
        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 @@ static char *handle_cli_devstate_change(struct ast_cli_entry *e, int cmd, struct
 
        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 @@ static int load_module(void)
                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;
index 40dbf4381ce23c39217ad1f514bcd2c5912870b6..e2661870cfb2548eb10d7f6ec8a61abd6c7e6494 100644 (file)
@@ -888,6 +888,12 @@ enum {
         *  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 */
index 66ca2bd1a3ecddb1fd4d0ac44741cc1aa26e43dd..86740bc2fd69b735906d1e9d71adcd4798924d66 100644 (file)
@@ -61,6 +61,14 @@ enum ast_device_state {
        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 @@ enum ast_device_state ast_device_state(const char *device);
  * \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 @@ enum ast_device_state ast_device_state(const char *device);
  * \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 @@ int ast_devstate_changed(enum ast_device_state state, const char *fmt, ...)
  * \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.
index d3514f59c76a3008af983ea45c5be3957e90d182..10c76d0da0cc66dd975b125116d03ec5a2726bd8 100644 (file)
@@ -298,8 +298,14 @@ enum ast_event_ie_type {
        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,
 };
 
 /*!
index 47891b8ef25967cb33a5ddb54fa6bcf8e9d8a13c..b1585312ef91d2c276adf9c82deb69bd8e65424e 100644 (file)
@@ -638,7 +638,7 @@ static void ccss_notify_device_state_change(const char *device, enum cc_state st
                "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 */
index ec338e7b9d3f35456071a1acada485dbd1878864..da8452003bb8ec755c37d929718556d8f5ea0262 100644 (file)
@@ -2431,7 +2431,7 @@ static void ast_channel_destructor(void *obj)
                 * 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)));
@@ -7348,7 +7348,7 @@ int ast_setstate(struct ast_channel *chan, enum ast_channel_state state)
        /* 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
index c7ed84c349ba0fca84b69e96242e626a824acb16..3f892ddef54aaa845b283b2a696c24153d975b50 100644 (file)
@@ -263,6 +263,7 @@ static void channel_data_add_flags(struct ast_data *tree,
        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,
index 3256a7b4f9a074fcac9c6378a56af6f385590747..4ed51f9e3943a12f8bc4f69290c69bdf50b45a01 100644 (file)
@@ -174,6 +174,7 @@ static AST_RWLIST_HEAD_STATIC(devstate_provs, devstate_prov);
 
 struct state_change {
        AST_LIST_ENTRY(state_change) list;
+       enum ast_devstate_cache cachable;
        char device[1];
 };
 
@@ -191,6 +192,7 @@ struct devstate_change {
        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 @@ static int getproviderstate(const char *provider, const char *address)
        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 @@ static void devstate_event(const char *device, enum ast_device_state state)
        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 @@ static void do_state_change(const char *device)
 
        ast_debug(3, "Changing state for %s - state %d (%s)\n", device, state, ast_devstate2str(state));
 
-       devstate_event(device, state);
+       devstate_event(device, state, cachable);
 }
 
-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)
 {
        struct state_change *change;
 
@@ -483,14 +490,15 @@ int ast_devstate_changed_literal(enum ast_device_state state, const char *device
         */
 
        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_devstate_changed_literal(enum ast_device_state state, const char *device
 
 int ast_device_state_changed_literal(const char *dev)
 {
-       return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, dev);
+       return ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, dev);
 }
 
-int ast_devstate_changed(enum ast_device_state state, const char *fmt, ...)
+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 @@ int ast_devstate_changed(enum ast_device_state state, const char *fmt, ...)
        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 @@ int ast_device_state_changed(const char *fmt, ...)
        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 @@ static void *do_devstate_changes(void *data)
                /* 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 @@ static void devstate_cache_cb(const struct ast_event *event, void *data)
        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;
@@ -641,7 +649,11 @@ static void process_collection(const char *device, struct change_collection *col
                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)
@@ -667,7 +679,7 @@ static void handle_devstate_change(struct devstate_change *sc)
        /* 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);
 }
@@ -696,10 +708,12 @@ static void devstate_change_collector_cb(const struct ast_event *event, void *da
        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");
@@ -712,6 +726,7 @@ static void devstate_change_collector_cb(const struct ast_event *event, void *da
        strcpy(sc->device, device);
        sc->eid = *eid;
        sc->state = state;
+       sc->cachable = cachable;
 
        ast_mutex_lock(&devstate_collector.lock);
        AST_LIST_INSERT_TAIL(&devstate_collector.devstate_change_q, sc, entry);
index 4c231fe91f2d9b5d13ec43649b98d391fd12162a..c0295a7f25b0dead72c9606097ad332b94158c8e 100644 (file)
@@ -279,7 +279,7 @@ static const struct ie_map {
        [AST_EVENT_IE_RECEIVED_HASH]       = { AST_EVENT_IE_PLTYPE_STR,  "ReceivedHash" },
        [AST_EVENT_IE_USING_PASSWORD]      = { AST_EVENT_IE_PLTYPE_UINT, "UsingPassword" },
        [AST_EVENT_IE_ATTEMPTED_TRANSPORT] = { AST_EVENT_IE_PLTYPE_STR,  "AttemptedTransport" },
-
+       [AST_EVENT_IE_CACHABLE]            = { AST_EVENT_IE_PLTYPE_UINT,  "Cachable" },
 };
 
 const char *ast_event_get_type_name(const struct ast_event *event)
index 3b165d71ab52c038fd7ff4dbeb12992117b55286..9dab53ce565ae6ecac61de85f50d5cd323aeaacf 100644 (file)
@@ -1248,7 +1248,7 @@ static void notify_metermaids(const char *exten, char *context, enum ast_device_
        ast_debug(4, "Notification of state change to metermaids %s@%s\n to state '%s'",
                exten, context, ast_devstate2str(state));
 
-       ast_devstate_changed(state, "park:%s@%s", exten, context);
+       ast_devstate_changed(state, AST_DEVSTATE_CACHABLE, "park:%s@%s", exten, context);
 }
 
 /*! \brief metermaids callback from devicestate.c */
index 55ade21d790e7caec5f38746b1e66b219d279463..0553e6b465f34703a6be29ccdcdc6b9c15071866 100644 (file)
@@ -603,6 +603,7 @@ struct ast_variable *ast_http_get_post_vars(
        int content_length = 0;
        struct ast_variable *v, *post_vars=NULL, *prev = NULL;
        char *buf, *var, *val;
+       int res;
 
        for (v = headers; v; v = v->next) {
                if (!strcasecmp(v->name, "Content-Type")) {
@@ -615,20 +616,28 @@ struct ast_variable *ast_http_get_post_vars(
 
        for (v = headers; v; v = v->next) {
                if (!strcasecmp(v->name, "Content-Length")) {
-                       content_length = atoi(v->value) + 1;
+                       content_length = atoi(v->value);
                        break;
                }
        }
 
-       if (!content_length) {
+       if (content_length <= 0) {
                return NULL;
        }
 
-       buf = ast_alloca(content_length);
-       if (!fgets(buf, content_length, ser->f)) {
+       buf = ast_malloc(content_length + 1);
+       if (!buf) {
                return NULL;
        }
 
+       res = fread(buf, 1, content_length, ser->f);
+       if (res < content_length) {
+               /* Error, distinguishable by ferror() or feof(), but neither
+                * is good. */
+               goto done;
+       }
+       buf[content_length] = '\0';
+
        while ((val = strsep(&buf, "&"))) {
                var = strsep(&val, "=");
                if (val) {
@@ -646,6 +655,9 @@ struct ast_variable *ast_http_get_post_vars(
                        prev = v;
                }
        }
+       
+done:
+       ast_free(buf);
        return post_vars;
 }
 
index 73683e805b7220cbf41b532ed58979d4290fbc01..64cc6f014d0faa92de5d2ef3329e6053962ebc6b 100755 (executable)
@@ -2401,7 +2401,7 @@ test -n "$target_alias" &&
   program_prefix=${target_alias}-
 ac_config_headers="$ac_config_headers pjlib/include/pj/compat/os_auto.h pjlib/include/pj/compat/m_auto.h pjmedia/include/pjmedia/config_auto.h pjmedia/include/pjmedia-codec/config_auto.h pjsip/include/pjsip/sip_autoconf.h"
 
-ac_config_files="$ac_config_files build.mak build/os-auto.mak build/cc-auto.mak pjlib/build/os-auto.mak pjlib-util/build/os-auto.mak pjmedia/build/os-auto.mak pjsip/build/os-auto.mak third_party/build/os-auto.mak third_party/build/portaudio/os-auto.mak"
+ac_config_files="$ac_config_files build.mak build/os-auto.mak pjlib/build/os-auto.mak pjlib-util/build/os-auto.mak pjmedia/build/os-auto.mak pjsip/build/os-auto.mak third_party/build/os-auto.mak third_party/build/portaudio/os-auto.mak"
 
 
 
@@ -7799,7 +7799,6 @@ do
     "pjsip/include/pjsip/sip_autoconf.h") CONFIG_HEADERS="$CONFIG_HEADERS pjsip/include/pjsip/sip_autoconf.h" ;;
     "build.mak") CONFIG_FILES="$CONFIG_FILES build.mak" ;;
     "build/os-auto.mak") CONFIG_FILES="$CONFIG_FILES build/os-auto.mak" ;;
-    "build/cc-auto.mak") CONFIG_FILES="$CONFIG_FILES build/cc-auto.mak" ;;
     "pjlib/build/os-auto.mak") CONFIG_FILES="$CONFIG_FILES pjlib/build/os-auto.mak" ;;
     "pjlib-util/build/os-auto.mak") CONFIG_FILES="$CONFIG_FILES pjlib-util/build/os-auto.mak" ;;
     "pjmedia/build/os-auto.mak") CONFIG_FILES="$CONFIG_FILES pjmedia/build/os-auto.mak" ;;
index 1de41faafa42da08d9c763110f7f3d049d8103d9..a19b84eebaeb33e032e35863a9158bfba4862063 100644 (file)
@@ -13,7 +13,6 @@ AC_CONFIG_HEADER([pjlib/include/pj/compat/os_auto.h
                 ])
 AC_CONFIG_FILES([build.mak 
                 build/os-auto.mak 
-                build/cc-auto.mak
                 pjlib/build/os-auto.mak 
                 pjlib-util/build/os-auto.mak 
                 pjmedia/build/os-auto.mak
index ad6df03e944c91ce6f384ef7cf7cdedea6f3a094..d6000078ead034fffbf9e0dd6d4badeeda8e9730 100644 (file)
@@ -16,15 +16,6 @@ include $(PJDIR)/build/cc-$(CC_NAME).mak
 #
 -include cc-$(CC_NAME).mak
 
-#
-# Include auto configured compiler specification.
-# This will override the compiler settings above.
-# Currently this is made OPTIONAL, to prevent people
-# from getting errors because they don't re-run ./configure
-# after downloading new PJSIP.
-#
--include $(PJDIR)/build/cc-auto.mak
-
 #
 # Include global machine specific definitions
 #
index 8c349946bb40374978452e6d1ad94c50e53b53df..13c95d9a9db32e25c394ef0f531adff600a17ab1 100644 (file)
@@ -611,9 +611,9 @@ static struct ast_calendar_event *destroy_event(struct ast_calendar_event *event
         * but haven't hit the end event yet, go ahead and set the devicestate to the current busy status */
        if (event->bs_start_sched < 0 && event->bs_end_sched >= 0) {
                if (!calendar_is_busy(event->owner)) {
-                       ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Calendar:%s", event->owner->name);
+                       ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
                } else {
-                       ast_devstate_changed(AST_DEVICE_BUSY, "Calendar:%s", event->owner->name);
+                       ast_devstate_changed(AST_DEVICE_BUSY, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
                }
        }
 
@@ -871,9 +871,9 @@ static int calendar_devstate_change(const void *data)
        /* We can have overlapping events, so ignore the event->busy_state and check busy state
         * based on all events in the calendar */
        if (!calendar_is_busy(event->owner)) {
-               ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Calendar:%s", event->owner->name);
+               ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
        } else {
-               ast_devstate_changed(AST_DEVICE_BUSY, "Calendar:%s", event->owner->name);
+               ast_devstate_changed(AST_DEVICE_BUSY, AST_DEVSTATE_CACHABLE, "Calendar:%s", event->owner->name);
        }
 
        event = ast_calendar_unref_event(event);
index 8eed3fb189e1728a9eb06c828fb9d4c6751ec4e6..8692de1884dfba7d995686350f005b608d4b4c84 100644 (file)
@@ -352,7 +352,7 @@ static char *aji_cli_create_leafnode(struct ast_cli_entry *e, int cmd,
 static void aji_create_affiliations(struct aji_client *client, const char *node);
 static iks* aji_pubsub_iq_create(struct aji_client *client, const char *type);
 static void aji_publish_device_state(struct aji_client *client, const char * device,
-       const char *device_state);
+                                    const char *device_state, unsigned int cachable);
 static int aji_handle_pubsub_error(void *data, ikspak *pak);
 static int aji_handle_pubsub_event(void *data, ikspak *pak);
 static void aji_pubsub_subscribe(struct aji_client *client, const char *node);
@@ -366,7 +366,7 @@ static void aji_publish_mwi(struct aji_client *client, const char *mailbox,
 static void aji_devstate_cb(const struct ast_event *ast_event, void *data);
 static void aji_mwi_cb(const struct ast_event *ast_event, void *data);
 static iks* aji_build_publish_skeleton(struct aji_client *client, const char *node,
-       const char *event_type);
+                                      const char *event_type, unsigned int cachable);
 /* No transports in this version */
 /*
 static int aji_create_transport(char *label, struct aji_client *client);
@@ -776,7 +776,7 @@ static struct ast_custom_function jabberstatus_function = {
  */
 static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen)
 {
-       char *aux = NULL, *parse = NULL;
+       char *parse = NULL;
        int timeout;
        int jidlen, resourcelen;
        struct timeval start;
@@ -893,7 +893,7 @@ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, ch
                                continue;
                        }
                        found = 1;
-                       aux = ast_strdupa(tmp->message);
+                       ast_copy_string(buf, tmp->message, buflen);
                        AST_LIST_REMOVE_CURRENT(list);
                        aji_message_destroy(tmp);
                        break;
@@ -918,7 +918,6 @@ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, ch
                ast_log(LOG_NOTICE, "Timed out : no message received from %s\n", args.jid);
                return -1;
        }
-       ast_copy_string(buf, aux, buflen);
 
        return 0;
 }
@@ -3267,6 +3266,7 @@ static void aji_devstate_cb(const struct ast_event *ast_event, void *data)
 {
        const char *device;
        const char *device_state;
+       unsigned int cachable;
        struct aji_client *client;
        if (ast_eid_cmp(&ast_eid_default, ast_event_get_ie_raw(ast_event, AST_EVENT_IE_EID)))
        {
@@ -3278,7 +3278,8 @@ static void aji_devstate_cb(const struct ast_event *ast_event, void *data)
        client = ASTOBJ_REF((struct aji_client *) data);
        device = ast_event_get_ie_str(ast_event, AST_EVENT_IE_DEVICE);
        device_state = ast_devstate_str(ast_event_get_ie_uint(ast_event, AST_EVENT_IE_STATE));
-       aji_publish_device_state(client, device, device_state);
+       cachable = ast_event_get_ie_uint(ast_event, AST_EVENT_IE_CACHABLE);
+       aji_publish_device_state(client, device, device_state, cachable);
        ASTOBJ_UNREF(client, ast_aji_client_destroy);
 }
 
@@ -3318,11 +3319,13 @@ static void aji_init_event_distribution(struct aji_client *client)
  */
 static int aji_handle_pubsub_event(void *data, ikspak *pak)
 {
-       char *item_id, *device_state, *context;
+       char *item_id, *device_state, *context, *cachable_str;
        int oldmsgs, newmsgs;
        iks *item, *item_content;
        struct ast_eid pubsub_eid;
        struct ast_event *event;
+       unsigned int cachable = AST_DEVSTATE_CACHABLE;
+
        item = iks_find(iks_find(iks_find(pak->x, "event"), "items"), "item");
        if (!item) {
                ast_log(LOG_ERROR, "Could not parse incoming PubSub event\n");
@@ -3337,11 +3340,14 @@ static int aji_handle_pubsub_event(void *data, ikspak *pak)
        }
        if (!strcasecmp(iks_name(item_content), "state")) {
                device_state = iks_find_cdata(item, "state");
+               if ((cachable_str = iks_find_cdata(item, "cachable"))) {
+                       sscanf(cachable_str, "%30d", &cachable);
+               }
                if (!(event = ast_event_new(AST_EVENT_DEVICE_STATE_CHANGE,
-                       AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, item_id, AST_EVENT_IE_STATE,
-                       AST_EVENT_IE_PLTYPE_UINT, ast_devstate_val(device_state), AST_EVENT_IE_EID,
-                       AST_EVENT_IE_PLTYPE_RAW, &pubsub_eid, sizeof(pubsub_eid),
-                       AST_EVENT_IE_END))) {
+                                           AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, item_id, AST_EVENT_IE_STATE,
+                                           AST_EVENT_IE_PLTYPE_UINT, ast_devstate_val(device_state), AST_EVENT_IE_EID,
+                                           AST_EVENT_IE_PLTYPE_RAW, &pubsub_eid, sizeof(pubsub_eid),
+                                           AST_EVENT_IE_END))) {
                        return IKS_FILTER_EAT;
                }
        } else if (!strcasecmp(iks_name(item_content), "mailbox")) {
@@ -3361,7 +3367,13 @@ static int aji_handle_pubsub_event(void *data, ikspak *pak)
                        iks_name(item_content));
                return IKS_FILTER_EAT;
        }
-       ast_event_queue_and_cache(event);
+
+       if (cachable == AST_DEVSTATE_CACHABLE) {
+               ast_event_queue_and_cache(event);
+       } else {
+               ast_event_queue(event);
+       }
+
        return IKS_FILTER_EAT;
 }
 
@@ -3436,7 +3448,7 @@ static void aji_pubsub_subscribe(struct aji_client *client, const char *node)
  * \return iks *
  */
 static iks* aji_build_publish_skeleton(struct aji_client *client, const char *node,
-       const char *event_type)
+                                      const char *event_type, unsigned int cachable)
 {
        iks *request = aji_pubsub_iq_create(client, "set");
        iks *pubsub, *publish, *item;
@@ -3450,8 +3462,24 @@ static iks* aji_build_publish_skeleton(struct aji_client *client, const char *no
        }
        item = iks_insert(publish, "item");
        iks_insert_attrib(item, "id", node);
-       return item;
 
+       if (cachable == AST_DEVSTATE_NOT_CACHABLE) {
+               iks *options, *x, *field_form_type, *field_persist;
+
+               options = iks_insert(pubsub, "publish-options");
+               x = iks_insert(options, "x");
+               iks_insert_attrib(x, "xmlns", "jabber:x:data");
+               iks_insert_attrib(x, "type", "submit");
+               field_form_type = iks_insert(x, "field");
+               iks_insert_attrib(field_form_type, "var", "FORM_TYPE");
+               iks_insert_attrib(field_form_type, "type", "hidden");
+               iks_insert_cdata(iks_insert(field_form_type, "value"), "http://jabber.org/protocol/pubsub#publish-options", 0);
+               field_persist = iks_insert(x, "field");
+               iks_insert_attrib(field_persist, "var", "pubsub#persist_items");
+               iks_insert_cdata(iks_insert(field_persist, "value"), "0", 1);
+       }
+
+       return item;
 }
 
 /*!
@@ -3462,11 +3490,11 @@ static iks* aji_build_publish_skeleton(struct aji_client *client, const char *no
  * \return void
  */
 static void aji_publish_device_state(struct aji_client *client, const char *device,
-       const char *device_state)
+                                    const char *device_state, unsigned int cachable)
 {
-       iks *request = aji_build_publish_skeleton(client, device, "device_state");
+       iks *request = aji_build_publish_skeleton(client, device, "device_state", cachable);
        iks *state;
-       char eid_str[20];
+       char eid_str[20], cachable_str[2];
        if (ast_test_flag(&pubsubflags, AJI_PUBSUB_AUTOCREATE)) {
                if (ast_test_flag(&pubsubflags, AJI_XEP0248)) {
                        aji_create_pubsub_node(client, "leaf", device, "device_state");
@@ -3478,6 +3506,8 @@ static void aji_publish_device_state(struct aji_client *client, const char *devi
        state = iks_insert(request, "state");
        iks_insert_attrib(state, "xmlns", "http://asterisk.org");
        iks_insert_attrib(state, "eid", eid_str);
+       snprintf(cachable_str, sizeof(cachable_str), "%u", cachable);
+       iks_insert_attrib(state, "cachable", cachable_str);
        iks_insert_cdata(state, device_state, strlen(device_state));
        ast_aji_send(client, iks_root(request));
        iks_delete(request);
@@ -3497,7 +3527,7 @@ static void aji_publish_mwi(struct aji_client *client, const char *mailbox,
        char eid_str[20];
        iks *mailbox_node, *request;
        snprintf(full_mailbox, sizeof(full_mailbox), "%s@%s", mailbox, context);
-       request = aji_build_publish_skeleton(client, full_mailbox, "message_waiting");
+       request = aji_build_publish_skeleton(client, full_mailbox, "message_waiting", 1);
        ast_eid_to_str(eid_str, sizeof(eid_str), &ast_eid_default);
        mailbox_node = iks_insert(request, "mailbox");
        iks_insert_attrib(mailbox_node, "xmlns", "http://asterisk.org");
index 4f7c3b02fb61303b63cbf8f087f8c71344a1a02a..1a73ca9e8a9999fe479d568d8ddb0a88a30c63a4 100644 (file)
@@ -919,7 +919,7 @@ static iks* xmpp_pubsub_iq_create(struct ast_xmpp_client *client, const char *ty
  * \return iks *
  */
 static iks* xmpp_pubsub_build_publish_skeleton(struct ast_xmpp_client *client, const char *node,
-                                              const char *event_type)
+                                              const char *event_type, unsigned int cachable)
 {
        RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
        iks *request, *pubsub, *publish, *item;
@@ -935,6 +935,22 @@ static iks* xmpp_pubsub_build_publish_skeleton(struct ast_xmpp_client *client, c
        item = iks_insert(publish, "item");
        iks_insert_attrib(item, "id", node);
 
+       if (cachable == AST_DEVSTATE_NOT_CACHABLE) {
+               iks *options, *x, *field_form_type, *field_persist;
+
+               options = iks_insert(pubsub, "publish-options");
+               x = iks_insert(options, "x");
+               iks_insert_attrib(x, "xmlns", "jabber:x:data");
+               iks_insert_attrib(x, "type", "submit");
+               field_form_type = iks_insert(x, "field");
+               iks_insert_attrib(field_form_type, "var", "FORM_TYPE");
+               iks_insert_attrib(field_form_type, "type", "hidden");
+               iks_insert_cdata(iks_insert(field_form_type, "value"), "http://jabber.org/protocol/pubsub#publish-options", 0);
+               field_persist = iks_insert(x, "field");
+               iks_insert_attrib(field_persist, "var", "pubsub#persist_items");
+               iks_insert_cdata(iks_insert(field_persist, "value"), "0", 1);
+       }
+
        return item;
 
 }
@@ -1107,7 +1123,7 @@ static void xmpp_pubsub_publish_mwi(struct ast_xmpp_client *client, const char *
 
        snprintf(full_mailbox, sizeof(full_mailbox), "%s@%s", mailbox, context);
 
-       if (!(request = xmpp_pubsub_build_publish_skeleton(client, full_mailbox, "message_waiting"))) {
+       if (!(request = xmpp_pubsub_build_publish_skeleton(client, full_mailbox, "message_waiting", AST_DEVSTATE_CACHABLE))) {
                return;
        }
 
@@ -1131,13 +1147,13 @@ static void xmpp_pubsub_publish_mwi(struct ast_xmpp_client *client, const char *
  * \return void
  */
 static void xmpp_pubsub_publish_device_state(struct ast_xmpp_client *client, const char *device,
-                                            const char *device_state)
+                                            const char *device_state, unsigned int cachable)
 {
        RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
        iks *request, *state;
-       char eid_str[20];
+       char eid_str[20], cachable_str[2];
 
-       if (!cfg || !cfg->global || !(request = xmpp_pubsub_build_publish_skeleton(client, device, "device_state"))) {
+       if (!cfg || !cfg->global || !(request = xmpp_pubsub_build_publish_skeleton(client, device, "device_state", cachable))) {
                return;
        }
 
@@ -1153,6 +1169,8 @@ static void xmpp_pubsub_publish_device_state(struct ast_xmpp_client *client, con
        state = iks_insert(request, "state");
        iks_insert_attrib(state, "xmlns", "http://asterisk.org");
        iks_insert_attrib(state, "eid", eid_str);
+       snprintf(cachable_str, sizeof(cachable_str), "%u", cachable);
+       iks_insert_attrib(state, "cachable", cachable_str);
        iks_insert_cdata(state, device_state, strlen(device_state));
        ast_xmpp_client_send(client, iks_root(request));
        iks_delete(request);
@@ -1195,6 +1213,7 @@ static void xmpp_pubsub_devstate_cb(const struct ast_event *ast_event, void *dat
 {
        struct ast_xmpp_client *client = data;
        const char *device, *device_state;
+       unsigned int cachable;
 
        if (ast_eid_cmp(&ast_eid_default, ast_event_get_ie_raw(ast_event, AST_EVENT_IE_EID))) {
                /* If the event didn't originate from this server, don't send it back out. */
@@ -1204,7 +1223,8 @@ static void xmpp_pubsub_devstate_cb(const struct ast_event *ast_event, void *dat
 
        device = ast_event_get_ie_str(ast_event, AST_EVENT_IE_DEVICE);
        device_state = ast_devstate_str(ast_event_get_ie_uint(ast_event, AST_EVENT_IE_STATE));
-       xmpp_pubsub_publish_device_state(client, device, device_state);
+       cachable = ast_event_get_ie_uint(ast_event, AST_EVENT_IE_CACHABLE);
+       xmpp_pubsub_publish_device_state(client, device, device_state, cachable);
 }
 
 /*!
@@ -1287,11 +1307,12 @@ static void xmpp_pubsub_subscribe(struct ast_xmpp_client *client, const char *no
  */
 static int xmpp_pubsub_handle_event(void *data, ikspak *pak)
 {
-       char *item_id, *device_state, *context;
+       char *item_id, *device_state, *context, *cachable_str;
        int oldmsgs, newmsgs;
        iks *item, *item_content;
        struct ast_eid pubsub_eid;
        struct ast_event *event;
+       unsigned int cachable = AST_DEVSTATE_CACHABLE;
        item = iks_find(iks_find(iks_find(pak->x, "event"), "items"), "item");
        if (!item) {
                ast_log(LOG_ERROR, "Could not parse incoming PubSub event\n");
@@ -1306,6 +1327,9 @@ static int xmpp_pubsub_handle_event(void *data, ikspak *pak)
        }
        if (!strcasecmp(iks_name(item_content), "state")) {
                device_state = iks_find_cdata(item, "state");
+               if ((cachable_str = iks_find_cdata(item, "cachable"))) {
+                       sscanf(cachable_str, "%30d", &cachable);
+               }
                if (!(event = ast_event_new(AST_EVENT_DEVICE_STATE_CHANGE,
                                            AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, item_id, AST_EVENT_IE_STATE,
                                            AST_EVENT_IE_PLTYPE_UINT, ast_devstate_val(device_state), AST_EVENT_IE_EID,
@@ -1330,7 +1354,13 @@ static int xmpp_pubsub_handle_event(void *data, ikspak *pak)
                          iks_name(item_content));
                return IKS_FILTER_EAT;
        }
-       ast_event_queue_and_cache(event);
+
+       if (cachable == AST_DEVSTATE_CACHABLE) {
+               ast_event_queue_and_cache(event);
+       } else {
+               ast_event_queue(event);
+       }
+
        return IKS_FILTER_EAT;
 }
 
@@ -1832,7 +1862,7 @@ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, ch
 {
        RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
        RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
-       char *aux = NULL, *parse = NULL;
+       char *parse = NULL;
        int timeout, jidlen, resourcelen, found = 0;
        struct timeval start;
        long diff = 0;
@@ -1946,7 +1976,7 @@ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, ch
                                continue;
                        }
                        found = 1;
-                       aux = ast_strdupa(message->message);
+                       ast_copy_string(buf, message->message, buflen);
                        AST_LIST_REMOVE_CURRENT(list);
                        xmpp_message_destroy(message);
                        break;
@@ -1970,7 +2000,6 @@ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, ch
                ast_log(LOG_NOTICE, "Timed out : no message received from %s\n", args.jid);
                return -1;
        }
-       ast_copy_string(buf, aux, buflen);
 
        return 0;
 }