[asterisk-commits] mmichelson: branch mmichelson/subscription_abstraction r416417 - in /team/mmi...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jun 16 13:31:25 CDT 2014


Author: mmichelson
Date: Mon Jun 16 13:31:19 2014
New Revision: 416417

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=416417
Log:
Commit more progress.

At this point, res_pjsip_mwi and res_pjsip_pubsub
compile.

The plan for the moment:

1) Fill in stubs in res_pjsip_pubsub.c
2) Test MWI.
3) Correct bugs found from MWI tests.
4) Convert res_pjsip_exten_state.
5) Test presence.
6) Correct bugs found from presence tests.
7) Address remaining TODOs in code.
8) Re-test.


Modified:
    team/mmichelson/subscription_abstraction/include/asterisk/res_pjsip_pubsub.h
    team/mmichelson/subscription_abstraction/res/res_pjsip_mwi.c
    team/mmichelson/subscription_abstraction/res/res_pjsip_pubsub.c

Modified: team/mmichelson/subscription_abstraction/include/asterisk/res_pjsip_pubsub.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/subscription_abstraction/include/asterisk/res_pjsip_pubsub.h?view=diff&rev=416417&r1=416416&r2=416417
==============================================================================
--- team/mmichelson/subscription_abstraction/include/asterisk/res_pjsip_pubsub.h (original)
+++ team/mmichelson/subscription_abstraction/include/asterisk/res_pjsip_pubsub.h Mon Jun 16 13:31:19 2014
@@ -34,6 +34,15 @@
  */
 struct ast_sip_publication;
 
+enum ast_sip_publish_state {
+    /*! Publication has just been initialized */
+    AST_SIP_PUBLISH_STATE_INITIALIZED,
+    /*! Publication is currently active */
+    AST_SIP_PUBLISH_STATE_ACTIVE,
+    /*! Publication has been terminated */
+    AST_SIP_PUBLISH_STATE_TERMINATED,
+};
+
 /*!
  * \brief Callbacks that publication handlers will define
  */
@@ -47,60 +56,38 @@
 	/*!
 	 * \brief Called when a PUBLISH to establish a new publication arrives.
 	 *
-	 * \param endpoint The endpoint from whom the PUBLISH arrived
-	 * \param rdata The PUBLISH request
-	 * \retval NULL PUBLISH was not accepted
-	 * \retval non-NULL New publication
-	 *
-	 * \note The callback is expected to send a response for the PUBLISH in success cases.
-	 */
-	struct ast_sip_publication *(*new_publication)(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata);
-
-	/*!
-	 * \brief Called when a PUBLISH for an existing publication arrives.
-	 *
-	 * This PUBLISH may be intending to change state or it may be simply renewing
-	 * the publication since the publication is nearing expiration. The callback
-	 * is expected to send a response to the PUBLISH.
-	 *
-	 * \param pub The publication on which the PUBLISH arrived
-	 * \param rdata The PUBLISH request
-	 * \retval 0 Publication was accepted
-	 * \retval non-zero Publication was denied
-	 *
-	 * \note The callback is expected to send a response for the PUBLISH.
-	 */
-	int (*publish_refresh)(struct ast_sip_publication *pub, pjsip_rx_data *rdata);
-
+	 * \param endpoint The endpoint from whom the PUBLISH arrived.
+	 * \param resource The resource whose state is being published.
+	 * \return Response code for the incoming PUBLISH
+	 */
+	int (*new_publication)(struct ast_sip_endpoint *endpoint, const char *resource);
 	/*!
 	 * \brief Called when a publication has reached its expiration.
 	 */
 	void (*publish_expire)(struct ast_sip_publication *pub);
-
-	/*!
-	 * \brief Called when a PUBLISH arrives to terminate a publication.
-	 *
-	 * \param pub The publication that is terminating
-	 * \param rdata The PUBLISH request terminating the publication
-	 *
-	 * \note The callback is expected to send a response for the PUBLISH.
-	 */
-	void (*publish_termination)(struct ast_sip_publication *pub, pjsip_rx_data *rdata);
-
+	/*!
+	 * \brief Published resource has changed states.
+	 *
+	 * The state parameter can be used to take further action. For instance,
+	 * if the state is AST_SIP_PUBLISH_STATE_INITIALIZED, then this is the initial
+	 * PUBLISH request. This is a good time to set up datastores on the publication
+	 * or any other initial needs.
+	 *
+	 * AST_SIP_PUBLISH_STATE_TERMINATED is used when the remote end is terminating
+	 * its publication. This is a good opportunity to free any resources associated with
+	 * the publication.
+	 *
+	 * AST_SIP_PUBLISH_STATE_ACTIVE is used when a publication that modifies state
+	 * arrives.
+	 *
+	 * \param pub The publication whose state has changed
+	 * \param body The body of the inbound PUBLISH
+	 * \param state The state of the publication
+	 */
+	int (*publication_state_change)(struct ast_sip_publication *pub, pjsip_msg_body *body,
+			enum ast_sip_publish_state state);
 	AST_LIST_ENTRY(ast_sip_publish_handler) next;
 };
-
-/*!
- * \brief Create a new publication
- *
- * Publication handlers should call this when a PUBLISH arrives to establish a new publication.
- *
- * \param endpoint The endpoint from whom the PUBLISHes arrive
- * \param rdata The PUBLISH that established the publication
- * \retval NULL Failed to create a publication
- * \retval non-NULL The newly-created publication
- */
-struct ast_sip_publication *ast_sip_create_publication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata);
 
 /*!
  * \brief Given a publication, get the associated endpoint
@@ -110,29 +97,6 @@
  * \retval non-NULL The associated endpoint
  */
 struct ast_sip_endpoint *ast_sip_publication_get_endpoint(struct ast_sip_publication *pub);
-
-/*!
- * \brief Create a response to an inbound PUBLISH
- *
- * The created response must be sent using ast_sip_publication_send_response
- *
- * \param pub The publication
- * \param status code The status code to place in the response
- * \param rdata The request to which the response is being made
- * \param[out] tdata The created response
- */
-int ast_sip_publication_create_response(struct ast_sip_publication *pub, int status_code, pjsip_rx_data *rdata,
-	pjsip_tx_data **tdata);
-
-/*!
- * \brief Send a response for an inbound PUBLISH
- *
- * \param pub The publication
- * \param rdata The request to which the response was made
- * \param tdata The response to the request
- */
-pj_status_t ast_sip_publication_send_response(struct ast_sip_publication *pub, pjsip_rx_data *rdata,
-	pjsip_tx_data *tdata);
 
 /*!
  * \brief Register a publish handler
@@ -257,8 +221,7 @@
 	 * \param resource The name of the resource to which the subscription is being made
 	 * \return The response code to send to the SUBSCRIBE.
 	 */
