]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
freetdm: clean up state change macros and functions to improve logging
authorMoises Silva <moy@sangoma.com>
Mon, 17 May 2010 18:36:10 +0000 (14:36 -0400)
committerMoises Silva <moy@sangoma.com>
Mon, 17 May 2010 18:36:10 +0000 (14:36 -0400)
libs/freetdm/mod_freetdm/mod_freetdm.c
libs/freetdm/src/ftdm_io.c
libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.c
libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c
libs/freetdm/src/include/freetdm.h
libs/freetdm/src/include/private/ftdm_core.h

index b3c0b4d67d1e0962ae5b8e5f863bc8761ccde5b5..a5355b2f33c81fe4b4a1937ad18a218f615dd542 100644 (file)
@@ -830,59 +830,17 @@ static switch_status_t channel_receive_message_b(switch_core_session_t *session,
        switch (msg->message_id) {
        case SWITCH_MESSAGE_INDICATE_RINGING:
                {
-#if 0
-                       if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
-                               ftdm_set_flag(tech_pvt->ftdmchan, FTDM_CHANNEL_PROGRESS);
-                       } else {
-                               ftdm_set_state_wait(tech_pvt->ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
-                       }
-#else
                        ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROGRESS);
-#endif
                }
                break;
        case SWITCH_MESSAGE_INDICATE_PROGRESS:
                {
-#if 0
-                       if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
-                               ftdm_set_flag(tech_pvt->ftdmchan, FTDM_CHANNEL_PROGRESS);
-                               ftdm_set_flag(tech_pvt->ftdmchan, FTDM_CHANNEL_MEDIA);
-                       } else {
-                               /* Don't skip messages in the ISDN call setup
-                                * TODO: make the isdn stack smart enough to handle that itself
-                                *       until then, this is here for safety...
-                                */
-                               if (tech_pvt->ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) {
-                                       ftdm_set_state_wait(tech_pvt->ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
-                               }
-                               ftdm_set_state_wait(tech_pvt->ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
-                       }
-#else
                        ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA);
-#endif
                }
                break;
        case SWITCH_MESSAGE_INDICATE_ANSWER:
                {
-#if 0
-                       if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
-                               ftdm_set_flag(tech_pvt->ftdmchan, FTDM_CHANNEL_ANSWERED);
-                       } else {
-                               /* Don't skip messages in the ISDN call setup
-                                * TODO: make the isdn stack smart enough to handle that itself
-                                *       until then, this is here for safety...
-                                */
-                               if (tech_pvt->ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) {
-                                       ftdm_set_state_wait(tech_pvt->ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
-                               }
-                               if (tech_pvt->ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS_MEDIA) {
-                                       ftdm_set_state_wait(tech_pvt->ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
-                               }
-                               ftdm_set_state_wait(tech_pvt->ftdmchan, FTDM_CHANNEL_STATE_UP);
-                       }
-#else
                        ftdm_channel_call_answer(tech_pvt->ftdmchan);
-#endif
                }
                break;
        default:
index c34d4d18a48a972addc8f496950039513b0a8193..088bd2f093d4697a9b93dc1aa63998c9189e79b8 100644 (file)
@@ -1139,39 +1139,48 @@ static int ftdm_parse_state_map(ftdm_channel_t *ftdmchan, ftdm_channel_state_t s
        return ok;
 }
 
-FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(ftdm_channel_t *ftdmchan, ftdm_channel_state_t state, int lock)
+/* this function MUST be called with the channel lock held. If waitrq == 1, the channel will be unlocked/locked (never call it with waitrq == 1 with an lock recursivity > 1) */
+#define DEFAULT_WAIT_TIME 1000
+FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_channel_state_t state, int waitrq)
 {
        int ok = 1;
-       
+       int waitms = DEFAULT_WAIT_TIME; 
+
        if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_READY)) {
+               ftdm_log(file, func, line, FTDM_LOG_LEVEL_ERROR, "%d:%d Ignored state change request from %s to %s, the channel is not ready\n",
+                               ftdmchan->span_id, ftdmchan->chan_id,
+                               ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
                return FTDM_FAIL;
        }
 
        if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_SUSPENDED)) {
                if (state != FTDM_CHANNEL_STATE_RESTART && state != FTDM_CHANNEL_STATE_DOWN) {
+                       ftdm_log(file, func, line, FTDM_LOG_LEVEL_ERROR, "%d:%d Ignored state change request from %s to %s, span %s is suspended\n",
+                               ftdmchan->span_id, ftdmchan->chan_id,
+                               ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state), ftdmchan->span->name);
                        return FTDM_FAIL;
                }
        }
 
-       if (lock) {
-               ftdm_mutex_lock(ftdmchan->mutex);
-       }
-
        if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
-               ftdm_log(FTDM_LOG_CRIT, "Ignored state change request from %s to %s, the previous state change has not been processed yet\n",
+               ftdm_log(file, func, line, FTDM_LOG_LEVEL_ERROR, "%d:%d Ignored state change request from %s to %s, the previous state change has not been processed yet\n",
+                               ftdmchan->span_id, ftdmchan->chan_id,
                                ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
-               if (lock) {
-                       ftdm_mutex_unlock(ftdmchan->mutex);
-               }
                return FTDM_FAIL;
        }
 
+       if (ftdmchan->state == state) {
+               ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "%d:%d Why bother changing state from %s to %s\n", 
+                       ftdmchan->span_id, ftdmchan->chan_id, ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
+               return FTDM_FAIL;
+       }
 
        if (ftdmchan->span->state_map) {
                ok = ftdm_parse_state_map(ftdmchan, state, ftdmchan->span->state_map);
                goto end;
        }
 
+       /* basic core state validation (by-passed if the signaling module provides a state_map) */
        switch(ftdmchan->state) {
        case FTDM_CHANNEL_STATE_HANGUP:
        case FTDM_CHANNEL_STATE_TERMINATING:
@@ -1248,15 +1257,14 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(ftdm_channel_t *ftdmchan, ftdm_
                break;
        }
 
- end:
-
-       if (state == ftdmchan->state) {
-               ok = 0;
-       }
-       
+end:
 
        if (ok) {
-               ftdm_set_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);     
+               ftdm_log(file, func, line, FTDM_LOG_LEVEL_DEBUG, "%d:%d Changed state from %s to %s\n",
+                               ftdmchan->span_id, ftdmchan->chan_id, ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
+               ftdmchan->last_state = ftdmchan->state; 
+               ftdmchan->state = state;
+               ftdm_set_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
 
                ftdm_mutex_lock(ftdmchan->span->mutex);
                ftdm_set_flag(ftdmchan->span, FTDM_SPAN_STATE_CHANGE);
@@ -1264,13 +1272,37 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(ftdm_channel_t *ftdmchan, ftdm_
                        ftdm_queue_enqueue(ftdmchan->span->pendingchans, ftdmchan);
                }
                ftdm_mutex_unlock(ftdmchan->span->mutex);
-
-               ftdmchan->last_state = ftdmchan->state; 
-               ftdmchan->state = state;
+       } else {
+               ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "%d:%d VETO state change from %s to %s\n",
+                               ftdmchan->span_id, ftdmchan->chan_id, ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
        }
 
-       if (lock) {
+       /* there is an inherent race here between set and check of the change flag but we do not care because
+        * the flag should never last raised for more than a few ms for any state change */
+       while (waitrq && waitms > 0) {
+               /* give a chance to the signaling stack to process it */
                ftdm_mutex_unlock(ftdmchan->mutex);
+
+               ftdm_sleep(10);
+               waitms -= 10;
+
+               ftdm_mutex_lock(ftdmchan->mutex);
+               
+               /* if the flag is no longer set, the state change was processed (or is being processed) */
+               if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
+                       break;
+               }
+
+               /* if the state is no longer what we set, the state change was 
+                * obviously processed (and the current state change flag is for other state change) */
+               if (ftdmchan->state != state) {
+                       break;
+               }
+       }
+
+       if (waitms <= 0) {
+               ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "%d:%d state change from %s to %s was most likely not processed after aprox %dms\n",
+                               ftdmchan->span_id, ftdmchan->chan_id, ftdm_channel_state2str(ftdmchan->last_state), ftdm_channel_state2str(state), DEFAULT_WAIT_TIME);
        }
 
        return ok ? FTDM_SUCCESS : FTDM_FAIL;
@@ -1548,7 +1580,7 @@ static ftdm_status_t ftdm_channel_reset(ftdm_channel_t *ftdmchan)
 FT_DECLARE(ftdm_status_t) ftdm_channel_init(ftdm_channel_t *ftdmchan)
 {
        if (ftdmchan->init_state != FTDM_CHANNEL_STATE_DOWN) {
-               ftdm_set_state_locked(ftdmchan, ftdmchan->init_state);
+               ftdm_set_state(ftdmchan, ftdmchan->init_state);
                ftdmchan->init_state = FTDM_CHANNEL_STATE_DOWN;
        }
 
@@ -1765,30 +1797,31 @@ FT_DECLARE(ftdm_bool_t) ftdm_channel_call_check_done(const ftdm_channel_t *ftdmc
        return condition;
 }
 
-FT_DECLARE(ftdm_status_t) ftdm_channel_call_hold(ftdm_channel_t *ftdmchan)
+FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hold(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan)
 {
        ftdm_channel_lock(ftdmchan);
        ftdm_set_flag(ftdmchan, FTDM_CHANNEL_HOLD);
-       ftdm_set_state_wait(ftdmchan, FTDM_CHANNEL_STATE_DIALTONE);
+       ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_DIALTONE, 1);
        ftdm_channel_unlock(ftdmchan);
        return FTDM_SUCCESS;
 }
 
-FT_DECLARE(ftdm_status_t) ftdm_channel_call_unhold(ftdm_channel_t *ftdmchan)
+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_set_state_wait(ftdmchan, FTDM_CHANNEL_STATE_UP);
+               ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 1);
        }
        ftdm_channel_unlock(ftdmchan);
        return FTDM_SUCCESS;
 }
 
