[asterisk-commits] branch oej/siptransfer r16689 - in /team/oej/siptransfer: ./ channels/ configs/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Fri Mar 31 08:10:57 MST 2006


Author: oej
Date: Fri Mar 31 09:10:55 2006
New Revision: 16689

URL: http://svn.digium.com/view/asterisk?rev=16689&view=rev
Log:
Cleaning up, making ready for sale

Modified:
    team/oej/siptransfer/   (props changed)
    team/oej/siptransfer/channels/chan_sip.c
    team/oej/siptransfer/configs/sip.conf.sample

Propchange: team/oej/siptransfer/
------------------------------------------------------------------------------
    automerge = http://edvina.net/training/

Propchange: team/oej/siptransfer/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri Mar 31 09:10:55 2006
@@ -1,1 +1,1 @@
-/trunk:1-15095
+/trunk:1-15181

Modified: team/oej/siptransfer/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/channels/chan_sip.c?rev=16689&r1=16688&r2=16689&view=diff
==============================================================================
--- team/oej/siptransfer/channels/chan_sip.c (original)
+++ team/oej/siptransfer/channels/chan_sip.c Fri Mar 31 09:10:55 2006
@@ -167,10 +167,9 @@
 
 /*! \brief Authorization scheme for call transfers */
 enum transfermodes {
-	openforall, 		/*!< Allow all SIP transfers */
-	strict,			/*!< Allow SIP transfers from authenticated users/peers */
-	closed,			/*!< Allow no SIP transfers */
-} global_skrep;
+	TRANSFER_OPENFORALL, 		/*!< Allow all SIP transfers */
+	TRANSFER_CLOSED,		/*!< Allow no SIP transfers */
+};
 
 /* Do _NOT_ make any changes to this enum, or the array following it;
    if you think you are doing the right thing, you are probably
@@ -371,7 +370,6 @@
 #define DEFAULT_NOTIFYMIME 	"application/simple-message-summary"
 #define DEFAULT_MWITIME 	10
 #define DEFAULT_ALLOWGUEST	TRUE
-#define DEFAULT_VIDEOSUPPORT	FALSE
 #define DEFAULT_SRVLOOKUP	FALSE		/*!< Recommended setting is ON */
 #define DEFAULT_COMPACTHEADERS	FALSE
 #define DEFAULT_TOS		FALSE
@@ -382,9 +380,11 @@
 #define DEFAULT_AUTOCREATEPEER	FALSE
 #define DEFAULT_QUALIFY		FALSE
 #define DEFAULT_T1MIN		100		/*!< 100 MS for minimal roundtrip time */
+#define DEFAULT_MAX_CALL_BITRATE (384)		/*!< Max bitrate for video */
 #ifndef DEFAULT_USERAGENT
 #define DEFAULT_USERAGENT "Asterisk PBX"	/*!< Default Useragent: header unless re-defined in sip.conf */
 #endif
+
 
 /* Default setttings are used as a channel setting and as a default when
    configuring devices */
@@ -397,6 +397,7 @@
 static int default_qualify;		/*!< Default Qualify= setting */
 static char default_vmexten[AST_MAX_EXTENSION];
 static char default_musicclass[MAX_MUSICCLASS];		/*!< Global music on hold class */
+static int default_maxcallbitrate;	/*!< Maximum bitrate for call */
 static struct ast_codec_pref default_prefs;		/*!< Default codec prefs */
 
 /* Global settings only apply to the channel */
@@ -412,9 +413,10 @@
 static int global_reg_timeout;	
 static int global_regattempts_max;	/*!< Registration attempts before giving up */
 static int global_allowguest;		/*!< allow unauthenticated users/peers to connect? */
+static int global_allowsubscribe;	/*!< Flag for disabling ALL subscriptions, this is FALSE only if all peers are FALSE 
+					    the global setting is in globals_flag_page2 */
 static int global_mwitime;		/*!< Time between MWI checks for peers */
 static int global_tos;			/*!< IP Type of service */
-static int global_videosupport;		/*!< Videosupport on or off */
 static int compactheaders;		/*!< send compact sip headers */
 static int recordhistory;		/*!< Record SIP history. Off by default */
 static int dumphistory;			/*!< Dump history to verbose before destroying SIP dialog */
@@ -625,6 +627,13 @@
 #define SIP_PAGE2_DEBUG_CONSOLE 	(1 << 6)
 #define SIP_PAGE2_DYNAMIC		(1 << 7)	/*!< Dynamic Peers register with Asterisk */
 #define SIP_PAGE2_SELFDESTRUCT		(1 << 8)	/*!< Automatic peers need to destruct themselves */
+#define SIP_PAGE2_VIDEOSUPPORT		(1 << 9)
+#define SIP_PAGE2_ALLOWSUBSCRIBE	(1 << 10)	/*!< Allow subscriptions from this peer? */
+#define SIP_PAGE2_ALLOWOVERLAP		(1 << 11)	/*!< Allow overlap dialing ? */
+
+
+#define SIP_PAGE2_FLAGS_TO_COPY \
+	(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_VIDEOSUPPORT)
 
 /* SIP packet flags */
 #define SIP_PKT_DEBUG		(1 << 0)	/*!< Debug this packet */
