ftmod_misdn: Rework mISDN channel de-/activation.
Remove the 'state' variable of per-channel data, use active flag exclusively to track open/close state. Add misdn_activate_channel()/misdn_deactivate_channel() helper functions, rename old one to _misdn_toggle_channel() (internal). Add _nowait variant of channel de-/activation function, that just sends the mISDN request message. Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
This commit is contained in:
parent
890ecc6d45
commit
7d0dcb6175
|
@ -245,14 +245,10 @@ struct misdn_span_private {
|
|||
pthread_cond_t event_cond;
|
||||
};
|
||||
|
||||
#define MISDN_CHAN_STATE_CLOSED 0
|
||||
#define MISDN_CHAN_STATE_OPEN 1
|
||||
|
||||
struct misdn_event_queue;
|
||||
|
||||
struct misdn_chan_private {
|
||||
/* */
|
||||
int state;
|
||||
int debugfd;
|
||||
int active;
|
||||
|
||||
|
@ -470,7 +466,50 @@ static inline int ts_before(struct timespec *a, struct timespec *b)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static ftdm_status_t misdn_activate_channel(ftdm_channel_t *chan, int activate)
|
||||
/*
|
||||
* Asynchronous channel (de-)activation
|
||||
*/
|
||||
static ftdm_status_t _misdn_toggle_channel_nowait(ftdm_channel_t *chan, int activate)
|
||||
{
|
||||
struct misdn_chan_private *priv = ftdm_chan_io_private(chan);
|
||||
char buf[MAX_DATA_MEM] = { 0 };
|
||||
struct mISDNhead *hh = (struct mISDNhead *) buf;
|
||||
int retval;
|
||||
|
||||
/* NOTE: sending PH_DEACTIVATE_REQ to closed b-channels kills the d-channel (hfcsusb)... */
|
||||
if ((activate && priv->active) || (!activate && !priv->active))
|
||||
return FTDM_SUCCESS;
|
||||
|
||||
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "mISDN sending %s request\n",
|
||||
(activate) ? "activation" : "deactivation");
|
||||
|
||||
/* prepare + send request primitive */
|
||||
hh->prim = (activate) ? PH_ACTIVATE_REQ : PH_DEACTIVATE_REQ;
|
||||
hh->id = MISDN_ID_ANY;
|
||||
|
||||
if ((retval = sendto(chan->sockfd, hh, sizeof(*hh), 0, NULL, 0)) < sizeof(*hh)) {
|
||||
ftdm_log_chan(chan, FTDM_LOG_ERROR, "mISDN failed to send activation request: %s\n",
|
||||
strerror(errno));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static ftdm_status_t misdn_activate_channel_nowait(ftdm_channel_t *chan)
|
||||
{
|
||||
return _misdn_toggle_channel_nowait(chan, 1);
|
||||
}
|
||||
|
||||
static ftdm_status_t misdn_deactivate_channel_nowait(ftdm_channel_t *chan)
|
||||
{
|
||||
return _misdn_toggle_channel_nowait(chan, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Synchronous channel (de-)activation
|
||||
*/
|
||||
static ftdm_status_t _misdn_toggle_channel(ftdm_channel_t *chan, int activate)
|
||||
{
|
||||
struct misdn_chan_private *priv = ftdm_chan_io_private(chan);
|
||||
char buf[MAX_DATA_MEM] = { 0 };
|
||||
|
@ -590,6 +629,16 @@ out:
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static ftdm_status_t misdn_activate_channel(ftdm_channel_t *chan)
|
||||
{
|
||||
return _misdn_toggle_channel(chan, 1);
|
||||
}
|
||||
|
||||
static ftdm_status_t misdn_deactivate_channel(ftdm_channel_t *chan)
|
||||
{
|
||||
return _misdn_toggle_channel(chan, 0);
|
||||
}
|
||||
|
||||
|
||||
#if 0 /* unused for now */
|
||||
static ftdm_status_t misdn_get_ph_info(ftdm_channel_t *chan, struct ph_info *info)
|
||||
|
@ -917,7 +966,7 @@ static FIO_OPEN_FUNCTION(misdn_open)
|
|||
assert(chan_priv);
|
||||
assert(span_priv);
|
||||
|
||||
if (chan_priv->state == MISDN_CHAN_STATE_OPEN) {
|
||||
if (chan_priv->active) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "mISDN channel is already open, skipping activation\n");
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
@ -928,24 +977,27 @@ static FIO_OPEN_FUNCTION(misdn_open)
|
|||
/*
|
||||
* Send activation request
|
||||
*/
|
||||
ret = misdn_activate_channel(ftdmchan, 1);
|
||||
ret = misdn_activate_channel(ftdmchan);
|
||||
if (ret != FTDM_SUCCESS) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to activate channel (socket: %d)\n",
|
||||
ftdmchan->sockfd);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
/*
|
||||
* Ignore error, ftdm_channel_open() does not correctly handle return FTDM_FAIL cases.
|
||||
* We will try to activate the channel later.
|
||||
*/
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "mISDN channel activation request sent\n");
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "mISDN channel activation request sent\n");
|
||||
|
||||
switch (ftdmchan->type) {
|
||||
case FTDM_CHAN_TYPE_B:
|
||||
case FTDM_CHAN_TYPE_DQ921:
|
||||
chan_priv->state = MISDN_CHAN_STATE_OPEN;
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "mISDN invalid channel type '%s'\n",
|
||||
ftdm_channel_get_type_str(ftdmchan));
|
||||
break;
|
||||
switch (ftdmchan->type) {
|
||||
case FTDM_CHAN_TYPE_B:
|
||||
case FTDM_CHAN_TYPE_DQ921:
|
||||
chan_priv->active = 1;
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "mISDN invalid channel type '%s'\n",
|
||||
ftdm_channel_get_type_str(ftdmchan));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
@ -964,21 +1016,25 @@ static FIO_CLOSE_FUNCTION(misdn_close)
|
|||
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "mISDN trying to close %c-channel\n",
|
||||
ftdm_channel_get_type(ftdmchan) == FTDM_CHAN_TYPE_B ? 'B' : 'D');
|
||||
|
||||
/* deactivate b-channels on close */
|
||||
if (ftdm_channel_get_type(ftdmchan) == FTDM_CHAN_TYPE_B) {
|
||||
/*
|
||||
* Send deactivation request (don't wait for answer)
|
||||
*/
|
||||
ret = misdn_activate_channel(ftdmchan, 0);
|
||||
if (chan_priv->active) {
|
||||
|
||||
if (ftdm_channel_get_type(ftdmchan) == FTDM_CHAN_TYPE_B) {
|
||||
ret = misdn_deactivate_channel(ftdmchan);
|
||||
} else {
|
||||
/* Don't wait for D-Channel deactivation */
|
||||
ret = misdn_deactivate_channel_nowait(ftdmchan);
|
||||
}
|
||||
|
||||
if (ret != FTDM_SUCCESS) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to deactivate %c-channel\n",
|
||||
ftdm_channel_get_type(ftdmchan) == FTDM_CHAN_TYPE_B ? 'B' : 'D');
|
||||
return FTDM_FAIL;
|
||||
/* Ignore error, channel might be closed already */
|
||||
} else {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "mISDN %c-channel deactivated\n",
|
||||
ftdm_channel_get_type(ftdmchan) == FTDM_CHAN_TYPE_B ? 'B' : 'D');
|
||||
}
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "mISDN %c-channel deactivated\n",
|
||||
ftdm_channel_get_type(ftdmchan) == FTDM_CHAN_TYPE_B ? 'B' : 'D');
|
||||
chan_priv->state = MISDN_CHAN_STATE_CLOSED;
|
||||
chan_priv->active = 0;
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
|
@ -1214,7 +1270,7 @@ static FIO_READ_FUNCTION(misdn_read)
|
|||
int retval;
|
||||
int maxretry = 10;
|
||||
|
||||
if (priv->state == MISDN_CHAN_STATE_CLOSED) {
|
||||
if (!priv->active) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "mISDN ignoring read on closed channel\n");
|
||||
/* ignore */
|
||||
*datalen = 0;
|
||||
|
@ -1369,6 +1425,13 @@ static FIO_WRITE_FUNCTION(misdn_write)
|
|||
|
||||
switch (ftdm_channel_get_type(ftdmchan)) {
|
||||
case FTDM_CHAN_TYPE_B:
|
||||
/*
|
||||
* Check state, send activation request (async) if channel is not open
|
||||
*/
|
||||
if (!priv->active) {
|
||||
misdn_activate_channel_nowait(ftdmchan);
|
||||
return FTDM_SUCCESS; /* eat data */
|
||||
}
|
||||
/*
|
||||
* Write to audio pipe, misdn_read() will pull
|
||||
* from there as needed and send it to the b-channel
|
||||
|
@ -1393,6 +1456,17 @@ static FIO_WRITE_FUNCTION(misdn_write)
|
|||
memcpy(wbuf + MISDN_HEADER_LEN, data, size);
|
||||
size += MISDN_HEADER_LEN;
|
||||
|
||||
/*
|
||||
* Check state, send activation request (sync) if channel is not open
|
||||
*/
|
||||
if (!priv->active) {
|
||||
retval = misdn_activate_channel(ftdmchan);
|
||||
if (retval) {
|
||||
*datalen = 0;
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/* wait for channel to get ready */
|
||||
wflags = FTDM_WRITE;
|
||||
retval = misdn_wait(ftdmchan, &wflags, 20);
|
||||
|
@ -1563,7 +1637,7 @@ static ftdm_status_t misdn_open_range(ftdm_span_t *span, ftdm_chan_type_t type,
|
|||
|
||||
} else {
|
||||
/* early activate D-Channel */
|
||||
misdn_activate_channel(ftdmchan, 1);
|
||||
misdn_activate_channel(ftdmchan);
|
||||
ftdmchan->native_codec = ftdmchan->effective_codec = FTDM_CODEC_NONE;
|
||||
}
|
||||
num_configured++;
|
||||
|
|
Loading…
Reference in New Issue