-FT_DECLARE(ftdm_status_t) ftdm_channel_call_answer(ftdm_channel_t *ftdmchan)
+FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan)
 {
        ftdm_channel_lock(ftdmchan);
 
        if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_ANSWERED)) {
+               ftdm_channel_unlock(ftdmchan);
                return FTDM_SUCCESS;
        }
 
@@ -1801,24 +1834,24 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_call_answer(ftdm_channel_t *ftdmchan)
        }
 
        if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) {
-               ftdm_set_state_wait(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
+               ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
        }
 
        if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS_MEDIA) {
-               ftdm_set_state_wait(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
+               ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1);
        }
 
-       ftdm_set_state_wait(ftdmchan, FTDM_CHANNEL_STATE_UP);
+       ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 1);
 
        ftdm_channel_unlock(ftdmchan);
        return FTDM_SUCCESS;
 }
 
-
-static ftdm_status_t call_hangup(ftdm_channel_t *chan)
+/* lock must be acquired by the caller! */
+static ftdm_status_t call_hangup(ftdm_channel_t *chan, const char *file, const char *func, int line)
 {
        if (chan->state != FTDM_CHANNEL_STATE_DOWN) {
-               ftdm_set_state_wait(chan, FTDM_CHANNEL_STATE_HANGUP);
+               ftdm_channel_set_state(file, func, line, chan, FTDM_CHANNEL_STATE_HANGUP, 1);
        } else {
                /* the signaling stack did not touch the state, 
                 * core is responsible from clearing flags and stuff */
@@ -1827,22 +1860,22 @@ static ftdm_status_t call_hangup(ftdm_channel_t *chan)
        return FTDM_SUCCESS;
 }
 
-FT_DECLARE(ftdm_status_t) ftdm_channel_call_hangup_with_cause(ftdm_channel_t *ftdmchan, ftdm_call_cause_t cause)
+FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup_with_cause(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_call_cause_t cause)
 {
        ftdm_channel_lock(ftdmchan);
 
        ftdmchan->caller_data.hangup_cause = cause;
        
-       call_hangup(ftdmchan);
+       call_hangup(ftdmchan, file, func, line);
 
        ftdm_channel_unlock(ftdmchan);
        return FTDM_SUCCESS;
 }
 
-FT_DECLARE(ftdm_status_t) ftdm_channel_call_hangup(ftdm_channel_t *ftdmchan)
+FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan)
 {
        ftdm_channel_lock(ftdmchan);
-       call_hangup(ftdmchan);
+       call_hangup(ftdmchan, file, func, line);
        ftdm_channel_unlock(ftdmchan);
        return FTDM_SUCCESS;
 }
