Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * | 2 * |
| 3 * Connection Manager | 3 * Connection Manager |
| 4 * | 4 * |
| 5 * Copyright (C) 2007-2009 Intel Corporation. All rights reserved. | 5 * Copyright (C) 2007-2009 Intel Corporation. All rights reserved. |
| 6 * | 6 * |
| 7 * This program is free software; you can redistribute it and/or modify | 7 * This program is free software; you can redistribute it and/or modify |
| 8 * it under the terms of the GNU General Public License version 2 as | 8 * it under the terms of the GNU General Public License version 2 as |
| 9 * published by the Free Software Foundation. | 9 * published by the Free Software Foundation. |
| 10 * | 10 * |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 | 32 |
| 33 #include "connman.h" | 33 #include "connman.h" |
| 34 | 34 |
| 35 #define PROFILE_DEFAULT_IDENT "default" | 35 #define PROFILE_DEFAULT_IDENT "default" |
| 36 #define PROFILE_MAX 3 /* 2 is probably sufficient */ | 36 #define PROFILE_MAX 3 /* 2 is probably sufficient */ |
| 37 | 37 |
| 38 #define _DBG_PROFILE(fmt, arg...) DBG(DBG_PROFILE, fmt, ## arg) | 38 #define _DBG_PROFILE(fmt, arg...) DBG(DBG_PROFILE, fmt, ## arg) |
| 39 | 39 |
| 40 struct connman_profile { | 40 struct connman_profile { |
| 41 struct connman_storage_ident ident; | 41 struct connman_storage_ident ident; |
| 42 guint changed_timeout; | |
| 42 char *path; | 43 char *path; |
| 43 char *name; | 44 char *name; |
| 44 connman_bool_t offlinemode; | 45 connman_bool_t offlinemode; |
| 45 }; | 46 }; |
| 46 | 47 |
| 47 static GHashTable *profile_hash = NULL; | 48 static GHashTable *profile_hash = NULL; |
| 48 | 49 |
| 49 static struct connman_profile *profile_stack[PROFILE_MAX]; | 50 static struct connman_profile *profile_stack[PROFILE_MAX]; |
| 50 static int cur_profile = -1; | 51 static int cur_profile = -1; |
| 51 | 52 |
| 52 static struct connman_storage_ident default_ident = { | 53 static struct connman_storage_ident default_ident = { |
| 53 .ident = PROFILE_DEFAULT_IDENT | 54 .ident = PROFILE_DEFAULT_IDENT |
| 54 }; | 55 }; |
| 55 static struct connman_profile *default_profile = NULL; | 56 static struct connman_profile *default_profile = NULL; |
| 56 | 57 |
| 57 static DBusConnection *connection = NULL; | 58 static DBusConnection *connection = NULL; |
| 58 | 59 |
| 60 /* | |
| 61 * Loading/Saving objects. | |
| 62 * | |
| 63 * Service objects go to the profile they are pinned too (typically | |
|
Paul Stewart
2011/03/30 00:56:18
s/too/to/
| |
| 64 * the active profile at the time they were created but this can be | |
| 65 * changed, e.g. from private -> global). | |
| 66 * | |
| 67 * Device and ipconfig objects go in the global profile (if any). | |
| 68 * This ensures that enable/disable state is maintained between | |
| 69 * users (and reboots); or possibly discarded (e.g. for testing). | |
| 70 * | |
| 71 * Likewise global state like offline mode is stored in the global | |
| 72 * profile (see above). | |
| 73 */ | |
| 74 | |
| 75 /* | |
| 76 * Return the active profile; it's on the top of the stack. | |
| 77 */ | |
| 78 static inline struct connman_profile *active_profile(void) | |
| 79 { | |
| 80 return cur_profile >= 0 ? profile_stack[cur_profile] : NULL; | |
| 81 } | |
| 82 | |
| 83 /* | |
| 84 * Return the global profile; it's top-most non-user profile. | |
| 85 */ | |
| 86 static struct connman_profile *global_profile(void) | |
| 87 { | |
| 88 /* TODO(sleffler) cheat for now */ | |
| 89 return default_profile != NULL ? default_profile : NULL; | |
| 90 } | |
| 91 | |
| 59 static int ident_equal(const struct connman_storage_ident *a, | 92 static int ident_equal(const struct connman_storage_ident *a, |
| 60 const struct connman_storage_ident *b) | 93 const struct connman_storage_ident *b) |
| 61 { | 94 { |
| 62 return (g_strcmp0(a->user, b->user) == 0 && | 95 return (g_strcmp0(a->user, b->user) == 0 && |
| 63 g_strcmp0(a->ident, b->ident) == 0); | 96 g_strcmp0(a->ident, b->ident) == 0); |
| 64 } | 97 } |
| 65 | 98 |
| 66 static void append_path(gpointer key, gpointer value, gpointer user_data) | 99 static void append_path(gpointer key, gpointer value, gpointer user_data) |
| 67 { | 100 { |
| 68 struct connman_profile *profile = value; | 101 struct connman_profile *profile = value; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 79 | 112 |
| 80 static void profiles_changed(void) | 113 static void profiles_changed(void) |
| 81 { | 114 { |
| 82 connman_dbus_send_property_changed_array(CONNMAN_MANAGER_PATH, | 115 connman_dbus_send_property_changed_array(CONNMAN_MANAGER_PATH, |
| 83 CONNMAN_MANAGER_INTERFACE, "Profiles", | 116 CONNMAN_MANAGER_INTERFACE, "Profiles", |
| 84 DBUS_TYPE_OBJECT_PATH, __connman_profile_list, NULL); | 117 DBUS_TYPE_OBJECT_PATH, __connman_profile_list, NULL); |
| 85 } | 118 } |
| 86 | 119 |
| 87 connman_bool_t __connman_profile_get_offlinemode(void) | 120 connman_bool_t __connman_profile_get_offlinemode(void) |
| 88 { | 121 { |
| 89 » return (default_profile == NULL) ? FALSE : default_profile->offlinemode; | 122 » struct connman_profile *profile = global_profile(); |
| 123 » return (profile == NULL) ? FALSE : profile->offlinemode; | |
| 90 } | 124 } |
| 91 | 125 |
| 92 int __connman_profile_set_offlinemode(connman_bool_t offlinemode) | 126 int __connman_profile_set_offlinemode(connman_bool_t offlinemode) |
| 93 { | 127 { |
| 94 » _DBG_PROFILE("offlinemode %d", offlinemode); | 128 » struct connman_profile *profile = global_profile(); |
| 129 » int ret; | |
| 95 | 130 |
| 96 » /* TODO(sleffler) disallow if no default profile? */ | 131 » _DBG_PROFILE("offlinemode %d profile %p", offlinemode, profile); |
| 97 » if (default_profile != NULL) { | 132 |
| 133 » /* NB: always succeeds (ATM) */ | |
| 134 » ret = __connman_device_set_offlinemode(offlinemode); | |
| 135 » if (ret != 0) | |
| 136 » » return ret; | |
| 137 | |
| 138 » /* TODO(sleffler) sallow even if no global profile? */ | |
| 139 » if (profile != NULL) { | |
| 98 /* | 140 /* |
| 99 * OfflineMode is only saved to the default profile; | 141 * OfflineMode is only saved to the default profile; |
| 100 * this ensures it is preserved across user changes. | 142 * this ensures it is preserved across user changes. |
| 101 */ | 143 */ |
| 102 » » if (default_profile->offlinemode == offlinemode) | 144 » » if (profile->offlinemode == offlinemode) |
| 103 return -EALREADY; | 145 return -EALREADY; |
| 104 | 146 |
| 105 » » default_profile->offlinemode = offlinemode; | 147 » » profile->offlinemode = offlinemode; |
| 106 | 148 |
| 107 connman_dbus_send_property_changed_variant( | 149 connman_dbus_send_property_changed_variant( |
| 108 » » default_profile->path, | 150 » » profile->path, |
| 109 CONNMAN_PROFILE_INTERFACE, "OfflineMode", | 151 CONNMAN_PROFILE_INTERFACE, "OfflineMode", |
| 110 DBUS_TYPE_BOOLEAN, &offlinemode); | 152 DBUS_TYPE_BOOLEAN, &offlinemode); |
| 153 | |
| 154 __connman_storage_save_profile(profile); | |
| 111 } | 155 } |
| 112 » return __connman_device_set_offlinemode(offlinemode); | 156 » return 0; |
| 113 } | 157 } |
| 114 | 158 |
| 115 /* | |
| 116 * Return the active profile; it's on the top of the stack. | |
| 117 */ | |
| 118 static inline struct connman_profile *active_profile(void) | |
| 119 { | |
| 120 return cur_profile >= 0 ? profile_stack[cur_profile] : NULL; | |
| 121 } | |
| 122 | |
| 123 /* | |
| 124 * Load/Save objects. When loading we walk the stack of profiles | |
| 125 * until we find a successful load. Saving always happens to the | |
| 126 * top-most/active profile. | |
| 127 */ | |
| 128 | |
| 129 static inline int load_continue(int err) | 159 static inline int load_continue(int err) |
| 130 { | 160 { |
| 131 » /* NB: ENXIO for no file, ESRCH for no group/key */ | 161 » /* NB: ENXIO for no file, ESRCH for no entry */ |
| 132 return (err == -ENXIO || err == -ESRCH); | 162 return (err == -ENXIO || err == -ESRCH); |
| 133 } | 163 } |
| 134 | 164 |
| 135 int __connman_profile_load_service(struct connman_service *service) | 165 int __connman_profile_load_service(struct connman_service *service) |
| 136 { | 166 { |
| 137 » int i, err; | 167 » struct connman_profile *profile = |
| 168 » __connman_service_get_profile(service); | |
| 169 » int err, i; | |
| 138 | 170 |
| 139 » _DBG_PROFILE("service %p", service); | 171 » _DBG_PROFILE("service %p profile %p", service, profile); |
| 140 | 172 |
| 173 if (profile != NULL) | |
| 174 return __connman_storage_load_service(service, &profile->ident); | |
| 175 /* | |
| 176 * Not bound to a profile yet, search the stack for an | |
| 177 * entry and if found bind the profile to the service. | |
| 178 */ | |
| 141 err = 0; | 179 err = 0; |
| 142 for (i = cur_profile; i >= 0; i--) { | 180 for (i = cur_profile; i >= 0; i--) { |
| 143 » » const struct connman_profile *profile = profile_stack[i]; | 181 » » profile = profile_stack[i]; |
| 144 | |
| 145 err = __connman_storage_load_service(service, &profile->ident); | 182 err = __connman_storage_load_service(service, &profile->ident); |
| 183 if (err == 0) { | |
| 184 _DBG_PROFILE("bind to profile %p", profile); | |
| 185 __connman_service_set_profile(service, profile); | |
| 186 return 0; | |
| 187 } | |
| 146 if (!load_continue(err)) | 188 if (!load_continue(err)) |
| 147 break; | 189 break; |
| 148 } | 190 } |
| 149 return err; | 191 return err; |
| 150 } | 192 } |
| 151 | 193 |
| 152 int __connman_profile_save_service(struct connman_service *service) | 194 int __connman_profile_save_service(struct connman_service *service) |
| 153 { | 195 { |
| 154 » struct connman_profile *profile = active_profile(); | 196 » struct connman_profile *profile = |
| 197 » __connman_service_get_profile(service); | |
| 155 | 198 |
| 156 _DBG_PROFILE("service %p profile %p", service, profile); | 199 _DBG_PROFILE("service %p profile %p", service, profile); |
| 157 | 200 |
| 201 if (profile == NULL) { | |
| 202 /* not bound yet, bind to the active profile */ | |
| 203 profile = active_profile(); | |
| 204 _DBG_PROFILE("bind to profile %p", profile); | |
| 205 __connman_service_set_profile(service, profile); | |
| 206 } | |
| 158 return (profile == NULL) ? 0 : | 207 return (profile == NULL) ? 0 : |
| 159 __connman_storage_save_service(service, &profile->ident); | 208 __connman_storage_save_service(service, &profile->ident); |
| 160 } | 209 } |
| 161 | 210 |
| 162 int __connman_profile_load_device(struct connman_device *device) | 211 int __connman_profile_load_device(struct connman_device *device) |
| 163 { | 212 { |
| 164 » int i, err; | 213 » struct connman_profile *profile = global_profile(); |
| 165 | 214 |
| 166 » _DBG_PROFILE("device %p", device); | 215 » _DBG_PROFILE("device %p profile %p", device, profile); |
| 167 | 216 |
| 168 » err = 0; | 217 » return (profile == NULL) ? 0 : |
| 169 » for (i = cur_profile; i >= 0; i--) { | 218 » __connman_storage_load_device(device, &profile->ident); |
| 170 » » const struct connman_profile *profile = profile_stack[i]; | |
| 171 | |
| 172 » » err = __connman_storage_load_device(device, &profile->ident); | |
| 173 » » if (!load_continue(err)) | |
| 174 » » » break; | |
| 175 » } | |
| 176 » return err; | |
| 177 } | 219 } |
| 178 | 220 |
| 179 int __connman_profile_save_device(struct connman_device *device) | 221 int __connman_profile_save_device(struct connman_device *device) |
| 180 { | 222 { |
| 181 » struct connman_profile *profile = active_profile(); | 223 » struct connman_profile *profile = global_profile(); |
| 182 | 224 |
| 183 _DBG_PROFILE("device %p profile %p", device, profile); | 225 _DBG_PROFILE("device %p profile %p", device, profile); |
| 184 | 226 |
| 185 return (profile == NULL) ? 0: | 227 return (profile == NULL) ? 0: |
| 186 __connman_storage_save_device(device, &profile->ident); | 228 __connman_storage_save_device(device, &profile->ident); |
| 187 } | 229 } |
| 188 | 230 |
| 189 int __connman_profile_load_ipconfig(struct connman_ipconfig *ipconfig) | 231 int __connman_profile_load_ipconfig(struct connman_ipconfig *ipconfig) |
| 190 { | 232 { |
| 191 » int i, err; | 233 » struct connman_profile *profile = global_profile(); |
| 192 | 234 |
| 193 » _DBG_PROFILE("ipconfig %p", ipconfig); | 235 » _DBG_PROFILE("ipconfig %p profile %p", ipconfig, profile); |
| 194 | 236 |
| 195 » err = 0; | 237 » return (profile == NULL) ? 0: |
| 196 » for (i = cur_profile; i >= 0; i--) { | 238 » __connman_storage_load_ipconfig(ipconfig, &profile->ident); |
| 197 » » const struct connman_profile *profile = profile_stack[i]; | |
| 198 | |
| 199 » » err = __connman_storage_load_ipconfig(ipconfig, | |
| 200 » » &profile->ident); | |
| 201 » » if (!load_continue(err)) | |
| 202 » » » break; | |
| 203 » } | |
| 204 » return err; | |
| 205 } | 239 } |
| 206 | 240 |
| 207 int __connman_profile_save_ipconfig(const struct connman_ipconfig *ipconfig) | 241 int __connman_profile_save_ipconfig(const struct connman_ipconfig *ipconfig) |
| 208 { | 242 { |
| 209 » struct connman_profile *profile = active_profile(); | 243 » struct connman_profile *profile = global_profile(); |
| 210 | 244 |
| 211 _DBG_PROFILE("ipconfig %p profile %p", ipconfig, profile); | 245 _DBG_PROFILE("ipconfig %p profile %p", ipconfig, profile); |
| 212 | 246 |
| 213 return (profile == NULL) ? 0 : | 247 return (profile == NULL) ? 0 : |
| 214 __connman_storage_save_ipconfig(ipconfig, &profile->ident); | 248 __connman_storage_save_ipconfig(ipconfig, &profile->ident); |
| 215 } | 249 } |
| 216 | 250 |
| 217 int __connman_profile_append_hidden_ssids(GSList **hidden_ssids, | 251 int __connman_profile_append_hidden_ssids(GSList **hidden_ssids, |
| 218 void (*append_hidden_ssids)(GKeyFile *keyfile, GSList **hidden_ssids)) | 252 void (*append_hidden_ssids)(GKeyFile *keyfile, GSList **hidden_ssids)) |
| 219 { | 253 { |
| 220 int i; | 254 int i; |
| 221 | 255 |
| 222 _DBG_PROFILE(""); | 256 _DBG_PROFILE(""); |
| 223 | 257 |
| 224 for (i = cur_profile; i >= 0; i--) { | 258 for (i = cur_profile; i >= 0; i--) { |
| 225 const struct connman_profile *profile = profile_stack[i]; | 259 const struct connman_profile *profile = profile_stack[i]; |
| 226 GKeyFile *keyfile; | 260 GKeyFile *keyfile; |
| 227 | 261 |
| 228 keyfile = __connman_storage_open(&profile->ident); | 262 keyfile = __connman_storage_open(&profile->ident); |
| 229 if (keyfile != NULL) { | 263 if (keyfile != NULL) { |
| 230 append_hidden_ssids(keyfile, hidden_ssids); | 264 append_hidden_ssids(keyfile, hidden_ssids); |
| 231 __connman_storage_close(&profile->ident, keyfile, | 265 __connman_storage_close(&profile->ident, keyfile, |
| 232 FALSE); | 266 FALSE); |
| 233 } | 267 } |
| 234 } | 268 } |
| 235 return 0; | 269 return 0; |
| 236 } | 270 } |
| 237 | 271 |
| 238 /* | 272 /* |
| 239 * Save the default profile if registered. | 273 * Return the object path for the specified profile. |
| 240 */ | 274 */ |
| 241 int __connman_profile_save_default(void) | 275 const char *__connman_profile_get_path(const struct connman_profile *profile) |
| 242 { | 276 { |
| 243 » if (default_profile != NULL) | 277 » return profile != NULL ? profile->path : NULL; |
| 244 » » __connman_storage_save_profile(default_profile); | |
| 245 » return 0; | |
| 246 } | 278 } |
| 247 | 279 |
| 248 /* | 280 /* |
| 249 * Save the active profile (if any). | 281 * Return the profile given an object path. |
| 250 */ | 282 */ |
| 251 int __connman_profile_save_active(void) | 283 struct connman_profile *__connman_profile_lookup_profile(const char *path) |
| 252 { | 284 { |
| 253 » struct connman_profile *profile = active_profile(); | 285 » return g_hash_table_lookup(profile_hash, path); |
| 254 » return (profile == NULL) ? -EINVAL : | |
| 255 » __connman_storage_save_profile(profile); | |
| 256 } | 286 } |
| 257 | 287 |
| 258 /* | 288 /* |
| 259 * Return the identifier for the active profile or NULL | 289 * Return the active profile or NULL |
| 260 * if there is none. | |
| 261 */ | 290 */ |
| 291 struct connman_profile *__connman_profile_active_profile(void) | |
| 292 { | |
| 293 return active_profile(); | |
| 294 } | |
| 295 | |
| 262 const struct connman_storage_ident *__connman_profile_active_ident(void) | 296 const struct connman_storage_ident *__connman_profile_active_ident(void) |
| 263 { | 297 { |
| 264 struct connman_profile *profile = active_profile(); | 298 struct connman_profile *profile = active_profile(); |
| 265 return profile != NULL ? &profile->ident : NULL; | 299 return profile != NULL ? &profile->ident : NULL; |
| 266 } | 300 } |
| 267 | 301 |
| 268 /* | 302 /* |
| 269 * Return the object path for the active profile or NULL | 303 * Return the object path for the active profile or NULL |
| 270 * if there is none. | 304 * if there is none. |
| 271 */ | 305 */ |
| 272 const char *__connman_profile_active_path(void) | 306 const char *__connman_profile_active_path(void) |
| 273 { | 307 { |
| 274 struct connman_profile *profile = active_profile(); | 308 struct connman_profile *profile = active_profile(); |
| 275 return profile != NULL ? profile->path : NULL; | 309 return profile != NULL ? profile->path : NULL; |
| 276 } | 310 } |
| 277 | 311 |
| 278 static guint changed_timeout = 0; | 312 /* |
| 313 * Delete an entry in the specified profile. | |
| 314 */ | |
| 315 int __connman_profile_delete_entry(struct connman_profile *profile, | |
| 316 const char *group) | |
| 317 { | |
| 318 » GKeyFile *keyfile; | |
| 319 » gboolean status; | |
| 279 | 320 |
| 280 static void clear_timeout(void) | 321 » _DBG_PROFILE("profile %p group %s", profile, group); |
| 322 | |
| 323 » keyfile = __connman_storage_open(&profile->ident); | |
| 324 » if (keyfile == NULL) { | |
| 325 » » _DBG_PROFILE("cannot open key file"); | |
| 326 » » return -EINVAL; | |
| 327 » } | |
| 328 | |
| 329 » status = g_key_file_remove_group(keyfile, group, NULL); | |
| 330 » __connman_storage_close(&profile->ident, keyfile, status); | |
| 331 | |
| 332 » if (status == FALSE) { | |
| 333 » » _DBG_PROFILE("cannot remove %s", group); | |
| 334 » » return -ENXIO; | |
| 335 » } | |
| 336 » return 0; | |
| 337 } | |
| 338 | |
| 339 static void clear_timeout(struct connman_profile *profile) | |
| 281 { | 340 { |
| 282 » if (changed_timeout > 0) { | 341 » if (profile->changed_timeout > 0) { |
| 283 » » g_source_remove(changed_timeout); | 342 » » g_source_remove(profile->changed_timeout); |
| 284 » » changed_timeout = 0; | 343 » » profile->changed_timeout = 0; |
| 285 } | 344 } |
| 286 } | 345 } |
| 287 | 346 |
| 288 static void append_services(DBusMessageIter *iter, void *arg) | 347 static void append_services(DBusMessageIter *iter, void *arg) |
| 289 { | 348 { |
| 290 __connman_service_list(iter, arg); | 349 __connman_service_list(iter, arg); |
| 291 } | 350 } |
| 292 static gboolean services_changed(gpointer user_data) | 351 static gboolean services_changed(gpointer user_data) |
| 293 { | 352 { |
| 294 » struct connman_profile *profile = active_profile(); | 353 » struct connman_profile *profile = user_data; |
| 295 | 354 |
| 296 » changed_timeout = 0; | 355 » profile->changed_timeout = 0; |
| 297 | 356 |
| 298 if (profile != NULL) { | 357 if (profile != NULL) { |
| 299 connman_dbus_send_property_changed_array(profile->path, | 358 connman_dbus_send_property_changed_array(profile->path, |
| 300 CONNMAN_PROFILE_INTERFACE, "Services", | 359 CONNMAN_PROFILE_INTERFACE, "Services", |
| 301 DBUS_TYPE_OBJECT_PATH, append_services, NULL); | 360 DBUS_TYPE_OBJECT_PATH, append_services, NULL); |
| 302 } | 361 } |
| 303 | 362 |
| 304 connman_dbus_send_property_changed_array(CONNMAN_MANAGER_PATH, | 363 connman_dbus_send_property_changed_array(CONNMAN_MANAGER_PATH, |
| 305 CONNMAN_MANAGER_INTERFACE, "Services", | 364 CONNMAN_MANAGER_INTERFACE, "Services", |
| 306 DBUS_TYPE_OBJECT_PATH, append_services, NULL); | 365 DBUS_TYPE_OBJECT_PATH, append_services, NULL); |
| 307 return FALSE; | 366 return FALSE; |
| 308 } | 367 } |
| 309 | 368 |
| 310 /* | 369 /* |
| 311 * Handle changes to the profile. Generate PropertyChanged signals | 370 * Handle changes to a profile. Generate PropertyChanged signals |
| 312 * on Manager.Services and Profile.Services for the currently active | 371 * on Manager.Services and Profile.Services for the currently active |
| 313 * profile. To minimize overhead requests may be coalesced using a | 372 * profile. To minimize overhead requests may be coalesced using a |
| 314 * 1 second delay on the signals. | 373 * 1 second delay on the signals. |
| 315 */ | 374 */ |
| 316 void __connman_profile_changed(gboolean delayed) | 375 void __connman_profile_changed(struct connman_profile *profile, |
| 376 gboolean delayed) | |
| 317 { | 377 { |
| 318 » _DBG_PROFILE("delayed %d changed_timeout %d", delayed, changed_timeout); | 378 » if (profile == NULL) |
| 379 » » return; | |
| 319 | 380 |
| 320 » clear_timeout(); | 381 » _DBG_PROFILE("profile %p delayed %d changed_timeout %d", |
| 382 » profile, delayed, profile->changed_timeout); | |
| 383 | |
| 384 » clear_timeout(profile); | |
| 321 | 385 |
| 322 if (delayed == TRUE) { | 386 if (delayed == TRUE) { |
| 323 » » changed_timeout = g_timeout_add_seconds(1, services_changed, | 387 » » profile->changed_timeout = g_timeout_add_seconds(1, |
| 324 » » NULL); | 388 » » services_changed, profile); |
| 325 } else | 389 } else |
| 326 » » services_changed(NULL); | 390 » » services_changed(profile); |
| 327 } | 391 } |
| 328 | 392 |
| 329 int __connman_profile_add_device(struct connman_device *device) | 393 int __connman_profile_add_device(struct connman_device *device) |
| 330 { | 394 { |
| 331 struct connman_service *service; | 395 struct connman_service *service; |
| 332 | 396 |
| 333 _DBG_PROFILE("device %p", device); | 397 _DBG_PROFILE("device %p", device); |
| 334 | 398 |
| 335 service = __connman_service_create_from_device(device); | 399 service = __connman_service_create_from_device(device); |
| 336 if (service == NULL) | 400 if (service == NULL) |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 454 | 518 |
| 455 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY, | 519 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY, |
| 456 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING | 520 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING |
| 457 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING | 521 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING |
| 458 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); | 522 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); |
| 459 | 523 |
| 460 if (profile->name != NULL) | 524 if (profile->name != NULL) |
| 461 connman_dbus_dict_append_variant(&dict, "Name", | 525 connman_dbus_dict_append_variant(&dict, "Name", |
| 462 DBUS_TYPE_STRING, &profile->name); | 526 DBUS_TYPE_STRING, &profile->name); |
| 463 | 527 |
| 464 » if (profile == default_profile) | 528 » if (profile == global_profile()) |
| 465 connman_dbus_dict_append_variant(&dict, "OfflineMode", | 529 connman_dbus_dict_append_variant(&dict, "OfflineMode", |
| 466 DBUS_TYPE_BOOLEAN, &profile->offlinemode); | 530 DBUS_TYPE_BOOLEAN, &profile->offlinemode); |
| 467 | 531 |
| 468 if (profile == active_profile()) | 532 if (profile == active_profile()) |
| 469 connman_dbus_dict_append_variant_array(&dict, "Services", | 533 connman_dbus_dict_append_variant_array(&dict, "Services", |
| 470 DBUS_TYPE_OBJECT_PATH, __connman_service_list, NULL); | 534 DBUS_TYPE_OBJECT_PATH, __connman_service_list, NULL); |
| 471 | 535 |
| 472 connman_dbus_dict_append_variant_array(&dict, "Entries", | 536 connman_dbus_dict_append_variant_array(&dict, "Entries", |
| 473 DBUS_TYPE_STRING, __profile_entry_list, profile); | 537 DBUS_TYPE_STRING, __profile_entry_list, profile); |
| 474 | 538 |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 643 #undef ADD_STR | 707 #undef ADD_STR |
| 644 } | 708 } |
| 645 | 709 |
| 646 static DBusMessage *delete_entry(DBusConnection *conn, | 710 static DBusMessage *delete_entry(DBusConnection *conn, |
| 647 DBusMessage *msg, void *data) | 711 DBusMessage *msg, void *data) |
| 648 { | 712 { |
| 649 struct connman_profile *profile = data; | 713 struct connman_profile *profile = data; |
| 650 DBusMessageIter iter; | 714 DBusMessageIter iter; |
| 651 const char *identifier; | 715 const char *identifier; |
| 652 struct connman_service *service; | 716 struct connman_service *service; |
| 653 » GKeyFile *keyfile; | 717 » int err; |
| 654 » gboolean status; | |
| 655 | 718 |
| 656 _DBG_PROFILE("profile %s:%s", profile->ident.user, | 719 _DBG_PROFILE("profile %s:%s", profile->ident.user, |
| 657 profile->ident.ident); | 720 profile->ident.ident); |
| 658 | 721 |
| 659 if (dbus_message_iter_init(msg, &iter) == FALSE) | 722 if (dbus_message_iter_init(msg, &iter) == FALSE) |
| 660 return __connman_error_invalid_arguments(msg); | 723 return __connman_error_invalid_arguments(msg); |
| 661 | 724 |
| 662 dbus_message_iter_get_basic(&iter, &identifier); | 725 dbus_message_iter_get_basic(&iter, &identifier); |
| 663 | 726 |
| 664 if (__connman_security_check_privilege(msg, | 727 if (__connman_security_check_privilege(msg, |
| 665 CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0) | 728 CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0) |
| 666 return __connman_error_permission_denied(msg); | 729 return __connman_error_permission_denied(msg); |
| 667 | 730 |
| 668 service = __connman_service_lookup(identifier); | 731 service = __connman_service_lookup(identifier); |
| 669 if (service != NULL) { | 732 if (service != NULL) { |
| 670 /* NB: this does not remove the service */ | 733 /* NB: this does not remove the service */ |
| 671 __connman_service_reset(service); | 734 __connman_service_reset(service); |
| 672 } | 735 } |
| 673 | 736 |
| 674 /* Remove directly from profile */ | 737 /* Remove directly from profile */ |
| 675 » keyfile = __connman_storage_open(&profile->ident); | 738 » err = __connman_profile_delete_entry(profile, identifier); |
| 676 » if (keyfile == NULL) { | 739 » if (err) |
| 677 » » _DBG_PROFILE("cannot open key file"); | 740 » » return __connman_error_failed(msg, -err); |
| 678 » » return __connman_error_invalid_arguments(msg); | |
| 679 » } | |
| 680 | |
| 681 » status = g_key_file_remove_group(keyfile, identifier, NULL); | |
| 682 » __connman_storage_close(&profile->ident, keyfile, status); | |
| 683 | |
| 684 » if (status == FALSE) { | |
| 685 » » _DBG_PROFILE("cannot remove %s", identifier); | |
| 686 » » return __connman_error_not_found(msg); | |
| 687 » } | |
| 688 | 741 |
| 689 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); | 742 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); |
| 690 } | 743 } |
| 691 | 744 |
| 692 static GDBusMethodTable profile_methods[] = { | 745 static GDBusMethodTable profile_methods[] = { |
| 693 { "GetProperties", "", "a{sv}", get_properties }, | 746 { "GetProperties", "", "a{sv}", get_properties }, |
| 694 { "SetProperty", "sv", "", set_property }, | 747 { "SetProperty", "sv", "", set_property }, |
| 695 { "GetEntry", "s", "a{sv}", get_entry }, | 748 { "GetEntry", "s", "a{sv}", get_entry }, |
| 696 { "DeleteEntry", "s", "", delete_entry }, | 749 { "DeleteEntry", "s", "", delete_entry }, |
| 697 { }, | 750 { }, |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 724 struct connman_profile *profile = data; | 777 struct connman_profile *profile = data; |
| 725 | 778 |
| 726 _DBG_PROFILE("profile %p", profile); | 779 _DBG_PROFILE("profile %p", profile); |
| 727 | 780 |
| 728 connman_info("Remove profile %s:%s", profile->ident.user, | 781 connman_info("Remove profile %s:%s", profile->ident.user, |
| 729 profile->ident.ident); | 782 profile->ident.ident); |
| 730 | 783 |
| 731 g_dbus_unregister_interface(connection, profile->path, | 784 g_dbus_unregister_interface(connection, profile->path, |
| 732 CONNMAN_PROFILE_INTERFACE); | 785 CONNMAN_PROFILE_INTERFACE); |
| 733 | 786 |
| 787 clear_timeout(profile); | |
| 788 | |
| 734 if (profile == default_profile) | 789 if (profile == default_profile) |
| 735 default_profile = NULL; | 790 default_profile = NULL; |
| 736 | 791 |
| 737 free_profile(profile); | 792 free_profile(profile); |
| 738 } | 793 } |
| 739 | 794 |
| 740 static char *getpath(const struct connman_storage_ident *ident) | 795 static char *getpath(const struct connman_storage_ident *ident) |
| 741 { | 796 { |
| 742 if (ident->user != NULL) { | 797 if (ident->user != NULL) { |
| 743 /* NB: check for two tokens done in validate_ident */ | 798 /* NB: check for two tokens done in validate_ident */ |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 943 return -EEXIST; | 998 return -EEXIST; |
| 944 } | 999 } |
| 945 if (path != NULL) | 1000 if (path != NULL) |
| 946 *path = profile->path; | 1001 *path = profile->path; |
| 947 } | 1002 } |
| 948 | 1003 |
| 949 profile_stack[++cur_profile] = profile; | 1004 profile_stack[++cur_profile] = profile; |
| 950 | 1005 |
| 951 profiles_changed(); | 1006 profiles_changed(); |
| 952 | 1007 |
| 953 » /* NB: this is a noop if we are online (or trying to get online) */ | 1008 » __connman_notifier_profile_push(profile); |
| 954 » __connman_service_auto_connect_any(); | |
| 955 | 1009 |
| 956 return 0; | 1010 return 0; |
| 957 } | 1011 } |
| 958 | 1012 |
| 959 /* | 1013 /* |
| 960 * Pop the profile from the top of the stack and remove it from | 1014 * Pop the profile from the top of the stack and remove it from |
| 961 * the in-memory table. Any associated services are invalidated | 1015 * the in-memory table. Any associated services are invalidated |
| 962 * (credentials revoked and connections closed). After a pop we | 1016 * (credentials revoked and connections closed). After a pop we |
| 963 * generate a PropertyChanged signal for Manager.Profiles. | 1017 * generate a PropertyChanged signal for Manager.Profiles. |
| 964 * | 1018 * |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 991 } | 1045 } |
| 992 if (ident_equal(&profile->ident, &sid) == FALSE) { | 1046 if (ident_equal(&profile->ident, &sid) == FALSE) { |
| 993 connman_error("%s: %s is not the active profile", | 1047 connman_error("%s: %s is not the active profile", |
| 994 __func__, ident); | 1048 __func__, ident); |
| 995 free_ident(&sid); | 1049 free_ident(&sid); |
| 996 return -ENXIO; | 1050 return -ENXIO; |
| 997 } | 1051 } |
| 998 free_ident(&sid); | 1052 free_ident(&sid); |
| 999 } | 1053 } |
| 1000 | 1054 |
| 1001 » __connman_service_invalidate_profile(&profile->ident); | 1055 » /* |
| 1056 » * Pop the stack, invalidate all objects holding references | |
| 1057 » * to the profile, then remove it from the in-memory table. | |
| 1058 » * We do the reclaim after notification in case anyone holding | |
| 1059 » * a reference tries to use it. | |
| 1060 » */ | |
| 1061 » cur_profile--; | |
| 1062 | |
| 1063 » __connman_notifier_profile_pop(profile); | |
| 1002 | 1064 |
| 1003 g_hash_table_remove(profile_hash, profile->path); | 1065 g_hash_table_remove(profile_hash, profile->path); |
| 1004 cur_profile--; | |
| 1005 | 1066 |
| 1006 profiles_changed(); | 1067 profiles_changed(); |
| 1007 | 1068 |
| 1008 /* NB: no need to kick auto-connect; it will happen due to invalidate */ | |
| 1009 | |
| 1010 return 0; | 1069 return 0; |
| 1011 } | 1070 } |
| 1012 | 1071 |
| 1013 /* | 1072 /* |
| 1014 * Create a profile file and register it in memory. The | 1073 * Create a profile file and register it in memory. The |
| 1015 * file is created with minimal contents. | 1074 * file is created with minimal contents. |
| 1016 * TODO(sleffler) disallow overwriting an existing file? | 1075 * TODO(sleffler) disallow overwriting an existing file? |
| 1017 */ | 1076 */ |
| 1018 int __connman_profile_create(const char *name, const char **path) | 1077 int __connman_profile_create(const char *name, const char **path) |
| 1019 { | 1078 { |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1215 | 1274 |
| 1216 if (connection == NULL) | 1275 if (connection == NULL) |
| 1217 return; | 1276 return; |
| 1218 | 1277 |
| 1219 while (cur_profile >= 0) | 1278 while (cur_profile >= 0) |
| 1220 __connman_profile_pop(NULL); | 1279 __connman_profile_pop(NULL); |
| 1221 | 1280 |
| 1222 g_hash_table_destroy(profile_hash); | 1281 g_hash_table_destroy(profile_hash); |
| 1223 profile_hash = NULL; | 1282 profile_hash = NULL; |
| 1224 | 1283 |
| 1225 clear_timeout(); /* cancel any pending timer */ | |
| 1226 | |
| 1227 connman_storage_unregister(&profile_storage); | 1284 connman_storage_unregister(&profile_storage); |
| 1228 | 1285 |
| 1229 dbus_connection_unref(connection); | 1286 dbus_connection_unref(connection); |
| 1230 } | 1287 } |
| OLD | NEW |