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

svn-commits at lists.digium.com svn-commits at lists.digium.com
Mon Nov 6 15:56:41 MST 2006


Author: oej
Date: Mon Nov  6 16:56:40 2006
New Revision: 47237

URL: http://svn.digium.com/view/asterisk?rev=47237&view=rev
Log:
More cleanups, movements, documentation

Modified:
    team/oej/codename-pineapple/channels/chan_sip3.c
    team/oej/codename-pineapple/channels/sip3/sip3.h
    team/oej/codename-pineapple/channels/sip3/sip3_compose.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/sip3funcs.h

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=47237&r1=47236&r2=47237&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/chan_sip3.c (original)
+++ team/oej/codename-pineapple/channels/chan_sip3.c Mon Nov  6 16:56:40 2006
@@ -119,7 +119,7 @@
 	- \subpage chan_sip3_auth
 	- \subpage chan_sip3_dialogs
 	- \subpage chan_sip3_overview
-
+	- \subpage sip3_dialog_match
 	\par todo Things to do, ideas
 	- \subpage chan_sip3_todo
 	- \subpage chan_sip3_subs
@@ -467,7 +467,6 @@
 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 void receive_message(struct sip_dialog *p, struct sip_request *req);
-static void parse_moved_contact(struct sip_dialog *p, struct sip_request *req);
 static int sip_send_mwi_to_peer(struct sip_peer *peer);
 static int does_peer_need_mwi(struct sip_peer *peer);
 
@@ -506,19 +505,7 @@
 static void sip_poke_all_peers(void);
 
 /*--- Applications, functions, CLI and manager command helpers */
-//static int __sip_show_channels(int fd, int argc, char *argv[], int subscriptions);
-//static int sip_show_channels(int fd, int argc, char *argv[]);
-//static int sip_show_subscriptions(int fd, int argc, char *argv[]);
-//static int __sip_show_channels(int fd, int argc, char *argv[], int subscriptions);
-//static int sip_show_channel(int fd, int argc, char *argv[]);
-//static int sip_show_history(int fd, int argc, char *argv[]);
-//static int sip_do_debug_ip(int fd, int argc, char *argv[]);
-//static int sip_do_debug_peer(int fd, int argc, char *argv[]);
-//static int sip_do_debug(int fd, int argc, char *argv[]);
-//static int sip_no_debug(int fd, int argc, char *argv[]);
 GNURK int sip_notify(int fd, int argc, char *argv[]);
-//static int sip_do_history(int fd, int argc, char *argv[]);
-//static int sip_no_history(int fd, int argc, char *argv[]);
 static int func_header_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len);
 static int function_sippeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len);
 static int function_sipchaninfo_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len);
@@ -556,7 +543,6 @@
 static int get_msg_text(char *buf, int len, struct sip_request *req);
 
 /*--- Constructing requests and responses */
-static void initreqprep(struct sip_request *req, struct sip_dialog *p, int sipmethod);
 static int create_addr_from_peer(struct sip_dialog *r, struct sip_peer *peer);
 static int add_vidupdate(struct sip_request *req);
 static void build_rpid(struct sip_dialog *p);
@@ -2455,135 +2441,6 @@
 			       fromdomain, p->tag);
 }
 
-/*! \brief Initiate new SIP request to peer/user */
-static void initreqprep(struct sip_request *req, struct sip_dialog *p, int sipmethod)
-{
-	char invite_buf[256] = "";
-	char *invite = invite_buf;
-	size_t invite_max = sizeof(invite_buf);
-	char from[256];
-	char to[256];
-	char tmp[BUFSIZ/2];
-	char tmp2[BUFSIZ/2];
-	const char *l = NULL, *n = NULL;
-	const char *urioptions = "";
-
-	if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
-	 	const char *s = p->username;	/* being a string field, cannot be NULL */
-
-		/* Test p->username against allowed characters in AST_DIGIT_ANY
-			If it matches the allowed characters list, then sipuser = ";user=phone"
-			If not, then sipuser = ""
-		*/
-		/* + is allowed in first position in a tel: uri */
-		if (*s == '+')
-			s++;
-		for (; *s; s++) {
-			if (!strchr(AST_DIGIT_ANYNUM, *s) )
-				break;
-		}
-		/* If we have only digits, add ;user=phone to the uri */
-		if (*s)
-			urioptions = ";user=phone";
-	}
-
-
-	snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_method2txt(sipmethod));
-
-	if (p->owner) {
-		l = p->owner->cid.cid_num;
-		n = p->owner->cid.cid_name;
-	}
-	/* if we are not sending RPID and user wants his callerid restricted */
-	if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) &&
-	    ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) {
-		l = CALLERID_UNKNOWN;
-		n = l;
-	}
-	if (ast_strlen_zero(l))
-		l = global.default_callerid;
-	if (ast_strlen_zero(n))
-		n = l;
-	/* Allow user to be overridden */
-	if (!ast_strlen_zero(p->fromuser))
-		l = p->fromuser;
-	else /* Save for any further attempts */
-		ast_string_field_set(p, fromuser, l);
-
-	/* Allow user to be overridden */
-	if (!ast_strlen_zero(p->fromname))
-		n = p->fromname;
-	else /* Save for any further attempts */
-		ast_string_field_set(p, fromname, n);
-
-	ast_uri_encode(n, tmp, sizeof(tmp), 0);
-	n = tmp;
-	ast_uri_encode(l, tmp2, sizeof(tmp2), 0);
-	l = tmp2;
-
-	if ((sipnet_ourport() != STANDARD_SIP_PORT) && ast_strlen_zero(p->fromdomain))	/* Needs to be 5060 */
-		snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), sipnet_ourport(), p->tag);
-	else
-		snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag);
-
-	/* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
-	if (!ast_strlen_zero(p->fullcontact)) {
-		/* If we have full contact, trust it */
-		ast_build_string(&invite, &invite_max, "%s", p->fullcontact);
-	} else {
-		/* Otherwise, use the defaultuser while waiting for registration */
-		ast_build_string(&invite, &invite_max, "sip:");
-		if (!ast_strlen_zero(p->defaultuser)) {
-			n = p->defaultuser;
-			ast_uri_encode(n, tmp, sizeof(tmp), 0);
-			n = tmp;
-			ast_build_string(&invite, &invite_max, "%s@", n);
-		}
-		ast_build_string(&invite, &invite_max, "%s", p->tohost);
-		if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT)		/* Needs to be 5060 */
-			ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port));
-		ast_build_string(&invite, &invite_max, "%s", urioptions);
-	}
-
-	/* If custom URI options have been provided, append them */
-	if (p->options && p->options->uri_options)
-		ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
-	
-	ast_string_field_set(p, uri, invite_buf);
-
-	if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 
-		/* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
-		snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag);
-	} else if (p->options && p->options->vxml_url) {
-		/* If there is a VXML URL append it to the SIP URL */
-		snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
-	} else 
-		snprintf(to, sizeof(to), "<%s>", p->uri);
-	
-	init_req(req, sipmethod, p->uri);
-	snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_method2txt(sipmethod));
-
-	add_header(req, "Via", p->via);
-	/* SLD: FIXME?: do Route: here too?  I think not cos this is the first request.
-	 * OTOH, then we won't have anything in p->route anyway */
-	/* Build Remote Party-ID and From */
-	if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) {
-		build_rpid(p);
-		add_header(req, "From", p->rpid_from);
-	} else 
-		add_header(req, "From", from);
-	add_header(req, "To", to);
-	ast_string_field_set(p, exten, l);
-	build_contact(p);
-	add_header(req, "Contact", p->our_contact);
-	add_header(req, "Call-ID", p->callid);
-	add_header(req, "CSeq", tmp);
-	add_header(req, "User-Agent", global.useragent);
-	add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
-	if (!ast_strlen_zero(p->rpid))
-		add_header(req, "Remote-Party-ID", p->rpid);
-}
-
 /*! \brief Build REFER/INVITE/OPTIONS message and transmit it */
 GNURK int transmit_invite(struct sip_dialog *p, int sipmethod, int sdp, int init)
 {
@@ -2593,12 +2450,12 @@
 	if (init) {		/* Seems like init always is 2 */
 		/* Bump branch even on initial requests */
 		build_via(p, TRUE);
-		if (init > 1)
+		if (init > 1) /* open a new dialog */
 			initreqprep(&req, p, sipmethod);
 		else
-			reqprep(&req, p, sipmethod, 0, 1);
+			reqprep(&req, p, sipmethod, 0, TRUE);
 	} else
-		reqprep(&req, p, sipmethod, 0, 1);
+		reqprep(&req, p, sipmethod, 0, TRUE);
 		
 	if (p->options && p->options->auth)
 		add_header(&req, p->options->authheader, p->options->auth);
@@ -2765,7 +2622,7 @@
 	}
 	mto = strsep(&c, ";");	/* trim ; and beyond */
 
