Exemple #1
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;
	
}
Exemple #2
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;
}
Exemple #3
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;
}