#include "ftdm_cpu_monitor.h"
#define SPAN_PENDING_CHANS_QUEUE_SIZE 1000
+#define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000
#define FTDM_READ_TRACE_INDEX 0
#define FTDM_WRITE_TRACE_INDEX 1
if (span->pendingchans) {
ftdm_queue_destroy(&span->pendingchans);
}
+ if (span->pendingsignals) {
+ ftdm_queue_destroy(&span->pendingsignals);
+ }
ftdm_mutex_unlock(span->mutex);
ftdm_mutex_destroy(&span->mutex);
ftdm_safe_free(span->signal_data);
if (ftdm_test_flag(span, FTDM_SPAN_USE_CHAN_QUEUE)) {
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;
}
-FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
+static ftdm_status_t ftdm_span_trigger_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
{
- ftdm_status_t status = FTDM_FAIL;
+ 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)
+{
if (sigmsg->channel) {
ftdm_mutex_lock(sigmsg->channel->mutex);
}
break;
}
-
- /* call the user callback only if set */
- if (span->signal_cb) {
- status = span->signal_cb(sigmsg);
+
+ /* if the signaling module uses a queue for signaling notifications, then enqueue it */
+ if (ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) {
+ ftdm_span_queue_signal(span, sigmsg);
+ } else {
+ ftdm_span_trigger_signal(span, sigmsg);
}
done:
ftdm_mutex_unlock(sigmsg->channel->mutex);
}
- return status;
+ return FTDM_SUCCESS;
}
static void *ftdm_cpu_monitor_run(ftdm_thread_t *me, void *obj)
float txgain;
} 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 Move from string to ftdm_signaling_status_t and viceversa */
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 */
typedef enum {
FTDM_NO_FLAGS = 0,
FTDM_SPAN_USE_CHAN_QUEUE = (1 << 6),
FTDM_SPAN_SUGGEST_CHAN_ID = (1 << 7),
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;
/*! \brief Channel supported features */