Index: apps/app_meetme.c =================================================================== RCS file: /usr/cvsroot/asterisk/apps/app_meetme.c,v retrieving revision 1.72 diff -u -r1.72 app_meetme.c --- apps/app_meetme.c 22 Jan 2005 04:51:30 -0000 1.72 +++ apps/app_meetme.c 23 Jan 2005 17:00:41 -0000 @@ -42,13 +42,16 @@ static char *tdesc = "MeetMe conference bridge"; +struct ast_config *meetmeadv_cfg; static char *app = "MeetMe"; static char *app2 = "MeetMeCount"; static char *app3 = "MeetMeAdmin"; +static char *app4 = "MeetMeAdv"; static char *synopsis = "MeetMe conference bridge"; static char *synopsis2 = "MeetMe participant count"; static char *synopsis3 = "MeetMe conference Administration"; +static char *synopsis4 = "MeetMe advance options"; static char *descrip = " MeetMe([confno][,[options][,pin]]): Enters the user into a specified MeetMe conference.\n" @@ -103,6 +106,9 @@ " 'n' -- Unmute entire conference (except admin)\n" ""; +static char *descrip4 = +" MeetMeAdv(confno)\n"; + STANDARD_LOCAL_USER; LOCAL_USER_DECL; @@ -132,6 +138,10 @@ int user_no; /* User Number */ struct ast_conf_user *prevuser; /* Pointer to the previous user */ struct ast_conf_user *nextuser; /* Pointer to the next user */ + int userid; + char *nick; + char *name; + char *pin; int userflags; /* Flags as set in the conference */ int adminflags; /* Flags set by the Admin */ struct ast_channel *chan; /* Connected channel */ @@ -140,6 +150,26 @@ time_t jointime; /* Time the user joined the conference */ }; +struct ast_conference_adv { + int id; + int public; + int usepin; + int askname; + int recording; + int savename; + char *recfilename; + char *recformat; + int confflags; +}; + +struct ast_conference_user_adv { + int userid; + char *nick; + char *name; + char *pin; + int userflags; +}; + #define ADMINFLAG_MUTED (1 << 1) /* User is muted */ #define ADMINFLAG_KICKME (1 << 2) /* User is kicked */ @@ -147,8 +177,14 @@ AST_MUTEX_DEFINE_STATIC(conflock); static int admin_exec(struct ast_channel *chan, void *data); - +static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int confflags); static void *recordthread(void *args); +static int meetmeadv_exec(struct ast_channel *chan, void *data); +static struct ast_conference *masterbuild_conf(char *confno); +struct ast_conference_user_adv *find_user_adv(struct ast_conference_adv *conf, char *str, int type); +int updateyesnoflag(int curflag,int flag,char *value); +int meetme_reload(void); +struct ast_conference_adv *find_conf_adv(int confid); #include "enter.h" #include "leave.h" @@ -222,8 +258,159 @@ careful_write(conf->fd, data, len); ast_mutex_unlock(&conflock); } +int meetme_reload(void) { + if (!meetmeadv_cfg) + meetmeadv_cfg = ast_load("meetme.conf"); + return 0; +} +int updateyesnoflag(int curflag,int flag,char *value) { + if (!strcasecmp(value, "yes")) + curflag |= flag; + else + curflag &= ~flag; + + return curflag; +} +struct ast_conference_user_adv *find_user_adv(struct ast_conference_adv *conf, char *str, int type) { + char context[AST_MAX_EXTENSION]; + struct ast_variable *v; + static struct ast_conference_user_adv user; + + snprintf(context,sizeof(context),"conf-%d",conf->id); + v = ast_variable_browse(meetmeadv_cfg, context); + while(v) { + if (!strcasecmp(v->name, "userid")) { + user.userid = atoi(ast_strdupa(v->value)); + if (type == 1 && !strcasecmp(v->value,str)) + return &user; + } + if (!strcasecmp(v->name, "pin")) { + user.pin = ast_strdupa(v->value); + if (type == 2 && !strcasecmp(v->value,str)) + return &user; + + } + if (!strcasecmp(v->name, "admin")) + user.userflags = updateyesnoflag(user.userflags,CONFFLAG_ADMIN,v->value); + if (!strcasecmp(v->name, "poundexit")) + user.userflags = updateyesnoflag(user.userflags,CONFFLAG_POUNDEXIT,v->value); + if (!strcasecmp(v->name, "onlymonitor")) + user.userflags = updateyesnoflag(user.userflags,CONFFLAG_MONITOR,v->value); + if (!strcasecmp(v->name, "onlytalker")) + user.userflags = updateyesnoflag(user.userflags,CONFFLAG_TALKER,v->value); + if (!strcasecmp(v->name, "quiet")) + user.userflags = updateyesnoflag(user.userflags,CONFFLAG_QUIET,v->value); + if (!strcasecmp(v->name, "moh")) + user.userflags = updateyesnoflag(user.userflags,CONFFLAG_MOH,v->value); + if (!strcasecmp(v->name, "waitmarked")) + user.userflags = updateyesnoflag(user.userflags,CONFFLAG_WAITMARKED,v->value); + if (!strcasecmp(v->name, "exitmarked")) + user.userflags = updateyesnoflag(user.userflags,CONFFLAG_MARKEDEXIT,v->value); + if (!strcasecmp(v->name, "intro")) + user.userflags = updateyesnoflag(user.userflags,CONFFLAG_INTROUSER,v->value); + if (!strcasecmp(v->name, "recordconf")) + user.userflags = updateyesnoflag(user.userflags,CONFFLAG_RECORDCONF,v->value); + if (!strcasecmp(v->name, "menu")) + user.userflags = updateyesnoflag(user.userflags,CONFFLAG_STARMENU,v->value); + if (!strcasecmp(v->name, "marked")) + user.userflags = updateyesnoflag(user.userflags,CONFFLAG_MARKEDUSER,v->value); -static struct ast_conference *build_conf(char *confno, char *pin, int make, int dynamic) + + v = v->next; + } + return NULL; +} + + +struct ast_conference_adv *find_conf_adv(int confid) { + struct ast_variable *v; + char context[AST_MAX_EXTENSION]; + static struct ast_conference_adv conf; + conf.id = confid; + + snprintf(context,sizeof(context),"conf-%d",confid); + v = ast_variable_browse(meetmeadv_cfg, context); + while(v) { + if (!strcasecmp(v->name, "public")) { + if (!strcasecmp(v->value, "yes")) + conf.public = 1; + else + conf.public = 0; + } + if (!strcasecmp(v->name, "public")) { + if (!strcasecmp(v->value, "yes")) + conf.usepin = 1; + else + conf.usepin = 0; + + } + + v = v->next; + } + return &conf; +} +static int meetmeadv_exec(struct ast_channel *chan, void *data) { + struct ast_conference_adv *conf; + struct ast_conference_user_adv *user; + struct ast_conference *cnf; + int allowretry = 1; + char confno[AST_MAX_EXTENSION] = ""; + int retrycnt = 0; + int res; + + meetme_reload(); + + conf = find_conf_adv(atoi(data)); + + if (conf->usepin == 1) { + // Ask for the PIN + while (allowretry && (ast_strlen_zero(confno)) && (++retrycnt < 4)) { + /* Prompt user for conference number */ + res = ast_app_getdata(chan, "conf-getconfno", confno, sizeof(confno) - 1, 0); + if (res < 0) { + /* Don't try to validate when we catch an error */ + confno[0] = '\0'; + allowretry = 0; + break; + } + if (!ast_strlen_zero(confno)) { + user = find_user_adv(conf,confno,2); + if (user) { + ast_log(LOG_WARNING, "Found PIN %s\n",user->pin); + allowretry = 0; + cnf = masterbuild_conf(data); + if (cnf) + conf_run(chan, cnf, user->userflags); + } else { + ast_log(LOG_WARNING, "Not found yet\n"); + confno[0] = '\0'; + } + } + } + } + return 0; +} +static struct ast_conference *build_conf(char *confno, char *pin, int make, int dynamic) +{ + struct ast_conference *tmp; + tmp = confs; + ast_mutex_lock(&conflock); + while(tmp) { + if (!strcmp(confno, tmp->confno)) + break; + tmp = tmp->next; + } + if (!tmp && (make || dynamic)) { + tmp = masterbuild_conf(confno); + tmp->isdynamic = dynamic; + strncpy(tmp->confno, confno, sizeof(tmp->confno) - 1); + strncpy(tmp->pin, pin, sizeof(tmp->pin) - 1); + } + ast_mutex_unlock(&conflock); + return tmp; + +} +static struct ast_conference *masterbuild_conf(char *confno) { struct ast_conference *cnf; struct zt_confinfo ztc; @@ -234,13 +421,12 @@ break; cnf = cnf->next; } - if (!cnf && (make || dynamic)) { + if (!cnf) { cnf = malloc(sizeof(struct ast_conference)); if (cnf) { /* Make a new one */ memset(cnf, 0, sizeof(struct ast_conference)); strncpy(cnf->confno, confno, sizeof(cnf->confno) - 1); - strncpy(cnf->pin, pin, sizeof(cnf->pin) - 1); cnf->markedusers = 0; cnf->chan = ast_request("zap", AST_FORMAT_ULAW, "pseudo", NULL); if (cnf->chan) { @@ -273,7 +459,6 @@ /* Fill the conference struct */ cnf->start = time(NULL); cnf->zapconf = ztc.confno; - cnf->isdynamic = dynamic; cnf->firstuser = NULL; cnf->lastuser = NULL; cnf->locked = 0; @@ -1702,6 +1887,7 @@ STANDARD_HANGUP_LOCALUSERS; ast_cli_unregister(&cli_show_confs); ast_cli_unregister(&cli_conf); + ast_unregister_application(app4); ast_unregister_application(app3); ast_unregister_application(app2); return ast_unregister_application(app); @@ -1711,6 +1897,7 @@ { ast_cli_register(&cli_show_confs); ast_cli_register(&cli_conf); + ast_register_application(app4, meetmeadv_exec, synopsis4, descrip4); ast_register_application(app3, admin_exec, synopsis3, descrip3); ast_register_application(app2, count_exec, synopsis2, descrip2); return ast_register_application(app, conf_exec, synopsis, descrip);