mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-30 10:33:13 +00:00
Fix signalling for GR303 FXSKS CPE so we can look like a concentrator
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3476 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -30,14 +30,14 @@ static char *synopsis = "Play a file";
|
|||||||
|
|
||||||
static char *descrip =
|
static char *descrip =
|
||||||
" Playback(filename[|option]): Plays back a given filename (do not put\n"
|
" Playback(filename[|option]): Plays back a given filename (do not put\n"
|
||||||
"extension). Options may also be included following a pipe symbol. The only\n"
|
"extension). Options may also be included following a pipe symbol. The 'skip'\n"
|
||||||
"defined option at this time is 'skip', which causes the playback of the\n"
|
"option causes the playback of the message to be skipped if the channel\n"
|
||||||
"message to be skipped if the channel is not in the 'up' state (i.e. it\n"
|
"is not in the 'up' state (i.e. it hasn't been answered yet. If 'skip' is \n"
|
||||||
"hasn't been answered yet. If 'skip' is specified, the application will\n"
|
"specified, the application will return immediately should the channel not be\n"
|
||||||
"return immediately should the channel not be off hook. Otherwise, unless\n"
|
"off hook. Otherwise, unless 'noanswer' is specified, the channel channel will\n"
|
||||||
"'noanswer' is specified, the channel channel will be answered before the sound\n"
|
"be answered before the sound is played. Not all channels support playing\n"
|
||||||
"is played. Not all channels support playing messages while on hook. Returns -1\n"
|
"messages while still hook. Returns -1 if the channel was hung up, or if the\n"
|
||||||
"if the channel was hung up, or if the file does not exist. Returns 0 otherwise.\n";
|
"file does not exist. Returns 0 otherwise.\n";
|
||||||
|
|
||||||
STANDARD_LOCAL_USER;
|
STANDARD_LOCAL_USER;
|
||||||
|
|
||||||
|
@@ -1610,8 +1610,9 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
|
|||||||
ast_mutex_unlock(&p->lock);
|
ast_mutex_unlock(&p->lock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
/* Start the trunk, if not GR-303 */
|
||||||
|
if (!p->pri) {
|
||||||
x = ZT_START;
|
x = ZT_START;
|
||||||
/* Start the trunk */
|
|
||||||
res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
|
res = ioctl(p->subs[SUB_REAL].zfd, ZT_HOOK, &x);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
if (errno != EINPROGRESS) {
|
if (errno != EINPROGRESS) {
|
||||||
@@ -1620,6 +1621,7 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
|
ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
|
||||||
p->dop.op = ZT_DIAL_OP_REPLACE;
|
p->dop.op = ZT_DIAL_OP_REPLACE;
|
||||||
if (p->sig == SIG_FEATD) {
|
if (p->sig == SIG_FEATD) {
|
||||||
@@ -1719,6 +1721,7 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
|
|||||||
ast_mutex_unlock(&p->lock);
|
ast_mutex_unlock(&p->lock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (p->sig != SIG_FXSKS) {
|
||||||
p->dop.op = ZT_DIAL_OP_REPLACE;
|
p->dop.op = ZT_DIAL_OP_REPLACE;
|
||||||
s = strchr(c + p->stripmsd, 'w');
|
s = strchr(c + p->stripmsd, 'w');
|
||||||
if (s) {
|
if (s) {
|
||||||
@@ -1730,6 +1733,7 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
|
|||||||
} else {
|
} else {
|
||||||
p->dop.dialstr[0] = '\0';
|
p->dop.dialstr[0] = '\0';
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (pri_grab(p, p->pri)) {
|
if (pri_grab(p, p->pri)) {
|
||||||
ast_log(LOG_WARNING, "Failed to grab PRI!\n");
|
ast_log(LOG_WARNING, "Failed to grab PRI!\n");
|
||||||
ast_mutex_unlock(&p->lock);
|
ast_mutex_unlock(&p->lock);
|
||||||
@@ -1746,10 +1750,13 @@ static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
|
|||||||
pri_rel(p->pri);
|
pri_rel(p->pri);
|
||||||
ast_mutex_unlock(&p->lock);
|
ast_mutex_unlock(&p->lock);
|
||||||
}
|
}
|
||||||
|
if (p->bearer || (p->sig == SIG_FXSKS)) {
|
||||||
if (p->bearer) {
|
if (p->bearer) {
|
||||||
ast_log(LOG_DEBUG, "Oooh, I have a bearer on %d (%d:%d)\n", PVT_TO_CHANNEL(p->bearer), p->bearer->logicalspan, p->bearer->channel);
|
ast_log(LOG_DEBUG, "Oooh, I have a bearer on %d (%d:%d)\n", PVT_TO_CHANNEL(p->bearer), p->bearer->logicalspan, p->bearer->channel);
|
||||||
pri_set_crv(p->pri->pri, p->call, p->channel, 0);
|
|
||||||
p->bearer->call = p->call;
|
p->bearer->call = p->call;
|
||||||
|
} else
|
||||||
|
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);
|
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),
|
pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p),
|
||||||
@@ -1858,6 +1865,8 @@ int pri_assign_bearer(struct zt_pvt *crv, struct zt_pri *pri, struct zt_pvt *bea
|
|||||||
bearer->owner = &inuse;
|
bearer->owner = &inuse;
|
||||||
bearer->master = crv;
|
bearer->master = crv;
|
||||||
crv->subs[SUB_REAL].zfd = bearer->subs[SUB_REAL].zfd;
|
crv->subs[SUB_REAL].zfd = bearer->subs[SUB_REAL].zfd;
|
||||||
|
if (crv->subs[SUB_REAL].owner)
|
||||||
|
crv->subs[SUB_REAL].owner->fds[0] = crv->subs[SUB_REAL].zfd;
|
||||||
crv->bearer = bearer;
|
crv->bearer = bearer;
|
||||||
crv->call = bearer->call;
|
crv->call = bearer->call;
|
||||||
crv->pri = pri;
|
crv->pri = pri;
|
||||||
@@ -4262,7 +4271,7 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int
|
|||||||
y = 1;
|
y = 1;
|
||||||
do {
|
do {
|
||||||
#ifdef ZAPATA_PRI
|
#ifdef ZAPATA_PRI
|
||||||
if (i->bearer)
|
if (i->bearer || (i->pri && (i->sig == SIG_FXSKS)))
|
||||||
snprintf(tmp->name, sizeof(tmp->name), "Zap/%d:%d-%d", i->pri->trunkgroup, i->channel, y);
|
snprintf(tmp->name, sizeof(tmp->name), "Zap/%d:%d-%d", i->pri->trunkgroup, i->channel, y);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@@ -6475,14 +6484,25 @@ static struct ast_channel *zt_request(char *type, int format, void *data)
|
|||||||
callwait = (p->owner != NULL);
|
callwait = (p->owner != NULL);
|
||||||
#ifdef ZAPATA_PRI
|
#ifdef ZAPATA_PRI
|
||||||
if (pri && (p->subs[SUB_REAL].zfd < 0)) {
|
if (pri && (p->subs[SUB_REAL].zfd < 0)) {
|
||||||
|
if (p->sig != SIG_FXSKS) {
|
||||||
/* Gotta find an actual channel to use for this
|
/* Gotta find an actual channel to use for this
|
||||||
CRV if this isn't a callwait */
|
CRV if this isn't a callwait */
|
||||||
bearer = pri_find_empty_chan(pri, 0);
|
bearer = pri_find_empty_chan(pri, 0);
|
||||||
if (bearer < 0) {
|
if (bearer < 0) {
|
||||||
ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
|
ast_log(LOG_NOTICE, "Out of bearer channels on span %d for call to CRV %d:%d\n", pri->span, trunkgroup, crv);
|
||||||
|
p = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pri_assign_bearer(p, pri, pri->pvts[bearer]);
|
pri_assign_bearer(p, pri, pri->pvts[bearer]);
|
||||||
|
} else {
|
||||||
|
if (alloc_sub(p, 0)) {
|
||||||
|
ast_log(LOG_NOTICE, "Failed to allocate place holder pseudo channel!\n");
|
||||||
|
p = NULL;
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
ast_log(LOG_DEBUG, "Allocated placeholder pseudo channel\n");
|
||||||
|
p->pri = pri;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (p->channel == CHAN_PSEUDO) {
|
if (p->channel == CHAN_PSEUDO) {
|
||||||
@@ -6596,6 +6616,7 @@ static int pri_find_principle(struct zt_pri *pri, int channel)
|
|||||||
static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
|
static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
|
struct zt_pvt *crv;
|
||||||
if (!c) {
|
if (!c) {
|
||||||
if (principle < 0)
|
if (principle < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -6606,6 +6627,7 @@ static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
|
|||||||
(pri->pvts[principle]) &&
|
(pri->pvts[principle]) &&
|
||||||
(pri->pvts[principle]->call == c))
|
(pri->pvts[principle]->call == c))
|
||||||
return principle;
|
return principle;
|
||||||
|
/* First, check for other bearers */
|
||||||
for (x=0;x<pri->numchans;x++) {
|
for (x=0;x<pri->numchans;x++) {
|
||||||
if (!pri->pvts[x]) continue;
|
if (!pri->pvts[x]) continue;
|
||||||
if (pri->pvts[x]->call == c) {
|
if (pri->pvts[x]->call == c) {
|
||||||
@@ -6635,6 +6657,30 @@ static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
|
|||||||
return principle;
|
return principle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Now check for a CRV with no bearer */
|
||||||
|
crv = pri->crvs;
|
||||||
|
while(crv) {
|
||||||
|
if (crv->call == c) {
|
||||||
|
/* This is our match... Perform some basic checks */
|
||||||
|
if (crv->bearer)
|
||||||
|
ast_log(LOG_WARNING, "Trying to fix up call which already has a bearer which isn't the one we think it is\n");
|
||||||
|
else if (pri->pvts[principle]->owner)
|
||||||
|
ast_log(LOG_WARNING, "Tring to fix up a call to a bearer which already has an owner!\n");
|
||||||
|
else {
|
||||||
|
/* Looks good. Drop the pseudo channel now, clear up the assignment, and
|
||||||
|
wakeup the potential sleeper */
|
||||||
|
close(crv->subs[SUB_REAL].zfd);
|
||||||
|
pri->pvts[principle]->call = crv->call;
|
||||||
|
pri_assign_bearer(crv, pri, pri->pvts[principle]);
|
||||||
|
ast_log(LOG_DEBUG, "Assigning bearer %d/%d to CRV %d:%d\n",
|
||||||
|
pri->pvts[principle]->logicalspan, pri->pvts[principle]->prioffset,
|
||||||
|
pri->trunkgroup, crv->channel);
|
||||||
|
wakeup_sub(crv, SUB_REAL);
|
||||||
|
}
|
||||||
|
return principle;
|
||||||
|
}
|
||||||
|
crv = crv->next;
|
||||||
|
}
|
||||||
ast_log(LOG_WARNING, "Call specified, but not found?\n");
|
ast_log(LOG_WARNING, "Call specified, but not found?\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -7361,7 +7407,16 @@ static void *pri_dchannel(void *vpri)
|
|||||||
chanpos = -1;
|
chanpos = -1;
|
||||||
} else {
|
} else {
|
||||||
ast_mutex_lock(&pri->pvts[chanpos]->lock);
|
ast_mutex_lock(&pri->pvts[chanpos]->lock);
|
||||||
if (!ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
|
if (pri->pvts[chanpos]->master && (pri->pvts[chanpos]->master->sig == SIG_FXSKS)) {
|
||||||
|
ast_log(LOG_DEBUG, "Starting up GR-303 trunk now that we got CONNECT...\n");
|
||||||
|
x = ZT_START;
|
||||||
|
res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_HOOK, &x);
|
||||||
|
if (res < 0) {
|
||||||
|
if (errno != EINPROGRESS) {
|
||||||
|
ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) {
|
||||||
pri->pvts[chanpos]->dialing = 1;
|
pri->pvts[chanpos]->dialing = 1;
|
||||||
/* Send any "w" waited stuff */
|
/* Send any "w" waited stuff */
|
||||||
res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_DIAL, &pri->pvts[chanpos]->dop);
|
res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_DIAL, &pri->pvts[chanpos]->dop);
|
||||||
@@ -8097,6 +8152,8 @@ static int zap_show_channel(int fd, int argc, char **argv)
|
|||||||
ast_cli(fd, "Resetting ");
|
ast_cli(fd, "Resetting ");
|
||||||
if (tmp->call)
|
if (tmp->call)
|
||||||
ast_cli(fd, "Call ");
|
ast_cli(fd, "Call ");
|
||||||
|
if (tmp->bearer)
|
||||||
|
ast_cli(fd, "Bearer ");
|
||||||
ast_cli(fd, "\n");
|
ast_cli(fd, "\n");
|
||||||
if (tmp->logicalspan)
|
if (tmp->logicalspan)
|
||||||
ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan);
|
ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan);
|
||||||
|
Reference in New Issue
Block a user