[asterisk-commits] dvossel: branch dvossel/sip_resource_list_trunk r186713 - /team/dvossel/sip_r...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Apr 6 18:37:01 CDT 2009
Author: dvossel
Date: Mon Apr 6 18:36:55 2009
New Revision: 186713
URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=186713
Log:
Added support dialogs to watch resource lists for notifications.
Modified:
team/dvossel/sip_resource_list_trunk/channels/chan_sip.c
Modified: team/dvossel/sip_resource_list_trunk/channels/chan_sip.c
URL: http://svn.digium.com/svn-view/asterisk/team/dvossel/sip_resource_list_trunk/channels/chan_sip.c?view=diff&rev=186713&r1=186712&r2=186713
==============================================================================
--- team/dvossel/sip_resource_list_trunk/channels/chan_sip.c (original)
+++ team/dvossel/sip_resource_list_trunk/channels/chan_sip.c Mon Apr 6 18:36:55 2009
@@ -643,7 +643,8 @@
DIALOG_INFO_XML,
CPIM_PIDF_XML,
PIDF_XML,
- MWI_NOTIFICATION
+ MWI_NOTIFICATION,
+ DIALOG_RLMI_XML
};
/*! \brief Subscription types that we support. We support
@@ -663,7 +664,8 @@
{ CPIM_PIDF_XML, "presence", "application/cpim-pidf+xml", "cpim-pidf+xml" }, /* RFC 3863 */
{ PIDF_XML, "presence", "application/pidf+xml", "pidf+xml" }, /* RFC 3863 */
{ XPIDF_XML, "presence", "application/xpidf+xml", "xpidf+xml" }, /* Pre-RFC 3863 with MS additions */
- { MWI_NOTIFICATION, "message-summary", "application/simple-message-summary", "mwi" } /* RFC 3842: Mailbox notification */
+ { MWI_NOTIFICATION, "message-summary", "application/simple-message-summary", "mwi" }, /* RFC 3842: Mailbox notification */
+ { DIALOG_RLMI_XML, "dialog", "multipart/related;boundary=UniqueAsteriskRLMIBoundary;type=application/rlmi+xml", "application/rlmi+xml" } /* RFC 4662 */
};
@@ -901,7 +903,7 @@
/* RFC3959: SIP Early session support */
{ SIP_OPT_EARLY_SESSION, NOT_SUPPORTED, "early-session" },
/* SIMPLE events: RFC4662 */
- { SIP_OPT_EVENTLIST, NOT_SUPPORTED, "eventlist" },
+ { SIP_OPT_EVENTLIST, SUPPORTED, "eventlist" },
/* RFC 4916- Connected line ID updates */
{ SIP_OPT_FROMCHANGE, NOT_SUPPORTED, "from-change" },
/* GRUU: Globally Routable User Agent URI's */
@@ -1751,8 +1753,8 @@
int stateid; /*!< SUBSCRIBE: ID for devicestate subscriptions */
int laststate; /*!< SUBSCRIBE: Last known extension state */
int dialogver; /*!< SUBSCRIBE: Version for subscription dialog-info */
-
- struct sip_rlist *rlist; /*!< SUBSCRIBE: prt to resource list */
+ struct sip_rlist *rlist; /*!< SUBSCRIBE: Resource list to get notifications from */
+ AST_LIST_ENTRY(sip_pvt) rlist_entry; /* SUBSCRIBE: entry into resource list's list of watchers */
struct ast_dsp *vad; /*!< Inband DTMF Detection dsp */
@@ -1898,6 +1900,7 @@
);
int version;
int the_mark;
+ AST_LIST_HEAD_NOLOCK(, sip_pvt) watchers;
AST_LIST_HEAD_NOLOCK(, sip_rlist_resource) resources;
};
@@ -2443,6 +2446,10 @@
static int attempt_transfer(struct sip_dual *transferer, struct sip_dual *target);
static int do_magic_pickup(struct ast_channel *channel, const char *extension, const char *context);
+/* add and remove resource list watchers */
+static int rlist_add_watcher(struct sip_pvt *p);
+static int rlist_remove_watcher(struct sip_pvt *p);
+
/*!
* \brief generic function for determining if a correct transport is being
* used to contact a peer
@@ -2965,12 +2972,6 @@
return peer;
}
-static void *unref_rlist(struct sip_rlist *rlist, char *tag)
-{
- ao2_t_ref(rlist, -1, tag);
- return NULL;
-}
-
/*! \brief maintain proper refcounts for a sip_pvt's outboundproxy
*
* This function sets pvt's outboundproxy pointer to the one referenced
@@ -3030,6 +3031,9 @@
ast_extension_state_del(dialog->stateid, NULL);
dialog_unref(dialog, "removing extension_state, should unref the associated dialog ptr that was stored there.");
dialog->stateid = -1; /* shouldn't we 'zero' this out? */
+ }
+ if (dialog->rlist) {
+ rlist_remove_watcher(dialog);
}
/* Remove link from peer to subscription of MWI */
if (dialog->relatedpeer && dialog->relatedpeer->mwipvt == dialog)
@@ -4659,6 +4663,33 @@
return CMP_MATCH | CMP_STOP;
}
+/*!
+ * \brief Locate resource list by name and context
+ *
+ * If sip_pvt *p is !NULL, then p->rlist is updated to point
+ * to the matching resource list if found.
+ */
+static int rlist_find(const char *name, const char *context, struct sip_pvt *p)
+{
+ struct sip_rlist tmp_rlist;
+ struct sip_rlist *rlist = NULL;
+ int found = 0;
+ ast_copy_string(tmp_rlist.name, name, sizeof(tmp_rlist.name));
+
+ rlist = ao2_t_find(rlists, &tmp_rlist, OBJ_POINTER, "ao2_find in rlist_find()");
+
+ if (rlist) {
+ found = 1;
+ if (p) {
+ p->rlist = rlist;
+ } else {
+ ao2_t_ref(rlist, -1, "unref rlist in rlist_find");
+ }
+ }
+
+ return found;
+}
+
/*!
* \brief Locate device by name or ip address
*
@@ -5359,6 +5390,10 @@
if (p->chanvars) {
ast_variables_destroy(p->chanvars);
p->chanvars = NULL;
+ }
+
+ if (p->rlist) {
+ ao2_t_ref(p->rlist, -1, "peer is destroyed, decrement ref of rlist.");
}
ast_string_field_free_memory(p);
@@ -12889,9 +12924,14 @@
ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
/* If this is a subscription we actually just need to see if a hint exists for the extension */
- if (req->method == SIP_SUBSCRIBE) { //todohere search rlist for dest instead of just hints
+ if (req->method == SIP_SUBSCRIBE) {
char hint[AST_MAX_EXTENSION];
- return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1);
+ int res;
+ res = ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1;
+ if (res) { /* if res is not 0, then hint not found, check rlists for destination. */
+ res = rlist_find(p->exten, p->context, NULL) ? 0 : -1;
+ }
+ return res;
} else {
decoded_uri = ast_strdupa(uri);
ast_uri_decode(decoded_uri);
@@ -20922,7 +20962,9 @@
/* Polycom phones only handle xpidf+xml, even if they say they can
handle pidf+xml as well
*/
- if (strstr(p->useragent, "Polycom")) {
+ if (strstr(acceptheader, " application/rlmi+xml")) {
+ p->subscribed = DIALOG_RLMI_XML;
+ } else if (strstr(p->useragent, "Polycom")) {
p->subscribed = XPIDF_XML;
} else if (strstr(acceptheader, "application/pidf+xml")) {
p->subscribed = PIDF_XML; /* RFC 3863 format */
@@ -21007,12 +21049,21 @@
/* Add subscription for extension state from the PBX core */
if (p->subscribed != MWI_NOTIFICATION && !resubscribe) {
- if (p->stateid > -1) {
- ast_extension_state_del(p->stateid, cb_extensionstate);
- /* we need to dec the refcount, now that the extensionstate is removed */
- dialog_unref(p, "the extensionstate containing this dialog ptr was deleted");
- }
- p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, dialog_ref(p,"copying dialog ptr into extension state struct"));
+
+ if (p->subscribed == DIALOG_RLMI_XML) {
+//todohere add code to add this pvt to subscribe to rlist updates
+ if (p->rlist) {
+ rlist_remove_watcher(p);
+ }
+ rlist_add_watcher(p);
+ } else {
+ if (p->stateid > -1) {
+ ast_extension_state_del(p->stateid, cb_extensionstate);
+ /* we need to dec the refcount, now that the extensionstate is removed */
+ dialog_unref(p, "the extensionstate containing this dialog ptr was deleted");
+ }
+ p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, dialog_ref(p,"copying dialog ptr into extension state struct"));
+ }
}
if (!req->ignore && p)
@@ -23194,7 +23245,37 @@
}
}
-static int add_rlist_resource(struct sip_rlist *rlist, const char *monitorexten)
+static int rlist_add_watcher(struct sip_pvt *p)
+{
+ if (p) {
+ /* find and point p->rlist to match, rlist ref is incremented if found */
+ rlist_find(p->exten, p->context, p);
+ if (p->rlist) {
+ dialog_ref(p, "add sip_pvt watcher to resource list notifications");
+ AST_LIST_INSERT_TAIL(&p->rlist->watchers, p, rlist_entry);
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+static int rlist_remove_watcher(struct sip_pvt *p)
+{
+ if (!p) {
+ return -1;
+ }
+ if (p->rlist) {
+ AST_LIST_REMOVE(&p->rlist->watchers, p, rlist_entry);
+ ao2_t_ref(p->rlist, -1, "remove dialog's ref to resource list");
+ p->rlist = NULL;
+ dialog_unref(p, "remove sip_pvt from resource list notifications");
+ return 0;
+ }
+ return -1;
+}
+
+static int rlist_add_resource(struct sip_rlist *rlist, const char *monitorexten)
{
struct sip_rlist_resource *resource;
@@ -23220,7 +23301,7 @@
AST_LIST_TRAVERSE(&rlist->resources, resource, entry) {
ast_log(LOG_NOTICE, "\tMONITOR EXTEN: %s\n", resource->exten);
}
- unref_rlist(rlist, "print_rlist");
+ ao2_t_ref(rlist, -1, "print_rlist");
}
} */
@@ -23247,16 +23328,16 @@
}
if (ast_string_field_init(rlist, 256)) {
- unref_rlist(rlist, "rlist failed to init string field");
+ ao2_t_ref(rlist, -1, "rlist failed to init string field");
return NULL;
}
-;
+
ast_copy_string(rlist->name, name, sizeof(rlist->name));
}
for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
if (!strcasecmp(v->name, "monitor")) {
- add_rlist_resource(rlist, v->value);
+ rlist_add_resource(rlist, v->value);
} else if (!strcasecmp(v->name, "context")) {
ast_string_field_set(rlist, context, v->value);
}
@@ -24542,9 +24623,9 @@
}
} else if (!strcasecmp(utype, "resourcelist")) {
rlist = build_rlist(cat, ast_variable_browse(cfg, cat), NULL, 0);
- if (rlist) { // todohere addrlists object and functions
+ if (rlist) {
ao2_t_link(rlists, rlist, "link rlist into rlists table");
- unref_rlist(rlist, "unref the result of the build_rlist call. Now, the links from the tables are the only ones left,");
+ ao2_t_ref(rlist, -1, "unref the result of the build_rlist call. Now, the links from the tables are the only ones left,");
}
} else {
ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
More information about the asterisk-commits
mailing list