[asterisk-commits] jrose: trunk r369414 - in /trunk: channels/ include/asterisk/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jun 26 16:45:31 CDT 2012


Author: jrose
Date: Tue Jun 26 16:45:22 2012
New Revision: 369414

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=369414
Log:
Unique Call ID logging Phases III and IV

Adds call ID logging changes to specific channel drivers that weren't handled
handled in phase II of Call ID Logging. Also covers logging for threads for
threads created by systems that may be involved with many different calls.
Extra special thanks to Richard for rigorous review of chan_dahdi and its
various signalling modules.

review: https://reviewboard.asterisk.org/r/1927/
review: https://reviewboard.asterisk.org/r/1950/


Modified:
    trunk/channels/chan_agent.c
    trunk/channels/chan_dahdi.c
    trunk/channels/chan_iax2.c
    trunk/channels/chan_local.c
    trunk/channels/sig_analog.c
    trunk/channels/sig_pri.c
    trunk/channels/sig_ss7.c
    trunk/include/asterisk/logger.h
    trunk/main/autoservice.c
    trunk/main/bridging.c
    trunk/main/channel_internal_api.c
    trunk/main/cli.c
    trunk/main/features.c
    trunk/main/logger.c
    trunk/main/pbx.c

Modified: trunk/channels/chan_agent.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_agent.c?view=diff&rev=369414&r1=369413&r2=369414
==============================================================================
--- trunk/channels/chan_agent.c (original)
+++ trunk/channels/chan_agent.c Tue Jun 26 16:45:22 2012
@@ -1099,7 +1099,7 @@
 }
 
 /*! \brief Create new agent channel */
-static struct ast_channel *agent_new(struct agent_pvt *p, int state, const char *linkedid)
+static struct ast_channel *agent_new(struct agent_pvt *p, int state, const char *linkedid, struct ast_callid *callid)
 {
 	struct ast_channel *tmp;
 #if 0
@@ -1115,6 +1115,10 @@
 	if (!tmp) {
 		ast_log(LOG_WARNING, "Unable to allocate agent channel structure\n");
 		return NULL;
+	}
+
+	if (callid) {
+		ast_channel_callid_set(tmp, callid);
 	}
 
 	ast_channel_tech_set(tmp, &agent_tech);
@@ -1329,7 +1333,7 @@
 		if (!p->abouttograb && p->pending && ((p->group && (newlyavailable->group & p->group)) || !strcmp(p->agent, newlyavailable->agent))) {
 			ast_debug(1, "Call '%s' looks like a winner for agent '%s'\n", ast_channel_name(p->owner), newlyavailable->agent);
 			/* We found a pending call, time to merge */
-			chan = agent_new(newlyavailable, AST_STATE_DOWN, p->owner ? ast_channel_linkedid(p->owner) : NULL);
+			chan = agent_new(newlyavailable, AST_STATE_DOWN, p->owner ? ast_channel_linkedid(p->owner) : NULL, NULL);
 			parent = p->owner;
 			p->abouttograb = 1;
 			ast_mutex_unlock(&p->lock);
@@ -1422,6 +1426,7 @@
 	int waitforagent=0;
 	int hasagent = 0;
 	struct timeval now;
+	struct ast_callid *callid = ast_read_threadstorage_callid();
 
 	s = data;
 	if ((s[0] == '@') && (sscanf(s + 1, "%30d", &groupoff) == 1)) {
@@ -1445,7 +1450,7 @@
 				/* Agent must be registered, but not have any active call, and not be in a waiting state */
 				if (!p->owner && p->chan) {
 					/* Fixed agent */
-					chan = agent_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL);
+					chan = agent_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL, callid);
 				}
 				if (chan) {
 					ast_mutex_unlock(&p->lock);
@@ -1468,7 +1473,7 @@
 					/* Agent must be registered, but not have any active call, and not be in a waiting state */
 					if (!p->owner && p->chan) {
 						/* Could still get a fixed agent */
-						chan = agent_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL);
+						chan = agent_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL, callid);
 					}
 					if (chan) {
 						ast_mutex_unlock(&p->lock);
@@ -1487,7 +1492,7 @@
 			ast_debug(1, "Creating place holder for '%s'\n", s);
 			p = add_agent(data, 1);
 			p->group = groupmatch;
-			chan = agent_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL);
+			chan = agent_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL, callid);
 			if (!chan) 
 				ast_log(LOG_WARNING, "Weird...  Fix this to drop the unused pending agent\n");
 		} else {
@@ -1496,6 +1501,10 @@
 	}
 	*cause = hasagent ? AST_CAUSE_BUSY : AST_CAUSE_UNREGISTERED;
 	AST_LIST_UNLOCK(&agents);
+
+	if (callid) {
+		callid = ast_callid_unref(callid);
+	}
 
 	if (chan) {
 		ast_mutex_lock(&p->lock);

Modified: trunk/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_dahdi.c?view=diff&rev=369414&r1=369413&r2=369414
==============================================================================
--- trunk/channels/chan_dahdi.c (original)
+++ trunk/channels/chan_dahdi.c Tue Jun 26 16:45:22 2012
@@ -2577,14 +2577,25 @@
 	return;
 }
 
-static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linkedid);
+/*!
+ * \internal
+ * \brief performs duties of dahdi_new, but also removes and possibly unbinds (if callid_created is 1) before returning
+ * \note this variant of dahdi should only be used in conjunction with ast_callid_threadstorage_auto()
+ *
+ * \param callid_created value returned from ast_callid_threadstorage_auto()
+ */
+static struct ast_channel *dahdi_new_callid_clean(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linked, struct ast_callid *callid, int callid_created);
+
+static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linkedid, struct ast_callid *callid);
 
 static struct ast_channel *my_new_analog_ast_channel(void *pvt, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor)
 {
+	struct ast_callid *callid = NULL;
+	int callid_created = ast_callid_threadstorage_auto(&callid);
 	struct dahdi_pvt *p = pvt;
 	int dsub = analogsub_to_dahdisub(sub);
 
-	return dahdi_new(p, state, startpbx, dsub, 0, requestor ? ast_channel_linkedid(requestor) : "");
+	return dahdi_new_callid_clean(p, state, startpbx, dsub, 0, requestor ? ast_channel_linkedid(requestor) : "", callid, callid_created);
 }
 
 #if defined(HAVE_PRI) || defined(HAVE_SS7)
@@ -2604,6 +2615,8 @@
 	struct dahdi_pvt *p = pvt;
 	int audio;
 	int newlaw = -1;
+	struct ast_callid *callid = NULL;
+	int callid_created = ast_callid_threadstorage_auto(&callid);
 
 	switch (p->sig) {
 	case SIG_PRI_LIB_HANDLE_CASES:
@@ -2639,7 +2652,8 @@
 			newlaw = DAHDI_LAW_MULAW;
 			break;
 	}
-	return dahdi_new(p, state, 0, SUB_REAL, newlaw, requestor ? ast_channel_linkedid(requestor) : "");
+
+	return dahdi_new_callid_clean(p, state, 0, SUB_REAL, newlaw, requestor ? ast_channel_linkedid(requestor) : "", callid, callid_created);
 }
 #endif	/* defined(HAVE_PRI) */
 
@@ -3519,6 +3533,8 @@
 	struct dahdi_pvt *p = pvt;
 	int audio;
 	int newlaw;
+	struct ast_callid *callid = NULL;
+	int callid_created = ast_callid_threadstorage_auto(&callid);
 
 	/* Set to audio mode at this point */
 	audio = 1;
@@ -3545,7 +3561,7 @@
 		newlaw = DAHDI_LAW_MULAW;
 		break;
 	}
-	return dahdi_new(p, state, 0, SUB_REAL, newlaw, requestor ? ast_channel_linkedid(requestor) : "");
+	return dahdi_new_callid_clean(p, state, 0, SUB_REAL, newlaw, requestor ? ast_channel_linkedid(requestor) : "", callid, callid_created);
 }
 #endif	/* defined(HAVE_SS7) */
 
@@ -3986,6 +4002,8 @@
 {
 	struct dahdi_pvt *p;
 	struct ast_channel *c;
+	struct ast_callid *callid = NULL;
+	int callid_created = ast_callid_threadstorage_auto(&callid);
 	ast_verbose("MFC/R2 call offered on chan %d. ANI = %s, DNIS = %s, Category = %s\n",
 			openr2_chan_get_number(r2chan), ani ? ani : "(restricted)", dnis,
 			openr2_proto_get_category_string(category));
@@ -3994,7 +4012,7 @@
 	if (!p->mfcr2_allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) {
 		ast_log(LOG_NOTICE, "Rejecting MFC/R2 collect call\n");
 		dahdi_r2_disconnect_call(p, OR2_CAUSE_COLLECT_CALL_REJECTED);
-		return;
+		goto dahdi_r2_on_call_offered_cleanup;
 	}
 	ast_mutex_lock(&p->lock);
 	p->mfcr2_recvd_category = category;
@@ -4015,16 +4033,16 @@
 		ast_log(LOG_NOTICE, "MFC/R2 call on channel %d requested non-existent extension '%s' in context '%s'. Rejecting call.\n",
 				p->channel, p->exten, p->context);
 		dahdi_r2_disconnect_call(p, OR2_CAUSE_UNALLOCATED_NUMBER);
-		return;
+		goto dahdi_r2_on_call_offered_cleanup;
 	}
 	if (!p->mfcr2_accept_on_offer) {
 		/* The user wants us to start the PBX thread right away without accepting the call first */
-		c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL);
+		c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL, callid);
 		if (c) {
 			/* Done here, don't disable reading now since we still need to generate MF tones to accept
 			   the call or reject it and detect the tone off condition of the other end, all of this
 			   will be done in the PBX thread now */
-			return;
+			goto dahdi_r2_on_call_offered_cleanup;
 		}
 		ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel);
 		dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
@@ -4035,6 +4053,9 @@
 		ast_debug(1, "Accepting MFC/R2 call with no charge on chan %d\n", p->channel);
 		openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE);
 	}
+
+dahdi_r2_on_call_offered_cleanup:
+	ast_callid_threadstorage_auto_clean(callid, callid_created);
 }
 
 static void dahdi_r2_on_call_end(openr2_chan_t *r2chan)
@@ -4051,6 +4072,8 @@
 {
 	struct dahdi_pvt *p = NULL;
 	struct ast_channel *c = NULL;
+	struct ast_callid *callid = NULL;
+	int callid_created = ast_callid_threadstorage_auto(&callid);
 	p = openr2_chan_get_client_data(r2chan);
 	dahdi_enable_ec(p);
 	p->mfcr2_call_accepted = 1;
@@ -4067,19 +4090,19 @@
 				ast_debug(1, "Answering MFC/R2 call after accepting it on chan %d\n", openr2_chan_get_number(r2chan));
 				dahdi_r2_answer(p);
 			}
-			return;
-		}
-		c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL);
+			goto dahdi_r2_on_call_accepted_cleanup;
+		}
+		c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL, callid);
 		if (c) {
 			/* chan_dahdi will take care of reading from now on in the PBX thread, tell the
 			   library to forget about it */
 			openr2_chan_disable_read(r2chan);
-			return;
+			goto dahdi_r2_on_call_accepted_cleanup;
 		}
 		ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel);
 		/* failed to create the channel, bail out and report it as an out of order line */
 		dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
-		return;
+		goto dahdi_r2_on_call_accepted_cleanup;
 	}
 	/* this is an outgoing call, no need to launch the PBX thread, most likely we're in one already */
 	ast_verbose("MFC/R2 call has been accepted on forward channel %d\n", p->channel);
@@ -4087,6 +4110,9 @@
 	p->dialing = 0;
 	/* chan_dahdi will take care of reading from now on in the PBX thread, tell the library to forget about it */
 	openr2_chan_disable_read(r2chan);
+
+dahdi_r2_on_call_accepted_cleanup:
+	ast_callid_threadstorage_auto_clean(callid, callid_created);
 }
 
 static void dahdi_r2_on_call_answered(openr2_chan_t *r2chan)
@@ -8590,6 +8616,8 @@
 					p->subs[SUB_REAL].needflash = 1;
 					goto winkflashdone;
 				} else if (!check_for_conference(p)) {
+					struct ast_callid *callid = NULL;
+					int callid_created;
 					char cid_num[256];
 					char cid_name[256];
 
@@ -8619,7 +8647,7 @@
 						ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
 						goto winkflashdone;
 					}
-
+					callid_created = ast_callid_threadstorage_auto(&callid);
 					/*
 					 * Make new channel
 					 *
@@ -8628,7 +8656,7 @@
 					 */
 					ast_mutex_unlock(&p->lock);
 					ast_channel_unlock(ast);
-					chan = dahdi_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, NULL);
+					chan = dahdi_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, NULL, callid);
 					ast_channel_lock(ast);
 					ast_mutex_lock(&p->lock);
 					if (p->dahditrcallerid) {
@@ -8665,6 +8693,7 @@
 						}
 						p->subs[SUB_THREEWAY].needhold = 1;
 					}
+					ast_callid_threadstorage_auto_clean(callid, callid_created);
 				}
 			} else {
 				/* Already have a 3 way call */
@@ -9699,7 +9728,16 @@
 	return chan_name;
 }
 
-static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linkedid)
+static struct ast_channel *dahdi_new_callid_clean(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linkedid, struct ast_callid *callid, int callid_created)
+{
+	struct ast_channel *new_channel = dahdi_new(i, state, startpbx, idx, law, linkedid, callid);
+
+	ast_callid_threadstorage_auto_clean(callid, callid_created);
+
+	return new_channel;
+}
+
+static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linkedid, struct ast_callid *callid)
 {
 	struct ast_channel *tmp;
 	struct ast_format deflaw;
@@ -9731,8 +9769,14 @@
 
 	tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "DAHDI/%s", ast_str_buffer(chan_name));
 	ast_free(chan_name);
-	if (!tmp)
+	if (!tmp) {
 		return NULL;
+	}
+
+	if (callid) {
+		ast_channel_callid_set(tmp, callid);
+	}
+
 	ast_channel_tech_set(tmp, &dahdi_tech);
 #if defined(HAVE_PRI)
 	if (i->pri) {
@@ -11197,6 +11241,8 @@
 
 		if (i & DAHDI_IOMUX_SIGEVENT) {
 			struct ast_channel *chan;
+			struct ast_callid *callid = NULL;
+			int callid_created;
 
 			/* If we get an event, screen out events that we do not act on.
 			 * Otherwise, cancel and go to the simple switch to let it deal with it.
@@ -11229,13 +11275,14 @@
 				handle_alarms(mtd->pvt, res);
 				break; /* What to do on channel alarm ???? -- fall thru intentionally?? */
 			default:
+				callid_created = ast_callid_threadstorage_auto(&callid);
 				ast_log(LOG_NOTICE, "Got event %d (%s)...  Passing along to analog_ss_thread\n", res, event2str(res));
 				callerid_free(cs);
 
 				restore_gains(mtd->pvt);
 				mtd->pvt->ringt = mtd->pvt->ringt_base;
 
-				if ((chan = dahdi_new(mtd->pvt, AST_STATE_RING, 0, SUB_REAL, 0, NULL))) {
+				if ((chan = dahdi_new(mtd->pvt, AST_STATE_RING, 0, SUB_REAL, 0, NULL, callid))) {
 					int result;
 
 					if (analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) {
@@ -11253,6 +11300,8 @@
 				} else {
 					ast_log(LOG_WARNING, "Could not create channel to handle call\n");
 				}
+
+				ast_callid_threadstorage_auto_clean(callid, callid_created);
 				goto quit_no_clean;
 			}
 		} else if (i & DAHDI_IOMUX_READ) {
@@ -11532,6 +11581,8 @@
 	int res;
 	pthread_t threadid;
 	struct ast_channel *chan;
+	struct ast_callid *callid = NULL;
+	int callid_created;
 
 	/* Handle an event on a given channel for the monitor thread. */
 
@@ -11549,8 +11600,11 @@
 		case SIG_FXOGS:
 		case SIG_FXOKS:
 			res = dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
-			if (res && (errno == EBUSY))
+			if (res && (errno == EBUSY)) {
 				break;
+			}
+
+			callid_created = ast_callid_threadstorage_auto(&callid);
 
 			/* Cancel VMWI spill */
 			ast_free(i->cidspill);
@@ -11561,7 +11615,7 @@
 				dahdi_enable_ec(i);
 				/* The channel is immediately up.  Start right away */
 				res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
-				chan = dahdi_new(i, AST_STATE_RING, 1, SUB_REAL, 0, NULL);
+				chan = dahdi_new(i, AST_STATE_RING, 1, SUB_REAL, 0, NULL, callid);
 				if (!chan) {
 					ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
 					res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
@@ -11570,7 +11624,7 @@
 				}
 			} else {
 				/* Check for callerid, digits, etc */
-				chan = dahdi_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, NULL);
+				chan = dahdi_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, NULL, callid);
 				if (chan) {
 					if (has_voicemail(i))
 						res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER);
@@ -11588,6 +11642,8 @@
 				} else
 					ast_log(LOG_WARNING, "Unable to create channel\n");
 			}
+
+			ast_callid_threadstorage_auto_clean(callid, callid_created);
 			break;
 		case SIG_FXSLS:
 		case SIG_FXSGS:
@@ -11610,10 +11666,11 @@
 		case SIG_SF_FEATB:
 		case SIG_SF:
 			/* Check for callerid, digits, etc */
+			callid_created = ast_callid_threadstorage_auto(&callid);
 			if (i->cid_start == CID_START_POLARITY_IN) {
-				chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL);
+				chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, callid);
 			} else {
-				chan = dahdi_new(i, AST_STATE_RING, 0, SUB_REAL, 0, NULL);
+				chan = dahdi_new(i, AST_STATE_RING, 0, SUB_REAL, 0, NULL, callid);
 			}
 
 			if (!chan) {
@@ -11626,6 +11683,8 @@
 				}
 				ast_hangup(chan);
 			}
+
+			ast_callid_threadstorage_auto_clean(callid, callid_created);
 			break;
 		default:
 			ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
@@ -11731,6 +11790,7 @@
 			   created, but it wasn't handled. We need polarity
 			   to be REV for remote hangup detection to work.
 			   At least in Spain */
+			callid_created = ast_callid_threadstorage_auto(&callid);
 			if (i->hanguponpolarityswitch)
 				i->polarity = POLARITY_REV;
 			if (i->cid_start == CID_START_POLARITY || i->cid_start == CID_START_POLARITY_IN) {
@@ -11738,13 +11798,14 @@
 				ast_verb(2, "Starting post polarity "
 					"CID detection on channel %d\n",
 					i->channel);
-				chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL);
+				chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, callid);
 				if (!chan) {
 					ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
 				} else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
 					ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
 				}
 			}
+			ast_callid_threadstorage_auto_clean(callid, callid_created);
 			break;
 		default:
 			ast_log(LOG_WARNING, "handle_init_event detected "
@@ -12003,7 +12064,9 @@
 										doomed = analog_handle_init_event(i->sig_pvt, ANALOG_EVENT_DTMFCID);  
 										i->dtmfcid_holdoff_state = 1;
 									} else {
-										chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL);
+										struct ast_callid *callid = NULL;
+										int callid_created = ast_callid_threadstorage_auto(&callid);
+										chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, callid);
 										if (!chan) {
 											ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
 										} else {
@@ -12014,6 +12077,7 @@
 												i->dtmfcid_holdoff_state = 1;
 											}
 										}
+										ast_callid_threadstorage_auto_clean(callid, callid_created);
 									}
 									ast_mutex_lock(&iflock);
 								}
@@ -13772,12 +13836,15 @@
 	int transcapdigital = 0;
 #endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) */
 	struct dahdi_starting_point start;
+	struct ast_callid *callid = NULL;
+	int callid_created = ast_callid_threadstorage_auto(&callid);
 
 	ast_mutex_lock(&iflock);
 	p = determine_starting_point(data, &start);
 	if (!p) {
 		/* We couldn't determine a starting point, which likely means badly-formatted channel name. Abort! */
 		ast_mutex_unlock(&iflock);
+		ast_callid_threadstorage_auto_clean(callid, callid_created);
 		return NULL;
 	}
 
@@ -13858,7 +13925,7 @@
 				tmp = sig_ss7_request(p->sig_pvt, SIG_SS7_DEFLAW, requestor, transcapdigital);
 #endif	/* defined(HAVE_SS7) */
 			} else {
-				tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, requestor ? ast_channel_linkedid(requestor) : "");
+				tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, requestor ? ast_channel_linkedid(requestor) : "", callid);
 			}
 			if (!tmp) {
 				p->outgoing = 0;
@@ -13917,6 +13984,7 @@
 		}
 	}
 
+	ast_callid_threadstorage_auto_clean(callid, callid_created);
 	return tmp;
 }
 
@@ -14090,12 +14158,12 @@
 	if (ss7) {
 		for (i = 0; i < NUM_SPANS; i++) {
 			if (linksets[i].ss7.ss7 == ss7) {
-				ast_verbose("[%d] %s", i + 1, s);
+				ast_verbose_callid(NULL, "[%d] %s", i + 1, s);
 				return;
 			}
 		}
 	}
-	ast_verbose("%s", s);
+	ast_verbose_callid(NULL, "%s", s);
 }
 #endif	/* defined(HAVE_SS7) */
 
@@ -14107,12 +14175,12 @@
 	if (ss7) {
 		for (i = 0; i < NUM_SPANS; i++) {
 			if (linksets[i].ss7.ss7 == ss7) {
-				ast_log(LOG_ERROR, "[%d] %s", i + 1, s);
+				ast_log_callid(LOG_ERROR, NULL, "[%d] %s", i + 1, s);
 				return;
 			}
 		}
 	}
-	ast_log(LOG_ERROR, "%s", s);
+	ast_log_callid(LOG_ERROR, NULL, "%s", s);
 }
 #endif	/* defined(HAVE_SS7) */
 
@@ -14225,22 +14293,22 @@
 		}
 		if (-1 < span) {
 			if (1 < dchancount) {
-				ast_verbose("[PRI Span: %d D-Channel: %d] %s", span + 1, dchan, s);
+				ast_verbose_callid(NULL, "[PRI Span: %d D-Channel: %d] %s", span + 1, dchan, s);
 			} else {
-				ast_verbose("PRI Span: %d %s", span + 1, s);
+				ast_verbose_callid(NULL, "PRI Span: %d %s", span + 1, s);
 			}
 		} else {
-			ast_verbose("PRI Span: ? %s", s);
+			ast_verbose_callid(NULL, "PRI Span: ? %s", s);
 		}
 	} else {
-		ast_verbose("PRI Span: ? %s", s);
+		ast_verbose_callid(NULL, "PRI Span: ? %s", s);
 	}
 
 	ast_mutex_lock(&pridebugfdlock);
 
 	if (pridebugfd >= 0) {
 		if (write(pridebugfd, s, strlen(s)) < 0) {
-			ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
+			ast_log_callid(LOG_WARNING, NULL, "write() failed: %s\n", strerror(errno));
 		}
 	}
 
@@ -14276,22 +14344,22 @@
 		}
 		if (-1 < span) {
 			if (1 < dchancount) {
-				ast_log(LOG_ERROR, "[PRI Span: %d D-Channel: %d] %s", span + 1, dchan, s);
+				ast_log_callid(LOG_ERROR, NULL, "[PRI Span: %d D-Channel: %d] %s", span + 1, dchan, s);
 			} else {
-				ast_log(LOG_ERROR, "PRI Span: %d %s", span + 1, s);
+				ast_log_callid(LOG_ERROR, NULL, "PRI Span: %d %s", span + 1, s);
 			}
 		} else {
-			ast_log(LOG_ERROR, "PRI Span: ? %s", s);
+			ast_log_callid(LOG_ERROR, NULL, "PRI Span: ? %s", s);
 		}
 	} else {
-		ast_log(LOG_ERROR, "PRI Span: ? %s", s);
+		ast_log_callid(LOG_ERROR, NULL, "PRI Span: ? %s", s);
 	}
 
 	ast_mutex_lock(&pridebugfdlock);
 
 	if (pridebugfd >= 0) {
 		if (write(pridebugfd, s, strlen(s)) < 0) {
-			ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
+			ast_log_callid(LOG_WARNING, NULL, "write() failed: %s\n", strerror(errno));
 		}
 	}
 

Modified: trunk/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_iax2.c?view=diff&rev=369414&r1=369413&r2=369414
==============================================================================
--- trunk/channels/chan_iax2.c (original)
+++ trunk/channels/chan_iax2.c Tue Jun 26 16:45:22 2012
@@ -653,6 +653,8 @@
 struct chan_iax2_pvt {
 	/*! Socket to send/receive on for this call */
 	int sockfd;
+	/*! ast_callid bound to dialog */
+	struct ast_callid *callid;
 	/*! Last received voice format */
 	iax2_format voiceformat;
 	/*! Last received video format */
@@ -1067,6 +1069,33 @@
  */
 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS + 1];
 
+static struct ast_callid *iax_pvt_callid_get(int callno)
+{
+	if (iaxs[callno]->callid) {
+		return ast_callid_ref(iaxs[callno]->callid);
+	}
+	return NULL;
+}
+
+static void iax_pvt_callid_set(int callno, struct ast_callid *callid)
+{
+	if (iaxs[callno]->callid) {
+		ast_callid_unref(iaxs[callno]->callid);
+	}
+	ast_callid_ref(callid);
+	iaxs[callno]->callid = callid;
+}
+
+static void iax_pvt_callid_new(int callno)
+{
+	struct ast_callid *callid = ast_create_callid();
+	char buffer[AST_CALLID_BUFFER_LENGTH];
+	ast_callid_strnprint(buffer, sizeof(buffer), callid);
+	ast_log(LOG_NOTICE, "iax_pvt_callid_new created and set %s\n", buffer);
+	iax_pvt_callid_set(callno, callid);
+	ast_callid_unref(callid);
+}
+
 /*!
  * \brief Another container of iax2_pvt structures
  *
@@ -1986,6 +2015,11 @@
 		jb_destroy(pvt->jb);
 		ast_string_field_free_memory(pvt);
 	}
+
+	if (pvt->callid) {
+		ast_callid_unref(pvt->callid);
+	}
+
 }
 
 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
@@ -5750,6 +5784,7 @@
 	struct chan_iax2_pvt *i;
 	struct ast_variable *v = NULL;
 	struct ast_format tmpfmt;
+	struct ast_callid *callid;
 
 	if (!(i = iaxs[callno])) {
 		ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
@@ -5770,8 +5805,14 @@
 		return NULL;
 	}
 	iax2_ami_channelupdate(i);
-	if (!tmp)
+	if (!tmp) {
 		return NULL;
+	}
+
+	if ((callid = iaxs[callno]->callid)) {
+		ast_channel_callid_set(tmp, callid);
+	}
+
 	ast_channel_tech_set(tmp, &iax2_tech);
 	/* We can support any format by default, until we get restricted */
 	ast_format_cap_from_old_bitfield(ast_channel_nativeformats(tmp), capability);
@@ -9920,7 +9961,7 @@
 	}
 }
 
-static int socket_process(struct iax2_thread *thread)
+static int socket_process_helper(struct iax2_thread *thread)
 {
 	struct sockaddr_in sin;
 	int res;
@@ -10103,8 +10144,15 @@
 		}
 	}
 
-	if (fr->callno > 0)
+	if (fr->callno > 0) {
+		struct ast_callid *mount_callid;
 		ast_mutex_lock(&iaxsl[fr->callno]);
+		if ((mount_callid = iax_pvt_callid_get(fr->callno))) {
+			/* Bind to thread */
+			ast_callid_threadassoc_add(mount_callid);
+			ast_callid_unref(mount_callid);
+		}
+	}
 
 	if (!fr->callno || !iaxs[fr->callno]) {
 		/* A call arrived for a nonexistent destination.  Unless it's an "inval"
@@ -10791,6 +10839,9 @@
 												using_prefs);
 
 								iaxs[fr->callno]->chosenformat = format;
+
+								/* Since this is a new call, we should go ahead and set the callid for it. */
+								iax_pvt_callid_new(fr->callno);
 								ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
 							} else {
 								ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
@@ -11732,6 +11783,17 @@
 	return 1;
 }
 
+static int socket_process(struct iax2_thread *thread)
+{
+	struct ast_callid *callid;
+	int res = socket_process_helper(thread);
+	if ((callid = ast_read_threadstorage_callid())) {
+		ast_callid_threadassoc_remove();
+		callid = ast_callid_unref(callid);
+	}
+	return res;
+}
+
 /* Function to clean up process thread if it is cancelled */
 static void iax2_process_thread_cleanup(void *data)
 {
@@ -12204,10 +12266,13 @@
 	struct parsed_dial_string pds;
 	struct create_addr_info cai;
 	char *tmpstr;
+	struct ast_callid *callid;
 
 	memset(&pds, 0, sizeof(pds));
 	tmpstr = ast_strdupa(data);
 	parse_dial_string(tmpstr, &pds);
+
+	callid = ast_read_threadstorage_callid();
 
 	if (ast_strlen_zero(pds.peer)) {
 		ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
@@ -12242,15 +12307,22 @@
 			callno = new_callno;
 	}
 	iaxs[callno]->maxtime = cai.maxtime;
-	if (cai.found)
+	if (callid) {
+		iax_pvt_callid_set(callno, callid);
+	}
+
+	if (cai.found) {
 		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);
-
 	ast_mutex_unlock(&iaxsl[callno]);
 
 	if (c) {
 		struct ast_format_cap *joint;
+		if (callid) {
+			ast_channel_callid_set(c, callid);
+		}
 
 		/* Choose a format we can live with */
 		if ((joint = ast_format_cap_joint(ast_channel_nativeformats(c), cap))) {
@@ -12274,6 +12346,9 @@
 		ast_format_copy(ast_channel_writeformat(c), ast_channel_readformat(c));
 	}
 
+	if (callid) {
+		ast_callid_unref(callid);
+	}
 	return c;
 }
 

Modified: trunk/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_local.c?view=diff&rev=369414&r1=369413&r2=369414
==============================================================================
--- trunk/channels/chan_local.c (original)
+++ trunk/channels/chan_local.c Tue Jun 26 16:45:22 2012
@@ -1161,7 +1161,7 @@
 }
 
 /*! \brief Start new local channel */
-static struct ast_channel *local_new(struct local_pvt *p, int state, const char *linkedid)
+static struct ast_channel *local_new(struct local_pvt *p, int state, const char *linkedid, struct ast_callid *callid)
 {
 	struct ast_channel *tmp = NULL, *tmp2 = NULL;
 	int randnum = ast_random() & 0xffff;
@@ -1190,6 +1190,11 @@
 		}
 		ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n");
 		return NULL;
+	}
+
+	if (callid) {
+		ast_channel_callid_set(tmp, callid);
+		ast_channel_callid_set(tmp2, callid);
 	}
 
 	ast_channel_tech_set(tmp, &local_tech);
@@ -1233,13 +1238,15 @@
 {
 	struct local_pvt *p;
 	struct ast_channel *chan;
+	struct ast_callid *callid = ast_read_threadstorage_callid();
 
 	/* Allocate a new private structure and then Asterisk channel */
 	p = local_alloc(data, cap);
 	if (!p) {
-		return NULL;
-	}
-	chan = local_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL);
+		chan = NULL;
+		goto local_request_end;
+	}
+	chan = local_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL, callid);
 	if (!chan) {
 		ao2_unlink(locals, p);
 	} else if (ast_channel_cc_params_init(chan, requestor ? ast_channel_get_cc_config_params((struct ast_channel *)requestor) : NULL)) {
@@ -1252,6 +1259,12 @@
 	}
 	ao2_ref(p, -1); /* kill the ref from the alloc */
 
+local_request_end:
+
+	if (callid) {
+		ast_callid_unref(callid);
+	}
+
 	return chan;
 }
 

Modified: trunk/channels/sig_analog.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/sig_analog.c?view=diff&rev=369414&r1=369413&r2=369414
==============================================================================
--- trunk/channels/sig_analog.c (original)
+++ trunk/channels/sig_analog.c Tue Jun 26 16:45:22 2012
@@ -1770,6 +1770,7 @@
 	int len = 0;
 	int res;
 	int idx;
+	struct ast_callid *callid;
 
 	analog_increase_ss_count(p);
 
@@ -1779,6 +1780,12 @@
 		/* What happened to the channel? */
 		goto quit;
 	}
+
+	if ((callid = ast_channel_callid(chan))) {
+		ast_callid_threadassoc_add(callid);
+		ast_callid_unref(callid);
+	}
+
 	/* in the bizarre case where the channel has become a zombie before we
 	   even get started here, abort safely
 	*/
@@ -3220,6 +3227,8 @@
 					ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_FLASH);
 					goto winkflashdone;
 				} else if (!analog_check_for_conference(p)) {
+					struct ast_callid *callid = NULL;
+					int callid_created;
 					char cid_num[256];
 					char cid_name[256];
 
@@ -3249,6 +3258,8 @@
 						ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
 						goto winkflashdone;
 					}
+
+					callid_created = ast_callid_threadstorage_auto(&callid);
 
 					/*
 					 * Make new channel
@@ -3266,6 +3277,7 @@
 							"Cannot allocate new call structure on channel %d\n",
 							p->channel);
 						analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
+						ast_callid_threadstorage_auto_clean(callid, callid_created);
 						goto winkflashdone;
 					}
 					if (p->dahditrcallerid) {
@@ -3303,6 +3315,7 @@
 								!ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
 						}
 					}
+					ast_callid_threadstorage_auto_clean(callid, callid_created);
 				}
 			} else {
 				/* Already have a 3 way call */
