~damg/ubuntu/quantal/asterisk/LP1097687

« back to all changes in this revision

Viewing changes to .pc/dahdi-fxsks-hookstate/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
4330
4332
 
4331
4333
        idx = dahdi_get_index(ast, p, 1);
4332
4334
 
4333
 
        if ((p->sig == SIG_PRI) || (p->sig == SIG_SS7) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP)) {
 
4335
        switch (p->sig) {
 
4336
        case SIG_PRI:
 
4337
        case SIG_BRI:
 
4338
        case SIG_BRI_PTMP:
 
4339
        case SIG_SS7:
4334
4340
                x = 1;
4335
4341
                ast_channel_setoption(ast,AST_OPTION_AUDIO_MODE,&x,sizeof(char),0);
 
4342
                /* Fall through */
 
4343
        case SIG_MFCR2:
4336
4344
                p->cid_num[0] = '\0';
4337
4345
                p->cid_name[0] = '\0';
 
4346
                break;
 
4347
        default:
 
4348
                break;
4338
4349
        }
4339
4350
 
4340
4351
        x = 0;
4483
4494
                        p->dsp = NULL;
4484
4495
                }
4485
4496
 
4486
 
                if (p->faxbuffersinuse) {
 
4497
                if (p->bufferoverrideinuse) {
4487
4498
                        /* faxbuffers are in use, revert them */
4488
4499
                        struct dahdi_bufferinfo bi = {
4489
4500
                                .txbufpolicy = p->buf_policy,
4496
4507
                        if ((bpres = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
4497
4508
                                ast_log(LOG_WARNING, "Channel '%s' unable to revert faxbuffer policy: %s\n", ast->name, strerror(errno));
4498
4509
                        }
4499
 
                        p->faxbuffersinuse = 0;
 
4510
                        p->bufferoverrideinuse = 0;
4500
4511
                }
4501
4512
 
4502
4513
                law = DAHDI_LAW_DEFAULT;
4529
4540
                }
4530
4541
#endif
4531
4542
#ifdef HAVE_OPENR2
4532
 
                p->cid_num[0] = '\0';
4533
 
                p->cid_name[0] = '\0';
4534
4543
                if (p->mfcr2 && p->mfcr2call && openr2_chan_get_direction(p->r2chan) != OR2_DIR_STOPPED) {
4535
4544
                        ast_log(LOG_DEBUG, "disconnecting MFC/R2 call on chan %d\n", p->channel);
4536
4545
                        /* If it's an incoming call, check the mfcr2_forced_release setting */
5025
5034
static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
5026
5035
{
5027
5036
        struct dahdi_pvt *p = chan->tech_pvt;
 
5037
        int res = 0;
5028
5038
 
5029
5039
        if (!strcasecmp(data, "rxgain")) {
5030
5040
                ast_mutex_lock(&p->lock);
5036
5046
                ast_mutex_unlock(&p->lock);
5037
5047
        } else {
5038
5048
                ast_copy_string(buf, "", len);
5039
 
        }
 
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
 
5040
5083
        return 0;
5041
5084
}
5042
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
}
5043
5117
 
5044
5118
static void dahdi_unlink(struct dahdi_pvt *slave, struct dahdi_pvt *master, int needlock)
5045
5119
{
5170
5244
 
5171
5245
#ifdef PRI_2BCT
5172
5246
        int triedtopribridge = 0;
5173
 
        q931_call *q931c0 = NULL, *q931c1 = NULL;
5174
5247
#endif
5175
5248
 
5176
5249
        /* For now, don't attempt to native bridge if either channel needs DTMF detection.
5387
5460
                }
5388
5461
 
5389
5462
#ifdef PRI_2BCT
5390
 
                q931c0 = p0->call;
5391
 
                q931c1 = p1->call;
5392
 
                if (p0->transfer && p1->transfer
5393
 
                        && q931c0 && q931c1
5394
 
                        && !triedtopribridge) {
5395
 
                        pri_channel_bridge(q931c0, q931c1);
 
5463
                if (!triedtopribridge) {
5396
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
                        }
5397
5472
                }
5398
5473
#endif
5399
5474
 
5635
5710
                /* Fax tone -- Handle and return NULL */
5636
5711
                if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) {
5637
5712
                        /* If faxbuffers are configured, use them for the fax transmission */
5638
 
                        if (p->usefaxbuffers && !p->faxbuffersinuse) {
 
5713
                        if (p->usefaxbuffers && !p->bufferoverrideinuse) {
5639
5714
                                struct dahdi_bufferinfo bi = {
5640
5715
                                        .txbufpolicy = p->faxbuf_policy,
5641
5716
                                        .bufsize = p->bufsize,
5646
5721
                                if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
5647
5722
                                        ast_log(LOG_WARNING, "Channel '%s' unable to set faxbuffer policy, reason: %s\n", ast->name, strerror(errno));
5648
5723
                                } else {
5649
 
                                        p->faxbuffersinuse = 1;
 
5724
                                        p->bufferoverrideinuse = 1;
5650
5725
                                }
5651
5726
                        }
5652
5727
                        p->faxhandled = 1;
6068
6143
                                        p->subs[idx].f.frametype = AST_FRAME_CONTROL;
6069
6144
                                        p->subs[idx].f.subclass = AST_CONTROL_ANSWER;
6070
6145
                                        /* Make sure it stops ringing */
 
6146
                                        p->subs[SUB_REAL].needringing = 0;
6071
6147
                                        dahdi_set_hook(p->subs[idx].dfd, DAHDI_OFFHOOK);
6072
6148
                                        ast_debug(1, "channel %d answered\n", p->channel);
6073
6149
                                        if (p->cidspill) {
8373
8449
                        if (p->cid_signalling == CID_SIG_DTMF) {
8374
8450
                                int k = 0;
8375
8451
                                cs = NULL;
8376
 
                                ast_debug(1, "Receiving DTMF cid on "
8377
 
                                        "channel %s\n", chan->name);
 
8452
                                ast_debug(1, "Receiving DTMF cid on channel %s\n", chan->name);
8378
8453
                                dahdi_setlinear(p->subs[idx].dfd, 0);
8379
 
                                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. */
8380
8462
                                for (;;) {
8381
8463
                                        struct ast_frame *f;
8382
8464
                                        res = ast_waitfor(chan, res);
8383
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
                                                 */
8384
8471
                                                ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
8385
8472
                                                        "Exiting simple switch\n");
8386
8473
                                                ast_hangup(chan);
8390
8477
                                        if (!f)
8391
8478
                                                break;
8392
8479
                                        if (f->frametype == AST_FRAME_DTMF) {
8393
 
                                                dtmfbuf[k++] = f->subclass;
 
8480
                                                if (k < ARRAY_LEN(dtmfbuf) - 1) {
 
8481
                                                        dtmfbuf[k++] = f->subclass;
 
8482
                                                }
8394
8483
                                                ast_debug(1, "CID got digit '%c'\n", f->subclass);
8395
 
                                                res = 2000;
 
8484
                                                res = 4000;/* This is a typical OFF time between rings. */
8396
8485
                                        }
8397
8486
                                        ast_frfree(f);
8398
8487
                                        if (chan->_state == AST_STATE_RING ||
8399
8488
                                                chan->_state == AST_STATE_RINGING)
8400
8489
                                                break; /* Got ring */
8401
8490
                                }
 
8491
                                ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
8402
8492
                                dtmfbuf[k] = '\0';
8403
8493
                                dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
8404
8494
                                /* Got cid and ring. */
8405
8495
                                ast_debug(1, "CID got string '%s'\n", dtmfbuf);
8406
8496
                                callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
8407
 
                                ast_debug(1, "CID is '%s', flags %d\n",
8408
 
                                        dtmfcid, flags);
 
8497
                                ast_debug(1, "CID is '%s', flags %d\n", dtmfcid, flags);
8409
8498
                                /* If first byte is NULL, we have no cid */
8410
8499
                                if (!ast_strlen_zero(dtmfcid))
8411
8500
                                        number = dtmfcid;
8465
8554
                                                        } else {
8466
8555
                                                                res = callerid_feed(cs, buf, res, AST_LAW(p));
8467
8556
                                                        }
8468
 
 
8469
8557
                                                        if (res < 0) {
8470
 
                                                                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);
8471
8565
                                                                break;
8472
8566
                                                        } else if (res)
8473
8567
                                                                break;
8483
8577
                                        if (p->cid_signalling == CID_SIG_V23_JP) {
8484
8578
                                                res = dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_ONHOOK);
8485
8579
                                                usleep(1);
8486
 
                                                res = 4000;
8487
 
                                        } else {
8488
 
 
8489
 
                                                /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
8490
 
                                                res = 2000;
8491
8580
                                        }
8492
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. */
8493
8584
                                        for (;;) {
8494
8585
                                                struct ast_frame *f;
8495
8586
                                                res = ast_waitfor(chan, res);
8732
8823
                                                        samples += res;
8733
8824
                                                        res = callerid_feed(cs, buf, res, AST_LAW(p));
8734
8825
                                                        if (res < 0) {
8735
 
                                                                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);
8736
8833
                                                                break;
8737
8834
                                                        } else if (res)
8738
8835
                                                                break;
9009
9106
                        samples += res;
9010
9107
                        if (!spill_done) {
9011
9108
                                if ((spill_result = callerid_feed(cs, mtd->buf, res, AST_LAW(mtd->pvt))) < 0) {
9012
 
                                        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");
9013
9114
                                        break;
9014
9115
                                } else if (spill_result) {
9015
9116
                                        spill_done = 1;
10436
10537
                tmp->adsi = conf->chan.adsi;
10437
10538
                tmp->use_smdi = conf->chan.use_smdi;
10438
10539
                tmp->permhidecallerid = conf->chan.hidecallerid;
 
10540
                tmp->hidecalleridname = conf->chan.hidecalleridname;
10439
10541
                tmp->callreturn = conf->chan.callreturn;
10440
10542
                tmp->echocancel = conf->chan.echocancel;
10441
10543
                tmp->echotraining = conf->chan.echotraining;
10502
10604
                ast_copy_string(tmp->context, conf->chan.context, sizeof(tmp->context));
10503
10605
                ast_copy_string(tmp->parkinglot, conf->chan.parkinglot, sizeof(tmp->parkinglot));
10504
10606
                tmp->cid_ton = 0;
10505
 
                if ((tmp->sig != SIG_PRI) || (tmp->sig != SIG_SS7) || (tmp->sig != SIG_BRI) || (tmp->sig != SIG_BRI_PTMP) || (tmp->sig != SIG_MFCR2)) {
 
10607
                switch (tmp->sig) {
 
10608
                case SIG_PRI:
 
10609
                case SIG_BRI:
 
10610
                case SIG_BRI_PTMP:
 
10611
                case SIG_SS7:
 
10612
                case SIG_MFCR2:
 
10613
                        tmp->cid_num[0] = '\0';
 
10614
                        tmp->cid_name[0] = '\0';
 
10615
                        break;
 
10616
                default:
10506
10617
                        ast_copy_string(tmp->cid_num, conf->chan.cid_num, sizeof(tmp->cid_num));
10507
10618
                        ast_copy_string(tmp->cid_name, conf->chan.cid_name, sizeof(tmp->cid_name));
10508
 
                } else {
10509
 
                        tmp->cid_num[0] = '\0';
10510
 
                        tmp->cid_name[0] = '\0';
 
10619
                        break;
10511
10620
                }
10512
10621
                ast_copy_string(tmp->mailbox, conf->chan.mailbox, sizeof(tmp->mailbox));
10513
10622
                if (channel != CHAN_PSEUDO && !ast_strlen_zero(tmp->mailbox)) {
15552
15661
                return CLI_SUCCESS;
15553
15662
        }
15554
15663
        if (linksets[span-1].ss7) {
15555
 
                if (strcasecmp(a->argv[3], "on")) {
 
15664
                if (!strcasecmp(a->argv[3], "on")) {
15556
15665
                        ss7_set_debug(linksets[span-1].ss7, SS7_DEBUG_MTP2 | SS7_DEBUG_MTP3 | SS7_DEBUG_ISUP);
15557
15666
                        ast_cli(a->fd, "Enabled debugging on linkset %d\n", span);
15558
15667
                } else {
16125
16234
                                        return -1;
16126
16235
                        ast_log(LOG_DEBUG, "Channel '%s' configured.\n", v->value);
16127
16236
                } else if (!strcasecmp(v->name, "buffers")) {
16128
 
                        int res;
16129
 
                        char policy[21] = "";
16130
 
 
16131
 
                        res = sscanf(v->value, "%30d,%20s", &confp->chan.buf_no, policy);
16132
 
                        if (res != 2) {
16133
 
                                ast_log(LOG_WARNING, "Parsing buffers option data failed, using defaults.\n");
16134
 
                                confp->chan.buf_no = numbufs;
16135
 
                                continue;
16136
 
                        }
16137
 
                        if (confp->chan.buf_no < 0)
16138
 
                                confp->chan.buf_no = numbufs;
16139
 
                        if (!strcasecmp(policy, "full")) {
16140
 
                                confp->chan.buf_policy = DAHDI_POLICY_WHEN_FULL;
16141
 
                        } else if (!strcasecmp(policy, "immediate")) {
 
16237
                        if (parse_buffers_policy(v->value, &confp->chan.buf_no, &confp->chan.buf_policy)) {
 
16238
                                ast_log(LOG_WARNING, "Using default buffer policy.\n");
 
16239
                                confp->chan.buf_no = numbufs;
16142
16240
                                confp->chan.buf_policy = DAHDI_POLICY_IMMEDIATE;
16143
 
#ifdef HAVE_DAHDI_HALF_FULL
16144
 
                        } else if (!strcasecmp(policy, "half_full")) {
16145
 
                                confp->chan.buf_policy = DAHDI_POLICY_HALF_FULL;
16146
 
#endif
16147
 
                        } else {
16148
 
                                ast_log(LOG_WARNING, "Invalid policy name given (%s).\n", policy);
16149
16241
                        }
16150
16242
                } else if (!strcasecmp(v->name, "faxbuffers")) {
16151
 
                        int res;
16152
 
                        char policy[21] = "";
16153
 
 
16154
 
                        res = sscanf(v->value, "%30d,%20s", &confp->chan.faxbuf_no, policy);
16155
 
                        if (res != 2) {
16156
 
                                ast_log(LOG_WARNING, "Parsing faxbuffers option data failed, using defaults.\n");
16157
 
                                confp->chan.faxbuf_no = numbufs;
16158
 
                                continue;
16159
 
                        }
16160
 
                        confp->chan.usefaxbuffers = 1;
16161
 
                        if (confp->chan.faxbuf_no < 0)
16162
 
                                confp->chan.faxbuf_no = numbufs;
16163
 
                        if (!strcasecmp(policy, "full")) {
16164
 
                                confp->chan.faxbuf_policy = DAHDI_POLICY_WHEN_FULL;
16165
 
                        } else if (!strcasecmp(policy, "immediate")) {
16166
 
                                confp->chan.faxbuf_policy = DAHDI_POLICY_IMMEDIATE;
16167
 
                        } else {
16168
 
                                ast_log(LOG_WARNING, "Invalid policy name given (%s).\n", policy);
16169
 
                                confp->chan.usefaxbuffers = 0;
16170
 
                        }
16171
 
                } else if (!strcasecmp(v->name, "dahdichan")) {
 
16243
                        if (!parse_buffers_policy(v->value, &confp->chan.faxbuf_no, &confp->chan.faxbuf_policy)) {
 
16244
                                confp->chan.usefaxbuffers = 1;
 
16245
                        }
 
16246
                } else if (!strcasecmp(v->name, "dahdichan")) {
16172
16247
                        ast_copy_string(dahdichan, v->value, sizeof(dahdichan));
16173
16248
                } else if (!strcasecmp(v->name, "usedistinctiveringdetection")) {
16174
16249
                        usedistinctiveringdetection = ast_true(v->value);
17225
17300
                        ast_mutex_unlock(&iflock);
17226
17301
                        ast_config_destroy(cfg);
17227
17302
                        if (ucfg) {
17228
 
                                ast_config_destroy(cfg);
 
17303
                                ast_config_destroy(ucfg);
17229
17304
                        }
17230
17305
                        return res;
17231
17306
                }