diff --git a/channels/chan_iax.c b/channels/chan_iax.c
index 80e19058cf71f37e55fca709c76846eb34307408..272228e86a678fcf4ef20568fcb7b8174b884841 100755
--- a/channels/chan_iax.c
+++ b/channels/chan_iax.c
@@ -452,8 +452,9 @@ static int do_deliver(void *data)
 				ts = calc_timestamp(iaxs[fr->callno], 0);
 				iaxs[fr->callno]->lag = ts - fr->ts;
 			}
-		} else
+		} else {
 			ast_fr_fdwrite(iaxs[fr->callno]->pipe[1], fr->f);
+		}
 	}
 	/* Free the packet */
 	ast_frfree(fr->f);
@@ -899,14 +900,15 @@ static int iax_call(struct ast_channel *c, char *dest, int timeout)
 	char *hname;
 	char requeststr[256] = "";
 	char myrdest [5] = "s";
+	char *portno = NULL;
 	if ((c->state != AST_STATE_DOWN) && (c->state != AST_STATE_RESERVED)) {
 		ast_log(LOG_WARNING, "Line is already in use (%s)?\n", c->name);
 		return -1;
 	}
 	strncpy(host, dest, sizeof(host));
-	strtok(host, ":");
+	strtok(host, "/");
 	/* If no destination extension specified, use 's' */
-	rdest = strtok(NULL, ":");
+	rdest = strtok(NULL, "/");
 	if (!rdest) 
 		rdest = myrdest;
 	strtok(rdest, "@");
@@ -920,10 +922,17 @@ static int iax_call(struct ast_channel *c, char *dest, int timeout)
 	} else {
 		hname = host;
 	}
+	if (strtok(hname, ":")) {
+		strtok(hname, ":");
+		portno = strtok(hname, ":");
+	}
 	if (create_addr(&sin, hname)) {
 		ast_log(LOG_WARNING, "No address associated with '%s'\n", hname);
 		return -1;
 	}
+	if (portno) {
+		sin.sin_port = htons(atoi(portno));
+	}
 	/* Now we build our request string */
 #define MYSNPRINTF snprintf(requeststr + strlen(requeststr), sizeof(requeststr) - strlen(requeststr), 
 	MYSNPRINTF "exten=%s;", rdest);
@@ -942,7 +951,7 @@ static int iax_call(struct ast_channel *c, char *dest, int timeout)
 		requeststr[strlen(requeststr) - 1] = '\0';
 	/* Transmit the string in a "NEW" request */
 	if (option_verbose > 2)
-	ast_verbose(VERBOSE_PREFIX_3 "Calling using options '%s'\n", requeststr);
+		ast_verbose(VERBOSE_PREFIX_3 "Calling using options '%s'\n", requeststr);
 	send_command((struct chan_iax_pvt *)c->pvt->pvt, AST_FRAME_IAX,
 		AST_IAX_COMMAND_NEW, 0, requeststr, strlen(requeststr) + 1, -1);
 	c->state = AST_STATE_RINGING;
@@ -1321,6 +1330,27 @@ static int apply_ha(struct iax_ha *ha, struct sockaddr_in *sin)
 	return res;
 }
 
+static int iax_getformats(int callno, char *orequest)
+{
+	char *var, *value;
+	char request[256];
+	strncpy(request, orequest, sizeof(request));
+	var = strtok(request, ";");
+	while(var) {
+		value = strchr(var, '=');
+		if (value) {
+			*value='\0';
+			value++;
+			if (!strcmp(var, "formats")) {
+				iaxs[callno]->peerformats = atoi(value);
+			} else 
+				ast_log(LOG_WARNING, "Unknown variable '%s' with value '%s'\n", var, value);
+		}
+		var = strtok(NULL, ";");
+	}
+	return 0;
+}
+
 static int check_access(int callno, struct sockaddr_in *sin, char *orequest, int requestl)
 {
 	/* Start pessimistic */
@@ -1688,15 +1718,38 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
 				iax_destroy(fr.callno);
 				break;
 			case AST_IAX_COMMAND_REJECT:
-				((char *)f.data)[f.datalen] = '\0';
+				if (f.data)
+					((char *)f.data)[f.datalen] = '\0';
 				ast_log(LOG_WARNING, "Call rejected by %s: %s\n", inet_ntoa(iaxs[fr.callno]->addr.sin_addr), f.data);
 				iaxs[fr.callno]->error = EPERM;
 				iax_destroy(fr.callno);
 				break;
 			case AST_IAX_COMMAND_ACCEPT:
+				if (f.data) {
+					((char *)f.data)[f.datalen]='\0';
+					iax_getformats(fr.callno, (char *)f.data);
+				} else {
+					iaxs[fr.callno]->peerformats = iax_capability;
+				}
 				if (option_verbose > 2)
 					ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s\n", inet_ntoa(iaxs[fr.callno]->addr.sin_addr));
 				iaxs[fr.callno]->state |= IAX_STATE_STARTED;
+				if (iaxs[fr.callno]->owner) {
+					/* Switch us to use a compatible format */
+					iaxs[fr.callno]->owner->format &= iaxs[fr.callno]->peerformats;
+
+					if (!iaxs[fr.callno]->owner->format) 
+						iaxs[fr.callno]->owner->format = iaxs[fr.callno]->peerformats & iax_capability;
+					if (!iaxs[fr.callno]->owner->format) {
+						ast_log(LOG_WARNING, "Unable to negotiate a common format with the peer.");
+						iaxs[fr.callno]->error = EBADE;
+						iax_destroy(fr.callno);
+					} else {
+						if (option_verbose > 2)
+							ast_verbose(VERBOSE_PREFIX_3 "Format for call is %d\n", iaxs[fr.callno]->owner->format);
+					}
+						
+				}
 				break;
 			case AST_IAX_COMMAND_PING:
 				/* Send back a pong packet with the original timestamp */
diff --git a/codecs/codec_g723_1.c b/codecs/codec_g723_1.c
index b71e28cc2d389db3c29880d7ebce32c9f8e32308..72dcd90133dcd8bcf97a1731ee07405e9f43addf 100755
--- a/codecs/codec_g723_1.c
+++ b/codecs/codec_g723_1.c
@@ -173,16 +173,14 @@ static struct ast_frame *g723tolin_frameout(struct ast_translator_pvt *pvt)
 	tmp->tail = 0;
 
 #if 0
-	/* Save a sample frame */
-	{ static int samplefr = 0;
-	if (samplefr == 80) {
-		int fd;
-		fd = open("g723.example", O_WRONLY | O_CREAT | O_TRUNC, 0644);
-		write(fd, tmp->f.data, tmp->f.datalen);
-		close(fd);
+	/* Save the frames */
+	{ 
+		static int fd2 = -1;
+		if (fd2 == -1) {
+			fd2 = open("g723.example", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+		}
+		write(fd2, tmp->f.data, tmp->f.datalen);
 	} 		
-	samplefr++;
-	}
 #endif
 	return &tmp->f;	
 }
@@ -200,7 +198,7 @@ static int g723tolin_framein(struct ast_translator_pvt *pvt, struct ast_frame *f
 #ifdef ANNEX_B
 		Decod(&tmp->dec, tmpdata, f->data, 0);
 		for (x=0;x<Frame;x++)
-			(tmp->buf + tmp->tail)[x] = (short)tmpdata[x]; 
+			(tmp->buf + tmp->tail)[x] = (short)(tmpdata[x]); 
 #else
 		Decod(&tmp->dec, tmp->buf + tmp->tail, f->data, 0);
 #endif
diff --git a/codecs/codec_gsm.c b/codecs/codec_gsm.c
index 169371230b3d27ed87e910f0e2a587ca3611f98e..9d43f390678237ada2ad5caf0644b46579353ab7 100755
--- a/codecs/codec_gsm.c
+++ b/codecs/codec_gsm.c
@@ -156,7 +156,7 @@ static int lintogsm_framein(struct ast_translator_pvt *tmp, struct ast_frame *f)
 	/* XXX We should look at how old the rest of our stream is, and if it
 	   is too old, then we should overwrite it entirely, otherwise we can
 	   get artifacts of earlier talk that do not belong */
-	if (tmp->tail + f->datalen < sizeof(tmp->buf) / 2) {
+	if (tmp->tail + f->datalen/2 < sizeof(tmp->buf) / 2) {
 		memcpy((tmp->buf + tmp->tail), f->data, f->datalen);
 		tmp->tail += f->datalen/2;
 	} else {
@@ -187,16 +187,14 @@ static struct ast_frame *lintogsm_frameout(struct ast_translator_pvt *tmp)
 	if (tmp->tail)
 		memmove(tmp->buf, tmp->buf + 160, tmp->tail * 2);
 #if 0
-	/* Save a sample frame */
-	{ static int samplefr = 0;
-	if (samplefr == 0) {
-		int fd;
-		fd = open("gsm.example", O_WRONLY | O_CREAT, 0644);
-		write(fd, tmp->f.data, tmp->f.datalen);
-		close(fd);
+	/* Save the frames */
+	{ 
+		static int fd2 = -1;
+		if (fd2 == -1) {
+			fd2 = open("gsm.example", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+		}
+		write(fd2, tmp->f.data, tmp->f.datalen);
 	} 		
-	samplefr++;
-	}
 #endif
 	return &tmp->f;	
 }