[svn-commits] kpfleming: branch kpfleming/udptl-updates r205983 - in /team/kpfleming/udptl-...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Jul 10 16:23:13 CDT 2009


Author: kpfleming
Date: Fri Jul 10 16:23:10 2009
New Revision: 205983

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=205983
Log:
store away some work in progress

Added:
    team/kpfleming/udptl-updates/
      - copied from r205974, trunk/
Modified:
    team/kpfleming/udptl-updates/apps/app_fax.c
    team/kpfleming/udptl-updates/channels/chan_sip.c
    team/kpfleming/udptl-updates/include/asterisk/frame.h
    team/kpfleming/udptl-updates/include/asterisk/udptl.h
    team/kpfleming/udptl-updates/main/udptl.c

Modified: team/kpfleming/udptl-updates/apps/app_fax.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/kpfleming/udptl-updates/apps/app_fax.c?view=diff&rev=205983&r1=205974&r2=205983
==============================================================================
--- team/kpfleming/udptl-updates/apps/app_fax.c (original)
+++ team/kpfleming/udptl-updates/apps/app_fax.c Fri Jul 10 16:23:10 2009
@@ -471,11 +471,12 @@
 			if (fr && fr->frametype == AST_FRAME_DTMF && fr->subclass == 'f') {
 				struct ast_control_t38_parameters parameters = { .request_response = AST_T38_REQUEST_NEGOTIATE,
 										 .version = 0,
-										 .max_datagram = 400,
+										 .max_ifp = 800,
 										 .rate = AST_T38_RATE_9600,
 										 .rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF,
 										 .fill_bit_removal = 1,
 										 .transcoding_mmr = 1,
+										 .transcoding_jbig = 1,
 				};
 				ast_debug(1, "Fax tone detected. Requesting T38\n");
 				ast_indicate_data(s->chan, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
@@ -509,20 +510,18 @@
 				res = 1;
 				break;
 			} else if (parameters->request_response == AST_T38_REQUEST_NEGOTIATE) {
+				struct ast_control_t38_parameters our_parameters = { .request_response = AST_T38_NEGOTIATED,
+										     .version = 0,
+										     .max_ifp = 800,
+										     .rate = AST_T38_RATE_9600,
+										     .rate_management = parameters->rate_management,
+										     .fill_bit_removal = parameters->fill_bit_removal,
+										     .transcoding_mmr = parameters->transcoding_mmr,
+										     .transcoding_jbig = parameters->transcoding_jbig,
+				};
 				ast_debug(1, "T38 request received, accepting\n");
-				if (parameters->version > 0) {
-					/* Only T.38 Version 0 is supported at this time */
-					parameters->version = 0;
-				}
-				if (parameters->max_datagram > 400) {
-					/* Limit incoming datagram size to our default */
-					/* TODO: this need to come from the udptl stack, not be hardcoded */
-					parameters->max_datagram = 400;
-				}
-				/* we only support bit rates up to 9.6kbps */
-				parameters->rate = AST_T38_RATE_9600;
 				/* Complete T38 switchover */
-				ast_indicate_data(s->chan, AST_CONTROL_T38_PARAMETERS, parameters, sizeof(*parameters));
+				ast_indicate_data(s->chan, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
 				/* Do not break audio loop, wait until channel driver finally acks switchover
 				   with AST_T38_NEGOTIATED */
 			}
@@ -593,7 +592,7 @@
 		return -1;
 	}
 
-	t38_set_max_datagram_size(t38state, s->t38parameters.max_datagram);
+	t38_set_max_datagram_size(t38state, s->t38parameters.max_ifp);
 
 	if (s->t38parameters.fill_bit_removal) {
 		t38_set_fill_bit_removal(t38state, TRUE);

Modified: team/kpfleming/udptl-updates/channels/chan_sip.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/kpfleming/udptl-updates/channels/chan_sip.c?view=diff&rev=205983&r1=205974&r2=205983
==============================================================================
--- team/kpfleming/udptl-updates/channels/chan_sip.c (original)
+++ team/kpfleming/udptl-updates/channels/chan_sip.c Fri Jul 10 16:23:10 2009
@@ -4943,7 +4943,7 @@
 		parameters->transcoding_jbig = 1;
 	}
 
-	parameters->max_datagram = ast_udptl_get_far_max_datagram(p->udptl);
+	parameters->max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
 }
 
 /*! \brief Change the T38 state on a SIP dialog */
@@ -6448,17 +6448,18 @@
 			p->t38.capability = p->t38.jointcapability |= T38FAX_VERSION_1;
 		}
 
-		if (parameters->rate == AST_T38_RATE_14400) {
-			p->t38.capability = p->t38.jointcapability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
-		} else if (parameters->rate == AST_T38_RATE_12000) {
-			p->t38.capability = p->t38.jointcapability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
-		} else if (parameters->rate == AST_T38_RATE_9600) {
-			p->t38.capability = p->t38.jointcapability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
-		} else if (parameters->rate == AST_T38_RATE_7200) {
-			p->t38.capability = p->t38.jointcapability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
-		} else if (parameters->rate == AST_T38_RATE_4800) {
-			p->t38.capability = p->t38.jointcapability |= T38FAX_RATE_4800 | T38FAX_RATE_2400;
-		} else if (parameters->rate == AST_T38_RATE_2400) {
+		switch (parameters->rate) {
+		case AST_T38_RATE_14400:
+			p->t38.capability = p->t38.jointcapability |= T38FAX_RATE_14400;
+		case AST_T38_RATE_12000:
+			p->t38.capability = p->t38.jointcapability |= T38FAX_RATE_12000;
+		case AST_T38_RATE_9600:
+			p->t38.capability = p->t38.jointcapability |= T38FAX_RATE_9600;
+		case AST_T38_RATE_7200:
+			p->t38.capability = p->t38.jointcapability |= T38FAX_RATE_7200;
+		case AST_T38_RATE_4800:
+			p->t38.capability = p->t38.jointcapability |= T38FAX_RATE_4800;
+		case AST_T38_RATE_2400:
 			p->t38.capability = p->t38.jointcapability |= T38FAX_RATE_2400;
 		}
 
@@ -6487,7 +6488,7 @@
 		}
 
 		if (p->udptl && request_response == AST_T38_REQUEST_NEGOTIATE) {
-			ast_udptl_set_local_max_datagram(p->udptl, parameters->max_datagram ? parameters->max_datagram : 400);
+			ast_udptl_set_local_max_ifp(p->udptl, parameters->max_ifp ? : 100);
 		}
 	}
 
@@ -8576,9 +8577,6 @@
 				found = 1;
 				ast_debug(3, "FaxMaxDatagram: %d\n", x);
 				ast_udptl_set_far_max_datagram(p->udptl, x);
-				if (!ast_udptl_get_local_max_datagram(p->udptl)) {
-					ast_udptl_set_local_max_datagram(p->udptl, x);
-				}
 			} else if ((strncmp(a, "T38FaxFillBitRemoval", 20) == 0)) {
 				found = 1;
 				if(sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1) {
@@ -10269,7 +10267,6 @@
 	}
 	respprep(&resp, p, msg, req);
 	if (p->udptl) {
-		ast_udptl_offered_from_local(p->udptl, 0);
 		add_sdp(&resp, p, 0, 0, 1);
 	} else 
 		ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid);
@@ -10787,7 +10784,6 @@
 	}
 	if (sdp) {
 		if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) {
-			ast_udptl_offered_from_local(p->udptl, 1);
 			ast_debug(1, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
 			add_sdp(&req, p, FALSE, FALSE, TRUE);
 		} else if (p->rtp) {

Modified: team/kpfleming/udptl-updates/include/asterisk/frame.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/kpfleming/udptl-updates/include/asterisk/frame.h?view=diff&rev=205983&r1=205974&r2=205983
==============================================================================
--- team/kpfleming/udptl-updates/include/asterisk/frame.h (original)
+++ team/kpfleming/udptl-updates/include/asterisk/frame.h Fri Jul 10 16:23:10 2009
@@ -350,14 +350,14 @@
 };
 
 struct ast_control_t38_parameters {
-	enum ast_control_t38 request_response;                /*!< Request or response of the T38 control frame */
-	unsigned int version;                                 /*!< Supported T.38 version */
-	unsigned int max_datagram;                            /*!< Maximum datagram size supported */
-	enum ast_control_t38_rate rate;                       /*!< Maximum fax rate supported */
-	enum ast_control_t38_rate_management rate_management; /*!< Rate management setting */
-	unsigned int fill_bit_removal:1;                      /*!< Set if fill bit removal should be used */
-	unsigned int transcoding_mmr:1;                       /*!< Set if MMR transcoding should be used */
-	unsigned int transcoding_jbig:1;                      /*!< Set if JBIG transcoding should be used */
+	enum ast_control_t38 request_response;			/*!< Request or response of the T38 control frame */
+	unsigned int version;					/*!< Supported T.38 version */
+	unsigned int max_ifp; 					/*!< Maximum IFP size supported */
+	enum ast_control_t38_rate rate;				/*!< Maximum fax rate supported */
+	enum ast_control_t38_rate_management rate_management;	/*!< Rate management setting */
+	unsigned int fill_bit_removal:1;			/*!< Set if fill bit removal can be used */
+	unsigned int transcoding_mmr:1;				/*!< Set if MMR transcoding can be used */
+	unsigned int transcoding_jbig:1;			/*!< Set if JBIG transcoding can be used */
 };
 
 enum ast_control_transfer {

Modified: team/kpfleming/udptl-updates/include/asterisk/udptl.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/kpfleming/udptl-updates/include/asterisk/udptl.h?view=diff&rev=205983&r1=205974&r2=205983
==============================================================================
--- team/kpfleming/udptl-updates/include/asterisk/udptl.h (original)
+++ team/kpfleming/udptl-updates/include/asterisk/udptl.h Fri Jul 10 16:23:10 2009
@@ -33,7 +33,7 @@
 #include "asterisk/channel.h"
 
 
-enum {
+enum ast_t38_ec_modes {
     UDPTL_ERROR_CORRECTION_NONE,
     UDPTL_ERROR_CORRECTION_FEC,
     UDPTL_ERROR_CORRECTION_REDUNDANCY
@@ -60,11 +60,11 @@
 
 struct ast_udptl *ast_udptl_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int callbackmode, struct in_addr in);
 
-void ast_udptl_set_peer(struct ast_udptl *udptl, struct sockaddr_in *them);
+void ast_udptl_set_peer(struct ast_udptl *udptl, const struct sockaddr_in *them);
 
-void ast_udptl_get_peer(struct ast_udptl *udptl, struct sockaddr_in *them);
+void ast_udptl_get_peer(const struct ast_udptl *udptl, struct sockaddr_in *them);
 
-void ast_udptl_get_us(struct ast_udptl *udptl, struct sockaddr_in *us);
+void ast_udptl_get_us(const struct ast_udptl *udptl, struct sockaddr_in *us);
 
 void ast_udptl_destroy(struct ast_udptl *udptl);
 
@@ -78,37 +78,33 @@
 
 struct ast_frame *ast_udptl_read(struct ast_udptl *udptl);
 
-int ast_udptl_fd(struct ast_udptl *udptl);
+int ast_udptl_fd(const struct ast_udptl *udptl);
 
-int ast_udptl_setqos(struct ast_udptl *udptl, int tos, int cos);
+int ast_udptl_setqos(struct ast_udptl *udptl, unsigned int tos, unsigned int cos);
 
-void ast_udptl_set_m_type(struct ast_udptl* udptl, int pt);
+void ast_udptl_set_m_type(struct ast_udptl *udptl, unsigned int pt);
 
-void ast_udptl_set_udptlmap_type(struct ast_udptl* udptl, int pt,
-			 char* mimeType, char* mimeSubtype);
+void ast_udptl_set_udptlmap_type(struct ast_udptl *udptl, unsigned int pt,
+				 char *mimeType, char *mimeSubtype);
 
-int ast_udptl_lookup_code(struct ast_udptl* udptl, int isAstFormat, int code);
+int ast_udptl_get_error_correction_scheme(const struct ast_udptl *udptl);
 
-void ast_udptl_offered_from_local(struct ast_udptl* udptl, int local);
+void ast_udptl_set_error_correction_scheme(struct ast_udptl *udptl, enum ast_t38_ec_modes ec);
 
-int ast_udptl_get_error_correction_scheme(struct ast_udptl* udptl);
+void ast_udptl_set_local_max_ifp(struct ast_udptl *udptl, unsigned int max_ifp);
 
-void ast_udptl_set_error_correction_scheme(struct ast_udptl* udptl, int ec);
+unsigned int ast_udptl_get_local_max_datagram(const struct ast_udptl *udptl);
 
-int ast_udptl_get_local_max_datagram(struct ast_udptl* udptl);
+void ast_udptl_set_far_max_datagram(struct ast_udptl *udptl, unsigned int max_datagram);
 
-void ast_udptl_set_local_max_datagram(struct ast_udptl* udptl, int max_datagram);
+unsigned int ast_udptl_get_far_max_datagram(const struct ast_udptl *udptl);
 
-int ast_udptl_get_far_max_datagram(struct ast_udptl* udptl);
-
-void ast_udptl_set_far_max_datagram(struct ast_udptl* udptl, int max_datagram);
-
-void ast_udptl_get_current_formats(struct ast_udptl* udptl,
-			     int* astFormats, int* nonAstFormats);
+unsigned int ast_udptl_get_far_max_ifp(const struct ast_udptl *udptl);
 
 void ast_udptl_setnat(struct ast_udptl *udptl, int nat);
 
-int ast_udptl_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc);
+int ast_udptl_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
+		     struct ast_frame **fo, struct ast_channel **rc);
 
 int ast_udptl_proto_register(struct ast_udptl_protocol *proto);
 

Modified: team/kpfleming/udptl-updates/main/udptl.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/kpfleming/udptl-updates/main/udptl.c?view=diff&rev=205983&r1=205974&r2=205983
==============================================================================
--- team/kpfleming/udptl-updates/main/udptl.c (original)
+++ team/kpfleming/udptl-updates/main/udptl.c Fri Jul 10 16:23:10 2009
@@ -81,7 +81,7 @@
 #ifdef SO_NO_CHECK
 static int nochecksums;
 #endif
-static int udptlfectype;
+static enum ast_t38_ec_modes udptlfectype;
 static int udptlfecentries;
 static int udptlfecspan;
 static int udptlmaxdatagram;
@@ -100,10 +100,10 @@
 typedef struct {
 	int buf_len;
 	uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
-	int fec_len[MAX_FEC_ENTRIES];
+	unsigned int fec_len[MAX_FEC_ENTRIES];
 	uint8_t fec[MAX_FEC_ENTRIES][LOCAL_FAX_MAX_DATAGRAM];
-	int fec_span;
-	int fec_entries;
+	unsigned int fec_span;
+	unsigned int fec_entries;
 } udptl_fec_rx_buffer_t;
 
 /*! \brief Structure for an UDPTL session */
@@ -122,35 +122,51 @@
 	struct io_context *io;
 	void *data;
 	ast_udptl_callback callback;
-	int udptl_offered_from_local;
 
 	/*! This option indicates the error correction scheme used in transmitted UDPTL
-	    packets. */
-	int error_correction_scheme;
+	 *    packets and expected in received UDPTL packets.
+	 */
+	enum ast_t38_ec_modes error_correction_scheme;
 
 	/*! This option indicates the number of error correction entries transmitted in
-	    UDPTL packets. */
-	int error_correction_entries;
+	 *  UDPTL packets and expected in received UDPTL packets.
+	 */
+	unsigned int error_correction_entries;
 
 	/*! This option indicates the span of the error correction entries in transmitted
-	    UDPTL packets (FEC only). */
-	int error_correction_span;
-
-	/*! This option indicates the maximum size of a UDPTL packet that can be accepted by
-	    the remote device. */
-	int far_max_datagram_size;
-
-	/*! This option indicates the maximum size of a UDPTL packet that we are prepared to
-	    accept. */
-	int local_max_datagram_size;
+	 *  UDPTL packets (FEC only).
+	 */
+	unsigned int error_correction_span;
+
+	/*! The maximum size UDPTL packet that can be accepted by
+	 *  the remote device.
+	 */
+	unsigned int far_max_datagram;
+
+	/*! The maximum size UDPTL packet that we are prepared to
+	 *  accept.
+	 */
+	unsigned int local_max_datagram;
+
+	/*! The maximum IFP that can be submitted for sending
+	 * to the remote device. Calculated from far_max_datagram,
+	 * error_correction_scheme and error_correction_entries.
+	 */
+	unsigned int far_max_ifp;
+
+	/*! The maximum IFP that the local endpoint is prepared
+	 * to accept. Along with error_correction_scheme and
+	 * error_correction_entries, used to calculate local_max_datagram.
+	 */
+	unsigned int local_max_ifp;
 
 	int verbose;
 
 	struct sockaddr_in far;
 
-	int tx_seq_no;
-	int rx_seq_no;
-	int rx_expected_seq_no;
+	unsigned int tx_seq_no;
+	unsigned int rx_seq_no;
+	unsigned int rx_expected_seq_no;
 
 	udptl_fec_tx_buffer_t tx[UDPTL_BUF_MASK + 1];
 	udptl_fec_rx_buffer_t rx[UDPTL_BUF_MASK + 1];
@@ -158,23 +174,20 @@
 
 static AST_RWLIST_HEAD_STATIC(protos, ast_udptl_protocol);
 
-static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len);
-static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, int buflen, uint8_t *ifp, int ifp_len);
-
-static inline int udptl_debug_test_addr(struct sockaddr_in *addr)
+static inline int udptl_debug_test_addr(const struct sockaddr_in *addr)
 {
 	if (udptldebug == 0)
 		return 0;
 	if (udptldebugaddr.sin_addr.s_addr) {
-		if (((ntohs(udptldebugaddr.sin_port) != 0)
-			&& (udptldebugaddr.sin_port != addr->sin_port))
-			|| (udptldebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
+		if (((ntohs(udptldebugaddr.sin_port) != 0) &&
+		     (udptldebugaddr.sin_port != addr->sin_port)) ||
+		    (udptldebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
 			return 0;
 	}
 	return 1;
 }
 
-static int decode_length(uint8_t *buf, int limit, int *len, int *pvalue)
+static int decode_length(uint8_t *buf, unsigned int limit, unsigned int *len, unsigned int *pvalue)
 {
 	if (*len >= limit)
 		return -1;
@@ -199,15 +212,16 @@
 }
 /*- End of function --------------------------------------------------------*/
 
-static int decode_open_type(uint8_t *buf, int limit, int *len, const uint8_t **p_object, int *p_num_octets)
-{
-	int octet_cnt;
-	int octet_idx;
-	int length;
-	int i;
+static int decode_open_type(uint8_t *buf, unsigned int limit, unsigned int *len, const uint8_t **p_object, unsigned int *p_num_octets)
+{
+	unsigned int octet_cnt;
+	unsigned int octet_idx;
+	unsigned int length;
+	unsigned int i;
 	const uint8_t **pbuf;
 
 	for (octet_idx = 0, *p_num_octets = 0; ; octet_idx += octet_cnt) {
+		octet_cnt = 0;
 		if ((length = decode_length(buf, limit, len, &octet_cnt)) < 0)
 			return -1;
 		if (octet_cnt > 0) {
@@ -229,9 +243,9 @@
 }
 /*- End of function --------------------------------------------------------*/
 
-static int encode_length(uint8_t *buf, int *len, int value)
-{
-	int multiplier;
+static unsigned int encode_length(uint8_t *buf, unsigned int *len, unsigned int value)
+{
+	unsigned int multiplier;
 
 	if (value < 0x80) {
 		/* 1 octet */
@@ -257,10 +271,10 @@
 }
 /*- End of function --------------------------------------------------------*/
 
-static int encode_open_type(uint8_t *buf, int buflen, int *len, const uint8_t *data, int num_octets)
-{
-	int enclen;
-	int octet_idx;
+static int encode_open_type(uint8_t *buf, unsigned int buflen, unsigned int *len, const uint8_t *data, unsigned int num_octets)
+{
+	unsigned int enclen;
+	unsigned int octet_idx;
 	uint8_t zero_byte;
 
 	/* If open type is of zero length, add a single zero byte (10.1) */
@@ -289,7 +303,7 @@
 }
 /*- End of function --------------------------------------------------------*/
 
-static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len)
+static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, unsigned int len)
 {
 	int stat1;
 	int stat2;
@@ -301,16 +315,16 @@
 	int x;
 	int limit;
 	int which;
-	int ptr;
-	int count;
+	unsigned int ptr;
+	unsigned int count;
 	int total_count;
 	int seq_no;
 	const uint8_t *ifp;
 	const uint8_t *data;
-	int ifp_len;
+	unsigned int ifp_len;
 	int repaired[16];
 	const uint8_t *bufs[16];
-	int lengths[16];
+	unsigned int lengths[16];
 	int span;
 	int entries;
 	int ifp_no;
@@ -497,7 +511,7 @@
 }
 /*- End of function --------------------------------------------------------*/
 
-static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, int buflen, uint8_t *ifp, int ifp_len)
+static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, unsigned int buflen, uint8_t *ifp, unsigned int ifp_len)
 {
 	uint8_t fec[LOCAL_FAX_MAX_DATAGRAM * 2];
 	int i;
@@ -507,7 +521,7 @@
 	int entries;
 	int span;
 	int m;
-	int len;
+	unsigned int len;
 	int limit;
 	int high_tide;
 
@@ -612,7 +626,7 @@
 	return len;
 }
 
-int ast_udptl_fd(struct ast_udptl *udptl)
+int ast_udptl_fd(const struct ast_udptl *udptl)
 {
 	return udptl->fd;
 }
@@ -695,15 +709,67 @@
 	return &udptl->f[0];
 }
 
-void ast_udptl_offered_from_local(struct ast_udptl* udptl, int local)
-{
-	if (udptl)
-		udptl->udptl_offered_from_local = local;
-	else
-		ast_log(LOG_WARNING, "udptl structure is null\n");
-}
-
-int ast_udptl_get_error_correction_scheme(struct ast_udptl* udptl)
+static void calculate_local_max_datagram(struct ast_udptl *udptl)
+{
+	unsigned int new_max = 200;
+
+	/* calculate the amount of space required to receive an IFP
+	 * using the current error correction mode, and ensure that our
+	 * local max datagram size is at least that big
+	 */
+	switch (udptl->error_correction_scheme) {
+	case UDPTL_ERROR_CORRECTION_NONE:
+		/* only need room for sequence number and length indicators */
+		new_max = 6 + udptl->local_max_ifp;
+		break;
+	case UDPTL_ERROR_CORRECTION_REDUNDANCY:
+		/* need room for sequence number, length indicators and the
+		 * configured number of redundant packets
+		 */
+		new_max = 6 + udptl->local_max_ifp + 2 + (udptl->error_correction_entries * udptl->local_max_ifp);
+		break;
+	case UDPTL_ERROR_CORRECTION_FEC:
+		/* need room for sequence number, length indicators and a
+		 * a single IFP of the maximum size expected
+		 */
+		new_max = 6 + udptl->local_max_ifp + 4 + udptl->local_max_ifp;
+		break;
+	}
+	/* add 25% of extra space for insurance, but no larger than LOCAL_FAX_MAX_DATAGRAM */
+	udptl->local_max_datagram = min(new_max * 1.25, LOCAL_FAX_MAX_DATAGRAM);
+}
+
+static void calculate_far_max_ifp(struct ast_udptl *udptl)
+{
+	unsigned new_max = 40;
+
+	/* calculate the maximum IFP the local endpoint should
+	 * generate based on the far end's maximum datagram size
+	 * and the current error correction mode
+	 */
+	switch (udptl->error_correction_scheme) {
+	case UDPTL_ERROR_CORRECTION_NONE:
+		/* only need room for sequence number and length indicators */
+		new_max = udptl->far_max_datagram - 6;
+		break;
+	case UDPTL_ERROR_CORRECTION_REDUNDANCY:
+		/* need room for sequence number, length indicators and the
+		 * configured number of redundant packets
+		 */
+		new_max = (udptl->far_max_datagram - 8) / (udptl->error_correction_entries + 1);
+		break;
+	case UDPTL_ERROR_CORRECTION_FEC:
+		/* need room for sequence number, length indicators and a
+		 * a single IFP of the maximum size expected
+		 */
+		new_max = (udptl->far_max_datagram - 10) / 2;
+		break;
+	}
+	/* subtract 25% of space for insurance */
+	udptl->far_max_ifp = new_max * 0.75;
+}
+
+int ast_udptl_get_error_correction_scheme(const struct ast_udptl *udptl)
 {
 	if (udptl)
 		return udptl->error_correction_scheme;
@@ -713,60 +779,83 @@
 	}
 }
 
-void ast_udptl_set_error_correction_scheme(struct ast_udptl* udptl, int ec)
+void ast_udptl_set_error_correction_scheme(struct ast_udptl *udptl, enum ast_t38_ec_modes ec)
 {
 	if (udptl) {
+		udptl->error_correction_scheme = ec;
 		switch (ec) {
 		case UDPTL_ERROR_CORRECTION_FEC:
 			udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_FEC;
+			if (udptl->error_correction_entries == 0) {
+				udptl->error_correction_entries = 3;
+			}
+			if (udptl->error_correction_span == 0) {
+				udptl->error_correction_span = 3;
+			}
 			break;
 		case UDPTL_ERROR_CORRECTION_REDUNDANCY:
 			udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_REDUNDANCY;
-			break;
-		case UDPTL_ERROR_CORRECTION_NONE:
-			udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_NONE;
+			if (udptl->error_correction_entries == 0) {
+				udptl->error_correction_entries = 3;
+			}
 			break;
 		default:
-			ast_log(LOG_WARNING, "error correction parameter invalid\n");
+			/* nothing to do */
+			break;
 		};
+		calculate_local_max_datagram(udptl);
+		calculate_far_max_ifp(udptl);
 	} else
 		ast_log(LOG_WARNING, "udptl structure is null\n");
 }
 
-int ast_udptl_get_local_max_datagram(struct ast_udptl* udptl)
+unsigned int ast_udptl_get_local_max_datagram(const struct ast_udptl *udptl)
 {
 	if (udptl)
-		return udptl->local_max_datagram_size;
+		return udptl->local_max_datagram;
 	else {
 		ast_log(LOG_WARNING, "udptl structure is null\n");
-		return -1;
-	}
-}
-
-int ast_udptl_get_far_max_datagram(struct ast_udptl* udptl)
+		return 0;
+	}
+}
+
+unsigned int ast_udptl_get_far_max_datagram(const struct ast_udptl *udptl)
 {
 	if (udptl)
-		return udptl->far_max_datagram_size;
+		return udptl->far_max_datagram;
 	else {
 		ast_log(LOG_WARNING, "udptl structure is null\n");
-		return -1;
-	}
-}
-
-void ast_udptl_set_local_max_datagram(struct ast_udptl* udptl, int max_datagram)
+		return 0;
+	}
+}
+
+void ast_udptl_set_local_max_datagram(struct ast_udptl *udptl, unsigned int max_datagram)
 {
 	if (udptl)
-		udptl->local_max_datagram_size = max_datagram;
+		udptl->local_max_datagram = max_datagram;
 	else
 		ast_log(LOG_WARNING, "udptl structure is null\n");
 }
 
-void ast_udptl_set_far_max_datagram(struct ast_udptl* udptl, int max_datagram)
-{
-	if (udptl)
-		udptl->far_max_datagram_size = max_datagram;
-	else
+void ast_udptl_set_far_max_datagram(struct ast_udptl *udptl, unsigned int max_datagram)
+{
+	if (udptl) {
+		udptl->far_max_datagram = max_datagram;
+		calculate_far_max_ifp(udptl);
+	} else {
 		ast_log(LOG_WARNING, "udptl structure is null\n");
+	}
+}
+
+void ast_udptl_set_local_max_ifp(struct ast_udptl *udptl, unsigned int max_ifp)
+{
+	udptl->local_max_ifp = max_ifp;
+	calculate_local_max_datagram(udptl);
+}
+
+unsigned int ast_udptl_get_far_max_ifp(const struct ast_udptl *udptl)
+{
+	return udptl->far_max_ifp;
 }
 
 struct ast_udptl *ast_udptl_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int callbackmode, struct in_addr addr)
@@ -780,20 +869,13 @@
 	if (!(udptl = ast_calloc(1, sizeof(*udptl))))
 		return NULL;
 
-	if (udptlfectype == 2)
-		udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_FEC;
-	else if (udptlfectype == 1)
-		udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_REDUNDANCY;
-	else
-		udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_NONE;
+	udptl->error_correction_scheme = udptlfectype;
 	udptl->error_correction_span = udptlfecspan;
 	udptl->error_correction_entries = udptlfecentries;
 	
-	udptl->far_max_datagram_size = udptlmaxdatagram;
-	udptl->local_max_datagram_size = udptlmaxdatagram;
-
-	memset(&udptl->rx, 0, sizeof(udptl->rx));
-	memset(&udptl->tx, 0, sizeof(udptl->tx));
+	udptl->far_max_datagram = udptlmaxdatagram;
+	udptl->local_max_datagram = udptlmaxdatagram;
+
 	for (i = 0; i <= UDPTL_BUF_MASK; i++) {
 		udptl->rx[i].buf_len = -1;
 		udptl->tx[i].buf_len = -1;
@@ -852,18 +934,18 @@
 	return ast_udptl_new_with_bindaddr(sched, io, callbackmode, ia);
 }
 
-int ast_udptl_setqos(struct ast_udptl *udptl, int tos, int cos)
+int ast_udptl_setqos(struct ast_udptl *udptl, unsigned int tos, unsigned int cos)
 {
 	return ast_netsock_set_qos(udptl->fd, tos, cos, "UDPTL");
 }
 
-void ast_udptl_set_peer(struct ast_udptl *udptl, struct sockaddr_in *them)
+void ast_udptl_set_peer(struct ast_udptl *udptl, const struct sockaddr_in *them)
 {
 	udptl->them.sin_port = them->sin_port;
 	udptl->them.sin_addr = them->sin_addr;
 }
 
