Re: [PATCH BlueZ 1/2] advertising: Allow changes to properties

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

 



Hi,

On Tue, Aug 15, 2017 at 11:18 AM, Luiz Augusto von Dentz
<luiz.dentz@xxxxxxxxx> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>
>
> This enables the application to change the advertising object instead of
> having it unregistered and registered once again.
> ---
>  src/advertising.c | 156 +++++++++++++++++++++++++++++-------------------------
>  1 file changed, 85 insertions(+), 71 deletions(-)
>
> diff --git a/src/advertising.c b/src/advertising.c
> index 9eb22b9fd..f125ca5c8 100644
> --- a/src/advertising.c
> +++ b/src/advertising.c
> @@ -21,6 +21,7 @@
>
>  #include <stdint.h>
>  #include <stdbool.h>
> +#include <errno.h>
>
>  #include <dbus/dbus.h>
>  #include <gdbus/gdbus.h>
> @@ -468,6 +469,7 @@ static bool parse_local_name(DBusMessageIter *iter,
>
>         dbus_message_iter_get_basic(iter, &name);
>
> +       free(client->name);
>         client->name = strdup(name);
>
>         return true;
> @@ -504,58 +506,6 @@ static struct adv_parser {
>         { },
>  };
>
> -static void add_client_complete(struct btd_adv_client *client, uint8_t status)
> -{
> -       DBusMessage *reply;
> -
> -       if (status) {
> -               error("Failed to add advertisement: %s (0x%02x)",
> -                                               mgmt_errstr(status), status);
> -               reply = btd_error_failed(client->reg,
> -                                       "Failed to register advertisement");
> -               queue_remove(client->manager->clients, client);
> -               g_idle_add(client_free_idle_cb, client);
> -
> -       } else
> -               reply = dbus_message_new_method_return(client->reg);
> -
> -       g_dbus_send_message(btd_get_dbus_connection(), reply);
> -       dbus_message_unref(client->reg);
> -       client->reg = NULL;
> -}
> -
> -static void add_adv_callback(uint8_t status, uint16_t length,
> -                                         const void *param, void *user_data)
> -{
> -       struct btd_adv_client *client = user_data;
> -       const struct mgmt_rp_add_advertising *rp = param;
> -
> -       if (status)
> -               goto done;
> -
> -       if (!param || length < sizeof(*rp)) {
> -               status = MGMT_STATUS_FAILED;
> -               goto done;
> -       }
> -
> -       client->instance = rp->instance;
> -
> -       g_dbus_client_set_disconnect_watch(client->client, client_disconnect_cb,
> -                                                                       client);
> -       DBG("Advertisement registered: %s", client->path);
> -
> -       g_dbus_emit_property_changed(btd_get_dbus_connection(),
> -                               adapter_get_path(client->manager->adapter),
> -                               LE_ADVERTISING_MGR_IFACE, "SupportedInstances");
> -
> -       g_dbus_emit_property_changed(btd_get_dbus_connection(),
> -                               adapter_get_path(client->manager->adapter),
> -                               LE_ADVERTISING_MGR_IFACE, "ActiveInstances");
> -
> -done:
> -       add_client_complete(client, status);
> -}
> -
>  static size_t calc_max_adv_len(struct btd_adv_client *client, uint32_t flags)
>  {
>         size_t max = client->manager->max_adv_len;
> @@ -619,7 +569,7 @@ static uint8_t *generate_scan_rsp(struct btd_adv_client *client,
>         return bt_ad_generate(client->scan, len);
>  }
>
> -static DBusMessage *refresh_advertisement(struct btd_adv_client *client)
> +static int refresh_adv(struct btd_adv_client *client, mgmt_request_func_t func)
>  {
>         struct mgmt_cp_add_advertising *cp;
>         uint8_t param_len;
> @@ -639,33 +589,24 @@ static DBusMessage *refresh_advertisement(struct btd_adv_client *client)
>         adv_data = generate_adv_data(client, &flags, &adv_data_len);
>         if (!adv_data || (adv_data_len > calc_max_adv_len(client, flags))) {
>                 error("Advertising data too long or couldn't be generated.");
> -
> -               return g_dbus_create_error(client->reg, ERROR_INTERFACE
> -                                               ".InvalidLength",
> -                                               "Advertising data too long.");
> +               return -EINVAL;
>         }
>
>         scan_rsp = generate_scan_rsp(client, &flags, &scan_rsp_len);
>         if (!scan_rsp && scan_rsp_len) {
>                 error("Scan data couldn't be generated.");
> -
> -               return g_dbus_create_error(client->reg, ERROR_INTERFACE
> -                                               ".InvalidLength",
> -                                               "Advertising data too long.");
> +               return -EINVAL;
>         }
>
>         param_len = sizeof(struct mgmt_cp_add_advertising) + adv_data_len +
>                                                         scan_rsp_len;
>
>         cp = malloc0(param_len);
> -
>         if (!cp) {
>                 error("Couldn't allocate for MGMT!");
> -
>                 free(adv_data);
>                 free(scan_rsp);
> -
> -               return btd_error_failed(client->reg, "Failed");
> +               return -ENOMEM;
>         }
>
>         cp->flags = htobl(flags);
> @@ -680,22 +621,93 @@ static DBusMessage *refresh_advertisement(struct btd_adv_client *client)
>
>         if (!mgmt_send(client->manager->mgmt, MGMT_OP_ADD_ADVERTISING,
>                                 client->manager->mgmt_index, param_len, cp,
> -                               add_adv_callback, client, NULL)) {
> +                               func, client, NULL)) {
>                 error("Failed to add Advertising Data");
> -
>                 free(cp);
> -
> -               return btd_error_failed(client->reg, "Failed");
> +               return -EINVAL;
>         }
>
>         free(cp);
>
> -       return NULL;
> +       return 0;
> +}
> +
> +static void properties_changed(GDBusProxy *proxy, const char *name,
> +                                       DBusMessageIter *iter, void *user_data)
> +{
> +       struct btd_adv_client *client = user_data;
> +       struct adv_parser *parser;
> +
> +       for (parser = parsers; parser && parser->name; parser++) {
> +               if (strcmp(parser->name, name))
> +                       continue;
> +
> +               if (parser->func(iter, client)) {
> +                       refresh_adv(client, NULL);
> +                       break;
> +               }
> +       }
> +}
> +
> +static void add_client_complete(struct btd_adv_client *client, uint8_t status)
> +{
> +       DBusMessage *reply;
> +
> +       if (status) {
> +               error("Failed to add advertisement: %s (0x%02x)",
> +                                               mgmt_errstr(status), status);
> +               reply = btd_error_failed(client->reg,
> +                                       "Failed to register advertisement");
> +               queue_remove(client->manager->clients, client);
> +               g_idle_add(client_free_idle_cb, client);
> +
> +       } else
> +               reply = dbus_message_new_method_return(client->reg);
> +
> +       g_dbus_send_message(btd_get_dbus_connection(), reply);
> +       dbus_message_unref(client->reg);
> +       client->reg = NULL;
> +}
> +
> +static void add_adv_callback(uint8_t status, uint16_t length,
> +                                         const void *param, void *user_data)
> +{
> +       struct btd_adv_client *client = user_data;
> +       const struct mgmt_rp_add_advertising *rp = param;
> +
> +       if (status)
> +               goto done;
> +
> +       if (!param || length < sizeof(*rp)) {
> +               status = MGMT_STATUS_FAILED;
> +               goto done;
> +       }
> +
> +       client->instance = rp->instance;
> +
> +       g_dbus_client_set_disconnect_watch(client->client, client_disconnect_cb,
> +                                                                       client);
> +       DBG("Advertisement registered: %s", client->path);
> +
> +       g_dbus_emit_property_changed(btd_get_dbus_connection(),
> +                               adapter_get_path(client->manager->adapter),
> +                               LE_ADVERTISING_MGR_IFACE, "SupportedInstances");
> +
> +       g_dbus_emit_property_changed(btd_get_dbus_connection(),
> +                               adapter_get_path(client->manager->adapter),
> +                               LE_ADVERTISING_MGR_IFACE, "ActiveInstances");
> +
> +       g_dbus_proxy_set_property_watch(client->proxy, properties_changed,
> +                                                               client);
> +
> +done:
> +       add_client_complete(client, status);
>  }
>
>  static DBusMessage *parse_advertisement(struct btd_adv_client *client)
>  {
>         struct adv_parser *parser;
> +       int err;
>
>         for (parser = parsers; parser && parser->name; parser++) {
>                 DBusMessageIter iter;
> @@ -710,7 +722,9 @@ static DBusMessage *parse_advertisement(struct btd_adv_client *client)
>                 }
>         }
>
> -       return refresh_advertisement(client);
> +       err = refresh_adv(client, add_adv_callback);
> +       if (!err)
> +               return NULL;
>
>  fail:
>         return btd_error_failed(client->reg, "Failed to parse advertisement.");
> --
> 2.13.4

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