[svn-commits] trunk r22128 - in /trunk: apps/ channels/ include/asterisk/

svn-commits at lists.digium.com svn-commits at lists.digium.com
Sat Apr 22 04:30:07 MST 2006


Author: jdixon
Date: Sat Apr 22 06:30:06 2006
New Revision: 22128

URL: http://svn.digium.com/view/asterisk?rev=22128&view=rev
Log:
Added "Operator Services" connection mode for Zap channels, and the 'O' option
in app_dial to support the use of this mode.

Modified:
    trunk/apps/app_dial.c
    trunk/channels/chan_zap.c
    trunk/include/asterisk/frame.h

Modified: trunk/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_dial.c?rev=22128&r1=22127&r2=22128&view=diff
==============================================================================
--- trunk/apps/app_dial.c (original)
+++ trunk/apps/app_dial.c Sat Apr 22 06:30:06 2006
@@ -154,6 +154,16 @@
 "    o    - Specify that the CallerID that was present on the *calling* channel\n"
 "           be set as the CallerID on the *called* channel. This was the\n"
 "           behavior of Asterisk 1.0 and earlier.\n"
+"    O([x]) - \"Operator Services\" mode (Zaptel channel to Zaptel channel\n"
+"             only, if specified on non-Zaptel interface, it will be ignored).\n"
+"             When the destination answers (presumably an operator services\n"
+"             station), the originator no longer has control of their line.\n"
+"             They may hang up, but the switch will not release their line\n"
+"             until the destination party hangs up (the operator). Specified\n"
+"             without an arg, or with 1 as an arg, the originator hanging up\n"
+"             will cause the phone to ring back immediately. With a 2 specified,\n"
+"             when the \"operator\" flashes the trunk, it will ring their phone\n"
+"             back.\n"
 "    p    - This option enables screening mode. This is basically Privacy mode\n"
 "           without memory.\n"
 "    P([x]) - Enable privacy mode. Use 'x' as the family/key in the database if\n"
@@ -213,6 +223,7 @@
 	OPT_CALLEE_MONITOR =	(1 << 21),
 	OPT_CALLER_MONITOR =	(1 << 22),
 	OPT_GOTO =		(1 << 23),
+	OPT_OPERMODE = 		(1 << 24),
 } dial_exec_option_flags;
 
 #define DIAL_STILLGOING			(1 << 30)
@@ -227,6 +238,7 @@
 	OPT_ARG_CALLEE_MACRO,
 	OPT_ARG_PRIVACY,
 	OPT_ARG_DURATION_STOP,
+	OPT_ARG_OPERMODE,
 	/* note: this entry _MUST_ be the last one in the enum */
 	OPT_ARG_ARRAY_SIZE,
 } dial_exec_option_args;
@@ -247,6 +259,7 @@
 	AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
 	AST_APP_OPTION('n', OPT_SCREEN_NOINTRO),
 	AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
+	AST_APP_OPTION_ARG('O', OPT_OPERMODE,OPT_ARG_OPERMODE),
 	AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
 	AST_APP_OPTION('p', OPT_SCREENING),
 	AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
@@ -744,6 +757,7 @@
 	char privintro[1024];
 	char privcid[256];
 	char *parse;
+	int opermode = 0;
 	AST_DECLARE_APP_ARGS(args,
 			     AST_APP_ARG(peers);
 			     AST_APP_ARG(timeout);
@@ -772,6 +786,14 @@
 	if (ast_strlen_zero(args.peers)) {
 		ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
 		goto done;
+	}
+
+	if (ast_test_flag(&opts, OPT_OPERMODE)) {
+		if (ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]))
+			opermode = 1;
+		else opermode = atoi(opt_args[OPT_ARG_OPERMODE]);
+		if (option_verbose > 2)
+			ast_verbose(VERBOSE_PREFIX_3 "Setting operator services mode to %d.\n", opermode);
 	}
 
 	if (ast_test_flag(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
@@ -1483,6 +1505,17 @@
 				res = -1;
 				goto done;
 			}
+			if (opermode && (!strncmp(chan->name,"Zap",3)) &&
+				(!strncmp(peer->name,"Zap",3)))
+			{
+				struct oprmode oprmode;
+
+				oprmode.peer = peer;
+				oprmode.mode = opermode;
+
+				ast_channel_setoption(chan,
+					AST_OPTION_OPRMODE,&oprmode,sizeof(struct oprmode),0);
+			}
 			res = ast_bridge_call(chan,peer,&config);
 			time(&end_time);
 			{

Modified: trunk/channels/chan_zap.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_zap.c?rev=22128&r1=22127&r2=22128&view=diff
==============================================================================
--- trunk/channels/chan_zap.c (original)
+++ trunk/channels/chan_zap.c Sat Apr 22 06:30:06 2006
@@ -543,6 +543,8 @@
 	int sig;					/*!< Signalling style */
 	int radio;					/*!< radio type */
 	int outsigmod;					/*!< Outbound Signalling style (modifier) */
+	int oprmode;					/*!< "Operator Services" mode */
+	struct zt_pvt *oprpeer;				/*!< "Operator Services" peer tech_pvt ptr */
 	float rxgain;
 	float txgain;
 	int tonezone;					/*!< tone zone for this chan, or -1 for default */
@@ -1771,7 +1773,7 @@
 		return -1;
 	}
 	p->dialednone = 0;
-	if (p->radio)  /* if a radio channel, up immediately */
+	if ((p->radio || (p->oprmode < 0)))  /* if a radio channel, up immediately */
 	{
 		/* Special pseudo -- automatically up */
 		ast_setstate(ast, AST_STATE_UP); 
@@ -2616,7 +2618,7 @@
 				ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
 #endif
 				/* If they're off hook, try playing congestion */
-				if ((par.rxisoffhook) && (!p->radio))
+				if ((par.rxisoffhook) && (!(p->radio || (p->oprmode < 0))))
 					tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
 				else
 					tone_zone_play_tone(p->subs[SUB_REAL].zfd, -1);
@@ -2676,6 +2678,7 @@
 
 	p->callwaitingrepeat = 0;
 	p->cidcwexpire = 0;
+	p->oprmode = 0;
 	ast->tech_pvt = NULL;
 	ast_mutex_unlock(&p->lock);
 	ast_mutex_lock(&usecnt_lock);
@@ -2717,7 +2720,7 @@
 	if (index < 0)
 		index = SUB_REAL;
 	/* nothing to do if a radio channel */
-	if (p->radio) {
+	if ((p->radio || (p->oprmode < 0))) {
 		ast_mutex_unlock(&p->lock);
 		return 0;
 	}
@@ -2803,7 +2806,9 @@
 	signed char *scp;
 	int x;
 	int index;
-	struct zt_pvt *p = chan->tech_pvt;
+	struct zt_pvt *p = chan->tech_pvt,*pp;
+	struct oprmode *oprmode;
+	
 
 	/* all supported options require data */
 	if (!data || (datalen < 1)) {
@@ -2938,6 +2943,22 @@
 		}
 		if (ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x) == -1)
 			ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x);
+		break;
+	case AST_OPTION_OPRMODE:  /* Operator services mode */
+		oprmode = (struct oprmode *) data;
+		pp = oprmode->peer->tech_pvt;
+		p->oprmode = pp->oprmode = 0;
+		/* setup peers */
+		p->oprpeer = pp;
+		pp->oprpeer = p;
+		/* setup modes, if any */
+		if (oprmode->mode) 
+		{
+			pp->oprmode = oprmode->mode;
+			p->oprmode = -oprmode->mode;
+		}
+		ast_log(LOG_DEBUG, "Set Operator Services mode, value: %d on %s/%s\n",
+			oprmode->mode, chan->name,oprmode->peer->name);;
 		break;
 	}
 	errno = 0;
@@ -3685,7 +3706,7 @@
 			break;	
 		case ZT_EVENT_DIALCOMPLETE:
 			if (p->inalarm) break;
