[asterisk-commits] file: branch file/bridging r79916 - in /team/file/bridging: ./ apps/ channels...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Aug 17 16:38:22 CDT 2007


Author: file
Date: Fri Aug 17 16:38:21 2007
New Revision: 79916

URL: http://svn.digium.com/view/asterisk?view=rev&rev=79916
Log:
Merged revisions 79841,79858-79862,79885,79888,79894,79901,79903,79905,79907,79913,79915 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
r79841 | crichter | 2007-08-17 05:29:56 -0300 (Fri, 17 Aug 2007) | 9 lines

Merged revisions 79833 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r79833 | crichter | 2007-08-17 10:22:36 +0200 (Fr, 17 Aug 2007) | 1 line

sometimes we don't need to signal dtmf tones to asterisk, we just want them to go through as inband. Otherwise they might be generated by the other channel partner and then there is a double tone.
........

................
r79858 | russell | 2007-08-17 10:39:17 -0300 (Fri, 17 Aug 2007) | 13 lines

Merged revisions 79857 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r79857 | russell | 2007-08-17 08:37:08 -0500 (Fri, 17 Aug 2007) | 5 lines

Fix some crashes in chan_sip.  This patch changes various places that add items
to the scheduler to ensure that they don't overwrite the ID of a previously
scheduled item.  If there is one, it should be removed.
(closes issue #10391, closes issue #10256, probably others, patch by me)

........

................
r79859 | tilghman | 2007-08-17 10:40:11 -0300 (Fri, 17 Aug 2007) | 2 lines

store and destroy implementations for realtime pgsql (closes issue #10372)

................
r79860 | tilghman | 2007-08-17 10:45:44 -0300 (Fri, 17 Aug 2007) | 2 lines

store and destroy implementations for sqlite (closes issue #10446) and odbc (closes issue #10447)

................
r79861 | russell | 2007-08-17 11:07:44 -0300 (Fri, 17 Aug 2007) | 12 lines

This commit adds a scheduler API call, ast_sched_replace that can be used
in place of a very common construct.  I also used it in a number of places
in chan_sip.

  if (id > -1)
     ast_sched_del(sched, id);
  id = ast_sched_add(sched, ...);

changes to:

  ast_sched_replace(id, sched, ...);

................
r79862 | russell | 2007-08-17 11:14:59 -0300 (Fri, 17 Aug 2007) | 2 lines

Make use of ast_sched_replace() in some places in chan_iax2

................
r79885 | tilghman | 2007-08-17 11:41:33 -0300 (Fri, 17 Aug 2007) | 2 lines

Change this flag... might not otherwise unlock in an OOM situation

................
r79888 | qwell | 2007-08-17 12:27:19 -0300 (Fri, 17 Aug 2007) | 4 lines

Correct the argument separator for a Dial statement in pbx_dundi.

Closes issue #10483, patch by lunn

................
r79894 | qwell | 2007-08-17 13:04:20 -0300 (Fri, 17 Aug 2007) | 4 lines

Fix Dial arguments in res_features.

Closes issue #10484, patch by lunn.

................
r79901 | tilghman | 2007-08-17 13:39:41 -0300 (Fri, 17 Aug 2007) | 2 lines

Documentation for %q in logger.conf, as suggested by jtodd (closes issue #10475)

................
r79903 | qwell | 2007-08-17 14:45:01 -0300 (Fri, 17 Aug 2007) | 13 lines

Merged revisions 79902 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

(closes issue #10485)
........
r79902 | qwell | 2007-08-17 12:44:22 -0500 (Fri, 17 Aug 2007) | 4 lines

Re-add the setting of callerid name and number.

Issue 10485, reported by and fix explained by paradise.

........

................
r79905 | qwell | 2007-08-17 16:13:25 -0300 (Fri, 17 Aug 2007) | 20 lines

Merged revisions 79904 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

(closes issue #10430)
........
r79904 | qwell | 2007-08-17 14:12:19 -0500 (Fri, 17 Aug 2007) | 11 lines

Don't send a semicolon over the wire in sip notify messages.
Caused by fix for issue 9938.

I basically took the code that existed before 9938 was fixed, and
 copied it into a new function - ast_unescape_semicolon

There should be very few places this will be needed (pbx_config
 does NOT need this (see issue 9938 for details))

Issue 10430, patch by me, with help/ideas from murf (thanks murf).

........

................
r79907 | mmichelson | 2007-08-17 16:16:51 -0300 (Fri, 17 Aug 2007) | 14 lines

Merged revisions 79906 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r79906 | mmichelson | 2007-08-17 14:14:05 -0500 (Fri, 17 Aug 2007) | 6 lines

Patch allows for more seamless transition from file storage voicemail to ODBC storage voicemail.
If a retrieval of a greeting from the database fails, but the file is found on the file system, then
we go ahead an insert the greeting into the database. The result of this is that people who
switch from file storage to ODBC storage do not need to rerecord their voicemail greetings.


........

................
r79913 | russell | 2007-08-17 18:04:33 -0300 (Fri, 17 Aug 2007) | 12 lines

Merged revisions 79912 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r79912 | russell | 2007-08-17 16:01:43 -0500 (Fri, 17 Aug 2007) | 4 lines

Avoid a crash in the handling of DTMF based Caller ID.  It is valid for
ast_read to return NULL in the case that the channel has been hung up.
(crash reported by anonymouz666 on IRC in #asterisk-dev)

........

................
r79915 | mmichelson | 2007-08-17 18:19:18 -0300 (Fri, 17 Aug 2007) | 3 lines

I broke the build. Now I'm fixing it.


................

Modified:
    team/file/bridging/   (props changed)
    team/file/bridging/apps/app_voicemail.c
    team/file/bridging/channels/chan_iax2.c
    team/file/bridging/channels/chan_local.c
    team/file/bridging/channels/chan_misdn.c
    team/file/bridging/channels/chan_sip.c
    team/file/bridging/channels/chan_zap.c
    team/file/bridging/configs/logger.conf.sample
    team/file/bridging/funcs/func_lock.c
    team/file/bridging/include/asterisk/sched.h
    team/file/bridging/include/asterisk/strings.h
    team/file/bridging/main/config.c
    team/file/bridging/main/sched.c
    team/file/bridging/main/utils.c
    team/file/bridging/pbx/pbx_dundi.c
    team/file/bridging/res/res_config_odbc.c
    team/file/bridging/res/res_config_pgsql.c
    team/file/bridging/res/res_config_sqlite.c
    team/file/bridging/res/res_features.c

Propchange: team/file/bridging/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/file/bridging/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/file/bridging/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri Aug 17 16:38:21 2007
@@ -1,1 +1,1 @@
-/trunk:1-79824
+/trunk:1-79915

Modified: team/file/bridging/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/file/bridging/apps/app_voicemail.c?view=diff&rev=79916&r1=79915&r2=79916
==============================================================================
--- team/file/bridging/apps/app_voicemail.c (original)
+++ team/file/bridging/apps/app_voicemail.c Fri Aug 17 16:38:21 2007
@@ -3061,10 +3061,19 @@
 
 	/* Play the beginning intro if desired */
 	if (!ast_strlen_zero(prefile)) {
-		RETRIEVE(prefile, -1, ext, context);
+#ifdef ODBC_STORAGE
+		int success = 
+#endif
+			RETRIEVE(prefile, -1, ext, context);
 		if (ast_fileexists(prefile, NULL, NULL) > 0) {
 			if (ast_streamfile(chan, prefile, chan->language) > -1) 
 				res = ast_waitstream(chan, ecodes);
+#ifdef ODBC_STORAGE
+			if(success == -1) 
+				/*We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database*/
+				ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n");
+				store_file(prefile, vmu->mailbox, vmu->context, -1);
+#endif
 		} else {
 			ast_debug(1, "%s doesn't exist, doing what we can\n", prefile);
 			res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes);

Modified: team/file/bridging/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/file/bridging/channels/chan_iax2.c?view=diff&rev=79916&r1=79915&r2=79916
==============================================================================
--- team/file/bridging/channels/chan_iax2.c (original)
+++ team/file/bridging/channels/chan_iax2.c Fri Aug 17 16:38:21 2007
@@ -1362,12 +1362,10 @@
 			iaxs[x]->callno = x;
 			iaxs[callno] = NULL;
 			/* Update the two timers that should have been started */
-			if (iaxs[x]->pingid > -1)
-				ast_sched_del(sched, iaxs[x]->pingid);
-			if (iaxs[x]->lagid > -1)
-				ast_sched_del(sched, iaxs[x]->lagid);
-			iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
-			iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
+			iaxs[x]->pingid = ast_sched_replace(iaxs[x]->pingid, sched, 
+				ping_time * 1000, send_ping, (void *)(long)x);
+			iaxs[x]->lagid = ast_sched_replace(iaxs[x]->lagid, sched, 
+				lagrq_time * 1000, send_lagrq, (void *)(long)x);
 			if (locked)
 				ast_mutex_unlock(&iaxsl[callno]);
 			res = x;
@@ -2504,14 +2502,13 @@
 	
 	when = jb_next(pvt->jb) - when;
 	
-	if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid);
-	
 	if(when <= 0) {
 		/* XXX should really just empty until when > 0.. */
 		when = 1;
 	}
 	
-	pvt->jbid = ast_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
+	pvt->jbid = ast_sched_replace(pvt->jbid, sched, when, get_from_jb, 
+		CALLNO_TO_PTR(pvt->callno));
 	
 	/* Signal scheduler thread */
 	signal_condition(&sched_lock, &sched_cond);
@@ -2815,9 +2812,8 @@
 	if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
 		ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
 		if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
-			if (peer->expire > -1)
-				ast_sched_del(sched, peer->expire);
-			peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, (void*)peer->name);
+			peer->expire = ast_sched_replace(peer->expire, sched, 
+				(global_rtautoclear) * 1000, expire_registry, (void *) peer->name);
 		}
 		AST_LIST_LOCK(&peers);
 		AST_LIST_INSERT_HEAD(&peers, peer, entry);
@@ -5894,9 +5890,8 @@
 	   we are registering to
 	*/
 	reg->refresh = refresh;
-	if (reg->expire > -1)
-		ast_sched_del(sched, reg->expire);
-	reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
+	reg->expire = ast_sched_replace(reg->expire, sched, 
+		(5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
 	if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
 			if (reg->messages > 255)
 				snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
@@ -6074,10 +6069,9 @@
 					p->addr.sin_family = AF_INET;
 					p->addr.sin_addr = in;
 					p->addr.sin_port = htons(atoi(c));
-					if (p->expire > -1)
-						ast_sched_del(sched, p->expire);
 					ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
-					p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p->name);
+					p->expire = ast_sched_replace(p->expire, sched, 
+						(p->expiry + 10) * 1000, expire_registry, (void *) p->name);
 					if (iax2_regfunk)
 						iax2_regfunk(p->name, 1);
 					register_peer_exten(p, 1);
@@ -6364,9 +6358,8 @@
 	if (iaxs[callno]) {
 		iaxs[callno]->authfail = failcode;
 		if (delayreject) {
-			if (iaxs[callno]->authid > -1)
-				ast_sched_del(sched, iaxs[callno]->authid);
-			iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
+			iaxs[callno]->authid = ast_sched_replace(iaxs[callno]->authid, 
+				sched, 1000, auth_reject, (void *)(long)callno);
 		} else
 			auth_reject((void *)(long)callno);
 	}
@@ -6407,9 +6400,8 @@
 {
 	struct iax_ie_data ied;
 	/* Auto-hangup with 30 seconds of inactivity */
-	if (iaxs[callno]->autoid > -1)
-		ast_sched_del(sched, iaxs[callno]->autoid);
-	iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
+	iaxs[callno]->autoid = ast_sched_replace(iaxs[callno]->autoid, 
+		sched, 30000, auto_hangup, (void *)(long)callno);
 	memset(&ied, 0, sizeof(ied));
 	iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
 	send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
@@ -8757,9 +8749,8 @@
 		if (iaxdebug)
 			ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
 		/* Setup the next registration attempt */
-		if (reg->expire > -1)
-			ast_sched_del(sched, reg->expire);
-		reg->expire  = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
+		reg->expire = ast_sched_replace(reg->expire, sched, 
+			(5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
 		return -1;
 	}
 
@@ -8773,11 +8764,9 @@
 			ast_debug(1, "Registration created on call %d\n", reg->callno);
 		iaxs[reg->callno]->reg = reg;
 	}
-	/* Schedule the next registration attempt */
-	if (reg->expire > -1)
-		ast_sched_del(sched, reg->expire);
 	/* Setup the next registration a little early */
-	reg->expire  = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
+	reg->expire = ast_sched_replace(reg->expire, sched, 
+		(5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
 	/* Send the request */
 	memset(&ied, 0, sizeof(ied));
 	iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
@@ -8831,9 +8820,8 @@
 	ast_mutex_lock(&iaxsl[callno]);
 	if (iaxs[callno]) {
 		/* Schedule autodestruct in case they don't ever give us anything back */
-		if (iaxs[callno]->autoid > -1)
-			ast_sched_del(sched, iaxs[callno]->autoid);
-		iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
+		iaxs[callno]->autoid = ast_sched_replace(iaxs[callno]->autoid, 
+			sched, 15000, auto_hangup, (void *)(long)callno);
 		ast_set_flag(iaxs[callno], IAX_PROVISION);
 		/* Got a call number now, so go ahead and send the provisioning information */
 		send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
@@ -8966,16 +8954,15 @@
 	iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
 	iaxs[peer->callno]->peerpoke = peer;
 	
-	/* Remove any pending pokeexpire task */
-	if (peer->pokeexpire > -1)
-		ast_sched_del(sched, peer->pokeexpire);
-
 	/* Queue up a new task to handle no reply */
 	/* If the host is already unreachable then use the unreachable interval instead */
 	if (peer->lastms < 0) {
-		peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer);
-	} else
-		peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer);
+		peer->pokeexpire = ast_sched_replace(peer->pokeexpire, 
+			sched, peer->pokefreqnotok, iax2_poke_noanswer, peer);
+	} else {
+		peer->pokeexpire = ast_sched_replace(peer->pokeexpire, 
+			sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer);
+	}
 
 	/* And send the poke */
 	send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);

Modified: team/file/bridging/channels/chan_local.c
URL: http://svn.digium.com/view/asterisk/team/file/bridging/channels/chan_local.c?view=diff&rev=79916&r1=79915&r2=79916
==============================================================================
--- team/file/bridging/channels/chan_local.c (original)
+++ team/file/bridging/channels/chan_local.c Fri Aug 17 16:38:21 2007
@@ -453,6 +453,12 @@
 	
 	ast_mutex_lock(&p->lock);
 
+	/*
+	 * Note that cid_num and cid_name aren't passed in the ast_channel_alloc
+	 * call, so it's done here instead.
+	 */
+	p->chan->cid.cid_num = ast_strdup(p->owner->cid.cid_num);
+	p->chan->cid.cid_name = ast_strdup(p->owner->cid.cid_name);
 	p->chan->cid.cid_rdnis = ast_strdup(p->owner->cid.cid_rdnis);
 	p->chan->cid.cid_ani = ast_strdup(p->owner->cid.cid_ani);
 	p->chan->cid.cid_pres = p->owner->cid.cid_pres;

Modified: team/file/bridging/channels/chan_misdn.c
URL: http://svn.digium.com/view/asterisk/team/file/bridging/channels/chan_misdn.c?view=diff&rev=79916&r1=79915&r2=79916
==============================================================================
--- team/file/bridging/channels/chan_misdn.c (original)
+++ team/file/bridging/channels/chan_misdn.c Fri Aug 17 16:38:21 2007
@@ -4828,6 +4828,7 @@
 				 "    s - send Non Inband DTMF as inband\n"
 				 "   vr - rxgain control\n"
 				 "   vt - txgain control\n"
+                                "    i - Ignore detected dtmf tones, don't signal them to asterisk, they will be transported inband.\n"
 		);
 
 	
@@ -5181,7 +5182,12 @@
 			} else if (strstr(tok, "not_screened")) {
 				ch->bc->pres = 1;
 			}
-
+			break;
+	  	case 'i' :
+			chan_misdn_log(1, ch->bc->port, "Ignoring dtmf tones, just use them inband\n");
+			ch->ignore_dtmf=1;
+			break;
+		default:
 			break;
 		}
 	}

Modified: team/file/bridging/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/file/bridging/channels/chan_sip.c?view=diff&rev=79916&r1=79915&r2=79916
==============================================================================
--- team/file/bridging/channels/chan_sip.c (original)
+++ team/file/bridging/channels/chan_sip.c Fri Aug 17 16:38:21 2007
@@ -2373,7 +2373,8 @@
 		siptimer_a = pkt->timer_t1 * 2;
 
 	/* Schedule retransmission */
-	pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1);
+	pkt->retransid = ast_sched_replace_variable(pkt->retransid, sched, 
+		siptimer_a, retrans_pkt, pkt, 1);
 	if (sipdebug)
 		ast_debug(4, "*** SIP TIMER: Initalizing retransmit timer on packet: Id  #%d\n", pkt->retransid);
 	if (sipmethod == SIP_INVITE) {
@@ -3132,10 +3133,8 @@
 		/* Cache peer */
 		ast_copy_flags(&peer->flags[1],&global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS);
 		if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
-			if (peer->expire > -1) {
-				ast_sched_del(sched, peer->expire);
-			}
-			peer->expire = ast_sched_add(sched, global_rtautoclear * 1000, expire_register, (void *)peer);
+			peer->expire = ast_sched_replace(peer->expire, sched, 
+				global_rtautoclear * 1000, expire_register, (void *) peer);
 		}
 		ASTOBJ_CONTAINER_LINK(&peerl,peer);
 	} else {
@@ -3561,7 +3560,8 @@
 		p->invitestate = INV_CALLING;
 	
 		/* Initialize auto-congest time */
-		p->initid = ast_sched_add(sched, SIP_TRANS_TIMEOUT, auto_congest, dialog_ref(p));
+		p->initid = ast_sched_replace(p->initid, sched, SIP_TRANS_TIMEOUT, 
+			auto_congest, dialog_ref(p));
 	}
 
 	return res;
@@ -8178,8 +8178,8 @@
 			 * probably DNS.  We need to reschedule a registration try */
 			sip_destroy(p);
 			if (r->timeout > -1) {
-				ast_sched_del(sched, r->timeout);
-				r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
+				r->timeout = ast_sched_replace(r->timeout, sched, 
+					global_reg_timeout * 1000, sip_reg_timeout, r);
 				ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
 			} else {
 				r->timeout = ast_sched_add(sched, global_reg_timeout*1000, sip_reg_timeout, r);
@@ -8228,11 +8228,9 @@
 
 	/* set up a timeout */
 	if (auth == NULL)  {
-		if (r->timeout > -1) {
+		if (r->timeout > -1)
 			ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
-			ast_sched_del(sched, r->timeout);
-		}
-		r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, r);
+		r->timeout = ast_sched_replace(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r);
 		ast_debug(1, "Scheduled a registration timeout for %s id  #%d \n", r->hostname, r->timeout);
 	}
 
@@ -8609,14 +8607,12 @@
 	peer->addr.sin_port = htons(port);
 	if (sipsock < 0) {
 		/* SIP isn't up yet, so schedule a poke only, pretty soon */
-		if (peer->pokeexpire > -1)
-			ast_sched_del(sched, peer->pokeexpire);
-		peer->pokeexpire = ast_sched_add(sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer);
+		peer->pokeexpire = ast_sched_replace(peer->pokeexpire, sched, 
+			ast_random() % 5000 + 1, sip_poke_peer_s, peer);
 	} else
 		sip_poke_peer(peer);
