2 * WPA Supplicant / dbus-based control interface
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
16 #include <dbus/dbus.h>
20 #include "drivers/driver.h"
22 #include "../config.h"
23 #include "../wpa_supplicant_i.h"
25 #include "dbus_old_handlers.h"
26 #include "dbus_common.h"
27 #include "dbus_common_i.h"
31 * wpas_dbus_decompose_object_path - Decompose an interface object path into parts
32 * @path: The dbus object path
33 * @network: (out) the configured network this object path refers to, if any
34 * @bssid: (out) the scanned bssid this object path refers to, if any
35 * Returns: The object path of the network interface this path refers to
37 * For a given object path, decomposes the object path into object id, network,
38 * and BSSID parts, if those parts exist.
40 char * wpas_dbus_decompose_object_path(const char *path
, char **network
,
43 const unsigned int dev_path_prefix_len
=
44 strlen(WPAS_DBUS_PATH_INTERFACES
"/");
48 /* Be a bit paranoid about path */
49 if (!path
|| strncmp(path
, WPAS_DBUS_PATH_INTERFACES
"/",
53 /* Ensure there's something at the end of the path */
54 if ((path
+ dev_path_prefix_len
)[0] == '\0')
57 obj_path_only
= os_strdup(path
);
58 if (obj_path_only
== NULL
)
61 next_sep
= strchr(obj_path_only
+ dev_path_prefix_len
, '/');
62 if (next_sep
!= NULL
) {
63 const char *net_part
= strstr(next_sep
,
64 WPAS_DBUS_NETWORKS_PART
"/");
65 const char *bssid_part
= strstr(next_sep
,
66 WPAS_DBUS_BSSIDS_PART
"/");
68 if (network
&& net_part
) {
69 /* Deal with a request for a configured network */
70 const char *net_name
= net_part
+
71 strlen(WPAS_DBUS_NETWORKS_PART
"/");
74 *network
= os_strdup(net_name
);
75 } else if (bssid
&& bssid_part
) {
76 /* Deal with a request for a scanned BSSID */
77 const char *bssid_name
= bssid_part
+
78 strlen(WPAS_DBUS_BSSIDS_PART
"/");
79 if (strlen(bssid_name
))
80 *bssid
= os_strdup(bssid_name
);
85 /* Cut off interface object path before "/" */
94 * wpas_dbus_new_invalid_iface_error - Return a new invalid interface error message
95 * @message: Pointer to incoming dbus message this error refers to
96 * Returns: A dbus error message
98 * Convenience function to create and return an invalid interface error
100 DBusMessage
* wpas_dbus_new_invalid_iface_error(DBusMessage
*message
)
102 return dbus_message_new_error(message
, WPAS_ERROR_INVALID_IFACE
,
103 "wpa_supplicant knows nothing about "
109 * wpas_dbus_new_invalid_network_error - Return a new invalid network error message
110 * @message: Pointer to incoming dbus message this error refers to
111 * Returns: a dbus error message
113 * Convenience function to create and return an invalid network error
115 DBusMessage
* wpas_dbus_new_invalid_network_error(DBusMessage
*message
)
117 return dbus_message_new_error(message
, WPAS_ERROR_INVALID_NETWORK
,
118 "The requested network does not exist.");
123 * wpas_dbus_new_invalid_bssid_error - Return a new invalid bssid error message
124 * @message: Pointer to incoming dbus message this error refers to
125 * Returns: a dbus error message
127 * Convenience function to create and return an invalid bssid error
129 static DBusMessage
* wpas_dbus_new_invalid_bssid_error(DBusMessage
*message
)
131 return dbus_message_new_error(message
, WPAS_ERROR_INVALID_BSSID
,
132 "The BSSID requested was invalid.");
137 * wpas_dispatch_network_method - dispatch messages for configured networks
138 * @message: the incoming dbus message
139 * @wpa_s: a network interface's data
140 * @network_id: id of the configured network we're interested in
141 * Returns: a reply dbus message, or a dbus error message
143 * This function dispatches all incoming dbus messages for configured networks.
145 static DBusMessage
* wpas_dispatch_network_method(DBusMessage
*message
,
146 struct wpa_supplicant
*wpa_s
,
149 DBusMessage
*reply
= NULL
;
150 const char *method
= dbus_message_get_member(message
);
151 struct wpa_ssid
*ssid
;
153 ssid
= wpa_config_get_network(wpa_s
->conf
, network_id
);
155 return wpas_dbus_new_invalid_network_error(message
);
157 if (!strcmp(method
, "set"))
158 reply
= wpas_dbus_iface_set_network(message
, wpa_s
, ssid
);
159 else if (!strcmp(method
, "enable"))
160 reply
= wpas_dbus_iface_enable_network(message
, wpa_s
, ssid
);
161 else if (!strcmp(method
, "disable"))
162 reply
= wpas_dbus_iface_disable_network(message
, wpa_s
, ssid
);
169 * wpas_dispatch_bssid_method - dispatch messages for scanned networks
170 * @message: the incoming dbus message
171 * @wpa_s: a network interface's data
172 * @bssid: bssid of the scanned network we're interested in
173 * Returns: a reply dbus message, or a dbus error message
175 * This function dispatches all incoming dbus messages for scanned networks.
177 static DBusMessage
* wpas_dispatch_bssid_method(DBusMessage
*message
,
178 struct wpa_supplicant
*wpa_s
,
181 DBusMessage
*reply
= NULL
;
182 const char *method
= dbus_message_get_member(message
);
183 struct wpa_scan_res
*res
= NULL
;
186 /* Ensure we actually have scan data */
187 if (wpa_s
->scan_res
== NULL
&&
188 wpa_supplicant_get_scan_results(wpa_s
) < 0) {
189 reply
= wpas_dbus_new_invalid_bssid_error(message
);
193 /* Find the bssid's scan data */
194 for (i
= 0; i
< wpa_s
->scan_res
->num
; i
++) {
195 struct wpa_scan_res
*search_res
= wpa_s
->scan_res
->res
[i
];
198 memset(mac_str
, 0, sizeof(mac_str
));
199 snprintf(mac_str
, sizeof(mac_str
) - 1, WPAS_DBUS_BSSID_FORMAT
,
200 MAC2STR(search_res
->bssid
));
201 if (!strcmp(bssid
, mac_str
)) {
208 reply
= wpas_dbus_new_invalid_bssid_error(message
);
212 /* Dispatch the method call against the scanned bssid */
213 if (!strcmp(method
, "properties"))
214 reply
= wpas_dbus_bssid_properties(message
, wpa_s
, res
);
222 * wpas_iface_message_handler - Dispatch messages for interfaces or networks
223 * @connection: Connection to the system message bus
224 * @message: An incoming dbus message
225 * @user_data: A pointer to a dbus control interface data structure
226 * Returns: Whether or not the message was handled
228 * This function dispatches all incoming dbus messages for network interfaces,
229 * or objects owned by them, such as scanned BSSIDs and configured networks.
231 static DBusHandlerResult
wpas_iface_message_handler(DBusConnection
*connection
,
232 DBusMessage
*message
,
235 struct wpa_supplicant
*wpa_s
= user_data
;
236 const char *method
= dbus_message_get_member(message
);
237 const char *path
= dbus_message_get_path(message
);
238 const char *msg_interface
= dbus_message_get_interface(message
);
239 char *iface_obj_path
= NULL
;
240 char *network
= NULL
;
242 DBusMessage
*reply
= NULL
;
244 /* Caller must specify a message interface */
248 iface_obj_path
= wpas_dbus_decompose_object_path(path
, &network
,
250 if (iface_obj_path
== NULL
) {
251 reply
= wpas_dbus_new_invalid_iface_error(message
);
255 /* Make sure the message's object path actually refers to the
256 * wpa_supplicant structure it's supposed to (which is wpa_s)
258 if (wpa_supplicant_get_iface_by_dbus_path(wpa_s
->global
,
259 iface_obj_path
) != wpa_s
) {
260 reply
= wpas_dbus_new_invalid_iface_error(message
);
264 if (network
&& !strcmp(msg_interface
, WPAS_DBUS_IFACE_NETWORK
)) {
265 /* A method for one of this interface's configured networks */
266 int nid
= strtoul(network
, NULL
, 10);
268 reply
= wpas_dispatch_network_method(message
, wpa_s
,
271 reply
= wpas_dbus_new_invalid_network_error(message
);
272 } else if (bssid
&& !strcmp(msg_interface
, WPAS_DBUS_IFACE_BSSID
)) {
273 /* A method for one of this interface's scanned BSSIDs */
274 reply
= wpas_dispatch_bssid_method(message
, wpa_s
, bssid
);
275 } else if (!strcmp(msg_interface
, WPAS_DBUS_IFACE_INTERFACE
)) {
276 /* A method for an interface only. */
277 if (!strcmp(method
, "scan"))
278 reply
= wpas_dbus_iface_scan(message
, wpa_s
);
279 else if (!strcmp(method
, "scanResults"))
280 reply
= wpas_dbus_iface_scan_results(message
, wpa_s
);
281 else if (!strcmp(method
, "addNetwork"))
282 reply
= wpas_dbus_iface_add_network(message
, wpa_s
);
283 else if (!strcmp(method
, "removeNetwork"))
284 reply
= wpas_dbus_iface_remove_network(message
, wpa_s
);
285 else if (!strcmp(method
, "selectNetwork"))
286 reply
= wpas_dbus_iface_select_network(message
, wpa_s
);
287 else if (!strcmp(method
, "capabilities"))
288 reply
= wpas_dbus_iface_capabilities(message
, wpa_s
);
289 else if (!strcmp(method
, "disconnect"))
290 reply
= wpas_dbus_iface_disconnect(message
, wpa_s
);
291 else if (!strcmp(method
, "setAPScan"))
292 reply
= wpas_dbus_iface_set_ap_scan(message
, wpa_s
);
293 else if (!strcmp(method
, "setSmartcardModules"))
294 reply
= wpas_dbus_iface_set_smartcard_modules(message
,
296 else if (!strcmp(method
, "state"))
297 reply
= wpas_dbus_iface_get_state(message
, wpa_s
);
298 else if (!strcmp(method
, "scanning"))
299 reply
= wpas_dbus_iface_get_scanning(message
, wpa_s
);
300 else if (!strcmp(method
, "setBlobs"))
301 reply
= wpas_dbus_iface_set_blobs(message
, wpa_s
);
302 else if (!strcmp(method
, "removeBlobs"))
303 reply
= wpas_dbus_iface_remove_blobs(message
, wpa_s
);
305 else if (!os_strcmp(method
, "wpsPbc"))
306 reply
= wpas_dbus_iface_wps_pbc(message
, wpa_s
);
307 else if (!os_strcmp(method
, "wpsPin"))
308 reply
= wpas_dbus_iface_wps_pin(message
, wpa_s
);
309 else if (!os_strcmp(method
, "wpsReg"))
310 reply
= wpas_dbus_iface_wps_reg(message
, wpa_s
);
311 #endif /* CONFIG_WPS */
314 /* If the message was handled, send back the reply */
316 if (!dbus_message_get_no_reply(message
))
317 dbus_connection_send(connection
, reply
, NULL
);
318 dbus_message_unref(reply
);
322 os_free(iface_obj_path
);
325 return reply
? DBUS_HANDLER_RESULT_HANDLED
:
326 DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
331 * wpas_message_handler - dispatch incoming dbus messages
332 * @connection: connection to the system message bus
333 * @message: an incoming dbus message
334 * @user_data: a pointer to a dbus control interface data structure
335 * Returns: whether or not the message was handled
337 * This function dispatches all incoming dbus messages to the correct
338 * handlers, depending on what the message's target object path is,
339 * and what the method call is.
341 static DBusHandlerResult
wpas_message_handler(DBusConnection
*connection
,
342 DBusMessage
*message
, void *user_data
)
344 struct wpas_dbus_priv
*ctrl_iface
= user_data
;
347 const char *msg_interface
;
348 DBusMessage
*reply
= NULL
;
350 method
= dbus_message_get_member(message
);
351 path
= dbus_message_get_path(message
);
352 msg_interface
= dbus_message_get_interface(message
);
353 if (!method
|| !path
|| !ctrl_iface
|| !msg_interface
)
354 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
356 /* Validate the method interface */
357 if (strcmp(msg_interface
, WPAS_DBUS_INTERFACE
) != 0)
358 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
360 if (!strcmp(path
, WPAS_DBUS_PATH
)) {
361 /* dispatch methods against our global dbus interface here */
362 if (!strcmp(method
, "addInterface")) {
363 reply
= wpas_dbus_global_add_interface(
364 message
, ctrl_iface
->global
);
365 } else if (!strcmp(method
, "removeInterface")) {
366 reply
= wpas_dbus_global_remove_interface(
367 message
, ctrl_iface
->global
);
368 } else if (!strcmp(method
, "getInterface")) {
369 reply
= wpas_dbus_global_get_interface(
370 message
, ctrl_iface
->global
);
371 } else if (!strcmp(method
, "setDebugParams")) {
372 reply
= wpas_dbus_global_set_debugparams(
373 message
, ctrl_iface
->global
);
377 /* If the message was handled, send back the reply */
379 if (!dbus_message_get_no_reply(message
))
380 dbus_connection_send(connection
, reply
, NULL
);
381 dbus_message_unref(reply
);
384 return reply
? DBUS_HANDLER_RESULT_HANDLED
:
385 DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
390 * wpa_supplicant_dbus_notify_scan_results - Send a scan results signal
391 * @wpa_s: %wpa_supplicant network interface data
392 * Returns: 0 on success, -1 on failure
394 * Notify listeners that this interface has updated scan results.
396 void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant
*wpa_s
)
398 struct wpas_dbus_priv
*iface
= wpa_s
->global
->dbus
;
399 DBusMessage
*_signal
;
402 /* Do nothing if the control interface is not turned on */
406 path
= wpa_supplicant_get_dbus_path(wpa_s
);
408 perror("wpa_supplicant_dbus_notify_scan_results[dbus]: "
409 "interface didn't have a dbus path");
410 wpa_printf(MSG_ERROR
,
411 "wpa_supplicant_dbus_notify_scan_results[dbus]: "
412 "interface didn't have a dbus path; can't send "
413 "scan result signal.");
416 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_IFACE_INTERFACE
,
417 "ScanResultsAvailable");
418 if (_signal
== NULL
) {
419 perror("wpa_supplicant_dbus_notify_scan_results[dbus]: "
420 "couldn't create dbus signal; likely out of memory");
421 wpa_printf(MSG_ERROR
, "dbus control interface: not enough "
422 "memory to send scan results signal.");
425 dbus_connection_send(iface
->con
, _signal
, NULL
);
426 dbus_message_unref(_signal
);
431 * wpa_supplicant_dbus_notify_state_change - Send a state change signal
432 * @wpa_s: %wpa_supplicant network interface data
433 * @new_state: new state wpa_supplicant is entering
434 * @old_state: old state wpa_supplicant is leaving
435 * Returns: 0 on success, -1 on failure
437 * Notify listeners that wpa_supplicant has changed state
439 void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant
*wpa_s
,
440 enum wpa_states new_state
,
441 enum wpa_states old_state
)
443 struct wpas_dbus_priv
*iface
;
444 DBusMessage
*_signal
= NULL
;
446 const char *new_state_str
, *old_state_str
;
448 /* Do nothing if the control interface is not turned on */
449 if (wpa_s
->global
== NULL
)
451 iface
= wpa_s
->global
->dbus
;
455 /* Only send signal if state really changed */
456 if (new_state
== old_state
)
459 path
= wpa_supplicant_get_dbus_path(wpa_s
);
461 perror("wpa_supplicant_dbus_notify_state_change[dbus]: "
462 "interface didn't have a dbus path");
463 wpa_printf(MSG_ERROR
,
464 "wpa_supplicant_dbus_notify_state_change[dbus]: "
465 "interface didn't have a dbus path; can't send "
469 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_IFACE_INTERFACE
,
471 if (_signal
== NULL
) {
472 perror("wpa_supplicant_dbus_notify_state_change[dbus]: "
473 "couldn't create dbus signal; likely out of memory");
474 wpa_printf(MSG_ERROR
,
475 "wpa_supplicant_dbus_notify_state_change[dbus]: "
476 "couldn't create dbus signal; likely out of "
481 new_state_str
= wpa_supplicant_state_txt(new_state
);
482 old_state_str
= wpa_supplicant_state_txt(old_state
);
483 if (new_state_str
== NULL
|| old_state_str
== NULL
) {
484 perror("wpa_supplicant_dbus_notify_state_change[dbus]: "
485 "couldn't convert state strings");
486 wpa_printf(MSG_ERROR
,
487 "wpa_supplicant_dbus_notify_state_change[dbus]: "
488 "couldn't convert state strings.");
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("wpa_supplicant_dbus_notify_state_change[dbus]: "
497 "not enough memory to construct state change signal.");
498 wpa_printf(MSG_ERROR
,
499 "wpa_supplicant_dbus_notify_state_change[dbus]: "
500 "not enough memory to construct state change "
505 dbus_connection_send(iface
->con
, _signal
, NULL
);
508 dbus_message_unref(_signal
);
513 * wpa_supplicant_dbus_notify_scanning - send scanning status
514 * @wpa_s: %wpa_supplicant network interface data
515 * Returns: 0 on success, -1 on failure
517 * Notify listeners of interface scanning state changes
519 void wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant
*wpa_s
)
521 struct wpas_dbus_priv
*iface
= wpa_s
->global
->dbus
;
522 DBusMessage
*_signal
;
524 dbus_bool_t scanning
= wpa_s
->scanning
? TRUE
: FALSE
;
526 /* Do nothing if the control interface is not turned on */
530 path
= wpa_supplicant_get_dbus_path(wpa_s
);
532 perror("wpa_supplicant_dbus_notify_scanning[dbus]: interface "
533 "didn't have a dbus path");
534 wpa_printf(MSG_ERROR
,
535 "%s[dbus]: interface didn't have a dbus path; "
536 "can't send scanning signal.", __FUNCTION__
);
539 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_IFACE_INTERFACE
,
541 if (_signal
== NULL
) {
542 perror("wpa_supplicant_dbus_notify_scanning[dbus]: couldn't "
543 "create dbus signal; likely out of memory");
544 wpa_printf(MSG_ERROR
, "%s[dbus]: dbus control interface: not "
545 "enough memory to send scan results signal.",
550 if (dbus_message_append_args(_signal
,
551 DBUS_TYPE_BOOLEAN
, &scanning
,
552 DBUS_TYPE_INVALID
)) {
553 dbus_connection_send(iface
->con
, _signal
, NULL
);
555 perror("wpa_supplicant_dbus_notify_scanning[dbus]: not enough "
556 "memory to construct signal.");
557 wpa_printf(MSG_ERROR
, "%s[dbus]: not enough memory to "
558 "construct signal.", __FUNCTION__
);
560 dbus_message_unref(_signal
);
565 void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant
*wpa_s
,
566 const struct wps_credential
*cred
)
568 struct wpas_dbus_priv
*iface
;
569 DBusMessage
*_signal
= NULL
;
572 /* Do nothing if the control interface is not turned on */
573 if (wpa_s
->global
== NULL
)
575 iface
= wpa_s
->global
->dbus
;
579 path
= wpa_supplicant_get_dbus_path(wpa_s
);
581 perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: "
582 "interface didn't have a dbus path");
583 wpa_printf(MSG_ERROR
,
584 "wpa_supplicant_dbus_notify_wps_cred[dbus]: "
585 "interface didn't have a dbus path; can't send "
589 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_IFACE_INTERFACE
,
591 if (_signal
== NULL
) {
592 perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: "
593 "couldn't create dbus signal; likely out of memory");
594 wpa_printf(MSG_ERROR
,
595 "wpa_supplicant_dbus_notify_wps_cred[dbus]: "
596 "couldn't create dbus signal; likely out of "
601 if (!dbus_message_append_args(_signal
,
602 DBUS_TYPE_ARRAY
, DBUS_TYPE_BYTE
,
603 &cred
->cred_attr
, cred
->cred_attr_len
,
604 DBUS_TYPE_INVALID
)) {
605 perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: "
606 "not enough memory to construct signal.");
607 wpa_printf(MSG_ERROR
,
608 "wpa_supplicant_dbus_notify_wps_cred[dbus]: "
609 "not enough memory to construct signal.");
613 dbus_connection_send(iface
->con
, _signal
, NULL
);
616 dbus_message_unref(_signal
);
618 #else /* CONFIG_WPS */
619 void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant
*wpa_s
,
620 const struct wps_credential
*cred
)
623 #endif /* CONFIG_WPS */
627 * wpa_supplicant_dbus_ctrl_iface_init - Initialize dbus control interface
628 * @global: Pointer to global data from wpa_supplicant_init()
629 * Returns: 0 on success, -1 on failure
631 * Initialize the dbus control interface and start receiving commands from
632 * external programs over the bus.
634 int wpa_supplicant_dbus_ctrl_iface_init(struct wpas_dbus_priv
*iface
)
638 DBusObjectPathVTable wpas_vtable
= {
639 NULL
, &wpas_message_handler
, NULL
, NULL
, NULL
, NULL
642 /* Register the message handler for the global dbus interface */
643 if (!dbus_connection_register_object_path(iface
->con
,
644 WPAS_DBUS_PATH
, &wpas_vtable
,
646 perror("dbus_connection_register_object_path[dbus]");
647 wpa_printf(MSG_ERROR
, "Could not set up DBus message "
652 /* Register our service with the message bus */
653 dbus_error_init(&error
);
654 switch (dbus_bus_request_name(iface
->con
, WPAS_DBUS_SERVICE
,
656 case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
:
659 case DBUS_REQUEST_NAME_REPLY_EXISTS
:
660 case DBUS_REQUEST_NAME_REPLY_IN_QUEUE
:
661 case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER
:
662 perror("dbus_bus_request_name[dbus]");
663 wpa_printf(MSG_ERROR
, "Could not request DBus service name: "
664 "already registered.");
667 perror("dbus_bus_request_name[dbus]");
668 wpa_printf(MSG_ERROR
, "Could not request DBus service name: "
669 "%s %s.", error
.name
, error
.message
);
672 dbus_error_free(&error
);
677 wpa_printf(MSG_DEBUG
, "Providing DBus service '" WPAS_DBUS_SERVICE
685 * wpas_dbus_register_new_iface - Register a new interface with dbus
686 * @wpa_s: %wpa_supplicant interface description structure to register
687 * Returns: 0 on success, -1 on error
689 * Registers a new interface with dbus and assigns it a dbus object path.
691 int wpas_dbus_register_iface(struct wpa_supplicant
*wpa_s
)
693 struct wpas_dbus_priv
*ctrl_iface
= wpa_s
->global
->dbus
;
694 DBusConnection
* con
;
696 DBusObjectPathVTable vtable
= {
697 NULL
, &wpas_iface_message_handler
, NULL
, NULL
, NULL
, NULL
701 /* Do nothing if the control interface is not turned on */
702 if (ctrl_iface
== NULL
)
705 con
= ctrl_iface
->con
;
706 next
= ctrl_iface
->next_objid
++;
708 /* Create and set the interface's object path */
709 wpa_s
->dbus_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
710 if (wpa_s
->dbus_path
== NULL
)
712 os_snprintf(wpa_s
->dbus_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
713 WPAS_DBUS_PATH_INTERFACES
"/%u",
716 /* Register the message handler for the interface functions */
717 if (!dbus_connection_register_fallback(con
, wpa_s
->dbus_path
, &vtable
,
719 perror("wpas_dbus_register_iface [dbus]");
720 wpa_printf(MSG_ERROR
, "Could not set up DBus message "
721 "handler for interface %s.", wpa_s
->ifname
);
732 * wpas_dbus_unregister_iface - Unregister an interface from dbus
733 * @wpa_s: wpa_supplicant interface structure
734 * Returns: 0 on success, -1 on failure
736 * Unregisters the interface with dbus
738 int wpas_dbus_unregister_iface(struct wpa_supplicant
*wpa_s
)
740 struct wpas_dbus_priv
*ctrl_iface
;
744 /* Do nothing if the control interface is not turned on */
745 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
747 ctrl_iface
= wpa_s
->global
->dbus
;
748 if (ctrl_iface
== NULL
)
751 con
= ctrl_iface
->con
;
752 path
= wpa_supplicant_get_dbus_path(wpa_s
);
754 if (!dbus_connection_unregister_object_path(con
, path
))
757 os_free(wpa_s
->dbus_path
);
758 wpa_s
->dbus_path
= NULL
;
765 * wpa_supplicant_get_iface_by_dbus_path - Get a new network interface
766 * @global: Pointer to global data from wpa_supplicant_init()
767 * @path: Pointer to a dbus object path representing an interface
768 * Returns: Pointer to the interface or %NULL if not found
770 struct wpa_supplicant
* wpa_supplicant_get_iface_by_dbus_path(
771 struct wpa_global
*global
, const char *path
)
773 struct wpa_supplicant
*wpa_s
;
775 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
) {
776 if (strcmp(wpa_s
->dbus_path
, path
) == 0)
784 * wpa_supplicant_get_dbus_path - Get an interface's dbus path
785 * @wpa_s: %wpa_supplicant interface structure
786 * Returns: Interface's dbus object path, or %NULL on error
788 const char * wpa_supplicant_get_dbus_path(struct wpa_supplicant
*wpa_s
)
790 return wpa_s
->dbus_path
;