diff --git a/channels/chan_iax.c b/channels/chan_iax.c
index 679ba65a5086dd83979f654a67036633494e7916..74c75393e03999b6c02800e9c92eb7ae4ad5b5b7 100755
--- a/channels/chan_iax.c
+++ b/channels/chan_iax.c
@@ -42,6 +42,15 @@
 
 #include "iax.h"
 
+/*
+ * Uncomment to try experimental IAX bridge optimization,
+ * designed to reduce latency when IAX calls cannot
+ * be trasnferred
+ */
+
+#define BRIDGE_OPTIMIZATION 
+
+
 #define DEFAULT_RETRY_TIME 1000
 #define MEMORY_SIZE 100
 #define DEFAULT_DROP 3
@@ -161,7 +170,10 @@ struct iax_peer {
 	char inkeys[80];				/* Key(s) this peer can use to authenticate to us */
 
 	int hascallerid;
+	/* Suggested caller id if registering */
 	char callerid[AST_MAX_EXTENSION];
+	/* Whether or not to send ANI */
+	int sendani;
 	int expire;						/* Schedule entry for expirey */
 	int expirey;					/* How soon to expire */
 	int capability;					/* Capability */
@@ -268,8 +280,10 @@ struct chan_iax_pvt {
 	char context[80];
 	/* Caller ID if available */
 	char callerid[80];
-	/* Hidden Caller ID if appropriate */
-	char hidden_callerid[80];
+	/* Hidden Caller ID (i.e. ANI) if appropriate */
+	char ani[80];
+	/* Whether or not ani should be transmitted in addition to Caller*ID */
+	int sendani;
 	/* DNID */
 	char dnid[80];
 	/* Requested Extension */
@@ -519,8 +533,12 @@ static unsigned int calc_timestamp(struct chan_iax_pvt *p, unsigned int ts);
 static int send_ping(void *data)
 {
 	int callno = (long)data;
+	/* Ping only if it's real, not if it's bridged */
 	if (iaxs[callno]) {
-		send_command(iaxs[callno], AST_FRAME_IAX, AST_IAX_COMMAND_PING, 0, NULL, 0, -1);
+#ifdef BRIDGE_OPTIMIZATION
+		if (iaxs[callno]->bridgecallno < 0)
+#endif		
+			send_command(iaxs[callno], AST_FRAME_IAX, AST_IAX_COMMAND_PING, 0, NULL, 0, -1);
 		return 1;
 	} else
 		return 0;
@@ -529,8 +547,12 @@ static int send_ping(void *data)
 static int send_lagrq(void *data)
 {
 	int callno = (long)data;
+	/* Ping only if it's real not if it's bridged */
 	if (iaxs[callno]) {
-		send_command(iaxs[callno], AST_FRAME_IAX, AST_IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
+#ifdef BRIDGE_OPTIMIZATION
+		if (iaxs[callno]->bridgecallno < 0)
+#endif		
+			send_command(iaxs[callno], AST_FRAME_IAX, AST_IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
 		return 1;
 	} else
 		return 0;
@@ -734,7 +756,7 @@ static int find_callno(short callno, short dcallno ,struct sockaddr_in *sin, int
 	if ((res < 0) && (new >= NEW_ALLOW)) {
 		/* Create a new one */
 		start = nextcallno;
-		for (x = nextcallno + 1; iaxs[x] && (x != start); x = (x + 1) % AST_IAX_MAX_CALLS) 
+		for (x = (nextcallno + 1) % AST_IAX_MAX_CALLS; iaxs[x] && (x != start); x = (x + 1) % AST_IAX_MAX_CALLS) 
 		if (x == start) {
 			ast_log(LOG_WARNING, "Unable to accept more calls\n");
 			return -1;
@@ -1106,6 +1128,22 @@ static struct ast_cli_entry cli_show_cache =
 
 static unsigned int calc_rxstamp(struct chan_iax_pvt *p);
 
+#ifdef BRIDGE_OPTIMIZATION
+static unsigned int calc_fakestamp(struct chan_iax_pvt *from, struct chan_iax_pvt *to, unsigned int ts);
+
+static int forward_delivery(struct ast_iax_frame *fr)
+{
+	struct chan_iax_pvt *p1, *p2;
+	p1 = iaxs[fr->callno];
+	p2 = iaxs[p1->bridgecallno];
+	/* Fix relative timestamp */
+	fr->ts = calc_fakestamp(p1, p2, fr->ts);
+	/* Now just send it send on the 2nd one 
+	   with adjusted timestamp */
+	return iax_send(p2, fr->f, fr->ts, -1, 0, 0, 0);
+}
+#endif
+
 static int schedule_delivery(struct ast_iax_frame *fr, int reallydeliver)
 {
 	int ms,x;
@@ -1114,6 +1152,7 @@ static int schedule_delivery(struct ast_iax_frame *fr, int reallydeliver)
 	/* ms is a measure of the "lateness" of the packet relative to the first
 	   packet we received, which always has a lateness of 1.  */
 	ms = calc_rxstamp(iaxs[fr->callno]) - fr->ts;
+
 	if (ms > 32768) {
 		/* What likely happened here is that our counter has circled but we haven't
 		   gotten the update from the main packet.  We'll just pretend that we did, and
@@ -1292,11 +1331,13 @@ static int iax_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan
 	return 0;
 }
 
-static int create_addr(struct sockaddr_in *sin, int *capability, char *peer)
+static int create_addr(struct sockaddr_in *sin, int *capability, int *sendani, char *peer)
 {
 	struct hostent *hp;
 	struct iax_peer *p;
 	int found=0;
+	if (sendani)
+		*sendani = 0;
 	sin->sin_family = AF_INET;
 	ast_pthread_mutex_lock(&peerl.lock);
 	p = peerl.peers;
@@ -1306,6 +1347,8 @@ static int create_addr(struct sockaddr_in *sin, int *capability, char *peer)
 			if (capability)
 				*capability = p->capability;
 			if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
+				if (sendani)
+					*sendani = p->sendani;
 				if (p->addr.sin_addr.s_addr) {
 					sin->sin_addr = p->addr.sin_addr;
 					sin->sin_port = p->addr.sin_port;
@@ -1376,7 +1419,7 @@ static int iax_call(struct ast_channel *c, char *dest, int timeout)
 		strtok(hname, ":");
 		portno = strtok(hname, ":");
 	}
-	if (create_addr(&sin, NULL, hname)) {
+	if (create_addr(&sin, NULL, NULL, hname)) {
 		ast_log(LOG_WARNING, "No address associated with '%s'\n", hname);
 		return -1;
 	}
@@ -1389,6 +1432,8 @@ static int iax_call(struct ast_channel *c, char *dest, int timeout)
 	MYSNPRINTF "exten=%s;", rdest);
 	if (c->callerid)
 		MYSNPRINTF "callerid=%s;", c->callerid);
+	if (p->sendani && c->ani)
+		MYSNPRINTF "ani=%s;", c->ani);
 	if (c->language && strlen(c->language))
 		MYSNPRINTF "language=%s;", c->language);
 	if (c->dnid)
@@ -1548,8 +1593,11 @@ static int iax_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
 	cs[1] = c1;
 	for (/* ever */;;) {
 		/* Check in case we got masqueraded into */
-		if ((c0->type != type) || (c1->type != type))
+		if ((c0->type != type) || (c1->type != type)) {
+			if (option_verbose > 2)
+				ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
 			return -2;
+		}
 		if (!transferstarted) {
 			/* Try the transfer */
 			if (iax_start_transfer(c0, c1))
@@ -1708,8 +1756,8 @@ static struct ast_channel *ast_iax_new(struct chan_iax_pvt *i, int state, int ca
 		tmp->pvt->bridge = iax_bridge;
 		if (strlen(i->callerid))
 			tmp->callerid = strdup(i->callerid);
-		if (strlen(i->hidden_callerid))
-			tmp->hidden_callerid = strdup(i->hidden_callerid);
+		if (strlen(i->ani))
+			tmp->ani = strdup(i->ani);
 		if (strlen(i->language))
 			strncpy(tmp->language, i->language, sizeof(tmp->language)-1);
 		if (strlen(i->dnid))
@@ -1758,13 +1806,42 @@ static unsigned int calc_timestamp(struct chan_iax_pvt *p, unsigned int ts)
 	return ms;
 }
 
+#ifdef BRIDGE_OPTIMIZATION
+static unsigned int calc_fakestamp(struct chan_iax_pvt *p1, struct chan_iax_pvt *p2, unsigned int fakets)
+{
+	int ms;
+	/* Receive from p1, send to p2 */
+	
+	/* Setup rxcore if necessary on outgoing channel */
+	if (!p1->rxcore.tv_sec && !p1->rxcore.tv_usec)
+		gettimeofday(&p1->rxcore, NULL);
+
+	/* Setup txcore if necessary on outgoing channel */
+	if (!p2->offset.tv_sec && !p2->offset.tv_usec)
+		gettimeofday(&p2->offset, NULL);
+	
+	/* Now, ts is the timestamp of the original packet in the orignal context.
+	   Adding rxcore to it gives us when we would want the packet to be delivered normally.
+	   Subtracting txcore of the outgoing channel gives us what we'd expect */
+	
+	ms = (p1->rxcore.tv_sec - p2->offset.tv_sec) * 1000 + (p1->rxcore.tv_usec - p1->offset.tv_usec) / 1000;
+	fakets += ms;
+	if (fakets <= p2->lastsent)
+		fakets = p2->lastsent + 1;
+	p2->lastsent = fakets;
+	return fakets;
+}
+#endif
+
 static unsigned int calc_rxstamp(struct chan_iax_pvt *p)
 {
 	/* Returns where in "receive time" we are */
 	struct timeval tv;
 	unsigned int ms;
+	/* Setup rxcore if necessary */
 	if (!p->rxcore.tv_sec && !p->rxcore.tv_usec)
 		gettimeofday(&p->rxcore, NULL);
+
 	gettimeofday(&tv, NULL);
 	ms = (tv.tv_sec - p->rxcore.tv_sec) * 1000 + (tv.tv_usec - p->rxcore.tv_usec) / 1000;
 	return ms;
@@ -2099,6 +2176,13 @@ static int send_command(struct chan_iax_pvt *i, char type, int command, unsigned
 	return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
 }
 
+#ifdef BRIDGE_OPTIMIZATION
+static int forward_command(struct chan_iax_pvt *i, char type, int command, unsigned int ts, char *data, int datalen, int seqno)
+{
+	return __send_command(iaxs[i->bridgecallno], type, command, ts, data, datalen, seqno, 0, 0, 0);
+}
+#endif
+
 static int send_command_final(struct chan_iax_pvt *i, char type, int command, unsigned int ts, char *data, int datalen, int seqno)
 {
 	iax_predestroy(i);
@@ -2183,6 +2267,8 @@ static int check_access(int callno, struct sockaddr_in *sin, char *orequest, int
 				strncpy(iaxs[callno]->exten, value, sizeof(iaxs[callno]->exten)-1);
 			else if (!strcmp(var, "callerid"))
 				strncpy(iaxs[callno]->callerid, value, sizeof(iaxs[callno]->callerid)-1);
+			else if (!strcmp(var, "ani"))
+				strncpy(iaxs[callno]->ani, value, sizeof(iaxs[callno]->ani) - 1);
 			else if (!strcmp(var, "dnid"))
 				strncpy(iaxs[callno]->dnid, value, sizeof(iaxs[callno]->dnid)-1);
 			else if (!strcmp(var, "context"))
@@ -2239,11 +2325,11 @@ static int check_access(int callno, struct sockaddr_in *sin, char *orequest, int
 			strncpy(iaxs[callno]->inkeys, user->inkeys, sizeof(iaxs[callno]->inkeys));
 			/* And the permitted authentication methods */
 			strncpy(iaxs[callno]->methods, user->methods, sizeof(iaxs[callno]->methods)-1);
-			/* If they have callerid, override the given caller id.  Always store the hidden */
+			/* If they have callerid, override the given caller id.  Always store the ANI */
 			if (strlen(iaxs[callno]->callerid)) {
 				if (user->hascallerid)
 					strncpy(iaxs[callno]->callerid, user->callerid, sizeof(iaxs[callno]->callerid)-1);
-				strncpy(iaxs[callno]->hidden_callerid, user->callerid, sizeof(iaxs[callno]->hidden_callerid)-1);
+				strncpy(iaxs[callno]->ani, user->callerid, sizeof(iaxs[callno]->ani)-1);
 			}
 			if (strlen(user->accountcode))
 				strncpy(iaxs[callno]->accountcode, user->accountcode, sizeof(iaxs[callno]->accountcode)-1);
@@ -2332,7 +2418,7 @@ static int authenticate_verify(struct chan_iax_pvt *p, char *orequest)
 				res = 0;
 				break;
 			} else if (!key)
-				ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n");
+				ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
 			keyn = strtok(NULL, ":");
 		}
 	} else if (strstr(p->methods, "md5")) {
@@ -3364,24 +3450,53 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
 				ast_pthread_mutex_unlock(&dpcache_lock);
 				break;
 			case AST_IAX_COMMAND_PING:
+#ifdef BRIDGE_OPTIMIZATION
+				if (iaxs[fr.callno]->bridgecallno > -1) {
+					/* If we're in a bridged call, just forward this */
+					forward_command(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_PING, fr.ts, NULL, 0, -1);
+				} else {
+					/* Send back a pong packet with the original timestamp */
+					send_command(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_PONG, fr.ts, NULL, 0, -1);
+				}
+#else				
 				/* Send back a pong packet with the original timestamp */
 				send_command(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_PONG, fr.ts, NULL, 0, -1);
+#endif				
 				break;
 			case AST_IAX_COMMAND_PONG:
+#ifdef BRIDGE_OPTIMIZATION
+				if (iaxs[fr.callno]->bridgecallno > -1) {
+					/* Forward to the other side of the bridge */
+					forward_command(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_PONG, fr.ts, NULL, 0, -1);
+				} else {
+					/* Calculate ping time */
+					iaxs[fr.callno]->pingtime =  calc_timestamp(iaxs[fr.callno], 0) - fr.ts;
+				}
+#else
+				/* Calculate ping time */
 				iaxs[fr.callno]->pingtime =  calc_timestamp(iaxs[fr.callno], 0) - fr.ts;
+#endif					
 				break;
 			case AST_IAX_COMMAND_LAGRQ:
 			case AST_IAX_COMMAND_LAGRP:
-				/* A little strange -- We have to actually go through the motions of
-				   delivering the packet.  In the very last step, it will be properly
-				   handled by do_deliver */
-				snprintf(src, sizeof(src), "LAGRQ-IAX/%s/%d", inet_ntoa(sin.sin_addr),fr.callno);
-				f.src = src;
-				f.mallocd = 0;
-				f.offset = 0;
-				fr.f = &f;
-				f.timelen = 0;
-				schedule_delivery(iaxfrdup2(&fr, 0), 1);
+#ifdef BRIDGE_OPTIMIZATION
+				if (iaxs[fr.callno]->bridgecallno > -1) {
+					forward_command(iaxs[fr.callno], AST_FRAME_IAX, f.subclass, fr.ts, NULL, 0, -1);
+				} else {
+#endif				
+					/* A little strange -- We have to actually go through the motions of
+					   delivering the packet.  In the very last step, it will be properly
+					   handled by do_deliver */
+					snprintf(src, sizeof(src), "LAGRQ-IAX/%s/%d", inet_ntoa(sin.sin_addr),fr.callno);
+					f.src = src;
+					f.mallocd = 0;
+					f.offset = 0;
+					fr.f = &f;
+					f.timelen = 0;
+					schedule_delivery(iaxfrdup2(&fr, 0), 1);
+#ifdef BRIDGE_OPTIMIZATION
+				}
+#endif				
 				break;
 			case AST_IAX_COMMAND_AUTHREQ:
 				if (iaxs[fr.callno]->state & (IAX_STATE_STARTED | IAX_STATE_TBD)) {
@@ -3632,7 +3747,15 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
 			ast_log(LOG_DEBUG, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr.ts, iaxs[fr.callno]->last);
 		fr.outoforder = -1;
 	}
+#ifdef BRIDGE_OPTIMIZATION
+	if (iaxs[fr.callno]->bridgecallno > -1) {
+		forward_delivery(&fr);
+	} else {
+		schedule_delivery(iaxfrdup2(&fr, 0), 1);
+	}
+#else
 	schedule_delivery(iaxfrdup2(&fr, 0), 1);
+#endif
 	/* Always run again */
 	ast_pthread_mutex_unlock(&iaxs_lock);
 	return 1;
@@ -3690,6 +3813,7 @@ static struct ast_channel *iax_request(char *type, int format, void *data)
 {
 	int callno;
 	int res;
+	int sendani;
 	int fmt, native;
 	struct sockaddr_in sin;
 	char s[256];
@@ -3703,7 +3827,7 @@ static struct ast_channel *iax_request(char *type, int format, void *data)
 	if (!st)
 		st = s;
 	/* Populate our address from the given */
-	if (create_addr(&sin, &capability, st)) {
+	if (create_addr(&sin, &capability, &sendani, st)) {
 		return NULL;
 	}
 	ast_pthread_mutex_lock(&iaxs_lock);
@@ -3712,6 +3836,8 @@ static struct ast_channel *iax_request(char *type, int format, void *data)
 		ast_log(LOG_WARNING, "Unable to create call\n");
 		return NULL;
 	}
+	/* Keep track of sendani flag */
+	iaxs[callno]->sendani = sendani;
 	c = ast_iax_new(iaxs[callno], AST_STATE_DOWN, capability);
 	if (c) {
 		/* Choose a format we can live with */
@@ -3963,6 +4089,8 @@ static struct iax_peer *build_peer(char *name, struct ast_variable *v)
 			} else if (!strcasecmp(v->name, "callerid")) {
 				strncpy(peer->callerid, v->value, sizeof(peer->callerid)-1);
 				peer->hascallerid=1;
+			} else if (!strcasecmp(v->name, "sendani")) {
+				peer->sendani = ast_true(v->value);
 			} else if (!strcasecmp(v->name, "inkeys")) {
 				strncpy(peer->inkeys, v->value, sizeof(peer->inkeys));
 			} else if (!strcasecmp(v->name, "outkey")) {
@@ -4293,7 +4421,7 @@ static int cache_get_callno(char *data)
 		host = st;
 	}
 	/* Populate our address from the given */
-	if (create_addr(&sin, NULL, host)) {
+	if (create_addr(&sin, NULL, NULL, host)) {
 		return -1;
 	}
 	ast_log(LOG_DEBUG, "host: %s, user: %s, password: %s, context: %s\n", host, username, password, context);
diff --git a/channels/chan_phone.c b/channels/chan_phone.c
index c481abb99264b569bda45873be6babcac632e946..7300646b60e72d813237336d3b09ddde1606467a 100755
--- a/channels/chan_phone.c
+++ b/channels/chan_phone.c
@@ -588,6 +588,8 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *conte
 		tmp->fds[0] = i->fd;
 		/* XXX Switching formats silently causes kernel panics XXX */
 		tmp->nativeformats = prefformat;
+		tmp->pvt->rawreadformat = prefformat;
+		tmp->pvt->rawwriteformat = prefformat;
 		tmp->state = state;
 		if (state == AST_STATE_RING)
 			tmp->rings = 1;
@@ -911,7 +913,7 @@ static struct phone_pvt *mkif(char *iface, int mode, int txgain, int rxgain)
 				ast_log(LOG_DEBUG, "Unable to set port to PSTN\n");
 		} else {
 			if (ioctl(tmp->fd, IXJCTL_PORT, PORT_POTS)) 
-				ast_log(LOG_DEBUG, "Unable to set port to PSTN\n");
+				ast_log(LOG_DEBUG, "Unable to set port to POTS\n");
 		}
 		ioctl(tmp->fd, PHONE_PLAY_STOP);
 		ioctl(tmp->fd, PHONE_REC_STOP);
@@ -1088,7 +1090,7 @@ int load_module()
 	ast_pthread_mutex_unlock(&iflock);
 	/* Make sure we can register our Adtranphone channel type */
 	if (ast_channel_register(type, tdesc, 
-			AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW, phone_request)) {
+			 AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW, phone_request)) {
 		ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
 		ast_destroy(cfg);
 		unload_module();