[asterisk-commits] russell: branch 1.4 r120671 - in /branches/1.4: doc/smdi.txt res/res_smdi.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jun 5 11:38:53 CDT 2008


Author: russell
Date: Thu Jun  5 11:38:52 2008
New Revision: 120671

URL: http://svn.digium.com/view/asterisk?view=rev&rev=120671
Log:
It turns out that searching on the forwarding station isn't very useful for
most people, so pull in the changes that allow searching for SMDI messages
based on other components of the SMDI message.  Also, update the SMDI
documentation.

Modified:
    branches/1.4/doc/smdi.txt
    branches/1.4/res/res_smdi.c

Modified: branches/1.4/doc/smdi.txt
URL: http://svn.digium.com/view/asterisk/branches/1.4/doc/smdi.txt?view=diff&rev=120671&r1=120670&r2=120671
==============================================================================
--- branches/1.4/doc/smdi.txt (original)
+++ branches/1.4/doc/smdi.txt Thu Jun  5 11:38:52 2008
@@ -1,25 +1,137 @@
-Asterisk SMDI (Simple Message Desk Interface) integration
----------------------------------------------------------
+===============================================================================
+===============================================================================
+=== Asterisk SMDI (Simple Message Desk Interface) integration =================
+===============================================================================
+===============================================================================
 
-SMDI integration is configured in smdi.conf, zaptel.conf, and voicemail.conf.
-Various characteristics of the SMDI interfaces to be used (serial ports) are
-defined in smdi.conf.  SMDI integration for callerid and MWI are defined in
-zaptel.conf and voicemail.conf respectively. SMDI only works with Zaptel
-interfaces configured for FXS signalling.
+===============================================================================
+===== 1) Accessing SMDI information in the dialplan. ==========================
+===============================================================================
 
-When SMDI is enabled and a call comes into Asterisk, the forwarding station
-number is used as the destination for the call and any callerid information
-present is used.  This way you can configure your extensions.conf as follows to
-behave as a message desk.
+There are two dialplan functions that can be used to access the details of
+incoming SMDI messages.
 
-[default]
+*CLI> core show function SMDI_MSG_RETRIEVE
 
-exten => _XXXXXXX,1,VoiceMail(${EXTEN}|${SMDI_VM_TYPE})
-exten => _XXXXXXX,n,Hangup
+  -= Info about function 'SMDI_MSG_RETRIEVE' =- 
 
-exten => s,1,VoiceMailMain(${CALLERID(num)})
-exten => s,n,Hangup
+[Syntax]
+SMDI_MSG_RETRIEVE(<smdi port>,<search key>[,timeout[,options]])
 
-The ${SMDI_VM_TYPE} variable will be set to u, b, or nothing depending on the
-contents of the type of SMDI message received.
+[Synopsis]
+Retrieve an SMDI message.
 
+[Description]
+   This function is used to retrieve an incoming SMDI message.  It returns
+an ID which can be used with the SMDI_MSG() function to access details of
+the message.  Note that this is a destructive function in the sense that
+once an SMDI message is retrieved using this function, it is no longer in
+the global SMDI message queue, and can not be accessed by any other Asterisk
+channels.  The timeout for this function is optional, and the default is
+3 seconds.  When providing a timeout, it should be in milliseconds.
+   The default search is done on the forwarding station ID.  However, if
+you set one of the search key options in the options field, you can change
+this behavior.
+   Options:
+     t - Instead of searching on the forwarding station, search on the message
+         desk terminal.
+     n - Instead of searching on the forwarding station, search on the message
+         desk number.
+
+
+*CLI> core show function SMDI_MSG
+
+  -= Info about function 'SMDI_MSG' =-
+
+[Syntax]
+SMDI_MSG(<message_id>,<component>)
+
+[Synopsis]
+Retrieve details about an SMDI message.
+
+[Description]
+   This function is used to access details of an SMDI message that was
+pulled from the incoming SMDI message queue using the SMDI_MSG_RETRIEVE()
+function.
+   Valid message components are:
+      station  - The forwarding station
+      callerid - The callerID of the calling party that was forwarded
+      type     - The call type.  The value here is the exact character
+                 that came in on the SMDI link.  Typically, example values
+                 are: D - Direct Calls, A - Forward All Calls,
+                      B - Forward Busy Calls, N - Forward No Answer Calls
+
+
+Here is an example of how to use these functions:
+
+; Retrieve the SMDI message that is associated with the number that
+; was called in Asterisk.
+exten => _0XXX,1,Set(SMDI_MSG_ID=${SMDI_MSG_RETRIEVE(/dev/tty0,${EXTEN})})
+
+; Ensure that the message was retrieved.
+exten => _0XXX,n,GotoIf($["x${SMDI_MSG_ID}" != "x"]?processcall:hangup)
+exten => _0XXX,n(hangup),NoOp(No SMDI message retrieved for ${EXTEN})
+
+; Grab the details out of the SMDI message.
+exten => _0XXX,n(processcall),NoOp(Message found for ${EXTEN})
+exten => _0XXX,n,Set(SMDI_EXTEN=${SMDI_MSG(${SMDI_MSG_ID},station)})
+exten => _0XXX,n,Set(SMDI_CID=${SMDI_MSG(${SMDI_MSG_ID},callerid)})
+
+; Map SMDI message types to the right voicemail option.  If it is "B", use the
+; busy option.  Otherwise, use the unavailable option.
+exten => _0XXX,n,GotoIf($["${SMDI_MSG(${SMDI_MSG_ID},type)}" == "B"]?usebusy:useunavail)
+
+exten => _0XXX,n(usebusy),Set(SMDI_VM_TYPE=b)
+exten => _0XXX,n,Goto(continue)
+
+exten => _0XXX,n,(useunavil),Set(SMDI_VM_TYPE=u)
+
+exten => _0XXX,n(continue),NoOp( Process the rest of the call ... )
+
+
+===============================================================================
+===== 2) Ensuring complete MWI information over SMDI ==========================
+===============================================================================
+
+Another change has been made to ensure that MWI state is properly propagated
+over the SMDI link.  This replaces the use of externnotify=smdi for
+voicemail.conf.  The issue is that we have to poll mailboxes occasionally for
+changes that were made using an IMAP client.  So, this ability was added to
+res_smdi.  To configure this, there is a new section in smdi.conf.  It looks
+like this:
+
+[mailboxes]
+; This section configures parameters related to MWI handling for the SMDI link.
+ ;
+; This option configures the polling interval used to check to see if the
+; mailboxes have any new messages.  This option is specified in seconds.
+; The default value is 10 seconds.
+;
+;pollinginterval=10
+;
+; Before specifying mailboxes, you must specify an SMDI interface.  All mailbox
+; definitions that follow will correspond to that SMDI interface.  If you
+; specify another interface, then all definitions following that will correspond
+; to the new interface.
+;
+; Every other entry in this section of the configuration file is interpreted as
+; a mapping between the mailbox ID on the SMDI link, and the local Asterisk
+; mailbox name.  In many cases, they are the same thing, but they still must be
+; listed here so that this module knows which mailboxes it needs to pay
+; attention to.
+;
+; Syntax:
+;   <SMDI mailbox ID>=<Asterisk Mailbox Name>[@Asterisk Voicemail Context]
+;
+; If no Asterisk voicemail context is specified, "default" will be assumed.
+;
+;
+;smdiport=/dev/ttyS0
+;2565551234=1234 at vmcontext1
+;2565555678=5678 at vmcontext2
+;smdiport=/dev/ttyS1
+;2565559999=9999
+
+===============================================================================
+===============================================================================
+===============================================================================

Modified: branches/1.4/res/res_smdi.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/res/res_smdi.c?view=diff&rev=120671&r1=120670&r2=120671
==============================================================================
--- branches/1.4/res/res_smdi.c (original)
+++ branches/1.4/res/res_smdi.c Thu Jun  5 11:38:52 2008
@@ -369,8 +369,13 @@
 	return msg;
 }
 
