[asterisk-commits] russell: branch group/sip_session_timers r97168 - in /team/group/sip_session_...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jan 8 14:32:27 CST 2008


Author: russell
Date: Tue Jan  8 14:32:26 2008
New Revision: 97168

URL: http://svn.digium.com/view/asterisk?view=rev&rev=97168
Log:
resolve, reset

Modified:
    team/group/sip_session_timers/   (props changed)
    team/group/sip_session_timers/apps/app_queue.c
    team/group/sip_session_timers/channels/chan_sip.c
    team/group/sip_session_timers/funcs/func_groupcount.c
    team/group/sip_session_timers/main/asterisk.c

Propchange: team/group/sip_session_timers/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/group/sip_session_timers/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Jan  8 14:32:26 2008
@@ -1,1 +1,1 @@
-/trunk:1-97050
+/trunk:1-97164

Modified: team/group/sip_session_timers/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/group/sip_session_timers/apps/app_queue.c?view=diff&rev=97168&r1=97167&r2=97168
==============================================================================
--- team/group/sip_session_timers/apps/app_queue.c (original)
+++ team/group/sip_session_timers/apps/app_queue.c Tue Jan  8 14:32:26 2008
@@ -2099,6 +2099,16 @@
 
 	/* Presense of ADSI CPE on outgoing channel follows ours */
 	tmp->chan->adsicpe = qe->chan->adsicpe;
+
+	/* Inherit context and extension */
+	if (!ast_strlen_zero(qe->chan->macrocontext))
+		ast_copy_string(tmp->chan->dialcontext, qe->chan->macrocontext, sizeof(tmp->chan->dialcontext));
+	else
+		ast_copy_string(tmp->chan->dialcontext, qe->chan->context, sizeof(tmp->chan->dialcontext));
+	if (!ast_strlen_zero(qe->chan->macroexten))
+		ast_copy_string(tmp->chan->exten, qe->chan->macroexten, sizeof(tmp->chan->exten));
+	else
+		ast_copy_string(tmp->chan->exten, qe->chan->exten, sizeof(tmp->chan->exten));
 
 	/* Place the call, but don't wait on the answer */
 	if ((res = ast_call(tmp->chan, location, 0))) {

Modified: team/group/sip_session_timers/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/group/sip_session_timers/channels/chan_sip.c?view=diff&rev=97168&r1=97167&r2=97168
==============================================================================
--- team/group/sip_session_timers/channels/chan_sip.c (original)
+++ team/group/sip_session_timers/channels/chan_sip.c Tue Jan  8 14:32:26 2008
@@ -175,6 +175,7 @@
 #include "asterisk/translate.h"
 #include "asterisk/version.h"
 #include "asterisk/event.h"
+#include "asterisk/astobj2.h"
 
 #ifndef FALSE
 #define FALSE    0
@@ -1257,7 +1258,7 @@
 	struct ast_rtp *rtp;			/*!< RTP Session */
 	struct ast_rtp *vrtp;			/*!< Video RTP session */
 	struct ast_rtp *trtp;			/*!< Text RTP session */
-	struct sip_pkt *packets;		/*!< Packets scheduled for re-transmission */
+	struct ao2_container *packets;		/*!< Packets scheduled for re-transmission */
 	struct sip_history_head *history;	/*!< History of this SIP dialog */
 	size_t history_entries;			/*!< Number of entires in the history */
 	struct ast_variable *chanvars;		/*!< Channel variables to set for inbound call */
@@ -1326,7 +1327,6 @@
  * require retransmissions.
  */
 struct sip_pkt {
-	struct sip_pkt *next;			/*!< Next packet in linked list */
 	int retrans;				/*!< Retransmission number */
 	int method;				/*!< SIP method for this packet */
 	int seqno;				/*!< Sequence number */
@@ -2420,12 +2420,15 @@
 /*! \brief Retransmit SIP message if no answer (Called from scheduler) */
 static int retrans_pkt(const void *data)
 {
-	struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL;
+	struct sip_pkt *pkt = (struct sip_pkt *)data, *prev;
 	int reschedule = DEFAULT_RETRANS;
 	int xmitres = 0;
 
+	ao2_ref(pkt, 1); /* Make sure this cannot go away while we're using it */
+
 	/* Lock channel PVT */
-	sip_pvt_lock(pkt->owner);
+	if (pkt->owner)
+		sip_pvt_lock(pkt->owner);
 
 	if (pkt->retrans < MAX_RETRANS) {
 		pkt->retrans++;
@@ -2452,7 +2455,7 @@
  			ast_debug(4, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n", pkt->retrans +1, siptimer_a, pkt->timer_t1, pkt->retransid);
  		} 
 
-		if (sip_debug_test_pvt(pkt->owner)) {
+		if (pkt->owner && sip_debug_test_pvt(pkt->owner)) {
 			const struct sockaddr_in *dst = sip_real_dst(pkt->owner);
 			ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n",
 				pkt->retrans, sip_nat_mode(pkt->owner),
@@ -2462,11 +2465,14 @@
 
 		append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data);
 		xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);
-		sip_pvt_unlock(pkt->owner);
+		if (pkt->owner)
+			sip_pvt_unlock(pkt->owner);
 		if (xmitres == XMIT_ERROR)
-			ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid);
-		else 
+			ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner ? pkt->owner->callid : "<unknown>");
+		else {
+			ao2_ref(pkt, -1);
 			return  reschedule;
+		}
 	} 
 	/* Too many retries */
 	if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) {
@@ -2474,29 +2480,31 @@
 			ast_log(LOG_WARNING, "Maximum retries exceeded on transmission %s for seqno %d (%s %s)\n",
 				pkt->owner->callid, pkt->seqno,
 				pkt->is_fatal ? "Critical" : "Non-critical", pkt->is_resp ? "Response" : "Request");
-	} else if (pkt->method == SIP_OPTIONS && sipdebug) {
-			ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid);
+	} else if (pkt->owner && (pkt->method == SIP_OPTIONS) && sipdebug) {
+		ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s) \n", pkt->owner->callid);
 
 	} 
