Index: channel.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channel.c,v
retrieving revision 1.174
diff -u -r1.174 channel.c
--- channel.c	28 Feb 2005 06:06:42 -0000	1.174
+++ channel.c	2 Mar 2005 10:47:31 -0000
@@ -40,6 +40,7 @@
 #include <asterisk/utils.h>
 #include <asterisk/lock.h>
 #include <asterisk/app.h>
+#include <libpri.h>
 #ifdef ZAPTEL_OPTIMIZATIONS
 #include <sys/ioctl.h>
 #ifdef __linux__
@@ -260,6 +261,25 @@
 	}
 }
 
+char *ast_transfercapability2str(int transfercapability)
+{
+	switch(transfercapability) {
+	case PRI_TRANS_CAP_SPEECH:
+		return "SPEECH";
+	case PRI_TRANS_CAP_DIGITAL:
+		return "DIGITAL";
+	case PRI_TRANS_CAP_RESTRICTED_DIGITAL:
+		return "RESTRICTED_DIGITAL";
+	case PRI_TRANS_CAP_3_1K_AUDIO:
+		return "3K1AUDIO";
+	case PRI_TRANS_CAP_DIGITAL_W_TONES:
+		return "DIGITAL_W_TONES";
+	case PRI_TRANS_CAP_VIDEO:
+		return "VIDEO";
+	default:
+		return "UNKNOWN";
+	}
+}
 
 int ast_best_codec(int fmts)
 {
Index: apps/Makefile
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/Makefile,v
retrieving revision 1.93
diff -u -r1.93 Makefile
--- apps/Makefile	27 Feb 2005 19:07:46 -0000	1.93
+++ apps/Makefile	2 Mar 2005 10:47:32 -0000
@@ -31,7 +31,7 @@
      app_talkdetect.so app_alarmreceiver.so app_userevent.so app_verbose.so \
      app_test.so app_forkcdr.so app_math.so app_realtime.so \
      app_dumpchan.so app_waitforsilence.so app_while.so app_setrdnis.so \
-     app_md5.so app_readfile.so
+     app_md5.so app_readfile.so app_settransfercapability.so
 
 ifneq (${OSARCH},Darwin)
 ifneq (${OSARCH},SunOS)
Index: apps/app_dial.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_dial.c,v
retrieving revision 1.142
diff -u -r1.142 app_dial.c
--- apps/app_dial.c	28 Feb 2005 06:06:42 -0000	1.142
+++ apps/app_dial.c	2 Mar 2005 10:47:32 -0000
@@ -77,8 +77,8 @@
 "      'r' -- indicate ringing to the calling party, pass no audio until answered.\n"
 "      'm[(class)]' -- provide hold music to the calling party until answered (optionally\n"
 "                      with the specified class.\n"
-"      'M(x[^arg]) -- Executes the macro (x with ^ delim arg list) upon connect of the call.\n"
-"                     Also, the macro can set the MACRO_RESULT variable to do the following:\n"
+"      'M(x[^arg])' -- Executes the macro (x with ^ delim arg list) upon connect of the call.\n"
+"                      Also, the macro can set the MACRO_RESULT variable to do the following:\n"
 "                     -- ABORT - Hangup both legs of the call.\n"
 "                     -- CONGESTION - Behave as if line congestion was encountered.\n"
 "                     -- BUSY - Behave as if a busy signal was encountered. (n+101)\n"
@@ -1015,8 +1015,10 @@
 		tmp->chan->cid.cid_tns = chan->cid.cid_tns;
 		/* Presense of ADSI CPE on outgoing channel follows ours */
 		tmp->chan->adsicpe = chan->adsicpe;
-		/* pass the digital flag */
+		/* Pass the digital flag */
 		ast_copy_flags(tmp->chan, chan, AST_FLAG_DIGITAL);
+		/* Pass the transfer capability */
+		tmp->chan->transfercapability = chan->transfercapability;
 
 		/* If we have an outbound group, set this peer channel to it */
 		if (outbound_group)
Index: channels/chan_zap.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_zap.c,v
retrieving revision 1.410
diff -u -r1.410 chan_zap.c
--- channels/chan_zap.c	28 Feb 2005 00:18:28 -0000	1.410
+++ channels/chan_zap.c	2 Mar 2005 10:47:37 -0000
@@ -1818,12 +1818,14 @@
 				ast_log(LOG_DEBUG, "I'm being setup with no bearer right now...\n");
 			pri_set_crv(p->pri->pri, p->call, p->channel, 0);
 		}
-		p->digital = ast_test_flag(ast,AST_FLAG_DIGITAL);
 		pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), 
 								p->pri->nodetype == PRI_NETWORK ? 0 : 1, 1);
-		pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : PRI_TRANS_CAP_SPEECH, 
+		p->digital = ast_test_flag(ast,AST_FLAG_DIGITAL);
+		pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, 
 					(p->digital ? -1 : 
 						((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)));
+		if (option_verbose > 2)
+			ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability));
 		pri_sr_set_called(sr, c + p->stripmsd, p->pri->dialplan - 1,  s ? 1 : 0);
 		pri_sr_set_caller(sr, l, n, p->pri->localdialplan - 1, 
 					l ? (p->use_callingpres ? ast->cid.cid_pres : PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN) : 
@@ -3911,7 +3913,7 @@
 	return f;
 }
 
-struct ast_frame  *zt_read(struct ast_channel *ast)
+struct ast_frame *zt_read(struct ast_channel *ast)
 {
 	struct zt_pvt *p = ast->pvt->pvt;
 	int res;
@@ -4510,35 +4512,7 @@
 	return res;
 }
 
-#ifdef ZAPATA_PRI
-static void set_calltype(struct ast_channel *chan, int ctype)
-{
-	char *s = "UNKNOWN";
-	switch(ctype) {
-	case PRI_TRANS_CAP_SPEECH:
-		s = "SPEECH";
-		break;
-	case PRI_TRANS_CAP_DIGITAL:
-		s = "DIGITAL";
-		break;
-	case PRI_TRANS_CAP_RESTRICTED_DIGITAL:
-		s = "RESTRICTED_DIGITAL";
-		break;
-	case PRI_TRANS_CAP_3_1K_AUDIO:
-		s = "31KAUDIO";
-		break;
-	case PRI_TRANS_CAP_7K_AUDIO:
-		s = "7KAUDIO";
-		break;
-	case PRI_TRANS_CAP_VIDEO:
-		s = "VIDEO";
-		break;
-	}
-	pbx_builtin_setvar_helper(chan, "CALLTYPE", s);
-}
-#endif
-
-static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int index, int law, int ctype)
+static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int index, int law, int transfercapability)
 {
 	struct ast_channel *tmp;
 	int deflaw;
@@ -4681,14 +4655,15 @@
 		tmp->cid.cid_pres = i->callingpres;
 		tmp->cid.cid_ton = i->cid_ton;
 #ifdef ZAPATA_PRI
-		set_calltype(tmp, ctype);
-		/* Assume calls are not idle calls unless we're told differently */
-		i->isidlecall = 0;
-		i->alreadyhungup = 0;
-		if (ctype & PRI_TRANS_CAP_DIGITAL) {
+		tmp->transfercapability = transfercapability;
+		pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability));
+		if (transfercapability & PRI_TRANS_CAP_DIGITAL) {
 			i->digital = 1;
 			ast_set_flag(tmp, AST_FLAG_DIGITAL);
 		}
+		/* Assume calls are not idle calls unless we're told differently */
+		i->isidlecall = 0;
+		i->alreadyhungup = 0;
 #endif
 		/* clear the fake event in case we posted one before we had ast_chanenl */
 		i->fake_event = 0;
@@ -10103,7 +10078,7 @@
 	ast_manager_register( "ZapDialOffhook", 0, action_zapdialoffhook, "Dial over Zap channel while offhook" );
     ast_manager_register( "ZapDNDon", 0, action_zapdndon, "Toggle Zap channel Do Not Disturb status ON" );
     ast_manager_register( "ZapDNDoff", 0, action_zapdndoff, "Toggle Zap channel Do Not Disturb status OFF" );
-	ast_manager_register("ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels");
+	ast_manager_register( "ZapShowChannels", 0, action_zapshowchannels, "Show status zapata channels");
 
 	return res;
 }
Index: include/asterisk/channel.h
===================================================================
RCS file: /usr/cvsroot/asterisk/include/asterisk/channel.h,v
retrieving revision 1.75
diff -u -r1.75 channel.h
--- include/asterisk/channel.h	23 Feb 2005 22:48:47 -0000	1.75
+++ include/asterisk/channel.h	2 Mar 2005 10:47:38 -0000
@@ -219,6 +219,9 @@
 	/*! channel flags of AST_FLAG_ type */
 	unsigned int flags;
 	
+	/* ISDN Transfer Capability - AST_FLAG_DIGITAL is simply not enough */
+	unsigned short transfercapability;
+	
 	/*! For easy linking */
 	struct ast_channel *next;
 
@@ -330,6 +333,8 @@
 #define AST_DEVICE_INVALID	4
 /*! Device is unavailable */
 #define AST_DEVICE_UNAVAILABLE	5
+/*! Device is ringing */
+#define AST_DEVICE_RINGING	6
 
 /*! Requests a channel */
 /*! 
@@ -686,6 +691,11 @@
  * Returns the text form of the binary state given
  */
 char *ast_state2str(int state);
+
+
+/*! Return the string from a given transfercapability */
+char *ast_transfercapability2str(int transfercapability);
+
 
 /* Options: Some low-level drivers may implement "options" allowing fine tuning of the
    low level channel.  See frame.h for options.  Note that many channel drivers may support
Index: apps/app_settransfercapability.c
===================================================================
RCS file: apps/app_settransfercapability.c
diff -N apps/app_settransfercapability.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ apps/app_settransfercapability.c	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,114 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * App to set the ISDN Transfer Capability
+ * 
+ * Copyright (C) 2005, Frank Sautter, levigo holding gmbh, www.levigo.de
+ *
+ * Frank Sautter - asterisk+at+sautter+dot+com 
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License
+ */
+ 
+#include <asterisk/logger.h>
+#include <asterisk/channel.h>
+#include <asterisk/pbx.h>
+#include <asterisk/module.h>
+#include <asterisk/options.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libpri.h>
+
+
+static char *app = "SetTransferCapability";
+
+static char *synopsis = "Set ISDN Transfer Capability";
+
+STANDARD_LOCAL_USER;
+
+LOCAL_USER_DECL;
+
+static struct {	int val; char *name; } transcaps[] = {
+	{ PRI_TRANS_CAP_SPEECH,				"SPEECH" },
+	{ PRI_TRANS_CAP_DIGITAL,			"DIGITAL" },
+	{ PRI_TRANS_CAP_RESTRICTED_DIGITAL,	"RESTRICTED_DIGITAL" },
+	{ PRI_TRANS_CAP_3_1K_AUDIO,			"3K1AUDIO" },
+	{ PRI_TRANS_CAP_DIGITAL_W_TONES,	"DIGITAL_W_TONES" },
+	{ PRI_TRANS_CAP_VIDEO,				"VIDEO" },
+};
+
+static char *descrip = 
+"  SetTransferCapability(transfercapability): Set the ISDN Transfer \n"
+"Capability of a call to a new value.\n"
+"Always returns 0.  Valid Transfer Capabilities are:\n"
+"\n"
+"  SPEECH             : 0x00 - Speech (default, voice calls)\n"
+"  DIGITAL            : 0x08 - Unrestricted digital information (data calls)\n"
+"  RESTRICTED_DIGITAL : 0x09 - Restricted digital information\n"
+"  3K1AUDIO           : 0x10 - 3.1kHz Audio (fax calls)\n"
+"  DIGITAL_W_TONES    : 0x11 - Unrestricted digital information with tones/announcements\n"
+"  VIDEO              : 0x18 - Video:\n"
+"\n"
+;
+
+static int settransfercapability_exec(struct ast_channel *chan, void *data)
+{
+	char tmp[256] = "";
+	struct localuser *u;
+	int x;
+	char *opts;
+	int transfercapability = -1;
+	
+	if (data)
+		strncpy(tmp, (char *)data, sizeof(tmp) - 1);
+	opts = strchr(tmp, '|');
+	if (opts)
+		*opts = '\0';
+	for (x=0;x<sizeof(transcaps) / sizeof(transcaps[0]);x++) {
+		if (!strcasecmp(transcaps[x].name, tmp)) {
+			transfercapability = transcaps[x].val;
+			break;
+		}
+	}
+	if (transfercapability < 0) {
+		ast_log(LOG_WARNING, "'%s' is not a valid transfer capability (see 'show application SetTransferCapability')\n", tmp);
+		return 0;
+	} else {
+		LOCAL_USER_ADD(u);
+		chan->transfercapability = (unsigned short)transfercapability;
+		LOCAL_USER_REMOVE(u);
+		if (option_verbose > 2)
+			ast_verbose(VERBOSE_PREFIX_3 "Setting transfer capability to: 0x%.2x - %s.\n", transfercapability, tmp);			
+		return 0;
+	}
+}
+
+
+int unload_module(void)
+{
+	STANDARD_HANGUP_LOCALUSERS;
+	return ast_unregister_application(app);
+}
+
+int load_module(void)
+{
+	return ast_register_application(app, settransfercapability_exec, synopsis, descrip);
+}
+
+char *description(void)
+{
+	return descrip;
+}
+
+int usecount(void)
+{
+	int res;
+	STANDARD_USECOUNT(res);
+	return res;
+}
+
+char *key()
+{
+	return ASTERISK_GPL_KEY;
+}
