~damg/ubuntu/quantal/asterisk/LP1097687

« back to all changes in this revision

Viewing changes to channels/chan_dahdi.c

  • Committer: Bazaar Package Importer
  • Author(s): Lorenzo De Liso
  • Date: 2010-10-15 22:24:34 UTC
  • mfrom: (1.2.8 upstream) (8.3.8 sid)
  • Revision ID: james.westby@ubuntu.com-20101015222434-iy328q8in3lajzlv
Tags: 1:1.6.2.9-2ubuntu1
* Merge from debian unstable, remaining changes:
  - debian/control:
    + Build-depend on hardening-wrapper
    + Change Maintainer
    + Removed Uploaders field.
    + Removed Debian Vcs-Svn entry and replaced with ubuntu-voip Vcs-Bzr,
      to reflect divergence in packages.
  - debian/rules: Make use of hardening-wrapper
  - debian/asterisk.init: chown /dev/dahdi
  - debian/backports/hardy: add file
  - debian/backports/asterisk.init.hardy: add file
 

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
 
49
49
#include "asterisk.h"
50
50
 
51
 
ASTERISK_FILE_VERSION(__FILE__, "$Revision: 253595 $")
 
51
ASTERISK_FILE_VERSION(__FILE__, "$Revision: 265615 $")
52
52
 
53
53
#if defined(__NetBSD__) || defined(__FreeBSD__)
54
54
#include <pthread.h>
762
762
        /*! \brief TRUE if dynamic faxbuffers are configured for use, default is OFF */
763
763
        unsigned int usefaxbuffers:1;
764
764
        /*! \brief TRUE while dynamic faxbuffers are in use */
765
 
        unsigned int faxbuffersinuse:1;
 
765
        unsigned int bufferoverrideinuse:1;
766
766
        /*! \brief TRUE if over a radio and dahdi_read() has been called. */
767
767
        unsigned int firstradio:1;
768
768
        /*!
1396
1396
static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
1397
1397
static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen);
1398
1398
static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len);
 
1399
static int dahdi_func_write(struct ast_channel *chan, const char *function, char *data, const char *value);
1399
1400
static struct dahdi_pvt *handle_init_event(struct dahdi_pvt *i, int event);
1400
1401
 
1401
1402
static const struct ast_channel_tech dahdi_tech = {
1417
1418
        .fixup = dahdi_fixup,
1418
1419
        .setoption = dahdi_setoption,
1419
1420
        .func_channel_read = dahdi_func_read,
 
1421
        .func_channel_write = dahdi_func_write,
1420
1422
};
1421
1423
 
1422
1424
#ifdef HAVE_PRI
4492
4494
                        p->dsp = NULL;
4493
4495
                }
4494
4496
 
4495
 
                if (p->faxbuffersinuse) {
 
4497
                if (p->bufferoverrideinuse) {
4496
4498
                        /* faxbuffers are in use, revert them */
4497
4499
                        struct dahdi_bufferinfo bi = {
4498
4500
                                .txbufpolicy = p->buf_policy,
4505
4507
                        if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
4506
4508
                                ast_log(LOG_WARNING, "Channel '%s' unable to revert faxbuffer policy: %s\n", ast->name, strerror(errno));
4507
4509
                        }
4508
 
                        p->faxbuffersinuse = 0;
 
4510
                        p->bufferoverrideinuse = 0;
4509
4511
                }
4510
4512
 
4511
4513
                law = DAHDI_LAW_DEFAULT;
5016
5018
        case AST_OPTION_ECHOCAN:
5017
5019
                cp = (char *) data;
5018
5020
                if (*cp) {
5019
 
                        ast_debug(1, "Enabling echo cancelation on %s\n", chan->name);
 
5021
                        ast_debug(1, "Enabling echo cancellation on %s\n", chan->name);
5020
5022
                        dahdi_enable_ec(p);
5021
5023
                } else {
5022
 
                        ast_debug(1, "Disabling echo cancelation on %s\n", chan->name);
 
5024
                        ast_debug(1, "Disabling echo cancellation on %s\n", chan->name);
5023
5025
                        dahdi_disable_ec(p);
5024
5026
                }
5025
5027
                break;
5032
5034
static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
5033
5035
{
5034
5036
        struct dahdi_pvt *p = chan->tech_pvt;
 
5037
        int res = 0;
5035
5038
 
5036
5039
        if (!strcasecmp(data, "rxgain")) {
5037
5040
                ast_mutex_lock(&p->lock);
5043
5046
                ast_mutex_unlock(&p->lock);
5044
5047
        } else {
5045
5048
                ast_copy_string(buf, "", len);
5046
 
        }
 
5049
                res = -1;
 
5050
        }
 
5051
 
 
5052
        return res;
 
5053
}
 
5054
 
 
5055
 
 
5056
static int parse_buffers_policy(const char *parse, int *num_buffers, int *policy)
 
5057
{
 
5058
        int res;
 
5059
        char policy_str[21] = "";
 
5060
        
 
5061
        if (((res = sscanf(parse, "%d,%20s", num_buffers, policy_str)) != 2) &&
 
5062
                ((res = sscanf(parse, "%d|%20s", num_buffers, policy_str)) != 2)) {
 
5063
                ast_log(LOG_WARNING, "Parsing buffer string '%s' failed.\n", parse);
 
5064
                return 1;
 
5065
        }
 
5066
        if (*num_buffers < 0) {
 
5067
                ast_log(LOG_WARNING, "Invalid buffer count given '%d'.\n", *num_buffers);
 
5068
                return -1;
 
5069
        }
 
5070
        if (!strcasecmp(policy_str, "full")) {
 
5071
                *policy = DAHDI_POLICY_WHEN_FULL;
 
5072
        } else if (!strcasecmp(policy_str, "immediate")) {
 
5073
                *policy = DAHDI_POLICY_IMMEDIATE;
 
5074
#ifdef DAHDI_POLICY_HALF_FULL
 
5075
        } else if (!strcasecmp(policy_str, "half")) {
 
5076
                *policy = DAHDI_POLICY_HALF_FULL;
 
5077
#endif
 
5078
        } else {
 
5079
                ast_log(LOG_WARNING, "Invalid policy name given '%s'.\n", policy_str);
 
5080
                return -1;
 
5081
        }
 
5082
 
5047
5083
        return 0;
5048
5084
}
5049
5085
 
 
5086
static int dahdi_func_write(struct ast_channel *chan, const char *function, char *data, const char *value)
 
5087
{
 
5088
        struct dahdi_pvt *p = chan->tech_pvt;
 
5089
        int res = 0;
 
5090
 
 
5091
        if (!strcasecmp(data, "buffers")) {
 
5092
                int num_bufs, policy;
 
5093
 
 
5094
                if (!(parse_buffers_policy(value, &num_bufs, &policy))) {
 
5095
                        struct dahdi_bufferinfo bi = {
 
5096
                                .txbufpolicy = policy,
 
5097
                                .rxbufpolicy = policy,
 
5098
                                .bufsize = p->bufsize,
 
5099
                                .numbufs = num_bufs,
 
5100
                        };
 
5101
                        int bpres;
 
5102
 
 
5103
                        if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
 
5104
                                ast_log(LOG_WARNING, "Channel '%d' unable to override buffer policy: %s\n", p->channel, strerror(errno));
 
5105
                        } else {
 
5106
                                p->bufferoverrideinuse = 1;
 
5107
                        }
 
5108
                } else {
 
5109
                        res = -1;
 
5110
                }
 
5111
        } else {
 
5112
                res = -1;
 
5113
        }
 
5114
 
 
5115
        return res;
 
5116
}
5050
5117
 
5051
5118
static void dahdi_unlink(struct dahdi_pvt *slave, struct dahdi_pvt *master, int needlock)
5052
5119
{
5177
5244
 
5178
5245
#ifdef PRI_2BCT
5179
5246
        int triedtopribridge = 0;
5180
 
        q931_call *q931c0 = NULL, *q931c1 = NULL;
5181
5247
#endif
5182
5248
 
5183
5249
        /* For now, don't attempt to native bridge if either channel needs DTMF detection.
5394
5460
                }
5395
5461
 
5396
5462
#ifdef PRI_2BCT
5397
 
                q931c0 = p0->call;
5398
 
                q931c1 = p1->call;
5399
 
                if (p0->transfer && p1->transfer
5400
 
                        && q931c0 && q931c1
5401
 
                        && !triedtopribridge) {
5402
 
                        pri_channel_bridge(q931c0, q931c1);
 
5463
                if (!triedtopribridge) {
5403
5464
                        triedtopribridge = 1;
 
5465
                        if (p0->pri && p0->pri == p1->pri && p0->transfer && p1->transfer) {
 
5466
                                ast_mutex_lock(&p0->pri->lock);
 
5467
                                if (p0->call && p1->call) {
 
5468
                                        pri_channel_bridge(p0->call, p1->call);
 
5469
                                }
 
5470
                                ast_mutex_unlock(&p0->pri->lock);
 
5471
                        }
5404
5472
                }
5405
5473
#endif
5406
5474
 
5642
5710
                /* Fax tone -- Handle and return NULL */
5643
5711
                if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) {
5644
5712
                        /* If faxbuffers are configured, use them for the fax transmission */
5645
 
                        if (p->usefaxbuffers && !p->faxbuffersinuse) {
 
5713
                        if (p->usefaxbuffers && !p->bufferoverrideinuse) {
5646
5714
                                struct dahdi_bufferinfo bi = {
5647
5715
                                        .txbufpolicy = p->faxbuf_policy,
5648
5716
                                        .bufsize = p->bufsize,
5653
5721
                                if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
5654
5722
                                        ast_log(LOG_WARNING, "Channel '%s' unable to set faxbuffer policy, reason: %s\n", ast->name, strerror(errno));
5655
5723
                                } else {
5656
 
                                        p->faxbuffersinuse = 1;
 
5724
                                        p->bufferoverrideinuse = 1;
5657
5725
                                }
5658
5726
                        }
5659
5727
                        p->faxhandled = 1;
6738
6806
 
6739
6807
        /* Hang up if we don't really exist */
6740
6808
        if (idx < 0)    {
6741
 
                ast_log(LOG_WARNING, "We dont exist?\n");
 
6809
                ast_log(LOG_WARNING, "We don't exist?\n");
6742
6810
                ast_mutex_unlock(&p->lock);
6743
6811
                return NULL;
6744
6812
        }
8381
8449
                        if (p->cid_signalling == CID_SIG_DTMF) {
8382
8450
                                int k = 0;
8383
8451
                                cs = NULL;
8384
 
                                ast_debug(1, "Receiving DTMF cid on "
8385
 
                                        "channel %s\n", chan->name);
 
8452
                                ast_debug(1, "Receiving DTMF cid on channel %s\n", chan->name);
8386
8453
                                dahdi_setlinear(p->subs[idx].dfd, 0);
8387
 
                                res = 2000;
 
8454
                                /*
 
8455
                                 * We are the only party interested in the Rx stream since
 
8456
                                 * we have not answered yet.  We don't need or even want DTMF
 
8457
                                 * emulation.  The DTMF digits can come so fast that emulation
 
8458
                                 * can drop some of them.
 
8459
                                 */
 
8460
                                ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY);
 
8461
                                res = 4000;/* This is a typical OFF time between rings. */
8388
8462
                                for (;;) {
8389
8463
                                        struct ast_frame *f;
8390
8464
                                        res = ast_waitfor(chan, res);
8391
8465
                                        if (res <= 0) {
 
8466
                                                /*
 
8467
                                                 * We do not need to restore the dahdi_setlinear()
 
8468
                                                 * or AST_FLAG_END_DTMF_ONLY flag settings since we
 
8469
                                                 * are hanging up the channel.
 
8470
                                                 */
8392
8471
                                                ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
8393
8472
                                                        "Exiting simple switch\n");
8394
8473
                                                ast_hangup(chan);
8398
8477
                                        if (!f)
8399
8478
                                                break;
8400
8479
                                        if (f->frametype == AST_FRAME_DTMF) {
8401
 
                                                dtmfbuf[k++] = f->subclass;
 
8480
                                                if (k < ARRAY_LEN(dtmfbuf) - 1) {
 
8481
                                                        dtmfbuf[k++] = f->subclass;
 
8482
                                                }
8402
8483
                                                ast_debug(1, "CID got digit '%c'\n", f->subclass);
8403
 
                                                res = 2000;
 
8484
                                                res = 4000;/* This is a typical OFF time between rings. */
8404
8485
                                        }
8405
8486
                                        ast_frfree(f);
8406
8487
                                        if (chan->_state == AST_STATE_RING ||
8407
8488
                                                chan->_state == AST_STATE_RINGING)
8408
8489
                                                break; /* Got ring */
8409
8490
                                }
 
8491
                                ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
8410
8492
                                dtmfbuf[k] = '\0';
8411
8493
                                dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
8412
8494
                                /* Got cid and ring. */
8413
8495
                                ast_debug(1, "CID got string '%s'\n", dtmfbuf);
8414
8496
                                callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
8415
 
                                ast_debug(1, "CID is '%s', flags %d\n",
8416
 
                                        dtmfcid, flags);
 
8497
                                ast_debug(1, "CID is '%s', flags %d\n", dtmfcid, flags);
8417
8498
                                /* If first byte is NULL, we have no cid */
8418
8499
                                if (!ast_strlen_zero(dtmfcid))
8419
8500
                                        number = dtmfcid;
8473
8554
                                                        } else {
8474
8555
                                                                res = callerid_feed(cs, buf, res, AST_LAW(p));
8475
8556
                                                        }
8476
 
 
8477
8557
                                                        if (res < 0) {
8478
 
                                                                ast_log(LOG_WARNING, "CallerID feed failed on channel '%s'\n", chan->name);
 
8558
                                                                /*
 
8559
                                                                 * The previous diagnostic message output likely
 
8560
                                                                 * explains why it failed.
 
8561
                                                                 */
 
8562
                                                                ast_log(LOG_WARNING,
 
8563
                                                                        "Failed to decode CallerID on channel '%s'\n",
 
8564
                                                                        chan->name);
8479
8565
                                                                break;
8480
8566
                                                        } else if (res)
8481
8567
                                                                break;
8491
8577
                                        if (p->cid_signalling == CID_SIG_V23_JP) {
8492
8578
                                                res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
8493
8579
                                                usleep(1);
8494
 
                                                res = 4000;
8495
 
                                        } else {
8496
 
 
8497
 
                                                /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
8498
 
                                                res = 2000;
8499
8580
                                        }
8500
8581
 
 
8582
                                        /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
 
8583
                                        res = 4000;/* This is a typical OFF time between rings. */
8501
8584
                                        for (;;) {
8502
8585
                                                struct ast_frame *f;
8503
8586
                                                res = ast_waitfor(chan, res);
8740
8823
                                                        samples += res;
8741
8824
                                                        res = callerid_feed(cs, buf, res, AST_LAW(p));
8742
8825
                                                        if (res < 0) {
8743
 
                                                                ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
 
8826
                                                                /*
 
8827
                                                                 * The previous diagnostic message output likely
 
8828
                                                                 * explains why it failed.
 
8829
                                                                 */
 
8830
                                                                ast_log(LOG_WARNING,
 
8831
                                                                        "Failed to decode CallerID on channel '%s'\n",
 
8832
                                                                        chan->name);
8744
8833
                                                                break;
8745
8834
                                                        } else if (res)
8746
8835
                                                                break;
9017
9106
                        samples += res;
9018
9107
                        if (!spill_done) {
9019
9108
                                if ((spill_result = callerid_feed(cs, mtd->buf, res, AST_LAW(mtd->pvt))) < 0) {
9020
 
                                        ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
 
9109
                                        /*
 
9110
                                         * The previous diagnostic message output likely
 
9111
                                         * explains why it failed.
 
9112
                                         */
 
9113
                                        ast_log(LOG_WARNING, "Failed to decode CallerID\n");
9021
9114
                                        break;
9022
9115
                                } else if (spill_result) {
9023
9116
                                        spill_done = 1;
10444
10537
                tmp->adsi = conf->chan.adsi;
10445
10538
                tmp->use_smdi = conf->chan.use_smdi;
10446
10539
                tmp->permhidecallerid = conf->chan.hidecallerid;
 
10540
                tmp->hidecalleridname = conf->chan.hidecalleridname;
10447
10541
                tmp->callreturn = conf->chan.callreturn;
10448
10542
                tmp->echocancel = conf->chan.echocancel;
10449
10543
                tmp->echotraining = conf->chan.echotraining;
15573
15667
                return CLI_SUCCESS;
15574
15668
        }
15575
15669
        if (linksets[span-1].ss7) {
15576
 
                if (strcasecmp(a->argv[3], "on")) {
 
15670
                if (!strcasecmp(a->argv[3], "on")) {
15577
15671
                        ss7_set_debug(linksets[span-1].ss7, SS7_DEBUG_MTP2 | SS7_DEBUG_MTP3 | SS7_DEBUG_ISUP);
15578
15672
                        ast_cli(a->fd, "Enabled debugging on linkset %d\n", span);
15579
15673
                } else {
16146
16240
                                        return -1;
16147
16241
                        ast_log(LOG_DEBUG, "Channel '%s' configured.\n", v->value);
16148
16242
                } else if (!strcasecmp(v->name, "buffers")) {
16149
 
                        int res;
16150
 
                        char policy[21] = "";
16151
 
 
16152
 
                        res = sscanf(v->value, "%30d,%20s", &confp->chan.buf_no, policy);
16153
 
                        if (res != 2) {
16154
 
                                ast_log(LOG_WARNING, "Parsing buffers option data failed, using defaults.\n");
16155
 
                                confp->chan.buf_no = numbufs;
16156
 
                                continue;
16157
 
                        }
16158
 
                        if (confp->chan.buf_no < 0)
16159
 
                                confp->chan.buf_no = numbufs;
16160
 
                        if (!strcasecmp(policy, "full")) {
16161
 
                                confp->chan.buf_policy = DAHDI_POLICY_WHEN_FULL;
16162
 
                        } else if (!strcasecmp(policy, "immediate")) {
 
16243
                        if (parse_buffers_policy(v->value, &confp->chan.buf_no, &confp->chan.buf_policy)) {
 
16244
                                ast_log(LOG_WARNING, "Using default buffer policy.\n");
 
16245
                                confp->chan.buf_no = numbufs;
16163
16246
                                confp->chan.buf_policy = DAHDI_POLICY_IMMEDIATE;
16164
 
#ifdef HAVE_DAHDI_HALF_FULL
16165
 
                        } else if (!strcasecmp(policy, "half_full")) {
16166
 
                                confp->chan.buf_policy = DAHDI_POLICY_HALF_FULL;
16167
 
#endif
16168
 
                        } else {
16169
 
                                ast_log(LOG_WARNING, "Invalid policy name given (%s).\n", policy);
16170
16247
                        }
16171
16248
                } else if (!strcasecmp(v->name, "faxbuffers")) {
16172
 
                        int res;
16173
 
                        char policy[21] = "";
16174
 
 
16175
 
                        res = sscanf(v->value, "%30d,%20s", &confp->chan.faxbuf_no, policy);
16176
 
                        if (res != 2) {
16177
 
                                ast_log(LOG_WARNING, "Parsing faxbuffers option data failed, using defaults.\n");
16178
 
                                confp->chan.faxbuf_no = numbufs;
16179
 
                                continue;
16180
 
                        }
16181
 
                        confp->chan.usefaxbuffers = 1;
16182
 
                        if (confp->chan.faxbuf_no < 0)
16183
 
                                confp->chan.faxbuf_no = numbufs;
16184
 
                        if (!strcasecmp(policy, "full")) {
16185
 
                                confp->chan.faxbuf_policy = DAHDI_POLICY_WHEN_FULL;
16186
 
                        } else if (!strcasecmp(policy, "immediate")) {
16187
 
                                confp->chan.faxbuf_policy = DAHDI_POLICY_IMMEDIATE;
16188
 
                        } else {
16189
 
                                ast_log(LOG_WARNING, "Invalid policy name given (%s).\n", policy);
16190
 
                                confp->chan.usefaxbuffers = 0;
16191
 
                        }
16192
 
                } else if (!strcasecmp(v->name, "dahdichan")) {
 
16249
                        if (!parse_buffers_policy(v->value, &confp->chan.faxbuf_no, &confp->chan.faxbuf_policy)) {
 
16250
                                confp->chan.usefaxbuffers = 1;
 
16251
                        }
 
16252
                } else if (!strcasecmp(v->name, "dahdichan")) {
16193
16253
                        ast_copy_string(dahdichan, v->value, sizeof(dahdichan));
16194
16254
                } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
16195
16255
                        usedistinctiveringdetection = ast_true(v->value);
17247
17307
                        ast_mutex_unlock(&iflock);
17248
17308
                        ast_config_destroy(cfg);
17249
17309
                        if (ucfg) {
17250
 
                                ast_config_destroy(cfg);
 
17310
                                ast_config_destroy(ucfg);
17251
17311
                        }
17252
17312
                        return res;
17253
17313
                }