[Nice] Starting with libnice

Tiago Sá tiagosa at di.uminho.pt
Fri Dec 16 03:42:31 PST 2011


Hi Youness,

Sure! I will share the application when I succeed.
Before trying to pipe from a local socket I am simply testing reading from
a file and sending that data to the other agent.
I am using nice_agent_new_reliable and pseudo_tcp is opened:
"(process:11881): libnice-DEBUG: Agent 0xb97de0: s1:1 pseudo Tcp socket
Opened"
Can I assume that Nice will manage the acknowledgments, sequencing and all
that TCP stuff?

This is the function I use to slice and send the file:

int send_file(char *filename){
        FILE *file = fopen(filename, "rb");
        char *file_chunk = malloc(CHUNK_SIZE);

        size_t nbytes = 0;
        int sent=0;
        while ( (nbytes = fread(file_chunk, sizeof(char), CHUNK_SIZE,file))
> 0)
        {
                int offset = 0;
                while (((sent =
nice_agent_send(agent,stream_id,NICE_COMPONENT_TYPE_RTP,nbytes,fi
le_chunk+offset)) > 0) || (sent == -1 && errno == EINTR) ) {
                        if (sent > 0) {
                                printf("SENT FILE: chunk size: %zu send
result: %d \n",nbytes,sent);
                                offset += sent;
                                nbytes -= sent;
                        }
                }
        }
        return 0;
}

And the callback to receive:

void
cb_nice_recv (NiceAgent * agent, guint stream_id, guint component_id,
              guint len, gchar * buf, gpointer user_data)
{
  FILE *file_received=fopen("testFile-received.txt", "ab");

  if(file_received){
      int writen = fwrite(buf,sizeof(char),len,file_received);
     printf("RECEIVED FILE: buf size: %d , writen size: %d\n\n",len,writen);
  }
  else{ perror("ERROR OPENING FILE\n"); }
}

It sends some chunks and then starts to fail on send.

Problably I should use the "reliable-transport-writable" signal, to wait
before trying to send a new chunk, but then, the signal must be handled by
a different callback, am I write? Or can I "wait" for the signal on the
same send_file function?

Thank you for the helpful information you are sharing.

Cheers,
Tiago Sá


On Mon, Dec 12, 2011 at 11:39 PM, Youness Alaoui <
youness.alaoui at collabora.co.uk> wrote:

> On 12/12/2011 06:20 AM, Tiago Sá wrote:
> > Hi again Youness,
> Hi again Tiago,
>
> >
> > my application is progressing in small steps.
> > We chose to use XMPP for the communication. We are using libstrophe, it
> lacks
> > some documentation, but was enough for our needs.
> > We implemented a naif handshake, life the one you mentioned above, by
> exchanging
> > some xmpp message stanzas.
>
> Cool, you may want to look at the jingle XEP to see how candidates are
> being
> transferred in a VoIP call.
>
> >
> > This application will be part of a research project involving the grid,
> where we
> > need private hosts (called agents) to be able to communicate someway. We
> will
> > implement that (inter-agent) communication protocol later, right now we
> are
> > concerned with the NAT traversal thing, and it seems to be working fine
> :)
> >
> > Now, I would like to ask you a final question:
> > Right now we are able to send strings using "nice_agent_send". We would
> like to
> > establish a socket between the hosts and use other common primitives to
> code our
> > application.
> > Maybe the best possibility would be to create some kind of pipe from an
> > "external" application using local ports (something
> > like http://code.google.com/p/gnat/)
> > Or, in a simpler way, just pipe stdin/stdout from another app, slice
> that data
> > and send it using libnice send primitive?
> >
> > Have you ever tried something like this?
> I have not tried something like that, but it shouldn't be too hard in my
> opinion. You could just create a local daemon that connects to the XMPP
> server,
> and when it gets a new local connection, it sends candidates and acts as a
> proxy
> between the 127.0.0.1:12345 socket and the remote socket with the
> nice_agent_send and the recv callback.
> Would be nice if that code gets shared if you ever get to do it. But I
> don't see
> anything that would prevent it from working.
> Good luck!
> >
> > Thank you very much for your help.
> >
> > Cheers,
> > Tiago
> >
> >
> >
> >
> > On Mon, Nov 28, 2011 at 12:46 PM, Youness Alaoui <
> youness.alaoui at collabora.co.uk
> > <mailto:youness.alaoui at collabora.co.uk>> wrote:
> >
> >     On 11/23/2011 01:14 PM, Tiago Sá wrote:
> >     > Hi Youness,
> >     >
> >     > thank you for your suggestions.
> >     > You'r right, the STUN/TURN server I was using had a connection
> limit. I
> >     > installed the turnserver.org <http://turnserver.org>
> >     <http://turnserver.org> one in a public addressed
> >     > machine.
> >     > I also changed the way how I was writing the candidates, setting
> those
> >     pointers
> >     > to NULL.
> >     > ICE seems to be working properly now! :)
> >     Glad it worked :)
> >
> >     >
> >     > I have a question:
> >     > According to the example in
> http://nice.freedesktop.org/libnice/NiceAgent.html
> >     > we should be able to start sending messages after the signal
> new-selected-pair
> >     > is fired. However, I tried it but no success:
> >     > void
> >     > cb_new_selected_pair (void)
> >     > {
> >     >   printf ("cb_new_selected_pair\n");
> >     >   nice_agent_send(agent, stream_id, NICE_COMPONENT_TYPE_RTP,
> >     strlen("Ola"),"Ola");
> >     > }
> >     >
> >     > That first message is never received. However, after "a while" I
> try to send
> >     > again and it works. Do I have to wait for the other agent to be
> ready to
> >     receive?
> >     Humm.. that might not have been entirely true.. technically if there
> is a
> >     selected pair, then it should work, unless you are ready locally,
> but the remote
> >     isn't ready to receive yet. technically you should wait for the
> state to go to
> >     READY... and not care about the selected pair.. the docs might be
> wrong there,
> >     but it's been a while and I'm not entirely sure of the use case that
> would make
> >     it fail (but in every other project, we use the READY state as an
> indication
> >     that we're ready to send).
> >
> >     >
> >     > Well, this is a checkpoint for me, but I must ask for another
> suggestion now.
> >     > I need to improve the way how the communication between agents is
> made
> >     > (exchanging candidates/credentials, initiating p2p connections,
> etc...)
> >     > As I read in this
> >     > thread
> http://lists.freedesktop.org/archives/nice/2010-August/000330.html
> >     , you
> >     > wrote:
> >     > "well, the serialization, if I understand what you mean, is how
> you send the
> >     > candidates to the other side, right ? In that case, that's not
> part of the ICE
> >     > methodology.. you can 'serialize' the candidates/user/pass any way
> you want..
> >     > one method is to put it in the SDP of a SIP invite. You can also
> send it as an
> >     > XML using Jingle's XEP over an XMPP connection.. it really all
> depends on what
> >     > protocol is being used to connect to the server (SIP, XMPP,
> custom, other...).
> >     > I'll let you decide on the best way to do that."
> >     Thanks for searching in the archives :)
> >
> >     >
> >     > After doing some research, I feel a bit scared. That is a
> completely new world
> >     > for me. Could you please point the "simplest and most feasible"
> solution for
> >     > this problem? Should I choose SIP or XMPP?
> >     > libjingle, for example, presents a huge API...
> >     > Do you know any simple client, possibly allowing me to connect to
> an existing
> >     > infrastructure (such as Google Talk), I could use for this trivial
> information
> >     > exchange?
> >
> >     Humm.. yes, libjingle is a big pile of **** :) my suggestion is to
> never use it!
> >     The real question here is what do you need libnice for? what will
> the clients be
> >     ? if it's for a game or some custom application and that you can
> control the
> >     server and the client, then you can setup something custom. If you
> want to have
> >     a list of contacts in your application and the user can just select
> one and it
> >     will know what to do, then using XMPP might be the best solution. It
> really all
> >     depends on your needs and capabilities.. you can decide all about
> it, but here's
> >     a simple example if you want :
> >     client sending to server is : --->
> >     client receiving from server is : <-----
> >     Comments are preceded with #
> >     ----> HELLO
> >     <---- HELLO 12345 # Where 12345 would be a random id that gets
> assigned to you
> >     ----> 54321 BEGIN ICE # first number being the 'random id' of the
> destination
> >     ----> 54321 ICE-CREDENTIALS <the_username> <the_password>
> >     ----> 54321 CANDIDATE 1 UDP 192.168.1.100 43132 host
> >     ----> 54321 CANDIDATE 2 UDP 1.2.3.4 52133 srv-reflx
> >     ----> 54321 ICE DONE # To say you're done, you can send it to the
> peer
> >     <---- 54321 ICE REPLY
> >     <---- 54321 ICE-CREDENTIALS foo bar # the remote's credentials
> >     <---- 54321 CANDIDATE 1 UDP  192.168.1.200 54521 host
> >     <---- 54321 CANDIDATE 2 UDP 1.2.4.1 9614 srv-reflx
> >     <---- 54321 CANDIDATE 3 UDP 4.3.2.1 32957 <tel:4.3.2.1%2032957>
> relay-reflx
> >     <---- 54321 ICE DONE
> >     [...]
> >     ----> 54321 ICE DESTROY
> >
> >     And your server just maps sockets with those random ids, and relays
> the data
> >     from one socket to another. And you parse the received input and
> build your
> >     candidates...
> >     So this is a very simple, but of course inefficient, you get a
> random id
> >     everytime, it's hard to improve the protocol, etc... so using XMPP
> would be
> >     better, but if you really don't need that much, then this might be
> the solution
> >     you want.. like I said, it really depends on what you need it for.
> >     As for XMPP, you can look at the 'wocky' library
> >     (http://cgit.freedesktop.org/wocky/)
> >
> >
> >     >
> >     > Thank you for your help.
> >     You're welcome :)
> >
> >     >
> >     > Regards,
> >     > Tiago Sá
> >     >
> >     >
> >     >
> >     > On Thu, Nov 17, 2011 at 9:42 PM, Youness Alaoui
> >     <youness.alaoui at collabora.co.uk <mailto:
> youness.alaoui at collabora.co.uk>
> >     > <mailto:youness.alaoui at collabora.co.uk
> >     <mailto:youness.alaoui at collabora.co.uk>>> wrote:
> >     >
> >     >     On 11/16/2011 08:30 PM, Tiago Sá wrote:
> >     >     > Hi again Youness,
> >     >     > thanks a lot for your help.
> >     >     > I believe I solved the problems you pointed before.
> >     >     > I am using a dumb method to exchange candidates. I write
> them to
> >     file and
> >     >     > exchange them using a ftp server (I will improve it later).
> >     >     >
> >     >     > So, the way I run it is:
> >     >     > (HostA) ./client l
> >     >     > (HostB) ./client r
> >     >     > //local candidates are gathered and written to file
> >     >     > (HostA) put leftCands.bin on FTP and get rightCands.bin
> >     >     > (HostB) put rightCands.bin on FTP and get leftCands.bin
> >     >     > //read local credentials and write them on the remote host
> >     >     >
> >     >     > I am using a relay server, that should work as a last
> resort. But
> >     during the
> >     >     > local candidate gathering, sometimes it gets a relayed
> candidate,
> >     but most of
> >     >     > the times it doesn't. Can it be related with timeouts?
> >     >     It's possible the timeouts are affecting it, but I doubt it,
> usually
> >     the RTT
> >     >     would be 200ms, but if you don't get a response from the relay
> or the stun
> >     >     server, it will retry 4 times until it times out after about 3
> seconds.
> >     >     It's possible though that the server has a limit on the number
> of
> >     allocations
> >     >     you can create (probably 5) and if you are testing your app
> and it
> >     creates 2
> >     >     allocations each time (one for each side), then it's possible
> the
> >     server starts
> >     >     rejecting your allocation requests (each time you want to use
> TURN, it
> >     will ask
> >     >     the server to allocate a port for you for that specific
> connection, so
> >     you have
> >     >     the same settings but one port for each stream/component).
> >     >     If that's the case, maybe that's why it sometimes works (when
> the
> >     allocation
> >     >     times out from the server). libnice should technically
> deallocate when the
> >     >     stream is destroyed, so maybe catch your Ctrl-C and do an
> unref on the
> >     agent
> >     >     before returning from the main.
> >     >
> >     >     >
> >     >     > Either way, it can never get a pair a establish a
> connection. :(
> >     >     > I don't have a clue why this happens..
> >     >
> >     >     A log + wireshark dump might be helpful in this case. You can
> enable
> >     logging
> >     >     with :
> >     >     export NICE_DEBUG=all
> >     >
> >     >
> >     >     >
> >     >     > Can you please have a look?
> >     >     The code looks sane enough.. apart from the obvious method of
> exchanging
> >     >     candidates which isn't "optimal". One thing I noticed though,
> you just
> >     fwrite
> >     >     the whole structure, but note that there are pointers in the
> structure
> >     that will
> >     >     be written as is to the file, and not their content. I'm
> thinking of
> >     >     username+password (but those should be NULL if you use the
> RFC5245
> >     compatibility
> >     >     mode) but mostly the turn structure (which is just for local
> >     candidates and
> >     >     wouldn't be used anyways for remote ones, but it's best to set
> it to
> >     NULL to
> >     >     avoid possible crashes).
> >     >
> >     >     >
> >     >     > Cheers,
> >     >     > Tiago
> >     >     >
> >     >     >
> >     >     > On Fri, Nov 4, 2011 at 2:03 PM, Youness Alaoui
> >     >     <youness.alaoui at collabora.co.uk
> >     <mailto:youness.alaoui at collabora.co.uk>
> >     <mailto:youness.alaoui at collabora.co.uk <mailto:
> youness.alaoui at collabora.co.uk>>
> >     >     > <mailto:youness.alaoui at collabora.co.uk
> >     <mailto:youness.alaoui at collabora.co.uk>
> >     >     <mailto:youness.alaoui at collabora.co.uk
> >     <mailto:youness.alaoui at collabora.co.uk>>>> wrote:
> >     >     >
> >     >     >     Hi again Tiago,
> >     >     >
> >     >     >     For the remote candidates, you will need a third party
> server to
> >     >     exchange that
> >     >     >     information, usually the candidates would be sent over
> SIP or
> >     XMPP for
> >     >     example.
> >     >     >     ICE cannot work if you don't have a third party server
> with
> >     which you can
> >     >     >     reliably exchange candidates. For testing purposes you
> could have it
> >     >     print the
> >     >     >     candidates to stdout, and you could copy/paste that into
> stdin
> >     of the
> >     >     other
> >     >     >     instance and have it parse the input.. or you could
> hardcode a
> >     port to
> >     >     connect
> >     >     >     to and do the candidate exchange.. there's no easy way
> of doing that
> >     >     though.
> >     >     >     You cannot hardcode the candidates because the port used
> will be
> >     random
> >     >     >     everytime, also, you will need to exchange the randomly
> generated
> >     >     >     username/password (nice_agent_get_local_credentials +
> >     >     >     nice_agent_set_remote_credentials) to make the
> connectivity
> >     checks work.
> >     >     >
> >     >     >     As for your example, here are a few comments :
> >     >     >     1 - you call the nice_agent_set_relay_info with
> stream_id being
> >     >     uninitialized,
> >     >     >     you must call it *after* you do the
> nice_agent_add_stream...
> >     >     >     2 - you don't need those GValues, you can just do
> >     >     >      g_object_set (G_OBJECT(agent),
> >     >     >                    "stun-server", "66.228.45.110",
> >     >     >                    "stun-server-port", 3478,
> >     >     >                     NULL);
> >     >     >     3 - You shouldn't set the remote credentials as the same
> as the
> >     local ones
> >     >     >     4 - In your print_candidate_info, you may also want to
> print the
> >     port
> >     >     used.
> >     >     >
> >     >     >     I hope this helps, let me know if you have further
> questions.
> >     >     >
> >     >     >     Youness.
> >     >     >
> >     >     >
> >     >     >     On 11/03/2011 12:57 PM, Tiago Sá wrote:
> >     >     >     > Hi Youness,
> >     >     >     >
> >     >     >     > I have been trying to create a simple application
> based on the
> >     first
> >     >     link you
> >     >     >     > pointed before.
> >     >     >     > Thanks for the tips you gave me. I have a couple of
> questions
> >     though, if
> >     >     >     you can
> >     >     >     > help me.
> >     >     >     >
> >     >     >     > I need to find a way to get the remote candidates
> passed from
> >     a peer to
> >     >     >     another.
> >     >     >     > Can you point an easy way to do that?
> >     >     >     > Could I hardcode the remote candidates list, for
> testing purposes?
> >     >     >     >
> >     >     >     > Right now, I only get two local candidates (HOST and
> >     SERVER_REFLEXIVE).
> >     >     >     > I am trying to use the numb TURN server, shouldn't I
> get a RELAYED
> >     >     >     candidate too?
> >     >     >     >
> >     >     >     > I am attaching the code. Can you please have a look at
> the
> >     code and
> >     >     check
> >     >     >     where
> >     >     >     > the error could be?
> >     >     >     >
> >     >     >     > Thanks for helping!
> >     >     >     >
> >     >     >     > Regards,
> >     >     >     > Tiago Sá
> >     >     >     >
> >     >     >     >
> >     >     >     > On Wed, Oct 19, 2011 at 10:53 PM, Youness Alaoui
> >     >     >     <youness.alaoui at collabora.co.uk
> >     <mailto:youness.alaoui at collabora.co.uk>
> >     >     <mailto:youness.alaoui at collabora.co.uk
> >     <mailto:youness.alaoui at collabora.co.uk>>
> >     >     <mailto:youness.alaoui at collabora.co.uk
> >     <mailto:youness.alaoui at collabora.co.uk>
> >     <mailto:youness.alaoui at collabora.co.uk <mailto:
> youness.alaoui at collabora.co.uk>>>
> >     >     >     > <mailto:youness.alaoui at collabora.co.uk
> >     <mailto:youness.alaoui at collabora.co.uk>
> >     >     <mailto:youness.alaoui at collabora.co.uk
> >     <mailto:youness.alaoui at collabora.co.uk>>
> >     >     >     <mailto:youness.alaoui at collabora.co.uk
> >     <mailto:youness.alaoui at collabora.co.uk>
> >     >     <mailto:youness.alaoui at collabora.co.uk
> >     <mailto:youness.alaoui at collabora.co.uk>>>>> wrote:
> >     >     >     >
> >     >     >     >     Hi,
> >     >     >     >
> >     >     >     >     Welcome to the world of libnice :)
> >     >     >     >     Yes, doing NAT traversal is far from being easy,
> the only
> >     >     solution is
> >     >     >     pretty
> >     >     >     >     much to use the ICE specification and that's not
> easy to
> >     >     implement, so
> >     >     >     that's
> >     >     >     >     why you'd need to use libnice.
> >     >     >     >
> >     >     >     >     For an example, you can have a look at the unit
> tests, like
> >     >     >     >     tests/test-fullmode.c for example, although that
> does a lot of
> >     >     stuff.
> >     >     >     You can
> >     >     >     >     see a quick example  in the documentation for
> NiceAgent :
> >     >     >     >     http://nice.freedesktop.org/libnice/NiceAgent.html
> >     >     >     >
> >     >     >     >     For smaller examples, you can look at the libnice
> mailing list
> >     >     >     archives, some
> >     >     >     >     people posted their example code where they were
> having
> >     >     problems. For
> >     >     >     example, a
> >     >     >     >     very simple example can be seen here :
> >     >     >     >
> >     http://lists.freedesktop.org/archives/nice/2011-January/000404.html
> >     >     >     >     But make sure to click on the "Next message" to
> read the whole
> >     >     thread
> >     >     >     because
> >     >     >     >     that example had a bug that I explained how to fix
> in the
> >     following
> >     >     >     emails.
> >     >     >     >     Same for this thread :
> >     >     >     >
> >     http://lists.freedesktop.org/archives/nice/2011-October/000434.html
> >     >     >     >
> >     >     >     >     I hope that helps,
> >     >     >     >     Youness.
> >     >     >     >
> >     >     >     >     On 10/19/2011 09:58 AM, Tiago Sá wrote:
> >     >     >     >     > Hi all,
> >     >     >     >     >
> >     >     >     >     > my name is Tiago Sá, I am a junior researcher
> from Portugal
> >     >     and this
> >     >     >     is my
> >     >     >     >     first
> >     >     >     >     > mail to this list.
> >     >     >     >     > I have a NAT traversal problem to solve and I
> have been
> >     >     looking for
> >     >     >     a solution
> >     >     >     >     > during the last weeks, which, as I found out, is
> not so
> >     >     trivial as I
> >     >     >     >     thought before.
> >     >     >     >     > As stated on the libnice homepage, libnice seems
> to be
> >     what I am
> >     >     >     looking for:
> >     >     >     >     >
> >     >     >     >     >     "ICE is useful for applications that want to
> establish
> >     >     peer-to-peer
> >     >     >     >     UDP data
> >     >     >     >     >     streams. It automates the process of
> traversing NATs and
> >     >     >     provides security
> >     >     >     >     >     against some attacks. It also allows
> applications to
> >     >     create reliable
> >     >     >     >     streams
> >     >     >     >     >     using a TCP over UDP layer."
> >     >     >     >     >
> >     >     >     >     >
> >     >     >     >     > I have been looking for the provided
> documentation and I am
> >     >     feeling kind
> >     >     >     >     of lost.
> >     >     >     >     > Is there any example application or tutorial to
> get started?
> >     >     >     >     > Could you please share a basic application of
> this kind or
> >     >     point me a
> >     >     >     >     direction?
> >     >     >     >     >
> >     >     >     >     >
> >     >     >     >     > Thanks in advance for your help.
> >     >     >     >     >
> >     >     >     >     > Regards,
> >     >     >     >     > Tiago Sá
> >     >     >     >     >
> >     >     >     >     > --
> >     >     >     >     > Tiago Sá
> >     >     >     >     > Universidade do Minho, Braga - Portugal
> >     >     >     >     >
> >     >     >     >     >  http://about.me/tiagosa/
> >     >     >     >     >
> >     >     >     >     >
> >     >     >     >     >
> >     >     >     >     > _______________________________________________
> >     >     >     >     > Nice mailing list
> >     >     >     >     > Nice at lists.freedesktop.org
> >     <mailto:Nice at lists.freedesktop.org> <mailto:
> Nice at lists.freedesktop.org
> >     <mailto:Nice at lists.freedesktop.org>>
> >     >     <mailto:Nice at lists.freedesktop.org <mailto:
> Nice at lists.freedesktop.org>
> >     <mailto:Nice at lists.freedesktop.org <mailto:
> Nice at lists.freedesktop.org>>>
> >     >     >     <mailto:Nice at lists.freedesktop.org
> >     <mailto:Nice at lists.freedesktop.org> <mailto:
> Nice at lists.freedesktop.org
> >     <mailto:Nice at lists.freedesktop.org>>
> >     >     <mailto:Nice at lists.freedesktop.org <mailto:
> Nice at lists.freedesktop.org>
> >     <mailto:Nice at lists.freedesktop.org <mailto:
> Nice at lists.freedesktop.org>>>>
> >     >     >     >     >
> http://lists.freedesktop.org/mailman/listinfo/nice
> >     >     >     >
> >     >     >     >
> >     >     >     >
> >     >     >     >     _______________________________________________
> >     >     >     >     Nice mailing list
> >     >     >     >     Nice at lists.freedesktop.org
> >     <mailto:Nice at lists.freedesktop.org> <mailto:
> Nice at lists.freedesktop.org
> >     <mailto:Nice at lists.freedesktop.org>>
> >     >     <mailto:Nice at lists.freedesktop.org <mailto:
> Nice at lists.freedesktop.org>
> >     <mailto:Nice at lists.freedesktop.org <mailto:
> Nice at lists.freedesktop.org>>>
> >     >     >     <mailto:Nice at lists.freedesktop.org
> >     <mailto:Nice at lists.freedesktop.org> <mailto:
> Nice at lists.freedesktop.org
> >     <mailto:Nice at lists.freedesktop.org>>
> >     >     <mailto:Nice at lists.freedesktop.org <mailto:
> Nice at lists.freedesktop.org>
> >     <mailto:Nice at lists.freedesktop.org <mailto:
> Nice at lists.freedesktop.org>>>>
> >     >     >     >     http://lists.freedesktop.org/mailman/listinfo/nice
> >     >     >     >
> >     >     >     >
> >     >     >     >
> >     >     >     >
> >     >     >     > --
> >     >     >     > Tiago Sá
> >     >     >     > Universidade do Minho, Braga - Portugal
> >     >     >     >  www.tiagosa.com <http://www.tiagosa.com>
> >     <http://www.tiagosa.com> <http://www.tiagosa.com>
> >     >     <http://www.tiagosa.com>
> >     >     >     >
> >     >     >
> >     >     >
> >     >     >
> >     >     >
> >     >     >
> >     >     > --
> >     >     > Tiago Sá
> >     >     > Universidade do Minho, Braga - Portugal
> >     >     >  www.tiagosa.com <http://www.tiagosa.com> <
> http://www.tiagosa.com>
> >     <http://www.tiagosa.com>
> >     >     >
> >     >
> >     >
> >     >
> >     >
> >     >
> >     > --
> >     > Tiago Sá
> >     > Universidade do Minho, Braga - Portugal
> >     >  www.tiagosa.com <http://www.tiagosa.com> <http://www.tiagosa.com>
> >     >
> >
> >
> >
> >
> >
> > --
> > Tiago Sá
> > Universidade do Minho, Braga - Portugal
> >  www.tiagosa.com <http://www.tiagosa.com>
> >
>
>
>


-- 
Tiago Sá
Universidade do Minho, Braga - Portugal
 www.tiagosa.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/nice/attachments/20111216/996cb8d1/attachment-0001.htm>


More information about the nice mailing list