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 |