{
ftdm_status_t status;
ftdm_sigmsg_t sig;
- ftdm_channel_t *peerchan = ftdmchan->call_data;
pritap_t *pritap = ftdmchan->span->signal_data;
pritap_t *peer_pritap = pritap->peerspan->signal_data;
{
ftdm_channel_t *fchan = ftdmchan;
- ftdmchan->call_data = NULL;
- ftdmchan->pflags = 0;
- ftdm_channel_close(&fchan);
+ /* Destroy the peer data first */
+ if (fchan->call_data) {
+ ftdm_channel_t *peerchan = fchan->call_data;
+ ftdm_channel_t *pchan = peerchan;
- if (peerchan) {
- peerchan->call_data = NULL;
- peerchan->pflags = 0;
- ftdm_channel_close(&peerchan);
+ ftdm_channel_lock(peerchan);
+
+ pchan->call_data = NULL;
+ pchan->pflags = 0;
+ ftdm_channel_close(&pchan);
+
+ ftdm_channel_unlock(peerchan);
} else {
- ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Odd, no peer chan\n");
+ ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "No call data?\n");
}
+
+ ftdmchan->call_data = NULL;
+ ftdmchan->pflags = 0;
+ ftdm_channel_close(&fchan);
}
break;
static __inline__ ftdm_channel_t *tap_pri_get_fchan(pritap_t *pritap, passive_call_t *pcall, int channel)
{
ftdm_channel_t *fchan = NULL;
+ int err = 0;
int chanpos = PRI_CHANNEL(channel);
if (!chanpos || chanpos > pritap->span->chan_count) {
ftdm_log(FTDM_LOG_CRIT, "Invalid pri tap channel %d requested in span %s\n", channel, pritap->span->name);
}
fchan = pritap->span->channels[PRI_CHANNEL(channel)];
+
+ ftdm_channel_lock(fchan);
+
if (ftdm_test_flag(fchan, FTDM_CHANNEL_INUSE)) {
ftdm_log(FTDM_LOG_ERROR, "Channel %d requested in span %s is already in use!\n", channel, pritap->span->name);
- return NULL;
+ err = 1;
+ goto done;
}
if (ftdm_channel_open_chan(fchan) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Could not open tap channel %d requested in span %s\n", channel, pritap->span->name);
- return NULL;
+ err = 1;
+ goto done;
}
memset(&fchan->caller_data, 0, sizeof(fchan->caller_data));
ftdm_set_string(fchan->caller_data.ani.digits, pcall->callingani.digits);
ftdm_set_string(fchan->caller_data.dnis.digits, pcall->callednum.digits);
+done:
+ if (fchan) {
+ ftdm_channel_unlock(fchan);
+ }
+
+ if (err) {
+ return NULL;
+ }
+
return fchan;
}
pcall->fchan = fchan;
peerpcall->fchan = fchan;
+ ftdm_log_chan(fchan, FTDM_LOG_NOTICE, "Starting new tapped call with callref %d\n", crv);
+
+ ftdm_channel_lock(fchan);
fchan->call_data = peerfchan;
+ ftdm_set_state(fchan, FTDM_CHANNEL_STATE_RING);
+ ftdm_channel_unlock(fchan);
+
+ ftdm_channel_lock(peerfchan);
peerfchan->call_data = fchan;
+ ftdm_channel_unlock(peerfchan);
- ftdm_log_chan(pcall->fchan, FTDM_LOG_NOTICE, "Starting new tapped call with callref %d\n", crv);
- ftdm_set_state_locked(fchan, FTDM_CHANNEL_STATE_RING);
break;
case PRI_EVENT_ANSWER:
case PRI_EVENT_HANGUP_REQ:
crv = tap_pri_get_crv(pritap->pri, e->hangup.call);
- ftdm_log(FTDM_LOG_DEBUG, "Hangup on channel %s:%d:%d with callref %d\n",
+
+ ftdm_log(FTDM_LOG_DEBUG, "Hangup on channel %s:%d:%d with callref %d\n",
pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), crv);
if (!(pcall = tap_pri_get_pcall_bycrv(pritap, crv))) {