[svn-commits] russell: branch russell/events r121364 - in /team/russell/events: ./ apps/ ch...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Jun 9 16:31:15 CDT 2008


Author: russell
Date: Mon Jun  9 16:31:14 2008
New Revision: 121364

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

Modified:
    team/russell/events/   (props changed)
    team/russell/events/CHANGES
    team/russell/events/apps/app_exec.c
    team/russell/events/apps/app_meetme.c
    team/russell/events/apps/app_parkandannounce.c
    team/russell/events/apps/app_privacy.c
    team/russell/events/apps/app_queue.c
    team/russell/events/apps/app_voicemail.c
    team/russell/events/channels/chan_agent.c
    team/russell/events/channels/chan_console.c
    team/russell/events/channels/chan_iax2.c
    team/russell/events/channels/chan_local.c
    team/russell/events/channels/chan_sip.c
    team/russell/events/configs/res_pgsql.conf.sample
    team/russell/events/contrib/scripts/dbsep.cgi
    team/russell/events/include/asterisk/config.h
    team/russell/events/include/asterisk/res_odbc.h
    team/russell/events/main/channel.c
    team/russell/events/main/config.c
    team/russell/events/main/dsp.c
    team/russell/events/main/features.c
    team/russell/events/main/pbx.c
    team/russell/events/res/res_config_curl.c
    team/russell/events/res/res_config_odbc.c
    team/russell/events/res/res_config_pgsql.c

Propchange: team/russell/events/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/russell/events/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/russell/events/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Jun  9 16:31:14 2008
@@ -1,1 +1,1 @@
-/trunk:1-120775
+/trunk:1-121363

Modified: team/russell/events/CHANGES
URL: http://svn.digium.com/view/asterisk/team/russell/events/CHANGES?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/CHANGES (original)
+++ team/russell/events/CHANGES Mon Jun  9 16:31:14 2008
@@ -79,6 +79,9 @@
    complete documentation.
  * ChanIsAvail has a new option, 'a', which will return all available channels instead
    of just the first one if you give the function more then one channel to check.
+ * PrivacyManager now takes an option where you can specify a context where the 
+   given number will be matched. This way you have more control over who is allowed
+   and it stops the people who blindly enter 10 digits.
 
 SIP Changes
 -----------
@@ -100,6 +103,7 @@
  * Added support for T140 RED - redundancy in T.140 to prevent text loss due to
    lost packets.
  * Added t38pt_usertpsource option. See sip.conf.sample for details.
+ * Added SIPnotify AMI command, for sending arbitrary SIP notify commands.
 
 IAX Changes
 -----------

Modified: team/russell/events/apps/app_exec.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/apps/app_exec.c?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/apps/app_exec.c (original)
+++ team/russell/events/apps/app_exec.c Mon Jun  9 16:31:14 2008
@@ -148,7 +148,7 @@
 static int execif_exec(struct ast_channel *chan, void *data)
 {
 	int res = 0;
-	char *truedata = NULL, *falsedata = NULL, *end;
+	char *truedata = NULL, *falsedata = NULL, *end, *firstcomma, *firstquestion;
 	struct ast_app *app = NULL;
 	AST_DECLARE_APP_ARGS(expr,
 		AST_APP_ARG(expr);
@@ -160,24 +160,49 @@
 	);
 	char *parse = ast_strdupa(data);
 
-	AST_NONSTANDARD_APP_ARGS(expr, parse, '?');
-	if (ast_strlen_zero(expr.remainder)) {
-		ast_log(LOG_ERROR, "Usage: ExecIf(<expr>?<appiftrue>(<args>)[:<appiffalse>(<args)])\n");
-		return -1;
-	}
-
-	AST_NONSTANDARD_APP_ARGS(apps, expr.remainder, ':');
-
-	if (apps.t && (truedata = strchr(apps.t, '('))) {
-		*truedata++ = '\0';
-		if ((end = strrchr(truedata, ')')))
-			*end = '\0';
-	}
-
-	if (apps.f && (falsedata = strchr(apps.f, '('))) {
-		*falsedata++ = '\0';
-		if ((end = strrchr(falsedata, ')')))
-			*end = '\0';
+	firstcomma = strchr(parse, ',');
+	firstquestion = strchr(parse, '?');
+
+	if ((firstcomma != NULL && firstquestion != NULL && firstcomma < firstquestion) || (firstquestion == NULL)) {
+		/* Deprecated syntax */
+		AST_DECLARE_APP_ARGS(depr,
+			AST_APP_ARG(expr);
+			AST_APP_ARG(appname);
+			AST_APP_ARG(appargs);
+		);
+		AST_STANDARD_APP_ARGS(depr, parse);
+
+		ast_log(LOG_WARNING, "Deprecated syntax found.  Please upgrade to using ExecIf(<expr>?%s(%s))\n", depr.appname, depr.appargs);
+
+		/* Make the two syntaxes look the same */
+		expr.expr = depr.expr;
+		apps.t = depr.appname;
+		apps.f = NULL;
+		truedata = depr.appargs;
+	} else {
+		/* Preferred syntax */
+
+		AST_NONSTANDARD_APP_ARGS(expr, parse, '?');
+		if (ast_strlen_zero(expr.remainder)) {
+			ast_log(LOG_ERROR, "Usage: ExecIf(<expr>?<appiftrue>(<args>)[:<appiffalse>(<args)])\n");
+			return -1;
+		}
+
+		AST_NONSTANDARD_APP_ARGS(apps, expr.remainder, ':');
+
+		if (apps.t && (truedata = strchr(apps.t, '('))) {
+			*truedata++ = '\0';
+			if ((end = strrchr(truedata, ')'))) {
+				*end = '\0';
+			}
+		}
+
+		if (apps.f && (falsedata = strchr(apps.f, '('))) {
+			*falsedata++ = '\0';
+			if ((end = strrchr(falsedata, ')'))) {
+				*end = '\0';
+			}
+		}
 	}
 
 	if (pbx_checkcondition(expr.expr)) {

Modified: team/russell/events/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/apps/app_meetme.c?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/apps/app_meetme.c (original)
+++ team/russell/events/apps/app_meetme.c Mon Jun  9 16:31:14 2008
@@ -1743,6 +1743,7 @@
 	if (rt_log_members) {
 		/* Update table */
 		snprintf(members, sizeof(members), "%d", conf->users);
+		ast_realtime_require_field("meetme", "confno", RQ_INTEGER, strlen(conf->confno), "members", RQ_INTEGER, strlen(members), NULL);
 		ast_update_realtime("meetme", "confno", conf->confno, "members", members, NULL);
 	}
 	setusercount = 1;
@@ -2682,6 +2683,7 @@
 			if (rt_log_members) {
 				/* Update table */
 				snprintf(members, sizeof(members), "%d", conf->users);
+				ast_realtime_require_field("meetme", "confno", RQ_INTEGER, strlen(conf->confno), "members", RQ_INTEGER, strlen(members), NULL);
 				ast_update_realtime("meetme", "confno", conf->confno, "members", members, NULL);
 			}
 			if (confflags & CONFFLAG_MARKEDUSER) 
@@ -5677,6 +5679,7 @@
 	sla_destroy();
 	
 	res |= ast_custom_function_unregister(&meetme_info_acf);
+	ast_unload_realtime("meetme");
 
 	return res;
 }
@@ -5707,12 +5710,14 @@
 	res |= ast_devstate_prov_add("SLA", sla_state);
 
 	res |= ast_custom_function_register(&meetme_info_acf);
+	ast_realtime_require_field("meetme", "confno", RQ_INTEGER, 3, "members", RQ_INTEGER, 3, NULL);
 
 	return res;
 }
 
 static int reload(void)
 {
+	ast_unload_realtime("meetme");
 	return load_config(1);
 }
 

Modified: team/russell/events/apps/app_parkandannounce.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/apps/app_parkandannounce.c?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/apps/app_parkandannounce.c (original)
+++ team/russell/events/apps/app_parkandannounce.c Mon Jun  9 16:31:14 2008
@@ -144,9 +144,12 @@
 
 	ast_verb(4, "Announce Template:%s\n", args.template);
 
-	for (looptemp = 0, tmp[looptemp++] = strsep(&args.template, ":");
-		 looptemp < sizeof(tmp) / sizeof(tmp[0]);
-		 tmp[looptemp++] = strsep(&args.template, ":"));
+	for (looptemp = 0; looptemp < sizeof(tmp) / sizeof(tmp[0]); looptemp++) {
+		if ((tmp[looptemp] = strsep(&args.template, ":")) != NULL)
+			continue;
+		else
+			break;
+	}
 
 	for (i = 0; i < looptemp; i++) {
 		ast_verb(4, "Announce:%s\n", tmp[i]);

Modified: team/russell/events/apps/app_privacy.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/apps/app_privacy.c?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/apps/app_privacy.c (original)
+++ team/russell/events/apps/app_privacy.c Mon Jun  9 16:31:14 2008
@@ -46,13 +46,14 @@
 static char *synopsis = "Require phone number to be entered, if no CallerID sent";
 
 static char *descrip =
-  "  PrivacyManager([maxretries][,minlength]): If no Caller*ID \n"
+  "  PrivacyManager([maxretries][,minlength][,context]): If no Caller*ID \n"
   "is sent, PrivacyManager answers the channel and asks the caller to\n"
   "enter their phone number. The caller is given 'maxretries' attempts to do so.\n"
   "The application does nothing if Caller*ID was received on the channel.\n"
   "   maxretries  default 3  -maximum number of attempts the caller is allowed \n"
   "               to input a callerid.\n"
   "   minlength   default 10 -minimum allowable digits in the input callerid number.\n"
+  "   context     context to check the given Caller*ID against patterns.\n"
   "The application sets the following channel variable upon completion: \n"
   "PRIVACYMGRSTATUS  The status of the privacy manager's attempt to collect \n"
   "                  a phone number from the user. A text string that is either:\n" 
@@ -73,6 +74,7 @@
 		AST_APP_ARG(maxretries);
 		AST_APP_ARG(minlength);
 		AST_APP_ARG(options);
+		AST_APP_ARG(checkcontext);
 	);
 
 	if (!ast_strlen_zero(chan->cid.cid_num)) {
@@ -101,7 +103,6 @@
 				else
 					ast_log(LOG_WARNING, "Invalid min length argument\n");
 			}
-
 		}		
 
 		/* Play unidentified call */
