diff options
author | dvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-05-17 13:01:39 +0000 |
---|---|---|
committer | dvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-05-17 13:01:39 +0000 |
commit | 6af339856937b17bb30e805d2e9ca809296500fe (patch) | |
tree | c1912b401005e7aefbb69114e95393e1176529de /channels | |
parent | d2397e65bc74ed89f518e6f8dcbac1a2d3cf5250 (diff) |
backport of DAHDI buffer policy dial string option
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@263292 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_dahdi.c | 121 |
1 files changed, 100 insertions, 21 deletions
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index 5582ae5de..835df5b87 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -439,6 +439,7 @@ static struct dahdi_pvt { struct dahdi_pvt *master; /*!< Master to us (we follow their conferencing) */ int inconference; /*!< If our real should be in the conference */ + int bufsize; /*!< Size of the buffers */ int buf_no; /*!< Number of buffers */ int buf_policy; /*!< Buffer policy */ int sig; /*!< Signalling style */ @@ -535,6 +536,8 @@ static struct dahdi_pvt { unsigned int echocanon:1; /*! \brief TRUE if a fax tone has already been handled. */ unsigned int faxhandled:1; + /*!< TRUE while buffer configuration override is in use. */ + unsigned int bufferoverrideinuse:1; /*! \brief TRUE if over a radio and dahdi_read() has been called. */ unsigned int firstradio:1; /*! @@ -968,7 +971,7 @@ static struct dahdi_chan_conf dahdi_chan_conf_default(void) { .sendcalleridafter = DEFAULT_CIDRINGS, .buf_policy = DAHDI_POLICY_IMMEDIATE, - .buf_no = numbufs + .buf_no = numbufs, }, .timing = { .prewinktime = -1, @@ -1001,6 +1004,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, char *function, char *data, char *buf, size_t len); +static int dahdi_func_write(struct ast_channel *chan, char *function, char *data, const char *value); static const struct ast_channel_tech dahdi_tech = { .type = "DAHDI", @@ -1021,6 +1025,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, }; static const struct ast_channel_tech zap_tech = { @@ -2971,6 +2976,22 @@ static int dahdi_hangup(struct ast_channel *ast) p->dsp = NULL; } + if (p->bufferoverrideinuse) { + /* faxbuffers are in use, revert them */ + struct dahdi_bufferinfo bi = { + .txbufpolicy = p->buf_policy, + .rxbufpolicy = p->buf_policy, + .bufsize = p->bufsize, + .numbufs = p->buf_no + }; + int bpres; + + 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->bufferoverrideinuse = 0; + } + law = DAHDI_LAW_DEFAULT; res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law); if (res < 0) @@ -3410,6 +3431,7 @@ static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int static int dahdi_func_read(struct ast_channel *chan, 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); @@ -3421,10 +3443,72 @@ static int dahdi_func_read(struct ast_channel *chan, char *function, char *data, 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, 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) { @@ -7967,8 +8051,16 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf, if (res < 0) { ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d: %s\n", channel, strerror(errno)); } - } else + } else { ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d: %s\n", channel, strerror(errno)); + } + tmp->buf_policy = conf->chan.buf_policy; + tmp->buf_no = conf->chan.buf_no; + /* This is not as gnarly as it may first appear. If the ioctl above failed, we'd be setting + * tmp->bufsize to zero which would cause subsequent faxbuffer-related ioctl calls to fail. + * The reason the ioctl call above failed should to be determined before worrying about the + * faxbuffer-related ioctl calls */ + tmp->bufsize = bi.bufsize; } #endif tmp->immediate = conf->chan.immediate; @@ -11430,30 +11522,17 @@ static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct iscrv = !strcasecmp(v->name, "crv"); if (build_channels(confp, iscrv, v->value, reload, v->lineno, &found_pseudo)) return -1; - } 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) - 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; - } else { - ast_log(LOG_WARNING, "Invalid policy name given (%s).\n", policy); - } } else if (!strcasecmp(v->name, "zapchan") || !strcasecmp(v->name, "dahdichan")) { ast_copy_string(dahdichan, v->value, sizeof(dahdichan)); if (v->name[0] == 'z' || v->name[0] == 'Z') { ast_log(LOG_WARNING, "Option zapchan has been deprecated in favor of dahdichan (found in [%s])\n", cat); } + } else if (!strcasecmp(v->name, "buffers")) { + 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; + confp->chan.buf_policy = DAHDI_POLICY_IMMEDIATE; + } } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) { if (ast_true(v->value)) confp->chan.usedistinctiveringdetection = 1; |