diff --git a/app.c b/app.c index 8b7ecb05cc964cf88658a061f2af042f61c1e592..592141c67272e205af0cac132603ff09087d046a 100755 --- a/app.c +++ b/app.c @@ -1060,3 +1060,101 @@ int ast_seperate_app_args(char *buf, char delim, char **array, int arraylen) } return x; } + +int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration) +{ + int silencethreshold = 128; + int maxsilence=0; + int res = 0; + int cmd = 0; + int max_attempts = 3; + int attempts = 0; + int recorded = 0; + int message_exists = 0; + /* Note that urgent and private are for flagging messages as such in the future */ + + /* barf if no pointer passed to store duration in */ + if (duration == NULL) { + ast_log(LOG_WARNING, "Error ast_record_review called without duration pointer\n"); + return -1; + } + + cmd = '3'; /* Want to start by recording */ + + while ((cmd >= 0) && (cmd != 't')) { + switch (cmd) { + case '1': + if (!message_exists) { + /* In this case, 1 is to record a message */ + cmd = '3'; + break; + } else { + ast_streamfile(chan, "vm-msgsaved", chan->language); + ast_waitstream(chan, ""); + cmd = 't'; + return res; + } + case '2': + /* Review */ + ast_verbose(VERBOSE_PREFIX_3 "Reviewing the recording\n"); + ast_streamfile(chan, recordfile, chan->language); + cmd = ast_waitstream(chan, AST_DIGIT_ANY); + break; + case '3': + message_exists = 0; + /* Record */ + if (recorded == 1) + ast_verbose(VERBOSE_PREFIX_3 "Re-recording\n"); + else + ast_verbose(VERBOSE_PREFIX_3 "Recording\n"); + recorded = 1; + cmd = ast_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence); + if (cmd == -1) { + /* User has hung up, no options to give */ + return cmd; + } + if (cmd == '0') { + break; + } else if (cmd == '*') { + break; + } + else { + /* If all is well, a message exists */ + message_exists = 1; + cmd = 0; + } + break; + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '*': + case '#': + cmd = ast_play_and_wait(chan, "vm-sorry"); + break; + default: + if (message_exists) { + cmd = ast_play_and_wait(chan, "vm-review"); + } + else { + cmd = ast_play_and_wait(chan, "vm-torerecord"); + if (!cmd) + cmd = ast_waitfordigit(chan, 600); + } + + if (!cmd) + cmd = ast_waitfordigit(chan, 6000); + if (!cmd) { + attempts++; + } + if (attempts > max_attempts) { + cmd = 't'; + } + } + } + if (cmd == 't') + cmd = 0; + return cmd; +} diff --git a/apps/app_meetme.c b/apps/app_meetme.c index df93d39b8b1d422fb31dd4816e21f8d9aafd9ef5..b4eec3038155700765ed462bd66cd273841cd32d 100755 --- a/apps/app_meetme.c +++ b/apps/app_meetme.c @@ -31,6 +31,8 @@ #include <errno.h> #include <stdlib.h> #include <sys/ioctl.h> +#include "../asterisk.h" +#include "../astconf.h" #ifdef __linux__ #include <linux/zaptel.h> @@ -58,6 +60,7 @@ static char *descrip = "The option string may contain zero or more of the following characters:\n" " 'm' -- set monitor only mode (Listen only, no talking)\n" " 't' -- set talk only mode. (Talk only, no listening)\n" +" 'i' -- announce user join/leave\n" " 'p' -- allow user to exit the conference by pressing '#'\n" " 'X' -- allow user to exit the conference by entering a valid single\n" " digit extension ${MEETME_EXIT_CONTEXT} or the current context\n" @@ -124,6 +127,7 @@ struct ast_conf_user { int adminflags; /* Flags set by the Admin */ struct ast_channel *chan; /* Connected channel */ char usrvalue[50]; /* Custom User Value */ + char namerecloc[AST_MAX_EXTENSION]; /* Name Recorded file Location */ time_t jointime; /* Time the user joined the conference */ }; @@ -156,7 +160,7 @@ static int admin_exec(struct ast_channel *chan, void *data); #define CONFFLAG_WAITMARKED (1 << 11) /* If set, the MeetMe will wait until a marked user enters */ #define CONFFLAG_EXIT_CONTEXT (1 << 12) /* If set, the MeetMe will exit to the specified context */ #define CONFFLAG_MARKEDUSER (1 << 13) /* If set, the user will be marked */ - +#define CONFFLAG_INTROUSER (1 << 14) /* If set, user will be ask record name on entry of conference */ static int careful_write(int fd, unsigned char *data, int len) { @@ -515,6 +519,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c int x; int menu_active = 0; int using_pseudo = 0; + int duration=20; struct ast_app *app; char *agifile; @@ -544,6 +549,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c goto outrun; } conf->users++; + if (confflags & CONFFLAG_MARKEDUSER) conf->markedusers++; @@ -582,6 +588,11 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int c else strncpy(exitcontext, chan->context, sizeof(exitcontext) - 1); } + snprintf(user->namerecloc,sizeof(user->namerecloc),"%s/meetme-username-%s-%d",AST_SPOOL_DIR,conf->confno,user->user_no); + + if (!(confflags & CONFFLAG_QUIET) && (confflags & CONFFLAG_INTROUSER)) + ast_record_review(chan,"vm-rec-name",user->namerecloc, 10,"sln", &duration); + while((confflags & CONFFLAG_WAITMARKED) && (conf->markedusers == 0)) { confflags &= ~CONFFLAG_QUIET; confflags |= origquiet; @@ -690,6 +701,16 @@ zapretry: /* Add us to the conference */ ztc.chan = 0; ztc.confno = conf->zapconf; + ast_mutex_lock(&conflock); + if (!(confflags & CONFFLAG_QUIET) && (confflags & CONFFLAG_INTROUSER) && conf->users > 1) { + if (ast_fileexists(user->namerecloc, NULL, NULL)) { + if (!ast_streamfile(conf->chan, user->namerecloc, chan->language)) + ast_waitstream(conf->chan, ""); + if (!ast_streamfile(conf->chan, "conf-hasjoin", chan->language)) + ast_waitstream(conf->chan, ""); + } + } + if (confflags & CONFFLAG_MONITOR) ztc.confmode = ZT_CONF_CONFMON | ZT_CONF_LISTENER; else if (confflags & CONFFLAG_TALKER) @@ -700,6 +721,7 @@ zapretry: if (ioctl(fd, ZT_SETCONF, &ztc)) { ast_log(LOG_WARNING, "Error setting conference\n"); close(fd); + ast_mutex_unlock(&conflock); goto outrun; } ast_log(LOG_DEBUG, "Placed channel %s in ZAP conf %d\n", chan->name, conf->zapconf); @@ -716,7 +738,7 @@ zapretry: if (!(confflags & CONFFLAG_QUIET)) conf_play(conf, ENTER); } - + ast_mutex_unlock(&conflock); if (confflags & CONFFLAG_AGI) { /* Get name of AGI file to run from $(MEETME_AGI_BACKGROUND) @@ -989,9 +1011,24 @@ zapretry: ast_log(LOG_WARNING, "Error setting conference\n"); } } + + ast_mutex_lock(&conflock); if (!(confflags & CONFFLAG_QUIET) && !(confflags & CONFFLAG_MONITOR) && !(confflags & CONFFLAG_ADMIN)) conf_play(conf, LEAVE); + if (!(confflags & CONFFLAG_QUIET) && (confflags & CONFFLAG_INTROUSER) && conf->users > 1) { + if (ast_fileexists(user->namerecloc, NULL, NULL)) { + if (!ast_streamfile(conf->chan, user->namerecloc, chan->language)) + ast_waitstream(conf->chan, ""); + if (!ast_streamfile(conf->chan, "conf-hasleft", chan->language)) + ast_waitstream(conf->chan, ""); + ast_filedelete(user->namerecloc, NULL); + + } + } + ast_mutex_unlock(&conflock); + + outrun: ast_mutex_lock(&conflock); if (user->user_no) { /* Only cleanup users who really joined! */ @@ -1214,6 +1251,8 @@ static int conf_exec(struct ast_channel *chan, void *data) if (inflags) { if (strchr(inflags, 'a')) confflags |= CONFFLAG_ADMIN; + if (strchr(inflags, 'i')) + confflags |= CONFFLAG_INTROUSER; if (strchr(inflags, 'm')) confflags |= CONFFLAG_MONITOR; if (strchr(inflags, 'p')) @@ -1573,6 +1612,7 @@ int load_module(void) return ast_register_application(app, conf_exec, synopsis, descrip); } + char *description(void) { return tdesc; @@ -1589,3 +1629,4 @@ char *key() { return ASTERISK_GPL_KEY; } + diff --git a/include/asterisk/app.h b/include/asterisk/app.h index 207ba83da59885cdf16296ec1871093cc24c56bd..f8f9d37dd795e7a6f041d7df9153976d6a167a49 100755 --- a/include/asterisk/app.h +++ b/include/asterisk/app.h @@ -93,6 +93,9 @@ int ast_seperate_app_args(char *buf, char delim, char **array, int arraylen); //! Present a dialtone and collect a certain length extension. Returns 1 on valid extension entered, -1 on hangup, or 0 on invalid extension. int ast_app_dtget(struct ast_channel *chan, const char *context, char *collect, size_t size, int maxlen, int timeout); +//! Allow to record message and have a review option +int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration); + #if defined(__cplusplus) || defined(c_plusplus) } #endif diff --git a/sounds.txt b/sounds.txt index 41b54bd2f4967dfad10fd1efa525f1ec5f10303c..7f73742141b6d2abf8bbbf2e52f51f6153479434 100755 --- a/sounds.txt +++ b/sounds.txt @@ -26,6 +26,10 @@ %beeperr.gsm%(this is an error beep tone) +%conf-hasleft.gsm%has left the conference. + +%conf-hasjoin.gsm%has joined the conference. + %conf-getconfno.gsm%Please enter your conference number followed by the pound key. %conf-getchannel.gsm%Please enter your channel number followed by the pound key.