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

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: fix diff Created 9 years, 8 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
58 static guint changed_timeout = 0; /* for NULL profile handling */
59
57 static DBusConnection *connection = NULL; 60 static DBusConnection *connection = NULL;
58 61
62 /*
63 * Loading/Saving objects.
64 *
65 * Service objects go to the profile they are pinned to (typically
66 * the active profile at the time they were created but this can be
67 * changed, e.g. from private -> global).
68 *
69 * Device and ipconfig objects go in the global profile (if any).
70 * This ensures that enable/disable state is maintained between
71 * users (and reboots); or possibly discarded (e.g. for testing).
72 *
73 * Likewise global state like offline mode is stored in the global
74 * profile (see above).
75 */
76
77 /*
78 * Return the active profile; it's on the top of the stack.
79 */
80 static inline struct connman_profile *active_profile(void)
81 {
82 return cur_profile >= 0 ? profile_stack[cur_profile] : NULL;
83 }
84
85 /*
86 * Return the global profile; it's top-most non-user profile.
87 */
88 static struct connman_profile *global_profile(void)
89 {
90 /* TODO(sleffler) cheat for now */
91 return default_profile != NULL ? default_profile : NULL;
92 }
93
59 static int ident_equal(const struct connman_storage_ident *a, 94 static int ident_equal(const struct connman_storage_ident *a,
60 const struct connman_storage_ident *b) 95 const struct connman_storage_ident *b)
61 { 96 {
62 return (g_strcmp0(a->user, b->user) == 0 && 97 return (g_strcmp0(a->user, b->user) == 0 &&
63 g_strcmp0(a->ident, b->ident) == 0); 98 g_strcmp0(a->ident, b->ident) == 0);
64 } 99 }
65 100
66 static void append_path(gpointer key, gpointer value, gpointer user_data) 101 static void append_path(gpointer key, gpointer value, gpointer user_data)
67 { 102 {
68 struct connman_profile *profile = value; 103 struct connman_profile *profile = value;
(...skipping 10 matching lines...) Expand all
79 114
80 static void profiles_changed(void) 115 static void profiles_changed(void)
81 { 116 {
82 connman_dbus_send_property_changed_array(CONNMAN_MANAGER_PATH, 117 connman_dbus_send_property_changed_array(CONNMAN_MANAGER_PATH,
83 CONNMAN_MANAGER_INTERFACE, "Profiles", 118 CONNMAN_MANAGER_INTERFACE, "Profiles",
84 DBUS_TYPE_OBJECT_PATH, __connman_profile_list, NULL); 119 DBUS_TYPE_OBJECT_PATH, __connman_profile_list, NULL);
85 } 120 }
86 121
87 connman_bool_t __connman_profile_get_offlinemode(void) 122 connman_bool_t __connman_profile_get_offlinemode(void)
88 { 123 {
89 » return (default_profile == NULL) ? FALSE : default_profile->offlinemode; 124 » struct connman_profile *profile = global_profile();
125 » return (profile == NULL) ? FALSE : profile->offlinemode;
90 } 126 }
91 127
92 int __connman_profile_set_offlinemode(connman_bool_t offlinemode) 128 int __connman_profile_set_offlinemode(connman_bool_t offlinemode)
93 { 129 {
94 » _DBG_PROFILE("offlinemode %d", offlinemode); 130 » struct connman_profile *profile = global_profile();
131 » int ret;
95 132
96 » /* TODO(sleffler) disallow if no default profile? */ 133 » _DBG_PROFILE("offlinemode %d profile %p", offlinemode, profile);
97 » if (default_profile != NULL) { 134
135 » /* NB: always succeeds (ATM) */
136 » ret = __connman_device_set_offlinemode(offlinemode);
137 » if (ret != 0)
138 » » return ret;
139
140 » /* TODO(sleffler) sallow even if no global profile? */
141 » if (profile != NULL) {
98 /* 142 /*
99 * OfflineMode is only saved to the default profile; 143 * OfflineMode is only saved to the default profile;
100 * this ensures it is preserved across user changes. 144 * this ensures it is preserved across user changes.
101 */ 145 */
102 » » if (default_profile->offlinemode == offlinemode) 146 » » if (profile->offlinemode == offlinemode)
103 return -EALREADY; 147 return -EALREADY;
104 148
105 » » default_profile->offlinemode = offlinemode; 149 » » profile->offlinemode = offlinemode;
106 150
107 connman_dbus_send_property_changed_variant( 151 connman_dbus_send_property_changed_variant(
108 » » default_profile->path, 152 » » profile->path,
109 CONNMAN_PROFILE_INTERFACE, "OfflineMode", 153 CONNMAN_PROFILE_INTERFACE, "OfflineMode",
110 DBUS_TYPE_BOOLEAN, &offlinemode); 154 DBUS_TYPE_BOOLEAN, &offlinemode);
155
156 __connman_storage_save_profile(profile);
111 } 157 }
112 » return __connman_device_set_offlinemode(offlinemode); 158 » return 0;
113 } 159 }
114 160
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) 161 static inline int load_continue(int err)
130 { 162 {
131 » /* NB: ENXIO for no file, ESRCH for no group/key */ 163 » /* NB: ENXIO for no file, ESRCH for no entry */
132 return (err == -ENXIO || err == -ESRCH); 164 return (err == -ENXIO || err == -ESRCH);
133 } 165 }
134 166
135 int __connman_profile_load_service(struct connman_service *service) 167 int __connman_profile_load_service(struct connman_service *service)
136 { 168 {
137 » int i, err; 169 » struct connman_profile *profile =
170 » __connman_service_get_profile(service);
171 » int err, i;
138 172
139 » _DBG_PROFILE("service %p", service); 173 » _DBG_PROFILE("service %p profile %p", service, profile);
140 174
175 if (profile != NULL)
176 return __connman_storage_load_service(service, &profile->ident);
177 /*
178 * Not bound to a profile yet, search the stack for an
179 * entry and if found bind the profile to the service.
180 */
141 err = 0; 181 err = 0;
142 for (i = cur_profile; i >= 0; i--) { 182 for (i = cur_profile; i >= 0; i--) {
143 » » const struct connman_profile *profile = profile_stack[i]; 183 » » profile = profile_stack[i];
144
145 err = __connman_storage_load_service(service, &profile->ident); 184 err = __connman_storage_load_service(service, &profile->ident);
185 if (err == 0) {
186 _DBG_PROFILE("bind to profile %p", profile);
187 __connman_service_set_profile(service, profile);
188 return 0;
189 }
146 if (!load_continue(err)) 190 if (!load_continue(err))
147 break; 191 break;
148 } 192 }
149 return err; 193 return err;
150 } 194 }
151 195
152 int __connman_profile_save_service(struct connman_service *service) 196 int __connman_profile_save_service(struct connman_service *service)
153 { 197 {
154 » struct connman_profile *profile = active_profile(); 198 » struct connman_profile *profile =
199 » __connman_service_get_profile(service);
155 200
156 _DBG_PROFILE("service %p profile %p", service, profile); 201 _DBG_PROFILE("service %p profile %p", service, profile);
157 202
203 if (profile == NULL) {
204 /* not bound yet, bind to the active profile */
205 profile = active_profile();
206 _DBG_PROFILE("bind to profile %p", profile);
207 __connman_service_set_profile(service, profile);
208 }
158 return (profile == NULL) ? 0 : 209 return (profile == NULL) ? 0 :
159 __connman_storage_save_service(service, &profile->ident); 210 __connman_storage_save_service(service, &profile->ident);
160 } 211 }
161 212
162 int __connman_profile_load_device(struct connman_device *device) 213 int __connman_profile_load_device(struct connman_device *device)
163 { 214 {
164 » int i, err; 215 » struct connman_profile *profile = global_profile();
165 216
166 » _DBG_PROFILE("device %p", device); 217 » _DBG_PROFILE("device %p profile %p", device, profile);
167 218
168 » err = 0; 219 » return (profile == NULL) ? 0 :
169 » for (i = cur_profile; i >= 0; i--) { 220 » __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 } 221 }
178 222
179 int __connman_profile_save_device(struct connman_device *device) 223 int __connman_profile_save_device(struct connman_device *device)
180 { 224 {
181 » struct connman_profile *profile = active_profile(); 225 » struct connman_profile *profile = global_profile();
182 226
183 _DBG_PROFILE("device %p profile %p", device, profile); 227 _DBG_PROFILE("device %p profile %p", device, profile);
184 228
185 return (profile == NULL) ? 0: 229 return (profile == NULL) ? 0:
186 __connman_storage_save_device(device, &profile->ident); 230 __connman_storage_save_device(device, &profile->ident);
187 } 231 }
188 232
189 int __connman_profile_load_ipconfig(struct connman_ipconfig *ipconfig) 233 int __connman_profile_load_ipconfig(struct connman_ipconfig *ipconfig)
190 { 234 {
191 » int i, err; 235 » struct connman_profile *profile = global_profile();
192 236
193 » _DBG_PROFILE("ipconfig %p", ipconfig); 237 » _DBG_PROFILE("ipconfig %p profile %p", ipconfig, profile);
194 238
195 » err = 0; 239 » return (profile == NULL) ? 0:
196 » for (i = cur_profile; i >= 0; i--) { 240 » __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 } 241 }
206 242
207 int __connman_profile_save_ipconfig(const struct connman_ipconfig *ipconfig) 243 int __connman_profile_save_ipconfig(const struct connman_ipconfig *ipconfig)
208 { 244 {
209 » struct connman_profile *profile = active_profile(); 245 » struct connman_profile *profile = global_profile();
210 246
211 _DBG_PROFILE("ipconfig %p profile %p", ipconfig, profile); 247 _DBG_PROFILE("ipconfig %p profile %p", ipconfig, profile);
212 248
213 return (profile == NULL) ? 0 : 249 return (profile == NULL) ? 0 :
214 __connman_storage_save_ipconfig(ipconfig, &profile->ident); 250 __connman_storage_save_ipconfig(ipconfig, &profile->ident);
215 } 251 }
216 252
217 int __connman_profile_append_hidden_ssids(GSList **hidden_ssids, 253 int __connman_profile_append_hidden_ssids(GSList **hidden_ssids,
218 void (*append_hidden_ssids)(GKeyFile *keyfile, GSList **hidden_ssids)) 254 void (*append_hidden_ssids)(GKeyFile *keyfile, GSList **hidden_ssids))
219 { 255 {
220 int i; 256 int i;
221 257
222 _DBG_PROFILE(""); 258 _DBG_PROFILE("");
223 259
224 for (i = cur_profile; i >= 0; i--) { 260 for (i = cur_profile; i >= 0; i--) {
225 const struct connman_profile *profile = profile_stack[i]; 261 const struct connman_profile *profile = profile_stack[i];
226 GKeyFile *keyfile; 262 GKeyFile *keyfile;
227 263
228 keyfile = __connman_storage_open(&profile->ident); 264 keyfile = __connman_storage_open(&profile->ident);
229 if (keyfile != NULL) { 265 if (keyfile != NULL) {
230 append_hidden_ssids(keyfile, hidden_ssids); 266 append_hidden_ssids(keyfile, hidden_ssids);
231 __connman_storage_close(&profile->ident, keyfile, 267 __connman_storage_close(&profile->ident, keyfile,
232 FALSE); 268 FALSE);
233 } 269 }
234 } 270 }
235 return 0; 271 return 0;
236 } 272 }
237 273
238 /* 274 /*
239 * Save the default profile if registered. 275 * Return the object path for the specified profile.
240 */ 276 */
241 int __connman_profile_save_default(void) 277 const char *__connman_profile_get_path(const struct connman_profile *profile)
242 { 278 {
243 » if (default_profile != NULL) 279 » return profile != NULL ? profile->path : NULL;
244 » » __connman_storage_save_profile(default_profile);
245 » return 0;
246 } 280 }
247 281
248 /* 282 /*
249 * Save the active profile (if any). 283 * Return the profile given an object path.
250 */ 284 */
251 int __connman_profile_save_active(void) 285 struct connman_profile *__connman_profile_lookup_profile(const char *path)
252 { 286 {
253 » struct connman_profile *profile = active_profile(); 287 » return g_hash_table_lookup(profile_hash, path);
254 » return (profile == NULL) ? -EINVAL :
255 » __connman_storage_save_profile(profile);
256 } 288 }
257 289
258 /* 290 /*
259 * Return the identifier for the active profile or NULL 291 * Return the active profile or NULL
260 * if there is none.
261 */ 292 */
293 struct connman_profile *__connman_profile_active_profile(void)
294 {
295 return active_profile();
296 }
297
262 const struct connman_storage_ident *__connman_profile_active_ident(void) 298 const struct connman_storage_ident *__connman_profile_active_ident(void)
263 { 299 {
264 struct connman_profile *profile = active_profile(); 300 struct connman_profile *profile = active_profile();
265 return profile != NULL ? &profile->ident : NULL; 301 return profile != NULL ? &profile->ident : NULL;
266 } 302 }
267 303
268 /* 304 /*
269 * Return the object path for the active profile or NULL 305 * Return the object path for the active profile or NULL
270 * if there is none. 306 * if there is none.
271 */ 307 */
272 const char *__connman_profile_active_path(void) 308 const char *__connman_profile_active_path(void)
273 { 309 {
274 struct connman_profile *profile = active_profile(); 310 struct connman_profile *profile = active_profile();
275 return profile != NULL ? profile->path : NULL; 311 return profile != NULL ? profile->path : NULL;
276 } 312 }
277 313
278 static guint changed_timeout = 0; 314 /*
315 * Delete an entry in the specified profile.
316 */
317 int __connman_profile_delete_entry(struct connman_profile *profile,
318 const char *group)
319 {
320 » GKeyFile *keyfile;
321 » gboolean status;
279 322
280 static void clear_timeout(void) 323 » _DBG_PROFILE("profile %p group %s", profile, group);
324
325 » keyfile = __connman_storage_open(&profile->ident);
326 » if (keyfile == NULL) {
327 » » _DBG_PROFILE("cannot open key file");
328 » » return -EINVAL;
329 » }
330
331 » status = g_key_file_remove_group(keyfile, group, NULL);
332 » __connman_storage_close(&profile->ident, keyfile, status);
333
334 » if (status == FALSE) {
335 » » _DBG_PROFILE("cannot remove %s", group);
336 » » return -ENXIO;
337 » }
338 » return 0;
339 }
340
341 static void __clear_timeout(guint *pchanged_timeout)
281 { 342 {
282 » if (changed_timeout > 0) { 343 » if (*pchanged_timeout > 0) {
283 » » g_source_remove(changed_timeout); 344 » » g_source_remove(*pchanged_timeout);
284 » » changed_timeout = 0; 345 » » *pchanged_timeout = 0;
285 } 346 }
286 } 347 }
287 348
349 static void clear_timeout(struct connman_profile *profile)
350 {
351 if (profile != NULL)
352 __clear_timeout(&profile->changed_timeout);
353 else
354 __clear_timeout(&changed_timeout);
355 }
356
288 static void append_services(DBusMessageIter *iter, void *arg) 357 static void append_services(DBusMessageIter *iter, void *arg)
289 { 358 {
290 __connman_service_list(iter, arg); 359 __connman_service_list(iter, arg);
291 } 360 }
292 static gboolean services_changed(gpointer user_data) 361 static gboolean services_changed(gpointer user_data)
293 { 362 {
294 » struct connman_profile *profile = active_profile(); 363 » struct connman_profile *profile = user_data;
295
296 » changed_timeout = 0;
297 364
298 if (profile != NULL) { 365 if (profile != NULL) {
366 profile->changed_timeout = 0;
367
299 connman_dbus_send_property_changed_array(profile->path, 368 connman_dbus_send_property_changed_array(profile->path,
300 CONNMAN_PROFILE_INTERFACE, "Services", 369 CONNMAN_PROFILE_INTERFACE, "Services",
301 DBUS_TYPE_OBJECT_PATH, append_services, NULL); 370 DBUS_TYPE_OBJECT_PATH, append_services, NULL);
302 » } 371 » } else
372 » » changed_timeout = 0;
303 373
304 connman_dbus_send_property_changed_array(CONNMAN_MANAGER_PATH, 374 connman_dbus_send_property_changed_array(CONNMAN_MANAGER_PATH,
305 CONNMAN_MANAGER_INTERFACE, "Services", 375 CONNMAN_MANAGER_INTERFACE, "Services",
306 DBUS_TYPE_OBJECT_PATH, append_services, NULL); 376 DBUS_TYPE_OBJECT_PATH, append_services, NULL);
307 return FALSE; 377 return FALSE;
308 } 378 }
309 379
310 /* 380 /*
311 * Handle changes to the profile. Generate PropertyChanged signals 381 * Handle changes to a profile. Generate PropertyChanged signals
312 * on Manager.Services and Profile.Services for the currently active 382 * on Manager.Services and Profile.Services for the currently active
313 * profile. To minimize overhead requests may be coalesced using a 383 * profile. To minimize overhead requests may be coalesced using a
314 * 1 second delay on the signals. 384 * 1 second delay on the signals.
315 */ 385 */
316 void __connman_profile_changed(gboolean delayed) 386 void __connman_profile_changed(struct connman_profile *profile,
387 gboolean delayed)
317 { 388 {
318 » _DBG_PROFILE("delayed %d changed_timeout %d", delayed, changed_timeout); 389 » _DBG_PROFILE("profile %p delayed %d changed_timeout %d",
390 » profile, delayed, profile != NULL ?
391 » profile->changed_timeout : changed_timeout);
319 392
320 » clear_timeout(); 393 » clear_timeout(profile);
321 394
322 if (delayed == TRUE) { 395 if (delayed == TRUE) {
323 » » changed_timeout = g_timeout_add_seconds(1, services_changed, 396 » » guint timeout = g_timeout_add_seconds(1,
324 » » NULL); 397 » » services_changed, profile);
398 » » if (profile != NULL)
399 » » » profile->changed_timeout = timeout;
400 » » else
401 » » » changed_timeout = timeout;
325 } else 402 } else
326 » » services_changed(NULL); 403 » » services_changed(profile);
327 } 404 }
328 405
329 int __connman_profile_add_device(struct connman_device *device) 406 int __connman_profile_add_device(struct connman_device *device)
330 { 407 {
331 struct connman_service *service; 408 struct connman_service *service;
332 409
333 _DBG_PROFILE("device %p", device); 410 _DBG_PROFILE("device %p", device);
334 411
335 service = __connman_service_create_from_device(device); 412 service = __connman_service_create_from_device(device);
336 if (service == NULL) 413 if (service == NULL)
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 531
455 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY, 532 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
456 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 533 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
457 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING 534 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
458 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); 535 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
459 536
460 if (profile->name != NULL) 537 if (profile->name != NULL)
461 connman_dbus_dict_append_variant(&dict, "Name", 538 connman_dbus_dict_append_variant(&dict, "Name",
462 DBUS_TYPE_STRING, &profile->name); 539 DBUS_TYPE_STRING, &profile->name);
463 540
464 » if (profile == default_profile) 541 » if (profile == global_profile())
465 connman_dbus_dict_append_variant(&dict, "OfflineMode", 542 connman_dbus_dict_append_variant(&dict, "OfflineMode",
466 DBUS_TYPE_BOOLEAN, &profile->offlinemode); 543 DBUS_TYPE_BOOLEAN, &profile->offlinemode);
467 544
468 if (profile == active_profile()) 545 if (profile == active_profile())
469 connman_dbus_dict_append_variant_array(&dict, "Services", 546 connman_dbus_dict_append_variant_array(&dict, "Services",
470 DBUS_TYPE_OBJECT_PATH, __connman_service_list, NULL); 547 DBUS_TYPE_OBJECT_PATH, __connman_service_list, NULL);
471 548
472 connman_dbus_dict_append_variant_array(&dict, "Entries", 549 connman_dbus_dict_append_variant_array(&dict, "Entries",
473 DBUS_TYPE_STRING, __profile_entry_list, profile); 550 DBUS_TYPE_STRING, __profile_entry_list, profile);
474 551
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 #undef ADD_STR 720 #undef ADD_STR
644 } 721 }
645 722
646 static DBusMessage *delete_entry(DBusConnection *conn, 723 static DBusMessage *delete_entry(DBusConnection *conn,
647 DBusMessage *msg, void *data) 724 DBusMessage *msg, void *data)
648 { 725 {
649 struct connman_profile *profile = data; 726 struct connman_profile *profile = data;
650 DBusMessageIter iter; 727 DBusMessageIter iter;
651 const char *identifier; 728 const char *identifier;
652 struct connman_service *service; 729 struct connman_service *service;
653 » GKeyFile *keyfile; 730 » int err;
654 » gboolean status;
655 731
656 _DBG_PROFILE("profile %s:%s", profile->ident.user, 732 _DBG_PROFILE("profile %s:%s", profile->ident.user,
657 profile->ident.ident); 733 profile->ident.ident);
658 734
659 if (dbus_message_iter_init(msg, &iter) == FALSE) 735 if (dbus_message_iter_init(msg, &iter) == FALSE)
660 return __connman_error_invalid_arguments(msg); 736 return __connman_error_invalid_arguments(msg);
661 737
662 dbus_message_iter_get_basic(&iter, &identifier); 738 dbus_message_iter_get_basic(&iter, &identifier);
663 739
664 if (__connman_security_check_privilege(msg, 740 if (__connman_security_check_privilege(msg,
665 CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0) 741 CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
666 return __connman_error_permission_denied(msg); 742 return __connman_error_permission_denied(msg);
667 743
668 service = __connman_service_lookup(identifier); 744 service = __connman_service_lookup(identifier);
669 if (service != NULL) { 745 if (service != NULL) {
670 /* NB: this does not remove the service */ 746 /* NB: this does not remove the service */
671 __connman_service_reset(service); 747 __connman_service_reset(service);
672 } 748 }
673 749
674 /* Remove directly from profile */ 750 /* Remove directly from profile */
675 » keyfile = __connman_storage_open(&profile->ident); 751 » err = __connman_profile_delete_entry(profile, identifier);
676 » if (keyfile == NULL) { 752 » if (err)
677 » » _DBG_PROFILE("cannot open key file"); 753 » » 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 754
689 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); 755 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
690 } 756 }
691 757
692 static GDBusMethodTable profile_methods[] = { 758 static GDBusMethodTable profile_methods[] = {
693 { "GetProperties", "", "a{sv}", get_properties }, 759 { "GetProperties", "", "a{sv}", get_properties },
694 { "SetProperty", "sv", "", set_property }, 760 { "SetProperty", "sv", "", set_property },
695 { "GetEntry", "s", "a{sv}", get_entry }, 761 { "GetEntry", "s", "a{sv}", get_entry },
696 { "DeleteEntry", "s", "", delete_entry }, 762 { "DeleteEntry", "s", "", delete_entry },
697 { }, 763 { },
(...skipping 26 matching lines...) Expand all
724 struct connman_profile *profile = data; 790 struct connman_profile *profile = data;
725 791
726 _DBG_PROFILE("profile %p", profile); 792 _DBG_PROFILE("profile %p", profile);
727 793
728 connman_info("Remove profile %s:%s", profile->ident.user, 794 connman_info("Remove profile %s:%s", profile->ident.user,
729 profile->ident.ident); 795 profile->ident.ident);
730 796
731 g_dbus_unregister_interface(connection, profile->path, 797 g_dbus_unregister_interface(connection, profile->path,
732 CONNMAN_PROFILE_INTERFACE); 798 CONNMAN_PROFILE_INTERFACE);
733 799
800 clear_timeout(profile);
801
734 if (profile == default_profile) 802 if (profile == default_profile)
735 default_profile = NULL; 803 default_profile = NULL;
736 804
737 free_profile(profile); 805 free_profile(profile);
738 } 806 }
739 807
740 static char *getpath(const struct connman_storage_ident *ident) 808 static char *getpath(const struct connman_storage_ident *ident)
741 { 809 {
742 if (ident->user != NULL) { 810 if (ident->user != NULL) {
743 /* NB: check for two tokens done in validate_ident */ 811 /* NB: check for two tokens done in validate_ident */
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 return -EEXIST; 1011 return -EEXIST;
944 } 1012 }
945 if (path != NULL) 1013 if (path != NULL)
946 *path = profile->path; 1014 *path = profile->path;
947 } 1015 }
948 1016
949 profile_stack[++cur_profile] = profile; 1017 profile_stack[++cur_profile] = profile;
950 1018
951 profiles_changed(); 1019 profiles_changed();
952 1020
953 » /* NB: this is a noop if we are online (or trying to get online) */ 1021 » __connman_notifier_profile_push(profile);
954 » __connman_service_auto_connect_any();
955 1022
956 return 0; 1023 return 0;
957 } 1024 }
958 1025
959 /* 1026 /*
960 * Pop the profile from the top of the stack and remove it from 1027 * Pop the profile from the top of the stack and remove it from
961 * the in-memory table. Any associated services are invalidated 1028 * the in-memory table. Any associated services are invalidated
962 * (credentials revoked and connections closed). After a pop we 1029 * (credentials revoked and connections closed). After a pop we
963 * generate a PropertyChanged signal for Manager.Profiles. 1030 * generate a PropertyChanged signal for Manager.Profiles.
964 * 1031 *
(...skipping 26 matching lines...) Expand all
991 } 1058 }
992 if (ident_equal(&profile->ident, &sid) == FALSE) { 1059 if (ident_equal(&profile->ident, &sid) == FALSE) {
993 connman_error("%s: %s is not the active profile", 1060 connman_error("%s: %s is not the active profile",
994 __func__, ident); 1061 __func__, ident);
995 free_ident(&sid); 1062 free_ident(&sid);
996 return -ENXIO; 1063 return -ENXIO;
997 } 1064 }
998 free_ident(&sid); 1065 free_ident(&sid);
999 } 1066 }
1000 1067
1001 » __connman_service_invalidate_profile(&profile->ident); 1068 » /*
1069 » * Pop the stack, invalidate all objects holding references
1070 » * to the profile, then remove it from the in-memory table.
1071 » * We do the reclaim after notification in case anyone holding
1072 » * a reference tries to use it.
1073 » */
1074 » cur_profile--;
1075
1076 » __connman_notifier_profile_pop(profile);
1002 1077
1003 g_hash_table_remove(profile_hash, profile->path); 1078 g_hash_table_remove(profile_hash, profile->path);
1004 cur_profile--;
1005 1079
1006 profiles_changed(); 1080 profiles_changed();
1007 1081
1008 /* NB: no need to kick auto-connect; it will happen due to invalidate */
1009
1010 return 0; 1082 return 0;
1011 } 1083 }
1012 1084
1013 /* 1085 /*
1014 * Create a profile file and register it in memory. The 1086 * Create a profile file and register it in memory. The
1015 * file is created with minimal contents. 1087 * file is created with minimal contents.
1016 * TODO(sleffler) disallow overwriting an existing file? 1088 * TODO(sleffler) disallow overwriting an existing file?
1017 */ 1089 */
1018 int __connman_profile_create(const char *name, const char **path) 1090 int __connman_profile_create(const char *name, const char **path)
1019 { 1091 {
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 void __connman_profile_cleanup(void) 1284 void __connman_profile_cleanup(void)
1213 { 1285 {
1214 _DBG_PROFILE(""); 1286 _DBG_PROFILE("");
1215 1287
1216 if (connection == NULL) 1288 if (connection == NULL)
1217 return; 1289 return;
1218 1290
1219 while (cur_profile >= 0) 1291 while (cur_profile >= 0)
1220 __connman_profile_pop(NULL); 1292 __connman_profile_pop(NULL);
1221 1293
1294 clear_timeout(NULL); /* NB: clear global timer */
1295
1222 g_hash_table_destroy(profile_hash); 1296 g_hash_table_destroy(profile_hash);
1223 profile_hash = NULL; 1297 profile_hash = NULL;
1224 1298
1225 clear_timeout(); /* cancel any pending timer */
1226
1227 connman_storage_unregister(&profile_storage); 1299 connman_storage_unregister(&profile_storage);
1228 1300
1229 dbus_connection_unref(connection); 1301 dbus_connection_unref(connection);
1230 } 1302 }
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