[asterisk-commits] oej: branch oej/codename-pineapple r53956 - in /team/oej/codename-pineapple: ...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Sun Feb 11 14:17:38 MST 2007


Author: oej
Date: Sun Feb 11 15:17:37 2007
New Revision: 53956

URL: http://svn.digium.com/view/asterisk?view=rev&rev=53956
Log:
Reset automerge

Added:
    team/oej/codename-pineapple/doc/queue.txt
      - copied unchanged from r53953, trunk/doc/queue.txt
    team/oej/codename-pineapple/doc/sla.txt
      - copied unchanged from r53953, trunk/doc/sla.txt
Modified:
    team/oej/codename-pineapple/   (props changed)
    team/oej/codename-pineapple/UPGRADE.txt
    team/oej/codename-pineapple/apps/app_adsiprog.c
    team/oej/codename-pineapple/apps/app_dial.c
    team/oej/codename-pineapple/apps/app_echo.c
    team/oej/codename-pineapple/apps/app_macro.c
    team/oej/codename-pineapple/apps/app_meetme.c
    team/oej/codename-pineapple/apps/app_playback.c
    team/oej/codename-pineapple/apps/app_queue.c
    team/oej/codename-pineapple/apps/app_setcallerid.c
    team/oej/codename-pineapple/apps/app_speech_utils.c
    team/oej/codename-pineapple/apps/app_userevent.c
    team/oej/codename-pineapple/apps/app_voicemail.c
    team/oej/codename-pineapple/build_tools/get_makeopts
    team/oej/codename-pineapple/build_tools/get_moduleinfo
    team/oej/codename-pineapple/channels/chan_gtalk.c
    team/oej/codename-pineapple/channels/chan_h323.c
    team/oej/codename-pineapple/channels/chan_iax2.c
    team/oej/codename-pineapple/channels/chan_jingle.c
    team/oej/codename-pineapple/channels/chan_mgcp.c
    team/oej/codename-pineapple/channels/chan_misdn.c
    team/oej/codename-pineapple/channels/chan_sip.c
    team/oej/codename-pineapple/channels/chan_skinny.c
    team/oej/codename-pineapple/channels/chan_zap.c
    team/oej/codename-pineapple/channels/h323/ast_h323.cxx
    team/oej/codename-pineapple/channels/misdn/isdn_lib.c
    team/oej/codename-pineapple/configs/sip.conf.sample
    team/oej/codename-pineapple/configs/sla.conf.sample
    team/oej/codename-pineapple/configure
    team/oej/codename-pineapple/configure.ac
    team/oej/codename-pineapple/doc/imapstorage.txt
    team/oej/codename-pineapple/funcs/func_callerid.c
    team/oej/codename-pineapple/funcs/func_odbc.c
    team/oej/codename-pineapple/include/asterisk/app.h
    team/oej/codename-pineapple/include/asterisk/dial.h
    team/oej/codename-pineapple/include/asterisk/utils.h
    team/oej/codename-pineapple/main/Makefile
    team/oej/codename-pineapple/main/acl.c
    team/oej/codename-pineapple/main/channel.c
    team/oej/codename-pineapple/main/config.c
    team/oej/codename-pineapple/main/db1-ast/Makefile
    team/oej/codename-pineapple/main/db1-ast/hash/hash.c
    team/oej/codename-pineapple/main/dial.c
    team/oej/codename-pineapple/main/io.c
    team/oej/codename-pineapple/main/loader.c
    team/oej/codename-pineapple/main/manager.c
    team/oej/codename-pineapple/main/rtp.c
    team/oej/codename-pineapple/pbx/pbx_dundi.c
    team/oej/codename-pineapple/pbx/pbx_spool.c
    team/oej/codename-pineapple/res/res_adsi.c
    team/oej/codename-pineapple/res/res_config_odbc.c
    team/oej/codename-pineapple/res/res_features.c
    team/oej/codename-pineapple/res/res_jabber.c
    team/oej/codename-pineapple/res/res_musiconhold.c

Propchange: team/oej/codename-pineapple/
------------------------------------------------------------------------------
Binary property 'branch-1.4-blocked' - no diff available.

Propchange: team/oej/codename-pineapple/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Propchange: team/oej/codename-pineapple/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Sun Feb 11 15:17:37 2007
@@ -1,1 +1,1 @@
-/trunk:1-53017
+/trunk:1-53953

Modified: team/oej/codename-pineapple/UPGRADE.txt
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/UPGRADE.txt?view=diff&rev=53956&r1=53955&r2=53956
==============================================================================
--- team/oej/codename-pineapple/UPGRADE.txt (original)
+++ team/oej/codename-pineapple/UPGRADE.txt Sun Feb 11 15:17:37 2007
@@ -34,3 +34,5 @@
 * ChanIsAvail() now has a 't' option, which allows the specified device
   to be queried for state without consulting the channel drivers. This
   performs mostly a 'ChanExists' sort of function.
+* SetCallerPres() has been replaced with the CALLERPRES() dialplan function
+  and is now deprecated.

Modified: team/oej/codename-pineapple/apps/app_adsiprog.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/apps/app_adsiprog.c?view=diff&rev=53956&r1=53955&r2=53956
==============================================================================
--- team/oej/codename-pineapple/apps/app_adsiprog.c (original)
+++ team/oej/codename-pineapple/apps/app_adsiprog.c Sun Feb 11 15:17:37 2007
@@ -24,6 +24,10 @@
  * 
  * \ingroup applications
  */
+
+/*** MODULEINFO
+	<depend>res_adsi</depend>
+ ***/
 
 #include "asterisk.h"
 

Modified: team/oej/codename-pineapple/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/apps/app_dial.c?view=diff&rev=53956&r1=53955&r2=53956
==============================================================================
--- team/oej/codename-pineapple/apps/app_dial.c (original)
+++ team/oej/codename-pineapple/apps/app_dial.c Sun Feb 11 15:17:37 2007
@@ -82,7 +82,7 @@
 "    ANSWEREDTIME - This is the amount of time for actual call.\n"
 "    DIALSTATUS   - This is the status of the call:\n"
 "                   CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | ANSWER | CANCEL\n" 
-"                   DONTCALL | TORTURE\n"
+"                   DONTCALL | TORTURE | INVALIDARGS\n"
 "  For the Privacy and Screening Modes, the DIALSTATUS variable will be set to\n"
 "DONTCALL if the called party chooses to send the calling party to the 'Go Away'\n"
 "script. The DIALSTATUS variable will be set to TORTURE if the called party\n"
@@ -937,8 +937,11 @@
 	   time and make the caller believe the peer hasn't picked up yet */
 
 	if (ast_test_flag(opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
+		char *original_moh = ast_strdupa(chan->musicclass);
 		ast_indicate(chan, -1);
+		ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
 		ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
+		ast_string_field_set(chan, musicclass, original_moh);
 	} else if (ast_test_flag(opts, OPT_RINGBACK)) {
 		ast_indicate(chan, AST_CONTROL_RINGING);
 		pa->sentringing++;
@@ -1183,6 +1186,7 @@
 	struct privacy_args pa = {
 		.sentringing = 0,
 		.privdb_val = 0,
+		.status = "INVALIDARGS",
 	};
 	int sentringing = 0, moh = 0;
 	const char *outbound_group = NULL;
@@ -1201,23 +1205,27 @@
 
 	if (ast_strlen_zero(data)) {
 		ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
+		pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
 		return -1;
 	}
 
 	u = ast_module_user_add(chan);	/* XXX is this the right place ? */
 
 	parse = ast_strdupa(data);
-
+	
 	AST_STANDARD_APP_ARGS(args, parse);
 
 	memset(&config,0,sizeof(struct ast_bridge_config));
 
 	if (!ast_strlen_zero(args.options) &&
-			ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options))
+			ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options)) {
+		pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
 		goto done;
+	}
 
 	if (ast_strlen_zero(args.peers)) {
 		ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
+		pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
 		goto done;
 	}
 
@@ -1231,6 +1239,7 @@
 		calldurationlimit = atoi(opt_args[OPT_ARG_DURATION_STOP]);
 		if (!calldurationlimit) {
 			ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
+			pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
 			goto done;
 		}
 		if (option_verbose > 2)
@@ -1437,7 +1446,14 @@
 		strcpy(pa.status, "NOANSWER");
 		if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
 			moh = 1;
-			ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
+			if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
+				char *original_moh = ast_strdupa(chan->musicclass);
+				ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
+				ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
+				ast_string_field_set(chan, musicclass, original_moh);
+			} else {
+				ast_moh_start(chan, NULL, NULL);
+			}
 			ast_indicate(chan, AST_CONTROL_PROGRESS);
 		} else if (ast_test_flag(outgoing, OPT_RINGBACK)) {
 			ast_indicate(chan, AST_CONTROL_RINGING);

Modified: team/oej/codename-pineapple/apps/app_echo.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/apps/app_echo.c?view=diff&rev=53956&r1=53955&r2=53956
==============================================================================
--- team/oej/codename-pineapple/apps/app_echo.c (original)
+++ team/oej/codename-pineapple/apps/app_echo.c Sun Feb 11 15:17:37 2007
@@ -69,19 +69,14 @@
 			break;
 		f->delivery.tv_sec = 0;
 		f->delivery.tv_usec = 0;
-		switch (f->frametype) {
-		case AST_FRAME_DTMF:
-			if (f->subclass == '#') {
-				res = 0;
-				ast_frfree(f);
-				goto end;
-			}
-			/* fall through */
-		default:
-			if (ast_write(chan, f)) {
-				ast_frfree(f);
-				goto end;
-			}
+		if (ast_write(chan, f)) {
+			ast_frfree(f);
+			goto end;
+		}
+		if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) {
+			res = 0;
+			ast_frfree(f);
+			goto end;
 		}
 		ast_frfree(f);
 	}

Modified: team/oej/codename-pineapple/apps/app_macro.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/apps/app_macro.c?view=diff&rev=53956&r1=53955&r2=53956
==============================================================================
--- team/oej/codename-pineapple/apps/app_macro.c (original)
+++ team/oej/codename-pineapple/apps/app_macro.c Sun Feb 11 15:17:37 2007
@@ -117,9 +117,10 @@
 	int oldpriority;
 	char pc[80], depthc[12];
 	char oldcontext[AST_MAX_CONTEXT] = "";
+	const char *inhangupc;
 	int offset, depth = 0, maxdepth = 7;
 	int setmacrocontext=0;
-	int autoloopflag, dead = 0;
+	int autoloopflag, dead = 0, inhangup = 0;
   
 	char *save_macro_exten;
 	char *save_macro_context;
@@ -143,6 +144,13 @@
 	s = pbx_builtin_getvar_helper(chan, "MACRO_DEPTH");
 	if (s)
 		sscanf(s, "%d", &depth);
+	/* Used for detecting whether to return when a Macro is called from another Macro after hangup */
+	if (strcmp(chan->exten, "h") == 0)
+		pbx_builtin_setvar_helper(chan, "MACRO_IN_HANGUP", "1");
+	inhangupc = pbx_builtin_getvar_helper(chan, "MACRO_IN_HANGUP");
+	if (!ast_strlen_zero(inhangupc))
+		sscanf(inhangupc, "%d", &inhangup);
+
 	if (depth >= maxdepth) {
 		ast_log(LOG_ERROR, "Macro():  possible infinite loop detected.  Returning early.\n");
 		ast_module_user_remove(u);
@@ -267,7 +275,7 @@
 			break;
 		}
 		/* don't stop executing extensions when we're in "h" */
