[asterisk-commits] kmoore: branch kmoore/stasis-http_sounds r391292 - in /team/kmoore/stasis-htt...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jun 10 14:01:58 CDT 2013


Author: kmoore
Date: Mon Jun 10 14:01:54 2013
New Revision: 391292

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=391292
Log:
Resolve merge conflict

Added:
    team/kmoore/stasis-http_sounds/include/asterisk/backtrace.h
      - copied unchanged from r391271, trunk/include/asterisk/backtrace.h
    team/kmoore/stasis-http_sounds/include/asterisk/features_config.h
      - copied unchanged from r391271, trunk/include/asterisk/features_config.h
    team/kmoore/stasis-http_sounds/main/backtrace.c
      - copied unchanged from r391271, trunk/main/backtrace.c
    team/kmoore/stasis-http_sounds/main/features_config.c
      - copied unchanged from r391271, trunk/main/features_config.c
    team/kmoore/stasis-http_sounds/res/parking/parking_devicestate.c
      - copied unchanged from r391271, trunk/res/parking/parking_devicestate.c
    team/kmoore/stasis-http_sounds/res/res_stasis_bridge_add.c
      - copied unchanged from r391271, trunk/res/res_stasis_bridge_add.c
    team/kmoore/stasis-http_sounds/res/res_stasis_bridge_add.exports.in
      - copied unchanged from r391271, trunk/res/res_stasis_bridge_add.exports.in
Modified:
    team/kmoore/stasis-http_sounds/   (props changed)
    team/kmoore/stasis-http_sounds/CHANGES
    team/kmoore/stasis-http_sounds/UPGRADE.txt
    team/kmoore/stasis-http_sounds/apps/app_bridgewait.c
    team/kmoore/stasis-http_sounds/apps/app_dial.c
    team/kmoore/stasis-http_sounds/apps/app_meetme.c
    team/kmoore/stasis-http_sounds/apps/app_queue.c
    team/kmoore/stasis-http_sounds/apps/confbridge/confbridge_manager.c
    team/kmoore/stasis-http_sounds/bridges/bridge_builtin_features.c
    team/kmoore/stasis-http_sounds/bridges/bridge_softmix.c
    team/kmoore/stasis-http_sounds/channels/chan_dahdi.c
    team/kmoore/stasis-http_sounds/channels/chan_iax2.c
    team/kmoore/stasis-http_sounds/channels/chan_mgcp.c
    team/kmoore/stasis-http_sounds/channels/chan_misdn.c
    team/kmoore/stasis-http_sounds/channels/chan_sip.c
    team/kmoore/stasis-http_sounds/channels/chan_unistim.c
    team/kmoore/stasis-http_sounds/channels/sig_analog.c
    team/kmoore/stasis-http_sounds/channels/sig_pri.c
    team/kmoore/stasis-http_sounds/channels/sig_pri.h
    team/kmoore/stasis-http_sounds/channels/sip/include/sip.h
    team/kmoore/stasis-http_sounds/configs/chan_dahdi.conf.sample
    team/kmoore/stasis-http_sounds/configs/iax.conf.sample
    team/kmoore/stasis-http_sounds/configs/queues.conf.sample
    team/kmoore/stasis-http_sounds/configs/sip.conf.sample
    team/kmoore/stasis-http_sounds/configs/skinny.conf.sample
    team/kmoore/stasis-http_sounds/include/asterisk/bridging.h
    team/kmoore/stasis-http_sounds/include/asterisk/bridging_features.h
    team/kmoore/stasis-http_sounds/include/asterisk/bridging_technology.h
    team/kmoore/stasis-http_sounds/include/asterisk/channel.h
    team/kmoore/stasis-http_sounds/include/asterisk/features.h
    team/kmoore/stasis-http_sounds/include/asterisk/lock.h
    team/kmoore/stasis-http_sounds/include/asterisk/logger.h
    team/kmoore/stasis-http_sounds/include/asterisk/manager.h
    team/kmoore/stasis-http_sounds/include/asterisk/pbx.h
    team/kmoore/stasis-http_sounds/include/asterisk/stasis.h
    team/kmoore/stasis-http_sounds/include/asterisk/stasis_app.h
    team/kmoore/stasis-http_sounds/include/asterisk/stasis_bridging.h
    team/kmoore/stasis-http_sounds/include/asterisk/stasis_message_router.h
    team/kmoore/stasis-http_sounds/main/app.c
    team/kmoore/stasis-http_sounds/main/astmm.c
    team/kmoore/stasis-http_sounds/main/astobj2.c
    team/kmoore/stasis-http_sounds/main/bridging.c
    team/kmoore/stasis-http_sounds/main/channel.c
    team/kmoore/stasis-http_sounds/main/endpoints.c
    team/kmoore/stasis-http_sounds/main/features.c
    team/kmoore/stasis-http_sounds/main/logger.c
    team/kmoore/stasis-http_sounds/main/manager.c
    team/kmoore/stasis-http_sounds/main/pbx.c
    team/kmoore/stasis-http_sounds/main/stasis_bridging.c
    team/kmoore/stasis-http_sounds/main/stasis_cache.c
    team/kmoore/stasis-http_sounds/main/stasis_channels.c
    team/kmoore/stasis-http_sounds/main/stasis_message_router.c
    team/kmoore/stasis-http_sounds/res/parking/parking_bridge.c
    team/kmoore/stasis-http_sounds/res/parking/parking_bridge_features.c
    team/kmoore/stasis-http_sounds/res/parking/parking_controller.c
    team/kmoore/stasis-http_sounds/res/parking/parking_manager.c
    team/kmoore/stasis-http_sounds/res/parking/res_parking.h
    team/kmoore/stasis-http_sounds/res/res_agi.c
    team/kmoore/stasis-http_sounds/res/res_parking.c
    team/kmoore/stasis-http_sounds/res/res_stasis.c
    team/kmoore/stasis-http_sounds/res/res_stasis_http_channels.c
    team/kmoore/stasis-http_sounds/res/res_stasis_json_events.c
    team/kmoore/stasis-http_sounds/res/res_stasis_json_events.exports.in
    team/kmoore/stasis-http_sounds/res/stasis/app.c
    team/kmoore/stasis-http_sounds/res/stasis/app.h
    team/kmoore/stasis-http_sounds/res/stasis/control.c
    team/kmoore/stasis-http_sounds/res/stasis_http/resource_bridges.c
    team/kmoore/stasis-http_sounds/res/stasis_http/resource_bridges.h
    team/kmoore/stasis-http_sounds/res/stasis_http/resource_channels.c
    team/kmoore/stasis-http_sounds/res/stasis_http/resource_channels.h
    team/kmoore/stasis-http_sounds/res/stasis_json/resource_channels.h
    team/kmoore/stasis-http_sounds/res/stasis_json/resource_events.h
    team/kmoore/stasis-http_sounds/rest-api/api-docs/bridges.json
    team/kmoore/stasis-http_sounds/rest-api/api-docs/channels.json
    team/kmoore/stasis-http_sounds/rest-api/api-docs/events.json
    team/kmoore/stasis-http_sounds/tests/test_devicestate.c
    team/kmoore/stasis-http_sounds/tests/test_stasis.c
    team/kmoore/stasis-http_sounds/utils/extconf.c

Propchange: team/kmoore/stasis-http_sounds/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.

Propchange: team/kmoore/stasis-http_sounds/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Jun 10 14:01:54 2013
@@ -1,1 +1,1 @@
-/trunk:1-390681
+/trunk:1-391291

Modified: team/kmoore/stasis-http_sounds/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-http_sounds/CHANGES?view=diff&rev=391292&r1=391291&r2=391292
==============================================================================
--- team/kmoore/stasis-http_sounds/CHANGES (original)
+++ team/kmoore/stasis-http_sounds/CHANGES Mon Jun 10 14:01:54 2013
@@ -106,6 +106,18 @@
    core, and is now two events: Hold and Unhold.  The status field has been
    removed.
 
+ * The AMI events in app_queue have been made more consistent with each other.
+   Events that reference channels (QueueCaller* and Agent*) will show
+   information about each channel.  The (infamous) "Join" and "Leave" AMI
+   events have been changed to "QueueCallerJoin" and "QueueCallerLeave".
+
+AGI (Asterisk Gateway Interface)
+------------------
+ * The manager event AGIExec has been split into AGIExecStart and AGIExecEnd.
+
+ * The manager event AsyncAGI has been split into AsyncAGIStart, AsyncAGIExec,
+   and AsyncAGIEnd.
+
 Channel Drivers
 ------------------
  * When a channel driver is configured to enable jiterbuffers, they are now
@@ -180,6 +192,11 @@
    The preferred way to configure parking is now through res_parking.conf while
    configuration through features.conf is not currently supported.
 
+ * res_parking uses the configuration framework. If an invalid configuration is
+   supplied, res_parking will fail to load or fail to reload. Previously parking
+   lots that were misconfigured would generally be accepted with certain
+   configuration problems leading to individual disabled parking lots.
+
  * Parked calls are now placed in bridges. This is a largely architectural change,
    but it could have some implications in allowing for new parked call retrieval
    methods and the contents of parking lots will be visible though certain bridge
@@ -219,6 +236,11 @@
    by default. Instead, it will follow the timeout rules of the parking lot. The
    old behavior can be reproduced by using the 'c' option.
 
+ * Added a channel variable PARKER_FLAT which stores the name of the extension
+   that would be used to come back to if comebacktoorigin was set to use. This can
+   be useful when comebacktoorigin is off if you still want to use the extensions
+   in the park-dial context that are generated to redial the parker on timeout.
+
 Queue
 -------------------
  * Add queue available hint.  exten => 8501,hint,Queue:markq_avail
@@ -226,6 +248,11 @@
    Reports 'InUse' for no logged in agents or no free agents.
    Reports 'Idle' when an agent is free.
 
+ * The configuration options eventwhencalled and eventmemberstatus have been
+   removed.  As a result, the AMI events QueueMemberStatus, AgentCalled,
+   AgentConnect, AgentComplete, AgentDump, and AgentRingNoAnswer will always be
+   sent.  The "Variable" fields will also no longer exist on the Agent* events.
+
 Core
 ------------------
  * Redirecting reasons can now be set to arbitrary strings. This means
@@ -233,6 +260,31 @@
    reason to any string. It also allows for custom strings to be read as the
    redirecting reason from SIP Diversion headers.
 
