first pass on some new stuff

This commit is contained in:
Anthony Minessale 2012-07-11 15:15:43 -05:00
parent 90cdc718ec
commit 2aebe2456f
12 changed files with 740 additions and 97 deletions

View File

@ -138,6 +138,10 @@ static const char *EVENT_NAMES[] = {
"SOCKET_DATA",
"MEDIA_BUG_START",
"MEDIA_BUG_START",
"CONFERENCE_DATA_QUERY",
"CALL_SETUP_REQ",
"CALL_SETUP_RESULT",
"CONFERENCE_DATA",
"ALL"
};

View File

@ -128,6 +128,10 @@ typedef enum {
ESL_EVENT_SOCKET_DATA,
ESL_EVENT_MEDIA_BUG_START,
ESL_EVENT_MEDIA_BUG_STOP,
ESL_EVENT_CONFERENCE_DATA_QUERY,
ESL_EVENT_CONFERENCE_DATA,
ESL_EVENT_CALL_SETUP_REQ,
ESL_EVENT_CALL_SETUP_RESULT,
ESL_EVENT_ALL
} esl_event_types_t;

View File

@ -1000,13 +1000,14 @@ int nua_refer_server_respond(nua_server_request_t *sr, tagi_t const *tags)
static
int nua_refer_server_report(nua_server_request_t *sr, tagi_t const *tags)
{
nua_handle_t *nh = sr->sr_owner;
//nua_handle_t *nh = sr->sr_owner;
struct notifier_usage *nu = nua_dialog_usage_private(sr->sr_usage);
sip_t const *sip = sr->sr_request.sip;
sip_referred_by_t *by = sip->sip_referred_by, default_by[1];
sip_event_t const *o = sr->sr_usage->du_event;
enum nua_substate substate = nua_substate_terminated;
int initial = sr->sr_initial, retval;
//int initial = sr->sr_initial, retval;
int retval;
if (nu) {
if (!sr->sr_terminating)
@ -1029,13 +1030,14 @@ int nua_refer_server_report(nua_server_request_t *sr, tagi_t const *tags)
if (retval >= 2 || nu == NULL)
return retval;
#if 0
if (initial)
nua_stack_post_signal(nh,
nua_r_notify,
SIPTAG_EVENT(o),
SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
SIPTAG_PAYLOAD_STR("SIP/2.0 100 Trying\r\n"),
TAG_END());
TAG_END());
#endif
return retval;
}

View File

