[asterisk-commits] mmichelson: branch group/CCSS r220997 - in /team/group/CCSS: apps/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Sep 29 16:30:42 CDT 2009


Author: mmichelson
Date: Tue Sep 29 16:30:39 2009
New Revision: 220997

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=220997
Log:
* Make sure we don't crash in monitor destruction if
  the event subscription pointer is NULL.
* Change logic of app_dial a bit so that nested dials
  cannot create multiple core instances. Now, any nested
  dial may add to the interface tree, but only the topmost
  Dial can actually create a new CC core instance.


Modified:
    team/group/CCSS/apps/app_dial.c
    team/group/CCSS/main/ccss.c

Modified: team/group/CCSS/apps/app_dial.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/apps/app_dial.c?view=diff&rev=220997&r1=220996&r2=220997
==============================================================================
--- team/group/CCSS/apps/app_dial.c (original)
+++ team/group/CCSS/apps/app_dial.c Tue Sep 29 16:30:39 2009
@@ -586,6 +586,7 @@
 static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str *featurecode);
 static void cc_set_done_flag(struct ast_channel *chan);
 static void handle_cc_control_frame(struct ast_channel *inbound, struct ast_channel *outbound, void *frame_data);
+static int dial_create_new_cc_core(struct ast_channel *inbound);
 
 static void hanguptree(struct chanlist *outgoing, struct ast_channel *exception, int answered_elsewhere)
 {
@@ -941,6 +942,7 @@
 				ast_verb(3, "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
 			}
 			*to = 0;
+			dial_create_new_cc_core(in);
 			return NULL;
 		}
 		winner = ast_waitfor_n(watchers, pos, to);
@@ -1211,6 +1213,7 @@
 					}
 					ast_frfree(f);
 				}
+				dial_create_new_cc_core(in);
 				return NULL;
 			}
 
@@ -1228,6 +1231,7 @@
 						strcpy(pa->status, "CANCEL");
 						ast_frfree(f);
 						ast_channel_unlock(in);
+						dial_create_new_cc_core(in);
 						return NULL;
 					}
 					ast_channel_unlock(in);
@@ -1240,6 +1244,7 @@
 					strcpy(pa->status, "CANCEL");
 					ast_cdr_noanswer(in->cdr);
 					ast_frfree(f);
+					dial_create_new_cc_core(in);
 					return NULL;
 				}
 			}
@@ -1282,6 +1287,7 @@
 	}
 #endif
 
+	dial_create_new_cc_core(in);
 	return peer;
 }
 
@@ -1598,13 +1604,11 @@
 	 */
 	char done;
 	/*!
-	 * When an AST_CONTROL_CC frame is received, we need to create
-	 * a new instance of the CC core. However, we only need to do
-	 * this one time, so if there are nested Dials, we need to let
-	 * the new one know not to try to create a new instance of the
-	 * core
+	 * When nested dials occur (i.e. dialing local channels), we need
+	 * to be sure that they will not try to create a core instance themselves.
+	 * Instead, they need to pass the frame up to the parent dialing application.
 	 */
-	char core_created;
+	char nested_dial;
 	/*!
 	 * Reference-counted "tree" of interfaces.
 	 */
@@ -1650,7 +1654,7 @@
 	}
 	new_cc_interfaces->done = old_cc_interfaces->done;
 	new_cc_interfaces->dial_parent_id = old_cc_interfaces->dial_parent_id;
-	new_cc_interfaces->core_created = old_cc_interfaces->core_created;
+	new_cc_interfaces->nested_dial = 1;
 	ao2_t_ref(old_cc_interfaces->interface_tree, +1, "New ref due to duplication of interface tree");
 	new_cc_interfaces->interface_tree = old_cc_interfaces->interface_tree;
 	return new_cc_interfaces;
@@ -1872,13 +1876,11 @@
 static void handle_cc_control_frame(struct ast_channel *inbound, struct ast_channel *outbound, void *frame_data)
 {
 	char device_name[AST_CHANNEL_NAME];
-	char core_id_str[20];
 	char *dash;
 	struct ast_cc_tree_item *tree_item;
 	struct ast_datastore *cc_datastore;
 	struct dial_cc_interfaces *cc_interfaces;
 	struct ast_control_cc_payload *cc_data = frame_data;
-	int core_id;
 
 	ast_copy_string(device_name, outbound->name, sizeof(device_name));
 	if ((dash = strrchr(device_name, '-'))) {
@@ -1900,21 +1902,45 @@
 	AST_LIST_LOCK(cc_interfaces->interface_tree);
 	AST_LIST_INSERT_TAIL(cc_interfaces->interface_tree, tree_item, next);
 	AST_LIST_UNLOCK(cc_interfaces->interface_tree);
-
-	/* If this is the first CC frame we're processing, we need to
-	 * save the list in the core.
-	 */
-	if (!cc_interfaces->core_created) {
+}
+
+static int dial_create_new_cc_core(struct ast_channel *inbound)
+{
+	struct ast_datastore *cc_datastore;
+	struct dial_cc_interfaces *cc_interfaces;
+	int is_tree_empty;
+
+	ast_channel_lock(inbound);
+	if (!(cc_datastore = ast_channel_datastore_find(inbound, &dial_cc_interfaces_info, NULL))) {
+		ast_channel_unlock(inbound);
+		return -1;
+	}
+	ast_channel_unlock(inbound);
+
+	cc_interfaces = cc_datastore->data;
+
+	if (cc_interfaces->nested_dial) {
+		/* Abort. Nested dials have no place trying
+		 * to create an instance of the core. Leave this
+		 * for the topmost Dial.
+		 */
+		return 0;
+	}
+
+	AST_LIST_LOCK(cc_interfaces->interface_tree);
+	is_tree_empty = AST_LIST_EMPTY(cc_interfaces->interface_tree);
+	AST_LIST_UNLOCK(cc_interfaces->interface_tree);
+
+	if (!is_tree_empty) {
+		int core_id;
+		char core_id_str[20]; 
 		core_id = ast_cc_core_init_instance(inbound, cc_interfaces->interface_tree);
-		cc_interfaces->core_created = 1;
-		/* We set the core_created flag to 1 even if the core instance creation was
-		 * unsuccessful. This way we don't keep attempting to do it and keep failing.
-		 */
 		if (core_id != -1) {
 			snprintf(core_id_str, sizeof(core_id_str), "%d", core_id);
 			pbx_builtin_setvar_helper(inbound, "CC_AVAIL", core_id_str);
 		}
 	}
+	return 0;
 }
 
 /*!

Modified: team/group/CCSS/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/main/ccss.c?view=diff&rev=220997&r1=220996&r2=220997
==============================================================================
--- team/group/CCSS/main/ccss.c (original)
+++ team/group/CCSS/main/ccss.c Tue Sep 29 16:30:39 2009
@@ -1752,7 +1752,9 @@
 	struct generic_monitor_pvt *gen_mon_pvt = mon->private_data;
 
 	ast_log(LOG_NOTICE, "Destroying generic monitor private\n");
-	gen_mon_pvt->sub = ast_event_unsubscribe(gen_mon_pvt->sub);
+	if (gen_mon_pvt->sub) {
+		gen_mon_pvt->sub = ast_event_unsubscribe(gen_mon_pvt->sub);
+	}
 	ast_free(gen_mon_pvt);
 	return;
 }




More information about the asterisk-commits mailing list