Re: [PATCH v2 BlueZ 1/2] core/gatt: Cleanup service probe

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

 



Hi,

On Thu, Sep 3, 2015 at 3:22 PM, Luiz Augusto von Dentz
<luiz.dentz@xxxxxxxxx> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>
>
> This cleanup code related to service probe making it use a single
> function, because of that now all driver must implement device_probe in
> order for the service probe to work properly.
>
> In addition to that a new flag called external was introduced to
> btd_profile to be possible to distinguish whether it is a internal
> plugin or external client, this was needed in order to decide if an
> attribute should be claimed which whould prevent it to be exported over
> D-Bus.
> ---
>  src/device.c        | 167 +++++++++++++++-------------------------------------
>  src/gatt-database.c |  30 ++++++++--
>  src/profile.c       |  11 +++-
>  src/profile.h       |   1 +
>  4 files changed, 84 insertions(+), 125 deletions(-)
>
> diff --git a/src/device.c b/src/device.c
> index bdea55b..999f09f 100644
> --- a/src/device.c
> +++ b/src/device.c
> @@ -2814,14 +2814,6 @@ static void device_add_uuids(struct btd_device *device, GSList *uuids)
>                                                 DEVICE_INTERFACE, "UUIDs");
>  }
>
> -struct gatt_probe_data {
> -       struct btd_device *dev;
> -       bool all_services;
> -       GSList *uuids;
> -       struct gatt_db_attribute *cur_attr;
> -       char cur_uuid[MAX_LEN_UUID_STR];
> -};
> -
>  static bool device_match_profile(struct btd_device *device,
>                                         struct btd_profile *profile,
>                                         GSList *uuids)
> @@ -2836,99 +2828,42 @@ static bool device_match_profile(struct btd_device *device,
>         return true;
>  }
>
> -static void dev_probe_gatt(struct btd_profile *p, void *user_data)
> +static void probe_gatt_profile(struct gatt_db_attribute *attr, void *user_data)
>  {
> -       struct gatt_probe_data *data = user_data;
> +       struct btd_device *device = user_data;
>         struct btd_service *service;
> -
> -       if (!p->remote_uuid || bt_uuid_strcmp(p->remote_uuid, data->cur_uuid))
> -               return;
> -
> -       /*
> -        * Add device to auto connect list in case the driver has the auto
> -        * connect flag set.
> -        * NOTE: This should work regardless if a service is created and
> -        * probed since external drivers don't need to maintain any
> -        * states they don't implement device_probe callback.
> -        */
> -       if (p->auto_connect)
> -               device_set_auto_connect(data->dev, TRUE);
> -
> -       if (p->device_probe == NULL)
> -               return;
> -
> -       service = service_create(data->dev, p);
> -       if (!service)
> -               return;
> -
> -       if (service_probe(service) < 0) {
> -               btd_service_unref(service);
> -               return;
> -       }
> -
> -       /* Mark service as active to skip discovering it again */
> -       gatt_db_service_set_active(data->cur_attr, true);
> -
> -       /* Mark service as claimed */
> -       gatt_db_service_set_claimed(data->cur_attr, true);
> -
> -       data->dev->services = g_slist_append(data->dev->services, service);
> -}
> -
> -static void dev_probe_gatt_profile(struct gatt_db_attribute *attr,
> -                                                       void *user_data)
> -{
> -       struct gatt_probe_data *data = user_data;
> +       struct btd_profile *profile;
>         bt_uuid_t uuid;
> -       GSList *l = NULL;
> +       char uuid_str[MAX_LEN_UUID_STR];
> +       GSList *l;
>
>         gatt_db_attribute_get_service_uuid(attr, &uuid);
> -       bt_uuid_to_string(&uuid, data->cur_uuid, sizeof(data->cur_uuid));
> -
> -       data->cur_attr = attr;
> -
> -       /*
> -        * If we're probing for all services, store the UUID since device->uuids
> -        * was cleared.
> -        */
> -       if (data->all_services)
> -               data->uuids = g_slist_append(data->uuids,
> -                                               g_strdup(data->cur_uuid));
> -
> -       /* Don't probe the profiles if a matching service already exists. */
> -       if (find_service_with_uuid(data->dev->services, data->cur_uuid)) {
> -               /* Mark service as active to skip discovering it again */
> -               gatt_db_service_set_active(data->cur_attr, true);
> -               /* Mark the service as claimed by the existing profile. */
> -               gatt_db_service_set_claimed(data->cur_attr, true);
> -               return;
> -       }
> +       bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
>
> -       btd_profile_foreach(dev_probe_gatt, data);
> +       /* Add UUID and probe service */
> +       btd_device_add_uuid(device, uuid_str);
>
> -       if (data->all_services)
> +       /* Check if service was probed */
> +       l = find_service_with_uuid(device->services, uuid_str);
> +       if (!l)
>                 return;
>
> -       l = g_slist_append(l, g_strdup(data->cur_uuid));
> -       device_add_uuids(data->dev, l);
> -}
> -
> -static void device_probe_gatt_profile(struct btd_device *device,
> -                                               struct gatt_db_attribute *attr)
> -{
> -       struct gatt_probe_data data;
> +       /* Mark service as active to skip discovering it again */
> +       gatt_db_service_set_active(attr, true);
>
> -       memset(&data, 0, sizeof(data));
> +       service = l->data;
> +       profile = btd_service_get_profile(service);
>
> -       data.dev = device;
> +       /* Don't claim attributes of external profiles */
> +       if (profile->external)
> +               return;
>
> -       dev_probe_gatt_profile(attr, &data);
> -       g_slist_free_full(data.uuids, g_free);
> +       /* Mark the service as claimed by the existing profile. */
> +       gatt_db_service_set_claimed(attr, true);
>  }
>
>  static void device_probe_gatt_profiles(struct btd_device *device)
>  {
> -       struct gatt_probe_data data;
>         char addr[18];
>
>         ba2str(&device->bdaddr, addr);
> @@ -2938,16 +2873,7 @@ static void device_probe_gatt_profiles(struct btd_device *device)
>                 return;
>         }
>
> -       memset(&data, 0, sizeof(data));
> -
> -       data.dev = device;
> -       data.all_services = true;
> -
> -       gatt_db_foreach_service(device->db, NULL, dev_probe_gatt_profile,
> -                                                                       &data);
> -
> -       device_add_uuids(device, data.uuids);
> -       g_slist_free_full(data.uuids, g_free);
> +       gatt_db_foreach_service(device->db, NULL, probe_gatt_profile, device);
>  }
>
>  static void device_accept_gatt_profiles(struct btd_device *device)
> @@ -3028,9 +2954,7 @@ static void gatt_service_added(struct gatt_db_attribute *attr, void *user_data)
>                         service_accept(l->data);
>         }
>
> -       device_probe_gatt_profile(device, attr);
> -
> -       store_device_info(device);
> +       btd_device_add_uuid(device, uuid_str);
>
>         btd_gatt_client_service_added(device->client_dbus, attr);
>
> @@ -3645,45 +3569,52 @@ struct probe_data {
>         GSList *uuids;
>  };
>
> -static void dev_probe(struct btd_profile *p, void *user_data)
> +static struct btd_service *probe_service(struct btd_device *device,
> +                                               struct btd_profile *profile,
> +                                               GSList *uuids)
>  {
> -       struct probe_data *d = user_data;
>         struct btd_service *service;
>
> -       if (p->device_probe == NULL)
> -               return;
> +       if (profile->device_probe == NULL)
> +               return NULL;
>
> -       if (!device_match_profile(d->dev, p, d->uuids))
> -               return;
> +       if (!device_match_profile(device, profile, uuids))
> +               return NULL;
>
> -       service = service_create(d->dev, p);
> +       service = service_create(device, profile);
>
> -       if (service_probe(service) < 0) {
> +       if (service_probe(service)) {
>                 btd_service_unref(service);
> -               return;
> +               return NULL;
>         }
>
> -       d->dev->services = g_slist_append(d->dev->services, service);
> +       if (profile->auto_connect)
> +               device_set_auto_connect(device, TRUE);
> +
> +       return service;
>  }
>
> -void device_probe_profile(gpointer a, gpointer b)
> +static void dev_probe(struct btd_profile *p, void *user_data)
>  {
> -       struct btd_device *device = a;
> -       struct btd_profile *profile = b;
> +       struct probe_data *d = user_data;
>         struct btd_service *service;
>
> -       if (profile->device_probe == NULL)
> +       service = probe_service(d->dev, p, d->uuids);
> +       if (!service)
>                 return;
>
> -       if (!device_match_profile(device, profile, device->uuids))
> -               return;
> +       d->dev->services = g_slist_append(d->dev->services, service);
> +}
>
> -       service = service_create(device, profile);
> +void device_probe_profile(gpointer a, gpointer b)
> +{
> +       struct btd_device *device = a;
> +       struct btd_profile *profile = b;
> +       struct btd_service *service;
>
> -       if (service_probe(service) < 0) {
> -               btd_service_unref(service);
> +       service = probe_service(device, profile, device->uuids);
> +       if (!service)
>                 return;
> -       }
>
>         device->services = g_slist_append(device->services, service);
>
> diff --git a/src/gatt-database.c b/src/gatt-database.c
> index 97cef77..774b19e 100644
> --- a/src/gatt-database.c
> +++ b/src/gatt-database.c
> @@ -43,6 +43,7 @@
>  #include "gatt-database.h"
>  #include "dbus-common.h"
>  #include "profile.h"
> +#include "service.h"
>
>  #ifndef ATT_CID
>  #define ATT_CID 4
> @@ -1074,7 +1075,7 @@ static void client_disconnect_cb(DBusConnection *conn, void *user_data)
>         service_remove_helper(user_data);
>  }
>
> -static void service_remove(void *data)
> +static void remove_service(void *data)
>  {
>         struct external_service *service = data;
>
> @@ -1453,7 +1454,7 @@ static void proxy_removed_cb(GDBusProxy *proxy, void *user_data)
>
>         DBG("Proxy removed - removing service: %s", service->path);
>
> -       service_remove(service);
> +       remove_service(service);
>  }
>
>  static bool parse_uuid(GDBusProxy *proxy, bt_uuid_t *uuid)
> @@ -2142,10 +2143,10 @@ reply:
>         service->reg = NULL;
>
>         if (fail)
> -               service_remove(service);
> +               remove_service(service);
>  }
>
> -static struct external_service *service_create(DBusConnection *conn,
> +static struct external_service *create_service(DBusConnection *conn,
>                                         DBusMessage *msg, const char *path)
>  {
>         struct external_service *service;
> @@ -2223,7 +2224,7 @@ static DBusMessage *manager_register_service(DBusConnection *conn,
>         if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
>                 return btd_error_invalid_args(msg);
>
> -       service = service_create(conn, msg, path);
> +       service = create_service(conn, msg, path);
>         if (!service)
>                 return btd_error_failed(msg, "Failed to register service");
>
> @@ -2279,6 +2280,22 @@ static void profile_exited(DBusConnection *conn, void *user_data)
>         profile_free(profile);
>  }
>
> +static int profile_device_probe(struct btd_service *service)
> +{
> +       struct btd_profile *p = btd_service_get_profile(service);
> +
> +       DBG("%s probed", p->name);
> +
> +       return 0;
> +}
> +
> +static void profile_device_remove(struct btd_service *service)
> +{
> +       struct btd_profile *p = btd_service_get_profile(service);
> +
> +       DBG("%s removed", p->name);
> +}
> +
>  static int profile_add(struct external_profile *profile, const char *uuid)
>  {
>         struct btd_profile *p;
> @@ -2302,7 +2319,10 @@ static int profile_add(struct external_profile *profile, const char *uuid)
>                 return -ENOMEM;
>         }
>
> +       p->device_probe = profile_device_probe;
> +       p->device_remove = profile_device_remove;
>         p->auto_connect = true;
> +       p->external = true;
>
>         queue_push_tail(profile->profiles, p);
>
> diff --git a/src/profile.c b/src/profile.c
> index f54749e..70ee4c1 100644
> --- a/src/profile.c
> +++ b/src/profile.c
> @@ -719,13 +719,19 @@ void btd_profile_foreach(void (*func)(struct btd_profile *p, void *data),
>
>  int btd_profile_register(struct btd_profile *profile)
>  {
> -       profiles = g_slist_append(profiles, profile);
> +       if (profile->external)
> +               ext_profiles = g_slist_append(ext_profiles, profile);
> +       else
> +               profiles = g_slist_append(profiles, profile);
>         return 0;
>  }
>
>  void btd_profile_unregister(struct btd_profile *profile)
>  {
> -       profiles = g_slist_remove(profiles, profile);
> +       if (profile->external)
> +               ext_profiles = g_slist_remove(ext_profiles, profile);
> +       else
> +               profiles = g_slist_remove(profiles, profile);
>  }
>
>  static struct ext_profile *find_ext_profile(const char *owner,
> @@ -2291,6 +2297,7 @@ static struct ext_profile *create_ext(const char *owner, const char *path,
>         p->name = ext->name;
>         p->local_uuid = ext->service ? ext->service : ext->uuid;
>         p->remote_uuid = ext->remote_uuid;
> +       p->external = true;
>
>         if (ext->enable_server) {
>                 p->adapter_probe = ext_adapter_probe;
> diff --git a/src/profile.h b/src/profile.h
> index f5a3ded..4448a2a 100644
> --- a/src/profile.h
> +++ b/src/profile.h
> @@ -35,6 +35,7 @@ struct btd_profile {
>         const char *remote_uuid;
>
>         bool auto_connect;
> +       bool external;
>
>         int (*device_probe) (struct btd_service *service);
>         void (*device_remove) (struct btd_service *service);
> --
> 2.4.3

Applied.


-- 
Luiz Augusto von Dentz
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[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