1

What i'm trying to do is implement a SIP client which listens for SIP messages.Ok so i have run the SIP client on a server 192.168.0.246 and the SIP server is running on 192.168.2.40.Now have a look at the below screen shot.

enter image description here

Its a trace file of the server running the client code on 192.168.0.246. As u can see the server receives messages from 192.168.2.40 using SIP/SDP protocol but when the client program running on 192.168.0.246 sends back message to 192.168.2.40 using UDP protocol its shown as UDP protocol, which is correct.But no response from 192.168.2.40 after this. So i'm assuming it has something to do with the protocol shown as UDP.So if i'm rite i should get that to SIP/SDP.

So my question is how to make this UDP change to SIP/SDP.

And here is my php code:

<?php

//Reduce errors
error_reporting(~E_WARNING);

//Create a UDP socket
if(!($sock = socket_create(AF_INET, SOCK_DGRAM, 0)))
{
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);

    die("Couldn't create socket: [$errorcode] $errormsg \n");
}

echo "Socket created \n";

// Bind the source address
if( !socket_bind($sock, "192.168.0.246" , 5060) )
{
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);

    die("Could not bind socket : [$errorcode] $errormsg \n");
}

echo "Socket bind OK \n";

//Do some communication, this loop can handle multiple clients

function GetBranchValue($message)
{
    $data = "";
    if(preg_match('/branch=.*/i', $message, $output))
        $data = explode("=",$output[0]);
    if(sizeOf($data)>1)
        return $data[1];
    else
        return "None";
}

function GetTag($message)
{
    $data = "";
    if(preg_match('/tag=.*/i',$message, $output))
        $data = explode("=", $output[0]);
    if(sizeOf($data)>1)
        return $data[1];
    else
        return "None";
}

function GetCallId($message)
{
    $data = "";
    if(preg_match('/Call-ID:.*/i', $message, $output))
        $data = explode(":",$output[0]);
    if(sizeOf($data)>1)
        return $data[1];
    else
        return "None";
}

function GetCSeq($message)
{ 
    $data = "";
    if(preg_match('/CSeq:.*/i', $message, $output))
    {
        $data = explode(":", $output[0]);
        $data = explode(" ",$data[1]);
    }
    if(sizeOf($data[1])>0)
        return $data[1];
    else
        return "None";
}

function CreateResponse($message)
{
    $msg = "SIP/2.0 302 Moved temporarily
Via:SIP/2.0/UDP 192.168.2.40:5060;branch=".GetBranchValue($message)."
From: <sip:+12012030008@192.168.2.40:5060>;tag=".GetTag($message)."
To:<sip:+17066458407@192.168.0.246:5060;user=phone>;tag=883069368-1363286882583
Call-ID:".GetCallId($message)."
CSeq:".GetCSeq($message)." INVITE
Contact:<sip:+17066458407@192.168.0.246:5060;user=phone>;q=0.5,<sip:+17066458407@192.168.0.246:5060;user=phone>;q=0.25
Content-Length:0";
    return $msg;
}

function Create300Response($message)
{
    $msg = "SIP/2.0 300 Multiple Choices
Via: SIP/2.0/UDP 192.168.2.40:5060;branch=".GetBranchValue($message)."
From: <sip:+12012030008@192.168.2.40:5060>;tag=".GetTag($message).";isup-oli;isup-oli=00
To:<sip:+17066458407@192.168.0.246:5060;user=phone>;tag=123
Contact: <sip: +17066458407@192.168.0.246:5060;dtg=16>
Contact: <sip: +17066458407@192.168.0.246:5060;dtg=16>
Contact: <sip: +17066458407@192.168.0.246:5060;dtg=16>
Contact: <sip: +17066458407@192.168.0.246:5060;dtg=16>";
    return $msg;
}

while(1)
{
    echo "Waiting for data ... \n";

    //Receive some data
    $r = socket_recvfrom($sock, $buf, 512, 0, $remote_ip, $remote_port);
    echo "$remote_ip : $remote_port -- " . $buf;
    file_put_contents("Log.txt","\n",FILE_APPEND);
    file_put_contents("Log.txt","Received Response------\n",FILE_APPEND);
    file_put_contents("Log.txt",$buf,FILE_APPEND);
    $respMessage = Create300Response($buf);
    //Send back the data to the client
    socket_sendto($sock, "OK " . $respMessage , 100 , 0 , $remote_ip , $remote_port);
    file_put_contents("Log.txt","\n",FILE_APPEND);
    file_put_contents("Log.txt","\n",FILE_APPEND);
    file_put_contents("Log.txt",$respMessage,FILE_APPEND);
}

socket_close($sock);
4

1 回答 1

5
socket_sendto($sock, "OK " . $respMessage , 100 , 0 , $remote_ip , $remote_port);
//                    ^^ remove this

The OK you are sending is not valid, it is a SIP protocol violation, and as a result the in-built SIP decoder in Wireshark does not recognise the message as a valid SIP packet.

You should just be responding with $respMessage

Also I highly recommend you use a proper parser for incoming messages and a proper object-oriented writer for constructing outgoing messages. SIP is a (some might say needlessly) complex protocol, you will need more than the small nuggets of information you are extracting to build an endpoint that can do anything even remotely useful.

This small library of mine might make a good base for your parser, and indeed this one almost does exactly what you want if you replace HTTP with SIP.

于 2013-03-19T13:43:29.683 回答