+enum {
+	OPT_SEARCH_TERMINAL = (1 << 0),
+	OPT_SEARCH_NUMBER   = (1 << 1),
+};
+
 static void *smdi_msg_find(struct ast_smdi_interface *iface,
-	enum smdi_message_type type, const char *station)
+	enum smdi_message_type type, const char *search_key, struct ast_flags options)
 {
 	void *msg = NULL;
 
@@ -378,10 +383,35 @@
 
 	switch (type) {
 	case SMDI_MD:
-		msg = ASTOBJ_CONTAINER_FIND(&iface->md_q, station);
+		if (ast_test_flag(&options, OPT_SEARCH_TERMINAL)) {
+			struct ast_smdi_md_message *md_msg = NULL;
+
+			/* Searching by the message desk terminal */
+
+			ASTOBJ_CONTAINER_TRAVERSE(&iface->md_q, !md_msg, do {
+				if (!strcasecmp(iterator->mesg_desk_term, search_key))
+					md_msg = ASTOBJ_REF(iterator);
+			} while (0); );
+
+			msg = md_msg;
+		} else if (ast_test_flag(&options, OPT_SEARCH_NUMBER)) {
+			struct ast_smdi_md_message *md_msg = NULL;
+
+			/* Searching by the message desk number */
+
+			ASTOBJ_CONTAINER_TRAVERSE(&iface->md_q, !md_msg, do {
+				if (!strcasecmp(iterator->mesg_desk_num, search_key))
+					md_msg = ASTOBJ_REF(iterator);
+			} while (0); );
+
+			msg = md_msg;
+		} else {
+			/* Searching by the forwarding station */
+			msg = ASTOBJ_CONTAINER_FIND(&iface->md_q, search_key);
+		}
 		break;
 	case SMDI_MWI:
-		msg = ASTOBJ_CONTAINER_FIND(&iface->mwi_q, station);
+		msg = ASTOBJ_CONTAINER_FIND(&iface->mwi_q, search_key);
 		break;
 	}
 
@@ -389,7 +419,7 @@
 }
 
 static void *smdi_message_wait(struct ast_smdi_interface *iface, int timeout, 
-	enum smdi_message_type type, const char *station)
+	enum smdi_message_type type, const char *search_key, struct ast_flags options)
 {
 	struct timeval start;
 	long diff = 0;
@@ -415,7 +445,7 @@
 
 		lock_msg_q(iface, type);
 
-		if ((msg = smdi_msg_find(iface, type, station))) {
+		if ((msg = smdi_msg_find(iface, type, search_key, options))) {
 			unlock_msg_q(iface, type);
 			return msg;
 		}
@@ -429,7 +459,7 @@
 
 		ast_cond_timedwait(cond, lock, &ts);
 
-		if ((msg = smdi_msg_find(iface, type, station))) {
+		if ((msg = smdi_msg_find(iface, type, search_key, options))) {
 			unlock_msg_q(iface, type);
 			return msg;
 		}
@@ -450,7 +480,8 @@
 
 struct ast_smdi_md_message *ast_smdi_md_message_wait(struct ast_smdi_interface *iface, int timeout)
 {
-	return smdi_message_wait(iface, timeout, SMDI_MD, NULL);
+	struct ast_flags options = { 0 };
+	return smdi_message_wait(iface, timeout, SMDI_MD, NULL, options);
 }
 
 struct ast_smdi_mwi_message *ast_smdi_mwi_message_pop(struct ast_smdi_interface *iface)
@@ -460,13 +491,15 @@
 
 struct ast_smdi_mwi_message *ast_smdi_mwi_message_wait(struct ast_smdi_interface *iface, int timeout)
 {
-	return smdi_message_wait(iface, timeout, SMDI_MWI, NULL);
+	struct ast_flags options = { 0 };
+	return smdi_message_wait(iface, timeout, SMDI_MWI, NULL, options);
 }
 
 struct ast_smdi_mwi_message *ast_smdi_mwi_message_wait_station(struct ast_smdi_interface *iface, int timeout,
 	const char *station)
 {
-	return smdi_message_wait(iface, timeout, SMDI_MWI, station);
+	struct ast_flags options = { 0 };
+	return smdi_message_wait(iface, timeout, SMDI_MWI, station, options);
 }
 
 struct ast_smdi_interface *ast_smdi_interface_find(const char *iface_name)
@@ -1059,14 +1092,21 @@
 /*! In milliseconds */
 #define SMDI_RETRIEVE_TIMEOUT_DEFAULT 3000
 
+AST_APP_OPTIONS(smdi_msg_ret_options, BEGIN_OPTIONS
+	AST_APP_OPTION('t', OPT_SEARCH_TERMINAL),
+	AST_APP_OPTION('n', OPT_SEARCH_NUMBER),
+END_OPTIONS );
+
 static int smdi_msg_retrieve_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 {
 	struct ast_module_user *u;
 	AST_DECLARE_APP_ARGS(args,
 		AST_APP_ARG(port);
-		AST_APP_ARG(station);
+		AST_APP_ARG(search_key);
 		AST_APP_ARG(timeout);
+		AST_APP_ARG(options);
 	);
+	struct ast_flags options = { 0 };
 	unsigned int timeout = SMDI_RETRIEVE_TIMEOUT_DEFAULT;
 	int res = -1;
 	char *parse = NULL;
@@ -1092,7 +1132,7 @@
 	parse = ast_strdupa(data);
 	AST_STANDARD_APP_ARGS(args, parse);
 
-	if (ast_strlen_zero(args.port) || ast_strlen_zero(args.station)) {
+	if (ast_strlen_zero(args.port) || ast_strlen_zero(args.search_key)) {
 		ast_log(LOG_ERROR, "Invalid arguments provided to SMDI_MSG_RETRIEVE\n");
 		goto return_error;
 	}
@@ -1100,6 +1140,10 @@
 	if (!(iface = ast_smdi_interface_find(args.port))) {
 		ast_log(LOG_ERROR, "SMDI port '%s' not found\n", args.port);
 		goto return_error;
+	}
+
+	if (!ast_strlen_zero(args.options)) {
+		ast_app_parse_options(smdi_msg_ret_options, &options, NULL, args.options);
 	}
 
 	if (!ast_strlen_zero(args.timeout)) {
@@ -1109,9 +1153,9 @@
 		}
 	}
 
-	if (!(md_msg = smdi_message_wait(iface, timeout, SMDI_MD, args.station))) {
-		ast_log(LOG_WARNING, "No SMDI message retrieved for station '%s' after "
-			"waiting %u ms.\n", args.station, timeout);
+	if (!(md_msg = smdi_message_wait(iface, timeout, SMDI_MD, args.search_key, options))) {
+		ast_log(LOG_WARNING, "No SMDI message retrieved for search key '%s' after "
+			"waiting %u ms.\n", args.search_key, timeout);
 		goto return_error;
 	}
 
@@ -1200,7 +1244,11 @@
 
 	smd = datastore->data;
 
-	if (!strcasecmp(args.component, "station")) {
+	if (!strcasecmp(args.component, "number")) {
+		ast_copy_string(buf, smd->md_msg->mesg_desk_num, len);
+	} else if (!strcasecmp(args.component, "terminal")) {
+		ast_copy_string(buf, smd->md_msg->mesg_desk_term, len);
+	} else if (!strcasecmp(args.component, "station")) {
 		ast_copy_string(buf, smd->md_msg->fwd_st, len);
 	} else if (!strcasecmp(args.component, "callerid")) {
 		ast_copy_string(buf, smd->md_msg->calling_st, len);
@@ -1223,7 +1271,7 @@
 static struct ast_custom_function smdi_msg_retrieve_function = {
 	.name = "SMDI_MSG_RETRIEVE",
 	.synopsis = "Retrieve an SMDI message.",
-	.syntax = "SMDI_MSG_RETRIEVE(<smdi port>,<station>[,timeout])",
+	.syntax = "SMDI_MSG_RETRIEVE(<smdi port>,<search key>[,timeout[,options]])",
 	.desc = 
 	"   This function is used to retrieve an incoming SMDI message.  It returns\n"
 	"an ID which can be used with the SMDI_MSG() function to access details of\n"
@@ -1232,6 +1280,14 @@
 	"the global SMDI message queue, and can not be accessed by any other Asterisk\n"
 	"channels.  The timeout for this function is optional, and the default is\n"
 	"3 seconds.  When providing a timeout, it should be in milliseconds.\n"
+	"   The default search is done on the forwarding station ID.  However, if\n"
+	"you set one of the search key options in the options field, you can change\n"
+	"this behavior.\n"
+	"   Options:\n"
+	"     t - Instead of searching on the forwarding station, search on the message\n"
+	"         desk terminal.\n"
+	"     n - Instead of searching on the forwarding station, search on the message\n"
+	"         desk number.\n"
 	"",
 	.read = smdi_msg_retrieve_read,
 };
@@ -1245,6 +1301,8 @@
 	"pulled from the incoming SMDI message queue using the SMDI_MSG_RETRIEVE()\n"
 	"function.\n"
 	"   Valid message components are:\n"
+	"      number   - The message desk number\n"
+	"      terminal - The message desk terminal\n"
 	"      station  - The forwarding station\n"
 	"      callerid - The callerID of the calling party that was forwarded\n"
 	"      type     - The call type.  The value here is the exact character\n"




More information about the asterisk-commits mailing list