[asterisk-commits] oej: branch oej/midcomstuff r48023 - /team/oej/midcomstuff/channels/chan_sip.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Sun Nov 26 09:58:59 MST 2006


Author: oej
Date: Sun Nov 26 10:58:58 2006
New Revision: 48023

URL: http://svn.digium.com/view/asterisk?view=rev&rev=48023
Log:
Update

Modified:
    team/oej/midcomstuff/channels/chan_sip.c

Modified: team/oej/midcomstuff/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/midcomstuff/channels/chan_sip.c?view=diff&rev=48023&r1=48022&r2=48023
==============================================================================
--- team/oej/midcomstuff/channels/chan_sip.c (original)
+++ team/oej/midcomstuff/channels/chan_sip.c Sun Nov 26 10:58:58 2006
@@ -146,6 +146,10 @@
 #include "asterisk/localtime.h"
 #include "asterisk/abstract_jb.h"
 #include "asterisk/compiler.h"
+
+#ifdef SIP_MIDCOM
+#include "asterisk/res_netsec.h"
+#endif
 
 #ifndef FALSE
 #define FALSE    0
@@ -969,6 +973,9 @@
 	struct sip_pvt *next;			/*!< Next dialog in chain */
 	struct sip_invite_param *options;	/*!< Options for INVITE */
 	int autoframing;
+#ifdef SIP_MIDCOM
+	void *r;				/*!< ???? */
+#endif
 } *iflist = NULL;
 
 #define FLAG_RESPONSE (1 << 0)
@@ -1507,6 +1514,27 @@
 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);
 
+#ifdef SIP_MIDCOM
+/* These should move to a generic framework that you register to */
+/* All of these need documentation! */
+static void sip_rtp_get_peer_audio_helper(void *p, struct sockaddr_in *them);
+static void sip_rtp_get_peer_video_helper(void *p, struct sockaddr_in *them);
+static void sip_rtp_get_us_audio_helper(void *p, struct sockaddr_in *sin);
+static void sip_rtp_get_us_video_helper(void *p, struct sockaddr_in *vsin);
+static void sip_map_hook_struct(void *p, void *r);
+static void *sip_get_hook_struct(void *p);
+static int sip_get_flag_novideo(void *p);
+static int sip_cmp_sa_addr(void *p, struct sockaddr_in *addr);
+static void sip_get_recv_addr(void *p, struct in_addr *addr);
+static char *sip_get_username(void *p);
+static struct ast_channel *sip_channel_helper(void *p);
+static struct ast_channel *sip_bridged_channel_helper(void *p);
+static int sip_get_capability_helper(void *p);
+static void sip_softhangup_helper(void *p);
+
+extern struct ast_sip_hook_cb *m_cb;
+#endif
+
 /*! \brief Definition of this channel for PBX channel registration */
 static const struct ast_channel_tech sip_tech = {
 	.type = "SIP",
@@ -1548,12 +1576,109 @@
 	get_codec: sip_get_codec,
 };
 
+#ifdef SIP_MIDCOM
+/*! \brief  sip_helper: Interface structure with callbacks used to connect to midcom module --*/
+static struct ast_sip_helper_cb sip_helper = {
+	ast_rtp_get_peer_audio_helper: sip_rtp_get_peer_audio_helper,
+	ast_rtp_get_peer_video_helper: sip_rtp_get_peer_video_helper,
+	ast_rtp_get_us_audio_helper: sip_rtp_get_us_audio_helper,
+	ast_rtp_get_us_video_helper: sip_rtp_get_us_video_helper,
+	ast_map_hook_struct: sip_map_hook_struct,
+	ast_get_hook_struct: sip_get_hook_struct,
+	ast_get_flag_novideo: sip_get_flag_novideo,
+	ast_cmp_sa_addr: sip_cmp_sa_addr,
+	ast_get_recv_addr: sip_get_recv_addr,
+	ast_get_username: sip_get_username,
+	ast_channel_helper: sip_channel_helper,
+	ast_bridged_channel_helper: sip_bridged_channel_helper,
+	ast_get_capability_helper: sip_get_capability_helper,
+	ast_softhangup_helper: sip_softhangup_helper,
+};
+#endif
+
 /*! \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,
 };
+
+#ifdef SIP_MIDCOM
+/* All these functions needs documentation */
+static void sip_rtp_get_peer_audio_helper(void *p, struct sockaddr_in *them)
+{
+	ast_rtp_get_peer(((struct sip_pvt*)p)->rtp, them);
+}
+
+static void sip_rtp_get_peer_video_helper(void *p, struct sockaddr_in *them)
+{
+	ast_rtp_get_peer(((struct sip_pvt*)p)->vrtp, them);
+}
+
+static void sip_rtp_get_us_audio_helper(void *p, struct sockaddr_in *sin)
+{
+	ast_rtp_get_us(((struct sip_pvt*)p)->rtp, sin);
+	sin->sin_addr = ((struct sip_pvt*)p)->ourip;
+}
+
+static void sip_rtp_get_us_video_helper(void *p, struct sockaddr_in *vsin)
+{
+	ast_rtp_get_us(((struct sip_pvt*)p)->vrtp, vsin);
+	vsin->sin_addr = ((struct sip_pvt*)p)->ourip;
+}
+
+static void sip_map_hook_struct(void *p, void *r)
+{
+	((struct sip_pvt*)p)->r = r;
+}
+
+static void *sip_get_hook_struct(void *p)
+{
+	return ((struct sip_pvt*)p)->r;
+}
+
+static int sip_get_flag_novideo(void *p)
+{
+	return ast_test_flag((struct sip_pvt*)p, SIP_NOVIDEO);
+}
+
+static int sip_cmp_sa_addr(void *p, struct sockaddr_in *addr)
+{
+	return (((struct sip_pvt*)p)->sa.sin_addr.s_addr == addr->sin_addr.s_addr);
+}
+
+static void sip_get_recv_addr(void *p, struct in_addr *addr)
+{
+	memcpy(addr, &((struct sip_pvt *)p)->recv.sin_addr, sizeof(struct in_addr));
+}
+
+static char *sip_get_username(void *p)
+{
+	return ((struct sip_pvt*)p)->username;
+}
+
+static struct ast_channel *sip_channel_helper(void *p)
+{
+	return ((struct sip_pvt*)p)->owner;
+}
+
+static struct ast_channel *sip_bridged_channel_helper(void *p)
+{
+	return ast_bridged_channel(((struct sip_pvt*)p)->owner);
+}
+
+static int sip_get_capability_helper(void *p)
+{
+	return ((struct sip_pvt*)p)->jointcapability;
+}
+
+static void sip_softhangup_helper(void *p)
+{
+	if (p && ((struct sip_pvt *)p)->owner)
+		ast_softhangup(((struct sip_pvt *)p)->owner, AST_SOFTHANGUP_APPUNLOAD);
+}
+#endif
+
 
 /*! \brief Convert transfer status to string */
 static char *referstatus2str(enum referstatus rstatus)
@@ -2786,6 +2911,10 @@
 
 	if (sip_debug_test_pvt(p) || option_debug > 2)
 		ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
+#ifdef SIP_MIDCOM
+	if (m_cb)
+	  m_cb->__sip_destroy_hook(p);
+#endif
 
 	/* Remove link from peer to subscription of MWI */
 	if (p->relatedpeer && p->relatedpeer->mwipvt)
@@ -3216,6 +3345,13 @@
 		if (option_debug > 3)
 			ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state));
 	}
+
+#ifdef SIP_MIDCOM
+        /* For callee to shutdown, send "BYE" instead of "CANCEL"
+           -- this needs to be verified */
+        if (m_cb && ast_test_flag(p, SIP_OUTGOING)) 
+		needcancel = 0;
+#endif
 
 	/* Disconnect */
 	if (p->vad)
@@ -5881,8 +6017,24 @@
 
 	/* Is this a re-invite to move the media out, then use the original offer from caller  */
 	if (p->redirip.sin_addr.s_addr) {
+#ifdef SIP_MIDCOM
+		if (m_cb && p->r) {
+			struct sockaddr_in redirip_hook;
+			char iabuf2[INET_ADDRSTRLEN];
+
+			m_cb->ast_get_redirip_audio_hook(p->r, &redirip_hook);
+			if (option_debug)
+				ast_log(LOG_DEBUG, "MIDCOM: Replacing %s:%d by %s:%d in SDP before sending to %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->redirip.sin_addr), ntohs(p->redirip.sin_port), ast_inet_ntoa(iabuf2, sizeof(iabuf2), redirip_hook.sin_addr), ntohs(redirip_hook.sin_port), p->username);
+			dest.sin_port = redirip_hook.sin_port;
+			dest.sin_addr = redirip_hook.sin_addr;
+		} else {
+			dest.sin_port = p->redirip.sin_port;
+			dest.sin_addr = p->redirip.sin_addr;
+		}
+#else
 		dest.sin_port = p->redirip.sin_port;
 		dest.sin_addr = p->redirip.sin_addr;
+#endif
 		if (p->redircodecs)
 			capability = p->redircodecs;
 	} else {
@@ -5921,8 +6073,24 @@
 
 		/* Determine video destination */
 		if (p->vredirip.sin_addr.s_addr) {
+#ifdef SIP_MIDCOM
+			if (m_cb && p->r) {
+				struct sockaddr_in vredirip_hook;
+				char iabuf2[INET_ADDRSTRLEN];
+
+				m_cb->ast_get_vredirip_video_hook(p->r, &vredirip_hook);
+				if (option_debug)
+					ast_log(LOG_DEBUG, "Replacing %s:%d by %s:%d in video SDP before sending to %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->vredirip.sin_addr), ntohs(p->vredirip.sin_port), ast_inet_ntoa(iabuf2, sizeof(iabuf2), vredirip_hook.sin_addr), ntohs(vredirip_hook.sin_port), p->username);
+				vdest.sin_port = vredirip_hook.sin_port;
+				vdest.sin_addr = vredirip_hook.sin_addr;
+		  	} else {
+				vdest.sin_port = p->vredirip.sin_port;
+				vdest.sin_addr = p->vredirip.sin_addr;
+			}
+#else
+			vdest.sin_port = p->vredirip.sin_port;
 			vdest.sin_addr = p->vredirip.sin_addr;
-			vdest.sin_port = p->vredirip.sin_port;
+#endif
 		} else {
 			vdest.sin_addr = p->ourip;
 			vdest.sin_port = vsin.sin_port;
@@ -6147,6 +6315,14 @@
 		add_sdp(&resp, p);
 	} else 
 		ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
+#ifdef SIP_MIDCOM
+	if (m_cb) {
+		if (!m_cb->transmit_response_with_sdp_hook(p)) { 
+			ast_log(LOG_ERROR, "Failed transmit_response_with_sdp_hook()\n");
+			return -1;
+		}
+	}
+#endif
 	return send_response(p, &resp, reliable, seqno);
 }
 
@@ -6200,6 +6376,18 @@
 static int transmit_reinvite_with_sdp(struct sip_pvt *p)
 {
 	struct sip_request req;
+
+#ifdef SIP_MIDCOM
+	if (m_cb) {
+		if (!m_cb->transmit_reinvite_with_sdp_hook(p)) { 
+			ast_log(LOG_ERROR, "Failed transmit_reinvite_with_sdp_hook()\n");
+			if (p->owner)
+				ast_queue_hangup(p->owner);
+			else
+				ast_set_flag(p, SIP_NEEDDESTROY);
+		}
+	}
+#endif
 
 	reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
 	
@@ -11371,6 +11559,17 @@
 					/* 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);	
+			
+#ifdef SIP_MIDCOM
+			if (m_cb) {
+				if (!m_cb->handle_response_invite_hook(p)) {
+					if (p->owner)
+						ast_queue_hangup(p->owner);
+					else
+						ast_set_flag(p, SIP_NEEDDESTROY);
+				}
+			}
+#endif
 		}
 
 		/* Parse contact header for continued conversation */
@@ -12890,6 +13089,20 @@
 						sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 					return -1;
 				}
+
+#ifdef SIP_MIDCOM
+				if (m_cb) {
+					if (!m_cb->handle_request_invite_hook((void *)p)) {
+						ast_log(LOG_NOTICE, "Failed to NAT for (%s)\n", get_header(req, "From"));
+						if (ignore)
+							transmit_response(p, "403 Forbidden", req);
+						else
+							transmit_response_reliable(p, "403 Forbidden", req, 1);
+						ast_set_flag(p, SIP_NEEDDESTROY);
+						return 0;
+					}
+				}
+#endif
 			} else {
 				p->jointcapability = p->capability;
 				ast_log(LOG_DEBUG, "Hm....  No sdp for the moment\n");
@@ -16279,6 +16492,12 @@
 		ast_mutex_unlock(&p->lock);
 		return AST_RTP_GET_FAILED;
 	}
+	
+#ifdef SIP_MIDCOM
+	/*! \note XXX THis function has changed, this needs to be checked /OEJ */
+	if (m_cb)
+		m_cb->ast_rtp_nat_us_audio_hook(p->rtp, p->r); /* change the ip port in rtp */
+#endif
 
 	*rtp = p->rtp;
 
@@ -16304,6 +16523,11 @@
 		ast_mutex_unlock(&p->lock);
 		return AST_RTP_GET_FAILED;
 	}
+#ifdef SIP_MIDCOM
+	/*! \note XXX THis function has changed, this needs to be checked /OEJ */
+	if (m_cb)
+		m_cb->ast_rtp_nat_us_audio_hook(p->vrtp, p->r); /* change the ip port in rtp */
+#endif
 
 	*rtp = p->vrtp;
 
@@ -16341,12 +16565,22 @@
 
 	if (rtp) {
 		changed |= ast_rtp_get_peer(rtp, &p->redirip);
+#ifdef SIP_MIDCOM
+		/*! \note In 1.4 we return from this function in some cases, before we do this */
+		if (m_cb)
+			m_cb->ast_rtp_get_their_nat_audio_hook(rtp, p->r);
+#endif
 	} else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
 		memset(&p->redirip, 0, sizeof(p->redirip));
 		changed = 1;
 	}
 	if (vrtp) {
 		changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
+#ifdef SIP_MIDCOM
+		/*! \note In 1.4 we return from this function in some cases, before we do this */
+		if (m_cb)
+			m_cb->ast_rtp_get_their_nat_video_hook(vrtp, p->r);
+#endif
 	} else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
 		memset(&p->vredirip, 0, sizeof(p->vredirip));
 		changed = 1;
@@ -16849,6 +17083,12 @@
 	/* Tell the RTP subdriver that we're here */
 	ast_rtp_proto_register(&sip_rtp);
 
+#ifdef SIP_MIDCOM
+	/* Register the sip helper functions */
+	if (m_cb)
+		 m_cb->ast_sip_helper_register(&sip_helper);
+#endif
+
 	/* Tell the UDPTL subdriver that we're here */
 	ast_udptl_proto_register(&sip_udptl);
 
@@ -16897,6 +17137,12 @@
 	ast_rtp_proto_unregister(&sip_rtp);
 
 	ast_udptl_proto_unregister(&sip_udptl);
+
+#ifdef SIP_MIDCOM
+	/* Unregister the sip helper functions */
+	if (m_cb)
+		 m_cb->ast_sip_helper_unregister();
+#endif
 
 	ast_manager_unregister("SIPpeers");
 	ast_manager_unregister("SIPshowpeer");



More information about the asterisk-commits mailing list