Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Unified Diff: src/service.c

Issue 6659006: flimflam: add support for multiple profiles (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/flimflam.git@master
Patch Set: rebase Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/profile.c ('K') | « src/profile.c ('k') | src/storage.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/service.c
diff --git a/src/service.c b/src/service.c
index aa5c2c63b807dea7fd65953ef48b686163c41088..fd64966b02d5c735430042ee356fe6ead7d1a3b2 100644
--- a/src/service.c
+++ b/src/service.c
@@ -96,7 +96,7 @@ struct connman_service {
char *key_mgmt;
} eap;
- char *profile;
+ const struct connman_storage_ident *profile;
char *proxy_config;
/* TODO(sleffler) overlay storage */
@@ -216,8 +216,12 @@ static const char* kEAPPIN = "EAP.PIN";
static const char* kEAPPassword = "EAP.Password";
static const char* kEAPKeyMgmt = "EAP.KeyMgmt";
+static void service_clear_passphrase(struct connman_service *service);
static void service_modified(struct connman_service *service);
+static void service_clear_eap(struct connman_service *service);
static void __service_resort(struct connman_service *service);
+static void set_reconnect_state(struct connman_service *service,
+ connman_bool_t onoff);
static connman_bool_t is_timeset(const GTimeVal *tv)
{
@@ -392,6 +396,40 @@ static struct connman_service *find_service(const char *path)
return data.service;
}
+static void invalidate_profile(gpointer value, gpointer user_data)
+{
+ struct connman_service *service = value;
+ const struct connman_storage_ident *profile = user_data;
+
+ if (service->profile == profile) {
+ /*
+ * Invalidate profile-related data and force a re-load
+ * the next time the service is to be used (so it can
+ * come from the active profile).
+ */
+ service->profile = NULL;
+
+ /*
+ * network_disconnect may drop the last reference to the
+ * service and cause it to be freed, so take a reference
+ * temporarily until we are done with it.
+ */
+ connman_service_ref(service);
+ /* TODO(sleffler) skip wired ethernet, open auth? */
+ __connman_service_disconnect(service);
+ service_clear_passphrase(service);
+ service_clear_eap(service);
+ connman_service_unref(service);
+ }
+}
+
+void __connman_service_invalidate_profile(const struct connman_storage_ident *ident)
+{
+ _DBG_SERVICE("ident %s/%s", ident->user, ident->ident);
+
+ g_sequence_foreach(service_list, invalidate_profile, (gpointer) ident);
+}
+
static const char *identifier(struct connman_service *service)
{
return service ? service->identifier : "<nil>";
@@ -761,68 +799,6 @@ static void hidden_ssid_changed(struct connman_service *service)
DBUS_TYPE_BOOLEAN, &service->wifi.hidden_ssid);
}
-/**
- * connman_service_append_hidden_ssids:
- * @hidden_ssids: pointer to a list of hidden SSIDs
- *
- * Append the list of SSIDs whose services whose WiFi.HiddenSSID property is
- * TRUE. These SSIDs should be directly probed whenever performing a WiFi
- * network scan.
- *
- * Return -EINVAL if profile could not be parsed cleanly
- */
-int connman_service_append_hidden_ssids(GSList **hidden_ssids)
-{
- const char *ident = __connman_profile_active_ident();
- GKeyFile *keyfile;
- gchar **keys;
- int ret = 0;
-
- _DBG_SERVICE("ident %s", ident);
-
- keyfile = __connman_storage_open(ident);
- if (keyfile == NULL)
- return -EINVAL;
-
- keys = g_key_file_get_groups(keyfile, NULL);
- if (keys == NULL) {
- ret = -EINVAL;
- goto done;
- }
-
- for (; *keys != NULL; keys++) {
- gchar *key = *keys;
- gchar *hex_ssid;
- struct blob *ssid;
-
- if (g_ascii_strncasecmp(key, "wifi_", 5) != 0)
- continue;
-
- if (!g_key_file_get_boolean(keyfile, key, "WiFi.HiddenSSID",
- NULL))
- continue;
-
- hex_ssid = g_key_file_get_string(keyfile, key, "SSID", NULL);
- if (hex_ssid == NULL)
- continue;
-
- _DBG_SERVICE("service %s", key);
-
- ret = blob_new_from_hex(&ssid, hex_ssid);
- g_free(hex_ssid);
- if (ret < 0)
- goto done;
-
- _DBG_SERVICE("ssid %.*s", ssid->len, ssid->data);
- *hidden_ssids = g_slist_prepend(*hidden_ssids, ssid);
- }
-
-done:
- g_key_file_free(keyfile);
-
- return ret;
-}
-
static connman_bool_t is_connectable(const struct connman_service *service)
{
@@ -1455,7 +1431,7 @@ static DBusMessage *set_eap_string(struct connman_service *service,
CONNMAN_SERVICE_INTERFACE, servicename,
DBUS_TYPE_STRING, storage);
- __connman_storage_save_service(service);
+ service_modified(service);
return NULL;
}
@@ -1502,8 +1478,7 @@ static DBusMessage *set_property(DBusConnection *conn,
hidden_ssid_changed(service);
- __connman_storage_save_service(service);
-
+ service_modified(service);
} else if (g_str_equal(name, "Passphrase") == TRUE) {
const char *passphrase;
@@ -1545,7 +1520,7 @@ static DBusMessage *set_property(DBusConnection *conn,
if (service->network != NULL)
prepare_network_passphrase(service);
- __connman_storage_save_service(service);
+ service_modified(service);
} else if (g_str_equal(name, kEAPIdentity) == TRUE) {
returnmsg = set_eap_string(service, msg, type, value,
&service->eap.identity,
@@ -1632,7 +1607,7 @@ static DBusMessage *set_property(DBusConnection *conn,
CONNMAN_SERVICE_INTERFACE, kEAPUseSystemCAs,
DBUS_TYPE_BOOLEAN, &service->eap.use_system_cas);
- __connman_storage_save_service(service);
+ __connman_profile_save_service(service);
} else if (g_str_equal(name, kEAPPIN) == TRUE) {
returnmsg = set_eap_string(service, msg, type, value,
&service->eap.pin,
@@ -1669,7 +1644,7 @@ static DBusMessage *set_property(DBusConnection *conn,
autoconnect_changed(service);
- __connman_storage_save_service(service);
+ service_modified(service);
} else if (g_str_equal(name, "ProxyConfig") == TRUE) {
const char *proxy_config;
@@ -1683,7 +1658,7 @@ static DBusMessage *set_property(DBusConnection *conn,
proxy_configuration_changed(service);
- __connman_storage_save_service(service);
+ service_modified(service);
} else if (g_str_has_prefix(name, "Priority") == TRUE) {
int pri;
@@ -1704,7 +1679,7 @@ static DBusMessage *set_property(DBusConnection *conn,
service_priority_changed(service);
- __connman_storage_save_service(service);
+ service_modified(service);
}
} else
return __connman_error_invalid_property(msg);
@@ -1729,12 +1704,17 @@ static void set_idle(struct connman_service *service)
state_change(service, CONNMAN_SERVICE_STATE_IDLE, TRUE);
}
-static void __connman_service_clear_passphrase(struct connman_service *service)
+static void service_clear_passphrase(struct connman_service *service)
{
g_free(service->passphrase);
service->passphrase = NULL;
memset(&service->wifi, 0, sizeof(service->wifi));
+}
+
+static void __connman_service_clear_passphrase(struct connman_service *service)
+{
+ service_clear_passphrase(service);
passphrase_required_changed(service);
}
@@ -1742,14 +1722,13 @@ static void __connman_service_clear_passphrase(struct connman_service *service)
static void service_modified(struct connman_service *service)
{
g_get_current_time(&service->modified);
- __connman_storage_save_service(service);
+
+ service->profile = __connman_profile_active_ident();
+ __connman_profile_save_service(service);
}
-void __connman_service_reset(struct connman_service *service)
+static void service_clear_eap(struct connman_service *service)
{
- connman_service_set_favorite(service, FALSE);
- __connman_service_clear_passphrase(service);
-
g_free(service->eap.identity);
service->eap.identity = NULL;
@@ -1790,6 +1769,13 @@ void __connman_service_reset(struct connman_service *service)
g_free(service->eap.password);
service->eap.password = NULL;
+}
+
+void __connman_service_reset(struct connman_service *service)
+{
+ connman_service_set_favorite(service, FALSE);
+ __connman_service_clear_passphrase(service);
+ service_clear_eap(service);
service_modified(service);
}
@@ -2152,6 +2138,23 @@ void connman_service_auto_connect(struct connman_service *service)
__connman_service_device_auto_connect(device);
}
+static gboolean auto_connect_any(gpointer data)
+{
+ _DBG_SERVICE("");
+
+ if (__connman_connection_is_online() == FALSE)
+ __auto_connect(NULL, NULL);
+ return FALSE;
+}
+
+/*
+ * Attempt autoconnect on any device, but only if offline.
+ */
+void __connman_service_auto_connect_any(void)
+{
+ g_idle_add(auto_connect_any, NULL);
+}
+
/**
* __connman_service_set_activation_state:
* @service: service structure
@@ -2706,7 +2709,7 @@ static DBusMessage *set_apn(DBusConnection *conn, DBusMessage *msg,
__connman_service_save_last_good_apn(service, NULL);
}
- __connman_storage_save_service(service);
+ service_modified(service);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
@@ -2760,7 +2763,6 @@ static void service_free(gpointer user_data)
if (service->provider != NULL)
connman_provider_unref(service->provider);
- g_free(service->profile);
g_free(service->name);
g_free(service->passphrase);
g_free(service->eap.identity);
@@ -3850,7 +3852,7 @@ DBusMessage *__connman_configure_wifi_service(DBusMessage *msg)
_DBG_SERVICE("service %p created %d", service, created);
- __connman_storage_save_service(service);
+ service_modified(service);
/*
* If __connman_get_wifi_service_int created the network object
@@ -3897,9 +3899,9 @@ static struct connman_service *__connman_service_get(const char *identifier)
service->identifier = g_strdup(identifier);
- service->profile = g_strdup(__connman_profile_active_ident());
+ service->profile = __connman_profile_active_ident();
- __connman_storage_load_service(service);
+ __connman_profile_load_service(service);
iter = g_sequence_insert_sorted(service_list, service,
service_compare, NULL);
@@ -3927,7 +3929,7 @@ static int service_register(struct connman_service *service)
service_methods, service_signals,
NULL, service, NULL);
- __connman_storage_load_service(service);
+ __connman_profile_load_service(service);
__service_resort(service);
@@ -3996,7 +3998,7 @@ __connman_service_create_from_device(struct connman_device *device)
service->device = device;
- __connman_storage_load_service(service);
+ __connman_profile_load_service(service);
service_register(service);
@@ -4398,7 +4400,7 @@ __connman_service_create_from_network(struct connman_network *network)
update_from_network(service, network, FALSE);
- __connman_storage_load_service(service);
+ __connman_profile_load_service(service);
service_register(service);
@@ -4607,7 +4609,7 @@ void __connman_service_save_last_good_apn(struct connman_service *service,
service->cellular.last_good_apn.password = NULL;
}
- __connman_storage_save_service(service);
+ __connman_profile_save_service(service);
}
static void populate_service_from_keyfile(GKeyFile *keyfile,
@@ -4635,9 +4637,17 @@ static char *__old_security(GKeyFile *keyfile,
if (service->security == CONNMAN_SERVICE_SECURITY_WPA) {
group = g_strdup(service->identifier);
g_strlcpy(group + strlen(group) - 3, "wpa", 4);
+ if (g_key_file_has_group(keyfile, group) == FALSE) {
+ g_free(group);
+ group = NULL;
+ }
} else if (service->security == CONNMAN_SERVICE_SECURITY_RSN) {
group = g_strdup(service->identifier);
g_strlcpy(group + strlen(group) - 3, "rsn", 4);
+ if (g_key_file_has_group(keyfile, group) == FALSE) {
+ g_free(group);
+ group = NULL;
+ }
}
return group;
}
@@ -4678,14 +4688,10 @@ static void load_apn(struct connman_service *service,
g_free(network_id_key);
}
-static int service_load(struct connman_service *service)
+static int service_load(struct connman_service *service, GKeyFile *keyfile)
{
- const char *ident = service->profile;
const char *group = service->identifier;
- GKeyFile *keyfile;
GError *error = NULL;
- gchar *pathname, *data = NULL;
- gsize length;
gchar *str;
connman_bool_t autoconnect, use_system_cas;
unsigned int ssid_len;
@@ -4694,40 +4700,22 @@ static int service_load(struct connman_service *service)
_DBG_SERVICE("service %p", service);
- if (ident == NULL)
- return -EINVAL;
-
- pathname = g_strdup_printf("%s/%s.profile", STORAGEDIR, ident);
- if (pathname == NULL)
- return -ENOMEM;
-
- keyfile = g_key_file_new();
-
- if (g_file_get_contents(pathname, &data, &length, NULL) == FALSE) {
- g_free(pathname);
- return -ENOENT;
- }
-
- g_free(pathname);
-
- if (g_key_file_load_from_data(keyfile, data, length,
- 0, NULL) == FALSE) {
- g_free(data);
- return -EILSEQ;
- }
-
- g_free(data);
-
- /*
- * Handle upgrade of old-style entries for wpa/rsn services.
- */
- if (g_key_file_has_group(keyfile, group) == FALSE &&
- g_str_has_suffix(group, "_psk") == TRUE) {
- char *old_group = __old_security(keyfile, service);
- if (old_group != NULL) {
- _DBG_SERVICE("check old entry %s", old_group);
- group = old_group;
+ if (g_key_file_has_group(keyfile, group) == FALSE) {
+ char *old_group;
+ /*
+ * Handle upgrade of old-style entries for wpa/rsn services.
+ */
+ if (g_str_has_suffix(group, "_psk") == FALSE) {
+ err = -ESRCH;
+ goto done;
}
+ old_group = __old_security(keyfile, service);
+ if (old_group == NULL) {
+ err = -ESRCH;
+ goto done;
+ }
+ _DBG_SERVICE("check old entry %s", old_group);
+ group = old_group;
}
switch (service->type) {
@@ -4813,8 +4801,8 @@ static int service_load(struct connman_service *service)
g_free(str);
}
- str = __connman_storage_get_encrypted_value(keyfile, service->profile,
- group, "Passphrase");
+ str = __connman_storage_get_encrypted_value(keyfile, group,
+ "Passphrase");
if (str != NULL) {
connman_bool_t valid_pass = TRUE;
g_free(service->passphrase);
@@ -4892,8 +4880,6 @@ static int service_load(struct connman_service *service)
load_apn(service, keyfile, group, &service->cellular.last_good_apn,
"LastGoodAPN");
done:
- g_key_file_free(keyfile);
-
if (group != service->identifier)
g_free((char *)group);
@@ -4941,38 +4927,12 @@ static void save_apn(struct connman_service *service,
g_free(network_id_key);
}
-static int service_save(struct connman_service *service)
+static int service_save(struct connman_service *service, GKeyFile *keyfile)
{
- const char *ident = service->profile;
- GKeyFile *keyfile;
- gchar *pathname, *data = NULL;
- gsize length;
gchar *str;
- int err = 0;
_DBG_SERVICE("service %p", service);
- if (ident == NULL)
- return -EINVAL;
-
- pathname = g_strdup_printf("%s/%s.profile", STORAGEDIR, ident);
- if (pathname == NULL)
- return -ENOMEM;
-
- keyfile = g_key_file_new();
-
- if (g_file_get_contents(pathname, &data, &length, NULL) == FALSE)
- goto update;
-
- if (length > 0) {
- if (g_key_file_load_from_data(keyfile, data, length,
- 0, NULL) == FALSE)
- goto done;
- }
-
- g_free(data);
-
-update:
if (service->name != NULL)
g_key_file_set_string(keyfile, service->identifier,
"Name", service->name);
@@ -5042,7 +5002,7 @@ update:
}
if (service->passphrase != NULL && strlen(service->passphrase) > 0) {
- __connman_storage_set_encrypted_value(keyfile, service->profile,
+ __connman_storage_set_encrypted_value(keyfile,
service->identifier, "Passphrase", service->passphrase);
} else {
g_key_file_remove_key(keyfile, service->identifier,
@@ -5088,19 +5048,7 @@ update:
save_apn(service, keyfile, &service->cellular.last_good_apn,
"LastGoodAPN");
- data = g_key_file_to_data(keyfile, &length, NULL);
-
- if (g_file_set_contents(pathname, data, length, NULL) == FALSE)
- connman_error("Failed to store service information");
-
-done:
- g_free(data);
-
- g_key_file_free(keyfile);
-
- g_free(pathname);
-
- return err;
+ return 0;
}
static struct connman_storage service_storage = {
« src/profile.c ('K') | « src/profile.c ('k') | src/storage.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698