Ejemplo n.º 1
0
FT_DECLARE(ftdm_status_t) ftdm_conf_node_add_param(ftdm_conf_node_t *node, const char *param, const char *val)
{
	void *newparameters;

	ftdm_assert_return(param != NULL, FTDM_FAIL, "param is null");
	ftdm_assert_return(val != NULL, FTDM_FAIL, "val is null");

	if (node->n_parameters == node->t_parameters) {
		newparameters = ftdm_realloc(node->parameters, (node->t_parameters + PARAMETERS_CHUNK_SIZE) * sizeof(*node->parameters));
		if (!newparameters) {
			return FTDM_MEMERR;
		}
		node->parameters = newparameters;
		node->t_parameters = node->n_parameters + PARAMETERS_CHUNK_SIZE;
	}
	node->parameters[node->n_parameters].var = param;
	node->parameters[node->n_parameters].val = val;
	node->n_parameters++;
	return FTDM_SUCCESS;
}
Ejemplo n.º 2
0
FT_DECLARE(ftdm_status_t) ftdm_conf_node_create(const char *name, ftdm_conf_node_t **node, ftdm_conf_node_t *parent)
{
	ftdm_conf_node_t *newnode;
	ftdm_conf_node_t *sibling = NULL;

	ftdm_assert_return(name != NULL, FTDM_FAIL, "null node name");

	newnode = ftdm_calloc(1, sizeof(**node));
	if (!newnode) {
		return FTDM_MEMERR;
	}

	strncpy(newnode->name, name, sizeof(newnode->name)-1);	
	newnode->name[sizeof(newnode->name)-1] = 0;

	newnode->parameters = ftdm_calloc(PARAMETERS_CHUNK_SIZE, sizeof(*newnode->parameters));
	if (!newnode->parameters) {
		ftdm_safe_free(newnode);
		return FTDM_MEMERR;
	}
	newnode->t_parameters = PARAMETERS_CHUNK_SIZE;

	if (parent) {
		/* store who my parent is */
		newnode->parent = parent;

		/* arrange them in FIFO order (newnode should be last) */
		if (!parent->child) {
			/* we're the first node being added */
			parent->child = newnode;
		} else {
			if (!parent->last) {
				/* we're the second node being added */
				parent->last = newnode;
				parent->child->next = newnode;
				newnode->prev = parent->child;
			} else {
				/* we're the third or Nth node to be added */
				sibling = parent->last;
				sibling->next = newnode;
				parent->last = newnode;
				newnode->prev = sibling;
			}
		}
	}

	*node = newnode;

	return FTDM_SUCCESS;
}
Ejemplo n.º 3
0
FT_DECLARE(ftdm_status_t) ftdm_sched_create(ftdm_sched_t **sched, const char *name)
{
	ftdm_sched_t *newsched = NULL;

	ftdm_assert_return(sched != NULL, FTDM_EINVAL, "invalid pointer\n");
	ftdm_assert_return(name != NULL, FTDM_EINVAL, "invalid sched name\n");

	*sched = NULL;

	newsched = ftdm_calloc(1, sizeof(*newsched));
	if (!newsched) {
		return FTDM_MEMERR;
	}

	if (ftdm_mutex_create(&newsched->mutex) != FTDM_SUCCESS) {
		goto failed;
	}

	ftdm_set_string(newsched->name, name);
	newsched->currid = 1;

	*sched = newsched;
	ftdm_log(FTDM_LOG_DEBUG, "Created schedule %s\n", name);
	return FTDM_SUCCESS;

failed:
	ftdm_log(FTDM_LOG_CRIT, "Failed to create schedule\n");

	if (newsched) {
		if (newsched->mutex) {
			ftdm_mutex_destroy(&newsched->mutex);
		}
		ftdm_safe_free(newsched);
	}
	return FTDM_FAIL;
}
Ejemplo n.º 4
0
FT_DECLARE(ftdm_status_t) ftdm_interrupt_create(ftdm_interrupt_t **ininterrupt, ftdm_socket_t device)
{
	ftdm_interrupt_t *interrupt = NULL;
#ifndef WIN32
	int fds[2];
#endif

	ftdm_assert_return(ininterrupt != NULL, FTDM_FAIL, "interrupt double pointer is null!\n");

	interrupt = ftdm_calloc(1, sizeof(*interrupt));
	if (!interrupt) {
		ftdm_log(FTDM_LOG_ERROR, "Failed to allocate interrupt memory\n");
		return FTDM_FAIL;
	}

	interrupt->device = device;
#ifdef WIN32
	interrupt->event = CreateEvent(NULL, FALSE, FALSE, NULL);
	if (!interrupt->event) {
		ftdm_log(FTDM_LOG_ERROR, "Failed to allocate interrupt event\n");
		goto failed;
	}
#else
	if (pipe(fds)) {
		ftdm_log(FTDM_LOG_ERROR, "Failed to allocate interrupt pipe: %s\n", strerror(errno));
		goto failed;
	}
	interrupt->readfd = fds[0];
	interrupt->writefd = fds[1];
#endif

	*ininterrupt = interrupt;
	return FTDM_SUCCESS;

failed:
	if (interrupt) {
#ifndef WIN32
		if (interrupt->readfd) {
			close(interrupt->readfd);
			close(interrupt->writefd);
			interrupt->readfd = -1;
			interrupt->writefd = -1;
		}
#endif
		ftdm_safe_free(interrupt);
	}
	return FTDM_FAIL;
}
ftdm_status_t sngisdn_add_var(sngisdn_chan_data_t *sngisdn_info, const char* var, const char* val)
{
	char *t_name = 0, *t_val = 0;
	if (!var || !val) {
		return FTDM_FAIL;
	}
	if (!sngisdn_info->variables) {
		/* initialize on first use */
		sngisdn_info->variables = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys);
		ftdm_assert_return(sngisdn_info->variables, FTDM_FAIL, "Failed to create hash table\n");
	}
	t_name = ftdm_strdup(var);
	t_val = ftdm_strdup(val);
	hashtable_insert(sngisdn_info->variables, t_name, t_val, HASHTABLE_FLAG_FREE_KEY | HASHTABLE_FLAG_FREE_VALUE);
	return FTDM_SUCCESS;
}
Ejemplo n.º 6
0
FT_DECLARE(ftdm_status_t) ftdm_interrupt_destroy(ftdm_interrupt_t **ininterrupt)
{
	ftdm_interrupt_t *interrupt = NULL;
	ftdm_assert_return(ininterrupt != NULL, FTDM_FAIL, "Interrupt null when destroying!\n");
	interrupt = *ininterrupt;
#ifdef WIN32
	CloseHandle(interrupt->event);
#else
	close(interrupt->readfd);
	close(interrupt->writefd);
	interrupt->readfd = -1;
	interrupt->writefd = -1;
#endif
	ftdm_safe_free(interrupt);
	*ininterrupt = NULL;
	return FTDM_SUCCESS;
}
Ejemplo n.º 7
0
FT_DECLARE(ftdm_status_t) ftdm_interrupt_signal(ftdm_interrupt_t *interrupt)
{
	ftdm_assert_return(interrupt != NULL, FTDM_FAIL, "Interrupt is null!\n");
#ifdef WIN32
	if (!SetEvent(interrupt->event)) {
		ftdm_log(FTDM_LOG_ERROR, "Failed to signal interrupt\n");
		return FTDM_FAIL;
	}
#else
	int err;
	if ((err = write(interrupt->writefd, "w", 1)) != 1) {
		ftdm_log(FTDM_LOG_ERROR, "Failed to signal interrupt: %s\n", errno, strerror(errno));
		return FTDM_FAIL;
	}
#endif
	return FTDM_SUCCESS;
}
Ejemplo n.º 8
0
FT_DECLARE(ftdm_status_t) ftdm_sched_free_run(ftdm_sched_t *sched)
{
	ftdm_status_t status = FTDM_FAIL;
	ftdm_assert_return(sched != NULL, FTDM_EINVAL, "invalid pointer\n");

	ftdm_mutex_lock(sched->mutex);

	ftdm_mutex_lock(sched_globals.mutex);

	if (sched->freerun) {
		ftdm_log(FTDM_LOG_ERROR, "Schedule %s is already running in free run\n", sched->name);
		goto done;
	}
	sched->freerun = 1;

	if (sched_globals.running == FTDM_FALSE) {
		ftdm_log(FTDM_LOG_NOTICE, "Launching main schedule thread\n");
		status = ftdm_thread_create_detached(run_main_schedule, NULL);
		if (status != FTDM_SUCCESS) {
			ftdm_log(FTDM_LOG_CRIT, "Failed to launch main schedule thread\n");
			goto done;
		} 
		sched_globals.running = FTDM_TRUE;
	}

	ftdm_log(FTDM_LOG_DEBUG, "Running schedule %s in the main schedule thread\n", sched->name);
	status = FTDM_SUCCESS;
	
	/* Add the schedule to the global list of free runs */
	if (!sched_globals.freeruns) {
		sched_globals.freeruns = sched;
	}  else {
		sched->next = sched_globals.freeruns;
		sched_globals.freeruns->prev = sched;
		sched_globals.freeruns = sched;
	}

done:
	ftdm_mutex_unlock(sched_globals.mutex);

	ftdm_mutex_unlock(sched->mutex);
	return status;
}
Ejemplo n.º 9
0
FT_DECLARE(ftdm_status_t) ftdm_channel_advance_states(ftdm_channel_t *fchan)
{
	ftdm_channel_state_t state;

	ftdm_assert_return(fchan->span->state_processor, FTDM_FAIL, "Cannot process states without a state processor!\n");
	
	while (fchan->state_status == FTDM_STATE_STATUS_NEW) {
		state = fchan->state;
		ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Executing state processor for %s\n", ftdm_channel_state2str(fchan->state));
		fchan->span->state_processor(fchan);
		if (state == fchan->state && fchan->state_status == FTDM_STATE_STATUS_NEW) {
			/* if the state did not change and is still NEW, the state status must go to PROCESSED
			 * otherwise we don't touch it since is a new state and the old state was
			 * already completed implicitly by the state_processor() function via some internal
			 * call to ftdm_set_state() */
			fchan->state_status = FTDM_STATE_STATUS_PROCESSED;
		}		
	}

	return FTDM_SUCCESS;
}
uint32_t get_unique_suInstId(int16_t cc_id)
{
	uint32_t suInstId;
	ftdm_assert_return((cc_id > 0 && cc_id <=MAX_VARIANTS), FTDM_FAIL, "Invalid cc_id\n");
	ftdm_mutex_lock(g_sngisdn_data.ccs[cc_id].mutex);
	suInstId = g_sngisdn_data.ccs[cc_id].last_suInstId;

	while(1) {
		if (++suInstId == MAX_INSTID) {
			suInstId = 1;
		}
		if (g_sngisdn_data.ccs[cc_id].active_suInstIds[suInstId] == NULL) {
			g_sngisdn_data.ccs[cc_id].last_suInstId = suInstId;
			ftdm_mutex_unlock(g_sngisdn_data.ccs[cc_id].mutex);
			return suInstId;
		}
	}
	/* Should never reach here */
	ftdm_mutex_unlock(g_sngisdn_data.ccs[cc_id].mutex);
	return 0;
}
Ejemplo n.º 11
0
FT_DECLARE(ftdm_status_t) ftdm_sched_cancel_timer(ftdm_sched_t *sched, ftdm_timer_id_t timerid)
{
	ftdm_status_t status = FTDM_FAIL;
	ftdm_timer_t *timer;

	ftdm_assert_return(sched != NULL, FTDM_EINVAL, "sched is null!\n");

	if (!timerid) {
		return FTDM_SUCCESS;
	}

	ftdm_mutex_lock(sched->mutex);

	/* look for the timer and destroy it */
	for (timer = sched->timers; timer; timer = timer->next) {
		if (timer->id == timerid) {
			if (timer == sched->timers) {
				/* it's the head timer, put a new head */
				sched->timers = timer->next;
			}
			if (timer->prev) {
				timer->prev->next = timer->next;
			}
			if (timer->next) {
				timer->next->prev = timer->prev;
			}
			ftdm_safe_free(timer);
			status = FTDM_SUCCESS;
			break;
		}
	}

	ftdm_mutex_unlock(sched->mutex);

	return status;
}
Ejemplo n.º 12
0
static void *ftdm_gsm_run(ftdm_thread_t *me, void *obj)
{

	ftdm_log(FTDM_LOG_INFO,"ftdm_gsm_run\r\n");

	ftdm_channel_t *ftdmchan = NULL;
	ftdm_span_t *span = (ftdm_span_t *) obj;
	ftdm_gsm_span_data_t *gsm_data = NULL;
	ftdm_interrupt_t *data_sources[2] = {NULL, NULL};
	int waitms = 0;
	
	gsm_data = span->signal_data;

	ftdm_assert_return(gsm_data != NULL, NULL, "No gsm data attached to span\n");

	ftdm_log(FTDM_LOG_DEBUG, "GSM monitor thread for span %s started\n", span->name);
	if (!gsm_data->dchan || ftdm_channel_open_chan(gsm_data->dchan) != FTDM_SUCCESS) {
		ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to open GSM d-channel of span %s!\n", span->name);
		gsm_data->dchan = NULL;
		goto done;
	}




	while (ftdm_running()) {

		wat_span_run(span->span_id);

		waitms = wat_span_schedule_next(span->span_id);
		if (waitms > GSM_POLL_INTERVAL_MS) {
			waitms = GSM_POLL_INTERVAL_MS;
		}

/////////////////////
		

		{
			ftdm_wait_flag_t flags = FTDM_READ | FTDM_EVENTS;
			ftdm_status_t status = ftdm_channel_wait(gsm_data->dchan, &flags, waitms);
			
	
			/* double check that this channel has a state change pending */
			ftdm_channel_lock(gsm_data->bchan);
			ftdm_channel_advance_states(gsm_data->bchan);
					
			if(FTDM_SUCCESS == status ) {
		
				if(flags &FTDM_READ ) {
					char buffer[1025];
					int n = 0, m = 0;
					memset(buffer, 0, sizeof(buffer));

					n = read_channel(gsm_data->dchan, buffer, sizeof(buffer)-1);
					m = strlen(buffer);	
					wat_span_process_read(span->span_id, buffer, m);
#if 	 LOG_SIG_DATA
						printf("<<======================= incomming data len = %d, %s\r\n", n, buffer);
#endif

				}
			}
			
			ftdm_channel_advance_states(gsm_data->bchan);
			
			ftdm_channel_unlock(gsm_data->bchan);
			

		}


		

		ftdm_span_trigger_signals(span);


	}

done:
	if (data_sources[0]) {
		ftdm_interrupt_destroy(&data_sources[0]);
	}

	ftdm_log(FTDM_LOG_DEBUG, "GSM thread ending.\n");

	return NULL;
}
Ejemplo n.º 13
0
FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const char *func, int line, ftdm_channel_t *fchan)
{
	uint8_t hindex = 0;
	ftdm_time_t diff = 0;
	ftdm_channel_state_t state = fchan->state;

	if (fchan->state_status == FTDM_STATE_STATUS_COMPLETED) {
		ftdm_assert_return(!ftdm_test_flag(fchan, FTDM_CHANNEL_STATE_CHANGE), FTDM_FAIL, 
				"State change flag set but state is not completed\n");
		return FTDM_SUCCESS;
	}

	ftdm_usrmsg_free(&fchan->usrmsg);
	
	ftdm_clear_flag(fchan, FTDM_CHANNEL_STATE_CHANGE);

	if (state == FTDM_CHANNEL_STATE_PROGRESS) {
		ftdm_set_flag(fchan, FTDM_CHANNEL_PROGRESS);
	} else if (state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA) {
		ftdm_set_flag(fchan, FTDM_CHANNEL_PROGRESS);	
		ftdm_test_and_set_media(fchan);
	} else if (state == FTDM_CHANNEL_STATE_UP) {
		ftdm_set_flag(fchan, FTDM_CHANNEL_PROGRESS);
		ftdm_set_flag(fchan, FTDM_CHANNEL_ANSWERED);	
		ftdm_test_and_set_media(fchan);
	} else if (state == FTDM_CHANNEL_STATE_DIALING) {
		ftdm_sigmsg_t msg;
		memset(&msg, 0, sizeof(msg));
		msg.channel = fchan;
		msg.event_id = FTDM_SIGEVENT_DIALING;
		ftdm_span_send_signal(fchan->span, &msg);
	} else if (state == FTDM_CHANNEL_STATE_HANGUP) {
		ftdm_set_echocancel_call_end(fchan);
	}

	/* MAINTENANCE WARNING
	 * we're assuming an indication performed 
	 * via state change will involve a single state change */
	ftdm_ack_indication(fchan, fchan->indication, FTDM_SUCCESS);

	hindex = (fchan->hindex == 0) ? (ftdm_array_len(fchan->history) - 1) : (fchan->hindex - 1);
	
	ftdm_assert(!fchan->history[hindex].end_time, "End time should be zero!\n");

	fchan->history[hindex].end_time = ftdm_current_time_in_ms();

	fchan->state_status = FTDM_STATE_STATUS_COMPLETED;

	diff = fchan->history[hindex].end_time - fchan->history[hindex].time;

	ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Completed state change from %s to %s in %llums\n", 
			ftdm_channel_state2str(fchan->last_state), ftdm_channel_state2str(state), diff);
	

	if (ftdm_test_flag(fchan, FTDM_CHANNEL_BLOCKING)) {
		ftdm_clear_flag(fchan, FTDM_CHANNEL_BLOCKING);
		ftdm_interrupt_signal(fchan->state_completed_interrupt);
	}

	return FTDM_SUCCESS;
}
Ejemplo n.º 14
0
FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name, 
		int ms, ftdm_sched_callback_t callback, void *data, ftdm_timer_id_t *timerid)
{
	ftdm_status_t status = FTDM_FAIL;
	struct timeval now;
	int rc = 0;
	ftdm_timer_t *newtimer;

	ftdm_assert_return(sched != NULL, FTDM_EINVAL, "sched is null!\n");
	ftdm_assert_return(name != NULL, FTDM_EINVAL, "timer name is null!\n");
	ftdm_assert_return(callback != NULL, FTDM_EINVAL, "sched callback is null!\n");
	ftdm_assert_return(ms > 0, FTDM_EINVAL, "milliseconds must be bigger than 0!\n");

	if (timerid) {
		*timerid = 0;
	}

	rc = gettimeofday(&now, NULL);
	if (rc == -1) {
		ftdm_log(FTDM_LOG_ERROR, "Failed to retrieve time of day\n");
		return FTDM_FAIL;
	}

	ftdm_mutex_lock(sched->mutex);

	newtimer = ftdm_calloc(1, sizeof(*newtimer));
	if (!newtimer) {
		goto done;
	}
	newtimer->id = sched->currid;
	sched->currid++;
	if (!sched->currid) {
		ftdm_log(FTDM_LOG_NOTICE, "Timer id wrap around for sched %s\n", sched->name);
		/* we do not want currid to be zero since is an invalid id 
		 * TODO: check that currid does not exists already in the context, it'd be insane
		 * though, having a timer to live all that time */
		sched->currid++;
	}

	ftdm_set_string(newtimer->name, name);
	newtimer->callback = callback;
	newtimer->usrdata = data;

	newtimer->time.tv_sec = now.tv_sec + (ms / 1000);
	newtimer->time.tv_usec = now.tv_usec + (ms % 1000) * 1000;
	if (newtimer->time.tv_usec >= FTDM_MICROSECONDS_PER_SECOND) {
		newtimer->time.tv_sec += 1;
		newtimer->time.tv_usec -= FTDM_MICROSECONDS_PER_SECOND;
	}

	if (!sched->timers) {
		sched->timers = newtimer;
	}  else {
		newtimer->next = sched->timers;
		sched->timers->prev = newtimer;
		sched->timers = newtimer;
	}

	if (timerid) {
		*timerid = newtimer->id;
	}

	status = FTDM_SUCCESS;
done:

	ftdm_mutex_unlock(sched->mutex);
#ifdef __WINDOWS__
	UNREFERENCED_PARAMETER(sched);
	UNREFERENCED_PARAMETER(name);
	UNREFERENCED_PARAMETER(ms);
	UNREFERENCED_PARAMETER(callback);
	UNREFERENCED_PARAMETER(data);
	UNREFERENCED_PARAMETER(timerid);
#endif
	return status;
}
Ejemplo n.º 15
0
FT_DECLARE(ftdm_status_t) ftdm_sched_run(ftdm_sched_t *sched)
{
	ftdm_status_t status = FTDM_FAIL;
	ftdm_timer_t *runtimer;
	ftdm_timer_t *timer;
	ftdm_sched_callback_t callback;
	int ms = 0;
	int rc = -1;
	void *data;
	struct timeval now;

	ftdm_assert_return(sched != NULL, FTDM_EINVAL, "sched is null!\n");

tryagain:

	ftdm_mutex_lock(sched->mutex);

	rc = gettimeofday(&now, NULL);
	if (rc == -1) {
		ftdm_log(FTDM_LOG_ERROR, "Failed to retrieve time of day\n");
		goto done;
	}

	timer = sched->timers;
	while (timer) {
		runtimer = timer;
		timer = runtimer->next;

		ms = ((runtimer->time.tv_sec - now.tv_sec) * 1000) +
		     ((runtimer->time.tv_usec - now.tv_usec) / 1000);

		if (ms <= 0) {

			if (runtimer == sched->timers) {
				sched->timers = runtimer->next;
				if (sched->timers) {
					sched->timers->prev = NULL;
				}
			}

			callback = runtimer->callback;
			data = runtimer->usrdata;
			if (runtimer->next) {
				runtimer->next->prev = runtimer->prev;
			}
			if (runtimer->prev) {
				runtimer->prev->next = runtimer->next;
			}

			runtimer->id = 0;
			ftdm_safe_free(runtimer);

			/* avoid deadlocks by releasing the sched lock before triggering callbacks */
			ftdm_mutex_unlock(sched->mutex);

			callback(data);
			/* after calling a callback we must start the scanning again since the
			 * callback or some other thread may have added or cancelled timers to 
			 * the linked list */
			goto tryagain;
		}
	}

	status = FTDM_SUCCESS;

done:

	ftdm_mutex_unlock(sched->mutex);
#ifdef __WINDOWS__
	UNREFERENCED_PARAMETER(sched);
#endif

	return status;
}
Ejemplo n.º 16
0
FT_DECLARE(ftdm_status_t) ftdm_interrupt_wait(ftdm_interrupt_t *interrupt, int ms)
{
	int num = 1;
#ifdef WIN32
	DWORD res = 0;
	HANDLE ints[2];
#else
	int res = 0;
	struct pollfd ints[2];
	char pipebuf[255];
#endif

	ftdm_assert_return(interrupt != NULL, FTDM_FAIL, "Condition is null!\n");


	/* start implementation */
#ifdef WIN32
	ints[0] = interrupt->event;
	if (interrupt->device != FTDM_INVALID_SOCKET) {
		num++;
		ints[1] = interrupt->device;
	}
	res = WaitForMultipleObjects(num, ints, FALSE, ms >= 0 ? ms : INFINITE);
	switch (res) {
	case WAIT_TIMEOUT:
		return FTDM_TIMEOUT;
	case WAIT_FAILED:
	case WAIT_ABANDONED: /* is it right to fail with abandoned? */
		return FTDM_FAIL;
	default:
		if (res >= (sizeof(ints)/sizeof(ints[0]))) {
			ftdm_log(FTDM_LOG_ERROR, "Error waiting for freetdm interrupt event (WaitForSingleObject returned %d)\n", res);
			return FTDM_FAIL;
		}
		return FTDM_SUCCESS;
	}
#else
	ints[0].fd = interrupt->readfd;
	ints[0].events = POLLIN;
	ints[0].revents = 0;

	if (interrupt->device != FTDM_INVALID_SOCKET) {
		num++;
		ints[1].fd = interrupt->device;
		ints[1].events = POLLIN;
		ints[1].revents = 0;
	}

	res = poll(ints, num, ms);

	if (res == -1) {
		ftdm_log(FTDM_LOG_CRIT, "interrupt poll failed (%s)\n", strerror(errno));
		return FTDM_FAIL;
	}

	if (res == 0) {
		return FTDM_TIMEOUT;
	}

	if (ints[0].revents & POLLIN) {
		res = read(ints[0].fd, pipebuf, sizeof(pipebuf));
		if (res == -1) {
			ftdm_log(FTDM_LOG_CRIT, "reading interrupt descriptor failed (%s)\n", strerror(errno));
		}
	}

	return FTDM_SUCCESS;
#endif
}