Merge branch 'nsg-4.3' of ssh://git.sangoma.com/smg_freeswitch into nsg-4.3
This commit is contained in:
commit
6571b88e15
|
@ -7,6 +7,7 @@ applications/mod_hash
|
||||||
applications/mod_spandsp
|
applications/mod_spandsp
|
||||||
dialplans/mod_dialplan_xml
|
dialplans/mod_dialplan_xml
|
||||||
endpoints/mod_sofia
|
endpoints/mod_sofia
|
||||||
|
endpoints/mod_opal
|
||||||
#endpoints/mod_media_gateway
|
#endpoints/mod_media_gateway
|
||||||
../../libs/freetdm/mod_freetdm
|
../../libs/freetdm/mod_freetdm
|
||||||
xml_int/mod_xml_cdr
|
xml_int/mod_xml_cdr
|
||||||
|
|
|
@ -2097,7 +2097,7 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
|
||||||
static FIO_SIGNAL_CB_FUNCTION(on_common_signal)
|
static FIO_SIGNAL_CB_FUNCTION(on_common_signal)
|
||||||
{
|
{
|
||||||
uint32_t chanid, spanid;
|
uint32_t chanid, spanid;
|
||||||
switch_event_t *event = NULL;
|
switch_event_t *event = NULL;
|
||||||
ftdm_alarm_flag_t alarmbits = FTDM_ALARM_NONE;
|
ftdm_alarm_flag_t alarmbits = FTDM_ALARM_NONE;
|
||||||
|
|
||||||
chanid = ftdm_channel_get_id(sigmsg->channel);
|
chanid = ftdm_channel_get_id(sigmsg->channel);
|
||||||
|
@ -2200,9 +2200,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_common_signal)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
|
|
||||||
|
|
||||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(sigmsg->channel));
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(sigmsg->channel));
|
||||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(sigmsg->channel));
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(sigmsg->channel));
|
||||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(sigmsg->channel));
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(sigmsg->channel));
|
||||||
|
|
|
@ -68,6 +68,9 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
||||||
static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg);
|
static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg);
|
||||||
static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf);
|
static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf);
|
||||||
|
|
||||||
|
|
||||||
|
static ftdm_status_t ctdm_span_prepare(ftdm_span_t *span);
|
||||||
|
|
||||||
switch_state_handler_table_t ctdm_state_handlers = {
|
switch_state_handler_table_t ctdm_state_handlers = {
|
||||||
.on_init = channel_on_init,
|
.on_init = channel_on_init,
|
||||||
.on_destroy = channel_on_destroy
|
.on_destroy = channel_on_destroy
|
||||||
|
@ -81,6 +84,119 @@ switch_io_routines_t ctdm_io_routines = {
|
||||||
.receive_message = channel_receive_message
|
.receive_message = channel_receive_message
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void ctdm_report_alarms(ftdm_channel_t *channel, const char* mg_profile_name)
|
||||||
|
{
|
||||||
|
switch_event_t *event = NULL;
|
||||||
|
ftdm_alarm_flag_t alarmflag = 0;
|
||||||
|
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
ftdm_log(FTDM_LOG_ERROR, "failed to create alarms events\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ftdm_channel_get_alarms(channel, &alarmflag) != FTDM_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve alarms %s:%d\n", ftdm_channel_get_span_name(channel), ftdm_channel_get_id(channel));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(channel));
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(channel));
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(channel));
|
||||||
|
|
||||||
|
if (alarmflag) {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-clear");
|
||||||
|
} else {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-trap");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "mg-profile-name", mg_profile_name);
|
||||||
|
|
||||||
|
if (alarmflag & FTDM_ALARM_RED) {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "red");
|
||||||
|
}
|
||||||
|
if (alarmflag & FTDM_ALARM_YELLOW) {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "yellow");
|
||||||
|
}
|
||||||
|
if (alarmflag & FTDM_ALARM_RAI) {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "rai");
|
||||||
|
}
|
||||||
|
if (alarmflag & FTDM_ALARM_BLUE) {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "blue");
|
||||||
|
}
|
||||||
|
if (alarmflag & FTDM_ALARM_AIS) {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "ais");
|
||||||
|
}
|
||||||
|
if (alarmflag & FTDM_ALARM_GENERAL) {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "general");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
switch_event_fire(&event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void ctdm_event_handler(switch_event_t *event)
|
||||||
|
{
|
||||||
|
ftdm_status_t status = FTDM_FAIL;
|
||||||
|
switch(event->event_id) {
|
||||||
|
case SWITCH_EVENT_TRAP:
|
||||||
|
{
|
||||||
|
ftdm_span_t *span = NULL;
|
||||||
|
ftdm_channel_t *channel = NULL;
|
||||||
|
const char *span_name = NULL;
|
||||||
|
const char *chan_number = NULL;
|
||||||
|
uint32_t chan_id = 0;
|
||||||
|
const char *cond = switch_event_get_header(event, "condition");
|
||||||
|
const char *mg_profile_name = switch_event_get_header(event, "mg-profile-name");
|
||||||
|
|
||||||
|
if (zstr(cond)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
span_name = switch_event_get_header(event, "span-name");
|
||||||
|
chan_number = switch_event_get_header(event, "chan-number");
|
||||||
|
|
||||||
|
if (ftdm_span_find_by_name(span_name, &span) != FTDM_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find span [%s]\n", span_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(cond, "mg-tdm-prepare")) {
|
||||||
|
status = ctdm_span_prepare(span);
|
||||||
|
if (status == FTDM_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Span %s prepared successfully\n", span_name);
|
||||||
|
} else if (status != FTDM_EINVAL) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to prepare span %s.\n", span_name);
|
||||||
|
}
|
||||||
|
} else if (!strcmp(cond, "mg-tdm-check")) {
|
||||||
|
if (zstr(chan_number)) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No channel number specified\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chan_id = atoi(chan_number);
|
||||||
|
if (!chan_id) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid channel number:%s\n", chan_number);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
channel = ftdm_span_get_channel(span, chan_id);
|
||||||
|
if (!channel) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find channel\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctdm_report_alarms(channel, mg_profile_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void ctdm_init(switch_loadable_module_interface_t *module_interface)
|
void ctdm_init(switch_loadable_module_interface_t *module_interface)
|
||||||
{
|
{
|
||||||
switch_endpoint_interface_t *endpoint_interface;
|
switch_endpoint_interface_t *endpoint_interface;
|
||||||
|
@ -90,7 +206,82 @@ void ctdm_init(switch_loadable_module_interface_t *module_interface)
|
||||||
endpoint_interface->io_routines = &ctdm_io_routines;
|
endpoint_interface->io_routines = &ctdm_io_routines;
|
||||||
endpoint_interface->state_handler = &ctdm_state_handlers;
|
endpoint_interface->state_handler = &ctdm_state_handlers;
|
||||||
ctdm.endpoint_interface = endpoint_interface;
|
ctdm.endpoint_interface = endpoint_interface;
|
||||||
|
|
||||||
|
switch_event_bind("mod_freetdm", SWITCH_EVENT_TRAP, SWITCH_EVENT_SUBCLASS_ANY, ctdm_event_handler, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static FIO_SIGNAL_CB_FUNCTION(on_signal_cb)
|
||||||
|
{
|
||||||
|
uint32_t chanid, spanid;
|
||||||
|
switch_event_t *event = NULL;
|
||||||
|
ftdm_alarm_flag_t alarmbits = FTDM_ALARM_NONE;
|
||||||
|
|
||||||
|
chanid = ftdm_channel_get_id(sigmsg->channel);
|
||||||
|
spanid = ftdm_channel_get_span_id(sigmsg->channel);
|
||||||
|
|
||||||
|
switch(sigmsg->event_id) {
|
||||||
|
case FTDM_SIGEVENT_ALARM_CLEAR:
|
||||||
|
case FTDM_SIGEVENT_ALARM_TRAP:
|
||||||
|
{
|
||||||
|
if (ftdm_channel_get_alarms(sigmsg->channel, &alarmbits) != FTDM_SUCCESS) {
|
||||||
|
ftdm_log(FTDM_LOG_ERROR, "failed to retrieve alarms\n");
|
||||||
|
return FTDM_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
ftdm_log(FTDM_LOG_ERROR, "failed to create alarms events\n");
|
||||||
|
return FTDM_FAIL;
|
||||||
|
}
|
||||||
|
if (sigmsg->event_id == FTDM_SIGEVENT_ALARM_CLEAR) {
|
||||||
|
ftdm_log(FTDM_LOG_NOTICE, "Alarm cleared on channel %d:%d\n", spanid, chanid);
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-clear");
|
||||||
|
} else {
|
||||||
|
ftdm_log(FTDM_LOG_NOTICE, "Alarm raised on channel %d:%d\n", spanid, chanid);
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-trap");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unhandled event %d\n", sigmsg->event_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event) {
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(sigmsg->channel));
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(sigmsg->channel));
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(sigmsg->channel));
|
||||||
|
|
||||||
|
if (alarmbits & FTDM_ALARM_RED) {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "red");
|
||||||
|
}
|
||||||
|
if (alarmbits & FTDM_ALARM_YELLOW) {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "yellow");
|
||||||
|
}
|
||||||
|
if (alarmbits & FTDM_ALARM_RAI) {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "rai");
|
||||||
|
}
|
||||||
|
if (alarmbits & FTDM_ALARM_BLUE) {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "blue");
|
||||||
|
}
|
||||||
|
if (alarmbits & FTDM_ALARM_AIS) {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "ais");
|
||||||
|
}
|
||||||
|
if (alarmbits & FTDM_ALARM_GENERAL) {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "general");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_event_fire(&event);
|
||||||
|
}
|
||||||
|
return FTDM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ftdm_status_t ctdm_span_prepare(ftdm_span_t *span)
|
||||||
|
{
|
||||||
|
if (ftdm_span_register_signal_cb(span, on_signal_cb) != FTDM_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register signal CB\n");
|
||||||
|
return FTDM_FAIL;
|
||||||
|
}
|
||||||
|
return ftdm_span_start(span);
|
||||||
}
|
}
|
||||||
|
|
||||||
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
|
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
|
||||||
|
@ -111,9 +302,8 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
||||||
const char *dname;
|
const char *dname;
|
||||||
ftdm_codec_t codec;
|
ftdm_codec_t codec;
|
||||||
uint32_t interval;
|
uint32_t interval;
|
||||||
|
|
||||||
ctdm_private_t *tech_pvt = NULL;
|
ctdm_private_t *tech_pvt = NULL;
|
||||||
|
|
||||||
if (zstr(szchanid) || zstr(span_name)) {
|
if (zstr(szchanid) || 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;
|
||||||
|
@ -128,7 +318,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
@ -5618,16 +5618,68 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span_signaling(ftdm_span_t *span, const
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *ftdm_span_service_events(ftdm_thread_t *me, void *obj)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned waitms;
|
||||||
|
ftdm_event_t *event;
|
||||||
|
ftdm_status_t status = FTDM_SUCCESS;
|
||||||
|
ftdm_span_t *span = (ftdm_span_t*) obj;
|
||||||
|
short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count);
|
||||||
|
|
||||||
|
memset(poll_events, 0, sizeof(short) * span->chan_count);
|
||||||
|
|
||||||
|
for(i = 1; i <= span->chan_count; i++) {
|
||||||
|
poll_events[i] |= FTDM_EVENTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ftdm_running() && !(ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD))) {
|
||||||
|
waitms = 1000;
|
||||||
|
status = ftdm_span_poll_event(span, waitms, poll_events);
|
||||||
|
switch (status) {
|
||||||
|
case FTDM_FAIL:
|
||||||
|
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to poll span for events\n", span->name);
|
||||||
|
break;
|
||||||
|
case FTDM_TIMEOUT:
|
||||||
|
break;
|
||||||
|
case FTDM_SUCCESS:
|
||||||
|
/* Check if there are any channels that have events available */
|
||||||
|
while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ftdm_log(FTDM_LOG_CRIT, "%s:Unhandled IO event\n", span->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
FT_DECLARE(ftdm_status_t) ftdm_span_register_signal_cb(ftdm_span_t *span, fio_signal_cb_t sig_cb)
|
||||||
|
{
|
||||||
|
span->signal_cb = sig_cb;
|
||||||
|
return FTDM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span)
|
FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span)
|
||||||
{
|
{
|
||||||
ftdm_status_t status = FTDM_FAIL;
|
ftdm_status_t status = FTDM_FAIL;
|
||||||
|
|
||||||
ftdm_mutex_lock(span->mutex);
|
ftdm_mutex_lock(span->mutex);
|
||||||
|
|
||||||
if (ftdm_test_flag(span, FTDM_SPAN_STARTED)) {
|
if (ftdm_test_flag(span, FTDM_SPAN_STARTED)) {
|
||||||
status = FTDM_EINVAL;
|
status = FTDM_EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (span->signal_type == FTDM_SIGTYPE_NONE) {
|
||||||
|
/* If there is no signalling component, start a thread to poll events */
|
||||||
|
status = ftdm_thread_create_detached(ftdm_span_service_events, span);
|
||||||
|
if (status != FTDM_SUCCESS) {
|
||||||
|
ftdm_log(FTDM_LOG_CRIT,"Failed to start span event monitor thread!\n");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
//ftdm_report_initial_channels_alarms(span);
|
||||||
|
ftdm_set_flag_locked(span, FTDM_SPAN_STARTED);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
if (!span->start) {
|
if (!span->start) {
|
||||||
status = FTDM_ENOSYS;
|
status = FTDM_ENOSYS;
|
||||||
|
@ -5643,7 +5695,6 @@ FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span)
|
||||||
if (status == FTDM_SUCCESS) {
|
if (status == FTDM_SUCCESS) {
|
||||||
ftdm_set_flag_locked(span, FTDM_SPAN_STARTED);
|
ftdm_set_flag_locked(span, FTDM_SPAN_STARTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
ftdm_mutex_unlock(span->mutex);
|
ftdm_mutex_unlock(span->mutex);
|
||||||
return status;
|
return status;
|
||||||
|
@ -5828,8 +5879,10 @@ FT_DECLARE(ftdm_status_t) ftdm_group_create(ftdm_group_t **group, const char *na
|
||||||
|
|
||||||
static ftdm_status_t ftdm_span_trigger_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
static ftdm_status_t ftdm_span_trigger_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
||||||
{
|
{
|
||||||
ftdm_status_t status = span->signal_cb(sigmsg);
|
if (!span->signal_cb) {
|
||||||
return status;
|
return FTDM_FAIL;
|
||||||
|
}
|
||||||
|
return span->signal_cb(sigmsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ftdm_status_t ftdm_span_queue_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
static ftdm_status_t ftdm_span_queue_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
||||||
|
|
|
@ -1611,6 +1611,17 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span(ftdm_span_t *span, const char *typ
|
||||||
*/
|
*/
|
||||||
FT_DECLARE(ftdm_status_t) ftdm_configure_span_signaling(ftdm_span_t *span, const char *type, fio_signal_cb_t sig_cb, ftdm_conf_parameter_t *parameters);
|
FT_DECLARE(ftdm_status_t) ftdm_configure_span_signaling(ftdm_span_t *span, const char *type, fio_signal_cb_t sig_cb, ftdm_conf_parameter_t *parameters);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Register callback to listen for incoming events
|
||||||
|
* \note This function should only be used when there is no signalling module
|
||||||
|
* \param span The span to register to
|
||||||
|
* \param sig_cb The callback that the signaling stack will use to notify about events
|
||||||
|
*
|
||||||
|
* \retval FTDM_SUCCESS success
|
||||||
|
* \retval FTDM_FAIL failure
|
||||||
|
*/
|
||||||
|
FT_DECLARE(ftdm_status_t) ftdm_span_register_signal_cb(ftdm_span_t *span, fio_signal_cb_t sig_cb);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Start the span signaling (must call ftdm_configure_span_signaling first)
|
* \brief Start the span signaling (must call ftdm_configure_span_signaling first)
|
||||||
*
|
*
|
||||||
|
@ -1626,7 +1637,6 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span_signaling(ftdm_span_t *span, const
|
||||||
*/
|
*/
|
||||||
FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span);
|
FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span);
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Stop the span signaling (must call ftdm_span_start first)
|
* \brief Stop the span signaling (must call ftdm_span_start first)
|
||||||
* \note certain signalings (boost signaling) does not support granular span start/stop
|
* \note certain signalings (boost signaling) does not support granular span start/stop
|
||||||
|
|
|
@ -155,6 +155,43 @@ done:
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_status_t megaco_prepare_tdm_termination(mg_termination_t *term)
|
||||||
|
{
|
||||||
|
switch_event_t *event = NULL;
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to create NOTIFY event\n");
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", term->u.tdm.span_name);
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", term->u.tdm.channel);
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "mg-tdm-prepare");
|
||||||
|
|
||||||
|
switch_event_fire(&event);
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @Kapil Call this function once H.248 link is up */
|
||||||
|
switch_status_t megaco_check_tdm_termination(mg_termination_t *term)
|
||||||
|
{
|
||||||
|
switch_event_t *event = NULL;
|
||||||
|
|
||||||
|
if(!term || !term->profile) return SWITCH_STATUS_FALSE;
|
||||||
|
|
||||||
|
if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to create NOTIFY event\n");
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", term->u.tdm.span_name);
|
||||||
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", term->u.tdm.channel);
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "mg-tdm-check");
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "mg-profile-name", term->profile->name);
|
||||||
|
|
||||||
|
switch_event_fire(&event);
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
mg_termination_t *megaco_choose_termination(megaco_profile_t *profile, const char *prefix)
|
mg_termination_t *megaco_choose_termination(megaco_profile_t *profile, const char *prefix)
|
||||||
{
|
{
|
||||||
mg_termination_type_t termtype;
|
mg_termination_type_t termtype;
|
||||||
|
@ -204,6 +241,42 @@ mg_termination_t *megaco_choose_termination(megaco_profile_t *profile, const cha
|
||||||
return term;
|
return term;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mg_termination_t* megaco_find_termination_by_span_chan(megaco_profile_t *profile, char *span_name, char *chan_number)
|
||||||
|
{
|
||||||
|
void *val = NULL;
|
||||||
|
switch_hash_index_t *hi = NULL;
|
||||||
|
mg_termination_t *term = NULL;
|
||||||
|
int found = 0x00;
|
||||||
|
const void *var;
|
||||||
|
|
||||||
|
if(!span_name || !chan_number){
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,"Invalid span_name/chan_number \n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (hi = switch_hash_first(NULL, profile->terminations); hi; hi = switch_hash_next(hi)) {
|
||||||
|
switch_hash_this(hi, &var, NULL, &val);
|
||||||
|
term = (mg_termination_t *) val;
|
||||||
|
if(!term) continue;
|
||||||
|
if(MG_TERM_TDM != term->type) continue;
|
||||||
|
|
||||||
|
if ((!strcasecmp(span_name, term->u.tdm.span_name))&& (atoi(chan_number) == term->u.tdm.channel)) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
|
||||||
|
"Got term[%s] associated with span[%s], channel[%s]\n",term->name, span_name, chan_number);
|
||||||
|
found = 0x01;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!found){
|
||||||
|
term = NULL;
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
||||||
|
" Not able to find termination associated with span[%s], channel[%s]\n", span_name, chan_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
return term;
|
||||||
|
}
|
||||||
|
|
||||||
mg_termination_t *megaco_find_termination(megaco_profile_t *profile, const char *name)
|
mg_termination_t *megaco_find_termination(megaco_profile_t *profile, const char *name)
|
||||||
{
|
{
|
||||||
mg_termination_t *term = switch_core_hash_find_rdlock(profile->terminations, name, profile->terminations_rwlock);
|
mg_termination_t *term = switch_core_hash_find_rdlock(profile->terminations, name, profile->terminations_rwlock);
|
||||||
|
@ -535,6 +608,35 @@ switch_status_t megaco_profile_destroy(megaco_profile_t **profile)
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
switch_status_t mgco_init_ins_service_change(SuId suId)
|
||||||
|
{
|
||||||
|
megaco_profile_t* profile = NULL;
|
||||||
|
void *val = NULL;
|
||||||
|
const void *key = NULL;
|
||||||
|
switch_ssize_t keylen;
|
||||||
|
switch_hash_index_t *hi = NULL;
|
||||||
|
mg_termination_t *term = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
if(NULL == (profile = megaco_get_profile_by_suId(suId))){
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
|
||||||
|
"mgco_init_ins_service_change : Initiating terminations service change for profile: %s\n", profile->name);
|
||||||
|
|
||||||
|
/* loop through all termination and post get status Event */
|
||||||
|
for (hi = switch_hash_first(NULL, profile->terminations); hi; hi = switch_hash_next(hi)) {
|
||||||
|
switch_hash_this(hi, &key, &keylen, &val);
|
||||||
|
term = (mg_termination_t *) val;
|
||||||
|
if(!term) continue;
|
||||||
|
megaco_check_tdm_termination(term);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
switch_status_t megaco_peer_profile_destroy(mg_peer_profile_t **profile)
|
switch_status_t megaco_peer_profile_destroy(mg_peer_profile_t **profile)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -198,7 +198,7 @@ switch_status_t mg_is_ito_pkg_req(megaco_profile_t* mg_profile, MgMgcoCommand *c
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
switch_status_t mg_prc_descriptors(megaco_profile_t* mg_profile, MgMgcoCommand *cmd, mg_termination_t* term)
|
switch_status_t mg_prc_descriptors(megaco_profile_t* mg_profile, MgMgcoCommand *cmd, mg_termination_t* term, CmMemListCp *memCp)
|
||||||
{
|
{
|
||||||
CmSdpMedProtoFmts *format;
|
CmSdpMedProtoFmts *format;
|
||||||
TknU8 *fmt;
|
TknU8 *fmt;
|
||||||
|
@ -301,7 +301,7 @@ switch_status_t mg_prc_descriptors(megaco_profile_t* mg_profile, MgMgcoCommand *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mgco_handle_sdp(&local->sdp, term, MG_SDP_LOCAL);
|
mgco_handle_incoming_sdp(&local->sdp, term, MG_SDP_LOCAL, mg_profile, memCp);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -313,7 +313,7 @@ switch_status_t mg_prc_descriptors(megaco_profile_t* mg_profile, MgMgcoCommand *
|
||||||
remote = &mediaPar->u.remote;
|
remote = &mediaPar->u.remote;
|
||||||
sdp = remote->sdp.info[0];
|
sdp = remote->sdp.info[0];
|
||||||
/* for Matt - same like local descriptor */
|
/* for Matt - same like local descriptor */
|
||||||
mgco_handle_sdp(&remote->sdp, term, MG_SDP_REMOTE);
|
mgco_handle_incoming_sdp(&remote->sdp, term, MG_SDP_REMOTE, mg_profile, memCp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,12 +406,12 @@ switch_status_t mg_prc_descriptors(megaco_profile_t* mg_profile, MgMgcoCommand *
|
||||||
|
|
||||||
if (mgStream->sl.remote.pres.pres) {
|
if (mgStream->sl.remote.pres.pres) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Got remote stream media description:\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Got remote stream media description:\n");
|
||||||
mgco_handle_sdp(&mgStream->sl.remote.sdp, term, MG_SDP_LOCAL);
|
mgco_handle_incoming_sdp(&mgStream->sl.remote.sdp, term, MG_SDP_LOCAL, mg_profile, memCp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mgStream->sl.local.pres.pres) {
|
if (mgStream->sl.local.pres.pres) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Got local stream media description:\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Got local stream media description:\n");
|
||||||
mgco_handle_sdp(&mgStream->sl.local.sdp, term, MG_SDP_REMOTE);
|
mgco_handle_incoming_sdp(&mgStream->sl.local.sdp, term, MG_SDP_REMOTE, mg_profile, memCp);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -500,7 +500,7 @@ switch_status_t handle_mg_add_cmd(megaco_profile_t* mg_profile, MgMgcoCommand *i
|
||||||
mg_context_t* mg_ctxt;
|
mg_context_t* mg_ctxt;
|
||||||
int mediaId;
|
int mediaId;
|
||||||
MgMgcoLocalDesc *local = NULL;
|
MgMgcoLocalDesc *local = NULL;
|
||||||
CmSdpInfoSet *psdp = NULL;
|
/*CmSdpInfoSet *psdp = NULL;*/
|
||||||
|
|
||||||
|
|
||||||
/* TODO - Kapil dummy line , will need to add with proper code */
|
/* TODO - Kapil dummy line , will need to add with proper code */
|
||||||
|
@ -610,7 +610,14 @@ switch_status_t handle_mg_add_cmd(megaco_profile_t* mg_profile, MgMgcoCommand *i
|
||||||
|
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
||||||
ret = mg_prc_descriptors(mg_profile, inc_cmd, term);
|
ret = mg_prc_descriptors(mg_profile, inc_cmd, term, &inc_cmd->u.mgCmdInd[0]->memCp);
|
||||||
|
|
||||||
|
/* IF there is any error , return */
|
||||||
|
if(term->mg_error_code && (*term->mg_error_code == MGT_MGCP_RSP_CODE_INCONSISTENT_LCL_OPT)){
|
||||||
|
mg_util_set_err_string(&errTxt, " Unsupported Codec ");
|
||||||
|
err_code = MGT_MGCP_RSP_CODE_INCONSISTENT_LCL_OPT;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO - locally assigned SDP must be the part of termination...which we can use to fill responses*/
|
/* TODO - locally assigned SDP must be the part of termination...which we can use to fill responses*/
|
||||||
|
|
||||||
|
@ -707,6 +714,17 @@ switch_status_t handle_mg_add_cmd(megaco_profile_t* mg_profile, MgMgcoCommand *i
|
||||||
|
|
||||||
/* only for RTP */
|
/* only for RTP */
|
||||||
if(is_rtp){
|
if(is_rtp){
|
||||||
|
if(SWITCH_STATUS_FALSE == mg_build_sdp(&desc->u.media, inc_med_desc, mg_profile, term, &rsp.u.mgCmdRsp[0]->memCp)) {
|
||||||
|
if(term->mg_error_code && (*term->mg_error_code == MGT_MGCP_RSP_CODE_INCONSISTENT_LCL_OPT)){
|
||||||
|
mg_util_set_err_string(&errTxt, " Unsupported Codec ");
|
||||||
|
err_code = MGT_MGCP_RSP_CODE_INCONSISTENT_LCL_OPT;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
if(is_rtp){
|
||||||
|
mg_build_sdp(desc, inc_med_desc, mg_profile, term, &rsp.u.mgCmdRsp[0]->memCp);
|
||||||
/* build local descriptors */
|
/* build local descriptors */
|
||||||
/*MgMgcoStreamDesc *stream;*/
|
/*MgMgcoStreamDesc *stream;*/
|
||||||
char* ipAddress[4];// = "192.168.1.1";
|
char* ipAddress[4];// = "192.168.1.1";
|
||||||
|
@ -762,11 +780,14 @@ switch_status_t handle_mg_add_cmd(megaco_profile_t* mg_profile, MgMgcoCommand *i
|
||||||
|
|
||||||
psdp = &(local->sdp);
|
psdp = &(local->sdp);
|
||||||
|
|
||||||
if (mgUtlGrowList((void ***)&psdp->info, sizeof(CmSdpInfo),
|
if((NOTPRSNT == local->sdp.numComp.pres) || (0 == local->sdp.numComp.val)){
|
||||||
&psdp->numComp, &rsp.u.mgCmdRsp[0]->memCp) != ROK)
|
|
||||||
{
|
if (mgUtlGrowList((void ***)&psdp->info, sizeof(CmSdpInfo),
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR,"Grow List failed\n");
|
&psdp->numComp, &rsp.u.mgCmdRsp[0]->memCp) != ROK)
|
||||||
return SWITCH_STATUS_FALSE;
|
{
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR,"Grow List failed\n");
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
psdp->info[psdp->numComp.val-1]->pres.pres = PRSNT_NODEF;
|
psdp->info[psdp->numComp.val-1]->pres.pres = PRSNT_NODEF;
|
||||||
|
@ -875,7 +896,7 @@ switch_status_t handle_mg_add_cmd(megaco_profile_t* mg_profile, MgMgcoCommand *i
|
||||||
|
|
||||||
MG_INIT_TOKEN_VALUE(&(media->field.par.pflst[media->field.par.numProtFmts.val-1]->u.rtp.fmts[0]->type), CM_SDP_SPEC);
|
MG_INIT_TOKEN_VALUE(&(media->field.par.pflst[media->field.par.numProtFmts.val-1]->u.rtp.fmts[0]->type), CM_SDP_SPEC);
|
||||||
|
|
||||||
MG_INIT_TOKEN_VALUE(&(media->field.par.pflst[media->field.par.numProtFmts.val-1]->u.rtp.fmts[0]->val), 4);
|
MG_INIT_TOKEN_VALUE(&(media->field.par.pflst[media->field.par.numProtFmts.val-1]->u.rtp.fmts[0]->val), 8);
|
||||||
|
|
||||||
/* Fill attribute if reqd */
|
/* Fill attribute if reqd */
|
||||||
{
|
{
|
||||||
|
@ -893,6 +914,7 @@ switch_status_t handle_mg_add_cmd(megaco_profile_t* mg_profile, MgMgcoCommand *i
|
||||||
|
|
||||||
free(dup);
|
free(dup);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* We will always send one command at a time..*/
|
/* We will always send one command at a time..*/
|
||||||
|
@ -1052,13 +1074,22 @@ switch_status_t handle_mg_modify_cmd(megaco_profile_t* mg_profile, MgMgcoCommand
|
||||||
|
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
||||||
ret = mg_prc_descriptors(mg_profile, inc_cmd, term);
|
ret = mg_prc_descriptors(mg_profile, inc_cmd, term, &inc_cmd->u.mgCmdInd[0]->memCp);
|
||||||
|
|
||||||
|
/* IF there is any error , return */
|
||||||
|
if(term->mg_error_code && (*term->mg_error_code == MGT_MGCP_RSP_CODE_INCONSISTENT_LCL_OPT)){
|
||||||
|
mg_util_set_err_string(&errTxt, " Unsupported Codec ");
|
||||||
|
err_code = MGT_MGCP_RSP_CODE_INCONSISTENT_LCL_OPT;
|
||||||
|
/* TODO delete RTP termination */
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* SDP updated to termination */
|
/* SDP updated to termination */
|
||||||
|
|
||||||
megaco_activate_termination(term);
|
megaco_activate_termination(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO - copy inc descriptor...not sure if we need to do this.. */
|
||||||
|
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
||||||
/* Matt - to provide the response SDP structure which needs to fill in Modify command response */
|
/* Matt - to provide the response SDP structure which needs to fill in Modify command response */
|
||||||
|
@ -2257,6 +2288,45 @@ U32 get_txn_id(){
|
||||||
return outgoing_txn_id;
|
return outgoing_txn_id;
|
||||||
}
|
}
|
||||||
/*****************************************************************************************************************************/
|
/*****************************************************************************************************************************/
|
||||||
|
switch_status_t mg_send_term_service_change(char* mg_profile_name,char *span_name, char *chan_number, mg_term_states_e term_state)
|
||||||
|
{
|
||||||
|
mg_termination_t* term = NULL;
|
||||||
|
switch_status_t ret = SWITCH_STATUS_SUCCESS;
|
||||||
|
megaco_profile_t *profile = NULL;
|
||||||
|
|
||||||
|
switch_assert(span_name);
|
||||||
|
switch_assert(chan_number);
|
||||||
|
|
||||||
|
profile = megaco_profile_locate(mg_profile_name);
|
||||||
|
|
||||||
|
term = megaco_find_termination_by_span_chan(profile, span_name, chan_number);
|
||||||
|
|
||||||
|
if(!term || !term->profile){
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(term_state)
|
||||||
|
{
|
||||||
|
case MG_TERM_SERVICE_STATE_IN_SERVICE:
|
||||||
|
{
|
||||||
|
ret = mg_send_ins_service_change(term->profile, term->name, 0x00 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MG_TERM_SERVICE_STATE_OUT_OF_SERVICE:
|
||||||
|
{
|
||||||
|
ret = mg_send_oos_service_change(term->profile, term->name, 0x00 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR," Invalid term_state[%d]\n", term_state);
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/*****************************************************************************************************************************/
|
||||||
/* Note : API to send Service Change when termination is coming up(in-service) */
|
/* Note : API to send Service Change when termination is coming up(in-service) */
|
||||||
/* INPUT : MG Profile structure and termination name */
|
/* INPUT : MG Profile structure and termination name */
|
||||||
/* wild flag will tell if service change request needs to be in W-SC format as we can have W-SC=A01* or SC=A01* */
|
/* wild flag will tell if service change request needs to be in W-SC format as we can have W-SC=A01* or SC=A01* */
|
||||||
|
|
|
@ -52,6 +52,13 @@ typedef enum{
|
||||||
SNG_MG_ENCODING_TEXT,
|
SNG_MG_ENCODING_TEXT,
|
||||||
}sng_mg_encoding_types_e;
|
}sng_mg_encoding_types_e;
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
MG_TERM_SERVICE_STATE_UNKNOWN,
|
||||||
|
MG_TERM_SERVICE_STATE_IN_SERVICE,
|
||||||
|
MG_TERM_SERVICE_STATE_OUT_OF_SERVICE,
|
||||||
|
MG_TERM_SERVICE_STATE_INVALID,
|
||||||
|
}mg_term_states_e;
|
||||||
|
|
||||||
#define PRNT_ENCODING_TYPE(_val)\
|
#define PRNT_ENCODING_TYPE(_val)\
|
||||||
((_val == SNG_MG_ENCODING_TEXT)?"SNG_MG_ENCODING_TEXT":\
|
((_val == SNG_MG_ENCODING_TEXT)?"SNG_MG_ENCODING_TEXT":\
|
||||||
(_val == SNG_MG_ENCODING_BINARY)?"SNG_MG_ENCODING_BINARY":\
|
(_val == SNG_MG_ENCODING_BINARY)?"SNG_MG_ENCODING_BINARY":\
|
||||||
|
@ -141,7 +148,7 @@ typedef enum {
|
||||||
(_reqId)->id.val = 0xFFFFFFFF;
|
(_reqId)->id.val = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
|
||||||
switch_status_t mg_prc_descriptors(megaco_profile_t* mg_profile, MgMgcoCommand *inc_cmd, mg_termination_t* term);
|
switch_status_t mg_prc_descriptors(megaco_profile_t* mg_profile, MgMgcoCommand *inc_cmd, mg_termination_t* term, CmMemListCp *memCp);
|
||||||
void handle_sng_log(uint8_t level, char *fmt, ...);
|
void handle_sng_log(uint8_t level, char *fmt, ...);
|
||||||
void handle_mgco_sta_ind(Pst *pst, SuId suId, MgMgtSta* msg);
|
void handle_mgco_sta_ind(Pst *pst, SuId suId, MgMgtSta* msg);
|
||||||
void handle_mgco_txn_sta_ind(Pst *pst, SuId suId, MgMgcoInd* msg);
|
void handle_mgco_txn_sta_ind(Pst *pst, SuId suId, MgMgcoInd* msg);
|
||||||
|
@ -155,6 +162,11 @@ int mg_enable_logging(void);
|
||||||
int mg_disable_logging(void);
|
int mg_disable_logging(void);
|
||||||
void mg_util_set_err_string ( MgStr *errTxt, char* str);
|
void mg_util_set_err_string ( MgStr *errTxt, char* str);
|
||||||
|
|
||||||
|
switch_status_t mg_build_sdp(MgMgcoMediaDesc* out, MgMgcoMediaDesc* inc, megaco_profile_t* mg_profile, mg_termination_t* term, CmMemListCp *memCp);
|
||||||
|
switch_status_t mg_add_local_descriptor(MgMgcoMediaDesc* media, megaco_profile_t* mg_profile, mg_termination_t* term, CmMemListCp *memCp);
|
||||||
|
switch_status_t mg_send_term_service_change(char* mg_profile_name, char *span_name, char *chan_number, mg_term_states_e term_state);
|
||||||
|
mg_termination_t* megaco_find_termination_by_span_chan(megaco_profile_t *profile , char *span_name, char *chan_number);
|
||||||
|
|
||||||
|
|
||||||
switch_status_t sng_mgco_cfg(megaco_profile_t* profile);
|
switch_status_t sng_mgco_cfg(megaco_profile_t* profile);
|
||||||
switch_status_t sng_mgco_init(sng_mg_event_interface_t* event);
|
switch_status_t sng_mgco_init(sng_mg_event_interface_t* event);
|
||||||
|
@ -163,7 +175,7 @@ int sng_mgco_mg_get_status(int elemId, MgMngmt* cfm, megaco_profile_t* mg_cfg, m
|
||||||
|
|
||||||
switch_status_t mg_is_ito_pkg_req(megaco_profile_t* mg_profile, MgMgcoCommand *cmd);
|
switch_status_t mg_is_ito_pkg_req(megaco_profile_t* mg_profile, MgMgcoCommand *cmd);
|
||||||
switch_status_t mg_send_end_of_axn(SuId suId, MgMgcoTransId* transId, MgMgcoContextId* ctxtId, TknU32* peerId);
|
switch_status_t mg_send_end_of_axn(SuId suId, MgMgcoTransId* transId, MgMgcoContextId* ctxtId, TknU32* peerId);
|
||||||
void mgco_handle_sdp(CmSdpInfoSet *sdp,mg_termination_t* term, mgco_sdp_types_e sdp_type);
|
void mgco_handle_incoming_sdp(CmSdpInfoSet *sdp,mg_termination_t* term, mgco_sdp_types_e sdp_type, megaco_profile_t* mg_profile, CmMemListCp *memCp);
|
||||||
void mg_util_set_ctxt_string ( MgStr *errTxt, MgMgcoContextId *ctxtId);
|
void mg_util_set_ctxt_string ( MgStr *errTxt, MgMgcoContextId *ctxtId);
|
||||||
switch_status_t handle_mg_add_cmd(megaco_profile_t* mg_profile, MgMgcoCommand *inc_cmd, MgMgcoContextId* new_ctxtId);
|
switch_status_t handle_mg_add_cmd(megaco_profile_t* mg_profile, MgMgcoCommand *inc_cmd, MgMgcoContextId* new_ctxtId);
|
||||||
switch_status_t handle_mg_subtract_cmd(megaco_profile_t* mg_profile, MgMgcoCommand *inc_cmd);
|
switch_status_t handle_mg_subtract_cmd(megaco_profile_t* mg_profile, MgMgcoCommand *inc_cmd);
|
||||||
|
@ -180,6 +192,7 @@ switch_status_t mg_send_audit_rsp(SuId suId, MgMgcoCommand *req);
|
||||||
switch_status_t handle_mg_audit_cmd(SuId suId, MgMgcoCommand *auditReq);
|
switch_status_t handle_mg_audit_cmd(SuId suId, MgMgcoCommand *auditReq);
|
||||||
switch_status_t mg_stack_termination_is_in_service(char* term_str, int len);
|
switch_status_t mg_stack_termination_is_in_service(char* term_str, int len);
|
||||||
void mg_util_set_cmd_name_string (MgStr *errTxt, MgMgcoCommand *cmd);
|
void mg_util_set_cmd_name_string (MgStr *errTxt, MgMgcoCommand *cmd);
|
||||||
|
switch_status_t mgco_init_ins_service_change(SuId suId);
|
||||||
|
|
||||||
switch_status_t mg_send_modify_rsp(SuId suId, MgMgcoCommand *req);
|
switch_status_t mg_send_modify_rsp(SuId suId, MgMgcoCommand *req);
|
||||||
switch_status_t mg_send_subtract_rsp(SuId suId, MgMgcoCommand *req);
|
switch_status_t mg_send_subtract_rsp(SuId suId, MgMgcoCommand *req);
|
||||||
|
@ -193,6 +206,9 @@ switch_status_t mg_fill_svc_change(MgMgcoSvcChgPar *srvPar, uint8_t method, c
|
||||||
void mg_fill_null_context(MgMgcoContextId* ctxt);
|
void mg_fill_null_context(MgMgcoContextId* ctxt);
|
||||||
switch_status_t mg_send_service_change(SuId suId, const char* term_name, uint8_t method, MgServiceChangeReason_e reason,uint8_t wild);
|
switch_status_t mg_send_service_change(SuId suId, const char* term_name, uint8_t method, MgServiceChangeReason_e reason,uint8_t wild);
|
||||||
switch_status_t mg_create_mgco_command(MgMgcoCommand *cmd, uint8_t apiType, uint8_t cmdType);
|
switch_status_t mg_create_mgco_command(MgMgcoCommand *cmd, uint8_t apiType, uint8_t cmdType);
|
||||||
|
switch_status_t mg_add_lcl_media(CmSdpMediaDescSet* med, megaco_profile_t* mg_profile, mg_termination_t* term, CmMemListCp *memCp);
|
||||||
|
switch_status_t mg_add_supported_media_codec(CmSdpMediaDesc* media, megaco_profile_t* mg_profile, mg_termination_t* term, CmMemListCp *memCp);
|
||||||
|
switch_status_t mg_rem_unsupported_codecs (megaco_profile_t* mg_profile, mg_termination_t* term, CmSdpMedFmtRtpList *fmtList, CmSdpAttrSet *attrSet, CmMemListCp *memCp);
|
||||||
|
|
||||||
switch_status_t mg_send_oos_service_change(megaco_profile_t* mg_profile, const char* term_name, int wild);
|
switch_status_t mg_send_oos_service_change(megaco_profile_t* mg_profile, const char* term_name, int wild);
|
||||||
switch_status_t mg_send_ins_service_change(megaco_profile_t* mg_profile, const char* term_name, int wild);
|
switch_status_t mg_send_ins_service_change(megaco_profile_t* mg_profile, const char* term_name, int wild);
|
||||||
|
|
|
@ -25,8 +25,8 @@ void handle_mg_alarm(Pst *pst, MgMngmt *usta)
|
||||||
|
|
||||||
memset(&prBuf[0], 0, sizeof(prBuf));
|
memset(&prBuf[0], 0, sizeof(prBuf));
|
||||||
|
|
||||||
len = len + sprintf(prBuf+len,"MG Status Indication: received with Category = %d, Event = %d, Cause = %d \n",
|
len = len + sprintf(prBuf+len,"MG Status Indication: received for sapId[%d] with Category = %d, Event = %d, Cause = %d \n",
|
||||||
usta->t.usta.alarm.category, usta->t.usta.alarm.event,
|
usta->t.usta.alarmInfo.sapId, usta->t.usta.alarm.category, usta->t.usta.alarm.event,
|
||||||
usta->t.usta.alarm.cause);
|
usta->t.usta.alarm.cause);
|
||||||
|
|
||||||
len = len + sprintf(prBuf+len, "Category ( ");
|
len = len + sprintf(prBuf+len, "Category ( ");
|
||||||
|
@ -218,9 +218,8 @@ void handle_mg_alarm(Pst *pst, MgMngmt *usta)
|
||||||
case LMG_EVENT_PEER_ENABLED:
|
case LMG_EVENT_PEER_ENABLED:
|
||||||
{
|
{
|
||||||
len = len + sprintf(prBuf+len, "gateway enabled");
|
len = len + sprintf(prBuf+len, "gateway enabled");
|
||||||
/* gateway enabled now we can send termination service change */
|
/* gateway enabled now we can send termination service change for all terminations */
|
||||||
/*TODO - probably we cannt immediate send Service change - we have to find proper place */
|
mgco_init_ins_service_change( usta->t.usta.alarmInfo.sapId );
|
||||||
/*mg_send_service_change(0x01, "A01", MGT_SVCCHGMETH_RESTART,MG_SVC_REASON_900_RESTORED );*/
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LMG_EVENT_PEER_DISCOVERED:
|
case LMG_EVENT_PEER_DISCOVERED:
|
||||||
|
|
|
@ -421,7 +421,7 @@ void mg_util_set_cmd_name_string (MgStr *errTxt, MgMgcoCommand *cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************************************************************/
|
/*****************************************************************************************************************************/
|
||||||
void mgco_print_sdp_attr_set(CmSdpAttrSet *s)
|
void mgco_handle_sdp_attr_set(CmSdpAttrSet *s, mg_termination_t* term)
|
||||||
{
|
{
|
||||||
int i=0x00;
|
int i=0x00;
|
||||||
if (s->numComp.pres) {
|
if (s->numComp.pres) {
|
||||||
|
@ -461,6 +461,9 @@ void mgco_print_sdp_attr_set(CmSdpAttrSet *s)
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\t PTIME = %ld \n",
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\t PTIME = %ld \n",
|
||||||
(NOTPRSNT != a->u.ptime.pres)?a->u.ptime.val:-1);
|
(NOTPRSNT != a->u.ptime.pres)?a->u.ptime.val:-1);
|
||||||
#endif
|
#endif
|
||||||
|
if(MG_TERM_RTP == term->type){
|
||||||
|
term->u.rtp.ptime = a->u.ptime.val;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CM_SDP_ATTR_RECVONLY:
|
case CM_SDP_ATTR_RECVONLY:
|
||||||
|
@ -786,7 +789,30 @@ void mgco_print_CmSdpU8OrNil(CmSdpU8OrNil* p)
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE,"CmSdpU8OrNil: Value = %d \n", (NOTPRSNT != p->val.pres)?p->val.val:-1);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE,"CmSdpU8OrNil: Value = %d \n", (NOTPRSNT != p->val.pres)?p->val.val:-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mgco_print_sdp_media_param(CmSdpMedPar *s, mg_termination_t* term, mgco_sdp_types_e sdp_type)
|
const char* mg_get_codec_name(megaco_profile_t* mg_profile, int iana_code)
|
||||||
|
{
|
||||||
|
int i = 0x00;
|
||||||
|
const switch_codec_implementation_t *codecs[16];
|
||||||
|
char *codec_prefs[16] = { 0 };
|
||||||
|
char *szcodec_prefs;
|
||||||
|
int codec_count;
|
||||||
|
|
||||||
|
szcodec_prefs = strdup(mg_profile->codec_prefs);
|
||||||
|
codec_count = switch_split(szcodec_prefs, ',', codec_prefs);
|
||||||
|
|
||||||
|
/* Get the list of codecs, by preference */
|
||||||
|
switch_loadable_module_get_codecs_sorted(codecs, switch_arraylen(codecs), codec_prefs, switch_arraylen(codec_prefs));
|
||||||
|
/* see if received codec is present in our codec supported list */
|
||||||
|
for (i = 0; codecs[i] && i < codec_count; i++) {
|
||||||
|
if(iana_code == codecs[i]->ianacode){
|
||||||
|
return codecs[i]->iananame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mgco_handle_sdp_media_param(CmSdpMedPar *s, mg_termination_t* term, mgco_sdp_types_e sdp_type, megaco_profile_t* mg_profile, CmSdpAttrSet *attrSet, CmMemListCp *memCp)
|
||||||
{
|
{
|
||||||
int i=0x00;
|
int i=0x00;
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "***** Media Parameter *********** \n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "***** Media Parameter *********** \n");
|
||||||
|
@ -837,6 +863,27 @@ void mgco_print_sdp_media_param(CmSdpMedPar *s, mg_termination_t* term, mgco_sdp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ideally remote descriptor should have supported codec..but just in case calling remove un-supported codecs api */
|
||||||
|
mg_rem_unsupported_codecs(mg_profile, term , r, attrSet, memCp);
|
||||||
|
|
||||||
|
|
||||||
|
/* now whatever we have , that will be suported one */
|
||||||
|
if((NOTPRSNT != r->num.pres) && (0 != r->num.val) && (NULL != r->fmts[0])){
|
||||||
|
const char* name = mg_get_codec_name(mg_profile, r->fmts[0]->val.val);
|
||||||
|
if(name){
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, " Updating codec to[%d], name[%s] \n",
|
||||||
|
r->fmts[0]->val.val, name);
|
||||||
|
if(MG_TERM_RTP == term->type){
|
||||||
|
term->u.rtp.codec = name;
|
||||||
|
term->u.rtp.pt = r->fmts[0]->val.val;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
/* ERROR */
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " NO Codec Name found against iana[%d] \n", r->fmts[0]->val.val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -854,7 +901,7 @@ void mgco_print_sdp_media_param(CmSdpMedPar *s, mg_termination_t* term, mgco_sdp
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "**************** \n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "**************** \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void mgco_handle_sdp(CmSdpInfoSet *sdp, mg_termination_t* term, mgco_sdp_types_e sdp_type)
|
void mgco_handle_incoming_sdp(CmSdpInfoSet *sdp, mg_termination_t* term, mgco_sdp_types_e sdp_type, megaco_profile_t* mg_profile, CmMemListCp *memCp)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -1021,7 +1068,7 @@ void mgco_handle_sdp(CmSdpInfoSet *sdp, mg_termination_t* term, mgco_sdp_types_e
|
||||||
/************************************************************************************************************************/
|
/************************************************************************************************************************/
|
||||||
/* Attribute Set */
|
/* Attribute Set */
|
||||||
|
|
||||||
mgco_print_sdp_attr_set(&s->attrSet);
|
mgco_handle_sdp_attr_set(&s->attrSet, term);
|
||||||
|
|
||||||
/************************************************************************************************************************/
|
/************************************************************************************************************************/
|
||||||
/* Media Descriptor Set */
|
/* Media Descriptor Set */
|
||||||
|
@ -1077,7 +1124,7 @@ void mgco_handle_sdp(CmSdpInfoSet *sdp, mg_termination_t* term, mgco_sdp_types_e
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mgco_print_sdp_media_param(&f->par, term, sdp_type);
|
mgco_handle_sdp_media_param(&f->par, term, sdp_type, mg_profile, &desc->attrSet, memCp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*info */
|
/*info */
|
||||||
|
@ -1097,7 +1144,7 @@ void mgco_handle_sdp(CmSdpInfoSet *sdp, mg_termination_t* term, mgco_sdp_types_e
|
||||||
}
|
}
|
||||||
|
|
||||||
/* attribute set */
|
/* attribute set */
|
||||||
mgco_print_sdp_attr_set(&desc->attrSet);
|
mgco_handle_sdp_attr_set(&desc->attrSet, term);
|
||||||
|
|
||||||
|
|
||||||
if (desc->field.mediaType.val == CM_SDP_MEDIA_AUDIO &&
|
if (desc->field.mediaType.val == CM_SDP_MEDIA_AUDIO &&
|
||||||
|
@ -1441,3 +1488,515 @@ void mg_print_time()
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,"Current Time = %s", ctime(&now));
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,"Current Time = %s", ctime(&now));
|
||||||
}
|
}
|
||||||
/*****************************************************************************************************************************/
|
/*****************************************************************************************************************************/
|
||||||
|
switch_status_t mg_add_local_descriptor(MgMgcoMediaDesc* media, megaco_profile_t* mg_profile, mg_termination_t* term,CmMemListCp *memCp)
|
||||||
|
{
|
||||||
|
char* ipAddress[4];
|
||||||
|
MgMgcoLocalDesc *local;
|
||||||
|
CmSdpInfoSet *psdp = NULL;
|
||||||
|
char * dup = NULL;
|
||||||
|
switch_status_t ret = SWITCH_STATUS_SUCCESS;
|
||||||
|
CmSdpMediaDescSet* med = NULL;
|
||||||
|
|
||||||
|
switch_assert(media);
|
||||||
|
switch_assert(mg_profile);
|
||||||
|
switch_assert(term);
|
||||||
|
|
||||||
|
dup = strdup((char*)term->u.rtp.local_addr);
|
||||||
|
switch_split(dup,'.',ipAddress);
|
||||||
|
|
||||||
|
/* allocating mem for local descriptor */
|
||||||
|
if (mgUtlGrowList((void ***)&media->parms, sizeof(MgMgcoMediaPar), &media->num, memCp) != ROK)
|
||||||
|
{
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR,"Grow List failed\n");
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
media->parms[media->num.val-1]->type.pres = PRSNT_NODEF;
|
||||||
|
media->parms[media->num.val-1]->type.val = MGT_MEDIAPAR_LOCAL;
|
||||||
|
|
||||||
|
local = &media->parms[media->num.val-1]->u.local;
|
||||||
|
|
||||||
|
local->pres.pres = PRSNT_NODEF;
|
||||||
|
|
||||||
|
psdp = &(local->sdp);
|
||||||
|
|
||||||
|
if (mgUtlGrowList((void ***)&psdp->info, sizeof(CmSdpInfo), &psdp->numComp, memCp) != ROK)
|
||||||
|
{
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR,"Grow List failed\n");
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
psdp->info[psdp->numComp.val-1]->pres.pres = PRSNT_NODEF;
|
||||||
|
|
||||||
|
/* fill version */
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->ver),1);
|
||||||
|
|
||||||
|
/* fill orig */
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->orig.pres), 1);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->orig.type), CM_SDP_SPEC);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->orig.orig.pres), 1);
|
||||||
|
|
||||||
|
MG_SET_TKNSTROSXL(psdp->info[psdp->numComp.val-1]->orig.orig.usrName, 1, "-",
|
||||||
|
memCp);
|
||||||
|
MG_SET_TKNSTROSXL(psdp->info[psdp->numComp.val-1]->orig.orig.sessId, 1, "0",
|
||||||
|
memCp);
|
||||||
|
MG_SET_TKNSTROSXL(psdp->info[psdp->numComp.val-1]->orig.orig.sessVer, 1, "0",
|
||||||
|
memCp);
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->orig.orig.sdpAddr.netType.type),
|
||||||
|
CM_SDP_NET_TYPE_IN);
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->orig.orig.sdpAddr.addrType),
|
||||||
|
CM_SDP_ADDR_TYPE_IPV4);
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->orig.orig.sdpAddr.u.ip4.addrType),
|
||||||
|
CM_SDP_IPV4_IP_UNI);
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->orig.orig.sdpAddr.u.ip4.addrType),
|
||||||
|
CM_SDP_IPV4_IP_UNI);
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->orig.orig.sdpAddr.u.ip4.u.ip.b[0]),
|
||||||
|
atoi(ipAddress[0]));
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->orig.orig.sdpAddr.u.ip4.u.ip.b[1]),
|
||||||
|
atoi(ipAddress[1]));
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->orig.orig.sdpAddr.u.ip4.u.ip.b[2]),
|
||||||
|
atoi(ipAddress[2]));
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->orig.orig.sdpAddr.u.ip4.u.ip.b[3]),
|
||||||
|
atoi(ipAddress[3]));
|
||||||
|
|
||||||
|
/* fill session name */
|
||||||
|
MG_SET_TKNSTROSXL(psdp->info[psdp->numComp.val-1]->sessName, 8, "SANGOMA", memCp);
|
||||||
|
|
||||||
|
|
||||||
|
/* Fill the SDP Connection Info */
|
||||||
|
/* "c=" line - ipaddress */
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->conn.netType.type),CM_SDP_NET_TYPE_IN);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->conn.addrType), CM_SDP_ADDR_TYPE_IPV4);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->conn.u.ip4.addrType), CM_SDP_IPV4_IP_UNI);
|
||||||
|
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->conn.u.ip4.u.uniIp.b[0]), atoi(ipAddress[0]));
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->conn.u.ip4.u.uniIp.b[1]), atoi(ipAddress[1]));
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->conn.u.ip4.u.uniIp.b[2]), atoi(ipAddress[2]));
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->conn.u.ip4.u.uniIp.b[3]), atoi(ipAddress[3]));
|
||||||
|
|
||||||
|
|
||||||
|
/* t= line */
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->sdpTime.pres),1);
|
||||||
|
#if 0
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->sdpTime.sdpOpTimeSet.numComp),0);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->sdpTime.zoneAdjSet.numComp),0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
med = &psdp->info[psdp->numComp.val-1]->mediaDescSet;
|
||||||
|
ret = mg_add_lcl_media(med, mg_profile, term, memCp);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/*****************************************************************************************************************************/
|
||||||
|
switch_status_t mg_add_supported_media_codec(CmSdpMediaDesc* media, megaco_profile_t* mg_profile, mg_termination_t* term, CmMemListCp *memCp)
|
||||||
|
{
|
||||||
|
const switch_codec_implementation_t *codecs[16];
|
||||||
|
char *codec_prefs[16] = { 0 };
|
||||||
|
char *szcodec_prefs;
|
||||||
|
int codec_count;
|
||||||
|
int i;
|
||||||
|
int fmt= 0x00;
|
||||||
|
|
||||||
|
switch_assert(media);
|
||||||
|
switch_assert(mg_profile);
|
||||||
|
switch_assert(term);
|
||||||
|
switch_assert(memCp);
|
||||||
|
|
||||||
|
szcodec_prefs = strdup(mg_profile->codec_prefs);
|
||||||
|
codec_count = switch_split(szcodec_prefs, ',', codec_prefs);
|
||||||
|
|
||||||
|
/* Get the list of codecs, by preference */
|
||||||
|
switch_loadable_module_get_codecs_sorted(codecs, switch_arraylen(codecs), codec_prefs, switch_arraylen(codec_prefs));
|
||||||
|
for (i = 0; codecs[i] && i < codec_count; i++) {
|
||||||
|
int pt = codecs[i]->ianacode;
|
||||||
|
const char *name = codecs[i]->iananame;
|
||||||
|
|
||||||
|
printf("Preference %d is %s/%d\n", i, name, pt);
|
||||||
|
|
||||||
|
|
||||||
|
if (mgUtlGrowList((void ***)&media->field.par.pflst[media->field.par.numProtFmts.val-1]->u.rtp.fmts, sizeof(CmSdpU8OrNil),
|
||||||
|
&media->field.par.pflst[media->field.par.numProtFmts.val-1]->u.rtp.num, memCp) != ROK)
|
||||||
|
{
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR,"Grow List failed\n");
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
fmt = media->field.par.pflst[media->field.par.numProtFmts.val-1]->u.rtp.num.val-1;
|
||||||
|
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->field.par.pflst[media->field.par.numProtFmts.val-1]->u.rtp.fmts[fmt]->type), CM_SDP_SPEC);
|
||||||
|
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->field.par.pflst[media->field.par.numProtFmts.val-1]->u.rtp.fmts[fmt]->val), pt);
|
||||||
|
|
||||||
|
/* add associated attributes */
|
||||||
|
{
|
||||||
|
if (mgUtlGrowList((void ***)&media->attrSet.attr, sizeof(CmSdpAttr), &media->attrSet.numComp, memCp) != ROK)
|
||||||
|
{
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR,"Grow List failed\n");
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->attrSet.attr[media->attrSet.numComp.val-1]->type),CM_SDP_ATTR_RTPMAP);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->attrSet.attr[media->attrSet.numComp.val-1]->u.rtpmap.pres), 1);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->attrSet.attr[media->attrSet.numComp.val-1]->u.rtpmap.pay.type), CM_SDP_SPEC);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->attrSet.attr[media->attrSet.numComp.val-1]->u.rtpmap.pay.val), pt);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->attrSet.attr[media->attrSet.numComp.val-1]->u.rtpmap.enc.val), CM_SDP_ENC_UNKNOWN);
|
||||||
|
MG_SET_TKNSTROSXL((media->attrSet.attr[media->attrSet.numComp.val-1]->u.rtpmap.enc.name), strlen(name), name, memCp);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->attrSet.attr[media->attrSet.numComp.val-1]->u.rtpmap.clk), codecs[i]->samples_per_second);
|
||||||
|
/* encoding parameter not required to fill */
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
free(szcodec_prefs);
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
/*****************************************************************************************************************************/
|
||||||
|
switch_status_t mg_add_lcl_media(CmSdpMediaDescSet* med, megaco_profile_t* mg_profile, mg_termination_t* term, CmMemListCp *memCp)
|
||||||
|
{
|
||||||
|
CmSdpMediaDesc* media;
|
||||||
|
|
||||||
|
switch_assert(med);
|
||||||
|
switch_assert(mg_profile);
|
||||||
|
switch_assert(term);
|
||||||
|
switch_assert(memCp);
|
||||||
|
|
||||||
|
if (mgUtlGrowList((void ***)&med->mediaDesc, sizeof(CmSdpMediaDesc),
|
||||||
|
&med->numComp, memCp) != ROK)
|
||||||
|
{
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR,"Grow List failed\n");
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
media = med->mediaDesc[med->numComp.val-1];
|
||||||
|
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->pres),1);
|
||||||
|
|
||||||
|
/* Fill CmSdpMediaField */
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->field.pres),1);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->field.mediaType),CM_SDP_MEDIA_AUDIO);
|
||||||
|
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->field.id.type),CM_SDP_VCID_PORT);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->field.id.u.port.type),CM_SDP_PORT_INT);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->field.id.u.port.u.portInt.pres),1);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->field.id.u.port.u.portInt.port.type), CM_SDP_SPEC);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->field.id.u.port.u.portInt.port.val), term->u.rtp.local_port);
|
||||||
|
|
||||||
|
if (mgUtlGrowList((void ***)&media->field.par.pflst, sizeof(CmSdpMedProtoFmts),
|
||||||
|
&media->field.par.numProtFmts, memCp) != ROK)
|
||||||
|
{
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR,"Grow List failed\n");
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CmSdpMedProtoFmts */
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->field.par.pflst[media->field.par.numProtFmts.val-1]->prot.type), CM_SDP_MEDIA_PROTO_RTP);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->field.par.pflst[media->field.par.numProtFmts.val-1]->prot.u.subtype.type), CM_SDP_PROTO_RTP_AVP);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->field.par.pflst[media->field.par.numProtFmts.val-1]->protType), CM_SDP_MEDIA_PROTO_RTP);
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************************************************************************************************/
|
||||||
|
/* Fill ptime attribute */
|
||||||
|
{
|
||||||
|
if (mgUtlGrowList((void ***)&media->attrSet.attr, sizeof(CmSdpAttr), &media->attrSet.numComp, memCp) != ROK)
|
||||||
|
{
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR,"Grow List failed\n");
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->attrSet.attr[media->attrSet.numComp.val-1]->type),CM_SDP_ATTR_PTIME);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->attrSet.attr[media->attrSet.numComp.val-1]->u.ptime), term->u.rtp.ptime);
|
||||||
|
}
|
||||||
|
/***************************************************************************************************************************************************************/
|
||||||
|
/* fill codec info */
|
||||||
|
mg_add_supported_media_codec(media, mg_profile, term, memCp);
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
/***************************************************************************************************************************************************************/
|
||||||
|
|
||||||
|
switch_status_t mg_rem_unsupported_codecs (megaco_profile_t* mg_profile, mg_termination_t* term, CmSdpMedFmtRtpList *fmtList, CmSdpAttrSet *attrSet, CmMemListCp *memCp)
|
||||||
|
{
|
||||||
|
int i = 0x00;
|
||||||
|
int id = 0x00;
|
||||||
|
int j = 0x00;
|
||||||
|
int a = 0x00;
|
||||||
|
CmSdpU8OrNil *fmt = NULL;
|
||||||
|
int foundCodec = 0x00;
|
||||||
|
const switch_codec_implementation_t *codecs[16];
|
||||||
|
char *codec_prefs[16] = { 0 };
|
||||||
|
char *szcodec_prefs;
|
||||||
|
int codec_count;
|
||||||
|
CmSdpAttr *attr = NULL;
|
||||||
|
CmSdpAttrRtpMap *rtp = NULL;
|
||||||
|
|
||||||
|
/* Check if code list is present */
|
||||||
|
if (!fmtList || (NOTPRSNT == fmtList->num.pres))
|
||||||
|
{
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "codec List Not present\n");
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
szcodec_prefs = strdup(mg_profile->codec_prefs);
|
||||||
|
codec_count = switch_split(szcodec_prefs, ',', codec_prefs);
|
||||||
|
|
||||||
|
/* Get the list of codecs, by preference */
|
||||||
|
switch_loadable_module_get_codecs_sorted(codecs, switch_arraylen(codecs), codec_prefs, switch_arraylen(codec_prefs));
|
||||||
|
|
||||||
|
|
||||||
|
/* codec type is specified one */
|
||||||
|
|
||||||
|
/* loop through coddec list and remove un-supported codec */
|
||||||
|
for(i = 0; i < fmtList->num.val; i++)
|
||||||
|
{
|
||||||
|
foundCodec = 0x00;
|
||||||
|
fmt = fmtList->fmts[i];
|
||||||
|
|
||||||
|
if((NOTPRSNT == fmt->type.pres) || (NOTPRSNT == fmt->val.pres)) continue;
|
||||||
|
|
||||||
|
if(CM_SDP_SPEC != fmt->type.val) continue; /* TODO - need to see for other cases like CM_SDP_NIL/CM_SDP_CHOICE etc not sure as of now */
|
||||||
|
|
||||||
|
|
||||||
|
/* see if received codec is present in our codec supported list */
|
||||||
|
for (id = 0; codecs[id] && id < codec_count; id++) {
|
||||||
|
int pt = codecs[id]->ianacode;
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Matching recv codec[%d] with supported codec[%d] \n", fmt->val.val, pt);
|
||||||
|
//const char *name = codecs[id]->iananame;
|
||||||
|
if(pt == fmt->val.val){
|
||||||
|
foundCodec = 0x01;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IF codec not found in list, remove it */
|
||||||
|
if(!foundCodec) {
|
||||||
|
|
||||||
|
for(j = i; j < fmtList->num.val - 1; j++)
|
||||||
|
{
|
||||||
|
fmtList->fmts[j] = fmtList->fmts[j +1];
|
||||||
|
}
|
||||||
|
mgUtlShrinkList((Void ***)&fmtList->fmts, sizeof(CmSdpU8OrNil), &fmtList->num, memCp);
|
||||||
|
i-- ;
|
||||||
|
|
||||||
|
/* remove associated a= , if present */
|
||||||
|
if((NOTPRSNT != attrSet->numComp.pres) && (0 != attrSet->numComp.val)){
|
||||||
|
for(a = 0; a < attrSet->numComp.val; a++) {
|
||||||
|
attr = attrSet->attr[a];
|
||||||
|
|
||||||
|
if(CM_SDP_ATTR_RTPMAP != attr->type.val) continue; /* as of now only checking RTPMAP */
|
||||||
|
|
||||||
|
rtp = &attr->u.rtpmap;
|
||||||
|
|
||||||
|
if((NOTPRSNT != rtp->pres.pres) && (fmt->val.val == rtp->pay.val.val)) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "a line found against codec[%d]..Removing a line \n", fmt->val.val);
|
||||||
|
|
||||||
|
/* mgUtlShrinkList API will delete last node from list, hence suffling list nodes */
|
||||||
|
for(j = a; j < attrSet->numComp.val - 1; j++)
|
||||||
|
{
|
||||||
|
attrSet->attr[j] = attrSet->attr[j +1];
|
||||||
|
}
|
||||||
|
mgUtlShrinkList((Void ***)&attrSet->attr, sizeof(CmSdpAttr), &attrSet->numComp, memCp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(0 == fmtList->num.val) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "No Supported codec found in offer, Rejecting request \n");
|
||||||
|
term->mg_error_code = switch_core_alloc(term->pool, sizeof(term->mg_error_code));
|
||||||
|
*term->mg_error_code = MGT_MGCP_RSP_CODE_INCONSISTENT_LCL_OPT;
|
||||||
|
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************************************************************/
|
||||||
|
switch_status_t mg_build_sdp(MgMgcoMediaDesc* out, MgMgcoMediaDesc* inc, megaco_profile_t* mg_profile, mg_termination_t* term, CmMemListCp *memCp)
|
||||||
|
{
|
||||||
|
CmSdpU8OrNil *fmt = NULL;
|
||||||
|
CmSdpInfoSet *psdp = NULL;
|
||||||
|
char* ipAddress[4];
|
||||||
|
int i = 0x00;
|
||||||
|
int j = 0x00;
|
||||||
|
int choose_codec = 0x00;
|
||||||
|
int k = 0x00;
|
||||||
|
MgMgcoLocalDesc *local = NULL;
|
||||||
|
int fresh_sdp = 0x00;
|
||||||
|
char* dup = NULL;
|
||||||
|
CmSdpMedProtoFmts *format=NULL;
|
||||||
|
|
||||||
|
|
||||||
|
switch_assert(out);
|
||||||
|
switch_assert(inc);
|
||||||
|
switch_assert(mg_profile);
|
||||||
|
switch_assert(term);
|
||||||
|
|
||||||
|
dup = strdup((char*)term->u.rtp.local_addr);
|
||||||
|
switch_split(dup,'.',ipAddress);
|
||||||
|
|
||||||
|
|
||||||
|
if((NOTPRSNT == inc->num.pres) || (0 == inc->num.val)){
|
||||||
|
fresh_sdp = 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if its fresh sdp then add only local descriptor */
|
||||||
|
if(fresh_sdp) {
|
||||||
|
mg_add_local_descriptor(out, mg_profile, term, memCp);
|
||||||
|
} else {
|
||||||
|
/* incoming has sdp, so copy that sdp and overwrite only local sdp */
|
||||||
|
mgUtlCpyMgMgcoMediaDesc(out, inc, memCp);
|
||||||
|
|
||||||
|
/* now see if we have local descriptor, then pick up that and modify the fields */
|
||||||
|
|
||||||
|
if((NOTPRSNT != out->num.pres) && (0 != out->num.val))
|
||||||
|
{
|
||||||
|
for(i=0; i<out->num.val; i++) {
|
||||||
|
if(MGT_MEDIAPAR_LOCAL == out->parms[i]->type.val) {
|
||||||
|
local = &out->parms[i]->u.local;
|
||||||
|
break;
|
||||||
|
} else if(MGT_MEDIAPAR_STRPAR == out->parms[i]->type.val){
|
||||||
|
MgMgcoStreamDesc *stream = &out->parms[i]->u.stream;
|
||||||
|
if((NOTPRSNT != stream->sl.pres.pres) && (NOTPRSNT != stream->sl.local.pres.pres)){
|
||||||
|
local = &stream->sl.local;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!local || (NOTPRSNT == local->sdp.numComp.pres) || (0 == local->sdp.numComp.val)){
|
||||||
|
/* local sdp is not part of media descriptor, then add local sdp*/
|
||||||
|
mg_add_local_descriptor(out, mg_profile, term, memCp);
|
||||||
|
}else{
|
||||||
|
/* local sdp is present.. now go over the local descriptor and modify fields */
|
||||||
|
psdp = &(local->sdp);
|
||||||
|
|
||||||
|
for(i=0; i< psdp->numComp.val; i++) {
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
/* version - let it be same, if present else use version 1 */
|
||||||
|
if(NOTPRSNT == psdp->info[psdp->numComp.val-1]->ver.pres) {
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->ver),1);
|
||||||
|
}
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
/* orig (o- line) fill with our info */
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->orig.pres), 1);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->orig.type), CM_SDP_SPEC);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->orig.orig.pres), 1);
|
||||||
|
|
||||||
|
MG_SET_TKNSTROSXL(psdp->info[psdp->numComp.val-1]->orig.orig.usrName, 1, "-", memCp);
|
||||||
|
MG_SET_TKNSTROSXL(psdp->info[psdp->numComp.val-1]->orig.orig.sessId, 1, "0", memCp);
|
||||||
|
MG_SET_TKNSTROSXL(psdp->info[psdp->numComp.val-1]->orig.orig.sessVer, 1, "0", memCp);
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->orig.orig.sdpAddr.netType.type),
|
||||||
|
CM_SDP_NET_TYPE_IN);
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->orig.orig.sdpAddr.addrType),
|
||||||
|
CM_SDP_ADDR_TYPE_IPV4);
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->orig.orig.sdpAddr.u.ip4.addrType),
|
||||||
|
CM_SDP_IPV4_IP_UNI);
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->orig.orig.sdpAddr.u.ip4.addrType),
|
||||||
|
CM_SDP_IPV4_IP_UNI);
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->orig.orig.sdpAddr.u.ip4.u.ip.b[0]),
|
||||||
|
atoi(ipAddress[0]));
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->orig.orig.sdpAddr.u.ip4.u.ip.b[1]),
|
||||||
|
atoi(ipAddress[1]));
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->orig.orig.sdpAddr.u.ip4.u.ip.b[2]),
|
||||||
|
atoi(ipAddress[2]));
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->orig.orig.sdpAddr.u.ip4.u.ip.b[3]),
|
||||||
|
atoi(ipAddress[3]));
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
/* session-name , let it be like this if present, else skip it */
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
/* "c=" line - ipaddress */
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->conn.netType.type),CM_SDP_NET_TYPE_IN);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->conn.addrType), CM_SDP_ADDR_TYPE_IPV4);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->conn.u.ip4.addrType), CM_SDP_IPV4_IP_UNI);
|
||||||
|
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->conn.u.ip4.u.uniIp.b[0]), atoi(ipAddress[0]));
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->conn.u.ip4.u.uniIp.b[1]), atoi(ipAddress[1]));
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->conn.u.ip4.u.uniIp.b[2]), atoi(ipAddress[2]));
|
||||||
|
MG_SET_VAL_PRES( (psdp->info[psdp->numComp.val-1]->conn.u.ip4.u.uniIp.b[3]), atoi(ipAddress[3]));
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
/* t= line */
|
||||||
|
MG_INIT_TOKEN_VALUE(&(psdp->info[psdp->numComp.val-1]->sdpTime.pres),1);
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
/* fill media descriptors */
|
||||||
|
{
|
||||||
|
CmSdpMediaDescSet* med = &psdp->info[psdp->numComp.val-1]->mediaDescSet;
|
||||||
|
CmSdpMediaDesc* media;
|
||||||
|
|
||||||
|
if((NOTPRSNT == med->numComp.pres) || (0 == med->numComp.val)){
|
||||||
|
mg_add_lcl_media(med, mg_profile, term, memCp);
|
||||||
|
}else{
|
||||||
|
for(j =0;j < med->numComp.val; j++){
|
||||||
|
media = med->mediaDesc[j];
|
||||||
|
/* check for choose port and fill the port */
|
||||||
|
if(NOTPRSNT != media->field.id.type.pres){
|
||||||
|
if(CM_SDP_VCID_CHOOSE == media->field.id.type.val){
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->field.id.type),CM_SDP_VCID_PORT);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->field.id.u.port.type),CM_SDP_PORT_INT);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->field.id.u.port.u.portInt.pres),1);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->field.id.u.port.u.portInt.port.type), CM_SDP_SPEC);
|
||||||
|
MG_INIT_TOKEN_VALUE(&(media->field.id.u.port.u.portInt.port.val), term->u.rtp.local_port);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for codec */
|
||||||
|
if((NOTPRSNT == media->field.par.numProtFmts.pres) ||
|
||||||
|
(0 == media->field.par.numProtFmts.val)){
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR,"No codec specified in incoming local descriptor \n");
|
||||||
|
mg_add_supported_media_codec(media, mg_profile, term, memCp );
|
||||||
|
}else{
|
||||||
|
/* check for media format/codec */
|
||||||
|
for(k =0;k < media->field.par.numProtFmts.val; k++){
|
||||||
|
format = media->field.par.pflst[k];
|
||||||
|
if ((NOTPRSNT != format->protType.pres) &&
|
||||||
|
(CM_SDP_MEDIA_PROTO_RTP == format->protType.val))
|
||||||
|
{
|
||||||
|
if((NOTPRSNT != format->u.rtp.num.pres)
|
||||||
|
&&(0 != format->u.rtp.num.val))
|
||||||
|
{
|
||||||
|
/* If the codec type is CHOOSE then we need to fill our list */
|
||||||
|
for(i = 0; i < format->u.rtp.num.val; i++)
|
||||||
|
{
|
||||||
|
fmt = format->u.rtp.fmts[i];
|
||||||
|
|
||||||
|
if((NOTPRSNT == fmt->type.pres) || (NOTPRSNT == fmt->val.pres)) continue;
|
||||||
|
|
||||||
|
if(CM_SDP_CHOOSE == fmt->type.val){
|
||||||
|
choose_codec = 0x1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(choose_codec){
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "CHOOSE codec is requested fill out supported codecs \n");
|
||||||
|
|
||||||
|
/* delete existing rtp format list..TODO find better way */
|
||||||
|
for(i = 0; i < format->u.rtp.num.val; i++)
|
||||||
|
{
|
||||||
|
mgUtlShrinkList((Void ***)&format->u.rtp.fmts, sizeof(CmSdpU8OrNil), &format->u.rtp.num, memCp);
|
||||||
|
}
|
||||||
|
/* If the codec type is CHOOSE then we need to fill our list */
|
||||||
|
mg_add_supported_media_codec(media, mg_profile, term, memCp);
|
||||||
|
}
|
||||||
|
else if (!choose_codec && (SWITCH_STATUS_FALSE == mg_rem_unsupported_codecs(mg_profile, term , &format->u.rtp, &media->attrSet, memCp)))
|
||||||
|
{
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload)
|
||||||
// <map termination-id-prefix="Term1/" termination-id-base="1" tech="freetdm" channel-prefix="wp2" channel-map"1-15,17-31"/>
|
// <map termination-id-prefix="Term1/" termination-id-base="1" tech="freetdm" channel-prefix="wp2" channel-map"1-15,17-31"/>
|
||||||
const char *prefix = switch_xml_attr(mg_term, "termination-id-prefix");
|
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 *sztermination_id_base = switch_xml_attr(mg_term, "termination-id-base");
|
||||||
//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");
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload)
|
||||||
char *channel_map_dup = strdup(channel_map);
|
char *channel_map_dup = strdup(channel_map);
|
||||||
char *chanmap[24];
|
char *chanmap[24];
|
||||||
int chanmap_count, i;
|
int chanmap_count, i;
|
||||||
chanmap_count = switch_split(channel_map_dup, ' ', chanmap);
|
chanmap_count = switch_split(channel_map_dup, ',', chanmap);
|
||||||
for (i = 0; i < chanmap_count; i++) {
|
for (i = 0; i < chanmap_count; i++) {
|
||||||
char *p = strchr(chanmap[i], '-');
|
char *p = strchr(chanmap[i], '-');
|
||||||
if (p) {
|
if (p) {
|
||||||
|
@ -100,7 +100,8 @@ 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->mg_ctxt = NULL;
|
term->mg_ctxt = NULL;
|
||||||
term->active_events = NULL;
|
term->tech = switch_core_strdup(pool, tech);
|
||||||
|
term->active_events = NULL;
|
||||||
term->name = switch_core_sprintf(pool, "%s%d", prefix, j);
|
term->name = switch_core_sprintf(pool, "%s%d", prefix, j);
|
||||||
term->u.tdm.channel = j;
|
term->u.tdm.channel = j;
|
||||||
term->u.tdm.span_name = switch_core_strdup(pool, channel_prefix);
|
term->u.tdm.span_name = switch_core_strdup(pool, channel_prefix);
|
||||||
|
@ -110,6 +111,8 @@ switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload)
|
||||||
profile->physical_terminations = term;
|
profile->physical_terminations = term;
|
||||||
|
|
||||||
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);
|
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);
|
||||||
|
|
||||||
|
megaco_prepare_tdm_termination(term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,6 +263,7 @@ static switch_xml_config_item_t *get_instructions(megaco_profile_t *profile) {
|
||||||
SWITCH_CONFIG_ITEM("rtp-port-range", SWITCH_CONFIG_STRING, CONFIG_REQUIRED, &profile->rtp_port_range, "1-65535", &switch_config_string_strdup, "", "rtp port range"),
|
SWITCH_CONFIG_ITEM("rtp-port-range", SWITCH_CONFIG_STRING, CONFIG_REQUIRED, &profile->rtp_port_range, "1-65535", &switch_config_string_strdup, "", "rtp port range"),
|
||||||
SWITCH_CONFIG_ITEM("rtp-termination-id-prefix", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->rtp_termination_id_prefix, "", &switch_config_string_strdup, "", "rtp termination prefix"),
|
SWITCH_CONFIG_ITEM("rtp-termination-id-prefix", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->rtp_termination_id_prefix, "", &switch_config_string_strdup, "", "rtp termination prefix"),
|
||||||
SWITCH_CONFIG_ITEM("rtp-termination-id-len", SWITCH_CONFIG_INT, CONFIG_RELOADABLE, &profile->rtp_termination_id_len, "", &opt_termination_id_len, "", "rtp termination id"),
|
SWITCH_CONFIG_ITEM("rtp-termination-id-len", SWITCH_CONFIG_INT, CONFIG_RELOADABLE, &profile->rtp_termination_id_len, "", &opt_termination_id_len, "", "rtp termination id"),
|
||||||
|
SWITCH_CONFIG_ITEM("codec-prefs", SWITCH_CONFIG_STRING, 0, &profile->codec_prefs, "", &switch_config_string_strdup, "", "codec preferences, coma-separated"),
|
||||||
SWITCH_CONFIG_ITEM_END()
|
SWITCH_CONFIG_ITEM_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,54 @@ static switch_status_t list_profiles(const char *line, const char *cursor, switc
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mg_event_handler(switch_event_t *event)
|
||||||
|
{
|
||||||
|
switch(event->event_id) {
|
||||||
|
case SWITCH_EVENT_TRAP:
|
||||||
|
{
|
||||||
|
const char *span_name = NULL;
|
||||||
|
const char *chan_number = NULL;
|
||||||
|
const char *cond = NULL;
|
||||||
|
const char *mg_profile_name = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
cond = switch_event_get_header(event, "condition");
|
||||||
|
if (zstr(cond)) {
|
||||||
|
printf("Condition NULL, returning \n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mg_profile_name = switch_event_get_header(event, "mg-profile-name");
|
||||||
|
if (zstr(mg_profile_name)) {
|
||||||
|
printf("mg_profile_name NULL, returning \n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
span_name = switch_event_get_header(event, "span-name");
|
||||||
|
chan_number = switch_event_get_header(event, "chan-number");
|
||||||
|
|
||||||
|
if (!strcmp(cond, "ftdm-alarm-trap")) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
|
||||||
|
"ftdm-alarm-trap for span_name[%s] chan_number[%s] associated with MG profile[%s]\n",
|
||||||
|
span_name,chan_number, mg_profile_name);
|
||||||
|
/* @KAPIL: TDM is in alarm, notify MGC */
|
||||||
|
mg_send_term_service_change(
|
||||||
|
(char*)mg_profile_name, (char*)span_name, (char*)chan_number, MG_TERM_SERVICE_STATE_OUT_OF_SERVICE);
|
||||||
|
} else if (!strcmp(cond, "ftdm-alarm-clear")) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
|
||||||
|
"ftdm-alarm-clear for span_name[%s] chan_number[%s] associated with MG profile[%s] \n",
|
||||||
|
span_name,chan_number, mg_profile_name);
|
||||||
|
/* TDM alarm cleared, notify MGC */
|
||||||
|
mg_send_term_service_change(
|
||||||
|
(char*)mg_profile_name, (char*)span_name, (char*)chan_number, MG_TERM_SERVICE_STATE_IN_SERVICE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_MODULE_LOAD_FUNCTION(mod_media_gateway_load)
|
SWITCH_MODULE_LOAD_FUNCTION(mod_media_gateway_load)
|
||||||
{
|
{
|
||||||
switch_api_interface_t *api_interface;
|
switch_api_interface_t *api_interface;
|
||||||
|
@ -82,7 +130,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_media_gateway_load)
|
||||||
switch_console_set_complete("add mg logging ::mg::list_profiles disable");
|
switch_console_set_complete("add mg logging ::mg::list_profiles disable");
|
||||||
switch_console_add_complete_func("::mg::list_profiles", list_profiles);
|
switch_console_add_complete_func("::mg::list_profiles", list_profiles);
|
||||||
|
|
||||||
|
|
||||||
/* Initialize MEGACO Stack */
|
/* Initialize MEGACO Stack */
|
||||||
sng_event.mg.sng_mgco_txn_ind = handle_mgco_txn_ind;
|
sng_event.mg.sng_mgco_txn_ind = handle_mgco_txn_ind;
|
||||||
sng_event.mg.sng_mgco_cmd_ind = handle_mgco_cmd_ind;
|
sng_event.mg.sng_mgco_cmd_ind = handle_mgco_cmd_ind;
|
||||||
|
@ -96,6 +143,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_media_gateway_load)
|
||||||
/* Log */
|
/* Log */
|
||||||
sng_event.sm.sng_log = handle_sng_log;
|
sng_event.sm.sng_log = handle_sng_log;
|
||||||
|
|
||||||
|
switch_event_bind("mod_media_gateway", SWITCH_EVENT_TRAP, SWITCH_EVENT_SUBCLASS_ANY, mg_event_handler, NULL);
|
||||||
|
|
||||||
/* initualize MEGACO stack */
|
/* initualize MEGACO stack */
|
||||||
return sng_mgco_init(&sng_event);
|
return sng_mgco_init(&sng_event);
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,9 @@ struct mg_termination_s {
|
||||||
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 */
|
||||||
mg_context_t* mg_ctxt;
|
mg_context_t* mg_ctxt;
|
||||||
|
int *mg_error_code; /* MEGACO error code */
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
const char *tech; /* Endpoint controlling the TDM interface - only FreeTDM tested so far */
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
|
@ -235,6 +237,7 @@ void megaco_release_context(mg_context_t *ctx);
|
||||||
switch_status_t megaco_context_sub_termination(mg_context_t *ctx, mg_termination_t *term);
|
switch_status_t megaco_context_sub_termination(mg_context_t *ctx, mg_termination_t *term);
|
||||||
switch_status_t megaco_context_sub_all_termination(mg_context_t *ctx);
|
switch_status_t megaco_context_sub_all_termination(mg_context_t *ctx);
|
||||||
switch_status_t megaco_activate_termination(mg_termination_t *term);
|
switch_status_t megaco_activate_termination(mg_termination_t *term);
|
||||||
|
switch_status_t megaco_prepare_termination(mg_termination_t *term);
|
||||||
|
|
||||||
mg_termination_t *megaco_choose_termination(megaco_profile_t *profile, const char *prefix);
|
mg_termination_t *megaco_choose_termination(megaco_profile_t *profile, const char *prefix);
|
||||||
mg_termination_t *megaco_find_termination(megaco_profile_t *profile, const char *name);
|
mg_termination_t *megaco_find_termination(megaco_profile_t *profile, const char *name);
|
||||||
|
@ -253,7 +256,8 @@ switch_status_t mg_process_cli_cmd(const char *cmd, switch_stream_handle_t *stre
|
||||||
switch_status_t megaco_context_add_termination(mg_context_t *ctx, mg_termination_t *term);
|
switch_status_t megaco_context_add_termination(mg_context_t *ctx, mg_termination_t *term);
|
||||||
switch_status_t megaco_context_is_term_present(mg_context_t *ctx, mg_termination_t *term);
|
switch_status_t megaco_context_is_term_present(mg_context_t *ctx, mg_termination_t *term);
|
||||||
|
|
||||||
|
switch_status_t megaco_prepare_tdm_termination(mg_termination_t *term);
|
||||||
|
switch_status_t megaco_check_tdm_termination(mg_termination_t *term);
|
||||||
#endif /* MOD_MEGACO_H */
|
#endif /* MOD_MEGACO_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -421,17 +421,26 @@ static switch_status_t channel_receive_event(switch_core_session_t *session, swi
|
||||||
const char *command = switch_event_get_header(event, "command");
|
const char *command = switch_event_get_header(event, "command");
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||||
crtp_private_t *tech_pvt = switch_core_session_get_private(session);
|
crtp_private_t *tech_pvt = switch_core_session_get_private(session);
|
||||||
|
char *codec = switch_event_get_header_nil(event, kCODEC);
|
||||||
|
char *szptime = switch_event_get_header_nil(event, kPTIME);
|
||||||
|
char *szrate = switch_event_get_header_nil(event, kRATE);
|
||||||
|
char *szpt = switch_event_get_header_nil(event, kPT);
|
||||||
|
|
||||||
|
int ptime = !zstr(szptime) ? atoi(szptime) : 0,
|
||||||
|
rate = !zstr(szrate) ? atoi(szrate) : 8000,
|
||||||
|
pt = !zstr(szpt) ? atoi(szpt) : 0;
|
||||||
|
|
||||||
|
|
||||||
if (!zstr(command) && !strcasecmp(command, "media_modify")) {
|
if (!zstr(command) && !strcasecmp(command, "media_modify")) {
|
||||||
/* Compare parameters */
|
/* Compare parameters */
|
||||||
if (compare_var(event, channel, kREMOTEADDR) ||
|
if (compare_var(event, channel, kREMOTEADDR) ||
|
||||||
compare_var(event, channel, kREMOTEPORT)) {
|
compare_var(event, channel, kREMOTEPORT)) {
|
||||||
char *remote_addr = switch_event_get_header(event, kREMOTEADDR);
|
char *remote_addr = switch_event_get_header(event, kREMOTEADDR);
|
||||||
char *szremote_port = switch_event_get_header(event, kREMOTEPORT);
|
char *szremote_port = switch_event_get_header(event, kREMOTEPORT);
|
||||||
switch_port_t remote_port = !zstr(szremote_port) ? atoi(szremote_port) : 0;
|
switch_port_t remote_port = !zstr(szremote_port) ? atoi(szremote_port) : 0;
|
||||||
const char *err;
|
const char *err;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
switch_channel_set_variable(channel, kREMOTEADDR, remote_addr);
|
switch_channel_set_variable(channel, kREMOTEADDR, remote_addr);
|
||||||
switch_channel_set_variable(channel, kREMOTEPORT, szremote_port);
|
switch_channel_set_variable(channel, kREMOTEPORT, szremote_port);
|
||||||
|
|
||||||
|
@ -446,10 +455,47 @@ static switch_status_t channel_receive_event(switch_core_session_t *session, swi
|
||||||
if (compare_var(event, channel, kCODEC) ||
|
if (compare_var(event, channel, kCODEC) ||
|
||||||
compare_var(event, channel, kPTIME) ||
|
compare_var(event, channel, kPTIME) ||
|
||||||
compare_var(event, channel, kPT) ||
|
compare_var(event, channel, kPT) ||
|
||||||
compare_var(event, channel, kRATE)) {
|
compare_var(event, channel, kRATE)) {
|
||||||
/* Reset codec */
|
/* Reset codec */
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Switching codec not yet implemented\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Switching codec updating \n");
|
||||||
}
|
|
||||||
|
if (switch_core_codec_init(&tech_pvt->read_codec,
|
||||||
|
codec,
|
||||||
|
NULL,
|
||||||
|
rate,
|
||||||
|
ptime,
|
||||||
|
1,
|
||||||
|
/*SWITCH_CODEC_FLAG_ENCODE |*/ SWITCH_CODEC_FLAG_DECODE,
|
||||||
|
NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
|
||||||
|
goto fail;
|
||||||
|
} else {
|
||||||
|
if (switch_core_codec_init(&tech_pvt->write_codec,
|
||||||
|
codec,
|
||||||
|
NULL,
|
||||||
|
rate,
|
||||||
|
ptime,
|
||||||
|
1,
|
||||||
|
SWITCH_CODEC_FLAG_ENCODE /*| SWITCH_CODEC_FLAG_DECODE*/,
|
||||||
|
NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switch_core_session_set_read_codec(session, &tech_pvt->read_codec) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set read codec?\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switch_core_session_set_write_codec(session, &tech_pvt->write_codec) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set write codec?\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_rtp_set_default_payload(tech_pvt->rtp_session, pt);
|
||||||
|
switch_rtp_set_recv_pt(tech_pvt->rtp_session, pt);
|
||||||
|
}
|
||||||
|
|
||||||
if (compare_var(event, channel, kRFC2833PT)) {
|
if (compare_var(event, channel, kRFC2833PT)) {
|
||||||
const char *szpt = switch_channel_get_variable(channel, kRFC2833PT);
|
const char *szpt = switch_channel_get_variable(channel, kRFC2833PT);
|
||||||
|
@ -464,6 +510,22 @@ static switch_status_t channel_receive_event(switch_core_session_t *session, swi
|
||||||
}
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
fail:
|
||||||
|
if (tech_pvt) {
|
||||||
|
if (tech_pvt->read_codec.implementation) {
|
||||||
|
switch_core_codec_destroy(&tech_pvt->read_codec);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tech_pvt->write_codec.implementation) {
|
||||||
|
switch_core_codec_destroy(&tech_pvt->write_codec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session) {
|
||||||
|
switch_core_session_destroy(&session);
|
||||||
|
}
|
||||||
|
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
|
static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
|
||||||
|
|
Loading…
Reference in New Issue