-			if (p->radio) break;
+			if ((p->radio || (p->oprmode < 0))) break;
 			if (ioctl(p->subs[index].zfd,ZT_DIALING,&x) == -1) {
 				ast_log(LOG_DEBUG, "ZT_DIALING ioctl failed on %s\n",ast->name);
 				return NULL;
@@ -3758,6 +3779,19 @@
 			if (p->radio) {
 				p->subs[index].f.frametype = AST_FRAME_CONTROL;
 				p->subs[index].f.subclass = AST_CONTROL_RADIO_UNKEY;
+				break;
+			}
+			if (p->oprmode < 0)
+			{
+				if (p->oprmode != -1) break;
+				if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
+				{
+					/* Make sure it starts ringing */
+					zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
+					zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RING);
+					save_conference(p->oprpeer);
+					tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
+				}
 				break;
 			}
 			switch(p->sig) {
@@ -3869,11 +3903,23 @@
 			break;
 		case ZT_EVENT_RINGOFFHOOK:
 			if (p->inalarm) break;
-			if (p->radio) {
+			if (p->oprmode < 0)
+			{
+				if ((p->sig == SIG_FXOLS) || (p->sig == SIG_FXOKS) || (p->sig == SIG_FXOGS))
+				{
+					/* Make sure it stops ringing */
+					zt_set_hook(p->subs[SUB_REAL].zfd, ZT_RINGOFF);
+					tone_zone_play_tone(p->oprpeer->subs[SUB_REAL].zfd, -1);
+					restore_conference(p->oprpeer);
+				}
+				break;
+			}
+			if (p->radio)
+			{
 				p->subs[index].f.frametype = AST_FRAME_CONTROL;
 				p->subs[index].f.subclass = AST_CONTROL_RADIO_KEY;
 				break;
-			}
+ 			}
 			/* for E911, its supposed to wait for offhook then dial
 			   the second half of the dial string */
 			if (((mysig == SIG_E911) || (mysig == SIG_FGC_CAMA) || (mysig == SIG_FGC_CAMAMF)) && (ast->_state == AST_STATE_DIALING_OFFHOOK)) {
@@ -4038,7 +4084,7 @@
 #endif			
 		case ZT_EVENT_RINGEROFF:
 			if (p->inalarm) break;
-			if (p->radio) break;
+			if ((p->radio || (p->oprmode < 0))) break;
 			ast->rings++;
 			if ((ast->rings > p->cidrings) && (p->cidspill)) {
 				ast_log(LOG_WARNING, "Didn't finish Caller-ID spill.  Cancelling.\n");
@@ -4065,6 +4111,24 @@
 		case ZT_EVENT_WINKFLASH:
 			if (p->inalarm) break;
 			if (p->radio) break;
+			if (p->oprmode < 0) break;
+			if (p->oprmode > 1)
+			{
+				struct zt_params par;
+
+				if (ioctl(p->oprpeer->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &par) != -1)
+				{
+					if (!par.rxisoffhook)
+					{
+						/* Make sure it stops ringing */
+						zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RINGOFF);
+						zt_set_hook(p->oprpeer->subs[SUB_REAL].zfd, ZT_RING);
+						save_conference(p);
+						tone_zone_play_tone(p->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE);
+					}
+				}
+				break;
+			}
 			/* Remember last time we got a flash-hook */
 			gettimeofday(&p->flashtime, NULL);
 			switch(mysig) {
@@ -4267,7 +4331,7 @@
 			break;
 		case ZT_EVENT_HOOKCOMPLETE:
 			if (p->inalarm) break;
-			if (p->radio) break;
+			if ((p->radio || (p->oprmode < 0))) break;
 			switch(mysig) {
 			case SIG_FXSLS:  /* only interesting for FXS */
 			case SIG_FXSGS:
@@ -4375,7 +4439,7 @@
 	p->subs[index].f.data = NULL;
 	
 	
-	if ((!p->owner) && (!p->radio)) {
+	if ((!p->owner) && (!(p->radio || (p->oprmode < 0)))) {
 		/* If nobody owns us, absorb the event appropriately, otherwise
 		   we loop indefinitely.  This occurs when, during call waiting, the
 		   other end hangs up our channel so that it no longer exists, but we
@@ -4446,7 +4510,7 @@
 		f = &p->subs[index].f;
 		return f;
 	}
-	if (!p->radio) ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
+	if (!(p->radio || (p->oprmode < 0))) ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
 	/* If it's not us, return NULL immediately */
 	if (ast != p->owner) {
 		ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
@@ -4487,7 +4551,7 @@
 		return NULL;
 	}
 	
-	if (p->radio && p->inalarm) return NULL;
+	if ((p->radio || (p->oprmode < 0)) && p->inalarm) return NULL;
 
 	p->subs[index].f.frametype = AST_FRAME_NULL;
 	p->subs[index].f.datalen = 0;
@@ -4500,7 +4564,7 @@
 	p->subs[index].f.data = NULL;
 	
 	/* make sure it sends initial key state as first frame */
-	if (p->radio && (!p->firstradio))
+	if ((p->radio || (p->oprmode < 0)) && (!p->firstradio))
 	{
 		ZT_PARAMS ps;
 
@@ -7539,7 +7603,7 @@
 				return 1;
 		}
 #endif
-		if (!p->radio)
+		if (!(p->radio || (p->oprmode < 0)))
 		{
 			if (!p->sig || (p->sig == SIG_FXSLS))
 				return 1;

Modified: trunk/include/asterisk/frame.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/frame.h?rev=22128&r1=22127&r2=22128&view=diff
==============================================================================
--- trunk/include/asterisk/frame.h (original)
+++ trunk/include/asterisk/frame.h Sat Apr 22 06:30:06 2006
@@ -321,6 +321,14 @@
 */
 #define AST_OPTION_RXGAIN		6
 
+/* set channel into "Operator Services" mode */
+#define	AST_OPTION_OPRMODE		7
+
+struct oprmode {
+	struct ast_channel *peer;
+	int mode;
+} ;
+
 struct ast_option_header {
 	/* Always keep in network byte order */
 #if __BYTE_ORDER == __BIG_ENDIAN



More information about the svn-commits mailing list