]> git.ipfire.org Git - thirdparty/hostap.git/blob - wpa_supplicant/dbus/dbus_new.c
dbus: Replace StateChanged with PropertiesChanged signal
[thirdparty/hostap.git] / wpa_supplicant / dbus / dbus_new.c
1 /*
2 * WPA Supplicant / dbus-based control interface
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4 * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
5 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
6 *
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
9 * published by the Free Software Foundation.
10 *
11 * Alternatively, this software may be distributed under the terms of BSD
12 * license.
13 *
14 * See README and COPYING for more details.
15 */
16
17 #include "includes.h"
18
19 #include "common.h"
20 #include "wps/wps.h"
21 #include "../config.h"
22 #include "../wpa_supplicant_i.h"
23 #include "../bss.h"
24 #include "dbus_new_helpers.h"
25 #include "dbus_dict_helpers.h"
26 #include "dbus_new.h"
27 #include "dbus_new_handlers.h"
28 #include "dbus_common.h"
29 #include "dbus_common_i.h"
30
31
32 /**
33 * wpas_dbus_signal_interface - Send a interface related event signal
34 * @wpa_s: %wpa_supplicant network interface data
35 * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
36 * @properties: Whether to add second argument with object properties
37 *
38 * Notify listeners about event related with interface
39 */
40 static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
41 const char *sig_name, int properties)
42 {
43 struct wpas_dbus_priv *iface;
44 DBusMessage *msg;
45 DBusMessageIter iter, iter_dict;
46
47 iface = wpa_s->global->dbus;
48
49 /* Do nothing if the control interface is not turned on */
50 if (iface == NULL)
51 return;
52
53 msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
54 WPAS_DBUS_NEW_INTERFACE, sig_name);
55 if (msg == NULL)
56 return;
57
58 dbus_message_iter_init_append(msg, &iter);
59 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
60 &wpa_s->dbus_new_path))
61 goto err;
62
63 if (properties) {
64 if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
65 goto err;
66
67 wpa_dbus_get_object_properties(iface, wpa_s->dbus_new_path,
68 WPAS_DBUS_NEW_IFACE_INTERFACE,
69 &iter_dict);
70
71 if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
72 goto err;
73 }
74
75 dbus_connection_send(iface->con, msg, NULL);
76 dbus_message_unref(msg);
77 return;
78
79 err:
80 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
81 dbus_message_unref(msg);
82 }
83
84
85 /**
86 * wpas_dbus_signal_interface_added - Send a interface created signal
87 * @wpa_s: %wpa_supplicant network interface data
88 *
89 * Notify listeners about creating new interface
90 */
91 static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
92 {
93 wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
94 }
95
96
97 /**
98 * wpas_dbus_signal_interface_removed - Send a interface removed signal
99 * @wpa_s: %wpa_supplicant network interface data
100 *
101 * Notify listeners about removing interface
102 */
103 static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
104 {
105 wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
106
107 }
108
109
110 /**
111 * wpas_dbus_signal_scan_done - send scan done signal
112 * @wpa_s: %wpa_supplicant network interface data
113 * @success: indicates if scanning succeed or failed
114 *
115 * Notify listeners about finishing a scan
116 */
117 void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
118 {
119 struct wpas_dbus_priv *iface;
120 DBusMessage *msg;
121 dbus_bool_t succ;
122
123 iface = wpa_s->global->dbus;
124
125 /* Do nothing if the control interface is not turned on */
126 if (iface == NULL)
127 return;
128
129 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
130 WPAS_DBUS_NEW_IFACE_INTERFACE,
131 "ScanDone");
132 if (msg == NULL)
133 return;
134
135 succ = success ? TRUE : FALSE;
136 if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ,
137 DBUS_TYPE_INVALID))
138 dbus_connection_send(iface->con, msg, NULL);
139 else
140 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
141 dbus_message_unref(msg);
142 }
143
144
145 /**
146 * wpas_dbus_signal_blob - Send a BSS related event signal
147 * @wpa_s: %wpa_supplicant network interface data
148 * @bss_obj_path: BSS object path
149 * @sig_name: signal name - BSSAdded or BSSRemoved
150 * @properties: Whether to add second argument with object properties
151 *
152 * Notify listeners about event related with BSS
153 */
154 static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
155 const char *bss_obj_path,
156 const char *sig_name, int properties)
157 {
158 struct wpas_dbus_priv *iface;
159 DBusMessage *msg;
160 DBusMessageIter iter, iter_dict;
161
162 iface = wpa_s->global->dbus;
163
164 /* Do nothing if the control interface is not turned on */
165 if (iface == NULL)
166 return;
167
168 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
169 WPAS_DBUS_NEW_IFACE_INTERFACE,
170 sig_name);
171 if (msg == NULL)
172 return;
173
174 dbus_message_iter_init_append(msg, &iter);
175 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
176 &bss_obj_path))
177 goto err;
178
179 if (properties) {
180 if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
181 goto err;
182
183 wpa_dbus_get_object_properties(iface, bss_obj_path,
184 WPAS_DBUS_NEW_IFACE_BSSID,
185 &iter_dict);
186
187 if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
188 goto err;
189 }
190
191 dbus_connection_send(iface->con, msg, NULL);
192 dbus_message_unref(msg);
193 return;
194
195 err:
196 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
197 dbus_message_unref(msg);
198 }
199
200
201 /**
202 * wpas_dbus_signal_bss_added - Send a BSS added signal
203 * @wpa_s: %wpa_supplicant network interface data
204 * @bss_obj_path: new BSS object path
205 *
206 * Notify listeners about adding new BSS
207 */
208 static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
209 const char *bss_obj_path)
210 {
211 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
212 }
213
214
215 /**
216 * wpas_dbus_signal_bss_removed - Send a BSS removed signal
217 * @wpa_s: %wpa_supplicant network interface data
218 * @bss_obj_path: BSS object path
219 *
220 * Notify listeners about removing BSS
221 */
222 static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
223 const char *bss_obj_path)
224 {
225 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
226 }
227
228
229 /**
230 * wpas_dbus_signal_blob - Send a blob related event signal
231 * @wpa_s: %wpa_supplicant network interface data
232 * @name: blob name
233 * @sig_name: signal name - BlobAdded or BlobRemoved
234 *
235 * Notify listeners about event related with blob
236 */
237 static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
238 const char *name, const char *sig_name)
239 {
240 struct wpas_dbus_priv *iface;
241 DBusMessage *msg;
242
243 iface = wpa_s->global->dbus;
244
245 /* Do nothing if the control interface is not turned on */
246 if (iface == NULL)
247 return;
248
249 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
250 WPAS_DBUS_NEW_IFACE_INTERFACE,
251 sig_name);
252 if (msg == NULL)
253 return;
254
255 if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &name,
256 DBUS_TYPE_INVALID))
257 dbus_connection_send(iface->con, msg, NULL);
258 else
259 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
260 dbus_message_unref(msg);
261 }
262
263
264 /**
265 * wpas_dbus_signal_blob_added - Send a blob added signal
266 * @wpa_s: %wpa_supplicant network interface data
267 * @name: blob name
268 *
269 * Notify listeners about adding a new blob
270 */
271 void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
272 const char *name)
273 {
274 wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
275 }
276
277
278 /**
279 * wpas_dbus_signal_blob_removed - Send a blob removed signal
280 * @wpa_s: %wpa_supplicant network interface data
281 * @name: blob name
282 *
283 * Notify listeners about removing blob
284 */
285 void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
286 const char *name)
287 {
288 wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
289 }
290
291
292 /**
293 * wpas_dbus_signal_network - Send a network related event signal
294 * @wpa_s: %wpa_supplicant network interface data
295 * @id: new network id
296 * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
297 * @properties: determines if add second argument with object properties
298 *
299 * Notify listeners about event related with configured network
300 */
301 static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
302 int id, const char *sig_name,
303 int properties)
304 {
305 struct wpas_dbus_priv *iface;
306 DBusMessage *msg;
307 DBusMessageIter iter, iter_dict;
308 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
309
310 iface = wpa_s->global->dbus;
311
312 /* Do nothing if the control interface is not turned on */
313 if (iface == NULL)
314 return;
315
316 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
317 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
318 wpa_s->dbus_new_path, id);
319
320 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
321 WPAS_DBUS_NEW_IFACE_INTERFACE,
322 sig_name);
323 if (msg == NULL)
324 return;
325
326 dbus_message_iter_init_append(msg, &iter);
327 path = net_obj_path;
328 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
329 &path))
330 goto err;
331
332 if (properties) {
333 if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
334 goto err;
335
336 wpa_dbus_get_object_properties(iface, net_obj_path,
337 WPAS_DBUS_NEW_IFACE_NETWORK,
338 &iter_dict);
339
340 if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
341 goto err;
342 }
343
344 dbus_connection_send(iface->con, msg, NULL);
345
346 dbus_message_unref(msg);
347 return;
348
349 err:
350 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
351 dbus_message_unref(msg);
352 }
353
354
355 /**
356 * wpas_dbus_signal_network_added - Send a network added signal
357 * @wpa_s: %wpa_supplicant network interface data
358 * @id: new network id
359 *
360 * Notify listeners about adding new network
361 */
362 static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
363 int id)
364 {
365 wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
366 }
367
368
369 /**
370 * wpas_dbus_signal_network_removed - Send a network removed signal
371 * @wpa_s: %wpa_supplicant network interface data
372 * @id: network id
373 *
374 * Notify listeners about removing a network
375 */
376 static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
377 int id)
378 {
379 wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
380 }
381
382
383 /**
384 * wpas_dbus_signal_network_selected - Send a network selected signal
385 * @wpa_s: %wpa_supplicant network interface data
386 * @id: network id
387 *
388 * Notify listeners about selecting a network
389 */
390 void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
391 {
392 wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
393 }
394
395
396 /**
397 * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
398 * @wpa_s: %wpa_supplicant network interface data
399 * @ssid: configured network which Enabled property has changed
400 *
401 * Sends PropertyChanged signals containing new value of Enabled property
402 * for specified network
403 */
404 void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
405 struct wpa_ssid *ssid)
406 {
407
408 struct network_handler_args args = { wpa_s, ssid };
409 char path[WPAS_DBUS_OBJECT_PATH_MAX];
410 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
411 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
412 wpa_s->dbus_new_path, ssid->id);
413
414 wpa_dbus_signal_property_changed(wpa_s->global->dbus,
415 (WPADBusPropertyAccessor)
416 wpas_dbus_getter_enabled, &args,
417 path, WPAS_DBUS_NEW_IFACE_NETWORK,
418 "Enabled");
419 }
420
421
422 #ifdef CONFIG_WPS
423
424 /**
425 * wpas_dbus_signal_wps_event_success - Signals Success WPS event
426 * @wpa_s: %wpa_supplicant network interface data
427 *
428 * Sends Event dbus signal with name "success" and empty dict as arguments
429 */
430 void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
431 {
432
433 DBusMessage *msg;
434 DBusMessageIter iter, dict_iter;
435 struct wpas_dbus_priv *iface;
436 char *key = "success";
437
438 iface = wpa_s->global->dbus;
439
440 /* Do nothing if the control interface is not turned on */
441 if (iface == NULL)
442 return;
443
444 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
445 WPAS_DBUS_NEW_IFACE_WPS, "Event");
446 if (msg == NULL)
447 return;
448
449 dbus_message_iter_init_append(msg, &iter);
450
451 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
452 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
453 !wpa_dbus_dict_close_write(&iter, &dict_iter))
454 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
455 else
456 dbus_connection_send(iface->con, msg, NULL);
457
458 dbus_message_unref(msg);
459 }
460
461
462 /**
463 * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
464 * @wpa_s: %wpa_supplicant network interface data
465 *
466 * Sends Event dbus signal with name "fail" and dictionary containing
467 * "msg field with fail message number (int32) as arguments
468 */
469 void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
470 struct wps_event_fail *fail)
471 {
472
473 DBusMessage *msg;
474 DBusMessageIter iter, dict_iter;
475 struct wpas_dbus_priv *iface;
476 char *key = "fail";
477
478 iface = wpa_s->global->dbus;
479
480 /* Do nothing if the control interface is not turned on */
481 if (iface == NULL)
482 return;
483
484 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
485 WPAS_DBUS_NEW_IFACE_WPS, "Event");
486 if (msg == NULL)
487 return;
488
489 dbus_message_iter_init_append(msg, &iter);
490
491 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
492 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
493 !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
494 !wpa_dbus_dict_close_write(&iter, &dict_iter))
495 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
496 else
497 dbus_connection_send(iface->con, msg, NULL);
498
499 dbus_message_unref(msg);
500 }
501
502
503 /**
504 * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
505 * @wpa_s: %wpa_supplicant network interface data
506 *
507 * Sends Event dbus signal with name "m2d" and dictionary containing
508 * fields of wps_event_m2d structure.
509 */
510 void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
511 struct wps_event_m2d *m2d)
512 {
513
514 DBusMessage *msg;
515 DBusMessageIter iter, dict_iter;
516 struct wpas_dbus_priv *iface;
517 char *key = "m2d";
518
519 iface = wpa_s->global->dbus;
520
521 /* Do nothing if the control interface is not turned on */
522 if (iface == NULL)
523 return;
524
525 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
526 WPAS_DBUS_NEW_IFACE_WPS, "Event");
527 if (msg == NULL)
528 return;
529
530 dbus_message_iter_init_append(msg, &iter);
531
532 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
533 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
534 !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
535 m2d->config_methods) ||
536 !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
537 (const char *) m2d->manufacturer,
538 m2d->manufacturer_len) ||
539 !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
540 (const char *) m2d->model_name,
541 m2d->model_name_len) ||
542 !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
543 (const char *) m2d->model_number,
544 m2d->model_number_len) ||
545 !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
546 (const char *)
547 m2d->serial_number,
548 m2d->serial_number_len) ||
549 !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
550 (const char *) m2d->dev_name,
551 m2d->dev_name_len) ||
552 !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
553 (const char *)
554 m2d->primary_dev_type, 8) ||
555 !wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
556 m2d->config_error) ||
557 !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
558 m2d->dev_password_id) ||
559 !wpa_dbus_dict_close_write(&iter, &dict_iter))
560 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
561 else
562 dbus_connection_send(iface->con, msg, NULL);
563
564 dbus_message_unref(msg);
565 }
566
567
568 /**
569 * wpas_dbus_signal_wps_cred - Signals new credentials
570 * @wpa_s: %wpa_supplicant network interface data
571 *
572 * Sends signal with credentials in directory argument
573 */
574 void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
575 const struct wps_credential *cred)
576 {
577 DBusMessage *msg;
578 DBusMessageIter iter, dict_iter;
579 struct wpas_dbus_priv *iface;
580 char *auth_type[6]; /* we have six possible authorization types */
581 int at_num = 0;
582 char *encr_type[4]; /* we have four possible encryption types */
583 int et_num = 0;
584
585 iface = wpa_s->global->dbus;
586
587 /* Do nothing if the control interface is not turned on */
588 if (iface == NULL)
589 return;
590
591 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
592 WPAS_DBUS_NEW_IFACE_WPS,
593 "Credentials");
594 if (msg == NULL)
595 return;
596
597 dbus_message_iter_init_append(msg, &iter);
598 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
599 goto nomem;
600
601 if (cred->auth_type & WPS_AUTH_OPEN)
602 auth_type[at_num++] = "open";
603 if (cred->auth_type & WPS_AUTH_WPAPSK)
604 auth_type[at_num++] = "wpa-psk";
605 if (cred->auth_type & WPS_AUTH_SHARED)
606 auth_type[at_num++] = "shared";
607 if (cred->auth_type & WPS_AUTH_WPA)
608 auth_type[at_num++] = "wpa-eap";
609 if (cred->auth_type & WPS_AUTH_WPA2)
610 auth_type[at_num++] = "wpa2-eap";
611 if (cred->auth_type & WPS_AUTH_WPA2PSK)
612 auth_type[at_num++] =
613 "wpa2-psk";
614
615 if (cred->encr_type & WPS_ENCR_NONE)
616 encr_type[et_num++] = "none";
617 if (cred->encr_type & WPS_ENCR_WEP)
618 encr_type[et_num++] = "wep";
619 if (cred->encr_type & WPS_ENCR_TKIP)
620 encr_type[et_num++] = "tkip";
621 if (cred->encr_type & WPS_ENCR_AES)
622 encr_type[et_num++] = "aes";
623
624 if (wpa_s->current_ssid) {
625 if (!wpa_dbus_dict_append_byte_array(
626 &dict_iter, "BSSID",
627 (const char *) wpa_s->current_ssid->bssid,
628 ETH_ALEN))
629 goto nomem;
630 }
631
632 if (!wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
633 (const char *) cred->ssid,
634 cred->ssid_len) ||
635 !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
636 (const char **) auth_type,
637 at_num) ||
638 !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
639 (const char **) encr_type,
640 et_num) ||
641 !wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
642 (const char *) cred->key,
643 cred->key_len) ||
644 !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
645 cred->key_idx) ||
646 !wpa_dbus_dict_close_write(&iter, &dict_iter))
647 goto nomem;
648
649 dbus_connection_send(iface->con, msg, NULL);
650
651 nomem:
652 dbus_message_unref(msg);
653 }
654
655 #endif /* CONFIG_WPS */
656
657
658 /**
659 * wpas_dbus_signal_prop_changed - Signals change of property
660 * @wpa_s: %wpa_supplicant network interface data
661 * @property: indicates which property has changed
662 *
663 * Sends ProertyChanged signals with path, interface and arguments
664 * depending on which property has changed.
665 */
666 void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
667 enum wpas_dbus_prop property)
668 {
669 WPADBusPropertyAccessor getter;
670 char *prop;
671
672 switch (property) {
673 case WPAS_DBUS_PROP_AP_SCAN:
674 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan;
675 prop = "ApScan";
676 break;
677 case WPAS_DBUS_PROP_SCANNING:
678 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_scanning;
679 prop = "Scanning";
680 break;
681 case WPAS_DBUS_PROP_STATE:
682 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_state;
683 prop = "State";
684 break;
685 case WPAS_DBUS_PROP_CURRENT_BSS:
686 getter = (WPADBusPropertyAccessor)
687 wpas_dbus_getter_current_bss;
688 prop = "CurrentBSS";
689 break;
690 case WPAS_DBUS_PROP_CURRENT_NETWORK:
691 getter = (WPADBusPropertyAccessor)
692 wpas_dbus_getter_current_network;
693 prop = "CurrentNetwork";
694 break;
695 default:
696 wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
697 __func__, property);
698 return;
699 }
700
701 wpa_dbus_signal_property_changed(wpa_s->global->dbus,
702 getter, wpa_s, wpa_s->dbus_new_path,
703 WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
704 }
705
706
707 /**
708 * wpas_dbus_signal_debug_level_changed - Signals change of debug param
709 * @global: wpa_global structure
710 *
711 * Sends ProertyChanged signals informing that debug level has changed.
712 */
713 void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
714 {
715 wpa_dbus_signal_property_changed(global->dbus,
716 (WPADBusPropertyAccessor)
717 wpas_dbus_getter_debug_level,
718 global, WPAS_DBUS_NEW_PATH,
719 WPAS_DBUS_NEW_INTERFACE,
720 "DebugLevel");
721 }
722
723
724 /**
725 * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
726 * @global: wpa_global structure
727 *
728 * Sends ProertyChanged signals informing that debug timestamp has changed.
729 */
730 void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
731 {
732 wpa_dbus_signal_property_changed(global->dbus,
733 (WPADBusPropertyAccessor)
734 wpas_dbus_getter_debug_timestamp,
735 global, WPAS_DBUS_NEW_PATH,
736 WPAS_DBUS_NEW_INTERFACE,
737 "DebugTimestamp");
738 }
739
740
741 /**
742 * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
743 * @global: wpa_global structure
744 *
745 * Sends ProertyChanged signals informing that debug show_keys has changed.
746 */
747 void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
748 {
749 wpa_dbus_signal_property_changed(global->dbus,
750 (WPADBusPropertyAccessor)
751 wpas_dbus_getter_debug_show_keys,
752 global, WPAS_DBUS_NEW_PATH,
753 WPAS_DBUS_NEW_INTERFACE,
754 "DebugShowKeys");
755 }
756
757
758 static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
759 void *priv,
760 WPADBusArgumentFreeFunction priv_free,
761 const struct wpa_dbus_method_desc *methods,
762 const struct wpa_dbus_property_desc *properties,
763 const struct wpa_dbus_signal_desc *signals)
764 {
765 obj_desc->user_data = priv;
766 obj_desc->user_data_free_func = priv_free;
767 obj_desc->methods = methods;
768 obj_desc->properties = properties;
769 obj_desc->signals = signals;
770 }
771
772
773 static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
774 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
775 (WPADBusMethodHandler) &wpas_dbus_handler_create_interface,
776 {
777 { "args", "a{sv}", ARG_IN },
778 { "path", "o", ARG_OUT },
779 END_ARGS
780 }
781 },
782 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
783 (WPADBusMethodHandler) &wpas_dbus_handler_remove_interface,
784 {
785 { "path", "o", ARG_IN },
786 END_ARGS
787 }
788 },
789 { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
790 (WPADBusMethodHandler) &wpas_dbus_handler_get_interface,
791 {
792 { "ifname", "s", ARG_IN },
793 { "path", "o", ARG_OUT },
794 END_ARGS
795 }
796 },
797 { NULL, NULL, NULL, { END_ARGS } }
798 };
799
800 static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
801 { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
802 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_level,
803 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_level,
804 RW
805 },
806 { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
807 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_timestamp,
808 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_timestamp,
809 RW
810 },
811 { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
812 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_show_keys,
813 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_show_keys,
814 RW
815 },
816 { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
817 (WPADBusPropertyAccessor) &wpas_dbus_getter_interfaces,
818 NULL,
819 R
820 },
821 { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
822 (WPADBusPropertyAccessor) wpas_dbus_getter_eap_methods,
823 NULL,
824 R
825 },
826 { NULL, NULL, NULL, NULL, NULL, 0 }
827 };
828
829 static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
830 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
831 {
832 { "path", "o", ARG_OUT },
833 { "properties", "a{sv}", ARG_OUT },
834 END_ARGS
835 }
836 },
837 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
838 {
839 { "path", "o", ARG_OUT },
840 END_ARGS
841 }
842 },
843 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
844 {
845 { "properties", "a{sv}", ARG_OUT },
846 END_ARGS
847 }
848 },
849 { NULL, NULL, { END_ARGS } }
850 };
851
852
853 /**
854 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
855 * @global: Pointer to global data from wpa_supplicant_init()
856 * Returns: 0 on success or -1 on failure
857 *
858 * Initialize the dbus control interface for wpa_supplicantand and start
859 * receiving commands from external programs over the bus.
860 */
861 int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
862 {
863 struct wpa_dbus_object_desc *obj_desc;
864 int ret;
865
866 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
867 if (!obj_desc) {
868 wpa_printf(MSG_ERROR, "Not enough memory "
869 "to create object description");
870 return -1;
871 }
872
873 wpas_dbus_register(obj_desc, priv->global, NULL,
874 wpas_dbus_global_methods,
875 wpas_dbus_global_properties,
876 wpas_dbus_global_signals);
877
878 wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
879 WPAS_DBUS_NEW_PATH);
880 ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
881 WPAS_DBUS_NEW_SERVICE,
882 obj_desc);
883 if (ret < 0)
884 free_dbus_object_desc(obj_desc);
885 else
886 priv->dbus_new_initialized = 1;
887
888 return ret;
889 }
890
891
892 /**
893 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
894 * wpa_supplicant
895 * @iface: Pointer to dbus private data from wpas_dbus_init()
896 *
897 * Deinitialize the dbus control interface that was initialized with
898 * wpas_dbus_ctrl_iface_init().
899 */
900 void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface)
901 {
902 if (!iface->dbus_new_initialized)
903 return;
904 wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
905 WPAS_DBUS_NEW_PATH);
906 dbus_connection_unregister_object_path(iface->con,
907 WPAS_DBUS_NEW_PATH);
908 }
909
910
911 static void wpa_dbus_free(void *ptr)
912 {
913 os_free(ptr);
914 }
915
916
917 static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
918 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
919 (WPADBusPropertyAccessor) wpas_dbus_getter_network_properties,
920 (WPADBusPropertyAccessor) wpas_dbus_setter_network_properties,
921 RW
922 },
923 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
924 (WPADBusPropertyAccessor) wpas_dbus_getter_enabled,
925 (WPADBusPropertyAccessor) wpas_dbus_setter_enabled,
926 RW
927 },
928 { NULL, NULL, NULL, NULL, NULL, 0 }
929 };
930
931
932 static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
933 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
934 {
935 { "properties", "a{sv}", ARG_OUT },
936 END_ARGS
937 }
938 },
939 { NULL, NULL, { END_ARGS } }
940 };
941
942
943 /**
944 * wpas_dbus_register_network - Register a configured network with dbus
945 * @wpa_s: wpa_supplicant interface structure
946 * @ssid: network configuration data
947 * Returns: 0 on success, -1 on failure
948 *
949 * Registers network representing object with dbus
950 */
951 int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
952 struct wpa_ssid *ssid)
953 {
954 struct wpas_dbus_priv *ctrl_iface;
955 struct wpa_dbus_object_desc *obj_desc;
956 struct network_handler_args *arg;
957 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
958
959 /* Do nothing if the control interface is not turned on */
960 if (wpa_s == NULL || wpa_s->global == NULL)
961 return 0;
962 ctrl_iface = wpa_s->global->dbus;
963 if (ctrl_iface == NULL)
964 return 0;
965
966 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
967 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
968 wpa_s->dbus_new_path, ssid->id);
969
970 wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
971 net_obj_path);
972 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
973 if (!obj_desc) {
974 wpa_printf(MSG_ERROR, "Not enough memory "
975 "to create object description");
976 goto err;
977 }
978
979 /* allocate memory for handlers arguments */
980 arg = os_zalloc(sizeof(struct network_handler_args));
981 if (!arg) {
982 wpa_printf(MSG_ERROR, "Not enough memory "
983 "to create arguments for method");
984 goto err;
985 }
986
987 arg->wpa_s = wpa_s;
988 arg->ssid = ssid;
989
990 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
991 wpas_dbus_network_properties,
992 wpas_dbus_network_signals);
993
994 if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
995 wpa_s->ifname, obj_desc))
996 goto err;
997
998 wpas_dbus_signal_network_added(wpa_s, ssid->id);
999
1000 return 0;
1001
1002 err:
1003 free_dbus_object_desc(obj_desc);
1004 return -1;
1005 }
1006
1007
1008 /**
1009 * wpas_dbus_unregister_network - Unregister a configured network from dbus
1010 * @wpa_s: wpa_supplicant interface structure
1011 * @nid: network id
1012 * Returns: 0 on success, -1 on failure
1013 *
1014 * Unregisters network representing object from dbus
1015 */
1016 int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
1017 {
1018 struct wpas_dbus_priv *ctrl_iface;
1019 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
1020 int ret;
1021
1022 /* Do nothing if the control interface is not turned on */
1023 if (wpa_s == NULL || wpa_s->global == NULL)
1024 return 0;
1025 ctrl_iface = wpa_s->global->dbus;
1026 if (ctrl_iface == NULL)
1027 return 0;
1028
1029 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1030 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
1031 wpa_s->dbus_new_path, nid);
1032
1033 wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
1034 net_obj_path);
1035 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
1036
1037 if (!ret)
1038 wpas_dbus_signal_network_removed(wpa_s, nid);
1039
1040 return ret;
1041 }
1042
1043
1044 static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
1045 { "SSID", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1046 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ssid,
1047 NULL,
1048 R
1049 },
1050 { "BSSID", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1051 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_bssid,
1052 NULL,
1053 R
1054 },
1055 { "Privacy", WPAS_DBUS_NEW_IFACE_BSSID, "b",
1056 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_privacy,
1057 NULL,
1058 R
1059 },
1060 { "Mode", WPAS_DBUS_NEW_IFACE_BSSID, "s",
1061 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_mode,
1062 NULL,
1063 R
1064 },
1065 { "Signal", WPAS_DBUS_NEW_IFACE_BSSID, "n",
1066 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_signal,
1067 NULL,
1068 R
1069 },
1070 { "Frequency", WPAS_DBUS_NEW_IFACE_BSSID, "q",
1071 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_frequency,
1072 NULL,
1073 R
1074 },
1075 { "MaxRate", WPAS_DBUS_NEW_IFACE_BSSID, "q",
1076 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_max_rate,
1077 NULL,
1078 R
1079 },
1080 { "WPAIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1081 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpaie,
1082 NULL,
1083 R
1084 },
1085 { "RSNIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1086 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rsnie,
1087 NULL,
1088 R
1089 },
1090 { "WPSIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1091 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpsie,
1092 NULL,
1093 R
1094 },
1095 { NULL, NULL, NULL, NULL, NULL, 0 }
1096 };
1097
1098
1099 static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
1100 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSSID,
1101 {
1102 { "properties", "a{sv}", ARG_OUT },
1103 END_ARGS
1104 }
1105 },
1106 { NULL, NULL, { END_ARGS } }
1107 };
1108
1109
1110 /**
1111 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
1112 * @wpa_s: wpa_supplicant interface structure
1113 * @bssid: scanned network bssid
1114 * @id: unique BSS identifier
1115 * Returns: 0 on success, -1 on failure
1116 *
1117 * Unregisters BSS representing object from dbus
1118 */
1119 int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
1120 u8 bssid[ETH_ALEN], unsigned int id)
1121 {
1122 struct wpas_dbus_priv *ctrl_iface;
1123 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
1124
1125 /* Do nothing if the control interface is not turned on */
1126 if (wpa_s == NULL || wpa_s->global == NULL)
1127 return 0;
1128 ctrl_iface = wpa_s->global->dbus;
1129 if (ctrl_iface == NULL)
1130 return 0;
1131
1132 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1133 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
1134 wpa_s->dbus_new_path, id);
1135
1136 wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
1137 bss_obj_path);
1138 if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
1139 wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
1140 bss_obj_path);
1141 return -1;
1142 }
1143
1144 wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
1145
1146 return 0;
1147 }
1148
1149
1150 /**
1151 * wpas_dbus_register_bss - Register a scanned BSS with dbus
1152 * @wpa_s: wpa_supplicant interface structure
1153 * @bssid: scanned network bssid
1154 * @id: unique BSS identifier
1155 * Returns: 0 on success, -1 on failure
1156 *
1157 * Registers BSS representing object with dbus
1158 */
1159 int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
1160 u8 bssid[ETH_ALEN], unsigned int id)
1161 {
1162 struct wpas_dbus_priv *ctrl_iface;
1163 struct wpa_dbus_object_desc *obj_desc;
1164 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
1165 struct bss_handler_args *arg;
1166
1167 /* Do nothing if the control interface is not turned on */
1168 if (wpa_s == NULL || wpa_s->global == NULL)
1169 return 0;
1170 ctrl_iface = wpa_s->global->dbus;
1171 if (ctrl_iface == NULL)
1172 return 0;
1173
1174 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1175 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
1176 wpa_s->dbus_new_path, id);
1177
1178 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1179 if (!obj_desc) {
1180 wpa_printf(MSG_ERROR, "Not enough memory "
1181 "to create object description");
1182 goto err;
1183 }
1184
1185 arg = os_zalloc(sizeof(struct bss_handler_args));
1186 if (!arg) {
1187 wpa_printf(MSG_ERROR, "Not enough memory "
1188 "to create arguments for handler");
1189 goto err;
1190 }
1191 arg->wpa_s = wpa_s;
1192 arg->id = id;
1193
1194 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
1195 wpas_dbus_bss_properties,
1196 wpas_dbus_bss_signals);
1197
1198 wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
1199 bss_obj_path);
1200 if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
1201 wpa_s->ifname, obj_desc)) {
1202 wpa_printf(MSG_ERROR,
1203 "Cannot register BSSID dbus object %s.",
1204 bss_obj_path);
1205 goto err;
1206 }
1207
1208 wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
1209
1210 return 0;
1211
1212 err:
1213 free_dbus_object_desc(obj_desc);
1214 return -1;
1215 }
1216
1217
1218 static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
1219 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
1220 (WPADBusMethodHandler) &wpas_dbus_handler_scan,
1221 {
1222 { "args", "a{sv}", ARG_IN },
1223 END_ARGS
1224 }
1225 },
1226 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
1227 (WPADBusMethodHandler) &wpas_dbus_handler_disconnect,
1228 {
1229 END_ARGS
1230 }
1231 },
1232 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1233 (WPADBusMethodHandler) &wpas_dbus_handler_add_network,
1234 {
1235 { "args", "a{sv}", ARG_IN },
1236 { "path", "o", ARG_OUT },
1237 END_ARGS
1238 }
1239 },
1240 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1241 (WPADBusMethodHandler) &wpas_dbus_handler_remove_network,
1242 {
1243 { "path", "o", ARG_IN },
1244 END_ARGS
1245 }
1246 },
1247 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1248 (WPADBusMethodHandler) &wpas_dbus_handler_select_network,
1249 {
1250 { "path", "o", ARG_IN },
1251 END_ARGS
1252 }
1253 },
1254 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1255 (WPADBusMethodHandler) &wpas_dbus_handler_add_blob,
1256 {
1257 { "name", "s", ARG_IN },
1258 { "data", "ay", ARG_IN },
1259 END_ARGS
1260 }
1261 },
1262 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1263 (WPADBusMethodHandler) &wpas_dbus_handler_get_blob,
1264 {
1265 { "name", "s", ARG_IN },
1266 { "data", "ay", ARG_OUT },
1267 END_ARGS
1268 }
1269 },
1270 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1271 (WPADBusMethodHandler) &wpas_dbus_handler_remove_blob,
1272 {
1273 { "name", "s", ARG_IN },
1274 END_ARGS
1275 }
1276 },
1277 #ifdef CONFIG_WPS
1278 { "Start", WPAS_DBUS_NEW_IFACE_WPS,
1279 (WPADBusMethodHandler) &wpas_dbus_handler_wps_start,
1280 {
1281 { "args", "a{sv}", ARG_IN },
1282 { "output", "a{sv}", ARG_OUT },
1283 END_ARGS
1284 }
1285 },
1286 #endif /* CONFIG_WPS */
1287 { NULL, NULL, NULL, { END_ARGS } }
1288 };
1289
1290 static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
1291 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
1292 (WPADBusPropertyAccessor) wpas_dbus_getter_capabilities,
1293 NULL, R
1294 },
1295 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1296 (WPADBusPropertyAccessor) wpas_dbus_getter_state,
1297 NULL, R
1298 },
1299 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
1300 (WPADBusPropertyAccessor) wpas_dbus_getter_scanning,
1301 NULL, R
1302 },
1303 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
1304 (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan,
1305 (WPADBusPropertyAccessor) wpas_dbus_setter_ap_scan,
1306 RW
1307 },
1308 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1309 (WPADBusPropertyAccessor) wpas_dbus_getter_ifname,
1310 NULL, R
1311 },
1312 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1313 (WPADBusPropertyAccessor) wpas_dbus_getter_driver,
1314 NULL, R
1315 },
1316 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1317 (WPADBusPropertyAccessor) wpas_dbus_getter_bridge_ifname,
1318 NULL, R
1319 },
1320 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
1321 (WPADBusPropertyAccessor) wpas_dbus_getter_current_bss,
1322 NULL, R
1323 },
1324 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
1325 (WPADBusPropertyAccessor) wpas_dbus_getter_current_network,
1326 NULL, R
1327 },
1328 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
1329 (WPADBusPropertyAccessor) wpas_dbus_getter_blobs,
1330 NULL, R
1331 },
1332 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
1333 (WPADBusPropertyAccessor) wpas_dbus_getter_bsss,
1334 NULL, R
1335 },
1336 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
1337 (WPADBusPropertyAccessor) wpas_dbus_getter_networks,
1338 NULL, R
1339 },
1340 #ifdef CONFIG_WPS
1341 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
1342 (WPADBusPropertyAccessor) wpas_dbus_getter_process_credentials,
1343 (WPADBusPropertyAccessor) wpas_dbus_setter_process_credentials,
1344 RW
1345 },
1346 #endif /* CONFIG_WPS */
1347 { NULL, NULL, NULL, NULL, NULL, 0 }
1348 };
1349
1350 static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
1351 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
1352 {
1353 { "success", "b", ARG_OUT },
1354 END_ARGS
1355 }
1356 },
1357 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1358 {
1359 { "path", "o", ARG_OUT },
1360 { "properties", "a{sv}", ARG_OUT },
1361 END_ARGS
1362 }
1363 },
1364 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1365 {
1366 { "path", "o", ARG_OUT },
1367 END_ARGS
1368 }
1369 },
1370 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1371 {
1372 { "name", "s", ARG_OUT },
1373 END_ARGS
1374 }
1375 },
1376 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1377 {
1378 { "name", "s", ARG_OUT },
1379 END_ARGS
1380 }
1381 },
1382 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1383 {
1384 { "path", "o", ARG_OUT },
1385 { "properties", "a{sv}", ARG_OUT },
1386 END_ARGS
1387 }
1388 },
1389 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1390 {
1391 { "path", "o", ARG_OUT },
1392 END_ARGS
1393 }
1394 },
1395 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
1396 {
1397 { "path", "o", ARG_OUT },
1398 END_ARGS
1399 }
1400 },
1401 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
1402 {
1403 { "properties", "a{sv}", ARG_OUT },
1404 END_ARGS
1405 }
1406 },
1407 #ifdef CONFIG_WPS
1408 { "Event", WPAS_DBUS_NEW_IFACE_WPS,
1409 {
1410 { "name", "s", ARG_OUT },
1411 { "args", "a{sv}", ARG_OUT },
1412 END_ARGS
1413 }
1414 },
1415 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
1416 {
1417 { "credentials", "a{sv}", ARG_OUT },
1418 END_ARGS
1419 }
1420 },
1421 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
1422 {
1423 { "properties", "a{sv}", ARG_OUT },
1424 END_ARGS
1425 }
1426 },
1427 #endif /* CONFIG_WPS */
1428 { NULL, NULL, { END_ARGS } }
1429 };
1430
1431
1432 int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
1433 {
1434
1435 struct wpa_dbus_object_desc *obj_desc = NULL;
1436 struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
1437 int next;
1438
1439 /* Do nothing if the control interface is not turned on */
1440 if (ctrl_iface == NULL)
1441 return 0;
1442
1443 /* Create and set the interface's object path */
1444 wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1445 if (wpa_s->dbus_new_path == NULL)
1446 return -1;
1447 next = ctrl_iface->next_objid++;
1448 os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
1449 WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
1450 next);
1451
1452 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1453 if (!obj_desc) {
1454 wpa_printf(MSG_ERROR, "Not enough memory "
1455 "to create object description");
1456 goto err;
1457 }
1458
1459 wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
1460 wpas_dbus_interface_properties,
1461 wpas_dbus_interface_signals);
1462
1463 wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
1464 wpa_s->dbus_new_path);
1465 if (wpa_dbus_register_object_per_iface(ctrl_iface,
1466 wpa_s->dbus_new_path,
1467 wpa_s->ifname, obj_desc))
1468 goto err;
1469
1470 wpas_dbus_signal_interface_added(wpa_s);
1471
1472 return 0;
1473
1474 err:
1475 os_free(wpa_s->dbus_new_path);
1476 wpa_s->dbus_new_path = NULL;
1477 free_dbus_object_desc(obj_desc);
1478 return -1;
1479 }
1480
1481
1482 int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
1483 {
1484 struct wpas_dbus_priv *ctrl_iface;
1485
1486 /* Do nothing if the control interface is not turned on */
1487 if (wpa_s == NULL || wpa_s->global == NULL)
1488 return 0;
1489 ctrl_iface = wpa_s->global->dbus;
1490 if (ctrl_iface == NULL)
1491 return 0;
1492
1493 wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
1494 wpa_s->dbus_new_path);
1495 if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
1496 wpa_s->dbus_new_path))
1497 return -1;
1498
1499 wpas_dbus_signal_interface_removed(wpa_s);
1500
1501 os_free(wpa_s->dbus_new_path);
1502 wpa_s->dbus_new_path = NULL;
1503
1504 return 0;
1505 }