Re: [PATCH BlueZ RFC] Refactor uid_state handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Andrew,

On Fri, Jun 20, 2025 at 7:39 AM Andrew Sayers
<kernel.org@xxxxxxxxxxxxxxx> wrote:
>
> We talked recently about refactoring logind.{c,h} to fit more neatly
> into the program's wider architecture.  This patch sketches out a
> possible approach.  It compiles, but has not been tested beyond that.
> If I'm on the right track, I'll come back with a proper solution.
>
> The old API provided callbacks on high-level "init" and "exit" events.
> That made sense for the limited case it was used for, but seems
> unlikely to scale if this starts picking up more use cases.  So the
> RFC API just provides a single event that passes a `logind_cb_context`
> struct to callbacks, and provides `LOGIND_USER_IS_ACTIVE(ctxt)` to
> replicate the old behaviour.
>
> The old API invited individual transports/drivers to use it directly,
> which again made sense for version 1, but bypassed `transport.h` and
> `driver.h`.  The RFC API registers callbacks with `driver.h` and
> `transport.h` in a more normal way, and they pass `logind_cb_context`
> straight through to the callbacks.  That means we won't need to do
> much refactoring if the struct changes some day, but also means
> individual transports/drivers need to know about `logind.h`.
> The alternative would look something like this:
>
> --- obexd/client/driver.h
> +++ obexd/client/driver.h
> struct obc_driver {
>         const char *service;
>         const char *uuid;
>         void *target;
>         gsize target_len;
>         void *(*supported_features) (struct obc_session *session);
>         int (*probe) (struct obc_session *session);
>         void (*remove) (struct obc_session *session);
> +       int (*uid_state) (const char *state, const int seats);

Don't think we really need to expose the seat state, etc, instead I
would just have a seated and unseated callback which just indicates to
the driver it can do the likes of RegisterProfile/UnregisterProfile
that way we can restrict the handling of seats just to driver.c and I
don't think we really need it for transport drivers the transports are
usable if there are drivers in obc_session_create:

    driver = obc_driver_find(service);
    if (driver == NULL)
        return NULL;

So once we integrate the seat logic into the driver.c I assume
obc_driver_find will only return drivers that are seated, so
users/applications on a unseated D-Bus connection won't be able to
create any sessions.

> };
> --- obexd/client/driver.c
> +++ obexd/client/driver.c
> +static void call_cb(gpointer data, gpointer ctxt_)
> +{
> +       struct obc_driver *driver = (struct obc_driver *)data;
> +       struct logind_cb_context *ctxt = (struct logind_cb_context *)ctxt_;
> +       if (driver->uid_state) {
> +               ctxt->res |= driver->uid_state(ctxt->state, ctxt->seats);
> +       }
> +}
>
> That would have a better best case (fewer `#include logind.h`s strewn
> throughout the code) but a worse worst case (bigger refactoring job if
> we need to pass an extra argument some day).  I think the RFC patch is
> a better balance of risks, but am happy either way.
>
> The RFC patches for `pbap.c` and `bluetooth.c` are designed to show
> the difference between the old and new API.  A proper patch will
> probably get rid of the `_cb()`, `_init()` and `_exit()` functions.
>
> Suggested-by: Luiz Augusto von Dentz <luiz.dentz@xxxxxxxxx>
> Signed-off-by: Andrew Sayers <kernel.org@xxxxxxxxxxxxxxx>
> ---
>  obexd/client/driver.c     |  18 +++++
>  obexd/client/driver.h     |   5 ++
>  obexd/client/pbap.c       |  62 ++++++++++------
>  obexd/plugins/bluetooth.c |  30 ++++++--
>  obexd/src/logind.c        | 152 ++++++++++++++++++--------------------
>  obexd/src/logind.h        |  59 ++++++++++++---
>  obexd/src/main.c          |  12 +++
>  obexd/src/transport.c     |  17 +++++
>  obexd/src/transport.h     |   5 ++
>  9 files changed, 237 insertions(+), 123 deletions(-)
>
> diff --git a/obexd/client/driver.c b/obexd/client/driver.c
> index 195cdd2f1..d5d0fe2ab 100644
> --- a/obexd/client/driver.c
> +++ b/obexd/client/driver.c
> @@ -74,3 +74,21 @@ void obc_driver_unregister(struct obc_driver *driver)
>
>         drivers = g_slist_remove(drivers, driver);
>  }
> +
> +static void call_cb(gpointer data, gpointer ctxt)
> +{
> +       struct obc_driver *driver = (struct obc_driver *)data;
> +
> +       if (driver->uid_state)
> +               driver->uid_state(((struct logind_cb_context *)ctxt));
> +}
> +
> +static void call_uid_state_cb(gpointer ctxt)
> +{
> +       g_slist_foreach(drivers, call_cb, ctxt);
> +}
> +
> +gboolean obc_driver_init(void)
> +{
> +       return logind_register(call_uid_state_cb) >= 0;
> +}
> diff --git a/obexd/client/driver.h b/obexd/client/driver.h
> index cc4cace7b..928c0c558 100644
> --- a/obexd/client/driver.h
> +++ b/obexd/client/driver.h
> @@ -8,6 +8,9 @@
>   *
>   */
>
> +#include "obexd/src/logind.h"
> +struct obc_session;
> +
>  struct obc_driver {
>         const char *service;
>         const char *uuid;
> @@ -16,8 +19,10 @@ struct obc_driver {
>         void *(*supported_features) (struct obc_session *session);
>         int (*probe) (struct obc_session *session);
>         void (*remove) (struct obc_session *session);
> +       void (*uid_state) (struct logind_cb_context *ctxt);
>  };
>
>  int obc_driver_register(struct obc_driver *driver);
>  void obc_driver_unregister(struct obc_driver *driver);
>  struct obc_driver *obc_driver_find(const char *pattern);
> +gboolean obc_driver_init(void);
> diff --git a/obexd/client/pbap.c b/obexd/client/pbap.c
> index 78c46bf86..dc2a519e5 100644
> --- a/obexd/client/pbap.c
> +++ b/obexd/client/pbap.c
> @@ -146,6 +146,9 @@ static DBusConnection *system_conn;
>  static unsigned int listener_id;
>  static char *client_path;
>
> +static int pbap_init_cb(void);
> +static void pbap_exit_cb(void);
> +
>  static struct pending_request *pending_request_new(struct pbap_data *pbap,
>                                                         DBusMessage *message)
>  {
> @@ -1300,6 +1303,20 @@ static void pbap_remove(struct obc_session *session)
>         g_dbus_unregister_interface(conn, path, PBAP_INTERFACE);
>  }
>
> +static gboolean user_was_active = FALSE;
> +static void pbap_uid_state(struct logind_cb_context *ctxt)
> +{
> +       gboolean user_is_active = LOGIND_USER_IS_ACTIVE(ctxt);
> +
> +       if (user_was_active == user_is_active)
> +               return;
> +       user_was_active = user_is_active;
> +       if (user_is_active)
> +               pbap_init_cb();
> +       else
> +               pbap_exit_cb();
> +}
> +
>  static DBusMessage *pbap_release(DBusConnection *conn,
>         DBusMessage *msg, void *data)
>  {
> @@ -1452,13 +1469,13 @@ static struct obc_driver pbap = {
>         .target_len = OBEX_PBAP_UUID_LEN,
>         .supported_features = pbap_supported_features,
>         .probe = pbap_probe,
> -       .remove = pbap_remove
> +       .remove = pbap_remove,
> +       .uid_state = pbap_uid_state
>  };
>
> -static int pbap_init_cb(gboolean at_register)
> +static int pbap_init_cb(void)
>  {
>         int err;
> -       (void)at_register;
>
>         DBG("");
>
> @@ -1483,7 +1500,7 @@ static int pbap_init_cb(gboolean at_register)
>         return 0;
>  }
>
> -static void pbap_exit_cb(gboolean at_unregister)
> +static void pbap_exit_cb(void)
>  {
>         DBusMessage *msg;
>         DBusMessageIter iter;
> @@ -1491,22 +1508,28 @@ static void pbap_exit_cb(gboolean at_unregister)
>
>         DBG("");
>
> -       if (!at_unregister) {
> -               client_path = g_strconcat("/org/bluez/obex/", uuid, NULL);
> -               g_strdelimit(client_path, "-", '_');
> +       client_path = g_strconcat("/org/bluez/obex/", uuid, NULL);
> +       g_strdelimit(client_path, "-", '_');
>
> -               msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
> -                                                       "org.bluez.ProfileManager1",
> -                                                       "UnregisterProfile");
> +       msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
> +                                               "org.bluez.ProfileManager1",
> +                                               "UnregisterProfile");
>
> -               dbus_message_iter_init_append(msg, &iter);
> +       dbus_message_iter_init_append(msg, &iter);
>
> -               dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
> -                                                               &client_path);
> +       dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
> +                                                       &client_path);
>
> -               g_dbus_send_message(system_conn, msg);
> -       }
> +       g_dbus_send_message(system_conn, msg);
>
> +       pbap_exit();
> +}
> +
> +int pbap_init(void)
> +{
> +}
> +void pbap_exit(void)
> +{
>         g_dbus_remove_watch(system_conn, listener_id);
>
>         unregister_profile();
> @@ -1524,12 +1547,3 @@ static void pbap_exit_cb(gboolean at_unregister)
>
>         obc_driver_unregister(&pbap);
>  }
> -
> -int pbap_init(void)
> -{
> -       return logind_register(pbap_init_cb, pbap_exit_cb);
> -}
> -void pbap_exit(void)
> -{
> -       return logind_unregister(pbap_init_cb, pbap_exit_cb);
> -}
> diff --git a/obexd/plugins/bluetooth.c b/obexd/plugins/bluetooth.c
> index 355921479..ebff88db3 100644
> --- a/obexd/plugins/bluetooth.c
> +++ b/obexd/plugins/bluetooth.c
> @@ -57,6 +57,9 @@ static DBusMessage *profile_release(DBusConnection *conn, DBusMessage *msg,
>         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
>  }
>
> +static int bluetooth_init_cb(void);
> +static void bluetooth_exit_cb(void);
> +
>  static void connect_event(GIOChannel *io, GError *err, void *user_data)
>  {
>         int sk = g_io_channel_unix_get_fd(io);
> @@ -381,6 +384,20 @@ static void bluetooth_stop(void *data)
>         profiles = NULL;
>  }
>
> +static gboolean user_was_active = FALSE;
> +static void bluetooth_uid_state(struct logind_cb_context *ctxt)
> +{
> +       gboolean user_is_active = LOGIND_USER_IS_ACTIVE(ctxt);
> +
> +       if (user_was_active == user_is_active)
> +               return;
> +       user_was_active = user_is_active;
> +       if (user_is_active)
> +               bluetooth_init_cb();
> +       else
> +               bluetooth_exit_cb();
> +}
> +
>  static int bluetooth_getpeername(GIOChannel *io, char **name)
>  {
>         GError *gerr = NULL;
> @@ -422,14 +439,14 @@ static const struct obex_transport_driver driver = {
>         .start = bluetooth_start,
>         .getpeername = bluetooth_getpeername,
>         .getsockname = bluetooth_getsockname,
> -       .stop = bluetooth_stop
> +       .stop = bluetooth_stop,
> +       .uid_state = bluetooth_uid_state
>  };
>
>  static unsigned int listener_id = 0;
>
> -static int bluetooth_init_cb(gboolean at_register)
> +static int bluetooth_init_cb(void)
>  {
> -       (void)at_register;
>         connection = g_dbus_setup_private(DBUS_BUS_SYSTEM, NULL, NULL);
>         if (connection == NULL)
>                 return -EPERM;
> @@ -440,10 +457,9 @@ static int bluetooth_init_cb(gboolean at_register)
>         return obex_transport_driver_register(&driver);
>  }
>
> -static void bluetooth_exit_cb(gboolean at_unregister)
> +static void bluetooth_exit_cb(void)
>  {
>         GSList *l;
> -       (void)at_unregister;
>
>         g_dbus_remove_watch(connection, listener_id);
>
> @@ -467,11 +483,11 @@ static void bluetooth_exit_cb(gboolean at_unregister)
>
>  static int bluetooth_init(void)
>  {
> -       return logind_register(bluetooth_init_cb, bluetooth_exit_cb);
>  }
>  static void bluetooth_exit(void)
>  {
> -       return logind_unregister(bluetooth_init_cb, bluetooth_exit_cb);
> +       if (user_was_active)
> +               bluetooth_exit_cb();
>  }
>
>  OBEX_PLUGIN_DEFINE(bluetooth, bluetooth_init, bluetooth_exit)
> diff --git a/obexd/src/logind.c b/obexd/src/logind.c
> index b4279b209..a8ea25543 100644
> --- a/obexd/src/logind.c
> +++ b/obexd/src/logind.c
> @@ -27,66 +27,48 @@
>
>  static sd_login_monitor * monitor;
>  static int uid;
> -static gboolean active = FALSE;
>  static gboolean monitoring_enabled = TRUE;
>  static guint event_source;
>  static guint timeout_source;
>
> -struct callback_pair {
> -       logind_init_cb init_cb;
> -       logind_exit_cb exit_cb;
> -};
> -
>  GSList *callbacks;
>
> -static void call_init_cb(gpointer data, gpointer user_data)
> -{
> -       int res;
> -
> -       res = ((struct callback_pair *)data)->init_cb(FALSE);
> -       if (res)
> -               *(int *)user_data = res;
> -}
> -static void call_exit_cb(gpointer data, gpointer user_data)
> +static void call_cb(gpointer data, gpointer user_data)
>  {
> -       ((struct callback_pair *)data)->exit_cb(FALSE);
> +       (*((logind_cb *)data))(user_data);
>  }
>
> -static int update(void)
> +static void logind_cb_context_init(struct logind_cb_context *ctxt)
>  {
> -       char *state = NULL;
> -       gboolean state_is_active;
> -       int res;
> -
> -       res = sd_login_monitor_flush(monitor);
> -       if (res < 0)
> -               return res;
> -       res = sd_uid_get_state(uid, &state);
> -       state_is_active = g_strcmp0(state, "active");
> -       free(state);
> -       if (res < 0)
> -               return res;
> -
> -       if (state_is_active) {
> -               if (!active)
> -                       return 0;
> -       } else {
> -               res = sd_uid_get_seats(uid, 1, NULL);
> -               if (res < 0)
> -                       return res;
> -               if (active == !!res)
> -                       return 0;
> +       ctxt->res = sd_login_monitor_flush(monitor);
> +       if (ctxt->res < 0)
> +               return;
> +
> +       ctxt->res = ctxt->seats = sd_uid_get_seats(uid, 1, NULL);
> +       if (ctxt->res < 0)
> +               return;
> +
> +       /*
> +        * the documentation for sd_uid_get_state() isn't clear about
> +        * what to do with the state on error.  The following should
> +        * be safe even if the behaviour changes in future
> +        */
> +       ctxt->state = 0;
> +       ctxt->res = sd_uid_get_state(uid, (char **)&ctxt->state);
> +       if (ctxt->res <= 0) {
> +               free((char *)ctxt->state);
> +               return;
>         }
> -       active ^= TRUE;
> -       res = 0;
> -       g_slist_foreach(callbacks, active ? call_init_cb : call_exit_cb, &res);
> -       return res;
> +
> +       ctxt->res = 0;
> +       return;
>  }
>
>  static gboolean timeout_handler(gpointer user_data);
>
>  static int check_event(void)
>  {
> +       struct logind_cb_context ctxt;
>         uint64_t timeout_usec;
>         int res;
>
> @@ -95,9 +77,14 @@ static int check_event(void)
>                 return res;
>         if (!monitoring_enabled)
>                 return 0;
> -       res = update();
> -       if (res < 0)
> -               return res;
> +
> +       logind_cb_context_init(&ctxt);
> +       if (ctxt.res)
> +               return ctxt.res;
> +       g_slist_foreach(callbacks, call_cb, &ctxt);
> +       free((char *)ctxt.state);
> +       if (ctxt.res)
> +               return ctxt.res;
>
>         res = sd_login_monitor_get_timeout(monitor, &timeout_usec);
>         if (res < 0)
> @@ -154,6 +141,7 @@ static gboolean timeout_handler(gpointer user_data)
>
>  static int logind_init(void)
>  {
> +       struct logind_cb_context ctxt;
>         GIOChannel *channel;
>         int events;
>         int fd;
> @@ -174,11 +162,6 @@ static int logind_init(void)
>                 goto FAIL;
>         }
>
> -       // Check this after creating the monitor, in case of race conditions:
> -       res = update();
> -       if (res < 0)
> -               goto FAIL;
> -
>         events = res = sd_login_monitor_get_events(monitor);
>         if (res < 0)
>                 goto FAIL;
> @@ -202,7 +185,10 @@ static int logind_init(void)
>  FAIL:
>         sd_login_monitor_unref(monitor);
>         monitoring_enabled = FALSE;
> -       active = TRUE;
> +       ctxt.state = "active";
> +       ctxt.seats = 1;
> +       ctxt.res = 0;
> +       g_slist_foreach(callbacks, call_cb, &ctxt);
>         return res;
>  }
>
> @@ -219,17 +205,18 @@ static void logind_exit(void)
>         sd_login_monitor_unref(monitor);
>  }
>
> -static gint find_cb(gconstpointer a, gconstpointer b)
> +int logind_register(logind_cb cb)
>  {
> -       return ((struct callback_pair *)a)->init_cb - (logind_init_cb)b;
> -}
> +       struct logind_cb_context ctxt;
>
> -int logind_register(logind_init_cb init_cb, logind_exit_cb exit_cb)
> -{
> -       struct callback_pair *cbs;
> +       logind_cb_context_init(&ctxt);
> +       if (ctxt.res) {
> +               free((char *)ctxt.state);
> +               return ctxt.res;
> +       }
>
>         if (!monitoring_enabled)
> -               return init_cb(TRUE);
> +               goto CALL_CB;
>         if (callbacks == NULL) {
>                 int res;
>
> @@ -237,24 +224,23 @@ int logind_register(logind_init_cb init_cb, logind_exit_cb exit_cb)
>                 if (res) {
>                         error("logind_init(): %s - login detection disabled",
>                                 strerror(-res));
> -                       return init_cb(TRUE);
> +                       goto CALL_CB;
>                 }
>         }
> -       cbs = g_new(struct callback_pair, 1);
> -       cbs->init_cb = init_cb;
> -       cbs->exit_cb = exit_cb;
> -       callbacks = g_slist_prepend(callbacks, cbs);
> -       return active ? init_cb(TRUE) : 0;
> +       callbacks = g_slist_prepend(callbacks, cb);
> +
> +CALL_CB:
> +       cb(&ctxt);
> +       free((char *)ctxt.state);
> +       return ctxt.res;
>  }
> -void logind_unregister(logind_init_cb init_cb, logind_exit_cb exit_cb)
> +void logind_unregister(logind_cb cb)
>  {
>         GSList *cb_node;
>
>         if (!monitoring_enabled)
> -               return exit_cb(TRUE);
> -       if (active)
> -               exit_cb(TRUE);
> -       cb_node = g_slist_find_custom(callbacks, init_cb, find_cb);
> +               return;
> +       cb_node = g_slist_find(callbacks, cb);
>         if (cb_node != NULL)
>                 callbacks = g_slist_delete_link(callbacks, cb_node);
>         if (callbacks == NULL)
> @@ -263,20 +249,26 @@ void logind_unregister(logind_init_cb init_cb, logind_exit_cb exit_cb)
>
>  int logind_set(gboolean enabled)
>  {
> -       int res = 0;
> -
> -       if (monitoring_enabled == enabled)
> -               return 0;
> -
>         monitoring_enabled = enabled;
>         if (enabled) {
> -               active = FALSE;
> -               return update();
> +               struct logind_cb_context ctxt;
> +
> +               logind_cb_context_init(&ctxt);
> +               if (ctxt.res)
> +                       return ctxt.res;
> +               g_slist_foreach(callbacks, call_cb, &ctxt);
> +               free((char *)ctxt.state);
> +               return ctxt.res;
>         }
>
> -       active = TRUE;
> -       g_slist_foreach(callbacks, call_exit_cb, &res);
> -       return res;
> +       struct logind_cb_context ctxt = {
> +               .state = "active",
> +               .seats = 1,
> +               .res = 0
> +       };
> +
> +       g_slist_foreach(callbacks, call_cb, &ctxt);
> +       return ctxt.res;
>  }
>
>  #endif
> diff --git a/obexd/src/logind.h b/obexd/src/logind.h
> index 3cdb03338..243aa17bd 100644
> --- a/obexd/src/logind.h
> +++ b/obexd/src/logind.h
> @@ -8,30 +8,65 @@
>   *
>   */
>
> -typedef int (*logind_init_cb)(gboolean at_register);
> -typedef void (*logind_exit_cb)(gboolean at_unregister);
> +#ifndef OBEXD_SRC_LOGIND_H
> +#define OBEXD_SRC_LOGIND_H
> +
> +struct logind_cb_context {
> +       const char *state;
> +       int seats;
> +       int res;
> +};
> +
> +typedef void (*logind_cb)(gpointer ctxt);
>
>  #ifdef SYSTEMD
>
> -int logind_register(logind_init_cb init_cb, logind_exit_cb exit_cb);
> -void logind_unregister(logind_init_cb init_cb, logind_exit_cb exit_cb);
> +/*
> + * Register callback and call it with the current state
> + */
> +int logind_register(logind_cb init_cb);
> +/*
> + * Unregister callback but DO NOT call it -
> + * unregistration usually happens when the user is logging out,
> + * and other programs are going away.
> + *
> + * If possible, close resources at exit instead of at unregister.
> + * Otherwise, you will need to explicitly call your callback.
> + */
> +void logind_unregister(logind_cb cb);
> +/*
> + * Override the detected login state
> + */
>  int logind_set(gboolean enabled);
>
> -#else
> +/* Recommended way to detect (in)activity */
> +#define LOGIND_USER_IS_ACTIVE(ctxt) \
> +       (!g_strcmp0(ctxt->state, "active") && !!(ctxt->seats))
>
> -static inline int logind_register(logind_init_cb init_cb,
> -                                       logind_exit_cb exit_cb)
> +#else /* SYSTEMD */
> +
> +static inline int logind_register(logind_cb cb)
>  {
> -       return init_cb(TRUE);
> +       (void)cb;
> +       struct logind_cb_context ctxt = {
> +               .state = "active",
> +               .seats = 1,
> +               .res = 0
> +       };
> +       cb(&ctxt);
> +       return ctxt.res;
>  }
> -static inline void logind_unregister(logind_init_cb init_cb,
> -                                       logind_exit_cb exit_cb)
> +static inline void logind_unregister(logind_cb cb)
>  {
> -       return exit_cb(TRUE);
> +       (void)cb;
>  }
>  static inline int logind_set(gboolean enabled)
>  {
>         return 0;
>  }
>
> -#endif
> +#define LOGIND_USER_IS_ACTIVE(...) 1
> +
> +#endif /* SYSTEMD */
> +
> +#endif /* OBEXD_SRC_LOGIND_H */
> diff --git a/obexd/src/main.c b/obexd/src/main.c
> index 6837f0d73..116888a78 100644
> --- a/obexd/src/main.c
> +++ b/obexd/src/main.c
> @@ -34,6 +34,9 @@
>
>  #include "../client/manager.h"
>
> +#include "../client/driver.h"
> +#include "transport.h"
> +
>  #include "log.h"
>  #include "logind.h"
>  #include "obexd.h"
> @@ -279,6 +282,15 @@ int main(int argc, char *argv[])
>         if (option_system_bus)
>                 logind_set(FALSE);
>
> +       if (obc_driver_init() == FALSE) {
> +               error("manager_init failed");
> +               exit(EXIT_FAILURE);
> +       }
> +       if (obex_transport_driver_init() == FALSE) {
> +               error("manager_init failed");
> +               exit(EXIT_FAILURE);
> +       }
> +
>         DBG("Entering main loop");
>
>         main_loop = g_main_loop_new(NULL, FALSE);
> diff --git a/obexd/src/transport.c b/obexd/src/transport.c
> index 527d9ffce..fdd49b7a2 100644
> --- a/obexd/src/transport.c
> +++ b/obexd/src/transport.c
> @@ -79,3 +79,20 @@ obex_transport_driver_unregister(const struct obex_transport_driver *driver)
>
>         drivers = g_slist_remove(drivers, driver);
>  }
> +
> +static void call_cb(gpointer data, gpointer ctxt)
> +{
> +       struct obex_transport_driver *driver =
> +               (struct obex_transport_driver *)data;
> +       if (driver->uid_state)
> +               driver->uid_state(((struct logind_cb_context *)ctxt));
> +}
> +
> +static int call_uid_state_cb(gpointer ctxt)
> +{
> +       g_slist_foreach(drivers, call_cb, ctxt);
> +}
> +
> +gboolean obex_transport_driver_init(void)
> +{
> +}
> diff --git a/obexd/src/transport.h b/obexd/src/transport.h
> index 322d8f526..087d8c211 100644
> --- a/obexd/src/transport.h
> +++ b/obexd/src/transport.h
> @@ -8,6 +8,9 @@
>   *
>   */
>
> +#include "obexd/src/logind.h"
> +struct obex_server;
> +
>  struct obex_transport_driver {
>         const char *name;
>         uint16_t service;
> @@ -15,9 +18,11 @@ struct obex_transport_driver {
>         int (*getpeername) (GIOChannel *io, char **name);
>         int (*getsockname) (GIOChannel *io, char **name);
>         void (*stop) (void *data);
> +       void (*uid_state) (struct logind_cb_context *ctxt);
>  };
>
>  int obex_transport_driver_register(const struct obex_transport_driver *driver);
>  void
>  obex_transport_driver_unregister(const struct obex_transport_driver *driver);
>  const GSList *obex_transport_driver_list(void);
> +gboolean obex_transport_driver_init(void);
> --
> 2.49.0
>


-- 
Luiz Augusto von Dentz





[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux