[asterisk-commits] file: branch file/rtp_engine r130793 - /team/file/rtp_engine/res/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Jul 14 12:51:42 CDT 2008
Author: file
Date: Mon Jul 14 12:51:41 2008
New Revision: 130793
URL: http://svn.digium.com/view/asterisk?view=rev&rev=130793
Log:
Add local bridging (Packet2Packet bridging) back into our RTP stack.
Modified:
team/file/rtp_engine/res/res_rtp_asterisk.c
Modified: team/file/rtp_engine/res/res_rtp_asterisk.c
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/res/res_rtp_asterisk.c?view=diff&rev=130793&r1=130792&r2=130793
==============================================================================
--- team/file/rtp_engine/res/res_rtp_asterisk.c (original)
+++ team/file/rtp_engine/res/res_rtp_asterisk.c Mon Jul 14 12:51:41 2008
@@ -95,10 +95,8 @@
#define FLAG_NAT_ACTIVE (3 << 1)
#define FLAG_NAT_INACTIVE (0 << 1)
#define FLAG_NAT_INACTIVE_NOWARN (1 << 1)
-#define FLAG_P2P_SENT_MARK (1 << 4)
-#define FLAG_P2P_NEED_DTMF (1 << 5)
-#define FLAG_NEED_MARKER_BIT (1 << 6)
-#define FLAG_DTMF_COMPENSATE (1 << 7)
+#define FLAG_NEED_MARKER_BIT (1 << 3)
+#define FLAG_DTMF_COMPENSATE (1 << 4)
/*! \brief RTP session description */
struct ast_rtp {
@@ -254,6 +252,7 @@
static void ast_rtp_remote_address_set(struct ast_rtp_instance *instance, struct sockaddr_in *sin);
static int rtp_red_init(struct ast_rtp_instance *instance, int buffer_time, int *payloads, int generations);
static int rtp_red_buffer(struct ast_rtp_instance *instance, struct ast_frame *frame);
+static int ast_rtp_local_bridge(struct ast_rtp_instance *instance0, struct ast_rtp_instance *instance1);
/* RTP Engine Declaration */
static struct ast_rtp_engine asterisk_rtp_engine = {
@@ -270,6 +269,7 @@
.remote_address_set = ast_rtp_remote_address_set,
.red_init = rtp_red_init,
.red_buffer = rtp_red_buffer,
+ .local_bridge = ast_rtp_local_bridge,
};
static inline int rtp_debug_test_addr(struct sockaddr_in *addr)
@@ -1675,6 +1675,58 @@
return f;
}
+static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance, unsigned int *rtpheader, int len, int hdrlen)
+{
+ struct ast_rtp *rtp = instance->data, *bridged = instance->bridged->data;
+ int res = 0, payload = 0, bridged_payload = 0, mark;
+ struct ast_rtp_payload_type payload_type;
+ int reconstruct = ntohl(rtpheader[0]);
+
+ /* Get fields from packet */
+ payload = (reconstruct & 0x7f0000) >> 16;
+ mark = (((reconstruct & 0x800000) >> 23) != 0);
+
+ /* Check what the payload value should be */
+ payload_type = ast_rtp_codecs_payload_lookup(&instance->codecs, payload);
+
+ /* Otherwise adjust bridged payload to match */
+ bridged_payload = ast_rtp_codecs_payload_code(&instance->bridged->codecs, payload_type.isAstFormat, payload_type.code);
+
+ /* If the payload coming in is not one of the negotiated ones then send it to the core, this will cause formats to change and the bridge to break */
+ if (!instance->bridged->codecs.payloads[bridged_payload].code) {
+ return -1;
+ }
+
+ /* If the marker bit has been explicitly set turn it on */
+ if (ast_test_flag(rtp, FLAG_NEED_MARKER_BIT)) {
+ mark = 1;
+ ast_clear_flag(rtp, FLAG_NEED_MARKER_BIT);
+ }
+
+ /* Reconstruct part of the packet */
+ reconstruct &= 0xFF80FFFF;
+ reconstruct |= (bridged_payload << 16);
+ reconstruct |= (mark << 23);
+ rtpheader[0] = htonl(reconstruct);
+
+ /* Send the packet back out */
+ res = sendto(bridged->s, (void *)rtpheader, len, 0, (struct sockaddr *)&instance->bridged->remote_address, sizeof(instance->bridged->remote_address));
+ if (res < 0) {
+ if (!instance->bridged->properties[AST_RTP_PROPERTY_NAT] || (instance->bridged->properties[AST_RTP_PROPERTY_NAT] && (ast_test_flag(bridged, FLAG_NAT_ACTIVE) == FLAG_NAT_ACTIVE))) {
+ ast_debug(1, "RTP Transmission error of packet to %s:%d: %s\n", ast_inet_ntoa(instance->bridged->remote_address.sin_addr), ntohs(instance->bridged->remote_address.sin_port), strerror(errno));
+ } else if (((ast_test_flag(bridged, FLAG_NAT_ACTIVE) == FLAG_NAT_INACTIVE) || rtpdebug) && !ast_test_flag(bridged, FLAG_NAT_INACTIVE_NOWARN)) {
+ if (option_debug || rtpdebug)
+ ast_debug(0, "RTP NAT: Can't write RTP to private address %s:%d, waiting for other end to send audio...\n", ast_inet_ntoa(instance->bridged->remote_address.sin_addr), ntohs(instance->bridged->remote_address.sin_port));
+ ast_set_flag(bridged, FLAG_NAT_INACTIVE_NOWARN);
+ }
+ return 0;
+ } else if (rtp_debug_test_addr(&instance->bridged->remote_address)) {
+ ast_verbose("Sent RTP P2P packet to %s:%u (type %-2.2d, len %-6.6u)\n", ast_inet_ntoa(instance->bridged->remote_address.sin_addr), ntohs(instance->bridged->remote_address.sin_port), bridged_payload, len - hdrlen);
+ }
+
+ return 0;
+}
+
static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtcp)
{
struct ast_rtp *rtp = instance->data;
@@ -1744,6 +1796,11 @@
}
}
+ /* If we are directly bridged to another instance send the audio directly out */
+ if (instance->bridged && !bridge_p2p_rtp_write(instance, rtpheader, res, hdrlen)) {
+ return &ast_null_frame;
+ }
+
/* If the version is not what we expected by this point then just drop the packet */
if (version != 2) {
return &ast_null_frame;
@@ -2067,6 +2124,15 @@
return 0;
}
+static int ast_rtp_local_bridge(struct ast_rtp_instance *instance0, struct ast_rtp_instance *instance1)
+{
+ struct ast_rtp *rtp = instance0->data;
+
+ ast_set_flag(rtp, FLAG_NEED_MARKER_BIT);
+
+ return 0;
+}
+
static char *rtp_do_debug_ip(struct ast_cli_args *a)
{
struct hostent *hp;
More information about the asterisk-commits
mailing list