@ -1233,6 +1233,7 @@ typedef enum {
CF_PICKUP,
CF_CONFIRM_BLIND_TRANSFER,
CF_NO_PRESENCE,
CF_CONFERENCE,
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
/* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */
CF_FLAG_MAX
@ -1654,6 +1655,10 @@ typedef enum {
SWITCH_EVENT_SOCKET_DATA,
SWITCH_EVENT_MEDIA_BUG_START,
SWITCH_EVENT_MEDIA_BUG_STOP,
SWITCH_EVENT_CONFERENCE_DATA_QUERY,
SWITCH_EVENT_CONFERENCE_DATA,
SWITCH_EVENT_CALL_SETUP_REQ,
SWITCH_EVENT_CALL_SETUP_RESULT,
SWITCH_EVENT_ALL
} switch_event_types_t;

View File

@ -43,30 +43,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_conference_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_conference_shutdown);
SWITCH_MODULE_DEFINITION(mod_conference, mod_conference_load, mod_conference_shutdown, NULL);
typedef struct conference_cdr_node_s {
switch_caller_profile_t *cp;
char *record_path;
switch_time_t join_time;
switch_time_t leave_time;
uint32_t flags;
struct conference_cdr_node_s *next;
} conference_cdr_node_t;
typedef enum {
CDRR_LOCKED = 1,
CDRR_PIN,
CDRR_MAXMEMBERS
} cdr_reject_reason_t;
typedef struct conference_cdr_reject_s {
switch_caller_profile_t *cp;
switch_time_t reject_time;
cdr_reject_reason_t reason;
struct conference_cdr_reject_s *next;
} conference_cdr_reject_t;
typedef enum {
CONF_SILENT_REQ = (1 << 0),
CONF_SILENT_DONE = (1 << 1)
@ -121,13 +97,40 @@ static struct {
uint32_t id_pool;
int32_t running;
uint32_t threads;
switch_event_node_t *node;
} globals;
/* forward declaration for conference_obj and caller_control */
struct conference_member;
typedef struct conference_member conference_member_t;
typedef struct conference_cdr_node_s {
switch_caller_profile_t *cp;
char *record_path;
switch_time_t join_time;
switch_time_t leave_time;
uint32_t flags;
uint32_t id;
conference_member_t *member;
struct conference_cdr_node_s *next;
} conference_cdr_node_t;
typedef enum {
CDRR_LOCKED = 1,
CDRR_PIN,
CDRR_MAXMEMBERS
} cdr_reject_reason_t;
typedef struct conference_cdr_reject_s {
switch_caller_profile_t *cp;
switch_time_t reject_time;
cdr_reject_reason_t reason;
struct conference_cdr_reject_s *next;
} conference_cdr_reject_t;
struct call_list {
char *string;
int iteration;
@ -190,7 +193,8 @@ typedef enum {
CFLAG_ENTER_SOUND = (1 << 13),
CFLAG_VIDEO_BRIDGE = (1 << 14),
CFLAG_AUDIO_ALWAYS = (1 << 15),
CFLAG_ENDCONF_FORCED = (1 << 16)
CFLAG_ENDCONF_FORCED = (1 << 16),
CFLAG_RFC4579 = (1 << 17)
} conf_flag_t;
typedef enum {
@ -263,6 +267,7 @@ struct vid_helper {
/* Conference Object */
typedef struct conference_obj {
char *name;
char *desc;
char *timer_name;
char *tts_engine;
char *tts_voice;
@ -288,6 +293,7 @@ typedef struct conference_obj {
char *record_filename;
uint32_t terminate_on_silence;
uint32_t max_members;
uint32_t doc_version;
char *maxmember_sound;
uint32_t announce_count;
char *pin;
@ -476,11 +482,11 @@ static switch_status_t conference_outcall(conference_obj_t *conference,
char *cid_num,
char *profile,
switch_call_cause_t *cause,
switch_call_cause_t *cancel_cause);
switch_call_cause_t *cancel_cause, switch_event_t *var_event);
static switch_status_t conference_outcall_bg(conference_obj_t *conference,
char *conference_name,
switch_core_session_t *session, char *bridgeto, uint32_t timeout, const char *flags, const char *cid_name,
const char *cid_num, const char *call_uuid, const char *profile, switch_call_cause_t *cancel_cause);
const char *cid_num, const char *call_uuid, const char *profile, switch_call_cause_t *cancel_cause, switch_event_t **var_event);
SWITCH_STANDARD_APP(conference_function);
static void launch_conference_thread(conference_obj_t *conference);
static void launch_conference_video_thread(conference_obj_t *conference);
@ -522,6 +528,7 @@ static void conference_cdr_del(conference_member_t *member)
{
member->cdr_node->leave_time = switch_epoch_time_now(NULL);
member->cdr_node->flags = member->flags;
member->cdr_node->member = NULL;
}
static void conference_cdr_add(conference_member_t *member)
@ -535,6 +542,7 @@ static void conference_cdr_add(conference_member_t *member)
np->next = member->conference->cdr_nodes;
member->conference->cdr_nodes = member->cdr_node = np;
member->cdr_node->join_time = switch_epoch_time_now(NULL);
member->cdr_node->member = member;
if (!member->session) {
member->cdr_node->record_path = switch_core_strdup(member->conference->pool, member->rec_path);
@ -548,6 +556,11 @@ static void conference_cdr_add(conference_member_t *member)
}
member->cdr_node->cp = switch_caller_profile_dup(member->conference->pool, cp);
member->cdr_node->id = member->id;
}
static void conference_cdr_rejected(conference_obj_t *conference, switch_channel_t *channel, cdr_reject_reason_t reason)
@ -569,6 +582,246 @@ static void conference_cdr_rejected(conference_obj_t *conference, switch_channel
rp->cp = switch_caller_profile_dup(conference->pool, cp);
}
static char *conference_rfc4579_render(conference_obj_t *conference, switch_event_t *event)
{
switch_xml_t xml, x_tag, x_tag1, x_tag2, x_tag3, x_tag4;
char tmp[30];
const char *domain; const char *name;
char *dup_domain = NULL;
char *uri;
int off = 0, off1 = 0, off2 = 0, off3 = 0, off4 = 0;
conference_cdr_node_t *np;
char *tmpp = tmp;
char *xml_text = NULL;
if (!(xml = switch_xml_new("conference-info"))) {
abort();
}
switch_mutex_lock(conference->mutex);
switch_snprintf(tmp, sizeof(tmp), "%u", conference->doc_version);
conference->doc_version++;
switch_mutex_unlock(conference->mutex);
if (!event || !(name = switch_event_get_header(event, "conference-name"))) {
if (!(name = conference->name)) {
name = "conference";
}
}
if (!event || !(domain = switch_event_get_header(event, "conference-domain"))) {
if (!(domain = conference->domain)) {
dup_domain = switch_core_get_variable_dup("domain");
if (!(domain = dup_domain)) {
domain = "cluecon.com";
}
}
}
switch_xml_set_attr_d(xml, "version", tmpp);
switch_xml_set_attr_d(xml, "state", "full");
switch_xml_set_attr_d(xml, "xmlns", "urn:ietf:params:xml:ns:conference-info");
uri = switch_mprintf("sip:%s@%s", name, domain);
switch_xml_set_attr_d(xml, "entity", uri);
if (!(x_tag = switch_xml_add_child_d(xml, "conference-description", off++))) {
abort();
}
if (!(x_tag1 = switch_xml_add_child_d(x_tag, "display-text", off1++))) {
abort();
}
switch_xml_set_txt_d(x_tag1, conference->desc ? conference->desc : "FreeSWITCH Conference");
if (!(x_tag1 = switch_xml_add_child_d(x_tag, "conf-uris", off1++))) {
abort();
}
if (!(x_tag2 = switch_xml_add_child_d(x_tag1, "entry", off2++))) {
abort();
}
if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "uri", off3++))) {
abort();
}
switch_xml_set_txt_d(x_tag3, uri);
if (!(x_tag = switch_xml_add_child_d(xml, "conference-state", off++))) {
abort();
}
if (!(x_tag1 = switch_xml_add_child_d(x_tag, "user-count", off1++))) {
abort();
}
switch_snprintf(tmp, sizeof(tmp), "%u", conference->count);
switch_xml_set_txt_d(x_tag1, tmpp);
if (!(x_tag1 = switch_xml_add_child_d(x_tag, "active", off1++))) {
abort();
}
switch_xml_set_txt_d(x_tag1, "true");
off1 = off2 = off3 = off4 = 0;
if (!(x_tag = switch_xml_add_child_d(xml, "users", off++))) {
abort();
}
switch_mutex_lock(conference->member_mutex);
for (np = conference->cdr_nodes; np; np = np->next) {
char *user_uri;
if (!np->cp || (np->member && !np->member->session) || np->leave_time) { /* for now we'll remove participants when the leave */
continue;
}
if (!(x_tag1 = switch_xml_add_child_d(x_tag, "user", off1++))) {
abort();
}
user_uri = switch_mprintf("sip:%s@%s", np->cp->caller_id_number, domain);
switch_xml_set_attr_d(x_tag1, "state", "full");
switch_xml_set_attr_d(x_tag1, "entity", user_uri);
if (!(x_tag2 = switch_xml_add_child_d(x_tag1, "display-text", off2++))) {
abort();
}
switch_xml_set_txt_d(x_tag2, np->cp->caller_id_name);
if (!(x_tag2 = switch_xml_add_child_d(x_tag1, "endpoint", off2++))) {
abort();
}
switch_xml_set_attr_d(x_tag2, "entity", user_uri);
if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "display-text", off3++))) {
abort();
}
switch_xml_set_txt_d(x_tag3, np->cp->caller_id_name);
if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "status", off3++))) {
abort();
}
switch_xml_set_txt_d(x_tag3, np->leave_time ? "disconnected" : "connected");
if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "joining-info", off3++))) {
abort();
}
if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "when", off4++))) {
abort();
} else {
switch_time_exp_t tm;
switch_size_t retsize;
const char *fmt = "%Y-%m-%dT%H:%M:%S%z";
char *p;
switch_time_exp_lt(&tm, (switch_time_t) conference->start_time * 1000000);
switch_strftime_nocheck(tmp, &retsize, sizeof(tmp), fmt, &tm);
p = end_of_p(tmpp) -1;
snprintf(p, 4, ":00");
switch_xml_set_txt_d(x_tag4, tmpp);
}
/** ok so this is in the rfc but not the xsd
if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "joining-method", off3++))) {
abort();
}
switch_xml_set_txt_d(x_tag3, np->cp->direction == SWITCH_CALL_DIRECTION_INBOUND ? "dialed-in" : "dialed-out");
*/
if (np->member) {
switch_channel_t *channel = switch_core_session_get_channel(np->member->session);
const char *var;
if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "media", off3++))) {
abort();
}
snprintf(tmp, sizeof(tmp), "%ua", np->member->id);
switch_xml_set_attr_d(x_tag3, "id", tmpp);
if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "type", off4++))) {
abort();
}
switch_xml_set_txt_d(x_tag4, "audio");
if ((var = switch_channel_get_variable(channel, "rtp_use_ssrc"))) {
if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "src-id", off4++))) {
abort();
}
switch_xml_set_txt_d(x_tag4, var);
}
if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "status", off4++))) {
abort();
}
switch_xml_set_txt_d(x_tag4, switch_channel_test_flag(channel, CF_HOLD) ? "sendonly" : "sendrecv");
if (switch_channel_test_flag(channel, CF_VIDEO)) {
off4 = 0;
if (!(x_tag3 = switch_xml_add_child_d(x_tag2, "media", off3++))) {
abort();
}
snprintf(tmp, sizeof(tmp), "%uv", np->member->id);
switch_xml_set_attr_d(x_tag3, "id", tmpp);
if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "type", off4++))) {
abort();
}
switch_xml_set_txt_d(x_tag4, "video");
if ((var = switch_channel_get_variable(channel, "rtp_use_video_ssrc"))) {
if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "src-id", off4++))) {
abort();
}
switch_xml_set_txt_d(x_tag4, var);
}
if (!(x_tag4 = switch_xml_add_child_d(x_tag3, "status", off4++))) {
abort();
}
switch_xml_set_txt_d(x_tag4, switch_channel_test_flag(channel, CF_HOLD) ? "sendonly" : "sendrecv");
}
}
switch_safe_free(user_uri);
}
switch_mutex_unlock(conference->member_mutex);
off1 = off2 = off3 = off4 = 0;
xml_text = switch_xml_toxml(xml, SWITCH_TRUE);
switch_xml_free(xml);
switch_safe_free(dup_domain);
switch_safe_free(uri);
return xml_text;
}
static void conference_cdr_render(conference_obj_t *conference)
{
switch_xml_t cdr, x_ptr, x_member, x_members, x_conference, x_cp, x_flags, x_tag, x_rejected, x_attempt;
@ -966,6 +1219,45 @@ static switch_status_t member_del_relationship(conference_member_t *member, uint
return status;
}
static void send_rfc_event(conference_obj_t *conference)
{
switch_event_t *event;
char *body;
char *name = NULL, *domain = NULL, *dup_domain = NULL;
if (!switch_test_flag(conference, CFLAG_RFC4579)) {
return;
}
if (!(name = conference->name)) {
name = "conference";
}
if (!(domain = conference->domain)) {
dup_domain = switch_core_get_variable_dup("domain");
if (!(domain = dup_domain)) {
domain = "cluecon.com";
}
}
if (switch_event_create(&event, SWITCH_EVENT_CONFERENCE_DATA) == SWITCH_STATUS_SUCCESS) {
event->flags |= EF_UNIQ_HEADERS;
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "conference-name", name);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "conference-domain", domain);
body = conference_rfc4579_render(conference, NULL);
switch_event_add_body(event, body);
free(body);
switch_event_fire(&event);
}
switch_safe_free(dup_domain);
}
/* Gain exclusive access and add the member to the list */
static switch_status_t conference_add_member(conference_obj_t *conference, conference_member_t *member)
{
@ -1109,9 +1401,14 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe
switch_mutex_unlock(member->audio_out_mutex);
switch_mutex_unlock(member->audio_in_mutex);
send_rfc_event(conference);
switch_mutex_unlock(conference->mutex);
status = SWITCH_STATUS_SUCCESS;
return status;
}
@ -1248,6 +1545,11 @@ static switch_status_t conference_del_member(conference_obj_t *conference, confe
unlock_member(member);
switch_mutex_unlock(member->audio_out_mutex);
switch_mutex_unlock(member->audio_in_mutex);
send_rfc_event(conference);
switch_mutex_unlock(conference->mutex);
status = SWITCH_STATUS_SUCCESS;
@ -3089,7 +3391,7 @@ static void conference_loop_output(conference_member_t *member)
char *dial_str = switch_mprintf("%s%s", switch_str_nil(prefix), argv[x]);
switch_assert(dial_str);
conference_outcall_bg(member->conference, NULL, NULL, dial_str, to, switch_str_nil(flags), cid_name, cid_num, NULL,
profile, &member->conference->cancel_cause);
profile, &member->conference->cancel_cause, NULL);
switch_safe_free(dial_str);
}
switch_safe_free(cpstr);
@ -5229,9 +5531,9 @@ static switch_status_t conf_api_sub_dial(conference_obj_t *conference, switch_st
}
if (conference) {
conference_outcall(conference, NULL, NULL, argv[2], 60, NULL, argv[4], argv[3], NULL, &cause, NULL);
conference_outcall(conference, NULL, NULL, argv[2], 60, NULL, argv[4], argv[3], NULL, &cause, NULL, NULL);
} else {
conference_outcall(NULL, argv[0], NULL, argv[2], 60, NULL, argv[4], argv[3], NULL, &cause, NULL);
conference_outcall(NULL, argv[0], NULL, argv[2], 60, NULL, argv[4], argv[3], NULL, &cause, NULL, NULL);
}
stream->write_function(stream, "Call Requested: result: [%s]\n", switch_channel_cause2str(cause));
@ -5254,9 +5556,9 @@ static switch_status_t conf_api_sub_bgdial(conference_obj_t *conference, switch_
switch_uuid_format(uuid_str, &uuid);
if (conference) {
conference_outcall_bg(conference, NULL, NULL, argv[2], 60, NULL, argv[4], argv[3], uuid_str, NULL, NULL);
conference_outcall_bg(conference, NULL, NULL, argv[2], 60, NULL, argv[4], argv[3], uuid_str, NULL, NULL, NULL);
} else {
conference_outcall_bg(NULL, argv[0], NULL, argv[2], 60, NULL, argv[4], argv[3], uuid_str, NULL, NULL);
conference_outcall_bg(NULL, argv[0], NULL, argv[2], 60, NULL, argv[4], argv[3], uuid_str, NULL, NULL, NULL);
}
stream->write_function(stream, "OK Job-UUID: %s\n", uuid_str);
@ -5777,7 +6079,7 @@ static switch_status_t conference_outcall(conference_obj_t *conference,
char *cid_num,
char *profile,
switch_call_cause_t *cause,
switch_call_cause_t *cancel_cause)
switch_call_cause_t *cancel_cause, switch_event_t *var_event)
{
switch_core_session_t *peer_session = NULL;
switch_channel_t *peer_channel;
@ -5792,7 +6094,7 @@ static switch_status_t conference_outcall(conference_obj_t *conference,
if (conference == NULL) {
char *dialstr = switch_mprintf("{ignore_early_media=true}%s", bridgeto);
status = switch_ivr_originate(NULL, &peer_session, cause, dialstr, 60, NULL, cid_name, cid_num, NULL, NULL, SOF_NO_LIMITS, NULL);
status = switch_ivr_originate(NULL, &peer_session, cause, dialstr, 60, NULL, cid_name, cid_num, NULL, var_event, SOF_NO_LIMITS, NULL);
switch_safe_free(dialstr);
if (status != SWITCH_STATUS_SUCCESS) {
@ -5828,7 +6130,7 @@ static switch_status_t conference_outcall(conference_obj_t *conference,
switch_mutex_lock(conference->mutex);
conference->originating++;
switch_mutex_unlock(conference->mutex);
status = switch_ivr_originate(session, &peer_session, cause, bridgeto, timeout, NULL, cid_name, cid_num, NULL, NULL, SOF_NO_LIMITS, cancel_cause);
status = switch_ivr_originate(session, &peer_session, cause, bridgeto, timeout, NULL, cid_name, cid_num, NULL, var_event, SOF_NO_LIMITS, cancel_cause);
switch_mutex_lock(conference->mutex);
conference->originating--;
switch_mutex_unlock(conference->mutex);
@ -5920,6 +6222,7 @@ struct bg_call {
char *uuid;
char *profile;
switch_call_cause_t *cancel_cause;
switch_event_t *var_event;
switch_memory_pool_t *pool;
};
@ -5931,8 +6234,10 @@ static void *SWITCH_THREAD_FUNC conference_outcall_run(switch_thread_t *thread,
switch_call_cause_t cause;
switch_event_t *event;
conference_outcall(call->conference, call->conference_name,
call->session, call->bridgeto, call->timeout, call->flags, call->cid_name, call->cid_num, call->profile, &cause, call->cancel_cause);
call->session, call->bridgeto, call->timeout,
call->flags, call->cid_name, call->cid_num, call->profile, &cause, call->cancel_cause, call->var_event);
if (call->conference && test_eflag(call->conference, EFLAG_BGDIAL_RESULT) &&
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
@ -5942,6 +6247,11 @@ static void *SWITCH_THREAD_FUNC conference_outcall_run(switch_thread_t *thread,
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-UUID", call->uuid);
switch_event_fire(&event);
}
if (call->var_event) {
switch_event_destroy(&call->var_event);
}
switch_safe_free(call->bridgeto);
switch_safe_free(call->flags);
switch_safe_free(call->cid_name);
@ -5961,7 +6271,7 @@ static void *SWITCH_THREAD_FUNC conference_outcall_run(switch_thread_t *thread,
static switch_status_t conference_outcall_bg(conference_obj_t *conference,
char *conference_name,
switch_core_session_t *session, char *bridgeto, uint32_t timeout, const char *flags, const char *cid_name,
const char *cid_num, const char *call_uuid, const char *profile, switch_call_cause_t *cancel_cause)
const char *cid_num, const char *call_uuid, const char *profile, switch_call_cause_t *cancel_cause, switch_event_t **var_event)
{
struct bg_call *call = NULL;
switch_thread_t *thread;
@ -5977,6 +6287,11 @@ static switch_status_t conference_outcall_bg(conference_obj_t *conference,
call->timeout = timeout;
call->cancel_cause = cancel_cause;
if (var_event) {
call->var_event = *var_event;
var_event = NULL;
}
if (conference) {
pool = conference->pool;
} else {
@ -6152,7 +6467,11 @@ static void set_cflags(const char *flags, uint32_t *f)
*f |= CFLAG_VIDEO_BRIDGE;
} else if (!strcasecmp(argv[i], "audio-always")) {
*f |= CFLAG_AUDIO_ALWAYS;
} else if (!strcasecmp(argv[i], "rfc-4579")) {
*f |= CFLAG_RFC4579;
}
}
free(dup);
@ -6403,30 +6722,34 @@ SWITCH_STANDARD_APP(conference_function)
switch_channel_set_app_flag_key("conf_silent", channel, CONF_SILENT_REQ);
}
switch_channel_set_flag(channel, CF_CONFERENCE);
if (switch_channel_answer(channel) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Channel answer failed.\n");
return;
goto end;
}
/* Save the original read codec. */
if (!(read_codec = switch_core_session_get_read_codec(session))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Channel has no media!\n");
return;
goto end;
}
if (zstr(data)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Invalid arguments\n");
return;
goto end;
}
mydata = switch_core_session_strdup(session, data);
if (!mydata) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Pool Failure\n");
return;
goto end;
}
if ((flags_str = strstr(mydata, flags_prefix))) {
char *p;
*((char *) flags_str) = '\0';
@ -6764,7 +7087,7 @@ SWITCH_STANDARD_APP(conference_function)
/* if we're using "bridge:" make an outbound call and bridge it in */
if (!zstr(bridgeto) && strcasecmp(bridgeto, "none")) {
switch_call_cause_t cause;
if (conference_outcall(conference, NULL, session, bridgeto, 60, NULL, NULL, NULL, NULL, &cause, NULL) != SWITCH_STATUS_SUCCESS) {
if (conference_outcall(conference, NULL, session, bridgeto, 60, NULL, NULL, NULL, NULL, &cause, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
goto done;
}
} else {
@ -6913,6 +7236,11 @@ SWITCH_STANDARD_APP(conference_function)
}
switch_channel_set_variable(channel, "last_transfered_conference", NULL);
end:
switch_channel_clear_flag(channel, CF_CONFERENCE);
}
/* Create a thread for the conference and launch it */
@ -7123,6 +7451,7 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c
switch_xml_t xml_kvp;
char *timer_name = NULL;
char *domain = NULL;
char *desc = NULL;
char *name_domain = NULL;
char *tts_engine = NULL;
char *tts_voice = NULL;
@ -7246,6 +7575,8 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c
}
} else if (!strcasecmp(var, "domain") && !zstr(val)) {
domain = val;
} else if (!strcasecmp(var, "description") && !zstr(val)) {
desc = val;
} else if (!force_interval_i && !strcasecmp(var, "interval") && !zstr(val)) {
uint32_t tmp = atoi(val);
@ -7606,6 +7937,11 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c
if (!zstr(auto_record)) {
conference->auto_record = switch_core_strdup(conference->pool, auto_record);
}
if (!zstr(desc)) {
conference->desc = switch_core_strdup(conference->pool, desc);
}
if (!zstr(terminate_on_silence)) {
conference->terminate_on_silence = atoi(terminate_on_silence);
}
@ -7681,6 +8017,89 @@ static void conference_send_presence(conference_obj_t *conference)
}
static void call_setup_event_handler(switch_event_t *event)
{
char *conf;
char *dial_str;
char *action;
conference_obj_t *conference = NULL;
if (!switch_test_flag(conference, CFLAG_RFC4579)) {
return;
}
conf = switch_event_get_header(event, "Target-Component");
dial_str = switch_event_get_header(event, "Request-Target");
action = switch_event_get_header(event, "Request-Action");
if (!zstr(conf) && !zstr(dial_str) && !zstr(action) && (conference = conference_find(conf))) {
switch_event_t *var_event;
switch_event_header_t *hp;
if (!strcasecmp(action, "call")) {
if (switch_event_create_plain(&var_event, SWITCH_EVENT_CHANNEL_DATA) != SWITCH_STATUS_SUCCESS) {
abort();
}
for(hp = event->headers; hp; hp = hp->next) {
if (!strncasecmp(hp->name, "var_", 4)) {
switch_event_add_header(var_event, SWITCH_STACK_BOTTOM, hp->name + 4, hp->value);
}
}
switch_event_add_header(var_event, SWITCH_STACK_BOTTOM, "conference_dial_str", dial_str);
conference_outcall_bg(conference, NULL, NULL, dial_str, 60, NULL, NULL, NULL, NULL, NULL, NULL, &var_event);
} else if (!strcasecmp(action, "end")) {
switch_core_session_hupall_matching_var("conference_dial_str", dial_str, SWITCH_CAUSE_NORMAL_CLEARING);
}
switch_thread_rwlock_unlock(conference->rwlock);
}
}
static void conf_data_event_handler(switch_event_t *event)
{
switch_event_t *revent;
char *name = switch_event_get_header(event, "conference-name");
conference_obj_t *conference = NULL;
char *body = NULL;
switch_event_dup(&revent, event);
revent->event_id = SWITCH_EVENT_CONFERENCE_DATA;
revent->flags |= EF_UNIQ_HEADERS;
switch_event_add_header(revent, SWITCH_STACK_TOP, "Event-Name", "CONFERENCE_DATA");
if (!zstr(name) && (conference = conference_find(name))) {
if (switch_test_flag(conference, CFLAG_RFC4579)) {
body = conference_rfc4579_render(conference, event);
}
switch_thread_rwlock_unlock(conference->rwlock);
}
if (!body) {
char *domain = switch_event_get_header(event, "conference-domain");
if (zstr(domain)) {
domain = "cluecon.com";
}
body = switch_mprintf("<conference-info xmlns=\"urn:ietf:params:xml:ns:conference-info\" "
"entity=\"sip:%s@%s\" state=\"full\"/>\n", name, domain);
switch_event_add_header(revent, SWITCH_STACK_BOTTOM, "notfound", "true");
}
switch_event_add_body(revent, body);
switch_event_fire(&revent);
switch_safe_free(body);
}
static void pres_event_handler(switch_event_t *event)
{
@ -7997,10 +8416,16 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_conference_load)
switch_mutex_init(&globals.setup_mutex, SWITCH_MUTEX_NESTED, globals.conference_pool);
/* Subscribe to presence request events */
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL, &globals.node) !=
SWITCH_STATUS_SUCCESS) {
if (switch_event_bind(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't subscribe to presence request events!\n");
return SWITCH_STATUS_GENERR;
}
if (switch_event_bind(modname, SWITCH_EVENT_CONFERENCE_DATA_QUERY, SWITCH_EVENT_SUBCLASS_ANY, conf_data_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't subscribe to conference data query events!\n");
}
if (switch_event_bind(modname, SWITCH_EVENT_CALL_SETUP_REQ, SWITCH_EVENT_SUBCLASS_ANY, call_setup_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't subscribe to conference data query events!\n");
}
SWITCH_ADD_API(api_interface, "conference", "Conference module commands", conf_api_main, p);
@ -8031,7 +8456,9 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_conference_shutdown)
switch_yield(100000);
}
switch_event_unbind(&globals.node);
switch_event_unbind_callback(pres_event_handler);
switch_event_unbind_callback(conf_data_event_handler);
switch_event_unbind_callback(call_setup_event_handler);
switch_event_free_subclass(CONF_EVENT_MAINT);
/* free api interface help ".syntax" field string */

View File

@ -1145,6 +1145,18 @@ SWITCH_STANDARD_APP(set_name_function)
SWITCH_STANDARD_APP(answer_function)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
const char *arg = (char *) data;
if (zstr(arg)) {
arg = switch_channel_get_variable(channel, "answer_flags");
}
if (!zstr(arg)) {
if (!switch_stristr("is_conference", arg)) {
switch_channel_set_flag(channel, CF_CONFERENCE);
}
}
switch_channel_answer(channel);
}

View File

@ -665,7 +665,10 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
int is_3pcc = 0;
char *sticky = NULL;
const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full");
if (switch_channel_test_flag(channel, CF_CONFERENCE)) {
tech_pvt->reply_contact = switch_core_session_sprintf(session, "%s;isfocus", tech_pvt->reply_contact);
}
if(sofia_test_flag(tech_pvt, TFLAG_3PCC_INVITE)) {
// SNARK: complete hack to get final ack sent when a 3pcc invite has been passed from the other leg in bypass_media mode.
@ -5554,44 +5557,48 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for profiles to start\n");
switch_yield(1500000);
if (switch_event_bind_removable(modname, SWITCH_EVENT_CUSTOM, MULTICAST_EVENT, event_handler, NULL,
&mod_sofia_globals.custom_node) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind(modname, SWITCH_EVENT_CUSTOM, MULTICAST_EVENT, event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_TERM;
}
if (switch_event_bind_removable(modname, SWITCH_EVENT_PRESENCE_IN, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL,
&mod_sofia_globals.in_node) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind(modname, SWITCH_EVENT_CONFERENCE_DATA, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_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_removable(modname, SWITCH_EVENT_PRESENCE_OUT, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL,
&mod_sofia_globals.out_node) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind(modname, SWITCH_EVENT_PRESENCE_IN, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_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_removable(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL,
&mod_sofia_globals.probe_node) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind(modname, SWITCH_EVENT_PRESENCE_OUT, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_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_removable(modname, SWITCH_EVENT_ROSTER, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL,
&mod_sofia_globals.roster_node) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_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_removable(modname, SWITCH_EVENT_MESSAGE_WAITING, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_mwi_event_handler, NULL,
&mod_sofia_globals.mwi_node) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind(modname, SWITCH_EVENT_ROSTER, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_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_removable(modname, SWITCH_EVENT_CUSTOM, MY_EVENT_RECOVERY, sofia_glue_track_event_handler, NULL,
&mod_sofia_globals.recovery_node) != SWITCH_STATUS_SUCCESS) {
if (switch_event_bind(modname, SWITCH_EVENT_MESSAGE_WAITING, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_mwi_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(modname, SWITCH_EVENT_CUSTOM, MY_EVENT_RECOVERY, sofia_glue_track_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_GENERR;
}
@ -5709,14 +5716,11 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown)
}
switch_mutex_unlock(mod_sofia_globals.mutex);
switch_event_unbind(&mod_sofia_globals.in_node);
switch_event_unbind(&mod_sofia_globals.probe_node);
switch_event_unbind(&mod_sofia_globals.out_node);
switch_event_unbind(&mod_sofia_globals.roster_node);
switch_event_unbind(&mod_sofia_globals.custom_node);
switch_event_unbind(&mod_sofia_globals.mwi_node);
switch_event_unbind(&mod_sofia_globals.recovery_node);
switch_event_unbind_callback(sofia_presence_event_handler);
switch_event_unbind_callback(sofia_presence_mwi_event_handler);
switch_event_unbind_callback(sofia_glue_track_event_handler);
switch_event_unbind_callback(general_event_handler);
switch_event_unbind_callback(event_handler);
while (mod_sofia_globals.threads) {
switch_cond_next();

View File

@ -368,13 +368,6 @@ struct mod_sofia_globals {
int msg_queue_len;
struct sofia_private destroy_private;
struct sofia_private keep_private;
switch_event_node_t *in_node;
switch_event_node_t *probe_node;
switch_event_node_t *out_node;
switch_event_node_t *roster_node;
switch_event_node_t *custom_node;
switch_event_node_t *mwi_node;
switch_event_node_t *recovery_node;
int guess_mask;
char guess_mask_str[16];
int debug_presence;

View File

@ -1189,8 +1189,59 @@ static void our_sofia_event_callback(nua_event_t event,
case nua_r_refer:
break;
case nua_i_refer:
if (session)
if (session) {
sofia_handle_sip_i_refer(nua, profile, nh, session, sip, de, tags);
} else {
const char *req_user = NULL, *req_host = NULL, *action = NULL, *ref_by_user = NULL;
char *refer_to = NULL, *referred_by = NULL, *method = NULL;
char *params = NULL;
switch_event_t *event;
if (sip->sip_refer_to) {
refer_to = sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_refer_to);
if ((params = strchr(refer_to, ';'))) {
*params++ = '\0';
if ((method = switch_find_parameter(params, "method", NULL))) {
if (!strcasecmp(method, "INVITE")) {
action = "call";
} else if (!strcasecmp(method, "BYE")) {
action = "end";
} else {
action = method;
}
}
}
refer_to = sofia_glue_get_url_from_contact(refer_to, 0);
}
if (sip->sip_referred_by) {
referred_by = sofia_glue_get_url_from_contact(sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_referred_by), 0);
ref_by_user = sip->sip_referred_by->b_url->url_user;
}
if (sip->sip_request && sip->sip_request->rq_url) {
req_user = sip->sip_request->rq_url->url_user;
req_host = sip->sip_request->rq_url->url_host;
}
if (switch_event_create(&event, SWITCH_EVENT_CALL_SETUP_REQ) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Requesting-Component", "mod_sofia");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Target-Component", req_user);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Target-Domain", req_host);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Request-Action", action);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Request-Target", "sofia/%s/%s", profile->name, refer_to);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Request-Sender", "sofia/%s/%s", profile->name, referred_by);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "var_origination_caller_id_number", ref_by_user);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "var_origination_caller_id_name", ref_by_user);
switch_event_fire(&event);
}
nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
switch_safe_free(method);
}
break;
case nua_r_subscribe:
sofia_presence_handle_sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, de, tags);
@ -2112,13 +2163,6 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
nua_set_params(profile->nua,
SIPTAG_ALLOW_STR("INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, UPDATE, INFO"),
NUTAG_APPL_METHOD("OPTIONS"),
NUTAG_APPL_METHOD("REFER"),
NUTAG_APPL_METHOD("REGISTER"),
NUTAG_APPL_METHOD("NOTIFY"), NUTAG_APPL_METHOD("INFO"), NUTAG_APPL_METHOD("ACK"), NUTAG_APPL_METHOD("SUBSCRIBE"),
#ifdef MANUAL_BYE
NUTAG_APPL_METHOD("BYE"),
#endif
NUTAG_AUTOANSWER(0),
NUTAG_AUTOACK(0),
NUTAG_AUTOALERT(0),
@ -2131,6 +2175,15 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
NUTAG_ALLOW("NOTIFY"),
NUTAG_ALLOW_EVENTS("talk"),
NUTAG_ALLOW_EVENTS("hold"),
NUTAG_ALLOW_EVENTS("conference"),
NUTAG_APPL_METHOD("OPTIONS"),
NUTAG_APPL_METHOD("REFER"),
NUTAG_APPL_METHOD("REGISTER"),
NUTAG_APPL_METHOD("NOTIFY"), NUTAG_APPL_METHOD("INFO"), NUTAG_APPL_METHOD("ACK"), NUTAG_APPL_METHOD("SUBSCRIBE"),
#ifdef MANUAL_BYE
NUTAG_APPL_METHOD("BYE"),
#endif
NUTAG_SESSION_TIMER(profile->session_timeout),
NTATAG_MAX_PROCEEDING(profile->max_proceeding),
TAG_IF(profile->pres_type, NUTAG_ALLOW("PUBLISH")),
@ -6829,11 +6882,13 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
goto done;
}
printf("DICK %d\n", __LINE__);
if (!sip->sip_cseq || !(etmp = switch_mprintf("refer;id=%u", sip->sip_cseq->cs_seq))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Memory Error!\n");
goto done;
}
printf("DICK %d\n", __LINE__);
from = sip->sip_from;
//to = sip->sip_to;
@ -6850,7 +6905,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
}
if ((refer_to = sip->sip_refer_to)) {
char *rep;
char *rep = NULL;
full_ref_to = sip_header_as_string(home, (void *) sip->sip_refer_to);
if (sofia_test_pflag(profile, PFLAG_FULL_ID)) {
@ -6861,7 +6916,16 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Process REFER to [%s@%s]\n", exten, (char *) refer_to->r_url->url_host);
if (refer_to->r_url->url_headers && (rep = (char *) switch_stristr("Replaces=", refer_to->r_url->url_headers))) {
if (refer_to->r_url && refer_to->r_url->url_headers) {
rep = (char *) switch_stristr("Replaces=", refer_to->r_url->url_headers);
}
printf("WTFX %s\n", rep);
if (!rep) {
printf("WTF [%s]\n", refer_to->r_url->url_headers);
} else {
sip_replaces_t *replaces;
nua_handle_t *bnh = NULL;

View File

@ -862,7 +862,102 @@ static void do_dialog_probe(switch_event_t *event)
switch_safe_free(probe_user);
}
static void send_conference_data(sofia_profile_t *profile, switch_event_t *event)
{
char *sql;
struct pres_sql_cb cb = {profile, 0};
const char *call_id = switch_event_get_header(event, "call_id");
const char *from_user = switch_event_get_header(event, "conference-name");
const char *from_host = switch_event_get_header(event, "conference-domain");
const char *notfound = switch_event_get_header(event, "notfound");
const char *body = switch_event_get_body(event);
if (!(from_user && from_host)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Event information not given\n");
return;
}
if (switch_true(notfound)) {
sql = switch_mprintf("update sip_subscriptions set expires=%ld where "
"hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='conference'",
(long)switch_epoch_time_now(NULL),
mod_sofia_globals.hostname, profile->name,
from_user, from_host);
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
}
if (call_id) {
sql = switch_mprintf("select full_to, full_from, contact %q ';_;isfocus', expires, call_id, event, network_ip, network_port, "
"'application/conference-info+xml' as ct,'%q' as pt "
" from sip_subscriptions where "
"hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='conference'"
"and call_id = '%q' ",
switch_sql_concat(),
switch_str_nil(body),
mod_sofia_globals.hostname, profile->name,
from_user, from_host, call_id);
} else {
sql = switch_mprintf("select full_to, full_from, contact %q ';_;isfocus', expires, call_id, event, network_ip, network_port, "
"'application/conference-info+xml' as ct,'%q' as pt "
" from sip_subscriptions where "
"hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='conference'",
switch_sql_concat(),
switch_str_nil(body),
mod_sofia_globals.hostname, profile->name,
from_user, from_host);
}
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_send_sql, &cb);
switch_safe_free(sql);
}
static void conference_data_event_handler(switch_event_t *event)
{
const char *pname;
//const char *from_user = switch_event_get_header(event, "conference-name");
//const char *from_host = switch_event_get_header(event, "conference-domain");
const char *host = switch_event_get_header(event, "conference-domain");
char *dup_domain = NULL;
sofia_profile_t *profile = NULL;
if (zstr(host)) {
dup_domain = switch_core_get_variable_dup("domain");
host = dup_domain;
}
if ((pname = switch_event_get_header(event, "sofia-profile"))) {
profile = sofia_glue_find_profile(pname);
}
if (host && !profile) {
profile = sofia_glue_find_profile(host);
}
if (profile) {
send_conference_data(profile, event);
sofia_glue_release_profile(profile);
} else {
switch_console_callback_match_t *matches;
if (list_profiles_full(NULL, NULL, &matches, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
switch_console_callback_match_node_t *m;
for (m = matches->head; m; m = m->next) {
if ((profile = sofia_glue_find_profile(m->val))) {
send_conference_data(profile, event);
sofia_glue_release_profile(profile);
}
}
switch_console_free_matches(&matches);
}
}
switch_safe_free(dup_domain);
}
static void actual_sofia_presence_event_handler(switch_event_t *event)
{
@ -1374,7 +1469,13 @@ void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread
if (!pop) {
break;
}
actual_sofia_presence_event_handler(event);
if (event->event_id == SWITCH_EVENT_CONFERENCE_DATA) {
conference_data_event_handler(event);
} else {
actual_sofia_presence_event_handler(event);
}
switch_event_destroy(&event);
count++;
}
@ -1871,14 +1972,22 @@ static void _send_presence_notify(sofia_profile_t *profile,
char *our_contact = profile->url, *our_contact_dup = NULL;
sofia_destination_t *dst = NULL;
char *contact_str, *contact, *user_via = NULL;
char *contact_str, *contact, *user_via = NULL, *send_contact = NULL;
char *route_uri = NULL, *o_contact_dup = NULL, *tmp, *to_uri, *dcs = NULL;
const char *tp;
char *cparams = NULL;
if (zstr(full_to) || zstr(full_from) || zstr(o_contact)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "MISSING DATA TO SEND NOTIFY.\n");
return;
}
if ((cparams = strstr(o_contact, ";_;"))) {
cparams += 3;
}
tmp = (char *)o_contact;
o_contact_dup = sofia_glue_get_url_from_contact(tmp, 1);
@ -2012,6 +2121,12 @@ static void _send_presence_notify(sofia_profile_t *profile,
callsequence = ++profile->cseq_base;
switch_mutex_unlock(profile->ireg_mutex);
if (cparams) {
send_contact = switch_mprintf("%s;%s", contact_str, cparams);
contact_str = send_contact;
}
nh = nua_handle(profile->nua, NULL, NUTAG_URL(contact), SIPTAG_CONTACT_STR(contact_str), TAG_END());
cseq = sip_cseq_create(nh->nh_home, callsequence, SIP_METHOD_NOTIFY);
@ -2047,6 +2162,7 @@ static void _send_presence_notify(sofia_profile_t *profile,
sofia_glue_free_destination(dst);
switch_safe_free(user_via);
switch_safe_free(o_contact_dup);
switch_safe_free(send_contact);
switch_safe_free(our_contact_dup);
@ -3649,9 +3765,17 @@ void sofia_presence_handle_sip_i_subscribe(int status,
switch_safe_free(sql);
}
}
if ( sip->sip_event && sip->sip_event->o_type && !strcasecmp(sip->sip_event->o_type, "ua-profile") && contact_host ) {
} else if (!strcasecmp(event, "conference")) {
switch_event_t *event;
switch_event_create(&event, SWITCH_EVENT_CONFERENCE_DATA_QUERY);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Conference-Name", to_user);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Conference-Domain", to_host);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Query-From", from_user);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Query-From-Domain", from_host);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Call-Id", call_id);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Sofia-Profile", profile->name);
switch_event_fire(&event);
} else if ( sip->sip_event && sip->sip_event->o_type && !strcasecmp(sip->sip_event->o_type, "ua-profile") && contact_host ) {
switch_event_t *params;
char *uri = NULL;
char *extra_headers = NULL;

View File

@ -193,6 +193,10 @@ static char *EVENT_NAMES[] = {
"SOCKET_DATA",
"MEDIA_BUG_START",
"MEDIA_BUG_STOP",
"CONFERENCE_DATA_QUERY",
"CONFERENCE_DATA",
"CALL_SETUP_REQ",
"CALL_SETUP_RESULT",
"ALL"
};

View File

@ -4676,7 +4676,7 @@ SWITCH_DECLARE(int) switch_rtp_write_manual(switch_rtp_t *rtp_session,
SWITCH_DECLARE(uint32_t) switch_rtp_get_ssrc(switch_rtp_t *rtp_session)
{
return rtp_session->send_msg.header.ssrc;
return rtp_session->ssrc;
}
SWITCH_DECLARE(void) switch_rtp_set_private(switch_rtp_t *rtp_session, void *private_data)