Merge branch 'master' of ssh://git.freeswitch.org/freeswitch
This commit is contained in:
commit
673678509f
|
@ -386,7 +386,11 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
|
||||||
case FTDM_CHANNEL_STATE_PROCEED:
|
case FTDM_CHANNEL_STATE_PROCEED:
|
||||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||||
case FTDM_CHANNEL_STATE_RINGING:
|
case FTDM_CHANNEL_STATE_RINGING:
|
||||||
if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) {
|
if ((cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) ||
|
||||||
|
(cnStEvnt->progInd1.eh.pres && cnStEvnt->progInd1.progDesc.val == IN_PD_IBAVAIL) ||
|
||||||
|
(cnStEvnt->progInd2.eh.pres && cnStEvnt->progInd2.progDesc.val == IN_PD_IBAVAIL) ||
|
||||||
|
(cnStEvnt->progInd3.eh.pres && cnStEvnt->progInd3.progDesc.val == IN_PD_IBAVAIL)) {
|
||||||
|
|
||||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media available\n");
|
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media available\n");
|
||||||
sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY);
|
sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -135,7 +135,9 @@ void dump_chan_xml(zap_span_t *span, uint32_t chan_id, switch_stream_handle_t *s
|
||||||
|
|
||||||
static void zap_set_npi(const char *npi_string, uint8_t *target)
|
static void zap_set_npi(const char *npi_string, uint8_t *target)
|
||||||
{
|
{
|
||||||
if (!strcasecmp(npi_string, "isdn") || !strcasecmp(npi_string, "e164")) {
|
if (switch_is_number(npi_string)) {
|
||||||
|
*target = (uint8_t)atoi(npi_string);
|
||||||
|
} else if (!strcasecmp(npi_string, "isdn") || !strcasecmp(npi_string, "e164")) {
|
||||||
*target = ZAP_NPI_ISDN;
|
*target = ZAP_NPI_ISDN;
|
||||||
} else if (!strcasecmp(npi_string, "data")) {
|
} else if (!strcasecmp(npi_string, "data")) {
|
||||||
*target = ZAP_NPI_DATA;
|
*target = ZAP_NPI_DATA;
|
||||||
|
@ -157,7 +159,9 @@ static void zap_set_npi(const char *npi_string, uint8_t *target)
|
||||||
|
|
||||||
static void zap_set_ton(const char *ton_string, uint8_t *target)
|
static void zap_set_ton(const char *ton_string, uint8_t *target)
|
||||||
{
|
{
|
||||||
if (!strcasecmp(ton_string, "national")) {
|
if (switch_is_number(ton_string)) {
|
||||||
|
*target = (uint8_t)atoi(ton_string);
|
||||||
|
} else if (!strcasecmp(ton_string, "national")) {
|
||||||
*target = ZAP_TON_NATIONAL;
|
*target = ZAP_TON_NATIONAL;
|
||||||
} else if (!strcasecmp(ton_string, "international")) {
|
} else if (!strcasecmp(ton_string, "international")) {
|
||||||
*target = ZAP_TON_INTERNATIONAL;
|
*target = ZAP_TON_INTERNATIONAL;
|
||||||
|
@ -1231,15 +1235,8 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((var = switch_event_get_header(var_event, "openzap_outbound_ton")) || (var = switch_core_get_variable("openzap_outbound_ton"))) {
|
if ((var = switch_event_get_header(var_event, "openzap_outbound_ton")) || (var = switch_core_get_variable("openzap_outbound_ton"))) {
|
||||||
if (!strcasecmp(var, "national")) {
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting TON to: %s\n", var);
|
||||||
caller_data.ani.type = ZAP_TON_NATIONAL;
|
zap_set_ton(var, &caller_data.ani.type);
|
||||||
} else if (!strcasecmp(var, "international")) {
|
|
||||||
caller_data.ani.type = ZAP_TON_INTERNATIONAL;
|
|
||||||
} else if (!strcasecmp(var, "local")) {
|
|
||||||
caller_data.ani.type = ZAP_TON_SUBSCRIBER_NUMBER;
|
|
||||||
} else if (!strcasecmp(var, "unknown")) {
|
|
||||||
caller_data.ani.type = ZAP_TON_UNKNOWN;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
caller_data.ani.type = outbound_profile->destination_number_ton;
|
caller_data.ani.type = outbound_profile->destination_number_ton;
|
||||||
}
|
}
|
||||||
|
@ -1249,7 +1246,12 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
||||||
caller_data.raw_data_len = strlen(var);
|
caller_data.raw_data_len = strlen(var);
|
||||||
}
|
}
|
||||||
|
|
||||||
caller_data.ani.plan = outbound_profile->destination_number_numplan;
|
if ((var = switch_event_get_header(var_event, "openzap_outbound_npi")) || (var = switch_core_get_variable("openzap_outbound_npi"))) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting NPI to: %s\n", var);
|
||||||
|
zap_set_npi(var, &caller_data.ani.plan);
|
||||||
|
} else {
|
||||||
|
caller_data.ani.plan = outbound_profile->destination_number_numplan;
|
||||||
|
}
|
||||||
|
|
||||||
/* blindly copy data from outbound_profile. They will be overwritten
|
/* blindly copy data from outbound_profile. They will be overwritten
|
||||||
* by calling zap_caller_data if needed after */
|
* by calling zap_caller_data if needed after */
|
||||||
|
|
|
@ -3778,6 +3778,7 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer
|
||||||
switch_xml_set_attr_d(x_conference, "member-count", ival);
|
switch_xml_set_attr_d(x_conference, "member-count", ival);
|
||||||
switch_snprintf(i, sizeof(i), "%u", conference->rate);
|
switch_snprintf(i, sizeof(i), "%u", conference->rate);
|
||||||
switch_xml_set_attr_d(x_conference, "rate", ival);
|
switch_xml_set_attr_d(x_conference, "rate", ival);
|
||||||
|
switch_xml_set_attr_d(x_conference, "uuid", conference->uuid_str);
|
||||||
|
|
||||||
if (switch_test_flag(conference, CFLAG_LOCKED)) {
|
if (switch_test_flag(conference, CFLAG_LOCKED)) {
|
||||||
switch_xml_set_attr_d(x_conference, "locked", "true");
|
switch_xml_set_attr_d(x_conference, "locked", "true");
|
||||||
|
|
|
@ -77,11 +77,12 @@ struct private_object {
|
||||||
|
|
||||||
switch_frame_t cng_frame;
|
switch_frame_t cng_frame;
|
||||||
unsigned char cng_databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
|
unsigned char cng_databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
|
||||||
|
switch_timer_t timer;
|
||||||
switch_caller_profile_t *caller_profile;
|
switch_caller_profile_t *caller_profile;
|
||||||
int32_t bowout_frame_count;
|
int32_t bowout_frame_count;
|
||||||
char *other_uuid;
|
char *other_uuid;
|
||||||
switch_queue_t *frame_queue;
|
switch_queue_t *frame_queue;
|
||||||
switch_codec_implementation_t read_impl;
|
int64_t packet_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct private_object private_t;
|
typedef struct private_object private_t;
|
||||||
|
@ -111,6 +112,7 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses
|
||||||
int interval = 20;
|
int interval = 20;
|
||||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||||
|
const switch_codec_implementation_t *read_impl;
|
||||||
|
|
||||||
if (codec) {
|
if (codec) {
|
||||||
iananame = codec->implementation->iananame;
|
iananame = codec->implementation->iananame;
|
||||||
|
@ -165,7 +167,15 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses
|
||||||
switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
|
switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
|
||||||
switch_core_session_set_write_codec(session, &tech_pvt->write_codec);
|
switch_core_session_set_write_codec(session, &tech_pvt->write_codec);
|
||||||
|
|
||||||
tech_pvt->read_impl = *tech_pvt->read_codec.implementation;
|
if (tech_pvt->flag_mutex) {
|
||||||
|
switch_core_timer_destroy(&tech_pvt->timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
read_impl = tech_pvt->read_codec.implementation;
|
||||||
|
|
||||||
|
switch_core_timer_init(&tech_pvt->timer, "soft",
|
||||||
|
read_impl->microseconds_per_packet / 1000, read_impl->samples_per_packet * 4, switch_core_session_get_pool(session));
|
||||||
|
|
||||||
|
|
||||||
if (!tech_pvt->flag_mutex) {
|
if (!tech_pvt->flag_mutex) {
|
||||||
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
|
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
|
||||||
|
@ -367,6 +377,7 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session)
|
||||||
tech_pvt = switch_core_session_get_private(session);
|
tech_pvt = switch_core_session_get_private(session);
|
||||||
|
|
||||||
if (tech_pvt) {
|
if (tech_pvt) {
|
||||||
|
switch_core_timer_destroy(&tech_pvt->timer);
|
||||||
|
|
||||||
if (switch_core_codec_ready(&tech_pvt->read_codec)) {
|
if (switch_core_codec_ready(&tech_pvt->read_codec)) {
|
||||||
switch_core_codec_destroy(&tech_pvt->read_codec);
|
switch_core_codec_destroy(&tech_pvt->read_codec);
|
||||||
|
@ -558,10 +569,12 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_core_timer_next(&tech_pvt->timer);
|
||||||
|
|
||||||
mutex = tech_pvt->mutex;
|
mutex = tech_pvt->mutex;
|
||||||
|
switch_mutex_lock(mutex);
|
||||||
|
|
||||||
|
if (switch_queue_trypop(tech_pvt->frame_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
|
||||||
if (switch_queue_pop_timeout(tech_pvt->frame_queue, &pop, tech_pvt->read_impl.microseconds_per_packet) == SWITCH_STATUS_SUCCESS && pop) {
|
|
||||||
if (tech_pvt->write_frame) {
|
if (tech_pvt->write_frame) {
|
||||||
switch_frame_free(&tech_pvt->write_frame);
|
switch_frame_free(&tech_pvt->write_frame);
|
||||||
}
|
}
|
||||||
|
@ -569,38 +582,18 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
||||||
tech_pvt->write_frame = (switch_frame_t *) pop;
|
tech_pvt->write_frame = (switch_frame_t *) pop;
|
||||||
tech_pvt->write_frame->codec = &tech_pvt->read_codec;
|
tech_pvt->write_frame->codec = &tech_pvt->read_codec;
|
||||||
*frame = tech_pvt->write_frame;
|
*frame = tech_pvt->write_frame;
|
||||||
|
tech_pvt->packet_count++;
|
||||||
|
switch_clear_flag_locked(tech_pvt, TFLAG_CNG);
|
||||||
|
switch_clear_flag(tech_pvt->write_frame, SFF_CNG);
|
||||||
} else {
|
} else {
|
||||||
switch_set_flag(tech_pvt, TFLAG_CNG);
|
switch_set_flag(tech_pvt, TFLAG_CNG);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_mutex_lock(mutex);
|
|
||||||
|
|
||||||
if (switch_test_flag(tech_pvt, TFLAG_CNG)) {
|
if (switch_test_flag(tech_pvt, TFLAG_CNG)) {
|
||||||
unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE];
|
|
||||||
uint32_t flag = 0;
|
|
||||||
switch_status_t encode_status;
|
|
||||||
uint32_t rate = tech_pvt->read_codec.implementation->actual_samples_per_second;
|
|
||||||
|
|
||||||
*frame = &tech_pvt->cng_frame;
|
*frame = &tech_pvt->cng_frame;
|
||||||
tech_pvt->cng_frame.codec = &tech_pvt->read_codec;
|
tech_pvt->cng_frame.codec = &tech_pvt->read_codec;
|
||||||
tech_pvt->cng_frame.datalen = tech_pvt->read_codec.implementation->decoded_bytes_per_packet;
|
tech_pvt->cng_frame.datalen = tech_pvt->read_codec.implementation->decoded_bytes_per_packet;
|
||||||
|
switch_set_flag((&tech_pvt->cng_frame), SFF_CNG);
|
||||||
memset(tech_pvt->cng_frame.data, 0, tech_pvt->cng_frame.datalen);
|
|
||||||
memset(&data, 0, tech_pvt->read_codec.implementation->decoded_bytes_per_packet);
|
|
||||||
|
|
||||||
if (strcasecmp(tech_pvt->read_codec.implementation->iananame, "L16")) {
|
|
||||||
encode_status = switch_core_codec_encode(&tech_pvt->read_codec,
|
|
||||||
NULL,
|
|
||||||
data,
|
|
||||||
tech_pvt->read_codec.implementation->decoded_bytes_per_packet,
|
|
||||||
tech_pvt->read_codec.implementation->actual_samples_per_second,
|
|
||||||
tech_pvt->cng_frame.data, &tech_pvt->cng_frame.datalen, &rate, &flag);
|
|
||||||
if (encode_status != SWITCH_STATUS_SUCCESS) {
|
|
||||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
//switch_set_flag((&tech_pvt->cng_frame), SFF_CNG);
|
|
||||||
switch_clear_flag_locked(tech_pvt, TFLAG_CNG);
|
switch_clear_flag_locked(tech_pvt, TFLAG_CNG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -632,7 +625,10 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
||||||
tech_pvt = switch_core_session_get_private(session);
|
tech_pvt = switch_core_session_get_private(session);
|
||||||
switch_assert(tech_pvt != NULL);
|
switch_assert(tech_pvt != NULL);
|
||||||
|
|
||||||
if (switch_test_flag(frame, SFF_CNG) || switch_test_flag(tech_pvt, TFLAG_CNG) || (switch_test_flag(tech_pvt, TFLAG_BOWOUT) && switch_test_flag(tech_pvt, TFLAG_BOWOUT_USED))) {
|
if (switch_test_flag(frame, SFF_CNG) ||
|
||||||
|
switch_test_flag(tech_pvt, TFLAG_CNG) || (switch_test_flag(tech_pvt, TFLAG_BOWOUT) && switch_test_flag(tech_pvt, TFLAG_BOWOUT_USED))) {
|
||||||
|
switch_core_timer_sync(&tech_pvt->timer);
|
||||||
|
switch_core_timer_sync(&tech_pvt->other_tech_pvt->timer);
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -765,6 +761,8 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
|
||||||
switch_frame_free(&frame);
|
switch_frame_free(&frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_core_timer_sync(&tech_pvt->timer);
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -707,11 +707,20 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
||||||
cid = generate_pai_str(tech_pvt);
|
cid = generate_pai_str(tech_pvt);
|
||||||
|
|
||||||
|
|
||||||
if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) && tech_pvt->early_sdp && strcmp(tech_pvt->early_sdp, tech_pvt->local_sdp_str)) {
|
if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) && tech_pvt->early_sdp) {
|
||||||
/* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless
|
char *a, *b;
|
||||||
we do so in this case we will abandon the SOA rules and go rogue.
|
|
||||||
*/
|
/* start at the s= line to avoid some devices who update the o= between messages */
|
||||||
sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
|
a = strstr(tech_pvt->early_sdp, "s=");
|
||||||
|
b = strstr(tech_pvt->local_sdp_str, "s=");
|
||||||
|
|
||||||
|
if (!a || !b || strcmp(a, b)) {
|
||||||
|
|
||||||
|
/* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless
|
||||||
|
we do so in this case we will abandon the SOA rules and go rogue.
|
||||||
|
*/
|
||||||
|
sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sofia_use_soa(tech_pvt)) {
|
if (sofia_use_soa(tech_pvt)) {
|
||||||
|
|
|
@ -2595,14 +2595,15 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_ring_ready_value(swi
|
||||||
if (var) {
|
if (var) {
|
||||||
char *arg = NULL;
|
char *arg = NULL;
|
||||||
app = switch_core_session_strdup(channel->session, var);
|
app = switch_core_session_strdup(channel->session, var);
|
||||||
if ((arg = strchr(app, ' '))) {
|
|
||||||
*arg++ = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (switch_core_session_in_thread(channel->session)) {
|
if (strstr(app, "::")) {
|
||||||
switch_core_session_execute_application(channel->session, app, arg);
|
|
||||||
} else {
|
|
||||||
switch_core_session_execute_application_async(channel->session, app, arg);
|
switch_core_session_execute_application_async(channel->session, app, arg);
|
||||||
|
} else {
|
||||||
|
if ((arg = strchr(app, ' '))) {
|
||||||
|
*arg++ = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_core_session_execute_application(channel->session, app, arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2653,14 +2654,16 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_pre_answered(switch_
|
||||||
(var = switch_channel_get_variable(channel, SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE))) && !zstr(var)) {
|
(var = switch_channel_get_variable(channel, SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE))) && !zstr(var)) {
|
||||||
char *arg = NULL;
|
char *arg = NULL;
|
||||||
app = switch_core_session_strdup(channel->session, var);
|
app = switch_core_session_strdup(channel->session, var);
|
||||||
if ((arg = strchr(app, ' '))) {
|
|
||||||
*arg++ = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (switch_core_session_in_thread(channel->session)) {
|
|
||||||
switch_core_session_execute_application(channel->session, app, arg);
|
if (strstr(app, "::")) {
|
||||||
} else {
|
|
||||||
switch_core_session_execute_application_async(channel->session, app, arg);
|
switch_core_session_execute_application_async(channel->session, app, arg);
|
||||||
|
} else {
|
||||||
|
if ((arg = strchr(app, ' '))) {
|
||||||
|
*arg++ = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_core_session_execute_application(channel->session, app, arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2825,27 +2828,17 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_chan
|
||||||
(!switch_channel_test_flag(channel, CF_EARLY_MEDIA) && (var = switch_channel_get_variable(channel, SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE))))
|
(!switch_channel_test_flag(channel, CF_EARLY_MEDIA) && (var = switch_channel_get_variable(channel, SWITCH_CHANNEL_EXECUTE_ON_MEDIA_VARIABLE))))
|
||||||
&& !zstr(var)) {
|
&& !zstr(var)) {
|
||||||
char *arg = NULL;
|
char *arg = NULL;
|
||||||
char *colon = NULL;
|
|
||||||
|
|
||||||
app = switch_core_session_strdup(channel->session, var);
|
app = switch_core_session_strdup(channel->session, var);
|
||||||
|
|
||||||
arg = strchr(app, ' ');
|
if (strstr(app, "::")) {
|
||||||
colon = strchr(app, ':');
|
switch_core_session_execute_application_async(channel->session, app, arg);
|
||||||
if (colon && (!arg || arg > colon) && *(colon + 1) == ':') {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "%s execute on answer: %s (BROADCAST)\n", channel->name, app);
|
|
||||||
switch_ivr_broadcast(switch_core_session_get_uuid(channel->session), app, SMF_NONE);
|
|
||||||
} else {
|
} else {
|
||||||
if (arg) {
|
if ((arg = strchr(app, ' '))) {
|
||||||
*arg++ = '\0';
|
*arg++ = '\0';
|
||||||
}
|
}
|
||||||
switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "%s execute on answer: %s(%s)\n", channel->name, app,
|
|
||||||
switch_str_nil(arg));
|
|
||||||
|
|
||||||
if (switch_core_session_in_thread(channel->session)) {
|
switch_core_session_execute_application(channel->session, app, arg);
|
||||||
switch_core_session_execute_application(channel->session, app, arg);
|
|
||||||
} else {
|
|
||||||
switch_core_session_execute_application_async(channel->session, app, arg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue