[asterisk-commits] file: branch file/pjsip-outbound-publish r419848 - /team/file/pjsip-outbound-...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Jul 31 08:07:50 CDT 2014
Author: file
Date: Thu Jul 31 08:07:46 2014
New Revision: 419848
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=419848
Log:
Add our own automatic refresh support.
Modified:
team/file/pjsip-outbound-publish/res/res_pjsip_outbound_publish.c
Modified: team/file/pjsip-outbound-publish/res/res_pjsip_outbound_publish.c
URL: http://svnview.digium.com/svn/asterisk/team/file/pjsip-outbound-publish/res/res_pjsip_outbound_publish.c?view=diff&rev=419848&r1=419847&r2=419848
==============================================================================
--- team/file/pjsip-outbound-publish/res/res_pjsip_outbound_publish.c (original)
+++ team/file/pjsip-outbound-publish/res/res_pjsip_outbound_publish.c Thu Jul 31 08:07:46 2014
@@ -107,6 +107,10 @@
struct ast_sip_outbound_publish_client {
/*! \brief Underlying publish client */
pjsip_publishc *client;
+ /*! \brief Timer entry for refreshing publish */
+ pj_timer_entry timer;
+ /*! \brief Configured expiration time */
+ unsigned int expiration;
/*! \brief Publisher datastores set up by handlers */
struct ao2_container *datastores;
/*! \brief Queue of outgoing publish messages to send*/
@@ -162,6 +166,57 @@
return iter;
}
+/*! \brief Helper function which cancels the refresh timer on a client */
+static void cancel_publish_refresh(struct ast_sip_outbound_publish_client *client)
+{
+ if (pj_timer_heap_cancel(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()), &client->timer)) {
+ /* The timer was successfully cancelled, drop the refcount of the client */
+ ao2_ref(client, -1);
+ }
+}
+
+/*! \brief Helper function which sets up the timer to send publication */
+static void schedule_publish_refresh(struct ast_sip_outbound_publish_client *client, pjsip_rx_data *rdata)
+{
+ pj_time_val delay = { .sec = 0, };
+ pjsip_expires_hdr *expires;
+
+ cancel_publish_refresh(client);
+
+ /* Determine when we should refresh - we favor the Expires header if possible */
+ expires = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL);
+ if (expires) {
+ delay.sec = expires->ivalue - PJSIP_PUBLISHC_DELAY_BEFORE_REFRESH;
+ }
+ if (client->expiration && ((delay.sec > client->expiration) || !delay.sec)) {
+ delay.sec = client->expiration;
+ }
+ if (delay.sec < PJSIP_PUBLISHC_DELAY_BEFORE_REFRESH) {
+ delay.sec = PJSIP_PUBLISHC_DELAY_BEFORE_REFRESH;
+ }
+
+ ao2_ref(client, +1);
+ if (pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(), &client->timer, &delay) != PJ_SUCCESS) {
+ ast_log(LOG_WARNING, "Failed to pass timed publish refresh to scheduler\n");
+ ao2_ref(client, -1);
+ }
+}
+
+/*! \brief Publish client timer callback function */
+static void sip_outbound_publish_timer_cb(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry)
+{
+ struct ast_sip_outbound_publish_client *client = entry->user_data;
+
+ ao2_lock(client);
+ if (AST_LIST_EMPTY(&client->queue)) {
+ /* If there are no outstanding messages send an empty PUBLISH message so our publication doesn't expire */
+ ast_sip_publish_client_send(client, NULL);
+ }
+ ao2_unlock(client);
+
+ ao2_ref(client, -1);
+}
+
/*! \brief Helper function which starts or stops publish clients when applicable */
static void sip_outbound_publish_synchronize(struct ast_sip_event_publisher_handler *removed)
{
@@ -192,6 +247,7 @@
/* If the publisher client has been started but it is going away stop it */
removed->stop_publishing(publish->state);
publish->state->started = 0;
+ cancel_publish_refresh(publish->state);
}
ao2_ref(publish, -1);
}
@@ -262,7 +318,10 @@
if (handler) {
handler->stop_publishing(publish->state);
}
- ao2_cleanup(publish->state);
+ if (publish->state) {
+ cancel_publish_refresh(publish->state);
+ ao2_ref(publish->state, -1);
+ }
ast_sip_auth_vector_destroy(&publish->outbound_auths);
ast_string_field_free_memory(publish);
@@ -368,7 +427,7 @@
return 0;
}
- if (pjsip_publishc_publish(client->client, PJ_TRUE, &tdata) != PJ_SUCCESS) {
+ if (pjsip_publishc_publish(client->client, PJ_FALSE, &tdata) != PJ_SUCCESS) {
goto fatal;
}
@@ -461,6 +520,8 @@
}
ao2_cleanup(state->datastores);
+
+ ast_log(LOG_NOTICE, "Destroying state\n");
}
/*!
@@ -516,6 +577,10 @@
publish->state->sending = NULL;
}
+ if (AST_LIST_EMPTY(&publish->state->queue)) {
+ schedule_publish_refresh(publish->state, param->rdata);
+ }
+
ao2_unlock(publish->state);
if (ast_sip_push_task(NULL, sip_publish_client_service_queue, ao2_bump(publish->state))) {
@@ -603,6 +668,8 @@
} else if (status != PJ_SUCCESS) {
return -1;
}
+
+ publish->state->expiration = publish->expiration;
return 0;
}
@@ -681,6 +748,9 @@
return NULL;
}
+ state->timer.user_data = state;
+ state->timer.cb = sip_outbound_publish_timer_cb;
+
return state;
}
More information about the asterisk-commits
mailing list