Merge branch 'arnaldo.ftdm_channel_read_event'

This commit is contained in:
Arnaldo Pereira 2010-12-02 20:53:18 -02:00
commit cf7d91a769
6 changed files with 653 additions and 358 deletions

View File

@ -64,6 +64,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_sangoma_isdn", "src\f
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_r2", "src\ftmod\ftmod_r2\ftmod_r2.2008.vcproj", "{08C3EA27-A51D-47F8-B47D-B189C649CF30}"
ProjectSection(ProjectDependencies) = postProject
{93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -131,7 +134,6 @@ Global
{1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Release|Win32.ActiveCfg = Release|Win32
{1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Release|x64.ActiveCfg = Release|x64
{D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|Win32.ActiveCfg = Debug|Win32
{D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|Win32.Build.0 = Debug|Win32
{D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|x64.ActiveCfg = Debug|x64
{D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|x64.Build.0 = Debug|x64
{D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|Win32.ActiveCfg = Release|Win32
@ -139,7 +141,6 @@ Global
{D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|x64.ActiveCfg = Release|x64
{D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|x64.Build.0 = Release|x64
{2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|Win32.ActiveCfg = Debug|Win32
{2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|Win32.Build.0 = Debug|Win32
{2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|x64.ActiveCfg = Debug|x64
{2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|x64.Build.0 = Debug|x64
{2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|Win32.ActiveCfg = Release|Win32
@ -147,7 +148,6 @@ Global
{2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|x64.ActiveCfg = Release|x64
{2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|x64.Build.0 = Release|x64
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|Win32.ActiveCfg = Debug|Win32
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|Win32.Build.0 = Debug|Win32
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|x64.ActiveCfg = Debug|x64
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|x64.Build.0 = Debug|x64
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|Win32.ActiveCfg = Release|Win32
@ -155,13 +155,11 @@ Global
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.ActiveCfg = Release|x64
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.Build.0 = Release|x64
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.ActiveCfg = Debug|Win32
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.Build.0 = Debug|Win32
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|x64.ActiveCfg = Debug|Win32
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.ActiveCfg = Release|Win32
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.Build.0 = Release|Win32
{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|x64.ActiveCfg = Release|Win32
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.ActiveCfg = Debug|Win32
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.Build.0 = Debug|Win32
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|x64.ActiveCfg = Debug|Win32
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|Win32.ActiveCfg = Release|Win32
{08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|Win32.Build.0 = Release|Win32

View File

@ -3238,29 +3238,6 @@ static switch_status_t load_config(void)
char *name = (char *) switch_xml_attr(myspan, "name");
ftdm_status_t zstatus = FTDM_FAIL;
/* strings */
const char *variant = "itu";
const char *category = "national_subscriber";
const char *logdir = "/usr/local/freeswitch/log/"; /* FIXME: get PREFIX variable */
const char *logging = "notice,warning,error";
const char *advanced_protocol_file = "";
/* booleans */
int call_files = 0;
int get_ani_first = -1;
int immediate_accept = -1;
int double_answer = -1;
int skip_category = -1;
int forced_release = -1;
int charge_calls = -1;
/* integers */
int mfback_timeout = -1;
int metering_pulse_timeout = -1;
int allow_collect_calls = -1;
int max_ani = 10;
int max_dnis = 4;
/* common non r2 stuff */
const char *context = "default";
const char *dialplan = "XML";
@ -3269,53 +3246,16 @@ static switch_status_t load_config(void)
uint32_t span_id = 0;
ftdm_span_t *span = NULL;
ftdm_conf_parameter_t spanparameters[30];
unsigned paramindex = 0;
memset(spanparameters, 0, sizeof(spanparameters));
for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
/* string parameters */
if (!strcasecmp(var, "variant")) {
variant = val;
} else if (!strcasecmp(var, "category")) {
category = val;
} else if (!strcasecmp(var, "logdir")) {
logdir = val;
} else if (!strcasecmp(var, "logging")) {
logging = val;
} else if (!strcasecmp(var, "advanced_protocol_file")) {
advanced_protocol_file = val;
/* booleans */
} else if (!strcasecmp(var, "allow_collect_calls")) {
allow_collect_calls = switch_true(val);
} else if (!strcasecmp(var, "immediate_accept")) {
immediate_accept = switch_true(val);
} else if (!strcasecmp(var, "double_answer")) {
double_answer = switch_true(val);
} else if (!strcasecmp(var, "skip_category")) {
skip_category = switch_true(var);
} else if (!strcasecmp(var, "forced_release")) {
forced_release = switch_true(val);
} else if (!strcasecmp(var, "charge_calls")) {
charge_calls = switch_true(val);
} else if (!strcasecmp(var, "get_ani_first")) {
get_ani_first = switch_true(val);
} else if (!strcasecmp(var, "call_files")) {
call_files = switch_true(val);
/* integers */
} else if (!strcasecmp(var, "mfback_timeout")) {
mfback_timeout = atoi(val);
} else if (!strcasecmp(var, "metering_pulse_timeout")) {
metering_pulse_timeout = atoi(val);
} else if (!strcasecmp(var, "max_ani")) {
max_ani = atoi(val);
} else if (!strcasecmp(var, "max_dnis")) {
max_dnis = atoi(val);
/* common non r2 stuff */
} else if (!strcasecmp(var, "context")) {
if (!strcasecmp(var, "context")) {
context = val;
} else if (!strcasecmp(var, "dialplan")) {
dialplan = val;
@ -3323,11 +3263,15 @@ static switch_status_t load_config(void)
dial_regex = val;
} else if (!strcasecmp(var, "fail-dial-regex")) {
fail_dial_regex = val;
} else {
spanparameters[paramindex].var = var;
spanparameters[paramindex].val = val;
paramindex++;
}
}
if (!id && !name) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "span missing required param 'id'\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "either 'id' or 'name' required params are missing\n");
continue;
}
@ -3353,25 +3297,7 @@ static switch_status_t load_config(void)
span_id = ftdm_span_get_id(span);
}
if (ftdm_configure_span(span, "r2", on_r2_signal,
"variant", variant,
"max_ani", max_ani,
"max_dnis", max_dnis,
"category", category,
"logdir", logdir,
"logging", logging,
"advanced_protocol_file", advanced_protocol_file,
"allow_collect_calls", allow_collect_calls,
"immediate_accept", immediate_accept,
"double_answer", double_answer,
"skip_category", skip_category,
"forced_release", forced_release,
"charge_calls", charge_calls,
"get_ani_first", get_ani_first,
"call_files", call_files,
"mfback_timeout", mfback_timeout,
"metering_pulse_timeout", metering_pulse_timeout,
FTDM_TAG_END) != FTDM_SUCCESS) {
if (ftdm_configure_span_signaling(span, "r2", on_r2_signal, spanparameters) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Error configuring R2 FreeTDM span %d, error: %s\n",
span_id, ftdm_span_get_last_error(span));
continue;

View File

@ -1004,6 +1004,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;

File diff suppressed because it is too large Load Diff

View File

@ -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
@ -794,7 +796,7 @@ static void wanpipe_write_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_tx_hdr_t *t
/* we don't test for 80% full in tx since is typically full for voice channels, should we test tx 80% full for D-channels? */
if (ftdmchan->iostats.tx.queue_len >= ftdmchan->iostats.tx.queue_size) {
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Tx Queue Full (%d/%d)\n",
ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.tx.queue_size);
ftdmchan->iostats.tx.queue_len, ftdmchan->iostats.tx.queue_size);
ftdm_set_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
} else if (ftdm_test_flag(&(ftdmchan->iostats.tx), FTDM_IOSTATS_ERROR_QUEUE_FULL)){
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Tx Queue no longer full (%d/%d)\n",
@ -861,7 +863,6 @@ static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx
ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
ftdm_set_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
} else if (ftdm_test_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES)){
/* any reason we have wanpipe_tdm_api_iface.h in ftmod_wanpipe/ dir? */
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Rx Queue length reduced 80% threshold (%d/%d)\n",
ftdmchan->iostats.rx.queue_len, ftdmchan->iostats.rx.queue_size);
ftdm_clear_flag(&(ftdmchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
@ -1181,13 +1182,155 @@ 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 (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_EVENT))
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_EVENT);
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:
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;
@ -1419,7 +1562,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;

View File

@ -483,6 +483,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)
@ -514,6 +515,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 ;
@ -546,6 +548,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
@ -584,6 +587,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 */
};
@ -902,6 +906,23 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_add_to_group(const char* name, ftdm_chann
/*! \brief Remove the channel from a hunt group */
FT_DECLARE(ftdm_status_t) ftdm_channel_remove_from_group(ftdm_group_t* group, ftdm_channel_t* ftdmchan);
/*!
* \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 ftdmchan 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 Find a hunt group by id */
FT_DECLARE(ftdm_status_t) ftdm_group_find(uint32_t id, ftdm_group_t **group);