[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