[asterisk-commits] mmichelson: branch mmichelson/rls-notify r417785 - in /team/mmichelson/rls-no...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jul 2 17:16:41 CDT 2014


Author: mmichelson
Date: Wed Jul  2 17:16:36 2014
New Revision: 417785

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=417785
Log:
A start towards generating NOTIFY bodies for RLS.

This takes care of some API changes and internal changes
required for generating NOTIFYs with RLS. Changes will
be required for notifiers since they currently will
not compile.


Modified:
    team/mmichelson/rls-notify/include/asterisk/res_pjsip_pubsub.h
    team/mmichelson/rls-notify/res/res_pjsip_pubsub.c

Modified: team/mmichelson/rls-notify/include/asterisk/res_pjsip_pubsub.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/rls-notify/include/asterisk/res_pjsip_pubsub.h?view=diff&rev=417785&r1=417784&r2=417785
==============================================================================
--- team/mmichelson/rls-notify/include/asterisk/res_pjsip_pubsub.h (original)
+++ team/mmichelson/rls-notify/include/asterisk/res_pjsip_pubsub.h Wed Jul  2 17:16:36 2014
@@ -223,23 +223,29 @@
 	 */
 	int (*new_subscribe)(struct ast_sip_endpoint *endpoint, const char *resource);
 	/*!
-	 * \brief The subscription is in need of a NOTIFY request.
-	 *
-	 * A reason of AST_SIP_SUBSCRIPTION_NOTIFY_REASON_STARTED is given immediately
-	 * after a SUBSCRIBE is accepted. This is a good opportunity for the notifier to
-	 * perform setup duties such as establishing Stasis subscriptions or adding
-	 * datastores to the subscription.
-	 *
-	 * A reason of AST_SIP_SUBSCRIPTION_NOTIFY_REASON_TERMINATED is given when the
-	 * subscriber has terminated the subscription. If there are any duties that the
-	 *
-	 *
-	 * \param sub The subscription to send the NOTIFY on.
-	 * \param reason The reason why the NOTIFY is being sent.
+	 * \brief Called when an inbound subscription has been accepted.
+	 *
+	 * This is a prime opportunity for notifiers to add any notifier-specific
+	 * data to the subscription (such as datastores) that it needs to.
+	 *
+	 * \note There is no need to send a NOTIFY request when this callback
+	 * is called
+	 *
+	 * \param sub The new subscription
 	 * \retval 0 Success
 	 * \retval -1 Failure
 	 */
-	int (*notify_required)(struct ast_sip_subscription *sub, enum ast_sip_subscription_notify_reason reason);
+	int (*subscription_established)(struct ast_sip_subscription *sub);
+	/*!
+	 * \brief Supply data needed to create a NOTIFY body.
+	 *
+	 * The returned data must be an ao2 object. The caller of this function
+	 * will be responsible for decrementing the refcount of the returned object
+	 *
+	 * \param sub The subscription
+	 * \return An ao2 object that can be used to create a NOTIFY body.
+	 */
+	void *(*get_notify_data)(struct ast_sip_subscription *sub);
 };
 
 struct ast_sip_subscriber {

Modified: team/mmichelson/rls-notify/res/res_pjsip_pubsub.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/rls-notify/res/res_pjsip_pubsub.c?view=diff&rev=417785&r1=417784&r2=417785
==============================================================================
--- team/mmichelson/rls-notify/res/res_pjsip_pubsub.c (original)
+++ team/mmichelson/rls-notify/res/res_pjsip_pubsub.c Wed Jul  2 17:16:36 2014
@@ -426,6 +426,8 @@
 	AST_LIST_ENTRY(ast_sip_subscription) next;
 	/*! List of child subscriptions */
 	AST_LIST_HEAD_NOLOCK(,ast_sip_subscription) children;
+	/*! Saved NOTIFY body text for this subscription */
+	struct ast_str *body_text;
 	/*! Name of resource being subscribed to */
 	char resource[0];
 };
@@ -967,6 +969,12 @@
 	}
 	strcpy(sub->resource, resource); /* Safe */
 
+	sub->body_text = ast_str_create(128);
+	if (!sub->body_text) {
+		ao2_ref(sub, -1);
+		return NULL;
+	}
+
 	sub->datastores = ao2_container_alloc(DATASTORE_BUCKETS, datastore_hash, datastore_cmp);
 	if (!sub->datastores) {
 		ao2_ref(sub, -1);
@@ -1428,28 +1436,16 @@
 	return res;
 }
 
