This is the last round of RTP bridge optimizations. Basically it introduces a way that under a straight bridge (ie: no transcoding and no DTMF detection) the core is not touched at all and no frames pass through (not even null frames). This is accomplished by stealing the file descriptors from the channel and using the provided IO context with a custom callback. When a channel is placed on hold this bridge is broken so audio can flow from the core to the other side. When a channel is off hold this bridge is re-established.
ast_log(LOG_DEBUG,"RTCP NAT: Got RTCP from other end. Now sending to address %s:%d\n",ast_inet_ntoa(rtp->rtcp->them.sin_addr),ntohs(rtp->rtcp->them.sin_port));
}
}
/* If we are P2P bridged to another RTP stream, send it directly over */
ast_log(LOG_DEBUG,"RTCP Transmission error of packet to %s:%d: %s\n",ast_inet_ntoa(bridged->rtcp->them.sin_addr),ntohs(bridged->rtcp->them.sin_port),strerror(errno));
ast_log(LOG_DEBUG,"RTCP NAT: Can't write RTCP to private address %s:%d, waiting for other end to send first...\n",ast_inet_ntoa(bridged->rtcp->them.sin_addr),ntohs(bridged->rtcp->them.sin_port));
ast_log(LOG_DEBUG,"RTP Transmission error of packet to %s:%d: %s\n",ast_inet_ntoa(bridged->them.sin_addr),ntohs(bridged->them.sin_port),strerror(errno));
ast_log(LOG_DEBUG,"RTP NAT: Can't write RTP to private address %s:%d, waiting for other end to send audio...\n",ast_inet_ntoa(bridged->them.sin_addr),ntohs(bridged->them.sin_port));
ast_set_flag(bridged,FLAG_NAT_INACTIVE_NOWARN);
}
return-1;
}else{
if(rtp_debug_test_addr(&bridged->them))
ast_verbose("Sent RTP P2P packet to %s:%d (type %-2.2d, len %-6.6u)\n",ast_inet_ntoa(bridged->them.sin_addr),ntohs(bridged->them.sin_port),bridged_payload,len-hdrlen);
ast_log(LOG_DEBUG,"RTP Transmission error of packet to %s:%d: %s\n",ast_inet_ntoa(bridged->them.sin_addr),ntohs(bridged->them.sin_port),strerror(errno));
ast_log(LOG_DEBUG,"RTP NAT: Can't write RTP to private address %s:%d, waiting for other end to send audio...\n",ast_inet_ntoa(bridged->them.sin_addr),ntohs(bridged->them.sin_port));
ast_set_flag(bridged,FLAG_NAT_INACTIVE_NOWARN);
}
}
return-1;
}elseif(rtp_debug_test_addr(&bridged->them))
ast_verbose("Sent RTP P2P packet to %s:%d (type %-2.2d, len %-6.6u)\n",ast_inet_ntoa(bridged->them.sin_addr),ntohs(bridged->them.sin_port),bridged_payload,len-hdrlen);
ast_log(LOG_DEBUG,"RTP Transmission error of packet %d to %s:%d: %s\n",rtp->seqno,ast_inet_ntoa(rtp->them.sin_addr),ntohs(rtp->them.sin_port),strerror(errno));
/* Only give this error message once if we are not RTP debugging */
if(option_debug||rtpdebug)
ast_log(LOG_DEBUG,"RTP NAT: Can't write RTP to private address %s:%d, waiting for other end to send audio...\n",ast_inet_ntoa(rtp->them.sin_addr),ntohs(rtp->them.sin_port));
ast_log(LOG_DEBUG,"P2P RTP NAT: Got audio from other end. Now sending to address %s:%d\n",ast_inet_ntoa(rtp->them.sin_addr),ntohs(rtp->them.sin_port));
ast_log(LOG_DEBUG,"P2P RTCP NAT: Got RTCP from other end. Now sending to address %s:%d\n",ast_inet_ntoa(rtp->rtcp->them.sin_addr),ntohs(rtp->rtcp->them.sin_port));
}
}
}
/* If this came from the RTP stream, write out via RTP - if it's RTCP, write out via RTCP */
if(is_rtp)
bridge_p2p_rtp_write(rtp,header,res,hdrlen);
elseif(is_rtcp)
bridge_p2p_rtcp_write(rtp,header,res);
return1;
}
/*! \brief Helper function to switch a channel and RTP stream into callback mode */