@@ -125,9 +126,21 @@
 				break;
 
 			/* Make sure we get at least digits */
-			if (strlen(phone) >= minlength ) 
-				break;
-			else {
+			if (strlen(phone) >= minlength ) {
+				/* if we have a checkcontext argument, do pattern matching */
+				if (!ast_strlen_zero(args.checkcontext)) {
+					if (!ast_exists_extension(NULL, args.checkcontext, phone, 1, NULL)) {
+						res = ast_streamfile(chan, "privacy-incorrect", chan->language);
+						if (!res) {
+							res = ast_waitstream(chan, "");
+						}
+					} else {
+						break;
+					}
+				} else {
+					break;
+				}
+			} else {
 				res = ast_streamfile(chan, "privacy-incorrect", chan->language);
 				if (!res)
 					res = ast_waitstream(chan, "");

Modified: team/russell/events/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/apps/app_queue.c?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/apps/app_queue.c (original)
+++ team/russell/events/apps/app_queue.c Mon Jun  9 16:31:14 2008
@@ -6284,6 +6284,7 @@
 	}
 	ao2_ref(queues, -1);
 	devicestate_tps = ast_taskprocessor_unreference(devicestate_tps);
+	ast_unload_realtime("queue_members");
 	return res;
 }
 
@@ -6337,11 +6338,14 @@
 		res = -1;
 	}
 
+	ast_realtime_require_field("queue_members", "paused", RQ_INTEGER, 1, "uniqueid", RQ_INTEGER, 5, NULL);
+
 	return res ? AST_MODULE_LOAD_DECLINE : 0;
 }
 
 static int reload(void)
 {
+	ast_unload_realtime("queue_members");
 	reload_queues(1);
 	return 0;
 }

Modified: team/russell/events/apps/app_voicemail.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/apps/app_voicemail.c?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/apps/app_voicemail.c (original)
+++ team/russell/events/apps/app_voicemail.c Mon Jun  9 16:31:14 2008
@@ -928,6 +928,9 @@
 {
 	int res;
 	if (!ast_strlen_zero(vmu->uniqueid)) {
+		if (strlen(password) > 10) {
+			ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), NULL);
+		}
 		res = ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, NULL);
 		if (res > 0) {
 			ast_copy_string(vmu->password, password, sizeof(vmu->password));
@@ -9367,6 +9370,9 @@
 	int tmpadsi[4];
 	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 
+	ast_unload_realtime("voicemail");
+	ast_unload_realtime("voicemail_data");
+
 	if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
 		if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
 			return 0;
@@ -10050,6 +10056,8 @@
 		stop_poll_thread();
 
 	mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps);
+	ast_unload_realtime("voicemail");
+	ast_unload_realtime("voicemail_data");
 	return res;
 }
 
@@ -10081,6 +10089,8 @@
 	ast_cli_register_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry));
 
 	ast_install_vm_functions(has_voicemail, inboxcount, messagecount, sayname);
+	ast_realtime_require_field("voicemail", "uniqueid", RQ_INTEGER, 11, "password", RQ_CHAR, 10, NULL);
+	ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_INTEGER, 5, NULL);
 
 	return res;
 }

Modified: team/russell/events/channels/chan_agent.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/channels/chan_agent.c?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/channels/chan_agent.c (original)
+++ team/russell/events/channels/chan_agent.c Mon Jun  9 16:31:14 2008
@@ -438,7 +438,17 @@
 			if (!ast_strlen_zero(p->loginchan)) {
 				if (p->chan)
 					ast_debug(1, "Bridge on '%s' being cleared (2)\n", p->chan->name);
-
+				if (p->owner->_state != AST_STATE_UP) {
+					int howlong = time(NULL) - p->start;
+					if (p->autologoff && howlong > p->autologoff) {
+						long logintime = time(NULL) - p->loginstart;
+						p->loginstart = 0;
+							ast_log(LOG_NOTICE, "Agent '%s' didn't answer/confirm within %d seconds (waited %d)\n", p->name, p->autologoff, howlong);
+						agent_logoff_maintenance(p, p->loginchan, logintime, ast->uniqueid, "Autologoff");
+						if (persistent_agents)
+							dump_agents();
+					}
+				}
 				status = pbx_builtin_getvar_helper(p->chan, "CHANLOCALSTATUS");
 				if (autologoffunavail && status && !strcasecmp(status, "CHANUNAVAIL")) {
 					long logintime = time(NULL) - p->loginstart;
@@ -2528,7 +2538,6 @@
 		ast_free(p);
 	}
 	AST_LIST_UNLOCK(&agents);
-	AST_LIST_HEAD_DESTROY(&agents);
 	return 0;
 }
 

Modified: team/russell/events/channels/chan_console.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/channels/chan_console.c?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/channels/chan_console.c (original)
+++ team/russell/events/channels/chan_console.c Mon Jun  9 16:31:14 2008
@@ -393,7 +393,7 @@
 
 static int stop_stream(struct console_pvt *pvt)
 {
-	if (!pvt->streamstate)
+	if (!pvt->streamstate || pvt->thread == AST_PTHREADT_NULL)
 		return 0;
 
 	pthread_cancel(pvt->thread);

Modified: team/russell/events/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/channels/chan_iax2.c?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/channels/chan_iax2.c (original)
+++ team/russell/events/channels/chan_iax2.c Mon Jun  9 16:31:14 2008
@@ -11284,6 +11284,7 @@
 	
 	reload_firmware(0);
 	iax_provision_reload(1);
+	ast_unload_realtime("iaxpeers");
 
 	return 0;
 }
@@ -12034,7 +12035,7 @@
 	con = ast_context_find(regcontext);
 	if (con)
 		ast_context_destroy(con, "IAX2");
-	
+	ast_unload_realtime("iaxpeers");
 	return 0;
 }
 
@@ -12187,6 +12188,8 @@
 	reload_firmware(0);
 	iax_provision_reload(0);
 
+	ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_INTEGER, 5, "regseconds", RQ_INTEGER, 6, NULL);
+
 	return AST_MODULE_LOAD_SUCCESS;
 }
 

Modified: team/russell/events/channels/chan_local.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/channels/chan_local.c?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/channels/chan_local.c (original)
+++ team/russell/events/channels/chan_local.c Mon Jun  9 16:31:14 2008
@@ -812,7 +812,6 @@
 				ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
 		}
 		AST_LIST_UNLOCK(&locals);
-		AST_LIST_HEAD_DESTROY(&locals);
 	} else {
 		ast_log(LOG_WARNING, "Unable to lock the monitor\n");
 		return -1;

Modified: team/russell/events/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/channels/chan_sip.c?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/channels/chan_sip.c (original)
+++ team/russell/events/channels/chan_sip.c Mon Jun  9 16:31:14 2008
@@ -1723,6 +1723,14 @@
 /*! \brief A per-thread temporary pvt structure */
 AST_THREADSTORAGE_CUSTOM(ts_temp_pvt, temp_pvt_init, temp_pvt_cleanup);
 
+#ifdef LOW_MEMORY
+static void ts_ast_rtp_destroy(void *);
+
+AST_THREADSTORAGE_CUSTOM(ts_audio_rtp, NULL, ts_ast_rtp_destroy);
+AST_THREADSTORAGE_CUSTOM(ts_video_rtp, NULL, ts_ast_rtp_destroy);
+AST_THREADSTORAGE_CUSTOM(ts_text_rtp, NULL, ts_ast_rtp_destroy);
+#endif
+
 /*! \brief Authentication list for realm authentication 
  * \todo Move the sip_auth list to AST_LIST */
 static struct sip_auth *authl = NULL;
@@ -2048,7 +2056,7 @@
 static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v);
 
 /* Realtime device support */
-static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expirey, int deprecated_username);
+static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, const char *useragent, int expirey, int deprecated_username);
 static struct sip_user *realtime_user(const char *username);
 static void update_peer(struct sip_peer *p, int expiry);
 static struct ast_variable *get_insecure_variable_from_config(struct ast_config *config);
@@ -3622,7 +3630,7 @@
 	that name and store that in the "regserver" field in the sippeers
 	table to facilitate multi-server setups.
 */
-static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *defaultuser, const char *fullcontact, int expirey, int deprecated_username)
+static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *defaultuser, const char *fullcontact, const char *useragent, int expirey, int deprecated_username)
 {
 	char port[10];
 	char ipaddr[INET_ADDRSTRLEN];
@@ -3648,14 +3656,19 @@
 	else if (sip_cfg.rtsave_sysname)
 		syslabel = "regserver";
 
-	if (fc)
+	if (fc) {
 		ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
 			"port", port, "regseconds", regseconds,
-			deprecated_username ? "username" : "defaultuser", defaultuser, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */
-	else
+			deprecated_username ? "username" : "defaultuser", defaultuser,
+			"useragent", useragent,
+			fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */
+	} else {
 		ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
 			"port", port, "regseconds", regseconds,
-			deprecated_username ? "username" : "defaultuser", defaultuser, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */
+			"useragent", useragent,
+			deprecated_username ? "username" : "defaultuser", defaultuser,
+			syslabel, sysname, NULL); /* note syslabel _can_ be NULL */
+	}
 }
 
 /*! \brief Automatically add peer extension to dial plan */
@@ -3775,7 +3788,7 @@
 	int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
 	if (sip_cfg.peer_rtupdate &&
 	    (p->is_realtime || rtcachefriends)) {
-		realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, expiry, p->deprecated_username);
+		realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, p->useragent, expiry, p->deprecated_username);
 	}
 }
 
@@ -6685,17 +6698,29 @@
 	}
 
 	/* Initialize the temporary RTP structures we use to evaluate the offer from the peer */
+#ifdef LOW_MEMORY
+	newaudiortp = ast_threadstorage_get(&ts_audio_rtp, ast_rtp_alloc_size());
+#else
 	newaudiortp = alloca(ast_rtp_alloc_size());
+#endif
 	memset(newaudiortp, 0, ast_rtp_alloc_size());
 	ast_rtp_new_init(newaudiortp);
 	ast_rtp_pt_clear(newaudiortp);
 
