]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
modifying XML parsing / configuration code
authorkapil <kgupta@sangoma.com>
Wed, 6 Jun 2012 09:14:20 +0000 (14:44 +0530)
committerkapil <kgupta@sangoma.com>
Wed, 6 Jun 2012 09:14:20 +0000 (14:44 +0530)
src/mod/endpoints/mod_megaco/megaco.c
src/mod/endpoints/mod_megaco/megaco_stack.c
src/mod/endpoints/mod_megaco/megaco_stack.h
src/mod/endpoints/mod_megaco/megaco_xml.c
src/mod/endpoints/mod_megaco/mod_megaco.c
src/mod/endpoints/mod_megaco/mod_megaco.h

index b73eaefec0d9055225669ba5341bc62b51683327..aa8fd8ede1dfbf1d4f68c5818ccefa3be4d859fe 100644 (file)
@@ -8,7 +8,7 @@
 
 #include "mod_megaco.h"
 
-megaco_profile_t *megaco_profile_locate(const char *name) 
+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);
 
@@ -22,97 +22,28 @@ megaco_profile_t *megaco_profile_locate(const char *name)
        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)
+mg_peer_profile_t *megaco_peer_profile_locate(const char *name)
 {
-       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;
-       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 (!(mg_interfaces = switch_xml_child(cfg, "sng_mg_interfaces"))) {
-               goto done;
-       }
-
-       /* iterate through MG Interface list to build requested MG profile */
-       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;
-               }
-
-               /* parse MG profile */
-               if(SWITCH_STATUS_FALSE == sng_parse_mg_profile(mg_interface)) {
-                       goto done;
-               }
-
-               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;
-               }
+       mg_peer_profile_t *profile = switch_core_hash_find_rdlock(megaco_globals.peer_profile_hash, name, megaco_globals.peer_profile_rwlock);
 
-               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;
-                       }
+       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;
                }
-
-
-               /* configure the MEGACO stack */
-               status = sng_mgco_cfg(profile->name);
-               
-               /* we should break from here , profile name should be unique */
-               break;
        }
 
-done:
-       if (xml) {
-               switch_xml_free(xml);   
-       }
+       return profile;
+}
 
-       if (event) {
-               switch_event_destroy(&event);
-       }
-       return status;
+void megaco_profile_release(megaco_profile_t *profile) 
+{
+       switch_thread_rwlock_unlock(profile->rwlock);
+}
+
+void megaco_peer_profile_release(mg_peer_profile_t *profile) 
+{
+       switch_thread_rwlock_unlock(profile->rwlock);
 }
 
 switch_status_t megaco_profile_start(const char *profilename)
@@ -130,14 +61,13 @@ switch_status_t megaco_profile_start(const char *profilename)
        profile->name = switch_core_strdup(pool, profilename);
        
        switch_thread_rwlock_create(&profile->rwlock, pool);
-       
-       if (config_profile(profile, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) {
+
+       if (SWITCH_STATUS_SUCCESS != config_profile(profile, SWITCH_FALSE)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error configuring profile %s\n", profile->name);
                goto fail;
        }
        
-       /* start MEGACP stack */
-       if(SWITCH_STATUS_FALSE == sng_mgco_start(profilename)) {
+       if(SWITCH_STATUS_FALSE == sng_mgco_start(profile)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error starting MEGACO Stack for profile  %s\n", profile->name);
                goto fail;
        }
@@ -161,8 +91,7 @@ switch_status_t megaco_profile_destroy(megaco_profile_t **profile)
        switch_thread_rwlock_wrlock((*profile)->rwlock);
        
        
-       /* stop MEGACP stack */
-       if(SWITCH_STATUS_FALSE == sng_mgco_stop((*profile)->name)) {
+       if(SWITCH_STATUS_FALSE == sng_mgco_stop((*profile))) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error stopping MEGACO Stack for profile  %s\n", (*profile)->name); 
        }
 
@@ -171,6 +100,8 @@ switch_status_t megaco_profile_destroy(megaco_profile_t **profile)
        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);
        
+       mg_config_cleanup(*profile);
+
        switch_core_destroy_memory_pool(&(*profile)->pool);
        
        return SWITCH_STATUS_SUCCESS;   
index 74874e75d5bf73befbb8d5292382770f5d910eeb..103f8726e7b8806a18da3edd0e87ec99a1298549 100644 (file)
@@ -8,6 +8,7 @@
 
 /* INCLUDES *******************************************************************/
 #include "mod_megaco.h"
+#include "megaco_stack.h"
 /******************************************************************************/
 
 /* DEFINES ********************************************************************/
@@ -17,28 +18,32 @@ 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_tsap_config(megaco_profile_t* profile);
 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_mg_ssap_config(megaco_profile_t* profile);
+int mgco_mg_peer_config(megaco_profile_t* profile);
+int mgco_mg_tpt_server_config(megaco_profile_t* profile);
 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);
 int sng_mgco_tucl_shutdown();
 int sng_mgco_mg_shutdown();
 int sng_mgco_mg_ssap_stop(int sapId);
-int sng_mgco_mg_tpt_server_stop(int idx);
+int sng_mgco_mg_tpt_server_stop(megaco_profile_t* profile);
 int sng_mgco_mg_app_ssap_stop(int idx);
 
 switch_status_t sng_mgco_stack_gen_cfg();
 
 void get_peer_xml_buffer(char* prntBuf, MgPeerSta* cfm);
 
+sng_mg_transport_types_e  mg_get_tpt_type(megaco_profile_t* mg_cfg);
+sng_mg_transport_types_e  mg_get_tpt_type_from_str(char* tpt_type);
+sng_mg_encoding_types_e  mg_get_enc_type_from_str(char* enc_type);
+sng_mg_protocol_types_e  mg_get_proto_type_from_str(char* proto_type);
+
 /******************************************************************************/
 
 /* FUNCTIONS ******************************************************************/
@@ -150,20 +155,15 @@ switch_status_t sng_mgco_stack_gen_cfg()
 
 /*****************************************************************************************************************/
 
-switch_status_t sng_mgco_cfg(const char* profilename)
+switch_status_t sng_mgco_cfg(megaco_profile_t* profile)
 {
        int idx   = 0x00;
 
-       switch_assert(profilename);
-
-       GET_MG_CFG_IDX(profilename, idx);
+       switch_assert(profile);
 
-       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", profile->idx, profile->name);
 
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO," Starting MG configuration for idx[%d] against profilename[%s]\n", idx, profilename);
+       idx = profile->idx;
 
        if(mgco_tucl_sap_config(idx)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR," mgco_tucl_sap_config FAILED \n");      
@@ -183,7 +183,7 @@ switch_status_t sng_mgco_cfg(const char* profilename)
        }
 
 
-       if(mgco_mg_tsap_config(idx)) {
+       if(mgco_mg_tsap_config(profile)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR," mgco_mg_tsap_config FAILED \n");       
                return SWITCH_STATUS_FALSE;
        }
