While working on a healthcare app called Simple at my previous company, we wanted to improve how nurses follow up with their patients. The aim was to replace traditional paper registers + landline phones with the app, which could intelligently suggest patients who are potentially at risk based on their medical history, age, and other important cues.
For protecting their privacy, we needed to route their phone calls through a proxy so that their personal numbers stayed hidden from their patients. This is referred to as “phone number masking” and is commonly used these days. When you take a ride with Uber, or order food with Zomato, both you and your driver/rider are assigned temporary numbers for privacy for the duration of the trip/task. When your driver dials your proxy number, Uber forwards the call to your actual phone number.
The plan was similar for Simple, but there was one problem with this approach: talking to the server required an internet connection. We wanted to keep Simple offline-first. While it’s nice to have a data connection, it was important for the app’s functionality to not degrade when a connection is unavailable, especially in remote villages.
We needed a way to send data to our server without an internet connection. A team member came up with this fantastic idea of using DTMF tones!
DTMF stands for Dual Tone – Multi Frequency. It’s the tone your phone plays when you press a number on the dial-pad during an ongoing phone call. Each number is assigned a combination of two sine waves for identifying its row and column indices on the dial-pad.
Turns out, DTMF tones are great. They are easy to implement and most communication-as-a-service platforms support them out of the box. On Android, DTMF tones can be played using a call Intent:
<span class="token keyword">val</span> dtmfTones <span class="token operator">=</span> patientNumber <span class="token operator">+</span> <span class="token string">"#"</span>
<span class="token keyword">val</span> numberToCall <span class="token operator">=</span> tollFreeNumber <span class="token operator">+</span> <span class="token string">","</span> <span class="token operator">+</span> dtmfTones
<span class="token keyword">val</span> numberUri <span class="token operator">=</span> Uri<span class="token punctuation">.</span><span class="token function">fromParts</span><span class="token punctuation">(</span><span class="token string">"tel"</span><span class="token punctuation">,</span> phoneNumber<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span>
context<span class="token punctuation">.</span><span class="token function">startActivity</span><span class="token punctuation">(</span><span class="token function">Intent</span><span class="token punctuation">(</span>Intent<span class="token punctuation">.</span>ACTION_CALL<span class="token punctuation">,</span> numberUri<span class="token punctuation">)</span>
When a nurse clicks a patient’s call button, the app dials our toll-free number and plays the patient’s number as DTMF tones. The server receives the patient’s number through Twilio (which does the job of decoding DTMF tones) and in turn, connects the nurse with the intended patient.
Here’s what the call sounds like:
It would have been nice if we could customize how DTMF tones are encoded because playing a phone number takes quite long, but it’s alright considering they’ll only be used when an internet connection is unavailable.
By now you’ve probably realized why this technology feels so familiar.
If you’re still not convinced that DTMF tones are cool then let me introduce you to “phone phreaking”: Before They Created Apple, Jobs And Wozniak Hacked The Phone System | FiveThirtyEight.
Exercise for the reader
If 1800-XXX-XXXX
is your network company’s customer support number and 9
is the number you press on the dialpad after hearing a recorded message for 20s to reach a human, what happens if you dial 1800-XXX-XXXX,9
directly? The dialer may not let you enter a comma, but you can work around this by saving the number as a contact. I tested this with my network carrier, Fido, but your mileage may vary.
Cover photo by Akshay Verma.