mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 10:47:18 +00:00 
			
		
		
		
	Fix up some T38 state change issues.
(closes issue #11630) Reported by: dimas Patches: v2-sip-t38state.patch uploaded by dimas (license 88) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@100671 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		| @@ -1662,6 +1662,12 @@ static struct ast_config *notify_types;		/*!< The list of manual NOTIFY types we | ||||
| 		(head) = (element)->next;	\ | ||||
| 	} while (0) | ||||
|  | ||||
| enum t38_action_flag { | ||||
| 	SDP_T38_NONE = 0, /*!< Do not modify T38 information at all */ | ||||
| 	SDP_T38_INITIATE, /*!< Remote side has requested T38 with us */ | ||||
| 	SDP_T38_ACCEPT,   /*!< Remote side accepted our T38 request */ | ||||
| }; | ||||
|  | ||||
| /*---------------------------- Forward declarations of functions in chan_sip.c */ | ||||
| /*! \note This is added to help splitting up chan_sip.c into several files | ||||
| 	in coming releases */ | ||||
| @@ -1753,7 +1759,7 @@ static void try_suggested_sip_codec(struct sip_pvt *p); | ||||
| static const char* get_sdp_iterate(int* start, struct sip_request *req, const char *name); | ||||
| static const char *get_sdp(struct sip_request *req, const char *name); | ||||
| static int find_sdp(struct sip_request *req); | ||||
| static int process_sdp(struct sip_pvt *p, struct sip_request *req); | ||||
| static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action); | ||||
| static void add_codec_to_sdp(const struct sip_pvt *p, int codec, int sample_rate, | ||||
| 			     struct ast_str **m_buf, struct ast_str **a_buf, | ||||
| 			     int debug, int *min_packet_size); | ||||
| @@ -6075,7 +6081,7 @@ static int find_sdp(struct sip_request *req) | ||||
|  	Return 0 on success, a negative value on errors. | ||||
| 	Must be called after find_sdp(). | ||||
| */ | ||||
| static int process_sdp(struct sip_pvt *p, struct sip_request *req) | ||||
| static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action) | ||||
| { | ||||
| 	const char *m;		/* SDP media offer */ | ||||
| 	const char *c; | ||||
| @@ -6292,14 +6298,6 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req) | ||||
| 				ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); | ||||
| 			udptlportno = x; | ||||
| 			numberofmediastreams++; | ||||
| 			 | ||||
| 			if (p->owner && p->lastinvite) { | ||||
| 				p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ | ||||
| 				ast_debug(2, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" ); | ||||
| 			} else { | ||||
| 				p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ | ||||
| 				ast_debug(2, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); | ||||
| 			} | ||||
| 		} else  | ||||
| 			ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); | ||||
| 		if (numberofports > 1) | ||||
| @@ -6608,11 +6606,25 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req) | ||||
| 				p->t38.capability, | ||||
| 				p->t38.peercapability, | ||||
| 				p->t38.jointcapability); | ||||
|  | ||||
|  | ||||
| 		/* Remote party offers T38, we need to update state */ | ||||
| 		if (t38action == SDP_T38_ACCEPT) { | ||||
| 			if (p->t38.state == T38_LOCAL_DIRECT || p->t38.state == T38_LOCAL_REINVITE) | ||||
| 				p->t38.state = T38_ENABLED; | ||||
| 		} else if (t38action == SDP_T38_INITIATE) { | ||||
| 			if (p->owner && p->lastinvite) { | ||||
| 				p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ | ||||
| 			} else { | ||||
| 				p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ | ||||
| 			} | ||||
| 		} | ||||
| 	} else { | ||||
| 		p->t38.state = T38_DISABLED; | ||||
| 		ast_debug(3, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); | ||||
| 	} | ||||
|  | ||||
| 	ast_debug(3, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>"); | ||||
|  | ||||
| 	/* Now gather all of the codecs that we are asked for: */ | ||||
| 	ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); | ||||
| 	ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); | ||||
| @@ -14278,7 +14290,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru | ||||
| 		if (find_sdp(req)) { | ||||
| 			if (p->invitestate != INV_CANCELLED) | ||||
| 				p->invitestate = INV_EARLY_MEDIA; | ||||
| 			res = process_sdp(p, req); | ||||
| 			res = process_sdp(p, req, SDP_T38_NONE); | ||||
| 			if (!req->ignore && p->owner) { | ||||
| 				/* Queue a progress frame only if we have SDP in 180 or 182 */ | ||||
| 				ast_queue_control(p->owner, AST_CONTROL_PROGRESS); | ||||
| @@ -14294,7 +14306,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru | ||||
| 		if (find_sdp(req)) { | ||||
| 			if (p->invitestate != INV_CANCELLED) | ||||
| 				p->invitestate = INV_EARLY_MEDIA; | ||||
| 			res = process_sdp(p, req); | ||||
| 			res = process_sdp(p, req, SDP_T38_NONE); | ||||
| 			if (!req->ignore && p->owner) { | ||||
| 				/* Queue a progress frame */ | ||||
| 				ast_queue_control(p->owner, AST_CONTROL_PROGRESS); | ||||
| @@ -14308,7 +14320,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru | ||||
| 			ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n"); | ||||
| 		p->authtries = 0; | ||||
| 		if (find_sdp(req)) { | ||||
| 			if ((res = process_sdp(p, req)) && !req->ignore) | ||||
| 			if ((res = process_sdp(p, req, SDP_T38_ACCEPT)) && !req->ignore) | ||||
| 				if (!reinvite) | ||||
| 					/* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ | ||||
| 					/* For re-invites, we try to recover */ | ||||
| @@ -15114,7 +15126,7 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_ | ||||
| 					if (!req->ignore && sip_cancel_destroy(p)) | ||||
| 						ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n"); | ||||
| 					if (find_sdp(req)) | ||||
| 						process_sdp(p, req); | ||||
| 						process_sdp(p, req, SDP_T38_NONE); | ||||
| 					if (p->owner) { | ||||
| 						/* Queue a progress frame */ | ||||
| 						ast_queue_control(p->owner, AST_CONTROL_PROGRESS); | ||||
| @@ -16045,7 +16057,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int | ||||
| 			ast_clear_flag(&p->flags[0], SIP_OUTGOING);	/* This is now an inbound dialog */ | ||||
| 			/* Handle SDP here if we already have an owner */ | ||||
| 			if (find_sdp(req)) { | ||||
| 				if (process_sdp(p, req)) { | ||||
| 				if (process_sdp(p, req, SDP_T38_INITIATE)) { | ||||
| 					transmit_response(p, "488 Not acceptable here", req); | ||||
| 					if (!p->lastinvite) | ||||
| 						sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); | ||||
| @@ -16086,7 +16098,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int | ||||
|  | ||||
| 		/* We have a succesful authentication, process the SDP portion if there is one */ | ||||
| 		if (find_sdp(req)) { | ||||
| 			if (process_sdp(p, req)) { | ||||
| 			if (process_sdp(p, req, SDP_T38_INITIATE)) { | ||||
| 				/* Unacceptable codecs */ | ||||
| 				transmit_response_reliable(p, "488 Not acceptable here", req); | ||||
| 				p->invitestate = INV_COMPLETED;	 | ||||
| @@ -17712,7 +17724,7 @@ static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct so | ||||
| 			p->pendinginvite = 0; | ||||
| 			__sip_ack(p, seqno, 1 /* response */, 0); | ||||
| 			if (find_sdp(req)) { | ||||
| 				if (process_sdp(p, req)) | ||||
| 				if (process_sdp(p, req, SDP_T38_NONE)) | ||||
| 					return -1; | ||||
| 			}  | ||||
| 			check_pendings(p); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user