freetdm: ftdm_channel_read_event() to retrieve events from a channel, removed from ftmod_r2: ftdm_r2_sig_read(), FTDM_R2_PROCESSING flag and locks for ftdmchan
This commit is contained in:
parent
5eb172d9f3
commit
c842466a68
|
@ -988,6 +988,51 @@ FT_DECLARE(ftdm_status_t) ftdm_span_next_event(ftdm_span_t *span, ftdm_event_t *
|
|||
return status;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_read_event(ftdm_channel_t *ftdmchan, ftdm_event_t **event)
|
||||
{
|
||||
ftdm_status_t status = FTDM_FAIL;
|
||||
ftdm_sigmsg_t sigmsg;
|
||||
ftdm_span_t *span = ftdmchan->span;
|
||||
ftdm_assert_return(span->fio != NULL, FTDM_FAIL, "No I/O module attached to this span!\n");
|
||||
|
||||
if (!span->fio->channel_next_event) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "channel_next_event method not implemented in module %s!", span->fio->name);
|
||||
return FTDM_NOTIMPL;
|
||||
}
|
||||
|
||||
status = span->fio->channel_next_event(ftdmchan, event);
|
||||
if (status != FTDM_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* before returning the event to the user we do some core operations with certain OOB events */
|
||||
memset(&sigmsg, 0, sizeof(sigmsg));
|
||||
sigmsg.span_id = span->span_id;
|
||||
sigmsg.chan_id = (*event)->channel->chan_id;
|
||||
sigmsg.channel = (*event)->channel;
|
||||
switch ((*event)->enum_id) {
|
||||
case FTDM_OOB_ALARM_CLEAR:
|
||||
{
|
||||
sigmsg.event_id = FTDM_SIGEVENT_ALARM_CLEAR;
|
||||
ftdm_clear_flag_locked((*event)->channel, FTDM_CHANNEL_IN_ALARM);
|
||||
ftdm_span_send_signal(span, &sigmsg);
|
||||
}
|
||||
break;
|
||||
case FTDM_OOB_ALARM_TRAP:
|
||||
{
|
||||
sigmsg.event_id = FTDM_SIGEVENT_ALARM_TRAP;
|
||||
ftdm_set_flag_locked((*event)->channel, FTDM_CHANNEL_IN_ALARM);
|
||||
ftdm_span_send_signal(span, &sigmsg);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* NOOP */
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static ftdm_status_t ftdmchan_fsk_write_sample(int16_t *buf, ftdm_size_t buflen, void *user_data)
|
||||
{
|
||||
ftdm_channel_t *ftdmchan = (ftdm_channel_t *) user_data;
|
||||
|
|
|
@ -57,8 +57,7 @@ typedef enum {
|
|||
} ftdm_r2_flag_t;
|
||||
|
||||
typedef enum {
|
||||
FTDM_R2_PROCESSING = (1 << 0),
|
||||
FTDM_R2_WAITING_ACK = (1 << 1),
|
||||
FTDM_R2_WAITING_ACK = (1 << 0),
|
||||
} ftdm_r2_call_flag_t;
|
||||
|
||||
/* private call information stored in ftdmchan->call_data void* ptr */
|
||||
|
@ -398,44 +397,26 @@ static ftdm_status_t ftdm_r2_stop(ftdm_span_t *span)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static ftdm_status_t ftdm_r2_sig_read(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t size)
|
||||
{
|
||||
openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan;
|
||||
if (!openr2_chan_get_read_enabled(r2chan)) {
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
//openr2_chan_process_input(r2chan, data, size);
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/* always called from the monitor thread */
|
||||
static void ftdm_r2_on_call_init(openr2_chan_t *r2chan)
|
||||
{
|
||||
//ftdm_status_t status;
|
||||
ftdm_r2_call_t *r2call;
|
||||
ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
|
||||
//ftdm_r2_data_t *r2data = ftdmchan->span->signal_data;
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_NOTICE, "Received request to start call\n");
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Cannot start call when channel is in use (state = %s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Cannot handle request to start call in state %s\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to open channel during incoming call! [%s]\n", ftdmchan->last_error);
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -448,7 +429,6 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan)
|
|||
/* clean the call data structure but keep the R2 processing flag on! */
|
||||
ft_r2_clean_call(ftdmchan->call_data);
|
||||
r2call = R2CALL(ftdmchan);
|
||||
ftdm_set_flag(r2call, FTDM_R2_PROCESSING);
|
||||
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN) {
|
||||
R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN;
|
||||
|
@ -457,7 +437,6 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan)
|
|||
}
|
||||
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
}
|
||||
|
||||
/* only called for incoming calls when the ANI, DNIS etc is complete and the user has to decide either to accept or reject the call */
|
||||
|
@ -574,11 +553,8 @@ static void ftdm_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_err
|
|||
ftdm_r2_data_t *r2data;
|
||||
ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Got protocol error when we're already down!\n");
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
}
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Protocol error\n");
|
||||
|
@ -587,7 +563,6 @@ static void ftdm_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_err
|
|||
|
||||
if (!R2CALL(ftdmchan)->ftdm_started) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -602,8 +577,6 @@ static void ftdm_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_err
|
|||
r2data = ftdmchan->span->signal_data;
|
||||
|
||||
ftdm_span_send_signal(ftdmchan->span, &sigev);
|
||||
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
}
|
||||
|
||||
static void ftdm_r2_on_line_blocked(openr2_chan_t *r2chan)
|
||||
|
@ -867,9 +840,37 @@ static int ftdm_r2_io_setup(openr2_chan_t *r2chan)
|
|||
|
||||
static int ftdm_r2_io_get_oob_event(openr2_chan_t *r2chan, openr2_oob_event_t *event)
|
||||
{
|
||||
*event = 0;
|
||||
ftdm_log(FTDM_LOG_ERROR, "I should not be called (I/O get oob event)!!\n");
|
||||
return 0;
|
||||
ftdm_status_t status;
|
||||
ftdm_event_t *fevent = NULL;
|
||||
ftdm_channel_t *ftdmchan = openr2_chan_get_fd(r2chan);
|
||||
|
||||
*event = OR2_OOB_EVENT_NONE;
|
||||
status = ftdm_channel_read_event(ftdmchan, &fevent);
|
||||
if (status != FTDM_SUCCESS) {
|
||||
//ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "failed to retrieve freetdm event!\n");
|
||||
return -1;
|
||||
}
|
||||
if (fevent->e_type != FTDM_EVENT_OOB)
|
||||
return 0;
|
||||
switch (fevent->enum_id) {
|
||||
case FTDM_OOB_CAS_BITS_CHANGE:
|
||||
{
|
||||
*event = OR2_OOB_EVENT_CAS_CHANGE;
|
||||
}
|
||||
break;
|
||||
case FTDM_OOB_ALARM_TRAP:
|
||||
{
|
||||
*event = OR2_OOB_EVENT_ALARM_ON;
|
||||
}
|
||||
break;
|
||||
case FTDM_OOB_ALARM_CLEAR:
|
||||
{
|
||||
*event = OR2_OOB_EVENT_ALARM_OFF;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "returning event: %s\n", ftdm_signal_event2str(*event));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static openr2_io_interface_t ftdm_r2_io_iface = {
|
||||
|
@ -1137,7 +1138,7 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_r2_configure_span)
|
|||
|
||||
span->start = ftdm_r2_start;
|
||||
span->stop = ftdm_r2_stop;
|
||||
span->sig_read = ftdm_r2_sig_read;
|
||||
span->sig_read = NULL;
|
||||
|
||||
span->signal_cb = sig_cb;
|
||||
span->signal_type = FTDM_SIGTYPE_R2;
|
||||
|
@ -1350,6 +1351,7 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
|||
int ms;
|
||||
struct timeval start, end;
|
||||
short *poll_events = ftdm_malloc(sizeof(short)*span->chan_count);
|
||||
ftdm_event_t *event = NULL;
|
||||
|
||||
#ifdef __linux__
|
||||
r2data->monitor_thread_id = syscall(SYS_gettid);
|
||||
|
@ -1401,63 +1403,44 @@ static void *ftdm_r2_run(ftdm_thread_t *me, void *obj)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (FTDM_SUCCESS == status) {
|
||||
ftdm_event_t *event;
|
||||
while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) {
|
||||
if (event->enum_id == FTDM_OOB_CAS_BITS_CHANGE) {
|
||||
r2call = R2CALL(event->channel);
|
||||
r2chan = r2call->r2chan;
|
||||
/* XXX
|
||||
* when ftdm_span_poll_event() returns FTDM_SUCCESS, means there are events pending on the span.
|
||||
* is it possible to know on which channels those events are pending, without traversing the span?
|
||||
* XXX */
|
||||
for (i = 1; i <= span->chan_count; i++) {
|
||||
r2chan = R2CALL(span->channels[i])->r2chan;
|
||||
r2call = R2CALL(ftdmchan);
|
||||
ftdmchan = openr2_chan_get_client_data(r2chan);
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Handling CAS on channel %d.\n", openr2_chan_get_number(r2chan));
|
||||
// we only expect CAS and other OOB events on this thread/loop, once a call is started
|
||||
// the MF events (in-band signaling) are handled in the call thread
|
||||
openr2_chan_process_cas_signaling(r2chan);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Ignoring event %d on channel %d.\n", event->enum_id, openr2_chan_get_number(r2chan));
|
||||
// XXX TODO: handle alarms here XXX
|
||||
status = ftdm_channel_read_event(ftdmchan, &event);
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
if (status == FTDM_SUCCESS) {
|
||||
switch (event->enum_id) {
|
||||
case FTDM_OOB_CAS_BITS_CHANGE:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Handling CAS on channel %d.\n", i);
|
||||
openr2_chan_process_cas_signaling(r2chan);
|
||||
}
|
||||
break;
|
||||
case FTDM_OOB_ALARM_TRAP:
|
||||
case FTDM_OOB_ALARM_CLEAR:
|
||||
{
|
||||
ftdm_log(FTDM_LOG_DEBUG, "OOB EVENT: %s\n", ftdm_signal_event2str(event->enum_id));
|
||||
openr2_chan_process_oob_events(r2chan);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX
|
||||
* when ftdm_span_poll_event() returns FTDM_SUCCESS, means there are events pending on the span.
|
||||
* is it possible to know on which channels those events are pending, without traversing the span?
|
||||
* XXX */
|
||||
for (i = 1; i <= span->chan_count; i++) {
|
||||
r2chan = R2CALL(span->channels[i])->r2chan;
|
||||
ftdmchan = openr2_chan_get_client_data(r2chan);
|
||||
r2call = R2CALL(ftdmchan);
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
ftdm_set_flag(r2call, FTDM_R2_PROCESSING);
|
||||
|
||||
if (ftdm_r2_state_advance(ftdmchan)) {
|
||||
ftdm_clear_flag(r2call, FTDM_R2_PROCESSING);
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* handle timeout events first if any */
|
||||
openr2_chan_run_schedule(r2chan);
|
||||
|
||||
/* process mf tones, if any */
|
||||
if (openr2_chan_get_read_enabled(r2chan)) {
|
||||
openr2_chan_process_mf_signaling(r2chan);
|
||||
}
|
||||
|
||||
if (ftdm_r2_state_advance(ftdmchan)) {
|
||||
ftdm_clear_flag(r2call, FTDM_R2_PROCESSING);
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
continue;
|
||||
}
|
||||
|
||||
ftdm_clear_flag(r2call, FTDM_R2_PROCESSING);
|
||||
if (!ftdm_r2_state_advance(ftdmchan)) {
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
}
|
||||
openr2_chan_process_signaling(r2chan);
|
||||
if (!ftdm_r2_state_advance(ftdmchan)) {
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
}
|
||||
} else if (status != FTDM_TIMEOUT) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "ftdm_span_poll_event returned %d.\n", status);
|
||||
}
|
||||
ftdm_span_trigger_signals(span);
|
||||
ftdm_sleep(20);
|
||||
}
|
||||
|
||||
for (i = 1; i <= span->chan_count; i++) {
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
* Moises Silva <moy@sangoma.com>
|
||||
* David Yat Sin <davidy@sangoma.com>
|
||||
* Nenad Corbic <ncorbic@sangoma.com>
|
||||
* Arnaldo Pereira <arnaldo@sangoma.com>
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -99,7 +100,8 @@ static struct {
|
|||
/* a bunch of this stuff should go into the wanpipe_tdm_api_iface.h */
|
||||
|
||||
FIO_SPAN_POLL_EVENT_FUNCTION(wanpipe_poll_event);
|
||||
FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event);
|
||||
FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event);
|
||||
FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event);
|
||||
|
||||
/**
|
||||
* \brief Poll for event on a wanpipe socket
|
||||
|
@ -1110,13 +1112,188 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves an event from a wanpipe channel
|
||||
* \param channel Channel to retrieve event from
|
||||
* \param event FreeTDM event to return
|
||||
* \return Success or failure
|
||||
*/
|
||||
FIO_CHANNEL_NEXT_EVENT_FUNCTION(wanpipe_channel_next_event)
|
||||
{
|
||||
ftdm_status_t status;
|
||||
ftdm_oob_event_t event_id;
|
||||
wanpipe_tdm_api_t tdm_api;
|
||||
ftdm_span_t *span = ftdmchan->span;
|
||||
|
||||
if (ftdmchan->last_event_time && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_EVENT)) {
|
||||
uint32_t diff = (uint32_t)(ftdm_current_time_in_ms() - ftdmchan->last_event_time);
|
||||
/* XX printf("%u %u %u\n", diff, (unsigned)ftdm_current_time_in_ms(), (unsigned)ftdmchan->last_event_time); */
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_WINK)) {
|
||||
if (diff > wp_globals.wink_ms) {
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_WINK);
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_FLASH);
|
||||
ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_OFFHOOK);
|
||||
event_id = FTDM_OOB_OFFHOOK;
|
||||
goto event;
|
||||
}
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_FLASH)) {
|
||||
if (diff > wp_globals.flash_ms) {
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_FLASH);
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_WINK);
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_OFFHOOK);
|
||||
event_id = FTDM_OOB_ONHOOK;
|
||||
|
||||
if (ftdmchan->type == FTDM_CHAN_TYPE_FXO) {
|
||||
wanpipe_tdm_api_t tdm_api;
|
||||
memset(&tdm_api, 0, sizeof(tdm_api));
|
||||
|
||||
sangoma_tdm_txsig_onhook(ftdmchan->sockfd,&tdm_api);
|
||||
}
|
||||
goto event;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_EVENT))
|
||||
return FTDM_FAIL;
|
||||
|
||||
memset(&tdm_api, 0, sizeof(tdm_api));
|
||||
status = sangoma_tdm_read_event(ftdmchan->sockfd, &tdm_api);
|
||||
if (status != FTDM_SUCCESS) {
|
||||
snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno));
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to read event from channel: %s\n", strerror(errno));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "read wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
|
||||
switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type) {
|
||||
|
||||
case WP_TDMAPI_EVENT_LINK_STATUS:
|
||||
{
|
||||
switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_link_status) {
|
||||
case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
|
||||
event_id = FTDM_OOB_ALARM_CLEAR;
|
||||
break;
|
||||
default:
|
||||
event_id = FTDM_OOB_ALARM_TRAP;
|
||||
break;
|
||||
};
|
||||
}
|
||||
break;
|
||||
|
||||
case WP_TDMAPI_EVENT_RXHOOK:
|
||||
{
|
||||
if (ftdmchan->type == FTDM_CHAN_TYPE_FXS) {
|
||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_OFFHOOK : FTDM_OOB_ONHOOK;
|
||||
if (event_id == FTDM_OOB_OFFHOOK) {
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_FLASH)) {
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_FLASH);
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_WINK);
|
||||
event_id = FTDM_OOB_FLASH;
|
||||
goto event;
|
||||
} else {
|
||||
ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_WINK);
|
||||
}
|
||||
} else {
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_WINK)) {
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_WINK);
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_FLASH);
|
||||
event_id = FTDM_OOB_WINK;
|
||||
goto event;
|
||||
} else {
|
||||
ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_FLASH);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
wanpipe_tdm_api_t onhook_tdm_api;
|
||||
memset(&onhook_tdm_api, 0, sizeof(onhook_tdm_api));
|
||||
status = sangoma_tdm_txsig_onhook(ftdmchan->sockfd, &onhook_tdm_api);
|
||||
if (status) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "ONHOOK Failed");
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
event_id = onhook_tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? FTDM_OOB_ONHOOK : FTDM_OOB_NOOP;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WP_TDMAPI_EVENT_RING_DETECT:
|
||||
{
|
||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_RING_START : FTDM_OOB_RING_STOP;
|
||||
}
|
||||
break;
|
||||
/*
|
||||
disabled this ones when configuring, we don't need them, do we?
|
||||
case WP_TDMAPI_EVENT_RING_TRIP_DETECT:
|
||||
{
|
||||
event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? FTDM_OOB_ONHOOK : FTDM_OOB_OFFHOOK;
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case WP_TDMAPI_EVENT_RBS:
|
||||
{
|
||||
event_id = FTDM_OOB_CAS_BITS_CHANGE;
|
||||
ftdmchan->rx_cas_bits = wanpipe_swap_bits(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_rbs_bits);
|
||||
}
|
||||
break;
|
||||
case WP_TDMAPI_EVENT_DTMF:
|
||||
{
|
||||
char tmp_dtmf[2] = { tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_digit, 0 };
|
||||
event_id = FTDM_OOB_NOOP;
|
||||
|
||||
if (tmp_dtmf[0] == 'f') {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Ignoring wanpipe DTMF: %c, fax tones will be passed through!\n", tmp_dtmf[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_PRESENT) {
|
||||
ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_MUTE);
|
||||
}
|
||||
|
||||
if (tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_dtmf_type == WAN_EC_TONE_STOP) {
|
||||
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_MUTE);
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Queuing wanpipe DTMF: %c\n", tmp_dtmf[0]);
|
||||
ftdm_channel_queue_dtmf(ftdmchan, tmp_dtmf);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WP_TDMAPI_EVENT_ALARM:
|
||||
{
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Got wanpipe alarms %d\n", tdm_api.wp_tdm_cmd.event.wp_api_event_alarm);
|
||||
event_id = FTDM_OOB_ALARM_TRAP;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unhandled wanpipe event %d\n", tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type);
|
||||
event_id = FTDM_OOB_INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
event:
|
||||
|
||||
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_EVENT);
|
||||
|
||||
ftdmchan->last_event_time = 0;
|
||||
span->event_header.e_type = FTDM_EVENT_OOB;
|
||||
span->event_header.enum_id = event_id;
|
||||
span->event_header.channel = ftdmchan;
|
||||
*event = &span->event_header;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves an event from a wanpipe span
|
||||
* \param span Span to retrieve event from
|
||||
* \param event FreeTDM event to return
|
||||
* \return Success or failure
|
||||
*/
|
||||
FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event)
|
||||
FIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_span_next_event)
|
||||
{
|
||||
uint32_t i,err;
|
||||
ftdm_oob_event_t event_id;
|
||||
|
@ -1348,7 +1525,8 @@ static FIO_IO_LOAD_FUNCTION(wanpipe_init)
|
|||
wanpipe_interface.read = wanpipe_read;
|
||||
wanpipe_interface.write = wanpipe_write;
|
||||
wanpipe_interface.poll_event = wanpipe_poll_event;
|
||||
wanpipe_interface.next_event = wanpipe_next_event;
|
||||
wanpipe_interface.next_event = wanpipe_span_next_event;
|
||||
wanpipe_interface.channel_next_event = wanpipe_channel_next_event;
|
||||
wanpipe_interface.channel_destroy = wanpipe_channel_destroy;
|
||||
wanpipe_interface.get_alarms = wanpipe_get_alarms;
|
||||
*fio = &wanpipe_interface;
|
||||
|
|
|
@ -467,6 +467,7 @@ struct ftdm_memory_handler {
|
|||
#define FIO_SPAN_GET_SIG_STATUS_ARGS (ftdm_span_t *span, ftdm_signaling_status_t *status)
|
||||
#define FIO_SPAN_POLL_EVENT_ARGS (ftdm_span_t *span, uint32_t ms, short *poll_events)
|
||||
#define FIO_SPAN_NEXT_EVENT_ARGS (ftdm_span_t *span, ftdm_event_t **event)
|
||||
#define FIO_CHANNEL_NEXT_EVENT_ARGS (ftdm_channel_t *ftdmchan, ftdm_event_t **event)
|
||||
#define FIO_SIGNAL_CB_ARGS (ftdm_sigmsg_t *sigmsg)
|
||||
#define FIO_EVENT_CB_ARGS (ftdm_channel_t *ftdmchan, ftdm_event_t *event)
|
||||
#define FIO_CONFIGURE_SPAN_ARGS (ftdm_span_t *span, const char *str, ftdm_chan_type_t type, char *name, char *number)
|
||||
|
@ -498,6 +499,7 @@ typedef ftdm_status_t (*fio_span_set_sig_status_t) FIO_SPAN_SET_SIG_STATUS_ARGS;
|
|||
typedef ftdm_status_t (*fio_span_get_sig_status_t) FIO_SPAN_GET_SIG_STATUS_ARGS;
|
||||
typedef ftdm_status_t (*fio_span_poll_event_t) FIO_SPAN_POLL_EVENT_ARGS ;
|
||||
typedef ftdm_status_t (*fio_span_next_event_t) FIO_SPAN_NEXT_EVENT_ARGS ;
|
||||
typedef ftdm_status_t (*fio_channel_next_event_t) FIO_CHANNEL_NEXT_EVENT_ARGS ;
|
||||
typedef ftdm_status_t (*fio_signal_cb_t) FIO_SIGNAL_CB_ARGS ;
|
||||
typedef ftdm_status_t (*fio_event_cb_t) FIO_EVENT_CB_ARGS ;
|
||||
typedef ftdm_status_t (*fio_configure_span_t) FIO_CONFIGURE_SPAN_ARGS ;
|
||||
|
@ -530,6 +532,7 @@ typedef ftdm_status_t (*fio_api_t) FIO_API_ARGS ;
|
|||
#define FIO_SPAN_GET_SIG_STATUS_FUNCTION(name) ftdm_status_t name FIO_SPAN_GET_SIG_STATUS_ARGS
|
||||
#define FIO_SPAN_POLL_EVENT_FUNCTION(name) ftdm_status_t name FIO_SPAN_POLL_EVENT_ARGS
|
||||
#define FIO_SPAN_NEXT_EVENT_FUNCTION(name) ftdm_status_t name FIO_SPAN_NEXT_EVENT_ARGS
|
||||
#define FIO_CHANNEL_NEXT_EVENT_FUNCTION(name) ftdm_status_t name FIO_CHANNEL_NEXT_EVENT_ARGS
|
||||
#define FIO_SIGNAL_CB_FUNCTION(name) ftdm_status_t name FIO_SIGNAL_CB_ARGS
|
||||
#define FIO_EVENT_CB_FUNCTION(name) ftdm_status_t name FIO_EVENT_CB_ARGS
|
||||
#define FIO_CONFIGURE_SPAN_FUNCTION(name) ftdm_status_t name FIO_CONFIGURE_SPAN_ARGS
|
||||
|
@ -568,6 +571,7 @@ struct ftdm_io_interface {
|
|||
fio_write_t write; /*!< Write data to the channel */
|
||||
fio_span_poll_event_t poll_event; /*!< Poll for events on the whole span */
|
||||
fio_span_next_event_t next_event; /*!< Retrieve an event from the span */
|
||||
fio_channel_next_event_t channel_next_event; /*!< Retrieve an event from channel */
|
||||
fio_api_t api; /*!< Execute a text command */
|
||||
};
|
||||
|
||||
|
|
|
@ -615,6 +615,23 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan);
|
|||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_next_event(ftdm_span_t *span, ftdm_event_t **event);
|
||||
|
||||
/*!
|
||||
* \brief Retrieves an event from the span
|
||||
*
|
||||
* \note
|
||||
* This function is non-reentrant and not thread-safe.
|
||||
* The event returned may be modified if the function is called again
|
||||
* from a different thread or even the same. It is recommended to
|
||||
* handle events from the same span in a single thread.
|
||||
*
|
||||
* \param span The channel to retrieve the event from
|
||||
* \param event Pointer to store the pointer to the event
|
||||
*
|
||||
* \retval FTDM_SUCCESS success (at least one event available)
|
||||
* \retval FTDM_FAIL failure
|
||||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_read_event(ftdm_channel_t *ftdmchan, ftdm_event_t **event);
|
||||
|
||||
/*!
|
||||
* \brief Enqueue a DTMF string into the channel
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue