[asterisk-commits] branch oej/t38passthrough r11840 - in /team/oej/t38passthrough: channels/ con...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Sat Mar 4 15:48:07 MST 2006


Author: oej
Date: Sat Mar  4 16:48:03 2006
New Revision: 11840

URL: http://svn.digium.com/view/asterisk?rev=11840&view=rev
Log:
- Adding ENUM for state
- Fixing whitespace problems
- Changing comments to doxygen
- Moving t38 variables in pvt into one combined structure

We need to set peer/user T38 flags instead of only one global flag that affects
the RTP native bridge for everyone.

Modified:
    team/oej/t38passthrough/channels/chan_sip.c
    team/oej/t38passthrough/configs/sip.conf.sample
    team/oej/t38passthrough/res/Makefile

Modified: team/oej/t38passthrough/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/t38passthrough/channels/chan_sip.c?rev=11840&r1=11839&r2=11840&view=diff
==============================================================================
--- team/oej/t38passthrough/channels/chan_sip.c (original)
+++ team/oej/t38passthrough/channels/chan_sip.c Sat Mar  4 16:48:03 2006
@@ -476,10 +476,7 @@
 static struct io_context *io;		/*!< The IO context */
 
 #if defined(T38_SUPPORT)
-static int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600; /* This is default: NO MMR and JBIG trancoding, NO fill bit removal, transfered TCF, UDP FEC, Version 0 and 9600 max fax rate */
-#endif
-
-#if defined(T38_SUPPORT)
+static int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600; /*!< This is default: NO MMR and JBIG trancoding, NO fill bit removal, transfered TCF, UDP FEC, Version 0 and 9600 max fax rate */
 static int global_t38udptl_support = 0;
 static int global_t38rtp_support = 0;
 static int global_t38tcp_support = 0;
@@ -531,10 +528,28 @@
 	char hop[0];
 };
 
+#ifdef T38_SUPPORT
+enum t38state {
+	T38_DISABLED	= 0,		/*! Not enabled */
+	T38_LOCAL_DIRECT,		/*! Offered from local */
+	T38_LOCAL_REINVITE,		/*! Offered from local - REINVITE */
+	T38_PEER_DIRECT,		/*! Offered from peer */
+	T38_PEER_REINVITE,		/*! Offered from peer - REINVITE */
+	T38_ENABLED			/*! Negotiated (enabled) */
+};
+
+struct t38properties {
+	int capability;			/*!< Our T38 capability */
+	int peercapability;		/*!< Peers T38 capability */
+	int jointcapability;		/*!< Supported T38 capability at both ends */
+	enum t38state state;		/*!< T.38 state */
+};
+#endif
+
 /*! \brief Modes for SIP domain handling in the PBX */
 enum domain_mode {
-	SIP_DOMAIN_AUTO,	/*!< This domain is auto-configured */
-	SIP_DOMAIN_CONFIG,	/*!< This domain is from configuration */
+	SIP_DOMAIN_AUTO,		/*!< This domain is auto-configured */
+	SIP_DOMAIN_CONFIG,		/*!< This domain is from configuration */
 };
 
 struct domain {
@@ -705,10 +720,9 @@
 	int prefcodec;				/*!< Preferred codec (outbound only) */
 	int noncodeccapability;
 #if defined(T38_SUPPORT)
-	int t38capability;			/*!< Our T38 capability */
-	int t38peercapability;			/*!< Peers T38 capability */
-	int t38jointcapability;			/*!< Supported T38 capability at both ends */
-	int t38state;				/*!< T.38 state : 0 not enabled, 1 offered from local - direct, 2 - offered from local - reinvite, 3 - offered from peer - direct, 4 offered from peer - reinvite, 5 negotiated (enabled) */
+	struct t38properties t38;		/*!< T38 settings */
+	struct sockaddr_in udptlredirip;	/*!< Where our T.38 UDPTL should be going if not to us */
+	struct ast_udptl *udptl;		/*!< T.38 UDPTL session */
 #endif
 	int callingpres;			/*!< Calling presentation */
 	int authtries;				/*!< Times we've tried to authenticate */
@@ -720,9 +734,6 @@
 	struct sockaddr_in sa;			/*!< Our peer */
 	struct sockaddr_in redirip;		/*!< Where our RTP should be going if not to us */
 	struct sockaddr_in vredirip;		/*!< Where our Video RTP should be going if not to us */
-#if defined(T38_SUPPORT)
-	struct sockaddr_in udptlredirip;	/*!< Where our T.38 UDPTL should be going if not to us */
-#endif
 	int redircodecs;			/*!< Redirect codecs */
 	struct sockaddr_in recv;		/*!< Received as */
 	struct in_addr ourip;			/*!< Our IP */
@@ -761,9 +772,6 @@
 	struct sip_registry *registry;		/*!< If this is a REGISTER dialog, to which registry */
 	struct ast_rtp *rtp;			/*!< RTP Session */
 	struct ast_rtp *vrtp;			/*!< Video RTP session */
-#if defined(T38_SUPPORT)
-	struct ast_udptl *udptl;		/*!< T.38 UDPTL session */
-#endif
 	struct sip_pkt *packets;		/*!< Packets scheduled for re-transmission */
 	struct sip_history_head *history;	/*!< History of this SIP dialog */
 	struct ast_variable *chanvars;		/*!< Channel variables to set for call */
@@ -960,18 +968,12 @@
 /*---------------------------- Forward declarations of functions in chan_sip.c */
 static int transmit_response(struct sip_pvt *p, char *msg, struct sip_request *req);
 static int transmit_response_with_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, int retrans);
