[svn-commits] mmichelson: branch group/rls r420357 - in /team/group/rls: ./ include/asteris...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Aug 7 12:26:39 CDT 2014


Author: mmichelson
Date: Thu Aug  7 12:26:33 2014
New Revision: 420357

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=420357
Log:
Resolve conflict and reset automerge.


Added:
    team/group/rls/include/asterisk/res_pjsip_outbound_publish.h
      - copied unchanged from r420315, trunk/include/asterisk/res_pjsip_outbound_publish.h
    team/group/rls/res/res_pjsip_outbound_publish.c
      - copied unchanged from r420315, trunk/res/res_pjsip_outbound_publish.c
    team/group/rls/res/res_pjsip_outbound_publish.exports.in
      - copied unchanged from r420315, trunk/res/res_pjsip_outbound_publish.exports.in
    team/group/rls/res/res_pjsip_publish_asterisk.c
      - copied unchanged from r420315, trunk/res/res_pjsip_publish_asterisk.c
Modified:
    team/group/rls/   (props changed)
    team/group/rls/include/asterisk/res_pjsip_pubsub.h
    team/group/rls/main/pbx.c
    team/group/rls/res/res_pjsip_pubsub.c
    team/group/rls/res/res_pjsip_pubsub.exports.in

Propchange: team/group/rls/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/group/rls/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu Aug  7 12:26:33 2014
@@ -1,1 +1,1 @@
-/trunk:1-420292
+/trunk:1-420335

Modified: team/group/rls/include/asterisk/res_pjsip_pubsub.h
URL: http://svnview.digium.com/svn/asterisk/team/group/rls/include/asterisk/res_pjsip_pubsub.h?view=diff&rev=420357&r1=420356&r2=420357
==============================================================================
--- team/group/rls/include/asterisk/res_pjsip_pubsub.h (original)
+++ team/group/rls/include/asterisk/res_pjsip_pubsub.h Thu Aug  7 12:26:33 2014
@@ -58,9 +58,10 @@
 	 *
 	 * \param endpoint The endpoint from whom the PUBLISH arrived.
 	 * \param resource The resource whose state is being published.
+	 * \param event_configuration The name of the event type configuration to use for this resource.
 	 * \return Response code for the incoming PUBLISH
 	 */
-	int (*new_publication)(struct ast_sip_endpoint *endpoint, const char *resource);
+	int (*new_publication)(struct ast_sip_endpoint *endpoint, const char *resource, const char *event_configuration);
 	/*!
 	 * \brief Called when a publication has reached its expiration.
 	 */
@@ -97,6 +98,22 @@
  * \retval non-NULL The associated endpoint
  */
 struct ast_sip_endpoint *ast_sip_publication_get_endpoint(struct ast_sip_publication *pub);
+
+/*!
+ * \brief Given a publication, get the resource the publication is to
+ *
+ * \param pub The publication
+ * \return The resource
+ */
+const char *ast_sip_publication_get_resource(const struct ast_sip_publication *pub);
+
+/*!
+ * \brief Given a publication, get the configuration name for the event type in use
+ *
+ * \param pub The publication
+ * \return The configuration name
+ */
+const char *ast_sip_publication_get_event_configuration(const struct ast_sip_publication *pub);
 
 /*!
  * \brief Register a publish handler

Modified: team/group/rls/main/pbx.c
URL: http://svnview.digium.com/svn/asterisk/team/group/rls/main/pbx.c?view=diff&rev=420357&r1=420356&r2=420357
==============================================================================
--- team/group/rls/main/pbx.c (original)
+++ team/group/rls/main/pbx.c Thu Aug  7 12:26:33 2014
@@ -11980,6 +11980,7 @@
 	const char *action_id = astman_get_header(m, "ActionID");
 	struct ast_hint *hint;
 	struct ao2_iterator it_hints;
+	int hint_count = 0;
 
 	if (!hints) {
 		astman_send_error(s, m, "No dialplan hints are available");
@@ -11993,6 +11994,18 @@
 	for (; (hint = ao2_iterator_next(&it_hints)); ao2_ref(hint, -1)) {
 
 		ao2_lock(hint);
+
+		/* Ignore pattern matching hints; they are stored in the
+		 * hints container but aren't real from the perspective of
+		 * an AMI user
+		 */
+		if (hint->exten->exten[0] == '_') {
+			ao2_unlock(hint);
+			continue;
+		}
+
+		++hint_count;
+
 		astman_append(s, "Event: ExtensionStatus\r\n");
 		if (!ast_strlen_zero(action_id)) {
 			astman_append(s, "ActionID: %s\r\n", action_id);
@@ -12015,7 +12028,7 @@
 		astman_append(s, "ActionID: %s\r\n", action_id);
 	}
 	astman_append(s, "EventList: Complete\r\n"
-		"ListItems: %d\r\n\r\n", ao2_container_count(hints));
+		"ListItems: %d\r\n\r\n", hint_count);
 
 	ao2_iterator_destroy(&it_hints);
 	ao2_unlock(hints);

Modified: team/group/rls/res/res_pjsip_pubsub.c
URL: http://svnview.digium.com/svn/asterisk/team/group/rls/res/res_pjsip_pubsub.c?view=diff&rev=420357&r1=420356&r2=420357
==============================================================================
--- team/group/rls/res/res_pjsip_pubsub.c (original)
+++ team/group/rls/res/res_pjsip_pubsub.c Thu Aug  7 12:26:33 2014
@@ -182,6 +182,15 @@
 					</description>
 				</configOption>
 			</configObject>
+			<configObject name="inbound-publication">
+				<synopsis>The configuration for inbound publications</synopsis>
+				<configOption name="endpoint" default="">
+					<synopsis>Optional name of an endpoint that is only allowed to publish to this resource</synopsis>
+				</configOption>
+				<configOption name="type">
+					<synopsis>Must be of type 'inbound-publication'.</synopsis>
+				</configOption>
+			</configObject>
 		</configFile>
 	</configInfo>
  ***/
@@ -317,6 +326,12 @@
 	int expires;
 	/*! \brief Scheduled item for expiration of publication */
 	int sched_id;
+	/*! \brief The resource the publication is to */
+	char *resource;
+	/*! \brief The name of the event type configuration */
+	char *event_configuration_name;
+	/*! \brief Data containing the above */
+	char data[0];
 };
 
 
@@ -430,6 +445,18 @@
 	char resource[0];
 };
 
+/*!
+ * \brief Structure representing a publication resource
+ */
+struct ast_sip_publication_resource {
+	/*! \brief Sorcery object details */
+	SORCERY_OBJECT(details);
+	/*! \brief Optional name of an endpoint that is only allowed to publish to this resource */
+	char *endpoint;
+	/*! \brief Mapping for event types to configuration */
+	struct ast_variable *events;
+};
+
 static const char *sip_subscription_roles_map[] = {
 	[AST_SIP_SUBSCRIBER] = "Subscriber",
 	[AST_SIP_NOTIFIER] = "Notifier"
@@ -456,6 +483,21 @@
 	} else {
 		return sub->reality.real.dlg;
 	}
+}
+
+/*! \brief Destructor for publication resource */
+static void publication_resource_destroy(void *obj)
+{
+	struct ast_sip_publication_resource *resource = obj;
+
+	ast_free(resource->endpoint);
+	ast_variables_destroy(resource->events);
+}
+
+/*! \brief Allocator for publication resource */
+static void *publication_resource_alloc(const char *name)
+{
+	return ast_sorcery_generic_alloc(sizeof(struct ast_sip_publication_resource), publication_resource_destroy);
 }
 
 /*! \brief Destructor for subscription persistence */
@@ -1650,7 +1692,7 @@
 
 void ast_sip_subscription_remove_datastore(struct ast_sip_subscription *subscription, const char *name)
 {
-	ao2_callback(subscription->datastores, OBJ_KEY | OBJ_UNLINK | OBJ_NODATA, NULL, (void *) name);
+	ao2_find(subscription->datastores, name, OBJ_SEARCH_KEY | OBJ_UNLINK | OBJ_NODATA);
 }
 
 int ast_sip_publication_add_datastore(struct ast_sip_publication *publication, struct ast_datastore *datastore)
@@ -2010,14 +2052,17 @@
 	ao2_cleanup(publication->endpoint);
 }
 
-static struct ast_sip_publication *sip_create_publication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
+static struct ast_sip_publication *sip_create_publication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata,
+	const char *resource, const char *event_configuration_name)
 {
 	struct ast_sip_publication *publication;
 	pjsip_expires_hdr *expires_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL);
+	size_t resource_len = strlen(resource) + 1, event_configuration_name_len = strlen(event_configuration_name) + 1;
+	char *dst;
 
 	ast_assert(endpoint != NULL);
 
-	if (!(publication = ao2_alloc(sizeof(*publication), publication_destroy_fn))) {
+	if (!(publication = ao2_alloc(sizeof(*publication) + resource_len + event_configuration_name_len, publication_destroy_fn))) {
 		return NULL;
 	}
 
@@ -2031,6 +2076,10 @@
 	publication->endpoint = endpoint;
 	publication->expires = expires_hdr ? expires_hdr->ivalue : DEFAULT_PUBLISH_EXPIRES;
 	publication->sched_id = -1;
+	dst = publication->data;
+	publication->resource = strcpy(dst, resource);
+	dst += resource_len;
+	publication->event_configuration_name = strcpy(dst, event_configuration_name);
 
 	return publication;
 }
@@ -2077,8 +2126,10 @@
 	struct ast_sip_publish_handler *handler)
 {
 	struct ast_sip_publication *publication;
-	char *resource;
+	char *resource_name;
 	size_t resource_size;
+	RAII_VAR(struct ast_sip_publication_resource *, resource, NULL, ao2_cleanup);
+	struct ast_variable *event_configuration_name = NULL;
 	pjsip_uri *request_uri;
 	pjsip_sip_uri *request_uri_sip;
 	int resp;
@@ -2096,17 +2147,39 @@
 
 	request_uri_sip = pjsip_uri_get_uri(request_uri);
 	resource_size = pj_strlen(&request_uri_sip->user) + 1;
-	resource = alloca(resource_size);
-	ast_copy_pj_str(resource, &request_uri_sip->user, resource_size);
-
-	resp = handler->new_publication(endpoint, resource);
-
-	if (PJSIP_IS_STATUS_IN_CLASS(resp, 200)) {
+	resource_name = alloca(resource_size);
+	ast_copy_pj_str(resource_name, &request_uri_sip->user, resource_size);
+
+	resource = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "inbound-publication", resource_name);
+	if (!resource) {
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 404, NULL, NULL, NULL);
+		return NULL;
+	}
+
+	if (!ast_strlen_zero(resource->endpoint) && strcmp(resource->endpoint, ast_sorcery_object_get_id(endpoint))) {
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
+		return NULL;
+	}
+
+	for (event_configuration_name = resource->events; event_configuration_name; event_configuration_name = event_configuration_name->next) {
+		if (!strcmp(event_configuration_name->name, handler->event_name)) {
+			break;
+		}
+	}
+
+	if (!event_configuration_name) {
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 404, NULL, NULL, NULL);
+		return NULL;
+	}
+
+	resp = handler->new_publication(endpoint, resource_name, event_configuration_name->value);
+
+	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);
+	publication = sip_create_publication(endpoint, rdata, S_OR(resource_name, ""), event_configuration_name->value);
 
 	if (!publication) {
 		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 503, NULL, NULL, NULL);
@@ -2130,7 +2203,9 @@
 {
 	RAII_VAR(struct ast_sip_publication *, publication, data, ao2_cleanup);
 
-	publication->handler->publish_expire(publication);
+	if (publication->handler->publish_expire) {
+		publication->handler->publish_expire(publication);
+	}
 
 	return 0;
 }
@@ -2159,7 +2234,7 @@
 	pjsip_generic_string_hdr *etag_hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_sip_if_match, NULL);
 	enum sip_publish_type publish_type;
 	RAII_VAR(struct ast_sip_publication *, publication, NULL, ao2_cleanup);
-	int expires = 0, entity_id;
+	int expires = 0, entity_id, response = 0;
 
 	endpoint = ast_pjsip_rdata_get_endpoint(rdata);
 	ast_assert(endpoint != NULL);
@@ -2203,19 +2278,18 @@
 			publication = publish_request_initial(endpoint, rdata, handler);
 			break;
 		case SIP_PUBLISH_REFRESH:
-			sip_publication_respond(publication, 200, rdata);
 		case SIP_PUBLISH_MODIFY:
 			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);
+			response = 200;
 			break;
 		case SIP_PUBLISH_REMOVE:
 			handler->publication_state_change(publication, rdata->msg_info.msg->body,
 					AST_SIP_PUBLISH_STATE_TERMINATED);
