[svn-commits] russell: branch group/newcdr r202756 - in /team/group/newcdr: include/asteris...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Jun 23 16:46:46 CDT 2009


Author: russell
Date: Tue Jun 23 16:46:43 2009
New Revision: 202756

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=202756
Log:
Add proper channel locking to ast_cel_report_event().

Also, make report_event() return success/failure.  Finally, add API documentation
for report_event().

Modified:
    team/group/newcdr/include/asterisk/cel.h
    team/group/newcdr/main/cel.c

Modified: team/group/newcdr/include/asterisk/cel.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/newcdr/include/asterisk/cel.h?view=diff&rev=202756&r1=202755&r2=202756
==============================================================================
--- team/group/newcdr/include/asterisk/cel.h (original)
+++ team/group/newcdr/include/asterisk/cel.h Tue Jun 23 16:46:43 2009
@@ -161,7 +161,7 @@
  *
  * \return nothing
  */
-void ast_cel_check_retire_linkedid(const struct ast_channel *chan);
+void ast_cel_check_retire_linkedid(struct ast_channel *chan);
 
 /*!
  * \brief Create a fake channel from data in a CEL event
@@ -179,9 +179,28 @@
  */
 struct ast_channel *ast_cel_fabricate_channel_from_event(const struct ast_event *event);
 
-void ast_cel_report_event(const struct ast_channel *chan, enum ast_cel_event_type,
-		char *userdefevname, const char *extra,
-		const struct ast_channel *peer2);
+/*!
+ * \brief Report a channel event
+ *
+ * \param chan This argument is required.  This is the primary channel associated with
+ *        this channel event.
+ * \param event_type This is the type of call event being reported.
+ * \param userdefevname This is an optional custom name for the call event.
+ * \param extra This is an optional opaque field that will go into the "CEL_EXTRA"
+ *        information element of the call event.
+ * \param peer2 All CEL events contain a "peer name" information element.  The first
+ *        place the code will look to get a peer name is from the bridged channel to
+ *        chan.  If chan has no bridged channel and peer2 is specified, then the name
+ *        of peer2 will go into the "peer name" field.  If neither are available, the
+ *        peer name field will be blank.
+ *
+ * \pre chan and peer2 are both unlocked
+ *
+ * \retval 0 success
+ * \retval non-zero failure
+ */
+int ast_cel_report_event(struct ast_channel *chan, enum ast_cel_event_type event_type,
+		const char *userdefevname, const char *extra, struct ast_channel *peer2);
 
 /*!
  * \brief Helper struct for getting the fields out of a CEL event

Modified: team/group/newcdr/main/cel.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/newcdr/main/cel.c?view=diff&rev=202756&r1=202755&r2=202756
==============================================================================
--- team/group/newcdr/main/cel.c (original)
+++ team/group/newcdr/main/cel.c Tue Jun 23 16:46:43 2009
@@ -348,7 +348,7 @@
 	return res ? CMP_MATCH | CMP_STOP : 0;
 }
 
-void ast_cel_check_retire_linkedid(const struct ast_channel *chan)
+void ast_cel_check_retire_linkedid(struct ast_channel *chan)
 {
 	const char *linkedid = chan->linkedid;
 	struct channel_find_data find_dat;
@@ -445,39 +445,36 @@
  * \todo Review channel locking requirements
  * \todo Document this API call
  */
-void ast_cel_report_event(const struct ast_channel *chan,
-		enum ast_cel_event_type event_type, char *userdefevname,
-		const char *extra, const struct ast_channel *peer2)
+int ast_cel_report_event(struct ast_channel *chan, enum ast_cel_event_type event_type,
+		const char *userdefevname, const char *extra, struct ast_channel *peer2)
 {
 	struct timeval eventtime;
 	struct ast_event *ev;
-	char *udef = userdefevname;
 	const char *peername = "";
-	struct ast_channel *peer = ast_bridged_channel((struct ast_channel *) chan);
+	struct ast_channel *peer;
+
+	ast_channel_lock(chan);
+	peer = ast_bridged_channel(chan);
+	if (peer) {
+		ast_channel_ref(peer);
+	}
+	ast_channel_unlock(chan);
 
 	/* Make sure a reload is not occurring while we're checking to see if this
 	 * is an event that we care about.  We could lose an important event in this
 	 * process otherwise. */
 	ast_mutex_lock(&reload_lock);
 
-	if (!cel_enabled) {
+	if (!cel_enabled || !ast_cel_track_event(event_type)) {
 		ast_mutex_unlock(&reload_lock);
-		return;
-	}
-
-	if (!ast_cel_track_event(event_type)) {
-		ast_debug(1, "CEL event UNtracked: %s\n", ast_cel_get_type_name(event_type));
-		ast_mutex_unlock(&reload_lock);
-		return;
-	}
-
-	ast_debug(3, "CEL event tracked: %s\n", ast_cel_get_type_name(event_type));
+		return 0;
+	}
 
 	if (event_type == AST_CEL_APP_START || event_type == AST_CEL_APP_END) {
 		char *app;
 		if (!(app = ao2_find(appset, (char *) chan->appl, OBJ_POINTER))) {
 			ast_mutex_unlock(&reload_lock);
-			return;
+			return 0;
 		}
 		ao2_ref(app, -1);
 	}
@@ -485,25 +482,32 @@
 	ast_mutex_unlock(&reload_lock);
 
 	if (peer) {
-		peername = peer->name;
-	}
-	if (peer2) {
-		peername = peer2->name;
-	}
-	if (!udef) {
-		udef = "";
-	}
+		ast_channel_lock(peer);
+		peername = ast_strdupa(peer->name);
+		ast_channel_unlock(peer);
+	} else if (peer2) {
+		ast_channel_lock(peer2);
+		peername = ast_strdupa(peer2->name);
+		ast_channel_unlock(peer2);
+	}
+
+	if (!userdefevname) {
+		userdefevname = "";
+	}
+
 	if (!extra) {
 		extra = "";
 	}
 
 	eventtime = ast_tvnow();
+
+	ast_channel_lock(chan);
 
 	ev = ast_event_new(AST_EVENT_CEL,
 			AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_PLTYPE_UINT, event_type,
 			AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_sec,
 			AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_usec,
-			AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_PLTYPE_STR, udef,
+			AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_PLTYPE_STR, userdefevname,
 			AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->cid.cid_name, ""),
 			AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->cid.cid_num, ""),
 			AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->cid.cid_ani, ""),
@@ -524,9 +528,18 @@
 			AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, peername,
 			AST_EVENT_IE_END);
 
+	ast_channel_unlock(chan);
+
+	if (peer) {
+		peer = ast_channel_unref(peer);
+	}
+
 	if (ev && ast_event_queue(ev)) {
 		ast_event_destroy(ev);
-	}
+		return -1;
+	}
+
+	return 0;
 }
 
 int ast_cel_fill_record(const struct ast_event *e, struct ast_cel_event_record *r)




More information about the svn-commits mailing list