diff --git a/libs/freetdm/src/include/openzap.h b/libs/freetdm/src/include/openzap.h index 44d54473ac..7052d8e17b 100644 --- a/libs/freetdm/src/include/openzap.h +++ b/libs/freetdm/src/include/openzap.h @@ -561,6 +561,7 @@ struct zap_span { teletone_multi_tone_t tone_finder[ZAP_TONEMAP_INVALID+1]; zap_channel_t *channels[ZAP_MAX_CHANNELS_SPAN+1]; zio_channel_outgoing_call_t outgoing_call; + zio_channel_get_sig_status_t get_sig_status; zio_channel_request_t channel_request; zap_span_start_t start; zap_span_stop_t stop; @@ -680,6 +681,7 @@ OZ_DECLARE(zap_status_t) zap_fsk_data_add_mdmf(zap_fsk_data_state_t *state, zap_ OZ_DECLARE(zap_status_t) zap_fsk_data_add_checksum(zap_fsk_data_state_t *state); OZ_DECLARE(zap_status_t) zap_fsk_data_add_sdmf(zap_fsk_data_state_t *state, const char *date, char *number); OZ_DECLARE(zap_status_t) zap_channel_outgoing_call(zap_channel_t *zchan); +OZ_DECLARE(zap_status_t) zap_channel_get_sig_status(zap_channel_t *zchan, zap_channel_sig_status_t *status); OZ_DECLARE(void) zap_channel_rotate_tokens(zap_channel_t *zchan); OZ_DECLARE(void) zap_channel_clear_detected_tones(zap_channel_t *zchan); OZ_DECLARE(void) zap_channel_clear_needed_tones(zap_channel_t *zchan); diff --git a/libs/freetdm/src/include/zap_types.h b/libs/freetdm/src/include/zap_types.h index 3f6d477243..38b749c0d7 100644 --- a/libs/freetdm/src/include/zap_types.h +++ b/libs/freetdm/src/include/zap_types.h @@ -190,6 +190,8 @@ typedef enum { /* The channel signaling link is ready and calls can be placed */ ZAP_SIG_STATE_UP } zap_channel_sig_status_t; +#define SIGSTATUS_STRINGS "DOWN", "SUSPENDED", "UP" +ZAP_STR2ENUM_P(zap_str2zap_channel_sig_status, zap_sig_status2str, zap_channel_sig_status_t) typedef enum { ZAP_SIGEVENT_START, @@ -208,10 +210,12 @@ typedef enum { ZAP_SIGEVENT_COLLECTED_DIGIT, ZAP_SIGEVENT_ADD_CALL, ZAP_SIGEVENT_RESTART, + /* Signaling link status changed (D-chan up, down, R2 blocked etc) */ + ZAP_SIGEVENT_SIGSTATUS_CHANGED, ZAP_SIGEVENT_INVALID } zap_signal_event_t; #define SIGNAL_STRINGS "START", "STOP", "TRANSFER", "ANSWER", "UP", "FLASH", "PROGRESS", \ - "PROGRESS_MEDIA", "NOTIFY", "TONE_DETECTED", "ALARM_TRAP", "ALARM_CLEAR", "MISC", "COLLECTED_DIGIT", "ADD_CALL", "RESTART", "INVALID" + "PROGRESS_MEDIA", "NOTIFY", "TONE_DETECTED", "ALARM_TRAP", "ALARM_CLEAR", "MISC", "COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGLINK_CHANGED", "INVALID" ZAP_STR2ENUM_P(zap_str2zap_signal_event, zap_signal_event2str, zap_signal_event_t) typedef enum { @@ -437,6 +441,7 @@ typedef zap_status_t (*zap_stream_handle_write_function_t) (zap_stream_handle_t #define ZIO_CHANNEL_REQUEST_ARGS (zap_span_t *span, uint32_t chan_id, zap_direction_t direction, zap_caller_data_t *caller_data, zap_channel_t **zchan) #define ZIO_CHANNEL_OUTGOING_CALL_ARGS (zap_channel_t *zchan) +#define ZIO_CHANNEL_GET_SIG_STATUS_ARGS (zap_channel_t *zchan, zap_channel_sig_status_t *status) #define ZIO_SPAN_POLL_EVENT_ARGS (zap_span_t *span, uint32_t ms) #define ZIO_SPAN_NEXT_EVENT_ARGS (zap_span_t *span, zap_event_t **event) #define ZIO_SIGNAL_CB_ARGS (zap_sigmsg_t *sigmsg) @@ -462,6 +467,7 @@ typedef zap_status_t (*zap_stream_handle_write_function_t) (zap_stream_handle_t typedef zap_status_t (*zio_channel_request_t) ZIO_CHANNEL_REQUEST_ARGS ; typedef zap_status_t (*zio_channel_outgoing_call_t) ZIO_CHANNEL_OUTGOING_CALL_ARGS ; +typedef zap_status_t (*zio_channel_get_sig_status_t) ZIO_CHANNEL_GET_SIG_STATUS_ARGS; typedef zap_status_t (*zio_span_poll_event_t) ZIO_SPAN_POLL_EVENT_ARGS ; typedef zap_status_t (*zio_span_next_event_t) ZIO_SPAN_NEXT_EVENT_ARGS ; typedef zap_status_t (*zio_signal_cb_t) ZIO_SIGNAL_CB_ARGS ; @@ -488,6 +494,7 @@ typedef zap_status_t (*zio_api_t) ZIO_API_ARGS ; #define ZIO_CHANNEL_REQUEST_FUNCTION(name) zap_status_t name ZIO_CHANNEL_REQUEST_ARGS #define ZIO_CHANNEL_OUTGOING_CALL_FUNCTION(name) zap_status_t name ZIO_CHANNEL_OUTGOING_CALL_ARGS +#define ZIO_CHANNEL_GET_SIG_STATUS_FUNCTION(name) zap_status_t name ZIO_CHANNEL_GET_SIG_STATUS_ARGS #define ZIO_SPAN_POLL_EVENT_FUNCTION(name) zap_status_t name ZIO_SPAN_POLL_EVENT_ARGS #define ZIO_SPAN_NEXT_EVENT_FUNCTION(name) zap_status_t name ZIO_SPAN_NEXT_EVENT_ARGS #define ZIO_SIGNAL_CB_FUNCTION(name) zap_status_t name ZIO_SIGNAL_CB_ARGS diff --git a/libs/freetdm/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c b/libs/freetdm/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c index 5aafbf3734..59f17ab875 100644 --- a/libs/freetdm/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c +++ b/libs/freetdm/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c @@ -29,6 +29,13 @@ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Contributors: + * + * Moises Silva + * David Yatzin + * Nenad Corbic + * */ #include "openzap.h" @@ -1506,10 +1513,30 @@ static BOOST_WRITE_MSG_FUNCTION(zap_boost_write_msg) static BOOST_SIG_STATUS_CB_FUNCTION(zap_boost_sig_status_change) { - /* TODO: Notify the upper layer of the signaling status change (via span signaling callback and a new msg type?) */ + zap_sigmsg_t sig; + zap_sangoma_boost_data_t *sangoma_boost_data = zchan->span->signal_data; + zap_log(ZAP_LOG_DEBUG, "%d:%d Signaling link status changed to %s\n", zchan->span_id, zchan->chan_id, zap_sig_status2str(status)); + + memset(&sig, 0, sizeof(sig)); + sig.chan_id = zchan->chan_id; + sig.span_id = zchan->span_id; + sig.channel = zchan; + sig.event_id = ZAP_SIGEVENT_SIGSTATUS_CHANGED; + sig.raw_data = &status; + sig.raw_data_len = sizeof(status); + sangoma_boost_data->signal_cb(&sig); return; } +static ZIO_CHANNEL_GET_SIG_STATUS_FUNCTION(sangoma_boost_get_sig_status) +{ + zap_sangoma_boost_data_t *sangoma_boost_data = zchan->span->signal_data; + if (!sangoma_boost_data->sigmod) { + zap_log(ZAP_LOG_ERROR, "Cannot get signaling status in boost channel with no signaling module configured\n"); + return ZAP_FAIL; + } + return sangoma_boost_data->sigmod->get_sig_status(zchan, status); +} /** * \brief Initialises an sangoma boost span from configuration variables @@ -1612,8 +1639,8 @@ static ZIO_SIG_CONFIGURE_FUNCTION(zap_sangoma_boost_configure_span) FAIL_CONFIG_RETURN(ZAP_FAIL); } sigmod_iface->pvt = lib; - sigmod_iface->set_sig_status_cb(zap_boost_sig_status_change); sigmod_iface->set_write_msg_cb(zap_boost_write_msg); + sigmod_iface->set_sig_status_cb(zap_boost_sig_status_change); hashtable_insert(g_boost_modules_hash, (void *)sigmod_iface->name, sigmod_iface, HASHTABLE_FLAG_NONE); lib = NULL; /* destroying the lib will be done when going down and NOT on FAIL_CONFIG_RETURN */ } @@ -1642,6 +1669,7 @@ static ZIO_SIG_CONFIGURE_FUNCTION(zap_sangoma_boost_configure_span) span->signal_type = ZAP_SIGTYPE_SANGOMABOOST; span->outgoing_call = sangoma_boost_outgoing_call; span->channel_request = sangoma_boost_channel_request; + span->get_sig_status = sangoma_boost_get_sig_status; span->state_map = &boost_state_map; zap_set_flag_locked(span, ZAP_SPAN_SUSPENDED); diff --git a/libs/freetdm/src/zap_io.c b/libs/freetdm/src/zap_io.c index 5141e2f524..3a623f3db7 100644 --- a/libs/freetdm/src/zap_io.c +++ b/libs/freetdm/src/zap_io.c @@ -1255,6 +1255,22 @@ OZ_DECLARE(zap_status_t) zap_channel_outgoing_call(zap_channel_t *zchan) return ZAP_FAIL; } +OZ_DECLARE(zap_status_t) zap_channel_get_sig_status(zap_channel_t *zchan, zap_channel_sig_status_t *sigstatus) +{ + zap_status_t status; + + zap_assert(zchan != NULL, ZAP_FAIL, "Null channel\n"); + zap_assert(sigstatus != NULL, ZAP_FAIL, "Null sig status"); + + if (zchan->span->get_sig_status) { + status = zchan->span->get_sig_status(zchan, sigstatus); + } else { + zap_log(ZAP_LOG_ERROR, "get_sig_status method not implemented!\n"); + } + + return ZAP_FAIL; +} + OZ_DECLARE(zap_status_t) zap_channel_done(zap_channel_t *zchan) { assert(zchan != NULL);