[asterisk-commits] dvossel: branch dvossel/sip_resource_list_trunk r187268 - /team/dvossel/sip_r...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Apr 8 17:12:33 CDT 2009


Author: dvossel
Date: Wed Apr  8 17:12:15 2009
New Revision: 187268

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=187268
Log:
Sends NOTIFY now.  Thinks left to do: make it suck less, locking. 

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=187268&r1=187267&r2=187268
==============================================================================
--- team/dvossel/sip_resource_list_trunk/channels/chan_sip.c (original)
+++ team/dvossel/sip_resource_list_trunk/channels/chan_sip.c Wed Apr  8 17:12:15 2009
@@ -665,7 +665,7 @@
 	{ 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 */
-	{ DIALOG_RLMI_XML, "dialog",   "multipart/related;boundary=UniqueAsteriskRLMIBoundary;type=application/rlmi+xml", "application/rlmi+xml" } /* RFC 4662 todohere fix boundary */
+	{ DIALOG_RLMI_XML, "",   "application/rlmi+xml", "rlmi+xml" } /* RFC 4662 todohere fix boundary */
 };
 
 
@@ -1750,6 +1750,7 @@
 	enum transfermodes allowtransfer;	/*!< REFER: restriction scheme */
 	struct sip_refer *refer;		/*!< REFER: SIP transfer data structure */
 	enum subscriptiontype subscribed;	/*!< SUBSCRIBE: Is this dialog a subscription?  */
+	enum subscriptiontype multipart_subscribed;	/*!< SUBSCRIBE: is this dialog a multipart/related subscription? */
 	int stateid;				/*!< SUBSCRIBE: ID for devicestate subscriptions */
 	int laststate;				/*!< SUBSCRIBE: Last known extension state */
 	int dialogver;				/*!< SUBSCRIBE: Version for subscription dialog-info */
@@ -10448,23 +10449,15 @@
 			(sip_cfg.notifycid == IGNORE_CONTEXT || !strcasecmp(c->context, p->context)));
 }
 
