Commit b16f41c1 authored by Dafydd Harries's avatar Dafydd Harries

implement ice_agent_recv ()

darcs-hash:20070122150905-c9803-feee5994406b308152c0d7c421189bd0a65d15f3.gz
parent 25e3a828
......@@ -9,7 +9,7 @@ libagent_la_SOURCES = agent.h agent.c
libagent_la_LIBADD = $(top_builddir)/udp/libudp.la
check_PROGRAMS = test test-readline test-util test-add-stream
check_PROGRAMS = test test-readline test-util test-add-stream test-recv
test_LDADD = libagent.la $(GLIB_LIBS)
......@@ -23,5 +23,7 @@ test_util_LDADD = libagent.la $(GLIB_LIBS)
test_add_stream_LDADD = libagent.la $(GLIB_LIBS)
TESTS = test test-readline test-util test-add-stream
test_recv_LDADD = libagent.la $(GLIB_LIBS)
TESTS = test test-readline test-util test-add-stream test-recv
......@@ -443,6 +443,113 @@ ice_agent_add_remote_candidate (
}
static Candidate *
_local_candidate_lookup (Agent *agent, guint candidate_id)
{
GSList *i;
for (i = agent->local_candidates; i; i = i->next)
{
Candidate *c = (Candidate *) i->data;
if (c->id == candidate_id)
return c;
}
return NULL;
}
static Stream *
_stream_lookup (Agent *agent, guint stream_id)
{
GSList *i;
for (i = agent->streams; i; i = i->next)
{
Stream *s = (Stream *) i->data;
if (s->id == stream_id)
return s;
}
return NULL;
}
/**
* ice_agent_recv (agent, candidate)
*
* Tell the agent to try receiving a packet on @candidate's socket. This is
* useful for integrating the agent into a select()-loop. This function will
* block if the socket is blocking.
*/
void
ice_agent_recv (
Agent *agent,
guint candidate_id)
{
Candidate *candidate;
guint len;
gchar buf[1024];
struct sockaddr_in from;
/* XXX: this is a probably a good place to start optimizing, as it gets
* called once for each packet recieved
*/
candidate = _local_candidate_lookup (agent, candidate_id);
if (candidate == NULL)
return;
len = udp_socket_recv (&(candidate->sock), &from,
sizeof (buf) / sizeof (gchar), buf);
g_assert (len > 0);
/* XXX: verify sender; maybe:
*
* if (candidate->other != NULL)
* {
* if (from != candidate->other.addr)
* // ignore packet from unexpected sender
* return;
* }
* else
* {
* // go through remote candidates, looking for one matching packet from
* // address; if found, assign it to candidate->other and call handler,
* // otherwise ignore it
* }
*
* Perhaps remote socket affinity is superfluous and all we need is the
* second part.
* Perhaps we should also check whether this candidate is supposed to be
* active.
*/
if ((buf[0] & 0xc0) == 0x80)
{
/* looks like RTP */
Stream *stream;
stream = _stream_lookup (agent, candidate->stream_id);
if (stream == NULL)
/* odd: a candidate that doesn't belong to a stream */
return;
/* XXX: should a NULL data handler be permitted? */
g_assert (stream->handle_recv != NULL);
stream->handle_recv (agent, candidate->stream_id, len, buf);
}
else
{
/* maybe STUN */
}
}
/*
void
ice_agent_set_stun_server (Address *addr, guint16 port)
......
......@@ -159,6 +159,10 @@ ice_agent_add_remote_candidate (
CandidateType type,
Address *addr,
guint port);
void
ice_agent_recv (
Agent *agent,
guint candidate_id);
#endif /* _AGENT_H */
#include <string.h>
#include <arpa/inet.h>
#include <glib.h>
#include <udp.h>
#include <udp-fake.h>
#include <agent.h>
static gboolean cb_called = FALSE;
void
handle_recv (Agent *agent, guint stream_id, guint len, gchar *buf)
{
g_assert (cb_called == FALSE);
g_assert (stream_id == 1);
g_assert (len == 7);
g_assert (0 == strncmp (buf, "\x80lalala", 7));
cb_called = TRUE;
}
int
main (void)
{
Agent *agent;
Address *addr;
Candidate *candidate;
UDPSocketManager mgr;
UDPSocket *sock;
struct sockaddr_in from = {0,};
udp_fake_socket_manager_init (&mgr);
/* set up agent */
agent = ice_agent_new (&mgr);
addr = address_new_ipv4_from_string ("192.168.0.1");
ice_agent_add_local_address (agent, addr);
address_free (addr);
ice_agent_add_stream (agent, MEDIA_TYPE_AUDIO, handle_recv);
g_assert (agent->local_candidates != NULL);
/* recieve an RTP packet */
candidate = (Candidate *) agent->local_candidates->data;
sock = &(candidate->sock);
udp_fake_socket_push_recv (sock, &from, 7, "\x80lalala");
ice_agent_recv (agent, candidate->id);
g_assert (cb_called == TRUE);
/* clean up */
ice_agent_free (agent);
udp_socket_manager_close (&mgr);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment