--- chan_sip.c.old	2005-03-02 18:38:27.000000000 +0100
+++ chan_sip.c	2005-09-22 09:52:57.000000000 +0200
@@ -1707,6 +1707,15 @@
 		return 0;
 	}
 	ast_mutex_lock(&p->lock);
+	/* Go ahead and free RTP port. Bugfix #3986 */
+	if (p->rtp) {
+		ast_rtp_destroy(p->rtp);
+		p->rtp = NULL;
+	}
+	if (p->vrtp) {
+		ast_rtp_destroy(p->vrtp);
+		p->vrtp = NULL;
+	}	
 #ifdef OSP_SUPPORT
 	if ((p->osphandle > -1) && (ast->_state == AST_STATE_UP)) {
 		ast_osp_terminate(p->osphandle, AST_CAUSE_NORMAL, p->ospstart, time(NULL) - p->ospstart);
@@ -2196,6 +2205,9 @@
 	/* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
 	struct ast_frame *f;
 	static struct ast_frame null_frame = { AST_FRAME_NULL, };
+	if (!p->rtp)
+		return &null_frame;
+	
 	switch(ast->fdno) {
 	case 0:
 		f = ast_rtp_read(p->rtp);	/* RTP Audio */
@@ -2266,6 +2278,28 @@
 		snprintf(callid, len, "@%s", ast_inet_ntoa(iabuf, sizeof(iabuf), ourip));
 }
 
+/*--- sip_rtp_alloc: RTP allocation ---*/
+static void sip_rtp_alloc(struct sip_pvt *p)
+{
+	if (!p)
+		return;
+	
+	p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
+	if (videosupport)
+		p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
+
+	ast_rtp_settos(p->rtp, tos);
+	if (p->vrtp)
+		ast_rtp_settos(p->vrtp, tos);
+	if (p->nat == global_nat) {
+		ast_rtp_setnat(p->rtp, (p->nat & SIP_NAT_ROUTE));
+		if (p->vrtp)
+			ast_rtp_setnat(p->vrtp, (p->nat & SIP_NAT_ROUTE));
+	}
+	if (option_debug)
+		ast_log(LOG_DEBUG, "%s allocating RTP port for %s\n", (p->rtp) ? "Success" : "Error", p->callid);
+}
+
 /*--- sip_alloc: Allocate SIP_PVT structure and set defaults ---*/
 static struct sip_pvt *sip_alloc(char *callid, struct sockaddr_in *sin, int useglobal_nat)
 {
@@ -2293,30 +2327,17 @@
 	} else {
 		memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
 	}
-	p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
-	if (videosupport)
-		p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
+
 	p->branch = rand();	
 	p->tag = rand();
 	
 	/* Start with 101 instead of 1 */
 	p->ocseq = 101;
-	if (!p->rtp) {
-		ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno));
-                ast_mutex_destroy(&p->lock);
-		free(p);
-		return NULL;
-	}
-	ast_rtp_settos(p->rtp, tos);
-	if (p->vrtp)
-		ast_rtp_settos(p->vrtp, tos);
+
 	if (useglobal_nat && sin) {
 		/* Setup NAT structure according to global settings if we have an address */
 		p->nat = global_nat;
 		memcpy(&p->recv, sin, sizeof(p->recv));
-		ast_rtp_setnat(p->rtp, (p->nat & SIP_NAT_ROUTE));
-		if (p->vrtp)
-			ast_rtp_setnat(p->vrtp, (p->nat & SIP_NAT_ROUTE));
 	}
 
 	strncpy(p->fromdomain, default_fromdomain, sizeof(p->fromdomain) - 1);
@@ -2660,7 +2681,8 @@
 		if ((sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) {
 			portno = x;
 			/* Scan through the RTP payload types specified in a "m=" line: */
-			ast_rtp_pt_clear(p->rtp);
+			if (p->rtp)
+				ast_rtp_pt_clear(p->rtp);
 			codecs = m + len;
 			while(!ast_strlen_zero(codecs)) {
 				if (sscanf(codecs, "%d%n", &codec, &len) != 1) {
@@ -2669,7 +2691,8 @@
 				}
 				if (debug)
 					ast_verbose("Found RTP audio format %d\n", codec);
-				ast_rtp_set_m_type(p->rtp, codec);
+				if (p->rtp)
+					ast_rtp_set_m_type(p->rtp, codec);
 				codecs += len;
 				/* Skip over any whitespace */
 				while(*codecs && (*codecs < 33)) codecs++;
@@ -2738,13 +2761,15 @@
 	  if (debug)
 		ast_verbose("Found description format %s\n", mimeSubtype);
 	  /* Note: should really look at the 'freq' and '#chans' params too */
-	  ast_rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype);
+	  if (p->rtp)
+			ast_rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype);
 	  if (p->vrtp)
 		  ast_rtp_set_rtpmap_type(p->vrtp, codec, "video", mimeSubtype);
 	}
 
 	/* Now gather all of the codecs that were asked for: */
-	ast_rtp_get_current_formats(p->rtp,
+	if (p->rtp)	
+		ast_rtp_get_current_formats(p->rtp,
 				&peercapability, &peernoncodeccapability);
 	if (p->vrtp)
 		ast_rtp_get_current_formats(p->vrtp,
@@ -2791,7 +2816,8 @@
 			} else {
 				ast_moh_start(p->owner->bridge, NULL);
 				if (sendonly)
-					ast_rtp_stop(p->rtp);
+					if (p->rtp)
+						ast_rtp_stop(p->rtp);
 			}
 		}
 	}
@@ -3525,7 +3551,8 @@
 		return -1;
 	}
 	respprep(&resp, p, msg, req);
-	ast_rtp_offered_from_local(p->rtp, 0);
+	if (p->rtp)
+		ast_rtp_offered_from_local(p->rtp, 0);
 	add_sdp(&resp, p);
 	return send_response(p, &resp, retrans, seqno);
 }
@@ -3605,7 +3632,8 @@
 		reqprep(&req, p, "INVITE", 0, 1);
 	
 	add_header(&req, "Allow", ALLOWED_METHODS);
-	ast_rtp_offered_from_local(p->rtp, 1);
+	if (p->rtp)
+		ast_rtp_offered_from_local(p->rtp, 1);
 	add_sdp(&req, p);
 	/* Use this as the basis */
 	copy_request(&p->initreq, &req);
@@ -3777,7 +3805,8 @@
 	}
 	add_header(&req, "Allow", ALLOWED_METHODS);
 	if (sdp) {
-		ast_rtp_offered_from_local(p->rtp, 1);
+		if (p->rtp)
+			ast_rtp_offered_from_local(p->rtp, 1);
 		add_sdp(&req, p);
 	} else {
 		add_header(&req, "Content-Length", "0");
@@ -7249,6 +7278,8 @@
 		if (!p->lastinvite)
 			p->needdestroy = 1;
 	} else if (!strcasecmp(cmd, "INVITE")) {
+		if (!p->rtp)
+			sip_rtp_alloc(p);
 		if (p->outgoing && p->owner && (p->owner->_state != AST_STATE_UP)) {
 			/* This is a call to ourself.  Send ourselves an error code and stop
 			   processing immediately, as SIP really has no good mechanism for
@@ -8160,6 +8191,11 @@
 		ast_log(LOG_WARNING, "Unable to build sip pvt data for '%s'\n", (char *)data);
 		return NULL;
 	}
+	sip_rtp_alloc(p);
+	if (!p->rtp) {
+		ast_log(LOG_WARNING, "Unable to allocate RTP port for '%s'\n", (char *)data);
+		return NULL;
+	}
 
 	strncpy(tmp, dest, sizeof(tmp) - 1);
 	host = strchr(tmp, '@');
