From: zzhang0 <[email protected]>

In current connman implementation, when we turn on/off airplane mode
quickly, sometimes, it may lead to device status conflict.
For example, initial status is airplane mode off, bluetooth device on,
then when we turn on/off airplane mode qucikly, bluetooth device will be
enabled and disabled according to it. But the bluetooth enable/disable
operation is asynchronous, in some time, for example if the device is in
the progress of powering on but not powered completed yet, then turn on
airplane mode, which means to disable the bluetooth device, connman will
treat it as the same device status and ignore the operation,
then the status would be turned to airplane mode on, bluetooth device on,
which can't keep consistent with the initial status.

This patch is trying to fix this issue, and the solution is when the device
is in powering progress, forbid upper layer to call manager dbus interface
to set "OfflineMode" properity.

---
 src/connman.h |    2 ++
 src/device.c  |   29 +++++++++++++++++++++++++++++
 src/manager.c |    4 ++++
 3 files changed, 35 insertions(+), 0 deletions(-)
 mode change 100644 => 100755 src/connman.h
 mode change 100644 => 100755 src/device.c
 mode change 100644 => 100755 src/manager.c

diff --git a/src/connman.h b/src/connman.h
old mode 100644
new mode 100755
index fd67cf2..4c1b7a4
--- a/src/connman.h
+++ b/src/connman.h
@@ -401,6 +401,8 @@ const char *__connman_device_get_type(struct connman_device 
*device);
 
 int __connman_device_set_offlinemode(connman_bool_t offlinemode);
 
+connman_bool_t __connman_device_is_powered_pending();
+
 #include <connman/network.h>
 
 int __connman_network_init(void);
diff --git a/src/device.c b/src/device.c
old mode 100644
new mode 100755
index ed0eaf2..abf461f
--- a/src/device.c
+++ b/src/device.c
@@ -1021,6 +1021,35 @@ int __connman_device_set_offlinemode(connman_bool_t 
offlinemode)
        return 0;
 }
 
+static connman_bool_t device_get_powered_pending_state(
+                                               struct connman_element *element,
+                                               gpointer user_data)
+{
+       struct connman_device *device = element->device;
+       connman_bool_t *powered_pending = GPOINTER_TO_UINT(user_data);
+
+       if (device == NULL)
+               return FALSE;
+
+       if (device->powered != device->powered_pending) {
+               DBG("Now device is powering on/off");
+               *powered_pending = TRUE;
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+connman_bool_t __connman_device_is_powered_pending(void)
+{
+       DBG("");
+       connman_bool_t powered_pending = FALSE;
+       __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_DEVICE,
+                                       device_get_powered_pending_state,
+                                       GUINT_TO_POINTER(&powered_pending));
+
+       return powered_pending;
+}
+
 void __connman_device_increase_connections(struct connman_device *device)
 {
        if (device == NULL)
diff --git a/src/manager.c b/src/manager.c
old mode 100644
new mode 100755
index 4fd966a..5c642b4
--- a/src/manager.c
+++ b/src/manager.c
@@ -113,6 +113,10 @@ static DBusMessage *set_property(DBusConnection *conn,
 
                if (type != DBUS_TYPE_BOOLEAN)
                        return __connman_error_invalid_arguments(msg);
+               if (__connman_device_is_powered_pending() == TRUE) {
+                       DBG("device is powering, forbid to set offline mode!");
+                       return __connman_error_permission_denied(msg);
+               }
 
                dbus_message_iter_get_basic(&value, &offlinemode);
 
-- 
1.6.3.3

_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to