From 9d45690006947148913279f83d4d92e1fb4783bc Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Thu, 20 May 2010 11:43:40 -0400 Subject: [PATCH] freetdm: add pvt data to freetdm channels fix fxs features --- libs/freetdm/mod_freetdm/mod_freetdm.c | 70 +++++++++++-------- libs/freetdm/src/ftdm_io.c | 28 ++++---- .../src/ftmod/ftmod_analog/ftmod_analog.c | 4 +- libs/freetdm/src/include/freetdm.h | 18 +++++ libs/freetdm/src/include/private/ftdm_core.h | 1 + 5 files changed, 76 insertions(+), 45 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 57dd2393c6..fd36deb611 100644 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -55,19 +55,6 @@ typedef enum { ANALOG_OPTION_CALL_SWAP = (1 << 1) } analog_option_t; -struct span_config { - ftdm_span_t *span; - char dialplan[80]; - char context[80]; - char dial_regex[256]; - char fail_dial_regex[256]; - char hold_music[256]; - char type[256]; - analog_option_t analog_options; -}; - -static struct span_config SPAN_CONFIG[FTDM_MAX_SPANS_INTERFACE] = {{0}}; - typedef enum { TFLAG_IO = (1 << 0), TFLAG_DTMF = (1 << 1), @@ -95,6 +82,7 @@ static struct { switch_hash_t *ss7_configs; } globals; +/* private data attached to each fs session */ struct private_object { unsigned int flags; switch_codec_t read_codec; @@ -114,8 +102,26 @@ struct private_object { uint32_t wr_error; }; +/* private data attached to FTDM channels (only FXS for now) */ +typedef struct chan_pvt { + unsigned int flags; +} chan_pvt_t; + typedef struct private_object private_t; +struct span_config { + ftdm_span_t *span; + char dialplan[80]; + char context[80]; + char dial_regex[256]; + char fail_dial_regex[256]; + char hold_music[256]; + char type[256]; + analog_option_t analog_options; + chan_pvt_t pvts[FTDM_MAX_CHANNELS_SPAN]; +}; + +static struct span_config SPAN_CONFIG[FTDM_MAX_SPANS_INTERFACE] = {{0}}; static switch_status_t channel_on_init(switch_core_session_t *session); static switch_status_t channel_on_hangup(switch_core_session_t *session); @@ -873,17 +879,7 @@ static switch_status_t channel_receive_message_fxo(switch_core_session_t *sessio switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_PROGRESS: case SWITCH_MESSAGE_INDICATE_ANSWER: -#if 0 - if (switch_channel_test_flag(channel, CF_OUTBOUND)) { - ftdm_set_flag_locked(tech_pvt->ftdmchan, FTDM_CHANNEL_ANSWERED); - ftdm_set_flag_locked(tech_pvt->ftdmchan, FTDM_CHANNEL_PROGRESS); - ftdm_set_flag_locked(tech_pvt->ftdmchan, FTDM_CHANNEL_MEDIA); - } else { - ftdm_set_state_locked(tech_pvt->ftdmchan, FTDM_CHANNEL_STATE_UP); - } -#else ftdm_channel_call_answer(tech_pvt->ftdmchan); -#endif break; default: break; @@ -1514,7 +1510,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal) spanid = ftdm_channel_get_span_id(sigmsg->channel); tokencount = ftdm_channel_get_token_count(sigmsg->channel); - ftdm_log(FTDM_LOG_DEBUG, "got FXS sig [%s]\n", ftdm_signal_event2str(sigmsg->event_id)); + ftdm_log(FTDM_LOG_DEBUG, "got FXS sig [%s]\n", ftdm_signal_event2str(sigmsg->event_id)); switch(sigmsg->event_id) { case FTDM_SIGEVENT_UP: @@ -1621,6 +1617,12 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal) break; case FTDM_SIGEVENT_FLASH: { + chan_pvt_t *chanpvt = ftdm_channel_get_private(sigmsg->channel); + if (!chanpvt) { + ftdm_log(FTDM_LOG_ERROR, "%d:%d has no private data, can't handle FXS features! (this is a bug)\n", + chanid, spanid); + break; + } if (ftdm_channel_call_check_hold(sigmsg->channel) && tokencount == 1) { switch_core_session_t *session; if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) { @@ -1636,10 +1638,9 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal) switch_clear_flag_locked(tech_pvt, TFLAG_HOLD); switch_core_session_rwunlock(session); } -#if 0 } else if (tokencount == 2 && (SPAN_CONFIG[sigmsg->span_id].analog_options & ANALOG_OPTION_3WAY)) { - if (ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_3WAY)) { - ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_3WAY); + if (switch_test_flag(chanpvt, ANALOG_OPTION_3WAY)) { + switch_clear_flag(chanpvt, ANALOG_OPTION_3WAY); if ((session = ftdm_channel_get_session(sigmsg->channel, 1))) { channel = switch_core_session_get_channel(session); switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); @@ -1649,8 +1650,8 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal) cycle_foreground(sigmsg->channel, 1, NULL); } else { char *cmd; - cmd = switch_mprintf("three_way::%s", sigmsg->channel->tokens[0]); - ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_3WAY); + cmd = switch_mprintf("three_way::%s", ftdm_channel_get_token(sigmsg->channel, 0)); + switch_set_flag(chanpvt, ANALOG_OPTION_3WAY); cycle_foreground(sigmsg->channel, 1, cmd); free(cmd); } @@ -1661,7 +1662,6 @@ static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal) if (tokencount == 1) { ftdm_channel_call_hold(sigmsg->channel); } -#endif } } @@ -2160,6 +2160,8 @@ static switch_status_t load_config(void) ftdm_span_t *boost_span = NULL; unsigned boosti = 0; unsigned int i = 0; + ftdm_channel_t *fchan = NULL; + unsigned int chancount = 0; memset(boost_spans, 0, sizeof(boost_spans)); memset(&globals, 0, sizeof(globals)); @@ -2366,7 +2368,7 @@ static switch_status_t load_config(void) "hotline", hotline, "enable_callerid", enable_callerid, FTDM_TAG_END) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "Error starting FreeTDM span %d\n", span_id); + ftdm_log(FTDM_LOG_ERROR, "Error configuring FreeTDM analog span %s\n", ftdm_span_get_name(span)); continue; } @@ -2375,6 +2377,12 @@ static switch_status_t load_config(void) switch_set_string(SPAN_CONFIG[span_id].dialplan, dialplan); SPAN_CONFIG[span_id].analog_options = analog_options | globals.analog_options; + chancount = ftdm_span_get_chan_count(span); + for (i = 1; i <= chancount; i++) { + fchan = ftdm_span_get_channel(span, i); + ftdm_channel_set_private(fchan, &SPAN_CONFIG[span_id].pvts[i]); + } + if (dial_regex) { switch_set_string(SPAN_CONFIG[span_id].dial_regex, dial_regex); } diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index cddd4849f2..6afa24da62 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -1002,6 +1002,16 @@ FT_DECLARE(void) ftdm_channel_replace_token(ftdm_channel_t *ftdmchan, const char } } +FT_DECLARE(void) ftdm_channel_set_private(ftdm_channel_t *ftdmchan, void *pvt) +{ + ftdmchan->user_private = pvt; +} + +FT_DECLARE(void *) ftdm_channel_get_private(const ftdm_channel_t *ftdmchan) +{ + return ftdmchan->user_private; +} + FT_DECLARE(uint32_t) ftdm_channel_get_token_count(const ftdm_channel_t *ftdmchan) { uint32_t count; @@ -1747,7 +1757,7 @@ FT_DECLARE(ftdm_bool_t) ftdm_channel_call_check_hold(const ftdm_channel_t *ftdmc { ftdm_bool_t condition; ftdm_channel_lock(ftdmchan); - condition = ftdm_test_flag(ftdmchan, FTDM_CHANNEL_HOLD); + condition = ftdm_test_flag(ftdmchan, FTDM_CHANNEL_HOLD) ? FTDM_TRUE : FTDM_FALSE; ftdm_channel_unlock(ftdmchan); return condition; } @@ -1801,7 +1811,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hold(const char *file, const char * { ftdm_channel_lock(ftdmchan); ftdm_set_flag(ftdmchan, FTDM_CHANNEL_HOLD); - ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_DIALTONE, 1); + ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_DIALTONE, 0); ftdm_channel_unlock(ftdmchan); return FTDM_SUCCESS; } @@ -1809,9 +1819,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hold(const char *file, const char * FT_DECLARE(ftdm_status_t) _ftdm_channel_call_unhold(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan) { ftdm_channel_lock(ftdmchan); - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_HOLD)) { - ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 1); - } + ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 0); ftdm_channel_unlock(ftdmchan); return FTDM_SUCCESS; } @@ -1820,15 +1828,11 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char { ftdm_channel_lock(ftdmchan); - if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_ANSWERED)) { - ftdm_channel_unlock(ftdmchan); - return FTDM_SUCCESS; - } + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_ANSWERED); + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS); + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_MEDIA); if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) { - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_ANSWERED); - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS); - ftdm_set_flag(ftdmchan, FTDM_CHANNEL_MEDIA); ftdm_channel_unlock(ftdmchan); return FTDM_SUCCESS; } diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c index daddb2115c..dd54a88d72 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c @@ -691,8 +691,8 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj) } if (ftdm_channel_read(ftdmchan, frame, &len) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "READ ERROR [%s]\n", ftdmchan->last_error); - goto done; + ftdm_log(FTDM_LOG_WARNING, "read error [%s]\n", ftdmchan->last_error); + continue; } if (ftdmchan->type == FTDM_CHAN_TYPE_FXO && ftdmchan->detected_tones[0]) { diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index cf73969862..480182a3b2 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -658,6 +658,24 @@ FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signa /*! \brief Get span signaling status (ie: whether protocol layer is up or down) */ FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan); +/*! + * \brief Set user private data in the channel + * + * \param ftdmchan The channel where the private data will be stored + * \param pvt The private pointer to store + * + */ +FT_DECLARE(void) ftdm_channel_set_private(ftdm_channel_t *ftdmchan, void *pvt); + +/*! + * \brief Get user private data in the channel + * + * \param ftdmchan The channel to retrieve the private data + * \retval The private data (if any or NULL if no data has been stored) + * + */ +FT_DECLARE(void *) ftdm_channel_get_private(const ftdm_channel_t *ftdmchan); + /*! * \brief Remove the given token from the channel * diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h index a900b0d808..93f197f0ed 100644 --- a/libs/freetdm/src/include/private/ftdm_core.h +++ b/libs/freetdm/src/include/private/ftdm_core.h @@ -407,6 +407,7 @@ struct ftdm_channel { uint8_t txgain_table[FTDM_GAINS_TABLE_SIZE]; float rxgain; float txgain; + void *user_private; }; struct ftdm_span {