The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Cisco::IPPhone - Package for creating Cisco IPPhone XML objects

SYNOPSIS

 use Cisco::IPPhone;

 $mytext = new Cisco::IPPhone;

 $mytext->Text({ Title => "My Title", Prompt => "My Prompt", 
                           Text => "My Text" });
 $mytext->AddSoftKeyItem( { Name => "Update", URL => "SoftKey:Update", 
                           Position => "1" });
 $mytext->AddSoftKeyItem( { Name => "Exit", URL => "SoftKey:Exit", 
                           Position => "2" });

 print $mytext->Content;

DESCRIPTION

Cisco::IPPhone - Package for creating Cisco IPPhone XML applications

This Cisco IPPhone module was created to provide a simple convenient method to display Cisco IP Phone objects and gather input from a Cisco 7940 or 7960 IP Phone. This module supports all known Cisco XML objects for 7940 and 7960 phones. Knowledge of Cisco XML syntax is not a requirement.

This Perl module gives the ability to use simple PERL objects to display XML on the IP Phone unlike to Cisco Software Development Kit (SDK) which uses Microsoft IIS Server, ASP's, JSP's, Javascript, COM Objects, and requires knowledge of XML syntax.

The following list gives typical services that might be supplied to a phone:

 - Weather
 - Stock information
 - Contact information
 - Company news
 - To-do lists
 - Real-time NFL scores
 - Daily schedule

Requirements

Developing Cisco IPPhone XML applications using the Cisco::IPPhone module requires the following: - Cisco CallManager Software or the CallManager Emulator Software - Any web server capable of running Perl CGI (Apache, etc) - A Cisco 7940 or 7960 IPPhone for testing the applications

Add services to Cisco CallManager:

 - Go to Feature -> Cisco IP Phone Services
 - Give the service a name and specify a URL such as:
       http://www.myorg.com/cgi-bin/menu.cgi
   Where menu.cgi is a Perl program that displays the menu
 - use the CCMUser URL to allow the user subscribe their phone to the service
   or have the Administrator assign the service to the phone using the 
   phone device configuration.

Methods