-/*! \brief Used in the SUBSCRIBE notification subsystem (RFC3265) */
-static int transmit_state_notify(struct sip_pvt *p, int state, int full, int timeout)
-{
-	struct ast_str *tmp = ast_str_alloca(4000);
-	char from[256], to[256];
-	char *c, *mfrom, *mto;
-	struct sip_request req;
-	char hint[AST_MAX_EXTENSION];
+//todohere note: subscribed may or may not match p->subscribed because of multipart/related. this function simply adds to the content of a NOTIFY
+static void state_notify_build(int state, int full, const char *exten, const char *context, struct ast_str **tmp, struct sip_pvt *p, int subscribed, char *mfrom, char *mto)
+{
+	enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
 	char *statestring = "terminated";
-	const struct cfsubscription_types *subscriptiontype;
-	enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
 	char *pidfstate = "--";
 	char *pidfnote= "Ready";
-	
-	memset(from, 0, sizeof(from));
-	memset(to, 0, sizeof(to));
-
+	char hint[AST_MAX_EXTENSION];
+	struct sip_rlist_resource *resource;
 	switch (state) {
 	case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
 		statestring = (sip_cfg.notifyringing) ? "early" : "confirmed";
@@ -10508,121 +10501,79 @@
 		break;
 	}
 
-	subscriptiontype = find_subscription_type(p->subscribed);
-	
 	/* Check which device/devices we are watching  and if they are registered */
-	//todohere this should not be done for rlmi, fix it
-	if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
-		char *hint2 = hint, *individual_hint = NULL;
-		int hint_count = 0, unavailable_count = 0;
-
-		while ((individual_hint = strsep(&hint2, "&"))) {
-			hint_count++;
-
-			if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE)
-				unavailable_count++;
-		}
-
-		/* If none of the hinted devices are registered, we will
-		 * override notification and show no availability.
-		 */
-		if (hint_count > 0 && hint_count == unavailable_count) {
-			local_state = NOTIFY_CLOSED;
-			pidfstate = "away";
-			pidfnote = "Not online";
-		}
-	}
-
-	ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
-	c = get_in_brackets(from);
-	if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
-		ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
-		return -1;
-	}
-	
-	mfrom = remove_uri_parameters(c);
-
-	ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
-	c = get_in_brackets(to);
-	if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
-		ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
-		return -1;
-	}
-	mto = remove_uri_parameters(c);
-
-	reqprep(&req, p, SIP_NOTIFY, 0, 1);
-
-	
-	add_header(&req, "Event", subscriptiontype->event);
-	add_header(&req, "Content-Type", subscriptiontype->mediatype);
-	switch(state) {
-	case AST_EXTENSION_DEACTIVATED:
-		if (timeout)
-			add_header(&req, "Subscription-State", "terminated;reason=timeout");
-		else {
-			add_header(&req, "Subscription-State", "terminated;reason=probation");
-			add_header(&req, "Retry-After", "60");
-		}
-		break;
-	case AST_EXTENSION_REMOVED:
-		add_header(&req, "Subscription-State", "terminated;reason=noresource");
-		break;
-	default:
-		if (p->expiry)
-			add_header(&req, "Subscription-State", "active");
-		else	/* Expired */
-			add_header(&req, "Subscription-State", "terminated;reason=timeout");
-	}
-	switch (p->subscribed) {
+	if (subscribed != DIALOG_RLMI_XML) {
+		if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten)) {
+			char *hint2 = hint, *individual_hint = NULL;
+			int hint_count = 0, unavailable_count = 0;
+
+			while ((individual_hint = strsep(&hint2, "&"))) {
+				hint_count++;
+
+				if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE)
+					unavailable_count++;
+			}
+
+			/* If none of the hinted devices are registered, we will
+			 * override notification and show no availability.
+			 */
+			if (hint_count > 0 && hint_count == unavailable_count) {
+				local_state = NOTIFY_CLOSED;
+				pidfstate = "away";
+				pidfnote = "Not online";
+			}
+		}
+	}
+	switch (subscribed) {
 	case XPIDF_XML:
 	case DIALOG_RLMI_XML:
 	//todohere finish progress made in creating rlmi NOTIFY
-	/*	struct sip_rlist_resource *resource;
 		//todohere add name attributes for list and elements within list
-		ast_str_append(&tmp, 0, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
-		ast_str_append(&tmp, 0, "<list xmlns=\"urn:ietf:params:xml:ns:rlmi\"\n");
-		ast_str_append(&tmp, 0, "uri=\"%s\">\n", mfrom);
-		ast_str_append(&tmp, 0, "version=\"%d\" fullState=\"true\">", p->dialogver);
+		ast_str_append(tmp, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+		ast_str_append(tmp, 0, "<list xmlns=\"urn:ietf:params:xml:ns:rlmi\" uri=\"%s\" version=\"%d\" fullState=\"true\">\n", mto, p->dialogver); //is mto correct?
 		AST_LIST_TRAVERSE(&p->rlist->resources, resource, entry) {
-			ast_str_append(&tmp, 0, "<resource uri=\"sip:%s@%s\">", resource->exten, p->fromdomain);
-			ast_str_append(&tmp, 0, "<instance id="
-		}
-		//ast_log(LOG_NOTICE, "IN NOTIFY, mfrom:%s, mto:%s p->domain:%s \n", mfrom, mto, p->fromdomain);
-	*/
+			ast_str_append(tmp, 0, "<resource uri=\"sip:%s@%s\">\n", resource->exten, p->fromdomain);
+			ast_str_append(tmp, 0, "<name>%s</name>\n", resource->exten); //todohere name? username? add to conf?
+			ast_str_append(tmp, 0, "<instance id=\"%08lx\" state=\"active\" cid=\"%s@%s\"/>\n", ast_random(), resource->contentid, p->fromdomain); //todohere random has to go away
+			ast_str_append(tmp, 0, "</resource>\n");
+		}
+		ast_str_append(tmp, 0, "</list>\n");
+		ast_log(LOG_NOTICE, "IN NOTIFY RLMI, mfrom:%s, mto:%s p->domain:%s \n", mfrom, mto, p->fromdomain);
+		break;
 	case CPIM_PIDF_XML:
-		ast_str_append(&tmp, 0,
+		ast_str_append(tmp, 0,
 			"<?xml version=\"1.0\"?>\n"
 			"<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
 			"<presence>\n");
-		ast_str_append(&tmp, 0, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
-		ast_str_append(&tmp, 0, "<atom id=\"%s\">\n", p->exten);
-		ast_str_append(&tmp, 0, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
-		ast_str_append(&tmp, 0, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
-		ast_str_append(&tmp, 0, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
-		ast_str_append(&tmp, 0, "</address>\n</atom>\n</presence>\n");
+		ast_str_append(tmp, 0, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
+		ast_str_append(tmp, 0, "<atom id=\"%s\">\n", exten);
+		ast_str_append(tmp, 0, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
+		ast_str_append(tmp, 0, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
+		ast_str_append(tmp, 0, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
+		ast_str_append(tmp, 0, "</address>\n</atom>\n</presence>\n");
 		break;
 	case PIDF_XML: /* Eyebeam supports this format */
-		ast_str_append(&tmp, 0,
+		ast_str_append(tmp, 0,
 			"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
 			"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \nxmlns:pp=\"urn:ietf:params:xml:ns:pidf:person\"\nxmlns:es=\"urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status\"\nxmlns:ep=\"urn:ietf:params:xml:ns:pidf:rpid:rpid-person\"\nentity=\"%s\">\n", mfrom);
-		ast_str_append(&tmp, 0, "<pp:person><status>\n");
+		ast_str_append(tmp, 0, "<pp:person><status>\n");
 		if (pidfstate[0] != '-')
-			ast_str_append(&tmp, 0, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
-		ast_str_append(&tmp, 0, "</status></pp:person>\n");
-		ast_str_append(&tmp, 0, "<note>%s</note>\n", pidfnote); /* Note */
-		ast_str_append(&tmp, 0, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
-		ast_str_append(&tmp, 0, "<contact priority=\"1\">%s</contact>\n", mto);
+			ast_str_append(tmp, 0, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
+		ast_str_append(tmp, 0, "</status></pp:person>\n");
+		ast_str_append(tmp, 0, "<note>%s</note>\n", pidfnote); /* Note */
+		ast_str_append(tmp, 0, "<tuple id=\"%s\">\n", exten); /* Tuple start */
+		ast_str_append(tmp, 0, "<contact priority=\"1\">%s</contact>\n", mto);
 		if (pidfstate[0] == 'b') /* Busy? Still open ... */
-			ast_str_append(&tmp, 0, "<status><basic>open</basic></status>\n");
+			ast_str_append(tmp, 0, "<status><basic>open</basic></status>\n");
 		else
-			ast_str_append(&tmp, 0, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
-		ast_str_append(&tmp, 0, "</tuple>\n</presence>\n");
+			ast_str_append(tmp, 0, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
+		ast_str_append(tmp, 0, "</tuple>\n</presence>\n");
 		break;
 	case DIALOG_INFO_XML: /* SNOM subscribes in this format */
-		ast_str_append(&tmp, 0, "<?xml version=\"1.0\"?>\n");
-		ast_str_append(&tmp, 0, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">\n", p->dialogver++, full ? "full" : "partial", mto);
+		ast_str_append(tmp, 0, "<?xml version=\"1.0\"?>\n");
+		ast_str_append(tmp, 0, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">\n", p->dialogver++, full ? "full" : "partial", mto);
 		if ((state & AST_EXTENSION_RINGING) && sip_cfg.notifyringing) {
-			const char *local_display = p->exten;
+			const char *local_display = exten;
 			char *local_target = mto;
 
 			/* There are some limitations to how this works.  The primary one is that the
@@ -10643,7 +10594,7 @@
 
 			/* We create a fake call-id which the phone will send back in an INVITE
 			   Replaces header which we can grab and do some magic with. */
-			ast_str_append(&tmp, 0, 
+			ast_str_append(tmp, 0, 
 					"<dialog id=\"%s\" call-id=\"pickup-%s\" direction=\"recipient\">\n"
 					"<remote>\n"
 					/* See the limitations of this above.  Luckily the phone seems to still be
@@ -10655,27 +10606,158 @@
 					"<identity>%s</identity>\n"
 					"<target uri=\"%s\"/>\n"
 					"</local>\n",
-					p->exten, p->callid, local_display, local_target, local_target, mto, mto);
+					exten, p->callid, local_display, local_target, local_target, mto, mto);
 		} else {
-			ast_str_append(&tmp, 0, "<dialog id=\"%s\">\n", p->exten);
-		}
-		ast_str_append(&tmp, 0, "<state>%s</state>\n", statestring);
+			ast_str_append(tmp, 0, "<dialog id=\"%s\">\n", exten);
+		}
+		ast_str_append(tmp, 0, "<state>%s</state>\n", statestring);
 		if (state == AST_EXTENSION_ONHOLD) {
-			ast_str_append(&tmp, 0, "<local>\n<target uri=\"%s\">\n"
+			ast_str_append(tmp, 0, "<local>\n<target uri=\"%s\">\n"
 			                                "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n"
 			                                "</target>\n</local>\n", mto);
 		}
-		ast_str_append(&tmp, 0, "</dialog>\n</dialog-info>\n");
+		ast_str_append(tmp, 0, "</dialog>\n</dialog-info>\n");
 		break;
 	case NONE:
 	default:
 		break;
 	}
+}
+
+/*! \brief Used in the SUBSCRIBE notification subsystem (RFC3265) */
+static int transmit_state_notify(struct sip_pvt *p, int state, int full, int timeout)
+{
+	struct ast_str *tmp = ast_str_alloca(4000);
+	struct ast_str *content_type = ast_str_alloca(256);
+	char from[256], to[256];
+	char *c, *mfrom, *mto;
+	struct sip_request req;
+	const struct cfsubscription_types *subscriptiontype;
+	struct sip_rlist *rlist = NULL;
+	struct sip_rlist_resource *resource = NULL;
+	char *boundary = "50UBfW7LSCVLtggUPe5z"; //todohere better boundary
+
+	memset(from, 0, sizeof(from));
+	memset(to, 0, sizeof(to));
+
+	subscriptiontype = find_subscription_type(p->subscribed);
+
+	ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
+	c = get_in_brackets(from);
+	if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
+		ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
+		return -1;
+	}
+
+	mfrom = remove_uri_parameters(c);
+
+	ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
+	c = get_in_brackets(to);
+	if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
+		ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
+		return -1;
+	}
+	mto = remove_uri_parameters(c);
+
+	reqprep(&req, p, SIP_NOTIFY, 0, 1);
+
+
+	if (p->subscribed != DIALOG_RLMI_XML) {
+		switch(state) {
+		case AST_EXTENSION_DEACTIVATED:
+			if (timeout)
+				add_header(&req, "Subscription-State", "terminated;reason=timeout");
+			else {
+				add_header(&req, "Subscription-State", "terminated;reason=probation");
+				add_header(&req, "Retry-After", "60");
+			}
+			break;
+		case AST_EXTENSION_REMOVED:
+			add_header(&req, "Subscription-State", "terminated;reason=noresource");
+			break;
+		default:
+			if (p->expiry) {
+				add_header(&req, "Subscription-State", "active");
+			} else {	/* Expired */
+				add_header(&req, "Subscription-State", "terminated;reason=timeout");
+			}
+		}
+	} else {
+		if (p->expiry) {
+			add_header(&req, "Subscription-State", "active");
+		} else {	/* Expired */
+			add_header(&req, "Subscription-State", "terminated;reason=timeout");
+		}
+	}
+
+	switch (p->subscribed) {
+	case XPIDF_XML:
+	case DIALOG_RLMI_XML:
+		rlist = p->rlist;
+		if(rlist) {
+			add_header(&req, "Require", "eventlist");
+			/* since multipart/related is involved, boundary and start must be added to Content-Type */
+			ast_str_append(&content_type, 0, "multipart/related;type=\"%s\";", subscriptiontype->mediatype);
+			ast_str_append(&content_type, 0, "start=\"<%s@%s>\";", rlist->contentid, p->fromdomain);
+			ast_str_append(&content_type, 0, "boundary=\"%s\"", boundary); //todohere better boundary
+			add_header(&req, "Content-Type", ast_str_buffer(content_type));
+
+			/* most of the Content of this NOTIFY is created in state_notify_build, 
+	 		* but when multipart/related is involved, some over head must be done here */
+			ast_str_append(&tmp, 0, "--%s\r\n", boundary);
+			ast_str_append(&tmp, 0, "Content-Transfer-Encoding: binary\r\n");
+			ast_str_append(&tmp, 0, "Content-ID: <%s@%s>\r\n", rlist->contentid, p->fromdomain);
+			ast_str_append(&tmp, 0, "Content-Type: %s; charset=\"UTF-8\"\r\n\r\n", subscriptiontype->mediatype);
+
+			/* building the RLMI portion */
+			state_notify_build(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto);
+
+			/* building the other part of the multipart/related RLMI */
+			subscriptiontype = find_subscription_type(p->multipart_subscribed);
+			AST_LIST_TRAVERSE(&rlist->resources, resource, entry) {
+				ast_str_append(&tmp, 0, "\r\n--%s\r\n", boundary);
+				ast_str_append(&tmp, 0, "Content-Transfer-Encoding: binary\r\n");
+				ast_str_append(&tmp, 0, "Content-ID: <%s@%s>\r\n", resource->contentid, p->fromdomain);
+				ast_str_append(&tmp, 0, "Content-Type: %s\r\n\r\n", subscriptiontype->mediatype);
+
+				//todohere, if not full, then only transmit resources marked for update
+				state_notify_build(resource->laststate, full, resource->exten, rlist->context, &tmp, p, p->multipart_subscribed, mfrom, mto);
+			}
+			ast_str_append(&tmp, 0, "\r\n--%s", boundary);
+
+			/* Event header matches the second part of the multipart/related */
+			add_header(&req, "Event", subscriptiontype->event);
+		} else {
+			ast_log(LOG_WARNING, "transmit_state_notify() NOTIFY rlmi, but no resource list\n");
+			return -1;
+		}
+		break;
+	case CPIM_PIDF_XML:
+		add_header(&req, "Event", subscriptiontype->event);
+		state_notify_build(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto);
+		add_header(&req, "Content-Type", subscriptiontype->mediatype);
+		break;
+	case PIDF_XML: /* Eyebeam supports this format */
+		add_header(&req, "Event", subscriptiontype->event);
+		state_notify_build(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto);
+		add_header(&req, "Content-Type", subscriptiontype->mediatype);
+		break;
+	case DIALOG_INFO_XML: /* SNOM subscribes in this format */
+		add_header(&req, "Event", subscriptiontype->event);
+		state_notify_build(state, full, p->exten, p->context, &tmp, p, p->subscribed, mfrom, mto);
+		add_header(&req, "Content-Type", subscriptiontype->mediatype);
+		break;
+	case NONE:
+	default:
+		break;
+	}
 
 	add_header_contentLength(&req, tmp->used);
 	add_line(&req, tmp->str);
 
 	p->pendinginvite = p->ocseq;	/* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */
+
+ast_log(LOG_NOTICE, "-----------------THE ENTIRE SIP NOTIFY IS-----------\n%s", ast_str_buffer(req.data));//todohere remove
 
 	return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
 }
@@ -12197,7 +12279,7 @@
 	ao2_unlock(peer);
 }
 
-static int cb_rlist_extensionstate(char *context, char* exten, int state, void *data)
+static int cb_rlist_extensionstate(char *context, char *exten, int state, void *data)
 {
 	struct sip_rlist *rlist = data;
 	struct sip_rlist_resource *resource;
@@ -21033,8 +21115,22 @@
 		/* Polycom phones only handle xpidf+xml, even if they say they can
 		   handle pidf+xml as well
 		*/
-		if (strstr(acceptheader, "application/rlmi+xml")) {
+		if (strstr(acceptheader, "application/rlmi+xml") && strstr(acceptheader, "multipart/related")) {
+			int i;
 			p->subscribed = DIALOG_RLMI_XML;
+			for (i = 1; i < ARRAY_LEN(subscription_types); i++) {
+				if (strstr(acceptheader, subscription_types[i].mediatype) && subscription_types[i].type != p->subscribed) {
+					p->multipart_subscribed = subscription_types[i].type;
+				}
+			}
+			/* second part of multipart/related not present.  send back bad event */
+			if (!p->multipart_subscribed) {
+				transmit_response(p, "489 Bad Event", req);
+				ast_log(LOG_WARNING, "SUBSCRIBE failure: Multipart RLMI malformed Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
+					p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
+				pvt_set_needdestroy(p, "Multipart RLMI malformed Accept header");
+				return 0;
+			}
 		} else if (strstr(p->useragent, "Polycom")) {
 			p->subscribed = XPIDF_XML;
 		} else if (strstr(acceptheader, "application/pidf+xml")) {
@@ -21049,7 +21145,6 @@
 		} else if (ast_strlen_zero(acceptheader)) {
 			if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
 				transmit_response(p, "489 Bad Event", req);
-  
 				ast_log(LOG_WARNING, "SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
 					p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
 				pvt_set_needdestroy(p, "no Accept header");




More information about the asterisk-commits mailing list