Cellular calls, straight into the phone system.
Put a SIM in a spare Android phone and leave it on the charger. When someone calls that number, the app answers. It then calls an extension on the office PBX and joins the two calls, so the call can be routed like any other.
Overview
CPBX is an Asterisk phone system that runs in Docker on the office PC (PC01). It has three containers: cpbx-asterisk (the PBX), cpbx-admin (the web admin) and cpbx-coturn (TURN relay for browser calls).
- Office (LAN) address: 192.168.1.106
- Tailnet address: 100.64.0.1, through Headscale at hs.neuereatec.org
- The ISP uses CGNAT, so there is no public IP. Port forwarding cannot work. Phones outside the office must use Headscale.
Office phones (LAN) ----+
| 192.168.1.106:5060
SIPDesk / GSM Gateway --+--> PC01: Docker
(Headscale tailnet) | cpbx-asterisk (PBX)
100.64.0.1:5060 | cpbx-admin :3000
| cpbx-coturn :3478
JavisLink (browser) ----+
wss://sip.neuereatec.org/ws
Caller -> SIM in gateway phone -> ext 150 -> ext 105
Extensions
- 100: desk extension (remote-ready over Headscale)
- 104: JavisLink WebRTC softphone
- 105: receives calls from the GSM Gateway (remote-ready)
- 150: the GSM Gateway phone (remote-ready)
- 1001: extension (remote-ready)
- 9487: extension (office LAN only)
How to use them
- To call someone, dial their extension number, for example 105.
- Dial 600 for the echo test. You hear a short message, then your own voice. That shows your audio works both ways.
- Dial 104 to reach the JavisLink softphone.
Softphone downloads and links
- SIPDesk 2.2.0 (Android desk phone): sipdesk.apk · download page
- GSM Gateway 1.2.2 (SIM bridge): gsm-gateway.apk · Magisk module
- JavisLink softphone (opens in the browser, nothing to install): javis.neuereatec.org/softphone
- Setup QR page (office Wi-Fi only): 192.168.1.106:8765, PIN 418043
Assigning an extension to each softphone
- SIPDesk: open Settings → Scan QR code, scan the Extension N QR, then tap Save & Connect.
- GSM Gateway: tap Scan QR and scan the extension 150 QR, or paste the setup link in the setup steps.
- JavisLink: point the phone's normal camera at the JavisLink N QR and open the link. The softphone opens, saves the extension and password, and signs in. You can still type the extension and password in its Settings.
JavisLink softphone (extension 104)
JavisLink is a browser softphone at javis.neuereatec.org/softphone. It registers on extension 104 through wss://sip.neuereatec.org/ws. To set it up, scan the JavisLink 104 QR on the setup QR page with the phone camera. To test it, dial 104 from any other extension.
Adding an extension and its QR
- On PC01, open CPBX Admin at http://localhost:3000. From another office computer, use
http://192.168.1.106:3000. - Create the extension and save it.
- Open the setup QR page (office LAN only) and enter the PIN 418043. The new extension's QR shows up within about 30 seconds.
- Scan it in SIPDesk (Settings → Scan QR code) or in the GSM Gateway app (Scan QR). For JavisLink, scan the second JavisLink QR with the phone camera.
- Tap New key on the QR page if you need a fresh code.
Remote use via Headscale
- Outside the office, phones reach the PBX at 100.64.0.1 over the Headscale tailnet (hs.neuereatec.org).
- SIPDesk: set the server to 100.64.0.1 and tick Use tailnet address for SIP.
- GSM Gateway: the phone needs the Tailscale app, logged in to Headscale. Use a different phone from the SIPDesk one.
- Remote-ready extensions today: 100, 105, 150, 1001.
- Ask Calton for the Headscale login. It is not published here.
When the network changes
Use this when PC01's office IP changes, for example after a new router, a new DHCP lease or an office move.
- On PC01, open Command Prompt and run
ipconfig. Note the IPv4 address. - Double-click Change-PBX-IP.bat on the Desktop. You do not need Run as administrator.
- Type the new IP and press Enter. The script checks the IP is valid and backs up
docker-compose.yml. It changes onlyCPBX_ADVERTISE_IPand restarts withdocker compose up -d. Then it shows SUCCESS or the error. - After SUCCESS, open CPBX Admin and save any one extension.
- Dial 600 to test.
PBX troubleshooting
- No audio or one-way audio: dial 600. If you cannot hear yourself, check that the office IP is still right (see When the network changes).
- SIPDesk will not connect away from the office: run only one VPN on the phone. Android allows just one, and the Tailscale app kicks SIPDesk's tunnel off.
- The app drops after a while: set its battery setting to Unrestricted.
- Still stuck: force-stop the app and open it again.
- QR page will not open: it only works on the office network (192.168.1.106:8765).
Staff quick guide
- To call a colleague, dial their extension.
- To test your phone, dial 600 and speak. You should hear yourself.
- To reach the softphone, dial 104.
- If your phone is new, open the QR page in the office, enter PIN 418043, and scan your extension in SIPDesk.
- If something breaks, force-stop and reopen the app, then tell Calton.
Setup QR codes
Before you install: rooted phones and normal phones sound different
How the bridge works
- The app stays registered to the PBX as an ordinary SIP extension. It runs as a foreground service and starts again after a reboot.
- A cellular call rings. If SIP is registered, the app answers it after a short delay (1.5 s by default).
- The app sends a SIP INVITE to the first extension in the ring list (or to the PBX route
gsmgw), then the next one on no answer. It puts the caller's number in the display name, inP-Asserted-Identityand inX-GSM-Caller. - Audio runs both ways as G.711 (PCMU/PCMA). If the PBX sends keypad presses (RFC 2833), the app plays them as tones to the caller. Keys the caller presses reach the PBX as in-band tones.
- When either side hangs up, the other call ends too.
Gateway setup, step by step
- Install the APK. Download gsm-gateway.apk on the gateway phone (the one with the SIM), open it, and allow installing from this source if Android asks.
- No Tailscale app needed. Version 1.1 has the Headscale (WireGuard) client built in. The QR carries the join key; the app brings the tunnel up first, then registers SIP over it. Android asks once to allow the VPN: tap OK. If the Tailscale app is installed, turn it off (only one VPN can run).
- Scan the gateway QR. Open the setup QR page on an office screen, enter the PIN, find GSM Gateway — 150. In the app tap Scan QR. SIPDesk softphone codes are refused on purpose.
- Choose who rings. The app asks Which extension should incoming cellular calls ring? Type the main extension, e.g.
100, and add more separated by commas (100, 105): the PBX rings them in that order, 20 s each, skips anyone busy or offline, then goes to the first one's voicemail. Numbers are used exactly as typed. Leave it blank for the PBX default (100). Change it later under Bridge → Change ring order. - Permissions. Tap Permissions and allow the microphone, phone, call logs, answering calls and notifications. Tap Battery and choose Unrestricted (battery optimisation off). Default phone app: version 1.0 can't take the default phone app role and doesn't need it, because it answers calls with the “Answer phone calls” permission. Keep your normal dialer as the default.
- Check the status. The top panel should read Tunnel: Online with a 100.64.x.x tailnet IP, SIP: Registered and Gateway: Idle.
- Test. Call the SIM from another mobile. The gateway answers in about 2 s and the first extension in your list rings with the mobile's number. Answer it and talk both ways. Press keys on the desk phone and listen for the tones on the mobile. Hang up on the mobile and check the desk phone drops. Call again, hang up on the desk phone, and check the mobile drops.
- Rooted phone only: add the Magisk priv-app module for cleaner audio.
Gateway troubleshooting
| Level bar stays at 0 during a call | The phone is blocking call audio. Tick Force speakerphone mode, tap Save & restart, and call again. |
|---|---|
| Not registered | Look at Tunnel first. Key used up / NeedsLogin = the key was spent or expired: make a New key for 150 on the QR page and scan again. Stopped = VPN permission missing or another VPN app is on. Once the tunnel is Online, SIP registers by itself. |
| Phone rings but is not answered | SIP must be Registered (the app won't answer otherwise), and “Answer phone calls” must be allowed. |
| Stops working after a while or after a reboot | Set Battery to Unrestricted. The tunnel and gateway restart after a reboot by themselves; if the status shows VPN permission missing, open the app once. |
What to configure
| Headscale | URL and key come from the QR. Blank URL = no tunnel (LAN use). |
|---|---|
| SIP server | 100.64.0.1 over the built-in tunnel, or a LAN address such as 192.168.x.x. |
| Port | 5060 (UDP) |
| Extension | The gateway's own SIP extension (from the administrator) |
| Password | That extension's SIP password |
| Ring order | Extensions in order, e.g. 100, 105. Sent to the PBX on every call; the PBX hunts (20 s each, skips busy/offline, then voicemail). Blank = PBX default 100. |
| Answer after | Delay before answering, in milliseconds (1500) |
| Audio mode | Chosen automatically: Rooted: call audio interception, Rooted: VOICE_CALL capture or Speakerphone (lower quality). Tick “Force speakerphone mode” to override. |
Rooted phone: Magisk priv-app
- Install and set up the APK first (above).
- In Magisk, open Modules → Install from storage and pick gsm-gateway-magisk.zip. Reboot the phone.
- The module copies the app to
/system/priv-app/NeuereatecGsmGateway/. It also adds a permission allow-list forCAPTURE_AUDIO_OUTPUT,CALL_AUDIO_INTERCEPTIONandMODIFY_PHONE_STATE. - Open the app. The audio mode should start with Rooted:. If it still says Speakerphone, check the result with
adb shell dumpsys package org.neuereatec.gsmgateway | grep -E "CAPTURE_AUDIO|INTERCEPTION". Both should showgranted=true. - To update later, install the new APK normally. It stays privileged because it is signed with the same key. To undo, remove the module in Magisk and reboot.
SIPDesk: a desk phone on the same PBX
- Download SIPDesk from bbscalton.github.io/sipdesk-android and install it.
- Connect it to Headscale (
https://hs.neuereatec.org) with the auth key from the office. - Open SIPDesk Settings → Scan QR code and scan that user's extension QR from the setup QR page (office PIN from the administrator). Then tap Save & Connect.
- Test: dial 600 (echo test) and check you hear yourself. Then call 104, the JavisLink softphone, and talk both ways.