This page is under rewriting

Overview

PushNotification module allows Flexisip to wake a liblinphone-basd application up when a chat message or call invite cannot be delivered because the application is unavailable. This feature has become crucial since mobile OSs got used to making the application to hibernate in order to save power.

Today, Flexisip supports native push systems of Android, iOS and Windows Phone ; but can also delegate the work of sending the push request to a tier service using HTTP GET API.

Enabling Push Notifications

First, enable the PushNotification module.

[module::PushNotification]
enabled=true

Applications notify Flexisip of their push IDs by using custom parameters in their REGISTER requests, so that Flexisip is able to send push requests to a given application if this one is still register. Thus, expire time of a REGISTER influence how long an application can be woken up, so you should set Flexisip to authorize high expire value.

[module::Registrar]
# Allow applications to be woken up for 7 days
# after their last REGISTER.
max-expires=604800

Furthermore, by default, Flexisip immediately give up call session establishment or delivering a message when the destination isn't available. Thus, the application won't be able to receive the call invitation or the chat message for which it has been woken up because it simply has been dropped by the proxy. fork-late in module::Router section must be set to true to allow the proxy to hold call invitations and chat messages for a given time before dropping them.

[module::Router]
fork-late=true

# Make chat messages to be hold for 7 days
# before to be dropped. Call invitations are hold for 32s
# in conformance with RFC 3261.
message-delivery-timeout=604800

Creating and installing push certificates

Apple

Generate a certificate

  • On your MacOSX, open Keychain Access > Certificate Assistant > Request a certificate from a Certificate Authority. Enter your email and check "Saved to disk" box (this file will be deleted soon).
  • Connect to apple developer website and ask for a Apple Push Notification service SSL certificate (either SandBox or Production)
  • Select your application in the list and when asked for a CSR file, select the file you generated at first step. Finalize the procedure.
  • Now you must export your certificate (named "Apple Development iOS Push Services: <bundle-id>") including private key from Keychain Access to p12 format.
  • Then you need to export from P12 format to PEM (mandatory for push notification on flexisip, no PEM passphrase!) withopenssl pkcs12 -nodes -in <generated-file>.p12 -out <bundle-id>.dev.pem for Sandbox or openssl pkcs12 -nodes -in <generated-file>.p12 -out <bundle-id>.prod.pem for Production.

Configure Flexisip

Finally configure your server (see below) and put these files on your flexisip installation (default is /etc/flexisip/apn/, backup old ones first if any!) and restart your flexisip instance. If everything is working fine, you may consider revoking your old certificates if any (or wait for them to expire).

Configuring Linphone iOS

If your application is properly configured, check that a  Contact header is emitted in REGISTER with push notification related parameters (pn-*):

SIP/2.0 200 Registration successful
Via: SIP/2.0/TLS <...>
From: <sip:username@sip.linphone.org>;tag=jrKCpF4oO
To: <sip:username@sip.linphone.org>;tag=6H3eKQXDD4jFg
Call-ID: wnyKVyry0N
CSeq: 21 REGISTER
Contact: <sip:username@52.243.117.188:49469;app-id=org.linphone.phone.dev;pn-type=apple;pn-tok=ABA3D8A75E1A4F2CF5D148F6A96871EF2AB23A3EA6C25D043D53566BD7E97457;pn-msg-str=IM_MSG;pn-call-str=IC_MSG;pn-call-snd=notes_of_the_optimistic.caf;pn-msg-snd=msg.caf;transport=tls>;expires=3600;q=0.00
Contact: <sip:username@52.243.117.188:64651;transport=tls>;expires=347041;q=0.00
Server: Flexisip/1.0.8 (sofia-sip-nta/2.0)
Content-Length: 0

If it is not working, check application code. linphone_proxy_config_set_contact_uri_parameters() should be invoked by application: didRegisterForRemoteNotificationsWithDeviceToken:.

Android push notifications (firebase)

Register your project on Google

First you need a Google Account. If you don't have one yet, create it.

Then go to https://console.developers.google.com/ and log in.

Create a project

If you haven't created a "project" yet, do it now. Otherwise go to the next paragraph.

Click on "Project", "Create a project" on the top right corner of your screen.

Open a new tab to https://console.cloud.google.com/home/ and keep somewhere the project number (not id). It is a very large number in parenthesis after the ID (without the #).

Enable Push Notifications

Now that you have a project id, click on "Google Cloud Messaging" link under the green Droid (mobile API section).

Somewhere on the page, there is an "Enable" button. Click on it. 

/!\ If the button's label is "Disable", don't click it.

Create an API key

Now click on the left panel on the "Credentials" link.

Click on "create credentials" and choose "API Key" and then "Server key".

Give it a name, and the IP(s) of the server(s) it will be used on (this isn't mandatory but I strongly recommend you do it).

Finally, click on "Create". 

You'll have a pop-up with an API key. This is the second value we need to configure Flexisip.

Client side

Edit the non_localizable_custom.xml file and add/edit to match the following:

<string name="push_type">firebase</string>
<string name="push_sender_id">your_firebase_id</string>

Server side

Firebase push notifications are supported in flexisip version 1.0.10-196 (0da032c963ad8c856bbde3769b58c7ae580cc815) and newer.

Edit the flexisip.conf file and add/edit to match the following (replace sender id and server key by the values from the firebase console, settings section, cloud messaging tab) :

[module::PushNotification]
firebase=true
firebase-projects-api-keys=<sender id>:<server key>

Then (re)start flexisip, and you'll have the push notifications for Android using firebase.

If you want to add multiple pairs of sender id and server key, separate them with a 'space' character in the firebase-projects-api-key.

Testing

You may test that your server-side configuration is ok by using the flexisip-pusher tool embedded in the Flexisip installation package. It enable to manually send a notification request to the push notification server. You may invoke flexisip-pusher using the following:

./flexisip_pusher --pntype <platform> --appid <appid> --pntok <device token> --debug

Testing on iOS

To send a push request to the Apple's server, one may use:

./flexisip_pusher --pntype apple --appid <bundle-id>.dev --pntok <tok> --debug

If it is alright, the ouput should look like:

Feb 14 06:42:14 ns3002422 flexisip: PushNotificationClient org.linphone.phone.voip.prod.pem PNR 0x7f3e04e79af8 sent 105/105 data
Feb 14 06:42:14 ns3002422 flexisip: PushNotificationClient org.linphone.phone.voip.prod.pem PNR 0x7f3e04e79af8 waiting for server response
Feb 14 06:42:15 ns3002422 flexisip: PushNotificationClient org.linphone.phone.voip.prod.pem PNR 0x7f3e04e79af8 nothing read, assuming success

If you get the following error:

E: PNR 0x7fed1a449858 with identifier 1 failed with error 8 (Invalid token)

It probably means that you are using the wrong application id. Note: to test the production certificate, you must generate an adhoc IPA and install it manually!

Testing on Android

You can test and troubleshoot your setup using the flexisip_pusher tool available with flexisip.

Here's how to send an Android (firebase) push notification:

/opt/belledonne-communications/bin/flexisip_pusher --pntype firebase --appid <sender_id> --key <server_key> --pntok <device_push_token> --debug