-			sip_publication_respond(publication, 200, rdata);
+			response = 200;
 			break;
 		case SIP_PUBLISH_UNKNOWN:
 		default:
@@ -2234,6 +2308,10 @@
 		}
 	}
 
+	if (response) {
+		sip_publication_respond(publication, response, rdata);
+	}
+
 	return PJ_TRUE;
 }
 
@@ -2242,6 +2320,15 @@
 	return pub->endpoint;
 }
 
+const char *ast_sip_publication_get_resource(const struct ast_sip_publication *pub)
+{
+	return pub->resource;
+}
+
+const char *ast_sip_publication_get_event_configuration(const struct ast_sip_publication *pub)
+{
+	return pub->event_configuration_name;
+}
 
 int ast_sip_pubsub_register_body_generator(struct ast_sip_pubsub_body_generator *generator)
 {
@@ -3421,6 +3508,40 @@
 
 #endif
 
+static int resource_endpoint_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_publication_resource *resource = obj;
+
+	ast_free(resource->endpoint);
+	resource->endpoint = ast_strdup(var->value);
+
+	return 0;
+}
+
+static int resource_event_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_publication_resource *resource = obj;
+	/* The event configuration name starts with 'event_' so skip past it to get the real name */
+	const char *event = var->name + 6;
+	struct ast_variable *item;
+
+	if (ast_strlen_zero(event) || ast_strlen_zero(var->value)) {
+		return -1;
+	}
+
+	item = ast_variable_new(event, var->value, "");
+	if (!item) {
+		return -1;
+	}
+
+	if (resource->events) {
+		item->next = resource->events;
+	}
+	resource->events = item;
+
+	return 0;
+}
+
 static int load_module(void)
 {
 	static const pj_str_t str_PUBLISH = { "PUBLISH", 7 };
@@ -3482,6 +3603,20 @@
 		ast_sched_context_destroy(sched);
 	}
 
+	ast_sorcery_apply_default(sorcery, "inbound-publication", "config", "pjsip.conf,criteria=type=inbound-publication");
+	if (ast_sorcery_object_register(sorcery, "inbound-publication", publication_resource_alloc,
+		NULL, NULL)) {
+		ast_log(LOG_ERROR, "Could not register subscription persistence object support\n");
+		ast_sip_unregister_service(&pubsub_module);
+		ast_sched_context_destroy(sched);
+		return AST_MODULE_LOAD_FAILURE;
+	}
+	ast_sorcery_object_field_register(sorcery, "inbound-publication", "type", "", OPT_NOOP_T, 0, 0);
+	ast_sorcery_object_field_register_custom(sorcery, "inbound-publication", "endpoint", "",
+		resource_endpoint_handler, NULL, NULL, 0, 0);
+	ast_sorcery_object_fields_register(sorcery, "inbound-publication", "^event_", resource_event_handler, NULL);
+	ast_sorcery_reload_object(sorcery, "inbound-publication");
+
 	if (ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) {
 		ast_sip_push_task(NULL, subscription_persistence_load, NULL);
 	} else {

Modified: team/group/rls/res/res_pjsip_pubsub.exports.in
URL: http://svnview.digium.com/svn/asterisk/team/group/rls/res/res_pjsip_pubsub.exports.in?view=diff&rev=420357&r1=420356&r2=420357
==============================================================================
--- team/group/rls/res/res_pjsip_pubsub.exports.in (original)
+++ team/group/rls/res/res_pjsip_pubsub.exports.in Thu Aug  7 12:26:33 2014
@@ -15,6 +15,8 @@
 		LINKER_SYMBOL_PREFIXast_sip_unregister_subscription_handler;
 		LINKER_SYMBOL_PREFIXast_sip_create_publication;
 		LINKER_SYMBOL_PREFIXast_sip_publication_get_endpoint;
+		LINKER_SYMBOL_PREFIXast_sip_publication_get_resource;
+		LINKER_SYMBOL_PREFIXast_sip_publication_get_event_configuration;
 		LINKER_SYMBOL_PREFIXast_sip_publication_create_response;
 		LINKER_SYMBOL_PREFIXast_sip_publication_send_response;
 		LINKER_SYMBOL_PREFIXast_sip_register_publish_handler;




More information about the svn-commits mailing list