@@ -1911,48 +1944,54 @@ FT_DECLARE(uint32_t) ftdm_channel_get_ph_span_id(const ftdm_channel_t *ftdmchan)
        return id;
 }
 
-FT_DECLARE(ftdm_status_t) ftdm_channel_call_indicate(ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication)
+FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication)
 {
+       ftdm_status_t status = FTDM_SUCCESS;
+       ftdm_channel_lock(ftdmchan);
        switch (indication) {
 
        /* FIXME: ring and busy cannot be used with all signaling stacks 
         * (particularly isdn stacks I think, we should emulate or just move to hangup with busy cause) */
        case FTDM_CHANNEL_INDICATE_RING:
-               ftdm_set_state_locked_wait(ftdmchan, FTDM_CHANNEL_STATE_RING);
+               ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RING, 1);
                break;
 
        case FTDM_CHANNEL_INDICATE_BUSY:
-               ftdm_set_state_locked_wait(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
+               ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_BUSY, 1);
                break;
 
        case FTDM_CHANNEL_INDICATE_PROGRESS:
                if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
-                       ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_PROGRESS);
+                       ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS);
                } else {
-                       ftdm_set_state_locked_wait(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
+                       ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
                }
                break;
 
        case FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA:
                if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
-                       ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_PROGRESS);
-                       ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_MEDIA);
+                       ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS);
+                       ftdm_set_flag(ftdmchan, FTDM_CHANNEL_MEDIA);
                } else {
                        if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) {
-                               ftdm_set_state_locked_wait(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
+                               ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
                        }
-                       ftdm_set_state_locked_wait(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
+                       ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1);
                }
                break;
 
        default:
-               ftdm_log(FTDM_LOG_WARNING, "Do not know how to indicate %d\n", indication);
-               return FTDM_FAIL;
+               ftdm_log(file, func, line, FTDM_LOG_LEVEL_WARNING, "Do not know how to indicate %d\n", indication);
+               status = FTDM_FAIL;
+               break;
        }
+
+       ftdm_channel_unlock(ftdmchan);
+
        return FTDM_SUCCESS;
 }
 
-FT_DECLARE(ftdm_status_t) ftdm_channel_call_place(ftdm_channel_t *ftdmchan)
+FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan)
 {
        ftdm_status_t status;
 
index a3396ae0ad036bcd98265eeff3e2a879ee4bd1e7..564a812496ec0ff8a8c45b098f4c2b3d212c07ab 100644 (file)
@@ -174,7 +174,7 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(r2_outgoing_call)
 
        ft_r2_clean_call(ftdmchan->call_data);
        R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN;
-       ftdm_channel_set_state(ftdmchan, FTDM_CHANNEL_STATE_DIALING, 0);
+       ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DIALING);
        ftdm_set_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND);
        R2CALL(ftdmchan)->ftdm_started = 1;
        ftdm_mutex_unlock(ftdmchan->mutex);
@@ -224,7 +224,7 @@ static void ftdm_r2_on_call_init(openr2_chan_t *r2chan)
        }
        ft_r2_clean_call(ftdmchan->call_data);
        R2CALL(ftdmchan)->chanstate = FTDM_CHANNEL_STATE_DOWN;
-       ftdm_channel_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT, 0);
+       ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
        ftdm_mutex_unlock(ftdmchan->mutex);
 
        status = ftdm_thread_create_detached(ftdm_r2_channel_run, ftdmchan);
index 69b6a22055a5fbd88784411efc38fb9ad6c195ab..572b394bf04d838e4fe875b02c81da5da15dee8e 100644 (file)
@@ -649,10 +649,10 @@ static void handle_call_start_ack(sangomabc_connection_t *mcon, sangomabc_short_
                                        ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA ||
                                        ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS) {
                                        ftdm_log(FTDM_LOG_CRIT, "FTDMCHAN CALL ACK STATE UP -> Changed to TERMINATING %d:%d\n", event_span, event_chan);
-                                       ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, 0, r);
+                                       ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, r);
                                } else if (ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP ||  ftdm_test_sflag(ftdmchan, SFLAG_HANGUP)) {
                                        ftdm_log(FTDM_LOG_CRIT, "FTDMCHAN CALL ACK STATE HANGUP  -> Changed to HANGUP COMPLETE %d:%d\n", event_span, event_chan);
-                                       ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, 0, r);
+                                       ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, r);
                                } else {
                                        ftdm_log(FTDM_LOG_CRIT, "FTDMCHAN STATE INVALID State %s on IN CALL ACK %d:%d\n",
                                                 ftdm_channel_state2str(ftdmchan->state), event_span, event_chan);
@@ -711,7 +711,7 @@ static void handle_call_done(ftdm_span_t *span, sangomabc_connection_t *mcon, sa
                        goto done;
                }
 
-               ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, 0, r);
+               ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, r);
                if (r) {
                        ftdm_mutex_unlock(ftdmchan->mutex);
                        return;
@@ -799,8 +799,8 @@ static void handle_call_start_nack(ftdm_span_t *span, sangomabc_connection_t *mc
 
                        CALL_DATA(ftdmchan)->last_event_id = event->event_id;
                        ftdm_mutex_lock(ftdmchan->mutex);
-                       ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, 0, r);
-                       if (r == FTDM_STATE_CHANGE_SUCCESS) {
+                       ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, r);
+                       if (r == FTDM_SUCCESS) {
                                ftdmchan->caller_data.hangup_cause = event->release_cause;
                        }
                        ftdm_mutex_unlock(ftdmchan->mutex);
@@ -882,10 +882,10 @@ static void handle_call_stop(ftdm_span_t *span, sangomabc_connection_t *mcon, sa
                        ftdm_mutex_unlock(ftdmchan->mutex);
                        return;
                } else {
-                       ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, 0, r);
+                       ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, r);
                }
 
-               if (r == FTDM_STATE_CHANGE_SUCCESS) {
+               if (r == FTDM_SUCCESS) {
                        ftdmchan->caller_data.hangup_cause = event->release_cause;
                }
 
@@ -928,7 +928,7 @@ static void handle_call_answer(ftdm_span_t *span, sangomabc_connection_t *mcon,
 
                } else {
                        int r = 0;
-                       ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_UP, 0, r);
+                       ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_UP, r);
                }
                ftdm_mutex_unlock(ftdmchan->mutex);
        } else {
@@ -969,11 +969,11 @@ static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, s
                                ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS) {
                                ftdm_log(FTDM_LOG_CRIT, "s%dc%d: FTDMCHAN STATE UP -> Changed to TERMINATING\n", 
                                                BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event));
-                               ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, 0, r);
+                               ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, r);
                        } else if (ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP ||  ftdm_test_sflag(ftdmchan, SFLAG_HANGUP)) {
                                ftdm_log(FTDM_LOG_CRIT, "s%dc%d: FTDMCHAN STATE HANGUP -> Changed to HANGUP COMPLETE\n", 
                                                BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event));
-                               ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, 0, r);
+                               ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, r);
                        } else if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) {
                                ftdm_log(FTDM_LOG_WARNING, "s%dc%d: Collision, hanging up incoming call\n", 
                                                BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event));
@@ -983,7 +983,7 @@ static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, s
                                 * when receiving call start nack we move the channel from DOWN to TERMINATING ( cuz we already
                                 * hangup here ) and the channel gets stuck in terminating forever. So at this point we're trusting
                                 * the other side to send the call start nack ( or proceed with the call )
