From 6a32e98c492f66fb5914e5f585c62f88bad09714 Mon Sep 17 00:00:00 2001
From: Mathieu Rene <mrene@avgs.ca>
Date: Tue, 15 May 2012 19:37:41 -0400
Subject: [PATCH 1/6] Add mod_megaco skeleton with basic profile support and a
 lot of todos for Kapil

---
 libs/ldns/install-sh                      |  29 +++--
 src/include/switch_apr.h                  |   3 +-
 src/mod/endpoints/mod_megaco/Makefile     |   3 +
 src/mod/endpoints/mod_megaco/megaco.c     | 132 ++++++++++++++++++++
 src/mod/endpoints/mod_megaco/mod_megaco.c | 141 ++++++++++++++++++++++
 src/mod/endpoints/mod_megaco/mod_megaco.h |  56 +++++++++
 6 files changed, 352 insertions(+), 12 deletions(-)
 create mode 100644 src/mod/endpoints/mod_megaco/Makefile
 create mode 100644 src/mod/endpoints/mod_megaco/megaco.c
 create mode 100644 src/mod/endpoints/mod_megaco/mod_megaco.c
 create mode 100644 src/mod/endpoints/mod_megaco/mod_megaco.h

diff --git a/libs/ldns/install-sh b/libs/ldns/install-sh
index 6781b987bd..a9244eb078 100755
--- a/libs/ldns/install-sh
+++ b/libs/ldns/install-sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2009-04-28.21; # UTC
+scriptversion=2011-01-19.21; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -156,6 +156,10 @@ while test $# -ne 0; do
     -s) stripcmd=$stripprog;;
 
     -t) dst_arg=$2
+	# Protect names problematic for `test' and other utilities.
+	case $dst_arg in
+	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
+	esac
 	shift;;
 
     -T) no_target_directory=true;;
@@ -186,6 +190,10 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
     fi
     shift # arg
     dst_arg=$arg
+    # Protect names problematic for `test' and other utilities.
+    case $dst_arg in
+      -* | [=\(\)!]) dst_arg=./$dst_arg;;
+    esac
   done
 fi
 
@@ -200,7 +208,11 @@ if test $# -eq 0; then
 fi
 
 if test -z "$dir_arg"; then
-  trap '(exit $?); exit' 1 2 13 15
+  do_exit='(exit $ret); exit $ret'
+  trap "ret=129; $do_exit" 1
+  trap "ret=130; $do_exit" 2
+  trap "ret=141; $do_exit" 13
+  trap "ret=143; $do_exit" 15
 
   # Set umask so as not to create temps with too-generous modes.
   # However, 'strip' requires both read and write access to temps.
@@ -228,9 +240,9 @@ fi
 
 for src
 do
-  # Protect names starting with `-'.
+  # Protect names problematic for `test' and other utilities.
   case $src in
-    -*) src=./$src;;
+    -* | [=\(\)!]) src=./$src;;
   esac
 
   if test -n "$dir_arg"; then
@@ -252,12 +264,7 @@ do
       echo "$0: no destination specified." >&2
       exit 1
     fi
-
     dst=$dst_arg
-    # Protect names starting with `-'.
-    case $dst in
-      -*) dst=./$dst;;
-    esac
 
     # If destination is a directory, append the input filename; won't work
     # if double slashes aren't ignored.
@@ -385,7 +392,7 @@ do
 
       case $dstdir in
 	/*) prefix='/';;
-	-*) prefix='./';;
+	[-=\(\)!]*) prefix='./';;
 	*)  prefix='';;
       esac
 
@@ -403,7 +410,7 @@ do
 
       for d
       do
-	test -z "$d" && continue
+	test X"$d" = X && continue
 
 	prefix=$prefix$d
 	if test -d "$prefix"; then
diff --git a/src/include/switch_apr.h b/src/include/switch_apr.h
index 0c8673570f..e125eb9390 100644
--- a/src/include/switch_apr.h
+++ b/src/include/switch_apr.h
@@ -773,7 +773,8 @@ typedef gid_t                     switch_gid_t;
 	 typedef ino_t switch_ino_t;
 	 typedef dev_t switch_dev_t;
 #endif
-	 typedef off64_t switch_off_t;
+
+typedef off_t switch_off_t;
 
 /**
  * Structure for referencing file information
diff --git a/src/mod/endpoints/mod_megaco/Makefile b/src/mod/endpoints/mod_megaco/Makefile
new file mode 100644
index 0000000000..e65d0f78eb
--- /dev/null
+++ b/src/mod/endpoints/mod_megaco/Makefile
@@ -0,0 +1,3 @@
+BASE=../../../..
+LOCAL_OBJS=megaco.o
+include $(BASE)/build/modmake.rules
diff --git a/src/mod/endpoints/mod_megaco/megaco.c b/src/mod/endpoints/mod_megaco/megaco.c
new file mode 100644
index 0000000000..72d03424f1
--- /dev/null
+++ b/src/mod/endpoints/mod_megaco/megaco.c
@@ -0,0 +1,132 @@
+/*
+* Copyright (c) 2012, Sangoma Technologies
+* Mathieu Rene <mrene@avgs.ca>
+* All rights reserved.
+* 
+* <Insert license here>
+*/
+
+#include "mod_megaco.h"
+
+megaco_profile_t *megaco_profile_locate(const char *name) 
+{
+	megaco_profile_t *profile = switch_core_hash_find_rdlock(megaco_globals.profile_hash, name, megaco_globals.profile_rwlock);
+
+	if (profile) {
+		if (switch_thread_rwlock_tryrdlock(profile->rwlock) != SWITCH_STATUS_SUCCESS) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile %s is locked\n", name);
+			profile = NULL;
+		}
+	}
+
+	return profile;
+}
+
+void megaco_profile_release(megaco_profile_t *profile) 
+{
+	switch_thread_rwlock_unlock(profile->rwlock);
+}
+
+static switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload)
+{
+	switch_xml_t cfg, xml, x_profiles, x_profile, x_settings;
+	switch_status_t status = SWITCH_STATUS_FALSE;
+	switch_event_t *event = NULL;
+	int count;
+	const char *file = "megaco.conf";
+
+	if (!(xml = switch_xml_open_cfg(file, &cfg, NULL))) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not open %s\n", file);
+		goto done;
+	}
+
+	if (!(x_profiles = switch_xml_child(cfg, "profiles"))) {
+		goto done;
+	}
+
+	for (x_profile = switch_xml_child(x_profiles, "profile"); x_profile; x_profile = x_profile->next) {
+		const char *name = switch_xml_attr_soft(x_profile, "name");
+		if (strcmp(name, profile->name)) {
+			continue;
+		}
+
+		if (!(x_settings = switch_xml_child(x_profile, "settings"))) {
+			goto done;
+		}
+		count = switch_event_import_xml(switch_xml_child(x_settings, "param"), "name", "value", &event);
+		// status = switch_xml_config_parse_event(event, count, reload, instructions);
+		
+		/* TODO: Initialize stack configuration */
+	}
+
+done:
+	if (xml) {
+		switch_xml_free(xml);	
+	}
+
+	if (event) {
+		switch_event_destroy(&event);
+	}
+	return status;
+}
+
+switch_status_t megaco_profile_start(const char *profilename)
+{
+	switch_memory_pool_t *pool;
+	megaco_profile_t *profile;
+	
+	switch_assert(profilename);
+	
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Starting profile: %s\n", profilename);
+	
+	switch_core_new_memory_pool(&pool);
+	profile = switch_core_alloc(pool, sizeof(*profile));
+	profile->pool = pool;
+	profile->name = switch_core_strdup(pool, profilename);
+	
+	switch_thread_rwlock_create(&profile->rwlock, pool);
+	
+	/* TODO: Kapil: Insert stack per-interface startup code here */
+	
+	switch_core_hash_insert_wrlock(megaco_globals.profile_hash, profile->name, profile, megaco_globals.profile_rwlock);
+	
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Started profile: %s\n", profile->name);
+	
+	return SWITCH_STATUS_SUCCESS;
+fail:
+	switch_core_destroy_memory_pool(&pool);
+	return SWITCH_STATUS_FALSE;	
+}
+
+
+switch_status_t megaco_profile_destroy(megaco_profile_t **profile) 
+{
+
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Stopping profile: %s\n", (*profile)->name);	
+	switch_thread_rwlock_wrlock((*profile)->rwlock);
+	
+	
+	/* TODO: Kapil: Insert stack per-interface shutdown code here */
+
+	
+	switch_thread_rwlock_unlock((*profile)->rwlock);
+	
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Stopped profile: %s\n", (*profile)->name);	
+	switch_core_hash_delete_wrlock(megaco_globals.profile_hash, (*profile)->name, megaco_globals.profile_rwlock);
+	
+	switch_core_destroy_memory_pool(&(*profile)->pool);
+	
+	return SWITCH_STATUS_SUCCESS;	
+}
+
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
diff --git a/src/mod/endpoints/mod_megaco/mod_megaco.c b/src/mod/endpoints/mod_megaco/mod_megaco.c
new file mode 100644
index 0000000000..bf23077e00
--- /dev/null
+++ b/src/mod/endpoints/mod_megaco/mod_megaco.c
@@ -0,0 +1,141 @@
+/*
+* Copyright (c) 2012, Sangoma Technologies
+* Mathieu Rene <mrene@avgs.ca>
+* All rights reserved.
+* 
+* <Insert license here>
+*/
+
+#include "mod_megaco.h"
+
+struct megaco_globals megaco_globals;
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_megaco_load);
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_megaco_shutdown);
+SWITCH_MODULE_DEFINITION(mod_megaco, mod_megaco_load, mod_megaco_shutdown, NULL);
+
+
+#define MEGACO_FUNCTION_SYNTAX "profile [name] [start | stop]"
+SWITCH_STANDARD_API(megaco_function)
+{
+	int argc;
+	char *argv[10];
+	char *dup = NULL;
+	
+	if (zstr(cmd)) {
+		goto usage;
+	}
+	
+	dup = strdup(cmd);
+	argc = switch_split(dup, ' ', argv);
+	
+	if (argc < 1 || zstr(argv[0])) {
+		goto usage;
+	}
+	
+	if (!strcmp(argv[0], "profile")) {
+		if (zstr(argv[1]) || zstr(argv[2])) {
+			goto usage;
+		}
+		if (!strcmp(argv[2], "start")) {
+			megaco_profile_t *profile = megaco_profile_locate(argv[1]);
+			if (profile) {
+				megaco_profile_release(profile);
+				stream->write_function(stream, "-ERR Profile %s is already started\n", argv[2]);
+			} else {
+				megaco_profile_start(argv[1]);
+				stream->write_function(stream, "+OK\n");
+			}
+		} else if (!strcmp(argv[2], "stop")) {
+			megaco_profile_t *profile = megaco_profile_locate(argv[1]);
+			if (profile) {
+				megaco_profile_release(profile);
+				megaco_profile_destroy(&profile);
+				stream->write_function(stream, "+OK\n");
+			} else {
+				stream->write_function(stream, "-ERR No such profile\n");
+			}
+		}
+	}
+	
+	goto done;
+	
+	usage:
+		stream->write_function(stream, "-ERR Usage: "MEGACO_FUNCTION_SYNTAX"\n");
+		
+	done:
+		switch_safe_free(dup);
+		return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t console_complete_hashtable(switch_hash_t *hash, const char *line, const char *cursor, switch_console_callback_match_t **matches)
+{
+	switch_hash_index_t *hi;
+	void *val;
+	const void *vvar;
+	switch_console_callback_match_t *my_matches = NULL;
+	switch_status_t status = SWITCH_STATUS_FALSE;
+
+	for (hi = switch_hash_first(NULL, hash); hi; hi = switch_hash_next(hi)) {
+		switch_hash_this(hi, &vvar, NULL, &val);
+		switch_console_push_match(&my_matches, (const char *) vvar);
+	}
+
+	if (my_matches) {
+		*matches = my_matches;
+		status = SWITCH_STATUS_SUCCESS;
+	}
+
+	return status;
+}
+
+static switch_status_t list_profiles(const char *line, const char *cursor, switch_console_callback_match_t **matches)
+{
+	switch_status_t status;
+	switch_thread_rwlock_rdlock(megaco_globals.profile_rwlock);
+	status = console_complete_hashtable(megaco_globals.profile_hash, line, cursor, matches);
+	switch_thread_rwlock_unlock(megaco_globals.profile_rwlock);
+	return status;
+}
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_megaco_load)
+{
+	switch_api_interface_t *api_interface;
+	
+	memset(&megaco_globals, 0, sizeof(megaco_globals));
+	megaco_globals.pool = pool;
+	
+	*module_interface = switch_loadable_module_create_module_interface(pool, modname);
+		
+	switch_core_hash_init(&megaco_globals.profile_hash, pool);
+	switch_thread_rwlock_create(&megaco_globals.profile_rwlock, pool);
+	
+	SWITCH_ADD_API(api_interface, "megaco", "megaco", megaco_function, MEGACO_FUNCTION_SYNTAX);
+	
+	switch_console_set_complete("add megaco profile ::megaco::list_profiles start");
+	switch_console_set_complete("add megaco profile ::megaco::list_profiles stop");
+	switch_console_add_complete_func("::megaco::list_profiles", list_profiles);
+	
+	/* TODO: Kapil: Insert stack global startup code here */
+	
+	
+	return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_megaco_shutdown)
+{
+	/* TODO: Kapil: Insert stack global shutdown code here */	
+	return SWITCH_STATUS_SUCCESS;
+}
+
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
diff --git a/src/mod/endpoints/mod_megaco/mod_megaco.h b/src/mod/endpoints/mod_megaco/mod_megaco.h
new file mode 100644
index 0000000000..b12982de8c
--- /dev/null
+++ b/src/mod/endpoints/mod_megaco/mod_megaco.h
@@ -0,0 +1,56 @@
+/*
+* Copyright (c) 2012, Sangoma Technologies
+* Mathieu Rene <mrene@avgs.ca>
+* All rights reserved.
+* 
+* <Insert license here>
+*/
+
+
+#ifndef MOD_MEGACO_H
+#define MOD_MEGACO_H
+
+#include <switch.h>
+
+struct megaco_globals {
+	switch_memory_pool_t *pool;
+	switch_hash_t *profile_hash;
+	switch_thread_rwlock_t *profile_rwlock;
+	/* TODO: Kapil: add global variables here */
+};
+extern struct megaco_globals megaco_globals; /* < defined in mod_megaco.c */
+
+typedef enum {
+	PF_RUNNING = (1 << 0)
+} megaco_profile_flags_t;
+
+typedef struct megaco_profile_s {
+	char *name;
+	switch_memory_pool_t *pool;
+	switch_thread_rwlock_t *rwlock; /* < Reference counting rwlock */
+	megaco_profile_flags_t flags;
+	
+	/* TODO: Kapil: Insert interface-specific stack elements here */
+} megaco_profile_t;
+
+
+megaco_profile_t *megaco_profile_locate(const char *name);
+void megaco_profile_release(megaco_profile_t *profile);
+
+switch_status_t megaco_profile_start(const char *profilename);
+switch_status_t megaco_profile_destroy(megaco_profile_t **profile);
+
+
+#endif /* MOD_MEGACO_H */
+
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */

From bb875ce6ff692c129647206ce8956a01fcb8f9d0 Mon Sep 17 00:00:00 2001
From: Mathieu Rene <mrene@avgs.ca>
Date: Tue, 15 May 2012 19:45:36 -0400
Subject: [PATCH 2/6] mod_megaco: add sample config file and refuse to start a
 profile without a configuration

---
 src/mod/endpoints/mod_megaco/conf/megaco.conf.xml | 9 +++++++++
 src/mod/endpoints/mod_megaco/megaco.c             | 8 +++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)
 create mode 100644 src/mod/endpoints/mod_megaco/conf/megaco.conf.xml

diff --git a/src/mod/endpoints/mod_megaco/conf/megaco.conf.xml b/src/mod/endpoints/mod_megaco/conf/megaco.conf.xml
new file mode 100644
index 0000000000..c219023dd8
--- /dev/null
+++ b/src/mod/endpoints/mod_megaco/conf/megaco.conf.xml
@@ -0,0 +1,9 @@
+<configuration name="megaco.conf" description="Megaco Controllee">
+  <profiles>
+	<profile name="default">
+		<settings>
+			<param name="foo" value="bar" />
+		</settings>
+	</profile>
+  </profiles>
+</configuration>
diff --git a/src/mod/endpoints/mod_megaco/megaco.c b/src/mod/endpoints/mod_megaco/megaco.c
index 72d03424f1..9ac7af4355 100644
--- a/src/mod/endpoints/mod_megaco/megaco.c
+++ b/src/mod/endpoints/mod_megaco/megaco.c
@@ -56,7 +56,8 @@ static switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t r
 		count = switch_event_import_xml(switch_xml_child(x_settings, "param"), "name", "value", &event);
 		// status = switch_xml_config_parse_event(event, count, reload, instructions);
 		
-		/* TODO: Initialize stack configuration */
+		/* TODO: Kapil: Initialize stack configuration */
+		status = SWITCH_STATUS_SUCCESS;
 	}
 
 done:
@@ -87,12 +88,17 @@ switch_status_t megaco_profile_start(const char *profilename)
 	switch_thread_rwlock_create(&profile->rwlock, pool);
 	
 	/* TODO: Kapil: Insert stack per-interface startup code here */
+	if (config_profile(profile, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error configuring profile %s\n", profile->name);
+		goto fail;
+	}
 	
 	switch_core_hash_insert_wrlock(megaco_globals.profile_hash, profile->name, profile, megaco_globals.profile_rwlock);
 	
 	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Started profile: %s\n", profile->name);
 	
 	return SWITCH_STATUS_SUCCESS;
+	
 fail:
 	switch_core_destroy_memory_pool(&pool);
 	return SWITCH_STATUS_FALSE;	

From dbd90db7196d98ca17eca90f216af5b0907295a3 Mon Sep 17 00:00:00 2001
From: Mathieu Rene <mrene@avgs.ca>
Date: Tue, 15 May 2012 19:51:58 -0400
Subject: [PATCH 3/6] Add mod_megaco to modules.conf.in

---
 build/modules.conf.in | 1 +
 1 file changed, 1 insertion(+)

diff --git a/build/modules.conf.in b/build/modules.conf.in
index 1d27aaad1b..cc99d528f0 100644
--- a/build/modules.conf.in
+++ b/build/modules.conf.in
@@ -7,6 +7,7 @@ applications/mod_hash
 applications/mod_spandsp
 dialplans/mod_dialplan_xml
 endpoints/mod_sofia
+endpoints/mod_megaco
 ../../libs/freetdm/mod_freetdm
 xml_int/mod_xml_cdr
 event_handlers/mod_event_socket

From f3fe2232f38534fdaa53fa91bca6256f2c474e12 Mon Sep 17 00:00:00 2001
From: Mathieu Rene <mrene@avgs.ca>
Date: Tue, 15 May 2012 19:52:57 -0400
Subject: [PATCH 4/6] Remove stuff that should've been gitignored

---
 libs/ldns/install-sh     | 29 +++++++++++------------------
 src/include/switch_apr.h |  3 +--
 2 files changed, 12 insertions(+), 20 deletions(-)

diff --git a/libs/ldns/install-sh b/libs/ldns/install-sh
index a9244eb078..6781b987bd 100755
--- a/libs/ldns/install-sh
+++ b/libs/ldns/install-sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2011-01-19.21; # UTC
+scriptversion=2009-04-28.21; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -156,10 +156,6 @@ while test $# -ne 0; do
     -s) stripcmd=$stripprog;;
 
     -t) dst_arg=$2
-	# Protect names problematic for `test' and other utilities.
-	case $dst_arg in
-	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
-	esac
 	shift;;
 
     -T) no_target_directory=true;;
@@ -190,10 +186,6 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
     fi
     shift # arg
     dst_arg=$arg
-    # Protect names problematic for `test' and other utilities.
-    case $dst_arg in
-      -* | [=\(\)!]) dst_arg=./$dst_arg;;
-    esac
   done
 fi
 
@@ -208,11 +200,7 @@ if test $# -eq 0; then
 fi
 
 if test -z "$dir_arg"; then
-  do_exit='(exit $ret); exit $ret'
-  trap "ret=129; $do_exit" 1
-  trap "ret=130; $do_exit" 2
-  trap "ret=141; $do_exit" 13
-  trap "ret=143; $do_exit" 15
+  trap '(exit $?); exit' 1 2 13 15
 
   # Set umask so as not to create temps with too-generous modes.
   # However, 'strip' requires both read and write access to temps.
@@ -240,9 +228,9 @@ fi
 
 for src
 do
-  # Protect names problematic for `test' and other utilities.
+  # Protect names starting with `-'.
   case $src in
-    -* | [=\(\)!]) src=./$src;;
+    -*) src=./$src;;
   esac
 
   if test -n "$dir_arg"; then
@@ -264,7 +252,12 @@ do
       echo "$0: no destination specified." >&2
       exit 1
     fi
+
     dst=$dst_arg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst;;
+    esac
 
     # If destination is a directory, append the input filename; won't work
     # if double slashes aren't ignored.
@@ -392,7 +385,7 @@ do
 
       case $dstdir in
 	/*) prefix='/';;
-	[-=\(\)!]*) prefix='./';;
+	-*) prefix='./';;
 	*)  prefix='';;
       esac
 
@@ -410,7 +403,7 @@ do
 
       for d
       do
-	test X"$d" = X && continue
+	test -z "$d" && continue
 
 	prefix=$prefix$d
 	if test -d "$prefix"; then
diff --git a/src/include/switch_apr.h b/src/include/switch_apr.h
index e125eb9390..0c8673570f 100644
--- a/src/include/switch_apr.h
+++ b/src/include/switch_apr.h
@@ -773,8 +773,7 @@ typedef gid_t                     switch_gid_t;
 	 typedef ino_t switch_ino_t;
 	 typedef dev_t switch_dev_t;
 #endif
-
-typedef off_t switch_off_t;
+	 typedef off64_t switch_off_t;
 
 /**
  * Structure for referencing file information

From 32c5100e625f99c68f7979bddc24100aeea8e293 Mon Sep 17 00:00:00 2001
From: kapil <kgupta@sangoma.com>
Date: Wed, 16 May 2012 18:36:26 +0530
Subject: [PATCH 5/6] Adding megaco stack configuration code and
 "megaco.conf.xml"

---
 src/mod/endpoints/mod_megaco/Makefile         |   3 +-
 .../endpoints/mod_megaco/conf/megaco.conf.xml |  51 +++-
 src/mod/endpoints/mod_megaco/megaco.c         |  61 ++++-
 src/mod/endpoints/mod_megaco/megaco_cfg.h     |  98 ++++++++
 src/mod/endpoints/mod_megaco/megaco_xml.c     | 219 ++++++++++++++++++
 src/mod/endpoints/mod_megaco/mod_megaco.c     | 102 +++++++-
 src/mod/endpoints/mod_megaco/mod_megaco.h     |  19 +-
 7 files changed, 520 insertions(+), 33 deletions(-)
 create mode 100644 src/mod/endpoints/mod_megaco/megaco_cfg.h
 create mode 100644 src/mod/endpoints/mod_megaco/megaco_xml.c

diff --git a/src/mod/endpoints/mod_megaco/Makefile b/src/mod/endpoints/mod_megaco/Makefile
index e65d0f78eb..29349edca1 100644
--- a/src/mod/endpoints/mod_megaco/Makefile
+++ b/src/mod/endpoints/mod_megaco/Makefile
@@ -1,3 +1,4 @@
 BASE=../../../..
-LOCAL_OBJS=megaco.o
+LOCAL_OBJS=megaco.o megaco_cfg.o
+LOCAL_LDFLAGS=-lsng_megaco
 include $(BASE)/build/modmake.rules
diff --git a/src/mod/endpoints/mod_megaco/conf/megaco.conf.xml b/src/mod/endpoints/mod_megaco/conf/megaco.conf.xml
index c219023dd8..ed849030bf 100644
--- a/src/mod/endpoints/mod_megaco/conf/megaco.conf.xml
+++ b/src/mod/endpoints/mod_megaco/conf/megaco.conf.xml
@@ -1,9 +1,46 @@
 <configuration name="megaco.conf" description="Megaco Controllee">
-  <profiles>
-	<profile name="default">
-		<settings>
-			<param name="foo" value="bar" />
-		</settings>
-	</profile>
-  </profiles>
+
+  	<!--Each instances of MG will have each mg profile  -->
+	<sng_mg_interfaces>
+		   <sng_mg_interface name="default">
+			   <param name="id" value="1"/>                			<!-- /* equivalent to SSAP ID of MEGACO layer */-->
+			   <param name="protocol" value="MEGACO"/>         		<!-- /* Protocol Type , Supported values are MEGACO/MGCP */ -->
+			   <param name="transportProfileId" value="1"/>   		<!-- /* Link to transport layer configuration --> 
+			   <param name="localIp" value="xxx-xxx-xx-xx"/>  		<!-- /* Local node IP */ -->
+			   <param name="port"     value="2944" />	    		<!-- /* Port */ -->
+			   <param name="myDomainName" value="mg.sangoma.com" />   	<!--/* Local domain name */ -->
+			   <param name="mid" value="<lab.sangoma.com>" />        		 <!-- /* Message Identifier (MID) of MEGACO message  */ -->
+		           <param name="peerId" value="1" />  	    		 	<!--/* MGC Peer Configuration profile ID */-->
+			   <!--/*We can define multiple peer_ids depends on number of MGC per MG.
+		  	   MGC Priority          - peer order can defines the priority or we can priority attribute in peer_id element..Not needed now..we can think later
+		 	   Primart/Secondary MGC - we can think later in future when we need this functionality..as of now not requied. */
+			  -->
+                    </sng_mg_interface>
+
+    </sng_mg_interfaces>
+
+    <!--/*transport profiles which can be TCP, UDP or SCTP */-->
+    <sng_transport_interfaces>
+ 
+    	 <!--/* for TUCL we dont need any layer specific config parameters */ -->
+		     <sng_transport_interface name="TPT-1">
+			  <param name="id" value="1" />   		  	 <!-- /* transport profile id    */ -->
+		    	  <param name="transportType" value="UDP"/>   	 	 <!-- /* transport profile type values could be UDP/TCP/SCTP */ -->
+                    </sng_transport_interface>
+
+    </sng_transport_interfaces>
+
+
+    <sng_mg_peer_interfaces>			 				<!--/* Supported number of peers */ -->
+
+   		   <sng_mg_peer_interface name="MG_PEER1">
+			   <param name="id" value="1"/>         		<!-- /* Peer profile ID */-->
+			   <param name="ip" value="xxx-xxx-xx-xx"/>  		<!-- /* Peer node IP */ -->
+			   <param name="port" value="2944"/>   			<!--/* peer port */ -->
+			   <param name="encodingScheme" value="TEXT"/>  	<!--/* H.248 Encoding scheme TEXT/BINARY */ -->
+			    <param name="mid" value="remote.mgc.com" />    	<!-- /* Message Identifier (MID) of remote MGC MEGACO message  */-->
+		   </sng_mg_peer_interface>
+
+    </sng_mg_peer_interfaces>
+
 </configuration>
