[asterisk-commits] tzafrir: trunk r269238 - in /trunk: ./ channels/ configs/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jun 9 08:17:47 CDT 2010


Author: tzafrir
Date: Wed Jun  9 08:17:43 2010
New Revision: 269238

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=269238
Log:
dial by name in chan_dahdi

* chan_dahdi supports dialing configuring and dialing by device file name.
  DAHDI/span-name!local!1 will use /dev/dahdi/span-name/local/1 . Likewise
  it may appear in chan_dahdi.conf as 'channel => span-name!local!1'.
* A new options for chan_dahdi.conf: 'ignore_failed_channels'. Boolean.
  False by default. If set, chan_dahdi will ignore failed 'channel' entries.
  Handy for the above name-based syntax as it does not depend on
  initialization order.
* have my_pri_make_cc_dialstring() only manupulate dial-strings of group
  (gGrR) dialing, which make it lsightly more complicated.

https://reviewboard.asterisk.org/r/535/

Modified:
    trunk/CHANGES
    trunk/channels/chan_dahdi.c
    trunk/configs/chan_dahdi.conf.sample

Modified: trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/trunk/CHANGES?view=diff&rev=269238&r1=269237&r2=269238
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Wed Jun  9 08:17:43 2010
@@ -485,6 +485,13 @@
    of dynamic parkinglots.
  * chan_dahdi now supports reporting alarms over AMI either by channel or span via
    the reportalarms config option.
+ * chan_dahdi supports dialing configuring and dialing by device file name.
+   DAHDI/span-name!local!1 will use /dev/dahdi/span-name/local/1 . Likewise
+   it may appear in chan_dahdi.conf as 'channel => span-name!local!1'.
+ * A new options for chan_dahdi.conf: 'ignore_failed_channels'. Boolean.
+   False by default. If set, chan_dahdi will ignore failed 'channel' entries.
+   Handy for the above name-based syntax as it does not depend on
+   initialization order.
  * The Realtime dialplan switch now caches entries for 1 second.  This provides a
    significant increase in performance (about 3X) for installations using this switchtype.
 

Modified: trunk/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_dahdi.c?view=diff&rev=269238&r1=269237&r2=269238
==============================================================================
--- trunk/channels/chan_dahdi.c (original)
+++ trunk/channels/chan_dahdi.c Wed Jun  9 08:17:43 2010
@@ -1240,6 +1240,8 @@
 #endif
 	struct dahdi_params timing;
 	int is_sig_auto; /*!< Use channel signalling from DAHDI? */
+	/*! Continue configuration even if a channel is not there. */
+	int ignore_failed_channels;
 
 	/*!
 	 * \brief The serial port to listen for SMDI data on
@@ -2900,14 +2902,12 @@
  *
  * \details
  * original dialstring:
- * DAHDI/[i<span>-]<channel#>[c|r<cadance#>|d][/extension[/options]]
  * DAHDI/[i<span>-](g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]
  *
  * The modified dialstring will have prefixed the channel-group section
  * with the ISDN channel restriction.
  *
  * buf:
- * DAHDI/i<span>-<channel#>[c|r<cadance#>|d][/extension[/options]]
  * DAHDI/i<span>-(g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]
  *
  * The routine will check to see if the ISDN channel restriction is already
@@ -2939,8 +2939,9 @@
 		snprintf(buf, buf_size, "%s/i%d-", args.tech, pvt->pri->span);
 		return;
 	}
-	if (args.group[0] == 'i') {
-		/* The ISDN span channel restriction is already in the dialstring. */
+	if (isdigit(args.group[0]) || args.group[0] == 'i' || strchr(args.group, '!')) {
+		/* The ISDN span channel restriction is not needed or already
+		 * in the dialstring. */
 		ast_copy_string(buf, pvt->dialstring, buf_size);
 		return;
 	}