-	struct ast_sip_subscription *(*new_subscribe)(struct ast_sip_endpoint *endpoint,
-			const char *resource);
+	int (*new_subscribe)(struct ast_sip_endpoint *endpoint, const char *resource);
 	/*!
 	 * \brief The subscription is in need of a NOTIFY request.
 	 *
@@ -273,8 +236,10 @@
 	 *
 	 * \param sub The subscription to send the NOTIFY on.
 	 * \param reason The reason why the NOTIFY is being sent.
-	 */
-	void (notify_required)(struct ast_sip_subscription *sub, enum ast_sip_subscription_notify_reason reason);
+	 * \retval 0 Success
+	 * \retval -1 Failure
+	 */
+	int (*notify_required)(struct ast_sip_subscription *sub, enum ast_sip_subscription_notify_reason reason);
 };
 
 struct ast_sip_subscriber {
@@ -293,7 +258,7 @@
 	 * \param body The body of the NOTIFY
 	 * \param state The subscription state
 	 */
-	void (*state_change)(struct ast_sip_subscription *sub, const char *body, enum pjsip_evsub_state state);
+	void (*state_change)(struct ast_sip_subscription *sub, pjsip_msg_body *body, enum pjsip_evsub_state state);
 };
 
 struct ast_sip_subscription_handler {
@@ -317,7 +282,7 @@
 	/*! Subscriber callbacks for this handler */
 	struct ast_sip_subscriber *subscriber;
 	/*! Notifier callbacks for this handler */
-	struct ast_sip_subscriber *notifier;
+	struct ast_sip_notifier *notifier;
 	AST_LIST_ENTRY(ast_sip_subscription_handler) next;
 };
 
@@ -380,7 +345,9 @@
 void ast_sip_subscription_get_remote_uri(struct ast_sip_subscription *sub, char *buf, size_t size);
  
 /*! Terminate an active SIP subscription. */
-void ast_sip_subscription_terminate(struct ast_sip_subscripiton *sub);
+void ast_sip_subscription_terminate(struct ast_sip_subscription *sub);
+
+const char *ast_sip_subscription_get_resource_name(struct ast_sip_subscription *sub);
 
 /*!
  * \brief Accept a subscription request
@@ -463,30 +430,17 @@
 void ast_sip_subscription_remove_datastore(struct ast_sip_subscription *subscription, const char *name);
 
 /*!
- * \brief Register a notifier
- *
- * \retval 0 Notifier was registered successfully
- * \retval non-zero Notifier was not registered successfully
- */
-int ast_sip_register_notifier(struct ast_sip_notifier *notifier);
-
-/*!
- * \brief Unregister a notifier
- */
-void ast_sip_unregister_notifier(struct ast_sip_notifier *notifier);
-
-/*!
- * \brief Register a subscriber
- *
- * \retval 0 Subscriber was registered successfully
- * \retval non-zero Subscriber was not registered successfully
- */
-int ast_sip_register_subscriber(struct ast_sip_subscriber *subscriber);
-
-/*!
- * \brief Unregister a subscriber
- */
-void ast_sip_unregister_subscriber(struct ast_sip_subscriber *subscriber);
+ * \brief Register a subscription handler
+ *
+ * \retval 0 Handler was registered successfully
+ * \retval non-zero Handler was not registered successfully
+ */
+int ast_sip_register_subscription_handler(struct ast_sip_subscription_handler *handler);
+
+/*!
+ * \brief Unregister a subscription handler
+ */
+void ast_sip_unregister_subscription_handler(struct ast_sip_subscription_handler *handler);
 
 /*!
  * \brief Pubsub body generator

Modified: team/mmichelson/subscription_abstraction/res/res_pjsip_mwi.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/subscription_abstraction/res/res_pjsip_mwi.c?view=diff&rev=416417&r1=416416&r2=416417
==============================================================================
--- team/mmichelson/subscription_abstraction/res/res_pjsip_mwi.c (original)
+++ team/mmichelson/subscription_abstraction/res/res_pjsip_mwi.c Mon Jun 16 13:31:19 2014
@@ -49,31 +49,23 @@
 #define MWI_SUBTYPE "simple-message-summary"
 
 static void mwi_subscription_shutdown(struct ast_sip_subscription *sub);
-static struct ast_sip_subscription *mwi_new_subscribe(struct ast_sip_endpoint *endpoint,
-		pjsip_rx_data *rdata);
-static void mwi_resubscribe(struct ast_sip_subscription *sub, pjsip_rx_data *rdata,
-		struct ast_sip_subscription_response_data *response_data);
-static void mwi_subscription_timeout(struct ast_sip_subscription *sub);
-static void mwi_subscription_terminated(struct ast_sip_subscription *sub, pjsip_rx_data *rdata);
-static void mwi_notify_response(struct ast_sip_subscription *sub, pjsip_rx_data *rdata);
-static void mwi_notify_request(struct ast_sip_subscription *sub, pjsip_rx_data *rdata,
-		struct ast_sip_subscription_response_data *response_data);
-static int mwi_refresh_subscription(struct ast_sip_subscription *sub);
 static void mwi_to_ami(struct ast_sip_subscription *sub, struct ast_str **buf);
+static int mwi_new_subscribe(struct ast_sip_endpoint *endpoint,
+		const char *resource);
+static int mwi_notify_required(struct ast_sip_subscription *sip_sub,
+		enum ast_sip_subscription_notify_reason reason);
+
+static struct ast_sip_notifier mwi_notifier = {
+	.default_accept = MWI_TYPE"/"MWI_SUBTYPE,
+	.new_subscribe = mwi_new_subscribe,
+	.notify_required = mwi_notify_required,
+};
 
 static struct ast_sip_subscription_handler mwi_handler = {
 	.event_name = "message-summary",
-	.accept = { MWI_TYPE"/"MWI_SUBTYPE, },
-	.default_accept =  MWI_TYPE"/"MWI_SUBTYPE,
 	.subscription_shutdown = mwi_subscription_shutdown,
-	.new_subscribe = mwi_new_subscribe,
-	.resubscribe = mwi_resubscribe,
-	.subscription_timeout = mwi_subscription_timeout,
-	.subscription_terminated = mwi_subscription_terminated,
-	.notify_response = mwi_notify_response,
-	.notify_request = mwi_notify_request,
-	.refresh_subscription = mwi_refresh_subscription,
 	.to_ami = mwi_to_ami,
+	.notifier = &mwi_notifier,
 };
 
 /*!
@@ -202,7 +194,7 @@
 }
 
 static struct mwi_subscription *mwi_subscription_alloc(struct ast_sip_endpoint *endpoint,
-		enum ast_sip_subscription_role role, unsigned int is_solicited, pjsip_rx_data *rdata)
+		unsigned int is_solicited, struct ast_sip_subscription *sip_sub)
 {
 	struct mwi_subscription *sub;
 	const char *endpoint_id = ast_sorcery_object_get_id(endpoint);
@@ -216,6 +208,7 @@
 
 	/* Safe strcpy */
 	strcpy(sub->id, endpoint_id);
