[asterisk-commits] kpfleming: branch kpfleming/constify r195989 - in /team/kpfleming/constify: ....

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu May 21 13:28:20 CDT 2009


Author: kpfleming
Date: Thu May 21 13:28:13 2009
New Revision: 195989

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=195989
Log:
bring completely up to date and re-enable automerge

Modified:
    team/kpfleming/constify/   (props changed)
    team/kpfleming/constify/apps/app_dial.c
    team/kpfleming/constify/apps/app_meetme.c
    team/kpfleming/constify/apps/app_stack.c
    team/kpfleming/constify/channels/chan_sip.c
    team/kpfleming/constify/configs/cdr_custom.conf.sample
    team/kpfleming/constify/configs/sip.conf.sample
    team/kpfleming/constify/include/asterisk/cdr.h
    team/kpfleming/constify/main/cdr.c
    team/kpfleming/constify/main/features.c

Propchange: team/kpfleming/constify/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/kpfleming/constify/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/kpfleming/constify/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu May 21 13:28:13 2009
@@ -1,1 +1,1 @@
-/trunk:1-195545
+/trunk:1-195988

Modified: team/kpfleming/constify/apps/app_dial.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/kpfleming/constify/apps/app_dial.c?view=diff&rev=195989&r1=195988&r2=195989
==============================================================================
--- team/kpfleming/constify/apps/app_dial.c (original)
+++ team/kpfleming/constify/apps/app_dial.c Thu May 21 13:28:13 2009
@@ -594,6 +594,7 @@
 				/* This is for the channel drivers */
 				outgoing->chan->hangupcause = AST_CAUSE_ANSWERED_ELSEWHERE;
 			}
+			ast_party_connected_line_free(&outgoing->connected);
 			ast_hangup(outgoing->chan);
 		}
 		oo = outgoing;

Modified: team/kpfleming/constify/apps/app_meetme.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/kpfleming/constify/apps/app_meetme.c?view=diff&rev=195989&r1=195988&r2=195989
==============================================================================
--- team/kpfleming/constify/apps/app_meetme.c (original)
+++ team/kpfleming/constify/apps/app_meetme.c Thu May 21 13:28:13 2009
@@ -3698,7 +3698,7 @@
 
 		empty = ast_test_flag(&confflags, CONFFLAG_EMPTY | CONFFLAG_EMPTYNOPIN);
 		empty_no_pin = ast_test_flag(&confflags, CONFFLAG_EMPTYNOPIN);
-		always_prompt = ast_test_flag(&confflags, CONFFLAG_ALWAYSPROMPT);
+		always_prompt = ast_test_flag(&confflags, CONFFLAG_ALWAYSPROMPT | CONFFLAG_DYNAMICPIN);
 	}
 
 	do {

Modified: team/kpfleming/constify/apps/app_stack.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/kpfleming/constify/apps/app_stack.c?view=diff&rev=195989&r1=195988&r2=195989
==============================================================================
--- team/kpfleming/constify/apps/app_stack.c (original)
+++ team/kpfleming/constify/apps/app_stack.c Thu May 21 13:28:13 2009
@@ -201,21 +201,20 @@
 		}
 	}
 
-	if (!ast_strlen_zero(value)) {
-		if (!found) {
-			variables = ast_var_assign(var, "");
-			AST_LIST_INSERT_HEAD(&frame->varshead, variables, entries);
-			pbx_builtin_pushvar_helper(chan, var, value);
-		} else
-			pbx_builtin_setvar_helper(chan, var, value);
-
-		manager_event(EVENT_FLAG_DIALPLAN, "VarSet", 
-			"Channel: %s\r\n"
-			"Variable: LOCAL(%s)\r\n"
-			"Value: %s\r\n"
-			"Uniqueid: %s\r\n", 
-			chan->name, var, value, chan->uniqueid);
-	}
+	if (!found) {
+		variables = ast_var_assign(var, "");
+		AST_LIST_INSERT_HEAD(&frame->varshead, variables, entries);
+		pbx_builtin_pushvar_helper(chan, var, value);
+	} else {
+		pbx_builtin_setvar_helper(chan, var, value);
+	}
+
+	manager_event(EVENT_FLAG_DIALPLAN, "VarSet",
+		"Channel: %s\r\n"
+		"Variable: LOCAL(%s)\r\n"
+		"Value: %s\r\n"
+		"Uniqueid: %s\r\n",
+		chan->name, var, value, chan->uniqueid);
 	return 0;
 }
 

Modified: team/kpfleming/constify/channels/chan_sip.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/kpfleming/constify/channels/chan_sip.c?view=diff&rev=195989&r1=195988&r2=195989
==============================================================================
--- team/kpfleming/constify/channels/chan_sip.c (original)
+++ team/kpfleming/constify/channels/chan_sip.c Thu May 21 13:28:13 2009
@@ -1423,6 +1423,7 @@
 /* realtime flags */
 #define SIP_PAGE2_RTCACHEFRIENDS	(1 << 0)	/*!< GP: Should we keep RT objects in memory for extended time? */
 #define SIP_PAGE2_RTAUTOCLEAR		(1 << 2)	/*!< GP: Should we clean memory from peers after expiry? */
+#define SIP_PAGE2_RPID_UPDATE		(1 << 3)
 /* Space for addition of other realtime flags in the future */
 #define SIP_PAGE2_STATECHANGEQUEUE	(1 << 9)	/*!< D: Unsent state pending change exists */
 
@@ -1460,7 +1461,7 @@
 	SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | \
 	SIP_PAGE2_BUGGY_MWI | SIP_PAGE2_TEXTSUPPORT | SIP_PAGE2_FAX_DETECT | \
 	SIP_PAGE2_UDPTL_DESTINATION | SIP_PAGE2_VIDEOSUPPORT_ALWAYS | SIP_PAGE2_PREFERRED_CODEC | \
-	SIP_PAGE2_RPID_IMMEDIATE)
+	SIP_PAGE2_RPID_IMMEDIATE | SIP_PAGE2_RPID_UPDATE)
 
 /*@}*/ 
 
@@ -1780,6 +1781,11 @@
 	int hangupcause;			/*!< Storage of hangupcause copied from our owner before we disconnect from the AST channel (only used at hangup) */
 
 	struct sip_subscription_mwi *mwi;       /*!< If this is a subscription MWI dialog, to which subscription */
+	/*! The SIP methods allowed on this dialog. We get this information from the Allow header present in 
+	 * the peer's REGISTER. If peer does not register with us, then we will use the first transaction we
+	 * have with this peer to determine its allowed methods.
+	 */
+	unsigned int allowed_methods;
 }; 
 
 
@@ -1966,6 +1972,7 @@
 	
 	/*XXX Seems like we suddenly have two flags with the same content. Why? To be continued... */
 	enum sip_peer_type type; /*!< Distinguish between "user" and "peer" types. This is used solely for CLI and manager commands */
+	unsigned int allowed_methods;
 };
 
 
@@ -2546,6 +2553,8 @@
 static const char *gettag(const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize);
 static int find_sip_method(const char *msg);
 static unsigned int parse_sip_options(struct sip_pvt *pvt, const char *supported);
+static unsigned int parse_allowed_methods(struct sip_request *req);
+static unsigned int set_pvt_allowed_methods(struct sip_pvt *pvt, struct sip_request *req);
 static int parse_request(struct sip_request *req);
 static const char *get_header(const struct sip_request *req, const char *name);
 static const char *referstatus2str(enum referstatus rstatus) attribute_pure;
@@ -2609,6 +2618,7 @@
 
 /*------Request handling functions */
 static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock);
+static int handle_request_update(struct sip_pvt *p, struct sip_request *req);
 static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, const char *e, int *nounlock);
 static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, int debug, int seqno, int *nounlock);
 static int handle_request_bye(struct sip_pvt *p, struct sip_request *req);
@@ -4915,6 +4925,7 @@
 	dialog->rtptimeout = peer->rtptimeout;
 	dialog->peerauth = peer->auth;
 	dialog->maxcallbitrate = peer->maxcallbitrate;
+	dialog->allowed_methods = peer->allowed_methods;
 	if (ast_strlen_zero(dialog->tohost))
 		ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr));
 	if (!ast_strlen_zero(peer->fromdomain)) {
@@ -7236,6 +7247,87 @@
 	ASTOBJ_UNREF(mwi, sip_subscribe_mwi_destroy);
 	
 	return 0;
+}
+
+static void mark_method_allowed(unsigned int *allowed_methods, enum sipmethod method)
+{
+	(*allowed_methods) |= (1 << method);
+}
+
+static void mark_method_unallowed(unsigned int *allowed_methods, enum sipmethod method)
+{
+	(*allowed_methods) &= ~(1 << method);
+}
+
+static int is_method_allowed(unsigned int *allowed_methods, enum sipmethod method)
+{
+	return ((*allowed_methods) >> method) & 1;
+}
+
+/*!
+ * \brief parse the Allow header to see what methods the endpoint we
+ * are communicating with allows.
+ *
+ * We parse the allow header on incoming Registrations and save the
+ * result to the SIP peer that is registering. When the registration
+ * expires, we clear what we know about the peer's allowed methods.
+ * When the peer re-registers, we once again parse to see if the 
+ * list of allowed methods has changed.
+ *
+ * For peers that do not register, we parse the first message we receive
+ * during a call to see what is allowed, and save the information
+ * for the duration of the call.
+ * \param req The SIP request we are parsing
+ * \retval The methods allowed
+ */
+static unsigned int parse_allowed_methods(struct sip_request *req)
+{
+	char *allow = ast_strdupa(get_header(req, "Allow"));
+	char *method;
+	unsigned int allowed_methods = SIP_UNKNOWN;
+
+	if (ast_strlen_zero(allow)) {
+		/* RFC 3261 states:
+		 *
+		 * "The absence of an Allow header field MUST NOT be
+		 * interpreted to mean that the UA sending the message supports no
+		 * methods.   Rather, it implies that the UA is not providing any
+		 * information on what methods it supports."
+		 *
+		 * For simplicity, we'll assume that the peer allows all known
+		 * SIP methods if they have no Allow header. We can then clear out the necessary
+		 * bits if the peer lets us know that we have sent an unsupported method.
+		 */
+		return UINT_MAX;
+	}
+	for (method = strsep(&allow, ","); !ast_strlen_zero(method); method = strsep(&allow, ",")) {
+		int id = find_sip_method(ast_skip_blanks(method));
+		if (id == SIP_UNKNOWN) {
+			continue;
+		}
+		mark_method_allowed(&allowed_methods, id);
+	}
+	return allowed_methods;
+}
+
+/*! A wrapper for parse_allowed_methods geared toward sip_pvts
+ *
+ * This function, in addition to setting the allowed methods for a sip_pvt
+ * also will take into account the setting of the SIP_PAGE2_RPID_UPDATE flag.
+ *
+ * \param pvt The sip_pvt we are setting the allowed_methods for
+ * \param req The request which we are parsing
+ * \retval The methods alloweded by the sip_pvt
+ */
+static unsigned int set_pvt_allowed_methods(struct sip_pvt *pvt, struct sip_request *req)
+{
+	pvt->allowed_methods = parse_allowed_methods(req);
+	
+	if (ast_test_flag(&pvt->flags[1], SIP_PAGE2_RPID_UPDATE)) {
+		mark_method_allowed(&pvt->allowed_methods, SIP_UPDATE);
+	}
+
+	return pvt->allowed_methods;
 }
 
 /*! \brief  Parse multiline SIP headers into one header
@@ -9875,8 +9967,12 @@
 			add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)");
 	}
 
+	if (ast_test_flag(&p->flags[1], SIP_SENDRPID))
+		add_rpid(&req, p);
+
 	if (p->do_history)
 		append_history(p, "ReInv", "Re-invite sent");
+
 	try_suggested_sip_codec(p);
 	if (t38version)
 		add_sdp(&req, p, oldsdp, FALSE, TRUE);
@@ -10262,7 +10358,9 @@
 
 	if (!p->initreq.headers || init > 2)
 		initialize_initreq(p, &req);
-	p->lastinvite = p->ocseq;
+	if (sipmethod == SIP_INVITE) {
+		p->lastinvite = p->ocseq;
+	}
 	return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
 }
 
@@ -10815,11 +10913,15 @@
 			p->lastinvite = p->ocseq;
 			ast_set_flag(&p->flags[0], SIP_OUTGOING);
 			send_request(p, &req, XMIT_CRITICAL, p->ocseq);
-		} else {
+		} else if (is_method_allowed(&p->allowed_methods, SIP_UPDATE)) {
 			reqprep(&req, p, SIP_UPDATE, 0, 1);
 			add_rpid(&req, p);
+			add_header(&req, "X-Asterisk-rpid-update", "Yes");
 			add_header_contentLength(&req, 0);
 			send_request(p, &req, XMIT_CRITICAL, p->ocseq);
+		} else {
+			/* We cannot send the update yet, so we have to wait until we can */
+			ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
 		}
 	} else {
 		if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPID_IMMEDIATE)) {
@@ -11424,6 +11526,7 @@
 	manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
 	register_peer_exten(peer, FALSE);	/* Remove regexten */
 	ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
+	peer->allowed_methods = SIP_UNKNOWN;
 
 	/* Do we need to release this peer from memory? 
 		Only for realtime peers and autocreated peers
@@ -12362,6 +12465,7 @@
 	}
 
 	if (peer) {
+		ao2_lock(peer);
 		if (!peer->host_dynamic) {
 			ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
 			res = AUTH_PEER_NOT_DYNAMIC;
@@ -12406,6 +12510,7 @@
 
 			} 
 		}
+		ao2_unlock(peer);
 	}
 	if (!peer && sip_cfg.autocreatepeer) {
 		/* Create peer if we have autocreate mode enabled */
@@ -12415,7 +12520,7 @@
 			if (peer->addr.sin_addr.s_addr) {
 				ao2_t_link(peers_by_ip, peer, "link peer into peers-by-ip table");
 			}
-			
+			ao2_lock(peer);
 			if (sip_cancel_destroy(p))
 				ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
 			switch (parse_register_contact(p, peer, req)) {
@@ -12438,6 +12543,7 @@
 				res = 0;
 				break;
 			}
+			ao2_unlock(peer);
 		}
 	}
 	if (!peer && sip_cfg.alwaysauthreject) {
@@ -12500,8 +12606,14 @@
 			break;
 		}
 	}
