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] 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;