diff --git a/src/mod/endpoints/mod_megaco/megaco.c b/src/mod/endpoints/mod_megaco/megaco.c
index 9ac7af4355..20024ace87 100644
--- a/src/mod/endpoints/mod_megaco/megaco.c
+++ b/src/mod/endpoints/mod_megaco/megaco.c
@@ -29,34 +29,73 @@ void megaco_profile_release(megaco_profile_t *profile)
 
 static switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload)
 {
-	switch_xml_t cfg, xml, x_profiles, x_profile, x_settings;
+	switch_xml_t cfg, xml, mg_interfaces, mg_interface, tpt_interfaces, tpt_interface, peer_interfaces, peer_interface;
 	switch_status_t status = SWITCH_STATUS_FALSE;
 	switch_event_t *event = NULL;
-	int count;
 	const char *file = "megaco.conf";
+	const char* mg_profile_tpt_id = NULL;
+	const char* mg_profile_peer_id = NULL;
 
 	if (!(xml = switch_xml_open_cfg(file, &cfg, NULL))) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not open %s\n", file);
 		goto done;
 	}
 
-	if (!(x_profiles = switch_xml_child(cfg, "profiles"))) {
+	if (!(mg_interfaces = switch_xml_child(cfg, "sng_mg_interfaces"))) {
 		goto done;
 	}
 
-	for (x_profile = switch_xml_child(x_profiles, "profile"); x_profile; x_profile = x_profile->next) {
-		const char *name = switch_xml_attr_soft(x_profile, "name");
+	/* iterate through MG Interface list to build all MG profiles */
+	for (mg_interface = switch_xml_child(mg_interfaces, "sng_mg_interface"); mg_interface; mg_interface = mg_interface->next) {
+
+		const char *name = switch_xml_attr_soft(mg_interface, "name");
 		if (strcmp(name, profile->name)) {
 			continue;
 		}
 
-		if (!(x_settings = switch_xml_child(x_profile, "settings"))) {
+		/* parse MG profile */
+		if(SWITCH_STATUS_FALSE == sng_parse_mg_profile(mg_interface)) {
 			goto done;
 		}
-		count = switch_event_import_xml(switch_xml_child(x_settings, "param"), "name", "value", &event);
-		// status = switch_xml_config_parse_event(event, count, reload, instructions);
-		
-		/* TODO: Kapil: Initialize stack configuration */
+
+		mg_profile_tpt_id = switch_xml_attr_soft(mg_interface, "id");
+
+		/* Now get required transport profile against mg_profile_tpt_id*/
+		if (!(tpt_interfaces = switch_xml_child(cfg, "sng_transport_interfaces"))) {
+			goto done;
+		}
+
+		for (tpt_interface = switch_xml_child(tpt_interfaces, "sng_transport_interface"); tpt_interface; tpt_interface = tpt_interface->next) {
+			const char *id = switch_xml_attr_soft(tpt_interface, "id");
+			if (strcmp(id, mg_profile_tpt_id)) {
+				continue;
+			}
+
+			/* parse MG transport profile */
+			if(SWITCH_STATUS_FALSE == sng_parse_mg_tpt_profile(tpt_interface)) {
+				goto done;
+			}
+		}
+
+		/* as of now supporting only one peer */
+		mg_profile_peer_id = switch_xml_attr_soft(mg_interface, "peerId");
+		/* Now get required peer profile against mg_profile_peer_id*/
+		if (!(peer_interfaces = switch_xml_child(cfg, "sng_mg_peer_interfaces"))) {
+			goto done;
+		}
+
+		for (peer_interface = switch_xml_child(peer_interfaces, "sng_mg_peer_interface"); peer_interface; peer_interface = peer_interface->next) {
+			const char *id = switch_xml_attr_soft(peer_interface, "id");
+			if (strcmp(id, mg_profile_peer_id)) {
+				continue;
+			}
+
+			/* parse MG Peer profile */
+			if(SWITCH_STATUS_FALSE == sng_parse_mg_peer_profile(peer_interface)) {
+				goto done;
+			}
+		}
+
 		status = SWITCH_STATUS_SUCCESS;
 	}
 
@@ -87,7 +126,6 @@ switch_status_t megaco_profile_start(const char *profilename)
 	
 	switch_thread_rwlock_create(&profile->rwlock, pool);
 	
-	/* TODO: Kapil: Insert stack per-interface startup code here */
 	if (config_profile(profile, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error configuring profile %s\n", profile->name);
 		goto fail;
@@ -125,7 +163,6 @@ switch_status_t megaco_profile_destroy(megaco_profile_t **profile)
 	return SWITCH_STATUS_SUCCESS;	
 }
 
-
 /* For Emacs:
  * Local Variables:
  * mode:c
diff --git a/src/mod/endpoints/mod_megaco/megaco_cfg.h b/src/mod/endpoints/mod_megaco/megaco_cfg.h
new file mode 100644
index 0000000000..54bf310b29
--- /dev/null
+++ b/src/mod/endpoints/mod_megaco/megaco_cfg.h
@@ -0,0 +1,98 @@
+/*
+* Copyright (c) 2012, Sangoma Technologies
+* Kapil Gupta <kgupta@sangoma.com>
+* All rights reserved.
+* 
+* <Insert license here>
+*/
+
+#include "sng_megaco/sng_ss7.h"
+
+#ifndef _MEGACO_CFG_H_
+#define _MEGACO_CFG_H_
+
+#define MAX_MID_LEN    30
+#define MAX_DOMAIN_LEN 30
+#define MAX_NAME_LEN    25
+#define MAX_MG_PROFILES 5
+
+typedef struct sng_mg_peer{
+  char          name[MAX_NAME_LEN];	     /* Peer Name as defined in config file */
+  uint16_t 	id;			     /* Peer ID as defined in config file */
+  uint8_t  	ipaddr[MAX_DOMAIN_LEN];      /* Peer IP  */
+  uint16_t 	port;                        /*Peer Port */
+  uint8_t       mid[MAX_MID_LEN];  	     /* Peer H.248 MID */
+  uint16_t      encoding_type;               /* Encoding TEXT/Binary */
+}sng_mg_peer_t;
+
+typedef struct sng_mg_peers{
+    uint16_t  total_peer;   		     /* Total number of MGC Peer */
+    sng_mg_peer_t peers[MG_MAX_PEERS+1];
+}sng_mg_peers_t;
+
+typedef struct sng_mg_transport_profile{
+  	char          name[MAX_NAME_LEN];	     /* Peer Name as defined in config file */
+        uint32_t      id;      		     	     /* map to tsap id */
+        uint16_t      transport_type;                /* transport type */
+}sng_mg_transport_profile_t;
+
+
+typedef enum{
+        SNG_MG_TPT_NONE,
+        SNG_MG_TPT_UDP,
+        SNG_MG_TPT_TCP,
+        SNG_MG_TPT_SCTP,
+        SNG_MG_TPT_MTP3
+}sng_mg_transport_types_e;
+
+typedef enum{
+        SNG_MG_NONE,
+        SNG_MG_MGCP,
+        SNG_MG_MEGACO,
+}sng_mg_protocol_types_e;
+
+typedef enum{
+        SNG_MG_ENCODING_NONE,
+        SNG_MG_ENCODING_TEXT,
+        SNG_MG_ENCODING_BINARY,
+}sng_mg_encoding_types_e;
+
+
+
+/* each profile is corresponds to each MG Instance */
+typedef struct sng_mg_cfg{
+  	char          		name[MAX_NAME_LEN];	     /* MG(Virtual MG) Name as defined in config file */
+        uint32_t                id;                	     /* Id - map to MG SAP ID */
+        uint8_t                 mid[MAX_MID_LEN];  	     /* MG H.248 MID */
+        uint8_t                 my_domain[MAX_DOMAIN_LEN];   /* local domain name */
+        uint8_t                 my_ipaddr[MAX_DOMAIN_LEN];   /* local domain name */
+        uint32_t                port;              	     /* port */
+        uint16_t                peer_id;                     /* MGC Peer ID */
+        uint16_t                transport_prof_id;           /* Transport profile id ..this also will be the spId for MG SAP*/
+        uint16_t                protocol_type;    	     /* MEGACO/MGCP */
+}sng_mg_cfg_t;
+
+
+typedef struct sng_mg_gbl_cfg{
+	sng_mg_cfg_t                    mgCfg[MAX_MG_PROFILES + 1];
+	sng_mg_transport_profile_t 	mgTptProf[MG_MAX_PEERS+1];	/* transport profile */
+	sng_mg_peers_t 			mgPeer;
+}sng_mg_gbl_cfg_t;
+
+
+extern switch_status_t sng_parse_mg_peer_profile(switch_xml_t mg_peer_profile);
+extern switch_status_t sng_parse_mg_tpt_profile(switch_xml_t mg_tpt_profile);
+extern switch_status_t sng_parse_mg_profile(switch_xml_t mg_interface);
+
+
+void handle_sng_log(uint8_t level, char *fmt, ...);
+void handle_mgco_sta_ind(Pst *pst, SuId suId, MgMgtSta* msg);
+void handle_mgco_txn_sta_ind(Pst *pst, SuId suId, MgMgcoInd* msg);
+void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* msg);
+void handle_mgco_cntrl_cfm(Pst *pst, SuId suId, MgMgtCntrl* cntrl, Reason reason); 
+void handle_mgco_txn_ind(Pst *pst, SuId suId, MgMgcoMsg* msg);
+void handle_mgco_audit_cfm(Pst *pst, SuId suId, MgMgtAudit* audit, Reason reason); 
+void handle_mg_alarm(Pst *pst, MgMngmt *sta);
+void handle_tucl_alarm(Pst *pst, HiMngmt *sta);
+
+#endif /* _MEGACO_CFG_H_ */
diff --git a/src/mod/endpoints/mod_megaco/megaco_xml.c b/src/mod/endpoints/mod_megaco/megaco_xml.c
new file mode 100644
index 0000000000..506cc3b29e
--- /dev/null
+++ b/src/mod/endpoints/mod_megaco/megaco_xml.c
@@ -0,0 +1,219 @@
+/*
+* Copyright (c) 2012, Sangoma Technologies
+* Kapil Gupta <kgupta@sangoma.com>
+* All rights reserved.
+* 
+* <Insert license here>
+*/
+#include "mod_megaco.h"
+
+
+switch_status_t sng_parse_mg_profile(switch_xml_t mg_interface)
+{
+	int i = 0x00;
+	const char *prof_name   = NULL;
+	switch_xml_t param;
+
+	/*************************************************************************/
+	prof_name = switch_xml_attr_soft(mg_interface, "name");
+
+	/*************************************************************************/
+	for (param = switch_xml_child(mg_interface, "param"); param; param = param->next) {
+		char *var = (char *) switch_xml_attr_soft(param, "name");
+		char *val = (char *) switch_xml_attr_soft(param, "value");
+		if (!var || !val) {
+			continue;
+		}
+
+		/******************************************************************************************/
+		if(!strcasecmp(var, "id")){
+			i   = atoi(val);
+			megaco_globals.g_mg_cfg.mgCfg[i].id = i;
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mg_interface Id[%d] \n", i);
+			/*******************************************************************************************/
+		}else if(!strcasecmp(var, "protocol")){
+			/********************************************************************************************/
+			if(!strcasecmp(val,"MEGACO")) {
+				megaco_globals.g_mg_cfg.mgCfg[i].protocol_type = SNG_MG_MEGACO;
+			}else if(!strcasecmp(val,"MGCP")){
+				megaco_globals.g_mg_cfg.mgCfg[i].protocol_type = SNG_MG_MGCP;
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MGCP Protocol Not Yet Supported \n");
+				return SWITCH_STATUS_FALSE;
+			}else{
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Protocol Value[%s] \n",val);
+				return SWITCH_STATUS_FALSE;
+			}
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mg_interface protocol[%d] \n", 
+					megaco_globals.g_mg_cfg.mgCfg[i].protocol_type);
+			/********************************************************************************************/
+		}else if(!strcasecmp(var, "transportProfileId")){
+			/********************************************************************************************/
+			megaco_globals.g_mg_cfg.mgCfg[i].transport_prof_id   = atoi(val);
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mg_interface transport_prof_id[%d] \n", 
+					megaco_globals.g_mg_cfg.mgCfg[i].transport_prof_id);
+			/********************************************************************************************/
+		}else if(!strcasecmp(var, "localIp")){
+			/***********************************************************************i*********************/
+			strcpy((char*)&megaco_globals.g_mg_cfg.mgCfg[i].my_ipaddr[0],val);
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mg_interface my_ipaddr[%s] \n", 
+					megaco_globals.g_mg_cfg.mgCfg[i].my_ipaddr);
+			/********************************************************************************************/
+		}else if(!strcasecmp(var, "port")){
+			/********************************************************************************************/
+			megaco_globals.g_mg_cfg.mgCfg[i].port   = atoi(val);
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, 
+					" mg_interface my_port[%d] \n", megaco_globals.g_mg_cfg.mgCfg[i].port);
+			/********************************************************************************************/
+		}else if(!strcasecmp(var, "myDomainName")){
+			/********************************************************************************************/
+			strcpy((char*)&megaco_globals.g_mg_cfg.mgCfg[i].my_domain[0],val);	
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, 
+					" mg_interface myDomainName[%s] \n", megaco_globals.g_mg_cfg.mgCfg[i].my_domain);
+			/********************************************************************************************/
+		}else if(!strcasecmp(var, "mid")){
+			/********************************************************************************************/
+			strcpy((char*)&megaco_globals.g_mg_cfg.mgCfg[i].mid[0],val);
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, 
+					" mg_interface mid[%s] \n", megaco_globals.g_mg_cfg.mgCfg[i].mid);
+			/********************************************************************************************/
+		}else if(!strcasecmp(var, "peerId")){
+			/********************************************************************************************/
+			megaco_globals.g_mg_cfg.mgCfg[i].peer_id   = atoi(val);
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, 
+					" mg_interface peerId[%d] \n", megaco_globals.g_mg_cfg.mgCfg[i].peer_id);
+			/********************************************************************************************/
+		}else {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " Invalid var[%s] in mg_interface \n", var);
+			return SWITCH_STATUS_FALSE;
+		}
+	}
+
+	strcpy((char*)&megaco_globals.g_mg_cfg.mgCfg[i].name[0], prof_name);
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
+/***********************************************************************************************************/
+
+switch_status_t sng_parse_mg_tpt_profile(switch_xml_t mg_tpt_profile)
+{
+	int i = 0x00;
+	switch_xml_t param;
+	const char *prof_name   = NULL;
+
+	/*************************************************************************/
+	prof_name = switch_xml_attr_soft(mg_tpt_profile, "name");
+
+	/*************************************************************************/
+	for (param = switch_xml_child(mg_tpt_profile, "param"); param; param = param->next) {
+		char *var = (char *) switch_xml_attr_soft(param, "name");
+		char *val = (char *) switch_xml_attr_soft(param, "value");
+		if (!var || !val) {
+			continue;
+		}
+
+		/******************************************************************************************/
+		if(!strcasecmp(var, "id")){
+			/*******************************************************************************************/
+			i   = atoi(val);
+			megaco_globals.g_mg_cfg.mgTptProf[i].id = i;
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mg_tpt_profile Id[%d] \n", i);
+			/*******************************************************************************************/
+		}else if(!strcasecmp(var, "transportType")){
+			/*******************************************************************************************/
+			if(!strcasecmp(val,"UDP")) {
+				megaco_globals.g_mg_cfg.mgTptProf[i].transport_type = SNG_MG_TPT_UDP;
+			}else if(!strcasecmp(val,"TCP")){
+				megaco_globals.g_mg_cfg.mgTptProf[i].transport_type = SNG_MG_TPT_TCP;
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "TCP Transport for H.248 Protocol Not Yet Supported \n");
+				return SWITCH_STATUS_FALSE;
+			}else if(!strcasecmp(val,"STCP")){
+				megaco_globals.g_mg_cfg.mgTptProf[i].transport_type = SNG_MG_TPT_SCTP;
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STCP Transport for H.248 Protocol Not Yet Supported \n");
+				return SWITCH_STATUS_FALSE;
+			}else{
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Protocol Value[%s] \n",val);
+				return SWITCH_STATUS_FALSE;
+			}
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mg_tpt_profile transport_type[%d] \n", 
+					megaco_globals.g_mg_cfg.mgTptProf[i].transport_type);
+			/********************************************************************************************/
+		}else {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " Invalid var[%s] in mg_transport \n", var);
+			return SWITCH_STATUS_FALSE;
+		}
+	}
+
+	strcpy((char*)&megaco_globals.g_mg_cfg.mgTptProf[i].name[0], prof_name);
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, 
+			" mg_tpt_profile Name[%s] \n", &megaco_globals.g_mg_cfg.mgTptProf[i].name[0]); 
+
+	return SWITCH_STATUS_SUCCESS;
+}
+/***********************************************************************************************************/
+
+switch_status_t sng_parse_mg_peer_profile(switch_xml_t mg_peer_profile)
+{
+	int i = 0x00;
+	switch_xml_t param;
+	const char *prof_name   = NULL;
+
+	/*************************************************************************/
+	prof_name = switch_xml_attr_soft(mg_peer_profile, "name");
+
+	for (param = switch_xml_child(mg_peer_profile, "param"); param; param = param->next) {
+		/***********************************************************************************************************/
+		char *var = (char *) switch_xml_attr_soft(param, "name");
+		char *val = (char *) switch_xml_attr_soft(param, "value");
+		if (!var || !val) {
+			continue;
+		}
+
+		/***********************************************************************************************************/
+		if(!strcasecmp(var, "id")){
+			/***********************************************************************************************************/
+			i   = atoi(val);
+			megaco_globals.g_mg_cfg.mgPeer.peers[i].id = i;
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mg_peer_profile Id[%d] \n", i);
+			/***********************************************************************************************************/
+		}else if(!strcasecmp(var, "port")){
+			/***********************************************************************************************************/
+			megaco_globals.g_mg_cfg.mgPeer.peers[i].port = atoi(val);
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, 
+					" mg_peer_profile port[%d] \n", megaco_globals.g_mg_cfg.mgPeer.peers[i].port);
+			/***********************************************************************************************************/
+		}else if(!strcasecmp(var, "encodingScheme")){
+			/***********************************************************************************************************/
+			if(!strcasecmp(val, "TEXT")){
+				megaco_globals.g_mg_cfg.mgPeer.peers[i].encoding_type = SNG_MG_ENCODING_TEXT; 
+			} else if(!strcasecmp(val, "BINARY")){
+				megaco_globals.g_mg_cfg.mgPeer.peers[i].encoding_type = SNG_MG_ENCODING_BINARY; 
+			} else {
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Encoding Type[%s] \n",val);
+				return SWITCH_STATUS_FALSE;
+			}
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, 
+					" mg_peer_profile encodingScheme[%d] \n", megaco_globals.g_mg_cfg.mgPeer.peers[i].encoding_type);
+			/***********************************************************************************************************/
+		}else if(!strcasecmp(var, "mid")){
+			/***********************************************************************************************************/
+			strcpy((char*)&megaco_globals.g_mg_cfg.mgPeer.peers[i].mid[0],val);
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, 
+					" mg_peer_profile mid[%s] \n", megaco_globals.g_mg_cfg.mgPeer.peers[i].mid);
+			/***********************************************************************************************************/
+		}else if(!strcasecmp(var, "ip")){
+			/***********************************************************************************************************/
+			strcpy((char*)&megaco_globals.g_mg_cfg.mgPeer.peers[i].ipaddr[0],val);
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, 
+					" mg_peer_profile ip[%s] \n", megaco_globals.g_mg_cfg.mgPeer.peers[i].ipaddr);
+			/***********************************************************************************************************/
+		}else{
+			/***********************************************************************************************************/
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " Invalid var[%s] in mg_peer \n", var);
+			return SWITCH_STATUS_FALSE;
+		}
+	}
+
+	return SWITCH_STATUS_SUCCESS;
+}
+/***********************************************************************************************************/
diff --git a/src/mod/endpoints/mod_megaco/mod_megaco.c b/src/mod/endpoints/mod_megaco/mod_megaco.c
index bf23077e00..bda8e53ec0 100644
--- a/src/mod/endpoints/mod_megaco/mod_megaco.c
+++ b/src/mod/endpoints/mod_megaco/mod_megaco.c
@@ -9,6 +9,7 @@
 #include "mod_megaco.h"
 
 struct megaco_globals megaco_globals;
+static sng_isup_event_interface_t sng_event;
 
 SWITCH_MODULE_LOAD_FUNCTION(mod_megaco_load);
 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_megaco_shutdown);
@@ -115,9 +116,25 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_megaco_load)
 	switch_console_set_complete("add megaco profile ::megaco::list_profiles start");
 	switch_console_set_complete("add megaco profile ::megaco::list_profiles stop");
 	switch_console_add_complete_func("::megaco::list_profiles", list_profiles);
-	
-	/* TODO: Kapil: Insert stack global startup code here */
-	
+
+
+	/* Initialize MEGACO Stack */
+	sng_event.mg.sng_mgco_txn_ind  		= handle_mgco_txn_ind;
+	sng_event.mg.sng_mgco_cmd_ind  		= handle_mgco_cmd_ind;
+	sng_event.mg.sng_mgco_txn_sta_ind  	= handle_mgco_txn_sta_ind;
+	sng_event.mg.sng_mgco_sta_ind  		= handle_mgco_sta_ind;
+	sng_event.mg.sng_mgco_cntrl_cfm  		= handle_mgco_cntrl_cfm;
+	sng_event.mg.sng_mgco_audit_cfm  		= handle_mgco_audit_cfm;
+
+	/* Alarm CB */
+	sng_event.sm.sng_mg_alarm  		= handle_mg_alarm;
+	sng_event.sm.sng_tucl_alarm  		= handle_tucl_alarm;
+
+	/* Log */
+	sng_event.sm.sng_log  			= handle_sng_log;
+
+	/* initalize sng_mg library */
+	sng_isup_init_gen(&sng_event);
 	
 	return SWITCH_STATUS_SUCCESS;
 }
@@ -128,6 +145,85 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_megaco_shutdown)
 	return SWITCH_STATUS_SUCCESS;
 }
 
+/*****************************************************************************************************************************/
+void handle_sng_log(uint8_t level, char *fmt, ...)
+{
+	int log_level;
+	char print_buf[1024];
+	va_list ptr;
+
+	memset(&print_buf[0],0,sizeof(1024));
+
+	va_start(ptr, fmt);
+
+	switch(level)
+	{
+		case SNG_LOGLEVEL_DEBUG:    log_level = SWITCH_LOG_DEBUG;       break;
+		case SNG_LOGLEVEL_INFO:     log_level = SWITCH_LOG_INFO;        break;
+		case SNG_LOGLEVEL_WARN:     log_level = SWITCH_LOG_WARNING;     break;
+		case SNG_LOGLEVEL_ERROR:    log_level = SWITCH_LOG_ERROR;       break;
+		case SNG_LOGLEVEL_CRIT:     log_level = SWITCH_LOG_CRIT;        break;
+		default:                    log_level = SWITCH_LOG_DEBUG;       break;
+	};
+
+	vsprintf(&print_buf[0], fmt, ptr);
+
+	switch_log_printf(SWITCH_CHANNEL_LOG, log_level, " MOD_MEGACO: %s \n", &print_buf[0]); 
+
+	va_end(ptr);
+}
+
+/*****************************************************************************************************************************/
+
+void handle_mgco_txn_ind(Pst *pst, SuId suId, MgMgcoMsg* msg)
+{
+	/*TODO*/
+}
+
+/*****************************************************************************************************************************/
+void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd)
+{
+	/*TODO*/
+}
+
+/*****************************************************************************************************************************/
+void handle_mgco_sta_ind(Pst *pst, SuId suId, MgMgtSta* sta)
+{
+	/*TODO*/
+}
+
+/*****************************************************************************************************************************/
+
+void handle_mgco_txn_sta_ind(Pst *pst, SuId suId, MgMgcoInd* txn_sta_ind)
+{
+	/*TODO*/
+}
+
+/*****************************************************************************************************************************/
+void handle_mgco_cntrl_cfm(Pst *pst, SuId suId, MgMgtCntrl* cntrl, Reason reason) 
+{
+	/*TODO*/
+}
+
+/*****************************************************************************************************************************/
+void handle_mgco_audit_cfm(Pst *pst, SuId suId, MgMgtAudit* audit, Reason reason) 
+{
+	/*TODO*/
+}
+
+/*****************************************************************************************************************************/
+void handle_mg_alarm(Pst *pst, MgMngmt *sta)
+{
+	/*TODO*/
+}
+
+/*****************************************************************************************************************************/
+void handle_tucl_alarm(Pst *pst, HiMngmt *sta)
+{
+	/*TODO*/
+}
+
+/*****************************************************************************************************************************/
 
 /* For Emacs:
  * Local Variables:
diff --git a/src/mod/endpoints/mod_megaco/mod_megaco.h b/src/mod/endpoints/mod_megaco/mod_megaco.h
index b12982de8c..3efa48e3bc 100644
--- a/src/mod/endpoints/mod_megaco/mod_megaco.h
+++ b/src/mod/endpoints/mod_megaco/mod_megaco.h
@@ -11,12 +11,13 @@
 #define MOD_MEGACO_H
 
 #include <switch.h>
+#include "megaco_cfg.h"
 
 struct megaco_globals {
-	switch_memory_pool_t *pool;
-	switch_hash_t *profile_hash;
-	switch_thread_rwlock_t *profile_rwlock;
-	/* TODO: Kapil: add global variables here */
+	switch_memory_pool_t 		*pool;
+	switch_hash_t 			*profile_hash;
+	switch_thread_rwlock_t 		*profile_rwlock;
+	sng_mg_gbl_cfg_t 		 g_mg_cfg;
 };
 extern struct megaco_globals megaco_globals; /* < defined in mod_megaco.c */
 