-	reqprep(&req, p, SIP_NOTIFY, 0, 1);
+	reqprep(&req, p, SIP_NOTIFY, 0, TRUE);
 
 	
 	add_header(&req, "Event", subscriptiontype->event);
@@ -2894,7 +2751,7 @@
 	struct sip_request req;
 	char tmp[BUFSIZ/2];
 
-	reqprep(&req, p, SIP_NOTIFY, 0, 1);
+	reqprep(&req, p, SIP_NOTIFY, 0, TRUE);
 	snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
 	add_header(&req, "Event", tmp);
 	add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
@@ -2917,7 +2774,7 @@
 {
 	struct sip_request req;
 
-	reqprep(&req, p, SIP_MESSAGE, 0, 1);
+	reqprep(&req, p, SIP_MESSAGE, 0, TRUE);
 	add_text(&req, text);
 	return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
 }
@@ -2976,7 +2833,7 @@
 	ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by));
 	p->refer->status = REFER_SENT;   /* Set refer status */
 
-	reqprep(&req, p, SIP_REFER, 0, 1);
+	reqprep(&req, p, SIP_REFER, 0, TRUE);
 	add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
 
 	add_header(&req, "Refer-To", referto);
@@ -3002,7 +2859,7 @@
 {
 	struct sip_request req;
 
-	reqprep(&req, p, SIP_INFO, 0, 1);
+	reqprep(&req, p, SIP_INFO, 0, TRUE);
 	add_digit(&req, digit);
 	return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
 }
@@ -3012,7 +2869,7 @@
 {
 	struct sip_request req;
 
-	reqprep(&req, p, SIP_INFO, 0, 1);
+	reqprep(&req, p, SIP_INFO, 0, TRUE);
 	add_vidupdate(&req);
 	return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
 }
@@ -4818,7 +4675,7 @@
 
 static struct ast_custom_function sip_header_function = {
 	.name = "SIP_HEADER",
-	.synopsis = "Gets the specified SIP header",
+	.synopsis = "Gets the specified SIP header from the INVITE",
 	.syntax = "SIP_HEADER(<name>[,<number>])",
 	.desc = "Since there are several headers (such as Via) which can occur multiple\n"
 	"times, SIP_HEADER takes an optional second argument to specify which header with\n"
@@ -4985,48 +4842,6 @@
 	"- t38passthrough        1 if T38 is offered or enabled in this channel, otherwise 0\n"
 };
 
-/*! \brief Parse 302 Moved temporalily response */
-static void parse_moved_contact(struct sip_dialog *p, struct sip_request *req)
-{
-	char tmp[256];
-	char *s, *e;
-	char *domain;
-
-	ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
-	s = get_in_brackets(tmp);
-	s = strsep(&s, ";");	/* strip ; and beyond */
-	if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
-		if (!strncasecmp(s, "sip:", 4))
-			s += 4;
-		e = strchr(s, '/');
-		if (e)
-			*e = '\0';
-		if (option_debug)
-			ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
-		if (p->owner)
-			ast_string_field_build(p->owner, call_forward, "SIP/%s", s);
-	} else {
-		e = strchr(tmp, '@');
-		if (e) {
-			*e++ = '\0';
-			domain = e;
-		} else {
-			/* No username part */
-			domain = tmp;
-		}
-		e = strchr(tmp, '/');
-		if (e)
-			*e = '\0';
-		if (!strncasecmp(s, "sip:", 4))
-			s += 4;
-		if (option_debug > 1)
-			ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
-		if (p->owner) {
-			pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
-			ast_string_field_set(p->owner, call_forward, s);
-		}
-	}
-}
 
 /*! \brief Check pending actions on SIP call */
 static void check_pendings(struct sip_dialog *p)