-#if defined(T38_SUPPORT)
-static int transmit_response_with_t38_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, int retrans);
-#endif
 static int transmit_response_with_unsupported(struct sip_pvt *p, char *msg, struct sip_request *req, char *unsupported);
 static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, struct sip_request *req, const char *rand, int reliable, const char *header, int stale);
 static int transmit_request(struct sip_pvt *p, int sipmethod, int inc, int reliable, int newbranch);
 static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int inc, int reliable, int newbranch);
 static int transmit_invite(struct sip_pvt *p, int sipmethod, int sendsdp, int init);
 static int transmit_reinvite_with_sdp(struct sip_pvt *p);
-#if defined(T38_SUPPORT)
-static int transmit_reinvite_with_t38_sdp(struct sip_pvt *p);
-#endif
 static int transmit_info_with_digit(struct sip_pvt *p, char digit);
 static int transmit_info_with_vidupdate(struct sip_pvt *p);
 static int transmit_message_with_text(struct sip_pvt *p, const char *text);
@@ -1025,10 +1027,16 @@
 static void set_peer_defaults(struct sip_peer *peer);
 static struct sip_peer *temp_peer(const char *name);
 
+/*------ T38 Support --------- */
 #if defined(T38_SUPPORT)
-static int sip_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo,struct ast_channel **rc, int timeoutms); /* Function to bridge to SIP channels if NOT T.38 enabled */
-static int sip_handle_t38_reinvite(struct ast_channel *chan, struct sip_pvt *pvt, int reinvite); /* T38 negotiation helper function */
+static int sip_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo,struct ast_channel **rc, int timeoutms);	/*!< Function to bridge to SIP channels if NOT T.38 enabled */
+static int sip_handle_t38_reinvite(struct ast_channel *chan, struct sip_pvt *pvt, int reinvite); /*!< T38 negotiation helper function */
+static int transmit_response_with_t38_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, int retrans);
+static int transmit_reinvite_with_t38_sdp(struct sip_pvt *p);
+static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan);
+static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl);
 #endif
+
 /*----- RTP interface functions */
 static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active);
 static struct ast_rtp *sip_get_rtp_peer(struct ast_channel *chan);
@@ -1070,6 +1078,15 @@
 	get_codec: sip_get_codec,
 };
 
+#if defined(T38_SUPPORT)
+/*! \brief Interface structure with callbacks used to connect to UDPTL module*/
+static struct ast_udptl_protocol sip_udptl = {
+	type: "SIP",
+	get_udptl_info: sip_get_udptl_peer,
+	set_udptl_peer: sip_set_udptl_peer,
+};
+#endif
+
 
 /*!
   \brief Thread-safe random number generator
@@ -1973,18 +1990,19 @@
 	r->capability = peer->capability;
 	r->prefs = peer->prefs;
 #if defined(T38_SUPPORT)
-	r->t38capability = global_t38_capability;
+	r->t38.capability = global_t38_capability;
 	if (r->udptl) {
-		if ( ast_udptl_get_error_correction_scheme(r->udptl) == UDPTL_ERROR_CORRECTION_FEC )
-			r->t38capability |= T38FAX_UDP_EC_FEC;
-		else if ( ast_udptl_get_error_correction_scheme(r->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY )
-			r->t38capability |= T38FAX_UDP_EC_REDUNDANCY;			
-		else if (  ast_udptl_get_error_correction_scheme(r->udptl) == UDPTL_ERROR_CORRECTION_NONE )
-			r->t38capability |= T38FAX_UDP_EC_NONE;
-		r->t38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
-		ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", r->t38capability);
-	}
-	r->t38jointcapability = r->t38capability;
+		if (ast_udptl_get_error_correction_scheme(r->udptl) == UDPTL_ERROR_CORRECTION_FEC )
+			r->t38.capability |= T38FAX_UDP_EC_FEC;
+		else if (ast_udptl_get_error_correction_scheme(r->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY )
+			r->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;			
+		else if (ast_udptl_get_error_correction_scheme(r->udptl) == UDPTL_ERROR_CORRECTION_NONE )
+			r->t38.capability |= T38FAX_UDP_EC_NONE;
+		r->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
+		if (option_debug > 1)
+			ast_log(LOG_DEBUG,"Our T38 capability (%d)\n", r->t38.capability);
+	}
+	r->t38.jointcapability = r->t38.capability;
 #endif
 	if (r->rtp) {
 		if (option_debug)
@@ -1998,7 +2016,8 @@
 	}
 #if defined(T38_SUPPORT)
 	if (r->udptl) {
-		ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
+		if (option_debug)
+			ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %d\n", (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
 		ast_udptl_setnat(r->udptl, (ast_test_flag(r, SIP_NAT) & SIP_NAT_ROUTE));
 	}
 #endif
@@ -2175,8 +2194,9 @@
 #if defined(T38_SUPPORT)
 		} else if (!strncasecmp(ast_var_name(current), "T38CALL", strlen("T38CALL"))) {
 			/* Check whether there is a variable with a name starting with T38CALL */
-			p->t38state = 1;
-			ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n",p->t38state, ast->name);
+			p->t38.state = T38_LOCAL_DIRECT;
+			if (option_debug)
+				ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name);
 #endif
 		}
 
@@ -2208,8 +2228,9 @@
 		p->callingpres = ast->cid.cid_pres;
 		p->jointcapability = p->capability;
 #if defined(T38_SUPPORT)
-		p->t38jointcapability = p->t38capability;
-		ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38capability, p->t38jointcapability);
+		p->t38.jointcapability = p->t38.capability;
+		if (option_debug)
+			ast_log(LOG_DEBUG,"Our T38 capability (%d), joint T38 capability (%d)\n", p->t38.capability, p->t38.jointcapability);
 #endif
 		transmit_invite(p, SIP_INVITE, 1, 2);
 		if (p->maxtime) {
@@ -2732,9 +2753,10 @@
 		if (option_debug)
 			ast_log(LOG_DEBUG, "SIP answering channel: %s\n", ast->name);
 #if defined(T38_SUPPORT)
-		if (p->t38state == 3) {
-			p->t38state=5;
-			ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n",p->t38state, ast->name);
+		if (p->t38.state == T38_PEER_DIRECT) {
+			p->t38.state = T38_ENABLED;
+			if (option_debug > 1)
+				ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name);
 			res = transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, 1);
 		} else
 #endif
@@ -2957,15 +2979,16 @@
 }
 
 #ifdef T38_SUPPORT
-static int sip_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo,struct ast_channel **rc, int timeoutms) {
-
-     /* Because attempt to do a native RTP bridge between peers happens before T38 re-invites
+/*! \brief SIP bridge
+\note	 Because attempt to do a native RTP bridge between peers happens before T38 re-invites
         and that one time only, and at that moment neither peers have T38 enabled, this will
         lead to the native RTP bridge always (if canreinvite is set to yes). 
 	Since this is not good for T38 bridging, we have to disable native bridging entirely if 
 	t38 support is enabled - not good, but working. 
 	XXX: It would be better to have user/peer configuration flag for t38support. :XXX
      */
+static int sip_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo,struct ast_channel **rc, int timeoutms) {
+
 	if (!global_t38udptl_support) {
 		return ast_rtp_bridge(c0,c1,flags,fo,rc,timeoutms);
 	} else {
@@ -3277,7 +3300,7 @@
 	struct ast_frame *fr;
 	struct sip_pvt *p = ast->tech_pvt;
 #if defined(T38_SUPPORT)
-	int faxdetected = 0;
+	int faxdetected = FALSE;
 #endif
 	ast_mutex_lock(&p->lock);
 #if defined(T38_SUPPORT)
@@ -3289,15 +3312,16 @@
 	ast_mutex_unlock(&p->lock);
 #if defined(T38_SUPPORT)
 	/* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */
-	/* If we are bridged than it is responsibility of the SIP device to issue T38 re-invite if it detects CNG or fax preabmle */
-	if (faxdetected  && global_t38udptl_support && (p->t38state == 0) && !(ast_bridged_channel(ast))) {
+	/* If we are bridged then it is responsibility of the SIP device to issue T38 re-invite if it detects CNG or fax preabmle */
+	if (faxdetected  && global_t38udptl_support && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) {
 		if (!ast_test_flag(p, SIP_GOTREFER)) {
 			if (!p->pendinginvite) {
 				if (option_debug > 2)
 					ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name);
-				p->t38state = 2;
+				p->t38.state = T38_LOCAL_REINVITE;
 				transmit_reinvite_with_t38_sdp(p);
-				ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s",p->t38state,ast->name);
+				if (option_debug > 1)
+					ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s", p->t38.state, ast->name);
 			}
 		} else if (!ast_test_flag(p, SIP_PENDINGBYE)) {
 				if (option_debug > 2)
@@ -3401,6 +3425,7 @@
 #if defined(T38_SUPPORT)
 		if (global_t38udptl_support)
 			p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr);
+			/* TODO: Need to check for error - or ?? */
 #endif
 		if (!p->rtp || (global_videosupport && !p->vrtp)) {
 			ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", global_videosupport ? "and video" : "", strerror(errno));
@@ -3453,15 +3478,15 @@
 		p->noncodeccapability |= AST_RTP_DTMF;
 #if defined(T38_SUPPORT)
 	if (p->udptl) {
-	    p->t38capability = global_t38_capability;
-	    if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY)
-		    p->t38capability |= T38FAX_UDP_EC_REDUNDANCY;
-	    else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC)
-		    p->t38capability |= T38FAX_UDP_EC_FEC;
-	    else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE)
-		    p->t38capability |= T38FAX_UDP_EC_NONE;
-	    p->t38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
-	    p->t38jointcapability = p->t38capability;
+		p->t38.capability = global_t38_capability;
+		if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY)
+			p->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
+		else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_FEC)
+			p->t38.capability |= T38FAX_UDP_EC_FEC;
+		else if (ast_udptl_get_error_correction_scheme(p->udptl) == UDPTL_ERROR_CORRECTION_NONE)
+			p->t38.capability |= T38FAX_UDP_EC_NONE;
+		p->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
+		p->t38.jointcapability = p->t38.capability;
 	}	
 #endif
 	ast_string_field_set(p, context, default_context);
@@ -3839,11 +3864,13 @@
 			udptlportno = x;
 			
 			if (p->owner && p->lastinvite) {
-				p->t38state = 4; /* T38 Offered in re-invite from remote party */
-				ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n",p->t38state,p->owner ? p->owner->name : "<none>" );
+				p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */
+				if (option_debug > 1)
+					ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" );
 			} else {
-				p->t38state = 3; /* T38 Offered directly from peer in first invite */
-				ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n",p->t38state,p->owner ? p->owner->name : "<none>");
+				p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */
+				if (option_debug > 1)
+					ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
 			}				
 		}
 #endif
@@ -3934,7 +3961,6 @@
 	if (p->udptl && global_t38udptl_support && sin.sin_port) {
 		ast_udptl_set_peer(p->udptl, &sin);
 		if (debug) {
-			ast_verbose("Peer T.38 UDPTL is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
 			ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
 		}
 	}
@@ -3963,22 +3989,25 @@
 	}
 #if defined(T38_SUPPORT)
 	if (udptlportno != -1) {
+		old = 0;
+		int found = 0;
+
 		/* Scan trough the a= lines for T38 attributes and set apropriate fileds */
 		sdpLineNum_iterator_init(&iterator);
-		old = 0;
-		int found = 0;
 		while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
 			if (old && (iterator-old != 1))
-			    break;
+				break;
 			old = iterator;
 			
 			if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) {
 				found = 1;
-				ast_log(LOG_DEBUG,"MaxBufferSize:%d\n",x);
+				if (option_debug > 2)
+					ast_log(LOG_DEBUG,"MaxBufferSize:%d\n",x);
 			}
 			if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) {
 				found = 1;
-				ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x);
+				if (option_debug > 2)
+					ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x);
 				switch (x) {
 				    case 14400:
 					peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
@@ -4002,7 +4031,8 @@
 			}
 			if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) {
 				found = 1;
-				ast_log(LOG_DEBUG,"FaxVerison: %d\n",x);
+				if (option_debug > 2)
+					ast_log(LOG_DEBUG,"FaxVerison: %d\n",x);
 				if (x == 0)
 					peert38capability |= T38FAX_VERSION_0;
 				else if (x == 1)
@@ -4010,31 +4040,36 @@
 			}
 			if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) {
 				found = 1;
-				ast_log(LOG_DEBUG,"FaxMaxDatagram: %d\n",x);
+				if (option_debug > 2)
+					ast_log(LOG_DEBUG,"FaxMaxDatagram: %d\n",x);
 				ast_udptl_set_far_max_datagram(p->udptl, x);
 				ast_udptl_set_local_max_datagram(p->udptl, x);
 			}
 			if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) {
 				found = 1;
-				ast_log(LOG_DEBUG,"FillBitRemoval: %d\n",x);
+				if (option_debug > 2)
+					ast_log(LOG_DEBUG,"FillBitRemoval: %d\n",x);
 				if (x == 1)
 					peert38capability |= T38FAX_FILL_BIT_REMOVAL;
 			}
 			if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) {
 				found = 1;
-				ast_log(LOG_DEBUG,"Transcoding MMR: %d\n",x);
+				if (option_debug > 2)
+					ast_log(LOG_DEBUG,"Transcoding MMR: %d\n",x);
 				if (x == 1)
 					peert38capability |= T38FAX_TRANSCODING_MMR;
 			}
 			if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) {
 				found = 1;
-				ast_log(LOG_DEBUG,"Transcoding JBIG: %d\n",x);
+				if (option_debug > 2)
+					ast_log(LOG_DEBUG,"Transcoding JBIG: %d\n",x);
 				if (x == 1)
 					peert38capability |= T38FAX_TRANSCODING_JBIG;
 			}
 			if ((sscanf(a, "T38FaxRateManagement:%s", s) == 1)) {
 			    	found = 1;
-				ast_log(LOG_DEBUG,"RateMangement: %s\n", s);
+				if (option_debug > 2)
+					ast_log(LOG_DEBUG,"RateMangement: %s\n", s);
 				if (!strcasecmp(s, "localTCF"))
 					peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF;
 				else if (!strcasecmp(s, "transferedTCF"))
@@ -4042,7 +4077,8 @@
 			}
 			if ((sscanf(a, "T38FaxUdpEC:%s", s) == 1)) {
 				found = 1;
-				ast_log(LOG_DEBUG,"UDP EC: %s\n", s);
+				if (option_debug > 2)
+					ast_log(LOG_DEBUG,"UDP EC: %s\n", s);
 				if (!strcasecmp(s, "t38UDPRedundancy")) {
 					peert38capability |= T38FAX_UDP_EC_REDUNDANCY;
 					ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY);
@@ -4056,19 +4092,20 @@
 			}
 		}
 		if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */ 
-			p->t38peercapability = peert38capability;
-			p->t38jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */
+			p->t38.peercapability = peert38capability;
+			p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */
 			peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400); /* Mask speeds only */ 
-			p->t38jointcapability |= (peert38capability & p->t38capability); /* Put the lower of our's and peer's speed */
+			p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */
 		}
 		if (debug)
 			ast_log(LOG_DEBUG,"Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n",
-				    p->t38capability, 
-				    p->t38peercapability,
-				    p->t38jointcapability);
+				    p->t38.capability, 
+				    p->t38.peercapability,
+				    p->t38.jointcapability);
 	} else {
-		p->t38state = 0;
-		ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n",p->t38state,p->owner ? p->owner->name : "<none>");
+		p->t38.state = T38_DISABLED;
+		if (option_debug > 1)
+			ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
 	}
 #endif
 
@@ -4816,35 +4853,43 @@
 		ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code);
 }
 #if defined(T38_SUPPORT)
-/*--- t38_get_rate: Get Max T.38 Transmision rate from T38 capabilities ---*/
+/*! \brief Get Max T.38 Transmision rate from T38 capabilities */
 int t38_get_rate(int t38cap)
 {
     int maxrate = (t38cap & (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400));
+
     if (maxrate & T38FAX_RATE_14400) {
-		ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n");
+		if (option_debug > 1)
+			ast_log(LOG_DEBUG, "T38MaxFaxRate 14400 found\n");
 		return 14400;
     } else if (maxrate & T38FAX_RATE_12000) {
-		ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n");
+		if (option_debug > 1)
+			ast_log(LOG_DEBUG, "T38MaxFaxRate 12000 found\n");
 		return 12000;
     } else if (maxrate & T38FAX_RATE_9600) {
-		ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n");
+		if (option_debug > 1)
+			ast_log(LOG_DEBUG, "T38MaxFaxRate 9600 found\n");
 		return 9600;
     } else if (maxrate & T38FAX_RATE_7200) {
-		ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n");
+		if (option_debug > 1)
+			ast_log(LOG_DEBUG, "T38MaxFaxRate 7200 found\n");
 		return 7200;
     } else if (maxrate & T38FAX_RATE_4800) {
-		ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n");
+		if (option_debug > 1)
+			ast_log(LOG_DEBUG, "T38MaxFaxRate 4800 found\n");
 		return 4800;
     } else if (maxrate & T38FAX_RATE_2400) {
-		ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n");
+		if (option_debug > 1)
+			ast_log(LOG_DEBUG, "T38MaxFaxRate 2400 found\n");
 		return 2400;
     } else {
-		ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n");
+		if (option_debug > 1)
+			ast_log(LOG_DEBUG, "Strange, T38MaxFaxRate NOT found in peers T38 SDP.\n");
 		return 0;
     }
 }
 
-/*--- add_t38_sdp: Add T.38 Session Description Protocol message ---*/
+/*! \brief Add T.38 Session Description Protocol message */
 static int add_t38_sdp(struct sip_request *resp, struct sip_pvt *p)
 {
 	int len = 0;
@@ -4893,19 +4938,19 @@
 		}
 	}
 