+
 	/* Unsolicited MWI doesn't actually result in a SIP subscription being
 	 * created. This is because a SIP subscription associates with a dialog.
 	 * Most devices expect unsolicited MWI NOTIFYs to appear out of dialog. If
@@ -224,13 +217,7 @@
 	 * state not being updated on the device
 	 */
 	if (is_solicited) {
-		sub->sip_sub = ast_sip_create_subscription(&mwi_handler,
-				role, endpoint, rdata);
-		if (!sub->sip_sub) {
-			ast_log(LOG_WARNING, "Unable to create MWI SIP subscription for endpoint %s\n", sub->id);
-			ao2_cleanup(sub);
-			return NULL;
-		}
+		sub->sip_sub = ao2_bump(sip_sub);
 	}
 
 	sub->stasis_subs = ao2_container_alloc(STASIS_BUCKETS, stasis_sub_hash, stasis_sub_cmp);
@@ -314,7 +301,6 @@
 	struct mwi_subscription *sub;
 	struct ast_sip_endpoint *endpoint;
 	pjsip_evsub_state state;
-	const char *reason;
 	const struct ast_sip_body *body;
 };
 
@@ -324,7 +310,6 @@
 	struct mwi_subscription *sub = mwi_data->sub;
 	struct ast_sip_endpoint *endpoint = mwi_data->endpoint;
 	pjsip_evsub_state state = mwi_data->state;
-	const char *reason = mwi_data->reason;
 	const struct ast_sip_body *body = mwi_data->body;
 	struct ast_sip_contact *contact = obj;
 	const char *state_name;
@@ -358,9 +343,6 @@
 
 	sub_state = pjsip_sub_state_hdr_create(tdata->pool);
 	pj_cstr(&sub_state->sub_state, state_name);
-	if (reason) {
-		pj_cstr(&sub_state->reason_param, reason);
-	}
 	pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) sub_state);
 
 	event = pjsip_event_hdr_create(tdata->pool);
@@ -374,13 +356,15 @@
 	return 0;
 }
 
-static void send_unsolicited_mwi_notify(struct mwi_subscription *sub, pjsip_evsub_state state, const char *reason,
-		struct ast_sip_body *body)
+static void send_unsolicited_mwi_notify(struct mwi_subscription *sub,
+		struct ast_sip_message_accumulator *counter)
 {
 	RAII_VAR(struct ast_sip_endpoint *, endpoint, ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(),
 				"endpoint", sub->id), ao2_cleanup);
 	char *endpoint_aors;
 	char *aor_name;
+	struct ast_sip_body body;
+	struct ast_str *body_text;
 
 	if (!endpoint) {
 		ast_log(LOG_WARNING, "Unable to send unsolicited MWI to %s because endpoint does not exist\n",
@@ -393,7 +377,27 @@
 		return;
 	}
 
+	body.type = MWI_TYPE;
+	body.subtype = MWI_SUBTYPE;
+
+	body_text = ast_str_create(64);
+
+	if (!body_text) {
+		return;
+	}
+
+	if (ast_sip_pubsub_generate_body_content(body.type, body.subtype, counter, &body_text)) {
+		ast_log(LOG_WARNING, "Unable to generate SIP MWI NOTIFY body.\n");
+		ast_free(body_text);
+		return;
+	}
+
+	body.body_text = ast_str_buffer(body_text);
+
 	endpoint_aors = ast_strdupa(endpoint->aors);
+
+	ast_debug(5, "Sending unsolicited MWI NOTIFY to endpoint %s, new messages: %d, old messages: %d\n",
+			sub->id, counter->new_msgs, counter->old_msgs);
 
 	while ((aor_name = strsep(&endpoint_aors, ","))) {
 		RAII_VAR(struct ast_sip_aor *, aor, ast_sip_location_retrieve_aor(aor_name), ao2_cleanup);
@@ -401,9 +405,7 @@
 		struct unsolicited_mwi_data mwi_data = {
 			.sub = sub,
 			.endpoint = endpoint,
-			.state = state,
-			.reason = reason,
-			.body = body,
+			.body = &body,
 		};
 
 		if (!aor) {
@@ -419,63 +421,25 @@
 
 		ao2_callback(contacts, OBJ_NODATA, send_unsolicited_mwi_notify_to_contact, &mwi_data);
 	}
-}
-
-static void send_mwi_notify(struct mwi_subscription *sub, pjsip_evsub_state state, const char *reason)
-{
-	const pj_str_t *reason_str_ptr = NULL;
+
+	ast_free(body_text);
+}
+
+static void send_mwi_notify(struct mwi_subscription *sub)
+{
 	struct ast_sip_message_accumulator counter = {
 		.old_msgs = 0,
 		.new_msgs = 0,
 	};
-	RAII_VAR(struct ast_str *, body_text, ast_str_create(64), ast_free_ptr);
-	pjsip_tx_data *tdata;
-	pj_str_t reason_str;
-	struct ast_sip_body body;
-
-	body.type = sub->is_solicited ?
-		ast_sip_subscription_get_body_type(sub->sip_sub) :
-		MWI_TYPE;
-
-	body.subtype = sub->is_solicited ?
-		ast_sip_subscription_get_body_subtype(sub->sip_sub) :
-		MWI_SUBTYPE;
 
 	ao2_callback(sub->stasis_subs, OBJ_NODATA, get_message_count, &counter);
 
-	if (reason) {
-		pj_cstr(&reason_str, reason);
-		reason_str_ptr = &reason_str;
-	}
-
-	if (ast_sip_pubsub_generate_body_content(body.type, body.subtype, &counter, &body_text)) {
-		ast_log(LOG_WARNING, "Unable to generate SIP MWI NOTIFY body.\n");
+	if (sub->is_solicited) {
+		ast_sip_subscription_notify(sub->sip_sub, &counter);
 		return;
 	}
 
-	body.body_text = ast_str_buffer(body_text);
-
-	ast_debug(5, "Sending %s MWI NOTIFY to endpoint %s, new messages: %d, old messages: %d\n",
-			sub->is_solicited ? "solicited" : "unsolicited", sub->id, counter.new_msgs,
-			counter.old_msgs);
-
-	if (sub->is_solicited) {
-		if (pjsip_evsub_notify(ast_sip_subscription_get_evsub(sub->sip_sub),
-					state, NULL, reason_str_ptr, &tdata) != PJ_SUCCESS) {
-			ast_log(LOG_WARNING, "Unable to create MWI NOTIFY request to %s.\n", sub->id);
-			return;
-		}
-		if (ast_sip_add_body(tdata, &body)) {
-			ast_log(LOG_WARNING, "Unable to add body to MWI NOTIFY request\n");
-			return;
-		}
-		if (ast_sip_subscription_send_request(sub->sip_sub, tdata) != PJ_SUCCESS) {
-			ast_log(LOG_WARNING, "Unable to send MWI NOTIFY request to %s\n", sub->id);
-			return;
-		}
-	} else {
-		send_unsolicited_mwi_notify(sub, state, reason, &body);
-	}
+	send_unsolicited_mwi_notify(sub, &counter);
 }
 
 static int unsubscribe_stasis(void *obj, void *arg, int flags)
@@ -620,10 +584,9 @@
 }
 
 static struct mwi_subscription *mwi_create_subscription(
-	struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
-{
-	struct mwi_subscription *sub = mwi_subscription_alloc(
-		endpoint, AST_SIP_NOTIFIER, 1, rdata);
+	struct ast_sip_endpoint *endpoint, struct ast_sip_subscription *sip_sub)
+{
+	struct mwi_subscription *sub = mwi_subscription_alloc(endpoint, 1, sip_sub);
 
 	if (!sub) {
 		return NULL;
@@ -640,7 +603,7 @@
 }
 
 static struct mwi_subscription *mwi_subscribe_single(
-	struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, const char *name)
+	struct ast_sip_endpoint *endpoint, struct ast_sip_subscription *sip_sub, const char *name)
 {
 	RAII_VAR(struct ast_sip_aor *, aor,
 		 ast_sip_location_retrieve_aor(name), ao2_cleanup);
@@ -662,7 +625,7 @@
 		return NULL;
 	}
 
-	if (!(sub = mwi_create_subscription(endpoint, rdata))) {
+	if (!(sub = mwi_create_subscription(endpoint, sip_sub))) {
 		return NULL;
 	}
 
@@ -671,7 +634,7 @@
 }
 
 static struct mwi_subscription *mwi_subscribe_all(
-	struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
+	struct ast_sip_endpoint *endpoint, struct ast_sip_subscription *sip_sub)
 {
 	struct mwi_subscription *sub;
 
@@ -679,7 +642,7 @@
 		return NULL;
 	}
 
-	sub = mwi_create_subscription(endpoint, rdata);
+	sub = mwi_create_subscription(endpoint, sip_sub);
 
 	if (!sub) {
 		return NULL;
@@ -689,106 +652,67 @@
 	return sub;
 }
 
-static struct ast_sip_subscription *mwi_new_subscribe(struct ast_sip_endpoint *endpoint,
-		pjsip_rx_data *rdata)
+static int mwi_new_subscribe(struct ast_sip_endpoint *endpoint,
+		const char *resource)
+{
+	/* The MWI notifier does not care what resource is being subscribed to. We'll happily
+	 * accept whatever resource is thrown our way.
+	 */
+	return 200;
+}
+
+static int mwi_initial_subscription(struct ast_sip_subscription *sip_sub)
 {
 	/* It's not obvious here, but the reference(s) to this subscription,
 	 * once this function exits, is held by the stasis subscription(s)
 	 * created in mwi_stasis_subscription_alloc()
 	 */
-	RAII_VAR(struct mwi_subscription *, sub, NULL, ao2_cleanup);
-	pjsip_uri *ruri = rdata->msg_info.msg->line.req.uri;
-	pjsip_sip_uri *sip_ruri;
-	char aor_name[80];
-
-	if (!PJSIP_URI_SCHEME_IS_SIP(ruri) && !PJSIP_URI_SCHEME_IS_SIPS(ruri)) {
-		ast_log(LOG_WARNING, "Attempt to SUBSCRIBE to a non-SIP URI\n");
-		return NULL;
-	}
-	sip_ruri = pjsip_uri_get_uri(ruri);
-	ast_copy_pj_str(aor_name, &sip_ruri->user, sizeof(aor_name));
+	const char *resource = ast_sip_subscription_get_resource_name(sip_sub);
+	struct mwi_subscription *sub;
+	struct ast_sip_endpoint *endpoint = ast_sip_subscription_get_endpoint(sip_sub);
 
 	/* no aor in uri? subscribe to all on endpoint */
-	if (!(sub = ast_strlen_zero(aor_name) ? mwi_subscribe_all(endpoint, rdata) :
-	      mwi_subscribe_single(endpoint, rdata, aor_name))) {
-		return NULL;
-	}
-
-	ast_sip_subscription_accept(sub->sip_sub, rdata, 200);
-	send_mwi_notify(sub, PJSIP_EVSUB_STATE_ACTIVE, NULL);
-
-	return sub->sip_sub;
-}
-
-static void mwi_resubscribe(struct ast_sip_subscription *sub,
-		pjsip_rx_data *rdata, struct ast_sip_subscription_response_data *response_data)
+	if (ast_strlen_zero(resource)) {
+		sub = mwi_subscribe_all(endpoint, sip_sub);
+	} else {
+		sub = mwi_subscribe_single(endpoint, sip_sub, resource);
+	}
+
+	if (!sub) {
+		return -1;
+	}
+
+	send_mwi_notify(sub);
+	ao2_cleanup(sub);
+
+	return 0;
+}
+
+static int mwi_notify_required(struct ast_sip_subscription *sip_sub,
+		enum ast_sip_subscription_notify_reason reason)
 {
 	struct mwi_subscription *mwi_sub;
-	pjsip_evsub_state state;
-	pjsip_evsub *evsub;
-	RAII_VAR(struct ast_datastore *, mwi_datastore,
-			ast_sip_subscription_get_datastore(sub, "MWI datastore"), ao2_cleanup);
-
-	if (!mwi_datastore) {
-		return;
-	}
-
-	mwi_sub = mwi_datastore->data;
-	evsub = ast_sip_subscription_get_evsub(sub);
-	state = pjsip_evsub_get_state(evsub);
-
-	send_mwi_notify(mwi_sub, state, NULL);
-}
-
-static void mwi_subscription_timeout(struct ast_sip_subscription *sub)
-{
-	struct mwi_subscription *mwi_sub;
-	RAII_VAR(struct ast_datastore *, mwi_datastore,
-			ast_sip_subscription_get_datastore(sub, "MWI datastore"), ao2_cleanup);
-
-	if (!mwi_datastore) {
-		return;
-	}
-
-
-	mwi_sub = mwi_datastore->data;
-
-	ast_log(LOG_NOTICE, "MWI subscription for %s has timed out.\n", mwi_sub->id);
-
-	send_mwi_notify(mwi_sub, PJSIP_EVSUB_STATE_TERMINATED, "timeout");
-}
-
-static void mwi_subscription_terminated(struct ast_sip_subscription *sub, pjsip_rx_data *rdata)
-{
-	struct mwi_subscription *mwi_sub;
-	RAII_VAR(struct ast_datastore *, mwi_datastore,
-			ast_sip_subscription_get_datastore(sub, "MWI datastore"), ao2_cleanup);
-
-	if (!mwi_datastore) {
-		return;
-	}
-
-	mwi_sub = mwi_datastore->data;
-
-	ast_log(LOG_NOTICE, "MWI subscription for %s has been terminated\n", mwi_sub->id);
-
-	send_mwi_notify(mwi_sub, PJSIP_EVSUB_STATE_TERMINATED, NULL);
-}
-
-static void mwi_notify_response(struct ast_sip_subscription *sub, pjsip_rx_data *rdata)
-{
-	/* We don't really care about NOTIFY responses for the moment */
-}
-
-static void mwi_notify_request(struct ast_sip_subscription *sub, pjsip_rx_data *rdata,
-		struct ast_sip_subscription_response_data *response_data)
-{
-	ast_log(LOG_WARNING, "Received an MWI NOTIFY request? This should not happen\n");
-}
-
-static int mwi_refresh_subscription(struct ast_sip_subscription *sub)
-{
-	ast_log(LOG_WARNING, "Being told to refresh an MWI subscription? This should not happen\n");
+	struct ast_datastore *mwi_datastore;
+
+	switch (reason) {
+	case AST_SIP_SUBSCRIPTION_NOTIFY_REASON_STARTED:
+		return mwi_initial_subscription(sip_sub);
+	case AST_SIP_SUBSCRIPTION_NOTIFY_REASON_RENEWED:
+	case AST_SIP_SUBSCRIPTION_NOTIFY_REASON_TERMINATED:
+	case AST_SIP_SUBSCRIPTION_NOTIFY_REASON_OTHER:
+		mwi_datastore = ast_sip_subscription_get_datastore(sip_sub, "MWI datastore");
+	
+		if (!mwi_datastore) {
+			return -1;
+		}
+	
+		mwi_sub = mwi_datastore->data;
+
+		send_mwi_notify(mwi_sub);
+		ao2_cleanup(mwi_datastore);
+		break;
+	}
+
 	return 0;
 }
 
@@ -834,7 +758,7 @@
 {
 	struct mwi_subscription *mwi_sub = userdata;
 
-	send_mwi_notify(mwi_sub, PJSIP_EVSUB_STATE_ACTIVE, NULL);
+	send_mwi_notify(mwi_sub);
 	ao2_ref(mwi_sub, -1);
 	return 0;
 }
@@ -885,7 +809,7 @@
 	}
 
 	if (endpoint->subscription.mwi.aggregate) {
-		aggregate_sub = mwi_subscription_alloc(endpoint, AST_SIP_NOTIFIER, 0, NULL);
+		aggregate_sub = mwi_subscription_alloc(endpoint, 0, NULL);
 		if (!aggregate_sub) {
 			return 0;
 		}
@@ -894,7 +818,7 @@
 	mailboxes = ast_strdupa(endpoint->subscription.mwi.mailboxes);
 	while ((mailbox = strsep(&mailboxes, ","))) {
 		struct mwi_subscription *sub = aggregate_sub ?:
-			mwi_subscription_alloc(endpoint, AST_SIP_SUBSCRIBER, 0, NULL);
+			mwi_subscription_alloc(endpoint, 0, NULL);
 		RAII_VAR(struct mwi_stasis_subscription *, mwi_stasis_sub,
 				mwi_stasis_subscription_alloc(mailbox, sub), ao2_cleanup);
 		if (mwi_stasis_sub) {

Modified: team/mmichelson/subscription_abstraction/res/res_pjsip_pubsub.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/subscription_abstraction/res/res_pjsip_pubsub.c?view=diff&rev=416417&r1=416416&r2=416417
==============================================================================
--- team/mmichelson/subscription_abstraction/res/res_pjsip_pubsub.c (original)
+++ team/mmichelson/subscription_abstraction/res/res_pjsip_pubsub.c Mon Jun 16 13:31:19 2014
@@ -319,6 +319,16 @@
 AST_RWLIST_HEAD_STATIC(body_generators, ast_sip_pubsub_body_generator);
 AST_RWLIST_HEAD_STATIC(body_supplements, ast_sip_pubsub_body_supplement);
 
+static pjsip_evsub *sip_subscription_get_evsub(struct ast_sip_subscription *sub)
+{
+	return sub->pants.real->evsub;
+}
+
+static pjsip_dialog *sip_subscription_get_dlg(struct ast_sip_subscription *sub)
+{
+	return sub->pants.real->dlg;
+}
+
 /*! \brief Destructor for subscription persistence */
 static void subscription_persistence_destroy(void *obj)
 {
@@ -345,12 +355,14 @@
 	struct subscription_persistence *persistence = ast_sorcery_alloc(ast_sip_get_sorcery(),
 		"subscription_persistence", NULL);
 
+	pjsip_dialog *dlg = sip_subscription_get_dlg(sub);
+
 	if (!persistence) {
 		return NULL;
 	}
 
 	persistence->endpoint = ast_strdup(ast_sorcery_object_get_id(sub->endpoint));
-	ast_copy_pj_str(tag, &sub->dlg->local.info->tag, sizeof(tag));
+	ast_copy_pj_str(tag, &dlg->local.info->tag, sizeof(tag));
 	persistence->tag = ast_strdup(tag);
 
 	ast_sorcery_create(ast_sip_get_sorcery(), persistence);
@@ -361,11 +373,14 @@
 static void subscription_persistence_update(struct ast_sip_subscription *sub,
 	pjsip_rx_data *rdata)
 {
+	pjsip_dialog *dlg;
+
 	if (!sub->persistence) {
 		return;
 	}
 
-	sub->persistence->cseq = sub->dlg->local.cseq;
+	dlg = sip_subscription_get_dlg(sub);
+	sub->persistence->cseq = dlg->local.cseq;
 
 	if (rdata) {
 		int expires;
@@ -445,12 +460,15 @@
 		/* If a SUBSCRIBE contains no Accept headers, then we must assume that
 		 * the default accept type for the event package is to be used.
 		 */
-		ast_copy_string(accept[0], handler->default_accept, sizeof(accept[0]));
+		ast_copy_string(accept[0], handler->notifier->default_accept, sizeof(accept[0]));
 		num_accept_headers = 1;
 	}
 
 	return find_body_generator(accept, num_accept_headers);
 }
+
+static struct ast_sip_subscription *notifier_create_subscription(const struct ast_sip_subscription_handler *handler,
+		struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata);
 
 /*! \brief Callback function to perform the actual recreation of a subscription */
 static int subscription_persistence_recreate(void *obj, void *arg, int flags)
@@ -465,6 +483,8 @@
 	struct ast_sip_pubsub_body_generator *generator;
 	int resp;
 	char *resource;
+	size_t resource_size;
+	pjsip_sip_uri *request_uri;
 
 	/* If this subscription has already expired remove it */
 	if (ast_tvdiff_ms(persistence->expires, ast_tvnow()) <= 0) {
@@ -490,6 +510,11 @@
 		ast_sorcery_delete(ast_sip_get_sorcery(), persistence);
 		return 0;
 	}
+
+	request_uri = pjsip_uri_get_uri(rdata.msg_info.msg->line.req.uri);
+	resource_size = pj_strlen(&request_uri->user) + 1;
+	resource = alloca(resource_size);
+	ast_copy_pj_str(resource, &request_uri->user, resource_size);
 
 	/* Update the expiration header with the new expiration */
 	expires_header = pjsip_msg_find_hdr(rdata.msg_info.msg, PJSIP_H_EXPIRES, rdata.msg_info.msg->hdr.next);
@@ -520,8 +545,9 @@
 	ast_sip_mod_data_set(rdata.tp_info.pool, rdata.endpt_info.mod_data,
 			pubsub_module.id, MOD_DATA_PERSISTENCE, persistence);
 
-	sub = handler->new_subscribe(endpoint, &rdata);
-	if (sub) {
+	resp = handler->notifier->new_subscribe(endpoint, resource);
+	if (resp >= 200 && resp < 300) {
+		sub = notifier_create_subscription(handler, endpoint, &rdata);
 		sub->persistence = ao2_bump(persistence);
 		subscription_persistence_update(sub, &rdata);
 	} else {
@@ -633,11 +659,11 @@
 	ast_str_append(buf, 0, "Endpoint: %s\r\n",
 		       ast_sorcery_object_get_id(sub->endpoint));
 
-	ast_copy_pj_str(str, &sub->dlg->call_id->id, sizeof(str));
+	ast_copy_pj_str(str, &sip_subscription_get_dlg(sub)->call_id->id, sizeof(str));
 	ast_str_append(buf, 0, "Callid: %s\r\n", str);
 
 	ast_str_append(buf, 0, "State: %s\r\n", pjsip_evsub_get_state_name(
-			       ast_sip_subscription_get_evsub(sub)));
+			       sip_subscription_get_evsub(sub)));
 
 	ast_callerid_merge(str, sizeof(str),
 			   S_COR(id->self.name.valid, id->self.name.str, NULL),
@@ -690,8 +716,8 @@
 	 * subscription is destroyed so that we can guarantee that our attempt to
 	 * remove the serializer will be successful.
 	 */
-	ast_sip_dialog_set_serializer(sub->dlg, NULL);
-	pjsip_dlg_dec_session(sub->dlg, &pubsub_module);
+	ast_sip_dialog_set_serializer(sip_subscription_get_dlg(sub), NULL);
+	pjsip_dlg_dec_session(sip_subscription_get_dlg(sub), &pubsub_module);
 
 	return 0;
 }
@@ -709,11 +735,12 @@
 	ao2_cleanup(sub->datastores);
 	ao2_cleanup(sub->endpoint);
 
-	if (sub->dlg) {
+	if (sip_subscription_get_dlg(sub)) {
 		ast_sip_push_task_synchronous(NULL, subscription_remove_serializer, sub);
 	}
 	ast_taskprocessor_unreference(sub->serializer);
 }
+
 
 static void pubsub_on_evsub_state(pjsip_evsub *sub, pjsip_event *event);
 static void pubsub_on_rx_refresh(pjsip_evsub *sub, pjsip_rx_data *rdata,
@@ -732,22 +759,9 @@
 	.on_server_timeout = pubsub_on_server_timeout,
 };
 
-static pjsip_evsub *allocate_evsub(const char *event, enum ast_sip_subscription_role role,
-		struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pjsip_dialog *dlg)
-{
-	pjsip_evsub *evsub;
-	if (role == AST_SIP_NOTIFIER) {
-	} else {
-		pj_str_t pj_event;
-		pj_cstr(&pj_event, event);
-		pjsip_evsub_create_uac(dlg, &pubsub_cb, &pj_event, 0, &evsub);
-	}
-	return evsub;
-}
-
 /* XXX TODO There is a lot of repeated code between the two subscription creation functions. */
 
-struct ast_sip_subscription *notifier_create_subscription(const struct ast_sip_subscription_handler *handler,
+static struct ast_sip_subscription *notifier_create_subscription(const struct ast_sip_subscription_handler *handler,
 		struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
 {
 	struct ast_sip_subscription *sub = ao2_alloc(sizeof(*sub), subscription_destructor);
@@ -770,6 +784,7 @@
 	sub->body_generator = ast_sip_mod_data_get(rdata->endpt_info.mod_data,
 			pubsub_module.id, MOD_DATA_BODY_GENERATOR);
 	sub->role = AST_SIP_NOTIFIER;
+	sub->type = SIP_SUBSCRIPTION_REAL;
 	dlg = ast_sip_create_dialog_uas(endpoint, rdata);
 	if (!dlg) {
 		ast_log(LOG_WARNING, "Unable to create dialog for SIP subscription\n");
@@ -789,14 +804,14 @@
 		dlg->remote.cseq = persistence->cseq;
 	}
 
-	pjsip_evsub_create_uas(dlg, &pubsub_cb, rdata, 0, &sub->evsub);
+	pjsip_evsub_create_uas(dlg, &pubsub_cb, rdata, 0, &sub->pants.real->evsub);
 	/* We keep a reference to the dialog until our subscription is destroyed. See
 	 * the subscription_destructor for more details
 	 */
 	pjsip_dlg_inc_session(dlg, &pubsub_module);
-	sub->dlg = dlg;
+	sub->pants.real->dlg = dlg;
 	ast_sip_dialog_set_serializer(dlg, sub->serializer);
-	pjsip_evsub_set_mod_data(sub->evsub, pubsub_module.id, sub);
+	pjsip_evsub_set_mod_data(sip_subscription_get_evsub(sub), pubsub_module.id, sub);
 	sub->endpoint = ao2_bump(endpoint);
 	sub->handler = handler;
 
@@ -826,6 +841,7 @@
 		return NULL;
 	}
 	sub->role = AST_SIP_SUBSCRIBER;
+	sub->type = SIP_SUBSCRIPTION_REAL;
 	contact = ast_sip_location_retrieve_contact_from_aor_list(endpoint->aors);
 	if (!contact || ast_strlen_zero(contact->uri)) {
 		ast_log(LOG_WARNING, "No contacts configured for endpoint %s. Unable to create SIP subsription\n",
@@ -843,14 +859,14 @@
 	}
 
 	pj_cstr(&event, handler->event_name);
-	pjsip_evsub_create_uac(dlg, &pubsub_cb, &event, 0, &sub->evsub);
+	pjsip_evsub_create_uac(dlg, &pubsub_cb, &event, 0, &sub->pants.real->evsub);
 	/* We keep a reference to the dialog until our subscription is destroyed. See
 	 * the subscription_destructor for more details
 	 */
 	pjsip_dlg_inc_session(dlg, &pubsub_module);
-	sub->dlg = dlg;
+	sub->pants.real->dlg = dlg;
 	ast_sip_dialog_set_serializer(dlg, sub->serializer);
-	pjsip_evsub_set_mod_data(sub->evsub, pubsub_module.id, sub);
+	pjsip_evsub_set_mod_data(sip_subscription_get_evsub(sub), pubsub_module.id, sub);
 	ao2_ref(endpoint, +1);
 	sub->endpoint = endpoint;
 	sub->handler = handler;
@@ -874,14 +890,26 @@
 	return sub->serializer;
 }
 
-pjsip_evsub *ast_sip_subscription_get_evsub(struct ast_sip_subscription *sub)
-{
-	return sub->evsub;
-}
-
-pjsip_dialog *ast_sip_subscription_get_dlg(struct ast_sip_subscription *sub)
-{
-	return sub->dlg;
+int ast_sip_subscription_notify(struct ast_sip_subscription *sub, void *notify_data)
+{
+	/* XXX STUB */
+	return 0;
+}
+
+void ast_sip_subscription_get_local_uri(struct ast_sip_subscription *sub, char *buf, size_t size)
+{
+	/* XXX STUB */
+}
+ 
+void ast_sip_subscription_get_remote_uri(struct ast_sip_subscription *sub, char *buf, size_t size)
+{
+	/* XXX STUB */
+}
+
+const char *ast_sip_subscription_get_resource_name(struct ast_sip_subscription *sub)
+{
+	/* XXX STUB */
+	return NULL;
 }
 
 int ast_sip_subscription_accept(struct ast_sip_subscription *sub, pjsip_rx_data *rdata, int response)
@@ -891,7 +919,7 @@
 		return 0;
 	}
 
-	return pjsip_evsub_accept(ast_sip_subscription_get_evsub(sub), rdata, response, NULL) == PJ_SUCCESS ? 0 : -1;
+	return pjsip_evsub_accept(sip_subscription_get_evsub(sub), rdata, response, NULL) == PJ_SUCCESS ? 0 : -1;
 }
 
 int ast_sip_subscription_send_request(struct ast_sip_subscription *sub, pjsip_tx_data *tdata)
@@ -900,7 +928,7 @@
 	int res;
 
 	ao2_ref(sub, +1);
-	res = pjsip_evsub_send_request(ast_sip_subscription_get_evsub(sub),
+	res = pjsip_evsub_send_request(sip_subscription_get_evsub(sub),
 			tdata) == PJ_SUCCESS ? 0 : -1;
 
 	subscription_persistence_update(sub, NULL);
@@ -908,7 +936,7 @@
 	ast_test_suite_event_notify("SUBSCRIPTION_STATE_SET",
 		"StateText: %s\r\n"
 		"Endpoint: %s\r\n",
-		pjsip_evsub_get_state_name(ast_sip_subscription_get_evsub(sub)),
+		pjsip_evsub_get_state_name(sip_subscription_get_evsub(sub)),
 		ast_sorcery_object_get_id(endpoint));
 	ao2_cleanup(sub);
 	ao2_cleanup(endpoint);
@@ -1199,6 +1227,7 @@
 	char *resource;
 	struct pjsip_sip_uri *request_uri;
 	size_t resource_size;
+	int resp;
 
 	endpoint = ast_pjsip_rdata_get_endpoint(rdata);
 	ast_assert(endpoint != NULL);
@@ -1256,7 +1285,7 @@
 	} else {
 		sub->persistence = subscription_persistence_create(sub);
 		subscription_persistence_update(sub, rdata);
-		pjsip_evsub_accept(sub->evsub, rdata, resp, NULL);
+		pjsip_evsub_accept(sip_subscription_get_evsub(sub), rdata, resp, NULL);
 		handler->notifier->notify_required(sub, AST_SIP_SUBSCRIPTION_NOTIFY_REASON_STARTED);
 	}
 
@@ -1310,10 +1339,102 @@
 	return SIP_PUBLISH_UNKNOWN;
 }
 
+/*! \brief Internal destructor for publications */
+static void publication_destroy_fn(void *obj)
+{
+	struct ast_sip_publication *publication = obj;
+
+	ast_debug(3, "Destroying SIP publication\n");
+
+	ao2_cleanup(publication->datastores);
+	ao2_cleanup(publication->endpoint);
+}
+
+static struct ast_sip_publication *sip_create_publication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
+{
+	struct ast_sip_publication *publication;
+	pjsip_expires_hdr *expires_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL);
+
+	ast_assert(endpoint != NULL);
+
+	if (!(publication = ao2_alloc(sizeof(*publication), publication_destroy_fn))) {
+		return NULL;
+	}
+
+	if (!(publication->datastores = ao2_container_alloc(DATASTORE_BUCKETS, datastore_hash, datastore_cmp))) {
+		ao2_ref(publication, -1);
+		return NULL;
+	}
+
+	publication->entity_tag = ast_atomic_fetchadd_int(&esc_etag_counter, +1);
+	ao2_ref(endpoint, +1);
+	publication->endpoint = endpoint;
+	publication->expires = expires_hdr ? expires_hdr->ivalue : DEFAULT_PUBLISH_EXPIRES;
+	publication->sched_id = -1;
+
+	return publication;
+}
+
+static int sip_publication_respond(struct ast_sip_publication *pub, int status_code,
+		pjsip_rx_data *rdata)
+{
+	pj_status_t status;
+	pjsip_tx_data *tdata;
+	pjsip_transaction *tsx;
+
+	if (pjsip_endpt_create_response(ast_sip_get_pjsip_endpoint(), rdata, status_code, NULL, &tdata) != PJ_SUCCESS) {
+		return -1;
+	}
+
+	if (PJSIP_IS_STATUS_IN_CLASS(status_code, 200)) {
+		RAII_VAR(char *, entity_tag, NULL, ast_free_ptr);
+		RAII_VAR(char *, expires, NULL, ast_free_ptr);
+
+		if ((ast_asprintf(&entity_tag, "%d", pub->entity_tag) < 0) ||
+			(ast_asprintf(&expires, "%d", pub->expires) < 0)) {
+			pjsip_tx_data_dec_ref(tdata);
+			return -1;
+		}
+
+		ast_sip_add_header(tdata, "SIP-ETag", entity_tag);
+		ast_sip_add_header(tdata, "Expires", expires);
+	}
+
+	if ((status = pjsip_tsx_create_uas(&pubsub_module, rdata, &tsx)) != PJ_SUCCESS) {
+		return -1;
+	}
+
+	pjsip_tsx_recv_msg(tsx, rdata);
+
+	if (pjsip_tsx_send_msg(tsx, tdata) != PJ_SUCCESS) {
+		return -1;
+	}
+	
+	return 0;
+}
+
 static struct ast_sip_publication *publish_request_initial(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata,
 	struct ast_sip_publish_handler *handler)
 {
-	struct ast_sip_publication *publication = handler->new_publication(endpoint, rdata);
+	struct ast_sip_publication *publication;
+	char *resource;
+	size_t resource_size;
+	pjsip_sip_uri *request_uri;
+	int resp;
+	
+	request_uri = pjsip_uri_get_uri(rdata->msg_info.msg->line.req.uri);
+	resource_size = pj_strlen(&request_uri->user) + 1;
+	resource = alloca(resource_size);
+	ast_copy_pj_str(resource, &request_uri->user, resource_size);
+	
+	resp = handler->new_publication(endpoint, resource);
+
+	if (PJSIP_IS_STATUS_IN_CLASS(resp, 200)) {
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, resp, NULL, NULL, NULL);
+		return NULL;
+	}
+
+	publication = sip_create_publication(endpoint, rdata);
 
 	if (!publication) {
 		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 503, NULL, NULL, NULL);
@@ -1321,6 +1442,14 @@
 	}
 
 	publication->handler = handler;
+	if (publication->handler->publication_state_change(publication, rdata->msg_info.msg->body,
+			AST_SIP_PUBLISH_STATE_INITIALIZED)) {
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+		ao2_cleanup(publication);
+		return NULL;
+	}
+
+	sip_publication_respond(publication, resp, rdata);
 
 	return publication;
 }
@@ -1402,14 +1531,19 @@
 			publication = publish_request_initial(endpoint, rdata, handler);
 			break;
 		case SIP_PUBLISH_REFRESH:
+			sip_publication_respond(publication, 200, rdata);
 		case SIP_PUBLISH_MODIFY:
-			if (handler->publish_refresh(publication, rdata)) {
+			if (handler->publication_state_change(publication, rdata->msg_info.msg->body,
+						AST_SIP_PUBLISH_STATE_ACTIVE)) {
 				/* If an error occurs we want to terminate the publication */
 				expires = 0;
 			}
+			sip_publication_respond(publication, 200, rdata);
 			break;
 		case SIP_PUBLISH_REMOVE:
-			handler->publish_termination(publication, rdata);
+			handler->publication_state_change(publication, rdata->msg_info.msg->body,
+					AST_SIP_PUBLISH_STATE_TERMINATED);
+			sip_publication_respond(publication, 200, rdata);
 			break;
 		case SIP_PUBLISH_UNKNOWN:
 		default:

[... 212 lines stripped ...]



More information about the asterisk-commits mailing list