@@ -5231,6 +5046,17 @@
 		ast_set_flag(&p->flags[0], SIP_CAN_BYE);
 		check_pendings(p);
 		break;
+	case 300: /* Multiple Choices */
+	case 301: /* Moved permenantly */
+	case 302: /* Moved temporarily */
+	case 305: /* Use Proxy */
+		transmit_request(p, SIP_ACK, req->seqno, XMIT_UNRELIABLE, FALSE);
+		ast_set_flag(&p->flags[0], SIP_ALREADYGONE);	
+		stop_media_flows(p);	/* Stop RTP, VRTP and UDPTL */
+		parse_moved_contact(p, req);
+		if (p->owner)
+			ast_queue_control(p->owner, AST_CONTROL_BUSY);
+		break;
 	case 407: /* Proxy authentication */
 	case 401: /* Www auth */
 		/* First we ACK */
@@ -5279,12 +5105,24 @@
 		/* we have to wait a while, then retransmit */
 		/* Transmission is rescheduled, so everything should be taken care of.
 			We should support the retry-after at some point */
+		/*! \todo fix 491 pending support */
 		break;
+	case 488: /* Not acceptable here - codec error */
 	case 501: /* Not implemented */
 		transmit_request(p, SIP_ACK, req->seqno, XMIT_UNRELIABLE, FALSE);
 		dialogstatechange(p, DIALOG_STATE_TERMINATED);
 		if (p->owner)
 			ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+		break;
+	case 486: /* Busy here */
+	case 600: /* Busy everywhere */
+	case 603: /* Decline */
+		dialogstatechange(p, DIALOG_STATE_TERMINATED);
+		transmit_request(p, SIP_ACK, req->seqno, XMIT_UNRELIABLE, FALSE);
+		ast_set_flag(&p->flags[0], SIP_ALREADYGONE);	
+		stop_media_flows(p);	/* Stop RTP, VRTP and UDPTL */
+		if (p->owner)
+			ast_queue_control(p->owner, AST_CONTROL_BUSY);
 		break;
 	}
 }
@@ -5575,6 +5413,9 @@
 			if (sipmethod == SIP_REFER) {
 				handle_response_refer(p, resp, rest, req);
 				break;
+			} else if (sipmethod == SIP_INVITE) {
+				handle_response_invite(p, resp, rest, req);
+				break;
 			}
 			/* Fallthrough */
 		default:
@@ -5590,13 +5431,10 @@
 				case 301: /* Moved permenantly */
 				case 302: /* Moved temporarily */
 				case 305: /* Use Proxy */
-					parse_moved_contact(p, req);
-					/* Fall through */
 				case 486: /* Busy here */
 				case 600: /* Busy everywhere */
-				case 603: /* Decline */
-					if (p->owner)
-						ast_queue_control(p->owner, AST_CONTROL_BUSY);
+					if (sipmethod == SIP_INVITE)
+						handle_response_invite(p, resp, rest, req);
 					break;
 				case 487:	/* Response on INVITE that has been CANCELled */
 					/* channel now destroyed - dec the inUse counter */
@@ -5604,6 +5442,11 @@
 						ast_queue_hangup(p->owner);
 					update_call_counter(p, DEC_CALL_LIMIT);
 					break;
+				case 488: /* Not acceptable here - codec error */
+					if (sipmethod == SIP_INVITE) {
+						handle_response_invite(p, resp, rest, req);
+						break;
+					}
 				case 482: /*
 					\note SIP is incapable of performing a hairpin call, which
 					is yet another failure of not having a layer 2 (again, YAY
@@ -5615,7 +5458,6 @@
 						ast_string_field_build(p->owner, call_forward,
 								       "Local/%s@%s", p->peername, p->context);
 					/* Fall through */
-				case 488: /* Not acceptable here - codec error */
 				case 480: /* Temporarily Unavailable */
 				case 404: /* Not Found */
 				case 410: /* Gone */

Modified: team/oej/codename-pineapple/channels/sip3/sip3.h
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3.h?rev=47237&r1=47236&r2=47237&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3.h (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3.h Mon Nov  6 16:56:40 2006
@@ -187,7 +187,11 @@
 	TRANSFER_CLOSED,                /*!< Allow no SIP transfers */
 };
 