-	if (debug){
-		if (p->udptl)
-			ast_verbose("T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(udptlsin.sin_port));	
+	if (debug) {
+		if (p->udptl && debug)
+			ast_log(LOG_DEBUG, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(udptlsin.sin_port));	
 	}
 
 	/* We break with the "recommendation" and send our IP, in order that our
 	   peer doesn't have to ast_gethostbyname() us */
 
-	if (debug){
+	if (debug) {
 		ast_log(LOG_DEBUG, "Our T38 capability (%d), peer T38 capability (%d), joint capability (%d)\n",
-			p->t38capability,
-			p->t38peercapability,
-			p->t38jointcapability);	
+			p->t38.capability,
+			p->t38.peercapability,
+			p->t38.jointcapability);	
 	}
 	snprintf(v, sizeof(v), "v=0\r\n");
 	snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(iabuf, sizeof(iabuf), udptldest.sin_addr));
@@ -4914,21 +4959,21 @@
 	snprintf(t, sizeof(t), "t=0 0\r\n");
 	ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port));
 
-	if ((p->t38jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0)
+	if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0)
 		ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVerison:0\r\n");
-	if ((p->t38jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1)
+	if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1)
 		ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVerison:1\r\n");
-	if ((x = t38_get_rate(p->t38jointcapability))) 
+	if ((x = t38_get_rate(p->t38.jointcapability))) 
 		ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x);
-	ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0);
-	ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0);
-	ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0);
-	ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferedTCF");
+	ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0);
+	ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0);
+	ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0);
+	ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferedTCF");
 	x = ast_udptl_get_local_max_datagram(p->udptl);
 	ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x);
 	ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x);
-	if (p->t38jointcapability != T38FAX_UDP_EC_NONE)
-		ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC");
+	if (p->t38.jointcapability != T38FAX_UDP_EC_NONE)
+		ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC");
 	if (p->udptl)
 		len = strlen(m_modem) + strlen(a_modem);
 	add_header(resp, "Content-Type", "application/sdp");
@@ -5189,6 +5234,7 @@
 {
 	struct sip_request resp;
 	int seqno;
+
 	if (sscanf(get_header(req, "CSeq"), "%d ", &seqno) != 1) {
 		ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
 		return -1;
@@ -5637,9 +5683,10 @@
 		}
 	}
 #if defined(T38_SUPPORT)