@@ -664,20 +673,20 @@
 /*! \brief Structure to handle SIP transfers. Dynamically allocated when needed  */
 /* OEJ: Should be moved to string fields */
 struct sip_refer {
-	char refer_to[AST_MAX_EXTENSION];				/*!< Place to store REFER-TO extension */
-	char refer_to_domain[AST_MAX_EXTENSION];		/*!< Place to store REFER-TO domain */
+	char refer_to[AST_MAX_EXTENSION];		/*!< Place to store REFER-TO extension */
+	char refer_to_domain[AST_MAX_EXTENSION];	/*!< Place to store REFER-TO domain */
 	char refer_to_urioption[AST_MAX_EXTENSION];	/*!< Place to store REFER-TO uri options */
-	char refer_to_context[AST_MAX_EXTENSION];		/*!< Place to store REFER-TO context */
-	char referred_by[AST_MAX_EXTENSION];			/*!< Place to store REFERRED-BY extension */
-	char referred_by_name[AST_MAX_EXTENSION];		/*!< Place to store REFERRED-BY extension */
-	char refer_contact[AST_MAX_EXTENSION];			/*!< Place to store Contact info from a REFER extension */
-	char replaces_callid[BUFSIZ];						/*!< Replace info */
-	char replaces_callid_totag[BUFSIZ/2];			/*!< Replace info */
+	char refer_to_context[AST_MAX_EXTENSION];	/*!< Place to store REFER-TO context */
+	char referred_by[AST_MAX_EXTENSION];		/*!< Place to store REFERRED-BY extension */
+	char referred_by_name[AST_MAX_EXTENSION];	/*!< Place to store REFERRED-BY extension */
+	char refer_contact[AST_MAX_EXTENSION];		/*!< Place to store Contact info from a REFER extension */
+	char replaces_callid[BUFSIZ];			/*!< Replace info */
+	char replaces_callid_totag[BUFSIZ/2];		/*!< Replace info */
 	char replaces_callid_fromtag[BUFSIZ/2];		/*!< Replace info */
-	struct sip_pvt *refer_call;						/*!< Call we are referring */
-	int attendedtransfer;								/*!< Attended or blind transfer? */
-	int localtransfer;									/*!< Transfer to local domain? */
-	enum referstatus status;							/*!< REFER status */
+	struct sip_pvt *refer_call;			/*!< Call we are referring */
+	int attendedtransfer;				/*!< Attended or blind transfer? */
+	int localtransfer;				/*!< Transfer to local domain? */
+	enum referstatus status;			/*!< REFER status */
 };
 
 /*! \brief sip_pvt: PVT structures are used for each SIP dialog, ie. a call, a registration, a subscribe  */
@@ -693,9 +702,6 @@
 		AST_STRING_FIELD(opaque);	/*!< Opaque nonsense */
 		AST_STRING_FIELD(qop);		/*!< Quality of Protection, since SIP wasn't complicated enough yet. */
 		AST_STRING_FIELD(domain);	/*!< Authorization domain */
-		AST_STRING_FIELD(refer_to);	/*!< Place to store REFER-TO extension */
-		AST_STRING_FIELD(referred_by);	/*!< Place to store REFERRED-BY extension */
-		AST_STRING_FIELD(refer_contact);/*!< Place to store Contact info from a REFER extension */
 		AST_STRING_FIELD(from);		/*!< The From: header */
 		AST_STRING_FIELD(useragent);	/*!< User agent in SIP request */
 		AST_STRING_FIELD(exten);	/*!< Extension where to start */
@@ -731,6 +737,7 @@
 	ast_group_t pickupgroup;		/*!< Pickup group */
 	int lastinvite;				/*!< Last Cseq of invite */
 	unsigned int flags;			/*!< SIP_ flags */	
+	struct ast_flags flags_page2;		/*!< SIP PAGE2 flags */
 	int timer_t1;				/*!< SIP timer T1, ms rtt */
 	unsigned int sipoptions;		/*!< Supported SIP sipoptions on the other end */
 	int capability;				/*!< Special capability (codec) */
@@ -738,6 +745,7 @@
 	int peercapability;			/*!< Supported peer capability */
 	int prefcodec;				/*!< Preferred codec (outbound only) */
 	int noncodeccapability;
+	int maxcallbitrate;			/*!< Maximum Call Bitrate for Video Calls */	
 	int callingpres;			/*!< Calling presentation */
 	int authtries;				/*!< Times we've tried to authenticate */
 	int expiry;				/*!< How long we take to expire */
@@ -752,7 +760,6 @@
 	struct sockaddr_in recv;		/*!< Received as */
 	struct in_addr ourip;			/*!< Our IP */
 	struct ast_channel *owner;		/*!< Who owns us */
-	struct sip_pvt *refer_call;		/*!< Call we are referring */
 	struct sip_route *route;		/*!< Head of linked list of routing steps (fm Record-Route) */
 	int route_persistant;			/*!< Is this the "real" route? */
 	struct sip_auth *peerauth;		/*!< Realm authentication */
@@ -776,7 +783,7 @@
 	int rtpholdtimeout;			/*!< RTP timeout when on hold */
 	int rtpkeepalive;			/*!< Send RTP packets for keepalive */
 	enum transfermodes allowtransfer;	/*!< Allow transfer modes */
-	struct sip_refer *refer;	/*!< Refer data */
+	struct sip_refer *refer;		/*!< Refer data */
 	enum subscriptiontype subscribed;	/*!< Is this dialog a subscription?  */
 	int stateid;
 	int laststate;				/*!< Last known extension state */
@@ -841,6 +848,7 @@
 	enum transfermodes allowtransfer;   /*!< Allow transfer modes */
 	struct ast_ha *ha;		/*!< ACL setting */
 	struct ast_variable *chanvars;	/*!< Variables to set for channel created by user */
+	int maxcallbitrate;		/*!< Maximum Bitrate for a video call */
 };
 
 /*! \brief Structure for SIP peer data, we place calls to peers if registered  or fixed IP address (host) */
@@ -885,7 +893,8 @@
 	ast_group_t pickupgroup;	/*!<  Pickup group */
 	struct ast_dnsmgr_entry *dnsmgr;/*!<  DNS refresh manager for peer */
 	struct sockaddr_in addr;	/*!<  IP address of peer */
-
+	int maxcallbitrate;		/*!< Maximum Bitrate for a video call */
+	
 	/* Qualification */
 	struct sip_pvt *call;		/*!<  Call pointer */
 	int pokeexpire;			/*!<  When to expire poke (qualify= checking) */