@@ -25,12 +26,10 @@ typedef enum {
 } megaco_profile_flags_t;
 
 typedef struct megaco_profile_s {
-	char *name;
-	switch_memory_pool_t *pool;
-	switch_thread_rwlock_t *rwlock; /* < Reference counting rwlock */
-	megaco_profile_flags_t flags;
-	
-	/* TODO: Kapil: Insert interface-specific stack elements here */
+	char 				*name;
+	switch_memory_pool_t 		*pool;
+	switch_thread_rwlock_t 		*rwlock; /* < Reference counting rwlock */
+	megaco_profile_flags_t 		flags;
 } megaco_profile_t;
 
 

From df76709e95241e7971e380e99f66853838902397 Mon Sep 17 00:00:00 2001
From: kapil <kgupta@sangoma.com>
Date: Thu, 17 May 2012 16:14:05 +0530
Subject: [PATCH 6/6] Adding code to bring up MEGACO stack

---
 src/mod/endpoints/mod_megaco/Makefile         |  10 +-
 src/mod/endpoints/mod_megaco/megaco.c         |  13 +-
 src/mod/endpoints/mod_megaco/megaco_stack.c   | 964 ++++++++++++++++++
 .../{megaco_cfg.h => megaco_stack.h}          |  39 +-
 src/mod/endpoints/mod_megaco/megaco_xml.c     |   1 +
 src/mod/endpoints/mod_megaco/mod_megaco.c     |  15 +-
 src/mod/endpoints/mod_megaco/mod_megaco.h     |   2 +-
 7 files changed, 1031 insertions(+), 13 deletions(-)
 create mode 100644 src/mod/endpoints/mod_megaco/megaco_stack.c
 rename src/mod/endpoints/mod_megaco/{megaco_cfg.h => megaco_stack.h} (71%)

diff --git a/src/mod/endpoints/mod_megaco/Makefile b/src/mod/endpoints/mod_megaco/Makefile
index 29349edca1..4564a420e9 100644
--- a/src/mod/endpoints/mod_megaco/Makefile
+++ b/src/mod/endpoints/mod_megaco/Makefile
@@ -1,4 +1,12 @@
+ifndef ARCH
+        ARCH=$(shell uname -m)
+endif
+
+ifeq ($(ARCH),x86_64)
+        LOCAL_CFLAGS+=-DBIT_64 -DALIGN_64BIT
+endif
+
 BASE=../../../..
-LOCAL_OBJS=megaco.o megaco_cfg.o
+LOCAL_OBJS=megaco.o megaco_stack.o megaco_xml.o
 LOCAL_LDFLAGS=-lsng_megaco
 include $(BASE)/build/modmake.rules
diff --git a/src/mod/endpoints/mod_megaco/megaco.c b/src/mod/endpoints/mod_megaco/megaco.c
index 20024ace87..84bf70963b 100644
--- a/src/mod/endpoints/mod_megaco/megaco.c
+++ b/src/mod/endpoints/mod_megaco/megaco.c
@@ -96,7 +96,12 @@ static switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t r
 			}
 		}
 
-		status = SWITCH_STATUS_SUCCESS;
+
+		/* configure the MEGACO stack */
+		status = sng_mgco_cfg(profile->name);
+		
+		/* we should break from here , profile name should be unique */
+		break;
 	}
 
 done:
@@ -131,6 +136,12 @@ switch_status_t megaco_profile_start(const char *profilename)
 		goto fail;
 	}
 	
+	/* start MEGACP stack */
+	if(SWITCH_STATUS_FALSE == sng_mgco_start(profilename)) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error starting MEGACO Stack for profile  %s\n", profile->name);
+		goto fail;
+	}
+	
 	switch_core_hash_insert_wrlock(megaco_globals.profile_hash, profile->name, profile, megaco_globals.profile_rwlock);
 	
 	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Started profile: %s\n", profile->name);
