Re: [PATCH BlueZ] adapter: Fix not waiting for start discovery result

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

 



Hi Sonny,

On Wed, Sep 13, 2017 at 12:54 AM, Sonny Sasaka <sonnysasaka@xxxxxxxxxxxx> wrote:
> Hi Luiz,
>
> Thank you for the patch. However I see that the patch doesn't address
> the case where start discovery happens during stop discovery (after
> stop_discovery but before stop_discovery_complete).

I would considered this a different problem, but yes either multiple
starts or start/stop in a sequence may cause the states to be out of
sync so it needs fixing.

> On Sun, Sep 10, 2017 at 12:24 PM, Luiz Augusto von Dentz
> <luiz.dentz@xxxxxxxxx> wrote:
>> Hi,
>>
>> On Thu, Sep 7, 2017 at 2:59 PM, Luiz Augusto von Dentz
>> <luiz.dentz@xxxxxxxxx> wrote:
>>> From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>
>>>
>>> We should not reply until the start discovery completes otherwise
>>> clients may attempt to stop the discovery before it even has started.
>>>
>>> On top of this it will now block clients so they so not be able to
>>> queue more requests.
>>> ---
>>>  src/adapter.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++--------
>>>  1 file changed, 47 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/src/adapter.c b/src/adapter.c
>>> index a571b1870..4b9f5a1cd 100644
>>> --- a/src/adapter.c
>>> +++ b/src/adapter.c
>>> @@ -160,6 +160,7 @@ struct discovery_filter {
>>>
>>>  struct watch_client {
>>>         struct btd_adapter *adapter;
>>> +       DBusMessage *msg;
>>>         char *owner;
>>>         guint watch;
>>>         struct discovery_filter *discovery_filter;
>>> @@ -1421,13 +1422,17 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
>>>                                         const void *param, void *user_data)
>>>  {
>>>         struct btd_adapter *adapter = user_data;
>>> +       struct watch_client *client = adapter->discovery_list->data;
>>>         const struct mgmt_cp_start_discovery *rp = param;
>>> +       DBusMessage *reply;
>>>
>>>         DBG("status 0x%02x", status);
>>>
>>>         if (length < sizeof(*rp)) {
>>>                 btd_error(adapter->dev_id,
>>>                         "Wrong size of start discovery return parameters");
>>> +               if (client->msg)
>>> +                       goto fail;
>>>                 return;
>>>         }
>>>
>>> @@ -1440,6 +1445,14 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
>>>                 else
>>>                         adapter->filtered_discovery = false;
>>>
>>> +               if (client->msg) {
>>> +                       reply = g_dbus_create_reply(client->msg,
>>> +                                                       DBUS_TYPE_INVALID);
>>> +                       g_dbus_send_message(dbus_conn, reply);
>>> +                       dbus_message_unref(client->msg);
>>> +                       client->msg = NULL;
>>> +               }
>>> +
>>>                 if (adapter->discovering)
>>>                         return;
>>>
>>> @@ -1449,6 +1462,15 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
>>>                 return;
>>>         }
>>>
>>> +fail:
>>> +       /* Reply with an error if the first discovery has failed */
>>> +       if (client->msg) {
>>> +               reply = btd_error_busy(client->msg);
>>> +               g_dbus_send_message(dbus_conn, reply);
>>> +               g_dbus_remove_watch(dbus_conn, client->watch);
>>> +               return;
>>> +       }
>>> +
>>>         /*
>>>          * In case the restart of the discovery failed, then just trigger
>>>          * it for the next idle timeout again.
>>> @@ -1933,7 +1955,7 @@ static bool filters_equal(struct mgmt_cp_start_service_discovery *a,
>>>         return true;
>>>  }
>>>
>>> -static void update_discovery_filter(struct btd_adapter *adapter)
>>> +static int update_discovery_filter(struct btd_adapter *adapter)
>>>  {
>>>         struct mgmt_cp_start_service_discovery *sd_cp;
>>>
>>> @@ -1942,7 +1964,7 @@ static void update_discovery_filter(struct btd_adapter *adapter)
>>>         if (discovery_filter_to_mgmt_cp(adapter, &sd_cp)) {
>>>                 btd_error(adapter->dev_id,
>>>                                 "discovery_filter_to_mgmt_cp returned error");
>>> -               return;
>>> +               return -ENOMEM;
>>>         }
>>>
>>>         /*
>>> @@ -1953,13 +1975,15 @@ static void update_discovery_filter(struct btd_adapter *adapter)
>>>             adapter->discovering != 0) {
>>>                 DBG("filters were equal, deciding to not restart the scan.");
>>>                 g_free(sd_cp);
>>> -               return;
>>> +               return 0;
>>>         }
>>>
>>>         g_free(adapter->current_discovery_filter);
>>>         adapter->current_discovery_filter = sd_cp;
>>>
>>>         trigger_start_discovery(adapter, 0);
>>> +
>>> +       return -EINPROGRESS;
>>>  }
>>>
>>>  static void discovery_destroy(void *user_data)
>>> @@ -1980,6 +2004,9 @@ static void discovery_destroy(void *user_data)
>>>                 client->discovery_filter = NULL;
>>>         }
>>>
>>> +       if (client->msg)
>>> +               dbus_message_unref(client->msg);
>>> +
>>>         g_free(client->owner);
>>>         g_free(client);
>>>
>>> @@ -2087,6 +2114,7 @@ static DBusMessage *start_discovery(DBusConnection *conn,
>>>         const char *sender = dbus_message_get_sender(msg);
>>>         struct watch_client *client;
>>>         bool is_discovering;
>>> +       int err;
>>>
>>>         DBG("sender %s", sender);
>>>
>>> @@ -2107,12 +2135,14 @@ static DBusMessage *start_discovery(DBusConnection *conn,
>>>          * and trigger scan.
>>>          */
>>>         if (client) {
>>> +               if (client->msg)
>>> +                       return btd_error_busy(msg);
>>> +
>>>                 adapter->set_filter_list = g_slist_remove(
>>>                                              adapter->set_filter_list, client);
>>>                 adapter->discovery_list = g_slist_prepend(
>>>                                               adapter->discovery_list, client);
>>> -               update_discovery_filter(adapter);
>>> -               return dbus_message_new_method_return(msg);
>>> +               goto done;
>>>         }
>>>
>>>         client = g_new0(struct watch_client, 1);
>>> @@ -2126,14 +2156,23 @@ static DBusMessage *start_discovery(DBusConnection *conn,
>>>         adapter->discovery_list = g_slist_prepend(adapter->discovery_list,
>>>                                                                 client);
>>>
>>> +done:
>>>         /*
>>>          * Just trigger the discovery here. In case an already running
>>>          * discovery in idle phase exists, it will be restarted right
>>>          * away.
>>>          */
>>> -       update_discovery_filter(adapter);
>>> +       err = update_discovery_filter(adapter);
>>> +       if (!err)
>>> +               return dbus_message_new_method_return(msg);
>>>
>>> -       return dbus_message_new_method_return(msg);
>>> +       /* If the discovery has to be started wait it complete to reply */
>>> +       if (err == -EINPROGRESS) {
>>> +               client->msg = dbus_message_ref(msg);
>>> +               return NULL;
>>> +       }
>>> +
>>> +       return btd_error_failed(msg, strerror(-err));
>>>  }
>>>
>>>  static bool parse_uuids(DBusMessageIter *value, struct discovery_filter *filter)
>>> @@ -2984,7 +3023,7 @@ static DBusMessage *get_discovery_filters(DBusConnection *conn,
>>>  }
>>>
>>>  static const GDBusMethodTable adapter_methods[] = {
>>> -       { GDBUS_METHOD("StartDiscovery", NULL, NULL, start_discovery) },
>>> +       { GDBUS_ASYNC_METHOD("StartDiscovery", NULL, NULL, start_discovery) },
>>>         { GDBUS_METHOD("SetDiscoveryFilter",
>>>                                 GDBUS_ARGS({ "properties", "a{sv}" }), NULL,
>>>                                 set_discovery_filter) },
>>> --
>>> 2.13.5
>>
>> Could you guys please check if this does address the problem you are having?
>>
>>
>> --
>> Luiz Augusto von Dentz



-- 
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