[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