[asterisk-commits] branch oej/siptransfer r19580 - in /team/oej/siptransfer: ./ channels/ doc/ i...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Wed Apr 12 14:40:32 MST 2006


Author: oej
Date: Wed Apr 12 16:40:25 2006
New Revision: 19580

URL: http://svn.digium.com/view/asterisk?rev=19580&view=rev
Log:
Update and reset

Modified:
    team/oej/siptransfer/   (props changed)
    team/oej/siptransfer/asterisk.c
    team/oej/siptransfer/channels/chan_sip.c
    team/oej/siptransfer/doc/speechrec.txt
    team/oej/siptransfer/include/asterisk.h
    team/oej/siptransfer/include/asterisk/compat.h
    team/oej/siptransfer/include/asterisk/lock.h
    team/oej/siptransfer/include/asterisk/utils.h
    team/oej/siptransfer/utils.c
    team/oej/siptransfer/utils/astman.c

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

Propchange: team/oej/siptransfer/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Wed Apr 12 16:40:25 2006
@@ -1,1 +1,1 @@
-/trunk:1-19537
+/trunk:1-19576

Modified: team/oej/siptransfer/asterisk.c
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/asterisk.c?rev=19580&r1=19579&r2=19580&view=diff
==============================================================================
--- team/oej/siptransfer/asterisk.c (original)
+++ team/oej/siptransfer/asterisk.c Wed Apr 12 16:40:25 2006
@@ -74,6 +74,9 @@
 #include <grp.h>
 #include <pwd.h>
 #include <sys/stat.h>
+#ifdef linux
+#include <sys/prctl.h>
+#endif
 #include <regex.h>
 
 #ifdef linux
@@ -270,6 +273,207 @@
 	AST_LIST_UNLOCK(&file_versions);
 	if (find)
 		free(find);