diff --git a/src/mod/endpoints/mod_megaco/megaco_stack.c b/src/mod/endpoints/mod_megaco/megaco_stack.c
new file mode 100644
index 0000000000..4ba2cd05f6
--- /dev/null
+++ b/src/mod/endpoints/mod_megaco/megaco_stack.c
@@ -0,0 +1,964 @@
+/*
+* Copyright (c) 2012, Sangoma Technologies
+* Kapil Gupta <kgupta@sangoma.com>
+* All rights reserved.
+* 
+* <Insert license here>
+*/
+
+/* INCLUDES *******************************************************************/
+#include "mod_megaco.h"
+/******************************************************************************/
+
+/* DEFINES ********************************************************************/
+
+/* FUNCTION PROTOTYPES ********************************************************/
+int mgco_mg_gen_config(void);
+int mgco_mu_gen_config(void);
+int mgco_tucl_gen_config(void);
+int mgco_mu_ssap_config(int idx);
+int mgco_mg_tsap_config(int idx);
+int mgco_mg_enble_debug(void);
+int mgco_mg_ssap_config(int idx);
+int mgco_mg_peer_config(int idx);
+int mgco_mg_tpt_server_config(int idx);
+int mgco_tucl_sap_config(int idx);
+
+int mgco_mg_tsap_bind_cntrl(int idx);
+int mgco_mg_tsap_enable_cntrl(int idx);
+int mgco_mg_ssap_cntrl(int idx);
+int mgco_mu_ssap_cntrl(int idx);
+int mgco_mg_tpt_server(int idx);
+
+switch_status_t sng_mgco_stack_gen_cfg();
+
+/******************************************************************************/
+
+/* FUNCTIONS ******************************************************************/
+
+switch_status_t sng_mgco_init(sng_isup_event_interface_t* event)
+{
+	uint32_t major, minor, build;
+
+	switch_assert(event);
+
+	/* initalize sng_mg library */
+	sng_isup_init_gen(event);
+
+	/* print the version of the library being used */
+	sng_isup_version(&major, &minor, &build);
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,"Loaded LibSng-MEGACO %d.%d.%d\n", major, minor, build);
+
+	/* start up the stack manager */
+	if (sng_isup_init_sm()) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,"Failed to start Stack Manager\n");
+		return SWITCH_STATUS_FALSE;
+	} else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,"Started Stack Manager!\n");
+	}
+
+	if (sng_isup_init_tucl()) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"Failed to start TUCL\n");
+		return SWITCH_STATUS_FALSE;
+	} else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,"Started TUCL!\n");
+	}
+
+	if (sng_isup_init_mg()) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"Failed to start MG\n");
+		return SWITCH_STATUS_FALSE;
+	} else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,"Started MG!\n");
+	}
+
+	if (sng_isup_init_mu()) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"Failed to start MU\n");
+		return SWITCH_STATUS_FALSE;
+	} else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,"Started MU!\n");
+	}
+
+
+	/* gen config for all the layers of megaco */
+	return sng_mgco_stack_gen_cfg();
+}
+
+/*****************************************************************************************************************/
+switch_status_t sng_mgco_stack_shutdown()
+{
+	/* free MEGACO Application */
+	sng_isup_free_mu();
+
+	/* free MEGACO */
+	sng_isup_free_mg();
+
+	/* free TUCL */
+	sng_isup_free_tucl();
+
+	/* free SM */
+	sng_isup_free_sm();
+
+	/* free gen */
+	sng_isup_free_gen();
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
+/*****************************************************************************************************************/
+switch_status_t sng_mgco_stack_gen_cfg()
+{
+	if(mgco_mg_gen_config()) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"MG Gen Config FAILED \n");	
+		return SWITCH_STATUS_FALSE;
+	}
+	else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,"MG Gen Config SUCCESS \n");	
+	}
+
+	if(mgco_mu_gen_config()) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"MU(MG-Application) Gen Config FAILED \n");	
+		return SWITCH_STATUS_FALSE;
+	}
+	else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,"MU(MG-Application) Gen Config SUCCESS \n");	
+	}
+
+	if(mgco_tucl_gen_config()) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR," TUCL Gen Config FAILED \n");	
+		return SWITCH_STATUS_FALSE;
+	}
+	else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO," TUCL Gen Config SUCCESS \n");	
+	}
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
+
+/*****************************************************************************************************************/
+
+switch_status_t sng_mgco_cfg(const char* profilename)
+{
+	int idx   = 0x00;
+
+	switch_assert(profilename);
+
+	GET_MG_CFG_IDX(profilename, idx);
+
+	if(!idx || (idx == MAX_MG_PROFILES)){
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR," No MG configuration found against profilename[%s]\n",profilename);
+		return SWITCH_STATUS_FALSE;
+	}
+
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO," Starting MG configuration for idx[%d] against profilename[%s]\n", idx, profilename);
+
+	if(mgco_tucl_sap_config(idx)) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR," mgco_tucl_sap_config FAILED \n");	
+		return SWITCH_STATUS_FALSE;
+	}
+	else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO," mgco_tucl_sap_config SUCCESS \n");	
+	}
+
+
+	if(mgco_mu_ssap_config(idx)) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR," mgco_mu_ssap_config FAILED \n");	
+		return SWITCH_STATUS_FALSE;
+	}
+	else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO," mgco_mu_ssap_config SUCCESS \n");	
+	}
+
+
+	if(mgco_mg_tsap_config(idx)) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR," mgco_mg_tsap_config FAILED \n");	
+		return SWITCH_STATUS_FALSE;
+	}
+	else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO," mgco_mg_tsap_config SUCCESS \n");	
+	}
+
+	if(mgco_mg_ssap_config(idx)) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " mgco_mg_ssap_config FAILED \n");	
+		return SWITCH_STATUS_FALSE;
+	}
+	else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mgco_mg_ssap_config SUCCESS \n");	
+	}
+
+	if(mgco_mg_peer_config(idx)) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " mgco_mg_peer_config FAILED \n");	
+		return SWITCH_STATUS_FALSE;
+	}
+	else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mgco_mg_peer_config SUCCESS \n");	
+	}
+
+	if(mgco_mg_tpt_server_config(idx)) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " mgco_mg_tpt_server_config FAILED \n");	
+		return SWITCH_STATUS_FALSE;
+	}
+	else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mgco_mg_tpt_server_config SUCCESS \n");	
+	}
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
+/*****************************************************************************************************************/
+
+switch_status_t sng_mgco_start(const char* profilename)
+{
+	int idx   = 0x00;
+
+	switch_assert(profilename);
+
+	GET_MG_CFG_IDX(profilename, idx);
+
+	if(!idx || (idx == MAX_MG_PROFILES)){
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR," No MG configuration found against profilename[%s]\n",profilename);
+		return SWITCH_STATUS_FALSE;
+	}
+
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO," Starting MG stack for idx[%d] against profilename[%s]\n", idx, profilename);
+
+	if(mgco_mu_ssap_cntrl(idx)) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " mgco_mu_ssap_cntrl FAILED \n");
+		return SWITCH_STATUS_FALSE;
+	}
+	else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mgco_mu_ssap_cntrl SUCCESS \n");
+	}
+
+	if(mgco_mg_tsap_bind_cntrl(idx)) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " mgco_mg_tsap_bind_cntrl FAILED \n");
+		return SWITCH_STATUS_FALSE;
+	}
+	else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mgco_mg_tsap_bind_cntrl SUCCESS \n");
+	}
+
+	if(mgco_mg_ssap_cntrl(idx)) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " mgco_mg_ssap_cntrl FAILED \n");
+		return SWITCH_STATUS_FALSE;
+	}
+	else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mgco_mg_ssap_cntrl SUCCESS \n");
+	}
+
+	if(mgco_mg_tsap_enable_cntrl(idx)) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " mgco_mg_tsap_enable_cntrl FAILED \n");
+		return SWITCH_STATUS_FALSE;
+	}
+	else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mgco_mg_tsap_enable_cntrl SUCCESS \n");
+	}
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
+/*****************************************************************************************************************/
+int mgco_mg_tsap_bind_cntrl(int idx)
+{
+        MgMngmt         mgMngmt;
+        Pst             pst;              /* Post for layer manager */
+        MgCntrl         *cntrl;
+
+        memset(&mgMngmt, 0, sizeof(mgMngmt));
+
+        cntrl = &(mgMngmt.t.cntrl);
+
+        /* initalize the post structure */
+        smPstInit(&pst);
+
+        /* insert the destination Entity */
+        pst.dstEnt = ENTMG;
+
+        /*fill in the specific fields of the header */
+        mgMngmt.hdr.msgType         = TCNTRL;
+        mgMngmt.hdr.entId.ent       = ENTMG;
+        mgMngmt.hdr.entId.inst      = S_INST;
+        mgMngmt.hdr.elmId.elmnt     = STTSAP;
+
+        cntrl->action       = ABND_ENA;
+        cntrl->subAction    = SAELMNT;
+        cntrl->spId 	    = GET_TPT_ID(idx);
+
+        return(sng_cntrl_mg(&pst, &mgMngmt));
+}
+
+/*****************************************************************************************************************/
+
+int mgco_mg_tsap_enable_cntrl(int idx)
+{
+        MgMngmt         mgMngmt;
+        Pst             pst;              /* Post for layer manager */
+        MgCntrl         *cntrl;
+
+        memset(&mgMngmt, 0, sizeof(mgMngmt));
+
+        cntrl = &(mgMngmt.t.cntrl);
+
+        /* initalize the post structure */
+        smPstInit(&pst);
+
+        /* insert the destination Entity */
+        pst.dstEnt = ENTMG;
+
+        /*fill in the specific fields of the header */
+        mgMngmt.hdr.msgType         = TCNTRL;
+        mgMngmt.hdr.entId.ent       = ENTMG;
+        mgMngmt.hdr.entId.inst      = S_INST;
+        mgMngmt.hdr.elmId.elmnt     = STTSAP;
+
+        cntrl->action       = AENA;
+        cntrl->subAction    = SAELMNT;
+        cntrl->spId 	    = GET_TPT_ID(idx);
+
+        return(sng_cntrl_mg(&pst, &mgMngmt));
+}
+
+/*****************************************************************************************************************/
+
+int mgco_mg_tpt_server(int idx)
+{
+        MgMngmt         mgMngmt;
+        Pst             pst;              /* Post for layer manager */
+        MgCntrl         *cntrl;
+        MgTptCntrl *tptCntrl = &mgMngmt.t.cntrl.s.tptCntrl;
+        CmInetIpAddr   ipAddr = 0;
+	sng_mg_cfg_t* mgCfg  = &megaco_globals.g_mg_cfg.mgCfg[idx];
+
+        cntrl = &(mgMngmt.t.cntrl);
+
+        memset(&mgMngmt, 0, sizeof(mgMngmt));
+
+        /* initalize the post structure */
+        smPstInit(&pst);
+
+        /* insert the destination Entity */
+        pst.dstEnt = ENTMG;
+
+	tptCntrl->transportType = GET_TPT_TYPE(idx);
+        
+	tptCntrl->serverAddr.type =  CM_INET_IPV4ADDR_TYPE;
+	tptCntrl->serverAddr.u.ipv4TptAddr.port = mgCfg->port;
+	if(ROK == cmInetAddr((S8*)mgCfg->my_ipaddr, &ipAddr))
+	{
+		tptCntrl->serverAddr.u.ipv4TptAddr.address = ntohl(ipAddr);
+	}
+
+        /*fill in the specific fields of the header */
+        mgMngmt.hdr.msgType         = TCNTRL;
+        mgMngmt.hdr.entId.ent       = ENTMG;
+        mgMngmt.hdr.entId.inst      = S_INST;
+        mgMngmt.hdr.elmId.elmnt     = STSERVER;
+
+        cntrl->action       = AENA;
+        cntrl->subAction    = SAELMNT;
+        cntrl->spId = (SpId)0x01;
+
+        return(sng_cntrl_mg(&pst, &mgMngmt));
+}
+
+/*****************************************************************************************************************/
+
+int mgco_mu_ssap_cntrl(int idx)
+{
+        MuMngmt         mgMngmt;
+        Pst             pst;              /* Post for layer manager */
+        MuCntrl         *cntrl;
+
+        memset(&mgMngmt, 0, sizeof(mgMngmt));
+
+        cntrl = &(mgMngmt.t.cntrl);
+
+        /* initalize the post structure */
+        smPstInit(&pst);
+
+        /* insert the destination Entity */
+        pst.dstEnt = ENTMU;
+
+        /*fill in the specific fields of the header */
+        mgMngmt.hdr.msgType         = TCNTRL;
+        mgMngmt.hdr.entId.ent       = ENTMG;
+        mgMngmt.hdr.entId.inst      = S_INST;
+        mgMngmt.hdr.elmId.elmnt     = STSSAP;
+        mgMngmt.hdr.elmId.elmntInst1     = GET_MU_SAP_ID(idx);
+
+        cntrl->action       = ABND_ENA;
+        cntrl->subAction    = SAELMNT;
+
+        return(sng_cntrl_mu(&pst, &mgMngmt));
+}
+
+/*****************************************************************************************************************/
+
+int mgco_mg_ssap_cntrl(int idx)
+{
+        MgMngmt         mgMngmt;
+        Pst             pst;              /* Post for layer manager */
+        MgCntrl         *cntrl;
+
+        memset(&mgMngmt, 0, sizeof(mgMngmt));
+
+        cntrl = &(mgMngmt.t.cntrl);
+
+        /* initalize the post structure */
+        smPstInit(&pst);
+
+        /* insert the destination Entity */
+        pst.dstEnt = ENTMG;
+
+        /*fill in the specific fields of the header */
+        mgMngmt.hdr.msgType         = TCNTRL;
+        mgMngmt.hdr.entId.ent       = ENTMG;
+        mgMngmt.hdr.entId.inst      = S_INST;
+        mgMngmt.hdr.elmId.elmnt     = STSSAP;
+
+        cntrl->action       = AENA;
+        cntrl->subAction    = SAELMNT;
+        cntrl->spId = (SpId)1;
+
+        return(sng_cntrl_mg(&pst, &mgMngmt));
+}
+/******************************************************************************/
+                                                                                                       
+int mgco_mg_enble_debug()
+{
+	MgMngmt    mgMngmt;
+	Pst          pst;              /* Post for layer manager */
+	MgCntrl*    cntrl;
+
+	memset(&mgMngmt, 0, sizeof(mgMngmt));
+	cntrl = &mgMngmt.t.cntrl;
+
+	/* initalize the post structure */
+	smPstInit(&pst);
+
+	/* insert the destination Entity */
+	pst.dstEnt = ENTMG;
+	mgMngmt.hdr.msgType         = TCFG;
+	mgMngmt.hdr.entId.ent       = ENTHI;
+	mgMngmt.hdr.entId.inst      = S_INST;
+	mgMngmt.hdr.elmId.elmnt     = STGEN;
+
+	cntrl->action  		        = AENA;
+	cntrl->subAction                = SADBG;
+	cntrl->s.dbg.genDbgMask    = 0xfffffdff;
+
+	return(sng_cntrl_mg(&pst, &mgMngmt));
+}
+
+/******************************************************************************/
+int mgco_tucl_gen_config(void)
+{
+	HiMngmt cfg;
+	Pst     pst;
+
+	/* initalize the post structure */
+	smPstInit(&pst);
+
+	/* insert the destination Entity */
+	pst.dstEnt = ENTHI;
+
+	/* clear the configuration structure */
+	memset(&cfg, 0, sizeof(cfg));
+
+	/* fill in the post structure */
+	set_dest_sm_pst(&cfg.t.cfg.s.hiGen.lmPst);
+	/*fill in the specific fields of the header */
+	cfg.hdr.msgType         = TCFG;
+	cfg.hdr.entId.ent       = ENTHI;
+	cfg.hdr.entId.inst      = S_INST;
+	cfg.hdr.elmId.elmnt     = STGEN;
+
+	cfg.t.cfg.s.hiGen.numSaps               = HI_MAX_SAPS;            		/* number of SAPs */
+	cfg.t.cfg.s.hiGen.numCons               = HI_MAX_NUM_OF_CON;          		/* maximum num of connections */
+	cfg.t.cfg.s.hiGen.numFdsPerSet          = HI_MAX_NUM_OF_FD_PER_SET;     	/* maximum num of fds to use per set */
+	cfg.t.cfg.s.hiGen.numFdBins             = HI_MAX_NUM_OF_FD_HASH_BINS;   	/* for fd hash lists */
+	cfg.t.cfg.s.hiGen.numClToAccept         = HI_MAX_NUM_OF_CLIENT_TO_ACCEPT; 	/* clients to accept simultaneously */
+	cfg.t.cfg.s.hiGen.permTsk               = TRUE;         		 	/* schedule as perm task or timer */
+	cfg.t.cfg.s.hiGen.schdTmrVal            = HI_MAX_SCHED_TMR_VALUE;            	/* if !permTsk - probably ignored */
+	cfg.t.cfg.s.hiGen.selTimeout            = HI_MAX_SELECT_TIMEOUT_VALUE;     	/* select() timeout */
+
+	/* number of raw/UDP messages to read in one iteration */
+	cfg.t.cfg.s.hiGen.numRawMsgsToRead      = HI_MAX_RAW_MSG_TO_READ;
+	cfg.t.cfg.s.hiGen.numUdpMsgsToRead      = HI_MAX_UDP_MSG_TO_READ;
+
+	/* thresholds for congestion on the memory pool */
+	cfg.t.cfg.s.hiGen.poolStrtThr           = HI_MEM_POOL_START_THRESHOLD;
+	cfg.t.cfg.s.hiGen.poolDropThr           = HI_MEM_POOL_DROP_THRESHOLD;
+	cfg.t.cfg.s.hiGen.poolStopThr           = HI_MEM_POOL_STOP_THRESHOLD;
+
+	cfg.t.cfg.s.hiGen.timeRes               = SI_PERIOD;        /* time resolution */
+
+#ifdef HI_SPECIFY_GENSOCK_ADDR
+	cfg.t.cfg.s.hiGen.ipv4GenSockAddr.address = CM_INET_INADDR_ANY;
+	cfg.t.cfg.s.hiGen.ipv4GenSockAddr.port  = 0;                /* DAVIDY - why 0? */
+#ifdef IPV6_SUPPORTED
+	cfg.t.cfg.s.hiGen.ipv6GenSockAddr.address = CM_INET_INADDR6_ANY;
+	cfg.t.cfg.s.hiGen.ipv4GenSockAddr.port  = 0;
+#endif
+#endif
+
+	return(sng_cfg_tucl(&pst, &cfg));
+}
+
+/******************************************************************************/
+
+int mgco_tucl_sap_config(int idx)
+{
+	HiMngmt cfg;
+	Pst     pst;
+	HiSapCfg  *pCfg;
+
+	/* initalize the post structure */
+	smPstInit(&pst);
+
+	/* insert the destination Entity */
+	pst.dstEnt = ENTHI;
+
+	/* clear the configuration structure */
+	memset(&cfg, 0, sizeof(cfg));
+
+	/* fill in the post structure */
+	set_dest_sm_pst(&cfg.t.cfg.s.hiGen.lmPst);
+	/*fill in the specific fields of the header */
+	cfg.hdr.msgType         = TCFG;
+	cfg.hdr.entId.ent       = ENTHI;
+	cfg.hdr.entId.inst      = S_INST;
+	cfg.hdr.elmId.elmnt     = STTSAP;
+
+	pCfg = &cfg.t.cfg.s.hiSap;
+
+	pCfg->spId 		= GET_TPT_ID(idx); 
+	pCfg->uiSel 		= 0x00;  /*loosley coupled */
+	pCfg->flcEnb 		= TRUE;
+	pCfg->txqCongStrtLim 	= HI_SAP_TXN_QUEUE_CONG_START_LIMIT;
+	pCfg->txqCongDropLim 	= HI_SAP_TXN_QUEUE_CONG_DROP_LIMIT;
+	pCfg->txqCongStopLim 	= HI_SAP_TXN_QUEUE_CONG_STOP_LIMIT;
+	pCfg->numBins 		= 10;
+
+	pCfg->uiMemId.region 	= S_REG;
+	pCfg->uiMemId.pool   	= S_POOL;
+	pCfg->uiPrior 	     	= PRIOR0;
+	pCfg->uiRoute        	= RTESPEC;
+
+	return(sng_cfg_tucl(&pst, &cfg));
+}
+
+/******************************************************************************/
+
+int mgco_mg_gen_config(void)
+{
+	MgMngmt    mgMngmt;
+	MgGenCfg    *cfg;
+	Pst          pst;              /* Post for layer manager */
+
+	memset(&mgMngmt, 0, sizeof(mgMngmt));
+	cfg   = &(mgMngmt.t.cfg.c.genCfg);
+
+	/* initalize the post structure */
+	smPstInit(&pst);
+
+	/* insert the destination Entity */
+	pst.dstEnt = ENTMG;
+
+	/* fill in the post structure */
+	set_dest_sm_pst(&mgMngmt.t.cfg.c.genCfg.lmPst);
+	/*fill in the specific fields of the header */
+	mgMngmt.hdr.msgType         = TCFG;
+	mgMngmt.hdr.entId.ent       = ENTMG;
+	mgMngmt.hdr.entId.inst      = S_INST;
+	mgMngmt.hdr.elmId.elmnt     = STGEN;
+
+
+	/*----------- Fill General Configuration Parameters ---------*/
+	cfg->maxSSaps = (U16)MG_MAX_SSAPS;
+	cfg->maxTSaps = (U32)MG_MAX_TSAPS;
+	cfg->maxServers = (U16)MG_MAX_SERVERS;
+	cfg->maxConn = (U32)10;
+	cfg->maxTxn = (U16)MG_MAX_OUTSTANDING_TRANSACTIONS;
+	cfg->maxPeer = (U32)MG_MAX_PEER;
+	cfg->resThUpper = (Status)7;
+	cfg->resThLower = (Status)3;
+#if (defined(GCP_MGCP) || defined(TDS_ROLL_UPGRADE_SUPPORT))   
+	cfg->timeResTTL = (Ticks)10000;
+#endif
+
+	cfg->timeRes = (Ticks)10;
+	cfg->reCfg.rspAckEnb = MG_LMG_GET_RSPACK_MGCO;
+	cfg->numBlks = (U32)MG_NUM_BLK;
+	cfg->maxBlkSize = (Size)MG_MAXBLKSIZE;
+	cfg->numBinsTxnIdHl = (U16)149;
+	cfg->numBinsNameHl = (U16)149;
+	cfg->entType = LMG_ENT_GW;
+	cfg->numBinsTptSrvrHl = (U16)149;
+	cfg->indicateRetx = TRUE;  /* Assume environment to be lossy */
+	cfg->resOrder = LMG_RES_IPV4; /* IPV4 only */
+
+#ifdef CM_ABNF_MT_LIB
+	cfg->firstInst = 1;
+	cfg->edEncTmr.enb = FALSE;
+	cfg->edEncTmr.val = (U16)50;
+	cfg->edDecTmr.enb = TRUE;
+	cfg->edDecTmr.val = (U16)50;
+	cfg->noEDInst = 1;
+#endif /* CM_ABNF_MT_LIB */
+
+#ifdef GCP_CH
+	cfg->numBinsPeerCmdHl = 20;
+	cfg->numBinsTransReqHl = 50;
+	cfg->numBinsTransIndRspCmdHl = 50;
+#endif /* GCP_CH */
+
+#ifdef GCP_MG
+	cfg->maxMgCmdTimeOut.enb =TRUE;
+	cfg->maxMgCmdTimeOut.val =20;
+#endif /* GCP_MG */
+
+#ifdef GCP_MG
+	cfg->maxMgCmdTimeOut.enb =TRUE;
+	cfg->maxMgCmdTimeOut.val =20;
+#endif /* GCP_MG */
+
+#ifdef GCP_MGC
+	cfg->maxMgcCmdTimeOut.enb =TRUE;
+	cfg->maxMgcCmdTimeOut.val =20;
+#endif /* GCP_MG */
+
+#if (defined(GCP_MGCO) && (defined GCP_VER_2_1))
+	cfg->reCfg.segRspTmr.enb = TRUE;
+	cfg->reCfg.segRspTmr.val = (U16)50;
+	cfg->reCfg.segRspAckTmr.enb = TRUE;
+	cfg->reCfg.segRspAckTmr.val = (U16)25;
+#endif
+
+#ifdef GCP_PKG_MGCO_ROOT
+	cfg->limit.pres.pres = PRSNT_NODEF;
+	cfg->limit.mgcOriginatedPendingLimit = 20000;
+	cfg->limit.mgOriginatedPendingLimit  = 20000;
+#endif /* GCP_PKG_MGCO_ROOT */
+
+	return(sng_cfg_mg(&pst, &mgMngmt));
+}
+
+/******************************************************************************/
+
+int mgco_mu_gen_config(void)
+{
+	MuMngmt      mgmt;
+	MuGenCfg    *cfg;
+	Pst          pst;              /* Post for layer manager */
+
+	memset(&mgmt, 0, sizeof(mgmt));
+	cfg   = &(mgmt.t.cfg);
+
+	/* initalize the post structure */
+	smPstInit(&pst);
+
+	/* insert the destination Entity */
+	pst.dstEnt = ENTMU;
+
+	/*fill in the specific fields of the header */
+	mgmt.hdr.msgType         = TCFG;
+	mgmt.hdr.entId.ent       = ENTMU;
+	mgmt.hdr.entId.inst      = S_INST;
+	mgmt.hdr.elmId.elmnt     = STGEN;
+
+	return(sng_cfg_mu(&pst, &mgmt));
+}
+
+/******************************************************************************/
+
+int mgco_mu_ssap_config(int idx)
+{
+	MuMngmt      mgmt;
+	MuSAP_t      *cfg;
+	Pst          pst;              /* Post for layer manager */
+
+	memset(&mgmt, 0, sizeof(mgmt));
+	cfg   = &(mgmt.t.sapCfg);
+
+	/* initalize the post structure */
+	smPstInit(&pst);
+
+	/* insert the destination Entity */
+	pst.dstEnt = ENTMU;
+
+	/*fill in the specific fields of the header */
+	mgmt.hdr.msgType         = TCFG;
+	mgmt.hdr.entId.ent       = ENTMU;
+	mgmt.hdr.entId.inst      = S_INST;
+	mgmt.hdr.elmId.elmnt     = STSSAP;
+
+	/* fill lower layer i.e. MG PST */ 
+	cfg->ssapId 		= GET_MU_SAP_ID(idx); 						/* SSAP ID */ 
+	cfg->spId 		= GET_MU_SAP_ID(idx);  		        			/* SSAP ID */ 
+
+	cfg->mem.region 	= S_REG; 
+	cfg->mem.pool 	        = S_POOL;
+	cfg->dstProcId          = SFndProcId();
+	cfg->dstEnt             = ENTMG; 
+	cfg->dstInst            = S_INST; 
+	cfg->dstPrior     	= PRIOR0; 
+	cfg->dstRoute     	= RTESPEC; 
+	cfg->selector       	= 0x00; /* Loosely coupled */ 
+
+	return(sng_cfg_mu(&pst, &mgmt));
+}
+
+/******************************************************************************/
+
+int mgco_mg_ssap_config(int idx)
+{
+	MgMngmt       mgMngmt;
+	MgSSAPCfg    *pCfg;
+	Pst          pst;              /* Post for layer manager */
+	CmInetIpAddr ipAddr;
+	int len = 0x00;
+	sng_mg_cfg_t* mgCfg  = &megaco_globals.g_mg_cfg.mgCfg[idx];
+
+	memset(&mgMngmt, 0, sizeof(mgMngmt));
+	pCfg   = &(mgMngmt.t.cfg.c.sSAPCfg);
+
+	/* initalize the post structure */
+	smPstInit(&pst);
+
+	/* insert the destination Entity */
+	pst.dstEnt = ENTMG;
+
+	/*fill in the specific fields of the header */
+	mgMngmt.hdr.msgType         = TCFG;
+	mgMngmt.hdr.entId.ent       = ENTMG;
+	mgMngmt.hdr.entId.inst      = S_INST;
+	mgMngmt.hdr.elmId.elmnt     = STSSAP;
+
+	/* FILL SAP config */
+
+	pCfg->sSAPId 		= mgCfg->id;  		/* SSAP ID */ 
+	pCfg->sel 		= 0x00 ; 				/* Loosely coupled */ 
+	pCfg->memId.region 	= S_REG; 
+	pCfg->memId.pool 	= S_POOL;
+	pCfg->prior 		= PRIOR0; 
+	pCfg->route 		= RTESPEC;
+
+	pCfg->protocol 		= mgCfg->protocol_type;
+
+	pCfg->startTxnNum = 50;
+	pCfg->endTxnNum   = 60;
+
+	pCfg->initReg = TRUE;
+	pCfg->mwdTimer = (U16)10;
+
+	pCfg->minMgcoVersion = LMG_VER_PROF_MGCO_H248_1_0;
+	pCfg->maxMgcoVersion = LMG_VER_PROF_MGCO_H248_3_0;
+
+	pCfg->userInfo.pres.pres = PRSNT_NODEF;
+	pCfg->userInfo.id.pres 	 = NOTPRSNT;
+	pCfg->userInfo.mid.pres = PRSNT_NODEF;
+	pCfg->userInfo.dname.namePres.pres = PRSNT_NODEF;
+
+	pCfg->userInfo.mid.len = (U8)strlen((char*)mgCfg->mid);
+	strncpy((char*)pCfg->userInfo.mid.val, (char*)mgCfg->mid, MAX_MID_LEN);
+
+	len = (U32)strlen((char*)mgCfg->my_domain);
+	memcpy( (U8*)(pCfg->userInfo.dname.name),
+			(CONSTANT U8*)(mgCfg->my_domain), len );
+	pCfg->userInfo.dname.name[len] = '\0';
+
+	pCfg->userInfo.dname.netAddr.type = CM_TPTADDR_IPV4;
+	memset(&ipAddr,'\0',sizeof(ipAddr));
+	if(ROK == cmInetAddr((S8*)mgCfg->my_ipaddr,&ipAddr))
+	{
+		pCfg->userInfo.dname.netAddr.u.ipv4NetAddr = ntohl(ipAddr);
+	}
+
+	pCfg->reCfg.initRetxTmr.enb = TRUE;
+	pCfg->reCfg.initRetxTmr.val = MG_INIT_RTT;
+	pCfg->reCfg.provRspTmr.enb = TRUE;
+	pCfg->reCfg.provRspTmr.val = (U16)50; /* In timer resolution */
+	pCfg->reCfg.provRspDelay = 2;
+	pCfg->reCfg.atMostOnceTmr.enb = TRUE;
+	pCfg->reCfg.atMostOnceTmr.val = (U16)30;
+
+	return(sng_cfg_mg(&pst, &mgMngmt));
+}
+
+/******************************************************************************/
+
+int mgco_mg_tsap_config(int idx)
+{
+	MgMngmt    mgMngmt;
+	/* local variables */
+	MgTSAPCfg    *cfg;
+	Pst          pst;              /* Post for layer manager */
+	sng_mg_cfg_t* mgCfg  = &megaco_globals.g_mg_cfg.mgCfg[idx];
+
+	memset(&mgMngmt, 0, sizeof(mgMngmt));
+	cfg   = &(mgMngmt.t.cfg.c.tSAPCfg);
+
+	/* initalize the post structure */
+	smPstInit(&pst);
+
+	/* insert the destination Entity */
+	pst.dstEnt = ENTMG;
+
+	/*fill in the specific fields of the header */
+	mgMngmt.hdr.msgType         = TCFG;
+	mgMngmt.hdr.entId.ent       = ENTMG;
+	mgMngmt.hdr.entId.inst      = S_INST;
+	mgMngmt.hdr.elmId.elmnt     = STTSAP;
+
+	/* FILL TSAP config */
+	cfg->tSAPId 	= mgCfg->id;
+	cfg->spId   	= GET_TPT_ID(idx);
+	cfg->provType 	= GET_TPT_TYPE(idx);
+
+	/* FILL TUCL Information */
+	cfg->memId.region = S_REG; 
+	cfg->memId.pool   = S_POOL; 
+	cfg->dstProcId    = SFndProcId();
+	cfg->dstEnt       = ENTHI; 
+	cfg->dstInst      = S_INST; 
+	cfg->dstPrior     = PRIOR0; 
+	cfg->dstRoute     = RTESPEC; 
+	cfg->dstSel       = 0x00; /* Loosely coupled */ 
+	cfg->bndTmrCfg.enb = TRUE;
+	cfg->bndTmrCfg.val = 5; /* 5 seconds */
+
+
+	/* Disable DNS as of now */
+	cfg->reCfg.idleTmr.enb = FALSE;
+        cfg->reCfg.dnsCfg.dnsAccess = LMG_DNS_DISABLED;
+        cfg->reCfg.dnsCfg.dnsAddr.type = CM_TPTADDR_IPV4;
+        cfg->reCfg.dnsCfg.dnsAddr.u.ipv4TptAddr.port = (U16)53;
+        cfg->reCfg.dnsCfg.dnsAddr.u.ipv4TptAddr.address = (CmInetIpAddr)MG_DNS_IP;
+
+        cfg->reCfg.dnsCfg.dnsRslvTmr.enb = FALSE;
+        cfg->reCfg.dnsCfg.dnsRslvTmr.val = 60; /* 60 sec */
+        cfg->reCfg.dnsCfg.maxRetxCnt = 4;
+
+        cfg->reCfg.tMax = 1000;
+        cfg->reCfg.tptParam.type = CM_TPTPARAM_SOCK;
+        cfg->reCfg.tptParam.u.sockParam.listenQSize = 5;
+        cfg->reCfg.tptParam.u.sockParam.numOpts = 0;
+
+
+	return(sng_cfg_mg(&pst, &mgMngmt));
+}
+
+/******************************************************************************/
+
+int mgco_mg_peer_config(int idx)
+{
+	MgMngmt    	mgMngmt;
+	MgGcpEntCfg    *cfg;
+	Pst          	pst;              /* Post for layer manager */
+	U32            peerIdx = 0;
+	CmInetIpAddr   ipAddr = 0;
+	sng_mg_cfg_t*  mgCfg  = &megaco_globals.g_mg_cfg.mgCfg[idx];
+	sng_mg_peer_t*  mgPeer = &megaco_globals.g_mg_cfg.mgPeer.peers[mgCfg->peer_id];
+
+	memset(&mgMngmt, 0, sizeof(mgMngmt));
+	cfg   = &(mgMngmt.t.cfg.c.mgGcpEntCfg);
+
+	/* initalize the post structure */
+	smPstInit(&pst);
+
+	/* insert the destination Entity */
+	pst.dstEnt = ENTMG;
+
+	/*fill in the specific fields of the header */
+	mgMngmt.hdr.msgType         = TCFG;
+	mgMngmt.hdr.entId.ent       = ENTMG;
+	mgMngmt.hdr.entId.inst      = S_INST;
+	mgMngmt.hdr.elmId.elmnt     = STGCPENT;
+
+	cfg->numPeer 			= megaco_globals.g_mg_cfg.mgPeer.total_peer;
+	cfg->peerCfg[peerIdx].sSAPId 	= mgCfg->id;        /* SSAP ID */;
+	cfg->peerCfg[peerIdx].port 	= mgPeer->port;
+	cfg->peerCfg[peerIdx].tsapId 	= GET_TPT_ID(idx);
+
+	cfg->peerCfg[peerIdx].mtuSize = MG_MAX_MTU_SIZE;
+
+
+	cfg->peerCfg[peerIdx].peerAddrTbl.count = 1;
+	cfg->peerCfg[peerIdx].peerAddrTbl.netAddr[0].type =
+		CM_NETADDR_IPV4;
+
+	if(ROK == cmInetAddr((S8*)&mgPeer->ipaddr[0],&ipAddr))
+	{
+		cfg->peerCfg[peerIdx].peerAddrTbl.netAddr[0].u.ipv4NetAddr = ntohl(ipAddr);
+	}
+	else
+	{
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "cmInetAddr failed \n");
+		cfg->peerCfg[peerIdx].peerAddrTbl.count = 0;
+	}
+
+#ifdef GCP_MG
+	cfg->peerCfg[peerIdx].transportType  = GET_TPT_TYPE(idx);
+	cfg->peerCfg[peerIdx].encodingScheme = GET_ENCODING_TYPE(idx); 
+	cfg->peerCfg[peerIdx].mgcPriority = 0;
+	cfg->peerCfg[peerIdx].useAHScheme = FALSE;
+	cfg->peerCfg[peerIdx].mid.pres = PRSNT_NODEF;
+	cfg->peerCfg[peerIdx].mid.len = strlen((char*)mgPeer->mid);
+	cmMemcpy((U8 *)cfg->peerCfg[peerIdx].mid.val, 
+		(CONSTANT U8*)(char*)mgPeer->mid, 
+		 cfg->peerCfg[peerIdx].mid.len);
+
+#endif /* GCP_MG */
+
+	return(sng_cfg_mg(&pst, &mgMngmt));
+}
+
+/******************************************************************************/
+
+int mgco_mg_tpt_server_config(int idx)
+{
+	MgMngmt    	mgMngmt;
+	MgTptSrvrCfg    *cfg;
+	Pst          	pst;              /* Post for layer manager */
+	CmInetIpAddr   ipAddr = 0;
+	sng_mg_cfg_t*  mgCfg  = &megaco_globals.g_mg_cfg.mgCfg[idx];
+	int srvIdx = 0;
+
+	memset(&mgMngmt, 0, sizeof(mgMngmt));
+	cfg   = &(mgMngmt.t.cfg.c.tptSrvrCfg);
+
+	/* initalize the post structure */
+	smPstInit(&pst);
+
+	/* insert the destination Entity */
+	pst.dstEnt = ENTMG;
+
+	/*fill in the specific fields of the header */
+	mgMngmt.hdr.msgType         = TCFG;
+	mgMngmt.hdr.entId.ent       = ENTMG;
+	mgMngmt.hdr.entId.inst      = S_INST;
+	mgMngmt.hdr.elmId.elmnt     = STSERVER;
+
+	cfg->count = 1;
+	cfg->srvr[srvIdx].isDefault = TRUE;
+	cfg->srvr[srvIdx].sSAPId = mgCfg->id;
+	cfg->srvr[srvIdx].tSAPId = GET_TPT_ID(idx);
+	cfg->srvr[srvIdx].protocol = mgCfg->protocol_type;
+	cfg->srvr[srvIdx].transportType = GET_TPT_TYPE(idx); 
+	cfg->srvr[srvIdx].encodingScheme = GET_ENCODING_TYPE(idx);
+
+	cfg->srvr[srvIdx].tptParam.type = CM_TPTPARAM_SOCK;
+	cfg->srvr[srvIdx].tptParam.u.sockParam.listenQSize = 5;
+	cfg->srvr[srvIdx].tptParam.u.sockParam.numOpts = 0;
+	cfg->srvr[srvIdx].lclTptAddr.type = CM_TPTADDR_IPV4;
+	cfg->srvr[srvIdx].lclTptAddr.u.ipv4TptAddr.port = mgCfg->port;
+	if(ROK == cmInetAddr((S8*)mgCfg->my_ipaddr, &ipAddr))
+	{
+		cfg->srvr[srvIdx].lclTptAddr.u.ipv4TptAddr.address = ntohl(ipAddr);
+	}
+
+	return(sng_cfg_mg(&pst, &mgMngmt));
+}
+
+/******************************************************************************/
diff --git a/src/mod/endpoints/mod_megaco/megaco_cfg.h b/src/mod/endpoints/mod_megaco/megaco_stack.h
similarity index 71%
rename from src/mod/endpoints/mod_megaco/megaco_cfg.h
rename to src/mod/endpoints/mod_megaco/megaco_stack.h
index 54bf310b29..24cf6e26ca 100644
--- a/src/mod/endpoints/mod_megaco/megaco_cfg.h
+++ b/src/mod/endpoints/mod_megaco/megaco_stack.h
@@ -51,12 +51,21 @@ typedef enum{
         SNG_MG_MEGACO,
 }sng_mg_protocol_types_e;
 
