* Replace ftdm_channel_flag_t with defines. We reached the 32bit limit where does not seem reliable
to keep using enum.
* Flags member for ftdm_channel_t is now uint64_t
* Added FTDM_CHANNEL_CALL_STARTED flag to indicate when the API user knows about a call
* Refactored raw_data member for ftdm_sigmsg_t. If raw_data needs to be freed it must be requested explicitly
through the autofree member
* Added collected member to ftdm_sigmsg_t for FTDM_SIGEVENT_COLLECTED data instead of using raw_data
* Created define FTDM_DIGITS_LIMIT for DNIS/ANI digits limit
* Fix some stat checks and outdated code in ftmod_analog
* Refactored ftdm_channel_get_history_str API to return the time offsets and time since last state change
* Do not send FTDM_SIGEVENT_STOP and FTDM_SIGEVENT_RELEASED on calls that were never reported to the user
case FTDM_SIGEVENT_COLLECTED_DIGIT:
{
int span_id = ftdm_channel_get_span_id(sigmsg->channel);
- char *dtmf = sigmsg->raw_data;
+ char *dtmf = sigmsg->ev_data.collected.digits;
char *regex = SPAN_CONFIG[span_id].dial_regex;
char *fail_regex = SPAN_CONFIG[span_id].fail_dial_regex;
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
break;
case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
{
- ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->ev_data.sigstatus.status;
+ ftdm_signaling_status_t sigstatus = sigmsg->ev_data.sigstatus.status;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to :%s\n",
spanid, chanid, ftdm_signaling_status2str(sigstatus));
}
ftdm_log(FTDM_LOG_ERROR, "outgoing_call method not implemented in this span!\n");
}
+ if (status == FTDM_SUCCESS) {
+ ftdm_set_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED);
+ ftdm_call_set_call_id(&ftdmchan->caller_data);
+ ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 100);
+ }
+
+ ftdm_channel_unlock(ftdmchan);
+
#ifdef __WINDOWS__
UNREFERENCED_PARAMETER(file);
UNREFERENCED_PARAMETER(func);
UNREFERENCED_PARAMETER(line);
#endif
- ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 100);
-
- ftdm_call_set_call_id(&ftdmchan->caller_data);
- ftdm_channel_unlock(ftdmchan);
-
return status;
}
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_INPUT_DUMP, NULL);
ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_OUTPUT_DUMP, NULL);
- if (FTDM_IS_VOICE_CHANNEL(ftdmchan)) {
+ if (FTDM_IS_VOICE_CHANNEL(ftdmchan) && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED)) {
ftdm_sigmsg_t sigmsg;
memset(&sigmsg, 0, sizeof(sigmsg));
sigmsg.span_id = ftdmchan->span_id;
sigmsg.event_id = FTDM_SIGEVENT_RELEASED;
ftdm_span_send_signal(ftdmchan->span, &sigmsg);
ftdm_call_clear_call_id(&ftdmchan->caller_data);
+ ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED);
}
if (ftdmchan->txdrops || ftdmchan->rxdrops) {
}
status = ftdm_raw_read(ftdmchan, data, datalen);
-
if (status != FTDM_SUCCESS) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "raw I/O read filed\n");
+ goto done;
}
- if (status == FTDM_SUCCESS) {
- if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_USE_RX_GAIN)
- && (ftdmchan->native_codec == FTDM_CODEC_ALAW || ftdmchan->native_codec == FTDM_CODEC_ULAW)) {
- unsigned char *rdata = data;
- for (i = 0; i < *datalen; i++) {
- rdata[i] = ftdmchan->rxgain_table[rdata[i]];
- }
+ if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_USE_RX_GAIN)
+ && (ftdmchan->native_codec == FTDM_CODEC_ALAW || ftdmchan->native_codec == FTDM_CODEC_ULAW)) {
+ unsigned char *rdata = data;
+ for (i = 0; i < *datalen; i++) {
+ rdata[i] = ftdmchan->rxgain_table[rdata[i]];
}
- handle_dtmf(ftdmchan, *datalen);
}
+ handle_dtmf(ftdmchan, *datalen);
- if (status == FTDM_SUCCESS && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) {
+ if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) {
if (ftdmchan->native_codec == FTDM_CODEC_ULAW && ftdmchan->effective_codec == FTDM_CODEC_SLIN) {
codec_func = fio_ulaw2slin;
} else if (ftdmchan->native_codec == FTDM_CODEC_ULAW && ftdmchan->effective_codec == FTDM_CODEC_ALAW) {
ftdm_mutex_unlock(globals.group_mutex);
}
-
FT_DECLARE(ftdm_status_t) ftdm_group_create(ftdm_group_t **group, const char *name)
{
ftdm_group_t *new_group = NULL;
if (sigmsg->channel) {
ftdm_call_clear_data(&(sigmsg->channel->caller_data));
}
- ftdm_safe_free(sigmsg->raw_data);
+ if (sigmsg->raw.autofree) {
+ ftdm_safe_free(sigmsg->raw.data);
+ sigmsg->raw.data = NULL;
+ sigmsg->raw.len = 0;
+ }
return status;
}
case FTDM_SIGEVENT_START:
{
+ ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED);
ftdm_call_set_call_id(&sigmsg->channel->caller_data);
ftdm_set_echocancel_call_begin(sigmsg->channel);
if (sigmsg->channel->dtmfdbg.requested) {
break;
case FTDM_SIGEVENT_STOP:
+ if (!ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED)) {
+ /* this happens for FXS devices which blindly send SIGEVENT_STOP, we should fix it there ... */
+ ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user never knew about a call in this channel\n");
+ goto done;
+ }
if (ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_USER_HANGUP)) {
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user already requested hangup\n");
goto done;
return new;
}
-FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan)
+
+static void write_history_entry(const ftdm_channel_t *fchan, ftdm_stream_handle_t *stream, int i, ftdm_time_t *prevtime)
{
char func[255];
char line[255];
char states[255];
+ const char *filename = NULL;
+ snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state));
+ snprintf(func, sizeof(func), "[%s]", fchan->history[i].func);
+ filename = strrchr(fchan->history[i].file, *FTDM_PATH_SEPARATOR);
+ if (!filename) {
+ filename = fchan->history[i].file;
+ } else {
+ filename++;
+ }
+ if (!(*prevtime)) {
+ *prevtime = fchan->history[i].time;
+ }
+ snprintf(line, sizeof(func), "[%s:%d]", filename, fchan->history[i].line);
+ stream->write_function(stream, "%-30.30s %-30.30s %-30.30s %lums\n", states, func, line, (fchan->history[i].time - *prevtime));
+ *prevtime = fchan->history[i].time;
+}
+
+FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan)
+{
uint8_t i = 0;
+ ftdm_time_t currtime = 0;
+ ftdm_time_t prevtime = 0;
ftdm_stream_handle_t stream = { 0 };
FTDM_STANDARD_STREAM(stream);
return stream.data;
}
- stream.write_function(&stream, "%-30.30s %-30.30s %s", "-- States --", "-- Function --", "-- Location --\n");
+ stream.write_function(&stream, "%-30.30s %-30.30s %-30.30s %s",
+ "-- States --", "-- Function --", "-- Location --", "-- Time Offset --\n");
for (i = fchan->hindex; i < ftdm_array_len(fchan->history); i++) {
if (!fchan->history[i].file) {
break;
}
- snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state));
- snprintf(func, sizeof(func), "[%s]", fchan->history[i].func);
- snprintf(line, sizeof(func), "[%s:%d]", fchan->history[i].file, fchan->history[i].line);
- stream.write_function(&stream, "%-30.30s %-30.30s %s\n", states, func, line);
+ write_history_entry(fchan, &stream, i, &prevtime);
}
for (i = 0; i < fchan->hindex; i++) {
- snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state));
- snprintf(func, sizeof(func), "[%s]", fchan->history[i].func);
- snprintf(line, sizeof(func), "[%s:%d]", fchan->history[i].file, fchan->history[i].line);
- stream.write_function(&stream, "%-30.30s %-30.30s %s\n", states, func, line);
+ write_history_entry(fchan, &stream, i, &prevtime);
}
+ currtime = ftdm_current_time_in_ms();
+
+ stream.write_function(&stream, "\nTime since last state change: %lums\n", (currtime - prevtime));
+
return stream.data;
}
static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data)
{
- ftdm_assert_return((caller_data->call_id && caller_data->call_id <= MAX_CALLIDS), FTDM_FAIL, "Clearing call with invalid call-id\n");
+ if (caller_data->call_id) {
+ ftdm_assert_return((caller_data->call_id <= MAX_CALLIDS), FTDM_FAIL, "Cannot clear call with invalid call-id\n");
+ } else {
+ /* there might not be a call at all */
+ return FTDM_SUCCESS;
+ }
+
ftdm_mutex_lock(globals.call_id_mutex);
if (globals.call_ids[caller_data->call_id]) {
+ ftdm_log(FTDM_LOG_DEBUG, "Cleared call with id %u\n", caller_data->call_id);
caller_data->call_id = 0;
globals.call_ids[caller_data->call_id] = NULL;
} else {
ftdm_log(FTDM_LOG_CRIT, "call-id did not exist %u\n", caller_data->call_id);
}
ftdm_mutex_unlock(globals.call_id_mutex);
+
return FTDM_SUCCESS;
}
if (ftdmchan->type == FTDM_CHAN_TYPE_FXS &&
ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) &&
- (ftdmchan->last_state == FTDM_CHANNEL_STATE_RINGING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE
- || ftdmchan->last_state == FTDM_CHANNEL_STATE_RING)) {
+ (ftdmchan->last_state == FTDM_CHANNEL_STATE_RINGING
+ || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE
+ || ftdmchan->last_state == FTDM_CHANNEL_STATE_RING
+ || ftdmchan->last_state == FTDM_CHANNEL_STATE_UP)) {
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
} else {
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING;
dtmf_offset = strlen(dtmf);
last_digit = elapsed;
sig.event_id = FTDM_SIGEVENT_COLLECTED_DIGIT;
- sig.raw_data = dtmf;
+ ftdm_set_string(sig.ev_data.collected.digits, dtmf);
if (ftdm_span_send_signal(ftdmchan->span, &sig) == FTDM_BREAK) {
collecting = 0;
}
{
if (event->channel->type != FTDM_CHAN_TYPE_FXO) {
ftdm_log_chan_msg(event->channel, FTDM_LOG_ERROR, "Cannot get a RING_START event on a non-fxo channel, please check your config.\n");
- ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DOWN);
+ ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN);
goto end;
}
if (!event->channel->ring_count && (event->channel->state == FTDM_CHANNEL_STATE_DOWN && !ftdm_test_flag(event->channel, FTDM_CHANNEL_INTHREAD))) {
if (ftdm_test_flag(analog_data, FTDM_ANALOG_CALLERID)) {
- ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_GET_CALLERID);
+ ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_GET_CALLERID);
} else {
- ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_RING);
+ ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_RING);
}
event->channel->ring_count = 1;
ftdm_mutex_unlock(event->channel->mutex);
}
if (event->channel->state != FTDM_CHANNEL_STATE_DOWN) {
- ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DOWN);
+ if (event->channel->state == FTDM_CHANNEL_STATE_HANGUP &&
+ ftdm_test_flag(event->channel, FTDM_CHANNEL_STATE_CHANGE)) {
+ ftdm_clear_flag(event->channel, FTDM_CHANNEL_STATE_CHANGE);
+ /* we do not need to process HANGUP since the device also hangup already */
+ }
+ ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN);
}
}
case FTDM_OOB_FLASH:
{
if (event->channel->state == FTDM_CHANNEL_STATE_CALLWAITING) {
- ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_UP);
- ftdm_clear_flag_locked(event->channel, FTDM_CHANNEL_STATE_CHANGE);
- ftdm_clear_flag_locked(event->channel->span, FTDM_SPAN_STATE_CHANGE);
+ ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_UP);
+ ftdm_clear_flag(event->channel, FTDM_CHANNEL_STATE_CHANGE);
+ ftdm_clear_flag(event->channel->span, FTDM_SPAN_STATE_CHANGE);
event->channel->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK] = 0;
}
ftdm_channel_rotate_tokens(event->channel);
if (ftdm_test_flag(event->channel, FTDM_CHANNEL_HOLD) && event->channel->token_count != 1) {
- ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_UP);
+ ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_UP);
} else {
sig.event_id = FTDM_SIGEVENT_FLASH;
ftdm_span_send_signal(span, &sig);
if (ftdm_test_flag(event->channel, FTDM_CHANNEL_RINGING)) {
ftdm_channel_command(event->channel, FTDM_COMMAND_GENERATE_RING_OFF, NULL);
}
- ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_UP);
+ ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_UP);
} else {
if(!analog_data->max_dialstr) {
- ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_COLLECT);
+ ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_COLLECT);
} else {
- ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DIALTONE);
+ ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DIALTONE);
}
ftdm_mutex_unlock(event->channel->mutex);
locked = 0;
ftdm_channel_command(event->channel, FTDM_COMMAND_ONHOOK, NULL);
}
}
- ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DOWN);
+ ftdm_set_state(event->channel, FTDM_CHANNEL_STATE_DOWN);
}
}
default:
dtmf_offset = strlen(dtmf);
last_digit = elapsed;
sig.event_id = FTDM_SIGEVENT_COLLECTED_DIGIT;
- sig.raw_data = dtmf;
+ ftdm_set_string(sig.ev_data.collected.digits, dtmf);
if (ftdm_span_send_signal(ftdmchan->span, &sig) == FTDM_BREAK) {
collecting = 0;
}
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);
}
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);
}
#define CALLING_PARTY_CATEGORY_STRINGS "unknown", "operator", "ordinary", "priority", "data-call", "test-call", "payphone", "invalid"
FTDM_STR2ENUM_P(ftdm_str2ftdm_calling_party_category, ftdm_calling_party_category2str, ftdm_calling_party_category_t)
+/*! \brief Digit limit used in DNIS/ANI */
+#define FTDM_DIGITS_LIMIT 25
/*! \brief Number abstraction */
typedef struct {
- char digits[25];
+ char digits[FTDM_DIGITS_LIMIT];
uint8_t type;
uint8_t plan;
} ftdm_number_t;
typedef void * ftdm_variable_container_t;
-
+
/*! \brief Caller information */
typedef struct ftdm_caller_data {
char cid_date[8]; /*!< Caller ID date */
ftdm_number_t ani; /*!< ANI (Automatic Number Identification) */
ftdm_number_t dnis; /*!< DNIS (Dialed Number Identification Service) */
ftdm_number_t rdnis; /*!< RDNIS (Redirected Dialed Number Identification Service) */
- char aniII[25]; /*! ANI II */
+ char aniII[FTDM_DIGITS_LIMIT]; /*! ANI II */
uint8_t screen; /*!< Screening */
uint8_t pres; /*!< Presentation*/
- char collected[25]; /*!< Collected digits so far */
+ char collected[FTDM_DIGITS_LIMIT]; /*!< Collected digits so far */
int hangup_cause; /*!< Hangup cause */
char raw_data[1024]; /*!< Protocol specific raw caller data */
uint32_t raw_data_len; /*!< Raw data length */
uint8_t level; /* 1 for phy layer, 2 for q921/mtp2, 3 for q931/mtp3 */
} ftdm_event_trace_t;
+typedef struct {
+ /* Digits collected */
+ char digits[FTDM_DIGITS_LIMIT];
+} ftdm_event_collected_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 */
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_collected_t collected; /*!< valif if event_id is FTDM_SIGEVENT_COLLECTED_DIGIT */
} 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
uint32_t extra_id;
ftdm_chan_type_t type;
ftdm_socket_t sockfd;
- uint32_t flags;
+ uint64_t flags;
uint32_t pflags;
uint32_t sflags;
ftdm_alarm_flag_t alarm_flags;
"HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "RESET", "INVALID"
FTDM_STR2ENUM_P(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t)
-typedef enum {
- FTDM_CHANNEL_CONFIGURED = (1 << 0),
- FTDM_CHANNEL_READY = (1 << 1),
- FTDM_CHANNEL_OPEN = (1 << 2),
- FTDM_CHANNEL_DTMF_DETECT = (1 << 3),
- FTDM_CHANNEL_SUPRESS_DTMF = (1 << 4),
- FTDM_CHANNEL_TRANSCODE = (1 << 5),
- FTDM_CHANNEL_BUFFER = (1 << 6),
- FTDM_CHANNEL_EVENT = (1 << 7),
- FTDM_CHANNEL_INTHREAD = (1 << 8),
- FTDM_CHANNEL_WINK = (1 << 9),
- FTDM_CHANNEL_FLASH = (1 << 10),
- FTDM_CHANNEL_STATE_CHANGE = (1 << 11),
- FTDM_CHANNEL_HOLD = (1 << 12),
- FTDM_CHANNEL_INUSE = (1 << 13),
- FTDM_CHANNEL_OFFHOOK = (1 << 14),
- FTDM_CHANNEL_RINGING = (1 << 15),
- FTDM_CHANNEL_PROGRESS_DETECT = (1 << 16),
- FTDM_CHANNEL_CALLERID_DETECT = (1 << 17),
- FTDM_CHANNEL_OUTBOUND = (1 << 18),
- FTDM_CHANNEL_SUSPENDED = (1 << 19),
- FTDM_CHANNEL_3WAY = (1 << 20),
- FTDM_CHANNEL_PROGRESS = (1 << 21),
- FTDM_CHANNEL_MEDIA = (1 << 22),
- FTDM_CHANNEL_ANSWERED = (1 << 23),
- FTDM_CHANNEL_MUTE = (1 << 24),
- FTDM_CHANNEL_USE_RX_GAIN = (1 << 25),
- FTDM_CHANNEL_USE_TX_GAIN = (1 << 26),
- FTDM_CHANNEL_IN_ALARM = (1 << 27),
- FTDM_CHANNEL_SIG_UP = (1 << 28),
- FTDM_CHANNEL_USER_HANGUP = (1 << 29),
- FTDM_CHANNEL_RX_DISABLED = (1 << 30),
- FTDM_CHANNEL_TX_DISABLED = (1 << 31),
- /* ok, when we reach 32, we need to move to uint64_t all the flag stuff */
-} ftdm_channel_flag_t;
-#if defined(__cplusplus) && defined(WIN32)
- // fix C2676
-__inline__ ftdm_channel_flag_t operator|=(ftdm_channel_flag_t a, int32_t b) {
- a = (ftdm_channel_flag_t)(a | b);
- return a;
-}
-__inline__ ftdm_channel_flag_t operator&=(ftdm_channel_flag_t a, int32_t b) {
- a = (ftdm_channel_flag_t)(a & b);
- return a;
-}
-#endif
+/*!< Channel flags. This used to be an enum but we reached the 32bit limit for enums */
+#define FTDM_CHANNEL_CONFIGURED (1UL << 0)
+#define FTDM_CHANNEL_READY (1UL << 1)
+#define FTDM_CHANNEL_OPEN (1UL << 2)
+#define FTDM_CHANNEL_DTMF_DETECT (1UL << 3)
+#define FTDM_CHANNEL_SUPRESS_DTMF (1UL << 4)
+#define FTDM_CHANNEL_TRANSCODE (1UL << 5)
+#define FTDM_CHANNEL_BUFFER (1UL << 6)
+#define FTDM_CHANNEL_EVENT (1UL << 7)
+#define FTDM_CHANNEL_INTHREAD (1UL << 8)
+#define FTDM_CHANNEL_WINK (1UL << 9)
+#define FTDM_CHANNEL_FLASH (1UL << 10)
+#define FTDM_CHANNEL_STATE_CHANGE (1UL << 11)
+#define FTDM_CHANNEL_HOLD (1UL << 12)
+#define FTDM_CHANNEL_INUSE (1UL << 13)
+#define FTDM_CHANNEL_OFFHOOK (1UL << 14)
+#define FTDM_CHANNEL_RINGING (1UL << 15)
+#define FTDM_CHANNEL_PROGRESS_DETECT (1UL << 16)
+#define FTDM_CHANNEL_CALLERID_DETECT (1UL << 17)
+#define FTDM_CHANNEL_OUTBOUND (1UL << 18)
+#define FTDM_CHANNEL_SUSPENDED (1UL << 19)
+#define FTDM_CHANNEL_3WAY (1UL << 20)
+#define FTDM_CHANNEL_PROGRESS (1UL << 21)
+#define FTDM_CHANNEL_MEDIA (1UL << 22)
+#define FTDM_CHANNEL_ANSWERED (1UL << 23)
+#define FTDM_CHANNEL_MUTE (1UL << 24)
+#define FTDM_CHANNEL_USE_RX_GAIN (1UL << 25)
+#define FTDM_CHANNEL_USE_TX_GAIN (1UL << 26)
+#define FTDM_CHANNEL_IN_ALARM (1UL << 27)
+#define FTDM_CHANNEL_SIG_UP (1UL << 28)
+#define FTDM_CHANNEL_USER_HANGUP (1UL << 29)
+#define FTDM_CHANNEL_RX_DISABLED (1UL << 30)
+#define FTDM_CHANNEL_TX_DISABLED (1UL << 31)
+/*!< The user knows about a call in this channel */
+#define FTDM_CHANNEL_CALL_STARTED (1UL << 32)
typedef enum {
ZSM_NONE,