summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorMatthew Fredrickson <creslin@digium.com>2006-10-27 17:46:04 +0000
committerMatthew Fredrickson <creslin@digium.com>2006-10-27 17:46:04 +0000
commitead98e2b7f8b25cce8e44e79c74ddb57eeb24238 (patch)
treeb26ecb3005dae2ca20d7944c259deccf4a8d5490 /channels
parent12a966cb0eebe8373f998f8c580086577c35047e (diff)
First pass at implementation to be able to block and unblock zap channels for
use. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@46366 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_zap.c81
1 files changed, 63 insertions, 18 deletions
diff --git a/channels/chan_zap.c b/channels/chan_zap.c
index 2f2d660ca..2425c7508 100644
--- a/channels/chan_zap.c
+++ b/channels/chan_zap.c
@@ -635,6 +635,10 @@ static struct zt_pvt {
unsigned int usedistinctiveringdetection:1;
unsigned int zaptrcallerid:1; /*!< should we use the callerid from incoming call on zap transfer or not */
unsigned int transfertobusy:1; /*!< allow flash-transfers to busy channels */
+ /* Channel state or unavilability flags */
+ unsigned int inservice:1;
+ unsigned int locallyblocked:1;
+ unsigned int remotelyblocked:1;
#if defined(HAVE_PRI)
unsigned int alerting:1;
unsigned int alreadyhungup:1;
@@ -644,9 +648,6 @@ static struct zt_pvt {
unsigned int resetting:1;
unsigned int setup_ack:1;
#endif
-#if defined(HAVE_SS7)
- unsigned int blocked:1;
-#endif
unsigned int use_smdi:1; /* Whether to use SMDI on this channel */
struct ast_smdi_interface *smdi_iface; /* The serial port to listen for SMDI data on */
@@ -7840,7 +7841,13 @@ static struct zt_pvt *mkintf(int channel, int signalling, int outsignalling, int
tmp->answeronpolarityswitch = answeronpolarityswitch;
tmp->hanguponpolarityswitch = hanguponpolarityswitch;
tmp->sendcalleridafter = sendcalleridafter;
-
+ if (!here) {
+ tmp->locallyblocked = tmp->remotelyblocked = 0;
+ if ((signalling == SIG_PRI) || (signalling == SIG_SS7))
+ tmp->inservice = 0;
+ else /* We default to in service on protocols that don't have a reset */
+ tmp->inservice = 1;
+ }
}
if (tmp && !here) {
/* nothing on the iflist */
@@ -7917,6 +7924,9 @@ static inline int available(struct zt_pvt *p, int channelmatch, int groupmatch,
/* If guard time, definitely not */
if (p->guardtime && (time(NULL) < p->guardtime))
return 0;
+
+ if (p->locallyblocked || p->remotelyblocked || !p->inservice)
+ return 0;
/* If no owner definitely available */
if (!p->owner) {
@@ -7930,9 +7940,9 @@ static inline int available(struct zt_pvt *p, int channelmatch, int groupmatch,
}
#endif
#ifdef HAVE_SS7
- /* Trust PRI */
+ /* Trust SS7 */
if (p->ss7) {
- if (p->ss7call || p->blocked)
+ if (p->ss7call)
return 0;
else
return 1;
@@ -8312,13 +8322,23 @@ static inline void ss7_block_cics(struct zt_ss7 *linkset, int startcic, int endc
if (linkset->pvts[i] && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic))) {
if (state) {
if (state[i])
- linkset->pvts[i]->blocked = block;
+ linkset->pvts[i]->remotelyblocked = block;
} else
- linkset->pvts[i]->blocked = block;
+ linkset->pvts[i]->remotelyblocked = block;
}
}
}
+static void ss7_inservice(struct zt_ss7 *linkset, int startcic, int endcic)
+{
+ int i;
+
+ for (i = 0; i < linkset->numchans; i++) {
+ if (linkset->pvts[i] && (linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic))
+ linkset->pvts[i]->inservice = 1;
+ }
+}
+
static int ss7_reset_linkset(struct zt_ss7 *linkset)
{
int i, startcic = -1, endcic;
@@ -8333,7 +8353,7 @@ static int ss7_reset_linkset(struct zt_ss7 *linkset)
continue;
} else {
endcic = linkset->pvts[i]->cic;
- ast_verbose(VERBOSE_PREFIX_3 "Resetting CICs %d to %d\n", startcic, endcic);
+ ast_verbose("Resetting CICs %d to %d\n", startcic, endcic);
isup_grs(linkset->ss7, startcic, endcic);
if (linkset->pvts[i+1])
@@ -8530,7 +8550,10 @@ static void *ss7_linkset(void *data)
break;
}
p = linkset->pvts[chanpos];
- p->blocked = 0;
+ ast_mutex_lock(&p->lock);
+ p->inservice = 1;
+ p->remotelyblocked = 0;
+ ast_mutex_unlock(&p->lock);
isup_rlc(ss7, e->rsc.call);
break;
case ISUP_EVENT_GRS:
@@ -8539,7 +8562,8 @@ static void *ss7_linkset(void *data)
ss7_block_cics(linkset, e->grs.startcic, e->grs.endcic, NULL, 0);
break;
case ISUP_EVENT_GRA:
- ast_log(LOG_DEBUG, "Got GRA from CIC %d to %d.\n", e->gra.startcic, e->gra.endcic);
+ ast_verbose("Got reset acknowledgement from CIC %d to %d.\n", e->gra.startcic, e->gra.endcic);
+ ss7_inservice(linkset, e->gra.startcic, e->gra.endcic);
ss7_block_cics(linkset, e->gra.startcic, e->gra.endcic, e->gra.status, 1);
break;
case ISUP_EVENT_IAM:
@@ -8670,7 +8694,7 @@ static void *ss7_linkset(void *data)
}
p = linkset->pvts[chanpos];
ast_log(LOG_DEBUG, "Blocking CIC %d\n", e->blo.cic);
- p->blocked = 1;
+ p->remotelyblocked = 1;
isup_bla(linkset->ss7, e->blo.cic);
break;
case ISUP_EVENT_UBL:
@@ -8681,7 +8705,7 @@ static void *ss7_linkset(void *data)
}
p = linkset->pvts[chanpos];
ast_log(LOG_DEBUG, "Unblocking CIC %d\n", e->ubl.cic);
- p->blocked = 0;
+ p->remotelyblocked = 0;
isup_uba(linkset->ss7, e->ubl.cic);
break;
case ISUP_EVENT_CON:
@@ -10078,6 +10102,7 @@ static void *pri_dchannel(void *vpri)
pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV;
}
pri->pvts[chanpos]->resetting = 0;
+ pri->pvts[chanpos]->inservice = 1;
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "B-channel %d/%d successfully restarted on span %d\n", pri->pvts[chanpos]->logicalspan,
pri->pvts[chanpos]->prioffset, pri->span);
@@ -10751,7 +10776,6 @@ static int zap_show_channel(int fd, int argc, char **argv)
#ifdef HAVE_SS7
if (tmp->ss7) {
ast_cli(fd, "CIC: %d\n", tmp->cic);
- ast_cli(fd, "Blocked: %s\n", tmp->blocked ? "yes" : "no");
}
#endif
#ifdef HAVE_PRI
@@ -11362,6 +11386,7 @@ static int handle_ss7_debug(int fd, int argc, char *argv[])
static int handle_ss7_block_cic(int fd, int argc, char *argv[])
{
int linkset, cic;
+ int blocked = -1, i;
if (argc == 5)
linkset = atoi(argv[3]);
else
@@ -11384,10 +11409,30 @@ static int handle_ss7_block_cic(int fd, int argc, char *argv[])
return RESULT_SUCCESS;
}
- ast_mutex_lock(&linksets[linkset-1].lock);
- isup_blo(linksets[linkset-1].ss7, cic);
- ast_mutex_unlock(&linksets[linkset-1].lock);
- ast_cli(fd, "Sent blocking request for linkset %d on CIC %d\n", linkset, cic);
+ for (i = 0; i < linksets[linkset-1].numchans; i++) {
+ if (linksets[linkset-1].pvts[i]->cic == cic) {
+ blocked = linksets[linkset-1].pvts[i]->locallyblocked;
+ if (!blocked) {
+ ast_mutex_lock(&linksets[linkset-1].pvts[i]->lock);
+ linksets[linkset-1].pvts[i]->locallyblocked = 1;
+ ast_mutex_unlock(&linksets[linkset-1].pvts[i]->lock);
+ ast_mutex_lock(&linksets[linkset-1].lock);
+ isup_blo(linksets[linkset-1].ss7, cic);
+ ast_mutex_unlock(&linksets[linkset-1].lock);
+ }
+ }
+ }
+
+ if (blocked < 0) {
+ ast_cli(fd, "Invalid CIC specified!\n");
+ return RESULT_SUCCESS;
+ }
+
+ if (!blocked)
+ ast_cli(fd, "Sent blocking request for linkset %d on CIC %d\n", linkset, cic);
+ else
+ ast_cli(fd, "CIC %d already locally blocked\n", cic);
+
return RESULT_SUCCESS;
}