@@ -2112,9 +2121,13 @@
 	} else {
 		return -1;
 	}
-
-	ast_copy_flags(r, peer, SIP_FLAGS_TO_COPY);
+	ast_copy_flags(&r->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
+	ast_copy_flags(&r->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
 	r->capability = peer->capability;
+	if (!ast_test_flag((&r->flags_page2), SIP_PAGE2_VIDEOSUPPORT) && r->vrtp) {
+		ast_rtp_destroy(r->vrtp);
+		r->vrtp = NULL;
+	}
 	r->prefs = peer->prefs;
 	if (r->rtp) {
 		if (option_debug)
@@ -2157,6 +2170,7 @@
 	if (!ast_strlen_zero(peer->fromuser))
 		ast_string_field_set(r, fromuser, peer->fromuser);
 	r->maxtime = peer->maxms;
+	r->allowtransfer = peer->allowtransfer;
 	r->callgroup = peer->callgroup;
 	r->pickupgroup = peer->pickupgroup;
 	/* Set timer T1 to RTT for this peer (if known by qualify=) */
@@ -2173,7 +2187,8 @@
 	r->rtpkeepalive = peer->rtpkeepalive;
 	if (peer->call_limit)
 		ast_set_flag(r, SIP_CALL_LIMIT);
-
+	r->maxcallbitrate = peer->maxcallbitrate;
+	
 	return 0;
 }
 
@@ -2299,13 +2314,13 @@
 			/* Check whether there is a variable with a name starting with SIPADDHEADER */
 			p->options->addsipheaders = 1;
 		} else if (!strcasecmp(ast_var_name(current),"SIPTRANSFER")) {
-		/* This is a transfered call */
+			/* This is a transfered call */
 			p->options->transfer = 1;
 		} else if (!strcasecmp(ast_var_name(current),"SIPTRANSFER_REFERER")) {
-		/* This is the referer */
+			/* This is the referer */
 			referer = ast_var_value(current);
 		} else if (!strcasecmp(ast_var_name(current),"SIPTRANSFER_REPLACES")) {
-		/* We're replacing a call. */
+			/* We're replacing a call. */
 			p->options->replaces = ast_var_value(current);
 		}
 		
@@ -2772,22 +2787,22 @@
 	if (option_debug && sipdebug)
 		ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid);
 
-   if (ast_test_flag(p, SIP_PAGE2_DEFER_BYE_ON_TRANSFER)) {
-      if (option_debug >3)
-         ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup.");
-      if (p->autokillid > -1)
-         sip_cancel_destroy(p);
-      sip_scheddestroy(p, 15000);
-      ast_clear_flag(p, SIP_PAGE2_DEFER_BYE_ON_TRANSFER);
-      ast_clear_flag(p, SIP_NEEDDESTROY);
-      p->owner = NULL;  /* Owner will be gone after we return, so take it away */
-      return 0;
-   }
-   if (ast_test_flag(ast, AST_FLAG_ZOMBIE)) {
-      if (p->refer && option_debug)
-         ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid);
-   } else if (option_debug)
-      ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid);
+	if (ast_test_flag(p, SIP_PAGE2_DEFER_BYE_ON_TRANSFER)) {
+		if (option_debug >3)
+			ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup.");
+		if (p->autokillid > -1)
+			sip_cancel_destroy(p);
+		sip_scheddestroy(p, 15000);
+		ast_clear_flag(p, SIP_PAGE2_DEFER_BYE_ON_TRANSFER);
+		ast_clear_flag(p, SIP_NEEDDESTROY);
+		p->owner = NULL;  /* Owner will be gone after we return, so take it away */
+		return 0;
+	}
+	if (ast_test_flag(ast, AST_FLAG_ZOMBIE)) {
+		if (p->refer && option_debug)
+         		ast_log(LOG_DEBUG, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid);
+	} else if (option_debug)
+		ast_log(LOG_DEBUG, "Hangup call %s, SIP callid %s)\n", ast->name, p->callid);
 
 	ast_mutex_lock(&p->lock);
 #ifdef OSP_SUPPORT
@@ -3108,6 +3123,7 @@
 	case AST_CONTROL_VIDUPDATE:	/* Request a video frame update */
 		if (p->vrtp && !ast_test_flag(p, SIP_NOVIDEO)) {
 			transmit_info_with_vidupdate(p);
+			/* ast_rtcp_send_h261fur(p->vrtp); */
 			res = 0;
 		} else
 			res = -1;
@@ -3489,6 +3505,9 @@
 	} else {
 		memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
 	}
+	
+	ast_copy_flags(p, &global_flags, SIP_FLAGS_TO_COPY);
+	ast_copy_flags((&p->flags_page2),(&global_flags_page2), SIP_PAGE2_FLAGS_TO_COPY);
 
 	p->branch = thread_safe_rand();	
 	make_our_tag(p->tag, sizeof(p->tag));
@@ -3497,10 +3516,10 @@
 
 	if (sip_methods[intended_method].need_rtp) {
 		p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
-		if (global_videosupport)
+		if (ast_test_flag((&p->flags_page2), SIP_PAGE2_VIDEOSUPPORT))
 			p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
-		if (!p->rtp || (global_videosupport && !p->vrtp)) {
-			ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", global_videosupport ? "and video" : "", strerror(errno));
+		if (!p->rtp || (ast_test_flag((&p->flags_page2), SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp)) {
+			ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n", ast_test_flag((&p->flags_page2), SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno));
 			ast_mutex_destroy(&p->lock);
 			if (p->chanvars) {
 				ast_variables_destroy(p->chanvars);
@@ -3515,6 +3534,7 @@
 		p->rtptimeout = global_rtptimeout;
 		p->rtpholdtimeout = global_rtpholdtimeout;
 		p->rtpkeepalive = global_rtpkeepalive;
+		p->maxcallbitrate = default_maxcallbitrate;
 	}
 
 	if (useglobal_nat && sin) {
@@ -3534,7 +3554,6 @@
 		build_callid_pvt(p);
 	else
 		ast_string_field_set(p, callid, callid);
-	ast_copy_flags(p, &global_flags, SIP_FLAGS_TO_COPY);
 	/* Assign default music on hold class */
 	ast_string_field_set(p, musicclass, default_musicclass);
 	p->allowtransfer = global_allowtransfer;
@@ -4776,6 +4795,7 @@
 	char o[256];
 	char c[256];
 	char t[256];
+	char b[256];
 	char m_audio[256];
 	char m_video[256];
 	char a_audio[1024];
@@ -4846,6 +4866,8 @@
 	snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr));
 	snprintf(s, sizeof(s), "s=session\r\n");
 	snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr));
+	if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) /* only if video response is appropriate */
+		snprintf(b, sizeof(b), "b=CT:%d\r\n", p->maxcallbitrate);	
 	snprintf(t, sizeof(t), "t=0 0\r\n");
 
 	ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
@@ -4891,7 +4913,7 @@
 	}
 
 	/* Now send any other common codecs, and non-codec formats: */
-	for (x = 1; x <= ((global_videosupport && p->vrtp) ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) {
+	for (x = 1; x <= ((ast_test_flag((&p->flags_page2), SIP_PAGE2_VIDEOSUPPORT) && p->vrtp) ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) {
 		if (!(capability & x))
 			continue;
 
@@ -4932,7 +4954,7 @@
 
 	len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m_audio) + strlen(a_audio);
 	if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) /* only if video response is appropriate */
-		len += strlen(m_video) + strlen(a_video);
+		len += strlen(m_video) + strlen(a_video) + strlen(b);
 
 	add_header(resp, "Content-Type", "application/sdp");
 	add_header_contentLength(resp, len);
@@ -4940,6 +4962,8 @@
 	add_line(resp, o);
 	add_line(resp, s);
 	add_line(resp, c);
+	if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) /* only if video response is appropriate */
+		add_line(resp, b);
 	add_line(resp, t);
 	add_line(resp, m_audio);
 	add_line(resp, a_audio);
@@ -7582,6 +7606,7 @@
 	/* Find user based on user name in the from header */
 	if (user && ast_apply_ha(user->ha, sin)) {
 		ast_copy_flags(p, user, SIP_FLAGS_TO_COPY);
+		ast_copy_flags(p, &user->flags_page2, SIP_PAGE2_FLAGS_TO_COPY);
 		/* copy channel vars */
 		for (v = user->chanvars ; v ; v = v->next) {
 			if ((tmpvar = ast_variable_new(v->name, v->value))) {
@@ -7617,6 +7642,7 @@
 		if (!(res = check_auth(p, req, user->name, user->secret, user->md5secret, sipmethod, uri, reliable, ignore))) {
 			sip_cancel_destroy(p);
 			ast_copy_flags(p, user, SIP_FLAGS_TO_COPY);
+			ast_copy_flags((&p->flags_page2),(&user->flags_page2), SIP_PAGE2_FLAGS_TO_COPY);
 			/* Copy SIP extensions profile from INVITE */
 			if (p->sipoptions)
 				user->sipoptions = p->sipoptions;
@@ -7644,12 +7670,18 @@
 			ast_string_field_set(p, accountcode, user->accountcode);
 			ast_string_field_set(p, language, user->language);
 			ast_string_field_set(p, musicclass, user->musicclass);
+			p->allowtransfer = user->allowtransfer;
 			p->amaflags = user->amaflags;
 			p->callgroup = user->callgroup;
 			p->pickupgroup = user->pickupgroup;
 			p->callingpres = user->callingpres;
 			p->capability = user->capability;
 			p->jointcapability = user->capability;
+			p->maxcallbitrate = user->maxcallbitrate;
+			if (!ast_test_flag((&p->flags_page2), SIP_PAGE2_VIDEOSUPPORT) && p->vrtp) {
+				ast_rtp_destroy(p->vrtp);
+				p->vrtp = NULL;
+			}
 			if (p->peercapability)
 				p->jointcapability &= p->peercapability;
 			if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
@@ -7769,6 +7801,11 @@
 				p->jointcapability = peer->capability;
 				if (p->peercapability)
 					p->jointcapability &= p->peercapability;
+				p->maxcallbitrate = peer->maxcallbitrate;
+				if (!ast_test_flag((&p->flags_page2), SIP_PAGE2_VIDEOSUPPORT) && p->vrtp) {
+					ast_rtp_destroy(p->vrtp);
+					p->vrtp = NULL;
+				}
 				if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_RFC2833) || (ast_test_flag(p, SIP_DTMF) == SIP_DTMF_AUTO))
 					p->noncodeccapability |= AST_RTP_DTMF;
 				else
@@ -7918,7 +7955,7 @@
 /*! \brief Convert transfer mode to text string */
 static char *transfermode2str(enum transfermodes mode)
 {
-	if (mode == openforall)
+	if (mode == TRANSFER_OPENFORALL)
 		return "open";
 	else if (mode == closed)
 		return "closed";
@@ -8157,6 +8194,7 @@
 			"IPport: %d\r\n"
 			"Dynamic: %s\r\n"
 			"Natsupport: %s\r\n"
+			"Video Support: %s\r\n"
 			"ACL: %s\r\n"
 			"Status: %s\r\n"
 			"RealtimeDevice: %s\r\n\r\n", 
@@ -8166,7 +8204,8 @@
 			ntohs(iterator->addr.sin_port), 
 			ast_test_flag((&iterator->flags_page2), SIP_PAGE2_DYNAMIC) ? "yes" : "no", 	/* Dynamic or not? */
 			(ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? "yes" : "no",	/* NAT=yes? */
-			iterator->ha ? "yes" : "no",       /* iterator/deny */
+			ast_test_flag((&iterator->flags_page2), SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no",	/* VIDEOSUPPORT=yes? */
+			iterator->ha ? "yes" : "no",       /* permit/deny */
 			status,
 			realtimepeers ? (ast_test_flag(iterator, SIP_REALTIME) ? "yes":"no") : "no");
 		}
@@ -8545,6 +8584,7 @@
 		ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
 		ast_cli(fd, "  Dynamic      : %s\n", (ast_test_flag((&peer->flags_page2), SIP_PAGE2_DYNAMIC)?"Yes":"No"));
 		ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
+		ast_cli(fd, "  MaxCallBR    : %dkbps\n", peer->maxcallbitrate);
 		ast_cli(fd, "  Expire       : %d\n", peer->expire);
 		ast_cli(fd, "  Insecure     : %s\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE)));
 		ast_cli(fd, "  Nat          : %s\n", nat2str(ast_test_flag(peer, SIP_NAT)));
@@ -8552,8 +8592,11 @@
 		ast_cli(fd, "  CanReinvite  : %s\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Yes":"No"));
 		ast_cli(fd, "  PromiscRedir : %s\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Yes":"No"));
 		ast_cli(fd, "  User=Phone   : %s\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Yes":"No"));
+		ast_cli(fd, "  Video Support: %s\n", (ast_test_flag((&peer->flags_page2), SIP_PAGE2_VIDEOSUPPORT)?"Yes":"No"));
 		ast_cli(fd, "  Trust RPID   : %s\n", (ast_test_flag(peer, SIP_TRUSTRPID) ? "Yes" : "No"));
 		ast_cli(fd, "  Send RPID    : %s\n", (ast_test_flag(peer, SIP_SENDRPID) ? "Yes" : "No"));
+		ast_cli(fd, "  Subscriptions: %s\n", ast_test_flag(&peer->flags_page2, SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
+		ast_cli(fd, "  Overlap dial : %s\n", ast_test_flag(&peer->flags_page2, SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
 
 		/* - is enumerated */
 		ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF)));
@@ -8621,6 +8664,7 @@
 		astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox);
 		astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
 		astman_append(s, "Call limit: %d\r\n", peer->call_limit);
+		astman_append(s, "MaxCallBR: %dkbps\r\n", peer->maxcallbitrate);
 		astman_append(s, "Dynamic: %s\r\n", (ast_test_flag((&peer->flags_page2), SIP_PAGE2_DYNAMIC)?"Y":"N"));
 		astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
 		astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire));
