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

Side by Side Diff: src/profile.c

Issue 6731067: flimflam: revise multi-profile support to pin objects to a profile (Closed) Base URL: ssh://gitrw.chromium.org:9222/flimflam.git@master
Patch Set: 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/notifier.c ('k') | src/service.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « src/notifier.c ('k') | src/service.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698