use span name instead of id. implement termination choose for tdm.

This commit is contained in:
Mathieu Rene 2012-07-25 17:18:18 -04:00
parent 828a13733b
commit 6cf298a746
4 changed files with 43 additions and 9 deletions

View File

@ -38,6 +38,7 @@ void ctdm_init(switch_loadable_module_interface_t *module_interface);
#define kSPAN_ID "span" #define kSPAN_ID "span"
#define kCHAN_ID "chan" #define kCHAN_ID "chan"
#define kSPAN_NAME "span_name"
static struct { static struct {
switch_memory_pool_t *pool; switch_memory_pool_t *pool;
@ -97,7 +98,8 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
switch_originate_flag_t flags, switch_call_cause_t *cancel_cause) switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
{ {
const char *szspanid = switch_event_get_header(var_event, kSPAN_ID), const char *szspanid = switch_event_get_header(var_event, kSPAN_ID),
*szchanid = switch_event_get_header(var_event, kCHAN_ID); *szchanid = switch_event_get_header(var_event, kCHAN_ID),
*span_name = switch_event_get_header(var_event, kSPAN_NAME);
int chan_id; int chan_id;
int span_id; int span_id;
@ -111,7 +113,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
ctdm_private_t *tech_pvt = NULL; ctdm_private_t *tech_pvt = NULL;
if (zstr(szchanid) || zstr(szspanid)) { if (zstr(szchanid) || (zstr(szspanid) && zstr(span_name))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Both ["kSPAN_ID"] and ["kCHAN_ID"] have to be set.\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Both ["kSPAN_ID"] and ["kCHAN_ID"] have to be set.\n");
goto fail; goto fail;
} }
@ -120,6 +122,14 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
span_id = atoi(szspanid); span_id = atoi(szspanid);
if (!span_id) {
if (ftdm_span_find_by_name(span_name, &span) == FTDM_SUCCESS) {
span_id = ftdm_span_get_id(span);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find span [%s]\n");
}
}
if (!(*new_session = switch_core_session_request(ctdm.endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, 0, pool))) { if (!(*new_session = switch_core_session_request(ctdm.endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, 0, pool))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't request session.\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't request session.\n");
goto fail; goto fail;

View File

@ -120,7 +120,7 @@ switch_status_t megaco_activate_termination(mg_termination_t *term)
} else if (term->type == MG_TERM_TDM) { } else if (term->type == MG_TERM_TDM) {
switch_snprintf(dialstring, sizeof dialstring, "tdm/%s", term->name); switch_snprintf(dialstring, sizeof dialstring, "tdm/%s", term->name);
switch_event_add_header(var_event, SWITCH_STACK_BOTTOM, kSPAN_ID, "%d", term->u.tdm.span); switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, kSPAN_NAME, term->u.tdm.span_name);
switch_event_add_header(var_event, SWITCH_STACK_BOTTOM, kCHAN_ID, "%d", term->u.tdm.channel); switch_event_add_header(var_event, SWITCH_STACK_BOTTOM, kCHAN_ID, "%d", term->u.tdm.channel);
} }
@ -135,6 +135,8 @@ switch_status_t megaco_activate_termination(mg_termination_t *term)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Termination [%s] successfully instanciated as [%s] [%s]\n", term->name, dialstring, switch_core_session_get_uuid(session)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Termination [%s] successfully instanciated as [%s] [%s]\n", term->name, dialstring, switch_core_session_get_uuid(session));
switch_set_flag(term, MGT_ACTIVE);
done: done:
if (session) { if (session) {
switch_core_session_rwunlock(session); switch_core_session_rwunlock(session);
@ -151,6 +153,7 @@ mg_termination_t *megaco_choose_termination(megaco_profile_t *profile, const cha
mg_termination_t *term = NULL; mg_termination_t *term = NULL;
char name[100]; char name[100];
int term_id; int term_id;
size_t prefixlen = strlen(prefix);
/* Check the termination type by prefix */ /* Check the termination type by prefix */
if (strncasecmp(prefix, profile->rtp_termination_id_prefix, strlen(profile->rtp_termination_id_prefix)) == 0) { if (strncasecmp(prefix, profile->rtp_termination_id_prefix, strlen(profile->rtp_termination_id_prefix)) == 0) {
@ -158,9 +161,15 @@ mg_termination_t *megaco_choose_termination(megaco_profile_t *profile, const cha
term_id = mg_rtp_request_id(profile); term_id = mg_rtp_request_id(profile);
switch_snprintf(name, sizeof name, "%s/%d", profile->rtp_termination_id_prefix, term_id); switch_snprintf(name, sizeof name, "%s/%d", profile->rtp_termination_id_prefix, term_id);
} else { } else {
for (term = profile->physical_terminations; term; term = term->next) {
if (!strncasecmp(prefix, term->name, prefixlen) && !switch_test_flag(term, MGT_ALLOCATED)) {
switch_set_flag(term, MGT_ALLOCATED);
return term; return term;
} }
}
return NULL;
}
switch_core_new_memory_pool(&pool); switch_core_new_memory_pool(&pool);
term = switch_core_alloc(pool, sizeof *term); term = switch_core_alloc(pool, sizeof *term);
@ -168,6 +177,7 @@ mg_termination_t *megaco_choose_termination(megaco_profile_t *profile, const cha
term->type = termtype; term->type = termtype;
term->active_events = NULL; term->active_events = NULL;
term->profile = profile; term->profile = profile;
switch_set_flag(term, MGT_ALLOCATED);
if (termtype == MG_TERM_RTP) { if (termtype == MG_TERM_RTP) {
/* Fill in local address and reserve an rtp port */ /* Fill in local address and reserve an rtp port */
@ -212,6 +222,9 @@ void megaco_termination_destroy(mg_termination_t *term)
term->active_events = NULL; term->active_events = NULL;
} }
switch_clear_flag(term, MGT_ALLOCATED);
switch_clear_flag(term, MGT_ACTIVE);
if (term->type == MG_TERM_RTP) { if (term->type == MG_TERM_RTP) {
switch_core_hash_delete_wrlock(term->profile->terminations, term->name, term->profile->terminations_rwlock); switch_core_hash_delete_wrlock(term->profile->terminations, term->name, term->profile->terminations_rwlock);
switch_core_destroy_memory_pool(&term->pool); switch_core_destroy_memory_pool(&term->pool);

View File

@ -77,8 +77,6 @@ switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload)
//const char *tech = switch_xml_attr(mg_term, "tech"); //const char *tech = switch_xml_attr(mg_term, "tech");
const char *channel_prefix = switch_xml_attr(mg_term, "channel-prefix"); const char *channel_prefix = switch_xml_attr(mg_term, "channel-prefix");
const char *channel_map = switch_xml_attr(mg_term, "channel-map"); 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;
if (!zstr(channel_map)) { if (!zstr(channel_map)) {
@ -102,12 +100,14 @@ switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload)
term->type = MG_TERM_TDM; term->type = MG_TERM_TDM;
term->profile = profile; term->profile = profile;
term->name = switch_core_sprintf(pool, "%s%d", prefix, j); term->name = switch_core_sprintf(pool, "%s%d", prefix, j);
term->u.tdm.span = span_id;
term->u.tdm.channel = j; term->u.tdm.channel = j;
term->u.tdm.span_name = switch_core_strdup(pool, channel_prefix);
switch_core_hash_insert_wrlock(profile->terminations, term->name, term, profile->terminations_rwlock); switch_core_hash_insert_wrlock(profile->terminations, term->name, term, profile->terminations_rwlock);
term->next = profile->physical_terminations;
profile->physical_terminations = term;
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); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Mapped termination [%s] to freetdm span: %s chan: %d\n", term->name, term->u.tdm.span_name, term->u.tdm.channel);
} }
} }
} }

View File

@ -83,10 +83,17 @@ typedef struct mg_context_s mg_context_t;
/* TDM parameters understood by the controllable channel */ /* TDM parameters understood by the controllable channel */
#define kSPAN_ID "span" #define kSPAN_ID "span"
#define kCHAN_ID "chan" #define kCHAN_ID "chan"
#define kSPAN_NAME "span_name"
typedef struct mg_termination_s mg_termination_t; typedef struct mg_termination_s mg_termination_t;
enum {
MGT_ALLOCATED = (1 << 0),
MGT_ACTIVE = (1 << 1),
} mg_termination_flags;
struct mg_termination_s { struct mg_termination_s {
switch_memory_pool_t *pool; switch_memory_pool_t *pool;
mg_termination_type_t type; mg_termination_type_t type;
@ -96,6 +103,7 @@ struct mg_termination_s {
megaco_profile_t *profile; /*!< Parent MG profile */ megaco_profile_t *profile; /*!< Parent MG profile */
MgMgcoReqEvtDesc *active_events; /* !< active megaco events */ MgMgcoReqEvtDesc *active_events; /* !< active megaco events */
mg_termination_t *next; /*!< List for physical terminations */ mg_termination_t *next; /*!< List for physical terminations */
uint32_t flags;
union { union {
struct { struct {
@ -116,8 +124,8 @@ struct mg_termination_s {
} rtp; } rtp;
struct { struct {
int span;
int channel; int channel;
const char *span_name;
} tdm; } tdm;
} u; } u;
}; };
@ -165,6 +173,9 @@ struct megaco_profile_s {
uint8_t rtpid_bitmap[MG_MAX_CONTEXTS/8]; uint8_t rtpid_bitmap[MG_MAX_CONTEXTS/8];
uint32_t rtpid_next; uint32_t rtpid_next;
mg_termination_t *physical_terminations;
switch_hash_t *terminations; switch_hash_t *terminations;
switch_thread_rwlock_t *terminations_rwlock; switch_thread_rwlock_t *terminations_rwlock;
}; };