[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