+#ifdef LOW_MEMORY
+	newvideortp = ast_threadstorage_get(&ts_video_rtp, ast_rtp_alloc_size());
+#else
 	newvideortp = alloca(ast_rtp_alloc_size());
+#endif
 	memset(newvideortp, 0, ast_rtp_alloc_size());
 	ast_rtp_new_init(newvideortp);
 	ast_rtp_pt_clear(newvideortp);
 
+#ifdef LOW_MEMORY
+	newtextrtp = ast_threadstorage_get(&ts_text_rtp, ast_rtp_alloc_size());
+#else
 	newtextrtp = alloca(ast_rtp_alloc_size());
+#endif
 	memset(newtextrtp, 0, ast_rtp_alloc_size());
 	ast_rtp_new_init(newtextrtp);
 	ast_rtp_pt_clear(newtextrtp);
@@ -7364,6 +7389,13 @@
 	return 0;
 }
 
+#ifdef LOW_MEMORY
+static void ts_ast_rtp_destroy(void *data)
+{
+    struct ast_rtp *tmp = data;
+    ast_rtp_destroy(tmp);
+}
+#endif
 
 /*! \brief Add header to SIP message */
 static int add_header(struct sip_request *req, const char *var, const char *value)
@@ -9482,6 +9514,65 @@
 	return send_request(p, &req, XMIT_UNRELIABLE, p->ocseq);
 }
 
+static int manager_sipnotify(struct mansession *s, const struct message *m)
+{
+	const char *channame = astman_get_header(m, "Channel");
+	struct ast_variable *vars = astman_get_variables(m);
+	struct sip_pvt *p;
+
+	if (!channame) {
+		astman_send_error(s, m, "SIPNotify requires a channel name");
+		return -1;
+	}
+
+	if (strncasecmp(channame, "sip/", 4) == 0) {
+		channame += 4;
+	}
+
+	if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) {
+		astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)");
+		return -1;
+	}
+
+	if (create_addr(p, channame, NULL)) {
+		/* Maybe they're not registered, etc. */
+		dialog_unlink_all(p, TRUE, TRUE);
+		dialog_unref(p, "unref dialog inside for loop" );
+		/* sip_destroy(p); */
+		astman_send_error(s, m, "Could not create address");
+		return -1;
+	}
+
+	/* Notify is outgoing call */
+	ast_set_flag(&p->flags[0], SIP_OUTGOING);
+
+	/* Recalculate our side, and recalculate Call ID */
+	ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip);
+	build_via(p);
+	ao2_t_unlink(dialogs, p, "About to change the callid -- remove the old name");
+	build_callid_pvt(p);
+	ao2_t_link(dialogs, p, "Linking in new name");
+	dialog_ref(p, "bump the count of p, which transmit_sip_request will decrement.");
+	sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
+
+	if (!transmit_notify_custom(p, vars)) {
+		astman_send_ack(s, m, "Notify Sent");
+	} else {
+		astman_send_error(s, m, "Unable to send notify");
+	}
+	ast_variables_destroy(vars);
+	return 0;
+}
+
+static char mandescr_sipnotify[] =
+"Description: Sends a SIP Notify event\n"
+"All parameters for this event must be specified in the body of this request\n"
+"via multiple Variable: name=value sequences.\n"
+"Variables: \n"
+"  *Channel: <peername>       Peer to receive the notify. Required.\n"
+"  *Variable: <name>=<value>  At least one variable pair must be specified.\n"
+"  ActionID: <id>             Action ID for this transaction. Will be returned.\n";
+
 static const struct _map_x_s regstatestrings[] = {
 	{ REG_STATE_FAILED,     "Failed" },
 	{ REG_STATE_UNREGISTERED, "Unregistered"},
@@ -10007,7 +10098,7 @@
 
 	if (!sip_cfg.ignore_regexpire) {
 		if (peer->rt_fromcontact)
-			ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", peer->deprecated_username ? "username" : "defaultuser", "", "regserver", "", NULL);
+			ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", peer->deprecated_username ? "username" : "defaultuser", "", "regserver", "", "useragent", "", NULL);
 		else 
 			ast_db_del("SIP/Registry", peer->name);
 	}
@@ -21334,7 +21425,8 @@
 	time_t run_start, run_end;
 	
 	run_start = time(0);
-	
+	ast_unload_realtime("sipregs");
+	ast_unload_realtime("sippeers");
 	cfg = ast_config_load(config, config_flags);
 
 	/* We *must* have a config file otherwise stop immediately */
@@ -22760,12 +22852,25 @@
 			"Show SIP peer (text format)", mandescr_show_peer);
 	ast_manager_register2("SIPshowregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_show_registry,
 			"Show SIP registrations (text format)", mandescr_show_registry);
+	ast_manager_register2("SIPnotify", EVENT_FLAG_SYSTEM, manager_sipnotify,
+			"Send a SIP notify", mandescr_sipnotify);
 	sip_poke_all_peers();	
 	sip_send_all_registers();
 	
 	/* And start the monitor for the first time */
 	restart_monitor();
 
