MF Signalling History

MF Signalling was used mainly in the early days of digital and electromechanical telecommunications switching systems, as a means of signalling in between pieces of equipment. Such as sending the information for call routing from an operator to a long distance switching system. The difference between MF tones, and the previous most common forms of dial signalling, is that MF tones, could easily be sent through voice traffic, because the tones are in the AF (Audible Frequency) range, which the entire telephone system was built around. All of the other standards of signalling at the time relied on electrical signals, such as off-hook supervision, like pulse dialing, which rapidly pulsed the number being dialed by basically putting the phone on-hook for a fraction of a second, and then taking it back off-hook. This new form of signalling was revolutionary because it could make its way easily through things such as repeater buildings, on long distance circuits, and soon become the standard for tandem switching signalling. Once your call was placed, it would go through your local Central Office (AKA, The Originating Office), your local switch would see that you are placing a long distance call and would route to a long distance trunk. I am not going to get into trunk selection, because I don't fully understand it, and it's a completely different scope from this topic. Anyways, your local switch would pickup a local MF sender, pickup a line of another switch, which could either be the End Office switch (AKA, the switch that hosts the called party) or, would call into another tandem switch, then send an MF Tone sequence for routing information. The called switch, would either connect you to the called party (if it was an End Office switch), or call out one of it's trunks to another switch, and so on, until reaching the End Office.

Here is a video explaining MF signalling in better detail, and more accurately, than my little description above. Note, this is not my video, it was create by the Connections Museum, in Seattle, WA. They are a great source of information on older telecommunications equipment. Check out their youtube channel!

Why use MF signalling in Asterisk?

To be truthful, it's not needed. You really don't need to use MF signalling in Asterisk. But it's cool! That's why! But, in all seriousness, the everyday person would not need MF signalling. However, there is definitely some special applications, where you would. For example, MF tones are still used in backend telecommunications trunking, most of the time, the tones are muted, so you, the calling party, can't here them. Another very important use of MF signalling in Asterisk, is for interfacing with existing equipment. Such as interfacing with an MF receiver on an older electromechanical switching system. But in the real world, outside of these special uses, MF signalling isn't a necessary requirement of Asterisk. It's the sad truth.

Prerequisites

To use MF signalling in Asterisk, your going to need ProjectMF 2.0. To install ProjectMF2, follow the steps below. Link to ProjectMF2.0 github
  1. Download the ProjectMF2 files to a working directory. Enter wget https://github.com/npstn-soft/ProjectMF2.0/archive/refs/heads/master.zip
  2. Unzip the file using unzip ProjectMF2.0-master
  3. Enter the directory cd ProjectMF2.0-master
  4. Move important files mv mf.conf /etc/asterisk and then mv confbridge.conf /etc/asterisk
  5. Then, move the detect folder, mv detect /etc/asterisk
  6. Proceed to enter the detect folder in the Asterisk directory cd /etc/asterisk/detect
  7. Make the uncompiled code make
  8. Set permissions by chmod a+x mf followed by chmod a+x mf2
  9. Finally, include the "mf.conf" file at the top of your dialplan, by editing your dialplan, and pasting include "mf.conf"

MF Main Arguments

I'll quickly go over the "mfmain" subroutine's arguments, as they can be useful.

MF Main Example
exten => s,1,Gosub(mfmain,s,1(A,B,C,D,E))
  • A=(0/or register map exten), This is used to tell mfmain if it should stay local, or try to dial out using one of the register map extensions. If not 0, it will attempt to dial out the register map.
  • B=(0/1), This tells "mfmain" if you want to use a local MF sender. Basically telling "mfmain" if you want to send tones, or let something else do it. Note, if you want an external piece of equipment do it, you must disable "FAM" or "Forward Audio Mute"
  • C=(0/1), Forward Audio Mute Enable/Disable. Preferred to leave it enabled, so that way line noise won't effect signalling.
  • D=(X!), This tells the local MF sender what digits to send. If using an MF receiver only, leave this blank. Note, this automatically adds "KP" and "ST" to the beginning and end of your sequence.
  • E=(context), This tells "mfmain" what context to send the call if being used as an MF register. It removes the "KP" and "ST" from the decoded data, and will send it directly to the decoded extension at the listed context, with a priority of 1.

Using ProjectMF to generate MF tones

