On ConnMan starting, the device block state will be recored using update_rfkill_state(). And at following device detection stage, before enable the device, __connman_udev_get_blocked() should be used to check the block state. If the device is blocked, it should not be enable. That can avoid unnecessary enable and disable operation and racy issue. --- src/connman.h | 1 + src/device.c | 3 ++ src/udev-compat.c | 5 ++++ src/udev.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 0 deletions(-)
diff --git a/src/connman.h b/src/connman.h index a6619df..a704027 100644 --- a/src/connman.h +++ b/src/connman.h @@ -265,6 +265,7 @@ char *__connman_udev_get_devtype(const char *ifname); char *__connman_udev_get_mbm_devnode(const char *ifname); void __connman_udev_rfkill(const char *sysname, connman_bool_t blocked); void __connman_udev_enable_rfkill_processing(void); +connman_bool_t __connman_udev_get_blocked(int phyindex); #include <connman/device.h> diff --git a/src/device.c b/src/device.c index 0d41863..875b197 100644 --- a/src/device.c +++ b/src/device.c @@ -545,6 +545,9 @@ static int setup_device(struct connman_device *device) break; } + if (__connman_udev_get_blocked(device->phyindex) == TRUE) + return 0; + if (device->offlinemode == FALSE && device->powered_persistent == TRUE) __connman_device_enable(device); diff --git a/src/udev-compat.c b/src/udev-compat.c index 70cc3bb..1156705 100644 --- a/src/udev-compat.c +++ b/src/udev-compat.c @@ -127,6 +127,11 @@ void __connman_udev_rfkill(const char *sysname, connman_bool_t blocked) DBG("sysname %s blocked %d", sysname, blocked); } +connman_bool_t __connman_udev_get_blocked(int phyindex) +{ + return FALSE; +} + int __connman_udev_init(void) { DBG(""); diff --git a/src/udev.c b/src/udev.c index 59f36ea..676fe6f 100644 --- a/src/udev.c +++ b/src/udev.c @@ -155,6 +155,56 @@ static void remove_net_device(struct udev_device *udev_device) connman_device_unref(device); } +static GSList *rfkill_list = NULL; + +struct rfkill_data { + int phyindex; + connman_bool_t blocked; +}; + +connman_bool_t __connman_udev_get_blocked(int phyindex) +{ + GSList *list; + + if (phyindex < 0) + return FALSE; + + for (list = rfkill_list; list; list = rfkill_list->next) { + struct rfkill_data *block = list->data; + + if (block->phyindex == phyindex) + return block->blocked; + } + + return FALSE; +} + +static void update_rfkill_state(int phyindex, connman_bool_t blocked) +{ + GSList *list; + struct rfkill_data *block; + + DBG("index %d blocked %d", phyindex, blocked); + + for (list = rfkill_list; list; list = rfkill_list->next) { + block = list->data; + + if (block->phyindex == phyindex) { + block->blocked = blocked; + return; + } + } + + block = g_try_new0(struct rfkill_data, 1); + if (block == NULL) + return; + + block->phyindex = phyindex; + block->blocked = blocked; + + rfkill_list = g_slist_prepend(rfkill_list, block); +} + static void phyindex_rfkill(int phyindex, connman_bool_t blocked) { GSList *list; @@ -162,6 +212,8 @@ static void phyindex_rfkill(int phyindex, connman_bool_t blocked) if (phyindex < 0) return; + update_rfkill_state(phyindex, blocked); + for (list = device_list; list; list = list->next) { struct connman_device *device = list->data; @@ -543,6 +595,14 @@ void __connman_udev_cleanup(void) g_slist_free(device_list); device_list = NULL; + for (list = rfkill_list; list; list = list->next) { + struct rfkill_data *block = list->data; + g_free(block); + } + + g_slist_free(rfkill_list); + rfkill_list = NULL; + if (udev_ctx == NULL) return; -- 1.6.1.3 _______________________________________________ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman