Beispiel #1
0
static int directory_exec(struct cw_channel *chan, int argc, char **argv)
{
	struct localuser *u;
	struct cw_config *cfg;
	char *context, *dialcontext, *dirintro;
	int res = 0;
	int last = 1;

	if (argc < 1 || argc > 3) {
		cw_log(LOG_ERROR, "Syntax: %s\n", directory_syntax);
		return -1;
	}

	LOCAL_USER_ADD(u);

	context = argv[0];
	dialcontext = (argc > 1 && argv[1][0] ? argv[1] : context);
	if (argc > 2 && strchr(argv[2], 'f'))
		last = 0;

	cfg = realtime_directory(context);
	if (!cfg) {
		LOCAL_USER_REMOVE(u);
		return -1;
	}

	dirintro = cw_variable_retrieve(cfg, context, "directoryintro");
	if (cw_strlen_zero(dirintro))
		dirintro = cw_variable_retrieve(cfg, "general", "directoryintro");
	if (cw_strlen_zero(dirintro)) {
		if (last)
			dirintro = "dir-intro";	
		else
			dirintro = "dir-intro-fn";
	}
	
	for (;;) {
		if (!res)
			res = cw_streamfile(chan, dirintro, chan->language);
		if (!res)
			res = cw_waitstream(chan, CW_DIGIT_ANY);
		cw_stopstream(chan);
		if (!res)
			res = cw_waitfordigit(chan, 5000);
		if (res >0) {
			res = do_directory(chan, cfg, context, dialcontext, res, last);
			if (res > 0){
				res = cw_waitstream(chan, CW_DIGIT_ANY);
				cw_stopstream(chan);
				if (res >= 0) {
					continue;
				}
			}
		}
		break;
	}
	cw_config_destroy(cfg);
	LOCAL_USER_REMOVE(u);
	return res;
}
Beispiel #2
0
static int read_newoption(struct cw_channel *chan, struct cw_ivr_menu *menu, char *exten, int maxexten)
{
	int res=0;
	int ms;
	while(option_matchmore(menu, exten)) {
		ms = chan->pbx ? chan->pbx->dtimeout : 5000;
		if (strlen(exten) >= maxexten - 1) 
			break;
		res = cw_waitfordigit(chan, ms);
		if (res < 1)
			break;
		exten[strlen(exten) + 1] = '\0';
		exten[strlen(exten)] = res;
	}
	return res > 0 ? 0 : res;
}
Beispiel #3
0
/* 
This function presents a dialtone and reads an extension into 'collect' 
which must be a pointer to a **pre-initilized** array of char having a 
size of 'size' suitable for writing to.  It will collect no more than the smaller 
of 'maxlen' or 'size' minus the original strlen() of collect digits.
*/
int cw_app_dtget(struct cw_channel *chan, const char *context, char *collect, size_t size, int maxlen, int timeout) 
{
	struct tone_zone_sound *ts;
	int res=0, x=0;

	if(maxlen > size)
		maxlen = size;
	
	if(!timeout && chan->pbx)
		timeout = chan->pbx->dtimeout;
	else if(!timeout)
		timeout = 5;
	
	ts = cw_get_indication_tone(chan->zone,"dial");
	if (ts && ts->data[0])
		res = cw_playtones_start(chan, 0, ts->data, 0);
	else 
		cw_log(LOG_NOTICE,"Huh....? no dial for indications?\n");
	
	for (x = strlen(collect); strlen(collect) < maxlen; ) {
		res = cw_waitfordigit(chan, timeout);
		if (!cw_ignore_pattern(context, collect))
			cw_playtones_stop(chan);
		if (res < 1)
			break;
		collect[x++] = res;
		if (!cw_matchmore_extension(chan, context, collect, 1, chan->cid.cid_num)) {
			if (collect[x-1] == '#') {
				/* Not a valid extension, ending in #, assume the # was to finish dialing */
				collect[x-1] = '\0';
			}
			break;
		}
	}
	if (res >= 0) {
		if (cw_exists_extension(chan, context, collect, 1, chan->cid.cid_num))
			res = 1;
		else
			res = 0;
	}
	return res;
}
Beispiel #4
0
static int _while_exec(struct cw_channel *chan, int argc, char **argv, int end)
{
	int res=0;
	struct localuser *u;
	char *while_pri = NULL;
	char *goto_str = NULL, *my_name = NULL;
	char *label = NULL;
	char varname[VAR_SIZE], end_varname[VAR_SIZE];
	const char *prefix = "WHILE";
	size_t size=0;
	int used_index_i = -1, x=0;
	char used_index[VAR_SIZE] = "0", new_index[VAR_SIZE] = "0";

	if (!end && argc != 1) {
		cw_log(LOG_ERROR, "Syntax: %s\n", while_syntax);
		return -1;
	}

	if (!chan) {
		/* huh ? */
		return -1;
	}

	LOCAL_USER_ADD(u);

	/* dont want run away loops if the chan isn't even up
	   this is up for debate since it slows things down a tad ......
	*/
	if (cw_waitfordigit(chan,1) < 0)
		ALL_DONE(u,-1);


	for (x=0;;x++) {
		if (get_index(chan, prefix, x)) {
			used_index_i = x;
		} else 
			break;
	}
	
	snprintf(used_index, VAR_SIZE, "%d", used_index_i);
	snprintf(new_index, VAR_SIZE, "%d", used_index_i + 1);
	
	size = strlen(chan->context) + strlen(chan->exten) + 32;
	my_name = alloca(size);
	snprintf(my_name, size, "%s_%s_%d", chan->context, chan->exten, chan->priority);
	
	if (cw_strlen_zero(label)) {
		if (end) 
			label = used_index;
		else if (!(label = pbx_builtin_getvar_helper(chan, my_name))) {
			label = new_index;
			pbx_builtin_setvar_helper(chan, my_name, label);
		}
		
	}
	
	snprintf(varname, VAR_SIZE, "%s_%s", prefix, label);
	while_pri = pbx_builtin_getvar_helper(chan, varname);
	
	if ((while_pri = pbx_builtin_getvar_helper(chan, varname)) && !end) {
		snprintf(end_varname, VAR_SIZE, "END_%s", varname);
	}
	

	if (!end && !cw_true(argv[0])) {
		/* Condition Met (clean up helper vars) */
		pbx_builtin_setvar_helper(chan, varname, NULL);
		pbx_builtin_setvar_helper(chan, my_name, NULL);
		snprintf(end_varname, VAR_SIZE, "END_%s", varname);
		if ((goto_str=pbx_builtin_getvar_helper(chan, end_varname))) {
			pbx_builtin_setvar_helper(chan, end_varname, NULL);
			cw_parseable_goto(chan, goto_str);
		} else {
			int pri = find_matching_endwhile(chan);
			if (pri > 0) {
				if (option_verbose > 2)
					cw_verbose(VERBOSE_PREFIX_3 "Jumping to priority %d\n", pri);
				chan->priority = pri;
			} else {
				cw_log(LOG_WARNING, "Couldn't find matching EndWhile? (While at %s@%s priority %d)\n", chan->context, chan->exten, chan->priority);
			}
		}
		ALL_DONE(u,res);
	}

	if (!end && !while_pri) {
		size = strlen(chan->context) + strlen(chan->exten) + 32;
		goto_str = alloca(size);
		snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority);
		pbx_builtin_setvar_helper(chan, varname, goto_str);
	} 

	else if (end && while_pri) {
		/* END of loop */
		snprintf(end_varname, VAR_SIZE, "END_%s", varname);
		if (! pbx_builtin_getvar_helper(chan, end_varname)) {
			size = strlen(chan->context) + strlen(chan->exten) + 32;
			goto_str = alloca(size);
			snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority+1);
			pbx_builtin_setvar_helper(chan, end_varname, goto_str);
		}
		cw_parseable_goto(chan, while_pri);
	}
	



	ALL_DONE(u, res);
}
Beispiel #5
0
/* play name of mailbox owner.
 * returns:  -1 for bad or missing extension
 *           '1' for selected entry from directory
 *           '*' for skipped entry from directory
 */
