diff --git a/src/include/switch_core.h b/src/include/switch_core.h index a493eceda8..55612d03a3 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -78,7 +78,6 @@ struct switch_core_session_message { void *pointer_reply; /*! optional arbitrary pointer reply's size */ switch_size_t pointer_reply_size; - }; /*! \brief A generic object to pass as a thread's session object to allow mutiple arguements and a pool */ @@ -289,6 +288,14 @@ SWITCH_DECLARE(switch_core_session *) switch_core_session_locate(char *uuid_str) */ SWITCH_DECLARE (switch_status) switch_core_session_message_send(char *uuid_str, switch_core_session_message *message); +/*! + \brief Queue an event on another session using its uuid + \param uuid_str the unique id of the session you want to send a message to + \param event the event to send + \return the status returned by the message handler +*/ +SWITCH_DECLARE(switch_status) switch_core_session_event_send(char *uuid_str, switch_event *event); + /*! \brief Retrieve private user data from a session \param session the session to retrieve from @@ -379,6 +386,14 @@ SWITCH_DECLARE(switch_status) switch_core_session_answer_channel(switch_core_ses */ SWITCH_DECLARE(switch_status) switch_core_session_receive_message(switch_core_session *session, switch_core_session_message *message); +/*! + \brief Queue an event on a given session + \param session the session to queue the message on + \param event the event to queue + \return the status returned by the message handler +*/ +SWITCH_DECLARE(switch_status) switch_core_session_queue_event(switch_core_session *session, switch_event *event); + /*! \brief Read a frame from a session \param session the session to read from diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index ffc529e7f3..664a1c9b4d 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -83,6 +83,13 @@ struct switch_io_event_hook_receive_message { struct switch_io_event_hook_receive_message *next; }; +/*! \brief Node in which to store custom receive message callback hooks */ +struct switch_io_event_hook_queue_event { + /*! the answer channel callback hook*/ + switch_queue_event_hook queue_event; + struct switch_io_event_hook_queue_event *next; +}; + /*! \brief Node in which to store custom read frame channel callback hooks */ struct switch_io_event_hook_read_frame { /*! the read frame channel callback hook*/ @@ -133,6 +140,8 @@ struct switch_io_event_hooks { struct switch_io_event_hook_answer_channel *answer_channel; /*! a list of receive message hooks */ struct switch_io_event_hook_receive_message *receive_message; + /*! a list of queue message hooks */ + struct switch_io_event_hook_queue_event *queue_event; /*! a list of read frame hooks */ struct switch_io_event_hook_read_frame *read_frame; /*! a list of write frame hooks */ @@ -167,6 +176,8 @@ struct switch_io_routines { switch_status (*send_dtmf)(switch_core_session *, char *); /*! receive a message from another session*/ switch_status (*receive_message)(switch_core_session *, switch_core_session_message *); + /*! queue a message for another session*/ + switch_status (*queue_event)(switch_core_session *, switch_event *); }; /*! \brief Abstraction of an module endpoint interface diff --git a/src/include/switch_types.h b/src/include/switch_types.h index d14f5d7ba5..1461220f20 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -528,6 +528,7 @@ typedef struct switch_codec_implementation switch_codec_implementation; typedef struct switch_io_event_hook_outgoing_channel switch_io_event_hook_outgoing_channel; typedef struct switch_io_event_hook_answer_channel switch_io_event_hook_answer_channel; typedef struct switch_io_event_hook_receive_message switch_io_event_hook_receive_message; +typedef struct switch_io_event_hook_queue_event switch_io_event_hook_queue_event; typedef struct switch_io_event_hook_read_frame switch_io_event_hook_read_frame; typedef struct switch_io_event_hook_write_frame switch_io_event_hook_write_frame; typedef struct switch_io_event_hook_kill_channel switch_io_event_hook_kill_channel; @@ -550,6 +551,7 @@ typedef switch_status (*switch_state_handler)(switch_core_session *); typedef switch_status (*switch_outgoing_channel_hook)(switch_core_session *, switch_caller_profile *, switch_core_session *); typedef switch_status (*switch_answer_channel_hook)(switch_core_session *); typedef switch_status (*switch_receive_message_hook)(switch_core_session *, switch_core_session_message *); +typedef switch_status (*switch_queue_event_hook)(switch_core_session *, switch_event *); typedef switch_status (*switch_read_frame_hook)(switch_core_session *, switch_frame **, int, switch_io_flag, int); typedef switch_status (*switch_write_frame_hook)(switch_core_session *, switch_frame *, int, switch_io_flag, int); typedef switch_status (*switch_kill_channel_hook)(switch_core_session *, int); diff --git a/src/switch_core.c b/src/switch_core.c index f6097310c0..2afcc2d0d7 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -34,6 +34,8 @@ #include //#define DEBUG_ALLOC +#define SWITCH_EVENT_QUEUE_LEN 256 + struct switch_core_session { uint32_t id; char name[80]; @@ -70,6 +72,7 @@ struct switch_core_session { char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; void *private_info; + switch_queue_t *event_queue; }; SWITCH_DECLARE_DATA switch_directories SWITCH_GLOBAL_dirs; @@ -236,6 +239,19 @@ SWITCH_DECLARE(switch_status) switch_core_session_message_send(char *uuid_str, s return SWITCH_STATUS_FALSE; } +SWITCH_DECLARE(switch_status) switch_core_session_event_send(char *uuid_str, switch_event *event) +{ + switch_core_session *session = NULL; + + if ((session = switch_core_hash_find(runtime.session_table, uuid_str)) != 0) { + if (switch_channel_get_state(session->channel) < CS_HANGUP) { + return switch_core_session_queue_event(session, event); + } + } + + return SWITCH_STATUS_FALSE; +} + SWITCH_DECLARE(char *) switch_core_session_get_uuid(switch_core_session *session) { return session->uuid_str; @@ -926,6 +942,35 @@ SWITCH_DECLARE(switch_status) switch_core_session_receive_message(switch_core_se return status; } +SWITCH_DECLARE(switch_status) switch_core_session_queue_event(switch_core_session *session, switch_event *event) + +{ + struct switch_io_event_hook_queue_event *ptr; + switch_status status = SWITCH_STATUS_FALSE, istatus = SWITCH_STATUS_FALSE;; + + assert(session != NULL); + if (session->endpoint_interface->io_routines->queue_event) { + status = session->endpoint_interface->io_routines->queue_event(session, event); + + if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { + for (ptr = session->event_hooks.queue_event; ptr; ptr = ptr->next) { + if ((istatus = ptr->queue_event(session, event)) != SWITCH_STATUS_SUCCESS) { + break; + } + } + } + + if (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK) { + if (!session->event_queue) { + switch_queue_create(&session->event_queue, SWITCH_EVENT_QUEUE_LEN, session->pool); + } + switch_queue_push(session->event_queue, event); + } + } + + return status; +} + SWITCH_DECLARE(switch_status) switch_core_session_read_frame(switch_core_session *session, switch_frame **frame, int timeout, int stream_id) {