Click to Call with PHP-SIP

posted by Chris on 2009-10-07 22:29:27

In this tutorial we will show how to implement "click to call" functionality in a web page using PHP-SIP class, free opensips.org SIP registrar service and Twinkle softphone.

The same principle can be used with any RFC compliant SIP service or your own PBX such as Asterisk or OpenSIPs.

Prerequisites

In order to accomplish scenario shown in a diagram below, you will need the following:

  • Basic knowledge of SIP protocol.
  • Free SIP account from opensips.org - this will be our SIP Proxy and sip:user1@sip as shown in the diagram below. Alternatively any SIP compliant SIP service or your own SIP Proxy can be used instead.
  • PHP (version >= 5) enabled web server.
  • Twinkle softphone (on Ubuntu linux can be installed with the following command: apt-get install twinkle) or any other SIP softphone or normal phone. However we provide detailed instructions for Twinkle only.


SIP Flow diagram

Click to Call SIP flow diagram

  1. User submits a form with calling (sip:user1@sip) and called (sip:user2@sip) parties SIP URIs.
  2. Web Server sends INVITE to sip:user1@sip.
  3. Once INVITE is accepted by user1, web server immediately sends REFER with sip:user2@sip in "Refer-to" header.
  4. Web Server terminates "call" by sending BYE to user1.
  5. As instructed in REFER request sent by a web server, user1 sends INVITE to sip:user2@sip.


1. Create Click to Call web page

Go to your web server root directory and create c2c.php file:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">

<head><title>PHP-SIP Click to Call</title></head>

<body>

<?php if (isset($_POST['from']) && isset($_POST['to'])) : ?>

  <?php require_once('php-sip/PhpSIP.class.php') ?>

  <?php $from = $_POST['from']; $to = $_POST['to'] ?>

  Trying call from <?php echo $from ?> to <?php echo $to ?> ...<br />

  <?php flush() ?>

  <pre>
  <?php 

    try{

      $api = new PhpSIP();
      // if you get "Failed to obtain IP address to bind. Please set bind address manualy."
      // error, use the line below instead
      // $api = new PhpSIP('you_server_IP_address');

      $api->setDebug(true);

      // if your SIP service doesn't accept anonymous inbound calls uncomment two lines below
      //$api->setUsername('auth_username');
      //$api->setPassword('auth_password');

      $api->addHeader('Subject: click2call');
      $api->setMethod('INVITE');
      $api->setFrom('sip:c2c@'.$api->getSrcIp());
      $api->setUri($from);

      $res = $api->send();

      if ($res == 200)
      { 
        $api->setMethod('REFER');
        $api->addHeader('Refer-to: '.$to);
        $api->addHeader('Referred-By: sip:c2c@'.$api->getSrcIp());
        $api->send();

        $api->setMethod('BYE');
        $api->send();

        $api->listen('NOTIFY');
        $api->reply(481,'Call Leg/Transaction Does Not Exist');
      }

      if ($res == 'No final response in 5 seconds.')
      {
        $api->setMethod('CANCEL');
        $res = $api->send();
      }

      echo $res;

    } catch (Exception $e) {

      echo "Opps... Caught exception:";
      echo $e;
    }

  ?>
  </pre>
  <hr />

  <a href="<?php echo $_SERVER['PHP_SELF']; ?>">Back</a>

<?php else : ?>

  <form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
    <fieldset>
      From: <input type="text" name="from" size="25" value="" />
      To: <input type="text" name="to" size="25" value="sip:enum-test@sip.nemox.net" />
      <input type="submit" value="Call" />
    </fieldset>
  </form>

<?php endif ?>

</body>
</html>


Next we need to download PHP-SIP class from code.google.com/p/php-sip/downloads/list and extract it into your web server root directory, so it looks as shown below:

/web-root/c2c.php
/web-root/php-sip/PhpSIP.class.php
/web-root/php-sip/PhpSIP.Exception.php
/web-root/php-sip/README


