SolutionsTools & SDKSupportForums Register



Quick Links
 
March 2002
 
 

Jack's Hack for the month of March, 2002:

Technical Overview of Delivering WAP Push Using Perl

Last month in Jack's Hacks, we examined how to deliver WAP Push messages by using Java Servlets, the Openwave WAP Push Libraries and MySQL. Since servlets don't fit everyone's needs, this month we're going to take a deeper look at WAP Push, the Push Access Protocol, and how WAP Push messages can be generated using other languages (specifically perl).

The term "WAP Push" is used to encompas an architecture which is composed of several pieces:

  1. A WAP Push capable Handset
  2. A WAP Push Proxy Gateway (PPG)
  3. A Wap Push Initiator (PI)
  4. The Protocol between the PI and the PPG (PAP)
  5. The Protocol between the PPG and the Handset (Push OTA)

The overall architecture of WAP Push is described by the WAP Push Architectural Overview that is part of the June 2000 Conformance release from the WAP Forum (also know as WAP 1.2.1). The most relevant part of the WAP Push system for developers is PAP.

Openwave makes available a WAP Push library package that contains some sample code and classes that simplifiy PAP, and allow developers to simply integrate push into java based applications without needing extensive knowledge of PAP or WAP Push. However, Java based libraries do not meet the needs of all developers, so lets take a look at how PAP can be implemented without using the Openwave WAP Push libaray.

There are a few essential pieces needed to construct a WAP Push Service load

  1. The Subscriber address
  2. The PPG address
  3. The URL to be pushed
  4. A text string to be displayed
  5. A unique identifier for the push message

Once this information is collected, it can be used to build the Push entity.

We will take a look at how all of these pieces can be brought together using an HTML front end, we can capture the data that will change from message to message, and pass it on to some simple prel processing scripts. The source code that this sample application is based on can be found in the following 3 files: newpush.html, newpush.cgi, and pushUtils.pm.

HTML Push Screen

This information realistaclly will come from some buisness logic or triggered even in a back end system, however for the purposes of this example, we will employ a manual push initation.

The data submitted will be decoded on the server side by newpush.cgi, and is processed in 5 steps:

  1. Parse the query string
    &parse_string;
  2. Generate a unique ID for the push
    $id = &getid;
  3. Create the XML Push entity
    &create_content($id);
  4. Post the push entity to the PPG
    $request = HTTP::Request->new(POST, $url, $headers, $content);
    $ua = LWP::UserAgent->new;
    $response = $ua->request($request);
  5. Display back some results
    &print_html($string, $content, $$response{_content}, $url);

As we step through each of the functions in newpush.cgi we can see that the bulk of the work will be done in the create_content method.

  • parse_string simply takes the arguments that are delivered on the query string to the sciprt and populates an array of variables.

        $ppgaddr		= $string{ppg};
        $url            	= 'http://'.$ppgaddr.':9002/pap'; 
        $subscriber     	= $string{subscriber};        
        $url_to_push    	= $string{url_to_push};        
        $message        	= $string{message};        
        $delivery_method 	= 'unconfirmed';
        $bearer         	= 'SMS';
        $bearer_required 	= 'true';
        $content_severity	= 'high';
    As we mentioned earlier, there are only certain values that will change with each new push, so we also assign static values at this stage for the delivery method, the bearer, if the bearer we specify should be required, and the urgency of the alert. Notice that the variable url is not the url that is being pushed, but instead is the URL on the PPG that is listening for PAP input. Port 9002 is specified as the public, non-secure port for WAP Push

  • In the getID method, we need to generate a unique ID for each push that is sent by the application. Furthermore, this ID must be unique across all push messages sent to any particular PPG. So, we maintain a file that we increment the push ID from and append this to a string unique to our particular application.

         open (ID,">/tmp/pushid");
        $newid = $id;
        $newid += 1;
        print ID "$newid\n";
        
        # return value
        return "testpush-".$id;

  • At this point in the application, we start the heavy lifting of building the PUSH in the create_content method. Here we build an mime-multipart that is composed of 2 parts, the control entity, and the content entity. The control entity covers the addressing and delivery specifics, while the content entity contains the data that is to be delivered to the handset. The construction of these is done by the newPush.pm library.

    • The createControl method builds the XML control entity first ensuring that all required fields have been passed in. Next, the variables gathered from the form are placed in their appropriate locations in the addressing scheme, and then the entire XML entity is returned back to the calling script.
    • The createContentSI method build the other half of the PUSH entity. This is again, and XML contsruct that accepts the URL to be pushed to the user along with a text message to be displayed by the device. Upon completion, this method returns the XML back to the calling script

  • Once the multipart has been completely assembled, we can now open up an HTTP connection to the PPG that has been specified, and POST the entity. To accomplish this, we rely on some public libraries to manage the HTTP connection, these are:

    require HTTP::Request;
    require LWP::UserAgent;
    require HTTP::Headers;
    

    which are available from CPAN. if they are not present in your current perl environment.
    We send the multipart to the address of our PPG on port 9002, set the headers indicating that we are delivering a multipart entity, and then setup to capture the response from our POST

    
    ### POST to the url
    $request = HTTP::Request->new(POST, $url, $headers, $content);
    $ua = LWP::UserAgent->new;
    
    ### get the response
    $response = $ua->request($request);

  • The final step is simply presenting back to the user a readable presentation of the multipart that was assembled as well as the XML response that came back from the PPG. For an application deployed in a production enviroment, this step would likely involve only writing some of the information out to a database, or undertaking some additional processing based on the response.

This application has built a simple ServiceIndication, and does not address all of the features that are available via WAP Push. Developers can also send ServiceLoad, and CacheOperations, in addtion to querying client capabilities. Furthermore, many other optional delivery attirbutes can be set including deliver before and deliver after times. These are discussed in detail in the Openwave WAP Push Library.

Thank you for taking the time to read this note, and if you have any comments, suggestions, or feedback, please visit us in the Openwave Developer Forum.
 
Copyright © 2000-2008 Openwave Systems Inc.    About Us  |  Openwave  |  Terms & Conditions  |  Privacy Policy  |  Update Profile