cancel
Showing results for 
Search instead for 
Did you mean: 
cancel

PHP and Cisco IM&P (Jabber)

1342
Views
1
Helpful
0
Comments
Cisco Employee

PHP and Cisco IM&P (Jabber)

If you want to integrate Jabber/XMPP access to Cisco IM&P within a web application, the best way to do that is to use Cisco Jabber SDK, also known as CAXL, a Javascript library.

However, there are times when you want to put together simple web or command-line applications and utilities that make use of XMPP.  JAXL (an open source project, not Cisco) is a good way to do that with PHP.  With a little easy tweaking, it works fine with Cisco IM&P XMPP servers.  And, while not being as comprehensive as Jabber SDK, PHP is often easier to work with than Javascript if what you want is basic XMPP IM and Presence functionality.

What follows are instructions for getting JAXL installed and working, along with two sample applications.  One sample application is a modified version of an example program that comes with JAXL.  This sample is an echo bot.  You log in as a Jabber user when you run it, and whenever you send a message to that Jabber user, it will be echoed back to you. The other sample application is a simple command-line program to send an instant message.  This is an easy way to invoke a message alert from other applications.

All the instructions below are for Windows 10.

INSTALL AND CONFIGURE PHP

Download and install PHP.  I recommend the latest version which is currently 7.1.2.

All of the instructions below assume you install php in the directory C:\php.  Modify the instructions for your installation if necessary.

I recommend you start by copying the file php.ini-development to php.ini.  You can copy php.ini-production to php.ini and make the needed edits when you're ready to put your project into production.

Edit your php.ini file to enable a number of extensions you'll need.  These are all the extensions I have enabled in PHP 7.1.2.  Not all of them are needed for JAXL, but I use PHP for other projects, too. You may want to enable other extensions if you're using typical services like MySQL or PostgreSQL.

You'll need curl if you intend to use HTTP/BOSH for your Jabber connection.  You need openssl for authentication.  Enable all the other extensions below the comments except maybe sqlite3 (unless you intend to use sqlite).  You don't need SOAP for JAXL, but it comes in handy for other Cisco APIs.

;extension=php_bz2.dll
extension=php_curl.dll
;extension=php_fileinfo.dll
;extension=php_ftp.dll
;extension=php_gd2.dll
;extension=php_gettext.dll
;extension=php_gmp.dll
;extension=php_intl.dll
;extension=php_imap.dll
;extension=php_interbase.dll
;extension=php_ldap.dll
;extension=php_mbstring.dll
;extension=php_exif.dll      ; Must be after mbstring as it depends on it
;extension=php_mysqli.dll
;extension=php_oci8_12c.dll  ; Use with Oracle Database 12c Instant Client
extension=php_openssl.dll
;extension=php_pdo_firebird.dll
;extension=php_pdo_mysql.dll
;extension=php_pdo_oci.dll
;extension=php_pdo_odbc.dll
;extension=php_pdo_pgsql.dll
;extension=php_pdo_sqlite.dll
;extension=php_pgsql.dll
;extension=php_shmop.dll

; The MIBS data available in the PHP distribution must be installed.
; See http://www.php.net/manual/en/snmp.installation.php
;extension=php_snmp.dll

extension=php_soap.dll
extension=php_sockets.dll
;extension=php_sqlite3.dll
extension=php_tidy.dll
extension=php_xmlrpc.dll
extension=php_xsl.dll

INSTALLING JAXL

You should install JAXL using a PHP dependency manager called Composer.  See the link below.

I do not recommend downloading and running the Composer-Setup.exe from the linked page.  The PHP installation commands are more reliable.  Copy each line from the page linked below and run each one from your PHP directory.

I am not including those PHP commands here because they change with new versions.  You should get the commands from the linked page.

https://getcomposer.org/download/

The instructions on this next page ensures you always get the latest version of Composer . These instructions, however, are based on unix/Linux shell commands, not Windows shells.

https://getcomposer.org/doc/faqs/how-to-install-composer-programmatically.md