-
+typedef enum {
+	AST_FALSE = 0,
+	AST_TRUE = 1,
+	AST_HAVENOCLUEANDDONOTCARE = -1,
+} sip_boolean;
 
 enum sip_result {
 	AST_SUCCESS = 0,

Modified: team/oej/codename-pineapple/channels/sip3/sip3_compose.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_compose.c?rev=47237&r1=47236&r2=47237&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_compose.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_compose.c Mon Nov  6 16:56:40 2006
@@ -132,6 +132,85 @@
 	return 0;
 }
 
+/*! \brief Build the Remote Party-ID & From using callingpres options */
+static void build_rpid(struct sip_dialog *p)
+{
+	int send_pres_tags = TRUE;
+	const char *privacy=NULL;
+	const char *screen=NULL;
+	char buf[256];
+	const char *clid = global.default_callerid;
+	const char *clin = NULL;
+	const char *fromdomain;
+
+	if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from))  
+		return;
+
+	if (p->owner && p->owner->cid.cid_num)
+		clid = p->owner->cid.cid_num;
+	if (p->owner && p->owner->cid.cid_name)
+		clin = p->owner->cid.cid_name;
+	if (ast_strlen_zero(clin))
+		clin = clid;
+
+	switch (p->callingpres) {
+	case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
+		privacy = "off";
+		screen = "no";
+		break;
+	case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
+		privacy = "off";
+		screen = "pass";
+		break;
+	case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
+		privacy = "off";
+		screen = "fail";
+		break;
+	case AST_PRES_ALLOWED_NETWORK_NUMBER:
+		privacy = "off";
+		screen = "yes";
+		break;
+	case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
+		privacy = "full";
+		screen = "no";
+		break;
+	case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
+		privacy = "full";
+		screen = "pass";
+		break;
+	case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
+		privacy = "full";
+		screen = "fail";
+		break;
+	case AST_PRES_PROHIB_NETWORK_NUMBER:
+		privacy = "full";
+		screen = "pass";
+		break;
+	case AST_PRES_NUMBER_NOT_AVAILABLE:
+		send_pres_tags = FALSE;
+		break;
+	default:
+		ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres);
+		if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)
+			privacy = "full";
+		else
+			privacy = "off";
+		screen = "no";
+		break;
+	}
+	
+	fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip));
+
+	snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
+	if (send_pres_tags)
+		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen);
+	ast_string_field_set(p, rpid, buf);
+
+	ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin,
+			       S_OR(p->fromuser, clid),
+			       fromdomain, p->tag);
+}
+
 /*! \brief Prepare SIP response packet */
 int respprep(struct sip_request *resp, struct sip_dialog *p, const char *msg, const struct sip_request *req)
 {
@@ -305,6 +384,135 @@
 	p->sa.sin_port = htons(port);
 	if (debug)
 		ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port);
