Esempio n. 1
0
void cw_sched_dump(const struct sched_context *con)
{
	/*
	 * Dump the contents of the scheduler to
	 * stderr
	 */
	struct sched *q;
	struct timeval tv = cw_tvnow();
#ifdef SCHED_MAX_CACHE
	cw_log(LOG_DEBUG, "CallWeaver Schedule Dump (%d in Q, %d Total, %d Cache)\n", con->schedcnt, con->eventcnt - 1, con->schedccnt);
#else
	cw_log(LOG_DEBUG, "CallWeaver Schedule Dump (%d in Q, %d Total)\n", con->schedcnt, con->eventcnt - 1);
#endif

	cw_log(LOG_DEBUG, "=============================================================\n");
	cw_log(LOG_DEBUG, "|ID    Callback          Data              Time  (sec:ms)   |\n");
	cw_log(LOG_DEBUG, "+-----+-----------------+-----------------+-----------------+\n");
 	for (q = con->schedq; q; q = q->next) {
 		struct timeval delta =  cw_tvsub(q->when, tv);

		cw_log(LOG_DEBUG, "|%.4d | %-15p | %-15p | %.6ld : %.6ld |\n", 
			q->id,
			q->callback,
			q->data,
			delta.tv_sec,
			(long int)delta.tv_usec);
	}
	cw_log(LOG_DEBUG, "=============================================================\n");
	
}
Esempio n. 2
0
static char *acf_strftime(struct cw_channel *chan, int argc, char **argv, char *buf, size_t len) 
{
	char *epoch = NULL;
	char *timezone = NULL;
	char *format = "%c";
	long epochi;
	struct tm time;

	if ( (argc>0) && (!cw_strlen_zero(argv[0])) ) epoch=argv[0];
	if ( (argc>1) && (!cw_strlen_zero(argv[1])) ) timezone=argv[1];
	if ( (argc>2) && (!cw_strlen_zero(argv[2])) ) format=argv[2];

	if (argc < 1 || !argv[0][0] || !sscanf(epoch, "%ld", &epochi)) {
		struct timeval tv = cw_tvnow();
		epochi = tv.tv_sec;
	}
	buf[0] = '\0';
	cw_localtime(&epochi, &time, timezone );

	if (!strftime(buf, len, format, &time)) {
		cw_log(LOG_WARNING, "C function strftime() output nothing?!!\n");
		/* AGX: return empty string buffer in case of error */
		buf[0] = '\0';
		return buf;
	}
	/* AGX: strfttime man page says it should already add 0 at the end of the string,
	 * 	is this something OS specific ? */
	buf[len - 1] = '\0';
	return buf;
}
Esempio n. 3
0
int cw_sched_add_variable(struct sched_context *con, int when, cw_sched_cb callback, void *data, int variable)
{
	/*
	 * Schedule callback(data) to happen when ms into the future
	 */
	struct sched *tmp;
	int res = -1;

#ifdef DEBUG_SCHED
	DEBUG_LOG(cw_log(LOG_DEBUG, "cw_sched_add_variable()\n"));
#endif
	cw_mutex_lock(&con->lock);
	if ((tmp = sched_alloc(con))) {
		if ((tmp->id = con->eventcnt++) < 0)
			tmp->id = con->eventcnt = 0;
		tmp->callback = callback;
		tmp->data = data;
		tmp->resched = when;
		tmp->variable = variable;
		tmp->when = cw_tvadd(cw_tvnow(), cw_samp2tv(when, 1000));
		schedule(con, tmp);
		res = tmp->id;
	}
#ifdef DUMP_SCHEDULER
	/* Dump contents of the context while we have the lock so nothing gets screwed up by accident. */
	cw_sched_dump(con);
#endif

	cw_mutex_unlock(&con->lock);
	return res;
}
Esempio n. 4
0
int cw_sched_runq(struct sched_context *con)
{
	/*
	 * Launch all events which need to be run at this time.
	 */
	struct sched *runq, **endq, *current;
	struct timeval tv;
	int x=0;
	int res;
#ifdef DEBUG_SCHED
	DEBUG_LOG(cw_log(LOG_DEBUG, "cw_sched_runq()\n"));
#endif		

	cw_mutex_lock(&con->lock);

	/* schedule all events which are going to expire within 1ms.
	 * We only care about millisecond accuracy anyway, so this will
	 * help us get more than one event at one time if they are very
	 * close together.
	 */
	tv = cw_tvadd(cw_tvnow(), cw_tv(0, 1000));

	runq = con->schedq;
	endq = &runq;
	while (con->schedq && SOONER(con->schedq->when, tv)) {
		endq = &con->schedq->next;
		con->schedq = con->schedq->next;
		con->schedcnt--;
	}
	*endq = NULL;

	cw_mutex_unlock(&con->lock);

	while ((current = runq)) {
		runq = runq->next;
		x++;

		res = current->callback(current->data);

		if (res) {
		 	/*
			 * If they return non-zero, we should schedule them to be
			 * run again.
			 */
			current->when = cw_tvadd(current->when, cw_samp2tv((current->variable ? res : current->resched), 1000));
			schedule(con, current);
		} else {
			/* No longer needed, so release it */
		 	sched_release(con, current);
		}
	}

	return x;
}
Esempio n. 5
0
long cw_sched_when(struct sched_context *con,int id)
{
	struct sched *s;
	long secs;
#ifdef DEBUG_SCHED
	DEBUG_LOG(cw_log(LOG_DEBUG, "cw_sched_when()\n"));
#endif
	cw_mutex_lock(&con->lock);
	s=con->schedq;
	while (s!=NULL) {
		if (s->id==id) break;
		s=s->next;
	}
	secs=-1;
	if (s!=NULL) {
		struct timeval now = cw_tvnow();
		secs=s->when.tv_sec-now.tv_sec;
	}
	cw_mutex_unlock(&con->lock);
	return secs;
}
Esempio n. 6
0
int cw_sched_wait(struct sched_context *con)
{
	/*
	 * Return the number of milliseconds 
	 * until the next scheduled event
	 */
	int ms;
#ifdef DEBUG_SCHED
	DEBUG_LOG(cw_log(LOG_DEBUG, "cw_sched_wait()\n"));
#endif
	cw_mutex_lock(&con->lock);
	if (!con->schedq) {
		ms = -1;
	} else {
		ms = cw_tvdiff_ms(con->schedq->when, cw_tvnow());
		if (ms < 0)
			ms = 0;
	}
	cw_mutex_unlock(&con->lock);
	return ms;
	
}
Esempio n. 7
0
static int sayunixtime_exec(struct cw_channel *chan, int argc, char **argv)
{
	struct timeval tv;
	time_t unixtime;
	struct localuser *u;
	char *format;
	int res=0;

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

	LOCAL_USER_ADD(u);

	if (argc < 1 || !(unixtime = (time_t)atol(argv[0]))) {
		tv = cw_tvnow();
		unixtime = (time_t)tv.tv_sec;
	}

	if (argc > 2 && argv[2][0]) {
		format = argv[2];
	} else if (!strcasecmp(chan->language, "da")) {
		format = "A dBY HMS";
	} else if (!strcasecmp(chan->language, "de")) {
		format = "A dBY HMS";
	} else {
		format = "ABdY 'digits/at' IMp";
	} 

	if (chan->_state != CW_STATE_UP)
		res = cw_answer(chan);

	if (!res)
		res = cw_say_date_with_format(chan, unixtime, CW_DIGIT_ANY, chan->language, format, (argc > 1 && argv[1][0] ? argv[1] : NULL));

	LOCAL_USER_REMOVE(u);
	return res;
}
Esempio n. 8
0
static int pipe_exec(struct cw_channel *chan, int argc, char **argv)
{
	int res=0;
	struct localuser *u;
	int fds[2];
	int ms = -1;
	int pid = -1;
	int owriteformat;
	int oreadformat;
	int timeout = 2000;
	struct timeval last;
	struct cw_frame *f;
	struct myframe {
		struct cw_frame f;
		char offset[CW_FRIENDLY_OFFSET];
		short frdata[160];
	} myf;

	last.tv_usec = 0;
	last.tv_sec = 0;

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

	LOCAL_USER_ADD(u);

	if (pipe(fds)) {
		cw_log(LOG_WARNING, "Unable to create pipe\n");
		LOCAL_USER_REMOVE(u);
		return -1;
	}

// MOC: Setting non blocking doesn't seem to change anything
//	flags = fcntl(fds[1], F_GETFL);
//	fcntl(fds[1], F_SETFL, flags | O_NONBLOCK);

//	flags = fcntl(fds[0], F_GETFL);
//	fcntl(fds[0], F_SETFL, flags | O_NONBLOCK);

	cw_stopstream(chan);

	if (chan->_state != CW_STATE_UP)
		res = cw_answer(chan);
		
	if (res) {
		close(fds[0]);
		close(fds[1]);
		cw_log(LOG_WARNING, "Answer failed!\n");
		LOCAL_USER_REMOVE(u);
		return -1;
	}

	oreadformat = chan->readformat;
	res = cw_set_read_format(chan, CW_FORMAT_SLINEAR);

	owriteformat = chan->writeformat;
	res += cw_set_write_format(chan, CW_FORMAT_SLINEAR);

	if (res < 0) {
		close(fds[0]);
		close(fds[1]);
		cw_log(LOG_WARNING, "Unable to set write format to signed linear\n");
		LOCAL_USER_REMOVE(u);
		return -1;
	}

	res = pipeencode(argv[1], argv[2], fds[0], fds[1]);

	if (res >= 0) {
	   last = cw_tvnow();
	   last.tv_sec += 1;

		pid = res;
		for (;;) {
			/* Wait for audio, and stream */
			if (argv[0][0] == '0') {
				/* START WRITE TO FD */
				ms = cw_waitfor(chan, 10);
				if (ms < 0) {
					cw_log(LOG_DEBUG, "Hangup detected\n");
					res = -1;
					break;
				} else if (ms > 0) {
					f = cw_read(chan);
					if (!f) {
						cw_log(LOG_DEBUG, "Null frame == hangup() detected\n");
						res = -1;
						break;
					}
					if (f->frametype == CW_FRAME_DTMF) {
						cw_log(LOG_DEBUG, "User pressed a key\n");
						cw_fr_free(f);
						res = 0;
						break;
					}
					if (f->frametype == CW_FRAME_VOICE) {
						res = write(fds[1], f->data, f->datalen);
						if (res < 0) {
							if (errno != EAGAIN) {
								cw_log(LOG_WARNING, "Write failed to pipe: %s\n", strerror(errno));
                                cw_fr_free(f);
								res = -1;
								break;
							}
						}
					}
					cw_fr_free(f);
				} /* END WRITE TO FD */
			} else {
				/* START WRITE CHANNEL */
				ms = cw_tvdiff_ms(last, cw_tvnow());
				if (ms <= 0) {
					res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata), timeout);
					if (res > 0) {
                        cw_fr_init_ex(&myf.f, CW_FRAME_VOICE, CW_FORMAT_SLINEAR, __PRETTY_FUNCTION__);
						myf.f.datalen = res;
						myf.f.samples = res/sizeof(int16_t);
						myf.f.offset = CW_FRIENDLY_OFFSET;
						myf.f.data = myf.frdata;
						if (cw_write(chan, &myf.f) < 0)
                        {
							res = -1;
							break;
						}
					} else {
						cw_log(LOG_DEBUG, "No more stream\n");
						res = 0;
						break;
					}
					last = cw_tvadd(last, cw_samp2tv(myf.f.samples, 8000));
				} else {
					ms = cw_waitfor(chan, ms);
					if (ms < 0) {
						cw_log(LOG_DEBUG, "Hangup detected\n");
						res = -1;
						break;
					}
					if (ms) {
						f = cw_read(chan);
						if (!f) {
							cw_log(LOG_DEBUG, "Null frame == hangup() detected\n");
							res = -1;
							break;
						}
						if (f->frametype == CW_FRAME_DTMF) {
							cw_log(LOG_DEBUG, "User pressed a key\n");
							cw_fr_free(f);
							res = 0;
							break;
						}
						cw_fr_free(f);
					}
				}
				/* END WRITE CHANNEL */
			}
		}
	}
	close(fds[0]);
	close(fds[1]);

	LOCAL_USER_REMOVE(u);
	if (pid > -1)
		kill(pid, SIGKILL);
	if (!res && oreadformat)
		cw_set_read_format(chan, oreadformat);
	if (!res && owriteformat)
		cw_set_write_format(chan, owriteformat);

	return res;
}
Esempio n. 9
0
static int cw_serialize_showchan(struct cw_channel *c, char *buf, size_t size)
{
	struct timeval now;
	long elapsed_seconds=0;
	int hour=0, min=0, sec=0;
	char cgrp[256];
	char pgrp[256];
	
	now = cw_tvnow();
	memset(buf,0,size);
	if (!c)
		return 0;

	if (c->cdr) {
		elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
		hour = elapsed_seconds / 3600;
		min = (elapsed_seconds % 3600) / 60;
		sec = elapsed_seconds % 60;
	}

	snprintf(buf,size, 
			 "Name=               %s\n"
			 "Type=               %s\n"
			 "UniqueID=           %s\n"
			 "CallerID=           %s\n"
			 "CallerIDName=       %s\n"
			 "DNIDDigits=         %s\n"
			 "State=              %s (%d)\n"
			 "Rings=              %d\n"
			 "NativeFormat=       %d\n"
			 "WriteFormat=        %d\n"
			 "ReadFormat=         %d\n"
			 "1stFileDescriptor=  %d\n"
			 "Framesin=           %d %s\n"
			 "Framesout=          %d %s\n"
			 "TimetoHangup=       %ld\n"
			 "ElapsedTime=        %dh%dm%ds\n"
			 "Context=            %s\n"
			 "Extension=          %s\n"
			 "Priority=           %d\n"
			 "CallGroup=          %s\n"
			 "PickupGroup=        %s\n"
			 "Application=        %s\n"
			 "Blocking_in=        %s\n",
			 c->name,
			 c->type,
			 c->uniqueid,
			 (c->cid.cid_num ? c->cid.cid_num : "(N/A)"),
			 (c->cid.cid_name ? c->cid.cid_name : "(N/A)"),
			 (c->cid.cid_dnid ? c->cid.cid_dnid : "(N/A)" ),
			 cw_state2str(c->_state),
			 c->_state,
			 c->rings,
			 c->nativeformats,
			 c->writeformat,
			 c->readformat,
			 c->fds[0], c->fin & 0x7fffffff, (c->fin & 0x80000000) ? " (DEBUGGED)" : "",
			 c->fout & 0x7fffffff, (c->fout & 0x80000000) ? " (DEBUGGED)" : "", (long)c->whentohangup,
			 hour,
			 min,
			 sec,
			 c->context,
			 c->exten,
			 c->priority,
			 cw_print_group(cgrp, sizeof(cgrp), c->callgroup),
			 cw_print_group(pgrp, sizeof(pgrp), c->pickupgroup),
			 ( c->appl ? c->appl : "(N/A)" ),
			 (cw_test_flag(c, CW_FLAG_BLOCKING) ? c->blockproc : "(Not Blocking)"));

	return 0;
}
Esempio n. 10
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;
}