+	ast_realtime_require_field(ast_check_realtime("sipregs") ? "sipregs" : "sippeers",
+		"name", RQ_CHAR, 10,
+		"ipaddr", RQ_CHAR, 15,
+		"port", RQ_INTEGER, 5,
+		"regseconds", RQ_INTEGER, 5,
+		"defaultuser", RQ_CHAR, 10,
+		"fullcontact", RQ_CHAR, 20,
+		"regserver", RQ_CHAR, 20,
+		"useragent", RQ_CHAR, 20,
+		NULL);
+
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
@@ -22806,6 +22911,7 @@
 	ast_manager_unregister("SIPshowpeer");
 	ast_manager_unregister("SIPqualifypeer");
 	ast_manager_unregister("SIPshowregistry");
+	ast_manager_unregister("SIPnotify");
 	
 	/* Kill TCP/TLS server threads */
 	if (sip_tcp_desc.master)
@@ -22879,6 +22985,8 @@
 	con = ast_context_find(used_context);
 	if (con)
 		ast_context_destroy(con, "SIP");
+	ast_unload_realtime("sipregs");
+	ast_unload_realtime("sippeers");
 
 	return 0;
 }

Modified: team/russell/events/configs/res_pgsql.conf.sample
URL: http://svn.digium.com/view/asterisk/team/russell/events/configs/res_pgsql.conf.sample?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/configs/res_pgsql.conf.sample (original)
+++ team/russell/events/configs/res_pgsql.conf.sample Mon Jun  9 16:31:14 2008
@@ -12,3 +12,11 @@
 dbname=asterisk
 dbuser=asterisk
 dbpass=password
+;
+; requirements - At startup, each realtime family will make requirements
+; on the backend.  There are several strategies for handling requirements:
+; warn        - Warn if the required column does not exist.
+; createclose - Create columns as close to the requirements as possible.
+; createchar  - Create char columns only
+;
+requirements=warn

Modified: team/russell/events/contrib/scripts/dbsep.cgi
URL: http://svn.digium.com/view/asterisk/team/russell/events/contrib/scripts/dbsep.cgi?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/contrib/scripts/dbsep.cgi (original)
+++ team/russell/events/contrib/scripts/dbsep.cgi Mon Jun  9 16:31:14 2008
@@ -28,6 +28,7 @@
 # dsn=<some valid dsn>
 # dbuser=<user>
 # dbpass=<passwd>
+# dbschema=<dbname>
 # backslash_is_escape={yes|no}
 #
 open CFG, "</etc/asterisk/dbsep.conf";
@@ -120,6 +121,43 @@
 	$affected = $dbh->do($sql);
 	$dbh->disconnect();
 	print "Content-type: text/html\n\n$affected\n";
