X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Ftechnology.c;h=37d3974f18f6d4f4afc44b1ab5918ccf2666ab28;hb=eb93dcfa05a8ddcaea9d80b990f3055c1f4e0edf;hp=34c50be6beff44a4ef4cd5aeb25c3dd20e46151a;hpb=54c3ca35ef4601a5068b7cae464197648d6918dc;p=platform%2Fupstream%2Fconnman.git diff --git a/src/technology.c b/src/technology.c index 34c50be..37d3974 100644 --- a/src/technology.c +++ b/src/technology.c @@ -36,14 +36,17 @@ static GSList *technology_list = NULL; struct connman_rfkill { unsigned int index; enum connman_service_type type; + connman_bool_t softblock; + connman_bool_t hardblock; }; enum connman_technology_state { CONNMAN_TECHNOLOGY_STATE_UNKNOWN = 0, CONNMAN_TECHNOLOGY_STATE_OFFLINE = 1, CONNMAN_TECHNOLOGY_STATE_AVAILABLE = 2, - CONNMAN_TECHNOLOGY_STATE_ENABLED = 3, - CONNMAN_TECHNOLOGY_STATE_CONNECTED = 4, + CONNMAN_TECHNOLOGY_STATE_BLOCKED = 3, + CONNMAN_TECHNOLOGY_STATE_ENABLED = 4, + CONNMAN_TECHNOLOGY_STATE_CONNECTED = 5, }; struct connman_technology { @@ -54,6 +57,7 @@ struct connman_technology { GHashTable *rfkill_list; GSList *device_list; gint enabled; + gint blocked; struct connman_technology_driver *driver; void *driver_data; @@ -101,7 +105,7 @@ void connman_technology_driver_unregister(struct connman_technology_driver *driv } void __connman_technology_add_interface(enum connman_service_type type, - int index, const char *name) + int index, const char *name, const char *ident) { GSList *list; @@ -133,12 +137,12 @@ void __connman_technology_add_interface(enum connman_service_type type, if (technology->driver->add_interface) technology->driver->add_interface(technology, - index, name); + index, name, ident); } } void __connman_technology_remove_interface(enum connman_service_type type, - int index, const char *name) + int index, const char *name, const char *ident) { GSList *list; @@ -173,7 +177,7 @@ void __connman_technology_remove_interface(enum connman_service_type type, } } -static int set_tethering(connman_bool_t enabled) +static int set_tethering(const char *bridge, connman_bool_t enabled) { GSList *list; @@ -184,20 +188,20 @@ static int set_tethering(connman_bool_t enabled) continue; if (technology->driver->set_tethering) - technology->driver->set_tethering(technology, enabled); + technology->driver->set_tethering(technology, bridge, enabled); } return 0; } -int __connman_technology_enable_tethering(void) +int __connman_technology_enable_tethering(const char *bridge) { - return set_tethering(TRUE); + return set_tethering(bridge, TRUE); } -int __connman_technology_disable_tethering(void) +int __connman_technology_disable_tethering(const char *bridge) { - return set_tethering(FALSE); + return set_tethering(bridge, FALSE); } static void free_rfkill(gpointer data) @@ -229,31 +233,6 @@ static void technologies_changed(void) DBUS_TYPE_OBJECT_PATH, __connman_technology_list, NULL); } -static void device_list(DBusMessageIter *iter, void *user_data) -{ - struct connman_technology *technology = user_data; - GSList *list; - - for (list = technology->device_list; list; list = list->next) { - struct connman_device *device = list->data; - const char *path; - - path = connman_device_get_path(device); - if (path == NULL) - continue; - - dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, - &path); - } -} - -static void devices_changed(struct connman_technology *technology) -{ - connman_dbus_property_changed_array(technology->path, - CONNMAN_TECHNOLOGY_INTERFACE, "Devices", - DBUS_TYPE_OBJECT_PATH, device_list, technology); -} - static const char *state2string(enum connman_technology_state state) { switch (state) { @@ -263,6 +242,8 @@ static const char *state2string(enum connman_technology_state state) return "offline"; case CONNMAN_TECHNOLOGY_STATE_AVAILABLE: return "available"; + case CONNMAN_TECHNOLOGY_STATE_BLOCKED: + return "blocked"; case CONNMAN_TECHNOLOGY_STATE_ENABLED: return "enabled"; case CONNMAN_TECHNOLOGY_STATE_CONNECTED: @@ -339,9 +320,6 @@ static DBusMessage *get_properties(DBusConnection *conn, connman_dbus_dict_append_basic(&dict, "Type", DBUS_TYPE_STRING, &str); - connman_dbus_dict_append_array(&dict, "Devices", - DBUS_TYPE_OBJECT_PATH, device_list, technology); - connman_dbus_dict_close(&array, &dict); return reply; @@ -492,14 +470,17 @@ int __connman_technology_add_device(struct connman_device *device) g_hash_table_insert(device_table, device, technology); - if (technology->device_list == NULL) { - technology->state = CONNMAN_TECHNOLOGY_STATE_AVAILABLE; - state_changed(technology); - } + if (g_atomic_int_get(&technology->blocked)) + goto done; + + technology->state = CONNMAN_TECHNOLOGY_STATE_AVAILABLE; + + state_changed(technology); + +done: technology->device_list = g_slist_append(technology->device_list, device); - devices_changed(technology); return 0; } @@ -512,7 +493,6 @@ int __connman_technology_remove_device(struct connman_device *device) DBG("device %p", device); type = __connman_device_get_service_type(device); - __connman_notifier_disable(type); __connman_notifier_unregister(type); technology = g_hash_table_lookup(device_table, device); @@ -521,8 +501,6 @@ int __connman_technology_remove_device(struct connman_device *device) technology->device_list = g_slist_remove(technology->device_list, device); - devices_changed(technology); - if (technology->device_list == NULL) { technology->state = CONNMAN_TECHNOLOGY_STATE_OFFLINE; state_changed(technology); @@ -540,13 +518,16 @@ int __connman_technology_enable_device(struct connman_device *device) DBG("device %p", device); - type = __connman_device_get_service_type(device); - __connman_notifier_enable(type); - technology = g_hash_table_lookup(device_table, device); if (technology == NULL) return -ENXIO; + if (g_atomic_int_get(&technology->blocked)) + return -ERFKILL; + + type = __connman_device_get_service_type(device); + __connman_notifier_enable(type); + if (g_atomic_int_exchange_and_add(&technology->enabled, 1) == 0) { technology->state = CONNMAN_TECHNOLOGY_STATE_ENABLED; state_changed(technology); @@ -559,6 +540,7 @@ int __connman_technology_disable_device(struct connman_device *device) { struct connman_technology *technology; enum connman_service_type type; + GSList *list; DBG("device %p", device); @@ -574,9 +556,31 @@ int __connman_technology_disable_device(struct connman_device *device) state_changed(technology); } + for (list = technology->device_list; list; list = list->next) { + struct connman_device *device = list->data; + + if (__connman_device_get_blocked(device) == FALSE) + return 0; + } + + technology->state = CONNMAN_TECHNOLOGY_STATE_BLOCKED; + state_changed(technology); + return 0; } +static void technology_blocked(struct connman_technology *technology, + connman_bool_t blocked) +{ + GSList *list; + + for (list = technology->device_list; list; list = list->next) { + struct connman_device *device = list->data; + + __connman_device_set_blocked(device, blocked); + } +} + int __connman_technology_add_rfkill(unsigned int index, enum connman_service_type type, connman_bool_t softblock, @@ -584,26 +588,38 @@ int __connman_technology_add_rfkill(unsigned int index, { struct connman_technology *technology; struct connman_rfkill *rfkill; + connman_bool_t blocked; DBG("index %u type %d soft %u hard %u", index, type, softblock, hardblock); + technology = technology_get(type); + if (technology == NULL) + return -ENXIO; + rfkill = g_try_new0(struct connman_rfkill, 1); if (rfkill == NULL) return -ENOMEM; rfkill->index = index; rfkill->type = type; + rfkill->softblock = softblock; + rfkill->hardblock = hardblock; - technology = technology_get(type); - if (technology == NULL) { - g_free(rfkill); - return -ENXIO; - } + g_hash_table_replace(rfkill_table, &rfkill->index, technology); + + g_hash_table_replace(technology->rfkill_list, &rfkill->index, rfkill); + + blocked = (softblock || hardblock) ? TRUE : FALSE; + if (blocked == FALSE) + return 0; - g_hash_table_replace(rfkill_table, &index, technology); + if (g_atomic_int_exchange_and_add(&technology->blocked, 1) == 0) { + technology_blocked(technology, TRUE); - g_hash_table_replace(technology->rfkill_list, &index, rfkill); + technology->state = CONNMAN_TECHNOLOGY_STATE_BLOCKED; + state_changed(technology); + } return 0; } @@ -613,6 +629,8 @@ int __connman_technology_update_rfkill(unsigned int index, connman_bool_t hardblock) { struct connman_technology *technology; + struct connman_rfkill *rfkill; + connman_bool_t blocked, old_blocked; DBG("index %u soft %u hard %u", index, softblock, hardblock); @@ -620,6 +638,39 @@ int __connman_technology_update_rfkill(unsigned int index, if (technology == NULL) return -ENXIO; + rfkill = g_hash_table_lookup(technology->rfkill_list, &index); + if (rfkill == NULL) + return -ENXIO; + + old_blocked = (rfkill->softblock || rfkill->hardblock) ? TRUE : FALSE; + blocked = (softblock || hardblock) ? TRUE : FALSE; + + rfkill->softblock = softblock; + rfkill->hardblock = hardblock; + + if (blocked == old_blocked) + return 0; + + if (blocked) { + guint n_blocked; + + n_blocked = + g_atomic_int_exchange_and_add(&technology->blocked, 1); + if (n_blocked != g_hash_table_size(technology->rfkill_list) - 1) + return 0; + + technology_blocked(technology, blocked); + technology->state = CONNMAN_TECHNOLOGY_STATE_BLOCKED; + state_changed(technology); + } else { + if (g_atomic_int_dec_and_test(&technology->blocked) == FALSE) + return 0; + + technology_blocked(technology, blocked); + technology->state = CONNMAN_TECHNOLOGY_STATE_AVAILABLE; + state_changed(technology); + } + return 0; } @@ -637,9 +688,29 @@ int __connman_technology_remove_rfkill(unsigned int index) g_hash_table_remove(rfkill_table, &index); + if (g_atomic_int_dec_and_test(&technology->blocked) == TRUE) { + technology_blocked(technology, FALSE); + technology->state = CONNMAN_TECHNOLOGY_STATE_AVAILABLE; + state_changed(technology); + } + return 0; } +connman_bool_t __connman_technology_get_blocked(enum connman_service_type type) +{ + struct connman_technology *technology; + + technology = technology_get(type); + if (technology == NULL) + return FALSE; + + if (g_atomic_int_get(&technology->blocked)) + return TRUE; + + return FALSE; +} + int __connman_technology_init(void) { DBG("");