+ * For DTMF blind and attended transfers, the channel variable TRANSFER_CONTEXT
+   must be on the channel initiating the transfer to have any effect.
+
+ * The channel variable ATTENDED_TRANSFER_COMPLETE_SOUND is no longer channel
+   driver specific.  If the channel variable is set on the transferrer channel,
+   the sound will be played to the target of an attended transfer.
+
+ * The channel variable BRIDGEPEER becomes a comma separated list of peers in
+   a multi-party bridge.  The BRIDGEPEER value can have a maximum of 10 peers
+   listed.  Any more peers in the bridge will not be included in the list.
+   BRIDGEPEER is not valid in holding bridges like parking since those channels
+   do not talk to each other even though they are in a bridge.
+
+ * The channel variable BRIDGEPVTCALLID is only valid for two party bridges
+   and will contain a value if the BRIDGEPEER's channel driver supports it.
+
+ * The channel variable DYNAMIC_PEERNAME is redundant with BRIDGEPEER and is
+   removed.  The more useful DYNAMIC_WHO_ACTIVATED gives the channel name that
+   activated the dynamic feature.
+
+ * The channel variables DYNAMIC_FEATURENAME and DYNAMIC_WHO_ACTIVATED are set
+   only on the channel executing the dynamic feature.  Executing a dynamic
+   feature on the bridge peer in a multi-party bridge will execute it on all
+   peers of the activating channel.
+
 Realtime
 ------------------
  * Dynamic realtime tables for SIP Users can now include a 'path' field. This
@@ -240,7 +292,7 @@
    tables can also use the 'supportpath' field to enable Path header support.
 
  * LDAP realtime configurations for SIP Users now have the AstAccountPathSupport
-   objectIdentifier. This maps to the supportpath option in sip.conf. 
+   objectIdentifier. This maps to the supportpath option in sip.conf.
 
 RTP
 ------------------

Modified: team/kmoore/stasis-http_sounds/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-http_sounds/UPGRADE.txt?view=diff&rev=391292&r1=391291&r2=391292
==============================================================================
--- team/kmoore/stasis-http_sounds/UPGRADE.txt (original)
+++ team/kmoore/stasis-http_sounds/UPGRADE.txt Mon Jun 10 14:01:54 2013
@@ -20,7 +20,6 @@
 === UPGRADE-11.txt -- Upgrade info for 10 to 11
 ===
 ===========================================================
-
 
 AMI:
  - The SIP SIPqualifypeer action now sends a response indicating it will qualify
@@ -37,6 +36,11 @@
 CEL:
  - The Uniqueid field for a channel is now a stable identifier, and will not
    change due to transfers, parking, etc.
+
+Core:
+ - The following channel variables have changed behavior which is described in
+   the CHANGES file: TRANSFER_CONTEXT, BRIDGEPEER, BRIDGEPVTCALLID,
+   ATTENDED_TRANSFER_COMPLETE_SOUND, DYNAMIC_FEATURENAME, and DYNAMIC_PEERNAME.
 
 Queues:
  - Queue logging for PAUSEALL/UNPAUSEALL now only occurs if the interface this is
@@ -50,6 +54,11 @@
    Queue member being paused would result in a disposition of BUSY.
  - Removed the queues.conf check_state_unknown option.  It is no longer
    necessary.
+ - It is now possible to play the Queue prompts to the first user waiting in a
+   call queue. Note that this may impact the ability for agents to talk with
+   users, as a prompt may still be playing when an agent connects to the user.
+   This ability is disabled by default but can be enabled on an individual
+   queue using the 'announce-to-first-user' option.
 
 Dial:
  - Now recognizes 'W' to pause sending DTMF for one second in addition to
@@ -86,9 +95,12 @@
 
 Features:
  - The features.conf [applicationmap] <FeatureName>  ActivatedBy option is
-   no longer honored.  The feature is activated by which channel
-   DYNAMIC_FEATURES includes the feature is on.  Use predial to set different
-   values of DYNAMIC_FEATURES on the channels
+   no longer honored.  The feature is always activated by the channel that has
+   DYNAMIC_FEATURES defined on it when it enters the bridge.  Use predial to set
+   different values of DYNAMIC_FEATURES on the channels
+
+ - Executing a dynamic feature on the bridge peer in a multi-party bridge will
+   execute it on all peers of the activating channel.
 
 Parking:
  - The arguments for the Park, ParkedCall, and ParkAndAnnounce applications have

Modified: team/kmoore/stasis-http_sounds/apps/app_bridgewait.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-http_sounds/apps/app_bridgewait.c?view=diff&rev=391292&r1=391291&r2=391292
==============================================================================
--- team/kmoore/stasis-http_sounds/apps/app_bridgewait.c (original)
+++ team/kmoore/stasis-http_sounds/apps/app_bridgewait.c Mon Jun 10 14:01:54 2013
@@ -141,7 +141,7 @@
 
 	/* Limits struct holds time as milliseconds, so muliply 1000x */
 	hold_limits.duration *= 1000;
-	ast_bridge_features_set_limits(features, &hold_limits, 1 /* remove_on_pull */);
+	ast_bridge_features_set_limits(features, &hold_limits, AST_BRIDGE_HOOK_REMOVE_ON_PULL);
 	ast_bridge_features_limits_destroy(&hold_limits);
 
 	return 0;

Modified: team/kmoore/stasis-http_sounds/apps/app_dial.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-http_sounds/apps/app_dial.c?view=diff&rev=391292&r1=391291&r2=391292
==============================================================================
--- team/kmoore/stasis-http_sounds/apps/app_dial.c (original)
+++ team/kmoore/stasis-http_sounds/apps/app_dial.c Mon Jun 10 14:01:54 2013
@@ -69,6 +69,7 @@
 #include "asterisk/dial.h"
 #include "asterisk/stasis_channels.h"
 #include "asterisk/bridging.h"
+#include "asterisk/features_config.h"
 
 /*** DOCUMENTATION
 	<application name="Dial" language="en_US">
@@ -1074,7 +1075,7 @@
 	int caller_entertained = outgoing
 		&& ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
 	struct ast_party_connected_line connected_caller;
-	struct ast_str *featurecode = ast_str_alloca(FEATURE_MAX_LEN + 1);
+	struct ast_str *featurecode = ast_str_alloca(AST_FEATURE_MAX_LEN + 1);
 	int cc_recall_core_id;
 	int is_cc_recall;
 	int cc_frame_received = 0;
@@ -1701,22 +1702,31 @@
 
 static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str **featurecode)
 {
-	struct ast_flags features = { AST_FEATURE_DISCONNECT }; /* only concerned with disconnect feature */
-	struct ast_call_feature feature = { 0, };
+	char disconnect_code[AST_FEATURE_MAX_LEN];
 	int res;
 
 	ast_str_append(featurecode, 1, "%c", code);
 
-	res = ast_feature_detect(chan, &features, ast_str_buffer(*featurecode), &feature);
-
-	if (res != AST_FEATURE_RETURN_STOREDIGITS) {
+	res = ast_get_builtin_feature(chan, "disconnect", disconnect_code, sizeof(disconnect_code));
+	if (res) {
 		ast_str_reset(*featurecode);
-	}
-	if (feature.feature_mask & AST_FEATURE_DISCONNECT) {
-		return 1;
-	}
-
-	return 0;
+		return 0;
+	}
+
+	if (strlen(disconnect_code) > ast_str_strlen(*featurecode)) {
+		/* Could be a partial match, anyway */
+		if (strncmp(disconnect_code, ast_str_buffer(*featurecode), ast_str_strlen(*featurecode))) {
+			ast_str_reset(*featurecode);
+		}
+		return 0;
+	}
+
+	if (strcmp(disconnect_code, ast_str_buffer(*featurecode))) {
+		ast_str_reset(*featurecode);
+		return 0;
+	}
+
+	return 1;
 }
 
 /* returns true if there is a valid privacy reply */

Modified: team/kmoore/stasis-http_sounds/apps/app_meetme.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-http_sounds/apps/app_meetme.c?view=diff&rev=391292&r1=391291&r2=391292
==============================================================================
--- team/kmoore/stasis-http_sounds/apps/app_meetme.c (original)
+++ team/kmoore/stasis-http_sounds/apps/app_meetme.c Mon Jun 10 14:01:54 2013
@@ -73,6 +73,10 @@
 #include "asterisk/paths.h"
 #include "asterisk/data.h"
 #include "asterisk/test.h"
+#include "asterisk/stasis.h"
+#include "asterisk/stasis_channels.h"
+#include "asterisk/stasis_message_router.h"
+#include "asterisk/json.h"
 
 #include "enter.h"
 #include "leave.h"
@@ -553,6 +557,88 @@
 				MeetmeListRoomsComplete.</para>
 		</description>
 	</manager>
+	<managerEvent language="en_US" name="MeetmeJoin">
+		<managerEventInstance class="EVENT_FLAG_CALL">
+			<synopsis>Raised when a user joins a MeetMe conference.</synopsis>
+			<syntax>
+				<parameter name="Meetme">
+					<para>The identifier for the MeetMe conference.</para>
+				</parameter>
+				<parameter name="Usernum">
+					<para>The identifier of the MeetMe user who joined.</para>
+				</parameter>
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
+			</syntax>
+			<see-also>
+				<ref type="managerEvent">MeetmeLeave</ref>
+				<ref type="application">MeetMe</ref>
+			</see-also>
+		</managerEventInstance>
+	</managerEvent>
+	<managerEvent language="en_US" name="MeetmeLeave">
+		<managerEventInstance class="EVENT_FLAG_CALL">
+			<synopsis>Raised when a user leaves a MeetMe conference.</synopsis>
+			<syntax>
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter)" />
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
+				<parameter name="Duration">
+					<para>The length of time in seconds that the Meetme user was in the conference.</para>
+				</parameter>
+			</syntax>
+			<see-also>
+				<ref type="managerEvent">MeetmeJoin</ref>
+			</see-also>
+		</managerEventInstance>
+	</managerEvent>
+	<managerEvent language="en_US" name="MeetmeEnd">
+		<managerEventInstance class="EVENT_FLAG_CALL">
+			<synopsis>Raised when a MeetMe conference ends.</synopsis>
+			<syntax>
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Meetme'])" />
+			</syntax>
+			<see-also>
+				<ref type="managerEvent">MeetmeJoin</ref>
+			</see-also>
+		</managerEventInstance>
+	</managerEvent>
+	<managerEvent language="en_US" name="MeetmeTalkRequest">
+		<managerEventInstance class="EVENT_FLAG_CALL">
+			<synopsis>Raised when a MeetMe user has started talking.</synopsis>
+			<syntax>
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter)" />
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
+				<parameter name="Duration">
+					<para>The length of time in seconds that the Meetme user has been in the conference at the time of this event.</para>
+				</parameter>
+				<parameter name="Status">
+					<enumlist>
+						<enum name="on"/>
+						<enum name="off"/>
+					</enumlist>
+				</parameter>
+			</syntax>
+		</managerEventInstance>
+	</managerEvent>
+	<managerEvent language="en_US" name="MeetmeTalking">
+		<managerEventInstance class="EVENT_FLAG_CALL">
+			<synopsis>Raised when a MeetMe user begins or ends talking.</synopsis>
+			<syntax>
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter)" />
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeTalkRequest']/managerEventInstance/syntax/parameter)" />
+			</syntax>
+		</managerEventInstance>
+	</managerEvent>
+	<managerEvent language="en_US" name="MeetmeMute">
+		<managerEventInstance class="EVENT_FLAG_CALL">
+			<synopsis>Raised when a MeetMe user is muted or unmuted.</synopsis>
+			<syntax>
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter)" />
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
+				<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeTalkRequest']/managerEventInstance/syntax/parameter)" />
+			</syntax>
+		</managerEventInstance>
+	</managerEvent>
  ***/
 
 #define CONFIG_FILE_NAME	"meetme.conf"
@@ -1031,6 +1117,330 @@
 	15,
 };
 
+/*!
+ * \internal
+ * \brief accessor for join message type
+ * \since 12.0.0
+ *
+ * \retval pointer to the stasis message type
+ * \retval NULL if not initialized
+ */
+static struct stasis_message_type *meetme_join_type(void);
+
+/*!
+ * \internal
+ * \brief accessor for leave message type
+ * \since 12.0.0
+ *
+ * \retval pointer to the stasis message type
+ * \retval NULL if not initialized
+ */
+static struct stasis_message_type *meetme_leave_type(void);
+
+/*!
+ * \internal
+ * \brief accessor for end message type
+ * \since 12.0.0
+ *
+ * \retval pointer to the stasis message type
+ * \retval NULL if not initialized
+ */
+static struct stasis_message_type *meetme_end_type(void);
+
+/*!
+ * \internal
+ * \brief accessor for mute message type
+ * \since 12.0.0
+ *
+ * \retval pointer to the stasis message type
+ * \retval NULL if not initialized
+ */
+static struct stasis_message_type *meetme_mute_type(void);
+
+/*!
+ * \internal
+ * \brief accessor for talking message type
+ * \since 12.0.0
+ *
+ * \retval pointer to the stasis message type
+ * \retval NULL if not initialized
+ */
+static struct stasis_message_type *meetme_talking_type(void);
+
+/*!
+ * \internal
+ * \brief accessor for talk request message type
+ * \since 12.0.0
+ *
+ * \retval pointer to the stasis message type
+ * \retval NULL if not initialized
+ */
+static struct stasis_message_type *meetme_talk_request_type(void);
+
+/* Routes the various meetme message types to the meetme stasis callback function to turn them into events */
+static struct stasis_message_router *meetme_event_message_router;
+
+STASIS_MESSAGE_TYPE_DEFN(meetme_join_type);
+STASIS_MESSAGE_TYPE_DEFN(meetme_leave_type);
+STASIS_MESSAGE_TYPE_DEFN(meetme_end_type);
+STASIS_MESSAGE_TYPE_DEFN(meetme_mute_type);
+STASIS_MESSAGE_TYPE_DEFN(meetme_talking_type);
+STASIS_MESSAGE_TYPE_DEFN(meetme_talk_request_type);
+
+static void meetme_stasis_cb(void *data, struct stasis_subscription *sub,
+	struct stasis_topic *topic, struct stasis_message *message);
+
+static void meetme_stasis_cleanup(void)
+{
+	if (meetme_event_message_router) {
+		stasis_message_router_unsubscribe(meetme_event_message_router);
+		meetme_event_message_router = NULL;
+	}
+
+	STASIS_MESSAGE_TYPE_CLEANUP(meetme_join_type);
+	STASIS_MESSAGE_TYPE_CLEANUP(meetme_leave_type);
+	STASIS_MESSAGE_TYPE_CLEANUP(meetme_end_type);
+	STASIS_MESSAGE_TYPE_CLEANUP(meetme_mute_type);
+	STASIS_MESSAGE_TYPE_CLEANUP(meetme_talking_type);
+	STASIS_MESSAGE_TYPE_CLEANUP(meetme_talk_request_type);
+}
+
+static int meetme_stasis_init(void)
+{
+
+	STASIS_MESSAGE_TYPE_INIT(meetme_join_type);
+	STASIS_MESSAGE_TYPE_INIT(meetme_leave_type);
+	STASIS_MESSAGE_TYPE_INIT(meetme_end_type);
+	STASIS_MESSAGE_TYPE_INIT(meetme_mute_type);
+	STASIS_MESSAGE_TYPE_INIT(meetme_talking_type);
+	STASIS_MESSAGE_TYPE_INIT(meetme_talk_request_type);
+
+	meetme_event_message_router = stasis_message_router_create(
+		stasis_caching_get_topic(ast_channel_topic_all_cached()));
+
+	if (!meetme_event_message_router) {
+		meetme_stasis_cleanup();
+		return -1;
+	}
+
+	if (stasis_message_router_add(meetme_event_message_router,
+			meetme_join_type(),
+			meetme_stasis_cb,
+			NULL)) {
+		meetme_stasis_cleanup();
+		return -1;
+	}
+
+	if (stasis_message_router_add(meetme_event_message_router,
+			meetme_leave_type(),
+			meetme_stasis_cb,
+			NULL)) {
+		meetme_stasis_cleanup();
+		return -1;
+	}
+
+	if (stasis_message_router_add(meetme_event_message_router,
+			meetme_end_type(),
+			meetme_stasis_cb,
+			NULL)) {
+		meetme_stasis_cleanup();
+		return -1;
+	}
+
+	if (stasis_message_router_add(meetme_event_message_router,
+			meetme_mute_type(),
+			meetme_stasis_cb,
+			NULL)) {
+		meetme_stasis_cleanup();
+		return -1;
+	}
+
+	if (stasis_message_router_add(meetme_event_message_router,
+			meetme_talking_type(),
+			meetme_stasis_cb,
+			NULL)) {
+		meetme_stasis_cleanup();
+		return -1;
+	}
+
+	if (stasis_message_router_add(meetme_event_message_router,
+			meetme_talk_request_type(),
+			meetme_stasis_cb,
+			NULL)) {
+		meetme_stasis_cleanup();
+		return -1;
+	}
+
+	return 0;
+}
+
+static void meetme_stasis_cb(void *data, struct stasis_subscription *sub,
+	struct stasis_topic *topic, struct stasis_message *message)
+{
+	struct ast_channel_blob *channel_blob = stasis_message_data(message);
+	struct stasis_message_type *message_type;
+	const char *event;
+	const char *conference_num;
+	const char *status;
+	struct ast_json *json_cur;
+	RAII_VAR(struct ast_str *, channel_text, NULL, ast_free);
+	RAII_VAR(struct ast_str *, extra_text, NULL, ast_free);
+
+	if (!channel_blob) {
+		ast_assert(0);
+		return;
+	}
+
+	message_type = stasis_message_type(message);
+
+	if (!message_type) {
+		ast_assert(0);
+		return;
+	}
+
+	if (message_type == meetme_join_type()) {
+		event = "MeetmeJoin";
+	} else if (message_type == meetme_leave_type()) {
+		event = "MeetmeLeave";
+	} else if (message_type == meetme_end_type()) {
+		event = "MeetmeEnd";
+	} else if (message_type == meetme_mute_type()) {
+		event = "MeetmeMute";
+	} else if (message_type == meetme_talking_type()) {
+		event = "MeetmeTalking";
+	} else if (message_type == meetme_talk_request_type()) {
+		event = "MeetmeTalkRequest";
+	} else {
+		ast_assert(0);
+		return;
+	}
+
+	if (!event) {
+		ast_assert(0);
+		return;
+	}
+
+	conference_num = ast_json_string_get(ast_json_object_get(channel_blob->blob, "Meetme"));
+	if (!conference_num) {
+		ast_assert(0);
+		return;
+	}
+
+	status = ast_json_string_get(ast_json_object_get(channel_blob->blob, "status"));
+	if (status) {
+		ast_str_append_event_header(&extra_text, "Status", status);
+	}
+
+	if (channel_blob->snapshot) {
+		channel_text = ast_manager_build_channel_state_string(channel_blob->snapshot);
+	}
+
+	if ((json_cur = ast_json_object_get(channel_blob->blob, "user"))) {
+		int user_number = ast_json_integer_get(json_cur);
+		RAII_VAR(struct ast_str *, user_prop_str, ast_str_create(32), ast_free);
+		if (!user_prop_str) {
+			return;
+		}
+
+		ast_str_set(&user_prop_str, 0, "%d", user_number);
+		ast_str_append_event_header(&extra_text, "User", ast_str_buffer(user_prop_str));
+
+		if ((json_cur = ast_json_object_get(channel_blob->blob, "duration"))) {
+			int duration = ast_json_integer_get(json_cur);
+			ast_str_set(&user_prop_str, 0, "%d", duration);
+			ast_str_append_event_header(&extra_text, "Duration", ast_str_buffer(user_prop_str));
+		}
+
+		json_cur = NULL;
+	}
+
+	manager_event(EVENT_FLAG_CALL, event,
+		"Meetme: %s\r\n"
+		"%s"
+		"%s",
+		conference_num,
+		channel_text ? ast_str_buffer(channel_text) : "",
+		extra_text ? ast_str_buffer(extra_text) : "");
+}
+
+/*!
+ * \internal
+ * \brief Build a json object from a status value for inclusion in json extras for meetme_stasis_generate_msg
+ * \since 12.0.0
+ *
+ * \param on if true, then status is on. Otherwise status is off
+ * \retval NULL on failure to allocate the JSON blob.
+ * \retval pointer to the JSON blob if successful.
+ */
+static struct ast_json *status_to_json(int on)
+{
+	struct ast_json *json_object = ast_json_pack("{s: s}",
+		"status", on ? "on" : "off");
+
+	return json_object;
+}
+
+/*!
+ * \internal
+ * \brief Generate a stasis message associated with a meetme event
+ * \since 12.0.0
+ *
+ * \param meetme_confere The conference responsible for generating this message
+ * \param chan The channel involved in the message (NULL allowed)
+ * \param user The conference user involved in the message (NULL allowed)
+ * \param message_type the type the stasis message being generated
+ * \param extras Additional json fields desired for inclusion
+ */
+static void meetme_stasis_generate_msg(struct ast_conference *meetme_conference, struct ast_channel *chan,
+	struct ast_conf_user *user, struct stasis_message_type *message_type, struct ast_json *extras)
+{
+	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
+
+	json_object = ast_json_pack("{s: s}",
+		"Meetme", meetme_conference->confno);
+
+	if (!json_object) {
+		return;
+	}
+
+	if (extras) {
+		ast_json_object_update(json_object, extras);
+	}
+
+	if (user) {
+		struct timeval now = ast_tvnow();
+		long duration = (long)(now.tv_sec - user->jointime);
+		RAII_VAR(struct ast_json *, json_user, ast_json_integer_create(user->user_no), ast_json_unref);
+		RAII_VAR(struct ast_json *, json_user_duration, NULL, ast_json_unref);
+
+		if (ast_json_object_set(json_object, "user", json_user)) {
+			return;
+		}
+		json_user = NULL;
+
+		if (duration > 0) {
+			json_user_duration = ast_json_integer_create(duration);
+
+			if (!json_user_duration) {
+				return;
+			}
+
+			if (ast_json_object_set(json_object, "duration", json_user_duration)) {
+				return;
+			}
+			json_user_duration = NULL;
+		}
+	}
+
+	msg = ast_channel_blob_create(chan, message_type, json_object);
+
+	if (!msg) {
+		return;
+	}
+
+	stasis_publish(ast_channel_topic(chan), msg);
+}
 
 static int admin_exec(struct ast_channel *chan, const char *data);
 static void *recordthread(void *args);
@@ -1951,20 +2361,10 @@
 {
 	int x;
 	struct announce_listitem *item;
-	
+
 	AST_LIST_REMOVE(&confs, conf, list);
-	/*** DOCUMENTATION
-		<managerEventInstance>
-			<synopsis>Raised when a MeetMe conference ends.</synopsis>
-			<syntax>
-				<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Meetme'])" />
-			</syntax>
-			<see-also>
-				<ref type="managerEvent">MeetmeJoin</ref>
-			</see-also>
-		</managerEventInstance>
-	***/
-	manager_event(EVENT_FLAG_CALL, "MeetmeEnd", "Meetme: %s\r\n", conf->confno);
+
+	meetme_stasis_generate_msg(conf, NULL, NULL, meetme_end_type(), NULL);
 
 	if (conf->recording == MEETME_RECORD_ACTIVE) {
 		conf->recording = MEETME_RECORD_TERMINATE;
@@ -2298,30 +2698,8 @@
 
 static void send_talking_event(struct ast_channel *chan, struct ast_conference *conf, struct ast_conf_user *user, int talking)
 {
-	/*** DOCUMENTATION
-		<managerEventInstance>
-			<synopsis>Raised when a MeetMe user begins or ends talking.</synopsis>
-			<syntax>
-				<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Meetme'])" />
-				<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Usernum'])" />
-				<parameter name="Status">
-					<enumlist>
-						<enum name="on"/>
-						<enum name="off"/>
-					</enumlist>
-				</parameter>
-			</syntax>
-		</managerEventInstance>
-	***/
-	ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeTalking",
-		"Channel: %s\r\n"
-		"Uniqueid: %s\r\n"
-		"Meetme: %s\r\n"
-		"Usernum: %d\r\n"
-		"Status: %s\r\n",
-		ast_channel_name(chan), ast_channel_uniqueid(chan),
-		conf->confno,
-		user->user_no, talking ? "on" : "off");
+	RAII_VAR(struct ast_json *, status_blob, status_to_json(talking), ast_json_unref);
+	meetme_stasis_generate_msg(conf, chan, user, meetme_talking_type(), status_blob);
 }
 
 static void set_user_talking(struct ast_channel *chan, struct ast_conference *conf, struct ast_conf_user *user, int talking, int monitor)
@@ -3335,39 +3713,7 @@
 	ast_debug(1, "Placed channel %s in DAHDI conf %d\n", ast_channel_name(chan), conf->dahdiconf);
 
 	if (!sent_event) {
-		/*** DOCUMENTATION
-			<managerEventInstance>
-				<synopsis>Raised when a user joins a MeetMe conference.</synopsis>
-				<syntax>
-					<parameter name="Meetme">
-						<para>The identifier for the MeetMe conference.</para>
-					</parameter>
-					<parameter name="Usernum">
-						<para>The identifier of the MeetMe user who joined.</para>
-					</parameter>
-				</syntax>
-				<see-also>
-					<ref type="managerEvent">MeetmeLeave</ref>
-					<ref type="application">MeetMe</ref>
-				</see-also>
-			</managerEventInstance>
-		***/
-		ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeJoin",
-			"Channel: %s\r\n"
-			"Uniqueid: %s\r\n"
-			"Meetme: %s\r\n"
-			"Usernum: %d\r\n"
-			"CallerIDnum: %s\r\n"
-			"CallerIDname: %s\r\n"
-			"ConnectedLineNum: %s\r\n"
-			"ConnectedLineName: %s\r\n",
-			ast_channel_name(chan), ast_channel_uniqueid(chan), conf->confno,
-			user->user_no,
-			S_COR(ast_channel_caller(user->chan)->id.number.valid, ast_channel_caller(user->chan)->id.number.str, "<unknown>"),
-			S_COR(ast_channel_caller(user->chan)->id.name.valid, ast_channel_caller(user->chan)->id.name.str, "<unknown>"),
-			S_COR(ast_channel_connected(user->chan)->id.number.valid, ast_channel_connected(user->chan)->id.number.str, "<unknown>"),
-			S_COR(ast_channel_connected(user->chan)->id.name.valid, ast_channel_connected(user->chan)->id.name.str, "<unknown>")
-			);
+		meetme_stasis_generate_msg(conf, chan, user, meetme_join_type(), NULL);
 		sent_event = 1;
 	}
 
@@ -3716,6 +4062,7 @@
 
 			/* If I should be muted but am still talker, mute me */
 			if ((user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) && (dahdic.confmode & DAHDI_CONF_TALKER)) {
+				RAII_VAR(struct ast_json *, status_blob, status_to_json(1), ast_json_unref);
 				dahdic.confmode ^= DAHDI_CONF_TALKER;
 				if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
 					ast_log(LOG_WARNING, "Error setting conference - Un/Mute \n");
@@ -3727,95 +4074,34 @@
 				if (ast_test_flag64(confflags,  (CONFFLAG_MONITORTALKER | CONFFLAG_OPTIMIZETALKER))) {
 					set_user_talking(chan, conf, user, -1, ast_test_flag64(confflags, CONFFLAG_MONITORTALKER));
 				}
-				/*** DOCUMENTATION
-				<managerEventInstance>
-					<synopsis>Raised when a MeetMe user is muted.</synopsis>
-					<syntax>
-						<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Meetme'])" />
-						<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Usernum'])" />
-						<parameter name="Status">
-							<enumlist>
-								<enum name="on"/>
-								<enum name="off"/>
-							</enumlist>
-						</parameter>
-					</syntax>
-				</managerEventInstance>
-				***/
-				ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeMute",
-					"Channel: %s\r\n"
-					"Uniqueid: %s\r\n"
-					"Meetme: %s\r\n"
-					"Usernum: %d\r\n"
-					"Status: on\r\n",
-					ast_channel_name(chan), ast_channel_uniqueid(chan), conf->confno, user->user_no);
+				meetme_stasis_generate_msg(conf, chan, user, meetme_mute_type(), status_blob);
 			}
 
 			/* If I should be un-muted but am not talker, un-mute me */
 			if (!(user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) && !ast_test_flag64(confflags, CONFFLAG_MONITOR) && !(dahdic.confmode & DAHDI_CONF_TALKER)) {
+				RAII_VAR(struct ast_json *, status_blob, status_to_json(0), ast_json_unref);
 				dahdic.confmode |= DAHDI_CONF_TALKER;
 				if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
 					ast_log(LOG_WARNING, "Error setting conference - Un/Mute \n");
 					ret = -1;
 					break;
 				}