-	if (sdp && (p->udptl) && (p->t38state == 1)) {
+	if (sdp && (p->udptl) && (p->t38.state == T38_LOCAL_DIRECT)) {
 		ast_udptl_offered_from_local(p->udptl, 1);
-		ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n",p->t38state, p->owner ? p->owner->name : "<none>");
+		if (option_debug)
+			ast_log(LOG_DEBUG, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
 		add_t38_sdp(&req, p);
 	} else if (sdp && p->rtp) {
 #else
@@ -7729,7 +7776,8 @@
 		}
 #if defined(T38_SUPPORT)
 		if (p->udptl) {
-			ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
+			if (option_debug)
+				ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
 			ast_udptl_setnat(p->udptl, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
 		}
 #endif
@@ -7776,8 +7824,8 @@
 			else
 				p->noncodeccapability &= ~AST_RTP_DTMF;
 #if defined(T38_SUPPORT)
-			if (p->t38peercapability)
-				p->t38jointcapability &= p->t38peercapability;
+			if (p->t38.peercapability)
+				p->t38.jointcapability &= p->t38.peercapability;
 #endif
 		}
 		if (user && debug)
@@ -7826,16 +7874,19 @@
 				}
 			}
 			if (p->rtp) {
-				ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
+				if (option_debug)
+					ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
 				ast_rtp_setnat(p->rtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
 			}
 			if (p->vrtp) {
-				ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
+				if (option_debug)
+					ast_log(LOG_DEBUG, "Setting NAT on VRTP to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
 				ast_rtp_setnat(p->vrtp, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
 			}
 #if defined(T38_SUPPORT)
 			if (p->udptl) {
-				ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
+				if (option_debug)
+					ast_log(LOG_DEBUG, "Setting NAT on UDPTL to %d\n", (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
 				ast_udptl_setnat(p->udptl, (ast_test_flag(p, SIP_NAT) & SIP_NAT_ROUTE));
 			}
 #endif
@@ -7903,8 +7954,8 @@
 				else
 					p->noncodeccapability &= ~AST_RTP_DTMF;
 #if defined(T38_SUPPORT)
-				if (p->t38peercapability)
-					p->t38jointcapability &= p->t38peercapability;
+				if (p->t38.peercapability)
+					p->t38.jointcapability &= p->t38.peercapability;
 #endif
 			}
 			ASTOBJ_UNREF(peer, sip_destroy_peer);
@@ -10199,6 +10250,7 @@
 		if (p->owner && (p->owner->_state == AST_STATE_UP)) { /* if this is a re-invite */ 
 			struct ast_channel *bridgepeer = NULL;
 			struct sip_pvt *bridgepvt = NULL;
+
 			bridgepeer = ast_bridged_channel(p->owner);
 			if (!bridgepeer->tech) {
 				ast_log(LOG_WARNING, "Ooooh.. no tech!  That's REALLY bad\n");
@@ -10207,11 +10259,11 @@
 			if (!strcasecmp(bridgepeer->tech->type,"SIP")) {
 				bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt);
 				if (bridgepvt->udptl) {
-					if (p->t38state == 4) { 
+					if (p->t38.state == T38_PEER_REINVITE) { 
 						/* This is 200 OK to re-invite where T38 was offered on channel so we need to send 200 OK with T38 the other side of the bridge */
 						/* Send response with T38 SDP to the other side of the bridge */
-						sip_handle_t38_reinvite(bridgepeer,p,0);
-					} else if (p->t38state == 0 && bridgepeer && (bridgepvt->t38state == 5)) { /* This is case of RTP re-invite after T38 session */
+						sip_handle_t38_reinvite(bridgepeer, p, 0);
+					} else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) { /* This is case of RTP re-invite after T38 session */
 						ast_log(LOG_WARNING, "RTP re-inivte after T38 session not handled yet !\n");
 						/* Insted of this we should somehow re-invite the other side of the bridge to RTP */
 						ast_set_flag(p, SIP_NEEDDESTROY);
@@ -10219,23 +10271,27 @@
 				} else {
 						ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n");
 						ast_mutex_lock(&bridgepvt->lock);
-						bridgepvt->t38state = 0;
+						bridgepvt->t38.state = T38_DISABLED;
 						ast_mutex_unlock(&bridgepvt->lock);
-						ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n",bridgepvt->t38state, bridgepeer->tech->type);
-						p->t38state = 0;
-						ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n",p->t38state, p->owner ? p->owner->name : "<none>");
+						if (option_debug)
+							ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->tech->type);
+						p->t38.state = T38_DISABLED;
+						if (option_debug > 1)
+							ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
 				}
 			} else {
-					/* Other side is not a SIP channel */ 
-					ast_log(LOG_WARNING, "Strange... The other side of the bridge is not a SIP channel\n");
-					p->t38state = 0;
-					ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n",p->t38state, p->owner ? p->owner->name : "<none>");
+				/* Other side is not a SIP channel */ 
+				ast_log(LOG_WARNING, "Strange... The other side of the bridge is not a SIP channel\n");
+				p->t38.state = T38_DISABLED;
+				if (option_debug > 1)
+					ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
 			}
 		}
-		if ((p->t38state == 2) || (p->t38state == 1)) {
+		if ((p->t38.state == T38_LOCAL_REINVITE) || (p->t38.state == T38_LOCAL_DIRECT)) {
 			/* If there was T38 reinvite and we are supposed to answer with 200 OK than this should set us to T38 negotiated mode */
-			p->t38state = 5;
-			ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38state, p->owner ? p->owner->name : "<none>");
+			p->t38.state = T38_ENABLED;
+			if (option_debug)
+				ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
 		}
 #endif
 		if (!ignore && p->owner) {
@@ -11210,32 +11266,32 @@
 			break;
 		case AST_STATE_UP:
 #if defined(T38_SUPPORT)
-			if (p->t38state == 4) {
-	    		    struct ast_channel *bridgepeer = NULL;
-			    struct sip_pvt *bridgepvt = NULL;
-			    if ((bridgepeer=ast_bridged_channel(p->owner))) {
+			if (p->t38.state == T38_PEER_REINVITE) {
+	    			struct ast_channel *bridgepeer = NULL;
+				struct sip_pvt *bridgepvt = NULL;
+
+				if ((bridgepeer = ast_bridged_channel(p->owner))) {
 					/* We have a bridge, and this is re-invite to switchover to T38 so we send re-invite with T38 SDP, to other side of bridge*/
 					/*! XXX: we should also check here does the other side supports t38 at all !!! XXX */  
-					if (!strcasecmp(bridgepeer->tech->type,"SIP")) { /* If we are bridged to SIP channel */
+					if (!strcasecmp(bridgepeer->tech->type, "SIP")) { /* If we are bridged to SIP channel */
 						bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
-						if (!(bridgepvt->t38state)) {
-						    if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */
-							    /* Send re-invite to the bridged channel */ 
-							    sip_handle_t38_reinvite(bridgepeer,p,1);
-						    } else { /* Something is wrong with peers udptl struct */
-							    ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n");
-							    ast_mutex_lock(&bridgepvt->lock);
-							    bridgepvt->t38state = 0;
-							    ast_mutex_unlock(&bridgepvt->lock);
-							    ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n",bridgepvt->t38state, bridgepeer->name);
-							    p->t38state = 0;
-							    ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n",p->t38state, p->owner ? p->owner->name : "<none>");
-	    						    if (ignore)
-								    transmit_response(p, "415 Unsupported Media Type", req);
-							    else
-								    transmit_response_reliable(p, "415 Unsupported Media Type", req, 1);
-							    ast_set_flag(p, SIP_NEEDDESTROY);
-						    } 
+						if (bridgepvt->t38.state == T38_DISABLED) {
+							if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */
+								/* Send re-invite to the bridged channel */ 
+								sip_handle_t38_reinvite(bridgepeer, p, 1);
+							} else { /* Something is wrong with peers udptl struct */
+								ast_log(LOG_WARNING, "Strange... The other side of the bridge don't have udptl struct\n");
+								ast_mutex_lock(&bridgepvt->lock);
+								bridgepvt->t38.state = T38_DISABLED;
+								ast_mutex_unlock(&bridgepvt->lock);
+								if (option_debug > 1)
+							    		ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name);
+	    						 	if (ignore)
+									transmit_response(p, "415 Unsupported Media Type", req);
+								else
+									transmit_response_reliable(p, "415 Unsupported Media Type", req, 1);
+								ast_set_flag(p, SIP_NEEDDESTROY);
+							} 
 						}
 					} else {
 						/* Other side is not a SIP channel */
@@ -11243,41 +11299,43 @@
 							transmit_response(p, "415 Unsupported Media Type", req);
 						else 
 	    						transmit_response_reliable(p, "415 Unsupported Media Type", req, 1);
-						p->t38state = 0;
-						ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n",p->t38state, p->owner ? p->owner->name : "<none>");
+						p->t38.state = T38_DISABLED;
+						if (option_debug > 1)
+							ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
 						ast_set_flag(p, SIP_NEEDDESTROY);		
 					}	
-			    } else {
-				/* we are not bridged in a call */ 
-				transmit_response_with_t38_sdp(p, "200 OK", req, 1);
-				p->t38state = 5;
-				ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n",p->t38state, p->owner ? p->owner->name : "<none>");
-			    }
-			} else if (p->t38state == 0) { /* Channel doesn't have T38 offered or enabled */
-					/* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */
-					/* so handle it here (re-invite other party to RTP) */
-	    				struct ast_channel *bridgepeer = NULL;
-					struct sip_pvt *bridgepvt = NULL;
-					if ((bridgepeer=ast_bridged_channel(p->owner))) {
-						if (!strcasecmp(bridgepeer->tech->type,"SIP")) {
-							bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
-							if (bridgepvt->t38state == 5) {
-								ast_log(LOG_WARNING, "RTP re-inivte after T38 session not handled yet !\n");
-								/* Insted of this we should somehow re-invite the other side of the bridge to RTP */
-								if (ignore)
-									transmit_response(p, "488 Not Acceptable Here (unsupported)", req);
-								else
-									transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req, 1);
-								ast_set_flag(p, SIP_NEEDDESTROY);
-							} else {
-								/* No bridged peer with T38 enabled*/
-								transmit_response_with_sdp(p, "200 OK", req, 1);
-							}
+				} else {
+					/* we are not bridged in a call */ 
+					transmit_response_with_t38_sdp(p, "200 OK", req, 1);
+					p->t38.state = T38_ENABLED;
+					if (option_debug)
+						ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
+				}
+			} else if (p->t38.state == T38_DISABLED) { /* Channel doesn't have T38 offered or enabled */
+				/* If we are bridged to a channel that has T38 enabled than this is a case of RTP re-invite after T38 session */
+				/* so handle it here (re-invite other party to RTP) */
+	    			struct ast_channel *bridgepeer = NULL;
+				struct sip_pvt *bridgepvt = NULL;
+				if ((bridgepeer = ast_bridged_channel(p->owner))) {
+					if (!strcasecmp(bridgepeer->tech->type, sip_tech.type)) {
+						bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
+						if (bridgepvt->t38.state == T38_ENABLED) {
+							ast_log(LOG_WARNING, "RTP re-invite after T38 session not handled yet !\n");
+							/* Insted of this we should somehow re-invite the other side of the bridge to RTP */
+							if (ignore)
+								transmit_response(p, "488 Not Acceptable Here (unsupported)", req);
+							else
+								transmit_response_reliable(p, "488 Not Acceptable Here (unsupported)", req, 1);
+							ast_set_flag(p, SIP_NEEDDESTROY);
+						} else {

[... 88 lines stripped ...]


More information about the asterisk-commits mailing list