Now open the web browser and navigate to http://you_web_server/c2c.php which should show a form similar to:

Click to Call form


2. Register SIP Phone

For the purpose of this tutorial we assume our test account at opensips.org is jsmith and softphone used for our test will be Twinkle. However you can use any other SIP proxy and software or normal SIP phone.

Once your SIP account at opensips.org is set up, start Twinkle, select Edit => User profile... and enter your SIP account details as shown below:

Twinkle settings

  • enter your username into fields (1) (2) and (5)
  • enter opensips.org into fields (3) and (4)
  • enter your password into field (6)
  • select SIP server tab (7) and enter opensips.org into field (8)
  • select SIP protocol tab (9) and deselect Ask user permission for transfer check box


...finally click OK button and if everything went well your Twinkle will display:

opensips.org, registration succeeded (expires = 3600 secods)


3. Testing

Open a web browser and navigate to our "Click to Call" page. Enter sip:your_username@opensips.org into From field, leave default sip:enum-test@sip.nemox.net in To field and click Call button. Twinkle should indicate incoming call...

Twinkle - incoming call

...click Answer and your phone will be automatically connected to sip:enum-test@sip.nemox.net which is a public ENUM test service provided by nemox.net group.

Congratulations! Your Click to Call web page works!

Summary

The above illustrates the simplest possible scenario. In a real life applications you may want to use fancy Ajax instead of standard HTML form. Fetch From and/or To SIP URIs from database or do number of even more exciting things.



Comments

Gravatar
Dmitry 2009-10-16 15:17:02

How can I place an outbound call and then connect it with my extension?

I try to do as following:

from: sip:91112233@my-asterisk.ip.com
to: sip:1000@my-asterisk.ip.com

where 91112233 is number 111-2233 called via 9-trunk
and 1000 - my extension.

but it does not call anywhere...
can somebody tell me if my task is reachable with phpsip ?

thanx for help!

Gravatar
Alan 2009-10-16 19:47:57

Hi Dmitry, thanks for your interest in PHP-SIP project.

Yes, your scenario is possible. You will need to download the latest version (>= 0.3.1) of php-sip and make modifications to c2c.php as shown below:

Uncomment:
$api->setUsername('1000');
$api->setPassword('auth_password');

and replace auth_password as defined in your sip.conf for user 1000.

Replace:
$api->setFrom('sip:c2c@'.$api->getSrcIp());
with:
$api->setFrom('sip:1000@asterisk_ip');

Replace:
$api->addHeader('Referred-By: sip:c2c@'.$api->getSrcIp());
with:
$api->addHeader('Referred-By: sip:1000@asterisk_ip');

Add:
usleep(500000);
before:
$api->setMethod('REFER');

Gravatar
Mehul 2009-11-13 11:54:51

Thanks for useful information. I am making outbound call thru c2c.php. For that i m putting
From : 19782232254@192.168.1.10
To: 1000@192.168.1.10

I did below changes in c2c.php:
$api->setUsername('1000');
$api->setPassword('1234');

$api->setFrom('sip:1000@192.168.1.10');

$api->addHeader('Referred-By: sip:1000@192.168.1.10');

After doing this when i m clicking on call it is giving me below error.

=============================================
Trying call from 19782232254@192.168.1.10 to sip:1000@192.168.1.10 ...



Fatal error: Call to undefined function sys_get_temp_dir() in /var/www/html/php-sip/PhpSIP.class.php on line 247

==============================================

What could be the issue...

Thanks

Gravatar
Chris 2009-11-13 12:06:44

Hi Mehul,

It seems to me you are running PHP version 4.x, and it is missing sys_get_temp_dir() function.

You will need to use PHP version >= 5.2 with PhpSIP.

Gravatar
Kathy 2009-11-18 18:27:12

Hi,

This is a great script. I have a small problem that maybe you could help me with. I am trying to use the class to make an outgoing call from a webpage. I have done all the things above you stated to do. No matter what configuration or port options I set, I always get No Final Response in 5 seconds.