+} elsif ($ENV{PATH_INFO} =~ m/require$/) {
+	my $result = 0;
+	my $dbh = DBI->connect($cfg{dsn}, $cfg{dbuser}, $cfg{dbpass});
+	my $sql = "SELECT data_type, character_maximum_length FROM information_schema.tables AS t " .
+			"JOIN information_schema.columns AS c " .
+			"ON t.table_catalog=c.table_catalog AND " .
+			"t.table_schema=c.table_schema AND " .
+			"t.table_name=c.table_name " .
+			"WHERE c.table_schema='$cfg{dbschema}' AND " .
+			"c.table_name=? AND c.column_name=?";
+	my $sth = $dbh->prepare($sql);
+	foreach my $param (cgi_to_where_clause($cgi, \%cfg)) {
+		my ($colname, $value) = split /=/, $param;
+		my ($type, $size) = split /:/, $value;
+		$sth->execute($table, $colname);
+		my ($dbtype, $dblen) = $sth->fetchrow_array();
+		$sth->finish();
+		if ($type eq 'char') {
+			if ($dbtype !~ m#char#i) {
+				print STDERR "REQUIRE: $table: Type of column $colname requires char($size), but column is of type $dbtype instead!\n";
+				$result = -1;
+			} elsif ($dblen < $size) {
+				print STDERR "REQUIRE: $table: Size of column $colname requires $size, but column is only $dblen long!\n";
+				$result = -1;
+			}
+		} elsif ($type eq 'integer') {
+			if ($dbtype =~ m#char#i and $dblen < $size) {
+				print STDERR "REQUIRE: $table: Size of column $colname requires $size, but column is only $dblen long!\n";
+				$result = -1;
+			} elsif ($dbtype !~ m#int|float|double|dec|num#i) {
+				print STDERR "REQUIRE: $table: Type of column $colname requires integer($size), but column is of type $dbtype instead!\n";
+				$result = -1;
+			}
+		} # TODO More type checks
+	}
+	$dbh->disconnect();
+	print "Content-type: text/html\n\n$result\n";
 } elsif ($ENV{PATH_INFO} =~ m/static$/) {
 	# file parameter in GET, no POST
 	my (@get, $filename, $sql, $sth);

Modified: team/russell/events/include/asterisk/config.h
URL: http://svn.digium.com/view/asterisk/team/russell/events/include/asterisk/config.h?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/include/asterisk/config.h (original)
+++ team/russell/events/include/asterisk/config.h Mon Jun  9 16:31:14 2008
@@ -46,6 +46,17 @@
 
 #define	CONFIG_STATUS_FILEUNCHANGED	(void *)-1
 
+/*!
+ * \brief Types used in ast_realtime_require_field
+ */
+typedef enum {
+	RQ_INTEGER,
+	RQ_CHAR,
+	RQ_FLOAT,
+	RQ_DATE,
+	RQ_DATETIME,
+} require_type;
+
 /*! \brief Structure for variables, used for configurations and for channel variables 
 */
 struct ast_variable {
@@ -70,6 +81,8 @@
 typedef int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
 typedef int realtime_store(const char *database, const char *table, va_list ap);
 typedef int realtime_destroy(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
+typedef int realtime_require(const char *database, const char *table, va_list ap);
+typedef int realtime_unload(const char *database, const char *table);
 
 /*! \brief Configuration engine structure, used to define realtime drivers */
 struct ast_config_engine {
@@ -80,6 +93,8 @@
 	realtime_update *update_func;
 	realtime_store *store_func;
 	realtime_destroy *destroy_func;
+	realtime_require *require_func;
+	realtime_unload *unload_func;
 	struct ast_config_engine *next;
 };
 
@@ -185,6 +200,26 @@
 struct ast_variable *ast_load_realtime(const char *family, ...) attribute_sentinel;
 struct ast_variable *ast_load_realtime_all(const char *family, ...) attribute_sentinel;
 
+/*!
+ * \brief Release any resources cached for a realtime family
+ * \param family which family/config to destroy
+ * Various backends may cache attributes about a realtime data storage
+ * facility; on reload, a front end resource may request to purge that cache.
+ */
+int ast_unload_realtime(const char *family);
+
+/*!
+ * \brief Inform realtime what fields that may be stored
+ * \param family which family/config is referenced
+ * This will inform builtin configuration backends that particular fields
+ * may be updated during the use of that configuration section.  This is
+ * mainly to be used during startup routines, to ensure that various fields
+ * exist in the backend.  The backends may take various actions, such as
+ * creating new fields in the data store or warning the administrator that
+ * new fields may need to be created, in order to ensure proper function.
+ */
+int ast_require_realtime_fields(const char *family, ...) attribute_sentinel;
+
 /*! 
  * \brief Retrieve realtime configuration 
  * \param family which family/config to lookup
@@ -231,6 +266,8 @@
  * \return 1 if family is configured in realtime and engine exists
 */
 int ast_check_realtime(const char *family);
+
+int ast_realtime_require_field(const char *family, ...) attribute_sentinel;
 
 /*! \brief Check if there's any realtime engines loaded */
 int ast_realtime_enabled(void);

Modified: team/russell/events/include/asterisk/res_odbc.h
URL: http://svn.digium.com/view/asterisk/team/russell/events/include/asterisk/res_odbc.h?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/include/asterisk/res_odbc.h (original)
+++ team/russell/events/include/asterisk/res_odbc.h Mon Jun  9 16:31:14 2008
@@ -30,6 +30,7 @@
 #include <sql.h>
 #include <sqlext.h>
 #include <sqltypes.h>
+#include "asterisk/linkedlists.h"
 
 typedef enum { ODBC_SUCCESS=0, ODBC_FAIL=-1} odbc_status;
 
@@ -42,6 +43,27 @@
 	unsigned int used:1;
 	unsigned int up:1;
 	AST_LIST_ENTRY(odbc_obj) list;
+};
+
+/*!\brief These aren't used in any API calls, but they are kept in a common
+ * location, simply for convenience and to avoid duplication.
+ */
+struct odbc_cache_columns {
+	char *name;
+	SQLSMALLINT type;
+	SQLINTEGER size;
+	SQLSMALLINT decimals;
+	SQLSMALLINT radix;
+	SQLSMALLINT nullable;
+	SQLINTEGER octetlen;
+	AST_RWLIST_ENTRY(odbc_cache_columns) list;
+};
+
+struct odbc_cache_tables {
+	char *connection;
+	char *table;
+	AST_RWLIST_HEAD(_columns, odbc_cache_columns) columns;
+	AST_RWLIST_ENTRY(odbc_cache_tables) list;
 };
 
 /* functions */

Modified: team/russell/events/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/main/channel.c?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/main/channel.c (original)
+++ team/russell/events/main/channel.c Mon Jun  9 16:31:14 2008
@@ -1035,6 +1035,7 @@
 
 		ast_channel_unlock(chan);
 	}
+
 	return ast_queue_frame(chan, &f);
 }
 
@@ -1556,9 +1557,11 @@
 int ast_softhangup(struct ast_channel *chan, int cause)
 {
 	int res;
+
 	ast_channel_lock(chan);
 	res = ast_softhangup_nolock(chan, cause);
 	ast_channel_unlock(chan);
+
 	return res;
 }
 
@@ -2559,7 +2562,7 @@
 					ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass, chan->name);
 					f->len = AST_MIN_DTMF_DURATION;
 				}
