# How to STOP DTMF tones being heard in Bridge

**URL:** <https://community.asterisk.org/t/how-to-stop-dtmf-tones-being-heard-in-bridge/67618>\
**Category:** Asterisk Support\
**Created:** [August 5, 2016, 3:16pm UTC](https://community.asterisk.org/t/how-to-stop-dtmf-tones-being-heard-in-bridge/67618 "2016-08-05T15:16:23Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![dixoncb](https://avatars.discourse-cdn.com/v4/letter/d/74df32/32.png) [@dixoncb](https://community.asterisk.org/u/dixoncb)\
**Post date:** [August 5, 2016, 3:16pm UTC](https://community.asterisk.org/t/how-to-stop-dtmf-tones-being-heard-in-bridge/67618/1 "2016-08-05T15:16:24Z")

</div>

We are using Asterisk 13.8-cert1 on Ubuntu. We are using Stasis, with an external .Net box running the application.

Our application makes extensive use of bridges, and we use a specific DTMF sequence when a participant in the bridge needs help. Our problem is that everyone in the bridge can hear the tones being generated (this seems to be the reverse of most DTMF problems, where the tone is not being picked up). Our bridges are initialised with the mixing,dtmf\_events option.

We’ve tried various combinations in pjsip,.conf for dtmf\_mode (rfc4733, info, inband and auto) and we can still hear the tones.

How can we configure Asterisk running an ARI app so that it picks up the tones, but does not retransmit them?

Colin Dixon

---

<div class="post-metadata">

**Author:** ![mjordan](https://sea1.discourse-cdn.com/asterisk/user_avatar/community.asterisk.org/mjordan/32/1509_2.png) [@mjordan](https://community.asterisk.org/u/mjordan)\
**Post date:** [August 5, 2016, 5:06pm UTC](https://community.asterisk.org/t/how-to-stop-dtmf-tones-being-heard-in-bridge/67618/2 "2016-08-05T17:06:16Z")

</div>

While the bridging framework in Asterisk does have the ability to toggle passthrough of DTMF, it doesn’t expose this ability through ARI. As you’ve discovered, the default is to allow the DTMF to pass through. In order to manipulate this, ARI would have to be updated to expose that either on bridge creation or when a channel is added to a bridge (the DTMF passthrough can be set on a channel-by-channel basis).

---

<div class="post-metadata">

**Author:** ![dixoncb](https://avatars.discourse-cdn.com/v4/letter/d/74df32/32.png) [@dixoncb](https://community.asterisk.org/u/dixoncb)\
**Post date:** [August 5, 2016, 9:13pm UTC](https://community.asterisk.org/t/how-to-stop-dtmf-tones-being-heard-in-bridge/67618/4 "2016-08-05T21:13:04Z")

</div>

Hello Matt, and thank you. Looking through the source, I can see that you are the person to ask!

I’m a C# developer, spending most of my time on .Net WCF apps, but I once was a C++ ATL developer, so I can maybe take a shot at this. I’m happy with Asterisk and compiling from source. Where could I find information about the entry points to the code to make the change, in order to turn off DTMF passthrough universally for an app (or in the worst case, universally. It’s the only app that will be running on the box)?

---

<div class="post-metadata">

**Author:** ![mjordan](https://sea1.discourse-cdn.com/asterisk/user_avatar/community.asterisk.org/mjordan/32/1509_2.png) [@mjordan](https://community.asterisk.org/u/mjordan)\
**Post date:** [August 6, 2016, 3:37am UTC](https://community.asterisk.org/t/how-to-stop-dtmf-tones-being-heard-in-bridge/67618/5 "2016-08-06T03:37:25Z")

</div>

Well, this is an interesting one, since exposing things through ARI has a few hoops to jump through that other parts of Asterisk don’t really have. (They’re good hoops, and they all exist for a reason - but it is a bit more involved.)

Anyway, a few wiki pages you could read up on:

1. [How to write an ARI resource](https://wiki.asterisk.org/wiki/display/AST/Create+a+new+resource+with+ARI) - this is the most appropriate. You won’t need to write an entire resource, but the act of updating an existing resource (in this case, `bridges`) will require a lot of the same steps. I’ll step through it next.
2. When you have a patch that you’d like to contribute back, you’ll want to take a look at the [patch contribution process](https://wiki.asterisk.org/wiki/display/AST/Patch+Contribution+Process). I walked through how to contribute a patch in a series of blog posts on the [Asterisk blog](http://blogs.asterisk.org/2016/01/04/how-to-contribute-to-asterisk-part-one/) awhile back, which may also be helpful (there’s some administrative steps involved).
3. Being aware of the [project coding guidelines](https://wiki.asterisk.org/wiki/display/AST/Coding+Guidelines) is also always good, if for no other reason than it helps you get through [code review](https://wiki.asterisk.org/wiki/display/AST/Code+Review) faster 🙂

Anyway, assuming you have the source code cloned from [Gerrit](https://gerrit.asterisk.org), here’s how I’d approach this particular problem.

- In the Swagger specification - `rest-api/api-docs/bridges.json` - add a new parameter to either bridge creation or adding a channel to a bridge that allows an API user to specify how the DTMF should be passed through. I’d probably do it to `"/bridges/{bridgeId}/addChannel"`, since DTMF absorption is handled on a channel-by-channel basis. Something like:

```auto
			"parameters": [
    				{
    					"name": "bridgeId",
    					"description": "Bridge's id",
    					"paramType": "path",
    					"required": true,
    					"allowMultiple": false,
    					"dataType": "string"
    				},
    				{
    					"name": "channel",
    					"description": "Ids of channels to add to bridge",
    					"paramType": "query",
    					"required": true,
    					"allowMultiple": true,
    					"dataType": "string"
    				},
    				{
    					"name": "role",
    					"description": "Channel's role in the bridge",
    					"paramType": "query",
    					"required": false,
    					"allowMultiple": false,
    					"dataType": "string"
    				},
    				{
    					"name": "absorbDTMF",
    					"description": "Absorb DTMF from this channel, preventing it from passing through the bridge",
    					"paramType": "query",
    					"required": false,
    					"allowMultiple": false,
    					"dataType": "boolean",
    					"defaultValue": false
    				}

```

- Once the Swagger specification has been updated, you can re-generate the HTTP bindings using `make ari-stubs`. This will look at your JSON file and re-build `res/res_ari_bridges.c`, along with `res/ari/resource_bridges.h`. The generated header file defines the API that we have to write ourselves, in this case, `res/ari/resource_bridges.c`. In particular, it will update `struct ast_ari_bridges_add_channel_args` to contain a new parameter, `absorb_dtmf`, that we specified in Swagger. The code in `res_ari_bridges` will handle the HTTP callbacks from Asterisk’s HTTP server, and parse the query parameters into an instance of `ast_ari_bridges_add_channel_args`.

- With the bindings re-generated, we have to implement things in `resource_bridges.c`. Look for `ast_ari_bridges_add_channel`, which starts the process of adding a channel to a bridge. This is where things get tricky: ARI is asynchronous, which we means we have to pass the information from the HTTP callback handler (`ast_ari_bridges_add_channel`) to the thread servicing the channel in the Stasis application. You can see this occurring when `stasis_app_control_add_channel_to_bridge` calls `app_send_command_on_condition`, which passes the `bridge` as the `data` pointer, with `control_add_channel_to_bridge` as the callback that will be executed. While we could wrap both the `bridge` and `absorb_dtmf` value in a new struct, we’re probably better off just storing this on the `stasis_app_control` data structure, as that would allow us to eventually allow other bridge features to be passed in as well. In fact, we could just put a `struct ast_bridge_features` on there.

```auto
struct stasis_app_control {
	...
	struct ast_bridge_features features;
}

```

- Since this is an opaque structure, we’d need to provide our own accessors for it in `res/stasis/control.h`. I’d probably just add something that allows us to set that DTMF should be absorbed, something like `stasis_app_control_absorb_dtmf_in_bridge`.

- Make sure to initialize the bridge features via `ast_bridge_features_init` in `control_create` and destroy them via `ast_bridge_features_cleanup` in `control_dtor`.

- We’d then have something like this in `ast_ari_bridges_add_channel`:

```auto
	for (i = 0; i < list->count; i++) {
		/* role stuff here */
		if (args->absorb_dtmf) {
			stasis_app_control_absorb_dtmf_in_bridge(lists->controls[i]);
		}
	}

	for (i = 0; i < list->count; ++i) {
		if ((has_error = check_add_remove_channel(response, list->controls[i],
			     stasis_app_control_add_channel_to_bridge(
				    list->controls[i], bridge)))) {
			break;
		}
	}

```

- Now we have to make use of this in the Stasis application’s control handler for adding a channel to a bridge. In `res/stasis/control.c`'s `control_swap_channel_in_bridge`, pass the bridge features on the control structure into `ast_bridge_impart`. You can see where that is currently `NULL` in the code today. With it now on the control structure, it would look like this:

```auto
		res = ast_bridge_impart(bridge,
			chan,
			swap,
			control->bridge_features,
			AST_BRIDGE_IMPART_CHAN_DEPARTABLE);

```

I know that’s a lot of moving pieces and parts, but it won’t end up being a _lot_ of code changes - just small ones in a variety of places to get the needed data down into the Stasis control code.

Since I haven’t actually written any of this, you may find that there are some drawbacks or issues with what I suggested, so if your mileage starts to vary, feel free to try something else. You can always reach out on the asterisk-dev mailing list or in #asterisk-dev as well if you’d like, as that’s where questions regarding coding issues are usually asked/answered.

---

<div class="post-metadata">

**Author:** ![dixoncb](https://avatars.discourse-cdn.com/v4/letter/d/74df32/32.png) [@dixoncb](https://community.asterisk.org/u/dixoncb)\
**Post date:** [August 6, 2016, 8:52am UTC](https://community.asterisk.org/t/how-to-stop-dtmf-tones-being-heard-in-bridge/67618/6 "2016-08-06T08:52:37Z")

</div>

I am extremely grateful for this, and looking forward to making an attempt at it. Thank you for taking the time to answer this question so very thoroughly.

Colin Dixon

---

<div class="post-metadata">

**Author:** ![dixoncb](https://avatars.discourse-cdn.com/v4/letter/d/74df32/32.png) [@dixoncb](https://community.asterisk.org/u/dixoncb)\
**Post date:** [August 17, 2016, 6:48pm UTC](https://community.asterisk.org/t/how-to-stop-dtmf-tones-being-heard-in-bridge/67618/7 "2016-08-17T18:48:58Z")

</div>

I had a go at this, and succeeded (up to a point). There is a problem creating the **ast\_bridge\_features** on the **stasis\_app\_control**. All goes well, but when I move the channel from one bridge to another (from ARI, again), execution stops dead in **ast\_bridge\_features\_destroy** (bridge.c) when **ast\_free** is called as part of cleaning up the bridge features prior to the move. I’ve solved the problem by creating a new ast\_bridge\_features in **control\_swap\_channel\_in\_bridge** , and setting the dtmf\_passthrough property there. It’s not elegant, but it works for my use case, in which all conferences can cope without audible DTMF. I guess I could do a deep copy there, but my C is really rusty, and I’d be pushing it.

Thanks again for your help. It was a lot of fun. I’d like to do more of this.

---

<div class="post-metadata">

**Author:** ![eyalhasson](https://avatars.discourse-cdn.com/v4/letter/e/eb9ed0/32.png) [@eyalhasson](https://community.asterisk.org/u/eyalhasson)\
**Post date:** [August 20, 2017, 9:08am UTC](https://community.asterisk.org/t/how-to-stop-dtmf-tones-being-heard-in-bridge/67618/8 "2017-08-20T09:08:51Z")

</div>

Hello all,

I am having the same problem, and I wonder if there is any configuration option that will make a default that all created bridges will not have dtmf pass-through (that will be honored by ARI too, of cource)?

---

<div class="post-metadata">

**Author:** ![ulexus](https://sea1.discourse-cdn.com/asterisk/user_avatar/community.asterisk.org/ulexus/32/2560_2.png) [@ulexus](https://community.asterisk.org/u/ulexus)\
**Post date:** [October 10, 2017, 10:29am UTC](https://community.asterisk.org/t/how-to-stop-dtmf-tones-being-heard-in-bridge/67618/9 "2017-10-10T10:29:15Z")

</div>

Patch is up [here](http://gerrit.asterisk.org/#/c/6675/)

---

<div class="post-metadata">

**Author:** ![ulexus](https://sea1.discourse-cdn.com/asterisk/user_avatar/community.asterisk.org/ulexus/32/2560_2.png) [@ulexus](https://community.asterisk.org/u/ulexus)\
**Post date:** [October 11, 2017, 6:08pm UTC](https://community.asterisk.org/t/how-to-stop-dtmf-tones-being-heard-in-bridge/67618/10 "2017-10-11T18:08:27Z")

</div>

Feature is now in master

---

<div class="post-metadata">

**Author:** ![eyalhasson](https://avatars.discourse-cdn.com/v4/letter/e/eb9ed0/32.png) [@eyalhasson](https://community.asterisk.org/u/eyalhasson)\
**Post date:** [October 21, 2018, 3:11pm UTC](https://community.asterisk.org/t/how-to-stop-dtmf-tones-being-heard-in-bridge/67618/11 "2018-10-21T15:11:19Z")

</div>

Thanks. Which version is it implemented in? Is it turned on by default, or have to be turned on manually?

---

<div class="post-metadata">

**Author:** ![ulexus](https://sea1.discourse-cdn.com/asterisk/user_avatar/community.asterisk.org/ulexus/32/2560_2.png) [@ulexus](https://community.asterisk.org/u/ulexus)\
**Post date:** [October 21, 2018, 7:53pm UTC](https://community.asterisk.org/t/how-to-stop-dtmf-tones-being-heard-in-bridge/67618/12 "2018-10-21T19:53:08Z")

</div>

Dtmf filter is not on by default, but feature is available in Asterisk 16.

---

<div class="post-metadata">

**Author:** ![praiseable](https://avatars.discourse-cdn.com/v4/letter/p/65b543/32.png) [@praiseable](https://community.asterisk.org/u/praiseable)\
**Post date:** [May 18, 2021, 10:41am UTC](https://community.asterisk.org/t/how-to-stop-dtmf-tones-being-heard-in-bridge/67618/13 "2021-05-18T10:41:12Z")

</div>

Code is implemented in nodejs asterisk ARI to use absorbDTMF functionality in birdge

`  
bridge.addChannel({

```
                                        // bridge.AddChannelWithOptions({

                                        channel: [incoming.id, newincoming.id],

                                        absorbDTMF: true,

                                    }`
```
