]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Support for call ID
authorDavid Yat Sin <dyatsin@sangoma.com>
Sat, 11 Dec 2010 00:14:08 +0000 (19:14 -0500)
committerDavid Yat Sin <dyatsin@sangoma.com>
Sat, 11 Dec 2010 00:14:08 +0000 (19:14 -0500)
libs/freetdm/src/ftdm_io.c
libs/freetdm/src/include/freetdm.h

index eaa25e3da554edb096aad568dc0c179bd480deb2..78ae3d2b650cfb3f7d917f7c30bcfb27a08b60f1 100644 (file)
@@ -57,11 +57,14 @@ struct tm *localtime_r(const time_t *clock, struct tm *result);
 #define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000
 #define FTDM_READ_TRACE_INDEX 0
 #define FTDM_WRITE_TRACE_INDEX 1
+#define MAX_CALLIDS 6000
 
 ftdm_time_t time_last_throttle_log = 0;
 ftdm_time_t time_current_throttle_log = 0;
 
 static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t *iter);
+static ftdm_status_t ftdm_call_set_call_id(ftdm_caller_data_t *caller_data);
+static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data);
 
 static int time_is_init = 0;
 
@@ -235,6 +238,10 @@ static struct {
        ftdm_span_t *spans;
        ftdm_group_t *groups;
        cpu_monitor_t cpu_monitor;
+       
+       ftdm_caller_data_t *call_ids[MAX_CALLIDS+1];
+       ftdm_mutex_t *call_id_mutex;
+       uint32_t last_call_id;
 } globals;
 
 enum ftdm_enum_cpu_alarm_action_flags
@@ -1896,8 +1903,6 @@ static ftdm_status_t ftdm_channel_reset(ftdm_channel_t *ftdmchan)
                ftdmchan->dtmf_off = FTDM_DEFAULT_DTMF_OFF;
        }
 
-       ftdm_call_clear_vars(&ftdmchan->caller_data);
-                       
        memset(ftdmchan->dtmf_hangup_buf, '\0', ftdmchan->span->dtmf_hangup_len);
 
        if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE)) {
@@ -2483,6 +2488,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char
 
        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;
@@ -2545,9 +2551,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
        ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel can't be done!\n");
 
        ftdm_mutex_lock(ftdmchan->mutex);
-
-       memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
-
        ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_INUSE);
        ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND);
        ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_WINK);
@@ -2587,7 +2590,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
                sigmsg.channel = ftdmchan;
                sigmsg.event_id = FTDM_SIGEVENT_RELEASED;
                ftdm_span_send_signal(ftdmchan->span, &sigmsg);
-       }
+               ftdm_call_clear_call_id(&ftdmchan->caller_data);
+       }       
 
        if (ftdmchan->txdrops || ftdmchan->rxdrops) {
                ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "channel dropped data: txdrops = %d, rxdrops = %d\n", 
@@ -2595,8 +2599,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
        }
 
        ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n");
-
-
+       memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
        ftdm_mutex_unlock(ftdmchan->mutex);
 
        return FTDM_SUCCESS;
@@ -5328,7 +5331,7 @@ static void execute_safety_hangup(void *data)
 FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
 {
        if (sigmsg->channel) {
-               ftdm_mutex_lock(sigmsg->channel->mutex);
+               ftdm_mutex_lock(sigmsg->channel->mutex);                
        }
        
        /* some core things to do on special events */
@@ -5347,6 +5350,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
 
        case FTDM_SIGEVENT_START:
                {
+                       ftdm_call_set_call_id(&sigmsg->channel->caller_data);
                        ftdm_set_echocancel_call_begin(sigmsg->channel);
                        if (sigmsg->channel->dtmfdbg.requested) {
                                ftdm_channel_command(sigmsg->channel, FTDM_COMMAND_ENABLE_DEBUG_DTMF, NULL);
@@ -5376,7 +5380,10 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
                break;  
 
        }
-       
+
+       if (sigmsg->channel) {
+               sigmsg->call_id = sigmsg->channel->caller_data.call_id;
+       }
        /* if the signaling module uses a queue for signaling notifications, then enqueue it */
        if (ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) {
                ftdm_span_queue_signal(span, sigmsg);
@@ -5471,6 +5478,7 @@ static void ftdm_cpu_monitor_stop(void)
 
 FT_DECLARE(ftdm_status_t) ftdm_global_init(void)
 {
+       int i;
        memset(&globals, 0, sizeof(globals));
 
        time_init();
@@ -5485,6 +5493,8 @@ FT_DECLARE(ftdm_status_t) ftdm_global_init(void)
        ftdm_mutex_create(&globals.mutex);
        ftdm_mutex_create(&globals.span_mutex);
        ftdm_mutex_create(&globals.group_mutex);
+       ftdm_mutex_create(&globals.call_id_mutex);
+       
        ftdm_sched_global_init();
        if (ftdm_sched_create(&globals.timingsched, "freetdm-master") != FTDM_SUCCESS) {
                ftdm_log(FTDM_LOG_CRIT, "Failed to create master timing schedule context\n");
@@ -5494,6 +5504,9 @@ FT_DECLARE(ftdm_status_t) ftdm_global_init(void)
                ftdm_log(FTDM_LOG_CRIT, "Failed to run master timing schedule context\n");
                return FTDM_FAIL;
        }
+       for(i=0;i<MAX_CALLIDS;i++) {
+               globals.call_ids[i] = NULL;
+       }
        globals.running = 1;
        return FTDM_SUCCESS;
 }
@@ -5597,6 +5610,7 @@ FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
        ftdm_mutex_destroy(&globals.mutex);
        ftdm_mutex_destroy(&globals.span_mutex);
        ftdm_mutex_destroy(&globals.group_mutex);
+       ftdm_mutex_destroy(&globals.call_id_mutex);
 
        memset(&globals, 0, sizeof(globals));
        return FTDM_SUCCESS;
@@ -5955,6 +5969,47 @@ FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan)
        return stream.data;
 }
 
+static ftdm_status_t ftdm_call_set_call_id(ftdm_caller_data_t *caller_data)
+{
+       uint32_t current_call_id;
+       ftdm_assert_return(!caller_data->call_id, FTDM_FAIL, "Overwriting non-cleared call-id");
+
+       ftdm_mutex_lock(globals.call_id_mutex);
+       current_call_id = globals.last_call_id;
+
+       do {
+               if (++current_call_id > MAX_CALLIDS) {
+                       current_call_id = 1;
+               }
+               if (globals.call_ids[current_call_id] != NULL) {
+                       continue;
+               }
+       } while (0);
+
+       globals.last_call_id = current_call_id;
+       caller_data->call_id = current_call_id;
+
+       globals.call_ids[current_call_id] = caller_data;
+       ftdm_mutex_unlock(globals.call_id_mutex);
+       return FTDM_SUCCESS;
+}
+
+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");
+       ftdm_mutex_lock(globals.call_id_mutex);
+       if (globals.call_ids[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;
+}
+
+
+
 
 /* For Emacs:
  * Local Variables:
index 4ee6ff5f52d74380f1d378dea067213361539ff6..cc32d66bdd507463a842a14d0b049d280c24bd85 100644 (file)
@@ -295,6 +295,11 @@ typedef struct ftdm_caller_data {
        /* user information layer 1 protocol */
        ftdm_user_layer1_prot_t bearer_layer1;
        ftdm_variable_container_t variables; /*!<variables attached to this call */
+       /* We need call_id inside caller_data for the user to be able to retrieve 
+        * the call_id when ftdm_channel_call_place is called. This is the only time
+        * that the user can use caller_data.call_id to obtain the call_id. The user
+        * should use the call_id from sigmsg otherwise */
+       uint32_t call_id; /*!< Unique call ID for this call */
 } ftdm_caller_data_t;
 
 /*! \brief Tone type */
@@ -381,9 +386,10 @@ struct ftdm_sigmsg {
        ftdm_channel_t *channel; /*!< Related channel */
        uint32_t chan_id; /*!< easy access to chan id */
        uint32_t span_id; /*!< easy access to span_id */
-       ftdm_signaling_status_t sigstatus; /*!< Signaling status (valid if event_id is FTDM_SIGEVENT_SIGSTATUS_CHANGED) */      
+       ftdm_signaling_status_t sigstatus; /*!< Signaling status (valid if event_id is FTDM_SIGEVENT_SIGSTATUS_CHANGED) */
        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 */
 };
 
 /*! \brief Crash policy