Index: mod_conference.c =================================================================== --- mod_conference.c (revision 10020) +++ mod_conference.c (working copy) @@ -59,6 +59,13 @@ #define test_eflag(conference, flag) ((conference)->eflags & flag) +#ifdef _MSC_VER /* compilers are stupid sometimes */ +#define TRY_CODE(code) for(;;) {status = code; if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { goto end; } break;} +#else +#define TRY_CODE(code) do { status = code; if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { goto end; } break;} while(status) +#endif + + typedef enum { FILE_STOP_CURRENT, FILE_STOP_ALL, @@ -148,7 +155,8 @@ CFLAG_ENFORCE_MIN = (1 << 2), CFLAG_DESTRUCT = (1 << 3), CFLAG_LOCKED = (1 << 4), - CFLAG_ANSWERED = (1 << 5) + CFLAG_ANSWERED = (1 << 5), + CFLAG_INTROUSER = (1 << 6) } conf_flag_t; typedef enum { @@ -383,6 +391,128 @@ static switch_status_t conference_add_event_data(conference_obj_t *conference, switch_event_t *event); static switch_status_t conference_add_event_member_data(conference_member_t *member, switch_event_t *event); +static switch_status_t vm_macro_get(switch_core_session_t *session, + char *macro, + char *macro_arg, + char *buf, switch_size_t buflen, switch_size_t maxlen, char *term_chars, char *terminator_key, uint32_t timeout) +{ + switch_input_args_t args = { 0 }, *ap = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_size_t bslen; + + if (buf && buflen) { + memset(buf, 0, buflen); + //args.input_callback = cancel_on_dtmf; + args.buf = buf; + args.buflen = (uint32_t) buflen; + ap = &args; + } + + status = switch_ivr_phrase_macro(session, macro, macro_arg, NULL, ap); + + if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { + if (buf) { + memset(buf, 0, buflen); + } + return status; + } + + if (!buf) { + return status; + } + + bslen = strlen(buf); + + if (maxlen == 0 || maxlen > buflen - 1) { + maxlen = buflen - 1; + } + + if (bslen < maxlen) { + status = switch_ivr_collect_digits_count(session, buf + bslen, buflen, maxlen - bslen, term_chars, terminator_key, timeout, 0, 0); + if (status == SWITCH_STATUS_TIMEOUT) { + status = SWITCH_STATUS_SUCCESS; + } + } + + return status; +} + +static switch_status_t create_file(switch_core_session_t *session, conference_obj_t *conference, char *macro_name, char *file_path, switch_size_t *message_len, switch_bool_t limit) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_file_handle_t fh = { 0 }; + switch_input_args_t args = { 0 }; + char term; + char input[10] = "", key_buf[80] = ""; + //cc_t cc = { 0 }; + switch_codec_t *read_codec; + char *tone_spec; + + read_codec = switch_core_session_get_read_codec(session); + + while (switch_channel_ready(channel)) { + + switch_snprintf(key_buf, sizeof(key_buf), "1:2:3"); + +record_file: + *message_len = 0; + // args.input_callback = cancel_on_dtmf; + tone_spec = switch_core_strdup(conference->pool, "%(1000, 0, 640)"); + TRY_CODE(switch_ivr_phrase_macro(session, macro_name, NULL, NULL, NULL)); + TRY_CODE(switch_ivr_gentones(session, tone_spec, 0, NULL)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "File Path as in create_file is %s\n", file_path); + + memset(&fh, 0, sizeof(fh)); + fh.thresh = 200; + fh.silence_hits = 2; + fh.samplerate = 11025; + switch_ivr_record_file(session, &fh, file_path, &args, 300); + if (limit && (*message_len = fh.sample_count / read_codec->implementation->actual_samples_per_second) < 3) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Message is less than minimum record length: 3, discarding it.\n"); + if (unlink(file_path) != 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "failed to delete file [%s]\n", file_path); + } + if (switch_channel_ready(channel)) { + /* TODO Rel 1.0 : Add Playback of Prompt , then go back at record_file */ + goto record_file; + } else { + status = SWITCH_STATUS_BREAK; + goto end; + } + } else { + status = SWITCH_STATUS_SUCCESS; + } +play_file: + memset(&fh, 0, sizeof(fh)); + // args.input_callback = control_playback; + switch_ivr_play_file(session, &fh, file_path, &args); + + while (switch_channel_ready(channel)) { + /* if (*cc.buf) { + *input = *cc.buf; + *(input + 1) = '\0'; + status = SWITCH_STATUS_SUCCESS; + *cc.buf = '\0'; + } else {*/ + status = vm_macro_get(session, "voicemail_record_file_check", key_buf, input, sizeof(input), 1, "", &term, 10000); + //} + + if (!strcmp(input, "1")) { + goto play_file; + } else if (!strcmp(input, "3")) { + goto record_file; + } else { + TRY_CODE(switch_ivr_phrase_macro(session, "voicemail_ack", "saved", NULL, NULL)); + goto end; + } + } + } + +end: + return status; +} + static switch_status_t conference_add_event_data(conference_obj_t *conference, switch_event_t *event) { switch_status_t status = SWITCH_STATUS_SUCCESS; @@ -4402,6 +4532,27 @@ goto done; } + if (flags_str) { + if (strstr(flags_str, "introuser")) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Conference member introuser flag set.\n"); + switch_set_flag_locked(conference, CFLAG_INTROUSER); + } + } + + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_size_t message_len = 0; + char *file_path; + char *file_ext = "wav"; + /* Check for the flags passed and if it is INTROUSER */ + if (switch_test_flag(conference, CFLAG_INTROUSER)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Conference %s INTROUSER set.\n", conf_name); + file_path = switch_core_session_sprintf(session, "%sconference_member_%s.%s", SWITCH_GLOBAL_dirs.temp_dir, conf_name, file_ext); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "File Path is %s\n", file_path); + TRY_CODE(create_file(session, conference, "voicemail_record_name", file_path, &message_len, SWITCH_FALSE)); + } + +end: + /* dont allow more callers than the max_members allows for -- I explicitly didnt allow outbound calls * someone else can add that (see above) if they feel that outbound calls should be able to violate the * max_members limit