To get started, you need to find an extensions where you would like to pickup either an MF register, or a local MF sender. There is two ways to generate MF tones in Asterisk. Either, by using the "mfer" subroutine, which generates MF tones, and then returns, or "mfmain", which is preffered. "mfmain" can act either as an MF sender, an MF register, and can execute other functions. It's the main subroutine of ProjectMF2.0. It can also call into an MF receiver via the "register map". The register map, holds many extensions with directions telling Asterisk how to dial into an MF receiver. Below are some examples of "mfer" vs. "mfmain".

MF Main Example
exten => s,1,Gosub(mfmain,s,1(23,0,0,13044517075))
same => n,Hangup()

The above code sends the call to extension 23 of the register map, then proceeds to send MF tones of "KP + 1 304 451 7075 + ST" There is no need to indicate KP or ST in ProjectMF2.0, as it already has KP/ST hardcoded into it.

MFer Example
exten => s,1,Gosub(mfer,start,1(13044517075))
As you can see above it's a lot simpler, and so is it's fucntions. All the "mfer" subroutine does, is just sends the MF tone sequence specified in "${ARG1}", aka the first argument given to the subroutine. Doesn't attempt to call anyone, or anything fancy, just MF tones, thats it. So why use "mfmain" over "mfer", if they both send MF tones, and this one is less fancy. Well, the main thing, is that "mfmain" can enable a feature called "FAM" or "Forward Audio Mute", basically, a fancy way of preventing people from the ability to "phreak" or "bluebox" your MF receivers. It also, makes you code look a lot cleaner when you call one subroutine instead of trying to add "FAM" and dial out to your MF receiver inside of your extension. Just makes life cleaner, and easier, so use "mfmain".

Using ProjectMF2.0 to receive MF tones

This is complicated. Not in the way you have to call the subroutine, and that is all it is, a subroutine, but you have to have the general knowledge of how Asterisk works, because this is the part you have to kind of create yourself. You have to create a path to your MF register from the MF sender, if you are using "mfmain", which you should be, you have to create an IAX2 user, or some sort of SIP trunk, or some way of routing your call from one switch/extension to the receiver. And that can be complicated. So, I am not going to get into how to create an IAX2 user, or anything like that, but I will explain on how to make a subroutine that goes to an MF receiver. MF Receiver Example
[main]
exten => 13044517075,1,Progress()
same => n,Playback(nnis,noanswer)
same => n,Hangup()

[from-wherever]
exten => _X!,1,Gosub(mfmain,s,1(0,1,1,,main))
same => n,Hangup

As you can see from above, the "from-wherever" matches to any extension, so it will always route to "mfmain". Given MF mains arguments, it will pickup a local MF receiver, allow forward audio, and sends whatever MF tones it receives to that extension at "main" context. Basically, the tones it receives will be routed to the "main" context. Making it super easy to receive the tones. The only complication is in figuring out how to make a phone call in-between the switches. Which, is luckily up to you. That's your job.

Adding Extensions to the Register Map

To add users to the register map, you just have to edit "mf.conf", and find the [register_map] context. You just need to add an extension, and your code to dial into a remote switch. Below is an example of the register map to call into a remote switch via IAX2 using the "incoming" user. All of that information would be set inside of "iax.conf".

IAX2 Example:
[register_map]
exten => 22,1,Dial(IAX2/incoming@testswitch.com/${EXTEN})

Wise Words

And that's it! You've used ProjectMF2.0 for sending/receiving MF tone sequences! Congratulations, now adapt this to your Asterisk system. I hope you found this article useful on how to use ProjectMF2.0. The documentation on the github can be a little bit confusing. I hope I did a semi-okay job of explaining things in a little bit more detail.

WARNING! DO NOT JUST COPY AND PASTE THE ABOVE CODE EXAMPLES (BESIDES THE INSTALL). BY USING THE ABOVE EXAMPLES, YOU MAY BE PUTTING YOUR ASTERISK SWITCH AT A SEVERE SECURITY RISK. THE ABOVE EXMAPLES ARE MADE FOR READABILITY, A LOT OF IMPORTANT SECURITY STEPS WERE GLOSSED OVER IN THE EXAMPLE CODE BLOCKS TO KEEP THE CODE EASILY READABLE. IF YOU COPY THIS GUIDE, YOU DO SO AT YOUR OWN RISK, I AM NOT RESPONSIBLE FOR ANY DAMAGES.

Written by Jaiden Borich - 2022