Asterisk: wake a sleeping iPhone
Two pieces: a PJSIP endpoint the app registers to, and three lines of dialplan that wake the iPhone just before you dial it. Fifteen minutes, most of it copy-paste.
Before you start
- Asterisk 16 or newer with PJSIP (any current LTS is fine).
- The relay endpoint and PBX key from the app: Settings → Incoming Calls, then copy both. The key starts with
pk_and belongs to your account, so treat it like a password. curlon the PBX host, and outbound HTTPS allowed (port 443).
1. The endpoint
A wizard block gets you a working extension with the NAT settings a moving iPhone needs. Adjust the extension number and password:
[101]
type = wizard
accepts_registrations = yes
sends_registrations = no
accepts_auth = yes
sends_auth = no
endpoint/context = from-internal
endpoint/allow = !all,opus,g722,ulaw,alaw
endpoint/direct_media = no
endpoint/rtp_symmetric = yes
endpoint/force_rport = yes
endpoint/rewrite_contact = yes
aor/max_contacts = 1
aor/remove_existing = yes
aor/qualify_frequency = 60
inbound_auth/username = 101
inbound_auth/password = YOUR_SIP_PASSWORDThe NAT flags are the part worth understanding:
rtp_symmetricandforce_rportsend media and signalling back to where the phone's packets actually came from, which is what keeps audio working on cellular.rewrite_contactupdates the contact with the phone's NAT'd address.max_contacts = 1withremove_existingmeans a fresh registration after a wake cleanly replaces the stale one.
In the app: Settings → Account, with username 101, your SIP password, and your PBX's domain and port. Transport lives under Settings → Advanced if your server speaks TCP rather than TLS.
2. The wake dialplan
The whole trick: when a call arrives, tell the relay, give the push a moment to land, then dial the extension as usual.
[globals]
SAFFRON_KEY=pk_your_key_from_the_app
[from-trunk]
exten => 101,1,NoOp(Waking Saffron SIP for 101)
same => n,System(curl -s -m 2 https://sipreg.saffronsuite.com/v1/incoming-call -H "Authorization: Bearer ${SAFFRON_KEY}" -H "Content-Type: application/json" -d '{"call_id":"${UNIQUEID}","to":"sip:101@pbx.example.com","from":"${CALLERID(num)}","display_name":"${CALLERID(name)}"}')
same => n,Wait(1.5)
same => n,Dial(PJSIP/101,25)
same => n,VoiceMail(101@default,u)
same => n,Hangup()Notes on the three lines:
Wait(1.5)is the retain step: it holds the call while Apple's push wakes the phone and the app re-registers. Don't skip it.call_idjust needs to be unique per call and stable across retries;${UNIQUEID}does both. If you want the app to correlate the wake with the exact call, use the SIP Call-ID:${CHANNEL(pjsip,call-id)}.-m 2caps the webhook at two seconds so a network blip can't stall your call flow.- If your dialplan uses
Gotointo ring groups or queues, fire the wake at the point where the call is committed to this extension, then route as normal.
3. Prove it works
From the PBX host, fake a call with curl. Your phone should ring within a couple of seconds, even locked in your pocket:
curl -s https://sipreg.saffronsuite.com/v1/incoming-call \
-H "Authorization: Bearer pk_your_key_from_the_app" \
-H "Content-Type: application/json" \
-d '{"call_id":"test-1","to":"sip:101@pbx.example.com","from":"100","display_name":"Test"}'A 202 with "devices_woken": 1 means the relay found and woke your phone. Anything else, the troubleshooting page decodes it. Then reload the dialplan (dialplan reload in the Asterisk CLI) and make a real call.