# How to Make and Take IoT VoIP Calls via Super SIM

Super SIM provides any modem-equipped device with worldwide data connectivity. Once in place, this data channel can be used to send and receive any kind of information — and that includes voice calls.

But while voice apps are ten a penny in mobile operating system app stores, making it easy to try out Super SIM mediated voice-over-data on a phone, how might voice functionality be enabled on an IoT device?

<figure><img src="https://778147064-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuQQbnJlSgjMIxsWK06ol%2Fuploads%2Fn0TNKlfWY21HgYrMKLRK%2Fimage.png?alt=media&#x26;token=749ca099-0c71-4b62-b902-18cb2b467856" alt=""><figcaption></figcaption></figure>

Twilio's Programmable Voice product supports the Session Initiation Protocol (SIP) for starting, maintaining, and ending interactive sessions over IP networks, in particular voice communications sessions. Programmable Voice lets you set up a SIP Domain, which is a unique point of presence that SIP clients — say, a VoIP softphone running on a Super SIM-enabled IoT device — can connect to and call other SIP clients, and phone numbers on public switched telephone networks (PSTNs).

The result: any cellular IoT device fitted with Super SIM and suitable audio IO can participate in voice calls with similar devices and even landlines and mobiles via Twilio and the Internet. Calling is two-way: calls can be made by an IoT device and received by it too.

By way of demonstration, this guide shows you how to set up a Programmable Voice SIP Domain, set up an IoT client device, and connect them. You'll need a Twilio phone number as an entry point for inbound calls and as an outgoing Caller ID. We also make use of another Twilio product, Functions, to provide a basic admin dashboard and allow incoming calls to be routed to specific devices. A [Raspberry Pi single-board computer](https://www.raspberrypi.org/products/raspberry-pi-4-model-b/) stands in as the IoT device.

## 1. Prepare the Pi

First, you'll need a Raspberry Pi that has been set up and is ready to use. The Raspberry Pi Foundation [has a great guide to help you](https://projects.raspberrypi.org/en/projects/raspberry-pi-setting-up) if you've just unboxed your first Pi.

You'll also need a cellular module board — we'll use the same [Waveshare SIM7600X 4G Hat](https://www.waveshare.com/wiki/SIM7600G-H_4G_HAT) that's used in our main Super SIM tutorial. It will need to be fitted with a [configured Super SIM](https://docs.korewireless.com/supersim/supersim-first-steps).

We have a[ detailed guide to bringing the Pi and the modem together](https://docs.korewireless.com/supersim/supersim-first-steps/get-started-with-super-sim-the-raspberry-pi-4-and-the-waveshare-4g-hat). You should jump to it now and come back here when you've completed it. It will show you how to put in place the services you need to connect to the Internet using Super SIM. If you wish, you can skip Step 3, "Attach to a cellular network", to save a little time.

Finally, you'll need a USB audio adapter. The Raspberry Pi has a 3.5mm AV jack which can output to headphones, but it has no audio in. To remedy that, [fit a USB audio IO adapter like this one](https://amazon.co.uk/gp/product/B09MPM4748) and plug a headset into it. This is just one USB audio adapter — there are many, many similar ones available.

## 2. Install and configure the Twilio CLI tool

We'll interact with Twilio using the `twilio` command line tool. Unfortunately, support for `twilio` and the Serverless Toolkit plugin you'll use alongside it is not optimal on the Pi, so steps 2 through 4 need to be done on your primary computer. You may already have the Twilio CLI installed — if so, you can [jump straight to Step 3](#id-3.-install-the-serverless-toolkit).

{% tabs %}
{% tab title="Linux" %}
Install `twilio` on distributions such as Debian, Ubuntu, Linux Mint, and more with `apt`:

{% code lineNumbers="true" %}

```javascript
wget -qO- https://twilio-cli-prod.s3.amazonaws.com/twilio_pub.asc \
  | sudo apt-key add -
sudo touch /etc/apt/sources.list.d/twilio.list
echo 'deb https://twilio-cli-prod.s3.amazonaws.com/apt/ /' \
  | sudo tee /etc/apt/sources.list.d/twilio.list
sudo apt update && sudo apt install -y twilio
```

{% endcode %}
{% endtab %}

{% tab title="macOS" %}
Install `twilio` on macOS using [Homebrew](https://brew.sh/):&#x20;

{% code lineNumbers="true" %}

```
brew tap twilio/brew && brew install twilio
```

{% endcode %}
{% endtab %}

{% tab title="Windows" %}
Install `twilio` on Windows using [Scoop](https://scoop.sh/). Run [PowerShell as an administrator](https://www.techadvisor.com/how-to/windows/run-programs-as-administrator-windows-10-3632744/) and:

Add the `twilio-cli` [Bucket](https://github.com/ScoopInstaller/Scoop/wiki/Buckets):

{% code lineNumbers="true" %}

```
scoop bucket add twilio-scoop https://github.com/twilio/scoop-twilio-cli
```

{% endcode %}

Install the app:

{% code lineNumbers="true" %}

```
scoop install twilio
```

{% endcode %}
{% endtab %}
{% endtabs %}

Now you're ready to set `twilio` up with:

{% code lineNumbers="true" %}

```bash
twilio login
```

{% endcode %}

You'll be asked to name a profile — make sure you note the name and then run:

{% code lineNumbers="true" %}

```bash
twilio profiles:use <YOUR_PROFILE_NAME>
```

{% endcode %}

## 3. Install the Serverless Toolkit

Twilio's Serverless Toolkit is a `twilio` plugin that considerably simplifies the process of initializing, uploading, and starting a Twilio Functions environment. It uses the core Functions API as exposed by `twilio` and adds convenient bulk-upload functionality that will save you a lot of set up time.

Install the plugin with:

{% code lineNumbers="true" %}

```bash
twilio plugins:install @twilio-labs/plugin-serverless
```

{% endcode %}

## 4. Set up Twilio Functions

Now grab the source code files that underpin the Twilio-mediated SIP service that your IoT device will use to host calls. We have a [GitHub repo that contains all the files you need](https://github.com/korewireless/super-sim-raspberry-pi-voip-demo) and which the `twilio` tool will use to set up your service.

First, clone the repo:

{% code lineNumbers="true" %}

```bash
git clone https://github.com/korewireless/super-sim-raspberry-pi-voip-demo.git
cd super-sim-raspberry-pi-voip-demo
```

{% endcode %}

Optionally, you can edit the repo's `.env` file, which contains your application's admin and SIP client passwords. If you'd rather not use the default passwords, change these now.

Now upload and deploy the code:

{% code lineNumbers="true" %}

```bash
twilio serverless:deploy
```

{% endcode %}

## 5. Initialize the SIP service

The last command you ran will upload and deploy your Twilio Functions environment's functions and assets, and activate the environment. Look at the command's output in the terminal: there will be an `/admin/index.html` URL listed under `Assets:`. Copy the full URL and paste into into a browser window:

<figure><img src="https://778147064-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuQQbnJlSgjMIxsWK06ol%2Fuploads%2FuPtJdBlhlrI4O4OIbhEa%2Fimage.png?alt=media&#x26;token=5c8bb258-876b-473e-8df0-ce57a3542c65" alt=""><figcaption></figcaption></figure>

When the page loads, you'll first be asked to log in — use the password from the repo's `.env` file — and then be invited to initialize the environment:

<figure><img src="https://778147064-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuQQbnJlSgjMIxsWK06ol%2Fuploads%2F4McXW7tPwqfUYLgUyHz4%2Fimage.png?alt=media&#x26;token=a6d8bb62-a44d-4e7d-84d1-f122e433fa6d" alt=""><figcaption></figcaption></figure>

Click the **Initialize...** button to do so. The underlying code will set up your SIP Domain and an associated Credential List, which you can take a look at later in the [Twilio Console under **Voice > Credential lists**](https://console.twilio.com/us1/develop/voice/manage/cls?frameUrl=%2Fconsole%2Fvoice%2Fsip%2Fcls%3Fx-target-region%3Dus1). It will also configure the voice and fax functionality of your Twilio phone number: it will be set to accept voice calls and to route them to devices via the uploaded functions. When the service is configured, the admin page will look something like this:

<figure><img src="https://778147064-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuQQbnJlSgjMIxsWK06ol%2Fuploads%2Fy23Bjx1up1Wh0ojUbDhS%2Fimage.png?alt=media&#x26;token=53096109-3543-4a29-8a26-56d6c9045910" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
If you have multiple Twilio phone numbers available, the admin page will inform you of this and provide a list of numbers from which you can select the one you want to use for incoming calls.
{% endhint %}

Scroll up the admin page and click the **View your running application** link to jump to the list of available SIP clients. These are mock users and they're defined in the repo file `assets/extensions.private.js`. It also includes the extension numbers at which they can be reached. Feel free to make changes, but make sure you re-run `twilio serverless:deploy` every time you do so.

<figure><img src="https://778147064-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuQQbnJlSgjMIxsWK06ol%2Fuploads%2FAoWXzVbYWlhObPHRSJzk%2Fimage.png?alt=media&#x26;token=6db087ca-c261-4f9b-ab6a-6ab9d81e4493" alt=""><figcaption></figcaption></figure>

Pick one of the users as your Raspberry Pi SIP account and make a note of the SIP Registration Domain. Alternatively, note the page's address, enter that into the browser on the Pi when you jump across to it in the next step, and then copy the domain directly.

## 6. Install a SIP softphone on the Pi

A real IoT application would have to incorporate its own code for communicating via SIP and handling the audio IO. For this demo, however, we're using a [softphone called Jami](https://jami.net/). It's open source, free, and runs on the Raspberry Pi.

1. Switch over to the Raspberry Pi. If it hasn't already booted to the desktop, just enter `startx` at the command line.
2. Select the **Raspberry > Accessories > Terminal** menu entry.
3. Enter the following lines:

   <pre class="language-bash" data-line-numbers><code class="lang-bash">sudo apt install gnupg dirmngr \
     ca-certificates curl --no-install-recommends
   curl -s https://dl.jami.net/public-key.gpg \
     | sudo tee /usr/share/keyrings/jami-archive-keyring.gpg \
     > /dev/null
   sudo sh -c "echo 'deb [signed-by=/usr/share/keyrings/jami-archive-keyring.gpg] \
     https://dl.jami.net/nightly/debian_11/ jami main' > \
     /etc/apt/sources.list.d/jami.list"
   sudo apt-get update &#x26;&#x26; sudo apt-get install -y jami
   </code></pre>
4. Launch Jami by selecting the **Raspberry > Internet > Jami** menu entry.
5. On the **Welcome to Jami** page that appears, click on **Advanced features** at the bottom:

<figure><img src="https://778147064-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuQQbnJlSgjMIxsWK06ol%2Fuploads%2F5TrhAvpIsU794uuUY8LR%2Fimage.png?alt=media&#x26;token=0b330ed6-1a3b-4ee7-894e-6b4c299b6719" alt=""><figcaption></figcaption></figure>

6. Click the **Add a SIP account** button:

<figure><img src="https://778147064-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuQQbnJlSgjMIxsWK06ol%2Fuploads%2FOQhQ7dXvRAierYUwHRrd%2Fimage.png?alt=media&#x26;token=c19b02a5-1b02-4df5-8a2c-72f873f66abf" alt=""><figcaption></figcaption></figure>

7. Enter the account name you selected earlier, in Step 5 — or pick one of the names from your **IoT VoIP Demo** browser window — into the Jami **Username** field.
8. Enter the SIP Registered Domain from Step 5 into the Jami **Server** field.
9. Enter `ThisIs1Password!` — or your own password if you changed it earlier — into the Jami **Password** field:

<figure><img src="https://778147064-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuQQbnJlSgjMIxsWK06ol%2Fuploads%2F2vZRyrPOiyVwRHX83Lzk%2Fimage.png?alt=media&#x26;token=bb675c40-6f9c-41f4-a18d-3454deb95b4a" alt=""><figcaption></figcaption></figure>

10. Click the **Create SIP Account** button.
11. Back at the main Jami UI, click the gearwheel icon to the left of your SIP account name, then click the **Media** button.
12. Set your Ringtone, Output and Input Device to your USB audio adapter. This may not be listed as it appears in the screenshot below, so just make sure you **don't** select **Default** , **HDMI** or **AV Jack** :

<figure><img src="https://778147064-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuQQbnJlSgjMIxsWK06ol%2Fuploads%2FIsoEtZ309QEzVEij5DbJ%2Fimage.png?alt=media&#x26;token=5a57ba9e-38d1-47c3-ada8-a6e0b236c3e5" alt=""><figcaption></figcaption></figure>

13. Click the **<** to the left of your SIP account name to go back to the main screen.

## 7. Make a call

1. In Jami, enter your own cellphone number into the **Find or start a conversation** field in the left-hand column:

<figure><img src="https://778147064-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuQQbnJlSgjMIxsWK06ol%2Fuploads%2FomUVOC3VAI5UR2O5YHpn%2Fimage.png?alt=media&#x26;token=82fc3573-68af-4784-aebe-31e3f33affa7" alt=""><figcaption></figcaption></figure>

2. Click on the phone handset icon at the top right to call the number:

<figure><img src="https://778147064-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuQQbnJlSgjMIxsWK06ol%2Fuploads%2F0DP5g8EGho2XpQ7Oz3dJ%2Fimage.png?alt=media&#x26;token=28f60e53-f347-440d-a93d-054b1d113484" alt=""><figcaption></figcaption></figure>

3. Take the call on your phone!

## 8. Receive a call

1. On your cellphone, dial the number back.
2. You'll hear a request for the extension of the party you're trying to reach. Key in `100` on your phone keypad.
3. Talk!

## What next?

You've built yourself a working demo IoT VoIP system that connects a softphone running on a Raspberry Pi computer, via a Twilio Programmable Voice SIP Domain and a cloud-side application constructed with Twilio Functions, to a cellphone for the purpose of making and taking voice calls.

The crucial point to recall, however, is that it is a demo, not a full application. But it neatly shows how you might architect such an application — imagine an industrial IoT unit in the field capable of hosting back-to-base support calls — and of what it would be capable.

Now it's over to you. We can't wait to see what you build.