The following sections provide definitions and descriptions of each Cisco IP phone XML object: CiscoIPPhoneMenu, CiscoIPPhoneText, CiscoIPPhoneInput, CiscoIPPhoneDirectory, CiscoIPPhoneImage, CiscoIPPhoneGraphicMenu, CiscoIPPhoneIconMenu, CiscoIPPhoneExecute, CiscoIPPhoneError and CiscoIPPhoneResponse.

  • $object->Text

    This method takes a title, prompt, and text as input.

     $mytext = new IPPhone;
     $mytext->Text( { Title => "My Title", 
                      Prompt => "My Prompt",
                      Text => "My Text" });
  • $object->Menu

    This method takes a title, prompt, and text as input.

     # Create Menu Object
     $mymenu = new IPPhone;
     $mymenu->Menu( { Title => "My Title", 
                      Prompt => "My Prompt", 
                      Text => "My Text" });
  • $object->MenuItem

     $mymenu = new IPPhone;
     $mymenuitem = new IPPhone;
    
     # Create a menu object
     $mymenu->Menu( { Title => "My Title", 
                      Prompt => "My Prompt", 
                      Text => "My Text" });
    
     # Create a menuitem object 
     $mymenuitem->MenuItem({ Name => "Item1", 
                             URL => "http://www.mydomain.com" });
    
     # Add the menuitem object to the menu object
     $mymenu->AddMenuItemObject( { MenuItem => $mymenuitem });
  • $object->AddMenuItem

     $mymenu = new IPPhone;
    
     # Create a menu object
     $mymenu->Menu( { Title => "My Title", 
                      Prompt => "My Prompt", 
                      Text => "My Text" });
    
     # Add a menuitem to the menu object
     $mymenu->AddMenuItem({ Name => "Item 2", 
                            URL => "http://www.mydomain.com" });
  • $object->AddMenuItemObject

     $mymenu = new IPPhone;
     $mymenuitem = new IPPhone;
    
     # Create a menu object
     $mymenu->Menu( { Title => "My Title", 
                      Prompt => "My Prompt", 
                      Text => "My Text" });
    
     # Create a menuitem object 
     $mymenuitem->MenuItem({ Name => "Item1", 
                             URL => "http://www.mydomain.com" });
    
     # Add the menuitem object to the menu object
     $mymenu->AddMenuItemObject( { MenuItem => $mymenuitem });
    
     $mymenu->AddMenuItemObject( { MenuItem => $mymenuitem });
  • $object->Input

     $myinput = new IPPhone;
    
     # Create Input Object
     $myinput->Input( { Title => "Title Text", 
                       Prompt => "Prompt Text",
                       URL => "The target URL for the completed input" });
  • $object->InputItem

     # Input Types
    
     # ASCII => 'A'
     # Telephone => 'T
     # Numeric => 'N' 
     # Equation => 'E'
     # Uppercase => 'U'
     # Lowercase => 'L'
     # Password => 'P'
     
     $myinputitem = new IPPhone;
    
     # Create an input item
     $myinputitem->InputItem( { DisplayName => "Name of input field to display", 
                         QueryStringParam => "Parameter to be added to target URL",
                         DefaultValue => "Default Display Name",
                         InputFlags => "A"} );
  • $object->AddInputItem

     $myinput = new IPPhone;
    
     # Create Input Object
     $myinput->Input( { Title => "Title Text", 
                        Prompt => "Prompt Text",
    
     # Add an input item to the Menu Object
     $myinput->AddInputItem({ DisplayName => "Name of Input field to display", 
                          QueryStringParam => "Parameter to be added to target URl",
                          DefaultValue => "Default Display Name",
                          InputFlags => "A"} );
  • $object->AddInputItemObject

     $myinput = new IPPhone;
     $myinputitem = new IPPhone;
     
     # Create Input Object
     $myinput->Input( { Title => "My Title", 
                        Prompt => "My Prompt",
                        URL => "My URL" });

    # Create InputItem Object $myinputitem->InputItem( { DisplayName => "Display Name1", QueryStringParam => "QueryString:", DefaultValue => "Default", InputFlags => "A"} );

     # Add the inputitem to the input object
     $myinput->AddInputItemObject( { InputItem => $myinputitem });
  • $object->SoftKeyItem

     $mysoftkeyitem = new IPPhone;
     $mysoftkeyitem->SoftKeyItem ({ Name => "Submit",
                                   URL => "SoftKey:Submit",
                                   Position => "1" });
  • $object->AddSoftKeyItem

     $object->AddSoftKeyItem ({ Name => "Submit",
                                URL => "SoftKey:Submit",
                                Position => "1" });
     $object->AddSoftKeyItem ({ Name => "&lt&lt",
                                URL => "SoftKey:&lt&lt",
                                Position => "2" });
     $object->AddSoftKeyItem ({ Name => "Cancel",
                                URL => "SoftKey:Cancel",
                                Position => "3" });
  • $object->AddSoftKeyItemObject

     # Add the softkeyitem object to the object being built
     $object->AddInputItemObject( { SoftKeyItem => $mysoftkeyitem });
  • $object->Directory

     $mydirectory = new IPPhone;
    
     # Create Menu Object
     $mydirectory->Directory( { Title => "My Title", 
                               Prompt => "My Prompt" });
  • $object->DirectoryEntry

     # Add Directory Entries to Directory Object
     $mydirectoryentry->DirectoryEntry( { Name => "Entry1", 
                                         Telephone => "555-1212" } );
  • $object->AddDirectoryEntry

     $mydirectory->AddDirectoryEntry({ Name => "Entry 2", 
                                       Telephone => "555-1234" });
  • $object->AddDirectoryEntryObject

     $mydirectory->AddDirectoryEntryObject( { DirectoryEntry => $mydirectoryentry });
  • $object->Image

     $myimage = new IPPhone;
    
     # LocationX & LocationY: Position of the graphic (-1, -1 centers the graphic)
     # Height and Width define the number of pixels high and wide
     # Depth - number of bits per pixel (this number should be 2)
    
     # Create Menu Object
     $myimage->Image( { Title => "Some Image", Prompt => "View the image",
                      LocationX => "-1", LocationY => "-1", Width => "120",
                      Height => "44", Depth => "2", Data => "$data" });
     
  • $object->GraphicMenu

     # Data is the data portion of a CIP image.  Use gif2cip or the photoshop
     # plugin to generate the data portion of an image.
    
     use IPPhone;
     $mygraphicmenu = new IPPhone;
    
     $data = "FFFFFFFFFFFFFFFFFFFF";
    
     # Create Menu Object
     $mygraphicmenu->GraphicMenu( { Title => "My Image", 
                     Prompt => "View the image",
                     LocationX => "-1", LocationY => "-1", 
                     Width => "10",
                     Height => "10", 
                     Depth => "2", 
                     Data => "$data" });
    
     print $mygraphicmenu->Content;
  • $object->IconMenu

     use Cisco::IPPhone;
    
     $myiconmenu = new Cisco::IPPhone;
    
     $data = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
    
     # Create Icon Menu
     $myiconmenu->IconMenu( { Title => "Icon Menu", 
                       Prompt => "Select an icon" });
     
     $myiconmenu->AddMenuItem({  IconIndex => "1", 
                                Name => "Menu Item 1", 
         URL => "http://192.168.250.31/cgi-bin/metavante/text.cgi" });
     $myiconmenu->AddMenuItem({  IconIndex => "1", 
                                Name => "Menu Item 2", 
         URL => "http://192.168.250.31/cgi-bin/metavante/text.cgi" });
     $myiconmenu->AddMenuItem({  IconIndex => "1", 
                                Name => "Menu Item 3", 
         URL => "http://192.168.250.31/cgi-bin/metavante/text.cgi" });
    
     # Index is the numeric index of the icon to be displayed
     # Up to 10 instances of iconitem can be displayed
     $myiconmenu->AddIconItem ({ Index => "1", 
                                Width => "10",
                                Height => "10", 
                                Depth => "2", 
                                Data => "$data" });
    
     print $myiconmenu->Content;
  • $object->IconItem

     $myiconitem = IconItem ({ Index => "1",
                                Width => "5",
                                Height => "5", 
                                Depth => "2", 
                                Data => "$data" });
  • $object->AddIconItem

     $myiconmenu->AddIconItem ({ Index => "1", 
                                Width => "5",
                                Height => "5", 
                                Depth => "2", 
                                Data => "$data" });
  • $object->AddIconItemObject

     $myiconmenu->AddIconItemObject( { IconItem => $myiconitem });
  • $object->Execute

     # Use HTTP POST to push an execute ITEM to an IP Phone
     # One Execute Object can take up to 3 Execute Items
     # A response item will be returned from the phone
     # Phone will require authentiation.  This is the username and password
     # from the call manager database associated with this extension
    
     # Special characters in a URL pushed to a phone should be properly escaped 
     Character             Escape Sequence  
     & Ampersand           &
     " Quote               "
     ' Apostrophe          '
     < Left angle bracket  &lt;
     > Right angle bracket &gt;
     
     $myexecute->Execute;
     $myexecute->AddExecuteItem( { ExecuteItem => "http://$SERVER/cgi-bin/my.cgi" });
     
  • $object->AddExecuteItem

     $myexecute->Execute;
     $myexecute->AddExecuteItem( { ExecuteItem => "http://$SERVER/cgi-bin/my.cgi" });
     
     Here's the HTML that can push an execute object to an IP Phone
     <HTML>
     <HEAD></HEAD>
     <BODY>
     <FORM action="http://$ipphone/CGI/Execute" Method="POST">
     <TEXTAREA NAME="XML" Rows="5" Cols="60">
       print $myexecute->Content_Noheader;
     </TEXTAREA>
      <BR>
     <input type=submit value=POST>
     </FORM>
     </BODY>
     </HTML>
  • $object->ExecuteItem

     $myexecuteitem->ExecuteItem ( { ExecuteItem => "http://$SERVER/cgi-bin/my.cgi" });
  • $object->AddExecuteItemObject

     $myexecute->AddExecuteItemItemObject ( { ExecuteItem => $myexecuteitem });
  • $object->Response

     $myresponse = new IPPhone;
     $myresponse->Response; #Response Object takes no Input
  • $object->ResponseItem

     $myresponseitem = IPPhone;
     $myresponseitem->ResponseItem({ Status => "URL1",
                                     Data => "Data1",
                                    URL => "URL or URI associated with request" });
  • $object->AddResponseItem

     # Response Items are sent back from the phone, but you can build one
    
     use IPPhone;
     $myresponse = new IPPhone;
    
     $myresponse->Response; #Execute Object takes no Input
    
     # One Response Object can take up to 3 Execute Items
     $myresponse->AddResponseItem( { Status => "Success or failure of the action",
                                    Data => "Data1",
                                    URL => "URL or URI associated with request" });
     $myresponse->AddResponseItem( { Status => "Success or failure of the action",
                                    Data => "Data2",
                                    URL => "Success or failure of the action" });
     print $myresponse->Content;
  • $object->AddResponseItemObject

  • $object->Error

     # This object is usually sent back from the phone
     
     $myerror = new IPPhone;
     $myerror->Error( { Number => "1" });
     print $myerror->Content;
  • $object->Print

     # Print the Object to the Phone
     # Deprecated.  Use "print $object->Content"
     $object->Print
  • $object->Content

     # Print the Object to the Phone
     print $object->Content;
    
     # Print the Object to the phone with an automatic refresh every 60 seconds
     print $object->Content(Refresh=>'60');
     
     # Print the Object to the phone with an automatic refresh every 60 seconds
     # Refresh with a different URL
     print $object->Content(Refresh=>'60', URL=>"http://www.my.com/cgi-bin/t.cgi");
     
     # Expires page before current time (expires page immediately)
     print $object->Content(Date=>'Tue, 15 May 2002 23:45:04 GMT');
     print $object->Content(Expires=>'Tue, 15 May 2002 23:44:04 GMT');
    
     # Expiration is date and time of request minus one minute
     print $object->Content(Date=>'Tue, 15 May 2002 23:45:04 GMT');
     print $object->Content(Expires=>'-1');
    
     # Set a cookie. The IP Phone will use up to 4 cookies of 255 bytes in length
     print $object->Content(Cookie=>'MyCookieName=Bingo; path=/');
    
     # Go to a specified location in conjuntion with a status code such as
     # 301 Moved Permanently, 303 See Other, 307 Temporary Redirect, or 
     # 302 Object Moved.  Combined with user-agent logic, this can be effective
     print $object->Content(Location=>'http://services.acme.com');
  • $object->Content_Noheader

     # Assign object to another object with no Content Type header
     # Can be used to view an object without the header
     # This should not be sent to the phone since the phone needs a content-type
    
     $myobject = $object->Content_Noheader;

Examples

Example demonstrating Cisco IP Phone Text object

 #!/usr/bin/perl

 use IPPhone;
 $mytext = new IPPhone;

 $mytext->Text( { Title => "My Title", Prompt => "My Prompt",
                           Text => "My Text" });
 $mytext->AddSoftKeyItem( { Name => "Update", URL => "SoftKey:Update",
                           Position => "1" });
 $mytext->AddSoftKeyItem( { Name => "Exit", URL => "SoftKey:Exit",
                           Position => "2" });
 print $mytext->Content;
 __END__

 Generates the following:

 Content-Type: text/xml

 <CiscoIPPhoneText>
 <Title>My Title</Title>
 <Prompt>My Prompt</Prompt>
 <Text>My Text</Text>
 <SoftKeyItem>
   <Name>Update</Name>
   <URL>SoftKey:Update</URL>
   <Position>1</Position>
 </SoftKeyItem>
 <SoftKeyItem>
   <Name>Exit</Name>
   <URL>SoftKey:Exit</URL>
   <Position>2</Position>
 </SoftKeyItem>
 </CiscoIPPhoneText>

Example showing IP Phone Menu

 #!/usr/bin/perl
 use IPPhone;
 $mymenu = new IPPhone;
 $mymenuitem = new IPPhone;

 # Create Menu Object
 $mymenu->Menu( { Title => "My Title", 
                  Prompt => "My Prompt", 
                  Text => "My Text" });

 # Add Menu Items to Menu Object
 $mymenuitem->MenuItem( { Name => "Item1",  
                          URL => "http://www.mydomain.com" } );

 # Add Menu Item Object to the Menu
 $mymenu->AddMenuItemObject( { MenuItem => $mymenuitem });

 # Instead of creating a separate menu item object using MenuItem and
 # adding the object to the menu using AddMenuItemObject, 
 # you can simply use AddMenuItem to do it in one step

 $mymenu->AddMenuItem({ Name => "Item 2", 
                        URL => "http://www.mydomain.com" });
 
 $mymenu->AddSoftKeyItem({ Name => "Select", URL => "SoftKey:Select", 
                           Position => "1" });
 $mymenu->AddSoftKeyItem({ Name => "Exit", URL => "SoftKey:Exit", 
                           Position => "2" });
 
 # Print the Menu Object to the Phone
 print $mymenu->Content;

 
 Content-Type: text/xml

 <CiscoIPPhoneMenu>
 <Title>My Title</Title>
 <Prompt>My Prompt</Prompt>
 <MenuItem>
   <Name>Item1</Name>
   <URL>http://www.mydomain.com</URL>
 </MenuItem>
 <MenuItem>
   <Name>Item 2</Name>
   <URL>http://www.mydomain.com</URL>
 </MenuItem>
 <SoftKeyItem>
   <Name>Select</Name>
   <URL>SoftKey:Select</URL>
   <Position>1</Position>
 </SoftKeyItem>
 <SoftKeyItem>
   <Name>Exit</Name>
   <URL>SoftKey:Exit</URL>
   <Position>2</Position>
 </SoftKeyItem>
 </CiscoIPPhoneMenu>

Example using Execute object to push messages to the phone

 #!/usr/bin/perl
 # Mark Palmer - markpalmer@us.ibm.com
 # Must use authentication when POSTING an object to a Cisco IPPhone.
 # User should be a user in the global directory associated with the phone
 # Can use this script to send messages to IPPhones
 
 use Cisco::IPPhone;
 use LWP::UserAgent;
 use URI;
 $ua = LWP::UserAgent->new;
 $myexecute = new Cisco::IPPhone;
 
 $SERVER = "192.168.250.17";
 $IPPHONE = "192.168.250.7";
 $USER = 'myname';
 $PASSWORD = 'mypassword';
 $POSTURL = "http://${IPPHONE}/CGI/Execute";
 
 # URL that phone will fetch
 $URL1 = "http://$SERVER/cgi-bin/nfl.cgi";
 
 # Build Execute Object with up to 3 Execute Items
 $myexecute->Execute;
 $myexecute->AddExecuteItem( { ExecuteItem => "$URL1" });
 my $xml = $myexecute->Content_Noheader;
 
 # Translate non-alpha chars into hex
 $xml = URI::Escape::uri_escape("$xml"); 
 
 my $request = new HTTP::Request POST => "$POSTURL";
 $request->authorization_basic($USER, $PASSWORD);
 $request->content("XML=$xml"); # Phone requires parameter named XML
 my $response = $ua->request($request); # Send the POST
 
 if ($response->is_success) {
   $result = $response->content;
   if ($result =~ /CiscoIPPhoneError Number="(\d+)"/) {
      $errno = $1;
      if ($errno == 4) {
          print "Authentication error\n";
      } elsif ($errno == 3) {
          print "Internal file error\n"; 
      } elsif ($errno == 2) {
          print "Error framing CiscoIPPhoneResponse object\n"; 
      } elsif ($errno == 1) {
          print "Error parsing CiscoIPPhoneExecute object\n"; 
      } else {
          print "Unknown Error\n";
          print $result;
      }
   }
 } else {
   print "Failure: Unable to POST XML object to phone $IPPHONE\n";
   print $response->status_line;
 }

EXPORT

None by default.

AUTHOR

Mark Palmer, markpalmer@us.ibm.com, 7/13/2002

SEE ALSO

perl(1).