-	if (peer)
+	if (peer) {
+		ao2_lock(peer);
+		if (peer->allowed_methods == SIP_UNKNOWN) {
+			peer->allowed_methods = set_pvt_allowed_methods(p, req);
+		}
+		ao2_unlock(peer);
 		unref_peer(peer, "register_verify: unref_peer: tossing stack peer pointer at end of func");
+	}
 
 	return res;
 }
@@ -13480,6 +13592,11 @@
 	ast_string_field_set(p, mohsuggest, peer->mohsuggest);
 	ast_string_field_set(p, parkinglot, peer->parkinglot);
 	ast_string_field_set(p, engine, peer->engine);
+	if (peer->allowed_methods == SIP_UNKNOWN) {
+		set_pvt_allowed_methods(p, req);
+	} else {
+		p->allowed_methods = peer->allowed_methods;
+	}
 	if (peer->callingpres)	/* Peer calling pres setting will override RPID */
 		p->callingpres = peer->callingpres;
 	if (peer->maxms && peer->lastms)
@@ -17189,6 +17306,20 @@
 	return 0;
 }
 
+/*!
+ * \brief Handle authentication challenge for SIP UPDATE
+ *
+ * This function is only called upon the receipt of a 401/407 response to an UPDATE.
+ */
+static void handle_response_update(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
+{
+	if (p->options) {
+		p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
+	}
+	if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_UPDATE, 1)) {
+		ast_log(LOG_NOTICE, "Failed to authenticate on UPDATE to '%s'\n", get_header(&p->initreq, "From"));
+	}
+}
 
 /*! \brief Handle SIP response to INVITE dialogue */
 static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
@@ -17205,6 +17336,21 @@
 		ast_debug(4, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid);
 	else
 		ast_debug(4, "SIP response %d to standard invite\n", resp);
