From c017c24b8ed4d9959128945f95e2c3ee5293c9da Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthm@freeswitch.org>
Date: Tue, 25 May 2010 16:54:13 -0500
Subject: [PATCH] FSCORE-612 with mods

---
 src/include/private/switch_core_pvt.h         |  2 +-
 src/include/switch_core.h                     | 11 +++
 src/include/switch_types.h                    |  5 +-
 .../applications/mod_commands/mod_commands.c  | 16 ++++-
 .../languages/mod_managed/freeswitch_wrap.cxx | 51 ++++++++++++++
 src/mod/languages/mod_managed/managed/swig.cs | 43 +++++++++++-
 .../mod_spidermonkey/mod_spidermonkey.c       | 17 ++++-
 src/switch_core.c                             | 68 ++++++++++++-------
 src/switch_core_sqldb.c                       | 10 +--
 src/switch_cpp.cpp                            | 13 ++++
 src/switch_event.c                            |  4 +-
 11 files changed, 197 insertions(+), 43 deletions(-)

diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h
index 882c3c331a..bc174c67eb 100644
--- a/src/include/private/switch_core_pvt.h
+++ b/src/include/private/switch_core_pvt.h
@@ -195,7 +195,7 @@ struct switch_runtime {
 	switch_time_t initiated;
 	switch_time_t reference;
 	int64_t offset;
-	switch_hash_t *global_vars;
+	switch_event_t *global_vars;
 	switch_hash_t *mime_types;
 	switch_memory_pool_t *memory_pool;
 	const switch_state_handler_table_t *state_handlers[SWITCH_MAX_STATE_HANDLERS];
diff --git a/src/include/switch_core.h b/src/include/switch_core.h
index c75b1868d5..9db7385cce 100644
--- a/src/include/switch_core.h
+++ b/src/include/switch_core.h
@@ -750,6 +750,17 @@ SWITCH_DECLARE(char *) switch_core_get_variable(_In_z_ const char *varname);
 */
 SWITCH_DECLARE(void) switch_core_set_variable(_In_z_ const char *varname, _In_opt_z_ const char *value);
 
+/*! 
+  \brief Conditionally add a global variable to the core
+  \param varname the name of the variable
+  \param value the value of the variable
+  \param val2 the value of the variable to verify against
+  \     If the global did not exist and val2=="", add global with value, return true
+  \     If the global exists with the value of val2, replace it, return true
+  \     If the global exists with a value other than val2, return false
+*/
+SWITCH_DECLARE(switch_bool_t) switch_core_set_var_conditional(_In_z_ const char *varname, _In_opt_z_ const char *value, _In_opt_z_ const char *val2);
+
 SWITCH_DECLARE(void) switch_core_dump_variables(_In_ switch_stream_handle_t *stream);
 
 /*! 
diff --git a/src/include/switch_types.h b/src/include/switch_types.h
index 903b9527f2..c5781b5249 100644
--- a/src/include/switch_types.h
+++ b/src/include/switch_types.h
@@ -754,8 +754,9 @@ SWITCH_STACK_TOP	- Stack on the top
 </pre>
  */
 typedef enum {
-	SWITCH_STACK_BOTTOM,
-	SWITCH_STACK_TOP
+	SWITCH_STACK_BOTTOM = (1 << 0),
+	SWITCH_STACK_TOP = (1 << 1),
+	SWITCH_STACK_NODUP = (1 << 2)
 } switch_stack_t;
 
 /*!
diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c
index 500f35c44d..e0011e48c0 100644
--- a/src/mod/applications/mod_commands/mod_commands.c
+++ b/src/mod/applications/mod_commands/mod_commands.c
@@ -3966,10 +3966,10 @@ SWITCH_STANDARD_API(uuid_dump_function)
 	return SWITCH_STATUS_SUCCESS;
 }
 
-#define GLOBAL_SETVAR_SYNTAX "<var> <value>"
+#define GLOBAL_SETVAR_SYNTAX "<var> <value> [<value2>]"
 SWITCH_STANDARD_API(global_setvar_function)
 {
-	char *mycmd = NULL, *argv[2] = { 0 };
+	char *mycmd = NULL, *argv[3] = { 0 };
 	int argc = 0;
 
 	if (!zstr(cmd) && (mycmd = strdup(cmd))) {
@@ -3977,11 +3977,21 @@ SWITCH_STANDARD_API(global_setvar_function)
 		if (argc > 0 && !zstr(argv[0])) {
 			char *var_name = argv[0];
 			char *var_value = argv[1];
+			char *var_value2 = argv[2];
 
 			if (zstr(var_value)) {
 				var_value = NULL;
 			}
-			switch_core_set_variable(var_name, var_value);
+
+			if (zstr(var_value2)) {
+				var_value2 = NULL;
+			}
+
+			if (var_value2) {
+				switch_core_set_var_conditional(var_name, var_value, var_value2);
+			} else {
+				switch_core_set_variable(var_name, var_value);
+			}
 			stream->write_function(stream, "+OK");
 			goto done;
 		}
diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx
index b60c95026e..24f2c4aff2 100644
--- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx
+++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx
@@ -3389,6 +3389,29 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_rtcp_hdr_t(void * jarg1) {
 }
 
 
+SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_T38FaxVersion_set(void * jarg1, unsigned short jarg2) {
+  switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ;
+  uint16_t arg2 ;
+  
+  arg1 = (switch_t38_options_t *)jarg1; 
+  arg2 = (uint16_t)jarg2; 
+  if (arg1) (arg1)->T38FaxVersion = arg2;
+  
+}
+
+
+SWIGEXPORT unsigned short SWIGSTDCALL CSharp_switch_t38_options_t_T38FaxVersion_get(void * jarg1) {
+  unsigned short jresult ;
+  switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ;
+  uint16_t result;
+  
+  arg1 = (switch_t38_options_t *)jarg1; 
+  result = (uint16_t) ((arg1)->T38FaxVersion);
+  jresult = result; 
+  return jresult;
+}
+
+
 SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_T38MaxBitRate_set(void * jarg1, unsigned long jarg2) {
   switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ;
   uint32_t arg2 ;
@@ -6962,6 +6985,22 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_set_variable(char * jarg1, char *
 }
 
 
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_set_var_conditional(char * jarg1, char * jarg2, char * jarg3) {
+  int jresult ;
+  char *arg1 = (char *) 0 ;
+  char *arg2 = (char *) 0 ;
+  char *arg3 = (char *) 0 ;
+  switch_bool_t result;
+  
+  arg1 = (char *)jarg1; 
+  arg2 = (char *)jarg2; 
+  arg3 = (char *)jarg3; 
+  result = (switch_bool_t)switch_core_set_var_conditional((char const *)arg1,(char const *)arg2,(char const *)arg3);
+  jresult = result; 
+  return jresult;
+}
+
+
 SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_dump_variables(void * jarg1) {
   switch_stream_handle_t *arg1 = (switch_stream_handle_t *) 0 ;
   
@@ -26562,6 +26601,18 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_set_max_missed_packets(void * jarg
 }
 
 
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_udptl_mode(void * jarg1) {
+  int jresult ;
+  switch_rtp_t *arg1 = (switch_rtp_t *) 0 ;
+  switch_status_t result;
+  
+  arg1 = (switch_rtp_t *)jarg1; 
+  result = (switch_status_t)switch_rtp_udptl_mode(arg1);
+  jresult = result; 
+  return jresult;
+}
+
+
 SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_set_local_address(void * jarg1, char * jarg2, unsigned short jarg3, void * jarg4) {
   int jresult ;
   switch_rtp_t *arg1 = (switch_rtp_t *) 0 ;
diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs
index c2196a446d..8a8067ffc3 100644
--- a/src/mod/languages/mod_managed/managed/swig.cs
+++ b/src/mod/languages/mod_managed/managed/swig.cs
@@ -1308,6 +1308,11 @@ public class freeswitch {
     freeswitchPINVOKE.switch_core_set_variable(varname, value);
   }
 
+  public static switch_bool_t switch_core_set_var_conditional(string varname, string value, string val2) {
+    switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_core_set_var_conditional(varname, value, val2);
+    return ret;
+  }
+
   public static void switch_core_dump_variables(switch_stream_handle stream) {
     freeswitchPINVOKE.switch_core_dump_variables(switch_stream_handle.getCPtr(stream));
   }
@@ -4110,6 +4115,11 @@ public class freeswitch {
     freeswitchPINVOKE.switch_rtp_set_max_missed_packets(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), max);
   }
 
+  public static switch_status_t switch_rtp_udptl_mode(SWIGTYPE_p_switch_rtp rtp_session) {
+    switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_udptl_mode(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session));
+    return ret;
+  }
+
   public static switch_status_t switch_rtp_set_local_address(SWIGTYPE_p_switch_rtp rtp_session, string host, ushort port, ref string err) {
     switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_set_local_address(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), host, port, ref err);
     return ret;
@@ -5953,6 +5963,12 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_rtcp_hdr_t")]
   public static extern void delete_switch_rtcp_hdr_t(HandleRef jarg1);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_T38FaxVersion_set")]
+  public static extern void switch_t38_options_t_T38FaxVersion_set(HandleRef jarg1, ushort jarg2);
+
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_T38FaxVersion_get")]
+  public static extern ushort switch_t38_options_t_T38FaxVersion_get(HandleRef jarg1);
+
   [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_T38MaxBitRate_set")]
   public static extern void switch_t38_options_t_T38MaxBitRate_set(HandleRef jarg1, uint jarg2);
 
@@ -6814,6 +6830,9 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_switch_core_set_variable")]
   public static extern void switch_core_set_variable(string jarg1, string jarg2);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_core_set_var_conditional")]
+  public static extern int switch_core_set_var_conditional(string jarg1, string jarg2, string jarg3);
+
   [DllImport("mod_managed", EntryPoint="CSharp_switch_core_dump_variables")]
   public static extern void switch_core_dump_variables(HandleRef jarg1);
 
@@ -11353,6 +11372,9 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_max_missed_packets")]
   public static extern void switch_rtp_set_max_missed_packets(HandleRef jarg1, uint jarg2);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_udptl_mode")]
+  public static extern int switch_rtp_udptl_mode(HandleRef jarg1);
+
   [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_local_address")]
   public static extern int switch_rtp_set_local_address(HandleRef jarg1, string jarg2, ushort jarg3, ref string jarg4);
 
@@ -19815,7 +19837,8 @@ namespace FreeSWITCH.Native {
 namespace FreeSWITCH.Native {
 
 public enum switch_channel_app_flag_t {
-  CF_APP_TAGGED = (1 << 0)
+  CF_APP_TAGGED = (1 << 0),
+  CF_APP_T38 = (1 << 1)
 }
 
 }
@@ -21622,6 +21645,8 @@ public enum switch_core_session_message_types_t {
   SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC,
   SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC_COMPLETE,
   SWITCH_MESSAGE_INDICATE_PHONE_EVENT,
+  SWITCH_MESSAGE_INDICATE_T38_DESCRIPTION,
+  SWITCH_MESSAGE_INDICATE_UDPTL_MODE,
   SWITCH_MESSAGE_INVALID
 }
 
@@ -22508,6 +22533,7 @@ public class switch_dtmf_t : IDisposable {
 namespace FreeSWITCH.Native {
 
 [System.Flags] public enum switch_eavesdrop_flag_enum_t {
+  ED_NONE = 0,
   ED_MUX_READ = (1 << 0),
   ED_MUX_WRITE = (1 << 1),
   ED_DTMF = (1 << 2)
@@ -23952,7 +23978,8 @@ namespace FreeSWITCH.Native {
   SFF_RFC2833 = (1 << 4),
   SFF_PROXY_PACKET = (1 << 5),
   SFF_DYNAMIC = (1 << 6),
-  SFF_ZRTP = (1 << 7)
+  SFF_ZRTP = (1 << 7),
+  SFF_UDPTL_PACKET = (1 << 8)
 }
 
 }
@@ -26182,7 +26209,7 @@ namespace FreeSWITCH.Native {
   SWITCH_RTP_FLAG_GOOGLEHACK = (1 << 8),
   SWITCH_RTP_FLAG_VAD = (1 << 9),
   SWITCH_RTP_FLAG_BREAK = (1 << 10),
-  SWITCH_RTP_FLAG_MINI = (1 << 11),
+  SWITCH_RTP_FLAG_UDPTL = (1 << 11),
   SWITCH_RTP_FLAG_DATAWAIT = (1 << 12),
   SWITCH_RTP_FLAG_BUGGY_2833 = (1 << 13),
   SWITCH_RTP_FLAG_PASS_RFC2833 = (1 << 14),
@@ -27962,6 +27989,16 @@ public class switch_t38_options_t : IDisposable {
     }
   }
 
+  public ushort T38FaxVersion {
+    set {
+      freeswitchPINVOKE.switch_t38_options_t_T38FaxVersion_set(swigCPtr, value);
+    } 
+    get {
+      ushort ret = freeswitchPINVOKE.switch_t38_options_t_T38FaxVersion_get(swigCPtr);
+      return ret;
+    } 
+  }
+
   public uint T38MaxBitRate {
     set {
       freeswitchPINVOKE.switch_t38_options_t_T38MaxBitRate_set(swigCPtr, value);
diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
index 532123dd74..1ff5071317 100644
--- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
+++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
@@ -3331,12 +3331,23 @@ static JSBool js_log(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, j
 
 static JSBool js_global_set(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
 {
-	char *var_name = NULL, *val = NULL;
+	char *var_name = NULL, *val = NULL, *val2 = NULL;
+	JSBool tf = JS_TRUE;
 	if (argc > 1) {
 		var_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
 		val = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
-		switch_core_set_variable(var_name, val);
-		return JS_TRUE;
+		if (argc == 2) {
+			switch_core_set_variable(var_name, val);
+			*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
+			return JS_TRUE;
+		} else {
+			val2 = JS_GetStringBytes(JS_ValueToString(cx, argv[2]));
+			if (switch_core_set_var_conditional(var_name, val, val2) != SWITCH_TRUE) {
+				tf = JS_FALSE;
+			}
+			*rval = BOOLEAN_TO_JSVAL(tf);
+			return JS_TRUE;
+		}
 	}
 	/* this is so the wrong error message to throw for this one */
 	eval_some_js("~throw new Error(\"var name not supplied!\");", cx, obj, rval);
diff --git a/src/switch_core.c b/src/switch_core.c
index 3dfcdb239f..d24ea835b9 100644
--- a/src/switch_core.c
+++ b/src/switch_core.c
@@ -244,16 +244,11 @@ SWITCH_DECLARE(const switch_state_handler_table_t *) switch_core_get_state_handl
 
 SWITCH_DECLARE(void) switch_core_dump_variables(switch_stream_handle_t *stream)
 {
-	switch_hash_index_t *hi;
-	const void *var;
-	void *val;
+	switch_event_header_t *hi;
+
 	switch_mutex_lock(runtime.global_mutex);
-	for (hi = switch_hash_first(NULL, runtime.global_vars); hi; hi = switch_hash_next(hi)) {
-		char *vvar, *vval;
-		switch_hash_this(hi, &var, NULL, &val);
-		vvar = (char *) var;
-		vval = (char *) val;
-		stream->write_function(stream, "%s=%s\n", vvar, vval);
+	for (hi = runtime.global_vars->headers; hi; hi = hi->next) {
+		stream->write_function(stream, "%s=%s\n", hi->name, hi->value);
 	}
 	switch_mutex_unlock(runtime.global_mutex);
 }
@@ -262,22 +257,16 @@ SWITCH_DECLARE(char *) switch_core_get_variable(const char *varname)
 {
 	char *val;
 	switch_mutex_lock(runtime.global_var_mutex);
-	val = (char *) switch_core_hash_find(runtime.global_vars, varname);
+	val = (char *) switch_event_get_header(runtime.global_vars, varname);
 	switch_mutex_unlock(runtime.global_var_mutex);
 	return val;
 }
 
 static void switch_core_unset_variables(void)
 {
-	switch_hash_index_t *hi;
-	const void *var;
-	void *val;
-
 	switch_mutex_lock(runtime.global_var_mutex);
-	for (hi = switch_hash_first(NULL, runtime.global_vars); hi; hi = switch_hash_next(hi)) {
-		switch_hash_this(hi, &var, NULL, &val);
-		free(val);
-	}
+	switch_event_destroy(&runtime.global_vars);
+	switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA);
 	switch_mutex_unlock(runtime.global_var_mutex);
 }
 
@@ -287,21 +276,52 @@ SWITCH_DECLARE(void) switch_core_set_variable(const char *varname, const char *v
 
 	if (varname) {
 		switch_mutex_lock(runtime.global_var_mutex);
-		val = (char *) switch_core_hash_find(runtime.global_vars, varname);
+		val = (char *) switch_event_get_header(runtime.global_vars, varname);
 		if (val) {
-			free(val);
+			switch_event_del_header(runtime.global_vars, varname);
 		}
 		if (value) {
 			char *v = strdup(value);
 			switch_string_var_check(v, SWITCH_TRUE);
-			switch_core_hash_insert(runtime.global_vars, varname, v);
+			switch_event_add_header_string(runtime.global_vars, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, varname, v);
 		} else {
-			switch_core_hash_delete(runtime.global_vars, varname);
+			switch_event_del_header(runtime.global_vars, varname);
 		}
 		switch_mutex_unlock(runtime.global_var_mutex);
 	}
 }
 
+SWITCH_DECLARE(switch_bool_t) switch_core_set_var_conditional(const char *varname, const char *value, const char *val2)
+{
+	char *val;
+
+	if (varname) {
+		switch_mutex_lock(runtime.global_var_mutex);
+		val = (char *) switch_event_get_header(runtime.global_vars, varname);
+
+		if (val) {
+			if (!val2 || strcmp(val, val2) != 0) {
+				switch_mutex_unlock(runtime.global_var_mutex);
+				return SWITCH_FALSE;
+			}
+			switch_event_del_header(runtime.global_vars, varname);
+		} else if (!zstr(val2)) {
+			switch_mutex_unlock(runtime.global_var_mutex);
+			return SWITCH_FALSE;
+		}
+
+		if (value) {
+			char *v = strdup(value);
+			switch_string_var_check(v, SWITCH_TRUE);
+			switch_event_add_header_string(runtime.global_vars, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, varname, v);
+		} else {
+			switch_event_del_header(runtime.global_vars, varname);
+		}
+		switch_mutex_unlock(runtime.global_var_mutex);
+	}
+	return SWITCH_TRUE;
+}
+
 SWITCH_DECLARE(char *) switch_core_get_uuid(void)
 {
 	return runtime.uuid_str;
@@ -1249,7 +1269,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc
 	switch_mutex_init(&runtime.global_var_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
 	switch_core_set_globals();
 	switch_core_session_init(runtime.memory_pool);
-	switch_core_hash_init(&runtime.global_vars, runtime.memory_pool);
+	switch_event_create_plain(&runtime.global_vars, SWITCH_EVENT_CHANNEL_DATA);
 	switch_core_hash_init(&runtime.mime_types, runtime.memory_pool);
 	load_mime_types();
 	runtime.flags = flags;
@@ -1904,7 +1924,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void)
 	switch_safe_free(SWITCH_GLOBAL_dirs.run_dir);
 	switch_safe_free(SWITCH_GLOBAL_dirs.temp_dir);
 
-	switch_core_hash_destroy(&runtime.global_vars);
+	switch_event_destroy(&runtime.global_vars);
 	switch_core_hash_destroy(&runtime.mime_types);
 
 	if (IP_LIST.hash) {
diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c
index 9ecd011bf2..6608d2d219 100644
--- a/src/switch_core_sqldb.c
+++ b/src/switch_core_sqldb.c
@@ -91,14 +91,14 @@ static void sql_close(time_t prune)
 	switch_mutex_lock(sql_manager.dbh_mutex);
   top:
 	locked = 0;
-
+	printf("WTF1\n");
 	for (hi = switch_hash_first(NULL, sql_manager.dbh_hash); hi; hi = switch_hash_next(hi)) {
 		switch_hash_this(hi, &var, NULL, &val);
 		key = (char *) var;
-
+		printf("WTF2\n");
 		if ((dbh = (switch_cache_db_handle_t *) val)) {
 			time_t diff = 0;
-
+			printf("WTF3\n");
 			if (prune > 0 && prune > dbh->last_used) {
 				diff = (time_t) prune - dbh->last_used;
 			}
@@ -106,10 +106,10 @@ static void sql_close(time_t prune)
 			if (prune > 0 && diff < SQL_CACHE_TIMEOUT) {
 				continue;
 			}
-
+			printf("WTF4\n");
 			if (switch_mutex_trylock(dbh->mutex) == SWITCH_STATUS_SUCCESS) {
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Dropping idle DB connection %s\n", key);
-				
+				printf("WTF5\n");
 				switch (dbh->type) {
 				case SCDB_TYPE_ODBC:
 					{
diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp
index b08484fae7..fe1c594c5f 100644
--- a/src/switch_cpp.cpp
+++ b/src/switch_cpp.cpp
@@ -1135,6 +1135,19 @@ SWITCH_DECLARE(void) CoreSession::setHangupHook(void *hangup_func) {
 
 /* ---- methods not bound to CoreSession instance ---- */
 
+
+SWITCH_DECLARE(int) globalSetVariable(const char *var, const char *val, const char *val2)
+{
+	if (zstr(val)) val = NULL;
+	if (zstr(val2)) val2 = NULL;
+	
+	if (val2) {
+		switch_core_set_var_conditional(var, val, val2);
+	} else {
+		switch_core_set_variable(var, val);
+	}
+}
+
 SWITCH_DECLARE(void) consoleLog(char *level_str, char *msg)
 {
 	return console_log(level_str, msg);
diff --git a/src/switch_event.c b/src/switch_event.c
index f473f3d40a..464cd00a8e 100644
--- a/src/switch_event.c
+++ b/src/switch_event.c
@@ -772,7 +772,7 @@ switch_status_t switch_event_base_add_header(switch_event_t *event, switch_stack
 	header->value = data;
 	header->hash = switch_ci_hashfunc_default(header->name, &hlen);
 
-	if (stack == SWITCH_STACK_TOP) {
+	if ((stack & SWITCH_STACK_TOP)) {
 		header->next = event->headers;
 		event->headers = header;
 		if (!event->last_header) {
@@ -823,7 +823,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_set_subclass_name(switch_event_t *e
 SWITCH_DECLARE(switch_status_t) switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
 {
 	if (data) {
-		return switch_event_base_add_header(event, stack, header_name, DUP(data));
+		return switch_event_base_add_header(event, stack, header_name, (stack & SWITCH_STACK_NODUP) ? (char *)data : DUP(data));
 	}
 	return SWITCH_STATUS_GENERR;
 }