+#define PRNT_PROTOCOL_TYPE(_val)\
+	((_val == SNG_MG_MGCP)?"SNG_MG_MGCP":\
+	 (_val == SNG_MG_MEGACO)?"SNG_MG_MEGACO":\
+	 "SNG_MG_NONE")
+
 typedef enum{
         SNG_MG_ENCODING_NONE,
-        SNG_MG_ENCODING_TEXT,
         SNG_MG_ENCODING_BINARY,
+        SNG_MG_ENCODING_TEXT,
 }sng_mg_encoding_types_e;
 
+#define PRNT_ENCODING_TYPE(_val)\
+	((_val == SNG_MG_ENCODING_TEXT)?"SNG_MG_ENCODING_TEXT":\
+	 (_val == SNG_MG_ENCODING_BINARY)?"SNG_MG_ENCODING_BINARY":\
+	 "SNG_MG_ENCODING_NONE")
 
 
 /* each profile is corresponds to each MG Instance */
@@ -95,4 +104,32 @@ void handle_mgco_audit_cfm(Pst *pst, SuId suId, MgMgtAudit* audit, Reason reason
 void handle_mg_alarm(Pst *pst, MgMngmt *sta);
 void handle_tucl_alarm(Pst *pst, HiMngmt *sta);
 
+
+switch_status_t sng_mgco_init(sng_isup_event_interface_t* event);
+switch_status_t sng_mgco_cfg(const char* profilename);
+switch_status_t sng_mgco_start(const char* profilename);
+switch_status_t sng_mgco_stack_shutdown(void);
+
+/*****************************************************************************************************/
+
+#define GET_MG_CFG_IDX(_profilename, _idx){\
+	for(idx=0; idx < MAX_MG_PROFILES; idx++){\
+		/* id zero is not acceptable */\
+		if(megaco_globals.g_mg_cfg.mgCfg[idx].id){\
+			if (strcmp(megaco_globals.g_mg_cfg.mgCfg[idx].name, profilename)) {\
+				continue;\
+			} else{\
+				break;\
+			}\
+		}\
+	}\
+}
+
+#define GET_TPT_ID(_id) 		megaco_globals.g_mg_cfg.mgTptProf[megaco_globals.g_mg_cfg.mgCfg[_id].transport_prof_id].id
+#define GET_MU_SAP_ID(_id) 		megaco_globals.g_mg_cfg.mgCfg[_id].id
+
+#define GET_TPT_TYPE(_id)		megaco_globals.g_mg_cfg.mgTptProf[megaco_globals.g_mg_cfg.mgCfg[_id].transport_prof_id].transport_type
+
+#define GET_ENCODING_TYPE(_id) 		megaco_globals.g_mg_cfg.mgPeer.peers[megaco_globals.g_mg_cfg.mgCfg[_id].peer_id].encoding_type
+
 #endif /* _MEGACO_CFG_H_ */
diff --git a/src/mod/endpoints/mod_megaco/megaco_xml.c b/src/mod/endpoints/mod_megaco/megaco_xml.c
index 506cc3b29e..e7addf5875 100644
--- a/src/mod/endpoints/mod_megaco/megaco_xml.c
+++ b/src/mod/endpoints/mod_megaco/megaco_xml.c
@@ -214,6 +214,7 @@ switch_status_t sng_parse_mg_peer_profile(switch_xml_t mg_peer_profile)
 		}
 	}
 
+	megaco_globals.g_mg_cfg.mgPeer.total_peer++;
 	return SWITCH_STATUS_SUCCESS;
 }
 /***********************************************************************************************************/
diff --git a/src/mod/endpoints/mod_megaco/mod_megaco.c b/src/mod/endpoints/mod_megaco/mod_megaco.c
index bda8e53ec0..332392c59a 100644
--- a/src/mod/endpoints/mod_megaco/mod_megaco.c
+++ b/src/mod/endpoints/mod_megaco/mod_megaco.c
@@ -123,25 +123,22 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_megaco_load)
 	sng_event.mg.sng_mgco_cmd_ind  		= handle_mgco_cmd_ind;
 	sng_event.mg.sng_mgco_txn_sta_ind  	= handle_mgco_txn_sta_ind;
 	sng_event.mg.sng_mgco_sta_ind  		= handle_mgco_sta_ind;
-	sng_event.mg.sng_mgco_cntrl_cfm  		= handle_mgco_cntrl_cfm;
-	sng_event.mg.sng_mgco_audit_cfm  		= handle_mgco_audit_cfm;
-
+	sng_event.mg.sng_mgco_cntrl_cfm  	= handle_mgco_cntrl_cfm;
+	sng_event.mg.sng_mgco_audit_cfm  	= handle_mgco_audit_cfm;
 	/* Alarm CB */
 	sng_event.sm.sng_mg_alarm  		= handle_mg_alarm;
 	sng_event.sm.sng_tucl_alarm  		= handle_tucl_alarm;
-
 	/* Log */
 	sng_event.sm.sng_log  			= handle_sng_log;
 
-	/* initalize sng_mg library */
-	sng_isup_init_gen(&sng_event);
-	
-	return SWITCH_STATUS_SUCCESS;
+	/* initualize MEGACO stack */
+	return sng_mgco_init(&sng_event);
 }
 
 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_megaco_shutdown)
 {
-	/* TODO: Kapil: Insert stack global shutdown code here */	
+	sng_mgco_stack_shutdown();
+
 	return SWITCH_STATUS_SUCCESS;
 }
 
diff --git a/src/mod/endpoints/mod_megaco/mod_megaco.h b/src/mod/endpoints/mod_megaco/mod_megaco.h
index 3efa48e3bc..7c21610639 100644
--- a/src/mod/endpoints/mod_megaco/mod_megaco.h
+++ b/src/mod/endpoints/mod_megaco/mod_megaco.h
@@ -11,7 +11,7 @@
 #define MOD_MEGACO_H
 
 #include <switch.h>
-#include "megaco_cfg.h"
+#include "megaco_stack.h"
 
 struct megaco_globals {
 	switch_memory_pool_t 		*pool;