[svn-commits] oej: branch oej/codename-pineapple r46376 - in /team/oej/codename-pineapple: ...

svn-commits at lists.digium.com svn-commits at lists.digium.com
Sat Oct 28 02:49:30 MST 2006


Author: oej
Date: Sat Oct 28 04:49:29 2006
New Revision: 46376

URL: http://svn.digium.com/view/asterisk?rev=46376&view=rev
Log:
Moving around

Modified:
    team/oej/codename-pineapple/channels/chan_sip3.c
    team/oej/codename-pineapple/channels/sip3/sip3_dialog.c
    team/oej/codename-pineapple/channels/sip3/sip3_network.c
    team/oej/codename-pineapple/channels/sip3/sip3_parse.c
    team/oej/codename-pineapple/channels/sip3/sip3_sdprtp.c
    team/oej/codename-pineapple/channels/sip3/sip3funcs.h
    team/oej/codename-pineapple/configs/sip3.conf.sample

Modified: team/oej/codename-pineapple/channels/chan_sip3.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/chan_sip3.c?rev=46376&r1=46375&r2=46376&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/chan_sip3.c (original)
+++ team/oej/codename-pineapple/channels/chan_sip3.c Sat Oct 28 04:49:29 2006
@@ -378,7 +378,6 @@
 static int sip_call(struct ast_channel *ast, char *dest, int timeout);
 static int sip_hangup(struct ast_channel *ast);
 static int sip_answer(struct ast_channel *ast);
-static struct ast_frame *sip_read(struct ast_channel *ast);
 static int sip_write(struct ast_channel *ast, struct ast_frame *frame);
 static int sip_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
 static int sip_transfer(struct ast_channel *ast, const char *dest);
@@ -397,14 +396,12 @@
 static int transmit_response_with_allow(struct sip_dialog *p, const char *msg, const struct sip_request *req, enum xmittype reliable);
 static void transmit_fake_auth_response(struct sip_dialog *p, struct sip_request *req, int reliable);
 static int transmit_request(struct sip_dialog *p, int sipmethod, int inc, enum xmittype reliable, int newbranch);
-static int transmit_request_with_auth(struct sip_dialog *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch);
 static int transmit_info_with_digit(struct sip_dialog *p, const char digit);
 static int transmit_info_with_vidupdate(struct sip_dialog *p);
 static int transmit_message_with_text(struct sip_dialog *p, const char *text);
 static int transmit_refer(struct sip_dialog *p, const char *dest);
 static int transmit_notify_with_mwi(struct sip_dialog *p, int newmsgs, int oldmsgs, char *vmexten);
 static int transmit_notify_with_sipfrag(struct sip_dialog *p, int cseq, char *message, int terminate);
-static int transmit_state_notify(struct sip_dialog *p, int state, int full);
 static void copy_request(struct sip_request *dst, const struct sip_request *src);
 static void receive_message(struct sip_dialog *p, struct sip_request *req);
 static void parse_moved_contact(struct sip_dialog *p, struct sip_request *req);
@@ -414,9 +411,7 @@
 /*--- Dialog management */
 static struct sip_dialog *sip_alloc(ast_string_field callid, struct sockaddr_in *sin,
 				 int useglobal_nat, const int intended_method);
-static int __sip_autodestruct(void *data);
-static void sip_cancel_destroy(struct sip_dialog *p);
-static void sip_destroy(struct sip_dialog *p);
+GNURK void sip_destroy(struct sip_dialog *p);
 static void __sip_destroy(struct sip_dialog *p, int lockowner);
 static void __sip_ack(struct sip_dialog *p, int seqno, int resp, int sipmethod, int reset);
 static void __sip_pretend_ack(struct sip_dialog *p);
@@ -452,7 +447,6 @@
 static void *do_monitor(void *data);
 static int restart_monitor(void);
 static int sip_send_mwi_to_peer(struct sip_peer *peer);
-static void sip_destroy(struct sip_dialog *p);
 static int sip_addrcmp(char *name, struct sockaddr_in *sin);	/* Support for peer matching */
 static int sip_refer_allocate(struct sip_dialog *p);
 static void ast_quiet_chan(struct ast_channel *chan);
@@ -509,7 +503,6 @@
 static void update_peer(struct sip_peer *p, int expiry);
 
 /*--- Internal UA client handling (outbound registrations) */
-static int ast_sip_ouraddrfor(struct in_addr *them, struct in_addr *us);
 static void sip_registry_destroy(struct sip_registry *reg);
 static int sip_reregister(void *data);
 static int __sip_do_register(struct sip_registry *r);
@@ -521,8 +514,6 @@
 static int determine_firstline_parts(struct sip_request *req);
 static const char *gettag(const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize);
 static char *get_in_brackets(char *tmp);
-static const char *find_alias(const char *name, const char *_default);
-static const char *__get_header(const struct sip_request *req, const char *name, int *start);
 static void extract_uri(struct sip_dialog *p, struct sip_request *req);
 static int get_refer_info(struct sip_dialog *transferer, struct sip_request *outgoing_req);
 static int get_also_info(struct sip_dialog *p, struct sip_request *oreq);
@@ -553,9 +544,6 @@
 static int add_digit(struct sip_request *req, char digit);
 static int add_vidupdate(struct sip_request *req);
 static void add_route(struct sip_request *req, struct sip_route *route);
-static int copy_header(struct sip_request *req, const struct sip_request *orig, const char *field);
-static int copy_all_header(struct sip_request *req, const struct sip_request *orig, const char *field);
-static int copy_via_headers(struct sip_dialog *p, struct sip_request *req, const struct sip_request *orig, const char *field);
 static void set_destination(struct sip_dialog *p, char *uri);
 static void append_date(struct sip_request *req);
 static void build_contact(struct sip_dialog *p);
@@ -584,15 +572,11 @@
 static void handle_response(struct sip_dialog *p, int resp, char *rest, struct sip_request *req, int seqno);
 
 /*----- RTP interface functions */
-static struct ast_frame *sip_rtp_read(struct ast_channel *ast, struct sip_dialog *p, int *faxdetect);
 static void stop_media_flows(struct sip_dialog *p);
 
 /*------ T38 Support --------- */
 static int sip_handle_t38_reinvite(struct ast_channel *chan, struct sip_dialog *pvt, int reinvite); /*!< T38 negotiation helper function */
 static int transmit_response_with_t38_sdp(struct sip_dialog *p, char *msg, struct sip_request *req, int retrans);
-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);
-
 
 /*! \brief Definition of this channel for PBX channel registration */
 static const struct ast_channel_tech sip_tech = {
@@ -633,26 +617,6 @@
 		ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
 }
 
-/*! \brief See if we pass debug IP filter */
-GNURK inline int sip_debug_test_addr(const struct sockaddr_in *addr) 
-{
-	if (!sipdebug)
-		return 0;
-	if (sipnet.debugaddr.sin_addr.s_addr) {
-		if (((ntohs(sipnet.debugaddr.sin_port) != 0)
-			&& (sipnet.debugaddr.sin_port != addr->sin_port))
-			|| (sipnet.debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
-			return 0;
-	}
-	return 1;
-}
-
-/*! \brief The real destination address for a write */
-GNURK const struct sockaddr_in *sip_real_dst(const struct sip_dialog *p)
-{
-	return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
-}
-
 /*! \brief Test PVT for debugging output */
 inline int sip_debug_test_pvt(struct sip_dialog *p) 
 {
@@ -670,44 +634,6 @@
 	/* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
 	ast_string_field_build(p, via, "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x%s",
 			 ast_inet_ntoa(p->ourip), sipnet_ourport(), p->branch, rport);
-}
-
-/*! \brief NAT fix - decide which IP address to use for ASterisk server?
- *
- * Using the localaddr structure built up with localnet statements in sip.conf
- * apply it to their address to see if we need to substitute our
- * externip or can get away with our internal bindaddr
- */
-static enum sip_result ast_sip_ouraddrfor(struct in_addr *them, struct in_addr *us)
-{
-	struct sockaddr_in theirs, ours;
-
-	/* Get our local information */
-	ast_ouraddrfor(them, us);
-	theirs.sin_addr = *them;
-	ours.sin_addr = *us;
-
-	if (sipnet.localaddr && sipnet.externip.sin_addr.s_addr &&
-	    ast_apply_ha(sipnet.localaddr, &theirs) &&
-	    !ast_apply_ha(sipnet.localaddr, &ours)) {
-		if (sipnet.externexpire && time(NULL) >= sipnet.externexpire) {
-			struct ast_hostent ahp;
-			struct hostent *hp;
-
-			sipnet.externexpire = time(NULL) + sipnet.externrefresh;
-			if ((hp = ast_gethostbyname(sipnet.externhost, &ahp))) {
-				memcpy(&sipnet.externip.sin_addr, hp->h_addr, sizeof(sipnet.externip.sin_addr));
-			} else
-				ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", sipnet.externhost);
-		}
-		*us = sipnet.externip.sin_addr;
-		if (option_debug) {
-			ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 
-				ast_inet_ntoa(*(struct in_addr *)&them->s_addr));
-		}
-	} else if (sipnet.bindaddr.sin_addr.s_addr)
-		*us = sipnet.bindaddr.sin_addr;
-	return AST_SUCCESS;
 }
 
 GNURK void append_history_full(struct sip_dialog *p, const char *fmt, ...)
@@ -745,66 +671,6 @@
 	va_end(ap);
 
 	return;
-}
-
-/*! \brief Kill a SIP dialog (called by scheduler) */
-static int __sip_autodestruct(void *data)
-{
-	struct sip_dialog *p = data;
-
-	/* If this is a subscription, tell the phone that we got a timeout */
-	if (p->subscribed) {
-		p->subscribed = TIMEOUT;
-		transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1);	/* Send last notification */
-		p->subscribed = NONE;
-		append_history(p, "Subscribestatus", "timeout");
-		if (option_debug > 2)
-			ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>");
-		return 10000;	/* Reschedule this destruction so that we know that it's gone */
-	}
-
-	/* Reset schedule ID */
-	p->autokillid = -1;
-
-	if (option_debug)
-		ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid);
-	append_history(p, "AutoDestroy", "%s", p->callid);
-	if (p->owner) {
-		ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_method2txt(p->method));
-		ast_queue_hangup(p->owner);
-	} else if (p->refer)
-		transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
-	else 
-		sip_destroy(p);
-	return 0;
-}
-
-/*! \brief Schedule destruction of SIP dialog */
-GNURK void sip_scheddestroy(struct sip_dialog *p, int ms)
-{
-	if (ms < 0) {
-		if (p->timer_t1 == 0)
-			p->timer_t1 = 500;	/* Set timer T1 if not set (RFC 3261) */
-		ms = p->timer_t1 * 64;
-	}
-	if (sip_debug_test_pvt(p))
-		ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_method2txt(p->method));
-	if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
-		append_history(p, "SchedDestroy", "%d ms", ms);
-
-	if (p->autokillid > -1)
-		ast_sched_del(sched, p->autokillid);
-	p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p);
-}
-
-/*! \brief Cancel destruction of SIP dialog */
-static void sip_cancel_destroy(struct sip_dialog *p)
-{
-	if (p->autokillid > -1) {
-		ast_sched_del(sched, p->autokillid);
-		append_history(p, "CancelDestroy", "");
-		p->autokillid = -1;
-	}
 }
 
 /*! \brief Acknowledges receipt of a packet and stops retransmission */
@@ -1645,7 +1511,7 @@
 }
 
 /*! \brief Destroy SIP call structure */
-static void sip_destroy(struct sip_dialog *p)
+GNURK void sip_destroy(struct sip_dialog *p)
 {
 	dialoglist_lock();
 	if (option_debug > 2)
@@ -2124,6 +1990,8 @@
 	return ret;
 }
 
+/*! \brief Start sending DTMF character on SIP channel
+	within one call, we're able to transmit in many methods simultaneously */
 static int sip_senddigit_begin(struct ast_channel *ast, char digit)
 {
 	struct sip_dialog *p = ast->tech_pvt;
@@ -2434,81 +2302,6 @@
 	return tmp;
 }
 
-/*! \brief Find compressed SIP alias */
-static const char *find_alias(const char *name, const char *_default)
-{
-	/*! \brief Structure for conversion between compressed SIP and "normal" SIP */
-	static const struct cfalias {
-		char * const fullname;
-		char * const shortname;
-	} aliases[] = {
-		{ "Content-Type",	 "c" },
-		{ "Content-Encoding",	 "e" },
-		{ "From",		 "f" },
-		{ "Call-ID",		 "i" },
-		{ "Contact",		 "m" },
-		{ "Content-Length",	 "l" },
-		{ "Subject",		 "s" },
-		{ "To",			 "t" },
-		{ "Supported",		 "k" },
-		{ "Refer-To",		 "r" },
-		{ "Referred-By",	 "b" },
-		{ "Allow-Events",	 "u" },
-		{ "Event",		 "o" },
-		{ "Via",		 "v" },
-		{ "Accept-Contact",      "a" },
-		{ "Reject-Contact",      "j" },
-		{ "Request-Disposition", "d" },
-		{ "Session-Expires",     "x" },
-	};
-	int x;
-
-	for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 
-		if (!strcasecmp(aliases[x].fullname, name))
-			return aliases[x].shortname;
-
-	return _default;
-}
-
-static const char *__get_header(const struct sip_request *req, const char *name, int *start)
-{
-	int pass;
-
-	/*
-	 * Technically you can place arbitrary whitespace both before and after the ':' in
-	 * a header, although RFC3261 clearly says you shouldn't before, and place just
-	 * one afterwards.  If you shouldn't do it, what absolute idiot decided it was 
-	 * a good idea to say you can do it, and if you can do it, why in the hell would.
-	 * you say you shouldn't.
-	 */
-	for (pass = 0; name && pass < 2;pass++) {
-		int x, len = strlen(name);
-		for (x=*start; x<req->headers; x++) {
-			if (!strncasecmp(req->header[x], name, len)) {
-				char *r = req->header[x] + len;	/* skip name */
-				r = ast_skip_blanks(r);
-
-				if (*r == ':') {
-					*start = x+1;
-					return ast_skip_blanks(r+1);
-				}
-			}
-		}
-		if (pass == 0) /* Try aliases */
-			name = find_alias(name, NULL);
-	}
-
-	/* Don't return NULL, so get_header is always a valid pointer */
-	return "";
-}
-
-/*! \brief Get header from SIP request */
-GNURK const char *get_header(const struct sip_request *req, const char *name)
-{
-	int start = 0;
-	return __get_header(req, name, &start);
-}
-
 /*! \brief Generate 32 byte random string for callid's etc */
 static char *generate_random_string(char *buf, size_t size)
 {
@@ -2580,7 +2373,7 @@
 
 	if (sin) {
 		p->sa = *sin;
-		if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
+		if (sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
 			p->ourip = sipnet.__ourip;
 	} else
 		p->ourip = sipnet.__ourip;
@@ -3000,106 +2793,6 @@
 	return 0;	
 }
 
-/*! \brief Copy one header field from one request to another */
-static int copy_header(struct sip_request *req, const struct sip_request *orig, const char *field)
-{
-	const char *tmp = get_header(orig, field);
-
-	if (!ast_strlen_zero(tmp)) /* Add what we're responding to */
-		return add_header(req, field, tmp);
-	ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
-	return -1;
-}
-
-/*! \brief Copy all headers from one request to another */
-static int copy_all_header(struct sip_request *req, const struct sip_request *orig, const char *field)
-{
-	int start = 0;
-	int copied = 0;
-	int res;
-
-	for (;;) {
-		const char *tmp = __get_header(orig, field, &start);
-
-		if (ast_strlen_zero(tmp))
-			break;
-		/* Add what we're responding to */
-		res = add_header(req, field, tmp);
-		if (res != -1)
-			copied++;
-		else
-			return -1;
-		
-	}
-	return copied ? 0 : -1;
-}
-
-/*! \brief Copy SIP VIA Headers from the request to the response
-\note	If the client indicates that it wishes to know the port we received from,
-	it adds ;rport without an argument to the topmost via header. We need to
-	add the port number (from our point of view) to that parameter.
-	We always add ;received=<ip address> to the topmost via header.
-	Received: RFC 3261, rport RFC 3581 */
-static int copy_via_headers(struct sip_dialog *p, struct sip_request *req, const struct sip_request *orig, const char *field)
-{
-	int copied = 0;
-	int start = 0;
-
-	for (;;) {
-		char new[256];
-		const char *oh = __get_header(orig, field, &start);
-
-		if (ast_strlen_zero(oh))
-			break;
-
-		if (!copied) {	/* Only check for empty rport in topmost via header */
-			char *rport;
-
-			/* Find ;rport;  (empty request) */
-			rport = strstr(oh, ";rport");
-			if (rport && *(rport+6) == '=') 
-				rport = NULL;		/* We already have a parameter to rport */
-
-			if (rport && ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) {
-				/* We need to add received port - rport */
-				char tmp[256], *end;
-
-				ast_copy_string(tmp, oh, sizeof(tmp));
-
-				rport = strstr(tmp, ";rport");
-
-				if (rport) {
-					end = strchr(rport + 1, ';');
-					if (end)
-						memmove(rport, end, strlen(end) + 1);
-					else
-						*rport = '\0';
-				}
-
-				/* Add rport to first VIA header if requested */
-				/* Whoo hoo!  Now we can indicate port address translation too!  Just
-				   another RFC (RFC3581). I'll leave the original comments in for
-				   posterity.  */
-				snprintf(new, sizeof(new), "%s;received=%s;rport=%d",
-					tmp, ast_inet_ntoa(p->recv.sin_addr),
-					ntohs(p->recv.sin_port));
-			} else {
-				/* We should *always* add a received to the topmost via */
-				snprintf(new, sizeof(new), "%s;received=%s",
-					oh, ast_inet_ntoa(p->recv.sin_addr));
-			}
-			oh = new;	/* the header to copy */
-		}  /* else add the following via headers untouched */
-		add_header(req, field, oh);
-		copied++;
-	}
-	if (!copied) {
-		ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
-		return -1;
-	}
-	return 0;
-}
-
 /*! \brief Add route header into request per learned route */
 static void add_route(struct sip_request *req, struct sip_route *route)
 {
@@ -3431,7 +3124,7 @@
 
 	if (sin) {
 		p->sa = *sin;
-		if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
+		if (sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
 			p->ourip = sipnet.__ourip;
 	} else
 		p->ourip = sipnet.__ourip;
@@ -4190,7 +3883,7 @@
 }
 
 /*! \brief Used in the SUBSCRIBE notification subsystem */
-static int transmit_state_notify(struct sip_dialog *p, int state, int full)
+GNURK int transmit_state_notify(struct sip_dialog *p, int state, int full)
 {
 	char tmp[4000], from[256], to[256];
 	char *t = tmp, *c, *mfrom, *mto;
@@ -4607,7 +4300,7 @@
 		  based on whether the remote host is on the external or
 		  internal network so we can register through nat
 		 */
-		if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
+		if (sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
 			p->ourip = sipnet.bindaddr.sin_addr;
 		build_contact(p);
 	}
@@ -4822,7 +4515,7 @@
 }
 
 /*! \brief Transmit SIP request, auth added */
-static int transmit_request_with_auth(struct sip_dialog *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
+GNURK int transmit_request_with_auth(struct sip_dialog *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
 {
 	struct sip_request resp;
 
@@ -6646,7 +6339,7 @@
 			add_header(&req, var->name, var->value);
 
 		/* Recalculate our side, and recalculate Call ID */
-		if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
+		if (sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
 			p->ourip = sipnet.__ourip;
 		build_via(p);
 		build_callid_pvt(p);
@@ -9966,7 +9659,7 @@
 			return 0;
 		}
 		/* Recalculate our side, and recalculate Call ID */
-		if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
+		if (sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
 			p->ourip = sipnet.__ourip;
 		build_via(p);
 		build_callid_pvt(p);
@@ -10245,7 +9938,7 @@
 		ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr));
 
 	/* Recalculate our side, and recalculate Call ID */
-	if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
+	if (sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
 		p->ourip = sipnet.__ourip;
 	build_via(p);
 	build_callid_pvt(p);
@@ -10398,7 +10091,7 @@
 	if (ast_strlen_zero(p->peername) && ext)
 		ast_string_field_set(p, peername, ext);
 	/* Recalculate our side, and recalculate Call ID */
-	if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
+	if (sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
 		p->ourip = sipnet.__ourip;
 	build_via(p);
 	build_callid_pvt(p);

Modified: team/oej/codename-pineapple/channels/sip3/sip3_dialog.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_dialog.c?rev=46376&r1=46375&r2=46376&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_dialog.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_dialog.c Sat Oct 28 04:49:29 2006
@@ -118,3 +118,65 @@
 {
 	ast_mutex_unlock(&dialoglock);
 }
+
+
+/*! \brief Kill a SIP dialog (called by scheduler) */
+static int __sip_autodestruct(void *data)
+{
+	struct sip_dialog *p = data;
+
+	/* If this is a subscription, tell the phone that we got a timeout */
+	if (p->subscribed) {
+		p->subscribed = TIMEOUT;
+		transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1);	/* Send last notification */
+		p->subscribed = NONE;
+		append_history(p, "Subscribestatus", "timeout");
+		if (option_debug > 2)
+			ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", p->callid ? p->callid : "<unknown>");
+		return 10000;	/* Reschedule this destruction so that we know that it's gone */
+	}
+
+	/* Reset schedule ID */
+	p->autokillid = -1;
+
+	if (option_debug)
+		ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid);
+	append_history(p, "AutoDestroy", "%s", p->callid);
+	if (p->owner) {
+		ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_method2txt(p->method));
+		ast_queue_hangup(p->owner);
+	} else if (p->refer)
+		transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
+	else 
+		sip_destroy(p);
+	return 0;
+}
+
+/*! \brief Schedule destruction of SIP dialog */
+GNURK void sip_scheddestroy(struct sip_dialog *p, int ms)
+{
+	if (ms < 0) {
+		if (p->timer_t1 == 0)
+			p->timer_t1 = 500;	/* Set timer T1 if not set (RFC 3261) */
+		ms = p->timer_t1 * 64;
+	}
+	if (sip_debug_test_pvt(p))
+		ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_method2txt(p->method));
+	if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
+		append_history(p, "SchedDestroy", "%d ms", ms);
+
+	if (p->autokillid > -1)
+		ast_sched_del(sched, p->autokillid);
+	p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p);
+}
+
+/*! \brief Cancel destruction of SIP dialog */
+GNURK void sip_cancel_destroy(struct sip_dialog *p)
+{
+	if (p->autokillid > -1) {
+		ast_sched_del(sched, p->autokillid);
+		append_history(p, "CancelDestroy", "");
+		p->autokillid = -1;
+	}
+}
+

Modified: team/oej/codename-pineapple/channels/sip3/sip3_network.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_network.c?rev=46376&r1=46375&r2=46376&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_network.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_network.c Sat Oct 28 04:49:29 2006
@@ -470,3 +470,61 @@
 		__sip_xmit(p, req->data, req->len);
 	return res;
 }
+
+/*! \brief The real destination address for a write */
+const struct sockaddr_in *sip_real_dst(const struct sip_dialog *p)
+{
+	return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
+}
+
+/*! \brief See if we pass debug IP filter */
+inline int sip_debug_test_addr(const struct sockaddr_in *addr) 
+{
+	if (!sipdebug)
+		return 0;
+	if (sipnet.debugaddr.sin_addr.s_addr) {
+		if (((ntohs(sipnet.debugaddr.sin_port) != 0)
+			&& (sipnet.debugaddr.sin_port != addr->sin_port))
+			|| (sipnet.debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
+			return 0;
+	}
+	return 1;
+}
+
+/*! \brief NAT fix - decide which IP address to use for ASterisk server?
+ *
+ * Using the localaddr structure built up with localnet statements in sip.conf
+ * apply it to their address to see if we need to substitute our
+ * externip or can get away with our internal bindaddr
+ */
+enum sip_result sip_ouraddrfor(struct in_addr *them, struct in_addr *us)
+{
+	struct sockaddr_in theirs, ours;
+
+	/* Get our local information */
+	ast_ouraddrfor(them, us);
+	theirs.sin_addr = *them;
+	ours.sin_addr = *us;
+
+	if (sipnet.localaddr && sipnet.externip.sin_addr.s_addr &&
+	    ast_apply_ha(sipnet.localaddr, &theirs) &&
+	    !ast_apply_ha(sipnet.localaddr, &ours)) {
+		if (sipnet.externexpire && time(NULL) >= sipnet.externexpire) {
+			struct ast_hostent ahp;
+			struct hostent *hp;
+
+			sipnet.externexpire = time(NULL) + sipnet.externrefresh;
+			if ((hp = ast_gethostbyname(sipnet.externhost, &ahp))) {
+				memcpy(&sipnet.externip.sin_addr, hp->h_addr, sizeof(sipnet.externip.sin_addr));
+			} else
+				ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", sipnet.externhost);
+		}
+		*us = sipnet.externip.sin_addr;
+		if (option_debug) {
+			ast_log(LOG_DEBUG, "Target address %s is not local, substituting externip\n", 
+				ast_inet_ntoa(*(struct in_addr *)&them->s_addr));
+		}
+	} else if (sipnet.bindaddr.sin_addr.s_addr)
+		*us = sipnet.bindaddr.sin_addr;
+	return AST_SUCCESS;
+}

Modified: team/oej/codename-pineapple/channels/sip3/sip3_parse.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_parse.c?rev=46376&r1=46375&r2=46376&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_parse.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_parse.c Sat Oct 28 04:49:29 2006
@@ -266,4 +266,178 @@
 }
 
 
-
+/*! \brief Find compressed SIP alias */
+const char *find_alias(const char *name, const char *_default)
+{
+	/*! \brief Structure for conversion between compressed SIP and "normal" SIP */
+	static const struct cfalias {
+		char * const fullname;
+		char * const shortname;
+	} aliases[] = {
+		{ "Content-Type",	 "c" },
+		{ "Content-Encoding",	 "e" },
+		{ "From",		 "f" },
+		{ "Call-ID",		 "i" },
+		{ "Contact",		 "m" },
+		{ "Content-Length",	 "l" },
+		{ "Subject",		 "s" },
+		{ "To",			 "t" },
+		{ "Supported",		 "k" },
+		{ "Refer-To",		 "r" },
+		{ "Referred-By",	 "b" },
+		{ "Allow-Events",	 "u" },
+		{ "Event",		 "o" },
+		{ "Via",		 "v" },
+		{ "Accept-Contact",      "a" },
+		{ "Reject-Contact",      "j" },
+		{ "Request-Disposition", "d" },
+		{ "Session-Expires",     "x" },
+	};
+	int x;
+
+	for (x=0; x<sizeof(aliases) / sizeof(aliases[0]); x++) 
+		if (!strcasecmp(aliases[x].fullname, name))
+			return aliases[x].shortname;
+
+	return _default;
+}
+
+static const char *__get_header(const struct sip_request *req, const char *name, int *start)
+{
+	int pass;
+
+	/*
+	 * Technically you can place arbitrary whitespace both before and after the ':' in
+	 * a header, although RFC3261 clearly says you shouldn't before, and place just
+	 * one afterwards.  If you shouldn't do it, what absolute idiot decided it was 
+	 * a good idea to say you can do it, and if you can do it, why in the hell would.
+	 * you say you shouldn't.
+	 */
+	for (pass = 0; name && pass < 2;pass++) {
+		int x, len = strlen(name);
+		for (x=*start; x<req->headers; x++) {
+			if (!strncasecmp(req->header[x], name, len)) {
+				char *r = req->header[x] + len;	/* skip name */
+				r = ast_skip_blanks(r);
+
+				if (*r == ':') {
+					*start = x+1;
+					return ast_skip_blanks(r+1);
+				}
+			}
+		}
+		if (pass == 0) /* Try aliases */
+			name = find_alias(name, NULL);
+	}
+
+	/* Don't return NULL, so get_header is always a valid pointer */
+	return "";
+}
+
+/*! \brief Get header from SIP request */
+const char *get_header(const struct sip_request *req, const char *name)
+{
+	int start = 0;
+	return __get_header(req, name, &start);
+}
+
+/*! \brief Copy one header field from one request to another */
+int copy_header(struct sip_request *req, const struct sip_request *orig, const char *field)
+{
+	const char *tmp = get_header(orig, field);
+
+	if (!ast_strlen_zero(tmp)) /* Add what we're responding to */
+		return add_header(req, field, tmp);
+	ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
+	return -1;
+}
+
+/*! \brief Copy all headers from one request to another */
+int copy_all_header(struct sip_request *req, const struct sip_request *orig, const char *field)
+{
+	int start = 0;
+	int copied = 0;
+	int res;
+
+	for (;;) {
+		const char *tmp = __get_header(orig, field, &start);
+
+		if (ast_strlen_zero(tmp))
+			break;
+		/* Add what we're responding to */
+		res = add_header(req, field, tmp);
+		if (res != -1)
+			copied++;
+		else
+			return -1;
+		
+	}
+	return copied ? 0 : -1;
+}
+
+/*! \brief Copy SIP VIA Headers from the request to the response
+\note	If the client indicates that it wishes to know the port we received from,
+	it adds ;rport without an argument to the topmost via header. We need to
+	add the port number (from our point of view) to that parameter.
+	We always add ;received=<ip address> to the topmost via header.
+	Received: RFC 3261, rport RFC 3581 */
+int copy_via_headers(struct sip_dialog *p, struct sip_request *req, const struct sip_request *orig, const char *field)
+{
+	int copied = 0;
+	int start = 0;
+
+	for (;;) {
+		char new[256];
+		const char *oh = __get_header(orig, field, &start);
+
+		if (ast_strlen_zero(oh))
+			break;
+
+		if (!copied) {	/* Only check for empty rport in topmost via header */
+			char *rport;
+
+			/* Find ;rport;  (empty request) */
+			rport = strstr(oh, ";rport");
+			if (rport && *(rport+6) == '=') 
+				rport = NULL;		/* We already have a parameter to rport */
+
+			if (rport && ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) {
+				/* We need to add received port - rport */
+				char tmp[256], *end;
+
+				ast_copy_string(tmp, oh, sizeof(tmp));
+
+				rport = strstr(tmp, ";rport");
+
+				if (rport) {
+					end = strchr(rport + 1, ';');
+					if (end)
+						memmove(rport, end, strlen(end) + 1);
+					else
+						*rport = '\0';
+				}
+
+				/* Add rport to first VIA header if requested */
+				/* Whoo hoo!  Now we can indicate port address translation too!  Just
+				   another RFC (RFC3581). I'll leave the original comments in for
+				   posterity.  */
+				snprintf(new, sizeof(new), "%s;received=%s;rport=%d",
+					tmp, ast_inet_ntoa(p->recv.sin_addr),
+					ntohs(p->recv.sin_port));
+			} else {
+				/* We should *always* add a received to the topmost via */
+				snprintf(new, sizeof(new), "%s;received=%s",
+					oh, ast_inet_ntoa(p->recv.sin_addr));
+			}
+			oh = new;	/* the header to copy */
+		}  /* else add the following via headers untouched */
+		add_header(req, field, oh);
+		copied++;
+	}
+	if (!copied) {
+		ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
+		return -1;
+	}
+	return 0;
+}
+

Modified: team/oej/codename-pineapple/channels/sip3/sip3_sdprtp.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_sdprtp.c?rev=46376&r1=46375&r2=46376&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_sdprtp.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_sdprtp.c Sat Oct 28 04:49:29 2006
@@ -1318,7 +1318,7 @@
 }
 
 /*! \brief Read SIP RTP from channel */
