aboutsummaryrefslogtreecommitdiffstats
path: root/channels/chan_zap.c
diff options
context:
space:
mode:
authorjdixon <jdixon@f38db490-d61c-443f-a65b-d21fe96a405b>2006-04-22 11:30:06 +0000
committerjdixon <jdixon@f38db490-d61c-443f-a65b-d21fe96a405b>2006-04-22 11:30:06 +0000
commitc4e93002d617efd3568354cd4020191cfd79de52 (patch)
tree7ae4c12bf61dba4c0d883eda9942c18b6f356ab3 /channels/chan_zap.c
parenta139aad1f4ed15064e16e31605b65f8f995d01d3 (diff)
Added "Operator Services" connection mode for Zap channels, and the 'O' option
in app_dial to support the use of this mode. git-svn-id: http://svn.digium.com/svn/asterisk/trunk@22128 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_zap.c')
-rw-r--r--channels/chan_zap.c92
1 files changed, 78 insertions, 14 deletions
diff --git a/channels/chan_zap.c b/channels/chan_zap.c
index c7341d29c..13d26e545 100644
--- a/channels/chan_zap.c
+++ b/channels/chan_zap.c
@@ -543,6 +543,8 @@ static struct zt_pvt {
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 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
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 @@ static int zt_hangup(struct ast_channel *ast)
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 @@ static int zt_hangup(struct ast_channel *ast)
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 @@ static int zt_answer(struct ast_channel *ast)
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 @@ static int zt_setoption(struct ast_channel *chan, int option, void *data, int da
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)) {
@@ -2939,6 +2944,22 @@ static int zt_setoption(struct ast_channel *chan, int option, void *data, int da
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 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
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;
@@ -3760,6 +3781,19 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
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) {
case SIG_FXOLS:
case SIG_FXOGS:
@@ -3869,11 +3903,23 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
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 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
#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 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
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 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
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 @@ static struct ast_frame *__zt_exception(struct ast_channel *ast)
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 @@ static struct ast_frame *__zt_exception(struct ast_channel *ast)
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 @@ struct ast_frame *zt_read(struct ast_channel *ast)
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 @@ struct ast_frame *zt_read(struct ast_channel *ast)
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 @@ static inline int available(struct zt_pvt *p, int channelmatch, int groupmatch,
return 1;
}
#endif
- if (!p->radio)
+ if (!(p->radio || (p->oprmode < 0)))
{
if (!p->sig || (p->sig == SIG_FXSLS))
return 1;