Project "FreeSWITCH Source" received a push.

branch: master updated

       via: f64b03bd8b25deb191fd456a1854b02fd73626fc (commit)
       via: bcb2262fdc48b36bd2e6bfe45adcbaecd1d091ee (commit)
       via: f0a31e1bfff2d49d97bc0ee83627c426fa311bfc (commit)
       via: 526e6fe48cadc9418d64f2b639bad68d8883dcdd (commit)
       via: 8c12162a9d92ceac55c6305f2336efcf7157b923 (commit)
       via: bab7a2392f955facbb91d0f30512682e2b38773e (commit)
       via: 12c13e115b96e9e036bd65655c1f12a72a83510e (commit)
       via: cf83f9c381a6abb988efc41b8711271b4665b79e (commit)
       via: 080c5ae98167e590bebf698439c550bdb656925e (commit)
       via: 0806c3880104fff154802adb010713365ef6a0ed (commit)
       via: d4b5b07b2a76404ed8bf5adf8bc2bc9c0cbd9f04 (commit)
       via: 2b4f163826132cf55698008a22c065374320796a (commit)
       via: 7386b9f8f55e6b2648bcfb3f9dafaf62dccd772e (commit)
       via: 0d5fcf65a0fef932f32874da6f4bdddb69279c53 (commit)
       via: b3086c1d6b6f4900ec770e22878038ac565424d9 (commit)
       via: 294436486302d0547b34ba26e5fa402c4ebaa58f (commit)
       via: 998a04d2cfa361a4d600175809d5fef02374c720 (commit)
       via: e7d68a79dc7838d74e7b8985494dcde532910d32 (commit)
       via: 8f565277e3a9e814c12779f3d51f2527a081ef99 (commit)
       via: 20976da4114c2c5fc0213fa4cda91f7f4bf8a136 (commit)
       via: e37dd41e311986015393befed7160e27a6450933 (commit)
       via: b8b7266abb7a6c081ad1e1531aea69daf5d7509c (commit)
       via: f4481b05ab8ae1faf6eedb438085e688371e79c6 (commit)
       via: e9e33f5160fb5272c4f912dac6a29415215bba1c (commit)
       via: 36f6218b8bba3233cf3fb501b01a0288a08e9f00 (commit)
       via: 2ec2a9b0d335a8d6a30ab5a92448ac3ad63649ff (commit)
       via: 46f6c6e42d2775ccfecb8f445ebbaaf32ab34df7 (commit)
       via: b6ac001276961761b14a89270da02498b4d3e740 (commit)
       via: 2d190b37abe00999a2e76861b8c88f0053e0b78f (commit)
       via: dc436b82a52da05686ac178ad7854556e9688ed8 (commit)
       via: bdf678e401a8077aab06b9c04004c92ef6631e26 (commit)
       via: e79174cacf6abb943fe34840a5261b940b281c91 (commit)
       via: 33b74ca8c710a58d245ea8903f98e0e86cffe164 (commit)
       via: 68d08547f36777e2c091008b5e1207ca5b15e9e2 (commit)
       via: 673678509f0f3ea0464ea45798c0cdbc4843946b (commit)
       via: 45ec088753031fc60b1b1abeb25536b7ac042374 (commit)
       via: 53aeb1c1a71e6546950721d9f79f4a6131eb3071 (commit)
       via: 4371d3c804d890315ca623e2930286154d80a9a8 (commit)
       via: 231a7ffaa19886653705c217a73d8e25b705503c (commit)
       via: 9a8eea27feb6f300d5adeb078cad82974681bca7 (commit)
       via: f37390f0a7f1ca636d54c23d6873510fcf26e91e (commit)
       via: 1388ed811a2369b26778c4cce158691f285c45b4 (commit)
      from: 3830484155cfa3bd8ef09b88515e8afa6c251121 (commit)


= COMMIT LOG ===========================================================
committer: Moises Silva
comments: 
Merge remote branch 'fsorig/master'
committer: Daniel Swarbrick
comments: 
major factor of pgsql field handling

diff --git a/conf/autoload_configs/cdr_pg_csv.conf.xml b/conf/autoload_configs/cdr_pg_csv.conf.xml
index 427bf2d..4fec817 100644
--- a/conf/autoload_configs/cdr_pg_csv.conf.xml
+++ b/conf/autoload_configs/cdr_pg_csv.conf.xml
@@ -16,10 +16,25 @@
 
     <!-- This is like the info app but after the call is hung up -->
     <!--<param name="debug" value="true"/>-->
-
-    <param name="default-template" value="example"/>
   </settings>
-  <templates>
-    <template name="example">"${local_ip_v4}","${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}","${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}","${accountcode}","${read_codec}","${write_codec}","${sip_hangup_disposition}","${ani}"</template>
-  </templates>
+  <schema>
+    <field var="local_ip_v4"/>
+    <field var="caller_id_name"/>
+    <field var="caller_id_number"/>
+    <field var="destination_number"/>
+    <field var="context"/>
+    <field var="start_stamp"/>
+    <field var="answer_stamp"/>
+    <field var="end_stamp"/>
+    <field var="duration" quote="false"/>
+    <field var="billsec" quote="false"/>
+    <field var="hangup_cause"/>
+    <field var="uuid"/>
+    <field var="bleg_uuid"/>
+    <field var="accountcode"/>
+    <field var="read_codec"/>
+    <field var="write_codec"/>
+    <!-- <field var="sip_hangup_disposition"/> -->
+    <!-- <field var="ani"/> -->
+  </schema>
 </configuration>
diff --git a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c
index 1ec56bd..51194f4 100644
--- a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c
+++ b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c
@@ -59,28 +59,34 @@ typedef struct {
 	switch_mutex_t *mutex;
 } cdr_fd_t;
 
-const char *default_template =
-	"\"${local_ip_v4}\",\"${caller_id_name}\",\"${caller_id_number}\",\"${destination_number}\",\"${context}\",\"${start_stamp}\","
-	"\"${answer_stamp}\",\"${end_stamp}\",\"${duration}\",\"${billsec}\",\"${hangup_cause}\",\"${uuid}\",\"${bleg_uuid}\",\"${accountcode}\","
-	"\"${read_codec}\",\"${write_codec}\"";
+typedef struct {
+	char *col_name;
+	char *var_name;
+	switch_bool_t quote;
+	switch_bool_t not_null;
+} cdr_field_t;
+
+typedef struct {
+	char *columns;
+	cdr_field_t fields[1];
+} db_schema_t;
 
 static struct {
 	switch_memory_pool_t *pool;
 	switch_hash_t *fd_hash;
-	switch_hash_t *template_hash;
 	int shutdown;
 	char *db_info;
 	char *db_table;
+	db_schema_t *db_schema;
 	PGconn *db_connection;
+	switch_mutex_t *db_mutex;
 	int db_online;
 	cdr_leg_t legs;
 	char *spool_dir;
 	spool_format_t spool_format;
 	int rotate;
 	int debug;
-	char *default_template;
-	switch_mutex_t *db_mutex;
-} globals = { 0 };
+} globals;
 
 static switch_xml_config_enum_item_t config_opt_cdr_leg_enum[] = {
         {"a", CDR_LEG_A},
@@ -110,7 +116,6 @@ static switch_xml_config_item_t config_settings[] = {
 	/* key, type, flags, ptr, default_value, data, syntax, helptext */
 	SWITCH_CONFIG_ITEM_STRING_STRDUP("db-info", CONFIG_RELOADABLE, &globals.db_info, "dbname=cdr", NULL, NULL),
 	SWITCH_CONFIG_ITEM_STRING_STRDUP("db-table", CONFIG_RELOADABLE, &globals.db_table, "cdr", NULL, NULL),
-	SWITCH_CONFIG_ITEM_STRING_STRDUP("default-template", CONFIG_RELOADABLE, &globals.default_template, "default", NULL, NULL),
 	SWITCH_CONFIG_ITEM("legs", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &globals.legs, (void *) CDR_LEG_A, &config_opt_cdr_leg_enum, "a|b|ab", NULL),
 	SWITCH_CONFIG_ITEM("spool-format", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &globals.spool_format, (void *) SPOOL_FORMAT_CSV, &config_opt_spool_format_enum, "csv|sql", "Disk spool format to use if SQL insert fails."),
 	SWITCH_CONFIG_ITEM("rotate-on-hup", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &globals.rotate, SWITCH_FALSE, NULL, NULL, NULL),
@@ -239,135 +244,13 @@ static void spool_cdr(const char *path, const char *log_line)
 	switch_safe_free(log_line_lf);
 }
 
-static switch_status_t insert_cdr(const char * const template, const char * const cdr)
+static switch_status_t insert_cdr(const char *values)
 {
-	char *columns, *values;
-	char *p, *q;
-	unsigned vlen;
-	char *nullValues, *temp, *tp;
-	int nullCounter = 0, charCounter = 0;
 	char *sql = NULL, *path = NULL;
 	PGresult *res;
 
-	if (!template || !*template || !cdr || !*cdr) {
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Bad parameter\n");
-		return SWITCH_STATUS_FALSE;
-	}
-
-	/* Build comma-separated list of field names by dropping $ { } ; chars */
-	switch_strdup(columns, template);
-	for (p = columns, q = columns; *p; ++p) {
-		switch (*p) {
-			case '$': case '"': case '{': case '}': case ';':
-				break;
-			default:
-				*q++ = *p;
-		}
-	}
-	*q = '\0';
-
-	/*
-	 * In the expanded vars, replace double quotes (") with single quotes (')
-	 * for correct PostgreSQL syntax, and replace semi-colon with space to
-	 * prevent SQL injection attacks
-	 */
-	switch_strdup(values, cdr);
-	for (p = values; *p; ++p) {
-		switch(*p) {
-			case '"':
-				*p = '\'';
-				break;
-			case ';':
-				*p = ' ';
-				break;
-		}
-	}
-	vlen = p - values;
-
-	/*
-	 * Patch for changing empty strings ('') in the expanded variables to
-	 * PostgreSQL null
-	 */
-	for (p = values; *p; ++p) {
-		if (*p == ',') {
-			if (charCounter == 0) {
-				nullCounter++;
-			}
-			charCounter = 0;
-		} else if (*p != ' ' && *p != '\'') {
-			charCounter++;
-		}
-	}
-
-	if (charCounter == 0) {
-		nullCounter++;
-	}
-
-	nullCounter *= 4;
-	vlen += nullCounter;
-	switch_zmalloc(nullValues, strlen(values) + nullCounter + 1);
-	charCounter = 0;
-	temp = nullValues;
-	tp = nullValues;
-
-	for (p = values; *p; ++tp, ++p) {
-		if (*p == ',') {
-			if (charCounter == 0) {
-				temp++;
-				*temp = 'n';
-				temp++;
-				if (temp == tp) tp++;
-				*temp = 'u';
-				temp++;
-				if (temp == tp) tp++;
-				*temp = 'l';
-				temp++;
-				if (temp == tp) tp++;
-				*temp = 'l';
-				temp++;
-				while (temp != tp) {
-					*temp = ' ';
-					temp++;
-				}
-			}
-			charCounter = 0;
-			temp = tp;
-		} else if (*p != ' ' && *p != '\'') {
-			charCounter++;
-		}
-		*tp = *p;
-	}
-
-	if (charCounter == 0) {
-		temp++;
-		*temp = 'n';
-		temp++;
-		if (temp == tp) tp++;
-		*temp = 'u';
-		temp++;
-		if (temp == tp) tp++;
-		*temp = 'l';
-		temp++;
-		if (temp == tp) tp++;
-		*temp = 'l';
-		temp++;
-		while (temp != tp) {
-			*temp = ' ';
-			temp++;
-		}
-	}
-
-	charCounter = 0;
-	temp = tp;
-	*tp = 0;
-	tp = values;
-	values = nullValues;
-	switch_safe_free(tp);
-
-	sql = switch_mprintf("INSERT INTO %s (%s) VALUES (%s);", globals.db_table, columns, values);
+	sql = switch_mprintf("INSERT INTO %s (%s) VALUES (%s);", globals.db_table, globals.db_schema->columns, values);
 	assert(sql);
-	switch_safe_free(columns);
-	switch_safe_free(values);
 
 	if (globals.debug) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Query: \"%s\"\n", sql);
@@ -415,7 +298,7 @@ static switch_status_t insert_cdr(const char * const template, const char * cons
 	} else {
 		path = switch_mprintf("%s%scdr-spool.csv", globals.spool_dir, SWITCH_PATH_SEPARATOR);
 		assert(path);
-		spool_cdr(path, cdr);
+		spool_cdr(path, values);
 	}
 
 	switch_safe_free(path);
@@ -428,8 +311,10 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)
 {
 	switch_channel_t *channel = switch_core_session_get_channel(session);
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
-	const char *template_str = NULL;
-	char *expanded_vars = NULL;
+	char *values = NULL, *tmp = NULL, *pq_var = NULL;
+	const char *var = NULL;
+	cdr_field_t *cdr_field = NULL;
+	switch_size_t len, offset;
 
 	if (globals.shutdown) {
 		return SWITCH_STATUS_SUCCESS;
@@ -465,24 +350,40 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)
 		}
 	}
 
-	template_str = (const char *) switch_core_hash_find(globals.template_hash, globals.default_template);
+	switch_zmalloc(values, 1);
+	offset = 0;
 
-	if (!template_str) {
-		template_str = default_template;
-	}
+	for (cdr_field = globals.db_schema->fields; cdr_field->var_name; cdr_field++) {
+		if ((var = switch_channel_get_variable(channel, cdr_field->var_name))) {
+			/* Allocate sufficient buffer for PQescapeString */
+			len = strlen(var);
+			tmp = switch_core_session_alloc(session, len * 2 + 1);
+			PQescapeString(tmp, var, len);
+			var = tmp;
+		}
 
-	expanded_vars = switch_channel_expand_variables(channel, template_str);
+		if (cdr_field->quote) {
+			if ((cdr_field->not_null == SWITCH_FALSE) && zstr(var)) {
+				pq_var = switch_mprintf("null,", var);
+			} else {
+				pq_var = switch_mprintf("'%s',", var);
+			}
+		} else {
+			pq_var = switch_mprintf("%s,", var);
+		}
 
-	if (!expanded_vars) {
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error expanding CDR variables.\n");
-		return SWITCH_STATUS_FALSE;
+		/* Resize values buffer to accomodate next var */
+		len = strlen(pq_var);
+		tmp = realloc(values, offset + len);
+		values = tmp;
+		memcpy(values + offset, pq_var, len);
+		switch_safe_free(pq_var);
+		offset += len;
 	}
+	*(values + --offset) = '\0';
 
-	insert_cdr(template_str, expanded_vars);
-
-	if (expanded_vars != template_str) {
-		switch_safe_free(expanded_vars);
-	}
+	insert_cdr(values);
+	switch_safe_free(values);
 
 	return status;
 }
@@ -532,9 +433,13 @@ static switch_state_handler_table_t state_handlers = {
 
 static switch_status_t load_config(switch_memory_pool_t *pool)
 {
-	char *cf = "cdr_pg_csv.conf";
-	switch_xml_t cfg, xml, settings, param;
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
+	char *cf = "cdr_pg_csv.conf", *ptr;
+	switch_xml_t cfg, xml, schema, field;
+	const char *attr;
+	int num_fields = 0;
+	switch_size_t len = 0;
+	cdr_field_t *cdr_field;
 
 	if (globals.db_online) {
 		PQfinish(globals.db_connection);
@@ -544,32 +449,69 @@ static switch_status_t load_config(switch_memory_pool_t *pool)
 
 	memset(&globals, 0, sizeof(globals));
 	switch_core_hash_init(&globals.fd_hash, pool);
-	switch_core_hash_init(&globals.template_hash, pool);
 	switch_mutex_init(&globals.db_mutex, SWITCH_MUTEX_NESTED, pool);
 
 	globals.pool = pool;
 
-	switch_core_hash_insert(globals.template_hash, "default", default_template);
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding default template.\n");
-	globals.legs = CDR_LEG_A;
-
-	if (switch_xml_config_parse_module_settings("cdr_pg_csv.conf", SWITCH_FALSE, config_settings) != SWITCH_STATUS_SUCCESS) {
+	if (switch_xml_config_parse_module_settings(cf, SWITCH_FALSE, config_settings) != SWITCH_STATUS_SUCCESS) {
 		return SWITCH_STATUS_FALSE;
 	}
 
 	if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
-		if ((settings = switch_xml_child(cfg, "templates"))) {
-			for (param = switch_xml_child(settings, "template"); param; param = param->next) {
-				char *var = (char *) switch_xml_attr(param, "name");
-				if (var) {
-					char *tpl;
-					tpl = switch_core_strdup(pool, param->txt);
-
-					switch_core_hash_insert(globals.template_hash, var, tpl);
-					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding template %s.\n", var);
+		if ((schema = switch_xml_child(cfg, "schema"))) {
+			/* Count fields in schema so we can calculate required buffer size */
+			for (field = switch_xml_child(schema, "field"); field; field = field->next) {
+				if (switch_xml_attr(field, "var")) {
+					num_fields++;
 				}
 			}
+
+			globals.db_schema = switch_core_alloc(pool, (num_fields + 1) * sizeof(cdr_field_t));
+			cdr_field = globals.db_schema->fields;
+
+			for (field = switch_xml_child(schema, "field"); field; field = field->next) {
+				if ((attr = switch_xml_attr(field, "var"))) {
+					cdr_field->var_name = switch_core_strdup(pool, attr);
+
+					/* Assume SQL column name is the same as FreeSWITCH channel var name, unless specified otherwise */
+					if ((attr = switch_xml_attr(field, "column"))) {
+						cdr_field->col_name = switch_core_strdup(pool, attr);
+					} else {
+						cdr_field->col_name = switch_core_strdup(pool, cdr_field->var_name);
+					}
+
+					/* Assume all fields should be quoted (treated as strings), unless specified otherwise */
+					if ((attr = switch_xml_attr(field, "quote")) && !strncmp(attr, "false", 5)) {
+						cdr_field->quote = SWITCH_FALSE;
+					} else {
+						cdr_field->quote = SWITCH_TRUE;
+					}
+
+					/* Assume all fields allow SQL nulls, unless specified otherwise */
+					if ((attr = switch_xml_attr(field, "not-null")) && !strncmp(attr, "true", 4)) {
+						cdr_field->not_null = SWITCH_TRUE;
+					} else {
+						cdr_field->not_null = SWITCH_FALSE;
+					}
+
+					len += strlen(cdr_field->col_name) + 1;
+					cdr_field++;
+				}
+			}
+			cdr_field->var_name = 0;
+
+			globals.db_schema->columns = switch_core_alloc(pool, len);
+			ptr = globals.db_schema->columns;
+			for (cdr_field = globals.db_schema->fields; cdr_field->col_name; cdr_field++) {
+				len = strlen(cdr_field->col_name);
+				memcpy(ptr, cdr_field->col_name, len);
+				ptr += len;
+				*ptr = ',';
+				ptr++;
+			}
+			*--ptr = '\0';
 		}
+
 		switch_xml_free(xml);
 	}
 
@@ -596,7 +538,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cdr_pg_csv_load)
 	switch_core_add_state_handler(&state_handlers);
 	*module_interface = switch_loadable_module_create_module_interface(pool, modname);
 
-
 	return status;
 }
 
committer: Anthony Minessale
comments: 
default to 10

diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index c78aac7..c683203 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -3708,7 +3708,7 @@ SWITCH_STANDARD_API(sofia_function)
 
 				if (argc > 2) {
 					if (strstr(argv[2], "presence")) {
-						mod_sofia_globals.debug_presence = 1;
+						mod_sofia_globals.debug_presence = 10;
 						stream->write_function(stream, "+OK Debugging presence\n");
 					}
 					
committer: Anthony Minessale
comments: 
FS-3038

diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c
index 807770a..f34042a 100644
--- a/src/mod/applications/mod_commands/mod_commands.c
+++ b/src/mod/applications/mod_commands/mod_commands.c
@@ -4439,19 +4439,23 @@ SWITCH_STANDARD_API(strftime_tz_api_function)
 
 		if ((format = strchr(mycmd, ' '))) {
 			*format++ = '\0';
-		}
 		
-		if ((p = strchr(format, '|'))) {
-			*p++ = '\0';
-			when = atol(format);
-			format = p;
+			if (format && (p = strchr(format, '|'))) {
+				*p++ = '\0';
+				when = atol(format);
+				format = p;
+			}
 		}
 	}
 
-	if (switch_strftime_tz(tz_name, format, date, sizeof(date), when * 1000000) == SWITCH_STATUS_SUCCESS) {	/* The lookup of the zone may fail. */
+	if (zstr(format)) {
+		format = "%Y-%m-%d";
+	}
+	
+	if (format && switch_strftime_tz(tz_name, format, date, sizeof(date), when * 1000000) == SWITCH_STATUS_SUCCESS) {	/* The lookup of the zone may fail. */
 		stream->write_function(stream, "%s", date);
 	} else {
-		stream->write_function(stream, "-ERR Invalid Timezone\n");
+		stream->write_function(stream, "-ERR Invalid Timezone/Format\n");
 	}
 
 	switch_safe_free(mycmd);
committer: Anthony Minessale
comments: 
FS-3040

diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c
index f829e57..bea8214 100644
--- a/src/mod/applications/mod_voicemail/mod_voicemail.c
+++ b/src/mod/applications/mod_voicemail/mod_voicemail.c
@@ -1277,9 +1277,14 @@ static void message_count(vm_profile_t *profile, const char *id_in, const char *
 
 	myid = resolve_id(id_in, domain_name, "message-count");
 
-	switch_snprintf(sql, sizeof(sql), "select 1, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' "
-									  "and read_epoch=0 group by read_flags union select 0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' "
-									  "and domain='%s' and in_folder='%s' and read_epoch<>0 group by read_flags;", myid, domain_name, myfolder);
+	switch_snprintf(sql, sizeof(sql), "select 1, read_flags, count(read_epoch) from voicemail_msgs where "
+					"username='%s' and domain='%s' and in_folder='%s' "
+					"and read_epoch=0 group by read_flags union select 0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' "
+					"and domain='%s' and in_folder='%s' and read_epoch<>0 group by read_flags;", 
+					myid, domain_name, myfolder, myid, domain_name, myfolder);
+					
+				   
+
 	vm_execute_sql_callback(profile, profile->mutex, sql, message_count_callback, &cbt);
 
 	*total_new_messages = cbt.total_new_messages + cbt.total_new_urgent_messages;
committer: Daniel Swarbrick
comments: 
refactor config parsing

diff --git a/conf/autoload_configs/cdr_pg_csv.conf.xml b/conf/autoload_configs/cdr_pg_csv.conf.xml
index 2f2efa9..427bf2d 100644
--- a/conf/autoload_configs/cdr_pg_csv.conf.xml
+++ b/conf/autoload_configs/cdr_pg_csv.conf.xml
@@ -1,19 +1,23 @@
 <configuration name="cdr_pg_csv.conf" description="CDR PG CSV Format">
   <settings>
-    <!-- Log a-leg (a), b-leg (b) or both (ab) -->
-    <param name="legs" value="a"/>
     <!-- See parameters for PQconnectdb() at http://www.postgresql.org/docs/8.4/static/libpq-connect.html -->
     <param name="db-info" value="host=localhost dbname=cdr connect_timeout=10" />
     <!-- CDR table name -->
     <!--<param name="db-table" value="cdr"/>-->
-    <param name="default-template" value="example"/>
-    <!-- 'cdr-pg-csv' will always be appended to log-base -->
-    <!--<param name="log-base" value="/var/log"/>-->
+
+    <!-- Log a-leg (a), b-leg (b) or both (ab) -->
+    <param name="legs" value="a"/>
+
+    <!-- Directory in which to spool failed SQL inserts -->
+    <!-- <param name="spool-dir" value="$${base_dir}/log/cdr-pg-csv"/> -->
     <!-- Disk spool format if DB connection/insert fails - csv (default) or sql -->
     <param name="spool-format" value="csv"/>
     <param name="rotate-on-hup" value="true"/>
+
     <!-- This is like the info app but after the call is hung up -->
     <!--<param name="debug" value="true"/>-->
+
+    <param name="default-template" value="example"/>
   </settings>
   <templates>
     <template name="example">"${local_ip_v4}","${caller_id_name}","${caller_id_number}","${destination_number}","${context}","${start_stamp}","${answer_stamp}","${end_stamp}","${duration}","${billsec}","${hangup_cause}","${uuid}","${bleg_uuid}","${accountcode}","${read_codec}","${write_codec}","${sip_hangup_disposition}","${ani}"</template>
diff --git a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c
index 5227161..1ec56bd 100644
--- a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c
+++ b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c
@@ -37,18 +37,27 @@
 #include <switch.h>
 #include <libpq-fe.h>
 
+SWITCH_MODULE_LOAD_FUNCTION(mod_cdr_pg_csv_load);
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_cdr_pg_csv_shutdown);
+SWITCH_MODULE_DEFINITION(mod_cdr_pg_csv, mod_cdr_pg_csv_load, mod_cdr_pg_csv_shutdown, NULL);
+
+
 typedef enum {
 	CDR_LEG_A = (1 << 0),
 	CDR_LEG_B = (1 << 1)
 } cdr_leg_t;
 
-struct cdr_fd {
+typedef enum {
+	SPOOL_FORMAT_CSV,
+	SPOOL_FORMAT_SQL
+} spool_format_t;
+
+typedef struct {
 	int fd;
 	char *path;
 	int64_t bytes;
 	switch_mutex_t *mutex;
-};
-typedef struct cdr_fd cdr_fd_t;
+} cdr_fd_t;
 
 const char *default_template =
 	"\"${local_ip_v4}\",\"${caller_id_name}\",\"${caller_id_number}\",\"${destination_number}\",\"${context}\",\"${start_stamp}\","
@@ -59,23 +68,59 @@ static struct {
 	switch_memory_pool_t *pool;
 	switch_hash_t *fd_hash;
 	switch_hash_t *template_hash;
-	char *log_dir;
-	char *default_template;
 	int shutdown;
-	int rotate;
-	int debug;
-	cdr_leg_t legs;
 	char *db_info;
 	char *db_table;
-	char *spool_format;
 	PGconn *db_connection;
 	int db_online;
+	cdr_leg_t legs;
+	char *spool_dir;
+	spool_format_t spool_format;
+	int rotate;
+	int debug;
+	char *default_template;
 	switch_mutex_t *db_mutex;
 } globals = { 0 };
 
-SWITCH_MODULE_LOAD_FUNCTION(mod_cdr_pg_csv_load);
-SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_cdr_pg_csv_shutdown);
-SWITCH_MODULE_DEFINITION(mod_cdr_pg_csv, mod_cdr_pg_csv_load, mod_cdr_pg_csv_shutdown, NULL);
+static switch_xml_config_enum_item_t config_opt_cdr_leg_enum[] = {
+        {"a", CDR_LEG_A},
+        {"b", CDR_LEG_B},
+        {"ab", CDR_LEG_A | CDR_LEG_B},
+        {NULL, 0}
+};
+
+static switch_xml_config_enum_item_t config_opt_spool_format_enum[] = {
+        {"csv", SPOOL_FORMAT_CSV},
+        {"sql", SPOOL_FORMAT_SQL},
+        {NULL, 0}
+};
+
+static switch_status_t config_validate_spool_dir(switch_xml_config_item_t *item, const char *newvalue, switch_config_callback_type_t callback_type, switch_bool_t changed)
+{
+	if ((callback_type == CONFIG_LOAD || callback_type == CONFIG_RELOAD)) {
+		if (zstr(newvalue)) {
+			globals.spool_dir = switch_core_sprintf(globals.pool, "%s%scdr-pg-csv", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR);
+		}
+	}
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_xml_config_item_t config_settings[] = {
+	/* key, type, flags, ptr, default_value, data, syntax, helptext */
+	SWITCH_CONFIG_ITEM_STRING_STRDUP("db-info", CONFIG_RELOADABLE, &globals.db_info, "dbname=cdr", NULL, NULL),
+	SWITCH_CONFIG_ITEM_STRING_STRDUP("db-table", CONFIG_RELOADABLE, &globals.db_table, "cdr", NULL, NULL),
+	SWITCH_CONFIG_ITEM_STRING_STRDUP("default-template", CONFIG_RELOADABLE, &globals.default_template, "default", NULL, NULL),
+	SWITCH_CONFIG_ITEM("legs", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &globals.legs, (void *) CDR_LEG_A, &config_opt_cdr_leg_enum, "a|b|ab", NULL),
+	SWITCH_CONFIG_ITEM("spool-format", SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &globals.spool_format, (void *) SPOOL_FORMAT_CSV, &config_opt_spool_format_enum, "csv|sql", "Disk spool format to use if SQL insert fails."),
+	SWITCH_CONFIG_ITEM("rotate-on-hup", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &globals.rotate, SWITCH_FALSE, NULL, NULL, NULL),
+	SWITCH_CONFIG_ITEM("debug", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &globals.debug, SWITCH_FALSE, NULL, NULL, NULL),
+
+	/* key, type, flags, ptr, defaultvalue, function, functiondata, syntax, helptext */
+	SWITCH_CONFIG_ITEM_CALLBACK("spool-dir", SWITCH_CONFIG_STRING, CONFIG_RELOADABLE, &globals.spool_dir, NULL, config_validate_spool_dir, NULL, NULL, NULL),
+	SWITCH_CONFIG_ITEM_END()
+};
+
 
 static off_t fd_size(int fd)
 {
@@ -363,12 +408,12 @@ static switch_status_t insert_cdr(const char * const template, const char * cons
 	switch_mutex_unlock(globals.db_mutex);
 
 	/* SQL INSERT failed for whatever reason. Spool the attempted query to disk */
-	if (!strcasecmp(globals.spool_format, "sql")) {
-		path = switch_mprintf("%s%scdr-spool.sql", globals.log_dir, SWITCH_PATH_SEPARATOR);
+	if (globals.spool_format == SPOOL_FORMAT_SQL) {
+		path = switch_mprintf("%s%scdr-spool.sql", globals.spool_dir, SWITCH_PATH_SEPARATOR);
 		assert(path);
 		spool_cdr(path, sql);
 	} else {
-		path = switch_mprintf("%s%scdr-spool.csv", globals.log_dir, SWITCH_PATH_SEPARATOR);
+		path = switch_mprintf("%s%scdr-spool.csv", globals.spool_dir, SWITCH_PATH_SEPARATOR);
 		assert(path);
 		spool_cdr(path, cdr);
 	}
@@ -402,8 +447,8 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)
 		}
 	}
 
-	if (switch_dir_make_recursive(globals.log_dir, SWITCH_DEFAULT_DIR_PERMS, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", globals.log_dir);
+	if (switch_dir_make_recursive(globals.spool_dir, SWITCH_DEFAULT_DIR_PERMS, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", globals.spool_dir);
 		return SWITCH_STATUS_FALSE;
 	}
 
@@ -485,7 +530,6 @@ static switch_state_handler_table_t state_handlers = {
 };
 
 
-
 static switch_status_t load_config(switch_memory_pool_t *pool)
 {
 	char *cf = "cdr_pg_csv.conf";
@@ -509,40 +553,11 @@ static switch_status_t load_config(switch_memory_pool_t *pool)
 	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding default template.\n");
 	globals.legs = CDR_LEG_A;
 
-	if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
-
-		if ((settings = switch_xml_child(cfg, "settings"))) {
-			for (param = switch_xml_child(settings, "param"); param; param = param->next) {
-				char *var = (char *) switch_xml_attr_soft(param, "name");
-				char *val = (char *) switch_xml_attr_soft(param, "value");
-				if (!strcasecmp(var, "debug")) {
-					globals.debug = switch_true(val);
-				} else if (!strcasecmp(var, "legs")) {
-					globals.legs = 0;
-
-					if (strchr(val, 'a')) {
-						globals.legs |= CDR_LEG_A;
-					}
-
-					if (strchr(val, 'b')) {
-						globals.legs |= CDR_LEG_B;
-					}
-				} else if (!strcasecmp(var, "log-base")) {
-					globals.log_dir = switch_core_sprintf(pool, "%s%scdr-pg-csv", val, SWITCH_PATH_SEPARATOR);
-				} else if (!strcasecmp(var, "rotate-on-hup")) {
-					globals.rotate = switch_true(val);
-				} else if (!strcasecmp(var, "db-info")) {
-					globals.db_info = switch_core_strdup(pool, val);
-				} else if (!strcasecmp(var, "db-table") || !strcasecmp(var, "g-table")) {
-					globals.db_table = switch_core_strdup(pool, val);
-				} else if (!strcasecmp(var, "default-template")) {
-					globals.default_template = switch_core_strdup(pool, val);
-				} else if (!strcasecmp(var, "spool-format")) {
-					globals.spool_format = switch_core_strdup(pool, val);
-				}
-			}
-		}
+	if (switch_xml_config_parse_module_settings("cdr_pg_csv.conf", SWITCH_FALSE, config_settings) != SWITCH_STATUS_SUCCESS) {
+		return SWITCH_STATUS_FALSE;
+	}
 
+	if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
 		if ((settings = switch_xml_child(cfg, "templates"))) {
 			for (param = switch_xml_child(settings, "template"); param; param = param->next) {
 				char *var = (char *) switch_xml_attr(param, "name");
@@ -558,26 +573,6 @@ static switch_status_t load_config(switch_memory_pool_t *pool)
 		switch_xml_free(xml);
 	}
 
-	if (!globals.log_dir) {
-		globals.log_dir = switch_core_sprintf(pool, "%s%scdr-pg-csv", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR);
-	}
-
-	if (zstr(globals.db_info)) {
-		globals.db_info = switch_core_strdup(pool, "dbname=cdr");
-	}
-
-	if (zstr(globals.db_table)) {
-		globals.db_table = switch_core_strdup(pool, "cdr");
-	}
-
-	if (zstr(globals.default_template)) {
-		globals.default_template = switch_core_strdup(pool, "default");
-	}
-
-	if (zstr(globals.spool_format)) {
-		globals.spool_format = switch_core_strdup(pool, "csv");
-	}
-
 	return status;
 }
 
@@ -588,8 +583,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cdr_pg_csv_load)
 
 	load_config(pool);
 
-	if ((status = switch_dir_make_recursive(globals.log_dir, SWITCH_DEFAULT_DIR_PERMS, pool)) != SWITCH_STATUS_SUCCESS) {
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", globals.log_dir);
+	if ((status = switch_dir_make_recursive(globals.spool_dir, SWITCH_DEFAULT_DIR_PERMS, pool)) != SWITCH_STATUS_SUCCESS) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", globals.spool_dir);
 		return status;
 	}
 
committer: cypromis
comments: 
more formatting mistakes *sigh*

diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c
index 1684127..f829e57 100644
--- a/src/mod/applications/mod_voicemail/mod_voicemail.c
+++ b/src/mod/applications/mod_voicemail/mod_voicemail.c
@@ -1277,9 +1277,9 @@ static void message_count(vm_profile_t *profile, const char *id_in, const char *
 
 	myid = resolve_id(id_in, domain_name, "message-count");
 
-	switch_snprintf(sql, sizeof(sql), "select 1, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' and read_epoch=0 group by read_flags union 
-	select 0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' and read_epoch<>0 group by read_flags;",	myid, domain_name, myfolder);
-
+	switch_snprintf(sql, sizeof(sql), "select 1, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' "
+									  "and read_epoch=0 group by read_flags union select 0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' "
+									  "and domain='%s' and in_folder='%s' and read_epoch<>0 group by read_flags;", myid, domain_name, myfolder);
 	vm_execute_sql_callback(profile, profile->mutex, sql, message_count_callback, &cbt);
 
 	*total_new_messages = cbt.total_new_messages + cbt.total_new_urgent_messages;
committer: cypromis
comments: 
seems whitespaces are unpopular on some linux/gcc combinations

diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c
index f868c3a..1684127 100644
--- a/src/mod/applications/mod_voicemail/mod_voicemail.c
+++ b/src/mod/applications/mod_voicemail/mod_voicemail.c
@@ -1277,11 +1277,8 @@ static void message_count(vm_profile_t *profile, const char *id_in, const char *
 
 	myid = resolve_id(id_in, domain_name, "message-count");
 
-	switch_snprintf(sql, sizeof(sql),
-					"select 1, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' and read_epoch=0 group by read_flags 
-					union 
-					select 0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' and read_epoch<>0 group by read_flags;",	
-					myid, domain_name, myfolder);
+	switch_snprintf(sql, sizeof(sql), "select 1, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' and read_epoch=0 group by read_flags union 
+	select 0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' and read_epoch<>0 group by read_flags;",	myid, domain_name, myfolder);
 
 	vm_execute_sql_callback(profile, profile->mutex, sql, message_count_callback, &cbt);
 
committer: cypromis
comments: 
FS-1742 - Make Voicemail use 1 SQL query instead of 4 to get the message count use in MWI - Now also working on your more favourite and less favourite databases

diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c
index 80b011e..f868c3a 100644
--- a/src/mod/applications/mod_voicemail/mod_voicemail.c
+++ b/src/mod/applications/mod_voicemail/mod_voicemail.c
@@ -1278,7 +1278,9 @@ static void message_count(vm_profile_t *profile, const char *id_in, const char *
 	myid = resolve_id(id_in, domain_name, "message-count");
 
 	switch_snprintf(sql, sizeof(sql),
-					"select read_epoch=0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' group by read_epoch=0,read_flags;",
+					"select 1, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' and read_epoch=0 group by read_flags 
+					union 
+					select 0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' and read_epoch<>0 group by read_flags;",	
 					myid, domain_name, myfolder);
 
 	vm_execute_sql_callback(profile, profile->mutex, sql, message_count_callback, &cbt);
committer: Leon de Rooij
comments: 
Merge branch 'master' of ssh://git.freeswitch.org/freeswitch
committer: Leon de Rooij
comments: 
reswig mod_lua for freeswitch.email

diff --git a/src/mod/languages/mod_lua/mod_lua_wrap.cpp b/src/mod/languages/mod_lua/mod_lua_wrap.cpp
index 1d84a39..559d403 100644
--- a/src/mod/languages/mod_lua/mod_lua_wrap.cpp
+++ b/src/mod/languages/mod_lua/mod_lua_wrap.cpp
@@ -1582,6 +1582,55 @@ fail:
 }
 
 
+static int _wrap_email(lua_State* L) {
+  int SWIG_arg = -1;
+  char *arg1 = (char *) 0 ;
+  char *arg2 = (char *) 0 ;
+  char *arg3 = (char *) NULL ;
+  char *arg4 = (char *) NULL ;
+  char *arg5 = (char *) NULL ;
+  char *arg6 = (char *) NULL ;
+  char *arg7 = (char *) NULL ;
+  bool result;
+  
+  SWIG_check_num_args("email",2,7)
+  if(!lua_isstring(L,1)) SWIG_fail_arg("email",1,"char *");
+  if(!lua_isstring(L,2)) SWIG_fail_arg("email",2,"char *");
+  if(lua_gettop(L)>=3 && !lua_isstring(L,3)) SWIG_fail_arg("email",3,"char *");
+  if(lua_gettop(L)>=4 && !lua_isstring(L,4)) SWIG_fail_arg("email",4,"char *");
+  if(lua_gettop(L)>=5 && !lua_isstring(L,5)) SWIG_fail_arg("email",5,"char *");
+  if(lua_gettop(L)>=6 && !lua_isstring(L,6)) SWIG_fail_arg("email",6,"char *");
+  if(lua_gettop(L)>=7 && !lua_isstring(L,7)) SWIG_fail_arg("email",7,"char *");
+  arg1 = (char *)lua_tostring(L, 1);
+  arg2 = (char *)lua_tostring(L, 2);
+  if(lua_gettop(L)>=3){
+    arg3 = (char *)lua_tostring(L, 3);
+  }
+  if(lua_gettop(L)>=4){
+    arg4 = (char *)lua_tostring(L, 4);
+  }
+  if(lua_gettop(L)>=5){
+    arg5 = (char *)lua_tostring(L, 5);
+  }
+  if(lua_gettop(L)>=6){
+    arg6 = (char *)lua_tostring(L, 6);
+  }
+  if(lua_gettop(L)>=7){
+    arg7 = (char *)lua_tostring(L, 7);
+  }
+  result = (bool)email(arg1,arg2,arg3,arg4,arg5,arg6,arg7);
+  SWIG_arg=0;
+  lua_pushboolean(L,(int)(result==true)); SWIG_arg++;
+  return SWIG_arg;
+  
+  if(0) SWIG_fail;
+  
+fail:
+  lua_error(L);
+  return SWIG_arg;
+}
+
+
 static int _wrap_new_IVRMenu(lua_State* L) {
   int SWIG_arg = -1;
   IVRMenu *arg1 = (IVRMenu *) 0 ;
@@ -7525,6 +7574,7 @@ static swig_lua_class _wrap_class_LUA_Dbh = { "Dbh", &SWIGTYPE_p_LUA__Dbh,_wrap_
 static const struct luaL_reg swig_commands[] = {
     { "consoleLog", _wrap_consoleLog},
     { "consoleCleanLog", _wrap_consoleCleanLog},
+    { "email", _wrap_email},
     { "console_log", _wrap_console_log},
     { "console_clean_log", _wrap_console_clean_log},
     { "msleep", _wrap_msleep},
committer: Mathieu Rene
comments: 
Add libjpeg-dev to apt prereqs

diff --git a/support-d/prereq.sh b/support-d/prereq.sh
index 4e214cf..8bc454d 100755
--- a/support-d/prereq.sh
+++ b/support-d/prereq.sh
@@ -2,7 +2,7 @@ UNAME=`uname`
 
 
 NEEDED_PACKAGES_YUM='automake autoconf libtool screen gdb gcc-c++ compat-gcc-32 compat-gcc-32-c++ subversion ncurses-devel unixODBC-devel make wget'
-NEEDED_PACAKGES_APT='automake autoconf libtool screen gdb libncurses5-dev unixodbc-dev subversion emacs22-nox gcc g++ make'
+NEEDED_PACAKGES_APT='automake autoconf libtool screen gdb libncurses5-dev unixodbc-dev subversion emacs22-nox gcc g++ make libjpeg-dev'
 NEEDED_PACKAGES_PKG_ADD=''
 
 
committer: Mathieu Rene
comments: 
Add session.ringReady() to check for CF_RING_READY

diff --git a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
index 1d6ee8d..a818c1d 100644
--- a/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
+++ b/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
@@ -2126,6 +2126,15 @@ static JSBool session_media_ready(JSContext * cx, JSObject * obj, uintN argc, js
 }
 
 
+static JSBool session_ring_ready(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
+{
+	struct js_session *jss = JS_GetPrivate(cx, obj);
+
+	*rval = BOOLEAN_TO_JSVAL((jss && jss->session && switch_channel_test_flag(switch_core_session_get_channel(jss->session), CF_RING_READY)) ? JS_TRUE : JS_FALSE);
+
+	return JS_TRUE;
+}
+
 static JSBool session_answered(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
 {
 	struct js_session *jss = JS_GetPrivate(cx, obj);
@@ -2673,6 +2682,7 @@ static JSFunctionSpec session_methods[] = {
 	{"ready", session_ready, 0},
 	{"answered", session_answered, 0},
 	{"mediaReady", session_media_ready, 0},
+	{"ringReady", session_ring_ready, 0},
 	{"waitForAnswer", session_wait_for_answer, 0},
 	{"waitForMedia", session_wait_for_media, 0},
 	{"getEvent", session_get_event, 0},
committer: Mathieu Rene
comments: 
xml_config: change min/max enforcements to >= instead of >

diff --git a/src/switch_xml_config.c b/src/switch_xml_config.c
index b6b37bd..5ade057 100644
--- a/src/switch_xml_config.c
+++ b/src/switch_xml_config.c
@@ -177,7 +177,7 @@ SWITCH_DECLARE(switch_status_t) switch_xml_config_parse_event(switch_event_t *ev
 
 					if (int_options) {
 						/* Enforce validation options */
-						if ((int_options->enforce_min && !(intval > int_options->min)) || (int_options->enforce_max && !(intval < int_options->max))) {
+						if ((int_options->enforce_min && !(intval >= int_options->min)) || (int_options->enforce_max && !(intval <= int_options->max))) {
 							/* Validation failed, set default */
 							intval = (int) (intptr_t) item->defaultvalue;
 							/* Then complain */
committer: Leon de Rooij
comments: 
Merge branch 'master' of ssh://git.freeswitch.org/freeswitch
committer: Anthony Minessale
comments: 
nm 40 doesn't work yet

diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c
index 0234ed8..b9a3120 100644
--- a/src/mod/codecs/mod_opus/mod_opus.c
+++ b/src/mod/codecs/mod_opus/mod_opus.c
@@ -159,7 +159,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load)
 
 	SWITCH_ADD_CODEC(codec_interface, "OPUS (BETA 0.9.0)");
 
-	for (x = 0; x < 3; x++) {
+	for (x = 0; x < 2; x++) {
 		switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO,	/* enumeration defining the type of the codec */
 											 115,	/* the IANA code number */
 											 "Opus-0.9.0",/* the IANA code name */
committer: Anthony Minessale
comments: 
add 10 20 and 40ms

diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c
index ddb5a7a..0234ed8 100644
--- a/src/mod/codecs/mod_opus/mod_opus.c
+++ b/src/mod/codecs/mod_opus/mod_opus.c
@@ -147,52 +147,43 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
 SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load)
 {
 	switch_codec_interface_t *codec_interface;
+	int samples = 80;
+	int bytes = 960;
+	int mss = 10000;
+	int x = 0;
+	int rate = 48000;
+	int bits = 32000;
 
 	/* connect my internal structure to the blank pointer passed to me */
 	*module_interface = switch_loadable_module_create_module_interface(pool, modname);
 
 	SWITCH_ADD_CODEC(codec_interface, "OPUS (BETA 0.9.0)");
 
-	switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO,	/* enumeration defining the type of the codec */
-										 115,	/* the IANA code number */
-										 "Opus-0.9.0",/* the IANA code name */
-										 NULL,	/* default fmtp to send (can be overridden by the init function) */
-										 48000,	/* samples transferred per second */
-										 48000,	/* actual samples transferred per second */
-										 32000,	/* bits transferred per second */
-										 10000,	/* number of microseconds per frame */
-										 80,	/* number of samples per frame */
-										 960,	/* number of bytes per frame decompressed */
-										 0,	/* number of bytes per frame compressed */
-										 1,	/* number of channels represented */
-										 1,	/* number of frames per network packet */
-										 switch_opus_init,	/* function to initialize a codec handle using this implementation */
-										 switch_opus_encode,	/* function to encode raw data into encoded data */
-										 switch_opus_decode,	/* function to decode encoded data into raw data */
-										 switch_opus_destroy);	/* deinitalize a codec handle using this implementation */
-
-
-	switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO,	/* enumeration defining the type of the codec */
-										 115,	/* the IANA code number */
-										 "Opus-0.9.0",	/* the IANA code name */
-										 NULL,	/* default fmtp to send (can be overridden by the init function) */
-										 48000,	/* samples transferred per second */
-										 48000,	/* actual samples transferred per second */
-										 32000,	/* bits transferred per second */
-										 20000,	/* number of microseconds per frame */
-										 160,	/* number of samples per frame */
-										 1920,	/* number of bytes per frame decompressed */
-										 0,	/* number of bytes per frame compressed */
-										 1,	/* number of channels represented */
-										 1,	/* number of frames per network packet */
-										 switch_opus_init,	/* function to initialize a codec handle using this implementation */
-										 switch_opus_encode,	/* function to encode raw data into encoded data */
-										 switch_opus_decode,	/* function to decode encoded data into raw data */
-										 switch_opus_destroy);	/* deinitalize a codec handle using this implementation */
-
-
-
+	for (x = 0; x < 3; x++) {
+		switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO,	/* enumeration defining the type of the codec */
+											 115,	/* the IANA code number */
+											 "Opus-0.9.0",/* the IANA code name */
+											 NULL,	/* default fmtp to send (can be overridden by the init function) */
+											 rate,	/* samples transferred per second */
+											 rate,	/* actual samples transferred per second */
+											 bits,	/* bits transferred per second */
+											 mss,	/* number of microseconds per frame */
+											 samples,	/* number of samples per frame */
+											 bytes,	/* number of bytes per frame decompressed */
+											 0,	/* number of bytes per frame compressed */
+											 1,	/* number of channels represented */
+											 1,	/* number of frames per network packet */
+											 switch_opus_init,	/* function to initialize a codec handle using this implementation */
+											 switch_opus_encode,	/* function to encode raw data into encoded data */
+											 switch_opus_decode,	/* function to decode encoded data into raw data */
+											 switch_opus_destroy);	/* deinitalize a codec handle using this implementation */
+		
+		bytes *= 2;
+		samples *= 2;
+		mss *= 2;
 
+	}
+	
 	/* indicate that the module should continue to be loaded */
 	return SWITCH_STATUS_SUCCESS;
 }
committer: Anthony Minessale
comments: 
change signalling name to avoid polluting the namespace before its ready

diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c
index 341254f..ddb5a7a 100644
--- a/src/mod/codecs/mod_opus/mod_opus.c
+++ b/src/mod/codecs/mod_opus/mod_opus.c
@@ -151,11 +151,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load)
 	/* connect my internal structure to the blank pointer passed to me */
 	*module_interface = switch_loadable_module_create_module_interface(pool, modname);
 
-	SWITCH_ADD_CODEC(codec_interface, "OPUS (BETA)");
+	SWITCH_ADD_CODEC(codec_interface, "OPUS (BETA 0.9.0)");
 
 	switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO,	/* enumeration defining the type of the codec */
 										 115,	/* the IANA code number */
-										 "OPUS",	/* the IANA code name */
+										 "Opus-0.9.0",/* the IANA code name */
 										 NULL,	/* default fmtp to send (can be overridden by the init function) */
 										 48000,	/* samples transferred per second */
 										 48000,	/* actual samples transferred per second */
@@ -174,7 +174,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load)
 
 	switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO,	/* enumeration defining the type of the codec */
 										 115,	/* the IANA code number */
-										 "OPUS",	/* the IANA code name */
+										 "Opus-0.9.0",	/* the IANA code name */
 										 NULL,	/* default fmtp to send (can be overridden by the init function) */
 										 48000,	/* samples transferred per second */
 										 48000,	/* actual samples transferred per second */
committer: Anthony Minessale
comments: 
add mod_opus

diff --git a/build/modules.conf.in b/build/modules.conf.in
index 84a9e9a..8d3dfaa 100644
--- a/build/modules.conf.in
+++ b/build/modules.conf.in
@@ -48,6 +48,7 @@ codecs/mod_ilbc
 codecs/mod_speex
 codecs/mod_siren
 #codecs/mod_celt
+#codecs/mod_opus
 #codecs/mod_sangoma_codec
 #codecs/mod_dahdi_codec
 #dialplans/mod_dialplan_directory
diff --git a/conf/autoload_configs/modules.conf.xml b/conf/autoload_configs/modules.conf.xml
index 2e7ebfa..8b4a4e7 100644
--- a/conf/autoload_configs/modules.conf.xml
+++ b/conf/autoload_configs/modules.conf.xml
@@ -78,6 +78,7 @@
     <load module="mod_h26x"/>
     <load module="mod_siren"/>
     <!--<load module="mod_celt"/>-->
+    <!--<load module="mod_opus"/>-->
 
     <!-- File Format Interfaces -->
     <load module="mod_sndfile"/>
diff --git a/src/mod/codecs/mod_opus/Makefile b/src/mod/codecs/mod_opus/Makefile
new file mode 100644
index 0000000..a346956
--- /dev/null
+++ b/src/mod/codecs/mod_opus/Makefile
@@ -0,0 +1,28 @@
+BASE=../../../..
+
+OPUS=opus-0.9.0
+
+OPUS_DIR=$(switch_srcdir)/libs/$(OPUS)
+OPUS_BUILDDIR=$(switch_builddir)/libs/$(OPUS)
+LOCAL_CFLAGS=-I$(OPUS_DIR)/src -g -O2
+
+IETF_LA=$(OPUS_BUILDDIR)/src/.libs/libietfcodec.a
+CELT_LA=$(OPUS_BUILDDIR)/celt/libcelt/.libs/libcelt0.a
+SILK_LA=$(OPUS_BUILDDIR)/silk/.libs/libSKP_SILK_SDK.a
+
+LOCAL_LIBADD=$(IETF_LA) $(CELT_LA) $(SILK_LA) -lm -lz
+
+include $(BASE)/build/modmake.rules
+
+$(OPUS_DIR):
+	$(GETLIB) $(OPUS).tar.gz
+
+$(OPUS_BUILDDIR)/Makefile: $(OPUS_DIR)
+	mkdir -p $(OPUS_BUILDDIR)
+	cd $(OPUS_BUILDDIR) && $(DEFAULT_VARS) $(OPUS_DIR)/configure --disable-shared --with-pic --srcdir=$(OPUS_DIR)
+	$(TOUCH_TARGET)
+
+$(IETF_LA): $(OPUS_BUILDDIR)/Makefile
+	cd $(OPUS_BUILDDIR) && $(MAKE)
+	$(TOUCH_TARGET)
+
diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c
new file mode 100644
index 0000000..341254f
--- /dev/null
+++ b/src/mod/codecs/mod_opus/mod_opus.c
@@ -0,0 +1,209 @@
+/* 
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II <anthm@freeswitch.org>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Brian K. West <brian@freeswitch.org>
+ *
+ * mod_opus.c -- The OPUS ultra-low delay audio codec (http://www.opus-codec.org/)
+ *
+ */
+
+#include "switch.h"
+#include "opus.h"
+
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load);
+SWITCH_MODULE_DEFINITION(mod_opus, mod_opus_load, NULL, NULL);
+
+struct opus_context {
+	OpusEncoder *encoder_object;
+	OpusDecoder *decoder_object;
+	int frame_size;
+};
+
+static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
+{
+	struct opus_context *context = NULL;
+	int encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
+	int decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
+
+	if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
+		return SWITCH_STATUS_FALSE;
+	}
+
+	context->frame_size = codec->implementation->samples_per_packet;
+	
+	if (encoding) {
+		/* come up with a way to specify these */
+		int bitrate_bps = codec->implementation->bits_per_second;
+		int mode = MODE_HYBRID;
+		int use_vbr = 1;
+		int complexity = 10;
+		int use_inbandfec = 1;
+		int use_dtx = 1;
+		int bandwidth = BANDWIDTH_FULLBAND;
+
+		context->encoder_object = opus_encoder_create(codec->implementation->actual_samples_per_second, codec->implementation->number_of_channels);
+
+		opus_encoder_ctl(context->encoder_object, OPUS_SET_MODE(mode));
+		opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(bitrate_bps));
+		opus_encoder_ctl(context->encoder_object, OPUS_SET_BANDWIDTH(bandwidth));
+		opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR_FLAG(use_vbr));
+		opus_encoder_ctl(context->encoder_object, OPUS_SET_COMPLEXITY(complexity));
+		opus_encoder_ctl(context->encoder_object, OPUS_SET_INBAND_FEC_FLAG(use_inbandfec));
+		opus_encoder_ctl(context->encoder_object, OPUS_SET_DTX_FLAG(use_dtx));
+
+	}
+	
+	if (decoding) {
+		context->decoder_object = opus_decoder_create(codec->implementation->actual_samples_per_second, codec->implementation->number_of_channels);
+	}
+
+	codec->private_info = context;
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t switch_opus_destroy(switch_codec_t *codec)
+{
+	codec->private_info = NULL;
+	return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t switch_opus_encode(switch_codec_t *codec,
+										  switch_codec_t *other_codec,
+										  void *decoded_data,
+										  uint32_t decoded_data_len,
+										  uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate,
+										  unsigned int *flag)
+{
+	struct opus_context *context = codec->private_info;
+	int bytes = 0;
+	int len = (int) *encoded_data_len;
+
+	if (!context) {
+		return SWITCH_STATUS_FALSE;
+	}
+
+	if (len > 1275) len = 1275;
+
+	bytes = opus_encode(context->encoder_object, (void *) decoded_data, decoded_data_len / 2, (unsigned char *) encoded_data, len);
+	
+	if (bytes > 0) {
+		*encoded_data_len = (uint32_t) bytes;
+		return SWITCH_STATUS_SUCCESS;
+	}
+
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoder Error!\n");
+	return SWITCH_STATUS_GENERR;
+}
+
+static switch_status_t switch_opus_decode(switch_codec_t *codec,
+										  switch_codec_t *other_codec,
+										  void *encoded_data,
+										  uint32_t encoded_data_len,
+										  uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate,
+										  unsigned int *flag)
+{
+	struct opus_context *context = codec->private_info;
+	int samples = 0;
+
+	if (!context) {
+		return SWITCH_STATUS_FALSE;
+	}
+	
+	samples = opus_decode(context->decoder_object, encoded_data, encoded_data_len, decoded_data, *decoded_data_len);
+
+	if (samples < 0) {
+		return SWITCH_STATUS_GENERR;
+	}
+
+	*decoded_data_len = samples * 2;
+	
+	return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load)
+{
+	switch_codec_interface_t *codec_interface;
+
+	/* connect my internal structure to the blank pointer passed to me */
+	*module_interface = switch_loadable_module_create_module_interface(pool, modname);
+
+	SWITCH_ADD_CODEC(codec_interface, "OPUS (BETA)");
+
+	switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO,	/* enumeration defining the type of the codec */
+										 115,	/* the IANA code number */
+										 "OPUS",	/* the IANA code name */
+										 NULL,	/* default fmtp to send (can be overridden by the init function) */
+										 48000,	/* samples transferred per second */
+										 48000,	/* actual samples transferred per second */
+										 32000,	/* bits transferred per second */
+										 10000,	/* number of microseconds per frame */
+										 80,	/* number of samples per frame */
+										 960,	/* number of bytes per frame decompressed */
+										 0,	/* number of bytes per frame compressed */
+										 1,	/* number of channels represented */
+										 1,	/* number of frames per network packet */
+										 switch_opus_init,	/* function to initialize a codec handle using this implementation */
+										 switch_opus_encode,	/* function to encode raw data into encoded data */
+										 switch_opus_decode,	/* function to decode encoded data into raw data */
+										 switch_opus_destroy);	/* deinitalize a codec handle using this implementation */
+
+
+	switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO,	/* enumeration defining the type of the codec */
+										 115,	/* the IANA code number */
+										 "OPUS",	/* the IANA code name */
+										 NULL,	/* default fmtp to send (can be overridden by the init function) */
+										 48000,	/* samples transferred per second */
+										 48000,	/* actual samples transferred per second */
+										 32000,	/* bits transferred per second */
+										 20000,	/* number of microseconds per frame */
+										 160,	/* number of samples per frame */
+										 1920,	/* number of bytes per frame decompressed */
+										 0,	/* number of bytes per frame compressed */
+										 1,	/* number of channels represented */
+										 1,	/* number of frames per network packet */
+										 switch_opus_init,	/* function to initialize a codec handle using this implementation */
+										 switch_opus_encode,	/* function to encode raw data into encoded data */
+										 switch_opus_decode,	/* function to decode encoded data into raw data */
+										 switch_opus_destroy);	/* deinitalize a codec handle using this implementation */
+
+
+
+
+	/* indicate that the module should continue to be loaded */
+	return SWITCH_STATUS_SUCCESS;
+}
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
committer: Christopher Rienzo
comments: 
forgot this spot when closing speech channel

diff --git a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c
index 812744c..734ef21 100644
--- a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c
+++ b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c
@@ -1362,6 +1362,8 @@ static switch_status_t speech_channel_stop(speech_channel_t *schannel)
 			goto done;
 		}
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) %s stopped\n", schannel->name, speech_channel_type_to_string(schannel->type));
+	} else if (schannel->state == SPEECH_CHANNEL_DONE) {
+		speech_channel_set_state(schannel, SPEECH_CHANNEL_READY);
 	}
 
   done:
committer: Christopher Rienzo
comments: 
FS-3201 fix truncated TTS

diff --git a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c
index 5db1491..812744c 100644
--- a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c
+++ b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c
@@ -260,6 +260,7 @@ static switch_status_t audio_queue_create(audio_queue_t ** queue, const char *na
 static switch_status_t audio_queue_write(audio_queue_t *queue, void *data, switch_size_t *data_len);
 static switch_status_t audio_queue_read(audio_queue_t *queue, void *data, switch_size_t *data_len, int block);
 static switch_status_t audio_queue_clear(audio_queue_t *queue);
+static switch_status_t audio_queue_signal(audio_queue_t *queue);
 static switch_status_t audio_queue_destroy(audio_queue_t *queue);
 
 /*********************************************************************************************************************************************
@@ -287,6 +288,8 @@ enum speech_channel_state {
 	SPEECH_CHANNEL_READY,
 	/** processing speech request */
 	SPEECH_CHANNEL_PROCESSING,
+	/** finished processing speech request */
+	SPEECH_CHANNEL_DONE,
 	/** error opening channel */
 	SPEECH_CHANNEL_ERROR
 };
@@ -667,10 +670,12 @@ static switch_status_t audio_queue_create(audio_queue_t ** audio_queue, const ch
 static switch_status_t audio_queue_write(audio_queue_t *queue, void *data, switch_size_t *data_len)
 {
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
+#ifdef MOD_UNIMRCP_DEBUG_AUDIO_QUEUE
+	switch_size_t len = *data_len;
+#endif
 	switch_mutex_lock(queue->mutex);
 
 #ifdef MOD_UNIMRCP_DEBUG_AUDIO_QUEUE
-	switch_size_t len = *data_len;
 	if (queue->file_write) {
 		switch_file_write(queue->file_write, data, &len);
 	}
@@ -708,6 +713,9 @@ static switch_status_t audio_queue_read(audio_queue_t *queue, void *data, switch
 {
 	switch_size_t requested = *data_len;
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
+#ifdef MOD_UNIMRCP_DEBUG_AUDIO_QUEUE
+	switch_size_t len = *data_len;
+#endif
 	switch_mutex_lock(queue->mutex);
 
 	/* wait for data, if allowed */
@@ -736,7 +744,6 @@ static switch_status_t audio_queue_read(audio_queue_t *queue, void *data, switch
 #ifdef MOD_UNIMRCP_DEBUG_AUDIO_QUEUE
 	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) audio queue read total = %ld\tread = %ld\trequested = %ld\n", queue->name,
 					  queue->read_bytes, *data_len, requested);
-	switch_size_t len = *data_len;
 	if (queue->file_read) {
 		switch_file_write(queue->file_read, data, &len);
 	}
@@ -764,6 +771,20 @@ static switch_status_t audio_queue_clear(audio_queue_t *queue)
 }
 
 /**
+ * Wake any threads waiting on this queue
+ *
+ * @param queue the queue to empty
+ * @return SWITCH_STATUS_SUCCESS
+ */
+static switch_status_t audio_queue_signal(audio_queue_t *queue)
+{
+	switch_mutex_lock(queue->mutex);
+	switch_thread_cond_signal(queue->cond);
+	switch_mutex_unlock(queue->mutex);
+	return SWITCH_STATUS_SUCCESS;
+}
+
+/**
  * Destroy the audio queue
  *
  * @param queue the queue to clean up
@@ -1438,9 +1459,19 @@ static switch_status_t speech_channel_read(speech_channel_t *schannel, void *dat
 	}
 
 	switch_mutex_lock(schannel->mutex);
-	if (schannel->state == SPEECH_CHANNEL_PROCESSING) {
+	switch (schannel->state) {
+	case SPEECH_CHANNEL_DONE:
+		/* pull any remaining audio - never blocking */
+		if (audio_queue_read(schannel->audio_queue, data, len, 0) == SWITCH_STATUS_FALSE) {
+			/* all frames read */
+			status = SWITCH_STATUS_BREAK;
+		}
+		break;
+	case SPEECH_CHANNEL_PROCESSING:
+		/* IN-PROGRESS */
 		audio_queue_read(schannel->audio_queue, data, len, block);
-	} else {
+		break;
+	default:
 		status = SWITCH_STATUS_BREAK;
 	}
 	switch_mutex_unlock(schannel->mutex);
@@ -1463,6 +1494,8 @@ static const char *speech_channel_state_to_string(speech_channel_state_t state)
 		return "READY";
 	case SPEECH_CHANNEL_PROCESSING:
 		return "PROCESSING";
+	case SPEECH_CHANNEL_DONE:
+		return "DONE";
 	case SPEECH_CHANNEL_ERROR:
 		return "ERROR";
 	}
@@ -1498,7 +1531,7 @@ static switch_status_t speech_channel_set_state_unlocked(speech_channel_t *schan
 {
 	if (schannel->state == SPEECH_CHANNEL_PROCESSING && state != SPEECH_CHANNEL_PROCESSING) {
 		/* wake anyone waiting for audio data */
-		audio_queue_clear(schannel->audio_queue);
+		audio_queue_signal(schannel->audio_queue);
 	}
 
 	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) %s ==> %s\n", schannel->name, speech_channel_state_to_string(schannel->state),
@@ -1651,6 +1684,8 @@ static switch_status_t synth_speech_read_tts(switch_speech_handle_t *sh, void *d
 			memset((uint8_t *) data + bytes_read, schannel->silence, *datalen - bytes_read);
 		}
 	} else {
+		/* ready for next speak request */
+		speech_channel_set_state(schannel, SPEECH_CHANNEL_READY);
 		*datalen = 0;
 		status = SWITCH_STATUS_BREAK;
 	}
@@ -1878,7 +1913,7 @@ static apt_bool_t synth_on_message_receive(mrcp_application_t *application, mrcp
 			if (message->start_line.request_state == MRCP_REQUEST_STATE_COMPLETE) {
 				/* got COMPLETE */
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) COMPLETE\n", schannel->name);
-				speech_channel_set_state(schannel, SPEECH_CHANNEL_READY);
+				speech_channel_set_state(schannel, SPEECH_CHANNEL_DONE);
 			} else {
 				/* received unexpected request state */
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) unexpected STOP response, request_state = %d\n", schannel->name,
@@ -1896,7 +1931,7 @@ static apt_bool_t synth_on_message_receive(mrcp_application_t *application, mrcp
 		if (message->start_line.method_id == SYNTHESIZER_SPEAK_COMPLETE) {
 			/* got SPEAK-COMPLETE */
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) SPEAK-COMPLETE\n", schannel->name);
-			speech_channel_set_state(schannel, SPEECH_CHANNEL_READY);
+			speech_channel_set_state(schannel, SPEECH_CHANNEL_DONE);
 		} else {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) unexpected event, method_id = %d\n", schannel->name,
 							  (int) message->start_line.method_id);
committer: Anthony Minessale
comments: 
add default to conf to demonstrate min-idle-cpu

diff --git a/conf/autoload_configs/switch.conf.xml b/conf/autoload_configs/switch.conf.xml
index 8342f12..32cb76f 100644
--- a/conf/autoload_configs/switch.conf.xml
+++ b/conf/autoload_configs/switch.conf.xml
@@ -23,6 +23,10 @@
   <settings>
     <!--Colorize the Console -->
     <param name="colorize-console" value="true"/>
+
+    <!-- minimum idle CPU before refusing calls -->
+    <param name="min-idle-cpu" value="25"/>
+
     <!--
 	Max number of sessions to allow at any given time.
 	
committer: Anthony Minessale
comments: 
fix sql err

diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c
index a38a61e..2313cb7 100644
--- a/src/mod/endpoints/mod_sofia/sofia_presence.c
+++ b/src/mod/endpoints/mod_sofia/sofia_presence.c
@@ -2576,7 +2576,7 @@ uint32_t sofia_presence_contact_count(sofia_profile_t *profile, const char *cont
 	char buf[32] = "";
 	char *sql;
 	
-	sql = switch_mprintf("select count(*) from sip_subscriptions where profile_name='%q' and contact_str='%q'", profile->name, contact_str);
+	sql = switch_mprintf("select count(*) from sip_subscriptions where profile_name='%q' and contact='%q'", profile->name, contact_str);
 	
 	sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, buf, sizeof(buf));
 	switch_safe_free(sql);
committer: Jeff Lenk
comments: 
FS-3033 VS2010 libportaudio project improvements for DirectX builds and switch to build DirectX by default

diff --git a/Freeswitch.2010.sln b/Freeswitch.2010.sln
index edee701..464cb2e 100644
--- a/Freeswitch.2010.sln
+++ b/Freeswitch.2010.sln
@@ -1569,18 +1569,18 @@ Global
 		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.All|x64 Setup.ActiveCfg = Release DirectSound|x64
 		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.All|x64 Setup.Build.0 = Release DirectSound|x64
 		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.All|x86 Setup.ActiveCfg = Release DirectSound|x64
-		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.ActiveCfg = Debug|Win32
-		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.Build.0 = Debug|Win32
-		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.ActiveCfg = Debug|x64
-		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.Build.0 = Debug|x64
-		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64 Setup.ActiveCfg = Debug|x64
-		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x86 Setup.ActiveCfg = Debug|Win32
-		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.ActiveCfg = Release|Win32
-		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.Build.0 = Release|Win32
-		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.ActiveCfg = Release|x64
-		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.Build.0 = Release|x64
-		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64 Setup.ActiveCfg = Release|x64
-		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x86 Setup.ActiveCfg = Release|Win32
+		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.ActiveCfg = Debug DirectSound|Win32
+		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|Win32.Build.0 = Debug DirectSound|Win32
+		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.ActiveCfg = Debug DirectSound|x64
+		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64.Build.0 = Debug DirectSound|x64
+		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x64 Setup.ActiveCfg = Debug DirectSound|x64
+		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Debug|x86 Setup.ActiveCfg = Debug DirectSound|Win32
+		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.ActiveCfg = Release DirectSound|Win32
+		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|Win32.Build.0 = Release DirectSound|Win32
+		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.ActiveCfg = Release DirectSound|x64
+		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64.Build.0 = Release DirectSound|x64
+		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x64 Setup.ActiveCfg = Release DirectSound|x64
+		{0A18A071-125E-442F-AFF7-A3F68ABECF99}.Release|x86 Setup.ActiveCfg = Release DirectSound|Win32
 		{08DAD348-9E0A-4A2E-97F1-F1E7E24A7836}.All|Win32.ActiveCfg = Release|x64
 		{08DAD348-9E0A-4A2E-97F1-F1E7E24A7836}.All|x64.ActiveCfg = Release|x64
 		{08DAD348-9E0A-4A2E-97F1-F1E7E24A7836}.All|x64.Build.0 = Release|x64
diff --git a/libs/portaudio/build/msvc/portaudio.2010.vcxproj b/libs/portaudio/build/msvc/portaudio.2010.vcxproj
index b4eca56..10b4c25 100644
--- a/libs/portaudio/build/msvc/portaudio.2010.vcxproj
+++ b/libs/portaudio/build/msvc/portaudio.2010.vcxproj
@@ -41,11 +41,11 @@
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseOfMfc>false</UseOfMfc>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseOfMfc>false</UseOfMfc>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@@ -57,11 +57,11 @@
     <UseOfMfc>false</UseOfMfc>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseOfMfc>false</UseOfMfc>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseOfMfc>false</UseOfMfc>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
@@ -77,9 +77,11 @@
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\..\..\..\w32\extlib.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\..\..\..\w32\extlib.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
@@ -92,10 +94,12 @@
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
+    <Import Project="..\..\..\..\w32\extlib.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
+    <Import Project="..\..\..\..\w32\extlib.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
@@ -110,18 +114,6 @@
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">$(Configuration)\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">$(Configuration)\</IntDir>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">true</LinkIncremental>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">$(Platform)\$(Configuration)\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">$(Platform)\$(Configuration)\</IntDir>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">true</LinkIncremental>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">$(Configuration)\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">$(Configuration)\</IntDir>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">false</LinkIncremental>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">$(Platform)\$(Configuration)\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">$(Platform)\$(Configuration)\</IntDir>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">false</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <Midl>
@@ -231,45 +223,23 @@
       <MkTypLibCompatible>true</MkTypLibCompatible>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <TargetEnvironment>Win32</TargetEnvironment>
-      <TypeLibraryName>.\Debug_x86/portaudio.tlb</TypeLibraryName>
-      <HeaderFileName>
-      </HeaderFileName>
     </Midl>
     <ClCompile>
       <Optimization>Disabled</Optimization>
       <AdditionalIncludeDirectories>..\..\src\common;..\..\include;.\;..\..\src\os\win;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PAWIN_USE_WDMKS_DEVICE_INFO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PA_NO_WMME;PAWIN_USE_WDMKS_DEVICE_INFO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <MinimalRebuild>true</MinimalRebuild>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <PrecompiledHeaderOutputFile>$(Platform)\$(Configuration)/portaudio.pch</PrecompiledHeaderOutputFile>
-      <AssemblerListingLocation>$(Platform)\$(Configuration)\</AssemblerListingLocation>
-      <ObjectFileName>$(Platform)\$(Configuration)\</ObjectFileName>
-      <ProgramDataBaseFileName>$(Platform)\$(Configuration)\</ProgramDataBaseFileName>
       <WarningLevel>Level3</WarningLevel>
       <SuppressStartupBanner>true</SuppressStartupBanner>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
     <ResourceCompile>
       <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <Culture>0x0409</Culture>
     </ResourceCompile>
-    <Link>
-      <AdditionalDependencies>ksuser.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <OutputFile>$(Platform)\$(Configuration)\portaudio_x86.dll</OutputFile>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <ModuleDefinitionFile>.\portaudio.def</ModuleDefinitionFile>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <ProgramDatabaseFile>$(Platform)\$(Configuration)\portaudio_x86.pdb</ProgramDatabaseFile>
-      <RandomizedBaseAddress>false</RandomizedBaseAddress>
-      <DataExecutionPrevention>
-      </DataExecutionPrevention>
-      <ImportLibrary>$(Platform)\$(Configuration)\portaudio_x86.lib</ImportLibrary>
-      <TargetMachine>MachineX86</TargetMachine>
-    </Link>
     <Bscmake>
       <SuppressStartupBanner>true</SuppressStartupBanner>
-      <OutputFile>$(Platform)\$(Configuration)\portaudio.bsc</OutputFile>
     </Bscmake>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">
@@ -278,45 +248,23 @@
       <MkTypLibCompatible>true</MkTypLibCompatible>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <TargetEnvironment>X64</TargetEnvironment>
-      <TypeLibraryName>.\Debug_x86/portaudio.tlb</TypeLibraryName>
-      <HeaderFileName>
-      </HeaderFileName>
     </Midl>
     <ClCompile>
       <Optimization>Disabled</Optimization>
       <AdditionalIncludeDirectories>..\..\src\common;..\..\include;.\;..\..\src\os\win;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PAWIN_USE_WDMKS_DEVICE_INFO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PA_NO_WMME;PAWIN_USE_WDMKS_DEVICE_INFO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <MinimalRebuild>true</MinimalRebuild>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <PrecompiledHeaderOutputFile>$(Platform)\$(Configuration)\portaudio.pch</PrecompiledHeaderOutputFile>
-      <AssemblerListingLocation>$(Platform)\$(Configuration)\</AssemblerListingLocation>
-      <ObjectFileName>$(Platform)\$(Configuration)\</ObjectFileName>
-      <ProgramDataBaseFileName>$(Platform)\$(Configuration)\</ProgramDataBaseFileName>
       <WarningLevel>Level3</WarningLevel>
       <SuppressStartupBanner>true</SuppressStartupBanner>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
     <ResourceCompile>
       <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <Culture>0x0409</Culture>
     </ResourceCompile>
-    <Link>
-      <AdditionalDependencies>ksuser.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <OutputFile>$(Platform)\$(Configuration)\portaudio_x64.dll</OutputFile>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <ModuleDefinitionFile>.\portaudio.def</ModuleDefinitionFile>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <ProgramDatabaseFile>$(Platform)\$(Configuration)/portaudio_x64.pdb</ProgramDatabaseFile>
-      <RandomizedBaseAddress>false</RandomizedBaseAddress>
-      <DataExecutionPrevention>
-      </DataExecutionPrevention>
-      <ImportLibrary>$(Platform)\$(Configuration)\portaudio_x64.lib</ImportLibrary>
-      <TargetMachine>MachineX64</TargetMachine>
-    </Link>
     <Bscmake>
       <SuppressStartupBanner>true</SuppressStartupBanner>
-      <OutputFile>$(Platform)\$(Configuration)/portaudio_x64.bsc</OutputFile>
     </Bscmake>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">
@@ -325,22 +273,15 @@
       <MkTypLibCompatible>true</MkTypLibCompatible>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <TargetEnvironment>Win32</TargetEnvironment>
-      <TypeLibraryName>.\Release_x86/portaudio.tlb</TypeLibraryName>
-      <HeaderFileName>
-      </HeaderFileName>
     </Midl>
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
-      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
       <AdditionalIncludeDirectories>..\..\src\common;..\..\include;.\;..\..\src\os\win;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PA_NO_WMME;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <StringPooling>true</StringPooling>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <FunctionLevelLinking>true</FunctionLevelLinking>
-      <PrecompiledHeaderOutputFile>$(Platform)\$(Configuration)/portaudio.pch</PrecompiledHeaderOutputFile>
-      <AssemblerListingLocation>$(Platform)\$(Configuration)\</AssemblerListingLocation>
-      <ObjectFileName>$(Platform)\$(Configuration)\</ObjectFileName>
-      <ProgramDataBaseFileName>$(Platform)\$(Configuration)\</ProgramDataBaseFileName>
       <WarningLevel>Level3</WarningLevel>
       <SuppressStartupBanner>true</SuppressStartupBanner>
     </ClCompile>
@@ -348,20 +289,8 @@
       <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <Culture>0x0409</Culture>
     </ResourceCompile>
-    <Link>
-      <OutputFile>$(Platform)\$(Configuration)\portaudio_x86.dll</OutputFile>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <ModuleDefinitionFile>.\portaudio.def</ModuleDefinitionFile>
-      <ProgramDatabaseFile>$(Platform)\$(Configuration)\portaudio_x86.pdb</ProgramDatabaseFile>
-      <RandomizedBaseAddress>false</RandomizedBaseAddress>
-      <DataExecutionPrevention>
-      </DataExecutionPrevention>
-      <ImportLibrary>$(Platform)\$(Configuration)\portaudio_x86.lib</ImportLibrary>
-      <TargetMachine>MachineX86</TargetMachine>
-    </Link>
     <Bscmake>
       <SuppressStartupBanner>true</SuppressStartupBanner>
-      <OutputFile>$(Platform)\$(Configuration)\portaudio.bsc</OutputFile>
     </Bscmake>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">
@@ -370,22 +299,15 @@
       <MkTypLibCompatible>true</MkTypLibCompatible>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <TargetEnvironment>X64</TargetEnvironment>
-      <TypeLibraryName>.\Release_x86/portaudio.tlb</TypeLibraryName>
-      <HeaderFileName>
-      </HeaderFileName>
     </Midl>
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
-      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
-      <AdditionalIncludeDirectories>..\..\src\common;..\..\include;.\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\src\common;..\..\include;.\;..\..\src\os\win;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_USRDLL;PA_ENABLE_DEBUG_OUTPUT;_CRT_SECURE_NO_DEPRECATE;PA_NO_ASIO;PA_NO_WMME;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <StringPooling>true</StringPooling>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <FunctionLevelLinking>true</FunctionLevelLinking>
-      <PrecompiledHeaderOutputFile>$(Platform)\$(Configuration)\portaudio.pch</PrecompiledHeaderOutputFile>
-      <AssemblerListingLocation>$(Platform)\$(Configuration)\</AssemblerListingLocation>
-      <ObjectFileName>$(Platform)\$(Configuration)\</ObjectFileName>
-      <ProgramDataBaseFileName>$(Platform)\$(Configuration)\</ProgramDataBaseFileName>
       <WarningLevel>Level3</WarningLevel>
       <SuppressStartupBanner>true</SuppressStartupBanner>
     </ClCompile>
@@ -393,20 +315,8 @@
       <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <Culture>0x0409</Culture>
     </ResourceCompile>
-    <Link>
-      <OutputFile>$(Platform)\$(Configuration)\portaudio_x64.dll</OutputFile>
-      <SuppressStartupBanner>true</SuppressStartupBanner>
-      <ModuleDefinitionFile>.\portaudio.def</ModuleDefinitionFile>
-      <ProgramDatabaseFile>$(Platform)\$(Configuration)/portaudio_x64.pdb</ProgramDatabaseFile>
-      <RandomizedBaseAddress>false</RandomizedBaseAddress>
-      <DataExecutionPrevention>
-      </DataExecutionPrevention>
-      <ImportLibrary>$(Platform)\$(Configuration)/portaudio_x64.lib</ImportLibrary>
-      <TargetMachine>MachineX64</TargetMachine>
-    </Link>
     <Bscmake>
       <SuppressStartupBanner>true</SuppressStartupBanner>
-      <OutputFile>$(Platform)\$(Configuration)\portaudio_x64.bsc</OutputFile>
     </Bscmake>
   </ItemDefinitionGroup>
   <ItemGroup>
@@ -594,6 +504,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@@ -605,6 +516,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -618,6 +530,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@@ -629,6 +542,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -642,6 +556,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@@ -653,6 +568,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -666,6 +582,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@@ -677,6 +594,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -690,6 +608,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@@ -701,6 +620,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -714,6 +634,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@@ -725,6 +646,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -738,6 +660,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@@ -749,6 +672,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -762,6 +686,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug DirectSound|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@@ -773,6 +698,7 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">true</ExcludedFromBuild>
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">..\..\src\hostapi\asio\ASIOSDK\host;..\..\src\hostapi\asio\ASIOSDK\host\pc;..\..\src\hostapi\asio\ASIOSDK\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release DirectSound|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
committer: Anthony Minessale
comments: 
add sanity check on jitterbuffer debug

diff --git a/src/switch_rtp.c b/src/switch_rtp.c
index e8d7558..4df867a 100644
--- a/src/switch_rtp.c
+++ b/src/switch_rtp.c
@@ -1875,6 +1875,10 @@ static void jb_logger(const char *file, const char *func, int line, int level, c
 SWITCH_DECLARE(switch_status_t) switch_rtp_debug_jitter_buffer(switch_rtp_t *rtp_session, const char *name)
 {
 
+	if (!switch_rtp_ready(rtp_session)) {
+		return SWITCH_STATUS_FALSE;
+	}
+	
 	stfu_n_debug(rtp_session->jb, name);
 	stfu_global_set_logger(jb_logger);
 
committer: Anthony Minessale
comments: 
skip blocking writes on fs_cli to avoid backing up event socket

diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c
index 19e8d7f..a70d63f 100644
--- a/libs/esl/fs_cli.c
+++ b/libs/esl/fs_cli.c
@@ -589,22 +589,36 @@ static void *msg_thread_run(esl_thread_t *me, void *obj)
 
 	while(thread_running && handle->connected) {
 		esl_status_t status = esl_recv_event_timed(handle, 10, 1, NULL);
-
-		if (WARN_STOP) {
-			printf("Type control-D or /exit or /quit or /bye to exit.\n\n");
-			WARN_STOP = 0;
-		}
+		int aok = 1;		
 
 		if (status == ESL_FAIL) {
-			esl_log(ESL_LOG_WARNING, "Disconnected.\n");
+			if (aok) esl_log(ESL_LOG_WARNING, "Disconnected.\n");
 			running = -1; thread_running = 0;
 		} else if (status == ESL_SUCCESS) {
+#ifndef WIN32
+			fd_set can_write;
+			int fd;
+			struct timeval to;
+
+			fd = fileno(stdout);
+			memset(&to, 0, sizeof(to));
+			FD_ZERO(&can_write);
+			FD_SET(fd, &can_write);
+			to.tv_sec = 0;
+			to.tv_usec = 100000;
+			if (select(fd + 1, NULL, &can_write, NULL, &to) > 0) {
+				aok = FD_ISSET(fd, &can_write);
+			} else {
+				aok = 0;
+			}
+#endif
+			
 			if (handle->last_event) {
 				const char *type = esl_event_get_header(handle->last_event, "content-type");
 				int known = 0;
 
 				if (!esl_strlen_zero(type)) {
-					if (!strcasecmp(type, "log/data")) {
+					if (aok && !strcasecmp(type, "log/data")) {
 						const char *userdata = esl_event_get_header(handle->last_event, "user-data");
 						
 						if (esl_strlen_zero(userdata) || esl_strlen_zero(filter_uuid) || !strcasecmp(filter_uuid, userdata)) {
@@ -631,7 +645,7 @@ static void *msg_thread_run(esl_thread_t *me, void *obj)
 					} else if (!strcasecmp(type, "text/disconnect-notice")) {
 						running = -1; thread_running = 0;
 						known++;
-					} else if (!strcasecmp(type, "text/event-plain")) {
+					} else if (aok && !strcasecmp(type, "text/event-plain")) {
 						char *foo;
 						esl_event_serialize(handle->last_ievent, &foo, ESL_FALSE);
 						printf("RECV EVENT\n%s\n", foo);
@@ -641,7 +655,7 @@ static void *msg_thread_run(esl_thread_t *me, void *obj)
 					}
 				}
 				
-				if (!known) {
+				if (aok && !known) {
 					char *foo;
 					printf("INCOMING DATA [%s]\n%s\n", type, handle->last_event->body ? handle->last_event->body : "");
 					esl_event_serialize(handle->last_event, &foo, ESL_FALSE);
@@ -651,6 +665,11 @@ static void *msg_thread_run(esl_thread_t *me, void *obj)
 			}
 		}
 
+		if (WARN_STOP) {
+			if (aok) printf("Type control-D or /exit or /quit or /bye to exit.\n\n");
+			WARN_STOP = 0;
+		}
+
 		usleep(1000);
 	}
 
committer: Anthony Minessale
comments: 
fix regression from f60fdf653dd2d7f8d3eaa6a9086e1f68bd993c59

diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c
index 0b16492..f7bf86b 100755
--- a/src/mod/applications/mod_dptools/mod_dptools.c
+++ b/src/mod/applications/mod_dptools/mod_dptools.c
@@ -2774,7 +2774,7 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session
 	switch_originate_flag_t myflags = SOF_NONE;
 	char *cid_name_override = NULL;
 	char *cid_num_override = NULL;
-	char *domain = NULL;
+	char *domain = NULL, *dup_domain = NULL;
 	switch_channel_t *new_channel = NULL;
 	unsigned int timelimit = 60;
 	const char *skip, *var;
@@ -2788,6 +2788,7 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session
 		*domain++ = '\0';
 	} else {
 		domain = switch_core_get_variable_pdup("domain", switch_core_session_get_pool(session));
+		dup_domain = domain;
 	}
 
 	if (!domain) {
@@ -2859,6 +2860,7 @@ static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session
 
 	switch_safe_free(template);
 	switch_safe_free(group);
+	switch_safe_free(dup_domain);
 
 	if (cause == SWITCH_CAUSE_NONE) {
 		cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
diff --git a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c
index 43534da..3bc5cb4 100644
--- a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c
+++ b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c
@@ -309,11 +309,13 @@ static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session,
 												switch_call_cause_t *cancel_cause)
 {
 	const char *profile;
+	char *dup_profile = NULL;
 
 	if (session) {
 		profile = switch_channel_get_variable(switch_core_session_get_channel(session), "sip_profile");
 	} else {
-		profile = switch_core_get_variable_pdup("sip_profile", switch_core_session_get_pool(session));
+		dup_profile = switch_core_get_variable_dup("sip_profile");
+		profile = dup_profile;
 	}
 	if (zstr(profile)) {
 		profile = "default";
@@ -323,6 +325,8 @@ static switch_call_cause_t sip_outgoing_channel(switch_core_session_t *session,
 
 	UNPROTECT_INTERFACE(sip_endpoint_interface);
 
+	switch_safe_free(dup_profile);
+
 	return switch_core_session_outgoing_channel(session, var_event, "sofia", outbound_profile, new_session, pool, SOF_NONE, cancel_cause);
 }
 
committer: Anthony Minessale
comments: 
fix regression from f60fdf653dd2d7f8d3eaa6a9086e1f68bd993c59

diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c
index 4be2a64..0b16492 100755
--- a/src/mod/applications/mod_dptools/mod_dptools.c
+++ b/src/mod/applications/mod_dptools/mod_dptools.c
@@ -2887,7 +2887,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
 												 switch_call_cause_t *cancel_cause)
 {
 	switch_xml_t x_domain = NULL, xml = NULL, x_user = NULL, x_group = NULL, x_param, x_params;
-	char *user = NULL, *domain = NULL;
+	char *user = NULL, *domain = NULL, *dup_domain = NULL;
 	const char *dest = NULL;
 	static switch_call_cause_t cause = SWITCH_CAUSE_NONE;
 	unsigned int timelimit = 60;
@@ -2908,7 +2908,8 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
 	if ((domain = strchr(user, '@'))) {
 		*domain++ = '\0';
 	} else {
-		domain = switch_core_get_variable_pdup("domain", switch_core_session_get_pool(session));
+		domain = switch_core_get_variable_dup("domain");
+		dup_domain = domain;
 	}
 
 	if (!domain) {
@@ -3115,6 +3116,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
 	}
 
 	switch_safe_free(user);
+	switch_safe_free(dup_domain);
 
 	return cause;
 }
committer: Jeff Lenk
comments: 
fix iLBC under windows

diff --git a/libs/ilbc/src/iLBC_decode.c b/libs/ilbc/src/iLBC_decode.c
index fc46fe4..9fc7a24 100644
--- a/libs/ilbc/src/iLBC_decode.c
+++ b/libs/ilbc/src/iLBC_decode.c
@@ -47,7 +47,9 @@
     	{
             fld dbl
             frndint
+            fstp dbl
         }
+        return (long int) dbl;
     }
 #elif defined (_WIN64)
 #include <intrin.h>
committer: Anthony Minessale
comments: 
block control-z from fs cli and print a warning how to exit properly

diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c
index 1e3bf04..19e8d7f 100644
--- a/libs/esl/fs_cli.c
+++ b/libs/esl/fs_cli.c
@@ -8,6 +8,7 @@
 #include <signal.h>
 
 #define CMD_BUFLEN 1024
+static int WARN_STOP = 0;
 
 #ifdef WIN32
 #define strdup(src) _strdup(src)
@@ -535,6 +536,13 @@ static BOOL console_readConsole(HANDLE conIn, char* buf, int len, int* pRed, int
 static void handle_SIGINT(int sig)
 {
 	if (sig);
+
+	WARN_STOP = 1;
+
+	signal(SIGINT, handle_SIGINT);
+#ifdef SIGTSTP
+	signal(SIGTSTP, handle_SIGINT);
+#endif
 	return;
 }
 
@@ -581,6 +589,12 @@ static void *msg_thread_run(esl_thread_t *me, void *obj)
 
 	while(thread_running && handle->connected) {
 		esl_status_t status = esl_recv_event_timed(handle, 10, 1, NULL);
+
+		if (WARN_STOP) {
+			printf("Type control-D or /exit or /quit or /bye to exit.\n\n");
+			WARN_STOP = 0;
+		}
+
 		if (status == ESL_FAIL) {
 			esl_log(ESL_LOG_WARNING, "Disconnected.\n");
 			running = -1; thread_running = 0;
@@ -1023,6 +1037,9 @@ int main(int argc, char *argv[])
 	}
 	
 	signal(SIGINT, handle_SIGINT);
+#ifdef SIGTSTP
+	signal(SIGTSTP, handle_SIGINT);
+#endif
 #ifdef SIGQUIT
 	signal(SIGQUIT, handle_SIGQUIT);
 #endif
committer: Anthony Minessale
comments: 
dont run execute_on_fsk when there was no data collected

diff --git a/src/mod/applications/mod_fsk/mod_fsk.c b/src/mod/applications/mod_fsk/mod_fsk.c
index 9802353..0291707 100644
--- a/src/mod/applications/mod_fsk/mod_fsk.c
+++ b/src/mod/applications/mod_fsk/mod_fsk.c
@@ -220,6 +220,7 @@ static switch_bool_t fsk_detect_callback(switch_media_bug_t *bug, void *user_dat
 				char *sp;
 				switch_event_t *event;
 				const char *app_var;
+				int total = 0;
 
 				switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA);
 				
@@ -255,6 +256,7 @@ static switch_bool_t fsk_detect_callback(switch_media_bug_t *bug, void *user_dat
 					}
 
 					if (varname && val) {
+						total++;
 						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s setting FSK var [%s][%s]\n", 
 										  switch_channel_get_name(channel), varname, val);
 						switch_channel_set_variable(channel, varname, val);
@@ -270,7 +272,7 @@ static switch_bool_t fsk_detect_callback(switch_media_bug_t *bug, void *user_dat
 					}
 				}
 				
-				if ((app_var = switch_channel_get_variable(channel, "execute_on_fsk"))) {
+				if (total && (app_var = switch_channel_get_variable(channel, "execute_on_fsk"))) {
 					char *app_arg;
 
 					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s processing execute_on_fsk [%s]\n", 
committer: Anthony Minessale
comments: 
fix regression from d72cde9b76a856cf002366300bea02c26db44ffb

diff --git a/src/switch_core_session.c b/src/switch_core_session.c
index 4836aae..d2e28de 100644
--- a/src/switch_core_session.c
+++ b/src/switch_core_session.c
@@ -1865,6 +1865,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_app_flags(const char *ap
 SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_async(switch_core_session_t *session, const char *app, const char *arg)
 {
 	switch_event_t *execute_event;
+	char *ap, *arp;
+	
+	if (!arg && strstr(app, "::")) {
+		ap = switch_core_session_strdup(session, app);
+		app = ap;
+
+		if ((arp = strstr(ap, "::"))) {
+			*arp = '\0';
+			arg = arp + 2;
+		}
+	}
 	
 	if (switch_event_create(&execute_event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) {
 		switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute");
@@ -1894,6 +1905,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_get_flag
 	switch_application_interface_t *application_interface;
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
 
+	if (!arg && strstr(app, "::")) {
+		return switch_core_session_execute_application_async(session, app, arg);
+	}
+
 	if (switch_channel_down(session->channel)) {
 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Channel is hungup, aborting execution of application: %s\n", app);
 		return SWITCH_STATUS_FALSE;
committer: Anthony Minessale
comments: 
FS-3006

diff --git a/src/mod/endpoints/mod_portaudio/mod_portaudio.c b/src/mod/endpoints/mod_portaudio/mod_portaudio.c
index 8978b85..baa33d4 100644
--- a/src/mod/endpoints/mod_portaudio/mod_portaudio.c
+++ b/src/mod/endpoints/mod_portaudio/mod_portaudio.c
@@ -40,6 +40,8 @@
 
 #define MY_EVENT_RINGING "portaudio::ringing"
 #define MY_EVENT_MAKE_CALL "portaudio::makecall"
+#define MY_EVENT_CALL_HELD "portaudio::callheld"
+#define MY_EVENT_CALL_RESUMED "portaudio::callresumed"
 #define MY_EVENT_ERROR_AUDIO_DEV "portaudio::audio_dev_error"
 #define SWITCH_PA_CALL_ID_VARIABLE "pa_call_id"
 
@@ -90,12 +92,20 @@ struct private_object {
 	switch_file_handle_t *hfh;
 	switch_frame_t hold_frame;
 	unsigned char holdbuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
-	switch_codec_t write_codec;
 	struct private_object *next;
 };
 
 typedef struct private_object private_t;
 
+struct audio_stream {
+	int indev;
+	int outdev;
+	PABLIO_Stream *stream;
+	switch_timer_t write_timer;
+	struct audio_stream *next;
+};
+typedef struct audio_stream audio_stream_t;
+
 static struct {
 	int debug;
 	int port;
@@ -113,12 +123,13 @@ static struct {
 	switch_hash_t *call_hash;
 	switch_mutex_t *device_lock;
 	switch_mutex_t *pvt_lock;
+	switch_mutex_t *streams_lock;
 	switch_mutex_t *flag_mutex;
 	switch_mutex_t *pa_mutex;
 	int sample_rate;
 	int codec_ms;
-	PABLIO_Stream *audio_stream;
-	PABLIO_Stream *ring_stream;
+	audio_stream_t *main_stream;
+	audio_stream_t *ring_stream;
 	switch_codec_t read_codec;
 	switch_codec_t write_codec;
 	switch_frame_t read_frame;
@@ -126,13 +137,20 @@ static struct {
 	unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
 	unsigned char cngbuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
 	private_t *call_list;
+	audio_stream_t *stream_list;
 	int ring_interval;
 	GFLAGS flags;
 	switch_timer_t read_timer;
-	switch_timer_t write_timer;
+	switch_timer_t readfile_timer;
 	switch_timer_t hold_timer;
 	int dual_streams;
 	time_t deactivate_timer;
+	int live_stream_switch;
+	int no_auto_resume_call;
+	int no_ring_during_call;
+	int codecs_inited;
+	int stream_in_use; //only really used by playdev
+	int destroying_streams;
 } globals;
 
 
@@ -164,9 +182,22 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
 static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
 static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
 static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
-static switch_status_t engage_device(int restart);
-static switch_status_t engage_ring_device(void);
-static void deactivate_ring_device(void);
+
+static switch_status_t create_codecs(int restart);
+static void create_hold_event(private_t *tech_pvt, int unhold);
+static audio_stream_t * find_audio_stream(int indev, int outdev, int already_locked);
+static audio_stream_t * get_audio_stream(int indev, int outdev);
+static audio_stream_t * create_audio_stream(int indev, int outdev);
+PaError open_audio_stream(PABLIO_Stream **stream, const PaStreamParameters * inputParameters, const PaStreamParameters * outputParameters);
+static switch_status_t switch_audio_stream();
+static void add_stream(audio_stream_t *stream, int already_locked);
+static void remove_stream(audio_stream_t *stream, int already_locked);
+static switch_status_t destroy_audio_stream(int indev, int outdev);
+static switch_status_t destroy_actual_stream(audio_stream_t *stream);
+static void destroy_audio_streams();
+static switch_status_t validate_main_audio_stream();
+static switch_status_t validate_ring_audio_stream();
+
 static int dump_info(int verbose);
 static switch_status_t load_config(void);
 static int get_dev_by_name(char *name, int in);
@@ -212,9 +243,8 @@ static switch_status_t channel_on_routing(switch_core_session_t *session)
 	if (hold_file) {
 		tech_pvt->hold_file = switch_core_session_strdup(session, hold_file);
 	}
-	
-	if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
-		if (engage_device(0) != SWITCH_STATUS_SUCCESS) {
+		if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
+		if (validate_main_audio_stream() != SWITCH_STATUS_SUCCESS) {
 			switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
 			return SWITCH_STATUS_FALSE;
 		}
@@ -238,7 +268,7 @@ static switch_status_t channel_on_routing(switch_core_session_t *session)
 										  globals.read_codec.implementation->actual_samples_per_second,
 										  SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) {
 
-					if (engage_ring_device() != SWITCH_STATUS_SUCCESS) {
+					if (validate_ring_audio_stream() != SWITCH_STATUS_SUCCESS) {
 						switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
 						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Ring Error!\n");
 						switch_core_file_close(&fh);
@@ -263,7 +293,7 @@ static switch_status_t channel_on_routing(switch_core_session_t *session)
 		}
 
 		while (switch_channel_get_state(channel) == CS_ROUTING && !switch_test_flag(tech_pvt, TFLAG_ANSWER)) {
-			switch_size_t olen = globals.read_timer.samples;
+			switch_size_t olen = globals.readfile_timer.samples;
 
 			if (switch_micro_time_now() - last >= waitsec) {
 				char buf[512];
@@ -273,7 +303,8 @@ static switch_status_t channel_on_routing(switch_core_session_t *session)
 
 				if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_RINGING) == SWITCH_STATUS_SUCCESS) {
 					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_info", buf);
-					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call_id", tech_pvt->call_id);
+					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call_id", tech_pvt->call_id); /* left behind for backwards compatability */
+					switch_channel_set_variable(channel, SWITCH_PA_CALL_ID_VARIABLE, tech_pvt->call_id);
 					switch_channel_event_set_data(channel, event);
 					switch_event_fire(&event);
 				}
@@ -282,7 +313,7 @@ static switch_status_t channel_on_routing(switch_core_session_t *session)
 			}
 
 			if (ring_file) {
-				if (switch_core_timer_next(&globals.read_timer) != SWITCH_STATUS_SUCCESS) {
+				if (switch_core_timer_next(&globals.readfile_timer) != SWITCH_STATUS_SUCCESS) {
 					switch_core_file_close(&fh);
 					break;
 				}
@@ -292,8 +323,9 @@ static switch_status_t channel_on_routing(switch_core_session_t *session)
 					switch_core_file_seek(&fh, &pos, 0, SEEK_SET);
 				}
 
-				if (globals.ring_stream) {
-					WriteAudioStream(globals.ring_stream, abuf, (long) olen, &globals.write_timer);
+				if (globals.ring_stream && (! switch_test_flag(globals.call_list, TFLAG_MASTER) || 
+							( !globals.no_ring_during_call && globals.main_stream != globals.ring_stream)) ) { //if there is a ring stream and not an active call or if there is an active call and we are allowed to ring during it AND the ring stream is not the main stream						
+						WriteAudioStream(globals.ring_stream->stream, abuf, (long) olen, &globals.ring_stream->write_timer);
 				}
 			} else {
 				switch_yield(10000);
@@ -303,7 +335,6 @@ static switch_status_t channel_on_routing(switch_core_session_t *session)
 	}
 
 	if (ring_file) {
-		deactivate_ring_device();
 		switch_core_file_close(&fh);
 	}
 
@@ -329,27 +360,130 @@ static switch_status_t channel_on_execute(switch_core_session_t *session)
 	return SWITCH_STATUS_SUCCESS;
 }
 
-static void deactivate_audio_device(void)
+static audio_stream_t* find_audio_stream(int indev, int outdev, int already_locked)
 {
-	if (!globals.audio_stream) {
-		return;
+	audio_stream_t *cur_stream;
+	
+	if (! globals.stream_list) {
+		return NULL;
 	}
 
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Stop audio device.\n");
+	if (! already_locked) {
+		switch_mutex_lock(globals.streams_lock);
+	}
+	cur_stream = globals.stream_list;
 
-	switch_mutex_lock(globals.device_lock);
-	/* LOCKED ************************************************************************************************** */
+	while (cur_stream != NULL) {
+		if (cur_stream->outdev == outdev) {
+			if (indev == -1 || cur_stream->indev == indev) {
+				if (! already_locked) {
+					switch_mutex_unlock(globals.streams_lock);
+				}
+				return cur_stream;
+			}
+		}
+		cur_stream = cur_stream->next;
+	}
+	if (! already_locked) {
+		switch_mutex_unlock(globals.streams_lock);
+	}
+	return NULL;
+}
+static void destroy_audio_streams()
+{
+	int close_wait = 4;
+	globals.destroying_streams = 1;
+
+	while (globals.stream_in_use && close_wait--) {
+		switch_yield(250000);
+	}
+	while (globals.stream_list != NULL) {
+		destroy_audio_stream(globals.stream_list->indev, globals.stream_list->outdev);
+	}
+	globals.destroying_streams = 0;
+}
+static switch_status_t validate_main_audio_stream()
+{
+	if (globals.read_timer.timer_interface) {
+		switch_core_timer_sync(&globals.read_timer);
+	}
 
-	if (globals.audio_stream) {
-		if (globals.ring_stream == globals.audio_stream) {
-			globals.ring_stream = NULL;
+	if (globals.main_stream) {
+		if (globals.main_stream->write_timer.timer_interface) {
+			switch_core_timer_sync(&(globals.main_stream->write_timer));
 		}
-		CloseAudioStream(globals.audio_stream);
-		globals.audio_stream = NULL;
+
+		return SWITCH_STATUS_SUCCESS;
 	}
 
-	/* UNLOCKED ************************************************************************************************* */
-	switch_mutex_unlock(globals.device_lock);
+	globals.main_stream = get_audio_stream(globals.indev, globals.outdev);
+	
+	if (globals.main_stream) {
+		return SWITCH_STATUS_SUCCESS;
+	}
+
+	return SWITCH_STATUS_FALSE;
+}
+
+static switch_status_t validate_ring_audio_stream()
+{
+	if (globals.ringdev == -1) {
+		return SWITCH_STATUS_SUCCESS;
+	}
+	if (globals.ring_stream) {
+		if (globals.ring_stream->write_timer.timer_interface) {
+			switch_core_timer_sync(&(globals.ring_stream->write_timer));
+		}
+		return SWITCH_STATUS_SUCCESS;
+	}
+	globals.ring_stream = get_audio_stream(-1, globals.ringdev);
+	if (globals.ring_stream) {
+		return SWITCH_STATUS_SUCCESS;
+	}
+
+	return SWITCH_STATUS_FALSE;
+}
+
+static switch_status_t destroy_actual_stream(audio_stream_t *stream)
+{
+	if (stream == NULL) {
+		return SWITCH_STATUS_FALSE;
+	}
+
+	if (globals.main_stream == stream) {
+		globals.main_stream = NULL;
+	}
+
+	if (globals.ring_stream == stream) {
+		globals.ring_stream = NULL;
+	}
+
+	CloseAudioStream(stream->stream);
+	stream->stream = NULL;
+	
+	if (stream->write_timer.timer_interface) {
+		switch_core_timer_destroy(&stream->write_timer);
+	}
+
+	switch_safe_free(stream);
+	return SWITCH_STATUS_SUCCESS;
+}
+static switch_status_t destroy_audio_stream(int indev, int outdev)
+{
+	audio_stream_t *stream;
+	
+	switch_mutex_lock(globals.streams_lock);
+	stream = find_audio_stream(indev, outdev,1);
+	if (stream == NULL) {
+		switch_mutex_unlock(globals.streams_lock);
+		return SWITCH_STATUS_FALSE;		
+	}
+
+	remove_stream(stream, 1);
+	switch_mutex_unlock(globals.streams_lock);
+
+	destroy_actual_stream(stream);
+	return SWITCH_STATUS_SUCCESS;
 }
 
 
@@ -368,34 +502,69 @@ static void destroy_codecs(void)
 		switch_core_timer_destroy(&globals.read_timer);
 	}
 
-	if (globals.write_timer.timer_interface) {
-		switch_core_timer_destroy(&globals.write_timer);
+	if (globals.readfile_timer.timer_interface) {
+		switch_core_timer_destroy(&globals.readfile_timer);
 	}
 
 	if (globals.hold_timer.timer_interface) {
 		switch_core_timer_destroy(&globals.hold_timer);
 	}
 
-
-
+	globals.codecs_inited = 0;
 }
 
-static void deactivate_ring_device(void)
+static void create_hold_event(private_t *tech_pvt, int unhold)
 {
-	if (!globals.ring_stream) {
-		return;
+	switch_event_t *event;
+	char * event_id;
+
+	if (unhold) {
+		event_id = MY_EVENT_CALL_RESUMED;
+	} else {
+		event_id = MY_EVENT_CALL_HELD;
 	}
 
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Stop ring device.\n");
-	switch_mutex_lock(globals.device_lock);
-	if (globals.ring_stream && globals.ring_stream != globals.audio_stream) {
-		CloseAudioStream(globals.ring_stream);
+	if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, event_id) == SWITCH_STATUS_SUCCESS) {
+		switch_channel_event_set_data(switch_core_session_get_channel(tech_pvt->session), event);
+		switch_event_fire(&event);
 	}
-	globals.ring_stream = NULL;
-	switch_mutex_unlock(globals.device_lock);
 }
 
+static void add_stream(audio_stream_t * stream, int already_locked)
+{
+	audio_stream_t *last;
 
+	if (! already_locked) {
+		switch_mutex_lock(globals.streams_lock);
+	}
+	for (last = globals.stream_list; last && last->next; last = last->next);
+	if (last == NULL) {
+		globals.stream_list = stream;
+	} else {
+		last->next = stream;
+	}
+	if (! already_locked) {
+		switch_mutex_unlock(globals.streams_lock);
+	}
+}
+static void remove_stream(audio_stream_t * stream, int already_locked)
+{
+	audio_stream_t *previous;
+	if (! already_locked) {
+		switch_mutex_lock(globals.streams_lock);
+	}
+	if (globals.stream_list == stream) {
+		globals.stream_list = stream->next;
+	} else {
+		for (previous = globals.stream_list; previous && previous->next && previous->next != stream; previous = previous->next) {
+			;
+		}
+		previous->next = stream->next;
+	}
+	if (! already_locked) {
+		switch_mutex_unlock(globals.streams_lock);
+	}
+}
 
 static void add_pvt(private_t *tech_pvt, int master)
 {
@@ -418,8 +587,9 @@ static void add_pvt(private_t *tech_pvt, int master)
 		if (tp == tech_pvt) {
 			in_list = 1;
 		}
-		if (master) {
+		if (master && switch_test_flag(tp, TFLAG_MASTER) ) {
 			switch_clear_flag_locked(tp, TFLAG_MASTER);
+			create_hold_event(tp,0);
 		}
 	}
 
@@ -446,11 +616,16 @@ static void add_pvt(private_t *tech_pvt, int master)
 static void remove_pvt(private_t *tech_pvt)
 {
 	private_t *tp, *last = NULL;
+	int was_master = 0;
 
 	switch_mutex_lock(globals.pvt_lock);
 	for (tp = globals.call_list; tp; tp = tp->next) {
-		switch_clear_flag_locked(tp, TFLAG_MASTER);
+		
 		if (tp == tech_pvt) {
+			if (switch_test_flag(tp, TFLAG_MASTER)) {
+				switch_clear_flag_locked(tp, TFLAG_MASTER);
+				was_master = 1;
+			}
 			if (last) {
 				last->next = tp->next;
 			} else {
@@ -461,10 +636,13 @@ static void remove_pvt(private_t *tech_pvt)
 	}
 
 	if (globals.call_list) {
-		switch_set_flag_locked(globals.call_list, TFLAG_MASTER);
+		if (was_master && ! globals.no_auto_resume_call) {
+			switch_set_flag_locked(globals.call_list, TFLAG_MASTER);
+			create_hold_event(globals.call_list, 1);
+		}
 	} else {
 		globals.deactivate_timer = switch_epoch_time_now(NULL) + 2;
-		deactivate_audio_device();
+		destroy_audio_streams();
 	}
 
 	switch_mutex_unlock(globals.pvt_lock);
@@ -555,8 +733,8 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
 	int samples = 0;
 	switch_status_t status = SWITCH_STATUS_FALSE;
 	switch_assert(tech_pvt != NULL);
-
-	if (!globals.audio_stream) {
+	
+	if (!globals.main_stream) {
 		goto normal_return;
 	}
 
@@ -618,7 +796,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
 	}
 
 	switch_mutex_lock(globals.device_lock);
-	samples = ReadAudioStream(globals.audio_stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_packet, &globals.read_timer);
+	samples = ReadAudioStream(globals.main_stream->stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_packet, &globals.read_timer);
 	switch_mutex_unlock(globals.device_lock);
 
 	if (samples) {
@@ -635,7 +813,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
 		goto cng_nowait;
 	}
 
-  normal_return:
+normal_return:
 	return status;
 
   cng_nowait:
@@ -655,7 +833,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
 	private_t *tech_pvt = switch_core_session_get_private(session);
 	switch_assert(tech_pvt != NULL);
 
-	if (!globals.audio_stream) {
+	if (!globals.main_stream) {
 		return SWITCH_STATUS_FALSE;
 	}
 
@@ -667,9 +845,9 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
 		return SWITCH_STATUS_SUCCESS;
 	}
 
-	if (globals.audio_stream) {
+	if (globals.main_stream) {
 		if (switch_test_flag((&globals), GFLAG_EAR)) {
-			WriteAudioStream(globals.audio_stream, (short *) frame->data, (int) (frame->datalen / sizeof(SAMPLE)), &globals.write_timer);
+			WriteAudioStream(globals.main_stream->stream, (short *) frame->data, (int) (frame->datalen / sizeof(SAMPLE)), &(globals.main_stream->write_timer));
 		}
 		status = SWITCH_STATUS_SUCCESS;
 	}
@@ -747,7 +925,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
 			channel = switch_core_session_get_channel(*new_session);
 			switch_core_session_set_private(*new_session, tech_pvt);
 			tech_pvt->session = *new_session;
-			globals.flags = GFLAG_EAR | GFLAG_MOUTH;
 		} else {
 			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(*new_session), SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
 			switch_core_session_destroy(new_session);
@@ -796,16 +973,17 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load)
 	switch_core_hash_init(&globals.call_hash, module_pool);
 	switch_mutex_init(&globals.device_lock, SWITCH_MUTEX_NESTED, module_pool);
 	switch_mutex_init(&globals.pvt_lock, SWITCH_MUTEX_NESTED, module_pool);
+	switch_mutex_init(&globals.streams_lock, SWITCH_MUTEX_NESTED, module_pool);
 	switch_mutex_init(&globals.flag_mutex, SWITCH_MUTEX_NESTED, module_pool);
 	switch_mutex_init(&globals.pa_mutex, SWITCH_MUTEX_NESTED, module_pool);
-
+	globals.codecs_inited=0;
 	globals.read_frame.data = globals.databuf;
 	globals.read_frame.buflen = sizeof(globals.databuf);
 	globals.cng_frame.data = globals.cngbuf;
 	globals.cng_frame.buflen = sizeof(globals.cngbuf);
 	globals.cng_frame.datalen = switch_samples_per_packet(globals.sample_rate, globals.codec_ms) * 2;
 	switch_set_flag((&globals.cng_frame), SFF_CNG);
-
+	globals.flags = GFLAG_EAR | GFLAG_MOUTH;
 	/* dual streams makes portaudio on solaris choke */
 #if defined(sun) || defined(__sun)
 	globals.dual_streams = 0;
@@ -834,6 +1012,14 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load)
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n");
 		return SWITCH_STATUS_GENERR;
 	}
+	if (switch_event_reserve_subclass(MY_EVENT_CALL_HELD) != SWITCH_STATUS_SUCCESS) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n");
+		return SWITCH_STATUS_GENERR;
+	}
+	if (switch_event_reserve_subclass(MY_EVENT_CALL_RESUMED) != SWITCH_STATUS_SUCCESS) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n");
+		return SWITCH_STATUS_GENERR;
+	}
 
 	if (switch_event_reserve_subclass(MY_EVENT_ERROR_AUDIO_DEV) != SWITCH_STATUS_SUCCESS) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n");
@@ -861,9 +1047,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load)
 	switch_console_set_complete("add pa devlist");
 	switch_console_set_complete("add pa indev");
 	switch_console_set_complete("add pa outdev");
+	switch_console_set_complete("add pa preparestream");
+	switch_console_set_complete("add pa switchstream");
+	switch_console_set_complete("add pa closestreams");
 	switch_console_set_complete("add pa ringdev");
 	switch_console_set_complete("add pa ringfile");
 	switch_console_set_complete("add pa play");
+	switch_console_set_complete("add pa playdev");
 	switch_console_set_complete("add pa looptest");
 
 	/* indicate that the module should continue to be loaded */
@@ -881,9 +1071,12 @@ static switch_status_t load_config(void)
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
 		return SWITCH_STATUS_TERM;
 	}
-
+	destroy_audio_streams();
+	destroy_codecs();
 	globals.dual_streams = 0;
-
+	globals.live_stream_switch = 0;
+	globals.no_auto_resume_call = 0;
+	globals.no_ring_during_call = 0;
 	globals.indev = globals.outdev = globals.ringdev = -1;
 	globals.sample_rate = 8000;
 
@@ -896,6 +1089,24 @@ static switch_status_t load_config(void)
 				globals.debug = atoi(val);
 			} else if (!strcmp(var, "ring-interval")) {
 				globals.ring_interval = atoi(val);
+			} else if (!strcmp(var, "no-auto-resume-call")) {
+				if (switch_true(val)) {
+					globals.no_auto_resume_call = 1;
+				} else {
+					globals.no_auto_resume_call = 0;
+				}
+			} else if (!strcmp(var, "no-ring-during-call")) {
+				if (switch_true(val)) {
+					globals.no_ring_during_call = 1;
+				} else {
+					globals.no_ring_during_call = 0;
+				}
+			} else if (!strcmp(var, "live-stream-switch")) {
+				if (switch_true(val)) {
+					globals.live_stream_switch = 1;
+				} else {
+					globals.live_stream_switch = 0;
+				}
 			} else if (!strcmp(var, "ring-file")) {
 				set_global_ring_file(val);
 			} else if (!strcmp(var, "hold-file")) {
@@ -1007,8 +1218,7 @@ static switch_status_t load_config(void)
 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_shutdown)
 {
 
-	deactivate_audio_device();
-	deactivate_ring_device();
+	destroy_audio_streams();
 	destroy_codecs();
 
 	Pa_Terminate();
@@ -1017,6 +1227,9 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_shutdown)
 	switch_event_free_subclass(MY_EVENT_RINGING);
 	switch_event_free_subclass(MY_EVENT_MAKE_CALL);
 	switch_event_free_subclass(MY_EVENT_ERROR_AUDIO_DEV);
+	switch_event_free_subclass(MY_EVENT_CALL_HELD);
+	switch_event_free_subclass(MY_EVENT_CALL_RESUMED);
+	
 
 	switch_safe_free(globals.dialplan);
 	switch_safe_free(globals.context);
@@ -1118,7 +1331,99 @@ static void PrintSupportedStandardSampleRates(const PaStreamParameters * inputPa
 }
 
 /*******************************************************************/
+static switch_status_t play_dev(switch_stream_handle_t *stream, int outdev, char * file, const char * max_seconds, const char * no_close)
+{
+	switch_file_handle_t fh = { 0 };
+	int samples = 0;
+	int seconds = 5;
+	audio_stream_t * audio_stream;
+	int created_stream = 0;
+	int wrote = 0;
+	switch_size_t olen;
+	int16_t abuf[2048];
+
+
+	if (!strcasecmp(file, "ringtest")) {
+		file = globals.ring_file;
+	}
+	if (outdev == -1) {
+		stream->write_function(stream, "Invalid output audio device\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	audio_stream = get_audio_stream(-1, outdev);
+
+	fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN;
+
+	if (switch_core_file_open(&fh,	file,
+		globals.read_codec.implementation->number_of_channels,
+		globals.read_codec.implementation->actual_samples_per_second,
+		SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
+			stream->write_function(stream, "Cannot play requested file %s\n", file);
+			return SWITCH_STATUS_FALSE;
+	}
+
+	olen = globals.read_codec.implementation->samples_per_packet;
+
+	if (max_seconds) {
+		int i = atoi(max_seconds);
+		if (i >= 0) {
+			seconds = i;
+		}
+	}
+
+	if (globals.call_list) {
+		switch_mutex_lock(globals.pvt_lock);
+		if (!globals.main_stream) {
+			switch_mutex_unlock(globals.pvt_lock);
+			return SWITCH_STATUS_FALSE;
+		}
+
+		if ( switch_test_flag(globals.call_list, TFLAG_MASTER) && globals.main_stream->outdev == outdev) { /*so we are the active stream so we need to dupe it basically */
+			audio_stream = create_audio_stream(-1,outdev);
+			created_stream=1;
+		}
+		switch_mutex_unlock(globals.pvt_lock);
+	}
+
+	if (! audio_stream) {
+		stream->write_function(stream, "Failed to engage audio device\n");
+		return SWITCH_STATUS_FALSE;
+	}
+
+
 
+	samples = globals.read_codec.implementation->actual_samples_per_second * seconds;
+	globals.stream_in_use=1;
+	while (switch_core_file_read(&fh, abuf, &olen) == SWITCH_STATUS_SUCCESS) {
+		if (globals.destroying_streams ||  ! audio_stream->stream) {
+			break;
+		}
+		
+		WriteAudioStream(audio_stream->stream, abuf, (long) olen, &(audio_stream->write_timer));
+		wrote += (int) olen;
+		if (samples) {
+			samples -= (int) olen;
+			if (samples <= 0) {
+				break;
+			}
+		}
+		olen = globals.read_codec.implementation->samples_per_packet;
+	}
+	globals.stream_in_use = 0;
+
+	switch_core_file_close(&fh);
+	if (! globals.call_list && ( ! no_close || strcasecmp(no_close,  "no_close"))) {
+		destroy_audio_streams();
+	}
+
+	seconds = wrote / globals.read_codec.implementation->actual_samples_per_second;
+	stream->write_function(stream, "playback test [%s] %d second(s) %d samples @%dkhz",
+		file, seconds, wrote, globals.read_codec.implementation->actual_samples_per_second);
+	if (created_stream) { /*still need this as not added to the global pool */
+		destroy_actual_stream(audio_stream);
+	}
+	return SWITCH_STATUS_SUCCESS;
+}
 static switch_status_t devlist(char **argv, int argc, switch_stream_handle_t *stream)
 {
 	int i, numDevices, prev;
@@ -1200,8 +1505,7 @@ static int dump_info(int verbose)
 	}
 
 	if (verbose < 0) {
-		deactivate_audio_device();
-		deactivate_ring_device();
+		destroy_audio_streams();
 		destroy_codecs();
 		Pa_Terminate();
 		Pa_Initialize();
@@ -1309,36 +1613,15 @@ static int dump_info(int verbose)
 	return err;
 }
 
-static switch_status_t engage_device(int restart)
+static switch_status_t create_codecs(int restart)
 {
-	PaStreamParameters inputParameters, outputParameters;
-	PaError err;
 	int sample_rate = globals.sample_rate;
 	int codec_ms = globals.codec_ms;
-	switch_event_t *event;
-
-	switch_mutex_lock(globals.device_lock);
-	while (globals.deactivate_timer > switch_epoch_time_now(NULL)) {
-		switch_yield(1000000);
-	}
-	switch_mutex_unlock(globals.device_lock);
-
 
 	if (restart) {
-		deactivate_audio_device();
-		deactivate_ring_device();
 		destroy_codecs();
 	}
-
-	if (globals.read_timer.timer_interface) {
-		switch_core_timer_sync(&globals.read_timer);
-	}
-
-	if (globals.write_timer.timer_interface) {
-		switch_core_timer_sync(&globals.write_timer);
-	}
-
-	if (globals.audio_stream) {
+	if (globals.codecs_inited) {
 		return SWITCH_STATUS_SUCCESS;
 	}
 
@@ -1375,20 +1658,18 @@ static switch_status_t engage_device(int restart)
 			return SWITCH_STATUS_FALSE;
 		}
 	}
-
-
-	if (!globals.write_timer.timer_interface) {
-		if (switch_core_timer_init(&globals.write_timer,
+	if (!globals.readfile_timer.timer_interface) {
+		if (switch_core_timer_init(&globals.readfile_timer,
 								   globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_packet,
 								   module_pool) != SWITCH_STATUS_SUCCESS) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n");
 			switch_core_codec_destroy(&globals.read_codec);
 			switch_core_codec_destroy(&globals.write_codec);
-			switch_core_timer_destroy(&globals.read_timer);
 			return SWITCH_STATUS_FALSE;
 		}
 	}
 
+
 	if (!globals.hold_timer.timer_interface) {
 		if (switch_core_timer_init(&globals.hold_timer,
 								   globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_packet,
@@ -1397,106 +1678,119 @@ static switch_status_t engage_device(int restart)
 			switch_core_codec_destroy(&globals.read_codec);
 			switch_core_codec_destroy(&globals.write_codec);
 			switch_core_timer_destroy(&globals.read_timer);
-			switch_core_timer_destroy(&globals.write_timer);
+			switch_core_timer_destroy(&globals.readfile_timer);
+			
 			return SWITCH_STATUS_FALSE;
 		}
 	}
 
-	globals.read_frame.rate = sample_rate;
-	globals.read_frame.codec = &globals.read_codec;
+	globals.cng_frame.rate = globals.read_frame.rate = sample_rate;
+	globals.cng_frame.codec = globals.read_frame.codec = &globals.read_codec;
 
-	switch_mutex_lock(globals.device_lock);
-	/* LOCKED ************************************************************************************************** */
-	inputParameters.device = globals.indev;
-	inputParameters.channelCount = 1;
-	inputParameters.sampleFormat = SAMPLE_TYPE;
-	inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
-	inputParameters.hostApiSpecificStreamInfo = NULL;
-	outputParameters.device = globals.outdev;
+	globals.codecs_inited=1;
+	return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t switch_audio_stream()
+{
+	audio_stream_t *stream;
+	if (! globals.call_list) { /* If no active calls then it will automatically switch over on next call */
+		return SWITCH_STATUS_SUCCESS;
+	}
+	stream = get_audio_stream(globals.indev, globals.outdev);
+	if (stream == NULL) {
+		return SWITCH_STATUS_FALSE;
+	}
+
+	globals.main_stream = stream;//TODO: need locks around here??
+
+	return SWITCH_STATUS_SUCCESS;
+}
+PaError open_audio_stream(PABLIO_Stream **stream, const PaStreamParameters * inputParameters, const PaStreamParameters * outputParameters)
+{
+	if (inputParameters->device != -1) {
+		return OpenAudioStream(stream, inputParameters, outputParameters, globals.sample_rate, paClipOff, globals.read_codec.implementation->samples_per_packet, globals.dual_streams);
+	}
+	return OpenAudioStream(stream, NULL, outputParameters, globals.sample_rate, paClipOff, globals.read_codec.implementation->samples_per_packet, 0);
+}
+
+static audio_stream_t *create_audio_stream(int indev, int outdev)
+{
+	PaStreamParameters inputParameters, outputParameters;
+	PaError err;
+	switch_event_t *event;
+	audio_stream_t *stream;
+
+	stream = malloc(sizeof(audio_stream_t));
+	if (stream == NULL) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to alloc memory\n");
+		return NULL;
+	}
+	memset(stream, 0, sizeof(audio_stream_t));
+	stream->next = NULL;
+	stream->stream = NULL;
+	stream->indev = indev;
+	stream->outdev = outdev;
+	if (!stream->write_timer.timer_interface) {
+		if (switch_core_timer_init(&(stream->write_timer),
+								   globals.timer_name, globals.codec_ms, globals.read_codec.implementation->samples_per_packet,
+								   module_pool) != SWITCH_STATUS_SUCCESS) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n");
+			switch_safe_free(stream);
+			return NULL;
+		}
+	}
+	inputParameters.device = indev;
+	if (indev != -1) {
+		inputParameters.channelCount = 1;
+		inputParameters.sampleFormat = SAMPLE_TYPE;
+		inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
+		inputParameters.hostApiSpecificStreamInfo = NULL;
+	}
+	outputParameters.device = outdev;
 	outputParameters.channelCount = 1;
 	outputParameters.sampleFormat = SAMPLE_TYPE;
 	outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
 	outputParameters.hostApiSpecificStreamInfo = NULL;
-	//err = OpenAudioStream(&globals.audio_stream, NULL/*&inputParameters*/, &outputParameters, sample_rate, paClipOff,
-	//globals.read_codec.implementation->samples_per_packet);
-	err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff,
-						  globals.read_codec.implementation->samples_per_packet, globals.dual_streams);
-	/* UNLOCKED ************************************************************************************************* */
+	
+	err = open_audio_stream(&(stream->stream), &inputParameters, &outputParameters);
 	if (err != paNoError) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening audio device retrying\n");
 		switch_yield(1000000);
-		err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff,
-							  globals.read_codec.implementation->samples_per_packet, globals.dual_streams);
+		err = open_audio_stream(&(stream->stream), &inputParameters, &outputParameters);
 	}
 
-	switch_mutex_unlock(globals.device_lock);
-
 	if (err != paNoError) {
+		switch_safe_free(stream);
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open audio device\n");
-		switch_core_codec_destroy(&globals.read_codec);
-		switch_core_codec_destroy(&globals.write_codec);
-		switch_core_timer_destroy(&globals.read_timer);
-		switch_core_timer_destroy(&globals.write_timer);
-		switch_core_timer_destroy(&globals.hold_timer);
 		if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_ERROR_AUDIO_DEV) == SWITCH_STATUS_SUCCESS) {
 			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Reason", Pa_GetErrorText(err));
 			switch_event_fire(&event);
 		}
-		return SWITCH_STATUS_FALSE;
+		return NULL;
 	}
-
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engage audio device rate: %d channels %d\n", sample_rate, outputParameters.channelCount);
-
-	engage_ring_device();
-
-	return SWITCH_STATUS_SUCCESS;
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created audio stream: %d channels %d\n", globals.sample_rate, outputParameters.channelCount);
+	return stream;
 }
 
-static switch_status_t engage_ring_device(void)
+audio_stream_t *get_audio_stream(int indev, int outdev)
 {
-	PaStreamParameters outputParameters = { 0 };
-	PaError err;
-	int sample_rate = globals.sample_rate;
-	int channels = 1;
-
-	if (globals.ring_stream) {
-		return SWITCH_STATUS_SUCCESS;
+	audio_stream_t *stream;
+	if (outdev == -1) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error invalid output audio device\n");
 	}
-
-	if (globals.ringdev == globals.outdev) {
-		if (engage_device(0) == SWITCH_STATUS_SUCCESS) {
-			globals.ring_stream = globals.audio_stream;
-		} else {
-			goto error;
-		}
-	} else {
-		switch_mutex_lock(globals.device_lock);
-		/* LOCKED ************************************************************************************************** */
-		outputParameters.device = globals.ringdev;
-		outputParameters.channelCount = channels;
-		outputParameters.sampleFormat = SAMPLE_TYPE;
-		outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
-		outputParameters.hostApiSpecificStreamInfo = NULL;
-		err = OpenAudioStream(&globals.ring_stream, NULL,
-							  &outputParameters, sample_rate, paClipOff, globals.read_codec.implementation->samples_per_packet, globals.dual_streams);
-		/* UNLOCKED ************************************************************************************************* */
-		switch_mutex_unlock(globals.device_lock);
-
-		if (err != paNoError) {
-			goto error;
-		}
+	if (create_codecs(0) != SWITCH_STATUS_SUCCESS) {
+		return NULL;
 	}
-
-	switch_yield(10000);
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engage ring device rate: %d channels %d\n", sample_rate, channels);
-	return SWITCH_STATUS_SUCCESS;
-
-
-  error:
-
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open ring device\n");
-	return SWITCH_STATUS_FALSE;
-
+	stream = find_audio_stream(indev, outdev, 0);
+	if (stream != NULL) {
+		return stream;
+	}
+	stream = create_audio_stream(indev, outdev);
+	if (stream) {
+		add_stream(stream, 0);
+	}
+	return stream;
 }
 
 static switch_status_t dtmf_call(char **argv, int argc, switch_stream_handle_t *stream)
@@ -1523,6 +1817,211 @@ static switch_status_t dtmf_call(char **argv, int argc, switch_stream_handle_t *
 	return SWITCH_STATUS_SUCCESS;
 }
 
+static switch_status_t close_streams(char **argv, int argc, switch_stream_handle_t *stream)
+{
+	if (globals.call_list) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	destroy_audio_streams();
+	stream->write_function(stream, "closestreams all open streams closed\n");
+	return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t set_indev(char **argv, int argc, switch_stream_handle_t *stream)
+{
+	int devval;
+
+	if (globals.call_list && ! globals.live_stream_switch) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	if (*argv[0] == '#') {
+		devval = get_dev_by_number(argv[0] + 1, 1);
+	} else {
+		devval = get_dev_by_name(argv[0], 1);
+	}
+	if (devval < 0) {
+		stream->write_function(stream, "indev not set (invalid value)\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	globals.indev = devval;
+	switch_audio_stream();
+	stream->write_function(stream, "indev set to %d\n", devval);
+	return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t set_outdev(char **argv, int argc, switch_stream_handle_t *stream)
+{
+	int devval;
+	if (globals.call_list && ! globals.live_stream_switch) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	if (*argv[0] == '#') {
+		devval = get_dev_by_number(argv[0] + 1, 0);
+	} else {
+		devval = get_dev_by_name(argv[0], 0);
+	}
+	if (devval < 0) {
+		stream->write_function(stream, "outdev not set (invalid value)\n");
+		return SWITCH_STATUS_FALSE;
+	}
+
+	globals.outdev = devval;
+	switch_audio_stream();
+	stream->write_function(stream, "outdev set to %d\n", devval);
+	return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t prepare_stream(char **argv, int argc, switch_stream_handle_t *stream)
+{
+	int devval=-2,devval2=-1;
+	if (! strcmp(argv[0], "#-1")) {
+		devval = -1;
+	} else if (*argv[0] == '#') {
+		devval = get_dev_by_number(argv[0]+1, 1);
+	}
+	if (devval == -2) {
+		stream->write_function(stream, "preparestream not prepared as indev has (invalid value)\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	if (*argv[1] == '#') {
+		devval2 = get_dev_by_number(argv[1]+1, 0);
+	}
+	if (devval2 == -1) {
+		stream->write_function(stream, "preparestream not prepared as outdev has (invalid value)\n");
+		return SWITCH_STATUS_FALSE;
+	}
+
+	if (! get_audio_stream(devval,devval2)) {
+		stream->write_function(stream, "preparestream not prepared received an invalid stream back\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	stream->write_function(stream, "preparestream prepared indev: %d outdev: %d\n", devval, devval2);
+	return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t switch_stream(char **argv, int argc, switch_stream_handle_t *stream)
+{
+	int devval =-1, devval2 = -1;
+	if (globals.call_list && ! globals.live_stream_switch) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	if (*argv[0] == '#') {
+		devval = get_dev_by_number(argv[0]+1, 1);
+	}
+	if (devval == -1) {
+		stream->write_function(stream, "switchstream not prepared as indev has (invalid value)\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	if (*argv[1] == '#') {
+		devval2 = get_dev_by_number(argv[1]+1, 0);
+	}
+	if (devval2 == -1) {
+		stream->write_function(stream, "switchstream not prepared as outdev has (invalid value)\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	globals.indev = devval;
+	globals.outdev = devval2;
+	if (switch_audio_stream() != SWITCH_STATUS_SUCCESS) {
+		stream->write_function(stream, "switchstream was unable to switch\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	stream->write_function(stream, "switchstream switched to indev: %d outdev: %d\n", devval, devval2);
+	return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t set_ringdev(char **argv, int argc, switch_stream_handle_t *stream)
+{
+	int devval;
+	if (globals.call_list && ! globals.live_stream_switch) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	if (! strcmp(argv[0], "#-1")) {
+		globals.ring_stream = NULL;
+		globals.ringdev = -1;
+		stream->write_function(stream, "ringdev set to %d\n", globals.ringdev);
+		return SWITCH_STATUS_SUCCESS;
+	} else if (*argv[0] == '#') {
+		devval = get_dev_by_number(argv[0] + 1, 0);
+	} else {
+		devval = get_dev_by_name(argv[0], 0);
+	}
+	if (devval == -1) {
+		stream->write_function(stream, "ringdev not set as dev has (invalid value)\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	globals.ringdev = devval;
+	stream->write_function(stream, "ringdev set to %d\n", globals.ringdev);
+	return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t looptest(char **argv, int argc, switch_stream_handle_t *stream)
+{
+	int samples = 0;
+	int success = 0;
+	int i;
+
+	if (globals.call_list) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	if (validate_main_audio_stream() != SWITCH_STATUS_SUCCESS) {
+		stream->write_function(stream, "looptest Failed to engage audio device\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	globals.stream_in_use = 1;
+	for (i = 0; i < 400; i++) {
+		if (globals.destroying_streams ||  ! globals.main_stream->stream) {
+			break;
+		}
+		if ((samples = ReadAudioStream(globals.main_stream->stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_packet, &globals.read_timer))) {
+			WriteAudioStream(globals.main_stream->stream, globals.read_frame.data, (long) samples, &(globals.main_stream->write_timer));
+			success = 1;
+		}
+		switch_yield(10000);
+	}
+	globals.stream_in_use = 0;
+
+	if (!success) {
+		stream->write_function(stream, "Failed to read any bytes from indev\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	destroy_audio_streams();
+	stream->write_function(stream, "looptest complete\n");
+	return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t set_ringfile(char **argv, int argc, switch_stream_handle_t *stream)
+{
+	if (! argv[0]) {
+		stream->write_function(stream, "%s", globals.ring_file);
+		return SWITCH_STATUS_SUCCESS;
+	}
+	if (create_codecs(0) == SWITCH_STATUS_SUCCESS) {
+		switch_file_handle_t fh = { 0 };
+		if (switch_core_file_open(&fh,
+								  argv[0],
+								  globals.read_codec.implementation->number_of_channels,
+								  globals.read_codec.implementation->actual_samples_per_second,
+								  SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) {
+			switch_core_file_close(&fh);
+			set_global_ring_file(argv[0]);
+		} else {
+			stream->write_function(stream, "ringfile Unable to open ring file %s\n", argv[0]);
+			return SWITCH_STATUS_FALSE;
+		}
+	} else {
+		stream->write_function(stream, "ringfile Failed to init codecs device\n");
+		return SWITCH_STATUS_FALSE;
+	}
+	stream->write_function(stream, "ringfile set to %s", globals.ring_file);
+	return SWITCH_STATUS_SUCCESS;
+}
+
 static switch_status_t switch_call(char **argv, int argc, switch_stream_handle_t *stream)
 {
 	private_t *tp, *tech_pvt = NULL;
@@ -1542,7 +2041,10 @@ static switch_status_t switch_call(char **argv, int argc, switch_stream_handle_t
 		}
 	} else if (!strcasecmp(callid, "none")) {
 		for (tp = globals.call_list; tp; tp = tp->next) {
+			if (switch_test_flag(tp, TFLAG_MASTER))	{
 			switch_clear_flag_locked(tp, TFLAG_MASTER);
+				create_hold_event(tp,0);
+			}
 		}
 		stream->write_function(stream, "OK\n");
 		goto done;
@@ -1559,6 +2061,7 @@ static switch_status_t switch_call(char **argv, int argc, switch_stream_handle_t
 			remove_pvt(tech_pvt);
 		}
 		add_pvt(tech_pvt, PA_MASTER);
+		create_hold_event(tech_pvt, 1);
 		stream->write_function(stream, "OK\n");
 	} else {
 		stream->write_function(stream, "NO SUCH CALL\n");
@@ -1609,7 +2112,6 @@ static switch_status_t answer_call(char **argv, int argc, switch_stream_handle_t
 				switch_channel_t *channel = switch_core_session_get_channel(tp->session);
 				switch_set_flag_locked(tp, TFLAG_ANSWER);
 				add_pvt(tp, PA_MASTER);
-				deactivate_ring_device();
 				switch_channel_mark_answered(channel);
 			}
 		} else {
@@ -1624,7 +2126,6 @@ static switch_status_t answer_call(char **argv, int argc, switch_stream_handle_t
 			switch_channel_t *channel = switch_core_session_get_channel(tp->session);
 			switch_set_flag_locked(tp, TFLAG_ANSWER);
 			add_pvt(tp, PA_MASTER);
-			deactivate_ring_device();
 			switch_channel_mark_answered(channel);
 			x++;
 			break;
@@ -1766,7 +2267,6 @@ static switch_status_t place_call(char **argv, int argc, switch_stream_handle_t
 			channel = switch_core_session_get_channel(session);
 			switch_core_session_set_private(session, tech_pvt);
 			tech_pvt->session = session;
-			globals.flags = GFLAG_EAR | GFLAG_MOUTH;
 		} else {
 			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
 			switch_core_session_destroy(&session);
@@ -1805,9 +2305,8 @@ static switch_status_t place_call(char **argv, int argc, switch_stream_handle_t
 			switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
 		}
 		tech_pvt->session = session;
-		if ((status = engage_device(0)) == SWITCH_STATUS_SUCCESS) {
+		if ((status = validate_main_audio_stream()) == SWITCH_STATUS_SUCCESS) {
 			switch_set_flag_locked(tech_pvt, TFLAG_ANSWER);
-			deactivate_ring_device();
 			switch_channel_mark_answered(channel);
 			switch_channel_set_state(channel, CS_INIT);
 			if (switch_core_session_thread_launch(tech_pvt->session) != SWITCH_STATUS_SUCCESS) {
@@ -1855,10 +2354,11 @@ SWITCH_STANDARD_API(pa_cmd)
 {
 	char *argv[1024] = { 0 };
 	int argc = 0;
-	char *mycmd = NULL, *devname = NULL;
+	char *mycmd = NULL;
 	switch_status_t status = SWITCH_STATUS_SUCCESS;
 	pa_command_t func = NULL;
-	int lead = 1, devval = 0;
+	int devval;
+	int lead = 1;
 	char *wcmd = NULL, *action = NULL;
 	char cmd_buf[1024] = "";
 	char *http = NULL;
@@ -1878,9 +2378,15 @@ SWITCH_STANDARD_API(pa_cmd)
 		"pa devlist [xml]\n"
 		"pa indev #<num>|<partial name>\n"
 		"pa outdev #<num>|<partial name>\n"
+		"pa preparestream #<indev_num> #<outdev_num>\n"
+		"pa switchstream #<indev_num> #<outdev_num>\n"
+		"pa closestreams\n"
 		"pa ringdev #<num>|<partial name>\n"
-		"pa play [ringtest|<filename>]\n"
-		"pa ringfile [filename]\n" "pa looptest\n" "--------------------------------------------------------------------------------\n";
+		"pa play [ringtest|<filename>] [seconds] [no_close]\n"
+		"pa playdev #<num> [ringtest|<filename>] [seconds] [no_close]\n"
+		"pa ringfile [filename]\n"
+		"pa looptest\n"
+		"--------------------------------------------------------------------------------\n";
 
 
 	if (stream->param_event) {
@@ -1973,169 +2479,42 @@ SWITCH_STANDARD_API(pa_cmd)
 		func = switch_call;
 	} else if (!strcasecmp(argv[0], "dtmf")) {
 		func = dtmf_call;
+	} else if (!strcasecmp(argv[0], "closestreams")) {
+		func = close_streams;
 	} else if (argv[1] && !strcmp(argv[0], "indev")) {
-
-		if (globals.call_list) {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
-			goto done;
-		}
-
-		if (*argv[1] == '#') {
-			devval = get_dev_by_number(argv[1] + 1, 1);
-		} else {
-			devval = get_dev_by_name(argv[1], 1);
-		}
-		devname = "indev";
-		if (devval > -1) {
-			globals.indev = devval;
-			//engage_device(1);
-		}
+		func = set_indev;
 	} else if (argv[1] && !strcmp(argv[0], "outdev")) {
-
-		if (globals.call_list) {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
-			goto done;
-		}
-
-		if (*argv[1] == '#') {
-			devval = get_dev_by_number(argv[1] + 1, 0);
-		} else {
-			devval = get_dev_by_name(argv[1], 0);
-		}
-		devname = "outdev";
-		if (devval > -1) {
-			globals.outdev = devval;
-			//engage_device(1);
-		}
+		func = set_outdev;
+	} else if (argv[1] && argv[2] && !strcmp(argv[0], "preparestream")) {
+		func = prepare_stream;	
+	} else if (argv[1] && argv[2] && !strcmp(argv[0], "switchstream")) {
+		func = switch_stream;	
 	} else if (argv[1] && !strcmp(argv[0], "ringdev")) {
-
-		if (globals.call_list) {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
-			goto done;
+		func = set_ringdev;
+	} else if ((argv[1] && !strcmp(argv[0], "play"))) {
+		if (validate_main_audio_stream() == SWITCH_STATUS_SUCCESS) {
+			play_dev(stream, globals.main_stream ? globals.main_stream->outdev : -1,argv[1],argv[2], argv[3]);
+		}else{
+			stream->write_function(stream, "Failed to engage audio device\n");
 		}
-
+		goto done;
+	} else if ((argv[1] && argv[2] && !strcmp(argv[0], "playdev"))) {
 		if (*argv[1] == '#') {
 			devval = get_dev_by_number(argv[1] + 1, 0);
 		} else {
-			devval = get_dev_by_name(argv[1], 0);
-		}
-		devname = "ringdev";
-		if (devval > -1) {
-			globals.ringdev = devval;
-			//engage_device(1);
-		}
-	} else if ((argv[1] && !strcasecmp(argv[0], "play"))) {
-		switch_file_handle_t fh = { 0 };
-		char *playfile = NULL;
-		int samples = 0;
-		int seconds = 5;
-		int wrote = 0;
-
-		if (globals.call_list) {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
-			goto done;
-		}
-
-		if (!strcasecmp(argv[1], "ringtest")) {
-			playfile = globals.ring_file;
-		} else {
-			playfile = argv[1];
-		}
-
-		fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN;
-		if (engage_device(0) == SWITCH_STATUS_SUCCESS) {
-			if (switch_core_file_open(&fh,
-									  playfile,
-									  globals.read_codec.implementation->number_of_channels,
-									  globals.read_codec.implementation->actual_samples_per_second,
-									  SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) {
-				switch_size_t olen = globals.read_codec.implementation->samples_per_packet;
-				int16_t abuf[2048];
-
-				if (argv[2]) {
-					int i = atoi(argv[2]);
-					if (i >= 0) {
-						seconds = i;
-					}
-				}
-
-				samples = globals.read_codec.implementation->actual_samples_per_second * seconds;
-				while (switch_core_file_read(&fh, abuf, &olen) == SWITCH_STATUS_SUCCESS) {
-					WriteAudioStream(globals.audio_stream, abuf, (long) olen, &globals.read_timer);
-					wrote += (int) olen;
-					if (samples) {
-						samples -= (int) olen;
-						if (samples <= 0) {
-							break;
-						}
-					}
-					olen = globals.read_codec.implementation->samples_per_packet;
-				}
-
-				switch_core_file_close(&fh);
-				deactivate_audio_device();
-
-				seconds = wrote / globals.read_codec.implementation->actual_samples_per_second;
-				stream->write_function(stream, "playback test [%s] %d second(s) %d samples @%dkhz",
-									   playfile, seconds, wrote, globals.read_codec.implementation->actual_samples_per_second);
-
-
-			} else {
-				stream->write_function(stream, "Cannot play requested file %s\n", argv[1]);
-			}
-		} else {
-			stream->write_function(stream, "Failed to engage audio device\n");
+			devval = -1;
 		}
+		play_dev(stream, devval,argv[2],argv[3],argv[4]);
 		goto done;
 	} else if (!strcasecmp(argv[0], "looptest")) {
-		if (globals.call_list) {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
-			goto done;
-		}
-
-		if (engage_device(0) == SWITCH_STATUS_SUCCESS) {
-			int samples = 0;
-			int success = 0;
-			int i;
-			for (i = 0; i < 400; i++) {
-				if ((samples = ReadAudioStream(globals.audio_stream, globals.read_frame.data,
-											   globals.read_codec.implementation->samples_per_packet, &globals.read_timer))) {
-					WriteAudioStream(globals.audio_stream, globals.read_frame.data, (long) samples, &globals.write_timer);
-					success = 1;
-				}
-				switch_yield(10000);
-			}
-			if (!success) {
-				stream->write_function(stream, "Failed to read any bytes from indev\n");
-			}
-			deactivate_audio_device();
-		} else {
-			stream->write_function(stream, "Failed to engage audio device\n");
-		}
-		goto done;
+		func = looptest;
 	} else if (!strcasecmp(argv[0], "ringfile")) {
-		if (argv[1]) {
-			if (engage_device(0) == SWITCH_STATUS_SUCCESS) {
-				switch_file_handle_t fh = { 0 };
-				if (switch_core_file_open(&fh,
-										  argv[1],
-										  globals.read_codec.implementation->number_of_channels,
-										  globals.read_codec.implementation->actual_samples_per_second,
-										  SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) {
-					switch_core_file_close(&fh);
-					set_global_ring_file(argv[1]);
-				} else {
-					stream->write_function(stream, "Unable to open ring file %s\n", argv[1]);
-				}
-			} else {
-				stream->write_function(stream, "Failed to engage audio device\n");
-			}
-		} else {
-			stream->write_function(stream, "%s", globals.ring_file);
-		}
-		goto done;
+		func = set_ringfile;
+	} else {
+		stream->write_function(stream, "Unknown Command or not enough args [%s]\n", argv[0]);
 	}
 
+
 	if (func) {
 		if (http) {
 			stream->write_function(stream, "<pre>");
@@ -2143,21 +2522,12 @@ SWITCH_STANDARD_API(pa_cmd)
 
 		switch_mutex_lock(globals.pa_mutex);
 		status = func(&argv[lead], argc - lead, stream);
+		status = SWITCH_STATUS_SUCCESS; /*if func was defined we want to always return success as the command was found */
 		switch_mutex_unlock(globals.pa_mutex);
 
 		if (http) {
 			stream->write_function(stream, "\n\n</pre>");
 		}
-	} else {
-		if (devname) {
-			if (devval > -1) {
-				stream->write_function(stream, "%s set to %d\n", devname, devval);
-			} else {
-				stream->write_function(stream, "%s not set (invalid value)\n", devname);
-			}
-		} else {
-			stream->write_function(stream, "Unknown Command [%s]\n", argv[0]);
-		}
 	}
 
   done:
@@ -2171,6 +2541,14 @@ SWITCH_STANDARD_API(pa_cmd)
 							   "<input name=action type=submit value=\"switch\"> "
 							   "<input name=action type=submit value=\"mute\"> "
 							   "<input name=action type=submit value=\"unmute\"> "
+							   "<input name=action type=submit value=\"indev\"> "
+							   "<input name=action type=submit value=\"outdev\"> "
+							   "<input name=action type=submit value=\"preparestream\"> "
+							   "<input name=action type=submit value=\"switchstream\"> "
+							   "<input name=action type=submit value=\"closestreams\"> "
+							   "<input name=action type=submit value=\"ringdev\"> "
+							   "<input name=action type=submit value=\"play\"> "
+							   "<input name=action type=submit value=\"playdev\"> "
 							   "<input name=action type=submit value=\"answer\"> <br><br>"
 							   "<table border=1>\n"
 							   "<tr><td><input name=action type=submit value=\"1\"></td>"
committer: Anthony Minessale
comments: 
try to improve iLBC compat

diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c
index 8b2f470..a0b7fca 100644
--- a/src/mod/endpoints/mod_sofia/sofia_glue.c
+++ b/src/mod/endpoints/mod_sofia/sofia_glue.c
@@ -4480,7 +4480,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
 						match = strcasecmp(rm_encoding, imp->iananame) ? 0 : 1;
 					}
 
-					if (match && bit_rate && map_bit_rate && map_bit_rate != bit_rate) {
+					if (match && bit_rate && map_bit_rate && map_bit_rate != bit_rate && strcasecmp(map->rm_encoding, "ilbc")) {
 						/* nevermind */
 						match = 0;
 					}
diff --git a/src/switch_core.c b/src/switch_core.c
index 8754305..0eb51cc 100644
--- a/src/switch_core.c
+++ b/src/switch_core.c
@@ -1486,7 +1486,7 @@ static void switch_load_core_config(const char *file)
 {
 	switch_xml_t xml = NULL, cfg = NULL;
 
-	//switch_core_hash_insert(runtime.ptimes, "ilbc", &d_30);
+	switch_core_hash_insert(runtime.ptimes, "ilbc", &d_30);
 	switch_core_hash_insert(runtime.ptimes, "G723", &d_30);
 
 	if ((xml = switch_xml_open_cfg(file, &cfg, NULL))) {
committer: Leon de Rooij
comments: 
Merge branch 'master' of ssh://git.freeswitch.org/freeswitch
committer: Leon de Rooij
comments: 
Merge branch 'master' of ssh://git.freeswitch.org/freeswitch
committer: Leon de Rooij
comments: 
Merge branch 'master' of ssh://git.freeswitch.org/freeswitch
committer: Leon de Rooij
comments: 
Merge branch 'master' of ssh://git.freeswitch.org/freeswitch
committer: Leon de Rooij
comments: 
Merge branch 'master' of ssh://git.freeswitch.org/freeswitch
committer: Leon de Rooij
comments: 
Merge branch 'master' of ssh://git.freeswitch.org/freeswitch
committer: Leon de Rooij
comments: 
enter

diff --git a/src/mod/languages/mod_lua/mod_lua_extra.c b/src/mod/languages/mod_lua/mod_lua_extra.c
index 38776f9..821cc60 100644
--- a/src/mod/languages/mod_lua/mod_lua_extra.c
+++ b/src/mod/languages/mod_lua/mod_lua_extra.c
@@ -1,6 +1,8 @@
 using namespace LUA;
 
-SWITCH_BEGIN_EXTERN_C void mod_lua_conjure_event(lua_State * L, switch_event_t *event, const char *name, int destroy_me)
+SWITCH_BEGIN_EXTERN_C
+
+void mod_lua_conjure_event(lua_State * L, switch_event_t *event, const char *name, int destroy_me)
 {
 	Event *result = new Event(event);
 	SWIG_NewPointerObj(L, result, SWIGTYPE_p_Event, destroy_me);
committer: Leon de Rooij
comments: 
enter

diff --git a/src/mod/languages/mod_lua/mod_lua_extra.h b/src/mod/languages/mod_lua/mod_lua_extra.h
index b96adc3..3fca994 100644
--- a/src/mod/languages/mod_lua/mod_lua_extra.h
+++ b/src/mod/languages/mod_lua/mod_lua_extra.h
@@ -1,6 +1,8 @@
 #ifndef MOD_LUA_EXTRA
 #define MOD_LUA_EXTRA
-SWITCH_BEGIN_EXTERN_C void mod_lua_conjure_event(lua_State * L, switch_event_t *event, const char *name, int destroy_me);
+SWITCH_BEGIN_EXTERN_C
+
+void mod_lua_conjure_event(lua_State * L, switch_event_t *event, const char *name, int destroy_me);
 void mod_lua_conjure_stream(lua_State * L, switch_stream_handle_t *stream, const char *name, int destroy_me);
 void mod_lua_conjure_session(lua_State * L, switch_core_session_t *session, const char *name, int destroy_me);
 
========================================================================

Summary of changes:
 Freeswitch.2010.sln                                |   24 +-
 build/modules.conf.in                              |    1 +
 conf/autoload_configs/cdr_pg_csv.conf.xml          |   35 +-
 conf/autoload_configs/modules.conf.xml             |    1 +
 conf/autoload_configs/switch.conf.xml              |    4 +
 libs/esl/fs_cli.c                                  |   44 +-
 libs/ilbc/src/iLBC_decode.c                        |    2 +
 libs/portaudio/build/msvc/portaudio.2010.vcxproj   |  136 +--
 src/mod/applications/mod_commands/mod_commands.c   |   18 +-
 src/mod/applications/mod_dptools/mod_dptools.c     |   10 +-
 src/mod/applications/mod_fsk/mod_fsk.c             |    4 +-
 src/mod/applications/mod_voicemail/mod_voicemail.c |   10 +-
 src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c          |   51 +-
 src/mod/codecs/mod_opus/Makefile                   |   28 +
 .../{mod_celt/mod_celt.c => mod_opus/mod_opus.c}   |  153 ++--
 .../mod_dialplan_asterisk/mod_dialplan_asterisk.c  |    6 +-
 src/mod/endpoints/mod_portaudio/mod_portaudio.c    | 1046 +++++++++++++-------
 src/mod/endpoints/mod_sofia/mod_sofia.c            |    2 +-
 src/mod/endpoints/mod_sofia/sofia_glue.c           |    2 +-
 src/mod/endpoints/mod_sofia/sofia_presence.c       |    2 +-
 .../event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c |  396 ++++-----
 src/mod/languages/mod_lua/mod_lua_extra.c          |    4 +-
 src/mod/languages/mod_lua/mod_lua_extra.h          |    4 +-
 src/mod/languages/mod_lua/mod_lua_wrap.cpp         |   50 +
 .../languages/mod_spidermonkey/mod_spidermonkey.c  |   10 +
 src/switch_core.c                                  |    2 +-
 src/switch_core_session.c                          |   15 +
 src/switch_rtp.c                                   |    4 +
 src/switch_xml_config.c                            |    2 +-
 support-d/prereq.sh                                |    2 +-
 30 files changed, 1267 insertions(+), 801 deletions(-)
 create mode 100644 src/mod/codecs/mod_opus/Makefile
 copy src/mod/codecs/{mod_celt/mod_celt.c => mod_opus/mod_opus.c} (52%)

this email was generated because of /git/your-repo.git/hooks/post-receive by the file /git-core/contrib/hooks/post-receive-email
For more info, see http://blog.chomperstomp.com/?p=630 --
FreeSWITCH Source