dbus: Verify dbus_message_new_method_return() return value before use
[hostap-gosc2009.git] / wpa_supplicant / dbus / dbus_new.c
blob56a34c0f402fc86deb1279d47490c6aaa4881ec7
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>
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.
11 * Alternatively, this software may be distributed under the terms of BSD
12 * license.
14 * See README and COPYING for more details.
17 #include "includes.h"
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"
29 /**
30 * wpas_dbus_set_path - Assign a dbus path to an interface
31 * @wpa_s: wpa_supplicant interface structure
32 * @path: dbus path to set on the interface
33 * Returns: 0 on success, -1 on error
35 static int wpas_dbus_set_path(struct wpa_supplicant *wpa_s,
36 const char *path)
38 u32 len = os_strlen(path);
39 if (len >= WPAS_DBUS_OBJECT_PATH_MAX)
40 return -1;
41 if (wpa_s->dbus_new_path)
42 return -1;
43 wpa_s->dbus_new_path = os_strdup(path);
44 return 0;
48 /**
49 * wpas_dbus_signal_interface - Send a interface related event signal
50 * @wpa_s: %wpa_supplicant network interface data
51 * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
53 * Notify listeners about event related with interface
55 static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
56 const char *sig_name)
58 struct ctrl_iface_dbus_new_priv *iface;
59 DBusMessage *_signal;
60 const char *path;
62 iface = wpa_s->global->dbus_new_ctrl_iface;
64 /* Do nothing if the control interface is not turned on */
65 if (iface == NULL)
66 return;
68 path = wpas_dbus_get_path(wpa_s);
69 if (path == NULL) {
70 wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
71 "Interface doesn't have a dbus path. "
72 "Can't send signal.");
73 return;
75 _signal = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
76 WPAS_DBUS_NEW_INTERFACE, sig_name);
77 if (_signal == NULL) {
78 wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
79 "enough memory to send scan results signal.");
80 return;
83 if (dbus_message_append_args(_signal, DBUS_TYPE_OBJECT_PATH, &path,
84 DBUS_TYPE_INVALID)) {
85 dbus_connection_send(iface->con, _signal, NULL);
86 } else {
87 wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
88 "not enough memory to construct signal.");
90 dbus_message_unref(_signal);
94 /**
95 * wpas_dbus_signal_interface_created - Send a interface created signal
96 * @wpa_s: %wpa_supplicant network interface data
98 * Notify listeners about creating new interface
100 static void wpas_dbus_signal_interface_created(struct wpa_supplicant *wpa_s)
102 wpas_dbus_signal_interface(wpa_s, "InterfaceCreated");
107 * wpas_dbus_signal_interface_removed - Send a interface removed signal
108 * @wpa_s: %wpa_supplicant network interface data
110 * Notify listeners about removing interface
112 static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
114 wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved");
120 * wpas_dbus_signal_scan_done - send scan done signal
121 * @wpa_s: %wpa_supplicant network interface data
122 * @success: indicates if scanning succeed or failed
124 * Notify listeners about finishing a scan
126 static void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s,
127 int success)
129 struct ctrl_iface_dbus_new_priv *iface;
130 DBusMessage *_signal;
131 const char *path;
132 dbus_bool_t succ;
134 iface = wpa_s->global->dbus_new_ctrl_iface;
136 /* Do nothing if the control interface is not turned on */
137 if (iface == NULL)
138 return;
140 path = wpas_dbus_get_path(wpa_s);
141 if (path == NULL) {
142 wpa_printf(MSG_ERROR, "wpas_dbus_signal_scan_done[dbus]: "
143 "Interface doesn't have a dbus path. "
144 "Can't send signal.");
145 return;
147 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
148 "ScanDone");
149 if (_signal == NULL) {
150 wpa_printf(MSG_ERROR, "wpas_dbus_signal_scan_done[dbus]: "
151 "enough memory to send signal.");
152 return;
155 succ = success ? TRUE : FALSE;
156 if (dbus_message_append_args(_signal, DBUS_TYPE_BOOLEAN, &succ,
157 DBUS_TYPE_INVALID)) {
158 dbus_connection_send(iface->con, _signal, NULL);
159 } else {
160 wpa_printf(MSG_ERROR, "wpas_dbus_signal_scan_done[dbus]: "
161 "not enough memory to construct signal.");
163 dbus_message_unref(_signal);
168 * wpas_dbus_signal_blob - Send a BSS related event signal
169 * @wpa_s: %wpa_supplicant network interface data
170 * @bss_obj_path: BSS object path
171 * @sig_name: signal name - BSSAdded or BSSRemoved
173 * Notify listeners about event related with BSS
175 static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
176 const char *bss_obj_path,
177 const char *sig_name)
179 struct ctrl_iface_dbus_new_priv *iface;
180 DBusMessage *_signal;
181 const char *path;
183 iface = wpa_s->global->dbus_new_ctrl_iface;
185 /* Do nothing if the control interface is not turned on */
186 if (iface == NULL)
187 return;
189 path = wpas_dbus_get_path(wpa_s);
190 if (path == NULL) {
191 wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
192 "Interface doesn't have a dbus path. "
193 "Can't send signal.");
194 return;
196 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
197 sig_name);
198 if (_signal == NULL) {
199 wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
200 "enough memory to send signal.");
201 return;
204 if (dbus_message_append_args(_signal, DBUS_TYPE_OBJECT_PATH,
205 &bss_obj_path, DBUS_TYPE_INVALID)) {
206 dbus_connection_send(iface->con, _signal, NULL);
207 } else {
208 wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
209 "not enough memory to construct signal.");
211 dbus_message_unref(_signal);
216 * wpas_dbus_signal_bss_added - Send a BSS added signal
217 * @wpa_s: %wpa_supplicant network interface data
218 * @bss_obj_path: new BSS object path
220 * Notify listeners about adding new BSS
222 static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
223 const char *bss_obj_path)
225 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded");
230 * wpas_dbus_signal_bss_removed - Send a BSS removed signal
231 * @wpa_s: %wpa_supplicant network interface data
232 * @bss_obj_path: BSS object path
234 * Notify listeners about removing BSS
236 static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
237 const char *bss_obj_path)
239 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved");
244 * wpas_dbus_signal_blob - Send a blob related event signal
245 * @wpa_s: %wpa_supplicant network interface data
246 * @name: blob name
247 * @sig_name: signal name - BlobAdded or BlobRemoved
249 * Notify listeners about event related with blob
251 static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
252 const char *name, const char *sig_name)
254 struct ctrl_iface_dbus_new_priv *iface;
255 DBusMessage *_signal;
256 const char *path;
258 iface = wpa_s->global->dbus_new_ctrl_iface;
260 /* Do nothing if the control interface is not turned on */
261 if (iface == NULL)
262 return;
264 path = wpas_dbus_get_path(wpa_s);
265 if (path == NULL) {
266 wpa_printf(MSG_ERROR, "wpas_dbus_signal_blob[dbus]: "
267 "Interface doesn't have a dbus path. "
268 "Can't send signal.");
269 return;
271 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
272 sig_name);
273 if (_signal == NULL) {
274 wpa_printf(MSG_ERROR, "wpas_dbus_signal_blob[dbus]: "
275 "enough memory to send signal.");
276 return;
279 if (dbus_message_append_args(_signal, DBUS_TYPE_STRING, &name,
280 DBUS_TYPE_INVALID)) {
281 dbus_connection_send(iface->con, _signal, NULL);
282 } else {
283 wpa_printf(MSG_ERROR, "wpas_dbus_signal_blob[dbus]: "
284 "not enough memory to construct signal.");
286 dbus_message_unref(_signal);
291 * wpas_dbus_signal_blob_added - Send a blob added signal
292 * @wpa_s: %wpa_supplicant network interface data
293 * @name: blob name
295 * Notify listeners about adding a new blob
297 static void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
298 const char *name)
300 wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
305 * wpas_dbus_signal_blob_removed - Send a blob removed signal
306 * @wpa_s: %wpa_supplicant network interface data
307 * @name: blob name
309 * Notify listeners about removing blob
311 static void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
312 const char *name)
314 wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
319 * wpas_dbus_signal_network - Send a network related event signal
320 * @wpa_s: %wpa_supplicant network interface data
321 * @id: new network id
322 * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
324 * Notify listeners about event related with configured network
326 static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
327 int id, const char *sig_name)
329 struct ctrl_iface_dbus_new_priv *iface;
330 DBusMessage *_signal;
331 const char *path;
332 char *net_obj_path;
334 iface = wpa_s->global->dbus_new_ctrl_iface;
336 /* Do nothing if the control interface is not turned on */
337 if (iface == NULL)
338 return;
340 path = wpas_dbus_get_path(wpa_s);
341 if (path == NULL) {
342 wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
343 "Interface doesn't have a dbus path. "
344 "Can't send signal.");
345 return;
348 net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
349 if (net_obj_path == NULL)
350 return;
351 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
352 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", path, id);
354 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
355 sig_name);
356 if (_signal == NULL) {
357 wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
358 "enough memory to send signal.");
359 os_free(net_obj_path);
360 return;
363 if (dbus_message_append_args(_signal, DBUS_TYPE_OBJECT_PATH,
364 &net_obj_path, DBUS_TYPE_INVALID)) {
365 dbus_connection_send(iface->con, _signal, NULL);
366 } else {
367 wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
368 "not enough memory to construct signal.");
371 os_free(net_obj_path);
372 dbus_message_unref(_signal);
377 * wpas_dbus_signal_network_added - Send a network added signal
378 * @wpa_s: %wpa_supplicant network interface data
379 * @id: new network id
381 * Notify listeners about adding new network
383 static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
384 int id)
386 wpas_dbus_signal_network(wpa_s, id, "NetworkAdded");
391 * wpas_dbus_signal_network_removed - Send a network removed signal
392 * @wpa_s: %wpa_supplicant network interface data
393 * @id: network id
395 * Notify listeners about removing a network
397 static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
398 int id)
400 wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved");
405 * wpas_dbus_signal_network_selected - Send a network selected signal
406 * @wpa_s: %wpa_supplicant network interface data
407 * @id: network id
409 * Notify listeners about selecting a network
411 static void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s,
412 int id)
414 wpas_dbus_signal_network(wpa_s, id, "NetworkSelected");
419 * wpas_dbus_signal_state_changed - Send a state changed signal
420 * @wpa_s: %wpa_supplicant network interface data
421 * @new_state: new state wpa_supplicant is entering
422 * @old_state: old state wpa_supplicant is leaving
424 * Notify listeners that wpa_supplicant has changed state
426 static void wpas_dbus_signal_state_changed(struct wpa_supplicant *wpa_s,
427 enum wpa_states new_state,
428 enum wpa_states old_state)
430 struct ctrl_iface_dbus_new_priv *iface;
431 DBusMessage *_signal = NULL;
432 const char *path;
433 char *new_state_str, *old_state_str;
434 char *tmp;
436 /* Do nothing if the control interface is not turned on */
437 if (wpa_s->global == NULL)
438 return;
439 iface = wpa_s->global->dbus_new_ctrl_iface;
440 if (iface == NULL)
441 return;
443 /* Only send signal if state really changed */
444 if (new_state == old_state)
445 return;
447 path = wpas_dbus_get_path(wpa_s);
448 if (path == NULL) {
449 perror("wpas_dbus_signal_state_changed[dbus]: "
450 "interface didn't have a dbus path");
451 wpa_printf(MSG_ERROR,
452 "wpas_dbus_signal_state_changed[dbus]: "
453 "interface didn't have a dbus path; can't send "
454 "signal.");
455 return;
457 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
458 "StateChanged");
459 if (_signal == NULL) {
460 perror("wpas_dbus_signal_state_changed[dbus]: "
461 "couldn't create dbus signal; likely out of memory");
462 wpa_printf(MSG_ERROR,
463 "wpas_dbus_signal_state_changed[dbus]: "
464 "couldn't create dbus signal; likely out of "
465 "memory.");
466 return;
469 new_state_str = os_strdup(wpa_supplicant_state_txt(new_state));
470 old_state_str = os_strdup(wpa_supplicant_state_txt(old_state));
471 if (new_state_str == NULL || old_state_str == NULL) {
472 perror("wpas_dbus_signal_state_changed[dbus]: "
473 "couldn't convert state strings");
474 wpa_printf(MSG_ERROR,
475 "wpas_dbus_signal_state_changed[dbus]: "
476 "couldn't convert state strings.");
477 goto out;
480 /* make state string lowercase to fit new DBus API convention */
481 tmp = new_state_str;
482 while (*tmp) {
483 *tmp = tolower(*tmp);
484 tmp++;
486 tmp = old_state_str;
487 while (*tmp) {
488 *tmp = tolower(*tmp);
489 tmp++;
492 if (!dbus_message_append_args(_signal,
493 DBUS_TYPE_STRING, &new_state_str,
494 DBUS_TYPE_STRING, &old_state_str,
495 DBUS_TYPE_INVALID)) {
496 perror("wpas_dbus_signal_state_changed[dbus]: "
497 "not enough memory to construct state change signal.");
498 wpa_printf(MSG_ERROR,
499 "wpas_dbus_signal_state_changed[dbus]: "
500 "not enough memory to construct state change "
501 "signal.");
502 goto out;
505 dbus_connection_send(iface->con, _signal, NULL);
507 out:
508 dbus_message_unref(_signal);
509 os_free(new_state_str);
510 os_free(old_state_str);
515 * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
516 * @wpa_s: %wpa_supplicant network interface data
517 * @ssid: configured network which Enabled property has changed
519 * Sends PropertyChanged signals containing new value of Enabled property
520 * for specified network
522 static void wpas_dbus_signal_network_enabled_changed(
523 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
526 struct network_handler_args args = {wpa_s, ssid};
528 char path[WPAS_DBUS_OBJECT_PATH_MAX];
529 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
530 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
531 wpas_dbus_get_path(wpa_s), ssid->id);
533 wpa_dbus_signal_property_changed(wpa_s->global->dbus_new_ctrl_iface,
534 (WPADBusPropertyAccessor)
535 wpas_dbus_getter_enabled, &args,
536 path, WPAS_DBUS_NEW_IFACE_NETWORK,
537 "Enabled");
541 #ifdef CONFIG_WPS
544 * wpas_dbus_signal_wps_event_success - Signals Success WPS event
545 * @wpa_s: %wpa_supplicant network interface data
547 * Sends Event dbus signal with name "success" and empty dict as arguments
549 static void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
552 DBusMessage *_signal = NULL;
553 DBusMessageIter iter, dict_iter;
554 struct ctrl_iface_dbus_new_priv *iface;
555 char *key = "success";
556 const char *path;
558 iface = wpa_s->global->dbus_new_ctrl_iface;
560 /* Do nothing if the control interface is not turned on */
561 if (iface == NULL)
562 return;
564 path = wpas_dbus_get_path(wpa_s);
565 if (!path) {
566 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_success"
567 "[dbus]: interface has no dbus path set");
568 return;
571 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
572 "Event");
573 if (!_signal) {
574 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_success"
575 "[dbus]: out of memory when creating a signal");
576 return;
579 dbus_message_iter_init_append(_signal, &iter);
581 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
582 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
583 !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
584 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_success"
585 "[dbus]: out of memory");
586 goto out;
589 dbus_connection_send(iface->con, _signal, NULL);
590 out:
591 dbus_message_unref(_signal);
596 * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
597 * @wpa_s: %wpa_supplicant network interface data
599 * Sends Event dbus signal with name "fail" and dictionary containing
600 * "msg field with fail message number (int32) as arguments
602 static void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
603 struct wps_event_fail *fail)
606 DBusMessage *_signal = NULL;
607 DBusMessageIter iter, dict_iter;
608 struct ctrl_iface_dbus_new_priv *iface;
609 char *key = "fail";
610 const char *path;
612 iface = wpa_s->global->dbus_new_ctrl_iface;
614 /* Do nothing if the control interface is not turned on */
615 if (iface == NULL)
616 return;
618 path = wpas_dbus_get_path(wpa_s);
619 if (!path) {
620 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_fail[dbus]: "
621 "interface has no dbus path set");
622 return;
625 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
626 "Event");
627 if (!_signal) {
628 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_fail[dbus]: "
629 "out of memory when creating a signal");
630 return;
633 dbus_message_iter_init_append(_signal, &iter);
635 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
636 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
637 !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
638 !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
639 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_fail[dbus]: "
640 "out of memory");
641 goto out;
644 dbus_connection_send(iface->con, _signal, NULL);
645 out:
646 dbus_message_unref(_signal);
651 * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
652 * @wpa_s: %wpa_supplicant network interface data
654 * Sends Event dbus signal with name "m2d" and dictionary containing
655 * fields of wps_event_m2d structure.
657 static void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
658 struct wps_event_m2d *m2d)
661 DBusMessage *_signal = NULL;
662 DBusMessageIter iter, dict_iter;
663 struct ctrl_iface_dbus_new_priv *iface;
664 char *key = "m2d";
665 const char *path;
667 iface = wpa_s->global->dbus_new_ctrl_iface;
669 /* Do nothing if the control interface is not turned on */
670 if (iface == NULL)
671 return;
673 path = wpas_dbus_get_path(wpa_s);
674 if (!path) {
675 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_m2d[dbus]: "
676 "interface has no dbus path set");
677 return;
680 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
681 "Event");
682 if (!_signal) {
683 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_m2d[dbus]: "
684 "out of memory when creating a signal");
685 return;
688 dbus_message_iter_init_append(_signal, &iter);
690 if (!(dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) &&
691 wpa_dbus_dict_open_write(&iter, &dict_iter) &&
692 wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
693 m2d->config_methods) &&
694 wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
695 (const char *) m2d->manufacturer,
696 m2d->manufacturer_len) &&
697 wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
698 (const char *) m2d->model_name,
699 m2d->model_name_len) &&
700 wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
701 (const char *) m2d->model_number,
702 m2d->model_number_len) &&
703 wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
704 (const char *)
705 m2d->serial_number,
706 m2d->serial_number_len) &&
707 wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
708 (const char *) m2d->dev_name,
709 m2d->dev_name_len) &&
710 wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
711 (const char *)
712 m2d->primary_dev_type, 8) &&
713 wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
714 m2d->config_error) &&
715 wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
716 m2d->dev_password_id) &&
717 wpa_dbus_dict_close_write(&iter, &dict_iter))) {
718 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_m2d[dbus]: "
719 "out of memory");
720 goto out;
723 dbus_connection_send(iface->con, _signal, NULL);
724 out:
725 dbus_message_unref(_signal);
730 * wpas_dbus_signal_wps_cred - Signals new credentials
731 * @wpa_s: %wpa_supplicant network interface data
733 * Sends signal with credentials in directory argument
735 static void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
736 const struct wps_credential *cred)
738 DBusMessage *_signal = NULL;
739 DBusMessageIter iter, dict_iter;
740 struct ctrl_iface_dbus_new_priv *iface;
741 const char *path;
742 char *auth_type[6]; /* we have six possible authorization types */
743 int at_num = 0;
744 char *encr_type[4]; /* we have four possible encryption types */
745 int et_num = 0;
747 iface = wpa_s->global->dbus_new_ctrl_iface;
749 /* Do nothing if the control interface is not turned on */
750 if (iface == NULL)
751 return;
753 path = wpas_dbus_get_path(wpa_s);
754 if (!path) {
755 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_cred[dbus]: "
756 "interface has no dbus path set");
757 return;
760 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
761 "Credentials");
762 if (!_signal) {
763 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_cred[dbus]: "
764 "out of memory when creating a signal");
765 return;
768 dbus_message_iter_init_append(_signal, &iter);
770 if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) {
771 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
772 "when opening a dictionary");
773 goto nomem;
776 if (cred->auth_type & WPS_AUTH_OPEN)
777 auth_type[at_num++] = "open";
778 if (cred->auth_type & WPS_AUTH_WPAPSK)
779 auth_type[at_num++] = "wpa-psk";
780 if (cred->auth_type & WPS_AUTH_SHARED)
781 auth_type[at_num++] = "shared";
782 if (cred->auth_type & WPS_AUTH_WPA)
783 auth_type[at_num++] = "wpa-eap";
784 if (cred->auth_type & WPS_AUTH_WPA2)
785 auth_type[at_num++] = "wpa2-eap";
786 if (cred->auth_type & WPS_AUTH_WPA2PSK)
787 auth_type[at_num++] =
788 "wpa2-psk";
790 if (cred->encr_type & WPS_ENCR_NONE)
791 encr_type[et_num++] = "none";
792 if (cred->encr_type & WPS_ENCR_WEP)
793 encr_type[et_num++] = "wep";
794 if (cred->encr_type & WPS_ENCR_TKIP)
795 encr_type[et_num++] = "tkip";
796 if (cred->encr_type & WPS_ENCR_AES)
797 encr_type[et_num++] = "aes";
799 if (wpa_s->current_ssid) {
800 if (!wpa_dbus_dict_append_byte_array(
801 &dict_iter, "BSSID",
802 (const char *) wpa_s->current_ssid->bssid,
803 ETH_ALEN)) {
804 perror("wpas_dbus_signal_wps_cred[dbus]: out of "
805 "memory when appending bssid to dictionary");
806 goto nomem;
810 if (!(wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
811 (const char *) cred->ssid,
812 cred->ssid_len) &&
813 wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
814 (const char **) auth_type,
815 at_num) &&
816 wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
817 (const char **) encr_type,
818 et_num) &&
819 wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
820 (const char *) cred->key,
821 cred->key_len) &&
822 wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
823 cred->key_idx))) {
824 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
825 "when appending to dictionary");
826 goto nomem;
829 if (!wpa_dbus_dict_close_write(&iter, &dict_iter)) {
830 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
831 "when closing a dictionary");
832 goto nomem;
835 dbus_connection_send(iface->con, _signal, NULL);
837 nomem:
838 dbus_message_unref(_signal);
841 #endif /* CONFIG_WPS */
845 * wpas_dbus_signal_prop_changed - Signals change of property
846 * @wpa_s: %wpa_supplicant network interface data
847 * @property: indicates which property has changed
849 * Sends ProertyChanged signals with path, interface and arguments
850 * depending on which property has changed.
852 static void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
853 enum wpas_dbus_prop property)
855 WPADBusPropertyAccessor getter;
856 char *iface;
857 char *prop;
858 void *arg;
860 switch (property) {
861 case WPAS_DBUS_PROP_AP_SCAN:
862 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan;
863 arg = wpa_s;
864 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
865 prop = "ApScan";
866 break;
867 case WPAS_DBUS_PROP_SCANNING:
868 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_scanning;
869 arg = wpa_s;
870 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
871 prop = "Scanning";
872 break;
873 case WPAS_DBUS_PROP_CURRENT_BSS:
874 getter = (WPADBusPropertyAccessor)
875 wpas_dbus_getter_current_bss;
876 arg = wpa_s;
877 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
878 prop = "CurrentBSS";
879 break;
880 case WPAS_DBUS_PROP_CURRENT_NETWORK:
881 getter = (WPADBusPropertyAccessor)
882 wpas_dbus_getter_current_network;
883 arg = wpa_s;
884 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
885 prop = "CurrentNetwork";
886 break;
887 default:
888 wpa_printf(MSG_ERROR, "wpas_dbus_signal_prop_changed[dbus]: "
889 "Unknown Property enum value %d", property);
890 return;
893 wpa_dbus_signal_property_changed(wpa_s->global->dbus_new_ctrl_iface,
894 getter, arg,
895 wpas_dbus_get_path(wpa_s), iface,
896 prop);
901 * wpas_dbus_signal_debug_params_changed - Signals change of debug params
902 * @global: wpa_global structure
904 * Sends ProertyChanged signals informing that debug params has changed.
906 static void wpas_dbus_signal_debug_params_changed(struct wpa_global *global)
909 wpa_dbus_signal_property_changed(global->dbus_new_ctrl_iface,
910 (WPADBusPropertyAccessor)
911 wpas_dbus_getter_debug_params,
912 global, WPAS_DBUS_NEW_PATH,
913 WPAS_DBUS_NEW_INTERFACE,
914 "DebugParams");
918 struct wpas_dbus_method {
919 const char *name;
920 const char *iface;
921 WPADBusMethodHandler handler;
922 struct wpa_dbus_argument args[3];
925 struct wpas_dbus_property {
926 const char *name;
927 const char *iface;
928 const char *type;
929 WPADBusPropertyAccessor getter;
930 WPADBusPropertyAccessor setter;
931 enum dbus_prop_access _access;
934 struct wpas_dbus_signal {
935 const char *name;
936 const char *iface;
937 struct wpa_dbus_argument args[3];
941 static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
942 void *priv,
943 const struct wpas_dbus_method *methods,
944 const struct wpas_dbus_property *properties,
945 const struct wpas_dbus_signal *signals)
947 int i;
949 for (i = 0; methods && methods[i].name; i++) {
950 wpa_dbus_method_register(obj_desc, methods[i].iface,
951 methods[i].name, methods[i].handler,
952 priv, NULL, methods[i].args);
955 for (i = 0; properties && properties[i].name; i++) {
956 wpa_dbus_property_register(obj_desc, properties[i].iface,
957 properties[i].name,
958 properties[i].type,
959 properties[i].getter,
960 properties[i].setter,
961 priv, NULL, properties[i]._access);
964 for (i = 0; signals && signals[i].name; i++) {
965 wpa_dbus_signal_register(obj_desc, signals[i].iface,
966 signals[i].name, signals[i].args);
971 static const struct wpas_dbus_method wpas_dbus_global_methods[] = {
972 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
973 (WPADBusMethodHandler) &wpas_dbus_handler_create_interface,
975 { "args", "a{sv}", ARG_IN },
976 { "path", "o", ARG_OUT },
977 END_ARGS
980 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
981 (WPADBusMethodHandler) &wpas_dbus_handler_remove_interface,
983 { "path", "o", ARG_IN },
984 END_ARGS
987 { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
988 (WPADBusMethodHandler) &wpas_dbus_handler_get_interface,
990 { "ifname", "s", ARG_IN },
991 { "path", "o", ARG_OUT },
992 END_ARGS
995 { NULL, NULL, NULL, { END_ARGS } }
998 static const struct wpas_dbus_property wpas_dbus_global_properties[] = {
999 { "DebugParams", WPAS_DBUS_NEW_INTERFACE, "(ibb)",
1000 (WPADBusPropertyAccessor) &wpas_dbus_getter_debug_params,
1001 (WPADBusPropertyAccessor) &wpas_dbus_setter_debug_params,
1004 { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
1005 (WPADBusPropertyAccessor) &wpas_dbus_getter_interfaces,
1006 NULL,
1009 { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
1010 wpas_dbus_getter_eap_methods,
1011 NULL,
1014 { NULL, NULL, NULL, NULL, NULL, 0 }
1017 static const struct wpas_dbus_signal wpas_dbus_global_signals[] = {
1018 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
1020 { "path", "o", ARG_OUT },
1021 END_ARGS
1024 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
1026 { "path", "o", ARG_OUT },
1027 END_ARGS
1030 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
1032 { "properties", "a{sv}", ARG_OUT },
1033 END_ARGS
1036 { NULL, NULL, { END_ARGS } }
1041 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
1042 * @global: Pointer to global data from wpa_supplicant_init()
1043 * Returns: Pointer to dbus_new_ctrl_iface date or %NULL on failure
1045 * Initialize the dbus control interface for wpa_supplicantand and start
1046 * receiving commands from external programs over the bus.
1048 static struct ctrl_iface_dbus_new_priv * wpas_dbus_ctrl_iface_init(
1049 struct wpa_global *global)
1051 struct ctrl_iface_dbus_new_priv *ctrl_iface;
1052 struct wpa_dbus_object_desc *obj_desc;
1054 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1055 if (!obj_desc) {
1056 wpa_printf(MSG_ERROR, "Not enough memory "
1057 "to create object description");
1058 return NULL;
1061 wpas_dbus_register(obj_desc, global, wpas_dbus_global_methods,
1062 wpas_dbus_global_properties,
1063 wpas_dbus_global_signals);
1065 wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
1066 WPAS_DBUS_NEW_PATH);
1067 ctrl_iface = wpa_dbus_ctrl_iface_init(global, WPAS_DBUS_NEW_PATH,
1068 WPAS_DBUS_NEW_SERVICE,
1069 obj_desc);
1070 if (!ctrl_iface)
1071 free_dbus_object_desc(obj_desc);
1073 return ctrl_iface;
1078 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
1079 * wpa_supplicant
1080 * @iface: Pointer to dbus private data from
1081 * wpas_dbus_ctrl_iface_init()
1083 * Deinitialize the dbus control interface that was initialized with
1084 * wpas_dbus_ctrl_iface_init().
1086 static void wpas_dbus_ctrl_iface_deinit(struct ctrl_iface_dbus_new_priv *iface)
1088 if (iface) {
1089 wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
1090 WPAS_DBUS_NEW_PATH);
1091 dbus_connection_unregister_object_path(iface->con,
1092 WPAS_DBUS_NEW_PATH);
1093 wpa_dbus_ctrl_iface_deinit(iface);
1098 static void wpa_dbus_free(void *ptr)
1100 os_free(ptr);
1105 * wpas_dbus_register_network - Register a configured network with dbus
1106 * @wpa_s: wpa_supplicant interface structure
1107 * @ssid: network configuration data
1108 * Returns: 0 on success, -1 on failure
1110 * Registers network representing object with dbus
1112 static int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
1113 struct wpa_ssid *ssid)
1115 struct ctrl_iface_dbus_new_priv *ctrl_iface;
1116 struct wpa_dbus_object_desc *obj_desc;
1118 struct network_handler_args *arg1 = NULL;
1119 struct network_handler_args *arg2 = NULL;
1121 char *net_obj_path;
1123 struct wpa_dbus_argument sargs[] = {
1124 { "properties", "a{sv}", ARG_OUT },
1125 END_ARGS
1128 /* Do nothing if the control interface is not turned on */
1129 if (wpa_s == NULL || wpa_s->global == NULL)
1130 return 0;
1131 ctrl_iface = wpa_s->global->dbus_new_ctrl_iface;
1132 if (ctrl_iface == NULL)
1133 return 0;
1135 net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1136 if (net_obj_path == NULL)
1137 return -1;
1138 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1139 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
1140 wpas_dbus_get_path(wpa_s), ssid->id);
1142 wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
1143 net_obj_path);
1144 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1145 if (!obj_desc) {
1146 wpa_printf(MSG_ERROR, "Not enough memory "
1147 "to create object description");
1148 goto err;
1151 /* allocate memory for handlers arguments */
1152 arg1 = os_zalloc(sizeof(struct network_handler_args));
1153 if (!arg1) {
1154 wpa_printf(MSG_ERROR, "Not enough memory "
1155 "to create arguments for method");
1156 goto err;
1158 arg2 = os_zalloc(sizeof(struct network_handler_args));
1159 if (!arg2) {
1160 wpa_printf(MSG_ERROR, "Not enough memory "
1161 "to create arguments for method");
1162 goto err;
1165 arg1->wpa_s = wpa_s;
1166 arg1->ssid = ssid;
1167 arg2->wpa_s = wpa_s;
1168 arg2->ssid = ssid;
1170 /* Enabled property */
1171 wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_NETWORK,
1172 "Enabled", "b",
1173 (WPADBusPropertyAccessor)
1174 wpas_dbus_getter_enabled,
1175 (WPADBusPropertyAccessor)
1176 wpas_dbus_setter_enabled,
1177 arg1, wpa_dbus_free, RW);
1179 /* Properties property */
1180 wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_NETWORK,
1181 "Properties", "a{sv}",
1182 (WPADBusPropertyAccessor)
1183 wpas_dbus_getter_network_properties,
1184 (WPADBusPropertyAccessor)
1185 wpas_dbus_setter_network_properties,
1186 arg2, wpa_dbus_free, RW);
1188 /* PropertiesChanged signal */
1189 wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_NETWORK,
1190 "PropertiesChanged", sargs);
1192 if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
1193 wpa_s->ifname, obj_desc))
1194 goto err;
1196 wpas_dbus_signal_network_added(wpa_s, ssid->id);
1198 os_free(net_obj_path);
1199 return 0;
1201 err:
1202 os_free(net_obj_path);
1203 os_free(obj_desc);
1204 os_free(arg1);
1205 os_free(arg2);
1206 return -1;
1211 * wpas_dbus_unregister_network - Unregister a configured network from dbus
1212 * @wpa_s: wpa_supplicant interface structure
1213 * @nid: network id
1214 * Returns: 0 on success, -1 on failure
1216 * Unregisters network representing object from dbus
1218 static int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
1220 struct ctrl_iface_dbus_new_priv *ctrl_iface;
1221 char *net_obj_path;
1222 int ret;
1224 /* Do nothing if the control interface is not turned on */
1225 if (wpa_s == NULL || wpa_s->global == NULL)
1226 return 0;
1227 ctrl_iface = wpa_s->global->dbus_new_ctrl_iface;
1228 if (ctrl_iface == NULL)
1229 return 0;
1231 net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1232 if (net_obj_path == NULL)
1233 return -1;
1234 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1235 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
1236 wpas_dbus_get_path(wpa_s), nid);
1238 wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
1239 net_obj_path);
1240 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
1242 if (!ret)
1243 wpas_dbus_signal_network_removed(wpa_s, nid);
1245 os_free(net_obj_path);
1246 return ret;
1251 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
1252 * @wpa_s: wpa_supplicant interface structure
1253 * @bssid: scanned network bssid
1254 * @id: unique BSS identifier
1255 * Returns: 0 on success, -1 on failure
1257 * Unregisters BSS representing object from dbus
1259 static int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
1260 u8 bssid[ETH_ALEN], unsigned int id)
1262 struct ctrl_iface_dbus_new_priv *ctrl_iface;
1263 char *bss_obj_path;
1265 /* Do nothing if the control interface is not turned on */
1266 if (wpa_s == NULL || wpa_s->global == NULL)
1267 return 0;
1268 ctrl_iface = wpa_s->global->dbus_new_ctrl_iface;
1269 if (ctrl_iface == NULL)
1270 return 0;
1272 bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1273 if (bss_obj_path == NULL)
1274 return -1;
1276 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1277 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
1278 wpas_dbus_get_path(wpa_s), id);
1280 wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
1281 bss_obj_path);
1282 if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
1283 wpa_printf(MSG_ERROR,
1284 "Cannot unregister BSSID dbus object %s.",
1285 bss_obj_path);
1286 os_free(bss_obj_path);
1287 return -1;
1290 wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
1292 os_free(bss_obj_path);
1293 return 0;
1298 * wpas_dbus_register_bss - Register a scanned BSS with dbus
1299 * @wpa_s: wpa_supplicant interface structure
1300 * @bssid: scanned network bssid
1301 * @id: unique BSS identifier
1302 * Returns: 0 on success, -1 on failure
1304 * Registers BSS representing object with dbus
1306 static int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
1307 u8 bssid[ETH_ALEN], unsigned int id)
1309 struct ctrl_iface_dbus_new_priv *ctrl_iface;
1310 struct wpa_dbus_object_desc *obj_desc;
1311 char *bss_obj_path;
1313 struct bss_handler_args *arg = NULL;
1315 /* Do nothing if the control interface is not turned on */
1316 if (wpa_s == NULL || wpa_s->global == NULL)
1317 return 0;
1318 ctrl_iface = wpa_s->global->dbus_new_ctrl_iface;
1319 if (ctrl_iface == NULL)
1320 return 0;
1322 bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1323 if (bss_obj_path == NULL)
1324 return -1;
1326 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1327 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
1328 wpas_dbus_get_path(wpa_s), id);
1330 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1331 if (!obj_desc) {
1332 wpa_printf(MSG_ERROR, "Not enough memory "
1333 "to create object description");
1334 goto err;
1337 arg = os_zalloc(sizeof(struct bss_handler_args));
1338 if (!arg) {
1339 wpa_printf(MSG_ERROR, "Not enough memory "
1340 "to create arguments for handler");
1341 goto err;
1343 arg->wpa_s = wpa_s;
1344 arg->id = id;
1346 /* Properties property */
1347 wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_BSSID,
1348 "Properties", "a{sv}",
1349 (WPADBusPropertyAccessor)
1350 wpas_dbus_getter_bss_properties, NULL,
1351 arg, wpa_dbus_free, R);
1353 wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
1354 bss_obj_path);
1355 if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
1356 wpa_s->ifname, obj_desc)) {
1357 wpa_printf(MSG_ERROR,
1358 "Cannot register BSSID dbus object %s.",
1359 bss_obj_path);
1360 goto err;
1363 wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
1365 os_free(bss_obj_path);
1366 return 0;
1368 err:
1369 os_free(bss_obj_path);
1370 os_free(obj_desc);
1371 os_free(arg);
1372 return -1;
1376 static const struct wpas_dbus_method wpas_dbus_interface_methods[] = {
1377 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
1378 (WPADBusMethodHandler) &wpas_dbus_handler_scan,
1380 { "args", "a{sv}", ARG_IN },
1381 END_ARGS
1384 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
1385 (WPADBusMethodHandler) &wpas_dbus_handler_disconnect,
1387 END_ARGS
1390 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1391 (WPADBusMethodHandler) &wpas_dbus_handler_add_network,
1393 { "args", "a{sv}", ARG_IN },
1394 { "path", "o", ARG_OUT },
1395 END_ARGS
1398 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1399 (WPADBusMethodHandler) &wpas_dbus_handler_remove_network,
1401 { "path", "o", ARG_IN },
1402 END_ARGS
1405 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1406 (WPADBusMethodHandler) &wpas_dbus_handler_select_network,
1408 { "path", "o", ARG_IN },
1409 END_ARGS
1412 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1413 (WPADBusMethodHandler) &wpas_dbus_handler_add_blob,
1415 { "name", "s", ARG_IN },
1416 { "data", "ay", ARG_IN },
1417 END_ARGS
1420 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1421 (WPADBusMethodHandler) &wpas_dbus_handler_get_blob,
1423 { "name", "s", ARG_IN },
1424 { "data", "ay", ARG_OUT },
1425 END_ARGS
1428 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1429 (WPADBusMethodHandler) &wpas_dbus_handler_remove_blob,
1431 { "name", "s", ARG_IN },
1432 END_ARGS
1435 #ifdef CONFIG_WPS
1436 { "Start", WPAS_DBUS_NEW_IFACE_WPS,
1437 (WPADBusMethodHandler) &wpas_dbus_handler_wps_start,
1439 { "args", "a{sv}", ARG_IN },
1440 { "output", "a{sv}", ARG_OUT },
1441 END_ARGS
1444 #endif /* CONFIG_WPS */
1445 { NULL, NULL, NULL, { END_ARGS } }
1448 static const struct wpas_dbus_property wpas_dbus_interface_properties[] = {
1449 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
1450 (WPADBusPropertyAccessor) wpas_dbus_getter_capabilities,
1451 NULL, R
1453 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1454 (WPADBusPropertyAccessor) wpas_dbus_getter_state,
1455 NULL, R
1457 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
1458 (WPADBusPropertyAccessor) wpas_dbus_getter_scanning,
1459 NULL, R
1461 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
1462 (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan,
1463 (WPADBusPropertyAccessor) wpas_dbus_setter_ap_scan,
1466 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1467 (WPADBusPropertyAccessor) wpas_dbus_getter_ifname,
1468 NULL, R
1470 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1471 (WPADBusPropertyAccessor) wpas_dbus_getter_driver,
1472 NULL, R
1474 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1475 (WPADBusPropertyAccessor) wpas_dbus_getter_bridge_ifname,
1476 NULL, R
1478 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
1479 (WPADBusPropertyAccessor) wpas_dbus_getter_current_bss,
1480 NULL, R
1482 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
1483 (WPADBusPropertyAccessor) wpas_dbus_getter_current_network,
1484 NULL, R
1486 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
1487 (WPADBusPropertyAccessor) wpas_dbus_getter_blobs,
1488 NULL, R
1490 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
1491 (WPADBusPropertyAccessor) wpas_dbus_getter_bsss,
1492 NULL, R
1494 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
1495 (WPADBusPropertyAccessor) wpas_dbus_getter_networks,
1496 NULL, R
1498 #ifdef CONFIG_WPS
1499 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
1500 (WPADBusPropertyAccessor) wpas_dbus_getter_process_credentials,
1501 (WPADBusPropertyAccessor) wpas_dbus_setter_process_credentials,
1504 #endif /* CONFIG_WPS */
1505 { NULL, NULL, NULL, NULL, NULL, 0 }
1508 static const struct wpas_dbus_signal wpas_dbus_interface_signals[] = {
1509 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
1511 { "success", "b", ARG_OUT },
1512 END_ARGS
1515 { "StateChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
1517 { "newState", "s", ARG_OUT },
1518 { "oldState", "s", ARG_OUT },
1519 END_ARGS
1522 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1524 { "path", "o", ARG_OUT },
1525 END_ARGS
1528 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1530 { "path", "o", ARG_OUT },
1531 END_ARGS
1534 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1536 { "name", "s", ARG_OUT },
1537 END_ARGS
1540 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1542 { "name", "s", ARG_OUT },
1543 END_ARGS
1546 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1548 { "path", "o", ARG_OUT },
1549 END_ARGS
1552 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1554 { "path", "o", ARG_OUT },
1555 END_ARGS
1558 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
1560 { "path", "o", ARG_OUT },
1561 END_ARGS
1564 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
1566 { "properties", "a{sv}", ARG_OUT },
1567 END_ARGS
1570 #ifdef CONFIG_WPS
1571 { "Event", WPAS_DBUS_NEW_IFACE_WPS,
1573 { "name", "s", ARG_OUT },
1574 { "args", "a{sv}", ARG_OUT },
1575 END_ARGS
1578 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
1580 { "credentials", "a{sv}", ARG_OUT },
1581 END_ARGS
1584 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
1586 { "properties", "a{sv}", ARG_OUT },
1587 END_ARGS
1590 #endif /* CONFIG_WPS */
1591 { NULL, NULL, { END_ARGS } }
1595 static int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
1598 struct wpa_dbus_object_desc *obj_desc = NULL;
1599 char *path;
1600 struct ctrl_iface_dbus_new_priv *ctrl_iface =
1601 wpa_s->global->dbus_new_ctrl_iface;
1602 int next;
1604 /* Do nothing if the control interface is not turned on */
1605 if (ctrl_iface == NULL)
1606 return 0;
1608 /* Create and set the interface's object path */
1609 path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1610 if (path == NULL)
1611 return -1;
1612 next = wpa_dbus_next_objid(ctrl_iface);
1613 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
1614 WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
1615 next);
1616 if (wpas_dbus_set_path(wpa_s, path)) {
1617 wpa_printf(MSG_DEBUG,
1618 "Failed to set dbus path for interface %s",
1619 wpa_s->ifname);
1620 goto err;
1623 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1624 if (!obj_desc) {
1625 wpa_printf(MSG_ERROR, "Not enough memory "
1626 "to create object description");
1627 goto err;
1630 wpas_dbus_register(obj_desc, wpa_s, wpas_dbus_interface_methods,
1631 wpas_dbus_interface_properties,
1632 wpas_dbus_interface_signals);
1634 wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'", path);
1635 if (wpa_dbus_register_object_per_iface(ctrl_iface, path, wpa_s->ifname,
1636 obj_desc))
1637 goto err;
1639 wpas_dbus_signal_interface_created(wpa_s);
1641 os_free(path);
1642 return 0;
1644 err:
1645 os_free(obj_desc);
1646 os_free(path);
1647 return -1;
1651 static int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
1653 struct ctrl_iface_dbus_new_priv *ctrl_iface;
1655 /* Do nothing if the control interface is not turned on */
1656 if (wpa_s == NULL || wpa_s->global == NULL)
1657 return 0;
1658 ctrl_iface = wpa_s->global->dbus_new_ctrl_iface;
1659 if (ctrl_iface == NULL)
1660 return 0;
1662 wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
1663 wpas_dbus_get_path(wpa_s));
1664 if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
1665 wpas_dbus_get_path(wpa_s)))
1666 return -1;
1668 wpas_dbus_signal_interface_removed(wpa_s);
1670 os_free(wpa_s->dbus_new_path);
1671 wpa_s->dbus_new_path = NULL;
1673 return 0;
1677 static struct wpas_dbus_callbacks callbacks =
1679 .dbus_ctrl_init = wpas_dbus_ctrl_iface_init,
1680 .dbus_ctrl_deinit = wpas_dbus_ctrl_iface_deinit,
1682 .signal_interface_created = wpas_dbus_signal_interface_created,
1683 .signal_interface_removed = wpas_dbus_signal_interface_removed,
1685 .register_interface = wpas_dbus_register_interface,
1686 .unregister_interface = wpas_dbus_unregister_interface,
1688 .signal_scan_done = wpas_dbus_signal_scan_done,
1690 .signal_blob_added = wpas_dbus_signal_blob_added,
1691 .signal_blob_removed = wpas_dbus_signal_blob_removed,
1693 .signal_network_selected = wpas_dbus_signal_network_selected,
1695 .signal_state_changed = wpas_dbus_signal_state_changed,
1696 .register_network = wpas_dbus_register_network,
1697 .unregister_network = wpas_dbus_unregister_network,
1699 .signal_network_enabled_changed =
1700 wpas_dbus_signal_network_enabled_changed,
1702 .register_bss = wpas_dbus_register_bss,
1703 .unregister_bss = wpas_dbus_unregister_bss,
1705 .signal_prop_changed = wpas_dbus_signal_prop_changed,
1706 .signal_debug_params_changed = wpas_dbus_signal_debug_params_changed,
1708 #ifdef CONFIG_WPS
1709 .signal_wps_event_success = wpas_dbus_signal_wps_event_success,
1710 .signal_wps_event_fail = wpas_dbus_signal_wps_event_fail,
1711 .signal_wps_event_m2d = wpas_dbus_signal_wps_event_m2d,
1712 .signal_wps_credentials = wpas_dbus_signal_wps_cred,
1713 #endif /* CONFIG_WPS */
1717 struct wpas_dbus_callbacks * wpas_dbus_get_callbacks(void)
1719 return &callbacks;
1724 * wpas_dbus_get_path - Get an interface's dbus path
1725 * @wpa_s: %wpa_supplicant interface structure
1726 * Returns: Interface's dbus object path, or %NULL on error
1728 const char * wpas_dbus_get_path(struct wpa_supplicant *wpa_s)
1730 return wpa_s->dbus_new_path;