]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
set tdm pre buffer len to 200ms by default, and set it to 0 before fax calls
authorMathieu Rene <mrene@avgs.ca>
Tue, 14 Aug 2012 20:22:31 +0000 (16:22 -0400)
committerMathieu Rene <mrene@avgs.ca>
Tue, 14 Aug 2012 20:22:31 +0000 (16:22 -0400)
libs/freetdm/mod_freetdm/tdm.c
src/mod/endpoints/mod_media_gateway/media_gateway.c
src/mod/endpoints/mod_media_gateway/media_gateway_xml.c
src/mod/endpoints/mod_media_gateway/mod_media_gateway.h

index 7f44b640a95412f191b5eb7dc99c808ba7533436..1b401d364c9c1c6c2cd9dae311a2006d0364fc24 100644 (file)
@@ -39,6 +39,7 @@ void ctdm_init(switch_loadable_module_interface_t *module_interface);
 #define kSPAN_ID "span"
 #define kCHAN_ID "chan"
 #define kSPAN_NAME "span_name"
+#define kPREBUFFER_LEN "prebuffer_len"
 
 static struct {
     switch_memory_pool_t *pool;
@@ -52,6 +53,7 @@ typedef struct {
     switch_core_session_t *session;
     switch_codec_t read_codec, write_codec;
     switch_frame_t read_frame;
+    int prebuffer_len;
     
        unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
 } ctdm_private_t;
@@ -66,6 +68,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
 static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
 static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
 static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg);
+static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event);
 static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf);
 
 
@@ -81,7 +84,8 @@ switch_io_routines_t ctdm_io_routines = {
        .outgoing_channel = channel_outgoing_channel,
        .read_frame = channel_read_frame,
        .write_frame = channel_write_frame,
-       .receive_message = channel_receive_message
+       .receive_message = channel_receive_message,
+    .receive_event = channel_receive_event
 };
 
 static void ctdm_report_alarms(ftdm_channel_t *channel)
@@ -293,7 +297,8 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
                                                                                                        switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
 {
     const char  *szchanid = switch_event_get_header(var_event, kCHAN_ID),
-                *span_name = switch_event_get_header(var_event, kSPAN_NAME);
+                *span_name = switch_event_get_header(var_event, kSPAN_NAME),
+                *szprebuffer_len = switch_event_get_header(var_event, kPREBUFFER_LEN);
     int chan_id;
     int span_id;
     switch_caller_profile_t *caller_profile;
@@ -341,6 +346,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
     tech_pvt->session = *new_session;
     tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf);
     tech_pvt->read_frame.data = tech_pvt->databuf;
+    tech_pvt->prebuffer_len = zstr(szprebuffer_len) ? 0 : atoi(szprebuffer_len);
     switch_core_session_set_private(*new_session, tech_pvt);
     
     
@@ -363,6 +369,11 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
                return SWITCH_STATUS_GENERR;
        }
     
+    if (FTDM_SUCCESS != ftdm_channel_command(chan, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tech_pvt->prebuffer_len)) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set channel pre buffer size.\n");
+               return SWITCH_STATUS_GENERR;        
+    }
+    
        switch(codec) {
         case FTDM_CODEC_ULAW:
                {
@@ -623,3 +634,25 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
     return SWITCH_STATUS_SUCCESS;
 }
 
+static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event)
+{
+    const char *command = switch_event_get_header(event, "command");
+    ctdm_private_t *tech_pvt = switch_core_session_get_private(session);
+    
+    if (!zstr(command) && !strcasecmp(command, kPREBUFFER_LEN)) {
+        const char *szval = switch_event_get_header(event, kPREBUFFER_LEN);
+        int val = !zstr(szval) ? atoi(szval) : 0;
+        
+        if (tech_pvt->prebuffer_len == val) {
+            tech_pvt->prebuffer_len = val;
+            if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tech_pvt->prebuffer_len)) {
+                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set channel pre buffer size.\n");
+                return SWITCH_STATUS_GENERR;        
+            }
+        }
+    }
+    
+    
+    return SWITCH_STATUS_SUCCESS;
+}
+
index 87201b4dbb315e7bd052157e6b3f714b0182e7d3..7387343d5235a2cdb51d50f530a7077b5f610894 100644 (file)
@@ -134,6 +134,7 @@ switch_status_t megaco_activate_termination(mg_termination_t *term)
         
         switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, kSPAN_NAME,  term->u.tdm.span_name);
         switch_event_add_header(var_event, SWITCH_STACK_BOTTOM, kCHAN_ID, "%d", term->u.tdm.channel);
