Index: channels/chan_skinny.c =================================================================== --- apps/app_meetme.c (revision 94477) +++ 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; @@ -380,7 +381,7 @@ char pin[MAX_PIN]; /*!< If protected by a PIN */ char pinadmin[MAX_PIN]; /*!< If protected by a admin PIN */ char uniqueid[32]; - long endtime; /*!< When to end the conf if scheduled */ + long endtime; /*!< When to end the conf if scheduled */ struct ast_frame *transframe[32]; struct ast_frame *origframe; struct ast_trans_pvt *transpath[32]; @@ -1459,6 +1460,76 @@ 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; + int dsterror = 0; + 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); + dsterror = now.tv_sec - tmp.tv_sec; + + 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 +2033,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 +2085,10 @@ announcement_played = 1; } } + + if (extended) + announcement_played = 0; + checked = 1; } @@ -2411,6 +2520,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 +2594,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 +2798,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 +2822,6 @@ struct timeval now; char currenttime[19] = ""; char eatime[19] = ""; - char useropts[32] = ""; - char adminopts[32] = ""; struct ast_tm tm, etm; struct timeval starttime, endtime; @@ -2732,11 +2859,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[32])); } 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[32])); } else if (!strcasecmp(var->name, "endtime")) { union { struct ast_tm atm; @@ -3090,13 +3217,16 @@ } } if (!ast_strlen_zero(confno)) { + char useropts[32]; + char adminopts[32]; /* 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 +3262,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 +3799,7 @@ fuzzystart = 0; earlyalert = 0; endalert = 0; + extendby = 0; /* Logging of participants defaults to ON for compatibility reasons */ rt_log_members = 1; @@ -3701,6 +3839,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); } Index: configs/meetme.conf.sample =================================================================== --- configs/meetme.conf.sample (revision 94477) +++ configs/meetme.conf.sample (working copy) @@ -32,6 +32,10 @@ ; the participants be warned? ;endalert=120 ; +; Number of seconds to extend a conference by if the moderator +; uses the *5 menu option +;extendby=600 +; [rooms] ; ; Usage is conf => confno[,pin][,adminpin]