@@ -11508,6 +11509,38 @@
 
 /*!
  * \internal
+ * \brief Get file name and channel number from (subdir,number)
+ *
+ * \param subdir name of the subdirectory under /dev/dahdi/
+ * \param channel name of device file under /dev/dahdi/<subdir>/
+ * \param path buffer to put file name in
+ * \param pathlen maximal length of path
+ *
+ * \retval minor number of dahdi channel.
+ * \retval -errno on error.
+ */
+static int device2chan(const char *subdir, int channel, char *path, int pathlen)
+{
+	struct stat	stbuf;
+	int		num;
+
+	snprintf(path, pathlen, "/dev/dahdi/%s/%d", subdir, channel);
+	if (stat(path, &stbuf) < 0) {
+		ast_log(LOG_ERROR, "stat(%s) failed: %s\n", path, strerror(errno));
+		return -errno;
+	}
+	if (!S_ISCHR(stbuf.st_mode)) {
+		ast_log(LOG_ERROR, "%s: Not a character device file\n", path);
+		return -EINVAL;
+	}
+	num = minor(stbuf.st_rdev);
+	ast_log(LOG_DEBUG, "%s -> %d\n", path, num);
+	return num;
+
+}
+
+/*!
+ * \internal
  * \brief Initialize/create a channel interface.
  *
  * \param channel Channel interface number to initialize/create.
@@ -12686,6 +12719,7 @@
 	int x;
 	int res = 0;
 	struct dahdi_pvt *p;
+	char *subdir = NULL;
 	AST_DECLARE_APP_ARGS(args,
 		AST_APP_ARG(group);	/* channel/group token */
 		//AST_APP_ARG(ext);	/* extension token */
@@ -12696,8 +12730,9 @@
 	/*
 	 * data is ---v
 	 * Dial(DAHDI/pseudo[/extension[/options]])
-	 * Dial(DAHDI/[i<span>-]<channel#>[c|r<cadance#>|d][/extension[/options]])
+	 * Dial(DAHDI/<channel#>[c|r<cadance#>|d][/extension[/options]])
 	 * Dial(DAHDI/[i<span>-](g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]])
+	 * Dial(DAHDI/<subdir>!<channel#>[c|r<cadance#>|d][/extension[/options]])
 	 *
 	 * i - ISDN span channel restriction.
 	 *     Used by CC to ensure that the CC recall goes out the same span.
@@ -12728,7 +12763,16 @@
 	memset(param, 0, sizeof(*param));
 	param->channelmatch = -1;
 
-	if (args.group[0] == 'i') {
+	if (strchr(args.group, '!') != NULL) {
+		char *prev = args.group;
+		while ((s = strchr(prev, '!')) != NULL) {
+			*s++ = '/';
+			prev = s;
+		}
+		*(prev - 1) = '\0';
+		subdir = args.group;
+		args.group = prev;
+	} else if (args.group[0] == 'i') {
 		/* Extract the ISDN span channel restriction specifier. */
 		res = sscanf(args.group + 1, "%30d", &x);
 		if (res < 1) {
@@ -12795,6 +12839,24 @@
 			} else {
 				param->channelmatch = x;
 			}
+		}
+		if (subdir) {
+			char path[PATH_MAX];
+			struct stat stbuf;
+
+			snprintf(path, sizeof(path), "/dev/dahdi/%s/%d",
+					subdir, param->channelmatch);
+			if (stat(path, &stbuf) < 0) {
+				ast_log(LOG_WARNING, "stat(%s) failed: %s\n",
+						path, strerror(errno));
+				return NULL;
+			}
+			if (!S_ISCHR(stbuf.st_mode)) {
+				ast_log(LOG_ERROR, "%s: Not a character device file\n",
+						path);
+				return NULL;
+			}
+			param->channelmatch = minor(stbuf.st_rdev);
 		}
 
 		p = iflist;
@@ -15807,9 +15869,33 @@
 	return __unload_module();
 }
 
+static void string_replace(char *str, int char1, int char2)
+{
+	for (; *str; str++) {
+		if (*str == char1) {
+			*str = char2;
+		}
+	}
+}
+
+static char *parse_spanchan(char *chanstr, char **subdir)
+{
+	char *p;
+
+	if ((p = strrchr(chanstr, '!')) == NULL) {
+		*subdir = NULL;
+		return chanstr;
+	}
+	*p++ = '\0';
+	string_replace(chanstr, '!', '/');
+	*subdir = chanstr;
+	return p;
+}
+
 static int build_channels(struct dahdi_chan_conf *conf, const char *value, int reload, int lineno, int *found_pseudo)
 {
 	char *c, *chan;
+	char *subdir;
 	int x, start, finish;
 	struct dahdi_pvt *tmp;
 
@@ -15819,6 +15905,7 @@
 	}
 
 	c = ast_strdupa(value);
+	c = parse_spanchan(c, &subdir);
 
 	while ((chan = strsep(&c, ","))) {
 		if (sscanf(chan, "%30d-%30d", &start, &finish) == 2) {
@@ -15842,13 +15929,30 @@
 		}
 
 		for (x = start; x <= finish; x++) {
-			tmp = mkintf(x, conf, reload);
+			char fn[PATH_MAX];
+			int real_channel = x;
+
+			if (!ast_strlen_zero(subdir)) {
+				real_channel = device2chan(subdir, x, fn, sizeof(fn));
+				if (real_channel < 0) {
+					if (conf->ignore_failed_channels) {
+						ast_log(LOG_WARNING, "Failed configuring %s!%d, (got %d). But moving on to others.\n",
+								subdir, x, real_channel);
+						continue;
+					} else {
+						ast_log(LOG_ERROR, "Failed configuring %s!%d, (got %d).\n",
+								subdir, x, real_channel);
+						return -1;
+					}
+				}
+			}
+			tmp = mkintf(real_channel, conf, reload);
 
 			if (tmp) {
-				ast_verb(3, "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", x, sig2str(tmp->sig));
+				ast_verb(3, "%s channel %d, %s signalling\n", reload ? "Reconfigured" : "Registered", real_channel, sig2str(tmp->sig));
 			} else {
 				ast_log(LOG_ERROR, "Unable to %s channel '%s'\n",
-					(reload == 1) ? "reconfigure" : "register", value);
+						(reload == 1) ? "reconfigure" : "register", value);
 				return -1;
 			}
 		}
@@ -15939,9 +16043,17 @@
 				ast_log(LOG_WARNING, "Channel '%s' ignored.\n", v->value);
  				continue;
 			}
- 			if (build_channels(confp, v->value, reload, v->lineno, &found_pseudo))
+			if (build_channels(confp, v->value, reload, v->lineno, &found_pseudo)) {
+				if (confp->ignore_failed_channels) {
+					ast_log(LOG_WARNING, "Channel '%s' failure ignored: ignore_failed_channels.\n", v->value);
+					continue;
+				} else {
  					return -1;
+				}
+			}
 			ast_log(LOG_DEBUG, "Channel '%s' configured.\n", v->value);
+		} else if (!strcasecmp(v->name, "ignore_failed_channels")) {
+			confp->ignore_failed_channels = ast_true(v->value);
 		} else if (!strcasecmp(v->name, "buffers")) {
 			if (parse_buffers_policy(v->value, &confp->chan.buf_no, &confp->chan.buf_policy)) {
 				ast_log(LOG_WARNING, "Using default buffer policy.\n");

Modified: trunk/configs/chan_dahdi.conf.sample
URL: http://svnview.digium.com/svn/asterisk/trunk/configs/chan_dahdi.conf.sample?view=diff&rev=269238&r1=269237&r2=269238
==============================================================================
--- trunk/configs/chan_dahdi.conf.sample (original)
+++ trunk/configs/chan_dahdi.conf.sample Wed Jun  9 08:17:43 2010
@@ -915,6 +915,15 @@
 ;minunused=2
 ;minidle=1
 ;
+;
+; ignore_failed_channels: Continue even if some channels failed to configure.
+; False by default, as if even a single channel failed to configure, it might
+; mean other channels are misplaced and having them work may not be a good
+; idea. If enabled (set to true), chan_dahdi will nevertheless attempt to
+; configure other channels rather than giving up. This normally makes sense
+; only if you use names (<subdir>!<number>) for DAHDI channels.
+;ignore_failed_channels = true
+;
 ; Configure jitter buffers in DAHDI (each one is 20ms, default is 4)
 ; This is set globally, rather than per-channel.
 ;
@@ -1027,8 +1036,24 @@
 ; signalling = pri_cpe
 ; group = 2
 ; channel => 1-23
-
-;
+;
+; Alternatively, the number of the channel may be replaced with a relative
+; path to a device file under /dev/dahdi . The final element of that file
+; must be a number, though. The directory separator is '!', as we can't
+; use '/' in a dial string. So if we have
+;
+;   /dev/dahdi/span-name/pstn/00/1
+;   /dev/dahdi/span-name/pstn/00/2
+;   /dev/dahdi/span-name/pstn/00/3
+;   /dev/dahdi/span-name/pstn/00/4
+;
+; we could use:
+;channel => span-name!pstn!00!1-4
+;
+; or:
+;channel => span-name!pstn!00!1,2,3,4
+;
+; See also ignore_failed_channels above.
 
 ;  Used for distinctive ring support for x100p.
 ;  You can see the dringX patterns is to set any one of the dringXcontext fields




More information about the asterisk-commits mailing list