-                                * ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, 0, r);
+                                * ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, r);
                                 */
                        } else {
                                ftdm_log(FTDM_LOG_ERROR, "s%dc%d: rejecting incoming call in channel state %s\n", 
@@ -1076,7 +1076,7 @@ static void handle_call_loop_start(ftdm_span_t *span, sangomabc_connection_t *mc
                return;
        }
 
-       ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP, 0, res);
+       ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP, res);
        if (res != FTDM_SUCCESS) {
                ftdm_log(FTDM_LOG_CRIT, "yay, could not set the state of the channel to IN_LOOP, loop will fail\n");
                ftdm_channel_done(ftdmchan);
@@ -1100,7 +1100,7 @@ static void handle_call_loop_stop(ftdm_span_t *span, sangomabc_connection_t *mco
        ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);
        /* even when we did not sent a msg we set this flag to avoid sending call stop in the DOWN state handler */
        ftdm_set_flag(ftdmchan, SFLAG_SENT_FINAL_MSG);
-       ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_DOWN, 0, res);
+       ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_DOWN, res);
 }
 
 /**
@@ -1627,7 +1627,7 @@ static __inline__ void check_state(ftdm_span_t *span)
                                        ftdm_mutex_lock(span->channels[j]->mutex);
                                        ftdm_clear_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE);
                                        if (susp && span->channels[j]->state != FTDM_CHANNEL_STATE_DOWN) {
-                                               ftdm_channel_set_state(span->channels[j], FTDM_CHANNEL_STATE_RESTART, 0);
+                                               ftdm_set_state(span->channels[j], FTDM_CHANNEL_STATE_RESTART);
                                        }
                                        state_advance(span->channels[j]);
                                        ftdm_channel_complete_state(span->channels[j]);
index 4754edc94610ef55f34a3da9c6df607c504a195e..cf73969862e8edc1043c3bec48b885334eaf7adc 100644 (file)
@@ -587,25 +587,46 @@ typedef enum {
 FT_DECLARE(ftdm_status_t) ftdm_global_set_queue_handler(ftdm_queue_handler_t *handler);
 
 /*! \brief Answer call */
-FT_DECLARE(ftdm_status_t) ftdm_channel_call_answer(ftdm_channel_t *ftdmchan);
+#define ftdm_channel_call_answer(ftdmchan) _ftdm_channel_call_answer(__FILE__, __FUNCTION__, __LINE__, (ftdmchan))
+
+/*! \brief Answer call recording the source code point where the it was called (see ftdm_channel_call_answer for an easy to use macro) */
+FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan);
 
 /*! \brief Place an outgoing call */
-FT_DECLARE(ftdm_status_t) ftdm_channel_call_place(ftdm_channel_t *ftdmchan);
+#define ftdm_channel_call_place(ftdmchan) _ftdm_channel_call_place(__FILE__, __FUNCTION__, __LINE__, (ftdmchan))
+
+/*! \brief Place an outgoing call recording the source code point where it was called (see ftdm_channel_call_place for an easy to use macro) */
+FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan);
 
 /*! \brief Indicate a new condition in an incoming call */
-FT_DECLARE(ftdm_status_t) ftdm_channel_call_indicate(ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication);
+#define ftdm_channel_call_indicate(ftdmchan, indication) _ftdm_channel_call_indicate(__FILE__, __FUNCTION__, __LINE__, (ftdmchan), (indication))
+
+/*! \brief Indicate a new condition in an incoming call recording the source code point where it was called (see ftdm_channel_call_indicate for an easy to use macro) */
+FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication);
 
 /*! \brief Hangup the call without cause */
-FT_DECLARE(ftdm_status_t) ftdm_channel_call_hangup(ftdm_channel_t *ftdmchan);
+#define ftdm_channel_call_hangup(ftdmchan) _ftdm_channel_call_hangup(__FILE__, __FUNCTION__, __LINE__, (ftdmchan))
+
+/*! \brief Hangup the call without cause recording the source code point where it was called (see ftdm_channel_call_hangup for an easy to use macro)*/
+FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan);
 
 /*! \brief Hangup the call with cause */
-FT_DECLARE(ftdm_status_t) ftdm_channel_call_hangup_with_cause(ftdm_channel_t *ftdmchan, ftdm_call_cause_t);
+#define ftdm_channel_call_hangup_with_cause(ftdmchan, cause) _ftdm_channel_call_hangup_with_cause(__FILE__, __FUNCTION__, __LINE__, (ftdmchan), (cause))
+
+/*! \brief Hangup the call with cause recording the source code point where it was called (see ftdm_channel_call_hangup_with_cause for an easy to use macro) */
+FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup_with_cause(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_call_cause_t);
 
 /*! \brief Put a call on hold (if supported by the signaling stack) */