+        switch_event_add_header(var_event, SWITCH_STACK_BOTTOM, kPREBUFFER_LEN, "%d", term->profile->tdm_pre_buffer_size);
     }
     
     /* Set common variables on the channel */
@@ -146,9 +147,15 @@ switch_status_t megaco_activate_termination(mg_termination_t *term)
             switch_channel_t *channel = switch_core_session_get_channel(session);
             switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "command", "media_modify");
             
-            if (term->u.rtp.t38_options) {
-                               switch_channel_set_private(channel, "t38_options", term->u.rtp.t38_options);
-                       }
+            if (term->type == MG_TERM_RTP) {
+                if (term->u.rtp.t38_options) {
+                    switch_channel_set_private(channel, "t38_options", term->u.rtp.t38_options);
+                }
+                
+                if (term->u.rtp.media_type == MGM_IMAGE) {
+                    mg_term_set_pre_buffer_size(term, 0);
+                }
+            }
             
             switch_core_session_receive_event(session, &var_event);
 
@@ -176,10 +183,10 @@ switch_status_t megaco_activate_termination(mg_termination_t *term)
         channel = switch_core_session_get_channel(session);
         switch_channel_set_private(channel, PVT_MG_TERM, term);
 
-       if (term->u.rtp.t38_options) {
-               switch_channel_set_private(channel, "t38_options", term->u.rtp.t38_options);
-       }
-       
+        if (term->type == MG_TERM_RTP && term->u.rtp.t38_options) {
+            switch_channel_set_private(channel, "t38_options", term->u.rtp.t38_options);
+        }
+        
         switch_core_event_hook_add_recv_dtmf(session, mg_on_dtmf);
                
         if (term->type == MG_TERM_TDM) {
@@ -724,6 +731,34 @@ switch_status_t megaco_peer_profile_destroy(mg_peer_profile_t **profile)
        return SWITCH_STATUS_SUCCESS;   
 }
 
