[asterisk-commits] mmichelson: branch mmichelson/pub_sub r384606 - /team/mmichelson/pub_sub/res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Apr 2 17:26:08 CDT 2013


Author: mmichelson
Date: Tue Apr  2 17:26:04 2013
New Revision: 384606

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=384606
Log:
Add datastore support to subscriptions.


Modified:
    team/mmichelson/pub_sub/res/res_sip_pubsub.c

Modified: team/mmichelson/pub_sub/res/res_sip_pubsub.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pub_sub/res/res_sip_pubsub.c?view=diff&rev=384606&r1=384605&r2=384606
==============================================================================
--- team/mmichelson/pub_sub/res/res_sip_pubsub.c (original)
+++ team/mmichelson/pub_sub/res/res_sip_pubsub.c Tue Apr  2 17:26:04 2013
@@ -28,58 +28,152 @@
 #include "asterisk/res_sip_pubsub.h"
 #include "asterisk/module.h"
 #include "asterisk/linkedlists.h"
- 
+#include "asterisk/astobj2.h"
+#include "asterisk/datastore.h"
+#include "asterisk/uuid.h"
+
+struct ast_sip_subscription {
+	struct ao2_container *datastores;
+};
+
+#define DATASTORE_BUCKETS 53
+
+static int datastore_hash(const void *obj, int flags)
+{
+	const struct ast_datastore *datastore = obj;
+	const char *uid = flags & OBJ_KEY ? obj : datastore->uid;
+
+	ast_assert(uid != NULL);
+
+	return ast_str_hash(uid);
+}
+
+static int datastore_cmp(void *obj, void *arg, int flags)
+{
+	const struct ast_datastore *datastore1 = obj;
+	const struct ast_datastore *datastore2 = arg;
+	const char *uid2 = flags & OBJ_KEY ? arg : datastore2->uid;
+
+	ast_assert(datastore1->uid != NULL);
+	ast_assert(uid2 != NULL);
+
+	return strcmp(datastore1->uid, uid2) ? 0 : CMP_MATCH | CMP_STOP;
+}
+
+static void subscription_destructor(void *obj)
+{
+	struct ast_sip_subscription *sub = obj;
+	ao2_cleanup(sub->datastores);
+}
+
 struct ast_sip_subscription *ast_sip_create_subscription(const struct ast_sip_subscription_handler *handler,
         enum ast_sip_subscription_role role, struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
 {
+	struct ast_sip_subscription *sub = ao2_alloc(sizeof(*sub), subscription_destructor);
+	if (!sub) {
+		return NULL;
+	}
+	sub->datastores = ao2_container_alloc(DATASTORE_BUCKETS, datastore_hash, datastore_cmp);
+	if (!sub->datastores) {
+		ao2_ref(sub, -1);
+		return NULL;
+	}
+	return sub;
+}
+ 
+struct ast_sip_endpoint *ast_sip_subscription_get_endpoint(struct ast_sip_subscription *sub)
+{
 	/* XXX STUB */
 	return NULL;
 }
  
-struct ast_sip_endpoint *ast_sip_subscription_get_endpoint(struct ast_sip_subscription *sub)
+struct ast_sip_serializer *ast_sip_subscription_get_serializer(struct ast_sip_subscription *sub)
 {
 	/* XXX STUB */
 	return NULL;
 }
- 
-struct ast_sip_serializer *ast_sip_subscription_get_serializer(struct ast_sip_subscription *sub)
+
+pjsip_evsub *ast_sip_subscription_get_evsub(struct ast_sip_subscription *sub)
 {
 	/* XXX STUB */
 	return NULL;
 }
 
-pjsip_evsub *ast_sip_subscription_get_evsub(struct ast_sip_subscription *sub)
-{
-	/* XXX STUB */
-	return NULL;
-}
-
 int ast_sip_subscription_send_request(struct ast_sip_subscription *sub, pjsip_tx_data *tdata)
 {
 	/* XXX STUB */
 	return 0;
 }
+
+static void subscription_datastore_destroy(void *obj)
+{
+	struct ast_datastore *datastore = obj;
+
+	/* Using the destroy function (if present) destroy the data */
+	if (datastore->info->destroy != NULL && datastore->data != NULL) {
+		datastore->info->destroy(datastore->data);
+		datastore->data = NULL;
+	}
+
+	ast_free((void *) datastore->uid);
+	datastore->uid = NULL;
+}
+
 struct ast_datastore *ast_sip_subscription_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
 {
-	/* XXX STUB */
-	return NULL;
+	RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
+	const char *uid_ptr = uid;
+
+	if (!info) {
+		return NULL;
+	}
+
+	datastore = ao2_alloc(sizeof(*datastore), subscription_datastore_destroy);
+	if (!datastore) {
+		return NULL;
+	}
+
+	datastore->info = info;
+	if (ast_strlen_zero(uid)) {
+		/* They didn't provide an ID so we'll provide one ourself */
+		struct ast_uuid *uuid = ast_uuid_generate();
+		char uuid_buf[AST_UUID_STR_LEN];
+		if (!uuid) {
+			return NULL;
+		}
+		uid_ptr = ast_uuid_to_str(uuid, uuid_buf, sizeof(uuid_buf));
+		ast_free(uuid);
+	}
+
+	datastore->uid = ast_strdup(uid_ptr);
+	if (!datastore->uid) {
+		return NULL;
+	}
+
+	ao2_ref(datastore, +1);
+	return datastore;
 }
  
 int ast_sip_subscription_add_datastore(struct ast_sip_subscription *subscription, struct ast_datastore *datastore)
 {
-	/* XXX STUB */
+	ast_assert(datastore != NULL);
+	ast_assert(datastore->info != NULL);
+	ast_assert(ast_strlen_zero(datastore->uid) == 0);
+
+	if (!ao2_link(subscription->datastores, datastore)) {
+		return -1;
+	}
 	return 0;
 }
 
 struct ast_datastore *ast_sip_subscription_get_datastore(struct ast_sip_subscription *subscription, const char *name)
 {
-	/* XXX STUB */
-	return NULL;
+	return ao2_find(subscription->datastores, name, OBJ_KEY);
 }
 
 void ast_sip_subscription_remove_datastore(struct ast_sip_subscription *subscription, const char *name)
 {
-	/* XXX STUB */
+	ao2_callback(subscription->datastores, OBJ_KEY | OBJ_UNLINK | OBJ_NODATA, NULL, (void *) name);
 }
 
 AST_RWLIST_HEAD_STATIC(subscription_handlers, ast_sip_subscription_handler);




More information about the asterisk-commits mailing list