-int ast_sip_subscription_notify(struct ast_sip_subscription *sub, void *notify_data,
-		int terminate)
-{
+static int send_notify(struct ast_sip_subscription *sub, int terminate)
+{
+	pjsip_evsub *evsub = sip_subscription_get_evsub(sub);
+	pjsip_evsub_state state;
+	pjsip_tx_data *tdata;
 	struct ast_sip_body body = {
 		.type = ast_sip_subscription_get_body_type(sub),
 		.subtype = ast_sip_subscription_get_body_subtype(sub),
+		.body_text = ast_str_buffer(sub->body_text),
 	};
-	struct ast_str *body_text = ast_str_create(64);
-	pjsip_evsub *evsub = sip_subscription_get_evsub(sub);
-	pjsip_tx_data *tdata;
-	pjsip_evsub_state state;
-
-	if (!body_text) {
-		return -1;
-	}
-
-	if (ast_sip_pubsub_generate_body_content(body.type, body.subtype, notify_data, &body_text)) {
-		ast_free(body_text);
-		return -1;
-	}
-
-	body.body_text = ast_str_buffer(body_text);
 
 	if (terminate) {
 		state = PJSIP_EVSUB_STATE_TERMINATED;
@@ -1458,22 +1454,49 @@
 			PJSIP_EVSUB_STATE_ACTIVE : PJSIP_EVSUB_STATE_TERMINATED;
 	}
 
-	ast_log_backtrace();
-
 	if (pjsip_evsub_notify(evsub, state, NULL, NULL, &tdata) != PJ_SUCCESS) {
-		ast_free(body_text);
 		return -1;
 	}
+
 	if (ast_sip_add_body(tdata, &body)) {
-		ast_free(body_text);
 		pjsip_tx_data_dec_ref(tdata);
 		return -1;
 	}
+
 	if (sip_subscription_send_request(sub, tdata)) {
-		ast_free(body_text);
 		pjsip_tx_data_dec_ref(tdata);
 		return -1;
 	}
+}
+
+static int generate_list_body(struct ast_sip_subscription *sub)
+{
+	/* XXX This is where a multipart/related body would be created with
+	 * an RLMI part and the bodies of all child parts of the subscription.
+	 * The generated multipart/related body is then saved on sub->body_text.
+	 *
+	 * This will be added when working on ASTERISK-23867. For now, this is
+	 * just a STUB.
+	 */
+	return 0;
+}
+
+int ast_sip_subscription_notify(struct ast_sip_subscription *sub, void *notify_data,
+		int terminate)
+{
+	if (ast_sip_pubsub_generate_body_content(ast_sip_subscription_get_body_type(sub),
+				ast_sip_subscription_get_body_subtype(sub), notify_data, &sub->body_text)) {
+		return -1;
+	}
+
+	while (sub->type == SIP_SUBSCRIPTION_VIRTUAL) {
+		sub = sub->reality.virtual.parent;
+		if (generate_list_body(sub)) {
+			return -1;
+		}
+	}
+
+	send_notify(sub, terminate);
 
 	return 0;
 }
@@ -1795,6 +1818,40 @@
 	}
 
 	return generator;
+}
+
+static int generate_initial_notify(struct ast_sip_subscription *sub)
+{
+	int i;
+	struct ast_sip_subscription *child;
+	void *notify_data;
+	int res;
+
+	if (sub->handler->notifier->subscription_established(sub)) {
+		return -1;
+	}
+
+	AST_LIST_TRAVERSE(&sub->children, child, next) {
+		if (generate_initial_notify(child)) {
+			return -1;
+		}
+	}
+
+	if (!AST_LIST_EMPTY(&sub->children)) {
+		return generate_list_body(sub);
+	}
+
+	notify_data = sub->handler->notifier->get_notify_data(sub);
+	if (!notify_data) {
+		return -1;
+	}
+
+	res = ast_sip_pubsub_generate_body_content(ast_sip_subscription_get_body_type(sub),
+			ast_sip_subscription_get_body_subtype(sub), notify_data, &sub->body_text);
+
+	ao2_cleanup(notify_data);
+
+	return res;
 }
 
 static pj_bool_t pubsub_on_rx_subscribe_request(pjsip_rx_data *rdata)
@@ -1880,13 +1937,10 @@
 		sub->persistence = subscription_persistence_create(sub);
 		subscription_persistence_update(sub, rdata);
 		sip_subscription_accept(sub, rdata, resp);
-		/* XXX Currently this is calling directly into the event handler instead of traversing
-		 * the subscription tree. For single resource subscriptions, this is fine, but this will
-		 * malfunction for lists. This will be handled with ASTERISK-23869
-		 */
-		if (handler->notifier->notify_required(sub, AST_SIP_SUBSCRIPTION_NOTIFY_REASON_STARTED)) {
+		if (generate_initial_notify(sub)) {
 			pjsip_evsub_terminate(sip_subscription_get_evsub(sub), PJ_TRUE);
 		}
+		send_notify(sub, 0);
 	}
 
 	resource_tree_destroy(&tree);
@@ -2359,11 +2413,8 @@
 	} else {
 		reason = AST_SIP_SUBSCRIPTION_NOTIFY_REASON_RENEWED;
 	}
-	/* XXX Currently this is calling directly into the event handler instead of traversing
-	 * the subscription tree. For single resource subscriptions, this is fine, but this will
-	 * malfunction for lists. This will be handled with ASTERISK-23869
-	 */
-	if (sub->handler->notifier->notify_required(sub, reason)) {
+
+	if (send_notify(sub, 0)) {
 		*p_st_code = 500;
 	}
 
@@ -2415,13 +2466,7 @@
 {
 	struct ast_sip_subscription *sub = userdata;
 
-	/* XXX Currently this is calling directly into the event handler instead of traversing
-	 * the subscription tree. For single resource subscriptions, this is fine, but this will
-	 * malfunction for lists. This will be handled with ASTERISK-23869
-	 */
-	sub->handler->notifier->notify_required(sub,
-			AST_SIP_SUBSCRIPTION_NOTIFY_REASON_TERMINATED);
-
+	send_notify(sub, 1);
 	ao2_cleanup(sub);
 	return 0;
 }




More information about the asterisk-commits mailing list