- removed pipe code, use queue_frame instead
This commit is contained in:
parent
620556efd6
commit
1742806313
265
chan_capi.c
265
chan_capi.c
|
@ -619,41 +619,35 @@ static int capi_detect_dtmf(struct ast_channel *c, int flag)
|
|||
}
|
||||
|
||||
/*
|
||||
* send a frame to PBX via pipe
|
||||
* queue a frame to PBX
|
||||
* we assume i->lock held
|
||||
*/
|
||||
static int pipe_frame(struct capi_pvt *i, struct ast_frame *f)
|
||||
static int local_queue_frame(struct capi_pvt *i, struct ast_frame *f)
|
||||
{
|
||||
#ifdef CAPINOPIPE
|
||||
int res;
|
||||
struct ast_channel *chan = i->owner;
|
||||
|
||||
if (chan == NULL) {
|
||||
cc_log(LOG_ERROR, "No owner in pipe_frame for %s\n",
|
||||
i->name);
|
||||
return -1;
|
||||
}
|
||||
return (ast_queue_frame(chan, f));
|
||||
#else
|
||||
fd_set wfds;
|
||||
int written = 0;
|
||||
struct timeval tv;
|
||||
|
||||
if (i->owner == NULL) {
|
||||
cc_verbose(1, 1, VERBOSE_PREFIX_1 "%s: No owner in pipe_frame\n",
|
||||
cc_log(LOG_ERROR, "No owner in local_queue_frame for %s\n",
|
||||
i->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i->fd2 == -1) {
|
||||
cc_log(LOG_ERROR, "No fd in pipe_frame for %s\n",
|
||||
i->owner->name);
|
||||
if (!(i->isdnstate & CAPI_ISDN_STATE_PBX)) {
|
||||
/* if there is no PBX running yet,
|
||||
we don't need any frames sent */
|
||||
return -1;
|
||||
}
|
||||
|
||||
FD_ZERO(&wfds);
|
||||
FD_SET(i->fd2, &wfds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 10;
|
||||
|
||||
|
||||
if ((capidebug) && (f->frametype != AST_FRAME_VOICE)) {
|
||||
ast_frame_dump("CAPI", f, VERBOSE_PREFIX_3 "queue frame:");
|
||||
}
|
||||
|
||||
if ((f->frametype == AST_FRAME_CONTROL) &&
|
||||
(f->subclass == AST_CONTROL_HANGUP)) {
|
||||
return (ast_queue_hangup(chan));
|
||||
}
|
||||
|
||||
if ((f->frametype == AST_FRAME_VOICE) &&
|
||||
(i->doDTMF > 0) &&
|
||||
(i->vad != NULL) ) {
|
||||
|
@ -662,31 +656,12 @@ static int pipe_frame(struct capi_pvt *i, struct ast_frame *f)
|
|||
#else
|
||||
f = ast_dsp_process(i->owner, i->vad, f);
|
||||
#endif
|
||||
if (f->frametype == AST_FRAME_NULL) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* we dont want the monitor thread to block */
|
||||
if (select(i->fd2 + 1, NULL, &wfds, NULL, &tv) == 1) {
|
||||
written = write(i->fd2, f, sizeof(struct ast_frame));
|
||||
if (written < (signed int) sizeof(struct ast_frame)) {
|
||||
cc_log(LOG_ERROR, "wrote %d bytes instead of %d\n",
|
||||
written, sizeof(struct ast_frame));
|
||||
return -1;
|
||||
}
|
||||
if (f->frametype == AST_FRAME_VOICE) {
|
||||
written = write(i->fd2, f->data, f->datalen);
|
||||
if (written < f->datalen) {
|
||||
cc_log(LOG_ERROR, "wrote %d bytes instead of %d\n",
|
||||
written, f->datalen);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
cc_mutex_unlock(&i->lock); /* give up lock to avoid deadlock */
|
||||
res = ast_queue_frame(chan, f);
|
||||
cc_mutex_lock(&i->lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -845,18 +820,6 @@ static void interface_cleanup(struct capi_pvt *i)
|
|||
cc_verbose(2, 1, VERBOSE_PREFIX_2 "%s: Interface cleanup PLCI=%#x\n",
|
||||
i->name, i->PLCI);
|
||||
|
||||
#ifndef CAPINOPIPE
|
||||
if (i->fd != -1) {
|
||||
close(i->fd);
|
||||
i->fd = -1;
|
||||
}
|
||||
|
||||
if (i->fd2 != -1) {
|
||||
close(i->fd2);
|
||||
i->fd2 = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
i->isdnstate = 0;
|
||||
i->cause = 0;
|
||||
|
||||
|
@ -945,15 +908,14 @@ static void start_early_b3(struct capi_pvt *i)
|
|||
*/
|
||||
static void send_progress(struct capi_pvt *i)
|
||||
{
|
||||
struct ast_frame fr;
|
||||
struct ast_frame fr = { AST_FRAME_CONTROL, };
|
||||
|
||||
start_early_b3(i);
|
||||
|
||||
if (!(i->isdnstate & CAPI_ISDN_STATE_PROGRESS)) {
|
||||
i->isdnstate |= CAPI_ISDN_STATE_PROGRESS;
|
||||
fr.frametype = AST_FRAME_CONTROL;
|
||||
fr.subclass = AST_CONTROL_PROGRESS;
|
||||
pipe_frame(i, &fr);
|
||||
local_queue_frame(i, &fr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1227,12 +1189,8 @@ static int capi_call(struct ast_channel *c, char *idest, int timeout)
|
|||
i->name, c->name, i->doB3 ? "with B3 ":" ",
|
||||
i->doOverlap ? "overlap":"", CLIR, callernplan);
|
||||
|
||||
#ifndef CAPINOPIPE
|
||||
/* set FD for PBX */
|
||||
c->fds[0] = i->fd;
|
||||
#endif
|
||||
|
||||
i->outgoing = 1;
|
||||
i->isdnstate |= CAPI_ISDN_STATE_PBX;
|
||||
|
||||
if ((p = pbx_builtin_getvar_helper(c, "CALLINGSUBADDRESS"))) {
|
||||
callingsubaddress[0] = strlen(p) + 1;
|
||||
|
@ -1398,65 +1356,9 @@ static int capi_answer(struct ast_channel *c)
|
|||
*/
|
||||
static struct ast_frame *capi_read(struct ast_channel *c)
|
||||
{
|
||||
#ifdef CAPINOPIPE
|
||||
static struct ast_frame null = { AST_FRAME_NULL, };
|
||||
|
||||
return &null;
|
||||
#else
|
||||
struct capi_pvt *i = CC_CHANNEL_PVT(c);
|
||||
int readsize = 0;
|
||||
|
||||
if (i == NULL) {
|
||||
cc_log(LOG_ERROR, "channel has no interface\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (i->state == CAPI_STATE_ONHOLD) {
|
||||
i->fr.frametype = AST_FRAME_NULL;
|
||||
return &i->fr;
|
||||
}
|
||||
|
||||
i->fr.frametype = AST_FRAME_NULL;
|
||||
i->fr.subclass = 0;
|
||||
|
||||
#ifdef CC_AST_FRAME_HAS_TIMEVAL
|
||||
i->fr.delivery.tv_sec = 0;
|
||||
i->fr.delivery.tv_usec = 0;
|
||||
#endif
|
||||
readsize = read(i->fd, &i->fr, sizeof(struct ast_frame));
|
||||
if (readsize != sizeof(struct ast_frame)) {
|
||||
cc_log(LOG_ERROR, "did not read a whole frame\n");
|
||||
}
|
||||
if (i->fr.frametype == AST_FRAME_VOICE) {
|
||||
readsize = read(i->fd, i->fr.data, i->fr.datalen);
|
||||
if (readsize != i->fr.datalen) {
|
||||
cc_log(LOG_ERROR, "did not read whole frame data\n");
|
||||
}
|
||||
}
|
||||
|
||||
i->fr.mallocd = 0;
|
||||
|
||||
if (i->fr.frametype == AST_FRAME_NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if ((i->fr.frametype == AST_FRAME_DTMF) && (i->fr.subclass == 'f')) {
|
||||
if (strcmp(c->exten, "fax")) {
|
||||
if (ast_exists_extension(c, ast_strlen_zero(c->macrocontext) ? c->context : c->macrocontext, "fax", 1, i->cid)) {
|
||||
cc_verbose(2, 0, VERBOSE_PREFIX_3 "%s: Redirecting %s to fax extension\n",
|
||||
i->name, c->name);
|
||||
/* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
|
||||
pbx_builtin_setvar_helper(c, "FAXEXTEN", c->exten);
|
||||
if (ast_async_goto(c, c->context, "fax", 1))
|
||||
cc_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", c->name, c->context);
|
||||
} else {
|
||||
cc_verbose(3, 0, VERBOSE_PREFIX_3 "Fax detected, but no fax extension\n");
|
||||
}
|
||||
} else {
|
||||
cc_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
|
||||
}
|
||||
}
|
||||
return &i->fr;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1476,8 +1378,8 @@ static int capi_write(struct ast_channel *c, struct ast_frame *f)
|
|||
if (!i) {
|
||||
cc_log(LOG_ERROR, "channel has no interface\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cc_mutex_lock(&i->lock);
|
||||
|
||||
if ((!(i->isdnstate & CAPI_ISDN_STATE_B3_UP)) || (!i->NCCI) ||
|
||||
|
@ -1875,11 +1777,8 @@ static struct ast_channel *capi_new(struct capi_pvt *i, int state)
|
|||
{
|
||||
struct ast_channel *tmp;
|
||||
int fmt;
|
||||
#ifndef CAPINOPIPE
|
||||
int fds[2];
|
||||
#endif
|
||||
|
||||
tmp = ast_channel_alloc(0);
|
||||
tmp = ast_channel_alloc(1);
|
||||
|
||||
if (tmp == NULL) {
|
||||
cc_log(LOG_ERROR,"Unable to allocate channel!\n");
|
||||
|
@ -1904,27 +1803,10 @@ static struct ast_channel *capi_new(struct capi_pvt *i, int state)
|
|||
tmp->type = channeltype;
|
||||
#endif
|
||||
|
||||
#ifndef CAPINOPIPE
|
||||
if (pipe(fds) != 0) {
|
||||
cc_log(LOG_ERROR, "%s: unable to create pipe.\n", i->name);
|
||||
ast_channel_free(tmp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
i->fd = fds[0];
|
||||
i->fd2 = fds[1];
|
||||
|
||||
tmp->fds[0] = i->fd;
|
||||
#endif
|
||||
if (i->smoother != NULL) {
|
||||
ast_smoother_reset(i->smoother, CAPI_MAX_B3_BLOCK_SIZE);
|
||||
}
|
||||
i->fr.frametype = 0;
|
||||
i->fr.subclass = 0;
|
||||
#ifdef CC_AST_FRAME_HAS_TIMEVAL
|
||||
i->fr.delivery.tv_sec = 0;
|
||||
i->fr.delivery.tv_usec = 0;
|
||||
#endif
|
||||
|
||||
i->state = CAPI_STATE_DISCONNECTED;
|
||||
i->calledPartyIsISDN = 1;
|
||||
i->doB3 = CAPI_B3_DONT;
|
||||
|
@ -2483,7 +2365,7 @@ static void start_pbx_on_match(struct capi_pvt *i, unsigned int PLCI, _cword Mes
|
|||
static void handle_did_digits(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
|
||||
{
|
||||
char *did;
|
||||
struct ast_frame fr;
|
||||
struct ast_frame fr = { AST_FRAME_NULL, };
|
||||
int a;
|
||||
|
||||
if (!i->owner) {
|
||||
|
@ -2516,7 +2398,7 @@ static void handle_did_digits(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI,
|
|||
for (a = 0; a < strlen(did); a++) {
|
||||
fr.frametype = AST_FRAME_DTMF;
|
||||
fr.subclass = did[a];
|
||||
pipe_frame(i, &fr);
|
||||
local_queue_frame(i, &fr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -2528,26 +2410,21 @@ static void handle_did_digits(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI,
|
|||
/*
|
||||
* send control according to cause code
|
||||
*/
|
||||
static void pipe_cause_control(struct capi_pvt *i, int control)
|
||||
static void queue_cause_control(struct capi_pvt *i, int control)
|
||||
{
|
||||
struct ast_frame fr;
|
||||
struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, };
|
||||
|
||||
fr.frametype = AST_FRAME_NULL;
|
||||
fr.datalen = 0;
|
||||
|
||||
if ((i->owner) && (control)) {
|
||||
int cause = i->owner->hangupcause;
|
||||
if (cause == AST_CAUSE_NORMAL_CIRCUIT_CONGESTION) {
|
||||
fr.frametype = AST_FRAME_CONTROL;
|
||||
fr.subclass = AST_CONTROL_CONGESTION;
|
||||
} else if ((cause != AST_CAUSE_NO_USER_RESPONSE) &&
|
||||
(cause != AST_CAUSE_NO_ANSWER)) {
|
||||
/* not NOANSWER */
|
||||
fr.frametype = AST_FRAME_CONTROL;
|
||||
fr.subclass = AST_CONTROL_BUSY;
|
||||
}
|
||||
}
|
||||
pipe_frame(i, &fr);
|
||||
local_queue_frame(i, &fr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2582,7 +2459,7 @@ static void handle_info_disconnect(_cmsg *CMSG, unsigned int PLCI, unsigned int
|
|||
if ((i->doB3 != CAPI_B3_ALWAYS) && (i->outgoing == 1)) {
|
||||
cc_verbose(4, 1, VERBOSE_PREFIX_3 "%s: Disconnect case 1\n",
|
||||
i->name);
|
||||
pipe_cause_control(i, 1);
|
||||
queue_cause_control(i, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2591,7 +2468,7 @@ static void handle_info_disconnect(_cmsg *CMSG, unsigned int PLCI, unsigned int
|
|||
(i->state == CAPI_STATE_CONNECTED) && (i->outgoing == 1)) {
|
||||
cc_verbose(4, 1, VERBOSE_PREFIX_3 "%s: Disconnect case 2\n",
|
||||
i->name);
|
||||
pipe_cause_control(i, 1);
|
||||
queue_cause_control(i, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2610,7 +2487,7 @@ static void handle_info_disconnect(_cmsg *CMSG, unsigned int PLCI, unsigned int
|
|||
_capi_put_cmsg(&CMSG2);
|
||||
return;
|
||||
}
|
||||
pipe_cause_control(i, 0);
|
||||
queue_cause_control(i, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2620,7 +2497,7 @@ static void handle_info_disconnect(_cmsg *CMSG, unsigned int PLCI, unsigned int
|
|||
i->name);
|
||||
if ((i->state == CAPI_STATE_CONNECTED) &&
|
||||
(i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
|
||||
pipe_cause_control(i, 1);
|
||||
queue_cause_control(i, 1);
|
||||
return;
|
||||
}
|
||||
/* wait for the 0x001e (PROGRESS), play audio and wait for a timeout from the network */
|
||||
|
@ -2665,7 +2542,7 @@ static void handle_setup_element(_cmsg *CMSG, unsigned int PLCI, struct capi_pvt
|
|||
static void capi_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
|
||||
{
|
||||
_cmsg CMSG2;
|
||||
struct ast_frame fr;
|
||||
struct ast_frame fr = { AST_FRAME_NULL, };
|
||||
char *p = NULL;
|
||||
int val = 0;
|
||||
|
||||
|
@ -2778,14 +2655,14 @@ static void capi_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsigned
|
|||
send_progress(i);
|
||||
fr.frametype = AST_FRAME_CONTROL;
|
||||
fr.subclass = AST_CONTROL_RINGING;
|
||||
pipe_frame(i, &fr);
|
||||
local_queue_frame(i, &fr);
|
||||
break;
|
||||
case 0x8002: /* CALL PROCEEDING */
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CALL PROCEEDING\n",
|
||||
i->name);
|
||||
fr.frametype = AST_FRAME_CONTROL;
|
||||
fr.subclass = AST_CONTROL_PROCEEDING;
|
||||
pipe_frame(i, &fr);
|
||||
local_queue_frame(i, &fr);
|
||||
break;
|
||||
case 0x8003: /* PROGRESS */
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element PROGRESS\n",
|
||||
|
@ -2805,7 +2682,7 @@ static void capi_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsigned
|
|||
if (i->doB3 == CAPI_B3_DONT) {
|
||||
if ((i->owner) &&
|
||||
(i->owner->hangupcause == AST_CAUSE_USER_BUSY)) {
|
||||
pipe_cause_control(i, 1);
|
||||
queue_cause_control(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2879,7 +2756,7 @@ static void capi_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsigned
|
|||
static void capi_handle_facility_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
|
||||
{
|
||||
_cmsg CMSG2;
|
||||
struct ast_frame fr;
|
||||
struct ast_frame fr = { AST_FRAME_NULL, };
|
||||
char dtmf;
|
||||
unsigned dtmflen;
|
||||
unsigned dtmfpos = 0;
|
||||
|
@ -2924,7 +2801,7 @@ static void capi_handle_facility_indication(_cmsg *CMSG, unsigned int PLCI, unsi
|
|||
} else {
|
||||
fr.frametype = AST_FRAME_DTMF;
|
||||
fr.subclass = dtmf;
|
||||
pipe_frame(i, &fr);
|
||||
local_queue_frame(i, &fr);
|
||||
}
|
||||
}
|
||||
dtmflen--;
|
||||
|
@ -2994,7 +2871,7 @@ static void capi_handle_facility_indication(_cmsg *CMSG, unsigned int PLCI, unsi
|
|||
static void capi_handle_data_b3_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
|
||||
{
|
||||
_cmsg CMSG2;
|
||||
struct ast_frame fr;
|
||||
struct ast_frame fr = { AST_FRAME_NULL, };
|
||||
unsigned char *b3buf = NULL;
|
||||
int b3len = 0;
|
||||
int j;
|
||||
|
@ -3035,7 +2912,7 @@ static void capi_handle_data_b3_indication(_cmsg *CMSG, unsigned int PLCI, unsig
|
|||
if ((i->isdnstate & CAPI_ISDN_STATE_RTP)) {
|
||||
struct ast_frame *f = capi_read_rtp(i, b3buf, b3len);
|
||||
if (f)
|
||||
pipe_frame(i, f);
|
||||
local_queue_frame(i, f);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3093,7 +2970,7 @@ static void capi_handle_data_b3_indication(_cmsg *CMSG, unsigned int PLCI, unsig
|
|||
fr.src = NULL;
|
||||
cc_verbose(8, 1, VERBOSE_PREFIX_3 "%s: DATA_B3_IND (len=%d) fr.datalen=%d fr.subclass=%d\n",
|
||||
i->name, b3len, fr.datalen, fr.subclass);
|
||||
pipe_frame(i, &fr);
|
||||
local_queue_frame(i, &fr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3102,12 +2979,11 @@ static void capi_handle_data_b3_indication(_cmsg *CMSG, unsigned int PLCI, unsig
|
|||
*/
|
||||
static void capi_signal_answer(struct capi_pvt *i)
|
||||
{
|
||||
struct ast_frame fr;
|
||||
struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER, };
|
||||
|
||||
fr.frametype = AST_FRAME_CONTROL;
|
||||
fr.subclass = AST_CONTROL_ANSWER;
|
||||
fr.datalen = 0;
|
||||
pipe_frame(i, &fr);
|
||||
if (i->outgoing == 1) {
|
||||
local_queue_frame(i, &fr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3132,7 +3008,6 @@ static void capi_handle_connect_active_indication(_cmsg *CMSG, unsigned int PLCI
|
|||
i->state = CAPI_STATE_CONNECTED;
|
||||
|
||||
if ((i->owner) && (i->FaxState)) {
|
||||
ast_setstate(i->owner, AST_STATE_UP);
|
||||
capi_signal_answer(i);
|
||||
return;
|
||||
}
|
||||
|
@ -3149,10 +3024,6 @@ static void capi_handle_connect_active_indication(_cmsg *CMSG, unsigned int PLCI
|
|||
/* RESP already sent ... wait for CONNECT_B3_IND */
|
||||
}
|
||||
} else {
|
||||
/* special treatment for early B3 connects */
|
||||
if ((i->owner) && (i->owner->_state != AST_STATE_UP)) {
|
||||
ast_setstate(i->owner, AST_STATE_UP);
|
||||
}
|
||||
capi_signal_answer(i);
|
||||
}
|
||||
return;
|
||||
|
@ -3215,7 +3086,6 @@ static void capi_handle_connect_b3_active_indication(_cmsg *CMSG, unsigned int P
|
|||
}
|
||||
|
||||
if (i->state == CAPI_STATE_CONNECTED) {
|
||||
ast_setstate(i->owner, AST_STATE_UP);
|
||||
capi_signal_answer(i);
|
||||
}
|
||||
return;
|
||||
|
@ -3299,7 +3169,7 @@ static void capi_handle_connect_b3_indication(_cmsg *CMSG, unsigned int PLCI, un
|
|||
static void capi_handle_disconnect_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
|
||||
{
|
||||
_cmsg CMSG2;
|
||||
struct ast_frame fr;
|
||||
struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, };
|
||||
int state;
|
||||
|
||||
DISCONNECT_RESP_HEADER(&CMSG2, capi_ApplID, HEADER_MSGNUM(CMSG) , 0);
|
||||
|
@ -3346,32 +3216,14 @@ static void capi_handle_disconnect_indication(_cmsg *CMSG, unsigned int PLCI, un
|
|||
return;
|
||||
}
|
||||
|
||||
fr.frametype = AST_FRAME_CONTROL;
|
||||
if (DISCONNECT_IND_REASON(CMSG) == 0x34a2) {
|
||||
fr.subclass = AST_CONTROL_CONGESTION;
|
||||
} else {
|
||||
fr.frametype = AST_FRAME_NULL;
|
||||
}
|
||||
fr.datalen = 0;
|
||||
|
||||
if (pipe_frame(i, &fr) == -1) {
|
||||
/*
|
||||
* in this case the PBX did not read our hangup control frame
|
||||
* so we must hangup the channel!
|
||||
*/
|
||||
if ( (i->owner) && (state != CAPI_STATE_DISCONNECTED) && (state != CAPI_STATE_INCALL) &&
|
||||
(state != CAPI_STATE_DISCONNECTING) && (ast_check_hangup(i->owner) == 0)) {
|
||||
cc_verbose(1, 0, VERBOSE_PREFIX_3 "%s: soft hangup by capi\n",
|
||||
i->name);
|
||||
chan_to_softhangup = i->owner;
|
||||
} else {
|
||||
/* dont ever hangup while hanging up! */
|
||||
/* cc_log(LOG_NOTICE,"no soft hangup by capi\n"); */
|
||||
}
|
||||
}
|
||||
|
||||
if (state == CAPI_STATE_DISCONNECTING) {
|
||||
interface_cleanup(i);
|
||||
} else {
|
||||
local_queue_frame(i, &fr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -3816,11 +3668,8 @@ static void capi_handle_msg(_cmsg *CMSG)
|
|||
i->PLCI = PLCI;
|
||||
} else {
|
||||
/* here, something has to be done --> */
|
||||
struct ast_frame fr;
|
||||
fr.frametype = AST_FRAME_CONTROL;
|
||||
fr.subclass = AST_CONTROL_BUSY;
|
||||
fr.datalen = 0;
|
||||
pipe_frame(i, &fr);
|
||||
struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_BUSY, };
|
||||
local_queue_frame(i, &fr);
|
||||
}
|
||||
break;
|
||||
case CAPI_P_CONF(CONNECT_B3):
|
||||
|
|
|
@ -247,15 +247,11 @@ struct cc_capi_gains {
|
|||
/* ! Private data for a capi device */
|
||||
struct capi_pvt {
|
||||
cc_mutex_t lock;
|
||||
int fd;
|
||||
int fd2;
|
||||
|
||||
char name[CAPI_MAX_STRING];
|
||||
|
||||
/*! Channel we belong to, possibly NULL */
|
||||
struct ast_channel *owner;
|
||||
/*! Frame */
|
||||
struct ast_frame fr;
|
||||
|
||||
/* capi message number */
|
||||
_cword MessageNumber;
|
||||
|
|
Loading…
Reference in New Issue