]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[ftmod_libpri] Use FTDM_SPAN_USE_PROCEED_STATE and rework state handling.
authorStefan Knoblich <s.knoblich@axsentis.de>
Thu, 13 Jan 2011 22:09:51 +0000 (23:09 +0100)
committerStefan Knoblich <s.knoblich@axsentis.de>
Thu, 13 Jan 2011 22:28:00 +0000 (23:28 +0100)
- Use the newly introduced FTDM_SPAN_USE_PROCEED_STATE flag and FTDM_CHANNEL_STATE_PROCEED.

- Update ftmod_libpri's state machine table (taken from ftmod_sangoma_isdn).

- Move pri_destroycall() to HANGUP_COMPLETE state.

- Try to get a little bit closer to the ISDN states by using pri_acknowledge() in RINGING,
  pri_progress() in PROGRESS and pri_proceeding() in PROCEED state.

- Go to PROGRESS_MEDIA in on_progress() only if there is inband indication available, go to
  PROGRESS if not.

- Go to RINGING state in on_ringing() and remove PROGRESS_MEDIA check.

NOTE: One libpri error message and a VETO (PROGRESS -> RINGING) warning to investigate,
      but changes seem to work fine nonetheless.

Tested-by: SparFux (#freeswitch / #freeswitch-de @ irc.freenode.net)
Signed-off-by: Stefan Knoblich <s.knoblich@axsentis.de>
libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c

index 8be6d579e168914fda26ac90221da8c38d197ad5..2f9c70a48d9cdbb815cfa3846156592f7e57cc8a 100644 (file)
@@ -406,25 +406,36 @@ static ftdm_state_map_t isdn_state_map = {
                        ZSD_OUTBOUND,
                        ZSM_UNACCEPTABLE,
                        {FTDM_CHANNEL_STATE_DIALING, FTDM_END},
-                       {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
+                       {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
+                        FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS,
+                        FTDM_CHANNEL_STATE_UP, FTDM_END}
                },
                {
                        ZSD_OUTBOUND,
                        ZSM_UNACCEPTABLE,
-                       {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
-                       {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_END}
+                       {FTDM_CHANNEL_STATE_PROCEED, FTDM_END},
+                       {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
+                        FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
                },
                {
                        ZSD_OUTBOUND,
                        ZSM_UNACCEPTABLE,
-                       {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
-                       {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
+                       {FTDM_CHANNEL_STATE_RINGING, FTDM_END},
+                       {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
+                        FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
                },
                {
                        ZSD_OUTBOUND,
                        ZSM_UNACCEPTABLE,
-                       {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
-                       {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
+                       {FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
+                       {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
+                        FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_END}
+               },
+               {
+                       ZSD_OUTBOUND,
+                       ZSM_UNACCEPTABLE,
+                       {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
+                       {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_END}
                },
                {
                        ZSD_OUTBOUND,
@@ -432,6 +443,24 @@ static ftdm_state_map_t isdn_state_map = {
                        {FTDM_CHANNEL_STATE_UP, FTDM_END},
                        {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
                },
+               {
+                       ZSD_OUTBOUND,
+                       ZSM_UNACCEPTABLE,
+                       {FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
+                       {FTDM_CHANNEL_STATE_HANGUP, FTDM_END}
+               },
+               {
+                       ZSD_OUTBOUND,
+                       ZSM_UNACCEPTABLE,
+                       {FTDM_CHANNEL_STATE_HANGUP, FTDM_END},
+                       {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
+               },
+               {
+                       ZSD_OUTBOUND,
+                       ZSM_UNACCEPTABLE,
+                       {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
+                       {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
+               },
 
                /****************************************/
                {
@@ -462,26 +491,33 @@ static ftdm_state_map_t isdn_state_map = {
                        ZSD_INBOUND,
                        ZSM_UNACCEPTABLE,
                        {FTDM_CHANNEL_STATE_RING, FTDM_END},
-                       {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}
+                       {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_END}
                },
                {
                        ZSD_INBOUND,
                        ZSM_UNACCEPTABLE,
-                       {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
-                       {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END},
+                       {FTDM_CHANNEL_STATE_PROCEED, FTDM_END},
+                       {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS,
+                        FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}
                },
                {
                        ZSD_INBOUND,
                        ZSM_UNACCEPTABLE,
-                       {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
-                       {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
+                       {FTDM_CHANNEL_STATE_RINGING, FTDM_END},
+                       {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA,
+                        FTDM_CHANNEL_STATE_UP, FTDM_END}
                },
                {
                        ZSD_INBOUND,
                        ZSM_UNACCEPTABLE,
-                       {FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
-                       {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 
-                        FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_UP, FTDM_END},
+                       {FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
+                       {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}
+               },
+               {
+                       ZSD_INBOUND,
+                       ZSM_UNACCEPTABLE,
+                       {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
+                       {FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_UP, FTDM_END}
                },
                {
                        ZSD_INBOUND,
@@ -489,6 +525,24 @@ static ftdm_state_map_t isdn_state_map = {
                        {FTDM_CHANNEL_STATE_UP, FTDM_END},
                        {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
                },
+               {
+                       ZSD_INBOUND,
+                       ZSM_UNACCEPTABLE,
+                       {FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
+                       {FTDM_CHANNEL_STATE_HANGUP, FTDM_END},
+               },
+               {
+                       ZSD_INBOUND,
+                       ZSM_UNACCEPTABLE,
+                       {FTDM_CHANNEL_STATE_HANGUP, FTDM_END},
+                       {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
+               },
+               {
+                       ZSD_INBOUND,
+                       ZSM_UNACCEPTABLE,
+                       {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
+                       {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
+               },
        }
 };
 
@@ -533,8 +587,6 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
                break;
 
        case FTDM_CHANNEL_STATE_PROGRESS:
-       /* RINGING is an alias for PROGRESS state in inbound calls ATM */
-       case FTDM_CHANNEL_STATE_RINGING:
                {
                        if (ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) {
                                sig.event_id = FTDM_SIGEVENT_PROGRESS;
@@ -542,7 +594,23 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
                                        ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP);
                                }
                        } else if (call) {
-                               pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1);
+                               pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0);
+                       } else {
+                               ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART);
+                       }
+               }
+               break;
+
+       case FTDM_CHANNEL_STATE_RINGING:
+               {
+                       if (ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) {
+                               sig.event_id = FTDM_SIGEVENT_RINGING;
+                               if ((status = ftdm_span_send_signal(ftdm_channel_get_span(chan), &sig) != FTDM_SUCCESS)) {
+                                       ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP);
+                               }
+                       } else if (call) {
+//                             pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1);
+                               pri_acknowledge(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1);
                        } else {
                                ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART);
                        }
@@ -561,7 +629,26 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
                                if (!ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) {
                                        ftdm_channel_open_chan(chan);
                                }
-                               pri_proceeding(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1);
+                               pri_progress(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 1);
+                       } else {
+                               ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART);
+                       }
+               }
+               break;
+
+       case FTDM_CHANNEL_STATE_PROCEED:
+               {
+                       if (ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) {
+                               /* PROCEED from other end, notify user */
+                               sig.event_id = FTDM_SIGEVENT_PROCEED;
+                               if ((status = ftdm_span_send_signal(ftdm_channel_get_span(chan), &sig) != FTDM_SUCCESS)) {
+                                       ftdm_log(FTDM_LOG_ERROR, "Failed to send PROCEED sigevent on Channel %d:%d\n",
+                                               ftdm_channel_get_span_id(chan),
+                                               ftdm_channel_get_id(chan));
+                                       ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP);
+                               }
+                       } else if (call) {
+                               pri_proceeding(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0);
                        } else {
                                ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RESTART);
                        }
@@ -572,11 +659,12 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
                {
                        /*
                         * This needs more auditing for BRI PTMP:
-                        * does pri_acknowledge() steal the call from other devices?
+                        * does pri_acknowledge() steal the call from other devices? (yes, it does)
                         */
                        if (!ftdm_test_flag(chan, FTDM_CHANNEL_OUTBOUND)) {
                                if (call) {
-                                       pri_acknowledge(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0);
+                                       pri_proceeding(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0);
+//                                     pri_acknowledge(isdn_data->spri.pri, call, ftdm_channel_get_id(chan), 0);
                                        sig.event_id = FTDM_SIGEVENT_START;
                                        if ((status = ftdm_span_send_signal(ftdm_channel_get_span(chan), &sig) != FTDM_SUCCESS)) {
                                                ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP);
@@ -690,15 +778,22 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
                                ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
 
                                pri_hangup(isdn_data->spri.pri, call, caller_data->hangup_cause);
-                               pri_destroycall(isdn_data->spri.pri, call);
+//                             pri_destroycall(isdn_data->spri.pri, call);
 
                                chan->call_data = NULL;
                        }
-                       ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_DOWN);
+                       ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
                }
                break;
 
        case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
+               {
+                       if (call) {
+                               pri_destroycall(isdn_data->spri.pri, call);
+                               chan->call_data = NULL;
+                       }
+                       ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_DOWN);
+               }
                break;
 
        case FTDM_CHANNEL_STATE_TERMINATING:
@@ -869,7 +964,7 @@ static int on_proceeding(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_
                        }
                }
                ftdm_log(FTDM_LOG_DEBUG, "-- Proceeding on channel %d:%d\n", ftdm_span_get_id(span), pevent->proceeding.channel);
-               ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
+               ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROCEED);
        } else {
                ftdm_log(FTDM_LOG_DEBUG, "-- Proceeding on channel %d:%d but it's not in the span?\n",
                                                ftdm_span_get_id(span), pevent->proceeding.channel);
@@ -909,9 +1004,12 @@ static int on_progress(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ev
                                ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_TERMINATING);
                                goto out;
                        }
+                       ftdm_log(FTDM_LOG_DEBUG, "-- Progress on channel %d:%d with media\n", ftdm_span_get_id(span), pevent->proceeding.channel);
+                       ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
+               } else {
+                       ftdm_log(FTDM_LOG_DEBUG, "-- Progress on channel %d:%d\n", ftdm_span_get_id(span), pevent->proceeding.channel);
+                       ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS);
                }
-               ftdm_log(FTDM_LOG_DEBUG, "-- Progress on channel %d:%d\n", ftdm_span_get_id(span), pevent->proceeding.channel);
-               ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
        } else {
                ftdm_log(FTDM_LOG_DEBUG, "-- Progress on channel %d:%d but it's not in the span?\n",
                                                ftdm_span_get_id(span), pevent->proceeding.channel);
@@ -936,10 +1034,10 @@ static int on_ringing(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_eve
                ftdm_log(FTDM_LOG_DEBUG, "-- Ringing on channel %d:%d\n", ftdm_span_get_id(span), pevent->ringing.channel);
 
                /* we may get on_ringing even when we're already in FTDM_CHANNEL_STATE_PROGRESS_MEDIA */
-               if (ftdm_channel_get_state(chan) == FTDM_CHANNEL_STATE_PROGRESS_MEDIA) {
-                       /* dont try to move to STATE_PROGRESS to avoid annoying veto warning */
-                       return 0;
-               }
+//             if (ftdm_channel_get_state(chan) == FTDM_CHANNEL_STATE_PROGRESS_MEDIA) {
+//                     /* dont try to move to STATE_PROGRESS to avoid annoying veto warning */
+//                     return 0;
+//             }
 
                /* Open channel if inband information is available */
                if ((pevent->ringing.progressmask & PRI_PROG_INBAND_AVAILABLE) && !ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) {
@@ -959,7 +1057,8 @@ static int on_ringing(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_eve
                                goto out;
                        }
                }
-               ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS);
+//             ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_PROGRESS);
+               ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RINGING);
        } else {
                ftdm_log(FTDM_LOG_DEBUG, "-- Ringing on channel %d:%d but it's not in the span?\n",
                        ftdm_span_get_id(span), pevent->ringing.channel);
@@ -1913,6 +2012,9 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span)
        span->get_channel_sig_status = isdn_get_channel_sig_status;
        span->get_span_sig_status = isdn_get_span_sig_status;
 
+       /* move calls to PROCEED state when they hit dialplan (ROUTING state in FreeSWITCH) */
+       ftdm_set_flag(span, FTDM_SPAN_USE_PROCEED_STATE);
+
        if ((isdn_data->opts & FTMOD_LIBPRI_OPT_SUGGEST_CHANNEL)) {
                span->channel_request = isdn_channel_request;
                ftdm_set_flag(span, FTDM_SPAN_SUGGEST_CHAN_ID);