-		if (chan->_softhangup && strcasecmp(oldexten,"h") && strcasecmp(chan->macroexten,"h")) {
+		if (chan->_softhangup && !inhangup) {
 			if (option_debug)
 				ast_log(LOG_DEBUG, "Extension %s, macroexten %s, priority %d returned normally even though call was hung up\n",
 					chan->exten, chan->macroexten, chan->priority);

Modified: team/oej/codename-pineapple/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/apps/app_meetme.c?view=diff&rev=53956&r1=53955&r2=53956
==============================================================================
--- team/oej/codename-pineapple/apps/app_meetme.c (original)
+++ team/oej/codename-pineapple/apps/app_meetme.c Sun Feb 11 15:17:37 2007
@@ -60,11 +60,13 @@
 #include "asterisk/ulaw.h"
 #include "asterisk/astobj.h"
 #include "asterisk/devicestate.h"
+#include "asterisk/dial.h"
 
 #include "enter.h"
 #include "leave.h"
 
 #define CONFIG_FILE_NAME "meetme.conf"
+#define SLA_CONFIG_FILE  "sla.conf"
 
 /*! each buffer is 20ms, so this is 640ms total */
 #define DEFAULT_AUDIO_BUFFERS  32
@@ -148,12 +150,10 @@
 	CONFFLAG_INTROUSERNOREVIEW = (1 << 23),
 	/*! If set, the user will be initially self-muted */
 	CONFFLAG_STARTMUTED = (1 << 24),
-	/*! If set, the user is a shared line appearance station */
-	CONFFLAG_SLA_STATION = (1 << 25),
-	/*! If set, the user is a shared line appearance trunk */
-	CONFFLAG_SLA_TRUNK = (1 << 26),
-	/*! If set, the user has put us on hold */
-	CONFFLAG_HOLD = (1 << 27),
+	/*! Pass DTMF through the conference */
+	CONFFLAG_PASS_DTMF = (1 << 25),
+	CONFFLAG_SLA_STATION = (1 << 26),
+	CONFFLAG_SLA_TRUNK = (1 << 27),
 	/*! If set, the user should continue in the dialplan if kicked out */
 	CONFFLAG_KICK_CONTINUE = (1 << 28)
 };
@@ -163,7 +163,7 @@
 	OPT_ARG_ARRAY_SIZE = 1,
 };
 
-AST_APP_OPTIONS(meetme_opts, {
+AST_APP_OPTIONS(meetme_opts, BEGIN_OPTIONS
 	AST_APP_OPTION('A', CONFFLAG_MARKEDUSER ),
 	AST_APP_OPTION('a', CONFFLAG_ADMIN ),
 	AST_APP_OPTION('b', CONFFLAG_AGI ),
@@ -173,6 +173,7 @@
 	AST_APP_OPTION('d', CONFFLAG_DYNAMIC ),
 	AST_APP_OPTION('E', CONFFLAG_EMPTYNOPIN ),
 	AST_APP_OPTION('e', CONFFLAG_EMPTY ),
+	AST_APP_OPTION('F', CONFFLAG_PASS_DTMF ),
 	AST_APP_OPTION('i', CONFFLAG_INTROUSER ),
 	AST_APP_OPTION('I', CONFFLAG_INTROUSERNOREVIEW ),
 	AST_APP_OPTION('M', CONFFLAG_MOH ),
@@ -190,22 +191,19 @@
 	AST_APP_OPTION('X', CONFFLAG_EXIT_CONTEXT ),
 	AST_APP_OPTION('x', CONFFLAG_MARKEDEXIT ),
 	AST_APP_OPTION('1', CONFFLAG_NOONLYPERSON ),
-});
-
-AST_APP_OPTIONS(sla_opts, {
-	/* Just a placeholder for now */
-});
+END_OPTIONS );
+
 static const char *app = "MeetMe";
 static const char *app2 = "MeetMeCount";
 static const char *app3 = "MeetMeAdmin";
-static const char *appslas = "SLAStation";
-static const char *appslat = "SLATrunk";
+static const char *slastation_app = "SLAStation";
+static const char *slatrunk_app = "SLATrunk";
 
 static const char *synopsis = "MeetMe conference bridge";
 static const char *synopsis2 = "MeetMe participant count";
 static const char *synopsis3 = "MeetMe conference Administration";
-static const char *synopslas = "Shared Line Appearance - Station";
-static const char *synopslat = "Shared Line Appearance - Trunk";
+static const char *slastation_synopsis = "Shared Line Appearance Station";
+static const char *slatrunk_synopsis = "Shared Line Appearance Trunk";
 
 static const char *descrip =
 "  MeetMe([confno][,[options][,pin]]): Enters the user into a specified MeetMe\n"
@@ -227,6 +225,8 @@
 "      'D' -- dynamically add conference, prompting for a PIN\n"
 "      'e' -- select an empty conference\n"
 "      'E' -- select an empty pinless conference\n"
+"      'F' -- Pass DTMF through the conference.  DTMF used to activate any\n"
+"             conference features will not be passed through.\n"
 "      'i' -- announce user join/leave with review\n"
 "      'I' -- announce user join/leave without review\n"
 "      'l' -- set listen only mode (Listen only, no talking)\n"
@@ -285,25 +285,20 @@
 "      'V' -- Raise entire conference listening volume\n"
 "";
 
-static const char *descripslas =
-"  SLAStation(sla[,options]): Run Shared Line Appearance for station\n"
-"Runs the share line appearance for a station calling in.  If there are no\n"
-"other participants in the conference, the trunk is called and is dumped into\n"
-"the bridge.\n";
-
-static const char *descripslat =
-"  SLATrunk(sla[,options]): Run Shared Line Appearance for trunk\n"
-"Runs the share line appearance for a trunk calling in.  If there are no\n"
-"other participants in the conference, all member stations are invited into\n"
-"the bridge.\n";
-
-#define CONFIG_FILE_NAME_SLA "sla.conf"
+static const char *slastation_desc =
+"  SLAStation():\n";
+
+static const char *slatrunk_desc =
+"  SLATrunk():\n";
+
+#define MAX_CONFNUM 80
+#define MAX_PIN     80
 
 /*! \brief The MeetMe Conference object */
 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 */
+	char confno[MAX_CONFNUM];               /*!< Conference */
 	struct ast_channel *chan;               /*!< Announcements channel */
 	struct ast_channel *lchan;              /*!< Listen/Record channel */
 	int fd;                                 /*!< Announcements fd */
@@ -319,8 +314,8 @@
 	pthread_attr_t attr;                    /*!< thread attribute */
 	const char *recordingfilename;          /*!< Filename to record the Conference into */
 	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 */
+	char pin[MAX_PIN];                      /*!< If protected by a PIN */
+	char pinadmin[MAX_PIN];                 /*!< If protected by a admin PIN */
 	struct ast_frame *transframe[32];
 	struct ast_frame *origframe;
 	struct ast_trans_pvt *transpath[32];
@@ -344,39 +339,94 @@
 	int zapchannel;                         /*!< Is a Zaptel channel */
 	char usrvalue[50];                      /*!< Custom User Value */
 	char namerecloc[PATH_MAX];				/*!< Name Recorded file Location */
-	int control;							/*! Queue Control for transmission */
-	int dtmf;								/*! Queue DTMF for transmission */
 	time_t jointime;                        /*!< Time the user joined the conference */
 	struct volume talk;
 	struct volume listen;
+	AST_LIST_HEAD_NOLOCK(, ast_frame) frame_q;
 	AST_LIST_ENTRY(ast_conf_user) list;
 };
 
-/*! SLA station - one device in an SLA configuration */
-struct ast_sla_station {
-	ASTOBJ_COMPONENTS(struct ast_sla_station);
-	char *dest;
-	char tech[0];
+enum sla_trunk_state {
+	SLA_TRUNK_STATE_IDLE,
+	SLA_TRUNK_STATE_RINGING,
+	SLA_TRUNK_STATE_UP,
+	SLA_TRUNK_STATE_ONHOLD,
 };
 
-struct ast_sla_station_box {
-	ASTOBJ_CONTAINER_COMPONENTS(struct ast_sla_station);
+struct sla_trunk_ref;
+
+struct sla_station {
+	AST_RWLIST_ENTRY(sla_station) entry;
+	AST_DECLARE_STRING_FIELDS(
+		AST_STRING_FIELD(name);	
+		AST_STRING_FIELD(device);	
+		AST_STRING_FIELD(autocontext);	
+	);
+	AST_LIST_HEAD_NOLOCK(, sla_trunk_ref) trunks;
+	struct ast_dial *dial;
 };
 
-/*! SLA - Shared Line Appearance object. These consist of one trunk (outbound line)
-	and stations that receive incoming calls and place outbound calls over the trunk 
-*/
-struct ast_sla {
-	ASTOBJ_COMPONENTS (struct ast_sla);
-	struct ast_sla_station_box stations;	/*!< Stations connected to this SLA */
-	char confname[80];	/*!< Name for this SLA bridge */
-	char trunkdest[256];	/*!< Device (channel) identifier for the trunk line */
-	char trunktech[20];	/*!< Technology used for the trunk (channel driver) */
+struct sla_station_ref {
+	AST_LIST_ENTRY(sla_station_ref) entry;
+	struct sla_station *station;
 };
 
-struct ast_sla_box {
-	ASTOBJ_CONTAINER_COMPONENTS(struct ast_sla);
-} slas;
+struct sla_trunk {
+	AST_RWLIST_ENTRY(sla_trunk) entry;
+	AST_DECLARE_STRING_FIELDS(
+		AST_STRING_FIELD(name);
+		AST_STRING_FIELD(device);
+		AST_STRING_FIELD(autocontext);	
+	);
+	AST_LIST_HEAD_NOLOCK(, sla_station_ref) stations;
+	/*! Number of stations that use this trunk */
+	unsigned int num_stations;
+	/*! Number of stations currently on a call with this trunk */
+	unsigned int active_stations;
+	/*! Number of stations that have this trunk on hold. */
+	unsigned int hold_stations;
+	struct ast_channel *chan;
+	pthread_t station_thread;
+};
+
+struct sla_trunk_ref {
+	AST_LIST_ENTRY(sla_trunk_ref) entry;
+	struct sla_trunk *trunk;
+	enum sla_trunk_state state;
+	struct ast_channel *chan;
+};
+
+static AST_RWLIST_HEAD_STATIC(sla_stations, sla_station);
+static AST_RWLIST_HEAD_STATIC(sla_trunks, sla_trunk);
+
+static const char sla_registrar[] = "SLA";
+
+enum sla_event_type {
+	SLA_EVENT_HOLD,
+	SLA_EVENT_UNHOLD
+};
+
+struct sla_event {
+	enum sla_event_type type;
+	struct sla_station *station;
+	struct sla_trunk_ref *trunk_ref;
+	AST_LIST_ENTRY(sla_event) entry;
+};
+
+/*!
+ * \brief A structure for data used by the sla thread
+ */
+static struct sla {
+	/*! The SLA thread ID */
+	pthread_t thread;
+	ast_cond_t cond;
+	ast_mutex_t lock;
+	AST_LIST_HEAD_NOLOCK(, sla_trunk_ref) ringing_trunks;
+	AST_LIST_HEAD_NOLOCK(, sla_event) event_q;
+	unsigned int stop:1;
+} sla = {
+	.thread = AST_PTHREADT_NULL,
+};
 
 /*! The number of audio buffers to be allocated on pseudo channels
  *  when in a conference */
@@ -388,7 +438,7 @@
  *  conversion... the numbers have been modified
  *  to give the user a better level of adjustability
  */
-static signed char gain_map[] = {
+static const char const gain_map[] = {
 	-15,
 	-13,
 	-10,
@@ -445,7 +495,7 @@
 
 static int set_talk_volume(struct ast_conf_user *user, int volume)
 {
-	signed char gain_adjust;
+	char gain_adjust;
 
 	/* attempt to make the adjustment in the channel driver;
 	   if successful, don't adjust in the frame reading routine
@@ -457,7 +507,7 @@
 
 static int set_listen_volume(struct ast_conf_user *user, int volume)
 {
-	signed char gain_adjust;
+	char gain_adjust;
 
 	/* attempt to make the adjustment in the channel driver;
 	   if successful, don't adjust in the frame reading routine
@@ -471,7 +521,7 @@
 {
 	switch (action) {
 	case VOL_UP:
-		switch (vol->desired) {
+		switch (vol->desired) { 
 		case 5:
 			break;
 		case 0:
@@ -568,18 +618,19 @@
 		ast_autoservice_stop(chan);
 }
 
-static void station_destroy(struct ast_sla_station *station)
-{
-	free(station);
-}
-
-static void sla_destroy(struct ast_sla *sla)
-{
-	ASTOBJ_CONTAINER_DESTROYALL(&sla->stations, station_destroy);
-	ASTOBJ_CONTAINER_DESTROY(&sla->stations);
-	free(sla);
-}
-
+/*!
+ * \brief Find or create a conference
+ *
+ * \param confno The conference name/number
+ * \param pin The regular user pin
+ * \param pinadmin The admin pin
+ * \param make Make the conf if it doesn't exist
+ * \param dynamic Mark the newly created conference as dynamic
+ * \param refcount How many references to mark on the conference
+ *
+ * \return A pointer to the conference struct, or NULL if it wasn't found and
+ *         make or dynamic were not set.
+ */
 static struct ast_conference *build_conf(char *confno, char *pin, char *pinadmin, int make, int dynamic, int refcount)
 {
 	struct ast_conference *cnf;
@@ -592,99 +643,77 @@
 			break;
 	}
 
-	if (!cnf && (make || dynamic)) {
-		/* Make a new one */
-		if ((cnf = ast_calloc(1, sizeof(*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->refcount = 0;
-			cnf->markedusers = 0;
-			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");
-				cnf->fd = open("/dev/zap/pseudo", O_RDWR);
-				if (cnf->fd < 0) {
-					ast_log(LOG_WARNING, "Unable to open pseudo device\n");
-					free(cnf);
-					cnf = NULL;
-					goto cnfout;
-				}
-			}
-			memset(&ztc, 0, sizeof(ztc));
-			/* Setup a new zap conference */
-			ztc.chan = 0;
-			ztc.confno = -1;
-			ztc.confmode = ZT_CONF_CONFANN | ZT_CONF_CONFANNMON;
-			if (ioctl(cnf->fd, ZT_SETCONF, &ztc)) {
-				ast_log(LOG_WARNING, "Error setting conference\n");
-				if (cnf->chan)
-					ast_hangup(cnf->chan);
-				else
-					close(cnf->fd);
-				free(cnf);
-				cnf = NULL;
-				goto cnfout;
-			}
-			cnf->lchan = ast_request("zap", AST_FORMAT_SLINEAR, "pseudo", NULL);
-			if (cnf->lchan) {
-				ast_set_read_format(cnf->lchan, AST_FORMAT_SLINEAR);
-				ast_set_write_format(cnf->lchan, AST_FORMAT_SLINEAR);
-				ztc.chan = 0;
-				ztc.confmode = ZT_CONF_CONFANN | ZT_CONF_CONFANNMON;
-				if (ioctl(cnf->lchan->fds[0], ZT_SETCONF, &ztc)) {
-					ast_log(LOG_WARNING, "Error setting conference\n");
-					ast_hangup(cnf->lchan);
-					cnf->lchan = NULL;
-				}
-			}
-			/* Fill the conference struct */
-			cnf->start = time(NULL);
-			cnf->zapconf = ztc.confno;
-			cnf->isdynamic = dynamic ? 1 : 0;
-			if (option_verbose > 2)
-				ast_verbose(VERBOSE_PREFIX_3 "Created MeetMe conference %d for conference '%s'\n", cnf->zapconf, cnf->confno);
-			AST_LIST_INSERT_HEAD(&confs, cnf, list);
-			manager_event(EVENT_FLAG_CALL, "MeetmeStart", "Meetme: %s\r\n", cnf->confno);
-		} 
-	}
- cnfout:
-	if (cnf){ 
+	if (cnf || (!make && !dynamic))
+		goto cnfout;
+
+	/* Make a new one */
+	if (!(cnf = ast_calloc(1, sizeof(*cnf))))
+		goto cnfout;
+
+	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->refcount = 0;
+	cnf->markedusers = 0;
+	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");
+		cnf->fd = open("/dev/zap/pseudo", O_RDWR);
+		if (cnf->fd < 0) {
+			ast_log(LOG_WARNING, "Unable to open pseudo device\n");
+			free(cnf);
+			cnf = NULL;
+			goto cnfout;
+		}
+	}
+	memset(&ztc, 0, sizeof(ztc));
+	/* Setup a new zap conference */
+	ztc.chan = 0;
+	ztc.confno = -1;
+	ztc.confmode = ZT_CONF_CONFANN | ZT_CONF_CONFANNMON;
+	if (ioctl(cnf->fd, ZT_SETCONF, &ztc)) {
+		ast_log(LOG_WARNING, "Error setting conference\n");
+		if (cnf->chan)
+			ast_hangup(cnf->chan);
+		else
+			close(cnf->fd);
+		free(cnf);
+		cnf = NULL;
+		goto cnfout;
+	}
+	cnf->lchan = ast_request("zap", AST_FORMAT_SLINEAR, "pseudo", NULL);
+	if (cnf->lchan) {
+		ast_set_read_format(cnf->lchan, AST_FORMAT_SLINEAR);
+		ast_set_write_format(cnf->lchan, AST_FORMAT_SLINEAR);
+		ztc.chan = 0;
+		ztc.confmode = ZT_CONF_CONFANN | ZT_CONF_CONFANNMON;
+		if (ioctl(cnf->lchan->fds[0], ZT_SETCONF, &ztc)) {
+			ast_log(LOG_WARNING, "Error setting conference\n");
+			ast_hangup(cnf->lchan);
+			cnf->lchan = NULL;
+		}
+	}
+	/* Fill the conference struct */
+	cnf->start = time(NULL);
+	cnf->zapconf = ztc.confno;
+	cnf->isdynamic = dynamic ? 1 : 0;
+	if (option_verbose > 2)
+		ast_verbose(VERBOSE_PREFIX_3 "Created MeetMe conference %d for conference '%s'\n", cnf->zapconf, cnf->confno);
+	AST_LIST_INSERT_HEAD(&confs, cnf, list);
+	
+cnfout:
+	if (cnf)
 		cnf->refcount += refcount;
-	}
+
 	AST_LIST_UNLOCK(&confs);
+
 	return cnf;
-}
-
-/*! \brief CLI command for showing SLAs */
-static int sla_show(int fd, int argc, char *argv[]) 
-{
-	struct ast_sla *sla;
-	if (argc != 2)
-		return RESULT_SHOWUSAGE;
-
-	ast_cli(fd, "Shared line appearances:\n");
-	ASTOBJ_CONTAINER_TRAVERSE(&slas, 1, {
-		ASTOBJ_RDLOCK(iterator);
-		ast_cli(fd, "SLA %s\n", iterator->name);
-		if (ast_strlen_zero(iterator->trunkdest) || ast_strlen_zero(iterator->trunktech))
-			ast_cli(fd, "   Trunk => <unspecified>\n");
-		else
-			ast_cli(fd, "   Trunk => %s/%s\n", iterator->trunktech, iterator->trunkdest);
-		sla = iterator;
-		ASTOBJ_CONTAINER_TRAVERSE(&sla->stations, 1, {
-			ast_cli(fd, "   Station: %s/%s\n", iterator->tech, iterator->dest);
-		});
-		ASTOBJ_UNLOCK(iterator);
-	});
-
-	return RESULT_SUCCESS;
 }
 
 static int meetme_cmd(int fd, int argc, char **argv) 
@@ -797,7 +826,7 @@
 			min = ((now - user->jointime) % 3600) / 60;
 			sec = (now - user->jointime) % 60;
 			if ( !concise )
-				ast_cli(fd, "User #: %-2.2d %12.12s %-20.20s Channel: %s %s %s %s %s %s %02d:%02d:%02d\n",
+				ast_cli(fd, "User #: %-2.2d %12.12s %-20.20s Channel: %s %s %s %s %s %02d:%02d:%02d\n",
 					user->user_no,
 					S_OR(user->chan->cid.cid_num, "<unknown>"),
 					S_OR(user->chan->cid.cid_name, "<no name>"),
@@ -805,8 +834,7 @@
 					user->userflags & CONFFLAG_ADMIN ? "(Admin)" : "",
 					user->userflags & CONFFLAG_MONITOR ? "(Listen only)" : "",
 					user->adminflags & ADMINFLAG_MUTED ? "(Admin Muted)" : user->adminflags & ADMINFLAG_SELFMUTED ? "(Muted)" : "",
-					istalking(user->talking), 
-					user->userflags & CONFFLAG_HOLD ? " (On Hold) " : "", hr, min, sec);
+					istalking(user->talking), hr, min, sec); 
 			else 
 				ast_cli(fd, "%d!%s!%s!%s!%s!%s!%s!%d!%02d:%02d:%02d\n",
 					user->user_no,
@@ -900,18 +928,94 @@
 "Usage: meetme (un)lock|(un)mute|kick|list [concise] <confno> <usernumber>\n"
 "       Executes a command for the conference or on a conferee\n";
 
-static const char sla_show_usage[] =
-"Usage: sla show\n"
-"       Lists status of all shared line appearances\n";
+static int sla_show_trunks(int fd, int argc, char **argv)
+{
+	const struct sla_trunk *trunk;
+
+	ast_cli(fd, "--- Configured SLA Trunks -----------------------------------\n"
+	            "-------------------------------------------------------------\n\n");
+	AST_RWLIST_RDLOCK(&sla_trunks);
+	AST_RWLIST_TRAVERSE(&sla_trunks, trunk, entry) {
+		struct sla_station_ref *station_ref;
+		ast_cli(fd, "--- Trunk Name:      %s\n"
+		            "--- ==> Device:      %s\n"
+					"--- ==> AutoContext: %s\n"
+					"--- ==> Stations ...\n",
+					trunk->name, trunk->device, 
+					S_OR(trunk->autocontext, "(none)"));
+		AST_RWLIST_RDLOCK(&sla_stations);
+		AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry)
+			ast_cli(fd, "--- =====> Station name: %s\n", station_ref->station->name);
+		AST_RWLIST_UNLOCK(&sla_stations);
+		ast_cli(fd, "\n");
+	}
+	AST_RWLIST_UNLOCK(&sla_trunks);
+	ast_cli(fd, "-------------------------------------------------------------\n");
+
+	return RESULT_SUCCESS;
+}
+
+static const char *trunkstate2str(enum sla_trunk_state state)
+{
+#define S(e) case e: return # e;
+	switch (state) {
+	S(SLA_TRUNK_STATE_IDLE)
+	S(SLA_TRUNK_STATE_RINGING)
+	S(SLA_TRUNK_STATE_UP)
+	S(SLA_TRUNK_STATE_ONHOLD)
+	}
+	return "Uknown State";
+#undef S
+}
+
+static const char sla_show_trunks_usage[] =
+"Usage: sla show trunks\n"
+"       This will list all trunks defined in sla.conf\n";
+
+static int sla_show_stations(int fd, int argc, char **argv)
+{
+	const struct sla_station *station;
+
+	ast_cli(fd, "--- Configured SLA Stations ---------------------------------\n"
+	            "-------------------------------------------------------------\n\n");
+	AST_RWLIST_RDLOCK(&sla_stations);
+	AST_RWLIST_TRAVERSE(&sla_stations, station, entry) {
+		struct sla_trunk_ref *trunk_ref;
+		ast_cli(fd, "--- Station Name:    %s\n"
+		            "--- ==> Device:      %s\n"
+					"--- ==> AutoContext: %s\n"
+					"--- ==> Trunks ...\n",
+					station->name, station->device, 
+					S_OR(station->autocontext, "(none)"));
+		AST_RWLIST_RDLOCK(&sla_trunks);
+		AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry)
+			ast_cli(fd, "--- =====> Trunk Name: %s State: %s\n", 
+				trunk_ref->trunk->name, trunkstate2str(trunk_ref->state));
+		AST_RWLIST_UNLOCK(&sla_trunks);
+		ast_cli(fd, "\n");
+	}
+	AST_RWLIST_UNLOCK(&sla_stations);
+	ast_cli(fd, "-------------------------------------------------------------\n");
+
+	return RESULT_SUCCESS;
+}
+
+static const char sla_show_stations_usage[] =
+"Usage: sla show stations\n"
+"       This will list all stations defined in sla.conf\n";
 
 static struct ast_cli_entry cli_meetme[] = {
-	{ { "sla", "show", NULL },
-	sla_show, "Show status of Shared Line Appearances",
-	sla_show_usage, NULL },
-
 	{ { "meetme", NULL, NULL },
 	meetme_cmd, "Execute a command on a conference or conferee",
 	meetme_usage, complete_meetmecmd },
+
+	{ { "sla", "show", "trunks", NULL },
+	sla_show_trunks, "Show SLA Trunks",
+	sla_show_trunks_usage, NULL },
+
+	{ { "sla", "show", "stations", NULL },
+	sla_show_stations, "Show SLA Stations",
+	sla_show_stations_usage, NULL },
 };
 
 static void conf_flush(int fd, struct ast_channel *chan)
@@ -983,22 +1087,64 @@
 	return 0;
 }
 
-static void conf_queue_dtmf(struct ast_conference *conf, int digit)
-{
+static void conf_queue_dtmf(const struct ast_conference *conf,
+	const struct ast_conf_user *sender, const struct ast_frame *_f)
+{
+	struct ast_frame *f;
 	struct ast_conf_user *user;
+
 	AST_LIST_TRAVERSE(&conf->userlist, user, list) {
-		user->dtmf = digit;
-	}
-}
-
-static void conf_queue_control(struct ast_conference *conf, int control)
-{
-	struct ast_conf_user *user;
-	AST_LIST_TRAVERSE(&conf->userlist, user, list) {
-		user->control = control;
-	}
-}
-
+		if (user == sender)
+			continue;
+		if (!(f = ast_frdup(_f)))
+			return;
+		AST_LIST_INSERT_TAIL(&user->frame_q, f, frame_list);
+	}
+}
+
+static void sla_queue_event(enum sla_event_type type, const struct ast_channel *chan,
+	struct ast_conference *conf)
+{
+	struct sla_event *event;
+	struct sla_station *station;
+	struct sla_trunk_ref *trunk_ref = NULL;
+	char *trunk_name;
+
+	trunk_name = ast_strdupa(conf->confno);
+	strsep(&trunk_name, "_");
+	if (ast_strlen_zero(trunk_name)) {
+		ast_log(LOG_ERROR, "Invalid conference name for SLA - '%s'!\n", conf->confno);
+		return;
+	}
+
+	AST_RWLIST_RDLOCK(&sla_stations);
+	AST_RWLIST_TRAVERSE(&sla_stations, station, entry) {
+		AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
+			if (trunk_ref->chan == chan && !strcmp(trunk_ref->trunk->name, trunk_name))
+				break;
+		}
+		if (trunk_ref)
+			break;
+	}
+	AST_RWLIST_UNLOCK(&sla_stations);
+
+	if (!trunk_ref) {
+		ast_log(LOG_DEBUG, "Trunk not found for event!\n");
+		return;
+	}
+
+	if (!(event = ast_calloc(1, sizeof(*event))))
+		return;
+
+	event->type = type;
+	event->trunk_ref = trunk_ref;
+	event->station = station;
+
+	ast_mutex_lock(&sla.lock);
+	AST_LIST_INSERT_TAIL(&sla.event_q, event, entry);
+	ast_cond_signal(&sla.cond);
+	ast_mutex_unlock(&sla.lock);
+}
 
 static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int confflags, char *optargs[])
 {
@@ -1081,6 +1227,7 @@
 		pthread_attr_init(&conf->attr);
 		pthread_attr_setdetachstate(&conf->attr, PTHREAD_CREATE_DETACHED);
 		ast_pthread_create_background(&conf->recordthread, &conf->attr, recordthread, conf);
+		pthread_attr_destroy(&conf->attr);
 	}
 
 	time(&user->jointime);
@@ -1116,8 +1263,6 @@
 	/* This device changed state now - if this is the first user */
 	if (conf->users == 1)
 		ast_device_state_changed("meetme:%s", conf->confno);
-	if (confflags & (CONFFLAG_SLA_STATION|CONFFLAG_SLA_TRUNK))
-		ast_device_state_changed("SLA:%s", conf->confno + 4);
 
 	ast_mutex_unlock(&conf->playlock);
 
@@ -1521,8 +1666,10 @@
 			/* If I have been kicked, exit the conference */
 			if (user->adminflags & ADMINFLAG_KICKME) {
 				//You have been kicked.
-				if (!ast_streamfile(chan, "conf-kicked", chan->language))
+				if (!(confflags & CONFFLAG_QUIET) && 
+					!ast_streamfile(chan, "conf-kicked", chan->language)) {
 					ast_waitstream(chan, "");
+				}
 				ret = 0;
 				break;
 			}
@@ -1546,6 +1693,14 @@
 					f = ast_read(c);
 				if (!f)
 					break;
+				if (!AST_LIST_EMPTY(&user->frame_q)) {
+					struct ast_frame *f;
+					f = AST_LIST_REMOVE_HEAD(&user->frame_q, frame_list);
+					if (ast_write(chan, f) < 0) {
+						ast_log(LOG_WARNING, "Error writing frame to channel!\n");
+					}
+					ast_frfree(f);
+				}
 				if ((f->frametype == AST_FRAME_VOICE) && (f->subclass == AST_FORMAT_SLINEAR)) {
 					if (user->talk.actual)
 						ast_frame_adjust_volume(f, user->talk.actual);
@@ -1596,17 +1751,6 @@
 						if (user->talking || !(confflags & CONFFLAG_OPTIMIZETALKER))
 							careful_write(fd, f->data, f->datalen, 0);
 					}
-				} else if ((f->frametype == AST_FRAME_DTMF) && 
-							(confflags & (CONFFLAG_SLA_STATION|CONFFLAG_SLA_TRUNK))) {
-					conf_queue_dtmf(conf, f->subclass);
-				} else if ((f->frametype == AST_FRAME_CONTROL) && 
-							(confflags & (CONFFLAG_SLA_STATION|CONFFLAG_SLA_TRUNK))) {
-					conf_queue_control(conf, f->subclass);
-					if (f->subclass == AST_CONTROL_HOLD)
-						confflags |= CONFFLAG_HOLD;
-					else if (f->subclass == AST_CONTROL_UNHOLD)
-						confflags &= ~CONFFLAG_HOLD;
-					user->userflags = confflags;
 				} else if ((f->frametype == AST_FRAME_DTMF) && (confflags & CONFFLAG_EXIT_CONTEXT)) {
 					char tmp[2];
 
@@ -1779,6 +1923,21 @@
 					}
 
 					conf_flush(fd, chan);
+				} else if ((f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END)
+					&& confflags & CONFFLAG_PASS_DTMF) {
+					conf_queue_dtmf(conf, user, f);
+				} else if ((confflags & CONFFLAG_SLA_STATION) && f->frametype == AST_FRAME_CONTROL) {
+					switch (f->subclass) {
+					case AST_CONTROL_HOLD:
+						ast_log(LOG_DEBUG, "Got a HOLD frame!\n");
+						sla_queue_event(SLA_EVENT_HOLD, chan, conf);
+						break;
+					case AST_CONTROL_UNHOLD:
+						ast_log(LOG_DEBUG, "Got a UNHOLD frame!\n");
+						sla_queue_event(SLA_EVENT_UNHOLD, chan, conf);
+					default:
+						break;
+					}
 				} else if (option_debug) {
 					ast_log(LOG_DEBUG,
 						"Got unrecognized frame on channel %s, f->frametype=%d,f->subclass=%d\n",
@@ -1786,33 +1945,6 @@
 				}
 				ast_frfree(f);
 			} else if (outfd > -1) {
-				if (user->control) {
-					switch(user->control) {
-					case AST_CONTROL_RINGING:
-					case AST_CONTROL_PROGRESS:
-					case AST_CONTROL_PROCEEDING:
-						ast_indicate(chan, user->control);
-						break;
-					case AST_CONTROL_ANSWER:
-						if (chan->_state != AST_STATE_UP)
-							ast_answer(chan);
-						break;
-					}
-					user->control = 0;
-					if (confflags & (CONFFLAG_SLA_STATION|CONFFLAG_SLA_TRUNK))
-						ast_device_state_changed("SLA:%s", conf->confno + 4);
-					continue;
-				}
-				if (user->dtmf) {
-					memset(&fr, 0, sizeof(fr));
-					fr.frametype = AST_FRAME_DTMF;
-					fr.subclass = user->dtmf;
-					if (ast_write(chan, &fr) < 0) {
-						ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno));
-					}
-					user->dtmf = 0;
-					continue;
-				}
 				res = read(outfd, buf, CONF_SIZE);
 				if (res > 0) {
 					memset(&fr, 0, sizeof(fr));
@@ -1945,8 +2077,6 @@
 		/* Change any states */
 		if (!conf->users)
 			ast_device_state_changed("meetme:%s", conf->confno);
-		if (confflags & (CONFFLAG_SLA_STATION|CONFFLAG_SLA_TRUNK))
-			ast_device_state_changed("SLA:%s", conf->confno + 4);
 
 		if (AST_LIST_EMPTY(&conf->userlist)) {
 			/* close this one when no more users and no references*/
@@ -1964,7 +2094,7 @@
 }
 
 static struct ast_conference *find_conf_realtime(struct ast_channel *chan, char *confno, int make, int dynamic,
-						 char *dynamic_pin, int refcount, struct ast_flags *confflags)
+						 char *dynamic_pin, size_t pin_buf_len, int refcount, struct ast_flags *confflags)
 {
 	struct ast_variable *var;
 	struct ast_conference *cnf;
@@ -2021,7 +2151,7 @@
 
 
 static struct ast_conference *find_conf(struct ast_channel *chan, char *confno, int make, int dynamic,
-					char *dynamic_pin, int refcount, struct ast_flags *confflags)
+					char *dynamic_pin, size_t pin_buf_len, int refcount, struct ast_flags *confflags)
 {
 	struct ast_config *cfg;
 	struct ast_variable *var;
@@ -2052,7 +2182,7 @@
 			if (dynamic_pin) {
 				if (dynamic_pin[0] == 'q') {
 					/* Query the user to enter a PIN */
-					if (ast_app_getdata(chan, "conf-getpin", dynamic_pin, AST_MAX_EXTENSION - 1, 0) < 0)
+					if (ast_app_getdata(chan, "conf-getpin", dynamic_pin, pin_buf_len - 1, 0) < 0)
 						return NULL;
 				}
 				cnf = build_conf(confno, dynamic_pin, "", make, dynamic, refcount);
@@ -2143,7 +2273,7 @@
 
 	AST_STANDARD_APP_ARGS(args, localdata);
 	
-	conf = find_conf(chan, args.confno, 0, 0, NULL, 0, NULL);
+	conf = find_conf(chan, args.confno, 0, 0, NULL, 0, 0, NULL);
 
 	if (conf)
 		count = conf->users;
@@ -2169,7 +2299,7 @@
 {
 	int res=-1;
 	struct ast_module_user *u;
-	char confno[AST_MAX_EXTENSION] = "";

[... 3945 lines stripped ...]


More information about the asterisk-commits mailing list