*/
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
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;
\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);
/*!
\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);
/*!
char *server;
char *exten;
char *context;
+ char *timer_name;
ldl_handle_t *handle;
uint32_t flags;
uint32_t user_flags;
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);
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")) {
ms,
flags,
key,
+ "soft",
&err, switch_core_session_get_pool(tech_pvt->session));
if (switch_rtp_ready(tech_pvt->rtp_session)) {
char *username;
char *url;
char *sipdomain;
+ char *timer_name;
int sip_port;
char *codec_string;
char *codec_order[SWITCH_MAX_CODECS];
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));
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")) {
#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;
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;
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;
/*.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
};
}
+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)
{
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;
uint8_t mini;
switch_payload_t te;
switch_mutex_t *flag_mutex;
+ switch_timer_t timer;
};
static int global_init = 0;
}
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;
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;
}
}
+ 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;
}
srtp_dealloc((*rtp_session)->send_ctx);
}
+ if ((*rtp_session)->timer.timer_interface) {
+ switch_core_timer_destroy(&(*rtp_session)->timer);
+ }
+
return;
}
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);
}
}
}
-
- 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) {
}
rtp_session->last_read = switch_time_now();
- rtp_session->next_read += rtp_session->ms_per_packet;
*payload_type = rtp_session->recv_msg.header.pt;