X-Git-Url: http://git.maemo.org/git/?p=connman;a=blobdiff_plain;f=src%2Fdevice.c;h=cd9105d0775953445c3455e0115f57786589bcf9;hp=e7c4b677629e743fa318af9ffdbe3d63ee5a83a0;hb=HEAD;hpb=c6ad3d59d894b089f122e6f22f320e05c78cc97c diff --git a/src/device.c b/src/device.c index e7c4b67..cd9105d 100644 --- a/src/device.c +++ b/src/device.c @@ -35,6 +35,7 @@ struct connman_device { enum connman_device_type type; enum connman_device_mode mode; enum connman_device_policy policy; + connman_bool_t secondary; connman_bool_t powered; connman_bool_t carrier; connman_bool_t scanning; @@ -45,6 +46,7 @@ struct connman_device { char *node; char *address; char *interface; + char *ident; unsigned int connections; guint scan_timeout; @@ -159,6 +161,61 @@ static enum connman_device_policy string2policy(const char *policy) return CONNMAN_DEVICE_POLICY_UNKNOWN; } +static int set_carrier(struct connman_device *device, connman_bool_t carrier) +{ + struct connman_service *service; + + service = __connman_service_lookup_from_device(device); + __connman_service_set_carrier(service, carrier); + + if (carrier == TRUE) { + enum connman_element_type type = CONNMAN_ELEMENT_TYPE_UNKNOWN; + struct connman_element *element; + + device->disconnected = TRUE; + + switch (device->policy) { + case CONNMAN_DEVICE_POLICY_UNKNOWN: + case CONNMAN_DEVICE_POLICY_IGNORE: + case CONNMAN_DEVICE_POLICY_OFF: + case CONNMAN_DEVICE_POLICY_MANUAL: + return 0; + case CONNMAN_DEVICE_POLICY_AUTO: + break; + } + + switch (device->element.ipv4.method) { + case CONNMAN_IPV4_METHOD_UNKNOWN: + case CONNMAN_IPV4_METHOD_OFF: + return 0; + case CONNMAN_IPV4_METHOD_STATIC: + type = CONNMAN_ELEMENT_TYPE_IPV4; + break; + case CONNMAN_IPV4_METHOD_DHCP: + type = CONNMAN_ELEMENT_TYPE_DHCP; + break; + } + + element = connman_element_create(NULL); + if (element != NULL) { + element->type = type; + element->index = device->element.index; + + if (connman_element_register(element, + &device->element) < 0) + connman_element_unref(element); + + device->disconnected = FALSE; + + __connman_service_indicate_state(service, + CONNMAN_SERVICE_STATE_CONFIGURATION); + } + } else + connman_element_unregister_children(&device->element); + + return 0; +} + static int set_powered(struct connman_device *device, connman_bool_t powered) { struct connman_device_driver *driver = device->driver; @@ -178,6 +235,8 @@ static int set_powered(struct connman_device *device, connman_bool_t powered) } else { g_hash_table_remove_all(device->networks); + set_carrier(device, FALSE); + if (driver->disable) { err = driver->disable(device); __connman_notifier_device_type_decrease(device->type); @@ -215,6 +274,8 @@ static int set_policy(DBusConnection *connection, case CONNMAN_DEVICE_POLICY_MANUAL: if (device->powered == FALSE) err = set_powered(device, TRUE); + else + err = set_carrier(device, device->carrier); break; } @@ -298,14 +359,9 @@ static DBusMessage *get_properties(DBusConnection *conn, DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); - str = type2description(device->type); - if (str != NULL && device->interface != NULL) { - char *name = g_strdup_printf("%s (%s)", str, device->interface); - if (name != NULL) - connman_dbus_dict_append_variant(&dict, "Name", - DBUS_TYPE_STRING, &name); - g_free(name); - } + if (device->name != NULL) + connman_dbus_dict_append_variant(&dict, "Name", + DBUS_TYPE_STRING, &device->name); str = type2string(device->type); if (str != NULL) @@ -397,7 +453,7 @@ static DBusMessage *set_property(DBusConnection *conn, err = set_powered(device, powered); if (err < 0 && err != -EINPROGRESS) - return __connman_error_failed(msg); + return __connman_error_failed(msg, -err); } else if (g_str_equal(name, "Policy") == TRUE) { enum connman_device_policy policy; const char *str; @@ -413,7 +469,7 @@ static DBusMessage *set_property(DBusConnection *conn, err = set_policy(conn, device, policy); if (err < 0) - return __connman_error_failed(msg); + return __connman_error_failed(msg, -err); } else if (g_str_equal(name, "Priority") == TRUE) { connman_uint8_t priority; @@ -501,7 +557,7 @@ static DBusMessage *join_network(DBusConnection *conn, network = connman_network_create("00_00_00_00_00_00", type); if (network == NULL) - return __connman_error_failed(msg); + return __connman_error_failed(msg, ENOMEM); while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) { DBusMessageIter entry, value; @@ -537,7 +593,7 @@ static DBusMessage *join_network(DBusConnection *conn, connman_network_unref(network); if (err < 0) - return __connman_error_failed(msg); + return __connman_error_failed(msg, -err); return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } @@ -587,11 +643,11 @@ static DBusMessage *propose_scan(DBusConnection *conn, return __connman_error_not_supported(msg); if (device->powered == FALSE) - return __connman_error_failed(msg); + return __connman_error_failed(msg, EINVAL); err = device->driver->scan(device); if (err < 0) - return __connman_error_failed(msg); + return __connman_error_failed(msg, -err); return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } @@ -739,7 +795,8 @@ static int setup_device(struct connman_device *device) case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE: break; case CONNMAN_DEVICE_MODE_TRANSPORT_IP: - __connman_profile_add_device(device); + if (device->secondary == FALSE) + __connman_profile_add_device(device); break; } @@ -783,7 +840,8 @@ static void remove_device(struct connman_device *device) case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE: break; case CONNMAN_DEVICE_MODE_TRANSPORT_IP: - __connman_profile_remove_device(device); + if (device->secondary == FALSE) + __connman_profile_remove_device(device); break; } @@ -880,6 +938,7 @@ static void device_destruct(struct connman_element *element) DBG("element %p name %s", element, element->name); + g_free(device->ident); g_free(device->node); g_free(device->name); g_free(device->address); @@ -929,9 +988,11 @@ struct connman_device *connman_device_create(const char *node, device->element.ipv4.method = CONNMAN_IPV4_METHOD_DHCP; - device->type = type; - device->mode = CONNMAN_DEVICE_MODE_UNKNOWN; - device->policy = CONNMAN_DEVICE_POLICY_AUTO; + device->type = type; + device->name = g_strdup(type2description(device->type)); + device->mode = CONNMAN_DEVICE_MODE_UNKNOWN; + device->policy = CONNMAN_DEVICE_POLICY_AUTO; + device->secondary = FALSE; switch (type) { case CONNMAN_DEVICE_TYPE_UNKNOWN: @@ -996,6 +1057,22 @@ void connman_device_unref(struct connman_device *device) connman_element_unref(&device->element); } +const char *__connman_device_get_type(struct connman_device *device) +{ + return type2string(device->type); +} + +/** + * connman_device_get_type: + * @device: device structure + * + * Get type of device + */ +enum connman_device_type connman_device_get_type(struct connman_device *device) +{ + return device->type; +} + /** * connman_device_get_name: * @device: device structure @@ -1056,6 +1133,13 @@ void connman_device_set_interface(struct connman_device *device, g_free(device->interface); device->interface = g_strdup(interface); + + if (device->name == NULL) { + const char *str = type2description(device->type); + if (str != NULL && device->interface != NULL) + device->name = g_strdup_printf("%s (%s)", str, + device->interface); + } } /** @@ -1070,6 +1154,25 @@ const char *connman_device_get_interface(struct connman_device *device) } /** + * connman_device_set_ident: + * @device: device structure + * @ident: unique identifier + * + * Set unique identifier of device + */ +void connman_device_set_ident(struct connman_device *device, + const char *ident) +{ + g_free(device->ident); + device->ident = g_strdup(ident); +} + +const char *__connman_device_get_ident(struct connman_device *device) +{ + return device->ident; +} + +/** * connman_device_set_policy: * @device: device structure * @policy: power and connection policy @@ -1107,6 +1210,30 @@ enum connman_device_mode connman_device_get_mode(struct connman_device *device) } /** + * connman_device_set_secondary: + * @device: device structure + * @secondary: secondary value + * + * Change secondary value of device + */ +void connman_device_set_secondary(struct connman_device *device, + connman_bool_t secondary) +{ + device->secondary = secondary; +} + +/** + * connman_device_get_secondary: + * @device: device structure + * + * Get secondary value of device + */ +connman_bool_t connman_device_get_secondary(struct connman_device *device) +{ + return device->secondary; +} + +/** * connman_device_set_powered: * @device: device structure * @powered: powered state @@ -1195,38 +1322,20 @@ int connman_device_set_carrier(struct connman_device *device, device->carrier = carrier; - if (carrier == TRUE) { - enum connman_element_type type = CONNMAN_ELEMENT_TYPE_UNKNOWN; - struct connman_element *element; - - switch (device->element.ipv4.method) { - case CONNMAN_IPV4_METHOD_UNKNOWN: - case CONNMAN_IPV4_METHOD_OFF: - return 0; - case CONNMAN_IPV4_METHOD_STATIC: - type = CONNMAN_ELEMENT_TYPE_IPV4; - break; - case CONNMAN_IPV4_METHOD_DHCP: - type = CONNMAN_ELEMENT_TYPE_DHCP; - break; - } + return set_carrier(device, device->carrier); +} - element = connman_element_create(NULL); - if (element != NULL) { - element->type = type; - element->index = device->element.index; +int __connman_device_connect(struct connman_device *device) +{ + DBG("device %p", device); - if (connman_element_register(element, - &device->element) < 0) - connman_element_unref(element); - } - } else - connman_element_unregister_children(&device->element); + if (device->disconnected == FALSE) + return -EINVAL; return 0; } -void __connman_device_disconnect(struct connman_device *device) +int __connman_device_disconnect(struct connman_device *device) { GHashTableIter iter; gpointer key, value; @@ -1243,6 +1352,8 @@ void __connman_device_disconnect(struct connman_device *device) if (connman_network_get_connected(network) == TRUE) __connman_network_disconnect(network); } + + return 0; } static void connect_known_network(struct connman_device *device) @@ -1250,6 +1361,7 @@ static void connect_known_network(struct connman_device *device) struct connman_network *network = NULL; GHashTableIter iter; gpointer key, value; + const char *name; unsigned int count = 0; DBG("device %p", device); @@ -1257,9 +1369,7 @@ static void connect_known_network(struct connman_device *device) g_hash_table_iter_init(&iter, device->networks); while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) { - connman_uint8_t old_priority, new_priority; connman_uint8_t old_strength, new_strength; - const char *name; count++; @@ -1275,25 +1385,11 @@ static void connect_known_network(struct connman_device *device) } } - if (connman_network_get_remember(value) == FALSE) - continue; - if (network == NULL) { network = value; continue; } - old_priority = connman_network_get_uint8(network, - CONNMAN_PROPERTY_ID_PRIORITY); - new_priority = connman_network_get_uint8(value, - CONNMAN_PROPERTY_ID_PRIORITY); - - if (new_priority != old_priority) { - if (new_priority > old_priority) - network = value; - continue; - } - old_strength = connman_network_get_uint8(network, CONNMAN_PROPERTY_ID_STRENGTH); new_strength = connman_network_get_uint8(value, @@ -1306,9 +1402,13 @@ static void connect_known_network(struct connman_device *device) if (network != NULL) { int err; - err = connman_network_connect(network); - if (err == 0 || err == -EINPROGRESS) - return; + name = connman_network_get_string(value, + CONNMAN_PROPERTY_ID_NAME); + if (name != NULL) { + err = __connman_network_connect(network); + if (err == 0 || err == -EINPROGRESS) + return; + } } if (count > 0) @@ -1337,9 +1437,6 @@ static gboolean remove_unavailable_network(gpointer key, gpointer value, if (connman_network_get_connected(network) == TRUE) return FALSE; - if (connman_network_get_remember(network) == TRUE) - return FALSE; - if (connman_network_get_available(network) == TRUE) return FALSE; @@ -1617,13 +1714,25 @@ void __connman_device_set_network(struct connman_device *device, { const char *name; + if (device->network == network) + return; + + if (device->network != NULL) + connman_network_unref(device->network); + if (network != NULL) { name = connman_network_get_string(network, CONNMAN_PROPERTY_ID_NAME); + g_free(device->last_network); device->last_network = g_strdup(name); - } - device->network = network; + device->network = connman_network_ref(network); + } else { + g_free(device->last_network); + device->last_network = NULL; + + device->network = NULL; + } } /** @@ -1754,7 +1863,7 @@ static struct connman_driver device_driver = { static int device_load(struct connman_device *device) { GKeyFile *keyfile; - gchar *pathname, *data = NULL; + gchar *pathname, *identifier, *data = NULL; gsize length; char *str; int val; @@ -1762,7 +1871,7 @@ static int device_load(struct connman_device *device) DBG("device %p", device); pathname = g_strdup_printf("%s/%s.conf", STORAGEDIR, - device->element.name); + __connman_profile_active_ident()); if (pathname == NULL) return -ENOMEM; @@ -1783,53 +1892,48 @@ static int device_load(struct connman_device *device) g_free(data); - str = g_key_file_get_string(keyfile, "Configuration", "Policy", NULL); + identifier = g_strdup_printf("device_%s", device->element.name); + if (identifier == NULL) + goto done; + + str = g_key_file_get_string(keyfile, identifier, "Policy", NULL); if (str != NULL) { device->policy = string2policy(str); g_free(str); } - val = g_key_file_get_integer(keyfile, "Configuration", - "Priority", NULL); - if (val > 0) - device->priority = val; - switch (device->mode) { case CONNMAN_DEVICE_MODE_UNKNOWN: case CONNMAN_DEVICE_MODE_TRANSPORT_IP: break; case CONNMAN_DEVICE_MODE_NETWORK_SINGLE: case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE: - val = g_key_file_get_integer(keyfile, "Configuration", + val = g_key_file_get_integer(keyfile, identifier, "ScanInterval", NULL); if (val > 0) device->scan_interval = val; break; } -#if 0 - str = g_key_file_get_string(keyfile, "Configuration", - "LastNetwork", NULL); - if (str != NULL) - device->last_network = str; -#endif - +done: g_key_file_free(keyfile); + g_free(identifier); + return 0; } static int device_save(struct connman_device *device) { GKeyFile *keyfile; - gchar *pathname, *data = NULL; + gchar *pathname, *identifier = NULL, *data = NULL; gsize length; const char *str; DBG("device %p", device); pathname = g_strdup_printf("%s/%s.conf", STORAGEDIR, - device->element.name); + __connman_profile_active_ident()); if (pathname == NULL) return -ENOMEM; @@ -1847,13 +1951,13 @@ static int device_save(struct connman_device *device) g_free(data); update: + identifier = g_strdup_printf("device_%s", device->element.name); + if (identifier == NULL) + goto done; + str = policy2string(device->policy); if (str != NULL) - g_key_file_set_string(keyfile, "Configuration", "Policy", str); - - if (device->priority > 0) - g_key_file_set_integer(keyfile, "Configuration", - "Priority", device->priority); + g_key_file_set_string(keyfile, identifier, "Policy", str); switch (device->mode) { case CONNMAN_DEVICE_MODE_UNKNOWN: @@ -1862,29 +1966,24 @@ update: case CONNMAN_DEVICE_MODE_NETWORK_SINGLE: case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE: if (device->scan_interval > 0) - g_key_file_set_integer(keyfile, "Configuration", + g_key_file_set_integer(keyfile, identifier, "ScanInterval", device->scan_interval); break; } - if (device->last_network != NULL) - g_key_file_set_string(keyfile, "Configuration", - "LastNetwork", device->last_network); - data = g_key_file_to_data(keyfile, &length, NULL); - g_file_set_contents(pathname, data, length, NULL); + if (g_file_set_contents(pathname, data, length, NULL) == FALSE) + connman_error("Failed to store device information"); done: g_free(data); g_key_file_free(keyfile); + g_free(identifier); g_free(pathname); - if (device->network != NULL) - __connman_storage_save_network(device->network); - return 0; }