- changed locking in hangup which might caused race-condition
This commit is contained in:
parent
8365b305c5
commit
2f3a449f5b
59
chan_capi.c
59
chan_capi.c
|
@ -1023,21 +1023,12 @@ static void send_progress(struct capi_pvt *i)
|
||||||
/*
|
/*
|
||||||
* hangup a line (CAPI messages)
|
* hangup a line (CAPI messages)
|
||||||
*/
|
*/
|
||||||
static void capi_activehangup(struct ast_channel *c)
|
static void capi_activehangup(struct ast_channel *c, int state)
|
||||||
{
|
{
|
||||||
struct capi_pvt *i = CC_CHANNEL_PVT(c);
|
struct capi_pvt *i = CC_CHANNEL_PVT(c);
|
||||||
_cmsg CMSG;
|
_cmsg CMSG;
|
||||||
int state;
|
|
||||||
const char *cause;
|
const char *cause;
|
||||||
|
|
||||||
if (i == NULL) {
|
|
||||||
cc_log(LOG_WARNING, "No interface!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
state = i->state;
|
|
||||||
i->state = CAPI_STATE_DISCONNECTING;
|
|
||||||
|
|
||||||
i->cause = c->hangupcause;
|
i->cause = c->hangupcause;
|
||||||
if ((cause = pbx_builtin_getvar_helper(c, "PRI_CAUSE"))) {
|
if ((cause = pbx_builtin_getvar_helper(c, "PRI_CAUSE"))) {
|
||||||
i->cause = atoi(cause);
|
i->cause = atoi(cause);
|
||||||
|
@ -1087,6 +1078,7 @@ static int pbx_capi_hangup(struct ast_channel *c)
|
||||||
{
|
{
|
||||||
struct capi_pvt *i = CC_CHANNEL_PVT(c);
|
struct capi_pvt *i = CC_CHANNEL_PVT(c);
|
||||||
int cleanup = 0;
|
int cleanup = 0;
|
||||||
|
int state;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* hmm....ok...this is called to free the capi interface (passive disconnect)
|
* hmm....ok...this is called to free the capi interface (passive disconnect)
|
||||||
|
@ -1098,40 +1090,46 @@ static int pbx_capi_hangup(struct ast_channel *c)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cc_mutex_lock(&i->lock);
|
||||||
|
|
||||||
|
state = i->state;
|
||||||
|
|
||||||
cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: CAPI Hangingup for PLCI=%#x in state %d\n",
|
cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: CAPI Hangingup for PLCI=%#x in state %d\n",
|
||||||
i->vname, i->PLCI, i->state);
|
i->vname, i->PLCI, state);
|
||||||
|
|
||||||
/* are we down, yet? */
|
/* are we down, yet? */
|
||||||
if (i->state != CAPI_STATE_DISCONNECTED) {
|
if (state != CAPI_STATE_DISCONNECTED) {
|
||||||
/* no */
|
/* no */
|
||||||
capi_activehangup(c);
|
i->state = CAPI_STATE_DISCONNECTING;
|
||||||
} else {
|
} else {
|
||||||
cleanup = 1;
|
cleanup = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ast_update_use_count();
|
||||||
|
|
||||||
|
CC_CHANNEL_PVT(c) = NULL;
|
||||||
|
ast_setstate(c, AST_STATE_DOWN);
|
||||||
|
|
||||||
if ((i->doDTMF > 0) && (i->vad != NULL)) {
|
if ((i->doDTMF > 0) && (i->vad != NULL)) {
|
||||||
ast_dsp_free(i->vad);
|
ast_dsp_free(i->vad);
|
||||||
i->vad = NULL;
|
i->vad = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_mutex_lock(&usecnt_lock);
|
|
||||||
usecnt--;
|
|
||||||
cc_mutex_unlock(&usecnt_lock);
|
|
||||||
|
|
||||||
ast_update_use_count();
|
|
||||||
|
|
||||||
cc_mutex_lock(&i->lock);
|
|
||||||
|
|
||||||
CC_CHANNEL_PVT(c) = NULL;
|
|
||||||
ast_setstate(c, AST_STATE_DOWN);
|
|
||||||
|
|
||||||
if (cleanup) {
|
if (cleanup) {
|
||||||
/* disconnect already done, so cleanup */
|
/* disconnect already done, so cleanup */
|
||||||
interface_cleanup(i);
|
interface_cleanup(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_mutex_unlock(&i->lock);
|
cc_mutex_unlock(&i->lock);
|
||||||
|
|
||||||
|
if (!cleanup) {
|
||||||
|
/* not disconnected yet, we must actively do it */
|
||||||
|
capi_activehangup(c, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_mutex_lock(&usecnt_lock);
|
||||||
|
usecnt--;
|
||||||
|
cc_mutex_unlock(&usecnt_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1237,8 +1235,6 @@ static int pbx_capi_call(struct ast_channel *c, char *idest, int timeout)
|
||||||
cc_copy_string(buffer, idest, sizeof(buffer));
|
cc_copy_string(buffer, idest, sizeof(buffer));
|
||||||
parse_dialstring(buffer, &interface, &dest, ¶m, &ocid);
|
parse_dialstring(buffer, &interface, &dest, ¶m, &ocid);
|
||||||
|
|
||||||
cc_mutex_lock(&i->lock);
|
|
||||||
|
|
||||||
/* init param settings */
|
/* init param settings */
|
||||||
i->doB3 = CAPI_B3_DONT;
|
i->doB3 = CAPI_B3_DONT;
|
||||||
i->doOverlap = 0;
|
i->doOverlap = 0;
|
||||||
|
@ -1275,7 +1271,6 @@ static int pbx_capi_call(struct ast_channel *c, char *idest, int timeout)
|
||||||
}
|
}
|
||||||
if (((!dest) || (!dest[0])) && (i->doB3 != CAPI_B3_ALWAYS)) {
|
if (((!dest) || (!dest[0])) && (i->doB3 != CAPI_B3_ALWAYS)) {
|
||||||
cc_log(LOG_ERROR, "No destination or dialtone requested in '%s'\n", idest);
|
cc_log(LOG_ERROR, "No destination or dialtone requested in '%s'\n", idest);
|
||||||
cc_mutex_unlock(&i->lock);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1289,9 +1284,6 @@ static int pbx_capi_call(struct ast_channel *c, char *idest, int timeout)
|
||||||
i->vname, c->name, i->doB3 ? "with B3 ":" ",
|
i->vname, c->name, i->doB3 ? "with B3 ":" ",
|
||||||
i->doOverlap ? "overlap":"", CLIR, callernplan);
|
i->doOverlap ? "overlap":"", CLIR, callernplan);
|
||||||
|
|
||||||
i->outgoing = 1;
|
|
||||||
i->isdnstate |= CAPI_ISDN_STATE_PBX;
|
|
||||||
|
|
||||||
if ((p = pbx_builtin_getvar_helper(c, "CALLINGSUBADDRESS"))) {
|
if ((p = pbx_builtin_getvar_helper(c, "CALLINGSUBADDRESS"))) {
|
||||||
callingsubaddress[0] = strlen(p) + 1;
|
callingsubaddress[0] = strlen(p) + 1;
|
||||||
callingsubaddress[1] = 0x80;
|
callingsubaddress[1] = 0x80;
|
||||||
|
@ -1359,6 +1351,11 @@ static int pbx_capi_call(struct ast_channel *c, char *idest, int timeout)
|
||||||
bchaninfo[2] = 0x0;
|
bchaninfo[2] = 0x0;
|
||||||
CONNECT_REQ_BCHANNELINFORMATION(&CMSG) = (_cstruct)bchaninfo; /* 0 */
|
CONNECT_REQ_BCHANNELINFORMATION(&CMSG) = (_cstruct)bchaninfo; /* 0 */
|
||||||
|
|
||||||
|
cc_mutex_lock(&i->lock);
|
||||||
|
|
||||||
|
i->outgoing = 1;
|
||||||
|
i->isdnstate |= CAPI_ISDN_STATE_PBX;
|
||||||
|
|
||||||
if ((error = _capi_put_cmsg_wait_conf(i, &CMSG))) {
|
if ((error = _capi_put_cmsg_wait_conf(i, &CMSG))) {
|
||||||
cc_mutex_unlock(&i->lock);
|
cc_mutex_unlock(&i->lock);
|
||||||
return error;
|
return error;
|
||||||
|
|
Loading…
Reference in New Issue