This article will go through setting up Kannel to send "WAP Push" messages to mobile phones. It assumes you have a working Kannel
installation with a real modem -- see parts
1 &
2 of this series for more information.
Before we continue with this article, let me save you some time. I have found WAP Push messages to be very unreliable. Specifically I was only able to get a WAP Push message sent to a T-Mobile phone from my GSM modem with a T-Mobile SIM card. I tried a Cingular SIM card in the modem, but was unable to successfully send a WAP Push message to a Cingular or other network phone.
I searched for 3rd party companies that will send WAP Push messages, and contacting a few of them. It seems here in the U.S. this type of service is relatively unreliable and sometimes only the network providers themselves can send WAP Push messages that will get through. Case in point: I couldn't get a WAP Push message to a Cingular phone, but you can download ringtones from cingular.com, for which the URL is sent to the phone via WAP Push.
So, if you want to send WAP Push messages from a T-Mobile modem to only T-Mobile phones, read on! If not, you might save yourself the headache and time and skip the next article of my WAP series:
Send SMS from PHP.
Sending WAP Push from the command line
To our working configuration file from
WAP: Part 2 - Send SMS from Kannel, we'll add the ppg and wap-push-user groups. Also add
wapbox to the startup file and restart Kannel.
/etc/kannel/kannel.conf
...
group = ppg
ppg-url = /wappush
ppg-port = 8080
service-name = ppg
trusted-pi = true
group = wap-push-user
wap-push-user = SellingSource
ppg-username = sellingsource
ppg-password = sellingsource
start_kannel.sh
rm /var/log/kannel/*
bearerbox --verbosity 4 --logfile /var/log/kannel/bearerbox.log /etc/kannel/kannel.conf &
sleep 10
smsbox --verbosity 4 --logfile /var/log/kannel/smsbox.log /etc/kannel/kannel.conf &
wapbox --verbosity 4 --logfile /var/log/kannel/wapbox.log /etc/kannel/kannel.conf &
I initially tested WAP Push using the included
test_ppg executable included with the Kannel source. If you don't want/need to test it from the command line you can skip to the
PHP segment.
Unfortunately the test programs are not included with the Gentoo/portage installation of Kannel. So I downloaded the source and
compiled (but did not install) it to get the test programs. Then I copied the example xml files used by
test_ppg to my home directory for modification.
~ # cd ~/src
src # wget http://kannel.org/download/1.4.1/gateway-1.4.1.tar.bz2
src # tar -jxvf gateway-1.4.1.tar.bz2
src # cd gateway-1.4.1
gateway-1.4.1 # ./configure && make
gateway-1.4.1 # cp test/si.txt ~/si.xml
gateway-1.4.1 # cp test/smstestppg.txt ~/pap.xml
In si.xml I removed the created and si-expires attributes so there's no delivery timing issues (deliver immediately). The indication href
is a URL that will be shown as the 'From:' in the message, and is where the message will take them. The si-id is a unique message
identifier and should be changed everytime the message is sent. I like to use number@domain and up the number once before sending.
Change the message to something suitable, hopefully describing where the href URL will take them.
si.xml
xml version="1.0"
<!DOCTYPE si PUBLIC "-//WAPFORUM//DTD SI 1.0//EN"
"http://www.wapforum.org/DTD/si.dtd">
<si>
<indication href="http://wap.yahoo.com"
si-id="01@sellingsource.com"
action="signal-high">
Visit Yahoo! on your phone
</indication>
</si>
In pap.xml, I changed to the push-id to the same as the si-id, this value should change per message as well. I changed the WAPPUSH number to my own, this time with country code (leading "+1"). I also changed the "carrier" after the 'PLMN@' to be our domain.
pap.xml
xml version="1.0"
<!DOCTYPE pap PUBLIC "-//WAPFORUM//DTD PAP//EN"
"http://www.wapforum.org/DTD/pap_1.0.dtd">
<pap>
<push-message push-id="01@sellingsource.com"
deliver-after-timestamp="2001-02-28T06:45:00Z"
progress-notes-requested="false">
<address address-value="WAPPUSH=+17025551212/TYPE=PLMN@sellingsource.com">
</address>
<quality-of-service
priority="low"
delivery-method="unconfirmed"
network-required="true"
network="gsm"
bearer-required="true"
bearer="sms">
</quality-of-service>
</push-message>
</pap>
So let's test this from the command line:
gateway-1.4.1 # ./test/test_ppg "http://localhost:8080/wappush?username=wap_user&password=wap_pass" ~/si.xml ~/pap.xml
On my T-Mobile Motorola phone, I now have a message under "Browser Msgs." I can click the "GO TO" button and it will take me to the URL specified in the 'href' attribute of si.xml.
Sending WAP Push from PHP
Now let's do the same thing using PHP. But first let me explain how things are going to change. XML is pretty chatty, so we'll be using a binary format called WBXML. Since we'll be communicating directly to Kannel via HTTP with a URL, we'll represent the hexadecimal numbers with a prefix of '%' for URL encoding, rather than '0x'. Along with the Service Indication (SI) document in WBXML, we'll also have to pass a User Data Header (udh) for WAP Push. For an explanation of the udh and WBXML, please see the reference information links below, I've also documented them as best I know in the code:
<?php
require_once 'SMSBase.php';
class WAPPush extends SMSBase
{
public function __construct(KannelInfo $kannel_info)
{
parent::__construct($kannel_info);
}
public function sendSMSLink(LinkSMS $sms)
{
$fields = array('to' =>; urlencode($sms->getTo()),
'udh' => '',
'text' => '');
$fields['udh'] .= '%06';
$fields['udh'] .= '%05';
$fields['udh'] .= '%04';
$fields['udh'] .= '%0B%84';
$fields['udh'] .= '%23%F0';
$fields['text'] .= '%1B';
$fields['text'] .= '%06';
$fields['text'] .= '%01';
$fields['text'] .= '%AE';
$fields['text'] .= '%02';
$fields['text'] .= '%05';
$fields['text'] .= '%6A';
$fields['text'] .= '%00';
$fields['text'] .= '%45';
$fields['text'] .= '%C6';
$fields['text'] .= '%0C';
$fields['text'] .= '%03';
$fields['text'] .= $this->urlHexEncode($sms->getURL());
$fields['text'] .= '%00';
$fields['text'] .= '%01';
$fields['text'] .= '%03';
$fields['text'] .= $this->urlHexEncode($sms->getText());
$fields['text'] .= '%00';
$fields['text'] .= '%01';
$fields['text'] .= '%01';
return $this->sendSMS($fields);
}
private function urlHexEncode($text)
{
$string = '';
for ($i=0; $i < strlen($text); $i++)
{
$letter = $text[$i];
$string .= sprintf('%%%02X', ord($letter));
}
return $string;
}
}
?>
sendSMS() in the parent, SMSBase, simply uses the file() function to send the URL via HTTP GET -- you'll have to make sure allow_url_fopen is set to On in your php.ini or with ini_set().
Also, now that we're doing all of the encoding ourselves and sending directly to the
smsbox daemon, we can turn off
wapbox. In the startup script, comment out the
wapbox line. In kannel.conf you can comment out any wap related entries in the core group (wapbox-port, wdp-interface-name, etc.). You can also comment out the entire wapbox, ppg, and wap-push-user group blocks. You'll have to restart kannel for these changes to take effect.
Resources
Download the entire example.
(udh explanation)
http://discussion.forum.nokia.com/forum/archive/index.php/t-13518.html
(wbxml breakdown)
http://discussion.forum.nokia.com/forum/archive/index.php/t-16775.html
http://www.activexperts.com/activsms/sms/wappushsi/
(wappush using PHP)
http://www.mail-archive.com/users@kannel.org/msg07893.html
Articles In This Series:
WAP: Part 1 - MultiTech USB GPRS Modem in Linux
WAP: Part 2 - Send SMS from Kannel
WAP: Part 3 - WAP Push with Kannel & PHP
WAP: Part 4 - Send SMS from PHP
WAP: Part 5 - Customizing content with WURFL
WAP: Part 6 - Microbrowser content in WML / XHTML MP