-				if (f->len < AST_MIN_DTMF_DURATION) {
+				if (f->len < AST_MIN_DTMF_DURATION && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) {
 					ast_log(LOG_DTMF, "DTMF end '%c' has duration %ld but want minimum %d, emulating on %s\n", f->subclass, f->len, AST_MIN_DTMF_DURATION, chan->name);
 					ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
 					chan->emulate_dtmf_digit = f->subclass;
@@ -2568,6 +2571,9 @@
 					f = &ast_null_frame;
 				} else {
 					ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass, chan->name);
+					if (f->len < AST_MIN_DTMF_DURATION) {
+						f->len = AST_MIN_DTMF_DURATION;
+					}
 					chan->dtmf_tv = now;
 				}
 				if (chan->audiohooks) {

Modified: team/russell/events/main/config.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/main/config.c?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/main/config.c (original)
+++ team/russell/events/main/config.c Mon Jun  9 16:31:14 2008
@@ -2101,6 +2101,38 @@
 	return config_maps ? 1 : 0;
 }
 
+int ast_realtime_require_field(const char *family, ...)
+{
+	struct ast_config_engine *eng;
+	char db[256] = "";
+	char table[256] = "";
+	va_list ap;
+	int res = -1;
+
+	va_start(ap, family);
+	eng = find_engine(family, db, sizeof(db), table, sizeof(table));
+	if (eng && eng->require_func) {
+		res = eng->require_func(db, table, ap);
+	}
+	va_end(ap);
+
+	return res;
+}
+
+int ast_unload_realtime(const char *family)
+{
+	struct ast_config_engine *eng;
+	char db[256] = "";
+	char table[256] = "";
+	int res = -1;
+
+	eng = find_engine(family, db, sizeof(db), table, sizeof(table));
+	if (eng && eng->unload_func) {
+		res = eng->unload_func(db, table);
+	}
+	return res;
+}
+
 struct ast_config *ast_load_realtime_multientry(const char *family, ...)
 {
 	struct ast_config_engine *eng;

Modified: team/russell/events/main/dsp.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/main/dsp.c?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/main/dsp.c (original)
+++ team/russell/events/main/dsp.c Mon Jun  9 16:31:14 2008
@@ -556,7 +556,6 @@
 		ast_debug(10, "tone %d, Ew=%.2E, Et=%.2E, s/n=%10.2f\n", s->freq, tone_energy, s->energy, tone_energy / (s->energy - tone_energy));
 		hit = 0;
 		if (tone_energy > s->energy * s->threshold) {
-
 			ast_debug(10, "Hit! count=%d\n", s->hit_count);
 			hit = 1;
 		}

Modified: team/russell/events/main/features.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/main/features.c?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/main/features.c (original)
+++ team/russell/events/main/features.c Mon Jun  9 16:31:14 2008
@@ -464,11 +464,12 @@
 	struct parkeduser *pu;
 	int i, x = -1, parking_range;
 	struct ast_context *con;
-	const char *parkinglotname;
+	const char *parkinglotname = NULL;
 	const char *parkingexten;
 	struct ast_parkinglot *parkinglot = NULL;
 	
-	parkinglotname = findparkinglotname(peer);
+	if (peer)
+		parkinglotname = findparkinglotname(peer);
 
 	if (parkinglotname) {
 		if (option_debug)

Modified: team/russell/events/main/pbx.c
URL: http://svn.digium.com/view/asterisk/team/russell/events/main/pbx.c?view=diff&rev=121364&r1=121363&r2=121364
==============================================================================
--- team/russell/events/main/pbx.c (original)
+++ team/russell/events/main/pbx.c Mon Jun  9 16:31:14 2008
@@ -309,7 +309,7 @@
 int pbx_builtin_setvar_multiple(struct ast_channel *, void *);
 static int pbx_builtin_importvar(struct ast_channel *, void *);
 static void set_ext_pri(struct ast_channel *c, const char *exten, int pri); 
-static void new_find_extension(const char *str, struct scoreboard *score, struct match_char *tree, int length, int spec, const char *callerid, enum ext_match_t action);
+static void new_find_extension(const char *str, struct scoreboard *score, struct match_char *tree, int length, int spec, const char *callerid, const char *label, enum ext_match_t action);
 static struct match_char *already_in_tree(struct match_char *current, char *pat);
 static struct match_char *add_exten_to_pattern_tree(struct ast_context *con, struct ast_exten *e1, int findonly);
 static struct match_char *add_pattern_node(struct ast_context *con, struct match_char *current, char *pattern, int is_pattern, int already, int specificity, struct match_char **parent);
@@ -1020,9 +1020,10 @@
 
 #endif
 
-static void new_find_extension(const char *str, struct scoreboard *score, struct match_char *tree, int length, int spec, const char *callerid, enum ext_match_t action)
+static void new_find_extension(const char *str, struct scoreboard *score, struct match_char *tree, int length, int spec, const char *label, const char *callerid, enum ext_match_t action)
 {
 	struct match_char *p; /* note minimal stack storage requirements */
+	struct ast_exten pattern = { .label = label };
 #ifdef DEBUG_THIS
 	if (tree)
 		ast_log(LOG_NOTICE,"new_find_extension called with %s on (sub)tree %s action=%s\n", str, tree->x, action2str(action));
@@ -1034,11 +1035,18 @@
 			if (p->x[1] == 0 && *str >= '2' && *str <= '9' ) {
 #define NEW_MATCHER_CHK_MATCH	       \
 				if (p->exten && !(*(str+1))) { /* if a shorter pattern matches along the way, might as well report it */             \

[... 1097 lines stripped ...]



More information about the svn-commits mailing list