+void mg_term_set_pre_buffer_size(mg_termination_t *term, int newval) 
+{
+    switch_event_t *event = NULL, *event2 = NULL;
+    switch_core_session_t *session, *session2;
+    
+    if (!zstr(term->uuid) && (session = switch_core_session_locate(term->uuid))) {
+        switch_event_create(&event, SWITCH_EVENT_CLONE);
+        
+        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "command", kPREBUFFER_LEN);
+        switch_event_add_header(event, SWITCH_STACK_BOTTOM, kPREBUFFER_LEN, "%d", newval);
+    
+        /* Propagate event to bridged session if there is one */
+        if (switch_core_session_get_partner(session, &session2) == SWITCH_STATUS_SUCCESS) {
+            switch_event_dup(&event2, event);
+            switch_core_session_receive_event(session2, &event2);
+            switch_core_session_rwunlock(session2);
+        }
+        
+        switch_core_session_receive_event(session, &event);
+        switch_core_session_rwunlock(session);
+        
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sent prebuffer_size event to [%s] to [%d ms]\n", term->uuid, newval);
+    }
+    
+done:
+    switch_event_destroy(&event);
+}
+
 /* For Emacs:
  * Local Variables:
  * mode:c
index 4d1269fea79d76009a448dec9d537d74219c09cb..d2c0e991b459b4374eeff6b83ec921e9c5ac303d 100644 (file)
@@ -288,6 +288,13 @@ static switch_xml_config_item_t *get_instructions(megaco_profile_t *profile) {
                9
        };
 
+    static switch_xml_config_int_options_t pre_buffer_len = {
+               SWITCH_TRUE,  /* enforce min */
+               0,
+               SWITCH_TRUE, /* enforce Max */
+               10000
+       };
+    
 #if 0
        static switch_xml_config_enum_item_t opt_default_codec_enum[] = {
                {  "PCMA",  MEGACO_CODEC_PCMA},
@@ -311,6 +318,7 @@ static switch_xml_config_item_t *get_instructions(megaco_profile_t *profile) {
                SWITCH_CONFIG_ITEM("rtp-port-range", SWITCH_CONFIG_STRING, CONFIG_REQUIRED, &profile->rtp_port_range, "1-65535", &switch_config_string_strdup, "", "rtp port range"),
                SWITCH_CONFIG_ITEM("rtp-termination-id-prefix", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &profile->rtp_termination_id_prefix, "", &switch_config_string_strdup, "", "rtp termination prefix"),
                SWITCH_CONFIG_ITEM("rtp-termination-id-length", SWITCH_CONFIG_INT, CONFIG_RELOADABLE, &profile->rtp_termination_id_len, "", &opt_termination_id_len, "", "rtp termination id"),
+               SWITCH_CONFIG_ITEM("rtp-pre-buffer-size", SWITCH_CONFIG_INT, CONFIG_RELOADABLE, &profile->tdm_pre_buffer_size, 200, &pre_buffer_len, "", "freetdm pre buffer size"),
                SWITCH_CONFIG_ITEM("codec-prefs", SWITCH_CONFIG_STRING, 0, &profile->codec_prefs, "", &switch_config_string_strdup, "", "codec preferences, coma-separated"),
                SWITCH_CONFIG_ITEM_END()
        };
index 62c1367f6fd475aff512f643db084809d20fe5f6..15f1cf7bed160210d652d9ac212c40c9079d69b3 100644 (file)
@@ -87,7 +87,7 @@ typedef struct mg_context_s mg_context_t;
 #define kSPAN_ID "span"
 #define kCHAN_ID "chan"
 #define kSPAN_NAME "span_name"
-
+#define kPREBUFFER_LEN "prebuffer_len"
 
 typedef struct mg_termination_s mg_termination_t;
 
@@ -200,6 +200,7 @@ struct megaco_profile_s {
        char*                                   rtp_port_range;
        char*                                   rtp_termination_id_prefix;
        int                                             rtp_termination_id_len;
+    int                     tdm_pre_buffer_size;
        char*                   peer_list[MG_MAX_PEERS];     /* MGC Peer ID LIST */
     char*                   codec_prefs;
        int                                             inact_tmr;                   /* inactivity timer value */
@@ -267,6 +268,7 @@ switch_status_t megaco_profile_destroy(megaco_profile_t **profile);
 
 uint32_t mg_rtp_request_id(megaco_profile_t *profile);
 void mg_rtp_release_id(megaco_profile_t *profile, uint32_t id);
+void mg_term_set_pre_buffer_size(mg_termination_t *term, int newval);
 
 mg_context_t *megaco_get_context(megaco_profile_t *profile, uint32_t context_id);
 mg_context_t *megaco_choose_context(megaco_profile_t *profile);
@@ -295,6 +297,9 @@ switch_status_t megaco_context_is_term_present(mg_context_t *ctx, mg_termination
 
 switch_status_t megaco_prepare_tdm_termination(mg_termination_t *term);
 switch_status_t megaco_check_tdm_termination(mg_termination_t *term);
+
+
+
 #endif /* MOD_MEGACO_H */