static int play_mailbox_owner(struct cw_channel *chan, char *context, char *dialcontext, char *ext, char *name) {
	int res = 0;
	int loop = 3;
	char fn[256];
	char fn2[256];

	/* Check for the VoiceMail2 greeting first */
	snprintf(fn, sizeof(fn), "%s/voicemail/%s/%s/greet",
		(char *)cw_config_CW_SPOOL_DIR, context, ext);

	/* Otherwise, check for an old-style Voicemail greeting */
	snprintf(fn2, sizeof(fn2), "%s/vm/%s/greet",
		(char *)cw_config_CW_SPOOL_DIR, ext);

	if (cw_fileexists(fn, NULL, chan->language) > 0) {
		res = cw_streamfile(chan, fn, chan->language);
		if (!res) {
			res = cw_waitstream(chan, CW_DIGIT_ANY);
		}
		cw_stopstream(chan);
	} else if (cw_fileexists(fn2, NULL, chan->language) > 0) {
		res = cw_streamfile(chan, fn2, chan->language);
		if (!res) {
			res = cw_waitstream(chan, CW_DIGIT_ANY);
		}
		cw_stopstream(chan);
	} else {
		res = cw_say_character_str(chan, !cw_strlen_zero(name) ? name : ext,
					CW_DIGIT_ANY, chan->language);
	}

	while (loop) {
		if (!res) {
			res = cw_streamfile(chan, "dir-instr", chan->language);
		}
		if (!res) {
			res = cw_waitstream(chan, CW_DIGIT_ANY);
		}
		if (!res) {
			res = cw_waitfordigit(chan, 3000);
		}
		cw_stopstream(chan);
	
		if (res > -1) {
			switch (res) {
				case '1':
					/* Name selected */
					loop = 0;
					if (cw_goto_if_exists(chan, dialcontext, ext, 1)) {
						cw_log(LOG_WARNING,
							"Can't find extension '%s' in context '%s'.  "
							"Did you pass the wrong context to Directory?\n",
							ext, dialcontext);
						res = -1;
					}
					break;
	
				case '*':   
					/* Skip to next match in list */
					loop = 0;
					break;
	
				default:
					/* Not '1', or '*', so decrement number of tries */
					res = 0;
					loop--;
					break;
			} /* end switch */
		} /* end if */
		else {
			/* User hungup, so jump out now */
			loop = 0;
		}
	} /* end while */

	return(res);
}
Beispiel #6
0
int cw_control_streamfile(struct cw_channel *chan, const char *file,
			   const char *fwd, const char *rev,
			   const char *stop, const char *pause,
			   const char *restart, int skipms) 
{
	long elapsed = 0, last_elapsed = 0;
	char *breaks = NULL;
	char *end = NULL;
	int blen = 2;
	int res;

	if (stop)
		blen += strlen(stop);
	if (pause)
		blen += strlen(pause);
	if (restart)
		blen += strlen(restart);

	if (blen > 2) {
		breaks = alloca(blen + 1);
		breaks[0] = '\0';
		if (stop)
			strcat(breaks, stop);
		if (pause)
			strcat(breaks, pause);
		if (restart)
			strcat(breaks, restart);
	}
	if (chan->_state != CW_STATE_UP)
		res = cw_answer(chan);

	if (chan)
		cw_stopstream(chan);

	if (file) {
		if ((end = strchr(file,':'))) {
			if (!strcasecmp(end, ":end")) {
				*end = '\0';
				end++;
			}
		}
	}

	for (;;) {
		struct timeval started = cw_tvnow();

		if (chan)
			cw_stopstream(chan);
		res = cw_streamfile(chan, file, chan->language);
		if (!res) {
			if (end) {
				cw_seekstream(chan->stream, 0, SEEK_END);
				end=NULL;
			}
			res = 1;
			if (elapsed) {
				cw_stream_fastforward(chan->stream, elapsed);
				last_elapsed = elapsed - 200;
			}
			if (res)
				res = cw_waitstream_fr(chan, breaks, fwd, rev, skipms);
			else
				break;
		}

		if (res < 1)
			break;

		/* We go at next loop if we got the restart char */
		if (restart && strchr(restart, res)) {
			cw_log(LOG_DEBUG, "we'll restart the stream here at next loop\n");
			elapsed=0; /* To make sure the next stream will start at beginning */
			continue;
		}

		if (pause != NULL && strchr(pause, res)) {
			elapsed = cw_tvdiff_ms(cw_tvnow(), started) + last_elapsed;
			for(;;) {
				if (chan)
					cw_stopstream(chan);
				res = cw_waitfordigit(chan, 1000);
				if (res == 0)
					continue;
				else if (res == -1 || strchr(pause, res) || (stop && strchr(stop, res)))
					break;
			}
			if (res == *pause) {
				res = 0;
				continue;
			}
		}
		if (res == -1)
			break;

		/* if we get one of our stop chars, return it to the calling function */
		if (stop && strchr(stop, res)) {
			/* res = 0; */
			break;
		}
	}
	if (chan)
		cw_stopstream(chan);

	return res;
}
Beispiel #7
0
static int ivr_dispatch(struct cw_channel *chan, struct cw_ivr_option *option, char *exten, void *cbdata)
{
	int res;
	int (*ivr_func)(struct cw_channel *, void *);
	char *c;
	char *n;
	
	switch(option->action) {
	case CW_ACTION_UPONE:
		return RES_UPONE;
	case CW_ACTION_EXIT:
		return RES_EXIT | (((unsigned long)(option->adata)) & 0xffff);
	case CW_ACTION_REPEAT:
		return RES_REPEAT | (((unsigned long)(option->adata)) & 0xffff);
	case CW_ACTION_RESTART:
		return RES_RESTART ;
	case CW_ACTION_NOOP:
		return 0;
	case CW_ACTION_BACKGROUND:
		res = cw_streamfile(chan, (char *)option->adata, chan->language);
		if (!res) {
			res = cw_waitstream(chan, CW_DIGIT_ANY);
		} else {
			cw_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata);
			res = 0;
		}
		return res;
	case CW_ACTION_PLAYBACK:
		res = cw_streamfile(chan, (char *)option->adata, chan->language);
		if (!res) {
			res = cw_waitstream(chan, "");
		} else {
			cw_log(LOG_NOTICE, "Unable to find file '%s'!\n", (char *)option->adata);
			res = 0;
		}
		return res;
	case CW_ACTION_MENU:
		res = cw_ivr_menu_run_internal(chan, (struct cw_ivr_menu *)option->adata, cbdata);
		/* Do not pass entry errors back up, treat as though it was an "UPONE" */
		if (res == -2)
			res = 0;
		return res;
	case CW_ACTION_WAITOPTION:
		res = cw_waitfordigit(chan, 1000 * (chan->pbx ? chan->pbx->rtimeout : 10));
		if (!res)
			return 't';
		return res;
	case CW_ACTION_CALLBACK:
		ivr_func = option->adata;
		res = ivr_func(chan, cbdata);
		return res;
	case CW_ACTION_TRANSFER:
		res = cw_parseable_goto(chan, option->adata);
		return 0;
	case CW_ACTION_PLAYLIST:
	case CW_ACTION_BACKLIST:
		res = 0;
		c = cw_strdupa(option->adata);
		while((n = strsep(&c, ";")))
			if ((res = cw_streamfile(chan, n, chan->language)) || (res = cw_waitstream(chan, (option->action == CW_ACTION_BACKLIST) ? CW_DIGIT_ANY : "")))
				break;
		cw_stopstream(chan);
		return res;
	default:
		cw_log(LOG_NOTICE, "Unknown dispatch function %d, ignoring!\n", option->action);
		return 0;
	};
	return -1;
}
Beispiel #8
0
int cw_record_review(struct cw_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path) 
{
	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) {
		cw_log(LOG_WARNING, "Error cw_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 {
				cw_streamfile(chan, "vm-msgsaved", chan->language);
				cw_waitstream(chan, "");
				cmd = 't';
				return res;
			}
		case '2':
			/* Review */
			cw_verbose(VERBOSE_PREFIX_3 "Reviewing the recording\n");
			cw_streamfile(chan, recordfile, chan->language);
			cmd = cw_waitstream(chan, CW_DIGIT_ANY);
			break;
		case '3':
			message_exists = 0;
			/* Record */
			if (recorded == 1)
				cw_verbose(VERBOSE_PREFIX_3 "Re-recording\n");
			else	
				cw_verbose(VERBOSE_PREFIX_3 "Recording\n");
			recorded = 1;
			cmd = cw_play_and_record(chan, playfile, recordfile, maxtime, fmt, duration, silencethreshold, maxsilence, path);
			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 = cw_play_and_wait(chan, "vm-sorry");
			break;
		default:
			if (message_exists) {
				cmd = cw_play_and_wait(chan, "vm-review");
			}
			else {
				cmd = cw_play_and_wait(chan, "vm-torerecord");
				if (!cmd)
					cmd = cw_waitfordigit(chan, 600);
			}
			
			if (!cmd)
				cmd = cw_waitfordigit(chan, 6000);
			if (!cmd) {
				attempts++;
			}
			if (attempts > max_attempts) {
				cmd = 't';
			}
		}
	}
	if (cmd == 't')
		cmd = 0;
	return cmd;
}