Index: chan_iax2.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_iax2.c,v
retrieving revision 1.88
diff -u -r1.88 chan_iax2.c
--- chan_iax2.c	12 Jan 2004 18:03:35 -0000	1.88
+++ chan_iax2.c	21 Jan 2004 20:26:32 -0000
@@ -585,6 +585,9 @@
 		strncpy(tmp->exten, "s", sizeof(tmp->exten)-1);
 		if (!iax2_getpeername(*sin, tmp->host, sizeof(tmp->host), lockpeer))
 			snprintf(tmp->host, sizeof(tmp->host), "%s:%d", inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
+
+
+
 	}
 	return tmp;
 }
@@ -1782,6 +1785,7 @@
 	char context[AST_MAX_EXTENSION] ="";
 	char *portno = NULL;
 	char *opts = "";
+	char *tmp;
 	struct chan_iax2_pvt *p = c->pvt->pvt;
 	char *stringp=NULL;
 	char storedsecret[80];
@@ -1826,6 +1830,17 @@
 		strsep(&stringp, ":");
 		portno = strsep(&stringp, ":");
 	}
+
+	tmp = strchr(hname,'%');
+	if(tmp) {
+		*tmp = '\0';
+		tmp++;
+		hname = tmp;
+	}
+	
+
+	
+
 	if (create_addr(&sin, NULL, NULL, NULL, hname, context, NULL, NULL, storedsecret, sizeof(storedsecret) - 1)) {
 		ast_log(LOG_WARNING, "No address associated with '%s'\n", hname);
 		return -1;
@@ -2549,6 +2564,16 @@
 #undef FORMAT2
 }
 
+static int get_host_capability(char *host) {
+	struct iax2_peer *peer;
+	for (peer = peerl.peers;peer;peer = peer->next) {
+		if(!strcmp(peer->name,host))
+			return peer->capability;
+	}
+	return 0;
+}
+
+
 static int iax2_show_peers(int fd, int argc, char *argv[])
 {
 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %-10s\n"
@@ -3952,6 +3977,7 @@
 	int format;
 	int exists;
 	int mm;
+	int cap;
 	int minivid = 0;
 	unsigned int ts;
 	char empty[32]="";		/* Safety measure */
@@ -4613,13 +4639,26 @@
 					send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
 				} else {
 					/* Select an appropriate format */
+					
+
+					/* match the capabilities of the peer we called by */
+					cap = get_host_capability(iaxs[fr.callno]->host);
+					if(cap)
+						iaxs[fr.callno]->capability = cap;
+
 					format = iaxs[fr.callno]->peerformat & iaxs[fr.callno]->capability;
 					if (!format) {
 						ast_log(LOG_DEBUG, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr.callno]->peerformat), iaxs[fr.callno]->peercapability);
+
+
+
+
 						format = iaxs[fr.callno]->peercapability & iaxs[fr.callno]->capability;
+
+						
 						if (!format) {
 							if (authdebug)
-								ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible  with our capability 0x%x.\n", inet_ntoa(sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability);
+								ast_log(LOG_NOTICE, "[%s]: Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible  with our capability 0x%x.\n", iaxs[fr.callno]->host,inet_ntoa(sin.sin_addr), iaxs[fr.callno]->peerformat, iaxs[fr.callno]->peercapability, iaxs[fr.callno]->capability);
 							memset(&ied0, 0, sizeof(ied0));
 							iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
 							send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
@@ -4987,27 +5026,62 @@
 	int maxtime;
 	int fmt, native;
 	struct sockaddr_in sin;
-	char s[256];
+	char sval[256];
+	char *s;
 	char *st;
 	struct ast_channel *c;
 	char *stringp=NULL;
 	int capability = iax2_capability;
 	int trunk;
 	int notransfer = 0;
-	strncpy(s, (char *)data, sizeof(s)-1);
+	char *codecname;
+	int codec;
+
+	strncpy(sval, (char *)data, sizeof(sval)-1);
+	s=codecname=sval;
+
+    s = strchr(codecname,'%');
+	if(s) {
+		*s = '\0';
+		s++;
+	}
+	else {
+		s=sval;
+		codecname = NULL;
+	}
+
+
+
 	/* FIXME The next two lines seem useless */
 	stringp=s;
 	strsep(&stringp, "/");
 
+
 	stringp=s;
 	strsep(&stringp, "@");
+
 	st = strsep(&stringp, "@");
+
+
 	if (!st)
 		st = s;
+
+
 	/* Populate our address from the given */
 	if (create_addr(&sin, &capability, &sendani, &maxtime, st, NULL, &trunk, &notransfer, NULL, 0)) {
 		return NULL;
 	}
+	
+	if(codecname) {
+		codec = ast_getformatbyname(codecname);
+		if(codec < 1)
+			ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", codecname);
+		else 
+			ast_log(LOG_WARNING, "using override format '%s'\n", codecname);
+			capability = codec;
+	}
+
+
 	callno = find_callno(0, 0, &sin, NEW_FORCE, 1);
 	if (callno < 1) {
 		ast_log(LOG_WARNING, "Unable to create call\n");
@@ -5273,6 +5347,8 @@
 		if (!found && peer->dynamic)
 			reg_source_db(peer);
 	}
+	
+
 	return peer;
 }
 