Once Composer is installed, change to the php directory and run:

php composer.phar require "jaxl/jaxl=^3.1.0"

You should see something like this (on Windows you will also see a number of cryptic looking escape characters):

./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing jaxl/jaxl (v3.1.0): DownloadinDownloading (100%)
jaxl/jaxl suggests installing ext-pcntl (Interrupt JAXL with signals)
Writing lock file
Generating autoload files

Now that JAXL is installed, change to your php subdirectory \php\vendor\jaxl\jaxl\src\JAXL

Edit jaxl.php and change this:

     $this->require_xep('0206');

To this:

     $this->require_xep(array('0206'));

Reason: The require_xep method takes an array as an argument.  There are other possible fixes, but this is the simplest.  This should fix any problems you might have connecting using HTTP/BOSH. However, if you intend to use BOSH, we strongly recommend that you use Cisco Jabber SDK (CAXL) instead of JAXL.  If you use Jabber SDK or simply use JAXL with an XMPP connection (not BOSH), you don't need to make the above change, because it will never be used.

Now change to the subdirectory .\xmpp

Edit xmpp_stream.php and change this:

case 'PLAIN':
case 'X-OAUTH2':
     $stanza->t(base64_encode("\x00".$user."\x00".$pass));
     break;

To this:

case 'PLAIN':
     $stanza->t(base64_encode($user."\x00".substr($user,0,strpos($user,'@'))."\x00".$pass));
     break;
case 'X-OAUTH2':
     $stanza->t(base64_encode("\x00".$user."\x00".$pass));
     break;

Reason: Many, if not most XMPP servers (including Cisco IM&P) use a base64 encoding of a combination of JID, USERNAME and PASSWORD for PLAIN authentication.  In this case, $user is actually the jid, so I just substring it to get the username.  I haven’t tried it with X-OAUTH2, so I don’t know if the change applies to that, as well.  So I just separated the two.

RUNNING EXAMPLES IN THE EXAMPLES DIRECTORY

Change to the php subdirectory php\vendor\jaxl\jaxl\examples

If you want to run some of the examples from here, you'll need to make a couple modifications.

Normally, you run the JAXL examples from the parent directory and specify the path in your command, like php examples\some-example.php.  Personally, I like to save typing and run the examples from the examples directory.

Edit php\vendor\jaxl\jaxl\examples\_bootstrap.php to make sure it can find your autoload.php file and can find all of the dependencies when you run the examples from within the examples directory.

Add a comma and the bottom line to this code to make it possible to run the examples in the examples directory:

foreach (array(
     dirname(__FILE__) . '/../../autoload.php',
     dirname(__FILE__) . '/../vendor/autoload.php',
     dirname(__FILE__) . '/vendor/autoload.php',  // add comma
     dirname(__FILE__) . '/../../../autoload.php' // add this line

EXAMPLE PROGRAM: MESSAGE.PHP

This is a simple message sending application (you'll find a proper version attached as message.php; this is simplified).

All this does is send a message you specify on the command line to a user you specify on the command line.  It sends the message and exits.

This is not only a useful example for JAXL, it's actually useful in practice.  This is suitable to send alerts via Jabber.  For example, if you have an application that runs into a network problem, you could have your application run this simple program to send a message like "Application lost connection to server" to an IT worker.

Here is the simplified sample code:

<?php

// Run as:
// php message.php userJid password destinationJid "message in quotes"

// Get all the needed dependencies
require dirname(__FILE__) . '/_bootstrap.php';

// Get the destination Jid and the message from the command line
if ($argc < 5) {
    echo "Usage: $argv[0] jid pass to message".PHP_EOL;
    exit;
} else {
     $message = $argv[4];
     $tojid = $argv[3];
}

//
// initialize JAXL object with initial config
// based on the command line arguments
//
$client = new JAXL(array(
    'jid' => $argv[1],
    'pass' => $argv[2],
     
     // If your Cisco IM&P server address is different than the domain in your Jid
     // then you should uncomment and define this
     // For example, our lab uses a Jid like nicholas@cisco.com, 
     // but the host is ds-cup11-5.cisco.com, not cisco.com,
     // so we would define the host here to be ds-cup11-5.cisco.com
    //'host' => 'Your Cisco IM&P server',

     // authorization will default to PLAIN
    'auth_type' => 'PLAIN',

     // get debug output just for kicks
    'log_level' => JAXLLogger::DEBUG  // INFO is default
));

//
// required XEP's
//
$client->require_xep(array(
    '0199'  // XMPP Ping
));

//
// add necessary event callbacks here
//
function on_disconnect_callback()
{
    JAXLLogger::info("got on_disconnect cb");
}
$client->add_cb('on_disconnect', 'on_disconnect_callback');

function on_auth_success_callback()
{
    global $client;
     global $message;
     global $tojid;
    JAXLLogger::info("got on_auth_success cb, jid ".$client->full_jid->to_string());

     $client->send_chat_msg($tojid, $message, null, null);
    $client->send_end_stream();
}
$client->add_cb('on_auth_success', 'on_auth_success_callback');

function on_auth_failure_callback($reason)
{
    global $client;

    $client->send_end_stream();
    JAXLLogger::info("got on_auth_failure cb with reason $reason");
}
$client->add_cb('on_auth_failure', 'on_auth_failure_callback');

//
// finally start configured xmpp stream
//
$client->start();

echo "done".PHP_EOL;

EXAMPLE PROGRAM: ECHO_BOT_CISCO.PHP

This one is an echo bot (it logs in as a Jabber user, and echos back whatever messages you send to that user).  The file is echo_bot_cisco.php.

See the attached file echo_bot_cisco.php to view this one.

Here's how to create it yourself from the sample echo_bot.php.

Edit echo_bot.php and save it as echo_bot_cisco.php.

First, we'll need to start JAXL differently, because we're not using unix sockets on Windows 10.  We also don't want the debug shell.

Change this (this is near the bottom of the file):

$client->start(array(
    '--with-debug-shell' => true,
    '--with-unix-sock' => true
));

To this:

$client->start();

Let's get some more informative output when running the echo bot.  This is near the top of the file.

Change this:

    'log_level' => JAXLLogger::INFO

To this:

     
    'log_level' => JAXLLogger::DEBUG

Let's get rid of the outdated vCard queries, too.  Otherwise your echo bot may hang while trying to get a vCard.

Comment out this code:

    // fetch vcard
//    $client->get_vcard();

Comment out this code, too, like this:

/*
    if ($type == "available") {
        // fetch vcard
        $client->get_vcard($stanza->from);
    }
*/     

The default show value for your echo bot is "dnd" (Do Not Disturb).  Let's change it to "available", which in XMPP terms is actually an empty string.  The "available!" string is actually a custom status, which could be anything, like "Out to lunch".

Change this:

    $client->set_status("available!", "dnd", 10);

To this:

    $client->set_status("available!", "", 10);

Finally, the echo bot assumes the host value is the same as the domain in your JID (username@domain).  Depending upon how you have your Cisco IM&P server set up, your host may not equal your JID domain.  For example, in our lab, we use the domain cisco.com, but the CIMP host is actually ds-cup11-5.cisco.com. So I edited the configuration at the top of the PHP file to this:

$client = new JAXL(array(
    // (required) credentials
    'jid' => $argv[1],
    'pass' => $argv[2],

    // (optional) srv lookup is done if not provided
    'host' => 'ds-cup11-5.cisco.com',

Now you're ready to run the echo bot and try it out.  Assuming your JID is carlotta@tendant.com and your password is tendant, run it this way:

php echo_bot.php carlotta@tendant.com tendant

You could specify an authorization type as the third argument, but our lab is fine with the default PLAIN.

Open another client and send some messages to carlotta@tendant.com.  They should be echoed back to you.  Once you have this working, you'll know what to look out for and create a solid base on which to build a more complex application.

CreatePlease to create content
Content for Community-Ad
August's Community Spotlight Awards