Hello community, here is the log from the commit of package gupnp for openSUSE:Factory checked in at Tue Dec 8 11:37:41 CET 2009. -------- --- GNOME/gupnp/gupnp.changes 2009-10-01 17:11:09.000000000 +0200 +++ /mounts/work_src_done/STABLE/gupnp/gupnp.changes 2009-12-04 20:04:18.000000000 +0100 @@ -1,0 +2,31 @@ +Fri Dec 4 20:02:16 CET 2009 - vuntz@opensuse.org + +- Update to version 0.13.2: + + Utilize libconic (Maemo5) if available. + + Unix context manager must signal the unavailibility of all + contexts when disposed. + + Enable silent build rules if they are available. + + Fix race-conditions in client-side notification handling. + + Unix context manager ignores point-to-point interfaces. + + Context manager ignores interfaces without IP addresses. + + Don't require timeouts to be specified in subscription + requests. + + Fix build against gcc 4.[1,2]. + + Make network manager thread-safe. + + Remove idle source on dispose in context manager + implementations. + + Warn in docs that gupnp_service_info_get_introspection() is + evil and why. + + Service retrieves introspection data in truly async way. + + Fix some leaks. + + A bunch of code clean-ups. + +------------------------------------------------------------------- +Mon Nov 30 19:56:33 CET 2009 - dimstar@opensuse.org + +- Update to version 0.13.1: + + Use unix context manager if NetworkManager service is not + available + + Fix some minor leaks. + +------------------------------------------------------------------- calling whatdependson for head-i586 Old: ---- gupnp-0.13.0.tar.bz2 New: ---- gupnp-0.13.2.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ gupnp.spec ++++++ --- /var/tmp/diff_new_pack.IJmDFO/_old 2009-12-08 11:35:05.000000000 +0100 +++ /var/tmp/diff_new_pack.IJmDFO/_new 2009-12-08 11:35:05.000000000 +0100 @@ -1,5 +1,5 @@ # -# spec file for package gupnp (Version 0.13.0) +# spec file for package gupnp (Version 0.13.2) # # Copyright (c) 2009 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -18,7 +18,7 @@ Name: gupnp -Version: 0.13.0 +Version: 0.13.2 Release: 1 Summary: Implementation of the UPnP specification License: LGPL v2 or later ++++++ gupnp-0.13.0.tar.bz2 -> gupnp-0.13.2.tar.bz2 ++++++ ++++ 3116 lines of diff (skipped) ++++ retrying with extended exclude list diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/NEWS new/gupnp-0.13.2/NEWS --- old/gupnp-0.13.0/NEWS 2009-09-09 14:37:08.000000000 +0200 +++ new/gupnp-0.13.2/NEWS 2009-12-04 16:26:37.000000000 +0100 @@ -1,3 +1,54 @@ +0.13.2 +====== + +Changes since 0.13.1: + +- Utilize libconic (Maemo5) if available. +- Unix context manager must signal the unavailibility of all contexts when + disposed. +- Enable silent build rules if they are available. +- Fix race-conditions in client-side notification handling. +- Unix context manager ignores point-to-point interfaces. +- Context manager ignores interfaces without IP addresses. +- Don't require timeouts to be specified in subscription requests. +- Fix build against gcc 4.[1,2]. +- Make network manager thread-safe. +- Remove idle source on dispose in context manager implementations. +- Warn in docs that gupnp_service_info_get_introspection() is evil and why. +- Service retrieves introspection data in truly async way. +- Fix some leaks. +- A bunch of code clean-ups. + +All contributors: + +Olivier Crête <olivier.crete@collabora.co.uk> +Zeeshan Ali (Khattak) <zeeshanak@gnome.org> +Ross Burton <ross@linux.intel.com> +Jens Georg <mail@jensge.org> +Cem Eliguzel <celiguzel@ubicom.com> + +Bugs fixed: + +1890 - Timeout parsing problem with SUBSCRIBE method +1880 - subscription/notification handling is racy +1906 - Tests failed with gupnp 0.13 +1849 - Compile error when using gcc 4.[1,2] and strict aliasing +1494 - Ability to deal with multiple network interfaces +1881 - networkmanager interaction should use its own dbus connection + +0.13.1 +====== + +Changes since 0.13: + +- Use unix context manager if NetworkManager service is not available. +- Fix some minor leaks. + +All contributors: + +Zeeshan Ali (Khattak) <zeeshanak@gnome.org> +Ross Burton <ross@linux.intel.com> + 0.13 ==== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/config.h.in new/gupnp-0.13.2/config.h.in --- old/gupnp-0.13.0/config.h.in 2009-09-09 14:37:55.000000000 +0200 +++ new/gupnp-0.13.2/config.h.in 2009-12-04 16:27:12.000000000 +0100 @@ -27,6 +27,9 @@ /* Define to 1 if you have the <string.h> header file. */ #undef HAVE_STRING_H +/* Define to 1 if you have the <sys/param.h> header file. */ +#undef HAVE_SYS_PARAM_H + /* Define to 1 if you have the <sys/stat.h> header file. */ #undef HAVE_SYS_STAT_H diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/configure.ac new/gupnp-0.13.2/configure.ac --- old/gupnp-0.13.0/configure.ac 2009-09-09 14:37:08.000000000 +0200 +++ new/gupnp-0.13.2/configure.ac 2009-12-04 16:26:37.000000000 +0100 @@ -1,10 +1,12 @@ AC_PREREQ(2.53) -AC_INIT(gupnp, 0.13.0, http://www.gupnp.org/) +AC_INIT(gupnp, 0.13.2, http://www.gupnp.org/) AM_INIT_AUTOMAKE() AC_CONFIG_SRCDIR(libgupnp/gupnp.h) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + AC_ISC_POSIX AC_PROG_CC AC_STDC_HEADERS @@ -30,13 +32,33 @@ AC_MSG_CHECKING([Context Manager backend to use]) AC_MSG_RESULT([${with_context_manager}]) -if test "x$with_context_manager" = "xnetwork-manager"; then - PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1 >= 0.76) -fi AM_CONDITIONAL([USE_NETWORK_MANAGER], [test "x$with_context_manager" = "xnetwork-manager"]) +USE_CONIC=no +if test "x$with_context_manager" = "xunix"; then + dnl Use libconic if it's available + PKG_CHECK_MODULES(LIBCONIC, conic >= 0.13, + [ USE_CONIC=yes + AC_SUBST(LIBCONIC_CFLAGS) + AC_SUBST(LIBCONIC_LIBS) + ], + [ USE_CONIC=no + AC_MSG_WARN([conic 0.13 or greater not found.]) + ]) +fi + +AM_CONDITIONAL(USE_CONIC, test x$USE_CONIC = xyes) +AC_SUBST(USE_CONIC) + +# We need dbus-glib if either NetworkManager or libconic is used +if test "x$with_context_manager" = "xnetwork-manager" -o \ + "x$with_context_manager" = "xunix" -a \ + "x$USE_CONIC" = "xyes"; then + PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1 >= 0.76) +fi + # glib-genmarshal GLIB_GENMARSHAL=`pkg-config --variable=glib_genmarshal glib-2.0` AC_SUBST(GLIB_GENMARSHAL) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/doc/html/GUPnPServiceInfo.html new/gupnp-0.13.2/doc/html/GUPnPServiceInfo.html --- old/gupnp-0.13.0/doc/html/GUPnPServiceInfo.html 2009-09-09 14:38:29.000000000 +0200 +++ new/gupnp-0.13.2/doc/html/GUPnPServiceInfo.html 2009-12-04 16:28:22.000000000 +0100 @@ -438,7 +438,11 @@ <p> Note that introspection object is created from the information in service description document (SCPD) provided by the service so it can not be created -if the service does not provide an SCPD.</p> +if the service does not provide an SCPD. +</p> +<p> +Warning: You should use <a class="link" href="GUPnPServiceInfo.html#gupnp-service-info-get-introspection-async" title="gupnp_service_info_get_introspection_async ()"><code class="function">gupnp_service_info_get_introspection_async()</code></a> +instead, this function re-enter the GMainloop before returning.</p> <p> </p> <div class="variablelist"><table border="0"> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/doc/html/client-tutorial.html new/gupnp-0.13.2/doc/html/client-tutorial.html --- old/gupnp-0.13.0/doc/html/client-tutorial.html 2009-09-09 14:38:29.000000000 +0200 +++ new/gupnp-0.13.2/doc/html/client-tutorial.html 2009-12-04 16:28:22.000000000 +0100 @@ -39,7 +39,7 @@ <a name="client-tutorial"></a>Writing a UPnP Client</h2></div></div></div> <div class="simplesect" title="Introduction"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> -<a name="id420489"></a>Introduction</h2></div></div></div> +<a name="id381525"></a>Introduction</h2></div></div></div> <p> This chapter explains how to write an application which fetches the external IP address from an UPnP-compliant modem. To do this a @@ -56,7 +56,7 @@ </div> <div class="simplesect" title="Finding Services"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> -<a name="id421007"></a>Finding Services</h2></div></div></div> +<a name="id414188"></a>Finding Services</h2></div></div></div> <p> First, we initialize GUPnP and create a control point targeting the service type. Then we connect a signal handler so that we are notified @@ -118,7 +118,7 @@ </div> <div class="simplesect" title="Invoking Actions"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> -<a name="id430772"></a>Invoking Actions</h2></div></div></div> +<a name="id385845"></a>Invoking Actions</h2></div></div></div> <p> Now we have an application which searches for the service we specified and calls <code class="function">service_proxy_available_cb</code> for each one it @@ -168,7 +168,7 @@ </div> <div class="simplesect" title="Subscribing to state variable change notifications"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> -<a name="id456999"></a>Subscribing to state variable change notifications</h2></div></div></div> +<a name="id382128"></a>Subscribing to state variable change notifications</h2></div></div></div> <p> It is possible to get change notifications for the service state variables that have attribute <code class="literal">sendEvents="yes"</code>. We'll demonstrate @@ -203,7 +203,7 @@ </div> <div class="simplesect" title="Generating Wrappers"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> -<a name="id448364"></a>Generating Wrappers</h2></div></div></div> +<a name="id397945"></a>Generating Wrappers</h2></div></div></div> <p> Using <a class="link" href="GUPnPServiceProxy.html#gupnp-service-proxy-send-action" title="gupnp_service_proxy_send_action ()"><code class="function">gupnp_service_proxy_send_action()</code></a> and <a class="link" href="GUPnPServiceProxy.html#gupnp-service-proxy-add-notify" title="gupnp_service_proxy_add_notify ()"><code class="function">gupnp_service_proxy_add_notify()</code></a> can become tedious, because of the requirement to specify the types and deal diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/doc/html/gupnp-binding-tool.html new/gupnp-0.13.2/doc/html/gupnp-binding-tool.html --- old/gupnp-0.13.0/doc/html/gupnp-binding-tool.html 2009-09-09 14:38:29.000000000 +0200 +++ new/gupnp-0.13.2/doc/html/gupnp-binding-tool.html 2009-12-04 16:28:22.000000000 +0100 @@ -48,7 +48,7 @@ <div class="cmdsynopsis"><p><code class="command">gupnp-binding-tool</code> [--prefix {PREFIX}] [--mode {client|server}] {SCPD file}</p></div> </div> <div class="refsect1" title="Description"> -<a name="id430856"></a><h2>Description</h2> +<a name="id406841"></a><h2>Description</h2> <p> <span class="command"><strong>gupnp-binding-tool</strong></span> takes a <a class="glossterm" href="glossary.html#scpd"><em class="glossterm">SCPD file</em></a> and generates convenience C functions which call the actual GUPnP functions. The client-side bindings can be seen @@ -64,7 +64,7 @@ </p> </div> <div class="refsect1" title="Client side bindings"> -<a name="id474861"></a><h2>Client side bindings</h2> +<a name="id404827"></a><h2>Client side bindings</h2> <p> As an example, this action: </p> @@ -153,7 +153,7 @@ </p> </div> <div class="refsect1" title="Server side bindings"> -<a name="id479518"></a><h2>Server side bindings</h2> +<a name="id390836"></a><h2>Server side bindings</h2> <p> The corresponding server bindings for the same UPnP action (DeletePortMapping) look like this: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/doc/html/index.html new/gupnp-0.13.2/doc/html/index.html --- old/gupnp-0.13.0/doc/html/index.html 2009-09-09 14:38:29.000000000 +0200 +++ new/gupnp-0.13.2/doc/html/index.html 2009-12-04 16:28:22.000000000 +0100 @@ -29,11 +29,11 @@ <div class="titlepage"> <div> <div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">GUPnP Reference Manual</p></th></tr></table></div> -<div><p class="releaseinfo">Version 0.13.0 +<div><p class="releaseinfo">Version 0.13.2 </p></div> <div><p class="copyright">Copyright © 2007, 2008, 2009 OpenedHand Ltd, Nokia Corporation</p></div> <div><div class="legalnotice" title="Legal Notice"> -<a name="id411501"></a><p> +<a name="id363024"></a><p> Permission is granted to copy, distribute and/or modify this document under the terms of the <em class="citetitle">GNU Free Documentation License</em>, Version 1.1 or any later diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/doc/html/ix01.html new/gupnp-0.13.2/doc/html/ix01.html --- old/gupnp-0.13.0/doc/html/ix01.html 2009-09-09 14:38:29.000000000 +0200 +++ new/gupnp-0.13.2/doc/html/ix01.html 2009-12-04 16:28:22.000000000 +0100 @@ -35,7 +35,7 @@ </tr></table> <div class="index" title="Index"> <div class="titlepage"><div><div><h2 class="title"> -<a name="id384260"></a>Index</h2></div></div></div> +<a name="id335784"></a>Index</h2></div></div></div> <div class="index"><div class="indexdiv"> <h3>G</h3> <dl> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/doc/html/server-tutorial.html new/gupnp-0.13.2/doc/html/server-tutorial.html --- old/gupnp-0.13.0/doc/html/server-tutorial.html 2009-09-09 14:38:29.000000000 +0200 +++ new/gupnp-0.13.2/doc/html/server-tutorial.html 2009-12-04 16:28:22.000000000 +0100 @@ -39,7 +39,7 @@ <a name="server-tutorial"></a>Writing a UPnP Service</h2></div></div></div> <div class="simplesect" title="Introduction"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> -<a name="id429633"></a>Introduction</h2></div></div></div> +<a name="id400525"></a>Introduction</h2></div></div></div> <p> This chapter explains how to implement a UPnP service using GUPnP. For this example we will create a virtual UPnP-enabled light bulb. @@ -56,7 +56,7 @@ </div> <div class="simplesect" title="Defining the Device"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> -<a name="id459332"></a>Defining the Device</h2></div></div></div> +<a name="id408609"></a>Defining the Device</h2></div></div></div> <p> The first step is to write the <em class="firstterm">device description</em> file. This is a short XML document which describes the device and what @@ -132,7 +132,7 @@ </div> <div class="simplesect" title="Defining Services"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> -<a name="id458868"></a>Defining Services</h2></div></div></div> +<a name="id406106"></a>Defining Services</h2></div></div></div> <p> Becase we are using a standard service we can use the service description from the specification. This is the <code class="literal">SwitchPower1</code> @@ -225,7 +225,7 @@ </div> <div class="simplesect" title="Implementing the Device"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> -<a name="id464056"></a>Implementing the Device</h2></div></div></div> +<a name="id408236"></a>Implementing the Device</h2></div></div></div> <p> Before starting to implement the device, some boilerplate code is needed to initialise GUPnP. GLib types and threading needs to be initialised, @@ -262,7 +262,7 @@ </div> <div class="simplesect" title="Implementing a Service"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> -<a name="id464125"></a>Implementing a Service</h2></div></div></div> +<a name="id408304"></a>Implementing a Service</h2></div></div></div> <p> To implement a service we first fetch the <a class="link" href="GUPnPService.html" title="GUPnPService"><span class="type">GUPnPService</span></a> from the root device using <a class="link" href="GUPnPDeviceInfo.html#gupnp-device-info-get-service" title="gupnp_device_info_get_service ()"><code class="function">gupnp_device_info_get_service()</code></a> (<a class="link" href="GUPnPRootDevice.html" title="GUPnPRootDevice"><span class="type">GUPnPRootDevice</span></a> is a @@ -375,7 +375,7 @@ </div> <div class="simplesect" title="Generating Service-specific Wrappers"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> -<a name="id421444"></a>Generating Service-specific Wrappers</h2></div></div></div> +<a name="id374128"></a>Generating Service-specific Wrappers</h2></div></div></div> <p> Using service-specific wrappers can simplify the implementation of a service. Wrappers can be generated with <a class="xref" href="gupnp-binding-tool.html" title="gupnp-binding-tool"><span class="refentrytitle">gupnp-binding-tool</span>(1)</a> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/doc/xml/gupnp-service-info.xml new/gupnp-0.13.2/doc/xml/gupnp-service-info.xml --- old/gupnp-0.13.0/doc/xml/gupnp-service-info.xml 2009-09-09 14:38:29.000000000 +0200 +++ new/gupnp-0.13.2/doc/xml/gupnp-service-info.xml 2009-12-04 16:28:22.000000000 +0100 @@ -240,7 +240,11 @@ <para> Note that introspection object is created from the information in service description document (SCPD) provided by the service so it can not be created -if the service does not provide an SCPD.</para> +if the service does not provide an SCPD. +</para> +<para> +Warning: You should use <link linkend="gupnp-service-info-get-introspection-async"><function>gupnp_service_info_get_introspection_async()</function></link> +instead, this function re-enter the GMainloop before returning.</para> <para> </para><variablelist role="params"> <varlistentry><term><parameter>info</parameter> :</term> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/libgupnp/Makefile.am new/gupnp-0.13.2/libgupnp/Makefile.am --- old/gupnp-0.13.0/libgupnp/Makefile.am 2009-08-24 18:29:33.000000000 +0200 +++ new/gupnp-0.13.2/libgupnp/Makefile.am 2009-11-23 18:49:53.000000000 +0100 @@ -5,13 +5,19 @@ gupnp-network-manager.h CONTEXT_MANAGER_CFLAGS = -DUSE_NETWORK_MANAGER else -CONTEXT_MANAGER_IMPL = gupnp-unix-context-manager.c \ - gupnp-unix-context-manager.h +CONTEXT_MANAGER_IMPL = CONTEXT_MANAGER_CFLAGS = endif +if USE_CONIC +CONIC_CFLAGS = $(LIBCONIC_CFLAGS) -DUSE_CONIC +else +CONIC_CFLAGS = +endif + AM_CFLAGS = $(LIBGUPNP_CFLAGS) \ $(DBUS_GLIB_CFLAGS) \ + $(CONIC_CFLAGS) \ -I$(top_srcdir) \ $(CONTEXT_MANAGER_CFLAGS) @@ -37,10 +43,10 @@ gupnp.h gupnp-marshal.c: gupnp-marshal.list - $(GLIB_GENMARSHAL) --prefix=gupnp_marshal $(srcdir)/gupnp-marshal.list --header --body > gupnp-marshal.c + $(AM_V_GEN)$(GLIB_GENMARSHAL) --prefix=gupnp_marshal $(srcdir)/gupnp-marshal.list --header --body > gupnp-marshal.c gupnp-marshal.h: gupnp-marshal.list - $(GLIB_GENMARSHAL) --prefix=gupnp_marshal $(srcdir)/gupnp-marshal.list --header > gupnp-marshal.h + $(AM_V_GEN)$(GLIB_GENMARSHAL) --prefix=gupnp_marshal $(srcdir)/gupnp-marshal.list --header > gupnp-marshal.h BUILT_SOURCES = gupnp-marshal.c gupnp-marshal.h @@ -52,6 +58,8 @@ gupnp-context-private.h \ gupnp-context-manager.c \ $(CONTEXT_MANAGER_IMPL) \ + gupnp-unix-context-manager.c \ + gupnp-unix-context-manager.h \ gupnp-control-point.c \ gupnp-device.c \ gupnp-device-info.c \ @@ -77,7 +85,7 @@ gena-protocol.h \ $(BUILT_SOURCES) -libgupnp_1_0_la_LIBADD = $(LIBGUPNP_LIBS) $(DBUS_GLIB_LIBS) +libgupnp_1_0_la_LIBADD = $(LIBGUPNP_LIBS) $(DBUS_GLIB_LIBS) $(LIBCONIC_LIBS) EXTRA_DIST = gupnp-marshal.list \ gupnp-network-manager.c \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/libgupnp/gupnp-context-manager.c new/gupnp-0.13.2/libgupnp/gupnp-context-manager.c --- old/gupnp-0.13.0/libgupnp/gupnp-context-manager.c 2009-08-24 18:29:33.000000000 +0200 +++ new/gupnp-0.13.2/libgupnp/gupnp-context-manager.c 2009-12-04 11:00:49.000000000 +0100 @@ -42,6 +42,8 @@ #include "gupnp.h" #include "gupnp-marshal.h" +#include "gupnp-unix-context-manager.h" + G_DEFINE_TYPE (GUPnPContextManager, gupnp_context_manager, G_TYPE_OBJECT); @@ -226,6 +228,10 @@ manager->priv->impl = NULL; } + g_list_foreach (manager->priv->objects, (GFunc) g_object_unref, NULL); + g_list_free (manager->priv->objects); + manager->priv->objects = NULL; + /* Call super */ object_class = G_OBJECT_CLASS (gupnp_context_manager_parent_class); object_class->dispose (object); @@ -371,18 +377,18 @@ { GUPnPContextManager *manager; GUPnPContextManager *impl; - GType impl_type; + GType impl_type = G_TYPE_INVALID; #ifdef USE_NETWORK_MANAGER #include "gupnp-network-manager.h" - impl_type = GUPNP_TYPE_NETWORK_MANAGER; -#else -#include "gupnp-unix-context-manager.h" - - impl_type = GUPNP_TYPE_UNIX_CONTEXT_MANAGER; + if (gupnp_network_manager_is_available (main_context)) + impl_type = GUPNP_TYPE_NETWORK_MANAGER; #endif + if (impl_type == G_TYPE_INVALID) + impl_type = GUPNP_TYPE_UNIX_CONTEXT_MANAGER; + impl = g_object_new (impl_type, "main-context", main_context, "port", port, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/libgupnp/gupnp-device.c new/gupnp-0.13.2/libgupnp/gupnp-device.c --- old/gupnp-0.13.0/libgupnp/gupnp-device.c 2009-01-06 15:32:22.000000000 +0100 +++ new/gupnp-0.13.2/libgupnp/gupnp-device.c 2009-12-01 10:47:45.000000000 +0100 @@ -141,9 +141,11 @@ /* This can be NULL in which case *this* is the root device */ if (device->priv->root_device) { + GUPnPRootDevice **dev = &(device->priv->root_device); + g_object_add_weak_pointer (G_OBJECT (device->priv->root_device), - (gpointer *) &device->priv->root_device); + (gpointer *) dev); } break; @@ -182,9 +184,11 @@ device = GUPNP_DEVICE (object); if (device->priv->root_device) { + GUPnPRootDevice **dev = &(device->priv->root_device); + g_object_remove_weak_pointer (G_OBJECT (device->priv->root_device), - (gpointer *) &device->priv->root_device); + (gpointer *) dev); device->priv->root_device = NULL; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/libgupnp/gupnp-network-manager.c new/gupnp-0.13.2/libgupnp/gupnp-network-manager.c --- old/gupnp-0.13.0/libgupnp/gupnp-network-manager.c 2009-09-09 14:37:08.000000000 +0200 +++ new/gupnp-0.13.2/libgupnp/gupnp-network-manager.c 2009-12-04 11:00:49.000000000 +0100 @@ -33,6 +33,8 @@ #include <stdlib.h> #include <stdio.h> #include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> +#include <dbus/dbus.h> #include "gupnp-network-manager.h" #include "gupnp-context.h" @@ -75,9 +77,12 @@ } NMDevice; struct _GUPnPNetworkManagerPrivate { + DBusConnection *dbus_connection; DBusGConnection *connection; DBusGProxy *manager_proxy; + GSource *idle_context_creation_src; + GList *nm_devices; }; @@ -136,6 +141,8 @@ guint port; GError *error = NULL; + manager->priv->idle_context_creation_src = NULL; + g_object_get (manager, "main-context", &main_context, "port", &port, @@ -396,7 +403,6 @@ schedule_loopback_context_creation (GUPnPNetworkManager *manager) { GMainContext *main_context; - GSource *source; g_object_get (manager, "main-context", &main_context, @@ -405,30 +411,42 @@ /* Create contexts in mainloop so that is happens after user has hooked * to the "context-available" signal. */ - source = g_idle_source_new (); - g_source_attach (source, main_context); - g_source_set_callback (source, + manager->priv->idle_context_creation_src = g_idle_source_new (); + g_source_attach (manager->priv->idle_context_creation_src, + main_context); + g_source_set_callback (manager->priv->idle_context_creation_src, create_loopback_context, manager, NULL); + g_source_unref (manager->priv->idle_context_creation_src); } static void init_network_manager (GUPnPNetworkManager *manager) { GUPnPNetworkManagerPrivate *priv; - GError *error; - error = NULL; + DBusError derror; + GMainContext *main_context; priv = manager->priv; - priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (priv->connection == NULL) { - g_warning ("Failed to connect to System Bus: %s\n", - error->message); + g_object_get (manager, "main-context", &main_context, NULL); + + /* Do fake open to initialize types */ + dbus_g_connection_open ("", NULL); + dbus_error_init (&derror); + priv->dbus_connection = dbus_bus_get_private (DBUS_BUS_SYSTEM, &derror); + if (priv->dbus_connection == NULL) { + g_warning ("Failed to connect to System Bus: %s", + derror.message); return; } + dbus_connection_setup_with_g_main (priv->dbus_connection, main_context); + + priv->connection = + dbus_connection_get_g_connection (priv->dbus_connection); + priv->manager_proxy = dbus_g_proxy_new_for_name (priv->connection, DBUS_SERVICE_NM, MANAGER_PATH, @@ -497,10 +515,17 @@ static void gupnp_network_manager_dispose (GObject *object) { + GUPnPNetworkManager *manager; GUPnPNetworkManagerPrivate *priv; GObjectClass *object_class; - priv = GUPNP_NETWORK_MANAGER (object)->priv; + manager = GUPNP_NETWORK_MANAGER (object); + priv = manager->priv; + + if (manager->priv->idle_context_creation_src) { + g_source_destroy (manager->priv->idle_context_creation_src); + manager->priv->idle_context_creation_src = NULL; + } if (priv->manager_proxy != NULL) { g_object_unref (priv->manager_proxy); @@ -513,6 +538,12 @@ priv->nm_devices = NULL; } + if (priv->connection) { + dbus_connection_close (priv->dbus_connection); + dbus_g_connection_unref (priv->connection); + } + priv->connection = NULL; + /* Call super */ object_class = G_OBJECT_CLASS (gupnp_network_manager_parent_class); object_class->dispose (object); @@ -538,3 +569,50 @@ g_type_class_add_private (klass, sizeof (GUPnPNetworkManagerPrivate)); } +gboolean +gupnp_network_manager_is_available (GMainContext *main_context) +{ + DBusConnection *connection; + DBusError derror; + DBusGConnection *gconnection; + DBusGProxy *dbus_proxy; + GError *error = NULL; + gboolean ret = FALSE; + + /* Do fake open to initialize types */ + dbus_g_connection_open ("", NULL); + dbus_error_init (&derror); + connection = dbus_bus_get_private (DBUS_BUS_SYSTEM, &derror); + if (connection == NULL) { + g_warning ("Failed to connect to System Bus: %s", + derror.message); + return FALSE; + } + + dbus_connection_setup_with_g_main (connection, main_context); + gconnection = dbus_connection_get_g_connection (connection); + + dbus_proxy = dbus_g_proxy_new_for_name (gconnection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); + + if (!dbus_g_proxy_call (dbus_proxy, + "NameHasOwner", + &error, + G_TYPE_STRING, DBUS_SERVICE_NM, + G_TYPE_INVALID, + G_TYPE_BOOLEAN, &ret, + G_TYPE_INVALID)) { + g_warning ("%s.NameHasOwner() failed: %s", + DBUS_INTERFACE_DBUS, + error->message); + g_error_free (error); + } + + g_object_unref (dbus_proxy); + dbus_connection_close (connection); + dbus_g_connection_unref (gconnection); + + return ret; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/libgupnp/gupnp-network-manager.h new/gupnp-0.13.2/libgupnp/gupnp-network-manager.h --- old/gupnp-0.13.0/libgupnp/gupnp-network-manager.h 2009-06-26 12:36:37.000000000 +0200 +++ new/gupnp-0.13.2/libgupnp/gupnp-network-manager.h 2009-12-04 11:00:49.000000000 +0100 @@ -69,6 +69,9 @@ void (* _gupnp_reserved4) (void); } GUPnPNetworkManagerClass; +gboolean +gupnp_network_manager_is_available (GMainContext *main_context); + G_END_DECLS #endif /* __GUPNP_NETWORK_MANAGER_H__ */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/libgupnp/gupnp-service-info.c new/gupnp-0.13.2/libgupnp/gupnp-service-info.c --- old/gupnp-0.13.0/libgupnp/gupnp-service-info.c 2009-08-24 18:29:33.000000000 +0200 +++ new/gupnp-0.13.2/libgupnp/gupnp-service-info.c 2009-12-02 15:27:43.000000000 +0100 @@ -195,6 +195,7 @@ data->message, SOUP_STATUS_CANCELLED); + g_object_unref (data->message); get_scpd_url_data_free (data); info->priv->pending_gets = @@ -543,6 +544,9 @@ * description document (SCPD) provided by the service so it can not be created * if the service does not provide an SCPD. * + * Warning: You should use gupnp_service_info_get_introspection_async() + * instead, this function re-enter the GMainloop before returning. + * * Return value: A new #GUPnPServiceIntrospection for this service or %NULL. * Unref after use. **/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/libgupnp/gupnp-service-proxy.c new/gupnp-0.13.2/libgupnp/gupnp-service-proxy.c --- old/gupnp-0.13.0/libgupnp/gupnp-service-proxy.c 2009-07-29 16:00:39.000000000 +0200 +++ new/gupnp-0.13.2/libgupnp/gupnp-service-proxy.c 2009-12-02 15:27:43.000000000 +0100 @@ -106,6 +106,13 @@ gpointer user_data; } CallbackData; +typedef struct { + char *sid; + int seq; + + xmlDoc *doc; +} EmitNotifyData; + static void subscribe_got_response (SoupSession *session, SoupMessage *msg, @@ -135,6 +142,32 @@ g_slice_free (NotifyData, data); } +/* Steals doc reference */ +static EmitNotifyData * +emit_notify_data_new (const char *sid, + int seq, + xmlDoc *doc) +{ + EmitNotifyData *data; + + data = g_slice_new (EmitNotifyData); + + data->sid = g_strdup (sid); + data->seq = seq; + data->doc = doc; + + return data; +} + +static void +emit_notify_data_free (EmitNotifyData *data) +{ + g_free (data->sid); + xmlFreeDoc (data->doc); + + g_slice_free (EmitNotifyData, data); +} + static void gupnp_service_proxy_init (GUPnPServiceProxy *proxy) { @@ -252,7 +285,7 @@ } while (proxy->priv->pending_notifies) { - xmlFreeDoc (proxy->priv->pending_notifies->data); + emit_notify_data_free (proxy->priv->pending_notifies->data); proxy->priv->pending_notifies = g_list_delete_link (proxy->priv->pending_notifies, proxy->priv->pending_notifies); @@ -1325,79 +1358,117 @@ return found; } +static void emit_notification (GUPnPServiceProxy *proxy, + xmlDoc *doc) +{ + xmlNode *node; + + node = xmlDocGetRootElement (doc); + + /* Iterate over all provided properties */ + for (node = node->children; node; node = node->next) { + xmlNode *var_node; + NotifyData *data; + GValue value = {0, }; + GList *l; + + /* variableName node */ + var_node = node->children; + + if (var_node == NULL || + strcmp ((char *) node->name, "property") != 0) + continue; + + data = g_hash_table_lookup (proxy->priv->notify_hash, + var_node->name); + if (data == NULL) + continue; + + /* Make a GValue of the desired type */ + g_value_init (&value, data->type); + + if (!gvalue_util_set_value_from_xml_node (&value, var_node)) { + g_value_unset (&value); + + continue; + } + + /* Call callbacks */ + for (l = data->callbacks; l; l = l->next) { + CallbackData *callback_data; + + callback_data = l->data; + + callback_data->callback (proxy, + (const char *) var_node->name, + &value, + callback_data->user_data); + } + + /* Cleanup */ + g_value_unset (&value); + } +} + /* Emit pending notifications. See comment below on why we do this. */ static gboolean emit_notifications (gpointer user_data) { GUPnPServiceProxy *proxy = user_data; + GList *pending_notify; + gboolean resubscribe = FALSE; g_assert (user_data); - - while (proxy->priv->pending_notifies != NULL) { - xmlDoc *doc; - xmlNode *node; - doc = proxy->priv->pending_notifies->data; - node = xmlDocGetRootElement (doc); - - /* Iterate over all provided properties */ - for (node = node->children; node; node = node->next) { - xmlNode *var_node; - - if (strcmp ((char *) node->name, "property") != 0) - continue; - - /* property */ - for (var_node = node->children; var_node; - var_node = var_node->next) { - NotifyData *data; - GValue value = {0, }; - GList *l; - - data = g_hash_table_lookup - (proxy->priv->notify_hash, - var_node->name); - if (data == NULL) - continue; - - /* Make a GValue of the desired type */ - g_value_init (&value, data->type); - - if (!gvalue_util_set_value_from_xml_node - (&value, var_node)) { - g_value_unset (&value); - - continue; - } - - /* Call callbacks */ - for (l = data->callbacks; l; l = l->next) { - CallbackData *callback_data; - - callback_data = l->data; - - callback_data->callback - (proxy, - (const char *) var_node->name, - &value, - callback_data->user_data); - } - - /* Cleanup */ - g_value_unset (&value); - } + if (proxy->priv->sid == NULL) + /* No SID */ + if (G_LIKELY (proxy->priv->subscribed)) + /* subscription in progress, delay emision! */ + return TRUE; + + for (pending_notify = proxy->priv->pending_notifies; + pending_notify != NULL; + pending_notify = pending_notify->next) { + EmitNotifyData *emit_notify_data; + + emit_notify_data = pending_notify->data; + + if (emit_notify_data->seq > proxy->priv->seq) { + /* Oops, we missed a notify. Resubscribe .. */ + resubscribe = TRUE; + + break; } - - /* Cleanup */ - xmlFreeDoc (doc); + + /* Increment our own event sequence number */ + if (proxy->priv->seq < G_MAXINT32) + proxy->priv->seq++; + else + proxy->priv->seq = 1; + + if (G_LIKELY (proxy->priv->sid != NULL && + strcmp (emit_notify_data->sid, + proxy->priv->sid) == 0)) + /* Our SID, entertain! */ + emit_notification (proxy, emit_notify_data->doc); + } + + /* Cleanup */ + while (proxy->priv->pending_notifies != NULL) { + emit_notify_data_free (proxy->priv->pending_notifies->data); proxy->priv->pending_notifies = g_list_delete_link (proxy->priv->pending_notifies, proxy->priv->pending_notifies); } - + proxy->priv->notify_idle_src = NULL; + if (resubscribe) { + unsubscribe (proxy); + subscribe (proxy); + } + return FALSE; } @@ -1418,6 +1489,7 @@ int seq; xmlDoc *doc; xmlNode *node; + EmitNotifyData *emit_notify_data; proxy = GUPNP_SERVICE_PROXY (user_data); @@ -1444,16 +1516,6 @@ return; } - hdr = soup_message_headers_get (msg->request_headers, "SID"); - if (hdr == NULL || - (proxy->priv->sid == NULL || - strcmp (hdr, proxy->priv->sid) != 0)) { - /* No SID or not ours */ - soup_message_set_status (msg, SOUP_STATUS_PRECONDITION_FAILED); - - return; - } - hdr = soup_message_headers_get (msg->request_headers, "SEQ"); if (hdr == NULL) { /* No SEQ header */ @@ -1463,23 +1525,15 @@ } seq = atoi (hdr); - if (seq > proxy->priv->seq) { - /* Oops, we missed a notify. Resubscribe .. */ - unsubscribe (proxy); - subscribe (proxy); - /* Message was OK otherwise */ - soup_message_set_status (msg, SOUP_STATUS_OK); + hdr = soup_message_headers_get (msg->request_headers, "SID"); + if (hdr == NULL) { + /* No SID */ + soup_message_set_status (msg, SOUP_STATUS_PRECONDITION_FAILED); return; } - /* Increment our own event sequence number */ - if (proxy->priv->seq < G_MAXINT32) - proxy->priv->seq++; - else - proxy->priv->seq = 1; - /* Parse the actual XML message content */ doc = xmlRecoverMemory (msg->request_body->data, msg->request_body->length); @@ -1509,8 +1563,10 @@ * call the callbacks in an idle handler so that if the client calls the * device in the notify callback the server can actually respond. */ + emit_notify_data = emit_notify_data_new (hdr, seq, doc); + proxy->priv->pending_notifies = - g_list_append (proxy->priv->pending_notifies, doc); + g_list_append (proxy->priv->pending_notifies, emit_notify_data); if (!proxy->priv->notify_idle_src) { GUPnPContext *context; GMainContext *main_context; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/libgupnp/gupnp-service.c new/gupnp-0.13.2/libgupnp/gupnp-service.c --- old/gupnp-0.13.0/libgupnp/gupnp-service.c 2009-08-24 18:29:33.000000000 +0200 +++ new/gupnp-0.13.2/libgupnp/gupnp-service.c 2009-12-02 15:27:43.000000000 +0100 @@ -98,6 +98,9 @@ subscription */ } SubscriptionData; +static void +send_initial_state (SubscriptionData *data); + static SoupSession * gupnp_service_get_session (GUPnPService *service) { @@ -893,7 +896,7 @@ timeout_seconds = 0; - if (strncmp (timeout, "Second-", strlen ("Second-")) == 0) { + if (timeout && strncmp (timeout, "Second-", strlen ("Second-")) == 0) { /* We have a finite timeout */ timeout_seconds = CLAMP (atoi (timeout + strlen ("Second-")), GENA_MIN_TIMEOUT, @@ -904,6 +907,48 @@ return timeout_seconds; } +static void +send_initial_state (SubscriptionData *data) +{ + GQueue *queue; + char *mem; + GList *l; + + /* Send initial event message */ + queue = g_queue_new (); + + for (l = data->service->priv->state_variables; l; l = l->next) { + NotifyData *ndata; + + ndata = g_slice_new0 (NotifyData); + + g_signal_emit (data->service, + signals[QUERY_VARIABLE], + g_quark_from_string (l->data), + l->data, + &ndata->value); + + if (!G_IS_VALUE (&ndata->value)) { + g_slice_free (NotifyData, ndata); + + continue; + } + + ndata->variable = g_strdup (l->data); + + g_queue_push_tail (queue, ndata); + } + + mem = create_property_set (queue); + notify_subscriber (data->sid, data, mem); + + /* Cleanup */ + g_queue_free (queue); + + g_free (mem); +} + + /* Subscription request */ static void subscribe (GUPnPService *service, @@ -914,9 +959,6 @@ SubscriptionData *data; char *start, *end, *uri; int timeout_seconds; - GQueue *queue; - char *mem; - GList *l; data = g_slice_new0 (SubscriptionData); @@ -981,38 +1023,7 @@ /* Respond */ subscription_response (service, msg, data->sid, timeout_seconds); - /* Send initial event message */ - queue = g_queue_new (); - - for (l = service->priv->state_variables; l; l = l->next) { - NotifyData *ndata; - - ndata = g_slice_new0 (NotifyData); - - g_signal_emit (service, - signals[QUERY_VARIABLE], - g_quark_from_string (l->data), - l->data, - &ndata->value); - - if (!G_IS_VALUE (&ndata->value)) { - g_slice_free (NotifyData, ndata); - - continue; - } - - ndata->variable = g_strdup (l->data); - - g_queue_push_tail (queue, ndata); - } - - mem = create_property_set (queue); - notify_subscriber (data->sid, data, mem); - - /* Cleanup */ - g_queue_free (queue); - - g_free (mem); + send_initial_state (data); } /* Resubscription request */ @@ -1148,6 +1159,50 @@ } } +void +got_introspection (GUPnPServiceInfo *info, + GUPnPServiceIntrospection *introspection, + const GError *error, + gpointer user_data) +{ + GUPnPService *service = user_data; + const GList *state_variables, *l; + GHashTableIter iter; + SubscriptionData *data; + + if (introspection) { + state_variables = + gupnp_service_introspection_list_state_variables + (introspection); + + for (l = state_variables; l; l = l->next) { + GUPnPServiceStateVariableInfo *variable; + + variable = l->data; + + if (!variable->send_events) + continue; + + service->priv->state_variables = + g_list_prepend (service->priv->state_variables, + g_strdup (variable->name)); + } + + g_object_unref (introspection); + } else { + g_warning ("Failed to get SCPD: %s\n" + "The initial event message will not be sent.", + error ? error->message : "No error"); + } + + g_hash_table_iter_init (&iter, service->priv->subscriptions); + + while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &data)) + send_initial_state (data); + + g_object_unref (service); +} + static GObject * gupnp_service_constructor (GType type, guint n_construct_params, @@ -1157,9 +1212,6 @@ GObject *object; GUPnPService *service; GUPnPServiceInfo *info; - GError *error; - GUPnPServiceIntrospection *introspection; - const GList *state_variables, *l; GUPnPContext *context; SoupServer *server; SoupURI *uri; @@ -1176,35 +1228,10 @@ info = GUPNP_SERVICE_INFO (object); /* Get introspection and save state variable names */ - error = NULL; - - introspection = gupnp_service_info_get_introspection (info, &error); - if (introspection) { - state_variables = - gupnp_service_introspection_list_state_variables - (introspection); - for (l = state_variables; l; l = l->next) { - GUPnPServiceStateVariableInfo *variable; - - variable = l->data; - - if (!variable->send_events) - continue; - - service->priv->state_variables = - g_list_prepend (service->priv->state_variables, - g_strdup (variable->name)); - } - - g_object_unref (introspection); - } else { - g_warning ("Failed to get SCPD: %s\n" - "The initial event message will not be sent.", - error->message); - - g_error_free (error); - } + gupnp_service_info_get_introspection_async (info, got_introspection, + object); + g_object_ref (object); /* Get server */ context = gupnp_service_info_get_context (info); @@ -1276,9 +1303,11 @@ switch (property_id) { case PROP_ROOT_DEVICE: service->priv->root_device = g_value_get_object (value); + GUPnPRootDevice **dev = &(service->priv->root_device); + g_object_add_weak_pointer (G_OBJECT (service->priv->root_device), - (gpointer *) &service->priv->root_device); + (gpointer *) dev); service->priv->notify_available_id = g_signal_connect_object (service->priv->root_device, @@ -1324,6 +1353,8 @@ service = GUPNP_SERVICE (object); if (service->priv->root_device) { + GUPnPRootDevice **dev = &(service->priv->root_device); + if (g_signal_handler_is_connected (service->priv->root_device, service->priv->notify_available_id)) { @@ -1334,7 +1365,7 @@ g_object_remove_weak_pointer (G_OBJECT (service->priv->root_device), - (gpointer *) &service->priv->root_device); + (gpointer *) dev); service->priv->root_device = NULL; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/libgupnp/gupnp-unix-context-manager.c new/gupnp-0.13.2/libgupnp/gupnp-unix-context-manager.c --- old/gupnp-0.13.0/libgupnp/gupnp-unix-context-manager.c 2009-07-29 16:00:34.000000000 +0200 +++ new/gupnp-0.13.2/libgupnp/gupnp-unix-context-manager.c 2009-12-02 15:27:43.000000000 +0100 @@ -44,14 +44,33 @@ #include <ifaddrs.h> #include <libsoup/soup-address.h> #include <glib/gstdio.h> +#include <libgssdp/gssdp-error.h> #include "gupnp-unix-context-manager.h" #include "gupnp-context.h" +#ifdef USE_CONIC /* MAEMO */ +#include <conic.h> +#include <dbus/dbus.h> +#include <dbus/dbus-glib-lowlevel.h> +#endif /* MAEMO */ + G_DEFINE_TYPE (GUPnPUnixContextManager, gupnp_unix_context_manager, GUPNP_TYPE_CONTEXT_MANAGER); +struct _GUPnPUnixContextManagerPrivate { + GList *contexts; /* List of GUPnPContext instances */ + + GSource *idle_context_creation_src; + + +#ifdef USE_CONIC /* MAEMO */ + ConIcConnection *conic; + DBusConnection *system_bus; +#endif /* MAEMO */ +}; + void create_and_signal_context (GUPnPUnixContextManager *manager, const char *interface) @@ -75,9 +94,12 @@ "error", &error, NULL); if (error != NULL) { - g_warning ("Failed to create context for interface '%s': %s\n", - interface, - error->message); + if (!(error->domain == GSSDP_ERROR && + error->code == GSSDP_ERROR_NO_IP_ADDRESS)) + g_warning ( + "Failed to create context for interface '%s': %s\n", + interface, + error->message); g_error_free (error); @@ -88,7 +110,8 @@ "context-available", context); - g_object_unref (context); + manager->priv->contexts = g_list_append (manager->priv->contexts, + context); } /* @@ -102,6 +125,12 @@ char *ret; GList *processed; + manager->priv->idle_context_creation_src = NULL; + + if (manager->priv->contexts != NULL) { + return FALSE; + } + ret = NULL; if (getifaddrs (&ifa_list) != 0) { @@ -120,6 +149,9 @@ (GCompareFunc) strcmp) != NULL) continue; + if (ifa->ifa_flags & IFF_POINTOPOINT) + continue; + if (ifa->ifa_flags & IFF_UP) create_and_signal_context (manager, ifa->ifa_name); @@ -133,10 +165,60 @@ } static void +destroy_contexts (GUPnPUnixContextManager *manager) +{ + while (manager->priv->contexts) { + GUPnPContext *context; + + context = GUPNP_CONTEXT (manager->priv->contexts->data); + + g_signal_emit_by_name (manager, + "context-unavailable", + context); + g_object_unref (context); + + manager->priv->contexts = g_list_delete_link + (manager->priv->contexts, + manager->priv->contexts); + } +} + +#ifdef USE_CONIC /* MAEMO */ +static void conic_event (ConIcConnection* connection, + ConIcConnectionEvent* event, + gpointer user_data) +{ + GUPnPUnixContextManager *manager; + ConIcConnectionStatus status; + const gchar* bearer; + + manager = GUPNP_UNIX_CONTEXT_MANAGER (user_data); + status = con_ic_connection_event_get_status (event); + + bearer = con_ic_event_get_bearer_type (CON_IC_EVENT (event)); + if (bearer != NULL && + (strcmp (bearer, CON_IC_BEARER_WLAN_INFRA) == 0 || + strcmp (bearer, CON_IC_BEARER_WLAN_ADHOC) == 0)) { + switch (status) { + case CON_IC_STATUS_CONNECTED: + create_contexts (manager); + break; + case CON_IC_STATUS_DISCONNECTED: + destroy_contexts (manager); + break; + default: + /* Ignore other events */ + break; + } + } +} +#else +static void schedule_contexts_creation (GUPnPUnixContextManager *manager) { GMainContext *main_context; - GSource *source; + + manager->priv->idle_context_creation_src = NULL; g_object_get (manager, "main-context", &main_context, @@ -145,17 +227,24 @@ /* Create contexts in mainloop so that is happens after user has hooked * to the "context-available" signal. */ - source = g_idle_source_new (); - g_source_attach (source, main_context); - g_source_set_callback (source, + manager->priv->idle_context_creation_src = g_idle_source_new (); + g_source_attach (manager->priv->idle_context_creation_src, + main_context); + g_source_set_callback (manager->priv->idle_context_creation_src, create_contexts, manager, NULL); + g_source_unref (manager->priv->idle_context_creation_src); } +#endif /* MAEMO */ static void gupnp_unix_context_manager_init (GUPnPUnixContextManager *manager) { + manager->priv = + G_TYPE_INSTANCE_GET_PRIVATE (manager, + GUPNP_TYPE_UNIX_CONTEXT_MANAGER, + GUPnPUnixContextManagerPrivate); } static void @@ -166,7 +255,25 @@ manager = GUPNP_UNIX_CONTEXT_MANAGER (object); +#ifdef USE_CONIC /* MAEMO */ + /* Initialize the system bus so libconic can receive ICD messages. */ + manager->priv->system_bus = dbus_bus_get (DBUS_BUS_SYSTEM, NULL); + dbus_connection_setup_with_g_main (manager->priv->system_bus, NULL); + + manager->priv->conic = con_ic_connection_new (); + g_assert (manager->priv->conic != NULL); + + g_signal_connect (manager->priv->conic, + "connection-event", + G_CALLBACK (conic_event), + manager); + g_object_set (manager->priv->conic, + "automatic-connection-events", + TRUE, + NULL); +#else schedule_contexts_creation (manager); +#endif /* MAEMO */ /* Chain-up */ parent_class = G_OBJECT_CLASS (gupnp_unix_context_manager_parent_class); @@ -183,6 +290,26 @@ manager = GUPNP_UNIX_CONTEXT_MANAGER (object); + destroy_contexts (manager); + +#ifdef USE_CONIC /* MAEMO */ + if (manager->priv->conic != NULL) { + g_object_unref (manager->priv->conic); + manager->priv->conic = NULL; + } + + if (manager->priv->system_bus != NULL) { + dbus_connection_unref (manager->priv->system_bus); + manager->priv->system_bus = NULL; + } +#endif /* MAEMO */ + + if (manager->priv->idle_context_creation_src) { + g_source_destroy (manager->priv->idle_context_creation_src); + manager->priv->idle_context_creation_src = NULL; + } + + /* Call super */ object_class = G_OBJECT_CLASS (gupnp_unix_context_manager_parent_class); object_class->dispose (object); @@ -197,5 +324,8 @@ object_class->constructed = gupnp_unix_context_manager_constructed; object_class->dispose = gupnp_unix_context_manager_dispose; + + g_type_class_add_private (klass, + sizeof (GUPnPUnixContextManagerPrivate)); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/gupnp-0.13.0/libgupnp/gupnp-unix-context-manager.h new/gupnp-0.13.2/libgupnp/gupnp-unix-context-manager.h --- old/gupnp-0.13.0/libgupnp/gupnp-unix-context-manager.h 2009-06-26 12:36:37.000000000 +0200 +++ new/gupnp-0.13.2/libgupnp/gupnp-unix-context-manager.h 2009-11-23 18:49:53.000000000 +0100 @@ -52,8 +52,12 @@ GUPNP_TYPE_UNIX_CONTEXT_MANAGER, \ GUPnPUnixContextManagerClass)) +typedef struct _GUPnPUnixContextManagerPrivate GUPnPUnixContextManagerPrivate; + typedef struct { GUPnPContextManager parent; + + GUPnPUnixContextManagerPrivate *priv; } GUPnPUnixContextManager; typedef struct { ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... -- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org