-				/*** DOCUMENTATION
-				<managerEventInstance>
-					<synopsis>Raised when a MeetMe user is unmuted.</synopsis>
-				</managerEventInstance>
-				***/
-				ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeMute",
-					"Channel: %s\r\n"
-					"Uniqueid: %s\r\n"
-					"Meetme: %s\r\n"
-					"Usernum: %d\r\n"
-					"Status: off\r\n",
-					ast_channel_name(chan), ast_channel_uniqueid(chan), conf->confno, user->user_no);
-			}
-			
+				meetme_stasis_generate_msg(conf, chan, user, meetme_mute_type(), status_blob);
+			}
+
 			if ((user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) && 
 				(user->adminflags & ADMINFLAG_T_REQUEST) && !(talkreq_manager)) {
+
+				RAII_VAR(struct ast_json *, status_blob, status_to_json(1), ast_json_unref);
 				talkreq_manager = 1;
-
-				/*** DOCUMENTATION
-				<managerEventInstance>
-					<synopsis>Raised when a MeetMe user has started talking.</synopsis>
-					<syntax>
-						<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Meetme'])" />
-						<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Usernum'])" />
-						<parameter name="Status">
-							<enumlist>
-								<enum name="on"/>
-								<enum name="off"/>
-							</enumlist>
-						</parameter>
-					</syntax>
-				</managerEventInstance>
-				***/
-				ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeTalkRequest",
-					"Channel: %s\r\n"
-					"Uniqueid: %s\r\n"
-					"Meetme: %s\r\n"
-					"Usernum: %d\r\n"
-					"Status: on\r\n",
-					ast_channel_name(chan), ast_channel_uniqueid(chan), conf->confno, user->user_no);
+				meetme_stasis_generate_msg(conf, chan, user, meetme_talk_request_type(), status_blob);
 			}
 
 			if (!(user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) && 
 				!(user->adminflags & ADMINFLAG_T_REQUEST) && (talkreq_manager)) {
+				RAII_VAR(struct ast_json *, status_blob, status_to_json(0), ast_json_unref);
 				talkreq_manager = 0;
-				/*** DOCUMENTATION
-				<managerEventInstance>
-					<synopsis>Raised when a MeetMe user has finished talking.</synopsis>
-				</managerEventInstance>
-				***/
-				ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeTalkRequest",
-					"Channel: %s\r\n"
-					"Uniqueid: %s\r\n"
-					"Meetme: %s\r\n"
-					"Usernum: %d\r\n"
-					"Status: off\r\n",
-					ast_channel_name(chan), ast_channel_uniqueid(chan), conf->confno, user->user_no);
+				meetme_stasis_generate_msg(conf, chan, user, meetme_talk_request_type(), status_blob);
 			}
 
 			/* If user have been hung up, exit the conference */
@@ -4169,38 +4455,7 @@
 		now = ast_tvnow();
 
 		if (sent_event) {
-			/*** DOCUMENTATION
-			<managerEventInstance>
-				<synopsis>Raised when a user leaves a MeetMe conference.</synopsis>
-				<syntax>
-					<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Meetme'])" />
-					<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Usernum'])" />
-					<parameter name="Duration">
-						<para>The length of time in seconds that the Meetme user was in the conference.</para>
-					</parameter>
-				</syntax>
-				<see-also>
-					<ref type="managerEvent">MeetmeJoin</ref>
-				</see-also>
-			</managerEventInstance>
-			***/
-			ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeLeave",
-				"Channel: %s\r\n"
-				"Uniqueid: %s\r\n"
-				"Meetme: %s\r\n"
-				"Usernum: %d\r\n"
-				"CallerIDNum: %s\r\n"
-				"CallerIDName: %s\r\n"
-				"ConnectedLineNum: %s\r\n"

[... 12676 lines stripped ...]



More information about the asterisk-commits mailing list