@@ -191,7 +191,7 @@ switch_status_t sng_mgco_cfg(const char* profilename)
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO," mgco_mg_tsap_config SUCCESS \n");       
        }
 
-       if(mgco_mg_ssap_config(idx)) {
+       if(mgco_mg_ssap_config(profile)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " mgco_mg_ssap_config FAILED \n");      
                return SWITCH_STATUS_FALSE;
        }
@@ -199,7 +199,7 @@ switch_status_t sng_mgco_cfg(const char* profilename)
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mgco_mg_ssap_config SUCCESS \n");      
        }
 
-       if(mgco_mg_peer_config(idx)) {
+       if(mgco_mg_peer_config(profile)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " mgco_mg_peer_config FAILED \n");      
                return SWITCH_STATUS_FALSE;
        }
@@ -207,7 +207,7 @@ switch_status_t sng_mgco_cfg(const char* profilename)
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mgco_mg_peer_config SUCCESS \n");      
        }
 
-       if(mgco_mg_tpt_server_config(idx)) {
+       if(mgco_mg_tpt_server_config(profile)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " mgco_mg_tpt_server_config FAILED \n");        
                return SWITCH_STATUS_FALSE;
        }
@@ -220,22 +220,11 @@ switch_status_t sng_mgco_cfg(const char* profilename)
 
 /*****************************************************************************************************************/
 
-switch_status_t sng_mgco_start(const char* profilename)
+switch_status_t sng_mgco_start(megaco_profile_t* profile )
 {
-       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", profile->idx, profile->name);
 
-       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)) {
+       if(mgco_mu_ssap_cntrl(profile->idx)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " mgco_mu_ssap_cntrl FAILED \n");
                return SWITCH_STATUS_FALSE;
        }
@@ -243,7 +232,7 @@ switch_status_t sng_mgco_start(const char* profilename)
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mgco_mu_ssap_cntrl SUCCESS \n");
        }
 
-       if(mgco_mg_tsap_bind_cntrl(idx)) {
+       if(mgco_mg_tsap_bind_cntrl(profile->idx)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " mgco_mg_tsap_bind_cntrl FAILED \n");
                return SWITCH_STATUS_FALSE;
        }
@@ -251,7 +240,7 @@ switch_status_t sng_mgco_start(const char* profilename)
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mgco_mg_tsap_bind_cntrl SUCCESS \n");
        }
 
-       if(mgco_mg_ssap_cntrl(idx)) {
+       if(mgco_mg_ssap_cntrl(profile->idx)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " mgco_mg_ssap_cntrl FAILED \n");
                return SWITCH_STATUS_FALSE;
        }
@@ -259,7 +248,7 @@ switch_status_t sng_mgco_start(const char* profilename)
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " mgco_mg_ssap_cntrl SUCCESS \n");
        }
 
-       if(mgco_mg_tsap_enable_cntrl(idx)) {
+       if(mgco_mg_tsap_enable_cntrl(profile->idx)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " mgco_mg_tsap_enable_cntrl FAILED \n");
                return SWITCH_STATUS_FALSE;
        }
@@ -272,28 +261,20 @@ switch_status_t sng_mgco_start(const char* profilename)
 
 /*****************************************************************************************************************/
 
-switch_status_t sng_mgco_stop(const char* profilename)
+switch_status_t sng_mgco_stop(megaco_profile_t* profile )
 {
-       int idx   = 0x00;
-       sng_mg_cfg_t* mgCfg  = NULL; 
+       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_assert(profile);
 
-       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO," Stopping MG stack for idx[%d] against profilename[%s]\n", idx, profilename);
+       idx = profile->idx;     
 
-       mgCfg  = &megaco_globals.g_mg_cfg.mgCfg[idx];
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO," Stopping MG stack for idx[%d] against profilename[%s]\n", idx, profile->name);
 
        /* MG STOP is as good as deleting that perticular mg(virtual mg instance) data from megaco stack */
        /* currently we are not supporting enable/disable MG stack */
 
-       if(sng_mgco_mg_ssap_stop(mgCfg->id)) {
+       if(sng_mgco_mg_ssap_stop(idx)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " sng_mgco_mg_ssap_stop FAILED \n");
                return SWITCH_STATUS_FALSE;
        }
@@ -301,7 +282,7 @@ switch_status_t sng_mgco_stop(const char* profilename)
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " sng_mgco_mg_ssap_stop SUCCESS \n");
        }
 
-       if(sng_mgco_mg_tpt_server_stop(idx)) {
+       if(sng_mgco_mg_tpt_server_stop(profile)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " sng_mgco_mg_tpt_server_stop FAILED \n");
                return SWITCH_STATUS_FALSE;
        }
@@ -342,7 +323,7 @@ int sng_mgco_mg_app_ssap_stop(int idx)
         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);
+        mgMngmt.hdr.elmId.elmntInst1     = idx;
 
         cntrl->action       = ADEL;
         cntrl->subAction    = SAELMNT;
@@ -383,14 +364,13 @@ int sng_mgco_mg_ssap_stop(int sapId)
 }
 
 /*****************************************************************************************************************/
-int sng_mgco_mg_tpt_server_stop(int idx)
+int sng_mgco_mg_tpt_server_stop(megaco_profile_t* mg_cfg)
 {
         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);
 
@@ -402,11 +382,11 @@ int sng_mgco_mg_tpt_server_stop(int idx)
         /* insert the destination Entity */
         pst.dstEnt = ENTMG;
 
-       tptCntrl->transportType = GET_TPT_TYPE(idx);
+       tptCntrl->transportType = mg_get_tpt_type(mg_cfg); 
         
        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.port = atoi(mg_cfg->port);
+       if(ROK == cmInetAddr((S8*)mg_cfg->my_ipaddr, &ipAddr))
        {
                tptCntrl->serverAddr.u.ipv4TptAddr.address = ntohl(ipAddr);
        }
@@ -448,7 +428,7 @@ int mgco_mg_tsap_bind_cntrl(int idx)
 
         cntrl->action       = ABND_ENA;
         cntrl->subAction    = SAELMNT;
-        cntrl->spId        = GET_TPT_ID(idx);
+        cntrl->spId        = idx; 
 
         return(sng_cntrl_mg(&pst, &mgMngmt));
 }
@@ -479,13 +459,14 @@ int mgco_mg_tsap_enable_cntrl(int idx)
 
         cntrl->action       = AENA;
         cntrl->subAction    = SAELMNT;
-        cntrl->spId        = GET_TPT_ID(idx);
+        cntrl->spId        = idx;
 
         return(sng_cntrl_mg(&pst, &mgMngmt));
 }
 
 /*****************************************************************************************************************/
 
+#if 0
 int mgco_mg_tpt_server(int idx)
 {
         MgMngmt         mgMngmt;
@@ -493,7 +474,7 @@ int mgco_mg_tpt_server(int idx)
         MgCntrl         *cntrl;
         MgTptCntrl *tptCntrl = &mgMngmt.t.cntrl.s.tptCntrl;
         CmInetIpAddr   ipAddr = 0;
-       sng_mg_cfg_t* mgCfg  = &megaco_globals.g_mg_cfg.mgCfg[idx];
+       sng_mg_cfg_t* mg_cfg  = &megaco_globals.g_mg_cfg.mg_cfg[idx];
 
         cntrl = &(mgMngmt.t.cntrl);
 
@@ -508,8 +489,8 @@ int mgco_mg_tpt_server(int idx)
        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.port = mg_cfg->port;
+       if(ROK == cmInetAddr((S8*)mg_cfg->my_ipaddr, &ipAddr))
        {
                tptCntrl->serverAddr.u.ipv4TptAddr.address = ntohl(ipAddr);
        }
@@ -526,6 +507,7 @@ int mgco_mg_tpt_server(int idx)
 
         return(sng_cntrl_mg(&pst, &mgMngmt));
 }
+#endif
 
 /*****************************************************************************************************************/
 
@@ -550,7 +532,7 @@ int mgco_mu_ssap_cntrl(int idx)
         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);
+        mgMngmt.hdr.elmId.elmntInst1     = idx;
 
         cntrl->action       = ABND_ENA;
         cntrl->subAction    = SAELMNT;
@@ -584,7 +566,7 @@ int mgco_mg_ssap_cntrl(int idx)
 
         cntrl->action       = AENA;
         cntrl->subAction    = SAELMNT;
-        cntrl->spId = (SpId)1;
+        cntrl->spId = (SpId)idx;
 
         return(sng_cntrl_mg(&pst, &mgMngmt));
 }
@@ -698,7 +680,7 @@ int mgco_tucl_sap_config(int idx)
 
        pCfg = &cfg.t.cfg.s.hiSap;
 
-       pCfg->spId              = GET_TPT_ID(idx)
+       pCfg->spId              = idx
        pCfg->uiSel             = 0x00;  /*loosley coupled */
        pCfg->flcEnb            = TRUE;
        pCfg->txqCongStrtLim    = HI_SAP_TXN_QUEUE_CONG_START_LIMIT;
@@ -860,8 +842,8 @@ int mgco_mu_ssap_config(int idx)
        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->ssapId             = idx; 
+       cfg->spId               = idx;
 
        cfg->mem.region         = S_REG; 
        cfg->mem.pool           = S_POOL;
@@ -877,14 +859,13 @@ int mgco_mu_ssap_config(int idx)
 
 /******************************************************************************/
 
-int mgco_mg_ssap_config(int idx)
+int mgco_mg_ssap_config(megaco_profile_t* profile)
 {
        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);
@@ -903,14 +884,14 @@ int mgco_mg_ssap_config(int idx)
 
        /* FILL SAP config */
 
-       pCfg->sSAPId            = mgCfg->id;            /* SSAP ID */ 
+       pCfg->sSAPId            = profile->idx;                 /* 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->protocol          = mg_get_proto_type_from_str(profile->protocol_type);
 
        pCfg->startTxnNum = 50;
        pCfg->endTxnNum   = 60;
@@ -919,7 +900,7 @@ int mgco_mg_ssap_config(int idx)
        pCfg->mwdTimer = (U16)10;
 
        pCfg->minMgcoVersion = LMG_VER_PROF_MGCO_H248_1_0;
-       switch(mgCfg->protocol_version)
+       switch(profile->protocol_version)
        {
                case 1:
                        pCfg->maxMgcoVersion = LMG_VER_PROF_MGCO_H248_1_0;
@@ -931,7 +912,7 @@ int mgco_mg_ssap_config(int idx)
                        pCfg->maxMgcoVersion = LMG_VER_PROF_MGCO_H248_3_0;
                        break;
                default:
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Protocol version[%d] \n",mgCfg->protocol_version);
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Protocol version[%d] \n",profile->protocol_version);
                        return SWITCH_STATUS_FALSE;
        }
 
@@ -940,17 +921,17 @@ int mgco_mg_ssap_config(int idx)
        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);
+       pCfg->userInfo.mid.len = (U8)strlen((char*)profile->mid);
+       strncpy((char*)pCfg->userInfo.mid.val, (char*)profile->mid, MAX_MID_LEN);
 
-       len = (U32)strlen((char*)mgCfg->my_domain);
+       len = (U32)strlen((char*)profile->my_domain);
        memcpy( (U8*)(pCfg->userInfo.dname.name),
-                       (CONSTANT U8*)(mgCfg->my_domain), len );
+                       (CONSTANT U8*)(profile->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))
+       if(ROK == cmInetAddr((S8*)profile->my_ipaddr,&ipAddr))
        {
                pCfg->userInfo.dname.netAddr.u.ipv4NetAddr = ntohl(ipAddr);
        }
@@ -968,13 +949,11 @@ int mgco_mg_ssap_config(int idx)
 
 /******************************************************************************/
 
-int mgco_mg_tsap_config(int idx)
+int mgco_mg_tsap_config(megaco_profile_t* profile)
 {
        MgMngmt    mgMngmt;
-       /* local variables */
        MgTSAPCfg    *cfg;
-       Pst          pst;              /* Post for layer manager */
-       sng_mg_cfg_t* mgCfg  = &megaco_globals.g_mg_cfg.mgCfg[idx];
+       Pst          pst; 
 
        memset(&mgMngmt, 0, sizeof(mgMngmt));
        cfg   = &(mgMngmt.t.cfg.c.tSAPCfg);
@@ -992,9 +971,9 @@ int mgco_mg_tsap_config(int idx)
        mgMngmt.hdr.elmId.elmnt     = STTSAP;
 
        /* FILL TSAP config */
-       cfg->tSAPId     = mgCfg->id;
-       cfg->spId       = GET_TPT_ID(idx);
-       cfg->provType   = GET_TPT_TYPE(idx);
+       cfg->tSAPId     = profile->idx;
+       cfg->spId       = profile->idx;
+       cfg->provType   = mg_get_tpt_type(profile);
 
        /* FILL TUCL Information */
        cfg->memId.region = S_REG; 
@@ -1031,15 +1010,14 @@ int mgco_mg_tsap_config(int idx)
 
 /******************************************************************************/
 
-int mgco_mg_peer_config(int idx)
+int mgco_mg_peer_config(megaco_profile_t* mg_cfg)
 {
        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];
+       mg_peer_profile_t*  mg_peer = megaco_peer_profile_locate(mg_cfg->peer_list[0]);
 
        memset(&mgMngmt, 0, sizeof(mgMngmt));
        cfg   = &(mgMngmt.t.cfg.c.mgGcpEntCfg);
@@ -1056,10 +1034,10 @@ int mgco_mg_peer_config(int idx)
        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->numPeer                    = mg_cfg->total_peers;
+       cfg->peerCfg[peerIdx].sSAPId    = mg_cfg->idx;        /* SSAP ID */;
+       cfg->peerCfg[peerIdx].port      = atoi(mg_peer->port);
+       cfg->peerCfg[peerIdx].tsapId    = mg_cfg->idx;
 
        cfg->peerCfg[peerIdx].mtuSize = MG_MAX_MTU_SIZE;
 
@@ -1068,7 +1046,7 @@ int mgco_mg_peer_config(int idx)
        cfg->peerCfg[peerIdx].peerAddrTbl.netAddr[0].type =
                CM_NETADDR_IPV4;
 
-       if(ROK == cmInetAddr((S8*)&mgPeer->ipaddr[0],&ipAddr))
+       if(ROK == cmInetAddr((S8*)&mg_peer->ipaddr[0],&ipAddr))
        {
                cfg->peerCfg[peerIdx].peerAddrTbl.netAddr[0].u.ipv4NetAddr = ntohl(ipAddr);
        }
@@ -1079,14 +1057,14 @@ int mgco_mg_peer_config(int idx)
        }
 
 #ifdef GCP_MG
-       cfg->peerCfg[peerIdx].transportType  = GET_TPT_TYPE(idx);
-       cfg->peerCfg[peerIdx].encodingScheme = GET_ENCODING_TYPE(idx); 
+       cfg->peerCfg[peerIdx].transportType  = mg_get_tpt_type_from_str(mg_peer->transport_type);
+       cfg->peerCfg[peerIdx].encodingScheme = mg_get_enc_type_from_str(mg_peer->encoding_type);
        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);
+       cfg->peerCfg[peerIdx].mid.len = strlen((char*)mg_peer->mid);
        cmMemcpy((U8 *)cfg->peerCfg[peerIdx].mid.val, 
-               (CONSTANT U8*)(char*)mgPeer->mid, 
+               (CONSTANT U8*)(char*)mg_peer->mid, 
                 cfg->peerCfg[peerIdx].mid.len);
 
 #endif /* GCP_MG */
@@ -1096,14 +1074,14 @@ int mgco_mg_peer_config(int idx)
 
 /******************************************************************************/
 
-int mgco_mg_tpt_server_config(int idx)
+int mgco_mg_tpt_server_config(megaco_profile_t* mg_cfg)
 {
        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;
+       mg_peer_profile_t*  mg_peer = megaco_peer_profile_locate(mg_cfg->peer_list[0]);
 
        memset(&mgMngmt, 0, sizeof(mgMngmt));
        cfg   = &(mgMngmt.t.cfg.c.tptSrvrCfg);
@@ -1122,18 +1100,18 @@ int mgco_mg_tpt_server_config(int idx)
 
        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].sSAPId = mg_cfg->idx;
+       cfg->srvr[srvIdx].tSAPId = mg_cfg->idx; 
+       cfg->srvr[srvIdx].protocol = mg_get_proto_type_from_str(mg_cfg->protocol_type);
+       cfg->srvr[srvIdx].transportType = mg_get_tpt_type(mg_cfg); 
+       cfg->srvr[srvIdx].encodingScheme = mg_get_enc_type_from_str(mg_peer->encoding_type);
 
        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.port = atoi(mg_cfg->port);
+       if(ROK == cmInetAddr((S8*)mg_cfg->my_ipaddr, &ipAddr))
        {
                cfg->srvr[srvIdx].lclTptAddr.u.ipv4TptAddr.address = ntohl(ipAddr);
        }
@@ -1677,12 +1655,10 @@ void handle_tucl_alarm(Pst *pst, HiMngmt *sta)
 }   /* handle_sng_tucl_alarm */
 /******************************************************************************/
 
-int sng_mgco_mg_get_status(int elemId, MgMngmt* cfm, int mg_cfg_idx)
+int sng_mgco_mg_get_status(int elemId, MgMngmt* cfm,  megaco_profile_t* mg_cfg, mg_peer_profile_t* mg_peer)
 {
        Pst pst;
        MgMngmt cntrl;
-       sng_mg_cfg_t*  mgCfg  = &megaco_globals.g_mg_cfg.mgCfg[mg_cfg_idx];
-       sng_mg_peer_t*  mgPeer = &megaco_globals.g_mg_cfg.mgPeer.peers[mgCfg->peer_id];
        CmInetIpAddr   ipAddr = 0;
 
        memset((U8 *)&pst, 0, sizeof(Pst));
@@ -1709,30 +1685,30 @@ int sng_mgco_mg_get_status(int elemId, MgMngmt* cfm, int mg_cfg_idx)
                case STGCPENT:
                        {
                                cntrl.t.ssta.s.mgPeerSta.peerId.pres = PRSNT_NODEF;
-                               cntrl.t.ssta.s.mgPeerSta.peerId.val = mgCfg->peer_id;
+                               cntrl.t.ssta.s.mgPeerSta.peerId.val  = mg_cfg->idx;
 
                                cntrl.t.ssta.s.mgPeerSta.mid.pres = PRSNT_NODEF;
-                               cntrl.t.ssta.s.mgPeerSta.mid.len  = strlen((char*)mgPeer->mid);
+                               cntrl.t.ssta.s.mgPeerSta.mid.len  = strlen((char*)mg_peer->mid);
                                cmMemcpy((U8 *)cntrl.t.ssta.s.mgPeerSta.mid.val, 
-                                               (CONSTANT U8*)(char*)mgPeer->mid, 
+                                               (CONSTANT U8*)(char*)mg_peer->mid, 
                                                cntrl.t.ssta.s.mgPeerSta.mid.len);      
                                break;
                        }
                case STSSAP:
                        {
-                               cntrl.t.ssta.s.mgSSAPSta.sapId = mgCfg->id
+                               cntrl.t.ssta.s.mgSSAPSta.sapId = mg_cfg->idx
                                break;
                        }
                case STTSAP:
                        {
-                               cntrl.t.ssta.s.mgTSAPSta.tSapId = GET_TPT_ID(mg_cfg_idx);
+                               cntrl.t.ssta.s.mgTSAPSta.tSapId = mg_cfg->idx;
                                break;
                        }
                case STSERVER:
                        {
                                cntrl.t.ssta.s.mgTptSrvSta.tptAddr.type =  CM_INET_IPV4ADDR_TYPE;
                                cntrl.t.ssta.s.mgTptSrvSta.tptAddr.u.ipv4TptAddr.port = ntohl(ipAddr);
-                               if(ROK == cmInetAddr((S8*)mgCfg->my_ipaddr, &ipAddr))
+                               if(ROK == cmInetAddr((S8*)mg_cfg->my_ipaddr, &ipAddr))
                                {
                                        cntrl.t.ssta.s.mgTptSrvSta.tptAddr.u.ipv4TptAddr.address = ntohl(ipAddr);
                                }
@@ -1753,19 +1729,27 @@ switch_status_t megaco_profile_status(switch_stream_handle_t *stream, const char
        int len   = 0x00;
        MgMngmt   cfm;
        char      prntBuf[1024];
+       megaco_profile_t*   mg_cfg  = NULL; 
+       mg_peer_profile_t*  mg_peer = NULL;
 
        switch_assert(profilename);
 
        memset((U8 *)&cfm, 0, sizeof(cfm));
        memset((char *)&prntBuf, 0, sizeof(prntBuf));
 
-       GET_MG_CFG_IDX(profilename, idx);
-
-       if(!idx || (idx == MAX_MG_PROFILES)){
+       mg_cfg  = megaco_profile_locate(profilename);
+       if(!mg_cfg){
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR," No MG configuration found against profilename[%s]\n",profilename);
                return SWITCH_STATUS_FALSE;
        }
+       mg_peer = megaco_peer_profile_locate(mg_cfg->peer_list[0]);
+
+       if(!mg_peer){
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR," No MG peer configuration found for peername[%s] against profilename[%s]\n",mg_cfg->peer_list[0],profilename);
+               return SWITCH_STATUS_FALSE;
+       }
 
+       idx = mg_cfg->idx;
 
        /*stream->write_function(stream, "Collecting MG Profile[%s] status... \n",profilename);*/
 
@@ -1791,15 +1775,15 @@ switch_status_t megaco_profile_status(switch_stream_handle_t *stream, const char
 #endif
 
        /* MG Peer Information */
-       sng_mgco_mg_get_status(STGCPENT, &cfm, idx);
+       sng_mgco_mg_get_status(STGCPENT, &cfm, mg_cfg, mg_peer);
        smmgPrntPeerSta(&cfm.t.ssta.s.mgPeerSta);
 
        /* MG Peer Information */
-       sng_mgco_mg_get_status(STSSAP, &cfm, idx);
+       sng_mgco_mg_get_status(STSSAP, &cfm, mg_cfg, mg_peer);
        smmgPrntSsapSta(&cfm.t.ssta.s.mgSSAPSta);
 
        /* MG Transport SAP Information */
-       sng_mgco_mg_get_status(STTSAP, &cfm, idx);
+       sng_mgco_mg_get_status(STTSAP, &cfm, mg_cfg, mg_peer);
        len = len + sprintf(prntBuf+len,"***********************************************\n"); 
        len = len + sprintf(prntBuf+len,"**********MG TRANSPORT SAP Information**********\n");
        len = len + sprintf(prntBuf+len,"TSAP status:\n");
@@ -1810,7 +1794,7 @@ switch_status_t megaco_profile_status(switch_stream_handle_t *stream, const char
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,"%s\n",prntBuf); 
 
        /* MG Transport Server Information */
-       sng_mgco_mg_get_status(STSERVER, &cfm, idx);
+       sng_mgco_mg_get_status(STSERVER, &cfm, mg_cfg, mg_peer);
        smmgPrntSrvSta(&cfm.t.ssta.s.mgTptSrvSta);
 
        return SWITCH_STATUS_SUCCESS;
@@ -1822,33 +1806,37 @@ switch_status_t megaco_profile_xmlstatus(switch_stream_handle_t *stream, const c
        int len   = 0x00;
        MgMngmt   cfm;
        char*     xmlhdr = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
-       char      prntBuf[10024];
-       sng_mg_cfg_t*  mgCfg  = NULL; 
-       sng_mg_peer_t*  mgPeer = NULL; 
+       char      prntBuf[3048];
        int i = 0x00;
        char *asciiAddr;
        CmInetIpAddr ip;
+       megaco_profile_t*   mg_cfg  = NULL; 
+       mg_peer_profile_t*  mg_peer = NULL;
 
        switch_assert(profilename);
 
        memset((U8 *)&cfm, 0, sizeof(cfm));
        memset((char *)&prntBuf, 0, sizeof(prntBuf));
 
-       GET_MG_CFG_IDX(profilename, idx);
-
-       if(!idx || (idx == MAX_MG_PROFILES)){
+       mg_cfg  = megaco_profile_locate(profilename);
+       if(!mg_cfg){
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR," No MG configuration found against profilename[%s]\n",profilename);
                return SWITCH_STATUS_FALSE;
        }
+        mg_peer = megaco_peer_profile_locate(mg_cfg->peer_list[0]);
+
+       if(!mg_peer){
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR," No MG peer configuration found for peername[%s] against profilename[%s]\n",mg_cfg->peer_list[0],profilename);
+               return SWITCH_STATUS_FALSE;
+       }
 
-       mgCfg  = &megaco_globals.g_mg_cfg.mgCfg[idx];
-       mgPeer = &megaco_globals.g_mg_cfg.mgPeer.peers[mgCfg->peer_id];
 
+       idx = mg_cfg->idx;
 
        len = len + sprintf(&prntBuf[0] + len,"%s\n",xmlhdr);
 
        len = len + sprintf(&prntBuf[0] + len,"<mg_profile>\n");
-       len = len + sprintf(&prntBuf[0] + len,"<name>%s</name>\n",mgCfg->name);
+       len = len + sprintf(&prntBuf[0] + len,"<name>%s</name>\n",mg_cfg->name);
        len = len + sprintf(&prntBuf[0] + len,"<profile>%s</profile>\n",profilename);
 /****************************************************************************************************************/
 /* Print Peer Information ***************************************************************************************/
@@ -1856,10 +1844,10 @@ switch_status_t megaco_profile_xmlstatus(switch_stream_handle_t *stream, const c
        /* TODO - as of now supporting only one peer .. need to add logic to iterate through all the peers associated with this profile..*/
 
        len = len + sprintf(&prntBuf[0] + len,"<mg_peers>\n");
-       len = len + sprintf(&prntBuf[0] + len,"<mg_peer name=%s>\n",mgPeer->name);
+       len = len + sprintf(&prntBuf[0] + len,"<mg_peer name=%s>\n",mg_peer->name);
 
        /* send request to MEGACO Trillium stack to get peer information*/
-       sng_mgco_mg_get_status(STGCPENT, &cfm, idx);
+       sng_mgco_mg_get_status(STGCPENT, &cfm, mg_cfg, mg_peer);
 
        get_peer_xml_buffer(&prntBuf[0] + len, &cfm.t.ssta.s.mgPeerSta);
 
@@ -1873,7 +1861,7 @@ switch_status_t megaco_profile_xmlstatus(switch_stream_handle_t *stream, const c
        len = len + sprintf(&prntBuf[0] + len,"<mg_sap>\n");
 
        /* MG SAP Information */
-       sng_mgco_mg_get_status(STSSAP, &cfm, idx);
+       sng_mgco_mg_get_status(STSSAP, &cfm, mg_cfg, mg_peer);
 
        len = len + sprintf(prntBuf+len, "<state> %s </state>\n", PRNT_SAP_STATE((int)(cfm.t.ssta.s.mgSSAPSta.state)));
        len = len + sprintf(prntBuf+len, "<num_of_peer> %u </num_of_peer>\n", (unsigned int)(cfm.t.ssta.s.mgSSAPSta.numAssocPeer));
@@ -1917,7 +1905,7 @@ switch_status_t megaco_profile_xmlstatus(switch_stream_handle_t *stream, const c
 
        len = len + sprintf(&prntBuf[0] + len,"<mg_transport_sap>\n");
        /* MG Transport SAP Information */
-       sng_mgco_mg_get_status(STTSAP, &cfm, idx);
+       sng_mgco_mg_get_status(STTSAP, &cfm, mg_cfg, mg_peer);
        len = len + sprintf(&prntBuf[0] + len,"<state> %s </state>\n", PRNT_SAP_STATE(cfm.t.ssta.s.mgTSAPSta.state));
        len = len + sprintf(&prntBuf[0] + len,"<num_of_listeners> %u </num_of_listeners>\n", (unsigned int)(cfm.t.ssta.s.mgTSAPSta.numServers)); 
        len = len + sprintf(&prntBuf[0] + len,"</mg_transport_sap>\n");
@@ -1925,7 +1913,7 @@ switch_status_t megaco_profile_xmlstatus(switch_stream_handle_t *stream, const c
 /****************************************************************************************************************/
 /* Print MG Transport Server Information ***************************************************************************************/
 
-       if(sng_mgco_mg_get_status(STSERVER, &cfm, idx)){
+       if(sng_mgco_mg_get_status(STSERVER, &cfm, mg_cfg, mg_peer)){
                len = len + sprintf(&prntBuf[0] + len,"<mg_transport_server> no established server found </mg_transport_server>\n");
        }
        else {
@@ -2096,3 +2084,84 @@ void get_peer_xml_buffer(char* prntBuf, MgPeerSta* cfm)
 #endif
 
 } 
+/**********************************************************************************************************************************/
+sng_mg_transport_types_e mg_get_tpt_type(megaco_profile_t* mg_profile)
+{
+       mg_peer_profile_t*      mg_peer_profile = NULL; 
+
+       if(NULL == mg_profile){
+               return SNG_MG_TPT_NONE;
+       }
+
+       if(!mg_profile->total_peers){
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " No peer configured against profilename[%s]\n",mg_profile->name);
+               return SNG_MG_TPT_NONE;
+       }
+
+       if( NULL == (mg_peer_profile = megaco_peer_profile_locate(mg_profile->peer_list[0]))){
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " Not able to get peer_profile node based on profilename[%s]\n",mg_profile->peer_list[0]);
+               return SNG_MG_TPT_NONE;
+       }
+
+       return mg_get_tpt_type_from_str(mg_peer_profile->transport_type);
+}
+/**********************************************************************************************************************************/
+
+sng_mg_transport_types_e  mg_get_tpt_type_from_str(char* tpt_type)
+{
+       if(!tpt_type) return SNG_MG_TPT_NONE;
+
+       if(!strcasecmp(tpt_type, "UDP")){
+               return SNG_MG_TPT_UDP;
+       }else if(!strcasecmp(tpt_type,"TCP")){
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "TCP Transport for H.248 Protocol Not Yet Supported \n");
+               return SNG_MG_TPT_TCP;
+       }else if(!strcasecmp(tpt_type,"STCP")){
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STCP Transport for H.248 Protocol Not Yet Supported \n");
+               return SNG_MG_TPT_SCTP;
+       }else{
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Protocol Value[%s] \n",tpt_type);
+               return SNG_MG_TPT_NONE;
+       }
+
+       return SNG_MG_TPT_NONE;
+}
+/**********************************************************************************************************************************/
+
+sng_mg_encoding_types_e  mg_get_enc_type_from_str(char* enc_type)
+{
+       if(!enc_type) return SNG_MG_ENCODING_NONE;
+
+       if(!strcasecmp(enc_type, "TEXT")){
+               return SNG_MG_ENCODING_TEXT;
+       } else if(!strcasecmp(enc_type, "BINARY")){
+               return SNG_MG_ENCODING_BINARY;
+       } else {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Encoding Type[%s] \n", enc_type);
+               return SNG_MG_ENCODING_NONE;
+       }
+
+       return SNG_MG_ENCODING_NONE;
+}
+
+/**********************************************************************************************************************************/
+
+sng_mg_protocol_types_e  mg_get_proto_type_from_str(char* proto_type)
+{
+       if(!proto_type) return SNG_MG_NONE;
+
+       if(!strcasecmp(proto_type,"MEGACO")) {
+               return SNG_MG_MEGACO;
+       }else if(!strcasecmp(proto_type,"MGCP")){
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MGCP Protocol Not Yet Supported \n");
+               return SNG_MG_MGCP;
+       }else{
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Protocol Value[%s] \n",proto_type);
+               return SNG_MG_NONE;
+       }
+
+       return SNG_MG_NONE;
+}
+
+
+/**********************************************************************************************************************************/
index 8e1bc12bc1417eef62d924ff3bebc2bbc9c86ef4..dabf4a5551b5e41815b9df76f62187c0e947149a 100644 (file)
@@ -6,7 +6,7 @@
 * <Insert license here>
 */
 
-#include "sng_megaco/sng_ss7.h"
+#include "mod_megaco.h"
 
 #ifndef _MEGACO_CFG_H_
 #define _MEGACO_CFG_H_
@@ -16,6 +16,7 @@
 #define MAX_NAME_LEN    25
 #define MAX_MG_PROFILES 5
 
+#if 0
 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 */
@@ -36,6 +37,7 @@ typedef struct sng_mg_transport_profile{
         uint16_t      transport_type;                /* transport type */
 }sng_mg_transport_profile_t;
 
+#endif
 
 typedef enum{
         SNG_MG_TPT_NONE,
@@ -68,6 +70,7 @@ typedef enum{
         "SNG_MG_ENCODING_NONE")
 
 
+#if 0
 /* 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 */
@@ -94,6 +97,7 @@ typedef struct sng_mg_gbl_cfg{
 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);
+#endif
 
 
 void handle_sng_log(uint8_t level, char *fmt, ...);
@@ -107,17 +111,16 @@ void handle_mg_alarm(Pst *pst, MgMngmt *sta);
 void handle_tucl_alarm(Pst *pst, HiMngmt *sta);
 
 
+switch_status_t sng_mgco_cfg(megaco_profile_t* profile);
 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_stop(const char* profilename);
 switch_status_t sng_mgco_stack_shutdown(void);
-int sng_mgco_mg_get_status(int elemId, MgMngmt* cfm, int mg_cfg_idx);
+int sng_mgco_mg_get_status(int elemId, MgMngmt* cfm, megaco_profile_t* mg_cfg, mg_peer_profile_t* mg_peer);
 switch_status_t megaco_profile_status(switch_stream_handle_t *stream, const char* profilename);
 switch_status_t megaco_profile_xmlstatus(switch_stream_handle_t *stream, const char* profilename);
 
 /*****************************************************************************************************/
 
+#if 0
 #define GET_MG_CFG_IDX(_profilename, _idx){\
        for(idx=0; idx < MAX_MG_PROFILES; idx++){\
                /* id zero is not acceptable */\
@@ -130,12 +133,12 @@ switch_status_t megaco_profile_xmlstatus(switch_stream_handle_t *stream, const c
                }\
        }\
 }
-
 #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
 
 #endif /* _MEGACO_CFG_H_ */
index 23ff23468d9a93f4a5210d70abef2dc5c9d3ec99..52b1294cb2a689ddd87523856f81facf847abceb 100644 (file)
@@ -6,8 +6,167 @@
 * <Insert license here>
 */
 #include "mod_megaco.h"
+#include "megaco_stack.h"
 
+/****************************************************************************************************************************/
+static switch_xml_config_item_t *get_instructions(megaco_profile_t *profile) ;
+static switch_xml_config_item_t *get_peer_instructions(mg_peer_profile_t *profile) ;
+static int mg_sap_id;
 
+/****************************************************************************************************************************/
+switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload)
+{
+       switch_xml_t cfg, xml, param, mg_interfaces, mg_interface, mg_peers, mg_peer, peer_interfaces ;
+       switch_status_t status = SWITCH_STATUS_FALSE;
+       switch_event_t *event = NULL;
+       const char *file = "megaco.conf";
+       switch_xml_config_item_t *instructions = (profile ? get_instructions(profile) : NULL);
+       int count;
+       int idx;
+       char *var, *val;
+       mg_peer_profile_t* peer_profile = NULL;
+       switch_xml_config_item_t *instructions1 = 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 (!(mg_interfaces = switch_xml_child(cfg, "mg_profiles"))) {
+               goto done;
+       }
+
+       for (mg_interface = switch_xml_child(mg_interfaces, "mg_profile"); mg_interface; mg_interface = mg_interface->next) {
+               const char *name = switch_xml_attr_soft(mg_interface, "name");
+               if (strcmp(name, profile->name)) {
+                       continue;
+               }
+
+               count = switch_event_import_xml(switch_xml_child(mg_interface, "param"), "name", "value", &event);
+               status = switch_xml_config_parse_event(event, count, reload, instructions);
+
+               /* now build peer list */
+               if (!(peer_interfaces = switch_xml_child(mg_interface, "peers"))) {
+                       goto done;
+               }
+
+               for (param = switch_xml_child(peer_interfaces, "param"); param; param = param->next) {
+                       var = (char *) switch_xml_attr_soft(param, "name");
+                       val = (char *) switch_xml_attr_soft(param, "value");
+                       profile->peer_list[profile->total_peers] = switch_core_strdup(profile->pool, val);
+                       profile->total_peers++;
+               }
+
+               profile->idx = ++mg_sap_id;
+
+               /* we should break from here , profile name should be unique */
+               break;
+       }
+
+       /* go through the peer configuration and get the mg profile associated peers only */
+       if (!(mg_peers = switch_xml_child(cfg, "mg_peers"))) {
+               goto done;
+       }
+
+       count = 0x00;
+       event = NULL;
+       for (mg_peer = switch_xml_child(mg_peers, "mg_peer"); mg_peer; mg_peer = mg_peer->next) {
+               const char *name = switch_xml_attr_soft(mg_peer, "name");
+               for(idx=0; idx<profile->total_peers; idx++){
+                       if (!strcmp(name, profile->peer_list[idx])) {
+                               /* peer profile */
+                               peer_profile = switch_core_alloc(profile->pool, sizeof(*peer_profile));
+                               peer_profile->pool = profile->pool;
+                               peer_profile->name = switch_core_strdup(peer_profile->pool, name);
+                               switch_thread_rwlock_create(&peer_profile->rwlock, peer_profile->pool);
+                               instructions1 = (peer_profile ? get_peer_instructions(peer_profile) : NULL);
+
+                               count = switch_event_import_xml(switch_xml_child(mg_peer, "param"), "name", "value", &event);
+                               if(SWITCH_STATUS_FALSE == (status = switch_xml_config_parse_event(event, count, reload, instructions1))){
+                                    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " Peer XML Parsing failed \n");
+                                       goto done;
+                               }
+
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,"peer_profile name[%s], ipaddr[%s] port[%s], mid[%s] transport_type[%s], encoding_type[%s] \n",
+                                               peer_profile->name, peer_profile->ipaddr, peer_profile->port,peer_profile->mid, peer_profile->transport_type, peer_profile->encoding_type);
+
+                               switch_core_hash_insert_wrlock(megaco_globals.peer_profile_hash, peer_profile->name, peer_profile, megaco_globals.peer_profile_rwlock);
+                       }
+               }
+       }
+
+       /* configure the MEGACO stack */
+       status = sng_mgco_cfg(profile);
+
+done:
+       if (xml) {
+               switch_xml_free(xml);   
+       }
+
+       if (event) {
+               switch_event_destroy(&event);
+       }
+       return status;
+}
+
+/****************************************************************************************************************************/
+switch_status_t mg_config_cleanup(megaco_profile_t* profile)
+{
+       switch_xml_config_item_t *instructions = (profile ? get_instructions(profile) : NULL);
+       switch_xml_config_cleanup(instructions);
+
+       return SWITCH_STATUS_SUCCESS;
+}
+
+/****************************************************************************************************************************/
+static switch_xml_config_item_t *get_peer_instructions(mg_peer_profile_t *profile) {
+       switch_xml_config_item_t *dup;
+
+       switch_xml_config_item_t instructions[] = {
+               /* parameter name        type                 reloadable   pointer                         default value     options structure */
+               SWITCH_CONFIG_ITEM("ip", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->ipaddr, "", &switch_config_string_strdup, "", "Peer IP"),
+               SWITCH_CONFIG_ITEM("port", SWITCH_CONFIG_STRING, 0, &profile->port, "", &switch_config_string_strdup, "", "peer port"),
+               SWITCH_CONFIG_ITEM("encoding-scheme", SWITCH_CONFIG_STRING, 0, &profile->encoding_type, "TEXT", &switch_config_string_strdup, "", "peer encoding type"),
+               SWITCH_CONFIG_ITEM("transport-type", SWITCH_CONFIG_STRING, 0, &profile->transport_type, "", &switch_config_string_strdup, "", "peer transport type "),
+               SWITCH_CONFIG_ITEM("message-identifier", SWITCH_CONFIG_STRING, 0, &profile->mid, "", &switch_config_string_strdup, "", "peer message identifier "),
+               SWITCH_CONFIG_ITEM_END()
+       };
+       
+       dup = malloc(sizeof(instructions));
+       memcpy(dup, instructions, sizeof(instructions));
+       return dup;
+}
+
+/****************************************************************************************************************************/
+
+static switch_xml_config_item_t *get_instructions(megaco_profile_t *profile) {
+       switch_xml_config_item_t *dup;
+       static switch_xml_config_int_options_t opt_version = { 
+               SWITCH_TRUE,  /* enforce min */
+               1,
+               SWITCH_TRUE, /* Enforce Max */
+               3
+       };
+
+       switch_xml_config_item_t instructions[] = {
+               /* parameter name        type                 reloadable   pointer                         default value     options structure */
+               SWITCH_CONFIG_ITEM("protocol", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->protocol_type, "MEGACO", &switch_config_string_strdup, "", "MG Protocol type"),
+               SWITCH_CONFIG_ITEM("version", SWITCH_CONFIG_INT, CONFIG_RELOADABLE, &profile->protocol_version, 2, &opt_version, "", "MG Protocol version"),
+               SWITCH_CONFIG_ITEM("local-ip", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->my_ipaddr, "127.0.0.1", &switch_config_string_strdup, "", "local ip"),
+               SWITCH_CONFIG_ITEM("port", SWITCH_CONFIG_STRING, 0, &profile->port, "2944", &switch_config_string_strdup, "", "port"),
+               SWITCH_CONFIG_ITEM("domain-name", SWITCH_CONFIG_STRING, 0, &profile->my_domain, "", &switch_config_string_strdup, "", "domain name"),
+               SWITCH_CONFIG_ITEM("message-identifier", SWITCH_CONFIG_STRING, 0, &profile->mid, "", &switch_config_string_strdup, "", "message identifier "),
+               SWITCH_CONFIG_ITEM_END()
+       };
+       
+       dup = malloc(sizeof(instructions));
+       memcpy(dup, instructions, sizeof(instructions));
+       return dup;
+}
+
+/****************************************************************************************************************************/
+
+#if 0
 switch_status_t sng_parse_mg_profile(switch_xml_t mg_interface)
 {
        int i = 0x00;
@@ -230,4 +389,5 @@ 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;
 }
+#endif
 /***********************************************************************************************************/
index f8fa65a8ee743b9cf95efa283f53c4e785d80359..94a0f64d1321d291bcba23493a596ccb0aee0758 100644 (file)
@@ -7,6 +7,7 @@
 */
 
 #include "mod_megaco.h"
+#include "megaco_stack.h"
 
 struct megaco_globals megaco_globals;
 static sng_isup_event_interface_t sng_event;
@@ -15,7 +16,6 @@ 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] [status] [xmlstatus]"
 SWITCH_STANDARD_API(megaco_function)
 {
@@ -34,11 +34,14 @@ SWITCH_STANDARD_API(megaco_function)
                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);
@@ -47,7 +50,9 @@ SWITCH_STANDARD_API(megaco_function)
                                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);
@@ -56,22 +61,29 @@ SWITCH_STANDARD_API(megaco_function)
                        } else {
                                stream->write_function(stream, "-ERR No such profile\n");
                        }
+/**********************************************************************************/
                }else if(!strcmp(argv[2], "status")) {
+/**********************************************************************************/
                        megaco_profile_t *profile = megaco_profile_locate(argv[1]);
                        if (profile) {
                                megaco_profile_status(stream, profile->name);
                        } else {
                                stream->write_function(stream, "-ERR No such profile\n");
                        }
+/**********************************************************************************/
                }else if(!strcmp(argv[2], "xmlstatus")) {
+/**********************************************************************************/
                        megaco_profile_t *profile = megaco_profile_locate(argv[1]);
                        if (profile) {
                                megaco_profile_xmlstatus(stream, profile->name);
                        } else {
                                stream->write_function(stream, "-ERR No such profile\n");
                        }
+/**********************************************************************************/
+               }else {
+/**********************************************************************************/
+                       goto usage;
                }
-
        }
        
        goto done;
@@ -125,6 +137,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_megaco_load)
                
        switch_core_hash_init(&megaco_globals.profile_hash, pool);
        switch_thread_rwlock_create(&megaco_globals.profile_rwlock, pool);
+
+       switch_core_hash_init(&megaco_globals.peer_profile_hash, pool);
+       switch_thread_rwlock_create(&megaco_globals.peer_profile_rwlock, pool);
        
        SWITCH_ADD_API(api_interface, "megaco", "megaco", megaco_function, MEGACO_FUNCTION_SYNTAX);
        
