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);
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 */
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;
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;
};
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);
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);
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 *);
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];
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;
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;
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);
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);
}
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)) {
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)
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));