-void ast_udptl_get_peer(struct ast_udptl *udptl, struct sockaddr_in *them)
+void ast_udptl_get_peer(const struct ast_udptl *udptl, struct sockaddr_in *them)
 {
 	memset(them, 0, sizeof(*them));
 	them->sin_family = AF_INET;
@@ -871,7 +953,7 @@
 	them->sin_addr = udptl->them.sin_addr;
 }
 
-void ast_udptl_get_us(struct ast_udptl *udptl, struct sockaddr_in *us)
+void ast_udptl_get_us(const struct ast_udptl *udptl, struct sockaddr_in *us)
 {
 	memcpy(us, &udptl->us, sizeof(udptl->us));
 }
@@ -893,10 +975,10 @@
 
 int ast_udptl_write(struct ast_udptl *s, struct ast_frame *f)
 {
-	int seq;
-	int len;
+	unsigned int seq;
+	unsigned int len;
 	int res;
-	uint8_t buf[LOCAL_FAX_MAX_DATAGRAM * 2];
+	uint8_t buf[s->far_max_datagram];
 
 	/* If we have no peer, return immediately */	
 	if (s->them.sin_addr.s_addr == INADDR_ANY)
@@ -906,9 +988,14 @@
 	if (f->datalen == 0)
 		return 0;
 	
-	if (f->frametype != AST_FRAME_MODEM) {
-		ast_log(LOG_WARNING, "UDPTL can only send T.38 data\n");
+	if ((f->frametype != AST_FRAME_MODEM) ||
+	    (f->subclass != AST_MODEM_T38)) {
+		ast_log(LOG_WARNING, "UDPTL can only send T.38 data.\n");
 		return -1;
+	}
+
+	if (f->datalen > s->far_max_ifp) {
+		ast_log(LOG_WARNING, "UDPTL asked to send %d bytes of IFP when far end only prepared to accept %d bytes; data loss may occur.\n", f->datalen, s->far_max_ifp);
 	}
 
 	/* Save seq_no for debug output because udptl_build_packet increments it */
@@ -1175,7 +1262,7 @@
 
 	udptlstart = 4500;
 	udptlend = 4999;
-	udptlfectype = 0;
+	udptlfectype = UDPTL_ERROR_CORRECTION_NONE;
 	udptlfecentries = 0;
 	udptlfecspan = 0;
 	udptlmaxdatagram = 0;
@@ -1216,9 +1303,9 @@
 		}
 		if ((s = ast_variable_retrieve(cfg, "general", "T38FaxUdpEC"))) {
 			if (strcmp(s, "t38UDPFEC") == 0)
-				udptlfectype = 2;
+				udptlfectype = UDPTL_ERROR_CORRECTION_FEC;
 			else if (strcmp(s, "t38UDPRedundancy") == 0)
-				udptlfectype = 1;
+				udptlfectype = UDPTL_ERROR_CORRECTION_REDUNDANCY;
 		}
 		if ((s = ast_variable_retrieve(cfg, "general", "T38FaxMaxDatagram"))) {
 			udptlmaxdatagram = atoi(s);




More information about the svn-commits mailing list