From 56827bc9ec2f046e265aa2b8b2c657cb2c1752ae Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 12 Sep 2006 22:23:45 +0000 Subject: [PATCH] enhance timers and make rtp use it that way git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2669 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_core.h | 14 ++++ src/include/switch_module_interfaces.h | 4 ++ src/include/switch_rtp.h | 36 +++++----- .../endpoints/mod_dingaling/mod_dingaling.c | 4 ++ src/mod/endpoints/mod_exosip/mod_exosip.c | 1 + src/mod/endpoints/mod_sofia/mod_sofia.c | 4 ++ src/mod/timers/mod_softtimer/mod_softtimer.c | 45 +++++++++++- src/switch_core.c | 20 ++++++ src/switch_rtp.c | 68 ++++++++++--------- 9 files changed, 145 insertions(+), 51 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index c0e1133657..af6d248d64 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -787,6 +787,20 @@ SWITCH_DECLARE(switch_status_t) switch_core_timer_init(switch_timer_t *timer, ch */ SWITCH_DECLARE(int) switch_core_timer_next(switch_timer_t *timer); +/*! + \brief Step the timer one step + \param timer the timer to wait on + \return the newest sample count +*/ +SWITCH_DECLARE(switch_status_t) switch_core_timer_step(switch_timer_t *timer); + +/*! + \brief Check if the current step has been exceeded + \param timer the timer to wait on + \return the newest sample count +*/ +SWITCH_DECLARE(switch_status_t) switch_core_timer_check(switch_timer_t *timer); + /*! \brief Destroy an allocated timer \param timer timer to destroy diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 8b8f1bf603..703a982a9b 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -240,6 +240,10 @@ struct switch_timer_interface { switch_status_t (*timer_init)(switch_timer_t *); /*! function to wait for one cycle to pass */ switch_status_t (*timer_next)(switch_timer_t *); + /*! function to step the timer one step */ + switch_status_t (*timer_step)(switch_timer_t *); + /*! function to check if the current step has expired */ + switch_status_t (*timer_check)(switch_timer_t *); /*! function to deallocate the timer */ switch_status_t (*timer_destroy)(switch_timer_t *); const struct switch_timer_interface *next; diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index 6bbed70fde..bdaeb9243c 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -77,13 +77,14 @@ SWITCH_DECLARE(switch_port_t) switch_rtp_request_port(void); \return the new RTP session or NULL on failure */ SWITCH_DECLARE(switch_status_t)switch_rtp_create(switch_rtp_t **new_rtp_session, - switch_payload_t payload, - uint32_t packet_size, - uint32_t ms_per_packet, - switch_rtp_flag_t flags, - char *crypto_key, - const char **err, - switch_memory_pool_t *pool); + switch_payload_t payload, + uint32_t packet_size, + uint32_t ms_per_packet, + switch_rtp_flag_t flags, + char *crypto_key, + char *timer_name, + const char **err, + switch_memory_pool_t *pool); /*! @@ -102,16 +103,17 @@ SWITCH_DECLARE(switch_status_t)switch_rtp_create(switch_rtp_t **new_rtp_session, \return the new RTP session or NULL on failure */ SWITCH_DECLARE(switch_rtp_t *)switch_rtp_new(char *rx_host, - switch_port_t rx_port, - char *tx_host, - switch_port_t tx_port, - switch_payload_t payload, - uint32_t packet_size, - uint32_t ms_per_packet, - switch_rtp_flag_t flags, - char *crypto_key, - const char **err, - switch_memory_pool_t *pool); + switch_port_t rx_port, + char *tx_host, + switch_port_t tx_port, + switch_payload_t payload, + uint32_t packet_size, + uint32_t ms_per_packet, + switch_rtp_flag_t flags, + char *crypto_key, + char *timer_name, + const char **err, + switch_memory_pool_t *pool); /*! diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 56a33d2663..0105c83636 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -102,6 +102,7 @@ struct mdl_profile { char *server; char *exten; char *context; + char *timer_name; ldl_handle_t *handle; uint32_t flags; uint32_t user_flags; @@ -343,6 +344,7 @@ static int activate_rtp(struct private_object *tech_pvt) tech_pvt->read_codec.implementation->microseconds_per_frame, flags, NULL, + tech_pvt->profile->timer_name, &err, switch_core_session_get_pool(tech_pvt->session)))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "RTP ERROR %s\n", err); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); @@ -1326,6 +1328,8 @@ static void set_profile_val(struct mdl_profile *profile, char *var, char *val) profile->extip = switch_core_strdup(module_pool, val); } else if (!strcasecmp(var, "server")) { profile->server = switch_core_strdup(module_pool, val); + } else if (!strcasecmp(var, "rtp-timer-name")) { + profile->timer_name = switch_core_strdup(module_pool, val); } else if (!strcasecmp(var, "lanaddr")) { profile->lanaddr = switch_core_strdup(module_pool, val); } else if (!strcasecmp(var, "tls")) { diff --git a/src/mod/endpoints/mod_exosip/mod_exosip.c b/src/mod/endpoints/mod_exosip/mod_exosip.c index c9cbdcb4a6..dc10213c81 100644 --- a/src/mod/endpoints/mod_exosip/mod_exosip.c +++ b/src/mod/endpoints/mod_exosip/mod_exosip.c @@ -585,6 +585,7 @@ static switch_status_t activate_rtp(struct private_object *tech_pvt) ms, flags, key, + "soft", &err, switch_core_session_get_pool(tech_pvt->session)); if (switch_rtp_ready(tech_pvt->rtp_session)) { diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 769f958ae7..19bb50bc88 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -111,6 +111,7 @@ struct sofia_profile { char *username; char *url; char *sipdomain; + char *timer_name; int sip_port; char *codec_string; char *codec_order[SWITCH_MAX_CODECS]; @@ -697,6 +698,7 @@ static switch_status_t activate_rtp(private_object_t *tech_pvt) tech_pvt->codec_ms * 1000, (switch_rtp_flag_t) flags, NULL, + tech_pvt->profile->timer_name, &err, switch_core_session_get_pool(tech_pvt->session)); @@ -1698,6 +1700,8 @@ static switch_status_t config_sofia(int reload) profile->sipip = switch_core_strdup(profile->pool, val); } else if (!strcmp(var, "sip-domain")) { profile->sipdomain = switch_core_strdup(profile->pool, val); + } else if (!strcmp(var, "rtp-timer-name")) { + profile->timer_name = switch_core_strdup(profile->pool, val); } else if (!strcmp(var, "ext-sip-ip")) { profile->extsipip = switch_core_strdup(profile->pool, val); } else if (!strcmp(var, "bitpacking")) { diff --git a/src/mod/timers/mod_softtimer/mod_softtimer.c b/src/mod/timers/mod_softtimer/mod_softtimer.c index 3a30e5713e..e9b79f5b53 100644 --- a/src/mod/timers/mod_softtimer/mod_softtimer.c +++ b/src/mod/timers/mod_softtimer/mod_softtimer.c @@ -48,7 +48,7 @@ struct timer_private { #endif }; -static switch_status_t soft_timer_init(switch_timer_t *timer) +static inline switch_status_t soft_timer_init(switch_timer_t *timer) { struct timer_private *private; @@ -65,7 +65,7 @@ static switch_status_t soft_timer_init(switch_timer_t *timer) return SWITCH_STATUS_SUCCESS; } -static switch_status_t soft_timer_next(switch_timer_t *timer) +static inline switch_status_t soft_timer_next(switch_timer_t *timer) { struct timer_private *private = timer->private_info; @@ -91,7 +91,44 @@ static switch_status_t soft_timer_next(switch_timer_t *timer) return SWITCH_STATUS_SUCCESS; } -static switch_status_t soft_timer_destroy(switch_timer_t *timer) +static inline switch_status_t soft_timer_step(switch_timer_t *timer) +{ + struct timer_private *private = timer->private_info; +#ifdef WINTIMER + private->base.QuadPart += timer->interval * (private->freq.QuadPart / 1000); +#else + private->reference += timer->interval * 1000; +#endif + + return SWITCH_STATUS_SUCCESS; +} + + +static inline switch_status_t soft_timer_check(switch_timer_t *timer) + +{ + struct timer_private *private = timer->private_info; +#ifdef WINTIMER + QueryPerformanceCounter(&private->now); + if (private->now.QuadPart >= private->base.QuadPart) { + private->base.QuadPart += timer->interval * (private->freq.QuadPart / 1000); + return SWITCH_STATUS_SUCCESS; + } else { + return SWITCH_STATUS_FALSE; + } +#else + if (switch_time_now() < private->reference) { + return SWITCH_STATUS_FALSE; + } else { + private->reference += timer->interval * 1000; + return SWITCH_STATUS_SUCCESS; + } +#endif + +} + + +static inline switch_status_t soft_timer_destroy(switch_timer_t *timer) { timer->private_info = NULL; return SWITCH_STATUS_SUCCESS; @@ -101,6 +138,8 @@ static const switch_timer_interface_t soft_timer_interface = { /*.interface_name */ "soft", /*.timer_init */ soft_timer_init, /*.timer_next */ soft_timer_next, + /*.timer_step */ soft_timer_step, + /*.timer_check */ soft_timer_check, /*.timer_destroy */ soft_timer_destroy }; diff --git a/src/switch_core.c b/src/switch_core.c index 0b8f55c500..c7db02a095 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1050,6 +1050,26 @@ SWITCH_DECLARE(int) switch_core_timer_next(switch_timer_t *timer) } +SWITCH_DECLARE(switch_status_t) switch_core_timer_step(switch_timer_t *timer) +{ + if (!timer->timer_interface) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timer is not initilized!\n"); + return SWITCH_STATUS_GENERR; + } + + return timer->timer_interface->timer_step(timer); +} + +SWITCH_DECLARE(switch_status_t) switch_core_timer_check(switch_timer_t *timer) +{ + if (!timer->timer_interface) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timer is not initilized!\n"); + return SWITCH_STATUS_GENERR; + } + + return timer->timer_interface->timer_check(timer); +} + SWITCH_DECLARE(switch_status_t) switch_core_timer_destroy(switch_timer_t *timer) { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index a6020cfe05..a45ff985df 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -161,7 +161,6 @@ struct switch_rtp { uint32_t packet_size; uint32_t rpacket_size; switch_time_t last_read; - switch_time_t next_read; uint32_t ms_per_packet; uint32_t remote_port; uint8_t stuncount; @@ -171,6 +170,7 @@ struct switch_rtp { uint8_t mini; switch_payload_t te; switch_mutex_t *flag_mutex; + switch_timer_t timer; }; static int global_init = 0; @@ -353,13 +353,14 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_ } SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session, - switch_payload_t payload, - uint32_t packet_size, - uint32_t ms_per_packet, - switch_rtp_flag_t flags, - char *crypto_key, - const char **err, - switch_memory_pool_t *pool) + switch_payload_t payload, + uint32_t packet_size, + uint32_t ms_per_packet, + switch_rtp_flag_t flags, + char *crypto_key, + char *timer_name, + const char **err, + switch_memory_pool_t *pool) { switch_rtp_t *rtp_session = NULL; srtp_policy_t policy; @@ -456,7 +457,6 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session rtp_session->payload = payload; rtp_session->ms_per_packet = ms_per_packet; rtp_session->packet_size = packet_size; - rtp_session->next_read = switch_time_now() + rtp_session->ms_per_packet; if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_SECURE)) { err_status_t stat; @@ -473,26 +473,33 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session } } + if (!timer_name) { + timer_name = "soft"; + } + + switch_core_timer_init(&rtp_session->timer, timer_name, ms_per_packet / 1000, packet_size, rtp_session->pool); + *new_rtp_session = rtp_session; return SWITCH_STATUS_SUCCESS; } SWITCH_DECLARE(switch_rtp_t *)switch_rtp_new(char *rx_host, - switch_port_t rx_port, - char *tx_host, - switch_port_t tx_port, - switch_payload_t payload, - uint32_t packet_size, - uint32_t ms_per_packet, - switch_rtp_flag_t flags, - char *crypto_key, - const char **err, - switch_memory_pool_t *pool) + switch_port_t rx_port, + char *tx_host, + switch_port_t tx_port, + switch_payload_t payload, + uint32_t packet_size, + uint32_t ms_per_packet, + switch_rtp_flag_t flags, + char *crypto_key, + char *timer_name, + const char **err, + switch_memory_pool_t *pool) { switch_rtp_t *rtp_session; - if (switch_rtp_create(&rtp_session, payload, packet_size, ms_per_packet, flags, crypto_key, err, pool) != SWITCH_STATUS_SUCCESS) { + if (switch_rtp_create(&rtp_session, payload, packet_size, ms_per_packet, flags, crypto_key, timer_name, err, pool) != SWITCH_STATUS_SUCCESS) { return NULL; } @@ -573,6 +580,10 @@ SWITCH_DECLARE(void) switch_rtp_destroy(switch_rtp_t **rtp_session) srtp_dealloc((*rtp_session)->send_ctx); } + if ((*rtp_session)->timer.timer_interface) { + switch_core_timer_destroy(&(*rtp_session)->timer); + } + return; } @@ -714,6 +725,10 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ for(;;) { bytes = sizeof(rtp_msg_t); status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock, 0, (void *)&rtp_session->recv_msg, &bytes); + + if (!SWITCH_STATUS_IS_BREAK(status)) { + switch_core_timer_step(&rtp_session->timer); + } if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_BREAK)) { switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_BREAK); @@ -773,17 +788,9 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } } } - - if ((switch_time_now() - rtp_session->next_read) > 1000) { + if (switch_core_timer_check(&rtp_session->timer) == SWITCH_STATUS_SUCCESS) { do_2833(rtp_session); - - /* Set the next waypoint */ - if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_TIMER_RECLOCK)) { - rtp_session->next_read = switch_time_now() + rtp_session->ms_per_packet; - } else { - rtp_session->next_read += rtp_session->ms_per_packet; - } - + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) { /* We're late! We're Late!*/ if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_NOBLOCK) && status == SWITCH_STATUS_BREAK) { @@ -877,7 +884,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } rtp_session->last_read = switch_time_now(); - rtp_session->next_read += rtp_session->ms_per_packet; *payload_type = rtp_session->recv_msg.header.pt;