My sip listens on port 5090
My client softphone listens on port 5060

Call from:
sip:[mynum]*[ext]@[sip.provider.com]
Call to:
sip:[phonenum]@[sip.provider.com]

I have put in my user and password in the c2c.php file.

Any help would be great, Thanks

Gravatar
Chris 2009-11-21 09:24:16

Hi Kathy, I will try to help, but can you please let me know the following:

1. What OS do you use? Window/Linux
2. What version of PHP do you use?
3. What is your network layout? Is the web server hosting c2c.php on
the same network as your softphone? Is it a private LAN or public
internet?

Could you please email the above info to chris [at-sign-here] level7systems [dot] co [dot] uk

Gravatar
Franck Chionna 2010-01-06 03:02:20

hello Level7,

is php-sip can be used to as user management (create, modify, credits etc..) ? also is it possible to use pstn phone number format ?
sorry for my newbie question, I'm fairly new in SIP world

Thanks

Gravatar
Chris 2010-01-06 08:36:53

Hi Franck,

No, unfortunately you can't manage user accounts with php-sip. You would need SIP registrar/proxy server and database back end for this.

I can recommend openSIPs software: http://opensips.org

Gravatar
kloula moez 2010-02-14 21:51:29

hello level7
I use ubuntu 9.01 and i have some problem withe the installation and i have this message that i don't resolve please help me to understand :

Trying call from sip:kloulamoez@opensips.org to sip:enum-test@sip.nemox.net ...

Opps... Caught exception:exception 'Exception' with message 'Invalid argument' in /opt/lampp/htdocs/php-sip/PhpSIP.class.php:730
Stack trace:
#0 /opt/lampp/htdocs/php-sip/PhpSIP.class.php(664): PhpSIP->sendData('INVITE sip:klou...')
#1 /opt/lampp/htdocs/c2c.php(39): PhpSIP->send()
#2 {main

Gravatar
Chris 2010-02-14 22:15:33

Hi,

Try replacing:

$api = new PhpSIP();

with

$api = new PhpSIP('you_server_IP_address');

Gravatar
Pablo 2010-02-20 21:18:15

it worked very well... mmm... i tried this one many time without any success, until i tried a different PC... i'm still wondering why it didn't work in my laptop but my desktop PC. Important: i tried using the X-Lite and it worked as well as in a linux based PC using Twinkle. Thanks bro...

Gravatar
Peter 2010-02-23 16:06:26

I think this is just what I was looking for!

I'm just reading through the class now, any chance that I could read a hint status i.e. BLF button to show presence on the web page?

Gravatar
Chris 2010-02-23 21:17:50

Hi Peter. I am afraid you will not be able read BLF status with PHP-SIP. What you need is to SUBSCRIBE to phone BLF events sent via NOTIFY packets. To do this you will need a SIP server listening all the time in the background. This is currently not supported by PHP-SIP.

Gravatar
Tigran 2010-02-27 10:23:56

How can I make external calls betwwen two external phone numbers?
I try to use my SIP server, but:
Opps... Caught exception:exception 'PhpSIPException' with message 'Failed to bind my.sip.net:23 Invalid argument' in /www/php-sip/PhpSIP.class.php:1311
Stack trace:
#0 /www/php-sip/PhpSIP.class.php(256): PhpSIP->createSocket()
#1 /www/php-sip/c2c.php(23): PhpSIP->__construct('my.sip.net')
#2 {main}

Gravatar
Chris 2010-02-27 16:17:39

Hi Tigran, try using your server IP address, instead of domain name. For example:

$api = new PhpSIP('10.10.10.12');

instead of:

$api = new PhpSIP('my.sip.net');



Leave Your Comment

Your name: *
Your Email: *   Will not be published
Your comment: *
Captcha image
To help us prevent automated abuse of this service
please enter the text displayed in the image above: *



All submitted reviews/comments become the licensed property of Level 7 Systems Ltd.

Categories

Enter your email address:

Delivered by FeedBurner

RSS Feed Subscribe with in your feed reader