|
|
|
|
@ -4631,7 +4631,6 @@ static int manage_parked_call(struct parkeduser *pu, const struct pollfd *pfds,
|
|
|
|
|
struct ast_channel *chan = pu->chan; /* shorthand */
|
|
|
|
|
int tms; /* timeout for this item */
|
|
|
|
|
int x; /* fd index in channel */
|
|
|
|
|
int parking_complete = 0;
|
|
|
|
|
|
|
|
|
|
tms = ast_tvdiff_ms(ast_tvnow(), pu->start);
|
|
|
|
|
if (tms > pu->parkingtime) {
|
|
|
|
|
@ -4746,104 +4745,103 @@ static int manage_parked_call(struct parkeduser *pu, const struct pollfd *pfds,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* And take them out of the parking lot */
|
|
|
|
|
parking_complete = 1;
|
|
|
|
|
} else { /* still within parking time, process descriptors */
|
|
|
|
|
x = 0;
|
|
|
|
|
if (pfds) {
|
|
|
|
|
for (; x < AST_MAX_FDS; x++) {
|
|
|
|
|
struct ast_frame *f;
|
|
|
|
|
int y;
|
|
|
|
|
|
|
|
|
|
if (chan->fds[x] == -1) {
|
|
|
|
|
continue; /* nothing on this descriptor */
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (y = 0; y < nfds; y++) {
|
|
|
|
|
if (pfds[y].fd == chan->fds[x]) {
|
|
|
|
|
/* Found poll record! */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (y == nfds) {
|
|
|
|
|
/* Not found */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
/* still within parking time, process descriptors */
|
|
|
|
|
if (pfds) {
|
|
|
|
|
for (x = 0; x < AST_MAX_FDS; x++) {
|
|
|
|
|
struct ast_frame *f;
|
|
|
|
|
int y;
|
|
|
|
|
|
|
|
|
|
if (!(pfds[y].revents & (POLLIN | POLLERR | POLLPRI))) {
|
|
|
|
|
/* Next x */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (chan->fds[x] == -1) {
|
|
|
|
|
continue; /* nothing on this descriptor */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pfds[y].revents & POLLPRI) {
|
|
|
|
|
ast_set_flag(chan, AST_FLAG_EXCEPTION);
|
|
|
|
|
} else {
|
|
|
|
|
ast_clear_flag(chan, AST_FLAG_EXCEPTION);
|
|
|
|
|
for (y = 0; y < nfds; y++) {
|
|
|
|
|
if (pfds[y].fd == chan->fds[x]) {
|
|
|
|
|
/* Found poll record! */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
chan->fdno = x;
|
|
|
|
|
|
|
|
|
|
/* See if they need servicing */
|
|
|
|
|
f = ast_read(pu->chan);
|
|
|
|
|
/* Hangup? */
|
|
|
|
|
if (!f || (f->frametype == AST_FRAME_CONTROL
|
|
|
|
|
&& f->subclass.integer == AST_CONTROL_HANGUP)) {
|
|
|
|
|
if (f) {
|
|
|
|
|
ast_frfree(f);
|
|
|
|
|
}
|
|
|
|
|
post_manager_event("ParkedCallGiveUp", pu);
|
|
|
|
|
ast_cel_report_event(pu->chan, AST_CEL_PARK_END, NULL, "ParkedCallGiveUp",
|
|
|
|
|
NULL);
|
|
|
|
|
}
|
|
|
|
|
if (y == nfds) {
|
|
|
|
|
/* Not found */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* There's a problem, hang them up */
|
|
|
|
|
ast_verb(2, "%s got tired of being parked\n", chan->name);
|
|
|
|
|
ast_hangup(chan);
|
|
|
|
|
if (!(pfds[y].revents & (POLLIN | POLLERR | POLLPRI))) {
|
|
|
|
|
/* Next x */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* And take them out of the parking lot */
|
|
|
|
|
parking_complete = 1;
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
/* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
|
|
|
|
|
if (pfds[y].revents & POLLPRI) {
|
|
|
|
|
ast_set_flag(chan, AST_FLAG_EXCEPTION);
|
|
|
|
|
} else {
|
|
|
|
|
ast_clear_flag(chan, AST_FLAG_EXCEPTION);
|
|
|
|
|
}
|
|
|
|
|
chan->fdno = x;
|
|
|
|
|
|
|
|
|
|
/* See if they need servicing */
|
|
|
|
|
f = ast_read(pu->chan);
|
|
|
|
|
/* Hangup? */
|
|
|
|
|
if (!f || (f->frametype == AST_FRAME_CONTROL
|
|
|
|
|
&& f->subclass.integer == AST_CONTROL_HANGUP)) {
|
|
|
|
|
if (f) {
|
|
|
|
|
ast_frfree(f);
|
|
|
|
|
if (pu->hold_method == AST_CONTROL_HOLD
|
|
|
|
|
&& pu->moh_trys < 3
|
|
|
|
|
&& !chan->generatordata) {
|
|
|
|
|
ast_debug(1,
|
|
|
|
|
"MOH on parked call stopped by outside source. Restarting on channel %s.\n",
|
|
|
|
|
chan->name);
|
|
|
|
|
ast_indicate_data(chan, AST_CONTROL_HOLD,
|
|
|
|
|
S_OR(pu->parkinglot->cfg.mohclass, NULL),
|
|
|
|
|
(!ast_strlen_zero(pu->parkinglot->cfg.mohclass)
|
|
|
|
|
? strlen(pu->parkinglot->cfg.mohclass) + 1 : 0));
|
|
|
|
|
pu->moh_trys++;
|
|
|
|
|
}
|
|
|
|
|
goto std; /* XXX Ick: jumping into an else statement??? XXX */
|
|
|
|
|
}
|
|
|
|
|
} /* End for */
|
|
|
|
|
}
|
|
|
|
|
if (x >= AST_MAX_FDS) {
|
|
|
|
|
std:
|
|
|
|
|
for (x = 0; x < AST_MAX_FDS; x++) { /* mark fds for next round */
|
|
|
|
|
if (chan->fds[x] > -1) {
|
|
|
|
|
void *tmp = ast_realloc(*new_pfds,
|
|
|
|
|
(*new_nfds + 1) * sizeof(struct pollfd));
|
|
|
|
|
post_manager_event("ParkedCallGiveUp", pu);
|
|
|
|
|
ast_cel_report_event(pu->chan, AST_CEL_PARK_END, NULL, "ParkedCallGiveUp",
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
if (!tmp) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
*new_pfds = tmp;
|
|
|
|
|
(*new_pfds)[*new_nfds].fd = chan->fds[x];
|
|
|
|
|
(*new_pfds)[*new_nfds].events = POLLIN | POLLERR | POLLPRI;
|
|
|
|
|
(*new_pfds)[*new_nfds].revents = 0;
|
|
|
|
|
(*new_nfds)++;
|
|
|
|
|
/* There's a problem, hang them up */
|
|
|
|
|
ast_verb(2, "%s got tired of being parked\n", chan->name);
|
|
|
|
|
ast_hangup(chan);
|
|
|
|
|
|
|
|
|
|
/* And take them out of the parking lot */
|
|
|
|
|
return 1;
|
|
|
|
|
} else {
|
|
|
|
|
/* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */
|
|
|
|
|
ast_frfree(f);
|
|
|
|
|
if (pu->hold_method == AST_CONTROL_HOLD
|
|
|
|
|
&& pu->moh_trys < 3
|
|
|
|
|
&& !chan->generatordata) {
|
|
|
|
|
ast_debug(1,
|
|
|
|
|
"MOH on parked call stopped by outside source. Restarting on channel %s.\n",
|
|
|
|
|
chan->name);
|
|
|
|
|
ast_indicate_data(chan, AST_CONTROL_HOLD,
|
|
|
|
|
S_OR(pu->parkinglot->cfg.mohclass, NULL),
|
|
|
|
|
(!ast_strlen_zero(pu->parkinglot->cfg.mohclass)
|
|
|
|
|
? strlen(pu->parkinglot->cfg.mohclass) + 1 : 0));
|
|
|
|
|
pu->moh_trys++;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
/* Keep track of our shortest wait */
|
|
|
|
|
if (tms < *ms || *ms < 0) {
|
|
|
|
|
*ms = tms;
|
|
|
|
|
} /* End for */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* mark fds for next round */
|
|
|
|
|
for (x = 0; x < AST_MAX_FDS; x++) {
|
|
|
|
|
if (chan->fds[x] > -1) {
|
|
|
|
|
void *tmp = ast_realloc(*new_pfds,
|
|
|
|
|
(*new_nfds + 1) * sizeof(struct pollfd));
|
|
|
|
|
|
|
|
|
|
if (!tmp) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
*new_pfds = tmp;
|
|
|
|
|
(*new_pfds)[*new_nfds].fd = chan->fds[x];
|
|
|
|
|
(*new_pfds)[*new_nfds].events = POLLIN | POLLERR | POLLPRI;
|
|
|
|
|
(*new_pfds)[*new_nfds].revents = 0;
|
|
|
|
|
(*new_nfds)++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* Keep track of our shortest wait */
|
|
|
|
|
if (tms < *ms || *ms < 0) {
|
|
|
|
|
*ms = tms;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return parking_complete;
|
|
|
|
|
/* Stay in the parking lot. */
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! \brief Run management on parkinglots, called once per parkinglot */
|
|
|
|
|
|