-FT_DECLARE(ftdm_status_t) ftdm_channel_call_hold(ftdm_channel_t *ftdmchan);
+#define ftdm_channel_call_hold(ftdmchan) _ftdm_channel_call_hold(__FILE__, __FUNCTION__, __LINE__, (ftdmchan))
+
+/*! \brief Put a call on hold recording the source code point where it was called (see ftdm_channel_call_hold for an easy to use macro) */
+FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hold(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan);
 
 /*! \brief Unhold a call */
-FT_DECLARE(ftdm_status_t) ftdm_channel_call_unhold(ftdm_channel_t *ftdmchan);
+#define ftdm_channel_call_unhold(ftdmchan) _ftdm_channel_call_unhold(__FILE__, __FUNCTION__, __LINE__, (ftdmchan))
+
+/*! \brief Unhold a call recording the source code point where it was called (see ftdm_channel_call_unhold for an easy to use macro) */
+FT_DECLARE(ftdm_status_t) _ftdm_channel_call_unhold(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan);
 
 /*! \brief Check if the call is answered already */
 FT_DECLARE(ftdm_bool_t) ftdm_channel_call_check_answered(const ftdm_channel_t *ftdmchan);
index c1144b1e860268e3f2f45afeae2689408a5b0f2e..a900b0d8080ce38c901250544449ff737816db4b 100644 (file)
@@ -189,42 +189,23 @@ extern "C" {
 
 #define ftdm_clear_sflag_locked(obj, flag) assert(obj->mutex != NULL); ftdm_mutex_lock(obj->mutex); (obj)->sflags &= ~(flag); ftdm_mutex_unlock(obj->mutex);
 
+#define ftdm_set_state(obj, s) ftdm_channel_set_state(__FILE__, __FUNCTION__, __LINE__, obj, s, 0);                                                                    \
 
-#define ftdm_set_state_locked(obj, s) if ( obj->state == s ) {                 \
-               ftdm_log(FTDM_LOG_WARNING, "Why bother changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, ftdm_channel_state2str(obj->state), ftdm_channel_state2str(s)); \
-       } else if (ftdm_test_flag(obj, FTDM_CHANNEL_READY)) {                                                                   \
-               ftdm_channel_state_t st = obj->state;                                                                                   \
-               ftdm_channel_set_state(obj, s, 1);                                                                      \
-               if (obj->state == s) ftdm_log(FTDM_LOG_DEBUG, "Changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, ftdm_channel_state2str(st), ftdm_channel_state2str(s)); \
-               else ftdm_log(FTDM_LOG_WARNING, "VETO Changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, ftdm_channel_state2str(st), ftdm_channel_state2str(s)); \
-       }
+#define ftdm_set_state_locked(obj, s) \
+       do { \
+               ftdm_channel_lock(obj); \
+               ftdm_channel_set_state(__FILE__, __FUNCTION__, __LINE__, obj, s, 0);                                                                    \
+               ftdm_channel_unlock(obj); \
+       } while(0);
 
-#define ftdm_set_state(obj, s) if ( obj->state == s ) {                        \
-               ftdm_log(FTDM_LOG_WARNING, "Why bother changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, ftdm_channel_state2str(obj->state), ftdm_channel_state2str(s)); \
-       } else if (ftdm_test_flag(obj, FTDM_CHANNEL_READY)) {                                                                   \
-               ftdm_channel_state_t st = obj->state;                                                                                   \
-               ftdm_channel_set_state(obj, s, 0);                                                                      \
-               if (obj->state == s) ftdm_log(FTDM_LOG_DEBUG, "Changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, ftdm_channel_state2str(st), ftdm_channel_state2str(s)); \
-               else ftdm_log(FTDM_LOG_WARNING, "VETO Changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, ftdm_channel_state2str(st), ftdm_channel_state2str(s)); \
-       }
+#define ftdm_set_state_r(obj, s, r) r = ftdm_channel_set_state(__FILE__, __FUNCTION__, __LINE__, obj, s, 0);
 
 #ifdef _MSC_VER
 /* The while(0) below throws a conditional expression is constant warning */
 #pragma warning(disable:4127) 
 #endif
 
-#define ftdm_set_state_locked_wait(obj, s)                                             \
-       do {                                                                            \
-               int __safety = 100;                                                     \
-               ftdm_set_state_locked(obj, s);                                          \
-               while(__safety-- && ftdm_test_flag(obj, FTDM_CHANNEL_STATE_CHANGE)) {   \
-                       ftdm_sleep(10);                                                 \
-               }                                                                       \
-               if(!__safety) {                                                         \
-                       ftdm_log(FTDM_LOG_CRIT, "State change not completed\n");                \
-               }                                                                       \
-       } while(0);
-
+/* this macro assumes obj is locked! */
 #define ftdm_wait_for_flag_cleared(obj, flag, time)                                    \
        do {                                                                            \
                int __safety = time;                                                    \
@@ -238,23 +219,6 @@ extern "C" {
                }                                                                       \
        } while(0);
 
-#define ftdm_set_state_wait(obj, s)                                            \
-       do {                                                                            \
-               ftdm_channel_set_state(obj, s, 0);                                      \
-               ftdm_wait_for_flag_cleared(obj, FTDM_CHANNEL_STATE_CHANGE, 100);     \
-       } while(0);
-
-
-#define ftdm_set_state_r(obj, s, l, r) if ( obj->state == s ) {        \
-               if (s != FTDM_CHANNEL_STATE_HANGUP) ftdm_log(FTDM_LOG_WARNING, "Why bother changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, ftdm_channel_state2str(obj->state), ftdm_channel_state2str(s)); r = FTDM_STATE_CHANGE_SAME; \
-       } else if (ftdm_test_flag(obj, FTDM_CHANNEL_READY)) {                                   \
-               int st = obj->state;                                                                                    \
-               r = (ftdm_channel_set_state(obj, s, l) == FTDM_SUCCESS) ? FTDM_STATE_CHANGE_SUCCESS : FTDM_STATE_CHANGE_FAIL; \
-               if (obj->state == s) {ftdm_log(FTDM_LOG_DEBUG, "Changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, ftdm_channel_state2str(st), ftdm_channel_state2str(s));} \
-               else ftdm_log(FTDM_LOG_WARNING, "VETO Changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, ftdm_channel_state2str(st), ftdm_channel_state2str(s)); \
-       }
-
-
 #define ftdm_is_dtmf(key)  ((key > 47 && key < 58) || (key > 64 && key < 69) || (key > 96 && key < 101) || key == 35 || key == 42 || key == 87 || key == 119)
 
 /*!
@@ -265,13 +229,6 @@ extern "C" {
 */
 #define ftdm_copy_flags(dest, src, flags) (dest)->flags &= ~(flags);   (dest)->flags |= ((src)->flags & (flags))
 
-/*! \brief channel state change result */
-typedef enum {
-       FTDM_STATE_CHANGE_FAIL,
-       FTDM_STATE_CHANGE_SUCCESS,
-       FTDM_STATE_CHANGE_SAME,
-} ftdm_state_change_result_t;
-
 struct ftdm_stream_handle {
        ftdm_stream_handle_write_function_t write_function;
        ftdm_stream_handle_raw_write_function_t raw_write_function;
@@ -533,7 +490,8 @@ FT_DECLARE(ftdm_status_t) ftdm_fsk_data_add_checksum(ftdm_fsk_data_state_t *stat
 FT_DECLARE(ftdm_status_t) ftdm_fsk_data_add_sdmf(ftdm_fsk_data_state_t *state, const char *date, char *number);
 FT_DECLARE(ftdm_status_t) ftdm_channel_send_fsk_data(ftdm_channel_t *ftdmchan, ftdm_fsk_data_state_t *fsk_data, float db_level);
 
-FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(ftdm_channel_t *ftdmchan, ftdm_channel_state_t state, int lock);
+FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(const char *file, const char *func, int line,
+               ftdm_channel_t *ftdmchan, ftdm_channel_state_t state, int wait);
 
 FT_DECLARE(ftdm_status_t) ftdm_span_load_tones(ftdm_span_t *span, const char *mapname);
 FT_DECLARE(ftdm_time_t) ftdm_current_time_in_ms(void);