index 7c216106392594eb7f51f32a96368ba31dd7e4fe..a277a1f840f03afc42c4ca017b188ed2e8e42281 100644 (file)
 #ifndef MOD_MEGACO_H
 #define MOD_MEGACO_H
 
+#include "sng_megaco/sng_ss7.h"
 #include <switch.h>
-#include "megaco_stack.h"
+
+#define MG_MAX_PEERS    5
 
 struct megaco_globals {
        switch_memory_pool_t            *pool;
        switch_hash_t                   *profile_hash;
+       switch_hash_t                   *peer_profile_hash;
        switch_thread_rwlock_t          *profile_rwlock;
-       sng_mg_gbl_cfg_t                 g_mg_cfg;
+       switch_thread_rwlock_t          *peer_profile_rwlock;
 };
 extern struct megaco_globals megaco_globals; /* < defined in mod_megaco.c */
 
@@ -25,19 +28,46 @@ typedef enum {
        PF_RUNNING = (1 << 0)
 } megaco_profile_flags_t;
 
+typedef struct mg_peer_profile_s{
+       char                            *name;
+       switch_memory_pool_t            *pool;
+       switch_thread_rwlock_t          *rwlock; /* < Reference counting rwlock */
+       megaco_profile_flags_t          flags;
+       char*                           ipaddr;      /* Peer IP  */
+       char*                           port;        /*Peer Port */
+       char*                           mid;         /* Peer H.248 MID */
+       char*                           transport_type; /* UDP/TCP */ 
+       char*                           encoding_type; /* Encoding TEXT/Binary */
+}mg_peer_profile_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;
+       int                             idx;         /* Trillium MEGACO SAP identification*/
+       char*                           mid;         /* MG H.248 MID */
+       char*                           my_domain;   /* local domain name */
+       char*                           my_ipaddr;   /* local domain name */
+       char*                           port;                        /* port */
+       char*                           protocol_type;               /* MEGACO/MGCP */
+       int                             protocol_version;            /* Protocol supported version */
+       int                             total_peers;            
+       char*                           peer_list[MG_MAX_PEERS];     /* MGC Peer ID LIST */
 } megaco_profile_t;
 
 
 megaco_profile_t *megaco_profile_locate(const char *name);
+mg_peer_profile_t *megaco_peer_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);
+switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload);
+switch_status_t sng_mgco_start(megaco_profile_t* profile);
+switch_status_t sng_mgco_stop(megaco_profile_t* profile);
+switch_status_t mg_config_cleanup(megaco_profile_t* profile);
 
 
 #endif /* MOD_MEGACO_H */