diff --git a/src/include/switch_core_event_hook.h b/src/include/switch_core_event_hook.h index b60246cf24..575786f5ce 100644 --- a/src/include/switch_core_event_hook.h +++ b/src/include/switch_core_event_hook.h @@ -45,6 +45,7 @@ typedef struct switch_io_event_hook_kill_channel switch_io_event_hook_kill_chann typedef struct switch_io_event_hook_send_dtmf switch_io_event_hook_send_dtmf_t; typedef struct switch_io_event_hook_recv_dtmf switch_io_event_hook_recv_dtmf_t; typedef struct switch_io_event_hook_state_change switch_io_event_hook_state_change_t; +typedef struct switch_io_event_hook_state_run switch_io_event_hook_state_run_t; typedef struct switch_io_event_hook_resurrect_session switch_io_event_hook_resurrect_session_t; typedef switch_status_t (*switch_outgoing_channel_hook_t) (switch_core_session_t *, switch_event_t *, switch_caller_profile_t *, switch_core_session_t *, switch_originate_flag_t); @@ -58,6 +59,7 @@ typedef switch_status_t (*switch_kill_channel_hook_t) (switch_core_session_t *, typedef switch_status_t (*switch_send_dtmf_hook_t) (switch_core_session_t *, const switch_dtmf_t *, switch_dtmf_direction_t direction); typedef switch_status_t (*switch_recv_dtmf_hook_t) (switch_core_session_t *, const switch_dtmf_t *, switch_dtmf_direction_t direction); typedef switch_status_t (*switch_state_change_hook_t) (switch_core_session_t *); +typedef switch_status_t (*switch_state_run_hook_t) (switch_core_session_t *); typedef switch_call_cause_t (*switch_resurrect_session_hook_t) (switch_core_session_t **, switch_memory_pool_t **, void *); /*! \brief Node in which to store custom receive message callback hooks */ @@ -136,6 +138,13 @@ struct switch_io_event_hook_state_change { struct switch_io_event_hook_state_change *next; }; +/*! \brief Node in which to store state run callback hooks */ +struct switch_io_event_hook_state_run { + /*! the state run channel callback hook */ + switch_state_run_hook_t state_run; + struct switch_io_event_hook_state_run *next; +}; + struct switch_io_event_hook_resurrect_session { switch_resurrect_session_hook_t resurrect_session; @@ -166,6 +175,7 @@ struct switch_io_event_hooks { switch_io_event_hook_recv_dtmf_t *recv_dtmf; /*! a list of state change hooks */ switch_io_event_hook_state_change_t *state_change; + switch_io_event_hook_state_run_t *state_run; switch_io_event_hook_resurrect_session_t *resurrect_session; }; @@ -218,6 +228,7 @@ NEW_HOOK_DECL_ADD_P(outgoing_channel); NEW_HOOK_DECL_ADD_P(receive_message); NEW_HOOK_DECL_ADD_P(receive_event); NEW_HOOK_DECL_ADD_P(state_change); +NEW_HOOK_DECL_ADD_P(state_run); NEW_HOOK_DECL_ADD_P(read_frame); NEW_HOOK_DECL_ADD_P(write_frame); NEW_HOOK_DECL_ADD_P(video_read_frame); @@ -231,6 +242,7 @@ NEW_HOOK_DECL_REM_P(outgoing_channel); NEW_HOOK_DECL_REM_P(receive_message); NEW_HOOK_DECL_REM_P(receive_event); NEW_HOOK_DECL_REM_P(state_change); +NEW_HOOK_DECL_REM_P(state_run); NEW_HOOK_DECL_REM_P(read_frame); NEW_HOOK_DECL_REM_P(write_frame); NEW_HOOK_DECL_REM_P(video_read_frame); diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index a6013a9386..ae0ce900a9 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -134,6 +134,7 @@ typedef switch_status_t (*switch_io_send_dtmf_t) (switch_core_session_t *, const typedef switch_status_t (*switch_io_receive_message_t) (switch_core_session_t *, switch_core_session_message_t *); typedef switch_status_t (*switch_io_receive_event_t) (switch_core_session_t *, switch_event_t *); typedef switch_status_t (*switch_io_state_change_t) (switch_core_session_t *); +typedef switch_status_t (*switch_io_state_run_t) (switch_core_session_t *); typedef switch_status_t (*switch_io_read_video_frame_t) (switch_core_session_t *, switch_frame_t **, switch_io_flag_t, int); typedef switch_status_t (*switch_io_write_video_frame_t) (switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int); typedef switch_call_cause_t (*switch_io_resurrect_session_t) (switch_core_session_t **, switch_memory_pool_t **, void *); @@ -174,6 +175,8 @@ struct switch_io_routines { switch_io_read_video_frame_t read_video_frame; /*! write a video frame to a session */ switch_io_write_video_frame_t write_video_frame; + /*! change a sessions channel run state */ + switch_io_state_run_t state_run; /*! resurrect a session */ switch_io_resurrect_session_t resurrect_session; void *padding[10]; diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 4a3cfd5954..520e0628d4 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -61,7 +61,8 @@ typedef struct { typedef enum { FIFO_APP_BRIDGE_TAG = (1 << 0), - FIFO_APP_TRACKING = (1 << 1) + FIFO_APP_TRACKING = (1 << 1), + FIFO_APP_DID_HOOK = (1 << 2) } fifo_app_flag_t; @@ -2019,9 +2020,10 @@ static switch_status_t hanguphook(switch_core_session_t *session) switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_state_t state = switch_channel_get_state(channel); - if (state == CS_HANGUP) { + if (state >= CS_HANGUP && !switch_channel_test_app_flag_key(FIFO_APP_KEY, channel, FIFO_APP_DID_HOOK)) { dec_use_count(session, SWITCH_TRUE); switch_core_event_hook_remove_state_change(session, hanguphook); + switch_channel_set_app_flag_key(FIFO_APP_KEY, channel, FIFO_APP_DID_HOOK); } return SWITCH_STATUS_SUCCESS; @@ -2044,6 +2046,8 @@ SWITCH_STANDARD_APP(fifo_track_call_function) return; } + switch_core_event_hook_add_receive_message(session, messagehook); + switch_core_event_hook_add_state_run(session, hanguphook); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s tracking call on uuid %s!\n", switch_channel_get_name(channel), data); @@ -2085,9 +2089,6 @@ SWITCH_STANDARD_APP(fifo_track_call_function) switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-CID-Number", cid_number); switch_event_fire(&event); } - - switch_core_event_hook_add_receive_message(session, messagehook); - switch_core_event_hook_add_state_change(session, hanguphook); } @@ -2493,6 +2494,7 @@ SWITCH_STANDARD_APP(fifo_function) if (switch_core_event_hook_remove_receive_message(session, messagehook) == SWITCH_STATUS_SUCCESS) { dec_use_count(session, SWITCH_FALSE); switch_core_event_hook_remove_state_change(session, hanguphook); + switch_channel_clear_app_flag_key(FIFO_APP_KEY, channel, FIFO_APP_TRACKING); } if (!zstr(strat_str)) { diff --git a/src/switch_core_event_hook.c b/src/switch_core_event_hook.c index 63420f6f4f..102ea20776 100644 --- a/src/switch_core_event_hook.c +++ b/src/switch_core_event_hook.c @@ -35,6 +35,7 @@ NEW_HOOK_DECL(outgoing_channel) NEW_HOOK_DECL(receive_message) NEW_HOOK_DECL(receive_event) NEW_HOOK_DECL(state_change) + NEW_HOOK_DECL(state_run) NEW_HOOK_DECL(read_frame) NEW_HOOK_DECL(write_frame) NEW_HOOK_DECL(video_read_frame) diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index 27579c2fb4..439f9b7d89 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -314,11 +314,25 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) int proceed = 1; int global_proceed = 1; int do_extra_handlers = 1; + switch_io_event_hook_state_run_t *ptr; + switch_status_t rstatus = SWITCH_STATUS_SUCCESS; switch_channel_set_running_state(session->channel, state); switch_channel_clear_flag(session->channel, CF_TRANSFER); switch_channel_clear_flag(session->channel, CF_REDIRECT); - + + if (session->endpoint_interface->io_routines->state_run) { + rstatus = session->endpoint_interface->io_routines->state_run(session); + } + + if (rstatus == SWITCH_STATUS_SUCCESS) { + for (ptr = session->event_hooks.state_run; ptr; ptr = ptr->next) { + if ((rstatus = ptr->state_run(session)) != SWITCH_STATUS_SUCCESS) { + break; + } + } + } + switch (state) { case CS_NEW: /* Just created, Waiting for first instructions */ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) State NEW\n", switch_channel_get_name(session->channel));