|
|
|
@ -59,6 +59,10 @@ |
|
|
|
# include <net/if.h> |
|
|
|
#endif |
|
|
|
|
|
|
|
#ifdef HAVE_SEARCH_H |
|
|
|
# include <search.h> |
|
|
|
#endif |
|
|
|
|
|
|
|
#include "access/rtp/sdp.h" |
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
@ -92,6 +96,8 @@ typedef struct |
|
|
|
struct sap_announce_t **pp_announces; |
|
|
|
|
|
|
|
vlc_tick_t i_timeout; |
|
|
|
|
|
|
|
void *root_cat; |
|
|
|
} services_discovery_sys_t; |
|
|
|
|
|
|
|
static int Decompress( const unsigned char *psz_src, unsigned char **_dst, int i_len ) |
|
|
|
@ -142,6 +148,66 @@ static int Decompress( const unsigned char *psz_src, unsigned char **_dst, int i |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
struct category |
|
|
|
{ |
|
|
|
input_item_t *item; |
|
|
|
services_discovery_t *sd; |
|
|
|
char name[]; |
|
|
|
}; |
|
|
|
|
|
|
|
static void DestroyCategory(void *data) |
|
|
|
{ |
|
|
|
struct category *c = data; |
|
|
|
|
|
|
|
services_discovery_RemoveItem(c->sd, c->item); |
|
|
|
input_item_Release(c->item); |
|
|
|
free(c); |
|
|
|
} |
|
|
|
|
|
|
|
static int cmpcat (const void *a, const void *b) |
|
|
|
{ |
|
|
|
const struct category *ca = a, *cb = b; |
|
|
|
return strcmp(ca->name, cb->name); |
|
|
|
} |
|
|
|
|
|
|
|
static input_item_t *AddCategory (services_discovery_t *sd, const char *name) |
|
|
|
{ |
|
|
|
services_discovery_sys_t *sys = sd->p_sys; |
|
|
|
|
|
|
|
struct category *c = malloc(sizeof(*c) + strlen(name) + 1); |
|
|
|
if (unlikely(c == NULL)) |
|
|
|
return NULL; |
|
|
|
strcpy(c->name, name); |
|
|
|
|
|
|
|
void **cp = tsearch(c, &sys->root_cat, cmpcat); |
|
|
|
if (cp == NULL) /* Out-of-memory */ |
|
|
|
{ |
|
|
|
free(c); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
if (*cp != c) |
|
|
|
{ |
|
|
|
free(c); |
|
|
|
c = *cp; |
|
|
|
assert(c->item != NULL); |
|
|
|
return c->item; |
|
|
|
} |
|
|
|
|
|
|
|
c->item = input_item_NewExt("vlc://nop", c->name, |
|
|
|
INPUT_DURATION_INDEFINITE, |
|
|
|
ITEM_TYPE_NODE, ITEM_LOCAL); |
|
|
|
|
|
|
|
if (unlikely(c->item == NULL)) |
|
|
|
{ |
|
|
|
tdelete(c, &sys->root_cat, cmpcat); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
services_discovery_AddItem(sd, c->item); |
|
|
|
c->sd = sd; |
|
|
|
|
|
|
|
return c->item; |
|
|
|
} |
|
|
|
|
|
|
|
typedef struct sap_announce_t |
|
|
|
{ |
|
|
|
vlc_tick_t i_last; |
|
|
|
@ -218,8 +284,9 @@ static sap_announce_t *CreateAnnounce(services_discovery_t *p_sd, |
|
|
|
/* backward compatibility with VLC 0.7.3-2.0.0 senders */ |
|
|
|
psz_value = vlc_sdp_attr_value(p_sdp, "x-plgroup"); |
|
|
|
} |
|
|
|
services_discovery_AddItemCat(p_sd, p_input, psz_value); |
|
|
|
input_item_t *cat = AddCategory(p_sd, psz_value); |
|
|
|
free(str); |
|
|
|
services_discovery_AddSubItem(p_sd, cat, p_input); |
|
|
|
|
|
|
|
vlc_sdp_free(p_sdp); |
|
|
|
return p_sap; |
|
|
|
@ -583,6 +650,7 @@ static int Open( vlc_object_t *p_this ) |
|
|
|
|
|
|
|
p_sys->i_announces = 0; |
|
|
|
p_sys->pp_announces = NULL; |
|
|
|
p_sys->root_cat = NULL; |
|
|
|
/* TODO: create sockets here, and fix racy sockets table */ |
|
|
|
if (vlc_clone (&p_sys->thread, Run, p_sd)) |
|
|
|
{ |
|
|
|
@ -616,6 +684,7 @@ static void Close( vlc_object_t *p_this ) |
|
|
|
RemoveAnnounce( p_sd, p_sys->pp_announces[i] ); |
|
|
|
} |
|
|
|
FREENULL( p_sys->pp_announces ); |
|
|
|
tdestroy(p_sys->root_cat, DestroyCategory); |
|
|
|
|
|
|
|
free( p_sys ); |
|
|
|
} |
|
|
|
|