-	if (peer->expire > -1)
-		ast_sched_del(sched, peer->expire);
-	peer->expire = ast_sched_add(sched, (expiry + 10) * 1000, expire_register, peer);
+	peer->expire = ast_sched_replace(peer->expire, sched, 
+		(expiry + 10) * 1000, expire_register, peer);
 	register_peer_exten(peer, TRUE);
 }
 
@@ -12314,7 +12310,7 @@
 		initreqprep(&req, p, SIP_NOTIFY);
 
 		for (var = varlist; var; var = var->next)
-			add_header(&req, var->name, var->value);
+			add_header(&req, var->name, ast_unescape_semicolon(var->value));
 
 		/* Recalculate our side, and recalculate Call ID */
 		ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip);
@@ -13439,7 +13435,7 @@
 		r->refresh= (int) expires_ms / 1000;
 
 		/* Schedule re-registration before we expire */
-		r->expire=ast_sched_add(sched, expires_ms, sip_reregister, r); 
+		r->expire = ast_sched_replace(r->expire, sched, expires_ms, sip_reregister, r); 
 		registry_unref(r);
 	}
 	return 1;
@@ -13484,12 +13480,10 @@
 			register_peer_exten(peer, TRUE);
 	}
 
-	if (peer->pokeexpire > -1)
-		ast_sched_del(sched, peer->pokeexpire);
 	p->needdestroy = 1;
 
 	/* Try again eventually */
