diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index cffab0245f..247beae460 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -561,9 +561,15 @@ SWITCH_DECLARE(void) switch_channel_set_private_flag(switch_channel_t *channel, SWITCH_DECLARE(void) switch_channel_clear_private_flag(switch_channel_t *channel, uint32_t flags); SWITCH_DECLARE(int) switch_channel_test_private_flag(switch_channel_t *channel, uint32_t flags); -SWITCH_DECLARE(void) switch_channel_set_app_flag(switch_channel_t *channel, uint32_t flags); -SWITCH_DECLARE(void) switch_channel_clear_app_flag(switch_channel_t *channel, uint32_t flags); -SWITCH_DECLARE(int) switch_channel_test_app_flag(switch_channel_t *channel, uint32_t flags); +SWITCH_DECLARE(void) switch_channel_set_app_flag_key(const char *app, switch_channel_t *channel, uint32_t flags); +SWITCH_DECLARE(void) switch_channel_clear_app_flag_key(const char *app, switch_channel_t *channel, uint32_t flags); +SWITCH_DECLARE(int) switch_channel_test_app_flag_key(const char *app, switch_channel_t *channel, uint32_t flags); + +#define switch_channel_set_app_flag(_c, _f) switch_channel_set_app_flag_key(__FILE__, _c, _f) +#define switch_channel_clear_app_flag(_c, _f) switch_channel_clear_app_flag_key(__FILE__, _c, _f) +#define switch_channel_test_app_flag(_c, _f) switch_channel_test_app_flag_key(__FILE__, _c, _f) + + SWITCH_DECLARE(void) switch_channel_set_hangup_time(switch_channel_t *channel); SWITCH_DECLARE(switch_call_direction_t) switch_channel_direction(switch_channel_t *channel); SWITCH_DECLARE(switch_core_session_t *) switch_channel_get_session(switch_channel_t *channel); diff --git a/src/mod/applications/mod_fax/mod_fax.c b/src/mod/applications/mod_fax/mod_fax.c index a6ddfe5933..da1a98edf6 100644 --- a/src/mod/applications/mod_fax/mod_fax.c +++ b/src/mod/applications/mod_fax/mod_fax.c @@ -1122,7 +1122,7 @@ void process_fax(switch_core_session_t *session, const char *data, application_m switch (pvt->t38_mode) { case T38_MODE_REQUESTED: { - if (switch_channel_test_app_flag(channel, CF_APP_T38)) { + if (switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) { switch_core_session_message_t msg = { 0 }; pvt->t38_mode = T38_MODE_NEGOTIATED; spanfax_init(pvt, T38_MODE); @@ -1138,7 +1138,7 @@ void process_fax(switch_core_session_t *session, const char *data, application_m break; case T38_MODE_UNKNOWN: { - if (switch_channel_test_app_flag(channel, CF_APP_T38)) { + if (switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) { if (negotiate_t38(pvt) == T38_MODE_NEGOTIATED) { /* is is safe to call this again, it was already called above in AUDIO_MODE */ /* but this is the only way to set up the t38 stuff */ @@ -1458,7 +1458,7 @@ static switch_status_t t38_gateway_on_soft_execute(switch_core_session_t *sessio msg.string_arg = peer_uuid; switch_core_session_receive_message(session, &msg); - while (switch_channel_ready(channel) && switch_channel_up(other_channel) && !switch_channel_test_app_flag(channel, CF_APP_T38)) { + while (switch_channel_ready(channel) && switch_channel_up(other_channel) && !switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) { status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); if (!SWITCH_READ_ACCEPTABLE(status) || pvt->done) { @@ -1479,7 +1479,7 @@ static switch_status_t t38_gateway_on_soft_execute(switch_core_session_t *sessio goto end_unlock; } - if (!switch_channel_test_app_flag(channel, CF_APP_T38)) { + if (!switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Could not negotiate T38\n", switch_channel_get_name(channel)); goto end_unlock; @@ -1507,7 +1507,7 @@ static switch_status_t t38_gateway_on_soft_execute(switch_core_session_t *sessio /* wake up the audio side */ switch_channel_set_private(channel, "_t38_pvt", pvt); - switch_channel_set_app_flag(other_channel, CF_APP_T38); + switch_channel_set_app_flag_key("T38", other_channel, CF_APP_T38); while (switch_channel_ready(channel) && switch_channel_up(other_channel)) { @@ -1589,7 +1589,7 @@ static switch_status_t t38_gateway_on_consume_media(switch_core_session_t *sessi switch_event_fire(&event); } - while (switch_channel_ready(channel) && switch_channel_up(other_channel) && !switch_channel_test_app_flag(channel, CF_APP_T38)) { + while (switch_channel_ready(channel) && switch_channel_up(other_channel) && !switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) { status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); if (!SWITCH_READ_ACCEPTABLE(status)) { @@ -1610,7 +1610,7 @@ static switch_status_t t38_gateway_on_consume_media(switch_core_session_t *sessi goto end_unlock; } - if (!switch_channel_test_app_flag(channel, CF_APP_T38)) { + if (!switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); goto end_unlock; } diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 9af039e864..47d3cb9aa5 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -58,6 +58,10 @@ typedef struct { switch_mutex_t *mutex; } fifo_queue_t; +typedef enum { + FIFO_APP_BRIDGE_TAG = (1 << 0), + FIFO_APP_TRACKING = (1 << 1) +} fifo_app_flag_t; @@ -894,11 +898,11 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_ switch_size_t retsize; const char *ced_name, *ced_number, *cid_name, *cid_number; - if (switch_channel_test_app_flag(consumer_channel, CF_APP_TAGGED)) { + if (switch_channel_test_app_flag(consumer_channel, FIFO_APP_BRIDGE_TAG)) { goto end; } - switch_channel_set_app_flag(consumer_channel, CF_APP_TAGGED); + switch_channel_set_app_flag(consumer_channel, FIFO_APP_BRIDGE_TAG); switch_channel_set_variable(consumer_channel, "fifo_bridged", "true"); switch_channel_set_variable(consumer_channel, "fifo_manual_bridge", "true"); @@ -1002,7 +1006,7 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_ break; case SWITCH_MESSAGE_INDICATE_UNBRIDGE: { - if (switch_channel_test_app_flag(consumer_channel, CF_APP_TAGGED)) { + if (switch_channel_test_app_flag(consumer_channel, FIFO_APP_BRIDGE_TAG)) { char date[80] = ""; switch_time_exp_t tm; switch_time_t ts = switch_micro_time_now(); @@ -1010,7 +1014,7 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_ long epoch_start = 0, epoch_end = 0; const char *epoch_start_a = NULL; - switch_channel_clear_app_flag(consumer_channel, CF_APP_TAGGED); + switch_channel_clear_app_flag(consumer_channel, FIFO_APP_BRIDGE_TAG); switch_channel_set_variable(consumer_channel, "fifo_bridged", NULL); ts = switch_micro_time_now(); @@ -1987,13 +1991,15 @@ SWITCH_STANDARD_APP(fifo_track_call_function) return; } - if (switch_true(switch_channel_get_variable(channel, "fifo_track_call"))) { + if (switch_channel_test_app_flag(channel, FIFO_APP_TRACKING)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s trying to double-track call!\n", switch_channel_get_name(channel)); return; } add_bridge_call(data); + switch_channel_set_app_flag(channel, FIFO_APP_TRACKING); + switch_channel_set_variable(channel, "fifo_outbound_uuid", data); switch_channel_set_variable(channel, "fifo_track_call", "true"); @@ -2297,7 +2303,7 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_set_variable(channel, "fifo_timestamp", date); switch_channel_set_variable(channel, "fifo_serviced_uuid", NULL); - switch_channel_set_app_flag(channel, CF_APP_TAGGED); + switch_channel_set_app_flag(channel, FIFO_APP_BRIDGE_TAG); if (chime_list) { char *list_dup = switch_core_session_strdup(session, chime_list); @@ -2370,7 +2376,7 @@ SWITCH_STANDARD_APP(fifo_function) } } - switch_channel_clear_app_flag(channel, CF_APP_TAGGED); + switch_channel_clear_app_flag(channel, FIFO_APP_BRIDGE_TAG); abort: @@ -2724,7 +2730,7 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_set_flag(other_channel, CF_BREAK); - while (switch_channel_ready(channel) && switch_channel_ready(other_channel) && switch_channel_test_app_flag(other_channel, CF_APP_TAGGED)) { + while (switch_channel_ready(channel) && switch_channel_ready(other_channel) && switch_channel_test_app_flag(other_channel, FIFO_APP_BRIDGE_TAG)) { status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); if (!SWITCH_READ_ACCEPTABLE(status)) { break; @@ -3028,7 +3034,7 @@ SWITCH_STANDARD_APP(fifo_function) switch_mutex_unlock(globals.mutex); - switch_channel_clear_app_flag(channel, CF_APP_TAGGED); + switch_channel_clear_app_flag(channel, FIFO_APP_BRIDGE_TAG); switch_core_media_bug_resume(session); diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c index b4b42d738d..7ff106aceb 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c @@ -1106,7 +1106,7 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat switch (pvt->t38_mode) { case T38_MODE_REQUESTED: { - if (switch_channel_test_app_flag(channel, CF_APP_T38)) { + if (switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) { switch_core_session_message_t msg = { 0 }; pvt->t38_mode = T38_MODE_NEGOTIATED; spanfax_init(pvt, T38_MODE); @@ -1122,7 +1122,7 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat break; case T38_MODE_UNKNOWN: { - if (switch_channel_test_app_flag(channel, CF_APP_T38)) { + if (switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) { if (negotiate_t38(pvt) == T38_MODE_NEGOTIATED) { /* is is safe to call this again, it was already called above in AUDIO_MODE */ /* but this is the only way to set up the t38 stuff */ @@ -1338,7 +1338,7 @@ static switch_status_t t38_gateway_on_soft_execute(switch_core_session_t *sessio msg.string_arg = peer_uuid; switch_core_session_receive_message(session, &msg); - while (switch_channel_ready(channel) && switch_channel_up(other_channel) && !switch_channel_test_app_flag(channel, CF_APP_T38)) { + while (switch_channel_ready(channel) && switch_channel_up(other_channel) && !switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) { status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); if (!SWITCH_READ_ACCEPTABLE(status) || pvt->done) { @@ -1359,7 +1359,7 @@ static switch_status_t t38_gateway_on_soft_execute(switch_core_session_t *sessio goto end_unlock; } - if (!switch_channel_test_app_flag(channel, CF_APP_T38)) { + if (!switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Could not negotiate T38\n", switch_channel_get_name(channel)); goto end_unlock; @@ -1387,7 +1387,7 @@ static switch_status_t t38_gateway_on_soft_execute(switch_core_session_t *sessio /* wake up the audio side */ switch_channel_set_private(channel, "_t38_pvt", pvt); - switch_channel_set_app_flag(other_channel, CF_APP_T38); + switch_channel_set_app_flag_key("T38", other_channel, CF_APP_T38); while (switch_channel_ready(channel) && switch_channel_up(other_channel)) { @@ -1469,7 +1469,7 @@ static switch_status_t t38_gateway_on_consume_media(switch_core_session_t *sessi switch_event_fire(&event); } - while (switch_channel_ready(channel) && switch_channel_up(other_channel) && !switch_channel_test_app_flag(channel, CF_APP_T38)) { + while (switch_channel_ready(channel) && switch_channel_up(other_channel) && !switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) { status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); if (!SWITCH_READ_ACCEPTABLE(status)) { @@ -1490,7 +1490,7 @@ static switch_status_t t38_gateway_on_consume_media(switch_core_session_t *sessi goto end_unlock; } - if (!switch_channel_test_app_flag(channel, CF_APP_T38)) { + if (!switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); goto end_unlock; } diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 5be6335415..e4736690b7 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -4691,7 +4691,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, match = sofia_glue_negotiate_sdp(session, r_sdp); } - if (match && switch_channel_test_app_flag(tech_pvt->channel, CF_APP_T38)) { + if (match && switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38)) { goto done; } diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index b1681c85ca..d31ad9af8f 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -3446,7 +3446,7 @@ static switch_t38_options_t *tech_process_udptl(private_object_t *tech_pvt, sdp_ switch_channel_set_variable(tech_pvt->channel, "has_t38", "true"); switch_channel_set_private(tech_pvt->channel, "t38_options", t38_options); - switch_channel_set_app_flag(tech_pvt->channel, CF_APP_T38); + switch_channel_set_app_flag_key("T38", tech_pvt->channel, CF_APP_T38); return t38_options; } diff --git a/src/switch_channel.c b/src/switch_channel.c index e4c0c154f8..8a6e24bdd3 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -127,12 +127,12 @@ struct switch_channel { uint32_t caps[CC_FLAG_MAX]; uint8_t state_flags[CF_FLAG_MAX]; uint32_t private_flags; - uint32_t app_flags; switch_caller_profile_t *caller_profile; const switch_state_handler_table_t *state_handlers[SWITCH_MAX_STATE_HANDLERS]; int state_handler_index; switch_event_t *variables; switch_hash_t *private_hash; + switch_hash_t *app_flag_hash; switch_call_cause_t hangup_cause; int vi; int event_count; @@ -1285,30 +1285,55 @@ SWITCH_DECLARE(int) switch_channel_test_private_flag(switch_channel_t *channel, return (channel->private_flags & flags); } -SWITCH_DECLARE(void) switch_channel_set_app_flag(switch_channel_t *channel, uint32_t flags) +SWITCH_DECLARE(void) switch_channel_set_app_flag_key(const char *key, switch_channel_t *channel, uint32_t flags) { + uint32_t *flagp = NULL; + switch_assert(channel != NULL); switch_mutex_lock(channel->flag_mutex); - channel->app_flags |= flags; + + if (channel->app_flag_hash) { + flagp = switch_core_hash_find(channel->app_flag_hash, key); + } else { + switch_core_hash_init(&channel->app_flag_hash, switch_core_session_get_pool(channel->session)); + flagp = switch_core_session_alloc(channel->session, sizeof(uint32_t)); + switch_core_hash_insert(channel->app_flag_hash, key, flagp); + } + + if (flagp) *flagp |= flags; switch_mutex_unlock(channel->flag_mutex); } -SWITCH_DECLARE(void) switch_channel_clear_app_flag(switch_channel_t *channel, uint32_t flags) +SWITCH_DECLARE(void) switch_channel_clear_app_flag_key(const char *key, switch_channel_t *channel, uint32_t flags) { + uint32_t *flagp = NULL; + switch_assert(channel != NULL); switch_mutex_lock(channel->flag_mutex); - if (!flags) { - channel->app_flags = 0; - } else { - channel->app_flags &= ~flags; + if (channel->app_flag_hash && (flagp = switch_core_hash_find(channel->app_flag_hash, key))) { + if (!flags) { + *flagp = 0; + } else { + *flagp &= ~flags; + } } switch_mutex_unlock(channel->flag_mutex); } -SWITCH_DECLARE(int) switch_channel_test_app_flag(switch_channel_t *channel, uint32_t flags) +SWITCH_DECLARE(int) switch_channel_test_app_flag_key(const char *key, switch_channel_t *channel, uint32_t flags) { + int r = 0; + uint32_t *flagp = NULL; switch_assert(channel != NULL); - return (channel->app_flags & flags); + + switch_mutex_lock(channel->flag_mutex); + if (channel->app_flag_hash && (flagp = switch_core_hash_find(channel->app_flag_hash, key))) { + r = (*flagp & flags); + } + switch_mutex_unlock(channel->flag_mutex); + + + return r; } SWITCH_DECLARE(void) switch_channel_set_state_flag(switch_channel_t *channel, switch_channel_flag_t flag)