-static struct ast_frame *sip_read(struct ast_channel *ast)
+GNURK struct ast_frame *sip_read(struct ast_channel *ast)
 {
 	struct ast_frame *fr;
 	struct sip_dialog *p = ast->tech_pvt;

Modified: team/oej/codename-pineapple/channels/sip3/sip3funcs.h
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3funcs.h?rev=46376&r1=46375&r2=46376&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3funcs.h (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3funcs.h Sat Oct 28 04:49:29 2006
@@ -44,7 +44,6 @@
 /*! Chan_sip3.c */
 /* XXX Should we really expose functions in chan_sip3.c ? */
 /* These needs to be resorted and moved around */
-GNURK inline int sip_debug_test_pvt(struct sip_dialog *p) ;
 GNURK void append_history_full(struct sip_dialog *p, const char *fmt, ...);
 GNURK void append_history_va(struct sip_dialog *p, const char *fmt, va_list ap);
 GNURK void sip_peer_hold(struct sip_dialog *p, int hold);
@@ -55,7 +54,6 @@
 GNURK void add_blank(struct sip_request *req);
 GNURK int lws2sws(char *msgbuf, int len);
 GNURK int handle_request(struct sip_dialog *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock);
-GNURK const char *get_header(const struct sip_request *req, const char *name);
 GNURK int add_header(struct sip_request *req, const char *var, const char *value);
 GNURK int add_header_contentLength(struct sip_request *req, int len);
 GNURK void sip_destroy_device(struct sip_peer *peer);
@@ -68,7 +66,6 @@
 GNURK inline int sip_debug_test_addr(const struct sockaddr_in *addr);
 GNURK void parse_request(struct sip_request *req);
 GNURK int transmit_response(struct sip_dialog *p, const char *msg, const struct sip_request *req);
-GNURK const struct sockaddr_in *sip_real_dst(const struct sip_dialog *p);
 GNURK void parse_copy(struct sip_request *dst, const struct sip_request *src);
 GNURK int sip_prune_realtime(int fd, int argc, char *argv[]);	/* XXX Needs to move to sip3_cliami.c */
 GNURK int sip_notify(int fd, int argc, char *argv[]); /* XXX Move where ?? */
@@ -79,7 +76,9 @@
 GNURK int transmit_register(struct sip_registry *r, int sipmethod, const char *auth, const char *authheader);
 GNURK int transmit_invite(struct sip_dialog *p, int sipmethod, int sdp, int init);
 GNURK int transmit_reinvite_with_t38_sdp(struct sip_dialog *p);
-GNURK void sip_scheddestroy(struct sip_dialog *p, int ms);
+GNURK int transmit_state_notify(struct sip_dialog *p, int state, int full);
+GNURK int transmit_request_with_auth(struct sip_dialog *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch);
+GNURK void sip_destroy(struct sip_dialog *p);
 
 /*! sip3_refer.c */
 GNURK const char *referstatus2str(enum referstatus rstatus) attribute_pure;
@@ -100,6 +99,9 @@
    they involve the transaction states  and need to handle various transports (UDP, TCP) */
 GNURK int send_response(struct sip_dialog *p, struct sip_request *req, enum xmittype reliable, int seqno);
 GNURK int send_request(struct sip_dialog *p, struct sip_request *req, enum xmittype reliable, int seqno);
+GNURK const struct sockaddr_in *sip_real_dst(const struct sip_dialog *p);
+GNURK inline int sip_debug_test_pvt(struct sip_dialog *p) ;
+GNURK int sip_ouraddrfor(struct in_addr *them, struct in_addr *us);
 
 /*! sip3_parse.c */
 GNURK char *sip_method2txt(int method);
@@ -110,6 +112,12 @@
 GNURK unsigned int parse_sip_options(struct sip_dialog *pvt, const char *supported);
 GNURK char *sip_option2text(int option);
 GNURK void sip_options_print(int options, int fd);
+GNURK const char *find_alias(const char *name, const char *_default);
+GNURK const char *get_header(const struct sip_request *req, const char *name);
+GNURK int copy_header(struct sip_request *req, const struct sip_request *orig, const char *field);
+GNURK int copy_all_header(struct sip_request *req, const struct sip_request *orig, const char *field);
+GNURK int copy_via_headers(struct sip_dialog *p, struct sip_request *req, const struct sip_request *orig, const char *field);
+GNURK const char *__get_header(const struct sip_request *req, const char *name, int *start);
 
 /*! sip3_domain.c: Domain handling functions (sip domain hosting, not DNS lookups) */
 GNURK int add_sip_domain(const char *domain, const enum domain_mode mode, const char *context);
@@ -142,6 +150,7 @@
 GNURK char *get_body(struct sip_request *req, char *name);
 GNURK int find_sdp(struct sip_request *req);
 GNURK int add_sdp(struct sip_request *resp, struct sip_dialog *p);
+GNURK struct ast_frame *sip_read(struct ast_channel *ast);
 
 /* sip3_config.c */
 GNURK void set_device_defaults(struct sip_peer *device);
@@ -176,5 +185,7 @@
 /* sip3_dialog.h */
 GNURK void dialoglist_lock(void);
 GNURK void dialoglist_unlock(void);
+GNURK void sip_scheddestroy(struct sip_dialog *p, int ms);
+GNURK void sip_cancel_destroy(struct sip_dialog *p);
 
 #endif

Modified: team/oej/codename-pineapple/configs/sip3.conf.sample
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/configs/sip3.conf.sample?rev=46376&r1=46375&r2=46376&view=diff
==============================================================================
--- team/oej/codename-pineapple/configs/sip3.conf.sample (original)
+++ team/oej/codename-pineapple/configs/sip3.conf.sample Sat Oct 28 04:49:29 2006
@@ -205,8 +205,8 @@
 ;    unless you configure a [sip_proxy] section below, and configure a
 ;    context.
 ;    Tip 1: Avoid assigning hostname to a sip.conf section like [provider.com]
-;    Tip 2: Use separate type=peer and type=user sections for SIP providers
-;           (instead of type=friend) if you have calls in both directions
+;    Tip 2: Use separate type=peer  sections for SIP providers
+;           if you have calls in both directions, one for each direction
   
 ;registertimeout=20		; retry registration calls every 20 seconds (default)
 ;registerattempts=10		; Number of registration attempts before we give up
@@ -386,67 +386,65 @@
 ; Peer auth= override all other authentication settings if we match on realm
 
 ;------------------------------------------------------------------------------
-; Users and peers have different settings available. Friends have all settings,
-; since a friend is both a peer and a user
-;
-; User config options:        Peer configuration:
-; --------------------        -------------------
-; context                     context
-; callingpres		      callingpres
-; permit                      permit
-; deny                        deny
-; secret                      secret
-; md5secret                   md5secret
-; dtmfmode                    dtmfmode
-; canreinvite                 canreinvite
-; nat                         nat
-; callgroup                   callgroup
-; pickupgroup                 pickupgroup
-; language                    language
-; allow                       allow
-; disallow                    disallow
-; insecure                    insecure
-; trustrpid                   trustrpid
-; progressinband              progressinband
-; promiscredir                promiscredir
-; useclientcode               useclientcode
-; accountcode                 accountcode
-; setvar                      setvar
-; callerid		      callerid
-; amaflags		      amaflags
-; call-limit		      call-limit
-; allowoverlap		      allowoverlap
-; allowsubscribe	      allowsubscribe
-; allowtransfer	      	      allowtransfer
-; subscribecontext	      subscribecontext
-; videosupport		      videosupport
-; maxcallbitrate	      maxcallbitrate
-; rfc2833compensate           mailbox
-;                             username
-;                             template
-;                             fromdomain
-;                             regexten
-;                             fromuser
-;                             host
-;                             port
-;                             qualify
-;                             defaultip
-;                             rtptimeout
-;                             rtpholdtimeout
-;                             sendrpid
-;                             outboundproxy
-;                             rfc2833compensate
+; The settings are available for type=device (or phone)
+
+; -------------------
+;  context
+; callingpres
+; permit
+; deny
+; secret
+; md5secret
+; dtmfmode
+; canreinvite
+; nat
+; callgroup
+; pickupgroup
+; language
+; allow
+; disallow
+; insecure
+; trustrpid
+; progressinband
+; promiscredir
+; useclientcode
+; accountcode
+; setvar
+; callerid
+; amaflags
+; call-limit
+; allowoverlap
+; allowsubscribe
+; allowtransfer
+; subscribecontext
+; videosupport
+; maxcallbitrate
+; mailbox
+; username
+; template
+; fromdomain
+; regexten
+; fromuser
+; host
+; port
+; qualify
+; defaultip
+; rtptimeout
+; rtpholdtimeout
+; sendrpid
+; outboundproxy
+; rfc2833compensate
 

[... 108 lines stripped ...]


More information about the svn-commits mailing list