+}
+
+struct thread_list_t {
+	AST_LIST_ENTRY(thread_list_t) list;
+	char *name;
+	pthread_t id;
+};
+
+static AST_LIST_HEAD_STATIC(thread_list, thread_list_t);
+
+static char show_threads_help[] =
+"Usage: show threads\n"
+"       List threads currently active in the system.\n";
+
+void ast_register_thread(char *name)
+{ 
+	struct thread_list_t *new = ast_calloc(1, sizeof(*new));
+
+	if (!new)
+		return;
+	new->id = pthread_self();
+	new->name = name; /* this was a copy already */
+	AST_LIST_LOCK(&thread_list);
+	AST_LIST_INSERT_HEAD(&thread_list, new, list);
+	AST_LIST_UNLOCK(&thread_list);
+}
+
+void ast_unregister_thread(void *id)
+{
+	struct thread_list_t *x;
+
+	AST_LIST_LOCK(&thread_list);
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&thread_list, x, list) {
+		if ((void *)x->id == id) {
+			AST_LIST_REMOVE_CURRENT(&thread_list, list);
+			break;
+		}
+	}
+	AST_LIST_TRAVERSE_SAFE_END;
+	AST_LIST_UNLOCK(&thread_list);
+	if (x) {
+		free(x->name);
+		free(x);
+	}
+}
+
+static int handle_show_threads(int fd, int argc, char *argv[])
+{
+	int count = 0;
+	struct thread_list_t *cur;
+
+	AST_LIST_LOCK(&thread_list);
+	AST_LIST_TRAVERSE(&thread_list, cur, list) {
+		ast_cli(fd, "%p %s\n", (void *)cur->id, cur->name);
+		count++;
+	}
+        AST_LIST_UNLOCK(&thread_list);
+	ast_cli(fd, "%d threads listed.\n", count);
+	return 0;
+}
+
+struct profile_entry {
+	const char *name;
+	uint64_t	scale;	/* if non-zero, values are scaled by this */
+	int64_t	mark;
+	int64_t	value;
+	int64_t	events;
+};
+
+struct profile_data {
+	int entries;
+	int max_size;
+	struct profile_entry e[0];
+};
+
+static struct profile_data *prof_data;
+
+/*
+ * allocates a counter with a given name and scale.
+ * Returns the identifier of the counter.
+ */
+int ast_add_profile(const char *name, uint64_t scale)
+{
+	int l = sizeof(struct profile_data);
+	int n = 10;	/* default entries */
+
+	if (prof_data == NULL) {
+		prof_data = ast_calloc(1, l + n*sizeof(struct profile_entry));
+		if (prof_data == NULL)
+			return -1;
+		prof_data->entries = 0;
+		prof_data->max_size = n;
+	}
+	if (prof_data->entries >= prof_data->max_size) {
+		void *p;
+		n = prof_data->max_size + 20;
+		p = ast_realloc(prof_data, l + n*sizeof(struct profile_entry));
+		if (p == NULL)
+			return -1;
+		prof_data = p;
+		prof_data->max_size = n;
+	}
+	n = prof_data->entries++;
+	prof_data->e[n].name = ast_strdup(name);
+	prof_data->e[n].value = 0;
+	prof_data->e[n].events = 0;
+	prof_data->e[n].mark = 0;
+	prof_data->e[n].scale = scale;
+	return n;
+}
+
+int64_t ast_profile(int i, int64_t delta)
+{
+	if (!prof_data || i < 0 || i > prof_data->entries)	/* invalid index */
+		return 0;
+	if (prof_data->e[i].scale > 1)
+		delta /= prof_data->e[i].scale;
+	prof_data->e[i].value += delta;
+	prof_data->e[i].events++;
+	return prof_data->e[i].value;
+}
+
+#if defined ( __i386__) && (defined(__FreeBSD__) || defined(linux))
+#if defined(__FreeBSD__)
+#include <machine/cpufunc.h>
+#elif defined(linux)
+static __inline u_int64_t
+rdtsc(void)
+{ 
+	uint64_t rv;
+
+	__asm __volatile(".byte 0x0f, 0x31" : "=A" (rv));
+	return (rv);
+}
+#endif
+#else	/* supply a dummy function on other platforms */
+static __inline u_int64_t
+rdtsc(void)
+{
+	return 0;
+}
+#endif
+
+int64_t ast_mark(int i, int startstop)
+{
+	if (!prof_data || i < 0 || i > prof_data->entries) /* invalid index */
+		return 0;
+	if (startstop == 1)
+		prof_data->e[i].mark = rdtsc();
+	else {
+		prof_data->e[i].mark = (rdtsc() - prof_data->e[i].mark);
+		if (prof_data->e[i].scale > 1)
+			prof_data->e[i].mark /= prof_data->e[i].scale;
+		prof_data->e[i].value += prof_data->e[i].mark;
+		prof_data->e[i].events++;
+	}
+	return prof_data->e[i].mark;
+}
+
+static int handle_show_profile(int fd, int argc, char *argv[])
+{
+	int i, min, max;
+	char *search = NULL;
+
+	if (prof_data == NULL)
+		return 0;
+
+	min = 0;
+	max = prof_data->entries;
+	if  (argc >= 3) { /* specific entries */
+		if (isdigit(argv[2][0])) {
+			min = atoi(argv[2]);
+			if (argc == 4 && strcmp(argv[3], "-"))
+				max = atoi(argv[3]);
+		} else
+			search = argv[2];
+	}
+	if (max > prof_data->entries)
+		max = prof_data->entries;
+	if (!strcmp(argv[0], "clear")) {
+		for (i= min; i < max; i++) {
+			if (!search || strstr(prof_data->e[i].name, search)) {
+				prof_data->e[i].value = 0;
+				prof_data->e[i].events = 0;
+			}
+		}
+		return 0;
+	}
+	ast_cli(fd, "profile values (%d, allocated %d)\n-------------------\n",
+		prof_data->entries, prof_data->max_size);
+	for (i = min; i < max; i++) {
+		struct profile_entry *e = &prof_data->e[i];
+		if (!search || strstr(prof_data->e[i].name, search))
+		    ast_cli(fd, "%6d: [%8ld] %10ld %12lld %12lld %s\n",
+			i,
+			(long)e->scale,
+			(long)e->events, (long long)e->value,
+			(long long)(e->events ? e->value / e->events : e->value),
+			e->name);
+	}
+	return 0;
 }
 
 static char show_version_files_help[] = 
@@ -1231,6 +1435,12 @@
 #if !defined(LOW_MEMORY)
 	{ { "show", "version", "files", NULL }, handle_show_version_files,
 	  "Show versions of files used to build Asterisk", show_version_files_help, complete_show_version_files },
+	{ { "show", "threads", NULL }, handle_show_threads,
+	  "Show running threads", show_threads_help, NULL },
+	{ { "show", "profile", NULL }, handle_show_profile,
+	  "Show profiling info"},
+	{ { "clear", "profile", NULL }, handle_show_profile,
+	  "Clear profiling info"},
 #endif /* ! LOW_MEMORY */
 };
 

Modified: team/oej/siptransfer/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/channels/chan_sip.c?rev=19580&r1=19579&r2=19580&view=diff
==============================================================================
--- team/oej/siptransfer/channels/chan_sip.c (original)
+++ team/oej/siptransfer/channels/chan_sip.c Wed Apr 12 16:40:25 2006
@@ -34,6 +34,48 @@
  * \todo Better support of forking
  *
  * \ingroup channel_drivers
+ *
+ * \par Overview of the handling of SIP sessions
+ * The SIP channel handles several types of SIP sessions, or dialogs,
+ * not all of them being "telephone calls".
+ * - Incoming calls that will be sent to the PBX core
+ * - Outgoing calls, generated by the PBX
+ * - SIP subscriptions and notifications of states and voicemail messages
+ * - SIP registrations, both inbound and outbound
+ * - SIP peer management (peerpoke, OPTIONS)
+ * - SIP text messages
+ *
+ * In the SIP channel, there's a list of active SIP dialogs, which includes
+ * all of these when they are active. "sip show channels" in the CLI will
+ * show most of these, excluding subscriptions which are shown by
+ * "sip show subscriptions"
+ *
+ * \par incoming packets
+ * Incoming packets are received in the monitoring thread, then handled by
+ * sipsock_read(). This function parses the packet and matches an existing
+ * dialog or starts a new SIP dialog.
+ * 
+ * sipsock_read sends the packet to handle_request(), that parses a bit more.
+ * if it's a response to an outbound request, it's sent to handle_response().
+ * If it is a request, handle_request sends it to one of a list of functions
+ * depending on the request type - INVITE, OPTIONS, REFER, BYE, CANCEL etc
+ *
+ * A new INVITE is sent to handle_request_invite(), that will end up
+ * starting a new channel in the PBX, the new channel after that executing
+ * in a separate channel thread. This is an incoming "call".
+ * When the call is answered, either by a bridged channel or the PBX itself
+ * the sip_answer() function is called.
+ *
+ * The actual media - Video or Audio - is mostly handled by the RTP subsystem
+ * in rtp.c 
+ * 
+ * \par Outbound calls
+ * Outbound calls are set up by the PBX through the sip_request_call()
+ * function. After that, they are activated by sip_call().
+ * 
+ * \par Hanging up
+ * The PBX issues a hangup on both incoming and outgoing calls through
+ * the sip_hangup() function
  *
  */
 
@@ -161,12 +203,24 @@
 #define RTP 	1
 #define NO_RTP	0
 
+<<<<<<< .working
 /*! \brief Authorization scheme for call transfers */
 enum transfermodes {
 	TRANSFER_OPENFORALL, 		/*!< Allow all SIP transfers */
 	TRANSFER_CLOSED,		/*!< Allow no SIP transfers */
 };
 
+=======
+/*! \brief Authorization scheme for call transfers 
+\note Not a bitfield flag, since there are plans for other modes,
+	like "only allow transfers for authenticated devices" */
+enum transfermodes {
+	TRANSFER_OPENFORALL, 		/*!< Allow all SIP transfers */
+	TRANSFER_CLOSED,		/*!< Allow no SIP transfers */
+};
+
+
+>>>>>>> .merge-right.r19549
 /* 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
    not doing the right thing. If you think there are changes
@@ -305,8 +359,13 @@
 } sip_options[] = {	/* XXX used in 3 places */
 	/* Replaces: header for transfer */
 	{ SIP_OPT_REPLACES,	SUPPORTED,	"replaces" },	
+<<<<<<< .working
 	/* Polycom has the wrong notation. Tss tss. */
 	{ SIP_OPT_REPLACES,  SUPPORTED,  "replace" },
+=======
+	/* One version of Polycom firmware has the wrong label */
+	{ SIP_OPT_REPLACES,	SUPPORTED,	"replace" },	
+>>>>>>> .merge-right.r19549
 	/* RFC3262: PRACK 100% reliability */
 	{ SIP_OPT_100REL,	NOT_SUPPORTED,	"100rel" },	
 	/* SIP Session Timers */
@@ -505,11 +564,11 @@
 /*! \brief Parameters to the transmit_invite function */
 struct sip_invite_param {
 	const char *distinctive_ring;	/*!< Distinctive ring header */
-	int addsipheaders;	/*!< Add extra SIP headers */
+	int addsipheaders;		/*!< Add extra SIP headers */
 	const char *uri_options;	/*!< URI options to add to the URI */
 	const char *vxml_url;		/*!< VXML url for Cisco phones */
-	char *auth;		/*!< Authentication */
-	char *authheader;	/*!< Auth header */
+	char *auth;			/*!< Authentication */
+	char *authheader;		/*!< Auth header */
 	enum sip_auth_type auth_type;	/*!< Authentication type */
 	const char *replaces;		/*!< Replaces header for call transfers */
 	int transfer;		/*!< Flag: Invite Part of a SIP transfer? */
@@ -523,8 +582,8 @@
 
 /*! \brief Modes for SIP domain handling in the PBX */
 enum domain_mode {
-	SIP_DOMAIN_AUTO,	/*!< This domain is auto-configured */
-	SIP_DOMAIN_CONFIG,	/*!< This domain is from configuration */
+	SIP_DOMAIN_AUTO,		/*!< This domain is auto-configured */
+	SIP_DOMAIN_CONFIG,		/*!< This domain is from configuration */
 };
 
 struct domain {
@@ -554,11 +613,9 @@
 	struct sip_auth *next;		/*!< Next auth structure in list */
 };
 
-/*--- Various flags for the flags field in the pvt structure 
- Peer only flags should be set in PAGE2 below
-*/
+/*--- Various flags for the flags field in the pvt structure */
 #define SIP_ALREADYGONE		(1 << 0)	/*!< Whether or not we've already been destroyed by our peer */
-#define SIP_NEEDDESTROY		(1 << 1)	/*!< if we need to be destroyed */
+#define SIP_NEEDDESTROY		(1 << 1)	/*!< if we need to be destroyed by the monitor thread */
 #define SIP_NOVIDEO		(1 << 2)	/*!< Didn't get video in invite, don't offer */
 #define SIP_RINGING		(1 << 3)	/*!< Have sent 180 ringing */
 #define SIP_PROGRESS_SENT	(1 << 4)	/*!< Have sent 183 message progress */
@@ -772,8 +829,12 @@
 	int rtptimeout;				/*!< RTP timeout time */
 	int rtpholdtimeout;			/*!< RTP timeout when on hold */
 	int rtpkeepalive;			/*!< Send RTP packets for keepalive */
+<<<<<<< .working
 	enum transfermodes allowtransfer;	/*!< Allow transfer modes */
 	struct sip_refer *refer;		/*!< Refer data */
+=======
+	enum transfermodes allowtransfer;	/*! SIP Refer restriction scheme */
+>>>>>>> .merge-right.r19549
 	enum subscriptiontype subscribed;	/*!< Is this dialog a subscription?  */
 	int stateid;
 	int laststate;				/*!< Last known extension state */
@@ -835,7 +896,11 @@
 	int capability;			/*!< Codec capability */
 	int inUse;			/*!< Number of calls in use */
 	int call_limit;			/*!< Limit of concurrent calls */
+<<<<<<< .working
 	enum transfermodes allowtransfer;   /*!< Allow transfer modes */
+=======
+	enum transfermodes allowtransfer;	/*! SIP Refer restriction scheme */
+>>>>>>> .merge-right.r19549
 	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 */
@@ -864,6 +929,7 @@
 	int callingpres;		/*!< Calling id presentation */
 	int inUse;			/*!< Number of calls in use */
 	int call_limit;			/*!< Limit of concurrent calls */
+	enum transfermodes allowtransfer;	/*! SIP Refer restriction scheme */
 	char vmexten[AST_MAX_EXTENSION]; /*!< Dialplan extension for MWI notify message*/
 	char mailbox[AST_MAX_EXTENSION]; /*!< Mailbox setting for MWI checks */
 	char language[MAX_LANGUAGE];	/*!<  Default language for prompts */
@@ -2149,6 +2215,7 @@
 	r->allowtransfer = peer->allowtransfer;
 	r->callgroup = peer->callgroup;
 	r->pickupgroup = peer->pickupgroup;
+	r->allowtransfer = peer->allowtransfer;
 	/* Set timer T1 to RTT for this peer (if known by qualify=) */
 	/* Minimum is settable or default to 100 ms */
 	if (peer->maxms && peer->lastms)
@@ -3505,6 +3572,7 @@
 	ast_string_field_set(p, musicclass, default_musicclass);
 	p->allowtransfer = global_allowtransfer;
 	p->capability = global_capability;
+	p->allowtransfer = global_allowtransfer;
 	if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
 	    (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
 		p->noncodeccapability |= AST_RTP_DTMF;
@@ -8486,6 +8554,7 @@
 		if (!ast_strlen_zero(peer->accountcode))
 			ast_cli(fd, "  Accountcode  : %s\n", peer->accountcode);
 		ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(peer->amaflags));
+		ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(peer->allowtransfer));
 		ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(peer->callingpres));
 		if (!ast_strlen_zero(peer->fromuser))
 			ast_cli(fd, "  FromUser     : %s\n", peer->fromuser);
@@ -8526,9 +8595,13 @@
 		ast_cli(fd, "  Def. Username: %s\n", peer->username);
 		ast_cli(fd, "  SIP Options  : ");
 		if (peer->sipoptions) {
+			int lastoption = -1;
 			for (x=0 ; (x < (sizeof(sip_options) / sizeof(sip_options[0]))); x++) {
-				if (peer->sipoptions & sip_options[x].id)
-					ast_cli(fd, "%s ", sip_options[x].text);
+				if (sip_options[x].id != lastoption) {
+					if (peer->sipoptions & sip_options[x].id)
+						ast_cli(fd, "%s ", sip_options[x].text);
+					lastoption = x;
+				}
 			}
 		} else
 			ast_cli(fd, "(none)");
@@ -8575,6 +8648,7 @@
 		astman_append(s, "Pickupgroup: ");
 		print_group(fd, peer->pickupgroup, 1);
 		astman_append(s, "VoiceMailbox: %s\r\n", peer->mailbox);
+		astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
 		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);
@@ -8783,6 +8857,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, "  SIP Transfer mode:      %s\n", transfermode2str(global_allowtransfer));
 	ast_cli(fd, "  Max Call Bitrate:       %dkbps\r\n", default_maxcallbitrate);
 	ast_cli(fd, "\nDefault Settings:\n");
 	ast_cli(fd, "-----------------\n");
@@ -11902,6 +11977,7 @@
 	struct sip_dual current;	/* Chan1: Call between asterisk and transferer */
 					/* Chan2: Call between asterisk and transferee */
 
+<<<<<<< .working
 	int res = 0;
 
 	if (ast_test_flag(req, SIP_PKT_DEBUG))
@@ -11920,7 +11996,47 @@
 		if (option_debug > 2)
 			ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid);
 		transmit_response(p, "603 Declined (No dialog)", req);
-		if (!ignore) {
+=======
+	if (option_debug > 2)
+		ast_log(LOG_DEBUG, "SIP call transfer received for call %s (REFER)!\n", p->callid);
+
+	/* Check if transfer is allowed from this device */
+	if (p->allowtransfer == TRANSFER_CLOSED ) {
+		/* Transfer not allowed, decline */
+		transmit_response(p, "603 Declined (policy)", req);
+		append_history(p, "Xfer", "Refer failed. Allowtransfer == closed.");
+		/* Do not destroy SIP session */
+		return 0;
+	}
+
+	if (!p->owner) {
+		/* This is a REFER outside of an existing SIP dialog */
+		/* We can't handle that, so decline it */
+		if (option_debug > 2)
+			ast_log(LOG_DEBUG, "Call %s: Declined REFER, outside of dialog...\n", p->callid);
+		transmit_response(p, "603 Declined (No dialog)", req);
+		if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
+			append_history(p, "Xfer", "Refer failed. Outside of dialog.");
+			ast_set_flag(&p->flags[0], SIP_ALREADYGONE);	
+			ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);	
+		}
+		return 0;
+	}	
+
+	if (ast_strlen_zero(p->context))
+		ast_string_field_set(p, context, default_context);
+	res = get_refer_info(p, req);
+	if (res > 0) {
+		if (ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP)) 
+			transmit_response_with_allow(p, "484 Address Incomplete", req, 1);
+		else
+			transmit_response_with_allow(p, "404 Not Found", req, 1);
+	} else if (res < 0)
+		transmit_response_with_allow(p, "404 Not Found", req, 1);
+	else {
+		int nobye = 0;
+>>>>>>> .merge-right.r19549
+		if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
 			append_history(p, "Xfer", "Refer failed. Outside of dialog.");
 			ast_set_flag(&p->flags[0], SIP_ALREADYGONE);	
 			ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);	
@@ -13563,6 +13679,7 @@
 	ast_copy_flags(&user->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
 	ast_copy_flags(&user->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
 	user->capability = global_capability;
+	user->allowtransfer = global_allowtransfer;
 	user->prefs = default_prefs;
 	/* set default context */
 	strcpy(user->context, default_context);
@@ -13589,9 +13706,14 @@
 		} else if (!strcasecmp(v->name, "permit") ||
 				   !strcasecmp(v->name, "deny")) {
 			user->ha = ast_append_ha(v->name, v->value, user->ha);
+<<<<<<< .working
 		} else if (!strcasecmp(v->name, "allowtransfer")) {
 			if (!ast_true(v->value))	/* no */
 				user->allowtransfer = TRANSFER_CLOSED;
+=======
+		} else if (!strcasecmp(v->name, "allowtransfer")) {
+			user->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
+>>>>>>> .merge-right.r19549
 		} else if (!strcasecmp(v->name, "secret")) {
 			ast_copy_string(user->secret, v->value, sizeof(user->secret)); 
 		} else if (!strcasecmp(v->name, "md5secret")) {
@@ -13868,6 +13990,8 @@
 			ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten));
 		} else if (!strcasecmp(v->name, "callgroup")) {
 			peer->callgroup = ast_get_group(v->value);
+		} else if (!strcasecmp(v->name, "allowtransfer")) {
+			peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
 		} else if (!strcasecmp(v->name, "pickupgroup")) {
 			peer->pickupgroup = ast_get_group(v->value);
 		} else if (!strcasecmp(v->name, "allowtransfer")) {
@@ -14015,8 +14139,12 @@
 	global_rtptimeout = 0;
 	global_rtpholdtimeout = 0;
 	global_rtpkeepalive = 0;
+<<<<<<< .working
 	global_allowtransfer = TRANSFER_OPENFORALL;           /* Default transfer mode: Open */
 
+=======
+	global_allowtransfer = TRANSFER_OPENFORALL;	/* Merrily accept all transfers by default */
+>>>>>>> .merge-right.r19549
 	global_rtautoclear = 120;
 	ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE);	/* Default for peers, users: TRUE */
 	ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP);		/* Default for peers, users: TRUE */
@@ -14058,7 +14186,10 @@
 			ast_copy_string(global_realm, v->value, sizeof(global_realm));
 		} else if (!strcasecmp(v->name, "useragent")) {
 			ast_copy_string(global_useragent, v->value, sizeof(global_useragent));
-			ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent);
+			if (option_debug)
+				ast_log(LOG_DEBUG, "Setting SIP channel User-Agent Name to %s\n", global_useragent);
+		} else if (!strcasecmp(v->name, "allowtransfer")) {
+			global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
 		} else if (!strcasecmp(v->name, "allowtransfer")) {
 			if (!ast_true(v->value))
 				global_allowtransfer = TRANSFER_CLOSED;;

Modified: team/oej/siptransfer/doc/speechrec.txt
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/doc/speechrec.txt?rev=19580&r1=19579&r2=19580&view=diff
==============================================================================
--- team/oej/siptransfer/doc/speechrec.txt (original)
+++ team/oej/siptransfer/doc/speechrec.txt Wed Apr 12 16:40:25 2006
@@ -57,9 +57,9 @@
 
 root $company_directory;
 
-$josh = Joshua Colp:"6066";
-$mark = Mark Spencer:"4569";
-$kevin = Kevin Fleming:"2567";
+$josh = (Joshua | Josh) [Colp]:"6066";
+$mark = Mark [Spencer] | Markster:"4569";
+$kevin = Kevin [Fleming]:"2567";
 
 $company_directory = ($josh | $mark | $kevin) { $ = parseInt($$) };
 

Modified: team/oej/siptransfer/include/asterisk.h
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/include/asterisk.h?rev=19580&r1=19579&r2=19580&view=diff
==============================================================================
--- team/oej/siptransfer/include/asterisk.h (original)
+++ team/oej/siptransfer/include/asterisk.h Wed Apr 12 16:40:25 2006
@@ -14,6 +14,8 @@
 /*! \file
  * \brief Asterisk main include file. File version handling, generic pbx functions.
  */
+
+#include "asterisk/compat.h"
 
 #ifndef _ASTERISK_H
 #define _ASTERISK_H
@@ -108,6 +110,24 @@
 void ast_unregister_file_version(const char *file);
 
 /*!
+ * \brief support for event profiling
+ * (note, this must be documented a lot more)
+ * ast_add_profile allocates a generic 'counter' with a given name,
+ * which can be shown with the command 'show profile <name>'
+ *
+ * The counter accumulates positive or negative values supplied by
+ * ast_add_profile(), dividing them by the 'scale' value passed in the
+ * create call, and also counts the number of 'events'.
+ * Values can also be taked by the TSC counter on ia32 architectures,
+ * in which case you can mark the start of an event calling ast_mark(id, 1)
+ * and then the end of the event with ast_mark(id, 0).
+ * For non-i386 architectures, these two calls return 0.
+ */
+int ast_add_profile(const char *, uint64_t scale);
+int64_t ast_profile(int, int64_t);
+int64_t ast_mark(int, int start1_stop0);
+
+/*!
  * \brief Register/unregister a source code file with the core.
  * \param file the source file name
  * \param version the version string (typically a CVS revision keyword string)
@@ -129,6 +149,20 @@
  * revision number.
  */
 #if defined(__GNUC__) && !defined(LOW_MEMORY)
+#ifdef MTX_PROFILE
+#define	HAVE_MTX_PROFILE	/* used in lock.h */
+#define ASTERISK_FILE_VERSION(file, version) \
+	static int mtx_prof = -1;       /* profile mutex */	\
+	static void __attribute__((constructor)) __register_file_version(void) \
+	{ \
+		mtx_prof = ast_add_profile("mtx_lock_" file, 0);	\
+		ast_register_file_version(file, version); \
+	} \
+	static void __attribute__((destructor)) __unregister_file_version(void) \
+	{ \
+		ast_unregister_file_version(file); \
+	}
+#else
 #define ASTERISK_FILE_VERSION(file, version) \
 	static void __attribute__((constructor)) __register_file_version(void) \
 	{ \
@@ -138,6 +172,7 @@
 	{ \
 		ast_unregister_file_version(file); \
 	}
+#endif
 #elif !defined(LOW_MEMORY) /* ! __GNUC__  && ! LOW_MEMORY*/
 #define ASTERISK_FILE_VERSION(file, x) static const char __file_version[] = x;
 #else /* LOW_MEMORY */

Modified: team/oej/siptransfer/include/asterisk/compat.h
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/include/asterisk/compat.h?rev=19580&r1=19579&r2=19580&view=diff
==============================================================================
--- team/oej/siptransfer/include/asterisk/compat.h (original)
+++ team/oej/siptransfer/include/asterisk/compat.h Wed Apr 12 16:40:25 2006
@@ -80,6 +80,7 @@
 #endif
 
 #ifdef __linux__
+#include <inttypes.h>
 #define HAVE_STRCASESTR
 #define HAVE_STRNDUP
 #define HAVE_STRNLEN

Modified: team/oej/siptransfer/include/asterisk/lock.h
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/include/asterisk/lock.h?rev=19580&r1=19579&r2=19580&view=diff
==============================================================================
--- team/oej/siptransfer/include/asterisk/lock.h (original)
+++ team/oej/siptransfer/include/asterisk/lock.h Wed Apr 12 16:40:25 2006
@@ -56,6 +56,23 @@
 #ifndef _ASTERISK_LOCK_H
 #define _ASTERISK_LOCK_H
 
+/* internal macro to profile mutexes. Only computes the delay on
+ * non-blocking calls.
+ */
+#ifndef	HAVE_MTX_PROFILE
+#define	__MTX_PROF	/* nothing */
+#else
+#define	__MTX_PROF	{			\
+	int i;					\
+	/* profile only non-blocking events */	\
+	ast_mark(mtx_prof, 1);			\
+	i = pthread_mutex_trylock(pmutex);	\
+	ast_mark(mtx_prof, 0);			\
+	if (!i)					\
+		return i;			\
+	}
+#endif	/* HAVE_MTX_PROFILE */
+
 #include <pthread.h>
 #include <netdb.h>
 #include <time.h>
@@ -75,7 +92,7 @@
 #endif
 
 #ifdef BSD
-#ifdef __GNUC__
+#if 0 && defined( __GNUC__)
 #define AST_MUTEX_INIT_W_CONSTRUCTORS
 #else
 #define AST_MUTEX_INIT_ON_FIRST_USE
@@ -264,7 +281,13 @@
 		time_t seconds = time(NULL);
 		time_t current;
 		do {
+#ifdef	HAVE_MTX_PROFILE
+			ast_mark(mtx_prof, 1);
+#endif
 			res = pthread_mutex_trylock(&t->mutex);
+#ifdef	HAVE_MTX_PROFILE
+			ast_mark(mtx_prof, 0);
+#endif
 			if (res == EBUSY) {
 				current = time(NULL);
 				if ((current - seconds) && (!((current - seconds) % 5))) {
@@ -279,6 +302,12 @@
 		} while (res == EBUSY);
 	}
 #else
+#ifdef	HAVE_MTX_PROFILE
+	ast_mark(mtx_prof, 1);
+	res = pthread_mutex_trylock(&t->mutex);
+	ast_mark(mtx_prof, 0);
+	if (res)
+#endif
 	res = pthread_mutex_lock(&t->mutex);
 #endif /* DETECT_DEADLOCKS */
 
@@ -581,6 +610,7 @@
 
 static inline int ast_mutex_lock(ast_mutex_t *pmutex)
 {
+	__MTX_PROF
 	return pthread_mutex_lock(pmutex);
 }
 
@@ -601,8 +631,10 @@
 {
 	if (*pmutex == (ast_mutex_t)AST_MUTEX_KIND)
 		ast_mutex_init(pmutex);
+	__MTX_PROF
 	return pthread_mutex_lock(pmutex);
 }
+
 static inline int ast_mutex_trylock(ast_mutex_t *pmutex)
 {
 	if (*pmutex == (ast_mutex_t)AST_MUTEX_KIND)
@@ -616,6 +648,7 @@
 
 static inline int ast_mutex_lock(ast_mutex_t *pmutex)
 {
+	__MTX_PROF
 	return pthread_mutex_lock(pmutex);
 }
 

Modified: team/oej/siptransfer/include/asterisk/utils.h
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/include/asterisk/utils.h?rev=19580&r1=19579&r2=19580&view=diff
==============================================================================
--- team/oej/siptransfer/include/asterisk/utils.h (original)
+++ team/oej/siptransfer/include/asterisk/utils.h Wed Apr 12 16:40:25 2006
@@ -225,8 +225,14 @@
 }
 
 #define AST_STACKSIZE 256 * 1024
-#define ast_pthread_create(a,b,c,d) ast_pthread_create_stack(a,b,c,d,0)
-int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize);
+
+void ast_register_thread(char *name);
+void ast_unregister_thread(void *id);
+
+#define ast_pthread_create(a,b,c,d) ast_pthread_create_stack(a,b,c,d,0, \
+	 __FILE__, __FUNCTION__, __LINE__, #c)
+int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize,
+	const char *file, const char *caller, int line, const char *start_fn);
 
 /*!
 	\brief Process a string to find and replace characters

Modified: team/oej/siptransfer/utils.c
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/utils.c?rev=19580&r1=19579&r2=19580&view=diff
==============================================================================
--- team/oej/siptransfer/utils.c (original)
+++ team/oej/siptransfer/utils.c Wed Apr 12 16:40:25 2006
@@ -509,8 +509,42 @@
 #undef pthread_create /* For ast_pthread_create function only */
 #endif /* !__linux__ */
 
-int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize)
-{
+/*
+ * support for 'show threads'. The start routine is wrapped by
+ * dummy_start(), so that ast_register_thread() and
+ * ast_unregister_thread() know the thread identifier.
+ */
+struct thr_arg {
+	void *(*start_routine)(void *);
+	void *data;
+	char *name;
+};
+
+/*
+ * on OS/X, pthread_cleanup_push() and pthread_cleanup_pop()
+ * are odd macros which start and end a block, so they _must_ be
+ * used in pairs (the latter with a '1' argument to call the
+ * handler on exit.
+ * On BSD we don't need this, but we keep it for compatibility with the MAC.
+ */
+static void *dummy_start(void *data)
+{
+	void *ret;
+	struct thr_arg a = *((struct thr_arg *)data);	/* make a local copy */
+
+	free(data);
+	ast_register_thread(a.name);
+	pthread_cleanup_push(ast_unregister_thread, (void *)pthread_self());	/* on unregister */
+	ret = a.start_routine(a.data);
+	pthread_cleanup_pop(1);
+	return ret;
+}
+
+int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize,
+	const char *file, const char *caller, int line, const char *start_fn)
+{
+	struct thr_arg *a;
+
 	pthread_attr_t lattr;
 	if (!attr) {
 		pthread_attr_init(&lattr);
@@ -534,6 +568,17 @@
 	errno = pthread_attr_setstacksize(attr, stacksize);
 	if (errno)
 		ast_log(LOG_WARNING, "pthread_attr_setstacksize returned non-zero: %s\n", strerror(errno));
+	a = ast_malloc(sizeof(*a));
+	if (!a)
+		ast_log(LOG_WARNING, "no memory, thread %s will not be listed\n", start_fn);
+	else {	/* remap parameters */
+		a->start_routine = start_routine;
+		a->data = data;
+		start_routine = dummy_start;
+		asprintf(&a->name, "%-20s started at [%5d] %s %s()",
+			start_fn, line, file, caller);
+		data = a;
+	}
 	return pthread_create(thread, attr, start_routine, data); /* We're in ast_pthread_create, so it's okay */
 }
 

Modified: team/oej/siptransfer/utils/astman.c
URL: http://svn.digium.com/view/asterisk/team/oej/siptransfer/utils/astman.c?rev=19580&r1=19579&r2=19580&view=diff
==============================================================================
--- team/oej/siptransfer/utils/astman.c (original)
+++ team/oej/siptransfer/utils/astman.c Wed Apr 12 16:40:25 2006
@@ -83,6 +83,25 @@
 void ast_unregister_file_version(const char *file)
 {
 }
+
+int ast_add_profile(const char *, uint64_t scale);
+int ast_add_profile(const char *s, uint64_t scale)
+{
+	return -1;
+}
+
+int64_t ast_profile(int, int64_t);
+int64_t ast_profile(int key, int64_t val)
+{
+	return 0;
+}
+int64_t ast_mark(int, int start1_stop0);
+int64_t ast_mark(int key, int start1_stop0)
+{
+	return 0;
+}
+
+/* end of dummy functions */
 
 static struct ast_chan *find_chan(char *name)
 {



More information about the asterisk-commits mailing list