struct conference_member;
typedef struct conference_member conference_member_t;
+struct call_list {
+ char *string;
+ int itteration;
+ struct call_list *next;
+};
+typedef struct call_list call_list_t;
+
struct caller_control_actions;
typedef struct caller_control_fn_table {
char *caller_id_name;
char *caller_id_number;
char *sound_prefix;
+ char *special_announce;
uint32_t max_members;
char *maxmember_sound;
uint32_t anounce_count;
static void launch_conference_thread(conference_obj_t * conference);
static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t * thread, void *obj);
static switch_status_t conference_local_play_file(conference_obj_t * conference,
- switch_core_session_t *session, char *path, uint32_t leadin, char *buf, switch_size_t len);
+ switch_core_session_t *session, char *path, uint32_t leadin);
static switch_status_t conference_member_play_file(conference_member_t * member, char *file, uint32_t leadin);
static switch_status_t conference_member_say(conference_member_t * member, char *text, uint32_t leadin);
static uint32_t conference_member_stop_file(conference_member_t * member, file_stop_t stop);
switch_status_t status = SWITCH_STATUS_FALSE;
switch_event_t *event;
char msg[512]; // for conference count anouncement
+ call_list_t *call_list = NULL;
+ switch_channel_t *channel;
assert(conference != NULL);
assert(member != NULL);
if (conference->count > 1 && conference->enter_sound) {
conference_play_file(conference, conference->enter_sound, CONF_DEFAULT_LEADIN, switch_core_session_get_channel(member->session), 0);
}
- // anounce the total number of members in the conference
- if (conference->count >= conference->anounce_count && conference->anounce_count > 1) {
- snprintf(msg, sizeof(msg), "There are %d callers", conference->count);
- conference_member_say(member, msg, CONF_DEFAULT_LEADIN);
- } else if (conference->count == 1) {
- if (conference->alone_sound) {
- conference_play_file(conference, conference->alone_sound, CONF_DEFAULT_LEADIN, switch_core_session_get_channel(member->session), 0);
- } else {
- snprintf(msg, sizeof(msg), "You are currently the only person in this conference.");
- conference_member_say(member, msg, CONF_DEFAULT_LEADIN);
- }
+
+ channel = switch_core_session_get_channel(member->session);
+ call_list = (call_list_t *) switch_channel_get_private(channel, "_conference_autocall_list_");
+
+ if (call_list) {
+ char msg[1024];
+ snprintf(msg, sizeof(msg), "Auto Calling %d parties", call_list->itteration);
+ conference_member_say(member, msg, 0);
+ } else {
+ if (switch_strlen_zero(conference->special_announce)) {
+ // anounce the total number of members in the conference
+ if (conference->count >= conference->anounce_count && conference->anounce_count > 1) {
+ snprintf(msg, sizeof(msg), "There are %d callers", conference->count);
+ conference_member_say(member, msg, CONF_DEFAULT_LEADIN);
+ } else if (conference->count == 1) {
+ if (conference->alone_sound) {
+ conference_play_file(conference, conference->alone_sound, CONF_DEFAULT_LEADIN, switch_core_session_get_channel(member->session), 0);
+ } else {
+ snprintf(msg, sizeof(msg), "You are currently the only person in this conference.");
+ conference_member_say(member, msg, CONF_DEFAULT_LEADIN);
+ }
+ }
+ }
}
+
+
if (conference->min && conference->count >= conference->min) {
switch_set_flag(conference, CFLAG_ENFORCE_MIN);
}
//uint32_t samples = switch_bytes_per_frame(member->conference->rate, member->conference->interval);
uint32_t samples = switch_bytes_per_frame(read_codec->implementation->samples_per_second, interval);
uint32_t low_count = 0, bytes = samples * 2;
+ call_list_t *call_list = NULL, *cp = NULL;
channel = switch_core_session_get_channel(member->session);
/* build a digit stream object */
if (member->conference->dtmf_parser != NULL
&& switch_ivr_digit_stream_new(member->conference->dtmf_parser, &member->digit_stream) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Warning Will Robinson, there is no digit parser stream object\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Danger Will Robinson, there is no digit parser stream object\n");
}
+
+
+ if ((call_list = switch_channel_get_private(channel, "_conference_autocall_list_"))) {
+ char *cid_name = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_name");
+ char *cid_num = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_number");
+ char *toval = switch_channel_get_variable(channel, "conference_auto_outcall_timeout");
+ char *flags = switch_channel_get_variable(channel, "conference_auto_outcall_flags");
+ char *ann = switch_channel_get_variable(channel, "conference_auto_outcall_announce");
+ int to = 60;
+
+ if (ann) {
+ member->conference->special_announce = switch_core_strdup(member->conference->pool, ann);
+ }
+ switch_channel_set_private(channel, "_conference_autocall_list_", NULL);
+
+ if (toval) {
+ to = atoi(toval);
+ }
+
+ if (to < 10 || to > 500) {
+ to = 60;
+ }
+
+ for (cp = call_list; cp; cp = cp->next) {
+ conference_outcall_bg(member->conference, NULL, member->session, cp->string, to, switch_str_nil(flags), cid_name, cid_num);
+
+ }
+
+ }
/* Fair WARNING, If you expect the caller to hear anything or for digit handling to be proccessed, */
/* you better not block this thread loop for more than the duration of member->conference->timer_name! */
while (switch_test_flag(member, MFLAG_RUNNING) && switch_test_flag(member, MFLAG_ITHREAD)
goto done;
}
/* add them to the conference */
- if (flags && strcasecmp(flags, "none")) {
- snprintf(appdata, sizeof(appdata), "%s +flags{%s}", conference_name, flags);
+ if (flags && !strcasecmp(flags, "none")) {
+ snprintf(appdata, sizeof(appdata), "%s+flags{%s}", conference_name, flags);
switch_caller_extension_add_application(peer_session, extension, (char *) global_app_name, appdata);
} else {
switch_caller_extension_add_application(peer_session, extension, (char *) global_app_name, conference_name);
switch_call_cause_t cause;
switch_event_t *event;
- conference_outcall(call->conference, NULL, call->session, call->bridgeto, call->timeout, call->flags, call->cid_name, call->cid_num, &cause);
+ conference_outcall(call->conference, call->conference_name,
+ call->session, call->bridgeto, call->timeout, call->flags, call->cid_name, call->cid_num, &cause);
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Name", "%s", call->conference->name);
/* Play a file */
static switch_status_t conference_local_play_file(conference_obj_t * conference,
- switch_core_session_t *session, char *path, uint32_t leadin, char *buf, switch_size_t len)
+ switch_core_session_t *session, char *path, uint32_t leadin)
{
uint32_t x = 0;
switch_status_t status = SWITCH_STATUS_SUCCESS;
+ switch_channel_t *channel;
+ char *expanded = NULL;
/* generate some space infront of the file to be played */
for (x = 0; x < leadin; x++) {
/* if all is well, really play the file */
if (status == SWITCH_STATUS_SUCCESS) {
char *dpath = NULL;
+
+ channel = switch_core_session_get_channel(session);
+ if ((expanded = switch_channel_expand_variables(channel, path)) != path) {
+ path = expanded;
+ } else {
+ expanded = NULL;
+ }
+
+ if (!strncasecmp(path, "say:", 4)) {
+ if (!(conference->tts_engine && conference->tts_voice)) {
+ status = SWITCH_STATUS_FALSE;
+ } else {
+ status = switch_ivr_speak_text(session, conference->tts_engine, conference->tts_voice, 0, path + 4, NULL);
+ }
+ goto done;
+ }
+
if (conference->sound_prefix) {
if (!(dpath = switch_mprintf("%s/%s", conference->sound_prefix, path))) {
- return SWITCH_STATUS_MEMERR;
+ status = SWITCH_STATUS_MEMERR;
+ goto done;
}
path = dpath;
}
switch_safe_free(dpath);
}
+ done:
+ switch_safe_free(expanded);
+
return status;
}
}
+static void conference_auto_function(switch_core_session_t *session, char *data)
+{
+ switch_channel_t *channel = NULL;
+ call_list_t *call_list, *np;
+ char *addition = (char *) data;
+
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
+
+ call_list = switch_channel_get_private(channel, "_conference_autocall_list_");
+
+ if (switch_strlen_zero(addition)) {
+ call_list = NULL;
+ } else {
+ np = switch_core_session_alloc(session, sizeof(*np));
+ assert(np != NULL);
+
+ np->string = switch_core_session_strdup(session, addition);
+ if (call_list) {
+ np->next = call_list;
+ np->itteration = call_list->itteration + 1;
+ } else {
+ np->itteration = 1;
+ }
+
+ call_list = np;
+
+ }
+
+ switch_channel_set_private(channel, "_conference_autocall_list_", call_list);
+
+
+}
/* Application interface function that is called from the dialplan to join the channel to a conference */
static void conference_function(switch_core_session_t *session, char *data)
if (!(conference = (conference_obj_t *) switch_core_hash_find(globals.conference_hash, conf_name))) {
/* couldn't find the conference, create one */
conference = conference_new(conf_name, xml_cfg, NULL);
-
+
if (!conference) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
goto done;
/* be friendly */
if (conference->pin_sound) {
- conference_local_play_file(conference, session, conference->pin_sound, 20, pin_buf, sizeof(pin_buf));
+ conference_local_play_file(conference, session, conference->pin_sound, 20);
}
/* wait for them if neccessary */
if (strlen(pin_buf) < strlen(conference->pin)) {
/* more friendliness */
if (conference->bad_pin_sound) {
- conference_local_play_file(conference, session, conference->bad_pin_sound, 20, pin_buf, sizeof(pin_buf));
+ conference_local_play_file(conference, session, conference->bad_pin_sound, 20);
}
}
pin_retries--;
}
}
+ if (conference->special_announce) {
+ conference_local_play_file(conference, session, conference->special_announce, CONF_DEFAULT_LEADIN);
+ }
+
/* don't allow more callers if the conference is locked, unless we invited them */
if (switch_test_flag(conference, CFLAG_LOCKED) && !switch_channel_test_flag(channel, CF_OUTBOUND)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Conference %s is locked.\n", conf_name);
if (conference->locked_sound) {
/* Answer the channel */
switch_channel_answer(channel);
- conference_local_play_file(conference, session, conference->locked_sound, 20, NULL, 0);
+ conference_local_play_file(conference, session, conference->locked_sound, 20);
}
goto done;
}
if (conference->maxmember_sound) {
/* Answer the channel */
switch_channel_answer(channel);
- conference_local_play_file(conference, session, conference->maxmember_sound, 20, NULL, 0);
+ conference_local_play_file(conference, session, conference->maxmember_sound, 20);
}
goto done;
}
/* Run the confernece loop */
conference_loop_output(&member);
-
+ switch_channel_set_private(channel, "_conference_autocall_list_", NULL);
+
/* Tell the channel we are no longer going to be in a bridge */
msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE;
switch_core_session_receive_message(session, &msg);
switch_thread_create(&thread, thd_attr, conference_record_thread_run, rec, rec->pool);
}
+static const switch_application_interface_t conference_autocall_application_interface = {
+ /*.interface_name */ "conference_set_auto_outcall",
+ /*.application_function */ conference_auto_function,
+ NULL, NULL, NULL,
+ /* flags */ SAF_NONE,
+ /*.next */
+};
+
static const switch_application_interface_t conference_application_interface = {
/*.interface_name */ global_app_name,
/*.application_function */ conference_function,
NULL, NULL, NULL,
/* flags */ SAF_NONE,
- /*.next */ NULL
+ /*.next */ &conference_autocall_application_interface
};
static switch_api_interface_t conf_api_interface = {