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
14 * See README and COPYING for more details.
21 #include "../config.h"
22 #include "../wpa_supplicant_i.h"
24 #include "dbus_new_helpers.h"
25 #include "dbus_dict_helpers.h"
27 #include "dbus_new_handlers.h"
28 #include "dbus_common.h"
29 #include "dbus_common_i.h"
32 * wpas_dbus_set_path - Assign a dbus path to an interface
33 * @wpa_s: wpa_supplicant interface structure
34 * @path: dbus path to set on the interface
35 * Returns: 0 on success, -1 on error
37 static int wpas_dbus_set_path(struct wpa_supplicant *wpa_s,
40 u32 len = os_strlen(path);
41 if (len >= WPAS_DBUS_OBJECT_PATH_MAX)
43 if (wpa_s->dbus_new_path)
45 wpa_s->dbus_new_path = os_strdup(path);
51 * wpas_dbus_signal_interface - Send a interface related event signal
52 * @wpa_s: %wpa_supplicant network interface data
53 * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
55 * Notify listeners about event related with interface
57 static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
60 struct wpas_dbus_priv *iface;
64 iface = wpa_s->global->dbus;
66 /* Do nothing if the control interface is not turned on */
70 path = wpas_dbus_get_path(wpa_s);
72 wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
73 "Interface doesn't have a dbus path. "
74 "Can't send signal.");
77 _signal = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
78 WPAS_DBUS_NEW_INTERFACE, sig_name);
79 if (_signal == NULL) {
80 wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
81 "enough memory to send scan results signal.");
85 if (dbus_message_append_args(_signal, DBUS_TYPE_OBJECT_PATH, &path,
87 dbus_connection_send(iface->con, _signal, NULL);
89 wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
90 "not enough memory to construct signal.");
92 dbus_message_unref(_signal);
97 * wpas_dbus_signal_interface_created - Send a interface created signal
98 * @wpa_s: %wpa_supplicant network interface data
100 * Notify listeners about creating new interface
102 static void wpas_dbus_signal_interface_created(struct wpa_supplicant *wpa_s)
104 wpas_dbus_signal_interface(wpa_s, "InterfaceCreated");
109 * wpas_dbus_signal_interface_removed - Send a interface removed signal
110 * @wpa_s: %wpa_supplicant network interface data
112 * Notify listeners about removing interface
114 static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
116 wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved");
122 * wpas_dbus_signal_scan_done - send scan done signal
123 * @wpa_s: %wpa_supplicant network interface data
124 * @success: indicates if scanning succeed or failed
126 * Notify listeners about finishing a scan
128 static void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s,
131 struct wpas_dbus_priv *iface;
132 DBusMessage *_signal;
136 iface = wpa_s->global->dbus;
138 /* Do nothing if the control interface is not turned on */
142 path = wpas_dbus_get_path(wpa_s);
144 wpa_printf(MSG_ERROR, "wpas_dbus_signal_scan_done[dbus]: "
145 "Interface doesn't have a dbus path. "
146 "Can't send signal.");
149 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
151 if (_signal == NULL) {
152 wpa_printf(MSG_ERROR, "wpas_dbus_signal_scan_done[dbus]: "
153 "enough memory to send signal.");
157 succ = success ? TRUE : FALSE;
158 if (dbus_message_append_args(_signal, DBUS_TYPE_BOOLEAN, &succ,
159 DBUS_TYPE_INVALID)) {
160 dbus_connection_send(iface->con, _signal, NULL);
162 wpa_printf(MSG_ERROR, "wpas_dbus_signal_scan_done[dbus]: "
163 "not enough memory to construct signal.");
165 dbus_message_unref(_signal);
170 * wpas_dbus_signal_blob - Send a BSS related event signal
171 * @wpa_s: %wpa_supplicant network interface data
172 * @bss_obj_path: BSS object path
173 * @sig_name: signal name - BSSAdded or BSSRemoved
175 * Notify listeners about event related with BSS
177 static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
178 const char *bss_obj_path,
179 const char *sig_name)
181 struct wpas_dbus_priv *iface;
182 DBusMessage *_signal;
185 iface = wpa_s->global->dbus;
187 /* Do nothing if the control interface is not turned on */
191 path = wpas_dbus_get_path(wpa_s);
193 wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
194 "Interface doesn't have a dbus path. "
195 "Can't send signal.");
198 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
200 if (_signal == NULL) {
201 wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
202 "enough memory to send signal.");
206 if (dbus_message_append_args(_signal, DBUS_TYPE_OBJECT_PATH,
207 &bss_obj_path, DBUS_TYPE_INVALID)) {
208 dbus_connection_send(iface->con, _signal, NULL);
210 wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
211 "not enough memory to construct signal.");
213 dbus_message_unref(_signal);
218 * wpas_dbus_signal_bss_added - Send a BSS added signal
219 * @wpa_s: %wpa_supplicant network interface data
220 * @bss_obj_path: new BSS object path
222 * Notify listeners about adding new BSS
224 static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
225 const char *bss_obj_path)
227 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded");
232 * wpas_dbus_signal_bss_removed - Send a BSS removed signal
233 * @wpa_s: %wpa_supplicant network interface data
234 * @bss_obj_path: BSS object path
236 * Notify listeners about removing BSS
238 static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
239 const char *bss_obj_path)
241 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved");
246 * wpas_dbus_signal_blob - Send a blob related event signal
247 * @wpa_s: %wpa_supplicant network interface data
249 * @sig_name: signal name - BlobAdded or BlobRemoved
251 * Notify listeners about event related with blob
253 static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
254 const char *name, const char *sig_name)
256 struct wpas_dbus_priv *iface;
257 DBusMessage *_signal;
260 iface = wpa_s->global->dbus;
262 /* Do nothing if the control interface is not turned on */
266 path = wpas_dbus_get_path(wpa_s);
268 wpa_printf(MSG_ERROR, "wpas_dbus_signal_blob[dbus]: "
269 "Interface doesn't have a dbus path. "
270 "Can't send signal.");
273 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
275 if (_signal == NULL) {
276 wpa_printf(MSG_ERROR, "wpas_dbus_signal_blob[dbus]: "
277 "enough memory to send signal.");
281 if (dbus_message_append_args(_signal, DBUS_TYPE_STRING, &name,
282 DBUS_TYPE_INVALID)) {
283 dbus_connection_send(iface->con, _signal, NULL);
285 wpa_printf(MSG_ERROR, "wpas_dbus_signal_blob[dbus]: "
286 "not enough memory to construct signal.");
288 dbus_message_unref(_signal);
293 * wpas_dbus_signal_blob_added - Send a blob added signal
294 * @wpa_s: %wpa_supplicant network interface data
297 * Notify listeners about adding a new blob
299 static void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
302 wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
307 * wpas_dbus_signal_blob_removed - Send a blob removed signal
308 * @wpa_s: %wpa_supplicant network interface data
311 * Notify listeners about removing blob
313 static void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
316 wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
321 * wpas_dbus_signal_network - Send a network related event signal
322 * @wpa_s: %wpa_supplicant network interface data
323 * @id: new network id
324 * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
326 * Notify listeners about event related with configured network
328 static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
329 int id, const char *sig_name)
331 struct wpas_dbus_priv *iface;
332 DBusMessage *_signal;
336 iface = wpa_s->global->dbus;
338 /* Do nothing if the control interface is not turned on */
342 path = wpas_dbus_get_path(wpa_s);
344 wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
345 "Interface doesn't have a dbus path. "
346 "Can't send signal.");
350 net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
351 if (net_obj_path == NULL)
353 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
354 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", path, id);
356 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
358 if (_signal == NULL) {
359 wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
360 "enough memory to send signal.");
361 os_free(net_obj_path);
365 if (dbus_message_append_args(_signal, DBUS_TYPE_OBJECT_PATH,
366 &net_obj_path, DBUS_TYPE_INVALID)) {
367 dbus_connection_send(iface->con, _signal, NULL);
369 wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
370 "not enough memory to construct signal.");
373 os_free(net_obj_path);
374 dbus_message_unref(_signal);
379 * wpas_dbus_signal_network_added - Send a network added signal
380 * @wpa_s: %wpa_supplicant network interface data
381 * @id: new network id
383 * Notify listeners about adding new network
385 static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
388 wpas_dbus_signal_network(wpa_s, id, "NetworkAdded");
393 * wpas_dbus_signal_network_removed - Send a network removed signal
394 * @wpa_s: %wpa_supplicant network interface data
397 * Notify listeners about removing a network
399 static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
402 wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved");
407 * wpas_dbus_signal_network_selected - Send a network selected signal
408 * @wpa_s: %wpa_supplicant network interface data
411 * Notify listeners about selecting a network
413 static void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s,
416 wpas_dbus_signal_network(wpa_s, id, "NetworkSelected");
421 * wpas_dbus_signal_state_changed - Send a state changed signal
422 * @wpa_s: %wpa_supplicant network interface data
423 * @new_state: new state wpa_supplicant is entering
424 * @old_state: old state wpa_supplicant is leaving
426 * Notify listeners that wpa_supplicant has changed state
428 static void wpas_dbus_signal_state_changed(struct wpa_supplicant *wpa_s,
429 enum wpa_states new_state,
430 enum wpa_states old_state)
432 struct wpas_dbus_priv *iface;
433 DBusMessage *_signal = NULL;
435 char *new_state_str, *old_state_str;
438 /* Do nothing if the control interface is not turned on */
439 if (wpa_s->global == NULL)
441 iface = wpa_s->global->dbus;
445 /* Only send signal if state really changed */
446 if (new_state == old_state)
449 path = wpas_dbus_get_path(wpa_s);
451 perror("wpas_dbus_signal_state_changed[dbus]: "
452 "interface didn't have a dbus path");
453 wpa_printf(MSG_ERROR,
454 "wpas_dbus_signal_state_changed[dbus]: "
455 "interface didn't have a dbus path; can't send "
459 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
461 if (_signal == NULL) {
462 perror("wpas_dbus_signal_state_changed[dbus]: "
463 "couldn't create dbus signal; likely out of memory");
464 wpa_printf(MSG_ERROR,
465 "wpas_dbus_signal_state_changed[dbus]: "
466 "couldn't create dbus signal; likely out of "
471 new_state_str = os_strdup(wpa_supplicant_state_txt(new_state));
472 old_state_str = os_strdup(wpa_supplicant_state_txt(old_state));
473 if (new_state_str == NULL || old_state_str == NULL) {
474 perror("wpas_dbus_signal_state_changed[dbus]: "
475 "couldn't convert state strings");
476 wpa_printf(MSG_ERROR,
477 "wpas_dbus_signal_state_changed[dbus]: "
478 "couldn't convert state strings.");
482 /* make state string lowercase to fit new DBus API convention */
485 *tmp = tolower(*tmp);
490 *tmp = tolower(*tmp);
494 if (!dbus_message_append_args(_signal,
495 DBUS_TYPE_STRING, &new_state_str,
496 DBUS_TYPE_STRING, &old_state_str,
497 DBUS_TYPE_INVALID)) {
498 perror("wpas_dbus_signal_state_changed[dbus]: "
499 "not enough memory to construct state change signal.");
500 wpa_printf(MSG_ERROR,
501 "wpas_dbus_signal_state_changed[dbus]: "
502 "not enough memory to construct state change "
507 dbus_connection_send(iface->con, _signal, NULL);
510 dbus_message_unref(_signal);
511 os_free(new_state_str);
512 os_free(old_state_str);
517 * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
518 * @wpa_s: %wpa_supplicant network interface data
519 * @ssid: configured network which Enabled property has changed
521 * Sends PropertyChanged signals containing new value of Enabled property
522 * for specified network
524 static void wpas_dbus_signal_network_enabled_changed(
525 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
528 struct network_handler_args args = {wpa_s, ssid};
530 char path[WPAS_DBUS_OBJECT_PATH_MAX];
531 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
532 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
533 wpas_dbus_get_path(wpa_s), ssid->id);
535 wpa_dbus_signal_property_changed(wpa_s->global->dbus,
536 (WPADBusPropertyAccessor)
537 wpas_dbus_getter_enabled, &args,
538 path, WPAS_DBUS_NEW_IFACE_NETWORK,
546 * wpas_dbus_signal_wps_event_success - Signals Success WPS event
547 * @wpa_s: %wpa_supplicant network interface data
549 * Sends Event dbus signal with name "success" and empty dict as arguments
551 static void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
554 DBusMessage *_signal = NULL;
555 DBusMessageIter iter, dict_iter;
556 struct wpas_dbus_priv *iface;
557 char *key = "success";
560 iface = wpa_s->global->dbus;
562 /* Do nothing if the control interface is not turned on */
566 path = wpas_dbus_get_path(wpa_s);
568 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_success"
569 "[dbus]: interface has no dbus path set");
573 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
576 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_success"
577 "[dbus]: out of memory when creating a signal");
581 dbus_message_iter_init_append(_signal, &iter);
583 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
584 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
585 !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
586 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_success"
587 "[dbus]: out of memory");
591 dbus_connection_send(iface->con, _signal, NULL);
593 dbus_message_unref(_signal);
598 * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
599 * @wpa_s: %wpa_supplicant network interface data
601 * Sends Event dbus signal with name "fail" and dictionary containing
602 * "msg field with fail message number (int32) as arguments
604 static void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
605 struct wps_event_fail *fail)
608 DBusMessage *_signal = NULL;
609 DBusMessageIter iter, dict_iter;
610 struct wpas_dbus_priv *iface;
614 iface = wpa_s->global->dbus;
616 /* Do nothing if the control interface is not turned on */
620 path = wpas_dbus_get_path(wpa_s);
622 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_fail[dbus]: "
623 "interface has no dbus path set");
627 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
630 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_fail[dbus]: "
631 "out of memory when creating a signal");
635 dbus_message_iter_init_append(_signal, &iter);
637 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
638 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
639 !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
640 !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
641 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_fail[dbus]: "
646 dbus_connection_send(iface->con, _signal, NULL);
648 dbus_message_unref(_signal);
653 * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
654 * @wpa_s: %wpa_supplicant network interface data
656 * Sends Event dbus signal with name "m2d" and dictionary containing
657 * fields of wps_event_m2d structure.
659 static void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
660 struct wps_event_m2d *m2d)
663 DBusMessage *_signal = NULL;
664 DBusMessageIter iter, dict_iter;
665 struct wpas_dbus_priv *iface;
669 iface = wpa_s->global->dbus;
671 /* Do nothing if the control interface is not turned on */
675 path = wpas_dbus_get_path(wpa_s);
677 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_m2d[dbus]: "
678 "interface has no dbus path set");
682 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
685 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_m2d[dbus]: "
686 "out of memory when creating a signal");
690 dbus_message_iter_init_append(_signal, &iter);
692 if (!(dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) &&
693 wpa_dbus_dict_open_write(&iter, &dict_iter) &&
694 wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
695 m2d->config_methods) &&
696 wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
697 (const char *) m2d->manufacturer,
698 m2d->manufacturer_len) &&
699 wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
700 (const char *) m2d->model_name,
701 m2d->model_name_len) &&
702 wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
703 (const char *) m2d->model_number,
704 m2d->model_number_len) &&
705 wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
708 m2d->serial_number_len) &&
709 wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
710 (const char *) m2d->dev_name,
711 m2d->dev_name_len) &&
712 wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
714 m2d->primary_dev_type, 8) &&
715 wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
716 m2d->config_error) &&
717 wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
718 m2d->dev_password_id) &&
719 wpa_dbus_dict_close_write(&iter, &dict_iter))) {
720 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_m2d[dbus]: "
725 dbus_connection_send(iface->con, _signal, NULL);
727 dbus_message_unref(_signal);
732 * wpas_dbus_signal_wps_cred - Signals new credentials
733 * @wpa_s: %wpa_supplicant network interface data
735 * Sends signal with credentials in directory argument
737 static void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
738 const struct wps_credential *cred)
740 DBusMessage *_signal = NULL;
741 DBusMessageIter iter, dict_iter;
742 struct wpas_dbus_priv *iface;
744 char *auth_type[6]; /* we have six possible authorization types */
746 char *encr_type[4]; /* we have four possible encryption types */
749 iface = wpa_s->global->dbus;
751 /* Do nothing if the control interface is not turned on */
755 path = wpas_dbus_get_path(wpa_s);
757 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_cred[dbus]: "
758 "interface has no dbus path set");
762 _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
765 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_cred[dbus]: "
766 "out of memory when creating a signal");
770 dbus_message_iter_init_append(_signal, &iter);
772 if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) {
773 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
774 "when opening a dictionary");
778 if (cred->auth_type & WPS_AUTH_OPEN)
779 auth_type[at_num++] = "open";
780 if (cred->auth_type & WPS_AUTH_WPAPSK)
781 auth_type[at_num++] = "wpa-psk";
782 if (cred->auth_type & WPS_AUTH_SHARED)
783 auth_type[at_num++] = "shared";
784 if (cred->auth_type & WPS_AUTH_WPA)
785 auth_type[at_num++] = "wpa-eap";
786 if (cred->auth_type & WPS_AUTH_WPA2)
787 auth_type[at_num++] = "wpa2-eap";
788 if (cred->auth_type & WPS_AUTH_WPA2PSK)
789 auth_type[at_num++] =
792 if (cred->encr_type & WPS_ENCR_NONE)
793 encr_type[et_num++] = "none";
794 if (cred->encr_type & WPS_ENCR_WEP)
795 encr_type[et_num++] = "wep";
796 if (cred->encr_type & WPS_ENCR_TKIP)
797 encr_type[et_num++] = "tkip";
798 if (cred->encr_type & WPS_ENCR_AES)
799 encr_type[et_num++] = "aes";
801 if (wpa_s->current_ssid) {
802 if (!wpa_dbus_dict_append_byte_array(
804 (const char *) wpa_s->current_ssid->bssid,
806 perror("wpas_dbus_signal_wps_cred[dbus]: out of "
807 "memory when appending bssid to dictionary");
812 if (!(wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
813 (const char *) cred->ssid,
815 wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
816 (const char **) auth_type,
818 wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
819 (const char **) encr_type,
821 wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
822 (const char *) cred->key,
824 wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
826 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
827 "when appending to dictionary");
831 if (!wpa_dbus_dict_close_write(&iter, &dict_iter)) {
832 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
833 "when closing a dictionary");
837 dbus_connection_send(iface->con, _signal, NULL);
840 dbus_message_unref(_signal);
843 #endif /* CONFIG_WPS */
847 * wpas_dbus_signal_prop_changed - Signals change of property
848 * @wpa_s: %wpa_supplicant network interface data
849 * @property: indicates which property has changed
851 * Sends ProertyChanged signals with path, interface and arguments
852 * depending on which property has changed.
854 static void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
855 enum wpas_dbus_prop property)
857 WPADBusPropertyAccessor getter;
863 case WPAS_DBUS_PROP_AP_SCAN:
864 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan;
866 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
869 case WPAS_DBUS_PROP_SCANNING:
870 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_scanning;
872 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
875 case WPAS_DBUS_PROP_CURRENT_BSS:
876 getter = (WPADBusPropertyAccessor)
877 wpas_dbus_getter_current_bss;
879 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
882 case WPAS_DBUS_PROP_CURRENT_NETWORK:
883 getter = (WPADBusPropertyAccessor)
884 wpas_dbus_getter_current_network;
886 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
887 prop = "CurrentNetwork";
890 wpa_printf(MSG_ERROR, "wpas_dbus_signal_prop_changed[dbus]: "
891 "Unknown Property enum value %d", property);
895 wpa_dbus_signal_property_changed(wpa_s->global->dbus,
897 wpas_dbus_get_path(wpa_s), iface,
903 * wpas_dbus_signal_debug_params_changed - Signals change of debug params
904 * @global: wpa_global structure
906 * Sends ProertyChanged signals informing that debug params has changed.
908 static void wpas_dbus_signal_debug_params_changed(struct wpa_global *global)
911 wpa_dbus_signal_property_changed(global->dbus,
912 (WPADBusPropertyAccessor)
913 wpas_dbus_getter_debug_params,
914 global, WPAS_DBUS_NEW_PATH,
915 WPAS_DBUS_NEW_INTERFACE,
920 struct wpas_dbus_method {
923 WPADBusMethodHandler handler;
924 struct wpa_dbus_argument args[3];
927 struct wpas_dbus_property {
931 WPADBusPropertyAccessor getter;
932 WPADBusPropertyAccessor setter;
933 enum dbus_prop_access _access;
936 struct wpas_dbus_signal {
939 struct wpa_dbus_argument args[3];
943 static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
945 WPADBusArgumentFreeFunction priv_free,
946 const struct wpas_dbus_method *methods,
947 const struct wpas_dbus_property *properties,
948 const struct wpas_dbus_signal *signals)
952 obj_desc->user_data = priv;
953 obj_desc->user_data_free_func = priv_free;
955 for (i = 0; methods && methods[i].name; i++) {
956 wpa_dbus_method_register(obj_desc, methods[i].iface,
957 methods[i].name, methods[i].handler,
961 for (i = 0; properties && properties[i].name; i++) {
962 wpa_dbus_property_register(obj_desc, properties[i].iface,
965 properties[i].getter,
966 properties[i].setter,
967 properties[i]._access);
970 for (i = 0; signals && signals[i].name; i++) {
971 wpa_dbus_signal_register(obj_desc, signals[i].iface,
972 signals[i].name, signals[i].args);
977 static const struct wpas_dbus_method wpas_dbus_global_methods[] = {
978 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
979 (WPADBusMethodHandler) &wpas_dbus_handler_create_interface,
981 { "args", "a{sv}", ARG_IN },
982 { "path", "o", ARG_OUT },
986 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
987 (WPADBusMethodHandler) &wpas_dbus_handler_remove_interface,
989 { "path", "o", ARG_IN },
993 { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
994 (WPADBusMethodHandler) &wpas_dbus_handler_get_interface,
996 { "ifname", "s", ARG_IN },
997 { "path", "o", ARG_OUT },
1001 { NULL, NULL, NULL, { END_ARGS } }
1004 static const struct wpas_dbus_property wpas_dbus_global_properties[] = {
1005 { "DebugParams", WPAS_DBUS_NEW_INTERFACE, "(ibb)",
1006 (WPADBusPropertyAccessor) &wpas_dbus_getter_debug_params,
1007 (WPADBusPropertyAccessor) &wpas_dbus_setter_debug_params,
1010 { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
1011 (WPADBusPropertyAccessor) &wpas_dbus_getter_interfaces,
1015 { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
1016 wpas_dbus_getter_eap_methods,
1020 { NULL, NULL, NULL, NULL, NULL, 0 }
1023 static const struct wpas_dbus_signal wpas_dbus_global_signals[] = {
1024 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
1026 { "path", "o", ARG_OUT },
1030 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
1032 { "path", "o", ARG_OUT },
1036 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
1038 { "properties", "a{sv}", ARG_OUT },
1042 { NULL, NULL, { END_ARGS } }
1047 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
1048 * @global: Pointer to global data from wpa_supplicant_init()
1049 * Returns: 0 on success or -1 on failure
1051 * Initialize the dbus control interface for wpa_supplicantand and start
1052 * receiving commands from external programs over the bus.
1054 int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
1056 struct wpa_dbus_object_desc *obj_desc;
1059 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1061 wpa_printf(MSG_ERROR, "Not enough memory "
1062 "to create object description");
1066 wpas_dbus_register(obj_desc, priv->global, NULL,
1067 wpas_dbus_global_methods,
1068 wpas_dbus_global_properties,
1069 wpas_dbus_global_signals);
1071 wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
1072 WPAS_DBUS_NEW_PATH);
1073 ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
1074 WPAS_DBUS_NEW_SERVICE,
1077 free_dbus_object_desc(obj_desc);
1079 priv->dbus_new_initialized = 1;
1086 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
1088 * @iface: Pointer to dbus private data from wpas_dbus_init()
1090 * Deinitialize the dbus control interface that was initialized with
1091 * wpas_dbus_ctrl_iface_init().
1093 void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface)
1095 if (!iface->dbus_new_initialized)
1097 wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
1098 WPAS_DBUS_NEW_PATH);
1099 dbus_connection_unregister_object_path(iface->con,
1100 WPAS_DBUS_NEW_PATH);
1104 static void wpa_dbus_free(void *ptr)
1110 static const struct wpas_dbus_property wpas_dbus_network_properties[] = {
1111 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
1112 (WPADBusPropertyAccessor) wpas_dbus_getter_network_properties,
1113 (WPADBusPropertyAccessor) wpas_dbus_setter_network_properties,
1116 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
1117 (WPADBusPropertyAccessor) wpas_dbus_getter_enabled,
1118 (WPADBusPropertyAccessor) wpas_dbus_setter_enabled,
1121 { NULL, NULL, NULL, NULL, NULL, 0 }
1125 static const struct wpas_dbus_signal wpas_dbus_network_signals[] = {
1126 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
1128 { "properties", "a{sv}", ARG_OUT },
1132 { NULL, NULL, { END_ARGS } }
1137 * wpas_dbus_register_network - Register a configured network with dbus
1138 * @wpa_s: wpa_supplicant interface structure
1139 * @ssid: network configuration data
1140 * Returns: 0 on success, -1 on failure
1142 * Registers network representing object with dbus
1144 static int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
1145 struct wpa_ssid *ssid)
1147 struct wpas_dbus_priv *ctrl_iface;
1148 struct wpa_dbus_object_desc *obj_desc;
1150 struct network_handler_args *arg = NULL;
1154 /* Do nothing if the control interface is not turned on */
1155 if (wpa_s == NULL || wpa_s->global == NULL)
1157 ctrl_iface = wpa_s->global->dbus;
1158 if (ctrl_iface == NULL)
1161 net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1162 if (net_obj_path == NULL)
1164 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1165 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
1166 wpas_dbus_get_path(wpa_s), ssid->id);
1168 wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
1170 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1172 wpa_printf(MSG_ERROR, "Not enough memory "
1173 "to create object description");
1177 /* allocate memory for handlers arguments */
1178 arg = os_zalloc(sizeof(struct network_handler_args));
1180 wpa_printf(MSG_ERROR, "Not enough memory "
1181 "to create arguments for method");
1188 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
1189 wpas_dbus_network_properties,
1190 wpas_dbus_network_signals);
1192 if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
1193 wpa_s->ifname, obj_desc))
1196 wpas_dbus_signal_network_added(wpa_s, ssid->id);
1198 os_free(net_obj_path);
1202 os_free(net_obj_path);
1210 * wpas_dbus_unregister_network - Unregister a configured network from dbus
1211 * @wpa_s: wpa_supplicant interface structure
1213 * Returns: 0 on success, -1 on failure
1215 * Unregisters network representing object from dbus
1217 static int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
1219 struct wpas_dbus_priv *ctrl_iface;
1223 /* Do nothing if the control interface is not turned on */
1224 if (wpa_s == NULL || wpa_s->global == NULL)
1226 ctrl_iface = wpa_s->global->dbus;
1227 if (ctrl_iface == NULL)
1230 net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1231 if (net_obj_path == NULL)
1233 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1234 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
1235 wpas_dbus_get_path(wpa_s), nid);
1237 wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
1239 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
1242 wpas_dbus_signal_network_removed(wpa_s, nid);
1244 os_free(net_obj_path);
1249 static const struct wpas_dbus_property wpas_dbus_bss_properties[] = {
1250 { "Properties", WPAS_DBUS_NEW_IFACE_BSSID, "a{sv}",
1251 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_properties,
1255 { NULL, NULL, NULL, NULL, NULL, 0 }
1259 static const struct wpas_dbus_signal wpas_dbus_bss_signals[] = {
1260 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSSID,
1262 { "properties", "a{sv}", ARG_OUT },
1266 { NULL, NULL, { END_ARGS } }
1271 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
1272 * @wpa_s: wpa_supplicant interface structure
1273 * @bssid: scanned network bssid
1274 * @id: unique BSS identifier
1275 * Returns: 0 on success, -1 on failure
1277 * Unregisters BSS representing object from dbus
1279 static int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
1280 u8 bssid[ETH_ALEN], unsigned int id)
1282 struct wpas_dbus_priv *ctrl_iface;
1285 /* Do nothing if the control interface is not turned on */
1286 if (wpa_s == NULL || wpa_s->global == NULL)
1288 ctrl_iface = wpa_s->global->dbus;
1289 if (ctrl_iface == NULL)
1292 bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1293 if (bss_obj_path == NULL)
1296 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1297 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
1298 wpas_dbus_get_path(wpa_s), id);
1300 wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
1302 if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
1303 wpa_printf(MSG_ERROR,
1304 "Cannot unregister BSSID dbus object %s.",
1306 os_free(bss_obj_path);
1310 wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
1312 os_free(bss_obj_path);
1318 * wpas_dbus_register_bss - Register a scanned BSS with dbus
1319 * @wpa_s: wpa_supplicant interface structure
1320 * @bssid: scanned network bssid
1321 * @id: unique BSS identifier
1322 * Returns: 0 on success, -1 on failure
1324 * Registers BSS representing object with dbus
1326 static int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
1327 u8 bssid[ETH_ALEN], unsigned int id)
1329 struct wpas_dbus_priv *ctrl_iface;
1330 struct wpa_dbus_object_desc *obj_desc;
1333 struct bss_handler_args *arg = NULL;
1335 /* Do nothing if the control interface is not turned on */
1336 if (wpa_s == NULL || wpa_s->global == NULL)
1338 ctrl_iface = wpa_s->global->dbus;
1339 if (ctrl_iface == NULL)
1342 bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1343 if (bss_obj_path == NULL)
1346 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1347 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
1348 wpas_dbus_get_path(wpa_s), id);
1350 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1352 wpa_printf(MSG_ERROR, "Not enough memory "
1353 "to create object description");
1357 arg = os_zalloc(sizeof(struct bss_handler_args));
1359 wpa_printf(MSG_ERROR, "Not enough memory "
1360 "to create arguments for handler");
1366 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
1367 wpas_dbus_bss_properties,
1368 wpas_dbus_bss_signals);
1370 wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
1372 if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
1373 wpa_s->ifname, obj_desc)) {
1374 wpa_printf(MSG_ERROR,
1375 "Cannot register BSSID dbus object %s.",
1380 wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
1382 os_free(bss_obj_path);
1386 os_free(bss_obj_path);
1393 static const struct wpas_dbus_method wpas_dbus_interface_methods[] = {
1394 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
1395 (WPADBusMethodHandler) &wpas_dbus_handler_scan,
1397 { "args", "a{sv}", ARG_IN },
1401 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
1402 (WPADBusMethodHandler) &wpas_dbus_handler_disconnect,
1407 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1408 (WPADBusMethodHandler) &wpas_dbus_handler_add_network,
1410 { "args", "a{sv}", ARG_IN },
1411 { "path", "o", ARG_OUT },
1415 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1416 (WPADBusMethodHandler) &wpas_dbus_handler_remove_network,
1418 { "path", "o", ARG_IN },
1422 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1423 (WPADBusMethodHandler) &wpas_dbus_handler_select_network,
1425 { "path", "o", ARG_IN },
1429 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1430 (WPADBusMethodHandler) &wpas_dbus_handler_add_blob,
1432 { "name", "s", ARG_IN },
1433 { "data", "ay", ARG_IN },
1437 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1438 (WPADBusMethodHandler) &wpas_dbus_handler_get_blob,
1440 { "name", "s", ARG_IN },
1441 { "data", "ay", ARG_OUT },
1445 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1446 (WPADBusMethodHandler) &wpas_dbus_handler_remove_blob,
1448 { "name", "s", ARG_IN },
1453 { "Start", WPAS_DBUS_NEW_IFACE_WPS,
1454 (WPADBusMethodHandler) &wpas_dbus_handler_wps_start,
1456 { "args", "a{sv}", ARG_IN },
1457 { "output", "a{sv}", ARG_OUT },
1461 #endif /* CONFIG_WPS */
1462 { NULL, NULL, NULL, { END_ARGS } }
1465 static const struct wpas_dbus_property wpas_dbus_interface_properties[] = {
1466 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
1467 (WPADBusPropertyAccessor) wpas_dbus_getter_capabilities,
1470 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1471 (WPADBusPropertyAccessor) wpas_dbus_getter_state,
1474 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
1475 (WPADBusPropertyAccessor) wpas_dbus_getter_scanning,
1478 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
1479 (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan,
1480 (WPADBusPropertyAccessor) wpas_dbus_setter_ap_scan,
1483 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1484 (WPADBusPropertyAccessor) wpas_dbus_getter_ifname,
1487 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1488 (WPADBusPropertyAccessor) wpas_dbus_getter_driver,
1491 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1492 (WPADBusPropertyAccessor) wpas_dbus_getter_bridge_ifname,
1495 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
1496 (WPADBusPropertyAccessor) wpas_dbus_getter_current_bss,
1499 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
1500 (WPADBusPropertyAccessor) wpas_dbus_getter_current_network,
1503 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
1504 (WPADBusPropertyAccessor) wpas_dbus_getter_blobs,
1507 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
1508 (WPADBusPropertyAccessor) wpas_dbus_getter_bsss,
1511 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
1512 (WPADBusPropertyAccessor) wpas_dbus_getter_networks,
1516 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
1517 (WPADBusPropertyAccessor) wpas_dbus_getter_process_credentials,
1518 (WPADBusPropertyAccessor) wpas_dbus_setter_process_credentials,
1521 #endif /* CONFIG_WPS */
1522 { NULL, NULL, NULL, NULL, NULL, 0 }
1525 static const struct wpas_dbus_signal wpas_dbus_interface_signals[] = {
1526 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
1528 { "success", "b", ARG_OUT },
1532 { "StateChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
1534 { "newState", "s", ARG_OUT },
1535 { "oldState", "s", ARG_OUT },
1539 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1541 { "path", "o", ARG_OUT },
1545 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1547 { "path", "o", ARG_OUT },
1551 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1553 { "name", "s", ARG_OUT },
1557 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1559 { "name", "s", ARG_OUT },
1563 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1565 { "path", "o", ARG_OUT },
1569 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1571 { "path", "o", ARG_OUT },
1575 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
1577 { "path", "o", ARG_OUT },
1581 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
1583 { "properties", "a{sv}", ARG_OUT },
1588 { "Event", WPAS_DBUS_NEW_IFACE_WPS,
1590 { "name", "s", ARG_OUT },
1591 { "args", "a{sv}", ARG_OUT },
1595 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
1597 { "credentials", "a{sv}", ARG_OUT },
1601 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
1603 { "properties", "a{sv}", ARG_OUT },
1607 #endif /* CONFIG_WPS */
1608 { NULL, NULL, { END_ARGS } }
1612 static int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
1615 struct wpa_dbus_object_desc *obj_desc = NULL;
1617 struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
1620 /* Do nothing if the control interface is not turned on */
1621 if (ctrl_iface == NULL)
1624 /* Create and set the interface's object path */
1625 path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1628 next = ctrl_iface->next_objid++;
1629 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
1630 WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
1632 if (wpas_dbus_set_path(wpa_s, path)) {
1633 wpa_printf(MSG_DEBUG,
1634 "Failed to set dbus path for interface %s",
1639 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1641 wpa_printf(MSG_ERROR, "Not enough memory "
1642 "to create object description");
1646 wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
1647 wpas_dbus_interface_properties,
1648 wpas_dbus_interface_signals);
1650 wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'", path);
1651 if (wpa_dbus_register_object_per_iface(ctrl_iface, path, wpa_s->ifname,
1655 wpas_dbus_signal_interface_created(wpa_s);
1667 static int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
1669 struct wpas_dbus_priv *ctrl_iface;
1671 /* Do nothing if the control interface is not turned on */
1672 if (wpa_s == NULL || wpa_s->global == NULL)
1674 ctrl_iface = wpa_s->global->dbus;
1675 if (ctrl_iface == NULL)
1678 wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
1679 wpas_dbus_get_path(wpa_s));
1680 if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
1681 wpas_dbus_get_path(wpa_s)))
1684 wpas_dbus_signal_interface_removed(wpa_s);
1686 os_free(wpa_s->dbus_new_path);
1687 wpa_s->dbus_new_path = NULL;
1693 static struct wpas_dbus_callbacks callbacks =
1695 .signal_interface_created = wpas_dbus_signal_interface_created,
1696 .signal_interface_removed = wpas_dbus_signal_interface_removed,
1698 .register_interface = wpas_dbus_register_interface,
1699 .unregister_interface = wpas_dbus_unregister_interface,
1701 .signal_scan_done = wpas_dbus_signal_scan_done,
1703 .signal_blob_added = wpas_dbus_signal_blob_added,
1704 .signal_blob_removed = wpas_dbus_signal_blob_removed,
1706 .signal_network_selected = wpas_dbus_signal_network_selected,
1708 .signal_state_changed = wpas_dbus_signal_state_changed,
1709 .register_network = wpas_dbus_register_network,
1710 .unregister_network = wpas_dbus_unregister_network,
1712 .signal_network_enabled_changed =
1713 wpas_dbus_signal_network_enabled_changed,
1715 .register_bss = wpas_dbus_register_bss,
1716 .unregister_bss = wpas_dbus_unregister_bss,
1718 .signal_prop_changed = wpas_dbus_signal_prop_changed,
1719 .signal_debug_params_changed = wpas_dbus_signal_debug_params_changed,
1722 .signal_wps_event_success = wpas_dbus_signal_wps_event_success,
1723 .signal_wps_event_fail = wpas_dbus_signal_wps_event_fail,
1724 .signal_wps_event_m2d = wpas_dbus_signal_wps_event_m2d,
1725 .signal_wps_credentials = wpas_dbus_signal_wps_cred,
1726 #endif /* CONFIG_WPS */
1730 struct wpas_dbus_callbacks * wpas_dbus_get_callbacks(void)
1737 * wpas_dbus_get_path - Get an interface's dbus path
1738 * @wpa_s: %wpa_supplicant interface structure
1739 * Returns: Interface's dbus object path, or %NULL on error
1741 const char * wpas_dbus_get_path(struct wpa_supplicant *wpa_s)
1743 return wpa_s->dbus_new_path;