]> git.ipfire.org Git - thirdparty/hostap.git/blob - wpa_supplicant/dbus/dbus_new.c
dbus: Remove duplication of object methods/signals/properties
[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 static void str_to_lower(char *s)
397 {
398 while (*s) {
399 *s = tolower(*s);
400 s++;
401 }
402 }
403
404
405 /**
406 * wpas_dbus_signal_state_changed - Send a state changed signal
407 * @wpa_s: %wpa_supplicant network interface data
408 * @new_state: new state wpa_supplicant is entering
409 * @old_state: old state wpa_supplicant is leaving
410 *
411 * Notify listeners that wpa_supplicant has changed state
412 */
413 void wpas_dbus_signal_state_changed(struct wpa_supplicant *wpa_s,
414 enum wpa_states new_state,
415 enum wpa_states old_state)
416 {
417 struct wpas_dbus_priv *iface;
418 DBusMessage *msg;
419 char *new_state_str, *old_state_str;
420
421 /* Do nothing if the control interface is not turned on */
422 if (wpa_s->global == NULL)
423 return;
424 iface = wpa_s->global->dbus;
425 if (iface == NULL)
426 return;
427
428 /* Only send signal if state really changed */
429 if (new_state == old_state)
430 return;
431
432 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
433 WPAS_DBUS_NEW_IFACE_INTERFACE,
434 "StateChanged");
435 if (msg == NULL)
436 return;
437
438 new_state_str = os_strdup(wpa_supplicant_state_txt(new_state));
439 old_state_str = os_strdup(wpa_supplicant_state_txt(old_state));
440 if (new_state_str == NULL || old_state_str == NULL)
441 goto out;
442
443 /* make state string lowercase to fit new DBus API convention */
444 str_to_lower(new_state_str);
445 str_to_lower(old_state_str);
446
447 if (!dbus_message_append_args(msg,
448 DBUS_TYPE_STRING, &new_state_str,
449 DBUS_TYPE_STRING, &old_state_str,
450 DBUS_TYPE_INVALID)) {
451 wpa_printf(MSG_ERROR, "dbus: Failed to construct state change "
452 "signal");
453 goto out;
454 }
455
456 dbus_connection_send(iface->con, msg, NULL);
457
458 out:
459 dbus_message_unref(msg);
460 os_free(new_state_str);
461 os_free(old_state_str);
462 }
463
464
465 /**
466 * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
467 * @wpa_s: %wpa_supplicant network interface data
468 * @ssid: configured network which Enabled property has changed
469 *
470 * Sends PropertyChanged signals containing new value of Enabled property
471 * for specified network
472 */
473 void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
474 struct wpa_ssid *ssid)
475 {
476
477 struct network_handler_args args = { wpa_s, ssid };
478 char path[WPAS_DBUS_OBJECT_PATH_MAX];
479 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
480 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
481 wpa_s->dbus_new_path, ssid->id);
482
483 wpa_dbus_signal_property_changed(wpa_s->global->dbus,
484 (WPADBusPropertyAccessor)
485 wpas_dbus_getter_enabled, &args,
486 path, WPAS_DBUS_NEW_IFACE_NETWORK,
487 "Enabled");
488 }
489
490
491 #ifdef CONFIG_WPS
492
493 /**
494 * wpas_dbus_signal_wps_event_success - Signals Success WPS event
495 * @wpa_s: %wpa_supplicant network interface data
496 *
497 * Sends Event dbus signal with name "success" and empty dict as arguments
498 */
499 void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
500 {
501
502 DBusMessage *msg;
503 DBusMessageIter iter, dict_iter;
504 struct wpas_dbus_priv *iface;
505 char *key = "success";
506
507 iface = wpa_s->global->dbus;
508
509 /* Do nothing if the control interface is not turned on */
510 if (iface == NULL)
511 return;
512
513 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
514 WPAS_DBUS_NEW_IFACE_WPS, "Event");
515 if (msg == NULL)
516 return;
517
518 dbus_message_iter_init_append(msg, &iter);
519
520 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
521 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
522 !wpa_dbus_dict_close_write(&iter, &dict_iter))
523 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
524 else
525 dbus_connection_send(iface->con, msg, NULL);
526
527 dbus_message_unref(msg);
528 }
529
530
531 /**
532 * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
533 * @wpa_s: %wpa_supplicant network interface data
534 *
535 * Sends Event dbus signal with name "fail" and dictionary containing
536 * "msg field with fail message number (int32) as arguments
537 */
538 void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
539 struct wps_event_fail *fail)
540 {
541
542 DBusMessage *msg;
543 DBusMessageIter iter, dict_iter;
544 struct wpas_dbus_priv *iface;
545 char *key = "fail";
546
547 iface = wpa_s->global->dbus;
548
549 /* Do nothing if the control interface is not turned on */
550 if (iface == NULL)
551 return;
552
553 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
554 WPAS_DBUS_NEW_IFACE_WPS, "Event");
555 if (msg == NULL)
556 return;
557
558 dbus_message_iter_init_append(msg, &iter);
559
560 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
561 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
562 !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
563 !wpa_dbus_dict_close_write(&iter, &dict_iter))
564 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
565 else
566 dbus_connection_send(iface->con, msg, NULL);
567
568 dbus_message_unref(msg);
569 }
570
571
572 /**
573 * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
574 * @wpa_s: %wpa_supplicant network interface data
575 *
576 * Sends Event dbus signal with name "m2d" and dictionary containing
577 * fields of wps_event_m2d structure.
578 */
579 void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
580 struct wps_event_m2d *m2d)
581 {
582
583 DBusMessage *msg;
584 DBusMessageIter iter, dict_iter;
585 struct wpas_dbus_priv *iface;
586 char *key = "m2d";
587
588 iface = wpa_s->global->dbus;
589
590 /* Do nothing if the control interface is not turned on */
591 if (iface == NULL)
592 return;
593
594 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
595 WPAS_DBUS_NEW_IFACE_WPS, "Event");
596 if (msg == NULL)
597 return;
598
599 dbus_message_iter_init_append(msg, &iter);
600
601 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
602 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
603 !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
604 m2d->config_methods) ||
605 !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
606 (const char *) m2d->manufacturer,
607 m2d->manufacturer_len) ||
608 !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
609 (const char *) m2d->model_name,
610 m2d->model_name_len) ||
611 !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
612 (const char *) m2d->model_number,
613 m2d->model_number_len) ||
614 !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
615 (const char *)
616 m2d->serial_number,
617 m2d->serial_number_len) ||
618 !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
619 (const char *) m2d->dev_name,
620 m2d->dev_name_len) ||
621 !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
622 (const char *)
623 m2d->primary_dev_type, 8) ||
624 !wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
625 m2d->config_error) ||
626 !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
627 m2d->dev_password_id) ||
628 !wpa_dbus_dict_close_write(&iter, &dict_iter))
629 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
630 else
631 dbus_connection_send(iface->con, msg, NULL);
632
633 dbus_message_unref(msg);
634 }
635
636
637 /**
638 * wpas_dbus_signal_wps_cred - Signals new credentials
639 * @wpa_s: %wpa_supplicant network interface data
640 *
641 * Sends signal with credentials in directory argument
642 */
643 void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
644 const struct wps_credential *cred)
645 {
646 DBusMessage *msg;
647 DBusMessageIter iter, dict_iter;
648 struct wpas_dbus_priv *iface;
649 char *auth_type[6]; /* we have six possible authorization types */
650 int at_num = 0;
651 char *encr_type[4]; /* we have four possible encryption types */
652 int et_num = 0;
653
654 iface = wpa_s->global->dbus;
655
656 /* Do nothing if the control interface is not turned on */
657 if (iface == NULL)
658 return;
659
660 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
661 WPAS_DBUS_NEW_IFACE_WPS,
662 "Credentials");
663 if (msg == NULL)
664 return;
665
666 dbus_message_iter_init_append(msg, &iter);
667 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
668 goto nomem;
669
670 if (cred->auth_type & WPS_AUTH_OPEN)
671 auth_type[at_num++] = "open";
672 if (cred->auth_type & WPS_AUTH_WPAPSK)
673 auth_type[at_num++] = "wpa-psk";
674 if (cred->auth_type & WPS_AUTH_SHARED)
675 auth_type[at_num++] = "shared";
676 if (cred->auth_type & WPS_AUTH_WPA)
677 auth_type[at_num++] = "wpa-eap";
678 if (cred->auth_type & WPS_AUTH_WPA2)
679 auth_type[at_num++] = "wpa2-eap";
680 if (cred->auth_type & WPS_AUTH_WPA2PSK)
681 auth_type[at_num++] =
682 "wpa2-psk";
683
684 if (cred->encr_type & WPS_ENCR_NONE)
685 encr_type[et_num++] = "none";
686 if (cred->encr_type & WPS_ENCR_WEP)
687 encr_type[et_num++] = "wep";
688 if (cred->encr_type & WPS_ENCR_TKIP)
689 encr_type[et_num++] = "tkip";
690 if (cred->encr_type & WPS_ENCR_AES)
691 encr_type[et_num++] = "aes";
692
693 if (wpa_s->current_ssid) {
694 if (!wpa_dbus_dict_append_byte_array(
695 &dict_iter, "BSSID",
696 (const char *) wpa_s->current_ssid->bssid,
697 ETH_ALEN))
698 goto nomem;
699 }
700
701 if (!wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
702 (const char *) cred->ssid,
703 cred->ssid_len) ||
704 !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
705 (const char **) auth_type,
706 at_num) ||
707 !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
708 (const char **) encr_type,
709 et_num) ||
710 !wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
711 (const char *) cred->key,
712 cred->key_len) ||
713 !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
714 cred->key_idx) ||
715 !wpa_dbus_dict_close_write(&iter, &dict_iter))
716 goto nomem;
717
718 dbus_connection_send(iface->con, msg, NULL);
719
720 nomem:
721 dbus_message_unref(msg);
722 }
723
724 #endif /* CONFIG_WPS */
725
726
727 /**
728 * wpas_dbus_signal_prop_changed - Signals change of property
729 * @wpa_s: %wpa_supplicant network interface data
730 * @property: indicates which property has changed
731 *
732 * Sends ProertyChanged signals with path, interface and arguments
733 * depending on which property has changed.
734 */
735 void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
736 enum wpas_dbus_prop property)
737 {
738 WPADBusPropertyAccessor getter;
739 char *prop;
740
741 switch (property) {
742 case WPAS_DBUS_PROP_AP_SCAN:
743 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan;
744 prop = "ApScan";
745 break;
746 case WPAS_DBUS_PROP_SCANNING:
747 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_scanning;
748 prop = "Scanning";
749 break;
750 case WPAS_DBUS_PROP_CURRENT_BSS:
751 getter = (WPADBusPropertyAccessor)
752 wpas_dbus_getter_current_bss;
753 prop = "CurrentBSS";
754 break;
755 case WPAS_DBUS_PROP_CURRENT_NETWORK:
756 getter = (WPADBusPropertyAccessor)
757 wpas_dbus_getter_current_network;
758 prop = "CurrentNetwork";
759 break;
760 default:
761 wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
762 __func__, property);
763 return;
764 }
765
766 wpa_dbus_signal_property_changed(wpa_s->global->dbus,
767 getter, wpa_s, wpa_s->dbus_new_path,
768 WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
769 }
770
771
772 /**
773 * wpas_dbus_signal_debug_level_changed - Signals change of debug param
774 * @global: wpa_global structure
775 *
776 * Sends ProertyChanged signals informing that debug level has changed.
777 */
778 void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
779 {
780 wpa_dbus_signal_property_changed(global->dbus,
781 (WPADBusPropertyAccessor)
782 wpas_dbus_getter_debug_level,
783 global, WPAS_DBUS_NEW_PATH,
784 WPAS_DBUS_NEW_INTERFACE,
785 "DebugLevel");
786 }
787
788
789 /**
790 * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
791 * @global: wpa_global structure
792 *
793 * Sends ProertyChanged signals informing that debug timestamp has changed.
794 */
795 void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
796 {
797 wpa_dbus_signal_property_changed(global->dbus,
798 (WPADBusPropertyAccessor)
799 wpas_dbus_getter_debug_timestamp,
800 global, WPAS_DBUS_NEW_PATH,
801 WPAS_DBUS_NEW_INTERFACE,
802 "DebugTimestamp");
803 }
804
805
806 /**
807 * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
808 * @global: wpa_global structure
809 *
810 * Sends ProertyChanged signals informing that debug show_keys has changed.
811 */
812 void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
813 {
814 wpa_dbus_signal_property_changed(global->dbus,
815 (WPADBusPropertyAccessor)
816 wpas_dbus_getter_debug_show_keys,
817 global, WPAS_DBUS_NEW_PATH,
818 WPAS_DBUS_NEW_INTERFACE,
819 "DebugShowKeys");
820 }
821
822
823 static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
824 void *priv,
825 WPADBusArgumentFreeFunction priv_free,
826 const struct wpa_dbus_method_desc *methods,
827 const struct wpa_dbus_property_desc *properties,
828 const struct wpa_dbus_signal_desc *signals)
829 {
830 obj_desc->user_data = priv;
831 obj_desc->user_data_free_func = priv_free;
832 obj_desc->methods = methods;
833 obj_desc->properties = properties;
834 obj_desc->signals = signals;
835 }
836
837
838 static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
839 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
840 (WPADBusMethodHandler) &wpas_dbus_handler_create_interface,
841 {
842 { "args", "a{sv}", ARG_IN },
843 { "path", "o", ARG_OUT },
844 END_ARGS
845 }
846 },
847 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
848 (WPADBusMethodHandler) &wpas_dbus_handler_remove_interface,
849 {
850 { "path", "o", ARG_IN },
851 END_ARGS
852 }
853 },
854 { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
855 (WPADBusMethodHandler) &wpas_dbus_handler_get_interface,
856 {
857 { "ifname", "s", ARG_IN },
858 { "path", "o", ARG_OUT },
859 END_ARGS
860 }
861 },
862 { NULL, NULL, NULL, { END_ARGS } }
863 };
864
865 static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
866 { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "y",
867 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_level,
868 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_level,
869 RW
870 },
871 { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
872 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_timestamp,
873 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_timestamp,
874 RW
875 },
876 { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
877 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_show_keys,
878 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_show_keys,
879 RW
880 },
881 { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
882 (WPADBusPropertyAccessor) &wpas_dbus_getter_interfaces,
883 NULL,
884 R
885 },
886 { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
887 (WPADBusPropertyAccessor) wpas_dbus_getter_eap_methods,
888 NULL,
889 R
890 },
891 { NULL, NULL, NULL, NULL, NULL, 0 }
892 };
893
894 static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
895 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
896 {
897 { "path", "o", ARG_OUT },
898 { "properties", "a{sv}", ARG_OUT },
899 END_ARGS
900 }
901 },
902 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
903 {
904 { "path", "o", ARG_OUT },
905 END_ARGS
906 }
907 },
908 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
909 {
910 { "properties", "a{sv}", ARG_OUT },
911 END_ARGS
912 }
913 },
914 { NULL, NULL, { END_ARGS } }
915 };
916
917
918 /**
919 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
920 * @global: Pointer to global data from wpa_supplicant_init()
921 * Returns: 0 on success or -1 on failure
922 *
923 * Initialize the dbus control interface for wpa_supplicantand and start
924 * receiving commands from external programs over the bus.
925 */
926 int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
927 {
928 struct wpa_dbus_object_desc *obj_desc;
929 int ret;
930
931 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
932 if (!obj_desc) {
933 wpa_printf(MSG_ERROR, "Not enough memory "
934 "to create object description");
935 return -1;
936 }
937
938 wpas_dbus_register(obj_desc, priv->global, NULL,
939 wpas_dbus_global_methods,
940 wpas_dbus_global_properties,
941 wpas_dbus_global_signals);
942
943 wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
944 WPAS_DBUS_NEW_PATH);
945 ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
946 WPAS_DBUS_NEW_SERVICE,
947 obj_desc);
948 if (ret < 0)
949 free_dbus_object_desc(obj_desc);
950 else
951 priv->dbus_new_initialized = 1;
952
953 return ret;
954 }
955
956
957 /**
958 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
959 * wpa_supplicant
960 * @iface: Pointer to dbus private data from wpas_dbus_init()
961 *
962 * Deinitialize the dbus control interface that was initialized with
963 * wpas_dbus_ctrl_iface_init().
964 */
965 void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface)
966 {
967 if (!iface->dbus_new_initialized)
968 return;
969 wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
970 WPAS_DBUS_NEW_PATH);
971 dbus_connection_unregister_object_path(iface->con,
972 WPAS_DBUS_NEW_PATH);
973 }
974
975
976 static void wpa_dbus_free(void *ptr)
977 {
978 os_free(ptr);
979 }
980
981
982 static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
983 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
984 (WPADBusPropertyAccessor) wpas_dbus_getter_network_properties,
985 (WPADBusPropertyAccessor) wpas_dbus_setter_network_properties,
986 RW
987 },
988 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
989 (WPADBusPropertyAccessor) wpas_dbus_getter_enabled,
990 (WPADBusPropertyAccessor) wpas_dbus_setter_enabled,
991 RW
992 },
993 { NULL, NULL, NULL, NULL, NULL, 0 }
994 };
995
996
997 static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
998 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
999 {
1000 { "properties", "a{sv}", ARG_OUT },
1001 END_ARGS
1002 }
1003 },
1004 { NULL, NULL, { END_ARGS } }
1005 };
1006
1007
1008 /**
1009 * wpas_dbus_register_network - Register a configured network with dbus
1010 * @wpa_s: wpa_supplicant interface structure
1011 * @ssid: network configuration data
1012 * Returns: 0 on success, -1 on failure
1013 *
1014 * Registers network representing object with dbus
1015 */
1016 int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
1017 struct wpa_ssid *ssid)
1018 {
1019 struct wpas_dbus_priv *ctrl_iface;
1020 struct wpa_dbus_object_desc *obj_desc;
1021 struct network_handler_args *arg = NULL;
1022 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
1023
1024 /* Do nothing if the control interface is not turned on */
1025 if (wpa_s == NULL || wpa_s->global == NULL)
1026 return 0;
1027 ctrl_iface = wpa_s->global->dbus;
1028 if (ctrl_iface == NULL)
1029 return 0;
1030
1031 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1032 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
1033 wpa_s->dbus_new_path, ssid->id);
1034
1035 wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
1036 net_obj_path);
1037 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1038 if (!obj_desc) {
1039 wpa_printf(MSG_ERROR, "Not enough memory "
1040 "to create object description");
1041 goto err;
1042 }
1043
1044 /* allocate memory for handlers arguments */
1045 arg = os_zalloc(sizeof(struct network_handler_args));
1046 if (!arg) {
1047 wpa_printf(MSG_ERROR, "Not enough memory "
1048 "to create arguments for method");
1049 goto err;
1050 }
1051
1052 arg->wpa_s = wpa_s;
1053 arg->ssid = ssid;
1054
1055 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
1056 wpas_dbus_network_properties,
1057 wpas_dbus_network_signals);
1058
1059 if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
1060 wpa_s->ifname, obj_desc))
1061 goto err;
1062
1063 wpas_dbus_signal_network_added(wpa_s, ssid->id);
1064
1065 return 0;
1066
1067 err:
1068 os_free(obj_desc);
1069 os_free(arg);
1070 return -1;
1071 }
1072
1073
1074 /**
1075 * wpas_dbus_unregister_network - Unregister a configured network from dbus
1076 * @wpa_s: wpa_supplicant interface structure
1077 * @nid: network id
1078 * Returns: 0 on success, -1 on failure
1079 *
1080 * Unregisters network representing object from dbus
1081 */
1082 int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
1083 {
1084 struct wpas_dbus_priv *ctrl_iface;
1085 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
1086 int ret;
1087
1088 /* Do nothing if the control interface is not turned on */
1089 if (wpa_s == NULL || wpa_s->global == NULL)
1090 return 0;
1091 ctrl_iface = wpa_s->global->dbus;
1092 if (ctrl_iface == NULL)
1093 return 0;
1094
1095 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1096 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
1097 wpa_s->dbus_new_path, nid);
1098
1099 wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
1100 net_obj_path);
1101 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
1102
1103 if (!ret)
1104 wpas_dbus_signal_network_removed(wpa_s, nid);
1105
1106 return ret;
1107 }
1108
1109
1110 static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
1111 { "SSID", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1112 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ssid,
1113 NULL,
1114 R
1115 },
1116 { "BSSID", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1117 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_bssid,
1118 NULL,
1119 R
1120 },
1121 { "Privacy", WPAS_DBUS_NEW_IFACE_BSSID, "b",
1122 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_privacy,
1123 NULL,
1124 R
1125 },
1126 { "Mode", WPAS_DBUS_NEW_IFACE_BSSID, "s",
1127 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_mode,
1128 NULL,
1129 R
1130 },
1131 { "Signal", WPAS_DBUS_NEW_IFACE_BSSID, "n",
1132 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_signal,
1133 NULL,
1134 R
1135 },
1136 { "Frequency", WPAS_DBUS_NEW_IFACE_BSSID, "q",
1137 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_frequency,
1138 NULL,
1139 R
1140 },
1141 { "MaxRate", WPAS_DBUS_NEW_IFACE_BSSID, "q",
1142 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_max_rate,
1143 NULL,
1144 R
1145 },
1146 { "WPAIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1147 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpaie,
1148 NULL,
1149 R
1150 },
1151 { "RSNIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1152 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rsnie,
1153 NULL,
1154 R
1155 },
1156 { "WPSIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1157 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpsie,
1158 NULL,
1159 R
1160 },
1161 { NULL, NULL, NULL, NULL, NULL, 0 }
1162 };
1163
1164
1165 static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
1166 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSSID,
1167 {
1168 { "properties", "a{sv}", ARG_OUT },
1169 END_ARGS
1170 }
1171 },
1172 { NULL, NULL, { END_ARGS } }
1173 };
1174
1175
1176 /**
1177 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
1178 * @wpa_s: wpa_supplicant interface structure
1179 * @bssid: scanned network bssid
1180 * @id: unique BSS identifier
1181 * Returns: 0 on success, -1 on failure
1182 *
1183 * Unregisters BSS representing object from dbus
1184 */
1185 int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
1186 u8 bssid[ETH_ALEN], unsigned int id)
1187 {
1188 struct wpas_dbus_priv *ctrl_iface;
1189 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
1190
1191 /* Do nothing if the control interface is not turned on */
1192 if (wpa_s == NULL || wpa_s->global == NULL)
1193 return 0;
1194 ctrl_iface = wpa_s->global->dbus;
1195 if (ctrl_iface == NULL)
1196 return 0;
1197
1198 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1199 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
1200 wpa_s->dbus_new_path, id);
1201
1202 wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
1203 bss_obj_path);
1204 if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
1205 wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
1206 bss_obj_path);
1207 return -1;
1208 }
1209
1210 wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
1211
1212 return 0;
1213 }
1214
1215
1216 /**
1217 * wpas_dbus_register_bss - Register a scanned BSS with dbus
1218 * @wpa_s: wpa_supplicant interface structure
1219 * @bssid: scanned network bssid
1220 * @id: unique BSS identifier
1221 * Returns: 0 on success, -1 on failure
1222 *
1223 * Registers BSS representing object with dbus
1224 */
1225 int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
1226 u8 bssid[ETH_ALEN], unsigned int id)
1227 {
1228 struct wpas_dbus_priv *ctrl_iface;
1229 struct wpa_dbus_object_desc *obj_desc;
1230 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
1231 struct bss_handler_args *arg = NULL;
1232
1233 /* Do nothing if the control interface is not turned on */
1234 if (wpa_s == NULL || wpa_s->global == NULL)
1235 return 0;
1236 ctrl_iface = wpa_s->global->dbus;
1237 if (ctrl_iface == NULL)
1238 return 0;
1239
1240 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1241 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
1242 wpa_s->dbus_new_path, id);
1243
1244 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1245 if (!obj_desc) {
1246 wpa_printf(MSG_ERROR, "Not enough memory "
1247 "to create object description");
1248 goto err;
1249 }
1250
1251 arg = os_zalloc(sizeof(struct bss_handler_args));
1252 if (!arg) {
1253 wpa_printf(MSG_ERROR, "Not enough memory "
1254 "to create arguments for handler");
1255 goto err;
1256 }
1257 arg->wpa_s = wpa_s;
1258 arg->id = id;
1259
1260 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
1261 wpas_dbus_bss_properties,
1262 wpas_dbus_bss_signals);
1263
1264 wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
1265 bss_obj_path);
1266 if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
1267 wpa_s->ifname, obj_desc)) {
1268 wpa_printf(MSG_ERROR,
1269 "Cannot register BSSID dbus object %s.",
1270 bss_obj_path);
1271 goto err;
1272 }
1273
1274 wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
1275
1276 return 0;
1277
1278 err:
1279 os_free(obj_desc);
1280 os_free(arg);
1281 return -1;
1282 }
1283
1284
1285 static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
1286 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
1287 (WPADBusMethodHandler) &wpas_dbus_handler_scan,
1288 {
1289 { "args", "a{sv}", ARG_IN },
1290 END_ARGS
1291 }
1292 },
1293 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
1294 (WPADBusMethodHandler) &wpas_dbus_handler_disconnect,
1295 {
1296 END_ARGS
1297 }
1298 },
1299 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1300 (WPADBusMethodHandler) &wpas_dbus_handler_add_network,
1301 {
1302 { "args", "a{sv}", ARG_IN },
1303 { "path", "o", ARG_OUT },
1304 END_ARGS
1305 }
1306 },
1307 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1308 (WPADBusMethodHandler) &wpas_dbus_handler_remove_network,
1309 {
1310 { "path", "o", ARG_IN },
1311 END_ARGS
1312 }
1313 },
1314 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1315 (WPADBusMethodHandler) &wpas_dbus_handler_select_network,
1316 {
1317 { "path", "o", ARG_IN },
1318 END_ARGS
1319 }
1320 },
1321 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1322 (WPADBusMethodHandler) &wpas_dbus_handler_add_blob,
1323 {
1324 { "name", "s", ARG_IN },
1325 { "data", "ay", ARG_IN },
1326 END_ARGS
1327 }
1328 },
1329 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1330 (WPADBusMethodHandler) &wpas_dbus_handler_get_blob,
1331 {
1332 { "name", "s", ARG_IN },
1333 { "data", "ay", ARG_OUT },
1334 END_ARGS
1335 }
1336 },
1337 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1338 (WPADBusMethodHandler) &wpas_dbus_handler_remove_blob,
1339 {
1340 { "name", "s", ARG_IN },
1341 END_ARGS
1342 }
1343 },
1344 #ifdef CONFIG_WPS
1345 { "Start", WPAS_DBUS_NEW_IFACE_WPS,
1346 (WPADBusMethodHandler) &wpas_dbus_handler_wps_start,
1347 {
1348 { "args", "a{sv}", ARG_IN },
1349 { "output", "a{sv}", ARG_OUT },
1350 END_ARGS
1351 }
1352 },
1353 #endif /* CONFIG_WPS */
1354 { NULL, NULL, NULL, { END_ARGS } }
1355 };
1356
1357 static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
1358 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
1359 (WPADBusPropertyAccessor) wpas_dbus_getter_capabilities,
1360 NULL, R
1361 },
1362 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1363 (WPADBusPropertyAccessor) wpas_dbus_getter_state,
1364 NULL, R
1365 },
1366 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
1367 (WPADBusPropertyAccessor) wpas_dbus_getter_scanning,
1368 NULL, R
1369 },
1370 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
1371 (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan,
1372 (WPADBusPropertyAccessor) wpas_dbus_setter_ap_scan,
1373 RW
1374 },
1375 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1376 (WPADBusPropertyAccessor) wpas_dbus_getter_ifname,
1377 NULL, R
1378 },
1379 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1380 (WPADBusPropertyAccessor) wpas_dbus_getter_driver,
1381 NULL, R
1382 },
1383 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1384 (WPADBusPropertyAccessor) wpas_dbus_getter_bridge_ifname,
1385 NULL, R
1386 },
1387 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
1388 (WPADBusPropertyAccessor) wpas_dbus_getter_current_bss,
1389 NULL, R
1390 },
1391 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
1392 (WPADBusPropertyAccessor) wpas_dbus_getter_current_network,
1393 NULL, R
1394 },
1395 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
1396 (WPADBusPropertyAccessor) wpas_dbus_getter_blobs,
1397 NULL, R
1398 },
1399 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
1400 (WPADBusPropertyAccessor) wpas_dbus_getter_bsss,
1401 NULL, R
1402 },
1403 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
1404 (WPADBusPropertyAccessor) wpas_dbus_getter_networks,
1405 NULL, R
1406 },
1407 #ifdef CONFIG_WPS
1408 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
1409 (WPADBusPropertyAccessor) wpas_dbus_getter_process_credentials,
1410 (WPADBusPropertyAccessor) wpas_dbus_setter_process_credentials,
1411 RW
1412 },
1413 #endif /* CONFIG_WPS */
1414 { NULL, NULL, NULL, NULL, NULL, 0 }
1415 };
1416
1417 static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
1418 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
1419 {
1420 { "success", "b", ARG_OUT },
1421 END_ARGS
1422 }
1423 },
1424 { "StateChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
1425 {
1426 { "newState", "s", ARG_OUT },
1427 { "oldState", "s", ARG_OUT },
1428 END_ARGS
1429 }
1430 },
1431 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1432 {
1433 { "path", "o", ARG_OUT },
1434 { "properties", "a{sv}", ARG_OUT },
1435 END_ARGS
1436 }
1437 },
1438 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1439 {
1440 { "path", "o", ARG_OUT },
1441 END_ARGS
1442 }
1443 },
1444 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1445 {
1446 { "name", "s", ARG_OUT },
1447 END_ARGS
1448 }
1449 },
1450 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1451 {
1452 { "name", "s", ARG_OUT },
1453 END_ARGS
1454 }
1455 },
1456 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1457 {
1458 { "path", "o", ARG_OUT },
1459 { "properties", "a{sv}", ARG_OUT },
1460 END_ARGS
1461 }
1462 },
1463 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1464 {
1465 { "path", "o", ARG_OUT },
1466 END_ARGS
1467 }
1468 },
1469 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
1470 {
1471 { "path", "o", ARG_OUT },
1472 END_ARGS
1473 }
1474 },
1475 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
1476 {
1477 { "properties", "a{sv}", ARG_OUT },
1478 END_ARGS
1479 }
1480 },
1481 #ifdef CONFIG_WPS
1482 { "Event", WPAS_DBUS_NEW_IFACE_WPS,
1483 {
1484 { "name", "s", ARG_OUT },
1485 { "args", "a{sv}", ARG_OUT },
1486 END_ARGS
1487 }
1488 },
1489 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
1490 {
1491 { "credentials", "a{sv}", ARG_OUT },
1492 END_ARGS
1493 }
1494 },
1495 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
1496 {
1497 { "properties", "a{sv}", ARG_OUT },
1498 END_ARGS
1499 }
1500 },
1501 #endif /* CONFIG_WPS */
1502 { NULL, NULL, { END_ARGS } }
1503 };
1504
1505
1506 int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
1507 {
1508
1509 struct wpa_dbus_object_desc *obj_desc = NULL;
1510 struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
1511 int next;
1512
1513 /* Do nothing if the control interface is not turned on */
1514 if (ctrl_iface == NULL)
1515 return 0;
1516
1517 /* Create and set the interface's object path */
1518 wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1519 if (wpa_s->dbus_new_path == NULL)
1520 return -1;
1521 next = ctrl_iface->next_objid++;
1522 os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
1523 WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
1524 next);
1525
1526 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1527 if (!obj_desc) {
1528 wpa_printf(MSG_ERROR, "Not enough memory "
1529 "to create object description");
1530 goto err;
1531 }
1532
1533 wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
1534 wpas_dbus_interface_properties,
1535 wpas_dbus_interface_signals);
1536
1537 wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
1538 wpa_s->dbus_new_path);
1539 if (wpa_dbus_register_object_per_iface(ctrl_iface,
1540 wpa_s->dbus_new_path,
1541 wpa_s->ifname, obj_desc))
1542 goto err;
1543
1544 wpas_dbus_signal_interface_added(wpa_s);
1545
1546 return 0;
1547
1548 err:
1549 os_free(wpa_s->dbus_new_path);
1550 wpa_s->dbus_new_path = NULL;
1551 os_free(obj_desc);
1552 return -1;
1553 }
1554
1555
1556 int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
1557 {
1558 struct wpas_dbus_priv *ctrl_iface;
1559
1560 /* Do nothing if the control interface is not turned on */
1561 if (wpa_s == NULL || wpa_s->global == NULL)
1562 return 0;
1563 ctrl_iface = wpa_s->global->dbus;
1564 if (ctrl_iface == NULL)
1565 return 0;
1566
1567 wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
1568 wpa_s->dbus_new_path);
1569 if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
1570 wpa_s->dbus_new_path))
1571 return -1;
1572
1573 wpas_dbus_signal_interface_removed(wpa_s);
1574
1575 os_free(wpa_s->dbus_new_path);
1576 wpa_s->dbus_new_path = NULL;
1577
1578 return 0;
1579 }