Hi,
I just 'finished' writing the first part of my SIP client..
this is useful for the audio conference that uses SIP and
RTP (not the one with audio and video which uses msnp2p and
is being developped on a separate branch).

So here's the deal.. I have two phases for the client, first
phase is being able to make a call (send an invite) and it
already works pretty good! second phase is to be able to
receive a call (receive an invite) and that won't be too
difficult...
I consider the first phase complete, and I like the API and
the design a lot! :)
What I would need now is to have you guys test it.. so
here's how you can do a voice call with aMSN :

- first, you need to update to SVN r9697 or later..
- Download the latest version of farsight and compile it..
(with gst-plugins-farsight of course)
- Open the amsn console and type 'source sip.tcl'
Now you have everything you need to make a voice call..
- Enable MSNP15 support and connect so you can have your
authentification token...

The easy part :
- type in the console : 'createSIP' which will create a new
SIP connection object called 'sip'
- then type 'inviteSIP $email' to invite someone from WLM.
You should then see status messages on the console, once it
gets accepted on the other side, you'll see a status OK with
the list of codecs and candidates (ip/port combinations).
For example : "Invite SIP Response : OK -- {{{} 1 {} UDP 1
192.168.1.100 123456} {{} 2 {} UDP 1 192.168.1.100 123457}}
{{PCMA 8 8000} {PCMU 0 8000} {telephone-event 101 8000}}
The first list is the candidate list, you take the first one
("the one for RTP has a '1' as second element, RTCP has '2')
and you have your ip and port..
- Go to farsight's directory and type :
./tests/test-rtp-7 192.168.1.100 123456 1
That's it.. you should start hearing the WLM audio in your
PC..

The complicated part :
In theory, you should create a new SIP connection with :
SIPConnection create %AUTO% -user $your_email -password
[[$::sso GetSecurityTokenByName Voice] cget -ticket] 
The returned object is your SIP connection.. it's not
conneced yet.. you could do a :
$sip Invite $email $codec_list $candidate_list
The codec list is a list containing codecs.. each codec is
itself a list of the form [list $encoding_name $payload_type
$bitrate]
The encoding name and payload types should be following the
RTP RFCs.. to make it easy you can use PCMA which has a
static payload type of 8 and PCMU with payload type 0.

The condidate list is also a list containing candidates
(connection info like ip/port), each candidate is a list of
the form : [list $candidate_id $component_id $password
$transport $qvalue $ip $port]
those are ICE candidates, WLM uses ICE draft 6, so the
candidate id and password are randomly generated and used to
authenticate once the connection is established... you don't
need that.. it can work even without ICE, so you can give an
empty string as candidate id and password and it will skip
ice candidates... the qvalue is just a 'weight'.. the higher
the value (between 0.00 and 1.00) the better it is to
connect on it (ip/port priority). transport is either UDP or
TCP and that's it...

So let's say we want to create an object called 'sip' it
can be done like this :
SIPConnection create sip -user $your_email -password
[[$::sso GetSecurityTokenByName Voice] cget -ticket]
-error_handler myErrorHandler -request_handler
myRequestHandler
The error and request handlers should be procs that handle
errors and new requests.. you can skip the -request_handler
for now (since we don't handle incoming requests for now)
but the error_handler should have a prototype of the form :
proc myErrorHandler { reason } 
anyways, once the object is created, it's not connected yet,
so you can do it with :
sip Connect
but you don't really need to do that.. you mainly need to
Register.. if you try to register and it's not connected, it
will connect automatically.. so just do a :
sip Register
it will then register itself on the SIP server...
If you want to invite someone, you can also skip that and
just send the invite, it will automatically connect and
register before sending out the invite... So with everything
I said so far, here's how you can send an invite :
sip Invite $email [list [list "PCMA" 8 8000] [list "PCMU" 0
8000]] [list [list "" 1 "" UDP 1 $my_ip $my_port]]
Since we don't use ICE, if you're behind a firewall or a
NAT, then you just won't be able to make the connection
work, so I was testing between WLM and aMSN inside my local
network, so the $my_ip was actually my local ip.. which I
was getting with : [::abook::getDemographicField localip]
The $port is special though, since we're using a 'test'
application from farsight, and that test only takes the
destination ip/port, it has a hardcoded value for the port
to listen to and it's 7078... so until we write our own
application that uses farsight, we have to use the port
7078..
One last thing.. if you want to know what is happening (you
must!) then you need to specify one last argument : a
callback function with the protocol :
proc InviteCallback { status detail }
The status tells you what's happening and the detail is an
extra detail per status.. for example "ERROR" status will
have the reason in the detail.. a "OK" will have a list
containing the remote user's candidates and codecs in the
$detail variable...
So you end up doing this :
sip Invite $email [list [list "PCMA" 8 8000] [list "PCMU" 0 
8000]] [list [list "" 1 "" UDP 1
[::abook::getDemographicField localip] 7078 InviteCallback

Once you do that, the invite gets sent, the other user's WLM
starts ringing.. he can accept/decline/not answer/etc... the
Tcl client will tell you exactly what happens
The rest is the same as the 'easy method', you just look at
what you receive in your callback, when you get the OK, you
parse the remote candidates, get the ip/port and use that
with farsight :
./tests/test-rtp-7 $ip $port 1

Now To summarize everything I've just explained.. let's look
at the last few functions in sip.tcl which serve as test and
are what are being used for the 'easy method' :

proc createSIP { {host "vp.sip.messenger.msn.com"} } {
        global sso
        set token [$sso GetSecurityTokenByName Voice]
        catch {sip destroy}
        return [SIPConnection create sip -user
[::config::getKey login] -password [$token cget -ticket]
-error_handler errorSIP -request_handler requestSIP -host
$host]
}

This helper function just creates the 'sip' object for you
just like I said before...

proc inviteSIP { email } {
        sip Invite $email [list [list "PCMA" 8 8000] [list
"PCMU" 0 8000]] [list [list "" 1 "" UDP 1
[::abook::getDemographicField localip] 7078]] inviteSIPCB
}

and this one invites the user without having you type in the
list of codecs/candidates everytime...

proc inviteSIPCB { status detail} {
        puts "Invite SIP Response : $status -- $detail"
}

invite callback which tells you what's happening...

proc requestSIP { request headers body } {
        puts "Received Request : $request"
}

Request handler..
This will tell you if you receive a request from the other
user (assuming you are connected to the same SIP proxy but
it does nothing else...)

proc errorSIP { reason } {
        puts "Error in SIP : $reason"
}

Error handler which will tell you what happened when
something goes wrong...


That's about it.. if you follow these instructions, you
should *in theory* be able to do a voice call with WLM...
problem now is that WLM will not play your sound, and that's
because farsight doesn't send RTCP and without it, WLM
doesn't know if your SSRC (and id in the rtp header) is
yours... with farsight 2 (which we'll use), we'll have RTCP
so WLM will play our sound too... yeay!

If you have any questions.. you will find me tomorrow after
I wake up on IRC... or write to the ML...

Feedback appreciated!!!
Thanks
KaKaRoTo

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Register now and save $200. Hurry, offer ends at 11:59 p.m., 
Monday, April 7! Use priority code J8TLD2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Amsn-devel mailing list
Amsn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/amsn-devel

Reply via email to