+}
+
+/*! \brief Initiate new SIP request to peer/user */
+void initreqprep(struct sip_request *req, struct sip_dialog *p, int sipmethod)
+{
+	char invite_buf[256] = "";
+	char *invite = invite_buf;
+	size_t invite_max = sizeof(invite_buf);
+	char from[256];
+	char to[256];
+	char tmp[BUFSIZ/2];
+	char tmp2[BUFSIZ/2];
+	const char *l = NULL, *n = NULL;
+	const char *urioptions = "";
+
+	if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
+	 	const char *s = p->username;	/* being a string field, cannot be NULL */
+
+		/* Test p->username against allowed characters in AST_DIGIT_ANY
+			If it matches the allowed characters list, then sipuser = ";user=phone"
+			If not, then sipuser = ""
+		*/
+		/* + is allowed in first position in a tel: uri */
+		if (*s == '+')
+			s++;
+		for (; *s; s++) {
+			if (!strchr(AST_DIGIT_ANYNUM, *s) )
+				break;
+		}
+		/* If we have only digits, add ;user=phone to the uri */
+		if (*s)
+			urioptions = ";user=phone";
+	}
+
+
+	snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_method2txt(sipmethod));
+
+	if (p->owner) {
+		l = p->owner->cid.cid_num;
+		n = p->owner->cid.cid_name;
+	}
+	/* if we are not sending RPID and user wants his callerid restricted */
+	if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) &&
+	    ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) {
+		l = CALLERID_UNKNOWN;
+		n = l;
+	}
+	if (ast_strlen_zero(l))
+		l = global.default_callerid;
+	if (ast_strlen_zero(n))
+		n = l;
+	/* Allow user to be overridden */
+	if (!ast_strlen_zero(p->fromuser))
+		l = p->fromuser;
+	else /* Save for any further attempts */
+		ast_string_field_set(p, fromuser, l);
+
+	/* Allow user to be overridden */
+	if (!ast_strlen_zero(p->fromname))
+		n = p->fromname;
+	else /* Save for any further attempts */
+		ast_string_field_set(p, fromname, n);
+
+	ast_uri_encode(n, tmp, sizeof(tmp), 0);
+	n = tmp;
+	ast_uri_encode(l, tmp2, sizeof(tmp2), 0);
+	l = tmp2;
+
+	if ((sipnet_ourport() != STANDARD_SIP_PORT) && ast_strlen_zero(p->fromdomain))	/* Needs to be 5060 */
+		snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), sipnet_ourport(), p->tag);
+	else
+		snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)), p->tag);
+
+	/* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
+	if (!ast_strlen_zero(p->fullcontact)) {
+		/* If we have full contact, trust it */
+		ast_build_string(&invite, &invite_max, "%s", p->fullcontact);
+	} else {
+		/* Otherwise, use the defaultuser while waiting for registration */
+		ast_build_string(&invite, &invite_max, "sip:");
+		if (!ast_strlen_zero(p->defaultuser)) {
+			n = p->defaultuser;
+			ast_uri_encode(n, tmp, sizeof(tmp), 0);
+			n = tmp;
+			ast_build_string(&invite, &invite_max, "%s@", n);
+		}
+		ast_build_string(&invite, &invite_max, "%s", p->tohost);
+		if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT)		/* Needs to be 5060 */
+			ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port));
+		ast_build_string(&invite, &invite_max, "%s", urioptions);
+	}
+
+	/* If custom URI options have been provided, append them */
+	if (p->options && p->options->uri_options)
+		ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
+	
+	ast_string_field_set(p, uri, invite_buf);
+
+	if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 
+		/* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
+		snprintf(to, sizeof(to), "<sip:%s>;tag=%s", p->uri, p->theirtag);
+	} else if (p->options && p->options->vxml_url) {
+		/* If there is a VXML URL append it to the SIP URL */
+		snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
+	} else 
+		snprintf(to, sizeof(to), "<%s>", p->uri);
+	
+	init_req(req, sipmethod, p->uri);
+	snprintf(tmp, sizeof(tmp), "%d %s", ++p->ocseq, sip_method2txt(sipmethod));
+
+	add_header(req, "Via", p->via);
+	/* SLD: FIXME?: do Route: here too?  I think not cos this is the first request.
+	 * OTOH, then we won't have anything in p->route anyway */
+	/* Build Remote Party-ID and From */
+	if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) {
+		build_rpid(p);
+		add_header(req, "From", p->rpid_from);
+	} else 
+		add_header(req, "From", from);
+	add_header(req, "To", to);
+	ast_string_field_set(p, exten, l);
+	build_contact(p);
+	add_header(req, "Contact", p->our_contact);
+	add_header(req, "Call-ID", p->callid);
+	add_header(req, "CSeq", tmp);
+	add_header(req, "User-Agent", global.useragent);
+	add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
+	if (!ast_strlen_zero(p->rpid))
+		add_header(req, "Remote-Party-ID", p->rpid);
 }
 
 

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=47237&r1=47236&r2=47237&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_dialog.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_dialog.c Mon Nov  6 16:56:40 2006
@@ -439,6 +439,9 @@
 }
 
 /*! \brief Convert SIP hangup causes to Asterisk hangup causes */
+/* \page SIP_isdn2sip Conversion from ISDN to SIP codes
+	- see function \ref hangup_sip2cause()
+*/
 int hangup_sip2cause(int cause)
 {
 	/* Possible values taken from causes.h */
@@ -520,6 +523,7 @@
 }
 
 /*! \brief Convert Asterisk hangup causes to SIP codes 
+\page SIP_isdn2sip Conversion from ISDN to SIP codes
 \verbatim
  Possible values from causes.h
         AST_CAUSE_NOTDEFINED    AST_CAUSE_NORMAL        AST_CAUSE_BUSY
@@ -550,6 +554,7 @@
    29 facility rejected                    501 Not implemented
    31 normal unspecified                   480 Temporarily unavailable
 \endverbatim
+Also see \ref SIP_sip2isdn
 */
 const char *hangup_cause2sip(int cause)
 {
@@ -807,6 +812,7 @@
 /*! \brief Connect incoming SIP message to current dialog or create new dialog structure
 	\note Called by handle_request, sipsock_read 
 
+	\page sip3_dialog_match chan_sip3:: Dialog matching and scenarios
 	\title Dialog matching
 
 	SIP can be forked, so we need to separate dialogs from each other in a 
@@ -970,6 +976,7 @@
 				For requests, we might be getting a statelessly forked call to us. 
 			*/
 			if (!ast_strlen_zero(cur->remotebranch) && strcmp(cur->remotebranch, branch)) {
+				/* XXX What do we do here ? */
 				
 			}
 		}

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=47237&r1=47236&r2=47237&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_network.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_network.c Mon Nov  6 16:56:40 2006
@@ -249,6 +249,8 @@
 	setsockopt(sipnet.sipsock, SOL_SOCKET, SO_REUSEADDR,
 				   (const char*)&reuseFlag,
 				   sizeof reuseFlag);
+	
+	ast_enable_packet_fragmentation(sipnet.sipsock);
 
 	if (bind(sipnet.sipsock, (struct sockaddr *)&sipnet.bindaddr, sizeof(sipnet.bindaddr)) < 0) {
 		ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",

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=47237&r1=47236&r2=47237&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_parse.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_parse.c Mon Nov  6 16:56:40 2006
@@ -636,3 +636,46 @@
 		ast_string_field_set(p, uri, c);
 }
 
+/*! \brief Parse 302 Moved temporalily response */
+void parse_moved_contact(struct sip_dialog *p, struct sip_request *req)
+{
+	char tmp[256];
+	char *s, *e;
+	char *domain;
+
+	ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
+	s = get_in_brackets(tmp);
+	s = strsep(&s, ";");	/* strip ; and beyond */
+	if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
+		if (!strncasecmp(s, "sip:", 4))
+			s += 4;
+		e = strchr(s, '/');
+		if (e)
+			*e = '\0';
+		if (option_debug)
+			ast_log(LOG_DEBUG, "Found promiscuous redirection to 'SIP/%s'\n", s);
+		if (p->owner)
+			ast_string_field_build(p->owner, call_forward, "SIP/%s", s);
+	} else {
+		e = strchr(tmp, '@');
+		if (e) {
+			*e++ = '\0';
+			domain = e;
+		} else {
+			/* No username part */
+			domain = tmp;
+		}
+		e = strchr(tmp, '/');
+		if (e)
+			*e = '\0';
+		if (!strncasecmp(s, "sip:", 4))
+			s += 4;
+		if (option_debug > 1)
+			ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
+		if (p->owner) {
+			pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
+			ast_string_field_set(p->owner, call_forward, s);
+		}
+	}
+}
+

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=47237&r1=47236&r2=47237&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3funcs.h (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3funcs.h Mon Nov  6 16:56:40 2006
@@ -131,6 +131,7 @@
 GNURK const char *gettag(const char *header, char *tagbuf, int tagbufsize);
 GNURK int determine_firstline_parts(struct sip_request *req);
 GNURK void extract_uri(struct sip_dialog *p, struct sip_request *req);
+GNURK void parse_moved_contact(struct sip_dialog *p, struct sip_request *req);
 
 /*! sip3_compose.c : Composing new SIP messages */
 GNURK void build_callid_pvt(struct sip_dialog *pvt);
@@ -141,6 +142,7 @@
 GNURK void add_route(struct sip_request *req, struct sip_route *route);
 GNURK int add_line(struct sip_request *req, const char *line);
 GNURK int add_header_contentLength(struct sip_request *req, int len);
+GNURK void initreqprep(struct sip_request *req, struct sip_dialog *p, int sipmethod);
 GNURK int reqprep(struct sip_request *req, struct sip_dialog *p, int sipmethod, int seqno, int newbranch);
 
 /*! sip3_domain.c: Domain handling functions (sip domain hosting, not DNS lookups) */



More information about the svn-commits mailing list