[asterisk-commits] oej: branch oej/codename-pineapple r48339 - /team/oej/codename-pineapple/chan...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Wed Dec 6 13:53:23 MST 2006


Author: oej
Date: Wed Dec  6 14:53:22 2006
New Revision: 48339

URL: http://svn.digium.com/view/asterisk?view=rev&rev=48339
Log:
- Cleaning up handle_response_invite a bit more
- stringfieldization still needs some work.

Modified:
    team/oej/codename-pineapple/channels/chan_sip3.c

Modified: team/oej/codename-pineapple/channels/chan_sip3.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/chan_sip3.c?view=diff&rev=48339&r1=48338&r2=48339
==============================================================================
--- team/oej/codename-pineapple/channels/chan_sip3.c (original)
+++ team/oej/codename-pineapple/channels/chan_sip3.c Wed Dec  6 14:53:22 2006
@@ -4303,7 +4303,6 @@
 	"- t38passthrough        1 if T38 is offered or enabled in this channel, otherwise 0\n"
 };
 
-
 /*! \brief Check pending actions on SIP call */
 static void check_pendings(struct sip_dialog *p)
 {
@@ -4326,13 +4325,114 @@
 	}
 }
 
+/*! \brief Handle a positive response to an INVITE - 200 OK */
+static void handle_response_answer(struct sip_dialog *dialog, struct sip_request *req, int outgoing, int reinvite)
+{
+	int res; 	/*! \note XXX Not used now, but somehow we need to handle response from process_sdp */
+	struct ast_channel *bridgepeer = NULL;
+
+	/* If we have SDP in the 200 OK, then process it */
+	if (find_sdp(req)) {
+		if ((res = process_sdp(dialog, req)) && !ast_test_flag(req, SIP_PKT_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 */
+				ast_set_flag(&dialog->flags[0], SIP_PENDINGBYE);	
+	} else 
+		ast_log(LOG_NOTICE, "200 OK on INVITE without SDP??? Call-ID: %s\n", dialog->callid);
+
+	/* Parse contact header for continued conversation */
+	/* When we get 200 OK, we know which device (and IP) to contact for this call */
+	/* This is important when we have a SIP proxy between us and the phone */
+	if (outgoing) {
+		update_call_counter(dialog, DEC_CALL_RINGING);
+		parse_ok_contact(dialog, req);
+		if(set_address_from_contact(dialog)) {
+			/* Bad contact - we don't know how to reach this device */
+			/* We need to ACK, but then send a bye */
+			/* OEJ: Possible issue that may need a check:
+				If we have a proxy route between us and the device,
+				should we care about resolving the contact
+				or should we just send it?
+			*/
+			if (!ast_test_flag(req, SIP_PKT_IGNORE))
+				ast_set_flag(&dialog->flags[0], SIP_PENDINGBYE);	
+		} 
+
+		/* Save Record-Route for any later requests we make on this dialogue */
+		build_route(dialog, req, 1);
+	}
+		
+	if (dialog->owner && (dialog->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(dialog->owner))) { /* if this is a re-invite */
+		struct sip_dialog *bridge_dialog = NULL;
+
+		if (!bridgepeer->tech) {
+			ast_log(LOG_WARNING, "Ooooh.. no tech!  That's REALLY bad\n");
+			return;		/*! \todo Fix this - this looks really bad */
+		}
+		if (bridgepeer->tech == &sip_tech) {
+			bridge_dialog = (struct sip_dialog *)(bridgepeer->tech_pvt);
+			if (bridge_dialog->udptl) {
+				if (dialog->t38.state == T38_PEER_REINVITE) {
+					sip_handle_t38_reinvite(bridgepeer, dialog, 0);
+					ast_rtp_set_rtptimers_onhold(dialog->rtp);
+					if (dialog->vrtp)
+						ast_rtp_set_rtptimers_onhold(dialog->vrtp);	/* Turn off RTP timers while we send fax */
+				} else if (dialog->t38.state == T38_DISABLED && bridgepeer && (bridge_dialog->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 (!ast_test_flag(req, SIP_PKT_IGNORE))
+						ast_set_flag(&dialog->flags[0], SIP_PENDINGBYE);	
+				}
+			} else {
+				if (option_debug > 1)
+					ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n");
+				dialog_lock(bridge_dialog, TRUE);
+				bridge_dialog->t38.state = T38_DISABLED;
+				dialog_lock(bridge_dialog, FALSE);
+				if (option_debug)
+					ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridge_dialog->t38.state, bridgepeer->tech->type);
+				dialog->t38.state = T38_DISABLED;
+				if (option_debug > 1)
+					ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", dialog->t38.state, dialog->owner ? dialog->owner->name : "<none>");
+			}
+		} else {
+			/* Other side is not a SIP channel */
+			if (option_debug > 1)
+				ast_log(LOG_DEBUG, "Strange... The other side of the bridge is not a SIP channel\n");
+			dialog->t38.state = T38_DISABLED;
+			if (option_debug > 1)
+				ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", dialog->t38.state, dialog->owner ? dialog->owner->name : "<none>");
+		}
+	}
+	if ((dialog->t38.state == T38_LOCAL_REINVITE) || (dialog->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 */
+		dialog->t38.state = T38_ENABLED;
+		if (option_debug)
+			ast_log(LOG_DEBUG, "T38 changed state to %d on channel %s\n", dialog->t38.state, dialog->owner ? dialog->owner->name : "<none>");
+	}
+
+	/* Ok, let's go */
+	if (!ast_test_flag(req, SIP_PKT_IGNORE) && dialog->owner) {
+		if (!reinvite) 
+			ast_queue_control(dialog->owner, AST_CONTROL_ANSWER);
+		else 	/* RE-invite */
+			ast_queue_frame(dialog->owner, &ast_null_frame);
+	} else {
+		 /* It's possible we're getting an 200 OK after we've tried to disconnect
+			  by sending CANCEL */
+		/* First send ACK, then send bye */
+		if (!ast_test_flag(req, SIP_PKT_IGNORE))
+			ast_set_flag(&dialog->flags[0], SIP_PENDINGBYE);	
+	}
+}
+
 /*! \brief Handle SIP response to INVITE dialogue */
 static void handle_response_invite(struct sip_dialog *p, int resp, char *rest, struct sip_request *req)
 {
 	int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING);
 	int res = 0;
 	int reinvite = (p->owner && p->owner->_state == AST_STATE_UP);
-	struct ast_channel *bridgepeer = NULL;
 	
 	if (option_debug > 3) {
 		if (reinvite)
@@ -4417,95 +4517,9 @@
 			sip_cancel_destroy(p);
 		dialogstatechange(p, DIALOG_STATE_CONFIRMED);	/* We do have any type of response */
 		p->authtries = 0;
-		if (find_sdp(req)) {
-			if ((res = process_sdp(p, req)) && !ast_test_flag(req, SIP_PKT_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 */
-					ast_set_flag(&p->flags[0], SIP_PENDINGBYE);	
-		}
-
-		/* Parse contact header for continued conversation */
-		/* When we get 200 OK, we know which device (and IP) to contact for this call */
-		/* This is important when we have a SIP proxy between us and the phone */
-		if (outgoing) {
-			update_call_counter(p, DEC_CALL_RINGING);
-			parse_ok_contact(p, req);
-			if(set_address_from_contact(p)) {
-				/* Bad contact - we don't know how to reach this device */
-				/* We need to ACK, but then send a bye */
-				/* OEJ: Possible issue that may need a check:
-					If we have a proxy route between us and the device,
-					should we care about resolving the contact
-					or should we just send it?
-				*/
-				if (!ast_test_flag(req, SIP_PKT_IGNORE))
-					ast_set_flag(&p->flags[0], SIP_PENDINGBYE);	
-			} 
-
-			/* Save Record-Route for any later requests we make on this dialogue */
-			build_route(p, req, 1);
-		}
-		
-		if (p->owner && (p->owner->_state == AST_STATE_UP) && (bridgepeer = ast_bridged_channel(p->owner))) { /* if this is a re-invite */
-			struct sip_dialog *bridgepvt = NULL;
-
-			if (!bridgepeer->tech) {
-				ast_log(LOG_WARNING, "Ooooh.. no tech!  That's REALLY bad\n");
-				break;
-			}
-			if (!strcasecmp(bridgepeer->tech->type,"SIP")) {
-				bridgepvt = (struct sip_dialog*)(bridgepeer->tech_pvt);
-				if (bridgepvt->udptl) {
-					if (p->t38.state == T38_PEER_REINVITE) {
-						sip_handle_t38_reinvite(bridgepeer, p, 0);
-					} else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) {
-						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 */
-						/* XXXX Should we really destroy this session here, without any response at all??? */
-						sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
-					}
-				} else {
-					if (option_debug > 1)
-						ast_log(LOG_DEBUG, "Strange... The other side of the bridge does not have a udptl struct\n");
-					dialog_lock(bridgepvt, TRUE);
-					bridgepvt->t38.state = T38_DISABLED;
-					dialog_lock(bridgepvt, FALSE);
-					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 */
-				if (option_debug > 1)
-					ast_log(LOG_DEBUG, "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->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->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>");
-		}
-
-		if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) {
-			if (!reinvite) {
-				ast_queue_control(p->owner, AST_CONTROL_ANSWER);
-			} else {	/* RE-invite */
-				ast_queue_frame(p->owner, &ast_null_frame);
-			}
-		} else {
-			 /* It's possible we're getting an 200 OK after we've tried to disconnect
-				  by sending CANCEL */
-			/* First send ACK, then send bye */
-			if (!ast_test_flag(req, SIP_PKT_IGNORE))
-				ast_set_flag(&p->flags[0], SIP_PENDINGBYE);	
-		}
+		/* Ok, we got an answer - let's talk */
+		handle_response_answer(p, req, outgoing, reinvite);
+
 		/* If I understand this right, the branch is different for a non-200 ACK only */
 		transmit_request(p, SIP_ACK, req->seqno, XMIT_UNRELIABLE, TRUE);
 		ast_set_flag(&p->flags[0], SIP_CAN_BYE);
@@ -5582,24 +5596,24 @@
 
 			if (p->t38.state == T38_PEER_REINVITE) {
 				struct ast_channel *bridgepeer = NULL;
-				struct sip_dialog *bridgepvt = NULL;
+				struct sip_dialog *bridge_dialog = 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 */
-						bridgepvt = (struct sip_dialog*)bridgepeer->tech_pvt;
-						if (bridgepvt->t38.state == T38_DISABLED) {
-							if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */
+						bridge_dialog = (struct sip_dialog*)bridgepeer->tech_pvt;
+						if (bridge_dialog->t38.state == T38_DISABLED) {
+							if (bridge_dialog->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");
-								dialog_lock(bridgepvt, TRUE);
-								bridgepvt->t38.state = T38_DISABLED;
-								dialog_lock(bridgepvt, FALSE);
+								dialog_lock(bridge_dialog, TRUE);
+								bridge_dialog->t38.state = T38_DISABLED;
+								dialog_lock(bridge_dialog, FALSE);
 								if (option_debug > 1)
-									ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridgepvt->t38.state, bridgepeer->name);
+									ast_log(LOG_DEBUG,"T38 state changed to %d on channel %s\n", bridge_dialog->t38.state, bridgepeer->name);
 								transmit_final_response(p, "488 Not Acceptable here", req, ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_RELIABLE);
 							}
 						} else {
@@ -5631,12 +5645,12 @@
 				/* 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_dialog *bridgepvt = NULL;
+				struct sip_dialog *bridge_dialog = NULL;
 				if ((bridgepeer = ast_bridged_channel(p->owner))) {
 					if (!strcasecmp(bridgepeer->tech->type, sip_tech.type)) {
-						bridgepvt = (struct sip_dialog*)bridgepeer->tech_pvt;
+						bridge_dialog = (struct sip_dialog*)bridgepeer->tech_pvt;
 						/* Does the bridged peer have T38 ? */
-						if (bridgepvt->t38.state == T38_ENABLED) {
+						if (bridge_dialog->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 */
 							transmit_final_response(p, "488 Not Acceptable here (unsupported)", req, ast_test_flag(req, SIP_PKT_IGNORE) ? XMIT_UNRELIABLE : XMIT_RELIABLE);



More information about the asterisk-commits mailing list