mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-05-30 02:20:11 +00:00
refactoring and general improvement (do a make sure)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3035 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
dfb9845d85
commit
ba46200539
@ -445,11 +445,29 @@ static int on_presence(void *user_data, ikspak *pak)
|
|||||||
{
|
{
|
||||||
ldl_handle_t *handle = user_data;
|
ldl_handle_t *handle = user_data;
|
||||||
char *from = iks_find_attrib(pak->x, "from");
|
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 id[1024];
|
||||||
char *resource;
|
char *resource;
|
||||||
struct ldl_buffer *buffer;
|
struct ldl_buffer *buffer;
|
||||||
size_t x;
|
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)) {
|
if (!apr_hash_get(handle->sub_hash, from, APR_HASH_KEY_STRING)) {
|
||||||
iks *msg;
|
iks *msg;
|
||||||
apr_hash_set(handle->sub_hash, apr_pstrdup(handle->pool, from), APR_HASH_KEY_STRING, &marker);
|
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_INITIATE,
|
||||||
LDL_SIGNAL_CANDIDATES,
|
LDL_SIGNAL_CANDIDATES,
|
||||||
LDL_SIGNAL_MSG,
|
LDL_SIGNAL_MSG,
|
||||||
|
LDL_SIGNAL_PRESENCE_IN,
|
||||||
|
LDL_SIGNAL_PRESENCE_OUT,
|
||||||
LDL_SIGNAL_TERMINATE,
|
LDL_SIGNAL_TERMINATE,
|
||||||
LDL_SIGNAL_ERROR,
|
LDL_SIGNAL_ERROR,
|
||||||
LDL_SIGNAL_LOGIN_SUCCESS,
|
LDL_SIGNAL_LOGIN_SUCCESS,
|
||||||
|
@ -83,6 +83,8 @@ struct switch_core_session_message {
|
|||||||
void *pointer_reply;
|
void *pointer_reply;
|
||||||
/*! optional arbitrary pointer reply's size */
|
/*! optional arbitrary pointer reply's size */
|
||||||
switch_size_t pointer_reply_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 */
|
/*! \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);
|
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
|
\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 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_PROGRESS,
|
||||||
SWITCH_MESSAGE_INDICATE_BRIDGE,
|
SWITCH_MESSAGE_INDICATE_BRIDGE,
|
||||||
SWITCH_MESSAGE_INDICATE_UNBRIDGE,
|
SWITCH_MESSAGE_INDICATE_UNBRIDGE,
|
||||||
SWITCH_MESSAGE_INDICATE_TRANSFER
|
SWITCH_MESSAGE_INDICATE_TRANSFER,
|
||||||
|
SWITCH_MESSAGE_INDICATE_RINGING
|
||||||
} switch_core_session_message_types_t;
|
} switch_core_session_message_types_t;
|
||||||
|
|
||||||
|
|
||||||
@ -348,6 +349,10 @@ typedef enum {
|
|||||||
SWITCH_CHANNEL_ID_EVENT
|
SWITCH_CHANNEL_ID_EVENT
|
||||||
} switch_text_channel_t;
|
} 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_UUID_FORMATTED_LENGTH APR_UUID_FORMATTED_LENGTH
|
||||||
#define SWITCH_CHANNEL_LOG SWITCH_CHANNEL_ID_LOG, __FILE__, __FUNCTION__, __LINE__
|
#define SWITCH_CHANNEL_LOG SWITCH_CHANNEL_ID_LOG, __FILE__, __FUNCTION__, __LINE__
|
||||||
#define SWITCH_CHANNEL_LOG_CLEAN SWITCH_CHANNEL_ID_LOG_CLEAN, __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_MODULE_LOAD - Module was loaded
|
||||||
SWITCH_EVENT_DTMF - DTMF was sent
|
SWITCH_EVENT_DTMF - DTMF was sent
|
||||||
SWITCH_EVENT_MESSAGE - A Basic Message
|
SWITCH_EVENT_MESSAGE - A Basic Message
|
||||||
|
SWITCH_EVENT_PRESENCE - Presence Info
|
||||||
SWITCH_EVENT_CODEC - Codec Change
|
SWITCH_EVENT_CODEC - Codec Change
|
||||||
SWITCH_EVENT_BACKGROUND_JOB - Background Job
|
SWITCH_EVENT_BACKGROUND_JOB - Background Job
|
||||||
SWITCH_EVENT_ALL - All events at once
|
SWITCH_EVENT_ALL - All events at once
|
||||||
@ -644,6 +650,8 @@ typedef enum {
|
|||||||
SWITCH_EVENT_MODULE_LOAD,
|
SWITCH_EVENT_MODULE_LOAD,
|
||||||
SWITCH_EVENT_DTMF,
|
SWITCH_EVENT_DTMF,
|
||||||
SWITCH_EVENT_MESSAGE,
|
SWITCH_EVENT_MESSAGE,
|
||||||
|
SWITCH_EVENT_PRESENCE_IN,
|
||||||
|
SWITCH_EVENT_PRESENCE_OUT,
|
||||||
SWITCH_EVENT_CODEC,
|
SWITCH_EVENT_CODEC,
|
||||||
SWITCH_EVENT_BACKGROUND_JOB,
|
SWITCH_EVENT_BACKGROUND_JOB,
|
||||||
SWITCH_EVENT_ALL
|
SWITCH_EVENT_ALL
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
|
|
||||||
#define DL_EVENT_LOGIN_SUCCESS "dingaling::login_success"
|
#define DL_EVENT_LOGIN_SUCCESS "dingaling::login_success"
|
||||||
#define DL_EVENT_LOGIN_FAILURE "dingaling::login_failure"
|
#define DL_EVENT_LOGIN_FAILURE "dingaling::login_failure"
|
||||||
#define DL_EVENT_MESSAGE "dingaling::message"
|
|
||||||
#define DL_EVENT_CONNECTED "dingaling::connected"
|
#define DL_EVENT_CONNECTED "dingaling::connected"
|
||||||
|
|
||||||
static const char modname[] = "mod_dingaling";
|
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;
|
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) {
|
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);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!", DL_EVENT_CONNECTED);
|
||||||
return SWITCH_STATUS_GENERR;
|
return SWITCH_STATUS_GENERR;
|
||||||
@ -1533,12 +1527,30 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi
|
|||||||
|
|
||||||
if (!dlsession) {
|
if (!dlsession) {
|
||||||
switch(signal) {
|
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:
|
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, "login", profile->login);
|
||||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", from);
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", from);
|
||||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "subject", subject);
|
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);
|
switch_event_fire(&event);
|
||||||
}
|
}
|
||||||
break;
|
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);
|
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, "login", profile->login);
|
||||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", from);
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", from);
|
||||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "subject", subject);
|
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) {
|
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_add_header(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true");
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
|
@ -42,6 +42,9 @@
|
|||||||
struct outbound_reg;
|
struct outbound_reg;
|
||||||
typedef struct outbound_reg outbound_reg_t;
|
typedef struct outbound_reg outbound_reg_t;
|
||||||
|
|
||||||
|
struct sip_presence;
|
||||||
|
typedef struct sip_presence sip_presence_t;
|
||||||
|
|
||||||
struct sofia_profile;
|
struct sofia_profile;
|
||||||
typedef struct sofia_profile sofia_profile_t;
|
typedef struct sofia_profile sofia_profile_t;
|
||||||
#define NUA_MAGIC_T sofia_profile_t
|
#define NUA_MAGIC_T sofia_profile_t
|
||||||
@ -49,6 +52,7 @@ typedef struct sofia_profile sofia_profile_t;
|
|||||||
struct sofia_private {
|
struct sofia_private {
|
||||||
switch_core_session_t *session;
|
switch_core_session_t *session;
|
||||||
outbound_reg_t *oreg;
|
outbound_reg_t *oreg;
|
||||||
|
sip_presence_t *presence;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct sofia_private sofia_private_t;
|
typedef struct sofia_private sofia_private_t;
|
||||||
@ -113,7 +117,8 @@ typedef enum {
|
|||||||
PFLAG_AUTH_CALLS = (1 << 0),
|
PFLAG_AUTH_CALLS = (1 << 0),
|
||||||
PFLAG_BLIND_REG = (1 << 1),
|
PFLAG_BLIND_REG = (1 << 1),
|
||||||
PFLAG_AUTH_ALL = (1 << 2),
|
PFLAG_AUTH_ALL = (1 << 2),
|
||||||
PFLAG_FULL_ID = (1 << 3)
|
PFLAG_FULL_ID = (1 << 3),
|
||||||
|
PFLAG_PRESENCE = (1 << 4)
|
||||||
} PFLAGS;
|
} PFLAGS;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -183,6 +188,14 @@ struct outbound_reg {
|
|||||||
struct outbound_reg *next;
|
struct outbound_reg *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct sip_presence {
|
||||||
|
sofia_private_t sofia_private;
|
||||||
|
nua_handle_t *nh;
|
||||||
|
sofia_profile_t *profile;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct sofia_profile {
|
struct sofia_profile {
|
||||||
int debug;
|
int debug;
|
||||||
char *name;
|
char *name;
|
||||||
@ -216,6 +229,8 @@ struct sofia_profile {
|
|||||||
switch_mutex_t *ireg_mutex;
|
switch_mutex_t *ireg_mutex;
|
||||||
switch_mutex_t *oreg_mutex;
|
switch_mutex_t *oreg_mutex;
|
||||||
outbound_reg_t *registrations;
|
outbound_reg_t *registrations;
|
||||||
|
sip_presence_t *presence;
|
||||||
|
su_home_t *home;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1311,6 +1326,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
|||||||
SOATAG_AUDIO_AUX("cn telephone-event"),
|
SOATAG_AUDIO_AUX("cn telephone-event"),
|
||||||
NUTAG_INCLUDE_EXTRA_SDP(1),
|
NUTAG_INCLUDE_EXTRA_SDP(1),
|
||||||
TAG_END());
|
TAG_END());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1605,6 +1621,9 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
|||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Re-activate timed RTP!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Re-activate timed RTP!\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SWITCH_MESSAGE_INDICATE_RINGING:
|
||||||
|
nua_respond(tech_pvt->nh, SIP_180_RINGING, TAG_END());
|
||||||
|
break;
|
||||||
case SWITCH_MESSAGE_INDICATE_PROGRESS: {
|
case SWITCH_MESSAGE_INDICATE_PROGRESS: {
|
||||||
struct private_object *tech_pvt;
|
struct private_object *tech_pvt;
|
||||||
switch_channel_t *channel = NULL;
|
switch_channel_t *channel = NULL;
|
||||||
@ -1809,11 +1828,11 @@ static uint8_t negotiate_sdp(switch_core_session_t *session, sdp_session_t *sdp)
|
|||||||
|
|
||||||
for (map = m->m_rtpmaps; map; map = map->rm_next) {
|
for (map = m->m_rtpmaps; map; map = map->rm_next) {
|
||||||
int32_t i;
|
int32_t i;
|
||||||
|
|
||||||
if (!strcasecmp(map->rm_encoding, "telephone-event")) {
|
if (!strcasecmp(map->rm_encoding, "telephone-event")) {
|
||||||
tech_pvt->te = (switch_payload_t)map->rm_pt;
|
tech_pvt->te = (switch_payload_t)map->rm_pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < tech_pvt->num_codecs; i++) {
|
for (i = 0; i < tech_pvt->num_codecs; i++) {
|
||||||
const switch_codec_implementation_t *imp = tech_pvt->codecs[i];
|
const switch_codec_implementation_t *imp = tech_pvt->codecs[i];
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Codec Compare [%s:%d]/[%s:%d]\n",
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Codec Compare [%s:%d]/[%s:%d]\n",
|
||||||
@ -1823,7 +1842,7 @@ static uint8_t negotiate_sdp(switch_core_session_t *session, sdp_session_t *sdp)
|
|||||||
} else {
|
} else {
|
||||||
match = strcasecmp(map->rm_encoding, imp->iananame) ? 0 : 1;
|
match = strcasecmp(map->rm_encoding, imp->iananame) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match && (map->rm_rate == imp->samples_per_second)) {
|
if (match && (map->rm_rate == imp->samples_per_second)) {
|
||||||
tech_pvt->rm_encoding = switch_core_session_strdup(session, (char *)map->rm_encoding);
|
tech_pvt->rm_encoding = switch_core_session_strdup(session, (char *)map->rm_encoding);
|
||||||
tech_pvt->pt = (switch_payload_t)map->rm_pt;
|
tech_pvt->pt = (switch_payload_t)map->rm_pt;
|
||||||
@ -1902,6 +1921,76 @@ static switch_call_cause_t sip_cause_to_freeswitch(int status) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sip_i_message(int status,
|
||||||
|
char const *phrase,
|
||||||
|
nua_t *nua,
|
||||||
|
sofia_profile_t *profile,
|
||||||
|
nua_handle_t *nh,
|
||||||
|
sofia_private_t *sofia_private,
|
||||||
|
sip_t const *sip,
|
||||||
|
tagi_t tags[])
|
||||||
|
{
|
||||||
|
if (sip) {
|
||||||
|
sip_from_t const *from = sip->sip_from;
|
||||||
|
char *from_user = NULL;
|
||||||
|
char *from_host = NULL;
|
||||||
|
sip_to_t const *to = sip->sip_to;
|
||||||
|
char *to_user = NULL;
|
||||||
|
char *to_host = NULL;
|
||||||
|
sip_subject_t const *sip_subject = sip->sip_subject;
|
||||||
|
sip_payload_t *payload = sip->sip_payload;
|
||||||
|
const char *subject = "n/a";
|
||||||
|
char *msg = "";
|
||||||
|
|
||||||
|
|
||||||
|
if (from) {
|
||||||
|
from_user = (char *) from->a_url->url_user;
|
||||||
|
from_host = (char *) from->a_url->url_host;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to) {
|
||||||
|
to_user = (char *) to->a_url->url_user;
|
||||||
|
to_host = (char *) to->a_url->url_host;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload) {
|
||||||
|
msg = payload->pl_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sip_subject) {
|
||||||
|
subject = sip_subject->g_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nh) {
|
||||||
|
char *message = "hello world";
|
||||||
|
char buf[256] = "";
|
||||||
|
|
||||||
|
if (find_reg_url(profile, from_user, from_host, buf, sizeof(buf))) {
|
||||||
|
nua_handle_t *msg_nh;
|
||||||
|
|
||||||
|
|
||||||
|
msg_nh = nua_handle(profile->nua, NULL,
|
||||||
|
SIPTAG_FROM(sip->sip_to),
|
||||||
|
SIPTAG_TO_STR(buf),
|
||||||
|
SIPTAG_CONTACT_STR(profile->url),
|
||||||
|
TAG_END());
|
||||||
|
|
||||||
|
|
||||||
|
nua_message(msg_nh,
|
||||||
|
SIPTAG_CONTENT_TYPE_STR("text/plain"),
|
||||||
|
TAG_IF(message,
|
||||||
|
SIPTAG_PAYLOAD_STR(message)),
|
||||||
|
TAG_END());
|
||||||
|
|
||||||
|
nua_handle_destroy(msg_nh);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//printf("==================================\nFrom: %s@%s\nSubject: %s\n\n%s\n\n",from_user,from_host,subject,msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void sip_i_state(int status,
|
static void sip_i_state(int status,
|
||||||
char const *phrase,
|
char const *phrase,
|
||||||
nua_t *nua,
|
nua_t *nua,
|
||||||
@ -1964,6 +2053,27 @@ static void sip_i_state(int status,
|
|||||||
break;
|
break;
|
||||||
case nua_callstate_proceeding:
|
case nua_callstate_proceeding:
|
||||||
if (channel) {
|
if (channel) {
|
||||||
|
if (status == 180) {
|
||||||
|
if (switch_test_flag(tech_pvt, TFLAG_NOMEDIA)) {
|
||||||
|
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)) && (other_session = switch_core_session_locate(uuid))) {
|
||||||
|
switch_core_session_message_t msg;
|
||||||
|
msg.message_id = SWITCH_MESSAGE_INDICATE_RINGING;
|
||||||
|
msg.from = __FILE__;
|
||||||
|
switch_core_session_receive_message(other_session, &msg);
|
||||||
|
switch_core_session_rwunlock(other_session);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
switch_core_session_message_t *msg;
|
||||||
|
if ((msg = malloc(sizeof(*msg)))) {
|
||||||
|
memset(msg, 0, sizeof(*msg));
|
||||||
|
msg->message_id = SWITCH_MESSAGE_INDICATE_RINGING;
|
||||||
|
msg->from = __FILE__;
|
||||||
|
switch_core_session_queue_message(session, msg);
|
||||||
|
switch_set_flag(msg, SCSMF_DYNAMIC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (r_sdp) {
|
if (r_sdp) {
|
||||||
if (switch_test_flag(tech_pvt, TFLAG_NOMEDIA)) {
|
if (switch_test_flag(tech_pvt, TFLAG_NOMEDIA)) {
|
||||||
switch_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA);
|
switch_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA);
|
||||||
@ -2462,6 +2572,31 @@ static uint8_t handle_register(nua_t *nua,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void sip_i_subscribe(int status,
|
||||||
|
char const *phrase,
|
||||||
|
nua_t *nua,
|
||||||
|
sofia_profile_t *profile,
|
||||||
|
nua_handle_t *nh,
|
||||||
|
sofia_private_t *sofia_private,
|
||||||
|
sip_t const *sip,
|
||||||
|
tagi_t tags[])
|
||||||
|
{
|
||||||
|
nua_respond(nh, SIP_200_OK,
|
||||||
|
TAG_END());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sip_r_subscribe(int status,
|
||||||
|
char const *phrase,
|
||||||
|
nua_t *nua,
|
||||||
|
sofia_profile_t *profile,
|
||||||
|
nua_handle_t *nh,
|
||||||
|
sofia_private_t *sofia_private,
|
||||||
|
sip_t const *sip,
|
||||||
|
tagi_t tags[])
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------*/
|
/*---------------------------------------*/
|
||||||
static void sip_i_refer(nua_t *nua,
|
static void sip_i_refer(nua_t *nua,
|
||||||
@ -2850,6 +2985,22 @@ static void sip_i_register(nua_t *nua,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void sip_i_options(int status,
|
||||||
|
char const *phrase,
|
||||||
|
nua_t *nua,
|
||||||
|
sofia_profile_t *profile,
|
||||||
|
nua_handle_t *nh,
|
||||||
|
sofia_private_t *sofia_private,
|
||||||
|
sip_t const *sip,
|
||||||
|
tagi_t tags[])
|
||||||
|
{
|
||||||
|
nua_respond(nh, SIP_200_OK,
|
||||||
|
//SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
|
||||||
|
//SOATAG_AUDIO_AUX("cn telephone-event"),
|
||||||
|
//NUTAG_INCLUDE_EXTRA_SDP(1),
|
||||||
|
TAG_END());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void sip_r_register(int status,
|
static void sip_r_register(int status,
|
||||||
char const *phrase,
|
char const *phrase,
|
||||||
@ -3000,6 +3151,10 @@ static void event_callback(nua_event_t event,
|
|||||||
//sip_r_options(status, phrase, nua, profile, nh, sofia_private, sip, tags);
|
//sip_r_options(status, phrase, nua, profile, nh, sofia_private, sip, tags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case nua_i_options:
|
||||||
|
sip_i_options(status, phrase, nua, profile, nh, sofia_private, sip, tags);
|
||||||
|
break;
|
||||||
|
|
||||||
case nua_i_fork:
|
case nua_i_fork:
|
||||||
//sip_i_fork(status, phrase, nua, profile, nh, sofia_private, sip, tags);
|
//sip_i_fork(status, phrase, nua, profile, nh, sofia_private, sip, tags);
|
||||||
break;
|
break;
|
||||||
@ -3033,7 +3188,7 @@ static void event_callback(nua_event_t event,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case nua_i_message:
|
case nua_i_message:
|
||||||
//sip_i_message(nua, profile, nh, sofia_private, sip, tags);
|
sip_i_message(status, phrase, nua, profile, nh, sofia_private, sip, tags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nua_r_info:
|
case nua_r_info:
|
||||||
@ -3053,7 +3208,11 @@ static void event_callback(nua_event_t event,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case nua_r_subscribe:
|
case nua_r_subscribe:
|
||||||
//sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
|
sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nua_i_subscribe:
|
||||||
|
sip_i_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nua_r_unsubscribe:
|
case nua_r_unsubscribe:
|
||||||
@ -3063,7 +3222,9 @@ static void event_callback(nua_event_t event,
|
|||||||
case nua_r_publish:
|
case nua_r_publish:
|
||||||
//sip_r_publish(status, phrase, nua, profile, nh, sofia_private, sip, tags);
|
//sip_r_publish(status, phrase, nua, profile, nh, sofia_private, sip, tags);
|
||||||
break;
|
break;
|
||||||
|
case nua_r_notifier:
|
||||||
|
nua_respond(nh, SIP_200_OK, TAG_END());
|
||||||
|
break;
|
||||||
case nua_r_notify:
|
case nua_r_notify:
|
||||||
//sip_r_notify(status, phrase, nua, profile, nh, sofia_private, sip, tags);
|
//sip_r_notify(status, phrase, nua, profile, nh, sofia_private, sip, tags);
|
||||||
break;
|
break;
|
||||||
@ -3180,6 +3341,8 @@ static void *SWITCH_THREAD_FUNC profile_thread_run(switch_thread_t *thread, void
|
|||||||
NUTAG_AUTOALERT(0),
|
NUTAG_AUTOALERT(0),
|
||||||
NUTAG_ALLOW("REGISTER"),
|
NUTAG_ALLOW("REGISTER"),
|
||||||
NUTAG_ALLOW("REFER"),
|
NUTAG_ALLOW("REFER"),
|
||||||
|
TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW("PUBLISH")),
|
||||||
|
TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ENABLEMESSAGE(1)),
|
||||||
SIPTAG_SUPPORTED_STR("100rel, precondition"),
|
SIPTAG_SUPPORTED_STR("100rel, precondition"),
|
||||||
SIPTAG_USER_AGENT_STR(SOFIA_USER_AGENT),
|
SIPTAG_USER_AGENT_STR(SOFIA_USER_AGENT),
|
||||||
TAG_END());
|
TAG_END());
|
||||||
@ -3198,6 +3361,8 @@ static void *SWITCH_THREAD_FUNC profile_thread_run(switch_thread_t *thread, void
|
|||||||
NUTAG_AUTOALERT(0),
|
NUTAG_AUTOALERT(0),
|
||||||
NUTAG_ALLOW("REGISTER"),
|
NUTAG_ALLOW("REGISTER"),
|
||||||
NUTAG_ALLOW("REFER"),
|
NUTAG_ALLOW("REFER"),
|
||||||
|
TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ALLOW("PUBLISH")),
|
||||||
|
TAG_IF((profile->pflags & PFLAG_PRESENCE), NUTAG_ENABLEMESSAGE(1)),
|
||||||
SIPTAG_SUPPORTED_STR("100rel, precondition"),
|
SIPTAG_SUPPORTED_STR("100rel, precondition"),
|
||||||
SIPTAG_USER_AGENT_STR(SOFIA_USER_AGENT),
|
SIPTAG_USER_AGENT_STR(SOFIA_USER_AGENT),
|
||||||
TAG_END());
|
TAG_END());
|
||||||
@ -3217,10 +3382,6 @@ static void *SWITCH_THREAD_FUNC profile_thread_run(switch_thread_t *thread, void
|
|||||||
switch_mutex_init(&profile->ireg_mutex, SWITCH_MUTEX_NESTED, profile->pool);
|
switch_mutex_init(&profile->ireg_mutex, SWITCH_MUTEX_NESTED, profile->pool);
|
||||||
switch_mutex_init(&profile->oreg_mutex, SWITCH_MUTEX_NESTED, profile->pool);
|
switch_mutex_init(&profile->oreg_mutex, SWITCH_MUTEX_NESTED, profile->pool);
|
||||||
|
|
||||||
switch_mutex_lock(globals.mutex);
|
|
||||||
globals.running = 1;
|
|
||||||
switch_mutex_unlock(globals.mutex);
|
|
||||||
|
|
||||||
ireg_loops = IREG_SECONDS;
|
ireg_loops = IREG_SECONDS;
|
||||||
oreg_loops = OREG_SECONDS;
|
oreg_loops = OREG_SECONDS;
|
||||||
|
|
||||||
@ -3230,6 +3391,45 @@ static void *SWITCH_THREAD_FUNC profile_thread_run(switch_thread_t *thread, void
|
|||||||
switch_event_fire(&s_event);
|
switch_event_fire(&s_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (switch_event_create(&s_event, SWITCH_EVENT_PUBLISH) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._tcp");
|
||||||
|
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", profile->sip_port);
|
||||||
|
switch_event_fire(&s_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switch_event_create(&s_event, SWITCH_EVENT_PUBLISH) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._sctp");
|
||||||
|
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", profile->sip_port);
|
||||||
|
switch_event_fire(&s_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (profile->pflags & PFLAG_PRESENCE) {
|
||||||
|
if (!(profile->presence = switch_core_alloc(profile->pool, sizeof(*profile->presence)))) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
profile->presence->nh = nua_handle(profile->nua, NULL,
|
||||||
|
TAG_END());
|
||||||
|
profile->presence->sofia_private.presence = profile->presence;
|
||||||
|
nua_handle_bind(profile->presence->nh, &profile->presence->sofia_private);
|
||||||
|
|
||||||
|
nua_notifier(profile->presence->nh,
|
||||||
|
NUTAG_URL(profile->url),
|
||||||
|
SIPTAG_EXPIRES_STR("3600"),
|
||||||
|
SIPTAG_FROM_STR(profile->url),
|
||||||
|
//SIPTAG_EVENT_STR("presence"),
|
||||||
|
SIPTAG_EVENT_STR("message-summary"),
|
||||||
|
//SIPTAG_ALLOW_EVENTS_STR("message-summary"),
|
||||||
|
SIPTAG_CONTENT_TYPE_STR("text/urllist"),
|
||||||
|
//SIPTAG_CONTENT_TYPE_STR("application/pidf-partial+xml"),
|
||||||
|
//SIPTAG_CONTENT_TYPE_STR("text/plain"),
|
||||||
|
NUTAG_SUBSTATE(nua_substate_pending),
|
||||||
|
TAG_END());
|
||||||
|
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Creating notifier for %s\n", profile->url);
|
||||||
|
}
|
||||||
|
|
||||||
while(globals.running == 1) {
|
while(globals.running == 1) {
|
||||||
if (++ireg_loops >= IREG_SECONDS) {
|
if (++ireg_loops >= IREG_SECONDS) {
|
||||||
check_expire(profile, time(NULL));
|
check_expire(profile, time(NULL));
|
||||||
@ -3243,6 +3443,13 @@ static void *SWITCH_THREAD_FUNC profile_thread_run(switch_thread_t *thread, void
|
|||||||
|
|
||||||
su_root_step(profile->s_root, 1000);
|
su_root_step(profile->s_root, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (profile->presence && profile->presence->nh) {
|
||||||
|
nua_handle_destroy(profile->presence->nh);
|
||||||
|
profile->presence->nh = NULL;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (switch_event_create(&s_event, SWITCH_EVENT_UNPUBLISH) == SWITCH_STATUS_SUCCESS) {
|
if (switch_event_create(&s_event, SWITCH_EVENT_UNPUBLISH) == SWITCH_STATUS_SUCCESS) {
|
||||||
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp");
|
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp");
|
||||||
@ -3251,7 +3458,6 @@ static void *SWITCH_THREAD_FUNC profile_thread_run(switch_thread_t *thread, void
|
|||||||
}
|
}
|
||||||
|
|
||||||
su_root_destroy(profile->s_root);
|
su_root_destroy(profile->s_root);
|
||||||
|
|
||||||
pool = profile->pool;
|
pool = profile->pool;
|
||||||
switch_core_destroy_memory_pool(&pool);
|
switch_core_destroy_memory_pool(&pool);
|
||||||
switch_mutex_lock(globals.mutex);
|
switch_mutex_lock(globals.mutex);
|
||||||
@ -3285,6 +3491,10 @@ static switch_status_t config_sofia(int reload)
|
|||||||
sofia_profile_t *profile = NULL;
|
sofia_profile_t *profile = NULL;
|
||||||
char url[512] = "";
|
char url[512] = "";
|
||||||
|
|
||||||
|
switch_mutex_lock(globals.mutex);
|
||||||
|
globals.running = 1;
|
||||||
|
switch_mutex_unlock(globals.mutex);
|
||||||
|
|
||||||
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
|
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
|
||||||
status = SWITCH_STATUS_FALSE;
|
status = SWITCH_STATUS_FALSE;
|
||||||
@ -3367,6 +3577,10 @@ static switch_status_t config_sofia(int reload)
|
|||||||
profile->sipdomain = switch_core_strdup(profile->pool, val);
|
profile->sipdomain = switch_core_strdup(profile->pool, val);
|
||||||
} else if (!strcasecmp(var, "rtp-timer-name")) {
|
} else if (!strcasecmp(var, "rtp-timer-name")) {
|
||||||
profile->timer_name = switch_core_strdup(profile->pool, val);
|
profile->timer_name = switch_core_strdup(profile->pool, val);
|
||||||
|
} else if (!strcasecmp(var, "manage-presence")) {
|
||||||
|
if (switch_true(val)) {
|
||||||
|
profile->pflags |= PFLAG_PRESENCE;
|
||||||
|
}
|
||||||
} else if (!strcasecmp(var, "auth-calls")) {
|
} else if (!strcasecmp(var, "auth-calls")) {
|
||||||
if (switch_true(val)) {
|
if (switch_true(val)) {
|
||||||
profile->pflags |= PFLAG_AUTH_CALLS;
|
profile->pflags |= PFLAG_AUTH_CALLS;
|
||||||
@ -3588,6 +3802,58 @@ static void event_handler(switch_event_t *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void msg_event_handler(switch_event_t *event)
|
||||||
|
{
|
||||||
|
switch_hash_index_t *hi;
|
||||||
|
void *val;
|
||||||
|
sofia_profile_t *profile;
|
||||||
|
int open = 0;
|
||||||
|
char *from = switch_event_get_header(event, "from");
|
||||||
|
//char *status = switch_event_get_header(event, "status");
|
||||||
|
|
||||||
|
switch(event->event_id) {
|
||||||
|
case SWITCH_EVENT_PRESENCE_IN:
|
||||||
|
open = 1;
|
||||||
|
break;
|
||||||
|
case SWITCH_EVENT_PRESENCE_OUT:
|
||||||
|
open = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (hi = switch_hash_first(apr_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
|
||||||
|
switch_hash_this(hi, NULL, NULL, &val);
|
||||||
|
profile = (sofia_profile_t *) val;
|
||||||
|
if (profile && profile->presence) {
|
||||||
|
char *url;
|
||||||
|
char *myfrom = strdup(from);
|
||||||
|
char *p;
|
||||||
|
for(p = myfrom; *p ; p++) {
|
||||||
|
if (*p == '@') {
|
||||||
|
*p = '!';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
url = switch_core_db_mprintf("sip:%s", myfrom);
|
||||||
|
|
||||||
|
nua_publish(profile->presence->nh,
|
||||||
|
SIPTAG_EVENT_STR("presence"),
|
||||||
|
SIPTAG_CONTENT_TYPE_STR("text/urllist"),
|
||||||
|
SIPTAG_PAYLOAD_STR(url),
|
||||||
|
TAG_NULL());
|
||||||
|
|
||||||
|
switch_safe_free(url);
|
||||||
|
switch_safe_free(myfrom);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename)
|
SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename)
|
||||||
{
|
{
|
||||||
@ -3614,7 +3880,20 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_mod
|
|||||||
|
|
||||||
config_sofia(0);
|
config_sofia(0);
|
||||||
|
|
||||||
|
if (switch_event_bind((char *) modname, SWITCH_EVENT_MESSAGE, SWITCH_EVENT_SUBCLASS_ANY, msg_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||||
|
return SWITCH_STATUS_GENERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switch_event_bind((char *) modname, SWITCH_EVENT_PRESENCE_IN, SWITCH_EVENT_SUBCLASS_ANY, msg_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||||
|
return SWITCH_STATUS_GENERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (switch_event_bind((char *) modname, SWITCH_EVENT_PRESENCE_OUT, SWITCH_EVENT_SUBCLASS_ANY, msg_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||||
|
return SWITCH_STATUS_GENERR;
|
||||||
|
}
|
||||||
|
|
||||||
/* connect my internal structure to the blank pointer passed to me */
|
/* connect my internal structure to the blank pointer passed to me */
|
||||||
*module_interface = &sofia_module_interface;
|
*module_interface = &sofia_module_interface;
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SWITCH_EVENT_QUEUE_LEN 256
|
#define SWITCH_EVENT_QUEUE_LEN 256
|
||||||
|
#define SWITCH_MESSAGE_QUEUE_LEN 256
|
||||||
#define SWITCH_SQL_QUEUE_LEN 2000
|
#define SWITCH_SQL_QUEUE_LEN 2000
|
||||||
|
|
||||||
#define SWITCH_BUFFER_BLOCK_FRAMES 25
|
#define SWITCH_BUFFER_BLOCK_FRAMES 25
|
||||||
@ -105,6 +106,7 @@ struct switch_core_session {
|
|||||||
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
|
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
|
||||||
void *private_info;
|
void *private_info;
|
||||||
switch_queue_t *event_queue;
|
switch_queue_t *event_queue;
|
||||||
|
switch_queue_t *message_queue;
|
||||||
switch_queue_t *private_event_queue;
|
switch_queue_t *private_event_queue;
|
||||||
switch_thread_rwlock_t *bug_rwlock;
|
switch_thread_rwlock_t *bug_rwlock;
|
||||||
switch_media_bug_t *bugs;
|
switch_media_bug_t *bugs;
|
||||||
@ -1413,8 +1415,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_answer_channel(switch_core_s
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(switch_status_t) switch_core_session_receive_message(switch_core_session_t *session,
|
SWITCH_DECLARE(switch_status_t) switch_core_session_receive_message(switch_core_session_t *session, switch_core_session_message_t *message)
|
||||||
switch_core_session_message_t *message)
|
|
||||||
{
|
{
|
||||||
switch_io_event_hook_receive_message_t *ptr;
|
switch_io_event_hook_receive_message_t *ptr;
|
||||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
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;
|
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)
|
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",
|
"MODULE_LOAD",
|
||||||
"DTMF",
|
"DTMF",
|
||||||
"MESSAGE",
|
"MESSAGE",
|
||||||
|
"PRESENCE_IN",
|
||||||
|
"PRESENCE_OUT",
|
||||||
"CODEC",
|
"CODEC",
|
||||||
"BACKGROUND_JOB",
|
"BACKGROUND_JOB",
|
||||||
"ALL"
|
"ALL"
|
||||||
|
@ -1244,7 +1244,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
|||||||
int *stream_id_p;
|
int *stream_id_p;
|
||||||
int stream_id = 0, pre_b = 0, ans_a = 0, ans_b = 0, originator = 0;
|
int stream_id = 0, pre_b = 0, ans_a = 0, ans_b = 0, originator = 0;
|
||||||
switch_input_callback_function_t input_callback;
|
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;
|
void *user_data;
|
||||||
|
|
||||||
switch_channel_t *chan_a, *chan_b;
|
switch_channel_t *chan_a, *chan_b;
|
||||||
@ -1297,62 +1297,65 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!switch_channel_test_flag(chan_a, CF_HOLD)) {
|
if (switch_core_session_dequeue_private_event(session_a, &event) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_channel_set_flag(chan_b, CF_HOLD);
|
||||||
if (!ans_a && originator) {
|
switch_ivr_parse_event(session_a, event);
|
||||||
if (!ans_b && switch_channel_test_flag(chan_b, CF_ANSWERED)) {
|
switch_channel_clear_flag(chan_b, CF_HOLD);
|
||||||
switch_channel_answer(chan_a);
|
switch_event_destroy(&event);
|
||||||
ans_a++;
|
}
|
||||||
} else if (!pre_b && switch_channel_test_flag(chan_b, CF_EARLY_MEDIA)) {
|
|
||||||
switch_channel_pre_answer(chan_a);
|
/* if 1 channel has DTMF pass it to the other */
|
||||||
pre_b++;
|
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_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_dequeue_private_event(session_a, &event) == SWITCH_STATUS_SUCCESS) {
|
if (switch_core_session_receive_event(session_b, &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);
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 */
|
/* read audio from 1 channel and write it to the other */
|
||||||
status = switch_core_session_read_frame(session_a, &read_frame, -1, stream_id);
|
status = switch_core_session_read_frame(session_a, &read_frame, -1, stream_id);
|
||||||
|
|
||||||
if (SWITCH_READ_ACCEPTABLE(status)) {
|
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) {
|
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_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "write: %s Bad Frame....[%u] Bubye!\n",
|
||||||
switch_channel_get_name(chan_b), read_frame->datalen);
|
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;
|
data->running = -1;
|
||||||
switch_mutex_unlock(data->mutex);
|
switch_mutex_unlock(data->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
//switch_yield(1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE;
|
msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE;
|
||||||
msg.from = __FILE__;
|
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)) &&
|
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)) {
|
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 */
|
/* read from the channel while we wait if the audio is up on it */
|
||||||
if (session && !switch_channel_test_flag(caller_channel, CF_NOMEDIA) &&
|
if (session && !switch_channel_test_flag(caller_channel, CF_NOMEDIA) &&
|
||||||
|
Loading…
x
Reference in New Issue
Block a user