|
|
|
|
@ -762,7 +762,7 @@ static struct dahdi_pvt {
|
|
|
|
|
/*! \brief TRUE if dynamic faxbuffers are configured for use, default is OFF */
|
|
|
|
|
unsigned int usefaxbuffers:1;
|
|
|
|
|
/*! \brief TRUE while dynamic faxbuffers are in use */
|
|
|
|
|
unsigned int faxbuffersinuse:1;
|
|
|
|
|
unsigned int bufferoverrideinuse:1;
|
|
|
|
|
/*! \brief TRUE if over a radio and dahdi_read() has been called. */
|
|
|
|
|
unsigned int firstradio:1;
|
|
|
|
|
/*!
|
|
|
|
|
@ -1396,6 +1396,7 @@ static int dahdi_indicate(struct ast_channel *chan, int condition, const void *d
|
|
|
|
|
static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
|
|
|
|
|
static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen);
|
|
|
|
|
static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len);
|
|
|
|
|
static int dahdi_func_write(struct ast_channel *chan, const char *function, char *data, const char *value);
|
|
|
|
|
static struct dahdi_pvt *handle_init_event(struct dahdi_pvt *i, int event);
|
|
|
|
|
|
|
|
|
|
static const struct ast_channel_tech dahdi_tech = {
|
|
|
|
|
@ -1417,6 +1418,7 @@ static const struct ast_channel_tech dahdi_tech = {
|
|
|
|
|
.fixup = dahdi_fixup,
|
|
|
|
|
.setoption = dahdi_setoption,
|
|
|
|
|
.func_channel_read = dahdi_func_read,
|
|
|
|
|
.func_channel_write = dahdi_func_write,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_PRI
|
|
|
|
|
@ -4492,7 +4494,7 @@ static int dahdi_hangup(struct ast_channel *ast)
|
|
|
|
|
p->dsp = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (p->faxbuffersinuse) {
|
|
|
|
|
if (p->bufferoverrideinuse) {
|
|
|
|
|
/* faxbuffers are in use, revert them */
|
|
|
|
|
struct dahdi_bufferinfo bi = {
|
|
|
|
|
.txbufpolicy = p->buf_policy,
|
|
|
|
|
@ -4505,7 +4507,7 @@ static int dahdi_hangup(struct ast_channel *ast)
|
|
|
|
|
if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
|
|
|
|
|
ast_log(LOG_WARNING, "Channel '%s' unable to revert faxbuffer policy: %s\n", ast->name, strerror(errno));
|
|
|
|
|
}
|
|
|
|
|
p->faxbuffersinuse = 0;
|
|
|
|
|
p->bufferoverrideinuse = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
law = DAHDI_LAW_DEFAULT;
|
|
|
|
|
@ -5032,6 +5034,7 @@ static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int
|
|
|
|
|
static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
|
|
|
|
|
{
|
|
|
|
|
struct dahdi_pvt *p = chan->tech_pvt;
|
|
|
|
|
int res = 0;
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp(data, "rxgain")) {
|
|
|
|
|
ast_mutex_lock(&p->lock);
|
|
|
|
|
@ -5043,10 +5046,72 @@ static int dahdi_func_read(struct ast_channel *chan, const char *function, char
|
|
|
|
|
ast_mutex_unlock(&p->lock);
|
|
|
|
|
} else {
|
|
|
|
|
ast_copy_string(buf, "", len);
|
|
|
|
|
res = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int parse_buffers_policy(const char *parse, int *num_buffers, int *policy)
|
|
|
|
|
{
|
|
|
|
|
int res;
|
|
|
|
|
char policy_str[21] = "";
|
|
|
|
|
|
|
|
|
|
if (((res = sscanf(parse, "%d,%20s", num_buffers, policy_str)) != 2) &&
|
|
|
|
|
((res = sscanf(parse, "%d|%20s", num_buffers, policy_str)) != 2)) {
|
|
|
|
|
ast_log(LOG_WARNING, "Parsing buffer string '%s' failed.\n", parse);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
if (*num_buffers < 0) {
|
|
|
|
|
ast_log(LOG_WARNING, "Invalid buffer count given '%d'.\n", *num_buffers);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (!strcasecmp(policy_str, "full")) {
|
|
|
|
|
*policy = DAHDI_POLICY_WHEN_FULL;
|
|
|
|
|
} else if (!strcasecmp(policy_str, "immediate")) {
|
|
|
|
|
*policy = DAHDI_POLICY_IMMEDIATE;
|
|
|
|
|
} else if (!strcasecmp(policy_str, "half")) {
|
|
|
|
|
*policy = DAHDI_POLICY_HALF_FULL;
|
|
|
|
|
} else {
|
|
|
|
|
ast_log(LOG_WARNING, "Invalid policy name given '%s'.\n", policy_str);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int dahdi_func_write(struct ast_channel *chan, const char *function, char *data, const char *value)
|
|
|
|
|
{
|
|
|
|
|
struct dahdi_pvt *p = chan->tech_pvt;
|
|
|
|
|
int res = 0;
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp(data, "buffers")) {
|
|
|
|
|
int num_bufs, policy;
|
|
|
|
|
|
|
|
|
|
if (!(parse_buffers_policy(value, &num_bufs, &policy))) {
|
|
|
|
|
struct dahdi_bufferinfo bi = {
|
|
|
|
|
.txbufpolicy = policy,
|
|
|
|
|
.rxbufpolicy = policy,
|
|
|
|
|
.bufsize = p->bufsize,
|
|
|
|
|
.numbufs = num_bufs,
|
|
|
|
|
};
|
|
|
|
|
int bpres;
|
|
|
|
|
|
|
|
|
|
if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
|
|
|
|
|
ast_log(LOG_WARNING, "Channel '%d' unable to override buffer policy: %s\n", p->channel, strerror(errno));
|
|
|
|
|
} else {
|
|
|
|
|
p->bufferoverrideinuse = 1;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
res = -1;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
res = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void dahdi_unlink(struct dahdi_pvt *slave, struct dahdi_pvt *master, int needlock)
|
|
|
|
|
{
|
|
|
|
|
@ -5643,7 +5708,7 @@ static void dahdi_handle_dtmfup(struct ast_channel *ast, int idx, struct ast_fra
|
|
|
|
|
/* Fax tone -- Handle and return NULL */
|
|
|
|
|
if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) {
|
|
|
|
|
/* If faxbuffers are configured, use them for the fax transmission */
|
|
|
|
|
if (p->usefaxbuffers && !p->faxbuffersinuse) {
|
|
|
|
|
if (p->usefaxbuffers && !p->bufferoverrideinuse) {
|
|
|
|
|
struct dahdi_bufferinfo bi = {
|
|
|
|
|
.txbufpolicy = p->faxbuf_policy,
|
|
|
|
|
.bufsize = p->bufsize,
|
|
|
|
|
@ -5654,7 +5719,7 @@ static void dahdi_handle_dtmfup(struct ast_channel *ast, int idx, struct ast_fra
|
|
|
|
|
if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
|
|
|
|
|
ast_log(LOG_WARNING, "Channel '%s' unable to set faxbuffer policy, reason: %s\n", ast->name, strerror(errno));
|
|
|
|
|
} else {
|
|
|
|
|
p->faxbuffersinuse = 1;
|
|
|
|
|
p->bufferoverrideinuse = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
p->faxhandled = 1;
|
|
|
|
|
@ -16167,50 +16232,16 @@ static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct
|
|
|
|
|
return -1;
|
|
|
|
|
ast_log(LOG_DEBUG, "Channel '%s' configured.\n", v->value);
|
|
|
|
|
} else if (!strcasecmp(v->name, "buffers")) {
|
|
|
|
|
int res;
|
|
|
|
|
char policy[21] = "";
|
|
|
|
|
|
|
|
|
|
res = sscanf(v->value, "%30d,%20s", &confp->chan.buf_no, policy);
|
|
|
|
|
if (res != 2) {
|
|
|
|
|
ast_log(LOG_WARNING, "Parsing buffers option data failed, using defaults.\n");
|
|
|
|
|
confp->chan.buf_no = numbufs;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (confp->chan.buf_no < 0)
|
|
|
|
|
if (parse_buffers_policy(v->value, &confp->chan.buf_no, &confp->chan.buf_policy)) {
|
|
|
|
|
ast_log(LOG_WARNING, "Using default buffer policy.\n");
|
|
|
|
|
confp->chan.buf_no = numbufs;
|
|
|
|
|
if (!strcasecmp(policy, "full")) {
|
|
|
|
|
confp->chan.buf_policy = DAHDI_POLICY_WHEN_FULL;
|
|
|
|
|
} else if (!strcasecmp(policy, "immediate")) {
|
|
|
|
|
confp->chan.buf_policy = DAHDI_POLICY_IMMEDIATE;
|
|
|
|
|
#ifdef HAVE_DAHDI_HALF_FULL
|
|
|
|
|
} else if (!strcasecmp(policy, "half_full")) {
|
|
|
|
|
confp->chan.buf_policy = DAHDI_POLICY_HALF_FULL;
|
|
|
|
|
#endif
|
|
|
|
|
} else {
|
|
|
|
|
ast_log(LOG_WARNING, "Invalid policy name given (%s).\n", policy);
|
|
|
|
|
}
|
|
|
|
|
} else if (!strcasecmp(v->name, "faxbuffers")) {
|
|
|
|
|
int res;
|
|
|
|
|
char policy[21] = "";
|
|
|
|
|
|
|
|
|
|
res = sscanf(v->value, "%30d,%20s", &confp->chan.faxbuf_no, policy);
|
|
|
|
|
if (res != 2) {
|
|
|
|
|
ast_log(LOG_WARNING, "Parsing faxbuffers option data failed, using defaults.\n");
|
|
|
|
|
confp->chan.faxbuf_no = numbufs;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
confp->chan.usefaxbuffers = 1;
|
|
|
|
|
if (confp->chan.faxbuf_no < 0)
|
|
|
|
|
confp->chan.faxbuf_no = numbufs;
|
|
|
|
|
if (!strcasecmp(policy, "full")) {
|
|
|
|
|
confp->chan.faxbuf_policy = DAHDI_POLICY_WHEN_FULL;
|
|
|
|
|
} else if (!strcasecmp(policy, "immediate")) {
|
|
|
|
|
confp->chan.faxbuf_policy = DAHDI_POLICY_IMMEDIATE;
|
|
|
|
|
} else {
|
|
|
|
|
ast_log(LOG_WARNING, "Invalid policy name given (%s).\n", policy);
|
|
|
|
|
confp->chan.usefaxbuffers = 0;
|
|
|
|
|
if (!parse_buffers_policy(v->value, &confp->chan.faxbuf_no, &confp->chan.faxbuf_policy)) {
|
|
|
|
|
confp->chan.usefaxbuffers = 1;
|
|
|
|
|
}
|
|
|
|
|
} else if (!strcasecmp(v->name, "dahdichan")) {
|
|
|
|
|
} else if (!strcasecmp(v->name, "dahdichan")) {
|
|
|
|
|
ast_copy_string(dahdichan, v->value, sizeof(dahdichan));
|
|
|
|
|
} else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
|
|
|
|
|
usedistinctiveringdetection = ast_true(v->value);
|
|
|
|
|
|