gssdp_client_get_host_ip (client),
&error);
if (client->priv->request_socket != NULL) {
- g_source_set_callback
- (client->priv->request_socket->source,
- (GSourceFunc) request_socket_source_cb,
- client,
- NULL);
+ gssdp_socket_source_set_callback
+ (client->priv->request_socket,
+ (GSourceFunc) request_socket_source_cb,
+ client);
} else {
goto errors;
}
gssdp_client_get_host_ip (client),
&error);
if (client->priv->multicast_socket != NULL) {
- g_source_set_callback
- (client->priv->multicast_socket->source,
+ gssdp_socket_source_set_callback
+ (client->priv->multicast_socket,
(GSourceFunc) multicast_socket_source_cb,
- client,
- NULL);
+ client);
}
errors:
return;
}
- g_source_attach (client->priv->request_socket->source,
- client->priv->main_context);
- g_source_unref (client->priv->request_socket->source);
+ gssdp_socket_source_attach (client->priv->request_socket,
+ client->priv->main_context);
- g_source_attach (client->priv->multicast_socket->source,
- client->priv->main_context);
- g_source_unref (client->priv->multicast_socket->source);
+ gssdp_socket_source_attach (client->priv->multicast_socket,
+ client->priv->main_context);
}
static void
/* Destroy the SocketSources */
if (client->priv->request_socket) {
- gssdp_socket_source_destroy (client->priv->request_socket);
+ g_object_unref (client->priv->request_socket);
client->priv->request_socket = NULL;
}
if (client->priv->multicast_socket) {
- gssdp_socket_source_destroy (client->priv->multicast_socket);
+ g_object_unref (client->priv->multicast_socket);
client->priv->multicast_socket = NULL;
}
#include "gssdp-protocol.h"
#include "gssdp-error.h"
+static void
+gssdp_socket_source_initable_init (gpointer g_iface,
+ gpointer iface_data);
+
+G_DEFINE_TYPE_EXTENDED (GSSDPSocketSource,
+ gssdp_socket_source,
+ G_TYPE_OBJECT,
+ 0,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+ gssdp_socket_source_initable_init));
+
+struct _GSSDPSocketSourcePrivate {
+ GSource *source;
+ GSocket *socket;
+ GSSDPSocketSourceType type;
+ char *host_ip;
+};
+
+enum {
+ PROP_0,
+ PROP_TYPE,
+ PROP_HOST_IP
+};
+
+static void
+gssdp_socket_source_init (GSSDPSocketSource *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ GSSDP_TYPE_SOCKET_SOURCE,
+ GSSDPSocketSourcePrivate);
+}
+
+static gboolean
+gssdp_socket_source_do_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error);
+
+static void
+gssdp_socket_source_initable_init (gpointer g_iface,
+ gpointer iface_data)
+{
+ GInitableIface *iface = (GInitableIface *)g_iface;
+ iface->init = gssdp_socket_source_do_init;
+}
+
+static void
+gssdp_socket_source_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GSSDPSocketSource *self;
+
+ self = GSSDP_SOCKET_SOURCE (object);
+
+ /* All properties are construct-only, write-only */
+ switch (property_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gssdp_socket_source_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GSSDPSocketSource *self;
+
+ self = GSSDP_SOCKET_SOURCE (object);
+
+ switch (property_id) {
+ case PROP_TYPE:
+ self->priv->type = g_value_get_int (value);
+ break;
+ case PROP_HOST_IP:
+ self->priv->host_ip = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
/**
* gssdp_socket_source_new
*
const char *host_ip,
GError **error)
{
- GSSDPSocketSource *socket_source = NULL;
+ return g_initable_new (GSSDP_TYPE_SOCKET_SOURCE,
+ NULL,
+ error,
+ "type",
+ type,
+ "host-ip",
+ host_ip,
+ NULL);
+}
+
+static gboolean
+gssdp_socket_source_do_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GSSDPSocketSource *self = NULL;
GInetAddress *iface_address = NULL;
GSocketAddress *bind_address = NULL;
GInetAddress *group = NULL;
GError *inner_error = NULL;
GSocketFamily family;
- iface_address = g_inet_address_new_from_string (host_ip);
+ self = GSSDP_SOCKET_SOURCE (initable);
+ iface_address = g_inet_address_new_from_string (self->priv->host_ip);
if (iface_address == NULL) {
if (error != NULL) {
*error = g_error_new (GSSDP_ERROR,
GSSDP_ERROR_FAILED,
"Invalid host ip: %s",
- host_ip);
+ self->priv->host_ip);
inner_error = *error;
}
}
- /* Create source */
- socket_source = g_slice_new0 (GSSDPSocketSource);
-
/* Create socket */
- socket_source->socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
- G_SOCKET_TYPE_DATAGRAM,
- G_SOCKET_PROTOCOL_UDP,
- &inner_error);
+ self->priv->socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
+ G_SOCKET_TYPE_DATAGRAM,
+ G_SOCKET_PROTOCOL_UDP,
+ &inner_error);
- if (!socket_source->socket) {
+ if (!self->priv->socket) {
g_propagate_prefixed_error (error,
inner_error,
"Could not create socket");
}
/* Enable broadcasting */
- if (!gssdp_socket_enable_broadcast (socket_source->socket,
+ if (!gssdp_socket_enable_broadcast (self->priv->socket,
TRUE,
&inner_error)) {
g_propagate_prefixed_error (error,
}
/* TTL */
- if (!gssdp_socket_set_ttl (socket_source->socket,
+ if (!gssdp_socket_set_ttl (self->priv->socket,
4,
&inner_error)) {
g_propagate_prefixed_error (error,
}
/* Set up additional things according to the type of socket desired */
- if (type == GSSDP_SOCKET_SOURCE_TYPE_MULTICAST) {
+ if (self->priv->type == GSSDP_SOCKET_SOURCE_TYPE_MULTICAST) {
/* Enable multicast loopback */
- if (!gssdp_socket_enable_loop (socket_source->socket,
+ if (!gssdp_socket_enable_loop (self->priv->socket,
TRUE,
&inner_error)) {
g_propagate_prefixed_error (
goto error;
}
- if (!gssdp_socket_mcast_interface_set (socket_source->socket,
+ if (!gssdp_socket_mcast_interface_set (self->priv->socket,
iface_address,
&inner_error)) {
g_propagate_prefixed_error (
}
/* Bind to requested port and address */
- if (!g_socket_bind (socket_source->socket,
+ if (!g_socket_bind (self->priv->socket,
bind_address,
TRUE,
&inner_error)) {
goto error;
}
- if (type == GSSDP_SOCKET_SOURCE_TYPE_MULTICAST) {
+ if (self->priv->type == GSSDP_SOCKET_SOURCE_TYPE_MULTICAST) {
/* Subscribe to multicast channel */
- if (!gssdp_socket_mcast_group_join (socket_source->socket,
+ if (!gssdp_socket_mcast_group_join (self->priv->socket,
group,
iface_address,
&inner_error)) {
}
}
- socket_source->source = g_socket_create_source (socket_source->socket,
- G_IO_IN | G_IO_ERR,
- NULL);
+ self->priv->source = g_socket_create_source (self->priv->socket,
+ G_IO_IN | G_IO_ERR,
+ NULL);
error:
if (iface_address != NULL)
g_object_unref (iface_address);
g_error_free (inner_error);
}
- return NULL;
+ return FALSE;
}
- return socket_source;
+ return TRUE;
}
GSocket *
{
g_return_val_if_fail (socket_source != NULL, NULL);
- return socket_source->socket;
+ return socket_source->priv->socket;
}
void
-gssdp_socket_source_destroy (GSSDPSocketSource *socket_source)
+gssdp_socket_source_set_callback (GSSDPSocketSource *self,
+ GSourceFunc callback,
+ gpointer user_data)
{
- g_return_if_fail (socket_source != NULL);
- g_source_destroy (socket_source->source);
- g_socket_close (socket_source->socket, NULL);
- g_object_unref (socket_source->socket);
- g_slice_free (GSSDPSocketSource, socket_source);
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (GSSDP_IS_SOCKET_SOURCE (self));
+
+ g_source_set_callback (self->priv->source, callback, user_data, NULL);
+}
+
+void
+gssdp_socket_source_attach (GSSDPSocketSource *self,
+ GMainContext *context)
+{
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (GSSDP_IS_SOCKET_SOURCE (self));
+
+ g_source_attach (self->priv->source, context);
+}
+
+static void
+gssdp_socket_source_dispose (GObject *object)
+{
+ GSSDPSocketSource *self;
+
+ self = GSSDP_SOCKET_SOURCE (object);
+
+ if (self->priv->source != NULL) {
+ g_source_unref (self->priv->source);
+ g_source_destroy (self->priv->source);
+ self->priv->source = NULL;
+ }
+
+ if (self->priv->socket != NULL) {
+ g_socket_close (self->priv->socket, NULL);
+ g_object_unref (self->priv->socket);
+ self->priv->socket = NULL;
+ }
+
+ G_OBJECT_CLASS (gssdp_socket_source_parent_class)->dispose (object);
+}
+
+static void
+gssdp_socket_source_finalize (GObject *object)
+{
+ GSSDPSocketSource *self;
+
+ self = GSSDP_SOCKET_SOURCE (object);
+
+ if (self->priv->host_ip != NULL) {
+ g_free (self->priv->host_ip);
+ self->priv->host_ip = NULL;
+ }
+
+ G_OBJECT_CLASS (gssdp_socket_source_parent_class)->finalize (object);
+}
+
+static void
+gssdp_socket_source_class_init (GSSDPSocketSourceClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = gssdp_socket_source_get_property;
+ object_class->set_property = gssdp_socket_source_set_property;
+ object_class->dispose = gssdp_socket_source_dispose;
+ object_class->finalize = gssdp_socket_source_finalize;
+
+ g_type_class_add_private (klass, sizeof (GSSDPSocketSourcePrivate));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_TYPE,
+ g_param_spec_int
+ ("type",
+ "Type",
+ "Type of socket-source (Multicast/Unicast)",
+ GSSDP_SOCKET_SOURCE_TYPE_REQUEST,
+ GSSDP_SOCKET_SOURCE_TYPE_MULTICAST,
+ GSSDP_SOCKET_SOURCE_TYPE_REQUEST,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_HOST_IP,
+ g_param_spec_string
+ ("host-ip",
+ "Host ip",
+ "IP address of associated network interface",
+ NULL,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
}
#ifndef __GSSDP_SOCKET_SOURCE_H__
#define __GSSDP_SOCKET_SOURCE_H__
+#include <glib-object.h>
+
#include <gio/gio.h>
G_BEGIN_DECLS
-struct _GSSDPSocketSource {
- GSource *source;
- GSocket *socket;
-};
+#define GSSDP_TYPE_SOCKET_SOURCE \
+ (gssdp_socket_source_get_type ())
+#define GSSDP_SOCKET_SOURCE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GSSDP_TYPE_SOCKET_SOURCE, \
+ GSSDPSocketSource))
+#define GSSDP_SOCKET_SOURCE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GSSDP_TYPE_SOCKET_SOURCE, \
+ GSSDPSocketSourceClass))
+#define GSSDP_IS_SOCKET_SOURCE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ GSSDP_TYPE_SOCKET_SOURCE))
+#define GSSDP_IS_SOCKET_SOURCE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ GSSDP_TYPE_SOCKET_SOURCE))
+#define GSSDP_SOCKET_SOURCE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GSSDP_TYPE_SOCKET_SOURCE, \
+ GSSDPSocketSourceClass))
-typedef struct _GSSDPSocketSource GSSDPSocketSource;
+typedef struct _GSSDPSocketSourcePrivate GSSDPSocketSourcePrivate;
typedef enum {
GSSDP_SOCKET_SOURCE_TYPE_REQUEST,
GSSDP_SOCKET_SOURCE_TYPE_MULTICAST
} GSSDPSocketSourceType;
+
+
+typedef struct _GSSDPSocketSource {
+ GObject parent;
+
+ GSSDPSocketSourcePrivate *priv;
+} GSSDPSocketSource;
+
+typedef struct _GSSDPSocketSourceClass {
+ GObjectClass parent_class;
+} GSSDPSocketSourceClass;
+
G_GNUC_INTERNAL GSSDPSocketSource *
gssdp_socket_source_new (GSSDPSocketSourceType type,
const char *host_ip,
GError **error);
-G_GNUC_INTERNAL void
-gssdp_socket_source_destroy (GSSDPSocketSource *socket_source);
-
G_GNUC_INTERNAL GSocket*
gssdp_socket_source_get_socket (GSSDPSocketSource *socket_source);
+G_GNUC_INTERNAL void
+gssdp_socket_source_set_callback (GSSDPSocketSource *socket_source,
+ GSourceFunc callback,
+ gpointer user_data);
+
+G_GNUC_INTERNAL void
+gssdp_socket_source_attach (GSSDPSocketSource *socket_source,
+ GMainContext *context);
+
G_END_DECLS
#endif /* __GSSDP_SOCKET_SOURCE_H__ */