[asterisk-commits] mmichelson: branch mmichelson/pub_sub r385165 - /team/mmichelson/pub_sub/res/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Apr 9 17:46:30 CDT 2013
Author: mmichelson
Date: Tue Apr 9 17:46:27 2013
New Revision: 385165
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=385165
Log:
Restructure objects to more accurately reflect what is necessary.
This also fills in some of the missing container allocations and does isolates
some logic to their own functions.
Modified:
team/mmichelson/pub_sub/res/res_sip_mwi.c
Modified: team/mmichelson/pub_sub/res/res_sip_mwi.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pub_sub/res/res_sip_mwi.c?view=diff&rev=385165&r1=385164&r2=385165
==============================================================================
--- team/mmichelson/pub_sub/res/res_sip_mwi.c (original)
+++ team/mmichelson/pub_sub/res/res_sip_mwi.c Tue Apr 9 17:46:27 2013
@@ -37,6 +37,72 @@
<depend>res_sip_pubsub</depend>
<support_level>core</support_level>
***/
+
+struct ao2_container *mwi_subscriptions;
+
+#define STASIS_BUCKETS 13
+#define MWI_BUCKETS 53
+
+struct mwi_stasis_subscription {
+ struct stasis_subscription *stasis_sub;
+ char mailbox[1];
+};
+
+static void mwi_stasis_subscription_destructor(void *obj)
+{
+ struct mwi_stasis_subscription *mwi_stasis = obj;
+
+ if (mwi_stasis->stasis_sub) {
+ mwi_stasis->stasis_sub = stasis_unsubscribe(mwi_stasis->stasis_sub);
+ }
+}
+
+static int stasis_sub_hash(const void *obj, int flags)
+{
+ const struct mwi_stasis_subscription *mwi_stasis = obj;
+
+ return ast_str_hash(mwi_stasis->mailbox);
+}
+
+static int stasis_sub_cmp(void *obj, void *arg, int flags)
+{
+ struct mwi_stasis_subscription *mwi_stasis1 = obj;
+ struct mwi_stasis_subscription *mwi_stasis2 = arg;
+
+ return strcmp(mwi_stasis1->mailbox, mwi_stasis2->mailbox) ? 0 : CMP_MATCH;
+}
+
+struct mwi_subscription {
+ struct ao2_container *stasis_subs;
+ struct ast_sip_subscription *sip_sub;
+ char id[1];
+};
+
+static void mwi_subscription_destructor(void *obj)
+{
+ struct mwi_subscription *sub = obj;
+ ao2_cleanup(sub->sip_sub);
+ ao2_cleanup(sub->stasis_subs);
+}
+
+static int mwi_sub_hash(const void *obj, int flags)
+{
+ const struct mwi_subscription *mwi_sub = obj;
+
+ return ast_str_hash(mwi_sub->id);
+}
+
+static int mwi_sub_cmp(void *obj, void *arg, int flags)
+{
+ struct mwi_subscription *mwi_sub1 = obj;
+ struct mwi_subscription *mwi_sub2 = arg;
+
+ return strcmp(mwi_sub1->id, mwi_sub2->id) ? 0 : CMP_MATCH;
+}
+
+static void send_mwi_notify(struct mwi_subscription *sub)
+{
+}
static void mwi_subscription_shutdown(struct ast_sip_subscription *sub)
{
@@ -98,25 +164,6 @@
.refresh_subscription = mwi_refresh_subscription,
};
-struct ao2_container *mwi_subscriptions;
-
-struct mwi_subscription {
- const char *id;
- struct stasis_subscription *event_sub;
- struct ast_sip_subscription *sip_sub;
-};
-
-static void mwi_subscription_destructor(void *obj)
-{
- struct mwi_subscription *sub = obj;
- ao2_cleanup(sub->sip_sub);
- ast_free((char *)sub->id);
-}
-
-static void send_mwi_notify(struct ast_sip_subscription *sub)
-{
-}
-
static void mwi_stasis_cb(void *userdata, struct stasis_subscription *sub,
struct stasis_topic *topic, struct stasis_message *msg)
{
@@ -126,33 +173,75 @@
return;
}
if (stasis_mwi_state_type() == stasis_message_type(msg)) {
- send_mwi_notify(mwi_sub->sip_sub);
- }
+ send_mwi_notify(mwi_sub);
+ }
+}
+
+static struct mwi_subscription *mwi_subscription_alloc(struct ast_sip_endpoint *endpoint)
+{
+ struct mwi_subscription *sub;
+ const char *endpoint_id = ast_sorcery_object_get_id(endpoint);
+
+ sub = ao2_alloc(sizeof(*sub) + strlen(endpoint_id),
+ mwi_subscription_destructor);
+
+ if (!sub) {
+ return NULL;
+ }
+
+ /* Safe strcpy */
+ strcpy(sub->id, endpoint_id);
+ /* MWI is an interesting case because the NOTIFYs we send are
+ * unsolicited. We get around the requirement of needing an
+ * incoming SUBSCRIBE by pretending that we are the subscriber
+ */
+ sub->sip_sub = ast_sip_create_subscription(&mwi_handler,
+ AST_SIP_SUBSCRIBER, endpoint, NULL);
+ if (!sub->sip_sub) {
+ ao2_cleanup(sub);
+ return NULL;
+ }
+
+ sub->stasis_subs = ao2_container_alloc(STASIS_BUCKETS, stasis_sub_hash, stasis_sub_cmp);
+ if (!sub->stasis_subs) {
+ ao2_cleanup(sub);
+ return NULL;
+ }
+
+ return sub;
}
static int create_mwi_subscriptions_for_endpoint(void *obj, void *arg, int flags)
{
+ RAII_VAR(struct mwi_subscription *, sub, NULL, ao2_cleanup);
struct ast_sip_endpoint *endpoint = obj;
- char *mailboxes = ast_strdupa(endpoint->mailboxes);
+ char *mailboxes;
char *mailbox;
+ if (ast_strlen_zero(endpoint->mailboxes)) {
+ return 0;
+ }
+
+ sub = mwi_subscription_alloc(endpoint);
+ if (!sub) {
+ return 0;
+ }
+
+ mailboxes = ast_strdupa(endpoint->mailboxes);
while ((mailbox = strsep(&mailboxes, ","))) {
- struct mwi_subscription *sub;
+ RAII_VAR(struct mwi_stasis_subscription *, mwi_stasis_sub,
+ ao2_alloc(sizeof(*mwi_stasis_sub) + strlen(mailbox),
+ mwi_stasis_subscription_destructor), ao2_cleanup);
struct stasis_topic *topic;
topic = stasis_mwi_topic(mailbox);
-
- sub = ao2_alloc(sizeof(*sub), mwi_subscription_destructor);
- sub->id = ast_strdup(ast_sorcery_object_get_id(endpoint));
- /* MWI is an interesting case because the NOTIFYs we send are
- * unsolicited. We get around the requirement of needing an
- * incoming SUBSCRIBE by pretending that we are the subscriber
- */
- sub->sip_sub = ast_sip_create_subscription(&mwi_handler,
- AST_SIP_SUBSCRIBER, endpoint, NULL);
- sub->event_sub = stasis_subscribe(topic, mwi_stasis_cb, sub);
- ao2_link(mwi_subscriptions, sub);
- }
+
+ /* Safe strcpy */
+ strcpy(mwi_stasis_sub->mailbox, mailbox);
+ mwi_stasis_sub->stasis_sub = stasis_subscribe(topic, mwi_stasis_cb, sub);
+ ao2_link(sub->stasis_subs, mwi_stasis_sub);
+ }
+ ao2_link(mwi_subscriptions, sub);
return 0;
}
@@ -169,6 +258,10 @@
{
if (ast_sip_register_subscription_handler(&mwi_handler)) {
return AST_MODULE_LOAD_DECLINE;
+ }
+ mwi_subscriptions = ao2_container_alloc(MWI_BUCKETS, mwi_sub_hash, mwi_sub_cmp);
+ if (!mwi_subscriptions) {
+ ast_sip_unregister_subscription_handler(&mwi_handler);
}
create_mwi_subscriptions();
return AST_MODULE_LOAD_SUCCESS;
More information about the asterisk-commits
mailing list