UNREFERENCED_PARAMETER(func);
UNREFERENCED_PARAMETER(line);
#endif
- ftdm_call_set_call_id(&ftdmchan->caller_data);
- ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 100);
- ftdm_channel_unlock(ftdmchan);
-
return status;
}
FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span)
{
- if (span->start) {
- /* check the alarms again before starting the signaling module
- this works-around some I/O modules (netborder I/O module) that cannot
- check the alarm status before during configuration because the spans are
- not really started yet at the I/O level */
- if (ftdm_set_channels_alarms(span, 0) != FTDM_SUCCESS) {
- ftdm_log(FTDM_LOG_ERROR, "%d: Failed to set channel alarms\n", span->span_id);
- return FTDM_FAIL;
- }
- return span->start(span);
+ ftdm_status_t status = FTDM_FAIL;
+
+ ftdm_mutex_lock(span->mutex);
+
+ if (ftdm_test_flag(span, FTDM_SPAN_STARTED)) {
+ status = FTDM_EINVAL;
+ goto done;
}
- return FTDM_FAIL;
+
+ if (!span->start) {
+ status = FTDM_ENOSYS;
+ goto done;
+ }
+
++ /* check the alarms again before starting the signaling module
++ this works-around some I/O modules (netborder I/O module) that cannot
++ check the alarm status before during configuration because the spans are
++ not really started yet at the I/O level */
++ if (ftdm_set_channels_alarms(span, 0) != FTDM_SUCCESS) {
++ ftdm_log(FTDM_LOG_ERROR, "Failed to set channel alarms in span %s\n", span->name);
++ status = FTDM_FAIL;
++ goto done;
++ }
++
+ status = span->start(span);
+ if (status == FTDM_SUCCESS) {
+ ftdm_set_flag_locked(span, FTDM_SPAN_STARTED);
+ }
+
+ done:
+ ftdm_mutex_unlock(span->mutex);
+ return status;
}
FT_DECLARE(ftdm_status_t) ftdm_channel_add_to_group(const char* name, ftdm_channel_t* ftdmchan)
memset(&sigev, 0, sizeof(sigev));
- sigev.span_id = signal_data->ftdm_span->span_id;
- sigev.chan_id = signal_data->dchan->chan_id;
- sigev.channel = signal_data->dchan;
- sigev.event_id = FTDM_SIGEVENT_TRACE_RAW;
-
- sigev.ev_data.logevent.dir = dir;
- sigev.ev_data.logevent.level = 3;
-
- /* TODO: Map trace to call ID here */
+ /* Note: Mapped raw trace assume only exclusive b-channel selection is used. i.e the b-channel selected on outgoing SETUP is always used for the call */
- raw_data = ftdm_malloc(data_len);
- ftdm_assert(raw_data, "Failed to malloc");
-
- memcpy(raw_data, data, data_len);
- sigev.raw.data = raw_data;
- sigev.raw.len = data_len;
- sigev.raw.autofree = 1;
- ftdm_span_send_signal(signal_data->ftdm_span, &sigev);
+ if (sngisdn_get_frame_info(data, data_len, dir, &frame_info) == FTDM_SUCCESS) {
+ if (sngisdn_map_call(signal_data, frame_info, &ftdmchan) == FTDM_SUCCESS) {
+ sigev.call_id = ftdmchan->caller_data.call_id;
+ sigev.span_id = ftdmchan->physical_span_id;
+ sigev.chan_id = ftdmchan->physical_chan_id;
+ sigev.channel = ftdmchan;
+ }
+ sigev.event_id = FTDM_SIGEVENT_TRACE_RAW;
+
+ sigev.ev_data.trace.dir = dir;
+ sigev.ev_data.trace.type = FTDM_TRACE_TYPE_Q931;
+
+ raw_data = ftdm_malloc(data_len);
+ ftdm_assert(raw_data, "Failed to malloc");
+
+ memcpy(raw_data, data, data_len);
- sigev.raw_data = raw_data;
- sigev.raw_data_len = data_len;
++ sigev.raw.data = raw_data;
++ sigev.raw.len = data_len;
++ sigev.raw.autofree = 1;
+ ftdm_span_send_signal(signal_data->ftdm_span, &sigev);
+ }
}
void sngisdn_decode_q931(char* str, uint8_t* data, uint32_t data_len)
typedef struct {
/* Direction - incoming or outgoing */
ftdm_trace_dir_t dir;
- uint8_t level; /* 1 for phy layer, 2 for q921/mtp2, 3 for q931/mtp3 */
+ ftdm_trace_type_t type;
} ftdm_event_trace_t;
+ typedef struct {
+ /* Digits collected */
+ char digits[FTDM_DIGITS_LIMIT];
+ } ftdm_event_collected_t;
+
+ /*! \brief FreeTDM supported indications.
+ * This is used during incoming calls when you want to request the signaling stack
+ * to notify about indications occurring locally. See ftdm_channel_call_indicate for more info */
+ typedef enum {
+ FTDM_CHANNEL_INDICATE_NONE,
+ FTDM_CHANNEL_INDICATE_RINGING,
+ FTDM_CHANNEL_INDICATE_PROCEED,
+ FTDM_CHANNEL_INDICATE_PROGRESS,
+ FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA,
+ FTDM_CHANNEL_INDICATE_BUSY,
+ /* Using this indication is equivalent to call ftdm_channel_call_answer API */
+ FTDM_CHANNEL_INDICATE_ANSWER,
+ FTDM_CHANNEL_INDICATE_INVALID,
+ } ftdm_channel_indication_t;
+ #define INDICATION_STRINGS "NONE", "RINGING", "PROCEED", "PROGRESS", "PROGRESS_MEDIA", "BUSY", "ANSWER", "INVALID"
+
+ /*! \brief Move from string to ftdm_channel_indication_t and viceversa */
+ FTDM_STR2ENUM_P(ftdm_str2channel_indication, ftdm_channel_indication2str, ftdm_channel_indication_t)
+
+ typedef struct {
+ /* The indication that was completed */
+ ftdm_channel_indication_t indication;
+ /* Completion status of the indication */
+ ftdm_status_t status;
+ } ftdm_event_indication_completed_t;
+
/*! \brief Generic signaling message */
struct ftdm_sigmsg {
ftdm_signal_event_t event_id; /*!< The type of message */
uint32_t call_id; /*!< unique call id for this call */
union {
ftdm_event_sigstatus_t sigstatus; /*!< valid if event_id is FTDM_SIGEVENT_SIGSTATUS_CHANGED */
- ftdm_event_trace_t logevent; /*!< valid if event_id is FTDM_SIGEVENT_TRACE or FTDM_SIGEVENT_TRACE_RAW */
+ ftdm_event_trace_t trace; /*!< valid if event_id is FTDM_SIGEVENT_TRACE or FTDM_SIGEVENT_TRACE_RAW */
- }ev_data;
+ ftdm_event_collected_t collected; /*!< valid if event_id is FTDM_SIGEVENT_COLLECTED_DIGIT */
+ ftdm_event_indication_completed_t indication_completed; /*!< valid if the event_id is FTDM_SIGEVENT_INDICATION_COMPLETED */
+ } ev_data;
+ struct {
+ uint8_t autofree; /*!< Whether the freetdm core will free it after message delivery */
+ uint32_t len; /*!< Data len */
+ void *data; /*!< Signaling module specific data */
+ } raw;
};
/*! \brief Crash policy