-	peer->pokeexpire = ast_sched_add(sched,
+	peer->pokeexpire = ast_sched_replace(peer->pokeexpire, sched,
 		is_reachable ? DEFAULT_FREQ_OK : DEFAULT_FREQ_NOTOK,
 		sip_poke_peer_s, peer);
 }
@@ -16564,7 +16558,8 @@
 	peer->lastms = -1;
 	ast_device_state_changed("SIP/%s", peer->name);
 	/* Try again quickly */
-	peer->pokeexpire = ast_sched_add(sched, DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
+	peer->pokeexpire = ast_sched_replace(peer->pokeexpire, sched, 
+		DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer);
 	return 0;
 }
 
@@ -16626,8 +16621,10 @@
 	peer->ps = ast_tvnow();
 	if (xmitres == XMIT_ERROR)
 		sip_poke_noanswer(peer);	/* Immediately unreachable, network problems */
-	else
-		peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, sip_poke_noanswer, peer);
+	else {
+		peer->pokeexpire = ast_sched_replace(peer->pokeexpire, sched, 
+			DEFAULT_MAXMS * 2, sip_poke_noanswer, peer);
+	}
 
 	return 0;
 }
@@ -18661,10 +18658,9 @@
 
 	ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do {
 		ASTOBJ_WRLOCK(iterator);
-		if (iterator->pokeexpire > -1)
-			ast_sched_del(sched, iterator->pokeexpire);
 		ms += 100;
-		iterator->pokeexpire = ast_sched_add(sched, ms, sip_poke_peer_s, iterator);
+		iterator->pokeexpire = ast_sched_replace(iterator->pokeexpire, 
+			sched, ms, sip_poke_peer_s, iterator);
 		ASTOBJ_UNLOCK(iterator);
 	} while (0)
 	);
@@ -18683,10 +18679,9 @@
 	ms = regspacing;
 	ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
 		ASTOBJ_WRLOCK(iterator);
-		if (iterator->expire > -1)
-			ast_sched_del(sched, iterator->expire);
 		ms += regspacing;
-		iterator->expire = ast_sched_add(sched, ms, sip_reregister, iterator);
+		iterator->expire = ast_sched_replace(iterator->expire, 
+			sched, ms, sip_reregister, iterator);
 		ASTOBJ_UNLOCK(iterator);
 	} while (0)
 	);

Modified: team/file/bridging/channels/chan_zap.c
URL: http://svn.digium.com/view/asterisk/team/file/bridging/channels/chan_zap.c?view=diff&rev=79916&r1=79915&r2=79916
==============================================================================
--- team/file/bridging/channels/chan_zap.c (original)
+++ team/file/bridging/channels/chan_zap.c Fri Aug 17 16:38:21 2007
@@ -6397,6 +6397,8 @@
 						return NULL;
 					} 
 					f = ast_read(chan);
+					if (!f)
+						break;
 					if (f->frametype == AST_FRAME_DTMF) {
 						dtmfbuf[i++] = f->subclass;
 						ast_debug(1, "CID got digit '%c'\n", f->subclass);

Modified: team/file/bridging/configs/logger.conf.sample
URL: http://svn.digium.com/view/asterisk/team/file/bridging/configs/logger.conf.sample?view=diff&rev=79916&r1=79915&r2=79916
==============================================================================
--- team/file/bridging/configs/logger.conf.sample (original)
+++ team/file/bridging/configs/logger.conf.sample Fri Aug 17 16:38:21 2007
@@ -8,10 +8,16 @@
 ; of the logging system.
 
 [general]
+;
 ; Customize the display of debug message time stamps
 ; this example is the ISO 8601 date format (yyyy-mm-dd HH:MM:SS)
-; see strftime(3) Linux manual for format specifiers
-;dateformat=%F %T
+;
+; see strftime(3) Linux manual for format specifiers.  Note that there is also
+; a fractional second parameter which may be used in this field.  Use %1q
+; for tenths, %2q for hundredths, etc.
+; 
+;dateformat=%F %T       ; ISO 8601 date format
+;dateformat=%F %T.%3q   ; with milliseconds
 ;
 ; This appends the hostname to the name of the log files.
 ;appendhostname = yes

Modified: team/file/bridging/funcs/func_lock.c
URL: http://svn.digium.com/view/asterisk/team/file/bridging/funcs/func_lock.c?view=diff&rev=79916&r1=79915&r2=79916
==============================================================================
--- team/file/bridging/funcs/func_lock.c (original)
+++ team/file/bridging/funcs/func_lock.c Fri Aug 17 16:38:21 2007
@@ -97,7 +97,7 @@
 {
 	struct ast_datastore *lock_store = ast_channel_datastore_find(chan, &lock_info, NULL);
 	struct lock_frame *current;
-	struct channel_lock_frame *clframe, *save_clframe;
+	struct channel_lock_frame *clframe = NULL, *save_clframe = NULL;
 	AST_LIST_HEAD(, channel_lock_frame) *list;
 	int res, count_channel_locks = 0;
 

Modified: team/file/bridging/include/asterisk/sched.h
URL: http://svn.digium.com/view/asterisk/team/file/bridging/include/asterisk/sched.h?view=diff&rev=79916&r1=79915&r2=79916
==============================================================================
--- team/file/bridging/include/asterisk/sched.h (original)
+++ team/file/bridging/include/asterisk/sched.h Fri Aug 17 16:38:21 2007
@@ -71,6 +71,18 @@
  */
 int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, void *data);
 
+/*!
+ * \brief replace a scheduler entry
+ *
+ * This deletes the scheduler entry for old_id if it exists, and then
+ * calls ast_sched_add to create a new entry.  A negative old_id will
+ * be ignored.
+ *
+ * \retval -1 failure
+ * \retval otherwise, returns scheduled item ID
+ */
+int ast_sched_replace(int old_id, struct sched_context *con, int when, ast_sched_cb callback, void *data);
+
 /*!Adds a scheduled event with rescheduling support
  * \param con Scheduler context to add
  * \param when how many milliseconds to wait for event to occur
@@ -85,6 +97,18 @@
  * \return Returns a schedule item ID on success, -1 on failure
  */
 int ast_sched_add_variable(struct sched_context *con, int when, ast_sched_cb callback, void *data, int variable);
+
+/*!
+ * \brief replace a scheduler entry
+ *
+ * This deletes the scheduler entry for old_id if it exists, and then
+ * calls ast_sched_add to create a new entry.  A negative old_id will
+ * be ignored.
+ *
+ * \retval -1 failure
+ * \retval otherwise, returns scheduled item ID
+ */
+int ast_sched_replace_variable(int old_id, struct sched_context *con, int when, ast_sched_cb callback, void *data, int variable);
 
 /*! \brief Deletes a scheduled event
  * Remove this event from being run.  A procedure should not remove its

Modified: team/file/bridging/include/asterisk/strings.h
URL: http://svn.digium.com/view/asterisk/team/file/bridging/include/asterisk/strings.h?view=diff&rev=79916&r1=79915&r2=79916
==============================================================================
--- team/file/bridging/include/asterisk/strings.h (original)
+++ team/file/bridging/include/asterisk/strings.h Fri Aug 17 16:38:21 2007
@@ -147,6 +147,13 @@
 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes);
 
 /*!
+  \brief Strip backslash for "escaped" semicolons.
+  \brief s The string to be stripped (will be modified).
+  \return The stripped string.
+ */
+char *ast_unescape_semicolon(char *s);
+
+/*!
   \brief Size-limited null-terminating string copy.
   \arg dst The destination buffer.
   \arg src The source string

Modified: team/file/bridging/main/config.c
URL: http://svn.digium.com/view/asterisk/team/file/bridging/main/config.c?view=diff&rev=79916&r1=79915&r2=79916
==============================================================================
--- team/file/bridging/main/config.c (original)
+++ team/file/bridging/main/config.c Fri Aug 17 16:38:21 2007
@@ -967,7 +967,7 @@
 				return CONFIG_STATUS_FILEUNCHANGED;
 			}
 		}
-		if (cfmtime)
+		if (!ast_test_flag(&flags, CONFIG_FLAG_NOCACHE))
 			AST_LIST_UNLOCK(&cfmtime_head);
 
 		/* If cfg is NULL, then we just want an answer */

Modified: team/file/bridging/main/sched.c
URL: http://svn.digium.com/view/asterisk/team/file/bridging/main/sched.c?view=diff&rev=79916&r1=79915&r2=79916
==============================================================================
--- team/file/bridging/main/sched.c (original)
+++ team/file/bridging/main/sched.c Fri Aug 17 16:38:21 2007
@@ -207,6 +207,12 @@
 	return 0;
 }
 
+int ast_sched_replace_variable(int old_id, struct sched_context *con, int when, ast_sched_cb callback, void *data, int variable)
+{
+	if (old_id > -1)
+		ast_sched_del(con, old_id);
+	return ast_sched_add_variable(con, when, callback, data, variable);
+}
 
 /*! \brief
  * Schedule callback(data) to happen when ms into the future
@@ -242,6 +248,13 @@
 #endif
 	ast_mutex_unlock(&con->lock);
 	return res;
+}
+
+int ast_sched_replace(int old_id, struct sched_context *con, int when, ast_sched_cb callback, void *data)
+{
+	if (old_id > -1)
+		ast_sched_del(con, old_id);
+	return ast_sched_add(con, when, callback, data);
 }
 
 int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, void *data)

Modified: team/file/bridging/main/utils.c
URL: http://svn.digium.com/view/asterisk/team/file/bridging/main/utils.c?view=diff&rev=79916&r1=79915&r2=79916
==============================================================================
--- team/file/bridging/main/utils.c (original)
+++ team/file/bridging/main/utils.c Fri Aug 17 16:38:21 2007
@@ -935,6 +935,21 @@
 	return s;
 }
 
+char *ast_unescape_semicolon(char *s)
+{
+	char *e;
+	char *work = s;
+
+	while ((e = strchr(work, ';'))) {
+		if ((e > work) && (*(e-1) == '\\')) {
+			memmove(e - 1, e, strlen(e) + 1);
+			work = e;
+		}
+	}
+
+	return s;
+}
+
 int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
 {
 	int result;

Modified: team/file/bridging/pbx/pbx_dundi.c
URL: http://svn.digium.com/view/asterisk/team/file/bridging/pbx/pbx_dundi.c?view=diff&rev=79916&r1=79915&r2=79916
==============================================================================
--- team/file/bridging/pbx/pbx_dundi.c (original)
+++ team/file/bridging/pbx/pbx_dundi.c Fri Aug 17 16:38:21 2007
@@ -4530,7 +4530,7 @@
 	if (x < res) {
 		/* Got a hit! */
 		dundiargs = pbx_builtin_getvar_helper(chan, "DUNDIDIALARGS");
-		snprintf(req, sizeof(req), "%s/%s||%s", results[x].tech, results[x].dest, 
+		snprintf(req, sizeof(req), "%s/%s,,%s", results[x].tech, results[x].dest, 
 			S_OR(dundiargs, ""));
 		dial = pbx_findapp("Dial");
 		if (dial)

Modified: team/file/bridging/res/res_config_odbc.c
URL: http://svn.digium.com/view/asterisk/team/file/bridging/res/res_config_odbc.c?view=diff&rev=79916&r1=79915&r2=79916
==============================================================================
--- team/file/bridging/res/res_config_odbc.c (original)
+++ team/file/bridging/res/res_config_odbc.c Fri Aug 17 16:38:21 2007
@@ -450,6 +450,145 @@
 	return -1;
 }
 
+/*!
+ * \brief Excute an INSERT query
+ * \param database
+ * \param table
+ * \param ap list containing one or more field/value set(s)
+ * Insert a new record into database table, prepare the sql statement.
+ * All values to be changed are stored in ap list.
+ * Sub-in the values to the prepared statement and execute it.
+ *
+ * \retval number of rows affected
+ * \retval -1 on failure
+*/
+static int store_odbc(const char *database, const char *table, va_list ap)
+{
+	struct odbc_obj *obj;
+	SQLHSTMT stmt;
+	char sql[256];
+	char keys[256];
+	char vals[256];
+	SQLLEN rowcount=0;
+	const char *newparam, *newval;
+	int res;
+	va_list aq;
+	struct custom_prepare_struct cps = { .sql = sql, .extra = NULL };
+
+	va_copy(cps.ap, ap);
+	va_copy(aq, ap);
+	
+	if (!table)
+		return -1;
+
+	obj = ast_odbc_request_obj(database, 0);
+	if (!obj)
+		return -1;
+
+	newparam = va_arg(aq, const char *);
+	if (!newparam)  {
+		ast_odbc_release_obj(obj);
+		return -1;
+	}
+	newval = va_arg(aq, const char *);
+	snprintf(keys, sizeof(keys), "%s", newparam);
+	snprintf(vals, sizeof(vals), "?");
+	while ((newparam = va_arg(aq, const char *))) {
+		snprintf(keys + strlen(keys), sizeof(keys) - strlen(keys), ", %s", newparam);
+		snprintf(vals + strlen(vals), sizeof(vals) - strlen(vals), ", ?");
+		newval = va_arg(aq, const char *);
+	}
+	va_end(aq);
+	snprintf(sql, sizeof(sql), "INSERT INTO %s (%s) VALUES (%s)", table, keys, vals);
+
+	stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
+
+	if (!stmt) {
+		ast_odbc_release_obj(obj);
+		return -1;
+	}
+
+	res = SQLRowCount(stmt, &rowcount);
+	SQLFreeHandle (SQL_HANDLE_STMT, stmt);
+	ast_odbc_release_obj(obj);
+
+	if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
+		ast_log(LOG_WARNING, "SQL Row Count error!\n[%s]\n\n", sql);
+		return -1;
+	}
+
+	if (rowcount >= 0)
+		return (int)rowcount;
+
+	return -1;
+}
+
+/*!
+ * \brief Excute an DELETE query
+ * \param database
+ * \param table
+ * \param keyfield where clause field
+ * \param lookup value of field for where clause
+ * \param ap list containing one or more field/value set(s)
+ * Dlete a row from a database table, prepare the sql statement using keyfield and lookup
+ * control the number of records to change. Additional params to match rows are stored in ap list.
+ * Sub-in the values to the prepared statement and execute it.
+ *
+ * \retval number of rows affected
+ * \retval -1 on failure
+*/
+static int destroy_odbc(const char *database, const char *table, const char *keyfield, const char *lookup, va_list ap)
+{
+	struct odbc_obj *obj;
+	SQLHSTMT stmt;
+	char sql[256];
+	SQLLEN rowcount=0;
+	const char *newparam, *newval;
+	int res;
+	va_list aq;
+	struct custom_prepare_struct cps = { .sql = sql, .extra = lookup };
+
+	va_copy(cps.ap, ap);
+	va_copy(aq, ap);
+	
+	if (!table)
+		return -1;
+
+	obj = ast_odbc_request_obj(database, 0);
+	if (!obj)
+		return -1;
+
+	snprintf(sql, sizeof(sql), "DELETE FROM %s WHERE ", table);
+	while((newparam = va_arg(aq, const char *))) {
+		snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "%s=? AND ", newparam);
+		newval = va_arg(aq, const char *);
+	}
+	va_end(aq);
+	snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "%s=?", keyfield);
+
+	stmt = ast_odbc_prepare_and_execute(obj, custom_prepare, &cps);
+
+	if (!stmt) {
+		ast_odbc_release_obj(obj);
+		return -1;
+	}
+
+	res = SQLRowCount(stmt, &rowcount);
+	SQLFreeHandle (SQL_HANDLE_STMT, stmt);
+	ast_odbc_release_obj(obj);
+
+	if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
+		ast_log(LOG_WARNING, "SQL Row Count error!\n[%s]\n\n", sql);
+		return -1;
+	}
+
+	if (rowcount >= 0)
+		return (int)rowcount;
+
+	return -1;
+}
+
+
 struct config_odbc_obj {
 	char *sql;
 	unsigned long cat_metric;
@@ -575,6 +714,8 @@
 	.load_func = config_odbc,
 	.realtime_func = realtime_odbc,
 	.realtime_multi_func = realtime_multi_odbc,
+	.store_func = store_odbc,
+	.destroy_func = destroy_odbc,
 	.update_func = update_odbc
 };
 

Modified: team/file/bridging/res/res_config_pgsql.c
URL: http://svn.digium.com/view/asterisk/team/file/bridging/res/res_config_pgsql.c?view=diff&rev=79916&r1=79915&r2=79916
==============================================================================
--- team/file/bridging/res/res_config_pgsql.c (original)
+++ team/file/bridging/res/res_config_pgsql.c Fri Aug 17 16:38:21 2007
@@ -429,6 +429,191 @@
 	return -1;
 }
 
+static int store_pgsql(const char *database, const char *table, va_list ap)
+{
+	PGresult *result = NULL;
+	Oid insertid;
+	char sql[256];
+	char params[256];
+	char vals[256];
+	char buf[256];
+	int pgresult;
+	const char *newparam, *newval;
+
+	if (!table) {
+		ast_log(LOG_WARNING, "Postgresql RealTime: No table specified.\n");
+		return -1;
+	}
+
+	/* Get the first parameter and first value in our list of passed paramater/value pairs */
+	newparam = va_arg(ap, const char *);
+	newval = va_arg(ap, const char *);
+	if (!newparam || !newval) {
+		ast_log(LOG_WARNING,
+				"Postgresql RealTime: Realtime storage requires at least 1 parameter and 1 value to store.\n");
+		if (pgsqlConn) {
+			PQfinish(pgsqlConn);
+			pgsqlConn = NULL;
+		};
+		return -1;
+	}
+
+	/* Must connect to the server before anything else, as the escape function requires the connection handle.. */
+	ast_mutex_lock(&pgsql_lock);
+	if (!pgsql_reconnect(database)) {
+		ast_mutex_unlock(&pgsql_lock);
+		return -1;
+	}
+
+	/* Create the first part of the query using the first parameter/value pairs we just extracted
+	   If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
+	PQescapeStringConn(pgsqlConn, buf, newparam, sizeof(newparam), &pgresult);
+	snprintf(params, sizeof(params), "%s", buf);
+	PQescapeStringConn(pgsqlConn, buf, newval, sizeof(newval), &pgresult);
+	snprintf(vals, sizeof(vals), "'%s'", buf);
+	while ((newparam = va_arg(ap, const char *))) {
+		newval = va_arg(ap, const char *);
+		PQescapeStringConn(pgsqlConn, buf, newparam, sizeof(newparam), &pgresult);
+		snprintf(params + strlen(params), sizeof(params) - strlen(params), ", %s", buf);
+		PQescapeStringConn(pgsqlConn, buf, newval, sizeof(newval), &pgresult);
+		snprintf(vals + strlen(vals), sizeof(vals) - strlen(vals), ", '%s'", buf);
+	}
+	va_end(ap);
+	snprintf(sql, sizeof(sql), "INSERT INTO (%s) VALUES (%s)", params, vals);
+
+	ast_debug(1, "Postgresql RealTime: Insert SQL: %s\n", sql);
+
+	if (!(result = PQexec(pgsqlConn, sql))) {
+		ast_log(LOG_WARNING,
+				"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
+		ast_debug(1, "Postgresql RealTime: Query: %s\n", sql);
+		ast_debug(1, "Postgresql RealTime: Query Failed because: %s\n", PQerrorMessage(pgsqlConn));
+		ast_mutex_unlock(&pgsql_lock);
+		return -1;
+	} else {
+		ExecStatusType result_status = PQresultStatus(result);
+		if (result_status != PGRES_COMMAND_OK
+			&& result_status != PGRES_TUPLES_OK
+			&& result_status != PGRES_NONFATAL_ERROR) {
+			ast_log(LOG_WARNING,
+					"Postgresql RealTime: Failed to query database. Check debug for more info.\n");
+			ast_debug(1, "Postgresql RealTime: Query: %s\n", sql);
+			ast_debug(1, "Postgresql RealTime: Query Failed because: %s (%s)\n",
+						PQresultErrorMessage(result), PQresStatus(result_status));
+			ast_mutex_unlock(&pgsql_lock);
+			return -1;
+		}
+	}
+
+	insertid = PQoidValue(result);
+	ast_mutex_unlock(&pgsql_lock);
+
+	ast_debug(1, "Postgresql RealTime: row inserted on table: %s, id: %u\n", table, insertid);
+
+	/* From http://dev.pgsql.com/doc/pgsql/en/pgsql-affected-rows.html
+	 * An integer greater than zero indicates the number of rows affected
+	 * Zero indicates that no records were updated
+	 * -1 indicates that the query returned an error (although, if the query failed, it should have been caught above.)
+	 */
+
+	if (insertid >= 0)
+		return (int) insertid;
+
+	return -1;
+}
+
+static int destroy_pgsql(const char *database, const char *table, const char *keyfield, const char *lookup, va_list ap)
+{
+	PGresult *result = NULL;
+	int numrows = 0;
+	int pgresult;
+	char sql[256];
+	char buf[256], buf2[256];
+	const char *newparam, *newval;
+
+	if (!table) {
+		ast_log(LOG_WARNING, "Postgresql RealTime: No table specified.\n");
+		return -1;
+	}
+
+	/* Get the first parameter and first value in our list of passed paramater/value pairs */
+	/*newparam = va_arg(ap, const char *);
+	newval = va_arg(ap, const char *);

[... 342 lines stripped ...]



More information about the asterisk-commits mailing list