/*
 * Generated by gdbus-codegen 2.40.2. DO NOT EDIT.
 *
 * The license of this code is the same as for the source it was derived from.
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include "interfaces/watchdog.h"

#include <string.h>
#ifdef G_OS_UNIX
#  include <gio/gunixfdlist.h>
#endif

typedef struct
{
  GDBusArgInfo parent_struct;
  gboolean use_gvariant;
} _ExtendedGDBusArgInfo;

typedef struct
{
  GDBusMethodInfo parent_struct;
  const gchar *signal_name;
  gboolean pass_fdlist;
} _ExtendedGDBusMethodInfo;

typedef struct
{
  GDBusSignalInfo parent_struct;
  const gchar *signal_name;
} _ExtendedGDBusSignalInfo;

typedef struct
{
  GDBusPropertyInfo parent_struct;
  const gchar *hyphen_name;
  gboolean use_gvariant;
} _ExtendedGDBusPropertyInfo;

typedef struct
{
  GDBusInterfaceInfo parent_struct;
  const gchar *hyphen_name;
} _ExtendedGDBusInterfaceInfo;

typedef struct
{
  const _ExtendedGDBusPropertyInfo *info;
  guint prop_id;
  GValue orig_value; /* the value before the change */
} ChangedProperty;

static void
_changed_property_free (ChangedProperty *data)
{
  g_value_unset (&data->orig_value);
  g_free (data);
}

static gboolean
_g_strv_equal0 (gchar **a, gchar **b)
{
  gboolean ret = FALSE;
  guint n;
  if (a == NULL && b == NULL)
    {
      ret = TRUE;
      goto out;
    }
  if (a == NULL || b == NULL)
    goto out;
  if (g_strv_length (a) != g_strv_length (b))
    goto out;
  for (n = 0; a[n] != NULL; n++)
    if (g_strcmp0 (a[n], b[n]) != 0)
      goto out;
  ret = TRUE;
out:
  return ret;
}

static gboolean
_g_variant_equal0 (GVariant *a, GVariant *b)
{
  gboolean ret = FALSE;
  if (a == NULL && b == NULL)
    {
      ret = TRUE;
      goto out;
    }
  if (a == NULL || b == NULL)
    goto out;
  ret = g_variant_equal (a, b);
out:
  return ret;
}

G_GNUC_UNUSED static gboolean
_g_value_equal (const GValue *a, const GValue *b)
{
  gboolean ret = FALSE;
  g_assert (G_VALUE_TYPE (a) == G_VALUE_TYPE (b));
  switch (G_VALUE_TYPE (a))
    {
      case G_TYPE_BOOLEAN:
        ret = (g_value_get_boolean (a) == g_value_get_boolean (b));
        break;
      case G_TYPE_UCHAR:
        ret = (g_value_get_uchar (a) == g_value_get_uchar (b));
        break;
      case G_TYPE_INT:
        ret = (g_value_get_int (a) == g_value_get_int (b));
        break;
      case G_TYPE_UINT:
        ret = (g_value_get_uint (a) == g_value_get_uint (b));
        break;
      case G_TYPE_INT64:
        ret = (g_value_get_int64 (a) == g_value_get_int64 (b));
        break;
      case G_TYPE_UINT64:
        ret = (g_value_get_uint64 (a) == g_value_get_uint64 (b));
        break;
      case G_TYPE_DOUBLE:
        {
          /* Avoid -Wfloat-equal warnings by doing a direct bit compare */
          gdouble da = g_value_get_double (a);
          gdouble db = g_value_get_double (b);
          ret = memcmp (&da, &db, sizeof (gdouble)) == 0;
        }
        break;
      case G_TYPE_STRING:
        ret = (g_strcmp0 (g_value_get_string (a), g_value_get_string (b)) == 0);
        break;
      case G_TYPE_VARIANT:
        ret = _g_variant_equal0 (g_value_get_variant (a), g_value_get_variant (b));
        break;
      default:
        if (G_VALUE_TYPE (a) == G_TYPE_STRV)
          ret = _g_strv_equal0 (g_value_get_boxed (a), g_value_get_boxed (b));
        else
          g_critical ("_g_value_equal() does not handle type %s", g_type_name (G_VALUE_TYPE (a)));
        break;
    }
  return ret;
}

/* ------------------------------------------------------------------------
 * Code for interface org.openbmc.Watchdog
 * ------------------------------------------------------------------------
 */

/**
 * SECTION:Watchdog
 * @title: Watchdog
 * @short_description: Generated C code for the org.openbmc.Watchdog D-Bus interface
 *
 * This section contains code for working with the <link linkend="gdbus-interface-org-openbmc-Watchdog.top_of_page">org.openbmc.Watchdog</link> D-Bus interface in C.
 */

/* ---- Introspection data for org.openbmc.Watchdog ---- */

static const _ExtendedGDBusMethodInfo _watchdog_method_info_start =
{
  {
    -1,
    (gchar *) "start",
    NULL,
    NULL,
    NULL
  },
  "handle-start",
  FALSE
};

static const _ExtendedGDBusMethodInfo _watchdog_method_info_poke =
{
  {
    -1,
    (gchar *) "poke",
    NULL,
    NULL,
    NULL
  },
  "handle-poke",
  FALSE
};

static const _ExtendedGDBusMethodInfo _watchdog_method_info_stop =
{
  {
    -1,
    (gchar *) "stop",
    NULL,
    NULL,
    NULL
  },
  "handle-stop",
  FALSE
};

static const _ExtendedGDBusMethodInfo * const _watchdog_method_info_pointers[] =
{
  &_watchdog_method_info_start,
  &_watchdog_method_info_poke,
  &_watchdog_method_info_stop,
  NULL
};

static const _ExtendedGDBusSignalInfo _watchdog_signal_info_watchdog_error =
{
  {
    -1,
    (gchar *) "WatchdogError",
    NULL,
    NULL
  },
  "watchdog-error"
};

static const _ExtendedGDBusSignalInfo * const _watchdog_signal_info_pointers[] =
{
  &_watchdog_signal_info_watchdog_error,
  NULL
};

static const _ExtendedGDBusPropertyInfo _watchdog_property_info_watchdog =
{
  {
    -1,
    (gchar *) "watchdog",
    (gchar *) "i",
    G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE,
    NULL
  },
  "watchdog",
  FALSE
};

static const _ExtendedGDBusPropertyInfo _watchdog_property_info_poll_interval =
{
  {
    -1,
    (gchar *) "poll_interval",
    (gchar *) "i",
    G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE,
    NULL
  },
  "poll-interval",
  FALSE
};

static const _ExtendedGDBusPropertyInfo * const _watchdog_property_info_pointers[] =
{
  &_watchdog_property_info_watchdog,
  &_watchdog_property_info_poll_interval,
  NULL
};

static const _ExtendedGDBusInterfaceInfo _watchdog_interface_info =
{
  {
    -1,
    (gchar *) "org.openbmc.Watchdog",
    (GDBusMethodInfo **) &_watchdog_method_info_pointers,
    (GDBusSignalInfo **) &_watchdog_signal_info_pointers,
    (GDBusPropertyInfo **) &_watchdog_property_info_pointers,
    NULL
  },
  "watchdog",
};


/**
 * watchdog_interface_info:
 *
 * Gets a machine-readable description of the <link linkend="gdbus-interface-org-openbmc-Watchdog.top_of_page">org.openbmc.Watchdog</link> D-Bus interface.
 *
 * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free.
 */
GDBusInterfaceInfo *
watchdog_interface_info (void)
{
  return (GDBusInterfaceInfo *) &_watchdog_interface_info.parent_struct;
}

/**
 * watchdog_override_properties:
 * @klass: The class structure for a #GObject<!-- -->-derived class.
 * @property_id_begin: The property id to assign to the first overridden property.
 *
 * Overrides all #GObject properties in the #Watchdog interface for a concrete class.
 * The properties are overridden in the order they are defined.
 *
 * Returns: The last property id.
 */
guint
watchdog_override_properties (GObjectClass *klass, guint property_id_begin)
{
  g_object_class_override_property (klass, property_id_begin++, "watchdog");
  g_object_class_override_property (klass, property_id_begin++, "poll-interval");
  return property_id_begin - 1;
}



/**
 * Watchdog:
 *
 * Abstract interface type for the D-Bus interface <link linkend="gdbus-interface-org-openbmc-Watchdog.top_of_page">org.openbmc.Watchdog</link>.
 */

/**
 * WatchdogIface:
 * @parent_iface: The parent interface.
 * @handle_poke: Handler for the #Watchdog::handle-poke signal.
 * @handle_start: Handler for the #Watchdog::handle-start signal.
 * @handle_stop: Handler for the #Watchdog::handle-stop signal.
 * @get_poll_interval: Getter for the #Watchdog:poll-interval property.
 * @get_watchdog: Getter for the #Watchdog:watchdog property.
 * @watchdog_error: Handler for the #Watchdog::watchdog-error signal.
 *
 * Virtual table for the D-Bus interface <link linkend="gdbus-interface-org-openbmc-Watchdog.top_of_page">org.openbmc.Watchdog</link>.
 */

typedef WatchdogIface WatchdogInterface;
G_DEFINE_INTERFACE (Watchdog, watchdog, G_TYPE_OBJECT);

static void
watchdog_default_init (WatchdogIface *iface)
{
  /* GObject signals for incoming D-Bus method calls: */
  /**
   * Watchdog::handle-start:
   * @object: A #Watchdog.
   * @invocation: A #GDBusMethodInvocation.
   *
   * Signal emitted when a remote caller is invoking the <link linkend="gdbus-method-org-openbmc-Watchdog.start">start()</link> D-Bus method.
   *
   * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call watchdog_complete_start() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned.
   *
   * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run.
   */
  g_signal_new ("handle-start",
    G_TYPE_FROM_INTERFACE (iface),
    G_SIGNAL_RUN_LAST,
    G_STRUCT_OFFSET (WatchdogIface, handle_start),
    g_signal_accumulator_true_handled,
    NULL,
    g_cclosure_marshal_generic,
    G_TYPE_BOOLEAN,
    1,
    G_TYPE_DBUS_METHOD_INVOCATION);

  /**
   * Watchdog::handle-poke:
   * @object: A #Watchdog.
   * @invocation: A #GDBusMethodInvocation.
   *
   * Signal emitted when a remote caller is invoking the <link linkend="gdbus-method-org-openbmc-Watchdog.poke">poke()</link> D-Bus method.
   *
   * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call watchdog_complete_poke() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned.
   *
   * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run.
   */
  g_signal_new ("handle-poke",
    G_TYPE_FROM_INTERFACE (iface),
    G_SIGNAL_RUN_LAST,
    G_STRUCT_OFFSET (WatchdogIface, handle_poke),
    g_signal_accumulator_true_handled,
    NULL,
    g_cclosure_marshal_generic,
    G_TYPE_BOOLEAN,
    1,
    G_TYPE_DBUS_METHOD_INVOCATION);

  /**
   * Watchdog::handle-stop:
   * @object: A #Watchdog.
   * @invocation: A #GDBusMethodInvocation.
   *
   * Signal emitted when a remote caller is invoking the <link linkend="gdbus-method-org-openbmc-Watchdog.stop">stop()</link> D-Bus method.
   *
   * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call watchdog_complete_stop() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned.
   *
   * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run.
   */
  g_signal_new ("handle-stop",
    G_TYPE_FROM_INTERFACE (iface),
    G_SIGNAL_RUN_LAST,
    G_STRUCT_OFFSET (WatchdogIface, handle_stop),
    g_signal_accumulator_true_handled,
    NULL,
    g_cclosure_marshal_generic,
    G_TYPE_BOOLEAN,
    1,
    G_TYPE_DBUS_METHOD_INVOCATION);

  /* GObject signals for received D-Bus signals: */
  /**
   * Watchdog::watchdog-error:
   * @object: A #Watchdog.
   *
   * On the client-side, this signal is emitted whenever the D-Bus signal <link linkend="gdbus-signal-org-openbmc-Watchdog.WatchdogError">"WatchdogError"</link> is received.
   *
   * On the service-side, this signal can be used with e.g. g_signal_emit_by_name() to make the object emit the D-Bus signal.
   */
  g_signal_new ("watchdog-error",
    G_TYPE_FROM_INTERFACE (iface),
    G_SIGNAL_RUN_LAST,
    G_STRUCT_OFFSET (WatchdogIface, watchdog_error),
    NULL,
    NULL,
    g_cclosure_marshal_generic,
    G_TYPE_NONE,
    0);

  /* GObject properties for D-Bus properties: */
  /**
   * Watchdog:watchdog:
   *
   * Represents the D-Bus property <link linkend="gdbus-property-org-openbmc-Watchdog.watchdog">"watchdog"</link>.
   *
   * Since the D-Bus property for this #GObject property is both readable and writable, it is meaningful to both read from it and write to it on both the service- and client-side.
   */
  g_object_interface_install_property (iface,
    g_param_spec_int ("watchdog", "watchdog", "watchdog", G_MININT32, G_MAXINT32, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * Watchdog:poll-interval:
   *
   * Represents the D-Bus property <link linkend="gdbus-property-org-openbmc-Watchdog.poll_interval">"poll_interval"</link>.
   *
   * Since the D-Bus property for this #GObject property is both readable and writable, it is meaningful to both read from it and write to it on both the service- and client-side.
   */
  g_object_interface_install_property (iface,
    g_param_spec_int ("poll-interval", "poll_interval", "poll_interval", G_MININT32, G_MAXINT32, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

/**
 * watchdog_get_watchdog: (skip)
 * @object: A #Watchdog.
 *
 * Gets the value of the <link linkend="gdbus-property-org-openbmc-Watchdog.watchdog">"watchdog"</link> D-Bus property.
 *
 * Since this D-Bus property is both readable and writable, it is meaningful to use this function on both the client- and service-side.
 *
 * Returns: The property value.
 */
gint 
watchdog_get_watchdog (Watchdog *object)
{
  return WATCHDOG_GET_IFACE (object)->get_watchdog (object);
}

/**
 * watchdog_set_watchdog: (skip)
 * @object: A #Watchdog.
 * @value: The value to set.
 *
 * Sets the <link linkend="gdbus-property-org-openbmc-Watchdog.watchdog">"watchdog"</link> D-Bus property to @value.
 *
 * Since this D-Bus property is both readable and writable, it is meaningful to use this function on both the client- and service-side.
 */
void
watchdog_set_watchdog (Watchdog *object, gint value)
{
  g_object_set (G_OBJECT (object), "watchdog", value, NULL);
}

/**
 * watchdog_get_poll_interval: (skip)
 * @object: A #Watchdog.
 *
 * Gets the value of the <link linkend="gdbus-property-org-openbmc-Watchdog.poll_interval">"poll_interval"</link> D-Bus property.
 *
 * Since this D-Bus property is both readable and writable, it is meaningful to use this function on both the client- and service-side.
 *
 * Returns: The property value.
 */
gint 
watchdog_get_poll_interval (Watchdog *object)
{
  return WATCHDOG_GET_IFACE (object)->get_poll_interval (object);
}

/**
 * watchdog_set_poll_interval: (skip)
 * @object: A #Watchdog.
 * @value: The value to set.
 *
 * Sets the <link linkend="gdbus-property-org-openbmc-Watchdog.poll_interval">"poll_interval"</link> D-Bus property to @value.
 *
 * Since this D-Bus property is both readable and writable, it is meaningful to use this function on both the client- and service-side.
 */
void
watchdog_set_poll_interval (Watchdog *object, gint value)
{
  g_object_set (G_OBJECT (object), "poll-interval", value, NULL);
}

/**
 * watchdog_emit_watchdog_error:
 * @object: A #Watchdog.
 *
 * Emits the <link linkend="gdbus-signal-org-openbmc-Watchdog.WatchdogError">"WatchdogError"</link> D-Bus signal.
 */
void
watchdog_emit_watchdog_error (
    Watchdog *object)
{
  g_signal_emit_by_name (object, "watchdog-error");
}

/**
 * watchdog_call_start:
 * @proxy: A #WatchdogProxy.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously invokes the <link linkend="gdbus-method-org-openbmc-Watchdog.start">start()</link> D-Bus method on @proxy.
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call watchdog_call_start_finish() to get the result of the operation.
 *
 * See watchdog_call_start_sync() for the synchronous, blocking version of this method.
 */
void
watchdog_call_start (
    Watchdog *proxy,
    GCancellable *cancellable,
    GAsyncReadyCallback callback,
    gpointer user_data)
{
  g_dbus_proxy_call (G_DBUS_PROXY (proxy),
    "start",
    g_variant_new ("()"),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    callback,
    user_data);
}

/**
 * watchdog_call_start_finish:
 * @proxy: A #WatchdogProxy.
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to watchdog_call_start().
 * @error: Return location for error or %NULL.
 *
 * Finishes an operation started with watchdog_call_start().
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
watchdog_call_start_finish (
    Watchdog *proxy,
    GAsyncResult *res,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "()");
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * watchdog_call_start_sync:
 * @proxy: A #WatchdogProxy.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL.
 *
 * Synchronously invokes the <link linkend="gdbus-method-org-openbmc-Watchdog.start">start()</link> D-Bus method on @proxy. The calling thread is blocked until a reply is received.
 *
 * See watchdog_call_start() for the asynchronous version of this method.
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
watchdog_call_start_sync (
    Watchdog *proxy,
    GCancellable *cancellable,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
    "start",
    g_variant_new ("()"),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "()");
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * watchdog_call_poke:
 * @proxy: A #WatchdogProxy.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously invokes the <link linkend="gdbus-method-org-openbmc-Watchdog.poke">poke()</link> D-Bus method on @proxy.
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call watchdog_call_poke_finish() to get the result of the operation.
 *
 * See watchdog_call_poke_sync() for the synchronous, blocking version of this method.
 */
void
watchdog_call_poke (
    Watchdog *proxy,
    GCancellable *cancellable,
    GAsyncReadyCallback callback,
    gpointer user_data)
{
  g_dbus_proxy_call (G_DBUS_PROXY (proxy),
    "poke",
    g_variant_new ("()"),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    callback,
    user_data);
}

/**
 * watchdog_call_poke_finish:
 * @proxy: A #WatchdogProxy.
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to watchdog_call_poke().
 * @error: Return location for error or %NULL.
 *
 * Finishes an operation started with watchdog_call_poke().
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
watchdog_call_poke_finish (
    Watchdog *proxy,
    GAsyncResult *res,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "()");
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * watchdog_call_poke_sync:
 * @proxy: A #WatchdogProxy.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL.
 *
 * Synchronously invokes the <link linkend="gdbus-method-org-openbmc-Watchdog.poke">poke()</link> D-Bus method on @proxy. The calling thread is blocked until a reply is received.
 *
 * See watchdog_call_poke() for the asynchronous version of this method.
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
watchdog_call_poke_sync (
    Watchdog *proxy,
    GCancellable *cancellable,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
    "poke",
    g_variant_new ("()"),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "()");
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * watchdog_call_stop:
 * @proxy: A #WatchdogProxy.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously invokes the <link linkend="gdbus-method-org-openbmc-Watchdog.stop">stop()</link> D-Bus method on @proxy.
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call watchdog_call_stop_finish() to get the result of the operation.
 *
 * See watchdog_call_stop_sync() for the synchronous, blocking version of this method.
 */
void
watchdog_call_stop (
    Watchdog *proxy,
    GCancellable *cancellable,
    GAsyncReadyCallback callback,
    gpointer user_data)
{
  g_dbus_proxy_call (G_DBUS_PROXY (proxy),
    "stop",
    g_variant_new ("()"),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    callback,
    user_data);
}

/**
 * watchdog_call_stop_finish:
 * @proxy: A #WatchdogProxy.
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to watchdog_call_stop().
 * @error: Return location for error or %NULL.
 *
 * Finishes an operation started with watchdog_call_stop().
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
watchdog_call_stop_finish (
    Watchdog *proxy,
    GAsyncResult *res,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "()");
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * watchdog_call_stop_sync:
 * @proxy: A #WatchdogProxy.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL.
 *
 * Synchronously invokes the <link linkend="gdbus-method-org-openbmc-Watchdog.stop">stop()</link> D-Bus method on @proxy. The calling thread is blocked until a reply is received.
 *
 * See watchdog_call_stop() for the asynchronous version of this method.
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
watchdog_call_stop_sync (
    Watchdog *proxy,
    GCancellable *cancellable,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
    "stop",
    g_variant_new ("()"),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "()");
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * watchdog_complete_start:
 * @object: A #Watchdog.
 * @invocation: (transfer full): A #GDBusMethodInvocation.
 *
 * Helper function used in service implementations to finish handling invocations of the <link linkend="gdbus-method-org-openbmc-Watchdog.start">start()</link> D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.
 *
 * This method will free @invocation, you cannot use it afterwards.
 */
void
watchdog_complete_start (
    Watchdog *object,
    GDBusMethodInvocation *invocation)
{
  g_dbus_method_invocation_return_value (invocation,
    g_variant_new ("()"));
}

/**
 * watchdog_complete_poke:
 * @object: A #Watchdog.
 * @invocation: (transfer full): A #GDBusMethodInvocation.
 *
 * Helper function used in service implementations to finish handling invocations of the <link linkend="gdbus-method-org-openbmc-Watchdog.poke">poke()</link> D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.
 *
 * This method will free @invocation, you cannot use it afterwards.
 */
void
watchdog_complete_poke (
    Watchdog *object,
    GDBusMethodInvocation *invocation)
{
  g_dbus_method_invocation_return_value (invocation,
    g_variant_new ("()"));
}

/**
 * watchdog_complete_stop:
 * @object: A #Watchdog.
 * @invocation: (transfer full): A #GDBusMethodInvocation.
 *
 * Helper function used in service implementations to finish handling invocations of the <link linkend="gdbus-method-org-openbmc-Watchdog.stop">stop()</link> D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.
 *
 * This method will free @invocation, you cannot use it afterwards.
 */
void
watchdog_complete_stop (
    Watchdog *object,
    GDBusMethodInvocation *invocation)
{
  g_dbus_method_invocation_return_value (invocation,
    g_variant_new ("()"));
}

/* ------------------------------------------------------------------------ */

/**
 * WatchdogProxy:
 *
 * The #WatchdogProxy structure contains only private data and should only be accessed using the provided API.
 */

/**
 * WatchdogProxyClass:
 * @parent_class: The parent class.
 *
 * Class structure for #WatchdogProxy.
 */

struct _WatchdogProxyPrivate
{
  GData *qdata;
};

static void watchdog_proxy_iface_init (WatchdogIface *iface);

#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
G_DEFINE_TYPE_WITH_CODE (WatchdogProxy, watchdog_proxy, G_TYPE_DBUS_PROXY,
                         G_ADD_PRIVATE (WatchdogProxy)
                         G_IMPLEMENT_INTERFACE (TYPE_WATCHDOG, watchdog_proxy_iface_init));

#else
G_DEFINE_TYPE_WITH_CODE (WatchdogProxy, watchdog_proxy, G_TYPE_DBUS_PROXY,
                         G_IMPLEMENT_INTERFACE (TYPE_WATCHDOG, watchdog_proxy_iface_init));

#endif
static void
watchdog_proxy_finalize (GObject *object)
{
  WatchdogProxy *proxy = WATCHDOG_PROXY (object);
  g_datalist_clear (&proxy->priv->qdata);
  G_OBJECT_CLASS (watchdog_proxy_parent_class)->finalize (object);
}

static void
watchdog_proxy_get_property (GObject      *object,
  guint         prop_id,
  GValue       *value,
  GParamSpec   *pspec G_GNUC_UNUSED)
{
  const _ExtendedGDBusPropertyInfo *info;
  GVariant *variant;
  g_assert (prop_id != 0 && prop_id - 1 < 2);
  info = _watchdog_property_info_pointers[prop_id - 1];
  variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (object), info->parent_struct.name);
  if (info->use_gvariant)
    {
      g_value_set_variant (value, variant);
    }
  else
    {
      if (variant != NULL)
        g_dbus_gvariant_to_gvalue (variant, value);
    }
  if (variant != NULL)
    g_variant_unref (variant);
}

static void
watchdog_proxy_set_property_cb (GDBusProxy *proxy,
  GAsyncResult *res,
  gpointer      user_data)
{
  const _ExtendedGDBusPropertyInfo *info = user_data;
  GError *error;
  GVariant *_ret;
  error = NULL;
  _ret = g_dbus_proxy_call_finish (proxy, res, &error);
  if (!_ret)
    {
      g_warning ("Error setting property '%s' on interface org.openbmc.Watchdog: %s (%s, %d)",
                 info->parent_struct.name, 
                 error->message, g_quark_to_string (error->domain), error->code);
      g_error_free (error);
    }
  else
    {
      g_variant_unref (_ret);
    }
}

static void
watchdog_proxy_set_property (GObject      *object,
  guint         prop_id,
  const GValue *value,
  GParamSpec   *pspec G_GNUC_UNUSED)
{
  const _ExtendedGDBusPropertyInfo *info;
  GVariant *variant;
  g_assert (prop_id != 0 && prop_id - 1 < 2);
  info = _watchdog_property_info_pointers[prop_id - 1];
  variant = g_dbus_gvalue_to_gvariant (value, G_VARIANT_TYPE (info->parent_struct.signature));
  g_dbus_proxy_call (G_DBUS_PROXY (object),
    "org.freedesktop.DBus.Properties.Set",
    g_variant_new ("(ssv)", "org.openbmc.Watchdog", info->parent_struct.name, variant),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    NULL, (GAsyncReadyCallback) watchdog_proxy_set_property_cb, (GDBusPropertyInfo *) &info->parent_struct);
  g_variant_unref (variant);
}

static void
watchdog_proxy_g_signal (GDBusProxy *proxy,
  const gchar *sender_name G_GNUC_UNUSED,
  const gchar *signal_name,
  GVariant *parameters)
{
  _ExtendedGDBusSignalInfo *info;
  GVariantIter iter;
  GVariant *child;
  GValue *paramv;
  guint num_params;
  guint n;
  guint signal_id;
  info = (_ExtendedGDBusSignalInfo *) g_dbus_interface_info_lookup_signal ((GDBusInterfaceInfo *) &_watchdog_interface_info.parent_struct, signal_name);
  if (info == NULL)
    return;
  num_params = g_variant_n_children (parameters);
  paramv = g_new0 (GValue, num_params + 1);
  g_value_init (&paramv[0], TYPE_WATCHDOG);
  g_value_set_object (&paramv[0], proxy);
  g_variant_iter_init (&iter, parameters);
  n = 1;
  while ((child = g_variant_iter_next_value (&iter)) != NULL)
    {
      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.args[n - 1];
      if (arg_info->use_gvariant)
        {
          g_value_init (&paramv[n], G_TYPE_VARIANT);
          g_value_set_variant (&paramv[n], child);
          n++;
        }
      else
        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);
      g_variant_unref (child);
    }
  signal_id = g_signal_lookup (info->signal_name, TYPE_WATCHDOG);
  g_signal_emitv (paramv, signal_id, 0, NULL);
  for (n = 0; n < num_params + 1; n++)
    g_value_unset (&paramv[n]);
  g_free (paramv);
}

static void
watchdog_proxy_g_properties_changed (GDBusProxy *_proxy,
  GVariant *changed_properties,
  const gchar *const *invalidated_properties)
{
  WatchdogProxy *proxy = WATCHDOG_PROXY (_proxy);
  guint n;
  const gchar *key;
  GVariantIter *iter;
  _ExtendedGDBusPropertyInfo *info;
  g_variant_get (changed_properties, "a{sv}", &iter);
  while (g_variant_iter_next (iter, "{&sv}", &key, NULL))
    {
      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_watchdog_interface_info.parent_struct, key);
      g_datalist_remove_data (&proxy->priv->qdata, key);
      if (info != NULL)
        g_object_notify (G_OBJECT (proxy), info->hyphen_name);
    }
  g_variant_iter_free (iter);
  for (n = 0; invalidated_properties[n] != NULL; n++)
    {
      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_watchdog_interface_info.parent_struct, invalidated_properties[n]);
      g_datalist_remove_data (&proxy->priv->qdata, invalidated_properties[n]);
      if (info != NULL)
        g_object_notify (G_OBJECT (proxy), info->hyphen_name);
    }
}

static gint 
watchdog_proxy_get_watchdog (Watchdog *object)
{
  WatchdogProxy *proxy = WATCHDOG_PROXY (object);
  GVariant *variant;
  gint value = 0;
  variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "watchdog");
  if (variant != NULL)
    {
      value = g_variant_get_int32 (variant);
      g_variant_unref (variant);
    }
  return value;
}

static gint 
watchdog_proxy_get_poll_interval (Watchdog *object)
{
  WatchdogProxy *proxy = WATCHDOG_PROXY (object);
  GVariant *variant;
  gint value = 0;
  variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "poll_interval");
  if (variant != NULL)
    {
      value = g_variant_get_int32 (variant);
      g_variant_unref (variant);
    }
  return value;
}

static void
watchdog_proxy_init (WatchdogProxy *proxy)
{
#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
  proxy->priv = watchdog_proxy_get_instance_private (proxy);
#else
  proxy->priv = G_TYPE_INSTANCE_GET_PRIVATE (proxy, TYPE_WATCHDOG_PROXY, WatchdogProxyPrivate);
#endif

  g_dbus_proxy_set_interface_info (G_DBUS_PROXY (proxy), watchdog_interface_info ());
}

static void
watchdog_proxy_class_init (WatchdogProxyClass *klass)
{
  GObjectClass *gobject_class;
  GDBusProxyClass *proxy_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gobject_class->finalize     = watchdog_proxy_finalize;
  gobject_class->get_property = watchdog_proxy_get_property;
  gobject_class->set_property = watchdog_proxy_set_property;

  proxy_class = G_DBUS_PROXY_CLASS (klass);
  proxy_class->g_signal = watchdog_proxy_g_signal;
  proxy_class->g_properties_changed = watchdog_proxy_g_properties_changed;

  watchdog_override_properties (gobject_class, 1);

#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38
  g_type_class_add_private (klass, sizeof (WatchdogProxyPrivate));
#endif
}

static void
watchdog_proxy_iface_init (WatchdogIface *iface)
{
  iface->get_watchdog = watchdog_proxy_get_watchdog;
  iface->get_poll_interval = watchdog_proxy_get_poll_interval;
}

/**
 * watchdog_proxy_new:
 * @connection: A #GDBusConnection.
 * @flags: Flags from the #GDBusProxyFlags enumeration.
 * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection.
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously creates a proxy for the D-Bus interface <link linkend="gdbus-interface-org-openbmc-Watchdog.top_of_page">org.openbmc.Watchdog</link>. See g_dbus_proxy_new() for more details.
 *
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call watchdog_proxy_new_finish() to get the result of the operation.
 *
 * See watchdog_proxy_new_sync() for the synchronous, blocking version of this constructor.
 */
void
watchdog_proxy_new (
    GDBusConnection     *connection,
    GDBusProxyFlags      flags,
    const gchar         *name,
    const gchar         *object_path,
    GCancellable        *cancellable,
    GAsyncReadyCallback  callback,
    gpointer             user_data)
{
  g_async_initable_new_async (TYPE_WATCHDOG_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "org.openbmc.Watchdog", NULL);
}

/**
 * watchdog_proxy_new_finish:
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to watchdog_proxy_new().
 * @error: Return location for error or %NULL
 *
 * Finishes an operation started with watchdog_proxy_new().
 *
 * Returns: (transfer full) (type WatchdogProxy): The constructed proxy object or %NULL if @error is set.
 */
Watchdog *
watchdog_proxy_new_finish (
    GAsyncResult        *res,
    GError             **error)
{
  GObject *ret;
  GObject *source_object;
  source_object = g_async_result_get_source_object (res);
  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);
  g_object_unref (source_object);
  if (ret != NULL)
    return WATCHDOG (ret);
  else
    return NULL;
}

/**
 * watchdog_proxy_new_sync:
 * @connection: A #GDBusConnection.
 * @flags: Flags from the #GDBusProxyFlags enumeration.
 * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection.
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL
 *
 * Synchronously creates a proxy for the D-Bus interface <link linkend="gdbus-interface-org-openbmc-Watchdog.top_of_page">org.openbmc.Watchdog</link>. See g_dbus_proxy_new_sync() for more details.
 *
 * The calling thread is blocked until a reply is received.
 *
 * See watchdog_proxy_new() for the asynchronous version of this constructor.
 *
 * Returns: (transfer full) (type WatchdogProxy): The constructed proxy object or %NULL if @error is set.
 */
Watchdog *
watchdog_proxy_new_sync (
    GDBusConnection     *connection,
    GDBusProxyFlags      flags,
    const gchar         *name,
    const gchar         *object_path,
    GCancellable        *cancellable,
    GError             **error)
{
  GInitable *ret;
  ret = g_initable_new (TYPE_WATCHDOG_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "org.openbmc.Watchdog", NULL);
  if (ret != NULL)
    return WATCHDOG (ret);
  else
    return NULL;
}


/**
 * watchdog_proxy_new_for_bus:
 * @bus_type: A #GBusType.
 * @flags: Flags from the #GDBusProxyFlags enumeration.
 * @name: A bus name (well-known or unique).
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
 * @user_data: User data to pass to @callback.
 *
 * Like watchdog_proxy_new() but takes a #GBusType instead of a #GDBusConnection.
 *
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call watchdog_proxy_new_for_bus_finish() to get the result of the operation.
 *
 * See watchdog_proxy_new_for_bus_sync() for the synchronous, blocking version of this constructor.
 */
void
watchdog_proxy_new_for_bus (
    GBusType             bus_type,
    GDBusProxyFlags      flags,
    const gchar         *name,
    const gchar         *object_path,
    GCancellable        *cancellable,
    GAsyncReadyCallback  callback,
    gpointer             user_data)
{
  g_async_initable_new_async (TYPE_WATCHDOG_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "org.openbmc.Watchdog", NULL);
}

/**
 * watchdog_proxy_new_for_bus_finish:
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to watchdog_proxy_new_for_bus().
 * @error: Return location for error or %NULL
 *
 * Finishes an operation started with watchdog_proxy_new_for_bus().
 *
 * Returns: (transfer full) (type WatchdogProxy): The constructed proxy object or %NULL if @error is set.
 */
Watchdog *
watchdog_proxy_new_for_bus_finish (
    GAsyncResult        *res,
    GError             **error)
{
  GObject *ret;
  GObject *source_object;
  source_object = g_async_result_get_source_object (res);
  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);
  g_object_unref (source_object);
  if (ret != NULL)
    return WATCHDOG (ret);
  else
    return NULL;
}

/**
 * watchdog_proxy_new_for_bus_sync:
 * @bus_type: A #GBusType.
 * @flags: Flags from the #GDBusProxyFlags enumeration.
 * @name: A bus name (well-known or unique).
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL
 *
 * Like watchdog_proxy_new_sync() but takes a #GBusType instead of a #GDBusConnection.
 *
 * The calling thread is blocked until a reply is received.
 *
 * See watchdog_proxy_new_for_bus() for the asynchronous version of this constructor.
 *
 * Returns: (transfer full) (type WatchdogProxy): The constructed proxy object or %NULL if @error is set.
 */
Watchdog *
watchdog_proxy_new_for_bus_sync (
    GBusType             bus_type,
    GDBusProxyFlags      flags,
    const gchar         *name,
    const gchar         *object_path,
    GCancellable        *cancellable,
    GError             **error)
{
  GInitable *ret;
  ret = g_initable_new (TYPE_WATCHDOG_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "org.openbmc.Watchdog", NULL);
  if (ret != NULL)
    return WATCHDOG (ret);
  else
    return NULL;
}


/* ------------------------------------------------------------------------ */

/**
 * WatchdogSkeleton:
 *
 * The #WatchdogSkeleton structure contains only private data and should only be accessed using the provided API.
 */

/**
 * WatchdogSkeletonClass:
 * @parent_class: The parent class.
 *
 * Class structure for #WatchdogSkeleton.
 */

struct _WatchdogSkeletonPrivate
{
  GValue *properties;
  GList *changed_properties;
  GSource *changed_properties_idle_source;
  GMainContext *context;
  GMutex lock;
};

static void
_watchdog_skeleton_handle_method_call (
  GDBusConnection *connection G_GNUC_UNUSED,
  const gchar *sender G_GNUC_UNUSED,
  const gchar *object_path G_GNUC_UNUSED,
  const gchar *interface_name,
  const gchar *method_name,
  GVariant *parameters,
  GDBusMethodInvocation *invocation,
  gpointer user_data)
{
  WatchdogSkeleton *skeleton = WATCHDOG_SKELETON (user_data);
  _ExtendedGDBusMethodInfo *info;
  GVariantIter iter;
  GVariant *child;
  GValue *paramv;
  guint num_params;
  guint num_extra;
  guint n;
  guint signal_id;
  GValue return_value = G_VALUE_INIT;
  info = (_ExtendedGDBusMethodInfo *) g_dbus_method_invocation_get_method_info (invocation);
  g_assert (info != NULL);
  num_params = g_variant_n_children (parameters);
  num_extra = info->pass_fdlist ? 3 : 2;  paramv = g_new0 (GValue, num_params + num_extra);
  n = 0;
  g_value_init (&paramv[n], TYPE_WATCHDOG);
  g_value_set_object (&paramv[n++], skeleton);
  g_value_init (&paramv[n], G_TYPE_DBUS_METHOD_INVOCATION);
  g_value_set_object (&paramv[n++], invocation);
  if (info->pass_fdlist)
    {
#ifdef G_OS_UNIX
      g_value_init (&paramv[n], G_TYPE_UNIX_FD_LIST);
      g_value_set_object (&paramv[n++], g_dbus_message_get_unix_fd_list (g_dbus_method_invocation_get_message (invocation)));
#else
      g_assert_not_reached ();
#endif
    }
  g_variant_iter_init (&iter, parameters);
  while ((child = g_variant_iter_next_value (&iter)) != NULL)
    {
      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.in_args[n - num_extra];
      if (arg_info->use_gvariant)
        {
          g_value_init (&paramv[n], G_TYPE_VARIANT);
          g_value_set_variant (&paramv[n], child);
          n++;
        }
      else
        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);
      g_variant_unref (child);
    }
  signal_id = g_signal_lookup (info->signal_name, TYPE_WATCHDOG);
  g_value_init (&return_value, G_TYPE_BOOLEAN);
  g_signal_emitv (paramv, signal_id, 0, &return_value);
  if (!g_value_get_boolean (&return_value))
    g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method %s is not implemented on interface %s", method_name, interface_name);
  g_value_unset (&return_value);
  for (n = 0; n < num_params + num_extra; n++)
    g_value_unset (&paramv[n]);
  g_free (paramv);
}

static GVariant *
_watchdog_skeleton_handle_get_property (
  GDBusConnection *connection G_GNUC_UNUSED,
  const gchar *sender G_GNUC_UNUSED,
  const gchar *object_path G_GNUC_UNUSED,
  const gchar *interface_name G_GNUC_UNUSED,
  const gchar *property_name,
  GError **error,
  gpointer user_data)
{
  WatchdogSkeleton *skeleton = WATCHDOG_SKELETON (user_data);
  GValue value = G_VALUE_INIT;
  GParamSpec *pspec;
  _ExtendedGDBusPropertyInfo *info;
  GVariant *ret;
  ret = NULL;
  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_watchdog_interface_info.parent_struct, property_name);
  g_assert (info != NULL);
  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);
  if (pspec == NULL)
    {
      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name);
    }
  else
    {
      g_value_init (&value, pspec->value_type);
      g_object_get_property (G_OBJECT (skeleton), info->hyphen_name, &value);
      ret = g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (info->parent_struct.signature));
      g_value_unset (&value);
    }
  return ret;
}

static gboolean
_watchdog_skeleton_handle_set_property (
  GDBusConnection *connection G_GNUC_UNUSED,
  const gchar *sender G_GNUC_UNUSED,
  const gchar *object_path G_GNUC_UNUSED,
  const gchar *interface_name G_GNUC_UNUSED,
  const gchar *property_name,
  GVariant *variant,
  GError **error,
  gpointer user_data)
{
  WatchdogSkeleton *skeleton = WATCHDOG_SKELETON (user_data);
  GValue value = G_VALUE_INIT;
  GParamSpec *pspec;
  _ExtendedGDBusPropertyInfo *info;
  gboolean ret;
  ret = FALSE;
  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_watchdog_interface_info.parent_struct, property_name);
  g_assert (info != NULL);
  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);
  if (pspec == NULL)
    {
      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name);
    }
  else
    {
      if (info->use_gvariant)
        g_value_set_variant (&value, variant);
      else
        g_dbus_gvariant_to_gvalue (variant, &value);
      g_object_set_property (G_OBJECT (skeleton), info->hyphen_name, &value);
      g_value_unset (&value);
      ret = TRUE;
    }
  return ret;
}

static const GDBusInterfaceVTable _watchdog_skeleton_vtable =
{
  _watchdog_skeleton_handle_method_call,
  _watchdog_skeleton_handle_get_property,
  _watchdog_skeleton_handle_set_property,
  {NULL}
};

static GDBusInterfaceInfo *
watchdog_skeleton_dbus_interface_get_info (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED)
{
  return watchdog_interface_info ();
}

static GDBusInterfaceVTable *
watchdog_skeleton_dbus_interface_get_vtable (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED)
{
  return (GDBusInterfaceVTable *) &_watchdog_skeleton_vtable;
}

static GVariant *
watchdog_skeleton_dbus_interface_get_properties (GDBusInterfaceSkeleton *_skeleton)
{
  WatchdogSkeleton *skeleton = WATCHDOG_SKELETON (_skeleton);

  GVariantBuilder builder;
  guint n;
  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
  if (_watchdog_interface_info.parent_struct.properties == NULL)
    goto out;
  for (n = 0; _watchdog_interface_info.parent_struct.properties[n] != NULL; n++)
    {
      GDBusPropertyInfo *info = _watchdog_interface_info.parent_struct.properties[n];
      if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)
        {
          GVariant *value;
          value = _watchdog_skeleton_handle_get_property (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)), NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "org.openbmc.Watchdog", info->name, NULL, skeleton);
          if (value != NULL)
            {
              g_variant_take_ref (value);
              g_variant_builder_add (&builder, "{sv}", info->name, value);
              g_variant_unref (value);
            }
        }
    }
out:
  return g_variant_builder_end (&builder);
}

static gboolean _watchdog_emit_changed (gpointer user_data);

static void
watchdog_skeleton_dbus_interface_flush (GDBusInterfaceSkeleton *_skeleton)
{
  WatchdogSkeleton *skeleton = WATCHDOG_SKELETON (_skeleton);
  gboolean emit_changed = FALSE;

  g_mutex_lock (&skeleton->priv->lock);
  if (skeleton->priv->changed_properties_idle_source != NULL)
    {
      g_source_destroy (skeleton->priv->changed_properties_idle_source);
      skeleton->priv->changed_properties_idle_source = NULL;
      emit_changed = TRUE;
    }
  g_mutex_unlock (&skeleton->priv->lock);

  if (emit_changed)
    _watchdog_emit_changed (skeleton);
}

static void
_watchdog_on_signal_watchdog_error (
    Watchdog *object)
{
  WatchdogSkeleton *skeleton = WATCHDOG_SKELETON (object);

  GList      *connections, *l;
  GVariant   *signal_variant;
  connections = g_dbus_interface_skeleton_get_connections (G_DBUS_INTERFACE_SKELETON (skeleton));

  signal_variant = g_variant_ref_sink (g_variant_new ("()"));
  for (l = connections; l != NULL; l = l->next)
    {
      GDBusConnection *connection = l->data;
      g_dbus_connection_emit_signal (connection,
        NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "org.openbmc.Watchdog", "WatchdogError",
        signal_variant, NULL);
    }
  g_variant_unref (signal_variant);
  g_list_free_full (connections, g_object_unref);
}

static void watchdog_skeleton_iface_init (WatchdogIface *iface);
#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
G_DEFINE_TYPE_WITH_CODE (WatchdogSkeleton, watchdog_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,
                         G_ADD_PRIVATE (WatchdogSkeleton)
                         G_IMPLEMENT_INTERFACE (TYPE_WATCHDOG, watchdog_skeleton_iface_init));

#else
G_DEFINE_TYPE_WITH_CODE (WatchdogSkeleton, watchdog_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,
                         G_IMPLEMENT_INTERFACE (TYPE_WATCHDOG, watchdog_skeleton_iface_init));

#endif
static void
watchdog_skeleton_finalize (GObject *object)
{
  WatchdogSkeleton *skeleton = WATCHDOG_SKELETON (object);
  guint n;
  for (n = 0; n < 2; n++)
    g_value_unset (&skeleton->priv->properties[n]);
  g_free (skeleton->priv->properties);
  g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);
  if (skeleton->priv->changed_properties_idle_source != NULL)
    g_source_destroy (skeleton->priv->changed_properties_idle_source);
  g_main_context_unref (skeleton->priv->context);
  g_mutex_clear (&skeleton->priv->lock);
  G_OBJECT_CLASS (watchdog_skeleton_parent_class)->finalize (object);
}

static void
watchdog_skeleton_get_property (GObject      *object,
  guint         prop_id,
  GValue       *value,
  GParamSpec   *pspec G_GNUC_UNUSED)
{
  WatchdogSkeleton *skeleton = WATCHDOG_SKELETON (object);
  g_assert (prop_id != 0 && prop_id - 1 < 2);
  g_mutex_lock (&skeleton->priv->lock);
  g_value_copy (&skeleton->priv->properties[prop_id - 1], value);
  g_mutex_unlock (&skeleton->priv->lock);
}

static gboolean
_watchdog_emit_changed (gpointer user_data)
{
  WatchdogSkeleton *skeleton = WATCHDOG_SKELETON (user_data);
  GList *l;
  GVariantBuilder builder;
  GVariantBuilder invalidated_builder;
  guint num_changes;

  g_mutex_lock (&skeleton->priv->lock);
  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
  g_variant_builder_init (&invalidated_builder, G_VARIANT_TYPE ("as"));
  for (l = skeleton->priv->changed_properties, num_changes = 0; l != NULL; l = l->next)
    {
      ChangedProperty *cp = l->data;
      GVariant *variant;
      const GValue *cur_value;

      cur_value = &skeleton->priv->properties[cp->prop_id - 1];
      if (!_g_value_equal (cur_value, &cp->orig_value))
        {
          variant = g_dbus_gvalue_to_gvariant (cur_value, G_VARIANT_TYPE (cp->info->parent_struct.signature));
          g_variant_builder_add (&builder, "{sv}", cp->info->parent_struct.name, variant);
          g_variant_unref (variant);
          num_changes++;
        }
    }
  if (num_changes > 0)
    {
      GList *connections, *ll;
      GVariant *signal_variant;
      signal_variant = g_variant_ref_sink (g_variant_new ("(sa{sv}as)", "org.openbmc.Watchdog",
                                           &builder, &invalidated_builder));
      connections = g_dbus_interface_skeleton_get_connections (G_DBUS_INTERFACE_SKELETON (skeleton));
      for (ll = connections; ll != NULL; ll = ll->next)
        {
          GDBusConnection *connection = ll->data;

          g_dbus_connection_emit_signal (connection,
                                         NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)),
                                         "org.freedesktop.DBus.Properties",
                                         "PropertiesChanged",
                                         signal_variant,
                                         NULL);
        }
      g_variant_unref (signal_variant);
      g_list_free_full (connections, g_object_unref);
    }
  else
    {
      g_variant_builder_clear (&builder);
      g_variant_builder_clear (&invalidated_builder);
    }
  g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);
  skeleton->priv->changed_properties = NULL;
  skeleton->priv->changed_properties_idle_source = NULL;
  g_mutex_unlock (&skeleton->priv->lock);
  return FALSE;
}

static void
_watchdog_schedule_emit_changed (WatchdogSkeleton *skeleton, const _ExtendedGDBusPropertyInfo *info, guint prop_id, const GValue *orig_value)
{
  ChangedProperty *cp;
  GList *l;
  cp = NULL;
  for (l = skeleton->priv->changed_properties; l != NULL; l = l->next)
    {
      ChangedProperty *i_cp = l->data;
      if (i_cp->info == info)
        {
          cp = i_cp;
          break;
        }
    }
  if (cp == NULL)
    {
      cp = g_new0 (ChangedProperty, 1);
      cp->prop_id = prop_id;
      cp->info = info;
      skeleton->priv->changed_properties = g_list_prepend (skeleton->priv->changed_properties, cp);
      g_value_init (&cp->orig_value, G_VALUE_TYPE (orig_value));
      g_value_copy (orig_value, &cp->orig_value);
    }
}

static void
watchdog_skeleton_notify (GObject      *object,
  GParamSpec *pspec G_GNUC_UNUSED)
{
  WatchdogSkeleton *skeleton = WATCHDOG_SKELETON (object);
  g_mutex_lock (&skeleton->priv->lock);
  if (skeleton->priv->changed_properties != NULL &&
      skeleton->priv->changed_properties_idle_source == NULL)
    {
      skeleton->priv->changed_properties_idle_source = g_idle_source_new ();
      g_source_set_priority (skeleton->priv->changed_properties_idle_source, G_PRIORITY_DEFAULT);
      g_source_set_callback (skeleton->priv->changed_properties_idle_source, _watchdog_emit_changed, g_object_ref (skeleton), (GDestroyNotify) g_object_unref);
      g_source_attach (skeleton->priv->changed_properties_idle_source, skeleton->priv->context);
      g_source_unref (skeleton->priv->changed_properties_idle_source);
    }
  g_mutex_unlock (&skeleton->priv->lock);
}

static void
watchdog_skeleton_set_property (GObject      *object,
  guint         prop_id,
  const GValue *value,
  GParamSpec   *pspec)
{
  WatchdogSkeleton *skeleton = WATCHDOG_SKELETON (object);
  g_assert (prop_id != 0 && prop_id - 1 < 2);
  g_mutex_lock (&skeleton->priv->lock);
  g_object_freeze_notify (object);
  if (!_g_value_equal (value, &skeleton->priv->properties[prop_id - 1]))
    {
      if (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)) != NULL)
        _watchdog_schedule_emit_changed (skeleton, _watchdog_property_info_pointers[prop_id - 1], prop_id, &skeleton->priv->properties[prop_id - 1]);
      g_value_copy (value, &skeleton->priv->properties[prop_id - 1]);
      g_object_notify_by_pspec (object, pspec);
    }
  g_mutex_unlock (&skeleton->priv->lock);
  g_object_thaw_notify (object);
}

static void
watchdog_skeleton_init (WatchdogSkeleton *skeleton)
{
#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
  skeleton->priv = watchdog_skeleton_get_instance_private (skeleton);
#else
  skeleton->priv = G_TYPE_INSTANCE_GET_PRIVATE (skeleton, TYPE_WATCHDOG_SKELETON, WatchdogSkeletonPrivate);
#endif

  g_mutex_init (&skeleton->priv->lock);
  skeleton->priv->context = g_main_context_ref_thread_default ();
  skeleton->priv->properties = g_new0 (GValue, 2);
  g_value_init (&skeleton->priv->properties[0], G_TYPE_INT);
  g_value_init (&skeleton->priv->properties[1], G_TYPE_INT);
}

static gint 
watchdog_skeleton_get_watchdog (Watchdog *object)
{
  WatchdogSkeleton *skeleton = WATCHDOG_SKELETON (object);
  gint value;
  g_mutex_lock (&skeleton->priv->lock);
  value = g_value_get_int (&(skeleton->priv->properties[0]));
  g_mutex_unlock (&skeleton->priv->lock);
  return value;
}

static gint 
watchdog_skeleton_get_poll_interval (Watchdog *object)
{
  WatchdogSkeleton *skeleton = WATCHDOG_SKELETON (object);
  gint value;
  g_mutex_lock (&skeleton->priv->lock);
  value = g_value_get_int (&(skeleton->priv->properties[1]));
  g_mutex_unlock (&skeleton->priv->lock);
  return value;
}

static void
watchdog_skeleton_class_init (WatchdogSkeletonClass *klass)
{
  GObjectClass *gobject_class;
  GDBusInterfaceSkeletonClass *skeleton_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gobject_class->finalize = watchdog_skeleton_finalize;
  gobject_class->get_property = watchdog_skeleton_get_property;
  gobject_class->set_property = watchdog_skeleton_set_property;
  gobject_class->notify       = watchdog_skeleton_notify;


  watchdog_override_properties (gobject_class, 1);

  skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass);
  skeleton_class->get_info = watchdog_skeleton_dbus_interface_get_info;
  skeleton_class->get_properties = watchdog_skeleton_dbus_interface_get_properties;
  skeleton_class->flush = watchdog_skeleton_dbus_interface_flush;
  skeleton_class->get_vtable = watchdog_skeleton_dbus_interface_get_vtable;

#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38
  g_type_class_add_private (klass, sizeof (WatchdogSkeletonPrivate));
#endif
}

static void
watchdog_skeleton_iface_init (WatchdogIface *iface)
{
  iface->watchdog_error = _watchdog_on_signal_watchdog_error;
  iface->get_watchdog = watchdog_skeleton_get_watchdog;
  iface->get_poll_interval = watchdog_skeleton_get_poll_interval;
}

/**
 * watchdog_skeleton_new:
 *
 * Creates a skeleton object for the D-Bus interface <link linkend="gdbus-interface-org-openbmc-Watchdog.top_of_page">org.openbmc.Watchdog</link>.
 *
 * Returns: (transfer full) (type WatchdogSkeleton): The skeleton object.
 */
Watchdog *
watchdog_skeleton_new (void)
{
  return WATCHDOG (g_object_new (TYPE_WATCHDOG_SKELETON, NULL));
}

/* ------------------------------------------------------------------------
 * Code for Object, ObjectProxy and ObjectSkeleton
 * ------------------------------------------------------------------------
 */

/**
 * SECTION:Object
 * @title: Object
 * @short_description: Specialized GDBusObject types
 *
 * This section contains the #Object, #ObjectProxy, and #ObjectSkeleton types which make it easier to work with objects implementing generated types for D-Bus interfaces.
 */

/**
 * Object:
 *
 * The #Object type is a specialized container of interfaces.
 */

/**
 * ObjectIface:
 * @parent_iface: The parent interface.
 *
 * Virtual table for the #Object interface.
 */

typedef ObjectIface ObjectInterface;
G_DEFINE_INTERFACE_WITH_CODE (Object, object, G_TYPE_OBJECT, g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_DBUS_OBJECT));

static void
object_default_init (ObjectIface *iface)
{
  /**
   * Object:watchdog:
   *
   * The #Watchdog instance corresponding to the D-Bus interface <link linkend="gdbus-interface-org-openbmc-Watchdog.top_of_page">org.openbmc.Watchdog</link>, if any.
   *
   * Connect to the #GObject::notify signal to get informed of property changes.
   */
  g_object_interface_install_property (iface, g_param_spec_object ("watchdog", "watchdog", "watchdog", TYPE_WATCHDOG, G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS));

}

/**
 * object_get_watchdog:
 * @object: A #Object.
 *
 * Gets the #Watchdog instance for the D-Bus interface <link linkend="gdbus-interface-org-openbmc-Watchdog.top_of_page">org.openbmc.Watchdog</link> on @object, if any.
 *
 * Returns: (transfer full): A #Watchdog that must be freed with g_object_unref() or %NULL if @object does not implement the interface.
 */
Watchdog *object_get_watchdog (Object *object)
{
  GDBusInterface *ret;
  ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "org.openbmc.Watchdog");
  if (ret == NULL)
    return NULL;
  return WATCHDOG (ret);
}


/**
 * object_peek_watchdog: (skip)
 * @object: A #Object.
 *
 * Like object_get_watchdog() but doesn't increase the reference count on the returned object.
 *
 * <warning>It is not safe to use the returned object if you are on another thread than the one where the #GDBusObjectManagerClient or #GDBusObjectManagerServer for @object is running.</warning>
 *
 * Returns: (transfer none): A #Watchdog or %NULL if @object does not implement the interface. Do not free the returned object, it is owned by @object.
 */
Watchdog *object_peek_watchdog (Object *object)
{
  GDBusInterface *ret;
  ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "org.openbmc.Watchdog");
  if (ret == NULL)
    return NULL;
  g_object_unref (ret);
  return WATCHDOG (ret);
}


static void
object_notify (GDBusObject *object, GDBusInterface *interface)
{
  _ExtendedGDBusInterfaceInfo *info = (_ExtendedGDBusInterfaceInfo *) g_dbus_interface_get_info (interface);
  /* info can be NULL if the other end is using a D-Bus interface we don't know
   * anything about, for example old generated code in this process talking to
   * newer generated code in the other process. */
  if (info != NULL)
    g_object_notify (G_OBJECT (object), info->hyphen_name);
}

/**
 * ObjectProxy:
 *
 * The #ObjectProxy structure contains only private data and should only be accessed using the provided API.
 */

/**
 * ObjectProxyClass:
 * @parent_class: The parent class.
 *
 * Class structure for #ObjectProxy.
 */

static void
object_proxy__object_iface_init (ObjectIface *iface G_GNUC_UNUSED)
{
}

static void
object_proxy__g_dbus_object_iface_init (GDBusObjectIface *iface)
{
  iface->interface_added = object_notify;
  iface->interface_removed = object_notify;
}


G_DEFINE_TYPE_WITH_CODE (ObjectProxy, object_proxy, G_TYPE_DBUS_OBJECT_PROXY,
                         G_IMPLEMENT_INTERFACE (TYPE_OBJECT, object_proxy__object_iface_init)
                         G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, object_proxy__g_dbus_object_iface_init));

static void
object_proxy_init (ObjectProxy *object G_GNUC_UNUSED)
{
}

static void
object_proxy_set_property (GObject      *gobject,
  guint         prop_id,
  const GValue *value G_GNUC_UNUSED,
  GParamSpec   *pspec)
{
  G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
}

static void
object_proxy_get_property (GObject      *gobject,
  guint         prop_id,
  GValue       *value,
  GParamSpec   *pspec)
{
  ObjectProxy *object = OBJECT_PROXY (gobject);
  GDBusInterface *interface;

  switch (prop_id)
    {
    case 1:
      interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "org.openbmc.Watchdog");
      g_value_take_object (value, interface);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
      break;
  }
}

static void
object_proxy_class_init (ObjectProxyClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->set_property = object_proxy_set_property;
  gobject_class->get_property = object_proxy_get_property;

  g_object_class_override_property (gobject_class, 1, "watchdog");
}

/**
 * object_proxy_new:
 * @connection: A #GDBusConnection.
 * @object_path: An object path.
 *
 * Creates a new proxy object.
 *
 * Returns: (transfer full): The proxy object.
 */
ObjectProxy *
object_proxy_new (GDBusConnection *connection,
  const gchar *object_path)
{
  g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
  g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
  return OBJECT_PROXY (g_object_new (TYPE_OBJECT_PROXY, "g-connection", connection, "g-object-path", object_path, NULL));
}

/**
 * ObjectSkeleton:
 *
 * The #ObjectSkeleton structure contains only private data and should only be accessed using the provided API.
 */

/**
 * ObjectSkeletonClass:
 * @parent_class: The parent class.
 *
 * Class structure for #ObjectSkeleton.
 */

static void
object_skeleton__object_iface_init (ObjectIface *iface G_GNUC_UNUSED)
{
}


static void
object_skeleton__g_dbus_object_iface_init (GDBusObjectIface *iface)
{
  iface->interface_added = object_notify;
  iface->interface_removed = object_notify;
}

G_DEFINE_TYPE_WITH_CODE (ObjectSkeleton, object_skeleton, G_TYPE_DBUS_OBJECT_SKELETON,
                         G_IMPLEMENT_INTERFACE (TYPE_OBJECT, object_skeleton__object_iface_init)
                         G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, object_skeleton__g_dbus_object_iface_init));

static void
object_skeleton_init (ObjectSkeleton *object G_GNUC_UNUSED)
{
}

static void
object_skeleton_set_property (GObject      *gobject,
  guint         prop_id,
  const GValue *value,
  GParamSpec   *pspec)
{
  ObjectSkeleton *object = OBJECT_SKELETON (gobject);
  GDBusInterfaceSkeleton *interface;

  switch (prop_id)
    {
    case 1:
      interface = g_value_get_object (value);
      if (interface != NULL)
        {
          g_warn_if_fail (IS_WATCHDOG (interface));
          g_dbus_object_skeleton_add_interface (G_DBUS_OBJECT_SKELETON (object), interface);
        }
      else
        {
          g_dbus_object_skeleton_remove_interface_by_name (G_DBUS_OBJECT_SKELETON (object), "org.openbmc.Watchdog");
        }
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
      break;
  }
}

static void
object_skeleton_get_property (GObject      *gobject,
  guint         prop_id,
  GValue       *value,
  GParamSpec   *pspec)
{
  ObjectSkeleton *object = OBJECT_SKELETON (gobject);
  GDBusInterface *interface;

  switch (prop_id)
    {
    case 1:
      interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "org.openbmc.Watchdog");
      g_value_take_object (value, interface);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
      break;
  }
}

static void
object_skeleton_class_init (ObjectSkeletonClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->set_property = object_skeleton_set_property;
  gobject_class->get_property = object_skeleton_get_property;

  g_object_class_override_property (gobject_class, 1, "watchdog");
}

/**
 * object_skeleton_new:
 * @object_path: An object path.
 *
 * Creates a new skeleton object.
 *
 * Returns: (transfer full): The skeleton object.
 */
ObjectSkeleton *
object_skeleton_new (const gchar *object_path)
{
  g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
  return OBJECT_SKELETON (g_object_new (TYPE_OBJECT_SKELETON, "g-object-path", object_path, NULL));
}

/**
 * object_skeleton_set_watchdog:
 * @object: A #ObjectSkeleton.
 * @interface_: (allow-none): A #Watchdog or %NULL to clear the interface.
 *
 * Sets the #Watchdog instance for the D-Bus interface <link linkend="gdbus-interface-org-openbmc-Watchdog.top_of_page">org.openbmc.Watchdog</link> on @object.
 */
void object_skeleton_set_watchdog (ObjectSkeleton *object, Watchdog *interface_)
{
  g_object_set (G_OBJECT (object), "watchdog", interface_, NULL);
}


/* ------------------------------------------------------------------------
 * Code for ObjectManager client
 * ------------------------------------------------------------------------
 */

/**
 * SECTION:ObjectManagerClient
 * @title: ObjectManagerClient
 * @short_description: Generated GDBusObjectManagerClient type
 *
 * This section contains a #GDBusObjectManagerClient that uses object_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc.
 */

/**
 * ObjectManagerClient:
 *
 * The #ObjectManagerClient structure contains only private data and should only be accessed using the provided API.
 */

/**
 * ObjectManagerClientClass:
 * @parent_class: The parent class.
 *
 * Class structure for #ObjectManagerClient.
 */

G_DEFINE_TYPE (ObjectManagerClient, object_manager_client, G_TYPE_DBUS_OBJECT_MANAGER_CLIENT);

static void
object_manager_client_init (ObjectManagerClient *manager G_GNUC_UNUSED)
{
}

static void
object_manager_client_class_init (ObjectManagerClientClass *klass G_GNUC_UNUSED)
{
}

/**
 * object_manager_client_get_proxy_type:
 * @manager: A #GDBusObjectManagerClient.
 * @object_path: The object path of the remote object (unused).
 * @interface_name: (allow-none): Interface name of the remote object or %NULL to get the object proxy #GType.
 * @user_data: User data (unused).
 *
 * A #GDBusProxyTypeFunc that maps @interface_name to the generated #GDBusObjectProxy<!-- -->- and #GDBusProxy<!-- -->-derived types.
 *
 * Returns: A #GDBusProxy<!-- -->-derived #GType if @interface_name is not %NULL, otherwise the #GType for #ObjectProxy.
 */
GType
object_manager_client_get_proxy_type (GDBusObjectManagerClient *manager G_GNUC_UNUSED, const gchar *object_path G_GNUC_UNUSED, const gchar *interface_name, gpointer user_data G_GNUC_UNUSED)
{
  static gsize once_init_value = 0;
  static GHashTable *lookup_hash;
  GType ret;

  if (interface_name == NULL)
    return TYPE_OBJECT_PROXY;
  if (g_once_init_enter (&once_init_value))
    {
      lookup_hash = g_hash_table_new (g_str_hash, g_str_equal);
      g_hash_table_insert (lookup_hash, (gpointer) "org.openbmc.Watchdog", GSIZE_TO_POINTER (TYPE_WATCHDOG_PROXY));
      g_once_init_leave (&once_init_value, 1);
    }
  ret = (GType) GPOINTER_TO_SIZE (g_hash_table_lookup (lookup_hash, interface_name));
  if (ret == (GType) 0)
    ret = G_TYPE_DBUS_PROXY;
  return ret;
}

/**
 * object_manager_client_new:
 * @connection: A #GDBusConnection.
 * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.
 * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection.
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously creates #GDBusObjectManagerClient using object_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc. See g_dbus_object_manager_client_new() for more details.
 *
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call object_manager_client_new_finish() to get the result of the operation.
 *
 * See object_manager_client_new_sync() for the synchronous, blocking version of this constructor.
 */
void
object_manager_client_new (
    GDBusConnection        *connection,
    GDBusObjectManagerClientFlags  flags,
    const gchar            *name,
    const gchar            *object_path,
    GCancellable           *cancellable,
    GAsyncReadyCallback     callback,
    gpointer                user_data)
{
  g_async_initable_new_async (TYPE_OBJECT_MANAGER_CLIENT, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "flags", flags, "name", name, "connection", connection, "object-path", object_path, "get-proxy-type-func", object_manager_client_get_proxy_type, NULL);
}

/**
 * object_manager_client_new_finish:
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to object_manager_client_new().
 * @error: Return location for error or %NULL
 *
 * Finishes an operation started with object_manager_client_new().
 *
 * Returns: (transfer full) (type ObjectManagerClient): The constructed object manager client or %NULL if @error is set.
 */
GDBusObjectManager *
object_manager_client_new_finish (
    GAsyncResult        *res,
    GError             **error)
{
  GObject *ret;
  GObject *source_object;
  source_object = g_async_result_get_source_object (res);
  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);
  g_object_unref (source_object);
  if (ret != NULL)
    return G_DBUS_OBJECT_MANAGER (ret);
  else
    return NULL;
}

/**
 * object_manager_client_new_sync:
 * @connection: A #GDBusConnection.
 * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.
 * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection.
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL
 *
 * Synchronously creates #GDBusObjectManagerClient using object_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc. See g_dbus_object_manager_client_new_sync() for more details.
 *
 * The calling thread is blocked until a reply is received.
 *
 * See object_manager_client_new() for the asynchronous version of this constructor.
 *
 * Returns: (transfer full) (type ObjectManagerClient): The constructed object manager client or %NULL if @error is set.
 */
GDBusObjectManager *
object_manager_client_new_sync (
    GDBusConnection        *connection,
    GDBusObjectManagerClientFlags  flags,
    const gchar            *name,
    const gchar            *object_path,
    GCancellable           *cancellable,
    GError                **error)
{
  GInitable *ret;
  ret = g_initable_new (TYPE_OBJECT_MANAGER_CLIENT, cancellable, error, "flags", flags, "name", name, "connection", connection, "object-path", object_path, "get-proxy-type-func", object_manager_client_get_proxy_type, NULL);
  if (ret != NULL)
    return G_DBUS_OBJECT_MANAGER (ret);
  else
    return NULL;
}


/**
 * object_manager_client_new_for_bus:
 * @bus_type: A #GBusType.
 * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.
 * @name: A bus name (well-known or unique).
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
 * @user_data: User data to pass to @callback.
 *
 * Like object_manager_client_new() but takes a #GBusType instead of a #GDBusConnection.
 *
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call object_manager_client_new_for_bus_finish() to get the result of the operation.
 *
 * See object_manager_client_new_for_bus_sync() for the synchronous, blocking version of this constructor.
 */
void
object_manager_client_new_for_bus (
    GBusType                bus_type,
    GDBusObjectManagerClientFlags  flags,
    const gchar            *name,
    const gchar            *object_path,
    GCancellable           *cancellable,
    GAsyncReadyCallback     callback,
    gpointer                user_data)
{
  g_async_initable_new_async (TYPE_OBJECT_MANAGER_CLIENT, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "flags", flags, "name", name, "bus-type", bus_type, "object-path", object_path, "get-proxy-type-func", object_manager_client_get_proxy_type, NULL);
}

/**
 * object_manager_client_new_for_bus_finish:
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to object_manager_client_new_for_bus().
 * @error: Return location for error or %NULL
 *
 * Finishes an operation started with object_manager_client_new_for_bus().
 *
 * Returns: (transfer full) (type ObjectManagerClient): The constructed object manager client or %NULL if @error is set.
 */
GDBusObjectManager *
object_manager_client_new_for_bus_finish (
    GAsyncResult        *res,
    GError             **error)
{
  GObject *ret;
  GObject *source_object;
  source_object = g_async_result_get_source_object (res);
  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);
  g_object_unref (source_object);
  if (ret != NULL)
    return G_DBUS_OBJECT_MANAGER (ret);
  else
    return NULL;
}

/**
 * object_manager_client_new_for_bus_sync:
 * @bus_type: A #GBusType.
 * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.
 * @name: A bus name (well-known or unique).
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL
 *
 * Like object_manager_client_new_sync() but takes a #GBusType instead of a #GDBusConnection.
 *
 * The calling thread is blocked until a reply is received.
 *
 * See object_manager_client_new_for_bus() for the asynchronous version of this constructor.
 *
 * Returns: (transfer full) (type ObjectManagerClient): The constructed object manager client or %NULL if @error is set.
 */
GDBusObjectManager *
object_manager_client_new_for_bus_sync (
    GBusType                bus_type,
    GDBusObjectManagerClientFlags  flags,
    const gchar            *name,
    const gchar            *object_path,
    GCancellable           *cancellable,
    GError                **error)
{
  GInitable *ret;
  ret = g_initable_new (TYPE_OBJECT_MANAGER_CLIENT, cancellable, error, "flags", flags, "name", name, "bus-type", bus_type, "object-path", object_path, "get-proxy-type-func", object_manager_client_get_proxy_type, NULL);
  if (ret != NULL)
    return G_DBUS_OBJECT_MANAGER (ret);
  else
    return NULL;
}