+
+	/* If this is a response to our initial INVITE, we need to set what we can use
+	 * for this peer.
+	 */
+	if (!reinvite && p->allowed_methods == SIP_UNKNOWN) {
+		struct sip_peer *peer = find_peer(p->peername, NULL, 1, FINDPEERS, FALSE);
+		if (!peer || peer->allowed_methods == SIP_UNKNOWN) {
+			set_pvt_allowed_methods(p, req);
+		} else {
+			p->allowed_methods = peer->allowed_methods;
+		}
+		if (peer) {
+			unref_peer(peer, "handle_response_invite: Getting supported methods from peer");
+		}
+	}
 
 	if (p->alreadygone) { /* This call is already gone */
 		ast_debug(1, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
@@ -17321,7 +17467,7 @@
 					ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
 		}
 
-		if (!req->ignore && p->owner && get_rpid(p, req)) {
+		if (!req->ignore && p->owner && (get_rpid(p, req) || !reinvite)) {
 			/* Queue a connected line update */
 			ast_party_connected_line_init(&connected);
 			connected.id.number = (char *) p->cid_num;
@@ -17352,9 +17498,6 @@
 
 		if (!req->ignore && p->owner) {
 			if (!reinvite) {
-				struct ast_party_connected_line connected;
-				ast_party_connected_line_collect_caller(&connected, &p->owner->cid);
-				ast_channel_queue_connected_line_update(p->owner, &connected);
 				ast_queue_control(p->owner, AST_CONTROL_ANSWER);
 				if (sip_cfg.callevents)
 					manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
@@ -17592,6 +17735,7 @@
 /* \brief Handle SIP response in SUBSCRIBE transaction */
 static void handle_response_subscribe(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
 {
+	struct sip_peer *peer;
 	if (!p->mwi) {
 		return;
 	}
@@ -17599,6 +17743,15 @@
 	switch (resp) {
 	case 200: /* Subscription accepted */
 		ast_debug(3, "Got 200 OK on subscription for MWI\n");
+		peer = find_peer(p->peername, NULL, 1, FINDPEERS, FALSE);
+		if (!peer || peer->allowed_methods == SIP_UNKNOWN) {
+			set_pvt_allowed_methods(p, req);
+		} else {
+			p->allowed_methods = peer->allowed_methods;
+		}
+		if (peer) {
+			unref_peer(peer, "handle_response_subscribe: Getting supported methods");
+		}
 		if (p->options) {
 			ast_free(p->options);
 			p->options = NULL;
@@ -17911,6 +18064,12 @@
 		manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
 			"ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
 			peer->name, s, pingtime);
+		if (!is_reachable) {
+			peer->allowed_methods = SIP_UNKNOWN;
+		} else {
+			set_pvt_allowed_methods(p, req);
+			peer->allowed_methods = p->allowed_methods;
+		}
 		if (is_reachable && sip_cfg.regextenonqualify)
 			register_peer_exten(peer, TRUE);
 	}
@@ -17952,6 +18111,7 @@
 	char *c_copy = ast_strdupa(c);
 	/* Skip the Cseq and its subsequent spaces */
 	const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy));
+	struct sip_peer *peer;
 
 	if (!msg)
 		msg = "";
@@ -18052,7 +18212,9 @@
 				handle_response_subscribe(p, resp, rest, req, seqno);
 			else if (p->registry && sipmethod == SIP_REGISTER)
 				res = handle_response_register(p, resp, rest, req, seqno);
-			else if (sipmethod == SIP_BYE) {
+			else if (sipmethod == SIP_UPDATE) {
+				handle_response_update(p, resp, rest, req, seqno);
+			} else if (sipmethod == SIP_BYE) {
 				if (p->options)
 					p->options->auth_type = resp;
 				if (ast_strlen_zero(p->authname)) {
@@ -18152,6 +18314,11 @@
 			}
 			break;
 		case 501: /* Not Implemented */
+			mark_method_unallowed(&p->allowed_methods, sipmethod);
+			if ((peer = find_peer(p->peername, 0, 1, FINDPEERS, FALSE))) {
+				peer->allowed_methods = p->allowed_methods;
+				unref_peer(peer, "handle_response: marking a specific method as unallowed");
+			}
 			if (sipmethod == SIP_INVITE)
 				handle_response_invite(p, resp, rest, req, seqno);
 			else if (sipmethod == SIP_REFER)
@@ -19315,6 +19482,36 @@
 }
 
 /*!
+ * \brief bare-bones support for SIP UPDATE
+ *
+ * XXX This is not even close to being RFC 3311-compliant. We don't advertise
+ * that we support the UPDATE method, so no one should ever try sending us
+ * an UPDATE anyway. However, Asterisk can send an UPDATE to change connected
+ * line information, so we need to be prepared to handle this. The way we distinguish
+ * such an UPDATE is through the X-Asterisk-rpid-update header.
+ *
+ * Actually updating the media session may be some future work.
+ */
+static int handle_request_update(struct sip_pvt *p, struct sip_request *req)
+{
+	if (ast_strlen_zero(get_header(req, "X-Asterisk-rpid-update"))) {
+		transmit_response(p, "501 Method Not Implemented", req);
+		return 0;
+	}
+	if (get_rpid(p, req)) {
+		struct ast_party_connected_line connected;
+		ast_party_connected_line_init(&connected);
+		connected.id.number = (char *) p->cid_num;
+		connected.id.name = (char *) p->cid_name;
+		connected.id.number_presentation = p->callingpres;
+		connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
+		ast_channel_queue_connected_line_update(p->owner, &connected);
+	}
+	transmit_response(p, "200 OK", req);
+	return 0;
+}
+
+/*!
  * \brief Handle incoming INVITE request
  * \note If the INVITE has a Replaces header, it is part of an
  *	attended transfer. If so, we do not go through the dial
@@ -21382,6 +21579,9 @@
 	case SIP_NOTIFY:
 		res = handle_request_notify(p, req, sin, seqno, e);
 		break;
+	case SIP_UPDATE:
+		res = handle_request_update(p, req);
+		break;
 	case SIP_ACK:
 		/* Make sure we don't ignore this */
 		if (seqno == p->pendinginvite) {
@@ -22838,6 +23038,9 @@
 		} else if (ast_true(v->value)) {
 			ast_set_flag(&flags[0], SIP_SENDRPID_RPID);
 		}
+	} else if (!strcasecmp(v->name, "rpid_update")) {
+		ast_set_flag(&mask[1], SIP_PAGE2_RPID_UPDATE);
+		ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_UPDATE);
 	} else if (!strcasecmp(v->name, "rpid_immediate")) {
 		ast_set_flag(&mask[1], SIP_PAGE2_RPID_IMMEDIATE);
 		ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RPID_IMMEDIATE);

Modified: team/kpfleming/constify/configs/cdr_custom.conf.sample
URL: http://svn.asterisk.org/svn-view/asterisk/team/kpfleming/constify/configs/cdr_custom.conf.sample?view=diff&rev=195989&r1=195988&r2=195989
==============================================================================
--- team/kpfleming/constify/configs/cdr_custom.conf.sample (original)
+++ team/kpfleming/constify/configs/cdr_custom.conf.sample Thu May 21 13:28:13 2009
@@ -2,8 +2,9 @@
 ; Mappings for custom config file
 ;
 ; To get your CSV output in a format tailored to your liking, uncomment the
-; following look for the output in the cdr-custom/Master.csv file (usually
-; in /var/log/asterisk).
+; following lines and look for the output in the cdr-custom directory (usually
+; in /var/log/asterisk).  Depending on which mapping you uncomment, you may see
+; Master.csv, Simple.csv, or both.
 ;
 ;[mappings]
 ;Master.csv => "${CDR(clid)}","${CDR(src)}","${CDR(dst)}","${CDR(dcontext)}","${CDR(channel)}","${CDR(dstchannel)}","${CDR(lastapp)}","${CDR(lastdata)}","${CDR(start)}","${CDR(answer)}","${CDR(end)}","${CDR(duration)}","${CDR(billsec)}","${CDR(disposition)}","${CDR(amaflags)}","${CDR(accountcode)}","${CDR(uniqueid)}","${CDR(userfield)}"

Modified: team/kpfleming/constify/configs/sip.conf.sample
URL: http://svn.asterisk.org/svn-view/asterisk/team/kpfleming/constify/configs/sip.conf.sample?view=diff&rev=195989&r1=195988&r2=195989
==============================================================================
--- team/kpfleming/constify/configs/sip.conf.sample (original)
+++ team/kpfleming/constify/configs/sip.conf.sample Thu May 21 13:28:13 2009
@@ -232,6 +232,13 @@
                                 ; This is identical to sendrpid=yes
 ;sendrpid = pai                 ; Use the "P-Asserted-Identity" header
                                 ; to send the identity of the remote party
+;rpid_update = no               ; In certain cases, the only method by which a connected line
+                                ; change may be immediately transmitted is with a SIP UPDATE request.
+                                ; If communicating with another Asterisk server, and you wish to be able
+                                ; transmit such UPDATE messages to it, then you must enable this option.
+                                ; Otherwise, we will have to wait until we can send a reinvite to
+                                ; transmit the information.
+
 ;progressinband=never           ; If we should generate in-band ringing always
                                 ; use 'never' to never use in-band signalling, even in cases
                                 ; where some buggy devices might not render it

Modified: team/kpfleming/constify/include/asterisk/cdr.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/kpfleming/constify/include/asterisk/cdr.h?view=diff&rev=195989&r1=195988&r2=195989
==============================================================================
--- team/kpfleming/constify/include/asterisk/cdr.h (original)
+++ team/kpfleming/constify/include/asterisk/cdr.h Thu May 21 13:28:13 2009
@@ -284,6 +284,24 @@
  */
 void ast_cdr_setapp(struct ast_cdr *cdr, const char *app, const char *data);
 
+/*!
+ * \brief Set the answer time for a call
+ * \param cdr the cdr you wish to associate with the call
+ * \param t the answer time
+ * Starts all CDR stuff necessary for doing CDR when answering a call
+ * NULL argument is just fine.
+ */
+void ast_cdr_setanswer(struct ast_cdr *cdr, struct timeval t);
+
+/*!
+ * \brief Set the disposition for a call
+ * \param cdr the cdr you wish to associate with the call
+ * \param disposition the new disposition
+ * Set the disposition on a call.
+ * NULL argument is just fine.
+ */
+void ast_cdr_setdisposition(struct ast_cdr *cdr, long int disposition);
+
 /*! 
  * \brief Convert a string to a detail record AMA flag 
  * \param flag string form of flag

Modified: team/kpfleming/constify/main/cdr.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/kpfleming/constify/main/cdr.c?view=diff&rev=195989&r1=195988&r2=195989
==============================================================================
--- team/kpfleming/constify/main/cdr.c (original)
+++ team/kpfleming/constify/main/cdr.c Thu May 21 13:28:13 2009
@@ -787,6 +787,30 @@
 	}
 }
 
+void ast_cdr_setanswer(struct ast_cdr *cdr, struct timeval t)
+{
+
+	for (; cdr; cdr = cdr->next) {
+		if (ast_test_flag(cdr, AST_CDR_FLAG_ANSLOCKED))
+			continue;
+		if (ast_test_flag(cdr, AST_CDR_FLAG_DONT_TOUCH) && ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
+			continue;
+		check_post(cdr);
+		cdr->answer = t;
+	}
+}
+
+void ast_cdr_setdisposition(struct ast_cdr *cdr, long int disposition)
+{
+
+	for (; cdr; cdr = cdr->next) {
+		if (ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
+			continue;
+		check_post(cdr);
+		cdr->disposition = disposition;
+	}
+}
+
 /* set cid info for one record */
 static void set_one_cid(struct ast_cdr *cdr, struct ast_channel *c)
 {

Modified: team/kpfleming/constify/main/features.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/kpfleming/constify/main/features.c?view=diff&rev=195989&r1=195988&r2=195989
==============================================================================
--- team/kpfleming/constify/main/features.c (original)
+++ team/kpfleming/constify/main/features.c Thu May 21 13:28:13 2009
@@ -2604,15 +2604,21 @@
 		   hears nothing but ringing while the macro does its thing. */
 		if (peer_cdr && !ast_tvzero(peer_cdr->answer)) {
 			bridge_cdr->answer = peer_cdr->answer;
-			chan_cdr->answer = peer_cdr->answer;
 			bridge_cdr->disposition = peer_cdr->disposition;
-			chan_cdr->disposition = peer_cdr->disposition;
+			if (chan_cdr) {
+				chan_cdr->answer = peer_cdr->answer;
+				chan_cdr->disposition = peer_cdr->disposition;
+			}
 		} else {
 			ast_cdr_answer(bridge_cdr);
-			ast_cdr_answer(chan_cdr); /* for the sake of cli status checks */
-		}
-		if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT)) {
-			ast_set_flag(chan_cdr, AST_CDR_FLAG_BRIDGED);
+			if (chan_cdr) {
+				ast_cdr_answer(chan_cdr); /* for the sake of cli status checks */
+			}
+		}
+		if (ast_test_flag(chan,AST_FLAG_BRIDGE_HANGUP_DONT) && (chan_cdr || peer_cdr)) {
+			if (chan_cdr) {
+				ast_set_flag(chan_cdr, AST_CDR_FLAG_BRIDGED);
+			}
 			if (peer_cdr) {
 				ast_set_flag(peer_cdr, AST_CDR_FLAG_BRIDGED);
 			}




More information about the asterisk-commits mailing list