@@ -3687,6 +3700,8 @@
 	int res;
 	pthread_t threadid;
 	struct ast_channel *chan;
+	struct ast_callid *callid = NULL;
+	int callid_created;
 
 	ast_debug(1, "channel (%d) - signaling (%d) - event (%s)\n",
 				i->channel, i->sig, analog_event2str(event));
@@ -3708,6 +3723,7 @@
 			if (res && (errno == EBUSY)) {
 				break;
 			}
+			callid_created = ast_callid_threadstorage_auto(&callid);
 
 			/* Cancel VMWI spill */
 			analog_cancel_cidspill(i);
@@ -3748,6 +3764,7 @@
 				} else
 					ast_log(LOG_WARNING, "Unable to create channel\n");
 			}
+			ast_callid_threadstorage_auto_clean(callid, callid_created);
 			break;
 		case ANALOG_SIG_FXSLS:
 		case ANALOG_SIG_FXSGS:
@@ -3769,6 +3786,7 @@
 		case ANALOG_SIG_SF_FEATDMF:
 		case ANALOG_SIG_SF_FEATB:
 		case ANALOG_SIG_SF:
+			callid_created = ast_callid_threadstorage_auto(&callid);
 			/* Check for callerid, digits, etc */
 			if (i->cid_start == ANALOG_CID_START_POLARITY_IN || i->cid_start == ANALOG_CID_START_DTMF_NOALERT) {
 				chan = analog_new_ast_channel(i, AST_STATE_PRERING, 0, ANALOG_SUB_REAL, NULL);
@@ -3786,6 +3804,7 @@
 				}
 				ast_hangup(chan);
 			}
+			ast_callid_threadstorage_auto_clean(callid, callid_created);
 			break;
 		default:
 			ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", analog_sigtype_to_str(i->sig), i->channel);
@@ -3859,6 +3878,7 @@
 		case ANALOG_SIG_FXSLS:
 		case ANALOG_SIG_FXSKS:
 		case ANALOG_SIG_FXSGS:
+			callid_created = ast_callid_threadstorage_auto(&callid);
 			/* We have already got a PR before the channel was
 			   created, but it wasn't handled. We need polarity
 			   to be REV for remote hangup detection to work.
@@ -3879,6 +3899,7 @@
 					ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
 				}
 			}
+			ast_callid_threadstorage_auto_clean(callid, callid_created);
 			break;
 		default:
 			ast_log(LOG_WARNING, "handle_init_event detected "
@@ -3892,6 +3913,7 @@
 		case ANALOG_SIG_FXSLS:
 		case ANALOG_SIG_FXSKS:
 		case ANALOG_SIG_FXSGS:
+			callid_created = ast_callid_threadstorage_auto(&callid);
 			if (i->cid_start == ANALOG_CID_START_DTMF_NOALERT) {
 				ast_verb(2, "Starting DTMF CID detection on channel %d\n",
 					i->channel);
@@ -3903,6 +3925,7 @@
 					ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
 				}
 			}
+			ast_callid_threadstorage_auto_clean(callid, callid_created);
 			break;
 		default:
 			ast_log(LOG_WARNING, "handle_init_event detected "

Modified: trunk/channels/sig_pri.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/sig_pri.c?view=diff&rev=369414&r1=369413&r2=369414
==============================================================================
--- trunk/channels/sig_pri.c (original)
+++ trunk/channels/sig_pri.c Tue Jun 26 16:45:22 2012
@@ -1867,6 +1867,12 @@
 	char ex[80];
 	/* Wait up to 30 seconds for an answer */
 	int newms, ms = 30000;
+	struct ast_callid *callid;
+
+	if ((callid = ast_channel_callid(chan))) {
+		ast_callid_threadassoc_add(callid);
+		callid = ast_callid_unref(callid);
+	}
 
 	ast_verb(3, "Initiating idle call on channel %s\n", ast_channel_name(chan));
 	snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial);
@@ -1916,10 +1922,16 @@
 	int res;
 	int len;
 	int timeout;
+	struct ast_callid *callid;
 
 	if (!chan) {
 		/* We lost the owner before we could get started. */
 		return NULL;
+	}
+
+	if ((callid = ast_channel_callid(chan))) {
+		ast_callid_threadassoc_add(callid);
+		ast_callid_unref(callid);
 	}
 
 	/*
@@ -5151,6 +5163,60 @@
 }
 #endif	/* defined(HAVE_PRI_CALL_HOLD) */
 
+/*!
+ * \internal
+ * \brief Set callid threadstorage for the pri_dchannel thread when a new call is created
+ *
+ * \return A new callid which has been bound to threadstorage. The return must be
+ *         unreffed and the threadstorage should be unbound when the pri_dchannel
+ *         primary loop wraps.
+ */
+static struct ast_callid *func_pri_dchannel_new_callid(void)
+{
+	struct ast_callid *callid = ast_create_callid();
+
+	if (callid) {
+		ast_callid_threadassoc_add(callid);
+	}
+
+	return callid;
+}
+
+/*!
+ * \internal
+ * \brief Set callid threadstorage for the pri_dchannel thread to that of an existing channel
+ *
+ * \param pri PRI span control structure.
+ * \param chanpos channel position in the span
+ *
+ * \note Assumes the pri->lock is already obtained.
+ * \note Assumes the sig_pri_lock_private(pri->pvts[chanpos]) is already obtained.
+ *
+ * \return a reference to the callid bound to the channel which has also
+ *         been bound to threadstorage if it exists. If this returns non-NULL,
+ *         the callid must be unreffed and the threadstorage should be unbound
+ *         when the pri_dchannel primary loop wraps.
+ */
+static struct ast_callid *func_pri_dchannel_chanpos_callid(struct sig_pri_span *pri, int chanpos)
+{
+	if (chanpos < 0) {
+		return NULL;
+	}
+
+	sig_pri_lock_owner(pri, chanpos);
+	if (pri->pvts[chanpos]->owner) {
+		struct ast_callid *callid;
+		callid = ast_channel_callid(pri->pvts[chanpos]->owner);
+		ast_channel_unlock(pri->pvts[chanpos]->owner);
+		if (callid) {
+			ast_callid_threadassoc_add(callid);
+			return callid;
+		}
+	}
+
+	return NULL;
+}
+
 #if defined(HAVE_PRI_CALL_HOLD)
 /*!
  * \internal
@@ -5171,6 +5237,7 @@
 	int chanpos_old;
 	int chanpos_new;
 	struct ast_channel *owner;
+	struct ast_callid *callid = NULL;
 
 	chanpos_old = pri_find_principle_by_call(pri, ev->hold.call);
 	if (chanpos_old < 0) {
@@ -5190,6 +5257,13 @@
 	if (!owner) {
 		goto done_with_private;
 	}
+
+	callid = ast_channel_callid(owner);
+
+	if (callid) {
+		ast_callid_threadassoc_add(callid);
+	}
+
 	if (pri->pvts[chanpos_old]->call_level != SIG_PRI_CALL_LEVEL_CONNECT) {
 		/*
 		 * Make things simple.  Don't allow placing a call on hold that
@@ -5224,6 +5298,11 @@
 		retval = 0;
 	}
 
+	if (callid) {
+		ast_callid_unref(callid);
+		ast_callid_threadassoc_remove();
+	}
+
 	return retval;
 }
 #endif	/* defined(HAVE_PRI_CALL_HOLD) */
@@ -5244,6 +5323,7 @@
 static void sig_pri_handle_hold_ack(struct sig_pri_span *pri, pri_event *ev)
 {
 	int chanpos;
+	struct ast_callid *callid;
 
 	/*
 	 * We were successfully put on hold by the remote party
@@ -5266,11 +5346,18 @@
 	}
 
 	sig_pri_lock_private(pri->pvts[chanpos]);
+	callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
+
 	sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->hold_ack.subcmds, ev->hold_ack.call);
 	sig_pri_moh_fsm_event(pri->pvts[chanpos]->owner, pri->pvts[chanpos],
 		SIG_PRI_MOH_EVENT_HOLD_ACK);
 	sig_pri_unlock_private(pri->pvts[chanpos]);
 	sig_pri_span_devstate_changed(pri);
+
+	if (callid) {
+		ast_callid_unref(callid);
+		ast_callid_threadassoc_remove();
+	}
 }
 #endif	/* defined(HAVE_PRI_CALL_HOLD) */
 
@@ -5290,6 +5377,7 @@
 static void sig_pri_handle_hold_rej(struct sig_pri_span *pri, pri_event *ev)
 {
 	int chanpos;
+	struct ast_callid *callid;
 
 	chanpos = pri_find_principle(pri, ev->hold_rej.channel, ev->hold_rej.call);
 	if (chanpos < 0) {
@@ -5309,10 +5397,17 @@
 		ev->hold_rej.cause, pri_cause2str(ev->hold_rej.cause));
 
 	sig_pri_lock_private(pri->pvts[chanpos]);
+	callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
+
 	sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->hold_rej.subcmds, ev->hold_rej.call);
 	sig_pri_moh_fsm_event(pri->pvts[chanpos]->owner, pri->pvts[chanpos],
 		SIG_PRI_MOH_EVENT_HOLD_REJ);
 	sig_pri_unlock_private(pri->pvts[chanpos]);
+
+	if (callid) {
+		ast_callid_unref(callid);
+		ast_callid_threadassoc_remove();
+	}
 }
 #endif	/* defined(HAVE_PRI_CALL_HOLD) */
 
@@ -5332,6 +5427,7 @@
 static void sig_pri_handle_retrieve(struct sig_pri_span *pri, pri_event *ev)
 {
 	int chanpos;
+	struct ast_callid *callid;
 
 	if (!(ev->retrieve.channel & PRI_HELD_CALL)) {
 		/* The call is not currently held. */
@@ -5373,6 +5469,7 @@
 		return;
 	}
 	sig_pri_lock_private(pri->pvts[chanpos]);
+	callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
 	sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve.subcmds, ev->retrieve.call);
 	sig_pri_lock_owner(pri, chanpos);
 	pri_queue_control(pri, chanpos, AST_CONTROL_UNHOLD);
@@ -5386,6 +5483,11 @@
 		SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK);
 	sig_pri_unlock_private(pri->pvts[chanpos]);
 	sig_pri_span_devstate_changed(pri);
+
+	if (callid) {
+		ast_callid_unref(callid);
+		ast_callid_threadassoc_remove();
+	}
 }
 #endif	/* defined(HAVE_PRI_CALL_HOLD) */
 
@@ -5405,6 +5507,7 @@
 static void sig_pri_handle_retrieve_ack(struct sig_pri_span *pri, pri_event *ev)
 {
 	int chanpos;
+	struct ast_callid *callid;
 
 	chanpos = pri_find_fixup_principle(pri, ev->retrieve_ack.channel,
 		ev->retrieve_ack.call);
@@ -5413,12 +5516,19 @@
 	}
 
 	sig_pri_lock_private(pri->pvts[chanpos]);
+	callid = func_pri_dchannel_chanpos_callid(pri, chanpos);
+

[... 669 lines stripped ...]



More information about the asterisk-commits mailing list