-	if (xmitres == XMIT_ERROR) {
-		ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission on Call ID %s\n", pkt->owner->callid);
-		append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
-	} else 
-		append_history(pkt->owner, "MaxRetries", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
- 		
+	if (pkt->owner) {
+		if (xmitres == XMIT_ERROR) {
+			ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission of transaction in call id %s \n", pkt->owner->callid);
+			append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
+		} else
+			append_history(pkt->owner, "MaxRetries", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
+ 	}
 	pkt->retransid = -1;
 
 	if (pkt->is_fatal) {
-		while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) {
+		while (pkt->owner && pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) {
 			sip_pvt_unlock(pkt->owner);	/* SIP_PVT, not channel */
 			usleep(1);
-			sip_pvt_lock(pkt->owner);
-		}
-
-		if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 
+			if (pkt->owner)
+				sip_pvt_lock(pkt->owner);
+		}
+
+		if (pkt->owner && pkt->owner->owner && !pkt->owner->owner->hangupcause) 
 			pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE;
 		
-		if (pkt->owner->owner) {
+		if (pkt->owner && pkt->owner->owner) {
 			sip_alreadygone(pkt->owner);
 			ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pkt->owner->callid);
 			ast_queue_hangup(pkt->owner->owner);
@@ -2505,7 +2513,7 @@
 			/* If no channel owner, destroy now */
 
 			/* Let the peerpoke system expire packets when the timer expires for poke_noanswer */
-			if (pkt->method != SIP_OPTIONS && pkt->method != SIP_REGISTER) {
+			if (pkt->owner && pkt->method != SIP_OPTIONS && pkt->method != SIP_REGISTER) {
 				pkt->owner->needdestroy = 1;
 				sip_alreadygone(pkt->owner);
 				append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately");
@@ -2513,7 +2521,7 @@
 		}
 	}
 
-	if (pkt->method == SIP_BYE) {
+	if (pkt->owner && pkt->method == SIP_BYE) {
 		/* We're not getting answers on SIP BYE's.  Tear down the call anyway. */
 		if (pkt->owner->owner) 
 			ast_channel_unlock(pkt->owner->owner);
@@ -2522,18 +2530,23 @@
 	}
 
 	/* Remove the packet */
-	for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) {
-		if (cur == pkt) {
-			UNLINK(cur, pkt->owner->packets, prev);
+	if (pkt->owner && (prev = ao2_find(pkt->owner->packets, pkt, OBJ_UNLINK | OBJ_POINTER))) {
+		/* Destroy the container's reference (inherited) */
+		ao2_ref(prev, -1);
+		sip_pvt_unlock(pkt->owner);
+		/* Now destroy our initial reference */
+		ao2_ref(pkt, -1);
+		/* And destroy the sched ref */
+		ao2_ref(pkt, -1);
+		return 0;
+	} else {
+		ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n");
+		if (pkt->owner)
 			sip_pvt_unlock(pkt->owner);
-			ast_free(pkt);
-			return 0;
-		}
-	}
-	/* error case */
-	ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n");
-	sip_pvt_unlock(pkt->owner);
-	return 0;
+		ao2_ref(pkt, -1); /* Initial ref */
+		ao2_ref(pkt, -1); /* Sched ref */
+		return 0;
+	}
 }
 
 /*! \brief Transmit packet with retransmits 
@@ -2545,7 +2558,7 @@
 	int siptimer_a = DEFAULT_RETRANS;
 	int xmitres = 0;
 
-	if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1)))
+	if (!(pkt = ao2_alloc(sizeof(*pkt) + len + 1, ast_free)))
 		return AST_FAILURE;
 	/* copy data, add a terminator and save length */
 	memcpy(pkt->data, data, len);
@@ -2557,17 +2570,13 @@
 	pkt->is_resp = resp;
 	pkt->is_fatal = fatal;
 	pkt->owner = dialog_ref(p);
-	pkt->next = p->packets;
-	p->packets = pkt;
 	pkt->timer_t1 = p->timer_t1;	/* Set SIP timer T1 */
 	if (pkt->timer_t1)
 		siptimer_a = pkt->timer_t1 * 2;
 
-	/* Schedule retransmission */
-	pkt->retransid = ast_sched_replace_variable(pkt->retransid, sched, 
-		siptimer_a, retrans_pkt, pkt, 1);
-	if (sipdebug)
-		ast_debug(4, "*** SIP TIMER: Initializing retransmit timer on packet: Id  #%d\n", pkt->retransid);
+	if (option_debug > 3 && sipdebug)
+		ast_log(LOG_DEBUG, "*** SIP TIMER: Initializing retransmit timer on packet: Id  #%d\n", pkt->retransid);
+
 	if (sipmethod == SIP_INVITE) {
 		/* Note this is a pending invite */
 		p->pendinginvite = seqno;
@@ -2577,11 +2586,25 @@
 
 	if (xmitres == XMIT_ERROR) {	/* Serious network trouble, no need to try again */
 		append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
-		ast_sched_del(sched, pkt->retransid);	/* No more retransmission */
 		pkt->retransid = -1;
+		ao2_ref(pkt, -1);	/* and deallocate */
 		return AST_FAILURE;
-	} else
+	} else {
+		/* Add refcount for scheduler pointer */
+		ao2_ref(pkt, 1);
+		/* Schedule retransmission */
+		pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1);
+		/* Link into the list of packets */
+		ao2_link(p->packets, pkt);
 		return AST_SUCCESS;
+	}
+}
+
+static int __deref_ao2_owner_cb(void *obj, void *unused, int flags)
+{
+	struct sip_pkt *pkt = obj;
+	pkt->owner = NULL;
+	return 0;
 }
 
 /*! \brief Kill a SIP dialog (called only by the scheduler)
@@ -2602,11 +2625,11 @@
 		return 10000;	/* Reschedule this destruction so that we know that it's gone */
 	}
 