@@ -8630,6 +8674,7 @@
 		astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(peer, SIP_CAN_REINVITE)?"Y":"N"));
 		astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(peer, SIP_PROMISCREDIR)?"Y":"N"));
 		astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(peer, SIP_USEREQPHONE)?"Y":"N"));
+		astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag((&peer->flags_page2), SIP_PAGE2_VIDEOSUPPORT)?"Y":"N"));
 
 		/* - is enumerated */
 		astman_append(s, "SIP-DTMFmode %s\r\n", dtmfmode2str(ast_test_flag(peer, SIP_DTMF)));
@@ -8779,9 +8824,11 @@
 	ast_cli(fd, "----------------\n");
 	ast_cli(fd, "  SIP Port:               %d\n", ntohs(bindaddr.sin_port));
 	ast_cli(fd, "  Bindaddress:            %s\n", ast_inet_ntoa(tmp, sizeof(tmp), bindaddr.sin_addr));
-	ast_cli(fd, "  Videosupport:           %s\n", global_videosupport ? "Yes" : "No");
+	ast_cli(fd, "  Videosupport:           %s\n", ast_test_flag((&global_flags_page2), SIP_PAGE2_VIDEOSUPPORT) ? "Yes" : "No");
 	ast_cli(fd, "  AutoCreatePeer:         %s\n", autocreatepeer ? "Yes" : "No");
 	ast_cli(fd, "  Allow unknown access:   %s\n", global_allowguest ? "Yes" : "No");
+	ast_cli(fd, "  Allow subscriptions:    %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
+	ast_cli(fd, "  Allow overlap dialing:  %s\n", ast_test_flag(&global_flags_page2, SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
 	ast_cli(fd, "  Promsic. redir:         %s\n", ast_test_flag(&global_flags, SIP_PROMISCREDIR) ? "Yes" : "No");
 	ast_cli(fd, "  SIP domain support:     %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes");
 	ast_cli(fd, "  Call to non-local dom.: %s\n", allow_external_domains ? "Yes" : "No");
@@ -8826,6 +8873,7 @@
 	ast_cli(fd, "  Outbound reg. attempts: %d\n", global_regattempts_max);
 	ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(global_allowtransfer));
 	ast_cli(fd, "  Notify ringing state:   %s\n", global_notifyringing ? "Yes" : "No");
+	ast_cli(fd, "  Max Call Bitrate:       %dkbps\r\n", default_maxcallbitrate);
 	ast_cli(fd, "\nDefault Settings:\n");
 	ast_cli(fd, "-----------------\n");
 	ast_cli(fd, "  Context:                %s\n", default_context);
@@ -11003,8 +11051,6 @@
 		ast_string_field_set(p, context, default_context);
 	if (res < 0)
 		transmit_response_with_allow(p, "404 Not Found", req, 0);
-	else if (res > 0)
-		transmit_response_with_allow(p, "484 Address Incomplete", req, 0);
 	else 
 		transmit_response_with_allow(p, "200 OK", req, 0);
 	/* Destroy if this OPTIONS was the opening request, but not if
@@ -11195,20 +11241,16 @@
 	/* Check if this is an INVITE that sets up a new dialog or
 	   a re-invite in an existing dialog */
 	if (!ignore) {
-		/* Use this as the basis */
-		if (debug)
-			ast_verbose("Using latest INVITE request as basis request\n");
 		sip_cancel_destroy(p);
-		/* This call is no longer outgoing if it ever was */
-		ast_clear_flag(p, SIP_OUTGOING);
 		/* This also counts as a pending invite */
 		p->pendinginvite = seqno;
-//		copy_request(&p->initreq, req);
 		check_via(p, req);
 
-		if (!p->owner){  /* A first INVITE, no re-invite */
-		/*	 ast_clear_flag(p, SIP_OUTGOING);  Disabled */
-			copy_request(&p->initreq, req);
+		if (!p->owner) {  /* A first INVITE, no re-invite */
+			/* Use this as the basis */
+			copy_request(&p->initreq, req);	/* Save this initial request until session is over */
+			if (debug)
+				ast_verbose("Using latest INVITE request as basis request\n");
 		}
 
 		if (p->owner) {	/* re-invite */
@@ -11227,6 +11269,7 @@
 		}
 	} else if (debug)
 		ast_verbose("Ignoring this INVITE request\n");
+
 	if (!p->lastinvite && !ignore && !p->owner) {	/* This is a new INVITE */
 
 		/* Handle authentication if this is our first invite */
@@ -11286,11 +11329,11 @@
 		build_contact(p);			/* Build our contact header */
 
 		if (!replace_id && gotdest) {	/* No matching extension found */
-			if (gotdest < 0) {
-				transmit_response_reliable(p, "404 Not Found", req);
+			if (gotdest == 1 && ast_test_flag(&p->flags_page2, SIP_PAGE2_ALLOWOVERLAP)) {
+				transmit_response_reliable(p, "484 Address Incomplete", req);
 				update_call_counter(p, DEC_CALL_LIMIT);
 			} else {
-				transmit_response_reliable(p, "484 Address Incomplete", req);
+				transmit_response_reliable(p, "404 Not Found", req);
 				update_call_counter(p, DEC_CALL_LIMIT);
 			}
 			ast_set_flag(p, SIP_NEEDDESTROY);		
@@ -11353,7 +11396,6 @@
 				switch(res) {
 				case AST_PBX_FAILED:
 					ast_log(LOG_WARNING, "Failed to start PBX :(\n");
-					/* Unlock locks so ast_hangup can do its magic */
 					if (ignore)
 						transmit_response(p, "503 Unavailable", req);
 					else
@@ -11597,8 +11639,8 @@
 	return 0;
 }
 
-/*--- local_attended_transfer: Find all call legs and bridge transferee with target */
-/*	called from handle_request_refer */
+/*! \brief  Find all call legs and bridge transferee with target 
+ *	called from handle_request_refer */
 int local_attended_transfer(struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno)
 {
 	struct sip_dual target;		/* Chan 1: Call from tranferer to Asterisk */
@@ -11638,16 +11680,10 @@
 	}
 	/* We have a channel, find the bridge */
 	target.chan1 = targetcall_pvt->owner;				/* Transferer to Asterisk */
-	/* Check if the target outbound channel is ringing or up */
-	if (!error && target.chan1->_state == AST_STATE_RING) {
-		if (option_debug > 3)
-			ast_log(LOG_DEBUG, "SIP attended transfer: Error: Wrong state of target call: Channel is only ringing...\n");
-		// OEJ DISABLED error = 1;
-	}
 
 	if (!error) {
 		target.chan2 = ast_bridged_channel(targetcall_pvt->owner);	/* Asterisk to target */
-		//if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) {
+
 		if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) {
 			/* Wrong state of new channel */
 			if (option_debug > 3) {
@@ -11681,8 +11717,6 @@
 			ast_log(LOG_DEBUG, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name);
 	}
 
-	//ast_channel_unlock(current->chan1);
-	//ast_channel_unlock(target.chan1);
 	ast_set_flag(transferer, SIP_PAGE2_DEFER_BYE_ON_TRANSFER);	/* Delay hangup */
 	if (transferer->owner)
 		ast_set_flag(transferer->owner, AST_FLAG_KEEP_PVT_AT_HANGUP);	/* Delay hangup */
@@ -11710,32 +11744,30 @@
 			ast_log(LOG_DEBUG, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name);
 			ast_channel_unlock(targetcall_pvt->owner);
 		}
-		/* If the other end does not hangup, we hangup */
-		//if (transferer->owner) {
-			//transferer->owner->tech_pvt = NULL;
-			//ast_hangup(transferer->owner);
-		//}
-		/* Wonder if  disabling this will leave a zombie */
-		//sip_destroy(transferer);
 	}
 	return 1;
 }
 
 /*--- handle_request_refer: Handle incoming REFER request ---*/
-/*	REFER is used for call transfer in SIP. We get a REFER
+/*! \page SIP_REFER SIP transfer Support (REFER)
+
+	REFER is used for call transfer in SIP. We get a REFER
 	to place a new call with an INVITE somwhere and then
 	keep the transferor up-to-date of the transfer. If the
 	transfer fails, get back on line with the orginal call. 
 
-	REFER can be sent outside or inside of a dialog.
-
-	If we get a replaces header, it is an attended transfer
-
-	BASIC transfer: The transferor provides the transferee
+	- REFER can be sent outside or inside of a dialog.
+	  Asterisk only accepts REFER inside of a dialog.
+
+	- If we get a replaces header, it is an attended transfer
+
+	\par Blind transfers
+	The transferor provides the transferee
 	with the transfer targets contact. The signalling between
 	transferer or transferee should not be cancelled, so the
 	call is recoverable if the transfer target can not be reached 
 	by the transferee.
+
 	In this case, Asterisk receives a TRANSFER from
 	the transferor, thus is the transferee. We should
 	try to set up a call to the contact provided
@@ -11744,17 +11776,20 @@
 	In this scenario, we are following section 5.2
 	in the SIP CC Transfer draft. (Transfer without
 	a GRUU)
-	Transfer with consultation hold: In this case, the transferor
+
+	\par Transfer with consultation hold
+	In this case, the transferor
 	talks to the transfer target before the transfer takes place.
 	This is implemented with SIP hold and transfer.
-	(Note: The invite From: string could indicate a transfer.
+	Note: The invite From: string could indicate a transfer.
 	(Section 6. Transfer with consultation hold)
 	The transferor places the transferee on hold, starts a call
 	with the transfer target to alert them to the impending
 	transfer, terminates the connection with the target, then
-	proceeds with the transfer (as in Basic transfer above(
-
-	Attended transfer: The transferor places the transferee
+	proceeds with the transfer (as in Blind transfer above)
+
+	\par Attended transfer
+	The transferor places the transferee
 	on hold, calls the transfer target to alert them,
 	places the target on hold, then proceeds with the transfer
 	using a Replaces header field in the Refer-to header. This
@@ -12058,6 +12093,7 @@
 	}
 	return res;
 }
+
 /*! \brief Handle incoming CANCEL request */
 static int handle_request_cancel(struct sip_pvt *p, struct sip_request *req, int debug, int ignore)
 {
@@ -12173,6 +12209,17 @@
 				ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid);
 		}
 	}
+
+	/* Check if we have a global disallow setting on subscriptions. 
+		if so, we don't have to check peer/user settings after auth, which saves a lot of processing
+	*/
+	if (!global_allowsubscribe) {
+ 		transmit_response(p, "403 Forbidden (policy)", req);
+		ast_set_flag(p, SIP_NEEDDESTROY);	
+		return 0;
+
+	}
+
 	if (!ignore && !p->initreq.headers) {
 		/* Use this as the basis */
 		if (debug)
@@ -12213,6 +12260,14 @@
 			}
 			return 0;
 		}
+
+		/* Check if this user/peer is allowed to subscribe at all */
+		if (! ast_test_flag(&p->flags_page2, SIP_PAGE2_ALLOWSUBSCRIBE)) {
+ 			transmit_response(p, "403 Forbidden (policy)", req);
+			ast_set_flag(p, SIP_NEEDDESTROY);	
+			return 0;
+		}
+
 		/* Initialize the context if it hasn't been already */
 		if (!ast_strlen_zero(p->subscribecontext))
 			ast_string_field_set(p, context, p->subscribecontext);
@@ -12222,10 +12277,7 @@
 		gotdest = get_destination(p, NULL);
 		build_contact(p);
 		if (gotdest) {
-			if (gotdest < 0)
-				transmit_response(p, "404 Not Found", req);
-			else
-				transmit_response(p, "484 Address Incomplete", req);	/* Overlap dialing on SUBSCRIBE?? */
+			transmit_response(p, "404 Not Found", req);
 			ast_set_flag(p, SIP_NEEDDESTROY);	
 		} else {
 
@@ -13366,12 +13418,14 @@
 	oldha = user->ha;
 	user->ha = NULL;
 	ast_copy_flags(user, &global_flags, SIP_FLAGS_TO_COPY);
+	ast_copy_flags(user, &global_flags_page2, SIP_PAGE2_FLAGS_TO_COPY);
 	user->capability = global_capability;
 	user->prefs = default_prefs;
 	/* set default context */
 	strcpy(user->context, default_context);
 	strcpy(user->language, default_language);
 	strcpy(user->musicclass, default_musicclass);
+	peer->allowtransfer = global_allowtransfer;
 	for (; v; v = v->next) {
 		if (handle_common_options(&userflags, &mask, v))
 			continue;
@@ -13393,6 +13447,9 @@
 		} else if (!strcasecmp(v->name, "permit") ||
 				   !strcasecmp(v->name, "deny")) {
 			user->ha = ast_append_ha(v->name, v->value, user->ha);
+		} else if (!strcasecmp(v->name, "allowtransfer")) {
+			if (!ast_true(v->value))	/* no */
+				user->allowtransfer = TRANSFER_CLOSED;
 		} else if (!strcasecmp(v->name, "secret")) {
 			ast_copy_string(user->secret, v->value, sizeof(user->secret)); 
 		} else if (!strcasecmp(v->name, "md5secret")) {
@@ -13409,6 +13466,17 @@
 			ast_copy_string(user->musicclass, v->value, sizeof(user->musicclass));
 		} else if (!strcasecmp(v->name, "accountcode")) {
 			ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
+		} else if (!strcasecmp(v->name, "allowsubscribe")) {
+			if (ast_true(v->value)) {
+				global_allowsubscribe = TRUE;	/* No global ban any more */
+				ast_set_flag(&user->flags_page2, SIP_PAGE2_ALLOWSUBSCRIBE);
+			} else
+				ast_clear_flag(&user->flags_page2, SIP_PAGE2_ALLOWSUBSCRIBE);
+		} else if (!strcasecmp(v->name, "allowoverlap")) {
+			if (ast_true(v->value)) {
+				ast_set_flag(&user->flags_page2, SIP_PAGE2_ALLOWOVERLAP);
+			} else
+				ast_clear_flag(&user->flags_page2, SIP_PAGE2_ALLOWOVERLAP);
 		} else if (!strcasecmp(v->name, "call-limit")) {
 			user->call_limit = atoi(v->value);
 			if (user->call_limit < 0)
@@ -13428,7 +13496,18 @@
 			user->callingpres = ast_parse_caller_presentation(v->value);
 			if (user->callingpres == -1)
 				user->callingpres = atoi(v->value);
-		}
+		} else if (!strcasecmp(v->name, "maxcallbitrate")) {
+			user->maxcallbitrate = atoi(v->value);
+			if (user->maxcallbitrate < 0)
+				user->maxcallbitrate = default_maxcallbitrate;
+		} else if (!strcasecmp(v->name, "videosupport")) {
+			if (ast_test_flag((&global_flags_page2), SIP_PAGE2_VIDEOSUPPORT)) {
+				if (ast_true(v->value))
+					ast_set_flag((&user->flags_page2), SIP_PAGE2_VIDEOSUPPORT);
+				else
+					ast_clear_flag((&user->flags_page2), SIP_PAGE2_VIDEOSUPPORT);
+			}
+ 		}
 	}
 	ast_copy_flags(user, &userflags, mask.flags);
 	ast_free_ha(oldha);
@@ -13446,7 +13525,9 @@
 		peer->pokeexpire = -1;
 		peer->addr.sin_port = htons(DEFAULT_SIP_PORT);
 	}
+	ast_copy_flags((&peer->flags_page2), &global_flags_page2, SIP_PAGE2_FLAGS_TO_COPY);
 	ast_copy_flags(peer, &global_flags, SIP_FLAGS_TO_COPY);
+	ast_copy_flags(&peer->flags_page2, &global_flags_page2, SIP_PAGE2_FLAGS_TO_COPY);
 	strcpy(peer->context, default_context);
 	strcpy(peer->subscribecontext, default_subscribecontext);
 	strcpy(peer->language, default_language);
@@ -13454,9 +13535,11 @@
 	peer->addr.sin_family = AF_INET;
 	peer->defaddr.sin_family = AF_INET;
 	peer->capability = global_capability;
+	peer->maxcallbitrate = default_maxcallbitrate;
 	peer->rtptimeout = global_rtptimeout;
 	peer->rtpholdtimeout = global_rtpholdtimeout;
 	peer->rtpkeepalive = global_rtpkeepalive;
+	peer->allowtransfer = global_allowtransfer;
 	strcpy(peer->vmexten, default_vmexten);
 	ast_copy_flags(peer, &global_flags, SIP_USEREQPHONE);
 	peer->secret[0] = '\0';
@@ -13570,11 +13653,29 @@
 			ast_copy_string(peer->context, v->value, sizeof(peer->context));
 		} else if (!strcasecmp(v->name, "subscribecontext")) {
 			ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext));
+		} else if (!strcasecmp(v->name, "allowsubscribe")) {
+			if (ast_true(v->value)) {
+				global_allowsubscribe = TRUE;	/* No global ban any more */
+				ast_set_flag(&peer->flags_page2, SIP_PAGE2_ALLOWSUBSCRIBE);
+			} else
+				ast_clear_flag(&peer->flags_page2, SIP_PAGE2_ALLOWSUBSCRIBE);
+		} else if (!strcasecmp(v->name, "allowoverlap")) {
+			if (ast_true(v->value)) {
+				ast_set_flag(&peer->flags_page2, SIP_PAGE2_ALLOWOVERLAP);
+			} else
+				ast_clear_flag(&peer->flags_page2, SIP_PAGE2_ALLOWOVERLAP);
 		} else if (!strcasecmp(v->name, "fromdomain"))
 			ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain));
 		else if (!strcasecmp(v->name, "usereqphone"))
 			ast_set2_flag(peer, ast_true(v->value), SIP_USEREQPHONE);
-		else if (!strcasecmp(v->name, "fromuser"))
+		else if (!strcasecmp(v->name, "videosupport")) {
+			if (ast_test_flag((&global_flags_page2), SIP_PAGE2_VIDEOSUPPORT)) {
+				if (ast_true(v->value))
+					ast_set_flag((&peer->flags_page2), SIP_PAGE2_VIDEOSUPPORT);
+				else
+					ast_clear_flag((&peer->flags_page2), SIP_PAGE2_VIDEOSUPPORT);
+			}
+		} else if (!strcasecmp(v->name, "fromuser"))
 			ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser));
 		else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) {
 			if (!strcasecmp(v->value, "dynamic")) {
@@ -13659,6 +13760,9 @@
 			peer->callgroup = ast_get_group(v->value);
 		} else if (!strcasecmp(v->name, "pickupgroup")) {
 			peer->pickupgroup = ast_get_group(v->value);
+		} else if (!strcasecmp(v->name, "allowtransfer")) {
+			if (!ast_true(v->value))	/* no */
+				peer->allowtransfer = TRANSFER_CLOSED;
 		} else if (!strcasecmp(v->name, "allow")) {
 			ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
 		} else if (!strcasecmp(v->name, "disallow")) {
@@ -13698,6 +13802,10 @@
 				ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", peer->name, v->lineno);
 				peer->maxms = 0;
 			}
+		} else if (!strcasecmp(v->name, "maxcallbitrate")) {
+			peer->maxcallbitrate = atoi(v->value);
+			if (peer->maxcallbitrate < 0)
+				peer->maxcallbitrate = default_maxcallbitrate;
 		}
 	}
 	if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag((&peer->flags_page2), SIP_PAGE2_DYNAMIC) && realtime) {
@@ -13777,11 +13885,11 @@
 	global_regcontext[0] = '\0';
 	expiry = DEFAULT_EXPIRY;
 	global_notifyringing = DEFAULT_NOTIFYRINGING;
+	global_allowsubscribe = TRUE;
 	ast_copy_string(global_useragent, DEFAULT_USERAGENT, sizeof(global_useragent));
 	ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime));
 	ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm));
 	ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid));
-	global_videosupport = DEFAULT_VIDEOSUPPORT;
 	compactheaders = DEFAULT_COMPACTHEADERS;
 	global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
 	global_regattempts_max = 0;
@@ -13792,9 +13900,13 @@
 	global_rtptimeout = 0;
 	global_rtpholdtimeout = 0;

[... 146 lines stripped ...]


More information about the asterisk-commits mailing list