X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Ftechnology.c;h=8166d17c763172c14d493f66ac2039acbc340658;hb=35f61b1f8f53033a7333b56be18328d426dc24a1;hp=345dcabd6937442dd1221579d3a5e1b0b5a481aa;hpb=6e77ce0d8cd265c2a5bb438a9487a479f2991753;p=platform%2Fupstream%2Fconnman.git diff --git a/src/technology.c b/src/technology.c index 345dcab..8166d17 100644 --- a/src/technology.c +++ b/src/technology.c @@ -55,7 +55,7 @@ struct connman_technology { enum connman_service_type type; char *path; GSList *device_list; - int enabled; + connman_bool_t enabled; char *regdom; connman_bool_t connected; @@ -223,6 +223,10 @@ static int set_tethering(struct connman_technology *technology, technology->driver->set_tethering == NULL) return -EOPNOTSUPP; + __sync_synchronize(); + if (technology->enabled == FALSE) + return -EACCES; + bridge = __connman_tethering_get_bridge(); if (bridge == NULL) return -EOPNOTSUPP; @@ -304,8 +308,6 @@ static const char *get_name(enum connman_service_type type) return "Wired"; case CONNMAN_SERVICE_TYPE_WIFI: return "WiFi"; - case CONNMAN_SERVICE_TYPE_WIMAX: - return "WiMAX"; case CONNMAN_SERVICE_TYPE_BLUETOOTH: return "Bluetooth"; case CONNMAN_SERVICE_TYPE_CELLULAR: @@ -454,7 +456,6 @@ static void append_properties(DBusMessageIter *iter, { DBusMessageIter dict; const char *str; - connman_bool_t powered; connman_dbus_dict_open(iter, &dict); @@ -469,12 +470,9 @@ static void append_properties(DBusMessageIter *iter, DBUS_TYPE_STRING, &str); __sync_synchronize(); - if (technology->enabled > 0) - powered = TRUE; - else - powered = FALSE; connman_dbus_dict_append_basic(&dict, "Powered", - DBUS_TYPE_BOOLEAN, &powered); + DBUS_TYPE_BOOLEAN, + &technology->enabled); connman_dbus_dict_append_basic(&dict, "Connected", DBUS_TYPE_BOOLEAN, @@ -486,13 +484,13 @@ static void append_properties(DBusMessageIter *iter, if (technology->tethering_ident != NULL) connman_dbus_dict_append_basic(&dict, "TetheringIdentifier", - DBUS_TYPE_STRING, - &technology->tethering_ident); + DBUS_TYPE_STRING, + &technology->tethering_ident); if (technology->tethering_passphrase != NULL) connman_dbus_dict_append_basic(&dict, "TetheringPassphrase", - DBUS_TYPE_STRING, - &technology->tethering_passphrase); + DBUS_TYPE_STRING, + &technology->tethering_passphrase); connman_dbus_dict_close(iter, &dict); } @@ -600,33 +598,29 @@ static int technology_affect_devices(struct connman_technology *technology, return err; } -static int technology_enable(struct connman_technology *technology, - connman_bool_t hardblock) +static int technology_enable(struct connman_technology *technology) { DBG("technology %p enable", technology); __sync_synchronize(); - if (technology->enabled > 0) + if (technology->enabled == TRUE) return -EALREADY; if (technology->pending_reply != NULL) return -EBUSY; - if (hardblock == TRUE && technology->enable_persistent == FALSE) - return 0; - - __connman_rfkill_block(technology->type, FALSE); + if (technology->rfkill_driven == TRUE) + return __connman_rfkill_block(technology->type, FALSE); return technology_affect_devices(technology, TRUE); } -static int technology_disable(struct connman_technology *technology, - connman_bool_t hardblock) +static int technology_disable(struct connman_technology *technology) { DBG("technology %p disable", technology); __sync_synchronize(); - if (technology->enabled == 0) + if (technology->enabled == FALSE) return -EALREADY; if (technology->pending_reply != NULL) @@ -635,8 +629,8 @@ static int technology_disable(struct connman_technology *technology, if (technology->tethering == TRUE) set_tethering(technology, FALSE); - if (hardblock == FALSE) - __connman_rfkill_block(technology->type, TRUE); + if (technology->rfkill_driven == TRUE) + return __connman_rfkill_block(technology->type, TRUE); return technology_affect_devices(technology, FALSE); } @@ -653,9 +647,9 @@ static DBusMessage *set_powered(struct connman_technology *technology, } if (powered == TRUE) - err = technology_enable(technology, FALSE); + err = technology_enable(technology); else - err = technology_disable(technology, FALSE); + err = technology_disable(technology); if (err != -EBUSY) { technology->enable_persistent = powered; @@ -928,7 +922,7 @@ static const GDBusSignalTable technology_signals[] = { static gboolean technology_dbus_register(struct connman_technology *technology) { if (technology->dbus_registered == TRUE || - (technology->rfkill_driven && + (technology->rfkill_driven == TRUE && technology->hardblocked == TRUE)) return TRUE; @@ -990,11 +984,7 @@ static struct connman_technology *technology_get(enum connman_service_type type) technology->rfkill_driven = FALSE; technology->softblocked = FALSE; - - if (type == CONNMAN_SERVICE_TYPE_ETHERNET) - technology->hardblocked = FALSE; - else - technology->hardblocked = TRUE; + technology->hardblocked = FALSE; technology->type = type; technology->path = g_strdup_printf("%s/technology/%s", @@ -1073,7 +1063,6 @@ void __connman_technology_add_interface(enum connman_service_type type, return; case CONNMAN_SERVICE_TYPE_ETHERNET: case CONNMAN_SERVICE_TYPE_WIFI: - case CONNMAN_SERVICE_TYPE_WIMAX: case CONNMAN_SERVICE_TYPE_BLUETOOTH: case CONNMAN_SERVICE_TYPE_CELLULAR: case CONNMAN_SERVICE_TYPE_GPS: @@ -1106,7 +1095,6 @@ void __connman_technology_remove_interface(enum connman_service_type type, return; case CONNMAN_SERVICE_TYPE_ETHERNET: case CONNMAN_SERVICE_TYPE_WIFI: - case CONNMAN_SERVICE_TYPE_WIMAX: case CONNMAN_SERVICE_TYPE_BLUETOOTH: case CONNMAN_SERVICE_TYPE_CELLULAR: case CONNMAN_SERVICE_TYPE_GPS: @@ -1148,9 +1136,18 @@ int __connman_technology_add_device(struct connman_device *device) return -ENXIO; } - if (technology->enable_persistent && - global_offlinemode == FALSE && - technology->hardblocked == FALSE) { + __sync_synchronize(); + if (technology->rfkill_driven == TRUE) { + if (technology->enabled == TRUE) + __connman_device_enable(device); + else + __connman_device_disable(device); + + goto done; + } + + if (technology->enable_persistent == TRUE && + global_offlinemode == FALSE) { int err = __connman_device_enable(device); /* * connman_technology_add_device() calls __connman_device_enable() @@ -1161,11 +1158,11 @@ int __connman_technology_add_device(struct connman_device *device) if (err == -EALREADY) __connman_technology_enabled(type); } - /* if technology persistent state is offline or hardblocked */ - if (technology->enable_persistent == FALSE || - technology->hardblocked == TRUE) + /* if technology persistent state is offline */ + if (technology->enable_persistent == FALSE) __connman_device_disable(device); +done: technology->device_list = g_slist_prepend(technology->device_list, device); @@ -1197,13 +1194,8 @@ int __connman_technology_remove_device(struct connman_device *device) static void powered_changed(struct connman_technology *technology) { - connman_bool_t powered; - - __sync_synchronize(); - if (technology->enabled > 0) - powered = TRUE; - else - powered = FALSE; + if (technology->dbus_registered == FALSE) + return; if (technology->pending_reply != NULL) { g_dbus_send_reply(connection, @@ -1215,16 +1207,20 @@ static void powered_changed(struct connman_technology *technology) technology->pending_timeout = 0; } + __sync_synchronize(); connman_dbus_property_changed_basic(technology->path, CONNMAN_TECHNOLOGY_INTERFACE, "Powered", - DBUS_TYPE_BOOLEAN, &powered); + DBUS_TYPE_BOOLEAN, &technology->enabled); } static int technology_enabled(struct connman_technology *technology) { - if (__sync_fetch_and_add(&technology->enabled, 1) != 0) + __sync_synchronize(); + if (technology->enabled == TRUE) return -EALREADY; + technology->enabled = TRUE; + powered_changed(technology); return 0; @@ -1238,13 +1234,19 @@ int __connman_technology_enabled(enum connman_service_type type) if (technology == NULL) return -ENXIO; + if (technology->rfkill_driven == TRUE) + return 0; + return technology_enabled(technology); } static int technology_disabled(struct connman_technology *technology) { - if (__sync_fetch_and_sub(&technology->enabled, 1) != 1) - return -EINPROGRESS; + __sync_synchronize(); + if (technology->enabled == FALSE) + return -EALREADY; + + technology->enabled = FALSE; powered_changed(technology); @@ -1254,11 +1256,22 @@ static int technology_disabled(struct connman_technology *technology) int __connman_technology_disabled(enum connman_service_type type) { struct connman_technology *technology; + GSList *list; technology = technology_find(type); if (technology == NULL) return -ENXIO; + if (technology->rfkill_driven == TRUE) + return 0; + + for (list = technology->device_list; list != NULL; list = list->next) { + struct connman_device *device = list->data; + + if (connman_device_get_powered(device) == TRUE) + return 0; + } + return technology_disabled(technology); } @@ -1288,10 +1301,10 @@ int __connman_technology_set_offlinemode(connman_bool_t offlinemode) struct connman_technology *technology = list->data; if (offlinemode) - err = technology_disable(technology, FALSE); + err = technology_disable(technology); if (!offlinemode && technology->enable_persistent) - err = technology_enable(technology, FALSE); + err = technology_enable(technology); } if (err == 0 || err == -EINPROGRESS || err == -EALREADY) { @@ -1323,44 +1336,69 @@ void __connman_technology_set_connected(enum connman_service_type type, static connman_bool_t technology_apply_rfkill_change(struct connman_technology *technology, connman_bool_t softblock, - connman_bool_t hardblock) + connman_bool_t hardblock, + connman_bool_t new_rfkill) { + gboolean hardblock_changed = FALSE; gboolean apply = TRUE; GList *start, *list; + DBG("technology %p --> %d/%d vs %d/%d", + technology, softblock, hardblock, + technology->softblocked, technology->hardblocked); + if (technology->hardblocked == hardblock) goto softblock_change; - start = g_hash_table_get_values(rfkill_list); - for (list = start; list != NULL; list = list->next) { - struct connman_rfkill *rfkill = list->data; + if (!(new_rfkill == TRUE && hardblock == FALSE)) { + start = g_hash_table_get_values(rfkill_list); - if (rfkill->type != technology->type) - continue; + for (list = start; list != NULL; list = list->next) { + struct connman_rfkill *rfkill = list->data; - if (rfkill->hardblock != hardblock) - apply = FALSE; - } + if (rfkill->type != technology->type) + continue; + + if (rfkill->hardblock != hardblock) + apply = FALSE; + } - g_list_free(start); + g_list_free(start); + } if (apply == FALSE) goto softblock_change; technology->hardblocked = hardblock; - - if (hardblock == TRUE) { - DBG("%s is switched off.", get_name(technology->type)); - technology_disable(technology, TRUE); - technology_dbus_unregister(technology); - } else { - technology_enable(technology, TRUE); - technology_dbus_register(technology); - } + hardblock_changed = TRUE; softblock_change: + if (apply == FALSE && technology->softblocked != softblock) + apply = TRUE; + + if (apply == FALSE) + return technology->hardblocked; + technology->softblocked = softblock; + if (technology->hardblocked == TRUE || + technology->softblocked == TRUE) { + if (technology_disabled(technology) != -EALREADY) + technology_affect_devices(technology, FALSE); + } else if (technology->hardblocked == FALSE && + technology->softblocked == FALSE) { + if (technology_enabled(technology) != -EALREADY) + technology_affect_devices(technology, TRUE); + } + + if (hardblock_changed == TRUE) { + if (technology->hardblocked == TRUE) { + DBG("%s is switched off.", get_name(technology->type)); + technology_dbus_unregister(technology); + } else + technology_dbus_register(technology); + } + return technology->hardblocked; } @@ -1400,7 +1438,7 @@ done: /* If hardblocked, there is no need to handle softblocked state */ if (technology_apply_rfkill_change(technology, - softblock, hardblock) == TRUE) + softblock, hardblock, TRUE) == TRUE) return 0; /* @@ -1412,8 +1450,8 @@ done: technology->enable_persistent == TRUE) return __connman_rfkill_block(type, FALSE); else if (technology->softblocked == FALSE && - global_offlinemode == TRUE && - technology->enable_persistent == FALSE) + (global_offlinemode == TRUE || + technology->enable_persistent == FALSE)) return __connman_rfkill_block(type, TRUE); return 0; @@ -1447,7 +1485,7 @@ int __connman_technology_update_rfkill(unsigned int index, /* If hardblocked, there is no need to handle softblocked state */ if (technology_apply_rfkill_change(technology, - softblock, hardblock) == TRUE) + softblock, hardblock, FALSE) == TRUE) return 0; if (global_offlinemode == TRUE) @@ -1485,6 +1523,9 @@ int __connman_technology_remove_rfkill(unsigned int index, if (technology == NULL) return -ENXIO; + technology_apply_rfkill_change(technology, + technology->softblocked, !technology->hardblocked, FALSE); + technology_put(technology); return 0;