[asterisk-commits] russell: branch russell/sla_rewrite r52681 - /team/russell/sla_rewrite/apps/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Mon Jan 29 15:39:00 MST 2007


Author: russell
Date: Mon Jan 29 16:38:59 2007
New Revision: 52681

URL: http://svn.digium.com/view/asterisk?view=rev&rev=52681
Log:
Add DMTF passthrough support for MeetMe.  This is used by the SLA applications,
but I made it available for anyone to use should they find it useful.

Modified:
    team/russell/sla_rewrite/apps/app_meetme.c

Modified: team/russell/sla_rewrite/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/russell/sla_rewrite/apps/app_meetme.c?view=diff&rev=52681&r1=52680&r2=52681
==============================================================================
--- team/russell/sla_rewrite/apps/app_meetme.c (original)
+++ team/russell/sla_rewrite/apps/app_meetme.c Mon Jan 29 16:38:59 2007
@@ -150,6 +150,8 @@
 	CONFFLAG_INTROUSERNOREVIEW = (1 << 23),
 	/*! If set, the user will be initially self-muted */
 	CONFFLAG_STARTMUTED = (1 << 24),
+	/*! Pass DTMF through the conference */
+	CONFFLAG_PASS_DTMF = (1 << 25),
 };
 
 enum {
@@ -166,6 +168,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 ),
@@ -216,6 +219,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"
@@ -331,6 +336,7 @@
 	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;
 };
 
@@ -1037,6 +1043,21 @@
 	free(conf);
 
 	return 0;
+}
+
+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) {
+		if (user == sender)
+			continue;
+		if (!(f = ast_frdup(_f)))
+			return;
+		AST_LIST_INSERT_TAIL(&user->frame_q, f, frame_list);
+	}
 }
 
 static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int confflags, char *optargs[])
@@ -1577,6 +1598,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);
@@ -1798,6 +1827,9 @@
 					}
 
 					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 (option_debug) {
 					ast_log(LOG_DEBUG,
 						"Got unrecognized frame on channel %s, f->frametype=%d,f->subclass=%d\n",
@@ -2890,7 +2922,8 @@
 	}
 
 	snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk->name);
-	ast_set_flag(&conf_flags, CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_MARKEDUSER);
+	ast_set_flag(&conf_flags, 
+		CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_MARKEDUSER | CONFFLAG_PASS_DTMF);
 	conf = build_conf(conf_name, "", "", 1, 1, 1);
 
 	ast_mutex_lock(args->cond_lock);
@@ -3012,7 +3045,7 @@
 
 	ast_atomic_fetchadd_int((int *) &trunk_ref->trunk->active_stations, 1);
 	snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk_ref->trunk->name);
-	ast_set_flag(&conf_flags, CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT);
+	ast_set_flag(&conf_flags, CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_PASS_DTMF);
 	station->chan = chan;
 	ast_answer(chan);
 	conf = build_conf(conf_name, "", "", 0, 0, 1);
@@ -3163,7 +3196,7 @@
 
 	ast_atomic_fetchadd_int((int *) &trunk->active_stations, 1);
 	stations[winner]->chan = ast_dial_answered(dials[winner]);
-	ast_set_flag(&conf_flags, CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT);
+	ast_set_flag(&conf_flags, CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_PASS_DTMF);
 	snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk->name);
 	conf = build_conf(conf_name, "", "", 0, 0, 1);
 	if (conf)
@@ -3220,7 +3253,8 @@
 		return 0;
 	}
 
-	ast_set_flag(&conf_flags, CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_MARKEDUSER);
+	ast_set_flag(&conf_flags, 
+		CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_MARKEDUSER | CONFFLAG_PASS_DTMF);
 
 	ast_indicate(chan, AST_CONTROL_RINGING);
 	conf_run(chan, conf, conf_flags.flags, NULL);



More information about the asterisk-commits mailing list