[asterisk-commits] branch russell/agent_function - r7553 in /team/russell/agent_function: ./ app...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Dec 20 13:45:29 CST 2005


Author: russell
Date: Tue Dec 20 13:45:22 2005
New Revision: 7553

URL: http://svn.digium.com/view/asterisk?rev=7553&view=rev
Log:
Merged revisions 7509,7511-7512,7514,7516,7518,7520,7522,7524,7528,7538-7542,7547-7548,7551 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
r7509 | tilghman | 2005-12-16 20:07:44 -0500 (Fri, 16 Dec 2005) | 3 lines

Merged revisions 7508 via svnmerge from
/branches/1.2

................
r7511 | kpfleming | 2005-12-16 21:21:36 -0500 (Fri, 16 Dec 2005) | 2 lines

block a commit to a module that no longer exists in trunk

................
r7512 | kpfleming | 2005-12-16 21:22:24 -0500 (Fri, 16 Dec 2005) | 10 lines

Merged revision 7510 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r7510 | kpfleming | 2005-12-16 20:20:04 -0600 (Fri, 16 Dec 2005) | 2 lines

fix some buglet when building team branch version strings

........

................
r7514 | kpfleming | 2005-12-16 22:45:25 -0500 (Fri, 16 Dec 2005) | 10 lines

Merged revisions 7513 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r7513 | kpfleming | 2005-12-16 21:44:30 -0600 (Fri, 16 Dec 2005) | 2 lines

forcibly expire previous subscriptions from a peer when they resubscribe (keeps them from building up and waiting for expiration, and stops us sending unwanted NOTIFY messages to devices)

........

................
r7516 | kpfleming | 2005-12-16 22:59:27 -0500 (Fri, 16 Dec 2005) | 10 lines

Merged revisions 7515 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r7515 | kpfleming | 2005-12-16 21:59:05 -0600 (Fri, 16 Dec 2005) | 2 lines

Max-Forwards headers must only be present on requests, not responses

........

................
r7518 | tilghman | 2005-12-17 12:22:24 -0500 (Sat, 17 Dec 2005) | 3 lines

Merged revisions 7517 via svnmerge from
/branches/1.2

................
r7520 | tilghman | 2005-12-17 13:58:57 -0500 (Sat, 17 Dec 2005) | 3 lines

Merged revisions 7519 via svnmerge from
/branches/1.2

................
r7522 | tilghman | 2005-12-19 00:42:55 -0500 (Mon, 19 Dec 2005) | 3 lines

Merged revisions 7521 via svnmerge from
/branches/1.2

................
r7524 | tilghman | 2005-12-19 14:08:42 -0500 (Mon, 19 Dec 2005) | 3 lines

Merged revisions 7523 via svnmerge from
/branches/1.2

................
r7528 | russell | 2005-12-19 18:41:53 -0500 (Mon, 19 Dec 2005) | 4 lines

- add note on required values of sip_methods struct
- remove duplicate function prototype
- remove duplicate ast_mutex_lock (issue #6025)

................
r7538 | russell | 2005-12-20 02:45:05 -0500 (Tue, 20 Dec 2005) | 3 lines

allow forcing the build to exclude PRI support using WITHOUT_PRI, similar to
how we already have WITHOUT_ZAPTEL (issue #5985)

................
r7539 | russell | 2005-12-20 03:16:53 -0500 (Tue, 20 Dec 2005) | 2 lines

use the system libgsm if available (issue #5434, modified to still work with builtin libgsm)

................
r7540 | markster | 2005-12-20 04:39:31 -0500 (Tue, 20 Dec 2005) | 2 lines

Fix reload of peer contexts (bug #6007)

................
r7541 | markster | 2005-12-20 04:56:55 -0500 (Tue, 20 Dec 2005) | 2 lines

Fix segfault on directed pickup when no CDR is available (bug #5998)

................
r7542 | markster | 2005-12-20 05:26:53 -0500 (Tue, 20 Dec 2005) | 2 lines

Fix choppy audio with > 20ms audio frames (bug #5697)

................
r7547 | markster | 2005-12-20 08:07:02 -0500 (Tue, 20 Dec 2005) | 3 lines

Major peformance improvements to meetme


................
r7548 | markster | 2005-12-20 09:14:01 -0500 (Tue, 20 Dec 2005) | 2 lines

Don't bother decode on muted participants

................
r7551 | markster | 2005-12-20 12:52:31 -0500 (Tue, 20 Dec 2005) | 3 lines

Major RTP fixes for using inbound SDP on outbound connection, get rid of 
old local rtp stuff...

................

Modified:
    team/russell/agent_function/   (props changed)
    team/russell/agent_function/apps/app_chanspy.c
    team/russell/agent_function/apps/app_dial.c
    team/russell/agent_function/apps/app_directed_pickup.c
    team/russell/agent_function/apps/app_meetme.c
    team/russell/agent_function/build_tools/make_svn_branch_name
    team/russell/agent_function/cdr.c
    team/russell/agent_function/channel.c
    team/russell/agent_function/channels/Makefile
    team/russell/agent_function/channels/chan_iax2.c
    team/russell/agent_function/channels/chan_mgcp.c
    team/russell/agent_function/channels/chan_sip.c
    team/russell/agent_function/codecs/Makefile
    team/russell/agent_function/codecs/codec_gsm.c
    team/russell/agent_function/doc/README.ael
    team/russell/agent_function/file.c
    team/russell/agent_function/frame.c
    team/russell/agent_function/include/asterisk/channel.h
    team/russell/agent_function/include/asterisk/frame.h
    team/russell/agent_function/include/asterisk/linkedlists.h
    team/russell/agent_function/include/asterisk/rtp.h
    team/russell/agent_function/rtp.c

Propchange: team/russell/agent_function/
------------------------------------------------------------------------------
    svnmerge-blocked = /branches/1.2:7497

Propchange: team/russell/agent_function/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Dec 20 13:45:22 2005
@@ -1,1 +1,1 @@
-/trunk:1-7506
+/trunk:1-7552

Modified: team/russell/agent_function/apps/app_chanspy.c
URL: http://svn.digium.com/view/asterisk/team/russell/agent_function/apps/app_chanspy.c?rev=7553&r1=7552&r2=7553&view=diff
==============================================================================
--- team/russell/agent_function/apps/app_chanspy.c (original)
+++ team/russell/agent_function/apps/app_chanspy.c Tue Dec 20 13:45:22 2005
@@ -482,7 +482,7 @@
 					}
 				}
 				
-				if (igrp && (!spec || ((strlen(spec) < strlen(peer->name) &&
+				if (igrp && (!spec || ((strlen(spec) <= strlen(peer->name) &&
 							!strncasecmp(peer->name, spec, strlen(spec)))))) {
 					if (peer && (!bronly || ast_bridged_channel(peer)) &&
 					    !ast_check_hangup(peer) && !ast_test_flag(peer, AST_FLAG_SPYING)) {

Modified: team/russell/agent_function/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/russell/agent_function/apps/app_dial.c?rev=7553&r1=7552&r2=7553&view=diff
==============================================================================
--- team/russell/agent_function/apps/app_dial.c (original)
+++ team/russell/agent_function/apps/app_dial.c Tue Dec 20 13:45:22 2005
@@ -53,6 +53,7 @@
 #include "asterisk/utils.h"
 #include "asterisk/app.h"
 #include "asterisk/causes.h"
+#include "asterisk/rtp.h"
 #include "asterisk/manager.h"
 #include "asterisk/privacy.h"
 
@@ -310,7 +311,7 @@
 } while (0)
 
 
-static int onedigit_goto(struct ast_channel *chan, char *context, char exten, int pri) 
+static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri) 
 {
 	char rexten[2] = { exten, '\0' };
 
@@ -380,7 +381,7 @@
 	int pos;
 	int single;
 	struct ast_channel *winner;
-	char *context = NULL;
+	const char *context = NULL;
 	char cidname[AST_MAX_EXTENSION];
 
 	single = (outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK));
@@ -475,6 +476,7 @@
 						ast_clear_flag(o, DIAL_STILLGOING);	
 						HANDLE_CAUSE(cause, in);
 					} else {
+						ast_rtp_make_compatible(o->chan, in);
 						if (o->chan->cid.cid_num)
 							free(o->chan->cid.cid_num);
 						o->chan->cid.cid_num = NULL;
@@ -744,16 +746,17 @@
 	long timelimit = 0;
 	long play_warning = 0;
 	long warning_freq=0;
-	char *warning_sound=NULL;
-	char *end_sound=NULL;
-	char *start_sound=NULL;
+	const char *warning_sound=NULL;
+	const char *end_sound=NULL;
+	const char *start_sound=NULL;
 	char *dtmfcalled=NULL, *dtmfcalling=NULL;
-	char *var;
+	const char *var;
 	char status[256];
 	int play_to_caller=0,play_to_callee=0;
 	int sentringing=0, moh=0;
-	char *outbound_group = NULL;
-	char *macro_result = NULL, *macro_transfer_dest = NULL;
+	const char *outbound_group = NULL;
+	const char *macro_result = NULL;
+	char *macro_transfer_dest = NULL;
 	int digit = 0, result = 0;
 	time_t start_time, answer_time, end_time;
 	struct ast_app *app = NULL;
@@ -1052,6 +1055,9 @@
 			}
 		}
 
+		/* Setup outgoing SDP to match incoming one */
+		ast_rtp_make_compatible(tmp->chan, chan);
+		
 		/* Inherit specially named variables from parent channel */
 		ast_channel_inherit_variables(chan, tmp->chan);
 
@@ -1190,7 +1196,7 @@
 		if (peer->name)
 			pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
 
-		number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
+		number = (char *)pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
 		if (!number)
 			number = numsubst;
 		pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
@@ -1602,7 +1608,8 @@
 
 static int retrydial_exec(struct ast_channel *chan, void *data)
 {
-	char *announce = NULL, *context = NULL, *dialdata = NULL;
+	char *announce = NULL, *dialdata = NULL;
+	const char *context = NULL;
 	int sleep = 0, loops = 0, res = 0;
 	struct localuser *u;
 	struct ast_flags peerflags;

Modified: team/russell/agent_function/apps/app_directed_pickup.c
URL: http://svn.digium.com/view/asterisk/team/russell/agent_function/apps/app_directed_pickup.c?rev=7553&r1=7552&r2=7553&view=diff
==============================================================================
--- team/russell/agent_function/apps/app_directed_pickup.c (original)
+++ team/russell/agent_function/apps/app_directed_pickup.c Tue Dec 20 13:45:22 2005
@@ -77,7 +77,7 @@
 
 	/* Find a channel to pickup */
 	origin = ast_get_channel_by_exten_locked(exten, context);
-	if (origin) {
+	if (origin && origin->cdr) {
 		ast_cdr_getvar(origin->cdr, "dstchannel", &tmp, workspace,
 			       sizeof(workspace), 0);
 		if (tmp) {
@@ -89,6 +89,8 @@
 		}
 		ast_mutex_unlock(&origin->lock);
 	} else {
+		if (origin)
+			ast_mutex_unlock(&origin->lock);
 		ast_log(LOG_DEBUG, "No originating channel found.\n");
 	}
 	

Modified: team/russell/agent_function/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/russell/agent_function/apps/app_meetme.c?rev=7553&r1=7552&r2=7553&view=diff
==============================================================================
--- team/russell/agent_function/apps/app_meetme.c (original)
+++ team/russell/agent_function/apps/app_meetme.c Tue Dec 20 13:45:22 2005
@@ -54,6 +54,8 @@
 #include "asterisk/cli.h"
 #include "asterisk/say.h"
 #include "asterisk/utils.h"
+#include "asterisk/translate.h"
+#include "asterisk/ulaw.h"
 
 static const char *tdesc = "MeetMe conference bridge";
 
@@ -95,6 +97,10 @@
 "      's' -- Present menu (user or admin) when '*' is received ('send' to menu)\n"
 "      't' -- set talk only mode. (Talk only, no listening)\n"
 "      'T' -- set talker detection (sent to manager interface and meetme list)\n"
+"      'o' -- set talker optimization - treats talkers who aren't speaking as\n"
+"             being muted, meaning (a) No encode is done on transmission and\n"
+"             (b) Received audio that is not registered as talking is omitted\n"
+"             causing no buildup in background noise\n"
 "      'v' -- video mode\n"
 "      'w' -- wait until the marked user enters the conference\n"
 "      'x' -- close the conference when last marked user exits\n"
@@ -129,6 +135,8 @@
 LOCAL_USER_DECL;
 
 static struct ast_conference {
+	ast_mutex_t playlock;				/* Conference specific lock (players) */
+	ast_mutex_t listenlock;				/* Conference specific lock (listeners) */
 	char confno[AST_MAX_EXTENSION];		/* Conference */
 	struct ast_channel *chan;		/* Announcements channel */
 	int fd;					/* Announcements fd */
@@ -147,6 +155,9 @@
 	const char *recordingformat;			/* Format to record the Conference in */
 	char pin[AST_MAX_EXTENSION];		/* If protected by a PIN */
 	char pinadmin[AST_MAX_EXTENSION];	/* If protected by a admin PIN */
+	struct ast_frame *transframe[32];
+	struct ast_frame *origframe;
+	struct ast_trans_pvt *transpath[32];
 	struct ast_conference *next;
 } *confs;
 
@@ -182,6 +193,8 @@
 #define MEETME_DELAYDETECTTALK 		300
 #define MEETME_DELAYDETECTENDTALK 	1000
 
+#define AST_FRAME_BITS 32
+
 enum volume_action {
 	VOL_UP,
 	VOL_DOWN,
@@ -190,6 +203,7 @@
 AST_MUTEX_DEFINE_STATIC(conflock);
 
 static int admin_exec(struct ast_channel *chan, void *data);
+static struct ast_frame null_frame = { AST_FRAME_NULL, };
 
 static void *recordthread(void *args);
 
@@ -200,8 +214,9 @@
 #define LEAVE	1
 
 #define MEETME_RECORD_OFF	0
-#define MEETME_RECORD_ACTIVE	1
-#define MEETME_RECORD_TERMINATE	2
+#define MEETME_RECORD_STARTED	1
+#define MEETME_RECORD_ACTIVE	2
+#define MEETME_RECORD_TERMINATE	3
 
 #define CONF_SIZE 320
 
@@ -227,12 +242,14 @@
 #define CONFFLAG_EMPTYNOPIN (1 << 20)
 #define CONFFLAG_ALWAYSPROMPT (1 << 21)
 #define CONFFLAG_ANNOUNCEUSERCOUNT (1 << 22)	/* If set, when user joins the conference, they will be told the number of users that are already in */
+#define CONFFLAG_OPTIMIZETALKER (1 << 23)	/* If set, treats talking users as muted users */
 
 
 AST_APP_OPTIONS(meetme_opts, {
 	AST_APP_OPTION('a', CONFFLAG_ADMIN ),
 	AST_APP_OPTION('c', CONFFLAG_ANNOUNCEUSERCOUNT ),
 	AST_APP_OPTION('T', CONFFLAG_MONITORTALKER ),
+	AST_APP_OPTION('o', CONFFLAG_OPTIMIZETALKER ),
 	AST_APP_OPTION('i', CONFFLAG_INTROUSER ),
 	AST_APP_OPTION('m', CONFFLAG_MONITOR ),
 	AST_APP_OPTION('p', CONFFLAG_POUNDEXIT ),
@@ -263,14 +280,17 @@
 		return "(not talking)";
 }
 
-static int careful_write(int fd, unsigned char *data, int len)
+static int careful_write(int fd, unsigned char *data, int len, int block)
 {
 	int res;
 	int x;
 
 	while (len) {
-		x = ZT_IOMUX_WRITE | ZT_IOMUX_SIGEVENT;
-		res = ioctl(fd, ZT_IOMUX, &x);
+		if (block) {
+			x = ZT_IOMUX_WRITE | ZT_IOMUX_SIGEVENT;
+			res = ioctl(fd, ZT_IOMUX, &x);
+		} else
+			res = 0;
 		if (res >= 0)
 			res = write(fd, data, len);
 		if (res < 1) {
@@ -403,6 +423,8 @@
 	unsigned char *data;
 	int len;
 	int res = -1;
+	short *data2;
+	int x;
 
 	if (!chan->_softhangup)
 		res = ast_autoservice_start(chan);
@@ -422,8 +444,12 @@
 		data = NULL;
 		len = 0;
 	}
-	if (data) 
-		careful_write(conf->fd, data, len);
+	if (data) {
+		data2 = alloca(len * 2);
+		for (x=0;x<len;x++)
+			data2[x] = AST_MULAW(data[x]);
+		careful_write(conf->fd, (unsigned char *)data2, len << 1, 1);
+	}
 
 	ast_mutex_unlock(&conflock);
 
@@ -447,12 +473,16 @@
 		/* Make a new one */
 		cnf = calloc(1, sizeof(*cnf));
 		if (cnf) {
+			ast_mutex_init(&cnf->playlock);
+			ast_mutex_init(&cnf->listenlock);
 			ast_copy_string(cnf->confno, confno, sizeof(cnf->confno));
 			ast_copy_string(cnf->pin, pin, sizeof(cnf->pin));
 			ast_copy_string(cnf->pinadmin, pinadmin, sizeof(cnf->pinadmin));
 			cnf->markedusers = 0;
-			cnf->chan = ast_request("zap", AST_FORMAT_ULAW, "pseudo", NULL);
+			cnf->chan = ast_request("zap", AST_FORMAT_SLINEAR, "pseudo", NULL);
 			if (cnf->chan) {
+				ast_set_read_format(cnf->chan, AST_FORMAT_SLINEAR);
+				ast_set_write_format(cnf->chan, AST_FORMAT_SLINEAR);
 				cnf->fd = cnf->chan->fds[0];	/* for use by conf_play() */
 			} else {
 				ast_log(LOG_WARNING, "Unable to open pseudo channel - trying device\n");
@@ -479,6 +509,7 @@
 				cnf = NULL;
 				goto cnfout;
 			}
+
 			/* Fill the conference struct */
 			cnf->start = time(NULL);
 			cnf->zapconf = ztc.confno;
@@ -749,7 +780,8 @@
 static int conf_free(struct ast_conference *conf)
 {
 	struct ast_conference *prev = NULL, *cur = confs;
-
+	int x;
+	
 	while (cur) {
 		if (cur == conf) {
 			if (prev)
@@ -776,6 +808,14 @@
 		}
 	}
 
+	for (x=0;x<AST_FRAME_BITS;x++) {
+		if (conf->transframe[x])
+			ast_frfree(conf->transframe[x]);
+		if (conf->transpath[x])
+			ast_translator_free_path(conf->transpath[x]);
+		if (conf->origframe)
+			ast_frfree(conf->origframe);
+	}
 	if (conf->chan)
 		ast_hangup(conf->chan);
 	else
@@ -828,21 +868,26 @@
 		return ret;
 	}
 
-	if (confflags & CONFFLAG_RECORDCONF && conf->recording !=MEETME_RECORD_ACTIVE) {
-		conf->recordingfilename = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFILE");
+	if (confflags & CONFFLAG_RECORDCONF) {
 		if (!conf->recordingfilename) {
-			snprintf(recordingtmp, sizeof(recordingtmp), "meetme-conf-rec-%s-%s", conf->confno, chan->uniqueid);
-			conf->recordingfilename = ast_strdupa(recordingtmp);
-		}
-		conf->recordingformat = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFORMAT");
-		if (!conf->recordingformat) {
-			snprintf(recordingtmp, sizeof(recordingtmp), "wav");
-			conf->recordingformat = ast_strdupa(recordingtmp);
-		}
+			conf->recordingfilename = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFILE");
+			if (!conf->recordingfilename) {
+				snprintf(recordingtmp, sizeof(recordingtmp), "meetme-conf-rec-%s-%s", conf->confno, chan->uniqueid);
+				conf->recordingfilename = ast_strdupa(recordingtmp);
+			}
+			conf->recordingformat = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFORMAT");
+			if (!conf->recordingformat) {
+				snprintf(recordingtmp, sizeof(recordingtmp), "wav");
+				conf->recordingformat = ast_strdupa(recordingtmp);
+			}
+			ast_verbose(VERBOSE_PREFIX_4 "Starting recording of MeetMe Conference %s into file %s.%s.\n",
+				    conf->confno, conf->recordingfilename, conf->recordingformat);
+		}
+	}
+
+	if ((conf->recording == MEETME_RECORD_OFF) && ((confflags & CONFFLAG_RECORDCONF) || (conf->chan))) {
 		pthread_attr_init(&conf->attr);
 		pthread_attr_setdetachstate(&conf->attr, PTHREAD_CREATE_DETACHED);
-		ast_verbose(VERBOSE_PREFIX_4 "Starting recording of MeetMe Conference %s into file %s.%s.\n",
-			    conf->confno, conf->recordingfilename, conf->recordingformat);
 		ast_pthread_create(&conf->recordthread, &conf->attr, recordthread, conf);
 	}
 
@@ -858,7 +903,7 @@
 	if (confflags & CONFFLAG_MARKEDUSER)
 		conf->markedusers++;
       
-   	ast_mutex_lock(&conflock);
+   	ast_mutex_lock(&conf->playlock);
 	if (!conf->firstuser) {
 		/* Fill the first new User struct */
 		user->user_no = 1;
@@ -870,7 +915,7 @@
 		user->prevuser = conf->lastuser;
 		if (conf->lastuser->nextuser) {
 			ast_log(LOG_WARNING, "Error in User Management!\n");
-			ast_mutex_unlock(&conflock);
+			ast_mutex_unlock(&conf->playlock);
 			goto outrun;
 		} else {
 			conf->lastuser->nextuser = user;
@@ -883,7 +928,7 @@
 	user->adminflags = 0;
 	user->talking = -1;
 	conf->users++;
-	ast_mutex_unlock(&conflock);
+	ast_mutex_unlock(&conf->playlock);
 
 	if (confflags & CONFFLAG_EXIT_CONTEXT) {
 		if ((agifile = pbx_builtin_getvar_helper(chan, "MEETME_EXIT_CONTEXT"))) 
@@ -1026,7 +1071,7 @@
 	ztc.chan = 0;	
 	ztc.confno = conf->zapconf;
 
-	ast_mutex_lock(&conflock);
+	ast_mutex_lock(&conf->playlock);
 
 	if (!(confflags & CONFFLAG_QUIET) && (confflags & CONFFLAG_INTROUSER) && conf->users > 1) {
 		if (conf->chan && ast_fileexists(user->namerecloc, NULL, NULL)) {
@@ -1047,7 +1092,7 @@
 	if (ioctl(fd, ZT_SETCONF, &ztc)) {
 		ast_log(LOG_WARNING, "Error setting conference\n");
 		close(fd);
-		ast_mutex_unlock(&conflock);
+		ast_mutex_unlock(&conf->playlock);
 		goto outrun;
 	}
 	ast_log(LOG_DEBUG, "Placed channel %s in ZAP conf %d\n", chan->name, conf->zapconf);
@@ -1066,7 +1111,7 @@
 				conf_play(chan, conf, ENTER);
 	}
 
-	ast_mutex_unlock(&conflock);
+	ast_mutex_unlock(&conf->playlock);
 
 	conf_flush(fd, chan);
 
@@ -1103,7 +1148,7 @@
 			x = 1;
 			ast_channel_setoption(chan, AST_OPTION_TONE_VERIFY, &x, sizeof(char), 0);
 		}	
-		if (confflags & CONFFLAG_MONITORTALKER && !(dsp = ast_dsp_new())) {
+		if (confflags & (CONFFLAG_MONITORTALKER | CONFFLAG_OPTIMIZETALKER) && !(dsp = ast_dsp_new())) {
 			ast_log(LOG_WARNING, "Unable to allocate DSP!\n");
 			res = -1;
 		}
@@ -1142,6 +1187,7 @@
 			}
 
 			c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
+			
 			
 			/* Update the struct with the actual confflags */
 			user->userflags = confflags;
@@ -1266,14 +1312,17 @@
 					user->zapchannel = !retryzap;
 					goto zapretry;
 				}
-				f = ast_read(c);
+				if ((confflags & CONFFLAG_MONITOR) || (user->adminflags & ADMINFLAG_MUTED))
+					f = ast_read_noaudio(c);
+				else
+					f = ast_read(c);
 				if (!f)
 					break;
 				if ((f->frametype == AST_FRAME_VOICE) && (f->subclass == AST_FORMAT_SLINEAR)) {
 					if (user->talk.actual)
 						ast_frame_adjust_volume(f, user->talk.actual);
 
-					if (confflags &  CONFFLAG_MONITORTALKER) {
+					if (confflags & (CONFFLAG_MONITORTALKER | CONFFLAG_OPTIMIZETALKER)) {
 						int totalsilence;
 
 						if (user->talking == -1)
@@ -1282,7 +1331,8 @@
 						res = ast_dsp_silence(dsp, f, &totalsilence);
 						if (!user->talking && totalsilence < MEETME_DELAYDETECTTALK) {
 							user->talking = 1;
-							manager_event(EVENT_FLAG_CALL, "MeetmeTalking",
+							if (confflags & CONFFLAG_MONITORTALKER)
+								manager_event(EVENT_FLAG_CALL, "MeetmeTalking",
 								      "Channel: %s\r\n"
 								      "Uniqueid: %s\r\n"
 								      "Meetme: %s\r\n"
@@ -1291,7 +1341,8 @@
 						}
 						if (user->talking && totalsilence > MEETME_DELAYDETECTENDTALK) {
 							user->talking = 0;
-							manager_event(EVENT_FLAG_CALL, "MeetmeStopTalking",
+							if (confflags & CONFFLAG_MONITORTALKER)
+								manager_event(EVENT_FLAG_CALL, "MeetmeStopTalking",
 								      "Channel: %s\r\n"
 								      "Uniqueid: %s\r\n"
 								      "Meetme: %s\r\n"
@@ -1308,7 +1359,12 @@
 						   audio frames (in which case carefully writing would only
 						   have delayed the audio even further).
 						*/
-						write(fd, f->data, f->datalen);
+						/* As it turns out, we do want to use careful write.  We just
+						   don't want to block, but we do want to at least *try*
+						   to write out all the samples.
+						 */
+						if (user->talking || !(confflags & CONFFLAG_OPTIMIZETALKER))
+							careful_write(fd, f->data, f->datalen, 0);
 					}
 				} else if ((f->frametype == AST_FRAME_DTMF) && (confflags & CONFFLAG_EXIT_CONTEXT)) {
 					char tmp[2];
@@ -1504,10 +1560,46 @@
 					fr.samples = res/2;
 					fr.data = buf;
 					fr.offset = AST_FRIENDLY_OFFSET;
-					if (user->listen.actual)
-						ast_frame_adjust_volume(&fr, user->listen.actual);
-					if (ast_write(chan, &fr) < 0) {
-						ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno));
+					if (!user->listen.actual && 
+						((confflags & CONFFLAG_MONITOR) || 
+						 (user->adminflags & ADMINFLAG_MUTED) ||
+						 (user->talking && (confflags & CONFFLAG_OPTIMIZETALKER))
+						 )) {
+						int index;
+						for (index=0;index<AST_FRAME_BITS;index++)
+							if (chan->rawwriteformat & (1 << index))
+								break;
+						if (index >= AST_FRAME_BITS)
+							goto bailoutandtrynormal;
+						ast_mutex_lock(&conf->listenlock);
+						if (!conf->transframe[index]) {
+							if (conf->origframe) {
+								if (!conf->transpath[index])
+									conf->transpath[index] = ast_translator_build_path((1 << index), AST_FORMAT_SLINEAR);
+								if (conf->transpath[index]) {
+									conf->transframe[index] = ast_translate(conf->transpath[index], conf->origframe, 0);
+									if (!conf->transframe[index])
+										conf->transframe[index] = &null_frame;
+								}
+							}
+						}
+						if (conf->transframe[index]) {
+ 							if (conf->transframe[index]->frametype != AST_FRAME_NULL) {
+	 							if (ast_write(chan, conf->transframe[index]))
+									ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno));
+							}
+						} else {
+							ast_mutex_unlock(&conf->listenlock);
+							goto bailoutandtrynormal;
+						}
+						ast_mutex_unlock(&conf->listenlock);
+					} else {
+bailoutandtrynormal:					
+						if (user->listen.actual)
+							ast_frame_adjust_volume(&fr, user->listen.actual);
+						if (ast_write(chan, &fr) < 0) {
+							ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno));
+						}
 					}
 				} else 
 					ast_log(LOG_WARNING, "Failed to read frame: %s\n", strerror(errno));
@@ -1549,7 +1641,7 @@
  outrun:
 	ast_mutex_lock(&conflock);
 
-	if (confflags & CONFFLAG_MONITORTALKER && dsp)
+	if (dsp)
 		ast_dsp_free(dsp);
 	
 	if (user->user_no) { /* Only cleanup users who really joined! */
@@ -1991,15 +2083,16 @@
 	return res;
 }
 
-static struct ast_conf_user* find_user(struct ast_conference *conf, char *callerident) {
+static struct ast_conf_user* find_user(struct ast_conference *conf, char *callerident) 
+{
 	struct ast_conf_user *user = NULL;
-	char usrno[1024] = "";
-
+	int cid;
+	
+	sscanf(callerident, "%i", &cid);
 	if (conf && callerident) {
 		user = conf->firstuser;
 		while (user) {
-			snprintf(usrno, sizeof(usrno), "%d", user->user_no);
-			if (strcmp(usrno, callerident) == 0)
+			if (cid == user->user_no)
 				return user;
 			user = user->nextuser;
 		}
@@ -2093,7 +2186,7 @@
 				if (user && (user->adminflags & ADMINFLAG_MUTED)) {
 					user->adminflags ^= ADMINFLAG_MUTED;
 				} else {
-					ast_log(LOG_NOTICE, "Specified User not found or he muted himself!");
+					ast_log(LOG_NOTICE, "Specified User not found or he muted himself!\n");
 				}
 				break;
 			case  110: /* n: Unmute all users */
@@ -2133,39 +2226,62 @@
 	struct ast_conference *cnf = args;
 	struct ast_frame *f=NULL;
 	int flags;
-	struct ast_filestream *s;
+	struct ast_filestream *s=NULL;
 	int res=0;
+	int x;
+	const char *oldrecordingfilename = NULL;
 
 	if (!cnf || !cnf->chan) {
 		pthread_exit(0);
 	}
+
 	ast_stopstream(cnf->chan);
 	flags = O_CREAT|O_TRUNC|O_WRONLY;
-	s = ast_writefile(cnf->recordingfilename, cnf->recordingformat, NULL, flags, 0, 0644);
-
-	if (s) {
-		cnf->recording = MEETME_RECORD_ACTIVE;
-		while (ast_waitfor(cnf->chan, -1) > -1) {
-			f = ast_read(cnf->chan);
-			if (!f) {
-				res = -1;
+
+
+	cnf->recording = MEETME_RECORD_ACTIVE;
+	while (ast_waitfor(cnf->chan, -1) > -1) {
+		if (cnf->recording == MEETME_RECORD_TERMINATE) {
+			ast_mutex_lock(&conflock);
+			ast_mutex_unlock(&conflock);
+			break;
+		}
+		if (!s && cnf->recordingfilename && (cnf->recordingfilename != oldrecordingfilename)) {
+			s = ast_writefile(cnf->recordingfilename, cnf->recordingformat, NULL, flags, 0, 0644);
+			oldrecordingfilename = cnf->recordingfilename;
+		}
+		
+		f = ast_read(cnf->chan);
+		if (!f) {
+			res = -1;
+			break;
+		}
+		if (f->frametype == AST_FRAME_VOICE) {
+			ast_mutex_lock(&cnf->listenlock);
+			for (x=0;x<AST_FRAME_BITS;x++) {
+				/* Free any translations that have occured */
+				if (cnf->transframe[x]) {
+					ast_frfree(cnf->transframe[x]);
+					cnf->transframe[x] = NULL;
+				}
+				if (cnf->origframe)
+					ast_frfree(cnf->origframe);
+				cnf->origframe = f;
+			}
+			ast_mutex_unlock(&cnf->listenlock);
+			if (s)
+				res = ast_writestream(s, f);
+			if (res) {
+				ast_frfree(f);
 				break;
 			}
-			if (f->frametype == AST_FRAME_VOICE) {
-				res = ast_writestream(s, f);
-				if (res) 
-					break;
-			}
-			ast_frfree(f);
-			if (cnf->recording == MEETME_RECORD_TERMINATE) {
-				ast_mutex_lock(&conflock);
-				ast_mutex_unlock(&conflock);
-				break;
-			}
-		}
-		cnf->recording = MEETME_RECORD_OFF;
+		}
+		ast_frfree(f);
+	}
+	cnf->recording = MEETME_RECORD_OFF;
+	if (s)
 		ast_closestream(s);
-	}
+	
 	pthread_exit(0);
 }
 

Modified: team/russell/agent_function/build_tools/make_svn_branch_name
URL: http://svn.digium.com/view/asterisk/team/russell/agent_function/build_tools/make_svn_branch_name?rev=7553&r1=7552&r2=7553&view=diff
==============================================================================
--- team/russell/agent_function/build_tools/make_svn_branch_name (original)
+++ team/russell/agent_function/build_tools/make_svn_branch_name Tue Dec 20 13:45:22 2005
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-PARTS=`LANG=C svn info | grep URL | awk '{print $2;}' | sed -e s:^.*/svn/asterisk/:: | sed -e 's:/: :'`
+PARTS=`LANG=C svn info | grep URL | awk '{print $2;}' | sed -e s:^.*/svn/asterisk/:: | sed -e 's:/: :g'`
 BRANCH=0
 TEAM=0
 
@@ -47,4 +47,4 @@
   fi
 done
 
-echo ${RESULT}-r${REV}
+echo ${RESULT##-}-r${REV}

Modified: team/russell/agent_function/cdr.c
URL: http://svn.digium.com/view/asterisk/team/russell/agent_function/cdr.c?rev=7553&r1=7552&r2=7553&view=diff
==============================================================================
--- team/russell/agent_function/cdr.c (original)
+++ team/russell/agent_function/cdr.c Tue Dec 20 13:45:22 2005
@@ -691,12 +691,15 @@
 
 int ast_cdr_setamaflags(struct ast_channel *chan, const char *flag)
 {
-	struct ast_cdr *cdr = chan->cdr;
+	struct ast_cdr *cdr;
 	int newflag;
 
 	newflag = ast_cdr_amaflags2int(flag);
-	if (newflag)
-		cdr->amaflags = newflag;
+	if (newflag) {
+		for (cdr = chan->cdr; cdr; cdr = cdr->next) {
+			cdr->amaflags = newflag;
+		}
+	}
 
 	return 0;
 }

Modified: team/russell/agent_function/channel.c
URL: http://svn.digium.com/view/asterisk/team/russell/agent_function/channel.c?rev=7553&r1=7552&r2=7553&view=diff
==============================================================================
--- team/russell/agent_function/channel.c (original)
+++ team/russell/agent_function/channel.c Tue Dec 20 13:45:22 2005
@@ -1773,7 +1773,7 @@
 	return 0; /* Time is up */
 }
 
-struct ast_frame *ast_read(struct ast_channel *chan)
+static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
 {
 	struct ast_frame *f = NULL;
 	int blah;
@@ -1897,7 +1897,10 @@
 
 
 	if (f && (f->frametype == AST_FRAME_VOICE)) {
-		if (!(f->subclass & chan->nativeformats)) {
+		if (dropaudio) {
+			ast_frfree(f);
+			f = &null_frame;
+		} else if (!(f->subclass & chan->nativeformats)) {
 			/* This frame can't be from the current native formats -- drop it on the
 			   floor */
 			ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n", chan->name, ast_getformatname(f->subclass), ast_getformatname(chan->nativeformats));
@@ -1996,6 +1999,16 @@
 		chan->fin++;
 	ast_mutex_unlock(&chan->lock);
 	return f;
+}
+
+struct ast_frame *ast_read(struct ast_channel *chan)
+{
+	return __ast_read(chan, 0);
+}
+
+struct ast_frame *ast_read_noaudio(struct ast_channel *chan)
+{
+	return __ast_read(chan, 1);
 }
 
 int ast_indicate(struct ast_channel *chan, int condition)
@@ -2247,7 +2260,12 @@
 		break;
 	default:
 		if (chan->tech->write) {
-			f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
+			/* Bypass translator if we're writing format in the raw write format.  This
+			   allows mixing of native / non-native formats */
+			if (fr->subclass == chan->rawwriteformat)
+				f = fr;
+			else
+				f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
 			if (f) {
 				if (f->frametype == AST_FRAME_VOICE && chan->spies)
 					queue_frame_to_spies(chan, f, SPY_WRITE);

Modified: team/russell/agent_function/channels/Makefile
URL: http://svn.digium.com/view/asterisk/team/russell/agent_function/channels/Makefile?rev=7553&r1=7552&r2=7553&view=diff
==============================================================================
--- team/russell/agent_function/channels/Makefile (original)
+++ team/russell/agent_function/channels/Makefile Tue Dec 20 13:45:22 2005
@@ -92,10 +92,12 @@
   CHANNEL_LIBS+=chan_alsa.so
 endif
 
+ifndef WITHOUT_PRI
 ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/lib/libpri.so.1)$(wildcard $(CROSS_COMPILE_TARGET)/usr/local/lib/libpri.so.1),)
   CFLAGS+=-DZAPATA_PRI
   ZAPPRI=-lpri
 endif
+endif # WITHOUT_PRI
 
 ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/lib/libmfcr2.so.1)$(wildcard $(CROSS_COMPILE_TARGET)/usr/local/lib/libmfcr2.so.1),)
   CFLAGS+=-DZAPATA_R2

Modified: team/russell/agent_function/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/russell/agent_function/channels/chan_iax2.c?rev=7553&r1=7552&r2=7553&view=diff
==============================================================================
--- team/russell/agent_function/channels/chan_iax2.c (original)
+++ team/russell/agent_function/channels/chan_iax2.c Tue Dec 20 13:45:22 2005
@@ -8147,6 +8147,7 @@
 		peer->smoothing = 0;
 		peer->pokefreqok = DEFAULT_FREQ_OK;
 		peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
+		peer->context[0] = '\0';
 		while(v) {
 			if (!strcasecmp(v->name, "secret")) {
 				if (!ast_strlen_zero(peer->secret)) {

Modified: team/russell/agent_function/channels/chan_mgcp.c
URL: http://svn.digium.com/view/asterisk/team/russell/agent_function/channels/chan_mgcp.c?rev=7553&r1=7552&r2=7553&view=diff
==============================================================================
--- team/russell/agent_function/channels/chan_mgcp.c (original)
+++ team/russell/agent_function/channels/chan_mgcp.c Tue Dec 20 13:45:22 2005
@@ -2095,7 +2095,6 @@
 	add_header(&resp, "X", sub->txident);
 	add_header(&resp, "I", sub->cxident);
 	/*add_header(&resp, "S", "");*/
-	ast_rtp_offered_from_local(sub->rtp, 0);
 	add_sdp(&resp, sub, rtp);
 	/* SC: fill in new fields */
 	resp.cmd = MGCP_CMD_MDCX;
@@ -2129,7 +2128,6 @@
 	/* SC: X header should not be sent. kept for compatibility */
 	add_header(&resp, "X", sub->txident);
 	/*add_header(&resp, "S", "");*/
-	ast_rtp_offered_from_local(sub->rtp, 1);
 	add_sdp(&resp, sub, rtp);
 	/* SC: fill in new fields */
 	resp.cmd = MGCP_CMD_CRCX;
@@ -3948,7 +3946,7 @@
 	/* XXX Is there such thing as video support with MGCP? XXX */
 	struct mgcp_subchannel *sub;
 	sub = chan->tech_pvt;
-	if (sub) {
+	if (sub && !sub->alreadygone) {
 		transmit_modify_with_sdp(sub, rtp, codecs);
 		return 0;
 	}

Modified: team/russell/agent_function/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/russell/agent_function/channels/chan_sip.c?rev=7553&r1=7552&r2=7553&view=diff
==============================================================================
--- team/russell/agent_function/channels/chan_sip.c (original)
+++ team/russell/agent_function/channels/chan_sip.c Tue Dec 20 13:45:22 2005
@@ -202,6 +202,7 @@
 	WWW_AUTH,
 };
 
+/*! XXX Note that sip_methods[i].id == i must hold or the code breaks */
 static const struct  cfsip_methods { 
 	enum sipmethod id;
 	int need_rtp;		/*!< when this is the 'primary' use for a pvt structure, does it need RTP? */
@@ -878,7 +879,6 @@
 static struct sip_auth *authl;          /*!< Authentication list */
 
 
-static struct ast_frame  *sip_read(struct ast_channel *ast);
 static int transmit_response(struct sip_pvt *p, char *msg, struct sip_request *req);
 static int transmit_response_with_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, int retrans);
 static int transmit_response_with_unsupported(struct sip_pvt *p, char *msg, struct sip_request *req, char *unsupported);
@@ -2734,7 +2734,6 @@
 	tmp->tech = &sip_tech;
 	/* Select our native format based on codec preference until we receive
 	   something from another device to the contrary. */
-	ast_mutex_lock(&i->lock);
 	if (i->jointcapability)
 		tmp->nativeformats = ast_codec_choose(&i->prefs, i->jointcapability, 1);
 	else if (i->capability)
@@ -3993,7 +3992,6 @@
 	copy_header(resp, req, "CSeq");
 	add_header(resp, "User-Agent", default_useragent);
 	add_header(resp, "Allow", ALLOWED_METHODS);
-	add_header(resp, "Max-Forwards", DEFAULT_MAX_FORWARDS);
 	if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) {
 		/* For registration responses, we also need expiry and
 		   contact info */
@@ -4511,7 +4509,6 @@
 	}
 	respprep(&resp, p, msg, req);
 	if (p->rtp) {
-		ast_rtp_offered_from_local(p->rtp, 0);
 		add_sdp(&resp, p);
 	} else {
 		ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
@@ -4585,7 +4582,6 @@
 	add_header(&req, "Allow", ALLOWED_METHODS);
 	if (sipdebug)
 		add_header(&req, "X-asterisk-info", "SIP re-invite (RTP bridge)");
-	ast_rtp_offered_from_local(p->rtp, 1);
 	add_sdp(&req, p);
 	/* Use this as the basis */
 	copy_request(&p->initreq, &req);
@@ -4926,7 +4922,6 @@
 		}
 	}
 	if (sdp && p->rtp) {
-		ast_rtp_offered_from_local(p->rtp, 1);
 		add_sdp(&req, p);
 	} else {
 		add_header_contentLength(&req, 0);
@@ -10799,12 +10794,40 @@
 			ast_set_flag(p, SIP_NEEDDESTROY);	
 			return 0;
 		} else {
+			struct sip_pvt *p_old;
+
 			transmit_response(p, "200 OK", req);
 			transmit_state_notify(p, firststate, 1, 1);	/* Send first notification */
 			append_history(p, "Subscribestatus", ast_extension_state2str(firststate));
+
+			/* remove any old subscription from this peer for the same exten/context,
+			   as the peer has obviously forgotten about it and it's wasteful to wait
+			   for it to expire and send NOTIFY messages to the peer only to have them
+			   ignored (or generate errors)
+			*/
+			ast_mutex_lock(&iflock);
+			for (p_old = iflist; p_old; p_old = p_old->next) {
+				if (p_old == p)
+					continue;
+				if (p_old->initreq.method != SIP_SUBSCRIBE)
+					continue;
+				if (p_old->subscribed == NONE)
+					continue;
+				ast_mutex_lock(&p_old->lock);
+				if (!strcmp(p_old->username, p->username)) {
+					if (!strcmp(p_old->exten, p->exten) &&
+					    !strcmp(p_old->context, p->context)) {
+						ast_set_flag(p_old, SIP_NEEDDESTROY);
+						ast_mutex_unlock(&p_old->lock);
+						break;
+					}
+				}
+				ast_mutex_unlock(&p_old->lock);
+			}
+			ast_mutex_unlock(&iflock);
 		}
 		if (!p->expiry)
-			ast_set_flag(p, SIP_NEEDDESTROY);	
+			ast_set_flag(p, SIP_NEEDDESTROY);
 	}
 	return 1;
 }
@@ -12665,6 +12688,11 @@
 	if (!p) 
 		return -1;
 	ast_mutex_lock(&p->lock);
+	if (ast_test_flag(p, SIP_ALREADYGONE)) {
+		/* If we're destroyed, don't bother */
+		ast_mutex_unlock(&p->lock);
+		return 0;
+	}
 	if (rtp)
 		ast_rtp_get_peer(rtp, &p->redirip);
 	else

Modified: team/russell/agent_function/codecs/Makefile
URL: http://svn.digium.com/view/asterisk/team/russell/agent_function/codecs/Makefile?rev=7553&r1=7552&r2=7553&view=diff
==============================================================================
--- team/russell/agent_function/codecs/Makefile (original)
+++ team/russell/agent_function/codecs/Makefile Tue Dec 20 13:45:22 2005
@@ -60,8 +60,18 @@
 endif
 
 
+LIBGSM_PATH:=/usr/local/include /usr/include
+LIBGSM_SYSTEM_HEADERS:=$(wildcard $(LIBGSM_PATH:%=$(CROSS_COMPILE_TARGET)%/gsm/gsm.h))
+ifneq (,$(LIBGSM_SYSTEM_HEADERS))
+LIBGSM=-lgsm
+LIBGSMT=
+CFLAGS+=-DUSE_EXTERNAL_GSM_LIB
+else
 LIBGSM=gsm/lib/libgsm.a
-LIBGSMT=gsm/lib/libgsm.a
+LIBGSMT=$(LIBGSM)
+CFLAGS+=-I.
+endif
+
 LIBLPC10=lpc10/liblpc10.a
 
 ifeq ($(findstring BSD,${OSARCH}),BSD)

Modified: team/russell/agent_function/codecs/codec_gsm.c
URL: http://svn.digium.com/view/asterisk/team/russell/agent_function/codecs/codec_gsm.c?rev=7553&r1=7552&r2=7553&view=diff
==============================================================================
--- team/russell/agent_function/codecs/codec_gsm.c (original)
+++ team/russell/agent_function/codecs/codec_gsm.c Tue Dec 20 13:45:22 2005
@@ -45,7 +45,12 @@
 #include "asterisk/logger.h"
 #include "asterisk/channel.h"
 
+#ifdef USE_EXTERNAL_GSM_LIB
+#include <gsm/gsm.h>
+#else
 #include "gsm/inc/gsm.h"
+#endif
+
 #include "../formats/msgsm.h"
 
 /* Sample frame data */

Modified: team/russell/agent_function/doc/README.ael
URL: http://svn.digium.com/view/asterisk/team/russell/agent_function/doc/README.ael?rev=7553&r1=7552&r2=7553&view=diff
==============================================================================
--- team/russell/agent_function/doc/README.ael (original)
+++ team/russell/agent_function/doc/README.ael Tue Dec 20 13:45:22 2005
@@ -263,3 +263,11 @@
 	i => Playback(invalid);
 };
 
+
+Syntax Note
+------------------------
+Please note that all opening {'s are on the same line as the keyword.  For
+the time being, that syntax is mandatory.  We are looking at ways to allow
+other syntax in the future for flexibility, but for now, that is the way
+you must write AEL clauses.
+

Modified: team/russell/agent_function/file.c
URL: http://svn.digium.com/view/asterisk/team/russell/agent_function/file.c?rev=7553&r1=7552&r2=7553&view=diff

[... 330 lines stripped ...]


More information about the asterisk-commits mailing list