Hello,

As mobile applications based on kamailio are growing exponentially on Play Store and App Store, i would suggest if you could add by default the code for ios/android push notifications.

I have problems mainly for incoming call (phone wakeup) on linphone iphone app, as kamailio is missing the push solution. On Android i am using Baresip and works perfect without push.

Navigating on the web, i found some uncomplete or minimum tutorials to implement this.
Like: https://denys-pozniak.medium.com/apple-push-notification-with-kamailio-eeca2f8e08d

And also some code snippets of a modification of "kamailio.cfg" to add support for ios push notifications. (see below).
Could someone have this already working? Or kamailio official developers could add this by default inside source code?

# keep a record of an IPhone for 4 hours
modparam("htable", "htable", "iphone_remote=>size=10;autoexpire=14400;")
modparam("htable", "htable", "iphone_voip=>size=10;autoexpire=14400;")
modparam("htable", "htable", "iphone_check=>size=10;autoexpire=14400;")
modparam("htable", "htable", "vtp=>size=10;autoexpire=120;")


route[REGISTRAR] {

...

...

        if (save("location")) {

            # user registered, now look at the useragent header for iPhone string
            if ($hdr(User-Agent)=~"LinphoneiOS.*") {


                $var(uri) = @contact.uri;                               # select the uri from contact header
                $var(pn-prid) = $(var(uri){uri.param,pn-prid});         # get the uri param pn-prid from the uri, i.e. 1DF26BC10F597676B
                xlog("!!!! - $var(pn-prid)");
                $var(i) = 0;
                $var(n) = $(var(pn-prid){s.count,&});

                while( $var(i) <= $var(n)) {
                    $var(pn-prid_item) = $(var(pn-prid){s.select,$var(i),&});
                    $var(pn-prid_type) = $(var(pn-prid_item){s.select,1,:});
                    $var(pn-prid_token) = $(var(pn-prid_item){s.select,0,:});

                    if ( $var(pn-prid_type) == "remote" ) {
                        $var(pn-prid_remote) = $(var(pn-prid_item){s.select,0,:}) ;
                    }
                    if ( $var(pn-prid_type) == "voip" ) {
                        $var(pn-prid_voip) = $(var(pn-prid_item){s.select,0,:}) ;
                    }
                    $var(i) = $var(i) + 1;
                }

                xlog("L_INFO","iPhone PUSH tokens for user $fU - remote: $var(pn-prid_remote), voip: $var(pn-prid_voip)");

                # store the values of tokens to htable with fromUser as key
                $sht(iphone_remote=>$fU) = $var(pn-prid_remote);
                $sht(iphone_voip=>$fU) = $var(pn-prid_voip);
                $sht(iphone_check=>$fU) = 1;

                if ( $sht(vtp=>id_index::$tU) != $null ) {
                    xlog("L_INFO", "New $rm ru=$ru tu=$tu \n");
                    route(JOIN);
                }
           
            } else {
                # no iphone
                $sht(iphone_check=>$fU) = 0;
            }

...

...

}



route[LOCATION] {

...

...

        if (!lookup("location")) {
            $var(rc) = $rc;
               
            # handle PUSH notifications for iPhone
            # iphones should not be registered and contacts stored in database
            # hence lookup should fail and we need to try to push iphone first
            if ($sht(iphone_check=>$tU) == 1) {
                xlog("L_ERR", "[PUSH] The to user has already used iPhone, trying push notifications");
                xlog("L_ERR", "[PUSH] No registration to try, suspending.");
                sl_send_reply("100", "Suspending");
                route(SUSPEND);
                route(RELAY);
                exit;
            }
...

...

        if (is_method("INVITE")) {
            setflag(FLT_ACCMISSED);
           
            # handle PUSH notifications for iPhone
            # in some cases, iphone does not send de-register when going to background
            # for these circumstances, push iphone even if it has an active registration
            if ($sht(iphone_check=>$tU) == 1) {
                xlog("L_ERR", "[PUSH] The to user has already used iPhone, trying push notifications");
                xlog("L_ERR", "[PUSH] No registration to try, suspending.");
                sl_send_reply("100", "Suspending");
                route(SUSPEND);
            }

        }
        route(RELAY);
        exit;
}



route[SUSPEND] {
  if ( !t_suspend() ) {
    xlog("L_ERROR","[SUSPEND]  failed suspending trasaction [$T(id_index):$T(id_label)]\n");
    send_reply("501", "Suspending error");
    exit;
  } else {
    xlog("L_INFO","[SUSPEND]  suspended transaction [$T(id_index):$T(id_label)] $fU=> $rU\n");
    $sht(vtp=>id_index::$rU) = $T(id_index);
    $sht(vtp=>id_label::$rU) = $T(id_label);
    xlog("L_INFO","[SUSPEND] htable key value [$sht(vtp=>id_index::$rU)   --   $sht(vtp=>id_label::$rU)]\n");
    route(SENDPUSH);
    exit;
  }
}
   
route[SENDPUSH] {
    #http_client_query("http://url/push.php", "user=$rU\r\npn-tok=$sht(tokens=>$rU)\r\n","Content-Type: text/plain", "$var(result)");
    xlog("!!!!!!!!!!!!!!!!!!!!!! PUSH !!!!!!!!!!!!!!!!!!!");
    xlog("/opt/push/push.sh $ci $sht(iphone_voip=>$tU)");
    exec_avp("/opt/push/push.sh $ci $sht(iphone_voip=>$tU)");
    xlog("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
    sl_send_reply("100", "Pushing");
}

route[JOIN] {
    xlog("L_WARN","[JOIN] htable key value [$sht(vtp=>id_index::$tU)   --   $sht(vtp=>id_label::$tU)]\n");
    t_continue("$sht(vtp=>id_index::$tU)", "$sht(vtp=>id_label::$tU)", "RESUME");
    $sht(vtp=>joined::$tU) = 1;
}
   
route[RESUME] {
    lookup("location");
    xlog("L_INFO","[RESUME] rm=$rm ru=$ru du=$du \n");
    t_relay();
    $sht(vtp=>id_index::$tU) = $null;
    $sht(vtp=>id_label::$tU) = $null;
    exit; }