diff --git a/CHANGES b/CHANGES
index 90911a43848c61887d5e5c5ab2b09a7cf58c2bcb..db4253c5166ce834dd74cd510b3aae90d34a3bd5 100644
--- a/CHANGES
+++ b/CHANGES
@@ -426,6 +426,8 @@ MeetMe Changes
      for the "meetme" command.
   * Added the ability to specify the music on hold class used to play into the
      conference when there is only one member and the M option is used.
+  * Added MEETME_INFO dialplan function which provides a way to query
+     various properties of a Meetme conference.
 
 Other Dialplan Application Changes
 ----------------------------------
diff --git a/apps/app_meetme.c b/apps/app_meetme.c
index 5f265a1d7181166c634e63b9660579831a26dd2e..1243a255ae6c7b175bc98f020daf552cbbf0303a 100644
--- a/apps/app_meetme.c
+++ b/apps/app_meetme.c
@@ -5525,6 +5525,88 @@ static int sla_load_config(int reload)
 	return res;
 }
 
+static int acf_meetme_info_eval(char *keyword, struct ast_conference *conf)
+{
+	if (!strcasecmp("lock", keyword)) {
+		return conf->locked;
+	} else if (!strcasecmp("parties", keyword)) {
+		return conf->users;
+	} else if (!strcasecmp("activity", keyword)) {
+		time_t now;
+		now = time(NULL);
+		return (now - conf->start);
+	} else if (!strcasecmp("dynamic", keyword)) {
+		return conf->isdynamic;
+	} else {
+		return -1;
+	}
+
+}
+
+static int acf_meetme_info(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+{
+	struct ast_conference *conf;
+	char *parse;
+	int result = -2; /* only non-negative numbers valid, -1 is used elsewhere */
+	AST_DECLARE_APP_ARGS(args,
+		AST_APP_ARG(keyword);
+		AST_APP_ARG(confno);
+	);
+
+	if (ast_strlen_zero(data)) {
+		ast_log(LOG_ERROR, "Syntax: MEETME_INFO() requires two arguments\n");
+		return -1;
+	}
+
+	parse = ast_strdupa(data);
+	AST_STANDARD_APP_ARGS(args, parse);
+
+	if (ast_strlen_zero(args.keyword)) {
+		ast_log(LOG_ERROR, "Syntax: MEETME_INFO() requires a keyword\n");
+		return -1;
+	}
+
+	if (ast_strlen_zero(args.confno)) {
+		ast_log(LOG_ERROR, "Syntax: MEETME_INFO() requires a conference number\n");
+		return -1;
+	}
+
+	AST_LIST_LOCK(&confs);
+	AST_LIST_TRAVERSE(&confs, conf, list) {
+		if (!strcmp(args.confno, conf->confno)) {
+			result = acf_meetme_info_eval(args.keyword, conf);
+			break;
+		}
+	}
+	AST_LIST_UNLOCK(&confs);
+
+	if (result > -1) {
+		snprintf(buf, len, "%d", result);
+	} else if (result == -1) {
+		snprintf(buf, len, "%s %s", "Error: invalid keyword:", args.keyword);
+	} else if (result == -2) {
+		snprintf(buf, len, "Error: conference (%s) not found", args.confno);
+	}
+
+	return 0;
+}
+
+
+static struct ast_custom_function meetme_info_acf = {
+	.name = "MEETME_INFO",
+	.synopsis = "Query a given conference of various properties.",
+	.syntax = "MEETME_INFO(<keyword>,<confno>)",
+	.read = acf_meetme_info,
+	.desc =
+"Returns information from a given keyword. (For booleans 1-true, 0-false)\n"
+"  Options:\n"
+"    lock     - boolean of whether the corresponding conference is locked\n" 
+"    parties  - number of parties in a given conference\n"
+"    activity - duration of conference in seconds\n"
+"    dynamic  - boolean of whether the corresponding coference is dynamic\n",
+};
+
+
 static int load_config(int reload)
 {
 	load_config_meetme();
@@ -5558,6 +5640,8 @@ static int unload_module(void)
 	ast_devstate_prov_del("SLA");
 	
 	sla_destroy();
+	
+	res |= ast_custom_function_unregister(&meetme_info_acf);
 
 	return res;
 }
@@ -5587,6 +5671,8 @@ static int load_module(void)
 	res |= ast_devstate_prov_add("Meetme", meetmestate);
 	res |= ast_devstate_prov_add("SLA", sla_state);
 
+	res |= ast_custom_function_register(&meetme_info_acf);
+
 	return res;
 }