提交 d535563a authored 作者: kapil's avatar kapil

modifying XML parsing / configuration code

上级 67373e78
......@@ -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;
......
......@@ -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_ */
......@@ -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
/***********************************************************************************************************/
......@@ -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);
......
......@@ -10,14 +10,17 @@
#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 */
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论