freetdm: add asynchronous signal notification
This commit is contained in:
parent
f7669283a6
commit
3a35139a32
|
@ -51,6 +51,7 @@
|
||||||
#include "ftdm_cpu_monitor.h"
|
#include "ftdm_cpu_monitor.h"
|
||||||
|
|
||||||
#define SPAN_PENDING_CHANS_QUEUE_SIZE 1000
|
#define SPAN_PENDING_CHANS_QUEUE_SIZE 1000
|
||||||
|
#define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000
|
||||||
#define FTDM_READ_TRACE_INDEX 0
|
#define FTDM_READ_TRACE_INDEX 0
|
||||||
#define FTDM_WRITE_TRACE_INDEX 1
|
#define FTDM_WRITE_TRACE_INDEX 1
|
||||||
|
|
||||||
|
@ -463,6 +464,9 @@ static ftdm_status_t ftdm_span_destroy(ftdm_span_t *span)
|
||||||
if (span->pendingchans) {
|
if (span->pendingchans) {
|
||||||
ftdm_queue_destroy(&span->pendingchans);
|
ftdm_queue_destroy(&span->pendingchans);
|
||||||
}
|
}
|
||||||
|
if (span->pendingsignals) {
|
||||||
|
ftdm_queue_destroy(&span->pendingsignals);
|
||||||
|
}
|
||||||
ftdm_mutex_unlock(span->mutex);
|
ftdm_mutex_unlock(span->mutex);
|
||||||
ftdm_mutex_destroy(&span->mutex);
|
ftdm_mutex_destroy(&span->mutex);
|
||||||
ftdm_safe_free(span->signal_data);
|
ftdm_safe_free(span->signal_data);
|
||||||
|
@ -4097,6 +4101,9 @@ static ftdm_status_t post_configure_span_channels(ftdm_span_t *span)
|
||||||
if (ftdm_test_flag(span, FTDM_SPAN_USE_CHAN_QUEUE)) {
|
if (ftdm_test_flag(span, FTDM_SPAN_USE_CHAN_QUEUE)) {
|
||||||
status = ftdm_queue_create(&span->pendingchans, SPAN_PENDING_CHANS_QUEUE_SIZE);
|
status = ftdm_queue_create(&span->pendingchans, SPAN_PENDING_CHANS_QUEUE_SIZE);
|
||||||
}
|
}
|
||||||
|
if (status == FTDM_SUCCESS && ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) {
|
||||||
|
status = ftdm_queue_create(&span->pendingsignals, SPAN_PENDING_SIGNALS_QUEUE_SIZE);
|
||||||
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4362,10 +4369,39 @@ FT_DECLARE(ftdm_status_t) ftdm_group_create(ftdm_group_t **group, const char *na
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ftdm_status_t ftdm_span_trigger_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
||||||
|
{
|
||||||
|
return span->signal_cb(sigmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ftdm_status_t ftdm_span_queue_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
||||||
|
{
|
||||||
|
ftdm_sigmsg_t *new_sigmsg = NULL;
|
||||||
|
|
||||||
|
ftdm_assert_return((sigmsg->raw_data == NULL), FTDM_FAIL, "No raw data should be used with asynchronous notification\n");
|
||||||
|
|
||||||
|
new_sigmsg = ftdm_calloc(1, sizeof(*sigmsg));
|
||||||
|
if (!new_sigmsg) {
|
||||||
|
return FTDM_FAIL;
|
||||||
|
}
|
||||||
|
memcpy(new_sigmsg, sigmsg, sizeof(*sigmsg));
|
||||||
|
|
||||||
|
ftdm_queue_enqueue(span->pendingsignals, new_sigmsg);
|
||||||
|
return FTDM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
FT_DECLARE(ftdm_status_t) ftdm_span_trigger_signals(const ftdm_span_t *span)
|
||||||
|
{
|
||||||
|
ftdm_sigmsg_t *sigmsg = NULL;
|
||||||
|
while ((sigmsg = ftdm_queue_dequeue(span->pendingsignals))) {
|
||||||
|
ftdm_span_trigger_signal(span, sigmsg);
|
||||||
|
ftdm_safe_free(sigmsg);
|
||||||
|
}
|
||||||
|
return FTDM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
||||||
{
|
{
|
||||||
ftdm_status_t status = FTDM_FAIL;
|
|
||||||
|
|
||||||
if (sigmsg->channel) {
|
if (sigmsg->channel) {
|
||||||
ftdm_mutex_lock(sigmsg->channel->mutex);
|
ftdm_mutex_lock(sigmsg->channel->mutex);
|
||||||
}
|
}
|
||||||
|
@ -4400,10 +4436,12 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* call the user callback only if set */
|
/* if the signaling module uses a queue for signaling notifications, then enqueue it */
|
||||||
if (span->signal_cb) {
|
if (ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) {
|
||||||
status = span->signal_cb(sigmsg);
|
ftdm_span_queue_signal(span, sigmsg);
|
||||||
|
} else {
|
||||||
|
ftdm_span_trigger_signal(span, sigmsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -4411,7 +4449,7 @@ done:
|
||||||
ftdm_mutex_unlock(sigmsg->channel->mutex);
|
ftdm_mutex_unlock(sigmsg->channel->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return FTDM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *ftdm_cpu_monitor_run(ftdm_thread_t *me, void *obj)
|
static void *ftdm_cpu_monitor_run(ftdm_thread_t *me, void *obj)
|
||||||
|
|
|
@ -317,23 +317,6 @@ typedef struct ftdm_channel_config {
|
||||||
float txgain;
|
float txgain;
|
||||||
} ftdm_channel_config_t;
|
} ftdm_channel_config_t;
|
||||||
|
|
||||||
/*! \brief Generic signaling message */
|
|
||||||
struct ftdm_sigmsg {
|
|
||||||
ftdm_signal_event_t event_id; /*!< The type of message */
|
|
||||||
ftdm_channel_t *channel; /*!< Related channel */
|
|
||||||
uint32_t chan_id; /*!< easy access to chan id */
|
|
||||||
uint32_t span_id; /*!< easy access to span_id */
|
|
||||||
void *raw_data; /*!< Message specific data if any */
|
|
||||||
uint32_t raw_data_len; /*!< Data len in case is needed */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! \brief Crash policy
|
|
||||||
* Useful for debugging only, default policy is never, if you wish to crash on asserts then use ftdm_global_set_crash_policy */
|
|
||||||
typedef enum {
|
|
||||||
FTDM_CRASH_NEVER = 0,
|
|
||||||
FTDM_CRASH_ON_ASSERT
|
|
||||||
} ftdm_crash_policy_t;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Signaling status on a given span or specific channel on protocols that support it
|
\brief Signaling status on a given span or specific channel on protocols that support it
|
||||||
*/
|
*/
|
||||||
|
@ -352,6 +335,24 @@ typedef enum {
|
||||||
/*! \brief Move from string to ftdm_signaling_status_t and viceversa */
|
/*! \brief Move from string to ftdm_signaling_status_t and viceversa */
|
||||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_signaling_status, ftdm_signaling_status2str, ftdm_signaling_status_t)
|
FTDM_STR2ENUM_P(ftdm_str2ftdm_signaling_status, ftdm_signaling_status2str, ftdm_signaling_status_t)
|
||||||
|
|
||||||
|
/*! \brief Generic signaling message */
|
||||||
|
struct ftdm_sigmsg {
|
||||||
|
ftdm_signal_event_t event_id; /*!< The type of message */
|
||||||
|
ftdm_channel_t *channel; /*!< Related channel */
|
||||||
|
uint32_t chan_id; /*!< easy access to chan id */
|
||||||
|
uint32_t span_id; /*!< easy access to span_id */
|
||||||
|
ftdm_signaling_status_t sigstatus; /*!< Signaling status (valid if event_id is FTDM_SIGEVENT_SIGSTATUS_CHANGED) */
|
||||||
|
void *raw_data; /*!< Message specific data if any */
|
||||||
|
uint32_t raw_data_len; /*!< Data len in case is needed */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*! \brief Crash policy
|
||||||
|
* Useful for debugging only, default policy is never, if you wish to crash on asserts then use ftdm_global_set_crash_policy */
|
||||||
|
typedef enum {
|
||||||
|
FTDM_CRASH_NEVER = 0,
|
||||||
|
FTDM_CRASH_ON_ASSERT
|
||||||
|
} ftdm_crash_policy_t;
|
||||||
|
|
||||||
/*! \brief I/O waiting flags */
|
/*! \brief I/O waiting flags */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FTDM_NO_FLAGS = 0,
|
FTDM_NO_FLAGS = 0,
|
||||||
|
|
|
@ -466,6 +466,7 @@ struct ftdm_span {
|
||||||
ftdm_state_map_t *state_map;
|
ftdm_state_map_t *state_map;
|
||||||
ftdm_caller_data_t default_caller_data;
|
ftdm_caller_data_t default_caller_data;
|
||||||
ftdm_queue_t *pendingchans;
|
ftdm_queue_t *pendingchans;
|
||||||
|
ftdm_queue_t *pendingsignals;
|
||||||
struct ftdm_span *next;
|
struct ftdm_span *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -579,6 +580,8 @@ FT_DECLARE(ftdm_status_t) ftdm_span_next_event(ftdm_span_t *span, ftdm_event_t *
|
||||||
*/
|
*/
|
||||||
FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, const char *dtmf);
|
FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, const char *dtmf);
|
||||||
|
|
||||||
|
/* dequeue pending signals and notify the user via the span signal callback */
|
||||||
|
FT_DECLARE(ftdm_status_t) ftdm_span_trigger_signals(const ftdm_span_t *span);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Assert condition
|
\brief Assert condition
|
||||||
|
|
|
@ -176,6 +176,10 @@ typedef enum {
|
||||||
FTDM_SPAN_USE_CHAN_QUEUE = (1 << 6),
|
FTDM_SPAN_USE_CHAN_QUEUE = (1 << 6),
|
||||||
FTDM_SPAN_SUGGEST_CHAN_ID = (1 << 7),
|
FTDM_SPAN_SUGGEST_CHAN_ID = (1 << 7),
|
||||||
FTDM_SPAN_USE_AV_RATE = (1 << 8),
|
FTDM_SPAN_USE_AV_RATE = (1 << 8),
|
||||||
|
/* If you use this flag, you MUST call ftdm_span_trigger_signals to deliver the user signals
|
||||||
|
* after having called ftdm_send_span_signal(), which with this flag it will just enqueue the signal
|
||||||
|
* for later delivery */
|
||||||
|
FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 9),
|
||||||
} ftdm_span_flag_t;
|
} ftdm_span_flag_t;
|
||||||
|
|
||||||
/*! \brief Channel supported features */
|
/*! \brief Channel supported features */
|
||||||
|
|
Loading…
Reference in New Issue