-	/* If there are packets still waiting for delivery, delay the destruction */
-	if (p->packets) {
-		ast_debug(3, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>");
-		append_history(p, "ReliableXmit", "timeout");
-		return 10000;
+	/* If there are packets still waiting for delivery, make sure they can't callback to us anymore. */
+	if (ao2_container_count(p->packets)) {
+		sip_pvt_lock(p);
+		ao2_callback(p->packets, 0, __deref_ao2_owner_cb, NULL);
+		sip_pvt_unlock(p);
 	}
 
 	if (p->subscribed == MWI_NOTIFICATION)
@@ -2673,7 +2696,8 @@
 /*! \brief Acknowledges receipt of a packet and stops retransmission */
 static void __sip_ack(struct sip_pvt *p, int seqno, int resp, int sipmethod)
 {
-	struct sip_pkt *cur, *prev = NULL;
+	struct sip_pkt *cur;
+	struct ao2_iterator ao2i;
 	const char *msg = "Not Found";	/* used only for debugging */
 
 	sip_pvt_lock(p);
@@ -2686,7 +2710,8 @@
 	if (p->outboundproxy && !p->outboundproxy->force)
 		p->outboundproxy = NULL;
 
-	for (cur = p->packets; cur; prev = cur, cur = cur->next) {
+	ao2i = ao2_iterator_init(p->packets, 0);
+	while ((cur = ao2_iterator_next(&ao2i))) {
 		if (cur->seqno != seqno || cur->is_resp != resp)
 			continue;
 		if (cur->is_resp || cur->method == sipmethod) {
@@ -2698,57 +2723,65 @@
 			if (cur->retransid > -1) {
 				if (sipdebug)
 					ast_debug(4, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
-				ast_sched_del(sched, cur->retransid);
+				if (!ast_sched_del(sched, cur->retransid))
+					ao2_ref(cur, -1); /* scheduler deref */
 				cur->retransid = -1;
 			}
-			UNLINK(cur, p->packets, prev);
-			dialog_unref(cur->owner);
-			ast_free(cur);
+
+			/* Remove it from the list */
+			ao2_unlink(p->packets, cur);
+			ao2_ref(cur, -1); /* iterator deref */
 			break;
 		}
+
+		ao2_ref(cur, -1); /* iterator deref */
 	}
 	sip_pvt_unlock(p);
 	ast_debug(1, "Stopping retransmission on '%s' of %s %d: Match %s\n",
 		p->callid, resp ? "Response" : "Request", seqno, msg);
 }
 
-/*! \brief Pretend to ack all packets
- * maybe the lock on p is not strictly necessary but there might be a race */
+static int __sip_pretend_ack_cb(void *obj, void *vp, int flags)
+{
+	struct sip_pvt *p = vp;
+	struct sip_pkt *pkt = obj;
+	__sip_ack(p, pkt->seqno, pkt->is_resp, pkt->method ? pkt->method : find_sip_method(pkt->data));
+	return 0;
+}
+
+/*! \brief Pretend to ack all packets */
 static void __sip_pretend_ack(struct sip_pvt *p)
 {
-	struct sip_pkt *cur = NULL;
-
-	while (p->packets) {
-		int method;
-		if (cur == p->packets) {
-			ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
-			return;
-		}
-		cur = p->packets;
-		method = (cur->method) ? cur->method : find_sip_method(cur->data);
-		__sip_ack(p, cur->seqno, cur->is_resp, method);
-	}
+	ao2_callback(p->packets, 0, __sip_pretend_ack_cb, p);
 }
 
 /*! \brief Acks receipt of packet, keep it around (used for provisional responses) */
 static int __sip_semi_ack(struct sip_pvt *p, int seqno, int resp, int sipmethod)
 {
-	struct sip_pkt *cur;
+	struct sip_pkt *cur, *found;
 	int res = -1;
-
-	for (cur = p->packets; cur; cur = cur->next) {
+	struct ao2_iterator ao2i;
+
+	ao2i = ao2_iterator_init(p->packets, 0);
+	while ((cur = ao2_iterator_next(&ao2i))) {
 		if (cur->seqno == seqno && cur->is_resp == resp &&
 			(cur->is_resp || method_match(sipmethod, cur->data))) {
 			/* this is our baby */
 			if (cur->retransid > -1) {
 				if (sipdebug)
 					ast_debug(4, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
-				ast_sched_del(sched, cur->retransid);
+				if (!ast_sched_del(sched, cur->retransid))
+					ao2_ref(cur, -1); /* scheduler deref */
 				cur->retransid = -1;
 			}
 			res = 0;
+			/* Now remove it from the packet list. */
+			if ((found = ao2_find(p->packets, cur, OBJ_UNLINK | OBJ_POINTER)))
+				ao2_ref(found, -1); /* container item deref */
+			ao2_ref(cur, -1); /* iterator deref */
 			break;
 		}
+		ao2_ref(cur, -1); /* iterator deref */
 	}
 	ast_debug(1, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found");
 	return res;
@@ -3510,6 +3543,20 @@
 	}
 }
 
+static void set_t38_capabilities(struct sip_pvt *p)
+{
+	p->t38.capability = global_t38_capability;
+	if (p->udptl) {
+		if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC )
+			p->t38.capability |= T38FAX_UDP_EC_FEC;
+		else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY )
+			p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
+		else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE )
+			p->t38.capability |= T38FAX_UDP_EC_NONE;
+		p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
+	}
+}
+
 /*! \brief Create address structure from peer reference.
  *	This function copies data from peer to the dialog, so we don't have to look up the peer
  *	again from memory or database during the life time of the dialog.
@@ -3538,17 +3585,8 @@
 	}
 	dialog->prefs = peer->prefs;
 	if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) {
-		dialog->t38.capability = global_t38_capability;
-		if (dialog->udptl) {
-			if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC )
-				dialog->t38.capability |= T38FAX_UDP_EC_FEC;
-			else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY )
-				dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
-			else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE )
-				dialog->t38.capability |= T38FAX_UDP_EC_NONE;
-			dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
-			ast_debug(2,"Our T38 capability (%d)\n", dialog->t38.capability);
-		}
+		ast_copy_flags(&dialog->t38.t38support, &peer->flags[1], SIP_PAGE2_T38SUPPORT);
+		set_t38_capabilities(dialog);
 		dialog->t38.jointcapability = dialog->t38.capability;
 	} else if (dialog->udptl) {
 		ast_udptl_destroy(dialog->udptl);
@@ -3847,11 +3885,21 @@
 	
 }
 
+static int __sip_destroy_packet_cb(void *obj, void *unused, int flags)
+{
+	struct sip_pkt *pkt = obj;
+	if (pkt->retransid > -1) {
+		if (!ast_sched_del(sched, pkt->retransid))
+			ao2_ref(pkt, -1); /* scheduler deref */
+	}
+	pkt->owner = NULL;
+	return 0;
+}
+
 /*! \brief Execute destruction of SIP dialog structure, release memory */
 static void __sip_destroy(struct sip_pvt *p, int lockowner, int lockdialoglist)
 {
 	struct sip_pvt *cur, *prev = NULL;
-	struct sip_pkt *cp;
 
 	if (sip_debug_test_pvt(p))
 		ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
@@ -3944,13 +3992,8 @@
 	} 
 
 	/* remove all current packets in this dialog */
-	while((cp = p->packets)) {
-		p->packets = p->packets->next;
-		if (cp->retransid > -1)
-			ast_sched_del(sched, cp->retransid);
-		dialog_unref(cp->owner);
-		ast_free(cp);
-	}
+	ao2_callback(p->packets, 0, __sip_destroy_packet_cb, NULL);
+
 	if (p->chanvars) {
 		ast_variables_destroy(p->chanvars);
 		p->chanvars = NULL;
@@ -5259,6 +5302,22 @@
 }
 
 
+static int packet_hash_fn(const void *obj, const int flags)
+{
+	const struct sip_pkt *pkt = obj;
+	return pkt->seqno;
+}
+
+static int packet_cmp_fn(void *obj1, void *obj2, int flags)
+{
+	struct sip_pkt *p1 = obj1, *p2 = obj2;
+
+	if (flags & OBJ_POINTER)
+		return p1 == p2 ? CMP_MATCH : 0;
+	else
+		return p1->seqno == p2->seqno ? CMP_MATCH : 0;
+}
+
 /*! \brief Allocate sip_pvt structure, set defaults and link in the container.
  * Returns a reference to the object so whoever uses it later must
  * remember to release the reference.
@@ -5267,11 +5326,18 @@
 				 int useglobal_nat, const int intended_method)
 {
 	struct sip_pvt *p;
-
-	if (!(p = ast_calloc(1, sizeof(*p))))
+	struct ao2_container *aoc;
+
+	if (!(aoc = ao2_container_alloc(37, packet_hash_fn, packet_cmp_fn)))
 		return NULL;
 
+	if (!(p = ast_calloc(1, sizeof(*p)))) {
+		ao2_ref(aoc, -1);
+		return NULL;
+	}
+
 	if (ast_string_field_init(p, 512)) {
+		ao2_ref(aoc, -1);
 		ast_free(p);
 		return NULL;
 	}
@@ -5288,6 +5354,7 @@
 	p->session_modify = TRUE;
 	p->stimer = NULL;
 	p->prefs = default_prefs;		/* Set default codecs for this call */
+	p->packets = aoc;
 
 	if (intended_method != SIP_OPTIONS) {	/* Peerpoke has it's own system */
 		p->timer_t1 = global_t1;	/* Default SIP retransmission timer T1 (RFC 3261) */
@@ -5380,14 +5447,8 @@
 	    (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
 		p->noncodeccapability |= AST_RTP_DTMF;
 	if (p->udptl) {
-		p->t38.capability = global_t38_capability;
-		if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY)
-			p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
-		else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC)
-			p->t38.capability |= T38FAX_UDP_EC_FEC;
-		else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE)
-			p->t38.capability |= T38FAX_UDP_EC_NONE;
-		p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
+		ast_copy_flags(&p->t38.t38support, &p->flags[1], SIP_PAGE2_T38SUPPORT);
+		set_t38_capabilities(p);
 		p->t38.jointcapability = p->t38.capability;
 	}
 	ast_string_field_set(p, context, default_context);
@@ -17639,7 +17700,8 @@
 			/* If we have sessions that needs to be destroyed, do it now */
 			/* Check if we have outstanding requests not responsed to or an active call
 				- if that's the case, wait with destruction */
-			if (dialog->needdestroy && !dialog->packets && !dialog->owner) {
+			if (dialog->needdestroy && !ao2_container_count(dialog->packets) &&
+			    !dialog->owner) {
 				sip_pvt_unlock(dialog);
 				__sip_destroy(dialog, TRUE, FALSE);
 				goto restartsearch;

Modified: team/group/sip_session_timers/funcs/func_groupcount.c
URL: http://svn.digium.com/view/asterisk/team/group/sip_session_timers/funcs/func_groupcount.c?view=diff&rev=97168&r1=97167&r2=97168
==============================================================================
--- team/group/sip_session_timers/funcs/func_groupcount.c (original)
+++ team/group/sip_session_timers/funcs/func_groupcount.c Tue Jan  8 14:32:26 2008
@@ -39,6 +39,24 @@
 
 	ast_app_group_split_group(data, group, sizeof(group), category,
 				  sizeof(category));
+
+	/* If no group has been provided let's find one */
+	if (ast_strlen_zero(group)) {
+		struct ast_group_info *gi = NULL;
+
+		ast_app_group_list_rdlock();
+		for (gi = ast_app_group_list_head(); gi; gi = AST_LIST_NEXT(gi, list)) {
+			if (gi->chan != chan)
+				continue;
+			if (ast_strlen_zero(category) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))
+				break;
+		}
+		if (gi) {
+			ast_copy_string(group, gi->group, sizeof(group));
+			ast_copy_string(category, gi->category, sizeof(category));
+		}
+		ast_app_group_list_unlock();
+	}
 
 	if ((count = ast_app_group_get_count(group, category)) == -1)
 		ast_log(LOG_NOTICE, "No group could be found for channel '%s'\n", chan->name);

Modified: team/group/sip_session_timers/main/asterisk.c
URL: http://svn.digium.com/view/asterisk/team/group/sip_session_timers/main/asterisk.c?view=diff&rev=97168&r1=97167&r2=97168
==============================================================================
--- team/group/sip_session_timers/main/asterisk.c (original)
+++ team/group/sip_session_timers/main/asterisk.c Tue Jan  8 14:32:26 2008
@@ -2788,7 +2788,7 @@
 			break;
 		case 'x':
 			ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC);
-			xarg = optarg;
+			xarg = ast_strdupa(optarg);
 			break;
 		case 'C':
 			ast_copy_string(cfg_paths.config_file, optarg, sizeof(cfg_paths.config_file));
@@ -2810,10 +2810,10 @@
 			show_version();
 			exit(0);
 		case 'U':
-			runuser = optarg;
+			runuser = ast_strdupa(optarg);
 			break;
 		case 'G':
-			rungroup = optarg;
+			rungroup = ast_strdupa(optarg);
 			break;
 		case 's':
 			remotesock = optarg;




More information about the asterisk-commits mailing list