--- channels/chan_sip.c.working	2005-07-23 23:41:23.435918112 +0200
+++ channels/chan_sip.c	2005-07-24 20:07:50.079047952 +0200
@@ -6610,6 +6610,84 @@
 	return 0;
 }
 
+/*--- send_message_by_name: Sends SIP MESSAGE to user peername. Does a lookup on callerid
+ *      for correct from address setting (will probably not work if sender's domain is
+ *      different) */
+static int send_message_by_name(char *from, char *peername, char *content_type, char *text)
+{
+	struct sip_pvt *p;
+	struct sip_peer *r;
+	struct sip_request req;
+	char *sender_peername, *tmp, *tmp1;
+	char clen[256];
+
+	p = sip_alloc(NULL, NULL, 0, SIP_MESSAGE);
+	if (!p) {
+		ast_log(LOG_WARNING, "Unable to build sip pvt data for message\n");
+		return RESULT_FAILURE;
+	}
+
+	if (create_addr(p, peername)) {
+		sip_destroy(p);
+		ast_log(LOG_WARNING, "Could not create address for '%s'\n", peername);
+		return RESULT_FAILURE;
+	}
+
+
+	/* parse from and get their callerid */
+
+	sender_peername=ast_strdupa(from);
+	tmp=strstr(sender_peername,"sip:");
+	if (tmp) {
+		tmp+=4;
+		sender_peername=tmp;
+		if ((tmp=strstr(sender_peername,"@")))
+		{
+			*tmp='\0';
+			tmp++;
+			if ((tmp1=strstr(tmp,">"))) {
+				*tmp1='\0';
+				strcpy(p->fromdomain,tmp);
+			}
+		}
+		r=find_peer(sender_peername,NULL,1);
+		if (r) {
+			if (!ast_strlen_zero(r->cid_name))
+				strcpy(p->fromname,r->cid_name);
+			if (!ast_strlen_zero(r->cid_num))
+				strcpy(p->fromuser,r->cid_num);
+			if (!ast_strlen_zero(r->fromdomain))
+				strcpy(p->fromdomain,r->fromdomain);
+		}
+	}
+
+	initreqprep(&req, p, SIP_MESSAGE, NULL);
+	/* Recalculate our side, and recalculate Call ID */
+	if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
+		memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
+	build_via(p, p->via, sizeof(p->via));
+	build_callid(p->callid, sizeof(p->callid), p->ourip, p->fromdomain);
+
+
+	// These are added by initreqprep
+	// add_header(&req, "From", callerid);
+	// add_header(&req, "To", peername);
+
+	// we could use addtext, but we want to support different content-types, such
+	// as application/im-iscomposing+xml
+	// add_text(&req, text);
+
+	snprintf(clen, sizeof(clen), "%d", strlen(text));
+	add_header(&req, "Content-Type", content_type);
+	add_header(&req, "Content-Length", clen);
+	add_line(&req, text);
+
+	transmit_sip_request(p, &req);
+	sip_scheddestroy(p, 15000);
+	return RESULT_SUCCESS;
+}
+
+
 /*--- receive_message: Receive SIP MESSAGE method messages ---*/
 /*	We only handle messages within current calls currently */
 /*	Reference: RFC 3428 */
@@ -6618,10 +6696,14 @@
 	char buf[1024];
 	struct ast_frame f;
 	char *content_type;
+	char *message_to = "";
+	char *type;
+	char *tmp;
+	char hint[AST_MAX_EXTENSION];
 
 	content_type = get_header(req, "Content-Type");
 
-	if (strcmp(content_type, "text/plain")) {
+	if ( (strcmp(content_type, "text/plain")) && (strcmp(content_type, "application/im-iscomposing+xml"))) {
 		/* No text/plain attachment */
 		transmit_response(p, "415 unsupported media type", req);	/* Good enough or? */
 		ast_set_flag(p, SIP_NEEDDESTROY);
@@ -6648,9 +6730,35 @@
 		transmit_response(p, "202 Accepted", req);
 		/* We respond 202 accepted, since we relay the message */
 	} else {
-		/* Message outside of a call, we do not support that */
+		/* Preliminary support for SIP MESSAGE sending based on hints */
+		  tmp=get_header(req,"To");
+		  if (! (tmp=strstr(tmp,"sip:")))
+                    {
+		     ast_log(LOG_WARNING,"Received message to %s from %s, dropped it because target is not sip and we don't support that...\n  Content-Type:%s\n  Message: %s\n", get_header(req,"To"), get_header(req,"From"), content_type, buf);
+		     transmit_response(p, "405 Method not allowed", req);
+		     return;
+		    }
+		  tmp+=4;
+		  message_to=ast_strdupa(tmp);
+		  if ((tmp=strstr(message_to,"@"))) 
+			  *tmp='\0';
+		  if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, "default", message_to)) {
+			message_to=hint;
+			type=strsep(&message_to,"/");
+			if (strncmp(type,"SIP",3)) {
+				ast_log(LOG_WARNING,"Received message to %s from %s, dropped it, because hint channel type is not SIP, but %s. We don't support this...\n  Content-Type:%s\n  Message: %s\n", get_header(req,"To"), get_header(req,"From"), type, content_type, buf);
+		     		transmit_response(p, "405 Method not allowed", req);
+		     		return;
+			}
+			if (send_message_by_name(get_header(req,"From"), message_to, 
+						content_type, buf))
+				transmit_response(p, "405 Method not allowed", req);
+			else
+				transmit_response(p, "202 Accepted", req);
+		} else {
 		ast_log(LOG_WARNING,"Received message to %s from %s, dropped it...\n  Content-Type:%s\n  Message: %s\n", get_header(req,"To"), get_header(req,"From"), content_type, buf);
 		transmit_response(p, "405 Method not allowed", req);	/* Good enough or? */
+		}
 	}
 	ast_set_flag(p, SIP_NEEDDESTROY);
 	return;

