提交 ba462005 authored 作者: Anthony Minessale's avatar Anthony Minessale

refactoring and general improvement (do a make sure)

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3035 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 dfb9845d
......@@ -445,11 +445,29 @@ static int on_presence(void *user_data, ikspak *pak)
{
ldl_handle_t *handle = user_data;
char *from = iks_find_attrib(pak->x, "from");
char *type = iks_find_attrib(pak->x, "type");
char *show = iks_find_cdata(pak->x, "show");
char *status = iks_find_cdata(pak->x, "status");
char id[1024];
char *resource;
struct ldl_buffer *buffer;
size_t x;
ldl_signal_t signal;
if (type && !strcasecmp(type, "unavailable")) {
signal = LDL_SIGNAL_PRESENCE_OUT;
} else {
signal = LDL_SIGNAL_PRESENCE_IN;
}
if (!status) {
status = type;
}
if (handle->session_callback) {
handle->session_callback(handle, NULL, signal, from, status ? status : "n/a", show ? show : "n/a");
}
if (!apr_hash_get(handle->sub_hash, from, APR_HASH_KEY_STRING)) {
iks *msg;
apr_hash_set(handle->sub_hash, apr_pstrdup(handle->pool, from), APR_HASH_KEY_STRING, &marker);
......
......@@ -119,6 +119,8 @@ typedef enum {
LDL_SIGNAL_INITIATE,
LDL_SIGNAL_CANDIDATES,
LDL_SIGNAL_MSG,
LDL_SIGNAL_PRESENCE_IN,
LDL_SIGNAL_PRESENCE_OUT,
LDL_SIGNAL_TERMINATE,
LDL_SIGNAL_ERROR,
LDL_SIGNAL_LOGIN_SUCCESS,
......
......@@ -83,6 +83,8 @@ struct switch_core_session_message {
void *pointer_reply;
/*! optional arbitrary pointer reply's size */
switch_size_t pointer_reply_size;
/*! message flags */
switch_core_session_message_flag_t flags;
};
/*! \brief A generic object to pass as a thread's session object to allow mutiple arguements and a pool */
......@@ -421,6 +423,22 @@ SWITCH_DECLARE(void) switch_core_session_hupall(switch_call_cause_t cause);
*/
SWITCH_DECLARE (switch_status_t) switch_core_session_message_send(char *uuid_str, switch_core_session_message_t *message);
/*!
\brief Queue a message on a session
\param session the session to queue the message to
\param message the message to queue
\return SWITCH_STATUS_SUCCESS if the message was queued
*/
SWITCH_DECLARE(switch_status_t) switch_core_session_queue_message(switch_core_session_t *session, switch_core_session_message_t *message);
/*!
\brief DE-Queue an message on a given session
\param session the session to de-queue the message on
\param message the de-queued message
\return the SWITCH_STATUS_SUCCESS if the message was de-queued
*/
SWITCH_DECLARE(switch_status_t) switch_core_session_dequeue_message(switch_core_session_t *session, switch_core_session_message_t **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
......
......@@ -247,7 +247,8 @@ typedef enum {
SWITCH_MESSAGE_INDICATE_PROGRESS,
SWITCH_MESSAGE_INDICATE_BRIDGE,
SWITCH_MESSAGE_INDICATE_UNBRIDGE,
SWITCH_MESSAGE_INDICATE_TRANSFER
SWITCH_MESSAGE_INDICATE_TRANSFER,
SWITCH_MESSAGE_INDICATE_RINGING
} switch_core_session_message_types_t;
......@@ -348,6 +349,10 @@ typedef enum {
SWITCH_CHANNEL_ID_EVENT
} switch_text_channel_t;
typedef enum {
SCSMF_DYNAMIC = (1 << 0)
} switch_core_session_message_flag_t;
#define SWITCH_UUID_FORMATTED_LENGTH APR_UUID_FORMATTED_LENGTH
#define SWITCH_CHANNEL_LOG SWITCH_CHANNEL_ID_LOG, __FILE__, __FUNCTION__, __LINE__
#define SWITCH_CHANNEL_LOG_CLEAN SWITCH_CHANNEL_ID_LOG_CLEAN, __FILE__, __FUNCTION__, __LINE__
......@@ -610,6 +615,7 @@ typedef enum {
SWITCH_EVENT_MODULE_LOAD - Module was loaded
SWITCH_EVENT_DTMF - DTMF was sent
SWITCH_EVENT_MESSAGE - A Basic Message
SWITCH_EVENT_PRESENCE - Presence Info
SWITCH_EVENT_CODEC - Codec Change
SWITCH_EVENT_BACKGROUND_JOB - Background Job
SWITCH_EVENT_ALL - All events at once
......@@ -644,6 +650,8 @@ typedef enum {
SWITCH_EVENT_MODULE_LOAD,
SWITCH_EVENT_DTMF,
SWITCH_EVENT_MESSAGE,
SWITCH_EVENT_PRESENCE_IN,
SWITCH_EVENT_PRESENCE_OUT,
SWITCH_EVENT_CODEC,
SWITCH_EVENT_BACKGROUND_JOB,
SWITCH_EVENT_ALL
......
......@@ -38,7 +38,6 @@
#define DL_EVENT_LOGIN_SUCCESS "dingaling::login_success"
#define DL_EVENT_LOGIN_FAILURE "dingaling::login_failure"
#define DL_EVENT_MESSAGE "dingaling::message"
#define DL_EVENT_CONNECTED "dingaling::connected"
static const char modname[] = "mod_dingaling";
......@@ -1191,11 +1190,6 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod
return SWITCH_STATUS_GENERR;
}
if (switch_event_reserve_subclass(DL_EVENT_MESSAGE) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!", DL_EVENT_MESSAGE);
return SWITCH_STATUS_GENERR;
}
if (switch_event_reserve_subclass(DL_EVENT_CONNECTED) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!", DL_EVENT_CONNECTED);
return SWITCH_STATUS_GENERR;
......@@ -1533,12 +1527,30 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
if (!dlsession) {
switch(signal) {
case LDL_SIGNAL_PRESENCE_IN:
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", profile->login);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", from);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", subject);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", msg);
switch_event_fire(&event);
}
break;
case LDL_SIGNAL_PRESENCE_OUT:
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", profile->login);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", from);
switch_event_fire(&event);
}
break;
case LDL_SIGNAL_MSG:
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, DL_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", profile->login);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", from);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "subject", subject);
switch_event_add_body(event, msg);
if (msg) {
switch_event_add_body(event, msg);
}
switch_event_fire(&event);
}
break;
......@@ -1639,12 +1651,13 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "SESSION MSG [%s]\n", msg);
}
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, DL_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", profile->login);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", from);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "subject", subject);
switch_event_add_body(event, msg);
if (msg) {
switch_event_add_body(event, msg);
}
if (switch_core_session_queue_event(tech_pvt->session, &event) != SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true");
switch_event_fire(&event);
......
......@@ -50,6 +50,7 @@
#endif
#define SWITCH_EVENT_QUEUE_LEN 256
#define SWITCH_MESSAGE_QUEUE_LEN 256
#define SWITCH_SQL_QUEUE_LEN 2000
#define SWITCH_BUFFER_BLOCK_FRAMES 25
......@@ -105,6 +106,7 @@ struct switch_core_session {
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
void *private_info;
switch_queue_t *event_queue;
switch_queue_t *message_queue;
switch_queue_t *private_event_queue;
switch_thread_rwlock_t *bug_rwlock;
switch_media_bug_t *bugs;
......@@ -1413,8 +1415,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_answer_channel(switch_core_s
return status;
}
SWITCH_DECLARE(switch_status_t) switch_core_session_receive_message(switch_core_session_t *session,
switch_core_session_message_t *message)
SWITCH_DECLARE(switch_status_t) switch_core_session_receive_message(switch_core_session_t *session, switch_core_session_message_t *message)
{
switch_io_event_hook_receive_message_t *ptr;
switch_status_t status = SWITCH_STATUS_FALSE;
......@@ -1429,11 +1430,44 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_receive_message(switch_core_
}
}
}
}
}
return status;
}
SWITCH_DECLARE(switch_status_t) switch_core_session_queue_message(switch_core_session_t *session, switch_core_session_message_t *message)
{
switch_status_t status = SWITCH_STATUS_FALSE;
assert(session != NULL);
if (!session->message_queue) {
switch_queue_create(&session->message_queue, SWITCH_MESSAGE_QUEUE_LEN, session->pool);
}
if (session->message_queue) {
if (switch_queue_trypush(session->message_queue, message) == SWITCH_STATUS_SUCCESS) {
status = SWITCH_STATUS_SUCCESS;
}
}
return status;
}
SWITCH_DECLARE(switch_status_t) switch_core_session_dequeue_message(switch_core_session_t *session, switch_core_session_message_t **message)
{
switch_status_t status = SWITCH_STATUS_FALSE;
void *pop;
assert(session != NULL);
if (session->message_queue) {
if ((status = (switch_status_t) switch_queue_trypop(session->message_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
*message = (switch_core_session_message_t *) pop;
}
}
return status;
}
SWITCH_DECLARE(switch_status_t) switch_core_session_receive_event(switch_core_session_t *session, switch_event_t **event)
......
......@@ -123,6 +123,8 @@ static char *EVENT_NAMES[] = {
"MODULE_LOAD",
"DTMF",
"MESSAGE",
"PRESENCE_IN",
"PRESENCE_OUT",
"CODEC",
"BACKGROUND_JOB",
"ALL"
......
......@@ -1244,7 +1244,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
int *stream_id_p;
int stream_id = 0, pre_b = 0, ans_a = 0, ans_b = 0, originator = 0;
switch_input_callback_function_t input_callback;
switch_core_session_message_t msg = {0};
switch_core_session_message_t *message, msg = {0};
void *user_data;
switch_channel_t *chan_a, *chan_b;
......@@ -1297,62 +1297,65 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
break;
}
if (!switch_channel_test_flag(chan_a, CF_HOLD)) {
if (!ans_a && originator) {
if (!ans_b && switch_channel_test_flag(chan_b, CF_ANSWERED)) {
switch_channel_answer(chan_a);
ans_a++;
} else if (!pre_b && switch_channel_test_flag(chan_b, CF_EARLY_MEDIA)) {
switch_channel_pre_answer(chan_a);
pre_b++;
if (switch_core_session_dequeue_private_event(session_a, &event) == SWITCH_STATUS_SUCCESS) {
switch_channel_set_flag(chan_b, CF_HOLD);
switch_ivr_parse_event(session_a, event);
switch_channel_clear_flag(chan_b, CF_HOLD);
switch_event_destroy(&event);
}
/* if 1 channel has DTMF pass it to the other */
if (switch_channel_has_dtmf(chan_a)) {
char dtmf[128];
switch_channel_dequeue_dtmf(chan_a, dtmf, sizeof(dtmf));
switch_core_session_send_dtmf(session_b, dtmf);
if (input_callback) {
if (input_callback(session_a, dtmf, SWITCH_INPUT_TYPE_DTMF, user_data, 0) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s ended call via DTMF\n", switch_channel_get_name(chan_a));
switch_mutex_lock(data->mutex);
data->running = -1;
switch_mutex_unlock(data->mutex);
break;
}
switch_yield(10000);
continue;
}
}
if (switch_core_session_dequeue_private_event(session_a, &event) == SWITCH_STATUS_SUCCESS) {
switch_channel_set_flag(chan_b, CF_HOLD);
switch_ivr_parse_event(session_a, event);
switch_channel_clear_flag(chan_b, CF_HOLD);
switch_event_destroy(&event);
if (switch_core_session_dequeue_event(session_a, &event) == SWITCH_STATUS_SUCCESS) {
if (input_callback) {
status = input_callback(session_a, event, SWITCH_INPUT_TYPE_EVENT, user_data, 0);
}
/* if 1 channel has DTMF pass it to the other */
if (switch_channel_has_dtmf(chan_a)) {
char dtmf[128];
switch_channel_dequeue_dtmf(chan_a, dtmf, sizeof(dtmf));
switch_core_session_send_dtmf(session_b, dtmf);
if (input_callback) {
if (input_callback(session_a, dtmf, SWITCH_INPUT_TYPE_DTMF, user_data, 0) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s ended call via DTMF\n", switch_channel_get_name(chan_a));
switch_mutex_lock(data->mutex);
data->running = -1;
switch_mutex_unlock(data->mutex);
break;
}
}
if (switch_core_session_receive_event(session_b, &event) != SWITCH_STATUS_SUCCESS) {
switch_event_destroy(&event);
}
if (switch_core_session_dequeue_event(session_a, &event) == SWITCH_STATUS_SUCCESS) {
if (input_callback) {
status = input_callback(session_a, event, SWITCH_INPUT_TYPE_EVENT, user_data, 0);
}
if (switch_core_session_receive_event(session_b, &event) != SWITCH_STATUS_SUCCESS) {
switch_event_destroy(&event);
}
}
if (switch_core_session_dequeue_message(session_b, &message) == SWITCH_STATUS_SUCCESS) {
switch_core_session_receive_message(session_a, message);
if (switch_test_flag(message, SCSMF_DYNAMIC)) {
switch_safe_free(message);
}
}
if (!ans_a && originator) {
if (!ans_b && switch_channel_test_flag(chan_b, CF_ANSWERED)) {
switch_channel_answer(chan_a);
ans_a++;
} else if (!pre_b && switch_channel_test_flag(chan_b, CF_EARLY_MEDIA)) {
switch_channel_pre_answer(chan_a);
pre_b++;
}
switch_yield(10000);
continue;
}
/* read audio from 1 channel and write it to the other */
status = switch_core_session_read_frame(session_a, &read_frame, -1, stream_id);
if (SWITCH_READ_ACCEPTABLE(status)) {
if (status != SWITCH_STATUS_BREAK) {
if (status != SWITCH_STATUS_BREAK && !switch_channel_test_flag(chan_a, CF_HOLD)) {
if (switch_core_session_write_frame(session_b, read_frame, -1, stream_id) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "write: %s Bad Frame....[%u] Bubye!\n",
switch_channel_get_name(chan_b), read_frame->datalen);
......@@ -1367,10 +1370,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
data->running = -1;
switch_mutex_unlock(data->mutex);
}
//switch_yield(1000);
}
msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE;
msg.from = __FILE__;
......@@ -1968,6 +1968,15 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
while ((!caller_channel || switch_channel_ready(caller_channel)) &&
check_channel_status(peer_channels, peer_sessions, and_argc, &idx, file, key) && ((time(NULL) - start) < (time_t)timelimit_sec)) {
if (or_argc == 1 && and_argc == 1) { /* when there is only 1 channel to call and bridge */
switch_core_session_message_t *message = NULL;
if (switch_core_session_dequeue_message(peer_sessions[0], &message) == SWITCH_STATUS_SUCCESS) {
switch_core_session_receive_message(session, message);
if (switch_test_flag(message, SCSMF_DYNAMIC)) {
switch_safe_free(message);
}
}
}
/* read from the channel while we wait if the audio is up on it */
if (session && !switch_channel_test_flag(caller_channel, CF_NOMEDIA) &&
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论