[asterisk-commits] jrose: branch jrose/call_identifiers r363675 - in /team/jrose/call_identifier...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Apr 25 12:33:43 CDT 2012


Author: jrose
Date: Wed Apr 25 12:33:38 2012
New Revision: 363675

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=363675
Log:
Unreviewed phase 3 changes

Modified:
    team/jrose/call_identifiers/channels/chan_dahdi.c
    team/jrose/call_identifiers/channels/chan_iax2.c
    team/jrose/call_identifiers/channels/chan_sip.c
    team/jrose/call_identifiers/channels/sip/include/dialog.h
    team/jrose/call_identifiers/channels/sip/include/sip.h
    team/jrose/call_identifiers/include/asterisk/channel.h
    team/jrose/call_identifiers/include/asterisk/logger.h
    team/jrose/call_identifiers/main/channel.c
    team/jrose/call_identifiers/main/channel_internal_api.c
    team/jrose/call_identifiers/main/cli.c
    team/jrose/call_identifiers/main/logger.c
    team/jrose/call_identifiers/main/pbx.c

Modified: team/jrose/call_identifiers/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/call_identifiers/channels/chan_dahdi.c?view=diff&rev=363675&r1=363674&r2=363675
==============================================================================
--- team/jrose/call_identifiers/channels/chan_dahdi.c (original)
+++ team/jrose/call_identifiers/channels/chan_dahdi.c Wed Apr 25 12:33:38 2012
@@ -2577,14 +2577,26 @@
 	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;
+	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 +2616,8 @@
 	struct dahdi_pvt *p = pvt;
 	int audio;
 	int newlaw = -1;
+	struct ast_callid *callid;
+	int callid_created = ast_callid_threadstorage_auto(&callid);
 
 	switch (p->sig) {
 	case SIG_PRI_LIB_HANDLE_CASES:
@@ -2639,7 +2653,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) */
 
@@ -8565,6 +8580,8 @@
 					p->subs[SUB_REAL].needflash = 1;
 					goto winkflashdone;
 				} else if (!check_for_conference(p)) {
+					struct ast_callid *callid;
+					int callid_created;
 					char cid_num[256];
 					char cid_name[256];
 
@@ -8594,8 +8611,10 @@
 						ast_log(LOG_WARNING, "Unable to allocate three-way subchannel\n");
 						goto winkflashdone;
 					}
+					callid_created = ast_callid_threadstorage_auto(&callid);
+
 					/* Make new channel */
-					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);
 					if (p->dahditrcallerid) {
 						if (!p->origcid_num)
 							p->origcid_num = ast_strdup(p->cid_num);
@@ -8630,6 +8649,8 @@
 						}
 						p->subs[SUB_THREEWAY].needhold = 1;
 					}
+					ast_callid_threadstorage_auto_clean(callid, callid_created);
+
 				}
 			} else {
 				/* Already have a 3 way call */
@@ -9653,7 +9674,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;
@@ -9685,8 +9715,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) {
@@ -11151,6 +11187,8 @@
 
 		if (i & DAHDI_IOMUX_SIGEVENT) {
 			struct ast_channel *chan;
+			struct ast_callid *callid;
+			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.
@@ -11183,13 +11221,15 @@
 				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)) {
@@ -11207,6 +11247,9 @@
 				} 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) {
@@ -11487,6 +11530,9 @@
 	pthread_t threadid;
 	struct ast_channel *chan;
 
+	struct ast_callid *callid;
+	int callid_created;
+
 	/* Handle an event on a given channel for the monitor thread. */
 
 	switch (event) {
@@ -11503,8 +11549,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);
@@ -11515,7 +11564,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);
@@ -11524,7 +11573,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);
@@ -11542,6 +11591,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:
@@ -11564,10 +11615,12 @@
 		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) {
@@ -11580,6 +11633,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);
@@ -11685,6 +11740,8 @@
 			   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) {
@@ -11692,13 +11749,15 @@
 				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 "
@@ -11958,7 +12017,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;
+										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 {
@@ -11969,6 +12030,7 @@
 												i->dtmfcid_holdoff_state = 1;
 											}
 										}
+										ast_callid_threadstorage_auto_clean(callid, callid_created);
 									}
 									ast_mutex_lock(&iflock);
 								}
@@ -13813,7 +13875,10 @@
 				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) : "");
+				struct ast_callid *callid;
+				int callid_created = ast_callid_threadstorage_auto(&callid);
+				tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, requestor ? ast_channel_linkedid(requestor) : "", callid);
+				ast_callid_threadstorage_auto_clean(callid, callid_created);
 			}
 			if (!tmp) {
 				p->outgoing = 0;

Modified: team/jrose/call_identifiers/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/call_identifiers/channels/chan_iax2.c?view=diff&rev=363675&r1=363674&r2=363675
==============================================================================
--- team/jrose/call_identifiers/channels/chan_iax2.c (original)
+++ team/jrose/call_identifiers/channels/chan_iax2.c Wed Apr 25 12:33:38 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[13];
+	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
  *
@@ -1985,6 +2014,12 @@
 		jb_destroy(pvt->jb);
 		ast_string_field_free_memory(pvt);
 	}
+
+	/* JON XXX clear reference to unique callid. */
+	if (pvt->callid) {
+		ast_callid_unref(pvt->callid);
+	}
+
 }
 
 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
@@ -5729,6 +5764,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);
@@ -5749,8 +5785,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);
@@ -9888,7 +9930,7 @@
 	}
 }
 
-static int socket_process(struct iax2_thread *thread)
+static int socket_process_helper(struct iax2_thread *thread)
 {
 	struct sockaddr_in sin;
 	int res;
@@ -10071,8 +10113,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"
@@ -10703,6 +10752,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);
@@ -11644,6 +11696,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)
 {
@@ -12115,10 +12178,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);
@@ -12153,15 +12219,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))) {
@@ -12185,6 +12258,9 @@
 		ast_format_copy(ast_channel_writeformat(c), ast_channel_readformat(c));
 	}
 
+	if (callid) {
+		ast_callid_unref(callid);
+	}
 	return c;
 }
 

Modified: team/jrose/call_identifiers/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/call_identifiers/channels/chan_sip.c?view=diff&rev=363675&r1=363674&r2=363675
==============================================================================
--- team/jrose/call_identifiers/channels/chan_sip.c (original)
+++ team/jrose/call_identifiers/channels/chan_sip.c Wed Apr 25 12:33:38 2012
@@ -1940,7 +1940,7 @@
 		return -1;
 	}
 
-	if (!(monitor_instance->subscription_pvt = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL))) {
+	if (!(monitor_instance->subscription_pvt = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL, NULL))) {
 		return -1;
 	}
 
@@ -5967,6 +5967,11 @@
 	p->peercaps = ast_format_cap_destroy(p->peercaps);
 	p->redircaps = ast_format_cap_destroy(p->redircaps);
 	p->prefcaps = ast_format_cap_destroy(p->prefcaps);
+
+	/* Lastly, kill the callid associated with the pvt */
+	if (p->logger_callid) {
+		ast_callid_unref(p->logger_callid);
+	}
 }
 
 /*! \brief  update_call_counter: Handle call_limit for SIP devices
@@ -7107,7 +7112,7 @@
  *
  * \return New ast_channel locked.
  */
-static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *title, const char *linkedid)
+static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *title, const char *linkedid, struct ast_callid *callid)
 {
 	struct ast_channel *tmp;
 	struct ast_variable *v = NULL;
@@ -7136,6 +7141,12 @@
 		sip_pvt_lock(i);
 		return NULL;
 	}
+
+	/* If we sent in a callid, bind it to the channel. */
+	if (callid) {
+		ast_channel_callid_set(tmp, callid);
+	}
+
 	ast_channel_lock(tmp);
 	sip_pvt_lock(i);
 	ast_channel_cc_params_init(tmp, i->cc_params);
@@ -7782,12 +7793,21 @@
 	return p->stimer;
 }
 
+static void sip_pvt_callid_set(struct sip_pvt *pvt, struct ast_callid *callid)
+{
+	if (pvt->logger_callid) {
+		ast_callid_unref(pvt->logger_callid);
+	}
+	ast_callid_ref(callid);
+	pvt->logger_callid = callid;
+}
+
 /*! \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.
  */
 struct sip_pvt *sip_alloc(ast_string_field callid, struct ast_sockaddr *addr,
-				 int useglobal_nat, const int intended_method, struct sip_request *req)
+				 int useglobal_nat, const int intended_method, struct sip_request *req, struct ast_callid *logger_callid)
 {
 	struct sip_pvt *p;
 
@@ -7803,6 +7823,11 @@
 		ao2_t_ref(p, -1, "Yuck, couldn't allocate cc_params struct. Get rid o' p");
 		return NULL;
 	}
+
+	if (logger_callid) {
+		sip_pvt_callid_set(p, logger_callid);
+	}
+
 	p->caps = ast_format_cap_alloc_nolock();
 	p->jointcaps = ast_format_cap_alloc_nolock();
 	p->peercaps = ast_format_cap_alloc_nolock();
@@ -8171,7 +8196,7 @@
 {
 	struct sip_pvt *p;
 
-	if (!(p = sip_alloc(original->callid, addr, 1, SIP_INVITE, req)))  {
+	if (!(p = sip_alloc(original->callid, addr, 1, SIP_INVITE, req, NULL)))  {
 		return; /* alloc error */
 	}
 	p->invitestate = INV_TERMINATED;
@@ -8426,7 +8451,7 @@
 			transmit_response_using_temp(callid, addr, 1, intended_method, req, "603 Declined (no dialog)");
 	
 		/* Ok, time to create a new SIP dialog object, a pvt */
-		} else if (!(p = sip_alloc(callid, addr, 1, intended_method, req)))  {
+		} else if (!(p = sip_alloc(callid, addr, 1, intended_method, req, NULL)))  {
 			/* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
 				getting a dialog from sip_alloc.
 
@@ -12581,7 +12606,7 @@
 
 	epa_entry->publish_type = publish_type;
 
-	if (!(pvt = sip_alloc(NULL, NULL, 0, SIP_PUBLISH, NULL))) {
+	if (!(pvt = sip_alloc(NULL, NULL, 0, SIP_PUBLISH, NULL, NULL))) {
 		return -1;
 	}
 
@@ -12889,7 +12914,7 @@
 	}
 	
 	/* Create a dialog that we will use for the subscription */
-	if (!(mwi->call = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL))) {
+	if (!(mwi->call = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL, NULL))) {
 		return -1;
 	}
 
@@ -13371,7 +13396,7 @@
 		channame += 4;
 	}
 
-	if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) {
+	if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL, NULL))) {
 		astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)");
 		return 0;
 	}
@@ -13692,7 +13717,7 @@
 			r->callid_valid = TRUE;
 		}
 		/* Allocate SIP dialog for registration */
-		if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER, NULL))) {
+		if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER, NULL, NULL))) {
 			ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
 			return 0;
 		}
@@ -19821,7 +19846,7 @@
 		char buf[512];
 		struct ast_variable *header, *var;
 
-		if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) {
+		if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL, NULL))) {
 			ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n");
 			return CLI_FAILURE;
 		}
@@ -23577,6 +23602,7 @@
 			res = INV_REQ_FAILED;
 			goto request_invite_cleanup;
 		} else {
+			struct ast_callid *callid;
 
 			/* If no extension was specified, use the s one */
 			/* Basically for calling to IP/Host name only */
@@ -23587,7 +23613,17 @@
 			make_our_tag(p->tag, sizeof(p->tag));
 			/* First invitation - create the channel.  Allocation
 			 * failures are handled below. */
-			c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL), NULL);
+
+			callid = ast_create_callid();
+			sip_pvt_callid_set(p, callid);
+			if (callid) {
+				ast_callid_threadassoc_add(p->logger_callid);
+			}
+
+			c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL), NULL, callid);
+
+			callid = ast_callid_unref(callid);
+
 			if (cc_recall_core_id != -1) {
 				ast_setup_cc_recall_datastore(c, cc_recall_core_id);
 				ast_cc_agent_set_interfaces_chanvar(c);
@@ -24892,7 +24928,7 @@
 	struct ast_msg_var_iterator *iter;
 	struct sip_peer *peer_ptr;
 
-	if (!(pvt = sip_alloc(NULL, NULL, 0, SIP_MESSAGE, NULL))) {
+	if (!(pvt = sip_alloc(NULL, NULL, 0, SIP_MESSAGE, NULL, NULL))) {
 		return -1;
 	}
 
@@ -26420,6 +26456,10 @@
 		return 1;
 	}
 
+	if (p->logger_callid) {
+		ast_callid_threadassoc_add(p->logger_callid);
+	}
+
 	/* Lock both the pvt and the owner if owner is present.  This will
 	 * not fail. */
 	owner_chan_ref = sip_pvt_lock_full(p);
@@ -26453,6 +26493,10 @@
 	sip_pvt_unlock(p);
 	ao2_t_ref(p, -1, "throw away dialog ptr from find_call at end of routine"); /* p is gone after the return */
 	ast_mutex_unlock(&netlock);
+
+	if (p->logger_callid) {
+		ast_callid_threadassoc_remove();
+	}
 
 	return 1;
 }
@@ -26722,7 +26766,7 @@
 	} else {
 		ao2_unlock(peer);
 		/* Build temporary dialog for this message */
-		if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) {
+		if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL, NULL))) {
 			return -1;
 		}
 
@@ -27374,7 +27418,7 @@
 		peer->call = dialog_unref(peer->call, "unref dialog peer->call");
 		/* peer->call = sip_destroy(peer->call); */
 	}
-	if (!(p = sip_alloc(NULL, NULL, 0, SIP_OPTIONS, NULL))) {
+	if (!(p = sip_alloc(NULL, NULL, 0, SIP_OPTIONS, NULL, NULL))) {
 		return -1;
 	}
 	peer->call = dialog_ref(p, "copy sip alloc from p to peer->call");
@@ -27561,6 +27605,7 @@
 	char *remote_address;
 	enum sip_transport transport = 0;
 	struct ast_sockaddr remote_address_sa = { {0,} };
+	struct ast_callid *callid;
 	AST_DECLARE_APP_ARGS(args,
 		AST_APP_ARG(peerorhost);
 		AST_APP_ARG(exten);
@@ -27589,9 +27634,13 @@
 		return NULL;
 	}
 
-	if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE, NULL))) {
+	callid = ast_read_threadstorage_callid();
+	if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE, NULL, callid))) {
 		ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", dest);
 		*cause = AST_CAUSE_SWITCH_CONGESTION;
+		if (callid) {
+			ast_callid_unref(callid);
+		}
 		return NULL;
 	}
 
@@ -27606,6 +27655,9 @@
 		/* sip_destroy(p); */
 		ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
 		*cause = AST_CAUSE_SWITCH_CONGESTION;
+		if (callid) {
+			ast_callid_unref(callid);
+		}
 		return NULL;
 	}
 
@@ -27693,6 +27745,9 @@
 		dialog_unlink_all(p);
 		dialog_unref(p, "unref dialog p UNREGISTERED");
 		/* sip_destroy(p); */
+		if (callid) {
+			ast_callid_unref(callid);
+		}
 		return NULL;
 	}
 	if (ast_strlen_zero(p->peername) && ext)
@@ -27728,7 +27783,12 @@
 	ast_format_cap_joint_copy(cap, p->caps, p->jointcaps);
 
 	sip_pvt_lock(p);
-	tmpc = sip_new(p, AST_STATE_DOWN, host, requestor ? ast_channel_linkedid(requestor) : NULL);	/* Place the call */
+
+	tmpc = sip_new(p, AST_STATE_DOWN, host, requestor ? ast_channel_linkedid(requestor) : NULL, callid);	/* Place the call */
+	if (callid) {
+		callid = ast_callid_unref(callid);
+	}
+
 	if (sip_cfg.callevents)
 		manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
 			"Channel: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n",

Modified: team/jrose/call_identifiers/channels/sip/include/dialog.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/call_identifiers/channels/sip/include/dialog.h?view=diff&rev=363675&r1=363674&r2=363675
==============================================================================
--- team/jrose/call_identifiers/channels/sip/include/dialog.h (original)
+++ team/jrose/call_identifiers/channels/sip/include/dialog.h Wed Apr 25 12:33:38 2012
@@ -35,7 +35,7 @@
 struct sip_pvt *dialog_unref_debug(struct sip_pvt *p, const char *tag, char *file, int line, const char *func);
 
 struct sip_pvt *sip_alloc(ast_string_field callid, struct ast_sockaddr *sin,
-				 int useglobal_nat, const int intended_method, struct sip_request *req);
+				 int useglobal_nat, const int intended_method, struct sip_request *req, struct ast_callid *logger_callid);
 void sip_scheddestroy_final(struct sip_pvt *p, int ms);
 void sip_scheddestroy(struct sip_pvt *p, int ms);
 int sip_cancel_destroy(struct sip_pvt *p);

Modified: team/jrose/call_identifiers/channels/sip/include/sip.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/call_identifiers/channels/sip/include/sip.h?view=diff&rev=363675&r1=363674&r2=363675
==============================================================================
--- team/jrose/call_identifiers/channels/sip/include/sip.h (original)
+++ team/jrose/call_identifiers/channels/sip/include/sip.h Wed Apr 25 12:33:38 2012
@@ -988,6 +988,7 @@
 struct sip_pvt {
 	struct sip_pvt *next;                   /*!< Next dialog in chain */
 	enum invitestates invitestate;          /*!< Track state of SIP_INVITEs */
+	struct ast_callid *logger_callid;		/*!< Identifier for call used in log messages */
 	int method;                             /*!< SIP method that opened this dialog */
 	AST_DECLARE_STRING_FIELDS(
 		AST_STRING_FIELD(callid);       /*!< Global CallID */

Modified: team/jrose/call_identifiers/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/call_identifiers/include/asterisk/channel.h?view=diff&rev=363675&r1=363674&r2=363675
==============================================================================
--- team/jrose/call_identifiers/include/asterisk/channel.h (original)
+++ team/jrose/call_identifiers/include/asterisk/channel.h Wed Apr 25 12:33:38 2012
@@ -3661,12 +3661,15 @@
 enum ast_channel_adsicpe ast_channel_adsicpe(const struct ast_channel *chan);
 void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value);
 enum ast_channel_state ast_channel_state(const struct ast_channel *chan);
+struct ast_callid *ast_channel_callid(const struct ast_channel *chan);
+void ast_channel_callid_set(struct ast_channel *chan, struct ast_callid *value);
 
 /* XXX Internal use only, make sure to move later */
 void ast_channel_state_set(struct ast_channel *chan, enum ast_channel_state);
 void ast_channel_softhangup_internal_flag_set(struct ast_channel *chan, int value);
 void ast_channel_softhangup_internal_flag_add(struct ast_channel *chan, int value);
 void ast_channel_softhangup_internal_flag_clear(struct ast_channel *chan, int value);
+void ast_channel_callid_cleanup(struct ast_channel *chan);
 int ast_channel_softhangup_internal_flag(struct ast_channel *chan);
 
 /* Format getters */

Modified: team/jrose/call_identifiers/include/asterisk/logger.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/call_identifiers/include/asterisk/logger.h?view=diff&rev=363675&r1=363674&r2=363675
==============================================================================
--- team/jrose/call_identifiers/include/asterisk/logger.h (original)
+++ team/jrose/call_identifiers/include/asterisk/logger.h Wed Apr 25 12:33:38 2012
@@ -279,9 +279,43 @@
  */
 int ast_callid_threadassoc_add(struct ast_callid *callid);
 
-/*
- * May need a function to clean the threadstorage if we want to repurpose a thread.
- */
+/*!
+ * \brief Removes callid from thread storage of the calling thread
+ *
+ * \retval 0 - success
+ * \retval non-zero - failure
+ */
+int ast_callid_threadassoc_remove(void);
+
+/*!
+ * \brief Checks thread storage for a callid and stores a reference if it exists.
+ *        If not, then a new one will be created, bound to the thread, and a reference
+ *        to it will be stored.
+ *
+ * \param callid pointer to struct pointer used to store the referenced callid
+ * \retval 0 - callid was found
+ * \retval 1 - callid was created
+ * \retval -1 - the function failed somehow (presumably memory problems)
+ */
+int ast_callid_threadstorage_auto(struct ast_callid **callid);
+
+/*!
+ * \brief Use in conjunction with ast_callid_threadstorage_auto. Cleans up the
+ *        references and if the callid was created by threadstorage_auto, unbinds
+ *        the callid from the threadstorage
+ * \param callid The callid set by ast_callid_threadstorage_auto
+ * \param callid_created The integer returned through ast_callid_threadstorage_auto
+ */
+void ast_callid_threadstorage_auto_clean(struct ast_callid *callid, int callid_created);
+
+/*!
+ * \brief copy a string representation of the callid into a target string
+ *
+ * \param buffer destination of callid string (should be able to store 13 characters or more)
+ * \param buffer_size maximum writable length of the string (Less than 13 will result in truncation)
+ * \param callid Callid for which string is being requested
+ */
+void ast_callid_strnprint(char *buffer, size_t buffer_size, struct ast_callid *callid);
 
 /*!
  * \brief Send a log message to a dynamically registered log level

Modified: team/jrose/call_identifiers/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/call_identifiers/main/channel.c?view=diff&rev=363675&r1=363674&r2=363675
==============================================================================
--- team/jrose/call_identifiers/main/channel.c (original)
+++ team/jrose/call_identifiers/main/channel.c Wed Apr 25 12:33:38 2012
@@ -2177,6 +2177,7 @@
 	struct varshead *headp;
 	struct ast_datastore *datastore;
 	char device_name[AST_CHANNEL_NAME];
+	struct ast_callid *callid;
 
 	if (ast_channel_internal_is_finalized(chan)) {
 		ast_cel_report_event(chan, AST_CEL_CHANNEL_END, NULL, NULL, NULL);
@@ -2188,6 +2189,11 @@
 	while ((datastore = AST_LIST_REMOVE_HEAD(ast_channel_datastores(chan), entry)))
 		/* Free the data store */
 		ast_datastore_free(datastore);
+
+	/* While the channel is locked, take the reference to its callid while we tear down the call. */
+	callid = ast_channel_callid(chan);
+	ast_channel_callid_cleanup(chan);
+
 	ast_channel_unlock(chan);
 
 	/* Lock and unlock the channel just to be sure nobody has it locked still
@@ -2196,7 +2202,7 @@
 	ast_channel_unlock(chan);
 
 	if (ast_channel_tech_pvt(chan)) {
-		ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", ast_channel_name(chan));
+		ast_log_callid(LOG_WARNING, callid, "Channel '%s' may not have been hung up properly\n", ast_channel_name(chan));
 		ast_free(ast_channel_tech_pvt(chan));
 	}
 
@@ -2229,7 +2235,7 @@
 	if (ast_channel_writetrans(chan))
 		ast_translator_free_path(ast_channel_writetrans(chan));
 	if (ast_channel_pbx(chan))
-		ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", ast_channel_name(chan));
+		ast_log_callid(LOG_WARNING, callid, "PBX may not have been terminated properly on '%s'\n", ast_channel_name(chan));
 
 	ast_party_dialed_free(ast_channel_dialed(chan));
 	ast_party_caller_free(ast_channel_caller(chan));
@@ -2286,6 +2292,9 @@
 	}
 
 	ast_channel_nativeformats_set(chan, ast_format_cap_destroy(ast_channel_nativeformats(chan)));
+	if (callid) {
+		ast_callid_unref(callid);
+	}
 }
 
 /*! \brief Free a dummy channel structure */
@@ -5648,6 +5657,16 @@
 			ast_format_cap_destroy(joint_cap);
 			return NULL;
 		}
+
+		/* Set newly created channel callid to same as the requestor */
+		if (requestor) {
+			struct ast_callid *callid = ast_channel_callid(requestor);
+			if (callid) {
+				ast_channel_callid_set(c, callid);
+				callid = ast_callid_unref(callid);
+			}
+		}
+
 		joint_cap = ast_format_cap_destroy(joint_cap);
 
 		if (set_security_requirements(requestor, c)) {

Modified: team/jrose/call_identifiers/main/channel_internal_api.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/call_identifiers/main/channel_internal_api.c?view=diff&rev=363675&r1=363674&r2=363675
==============================================================================
--- team/jrose/call_identifiers/main/channel_internal_api.c (original)
+++ team/jrose/call_identifiers/main/channel_internal_api.c Wed Apr 25 12:33:38 2012
@@ -82,6 +82,7 @@
 	struct ast_tone_zone *zone;			/*!< Tone zone as set in indications.conf or
 							 *   in the CHANNEL dialplan function */
 	struct ast_channel_monitor *monitor;		/*!< Channel monitoring */
+	struct ast_callid *callid;			/*!< Bound call identifier pointer */
 #ifdef HAVE_EPOLL
 	struct ast_epoll_data *epfd_data[AST_MAX_FDS];
 #endif
@@ -829,6 +830,31 @@
 {
 	return chan->state;
 }
+struct ast_callid *ast_channel_callid(const struct ast_channel *chan)
+{
+	if (chan->callid) {
+		ast_callid_ref(chan->callid);
+		return chan->callid;
+	}
+	return NULL;
+}
+void ast_channel_callid_set(struct ast_channel *chan, struct ast_callid *callid)
+{
+	if (chan->callid) {
+
+		if ((option_debug >= 3) || (ast_opt_dbg_module && ast_debug_get_by_module(AST_MODULE) >= 3)) {
+			char call_identifier_from[13];
+			char call_identifier_to[13];
+			ast_callid_strnprint(call_identifier_from, sizeof(call_identifier_from), chan->callid);
+			ast_callid_strnprint(call_identifier_to, sizeof(call_identifier_to), callid);
+			ast_log(LOG_DEBUG, "Channel Call ID changing from %s to %s\n", call_identifier_from, call_identifier_to);
+		}
+
+		/* unbind if already set */
+		ast_callid_unref(chan->callid);
+	}
+	chan->callid = ast_callid_ref(callid);
+}
 void ast_channel_state_set(struct ast_channel *chan, enum ast_channel_state value)
 {
 	chan->state = value;
@@ -954,6 +980,13 @@
 void ast_channel_softhangup_internal_flag_clear(struct ast_channel *chan, int value)
 {
 	chan ->softhangup &= ~value;
+}
+
+void ast_channel_callid_cleanup(struct ast_channel *chan)
+{
+	if (chan->callid) {
+		chan->callid = ast_callid_unref(chan->callid);
+	}
 }
 
 /* Typedef accessors */

Modified: team/jrose/call_identifiers/main/cli.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/call_identifiers/main/cli.c?view=diff&rev=363675&r1=363674&r2=363675
==============================================================================
--- team/jrose/call_identifiers/main/cli.c (original)
+++ team/jrose/call_identifiers/main/cli.c Wed Apr 25 12:33:38 2012
@@ -1393,6 +1393,8 @@
 	struct ast_str *output;/*!< Accumulation buffer for all output. */
 	long elapsed_seconds=0;
 	int hour=0, min=0, sec=0;
+	struct ast_callid *callid;
+	char call_identifier_str[13];
 #ifdef CHANNEL_TRACE
 	int trace_enabled;
 #endif
@@ -1438,6 +1440,12 @@
 		snprintf(cdrtime, sizeof(cdrtime), "%dh%dm%ds", hour, min, sec);
 	} else {
 		strcpy(cdrtime, "N/A");
+	}
+
+	/* Construct the call identifier string based on the status of the channel's call identifier */
+	if ((callid = ast_channel_callid(c))) {
+		ast_callid_strnprint(call_identifier_str, sizeof(call_identifier_str), callid);
+		ast_callid_unref(callid);
 	}
 
 	ast_str_append(&output, 0,
@@ -1474,7 +1482,8 @@
 		"   Pickup Group: %llu\n"
 		"    Application: %s\n"
 		"           Data: %s\n"
-		"    Blocking in: %s\n",
+		"    Blocking in: %s\n"
+		" Call Identifer: %s\n",
 		ast_channel_name(c), ast_channel_tech(c)->type, ast_channel_uniqueid(c), ast_channel_linkedid(c),
 		S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, "(N/A)"),
 		S_COR(ast_channel_caller(c)->id.name.valid, ast_channel_caller(c)->id.name.str, "(N/A)"),
@@ -1497,7 +1506,8 @@
 		cdrtime, ast_channel_internal_bridged_channel(c) ? ast_channel_name(ast_channel_internal_bridged_channel(c)) : "<none>", ast_bridged_channel(c) ? ast_channel_name(ast_bridged_channel(c)) : "<none>",
 		ast_channel_context(c), ast_channel_exten(c), ast_channel_priority(c), ast_channel_callgroup(c), ast_channel_pickupgroup(c), (ast_channel_appl(c) ? ast_channel_appl(c) : "(N/A)" ),
 		(ast_channel_data(c) ? S_OR(ast_channel_data(c), "(Empty)") : "(None)"),
-		(ast_test_flag(ast_channel_flags(c), AST_FLAG_BLOCKING) ? ast_channel_blockproc(c) : "(Not Blocking)"));
+		(ast_test_flag(ast_channel_flags(c), AST_FLAG_BLOCKING) ? ast_channel_blockproc(c) : "(Not Blocking)"),
+		S_OR(call_identifier_str, "(None)"));
 
 	if (pbx_builtin_serialize_variables(c, &obuf)) {
 		ast_str_append(&output, 0, "      Variables:\n%s\n", ast_str_buffer(obuf));

Modified: team/jrose/call_identifiers/main/logger.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/call_identifiers/main/logger.c?view=diff&rev=363675&r1=363674&r2=363675
==============================================================================
--- team/jrose/call_identifiers/main/logger.c (original)
+++ team/jrose/call_identifiers/main/logger.c Wed Apr 25 12:33:38 2012
@@ -1236,6 +1236,11 @@
 	AST_RWLIST_UNLOCK(&logchannels);
 }
 
+void ast_callid_strnprint(char *buffer, size_t buffer_size, struct ast_callid *callid)
+{
+	snprintf(buffer, buffer_size, "[C-%08x]", callid->call_identifier);
+}
+
 struct ast_callid *ast_create_callid(void)
 {
 	struct ast_callid *call;
@@ -1249,7 +1254,7 @@
 	using = ast_atomic_fetchadd_int(&next_unique_callid, +1);
 
 	call->call_identifier = using;
-	ast_log(LOG_DEBUG, "CALL_ID [C-%08x] created by thread.\n", call->call_identifier);
+	ast_debug(3, "CALL_ID [C-%08x] created by thread.\n", call->call_identifier);
 	return call;
 }
 
@@ -1279,13 +1284,66 @@
 		/* callid will be unreffed at thread destruction */
 		ast_callid_ref(callid);
 		*pointing = callid;
-		ast_log(LOG_DEBUG, "CALL_ID [C-%08x] bound to thread.\n", callid->call_identifier);
+		ast_debug(3, "CALL_ID [C-%08x] bound to thread.\n", callid->call_identifier);
 	} else {
 		ast_log(LOG_WARNING, "Attempted to ast_callid_threadassoc_add on thread already associated with a callid.\n");
 		return 1;
 	}
 
 	return 0;
+}
+
+int ast_callid_threadassoc_remove()
+{
+	struct ast_callid **pointing;
+	pointing = ast_threadstorage_get(&unique_callid, sizeof(struct ast_callid **));
+	if (!(pointing)) {

[... 222 lines stripped ...]



More information about the asterisk-commits mailing list