From bc4c2d9fab831f19086f1958149ce7c53eb22fa2 Mon Sep 17 00:00:00 2001 From: Mathieu Rene Date: Wed, 25 Jul 2012 15:10:47 -0400 Subject: [PATCH] map physical terms --- .../mod_media_gateway/media_gateway.c | 34 ++++------- .../mod_media_gateway/media_gateway_xml.c | 60 ++++++++++++++++++- .../mod_media_gateway/mod_media_gateway.h | 9 ++- 3 files changed, 78 insertions(+), 25 deletions(-) diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway.c b/src/mod/endpoints/mod_media_gateway/media_gateway.c index 5d58674a0c..7670478644 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway.c +++ b/src/mod/endpoints/mod_media_gateway/media_gateway.c @@ -158,8 +158,8 @@ mg_termination_t *megaco_choose_termination(megaco_profile_t *profile, const cha term_id = mg_rtp_request_id(profile); switch_snprintf(name, sizeof name, "%s/%d", profile->rtp_termination_id_prefix, term_id); } else { - /* TODO Math: look through TDM channels */ - return NULL; + + return term; } switch_core_new_memory_pool(&pool); @@ -176,8 +176,6 @@ mg_termination_t *megaco_choose_termination(megaco_profile_t *profile, const cha term->u.rtp.codec = megaco_codec_str(profile->default_codec); term->u.rtp.term_id = term_id; term->name = switch_core_strdup(term->pool, name); - } else if (termtype == MG_TERM_TDM) { - /* XXX initialize tdm-specific fields */ } switch_core_hash_insert_wrlock(profile->terminations, term->name, term, profile->terminations_rwlock); @@ -214,8 +212,10 @@ void megaco_termination_destroy(mg_termination_t *term) term->active_events = NULL; } - switch_core_hash_delete_wrlock(term->profile->terminations, term->name, term->profile->terminations_rwlock); - switch_core_destroy_memory_pool(&term->pool); + if (term->type == MG_TERM_RTP) { + switch_core_hash_delete_wrlock(term->profile->terminations, term->name, term->profile->terminations_rwlock); + switch_core_destroy_memory_pool(&term->pool); + } } switch_status_t megaco_context_is_term_present(mg_context_t *ctx, mg_termination_t *term) @@ -276,10 +276,11 @@ switch_status_t megaco_context_sub_all_termination(mg_context_t *ctx) /* Channels will automatically go to park once the bridge ends */ if (ctx->terminations[0]) { - megaco_termination_destroy(ctx->terminations[0]); - ctx->terminations[0] = NULL; - } else if (ctx->terminations[1]) { - megaco_termination_destroy(ctx->terminations[1]); + megaco_context_sub_termination(ctx, ctx->terminations[0]); + } + + if (ctx->terminations[1]) { + megaco_context_sub_termination(ctx, ctx->terminations[1]); } return SWITCH_STATUS_SUCCESS; @@ -316,11 +317,6 @@ mg_context_t *megaco_find_context_by_suid(SuId suId, uint32_t context_id) if(NULL == (profile = megaco_get_profile_by_suId(suId))){ return NULL; } - - - if (context_id > MG_MAX_CONTEXTS) { - return NULL; - } return megaco_get_context(profile, context_id); } @@ -353,8 +349,6 @@ mg_context_t *megaco_get_context(megaco_profile_t *profile, uint32_t context_id) mg_context_t *megaco_choose_context(megaco_profile_t *profile) { mg_context_t *ctx; - int i = 0x0; - int j = 0x0; switch_thread_rwlock_wrlock(profile->contexts_rwlock); /* Try the next one */ @@ -366,14 +360,12 @@ mg_context_t *megaco_choose_context(megaco_profile_t *profile) for (; profile->next_context_id < MG_MAX_CONTEXTS; profile->next_context_id++) { if ((profile->contexts_bitmap[profile->next_context_id % 8] & (1 << (profile->next_context_id / 8))) == 0) { /* Found! */ + int i = profile->next_context_id % MG_CONTEXT_MODULO; profile->contexts_bitmap[profile->next_context_id % 8] |= 1 << (profile->next_context_id / 8); - i = profile->next_context_id % MG_CONTEXT_MODULO; ctx = malloc(sizeof *ctx); + memset(ctx, 0, sizeof *ctx); ctx->context_id = profile->next_context_id; ctx->profile = profile; - for(j = 0; j< MG_CONTEXT_MAX_TERMS; j++){ - ctx->terminations[j] = NULL; - } if (!profile->contexts[i]) { profile->contexts[i] = ctx; diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway_xml.c b/src/mod/endpoints/mod_media_gateway/media_gateway_xml.c index fe588df34a..ca2e20d10d 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway_xml.c +++ b/src/mod/endpoints/mod_media_gateway/media_gateway_xml.c @@ -17,7 +17,7 @@ static switch_status_t modify_mid(char** pmid); /****************************************************************************************************************************/ 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_xml_t cfg, xml, param, mg_interfaces, mg_interface, mg_peers, mg_peer, mg_phys_terms, mg_term, peer_interfaces ; switch_status_t status = SWITCH_STATUS_FALSE; switch_event_t *event = NULL; const char *file = "media_gateway.conf"; @@ -101,7 +101,7 @@ switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload) goto done; } - if(SWITCH_STATUS_FALSE == (status = modify_mid(&peer_profile->mid))){ + if (SWITCH_STATUS_FALSE == (status = modify_mid(&peer_profile->mid))) { goto done; } @@ -112,6 +112,62 @@ switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload) } } } + + + if ((mg_phys_terms = switch_xml_child(cfg, "physical_terminations"))) { + + for (mg_term = switch_xml_child(mg_phys_terms, "map"); mg_term; mg_term = mg_term->next) { + switch_memory_pool_t *pool; + mg_termination_t *term; + // + const char *prefix = switch_xml_attr(mg_term, "termination-id-prefix"); + const char *sztermination_id_base = switch_xml_attr(mg_term, "termination-id-base"); + const char *tech = switch_xml_attr(mg_term, "tech"); + const char *channel_prefix = switch_xml_attr(mg_term, "channel-prefix"); + const char *channel_map = switch_xml_attr(mg_term, "channel-map"); + const char *szspan_id = switch_xml_attr(mg_term, "span-id"); + const int span_id = !zstr(szspan_id) ? atoi(szspan_id) : 0; + + int term_id = 1; + int chan_id = 1; + + + if (!zstr(channel_map)) { + /* Split channel-map */ + char *channel_map_dup = strdup(channel_map); + char *chanmap[24]; + int chanmap_count, i; + chanmap_count = switch_split(channel_map_dup, ' ', chanmap); + for (i = 0; i < chanmap_count; i++) { + char *p = strchr(chanmap[i], '-'); + if (p) { + int startchan, endchan, j; + *p++ = '\0'; + startchan = atoi(chanmap[i]); + endchan = atoi(p); + + for (j = startchan; j < endchan; j++) { + switch_core_new_memory_pool(&pool); + term = switch_core_alloc(profile->pool, sizeof *term); + term->pool = pool; + term->type = MG_TERM_TDM; + term->profile = profile; + term->name = switch_core_sprintf(pool, "%s%d", prefix, j); + term->u.tdm.span = span_id; + term->u.tdm.channel = j; + + switch_core_hash_insert_wrlock(profile->terminations, term->name, term, profile->terminations_rwlock); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Mapped termination [%s] to freetdm span: %d chan: %d\n", term->name, term->u.tdm.span, term->u.tdm.channel); + } + } + } + + free(channel_map_dup); + } + + } + } /* configure the MEGACO stack */ status = sng_mgco_cfg(profile); diff --git a/src/mod/endpoints/mod_media_gateway/mod_media_gateway.h b/src/mod/endpoints/mod_media_gateway/mod_media_gateway.h index f5f83c6dd6..f2ecbe002b 100644 --- a/src/mod/endpoints/mod_media_gateway/mod_media_gateway.h +++ b/src/mod/endpoints/mod_media_gateway/mod_media_gateway.h @@ -83,7 +83,10 @@ typedef struct mg_context_s mg_context_t; #define kSPAN_ID "span" #define kCHAN_ID "chan" -typedef struct mg_termination_s { + +typedef struct mg_termination_s mg_termination_t; + +struct mg_termination_s { switch_memory_pool_t *pool; mg_termination_type_t type; const char *name; /*!< Megaco Name */ @@ -91,6 +94,7 @@ typedef struct mg_termination_s { mg_context_t *context; /*!< Context in which this termination is connected, or NULL */ megaco_profile_t *profile; /*!< Parent MG profile */ MgMgcoReqEvtDesc *active_events; /* !< active megaco events */ + mg_termination_t *next; /*!< List for physical terminations */ union { struct { @@ -115,7 +119,7 @@ typedef struct mg_termination_s { int channel; } tdm; } u; -} mg_termination_t; +}; struct mg_context_s { @@ -149,6 +153,7 @@ struct megaco_profile_s { char* rtp_termination_id_prefix; int rtp_termination_id_len; char* peer_list[MG_MAX_PEERS]; /* MGC Peer ID LIST */ + char* codec_prefs; switch_thread_rwlock_t *contexts_rwlock; uint32_t next_context_id;