Index: apps/app_meetme.c =================================================================== --- apps/app_meetme.c (revision 99543) +++ apps/app_meetme.c (working copy) @@ -220,6 +220,7 @@ static int fuzzystart; static int earlyalert; static int endalert; +static int extendby; /* Log participant count to the RealTime backend */ static int rt_log_members; @@ -353,6 +354,7 @@ #define MAX_CONFNUM 80 #define MAX_PIN 80 +#define OPTIONS_LEN 32 /*! \brief The MeetMe Conference object */ struct ast_conference { @@ -1459,6 +1461,74 @@ return res; } +static int rt_extend_conf(char *confno) +{ + char currenttime[32]; + char endtime[32]; + struct timeval now, tmp; + struct ast_tm tm; + struct ast_variable *var; + char bookid[8]; + + union { + struct ast_tm atm; + struct tm time; + } t = { { 0, }, }; + + if (!extendby) + return 0; + + now = ast_tvnow(); + + ast_localtime(&now, &tm, NULL); + ast_strftime(currenttime, sizeof(currenttime), DATE_FORMAT, &tm); + + var = ast_load_realtime("meetme", "confno", + confno, "startTime<= ", currenttime, + "endtime>= ", currenttime, NULL); + + /* Identify the specific RealTime conference */ + while (var) { + if (!strcasecmp(var->name, "bookid")) + ast_copy_string(bookid, var->value, sizeof(bookid)); + if (!strcasecmp(var->name, "endtime")) + ast_copy_string(endtime, var->value, sizeof(endtime)); + + var = var->next; + } + ast_variables_destroy(var); + + /* Calculate DST offset error, if any */ + strptime(currenttime, "%Y-%m-%d %H:%M:%S", &t.time); + tmp = ast_mktime(&t.atm, NULL); + + strptime(endtime, "%Y-%m-%d %H:%M:%S", &t.time); + + now = ast_mktime(&t.atm, NULL); + + now.tv_sec += extendby; + + ast_localtime(&now, &tm, NULL); + ast_strftime(currenttime, sizeof(currenttime), DATE_FORMAT, &tm); + strcat(currenttime, "0"); /* Seconds needs to be 00 */ + + var = ast_load_realtime("meetme", "confno", + confno, "startTime<= ", currenttime, + "endtime>= ", currenttime, NULL); + + + /* If there is no conflict with extending the conference, update the DB */ + if (!var){ + ast_debug(3,"Trying to update the endtime of Conference %s to %s\n", confno, currenttime); + ast_update_realtime("meetme", "bookid", bookid, "endtime", currenttime, NULL); + + return 0; + + } + + return -1; +} + static void conf_start_moh(struct ast_channel *chan, const char *musicclass) { char *original_moh; @@ -1962,10 +2032,44 @@ ms = -1; now = ast_tvnow(); - if (rt_schedule) { + if (rt_schedule && conf->endtime) { + char currenttime[32]; + long localendtime; + int extended = 0; + struct ast_tm tm; + struct ast_variable *var; + struct timeval tmp; + if (now.tv_sec % 60 == 0) { if (!checked) { - if (now.tv_sec > conf->endtime) { + ast_localtime(&now, &tm, NULL); + ast_strftime(currenttime, sizeof(currenttime), DATE_FORMAT, &tm); + var = ast_load_realtime("meetme", "confno", + conf->confno, "startTime<= ", currenttime, + "endtime>= ", currenttime, NULL); + + while (var) { + if (!strcasecmp(var->name, "endtime")) { + union { + struct ast_tm atm; + struct tm tm; + } t = { { 0, }, }; + strptime(var->value, "%Y-%m-%d %H:%M:%S", &t.tm); + tmp = ast_mktime(&t.atm, NULL); + localendtime = tmp.tv_sec; + } + var = var->next; + } + ast_variables_destroy(var); + + /* A conference can be extended from the + Admin/User menu or by an external source */ + if (localendtime > conf->endtime){ + conf->endtime = localendtime; + extended = 1; + } + + if (conf->endtime && (now.tv_sec > conf->endtime)) { ast_verbose("Quitting time...\n"); goto outrun; } @@ -1980,6 +2084,10 @@ announcement_played = 1; } } + + if (extended) + announcement_played = 0; + checked = 1; } @@ -2411,6 +2519,20 @@ case '4': tweak_listen_volume(user, VOL_DOWN); break; + case '5': + /* Extend RT conference */ + if (rt_schedule) { + if(!rt_extend_conf(conf->confno)){ + if(!ast_streamfile(chan, "conf-extended", chan->language)) + ast_waitstream(chan, ""); + } else { + if(!ast_streamfile(chan, "conf-notextended", chan->language)) + ast_waitstream(chan, ""); + } + ast_stopstream(chan); + } + menu_active = 0; + break; case '6': tweak_listen_volume(user, VOL_UP); break; @@ -2471,6 +2593,12 @@ case '4': tweak_listen_volume(user, VOL_DOWN); break; + case '5': + /* Extend RT conference */ + if (rt_schedule) + rt_extend_conf(conf->confno); + menu_active = 0; + break; case '6': tweak_listen_volume(user, VOL_UP); break; @@ -2669,7 +2797,7 @@ static struct ast_conference *find_conf_realtime(struct ast_channel *chan, char *confno, int make, int dynamic, char *dynamic_pin, size_t pin_buf_len, int refcount, struct ast_flags *confflags, - char *optargs[], int *too_early) + char *useropts, char *adminopts, int *too_early) { struct ast_variable *var; struct ast_conference *cnf; @@ -2693,8 +2821,6 @@ struct timeval now; char currenttime[19] = ""; char eatime[19] = ""; - char useropts[32] = ""; - char adminopts[32] = ""; struct ast_tm tm, etm; struct timeval starttime = { .tv_sec = 0 }, endtime = { .tv_sec = 0 }; @@ -2732,11 +2858,11 @@ } else if (!strcasecmp(var->name, "adminpin")) { pinadmin = ast_strdupa(var->value); } else if (!strcasecmp(var->name, "opts")) { - ast_copy_string(useropts, var->value, sizeof(useropts)); + ast_copy_string(useropts, var->value, sizeof(char[OPTIONS_LEN])); } else if (!strcasecmp(var->name, "maxusers")) { maxusers = atoi(var->value); } else if (!strcasecmp(var->name, "adminopts")) { - ast_copy_string(adminopts, var->value, sizeof(adminopts)); + ast_copy_string(adminopts, var->value, sizeof(char[OPTIONS_LEN])); } else if (!strcasecmp(var->name, "endtime")) { union { struct ast_tm atm; @@ -3090,13 +3216,16 @@ } } if (!ast_strlen_zero(confno)) { + char useropts[OPTIONS_LEN]; + char adminopts[OPTIONS_LEN]; /* Check the validity of the conference */ cnf = find_conf(chan, confno, 1, dynamic, the_pin, sizeof(the_pin), 1, &confflags); if (!cnf) { int too_early = 0; + cnf = find_conf_realtime(chan, confno, 1, dynamic, - the_pin, sizeof(the_pin), 1, &confflags, optargs, &too_early); + the_pin, sizeof(the_pin), 1, &confflags, useropts, adminopts, &too_early); if (rt_schedule && too_early) allowretry = 0; } @@ -3132,8 +3261,15 @@ !strcasecmp(pin, cnf->pinadmin))) { /* Pin correct */ allowretry = 0; - if (!ast_strlen_zero(cnf->pinadmin) && !strcasecmp(pin, cnf->pinadmin)) + if (!ast_strlen_zero(cnf->pinadmin) && !strcasecmp(pin, cnf->pinadmin)) { + if(!ast_strlen_zero(adminopts)) + ast_app_parse_options(meetme_opts, &confflags, optargs, adminopts); ast_set_flag(&confflags, CONFFLAG_ADMIN); + } else { + if(!ast_strlen_zero(useropts)) + ast_app_parse_options(meetme_opts, &confflags, optargs, useropts); + } + /* Run the conference */ res = conf_run(chan, cnf, confflags.flags, optargs); break; @@ -3662,6 +3798,7 @@ fuzzystart = 0; earlyalert = 0; endalert = 0; + extendby = 0; /* Logging of participants defaults to ON for compatibility reasons */ rt_log_members = 1; @@ -3701,6 +3838,12 @@ endalert = 0; } } + if ((val = ast_variable_retrieve(cfg, "general", "extendby"))) { + if ((sscanf(val, "%d", &extendby) != 1)) { + ast_log(LOG_WARNING, "extendby must be a number, not '%s'\n", val); + extendby = 0; + } + } ast_config_destroy(cfg); }